protected override void WriteBlock(
                Block block, bool isOpening, bool isClosing, out bool ignoreChildNodes)
            {
                // NSAttributedString will end up with paragraph spacing at the
                // end of paragraph elements which leaves empty space at the end
                // of the NSAttributedString; prevent this by committing <p> tags
                // for the last paragraph.
                var renderTightParagraphs = block == block.Top.LastChild;

                if (renderTightParagraphs)
                {
                    RenderTightParagraphs.Push(true);
                }

                base.WriteBlock(block, isOpening, isClosing, out ignoreChildNodes);

                if (renderTightParagraphs)
                {
                    RenderTightParagraphs.Pop();
                }

                // NSAttributedString lacks paragraph spacing between between
                // adjacent <ul> and <p> nodes, so insert a hard break.
                if (block.Tag == BlockTag.List && isClosing)
                {
                    Write("<br>");
                }
            }
        protected override void WriteBlock(Block block, bool isOpening, bool isClosing, out bool ignoreChildNodes)
        {
            ignoreChildNodes = false;

            switch (block.Tag)
            {
            case BlockTag.ListItem:
                if (isOpening)
                {
                    EnsureNewLine();
                    Write("<li");
                    if (block.ListData.ListType == ListType.Ordered)
                    {
                        Write(string.Format(" srn-priority=\"{0}\"", block.ListData.Start));
                    }
                    Write(">");
                }

                if (isClosing)
                {
                    WriteLine("</li>");
                }
                break;

            case BlockTag.List:
                if (isOpening)
                {
                    EnsureNewLine();
                    Write("<ul");
                    if (block.ListData.ListType == ListType.Ordered)
                    {
                        Write(" class=\"srn-priorities\"");
                    }
                    Write(">");
                    RenderTightParagraphs.Push(block.ListData.IsTight);
                }

                if (isClosing)
                {
                    WriteLine("</ul>");
                    RenderTightParagraphs.Pop();
                }

                break;

            default: base.WriteBlock(block, isOpening, isClosing, out ignoreChildNodes);
                break;
            }
        }
예제 #3
0
        /// <summary>
        /// Writes the specified block element to the output stream. Does not write the child nodes, instead
        /// the <paramref name="ignoreChildNodes"/> is used to notify the caller whether it should recurse
        /// into the child nodes.
        /// </summary>
        /// <param name="block">The block element to be written to the output stream.</param>
        /// <param name="isOpening">Specifies whether the block element is being opened (or started).</param>
        /// <param name="isClosing">Specifies whether the block element is being closed. If the block does not
        /// have child nodes, then both <paramref name="isClosing"/> and <paramref name="isOpening"/> can be
        /// <c>true</c> at the same time.</param>
        /// <param name="ignoreChildNodes">Instructs the caller whether to skip processing of child nodes or not.</param>
        protected virtual void WriteBlock(Block block, bool isOpening, bool isClosing, out bool ignoreChildNodes)
        {
            ignoreChildNodes = false;
            int x;

            switch (block.Tag)
            {
            case BlockTag.Document:
                break;

            case BlockTag.Paragraph:
                if (RenderTightParagraphs.Peek())
                {
                    break;
                }

                if (isOpening)
                {
                    EnsureNewLine();
                    Write("<p");
                    if (Settings.TrackSourcePosition)
                    {
                        WritePositionAttribute(block);
                    }
                    Write('>');
                }

                if (isClosing)
                {
                    WriteLine("</p>");
                }

                break;

            case BlockTag.BlockQuote:
                if (isOpening)
                {
                    EnsureNewLine();
                    Write("<blockquote");
                    if (Settings.TrackSourcePosition)
                    {
                        WritePositionAttribute(block);
                    }
                    WriteLine(">");

                    RenderTightParagraphs.Push(false);
                }

                if (isClosing)
                {
                    RenderTightParagraphs.Pop();
                    WriteLine("</blockquote>");
                }

                break;

            case BlockTag.ListItem:
                if (isOpening)
                {
                    EnsureNewLine();
                    Write("<li");
                    if (Settings.TrackSourcePosition)
                    {
                        WritePositionAttribute(block);
                    }
                    Write('>');
                }

                if (isClosing)
                {
                    WriteLine("</li>");
                }

                break;

            case BlockTag.List:
                var data = block.ListData;

                if (isOpening)
                {
                    EnsureNewLine();
                    Write(data.ListType == ListType.Bullet ? "<ul" : "<ol");
                    if (data.Start != 1)
                    {
                        Write(" start=\"");
                        Write(data.Start.ToString(CultureInfo.InvariantCulture));
                        Write('\"');
                    }
                    if (Settings.TrackSourcePosition)
                    {
                        WritePositionAttribute(block);
                    }
                    WriteLine(">");

                    RenderTightParagraphs.Push(data.IsTight);
                }

                if (isClosing)
                {
                    WriteLine(data.ListType == ListType.Bullet ? "</ul>" : "</ol>");
                    RenderTightParagraphs.Pop();
                }

                break;

            case BlockTag.AtxHeader:
            case BlockTag.SETextHeader:

                x = block.HeaderLevel;
                if (isOpening)
                {
                    EnsureNewLine();

                    Write("<h" + x.ToString(CultureInfo.InvariantCulture));
                    if (Settings.TrackSourcePosition)
                    {
                        WritePositionAttribute(block);
                    }

                    Write('>');
                }

                if (isClosing)
                {
                    WriteLine("</h" + x.ToString(CultureInfo.InvariantCulture) + ">");
                }

                break;

            case BlockTag.IndentedCode:
            case BlockTag.FencedCode:

                ignoreChildNodes = true;

                EnsureNewLine();
                Write("<pre><code");
                if (Settings.TrackSourcePosition)
                {
                    WritePositionAttribute(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;
                    }

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

            case BlockTag.HtmlBlock:
                ignoreChildNodes = true;
                // cannot output source position for HTML blocks
                Write(block.StringContent);

                break;

            case BlockTag.HorizontalRuler:
                ignoreChildNodes = true;
                if (Settings.TrackSourcePosition)
                {
                    Write("<hr");
                    WritePositionAttribute(block);
                    WriteLine();
                }
                else
                {
                    WriteLine("<hr />");
                }

                break;

            case BlockTag.ReferenceDefinition:
                break;

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

            if (ignoreChildNodes && !isClosing)
            {
                throw new InvalidOperationException("Block of type " + block.Tag + " cannot contain child nodes.");
            }
        }