Create intermediate class for code block markdown extension

Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Tilman Vatteroth 2022-03-28 21:21:51 +02:00
parent 9b118ac203
commit 76cae637e6
11 changed files with 82 additions and 41 deletions

View file

@ -4,15 +4,15 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { MarkdownExtension } from '../markdown-extension'
import { CodeBlockComponentReplacer } from '../../replace-components/code-block-component-replacer'
import { AbcFrame } from './abc-frame'
import type { ComponentReplacer } from '../../replace-components/component-replacer'
import { CodeBlockMarkdownExtension } from '../code-block-markdown-extension/code-block-markdown-extension'
/**
* Adds support for abc.js to the markdown rendering using code fences with "abc" as language.
*/
export class AbcjsMarkdownExtension extends MarkdownExtension {
export class AbcjsMarkdownExtension extends CodeBlockMarkdownExtension {
public buildReplacers(): ComponentReplacer[] {
return [new CodeBlockComponentReplacer(AbcFrame, 'abc')]
}

View file

@ -0,0 +1,18 @@
/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type MarkdownIt from 'markdown-it'
import { codeBlockMarkdownPlugin } from './code-block-markdown-plugin'
import { MarkdownExtension } from '../markdown-extension'
/**
* A {@link MarkdownExtension markdown extension} that is used for code fence replacements.
*/
export abstract class CodeBlockMarkdownExtension extends MarkdownExtension {
public configureMarkdownIt(markdownIt: MarkdownIt): void {
codeBlockMarkdownPlugin(markdownIt)
}
}

View file

@ -0,0 +1,46 @@
/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type MarkdownIt from 'markdown-it'
import type { RuleCore } from 'markdown-it/lib/parser_core'
const ruleName = 'code-highlighter'
const codeFenceArguments = /^ *([\w-]*)(.*)$/
/**
* Extracts the language name and additional flags from the code fence parameter and sets them as attributes in the token.
*
* @param state The current state of the processing {@link MarkdownIt} instance.
* @see MarkdownIt.RuleCore
*/
const rule: RuleCore = (state) => {
state.tokens.forEach((token) => {
if (token.type === 'fence') {
const highlightInfos = codeFenceArguments.exec(token.info)
if (!highlightInfos) {
return
}
if (highlightInfos[1]) {
token.attrJoin('data-highlight-language', highlightInfos[1])
}
if (highlightInfos[2]) {
token.attrJoin('data-extra', highlightInfos[2])
}
}
})
return true
}
/**
* Adds the rule to the given {@link MarkdownIt markdown-it instance} if it hasn't been added yet.
*
* @param markdownIt The {@link MarkdownIt markdown-it instance} to which the rule should be added
*/
export const codeBlockMarkdownPlugin: MarkdownIt.PluginSimple = (markdownIt) => {
if (markdownIt.core.ruler.getRules(ruleName).length === 0) {
markdownIt.core.ruler.push(ruleName, rule, { alt: [ruleName] })
}
}

View file

@ -4,15 +4,15 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { MarkdownExtension } from '../markdown-extension'
import { CodeBlockComponentReplacer } from '../../replace-components/code-block-component-replacer'
import type { ComponentReplacer } from '../../replace-components/component-replacer'
import { FlowChart } from './flowchart'
import { CodeBlockMarkdownExtension } from '../code-block-markdown-extension/code-block-markdown-extension'
/**
* Adds support for flow charts to the markdown rendering using code fences with "flow" as language.
*/
export class FlowchartMarkdownExtension extends MarkdownExtension {
export class FlowchartMarkdownExtension extends CodeBlockMarkdownExtension {
public buildReplacers(): ComponentReplacer[] {
return [new CodeBlockComponentReplacer(FlowChart, 'flow')]
}

View file

@ -4,15 +4,15 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { MarkdownExtension } from '../markdown-extension'
import { CodeBlockComponentReplacer } from '../../replace-components/code-block-component-replacer'
import type { ComponentReplacer } from '../../replace-components/component-replacer'
import { GraphvizFrame } from './graphviz-frame'
import { CodeBlockMarkdownExtension } from '../code-block-markdown-extension/code-block-markdown-extension'
/**
* Adds support for graphviz to the markdown rendering using code fences with "graphviz" as language.
*/
export class GraphvizMarkdownExtension extends MarkdownExtension {
export class GraphvizMarkdownExtension extends CodeBlockMarkdownExtension {
public buildReplacers(): ComponentReplacer[] {
return [new CodeBlockComponentReplacer(GraphvizFrame, 'graphviz')]
}

View file

@ -4,38 +4,15 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { MarkdownExtension } from '../markdown-extension'
import type MarkdownIt from 'markdown-it'
import { HighlightedCodeReplacer } from './highlighted-code-replacer'
import type { ComponentReplacer } from '../../replace-components/component-replacer'
import { CodeBlockMarkdownExtension } from '../code-block-markdown-extension/code-block-markdown-extension'
/**
* Adds support code highlighting to the markdown rendering.
* Every code fence that is not replaced by another replacer is highlighted using highlightjs.
* Every code fence that is not replaced by another replacer is highlighted using highlight-js.
*/
export class HighlightedCodeMarkdownExtension extends MarkdownExtension {
private static readonly highlightRegex = /^ *([\w-]*)(.*)$/
public configureMarkdownIt(markdownIt: MarkdownIt): void {
markdownIt.core.ruler.push('highlighted-code', (state) => {
state.tokens.forEach((token) => {
if (token.type === 'fence') {
const highlightInfos = HighlightedCodeMarkdownExtension.highlightRegex.exec(token.info)
if (!highlightInfos) {
return
}
if (highlightInfos[1]) {
token.attrJoin('data-highlight-language', highlightInfos[1])
}
if (highlightInfos[2]) {
token.attrJoin('data-extra', highlightInfos[2])
}
}
})
return true
})
}
export class HighlightedCodeMarkdownExtension extends CodeBlockMarkdownExtension {
public buildReplacers(): ComponentReplacer[] {
return [new HighlightedCodeReplacer()]
}

View file

@ -4,15 +4,15 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { MarkdownExtension } from '../markdown-extension'
import { CodeBlockComponentReplacer } from '../../replace-components/code-block-component-replacer'
import type { ComponentReplacer } from '../../replace-components/component-replacer'
import { MarkmapFrame } from './markmap-frame'
import { CodeBlockMarkdownExtension } from '../code-block-markdown-extension/code-block-markdown-extension'
/**
* Adds support for markmap to the markdown rendering using code fences with "markmap" as language.
*/
export class MarkmapMarkdownExtension extends MarkdownExtension {
export class MarkmapMarkdownExtension extends CodeBlockMarkdownExtension {
public buildReplacers(): ComponentReplacer[] {
return [new CodeBlockComponentReplacer(MarkmapFrame, 'markmap')]
}

View file

@ -4,15 +4,15 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { MarkdownExtension } from '../markdown-extension'
import { CodeBlockComponentReplacer } from '../../replace-components/code-block-component-replacer'
import type { ComponentReplacer } from '../../replace-components/component-replacer'
import { MermaidChart } from './mermaid-chart'
import { CodeBlockMarkdownExtension } from '../code-block-markdown-extension/code-block-markdown-extension'
/**
* Adds support for chart rendering using mermaid to the markdown rendering using code fences with "mermaid" as language.
*/
export class MermaidMarkdownExtension extends MarkdownExtension {
export class MermaidMarkdownExtension extends CodeBlockMarkdownExtension {
public buildReplacers(): ComponentReplacer[] {
return [new CodeBlockComponentReplacer(MermaidChart, 'mermaid')]
}

View file

@ -4,15 +4,15 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { MarkdownExtension } from '../markdown-extension'
import { CodeBlockComponentReplacer } from '../../replace-components/code-block-component-replacer'
import type { ComponentReplacer } from '../../replace-components/component-replacer'
import { SequenceDiagram } from './sequence-diagram'
import { CodeBlockMarkdownExtension } from '../code-block-markdown-extension/code-block-markdown-extension'
/**
* Adds legacy support for sequence diagram to the markdown rendering using code fences with "sequence" as language.
*/
export class SequenceDiagramMarkdownExtension extends MarkdownExtension {
export class SequenceDiagramMarkdownExtension extends CodeBlockMarkdownExtension {
public buildReplacers(): ComponentReplacer[] {
return [new CodeBlockComponentReplacer(SequenceDiagram, 'sequence')]
}

View file

@ -4,15 +4,15 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { MarkdownExtension } from '../markdown-extension'
import { CodeBlockComponentReplacer } from '../../replace-components/code-block-component-replacer'
import type { ComponentReplacer } from '../../replace-components/component-replacer'
import { VegaLiteChart } from './vega-lite-chart'
import { CodeBlockMarkdownExtension } from '../code-block-markdown-extension/code-block-markdown-extension'
/**
* Adds support for chart rendering using vega lite to the markdown rendering using code fences with "vega-lite" as language.
*/
export class VegaLiteMarkdownExtension extends MarkdownExtension {
export class VegaLiteMarkdownExtension extends CodeBlockMarkdownExtension {
public buildReplacers(): ComponentReplacer[] {
return [new CodeBlockComponentReplacer(VegaLiteChart, 'vega-lite')]
}

View file

@ -14,7 +14,7 @@ import { CustomTagWithIdComponentReplacer } from '../../replace-components/custo
import { YouTubeFrame } from './youtube-frame'
/**
* Adds youtube video embeddings using link detection and the legacy youtube short code syntax.
* Adds YouTube video embeddings using link detection and the legacy YouTube short code syntax.
*/
export class YoutubeMarkdownExtension extends MarkdownExtension {
public static readonly tagName = 'app-youtube'