test02/node_modules/@vuepress/plugin-prismjs/lib/node/parser/notation.js
罗佳鸿 6aa1ebe342
Some checks are pending
部署文档 / deploy-gh-pages (push) Waiting to run
first commit
2024-08-13 10:11:19 +08:00

115 lines
3.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* This module implements some of the functionalities of the `shiki` transformer.
* You can use the following magic comments:
*
* - line highlight: `// [!code highlight]`, or `// [!code hl]`
* - line diff add: `// [!code ++]`
* - line diff remove: `// [!code --]`
* - line focus: `// [!code focus]`
* - line warning: `// [!code warning]`
* - line error: `// [!code error]`
* - highlight word: `// [!code word:xxx]` `xxx` can be any word
*
* You can also add `:\d` to achieve the same effect for the following `number` lines
*
* - `// [!code highlight:3]`
* - `// [!code ++:3]`
* - ...more
*/
import { escapeRegExp } from '../utils/index.js';
import { createNotationRule } from './createNotationRule.js';
import { highlightWordInLine } from './highlightWord.js';
const toArray = (value) => Array.isArray(value) ? value : [value];
const createNotationCommentMarkerRule = (parser, { classMap, classPre }) => {
const marker = Object.keys(classMap).map(escapeRegExp).join('|');
createNotationRule(parser, new RegExp(
// comment-begin | marker | range | comment-end
`\\s*(?://|/\\*|<!--|#|--)\\s+\\[!code (${marker})(:\\d+)?\\]\\s*(?:\\*/|-->)?`), ([, match, range = ':1'], index) => {
const lineNum = Number.parseInt(range.slice(1), 10);
parser.lines.slice(index, index + lineNum).forEach((node) => {
node.classList.push(...toArray(classMap[match]));
});
if (classPre) {
parser.pre.classList.push(classPre);
}
return true;
});
};
/**
* line highlight
*
* `// [!code highlight]`, or `// [!code hl]`
*/
export const notationHighlight = (parser) => {
createNotationCommentMarkerRule(parser, {
classMap: {
highlight: 'highlighted',
hl: 'highlighted',
},
classPre: 'has-highlighted',
});
};
/**
* line focus
*
* `// [!code focus]`
*/
export const notationFocus = (parser) => {
createNotationCommentMarkerRule(parser, {
classMap: {
focus: 'has-focus',
},
classPre: 'has-focused-lines',
});
};
/**
* line diff
*
* `// [!code ++]` and `// [!code --]`
*/
export const notationDiff = (parser) => {
createNotationCommentMarkerRule(parser, {
classMap: {
'++': 'diff add',
'--': 'diff remove',
},
classPre: 'has-diff',
});
};
/**
* line error level
*
* `// [!code warning]` and `// [!code error]`
*/
export const notationErrorLevel = (parser) => {
createNotationCommentMarkerRule(parser, {
classMap: {
error: ['highlighted', 'error'],
warning: ['highlighted', 'warning'],
},
classPre: 'has-highlighted',
});
};
/**
* highlight word
*
* `// [!code word:xxx]`: `xxx` can be any word.
* @param parser
*/
export const notationWordHighlight = (parser) => {
createNotationRule(parser,
// comment-begin | marker |word | range | comment-end
/\s*(?:\/\/|\/\*|<!--|#)\s+\[!code word:((?:\\.|[^:\]])+)(:\d+)?\]\s*(?:\*\/|-->)?/, ([, word, range], index) => {
const lineNum = range
? Number.parseInt(range.slice(1), 10)
: parser.lines.length - 1;
// escape backslashes
word = word.replace(/\\(.)/g, '$1');
parser.lines
// start from the next line after the comment
.slice(index + 1, index + 1 + lineNum)
.forEach((line) => highlightWordInLine(line, word));
return true;
});
};