Comments for all renderers (HTML)

This commit is contained in:
Alexandre Mutel
2016-03-05 00:06:49 +09:00
parent ba5527e7b2
commit cb53ceaed7
27 changed files with 338 additions and 37 deletions

View File

@@ -8,23 +8,23 @@ namespace Textamina.Markdig.Extensions.Footnotes
{
public class HtmlFootnoteGroupRenderer : HtmlObjectRenderer<FootnoteGroup>
{
protected override void Write(HtmlRenderer writer, FootnoteGroup footnoteGroup)
protected override void Write(HtmlRenderer renderer, FootnoteGroup footnoteGroup)
{
var footnotes = footnoteGroup.Children;
writer.EnsureLine();
writer.WriteLine("<div class=\"footnotes\">");
writer.WriteLine("<hr />");
writer.WriteLine("<ol>");
renderer.EnsureLine();
renderer.WriteLine("<div class=\"footnotes\">");
renderer.WriteLine("<hr />");
renderer.WriteLine("<ol>");
for (int i = 0; i < footnotes.Count; i++)
{
var footnote = (Footnote)footnotes[i];
writer.WriteLine($"<li id=\"fn:{footnote.Order}\">");
writer.WriteChildren(footnote);
writer.WriteLine("</li>");
renderer.WriteLine($"<li id=\"fn:{footnote.Order}\">");
renderer.WriteChildren(footnote);
renderer.WriteLine("</li>");
}
writer.WriteLine("</ol>");
writer.WriteLine("</div>");
renderer.WriteLine("</ol>");
renderer.WriteLine("</div>");
}
}
}

View File

@@ -21,10 +21,10 @@ namespace Textamina.Markdig.Extensions.Footnotes
public string FootnoteBackLinkClass { get; set; }
protected override void Write(HtmlRenderer writer, FootnoteLink link)
protected override void Write(HtmlRenderer renderer, FootnoteLink link)
{
var order = link.Footnote.Order ?? 0;
writer.Write(link.IsBackLink
renderer.Write(link.IsBackLink
? $"<a href=\"#fnref:{link.Index}\" class=\"{FootnoteBackLinkClass}\">{HtmlHelper.Unescape(BackLinkString)}</a>"
: $"<a id=\"fnref:{link.Index}\" href=\"#fn:{order}\" class=\"{FootnoteLinkClass}\"><sup>{order}</sup></a>");
}

View File

@@ -8,10 +8,10 @@ namespace Textamina.Markdig.Extensions.Tables
{
public class HtmlTableRenderer : HtmlObjectRenderer<TableBlock>
{
protected override void Write(HtmlRenderer writer, TableBlock tableBlock)
protected override void Write(HtmlRenderer renderer, TableBlock tableBlock)
{
writer.EnsureLine();
writer.Write("<table").WriteAttributes(tableBlock).WriteLine(">");
renderer.EnsureLine();
renderer.Write("<table").WriteAttributes(tableBlock).WriteLine(">");
bool hasBody = false;
var header = (TableRowBlock)tableBlock.Children[0];
@@ -24,57 +24,57 @@ namespace Textamina.Markdig.Extensions.Tables
var row = (TableRowBlock)rowObj;
if (row.IsHeader)
{
writer.WriteLine("<thead>");
renderer.WriteLine("<thead>");
}
else if (!hasBody)
{
writer.WriteLine("<tbody>");
renderer.WriteLine("<tbody>");
hasBody = true;
}
writer.WriteLine("<tr>");
renderer.WriteLine("<tr>");
for (int i = 0; i < row.Children.Count; i++)
{
var cellObj = row.Children[i];
var cell = (TableCellBlock)cellObj;
writer.EnsureLine();
renderer.EnsureLine();
if (row.IsHeader)
{
writer.Write("<th");
renderer.Write("<th");
}
else
{
writer.Write("<td");
renderer.Write("<td");
}
if (header != null && i < header.ColumnAlignments.Count)
{
switch (header.ColumnAlignments[i])
{
case TableColumnAlign.Center:
writer.Write(" style=\"text-align: center;\"");
renderer.Write(" style=\"text-align: center;\"");
break;
case TableColumnAlign.Right:
writer.Write(" style=\"text-align: right;\"");
renderer.Write(" style=\"text-align: right;\"");
break;
}
}
writer.Write(">");
renderer.Write(">");
writer.WriteLeafInline(cell);
writer.WriteLine(row.IsHeader ? "</th>" : "</td>");
renderer.WriteLeafInline(cell);
renderer.WriteLine(row.IsHeader ? "</th>" : "</td>");
}
writer.WriteLine("</tr>");
renderer.WriteLine("</tr>");
if (row.IsHeader)
{
writer.WriteLine("</thead>");
renderer.WriteLine("</thead>");
}
}
if (hasBody)
{
writer.WriteLine("</tbody>");
renderer.WriteLine("</tbody>");
}
writer.WriteLine("</table>");
renderer.WriteLine("</table>");
}
}
}

View File

@@ -5,6 +5,10 @@ using Textamina.Markdig.Syntax;
namespace Textamina.Markdig.Renderers.Html
{
/// <summary>
/// An HTML renderer for a <see cref="CodeBlock"/> and <see cref="FencedCodeBlock"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.Html.HtmlObjectRenderer{Textamina.Markdig.Syntax.CodeBlock}" />
public class CodeBlockRenderer : HtmlObjectRenderer<CodeBlock>
{
public bool OutputAttributesOnPre { get; set; }

View File

@@ -6,6 +6,10 @@ using Textamina.Markdig.Syntax;
namespace Textamina.Markdig.Renderers.Html
{
/// <summary>
/// An HTML renderer for a <see cref="HeadingBlock"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.Html.HtmlObjectRenderer{Textamina.Markdig.Syntax.HeadingBlock}" />
public class HeadingRenderer : HtmlObjectRenderer<HeadingBlock>
{
protected override void Write(HtmlRenderer renderer, HeadingBlock obj)

View File

@@ -7,18 +7,37 @@ using Textamina.Markdig.Syntax;
namespace Textamina.Markdig.Renderers.Html
{
/// <summary>
/// Attached HTML attributes to a <see cref="MarkdownObject"/>.
/// </summary>
public class HtmlAttributes
{
/// <summary>
/// Initializes a new instance of the <see cref="HtmlAttributes"/> class.
/// </summary>
public HtmlAttributes()
{
}
/// <summary>
/// Gets or sets the HTML id/identifier. May be null.
/// </summary>
public string Id { get; set; }
/// <summary>
/// Gets or sets the CSS classes attached. May be null.
/// </summary>
public List<string> Classes { get; set; }
/// <summary>
/// Gets or sets the additional properties. May be null.
/// </summary>
public List<KeyValuePair<string, string>> Properties { get; set; }
/// <summary>
/// Adds a CSS class.
/// </summary>
/// <param name="name">The css class name.</param>
public void AddClass(string name)
{
if (Classes == null)
@@ -28,6 +47,11 @@ namespace Textamina.Markdig.Renderers.Html
Classes.Add(name);
}
/// <summary>
/// Adds a property.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="value">The value.</param>
public void AddProperty(string name, string value)
{
if (Properties == null)
@@ -37,6 +61,11 @@ namespace Textamina.Markdig.Renderers.Html
Properties.Add(new KeyValuePair<string, string>(name, value));
}
/// <summary>
/// Copies the values from this instance to the specified <see cref="HtmlAttributes"/> instance.
/// </summary>
/// <param name="htmlAttributes">The HTML attributes.</param>
/// <exception cref="System.ArgumentNullException"></exception>
public void CopyTo(HtmlAttributes htmlAttributes)
{
if (htmlAttributes == null) throw new ArgumentNullException(nameof(htmlAttributes));
@@ -62,15 +91,28 @@ namespace Textamina.Markdig.Renderers.Html
}
}
/// <summary>
/// Extensions for a <see cref="MarkdownObject"/> to allow accessing <see cref="HtmlAttributes"/>
/// </summary>
public static class HtmlAttributesExtensions
{
private static readonly object Key = typeof (HtmlAttributes);
/// <summary>
/// Tries the get <see cref="HtmlAttributes"/> stored on a <see cref="MarkdownObject"/>.
/// </summary>
/// <param name="obj">The markdown object.</param>
/// <returns>The attached html attributes or null if not found</returns>
public static HtmlAttributes TryGetAttributes(this MarkdownObject obj)
{
return obj.GetData(Key) as HtmlAttributes;
}
/// <summary>
/// Gets or creates the <see cref="HtmlAttributes"/> stored on a <see cref="MarkdownObject"/>
/// </summary>
/// <param name="obj">The markdown object.</param>
/// <returns>The attached html attributes</returns>
public static HtmlAttributes GetAttributes(this MarkdownObject obj)
{
var attributes = obj.GetData(Key) as HtmlAttributes;

View File

@@ -5,6 +5,10 @@ using Textamina.Markdig.Syntax;
namespace Textamina.Markdig.Renderers.Html
{
/// <summary>
/// A HTML renderer for a <see cref="HtmlBlock"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.Html.HtmlObjectRenderer{Textamina.Markdig.Syntax.HtmlBlock}" />
public class HtmlBlockRenderer : HtmlObjectRenderer<HtmlBlock>
{
protected override void Write(HtmlRenderer renderer, HtmlBlock obj)

View File

@@ -1,15 +1,19 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using System;
using System.Reflection;
using Textamina.Markdig.Syntax;
using Textamina.Markdig.Syntax.Inlines;
namespace Textamina.Markdig.Renderers.Html
{
/// <summary>
/// A base class for HTML rendering <see cref="Block"/> and <see cref="Inline"/> Markdown objects.
/// </summary>
/// <typeparam name="TObject">The type of the object.</typeparam>
/// <seealso cref="Textamina.Markdig.Renderers.IMarkdownObjectRenderer" />
public abstract class HtmlObjectRenderer<TObject> : IMarkdownObjectRenderer where TObject : MarkdownObject
{
public virtual bool Accept(RendererBase renderer, object obj)
public virtual bool Accept(RendererBase renderer, MarkdownObject obj)
{
return obj is TObject;
}
@@ -19,6 +23,11 @@ namespace Textamina.Markdig.Renderers.Html
Write((HtmlRenderer)renderer, (TObject)obj);
}
protected abstract void Write(HtmlRenderer visitor, TObject obj);
/// <summary>
/// Writes the specified Markdown object to the renderer.
/// </summary>
/// <param name="renderer">The renderer.</param>
/// <param name="obj">The markdown object.</param>
protected abstract void Write(HtmlRenderer renderer, TObject obj);
}
}

View File

@@ -5,6 +5,10 @@ using Textamina.Markdig.Syntax.Inlines;
namespace Textamina.Markdig.Renderers.Html.Inlines
{
/// <summary>
/// A HTML renderer for an <see cref="AutolinkInline"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.Html.HtmlObjectRenderer{Textamina.Markdig.Syntax.Inlines.AutolinkInline}" />
public class AutolinkInlineRenderer : HtmlObjectRenderer<AutolinkInline>
{
protected override void Write(HtmlRenderer renderer, AutolinkInline obj)

View File

@@ -1,11 +1,14 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using Textamina.Markdig.Helpers;
using Textamina.Markdig.Syntax.Inlines;
namespace Textamina.Markdig.Renderers.Html.Inlines
{
/// <summary>
/// A HTML renderer for a <see cref="CodeInline"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.Html.HtmlObjectRenderer{Textamina.Markdig.Syntax.Inlines.CodeInline}" />
public class CodeInlineRenderer : HtmlObjectRenderer<CodeInline>
{
protected override void Write(HtmlRenderer renderer, CodeInline obj)

View File

@@ -5,6 +5,10 @@ using Textamina.Markdig.Syntax.Inlines;
namespace Textamina.Markdig.Renderers.Html.Inlines
{
/// <summary>
/// A HTML renderer for a <see cref="DelimiterInline"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.Html.HtmlObjectRenderer{Textamina.Markdig.Syntax.Inlines.DelimiterInline}" />
public class DelimiterInlineRenderer : HtmlObjectRenderer<DelimiterInline>
{
protected override void Write(HtmlRenderer renderer, DelimiterInline obj)

View File

@@ -5,15 +5,30 @@ using Textamina.Markdig.Syntax.Inlines;
namespace Textamina.Markdig.Renderers.Html.Inlines
{
/// <summary>
/// A HTML renderer for an <see cref="EmphasisInline"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.Html.HtmlObjectRenderer{Textamina.Markdig.Syntax.Inlines.EmphasisInline}" />
public class EmphasisInlineRenderer : HtmlObjectRenderer<EmphasisInline>
{
/// <summary>
/// Delegates to get the tag associated to an <see cref="EmphasisInline"/> object.
/// </summary>
/// <param name="obj">The object.</param>
/// <returns>The HTML tag associated to this <see cref="EmphasisInline"/> object</returns>
public delegate string GetTagDelegate(EmphasisInline obj);
/// <summary>
/// Initializes a new instance of the <see cref="EmphasisInlineRenderer"/> class.
/// </summary>
public EmphasisInlineRenderer()
{
GetTag = GetDefaultTag;
}
/// <summary>
/// Gets or sets the GetTag delegate.
/// </summary>
public GetTagDelegate GetTag { get; set; }
protected override void Write(HtmlRenderer renderer, EmphasisInline obj)
@@ -31,6 +46,11 @@ namespace Textamina.Markdig.Renderers.Html.Inlines
}
}
/// <summary>
/// Gets the default HTML tag for ** and __ emphasis.
/// </summary>
/// <param name="obj">The object.</param>
/// <returns></returns>
public string GetDefaultTag(EmphasisInline obj)
{
if (obj.DelimiterChar == '*' || obj.DelimiterChar == '_')

View File

@@ -5,6 +5,10 @@ using Textamina.Markdig.Syntax.Inlines;
namespace Textamina.Markdig.Renderers.Html.Inlines
{
/// <summary>
/// A HTML renderer for a <see cref="HardlineBreakInline"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.Html.HtmlObjectRenderer{Textamina.Markdig.Syntax.Inlines.HardlineBreakInline}" />
public class HardlineBreakInlineRenderer : HtmlObjectRenderer<HardlineBreakInline>
{
protected override void Write(HtmlRenderer renderer, HardlineBreakInline obj)

View File

@@ -5,6 +5,10 @@ using Textamina.Markdig.Syntax.Inlines;
namespace Textamina.Markdig.Renderers.Html.Inlines
{
/// <summary>
/// A HTML renderer for a <see cref="HtmlInline"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.Html.HtmlObjectRenderer{Textamina.Markdig.Syntax.Inlines.HtmlInline}" />
public class HtmlInlineRenderer : HtmlObjectRenderer<HtmlInline>
{
protected override void Write(HtmlRenderer renderer, HtmlInline obj)

View File

@@ -5,6 +5,10 @@ using Textamina.Markdig.Syntax.Inlines;
namespace Textamina.Markdig.Renderers.Html.Inlines
{
/// <summary>
/// A HTML renderer for a <see cref="LinkInline"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.Html.HtmlObjectRenderer{Textamina.Markdig.Syntax.Inlines.LinkInline}" />
public class LinkInlineRenderer : HtmlObjectRenderer<LinkInline>
{
protected override void Write(HtmlRenderer renderer, LinkInline link)

View File

@@ -5,6 +5,10 @@ using Textamina.Markdig.Syntax.Inlines;
namespace Textamina.Markdig.Renderers.Html.Inlines
{
/// <summary>
/// A HTML renderer for a <see cref="LiteralInline"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.Html.HtmlObjectRenderer{Textamina.Markdig.Syntax.Inlines.LiteralInline}" />
public class LiteralInlineRenderer : HtmlObjectRenderer<LiteralInline>
{
protected override void Write(HtmlRenderer renderer, LiteralInline obj)

View File

@@ -5,8 +5,15 @@ using Textamina.Markdig.Syntax.Inlines;
namespace Textamina.Markdig.Renderers.Html.Inlines
{
/// <summary>
/// A HTML renderer for a <see cref="SoftlineBreakInline"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.Html.HtmlObjectRenderer{Textamina.Markdig.Syntax.Inlines.SoftlineBreakInline}" />
public class SoftlineBreakInlineRenderer : HtmlObjectRenderer<SoftlineBreakInline>
{
/// <summary>
/// Gets or sets a value indicating whether to render this softline break as a HTML hardline break tag (&lt;br /&gt;)
/// </summary>
public bool RenderAsHardlineBreak { get; set; }
protected override void Write(HtmlRenderer renderer, SoftlineBreakInline obj)

View File

@@ -6,6 +6,10 @@ using Textamina.Markdig.Syntax;
namespace Textamina.Markdig.Renderers.Html
{
/// <summary>
/// A HTML renderer for a <see cref="ListBlock"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.Html.HtmlObjectRenderer{Textamina.Markdig.Syntax.ListBlock}" />
public class ListRenderer : HtmlObjectRenderer<ListBlock>
{
protected override void Write(HtmlRenderer renderer, ListBlock listBlock)

View File

@@ -5,6 +5,10 @@ using Textamina.Markdig.Syntax;
namespace Textamina.Markdig.Renderers.Html
{
/// <summary>
/// A HTML renderer for a <see cref="ParagraphBlock"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.Html.HtmlObjectRenderer{Textamina.Markdig.Syntax.ParagraphBlock}" />
public class ParagraphRenderer : HtmlObjectRenderer<ParagraphBlock>
{
protected override void Write(HtmlRenderer renderer, ParagraphBlock obj)

View File

@@ -5,6 +5,10 @@ using Textamina.Markdig.Syntax;
namespace Textamina.Markdig.Renderers.Html
{
/// <summary>
/// A HTML renderer for a <see cref="QuoteBlock"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.Html.HtmlObjectRenderer{Textamina.Markdig.Syntax.QuoteBlock}" />
public class QuoteBlockRenderer : HtmlObjectRenderer<QuoteBlock>
{
protected override void Write(HtmlRenderer renderer, QuoteBlock obj)

View File

@@ -5,6 +5,10 @@ using Textamina.Markdig.Syntax;
namespace Textamina.Markdig.Renderers.Html
{
/// <summary>
/// A HTML renderer for a <see cref="ThematicBreakBlock"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.Html.HtmlObjectRenderer{Textamina.Markdig.Syntax.ThematicBreakBlock}" />
public class ThematicBreakRenderer : HtmlObjectRenderer<ThematicBreakBlock>
{
protected override void Write(HtmlRenderer renderer, ThematicBreakBlock obj)

View File

@@ -11,8 +11,16 @@ using Textamina.Markdig.Syntax;
namespace Textamina.Markdig.Renderers
{
/// <summary>
/// Default HTML renderer for a Markdown <see cref="Document"/> object.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.TextRendererBase{Textamina.Markdig.Renderers.HtmlRenderer}" />
public class HtmlRenderer : TextRendererBase<HtmlRenderer>
{
/// <summary>
/// Initializes a new instance of the <see cref="HtmlRenderer"/> class.
/// </summary>
/// <param name="writer">The writer.</param>
public HtmlRenderer(TextWriter writer) : base(writer)
{
// Default block renderers
@@ -38,10 +46,24 @@ namespace Textamina.Markdig.Renderers
EnableHtmlForInline = true;
}
/// <summary>
/// Gets or sets a value indicating whether to ouput HTML tags when rendering. See remarks.
/// </summary>
/// <remarks>
/// This is used by some renderers to disable HTML tags when rendering some inlines (for image links).
/// </remarks>
public bool EnableHtmlForInline { get; set; }
/// <summary>
/// Gets or sets a value indicating whether to use implicit paragraph (optional &lt;p&gt;)
/// </summary>
public bool ImplicitParagraph { get; set; }
/// <summary>
/// Writes the content escaped for HTML.
/// </summary>
/// <param name="content">The content.</param>
/// <returns>This instance</returns>
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
public HtmlRenderer WriteEscape(string content)
{
@@ -52,6 +74,11 @@ namespace Textamina.Markdig.Renderers
return this;
}
/// <summary>
/// Writes the content escaped for HTML.
/// </summary>
/// <param name="slice">The slice.</param>
/// <returns>This instance</returns>
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
public HtmlRenderer WriteEscape(ref StringSlice slice)
{
@@ -62,6 +89,13 @@ namespace Textamina.Markdig.Renderers
return WriteEscape(slice.Text, slice.Start, slice.Length);
}
/// <summary>
/// Writes the content escaped for HTML.
/// </summary>
/// <param name="content">The content.</param>
/// <param name="offset">The offset.</param>
/// <param name="length">The length.</param>
/// <returns>This instance</returns>
public HtmlRenderer WriteEscape(string content, int offset, int length)
{
if (string.IsNullOrEmpty(content) || length == 0)
@@ -100,6 +134,11 @@ namespace Textamina.Markdig.Renderers
return this;
}
/// <summary>
/// Writes the URL escaped for HTML.
/// </summary>
/// <param name="content">The content.</param>
/// <returns>This instance</returns>
public HtmlRenderer WriteEscapeUrl(string content)
{
if (content == null)
@@ -151,6 +190,11 @@ namespace Textamina.Markdig.Renderers
return this;
}
/// <summary>
/// Writes the attached <see cref="HtmlAttributes"/> on the specified <see cref="MarkdownObject"/>.
/// </summary>
/// <param name="obj">The object.</param>
/// <returns></returns>
public HtmlRenderer WriteAttributes(MarkdownObject obj)
{
var attributes = obj.TryGetAttributes();
@@ -191,6 +235,13 @@ namespace Textamina.Markdig.Renderers
return this;
}
/// <summary>
/// Writes the lines of a <see cref="LeafBlock"/>
/// </summary>
/// <param name="leafBlock">The leaf block.</param>
/// <param name="writeEndOfLines">if set to <c>true</c> write end of lines.</param>
/// <param name="escape">if set to <c>true</c> escape the content for HTML</param>
/// <returns>This instance</returns>
public HtmlRenderer WriteLeafRawLines(LeafBlock leafBlock, bool writeEndOfLines, bool escape)
{
if (leafBlock.Lines != null)

View File

@@ -1,15 +1,29 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using System;
using Textamina.Markdig.Syntax;
namespace Textamina.Markdig.Renderers
{
/// <summary>
/// Base interface for the renderer of a <see cref="MarkdownObject"/>.
/// </summary>
public interface IMarkdownObjectRenderer
{
bool Accept(RendererBase renderer, object obj);
/// <summary>
/// Accepts the specified <see cref="MarkdownObject"/>.
/// </summary>
/// <param name="renderer">The renderer.</param>
/// <param name="obj">The Markdown object.</param>
/// <returns><c>true</c> If this renderer is accepting to render the specified Markdown object</returns>
bool Accept(RendererBase renderer, MarkdownObject obj);
/// <summary>
/// Writes the specified <see cref="MarkdownObject"/> to the <see cref="renderer"/>.
/// </summary>
/// <param name="renderer">The renderer.</param>
/// <param name="objectToRender">The object to render.</param>
void Write(RendererBase renderer, MarkdownObject objectToRender);
}
}

View File

@@ -2,13 +2,25 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using Textamina.Markdig.Syntax;
using Textamina.Markdig.Syntax.Inlines;
namespace Textamina.Markdig.Renderers
{
/// <summary>
/// Base interface for a renderer for a Markdown <see cref="Document"/>.
/// </summary>
public interface IMarkdownRenderer
{
/// <summary>
/// Gets the object renderers that will render <see cref="Block"/> and <see cref="Inline"/> elements.
/// </summary>
ObjectRendererCollection ObjectRenderers { get; }
/// <summary>
/// Renders the specified markdown object.
/// </summary>
/// <param name="markdownObject">The markdown object.</param>
/// <returns>The result of the rendering.</returns>
object Render(MarkdownObject markdownObject);
}
}

View File

@@ -5,6 +5,10 @@ using Textamina.Markdig.Helpers;
namespace Textamina.Markdig.Renderers
{
/// <summary>
/// A collection of <see cref="IMarkdownObjectRenderer"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Helpers.OrderedList{Textamina.Markdig.Renderers.IMarkdownObjectRenderer}" />
public class ObjectRendererCollection : OrderedList<IMarkdownObjectRenderer>
{
}

View File

@@ -8,12 +8,19 @@ using Textamina.Markdig.Syntax.Inlines;
namespace Textamina.Markdig.Renderers
{
/// <summary>
/// Base class for a <see cref="IMarkdownRenderer"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.IMarkdownRenderer" />
public abstract class RendererBase : IMarkdownRenderer
{
private readonly Dictionary<Type, IMarkdownObjectRenderer> renderersPerType;
private IMarkdownObjectRenderer previousRenderer;
private Type previousObjectType;
/// <summary>
/// Initializes a new instance of the <see cref="RendererBase"/> class.
/// </summary>
protected RendererBase()
{
ObjectRenderers = new ObjectRendererCollection();
@@ -24,6 +31,10 @@ namespace Textamina.Markdig.Renderers
public abstract object Render(MarkdownObject markdownObject);
/// <summary>
/// Writes the children of the specified <see cref="ContainerBlock"/>.
/// </summary>
/// <param name="containerBlock">The container block.</param>
public void WriteChildren(ContainerBlock containerBlock)
{
if (containerBlock == null)
@@ -38,6 +49,10 @@ namespace Textamina.Markdig.Renderers
}
}
/// <summary>
/// Writes the children of the specified <see cref="ContainerInline"/>.
/// </summary>
/// <param name="containerInline">The container inline.</param>
public void WriteChildren(ContainerInline containerInline)
{
if (containerInline == null)
@@ -53,6 +68,11 @@ namespace Textamina.Markdig.Renderers
}
}
/// <summary>
/// Writes the specified Markdown object.
/// </summary>
/// <typeparam name="T">A MarkdownObject type</typeparam>
/// <param name="obj">The Markdown object to write to this renderer.</param>
public void Write<T>(T obj) where T : MarkdownObject
{
if (obj == null)

View File

@@ -10,16 +10,29 @@ using Textamina.Markdig.Syntax.Inlines;
namespace Textamina.Markdig.Renderers
{
/// <summary>
/// A text based <see cref="IMarkdownRenderer"/>.
/// </summary>
/// <seealso cref="Textamina.Markdig.Renderers.RendererBase" />
public abstract class TextRendererBase : RendererBase
{
private TextWriter writer;
/// <summary>
/// Initializes a new instance of the <see cref="TextRendererBase"/> class.
/// </summary>
/// <param name="writer">The writer.</param>
/// <exception cref="System.ArgumentNullException"></exception>
protected TextRendererBase(TextWriter writer)
{
if (writer == null) throw new ArgumentNullException(nameof(writer));
this.Writer = writer;
}
/// <summary>
/// Gets or sets the writer.
/// </summary>
/// <exception cref="System.ArgumentNullException">if the value is null</exception>
public TextWriter Writer
{
get { return writer; }
@@ -34,6 +47,11 @@ namespace Textamina.Markdig.Renderers
}
}
/// <summary>
/// Renders the specified markdown object (returns the <see cref="Writer"/> as a render object).
/// </summary>
/// <param name="markdownObject">The markdown object.</param>
/// <returns></returns>
public override object Render(MarkdownObject markdownObject)
{
Write(markdownObject);
@@ -41,11 +59,20 @@ namespace Textamina.Markdig.Renderers
}
}
/// <summary>
/// Typed <see cref="TextRendererBase"/>.
/// </summary>
/// <typeparam name="T">Type of the renderer</typeparam>
/// <seealso cref="Textamina.Markdig.Renderers.RendererBase" />
public abstract class TextRendererBase<T> : TextRendererBase where T : TextRendererBase<T>
{
private bool previousWasLine;
private char[] buffer;
/// <summary>
/// Initializes a new instance of the <see cref="TextRendererBase{T}"/> class.
/// </summary>
/// <param name="writer">The writer.</param>
protected TextRendererBase(TextWriter writer) : base(writer)
{
buffer = new char[1024];
@@ -53,6 +80,10 @@ namespace Textamina.Markdig.Renderers
previousWasLine = true;
}
/// <summary>
/// Ensures a newline.
/// </summary>
/// <returns>This instance</returns>
public T EnsureLine()
{
if (!previousWasLine)
@@ -62,6 +93,11 @@ namespace Textamina.Markdig.Renderers
return (T)this;
}
/// <summary>
/// Writes the specified content.
/// </summary>
/// <param name="content">The content.</param>
/// <returns>This instance</returns>
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
public T Write(string content)
{
@@ -70,6 +106,11 @@ namespace Textamina.Markdig.Renderers
return (T) this;
}
/// <summary>
/// Writes the specified slice.
/// </summary>
/// <param name="slice">The slice.</param>
/// <returns>This instance</returns>
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
public T Write(ref StringSlice slice)
{
@@ -80,6 +121,11 @@ namespace Textamina.Markdig.Renderers
return Write(slice.Text, slice.Start, slice.Length);
}
/// <summary>
/// Writes the specified character.
/// </summary>
/// <param name="content">The content.</param>
/// <returns>This instance</returns>
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
public T Write(char content)
{
@@ -88,6 +134,13 @@ namespace Textamina.Markdig.Renderers
return (T) this;
}
/// <summary>
/// Writes the specified content.
/// </summary>
/// <param name="content">The content.</param>
/// <param name="offset">The offset.</param>
/// <param name="length">The length.</param>
/// <returns>This instance</returns>
public T Write(string content, int offset, int length)
{
previousWasLine = false;
@@ -111,6 +164,10 @@ namespace Textamina.Markdig.Renderers
return (T) this;
}
/// <summary>
/// Writes a newline.
/// </summary>
/// <returns>This instance</returns>
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
public T WriteLine()
{
@@ -119,6 +176,11 @@ namespace Textamina.Markdig.Renderers
return (T) this;
}
/// <summary>
/// Writes a content followed by a newline.
/// </summary>
/// <param name="content">The content.</param>
/// <returns>This instance</returns>
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
public T WriteLine(string content)
{
@@ -127,6 +189,11 @@ namespace Textamina.Markdig.Renderers
return (T) this;
}
/// <summary>
/// Writes the inlines of a leaf inline.
/// </summary>
/// <param name="leafBlock">The leaf block.</param>
/// <returns>This instance</returns>
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
public T WriteLeafInline(LeafBlock leafBlock)
{