Exemple #1
0
        public override string ToString()
        {
            var mb = new MarkdownBuilder();

            mb.HeaderWithCode(2, Beautifier.BeautifyType(type, false));
            mb.AppendLine();

            var desc = commentLookup[type.FullName].FirstOrDefault(x => x.MemberType == MemberType.Type)?.Summary ?? "";

            if (desc != "")
            {
                mb.AppendLine(desc);
            }
            {
                var sb = new StringBuilder();

                var stat = (type.IsAbstract && type.IsSealed) ? "static " : "";
                var abst = (type.IsAbstract && !type.IsInterface && !type.IsSealed) ? "abstract " : "";
                var classOrStructOrEnumOrInterface = type.IsInterface ? "interface" : type.IsEnum ? "enum" : type.IsValueType ? "struct" : "class";

                sb.AppendLine($"public {stat}{abst}{classOrStructOrEnumOrInterface} {Beautifier.BeautifyType(type, true)}");
                var impl = string.Join(", ", new[] { type.BaseType }.Concat(type.GetInterfaces()).Where(x => x != null && x != typeof(object) && x != typeof(ValueType)).Select(x => Beautifier.BeautifyType(x)));
                if (impl != "")
                {
                    sb.AppendLine("    : " + impl);
                }

                mb.Code("csharp", sb.ToString());
            }

            mb.AppendLine();

            if (type.IsEnum)
            {
                var underlyingEnumType = Enum.GetUnderlyingType(type);

                var enums = Enum.GetNames(type)
                            .Select(x => new { Name = x, Value = (Convert.ChangeType(Enum.Parse(type, x), underlyingEnumType)) })
                            .OrderBy(x => x.Value)
                            .ToArray();

                BuildTable(mb, "Enum", enums, commentLookup[type.FullName], x => x.Value.ToString(), x => x.Name, x => x.Name);
            }
            else
            {
                BuildTable(mb, "Fields", GetFields(), commentLookup[type.FullName], x => Beautifier.BeautifyType(x.FieldType), x => x.Name, x => x.Name);
                BuildTable(mb, "Properties", GetProperties(), commentLookup[type.FullName], x => Beautifier.BeautifyType(x.PropertyType), x => x.Name, x => x.Name);
                BuildTable(mb, "Events", GetEvents(), commentLookup[type.FullName], x => Beautifier.BeautifyType(x.EventHandlerType), x => x.Name, x => x.Name);
                BuildTable(mb, "Methods", GetMethods(), commentLookup[type.FullName], x => Beautifier.BeautifyType(x.ReturnType), x => x.Name, x => Beautifier.ToMarkdownMethodInfo(x));
                BuildTable(mb, "Static Fields", GetStaticFields(), commentLookup[type.FullName], x => Beautifier.BeautifyType(x.FieldType), x => x.Name, x => x.Name);
                BuildTable(mb, "Static Properties", GetStaticProperties(), commentLookup[type.FullName], x => Beautifier.BeautifyType(x.PropertyType), x => x.Name, x => x.Name);
                BuildTable(mb, "Static Methods", GetStaticMethods(), commentLookup[type.FullName], x => Beautifier.BeautifyType(x.ReturnType), x => x.Name, x => Beautifier.ToMarkdownMethodInfo(x));
                BuildTable(mb, "Static Events", GetStaticEvents(), commentLookup[type.FullName], x => Beautifier.BeautifyType(x.EventHandlerType), x => x.Name, x => x.Name);
            }

            return(mb.ToString());
        }
        // put dll & xml on same diretory.
        private static void Main(string[] args)
        {
            //output path for documentation
            var dest = "md";
            //namespace regex
            var namespaceMatch = "*.Controllers";
            //class regex
            var classMatch = ".*Controller";
            //dll path which will be documented
            var dllPath = @"C:\example\example.dll";

            var assembly                 = Assembly.LoadFrom(dllPath);
            var commentsLookup           = MarkdownGenerator.GetCommentsLookup(assembly);
            var referencedModelContainer = new ReferencedModelContainer(commentsLookup);
            var types = MarkdownGenerator.Load(assembly, namespaceMatch, classMatch, referencedModelContainer, commentsLookup);

            // Home Markdown Builder
            var homeBuilder = new MarkdownBuilder();

            homeBuilder.Header(1, "References");
            homeBuilder.AppendLine();

            foreach (var g in types.GroupBy(x => x.Namespace).OrderBy(x => x.Key))
            {
                if (!Directory.Exists(dest))
                {
                    Directory.CreateDirectory(dest);
                }

                homeBuilder.HeaderWithLink(2, g.Key, g.Key);
                homeBuilder.AppendLine();

                var mb = new MarkdownBuilder();
                mb.Header(1, "Usage Documentation");
                mb.Header(2, "Controllers and Actions");
                foreach (var item in g.OrderBy(x => x.Name))
                {
                    homeBuilder.ListLink(MarkdownBuilder.MarkdownCodeQuote(item.BeautifyName), g.Key + "#" + item.BeautifyName.Replace("<", "").Replace(">", "").Replace(",", "").Replace(" ", "-").ToLower());

                    mb.Append(item.ToString());
                }
                mb.Header(2, "Referenced Types");
                mb.Append(referencedModelContainer.ToString());
                var result = Markdig.Markdown.Normalize(mb.ToString());
                File.WriteAllText(Path.Combine(dest, g.Key + ".md"), result);
                homeBuilder.AppendLine();
            }

            // Gen Home
            File.WriteAllText(Path.Combine(dest, "Home.md"), homeBuilder.ToString());
        }
Exemple #3
0
        public override string ToString()
        {
            var mb = new MarkdownBuilder();

            var isController = _type.Name.EndsWith("Controller");

            mb.Header(isController ? 3 : 4, _markdownableTypeName.AsHeader());
            mb.AppendLine();

            var desc = _commentLookup[_type.FullName].FirstOrDefault(x => x.MemberType == MemberType.Type)?.Summary ?? "";

            if (desc != "")
            {
                mb.AppendLine(desc);
            }

            mb.AppendLine();

            if (isController)
            {
                foreach (var method in GetMethods())
                {
                    var methodInfo = _beautifier.ToMarkdownMethodInfo(method, _type, _type.Name.Substring(0, _type.Name.Length - "Controller".Length));
                    mb.AppendLine(methodInfo);
                }
            }
            else if (_type.IsEnum)
            {
                var underlyingEnumType = Enum.GetUnderlyingType(_type);

                var enums = Enum.GetNames(_type)
                            .Select(x => new { Name = x, Value = (Convert.ChangeType(Enum.Parse(_type, x), underlyingEnumType)) })
                            .OrderBy(x => x.Value)
                            .ToArray();

                BuildTable(mb, "Enum", enums, _commentLookup[_type.FullName], x => x.Value.ToString(), x => x.Name, x => x.Name);
            }
            else
            {
                BuildTable(mb, "Fields", GetFields(), _commentLookup[_type.FullName], x => new MarkdownableTypeName(x.FieldType).AsLink(), x => x.Name, x => x.Name);
                BuildTable(mb, "Properties", GetProperties(), _commentLookup[_type.FullName], x => new MarkdownableTypeName(x.PropertyType).AsLink(), x => x.Name, x => x.Name);
            }

            return(mb.ToString());
        }
        private string GenericAsLink()
        {
            var typeName = Regex.Replace(_genericType.Name, @"`.+$", "");
            var md       = new MarkdownBuilder();

            if (_isCursorLink)
            {
                var link = $@"{typeName}{LtChar}{string.Join(",", _args.Select(c => c.Name))}{GtChar}";
                md.CursorLink(link);
            }
            else
            {
                md.Append(typeName);
                md.Append(LtChar);
                md.Append(string.Join(",", _args.Select(c => new MarkdownableTypeName(c).AsLink())));
                md.Append(GtChar);
            }
            return(md.ToString());
        }
Exemple #5
0
        private static void GenerateMarkdown(string target, string destination)
        {
            Console.WriteLine($"Generating markdown in location: {destination}");

            var types = MarkdownGenerator.Load(target, string.Empty);

            // Home Markdown Builder
            var homeBuilder = new MarkdownBuilder();

            homeBuilder.Header(1, "References");
            homeBuilder.AppendLine();

            foreach (var g in types.GroupBy(x => x.Namespace).OrderBy(x => x.Key))
            {
                if (!Directory.Exists(destination))
                {
                    Directory.CreateDirectory(destination);
                }

                homeBuilder.HeaderWithLink(2, g.Key, g.Key);
                homeBuilder.AppendLine();

                var sb = new StringBuilder();
                foreach (var item in g.OrderBy(x => x.Name))
                {
                    homeBuilder.ListLink(MarkdownBuilder.MarkdownCodeQuote(item.BeautifyName), g.Key + "#" + item.BeautifyName.Replace("<", "").Replace(">", "").Replace(",", "").Replace(" ", "-").ToLower());

                    sb.Append(item.ToString());
                }

                File.WriteAllText(Path.Combine(destination, g.Key + ".md"), sb.ToString());
                homeBuilder.AppendLine();
            }

            // Gen Home
            File.WriteAllText(Path.Combine(destination, "Home.md"), homeBuilder.ToString());
        }
        public string ToMarkdownMethodInfo(MethodInfo methodInfo, Type type, string controller)
        {
            var isExtension = methodInfo.GetCustomAttributes <System.Runtime.CompilerServices.ExtensionAttribute>(false).Any();

            var seq = methodInfo.GetParameters().Select(x =>
            {
                var suffix = x.HasDefaultValue ? (" = " + (x.DefaultValue ?? $"null")) : "";
                _referencedModelContainer.AddType(x.ParameterType);
                return($"{new MarkdownableTypeName(x.ParameterType).AsLink()} {x.Name}{suffix}");
            });

            var mb = new MarkdownBuilder();

            var coreAttributes    = methodInfo.GetCustomAttributes <ProducesResponseTypeAttribute>();
            var swaggerAttributes = methodInfo.GetCustomAttributes <SwaggerResponseAttribute>();

            //TODO get this from route also
            mb.Header(4, $"{controller}/{methodInfo.Name}");
            mb.AppendLine($"- {methodInfo.Name}({(isExtension ? "this " : "")}{string.Join(", ", seq)})").AppendLine();

            var documentation = _commentLookup[type.FullName]
                                .FirstOrDefault(c => c.MemberType == MemberType.Method && c.MemberName == methodInfo.Name)
                                ?.Summary;

            if (documentation != null)
            {
                mb.AppendLine(documentation);
                mb.AppendLine();
            }

            var headers = new[] {
                "StatusCode",
                "ReturnType",
                "Description"
            };

            var actionDescriptions = new List <string[]>();

            if (coreAttributes.Any())
            {
                foreach (var attribute in coreAttributes)
                {
                    actionDescriptions.Add(new[] {
                        attribute.StatusCode.ToString(),
                        new MarkdownableTypeName(attribute.Type).AsLink(),
                        ""
                    });
                    if (attribute.Type != null)
                    {
                        _referencedModelContainer.AddType(attribute.Type);
                    }
                }
            }
            else if (swaggerAttributes.Any())
            {
                foreach (var attribute in swaggerAttributes)
                {
                    actionDescriptions.Add(new[] {
                        attribute.StatusCode.ToString(),
                        new MarkdownableTypeName(attribute.Type).AsLink(),
                        attribute.Description
                    });
                    if (attribute.Type != null)
                    {
                        _referencedModelContainer.AddType(attribute.Type);
                    }
                }
            }

            mb.Table(headers, actionDescriptions);

            return(mb.ToString());
        }
        public override string ToString()
        {
            MarkdownBuilder mb = new MarkdownBuilder();

            mb.HeaderWithCode(1, Beautifier.BeautifyType(type));
            mb.AppendLine();

            string desc = commentLookup[type.FullName].FirstOrDefault(x => x.MemberType == MemberType.Type)?.Summary ??
                          "";

            if (desc != "")
            {
                mb.AppendLine(desc);
            }
            {
                StringBuilder sb = new StringBuilder();

                string stat = type.IsAbstract && type.IsSealed ? "static " : "";
                string abst = type.IsAbstract && !type.IsInterface && !type.IsSealed ? "abstract " : "";
                string classOrStructOrEnumOrInterface = type.IsInterface
                    ? "interface"
                    : type.IsEnum
                        ? "enum"
                        : type.IsValueType
                            ? "struct"
                            : "class";

                sb.AppendLine(
                    $"public {stat}{abst}{classOrStructOrEnumOrInterface} {Beautifier.BeautifyType(type, true)}");
                string impl = string.Join(
                    ", ",
                    new[] { type.BaseType }.Concat(type.GetInterfaces())
                    .Where(x => x != null && x != typeof(object) && x != typeof(ValueType))
                    .Select(x => Beautifier.BeautifyType(x)));
                if (impl != "")
                {
                    sb.AppendLine("    : " + impl);
                }

                mb.Code("csharp", sb.ToString());
            }

            mb.AppendLine();

            if (type.IsEnum)
            {
                Type underlyingEnumType = Enum.GetUnderlyingType(type);

                var enums = Enum.GetNames(type)
                            .Select(
                    x => new
                {
                    Name  = x,
                    Value = Convert.ChangeType(Enum.Parse(type, x), underlyingEnumType)
                })
                            .OrderBy(x => x.Value)
                            .ToArray();

                BuildTable(
                    mb, "Enum", enums, x => x.Value.ToString(), x => x.Name, x => x.Name, (info, comment) => true);
            }
            else
            {
                BuildTable(
                    mb, "Constructors", GetConstructors(type),
                    x => x.Name, x => "#ctor", Beautifier.ToMarkdownConstructorInfo, (info, comment) =>
                {
                    ParameterInfo[] param = info.GetParameters();
                    return(param.Length == comment.Parameters.Count && param.All(
                               p =>
                    {
                        return comment.Parameters.ContainsKey(p.Name);
                    }));
                });
                BuildTable(
                    mb, "Fields", GetFields(type),
                    x => Beautifier.BeautifyType(x.FieldType),
                    x => x.Name, x => x.Name, (info, comment) => true);
                BuildTable(
                    mb, "Properties", GetProperties(type),
                    x => Beautifier.BeautifyType(x.PropertyType), x => x.Name, x => x.Name, (info, comment) => true);
                BuildTable(
                    mb, "Events", GetEvents(type),
                    x => Beautifier.BeautifyType(x.EventHandlerType), x => x.Name, x => x.Name,
                    (info, comment) => true);
                BuildTable(
                    mb, "Methods", GetMethods(type),
                    x => Beautifier.BeautifyType(x.ReturnType), x => x.Name, Beautifier.ToMarkdownMethodInfo,
                    (info, comment) =>
                {
                    ParameterInfo[] param = info.GetParameters();
                    return(param.Length == comment.Parameters.Count && param.All(
                               p =>
                    {
                        return comment.Parameters.ContainsKey(p.Name);
                    }));
                });
                BuildTable(
                    mb, "Static Fields", GetStaticFields(type),
                    x => Beautifier.BeautifyType(x.FieldType), x => x.Name, x => x.Name, (info, comment) => true);
                BuildTable(
                    mb, "Static Properties", GetStaticProperties(type),
                    x => Beautifier.BeautifyType(x.PropertyType), x => x.Name, x => x.Name, (info, comment) => true);
                BuildTable(
                    mb, "Static Methods", GetStaticMethods(type),
                    x => Beautifier.BeautifyType(x.ReturnType), x => x.Name, Beautifier.ToMarkdownMethodInfo,
                    (info, comment) =>
                {
                    ParameterInfo[] param = info.GetParameters();
                    return(param.Length == comment.Parameters.Count && param.All(
                               p =>
                    {
                        return comment.Parameters.ContainsKey(p.Name);
                    }));
                });
                BuildTable(
                    mb, "Static Events", GetStaticEvents(type),
                    x => Beautifier.BeautifyType(x.EventHandlerType), x => x.Name, x => x.Name,
                    (info, comment) => true);
            }

            return(mb.ToString());
        }
        // 0 = dll src path, 1 = dest root
        private static void Main(string[] args)
        {
            // put dll & xml on same diretory.
            string target         = string.Empty;
            string dest           = "md";
            string namespaceMatch = string.Empty;

            switch (args.Length)
            {
            case 1:
                target = args[0];
                break;

            case 2:
                target = args[0];
                dest   = args[1];
                break;

            case 3:
                target         = args[0];
                dest           = args[1];
                namespaceMatch = args[2];
                break;
            }
            AppDomain.CurrentDomain.AssemblyResolve += (s, a) =>
            {
                string archSpecificPath = Path.Combine(
                    Directory.GetParent(target).FullName,
                    Environment.Is64BitProcess ? "x64" : "x86", a.Name.Split(new[] { ',' }, 2)[0] + ".dll");
                return(File.Exists(archSpecificPath)
                    ? Assembly.LoadFile(archSpecificPath)
                    : null);
            };
            MarkdownableType[] types = MarkdownGenerator.Load(target, namespaceMatch);

            // Home Markdown Builder
            MarkdownBuilder homeBuilder = new MarkdownBuilder();

            homeBuilder.Header(1, "References");
            homeBuilder.AppendLine();

            MarkdownBuilder sidebarBuilder = new MarkdownBuilder();

            foreach (IGrouping <string, MarkdownableType> g in types.GroupBy(x => x.Namespace).OrderBy(x => x.Key))
            {
                if (!Directory.Exists(dest))
                {
                    Directory.CreateDirectory(dest);
                }

                homeBuilder.HeaderWithLink(2, g.Key, g.Key);
                homeBuilder.AppendLine();

                sidebarBuilder.HeaderWithLink(5, g.Key, g.Key);
                sidebarBuilder.AppendLine();

                StringBuilder sb = new StringBuilder();
                foreach (MarkdownableType item in g.OrderBy(x => x.Name))
                {
                    homeBuilder.ListLink(
                        MarkdownBuilder.MarkdownCodeQuote(item.BeautifyName),
                        g.Key + "#" + item.BeautifyName.Replace("<", "")
                        .Replace(">", "")
                        .Replace(",", "")
                        .Replace(" ", "-")
                        .ToLower());
                    sidebarBuilder.ListLink(
                        MarkdownBuilder.MarkdownCodeQuote(item.BeautifyName),
                        g.Key + "#" + item.BeautifyName.Replace("<", "")
                        .Replace(">", "")
                        .Replace(",", "")
                        .Replace(" ", "-")
                        .ToLower());

                    sb.Append(item);
                }

                File.WriteAllText(Path.Combine(dest, g.Key + ".md"), sb.ToString());
                homeBuilder.AppendLine();
                sidebarBuilder.AppendLine();
            }

            // Gen Home
            File.WriteAllText(Path.Combine(dest, "Home.md"), homeBuilder.ToString());

            // Gen sidebar
            File.WriteAllText(Path.Combine(dest, "_Sidebar.md"), sidebarBuilder.ToString());

            File.WriteAllText(
                Path.Combine(dest, "_Footer.md"),
                $@"*** 
#### auto generated wiki!<br/>all changes can be removed within next update
_Copyright (c) {DateTime.Now.Year} exomia_
");
        }