833 lines
27 KiB
JavaScript
833 lines
27 KiB
JavaScript
import {
|
|
__commonJS
|
|
} from "./chunk-TKSB4YUA.js";
|
|
|
|
// node_modules/markdown-it-attrs/utils.js
|
|
var require_utils = __commonJS({
|
|
"node_modules/markdown-it-attrs/utils.js"(exports) {
|
|
exports.getAttrs = function(str, start, options) {
|
|
const allowedKeyChars = /[^\t\n\f />"'=]/;
|
|
const pairSeparator = " ";
|
|
const keySeparator = "=";
|
|
const classChar = ".";
|
|
const idChar = "#";
|
|
const attrs = [];
|
|
let key = "";
|
|
let value = "";
|
|
let parsingKey = true;
|
|
let valueInsideQuotes = false;
|
|
for (let i = start + options.leftDelimiter.length; i < str.length; i++) {
|
|
if (str.slice(i, i + options.rightDelimiter.length) === options.rightDelimiter) {
|
|
if (key !== "") {
|
|
attrs.push([key, value]);
|
|
}
|
|
break;
|
|
}
|
|
const char_ = str.charAt(i);
|
|
if (char_ === keySeparator && parsingKey) {
|
|
parsingKey = false;
|
|
continue;
|
|
}
|
|
if (char_ === classChar && key === "") {
|
|
if (str.charAt(i + 1) === classChar) {
|
|
key = "css-module";
|
|
i += 1;
|
|
} else {
|
|
key = "class";
|
|
}
|
|
parsingKey = false;
|
|
continue;
|
|
}
|
|
if (char_ === idChar && key === "") {
|
|
key = "id";
|
|
parsingKey = false;
|
|
continue;
|
|
}
|
|
if (char_ === '"' && value === "" && !valueInsideQuotes) {
|
|
valueInsideQuotes = true;
|
|
continue;
|
|
}
|
|
if (char_ === '"' && valueInsideQuotes) {
|
|
valueInsideQuotes = false;
|
|
continue;
|
|
}
|
|
if (char_ === pairSeparator && !valueInsideQuotes) {
|
|
if (key === "") {
|
|
continue;
|
|
}
|
|
attrs.push([key, value]);
|
|
key = "";
|
|
value = "";
|
|
parsingKey = true;
|
|
continue;
|
|
}
|
|
if (parsingKey && char_.search(allowedKeyChars) === -1) {
|
|
continue;
|
|
}
|
|
if (parsingKey) {
|
|
key += char_;
|
|
continue;
|
|
}
|
|
value += char_;
|
|
}
|
|
if (options.allowedAttributes && options.allowedAttributes.length) {
|
|
const allowedAttributes = options.allowedAttributes;
|
|
return attrs.filter(function(attrPair) {
|
|
const attr = attrPair[0];
|
|
function isAllowedAttribute(allowedAttribute) {
|
|
return attr === allowedAttribute || allowedAttribute instanceof RegExp && allowedAttribute.test(attr);
|
|
}
|
|
return allowedAttributes.some(isAllowedAttribute);
|
|
});
|
|
}
|
|
return attrs;
|
|
};
|
|
exports.addAttrs = function(attrs, token) {
|
|
for (let j = 0, l = attrs.length; j < l; ++j) {
|
|
const key = attrs[j][0];
|
|
if (key === "class") {
|
|
token.attrJoin("class", attrs[j][1]);
|
|
} else if (key === "css-module") {
|
|
token.attrJoin("css-module", attrs[j][1]);
|
|
} else {
|
|
token.attrPush(attrs[j]);
|
|
}
|
|
}
|
|
return token;
|
|
};
|
|
exports.hasDelimiters = function(where, options) {
|
|
if (!where) {
|
|
throw new Error('Parameter `where` not passed. Should be "start", "end" or "only".');
|
|
}
|
|
return function(str) {
|
|
const minCurlyLength = options.leftDelimiter.length + 1 + options.rightDelimiter.length;
|
|
if (!str || typeof str !== "string" || str.length < minCurlyLength) {
|
|
return false;
|
|
}
|
|
function validCurlyLength(curly) {
|
|
const isClass = curly.charAt(options.leftDelimiter.length) === ".";
|
|
const isId = curly.charAt(options.leftDelimiter.length) === "#";
|
|
return isClass || isId ? curly.length >= minCurlyLength + 1 : curly.length >= minCurlyLength;
|
|
}
|
|
let start, end, slice, nextChar;
|
|
const rightDelimiterMinimumShift = minCurlyLength - options.rightDelimiter.length;
|
|
switch (where) {
|
|
case "start":
|
|
slice = str.slice(0, options.leftDelimiter.length);
|
|
start = slice === options.leftDelimiter ? 0 : -1;
|
|
end = start === -1 ? -1 : str.indexOf(options.rightDelimiter, rightDelimiterMinimumShift);
|
|
nextChar = str.charAt(end + options.rightDelimiter.length);
|
|
if (nextChar && options.rightDelimiter.indexOf(nextChar) !== -1) {
|
|
end = -1;
|
|
}
|
|
break;
|
|
case "end":
|
|
start = str.lastIndexOf(options.leftDelimiter);
|
|
end = start === -1 ? -1 : str.indexOf(options.rightDelimiter, start + rightDelimiterMinimumShift);
|
|
end = end === str.length - options.rightDelimiter.length ? end : -1;
|
|
break;
|
|
case "only":
|
|
slice = str.slice(0, options.leftDelimiter.length);
|
|
start = slice === options.leftDelimiter ? 0 : -1;
|
|
slice = str.slice(str.length - options.rightDelimiter.length);
|
|
end = slice === options.rightDelimiter ? str.length - options.rightDelimiter.length : -1;
|
|
break;
|
|
default:
|
|
throw new Error(`Unexpected case ${where}, expected 'start', 'end' or 'only'`);
|
|
}
|
|
return start !== -1 && end !== -1 && validCurlyLength(str.substring(start, end + options.rightDelimiter.length));
|
|
};
|
|
};
|
|
exports.removeDelimiter = function(str, options) {
|
|
const start = escapeRegExp(options.leftDelimiter);
|
|
const end = escapeRegExp(options.rightDelimiter);
|
|
const curly = new RegExp(
|
|
"[ \\n]?" + start + "[^" + start + end + "]+" + end + "$"
|
|
);
|
|
const pos = str.search(curly);
|
|
return pos !== -1 ? str.slice(0, pos) : str;
|
|
};
|
|
function escapeRegExp(s) {
|
|
return s.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
}
|
|
exports.escapeRegExp = escapeRegExp;
|
|
exports.getMatchingOpeningToken = function(tokens, i) {
|
|
if (tokens[i].type === "softbreak") {
|
|
return false;
|
|
}
|
|
if (tokens[i].nesting === 0) {
|
|
return tokens[i];
|
|
}
|
|
const level = tokens[i].level;
|
|
const type = tokens[i].type.replace("_close", "_open");
|
|
for (; i >= 0; --i) {
|
|
if (tokens[i].type === type && tokens[i].level === level) {
|
|
return tokens[i];
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
var HTML_ESCAPE_TEST_RE = /[&<>"]/;
|
|
var HTML_ESCAPE_REPLACE_RE = /[&<>"]/g;
|
|
var HTML_REPLACEMENTS = {
|
|
"&": "&",
|
|
"<": "<",
|
|
">": ">",
|
|
'"': """
|
|
};
|
|
function replaceUnsafeChar(ch) {
|
|
return HTML_REPLACEMENTS[ch];
|
|
}
|
|
exports.escapeHtml = function(str) {
|
|
if (HTML_ESCAPE_TEST_RE.test(str)) {
|
|
return str.replace(HTML_ESCAPE_REPLACE_RE, replaceUnsafeChar);
|
|
}
|
|
return str;
|
|
};
|
|
}
|
|
});
|
|
|
|
// node_modules/markdown-it-attrs/patterns.js
|
|
var require_patterns = __commonJS({
|
|
"node_modules/markdown-it-attrs/patterns.js"(exports, module) {
|
|
"use strict";
|
|
var utils = require_utils();
|
|
module.exports = (options) => {
|
|
const __hr = new RegExp("^ {0,3}[-*_]{3,} ?" + utils.escapeRegExp(options.leftDelimiter) + "[^" + utils.escapeRegExp(options.rightDelimiter) + "]");
|
|
return [
|
|
{
|
|
/**
|
|
* ```python {.cls}
|
|
* for i in range(10):
|
|
* print(i)
|
|
* ```
|
|
*/
|
|
name: "fenced code blocks",
|
|
tests: [
|
|
{
|
|
shift: 0,
|
|
block: true,
|
|
info: utils.hasDelimiters("end", options)
|
|
}
|
|
],
|
|
transform: (tokens, i) => {
|
|
const token = tokens[i];
|
|
const start = token.info.lastIndexOf(options.leftDelimiter);
|
|
const attrs = utils.getAttrs(token.info, start, options);
|
|
utils.addAttrs(attrs, token);
|
|
token.info = utils.removeDelimiter(token.info, options);
|
|
}
|
|
},
|
|
{
|
|
/**
|
|
* bla `click()`{.c} {.d}
|
|
*
|
|
* differs from 'inline attributes' as it does
|
|
* not have a closing tag (nesting: -1)
|
|
*/
|
|
name: "inline nesting 0",
|
|
tests: [
|
|
{
|
|
shift: 0,
|
|
type: "inline",
|
|
children: [
|
|
{
|
|
shift: -1,
|
|
type: (str) => str === "image" || str === "code_inline"
|
|
},
|
|
{
|
|
shift: 0,
|
|
type: "text",
|
|
content: utils.hasDelimiters("start", options)
|
|
}
|
|
]
|
|
}
|
|
],
|
|
/**
|
|
* @param {!number} j
|
|
*/
|
|
transform: (tokens, i, j) => {
|
|
const token = tokens[i].children[j];
|
|
const endChar = token.content.indexOf(options.rightDelimiter);
|
|
const attrToken = tokens[i].children[j - 1];
|
|
const attrs = utils.getAttrs(token.content, 0, options);
|
|
utils.addAttrs(attrs, attrToken);
|
|
if (token.content.length === endChar + options.rightDelimiter.length) {
|
|
tokens[i].children.splice(j, 1);
|
|
} else {
|
|
token.content = token.content.slice(endChar + options.rightDelimiter.length);
|
|
}
|
|
}
|
|
},
|
|
{
|
|
/**
|
|
* | h1 |
|
|
* | -- |
|
|
* | c1 |
|
|
*
|
|
* {.c}
|
|
*/
|
|
name: "tables",
|
|
tests: [
|
|
{
|
|
// let this token be i, such that for-loop continues at
|
|
// next token after tokens.splice
|
|
shift: 0,
|
|
type: "table_close"
|
|
},
|
|
{
|
|
shift: 1,
|
|
type: "paragraph_open"
|
|
},
|
|
{
|
|
shift: 2,
|
|
type: "inline",
|
|
content: utils.hasDelimiters("only", options)
|
|
}
|
|
],
|
|
transform: (tokens, i) => {
|
|
const token = tokens[i + 2];
|
|
const tableOpen = utils.getMatchingOpeningToken(tokens, i);
|
|
const attrs = utils.getAttrs(token.content, 0, options);
|
|
utils.addAttrs(attrs, tableOpen);
|
|
tokens.splice(i + 1, 3);
|
|
}
|
|
},
|
|
{
|
|
/**
|
|
* | A | B |
|
|
* | -- | -- |
|
|
* | 1 | 2 |
|
|
*
|
|
* | C | D |
|
|
* | -- | -- |
|
|
*
|
|
* only `| A | B |` sets the colsnum metadata
|
|
*/
|
|
name: "tables thead metadata",
|
|
tests: [
|
|
{
|
|
shift: 0,
|
|
type: "tr_close"
|
|
},
|
|
{
|
|
shift: 1,
|
|
type: "thead_close"
|
|
},
|
|
{
|
|
shift: 2,
|
|
type: "tbody_open"
|
|
}
|
|
],
|
|
transform: (tokens, i) => {
|
|
const tr = utils.getMatchingOpeningToken(tokens, i);
|
|
const th = tokens[i - 1];
|
|
let colsnum = 0;
|
|
let n = i;
|
|
while (--n) {
|
|
if (tokens[n] === tr) {
|
|
tokens[n - 1].meta = Object.assign({}, tokens[n + 2].meta, { colsnum });
|
|
break;
|
|
}
|
|
colsnum += (tokens[n].level === th.level && tokens[n].type === th.type) >> 0;
|
|
}
|
|
tokens[i + 2].meta = Object.assign({}, tokens[i + 2].meta, { colsnum });
|
|
}
|
|
},
|
|
{
|
|
/**
|
|
* | A | B | C | D |
|
|
* | -- | -- | -- | -- |
|
|
* | 1 | 11 | 111 | 1111 {rowspan=3} |
|
|
* | 2 {colspan=2 rowspan=2} | 22 | 222 | 2222 |
|
|
* | 3 | 33 | 333 | 3333 |
|
|
*/
|
|
name: "tables tbody calculate",
|
|
tests: [
|
|
{
|
|
shift: 0,
|
|
type: "tbody_close",
|
|
hidden: false
|
|
}
|
|
],
|
|
/**
|
|
* @param {number} i index of the tbody ending
|
|
*/
|
|
transform: (tokens, i) => {
|
|
let idx = i - 2;
|
|
while (idx > 0 && "tbody_open" !== tokens[--idx].type) ;
|
|
const calc = tokens[idx].meta.colsnum >> 0;
|
|
if (calc < 2) {
|
|
return;
|
|
}
|
|
const level = tokens[i].level + 2;
|
|
for (let n = idx; n < i; n++) {
|
|
if (tokens[n].level > level) {
|
|
continue;
|
|
}
|
|
const token = tokens[n];
|
|
const rows = token.hidden ? 0 : token.attrGet("rowspan") >> 0;
|
|
const cols = token.hidden ? 0 : token.attrGet("colspan") >> 0;
|
|
if (rows > 1) {
|
|
let colsnum = calc - (cols > 0 ? cols : 1);
|
|
for (let k = n, num = rows; k < i, num > 1; k++) {
|
|
if ("tr_open" == tokens[k].type) {
|
|
tokens[k].meta = Object.assign({}, tokens[k].meta);
|
|
if (tokens[k].meta && tokens[k].meta.colsnum) {
|
|
colsnum -= 1;
|
|
}
|
|
tokens[k].meta.colsnum = colsnum;
|
|
num--;
|
|
}
|
|
}
|
|
}
|
|
if ("tr_open" == token.type && token.meta && token.meta.colsnum) {
|
|
const max = token.meta.colsnum;
|
|
for (let k = n, num = 0; k < i; k++) {
|
|
if ("td_open" == tokens[k].type) {
|
|
num += 1;
|
|
} else if ("tr_close" == tokens[k].type) {
|
|
break;
|
|
}
|
|
num > max && (tokens[k].hidden || hidden(tokens[k]));
|
|
}
|
|
}
|
|
if (cols > 1) {
|
|
const one = [];
|
|
let end = n + 3;
|
|
let num = calc;
|
|
for (let k = n; k > idx; k--) {
|
|
if ("tr_open" == tokens[k].type) {
|
|
num = tokens[k].meta && tokens[k].meta.colsnum || num;
|
|
break;
|
|
} else if ("td_open" === tokens[k].type) {
|
|
one.unshift(k);
|
|
}
|
|
}
|
|
for (let k = n + 2; k < i; k++) {
|
|
if ("tr_close" == tokens[k].type) {
|
|
end = k;
|
|
break;
|
|
} else if ("td_open" == tokens[k].type) {
|
|
one.push(k);
|
|
}
|
|
}
|
|
const off = one.indexOf(n);
|
|
let real = num - off;
|
|
real = real > cols ? cols : real;
|
|
cols > real && token.attrSet("colspan", real + "");
|
|
for (let k = one.slice(num + 1 - calc - real)[0]; k < end; k++) {
|
|
tokens[k].hidden || hidden(tokens[k]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
/**
|
|
* *emphasis*{.with attrs=1}
|
|
*/
|
|
name: "inline attributes",
|
|
tests: [
|
|
{
|
|
shift: 0,
|
|
type: "inline",
|
|
children: [
|
|
{
|
|
shift: -1,
|
|
nesting: -1
|
|
// closing inline tag, </em>{.a}
|
|
},
|
|
{
|
|
shift: 0,
|
|
type: "text",
|
|
content: utils.hasDelimiters("start", options)
|
|
}
|
|
]
|
|
}
|
|
],
|
|
/**
|
|
* @param {!number} j
|
|
*/
|
|
transform: (tokens, i, j) => {
|
|
const token = tokens[i].children[j];
|
|
const content = token.content;
|
|
const attrs = utils.getAttrs(content, 0, options);
|
|
const openingToken = utils.getMatchingOpeningToken(tokens[i].children, j - 1);
|
|
utils.addAttrs(attrs, openingToken);
|
|
token.content = content.slice(content.indexOf(options.rightDelimiter) + options.rightDelimiter.length);
|
|
}
|
|
},
|
|
{
|
|
/**
|
|
* - item
|
|
* {.a}
|
|
*/
|
|
name: "list softbreak",
|
|
tests: [
|
|
{
|
|
shift: -2,
|
|
type: "list_item_open"
|
|
},
|
|
{
|
|
shift: 0,
|
|
type: "inline",
|
|
children: [
|
|
{
|
|
position: -2,
|
|
type: "softbreak"
|
|
},
|
|
{
|
|
position: -1,
|
|
type: "text",
|
|
content: utils.hasDelimiters("only", options)
|
|
}
|
|
]
|
|
}
|
|
],
|
|
/**
|
|
* @param {!number} j
|
|
*/
|
|
transform: (tokens, i, j) => {
|
|
const token = tokens[i].children[j];
|
|
const content = token.content;
|
|
const attrs = utils.getAttrs(content, 0, options);
|
|
let ii = i - 2;
|
|
while (tokens[ii - 1] && tokens[ii - 1].type !== "ordered_list_open" && tokens[ii - 1].type !== "bullet_list_open") {
|
|
ii--;
|
|
}
|
|
utils.addAttrs(attrs, tokens[ii - 1]);
|
|
tokens[i].children = tokens[i].children.slice(0, -2);
|
|
}
|
|
},
|
|
{
|
|
/**
|
|
* - nested list
|
|
* - with double \n
|
|
* {.a} <-- apply to nested ul
|
|
*
|
|
* {.b} <-- apply to root <ul>
|
|
*/
|
|
name: "list double softbreak",
|
|
tests: [
|
|
{
|
|
// let this token be i = 0 so that we can erase
|
|
// the <p>{.a}</p> tokens below
|
|
shift: 0,
|
|
type: (str) => str === "bullet_list_close" || str === "ordered_list_close"
|
|
},
|
|
{
|
|
shift: 1,
|
|
type: "paragraph_open"
|
|
},
|
|
{
|
|
shift: 2,
|
|
type: "inline",
|
|
content: utils.hasDelimiters("only", options),
|
|
children: (arr) => arr.length === 1
|
|
},
|
|
{
|
|
shift: 3,
|
|
type: "paragraph_close"
|
|
}
|
|
],
|
|
transform: (tokens, i) => {
|
|
const token = tokens[i + 2];
|
|
const content = token.content;
|
|
const attrs = utils.getAttrs(content, 0, options);
|
|
const openingToken = utils.getMatchingOpeningToken(tokens, i);
|
|
utils.addAttrs(attrs, openingToken);
|
|
tokens.splice(i + 1, 3);
|
|
}
|
|
},
|
|
{
|
|
/**
|
|
* - end of {.list-item}
|
|
*/
|
|
name: "list item end",
|
|
tests: [
|
|
{
|
|
shift: -2,
|
|
type: "list_item_open"
|
|
},
|
|
{
|
|
shift: 0,
|
|
type: "inline",
|
|
children: [
|
|
{
|
|
position: -1,
|
|
type: "text",
|
|
content: utils.hasDelimiters("end", options)
|
|
}
|
|
]
|
|
}
|
|
],
|
|
/**
|
|
* @param {!number} j
|
|
*/
|
|
transform: (tokens, i, j) => {
|
|
const token = tokens[i].children[j];
|
|
const content = token.content;
|
|
const attrs = utils.getAttrs(content, content.lastIndexOf(options.leftDelimiter), options);
|
|
utils.addAttrs(attrs, tokens[i - 2]);
|
|
const trimmed = content.slice(0, content.lastIndexOf(options.leftDelimiter));
|
|
token.content = last(trimmed) !== " " ? trimmed : trimmed.slice(0, -1);
|
|
}
|
|
},
|
|
{
|
|
/**
|
|
* something with softbreak
|
|
* {.cls}
|
|
*/
|
|
name: "\n{.a} softbreak then curly in start",
|
|
tests: [
|
|
{
|
|
shift: 0,
|
|
type: "inline",
|
|
children: [
|
|
{
|
|
position: -2,
|
|
type: "softbreak"
|
|
},
|
|
{
|
|
position: -1,
|
|
type: "text",
|
|
content: utils.hasDelimiters("only", options)
|
|
}
|
|
]
|
|
}
|
|
],
|
|
/**
|
|
* @param {!number} j
|
|
*/
|
|
transform: (tokens, i, j) => {
|
|
const token = tokens[i].children[j];
|
|
const attrs = utils.getAttrs(token.content, 0, options);
|
|
let ii = i + 1;
|
|
while (tokens[ii + 1] && tokens[ii + 1].nesting === -1) {
|
|
ii++;
|
|
}
|
|
const openingToken = utils.getMatchingOpeningToken(tokens, ii);
|
|
utils.addAttrs(attrs, openingToken);
|
|
tokens[i].children = tokens[i].children.slice(0, -2);
|
|
}
|
|
},
|
|
{
|
|
/**
|
|
* horizontal rule --- {#id}
|
|
*/
|
|
name: "horizontal rule",
|
|
tests: [
|
|
{
|
|
shift: 0,
|
|
type: "paragraph_open"
|
|
},
|
|
{
|
|
shift: 1,
|
|
type: "inline",
|
|
children: (arr) => arr.length === 1,
|
|
content: (str) => str.match(__hr) !== null
|
|
},
|
|
{
|
|
shift: 2,
|
|
type: "paragraph_close"
|
|
}
|
|
],
|
|
transform: (tokens, i) => {
|
|
const token = tokens[i];
|
|
token.type = "hr";
|
|
token.tag = "hr";
|
|
token.nesting = 0;
|
|
const content = tokens[i + 1].content;
|
|
const start = content.lastIndexOf(options.leftDelimiter);
|
|
const attrs = utils.getAttrs(content, start, options);
|
|
utils.addAttrs(attrs, token);
|
|
token.markup = content;
|
|
tokens.splice(i + 1, 2);
|
|
}
|
|
},
|
|
{
|
|
/**
|
|
* end of {.block}
|
|
*/
|
|
name: "end of block",
|
|
tests: [
|
|
{
|
|
shift: 0,
|
|
type: "inline",
|
|
children: [
|
|
{
|
|
position: -1,
|
|
content: utils.hasDelimiters("end", options),
|
|
type: (t) => t !== "code_inline" && t !== "math_inline"
|
|
}
|
|
]
|
|
}
|
|
],
|
|
/**
|
|
* @param {!number} j
|
|
*/
|
|
transform: (tokens, i, j) => {
|
|
const token = tokens[i].children[j];
|
|
const content = token.content;
|
|
const attrs = utils.getAttrs(content, content.lastIndexOf(options.leftDelimiter), options);
|
|
let ii = i + 1;
|
|
do
|
|
if (tokens[ii] && tokens[ii].nesting === -1) {
|
|
break;
|
|
}
|
|
while (ii++ < tokens.length);
|
|
const openingToken = utils.getMatchingOpeningToken(tokens, ii);
|
|
utils.addAttrs(attrs, openingToken);
|
|
const trimmed = content.slice(0, content.lastIndexOf(options.leftDelimiter));
|
|
token.content = last(trimmed) !== " " ? trimmed : trimmed.slice(0, -1);
|
|
}
|
|
}
|
|
];
|
|
};
|
|
function last(arr) {
|
|
return arr.slice(-1)[0];
|
|
}
|
|
function hidden(token) {
|
|
token.hidden = true;
|
|
token.children && token.children.forEach((t) => (t.content = "", hidden(t), void 0));
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/markdown-it-attrs/index.js
|
|
var require_markdown_it_attrs = __commonJS({
|
|
"node_modules/markdown-it-attrs/index.js"(exports, module) {
|
|
var patternsConfig = require_patterns();
|
|
var defaultOptions = {
|
|
leftDelimiter: "{",
|
|
rightDelimiter: "}",
|
|
allowedAttributes: []
|
|
};
|
|
module.exports = function attributes(md, options_) {
|
|
let options = Object.assign({}, defaultOptions);
|
|
options = Object.assign(options, options_);
|
|
const patterns = patternsConfig(options);
|
|
function curlyAttrs(state) {
|
|
const tokens = state.tokens;
|
|
for (let i = 0; i < tokens.length; i++) {
|
|
for (let p = 0; p < patterns.length; p++) {
|
|
const pattern = patterns[p];
|
|
let j = null;
|
|
const match = pattern.tests.every((t) => {
|
|
const res = test(tokens, i, t);
|
|
if (res.j !== null) {
|
|
j = res.j;
|
|
}
|
|
return res.match;
|
|
});
|
|
if (match) {
|
|
try {
|
|
pattern.transform(tokens, i, j);
|
|
if (pattern.name === "inline attributes" || pattern.name === "inline nesting 0") {
|
|
p--;
|
|
}
|
|
} catch (error) {
|
|
console.error(`markdown-it-attrs: Error in pattern '${pattern.name}': ${error.message}`);
|
|
console.error(error.stack);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
md.core.ruler.before("linkify", "curly_attributes", curlyAttrs);
|
|
};
|
|
function test(tokens, i, t) {
|
|
const res = {
|
|
match: false,
|
|
j: null
|
|
// position of child
|
|
};
|
|
const ii = t.shift !== void 0 ? i + t.shift : t.position;
|
|
if (t.shift !== void 0 && ii < 0) {
|
|
return res;
|
|
}
|
|
const token = get(tokens, ii);
|
|
if (token === void 0) {
|
|
return res;
|
|
}
|
|
for (const key of Object.keys(t)) {
|
|
if (key === "shift" || key === "position") {
|
|
continue;
|
|
}
|
|
if (token[key] === void 0) {
|
|
return res;
|
|
}
|
|
if (key === "children" && isArrayOfObjects(t.children)) {
|
|
if (token.children.length === 0) {
|
|
return res;
|
|
}
|
|
let match;
|
|
const childTests = t.children;
|
|
const children = token.children;
|
|
if (childTests.every((tt) => tt.position !== void 0)) {
|
|
match = childTests.every((tt) => test(children, tt.position, tt).match);
|
|
if (match) {
|
|
const j = last(childTests).position;
|
|
res.j = j >= 0 ? j : children.length + j;
|
|
}
|
|
} else {
|
|
for (let j = 0; j < children.length; j++) {
|
|
match = childTests.every((tt) => test(children, j, tt).match);
|
|
if (match) {
|
|
res.j = j;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (match === false) {
|
|
return res;
|
|
}
|
|
continue;
|
|
}
|
|
switch (typeof t[key]) {
|
|
case "boolean":
|
|
case "number":
|
|
case "string":
|
|
if (token[key] !== t[key]) {
|
|
return res;
|
|
}
|
|
break;
|
|
case "function":
|
|
if (!t[key](token[key])) {
|
|
return res;
|
|
}
|
|
break;
|
|
case "object":
|
|
if (isArrayOfFunctions(t[key])) {
|
|
const r = t[key].every((tt) => tt(token[key]));
|
|
if (r === false) {
|
|
return res;
|
|
}
|
|
break;
|
|
}
|
|
// fall through for objects !== arrays of functions
|
|
default:
|
|
throw new Error(`Unknown type of pattern test (key: ${key}). Test should be of type boolean, number, string, function or array of functions.`);
|
|
}
|
|
}
|
|
res.match = true;
|
|
return res;
|
|
}
|
|
function isArrayOfObjects(arr) {
|
|
return Array.isArray(arr) && arr.length && arr.every((i) => typeof i === "object");
|
|
}
|
|
function isArrayOfFunctions(arr) {
|
|
return Array.isArray(arr) && arr.length && arr.every((i) => typeof i === "function");
|
|
}
|
|
function get(arr, n) {
|
|
return n >= 0 ? arr[n] : arr[arr.length + n];
|
|
}
|
|
function last(arr) {
|
|
return arr.slice(-1)[0] || {};
|
|
}
|
|
}
|
|
});
|
|
export default require_markdown_it_attrs();
|
|
//# sourceMappingURL=markdown-it-attrs.js.map
|