diff --git a/src/Markdig.Tests/TestNormalize.cs b/src/Markdig.Tests/TestNormalize.cs index adef0691d..df8be3f71 100644 --- a/src/Markdig.Tests/TestNormalize.cs +++ b/src/Markdig.Tests/TestNormalize.cs @@ -51,6 +51,16 @@ public void SyntaxHeadline() }); } + [Test] + public void SyntaxHeadlineLevel7() + { + AssertSyntax("####### Headline", new HeadingBlock(null) { + HeaderChar = '#', + Level = 7, + Inline = new ContainerInline().AppendChild(new LiteralInline("Headline")), + }); + } + [Test] public void SyntaxParagraph() { diff --git a/src/Markdig/Renderers/Normalize/CodeBlockRenderer.cs b/src/Markdig/Renderers/Normalize/CodeBlockRenderer.cs index 624ece86c..d6529e54c 100644 --- a/src/Markdig/Renderers/Normalize/CodeBlockRenderer.cs +++ b/src/Markdig/Renderers/Normalize/CodeBlockRenderer.cs @@ -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); @@ -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 { diff --git a/src/Markdig/Renderers/Normalize/HeadingRenderer.cs b/src/Markdig/Renderers/Normalize/HeadingRenderer.cs index 657df0046..0cf56c1bd 100644 --- a/src/Markdig/Renderers/Normalize/HeadingRenderer.cs +++ b/src/Markdig/Renderers/Normalize/HeadingRenderer.cs @@ -22,12 +22,17 @@ public class HeadingRenderer : NormalizeObjectRenderer ]; 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); diff --git a/src/Markdig/Renderers/Normalize/Inlines/CodeInlineRenderer.cs b/src/Markdig/Renderers/Normalize/Inlines/CodeInlineRenderer.cs index 7fdf42536..aaa38d8e7 100644 --- a/src/Markdig/Renderers/Normalize/Inlines/CodeInlineRenderer.cs +++ b/src/Markdig/Renderers/Normalize/Inlines/CodeInlineRenderer.cs @@ -31,8 +31,8 @@ protected override void Write(NormalizeRenderer renderer, CodeInline obj) if (delimiterCount < count) delimiterCount = count; } - var delimiterRun = new string(obj.Delimiter, delimiterCount + 1); - renderer.Write(delimiterRun); + + renderer.Write(obj.Delimiter, delimiterCount + 1); if (content.Length != 0) { if (content[0] == obj.Delimiter) @@ -49,6 +49,6 @@ protected override void Write(NormalizeRenderer renderer, CodeInline obj) { renderer.Write(' '); } - renderer.Write(delimiterRun); + renderer.Write(obj.Delimiter, delimiterCount + 1); } } \ No newline at end of file diff --git a/src/Markdig/Renderers/Normalize/Inlines/EmphasisInlineRenderer.cs b/src/Markdig/Renderers/Normalize/Inlines/EmphasisInlineRenderer.cs index 3e6a4328a..071951cd0 100644 --- a/src/Markdig/Renderers/Normalize/Inlines/EmphasisInlineRenderer.cs +++ b/src/Markdig/Renderers/Normalize/Inlines/EmphasisInlineRenderer.cs @@ -14,9 +14,8 @@ public class EmphasisInlineRenderer : NormalizeObjectRenderer { 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); } } \ No newline at end of file diff --git a/src/Markdig/Renderers/Roundtrip/CodeBlockRenderer.cs b/src/Markdig/Renderers/Roundtrip/CodeBlockRenderer.cs index 50d7dd9b6..5c90c4d28 100644 --- a/src/Markdig/Renderers/Roundtrip/CodeBlockRenderer.cs +++ b/src/Markdig/Renderers/Roundtrip/CodeBlockRenderer.cs @@ -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) { @@ -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); diff --git a/src/Markdig/Renderers/Roundtrip/HeadingRenderer.cs b/src/Markdig/Renderers/Roundtrip/HeadingRenderer.cs index 8471330a1..c99a17eef 100644 --- a/src/Markdig/Renderers/Roundtrip/HeadingRenderer.cs +++ b/src/Markdig/Renderers/Roundtrip/HeadingRenderer.cs @@ -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); @@ -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); diff --git a/src/Markdig/Renderers/Roundtrip/Inlines/CodeInlineRenderer.cs b/src/Markdig/Renderers/Roundtrip/Inlines/CodeInlineRenderer.cs index b4d03a2bb..2d149775b 100644 --- a/src/Markdig/Renderers/Roundtrip/Inlines/CodeInlineRenderer.cs +++ b/src/Markdig/Renderers/Roundtrip/Inlines/CodeInlineRenderer.cs @@ -14,12 +14,11 @@ public class CodeInlineRenderer : RoundtripObjectRenderer { 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); } } \ No newline at end of file diff --git a/src/Markdig/Renderers/Roundtrip/Inlines/EmphasisInlineRenderer.cs b/src/Markdig/Renderers/Roundtrip/Inlines/EmphasisInlineRenderer.cs index 5e61801ef..293919a3e 100644 --- a/src/Markdig/Renderers/Roundtrip/Inlines/EmphasisInlineRenderer.cs +++ b/src/Markdig/Renderers/Roundtrip/Inlines/EmphasisInlineRenderer.cs @@ -14,9 +14,8 @@ public class EmphasisInlineRenderer : RoundtripObjectRenderer { 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); } } \ No newline at end of file diff --git a/src/Markdig/Renderers/TextRendererBase.cs b/src/Markdig/Renderers/TextRendererBase.cs index ea9b31748..4d428a770 100644 --- a/src/Markdig/Renderers/TextRendererBase.cs +++ b/src/Markdig/Renderers/TextRendererBase.cs @@ -211,6 +211,25 @@ public T Write(string? content) return (T)this; } + /// + /// Writes the specified char repeated a specified number of times. + /// + /// The char to write. + /// The number of times to write the char. + /// This instance + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal T Write(char c, int count) + { + WriteIndent(); + + for (int i = 0; i < count; i++) + { + Writer.Write(c); + } + + return (T)this; + } + /// /// Writes the specified slice. ///