mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-21 10:45:20 -04:00
56 lines
1.7 KiB
TypeScript
56 lines
1.7 KiB
TypeScript
/*
|
|
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
|
*
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
*/
|
|
|
|
import type { Element } from 'domhandler'
|
|
import React from 'react'
|
|
import { ComponentReplacer } from '../../replace-components/component-replacer'
|
|
import { HighlightedCode } from './highlighted-code'
|
|
|
|
/**
|
|
* Detects code blocks and renders them as highlighted code blocks
|
|
*/
|
|
export class HighlightedCodeReplacer extends ComponentReplacer {
|
|
private lastLineNumber = 0
|
|
|
|
private extractCode(codeNode: Element): string | undefined {
|
|
return codeNode.name === 'code' && !!codeNode.attribs['data-highlight-language'] && !!codeNode.children[0]
|
|
? ComponentReplacer.extractTextChildContent(codeNode)
|
|
: undefined
|
|
}
|
|
|
|
public replace(codeNode: Element): React.ReactElement | undefined {
|
|
const code = this.extractCode(codeNode)
|
|
if (!code) {
|
|
return
|
|
}
|
|
|
|
const language = codeNode.attribs['data-highlight-language']
|
|
const extraData = codeNode.attribs['data-extra']
|
|
const extraInfos = /(=(\d+|\+)?)?(!?)/.exec(extraData)
|
|
const showLineNumbers = extraInfos ? extraInfos[1]?.startsWith('=') : false
|
|
const startLineNumberAttribute = extraInfos?.[2] ?? ''
|
|
const wrapLines = extraInfos?.[3] === '!'
|
|
const startLineNumber =
|
|
startLineNumberAttribute === '+' ? this.lastLineNumber : parseInt(startLineNumberAttribute) || 1
|
|
|
|
if (showLineNumbers) {
|
|
this.lastLineNumber = startLineNumber + code.split('\n').filter((line) => !!line).length
|
|
}
|
|
|
|
return (
|
|
<HighlightedCode
|
|
language={language}
|
|
startLineNumber={showLineNumbers ? startLineNumber : undefined}
|
|
wrapLines={wrapLines}
|
|
code={code}
|
|
/>
|
|
)
|
|
}
|
|
|
|
reset() {
|
|
this.lastLineNumber = 0
|
|
}
|
|
}
|