private void BuildTable <T>(MarkdownBuilder mb, string label, T[] array, IEnumerable <XmlDocumentComment> docs, Func <T, string> type, Func <T, string> name, Func <T, string> finalName) { if (array.Any()) { mb.AppendLine(label); mb.AppendLine(); string[] head = (this._type.IsEnum) ? new[] { "Value", "Name", "Summary" } : new[] { "Type", "Name", "Summary" }; IEnumerable <T> seq = array; if (!this._type.IsEnum) { seq = array.OrderBy(x => name(x)); } var data = seq.Select(item2 => { var summary = docs.FirstOrDefault(x => x.MemberName == name(item2) || x.MemberName.StartsWith(name(item2) + "`"))?.Summary ?? ""; var typeText = type(item2); return(new[] { typeText.Contains('[') ? typeText : MarkdownBuilder.MarkdownCodeQuote(typeText), finalName(item2), summary }); }); mb.Table(head, data); } }
// 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()); }
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()); }
private void BuildTable <T>(MarkdownBuilder mb, string label, T[] array, Func <T, string> type, Func <T, string> name, Func <T, string> finalName, Func <T, XmlDocumentComment, bool> get) { if (array.Any()) { mb.Header(2, label); mb.AppendLine(); IEnumerable <T> seq = array; if (!this.type.IsEnum) { seq = array.OrderBy(name); } IEnumerable <MarkdownBuilder.DropdownItem> data = seq.Select( item2 => { XmlDocumentComment _lookupInterfaces(Type t) { XmlDocumentComment lookup = null; Type[] interfaces = t.GetInterfaces(); for (int i = 0; i < interfaces.Length && lookup == null; i++) { lookup = commentLookup[interfaces[i].FullName] .FirstOrDefault( x => (x.MemberName == name(item2) || x.MemberName.StartsWith(name(item2) + "`")) && get(item2, x)); if (lookup == null || (lookup.Summary?.Trim() .Equals( "inheritdoc", StringComparison.InvariantCultureIgnoreCase) ?? true)) { lookup = _lookupInterfaces(interfaces[i]); } } return(lookup); } XmlDocumentComment _lookupType(Type t) { if (t == null) { return(null); } XmlDocumentComment lookup = commentLookup[t.FullName] .FirstOrDefault( x => (x.MemberName == name(item2) || x.MemberName.StartsWith(name(item2) + "`")) && get(item2, x)); if (lookup == null || (lookup.Summary?.Trim() .Equals( "inheritdoc", StringComparison.InvariantCultureIgnoreCase) ?? true)) { lookup = _lookupInterfaces(t) ?? _lookupType(t.BaseType); } return(lookup); } return(new MarkdownBuilder.DropdownItem { Type = MarkdownBuilder.MarkdownCodeQuote(type(item2)), Name = finalName(item2), XmlDocumentComment = _lookupType(this.type) }); }); mb.Dropdown(data); mb.AppendLine("___"); } }
// 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_ "); }