From d0a5982806ee7ad08aa0b4ef889f4788be05fe07 Mon Sep 17 00:00:00 2001 From: Martijn Laarman Date: Thu, 19 Dec 2024 19:05:35 +0100 Subject: [PATCH] Quick naming refactoring --- .../Myst/CodeBlocks/CallOut.cs | 16 +++++ .../Myst/CodeBlocks/CallOutParser.cs | 19 +++++ .../Myst/CodeBlocks/EnhancedCodeBlock.cs | 28 ++++++++ .../EnhancedCodeBlockHtmlRenderer.cs} | 56 +++++---------- .../EnhancedCodeBlockParser.cs} | 69 ++++--------------- .../EnhancedCodeMarkdownExtensions.cs | 33 +++++++++ .../Myst/Directives/DirectiveHtmlRenderer.cs | 4 +- src/Elastic.Markdown/Myst/MarkdownParser.cs | 4 +- .../CodeBlocks/CallOutTests.cs | 4 +- .../CodeBlocks/CodeTests.cs | 4 +- .../Inline/SubstitutionTest.cs | 4 +- 11 files changed, 137 insertions(+), 104 deletions(-) create mode 100644 src/Elastic.Markdown/Myst/CodeBlocks/CallOut.cs create mode 100644 src/Elastic.Markdown/Myst/CodeBlocks/CallOutParser.cs create mode 100644 src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeBlock.cs rename src/Elastic.Markdown/Myst/{CallOutCode/CallOutCodeMarkdownExtension.cs => CodeBlocks/EnhancedCodeBlockHtmlRenderer.cs} (63%) rename src/Elastic.Markdown/Myst/{CallOutCode/CallOutAwareFencedCodeBlock.cs => CodeBlocks/EnhancedCodeBlockParser.cs} (72%) create mode 100644 src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeMarkdownExtensions.cs diff --git a/src/Elastic.Markdown/Myst/CodeBlocks/CallOut.cs b/src/Elastic.Markdown/Myst/CodeBlocks/CallOut.cs new file mode 100644 index 0000000..dcc841c --- /dev/null +++ b/src/Elastic.Markdown/Myst/CodeBlocks/CallOut.cs @@ -0,0 +1,16 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information + +namespace Elastic.Markdown.Myst.CodeBlocks; + +public record CallOut +{ + public required int Index { get; init; } + public required string Text { get; init; } + public required bool InlineCodeAnnotation { get; init; } + + public required int SliceStart { get; init; } + + public required int Line { get; init; } +} diff --git a/src/Elastic.Markdown/Myst/CodeBlocks/CallOutParser.cs b/src/Elastic.Markdown/Myst/CodeBlocks/CallOutParser.cs new file mode 100644 index 0000000..66b740a --- /dev/null +++ b/src/Elastic.Markdown/Myst/CodeBlocks/CallOutParser.cs @@ -0,0 +1,19 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information + +using System.Text.RegularExpressions; + +namespace Elastic.Markdown.Myst.CodeBlocks; + +public static partial class CallOutParser +{ + [GeneratedRegex(@"^.+\S+.*?\s<\d+>$", RegexOptions.IgnoreCase, "en-US")] + public static partial Regex CallOutNumber(); + + [GeneratedRegex(@"^.+\S+.*?\s(?:\/\/|#)\s[^""]+$", RegexOptions.IgnoreCase, "en-US")] + public static partial Regex MathInlineAnnotation(); + + [GeneratedRegex(@"\{\{[^\r\n}]+?\}\}", RegexOptions.IgnoreCase, "en-US")] + public static partial Regex MatchSubstitutions(); +} diff --git a/src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeBlock.cs b/src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeBlock.cs new file mode 100644 index 0000000..b46b50b --- /dev/null +++ b/src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeBlock.cs @@ -0,0 +1,28 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information + +using System.IO.Abstractions; +using Elastic.Markdown.Myst.Directives; +using Markdig.Parsers; +using Markdig.Syntax; + +namespace Elastic.Markdown.Myst.CodeBlocks; + +public class EnhancedCodeBlock(BlockParser parser, ParserContext context) + : FencedCodeBlock(parser), IBlockExtension +{ + public BuildContext Build { get; } = context.Build; + + public IFileInfo CurrentFile { get; } = context.Path; + + public bool SkipValidation { get; } = context.SkipValidation; + + public int OpeningLength => Info?.Length ?? 0 + 3; + + public List? CallOuts { get; set; } + + public bool InlineAnnotations { get; set; } + + public string Language { get; set; } = "unknown"; +} diff --git a/src/Elastic.Markdown/Myst/CallOutCode/CallOutCodeMarkdownExtension.cs b/src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeBlockHtmlRenderer.cs similarity index 63% rename from src/Elastic.Markdown/Myst/CallOutCode/CallOutCodeMarkdownExtension.cs rename to src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeBlockHtmlRenderer.cs index c2db003..c3b724c 100644 --- a/src/Elastic.Markdown/Myst/CallOutCode/CallOutCodeMarkdownExtension.cs +++ b/src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeBlockHtmlRenderer.cs @@ -4,55 +4,37 @@ using Elastic.Markdown.Diagnostics; using Elastic.Markdown.Myst.Directives; -using Markdig; -using Markdig.Parsers; +using Elastic.Markdown.Slices.Directives; using Markdig.Renderers; using Markdig.Renderers.Html; using Markdig.Syntax; +using RazorSlices; -namespace Elastic.Markdown.Myst.CallOutCode; +namespace Elastic.Markdown.Myst.CodeBlocks; -public static class CallOutCodeBuilderExtensions +public class EnhancedCodeBlockHtmlRenderer : HtmlObjectRenderer { - public static MarkdownPipelineBuilder UseCallOutAwareCodeBlocks(this MarkdownPipelineBuilder pipeline) - { - pipeline.Extensions.AddIfNotAlready(); - return pipeline; - } -} -/// -/// Extension to allow custom containers. -/// -/// -public class CallOutCodeMarkdownExtension : IMarkdownExtension -{ - public void Setup(MarkdownPipelineBuilder pipeline) + private static void RenderRazorSlice(RazorSlice slice, HtmlRenderer renderer, EnhancedCodeBlock block) { - pipeline.BlockParsers.Replace(new CallOutAwareFencedCodeBlockParser()); - } - - public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) - { - if (!renderer.ObjectRenderers.Contains()) - { - // Must be inserted before CodeBlockRenderer - renderer.ObjectRenderers.InsertBefore(new DirectiveHtmlRenderer()); - } - - renderer.ObjectRenderers.Replace(new CallOutCodeRenderer()); + var html = slice.RenderAsync().GetAwaiter().GetResult(); + var blocks = html.Split("[CONTENT]", 2, StringSplitOptions.RemoveEmptyEntries); + renderer.Write(blocks[0]); + renderer.WriteLeafRawLines(block, true, false, false); + renderer.Write(blocks[1]); } -} - -public class CallOutCodeRenderer : HtmlObjectRenderer -{ - protected override void Write(HtmlRenderer renderer, CodeBlockWithCallOuts block) + protected override void Write(HtmlRenderer renderer, EnhancedCodeBlock block) { var callOuts = block.CallOuts ?? []; - renderer.WriteLine("
");
-		renderer.WriteLeafRawLines(block, true, false, false);
-		renderer.WriteLine("
"); + var slice = Code.Create(new CodeViewModel + { + CrossReferenceName = string.Empty,// block.CrossReferenceName, + Language = block.Language, + Caption = string.Empty + }); + + RenderRazorSlice(slice, renderer, block); if (!block.InlineAnnotations && callOuts.Count > 0) { diff --git a/src/Elastic.Markdown/Myst/CallOutCode/CallOutAwareFencedCodeBlock.cs b/src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeBlockParser.cs similarity index 72% rename from src/Elastic.Markdown/Myst/CallOutCode/CallOutAwareFencedCodeBlock.cs rename to src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeBlockParser.cs index cc148f9..ae77473 100644 --- a/src/Elastic.Markdown/Myst/CallOutCode/CallOutAwareFencedCodeBlock.cs +++ b/src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeBlockParser.cs @@ -2,70 +2,34 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information -using System.Collections.Frozen; -using System.IO.Abstractions; using System.Text.RegularExpressions; using Elastic.Markdown.Diagnostics; -using Elastic.Markdown.Myst.Directives; using Markdig.Helpers; using Markdig.Parsers; using Markdig.Syntax; -namespace Elastic.Markdown.Myst.CallOutCode; +namespace Elastic.Markdown.Myst.CodeBlocks; -public record CallOut -{ - public required int Index { get; init; } - public required string Text { get; init; } - public required bool InlineCodeAnnotation { get; init; } - - public required int SliceStart { get; init; } - - public required int Line { get; init; } -} - -public class CodeBlockWithCallOuts(BlockParser parser, ParserContext context) - : FencedCodeBlock(parser), IBlockExtension -{ - public BuildContext Build { get; } = context.Build; - - public IFileInfo CurrentFile { get; } = context.Path; - - public bool SkipValidation { get; } = context.SkipValidation; - - public int OpeningLength => Info?.Length ?? 0 + 3; - - public List? CallOuts { get; set; } - - public bool InlineAnnotations { get; set; } - - public string Language { get; set; } = "unknown"; -} - -/// -/// Parser for a . -/// -/// -public class CallOutAwareFencedCodeBlockParser : FencedBlockParserBase +public class EnhancedCodeBlockParser : FencedBlockParserBase { private const string DefaultInfoPrefix = "language-"; /// /// Initializes a new instance of the class. /// - public CallOutAwareFencedCodeBlockParser() + public EnhancedCodeBlockParser() { OpeningCharacters = ['`']; InfoPrefix = DefaultInfoPrefix; InfoParser = RoundtripInfoParser; } - protected override CodeBlockWithCallOuts CreateFencedBlock(BlockProcessor processor) + protected override EnhancedCodeBlock CreateFencedBlock(BlockProcessor processor) { if (processor.Context is not ParserContext context) throw new Exception("Expected parser context to be of type ParserContext"); - var codeBlock = new CodeBlockWithCallOuts(this, context) { IndentCount = processor.Indent }; + var codeBlock = new EnhancedCodeBlock(this, context) { IndentCount = processor.Indent }; if (processor.TrackTrivia) { @@ -85,7 +49,7 @@ public override BlockState TryContinue(BlockProcessor processor, Block block) var result = base.TryContinue(processor, block); if (result == BlockState.Continue && !processor.TrackTrivia) { - var fence = (CodeBlockWithCallOuts)block; + var fence = (EnhancedCodeBlock)block; // Remove any indent spaces var c = processor.CurrentChar; var indentCount = fence.IndentCount; @@ -101,7 +65,7 @@ public override BlockState TryContinue(BlockProcessor processor, Block block) public override bool Close(BlockProcessor processor, Block block) { - if (block is not CodeBlockWithCallOuts codeBlock) + if (block is not EnhancedCodeBlock codeBlock) return base.Close(processor, block); if (processor.Context is not ParserContext context) @@ -111,7 +75,7 @@ public override bool Close(BlockProcessor processor, Block block) (codeBlock.Info?.IndexOf("{") ?? -1) != -1 ? codeBlock.Arguments : codeBlock.Info - ) ?? "unknown"; + ) ?? "unknown"; var lines = codeBlock.Lines; var callOutIndex = 0; @@ -153,7 +117,10 @@ public override bool Close(BlockProcessor processor, Block block) foreach (var callout in codeBlock.CallOuts) { var line = lines.Lines[callout.Line - 1]; - line.Slice.End = line.Slice.Start + callout.SliceStart; + + var newSpan = line.Slice.AsSpan()[..callout.SliceStart]; + var s = new StringSlice(newSpan.ToString()); + lines.Lines[callout.Line -1 ] = new StringLine(ref s); } } @@ -234,15 +201,3 @@ private static bool ReplaceSubstitutions(ParserContext context, ReadOnlySpan$", RegexOptions.IgnoreCase, "en-US")] - public static partial Regex CallOutNumber(); - - [GeneratedRegex(@"^.+\S+.*?\s(?:\/\/|#)\s[^""]+$", RegexOptions.IgnoreCase, "en-US")] - public static partial Regex MathInlineAnnotation(); - - [GeneratedRegex(@"\{\{[^\r\n}]+?\}\}", RegexOptions.IgnoreCase, "en-US")] - public static partial Regex MatchSubstitutions(); -} diff --git a/src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeMarkdownExtensions.cs b/src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeMarkdownExtensions.cs new file mode 100644 index 0000000..9c6f003 --- /dev/null +++ b/src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeMarkdownExtensions.cs @@ -0,0 +1,33 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information + +using Elastic.Markdown.Myst.Directives; +using Markdig; +using Markdig.Parsers; +using Markdig.Renderers; +using Markdig.Renderers.Html; + +namespace Elastic.Markdown.Myst.CodeBlocks; + +public static class EnhancedCodeBuilderExtensions +{ + public static MarkdownPipelineBuilder UseEnhancedCodeBlocks(this MarkdownPipelineBuilder pipeline) + { + pipeline.Extensions.AddIfNotAlready(); + return pipeline; + } +} + +/// +/// Extension to allow custom containers. +/// +/// +public class EnhancedCodeBlockExtension : IMarkdownExtension +{ + public void Setup(MarkdownPipelineBuilder pipeline) => + pipeline.BlockParsers.Replace(new EnhancedCodeBlockParser()); + + public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) => + renderer.ObjectRenderers.Replace(new EnhancedCodeBlockHtmlRenderer()); +} diff --git a/src/Elastic.Markdown/Myst/Directives/DirectiveHtmlRenderer.cs b/src/Elastic.Markdown/Myst/Directives/DirectiveHtmlRenderer.cs index c27ed17..4e68d17 100644 --- a/src/Elastic.Markdown/Myst/Directives/DirectiveHtmlRenderer.cs +++ b/src/Elastic.Markdown/Myst/Directives/DirectiveHtmlRenderer.cs @@ -6,7 +6,7 @@ // See the license.txt file in the project root for more information. using Elastic.Markdown.Diagnostics; -using Elastic.Markdown.Myst.CallOutCode; +using Elastic.Markdown.Myst.CodeBlocks; using Elastic.Markdown.Myst.FrontMatter; using Elastic.Markdown.Myst.Settings; using Elastic.Markdown.Myst.Substitution; @@ -162,7 +162,7 @@ private void WriteDropdown(HtmlRenderer renderer, DropdownBlock block) RenderRazorSlice(slice, renderer, block); } - private void WriteCode(HtmlRenderer renderer, CodeBlockWithCallOuts block) + private void WriteCode(HtmlRenderer renderer, EnhancedCodeBlock block) { var slice = Code.Create(new CodeViewModel { diff --git a/src/Elastic.Markdown/Myst/MarkdownParser.cs b/src/Elastic.Markdown/Myst/MarkdownParser.cs index 0f36c82..aed329a 100644 --- a/src/Elastic.Markdown/Myst/MarkdownParser.cs +++ b/src/Elastic.Markdown/Myst/MarkdownParser.cs @@ -5,7 +5,7 @@ using System.IO.Abstractions; using Cysharp.IO; using Elastic.Markdown.IO; -using Elastic.Markdown.Myst.CallOutCode; +using Elastic.Markdown.Myst.CodeBlocks; using Elastic.Markdown.Myst.Comments; using Elastic.Markdown.Myst.Directives; using Elastic.Markdown.Myst.FrontMatter; @@ -49,7 +49,7 @@ public class MarkdownParser( .UseGridTables() .UsePipeTables() .UseDirectives() - .UseCallOutAwareCodeBlocks() + .UseEnhancedCodeBlocks() .DisableHtml() .Build(); diff --git a/tests/Elastic.Markdown.Tests/CodeBlocks/CallOutTests.cs b/tests/Elastic.Markdown.Tests/CodeBlocks/CallOutTests.cs index b67e9c1..550aed3 100644 --- a/tests/Elastic.Markdown.Tests/CodeBlocks/CallOutTests.cs +++ b/tests/Elastic.Markdown.Tests/CodeBlocks/CallOutTests.cs @@ -2,7 +2,7 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information -using Elastic.Markdown.Myst.CallOutCode; +using Elastic.Markdown.Myst.CodeBlocks; using Elastic.Markdown.Tests.Inline; using FluentAssertions; using JetBrains.Annotations; @@ -16,7 +16,7 @@ public abstract class CodeBlockCallOutTests( [LanguageInjection("csharp")] string code, [LanguageInjection("markdown")] string? markdown = null ) - : BlockTest(output, + : BlockTest(output, $$""" ```{{language}} {{code}} diff --git a/tests/Elastic.Markdown.Tests/CodeBlocks/CodeTests.cs b/tests/Elastic.Markdown.Tests/CodeBlocks/CodeTests.cs index e0920ce..f5f0707 100644 --- a/tests/Elastic.Markdown.Tests/CodeBlocks/CodeTests.cs +++ b/tests/Elastic.Markdown.Tests/CodeBlocks/CodeTests.cs @@ -2,7 +2,7 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information -using Elastic.Markdown.Myst.CallOutCode; +using Elastic.Markdown.Myst.CodeBlocks; using Elastic.Markdown.Tests.Inline; using FluentAssertions; using Xunit.Abstractions; @@ -10,7 +10,7 @@ namespace Elastic.Markdown.Tests.CodeBlocks; public abstract class CodeBlockTests(ITestOutputHelper output, string directive, string? language = null) - : BlockTest(output, + : BlockTest(output, $$""" ```{{directive}} {{language}} var x = 1; diff --git a/tests/Elastic.Markdown.Tests/Inline/SubstitutionTest.cs b/tests/Elastic.Markdown.Tests/Inline/SubstitutionTest.cs index 7889c02..e82debb 100644 --- a/tests/Elastic.Markdown.Tests/Inline/SubstitutionTest.cs +++ b/tests/Elastic.Markdown.Tests/Inline/SubstitutionTest.cs @@ -2,7 +2,7 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information -using Elastic.Markdown.Myst.CallOutCode; +using Elastic.Markdown.Myst.CodeBlocks; using Elastic.Markdown.Myst.Substitution; using FluentAssertions; using Xunit.Abstractions; @@ -65,7 +65,7 @@ public void GeneratesAttributesInHtml() => ); } -public class SubstitutionInCodeBlockTest(ITestOutputHelper output) : BlockTest(output, +public class SubstitutionInCodeBlockTest(ITestOutputHelper output) : BlockTest(output, """ --- sub: