예제 #1
0
        private void WriteMethods(Type type, MarkdownWriter writer)
        {
            var methods = type.GetMethods(MemberSearchFlags)
                          // Exclude compiler-generated and internal methods
                          .Where(m => !m.IsSpecialName && !m.IsAssembly)
                          // Exclude protected methods when class is sealed
                          .Where(m => type.IsSealed
                                        ? m.IsPublic
                                        : !m.IsPrivate)
                          // Sort alphabetically...
                          .OrderBy(m => m.Name)
                          // ... then by parameter count.
                          .ThenBy(m => m.GetParameters().Length)
                          .ToArray();

            if (methods.Length > 0)
            {
                writer.WriteHeader(3, "Methods");
                foreach (var method in methods)
                {
                    var methodDocs = Docs[ID.GetIDString(method)];

                    // Heading
                    writer.WriteHeader(4, DocUtilities.GetMethodSignature(method, false, false), true);
                    PrintObsoleteWarning(method, writer);
                    Summary(methodDocs, writer);
                    writer.WriteCodeBlock(Lang, DocUtilities.GetMethodSignature(method, true, true));

                    // Parameters
                    WriteParamList(4, method, writer, methodDocs);
                    Returns(4, methodDocs, writer);
                    Remarks(4, methodDocs, writer);
                }
            }
        }
예제 #2
0
        private void WriteConstructors(Type type, MarkdownWriter writer)
        {
            // Constructor list
            var ctors = type.GetConstructors();

            if (ctors.Length > 0)
            {
                writer.WriteHeader(3, "Constructors");

                for (int i = 0; i < ctors.Length; i++)
                {
                    // Heading for constructor section
                    var ctorDocs = Docs[ID.GetIDString(ctors[i])];
                    writer.WriteHeader(4, DocUtilities.GetMethodSignature(ctors[i], false, false));
                    PrintObsoleteWarning(ctors[i], writer);
                    Summary(ctorDocs, writer);

                    // Signature
                    writer.WriteCodeBlock(Lang, DocUtilities.GetMethodSignature(ctors[i], true, true));

                    // Get constructor's parameters and associated docs
                    WriteParamList(5, ctors[i], writer, ctorDocs);
                    Remarks(5, ctorDocs, writer);
                }
            }
        }
예제 #3
0
        public override void BuildDocs(string outputPath)
        {
            outputPath = DocUtilities.ChangeExtension(outputPath, "md");

            // Write markdown file
            using (var writer = new MarkdownWriter(outputPath))
            {
                foreach (var type in Library.ExportedTypes.Where(t => !t.Name.StartsWith("_")).OrderBy(t => t.Name))
                {
                    // Pull XML docs for type
                    var typeDocs = Docs[ID.GetIDString(type)];

                    // Header, e.g. "StringBuilder class (System)"
                    writer.WriteHeader(2, DocUtilities.GetTypeTitle(type, true), true);

                    // Summary and other info
                    PrintObsoleteWarning(type, writer);
                    writer.WriteParagraph($"**Namespace:** {type.Namespace}");
                    writer.WriteParagraph($"**Inheritance:** {DocUtilities.GetInheritanceString(type)}", true);
                    Summary(typeDocs, writer);

                    // Signature
                    writer.WriteCodeBlock(Lang, DocUtilities.GetClassSignature(type));

                    // Members
                    WriteConstructors(type, writer);
                    WriteProperties(type, writer);
                    WriteIndexers(type, writer);
                    WriteFields(type, writer);
                    WriteMethods(type, writer);
                }
            }
        }
예제 #4
0
        private void WriteFields(Type type, MarkdownWriter writer)
        {
            var fields = type.GetFields()
                         .Where(f => !f.IsSpecialName)
                         .OrderBy(f => f.Name)
                         .ToArray();

            if (fields.Length == 0)
            {
                return;
            }

            writer.WriteHeader(3, "Fields");

            for (int i = 0; i < fields.Length; i++)
            {
                var fieldDocs = Docs[ID.GetIDString(fields[i])];
                writer.WriteHeader(4, DocUtilities.GetFieldSignature(fields[i], false));
                PrintObsoleteWarning(fields[i], writer);
                Summary(fieldDocs, writer);

                writer.WriteCodeBlock(Lang, DocUtilities.GetFieldSignature(fields[i], true));

                Remarks(5, fieldDocs, writer);
            }
        }
예제 #5
0
        private void WriteIndexers(Type type, MarkdownWriter writer)
        {
            var indexers = type.GetProperties()
                           .Where(p => p.GetIndexParameters().Length > 0)
                           .OrderBy(p => p.GetIndexParameters().Length)
                           .ToArray();

            if (indexers.Length == 0)
            {
                return;
            }

            writer.WriteHeader(3, "Indexers");

            for (int i = 0; i < indexers.Length; i++)
            {
                var indexDocs = Docs[ID.GetIDString(indexers[i])];
                writer.WriteHeader(4, DocUtilities.GetPropertySignature(indexers[i], false, true, false));
                PrintObsoleteWarning(indexers[i], writer);
                Summary(indexDocs, writer);

                writer.WriteCodeBlock(Lang, DocUtilities.GetPropertySignature(indexers[i], true, true, true));

                Remarks(5, indexDocs, writer);
            }
        }
예제 #6
0
        private void WriteProperties(Type type, MarkdownWriter writer)
        {
            var props = type.GetProperties(MemberSearchFlags)
                        // Show protected members if class is not sealed
                        .Where(p => type.IsSealed
                                        ? (p.CanRead && p.GetMethod.IsPublic) || (p.CanWrite && p.SetMethod.IsPublic)
                                        : (p.CanRead && !p.GetMethod.IsPrivate) || (p.CanWrite && !p.SetMethod.IsPrivate))
                        // Indexers are technically properties, but we want to handle them separately
                        .Where(p => p.GetIndexParameters().Length == 0)
                        // Sort alphabetically
                        .OrderBy(p => p.Name)
                        .ToArray();

            if (props.Length == 0)
            {
                return;
            }

            writer.WriteHeader(3, "Properties");

            for (int i = 0; i < props.Length; i++)
            {
                var propDocs = Docs[ID.GetIDString(props[i])];
                writer.WriteHeader(4, DocUtilities.GetPropertySignature(props[i], false, false, false));
                PrintObsoleteWarning(props[i], writer);
                Summary(propDocs, writer);

                writer.WriteCodeBlock(Lang, DocUtilities.GetPropertySignature(props[i], true, true, true));

                Remarks(5, propDocs, writer);
            }
        }
예제 #7
0
        static void Main(string[] args)
        {
            var paths = Args.GetPaths();

            if (paths.Length == 0 || Args.Help)
            {
                Console.WriteLine($"Usage: {AppDomain.CurrentDomain.FriendlyName} [OPTIONS]... <dll_pathfilename>");
                Console.WriteLine();
                Console.WriteLine($"Options:");
                Console.WriteLine($"  -out <path>    Specifies the path where the docs will be saved.");
                Console.WriteLine($"  -xml <path>    Specifies a custom XML documentation path.");
                Console.WriteLine($"  --slim         Specifies that the docs will be combined into a single .md file.");
                Console.WriteLine($"  --noxml        Don't use XML.");
                Console.WriteLine($"  --mgtable      methods groups in type page will reported in a table with summary foreach method in the group");
                Console.WriteLine($"  --mgspace      space vertically each method when reported in groups");
                Console.WriteLine($"  --proptable    properties in type page will reported in a table with summary foreach");
                return;
            }

            var  dllPath    = Path.GetFullPath(paths[0]);
            var  xmlPath    = Args.Property("xml", DocUtilities.ChangeExtension(dllPath, "xml"));
            var  outputPath = Args.Property("out", "docs");
            var  outputDir  = Path.GetDirectoryName(outputPath);
            bool ignoreXML  = Args.Flag("noxml");

            // Check whether the file even exists
            if (!File.Exists(dllPath))
            {
                Console.WriteLine($"File '{dllPath}' does not exist.");
                return;
            }

            try
            {
                Console.WriteLine("Building docs...");

                var             dll = Assembly.LoadFrom(dllPath);
                DocpalGenerator docpal;
                var             xmlData = new XmlDocument();

                // Load XML document
                if (File.Exists(xmlPath) && !ignoreXML)
                {
                    xmlData.Load(xmlPath);
                    Console.WriteLine($"Found XML: {xmlPath}");
                }
                else
                {
                    Console.WriteLine("No XML docs found, using only assembly...");
                }

                var xmlDocs = new ProjectXmlDocs(xmlData);

                // Determine type of docs generator to use
                if (Args.Flag("slim"))
                {
                    docpal = new DocpalSlim(xmlDocs, dll);
                }
                else
                {
                    docpal = new DocpalPages(xmlDocs, dll);
                }

                Directory.CreateDirectory(outputDir);

                // Run build
                docpal.BuildDocs(outputPath);

                Console.WriteLine("Done, enjoy!");
            }
            catch (Exception e)
            {
                Console.WriteLine($"Unfortunately, there was an error.\n\n{e}");
                Environment.Exit(1);
            }
        }
예제 #8
0
        public override void BuildDocs(string outputPath)
        {
            var pages     = new PageTree("docs");
            var PageTrees = new List <PageTree>();

            foreach (var type in Library.GetExportedTypes())
            {
                var typePath = $"{type.Namespace.Replace('.', '/')}/{DocUtilities.GetURLTitle(type)}";
                var typeData = Docs[ID.GetIDString(type)];

                pages[typePath] = new TypePage(type, typeData, Docs);
                PageTrees.Add(pages.GetNode(typePath));

                // Constructors
                var ctors = type.GetConstructors();
                if (ctors.Length > 0)
                {
                    // Path to ctors group
                    var ctorsGroupPath = $"{typePath}/ctors";

                    var ctorsData = new Dictionary <ConstructorInfo, MemberXmlDocs>();
                    foreach (var ctor in ctors)
                    {
                        var ctorData = Docs[ID.GetIDString(ctor)];
                        ctorsData.Add(ctor, ctorData);
                    }

                    pages[ctorsGroupPath] = new ConstructorsPage(type, ctors, ctorsData);
                    PageTrees.Add(pages.GetNode(ctorsGroupPath));
                }

                // Method groups
                foreach (var methodGroup in type.GetMethods()
                         .Where(m => !m.Name.StartsWith("get_") && !m.Name.StartsWith("set_"))
                         .GroupBy(m => m.Name))
                {
                    // Path to method group
                    var methodGroupPath = $"{typePath}/{methodGroup.Key}";

                    // Map of reflected methods and documentation
                    var methods = new Dictionary <MethodInfo, MemberXmlDocs>();

                    foreach (var method in methodGroup)
                    {
                        var methodData = Docs[ID.GetIDString(method)];
                        methods[method] = methodData;
                    }

                    pages[methodGroupPath] = new MethodGroupPage(type, methodGroup.Key, methods);
                    PageTrees.Add(pages.GetNode(methodGroupPath));
                }

                // Fields
                foreach (var field in type.GetFields().Where(f => (f.IsPublic || !f.IsPrivate) && (!f.DeclaringType.IsEnum || !f.IsSpecialName)))
                {
                    var fieldPath = Path.Combine(typePath, field.Name).Replace('\\', '/');
                    var fieldData = Docs[ID.GetIDString(field)];
                    pages[fieldPath] = new FieldPage(field, fieldData);
                    PageTrees.Add(pages.GetNode(fieldPath));
                }

                // Properties and Indexers
                int numIndexers = 0;
                foreach (var property in type.GetProperties())
                {
                    var propData = Docs[ID.GetIDString(property)];

                    string propPath;
                    if (property.GetIndexParameters().Length > 0)
                    {
                        propPath = $"{typePath}/this/{++numIndexers}";
                    }
                    else
                    {
                        propPath = $"{typePath}/{property.Name}";
                    }

                    pages[propPath] = new PropertyPage(property, propData);
                    PageTrees.Add(pages.GetNode(propPath));
                }
            }

            // Create a task for each document that needs to be exported, run them all at once
            var exportTasks = new Task[PageTrees.Count];

            for (int i = 0; i < PageTrees.Count; i++)
            {
                var node = PageTrees[i];
                exportTasks[i] = Task.Run(() =>
                {
                    var documentDir  = Directory.GetParent($"{outputPath}/{node.Path}").FullName;
                    var documentPath = $"{outputPath}/{node.Path}.md";
                    Directory.CreateDirectory(documentDir);
                    using (var writer = new MarkdownWriter(documentPath))
                    {
                        node.Page.Render(node, writer);
                    }
                });
            }

            // Wait for all export tasks to finish
            Task.WaitAll(exportTasks);
        }
예제 #9
0
파일: Program.cs 프로젝트: vgregor/Docpal
        static void Main(string[] args)
        {
            var paths = Args.GetPaths();

            if (paths.Length == 0)
            {
                Console.WriteLine("No path specified.");
                return;
            }

            var  dllPath    = Path.GetFullPath(paths[0]);
            var  xmlPath    = Args.Property("xml", DocUtilities.ChangeExtension(dllPath, "xml"));
            var  outputPath = Args.Property("out", "docs");
            var  outputDir  = Path.GetDirectoryName(outputPath);
            bool ignoreXML  = Args.Flag("noxml");

            // Check whether the file even exists
            if (!File.Exists(dllPath))
            {
                Console.WriteLine($"File '{dllPath}' does not exist.");
                return;
            }

            try
            {
                Console.WriteLine("Building docs...");

                var             dll = Assembly.LoadFile(dllPath);
                DocpalGenerator docpal;
                var             xmlData = new XmlDocument();

                // Load XML document
                if (File.Exists(xmlPath) && !ignoreXML)
                {
                    xmlData.Load(xmlPath);
                    Console.WriteLine($"Found XML: {xmlPath}");
                }
                else
                {
                    Console.WriteLine("No XML docs found, using only assembly...");
                }

                var xmlDocs = new ProjectXmlDocs(xmlData);

                // Determine type of docs generator to use
                if (Args.Flag("slim"))
                {
                    docpal = new DocpalSlim(xmlDocs, dll);
                }
                else
                {
                    docpal = new DocpalPages(xmlDocs, dll);
                }

                Directory.CreateDirectory(outputDir);

                // Run build
                docpal.BuildDocs(outputPath);

                Console.WriteLine("Done, enjoy!");
            }
            catch (Exception e)
            {
                Console.WriteLine($"Unfortunately, there was an error.\n\n{e}");
                Environment.Exit(1);
            }
        }