UNPKG

4.61 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5const prismjs_1 = __importDefault(require("prismjs"));
6const strip_indent_1 = __importDefault(require("strip-indent"));
7const components_1 = __importDefault(require("prismjs/components/"));
8// https://github.com/PrismJS/prism/issues/2145
9const components_2 = __importDefault(require("prismjs/components"));
10const prismAlias = Object.entries(components_2.default.languages).reduce((acc, [key, value]) => {
11 if (value.alias) {
12 if (Array.isArray(value.alias)) {
13 value.alias.forEach(alias => (acc[alias] = key));
14 }
15 else if (typeof value.alias === 'string') {
16 acc[value.alias] = key;
17 }
18 }
19 return acc;
20}, {});
21const prismSupportedLanguages = Object.keys(components_2.default.languages).concat(Object.keys(prismAlias));
22const escape_html_1 = __importDefault(require("./escape_html"));
23/**
24 * Wrapper of Prism.highlight()
25 * @param {String} code
26 * @param {String} language
27 */
28function prismHighlight(code, language) {
29 // Prism has not load the language pattern
30 if (!prismjs_1.default.languages[language] && prismSupportedLanguages.includes(language))
31 (0, components_1.default)(language);
32 if (prismjs_1.default.languages[language]) {
33 // Prism escapes output by default
34 return prismjs_1.default.highlight(code, prismjs_1.default.languages[language], language);
35 }
36 // Current language is not supported by Prism, return origin code;
37 return (0, escape_html_1.default)(code);
38}
39/**
40 * Generate line number required HTML snippet
41 * @param {String} code - Highlighted code
42 */
43function lineNumberUtil(code) {
44 const matched = code.match(/\n(?!$)/g);
45 const num = matched ? matched.length + 1 : 1;
46 const lines = new Array(num + 1).join('<span></span>');
47 return `<span aria-hidden="true" class="line-numbers-rows">${lines}</span>`;
48}
49function replaceTabs(str, tab) {
50 return str.replace(/^\t+/gm, match => tab.repeat(match.length));
51}
52function PrismUtil(str, options = {}) {
53 if (typeof str !== 'string')
54 throw new TypeError('str must be a string!');
55 str = (0, strip_indent_1.default)(str);
56 const { lineNumber = true, lang = 'none', tab, mark, firstLine, isPreprocess = true, caption } = options;
57 // To be consistent with highlight.js
58 let language = lang === 'plaintext' || lang === 'none' ? 'none' : lang;
59 if (prismAlias[language])
60 language = prismAlias[language];
61 const preTagClassArr = [];
62 const preTagAttrArr = [];
63 let preTagAttr = '';
64 if (lineNumber)
65 preTagClassArr.push('line-numbers');
66 preTagClassArr.push(`language-${language}`);
67 // Show Languages plugin
68 // https://prismjs.com/plugins/show-language/
69 if (language !== 'none')
70 preTagAttrArr.push(`data-language="${language}"`);
71 if (!isPreprocess) {
72 // Shift Line Numbers ('firstLine' option) should only be added under non-preprocess mode
73 // https://prismjs.com/plugins/line-numbers/
74 if (lineNumber && firstLine)
75 preTagAttrArr.push(`data-start="${firstLine}"`);
76 // Line Highlight ('mark' option) should only be added under non-preprocess mode
77 // https://prismjs.com/plugins/line-highlight/
78 if (mark)
79 preTagAttrArr.push(`data-line="${mark}"`);
80 // Apply offset for 'mark' option
81 // https://github.com/hexojs/hexo-util/pull/172#issuecomment-571882480
82 if (firstLine && mark)
83 preTagAttrArr.push(`data-line-offset="${firstLine - 1}"`);
84 }
85 if (preTagAttrArr.length)
86 preTagAttr = ' ' + preTagAttrArr.join(' ');
87 if (tab)
88 str = replaceTabs(str, tab);
89 const codeCaption = caption ? `<div class="caption">${caption}</div>` : '';
90 const startTag = `<pre class="${preTagClassArr.join(' ')}"${preTagAttr}>${codeCaption}<code class="language-${language}">`;
91 const endTag = '</code></pre>';
92 let parsedCode = '';
93 if (language === 'none' || !isPreprocess) {
94 parsedCode = (0, escape_html_1.default)(str);
95 }
96 else {
97 parsedCode = prismHighlight(str, language);
98 }
99 // lineNumberUtil() should be used only under preprocess mode
100 if (lineNumber && isPreprocess) {
101 parsedCode += lineNumberUtil(parsedCode);
102 }
103 return startTag + parsedCode + endTag;
104}
105module.exports = PrismUtil;
106//# sourceMappingURL=prism.js.map
\No newline at end of file