726 lines
21 KiB
JavaScript
726 lines
21 KiB
JavaScript
import { parse } from 'yaml';
|
|
import TokenClass from 'markdown-it/lib/token.mjs';
|
|
|
|
const NUMBER_CHAR_RE = /\d/;
|
|
const STR_SPLITTERS = ["-", "_", "/", "."];
|
|
function isUppercase(char = "") {
|
|
if (NUMBER_CHAR_RE.test(char)) {
|
|
return void 0;
|
|
}
|
|
return char !== char.toLowerCase();
|
|
}
|
|
function splitByCase(str, separators) {
|
|
const splitters = STR_SPLITTERS;
|
|
const parts = [];
|
|
if (!str || typeof str !== "string") {
|
|
return parts;
|
|
}
|
|
let buff = "";
|
|
let previousUpper;
|
|
let previousSplitter;
|
|
for (const char of str) {
|
|
const isSplitter = splitters.includes(char);
|
|
if (isSplitter === true) {
|
|
parts.push(buff);
|
|
buff = "";
|
|
previousUpper = void 0;
|
|
continue;
|
|
}
|
|
const isUpper = isUppercase(char);
|
|
if (previousSplitter === false) {
|
|
if (previousUpper === false && isUpper === true) {
|
|
parts.push(buff);
|
|
buff = char;
|
|
previousUpper = isUpper;
|
|
continue;
|
|
}
|
|
if (previousUpper === true && isUpper === false && buff.length > 1) {
|
|
const lastChar = buff.at(-1);
|
|
parts.push(buff.slice(0, Math.max(0, buff.length - 1)));
|
|
buff = lastChar + char;
|
|
previousUpper = isUpper;
|
|
continue;
|
|
}
|
|
}
|
|
buff += char;
|
|
previousUpper = isUpper;
|
|
previousSplitter = isSplitter;
|
|
}
|
|
parts.push(buff);
|
|
return parts;
|
|
}
|
|
function kebabCase(str, joiner) {
|
|
return str ? (Array.isArray(str) ? str : splitByCase(str)).map((p) => p.toLowerCase()).join("-") : "";
|
|
}
|
|
|
|
function parseBracketContent(str, startIndex) {
|
|
if (str[startIndex] !== "[")
|
|
return null;
|
|
let index = startIndex + 1;
|
|
while (index < str.length) {
|
|
if (str[index] === "\\" && index + 1 < str.length) {
|
|
index += 2;
|
|
continue;
|
|
}
|
|
if (str[index] === "]") {
|
|
const content = str.slice(startIndex + 1, index);
|
|
return { content, endIndex: index + 1 };
|
|
}
|
|
index += 1;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
const bracketPairs = {
|
|
"[": "]",
|
|
"{": "}",
|
|
"(": ")"
|
|
};
|
|
const quotePairs = {
|
|
"'": "'",
|
|
'"': '"',
|
|
"`": "`"
|
|
};
|
|
function searchProps(content, index = 0) {
|
|
if (content[index] !== "{")
|
|
throw new Error(`Invalid props, expected \`{\` but got '${content[index]}'`);
|
|
const props = [];
|
|
if (content[index + 1] === "{")
|
|
return void 0;
|
|
index += 1;
|
|
while (index < content.length) {
|
|
if (content[index] === "\\") {
|
|
index += 2;
|
|
} else if (content[index] === "}") {
|
|
index += 1;
|
|
break;
|
|
} else if (content[index] === " ") {
|
|
index += 1;
|
|
} else if (content[index] === ".") {
|
|
index += 1;
|
|
props.push([
|
|
"class",
|
|
searchUntil(" #.}")
|
|
]);
|
|
} else if (content[index] === "#") {
|
|
index += 1;
|
|
props.push([
|
|
"id",
|
|
searchUntil(" #.}")
|
|
]);
|
|
} else {
|
|
const start = index;
|
|
while (index < content.length) {
|
|
index += 1;
|
|
if (" }=".includes(content[index]))
|
|
break;
|
|
}
|
|
const char = content[index];
|
|
if (start !== index) {
|
|
const key = content.slice(start, index).trim();
|
|
if (char === "=") {
|
|
index += 1;
|
|
props.push([
|
|
key,
|
|
searchValue()
|
|
]);
|
|
} else {
|
|
props.push([
|
|
key,
|
|
"true"
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function searchUntil(str) {
|
|
const start = index;
|
|
while (index < content.length) {
|
|
index += 1;
|
|
if (content[index] === "\\")
|
|
index += 2;
|
|
if (str.includes(content[index]))
|
|
break;
|
|
}
|
|
return content.slice(start, index);
|
|
}
|
|
function searchValue() {
|
|
const start = index;
|
|
if (content[index] in bracketPairs) {
|
|
searchBracket(bracketPairs[content[index]]);
|
|
index += 1;
|
|
return content.slice(start, index);
|
|
} else if (content[index] in quotePairs) {
|
|
searchString(quotePairs[content[index]]);
|
|
index += 1;
|
|
return content.slice(start, index);
|
|
} else {
|
|
return searchUntil(" }");
|
|
}
|
|
}
|
|
function searchBracket(end) {
|
|
while (index < content.length) {
|
|
index++;
|
|
if (content[index] in quotePairs)
|
|
searchString(quotePairs[content[index]]);
|
|
else if (content[index] in bracketPairs)
|
|
searchBracket(bracketPairs[content[index]]);
|
|
else if (content[index] === end)
|
|
return;
|
|
}
|
|
}
|
|
function searchString(end) {
|
|
return searchUntil(end);
|
|
}
|
|
props.forEach((v) => {
|
|
if (v[1].match(/^(['"`]).*\1$/))
|
|
v[1] = v[1].slice(1, -1);
|
|
});
|
|
return {
|
|
props,
|
|
index
|
|
};
|
|
}
|
|
|
|
const RE_BLOCK_NAME = /^[a-z$][$\w.-]*/i;
|
|
function parseBlockParams(str) {
|
|
str = str.trim();
|
|
if (!str)
|
|
return { name: "" };
|
|
const name = str.match(RE_BLOCK_NAME)?.[0];
|
|
if (!name)
|
|
throw new Error(`Invalid block params: ${str}`);
|
|
let remaining = str.slice(name.length).trim();
|
|
let content;
|
|
let props;
|
|
let unparsedRemaining;
|
|
if (remaining.startsWith("[")) {
|
|
const result2 = parseBracketContent(remaining, 0);
|
|
if (result2) {
|
|
content = result2.content;
|
|
remaining = remaining.slice(result2.endIndex).trim();
|
|
}
|
|
}
|
|
if (remaining.startsWith("{")) {
|
|
const propsResult = searchProps(remaining, 0);
|
|
if (propsResult) {
|
|
props = propsResult.props;
|
|
const afterProps = remaining.slice(propsResult.index).trim();
|
|
if (afterProps) {
|
|
unparsedRemaining = afterProps;
|
|
}
|
|
}
|
|
} else if (remaining) {
|
|
unparsedRemaining = remaining;
|
|
}
|
|
const result = {
|
|
name: kebabCase(name)
|
|
};
|
|
if (content !== void 0) {
|
|
result.content = content;
|
|
}
|
|
if (props !== void 0) {
|
|
result.props = props;
|
|
}
|
|
if (unparsedRemaining) {
|
|
result.remaining = unparsedRemaining;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
const MarkdownItMdcBlock = (md) => {
|
|
const min_markers = 2;
|
|
const marker_str = ":";
|
|
const marker_char = marker_str.charCodeAt(0);
|
|
md.block.ruler.before(
|
|
"fence",
|
|
"mdc_block_shorthand",
|
|
// eslint-disable-next-line prefer-arrow-callback
|
|
function mdc_block_shorthand(state, startLine, endLine, silent) {
|
|
const line = state.src.slice(state.bMarks[startLine] + state.tShift[startLine], state.eMarks[startLine]);
|
|
if (!line.match(/^:\w/))
|
|
return false;
|
|
const parsed = parseBlockParams(line.slice(1));
|
|
const {
|
|
name,
|
|
content,
|
|
props,
|
|
remaining
|
|
} = parsed;
|
|
if (remaining) {
|
|
return false;
|
|
}
|
|
state.lineMax = startLine + 1;
|
|
if (!silent) {
|
|
if (content !== void 0) {
|
|
const tokenOpen = state.push("mdc_block_shorthand", name, 1);
|
|
props?.forEach(([key, value]) => {
|
|
if (key === "class")
|
|
tokenOpen.attrJoin(key, value);
|
|
else
|
|
tokenOpen.attrSet(key, value);
|
|
});
|
|
const inline = state.push("inline", "", 0);
|
|
inline.content = "";
|
|
const text = new state.Token("text", "", 0);
|
|
text.content = content;
|
|
inline.children = [text];
|
|
state.push("mdc_block_shorthand", name, -1);
|
|
} else {
|
|
const token = state.push("mdc_block_shorthand", name, 0);
|
|
props?.forEach(([key, value]) => {
|
|
if (key === "class")
|
|
token.attrJoin(key, value);
|
|
else
|
|
token.attrSet(key, value);
|
|
});
|
|
}
|
|
}
|
|
state.line = startLine + 1;
|
|
return true;
|
|
}
|
|
);
|
|
md.block.ruler.before(
|
|
"fence",
|
|
"mdc_block",
|
|
// eslint-disable-next-line prefer-arrow-callback
|
|
function mdc_block(state, startLine, endLine, silent) {
|
|
let pos;
|
|
let nextLine;
|
|
let auto_closed = false;
|
|
let start = state.bMarks[startLine] + state.tShift[startLine];
|
|
let max = state.eMarks[startLine];
|
|
const indent = state.sCount[startLine];
|
|
let inCodeFence = false;
|
|
let codeFenceCharCode = 0;
|
|
let codeFenceCount = 0;
|
|
let nestingDepth = 0;
|
|
if (state.src[start] !== ":")
|
|
return false;
|
|
for (pos = start + 1; pos <= max; pos++) {
|
|
if (marker_str !== state.src[pos])
|
|
break;
|
|
}
|
|
const marker_count = Math.floor(pos - start);
|
|
if (marker_count < min_markers)
|
|
return false;
|
|
const markup = state.src.slice(start, pos);
|
|
const params = parseBlockParams(state.src.slice(pos, max));
|
|
if (!params.name)
|
|
return false;
|
|
if (silent)
|
|
return true;
|
|
nextLine = startLine;
|
|
for (; ; ) {
|
|
nextLine++;
|
|
if (nextLine >= endLine) {
|
|
break;
|
|
}
|
|
start = state.bMarks[nextLine] + state.tShift[nextLine];
|
|
max = state.eMarks[nextLine];
|
|
if (start < max && state.sCount[nextLine] < state.blkIndent) {
|
|
break;
|
|
}
|
|
const lineCharCode = state.src.charCodeAt(start);
|
|
if (inCodeFence) {
|
|
if (lineCharCode === codeFenceCharCode) {
|
|
let fencePos = start + 1;
|
|
while (fencePos < max && state.src.charCodeAt(fencePos) === codeFenceCharCode)
|
|
fencePos++;
|
|
if (fencePos - start >= codeFenceCount) {
|
|
const afterFence = state.skipSpaces(fencePos);
|
|
if (afterFence >= max)
|
|
inCodeFence = false;
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
if (lineCharCode === 96 || lineCharCode === 126) {
|
|
let fencePos = start + 1;
|
|
while (fencePos < max && state.src.charCodeAt(fencePos) === lineCharCode)
|
|
fencePos++;
|
|
if (fencePos - start >= 3) {
|
|
inCodeFence = true;
|
|
codeFenceCharCode = lineCharCode;
|
|
codeFenceCount = fencePos - start;
|
|
continue;
|
|
}
|
|
}
|
|
if (marker_char !== lineCharCode)
|
|
continue;
|
|
for (pos = start + 1; pos <= max; pos++) {
|
|
if (marker_str !== state.src[pos])
|
|
break;
|
|
}
|
|
if (pos - start !== marker_count)
|
|
continue;
|
|
pos = state.skipSpaces(pos);
|
|
if (pos < max) {
|
|
nestingDepth++;
|
|
continue;
|
|
}
|
|
if (nestingDepth > 0) {
|
|
nestingDepth--;
|
|
continue;
|
|
}
|
|
auto_closed = true;
|
|
break;
|
|
}
|
|
const old_parent = state.parentType;
|
|
const old_line_max = state.lineMax;
|
|
state.parentType = "mdc_block";
|
|
state.lineMax = nextLine;
|
|
const tokenOpen = state.push("mdc_block_open", params.name, 1);
|
|
tokenOpen.markup = markup;
|
|
tokenOpen.block = true;
|
|
tokenOpen.info = params.name;
|
|
tokenOpen.map = [startLine, nextLine];
|
|
if (params.props) {
|
|
params.props?.forEach(([key, value]) => {
|
|
if (key === "class")
|
|
tokenOpen.attrJoin(key, value);
|
|
else
|
|
tokenOpen.attrSet(key, value);
|
|
});
|
|
}
|
|
const blkIndent = state.blkIndent;
|
|
state.blkIndent = indent;
|
|
state.env.mdcBlockTokens ||= [];
|
|
state.env.mdcBlockTokens.unshift(tokenOpen);
|
|
state.md.block.tokenize(state, startLine + 1, nextLine);
|
|
state.blkIndent = blkIndent;
|
|
state.env.mdcBlockTokens.shift(tokenOpen);
|
|
const tokenClose = state.push("mdc_block_close", params.name, -1);
|
|
tokenClose.map = [startLine, nextLine];
|
|
tokenClose.markup = state.src.slice(start, pos);
|
|
tokenClose.block = true;
|
|
state.tokens.slice(
|
|
state.tokens.indexOf(tokenOpen) + 1,
|
|
state.tokens.indexOf(tokenClose)
|
|
).filter((i) => i.level === tokenOpen.level + 1).forEach((i, _, arr) => {
|
|
if (arr.length <= 2 && i.tag === "p")
|
|
i.hidden = true;
|
|
});
|
|
state.parentType = old_parent;
|
|
state.lineMax = old_line_max;
|
|
state.line = nextLine + (auto_closed ? 1 : 0);
|
|
return true;
|
|
},
|
|
{
|
|
alt: ["paragraph", "reference", "blockquote", "list"]
|
|
}
|
|
);
|
|
md.block.ruler.after(
|
|
"code",
|
|
"mdc_block_yaml",
|
|
// eslint-disable-next-line prefer-arrow-callback
|
|
function mdc_block_yaml(state, startLine, endLine, silent) {
|
|
if (!state.env.mdcBlockTokens?.length)
|
|
return false;
|
|
const start = state.bMarks[startLine] + state.tShift[startLine];
|
|
const end = state.eMarks[startLine];
|
|
if (state.src.slice(start, end) !== "---")
|
|
return false;
|
|
let lineEnd = startLine + 1;
|
|
let found = false;
|
|
while (lineEnd < endLine) {
|
|
const line = state.src.slice(state.bMarks[lineEnd] + state.tShift[startLine], state.eMarks[lineEnd]);
|
|
if (line === "---") {
|
|
found = true;
|
|
break;
|
|
}
|
|
lineEnd += 1;
|
|
}
|
|
if (!found)
|
|
return false;
|
|
if (!silent) {
|
|
const yaml = state.src.slice(state.bMarks[startLine + 1], state.eMarks[lineEnd - 1]);
|
|
const data = parse(yaml);
|
|
const token = state.env.mdcBlockTokens[0];
|
|
Object.entries(data || {}).forEach(([key, value]) => {
|
|
if (key === "class")
|
|
token.attrJoin(key, value);
|
|
else
|
|
token.attrSet(key, typeof value === "string" ? value : JSON.stringify(value));
|
|
});
|
|
}
|
|
state.line = lineEnd + 1;
|
|
state.lineMax = lineEnd + 1;
|
|
return true;
|
|
}
|
|
);
|
|
md.block.ruler.after(
|
|
"code",
|
|
"mdc_block_slots",
|
|
// eslint-disable-next-line prefer-arrow-callback
|
|
function mdc_block(state, startLine, endLine, silent) {
|
|
if (!state.env.mdcBlockTokens?.length)
|
|
return false;
|
|
const start = state.bMarks[startLine] + state.tShift[startLine];
|
|
if (!(state.src[start] === "#" && state.src[start + 1] !== " "))
|
|
return false;
|
|
const line = state.src.slice(start, state.eMarks[startLine]);
|
|
const {
|
|
name,
|
|
props
|
|
} = parseBlockParams(line.slice(1));
|
|
let lineEnd = startLine + 1;
|
|
while (lineEnd < endLine) {
|
|
const line2 = state.src.slice(state.bMarks[lineEnd] + state.tShift[startLine], state.eMarks[lineEnd]);
|
|
if (line2.match(/^#(\w)+/) || line2.startsWith("::"))
|
|
break;
|
|
lineEnd += 1;
|
|
}
|
|
if (silent) {
|
|
state.line = lineEnd;
|
|
state.lineMax = lineEnd;
|
|
return true;
|
|
}
|
|
state.lineMax = startLine + 1;
|
|
const slot = state.push("mdc_block_slot", "template", 1);
|
|
slot.attrSet(`#${name}`, "");
|
|
props?.forEach(([key, value]) => {
|
|
if (key === "class")
|
|
slot.attrJoin(key, value);
|
|
else
|
|
slot.attrSet(key, value);
|
|
});
|
|
state.line = startLine + 1;
|
|
state.lineMax = lineEnd;
|
|
state.md.block.tokenize(state, startLine + 1, lineEnd);
|
|
state.push("mdc_block_slot", "template", -1);
|
|
state.line = lineEnd;
|
|
state.lineMax = lineEnd;
|
|
return true;
|
|
}
|
|
);
|
|
};
|
|
|
|
const ALLOWED_PREV_CHARS = /* @__PURE__ */ new Set([" ", " ", "\n", "*", "_", "["]);
|
|
const MarkdownItInlineComponent = (md) => {
|
|
md.inline.ruler.after("entity", "mdc_inline_component", (state, silent) => {
|
|
const start = state.pos;
|
|
const char = state.src[start];
|
|
if (char !== ":")
|
|
return false;
|
|
const prevChar = state.src[start - 1];
|
|
if (start > 0 && !ALLOWED_PREV_CHARS.has(prevChar))
|
|
return false;
|
|
let index = start + 1;
|
|
let nameEnd = -1;
|
|
let content;
|
|
while (index < state.src.length) {
|
|
const char2 = state.src[index];
|
|
if (char2 === "[") {
|
|
nameEnd = index;
|
|
const result = parseBracketContent(state.src, index);
|
|
if (result) {
|
|
content = result.content;
|
|
index = result.endIndex;
|
|
}
|
|
break;
|
|
}
|
|
if (!/[\w$\-]/.test(char2))
|
|
break;
|
|
index += 1;
|
|
}
|
|
if (nameEnd === -1)
|
|
nameEnd = index;
|
|
if (nameEnd <= start + 1)
|
|
return false;
|
|
state.pos = index;
|
|
if (silent)
|
|
return true;
|
|
const name = state.src.slice(start + 1, nameEnd);
|
|
if (content !== void 0) {
|
|
state.push("mdc_inline_component", name, 1);
|
|
const text = state.push("text", "", 0);
|
|
text.content = content;
|
|
state.push("mdc_inline_component", name, -1);
|
|
} else {
|
|
state.push("mdc_inline_component", name, 0);
|
|
}
|
|
return true;
|
|
});
|
|
};
|
|
|
|
const MarkdownItInlineProps = (md) => {
|
|
md.inline.ruler.after("entity", "mdc_inline_props", (state, silent) => {
|
|
const start = state.pos;
|
|
const char = state.src[start];
|
|
if (char !== "{")
|
|
return false;
|
|
if (state.src[start + 1] === "{" || state.src[start - 1] === "{" || state.src[start - 1] === "$")
|
|
return false;
|
|
const search = searchProps(state.src, start);
|
|
if (!search)
|
|
return false;
|
|
const {
|
|
props,
|
|
index: end
|
|
} = search;
|
|
if (end === start)
|
|
return false;
|
|
state.pos = end;
|
|
if (silent)
|
|
return true;
|
|
const token = state.push("mdc_inline_props", "span", 0);
|
|
token.attrs = props;
|
|
token.hidden = true;
|
|
return true;
|
|
});
|
|
md.renderer.rules.mdc_inline_props = () => {
|
|
return "";
|
|
};
|
|
const _parse = md.parse;
|
|
md.parse = function(src, env) {
|
|
const tokens = _parse.call(this, src, env);
|
|
tokens.forEach((token, index) => {
|
|
const prev = tokens[index - 1];
|
|
const next = tokens[index + 1];
|
|
if (!["heading_open", "paragraph_open", "list_item_open"].includes(prev?.type) || prev.hidden)
|
|
return;
|
|
if (token.hidden && next.type === "inline")
|
|
token = next;
|
|
if (token.type === "inline" && token.children?.length === 2 && token.children[0].type === "text" && token.children[1].type === "mdc_inline_props") {
|
|
const props = token.children[1].attrs;
|
|
token.children.splice(1, 1);
|
|
props?.forEach(([key, value]) => {
|
|
if (key === "class")
|
|
prev.attrJoin("class", value);
|
|
else
|
|
prev.attrSet(key, value);
|
|
});
|
|
}
|
|
});
|
|
tokens.forEach((tokenOpen, index) => {
|
|
if (tokenOpen.type !== "bullet_list_open")
|
|
return;
|
|
const prev = tokens[index - 1];
|
|
if (!prev || prev.type !== "mdc_block_open" || prev.tag !== "ul")
|
|
return;
|
|
let closeIndex = index + 1;
|
|
while (closeIndex < tokens.length) {
|
|
const close = tokens[closeIndex];
|
|
if (close.type === "bullet_list_close" && close.level === tokenOpen.level)
|
|
break;
|
|
closeIndex += 1;
|
|
}
|
|
const tokenClose = tokens[closeIndex];
|
|
if (tokenClose.type !== "bullet_list_close")
|
|
return;
|
|
const next = tokens[closeIndex + 1];
|
|
if (next.type === "mdc_block_close" && next.tag === "ul") {
|
|
tokenOpen.hidden = true;
|
|
tokenClose.hidden = true;
|
|
}
|
|
});
|
|
return tokens;
|
|
};
|
|
const _renderInline = md.renderer.renderInline;
|
|
md.renderer.renderInline = function(tokens, options, env) {
|
|
tokens = [...tokens];
|
|
tokens.forEach((token, index) => {
|
|
if (token.type === "mdc_inline_props") {
|
|
let prevIndex = index - 1;
|
|
let prev = tokens[prevIndex];
|
|
while (prevIndex >= 0) {
|
|
if (prev.type === "text" && !prev.content.trim()) {
|
|
prevIndex--;
|
|
prev = tokens[prevIndex];
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
if (!prev.tag && prev.type === "text") {
|
|
prev = new TokenClass("mdc_inline_span", "span", 1);
|
|
tokens.splice(index - 1, 0, prev);
|
|
const close = new TokenClass("mdc_inline_span", "span", -1);
|
|
tokens.splice(index + 2, 0, close);
|
|
} else if (prev.nesting === -1) {
|
|
let searchIndex = index - 1;
|
|
while (searchIndex >= 0) {
|
|
const searchToken = tokens[searchIndex];
|
|
if (searchToken.nesting === 1 && searchToken.tag === prev.tag && searchToken.level === prev.level) {
|
|
prev = searchToken;
|
|
break;
|
|
}
|
|
searchIndex--;
|
|
}
|
|
}
|
|
if (prev.nesting === -1)
|
|
throw new Error(`No matching opening tag found for ${JSON.stringify(prev)}`);
|
|
token.attrs?.forEach(([key, value]) => {
|
|
if (key === "class")
|
|
prev.attrJoin("class", value);
|
|
else
|
|
prev.attrSet(key, value);
|
|
});
|
|
}
|
|
});
|
|
return _renderInline.call(this, tokens, options, env);
|
|
};
|
|
};
|
|
|
|
const MarkdownItInlineSpan = (md) => {
|
|
md.inline.ruler.before("link", "mdc_inline_span", (state, silent) => {
|
|
const start = state.pos;
|
|
const char = state.src[start];
|
|
if (char !== "[")
|
|
return false;
|
|
let index = start + 1;
|
|
let depth = 0;
|
|
while (index < state.src.length) {
|
|
if (state.src[index] === "\\") {
|
|
index += 2;
|
|
continue;
|
|
}
|
|
if (state.src[index] === "[") {
|
|
depth++;
|
|
} else if (state.src[index] === "]") {
|
|
if (depth === 0)
|
|
break;
|
|
depth--;
|
|
}
|
|
index += 1;
|
|
}
|
|
if (index === start)
|
|
return false;
|
|
const nextChar = state.src[index + 1];
|
|
if (nextChar === "(" || nextChar === "[")
|
|
return false;
|
|
if (silent)
|
|
return true;
|
|
state.push("mdc_inline_span", "span", 1);
|
|
const oldPos = state.pos;
|
|
const oldPosMax = state.posMax;
|
|
state.pos = start + 1;
|
|
state.posMax = index;
|
|
state.md.inline.tokenize(state);
|
|
state.pos = oldPos;
|
|
state.posMax = oldPosMax;
|
|
state.push("mdc_inline_span", "span", -1);
|
|
state.pos = index + 1;
|
|
return true;
|
|
});
|
|
};
|
|
|
|
const MarkdownItMdc = (md, options = {}) => {
|
|
const {
|
|
blockComponent = true,
|
|
inlineProps = true,
|
|
inlineSpan = true,
|
|
inlineComponent = true
|
|
} = options.syntax || {};
|
|
if (blockComponent)
|
|
md.use(MarkdownItMdcBlock);
|
|
if (inlineProps)
|
|
md.use(MarkdownItInlineProps);
|
|
if (inlineSpan)
|
|
md.use(MarkdownItInlineSpan);
|
|
if (inlineComponent)
|
|
md.use(MarkdownItInlineComponent);
|
|
};
|
|
|
|
export { MarkdownItMdc as default };
|