diff --git a/node_modules/.bin/marked b/node_modules/.bin/marked new file mode 120000 index 0000000..6827ff3 --- /dev/null +++ b/node_modules/.bin/marked @@ -0,0 +1 @@ +../marked/bin/marked.js \ No newline at end of file diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json index d51f49c..7823215 100644 --- a/node_modules/.package-lock.json +++ b/node_modules/.package-lock.json @@ -435,6 +435,17 @@ "node": ">=10" } }, + "node_modules/marked": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.17.tgz", + "integrity": "sha512-Wfk0ATOK5iPxM4ptrORkFemqroz0ZDxp5MWfYA7H/F+wO17NRWV5Ypxi6p3g2Xmw2bKeiYOl6oVnLHKxBA0VhA==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", diff --git a/node_modules/marked/LICENSE.md b/node_modules/marked/LICENSE.md new file mode 100644 index 0000000..4bd2d4a --- /dev/null +++ b/node_modules/marked/LICENSE.md @@ -0,0 +1,44 @@ +# License information + +## Contribution License Agreement + +If you contribute code to this project, you are implicitly allowing your code +to be distributed under the MIT license. You are also implicitly verifying that +all code is your original work. `` + +## Marked + +Copyright (c) 2018+, MarkedJS (https://github.com/markedjs/) +Copyright (c) 2011-2018, Christopher Jeffrey (https://github.com/chjj/) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +## Markdown + +Copyright © 2004, John Gruber +http://daringfireball.net/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* Neither the name “Markdown” nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +This software is provided by the copyright holders and contributors “as is” and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the copyright owner or contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage. diff --git a/node_modules/marked/README.md b/node_modules/marked/README.md new file mode 100644 index 0000000..87961a0 --- /dev/null +++ b/node_modules/marked/README.md @@ -0,0 +1,98 @@ + + + + +# Marked + +[![npm](https://badgen.net/npm/v/marked)](https://www.npmjs.com/package/marked) +[![gzip size](https://badgen.net/badgesize/gzip/https://cdn.jsdelivr.net/npm/marked/marked.min.js)](https://cdn.jsdelivr.net/npm/marked/marked.min.js) +[![install size](https://badgen.net/packagephobia/install/marked)](https://packagephobia.now.sh/result?p=marked) +[![downloads](https://badgen.net/npm/dt/marked)](https://www.npmjs.com/package/marked) +[![github actions](https://github.com/markedjs/marked/workflows/Tests/badge.svg)](https://github.com/markedjs/marked/actions) +[![snyk](https://snyk.io/test/npm/marked/badge.svg)](https://snyk.io/test/npm/marked) + +- ⚡ built for speed +- ⬇️ low-level compiler for parsing markdown without caching or blocking for long periods of time +- ⚖️ light-weight while implementing all markdown features from the supported flavors & specifications +- 🌐 works in a browser, on a server, or from a command line interface (CLI) + +## Demo + +Checkout the [demo page](https://marked.js.org/demo/) to see marked in action ⛹️ + +## Docs + +Our [documentation pages](https://marked.js.org) are also rendered using marked 💯 + +Also read about: + +* [Options](https://marked.js.org/#/USING_ADVANCED.md) +* [Extensibility](https://marked.js.org/#/USING_PRO.md) + +## Compatibility + +**Node.js:** Only [current and LTS](https://nodejs.org/en/about/releases/) Node.js versions are supported. End of life Node.js versions may become incompatible with Marked at any point in time. + +**Browser:** Not IE11 :) + +## Installation + +**CLI:** + +```sh +npm install -g marked +``` + +**In-browser:** + +```sh +npm install marked +``` + +## Usage + +### Warning: 🚨 Marked does not [sanitize](https://marked.js.org/#/USING_ADVANCED.md#options) the output HTML. Please use a sanitize library, like [DOMPurify](https://github.com/cure53/DOMPurify) (recommended), [sanitize-html](https://github.com/apostrophecms/sanitize-html) or [insane](https://github.com/bevacqua/insane) on the *output* HTML! 🚨 + +``` +DOMPurify.sanitize(marked.parse(``)); +``` + +**CLI** + +``` bash +# Example with stdin input +$ marked -o hello.html +hello world +^D +$ cat hello.html +

hello world

+``` + +```bash +# Print all options +$ marked --help +``` + +**Browser** + +```html + + + + + Marked in the browser + + +
+ + + + +``` + +## License + +Copyright (c) 2011-2022, Christopher Jeffrey. (MIT License) diff --git a/node_modules/marked/bin/marked.js b/node_modules/marked/bin/marked.js new file mode 100755 index 0000000..5031246 --- /dev/null +++ b/node_modules/marked/bin/marked.js @@ -0,0 +1,217 @@ +#!/usr/bin/env node + +/** + * Marked CLI + * Copyright (c) 2011-2013, Christopher Jeffrey (MIT License) + */ + +import { promises } from 'fs'; +import { marked } from '../lib/marked.esm.js'; + +const { readFile, writeFile } = promises; + +/** + * Man Page + */ + +async function help() { + const { spawn } = await import('child_process'); + + const options = { + cwd: process.cwd(), + env: process.env, + setsid: false, + stdio: 'inherit' + }; + + const { dirname, resolve } = await import('path'); + const { fileURLToPath } = await import('url'); + const __dirname = dirname(fileURLToPath(import.meta.url)); + const helpText = await readFile(resolve(__dirname, '../man/marked.1.txt'), 'utf8'); + + // eslint-disable-next-line promise/param-names + await new Promise(res => { + spawn('man', [resolve(__dirname, '../man/marked.1')], options) + .on('error', () => { + console.log(helpText); + }) + .on('close', res); + }); +} + +async function version() { + const { createRequire } = await import('module'); + const require = createRequire(import.meta.url); + const pkg = require('../package.json'); + console.log(pkg.version); +} + +/** + * Main + */ + +async function main(argv) { + const files = []; + const options = {}; + let input; + let output; + let string; + let arg; + let tokens; + let opt; + + function getarg() { + let arg = argv.shift(); + + if (arg.indexOf('--') === 0) { + // e.g. --opt + arg = arg.split('='); + if (arg.length > 1) { + // e.g. --opt=val + argv.unshift(arg.slice(1).join('=')); + } + arg = arg[0]; + } else if (arg[0] === '-') { + if (arg.length > 2) { + // e.g. -abc + argv = arg.substring(1).split('').map(function(ch) { + return '-' + ch; + }).concat(argv); + arg = argv.shift(); + } else { + // e.g. -a + } + } else { + // e.g. foo + } + + return arg; + } + + while (argv.length) { + arg = getarg(); + switch (arg) { + case '-o': + case '--output': + output = argv.shift(); + break; + case '-i': + case '--input': + input = argv.shift(); + break; + case '-s': + case '--string': + string = argv.shift(); + break; + case '-t': + case '--tokens': + tokens = true; + break; + case '-h': + case '--help': + return await help(); + case '-v': + case '--version': + return await version(); + default: + if (arg.indexOf('--') === 0) { + opt = camelize(arg.replace(/^--(no-)?/, '')); + if (!marked.defaults.hasOwnProperty(opt)) { + continue; + } + if (arg.indexOf('--no-') === 0) { + options[opt] = typeof marked.defaults[opt] !== 'boolean' + ? null + : false; + } else { + options[opt] = typeof marked.defaults[opt] !== 'boolean' + ? argv.shift() + : true; + } + } else { + files.push(arg); + } + break; + } + } + + async function getData() { + if (!input) { + if (files.length <= 2) { + if (string) { + return string; + } + return await getStdin(); + } + input = files.pop(); + } + return await readFile(input, 'utf8'); + } + + const data = await getData(); + + const html = tokens + ? JSON.stringify(marked.lexer(data, options), null, 2) + : marked(data, options); + + if (output) { + return await writeFile(output, html); + } + + process.stdout.write(html + '\n'); +} + +/** + * Helpers + */ + +function getStdin() { + return new Promise((resolve, reject) => { + const stdin = process.stdin; + let buff = ''; + + stdin.setEncoding('utf8'); + + stdin.on('data', function(data) { + buff += data; + }); + + stdin.on('error', function(err) { + reject(err); + }); + + stdin.on('end', function() { + resolve(buff); + }); + + stdin.resume(); + }); +} + +/** + * @param {string} text + */ +function camelize(text) { + return text.replace(/(\w)-(\w)/g, function(_, a, b) { + return a + b.toUpperCase(); + }); +} + +function handleError(err) { + if (err.code === 'ENOENT') { + console.error('marked: output to ' + err.path + ': No such directory'); + return process.exit(1); + } + throw err; +} + +/** + * Expose / Entry Point + */ + +process.title = 'marked'; +main(process.argv.slice()).then(code => { + process.exit(code || 0); +}).catch(err => { + handleError(err); +}); diff --git a/node_modules/marked/lib/marked.cjs b/node_modules/marked/lib/marked.cjs new file mode 100644 index 0000000..cbad34d --- /dev/null +++ b/node_modules/marked/lib/marked.cjs @@ -0,0 +1,3050 @@ +/** + * marked - a markdown parser + * Copyright (c) 2011-2022, Christopher Jeffrey. (MIT Licensed) + * https://github.com/markedjs/marked + */ + +/** + * DO NOT EDIT THIS FILE + * The code in this file is generated from files in ./src/ + */ + +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } +} + +function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + Object.defineProperty(Constructor, "prototype", { + writable: false + }); + return Constructor; +} + +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; +} + +function _createForOfIteratorHelperLoose(o, allowArrayLike) { + var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; + if (it) return (it = it.call(o)).next.bind(it); + + if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { + if (it) o = it; + var i = 0; + return function () { + if (i >= o.length) return { + done: true + }; + return { + done: false, + value: o[i++] + }; + }; + } + + throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); +} + +function getDefaults() { + return { + baseUrl: null, + breaks: false, + extensions: null, + gfm: true, + headerIds: true, + headerPrefix: '', + highlight: null, + langPrefix: 'language-', + mangle: true, + pedantic: false, + renderer: null, + sanitize: false, + sanitizer: null, + silent: false, + smartLists: false, + smartypants: false, + tokenizer: null, + walkTokens: null, + xhtml: false + }; +} +exports.defaults = getDefaults(); +function changeDefaults(newDefaults) { + exports.defaults = newDefaults; +} + +/** + * Helpers + */ +var escapeTest = /[&<>"']/; +var escapeReplace = /[&<>"']/g; +var escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/; +var escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g; +var escapeReplacements = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' +}; + +var getEscapeReplacement = function getEscapeReplacement(ch) { + return escapeReplacements[ch]; +}; + +function escape(html, encode) { + if (encode) { + if (escapeTest.test(html)) { + return html.replace(escapeReplace, getEscapeReplacement); + } + } else { + if (escapeTestNoEncode.test(html)) { + return html.replace(escapeReplaceNoEncode, getEscapeReplacement); + } + } + + return html; +} +var unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig; +/** + * @param {string} html + */ + +function unescape(html) { + // explicitly match decimal, hex, and named HTML entities + return html.replace(unescapeTest, function (_, n) { + n = n.toLowerCase(); + if (n === 'colon') return ':'; + + if (n.charAt(0) === '#') { + return n.charAt(1) === 'x' ? String.fromCharCode(parseInt(n.substring(2), 16)) : String.fromCharCode(+n.substring(1)); + } + + return ''; + }); +} +var caret = /(^|[^\[])\^/g; +/** + * @param {string | RegExp} regex + * @param {string} opt + */ + +function edit(regex, opt) { + regex = typeof regex === 'string' ? regex : regex.source; + opt = opt || ''; + var obj = { + replace: function replace(name, val) { + val = val.source || val; + val = val.replace(caret, '$1'); + regex = regex.replace(name, val); + return obj; + }, + getRegex: function getRegex() { + return new RegExp(regex, opt); + } + }; + return obj; +} +var nonWordAndColonTest = /[^\w:]/g; +var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i; +/** + * @param {boolean} sanitize + * @param {string} base + * @param {string} href + */ + +function cleanUrl(sanitize, base, href) { + if (sanitize) { + var prot; + + try { + prot = decodeURIComponent(unescape(href)).replace(nonWordAndColonTest, '').toLowerCase(); + } catch (e) { + return null; + } + + if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) { + return null; + } + } + + if (base && !originIndependentUrl.test(href)) { + href = resolveUrl(base, href); + } + + try { + href = encodeURI(href).replace(/%25/g, '%'); + } catch (e) { + return null; + } + + return href; +} +var baseUrls = {}; +var justDomain = /^[^:]+:\/*[^/]*$/; +var protocol = /^([^:]+:)[\s\S]*$/; +var domain = /^([^:]+:\/*[^/]*)[\s\S]*$/; +/** + * @param {string} base + * @param {string} href + */ + +function resolveUrl(base, href) { + if (!baseUrls[' ' + base]) { + // we can ignore everything in base after the last slash of its path component, + // but we might need to add _that_ + // https://tools.ietf.org/html/rfc3986#section-3 + if (justDomain.test(base)) { + baseUrls[' ' + base] = base + '/'; + } else { + baseUrls[' ' + base] = rtrim(base, '/', true); + } + } + + base = baseUrls[' ' + base]; + var relativeBase = base.indexOf(':') === -1; + + if (href.substring(0, 2) === '//') { + if (relativeBase) { + return href; + } + + return base.replace(protocol, '$1') + href; + } else if (href.charAt(0) === '/') { + if (relativeBase) { + return href; + } + + return base.replace(domain, '$1') + href; + } else { + return base + href; + } +} +var noopTest = { + exec: function noopTest() {} +}; +function merge(obj) { + var i = 1, + target, + key; + + for (; i < arguments.length; i++) { + target = arguments[i]; + + for (key in target) { + if (Object.prototype.hasOwnProperty.call(target, key)) { + obj[key] = target[key]; + } + } + } + + return obj; +} +function splitCells(tableRow, count) { + // ensure that every cell-delimiting pipe has a space + // before it to distinguish it from an escaped pipe + var row = tableRow.replace(/\|/g, function (match, offset, str) { + var escaped = false, + curr = offset; + + while (--curr >= 0 && str[curr] === '\\') { + escaped = !escaped; + } + + if (escaped) { + // odd number of slashes means | is escaped + // so we leave it alone + return '|'; + } else { + // add space before unescaped | + return ' |'; + } + }), + cells = row.split(/ \|/); + var i = 0; // First/last cell in a row cannot be empty if it has no leading/trailing pipe + + if (!cells[0].trim()) { + cells.shift(); + } + + if (cells.length > 0 && !cells[cells.length - 1].trim()) { + cells.pop(); + } + + if (cells.length > count) { + cells.splice(count); + } else { + while (cells.length < count) { + cells.push(''); + } + } + + for (; i < cells.length; i++) { + // leading or trailing whitespace is ignored per the gfm spec + cells[i] = cells[i].trim().replace(/\\\|/g, '|'); + } + + return cells; +} +/** + * Remove trailing 'c's. Equivalent to str.replace(/c*$/, ''). + * /c*$/ is vulnerable to REDOS. + * + * @param {string} str + * @param {string} c + * @param {boolean} invert Remove suffix of non-c chars instead. Default falsey. + */ + +function rtrim(str, c, invert) { + var l = str.length; + + if (l === 0) { + return ''; + } // Length of suffix matching the invert condition. + + + var suffLen = 0; // Step left until we fail to match the invert condition. + + while (suffLen < l) { + var currChar = str.charAt(l - suffLen - 1); + + if (currChar === c && !invert) { + suffLen++; + } else if (currChar !== c && invert) { + suffLen++; + } else { + break; + } + } + + return str.slice(0, l - suffLen); +} +function findClosingBracket(str, b) { + if (str.indexOf(b[1]) === -1) { + return -1; + } + + var l = str.length; + var level = 0, + i = 0; + + for (; i < l; i++) { + if (str[i] === '\\') { + i++; + } else if (str[i] === b[0]) { + level++; + } else if (str[i] === b[1]) { + level--; + + if (level < 0) { + return i; + } + } + } + + return -1; +} +function checkSanitizeDeprecation(opt) { + if (opt && opt.sanitize && !opt.silent) { + console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options'); + } +} // copied from https://stackoverflow.com/a/5450113/806777 + +/** + * @param {string} pattern + * @param {number} count + */ + +function repeatString(pattern, count) { + if (count < 1) { + return ''; + } + + var result = ''; + + while (count > 1) { + if (count & 1) { + result += pattern; + } + + count >>= 1; + pattern += pattern; + } + + return result + pattern; +} + +function outputLink(cap, link, raw, lexer) { + var href = link.href; + var title = link.title ? escape(link.title) : null; + var text = cap[1].replace(/\\([\[\]])/g, '$1'); + + if (cap[0].charAt(0) !== '!') { + lexer.state.inLink = true; + var token = { + type: 'link', + raw: raw, + href: href, + title: title, + text: text, + tokens: lexer.inlineTokens(text, []) + }; + lexer.state.inLink = false; + return token; + } + + return { + type: 'image', + raw: raw, + href: href, + title: title, + text: escape(text) + }; +} + +function indentCodeCompensation(raw, text) { + var matchIndentToCode = raw.match(/^(\s+)(?:```)/); + + if (matchIndentToCode === null) { + return text; + } + + var indentToCode = matchIndentToCode[1]; + return text.split('\n').map(function (node) { + var matchIndentInNode = node.match(/^\s+/); + + if (matchIndentInNode === null) { + return node; + } + + var indentInNode = matchIndentInNode[0]; + + if (indentInNode.length >= indentToCode.length) { + return node.slice(indentToCode.length); + } + + return node; + }).join('\n'); +} +/** + * Tokenizer + */ + + +var Tokenizer = /*#__PURE__*/function () { + function Tokenizer(options) { + this.options = options || exports.defaults; + } + + var _proto = Tokenizer.prototype; + + _proto.space = function space(src) { + var cap = this.rules.block.newline.exec(src); + + if (cap && cap[0].length > 0) { + return { + type: 'space', + raw: cap[0] + }; + } + }; + + _proto.code = function code(src) { + var cap = this.rules.block.code.exec(src); + + if (cap) { + var text = cap[0].replace(/^ {1,4}/gm, ''); + return { + type: 'code', + raw: cap[0], + codeBlockStyle: 'indented', + text: !this.options.pedantic ? rtrim(text, '\n') : text + }; + } + }; + + _proto.fences = function fences(src) { + var cap = this.rules.block.fences.exec(src); + + if (cap) { + var raw = cap[0]; + var text = indentCodeCompensation(raw, cap[3] || ''); + return { + type: 'code', + raw: raw, + lang: cap[2] ? cap[2].trim() : cap[2], + text: text + }; + } + }; + + _proto.heading = function heading(src) { + var cap = this.rules.block.heading.exec(src); + + if (cap) { + var text = cap[2].trim(); // remove trailing #s + + if (/#$/.test(text)) { + var trimmed = rtrim(text, '#'); + + if (this.options.pedantic) { + text = trimmed.trim(); + } else if (!trimmed || / $/.test(trimmed)) { + // CommonMark requires space before trailing #s + text = trimmed.trim(); + } + } + + var token = { + type: 'heading', + raw: cap[0], + depth: cap[1].length, + text: text, + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + }; + + _proto.hr = function hr(src) { + var cap = this.rules.block.hr.exec(src); + + if (cap) { + return { + type: 'hr', + raw: cap[0] + }; + } + }; + + _proto.blockquote = function blockquote(src) { + var cap = this.rules.block.blockquote.exec(src); + + if (cap) { + var text = cap[0].replace(/^ *>[ \t]?/gm, ''); + return { + type: 'blockquote', + raw: cap[0], + tokens: this.lexer.blockTokens(text, []), + text: text + }; + } + }; + + _proto.list = function list(src) { + var cap = this.rules.block.list.exec(src); + + if (cap) { + var raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, line, nextLine, rawLine, itemContents, endEarly; + var bull = cap[1].trim(); + var isordered = bull.length > 1; + var list = { + type: 'list', + raw: '', + ordered: isordered, + start: isordered ? +bull.slice(0, -1) : '', + loose: false, + items: [] + }; + bull = isordered ? "\\d{1,9}\\" + bull.slice(-1) : "\\" + bull; + + if (this.options.pedantic) { + bull = isordered ? bull : '[*+-]'; + } // Get next list item + + + var itemRegex = new RegExp("^( {0,3}" + bull + ")((?:[\t ][^\\n]*)?(?:\\n|$))"); // Check if current bullet point can start a new List Item + + while (src) { + endEarly = false; + + if (!(cap = itemRegex.exec(src))) { + break; + } + + if (this.rules.block.hr.test(src)) { + // End list if bullet was actually HR (possibly move into itemRegex?) + break; + } + + raw = cap[0]; + src = src.substring(raw.length); + line = cap[2].split('\n', 1)[0]; + nextLine = src.split('\n', 1)[0]; + + if (this.options.pedantic) { + indent = 2; + itemContents = line.trimLeft(); + } else { + indent = cap[2].search(/[^ ]/); // Find first non-space char + + indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent + + itemContents = line.slice(indent); + indent += cap[1].length; + } + + blankLine = false; + + if (!line && /^ *$/.test(nextLine)) { + // Items begin with at most one blank line + raw += nextLine + '\n'; + src = src.substring(nextLine.length + 1); + endEarly = true; + } + + if (!endEarly) { + var nextBulletRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}(?:[*+-]|\\d{1,9}[.)])((?: [^\\n]*)?(?:\\n|$))"); + var hrRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)"); + var fencesBeginRegex = new RegExp("^( {0," + Math.min(3, indent - 1) + "})(```|~~~)"); // Check if following lines should be included in List Item + + while (src) { + rawLine = src.split('\n', 1)[0]; + line = rawLine; // Re-align to follow commonmark nesting rules + + if (this.options.pedantic) { + line = line.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' '); + } // End list item if found code fences + + + if (fencesBeginRegex.test(line)) { + break; + } // End list item if found start of new heading + + + if (this.rules.block.heading.test(line)) { + break; + } // End list item if found start of new bullet + + + if (nextBulletRegex.test(line)) { + break; + } // Horizontal rule found + + + if (hrRegex.test(src)) { + break; + } + + if (line.search(/[^ ]/) >= indent || !line.trim()) { + // Dedent if possible + itemContents += '\n' + line.slice(indent); + } else if (!blankLine) { + // Until blank line, item doesn't need indentation + itemContents += '\n' + line; + } else { + // Otherwise, improper indentation ends this item + break; + } + + if (!blankLine && !line.trim()) { + // Check if current line is blank + blankLine = true; + } + + raw += rawLine + '\n'; + src = src.substring(rawLine.length + 1); + } + } + + if (!list.loose) { + // If the previous item ended with a blank line, the list is loose + if (endsWithBlankLine) { + list.loose = true; + } else if (/\n *\n *$/.test(raw)) { + endsWithBlankLine = true; + } + } // Check for task list items + + + if (this.options.gfm) { + istask = /^\[[ xX]\] /.exec(itemContents); + + if (istask) { + ischecked = istask[0] !== '[ ] '; + itemContents = itemContents.replace(/^\[[ xX]\] +/, ''); + } + } + + list.items.push({ + type: 'list_item', + raw: raw, + task: !!istask, + checked: ischecked, + loose: false, + text: itemContents + }); + list.raw += raw; + } // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic + + + list.items[list.items.length - 1].raw = raw.trimRight(); + list.items[list.items.length - 1].text = itemContents.trimRight(); + list.raw = list.raw.trimRight(); + var l = list.items.length; // Item child tokens handled here at end because we needed to have the final item to trim it first + + for (i = 0; i < l; i++) { + this.lexer.state.top = false; + list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []); + var spacers = list.items[i].tokens.filter(function (t) { + return t.type === 'space'; + }); + var hasMultipleLineBreaks = spacers.every(function (t) { + var chars = t.raw.split(''); + var lineBreaks = 0; + + for (var _iterator = _createForOfIteratorHelperLoose(chars), _step; !(_step = _iterator()).done;) { + var _char = _step.value; + + if (_char === '\n') { + lineBreaks += 1; + } + + if (lineBreaks > 1) { + return true; + } + } + + return false; + }); + + if (!list.loose && spacers.length && hasMultipleLineBreaks) { + // Having a single line break doesn't mean a list is loose. A single line break is terminating the last list item + list.loose = true; + list.items[i].loose = true; + } + } + + return list; + } + }; + + _proto.html = function html(src) { + var cap = this.rules.block.html.exec(src); + + if (cap) { + var token = { + type: 'html', + raw: cap[0], + pre: !this.options.sanitizer && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'), + text: cap[0] + }; + + if (this.options.sanitize) { + token.type = 'paragraph'; + token.text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]); + token.tokens = []; + this.lexer.inline(token.text, token.tokens); + } + + return token; + } + }; + + _proto.def = function def(src) { + var cap = this.rules.block.def.exec(src); + + if (cap) { + if (cap[3]) cap[3] = cap[3].substring(1, cap[3].length - 1); + var tag = cap[1].toLowerCase().replace(/\s+/g, ' '); + return { + type: 'def', + tag: tag, + raw: cap[0], + href: cap[2], + title: cap[3] + }; + } + }; + + _proto.table = function table(src) { + var cap = this.rules.block.table.exec(src); + + if (cap) { + var item = { + type: 'table', + header: splitCells(cap[1]).map(function (c) { + return { + text: c + }; + }), + align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), + rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : [] + }; + + if (item.header.length === item.align.length) { + item.raw = cap[0]; + var l = item.align.length; + var i, j, k, row; + + for (i = 0; i < l; i++) { + if (/^ *-+: *$/.test(item.align[i])) { + item.align[i] = 'right'; + } else if (/^ *:-+: *$/.test(item.align[i])) { + item.align[i] = 'center'; + } else if (/^ *:-+ *$/.test(item.align[i])) { + item.align[i] = 'left'; + } else { + item.align[i] = null; + } + } + + l = item.rows.length; + + for (i = 0; i < l; i++) { + item.rows[i] = splitCells(item.rows[i], item.header.length).map(function (c) { + return { + text: c + }; + }); + } // parse child tokens inside headers and cells + // header child tokens + + + l = item.header.length; + + for (j = 0; j < l; j++) { + item.header[j].tokens = []; + this.lexer.inline(item.header[j].text, item.header[j].tokens); + } // cell child tokens + + + l = item.rows.length; + + for (j = 0; j < l; j++) { + row = item.rows[j]; + + for (k = 0; k < row.length; k++) { + row[k].tokens = []; + this.lexer.inline(row[k].text, row[k].tokens); + } + } + + return item; + } + } + }; + + _proto.lheading = function lheading(src) { + var cap = this.rules.block.lheading.exec(src); + + if (cap) { + var token = { + type: 'heading', + raw: cap[0], + depth: cap[2].charAt(0) === '=' ? 1 : 2, + text: cap[1], + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + }; + + _proto.paragraph = function paragraph(src) { + var cap = this.rules.block.paragraph.exec(src); + + if (cap) { + var token = { + type: 'paragraph', + raw: cap[0], + text: cap[1].charAt(cap[1].length - 1) === '\n' ? cap[1].slice(0, -1) : cap[1], + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + }; + + _proto.text = function text(src) { + var cap = this.rules.block.text.exec(src); + + if (cap) { + var token = { + type: 'text', + raw: cap[0], + text: cap[0], + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + }; + + _proto.escape = function escape$1(src) { + var cap = this.rules.inline.escape.exec(src); + + if (cap) { + return { + type: 'escape', + raw: cap[0], + text: escape(cap[1]) + }; + } + }; + + _proto.tag = function tag(src) { + var cap = this.rules.inline.tag.exec(src); + + if (cap) { + if (!this.lexer.state.inLink && /^/i.test(cap[0])) { + this.lexer.state.inLink = false; + } + + if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { + this.lexer.state.inRawBlock = true; + } else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { + this.lexer.state.inRawBlock = false; + } + + return { + type: this.options.sanitize ? 'text' : 'html', + raw: cap[0], + inLink: this.lexer.state.inLink, + inRawBlock: this.lexer.state.inRawBlock, + text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0] + }; + } + }; + + _proto.link = function link(src) { + var cap = this.rules.inline.link.exec(src); + + if (cap) { + var trimmedUrl = cap[2].trim(); + + if (!this.options.pedantic && /^$/.test(trimmedUrl)) { + return; + } // ending angle bracket cannot be escaped + + + var rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\'); + + if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) { + return; + } + } else { + // find closing parenthesis + var lastParenIndex = findClosingBracket(cap[2], '()'); + + if (lastParenIndex > -1) { + var start = cap[0].indexOf('!') === 0 ? 5 : 4; + var linkLen = start + cap[1].length + lastParenIndex; + cap[2] = cap[2].substring(0, lastParenIndex); + cap[0] = cap[0].substring(0, linkLen).trim(); + cap[3] = ''; + } + } + + var href = cap[2]; + var title = ''; + + if (this.options.pedantic) { + // split pedantic href and title + var link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href); + + if (link) { + href = link[1]; + title = link[3]; + } + } else { + title = cap[3] ? cap[3].slice(1, -1) : ''; + } + + href = href.trim(); + + if (/^$/.test(trimmedUrl)) { + // pedantic allows starting angle bracket without ending angle bracket + href = href.slice(1); + } else { + href = href.slice(1, -1); + } + } + + return outputLink(cap, { + href: href ? href.replace(this.rules.inline._escapes, '$1') : href, + title: title ? title.replace(this.rules.inline._escapes, '$1') : title + }, cap[0], this.lexer); + } + }; + + _proto.reflink = function reflink(src, links) { + var cap; + + if ((cap = this.rules.inline.reflink.exec(src)) || (cap = this.rules.inline.nolink.exec(src))) { + var link = (cap[2] || cap[1]).replace(/\s+/g, ' '); + link = links[link.toLowerCase()]; + + if (!link || !link.href) { + var text = cap[0].charAt(0); + return { + type: 'text', + raw: text, + text: text + }; + } + + return outputLink(cap, link, cap[0], this.lexer); + } + }; + + _proto.emStrong = function emStrong(src, maskedSrc, prevChar) { + if (prevChar === void 0) { + prevChar = ''; + } + + var match = this.rules.inline.emStrong.lDelim.exec(src); + if (!match) return; // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well + + if (match[3] && prevChar.match(/(?:[0-9A-Za-z\xAA\xB2\xB3\xB5\xB9\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u0660-\u0669\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088E\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AE6-\u0AEF\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0BE6-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5D\u0C60\u0C61\u0C66-\u0C6F\u0C78-\u0C7E\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDD\u0CDE\u0CE0\u0CE1\u0CE6-\u0CEF\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D58-\u0D61\u0D66-\u0D78\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DE6-\u0DEF\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F-\u1049\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A16\u1A20-\u1A54\u1A80-\u1A89\u1A90-\u1A99\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B50-\u1B59\u1B83-\u1BA0\u1BAE-\u1BE5\u1C00-\u1C23\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070\u2071\u2074-\u2079\u207F-\u2089\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2150-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2CFD\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u3192-\u3195\u31A0-\u31BF\u31F0-\u31FF\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA830-\uA835\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uA9E0-\uA9E4\uA9E6-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDE80-\uDE9C\uDEA0-\uDED0\uDEE1-\uDEFB\uDF00-\uDF23\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC58-\uDC76\uDC79-\uDC9E\uDCA7-\uDCAF\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDD1B\uDD20-\uDD39\uDD80-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE40-\uDE48\uDE60-\uDE7E\uDE80-\uDE9F\uDEC0-\uDEC7\uDEC9-\uDEE4\uDEEB-\uDEEF\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDD23\uDD30-\uDD39\uDE60-\uDE7E\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF27\uDF30-\uDF45\uDF51-\uDF54\uDF70-\uDF81\uDFB0-\uDFCB\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC52-\uDC6F\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD03-\uDD26\uDD36-\uDD3F\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDD0-\uDDDA\uDDDC\uDDE1-\uDDF4\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDEF0-\uDEF9\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC50-\uDC59\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE50-\uDE59\uDE80-\uDEAA\uDEB8\uDEC0-\uDEC9\uDF00-\uDF1A\uDF30-\uDF3B\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCF2\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC50-\uDC6C\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDA0-\uDDA9\uDEE0-\uDEF2\uDFB0\uDFC0-\uDFD4]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDE70-\uDEBE\uDEC0-\uDEC9\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE96\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD834[\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD837[\uDF00-\uDF1E]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD40-\uDD49\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB\uDEF0-\uDEF9]|\uD839[\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF\uDD00-\uDD43\uDD4B\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF38\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])/)) return; + var nextChar = match[1] || match[2] || ''; + + if (!nextChar || nextChar && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar))) { + var lLength = match[0].length - 1; + var rDelim, + rLength, + delimTotal = lLength, + midDelimTotal = 0; + var endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd; + endReg.lastIndex = 0; // Clip maskedSrc to same section of string as src (move to lexer?) + + maskedSrc = maskedSrc.slice(-1 * src.length + lLength); + + while ((match = endReg.exec(maskedSrc)) != null) { + rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6]; + if (!rDelim) continue; // skip single * in __abc*abc__ + + rLength = rDelim.length; + + if (match[3] || match[4]) { + // found another Left Delim + delimTotal += rLength; + continue; + } else if (match[5] || match[6]) { + // either Left or Right Delim + if (lLength % 3 && !((lLength + rLength) % 3)) { + midDelimTotal += rLength; + continue; // CommonMark Emphasis Rules 9-10 + } + } + + delimTotal -= rLength; + if (delimTotal > 0) continue; // Haven't found enough closing delimiters + // Remove extra characters. *a*** -> *a* + + rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal); // Create `em` if smallest delimiter has odd char count. *a*** + + if (Math.min(lLength, rLength) % 2) { + var _text = src.slice(1, lLength + match.index + rLength); + + return { + type: 'em', + raw: src.slice(0, lLength + match.index + rLength + 1), + text: _text, + tokens: this.lexer.inlineTokens(_text, []) + }; + } // Create 'strong' if smallest delimiter has even char count. **a*** + + + var text = src.slice(2, lLength + match.index + rLength - 1); + return { + type: 'strong', + raw: src.slice(0, lLength + match.index + rLength + 1), + text: text, + tokens: this.lexer.inlineTokens(text, []) + }; + } + } + }; + + _proto.codespan = function codespan(src) { + var cap = this.rules.inline.code.exec(src); + + if (cap) { + var text = cap[2].replace(/\n/g, ' '); + var hasNonSpaceChars = /[^ ]/.test(text); + var hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text); + + if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) { + text = text.substring(1, text.length - 1); + } + + text = escape(text, true); + return { + type: 'codespan', + raw: cap[0], + text: text + }; + } + }; + + _proto.br = function br(src) { + var cap = this.rules.inline.br.exec(src); + + if (cap) { + return { + type: 'br', + raw: cap[0] + }; + } + }; + + _proto.del = function del(src) { + var cap = this.rules.inline.del.exec(src); + + if (cap) { + return { + type: 'del', + raw: cap[0], + text: cap[2], + tokens: this.lexer.inlineTokens(cap[2], []) + }; + } + }; + + _proto.autolink = function autolink(src, mangle) { + var cap = this.rules.inline.autolink.exec(src); + + if (cap) { + var text, href; + + if (cap[2] === '@') { + text = escape(this.options.mangle ? mangle(cap[1]) : cap[1]); + href = 'mailto:' + text; + } else { + text = escape(cap[1]); + href = text; + } + + return { + type: 'link', + raw: cap[0], + text: text, + href: href, + tokens: [{ + type: 'text', + raw: text, + text: text + }] + }; + } + }; + + _proto.url = function url(src, mangle) { + var cap; + + if (cap = this.rules.inline.url.exec(src)) { + var text, href; + + if (cap[2] === '@') { + text = escape(this.options.mangle ? mangle(cap[0]) : cap[0]); + href = 'mailto:' + text; + } else { + // do extended autolink path validation + var prevCapZero; + + do { + prevCapZero = cap[0]; + cap[0] = this.rules.inline._backpedal.exec(cap[0])[0]; + } while (prevCapZero !== cap[0]); + + text = escape(cap[0]); + + if (cap[1] === 'www.') { + href = 'http://' + text; + } else { + href = text; + } + } + + return { + type: 'link', + raw: cap[0], + text: text, + href: href, + tokens: [{ + type: 'text', + raw: text, + text: text + }] + }; + } + }; + + _proto.inlineText = function inlineText(src, smartypants) { + var cap = this.rules.inline.text.exec(src); + + if (cap) { + var text; + + if (this.lexer.state.inRawBlock) { + text = this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0]; + } else { + text = escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]); + } + + return { + type: 'text', + raw: cap[0], + text: text + }; + } + }; + + return Tokenizer; +}(); + +/** + * Block-Level Grammar + */ + +var block = { + newline: /^(?: *(?:\n|$))+/, + code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/, + fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/, + hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/, + heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/, + blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/, + list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/, + html: '^ {0,3}(?:' // optional indentation + + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)' // (1) + + '|comment[^\\n]*(\\n+|$)' // (2) + + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3) + + '|\\n*|$)' // (4) + + '|\\n*|$)' // (5) + + '|)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6) + + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag + + '|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag + + ')', + def: /^ {0,3}\[(label)\]: *(?:\n *)?]+)>?(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/, + table: noopTest, + lheading: /^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/, + // regex template, placeholders will be replaced according to different paragraph + // interruption rules of commonmark and the original markdown spec: + _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/, + text: /^[^\n]+/ +}; +block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/; +block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/; +block.def = edit(block.def).replace('label', block._label).replace('title', block._title).getRegex(); +block.bullet = /(?:[*+-]|\d{1,9}[.)])/; +block.listItemStart = edit(/^( *)(bull) */).replace('bull', block.bullet).getRegex(); +block.list = edit(block.list).replace(/bull/g, block.bullet).replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))').replace('def', '\\n+(?=' + block.def.source + ')').getRegex(); +block._tag = 'address|article|aside|base|basefont|blockquote|body|caption' + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption' + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe' + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option' + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr' + '|track|ul'; +block._comment = /|$)/; +block.html = edit(block.html, 'i').replace('comment', block._comment).replace('tag', block._tag).replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(); +block.paragraph = edit(block._paragraph).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs +.replace('|table', '').replace('blockquote', ' {0,3}>').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt +.replace('html', ')|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // pars can be interrupted by type (6) html blocks +.getRegex(); +block.blockquote = edit(block.blockquote).replace('paragraph', block.paragraph).getRegex(); +/** + * Normal Block Grammar + */ + +block.normal = merge({}, block); +/** + * GFM Block Grammar + */ + +block.gfm = merge({}, block.normal, { + table: '^ *([^\\n ].*\\|.*)\\n' // Header + + ' {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?' // Align + + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells + +}); +block.gfm.table = edit(block.gfm.table).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('blockquote', ' {0,3}>').replace('code', ' {4}[^\\n]').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt +.replace('html', ')|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // tables can be interrupted by type (6) html blocks +.getRegex(); +block.gfm.paragraph = edit(block._paragraph).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs +.replace('table', block.gfm.table) // interrupt paragraphs with table +.replace('blockquote', ' {0,3}>').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt +.replace('html', ')|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // pars can be interrupted by type (6) html blocks +.getRegex(); +/** + * Pedantic grammar (original John Gruber's loose markdown specification) + */ + +block.pedantic = merge({}, block.normal, { + html: edit('^ *(?:comment *(?:\\n|\\s*$)' + '|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)' // closed tag + + '|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))').replace('comment', block._comment).replace(/tag/g, '(?!(?:' + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub' + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)' + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b').getRegex(), + def: /^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, + heading: /^(#{1,6})(.*)(?:\n+|$)/, + fences: noopTest, + // fences not supported + paragraph: edit(block.normal._paragraph).replace('hr', block.hr).replace('heading', ' *#{1,6} *[^\n]').replace('lheading', block.lheading).replace('blockquote', ' {0,3}>').replace('|fences', '').replace('|list', '').replace('|html', '').getRegex() +}); +/** + * Inline-Level Grammar + */ + +var inline = { + escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, + autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/, + url: noopTest, + tag: '^comment' + '|^' // self-closing tag + + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag + + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. + + '|^' // declaration, e.g. + + '|^', + // CDATA section + link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/, + reflink: /^!?\[(label)\]\[(ref)\]/, + nolink: /^!?\[(ref)\](?:\[\])?/, + reflinkSearch: 'reflink|nolink(?!\\()', + emStrong: { + lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/, + // (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right. + // () Skip orphan inside strong () Consume to delim (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a + rDelimAst: /^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[^*]+(?=[^*])|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/, + rDelimUnd: /^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _ + + }, + code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, + br: /^( {2,}|\\)\n(?!\s*$)/, + del: noopTest, + text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\?@\\[\\]`^{|}~'; +inline.punctuation = edit(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex(); // sequences em should skip over [title](link), `code`, + +inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g; +inline.escapedEmSt = /\\\*|\\_/g; +inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex(); +inline.emStrong.lDelim = edit(inline.emStrong.lDelim).replace(/punct/g, inline._punctuation).getRegex(); +inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'g').replace(/punct/g, inline._punctuation).getRegex(); +inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'g').replace(/punct/g, inline._punctuation).getRegex(); +inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g; +inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/; +inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/; +inline.autolink = edit(inline.autolink).replace('scheme', inline._scheme).replace('email', inline._email).getRegex(); +inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/; +inline.tag = edit(inline.tag).replace('comment', inline._comment).replace('attribute', inline._attribute).getRegex(); +inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/; +inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/; +inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/; +inline.link = edit(inline.link).replace('label', inline._label).replace('href', inline._href).replace('title', inline._title).getRegex(); +inline.reflink = edit(inline.reflink).replace('label', inline._label).replace('ref', block._label).getRegex(); +inline.nolink = edit(inline.nolink).replace('ref', block._label).getRegex(); +inline.reflinkSearch = edit(inline.reflinkSearch, 'g').replace('reflink', inline.reflink).replace('nolink', inline.nolink).getRegex(); +/** + * Normal Inline Grammar + */ + +inline.normal = merge({}, inline); +/** + * Pedantic Inline Grammar + */ + +inline.pedantic = merge({}, inline.normal, { + strong: { + start: /^__|\*\*/, + middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, + endAst: /\*\*(?!\*)/g, + endUnd: /__(?!_)/g + }, + em: { + start: /^_|\*/, + middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/, + endAst: /\*(?!\*)/g, + endUnd: /_(?!_)/g + }, + link: edit(/^!?\[(label)\]\((.*?)\)/).replace('label', inline._label).getRegex(), + reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace('label', inline._label).getRegex() +}); +/** + * GFM Inline Grammar + */ + +inline.gfm = merge({}, inline.normal, { + escape: edit(inline.escape).replace('])', '~|])').getRegex(), + _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/, + url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, + _backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/, + del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/, + text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\ 0.5) { + ch = 'x' + ch.toString(16); + } + + out += '&#' + ch + ';'; + } + + return out; +} +/** + * Block Lexer + */ + + +var Lexer = /*#__PURE__*/function () { + function Lexer(options) { + this.tokens = []; + this.tokens.links = Object.create(null); + this.options = options || exports.defaults; + this.options.tokenizer = this.options.tokenizer || new Tokenizer(); + this.tokenizer = this.options.tokenizer; + this.tokenizer.options = this.options; + this.tokenizer.lexer = this; + this.inlineQueue = []; + this.state = { + inLink: false, + inRawBlock: false, + top: true + }; + var rules = { + block: block.normal, + inline: inline.normal + }; + + if (this.options.pedantic) { + rules.block = block.pedantic; + rules.inline = inline.pedantic; + } else if (this.options.gfm) { + rules.block = block.gfm; + + if (this.options.breaks) { + rules.inline = inline.breaks; + } else { + rules.inline = inline.gfm; + } + } + + this.tokenizer.rules = rules; + } + /** + * Expose Rules + */ + + + /** + * Static Lex Method + */ + Lexer.lex = function lex(src, options) { + var lexer = new Lexer(options); + return lexer.lex(src); + } + /** + * Static Lex Inline Method + */ + ; + + Lexer.lexInline = function lexInline(src, options) { + var lexer = new Lexer(options); + return lexer.inlineTokens(src); + } + /** + * Preprocessing + */ + ; + + var _proto = Lexer.prototype; + + _proto.lex = function lex(src) { + src = src.replace(/\r\n|\r/g, '\n'); + this.blockTokens(src, this.tokens); + var next; + + while (next = this.inlineQueue.shift()) { + this.inlineTokens(next.src, next.tokens); + } + + return this.tokens; + } + /** + * Lexing + */ + ; + + _proto.blockTokens = function blockTokens(src, tokens) { + var _this = this; + + if (tokens === void 0) { + tokens = []; + } + + if (this.options.pedantic) { + src = src.replace(/\t/g, ' ').replace(/^ +$/gm, ''); + } else { + src = src.replace(/^( *)(\t+)/gm, function (_, leading, tabs) { + return leading + ' '.repeat(tabs.length); + }); + } + + var token, lastToken, cutSrc, lastParagraphClipped; + + while (src) { + if (this.options.extensions && this.options.extensions.block && this.options.extensions.block.some(function (extTokenizer) { + if (token = extTokenizer.call({ + lexer: _this + }, src, tokens)) { + src = src.substring(token.raw.length); + tokens.push(token); + return true; + } + + return false; + })) { + continue; + } // newline + + + if (token = this.tokenizer.space(src)) { + src = src.substring(token.raw.length); + + if (token.raw.length === 1 && tokens.length > 0) { + // if there's a single \n as a spacer, it's terminating the last line, + // so move it there so that we don't get unecessary paragraph tags + tokens[tokens.length - 1].raw += '\n'; + } else { + tokens.push(token); + } + + continue; + } // code + + + if (token = this.tokenizer.code(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; // An indented code block cannot interrupt a paragraph. + + if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.text; + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else { + tokens.push(token); + } + + continue; + } // fences + + + if (token = this.tokenizer.fences(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // heading + + + if (token = this.tokenizer.heading(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // hr + + + if (token = this.tokenizer.hr(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // blockquote + + + if (token = this.tokenizer.blockquote(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // list + + + if (token = this.tokenizer.list(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // html + + + if (token = this.tokenizer.html(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // def + + + if (token = this.tokenizer.def(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + + if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.raw; + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else if (!this.tokens.links[token.tag]) { + this.tokens.links[token.tag] = { + href: token.href, + title: token.title + }; + } + + continue; + } // table (gfm) + + + if (token = this.tokenizer.table(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // lheading + + + if (token = this.tokenizer.lheading(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // top-level paragraph + // prevent paragraph consuming extensions by clipping 'src' to extension start + + + cutSrc = src; + + if (this.options.extensions && this.options.extensions.startBlock) { + (function () { + var startIndex = Infinity; + var tempSrc = src.slice(1); + var tempStart = void 0; + + _this.options.extensions.startBlock.forEach(function (getStartIndex) { + tempStart = getStartIndex.call({ + lexer: this + }, tempSrc); + + if (typeof tempStart === 'number' && tempStart >= 0) { + startIndex = Math.min(startIndex, tempStart); + } + }); + + if (startIndex < Infinity && startIndex >= 0) { + cutSrc = src.substring(0, startIndex + 1); + } + })(); + } + + if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) { + lastToken = tokens[tokens.length - 1]; + + if (lastParagraphClipped && lastToken.type === 'paragraph') { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.text; + this.inlineQueue.pop(); + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else { + tokens.push(token); + } + + lastParagraphClipped = cutSrc.length !== src.length; + src = src.substring(token.raw.length); + continue; + } // text + + + if (token = this.tokenizer.text(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + + if (lastToken && lastToken.type === 'text') { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.text; + this.inlineQueue.pop(); + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else { + tokens.push(token); + } + + continue; + } + + if (src) { + var errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0); + + if (this.options.silent) { + console.error(errMsg); + break; + } else { + throw new Error(errMsg); + } + } + } + + this.state.top = true; + return tokens; + }; + + _proto.inline = function inline(src, tokens) { + this.inlineQueue.push({ + src: src, + tokens: tokens + }); + } + /** + * Lexing/Compiling + */ + ; + + _proto.inlineTokens = function inlineTokens(src, tokens) { + var _this2 = this; + + if (tokens === void 0) { + tokens = []; + } + + var token, lastToken, cutSrc; // String with links masked to avoid interference with em and strong + + var maskedSrc = src; + var match; + var keepPrevChar, prevChar; // Mask out reflinks + + if (this.tokens.links) { + var links = Object.keys(this.tokens.links); + + if (links.length > 0) { + while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) { + if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) { + maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex); + } + } + } + } // Mask out other blocks + + + while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) { + maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex); + } // Mask out escaped em & strong delimiters + + + while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) { + maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex); + } + + while (src) { + if (!keepPrevChar) { + prevChar = ''; + } + + keepPrevChar = false; // extensions + + if (this.options.extensions && this.options.extensions.inline && this.options.extensions.inline.some(function (extTokenizer) { + if (token = extTokenizer.call({ + lexer: _this2 + }, src, tokens)) { + src = src.substring(token.raw.length); + tokens.push(token); + return true; + } + + return false; + })) { + continue; + } // escape + + + if (token = this.tokenizer.escape(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // tag + + + if (token = this.tokenizer.tag(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + + if (lastToken && token.type === 'text' && lastToken.type === 'text') { + lastToken.raw += token.raw; + lastToken.text += token.text; + } else { + tokens.push(token); + } + + continue; + } // link + + + if (token = this.tokenizer.link(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // reflink, nolink + + + if (token = this.tokenizer.reflink(src, this.tokens.links)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + + if (lastToken && token.type === 'text' && lastToken.type === 'text') { + lastToken.raw += token.raw; + lastToken.text += token.text; + } else { + tokens.push(token); + } + + continue; + } // em & strong + + + if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // code + + + if (token = this.tokenizer.codespan(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // br + + + if (token = this.tokenizer.br(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // del (gfm) + + + if (token = this.tokenizer.del(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // autolink + + + if (token = this.tokenizer.autolink(src, mangle)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // url (gfm) + + + if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // text + // prevent inlineText consuming extensions by clipping 'src' to extension start + + + cutSrc = src; + + if (this.options.extensions && this.options.extensions.startInline) { + (function () { + var startIndex = Infinity; + var tempSrc = src.slice(1); + var tempStart = void 0; + + _this2.options.extensions.startInline.forEach(function (getStartIndex) { + tempStart = getStartIndex.call({ + lexer: this + }, tempSrc); + + if (typeof tempStart === 'number' && tempStart >= 0) { + startIndex = Math.min(startIndex, tempStart); + } + }); + + if (startIndex < Infinity && startIndex >= 0) { + cutSrc = src.substring(0, startIndex + 1); + } + })(); + } + + if (token = this.tokenizer.inlineText(cutSrc, smartypants)) { + src = src.substring(token.raw.length); + + if (token.raw.slice(-1) !== '_') { + // Track prevChar before string of ____ started + prevChar = token.raw.slice(-1); + } + + keepPrevChar = true; + lastToken = tokens[tokens.length - 1]; + + if (lastToken && lastToken.type === 'text') { + lastToken.raw += token.raw; + lastToken.text += token.text; + } else { + tokens.push(token); + } + + continue; + } + + if (src) { + var errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0); + + if (this.options.silent) { + console.error(errMsg); + break; + } else { + throw new Error(errMsg); + } + } + } + + return tokens; + }; + + _createClass(Lexer, null, [{ + key: "rules", + get: function get() { + return { + block: block, + inline: inline + }; + } + }]); + + return Lexer; +}(); + +/** + * Renderer + */ + +var Renderer = /*#__PURE__*/function () { + function Renderer(options) { + this.options = options || exports.defaults; + } + + var _proto = Renderer.prototype; + + _proto.code = function code(_code, infostring, escaped) { + var lang = (infostring || '').match(/\S*/)[0]; + + if (this.options.highlight) { + var out = this.options.highlight(_code, lang); + + if (out != null && out !== _code) { + escaped = true; + _code = out; + } + } + + _code = _code.replace(/\n$/, '') + '\n'; + + if (!lang) { + return '
' + (escaped ? _code : escape(_code, true)) + '
\n'; + } + + return '
' + (escaped ? _code : escape(_code, true)) + '
\n'; + } + /** + * @param {string} quote + */ + ; + + _proto.blockquote = function blockquote(quote) { + return "
\n" + quote + "
\n"; + }; + + _proto.html = function html(_html) { + return _html; + } + /** + * @param {string} text + * @param {string} level + * @param {string} raw + * @param {any} slugger + */ + ; + + _proto.heading = function heading(text, level, raw, slugger) { + if (this.options.headerIds) { + var id = this.options.headerPrefix + slugger.slug(raw); + return "" + text + "\n"; + } // ignore IDs + + + return "" + text + "\n"; + }; + + _proto.hr = function hr() { + return this.options.xhtml ? '
\n' : '
\n'; + }; + + _proto.list = function list(body, ordered, start) { + var type = ordered ? 'ol' : 'ul', + startatt = ordered && start !== 1 ? ' start="' + start + '"' : ''; + return '<' + type + startatt + '>\n' + body + '\n'; + } + /** + * @param {string} text + */ + ; + + _proto.listitem = function listitem(text) { + return "
  • " + text + "
  • \n"; + }; + + _proto.checkbox = function checkbox(checked) { + return ' '; + } + /** + * @param {string} text + */ + ; + + _proto.paragraph = function paragraph(text) { + return "

    " + text + "

    \n"; + } + /** + * @param {string} header + * @param {string} body + */ + ; + + _proto.table = function table(header, body) { + if (body) body = "" + body + ""; + return '\n' + '\n' + header + '\n' + body + '
    \n'; + } + /** + * @param {string} content + */ + ; + + _proto.tablerow = function tablerow(content) { + return "\n" + content + "\n"; + }; + + _proto.tablecell = function tablecell(content, flags) { + var type = flags.header ? 'th' : 'td'; + var tag = flags.align ? "<" + type + " align=\"" + flags.align + "\">" : "<" + type + ">"; + return tag + content + ("\n"); + } + /** + * span level renderer + * @param {string} text + */ + ; + + _proto.strong = function strong(text) { + return "" + text + ""; + } + /** + * @param {string} text + */ + ; + + _proto.em = function em(text) { + return "" + text + ""; + } + /** + * @param {string} text + */ + ; + + _proto.codespan = function codespan(text) { + return "" + text + ""; + }; + + _proto.br = function br() { + return this.options.xhtml ? '
    ' : '
    '; + } + /** + * @param {string} text + */ + ; + + _proto.del = function del(text) { + return "" + text + ""; + } + /** + * @param {string} href + * @param {string} title + * @param {string} text + */ + ; + + _proto.link = function link(href, title, text) { + href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); + + if (href === null) { + return text; + } + + var out = '
    '; + return out; + } + /** + * @param {string} href + * @param {string} title + * @param {string} text + */ + ; + + _proto.image = function image(href, title, text) { + href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); + + if (href === null) { + return text; + } + + var out = "\""' : '>'; + return out; + }; + + _proto.text = function text(_text) { + return _text; + }; + + return Renderer; +}(); + +/** + * TextRenderer + * returns only the textual part of the token + */ +var TextRenderer = /*#__PURE__*/function () { + function TextRenderer() {} + + var _proto = TextRenderer.prototype; + + // no need for block level renderers + _proto.strong = function strong(text) { + return text; + }; + + _proto.em = function em(text) { + return text; + }; + + _proto.codespan = function codespan(text) { + return text; + }; + + _proto.del = function del(text) { + return text; + }; + + _proto.html = function html(text) { + return text; + }; + + _proto.text = function text(_text) { + return _text; + }; + + _proto.link = function link(href, title, text) { + return '' + text; + }; + + _proto.image = function image(href, title, text) { + return '' + text; + }; + + _proto.br = function br() { + return ''; + }; + + return TextRenderer; +}(); + +/** + * Slugger generates header id + */ +var Slugger = /*#__PURE__*/function () { + function Slugger() { + this.seen = {}; + } + /** + * @param {string} value + */ + + + var _proto = Slugger.prototype; + + _proto.serialize = function serialize(value) { + return value.toLowerCase().trim() // remove html tags + .replace(/<[!\/a-z].*?>/ig, '') // remove unwanted chars + .replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '').replace(/\s/g, '-'); + } + /** + * Finds the next safe (unique) slug to use + * @param {string} originalSlug + * @param {boolean} isDryRun + */ + ; + + _proto.getNextSafeSlug = function getNextSafeSlug(originalSlug, isDryRun) { + var slug = originalSlug; + var occurenceAccumulator = 0; + + if (this.seen.hasOwnProperty(slug)) { + occurenceAccumulator = this.seen[originalSlug]; + + do { + occurenceAccumulator++; + slug = originalSlug + '-' + occurenceAccumulator; + } while (this.seen.hasOwnProperty(slug)); + } + + if (!isDryRun) { + this.seen[originalSlug] = occurenceAccumulator; + this.seen[slug] = 0; + } + + return slug; + } + /** + * Convert string to unique id + * @param {object} [options] + * @param {boolean} [options.dryrun] Generates the next unique slug without + * updating the internal accumulator. + */ + ; + + _proto.slug = function slug(value, options) { + if (options === void 0) { + options = {}; + } + + var slug = this.serialize(value); + return this.getNextSafeSlug(slug, options.dryrun); + }; + + return Slugger; +}(); + +/** + * Parsing & Compiling + */ + +var Parser = /*#__PURE__*/function () { + function Parser(options) { + this.options = options || exports.defaults; + this.options.renderer = this.options.renderer || new Renderer(); + this.renderer = this.options.renderer; + this.renderer.options = this.options; + this.textRenderer = new TextRenderer(); + this.slugger = new Slugger(); + } + /** + * Static Parse Method + */ + + + Parser.parse = function parse(tokens, options) { + var parser = new Parser(options); + return parser.parse(tokens); + } + /** + * Static Parse Inline Method + */ + ; + + Parser.parseInline = function parseInline(tokens, options) { + var parser = new Parser(options); + return parser.parseInline(tokens); + } + /** + * Parse Loop + */ + ; + + var _proto = Parser.prototype; + + _proto.parse = function parse(tokens, top) { + if (top === void 0) { + top = true; + } + + var out = '', + i, + j, + k, + l2, + l3, + row, + cell, + header, + body, + token, + ordered, + start, + loose, + itemBody, + item, + checked, + task, + checkbox, + ret; + var l = tokens.length; + + for (i = 0; i < l; i++) { + token = tokens[i]; // Run any renderer extensions + + if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { + ret = this.options.extensions.renderers[token.type].call({ + parser: this + }, token); + + if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) { + out += ret || ''; + continue; + } + } + + switch (token.type) { + case 'space': + { + continue; + } + + case 'hr': + { + out += this.renderer.hr(); + continue; + } + + case 'heading': + { + out += this.renderer.heading(this.parseInline(token.tokens), token.depth, unescape(this.parseInline(token.tokens, this.textRenderer)), this.slugger); + continue; + } + + case 'code': + { + out += this.renderer.code(token.text, token.lang, token.escaped); + continue; + } + + case 'table': + { + header = ''; // header + + cell = ''; + l2 = token.header.length; + + for (j = 0; j < l2; j++) { + cell += this.renderer.tablecell(this.parseInline(token.header[j].tokens), { + header: true, + align: token.align[j] + }); + } + + header += this.renderer.tablerow(cell); + body = ''; + l2 = token.rows.length; + + for (j = 0; j < l2; j++) { + row = token.rows[j]; + cell = ''; + l3 = row.length; + + for (k = 0; k < l3; k++) { + cell += this.renderer.tablecell(this.parseInline(row[k].tokens), { + header: false, + align: token.align[k] + }); + } + + body += this.renderer.tablerow(cell); + } + + out += this.renderer.table(header, body); + continue; + } + + case 'blockquote': + { + body = this.parse(token.tokens); + out += this.renderer.blockquote(body); + continue; + } + + case 'list': + { + ordered = token.ordered; + start = token.start; + loose = token.loose; + l2 = token.items.length; + body = ''; + + for (j = 0; j < l2; j++) { + item = token.items[j]; + checked = item.checked; + task = item.task; + itemBody = ''; + + if (item.task) { + checkbox = this.renderer.checkbox(checked); + + if (loose) { + if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') { + item.tokens[0].text = checkbox + ' ' + item.tokens[0].text; + + if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') { + item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text; + } + } else { + item.tokens.unshift({ + type: 'text', + text: checkbox + }); + } + } else { + itemBody += checkbox; + } + } + + itemBody += this.parse(item.tokens, loose); + body += this.renderer.listitem(itemBody, task, checked); + } + + out += this.renderer.list(body, ordered, start); + continue; + } + + case 'html': + { + // TODO parse inline content if parameter markdown=1 + out += this.renderer.html(token.text); + continue; + } + + case 'paragraph': + { + out += this.renderer.paragraph(this.parseInline(token.tokens)); + continue; + } + + case 'text': + { + body = token.tokens ? this.parseInline(token.tokens) : token.text; + + while (i + 1 < l && tokens[i + 1].type === 'text') { + token = tokens[++i]; + body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text); + } + + out += top ? this.renderer.paragraph(body) : body; + continue; + } + + default: + { + var errMsg = 'Token with "' + token.type + '" type was not found.'; + + if (this.options.silent) { + console.error(errMsg); + return; + } else { + throw new Error(errMsg); + } + } + } + } + + return out; + } + /** + * Parse Inline Tokens + */ + ; + + _proto.parseInline = function parseInline(tokens, renderer) { + renderer = renderer || this.renderer; + var out = '', + i, + token, + ret; + var l = tokens.length; + + for (i = 0; i < l; i++) { + token = tokens[i]; // Run any renderer extensions + + if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { + ret = this.options.extensions.renderers[token.type].call({ + parser: this + }, token); + + if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) { + out += ret || ''; + continue; + } + } + + switch (token.type) { + case 'escape': + { + out += renderer.text(token.text); + break; + } + + case 'html': + { + out += renderer.html(token.text); + break; + } + + case 'link': + { + out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer)); + break; + } + + case 'image': + { + out += renderer.image(token.href, token.title, token.text); + break; + } + + case 'strong': + { + out += renderer.strong(this.parseInline(token.tokens, renderer)); + break; + } + + case 'em': + { + out += renderer.em(this.parseInline(token.tokens, renderer)); + break; + } + + case 'codespan': + { + out += renderer.codespan(token.text); + break; + } + + case 'br': + { + out += renderer.br(); + break; + } + + case 'del': + { + out += renderer.del(this.parseInline(token.tokens, renderer)); + break; + } + + case 'text': + { + out += renderer.text(token.text); + break; + } + + default: + { + var errMsg = 'Token with "' + token.type + '" type was not found.'; + + if (this.options.silent) { + console.error(errMsg); + return; + } else { + throw new Error(errMsg); + } + } + } + } + + return out; + }; + + return Parser; +}(); + +/** + * Marked + */ + +function marked(src, opt, callback) { + // throw error in case of non string input + if (typeof src === 'undefined' || src === null) { + throw new Error('marked(): input parameter is undefined or null'); + } + + if (typeof src !== 'string') { + throw new Error('marked(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected'); + } + + if (typeof opt === 'function') { + callback = opt; + opt = null; + } + + opt = merge({}, marked.defaults, opt || {}); + checkSanitizeDeprecation(opt); + + if (callback) { + var highlight = opt.highlight; + var tokens; + + try { + tokens = Lexer.lex(src, opt); + } catch (e) { + return callback(e); + } + + var done = function done(err) { + var out; + + if (!err) { + try { + if (opt.walkTokens) { + marked.walkTokens(tokens, opt.walkTokens); + } + + out = Parser.parse(tokens, opt); + } catch (e) { + err = e; + } + } + + opt.highlight = highlight; + return err ? callback(err) : callback(null, out); + }; + + if (!highlight || highlight.length < 3) { + return done(); + } + + delete opt.highlight; + if (!tokens.length) return done(); + var pending = 0; + marked.walkTokens(tokens, function (token) { + if (token.type === 'code') { + pending++; + setTimeout(function () { + highlight(token.text, token.lang, function (err, code) { + if (err) { + return done(err); + } + + if (code != null && code !== token.text) { + token.text = code; + token.escaped = true; + } + + pending--; + + if (pending === 0) { + done(); + } + }); + }, 0); + } + }); + + if (pending === 0) { + done(); + } + + return; + } + + try { + var _tokens = Lexer.lex(src, opt); + + if (opt.walkTokens) { + marked.walkTokens(_tokens, opt.walkTokens); + } + + return Parser.parse(_tokens, opt); + } catch (e) { + e.message += '\nPlease report this to https://github.com/markedjs/marked.'; + + if (opt.silent) { + return '

    An error occurred:

    ' + escape(e.message + '', true) + '
    '; + } + + throw e; + } +} +/** + * Options + */ + +marked.options = marked.setOptions = function (opt) { + merge(marked.defaults, opt); + changeDefaults(marked.defaults); + return marked; +}; + +marked.getDefaults = getDefaults; +marked.defaults = exports.defaults; +/** + * Use Extension + */ + +marked.use = function () { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + var opts = merge.apply(void 0, [{}].concat(args)); + var extensions = marked.defaults.extensions || { + renderers: {}, + childTokens: {} + }; + var hasExtensions; + args.forEach(function (pack) { + // ==-- Parse "addon" extensions --== // + if (pack.extensions) { + hasExtensions = true; + pack.extensions.forEach(function (ext) { + if (!ext.name) { + throw new Error('extension name required'); + } + + if (ext.renderer) { + // Renderer extensions + var prevRenderer = extensions.renderers ? extensions.renderers[ext.name] : null; + + if (prevRenderer) { + // Replace extension with func to run new extension but fall back if false + extensions.renderers[ext.name] = function () { + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + var ret = ext.renderer.apply(this, args); + + if (ret === false) { + ret = prevRenderer.apply(this, args); + } + + return ret; + }; + } else { + extensions.renderers[ext.name] = ext.renderer; + } + } + + if (ext.tokenizer) { + // Tokenizer Extensions + if (!ext.level || ext.level !== 'block' && ext.level !== 'inline') { + throw new Error("extension level must be 'block' or 'inline'"); + } + + if (extensions[ext.level]) { + extensions[ext.level].unshift(ext.tokenizer); + } else { + extensions[ext.level] = [ext.tokenizer]; + } + + if (ext.start) { + // Function to check for start of token + if (ext.level === 'block') { + if (extensions.startBlock) { + extensions.startBlock.push(ext.start); + } else { + extensions.startBlock = [ext.start]; + } + } else if (ext.level === 'inline') { + if (extensions.startInline) { + extensions.startInline.push(ext.start); + } else { + extensions.startInline = [ext.start]; + } + } + } + } + + if (ext.childTokens) { + // Child tokens to be visited by walkTokens + extensions.childTokens[ext.name] = ext.childTokens; + } + }); + } // ==-- Parse "overwrite" extensions --== // + + + if (pack.renderer) { + (function () { + var renderer = marked.defaults.renderer || new Renderer(); + + var _loop = function _loop(prop) { + var prevRenderer = renderer[prop]; // Replace renderer with func to run extension, but fall back if false + + renderer[prop] = function () { + for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args[_key3] = arguments[_key3]; + } + + var ret = pack.renderer[prop].apply(renderer, args); + + if (ret === false) { + ret = prevRenderer.apply(renderer, args); + } + + return ret; + }; + }; + + for (var prop in pack.renderer) { + _loop(prop); + } + + opts.renderer = renderer; + })(); + } + + if (pack.tokenizer) { + (function () { + var tokenizer = marked.defaults.tokenizer || new Tokenizer(); + + var _loop2 = function _loop2(prop) { + var prevTokenizer = tokenizer[prop]; // Replace tokenizer with func to run extension, but fall back if false + + tokenizer[prop] = function () { + for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; + } + + var ret = pack.tokenizer[prop].apply(tokenizer, args); + + if (ret === false) { + ret = prevTokenizer.apply(tokenizer, args); + } + + return ret; + }; + }; + + for (var prop in pack.tokenizer) { + _loop2(prop); + } + + opts.tokenizer = tokenizer; + })(); + } // ==-- Parse WalkTokens extensions --== // + + + if (pack.walkTokens) { + var _walkTokens = marked.defaults.walkTokens; + + opts.walkTokens = function (token) { + pack.walkTokens.call(this, token); + + if (_walkTokens) { + _walkTokens.call(this, token); + } + }; + } + + if (hasExtensions) { + opts.extensions = extensions; + } + + marked.setOptions(opts); + }); +}; +/** + * Run callback for every token + */ + + +marked.walkTokens = function (tokens, callback) { + var _loop3 = function _loop3() { + var token = _step.value; + callback.call(marked, token); + + switch (token.type) { + case 'table': + { + for (var _iterator2 = _createForOfIteratorHelperLoose(token.header), _step2; !(_step2 = _iterator2()).done;) { + var cell = _step2.value; + marked.walkTokens(cell.tokens, callback); + } + + for (var _iterator3 = _createForOfIteratorHelperLoose(token.rows), _step3; !(_step3 = _iterator3()).done;) { + var row = _step3.value; + + for (var _iterator4 = _createForOfIteratorHelperLoose(row), _step4; !(_step4 = _iterator4()).done;) { + var _cell = _step4.value; + marked.walkTokens(_cell.tokens, callback); + } + } + + break; + } + + case 'list': + { + marked.walkTokens(token.items, callback); + break; + } + + default: + { + if (marked.defaults.extensions && marked.defaults.extensions.childTokens && marked.defaults.extensions.childTokens[token.type]) { + // Walk any extensions + marked.defaults.extensions.childTokens[token.type].forEach(function (childTokens) { + marked.walkTokens(token[childTokens], callback); + }); + } else if (token.tokens) { + marked.walkTokens(token.tokens, callback); + } + } + } + }; + + for (var _iterator = _createForOfIteratorHelperLoose(tokens), _step; !(_step = _iterator()).done;) { + _loop3(); + } +}; +/** + * Parse Inline + * @param {string} src + */ + + +marked.parseInline = function (src, opt) { + // throw error in case of non string input + if (typeof src === 'undefined' || src === null) { + throw new Error('marked.parseInline(): input parameter is undefined or null'); + } + + if (typeof src !== 'string') { + throw new Error('marked.parseInline(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected'); + } + + opt = merge({}, marked.defaults, opt || {}); + checkSanitizeDeprecation(opt); + + try { + var tokens = Lexer.lexInline(src, opt); + + if (opt.walkTokens) { + marked.walkTokens(tokens, opt.walkTokens); + } + + return Parser.parseInline(tokens, opt); + } catch (e) { + e.message += '\nPlease report this to https://github.com/markedjs/marked.'; + + if (opt.silent) { + return '

    An error occurred:

    ' + escape(e.message + '', true) + '
    '; + } + + throw e; + } +}; +/** + * Expose + */ + + +marked.Parser = Parser; +marked.parser = Parser.parse; +marked.Renderer = Renderer; +marked.TextRenderer = TextRenderer; +marked.Lexer = Lexer; +marked.lexer = Lexer.lex; +marked.Tokenizer = Tokenizer; +marked.Slugger = Slugger; +marked.parse = marked; +var options = marked.options; +var setOptions = marked.setOptions; +var use = marked.use; +var walkTokens = marked.walkTokens; +var parseInline = marked.parseInline; +var parse = marked; +var parser = Parser.parse; +var lexer = Lexer.lex; + +exports.Lexer = Lexer; +exports.Parser = Parser; +exports.Renderer = Renderer; +exports.Slugger = Slugger; +exports.TextRenderer = TextRenderer; +exports.Tokenizer = Tokenizer; +exports.getDefaults = getDefaults; +exports.lexer = lexer; +exports.marked = marked; +exports.options = options; +exports.parse = parse; +exports.parseInline = parseInline; +exports.parser = parser; +exports.setOptions = setOptions; +exports.use = use; +exports.walkTokens = walkTokens; diff --git a/node_modules/marked/lib/marked.esm.js b/node_modules/marked/lib/marked.esm.js new file mode 100644 index 0000000..a7422a6 --- /dev/null +++ b/node_modules/marked/lib/marked.esm.js @@ -0,0 +1,2794 @@ +/** + * marked - a markdown parser + * Copyright (c) 2011-2022, Christopher Jeffrey. (MIT Licensed) + * https://github.com/markedjs/marked + */ + +/** + * DO NOT EDIT THIS FILE + * The code in this file is generated from files in ./src/ + */ + +function getDefaults() { + return { + baseUrl: null, + breaks: false, + extensions: null, + gfm: true, + headerIds: true, + headerPrefix: '', + highlight: null, + langPrefix: 'language-', + mangle: true, + pedantic: false, + renderer: null, + sanitize: false, + sanitizer: null, + silent: false, + smartLists: false, + smartypants: false, + tokenizer: null, + walkTokens: null, + xhtml: false + }; +} + +let defaults = getDefaults(); + +function changeDefaults(newDefaults) { + defaults = newDefaults; +} + +/** + * Helpers + */ +const escapeTest = /[&<>"']/; +const escapeReplace = /[&<>"']/g; +const escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/; +const escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g; +const escapeReplacements = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' +}; +const getEscapeReplacement = (ch) => escapeReplacements[ch]; +function escape(html, encode) { + if (encode) { + if (escapeTest.test(html)) { + return html.replace(escapeReplace, getEscapeReplacement); + } + } else { + if (escapeTestNoEncode.test(html)) { + return html.replace(escapeReplaceNoEncode, getEscapeReplacement); + } + } + + return html; +} + +const unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig; + +/** + * @param {string} html + */ +function unescape(html) { + // explicitly match decimal, hex, and named HTML entities + return html.replace(unescapeTest, (_, n) => { + n = n.toLowerCase(); + if (n === 'colon') return ':'; + if (n.charAt(0) === '#') { + return n.charAt(1) === 'x' + ? String.fromCharCode(parseInt(n.substring(2), 16)) + : String.fromCharCode(+n.substring(1)); + } + return ''; + }); +} + +const caret = /(^|[^\[])\^/g; + +/** + * @param {string | RegExp} regex + * @param {string} opt + */ +function edit(regex, opt) { + regex = typeof regex === 'string' ? regex : regex.source; + opt = opt || ''; + const obj = { + replace: (name, val) => { + val = val.source || val; + val = val.replace(caret, '$1'); + regex = regex.replace(name, val); + return obj; + }, + getRegex: () => { + return new RegExp(regex, opt); + } + }; + return obj; +} + +const nonWordAndColonTest = /[^\w:]/g; +const originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i; + +/** + * @param {boolean} sanitize + * @param {string} base + * @param {string} href + */ +function cleanUrl(sanitize, base, href) { + if (sanitize) { + let prot; + try { + prot = decodeURIComponent(unescape(href)) + .replace(nonWordAndColonTest, '') + .toLowerCase(); + } catch (e) { + return null; + } + if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) { + return null; + } + } + if (base && !originIndependentUrl.test(href)) { + href = resolveUrl(base, href); + } + try { + href = encodeURI(href).replace(/%25/g, '%'); + } catch (e) { + return null; + } + return href; +} + +const baseUrls = {}; +const justDomain = /^[^:]+:\/*[^/]*$/; +const protocol = /^([^:]+:)[\s\S]*$/; +const domain = /^([^:]+:\/*[^/]*)[\s\S]*$/; + +/** + * @param {string} base + * @param {string} href + */ +function resolveUrl(base, href) { + if (!baseUrls[' ' + base]) { + // we can ignore everything in base after the last slash of its path component, + // but we might need to add _that_ + // https://tools.ietf.org/html/rfc3986#section-3 + if (justDomain.test(base)) { + baseUrls[' ' + base] = base + '/'; + } else { + baseUrls[' ' + base] = rtrim(base, '/', true); + } + } + base = baseUrls[' ' + base]; + const relativeBase = base.indexOf(':') === -1; + + if (href.substring(0, 2) === '//') { + if (relativeBase) { + return href; + } + return base.replace(protocol, '$1') + href; + } else if (href.charAt(0) === '/') { + if (relativeBase) { + return href; + } + return base.replace(domain, '$1') + href; + } else { + return base + href; + } +} + +const noopTest = { exec: function noopTest() {} }; + +function merge(obj) { + let i = 1, + target, + key; + + for (; i < arguments.length; i++) { + target = arguments[i]; + for (key in target) { + if (Object.prototype.hasOwnProperty.call(target, key)) { + obj[key] = target[key]; + } + } + } + + return obj; +} + +function splitCells(tableRow, count) { + // ensure that every cell-delimiting pipe has a space + // before it to distinguish it from an escaped pipe + const row = tableRow.replace(/\|/g, (match, offset, str) => { + let escaped = false, + curr = offset; + while (--curr >= 0 && str[curr] === '\\') escaped = !escaped; + if (escaped) { + // odd number of slashes means | is escaped + // so we leave it alone + return '|'; + } else { + // add space before unescaped | + return ' |'; + } + }), + cells = row.split(/ \|/); + let i = 0; + + // First/last cell in a row cannot be empty if it has no leading/trailing pipe + if (!cells[0].trim()) { cells.shift(); } + if (cells.length > 0 && !cells[cells.length - 1].trim()) { cells.pop(); } + + if (cells.length > count) { + cells.splice(count); + } else { + while (cells.length < count) cells.push(''); + } + + for (; i < cells.length; i++) { + // leading or trailing whitespace is ignored per the gfm spec + cells[i] = cells[i].trim().replace(/\\\|/g, '|'); + } + return cells; +} + +/** + * Remove trailing 'c's. Equivalent to str.replace(/c*$/, ''). + * /c*$/ is vulnerable to REDOS. + * + * @param {string} str + * @param {string} c + * @param {boolean} invert Remove suffix of non-c chars instead. Default falsey. + */ +function rtrim(str, c, invert) { + const l = str.length; + if (l === 0) { + return ''; + } + + // Length of suffix matching the invert condition. + let suffLen = 0; + + // Step left until we fail to match the invert condition. + while (suffLen < l) { + const currChar = str.charAt(l - suffLen - 1); + if (currChar === c && !invert) { + suffLen++; + } else if (currChar !== c && invert) { + suffLen++; + } else { + break; + } + } + + return str.slice(0, l - suffLen); +} + +function findClosingBracket(str, b) { + if (str.indexOf(b[1]) === -1) { + return -1; + } + const l = str.length; + let level = 0, + i = 0; + for (; i < l; i++) { + if (str[i] === '\\') { + i++; + } else if (str[i] === b[0]) { + level++; + } else if (str[i] === b[1]) { + level--; + if (level < 0) { + return i; + } + } + } + return -1; +} + +function checkSanitizeDeprecation(opt) { + if (opt && opt.sanitize && !opt.silent) { + console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options'); + } +} + +// copied from https://stackoverflow.com/a/5450113/806777 +/** + * @param {string} pattern + * @param {number} count + */ +function repeatString(pattern, count) { + if (count < 1) { + return ''; + } + let result = ''; + while (count > 1) { + if (count & 1) { + result += pattern; + } + count >>= 1; + pattern += pattern; + } + return result + pattern; +} + +function outputLink(cap, link, raw, lexer) { + const href = link.href; + const title = link.title ? escape(link.title) : null; + const text = cap[1].replace(/\\([\[\]])/g, '$1'); + + if (cap[0].charAt(0) !== '!') { + lexer.state.inLink = true; + const token = { + type: 'link', + raw, + href, + title, + text, + tokens: lexer.inlineTokens(text, []) + }; + lexer.state.inLink = false; + return token; + } + return { + type: 'image', + raw, + href, + title, + text: escape(text) + }; +} + +function indentCodeCompensation(raw, text) { + const matchIndentToCode = raw.match(/^(\s+)(?:```)/); + + if (matchIndentToCode === null) { + return text; + } + + const indentToCode = matchIndentToCode[1]; + + return text + .split('\n') + .map(node => { + const matchIndentInNode = node.match(/^\s+/); + if (matchIndentInNode === null) { + return node; + } + + const [indentInNode] = matchIndentInNode; + + if (indentInNode.length >= indentToCode.length) { + return node.slice(indentToCode.length); + } + + return node; + }) + .join('\n'); +} + +/** + * Tokenizer + */ +class Tokenizer { + constructor(options) { + this.options = options || defaults; + } + + space(src) { + const cap = this.rules.block.newline.exec(src); + if (cap && cap[0].length > 0) { + return { + type: 'space', + raw: cap[0] + }; + } + } + + code(src) { + const cap = this.rules.block.code.exec(src); + if (cap) { + const text = cap[0].replace(/^ {1,4}/gm, ''); + return { + type: 'code', + raw: cap[0], + codeBlockStyle: 'indented', + text: !this.options.pedantic + ? rtrim(text, '\n') + : text + }; + } + } + + fences(src) { + const cap = this.rules.block.fences.exec(src); + if (cap) { + const raw = cap[0]; + const text = indentCodeCompensation(raw, cap[3] || ''); + + return { + type: 'code', + raw, + lang: cap[2] ? cap[2].trim() : cap[2], + text + }; + } + } + + heading(src) { + const cap = this.rules.block.heading.exec(src); + if (cap) { + let text = cap[2].trim(); + + // remove trailing #s + if (/#$/.test(text)) { + const trimmed = rtrim(text, '#'); + if (this.options.pedantic) { + text = trimmed.trim(); + } else if (!trimmed || / $/.test(trimmed)) { + // CommonMark requires space before trailing #s + text = trimmed.trim(); + } + } + + const token = { + type: 'heading', + raw: cap[0], + depth: cap[1].length, + text, + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + } + + hr(src) { + const cap = this.rules.block.hr.exec(src); + if (cap) { + return { + type: 'hr', + raw: cap[0] + }; + } + } + + blockquote(src) { + const cap = this.rules.block.blockquote.exec(src); + if (cap) { + const text = cap[0].replace(/^ *>[ \t]?/gm, ''); + + return { + type: 'blockquote', + raw: cap[0], + tokens: this.lexer.blockTokens(text, []), + text + }; + } + } + + list(src) { + let cap = this.rules.block.list.exec(src); + if (cap) { + let raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, + line, nextLine, rawLine, itemContents, endEarly; + + let bull = cap[1].trim(); + const isordered = bull.length > 1; + + const list = { + type: 'list', + raw: '', + ordered: isordered, + start: isordered ? +bull.slice(0, -1) : '', + loose: false, + items: [] + }; + + bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`; + + if (this.options.pedantic) { + bull = isordered ? bull : '[*+-]'; + } + + // Get next list item + const itemRegex = new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`); + + // Check if current bullet point can start a new List Item + while (src) { + endEarly = false; + if (!(cap = itemRegex.exec(src))) { + break; + } + + if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?) + break; + } + + raw = cap[0]; + src = src.substring(raw.length); + + line = cap[2].split('\n', 1)[0]; + nextLine = src.split('\n', 1)[0]; + + if (this.options.pedantic) { + indent = 2; + itemContents = line.trimLeft(); + } else { + indent = cap[2].search(/[^ ]/); // Find first non-space char + indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent + itemContents = line.slice(indent); + indent += cap[1].length; + } + + blankLine = false; + + if (!line && /^ *$/.test(nextLine)) { // Items begin with at most one blank line + raw += nextLine + '\n'; + src = src.substring(nextLine.length + 1); + endEarly = true; + } + + if (!endEarly) { + const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?: [^\\n]*)?(?:\\n|$))`); + const hrRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`); + const fencesBeginRegex = new RegExp(`^( {0,${Math.min(3, indent - 1)}})(\`\`\`|~~~)`); + + // Check if following lines should be included in List Item + while (src) { + rawLine = src.split('\n', 1)[0]; + line = rawLine; + + // Re-align to follow commonmark nesting rules + if (this.options.pedantic) { + line = line.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' '); + } + + // End list item if found code fences + if (fencesBeginRegex.test(line)) { + break; + } + + // End list item if found start of new heading + if (this.rules.block.heading.test(line)) { + break; + } + + // End list item if found start of new bullet + if (nextBulletRegex.test(line)) { + break; + } + + // Horizontal rule found + if (hrRegex.test(src)) { + break; + } + + if (line.search(/[^ ]/) >= indent || !line.trim()) { // Dedent if possible + itemContents += '\n' + line.slice(indent); + } else if (!blankLine) { // Until blank line, item doesn't need indentation + itemContents += '\n' + line; + } else { // Otherwise, improper indentation ends this item + break; + } + + if (!blankLine && !line.trim()) { // Check if current line is blank + blankLine = true; + } + + raw += rawLine + '\n'; + src = src.substring(rawLine.length + 1); + } + } + + if (!list.loose) { + // If the previous item ended with a blank line, the list is loose + if (endsWithBlankLine) { + list.loose = true; + } else if (/\n *\n *$/.test(raw)) { + endsWithBlankLine = true; + } + } + + // Check for task list items + if (this.options.gfm) { + istask = /^\[[ xX]\] /.exec(itemContents); + if (istask) { + ischecked = istask[0] !== '[ ] '; + itemContents = itemContents.replace(/^\[[ xX]\] +/, ''); + } + } + + list.items.push({ + type: 'list_item', + raw, + task: !!istask, + checked: ischecked, + loose: false, + text: itemContents + }); + + list.raw += raw; + } + + // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic + list.items[list.items.length - 1].raw = raw.trimRight(); + list.items[list.items.length - 1].text = itemContents.trimRight(); + list.raw = list.raw.trimRight(); + + const l = list.items.length; + + // Item child tokens handled here at end because we needed to have the final item to trim it first + for (i = 0; i < l; i++) { + this.lexer.state.top = false; + list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []); + const spacers = list.items[i].tokens.filter(t => t.type === 'space'); + const hasMultipleLineBreaks = spacers.every(t => { + const chars = t.raw.split(''); + let lineBreaks = 0; + for (const char of chars) { + if (char === '\n') { + lineBreaks += 1; + } + if (lineBreaks > 1) { + return true; + } + } + + return false; + }); + + if (!list.loose && spacers.length && hasMultipleLineBreaks) { + // Having a single line break doesn't mean a list is loose. A single line break is terminating the last list item + list.loose = true; + list.items[i].loose = true; + } + } + + return list; + } + } + + html(src) { + const cap = this.rules.block.html.exec(src); + if (cap) { + const token = { + type: 'html', + raw: cap[0], + pre: !this.options.sanitizer + && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'), + text: cap[0] + }; + if (this.options.sanitize) { + token.type = 'paragraph'; + token.text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]); + token.tokens = []; + this.lexer.inline(token.text, token.tokens); + } + return token; + } + } + + def(src) { + const cap = this.rules.block.def.exec(src); + if (cap) { + if (cap[3]) cap[3] = cap[3].substring(1, cap[3].length - 1); + const tag = cap[1].toLowerCase().replace(/\s+/g, ' '); + return { + type: 'def', + tag, + raw: cap[0], + href: cap[2], + title: cap[3] + }; + } + } + + table(src) { + const cap = this.rules.block.table.exec(src); + if (cap) { + const item = { + type: 'table', + header: splitCells(cap[1]).map(c => { return { text: c }; }), + align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), + rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : [] + }; + + if (item.header.length === item.align.length) { + item.raw = cap[0]; + + let l = item.align.length; + let i, j, k, row; + for (i = 0; i < l; i++) { + if (/^ *-+: *$/.test(item.align[i])) { + item.align[i] = 'right'; + } else if (/^ *:-+: *$/.test(item.align[i])) { + item.align[i] = 'center'; + } else if (/^ *:-+ *$/.test(item.align[i])) { + item.align[i] = 'left'; + } else { + item.align[i] = null; + } + } + + l = item.rows.length; + for (i = 0; i < l; i++) { + item.rows[i] = splitCells(item.rows[i], item.header.length).map(c => { return { text: c }; }); + } + + // parse child tokens inside headers and cells + + // header child tokens + l = item.header.length; + for (j = 0; j < l; j++) { + item.header[j].tokens = []; + this.lexer.inline(item.header[j].text, item.header[j].tokens); + } + + // cell child tokens + l = item.rows.length; + for (j = 0; j < l; j++) { + row = item.rows[j]; + for (k = 0; k < row.length; k++) { + row[k].tokens = []; + this.lexer.inline(row[k].text, row[k].tokens); + } + } + + return item; + } + } + } + + lheading(src) { + const cap = this.rules.block.lheading.exec(src); + if (cap) { + const token = { + type: 'heading', + raw: cap[0], + depth: cap[2].charAt(0) === '=' ? 1 : 2, + text: cap[1], + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + } + + paragraph(src) { + const cap = this.rules.block.paragraph.exec(src); + if (cap) { + const token = { + type: 'paragraph', + raw: cap[0], + text: cap[1].charAt(cap[1].length - 1) === '\n' + ? cap[1].slice(0, -1) + : cap[1], + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + } + + text(src) { + const cap = this.rules.block.text.exec(src); + if (cap) { + const token = { + type: 'text', + raw: cap[0], + text: cap[0], + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + } + + escape(src) { + const cap = this.rules.inline.escape.exec(src); + if (cap) { + return { + type: 'escape', + raw: cap[0], + text: escape(cap[1]) + }; + } + } + + tag(src) { + const cap = this.rules.inline.tag.exec(src); + if (cap) { + if (!this.lexer.state.inLink && /^
    /i.test(cap[0])) { + this.lexer.state.inLink = false; + } + if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { + this.lexer.state.inRawBlock = true; + } else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { + this.lexer.state.inRawBlock = false; + } + + return { + type: this.options.sanitize + ? 'text' + : 'html', + raw: cap[0], + inLink: this.lexer.state.inLink, + inRawBlock: this.lexer.state.inRawBlock, + text: this.options.sanitize + ? (this.options.sanitizer + ? this.options.sanitizer(cap[0]) + : escape(cap[0])) + : cap[0] + }; + } + } + + link(src) { + const cap = this.rules.inline.link.exec(src); + if (cap) { + const trimmedUrl = cap[2].trim(); + if (!this.options.pedantic && /^$/.test(trimmedUrl))) { + return; + } + + // ending angle bracket cannot be escaped + const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\'); + if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) { + return; + } + } else { + // find closing parenthesis + const lastParenIndex = findClosingBracket(cap[2], '()'); + if (lastParenIndex > -1) { + const start = cap[0].indexOf('!') === 0 ? 5 : 4; + const linkLen = start + cap[1].length + lastParenIndex; + cap[2] = cap[2].substring(0, lastParenIndex); + cap[0] = cap[0].substring(0, linkLen).trim(); + cap[3] = ''; + } + } + let href = cap[2]; + let title = ''; + if (this.options.pedantic) { + // split pedantic href and title + const link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href); + + if (link) { + href = link[1]; + title = link[3]; + } + } else { + title = cap[3] ? cap[3].slice(1, -1) : ''; + } + + href = href.trim(); + if (/^$/.test(trimmedUrl))) { + // pedantic allows starting angle bracket without ending angle bracket + href = href.slice(1); + } else { + href = href.slice(1, -1); + } + } + return outputLink(cap, { + href: href ? href.replace(this.rules.inline._escapes, '$1') : href, + title: title ? title.replace(this.rules.inline._escapes, '$1') : title + }, cap[0], this.lexer); + } + } + + reflink(src, links) { + let cap; + if ((cap = this.rules.inline.reflink.exec(src)) + || (cap = this.rules.inline.nolink.exec(src))) { + let link = (cap[2] || cap[1]).replace(/\s+/g, ' '); + link = links[link.toLowerCase()]; + if (!link || !link.href) { + const text = cap[0].charAt(0); + return { + type: 'text', + raw: text, + text + }; + } + return outputLink(cap, link, cap[0], this.lexer); + } + } + + emStrong(src, maskedSrc, prevChar = '') { + let match = this.rules.inline.emStrong.lDelim.exec(src); + if (!match) return; + + // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well + if (match[3] && prevChar.match(/[\p{L}\p{N}]/u)) return; + + const nextChar = match[1] || match[2] || ''; + + if (!nextChar || (nextChar && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar)))) { + const lLength = match[0].length - 1; + let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0; + + const endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd; + endReg.lastIndex = 0; + + // Clip maskedSrc to same section of string as src (move to lexer?) + maskedSrc = maskedSrc.slice(-1 * src.length + lLength); + + while ((match = endReg.exec(maskedSrc)) != null) { + rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6]; + + if (!rDelim) continue; // skip single * in __abc*abc__ + + rLength = rDelim.length; + + if (match[3] || match[4]) { // found another Left Delim + delimTotal += rLength; + continue; + } else if (match[5] || match[6]) { // either Left or Right Delim + if (lLength % 3 && !((lLength + rLength) % 3)) { + midDelimTotal += rLength; + continue; // CommonMark Emphasis Rules 9-10 + } + } + + delimTotal -= rLength; + + if (delimTotal > 0) continue; // Haven't found enough closing delimiters + + // Remove extra characters. *a*** -> *a* + rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal); + + // Create `em` if smallest delimiter has odd char count. *a*** + if (Math.min(lLength, rLength) % 2) { + const text = src.slice(1, lLength + match.index + rLength); + return { + type: 'em', + raw: src.slice(0, lLength + match.index + rLength + 1), + text, + tokens: this.lexer.inlineTokens(text, []) + }; + } + + // Create 'strong' if smallest delimiter has even char count. **a*** + const text = src.slice(2, lLength + match.index + rLength - 1); + return { + type: 'strong', + raw: src.slice(0, lLength + match.index + rLength + 1), + text, + tokens: this.lexer.inlineTokens(text, []) + }; + } + } + } + + codespan(src) { + const cap = this.rules.inline.code.exec(src); + if (cap) { + let text = cap[2].replace(/\n/g, ' '); + const hasNonSpaceChars = /[^ ]/.test(text); + const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text); + if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) { + text = text.substring(1, text.length - 1); + } + text = escape(text, true); + return { + type: 'codespan', + raw: cap[0], + text + }; + } + } + + br(src) { + const cap = this.rules.inline.br.exec(src); + if (cap) { + return { + type: 'br', + raw: cap[0] + }; + } + } + + del(src) { + const cap = this.rules.inline.del.exec(src); + if (cap) { + return { + type: 'del', + raw: cap[0], + text: cap[2], + tokens: this.lexer.inlineTokens(cap[2], []) + }; + } + } + + autolink(src, mangle) { + const cap = this.rules.inline.autolink.exec(src); + if (cap) { + let text, href; + if (cap[2] === '@') { + text = escape(this.options.mangle ? mangle(cap[1]) : cap[1]); + href = 'mailto:' + text; + } else { + text = escape(cap[1]); + href = text; + } + + return { + type: 'link', + raw: cap[0], + text, + href, + tokens: [ + { + type: 'text', + raw: text, + text + } + ] + }; + } + } + + url(src, mangle) { + let cap; + if (cap = this.rules.inline.url.exec(src)) { + let text, href; + if (cap[2] === '@') { + text = escape(this.options.mangle ? mangle(cap[0]) : cap[0]); + href = 'mailto:' + text; + } else { + // do extended autolink path validation + let prevCapZero; + do { + prevCapZero = cap[0]; + cap[0] = this.rules.inline._backpedal.exec(cap[0])[0]; + } while (prevCapZero !== cap[0]); + text = escape(cap[0]); + if (cap[1] === 'www.') { + href = 'http://' + text; + } else { + href = text; + } + } + return { + type: 'link', + raw: cap[0], + text, + href, + tokens: [ + { + type: 'text', + raw: text, + text + } + ] + }; + } + } + + inlineText(src, smartypants) { + const cap = this.rules.inline.text.exec(src); + if (cap) { + let text; + if (this.lexer.state.inRawBlock) { + text = this.options.sanitize ? (this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0])) : cap[0]; + } else { + text = escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]); + } + return { + type: 'text', + raw: cap[0], + text + }; + } + } +} + +/** + * Block-Level Grammar + */ +const block = { + newline: /^(?: *(?:\n|$))+/, + code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/, + fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/, + hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/, + heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/, + blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/, + list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/, + html: '^ {0,3}(?:' // optional indentation + + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)' // (1) + + '|comment[^\\n]*(\\n+|$)' // (2) + + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3) + + '|\\n*|$)' // (4) + + '|\\n*|$)' // (5) + + '|)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6) + + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag + + '|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag + + ')', + def: /^ {0,3}\[(label)\]: *(?:\n *)?]+)>?(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/, + table: noopTest, + lheading: /^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/, + // regex template, placeholders will be replaced according to different paragraph + // interruption rules of commonmark and the original markdown spec: + _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/, + text: /^[^\n]+/ +}; + +block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/; +block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/; +block.def = edit(block.def) + .replace('label', block._label) + .replace('title', block._title) + .getRegex(); + +block.bullet = /(?:[*+-]|\d{1,9}[.)])/; +block.listItemStart = edit(/^( *)(bull) */) + .replace('bull', block.bullet) + .getRegex(); + +block.list = edit(block.list) + .replace(/bull/g, block.bullet) + .replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))') + .replace('def', '\\n+(?=' + block.def.source + ')') + .getRegex(); + +block._tag = 'address|article|aside|base|basefont|blockquote|body|caption' + + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption' + + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe' + + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option' + + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr' + + '|track|ul'; +block._comment = /|$)/; +block.html = edit(block.html, 'i') + .replace('comment', block._comment) + .replace('tag', block._tag) + .replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/) + .getRegex(); + +block.paragraph = edit(block._paragraph) + .replace('hr', block.hr) + .replace('heading', ' {0,3}#{1,6} ') + .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs + .replace('|table', '') + .replace('blockquote', ' {0,3}>') + .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n') + .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt + .replace('html', ')|<(?:script|pre|style|textarea|!--)') + .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks + .getRegex(); + +block.blockquote = edit(block.blockquote) + .replace('paragraph', block.paragraph) + .getRegex(); + +/** + * Normal Block Grammar + */ + +block.normal = merge({}, block); + +/** + * GFM Block Grammar + */ + +block.gfm = merge({}, block.normal, { + table: '^ *([^\\n ].*\\|.*)\\n' // Header + + ' {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?' // Align + + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells +}); + +block.gfm.table = edit(block.gfm.table) + .replace('hr', block.hr) + .replace('heading', ' {0,3}#{1,6} ') + .replace('blockquote', ' {0,3}>') + .replace('code', ' {4}[^\\n]') + .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n') + .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt + .replace('html', ')|<(?:script|pre|style|textarea|!--)') + .replace('tag', block._tag) // tables can be interrupted by type (6) html blocks + .getRegex(); + +block.gfm.paragraph = edit(block._paragraph) + .replace('hr', block.hr) + .replace('heading', ' {0,3}#{1,6} ') + .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs + .replace('table', block.gfm.table) // interrupt paragraphs with table + .replace('blockquote', ' {0,3}>') + .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n') + .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt + .replace('html', ')|<(?:script|pre|style|textarea|!--)') + .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks + .getRegex(); +/** + * Pedantic grammar (original John Gruber's loose markdown specification) + */ + +block.pedantic = merge({}, block.normal, { + html: edit( + '^ *(?:comment *(?:\\n|\\s*$)' + + '|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)' // closed tag + + '|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))') + .replace('comment', block._comment) + .replace(/tag/g, '(?!(?:' + + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub' + + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)' + + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b') + .getRegex(), + def: /^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, + heading: /^(#{1,6})(.*)(?:\n+|$)/, + fences: noopTest, // fences not supported + paragraph: edit(block.normal._paragraph) + .replace('hr', block.hr) + .replace('heading', ' *#{1,6} *[^\n]') + .replace('lheading', block.lheading) + .replace('blockquote', ' {0,3}>') + .replace('|fences', '') + .replace('|list', '') + .replace('|html', '') + .getRegex() +}); + +/** + * Inline-Level Grammar + */ +const inline = { + escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, + autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/, + url: noopTest, + tag: '^comment' + + '|^' // self-closing tag + + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag + + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. + + '|^' // declaration, e.g. + + '|^', // CDATA section + link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/, + reflink: /^!?\[(label)\]\[(ref)\]/, + nolink: /^!?\[(ref)\](?:\[\])?/, + reflinkSearch: 'reflink|nolink(?!\\()', + emStrong: { + lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/, + // (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right. + // () Skip orphan inside strong () Consume to delim (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a + rDelimAst: /^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[^*]+(?=[^*])|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/, + rDelimUnd: /^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _ + }, + code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, + br: /^( {2,}|\\)\n(?!\s*$)/, + del: noopTest, + text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\?@\\[\\]`^{|}~'; +inline.punctuation = edit(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex(); + +// sequences em should skip over [title](link), `code`, +inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g; +inline.escapedEmSt = /\\\*|\\_/g; + +inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex(); + +inline.emStrong.lDelim = edit(inline.emStrong.lDelim) + .replace(/punct/g, inline._punctuation) + .getRegex(); + +inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'g') + .replace(/punct/g, inline._punctuation) + .getRegex(); + +inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'g') + .replace(/punct/g, inline._punctuation) + .getRegex(); + +inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g; + +inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/; +inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/; +inline.autolink = edit(inline.autolink) + .replace('scheme', inline._scheme) + .replace('email', inline._email) + .getRegex(); + +inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/; + +inline.tag = edit(inline.tag) + .replace('comment', inline._comment) + .replace('attribute', inline._attribute) + .getRegex(); + +inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/; +inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/; +inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/; + +inline.link = edit(inline.link) + .replace('label', inline._label) + .replace('href', inline._href) + .replace('title', inline._title) + .getRegex(); + +inline.reflink = edit(inline.reflink) + .replace('label', inline._label) + .replace('ref', block._label) + .getRegex(); + +inline.nolink = edit(inline.nolink) + .replace('ref', block._label) + .getRegex(); + +inline.reflinkSearch = edit(inline.reflinkSearch, 'g') + .replace('reflink', inline.reflink) + .replace('nolink', inline.nolink) + .getRegex(); + +/** + * Normal Inline Grammar + */ + +inline.normal = merge({}, inline); + +/** + * Pedantic Inline Grammar + */ + +inline.pedantic = merge({}, inline.normal, { + strong: { + start: /^__|\*\*/, + middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, + endAst: /\*\*(?!\*)/g, + endUnd: /__(?!_)/g + }, + em: { + start: /^_|\*/, + middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/, + endAst: /\*(?!\*)/g, + endUnd: /_(?!_)/g + }, + link: edit(/^!?\[(label)\]\((.*?)\)/) + .replace('label', inline._label) + .getRegex(), + reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/) + .replace('label', inline._label) + .getRegex() +}); + +/** + * GFM Inline Grammar + */ + +inline.gfm = merge({}, inline.normal, { + escape: edit(inline.escape).replace('])', '~|])').getRegex(), + _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/, + url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, + _backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/, + del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/, + text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\ 0.5) { + ch = 'x' + ch.toString(16); + } + out += '&#' + ch + ';'; + } + + return out; +} + +/** + * Block Lexer + */ +class Lexer { + constructor(options) { + this.tokens = []; + this.tokens.links = Object.create(null); + this.options = options || defaults; + this.options.tokenizer = this.options.tokenizer || new Tokenizer(); + this.tokenizer = this.options.tokenizer; + this.tokenizer.options = this.options; + this.tokenizer.lexer = this; + this.inlineQueue = []; + this.state = { + inLink: false, + inRawBlock: false, + top: true + }; + + const rules = { + block: block.normal, + inline: inline.normal + }; + + if (this.options.pedantic) { + rules.block = block.pedantic; + rules.inline = inline.pedantic; + } else if (this.options.gfm) { + rules.block = block.gfm; + if (this.options.breaks) { + rules.inline = inline.breaks; + } else { + rules.inline = inline.gfm; + } + } + this.tokenizer.rules = rules; + } + + /** + * Expose Rules + */ + static get rules() { + return { + block, + inline + }; + } + + /** + * Static Lex Method + */ + static lex(src, options) { + const lexer = new Lexer(options); + return lexer.lex(src); + } + + /** + * Static Lex Inline Method + */ + static lexInline(src, options) { + const lexer = new Lexer(options); + return lexer.inlineTokens(src); + } + + /** + * Preprocessing + */ + lex(src) { + src = src + .replace(/\r\n|\r/g, '\n'); + + this.blockTokens(src, this.tokens); + + let next; + while (next = this.inlineQueue.shift()) { + this.inlineTokens(next.src, next.tokens); + } + + return this.tokens; + } + + /** + * Lexing + */ + blockTokens(src, tokens = []) { + if (this.options.pedantic) { + src = src.replace(/\t/g, ' ').replace(/^ +$/gm, ''); + } else { + src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => { + return leading + ' '.repeat(tabs.length); + }); + } + + let token, lastToken, cutSrc, lastParagraphClipped; + + while (src) { + if (this.options.extensions + && this.options.extensions.block + && this.options.extensions.block.some((extTokenizer) => { + if (token = extTokenizer.call({ lexer: this }, src, tokens)) { + src = src.substring(token.raw.length); + tokens.push(token); + return true; + } + return false; + })) { + continue; + } + + // newline + if (token = this.tokenizer.space(src)) { + src = src.substring(token.raw.length); + if (token.raw.length === 1 && tokens.length > 0) { + // if there's a single \n as a spacer, it's terminating the last line, + // so move it there so that we don't get unecessary paragraph tags + tokens[tokens.length - 1].raw += '\n'; + } else { + tokens.push(token); + } + continue; + } + + // code + if (token = this.tokenizer.code(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + // An indented code block cannot interrupt a paragraph. + if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.text; + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else { + tokens.push(token); + } + continue; + } + + // fences + if (token = this.tokenizer.fences(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // heading + if (token = this.tokenizer.heading(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // hr + if (token = this.tokenizer.hr(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // blockquote + if (token = this.tokenizer.blockquote(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // list + if (token = this.tokenizer.list(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // html + if (token = this.tokenizer.html(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // def + if (token = this.tokenizer.def(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.raw; + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else if (!this.tokens.links[token.tag]) { + this.tokens.links[token.tag] = { + href: token.href, + title: token.title + }; + } + continue; + } + + // table (gfm) + if (token = this.tokenizer.table(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // lheading + if (token = this.tokenizer.lheading(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // top-level paragraph + // prevent paragraph consuming extensions by clipping 'src' to extension start + cutSrc = src; + if (this.options.extensions && this.options.extensions.startBlock) { + let startIndex = Infinity; + const tempSrc = src.slice(1); + let tempStart; + this.options.extensions.startBlock.forEach(function(getStartIndex) { + tempStart = getStartIndex.call({ lexer: this }, tempSrc); + if (typeof tempStart === 'number' && tempStart >= 0) { startIndex = Math.min(startIndex, tempStart); } + }); + if (startIndex < Infinity && startIndex >= 0) { + cutSrc = src.substring(0, startIndex + 1); + } + } + if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) { + lastToken = tokens[tokens.length - 1]; + if (lastParagraphClipped && lastToken.type === 'paragraph') { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.text; + this.inlineQueue.pop(); + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else { + tokens.push(token); + } + lastParagraphClipped = (cutSrc.length !== src.length); + src = src.substring(token.raw.length); + continue; + } + + // text + if (token = this.tokenizer.text(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + if (lastToken && lastToken.type === 'text') { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.text; + this.inlineQueue.pop(); + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else { + tokens.push(token); + } + continue; + } + + if (src) { + const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0); + if (this.options.silent) { + console.error(errMsg); + break; + } else { + throw new Error(errMsg); + } + } + } + + this.state.top = true; + return tokens; + } + + inline(src, tokens) { + this.inlineQueue.push({ src, tokens }); + } + + /** + * Lexing/Compiling + */ + inlineTokens(src, tokens = []) { + let token, lastToken, cutSrc; + + // String with links masked to avoid interference with em and strong + let maskedSrc = src; + let match; + let keepPrevChar, prevChar; + + // Mask out reflinks + if (this.tokens.links) { + const links = Object.keys(this.tokens.links); + if (links.length > 0) { + while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) { + if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) { + maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex); + } + } + } + } + // Mask out other blocks + while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) { + maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex); + } + + // Mask out escaped em & strong delimiters + while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) { + maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex); + } + + while (src) { + if (!keepPrevChar) { + prevChar = ''; + } + keepPrevChar = false; + + // extensions + if (this.options.extensions + && this.options.extensions.inline + && this.options.extensions.inline.some((extTokenizer) => { + if (token = extTokenizer.call({ lexer: this }, src, tokens)) { + src = src.substring(token.raw.length); + tokens.push(token); + return true; + } + return false; + })) { + continue; + } + + // escape + if (token = this.tokenizer.escape(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // tag + if (token = this.tokenizer.tag(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + if (lastToken && token.type === 'text' && lastToken.type === 'text') { + lastToken.raw += token.raw; + lastToken.text += token.text; + } else { + tokens.push(token); + } + continue; + } + + // link + if (token = this.tokenizer.link(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // reflink, nolink + if (token = this.tokenizer.reflink(src, this.tokens.links)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + if (lastToken && token.type === 'text' && lastToken.type === 'text') { + lastToken.raw += token.raw; + lastToken.text += token.text; + } else { + tokens.push(token); + } + continue; + } + + // em & strong + if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // code + if (token = this.tokenizer.codespan(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // br + if (token = this.tokenizer.br(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // del (gfm) + if (token = this.tokenizer.del(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // autolink + if (token = this.tokenizer.autolink(src, mangle)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // url (gfm) + if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // text + // prevent inlineText consuming extensions by clipping 'src' to extension start + cutSrc = src; + if (this.options.extensions && this.options.extensions.startInline) { + let startIndex = Infinity; + const tempSrc = src.slice(1); + let tempStart; + this.options.extensions.startInline.forEach(function(getStartIndex) { + tempStart = getStartIndex.call({ lexer: this }, tempSrc); + if (typeof tempStart === 'number' && tempStart >= 0) { startIndex = Math.min(startIndex, tempStart); } + }); + if (startIndex < Infinity && startIndex >= 0) { + cutSrc = src.substring(0, startIndex + 1); + } + } + if (token = this.tokenizer.inlineText(cutSrc, smartypants)) { + src = src.substring(token.raw.length); + if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started + prevChar = token.raw.slice(-1); + } + keepPrevChar = true; + lastToken = tokens[tokens.length - 1]; + if (lastToken && lastToken.type === 'text') { + lastToken.raw += token.raw; + lastToken.text += token.text; + } else { + tokens.push(token); + } + continue; + } + + if (src) { + const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0); + if (this.options.silent) { + console.error(errMsg); + break; + } else { + throw new Error(errMsg); + } + } + } + + return tokens; + } +} + +/** + * Renderer + */ +class Renderer { + constructor(options) { + this.options = options || defaults; + } + + code(code, infostring, escaped) { + const lang = (infostring || '').match(/\S*/)[0]; + if (this.options.highlight) { + const out = this.options.highlight(code, lang); + if (out != null && out !== code) { + escaped = true; + code = out; + } + } + + code = code.replace(/\n$/, '') + '\n'; + + if (!lang) { + return '
    '
    +        + (escaped ? code : escape(code, true))
    +        + '
    \n'; + } + + return '
    '
    +      + (escaped ? code : escape(code, true))
    +      + '
    \n'; + } + + /** + * @param {string} quote + */ + blockquote(quote) { + return `
    \n${quote}
    \n`; + } + + html(html) { + return html; + } + + /** + * @param {string} text + * @param {string} level + * @param {string} raw + * @param {any} slugger + */ + heading(text, level, raw, slugger) { + if (this.options.headerIds) { + const id = this.options.headerPrefix + slugger.slug(raw); + return `${text}\n`; + } + + // ignore IDs + return `${text}\n`; + } + + hr() { + return this.options.xhtml ? '
    \n' : '
    \n'; + } + + list(body, ordered, start) { + const type = ordered ? 'ol' : 'ul', + startatt = (ordered && start !== 1) ? (' start="' + start + '"') : ''; + return '<' + type + startatt + '>\n' + body + '\n'; + } + + /** + * @param {string} text + */ + listitem(text) { + return `
  • ${text}
  • \n`; + } + + checkbox(checked) { + return ' '; + } + + /** + * @param {string} text + */ + paragraph(text) { + return `

    ${text}

    \n`; + } + + /** + * @param {string} header + * @param {string} body + */ + table(header, body) { + if (body) body = `${body}`; + + return '\n' + + '\n' + + header + + '\n' + + body + + '
    \n'; + } + + /** + * @param {string} content + */ + tablerow(content) { + return `\n${content}\n`; + } + + tablecell(content, flags) { + const type = flags.header ? 'th' : 'td'; + const tag = flags.align + ? `<${type} align="${flags.align}">` + : `<${type}>`; + return tag + content + `\n`; + } + + /** + * span level renderer + * @param {string} text + */ + strong(text) { + return `${text}`; + } + + /** + * @param {string} text + */ + em(text) { + return `${text}`; + } + + /** + * @param {string} text + */ + codespan(text) { + return `${text}`; + } + + br() { + return this.options.xhtml ? '
    ' : '
    '; + } + + /** + * @param {string} text + */ + del(text) { + return `${text}`; + } + + /** + * @param {string} href + * @param {string} title + * @param {string} text + */ + link(href, title, text) { + href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); + if (href === null) { + return text; + } + let out = '
    '; + return out; + } + + /** + * @param {string} href + * @param {string} title + * @param {string} text + */ + image(href, title, text) { + href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); + if (href === null) { + return text; + } + + let out = `${text}' : '>'; + return out; + } + + text(text) { + return text; + } +} + +/** + * TextRenderer + * returns only the textual part of the token + */ +class TextRenderer { + // no need for block level renderers + strong(text) { + return text; + } + + em(text) { + return text; + } + + codespan(text) { + return text; + } + + del(text) { + return text; + } + + html(text) { + return text; + } + + text(text) { + return text; + } + + link(href, title, text) { + return '' + text; + } + + image(href, title, text) { + return '' + text; + } + + br() { + return ''; + } +} + +/** + * Slugger generates header id + */ +class Slugger { + constructor() { + this.seen = {}; + } + + /** + * @param {string} value + */ + serialize(value) { + return value + .toLowerCase() + .trim() + // remove html tags + .replace(/<[!\/a-z].*?>/ig, '') + // remove unwanted chars + .replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '') + .replace(/\s/g, '-'); + } + + /** + * Finds the next safe (unique) slug to use + * @param {string} originalSlug + * @param {boolean} isDryRun + */ + getNextSafeSlug(originalSlug, isDryRun) { + let slug = originalSlug; + let occurenceAccumulator = 0; + if (this.seen.hasOwnProperty(slug)) { + occurenceAccumulator = this.seen[originalSlug]; + do { + occurenceAccumulator++; + slug = originalSlug + '-' + occurenceAccumulator; + } while (this.seen.hasOwnProperty(slug)); + } + if (!isDryRun) { + this.seen[originalSlug] = occurenceAccumulator; + this.seen[slug] = 0; + } + return slug; + } + + /** + * Convert string to unique id + * @param {object} [options] + * @param {boolean} [options.dryrun] Generates the next unique slug without + * updating the internal accumulator. + */ + slug(value, options = {}) { + const slug = this.serialize(value); + return this.getNextSafeSlug(slug, options.dryrun); + } +} + +/** + * Parsing & Compiling + */ +class Parser { + constructor(options) { + this.options = options || defaults; + this.options.renderer = this.options.renderer || new Renderer(); + this.renderer = this.options.renderer; + this.renderer.options = this.options; + this.textRenderer = new TextRenderer(); + this.slugger = new Slugger(); + } + + /** + * Static Parse Method + */ + static parse(tokens, options) { + const parser = new Parser(options); + return parser.parse(tokens); + } + + /** + * Static Parse Inline Method + */ + static parseInline(tokens, options) { + const parser = new Parser(options); + return parser.parseInline(tokens); + } + + /** + * Parse Loop + */ + parse(tokens, top = true) { + let out = '', + i, + j, + k, + l2, + l3, + row, + cell, + header, + body, + token, + ordered, + start, + loose, + itemBody, + item, + checked, + task, + checkbox, + ret; + + const l = tokens.length; + for (i = 0; i < l; i++) { + token = tokens[i]; + + // Run any renderer extensions + if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { + ret = this.options.extensions.renderers[token.type].call({ parser: this }, token); + if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) { + out += ret || ''; + continue; + } + } + + switch (token.type) { + case 'space': { + continue; + } + case 'hr': { + out += this.renderer.hr(); + continue; + } + case 'heading': { + out += this.renderer.heading( + this.parseInline(token.tokens), + token.depth, + unescape(this.parseInline(token.tokens, this.textRenderer)), + this.slugger); + continue; + } + case 'code': { + out += this.renderer.code(token.text, + token.lang, + token.escaped); + continue; + } + case 'table': { + header = ''; + + // header + cell = ''; + l2 = token.header.length; + for (j = 0; j < l2; j++) { + cell += this.renderer.tablecell( + this.parseInline(token.header[j].tokens), + { header: true, align: token.align[j] } + ); + } + header += this.renderer.tablerow(cell); + + body = ''; + l2 = token.rows.length; + for (j = 0; j < l2; j++) { + row = token.rows[j]; + + cell = ''; + l3 = row.length; + for (k = 0; k < l3; k++) { + cell += this.renderer.tablecell( + this.parseInline(row[k].tokens), + { header: false, align: token.align[k] } + ); + } + + body += this.renderer.tablerow(cell); + } + out += this.renderer.table(header, body); + continue; + } + case 'blockquote': { + body = this.parse(token.tokens); + out += this.renderer.blockquote(body); + continue; + } + case 'list': { + ordered = token.ordered; + start = token.start; + loose = token.loose; + l2 = token.items.length; + + body = ''; + for (j = 0; j < l2; j++) { + item = token.items[j]; + checked = item.checked; + task = item.task; + + itemBody = ''; + if (item.task) { + checkbox = this.renderer.checkbox(checked); + if (loose) { + if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') { + item.tokens[0].text = checkbox + ' ' + item.tokens[0].text; + if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') { + item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text; + } + } else { + item.tokens.unshift({ + type: 'text', + text: checkbox + }); + } + } else { + itemBody += checkbox; + } + } + + itemBody += this.parse(item.tokens, loose); + body += this.renderer.listitem(itemBody, task, checked); + } + + out += this.renderer.list(body, ordered, start); + continue; + } + case 'html': { + // TODO parse inline content if parameter markdown=1 + out += this.renderer.html(token.text); + continue; + } + case 'paragraph': { + out += this.renderer.paragraph(this.parseInline(token.tokens)); + continue; + } + case 'text': { + body = token.tokens ? this.parseInline(token.tokens) : token.text; + while (i + 1 < l && tokens[i + 1].type === 'text') { + token = tokens[++i]; + body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text); + } + out += top ? this.renderer.paragraph(body) : body; + continue; + } + + default: { + const errMsg = 'Token with "' + token.type + '" type was not found.'; + if (this.options.silent) { + console.error(errMsg); + return; + } else { + throw new Error(errMsg); + } + } + } + } + + return out; + } + + /** + * Parse Inline Tokens + */ + parseInline(tokens, renderer) { + renderer = renderer || this.renderer; + let out = '', + i, + token, + ret; + + const l = tokens.length; + for (i = 0; i < l; i++) { + token = tokens[i]; + + // Run any renderer extensions + if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { + ret = this.options.extensions.renderers[token.type].call({ parser: this }, token); + if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) { + out += ret || ''; + continue; + } + } + + switch (token.type) { + case 'escape': { + out += renderer.text(token.text); + break; + } + case 'html': { + out += renderer.html(token.text); + break; + } + case 'link': { + out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer)); + break; + } + case 'image': { + out += renderer.image(token.href, token.title, token.text); + break; + } + case 'strong': { + out += renderer.strong(this.parseInline(token.tokens, renderer)); + break; + } + case 'em': { + out += renderer.em(this.parseInline(token.tokens, renderer)); + break; + } + case 'codespan': { + out += renderer.codespan(token.text); + break; + } + case 'br': { + out += renderer.br(); + break; + } + case 'del': { + out += renderer.del(this.parseInline(token.tokens, renderer)); + break; + } + case 'text': { + out += renderer.text(token.text); + break; + } + default: { + const errMsg = 'Token with "' + token.type + '" type was not found.'; + if (this.options.silent) { + console.error(errMsg); + return; + } else { + throw new Error(errMsg); + } + } + } + } + return out; + } +} + +/** + * Marked + */ +function marked(src, opt, callback) { + // throw error in case of non string input + if (typeof src === 'undefined' || src === null) { + throw new Error('marked(): input parameter is undefined or null'); + } + if (typeof src !== 'string') { + throw new Error('marked(): input parameter is of type ' + + Object.prototype.toString.call(src) + ', string expected'); + } + + if (typeof opt === 'function') { + callback = opt; + opt = null; + } + + opt = merge({}, marked.defaults, opt || {}); + checkSanitizeDeprecation(opt); + + if (callback) { + const highlight = opt.highlight; + let tokens; + + try { + tokens = Lexer.lex(src, opt); + } catch (e) { + return callback(e); + } + + const done = function(err) { + let out; + + if (!err) { + try { + if (opt.walkTokens) { + marked.walkTokens(tokens, opt.walkTokens); + } + out = Parser.parse(tokens, opt); + } catch (e) { + err = e; + } + } + + opt.highlight = highlight; + + return err + ? callback(err) + : callback(null, out); + }; + + if (!highlight || highlight.length < 3) { + return done(); + } + + delete opt.highlight; + + if (!tokens.length) return done(); + + let pending = 0; + marked.walkTokens(tokens, function(token) { + if (token.type === 'code') { + pending++; + setTimeout(() => { + highlight(token.text, token.lang, function(err, code) { + if (err) { + return done(err); + } + if (code != null && code !== token.text) { + token.text = code; + token.escaped = true; + } + + pending--; + if (pending === 0) { + done(); + } + }); + }, 0); + } + }); + + if (pending === 0) { + done(); + } + + return; + } + + try { + const tokens = Lexer.lex(src, opt); + if (opt.walkTokens) { + marked.walkTokens(tokens, opt.walkTokens); + } + return Parser.parse(tokens, opt); + } catch (e) { + e.message += '\nPlease report this to https://github.com/markedjs/marked.'; + if (opt.silent) { + return '

    An error occurred:

    '
    +        + escape(e.message + '', true)
    +        + '
    '; + } + throw e; + } +} + +/** + * Options + */ + +marked.options = +marked.setOptions = function(opt) { + merge(marked.defaults, opt); + changeDefaults(marked.defaults); + return marked; +}; + +marked.getDefaults = getDefaults; + +marked.defaults = defaults; + +/** + * Use Extension + */ + +marked.use = function(...args) { + const opts = merge({}, ...args); + const extensions = marked.defaults.extensions || { renderers: {}, childTokens: {} }; + let hasExtensions; + + args.forEach((pack) => { + // ==-- Parse "addon" extensions --== // + if (pack.extensions) { + hasExtensions = true; + pack.extensions.forEach((ext) => { + if (!ext.name) { + throw new Error('extension name required'); + } + if (ext.renderer) { // Renderer extensions + const prevRenderer = extensions.renderers ? extensions.renderers[ext.name] : null; + if (prevRenderer) { + // Replace extension with func to run new extension but fall back if false + extensions.renderers[ext.name] = function(...args) { + let ret = ext.renderer.apply(this, args); + if (ret === false) { + ret = prevRenderer.apply(this, args); + } + return ret; + }; + } else { + extensions.renderers[ext.name] = ext.renderer; + } + } + if (ext.tokenizer) { // Tokenizer Extensions + if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) { + throw new Error("extension level must be 'block' or 'inline'"); + } + if (extensions[ext.level]) { + extensions[ext.level].unshift(ext.tokenizer); + } else { + extensions[ext.level] = [ext.tokenizer]; + } + if (ext.start) { // Function to check for start of token + if (ext.level === 'block') { + if (extensions.startBlock) { + extensions.startBlock.push(ext.start); + } else { + extensions.startBlock = [ext.start]; + } + } else if (ext.level === 'inline') { + if (extensions.startInline) { + extensions.startInline.push(ext.start); + } else { + extensions.startInline = [ext.start]; + } + } + } + } + if (ext.childTokens) { // Child tokens to be visited by walkTokens + extensions.childTokens[ext.name] = ext.childTokens; + } + }); + } + + // ==-- Parse "overwrite" extensions --== // + if (pack.renderer) { + const renderer = marked.defaults.renderer || new Renderer(); + for (const prop in pack.renderer) { + const prevRenderer = renderer[prop]; + // Replace renderer with func to run extension, but fall back if false + renderer[prop] = (...args) => { + let ret = pack.renderer[prop].apply(renderer, args); + if (ret === false) { + ret = prevRenderer.apply(renderer, args); + } + return ret; + }; + } + opts.renderer = renderer; + } + if (pack.tokenizer) { + const tokenizer = marked.defaults.tokenizer || new Tokenizer(); + for (const prop in pack.tokenizer) { + const prevTokenizer = tokenizer[prop]; + // Replace tokenizer with func to run extension, but fall back if false + tokenizer[prop] = (...args) => { + let ret = pack.tokenizer[prop].apply(tokenizer, args); + if (ret === false) { + ret = prevTokenizer.apply(tokenizer, args); + } + return ret; + }; + } + opts.tokenizer = tokenizer; + } + + // ==-- Parse WalkTokens extensions --== // + if (pack.walkTokens) { + const walkTokens = marked.defaults.walkTokens; + opts.walkTokens = function(token) { + pack.walkTokens.call(this, token); + if (walkTokens) { + walkTokens.call(this, token); + } + }; + } + + if (hasExtensions) { + opts.extensions = extensions; + } + + marked.setOptions(opts); + }); +}; + +/** + * Run callback for every token + */ + +marked.walkTokens = function(tokens, callback) { + for (const token of tokens) { + callback.call(marked, token); + switch (token.type) { + case 'table': { + for (const cell of token.header) { + marked.walkTokens(cell.tokens, callback); + } + for (const row of token.rows) { + for (const cell of row) { + marked.walkTokens(cell.tokens, callback); + } + } + break; + } + case 'list': { + marked.walkTokens(token.items, callback); + break; + } + default: { + if (marked.defaults.extensions && marked.defaults.extensions.childTokens && marked.defaults.extensions.childTokens[token.type]) { // Walk any extensions + marked.defaults.extensions.childTokens[token.type].forEach(function(childTokens) { + marked.walkTokens(token[childTokens], callback); + }); + } else if (token.tokens) { + marked.walkTokens(token.tokens, callback); + } + } + } + } +}; + +/** + * Parse Inline + * @param {string} src + */ +marked.parseInline = function(src, opt) { + // throw error in case of non string input + if (typeof src === 'undefined' || src === null) { + throw new Error('marked.parseInline(): input parameter is undefined or null'); + } + if (typeof src !== 'string') { + throw new Error('marked.parseInline(): input parameter is of type ' + + Object.prototype.toString.call(src) + ', string expected'); + } + + opt = merge({}, marked.defaults, opt || {}); + checkSanitizeDeprecation(opt); + + try { + const tokens = Lexer.lexInline(src, opt); + if (opt.walkTokens) { + marked.walkTokens(tokens, opt.walkTokens); + } + return Parser.parseInline(tokens, opt); + } catch (e) { + e.message += '\nPlease report this to https://github.com/markedjs/marked.'; + if (opt.silent) { + return '

    An error occurred:

    '
    +        + escape(e.message + '', true)
    +        + '
    '; + } + throw e; + } +}; + +/** + * Expose + */ +marked.Parser = Parser; +marked.parser = Parser.parse; +marked.Renderer = Renderer; +marked.TextRenderer = TextRenderer; +marked.Lexer = Lexer; +marked.lexer = Lexer.lex; +marked.Tokenizer = Tokenizer; +marked.Slugger = Slugger; +marked.parse = marked; + +const options = marked.options; +const setOptions = marked.setOptions; +const use = marked.use; +const walkTokens = marked.walkTokens; +const parseInline = marked.parseInline; +const parse = marked; +const parser = Parser.parse; +const lexer = Lexer.lex; + +export { Lexer, Parser, Renderer, Slugger, TextRenderer, Tokenizer, defaults, getDefaults, lexer, marked, options, parse, parseInline, parser, setOptions, use, walkTokens }; diff --git a/node_modules/marked/lib/marked.umd.js b/node_modules/marked/lib/marked.umd.js new file mode 100644 index 0000000..32fed9b --- /dev/null +++ b/node_modules/marked/lib/marked.umd.js @@ -0,0 +1,3056 @@ +/** + * marked - a markdown parser + * Copyright (c) 2011-2022, Christopher Jeffrey. (MIT Licensed) + * https://github.com/markedjs/marked + */ + +/** + * DO NOT EDIT THIS FILE + * The code in this file is generated from files in ./src/ + */ + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.marked = {})); +})(this, (function (exports) { 'use strict'; + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + Object.defineProperty(Constructor, "prototype", { + writable: false + }); + return Constructor; + } + + 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; + } + + function _createForOfIteratorHelperLoose(o, allowArrayLike) { + var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; + if (it) return (it = it.call(o)).next.bind(it); + + if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { + if (it) o = it; + var i = 0; + return function () { + if (i >= o.length) return { + done: true + }; + return { + done: false, + value: o[i++] + }; + }; + } + + throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + + function getDefaults() { + return { + baseUrl: null, + breaks: false, + extensions: null, + gfm: true, + headerIds: true, + headerPrefix: '', + highlight: null, + langPrefix: 'language-', + mangle: true, + pedantic: false, + renderer: null, + sanitize: false, + sanitizer: null, + silent: false, + smartLists: false, + smartypants: false, + tokenizer: null, + walkTokens: null, + xhtml: false + }; + } + exports.defaults = getDefaults(); + function changeDefaults(newDefaults) { + exports.defaults = newDefaults; + } + + /** + * Helpers + */ + var escapeTest = /[&<>"']/; + var escapeReplace = /[&<>"']/g; + var escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/; + var escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g; + var escapeReplacements = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + var getEscapeReplacement = function getEscapeReplacement(ch) { + return escapeReplacements[ch]; + }; + + function escape(html, encode) { + if (encode) { + if (escapeTest.test(html)) { + return html.replace(escapeReplace, getEscapeReplacement); + } + } else { + if (escapeTestNoEncode.test(html)) { + return html.replace(escapeReplaceNoEncode, getEscapeReplacement); + } + } + + return html; + } + var unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig; + /** + * @param {string} html + */ + + function unescape(html) { + // explicitly match decimal, hex, and named HTML entities + return html.replace(unescapeTest, function (_, n) { + n = n.toLowerCase(); + if (n === 'colon') return ':'; + + if (n.charAt(0) === '#') { + return n.charAt(1) === 'x' ? String.fromCharCode(parseInt(n.substring(2), 16)) : String.fromCharCode(+n.substring(1)); + } + + return ''; + }); + } + var caret = /(^|[^\[])\^/g; + /** + * @param {string | RegExp} regex + * @param {string} opt + */ + + function edit(regex, opt) { + regex = typeof regex === 'string' ? regex : regex.source; + opt = opt || ''; + var obj = { + replace: function replace(name, val) { + val = val.source || val; + val = val.replace(caret, '$1'); + regex = regex.replace(name, val); + return obj; + }, + getRegex: function getRegex() { + return new RegExp(regex, opt); + } + }; + return obj; + } + var nonWordAndColonTest = /[^\w:]/g; + var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i; + /** + * @param {boolean} sanitize + * @param {string} base + * @param {string} href + */ + + function cleanUrl(sanitize, base, href) { + if (sanitize) { + var prot; + + try { + prot = decodeURIComponent(unescape(href)).replace(nonWordAndColonTest, '').toLowerCase(); + } catch (e) { + return null; + } + + if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) { + return null; + } + } + + if (base && !originIndependentUrl.test(href)) { + href = resolveUrl(base, href); + } + + try { + href = encodeURI(href).replace(/%25/g, '%'); + } catch (e) { + return null; + } + + return href; + } + var baseUrls = {}; + var justDomain = /^[^:]+:\/*[^/]*$/; + var protocol = /^([^:]+:)[\s\S]*$/; + var domain = /^([^:]+:\/*[^/]*)[\s\S]*$/; + /** + * @param {string} base + * @param {string} href + */ + + function resolveUrl(base, href) { + if (!baseUrls[' ' + base]) { + // we can ignore everything in base after the last slash of its path component, + // but we might need to add _that_ + // https://tools.ietf.org/html/rfc3986#section-3 + if (justDomain.test(base)) { + baseUrls[' ' + base] = base + '/'; + } else { + baseUrls[' ' + base] = rtrim(base, '/', true); + } + } + + base = baseUrls[' ' + base]; + var relativeBase = base.indexOf(':') === -1; + + if (href.substring(0, 2) === '//') { + if (relativeBase) { + return href; + } + + return base.replace(protocol, '$1') + href; + } else if (href.charAt(0) === '/') { + if (relativeBase) { + return href; + } + + return base.replace(domain, '$1') + href; + } else { + return base + href; + } + } + var noopTest = { + exec: function noopTest() {} + }; + function merge(obj) { + var i = 1, + target, + key; + + for (; i < arguments.length; i++) { + target = arguments[i]; + + for (key in target) { + if (Object.prototype.hasOwnProperty.call(target, key)) { + obj[key] = target[key]; + } + } + } + + return obj; + } + function splitCells(tableRow, count) { + // ensure that every cell-delimiting pipe has a space + // before it to distinguish it from an escaped pipe + var row = tableRow.replace(/\|/g, function (match, offset, str) { + var escaped = false, + curr = offset; + + while (--curr >= 0 && str[curr] === '\\') { + escaped = !escaped; + } + + if (escaped) { + // odd number of slashes means | is escaped + // so we leave it alone + return '|'; + } else { + // add space before unescaped | + return ' |'; + } + }), + cells = row.split(/ \|/); + var i = 0; // First/last cell in a row cannot be empty if it has no leading/trailing pipe + + if (!cells[0].trim()) { + cells.shift(); + } + + if (cells.length > 0 && !cells[cells.length - 1].trim()) { + cells.pop(); + } + + if (cells.length > count) { + cells.splice(count); + } else { + while (cells.length < count) { + cells.push(''); + } + } + + for (; i < cells.length; i++) { + // leading or trailing whitespace is ignored per the gfm spec + cells[i] = cells[i].trim().replace(/\\\|/g, '|'); + } + + return cells; + } + /** + * Remove trailing 'c's. Equivalent to str.replace(/c*$/, ''). + * /c*$/ is vulnerable to REDOS. + * + * @param {string} str + * @param {string} c + * @param {boolean} invert Remove suffix of non-c chars instead. Default falsey. + */ + + function rtrim(str, c, invert) { + var l = str.length; + + if (l === 0) { + return ''; + } // Length of suffix matching the invert condition. + + + var suffLen = 0; // Step left until we fail to match the invert condition. + + while (suffLen < l) { + var currChar = str.charAt(l - suffLen - 1); + + if (currChar === c && !invert) { + suffLen++; + } else if (currChar !== c && invert) { + suffLen++; + } else { + break; + } + } + + return str.slice(0, l - suffLen); + } + function findClosingBracket(str, b) { + if (str.indexOf(b[1]) === -1) { + return -1; + } + + var l = str.length; + var level = 0, + i = 0; + + for (; i < l; i++) { + if (str[i] === '\\') { + i++; + } else if (str[i] === b[0]) { + level++; + } else if (str[i] === b[1]) { + level--; + + if (level < 0) { + return i; + } + } + } + + return -1; + } + function checkSanitizeDeprecation(opt) { + if (opt && opt.sanitize && !opt.silent) { + console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options'); + } + } // copied from https://stackoverflow.com/a/5450113/806777 + + /** + * @param {string} pattern + * @param {number} count + */ + + function repeatString(pattern, count) { + if (count < 1) { + return ''; + } + + var result = ''; + + while (count > 1) { + if (count & 1) { + result += pattern; + } + + count >>= 1; + pattern += pattern; + } + + return result + pattern; + } + + function outputLink(cap, link, raw, lexer) { + var href = link.href; + var title = link.title ? escape(link.title) : null; + var text = cap[1].replace(/\\([\[\]])/g, '$1'); + + if (cap[0].charAt(0) !== '!') { + lexer.state.inLink = true; + var token = { + type: 'link', + raw: raw, + href: href, + title: title, + text: text, + tokens: lexer.inlineTokens(text, []) + }; + lexer.state.inLink = false; + return token; + } + + return { + type: 'image', + raw: raw, + href: href, + title: title, + text: escape(text) + }; + } + + function indentCodeCompensation(raw, text) { + var matchIndentToCode = raw.match(/^(\s+)(?:```)/); + + if (matchIndentToCode === null) { + return text; + } + + var indentToCode = matchIndentToCode[1]; + return text.split('\n').map(function (node) { + var matchIndentInNode = node.match(/^\s+/); + + if (matchIndentInNode === null) { + return node; + } + + var indentInNode = matchIndentInNode[0]; + + if (indentInNode.length >= indentToCode.length) { + return node.slice(indentToCode.length); + } + + return node; + }).join('\n'); + } + /** + * Tokenizer + */ + + + var Tokenizer = /*#__PURE__*/function () { + function Tokenizer(options) { + this.options = options || exports.defaults; + } + + var _proto = Tokenizer.prototype; + + _proto.space = function space(src) { + var cap = this.rules.block.newline.exec(src); + + if (cap && cap[0].length > 0) { + return { + type: 'space', + raw: cap[0] + }; + } + }; + + _proto.code = function code(src) { + var cap = this.rules.block.code.exec(src); + + if (cap) { + var text = cap[0].replace(/^ {1,4}/gm, ''); + return { + type: 'code', + raw: cap[0], + codeBlockStyle: 'indented', + text: !this.options.pedantic ? rtrim(text, '\n') : text + }; + } + }; + + _proto.fences = function fences(src) { + var cap = this.rules.block.fences.exec(src); + + if (cap) { + var raw = cap[0]; + var text = indentCodeCompensation(raw, cap[3] || ''); + return { + type: 'code', + raw: raw, + lang: cap[2] ? cap[2].trim() : cap[2], + text: text + }; + } + }; + + _proto.heading = function heading(src) { + var cap = this.rules.block.heading.exec(src); + + if (cap) { + var text = cap[2].trim(); // remove trailing #s + + if (/#$/.test(text)) { + var trimmed = rtrim(text, '#'); + + if (this.options.pedantic) { + text = trimmed.trim(); + } else if (!trimmed || / $/.test(trimmed)) { + // CommonMark requires space before trailing #s + text = trimmed.trim(); + } + } + + var token = { + type: 'heading', + raw: cap[0], + depth: cap[1].length, + text: text, + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + }; + + _proto.hr = function hr(src) { + var cap = this.rules.block.hr.exec(src); + + if (cap) { + return { + type: 'hr', + raw: cap[0] + }; + } + }; + + _proto.blockquote = function blockquote(src) { + var cap = this.rules.block.blockquote.exec(src); + + if (cap) { + var text = cap[0].replace(/^ *>[ \t]?/gm, ''); + return { + type: 'blockquote', + raw: cap[0], + tokens: this.lexer.blockTokens(text, []), + text: text + }; + } + }; + + _proto.list = function list(src) { + var cap = this.rules.block.list.exec(src); + + if (cap) { + var raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, line, nextLine, rawLine, itemContents, endEarly; + var bull = cap[1].trim(); + var isordered = bull.length > 1; + var list = { + type: 'list', + raw: '', + ordered: isordered, + start: isordered ? +bull.slice(0, -1) : '', + loose: false, + items: [] + }; + bull = isordered ? "\\d{1,9}\\" + bull.slice(-1) : "\\" + bull; + + if (this.options.pedantic) { + bull = isordered ? bull : '[*+-]'; + } // Get next list item + + + var itemRegex = new RegExp("^( {0,3}" + bull + ")((?:[\t ][^\\n]*)?(?:\\n|$))"); // Check if current bullet point can start a new List Item + + while (src) { + endEarly = false; + + if (!(cap = itemRegex.exec(src))) { + break; + } + + if (this.rules.block.hr.test(src)) { + // End list if bullet was actually HR (possibly move into itemRegex?) + break; + } + + raw = cap[0]; + src = src.substring(raw.length); + line = cap[2].split('\n', 1)[0]; + nextLine = src.split('\n', 1)[0]; + + if (this.options.pedantic) { + indent = 2; + itemContents = line.trimLeft(); + } else { + indent = cap[2].search(/[^ ]/); // Find first non-space char + + indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent + + itemContents = line.slice(indent); + indent += cap[1].length; + } + + blankLine = false; + + if (!line && /^ *$/.test(nextLine)) { + // Items begin with at most one blank line + raw += nextLine + '\n'; + src = src.substring(nextLine.length + 1); + endEarly = true; + } + + if (!endEarly) { + var nextBulletRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}(?:[*+-]|\\d{1,9}[.)])((?: [^\\n]*)?(?:\\n|$))"); + var hrRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)"); + var fencesBeginRegex = new RegExp("^( {0," + Math.min(3, indent - 1) + "})(```|~~~)"); // Check if following lines should be included in List Item + + while (src) { + rawLine = src.split('\n', 1)[0]; + line = rawLine; // Re-align to follow commonmark nesting rules + + if (this.options.pedantic) { + line = line.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' '); + } // End list item if found code fences + + + if (fencesBeginRegex.test(line)) { + break; + } // End list item if found start of new heading + + + if (this.rules.block.heading.test(line)) { + break; + } // End list item if found start of new bullet + + + if (nextBulletRegex.test(line)) { + break; + } // Horizontal rule found + + + if (hrRegex.test(src)) { + break; + } + + if (line.search(/[^ ]/) >= indent || !line.trim()) { + // Dedent if possible + itemContents += '\n' + line.slice(indent); + } else if (!blankLine) { + // Until blank line, item doesn't need indentation + itemContents += '\n' + line; + } else { + // Otherwise, improper indentation ends this item + break; + } + + if (!blankLine && !line.trim()) { + // Check if current line is blank + blankLine = true; + } + + raw += rawLine + '\n'; + src = src.substring(rawLine.length + 1); + } + } + + if (!list.loose) { + // If the previous item ended with a blank line, the list is loose + if (endsWithBlankLine) { + list.loose = true; + } else if (/\n *\n *$/.test(raw)) { + endsWithBlankLine = true; + } + } // Check for task list items + + + if (this.options.gfm) { + istask = /^\[[ xX]\] /.exec(itemContents); + + if (istask) { + ischecked = istask[0] !== '[ ] '; + itemContents = itemContents.replace(/^\[[ xX]\] +/, ''); + } + } + + list.items.push({ + type: 'list_item', + raw: raw, + task: !!istask, + checked: ischecked, + loose: false, + text: itemContents + }); + list.raw += raw; + } // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic + + + list.items[list.items.length - 1].raw = raw.trimRight(); + list.items[list.items.length - 1].text = itemContents.trimRight(); + list.raw = list.raw.trimRight(); + var l = list.items.length; // Item child tokens handled here at end because we needed to have the final item to trim it first + + for (i = 0; i < l; i++) { + this.lexer.state.top = false; + list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []); + var spacers = list.items[i].tokens.filter(function (t) { + return t.type === 'space'; + }); + var hasMultipleLineBreaks = spacers.every(function (t) { + var chars = t.raw.split(''); + var lineBreaks = 0; + + for (var _iterator = _createForOfIteratorHelperLoose(chars), _step; !(_step = _iterator()).done;) { + var _char = _step.value; + + if (_char === '\n') { + lineBreaks += 1; + } + + if (lineBreaks > 1) { + return true; + } + } + + return false; + }); + + if (!list.loose && spacers.length && hasMultipleLineBreaks) { + // Having a single line break doesn't mean a list is loose. A single line break is terminating the last list item + list.loose = true; + list.items[i].loose = true; + } + } + + return list; + } + }; + + _proto.html = function html(src) { + var cap = this.rules.block.html.exec(src); + + if (cap) { + var token = { + type: 'html', + raw: cap[0], + pre: !this.options.sanitizer && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'), + text: cap[0] + }; + + if (this.options.sanitize) { + token.type = 'paragraph'; + token.text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]); + token.tokens = []; + this.lexer.inline(token.text, token.tokens); + } + + return token; + } + }; + + _proto.def = function def(src) { + var cap = this.rules.block.def.exec(src); + + if (cap) { + if (cap[3]) cap[3] = cap[3].substring(1, cap[3].length - 1); + var tag = cap[1].toLowerCase().replace(/\s+/g, ' '); + return { + type: 'def', + tag: tag, + raw: cap[0], + href: cap[2], + title: cap[3] + }; + } + }; + + _proto.table = function table(src) { + var cap = this.rules.block.table.exec(src); + + if (cap) { + var item = { + type: 'table', + header: splitCells(cap[1]).map(function (c) { + return { + text: c + }; + }), + align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), + rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : [] + }; + + if (item.header.length === item.align.length) { + item.raw = cap[0]; + var l = item.align.length; + var i, j, k, row; + + for (i = 0; i < l; i++) { + if (/^ *-+: *$/.test(item.align[i])) { + item.align[i] = 'right'; + } else if (/^ *:-+: *$/.test(item.align[i])) { + item.align[i] = 'center'; + } else if (/^ *:-+ *$/.test(item.align[i])) { + item.align[i] = 'left'; + } else { + item.align[i] = null; + } + } + + l = item.rows.length; + + for (i = 0; i < l; i++) { + item.rows[i] = splitCells(item.rows[i], item.header.length).map(function (c) { + return { + text: c + }; + }); + } // parse child tokens inside headers and cells + // header child tokens + + + l = item.header.length; + + for (j = 0; j < l; j++) { + item.header[j].tokens = []; + this.lexer.inline(item.header[j].text, item.header[j].tokens); + } // cell child tokens + + + l = item.rows.length; + + for (j = 0; j < l; j++) { + row = item.rows[j]; + + for (k = 0; k < row.length; k++) { + row[k].tokens = []; + this.lexer.inline(row[k].text, row[k].tokens); + } + } + + return item; + } + } + }; + + _proto.lheading = function lheading(src) { + var cap = this.rules.block.lheading.exec(src); + + if (cap) { + var token = { + type: 'heading', + raw: cap[0], + depth: cap[2].charAt(0) === '=' ? 1 : 2, + text: cap[1], + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + }; + + _proto.paragraph = function paragraph(src) { + var cap = this.rules.block.paragraph.exec(src); + + if (cap) { + var token = { + type: 'paragraph', + raw: cap[0], + text: cap[1].charAt(cap[1].length - 1) === '\n' ? cap[1].slice(0, -1) : cap[1], + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + }; + + _proto.text = function text(src) { + var cap = this.rules.block.text.exec(src); + + if (cap) { + var token = { + type: 'text', + raw: cap[0], + text: cap[0], + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + }; + + _proto.escape = function escape$1(src) { + var cap = this.rules.inline.escape.exec(src); + + if (cap) { + return { + type: 'escape', + raw: cap[0], + text: escape(cap[1]) + }; + } + }; + + _proto.tag = function tag(src) { + var cap = this.rules.inline.tag.exec(src); + + if (cap) { + if (!this.lexer.state.inLink && /^
    /i.test(cap[0])) { + this.lexer.state.inLink = false; + } + + if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { + this.lexer.state.inRawBlock = true; + } else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { + this.lexer.state.inRawBlock = false; + } + + return { + type: this.options.sanitize ? 'text' : 'html', + raw: cap[0], + inLink: this.lexer.state.inLink, + inRawBlock: this.lexer.state.inRawBlock, + text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0] + }; + } + }; + + _proto.link = function link(src) { + var cap = this.rules.inline.link.exec(src); + + if (cap) { + var trimmedUrl = cap[2].trim(); + + if (!this.options.pedantic && /^$/.test(trimmedUrl)) { + return; + } // ending angle bracket cannot be escaped + + + var rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\'); + + if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) { + return; + } + } else { + // find closing parenthesis + var lastParenIndex = findClosingBracket(cap[2], '()'); + + if (lastParenIndex > -1) { + var start = cap[0].indexOf('!') === 0 ? 5 : 4; + var linkLen = start + cap[1].length + lastParenIndex; + cap[2] = cap[2].substring(0, lastParenIndex); + cap[0] = cap[0].substring(0, linkLen).trim(); + cap[3] = ''; + } + } + + var href = cap[2]; + var title = ''; + + if (this.options.pedantic) { + // split pedantic href and title + var link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href); + + if (link) { + href = link[1]; + title = link[3]; + } + } else { + title = cap[3] ? cap[3].slice(1, -1) : ''; + } + + href = href.trim(); + + if (/^$/.test(trimmedUrl)) { + // pedantic allows starting angle bracket without ending angle bracket + href = href.slice(1); + } else { + href = href.slice(1, -1); + } + } + + return outputLink(cap, { + href: href ? href.replace(this.rules.inline._escapes, '$1') : href, + title: title ? title.replace(this.rules.inline._escapes, '$1') : title + }, cap[0], this.lexer); + } + }; + + _proto.reflink = function reflink(src, links) { + var cap; + + if ((cap = this.rules.inline.reflink.exec(src)) || (cap = this.rules.inline.nolink.exec(src))) { + var link = (cap[2] || cap[1]).replace(/\s+/g, ' '); + link = links[link.toLowerCase()]; + + if (!link || !link.href) { + var text = cap[0].charAt(0); + return { + type: 'text', + raw: text, + text: text + }; + } + + return outputLink(cap, link, cap[0], this.lexer); + } + }; + + _proto.emStrong = function emStrong(src, maskedSrc, prevChar) { + if (prevChar === void 0) { + prevChar = ''; + } + + var match = this.rules.inline.emStrong.lDelim.exec(src); + if (!match) return; // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well + + if (match[3] && prevChar.match(/(?:[0-9A-Za-z\xAA\xB2\xB3\xB5\xB9\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u0660-\u0669\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088E\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AE6-\u0AEF\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0BE6-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5D\u0C60\u0C61\u0C66-\u0C6F\u0C78-\u0C7E\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDD\u0CDE\u0CE0\u0CE1\u0CE6-\u0CEF\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D58-\u0D61\u0D66-\u0D78\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DE6-\u0DEF\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F-\u1049\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A16\u1A20-\u1A54\u1A80-\u1A89\u1A90-\u1A99\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B50-\u1B59\u1B83-\u1BA0\u1BAE-\u1BE5\u1C00-\u1C23\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070\u2071\u2074-\u2079\u207F-\u2089\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2150-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2CFD\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u3192-\u3195\u31A0-\u31BF\u31F0-\u31FF\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA830-\uA835\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uA9E0-\uA9E4\uA9E6-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDE80-\uDE9C\uDEA0-\uDED0\uDEE1-\uDEFB\uDF00-\uDF23\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC58-\uDC76\uDC79-\uDC9E\uDCA7-\uDCAF\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDD1B\uDD20-\uDD39\uDD80-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE40-\uDE48\uDE60-\uDE7E\uDE80-\uDE9F\uDEC0-\uDEC7\uDEC9-\uDEE4\uDEEB-\uDEEF\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDD23\uDD30-\uDD39\uDE60-\uDE7E\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF27\uDF30-\uDF45\uDF51-\uDF54\uDF70-\uDF81\uDFB0-\uDFCB\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC52-\uDC6F\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD03-\uDD26\uDD36-\uDD3F\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDD0-\uDDDA\uDDDC\uDDE1-\uDDF4\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDEF0-\uDEF9\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC50-\uDC59\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE50-\uDE59\uDE80-\uDEAA\uDEB8\uDEC0-\uDEC9\uDF00-\uDF1A\uDF30-\uDF3B\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCF2\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC50-\uDC6C\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDA0-\uDDA9\uDEE0-\uDEF2\uDFB0\uDFC0-\uDFD4]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDE70-\uDEBE\uDEC0-\uDEC9\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE96\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD834[\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD837[\uDF00-\uDF1E]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD40-\uDD49\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB\uDEF0-\uDEF9]|\uD839[\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF\uDD00-\uDD43\uDD4B\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF38\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])/)) return; + var nextChar = match[1] || match[2] || ''; + + if (!nextChar || nextChar && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar))) { + var lLength = match[0].length - 1; + var rDelim, + rLength, + delimTotal = lLength, + midDelimTotal = 0; + var endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd; + endReg.lastIndex = 0; // Clip maskedSrc to same section of string as src (move to lexer?) + + maskedSrc = maskedSrc.slice(-1 * src.length + lLength); + + while ((match = endReg.exec(maskedSrc)) != null) { + rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6]; + if (!rDelim) continue; // skip single * in __abc*abc__ + + rLength = rDelim.length; + + if (match[3] || match[4]) { + // found another Left Delim + delimTotal += rLength; + continue; + } else if (match[5] || match[6]) { + // either Left or Right Delim + if (lLength % 3 && !((lLength + rLength) % 3)) { + midDelimTotal += rLength; + continue; // CommonMark Emphasis Rules 9-10 + } + } + + delimTotal -= rLength; + if (delimTotal > 0) continue; // Haven't found enough closing delimiters + // Remove extra characters. *a*** -> *a* + + rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal); // Create `em` if smallest delimiter has odd char count. *a*** + + if (Math.min(lLength, rLength) % 2) { + var _text = src.slice(1, lLength + match.index + rLength); + + return { + type: 'em', + raw: src.slice(0, lLength + match.index + rLength + 1), + text: _text, + tokens: this.lexer.inlineTokens(_text, []) + }; + } // Create 'strong' if smallest delimiter has even char count. **a*** + + + var text = src.slice(2, lLength + match.index + rLength - 1); + return { + type: 'strong', + raw: src.slice(0, lLength + match.index + rLength + 1), + text: text, + tokens: this.lexer.inlineTokens(text, []) + }; + } + } + }; + + _proto.codespan = function codespan(src) { + var cap = this.rules.inline.code.exec(src); + + if (cap) { + var text = cap[2].replace(/\n/g, ' '); + var hasNonSpaceChars = /[^ ]/.test(text); + var hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text); + + if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) { + text = text.substring(1, text.length - 1); + } + + text = escape(text, true); + return { + type: 'codespan', + raw: cap[0], + text: text + }; + } + }; + + _proto.br = function br(src) { + var cap = this.rules.inline.br.exec(src); + + if (cap) { + return { + type: 'br', + raw: cap[0] + }; + } + }; + + _proto.del = function del(src) { + var cap = this.rules.inline.del.exec(src); + + if (cap) { + return { + type: 'del', + raw: cap[0], + text: cap[2], + tokens: this.lexer.inlineTokens(cap[2], []) + }; + } + }; + + _proto.autolink = function autolink(src, mangle) { + var cap = this.rules.inline.autolink.exec(src); + + if (cap) { + var text, href; + + if (cap[2] === '@') { + text = escape(this.options.mangle ? mangle(cap[1]) : cap[1]); + href = 'mailto:' + text; + } else { + text = escape(cap[1]); + href = text; + } + + return { + type: 'link', + raw: cap[0], + text: text, + href: href, + tokens: [{ + type: 'text', + raw: text, + text: text + }] + }; + } + }; + + _proto.url = function url(src, mangle) { + var cap; + + if (cap = this.rules.inline.url.exec(src)) { + var text, href; + + if (cap[2] === '@') { + text = escape(this.options.mangle ? mangle(cap[0]) : cap[0]); + href = 'mailto:' + text; + } else { + // do extended autolink path validation + var prevCapZero; + + do { + prevCapZero = cap[0]; + cap[0] = this.rules.inline._backpedal.exec(cap[0])[0]; + } while (prevCapZero !== cap[0]); + + text = escape(cap[0]); + + if (cap[1] === 'www.') { + href = 'http://' + text; + } else { + href = text; + } + } + + return { + type: 'link', + raw: cap[0], + text: text, + href: href, + tokens: [{ + type: 'text', + raw: text, + text: text + }] + }; + } + }; + + _proto.inlineText = function inlineText(src, smartypants) { + var cap = this.rules.inline.text.exec(src); + + if (cap) { + var text; + + if (this.lexer.state.inRawBlock) { + text = this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0]; + } else { + text = escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]); + } + + return { + type: 'text', + raw: cap[0], + text: text + }; + } + }; + + return Tokenizer; + }(); + + /** + * Block-Level Grammar + */ + + var block = { + newline: /^(?: *(?:\n|$))+/, + code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/, + fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/, + hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/, + heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/, + blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/, + list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/, + html: '^ {0,3}(?:' // optional indentation + + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)' // (1) + + '|comment[^\\n]*(\\n+|$)' // (2) + + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3) + + '|\\n*|$)' // (4) + + '|\\n*|$)' // (5) + + '|)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6) + + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag + + '|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag + + ')', + def: /^ {0,3}\[(label)\]: *(?:\n *)?]+)>?(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/, + table: noopTest, + lheading: /^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/, + // regex template, placeholders will be replaced according to different paragraph + // interruption rules of commonmark and the original markdown spec: + _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/, + text: /^[^\n]+/ + }; + block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/; + block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/; + block.def = edit(block.def).replace('label', block._label).replace('title', block._title).getRegex(); + block.bullet = /(?:[*+-]|\d{1,9}[.)])/; + block.listItemStart = edit(/^( *)(bull) */).replace('bull', block.bullet).getRegex(); + block.list = edit(block.list).replace(/bull/g, block.bullet).replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))').replace('def', '\\n+(?=' + block.def.source + ')').getRegex(); + block._tag = 'address|article|aside|base|basefont|blockquote|body|caption' + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption' + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe' + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option' + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr' + '|track|ul'; + block._comment = /|$)/; + block.html = edit(block.html, 'i').replace('comment', block._comment).replace('tag', block._tag).replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(); + block.paragraph = edit(block._paragraph).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs + .replace('|table', '').replace('blockquote', ' {0,3}>').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt + .replace('html', ')|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // pars can be interrupted by type (6) html blocks + .getRegex(); + block.blockquote = edit(block.blockquote).replace('paragraph', block.paragraph).getRegex(); + /** + * Normal Block Grammar + */ + + block.normal = merge({}, block); + /** + * GFM Block Grammar + */ + + block.gfm = merge({}, block.normal, { + table: '^ *([^\\n ].*\\|.*)\\n' // Header + + ' {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?' // Align + + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells + + }); + block.gfm.table = edit(block.gfm.table).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('blockquote', ' {0,3}>').replace('code', ' {4}[^\\n]').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt + .replace('html', ')|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // tables can be interrupted by type (6) html blocks + .getRegex(); + block.gfm.paragraph = edit(block._paragraph).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs + .replace('table', block.gfm.table) // interrupt paragraphs with table + .replace('blockquote', ' {0,3}>').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt + .replace('html', ')|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // pars can be interrupted by type (6) html blocks + .getRegex(); + /** + * Pedantic grammar (original John Gruber's loose markdown specification) + */ + + block.pedantic = merge({}, block.normal, { + html: edit('^ *(?:comment *(?:\\n|\\s*$)' + '|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)' // closed tag + + '|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))').replace('comment', block._comment).replace(/tag/g, '(?!(?:' + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub' + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)' + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b').getRegex(), + def: /^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, + heading: /^(#{1,6})(.*)(?:\n+|$)/, + fences: noopTest, + // fences not supported + paragraph: edit(block.normal._paragraph).replace('hr', block.hr).replace('heading', ' *#{1,6} *[^\n]').replace('lheading', block.lheading).replace('blockquote', ' {0,3}>').replace('|fences', '').replace('|list', '').replace('|html', '').getRegex() + }); + /** + * Inline-Level Grammar + */ + + var inline = { + escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, + autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/, + url: noopTest, + tag: '^comment' + '|^' // self-closing tag + + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag + + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. + + '|^' // declaration, e.g. + + '|^', + // CDATA section + link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/, + reflink: /^!?\[(label)\]\[(ref)\]/, + nolink: /^!?\[(ref)\](?:\[\])?/, + reflinkSearch: 'reflink|nolink(?!\\()', + emStrong: { + lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/, + // (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right. + // () Skip orphan inside strong () Consume to delim (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a + rDelimAst: /^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[^*]+(?=[^*])|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/, + rDelimUnd: /^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _ + + }, + code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, + br: /^( {2,}|\\)\n(?!\s*$)/, + del: noopTest, + text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\?@\\[\\]`^{|}~'; + inline.punctuation = edit(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex(); // sequences em should skip over [title](link), `code`, + + inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g; + inline.escapedEmSt = /\\\*|\\_/g; + inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex(); + inline.emStrong.lDelim = edit(inline.emStrong.lDelim).replace(/punct/g, inline._punctuation).getRegex(); + inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'g').replace(/punct/g, inline._punctuation).getRegex(); + inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'g').replace(/punct/g, inline._punctuation).getRegex(); + inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g; + inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/; + inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/; + inline.autolink = edit(inline.autolink).replace('scheme', inline._scheme).replace('email', inline._email).getRegex(); + inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/; + inline.tag = edit(inline.tag).replace('comment', inline._comment).replace('attribute', inline._attribute).getRegex(); + inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/; + inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/; + inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/; + inline.link = edit(inline.link).replace('label', inline._label).replace('href', inline._href).replace('title', inline._title).getRegex(); + inline.reflink = edit(inline.reflink).replace('label', inline._label).replace('ref', block._label).getRegex(); + inline.nolink = edit(inline.nolink).replace('ref', block._label).getRegex(); + inline.reflinkSearch = edit(inline.reflinkSearch, 'g').replace('reflink', inline.reflink).replace('nolink', inline.nolink).getRegex(); + /** + * Normal Inline Grammar + */ + + inline.normal = merge({}, inline); + /** + * Pedantic Inline Grammar + */ + + inline.pedantic = merge({}, inline.normal, { + strong: { + start: /^__|\*\*/, + middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, + endAst: /\*\*(?!\*)/g, + endUnd: /__(?!_)/g + }, + em: { + start: /^_|\*/, + middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/, + endAst: /\*(?!\*)/g, + endUnd: /_(?!_)/g + }, + link: edit(/^!?\[(label)\]\((.*?)\)/).replace('label', inline._label).getRegex(), + reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace('label', inline._label).getRegex() + }); + /** + * GFM Inline Grammar + */ + + inline.gfm = merge({}, inline.normal, { + escape: edit(inline.escape).replace('])', '~|])').getRegex(), + _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/, + url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, + _backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/, + del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/, + text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\ 0.5) { + ch = 'x' + ch.toString(16); + } + + out += '&#' + ch + ';'; + } + + return out; + } + /** + * Block Lexer + */ + + + var Lexer = /*#__PURE__*/function () { + function Lexer(options) { + this.tokens = []; + this.tokens.links = Object.create(null); + this.options = options || exports.defaults; + this.options.tokenizer = this.options.tokenizer || new Tokenizer(); + this.tokenizer = this.options.tokenizer; + this.tokenizer.options = this.options; + this.tokenizer.lexer = this; + this.inlineQueue = []; + this.state = { + inLink: false, + inRawBlock: false, + top: true + }; + var rules = { + block: block.normal, + inline: inline.normal + }; + + if (this.options.pedantic) { + rules.block = block.pedantic; + rules.inline = inline.pedantic; + } else if (this.options.gfm) { + rules.block = block.gfm; + + if (this.options.breaks) { + rules.inline = inline.breaks; + } else { + rules.inline = inline.gfm; + } + } + + this.tokenizer.rules = rules; + } + /** + * Expose Rules + */ + + + /** + * Static Lex Method + */ + Lexer.lex = function lex(src, options) { + var lexer = new Lexer(options); + return lexer.lex(src); + } + /** + * Static Lex Inline Method + */ + ; + + Lexer.lexInline = function lexInline(src, options) { + var lexer = new Lexer(options); + return lexer.inlineTokens(src); + } + /** + * Preprocessing + */ + ; + + var _proto = Lexer.prototype; + + _proto.lex = function lex(src) { + src = src.replace(/\r\n|\r/g, '\n'); + this.blockTokens(src, this.tokens); + var next; + + while (next = this.inlineQueue.shift()) { + this.inlineTokens(next.src, next.tokens); + } + + return this.tokens; + } + /** + * Lexing + */ + ; + + _proto.blockTokens = function blockTokens(src, tokens) { + var _this = this; + + if (tokens === void 0) { + tokens = []; + } + + if (this.options.pedantic) { + src = src.replace(/\t/g, ' ').replace(/^ +$/gm, ''); + } else { + src = src.replace(/^( *)(\t+)/gm, function (_, leading, tabs) { + return leading + ' '.repeat(tabs.length); + }); + } + + var token, lastToken, cutSrc, lastParagraphClipped; + + while (src) { + if (this.options.extensions && this.options.extensions.block && this.options.extensions.block.some(function (extTokenizer) { + if (token = extTokenizer.call({ + lexer: _this + }, src, tokens)) { + src = src.substring(token.raw.length); + tokens.push(token); + return true; + } + + return false; + })) { + continue; + } // newline + + + if (token = this.tokenizer.space(src)) { + src = src.substring(token.raw.length); + + if (token.raw.length === 1 && tokens.length > 0) { + // if there's a single \n as a spacer, it's terminating the last line, + // so move it there so that we don't get unecessary paragraph tags + tokens[tokens.length - 1].raw += '\n'; + } else { + tokens.push(token); + } + + continue; + } // code + + + if (token = this.tokenizer.code(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; // An indented code block cannot interrupt a paragraph. + + if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.text; + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else { + tokens.push(token); + } + + continue; + } // fences + + + if (token = this.tokenizer.fences(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // heading + + + if (token = this.tokenizer.heading(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // hr + + + if (token = this.tokenizer.hr(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // blockquote + + + if (token = this.tokenizer.blockquote(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // list + + + if (token = this.tokenizer.list(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // html + + + if (token = this.tokenizer.html(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // def + + + if (token = this.tokenizer.def(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + + if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.raw; + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else if (!this.tokens.links[token.tag]) { + this.tokens.links[token.tag] = { + href: token.href, + title: token.title + }; + } + + continue; + } // table (gfm) + + + if (token = this.tokenizer.table(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // lheading + + + if (token = this.tokenizer.lheading(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // top-level paragraph + // prevent paragraph consuming extensions by clipping 'src' to extension start + + + cutSrc = src; + + if (this.options.extensions && this.options.extensions.startBlock) { + (function () { + var startIndex = Infinity; + var tempSrc = src.slice(1); + var tempStart = void 0; + + _this.options.extensions.startBlock.forEach(function (getStartIndex) { + tempStart = getStartIndex.call({ + lexer: this + }, tempSrc); + + if (typeof tempStart === 'number' && tempStart >= 0) { + startIndex = Math.min(startIndex, tempStart); + } + }); + + if (startIndex < Infinity && startIndex >= 0) { + cutSrc = src.substring(0, startIndex + 1); + } + })(); + } + + if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) { + lastToken = tokens[tokens.length - 1]; + + if (lastParagraphClipped && lastToken.type === 'paragraph') { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.text; + this.inlineQueue.pop(); + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else { + tokens.push(token); + } + + lastParagraphClipped = cutSrc.length !== src.length; + src = src.substring(token.raw.length); + continue; + } // text + + + if (token = this.tokenizer.text(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + + if (lastToken && lastToken.type === 'text') { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.text; + this.inlineQueue.pop(); + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else { + tokens.push(token); + } + + continue; + } + + if (src) { + var errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0); + + if (this.options.silent) { + console.error(errMsg); + break; + } else { + throw new Error(errMsg); + } + } + } + + this.state.top = true; + return tokens; + }; + + _proto.inline = function inline(src, tokens) { + this.inlineQueue.push({ + src: src, + tokens: tokens + }); + } + /** + * Lexing/Compiling + */ + ; + + _proto.inlineTokens = function inlineTokens(src, tokens) { + var _this2 = this; + + if (tokens === void 0) { + tokens = []; + } + + var token, lastToken, cutSrc; // String with links masked to avoid interference with em and strong + + var maskedSrc = src; + var match; + var keepPrevChar, prevChar; // Mask out reflinks + + if (this.tokens.links) { + var links = Object.keys(this.tokens.links); + + if (links.length > 0) { + while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) { + if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) { + maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex); + } + } + } + } // Mask out other blocks + + + while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) { + maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex); + } // Mask out escaped em & strong delimiters + + + while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) { + maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex); + } + + while (src) { + if (!keepPrevChar) { + prevChar = ''; + } + + keepPrevChar = false; // extensions + + if (this.options.extensions && this.options.extensions.inline && this.options.extensions.inline.some(function (extTokenizer) { + if (token = extTokenizer.call({ + lexer: _this2 + }, src, tokens)) { + src = src.substring(token.raw.length); + tokens.push(token); + return true; + } + + return false; + })) { + continue; + } // escape + + + if (token = this.tokenizer.escape(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // tag + + + if (token = this.tokenizer.tag(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + + if (lastToken && token.type === 'text' && lastToken.type === 'text') { + lastToken.raw += token.raw; + lastToken.text += token.text; + } else { + tokens.push(token); + } + + continue; + } // link + + + if (token = this.tokenizer.link(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // reflink, nolink + + + if (token = this.tokenizer.reflink(src, this.tokens.links)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + + if (lastToken && token.type === 'text' && lastToken.type === 'text') { + lastToken.raw += token.raw; + lastToken.text += token.text; + } else { + tokens.push(token); + } + + continue; + } // em & strong + + + if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // code + + + if (token = this.tokenizer.codespan(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // br + + + if (token = this.tokenizer.br(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // del (gfm) + + + if (token = this.tokenizer.del(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // autolink + + + if (token = this.tokenizer.autolink(src, mangle)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // url (gfm) + + + if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } // text + // prevent inlineText consuming extensions by clipping 'src' to extension start + + + cutSrc = src; + + if (this.options.extensions && this.options.extensions.startInline) { + (function () { + var startIndex = Infinity; + var tempSrc = src.slice(1); + var tempStart = void 0; + + _this2.options.extensions.startInline.forEach(function (getStartIndex) { + tempStart = getStartIndex.call({ + lexer: this + }, tempSrc); + + if (typeof tempStart === 'number' && tempStart >= 0) { + startIndex = Math.min(startIndex, tempStart); + } + }); + + if (startIndex < Infinity && startIndex >= 0) { + cutSrc = src.substring(0, startIndex + 1); + } + })(); + } + + if (token = this.tokenizer.inlineText(cutSrc, smartypants)) { + src = src.substring(token.raw.length); + + if (token.raw.slice(-1) !== '_') { + // Track prevChar before string of ____ started + prevChar = token.raw.slice(-1); + } + + keepPrevChar = true; + lastToken = tokens[tokens.length - 1]; + + if (lastToken && lastToken.type === 'text') { + lastToken.raw += token.raw; + lastToken.text += token.text; + } else { + tokens.push(token); + } + + continue; + } + + if (src) { + var errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0); + + if (this.options.silent) { + console.error(errMsg); + break; + } else { + throw new Error(errMsg); + } + } + } + + return tokens; + }; + + _createClass(Lexer, null, [{ + key: "rules", + get: function get() { + return { + block: block, + inline: inline + }; + } + }]); + + return Lexer; + }(); + + /** + * Renderer + */ + + var Renderer = /*#__PURE__*/function () { + function Renderer(options) { + this.options = options || exports.defaults; + } + + var _proto = Renderer.prototype; + + _proto.code = function code(_code, infostring, escaped) { + var lang = (infostring || '').match(/\S*/)[0]; + + if (this.options.highlight) { + var out = this.options.highlight(_code, lang); + + if (out != null && out !== _code) { + escaped = true; + _code = out; + } + } + + _code = _code.replace(/\n$/, '') + '\n'; + + if (!lang) { + return '
    ' + (escaped ? _code : escape(_code, true)) + '
    \n'; + } + + return '
    ' + (escaped ? _code : escape(_code, true)) + '
    \n'; + } + /** + * @param {string} quote + */ + ; + + _proto.blockquote = function blockquote(quote) { + return "
    \n" + quote + "
    \n"; + }; + + _proto.html = function html(_html) { + return _html; + } + /** + * @param {string} text + * @param {string} level + * @param {string} raw + * @param {any} slugger + */ + ; + + _proto.heading = function heading(text, level, raw, slugger) { + if (this.options.headerIds) { + var id = this.options.headerPrefix + slugger.slug(raw); + return "" + text + "\n"; + } // ignore IDs + + + return "" + text + "\n"; + }; + + _proto.hr = function hr() { + return this.options.xhtml ? '
    \n' : '
    \n'; + }; + + _proto.list = function list(body, ordered, start) { + var type = ordered ? 'ol' : 'ul', + startatt = ordered && start !== 1 ? ' start="' + start + '"' : ''; + return '<' + type + startatt + '>\n' + body + '\n'; + } + /** + * @param {string} text + */ + ; + + _proto.listitem = function listitem(text) { + return "
  • " + text + "
  • \n"; + }; + + _proto.checkbox = function checkbox(checked) { + return ' '; + } + /** + * @param {string} text + */ + ; + + _proto.paragraph = function paragraph(text) { + return "

    " + text + "

    \n"; + } + /** + * @param {string} header + * @param {string} body + */ + ; + + _proto.table = function table(header, body) { + if (body) body = "" + body + ""; + return '\n' + '\n' + header + '\n' + body + '
    \n'; + } + /** + * @param {string} content + */ + ; + + _proto.tablerow = function tablerow(content) { + return "\n" + content + "\n"; + }; + + _proto.tablecell = function tablecell(content, flags) { + var type = flags.header ? 'th' : 'td'; + var tag = flags.align ? "<" + type + " align=\"" + flags.align + "\">" : "<" + type + ">"; + return tag + content + ("\n"); + } + /** + * span level renderer + * @param {string} text + */ + ; + + _proto.strong = function strong(text) { + return "" + text + ""; + } + /** + * @param {string} text + */ + ; + + _proto.em = function em(text) { + return "" + text + ""; + } + /** + * @param {string} text + */ + ; + + _proto.codespan = function codespan(text) { + return "" + text + ""; + }; + + _proto.br = function br() { + return this.options.xhtml ? '
    ' : '
    '; + } + /** + * @param {string} text + */ + ; + + _proto.del = function del(text) { + return "" + text + ""; + } + /** + * @param {string} href + * @param {string} title + * @param {string} text + */ + ; + + _proto.link = function link(href, title, text) { + href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); + + if (href === null) { + return text; + } + + var out = '
    '; + return out; + } + /** + * @param {string} href + * @param {string} title + * @param {string} text + */ + ; + + _proto.image = function image(href, title, text) { + href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); + + if (href === null) { + return text; + } + + var out = "\""' : '>'; + return out; + }; + + _proto.text = function text(_text) { + return _text; + }; + + return Renderer; + }(); + + /** + * TextRenderer + * returns only the textual part of the token + */ + var TextRenderer = /*#__PURE__*/function () { + function TextRenderer() {} + + var _proto = TextRenderer.prototype; + + // no need for block level renderers + _proto.strong = function strong(text) { + return text; + }; + + _proto.em = function em(text) { + return text; + }; + + _proto.codespan = function codespan(text) { + return text; + }; + + _proto.del = function del(text) { + return text; + }; + + _proto.html = function html(text) { + return text; + }; + + _proto.text = function text(_text) { + return _text; + }; + + _proto.link = function link(href, title, text) { + return '' + text; + }; + + _proto.image = function image(href, title, text) { + return '' + text; + }; + + _proto.br = function br() { + return ''; + }; + + return TextRenderer; + }(); + + /** + * Slugger generates header id + */ + var Slugger = /*#__PURE__*/function () { + function Slugger() { + this.seen = {}; + } + /** + * @param {string} value + */ + + + var _proto = Slugger.prototype; + + _proto.serialize = function serialize(value) { + return value.toLowerCase().trim() // remove html tags + .replace(/<[!\/a-z].*?>/ig, '') // remove unwanted chars + .replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '').replace(/\s/g, '-'); + } + /** + * Finds the next safe (unique) slug to use + * @param {string} originalSlug + * @param {boolean} isDryRun + */ + ; + + _proto.getNextSafeSlug = function getNextSafeSlug(originalSlug, isDryRun) { + var slug = originalSlug; + var occurenceAccumulator = 0; + + if (this.seen.hasOwnProperty(slug)) { + occurenceAccumulator = this.seen[originalSlug]; + + do { + occurenceAccumulator++; + slug = originalSlug + '-' + occurenceAccumulator; + } while (this.seen.hasOwnProperty(slug)); + } + + if (!isDryRun) { + this.seen[originalSlug] = occurenceAccumulator; + this.seen[slug] = 0; + } + + return slug; + } + /** + * Convert string to unique id + * @param {object} [options] + * @param {boolean} [options.dryrun] Generates the next unique slug without + * updating the internal accumulator. + */ + ; + + _proto.slug = function slug(value, options) { + if (options === void 0) { + options = {}; + } + + var slug = this.serialize(value); + return this.getNextSafeSlug(slug, options.dryrun); + }; + + return Slugger; + }(); + + /** + * Parsing & Compiling + */ + + var Parser = /*#__PURE__*/function () { + function Parser(options) { + this.options = options || exports.defaults; + this.options.renderer = this.options.renderer || new Renderer(); + this.renderer = this.options.renderer; + this.renderer.options = this.options; + this.textRenderer = new TextRenderer(); + this.slugger = new Slugger(); + } + /** + * Static Parse Method + */ + + + Parser.parse = function parse(tokens, options) { + var parser = new Parser(options); + return parser.parse(tokens); + } + /** + * Static Parse Inline Method + */ + ; + + Parser.parseInline = function parseInline(tokens, options) { + var parser = new Parser(options); + return parser.parseInline(tokens); + } + /** + * Parse Loop + */ + ; + + var _proto = Parser.prototype; + + _proto.parse = function parse(tokens, top) { + if (top === void 0) { + top = true; + } + + var out = '', + i, + j, + k, + l2, + l3, + row, + cell, + header, + body, + token, + ordered, + start, + loose, + itemBody, + item, + checked, + task, + checkbox, + ret; + var l = tokens.length; + + for (i = 0; i < l; i++) { + token = tokens[i]; // Run any renderer extensions + + if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { + ret = this.options.extensions.renderers[token.type].call({ + parser: this + }, token); + + if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) { + out += ret || ''; + continue; + } + } + + switch (token.type) { + case 'space': + { + continue; + } + + case 'hr': + { + out += this.renderer.hr(); + continue; + } + + case 'heading': + { + out += this.renderer.heading(this.parseInline(token.tokens), token.depth, unescape(this.parseInline(token.tokens, this.textRenderer)), this.slugger); + continue; + } + + case 'code': + { + out += this.renderer.code(token.text, token.lang, token.escaped); + continue; + } + + case 'table': + { + header = ''; // header + + cell = ''; + l2 = token.header.length; + + for (j = 0; j < l2; j++) { + cell += this.renderer.tablecell(this.parseInline(token.header[j].tokens), { + header: true, + align: token.align[j] + }); + } + + header += this.renderer.tablerow(cell); + body = ''; + l2 = token.rows.length; + + for (j = 0; j < l2; j++) { + row = token.rows[j]; + cell = ''; + l3 = row.length; + + for (k = 0; k < l3; k++) { + cell += this.renderer.tablecell(this.parseInline(row[k].tokens), { + header: false, + align: token.align[k] + }); + } + + body += this.renderer.tablerow(cell); + } + + out += this.renderer.table(header, body); + continue; + } + + case 'blockquote': + { + body = this.parse(token.tokens); + out += this.renderer.blockquote(body); + continue; + } + + case 'list': + { + ordered = token.ordered; + start = token.start; + loose = token.loose; + l2 = token.items.length; + body = ''; + + for (j = 0; j < l2; j++) { + item = token.items[j]; + checked = item.checked; + task = item.task; + itemBody = ''; + + if (item.task) { + checkbox = this.renderer.checkbox(checked); + + if (loose) { + if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') { + item.tokens[0].text = checkbox + ' ' + item.tokens[0].text; + + if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') { + item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text; + } + } else { + item.tokens.unshift({ + type: 'text', + text: checkbox + }); + } + } else { + itemBody += checkbox; + } + } + + itemBody += this.parse(item.tokens, loose); + body += this.renderer.listitem(itemBody, task, checked); + } + + out += this.renderer.list(body, ordered, start); + continue; + } + + case 'html': + { + // TODO parse inline content if parameter markdown=1 + out += this.renderer.html(token.text); + continue; + } + + case 'paragraph': + { + out += this.renderer.paragraph(this.parseInline(token.tokens)); + continue; + } + + case 'text': + { + body = token.tokens ? this.parseInline(token.tokens) : token.text; + + while (i + 1 < l && tokens[i + 1].type === 'text') { + token = tokens[++i]; + body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text); + } + + out += top ? this.renderer.paragraph(body) : body; + continue; + } + + default: + { + var errMsg = 'Token with "' + token.type + '" type was not found.'; + + if (this.options.silent) { + console.error(errMsg); + return; + } else { + throw new Error(errMsg); + } + } + } + } + + return out; + } + /** + * Parse Inline Tokens + */ + ; + + _proto.parseInline = function parseInline(tokens, renderer) { + renderer = renderer || this.renderer; + var out = '', + i, + token, + ret; + var l = tokens.length; + + for (i = 0; i < l; i++) { + token = tokens[i]; // Run any renderer extensions + + if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { + ret = this.options.extensions.renderers[token.type].call({ + parser: this + }, token); + + if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) { + out += ret || ''; + continue; + } + } + + switch (token.type) { + case 'escape': + { + out += renderer.text(token.text); + break; + } + + case 'html': + { + out += renderer.html(token.text); + break; + } + + case 'link': + { + out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer)); + break; + } + + case 'image': + { + out += renderer.image(token.href, token.title, token.text); + break; + } + + case 'strong': + { + out += renderer.strong(this.parseInline(token.tokens, renderer)); + break; + } + + case 'em': + { + out += renderer.em(this.parseInline(token.tokens, renderer)); + break; + } + + case 'codespan': + { + out += renderer.codespan(token.text); + break; + } + + case 'br': + { + out += renderer.br(); + break; + } + + case 'del': + { + out += renderer.del(this.parseInline(token.tokens, renderer)); + break; + } + + case 'text': + { + out += renderer.text(token.text); + break; + } + + default: + { + var errMsg = 'Token with "' + token.type + '" type was not found.'; + + if (this.options.silent) { + console.error(errMsg); + return; + } else { + throw new Error(errMsg); + } + } + } + } + + return out; + }; + + return Parser; + }(); + + /** + * Marked + */ + + function marked(src, opt, callback) { + // throw error in case of non string input + if (typeof src === 'undefined' || src === null) { + throw new Error('marked(): input parameter is undefined or null'); + } + + if (typeof src !== 'string') { + throw new Error('marked(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected'); + } + + if (typeof opt === 'function') { + callback = opt; + opt = null; + } + + opt = merge({}, marked.defaults, opt || {}); + checkSanitizeDeprecation(opt); + + if (callback) { + var highlight = opt.highlight; + var tokens; + + try { + tokens = Lexer.lex(src, opt); + } catch (e) { + return callback(e); + } + + var done = function done(err) { + var out; + + if (!err) { + try { + if (opt.walkTokens) { + marked.walkTokens(tokens, opt.walkTokens); + } + + out = Parser.parse(tokens, opt); + } catch (e) { + err = e; + } + } + + opt.highlight = highlight; + return err ? callback(err) : callback(null, out); + }; + + if (!highlight || highlight.length < 3) { + return done(); + } + + delete opt.highlight; + if (!tokens.length) return done(); + var pending = 0; + marked.walkTokens(tokens, function (token) { + if (token.type === 'code') { + pending++; + setTimeout(function () { + highlight(token.text, token.lang, function (err, code) { + if (err) { + return done(err); + } + + if (code != null && code !== token.text) { + token.text = code; + token.escaped = true; + } + + pending--; + + if (pending === 0) { + done(); + } + }); + }, 0); + } + }); + + if (pending === 0) { + done(); + } + + return; + } + + try { + var _tokens = Lexer.lex(src, opt); + + if (opt.walkTokens) { + marked.walkTokens(_tokens, opt.walkTokens); + } + + return Parser.parse(_tokens, opt); + } catch (e) { + e.message += '\nPlease report this to https://github.com/markedjs/marked.'; + + if (opt.silent) { + return '

    An error occurred:

    ' + escape(e.message + '', true) + '
    '; + } + + throw e; + } + } + /** + * Options + */ + + marked.options = marked.setOptions = function (opt) { + merge(marked.defaults, opt); + changeDefaults(marked.defaults); + return marked; + }; + + marked.getDefaults = getDefaults; + marked.defaults = exports.defaults; + /** + * Use Extension + */ + + marked.use = function () { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + var opts = merge.apply(void 0, [{}].concat(args)); + var extensions = marked.defaults.extensions || { + renderers: {}, + childTokens: {} + }; + var hasExtensions; + args.forEach(function (pack) { + // ==-- Parse "addon" extensions --== // + if (pack.extensions) { + hasExtensions = true; + pack.extensions.forEach(function (ext) { + if (!ext.name) { + throw new Error('extension name required'); + } + + if (ext.renderer) { + // Renderer extensions + var prevRenderer = extensions.renderers ? extensions.renderers[ext.name] : null; + + if (prevRenderer) { + // Replace extension with func to run new extension but fall back if false + extensions.renderers[ext.name] = function () { + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + var ret = ext.renderer.apply(this, args); + + if (ret === false) { + ret = prevRenderer.apply(this, args); + } + + return ret; + }; + } else { + extensions.renderers[ext.name] = ext.renderer; + } + } + + if (ext.tokenizer) { + // Tokenizer Extensions + if (!ext.level || ext.level !== 'block' && ext.level !== 'inline') { + throw new Error("extension level must be 'block' or 'inline'"); + } + + if (extensions[ext.level]) { + extensions[ext.level].unshift(ext.tokenizer); + } else { + extensions[ext.level] = [ext.tokenizer]; + } + + if (ext.start) { + // Function to check for start of token + if (ext.level === 'block') { + if (extensions.startBlock) { + extensions.startBlock.push(ext.start); + } else { + extensions.startBlock = [ext.start]; + } + } else if (ext.level === 'inline') { + if (extensions.startInline) { + extensions.startInline.push(ext.start); + } else { + extensions.startInline = [ext.start]; + } + } + } + } + + if (ext.childTokens) { + // Child tokens to be visited by walkTokens + extensions.childTokens[ext.name] = ext.childTokens; + } + }); + } // ==-- Parse "overwrite" extensions --== // + + + if (pack.renderer) { + (function () { + var renderer = marked.defaults.renderer || new Renderer(); + + var _loop = function _loop(prop) { + var prevRenderer = renderer[prop]; // Replace renderer with func to run extension, but fall back if false + + renderer[prop] = function () { + for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args[_key3] = arguments[_key3]; + } + + var ret = pack.renderer[prop].apply(renderer, args); + + if (ret === false) { + ret = prevRenderer.apply(renderer, args); + } + + return ret; + }; + }; + + for (var prop in pack.renderer) { + _loop(prop); + } + + opts.renderer = renderer; + })(); + } + + if (pack.tokenizer) { + (function () { + var tokenizer = marked.defaults.tokenizer || new Tokenizer(); + + var _loop2 = function _loop2(prop) { + var prevTokenizer = tokenizer[prop]; // Replace tokenizer with func to run extension, but fall back if false + + tokenizer[prop] = function () { + for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; + } + + var ret = pack.tokenizer[prop].apply(tokenizer, args); + + if (ret === false) { + ret = prevTokenizer.apply(tokenizer, args); + } + + return ret; + }; + }; + + for (var prop in pack.tokenizer) { + _loop2(prop); + } + + opts.tokenizer = tokenizer; + })(); + } // ==-- Parse WalkTokens extensions --== // + + + if (pack.walkTokens) { + var _walkTokens = marked.defaults.walkTokens; + + opts.walkTokens = function (token) { + pack.walkTokens.call(this, token); + + if (_walkTokens) { + _walkTokens.call(this, token); + } + }; + } + + if (hasExtensions) { + opts.extensions = extensions; + } + + marked.setOptions(opts); + }); + }; + /** + * Run callback for every token + */ + + + marked.walkTokens = function (tokens, callback) { + var _loop3 = function _loop3() { + var token = _step.value; + callback.call(marked, token); + + switch (token.type) { + case 'table': + { + for (var _iterator2 = _createForOfIteratorHelperLoose(token.header), _step2; !(_step2 = _iterator2()).done;) { + var cell = _step2.value; + marked.walkTokens(cell.tokens, callback); + } + + for (var _iterator3 = _createForOfIteratorHelperLoose(token.rows), _step3; !(_step3 = _iterator3()).done;) { + var row = _step3.value; + + for (var _iterator4 = _createForOfIteratorHelperLoose(row), _step4; !(_step4 = _iterator4()).done;) { + var _cell = _step4.value; + marked.walkTokens(_cell.tokens, callback); + } + } + + break; + } + + case 'list': + { + marked.walkTokens(token.items, callback); + break; + } + + default: + { + if (marked.defaults.extensions && marked.defaults.extensions.childTokens && marked.defaults.extensions.childTokens[token.type]) { + // Walk any extensions + marked.defaults.extensions.childTokens[token.type].forEach(function (childTokens) { + marked.walkTokens(token[childTokens], callback); + }); + } else if (token.tokens) { + marked.walkTokens(token.tokens, callback); + } + } + } + }; + + for (var _iterator = _createForOfIteratorHelperLoose(tokens), _step; !(_step = _iterator()).done;) { + _loop3(); + } + }; + /** + * Parse Inline + * @param {string} src + */ + + + marked.parseInline = function (src, opt) { + // throw error in case of non string input + if (typeof src === 'undefined' || src === null) { + throw new Error('marked.parseInline(): input parameter is undefined or null'); + } + + if (typeof src !== 'string') { + throw new Error('marked.parseInline(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected'); + } + + opt = merge({}, marked.defaults, opt || {}); + checkSanitizeDeprecation(opt); + + try { + var tokens = Lexer.lexInline(src, opt); + + if (opt.walkTokens) { + marked.walkTokens(tokens, opt.walkTokens); + } + + return Parser.parseInline(tokens, opt); + } catch (e) { + e.message += '\nPlease report this to https://github.com/markedjs/marked.'; + + if (opt.silent) { + return '

    An error occurred:

    ' + escape(e.message + '', true) + '
    '; + } + + throw e; + } + }; + /** + * Expose + */ + + + marked.Parser = Parser; + marked.parser = Parser.parse; + marked.Renderer = Renderer; + marked.TextRenderer = TextRenderer; + marked.Lexer = Lexer; + marked.lexer = Lexer.lex; + marked.Tokenizer = Tokenizer; + marked.Slugger = Slugger; + marked.parse = marked; + var options = marked.options; + var setOptions = marked.setOptions; + var use = marked.use; + var walkTokens = marked.walkTokens; + var parseInline = marked.parseInline; + var parse = marked; + var parser = Parser.parse; + var lexer = Lexer.lex; + + exports.Lexer = Lexer; + exports.Parser = Parser; + exports.Renderer = Renderer; + exports.Slugger = Slugger; + exports.TextRenderer = TextRenderer; + exports.Tokenizer = Tokenizer; + exports.getDefaults = getDefaults; + exports.lexer = lexer; + exports.marked = marked; + exports.options = options; + exports.parse = parse; + exports.parseInline = parseInline; + exports.parser = parser; + exports.setOptions = setOptions; + exports.use = use; + exports.walkTokens = walkTokens; + + Object.defineProperty(exports, '__esModule', { value: true }); + +})); diff --git a/node_modules/marked/man/marked.1 b/node_modules/marked/man/marked.1 new file mode 100644 index 0000000..4dd24fd --- /dev/null +++ b/node_modules/marked/man/marked.1 @@ -0,0 +1,92 @@ +.ds q \N'34' +.TH marked 1 + +.SH NAME +marked \- a javascript markdown parser + +.SH SYNOPSIS +.B marked +[\-o \fI\fP] [\-i \fI\fP] [\-s \fI\fP] [\-\-help] +[\-\-tokens] [\-\-pedantic] [\-\-gfm] +[\-\-breaks] [\-\-sanitize] +[\-\-smart\-lists] [\-\-lang\-prefix \fI\fP] +[\-\-no\-etc...] [\-\-silent] [\fIfilename\fP] + +.SH DESCRIPTION +.B marked +is a full-featured javascript markdown parser, built for speed. +It also includes multiple GFM features. + +.SH EXAMPLES +.TP +cat in.md | marked > out.html +.TP +echo "hello *world*" | marked +.TP +marked \-o out.html \-i in.md \-\-gfm +.TP +marked \-\-output="hello world.html" \-i in.md \-\-no-breaks + +.SH OPTIONS +.TP +.BI \-o,\ \-\-output\ [\fIoutput\fP] +Specify file output. If none is specified, write to stdout. +.TP +.BI \-i,\ \-\-input\ [\fIinput\fP] +Specify file input, otherwise use last argument as input file. +If no input file is specified, read from stdin. +.TP +.BI \-s,\ \-\-string\ [\fIstring\fP] +Specify string input instead of a file. +.TP +.BI \-t,\ \-\-tokens +Output a token stream instead of html. +.TP +.BI \-\-pedantic +Conform to obscure parts of markdown.pl as much as possible. +Don't fix original markdown bugs. +.TP +.BI \-\-gfm +Enable github flavored markdown. +.TP +.BI \-\-breaks +Enable GFM line breaks. Only works with the gfm option. +.TP +.BI \-\-sanitize +Sanitize output. Ignore any HTML input. +.TP +.BI \-\-smart\-lists +Use smarter list behavior than the original markdown. +.TP +.BI \-\-lang\-prefix\ [\fIprefix\fP] +Set the prefix for code block classes. +.TP +.BI \-\-mangle +Mangle email addresses. +.TP +.BI \-\-no\-sanitize,\ \-no-etc... +The inverse of any of the marked options above. +.TP +.BI \-\-silent +Silence error output. +.TP +.BI \-h,\ \-\-help +Display help information. + +.SH CONFIGURATION +For configuring and running programmatically. + +.B Example + + import { marked } from 'marked'; + marked('*foo*', { gfm: true }); + +.SH BUGS +Please report any bugs to https://github.com/markedjs/marked. + +.SH LICENSE +Copyright (c) 2011-2014, Christopher Jeffrey (MIT License). + +.SH "SEE ALSO" +.BR markdown(1), +.BR node.js(1) diff --git a/node_modules/marked/man/marked.1.txt b/node_modules/marked/man/marked.1.txt new file mode 100644 index 0000000..1a6816b --- /dev/null +++ b/node_modules/marked/man/marked.1.txt @@ -0,0 +1,86 @@ +marked(1) General Commands Manual marked(1) + +NAME + marked - a javascript markdown parser + +SYNOPSIS + marked [-o ] [-i ] [-s ] [--help] [--tokens] + [--pedantic] [--gfm] [--breaks] [--sanitize] [--smart-lists] + [--lang-prefix ] [--no-etc...] [--silent] [filename] + + +DESCRIPTION + marked is a full-featured javascript markdown parser, built for speed. + It also includes multiple GFM features. + +EXAMPLES + cat in.md | marked > out.html + + echo "hello *world*" | marked + + marked -o out.html -i in.md --gfm + + marked --output="hello world.html" -i in.md --no-breaks + +OPTIONS + -o, --output [output] + Specify file output. If none is specified, write to stdout. + + -i, --input [input] + Specify file input, otherwise use last argument as input file. + If no input file is specified, read from stdin. + + -s, --string [string] + Specify string input instead of a file. + + -t, --tokens + Output a token stream instead of html. + + --pedantic + Conform to obscure parts of markdown.pl as much as possible. + Don't fix original markdown bugs. + + --gfm Enable github flavored markdown. + + --breaks + Enable GFM line breaks. Only works with the gfm option. + + --sanitize + Sanitize output. Ignore any HTML input. + + --smart-lists + Use smarter list behavior than the original markdown. + + --lang-prefix [prefix] + Set the prefix for code block classes. + + --mangle + Mangle email addresses. + + --no-sanitize, -no-etc... + The inverse of any of the marked options above. + + --silent + Silence error output. + + -h, --help + Display help information. + +CONFIGURATION + For configuring and running programmatically. + + Example + + import { marked } from 'marked'; + marked('*foo*', { gfm: true }); + +BUGS + Please report any bugs to https://github.com/markedjs/marked. + +LICENSE + Copyright (c) 2011-2014, Christopher Jeffrey (MIT License). + +SEE ALSO + markdown(1), node.js(1) + + marked(1) diff --git a/node_modules/marked/marked.min.js b/node_modules/marked/marked.min.js new file mode 100644 index 0000000..2d4934d --- /dev/null +++ b/node_modules/marked/marked.min.js @@ -0,0 +1,6 @@ +/** + * marked - a markdown parser + * Copyright (c) 2011-2022, Christopher Jeffrey. (MIT Licensed) + * https://github.com/markedjs/marked + */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).marked={})}(this,function(r){"use strict";function i(e,t){for(var u=0;ue.length)&&(t=e.length);for(var u=0,n=new Array(t);u=e.length?{done:!0}:{done:!1,value:e[u++]}};throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function e(){return{baseUrl:null,breaks:!1,extensions:null,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1}}r.defaults=e();function u(e){return t[e]}var n=/[&<>"']/,l=/[&<>"']/g,a=/[<>"']|&(?!#?\w+;)/,o=/[<>"']|&(?!#?\w+;)/g,t={"&":"&","<":"<",">":">",'"':""","'":"'"};function D(e,t){if(t){if(n.test(e))return e.replace(l,u)}else if(a.test(e))return e.replace(o,u);return e}var c=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi;function x(e){return e.replace(c,function(e,t){return"colon"===(t=t.toLowerCase())?":":"#"===t.charAt(0)?"x"===t.charAt(1)?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):""})}var h=/(^|[^\[])\^/g;function p(u,e){u="string"==typeof u?u:u.source,e=e||"";var n={replace:function(e,t){return t=(t=t.source||t).replace(h,"$1"),u=u.replace(e,t),n},getRegex:function(){return new RegExp(u,e)}};return n}var f=/[^\w:]/g,Z=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;function g(e,t,u){if(e){try{n=decodeURIComponent(x(u)).replace(f,"").toLowerCase()}catch(e){return null}if(0===n.indexOf("javascript:")||0===n.indexOf("vbscript:")||0===n.indexOf("data:"))return null}var n;t&&!Z.test(u)&&(e=u,F[" "+(n=t)]||(O.test(n)?F[" "+n]=n+"/":F[" "+n]=k(n,"/",!0)),t=-1===(n=F[" "+n]).indexOf(":"),u="//"===e.substring(0,2)?t?e:n.replace(q,"$1")+e:"/"===e.charAt(0)?t?e:n.replace(L,"$1")+e:n+e);try{u=encodeURI(u).replace(/%25/g,"%")}catch(e){return null}return u}var F={},O=/^[^:]+:\/*[^/]*$/,q=/^([^:]+:)[\s\S]*$/,L=/^([^:]+:\/*[^/]*)[\s\S]*$/;var A={exec:function(){}};function d(e){for(var t,u,n=1;nt)u.splice(t);else for(;u.length>=1,e+=e;return u+e}function B(e,t,u,n){var r=t.href,t=t.title?D(t.title):null,i=e[1].replace(/\\([\[\]])/g,"$1");return"!"!==e[0].charAt(0)?(n.state.inLink=!0,e={type:"link",raw:u,href:r,title:t,text:i,tokens:n.inlineTokens(i,[])},n.state.inLink=!1,e):{type:"image",raw:u,href:r,title:t,text:D(i)}}var w=function(){function e(e){this.options=e||r.defaults}var t=e.prototype;return t.space=function(e){e=this.rules.block.newline.exec(e);if(e&&0=u.length?e.slice(u.length):e}).join("\n")}(t=e[0],e[3]||""),{type:"code",raw:t,lang:e[2]&&e[2].trim(),text:u}},t.heading=function(e){var t,u,e=this.rules.block.heading.exec(e);if(e)return t=e[2].trim(),/#$/.test(t)&&(u=k(t,"#"),!this.options.pedantic&&u&&!/ $/.test(u)||(t=u.trim())),u={type:"heading",raw:e[0],depth:e[1].length,text:t,tokens:[]},this.lexer.inline(u.text,u.tokens),u},t.hr=function(e){e=this.rules.block.hr.exec(e);if(e)return{type:"hr",raw:e[0]}},t.blockquote=function(e){var t,e=this.rules.block.blockquote.exec(e);if(e)return t=e[0].replace(/^ *>[ \t]?/gm,""),{type:"blockquote",raw:e[0],tokens:this.lexer.blockTokens(t,[]),text:t}},t.list=function(e){var t=this.rules.block.list.exec(e);if(t){var u,n,r,i,s,l,a,o,D,c,h,p=1<(g=t[1].trim()).length,f={type:"list",raw:"",ordered:p,start:p?+g.slice(0,-1):"",loose:!1,items:[]},g=p?"\\d{1,9}\\"+g.slice(-1):"\\"+g;this.options.pedantic&&(g=p?g:"[*+-]");for(var F=new RegExp("^( {0,3}"+g+")((?:[\t ][^\\n]*)?(?:\\n|$))");e&&(h=!1,t=F.exec(e))&&!this.rules.block.hr.test(e);){if(u=t[0],e=e.substring(u.length),a=t[2].split("\n",1)[0],o=e.split("\n",1)[0],this.options.pedantic?(i=2,c=a.trimLeft()):(i=t[2].search(/[^ ]/),c=a.slice(i=4=i||!a.trim())c+="\n"+a.slice(i);else{if(s)break;c+="\n"+a}s||a.trim()||(s=!0),u+=D+"\n",e=e.substring(D.length+1)}f.loose||(l?f.loose=!0:/\n *\n *$/.test(u)&&(l=!0)),this.options.gfm&&(n=/^\[[ xX]\] /.exec(c))&&(r="[ ] "!==n[0],c=c.replace(/^\[[ xX]\] +/,"")),f.items.push({type:"list_item",raw:u,task:!!n,checked:r,loose:!1,text:c}),f.raw+=u}f.items[f.items.length-1].raw=u.trimRight(),f.items[f.items.length-1].text=c.trimRight(),f.raw=f.raw.trimRight();for(var k=f.items.length,E=0;E/i.test(e[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&/^<(pre|code|kbd|script)(\s|>)/i.test(e[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(e[0])&&(this.lexer.state.inRawBlock=!1),{type:this.options.sanitize?"text":"html",raw:e[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,text:this.options.sanitize?this.options.sanitizer?this.options.sanitizer(e[0]):D(e[0]):e[0]}},t.link=function(e){e=this.rules.inline.link.exec(e);if(e){var t=e[2].trim();if(!this.options.pedantic&&/^$/.test(t))return;var u=k(t.slice(0,-1),"\\");if((t.length-u.length)%2==0)return}else{u=function(e,t){if(-1===e.indexOf(t[1]))return-1;for(var u=e.length,n=0,r=0;r$/.test(t)?u.slice(1):u.slice(1,-1):u)&&u.replace(this.rules.inline._escapes,"$1"),title:r&&r.replace(this.rules.inline._escapes,"$1")},e[0],this.lexer)}},t.reflink=function(e,t){var u;if((u=this.rules.inline.reflink.exec(e))||(u=this.rules.inline.nolink.exec(e)))return(e=t[(e=(u[2]||u[1]).replace(/\s+/g," ")).toLowerCase()])&&e.href?B(u,e,u[0],this.lexer):{type:"text",raw:t=u[0].charAt(0),text:t}},t.emStrong=function(e,t,u){void 0===u&&(u="");var n=this.rules.inline.emStrong.lDelim.exec(e);if(n&&(!n[3]||!u.match(/(?:[0-9A-Za-z\xAA\xB2\xB3\xB5\xB9\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u0660-\u0669\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088E\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AE6-\u0AEF\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0BE6-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5D\u0C60\u0C61\u0C66-\u0C6F\u0C78-\u0C7E\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDD\u0CDE\u0CE0\u0CE1\u0CE6-\u0CEF\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D58-\u0D61\u0D66-\u0D78\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DE6-\u0DEF\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F-\u1049\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A16\u1A20-\u1A54\u1A80-\u1A89\u1A90-\u1A99\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B50-\u1B59\u1B83-\u1BA0\u1BAE-\u1BE5\u1C00-\u1C23\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070\u2071\u2074-\u2079\u207F-\u2089\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2150-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2CFD\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u3192-\u3195\u31A0-\u31BF\u31F0-\u31FF\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA830-\uA835\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uA9E0-\uA9E4\uA9E6-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDE80-\uDE9C\uDEA0-\uDED0\uDEE1-\uDEFB\uDF00-\uDF23\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC58-\uDC76\uDC79-\uDC9E\uDCA7-\uDCAF\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDD1B\uDD20-\uDD39\uDD80-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE40-\uDE48\uDE60-\uDE7E\uDE80-\uDE9F\uDEC0-\uDEC7\uDEC9-\uDEE4\uDEEB-\uDEEF\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDD23\uDD30-\uDD39\uDE60-\uDE7E\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF27\uDF30-\uDF45\uDF51-\uDF54\uDF70-\uDF81\uDFB0-\uDFCB\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC52-\uDC6F\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD03-\uDD26\uDD36-\uDD3F\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDD0-\uDDDA\uDDDC\uDDE1-\uDDF4\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDEF0-\uDEF9\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC50-\uDC59\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE50-\uDE59\uDE80-\uDEAA\uDEB8\uDEC0-\uDEC9\uDF00-\uDF1A\uDF30-\uDF3B\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCF2\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC50-\uDC6C\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDA0-\uDDA9\uDEE0-\uDEF2\uDFB0\uDFC0-\uDFD4]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDE70-\uDEBE\uDEC0-\uDEC9\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE96\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD834[\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD837[\uDF00-\uDF1E]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD40-\uDD49\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB\uDEF0-\uDEF9]|\uD839[\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF\uDD00-\uDD43\uDD4B\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF38\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])/))){var r=n[1]||n[2]||"";if(!r||""===u||this.rules.inline.punctuation.exec(u)){var i=n[0].length-1,s=i,l=0,a="*"===n[0][0]?this.rules.inline.emStrong.rDelimAst:this.rules.inline.emStrong.rDelimUnd;for(a.lastIndex=0,t=t.slice(-1*e.length+i);null!=(n=a.exec(t));)if(o=n[1]||n[2]||n[3]||n[4]||n[5]||n[6])if(o=o.length,n[3]||n[4])s+=o;else if((n[5]||n[6])&&i%3&&!((i+o)%3))l+=o;else if(!(0<(s-=o))){var o=Math.min(o,o+s+l);if(Math.min(i,o)%2)return D=e.slice(1,i+n.index+o),{type:"em",raw:e.slice(0,i+n.index+o+1),text:D,tokens:this.lexer.inlineTokens(D,[])};var D=e.slice(2,i+n.index+o-1);return{type:"strong",raw:e.slice(0,i+n.index+o+1),text:D,tokens:this.lexer.inlineTokens(D,[])}}}}},t.codespan=function(e){var t,u,n,e=this.rules.inline.code.exec(e);if(e)return n=e[2].replace(/\n/g," "),t=/[^ ]/.test(n),u=/^ /.test(n)&&/ $/.test(n),n=D(n=t&&u?n.substring(1,n.length-1):n,!0),{type:"codespan",raw:e[0],text:n}},t.br=function(e){e=this.rules.inline.br.exec(e);if(e)return{type:"br",raw:e[0]}},t.del=function(e){e=this.rules.inline.del.exec(e);if(e)return{type:"del",raw:e[0],text:e[2],tokens:this.lexer.inlineTokens(e[2],[])}},t.autolink=function(e,t){var u,e=this.rules.inline.autolink.exec(e);if(e)return t="@"===e[2]?"mailto:"+(u=D(this.options.mangle?t(e[1]):e[1])):u=D(e[1]),{type:"link",raw:e[0],text:u,href:t,tokens:[{type:"text",raw:u,text:u}]}},t.url=function(e,t){var u,n,r,i;if(u=this.rules.inline.url.exec(e)){if("@"===u[2])r="mailto:"+(n=D(this.options.mangle?t(u[0]):u[0]));else{for(;i=u[0],u[0]=this.rules.inline._backpedal.exec(u[0])[0],i!==u[0];);n=D(u[0]),r="www."===u[1]?"http://"+n:n}return{type:"link",raw:u[0],text:n,href:r,tokens:[{type:"text",raw:n,text:n}]}}},t.inlineText=function(e,t){e=this.rules.inline.text.exec(e);if(e)return t=this.lexer.state.inRawBlock?this.options.sanitize?this.options.sanitizer?this.options.sanitizer(e[0]):D(e[0]):e[0]:D(this.options.smartypants?t(e[0]):e[0]),{type:"text",raw:e[0],text:t}},e}(),y={newline:/^(?: *(?:\n|$))+/,code:/^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,fences:/^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/,hr:/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,heading:/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,html:"^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))",def:/^ {0,3}\[(label)\]: *(?:\n *)?]+)>?(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,table:A,lheading:/^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/,_paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,text:/^[^\n]+/,_label:/(?!\s*\])(?:\\.|[^\[\]\\])+/,_title:/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/},v=(y.def=p(y.def).replace("label",y._label).replace("title",y._title).getRegex(),y.bullet=/(?:[*+-]|\d{1,9}[.)])/,y.listItemStart=p(/^( *)(bull) */).replace("bull",y.bullet).getRegex(),y.list=p(y.list).replace(/bull/g,y.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+y.def.source+")").getRegex(),y._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",y._comment=/|$)/,y.html=p(y.html,"i").replace("comment",y._comment).replace("tag",y._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),y.paragraph=p(y._paragraph).replace("hr",y.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",y._tag).getRegex(),y.blockquote=p(y.blockquote).replace("paragraph",y.paragraph).getRegex(),y.normal=d({},y),y.gfm=d({},y.normal,{table:"^ *([^\\n ].*\\|.*)\\n {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"}),y.gfm.table=p(y.gfm.table).replace("hr",y.hr).replace("heading"," {0,3}#{1,6} ").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",y._tag).getRegex(),y.gfm.paragraph=p(y._paragraph).replace("hr",y.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("table",y.gfm.table).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",y._tag).getRegex(),y.pedantic=d({},y.normal,{html:p("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",y._comment).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:A,paragraph:p(y.normal._paragraph).replace("hr",y.hr).replace("heading"," *#{1,6} *[^\n]").replace("lheading",y.lheading).replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").getRegex()}),{escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,autolink:/^<(scheme:[^\s\x00-\x1f<>]*|email)>/,url:A,tag:"^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^",link:/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,reflink:/^!?\[(label)\]\[(ref)\]/,nolink:/^!?\[(ref)\](?:\[\])?/,reflinkSearch:"reflink|nolink(?!\\()",emStrong:{lDelim:/^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,rDelimAst:/^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[^*]+(?=[^*])|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/,rDelimUnd:/^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/},code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,br:/^( {2,}|\\)\n(?!\s*$)/,del:A,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\?@\\[\\]`^{|}~",v.punctuation=p(v.punctuation).replace(/punctuation/g,v._punctuation).getRegex(),v.blockSkip=/\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g,v.escapedEmSt=/\\\*|\\_/g,v._comment=p(y._comment).replace("(?:--\x3e|$)","--\x3e").getRegex(),v.emStrong.lDelim=p(v.emStrong.lDelim).replace(/punct/g,v._punctuation).getRegex(),v.emStrong.rDelimAst=p(v.emStrong.rDelimAst,"g").replace(/punct/g,v._punctuation).getRegex(),v.emStrong.rDelimUnd=p(v.emStrong.rDelimUnd,"g").replace(/punct/g,v._punctuation).getRegex(),v._escapes=/\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g,v._scheme=/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/,v._email=/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/,v.autolink=p(v.autolink).replace("scheme",v._scheme).replace("email",v._email).getRegex(),v._attribute=/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/,v.tag=p(v.tag).replace("comment",v._comment).replace("attribute",v._attribute).getRegex(),v._label=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,v._href=/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/,v._title=/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/,v.link=p(v.link).replace("label",v._label).replace("href",v._href).replace("title",v._title).getRegex(),v.reflink=p(v.reflink).replace("label",v._label).replace("ref",y._label).getRegex(),v.nolink=p(v.nolink).replace("ref",y._label).getRegex(),v.reflinkSearch=p(v.reflinkSearch,"g").replace("reflink",v.reflink).replace("nolink",v.nolink).getRegex(),v.normal=d({},v),v.pedantic=d({},v.normal,{strong:{start:/^__|\*\*/,middle:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,endAst:/\*\*(?!\*)/g,endUnd:/__(?!_)/g},em:{start:/^_|\*/,middle:/^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,endAst:/\*(?!\*)/g,endUnd:/_(?!_)/g},link:p(/^!?\[(label)\]\((.*?)\)/).replace("label",v._label).getRegex(),reflink:p(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",v._label).getRegex()}),v.gfm=d({},v.normal,{escape:p(v.escape).replace("])","~|])").getRegex(),_extended_email:/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,url:/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,_backpedal:/(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\'+(u?e:D(e,!0))+"\n":"
    "+(u?e:D(e,!0))+"
    \n"},t.blockquote=function(e){return"
    \n"+e+"
    \n"},t.html=function(e){return e},t.heading=function(e,t,u,n){return this.options.headerIds?"'+e+"\n":""+e+"\n"},t.hr=function(){return this.options.xhtml?"
    \n":"
    \n"},t.list=function(e,t,u){var n=t?"ol":"ul";return"<"+n+(t&&1!==u?' start="'+u+'"':"")+">\n"+e+"\n"},t.listitem=function(e){return"
  • "+e+"
  • \n"},t.checkbox=function(e){return" "},t.paragraph=function(e){return"

    "+e+"

    \n"},t.table=function(e,t){return"\n\n"+e+"\n"+(t=t&&""+t+"")+"
    \n"},t.tablerow=function(e){return"\n"+e+"\n"},t.tablecell=function(e,t){var u=t.header?"th":"td";return(t.align?"<"+u+' align="'+t.align+'">':"<"+u+">")+e+"\n"},t.strong=function(e){return""+e+""},t.em=function(e){return""+e+""},t.codespan=function(e){return""+e+""},t.br=function(){return this.options.xhtml?"
    ":"
    "},t.del=function(e){return""+e+""},t.link=function(e,t,u){if(null===(e=g(this.options.sanitize,this.options.baseUrl,e)))return u;e='
    "},t.image=function(e,t,u){if(null===(e=g(this.options.sanitize,this.options.baseUrl,e)))return u;e=''+u+'":">"},t.text=function(e){return e},e}(),S=function(){function e(){}var t=e.prototype;return t.strong=function(e){return e},t.em=function(e){return e},t.codespan=function(e){return e},t.del=function(e){return e},t.html=function(e){return e},t.text=function(e){return e},t.link=function(e,t,u){return""+u},t.image=function(e,t,u){return""+u},t.br=function(){return""},e}(),T=function(){function e(){this.seen={}}var t=e.prototype;return t.serialize=function(e){return e.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi,"").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g,"").replace(/\s/g,"-")},t.getNextSafeSlug=function(e,t){var u=e,n=0;if(this.seen.hasOwnProperty(u))for(n=this.seen[e];u=e+"-"+ ++n,this.seen.hasOwnProperty(u););return t||(this.seen[e]=n,this.seen[u]=0),u},t.slug=function(e,t){void 0===t&&(t={});e=this.serialize(e);return this.getNextSafeSlug(e,t.dryrun)},e}(),R=function(){function u(e){this.options=e||r.defaults,this.options.renderer=this.options.renderer||new $,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new S,this.slugger=new T}u.parse=function(e,t){return new u(t).parse(e)},u.parseInline=function(e,t){return new u(t).parseInline(e)};var e=u.prototype;return e.parse=function(e,t){void 0===t&&(t=!0);for(var u,n,r,i,s,l,a,o,D,c,h,p,f,g,F,A,d="",C=e.length,k=0;kAn error occurred:

    "+D(e.message+"",!0)+"
    ";throw e}}I.options=I.setOptions=function(e){return d(I.defaults,e),e=I.defaults,r.defaults=e,I},I.getDefaults=e,I.defaults=r.defaults,I.use=function(){for(var e=arguments.length,t=new Array(e),u=0;uAn error occurred:

    "+D(e.message+"",!0)+"
    ";throw e}},I.Parser=R,I.parser=R.parse,I.Renderer=$,I.TextRenderer=S,I.Lexer=z,I.lexer=z.lex,I.Tokenizer=w,I.Slugger=T;var A=(I.parse=I).options,P=I.setOptions,Q=I.use,U=I.walkTokens,M=I.parseInline,N=I,X=R.parse,G=z.lex;r.Lexer=z,r.Parser=R,r.Renderer=$,r.Slugger=T,r.TextRenderer=S,r.Tokenizer=w,r.getDefaults=e,r.lexer=G,r.marked=I,r.options=A,r.parse=N,r.parseInline=M,r.parser=X,r.setOptions=P,r.use=Q,r.walkTokens=U,Object.defineProperty(r,"__esModule",{value:!0})}); \ No newline at end of file diff --git a/node_modules/marked/package.json b/node_modules/marked/package.json new file mode 100644 index 0000000..fb8659e --- /dev/null +++ b/node_modules/marked/package.json @@ -0,0 +1,97 @@ +{ + "name": "marked", + "description": "A markdown parser built for speed", + "author": "Christopher Jeffrey", + "version": "4.0.17", + "type": "module", + "main": "./lib/marked.cjs", + "module": "./lib/marked.esm.js", + "browser": "./lib/marked.umd.js", + "bin": { + "marked": "bin/marked.js" + }, + "man": "./man/marked.1", + "files": [ + "bin/", + "lib/", + "src/", + "man/", + "marked.min.js" + ], + "exports": { + ".": { + "import": "./lib/marked.esm.js", + "default": "./lib/marked.cjs" + }, + "./package.json": "./package.json" + }, + "repository": "git://github.com/markedjs/marked.git", + "homepage": "https://marked.js.org", + "bugs": { + "url": "http://github.com/markedjs/marked/issues" + }, + "license": "MIT", + "keywords": [ + "markdown", + "markup", + "html" + ], + "tags": [ + "markdown", + "markup", + "html" + ], + "devDependencies": { + "@babel/core": "^7.18.2", + "@babel/preset-env": "^7.18.2", + "@markedjs/html-differ": "^4.0.2", + "@rollup/plugin-babel": "^5.3.1", + "@rollup/plugin-commonjs": "^22.0.0", + "@semantic-release/commit-analyzer": "^9.0.2", + "@semantic-release/git": "^10.0.1", + "@semantic-release/github": "^8.0.4", + "@semantic-release/npm": "^9.0.1", + "@semantic-release/release-notes-generator": "^10.0.3", + "cheerio": "^1.0.0-rc.11", + "commonmark": "0.30.0", + "eslint": "^8.17.0", + "eslint-config-standard": "^17.0.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-n": "^15.2.1", + "eslint-plugin-promise": "^6.0.0", + "front-matter": "^4.0.2", + "highlight.js": "^11.5.1", + "jasmine": "^4.1.0", + "markdown-it": "13.0.1", + "node-fetch": "^3.2.5", + "rollup": "^2.75.5", + "rollup-plugin-license": "^2.8.0", + "semantic-release": "^19.0.3", + "titleize": "^3.0.0", + "uglify-js": "^3.16.0", + "vuln-regex-detector": "^1.3.0" + }, + "scripts": { + "test": "jasmine --config=jasmine.json", + "test:all": "npm test && npm run test:lint", + "test:unit": "npm test -- test/unit/**/*-spec.js", + "test:specs": "npm test -- test/specs/**/*-spec.js", + "test:lint": "eslint .", + "test:redos": "node test/vuln-regex.js", + "test:update": "node test/update-specs.js", + "rules": "node test/rules.js", + "bench": "npm run rollup && node test/bench.js", + "lint": "eslint --fix .", + "build:reset": "git checkout upstream/master lib/marked.cjs lib/marked.umd.js lib/marked.esm.js marked.min.js", + "build": "npm run rollup && npm run minify", + "build:docs": "node build-docs.js", + "rollup": "npm run rollup:umd && npm run rollup:esm", + "rollup:umd": "rollup -c rollup.config.js", + "rollup:esm": "rollup -c rollup.config.esm.js", + "minify": "uglifyjs lib/marked.umd.js -cm --comments /Copyright/ -o marked.min.js", + "preversion": "npm run build && (git diff --quiet || git commit -am build)" + }, + "engines": { + "node": ">= 12" + } +} diff --git a/node_modules/marked/src/Lexer.js b/node_modules/marked/src/Lexer.js new file mode 100644 index 0000000..3c0a2c7 --- /dev/null +++ b/node_modules/marked/src/Lexer.js @@ -0,0 +1,501 @@ +import { Tokenizer } from './Tokenizer.js'; +import { defaults } from './defaults.js'; +import { block, inline } from './rules.js'; +import { repeatString } from './helpers.js'; + +/** + * smartypants text replacement + * @param {string} text + */ +function smartypants(text) { + return text + // em-dashes + .replace(/---/g, '\u2014') + // en-dashes + .replace(/--/g, '\u2013') + // opening singles + .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018') + // closing singles & apostrophes + .replace(/'/g, '\u2019') + // opening doubles + .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c') + // closing doubles + .replace(/"/g, '\u201d') + // ellipses + .replace(/\.{3}/g, '\u2026'); +} + +/** + * mangle email addresses + * @param {string} text + */ +function mangle(text) { + let out = '', + i, + ch; + + const l = text.length; + for (i = 0; i < l; i++) { + ch = text.charCodeAt(i); + if (Math.random() > 0.5) { + ch = 'x' + ch.toString(16); + } + out += '&#' + ch + ';'; + } + + return out; +} + +/** + * Block Lexer + */ +export class Lexer { + constructor(options) { + this.tokens = []; + this.tokens.links = Object.create(null); + this.options = options || defaults; + this.options.tokenizer = this.options.tokenizer || new Tokenizer(); + this.tokenizer = this.options.tokenizer; + this.tokenizer.options = this.options; + this.tokenizer.lexer = this; + this.inlineQueue = []; + this.state = { + inLink: false, + inRawBlock: false, + top: true + }; + + const rules = { + block: block.normal, + inline: inline.normal + }; + + if (this.options.pedantic) { + rules.block = block.pedantic; + rules.inline = inline.pedantic; + } else if (this.options.gfm) { + rules.block = block.gfm; + if (this.options.breaks) { + rules.inline = inline.breaks; + } else { + rules.inline = inline.gfm; + } + } + this.tokenizer.rules = rules; + } + + /** + * Expose Rules + */ + static get rules() { + return { + block, + inline + }; + } + + /** + * Static Lex Method + */ + static lex(src, options) { + const lexer = new Lexer(options); + return lexer.lex(src); + } + + /** + * Static Lex Inline Method + */ + static lexInline(src, options) { + const lexer = new Lexer(options); + return lexer.inlineTokens(src); + } + + /** + * Preprocessing + */ + lex(src) { + src = src + .replace(/\r\n|\r/g, '\n'); + + this.blockTokens(src, this.tokens); + + let next; + while (next = this.inlineQueue.shift()) { + this.inlineTokens(next.src, next.tokens); + } + + return this.tokens; + } + + /** + * Lexing + */ + blockTokens(src, tokens = []) { + if (this.options.pedantic) { + src = src.replace(/\t/g, ' ').replace(/^ +$/gm, ''); + } else { + src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => { + return leading + ' '.repeat(tabs.length); + }); + } + + let token, lastToken, cutSrc, lastParagraphClipped; + + while (src) { + if (this.options.extensions + && this.options.extensions.block + && this.options.extensions.block.some((extTokenizer) => { + if (token = extTokenizer.call({ lexer: this }, src, tokens)) { + src = src.substring(token.raw.length); + tokens.push(token); + return true; + } + return false; + })) { + continue; + } + + // newline + if (token = this.tokenizer.space(src)) { + src = src.substring(token.raw.length); + if (token.raw.length === 1 && tokens.length > 0) { + // if there's a single \n as a spacer, it's terminating the last line, + // so move it there so that we don't get unecessary paragraph tags + tokens[tokens.length - 1].raw += '\n'; + } else { + tokens.push(token); + } + continue; + } + + // code + if (token = this.tokenizer.code(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + // An indented code block cannot interrupt a paragraph. + if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.text; + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else { + tokens.push(token); + } + continue; + } + + // fences + if (token = this.tokenizer.fences(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // heading + if (token = this.tokenizer.heading(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // hr + if (token = this.tokenizer.hr(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // blockquote + if (token = this.tokenizer.blockquote(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // list + if (token = this.tokenizer.list(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // html + if (token = this.tokenizer.html(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // def + if (token = this.tokenizer.def(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.raw; + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else if (!this.tokens.links[token.tag]) { + this.tokens.links[token.tag] = { + href: token.href, + title: token.title + }; + } + continue; + } + + // table (gfm) + if (token = this.tokenizer.table(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // lheading + if (token = this.tokenizer.lheading(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // top-level paragraph + // prevent paragraph consuming extensions by clipping 'src' to extension start + cutSrc = src; + if (this.options.extensions && this.options.extensions.startBlock) { + let startIndex = Infinity; + const tempSrc = src.slice(1); + let tempStart; + this.options.extensions.startBlock.forEach(function(getStartIndex) { + tempStart = getStartIndex.call({ lexer: this }, tempSrc); + if (typeof tempStart === 'number' && tempStart >= 0) { startIndex = Math.min(startIndex, tempStart); } + }); + if (startIndex < Infinity && startIndex >= 0) { + cutSrc = src.substring(0, startIndex + 1); + } + } + if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) { + lastToken = tokens[tokens.length - 1]; + if (lastParagraphClipped && lastToken.type === 'paragraph') { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.text; + this.inlineQueue.pop(); + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else { + tokens.push(token); + } + lastParagraphClipped = (cutSrc.length !== src.length); + src = src.substring(token.raw.length); + continue; + } + + // text + if (token = this.tokenizer.text(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + if (lastToken && lastToken.type === 'text') { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.text; + this.inlineQueue.pop(); + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else { + tokens.push(token); + } + continue; + } + + if (src) { + const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0); + if (this.options.silent) { + console.error(errMsg); + break; + } else { + throw new Error(errMsg); + } + } + } + + this.state.top = true; + return tokens; + } + + inline(src, tokens) { + this.inlineQueue.push({ src, tokens }); + } + + /** + * Lexing/Compiling + */ + inlineTokens(src, tokens = []) { + let token, lastToken, cutSrc; + + // String with links masked to avoid interference with em and strong + let maskedSrc = src; + let match; + let keepPrevChar, prevChar; + + // Mask out reflinks + if (this.tokens.links) { + const links = Object.keys(this.tokens.links); + if (links.length > 0) { + while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) { + if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) { + maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex); + } + } + } + } + // Mask out other blocks + while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) { + maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex); + } + + // Mask out escaped em & strong delimiters + while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) { + maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex); + } + + while (src) { + if (!keepPrevChar) { + prevChar = ''; + } + keepPrevChar = false; + + // extensions + if (this.options.extensions + && this.options.extensions.inline + && this.options.extensions.inline.some((extTokenizer) => { + if (token = extTokenizer.call({ lexer: this }, src, tokens)) { + src = src.substring(token.raw.length); + tokens.push(token); + return true; + } + return false; + })) { + continue; + } + + // escape + if (token = this.tokenizer.escape(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // tag + if (token = this.tokenizer.tag(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + if (lastToken && token.type === 'text' && lastToken.type === 'text') { + lastToken.raw += token.raw; + lastToken.text += token.text; + } else { + tokens.push(token); + } + continue; + } + + // link + if (token = this.tokenizer.link(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // reflink, nolink + if (token = this.tokenizer.reflink(src, this.tokens.links)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + if (lastToken && token.type === 'text' && lastToken.type === 'text') { + lastToken.raw += token.raw; + lastToken.text += token.text; + } else { + tokens.push(token); + } + continue; + } + + // em & strong + if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // code + if (token = this.tokenizer.codespan(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // br + if (token = this.tokenizer.br(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // del (gfm) + if (token = this.tokenizer.del(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // autolink + if (token = this.tokenizer.autolink(src, mangle)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // url (gfm) + if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + + // text + // prevent inlineText consuming extensions by clipping 'src' to extension start + cutSrc = src; + if (this.options.extensions && this.options.extensions.startInline) { + let startIndex = Infinity; + const tempSrc = src.slice(1); + let tempStart; + this.options.extensions.startInline.forEach(function(getStartIndex) { + tempStart = getStartIndex.call({ lexer: this }, tempSrc); + if (typeof tempStart === 'number' && tempStart >= 0) { startIndex = Math.min(startIndex, tempStart); } + }); + if (startIndex < Infinity && startIndex >= 0) { + cutSrc = src.substring(0, startIndex + 1); + } + } + if (token = this.tokenizer.inlineText(cutSrc, smartypants)) { + src = src.substring(token.raw.length); + if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started + prevChar = token.raw.slice(-1); + } + keepPrevChar = true; + lastToken = tokens[tokens.length - 1]; + if (lastToken && lastToken.type === 'text') { + lastToken.raw += token.raw; + lastToken.text += token.text; + } else { + tokens.push(token); + } + continue; + } + + if (src) { + const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0); + if (this.options.silent) { + console.error(errMsg); + break; + } else { + throw new Error(errMsg); + } + } + } + + return tokens; + } +} diff --git a/node_modules/marked/src/Parser.js b/node_modules/marked/src/Parser.js new file mode 100644 index 0000000..a22a2bc --- /dev/null +++ b/node_modules/marked/src/Parser.js @@ -0,0 +1,286 @@ +import { Renderer } from './Renderer.js'; +import { TextRenderer } from './TextRenderer.js'; +import { Slugger } from './Slugger.js'; +import { defaults } from './defaults.js'; +import { + unescape +} from './helpers.js'; + +/** + * Parsing & Compiling + */ +export class Parser { + constructor(options) { + this.options = options || defaults; + this.options.renderer = this.options.renderer || new Renderer(); + this.renderer = this.options.renderer; + this.renderer.options = this.options; + this.textRenderer = new TextRenderer(); + this.slugger = new Slugger(); + } + + /** + * Static Parse Method + */ + static parse(tokens, options) { + const parser = new Parser(options); + return parser.parse(tokens); + } + + /** + * Static Parse Inline Method + */ + static parseInline(tokens, options) { + const parser = new Parser(options); + return parser.parseInline(tokens); + } + + /** + * Parse Loop + */ + parse(tokens, top = true) { + let out = '', + i, + j, + k, + l2, + l3, + row, + cell, + header, + body, + token, + ordered, + start, + loose, + itemBody, + item, + checked, + task, + checkbox, + ret; + + const l = tokens.length; + for (i = 0; i < l; i++) { + token = tokens[i]; + + // Run any renderer extensions + if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { + ret = this.options.extensions.renderers[token.type].call({ parser: this }, token); + if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) { + out += ret || ''; + continue; + } + } + + switch (token.type) { + case 'space': { + continue; + } + case 'hr': { + out += this.renderer.hr(); + continue; + } + case 'heading': { + out += this.renderer.heading( + this.parseInline(token.tokens), + token.depth, + unescape(this.parseInline(token.tokens, this.textRenderer)), + this.slugger); + continue; + } + case 'code': { + out += this.renderer.code(token.text, + token.lang, + token.escaped); + continue; + } + case 'table': { + header = ''; + + // header + cell = ''; + l2 = token.header.length; + for (j = 0; j < l2; j++) { + cell += this.renderer.tablecell( + this.parseInline(token.header[j].tokens), + { header: true, align: token.align[j] } + ); + } + header += this.renderer.tablerow(cell); + + body = ''; + l2 = token.rows.length; + for (j = 0; j < l2; j++) { + row = token.rows[j]; + + cell = ''; + l3 = row.length; + for (k = 0; k < l3; k++) { + cell += this.renderer.tablecell( + this.parseInline(row[k].tokens), + { header: false, align: token.align[k] } + ); + } + + body += this.renderer.tablerow(cell); + } + out += this.renderer.table(header, body); + continue; + } + case 'blockquote': { + body = this.parse(token.tokens); + out += this.renderer.blockquote(body); + continue; + } + case 'list': { + ordered = token.ordered; + start = token.start; + loose = token.loose; + l2 = token.items.length; + + body = ''; + for (j = 0; j < l2; j++) { + item = token.items[j]; + checked = item.checked; + task = item.task; + + itemBody = ''; + if (item.task) { + checkbox = this.renderer.checkbox(checked); + if (loose) { + if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') { + item.tokens[0].text = checkbox + ' ' + item.tokens[0].text; + if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') { + item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text; + } + } else { + item.tokens.unshift({ + type: 'text', + text: checkbox + }); + } + } else { + itemBody += checkbox; + } + } + + itemBody += this.parse(item.tokens, loose); + body += this.renderer.listitem(itemBody, task, checked); + } + + out += this.renderer.list(body, ordered, start); + continue; + } + case 'html': { + // TODO parse inline content if parameter markdown=1 + out += this.renderer.html(token.text); + continue; + } + case 'paragraph': { + out += this.renderer.paragraph(this.parseInline(token.tokens)); + continue; + } + case 'text': { + body = token.tokens ? this.parseInline(token.tokens) : token.text; + while (i + 1 < l && tokens[i + 1].type === 'text') { + token = tokens[++i]; + body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text); + } + out += top ? this.renderer.paragraph(body) : body; + continue; + } + + default: { + const errMsg = 'Token with "' + token.type + '" type was not found.'; + if (this.options.silent) { + console.error(errMsg); + return; + } else { + throw new Error(errMsg); + } + } + } + } + + return out; + } + + /** + * Parse Inline Tokens + */ + parseInline(tokens, renderer) { + renderer = renderer || this.renderer; + let out = '', + i, + token, + ret; + + const l = tokens.length; + for (i = 0; i < l; i++) { + token = tokens[i]; + + // Run any renderer extensions + if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { + ret = this.options.extensions.renderers[token.type].call({ parser: this }, token); + if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) { + out += ret || ''; + continue; + } + } + + switch (token.type) { + case 'escape': { + out += renderer.text(token.text); + break; + } + case 'html': { + out += renderer.html(token.text); + break; + } + case 'link': { + out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer)); + break; + } + case 'image': { + out += renderer.image(token.href, token.title, token.text); + break; + } + case 'strong': { + out += renderer.strong(this.parseInline(token.tokens, renderer)); + break; + } + case 'em': { + out += renderer.em(this.parseInline(token.tokens, renderer)); + break; + } + case 'codespan': { + out += renderer.codespan(token.text); + break; + } + case 'br': { + out += renderer.br(); + break; + } + case 'del': { + out += renderer.del(this.parseInline(token.tokens, renderer)); + break; + } + case 'text': { + out += renderer.text(token.text); + break; + } + default: { + const errMsg = 'Token with "' + token.type + '" type was not found.'; + if (this.options.silent) { + console.error(errMsg); + return; + } else { + throw new Error(errMsg); + } + } + } + } + return out; + } +} diff --git a/node_modules/marked/src/Renderer.js b/node_modules/marked/src/Renderer.js new file mode 100644 index 0000000..7c36a75 --- /dev/null +++ b/node_modules/marked/src/Renderer.js @@ -0,0 +1,203 @@ +import { defaults } from './defaults.js'; +import { + cleanUrl, + escape +} from './helpers.js'; + +/** + * Renderer + */ +export class Renderer { + constructor(options) { + this.options = options || defaults; + } + + code(code, infostring, escaped) { + const lang = (infostring || '').match(/\S*/)[0]; + if (this.options.highlight) { + const out = this.options.highlight(code, lang); + if (out != null && out !== code) { + escaped = true; + code = out; + } + } + + code = code.replace(/\n$/, '') + '\n'; + + if (!lang) { + return '
    '
    +        + (escaped ? code : escape(code, true))
    +        + '
    \n'; + } + + return '
    '
    +      + (escaped ? code : escape(code, true))
    +      + '
    \n'; + } + + /** + * @param {string} quote + */ + blockquote(quote) { + return `
    \n${quote}
    \n`; + } + + html(html) { + return html; + } + + /** + * @param {string} text + * @param {string} level + * @param {string} raw + * @param {any} slugger + */ + heading(text, level, raw, slugger) { + if (this.options.headerIds) { + const id = this.options.headerPrefix + slugger.slug(raw); + return `${text}\n`; + } + + // ignore IDs + return `${text}\n`; + } + + hr() { + return this.options.xhtml ? '
    \n' : '
    \n'; + } + + list(body, ordered, start) { + const type = ordered ? 'ol' : 'ul', + startatt = (ordered && start !== 1) ? (' start="' + start + '"') : ''; + return '<' + type + startatt + '>\n' + body + '\n'; + } + + /** + * @param {string} text + */ + listitem(text) { + return `
  • ${text}
  • \n`; + } + + checkbox(checked) { + return ' '; + } + + /** + * @param {string} text + */ + paragraph(text) { + return `

    ${text}

    \n`; + } + + /** + * @param {string} header + * @param {string} body + */ + table(header, body) { + if (body) body = `${body}`; + + return '\n' + + '\n' + + header + + '\n' + + body + + '
    \n'; + } + + /** + * @param {string} content + */ + tablerow(content) { + return `\n${content}\n`; + } + + tablecell(content, flags) { + const type = flags.header ? 'th' : 'td'; + const tag = flags.align + ? `<${type} align="${flags.align}">` + : `<${type}>`; + return tag + content + `\n`; + } + + /** + * span level renderer + * @param {string} text + */ + strong(text) { + return `${text}`; + } + + /** + * @param {string} text + */ + em(text) { + return `${text}`; + } + + /** + * @param {string} text + */ + codespan(text) { + return `${text}`; + } + + br() { + return this.options.xhtml ? '
    ' : '
    '; + } + + /** + * @param {string} text + */ + del(text) { + return `${text}`; + } + + /** + * @param {string} href + * @param {string} title + * @param {string} text + */ + link(href, title, text) { + href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); + if (href === null) { + return text; + } + let out = '
    '; + return out; + } + + /** + * @param {string} href + * @param {string} title + * @param {string} text + */ + image(href, title, text) { + href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); + if (href === null) { + return text; + } + + let out = `${text}' : '>'; + return out; + } + + text(text) { + return text; + } +} diff --git a/node_modules/marked/src/Slugger.js b/node_modules/marked/src/Slugger.js new file mode 100644 index 0000000..a0b68f5 --- /dev/null +++ b/node_modules/marked/src/Slugger.js @@ -0,0 +1,55 @@ +/** + * Slugger generates header id + */ +export class Slugger { + constructor() { + this.seen = {}; + } + + /** + * @param {string} value + */ + serialize(value) { + return value + .toLowerCase() + .trim() + // remove html tags + .replace(/<[!\/a-z].*?>/ig, '') + // remove unwanted chars + .replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '') + .replace(/\s/g, '-'); + } + + /** + * Finds the next safe (unique) slug to use + * @param {string} originalSlug + * @param {boolean} isDryRun + */ + getNextSafeSlug(originalSlug, isDryRun) { + let slug = originalSlug; + let occurenceAccumulator = 0; + if (this.seen.hasOwnProperty(slug)) { + occurenceAccumulator = this.seen[originalSlug]; + do { + occurenceAccumulator++; + slug = originalSlug + '-' + occurenceAccumulator; + } while (this.seen.hasOwnProperty(slug)); + } + if (!isDryRun) { + this.seen[originalSlug] = occurenceAccumulator; + this.seen[slug] = 0; + } + return slug; + } + + /** + * Convert string to unique id + * @param {object} [options] + * @param {boolean} [options.dryrun] Generates the next unique slug without + * updating the internal accumulator. + */ + slug(value, options = {}) { + const slug = this.serialize(value); + return this.getNextSafeSlug(slug, options.dryrun); + } +} diff --git a/node_modules/marked/src/TextRenderer.js b/node_modules/marked/src/TextRenderer.js new file mode 100644 index 0000000..4d6e08f --- /dev/null +++ b/node_modules/marked/src/TextRenderer.js @@ -0,0 +1,42 @@ +/** + * TextRenderer + * returns only the textual part of the token + */ +export class TextRenderer { + // no need for block level renderers + strong(text) { + return text; + } + + em(text) { + return text; + } + + codespan(text) { + return text; + } + + del(text) { + return text; + } + + html(text) { + return text; + } + + text(text) { + return text; + } + + link(href, title, text) { + return '' + text; + } + + image(href, title, text) { + return '' + text; + } + + br() { + return ''; + } +} diff --git a/node_modules/marked/src/Tokenizer.js b/node_modules/marked/src/Tokenizer.js new file mode 100644 index 0000000..0f77a01 --- /dev/null +++ b/node_modules/marked/src/Tokenizer.js @@ -0,0 +1,784 @@ +import { defaults } from './defaults.js'; +import { + rtrim, + splitCells, + escape, + findClosingBracket +} from './helpers.js'; + +function outputLink(cap, link, raw, lexer) { + const href = link.href; + const title = link.title ? escape(link.title) : null; + const text = cap[1].replace(/\\([\[\]])/g, '$1'); + + if (cap[0].charAt(0) !== '!') { + lexer.state.inLink = true; + const token = { + type: 'link', + raw, + href, + title, + text, + tokens: lexer.inlineTokens(text, []) + }; + lexer.state.inLink = false; + return token; + } + return { + type: 'image', + raw, + href, + title, + text: escape(text) + }; +} + +function indentCodeCompensation(raw, text) { + const matchIndentToCode = raw.match(/^(\s+)(?:```)/); + + if (matchIndentToCode === null) { + return text; + } + + const indentToCode = matchIndentToCode[1]; + + return text + .split('\n') + .map(node => { + const matchIndentInNode = node.match(/^\s+/); + if (matchIndentInNode === null) { + return node; + } + + const [indentInNode] = matchIndentInNode; + + if (indentInNode.length >= indentToCode.length) { + return node.slice(indentToCode.length); + } + + return node; + }) + .join('\n'); +} + +/** + * Tokenizer + */ +export class Tokenizer { + constructor(options) { + this.options = options || defaults; + } + + space(src) { + const cap = this.rules.block.newline.exec(src); + if (cap && cap[0].length > 0) { + return { + type: 'space', + raw: cap[0] + }; + } + } + + code(src) { + const cap = this.rules.block.code.exec(src); + if (cap) { + const text = cap[0].replace(/^ {1,4}/gm, ''); + return { + type: 'code', + raw: cap[0], + codeBlockStyle: 'indented', + text: !this.options.pedantic + ? rtrim(text, '\n') + : text + }; + } + } + + fences(src) { + const cap = this.rules.block.fences.exec(src); + if (cap) { + const raw = cap[0]; + const text = indentCodeCompensation(raw, cap[3] || ''); + + return { + type: 'code', + raw, + lang: cap[2] ? cap[2].trim() : cap[2], + text + }; + } + } + + heading(src) { + const cap = this.rules.block.heading.exec(src); + if (cap) { + let text = cap[2].trim(); + + // remove trailing #s + if (/#$/.test(text)) { + const trimmed = rtrim(text, '#'); + if (this.options.pedantic) { + text = trimmed.trim(); + } else if (!trimmed || / $/.test(trimmed)) { + // CommonMark requires space before trailing #s + text = trimmed.trim(); + } + } + + const token = { + type: 'heading', + raw: cap[0], + depth: cap[1].length, + text, + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + } + + hr(src) { + const cap = this.rules.block.hr.exec(src); + if (cap) { + return { + type: 'hr', + raw: cap[0] + }; + } + } + + blockquote(src) { + const cap = this.rules.block.blockquote.exec(src); + if (cap) { + const text = cap[0].replace(/^ *>[ \t]?/gm, ''); + + return { + type: 'blockquote', + raw: cap[0], + tokens: this.lexer.blockTokens(text, []), + text + }; + } + } + + list(src) { + let cap = this.rules.block.list.exec(src); + if (cap) { + let raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, + line, nextLine, rawLine, itemContents, endEarly; + + let bull = cap[1].trim(); + const isordered = bull.length > 1; + + const list = { + type: 'list', + raw: '', + ordered: isordered, + start: isordered ? +bull.slice(0, -1) : '', + loose: false, + items: [] + }; + + bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`; + + if (this.options.pedantic) { + bull = isordered ? bull : '[*+-]'; + } + + // Get next list item + const itemRegex = new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`); + + // Check if current bullet point can start a new List Item + while (src) { + endEarly = false; + if (!(cap = itemRegex.exec(src))) { + break; + } + + if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?) + break; + } + + raw = cap[0]; + src = src.substring(raw.length); + + line = cap[2].split('\n', 1)[0]; + nextLine = src.split('\n', 1)[0]; + + if (this.options.pedantic) { + indent = 2; + itemContents = line.trimLeft(); + } else { + indent = cap[2].search(/[^ ]/); // Find first non-space char + indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent + itemContents = line.slice(indent); + indent += cap[1].length; + } + + blankLine = false; + + if (!line && /^ *$/.test(nextLine)) { // Items begin with at most one blank line + raw += nextLine + '\n'; + src = src.substring(nextLine.length + 1); + endEarly = true; + } + + if (!endEarly) { + const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?: [^\\n]*)?(?:\\n|$))`); + const hrRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`); + const fencesBeginRegex = new RegExp(`^( {0,${Math.min(3, indent - 1)}})(\`\`\`|~~~)`); + + // Check if following lines should be included in List Item + while (src) { + rawLine = src.split('\n', 1)[0]; + line = rawLine; + + // Re-align to follow commonmark nesting rules + if (this.options.pedantic) { + line = line.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' '); + } + + // End list item if found code fences + if (fencesBeginRegex.test(line)) { + break; + } + + // End list item if found start of new heading + if (this.rules.block.heading.test(line)) { + break; + } + + // End list item if found start of new bullet + if (nextBulletRegex.test(line)) { + break; + } + + // Horizontal rule found + if (hrRegex.test(src)) { + break; + } + + if (line.search(/[^ ]/) >= indent || !line.trim()) { // Dedent if possible + itemContents += '\n' + line.slice(indent); + } else if (!blankLine) { // Until blank line, item doesn't need indentation + itemContents += '\n' + line; + } else { // Otherwise, improper indentation ends this item + break; + } + + if (!blankLine && !line.trim()) { // Check if current line is blank + blankLine = true; + } + + raw += rawLine + '\n'; + src = src.substring(rawLine.length + 1); + } + } + + if (!list.loose) { + // If the previous item ended with a blank line, the list is loose + if (endsWithBlankLine) { + list.loose = true; + } else if (/\n *\n *$/.test(raw)) { + endsWithBlankLine = true; + } + } + + // Check for task list items + if (this.options.gfm) { + istask = /^\[[ xX]\] /.exec(itemContents); + if (istask) { + ischecked = istask[0] !== '[ ] '; + itemContents = itemContents.replace(/^\[[ xX]\] +/, ''); + } + } + + list.items.push({ + type: 'list_item', + raw, + task: !!istask, + checked: ischecked, + loose: false, + text: itemContents + }); + + list.raw += raw; + } + + // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic + list.items[list.items.length - 1].raw = raw.trimRight(); + list.items[list.items.length - 1].text = itemContents.trimRight(); + list.raw = list.raw.trimRight(); + + const l = list.items.length; + + // Item child tokens handled here at end because we needed to have the final item to trim it first + for (i = 0; i < l; i++) { + this.lexer.state.top = false; + list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []); + const spacers = list.items[i].tokens.filter(t => t.type === 'space'); + const hasMultipleLineBreaks = spacers.every(t => { + const chars = t.raw.split(''); + let lineBreaks = 0; + for (const char of chars) { + if (char === '\n') { + lineBreaks += 1; + } + if (lineBreaks > 1) { + return true; + } + } + + return false; + }); + + if (!list.loose && spacers.length && hasMultipleLineBreaks) { + // Having a single line break doesn't mean a list is loose. A single line break is terminating the last list item + list.loose = true; + list.items[i].loose = true; + } + } + + return list; + } + } + + html(src) { + const cap = this.rules.block.html.exec(src); + if (cap) { + const token = { + type: 'html', + raw: cap[0], + pre: !this.options.sanitizer + && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'), + text: cap[0] + }; + if (this.options.sanitize) { + token.type = 'paragraph'; + token.text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]); + token.tokens = []; + this.lexer.inline(token.text, token.tokens); + } + return token; + } + } + + def(src) { + const cap = this.rules.block.def.exec(src); + if (cap) { + if (cap[3]) cap[3] = cap[3].substring(1, cap[3].length - 1); + const tag = cap[1].toLowerCase().replace(/\s+/g, ' '); + return { + type: 'def', + tag, + raw: cap[0], + href: cap[2], + title: cap[3] + }; + } + } + + table(src) { + const cap = this.rules.block.table.exec(src); + if (cap) { + const item = { + type: 'table', + header: splitCells(cap[1]).map(c => { return { text: c }; }), + align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), + rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : [] + }; + + if (item.header.length === item.align.length) { + item.raw = cap[0]; + + let l = item.align.length; + let i, j, k, row; + for (i = 0; i < l; i++) { + if (/^ *-+: *$/.test(item.align[i])) { + item.align[i] = 'right'; + } else if (/^ *:-+: *$/.test(item.align[i])) { + item.align[i] = 'center'; + } else if (/^ *:-+ *$/.test(item.align[i])) { + item.align[i] = 'left'; + } else { + item.align[i] = null; + } + } + + l = item.rows.length; + for (i = 0; i < l; i++) { + item.rows[i] = splitCells(item.rows[i], item.header.length).map(c => { return { text: c }; }); + } + + // parse child tokens inside headers and cells + + // header child tokens + l = item.header.length; + for (j = 0; j < l; j++) { + item.header[j].tokens = []; + this.lexer.inline(item.header[j].text, item.header[j].tokens); + } + + // cell child tokens + l = item.rows.length; + for (j = 0; j < l; j++) { + row = item.rows[j]; + for (k = 0; k < row.length; k++) { + row[k].tokens = []; + this.lexer.inline(row[k].text, row[k].tokens); + } + } + + return item; + } + } + } + + lheading(src) { + const cap = this.rules.block.lheading.exec(src); + if (cap) { + const token = { + type: 'heading', + raw: cap[0], + depth: cap[2].charAt(0) === '=' ? 1 : 2, + text: cap[1], + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + } + + paragraph(src) { + const cap = this.rules.block.paragraph.exec(src); + if (cap) { + const token = { + type: 'paragraph', + raw: cap[0], + text: cap[1].charAt(cap[1].length - 1) === '\n' + ? cap[1].slice(0, -1) + : cap[1], + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + } + + text(src) { + const cap = this.rules.block.text.exec(src); + if (cap) { + const token = { + type: 'text', + raw: cap[0], + text: cap[0], + tokens: [] + }; + this.lexer.inline(token.text, token.tokens); + return token; + } + } + + escape(src) { + const cap = this.rules.inline.escape.exec(src); + if (cap) { + return { + type: 'escape', + raw: cap[0], + text: escape(cap[1]) + }; + } + } + + tag(src) { + const cap = this.rules.inline.tag.exec(src); + if (cap) { + if (!this.lexer.state.inLink && /^/i.test(cap[0])) { + this.lexer.state.inLink = false; + } + if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { + this.lexer.state.inRawBlock = true; + } else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { + this.lexer.state.inRawBlock = false; + } + + return { + type: this.options.sanitize + ? 'text' + : 'html', + raw: cap[0], + inLink: this.lexer.state.inLink, + inRawBlock: this.lexer.state.inRawBlock, + text: this.options.sanitize + ? (this.options.sanitizer + ? this.options.sanitizer(cap[0]) + : escape(cap[0])) + : cap[0] + }; + } + } + + link(src) { + const cap = this.rules.inline.link.exec(src); + if (cap) { + const trimmedUrl = cap[2].trim(); + if (!this.options.pedantic && /^$/.test(trimmedUrl))) { + return; + } + + // ending angle bracket cannot be escaped + const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\'); + if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) { + return; + } + } else { + // find closing parenthesis + const lastParenIndex = findClosingBracket(cap[2], '()'); + if (lastParenIndex > -1) { + const start = cap[0].indexOf('!') === 0 ? 5 : 4; + const linkLen = start + cap[1].length + lastParenIndex; + cap[2] = cap[2].substring(0, lastParenIndex); + cap[0] = cap[0].substring(0, linkLen).trim(); + cap[3] = ''; + } + } + let href = cap[2]; + let title = ''; + if (this.options.pedantic) { + // split pedantic href and title + const link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href); + + if (link) { + href = link[1]; + title = link[3]; + } + } else { + title = cap[3] ? cap[3].slice(1, -1) : ''; + } + + href = href.trim(); + if (/^$/.test(trimmedUrl))) { + // pedantic allows starting angle bracket without ending angle bracket + href = href.slice(1); + } else { + href = href.slice(1, -1); + } + } + return outputLink(cap, { + href: href ? href.replace(this.rules.inline._escapes, '$1') : href, + title: title ? title.replace(this.rules.inline._escapes, '$1') : title + }, cap[0], this.lexer); + } + } + + reflink(src, links) { + let cap; + if ((cap = this.rules.inline.reflink.exec(src)) + || (cap = this.rules.inline.nolink.exec(src))) { + let link = (cap[2] || cap[1]).replace(/\s+/g, ' '); + link = links[link.toLowerCase()]; + if (!link || !link.href) { + const text = cap[0].charAt(0); + return { + type: 'text', + raw: text, + text + }; + } + return outputLink(cap, link, cap[0], this.lexer); + } + } + + emStrong(src, maskedSrc, prevChar = '') { + let match = this.rules.inline.emStrong.lDelim.exec(src); + if (!match) return; + + // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well + if (match[3] && prevChar.match(/[\p{L}\p{N}]/u)) return; + + const nextChar = match[1] || match[2] || ''; + + if (!nextChar || (nextChar && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar)))) { + const lLength = match[0].length - 1; + let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0; + + const endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd; + endReg.lastIndex = 0; + + // Clip maskedSrc to same section of string as src (move to lexer?) + maskedSrc = maskedSrc.slice(-1 * src.length + lLength); + + while ((match = endReg.exec(maskedSrc)) != null) { + rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6]; + + if (!rDelim) continue; // skip single * in __abc*abc__ + + rLength = rDelim.length; + + if (match[3] || match[4]) { // found another Left Delim + delimTotal += rLength; + continue; + } else if (match[5] || match[6]) { // either Left or Right Delim + if (lLength % 3 && !((lLength + rLength) % 3)) { + midDelimTotal += rLength; + continue; // CommonMark Emphasis Rules 9-10 + } + } + + delimTotal -= rLength; + + if (delimTotal > 0) continue; // Haven't found enough closing delimiters + + // Remove extra characters. *a*** -> *a* + rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal); + + // Create `em` if smallest delimiter has odd char count. *a*** + if (Math.min(lLength, rLength) % 2) { + const text = src.slice(1, lLength + match.index + rLength); + return { + type: 'em', + raw: src.slice(0, lLength + match.index + rLength + 1), + text, + tokens: this.lexer.inlineTokens(text, []) + }; + } + + // Create 'strong' if smallest delimiter has even char count. **a*** + const text = src.slice(2, lLength + match.index + rLength - 1); + return { + type: 'strong', + raw: src.slice(0, lLength + match.index + rLength + 1), + text, + tokens: this.lexer.inlineTokens(text, []) + }; + } + } + } + + codespan(src) { + const cap = this.rules.inline.code.exec(src); + if (cap) { + let text = cap[2].replace(/\n/g, ' '); + const hasNonSpaceChars = /[^ ]/.test(text); + const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text); + if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) { + text = text.substring(1, text.length - 1); + } + text = escape(text, true); + return { + type: 'codespan', + raw: cap[0], + text + }; + } + } + + br(src) { + const cap = this.rules.inline.br.exec(src); + if (cap) { + return { + type: 'br', + raw: cap[0] + }; + } + } + + del(src) { + const cap = this.rules.inline.del.exec(src); + if (cap) { + return { + type: 'del', + raw: cap[0], + text: cap[2], + tokens: this.lexer.inlineTokens(cap[2], []) + }; + } + } + + autolink(src, mangle) { + const cap = this.rules.inline.autolink.exec(src); + if (cap) { + let text, href; + if (cap[2] === '@') { + text = escape(this.options.mangle ? mangle(cap[1]) : cap[1]); + href = 'mailto:' + text; + } else { + text = escape(cap[1]); + href = text; + } + + return { + type: 'link', + raw: cap[0], + text, + href, + tokens: [ + { + type: 'text', + raw: text, + text + } + ] + }; + } + } + + url(src, mangle) { + let cap; + if (cap = this.rules.inline.url.exec(src)) { + let text, href; + if (cap[2] === '@') { + text = escape(this.options.mangle ? mangle(cap[0]) : cap[0]); + href = 'mailto:' + text; + } else { + // do extended autolink path validation + let prevCapZero; + do { + prevCapZero = cap[0]; + cap[0] = this.rules.inline._backpedal.exec(cap[0])[0]; + } while (prevCapZero !== cap[0]); + text = escape(cap[0]); + if (cap[1] === 'www.') { + href = 'http://' + text; + } else { + href = text; + } + } + return { + type: 'link', + raw: cap[0], + text, + href, + tokens: [ + { + type: 'text', + raw: text, + text + } + ] + }; + } + } + + inlineText(src, smartypants) { + const cap = this.rules.inline.text.exec(src); + if (cap) { + let text; + if (this.lexer.state.inRawBlock) { + text = this.options.sanitize ? (this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0])) : cap[0]; + } else { + text = escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]); + } + return { + type: 'text', + raw: cap[0], + text + }; + } + } +} diff --git a/node_modules/marked/src/defaults.js b/node_modules/marked/src/defaults.js new file mode 100644 index 0000000..3a68802 --- /dev/null +++ b/node_modules/marked/src/defaults.js @@ -0,0 +1,29 @@ +export function getDefaults() { + return { + baseUrl: null, + breaks: false, + extensions: null, + gfm: true, + headerIds: true, + headerPrefix: '', + highlight: null, + langPrefix: 'language-', + mangle: true, + pedantic: false, + renderer: null, + sanitize: false, + sanitizer: null, + silent: false, + smartLists: false, + smartypants: false, + tokenizer: null, + walkTokens: null, + xhtml: false + }; +} + +export let defaults = getDefaults(); + +export function changeDefaults(newDefaults) { + defaults = newDefaults; +} diff --git a/node_modules/marked/src/helpers.js b/node_modules/marked/src/helpers.js new file mode 100644 index 0000000..600c95e --- /dev/null +++ b/node_modules/marked/src/helpers.js @@ -0,0 +1,276 @@ +/** + * Helpers + */ +const escapeTest = /[&<>"']/; +const escapeReplace = /[&<>"']/g; +const escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/; +const escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g; +const escapeReplacements = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' +}; +const getEscapeReplacement = (ch) => escapeReplacements[ch]; +export function escape(html, encode) { + if (encode) { + if (escapeTest.test(html)) { + return html.replace(escapeReplace, getEscapeReplacement); + } + } else { + if (escapeTestNoEncode.test(html)) { + return html.replace(escapeReplaceNoEncode, getEscapeReplacement); + } + } + + return html; +} + +const unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig; + +/** + * @param {string} html + */ +export function unescape(html) { + // explicitly match decimal, hex, and named HTML entities + return html.replace(unescapeTest, (_, n) => { + n = n.toLowerCase(); + if (n === 'colon') return ':'; + if (n.charAt(0) === '#') { + return n.charAt(1) === 'x' + ? String.fromCharCode(parseInt(n.substring(2), 16)) + : String.fromCharCode(+n.substring(1)); + } + return ''; + }); +} + +const caret = /(^|[^\[])\^/g; + +/** + * @param {string | RegExp} regex + * @param {string} opt + */ +export function edit(regex, opt) { + regex = typeof regex === 'string' ? regex : regex.source; + opt = opt || ''; + const obj = { + replace: (name, val) => { + val = val.source || val; + val = val.replace(caret, '$1'); + regex = regex.replace(name, val); + return obj; + }, + getRegex: () => { + return new RegExp(regex, opt); + } + }; + return obj; +} + +const nonWordAndColonTest = /[^\w:]/g; +const originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i; + +/** + * @param {boolean} sanitize + * @param {string} base + * @param {string} href + */ +export function cleanUrl(sanitize, base, href) { + if (sanitize) { + let prot; + try { + prot = decodeURIComponent(unescape(href)) + .replace(nonWordAndColonTest, '') + .toLowerCase(); + } catch (e) { + return null; + } + if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) { + return null; + } + } + if (base && !originIndependentUrl.test(href)) { + href = resolveUrl(base, href); + } + try { + href = encodeURI(href).replace(/%25/g, '%'); + } catch (e) { + return null; + } + return href; +} + +const baseUrls = {}; +const justDomain = /^[^:]+:\/*[^/]*$/; +const protocol = /^([^:]+:)[\s\S]*$/; +const domain = /^([^:]+:\/*[^/]*)[\s\S]*$/; + +/** + * @param {string} base + * @param {string} href + */ +export function resolveUrl(base, href) { + if (!baseUrls[' ' + base]) { + // we can ignore everything in base after the last slash of its path component, + // but we might need to add _that_ + // https://tools.ietf.org/html/rfc3986#section-3 + if (justDomain.test(base)) { + baseUrls[' ' + base] = base + '/'; + } else { + baseUrls[' ' + base] = rtrim(base, '/', true); + } + } + base = baseUrls[' ' + base]; + const relativeBase = base.indexOf(':') === -1; + + if (href.substring(0, 2) === '//') { + if (relativeBase) { + return href; + } + return base.replace(protocol, '$1') + href; + } else if (href.charAt(0) === '/') { + if (relativeBase) { + return href; + } + return base.replace(domain, '$1') + href; + } else { + return base + href; + } +} + +export const noopTest = { exec: function noopTest() {} }; + +export function merge(obj) { + let i = 1, + target, + key; + + for (; i < arguments.length; i++) { + target = arguments[i]; + for (key in target) { + if (Object.prototype.hasOwnProperty.call(target, key)) { + obj[key] = target[key]; + } + } + } + + return obj; +} + +export function splitCells(tableRow, count) { + // ensure that every cell-delimiting pipe has a space + // before it to distinguish it from an escaped pipe + const row = tableRow.replace(/\|/g, (match, offset, str) => { + let escaped = false, + curr = offset; + while (--curr >= 0 && str[curr] === '\\') escaped = !escaped; + if (escaped) { + // odd number of slashes means | is escaped + // so we leave it alone + return '|'; + } else { + // add space before unescaped | + return ' |'; + } + }), + cells = row.split(/ \|/); + let i = 0; + + // First/last cell in a row cannot be empty if it has no leading/trailing pipe + if (!cells[0].trim()) { cells.shift(); } + if (cells.length > 0 && !cells[cells.length - 1].trim()) { cells.pop(); } + + if (cells.length > count) { + cells.splice(count); + } else { + while (cells.length < count) cells.push(''); + } + + for (; i < cells.length; i++) { + // leading or trailing whitespace is ignored per the gfm spec + cells[i] = cells[i].trim().replace(/\\\|/g, '|'); + } + return cells; +} + +/** + * Remove trailing 'c's. Equivalent to str.replace(/c*$/, ''). + * /c*$/ is vulnerable to REDOS. + * + * @param {string} str + * @param {string} c + * @param {boolean} invert Remove suffix of non-c chars instead. Default falsey. + */ +export function rtrim(str, c, invert) { + const l = str.length; + if (l === 0) { + return ''; + } + + // Length of suffix matching the invert condition. + let suffLen = 0; + + // Step left until we fail to match the invert condition. + while (suffLen < l) { + const currChar = str.charAt(l - suffLen - 1); + if (currChar === c && !invert) { + suffLen++; + } else if (currChar !== c && invert) { + suffLen++; + } else { + break; + } + } + + return str.slice(0, l - suffLen); +} + +export function findClosingBracket(str, b) { + if (str.indexOf(b[1]) === -1) { + return -1; + } + const l = str.length; + let level = 0, + i = 0; + for (; i < l; i++) { + if (str[i] === '\\') { + i++; + } else if (str[i] === b[0]) { + level++; + } else if (str[i] === b[1]) { + level--; + if (level < 0) { + return i; + } + } + } + return -1; +} + +export function checkSanitizeDeprecation(opt) { + if (opt && opt.sanitize && !opt.silent) { + console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options'); + } +} + +// copied from https://stackoverflow.com/a/5450113/806777 +/** + * @param {string} pattern + * @param {number} count + */ +export function repeatString(pattern, count) { + if (count < 1) { + return ''; + } + let result = ''; + while (count > 1) { + if (count & 1) { + result += pattern; + } + count >>= 1; + pattern += pattern; + } + return result + pattern; +} diff --git a/node_modules/marked/src/marked.js b/node_modules/marked/src/marked.js new file mode 100644 index 0000000..10f5433 --- /dev/null +++ b/node_modules/marked/src/marked.js @@ -0,0 +1,351 @@ +import { Lexer } from './Lexer.js'; +import { Parser } from './Parser.js'; +import { Tokenizer } from './Tokenizer.js'; +import { Renderer } from './Renderer.js'; +import { TextRenderer } from './TextRenderer.js'; +import { Slugger } from './Slugger.js'; +import { + merge, + checkSanitizeDeprecation, + escape +} from './helpers.js'; +import { + getDefaults, + changeDefaults, + defaults +} from './defaults.js'; + +/** + * Marked + */ +export function marked(src, opt, callback) { + // throw error in case of non string input + if (typeof src === 'undefined' || src === null) { + throw new Error('marked(): input parameter is undefined or null'); + } + if (typeof src !== 'string') { + throw new Error('marked(): input parameter is of type ' + + Object.prototype.toString.call(src) + ', string expected'); + } + + if (typeof opt === 'function') { + callback = opt; + opt = null; + } + + opt = merge({}, marked.defaults, opt || {}); + checkSanitizeDeprecation(opt); + + if (callback) { + const highlight = opt.highlight; + let tokens; + + try { + tokens = Lexer.lex(src, opt); + } catch (e) { + return callback(e); + } + + const done = function(err) { + let out; + + if (!err) { + try { + if (opt.walkTokens) { + marked.walkTokens(tokens, opt.walkTokens); + } + out = Parser.parse(tokens, opt); + } catch (e) { + err = e; + } + } + + opt.highlight = highlight; + + return err + ? callback(err) + : callback(null, out); + }; + + if (!highlight || highlight.length < 3) { + return done(); + } + + delete opt.highlight; + + if (!tokens.length) return done(); + + let pending = 0; + marked.walkTokens(tokens, function(token) { + if (token.type === 'code') { + pending++; + setTimeout(() => { + highlight(token.text, token.lang, function(err, code) { + if (err) { + return done(err); + } + if (code != null && code !== token.text) { + token.text = code; + token.escaped = true; + } + + pending--; + if (pending === 0) { + done(); + } + }); + }, 0); + } + }); + + if (pending === 0) { + done(); + } + + return; + } + + try { + const tokens = Lexer.lex(src, opt); + if (opt.walkTokens) { + marked.walkTokens(tokens, opt.walkTokens); + } + return Parser.parse(tokens, opt); + } catch (e) { + e.message += '\nPlease report this to https://github.com/markedjs/marked.'; + if (opt.silent) { + return '

    An error occurred:

    '
    +        + escape(e.message + '', true)
    +        + '
    '; + } + throw e; + } +} + +/** + * Options + */ + +marked.options = +marked.setOptions = function(opt) { + merge(marked.defaults, opt); + changeDefaults(marked.defaults); + return marked; +}; + +marked.getDefaults = getDefaults; + +marked.defaults = defaults; + +/** + * Use Extension + */ + +marked.use = function(...args) { + const opts = merge({}, ...args); + const extensions = marked.defaults.extensions || { renderers: {}, childTokens: {} }; + let hasExtensions; + + args.forEach((pack) => { + // ==-- Parse "addon" extensions --== // + if (pack.extensions) { + hasExtensions = true; + pack.extensions.forEach((ext) => { + if (!ext.name) { + throw new Error('extension name required'); + } + if (ext.renderer) { // Renderer extensions + const prevRenderer = extensions.renderers ? extensions.renderers[ext.name] : null; + if (prevRenderer) { + // Replace extension with func to run new extension but fall back if false + extensions.renderers[ext.name] = function(...args) { + let ret = ext.renderer.apply(this, args); + if (ret === false) { + ret = prevRenderer.apply(this, args); + } + return ret; + }; + } else { + extensions.renderers[ext.name] = ext.renderer; + } + } + if (ext.tokenizer) { // Tokenizer Extensions + if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) { + throw new Error("extension level must be 'block' or 'inline'"); + } + if (extensions[ext.level]) { + extensions[ext.level].unshift(ext.tokenizer); + } else { + extensions[ext.level] = [ext.tokenizer]; + } + if (ext.start) { // Function to check for start of token + if (ext.level === 'block') { + if (extensions.startBlock) { + extensions.startBlock.push(ext.start); + } else { + extensions.startBlock = [ext.start]; + } + } else if (ext.level === 'inline') { + if (extensions.startInline) { + extensions.startInline.push(ext.start); + } else { + extensions.startInline = [ext.start]; + } + } + } + } + if (ext.childTokens) { // Child tokens to be visited by walkTokens + extensions.childTokens[ext.name] = ext.childTokens; + } + }); + } + + // ==-- Parse "overwrite" extensions --== // + if (pack.renderer) { + const renderer = marked.defaults.renderer || new Renderer(); + for (const prop in pack.renderer) { + const prevRenderer = renderer[prop]; + // Replace renderer with func to run extension, but fall back if false + renderer[prop] = (...args) => { + let ret = pack.renderer[prop].apply(renderer, args); + if (ret === false) { + ret = prevRenderer.apply(renderer, args); + } + return ret; + }; + } + opts.renderer = renderer; + } + if (pack.tokenizer) { + const tokenizer = marked.defaults.tokenizer || new Tokenizer(); + for (const prop in pack.tokenizer) { + const prevTokenizer = tokenizer[prop]; + // Replace tokenizer with func to run extension, but fall back if false + tokenizer[prop] = (...args) => { + let ret = pack.tokenizer[prop].apply(tokenizer, args); + if (ret === false) { + ret = prevTokenizer.apply(tokenizer, args); + } + return ret; + }; + } + opts.tokenizer = tokenizer; + } + + // ==-- Parse WalkTokens extensions --== // + if (pack.walkTokens) { + const walkTokens = marked.defaults.walkTokens; + opts.walkTokens = function(token) { + pack.walkTokens.call(this, token); + if (walkTokens) { + walkTokens.call(this, token); + } + }; + } + + if (hasExtensions) { + opts.extensions = extensions; + } + + marked.setOptions(opts); + }); +}; + +/** + * Run callback for every token + */ + +marked.walkTokens = function(tokens, callback) { + for (const token of tokens) { + callback.call(marked, token); + switch (token.type) { + case 'table': { + for (const cell of token.header) { + marked.walkTokens(cell.tokens, callback); + } + for (const row of token.rows) { + for (const cell of row) { + marked.walkTokens(cell.tokens, callback); + } + } + break; + } + case 'list': { + marked.walkTokens(token.items, callback); + break; + } + default: { + if (marked.defaults.extensions && marked.defaults.extensions.childTokens && marked.defaults.extensions.childTokens[token.type]) { // Walk any extensions + marked.defaults.extensions.childTokens[token.type].forEach(function(childTokens) { + marked.walkTokens(token[childTokens], callback); + }); + } else if (token.tokens) { + marked.walkTokens(token.tokens, callback); + } + } + } + } +}; + +/** + * Parse Inline + * @param {string} src + */ +marked.parseInline = function(src, opt) { + // throw error in case of non string input + if (typeof src === 'undefined' || src === null) { + throw new Error('marked.parseInline(): input parameter is undefined or null'); + } + if (typeof src !== 'string') { + throw new Error('marked.parseInline(): input parameter is of type ' + + Object.prototype.toString.call(src) + ', string expected'); + } + + opt = merge({}, marked.defaults, opt || {}); + checkSanitizeDeprecation(opt); + + try { + const tokens = Lexer.lexInline(src, opt); + if (opt.walkTokens) { + marked.walkTokens(tokens, opt.walkTokens); + } + return Parser.parseInline(tokens, opt); + } catch (e) { + e.message += '\nPlease report this to https://github.com/markedjs/marked.'; + if (opt.silent) { + return '

    An error occurred:

    '
    +        + escape(e.message + '', true)
    +        + '
    '; + } + throw e; + } +}; + +/** + * Expose + */ +marked.Parser = Parser; +marked.parser = Parser.parse; +marked.Renderer = Renderer; +marked.TextRenderer = TextRenderer; +marked.Lexer = Lexer; +marked.lexer = Lexer.lex; +marked.Tokenizer = Tokenizer; +marked.Slugger = Slugger; +marked.parse = marked; + +export const options = marked.options; +export const setOptions = marked.setOptions; +export const use = marked.use; +export const walkTokens = marked.walkTokens; +export const parseInline = marked.parseInline; +export const parse = marked; +export const parser = Parser.parse; +export const lexer = Lexer.lex; +export { defaults, getDefaults } from './defaults.js'; +export { Lexer } from './Lexer.js'; +export { Parser } from './Parser.js'; +export { Tokenizer } from './Tokenizer.js'; +export { Renderer } from './Renderer.js'; +export { TextRenderer } from './TextRenderer.js'; +export { Slugger } from './Slugger.js'; diff --git a/node_modules/marked/src/rules.js b/node_modules/marked/src/rules.js new file mode 100644 index 0000000..25d1415 --- /dev/null +++ b/node_modules/marked/src/rules.js @@ -0,0 +1,302 @@ +import { + noopTest, + edit, + merge +} from './helpers.js'; + +/** + * Block-Level Grammar + */ +export const block = { + newline: /^(?: *(?:\n|$))+/, + code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/, + fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/, + hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/, + heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/, + blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/, + list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/, + html: '^ {0,3}(?:' // optional indentation + + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)' // (1) + + '|comment[^\\n]*(\\n+|$)' // (2) + + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3) + + '|\\n*|$)' // (4) + + '|\\n*|$)' // (5) + + '|)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6) + + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag + + '|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag + + ')', + def: /^ {0,3}\[(label)\]: *(?:\n *)?]+)>?(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/, + table: noopTest, + lheading: /^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/, + // regex template, placeholders will be replaced according to different paragraph + // interruption rules of commonmark and the original markdown spec: + _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/, + text: /^[^\n]+/ +}; + +block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/; +block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/; +block.def = edit(block.def) + .replace('label', block._label) + .replace('title', block._title) + .getRegex(); + +block.bullet = /(?:[*+-]|\d{1,9}[.)])/; +block.listItemStart = edit(/^( *)(bull) */) + .replace('bull', block.bullet) + .getRegex(); + +block.list = edit(block.list) + .replace(/bull/g, block.bullet) + .replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))') + .replace('def', '\\n+(?=' + block.def.source + ')') + .getRegex(); + +block._tag = 'address|article|aside|base|basefont|blockquote|body|caption' + + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption' + + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe' + + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option' + + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr' + + '|track|ul'; +block._comment = /|$)/; +block.html = edit(block.html, 'i') + .replace('comment', block._comment) + .replace('tag', block._tag) + .replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/) + .getRegex(); + +block.paragraph = edit(block._paragraph) + .replace('hr', block.hr) + .replace('heading', ' {0,3}#{1,6} ') + .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs + .replace('|table', '') + .replace('blockquote', ' {0,3}>') + .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n') + .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt + .replace('html', ')|<(?:script|pre|style|textarea|!--)') + .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks + .getRegex(); + +block.blockquote = edit(block.blockquote) + .replace('paragraph', block.paragraph) + .getRegex(); + +/** + * Normal Block Grammar + */ + +block.normal = merge({}, block); + +/** + * GFM Block Grammar + */ + +block.gfm = merge({}, block.normal, { + table: '^ *([^\\n ].*\\|.*)\\n' // Header + + ' {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?' // Align + + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells +}); + +block.gfm.table = edit(block.gfm.table) + .replace('hr', block.hr) + .replace('heading', ' {0,3}#{1,6} ') + .replace('blockquote', ' {0,3}>') + .replace('code', ' {4}[^\\n]') + .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n') + .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt + .replace('html', ')|<(?:script|pre|style|textarea|!--)') + .replace('tag', block._tag) // tables can be interrupted by type (6) html blocks + .getRegex(); + +block.gfm.paragraph = edit(block._paragraph) + .replace('hr', block.hr) + .replace('heading', ' {0,3}#{1,6} ') + .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs + .replace('table', block.gfm.table) // interrupt paragraphs with table + .replace('blockquote', ' {0,3}>') + .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n') + .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt + .replace('html', ')|<(?:script|pre|style|textarea|!--)') + .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks + .getRegex(); +/** + * Pedantic grammar (original John Gruber's loose markdown specification) + */ + +block.pedantic = merge({}, block.normal, { + html: edit( + '^ *(?:comment *(?:\\n|\\s*$)' + + '|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)' // closed tag + + '|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))') + .replace('comment', block._comment) + .replace(/tag/g, '(?!(?:' + + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub' + + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)' + + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b') + .getRegex(), + def: /^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, + heading: /^(#{1,6})(.*)(?:\n+|$)/, + fences: noopTest, // fences not supported + paragraph: edit(block.normal._paragraph) + .replace('hr', block.hr) + .replace('heading', ' *#{1,6} *[^\n]') + .replace('lheading', block.lheading) + .replace('blockquote', ' {0,3}>') + .replace('|fences', '') + .replace('|list', '') + .replace('|html', '') + .getRegex() +}); + +/** + * Inline-Level Grammar + */ +export const inline = { + escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, + autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/, + url: noopTest, + tag: '^comment' + + '|^' // self-closing tag + + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag + + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. + + '|^' // declaration, e.g. + + '|^', // CDATA section + link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/, + reflink: /^!?\[(label)\]\[(ref)\]/, + nolink: /^!?\[(ref)\](?:\[\])?/, + reflinkSearch: 'reflink|nolink(?!\\()', + emStrong: { + lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/, + // (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right. + // () Skip orphan inside strong () Consume to delim (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a + rDelimAst: /^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[^*]+(?=[^*])|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/, + rDelimUnd: /^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _ + }, + code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, + br: /^( {2,}|\\)\n(?!\s*$)/, + del: noopTest, + text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\?@\\[\\]`^{|}~'; +inline.punctuation = edit(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex(); + +// sequences em should skip over [title](link), `code`, +inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g; +inline.escapedEmSt = /\\\*|\\_/g; + +inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex(); + +inline.emStrong.lDelim = edit(inline.emStrong.lDelim) + .replace(/punct/g, inline._punctuation) + .getRegex(); + +inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'g') + .replace(/punct/g, inline._punctuation) + .getRegex(); + +inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'g') + .replace(/punct/g, inline._punctuation) + .getRegex(); + +inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g; + +inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/; +inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/; +inline.autolink = edit(inline.autolink) + .replace('scheme', inline._scheme) + .replace('email', inline._email) + .getRegex(); + +inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/; + +inline.tag = edit(inline.tag) + .replace('comment', inline._comment) + .replace('attribute', inline._attribute) + .getRegex(); + +inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/; +inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/; +inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/; + +inline.link = edit(inline.link) + .replace('label', inline._label) + .replace('href', inline._href) + .replace('title', inline._title) + .getRegex(); + +inline.reflink = edit(inline.reflink) + .replace('label', inline._label) + .replace('ref', block._label) + .getRegex(); + +inline.nolink = edit(inline.nolink) + .replace('ref', block._label) + .getRegex(); + +inline.reflinkSearch = edit(inline.reflinkSearch, 'g') + .replace('reflink', inline.reflink) + .replace('nolink', inline.nolink) + .getRegex(); + +/** + * Normal Inline Grammar + */ + +inline.normal = merge({}, inline); + +/** + * Pedantic Inline Grammar + */ + +inline.pedantic = merge({}, inline.normal, { + strong: { + start: /^__|\*\*/, + middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, + endAst: /\*\*(?!\*)/g, + endUnd: /__(?!_)/g + }, + em: { + start: /^_|\*/, + middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/, + endAst: /\*(?!\*)/g, + endUnd: /_(?!_)/g + }, + link: edit(/^!?\[(label)\]\((.*?)\)/) + .replace('label', inline._label) + .getRegex(), + reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/) + .replace('label', inline._label) + .getRegex() +}); + +/** + * GFM Inline Grammar + */ + +inline.gfm = merge({}, inline.normal, { + escape: edit(inline.escape).replace('])', '~|])').getRegex(), + _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/, + url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, + _backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/, + del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/, + text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\=10" } }, + "node_modules/marked": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.17.tgz", + "integrity": "sha512-Wfk0ATOK5iPxM4ptrORkFemqroz0ZDxp5MWfYA7H/F+wO17NRWV5Ypxi6p3g2Xmw2bKeiYOl6oVnLHKxBA0VhA==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -1080,6 +1092,11 @@ "minimatch": "^3.0.4" } }, + "marked": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.17.tgz", + "integrity": "sha512-Wfk0ATOK5iPxM4ptrORkFemqroz0ZDxp5MWfYA7H/F+wO17NRWV5Ypxi6p3g2Xmw2bKeiYOl6oVnLHKxBA0VhA==" + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", diff --git a/package.json b/package.json index 5340297..9405477 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "license": "GPL-3.0-only", "dependencies": { "ejs": "^3.1.8", - "express": "^4.18.1" + "express": "^4.18.1", + "marked": "^4.0.17" } }