Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#45 added Code Block Syntax Highlighting
- Loading branch information
Showing
10 changed files
with
219 additions
and
23 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
using System.Collections.Generic; | ||
using System.Text.RegularExpressions; | ||
using ColorCode; | ||
|
||
namespace Markdig.SyntaxHighlighting { | ||
public class LanguageTypeAdapter { | ||
private readonly Dictionary<string, ILanguage> languageMap = new Dictionary<string, ILanguage> { | ||
{"csharp", Languages.CSharp}, | ||
{"cplusplus", Languages.Cpp} | ||
}; | ||
|
||
public ILanguage Parse(string id, string firstLine = null) { | ||
if (id == null) { | ||
return null; | ||
} | ||
|
||
if (languageMap.ContainsKey(id)) { | ||
return languageMap[id]; | ||
} | ||
|
||
if (!string.IsNullOrWhiteSpace(firstLine)) { | ||
foreach (var lang in Languages.All) { | ||
if (lang.FirstLinePattern == null) { | ||
continue; | ||
} | ||
|
||
var firstLineMatcher = new Regex(lang.FirstLinePattern, RegexOptions.IgnoreCase); | ||
|
||
if (firstLineMatcher.IsMatch(firstLine)) { | ||
return lang; | ||
} | ||
} | ||
} | ||
|
||
var byIdCanidate = Languages.FindById(id); | ||
|
||
return byIdCanidate; | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
using System.IO; | ||
using System.Text; | ||
using ColorCode; | ||
using Markdig.Parsers; | ||
using Markdig.Renderers; | ||
using Markdig.Renderers.Html; | ||
using Markdig.Syntax; | ||
|
||
namespace Markdig.SyntaxHighlighting { | ||
public class SyntaxHighlightingCodeBlockRenderer : HtmlObjectRenderer<CodeBlock> { | ||
private readonly CodeBlockRenderer _underlyingRenderer; | ||
private readonly IStyleSheet _customCss; | ||
|
||
public SyntaxHighlightingCodeBlockRenderer(CodeBlockRenderer underlyingRenderer = null, IStyleSheet customCss = null) { | ||
_underlyingRenderer = underlyingRenderer ?? new CodeBlockRenderer(); | ||
_customCss = customCss; | ||
} | ||
|
||
protected override void Write(HtmlRenderer renderer, CodeBlock obj) { | ||
var fencedCodeBlock = obj as FencedCodeBlock; | ||
var parser = obj.Parser as FencedCodeBlockParser; | ||
if (fencedCodeBlock == null || parser == null) { | ||
_underlyingRenderer.Write(renderer, obj); | ||
return; | ||
} | ||
|
||
var attributes = obj.TryGetAttributes() ?? new HtmlAttributes(); | ||
|
||
var languageMoniker = fencedCodeBlock.Info.Replace(parser.InfoPrefix, string.Empty); | ||
if (string.IsNullOrEmpty(languageMoniker)) { | ||
_underlyingRenderer.Write(renderer, obj); | ||
return; | ||
} | ||
|
||
attributes.AddClass($"lang-{languageMoniker}"); | ||
attributes.Classes.Remove($"language-{languageMoniker}"); | ||
|
||
attributes.AddClass("editor-colors"); | ||
|
||
string firstLine; | ||
var code = GetCode(obj, out firstLine); | ||
|
||
renderer | ||
.Write("<div") | ||
.WriteAttributes(attributes) | ||
.Write(">"); | ||
|
||
var markup = ApplySyntaxHighlighting(languageMoniker, firstLine, code); | ||
|
||
renderer.WriteLine(markup); | ||
renderer.WriteLine("</div>"); | ||
} | ||
|
||
private string ApplySyntaxHighlighting(string languageMoniker, string firstLine, string code) { | ||
var languageTypeAdapter = new LanguageTypeAdapter(); | ||
var language = languageTypeAdapter.Parse(languageMoniker, firstLine); | ||
|
||
if (language == null) { //handle unrecognised language formats, e.g. when using mermaid diagrams | ||
return code; | ||
} | ||
|
||
var codeBuilder = new StringBuilder(); | ||
var codeWriter = new StringWriter(codeBuilder); | ||
var styleSheet = _customCss ?? StyleSheets.Default; | ||
var colourizer = new CodeColorizer(); | ||
colourizer.Colorize(code, language, Formatters.Default, styleSheet, codeWriter); | ||
return codeBuilder.ToString(); | ||
} | ||
|
||
private static string GetCode(LeafBlock obj, out string firstLine) { | ||
var code = new StringBuilder(); | ||
firstLine = null; | ||
foreach (var line in obj.Lines.Lines) { | ||
var slice = line.Slice; | ||
if (slice.Text == null) { | ||
continue; | ||
} | ||
|
||
var lineText = slice.Text.Substring(slice.Start, slice.Length); | ||
|
||
if (firstLine == null) { | ||
firstLine = lineText; | ||
} else { | ||
code.AppendLine(); | ||
} | ||
|
||
code.Append(lineText); | ||
} | ||
return code.ToString(); | ||
} | ||
} | ||
} |
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,36 @@ | ||
using System; | ||
using ColorCode; | ||
using Markdig.Renderers; | ||
using Markdig.Renderers.Html; | ||
|
||
namespace Markdig.SyntaxHighlighting { | ||
public class SyntaxHighlightingExtension : IMarkdownExtension { | ||
private readonly IStyleSheet _customCss; | ||
|
||
public SyntaxHighlightingExtension(IStyleSheet customCss = null) | ||
{ | ||
_customCss = customCss; | ||
} | ||
|
||
public void Setup(MarkdownPipelineBuilder pipeline) {} | ||
|
||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) { | ||
if (renderer == null) { | ||
throw new ArgumentNullException(nameof(renderer)); | ||
} | ||
|
||
var htmlRenderer = renderer as TextRendererBase<HtmlRenderer>; | ||
if (htmlRenderer == null) { | ||
return; | ||
} | ||
|
||
var originalCodeBlockRenderer = htmlRenderer.ObjectRenderers.FindExact<CodeBlockRenderer>(); | ||
if (originalCodeBlockRenderer != null) { | ||
htmlRenderer.ObjectRenderers.Remove(originalCodeBlockRenderer); | ||
} | ||
|
||
htmlRenderer.ObjectRenderers.AddIfNotAlready( | ||
new SyntaxHighlightingCodeBlockRenderer(originalCodeBlockRenderer, _customCss)); | ||
} | ||
} | ||
} |
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,10 @@ | ||
using ColorCode; | ||
|
||
namespace Markdig.SyntaxHighlighting { | ||
public static class SyntaxHighlightingExtensions { | ||
public static MarkdownPipelineBuilder UseSyntaxHighlighting(this MarkdownPipelineBuilder pipeline, IStyleSheet customCss = null) { | ||
pipeline.Extensions.Add(new SyntaxHighlightingExtension(customCss)); | ||
return pipeline; | ||
} | ||
} | ||
} |
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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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