csharp 从VS XML文档文件生成Markdown

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp 从VS XML文档文件生成Markdown相关的知识,希望对你有一定的参考价值。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Linq;

namespace GithubWikiDoc
{
    class Program
    {
        static void Main(string[] args)
        {
            var xml = File.ReadAllText(args[0]);
            var doc = XDocument.Parse(xml);
            var md = doc.Root.ToMarkDown();
            Console.WriteLine(md);
        }
    }

    static class XmlToMarkdown
    {
        internal static string ToMarkDown(this XNode e)
        {
            var templates = new Dictionary<string, string>
                {
                    {"doc", "## {0} ##\n\n{1}\n\n"},
                    {"type", "# {0}\n\n{1}\n\n---\n"},
                    {"field", "##### {0}\n\n{1}\n\n---\n"},
                    {"property", "##### {0}\n\n{1}\n\n---\n"},
                    {"method", "##### {0}\n\n{1}\n\n---\n"},
                    {"event", "##### {0}\n\n{1}\n\n---\n"},
                    {"summary", "{0}\n\n"},
                    {"remarks", "\n\n>{0}\n\n"},
                    {"example", "_C# code_\n\n```c#\n{0}\n```\n\n"},
                    {"seePage", "[[{1}|{0}]]"},
                    {"seeAnchor", "[{1}]({0})"},
                    {"param", "|Name | Description |\n|-----|------|\n|{0}: |{1}|\n" },
                    {"exception", "[[{0}|{0}]]: {1}\n\n" },
                    {"returns", "Returns: {0}\n\n"},
                    {"none", ""}
                };
            var d = new Func<string, XElement, string[]>((att, node) => new[]
                {
                    node.Attribute(att).Value, 
                    node.Nodes().ToMarkDown()
                });
            var methods = new Dictionary<string, Func<XElement, IEnumerable<string>>>
                {
                    {"doc", x=> new[]{
                        x.Element("assembly").Element("name").Value,
                        x.Element("members").Elements("member").ToMarkDown()
                    }},
                    {"type", x=>d("name", x)},
                    {"field", x=> d("name", x)},
                    {"property", x=> d("name", x)},
                    {"method",x=>d("name", x)},
                    {"event", x=>d("name", x)},
                    {"summary", x=> new[]{ x.Nodes().ToMarkDown() }},
                    {"remarks", x => new[]{x.Nodes().ToMarkDown()}},
                    {"example", x => new[]{x.Value.ToCodeBlock()}},
                    {"seePage", x=> d("cref", x) },
                    {"seeAnchor", x=> { var xx = d("cref", x); xx[0] = xx[0].ToLower(); return xx; }},
                    {"param", x => d("name", x) },
                    {"exception", x => d("cref", x) },
                    {"returns", x => new[]{x.Nodes().ToMarkDown()}},
                    {"none", x => new string[0]}
                };

            string name;
            if(e.NodeType== XmlNodeType.Element)
            {
                var el = (XElement) e;
                name = el.Name.LocalName;
                if (name == "member")
                {
                    switch (el.Attribute("name").Value[0])
                    {
                        case 'F': name = "field";  break;
                        case 'P': name = "property"; break;
                        case 'T': name = "type"; break;
                        case 'E': name = "event"; break;
                        case 'M': name = "method"; break;
                        default:  name = "none";   break;
                    }
                }
                if(name == "see")
                {
                    var anchor = el.Attribute("cref").Value.StartsWith("!:#");
                    name = anchor ? "seeAnchor" : "seePage";
                }
                var vals = methods[name](el).ToArray();
                string str="";
                switch (vals.Length)
                {
                    case 1: str= string.Format(templates[name], vals[0]);break;
                    case 2: str= string.Format(templates[name], vals[0],vals[1]);break;
                    case 3: str= string.Format(templates[name], vals[0],vals[1],vals[2]);break;
                    case 4: str= string.Format(templates[name], vals[0], vals[1], vals[2], vals[3]);break;
                }

                return str;
            }

            if(e.NodeType==XmlNodeType.Text)
                return Regex.Replace( ((XText)e).Value.Replace('\n', ' '), @"\s+", " ");

            return "";
        }

        internal static string ToMarkDown(this IEnumerable<XNode> es)
        {
            return es.Aggregate("", (current, x) => current + x.ToMarkDown());
        }

        static string ToCodeBlock(this string s)
        {
            var lines = s.Split(new char[] {'\n'}, StringSplitOptions.RemoveEmptyEntries);
            var blank = lines[0].TakeWhile(x => x == ' ').Count() - 4;
            return string.Join("\n",lines.Select(x => new string(x.SkipWhile((y, i) => i < blank).ToArray())));
        }
    }
}

以上是关于csharp 从VS XML文档文件生成Markdown的主要内容,如果未能解决你的问题,请参考以下文章

编译后的dll,xml,pdb分别是什么内容,各有什么用处?

如何从其 DTD 或 XSD 生成示例 XML 文档?

是否有能够从 DOCX、XLSX 等 Office XML 文档生成 XSL-FO 的库?

VS2013项目生成报“Newtonsoft.Json”已拥有为“Microsoft.CSharp”定义的依赖项。"

全面解析Unity3D自动生成的脚本工程文件

生成XML文档时如何插入元素计数