static bool BuildUdn(string XmlDir, string UdnDir, string SitemapDir, string MetadataPath, string StatsPath, List<string> Filters = null) { // Read the metadata MetadataLookup.Load(MetadataPath); // Read the input module index XmlDocument Document = Utility.ReadXmlDocument(Path.Combine(XmlDir, "modules.xml")); // Read the list of modules List<KeyValuePair<string, string>> InputModules = new List<KeyValuePair<string,string>>(); using (XmlNodeList NodeList = Document.SelectNodes("modules/module")) { foreach (XmlNode Node in NodeList) { string Name = Node.Attributes["name"].Value; string Source = Node.Attributes["source"].Value; InputModules.Add(new KeyValuePair<string, string>(Name, Source)); } } #if TEST_INDEX_PAGE // Just create empty modules List<DoxygenModule> Modules = new List<DoxygenModule>(); for (int Idx = 0; Idx < InputModules.Count; Idx++) { Modules.Add(new DoxygenModule(InputModules[Idx].Key, InputModules[Idx].Value)); } #else // Filter the input module list if (Filters != null && Filters.Count > 0) { InputModules = new List<KeyValuePair<string, string>>(InputModules.Where(x => Filters.Exists(y => y.StartsWith(x.Key + "/", StringComparison.InvariantCultureIgnoreCase)))); } // Read all the doxygen modules List<DoxygenModule> Modules = new List<DoxygenModule>(); for(int Idx = 0; Idx < InputModules.Count; Idx++) { Console.WriteLine("Reading module {0}... ({1}/{2})", InputModules[Idx].Key, Idx + 1, InputModules.Count); Modules.Add(DoxygenModule.Read(InputModules[Idx].Key, InputModules[Idx].Value, Path.Combine(XmlDir, InputModules[Idx].Key, "xml"))); } // Now filter all the entities in each module if(Filters != null && Filters.Count > 0) { FilterEntities(Modules, Filters); } #endif // Create the index page, and all the pages below it APIIndex Index = new APIIndex(Modules); // Build a list of pages to output List<APIPage> OutputPages = new List<APIPage>(Index.GatherPages().OrderBy(x => x.LinkPath)); // Dump the output stats if (StatsPath != null) { Console.WriteLine("Writing stats to " + StatsPath + "..."); Stats NewStats = new Stats(OutputPages.OfType<APIMember>()); NewStats.Write(StatsPath); } // Setup the output directory Utility.SafeCreateDirectory(UdnDir); // Build the manifest Console.WriteLine("Writing manifest..."); UdnManifest Manifest = new UdnManifest(Index); Manifest.PrintConflicts(); Manifest.Write(Path.Combine(UdnDir, APIFolder + "\\API.manifest")); // Write all the pages using (Tracker UdnTracker = new Tracker("Writing UDN pages...", OutputPages.Count)) { foreach(int Idx in UdnTracker.Indices) { APIPage Page = OutputPages[Idx]; // Create the output directory string MemberDirectory = Path.Combine(UdnDir, Page.LinkPath); if (!Directory.Exists(MemberDirectory)) { Directory.CreateDirectory(MemberDirectory); } // Write the page Page.WritePage(Manifest, Path.Combine(MemberDirectory, "index.INT.udn")); } } // Write the sitemap contents Console.WriteLine("Writing sitemap contents..."); Index.WriteSitemapContents(Path.Combine(SitemapDir, SitemapContentsFileName)); // Write the sitemap index Console.WriteLine("Writing sitemap index..."); Index.WriteSitemapIndex(Path.Combine(SitemapDir, SitemapIndexFileName)); return true; }
public static bool BuildChm(string ChmCompilerPath, string BaseHtmlDir, string ChmDir) { const string ProjectFileName = "API.hhp"; Console.WriteLine("Searching for CHM input files..."); // Build a list of all the files we want to copy List<string> FilePaths = new List<string>(); List<string> DirectoryPaths = new List<string>(); Utility.FindRelativeContents(BaseHtmlDir, "Images\\api*", false, FilePaths, DirectoryPaths); Utility.FindRelativeContents(BaseHtmlDir, "Include\\*", true, FilePaths, DirectoryPaths); // Find all the HTML files List<string> HtmlFilePaths = new List<string>(); Utility.FindRelativeContents(BaseHtmlDir, "INT\\API\\*.html", true, HtmlFilePaths, DirectoryPaths); // Create all the target directories foreach (string DirectoryPath in DirectoryPaths) { Utility.SafeCreateDirectory(Path.Combine(ChmDir, DirectoryPath)); } // Copy all the files across using (Tracker CopyTracker = new Tracker("Copying support files...", FilePaths.Count)) { foreach(int Idx in CopyTracker.Indices) { Utility.SafeCopyFile(Path.Combine(BaseHtmlDir, FilePaths[Idx]), Path.Combine(ChmDir, FilePaths[Idx])); } } // Copy the HTML files across, fixing up the HTML for display in the CHM window using (Tracker HtmlTracker = new Tracker("Copying html files...", HtmlFilePaths.Count)) { foreach(int Idx in HtmlTracker.Indices) { string HtmlFilePath = HtmlFilePaths[Idx]; string HtmlText = File.ReadAllText(Path.Combine(BaseHtmlDir, HtmlFilePath)); HtmlText = HtmlText.Replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n", ""); HtmlText = HtmlText.Replace("<div id=\"crumbs_bg\"></div>", ""); const string HeaderEndText = "<!-- end head -->"; int HeaderMinIdx = HtmlText.IndexOf("<div id=\"head\">"); int HeaderMaxIdx = HtmlText.IndexOf(HeaderEndText); HtmlText = HtmlText.Remove(HeaderMinIdx, HeaderMaxIdx + HeaderEndText.Length - HeaderMinIdx); int CrumbsMinIdx = HtmlText.IndexOf("<div class=\"crumbs\">"); int HomeMinIdx = HtmlText.IndexOf("<strong>", CrumbsMinIdx); int HomeMaxIdx = HtmlText.IndexOf(">", HomeMinIdx) + 4; HtmlText = HtmlText.Remove(HomeMinIdx, HomeMaxIdx - HomeMinIdx); File.WriteAllText(Path.Combine(ChmDir, HtmlFilePath), HtmlText); } } // Write the project file using (StreamWriter Writer = new StreamWriter(Path.Combine(ChmDir, ProjectFileName))) { Writer.WriteLine("[OPTIONS]"); Writer.WriteLine("Title=UE4 API Documentation"); Writer.WriteLine("Binary TOC=Yes"); Writer.WriteLine("Compatibility=1.1 or later"); Writer.WriteLine("Compiled file=API.chm"); Writer.WriteLine("Contents file=" + SitemapContentsFileName); Writer.WriteLine("Index file=" + SitemapIndexFileName); Writer.WriteLine("Default topic=INT\\API\\index.html"); Writer.WriteLine("Full-text search=Yes"); Writer.WriteLine("Display compile progress=Yes"); Writer.WriteLine("Language=0x409 English (United States)"); Writer.WriteLine(); Writer.WriteLine("[FILES]"); foreach (string FilePath in FilePaths) { Writer.WriteLine(FilePath); } foreach (string HtmlFilePath in HtmlFilePaths) { Writer.WriteLine(HtmlFilePath); } } // Compile the project Console.WriteLine("Compiling CHM file..."); using (Process CompilerProcess = new Process()) { CompilerProcess.StartInfo.WorkingDirectory = ChmDir; CompilerProcess.StartInfo.FileName = ChmCompilerPath; CompilerProcess.StartInfo.Arguments = ProjectFileName; CompilerProcess.StartInfo.UseShellExecute = false; CompilerProcess.StartInfo.RedirectStandardOutput = true; CompilerProcess.StartInfo.RedirectStandardError = true; CompilerProcess.OutputDataReceived += ProcessOutputReceived; CompilerProcess.ErrorDataReceived += ProcessOutputReceived; CompilerProcess.Start(); CompilerProcess.BeginOutputReadLine(); CompilerProcess.BeginErrorReadLine(); CompilerProcess.WaitForExit(); } return true; }
static bool BuildBlueprintUdn(string JsonDir, string UdnDir, string SitemapDir, string ArchivePath, string SitemapArchivePath, BuildActions ExecActions) { string ApiDir = Path.Combine(UdnDir, "BlueprintAPI"); if ((ExecActions & BuildActions.Clean) != 0) { Console.WriteLine("Cleaning '{0}'", ApiDir); Utility.SafeDeleteDirectoryContents(ApiDir, true); Utility.SafeDeleteDirectoryContents(SitemapDir, true); } if ((ExecActions & BuildActions.Build) != 0) { Directory.CreateDirectory(ApiDir); Directory.CreateDirectory(SitemapDir); // Read the input json file string JsonFilePath = Path.Combine(JsonDir, "BlueprintAPI.json"); var json = (Dictionary<string, object>)fastJSON.JSON.Instance.Parse(File.ReadAllText(JsonFilePath)); APICategory.LoadTooltips((Dictionary<string, object>)json["Categories"]); // TODO: This path is clearly sketchy as hell, but we'll clean it up later maybe var Actions = (Dictionary<string, object>)((Dictionary<string, object>)((Dictionary<string, object>)((Dictionary<string, object>)json["Actor"])["Palette"])["ActionSet"])["Actions"]; APICategory RootCategory = new APICategory(null, "BlueprintAPI", true); foreach (var Action in Actions) { var CategoryList = Action.Key.Split('|'); var ActionCategory = RootCategory; Debug.Assert(CategoryList.Length > 0); Debug.Assert(CategoryList[0] == "Library"); for (int CategoryIndex = 1; CategoryIndex < CategoryList.Length - 1; ++CategoryIndex) { ActionCategory = ActionCategory.GetSubCategory(CategoryList[CategoryIndex]); } ActionCategory.AddAction(new APIAction(ActionCategory, CategoryList.Last(), (Dictionary<string, object>)Action.Value)); } // Build a list of pages to output List<APIPage> OutputPages = new List<APIPage>(RootCategory.GatherPages().OrderBy(x => x.LinkPath)); // Create the output directory Utility.SafeCreateDirectory(UdnDir); Utility.SafeCreateDirectory(Path.Combine(UdnDir, APIFolder)); // Build the manifest Console.WriteLine("Writing manifest..."); UdnManifest Manifest = new UdnManifest(RootCategory); Manifest.PrintConflicts(); Manifest.Write(Path.Combine(UdnDir, BlueprintAPIFolder + "\\API.manifest")); Console.WriteLine("Categories: " + OutputPages.Count(page => page is APICategory)); Console.WriteLine("Actions: " + OutputPages.Count(page => page is APIAction)); // Write all the pages using (Tracker UdnTracker = new Tracker("Writing UDN pages...", OutputPages.Count)) { foreach (int Idx in UdnTracker.Indices) { APIPage Page = OutputPages[Idx]; // Create the output directory string MemberDirectory = Path.Combine(UdnDir, Page.LinkPath); if (!Directory.Exists(MemberDirectory)) { Directory.CreateDirectory(MemberDirectory); } // Write the page Page.WritePage(Manifest, Path.Combine(MemberDirectory, "index.INT.udn")); } } // Write the sitemap contents Console.WriteLine("Writing sitemap contents..."); RootCategory.WriteSitemapContents(Path.Combine(SitemapDir, "BlueprintAPI.hhc")); // Write the sitemap index Console.WriteLine("Writing sitemap index..."); RootCategory.WriteSitemapIndex(Path.Combine(SitemapDir, "BlueprintAPI.hhk")); } if ((ExecActions & BuildActions.Archive) != 0) { Console.WriteLine("Creating archive '{0}'", ArchivePath); Utility.CreateTgzFromDir(ArchivePath, ApiDir); Console.WriteLine("Creating archive '{0}'", SitemapArchivePath); Utility.CreateTgzFromDir(SitemapArchivePath, SitemapDir); } return true; }
static private void CreateChm(string ChmCompilerPath, string ChmFileName, string Title, string DefaultTopicPath, string ContentsFileName, string IndexFileName, string SourceDir, List<string> FileNames) { Console.WriteLine("CreateChm {0}", ChmFileName); string ProjectName = Path.GetFileNameWithoutExtension(ChmFileName); // Create an intermediate directory string IntermediateDir = Path.Combine(Path.GetDirectoryName(ChmFileName), ProjectName); Directory.CreateDirectory(IntermediateDir); Utility.SafeDeleteDirectoryContents(IntermediateDir, true); // Copy all the files across using (Tracker CopyTracker = new Tracker("Copying files...", FileNames.Count)) { foreach (int Idx in CopyTracker.Indices) { string SourceFileName = Path.Combine(SourceDir, FileNames[Idx]); string TargetFileName = Path.Combine(IntermediateDir, FileNames[Idx]); Directory.CreateDirectory(Path.GetDirectoryName(TargetFileName)); if (SourceFileName.EndsWith(".html", StringComparison.InvariantCultureIgnoreCase)) { string HtmlText = File.ReadAllText(SourceFileName); HtmlText = HtmlText.Replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n", ""); HtmlText = HtmlText.Replace("<div id=\"crumbs_bg\"></div>", ""); const string HeaderEndText = "<!-- end head -->"; int HeaderMinIdx = HtmlText.IndexOf("<div id=\"head\">"); int HeaderMaxIdx = HtmlText.IndexOf(HeaderEndText); HtmlText = HtmlText.Remove(HeaderMinIdx, HeaderMaxIdx + HeaderEndText.Length - HeaderMinIdx); int CrumbsMinIdx = HtmlText.IndexOf("<div class=\"crumbs\">"); if (CrumbsMinIdx >= 0) { int HomeMinIdx = HtmlText.IndexOf("<strong>", CrumbsMinIdx); int HomeMaxIdx = HtmlText.IndexOf(">", HomeMinIdx) + 4; HtmlText = HtmlText.Remove(HomeMinIdx, HomeMaxIdx - HomeMinIdx); } File.WriteAllText(TargetFileName, HtmlText); } else { Utility.SafeCopyFile(SourceFileName, TargetFileName); } } } // Copy the contents and index files Utility.SafeCopyFile(ContentsFileName, Path.Combine(IntermediateDir, ProjectName + ".hhc")); Utility.SafeCopyFile(IndexFileName, Path.Combine(IntermediateDir, ProjectName + ".hhk")); // Write the project file string ProjectFileName = Path.Combine(IntermediateDir, ProjectName + ".hhp"); using (StreamWriter Writer = new StreamWriter(ProjectFileName)) { Writer.WriteLine("[OPTIONS]"); Writer.WriteLine("Title={0}", Title); Writer.WriteLine("Binary TOC=Yes"); Writer.WriteLine("Compatibility=1.1 or later"); Writer.WriteLine("Compiled file={0}", Path.GetFileName(ChmFileName)); Writer.WriteLine("Contents file={0}.hhc", ProjectName); Writer.WriteLine("Index file={0}.hhk", ProjectName); Writer.WriteLine("Default topic={0}", DefaultTopicPath); Writer.WriteLine("Full-text search=Yes"); Writer.WriteLine("Display compile progress=Yes"); Writer.WriteLine("Language=0x409 English (United States)"); Writer.WriteLine("Default Window=MainWindow"); Writer.WriteLine(); Writer.WriteLine("[WINDOWS]"); Writer.WriteLine("MainWindow=\"{0}\",\"{1}.hhc\",\"{1}.hhk\",\"{2}\",\"{2}\",,,,,0x23520,230,0x304e,[10,10,1260,750],,,,,,,0", Title, ProjectName, DefaultTopicPath); Writer.WriteLine(); Writer.WriteLine("[FILES]"); foreach (string FileName in FileNames) { Writer.WriteLine(FileName); } } // Compile the project Console.WriteLine("Compiling CHM file..."); using (Process CompilerProcess = new Process()) { CompilerProcess.StartInfo.WorkingDirectory = IntermediateDir; CompilerProcess.StartInfo.FileName = ChmCompilerPath; CompilerProcess.StartInfo.Arguments = Path.GetFileName(ProjectFileName); CompilerProcess.StartInfo.UseShellExecute = false; CompilerProcess.StartInfo.RedirectStandardOutput = true; CompilerProcess.StartInfo.RedirectStandardError = true; CompilerProcess.OutputDataReceived += ChmOutputReceived; CompilerProcess.ErrorDataReceived += ChmOutputReceived; CompilerProcess.Start(); CompilerProcess.BeginOutputReadLine(); CompilerProcess.BeginErrorReadLine(); CompilerProcess.WaitForExit(); } // Copy it to the final output Utility.SafeCopyFile(Path.Combine(IntermediateDir, ProjectName + ".chm"), ChmFileName); }
static bool BuildCodeUdn(string EngineDir, string XmlDir, string UdnDir, string SitemapDir, string MetadataPath, string ArchivePath, string SitemapArchivePath, List<string> Filters, BuildActions Actions) { string ApiDir = Path.Combine(UdnDir, "API"); if((Actions & BuildActions.Clean) != 0) { Console.WriteLine("Cleaning '{0}'", ApiDir); Utility.SafeDeleteDirectoryContents(ApiDir, true); Utility.SafeDeleteDirectoryContents(SitemapDir, true); } if ((Actions & BuildActions.Build) != 0) { Directory.CreateDirectory(ApiDir); Directory.CreateDirectory(SitemapDir); // Read the metadata MetadataLookup.Load(MetadataPath); // Read the list of modules List<string> InputModules = new List<string>(File.ReadAllLines(Path.Combine(XmlDir, "modules.txt"))); // Build the doxygen modules List<DoxygenModule> Modules = new List<DoxygenModule>(); foreach (string InputModule in InputModules) { Modules.Add(new DoxygenModule(Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(InputModule)), Path.GetDirectoryName(InputModule))); } // Find all the entities if (!bIndexOnly) { Console.WriteLine("Reading Doxygen output..."); // Read the engine module and split it into smaller modules DoxygenModule RootModule = DoxygenModule.Read("UE4", EngineDir, Path.Combine(XmlDir, "xml")); foreach (DoxygenEntity Entity in RootModule.Entities) { DoxygenModule Module = Modules.Find(x => Entity.File.StartsWith(x.BaseSrcDir)); Entity.Module = Module; Module.Entities.Add(Entity); } // Now filter all the entities in each module if (Filters != null && Filters.Count > 0) { FilterEntities(Modules, Filters); } // Remove all the empty modules Modules.RemoveAll(x => x.Entities.Count == 0); } // Create the index page, and all the pages below it APIIndex Index = new APIIndex(Modules); // Build a list of pages to output List<APIPage> OutputPages = new List<APIPage>(Index.GatherPages().OrderBy(x => x.LinkPath)); // Remove any pages that don't want to be written int NumRemoved = OutputPages.RemoveAll(x => !x.ShouldOutputPage()); Console.WriteLine("Removed {0} pages", NumRemoved); // Dump the output stats string StatsPath = Path.Combine(SitemapDir, "Stats.txt"); Console.WriteLine("Writing stats to '" + StatsPath + "'"); Stats NewStats = new Stats(OutputPages.OfType<APIMember>()); NewStats.Write(StatsPath); // Setup the output directory Utility.SafeCreateDirectory(UdnDir); // Build the manifest Console.WriteLine("Writing manifest..."); UdnManifest Manifest = new UdnManifest(Index); Manifest.PrintConflicts(); Manifest.Write(Path.Combine(UdnDir, APIFolder + "\\API.manifest")); // Write all the pages using (Tracker UdnTracker = new Tracker("Writing UDN pages...", OutputPages.Count)) { foreach (int Idx in UdnTracker.Indices) { APIPage Page = OutputPages[Idx]; // Create the output directory string MemberDirectory = Path.Combine(UdnDir, Page.LinkPath); if (!Directory.Exists(MemberDirectory)) { Directory.CreateDirectory(MemberDirectory); } // Write the page Page.WritePage(Manifest, Path.Combine(MemberDirectory, "index.INT.udn")); } } // Write the sitemap contents Console.WriteLine("Writing sitemap contents..."); Index.WriteSitemapContents(Path.Combine(SitemapDir, "API.hhc")); // Write the sitemap index Console.WriteLine("Writing sitemap index..."); Index.WriteSitemapIndex(Path.Combine(SitemapDir, "API.hhk")); } if ((Actions & BuildActions.Archive) != 0) { Console.WriteLine("Creating archive '{0}'", ArchivePath); Utility.CreateTgzFromDir(ArchivePath, ApiDir); Console.WriteLine("Creating archive '{0}'", SitemapArchivePath); Utility.CreateTgzFromDir(SitemapArchivePath, SitemapDir); } return true; }