Beispiel #1
0
        private static void CreateNodeDocs(XmlElement Root, string OutputDir, string SourceDir, SaxonXform ClassXform, string tag)
        {
            XmlNodeList nodeList = Root.GetElementsByTagName(tag);

            foreach (XmlNode item in nodeList)
            {
                string ClassTitle  = item["id"].InnerText;
                string ClassFolder = Path.Combine(SourceDir, $"{ClassTitle}\\");

                // Skip generation of a separate class instance for the enum/struct group classes
                if (ClassTitle.Equals("UEnum") || ClassTitle.Equals("UUserDefinedEnum") ||
                    ClassTitle.Equals("UScriptStruct") || ClassTitle.Equals("UUserDefinedStruct"))
                {
                    continue;
                }

                string OutputClassDir = Path.Combine(OutputDir, ClassTitle);
                SafeCreateDirectory(OutputClassDir);

                string OutputClassPath = Path.Combine(OutputClassDir, $"{ClassTitle}.html");
                ClassXform.TransformXml(Path.Combine(ClassFolder, $"{ClassTitle}.xml"), OutputClassPath);

                //Copy the images for this class to the output directory

                CopyWholeDirectory(Path.Combine(ClassFolder, "img"), Path.Combine(OutputClassDir, "img"));
            }
        }
        static void Main(string[] args)
        {
            List <string> ArgumentList = new List <string>(args);

            Console.WriteLine("KantanDocGen invoked with arguments:");
            foreach (string Arg in ArgumentList)
            {
                Console.WriteLine(Arg);
            }

            string DocsTitle = ParseArgumentValue(ArgumentList, "-name=", null);

            if (DocsTitle == null)
            {
                Console.WriteLine("KantanDocGen: Error: Documentation title (-name=) required. Aborting.");
                return;
            }

            // Get the default paths

            // If unspecified, assume the directory containing our binary is one level below the base directory
            string DocGenBaseDir = ParseArgumentDirectory(ArgumentList, "-basedir=", Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), ".."));
            string OutputRoot    = ParseArgumentDirectory(ArgumentList, "-outputdir=", Directory.GetCurrentDirectory());
            string OutputDir     = Path.Combine(OutputRoot, DocsTitle);

            //string MsxslPath = ParseArgumentPath(ArgumentList, "-xslproc=", Path.Combine(EngineDir, "Binaries/ThirdParty/Msxsl/msxsl.exe"));

            // Xsl transform files - if not specified explicitly, look for defaults relative to base directory
            string IndexTransformPath = ParseArgumentPath(ArgumentList, "-indexxsl=", Path.Combine(DocGenBaseDir, "xslt/index_xform.xsl"));
            string ClassTransformPath = ParseArgumentPath(ArgumentList, "-classxsl=", Path.Combine(DocGenBaseDir, "xslt/class_docs_xform.xsl"));
            string NodeTransformPath  = ParseArgumentPath(ArgumentList, "-nodexsl=", Path.Combine(DocGenBaseDir, "xslt/node_docs_xform.xsl"));

            bool   bFromIntermediate = ArgumentList.Contains("-fromintermediate");
            string IntermediateDir;

            if (bFromIntermediate)
            {
                // Intermediate docs already created, we need to have been passed an intermediate directory to locate them
                IntermediateDir = ParseArgumentDirectory(ArgumentList, "-intermediatedir=", null);
                if (IntermediateDir == null)
                {
                    Console.WriteLine("KantanDocGen: Error: -fromintermediate requires -intermediatedir to be set. Aborting.");
                    return;
                }

                if (!Directory.Exists(IntermediateDir))
                {
                    Console.WriteLine("KantanDocGen: Error: Specified intermediate directory not found. Aborting.");
                    return;
                }
            }
            else
            {
                // @TODO: This doesn't work, since commandlet cannot create Slate windows!
                // Can reenable this path if manage to get a Program target type to build against the engine.
                Console.WriteLine("KantanDocGen: Error: Calling without -fromintermediate currently not supported. Use the KantanDocGen engine plugin to generate documentation.");
                return;

/*				IntermediateDir = ParseArgumentDirectory(ArgumentList, "-intermediatedir=", Path.Combine(EngineDir, "Intermediate\\KantanDocGen"));
 *
 *                              // Need to generate intermediate docs first
 *                              // Run editor commandlet to generate XML and image files
 *                              string EditorPath = Path.Combine(EngineDir, "Binaries\\Win64\\UE4Editor-Cmd.exe");
 *                              if (!RunXmlDocGenCommandlet(EngineDir, EditorPath, IntermediateDir))
 *                              {
 *                                      return;
 *                              }
 */         }

            const bool bCleanOutput = true;
            bool       bHardClean   = ArgumentList.Contains("-cleanoutput");

            if (bCleanOutput)
            {
                // If the output directory exists, attempt to delete it (this will fail if bHardClean is false and the directory contains files/subfolders)
                if (Directory.Exists(OutputDir))
                {
                    try
                    {
                        Directory.Delete(OutputDir, bHardClean);
                    }
                    catch (Exception)
                    {
                        Console.WriteLine("KantanDocGen: Error: Output directory '{0}' exists and not empty/couldn't delete. Remove and rerun, or specify -cleanoutput (If running from plugin console, add 'clean' parameter).", OutputDir);
                        return;
                    }
                }
            }

            //var XslXform = new MsxslXform(MsxslPath);
            var IndexXform = new SaxonXform();
            var ClassXform = new SaxonXform();
            var NodeXform  = new SaxonXform();

            // Initialize the transformations
            if (!IndexXform.Initialize(IndexTransformPath, ProcessOutputReceived))
            {
                Console.WriteLine("Error: Failed to initialize xslt processor.");
                return;
            }
            if (!ClassXform.Initialize(ClassTransformPath, ProcessOutputReceived))
            {
                Console.WriteLine("Error: Failed to initialize xslt processor.");
                return;
            }
            if (!NodeXform.Initialize(NodeTransformPath, ProcessOutputReceived))
            {
                Console.WriteLine("Error: Failed to initialize xslt processor.");
                return;
            }

            // Loop over all generated xml files and apply the transformation
            int Success = 0;
            int Failed  = 0;
            // @TODO: Should iterate over index/class xml entries rather than enumerate files and directories
            var SubFolders = Directory.EnumerateDirectories(IntermediateDir);

            foreach (string Sub in SubFolders)
            {
                string ClassTitle     = Path.GetFileName(Sub);
                string OutputClassDir = Path.Combine(OutputDir, ClassTitle);
                SafeCreateDirectory(OutputClassDir);
                string NodeDir = Path.Combine(Sub, "nodes");
                if (Directory.Exists(NodeDir))
                {
                    string OutputNodesDir = Path.Combine(OutputClassDir, "nodes");
                    SafeCreateDirectory(OutputNodesDir);

                    var InputFiles = Directory.EnumerateFiles(NodeDir, "*.xml", SearchOption.TopDirectoryOnly);
                    foreach (string FilePath in InputFiles)
                    {
                        string FileTitle  = Path.GetFileNameWithoutExtension(FilePath);
                        string OutputPath = Path.Combine(OutputNodesDir, FileTitle + ".html");

                        string InputPath = FilePath;
                        if (!NodeXform.TransformXml(InputPath, OutputPath))
                        {
                            Console.WriteLine("Error: Xsl transform failed for file {0} - skipping.", InputPath);
                            ++Failed;
                            continue;
                        }

                        ++Success;
                    }

                    string OutputClassPath = Path.Combine(OutputClassDir, ClassTitle + ".html");
                    ClassXform.TransformXml(Path.Combine(Sub, ClassTitle + ".xml"), OutputClassPath);
                }

                // Copy the images for this class to the output directory
                CopyWholeDirectory(Path.Combine(Sub, "img"), Path.Combine(OutputClassDir, "img"));
            }

            string OutputIndexPath = Path.Combine(OutputDir, "index.html");

            IndexXform.TransformXml(Path.Combine(IntermediateDir, "index.xml"), OutputIndexPath);

            CopyWholeDirectory(Path.Combine(DocGenBaseDir, "css"), Path.Combine(OutputDir, "css"));

            Console.WriteLine("KantanDocGen completed:");
            Console.WriteLine("{0} node docs successfully transformed.", Success);
            Console.WriteLine("{0} failed.", Failed);
        }
Beispiel #3
0
        static void Main(string[] args)
        {
            List <string> ArgumentList = new List <string>(args);

            Console.WriteLine("KantanDocGen invoked with arguments:");
            foreach (string Arg in ArgumentList)
            {
                Console.WriteLine(Arg);
            }

            // Get the default paths

            // If unspecified, assume the directory containing our binary is one level below the base directory
            string DocGenBaseDir = ParseArgumentDirectory(ArgumentList, "-basedir=", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
            string OutputDir     = ParseArgumentDirectory(ArgumentList, "-outputdir=", Directory.GetCurrentDirectory());

            //string MsxslPath = ParseArgumentPath(ArgumentList, "-xslproc=", Path.Combine(EngineDir, "Binaries/ThirdParty/Msxsl/msxsl.exe"));

            // Xsl transform files - if not specified explicitly, look for defaults relative to base directory
            string IndexTransformPath, ClassTransformPath, NodeTransformPath;

            IndexTransformPath = ParseArgumentPath(ArgumentList, "-indexxsl=", Path.Combine(DocGenBaseDir, "DeploymentFiles/xslt/index_xform.xsl"));
            ClassTransformPath = ParseArgumentPath(ArgumentList, "-classxsl=", Path.Combine(DocGenBaseDir, "DeploymentFiles/xslt/class_docs_xform.xsl"));
            NodeTransformPath  = ParseArgumentPath(ArgumentList, "-nodexsl=", Path.Combine(DocGenBaseDir, "DeploymentFiles/xslt/node_docs_xform.xsl"));

            string SourceDir;

            // Intermediate docs already created, we need to have been passed an intermediate directory to locate them
            SourceDir = ParseArgumentDirectory(ArgumentList, "-sourcedir=", null);
            if (SourceDir == null)
            {
                Console.WriteLine("KantanDocGen: Error: -sourcedir is required. Aborting.");
                return;
            }

            if (!Directory.Exists(SourceDir))
            {
                Console.WriteLine("KantanDocGen: Error: Specified source directory not found. Aborting.");
                return;
            }

            const bool bCleanOutput = true;
            bool       bHardClean   = ArgumentList.Contains("-cleanoutput");

            if (bCleanOutput)
            {
                // If the output directory exists, attempt to delete it (this will fail if bHardClean is false and the directory contains files/subfolders)
                if (Directory.Exists(OutputDir))
                {
                    try
                    {
                        Directory.Delete(OutputDir, true);
                    }
                    catch (Exception)
                    {
                        Console.WriteLine("KantanDocGen: Error: Output directory '{0}' exists and not empty/couldn't delete. Remove and rerun, or specify -cleanoutput (If running from plugin console, add 'clean' parameter).", OutputDir);
                        return;
                    }
                }
            }



            // Loop over all generated xml files and apply the transformation
            int Success = 0;
            int Failed  = 0;

            XmlDocument indexXMLDoc = new XmlDocument();

            indexXMLDoc.Load(Path.Combine(SourceDir, "index.xml"));
            XmlElement indexRoot = indexXMLDoc.DocumentElement;

            foreach (XmlNode item in indexRoot.GetElementsByTagName("class"))
            {
                string ClassTitle  = item["id"].InnerText;
                string ClassFolder = Path.Combine(SourceDir, $"{ClassTitle}\\");
                string NodeDir     = Path.Combine(ClassFolder, "nodes\\");


                XmlDocument doc = new XmlDocument();
                doc.Load(Path.Combine(ClassFolder, $"{ClassTitle}.xml"));
                XmlElement root = doc.DocumentElement;
                //XmlNode nodesNode = root.SelectSingleNode("descendant::nodes");

                root.RemoveChild(root.LastChild);

                if (Directory.Exists(NodeDir))
                {
                    XmlElement functionListElement = doc.CreateElement("FunctionList");

                    var InputFiles = Directory.EnumerateFiles(NodeDir, "*.xml", SearchOption.TopDirectoryOnly);

                    foreach (string FilePath in InputFiles)
                    {
                        XmlElement functionRoot = doc.CreateElement("Function");

                        XmlDocument functionDoc = new XmlDocument();
                        functionDoc.Load(FilePath);

                        foreach (XmlNode childElement in functionDoc.DocumentElement.ChildNodes)
                        {
                            //XmlNode nodeCopy = childElement.CloneNode(true);
                            XmlNode nodeCopy = doc.ImportNode(childElement, true);
                            functionRoot.AppendChild(nodeCopy);
                        }
                        doc.ImportNode(functionRoot, true);
                        functionListElement.AppendChild(functionRoot);

                        ++Success;
                    }

                    root.AppendChild(functionListElement);
                    doc.Save(Path.Combine(ClassFolder, $"{ClassTitle}.xml"));
                }

                XmlElement saveGame = indexXMLDoc.CreateElement("savegame");
                saveGame.InnerText = doc.DocumentElement["savegame"].InnerText;
                item.AppendChild(saveGame);

                XmlElement refactor = indexXMLDoc.CreateElement("refactor");
                refactor.InnerText = doc.DocumentElement["refactor"].InnerText;
                item.AppendChild(refactor);

                XmlElement shortTooltip = indexXMLDoc.CreateElement("short_tooltip");
                shortTooltip.InnerText = doc.DocumentElement["short_tooltip"].InnerText;
                item.AppendChild(shortTooltip);

                XmlElement native = indexXMLDoc.CreateElement("native");
                native.InnerText = doc.DocumentElement["native"].InnerText;
                item.AppendChild(native);
            }

            string nativeEnumPath = Path.Combine(SourceDir, "UEnum\\UEnum.xml");

            AddEnums(nativeEnumPath, ref indexXMLDoc, true);

            string bpEnumPath = Path.Combine(SourceDir, "UUserDefinedEnum\\UUserDefinedEnum.xml");

            AddEnums(bpEnumPath, ref indexXMLDoc, false);

            string nativeStructPath = Path.Combine(SourceDir, "UScriptStruct\\UScriptStruct.xml");

            AddStructs(nativeStructPath, ref indexXMLDoc, true);

            string bpStructPath = Path.Combine(SourceDir, "UUserDefinedStruct\\UUserDefinedStruct.xml");

            AddStructs(bpStructPath, ref indexXMLDoc, false);

            indexXMLDoc.Save(Path.Combine(SourceDir, "index_adjusted.xml"));

            SafeCreateDirectory(OutputDir);
            string OutputIndexPath = Path.Combine(OutputDir, "index.html");

            var IndexXform = new SaxonXform();
            var ClassXform = new SaxonXform();
            var NodeXform  = new SaxonXform();

            // Initialize the transformations
            if (!IndexXform.Initialize(IndexTransformPath, ProcessOutputReceived))
            {
                Console.WriteLine("Error: Failed to initialize xslt processor.");
                return;
            }
            if (!ClassXform.Initialize(ClassTransformPath, ProcessOutputReceived))
            {
                Console.WriteLine("Error: Failed to initialize xslt processor.");
                return;
            }
            if (!NodeXform.Initialize(NodeTransformPath, ProcessOutputReceived))
            {
                Console.WriteLine("Error: Failed to initialize xslt processor.");
                return;
            }

            IndexXform.TransformXml(Path.Combine(SourceDir, "index_adjusted.xml"), OutputIndexPath);

            // @TODO: Should iterate over index/class xml entries rather than enumerate files and directories
            var SubFolders = Directory.EnumerateDirectories(SourceDir);

            CreateNodeDocs(indexRoot, OutputDir, SourceDir, ClassXform, "class");
            CreateNodeDocs(indexRoot, OutputDir, SourceDir, ClassXform, "enum");
            CreateNodeDocs(indexRoot, OutputDir, SourceDir, ClassXform, "struct");

            //debug
            CopyWholeDirectory(Path.Combine(DocGenBaseDir, "DeploymentFiles/css"), Path.Combine(OutputDir, "css"));
            CopyWholeDirectory(Path.Combine(DocGenBaseDir, "DeploymentFiles/img"), Path.Combine(OutputDir, "img"));
            CopyWholeDirectory(Path.Combine(DocGenBaseDir, "DeploymentFiles/javascript"), Path.Combine(OutputDir, "javascript"));


            Console.WriteLine("KantanDocGen completed:");
            Console.WriteLine("{0} node docs successfully transformed.", Success);
            Console.WriteLine("{0} failed.", Failed);
        }