Skip to content

Commit abeae04

Browse files
committed
refactor(theme-common): Splitup parseLines
1 parent fd4d03a commit abeae04

File tree

1 file changed

+55
-9
lines changed

1 file changed

+55
-9
lines changed

packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,36 @@ export function parseLines(
257257
content: string,
258258
options: CodeBlockParseLinesOptions,
259259
): CodeBlockParsedLines {
260-
let code = content.replace(/\n$/, '');
261-
const {language, magicComments, metastring} = options;
260+
const parsedLines: CodeBlockParsedLines = {
261+
code: content.replace(/\n$/, ''),
262+
lineClassNames: {},
263+
};
264+
262265
// Highlighted lines specified in props: don't parse the content
266+
if (fillLineClassNamesFromMetastring(parsedLines, options)) {
267+
return parsedLines;
268+
}
269+
270+
fillLineClassNamesFromCode(parsedLines, options);
271+
272+
return parsedLines;
273+
}
274+
275+
/**
276+
* Parses {@link CodeBlockParsedLines.lineClassNames} from the given metastring and fills
277+
* it into {@link parsedLines}.
278+
* @param parsedLines The object to fill the parsed class names into.
279+
* @param options The options to configure the parsing behavior.
280+
* @throws {Error} Will throw an error if the metastring contains highlighted lines, but there are no magic comments configured.
281+
* @returns `true` if the metastring contained any highlighted lines, otherwise `false`.
282+
*/
283+
function fillLineClassNamesFromMetastring(
284+
parsedLines: CodeBlockParsedLines,
285+
options: CodeBlockParseLinesOptions,
286+
): boolean {
287+
const {magicComments, metastring} = options;
288+
const {lineClassNames} = parsedLines;
289+
263290
if (metastring && metastringLinesRangeRegex.test(metastring)) {
264291
const linesRange = metastring.match(metastringLinesRangeRegex)!.groups!
265292
.range!;
@@ -269,14 +296,35 @@ export function parseLines(
269296
);
270297
}
271298
const metastringRangeClassName = magicComments[0]!.className;
272-
const lines = rangeParser(linesRange)
299+
rangeParser(linesRange)
273300
.filter((n) => n > 0)
274-
.map((n) => [n - 1, [metastringRangeClassName]] as [number, string[]]);
275-
return {lineClassNames: Object.fromEntries(lines), code};
301+
.forEach((n) => {
302+
lineClassNames[n - 1] = [metastringRangeClassName];
303+
});
304+
return true;
276305
}
306+
307+
return false;
308+
}
309+
310+
/**
311+
* Parses {@link CodeBlockParsedLines.lineClassNames} from the magic comments contained in the source code,
312+
* The magic comments are erased from {@link CodeBlockParsedLines.code} during this process.
313+
* @param parsedLines The object to fill the parsed class names into.
314+
* @param options The options to configure the parsing behavior.
315+
*/
316+
function fillLineClassNamesFromCode(
317+
parsedLines: CodeBlockParsedLines,
318+
options: CodeBlockParseLinesOptions,
319+
) {
320+
const {language, magicComments} = options;
321+
const {code, lineClassNames} = parsedLines;
322+
323+
// only parse if there is a language specified
277324
if (language === undefined) {
278-
return {lineClassNames: {}, code};
325+
return;
279326
}
327+
280328
const directiveRegex = getAllMagicCommentDirectiveStyles(
281329
language,
282330
magicComments,
@@ -323,15 +371,13 @@ export function parseLines(
323371
}
324372
lines.splice(lineNumber, 1);
325373
}
326-
code = lines.join('\n');
327-
const lineClassNames: {[lineIndex: number]: string[]} = {};
374+
parsedLines.code = lines.join('\n');
328375
Object.entries(blocks).forEach(([className, {range}]) => {
329376
rangeParser(range).forEach((l) => {
330377
lineClassNames[l] ??= [];
331378
lineClassNames[l]!.push(className);
332379
});
333380
});
334-
return {lineClassNames, code};
335381
}
336382

337383
export function getPrismCssVariables(prismTheme: PrismTheme): CSSProperties {

0 commit comments

Comments
 (0)