예제 #1
0
        private static void BlocksToHtmlInner(HtmlTextWriter writer, Block block, CommonMarkSettings settings)
        {
            var    stack       = new Stack <BlockStackEntry>();
            var    inlineStack = new Stack <InlineStackEntry>();
            bool   visitChildren;
            string stackLiteral   = null;
            bool   stackTight     = false;
            bool   tight          = false;
            bool   trackPositions = settings.TrackSourcePosition;
            int    x;

            while (block != null)
            {
                visitChildren = false;

                switch (block.Tag)
                {
                case BlockTag.Document:
                    stackLiteral  = null;
                    stackTight    = false;
                    visitChildren = true;
                    break;

                case BlockTag.Paragraph:
                    if (tight)
                    {
                        InlinesToHtml(writer, block.InlineContent, settings, inlineStack);
                    }
                    else
                    {
                        writer.EnsureLine();
                        writer.WriteConstant("<p");
                        if (trackPositions)
                        {
                            PrintPosition(writer, block);
                        }
                        writer.Write('>');
                        InlinesToHtml(writer, block.InlineContent, settings, inlineStack);
                        writer.WriteLineConstant("</p>");
                    }
                    break;

                case BlockTag.BlockQuote:
                    writer.EnsureLine();
                    writer.WriteConstant("<blockquote");
                    if (trackPositions)
                    {
                        PrintPosition(writer, block);
                    }
                    writer.WriteLine('>');

                    stackLiteral  = "</blockquote>";
                    stackTight    = false;
                    visitChildren = true;
                    break;

                case BlockTag.ListItem:
                    writer.EnsureLine();
                    writer.WriteConstant("<li");
                    if (trackPositions)
                    {
                        PrintPosition(writer, block);
                    }
                    writer.Write('>');

                    stackLiteral  = "</li>";
                    stackTight    = tight;
                    visitChildren = true;
                    break;

                case BlockTag.List:
                    // make sure a list starts at the beginning of the line:
                    writer.EnsureLine();
                    var data = block.ListData;
                    writer.WriteConstant(data.ListType == ListType.Bullet ? "<ul" : "<ol");
                    if (data.Start != 1)
                    {
                        writer.WriteConstant(" start=\"");
                        writer.WriteConstant(data.Start.ToString(CultureInfo.InvariantCulture));
                        writer.Write('\"');
                    }
                    if (trackPositions)
                    {
                        PrintPosition(writer, block);
                    }
                    writer.WriteLine('>');

                    stackLiteral  = data.ListType == ListType.Bullet ? "</ul>" : "</ol>";
                    stackTight    = data.IsTight;
                    visitChildren = true;
                    break;

                case BlockTag.AtxHeading:
                case BlockTag.SetextHeading:
                    writer.EnsureLine();

                    x = block.Heading.Level;

                    if (trackPositions)
                    {
                        writer.WriteConstant("<h" + x.ToString(CultureInfo.InvariantCulture));
                        PrintPosition(writer, block);
                        writer.Write('>');
                        InlinesToHtml(writer, block.InlineContent, settings, inlineStack);
                        writer.WriteLineConstant(x > 0 && x < 7 ? HeadingCloserTags[x - 1] : "</h" + x.ToString(CultureInfo.InvariantCulture) + ">");
                    }
                    else
                    {
                        writer.WriteConstant(x > 0 && x < 7 ? HeadingOpenerTags[x - 1] : "<h" + x.ToString(CultureInfo.InvariantCulture) + ">");
                        InlinesToHtml(writer, block.InlineContent, settings, inlineStack);
                        writer.WriteLineConstant(x > 0 && x < 7 ? HeadingCloserTags[x - 1] : "</h" + x.ToString(CultureInfo.InvariantCulture) + ">");
                    }

                    break;

                case BlockTag.IndentedCode:
                case BlockTag.FencedCode:
                    writer.EnsureLine();
                    writer.WriteConstant("<pre><code");
                    if (trackPositions)
                    {
                        PrintPosition(writer, block);
                    }

                    var info = block.FencedCodeData == null ? null : block.FencedCodeData.Info;
                    if (info != null && info.Length > 0)
                    {
                        x = info.IndexOf(' ');
                        if (x == -1)
                        {
                            x = info.Length;
                        }

                        writer.WriteConstant(" class=\"language-");
                        EscapeHtml(new StringPart(info, 0, x), writer);
                        writer.Write('\"');
                    }
                    writer.Write('>');
                    EscapeHtml(block.StringContent, writer);
                    writer.WriteLineConstant("</code></pre>");
                    break;

                case BlockTag.HtmlBlock:
                    // cannot output source position for HTML blocks
                    block.StringContent.WriteTo(writer);

                    break;

                case BlockTag.ThematicBreak:
                    if (trackPositions)
                    {
                        writer.WriteConstant("<hr");
                        PrintPosition(writer, block);
                        writer.WriteLine();
                    }
                    else
                    {
                        writer.WriteLineConstant("<hr />");
                    }

                    break;

                case BlockTag.ReferenceDefinition:
                    break;

                default:
                    throw new CommonMarkException("Block type " + block.Tag + " is not supported.", block);
                }

                if (visitChildren)
                {
                    stack.Push(new BlockStackEntry(stackLiteral, block.NextSibling, tight));

                    tight = stackTight;
                    block = block.FirstChild;
                }
                else if (block.NextSibling != null)
                {
                    block = block.NextSibling;
                }
                else
                {
                    block = null;
                }

                while (block == null && stack.Count > 0)
                {
                    var entry = stack.Pop();

                    writer.WriteLineConstant(entry.Literal);
                    tight = entry.IsTight;
                    block = entry.Target;
                }
            }
        }
예제 #2
0
 /// <summary>
 /// Ensures that the output ends with a newline. This means that newline character will be written
 /// only if the writer does not currently end with a newline.
 /// </summary>
 protected void EnsureNewLine()
 {
     _target.EnsureLine();
 }
예제 #3
0
        private static void BlocksToHtmlInner(HtmlTextWriter writer, Block block, CommonMarkSettings settings)
        {
            var stack = new Stack<BlockStackEntry>();
            var inlineStack = new Stack<InlineStackEntry>();
            bool visitChildren;
            string stackLiteral = null;
            bool stackTight = false;
            bool tight = false;
            bool trackPositions = settings.TrackSourcePosition;
            int x;

            while (block != null)
            {
                visitChildren = false;

                switch (block.Tag)
                {
                    case BlockTag.Document:
                        stackLiteral = null;
                        stackTight = false;
                        visitChildren = true;
                        break;

                    case BlockTag.Paragraph:
                        if (tight)
                        {
                            InlinesToHtml(writer, block.InlineContent, settings, inlineStack);
                        }
                        else
                        {
                            writer.EnsureLine();
                            writer.WriteConstant("<p");
                            if (trackPositions) PrintPosition(writer, block);
                            writer.Write('>');
                            InlinesToHtml(writer, block.InlineContent, settings, inlineStack);
                            writer.WriteLineConstant("</p>");
                        }
                        break;

                    case BlockTag.BlockQuote:
                        writer.EnsureLine();
                        writer.WriteConstant("<blockquote");
                        if (trackPositions) PrintPosition(writer, block);
                        writer.WriteLine('>');

                        stackLiteral = "</blockquote>";
                        stackTight = false;
                        visitChildren = true;
                        break;

                    case BlockTag.ListItem:
                        writer.EnsureLine();
                        writer.WriteConstant("<li");
                        if (trackPositions) PrintPosition(writer, block);
                        writer.Write('>');

                        stackLiteral = "</li>";
                        stackTight = tight;
                        visitChildren = true;
                        break;

                    case BlockTag.List:
                        // make sure a list starts at the beginning of the line:
                        writer.EnsureLine();
                        var data = block.ListData;
                        writer.WriteConstant(data.ListType == ListType.Bullet ? "<ul" : "<ol");
                        if (data.Start != 1)
                        {
                            writer.WriteConstant(" start=\"");
                            writer.WriteConstant(data.Start.ToString(CultureInfo.InvariantCulture));
                            writer.Write('\"');
                        }
                        if (trackPositions) PrintPosition(writer, block);
                        writer.WriteLine('>');

                        stackLiteral = data.ListType == ListType.Bullet ? "</ul>" : "</ol>";
                        stackTight = data.IsTight;
                        visitChildren = true;
                        break;

                    case BlockTag.AtxHeader:
                    case BlockTag.SETextHeader:
                        writer.EnsureLine();

                        x = block.HeaderLevel;

                        if (trackPositions)
                        {
                            writer.WriteConstant("<h" + x.ToString(CultureInfo.InvariantCulture));
                            PrintPosition(writer, block);
                            writer.Write('>');
                            InlinesToHtml(writer, block.InlineContent, settings, inlineStack);
                            writer.WriteLineConstant(x > 0 && x < 7 ? HeaderCloserTags[x - 1] : "</h" + x.ToString(CultureInfo.InvariantCulture) + ">");
                        }
                        else
                        {
                            writer.WriteConstant(x > 0 && x < 7 ? HeaderOpenerTags[x - 1] : "<h" + x.ToString(CultureInfo.InvariantCulture) + ">");
                            InlinesToHtml(writer, block.InlineContent, settings, inlineStack);
                            writer.WriteLineConstant(x > 0 && x < 7 ? HeaderCloserTags[x - 1] : "</h" + x.ToString(CultureInfo.InvariantCulture) + ">");
                        }

                        break;

                    case BlockTag.IndentedCode:
                    case BlockTag.FencedCode:
                        writer.EnsureLine();
                        writer.WriteConstant("<pre><code");
                        if (trackPositions) PrintPosition(writer, block);

                        var info = block.FencedCodeData == null ? null : block.FencedCodeData.Info;
                        if (info != null && info.Length > 0)
                        {
                            x = info.IndexOf(' ');
                            if (x == -1)
                                x = info.Length;

                            writer.WriteConstant(" class=\"language-");
                            EscapeHtml(new StringPart(info, 0, x), writer);
                            writer.Write('\"');
                        }
                        writer.Write('>');
                        EscapeHtml(block.StringContent, writer);
                        writer.WriteLineConstant("</code></pre>");
                        break;

                    case BlockTag.HtmlBlock:
                        // cannot output source position for HTML blocks
                        block.StringContent.WriteTo(writer);

                        break;

                    case BlockTag.HorizontalRuler:
                        if (trackPositions)
                        {
                            writer.WriteConstant("<hr");
                            PrintPosition(writer, block);
                            writer.WriteLine();
                        }
                        else
                        {
                            writer.WriteLineConstant("<hr />");
                        }

                        break;

                    case BlockTag.ReferenceDefinition:
                        break;

                    default:
                        throw new CommonMarkException("Block type " + block.Tag + " is not supported.", block);
                }

                if (visitChildren)
                {
                    stack.Push(new BlockStackEntry(stackLiteral, block.NextSibling, tight));

                    tight = stackTight;
                    block = block.FirstChild;
                }
                else if (block.NextSibling != null)
                {
                    block = block.NextSibling;
                }
                else
                {
                    block = null;
                }

                while (block == null && stack.Count > 0)
                {
                    var entry = stack.Pop();

                    writer.WriteLineConstant(entry.Literal);
                    tight = entry.IsTight;
                    block = entry.Target;
                }
            }
        }