/// <summary> /// Writes the specified inline 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="inline">The inline element to be written to the output stream.</param> /// <param name="isOpening">Specifies whether the inline element is being opened (or started).</param> /// <param name="isClosing">Specifies whether the inline element is being closed. If the inline 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 WriteInline(Inline inline, bool isOpening, bool isClosing, out bool ignoreChildNodes) { if (RenderPlainTextInlines.Peek()) { switch (inline.Tag) { case InlineTag.String: case InlineTag.Code: case InlineTag.RawHtml: WriteEncodedHtml(inline.LiteralContentValue); break; case InlineTag.LineBreak: case InlineTag.SoftBreak: WriteLine(); break; case InlineTag.Image: if (isOpening) { RenderPlainTextInlines.Push(true); } if (isClosing) { RenderPlainTextInlines.Pop(); if (!RenderPlainTextInlines.Peek()) { goto useFullRendering; } } break; case InlineTag.Link: case InlineTag.Strong: case InlineTag.Emphasis: case InlineTag.Strikethrough: break; default: throw new CommonMarkException("Inline type " + inline.Tag + " is not supported.", inline); } ignoreChildNodes = false; return; } useFullRendering: switch (inline.Tag) { case InlineTag.String: ignoreChildNodes = true; if (Settings.TrackSourcePosition) { Write("<span"); WritePositionAttribute(inline); Write('>'); WriteEncodedHtml(inline.LiteralContentValue); Write("</span>"); } else { WriteEncodedHtml(inline.LiteralContentValue); } break; case InlineTag.LineBreak: ignoreChildNodes = true; WriteLine("<br />"); break; case InlineTag.SoftBreak: ignoreChildNodes = true; if (Settings.RenderSoftLineBreaksAsLineBreaks) { WriteLine("<br />"); } else { WriteLine(); } break; case InlineTag.Code: ignoreChildNodes = true; Write("<code"); if (Settings.TrackSourcePosition) { WritePositionAttribute(inline); } Write('>'); WriteEncodedHtml(inline.LiteralContentValue); Write("</code>"); break; case InlineTag.RawHtml: ignoreChildNodes = true; // cannot output source position for HTML blocks Write(inline.LiteralContentValue); break; case InlineTag.Link: ignoreChildNodes = false; if (isOpening) { Write("<a href=\""); var uriResolver = Settings.UriResolver; if (uriResolver != null) { WriteEncodedUrl(uriResolver(inline.TargetUrl)); } else { WriteEncodedUrl(inline.TargetUrl); } Write('\"'); if (inline.LiteralContentValue.Length > 0) { Write(" title=\""); WriteEncodedHtml(inline.LiteralContentValue); Write('\"'); } if (Settings.TrackSourcePosition) { WritePositionAttribute(inline); } Write('>'); } if (isClosing) { Write("</a>"); } break; case InlineTag.Image: ignoreChildNodes = false; if (isOpening) { Write("<img src=\""); var uriResolver = Settings.UriResolver; if (uriResolver != null) { WriteEncodedUrl(uriResolver(inline.TargetUrl)); } else { WriteEncodedUrl(inline.TargetUrl); } Write("\" alt=\""); if (!isClosing) { RenderPlainTextInlines.Push(true); } } if (isClosing) { // this.RenderPlainTextInlines.Pop() is done by the plain text renderer above. Write('\"'); if (inline.LiteralContentValue.Length > 0) { Write(" title=\""); WriteEncodedHtml(inline.LiteralContentValue); Write('\"'); } if (Settings.TrackSourcePosition) { WritePositionAttribute(inline); } Write(" />"); } break; case InlineTag.Strong: ignoreChildNodes = false; if (isOpening) { Write("<strong"); if (Settings.TrackSourcePosition) { WritePositionAttribute(inline); } Write('>'); } if (isClosing) { Write("</strong>"); } break; case InlineTag.Emphasis: ignoreChildNodes = false; if (isOpening) { Write("<em"); if (Settings.TrackSourcePosition) { WritePositionAttribute(inline); } Write('>'); } if (isClosing) { Write("</em>"); } break; case InlineTag.Strikethrough: ignoreChildNodes = false; if (isOpening) { Write("<del"); if (Settings.TrackSourcePosition) { WritePositionAttribute(inline); } Write('>'); } if (isClosing) { Write("</del>"); } break; default: throw new CommonMarkException("Inline type " + inline.Tag + " is not supported.", inline); } }
/// <summary> /// Writes the specified inline 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="inline">The inline element to be written to the output stream.</param> /// <param name="isOpening">Specifies whether the inline element is being opened (or started).</param> /// <param name="isClosing">Specifies whether the inline element is being closed. If the inline does not /// have child nodes, then both <paramref name="isClosing"/> and <paramref name="isOpening"/> can be /// <see langword="true"/> at the same time.</param> /// <param name="ignoreChildNodes">Instructs the caller whether to skip processing of child nodes or not.</param> protected virtual void WriteInline(Inline inline, bool isOpening, bool isClosing, out bool ignoreChildNodes) { if (RenderPlainTextInlines.Peek()) { switch (inline.Tag) { case InlineTag.String: case InlineTag.Code: case InlineTag.RawHtml: WriteEncodedHtml(inline.LiteralContentValue); break; case InlineTag.LineBreak: case InlineTag.SoftBreak: WriteLine(); break; case InlineTag.Image: if (isOpening) { RenderPlainTextInlines.Push(true); } if (isClosing) { RenderPlainTextInlines.Pop(); if (!RenderPlainTextInlines.Peek()) { goto useFullRendering; } } break; case InlineTag.Link: case InlineTag.Strong: case InlineTag.Emphasis: case InlineTag.Strikethrough: case InlineTag.Placeholder: break; default: throw new CommonMarkException("Inline type " + inline.Tag + " is not supported.", inline); } ignoreChildNodes = false; return; } useFullRendering: switch (inline.Tag) { case InlineTag.String: ignoreChildNodes = true; if (Settings.TrackSourcePosition) { Write("<span"); WritePositionAttribute(inline); Write('>'); WriteEncodedHtml(inline.LiteralContentValue); Write("</span>"); } else { WriteEncodedHtml(inline.LiteralContentValue); } break; case InlineTag.LineBreak: ignoreChildNodes = true; WriteLine("<br />"); break; case InlineTag.SoftBreak: ignoreChildNodes = true; if (Settings.RenderSoftLineBreaksAsLineBreaks) { WriteLine("<br />"); } else { if (Settings.RenderEmptyLines) { _target.WriteEmptyLine(); } else { WriteLine(); } } break; case InlineTag.Code: ignoreChildNodes = true; Write("<code"); if (Settings.TrackSourcePosition) { WritePositionAttribute(inline); } Write('>'); WriteEncodedHtml(inline.LiteralContentValue); Write("</code>"); break; case InlineTag.RawHtml: ignoreChildNodes = true; if (Settings.HtmlEntityEncode) { WriteEncodedHtml(inline.LiteralContentValue); } else { // cannot output source position for HTML blocks Write(inline.LiteralContentValue); } break; case InlineTag.Link: ignoreChildNodes = false; if (isOpening) { Write("<a href=\""); var uriResolver = Settings.UriResolver; if (uriResolver != null) { WriteEncodedUrl(uriResolver(inline.TargetUrl)); } else { WriteEncodedUrl(inline.TargetUrl); } Write('\"'); if (inline.LiteralContentValue.Length > 0) { Write(" title=\""); WriteEncodedHtml(inline.LiteralContentValue); Write('\"'); } if (Settings.TrackSourcePosition) { WritePositionAttribute(inline); } Write('>'); } if (isClosing) { Write("</a>"); } break; case InlineTag.Image: ignoreChildNodes = false; if (isOpening) { Write("<img src=\""); var uriResolver = Settings.UriResolver; if (uriResolver != null) { WriteEncodedUrl(uriResolver(inline.TargetUrl)); } else { WriteEncodedUrl(inline.TargetUrl); } Write("\" alt=\""); if (!isClosing) { RenderPlainTextInlines.Push(true); } } if (isClosing) { // this.RenderPlainTextInlines.Pop() is done by the plain text renderer above. Write('\"'); if (inline.LiteralContentValue.Length > 0) { Write(" title=\""); WriteEncodedHtml(inline.LiteralContentValue); Write('\"'); } if (Settings.TrackSourcePosition) { WritePositionAttribute(inline); } Write(" />"); } break; case InlineTag.Strong: ignoreChildNodes = false; if (isOpening) { Write("<strong"); if (Settings.TrackSourcePosition) { WritePositionAttribute(inline); } Write('>'); } if (isClosing) { Write("</strong>"); } break; case InlineTag.Emphasis: ignoreChildNodes = false; if (isOpening) { Write("<em"); if (Settings.TrackSourcePosition) { WritePositionAttribute(inline); } Write('>'); } if (isClosing) { Write("</em>"); } break; case InlineTag.Strikethrough: ignoreChildNodes = false; if (isOpening) { Write("<s"); if (Settings.TrackSourcePosition) { WritePositionAttribute(inline); } Write('>'); } if (isClosing) { Write("</s>"); } break; case InlineTag.Placeholder: ignoreChildNodes = false; if (isOpening) { string placeholderSubstitute = null; try { placeholderSubstitute = (_placeholderResolver != null) ? _placeholderResolver(inline.TargetUrl) : null; } catch (Exception ex) { throw new CommonMarkException("An error occurred while resolving a placeholder.", ex); } if (placeholderSubstitute != null) { ignoreChildNodes = true; if (Settings.TrackSourcePosition) { WritePositionAttribute(inline); } Write(placeholderSubstitute); _endPlaceholders.Push('\0'); } else { ignoreChildNodes = false; Write("["); _endPlaceholders.Push(']'); } } if (isClosing) { var closingChar = _endPlaceholders.Pop(); if (closingChar != '\0') { Write(closingChar); } } break; default: throw new CommonMarkException("Inline type " + inline.Tag + " is not supported.", inline); } }