Skip to content
This repository has been archived by the owner on Oct 21, 2024. It is now read-only.

Commit

Permalink
add nfdi-code parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
Freymaurer committed Jun 20, 2022
1 parent a506c9c commit a54f783
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/Nfdi4Plants.Fornax/Loaders.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ namespace Fornax.Nfdi4Plants

module Pipelines =
open Markdig
open Fornax.Nfdi4Plants.MarkdigExtensions.NfdiCode
open Fornax.Nfdi4Plants.MarkdigExtensions.NfdiHeader
open Fornax.Nfdi4Plants.MarkdigExtensions.NfdiSidebarElementHeader

Expand All @@ -10,6 +11,7 @@ module Pipelines =
.UseAdvancedExtensions()
.UseEmojiAndSmiley()
.UseNFDIHeader()
.UseNFDICodeBlock()
.Build()

let sidebarMarkdownPipeline =
Expand Down
86 changes: 86 additions & 0 deletions src/Nfdi4Plants.Fornax/MarkdigExtensions/nfdi-code.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
namespace Fornax.Nfdi4Plants.MarkdigExtensions

open System.Text
open Markdig.Parsers;
open Markdig.Renderers;
open Markdig.Renderers.Html;
open Markdig.Syntax;
open Markdig

module NfdiCode =

open System

// https://github.com/ilich/Markdig.Prism/blob/main/src/Markdig.Prism/PrismCodeBlockRenderer.cs
type NFDICodeBlockRenderer() =
inherit HtmlObjectRenderer<CodeBlock>()

let extractSourcecode (node: LeafBlock) =
let code = new StringBuilder()
let lines = node.Lines.Lines
let totalLines = lines.Length
let rec appendLines (counter: int) (c: StringBuilder) =
if counter >= totalLines then
c
else
let line = lines[counter]
let slice = line.Slice
if isNull slice.Text then
appendLines (counter + 1) c
else
let lineText = slice.Text.Substring(slice.Start, slice.Length);
if counter > 0 then
appendLines (counter+1) (c.AppendLine().Append(lineText))
else
appendLines (counter+1) (c.Append(lineText))
appendLines 0 code
|> fun x -> x.ToString()

override this.Write(renderer : HtmlRenderer , cb : CodeBlock ) =

if cb :? FencedCodeBlock && cb.Parser :? FencedCodeBlockParser then
let fcb = cb :?> FencedCodeBlock
let parser = cb.Parser :?> FencedCodeBlockParser
let languageCode = fcb.Info.Replace(parser.InfoPrefix, "").Trim()
let code = extractSourcecode(cb)
if languageCode = "" then
renderer
.Write("<nfdi-code>")
.Write(code)
.Write("</nfdi-code>")
|> ignore
else
let attributes = new HtmlAttributes()
attributes.AddClass($"language-{languageCode}")

renderer
.Write("<nfdi-code")
.WriteAttributes(attributes)
.Write(">")
.Write(code)
.Write("</nfdi-code>")
|> ignore
else
// let codeBlockRenderer = new CodeBlockRenderer()
renderer.Write(cb) |> ignore

/// An extension for Markdig that highlights syntax in fenced code blocks
type NFDICodeExtension() =

interface IMarkdownExtension with

member __.Setup(_) = ()

member __.Setup(_, renderer) =
renderer.ObjectRenderers.ReplaceOrAdd<CodeBlockRenderer>(new NFDICodeBlockRenderer()) |> ignore

open System.Runtime.CompilerServices

[<Extension>]
type MarkdownPipelineBuilderExtensions() =
[<Extension>]
// <summary>Highlight code in fenced code blocks</summary>
// <param name="pipeline">The Markdig <see cref="MarkdownPipelineBuilder"/> to add the extension to</param>
static member UseNFDICodeBlock(pipeline : MarkdownPipelineBuilder) =
pipeline.Extensions.Add(NFDICodeExtension())
pipeline
1 change: 1 addition & 0 deletions src/Nfdi4Plants.Fornax/Nfdi4Plants.Fornax.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="MarkdigExtensions/nfdi-code.fs" />
<Compile Include="MarkdigExtensions/nfdi-header.fs" />
<Compile Include="MarkdigExtensions/nfdi-sidebar-element-header.fs" />
<Compile Include="Loaders.fs" />
Expand Down

0 comments on commit a54f783

Please sign in to comment.