From deb0b6dc23fe4a5fe7eaeba9d07855da3270009c Mon Sep 17 00:00:00 2001 From: Yanlong Wang Date: Sat, 23 Nov 2024 23:15:09 +0800 Subject: [PATCH] fix: potential gfm performance issue --- .../src/services/snapshot-formatter.ts | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/backend/functions/src/services/snapshot-formatter.ts b/backend/functions/src/services/snapshot-formatter.ts index be6d65c..4532421 100644 --- a/backend/functions/src/services/snapshot-formatter.ts +++ b/backend/functions/src/services/snapshot-formatter.ts @@ -45,14 +45,37 @@ export interface FormattedPage { export const md5Hasher = new HashManager('md5', 'hex'); const gfmPlugin = require('turndown-plugin-gfm'); +const highlightRegExp = /highlight-(?:text|source)-([a-z0-9]+)/; + +export function highlightedCodeBlock(turndownService: TurndownService) { + turndownService.addRule('highlightedCodeBlock', { + filter: (node) => { + return ( + node.nodeName === 'DIV' && + node.firstChild?.nodeName === 'PRE' && + highlightRegExp.test(node.className) + ); + }, + replacement: (_content, node, options)=> { + const className = (node as any).className || ''; + const language = (className.match(highlightRegExp) || [null, ''])[1]; + + return ( + '\n\n' + options.fence + language + '\n' + + node.firstChild!.textContent + + '\n' + options.fence + '\n\n' + ); + } + }); +} @singleton() export class SnapshotFormatter extends AsyncService { logger = this.globalLogger.child({ service: this.constructor.name }); - gfmPlugin = gfmPlugin.gfm; - gfmNoTable = [gfmPlugin.highlightedCodeBlock, gfmPlugin.strikethrough, gfmPlugin.taskListItems]; + gfmPlugin = [gfmPlugin.tables, highlightedCodeBlock, gfmPlugin.strikethrough, gfmPlugin.taskListItems]; + gfmNoTable = [highlightedCodeBlock, gfmPlugin.strikethrough, gfmPlugin.taskListItems]; constructor( protected globalLogger: Logger, @@ -475,7 +498,7 @@ ${suffixMixins.length ? `\n${suffixMixins.join('\n\n')}\n` : ''}`; imgDataUrlToObjectUrl?: boolean; removeImages?: boolean | 'src'; customRules?: { [k: string]: Rule; }; - customKeep?: Filter + customKeep?: Filter; }) { const turnDownService = new TurndownService({ codeBlockStyle: 'fenced',