Skip to content

Commit

Permalink
Add TextRendererBase.Write(char c, int count) method, and eliminate v…
Browse files Browse the repository at this point in the history
…arious string allocations
  • Loading branch information
iamcarbon committed Feb 9, 2024
1 parent f52ecee commit 0446959
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 34 deletions.
8 changes: 4 additions & 4 deletions src/Markdig/Renderers/Normalize/CodeBlockRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ protected override void Write(NormalizeRenderer renderer, CodeBlock obj)
{
if (obj is FencedCodeBlock fencedCodeBlock)
{
var fencedCharCount = Math.Min(fencedCodeBlock.OpeningFencedCharCount, fencedCodeBlock.ClosingFencedCharCount);
var opening = new string(fencedCodeBlock.FencedChar, fencedCharCount);
renderer.Write(opening);
int fencedCharCount = Math.Min(fencedCodeBlock.OpeningFencedCharCount, fencedCodeBlock.ClosingFencedCharCount);

renderer.Write(fencedCodeBlock.FencedChar, fencedCharCount);
if (fencedCodeBlock.Info != null)
{
renderer.Write(fencedCodeBlock.Info);
Expand All @@ -41,7 +41,7 @@ protected override void Write(NormalizeRenderer renderer, CodeBlock obj)
renderer.WriteLine();

renderer.WriteLeafRawLines(obj, true);
renderer.Write(opening);
renderer.Write(fencedCodeBlock.FencedChar, fencedCharCount);
}
else
{
Expand Down
19 changes: 12 additions & 7 deletions src/Markdig/Renderers/Normalize/HeadingRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,27 @@ namespace Markdig.Renderers.Normalize;
/// <seealso cref="NormalizeObjectRenderer{HeadingBlock}" />
public class HeadingRenderer : NormalizeObjectRenderer<HeadingBlock>
{
private static readonly string[] HeadingTexts = {
private static readonly string[] HeadingTexts = [
"#",
"##",
"###",
"####",
"#####",
"######",
};
];

protected override void Write(NormalizeRenderer renderer, HeadingBlock obj)
{
var headingText = obj.Level > 0 && obj.Level <= 6
? HeadingTexts[obj.Level - 1]
: new string('#', obj.Level);
{
if (obj.Level is > 0 and <= 6)
{
renderer.Write(HeadingTexts[obj.Level - 1]);
}
else
{
renderer.Write('#', obj.Level);
}

renderer.Write(headingText).Write(' ');
renderer.Write(' ');
renderer.WriteLeafInline(obj);

renderer.FinishBlock(renderer.Options.EmptyLineAfterHeading);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ public class EmphasisInlineRenderer : NormalizeObjectRenderer<EmphasisInline>
{
protected override void Write(NormalizeRenderer renderer, EmphasisInline obj)
{
var emphasisText = new string(obj.DelimiterChar, obj.DelimiterCount);
renderer.Write(emphasisText);
renderer.Write(obj.DelimiterChar, obj.DelimiterCount);
renderer.WriteChildren(obj);
renderer.Write(emphasisText);
renderer.Write(obj.DelimiterChar, obj.DelimiterCount);
}
}
8 changes: 3 additions & 5 deletions src/Markdig/Renderers/Roundtrip/CodeBlockRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ protected override void Write(RoundtripRenderer renderer, CodeBlock obj)
if (obj is FencedCodeBlock fencedCodeBlock)
{
renderer.Write(obj.TriviaBefore);
var opening = new string(fencedCodeBlock.FencedChar, fencedCodeBlock.OpeningFencedCharCount);
renderer.Write(opening);
renderer.Write(fencedCodeBlock.FencedChar, fencedCodeBlock.OpeningFencedCharCount);

if (!fencedCodeBlock.TriviaAfterFencedChar.IsEmpty)
{
Expand Down Expand Up @@ -56,9 +55,8 @@ protected override void Write(RoundtripRenderer renderer, CodeBlock obj)
renderer.WriteLeafRawLines(obj);

renderer.Write(fencedCodeBlock.TriviaBeforeClosingFence);
var closing = new string(fencedCodeBlock.FencedChar, fencedCodeBlock.ClosingFencedCharCount);
renderer.Write(closing);
if (!string.IsNullOrEmpty(closing))
renderer.Write(fencedCodeBlock.FencedChar, fencedCodeBlock.ClosingFencedCharCount);
if (fencedCodeBlock.ClosingFencedCharCount > 0)
{
// See example 207: "> ```\nfoo\n```"
renderer.WriteLine(obj.NewLine);
Expand Down
22 changes: 13 additions & 9 deletions src/Markdig/Renderers/Roundtrip/HeadingRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ namespace Markdig.Renderers.Roundtrip;
/// <seealso cref="RoundtripObjectRenderer{HeadingBlock}" />
public class HeadingRenderer : RoundtripObjectRenderer<HeadingBlock>
{
private static readonly string[] HeadingTexts = {
private static readonly string[] HeadingTexts = [
"#",
"##",
"###",
"####",
"#####",
"######",
};
];

protected override void Write(RoundtripRenderer renderer, HeadingBlock obj)
{
Expand All @@ -28,12 +28,11 @@ protected override void Write(RoundtripRenderer renderer, HeadingBlock obj)
renderer.RenderLinesBefore(obj);

var headingChar = obj.Level == 1 ? '=' : '-';
var line = new string(headingChar, obj.HeaderCharCount);

renderer.WriteLeafInline(obj);
renderer.WriteLine(obj.SetextNewline);
renderer.Write(obj.TriviaBefore);
renderer.Write(line);
renderer.Write(headingChar, obj.HeaderCharCount);
renderer.WriteLine(obj.NewLine);
renderer.Write(obj.TriviaAfter);

Expand All @@ -43,12 +42,17 @@ protected override void Write(RoundtripRenderer renderer, HeadingBlock obj)
{
renderer.RenderLinesBefore(obj);

var headingText = obj.Level > 0 && obj.Level <= 6
? HeadingTexts[obj.Level - 1]
: new string('#', obj.Level);

renderer.Write(obj.TriviaBefore);
renderer.Write(headingText);

if (obj.Level is > 0 and <= 6)
{
renderer.Write(HeadingTexts[obj.Level - 1]);
}
else
{
renderer.Write('#', obj.Level);
}

renderer.Write(obj.TriviaAfterAtxHeaderChar);
renderer.WriteLeafInline(obj);
renderer.Write(obj.TriviaAfter);
Expand Down
5 changes: 2 additions & 3 deletions src/Markdig/Renderers/Roundtrip/Inlines/CodeInlineRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ public class CodeInlineRenderer : RoundtripObjectRenderer<CodeInline>
{
protected override void Write(RoundtripRenderer renderer, CodeInline obj)
{
var delimiterRun = new string(obj.Delimiter, obj.DelimiterCount);
renderer.Write(delimiterRun);
renderer.Write(obj.Delimiter, obj.DelimiterCount);
if (!obj.ContentSpan.IsEmpty)
{
renderer.Write(obj.ContentWithTrivia);
}
renderer.Write(delimiterRun);
renderer.Write(obj.Delimiter, obj.DelimiterCount);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ public class EmphasisInlineRenderer : RoundtripObjectRenderer<EmphasisInline>
{
protected override void Write(RoundtripRenderer renderer, EmphasisInline obj)
{
var emphasisText = new string(obj.DelimiterChar, obj.DelimiterCount);
renderer.Write(emphasisText);
renderer.Write(obj.DelimiterChar, obj.DelimiterCount);
renderer.WriteChildren(obj);
renderer.Write(emphasisText);
renderer.Write(obj.DelimiterChar, obj.DelimiterCount);
}
}
19 changes: 19 additions & 0 deletions src/Markdig/Renderers/TextRendererBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,25 @@ public T Write(string? content)
return (T)this;
}

/// <summary>
/// Writes the specified char repeated a specified number of times.
/// </summary>
/// <param name="c">The char to write.</param>
/// <param name="count">The number of times to write the char.</param>
/// <returns>This instance</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal T Write(char c, int count)
{
WriteIndent();

for (int i = 0; i < count; i++)
{
Writer.Write(c);
}

return (T)this;
}

/// <summary>
/// Writes the specified slice.
/// </summary>
Expand Down

0 comments on commit 0446959

Please sign in to comment.