Skip to content

Commit

Permalink
Update DiagramExtension.cs
Browse files Browse the repository at this point in the history
Update tests
  • Loading branch information
xoofx committed Oct 25, 2024
1 parent 41bdb0f commit 090e6d7
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 18 deletions.
8 changes: 4 additions & 4 deletions src/Markdig.Tests/Specs/DiagramsSpecs.generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class TestExtensionsMermaidDiagrams
//
// ## Mermaid diagrams
//
// Using a fenced code block with the `mermaid` language info will output a `<div class='mermaid'>` instead of a `pre/code` block:
// Using a fenced code block with the `mermaid` language info will output a `<pre class='mermaid'>` block (which is the default for other code block):
[Test]
public void ExtensionsMermaidDiagrams_Example001()
{
Expand All @@ -34,14 +34,14 @@ public void ExtensionsMermaidDiagrams_Example001()
// ```
//
// Should be rendered as:
// <div class="mermaid">graph TD;
// <pre class="mermaid">graph TD;
// A-->B;
// A-->C;
// B-->D;
// C-->D;
// </div>
// </pre>

TestParser.TestSpec("```mermaid\ngraph TD;\n A-->B;\n A-->C;\n B-->D;\n C-->D;\n```", "<div class=\"mermaid\">graph TD;\n A-->B;\n A-->C;\n B-->D;\n C-->D;\n</div>", "diagrams|advanced", context: "Example 1\nSection Extensions / Mermaid diagrams\n");
TestParser.TestSpec("```mermaid\ngraph TD;\n A-->B;\n A-->C;\n B-->D;\n C-->D;\n```", "<pre class=\"mermaid\">graph TD;\n A-->B;\n A-->C;\n B-->D;\n C-->D;\n</pre>", "diagrams|advanced", context: "Example 1\nSection Extensions / Mermaid diagrams\n");
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/Markdig.Tests/Specs/DiagramsSpecs.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Adds support for diagrams extension:

## Mermaid diagrams

Using a fenced code block with the `mermaid` language info will output a `<div class='mermaid'>` instead of a `pre/code` block:
Using a fenced code block with the `mermaid` language info will output a `<pre class='mermaid'>` block (which is the default for other code block):

```````````````````````````````` example
```mermaid
Expand All @@ -15,12 +15,12 @@ graph TD;
C-->D;
```
.
<div class="mermaid">graph TD;
<pre class="mermaid">graph TD;
A-->B;
A-->C;
B-->D;
C-->D;
</div>
</pre>
````````````````````````````````

## nomnoml diagrams
Expand Down
7 changes: 3 additions & 4 deletions src/Markdig/Extensions/Diagrams/DiagramExtension.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.

using Markdig.Renderers;
Expand All @@ -22,9 +22,8 @@ public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
if (renderer is HtmlRenderer htmlRenderer)
{
var codeRenderer = htmlRenderer.ObjectRenderers.FindExact<CodeBlockRenderer>()!;
// TODO: Add other well known diagram languages
codeRenderer.BlocksAsDiv.Add("mermaid");
codeRenderer.BlockMapping["mermaid"] = "pre";
codeRenderer.BlocksAsDiv.Add("nomnoml");
}
}
}
}
21 changes: 14 additions & 7 deletions src/Markdig/Renderers/Html/CodeBlockRenderer.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.

using Markdig.Parsers;
Expand All @@ -13,8 +13,6 @@ namespace Markdig.Renderers.Html;
/// <seealso cref="HtmlObjectRenderer{CodeBlock}" />
public class CodeBlockRenderer : HtmlObjectRenderer<CodeBlock>
{
private HashSet<string>? _blocksAsDiv;

/// <summary>
/// Initializes a new instance of the <see cref="CodeBlockRenderer"/> class.
/// </summary>
Expand All @@ -25,23 +23,32 @@ public CodeBlockRenderer() { }
/// <summary>
/// Gets a map of fenced code block infos that should be rendered as div blocks instead of pre/code blocks.
/// </summary>
public HashSet<string> BlocksAsDiv => _blocksAsDiv ??= new HashSet<string>(StringComparer.OrdinalIgnoreCase);
public HashSet<string> BlocksAsDiv { get; } = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

/// <summary>
/// Gets a map of custom block mapping to render as custom blocks instead of pre/code blocks.
/// For example defining {"mermaid", "pre"} will render a block with info `mermaid` as a `pre` block but without the code HTML element.
/// </summary>
public Dictionary<string, string> BlockMapping { get; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

protected override void Write(HtmlRenderer renderer, CodeBlock obj)
{
renderer.EnsureLine();

if (_blocksAsDiv is not null && (obj as FencedCodeBlock)?.Info is string info && _blocksAsDiv.Contains(info))
if ((obj as FencedCodeBlock)?.Info is string info && (BlocksAsDiv.Contains(info) || BlockMapping.ContainsKey(info)))
{
var infoPrefix = (obj.Parser as FencedCodeBlockParser)?.InfoPrefix ??
FencedCodeBlockParser.DefaultInfoPrefix;

var htmlBlock = BlockMapping.TryGetValue(info, out var blockType) ? blockType : "div";

// We are replacing the HTML attribute `language-mylang` by `mylang` only for a div block
// NOTE that we are allocating a closure here

if (renderer.EnableHtmlForBlock)
{
renderer.Write("<div")
renderer.WriteRaw('<');
renderer.Write(htmlBlock)
.WriteAttributes(obj.TryGetAttributes(),
cls => cls.StartsWith(infoPrefix, StringComparison.Ordinal) ? cls.Substring(infoPrefix.Length) : cls)
.WriteRaw('>');
Expand All @@ -51,7 +58,7 @@ protected override void Write(HtmlRenderer renderer, CodeBlock obj)

if (renderer.EnableHtmlForBlock)
{
renderer.WriteLine("</div>");
renderer.Write("</").Write(htmlBlock).WriteLine(">");
}
}
else
Expand Down
2 changes: 2 additions & 0 deletions src/markdig.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
This file is licensed under the BSD-Clause 2 license. &#xD;
See the license.txt file in the project root for more information.</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=4a98fdf6_002D7d98_002D4f5a_002Dafeb_002Dea44ad98c70c/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002ECodeCleanup_002EFileHeader_002EFileHeaderSettingsMigrate/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/Environment/UnitTesting/NUnitProvider/SetCurrentDirectoryTo/@EntryValue">TestFolder</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Autolink/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Inlines/@EntryIndexedValue">True</s:Boolean>
Expand Down

0 comments on commit 090e6d7

Please sign in to comment.