|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 |
- "use strict";
-
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.default = markdownItPrism;
-
- var _prismjs = _interopRequireDefault(require("prismjs"));
-
- var _components = _interopRequireDefault(require("prismjs/components/"));
-
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
-
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
-
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
-
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
-
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
-
- function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
-
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
-
- function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
-
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
-
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
-
- const SPECIFIED_LANGUAGE_META_KEY = 'de.joshuagleitze.markdown-it-prism.specifiedLanguage';
- const DEFAULTS = {
- highlightInlineCode: false,
- plugins: [],
- init: () => {// do nothing by default
- },
- defaultLanguageForUnknown: undefined,
- defaultLanguageForUnspecified: undefined,
- defaultLanguage: undefined
- };
- /**
- * Loads the provided `lang` into prism.
- *
- * @param lang
- * Code of the language to load.
- * @return The Prism language object for the provided {@code lang} code. {@code undefined} if the language is not known to Prism.
- */
-
- function loadPrismLang(lang) {
- if (!lang) return undefined;
- let langObject = _prismjs.default.languages[lang];
-
- if (langObject === undefined) {
- (0, _components.default)([lang]);
- langObject = _prismjs.default.languages[lang];
- }
-
- return langObject;
- }
- /**
- * Loads the provided Prism plugin.
- * @param name
- * Name of the plugin to load.
- * @throws {Error} If there is no plugin with the provided `name`.
- */
-
-
- function loadPrismPlugin(name) {
- try {
- require(`prismjs/plugins/${name}/prism-${name}`);
- } catch (e) {
- throw new Error(`Cannot load Prism plugin "${name}". Please check the spelling.`);
- }
- }
- /**
- * Select the language to use for highlighting, based on the provided options and the specified language.
- *
- * @param options
- * The options that were used to initialise the plugin.
- * @param lang
- * Code of the language to highlight the text in.
- * @return The name of the language to use and the Prism language object for that language.
- */
-
-
- function selectLanguage(options, lang) {
- let langToUse = lang;
-
- if (langToUse === '' && options.defaultLanguageForUnspecified !== undefined) {
- langToUse = options.defaultLanguageForUnspecified;
- }
-
- let prismLang = loadPrismLang(langToUse);
-
- if (prismLang === undefined && options.defaultLanguageForUnknown !== undefined) {
- langToUse = options.defaultLanguageForUnknown;
- prismLang = loadPrismLang(langToUse);
- }
-
- return [langToUse, prismLang];
- }
- /**
- * Highlights the provided text using Prism.
- *
- * @param markdownit
- * The markdown-it instance.
- * @param options
- * The options that have been used to initialise the plugin.
- * @param text
- * The text to highlight.
- * @param lang
- * Code of the language to highlight the text in.
- * @return If Prism knows the language that {@link selectLanguage} returns for `lang`, the `text` highlighted for that language. Otherwise, `text`
- * html-escaped.
- */
-
-
- function highlight(markdownit, options, text, lang) {
- return highlightWithSelectedLanguage(markdownit, options, text, selectLanguage(options, lang));
- }
- /**
- * Highlights the provided text using Prism.
- *
- * @param markdownit
- * The markdown-it instance.
- * @param options
- * The options that have been used to initialise the plugin.
- * @param text
- * The text to highlight.
- * @param lang
- * The selected Prism language to use for highlighting.
- * @return If Prism knows the language that {@link selectLanguage} returns for `lang`, the `text` highlighted for that language. Otherwise, `text`
- * html-escaped.
- */
-
-
- function highlightWithSelectedLanguage(markdownit, options, text, [langToUse, prismLang]) {
- return prismLang ? _prismjs.default.highlight(text, prismLang, langToUse) : markdownit.utils.escapeHtml(text);
- }
- /**
- * Construct the class name for the provided `lang`.
- *
- * @param markdownit
- * The markdown-it instance.
- * @param lang
- * The selected language.
- * @return the class to use for `lang`.
- */
-
-
- function languageClass(markdownit, lang) {
- return markdownit.options.langPrefix + lang;
- }
- /**
- * A {@link RuleCore} that searches for and extracts language specifications on inline code tokens.
- */
-
-
- function inlineCodeLanguageRule(state) {
- var _iterator = _createForOfIteratorHelper(state.tokens),
- _step;
-
- try {
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
- const inlineToken = _step.value;
-
- if (inlineToken.type === 'inline' && inlineToken.children !== null) {
- var _iterator2 = _createForOfIteratorHelper(inlineToken.children.entries()),
- _step2;
-
- try {
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
- const _step2$value = _slicedToArray(_step2.value, 2),
- index = _step2$value[0],
- token = _step2$value[1];
-
- if (token.type === 'code_inline' && index + 1 < inlineToken.children.length) {
- extractInlineCodeSpecifiedLanguage(token, inlineToken.children[index + 1]);
- }
- }
- } catch (err) {
- _iterator2.e(err);
- } finally {
- _iterator2.f();
- }
- }
- }
- } catch (err) {
- _iterator.e(err);
- } finally {
- _iterator.f();
- }
- }
- /**
- * Searches for a language specification after an inline code token (e.g. ``{language=cpp}). If present, extracts the language, sets
- * it on `inlineCodeToken`’s meta, and removes the specification.
- *
- * @param inlineCodeToken
- * The inline code token for which to extract the language.
- * @param followingToken
- * The token immediately following the `inlineCodeToken`.
- */
-
-
- function extractInlineCodeSpecifiedLanguage(inlineCodeToken, followingToken) {
- const languageSpecificationMatch = followingToken.content.match(/^\{((?:[^\s}]+\s)*)language=([^\s}]+)((?:\s[^\s}]+)*)}/);
-
- if (languageSpecificationMatch !== null) {
- inlineCodeToken.meta = _objectSpread(_objectSpread({}, inlineCodeToken.meta), {}, {
- [SPECIFIED_LANGUAGE_META_KEY]: languageSpecificationMatch[2]
- });
- followingToken.content = followingToken.content.slice(languageSpecificationMatch[0].length);
-
- if (languageSpecificationMatch[1] || languageSpecificationMatch[3]) {
- followingToken.content = `{${languageSpecificationMatch[1] || ''}${(languageSpecificationMatch[3] || ' ').slice(1)}}${followingToken.content}`;
- }
- }
- }
- /**
- * Patch the `<pre>` and `<code>` tags produced by the `existingRule` for fenced code blocks.
- *
- * @param markdownit
- * The markdown-it instance.
- * @param options
- * The options that have been used to initialise the plugin.
- * @param existingRule
- * The previously configured render rule for fenced code blocks.
- */
-
-
- function applyCodeAttributes(markdownit, options, existingRule) {
- return (tokens, idx, renderOptions, env, self) => {
- const fenceToken = tokens[idx];
- const info = fenceToken.info ? markdownit.utils.unescapeAll(fenceToken.info).trim() : '';
- const lang = info.split(/(\s+)/g)[0];
-
- const _selectLanguage = selectLanguage(options, lang),
- _selectLanguage2 = _slicedToArray(_selectLanguage, 1),
- langToUse = _selectLanguage2[0];
-
- if (!langToUse) {
- return existingRule(tokens, idx, renderOptions, env, self);
- } else {
- fenceToken.info = langToUse;
- const existingResult = existingRule(tokens, idx, renderOptions, env, self);
- const langClass = languageClass(markdownit, markdownit.utils.escapeHtml(langToUse));
- return existingResult.replace(/<((?:pre|code)[^>]*?)(?:\s+class="([^"]*)"([^>]*))?>/g, (match, tagStart, existingClasses, tagEnd) => existingClasses !== null && existingClasses !== void 0 && existingClasses.includes(langClass) ? match : `<${tagStart} class="${existingClasses ? `${existingClasses} ` : ''}${langClass}"${tagEnd || ''}>`);
- }
- };
- }
- /**
- * Renders inline code tokens by highlighting them with Prism.
- *
- * @param markdownit
- * The markdown-it instance.
- * @param options
- * The options that have been used to initialise the plugin.
- * @param existingRule
- * The previously configured render rule for inline code.
- */
-
-
- function renderInlineCode(markdownit, options, existingRule) {
- return (tokens, idx, renderOptions, env, self) => {
- const inlineCodeToken = tokens[idx];
- const specifiedLanguage = inlineCodeToken.meta ? inlineCodeToken.meta[SPECIFIED_LANGUAGE_META_KEY] || '' : '';
-
- const _selectLanguage3 = selectLanguage(options, specifiedLanguage),
- _selectLanguage4 = _slicedToArray(_selectLanguage3, 2),
- langToUse = _selectLanguage4[0],
- prismLang = _selectLanguage4[1];
-
- if (!langToUse) {
- return existingRule(tokens, idx, renderOptions, env, self);
- } else {
- const highlighted = highlightWithSelectedLanguage(markdownit, options, inlineCodeToken.content, [langToUse, prismLang]);
- inlineCodeToken.attrJoin('class', languageClass(markdownit, langToUse));
- return `<code${self.renderAttrs(inlineCodeToken)}>${highlighted}</code>`;
- }
- };
- }
- /**
- * Checks whether an option represents a valid Prism language
- *
- * @param options
- * The options that have been used to initialise the plugin.
- * @param optionName
- * The key of the option inside {@code options} that shall be checked.
- * @throws {Error} If the option is not set to a valid Prism language.
- */
-
-
- function checkLanguageOption(options, optionName) {
- const language = options[optionName];
-
- if (language !== undefined && loadPrismLang(language) === undefined) {
- throw new Error(`Bad option ${optionName}: There is no Prism language '${language}'.`);
- }
- }
- /**
- * ‘the most basic rule to render a token’ (https://github.com/markdown-it/markdown-it/blob/master/docs/examples/renderer_rules.md)
- */
-
-
- function renderFallback(tokens, idx, options, env, self) {
- return self.renderToken(tokens, idx, options);
- }
- /**
- * Initialisation function of the plugin. This function is not called directly by clients, but is rather provided
- * to MarkdownIt’s {@link MarkdownIt.use} function.
- *
- * @param markdownit
- * The markdown it instance the plugin is being registered to.
- * @param useroptions
- * The options this plugin is being initialised with.
- */
-
-
- function markdownItPrism(markdownit, useroptions) {
- const options = Object.assign({}, DEFAULTS, useroptions);
- checkLanguageOption(options, 'defaultLanguage');
- checkLanguageOption(options, 'defaultLanguageForUnknown');
- checkLanguageOption(options, 'defaultLanguageForUnspecified');
- options.defaultLanguageForUnknown = options.defaultLanguageForUnknown || options.defaultLanguage;
- options.defaultLanguageForUnspecified = options.defaultLanguageForUnspecified || options.defaultLanguage;
- options.plugins.forEach(loadPrismPlugin);
- options.init(_prismjs.default); // register ourselves as highlighter
-
- markdownit.options.highlight = (text, lang) => highlight(markdownit, options, text, lang);
-
- markdownit.renderer.rules.fence = applyCodeAttributes(markdownit, options, markdownit.renderer.rules.fence || renderFallback);
-
- if (options.highlightInlineCode) {
- markdownit.core.ruler.after('inline', 'prism_inline_code_language', inlineCodeLanguageRule);
- markdownit.renderer.rules.code_inline = renderInlineCode(markdownit, options, markdownit.renderer.rules.code_inline || renderFallback);
- }
- }
-
- module.exports = exports.default;
- module.exports.default = exports.default;
|