public static string ProcessArticle(string path, string projectRoot)
        {
            string result = QwfReader.ReadFileText(projectRoot + "\\layout\\template.html");
            // Get document info
            var           lines          = QwfReader.GetFileTextLines(path);
            List <string> qwiLines       = new List <string>();
            List <string> articleLines   = new List <string>();
            bool          readingArticle = false;

            foreach (string line in lines)
            {
                if (line == "==")
                {
                    readingArticle = true;
                    continue;
                }
                if (readingArticle)
                {
                    articleLines.Add(line);
                }
                else
                {
                    qwiLines.Add(line);
                }
            }
            var    qwi     = QwfReader.ReadQwi(qwiLines);
            string article = QwfReader.MDToHTML(articleLines);

            result = result.Replace(";;TITLE;;", qwi["Title"]);
            result = result.Replace(";;ARTICLE;;", article);
            result = result.Replace(";;SIDEBAR_LINKS;;", GetSidebarLinks());
            result = result.Replace(";;FOOTER;;", GetFooterText());
            return(result);
        }
        public static string GenerateHomepage(string projectRoot, string resultDir, Dictionary <string, string> siteSettings)
        {
            string        result       = QwfReader.ReadFileText(projectRoot + "\\layout\\template.html");
            List <string> articleLines = new List <string>()
            {
                "# Welcome to the Qudical Developer Wiki!",
                "Here you'll _(hopefully)_ find some useful information regarding the technical side of Qudical projects.",
                "# Categories:"
            };
            string article = QwfReader.MDToHTML(articleLines);

            foreach (KeyValuePair <string, Dictionary <string, List <string> > > category in categories)
            {
                string path = "\\qudicalwiki\\categories\\" + category.Key + ".html";
                article += "<h2><a href=\"" + path + "\">" + category.Key + "</a></h2>";
                article += $"<p>{categoryDescriptions[category.Key]}</p>";
            }
            result = result.Replace(";;TITLE;;", siteSettings["SiteName"]);
            result = result.Replace(";;ARTICLE;;", article);
            result = result.Replace(";;SIDEBAR_LINKS;;", GetSidebarLinks());
            result = result.Replace(";;FOOTER;;", GetFooterText());
            return(result);
        }
        private static void ProcessArticleCategory(string path, string projectRoot, string resultDir)
        {
            // Get document info
            var           lines          = QwfReader.GetFileTextLines(path);
            List <string> qwiLines       = new List <string>();
            bool          readingArticle = false;

            foreach (string line in lines)
            {
                if (line == "==")
                {
                    readingArticle = true;
                    continue;
                }
                if (!readingArticle)
                {
                    qwiLines.Add(line);
                }
            }
            var    qwi          = QwfReader.ReadQwi(qwiLines);
            string relativePath = Path.GetRelativePath(resultDir, path.Replace(".qwa", ".html"));

            // Add current page to category and section, create them if they don't exist already.
            if (categories.ContainsKey(qwi["Category"]))
            {
                if (categories[qwi["Category"]].ContainsKey(qwi["Section"]))
                {
                    if (!categories[qwi["Category"]][qwi["Section"]].Contains(relativePath))
                    {
                        categories[qwi["Category"]][qwi["Section"]].Add(relativePath);
                        categories[qwi["Category"]][qwi["Section"]].Add(qwi["Title"]);
                    }
                }
                else
                {
                    categories[qwi["Category"]][qwi["Section"]] = new List <string>()
                    {
                        relativePath, qwi["Title"]
                    };
                    Console.WriteLine("Creating section " + qwi["Section"]);
                }
            }
            else
            {
                categories[qwi["Category"]] = new Dictionary <string, List <string> >();
                Console.WriteLine("Creating category " + qwi["Category"]);

                if (categories[qwi["Category"]].ContainsKey(qwi["Section"]))
                {
                    if (!categories[qwi["Category"]][qwi["Section"]].Contains(relativePath))
                    {
                        categories[qwi["Category"]][qwi["Section"]].Add(relativePath);
                        categories[qwi["Category"]][qwi["Section"]].Add(qwi["Title"]);
                    }
                }
                else
                {
                    categories[qwi["Category"]][qwi["Section"]] = new List <string>()
                    {
                        relativePath, qwi["Title"]
                    };
                    Console.WriteLine("Creating section " + qwi["Section"]);
                }
            }

            // Get category description, if that has been set.
            if (qwi.ContainsKey("CategoryDescription"))
            {
                if (!categoryDescriptions.ContainsKey(qwi["Category"]))
                {
                    categoryDescriptions[qwi["Category"]] = QwfReader.MDToHTML(qwi["CategoryDescription"]);
                }
                else
                {
                    Console.WriteLine("WARNING! Category " + qwi["Category"] + " has multiple description definitions!");
                }
            }
        }