Skip to content

使 CommonMark.Net 支持 Table 解析

🏷️ CommonMark.Net Markdown

参照 为 CommonMark.Net 增加 Table 解析 增加了 CommonMark.Net 对表格的支持。下面是原文中的代码:

  1. Inline 增加一个类型 Table

    cs
    public enum InlineTag : byte
    {
        String = 0,
        SoftBreak,
        LineBreak,
        Code,
        RawHtml,
        Emphasis,
        Strong,
        Link,
        Image,
        Strikethrough,
        Table    //新增的 Table 类型
    }
  2. ‘|’ 符号增加处理方法

    cs
    internal static Func<Subject, Inline>[] InitializeParsers(CommonMarkSettings settings)
    {
        var strikethroughTilde = 0 != (settings.AdditionalFeatures & CommonMarkAdditionalFeatures.StrikethroughTilde);
    
        var p = new Func<Subject, Inline>[strikethroughTilde ? 127 : 125];
        p['\n'] = handle_newline;
        p['`'] = handle_backticks;
        p['\\'] = handle_backslash;
        p['&'] = HandleEntity;
        p['<'] = handle_pointy_brace;
        p['_'] = HandleEmphasis;
        p['*'] = HandleEmphasis;
        p['['] = HandleLeftSquareBracket;
        p[']'] = HandleRightSquareBracket;
        p['!'] = HandleExclamation;
        p['|'] = HandleTable;    //增加'|'的解析方法,把 | 到 | 封装为一个 Table 类型的 Inline
    
        if (strikethroughTilde)
            p['~'] = HandleTilde;
    
        return p;
    }
    
    private static Inline HandleTable(Subject subj)
    {
        //这里偷懒了,可以加个校验,确定是个 table,否则单个'|'也会被解析
        var start = subj.Buffer.IndexOf('|');
        var last = subj.Buffer.LastIndexOf('|');
        var inlTab = new Inline(InlineTag.Table, subj.Buffer.Substring(start, last - start + 1));
        subj.Position = last + 1;
        return inlTab;
    }
  3. Table 类型 Inline 的渲染,InlinesToHtml

    cs
    switch (inline.Tag)
    {
        case InlineTag.Table:
            //tab
            writer.WriteConstant("<table class=\"table table-bordered table-striped\">");
            var lines = inline.LiteralContentValue.ToString().Split(new char[] { '\n' }, System.StringSplitOptions.RemoveEmptyEntries);
            int i = 0;
            foreach (var line in lines)
            {
                i++;
    
                if (line.Split(new char[] { '|', '-', ' ', '\n' }, System.StringSplitOptions.RemoveEmptyEntries).Length == 0)
                {
                    continue;
                }
    
                writer.WriteConstant("<tr>");
                var tds = line.Split(new char[] { '|' });
                for (int j = 1; j < tds.Length - 1; j++)
                {
                    writer.WriteConstant(i == 1 ? "<th>" : "<td>");
                    writer.WriteConstant(tds[j]);
                    writer.WriteConstant(i == 1 ? "</th>" : "</td>");
                }
                writer.WriteConstant("</tr>");
            }
            writer.WriteConstant("</table>");
            break;
            ....... ......
    }