Skip to content

Commit

Permalink
#45 added Code Block Syntax Highlighting
Browse files Browse the repository at this point in the history
  • Loading branch information
mohzy83 committed Dec 8, 2022
1 parent fbfa697 commit 9ebbb73
Show file tree
Hide file tree
Showing 10 changed files with 219 additions and 23 deletions.
40 changes: 40 additions & 0 deletions MarkdigWrapper/LanguageTypeAdapter.cs
@@ -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;
}
}
}
19 changes: 9 additions & 10 deletions MarkdigWrapper/MarkdigMarkdownGenerator.cs
Expand Up @@ -8,26 +8,26 @@
using Markdig.Renderers;
using Markdig.Renderers.Html;
using Markdig.Syntax;
using Markdig.SyntaxHighlighting;

namespace MarkdigWrapper
{
public class MarkdigMarkdownGenerator
public class MarkdigMarkdownGenerator
{
private readonly HtmlRenderer htmlRenderer;
private readonly StringWriter htmlWriter;
private readonly StringBuilder sb;

public MarkdigMarkdownGenerator()
{
sb = new StringBuilder();
htmlWriter = new StringWriter(sb);
htmlRenderer = new HtmlRenderer(htmlWriter);
}

public string ConvertToHtml(string markDownText, string filepath)
{
var sb = new StringBuilder();
var htmlWriter = new StringWriter(sb);
var htmlRenderer = new HtmlRenderer(htmlWriter);

var pipeline = new MarkdownPipelineBuilder()
.UseAdvancedExtensions()
.UseSyntaxHighlighting()
.UsePreciseSourceLocation()
.Build();
try
Expand All @@ -40,11 +40,10 @@ public string ConvertToHtml(string markDownText, string filepath)
{
htmlRenderer.BaseUrl = null;
}

}
catch (Exception e)
{
if (e != null) {}
if (e != null) { }
}
sb.Clear();

Expand Down Expand Up @@ -72,7 +71,7 @@ private void SetLineNoAttributeOnAllBlocks(ContainerBlock rootBlock)
attributes.Id = childBlock.Line.ToString();
childBlock.SetAttributes(attributes);
}

}
}
}
13 changes: 10 additions & 3 deletions MarkdigWrapper/MarkdigWrapper.csproj
Expand Up @@ -37,14 +37,21 @@
</PropertyGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Compile Include="LanguageTypeAdapter.cs" />
<Compile Include="MarkdigMarkdownGenerator.cs" />
<Compile Include="SyntaxHighlightingCodeBlockRenderer.cs" />
<Compile Include="SyntaxHighlightingExtension.cs" />
<Compile Include="SyntaxHighlightingExtensions.cs" />
<Compile Include="Wrapper.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="ColorCode, Version=1.0.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ColorCode.Portable.1.0.3\lib\portable45-net45+win8+wp8+wpa81\ColorCode.dll</HintPath>
</Reference>
<Reference Include="Markdig, Version=0.30.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Markdig.0.30.4\lib\net452\Markdig.dll</HintPath>
</Reference>
Expand Down
92 changes: 92 additions & 0 deletions MarkdigWrapper/SyntaxHighlightingCodeBlockRenderer.cs
@@ -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();
}
}
}
36 changes: 36 additions & 0 deletions MarkdigWrapper/SyntaxHighlightingExtension.cs
@@ -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));
}
}
}
10 changes: 10 additions & 0 deletions MarkdigWrapper/SyntaxHighlightingExtensions.cs
@@ -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;
}
}
}
1 change: 1 addition & 0 deletions MarkdigWrapper/packages.config
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="ColorCode.Portable" version="1.0.3" targetFramework="net452" />
<package id="Markdig" version="0.30.4" targetFramework="net452" />
<package id="System.Buffers" version="4.5.1" targetFramework="net452" />
<package id="System.Memory" version="4.5.4" targetFramework="net452" />
Expand Down
9 changes: 5 additions & 4 deletions NppMarkdownPanel/Forms/MainResources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions NppMarkdownPanel/Forms/MainResources.resx
Expand Up @@ -129,14 +129,20 @@ Created by Mohzy 2019-2022

Github: https://github.com/mohzy83/NppMarkdownPanel

Using Markdig by xoofx - https://github.com/lunet-io/markdig
Using Markdig 0.30.4 by xoofx - https://github.com/lunet-io/markdig

Using NotepadPlusPlusPluginPack.Net by kbilsted - https://github.com/kbilsted/NotepadPlusPlusPluginPack.Net
Using NotepadPlusPlusPluginPack.Net 0.95.00 by kbilsted - https://github.com/kbilsted/NotepadPlusPlusPluginPack.Net

Using Markdown style github-markdown-css by sindresorhus - https://github.com/sindresorhus/github-markdown-css
Using ColorCode (Portable) 1.0.3 by Bashir Souid and Richard Slater
https://github.com/RichardSlater/ColorCodePortable

Using Markdig.SyntaxHighlighting 1.0.3 - Syntax Highlighting extension for Markdig by Richard Slater
https://github.com/RichardSlater/Markdig.SyntaxHighlighting

Using portions of nea's MarkdownViewerPlusPlus Plugin code - https://github.com/nea/MarkdownViewerPlusPlus

Using Markdown style github-markdown-css by sindresorhus - https://github.com/sindresorhus/github-markdown-css

Using the Markdown icon by dcurtis - https://github.com/dcurtis/markdown-mark</value>
</data>
<data name="DefaultDarkModeCssFile" xml:space="preserve">
Expand Down
10 changes: 7 additions & 3 deletions NppMarkdownPanel/style-dark.css
Expand Up @@ -369,8 +369,9 @@ code, tt {
padding: 0 5px;
white-space: nowrap;
border: 1px solid #eaeaea;
background-color: #070707;
background-color: #f8f8f8;
border-radius: 3px;

}

pre code {
Expand All @@ -379,26 +380,29 @@ pre code {
white-space: pre;
border: none;
background: transparent;

}

.highlight pre {
background-color: #070707;
background-color: #f8f8f8;
border: 1px solid #cccccc;
font-size: 13px;
line-height: 19px;
overflow: auto;
padding: 6px 10px;
border-radius: 3px;
color: #333;
}

pre {
background-color: #070707;
background-color: #f8f8f8;
border: 1px solid #cccccc;
font-size: 13px;
line-height: 19px;
overflow: auto;
padding: 6px 10px;
border-radius: 3px;
color: #333;
}

pre code, pre tt {
Expand Down

0 comments on commit 9ebbb73

Please sign in to comment.