-
Notifications
You must be signed in to change notification settings - Fork 868
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Added extensions configuration point and PlantUml support (#9574)
* Added extensions configuration point and PlantUmlExtension * Address review comments and improve error handling of PlantUmlExtension * Remove output formatters * Update JsonConverterTest.cs to ignoreLineEndingDifferences * Update JsonConverterTest.cs --------- Co-authored-by: Yufei Huang <yufeih@live.com>
- Loading branch information
Showing
16 changed files
with
365 additions
and
247 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
src/Docfx.MarkdigEngine.Extensions/PlantUml/PlantUmlCodeBlockRenderer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
using static System.Text.Encoding; | ||
|
||
using Markdig.Renderers; | ||
using Markdig.Syntax; | ||
using Markdig.Renderers.Html; | ||
using PlantUml.Net; | ||
|
||
namespace Docfx.MarkdigEngine.Extensions; | ||
|
||
/// <summary> | ||
/// An HTML renderer for a <see cref="CodeBlock"/> and <see cref="FencedCodeBlock"/>. | ||
/// </summary> | ||
/// <seealso cref="HtmlObjectRenderer{CodeBlock}" /> | ||
public class CustomCodeBlockRenderer : CodeBlockRenderer | ||
{ | ||
private readonly MarkdownContext _context; | ||
private readonly DocfxPlantUmlSettings _settings; | ||
private readonly RendererFactory rendererFactory; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="CodeBlockRenderer"/> class. | ||
/// </summary> | ||
/// <param name="context"></param> | ||
/// <param name="settings"></param> | ||
public CustomCodeBlockRenderer(MarkdownContext context, DocfxPlantUmlSettings settings) | ||
{ | ||
_context = context; | ||
_settings = settings; | ||
|
||
rendererFactory = new RendererFactory(); | ||
} | ||
|
||
protected override void Write(HtmlRenderer renderer, CodeBlock obj) | ||
{ | ||
if (obj is FencedCodeBlock fencedCodeBlock | ||
&& fencedCodeBlock.Info is string info | ||
&& info.Equals("plantuml", StringComparison.OrdinalIgnoreCase)) | ||
{ | ||
IPlantUmlRenderer plantUmlRenderer = rendererFactory.CreateRenderer(_settings); | ||
|
||
// Get PlantUML code. | ||
var plantUmlCode = fencedCodeBlock.Lines.ToString(); | ||
|
||
try | ||
{ | ||
byte[] output = plantUmlRenderer.Render(plantUmlCode, _settings.OutputFormat); | ||
|
||
renderer.EnsureLine(); | ||
renderer.Write(FormatOutput(_settings.OutputFormat, output)); | ||
renderer.EnsureLine(); | ||
} | ||
catch (RenderingException ex) | ||
{ | ||
_context.LogWarning(nameof(PlantUmlExtension), ex.Message, null); | ||
} | ||
catch (Exception ex) | ||
{ | ||
_context.LogError(nameof(PlantUmlExtension), ex.Message, null); | ||
|
||
// If the error is not related to rendering a specific diagram, re-throw to abort | ||
throw; | ||
} | ||
|
||
return; | ||
} | ||
|
||
// Fallback to default CodeBlockRenderer | ||
base.Write(renderer, obj); | ||
} | ||
|
||
private static string FormatOutput(OutputFormat format, byte[] output) | ||
{ | ||
switch (format) | ||
{ | ||
case OutputFormat.Svg: | ||
string svg = UTF8.GetString(output); | ||
return $"<div class=\"lang-plantUml\">{svg}</div>"; | ||
|
||
case OutputFormat.Ascii: | ||
string ascii = ASCII.GetString(output); | ||
return $"<div class=\"lang-plantUml\"><pre>{ascii}</pre></div>"; | ||
|
||
case OutputFormat.Ascii_Unicode: | ||
string asciiUnicode = UTF8.GetString(output); | ||
return $"<div class=\"lang-plantUml\"><pre>{asciiUnicode}</pre></div>"; | ||
|
||
case OutputFormat.Png: | ||
case OutputFormat.Eps: | ||
case OutputFormat.Pdf: | ||
case OutputFormat.Vdx: | ||
case OutputFormat.Xmi: | ||
case OutputFormat.Scxml: | ||
case OutputFormat.Html: | ||
case OutputFormat.LaTeX: | ||
default: | ||
throw new NotSupportedException($"Output format {format} is currently not supported"); | ||
} | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
src/Docfx.MarkdigEngine.Extensions/PlantUml/PlantUmlExtension.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
using Markdig; | ||
using Markdig.Renderers; | ||
using Markdig.Renderers.Html; | ||
using PlantUml.Net; | ||
|
||
namespace Docfx.MarkdigEngine.Extensions; | ||
|
||
public class DocfxPlantUmlSettings : PlantUmlSettings | ||
{ | ||
public DocfxPlantUmlSettings() : base() | ||
{ | ||
} | ||
|
||
public DocfxPlantUmlSettings(IReadOnlyDictionary<string, string> config) : this() | ||
{ | ||
if (config.TryGetValue("remoteUrl", out var url)) | ||
RemoteUrl = url; | ||
if (config.TryGetValue("outputFormat", out var format)) | ||
OutputFormat = Enum.Parse<OutputFormat>(format, true); | ||
if (config.TryGetValue("javaPath", out var path)) | ||
JavaPath = path; | ||
if (config.TryGetValue("localPlantUmlPath", out path)) | ||
LocalPlantUmlPath = path; | ||
if (config.TryGetValue("localGraphvizDotPath", out path)) | ||
LocalGraphvizDotPath = path; | ||
if (config.TryGetValue("renderingMode", out var renderMode)) | ||
RenderingMode = Enum.Parse<RenderingMode>(renderMode, true); | ||
} | ||
|
||
public OutputFormat OutputFormat { get; set; } = OutputFormat.Svg; | ||
} | ||
|
||
internal class PlantUmlExtension : IMarkdownExtension | ||
{ | ||
private readonly MarkdownContext _context; | ||
private readonly DocfxPlantUmlSettings _settings; | ||
|
||
public PlantUmlExtension(MarkdownContext context) | ||
{ | ||
_context = context; | ||
_settings = new(); | ||
|
||
if (_context.GetExtensionConfiguration("PlantUml") is Dictionary<string, string> config) | ||
_settings = new DocfxPlantUmlSettings(config); | ||
} | ||
|
||
public void Setup(MarkdownPipelineBuilder pipeline) | ||
{ | ||
} | ||
|
||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) | ||
{ | ||
if (renderer is HtmlRenderer { ObjectRenderers: not null } htmlRenderer) | ||
{ | ||
var customRenderer = new CustomCodeBlockRenderer(_context, _settings); | ||
var renderers = htmlRenderer.ObjectRenderers; | ||
|
||
if (renderers.Contains<CodeBlockRenderer>()) | ||
{ | ||
renderers.InsertBefore<CodeBlockRenderer>(customRenderer); | ||
} | ||
else | ||
{ | ||
renderers.AddIfNotAlready(customRenderer); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.