UNPKG

mermaid

Version:

Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.

1,699 lines 140 kB
import { b8 as dedent, l as log, b7 as decodeEntities } from "./mermaid-dcacb631.js"; const emptyOptions = {}; function toString(value, options) { const settings = options || emptyOptions; const includeImageAlt = typeof settings.includeImageAlt === "boolean" ? settings.includeImageAlt : true; const includeHtml = typeof settings.includeHtml === "boolean" ? settings.includeHtml : true; return one(value, includeImageAlt, includeHtml); } function one(value, includeImageAlt, includeHtml) { if (node(value)) { if ("value" in value) { return value.type === "html" && !includeHtml ? "" : value.value; } if (includeImageAlt && "alt" in value && value.alt) { return value.alt; } if ("children" in value) { return all(value.children, includeImageAlt, includeHtml); } } if (Array.isArray(value)) { return all(value, includeImageAlt, includeHtml); } return ""; } function all(values, includeImageAlt, includeHtml) { const result = []; let index2 = -1; while (++index2 < values.length) { result[index2] = one(values[index2], includeImageAlt, includeHtml); } return result.join(""); } function node(value) { return Boolean(value && typeof value === "object"); } function splice(list2, start, remove, items) { const end = list2.length; let chunkStart = 0; let parameters; if (start < 0) { start = -start > end ? 0 : end + start; } else { start = start > end ? end : start; } remove = remove > 0 ? remove : 0; if (items.length < 1e4) { parameters = Array.from(items); parameters.unshift(start, remove); list2.splice(...parameters); } else { if (remove) list2.splice(start, remove); while (chunkStart < items.length) { parameters = items.slice(chunkStart, chunkStart + 1e4); parameters.unshift(start, 0); list2.splice(...parameters); chunkStart += 1e4; start += 1e4; } } } function push(list2, items) { if (list2.length > 0) { splice(list2, list2.length, 0, items); return list2; } return items; } const hasOwnProperty = {}.hasOwnProperty; function combineExtensions(extensions) { const all2 = {}; let index2 = -1; while (++index2 < extensions.length) { syntaxExtension(all2, extensions[index2]); } return all2; } function syntaxExtension(all2, extension2) { let hook; for (hook in extension2) { const maybe = hasOwnProperty.call(all2, hook) ? all2[hook] : void 0; const left = maybe || (all2[hook] = {}); const right = extension2[hook]; let code; if (right) { for (code in right) { if (!hasOwnProperty.call(left, code)) left[code] = []; const value = right[code]; constructs( // @ts-expect-error Looks like a list. left[code], Array.isArray(value) ? value : value ? [value] : [] ); } } } } function constructs(existing, list2) { let index2 = -1; const before = []; while (++index2 < list2.length) { (list2[index2].add === "after" ? existing : before).push(list2[index2]); } splice(existing, 0, 0, before); } const unicodePunctuationRegex = /[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/; const asciiAlpha = regexCheck(/[A-Za-z]/); const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/); const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/); function asciiControl(code) { return ( // Special whitespace codes (which have negative values), C0 and Control // character DEL code !== null && (code < 32 || code === 127) ); } const asciiDigit = regexCheck(/\d/); const asciiHexDigit = regexCheck(/[\dA-Fa-f]/); const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/); function markdownLineEnding(code) { return code !== null && code < -2; } function markdownLineEndingOrSpace(code) { return code !== null && (code < 0 || code === 32); } function markdownSpace(code) { return code === -2 || code === -1 || code === 32; } const unicodePunctuation = regexCheck(unicodePunctuationRegex); const unicodeWhitespace = regexCheck(/\s/); function regexCheck(regex) { return check; function check(code) { return code !== null && regex.test(String.fromCharCode(code)); } } function factorySpace(effects, ok, type, max) { const limit = max ? max - 1 : Number.POSITIVE_INFINITY; let size = 0; return start; function start(code) { if (markdownSpace(code)) { effects.enter(type); return prefix(code); } return ok(code); } function prefix(code) { if (markdownSpace(code) && size++ < limit) { effects.consume(code); return prefix; } effects.exit(type); return ok(code); } } const content$1 = { tokenize: initializeContent }; function initializeContent(effects) { const contentStart = effects.attempt( this.parser.constructs.contentInitial, afterContentStartConstruct, paragraphInitial ); let previous2; return contentStart; function afterContentStartConstruct(code) { if (code === null) { effects.consume(code); return; } effects.enter("lineEnding"); effects.consume(code); effects.exit("lineEnding"); return factorySpace(effects, contentStart, "linePrefix"); } function paragraphInitial(code) { effects.enter("paragraph"); return lineStart(code); } function lineStart(code) { const token = effects.enter("chunkText", { contentType: "text", previous: previous2 }); if (previous2) { previous2.next = token; } previous2 = token; return data(code); } function data(code) { if (code === null) { effects.exit("chunkText"); effects.exit("paragraph"); effects.consume(code); return; } if (markdownLineEnding(code)) { effects.consume(code); effects.exit("chunkText"); return lineStart; } effects.consume(code); return data; } } const document$2 = { tokenize: initializeDocument }; const containerConstruct = { tokenize: tokenizeContainer }; function initializeDocument(effects) { const self = this; const stack = []; let continued = 0; let childFlow; let childToken; let lineStartOffset; return start; function start(code) { if (continued < stack.length) { const item = stack[continued]; self.containerState = item[1]; return effects.attempt( item[0].continuation, documentContinue, checkNewContainers )(code); } return checkNewContainers(code); } function documentContinue(code) { continued++; if (self.containerState._closeFlow) { self.containerState._closeFlow = void 0; if (childFlow) { closeFlow(); } const indexBeforeExits = self.events.length; let indexBeforeFlow = indexBeforeExits; let point2; while (indexBeforeFlow--) { if (self.events[indexBeforeFlow][0] === "exit" && self.events[indexBeforeFlow][1].type === "chunkFlow") { point2 = self.events[indexBeforeFlow][1].end; break; } } exitContainers(continued); let index2 = indexBeforeExits; while (index2 < self.events.length) { self.events[index2][1].end = Object.assign({}, point2); index2++; } splice( self.events, indexBeforeFlow + 1, 0, self.events.slice(indexBeforeExits) ); self.events.length = index2; return checkNewContainers(code); } return start(code); } function checkNewContainers(code) { if (continued === stack.length) { if (!childFlow) { return documentContinued(code); } if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { return flowStart(code); } self.interrupt = Boolean( childFlow.currentConstruct && !childFlow._gfmTableDynamicInterruptHack ); } self.containerState = {}; return effects.check( containerConstruct, thereIsANewContainer, thereIsNoNewContainer )(code); } function thereIsANewContainer(code) { if (childFlow) closeFlow(); exitContainers(continued); return documentContinued(code); } function thereIsNoNewContainer(code) { self.parser.lazy[self.now().line] = continued !== stack.length; lineStartOffset = self.now().offset; return flowStart(code); } function documentContinued(code) { self.containerState = {}; return effects.attempt( containerConstruct, containerContinue, flowStart )(code); } function containerContinue(code) { continued++; stack.push([self.currentConstruct, self.containerState]); return documentContinued(code); } function flowStart(code) { if (code === null) { if (childFlow) closeFlow(); exitContainers(0); effects.consume(code); return; } childFlow = childFlow || self.parser.flow(self.now()); effects.enter("chunkFlow", { contentType: "flow", previous: childToken, _tokenizer: childFlow }); return flowContinue(code); } function flowContinue(code) { if (code === null) { writeToChild(effects.exit("chunkFlow"), true); exitContainers(0); effects.consume(code); return; } if (markdownLineEnding(code)) { effects.consume(code); writeToChild(effects.exit("chunkFlow")); continued = 0; self.interrupt = void 0; return start; } effects.consume(code); return flowContinue; } function writeToChild(token, eof) { const stream = self.sliceStream(token); if (eof) stream.push(null); token.previous = childToken; if (childToken) childToken.next = token; childToken = token; childFlow.defineSkip(token.start); childFlow.write(stream); if (self.parser.lazy[token.start.line]) { let index2 = childFlow.events.length; while (index2--) { if ( // The token starts before the line ending… childFlow.events[index2][1].start.offset < lineStartOffset && // …and either is not ended yet… (!childFlow.events[index2][1].end || // …or ends after it. childFlow.events[index2][1].end.offset > lineStartOffset) ) { return; } } const indexBeforeExits = self.events.length; let indexBeforeFlow = indexBeforeExits; let seen; let point2; while (indexBeforeFlow--) { if (self.events[indexBeforeFlow][0] === "exit" && self.events[indexBeforeFlow][1].type === "chunkFlow") { if (seen) { point2 = self.events[indexBeforeFlow][1].end; break; } seen = true; } } exitContainers(continued); index2 = indexBeforeExits; while (index2 < self.events.length) { self.events[index2][1].end = Object.assign({}, point2); index2++; } splice( self.events, indexBeforeFlow + 1, 0, self.events.slice(indexBeforeExits) ); self.events.length = index2; } } function exitContainers(size) { let index2 = stack.length; while (index2-- > size) { const entry = stack[index2]; self.containerState = entry[1]; entry[0].exit.call(self, effects); } stack.length = size; } function closeFlow() { childFlow.write([null]); childToken = void 0; childFlow = void 0; self.containerState._closeFlow = void 0; } } function tokenizeContainer(effects, ok, nok) { return factorySpace( effects, effects.attempt(this.parser.constructs.document, ok, nok), "linePrefix", this.parser.constructs.disable.null.includes("codeIndented") ? void 0 : 4 ); } function classifyCharacter(code) { if (code === null || markdownLineEndingOrSpace(code) || unicodeWhitespace(code)) { return 1; } if (unicodePunctuation(code)) { return 2; } } function resolveAll(constructs2, events, context) { const called = []; let index2 = -1; while (++index2 < constructs2.length) { const resolve = constructs2[index2].resolveAll; if (resolve && !called.includes(resolve)) { events = resolve(events, context); called.push(resolve); } } return events; } const attention = { name: "attention", tokenize: tokenizeAttention, resolveAll: resolveAllAttention }; function resolveAllAttention(events, context) { let index2 = -1; let open; let group; let text2; let openingSequence; let closingSequence; let use; let nextEvents; let offset; while (++index2 < events.length) { if (events[index2][0] === "enter" && events[index2][1].type === "attentionSequence" && events[index2][1]._close) { open = index2; while (open--) { if (events[open][0] === "exit" && events[open][1].type === "attentionSequence" && events[open][1]._open && // If the markers are the same: context.sliceSerialize(events[open][1]).charCodeAt(0) === context.sliceSerialize(events[index2][1]).charCodeAt(0)) { if ((events[open][1]._close || events[index2][1]._open) && (events[index2][1].end.offset - events[index2][1].start.offset) % 3 && !((events[open][1].end.offset - events[open][1].start.offset + events[index2][1].end.offset - events[index2][1].start.offset) % 3)) { continue; } use = events[open][1].end.offset - events[open][1].start.offset > 1 && events[index2][1].end.offset - events[index2][1].start.offset > 1 ? 2 : 1; const start = Object.assign({}, events[open][1].end); const end = Object.assign({}, events[index2][1].start); movePoint(start, -use); movePoint(end, use); openingSequence = { type: use > 1 ? "strongSequence" : "emphasisSequence", start, end: Object.assign({}, events[open][1].end) }; closingSequence = { type: use > 1 ? "strongSequence" : "emphasisSequence", start: Object.assign({}, events[index2][1].start), end }; text2 = { type: use > 1 ? "strongText" : "emphasisText", start: Object.assign({}, events[open][1].end), end: Object.assign({}, events[index2][1].start) }; group = { type: use > 1 ? "strong" : "emphasis", start: Object.assign({}, openingSequence.start), end: Object.assign({}, closingSequence.end) }; events[open][1].end = Object.assign({}, openingSequence.start); events[index2][1].start = Object.assign({}, closingSequence.end); nextEvents = []; if (events[open][1].end.offset - events[open][1].start.offset) { nextEvents = push(nextEvents, [ ["enter", events[open][1], context], ["exit", events[open][1], context] ]); } nextEvents = push(nextEvents, [ ["enter", group, context], ["enter", openingSequence, context], ["exit", openingSequence, context], ["enter", text2, context] ]); nextEvents = push( nextEvents, resolveAll( context.parser.constructs.insideSpan.null, events.slice(open + 1, index2), context ) ); nextEvents = push(nextEvents, [ ["exit", text2, context], ["enter", closingSequence, context], ["exit", closingSequence, context], ["exit", group, context] ]); if (events[index2][1].end.offset - events[index2][1].start.offset) { offset = 2; nextEvents = push(nextEvents, [ ["enter", events[index2][1], context], ["exit", events[index2][1], context] ]); } else { offset = 0; } splice(events, open - 1, index2 - open + 3, nextEvents); index2 = open + nextEvents.length - offset - 2; break; } } } } index2 = -1; while (++index2 < events.length) { if (events[index2][1].type === "attentionSequence") { events[index2][1].type = "data"; } } return events; } function tokenizeAttention(effects, ok) { const attentionMarkers2 = this.parser.constructs.attentionMarkers.null; const previous2 = this.previous; const before = classifyCharacter(previous2); let marker; return start; function start(code) { marker = code; effects.enter("attentionSequence"); return inside(code); } function inside(code) { if (code === marker) { effects.consume(code); return inside; } const token = effects.exit("attentionSequence"); const after = classifyCharacter(code); const open = !after || after === 2 && before || attentionMarkers2.includes(code); const close = !before || before === 2 && after || attentionMarkers2.includes(previous2); token._open = Boolean(marker === 42 ? open : open && (before || !close)); token._close = Boolean(marker === 42 ? close : close && (after || !open)); return ok(code); } } function movePoint(point2, offset) { point2.column += offset; point2.offset += offset; point2._bufferIndex += offset; } const autolink = { name: "autolink", tokenize: tokenizeAutolink }; function tokenizeAutolink(effects, ok, nok) { let size = 0; return start; function start(code) { effects.enter("autolink"); effects.enter("autolinkMarker"); effects.consume(code); effects.exit("autolinkMarker"); effects.enter("autolinkProtocol"); return open; } function open(code) { if (asciiAlpha(code)) { effects.consume(code); return schemeOrEmailAtext; } return emailAtext(code); } function schemeOrEmailAtext(code) { if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) { size = 1; return schemeInsideOrEmailAtext(code); } return emailAtext(code); } function schemeInsideOrEmailAtext(code) { if (code === 58) { effects.consume(code); size = 0; return urlInside; } if ((code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && size++ < 32) { effects.consume(code); return schemeInsideOrEmailAtext; } size = 0; return emailAtext(code); } function urlInside(code) { if (code === 62) { effects.exit("autolinkProtocol"); effects.enter("autolinkMarker"); effects.consume(code); effects.exit("autolinkMarker"); effects.exit("autolink"); return ok; } if (code === null || code === 32 || code === 60 || asciiControl(code)) { return nok(code); } effects.consume(code); return urlInside; } function emailAtext(code) { if (code === 64) { effects.consume(code); return emailAtSignOrDot; } if (asciiAtext(code)) { effects.consume(code); return emailAtext; } return nok(code); } function emailAtSignOrDot(code) { return asciiAlphanumeric(code) ? emailLabel(code) : nok(code); } function emailLabel(code) { if (code === 46) { effects.consume(code); size = 0; return emailAtSignOrDot; } if (code === 62) { effects.exit("autolinkProtocol").type = "autolinkEmail"; effects.enter("autolinkMarker"); effects.consume(code); effects.exit("autolinkMarker"); effects.exit("autolink"); return ok; } return emailValue(code); } function emailValue(code) { if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { const next = code === 45 ? emailValue : emailLabel; effects.consume(code); return next; } return nok(code); } } const blankLine = { tokenize: tokenizeBlankLine, partial: true }; function tokenizeBlankLine(effects, ok, nok) { return start; function start(code) { return markdownSpace(code) ? factorySpace(effects, after, "linePrefix")(code) : after(code); } function after(code) { return code === null || markdownLineEnding(code) ? ok(code) : nok(code); } } const blockQuote = { name: "blockQuote", tokenize: tokenizeBlockQuoteStart, continuation: { tokenize: tokenizeBlockQuoteContinuation }, exit }; function tokenizeBlockQuoteStart(effects, ok, nok) { const self = this; return start; function start(code) { if (code === 62) { const state = self.containerState; if (!state.open) { effects.enter("blockQuote", { _container: true }); state.open = true; } effects.enter("blockQuotePrefix"); effects.enter("blockQuoteMarker"); effects.consume(code); effects.exit("blockQuoteMarker"); return after; } return nok(code); } function after(code) { if (markdownSpace(code)) { effects.enter("blockQuotePrefixWhitespace"); effects.consume(code); effects.exit("blockQuotePrefixWhitespace"); effects.exit("blockQuotePrefix"); return ok; } effects.exit("blockQuotePrefix"); return ok(code); } } function tokenizeBlockQuoteContinuation(effects, ok, nok) { const self = this; return contStart; function contStart(code) { if (markdownSpace(code)) { return factorySpace( effects, contBefore, "linePrefix", self.parser.constructs.disable.null.includes("codeIndented") ? void 0 : 4 )(code); } return contBefore(code); } function contBefore(code) { return effects.attempt(blockQuote, ok, nok)(code); } } function exit(effects) { effects.exit("blockQuote"); } const characterEscape = { name: "characterEscape", tokenize: tokenizeCharacterEscape }; function tokenizeCharacterEscape(effects, ok, nok) { return start; function start(code) { effects.enter("characterEscape"); effects.enter("escapeMarker"); effects.consume(code); effects.exit("escapeMarker"); return inside; } function inside(code) { if (asciiPunctuation(code)) { effects.enter("characterEscapeValue"); effects.consume(code); effects.exit("characterEscapeValue"); effects.exit("characterEscape"); return ok; } return nok(code); } } const element = document.createElement("i"); function decodeNamedCharacterReference(value) { const characterReference2 = "&" + value + ";"; element.innerHTML = characterReference2; const char = element.textContent; if (char.charCodeAt(char.length - 1) === 59 && value !== "semi") { return false; } return char === characterReference2 ? false : char; } const characterReference = { name: "characterReference", tokenize: tokenizeCharacterReference }; function tokenizeCharacterReference(effects, ok, nok) { const self = this; let size = 0; let max; let test; return start; function start(code) { effects.enter("characterReference"); effects.enter("characterReferenceMarker"); effects.consume(code); effects.exit("characterReferenceMarker"); return open; } function open(code) { if (code === 35) { effects.enter("characterReferenceMarkerNumeric"); effects.consume(code); effects.exit("characterReferenceMarkerNumeric"); return numeric; } effects.enter("characterReferenceValue"); max = 31; test = asciiAlphanumeric; return value(code); } function numeric(code) { if (code === 88 || code === 120) { effects.enter("characterReferenceMarkerHexadecimal"); effects.consume(code); effects.exit("characterReferenceMarkerHexadecimal"); effects.enter("characterReferenceValue"); max = 6; test = asciiHexDigit; return value; } effects.enter("characterReferenceValue"); max = 7; test = asciiDigit; return value(code); } function value(code) { if (code === 59 && size) { const token = effects.exit("characterReferenceValue"); if (test === asciiAlphanumeric && !decodeNamedCharacterReference(self.sliceSerialize(token))) { return nok(code); } effects.enter("characterReferenceMarker"); effects.consume(code); effects.exit("characterReferenceMarker"); effects.exit("characterReference"); return ok; } if (test(code) && size++ < max) { effects.consume(code); return value; } return nok(code); } } const nonLazyContinuation = { tokenize: tokenizeNonLazyContinuation, partial: true }; const codeFenced = { name: "codeFenced", tokenize: tokenizeCodeFenced, concrete: true }; function tokenizeCodeFenced(effects, ok, nok) { const self = this; const closeStart = { tokenize: tokenizeCloseStart, partial: true }; let initialPrefix = 0; let sizeOpen = 0; let marker; return start; function start(code) { return beforeSequenceOpen(code); } function beforeSequenceOpen(code) { const tail = self.events[self.events.length - 1]; initialPrefix = tail && tail[1].type === "linePrefix" ? tail[2].sliceSerialize(tail[1], true).length : 0; marker = code; effects.enter("codeFenced"); effects.enter("codeFencedFence"); effects.enter("codeFencedFenceSequence"); return sequenceOpen(code); } function sequenceOpen(code) { if (code === marker) { sizeOpen++; effects.consume(code); return sequenceOpen; } if (sizeOpen < 3) { return nok(code); } effects.exit("codeFencedFenceSequence"); return markdownSpace(code) ? factorySpace(effects, infoBefore, "whitespace")(code) : infoBefore(code); } function infoBefore(code) { if (code === null || markdownLineEnding(code)) { effects.exit("codeFencedFence"); return self.interrupt ? ok(code) : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code); } effects.enter("codeFencedFenceInfo"); effects.enter("chunkString", { contentType: "string" }); return info(code); } function info(code) { if (code === null || markdownLineEnding(code)) { effects.exit("chunkString"); effects.exit("codeFencedFenceInfo"); return infoBefore(code); } if (markdownSpace(code)) { effects.exit("chunkString"); effects.exit("codeFencedFenceInfo"); return factorySpace(effects, metaBefore, "whitespace")(code); } if (code === 96 && code === marker) { return nok(code); } effects.consume(code); return info; } function metaBefore(code) { if (code === null || markdownLineEnding(code)) { return infoBefore(code); } effects.enter("codeFencedFenceMeta"); effects.enter("chunkString", { contentType: "string" }); return meta(code); } function meta(code) { if (code === null || markdownLineEnding(code)) { effects.exit("chunkString"); effects.exit("codeFencedFenceMeta"); return infoBefore(code); } if (code === 96 && code === marker) { return nok(code); } effects.consume(code); return meta; } function atNonLazyBreak(code) { return effects.attempt(closeStart, after, contentBefore)(code); } function contentBefore(code) { effects.enter("lineEnding"); effects.consume(code); effects.exit("lineEnding"); return contentStart; } function contentStart(code) { return initialPrefix > 0 && markdownSpace(code) ? factorySpace( effects, beforeContentChunk, "linePrefix", initialPrefix + 1 )(code) : beforeContentChunk(code); } function beforeContentChunk(code) { if (code === null || markdownLineEnding(code)) { return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code); } effects.enter("codeFlowValue"); return contentChunk(code); } function contentChunk(code) { if (code === null || markdownLineEnding(code)) { effects.exit("codeFlowValue"); return beforeContentChunk(code); } effects.consume(code); return contentChunk; } function after(code) { effects.exit("codeFenced"); return ok(code); } function tokenizeCloseStart(effects2, ok2, nok2) { let size = 0; return startBefore; function startBefore(code) { effects2.enter("lineEnding"); effects2.consume(code); effects2.exit("lineEnding"); return start2; } function start2(code) { effects2.enter("codeFencedFence"); return markdownSpace(code) ? factorySpace( effects2, beforeSequenceClose, "linePrefix", self.parser.constructs.disable.null.includes("codeIndented") ? void 0 : 4 )(code) : beforeSequenceClose(code); } function beforeSequenceClose(code) { if (code === marker) { effects2.enter("codeFencedFenceSequence"); return sequenceClose(code); } return nok2(code); } function sequenceClose(code) { if (code === marker) { size++; effects2.consume(code); return sequenceClose; } if (size >= sizeOpen) { effects2.exit("codeFencedFenceSequence"); return markdownSpace(code) ? factorySpace(effects2, sequenceCloseAfter, "whitespace")(code) : sequenceCloseAfter(code); } return nok2(code); } function sequenceCloseAfter(code) { if (code === null || markdownLineEnding(code)) { effects2.exit("codeFencedFence"); return ok2(code); } return nok2(code); } } } function tokenizeNonLazyContinuation(effects, ok, nok) { const self = this; return start; function start(code) { if (code === null) { return nok(code); } effects.enter("lineEnding"); effects.consume(code); effects.exit("lineEnding"); return lineStart; } function lineStart(code) { return self.parser.lazy[self.now().line] ? nok(code) : ok(code); } } const codeIndented = { name: "codeIndented", tokenize: tokenizeCodeIndented }; const furtherStart = { tokenize: tokenizeFurtherStart, partial: true }; function tokenizeCodeIndented(effects, ok, nok) { const self = this; return start; function start(code) { effects.enter("codeIndented"); return factorySpace(effects, afterPrefix, "linePrefix", 4 + 1)(code); } function afterPrefix(code) { const tail = self.events[self.events.length - 1]; return tail && tail[1].type === "linePrefix" && tail[2].sliceSerialize(tail[1], true).length >= 4 ? atBreak(code) : nok(code); } function atBreak(code) { if (code === null) { return after(code); } if (markdownLineEnding(code)) { return effects.attempt(furtherStart, atBreak, after)(code); } effects.enter("codeFlowValue"); return inside(code); } function inside(code) { if (code === null || markdownLineEnding(code)) { effects.exit("codeFlowValue"); return atBreak(code); } effects.consume(code); return inside; } function after(code) { effects.exit("codeIndented"); return ok(code); } } function tokenizeFurtherStart(effects, ok, nok) { const self = this; return furtherStart2; function furtherStart2(code) { if (self.parser.lazy[self.now().line]) { return nok(code); } if (markdownLineEnding(code)) { effects.enter("lineEnding"); effects.consume(code); effects.exit("lineEnding"); return furtherStart2; } return factorySpace(effects, afterPrefix, "linePrefix", 4 + 1)(code); } function afterPrefix(code) { const tail = self.events[self.events.length - 1]; return tail && tail[1].type === "linePrefix" && tail[2].sliceSerialize(tail[1], true).length >= 4 ? ok(code) : markdownLineEnding(code) ? furtherStart2(code) : nok(code); } } const codeText = { name: "codeText", tokenize: tokenizeCodeText, resolve: resolveCodeText, previous }; function resolveCodeText(events) { let tailExitIndex = events.length - 4; let headEnterIndex = 3; let index2; let enter; if ((events[headEnterIndex][1].type === "lineEnding" || events[headEnterIndex][1].type === "space") && (events[tailExitIndex][1].type === "lineEnding" || events[tailExitIndex][1].type === "space")) { index2 = headEnterIndex; while (++index2 < tailExitIndex) { if (events[index2][1].type === "codeTextData") { events[headEnterIndex][1].type = "codeTextPadding"; events[tailExitIndex][1].type = "codeTextPadding"; headEnterIndex += 2; tailExitIndex -= 2; break; } } } index2 = headEnterIndex - 1; tailExitIndex++; while (++index2 <= tailExitIndex) { if (enter === void 0) { if (index2 !== tailExitIndex && events[index2][1].type !== "lineEnding") { enter = index2; } } else if (index2 === tailExitIndex || events[index2][1].type === "lineEnding") { events[enter][1].type = "codeTextData"; if (index2 !== enter + 2) { events[enter][1].end = events[index2 - 1][1].end; events.splice(enter + 2, index2 - enter - 2); tailExitIndex -= index2 - enter - 2; index2 = enter + 2; } enter = void 0; } } return events; } function previous(code) { return code !== 96 || this.events[this.events.length - 1][1].type === "characterEscape"; } function tokenizeCodeText(effects, ok, nok) { let sizeOpen = 0; let size; let token; return start; function start(code) { effects.enter("codeText"); effects.enter("codeTextSequence"); return sequenceOpen(code); } function sequenceOpen(code) { if (code === 96) { effects.consume(code); sizeOpen++; return sequenceOpen; } effects.exit("codeTextSequence"); return between(code); } function between(code) { if (code === null) { return nok(code); } if (code === 32) { effects.enter("space"); effects.consume(code); effects.exit("space"); return between; } if (code === 96) { token = effects.enter("codeTextSequence"); size = 0; return sequenceClose(code); } if (markdownLineEnding(code)) { effects.enter("lineEnding"); effects.consume(code); effects.exit("lineEnding"); return between; } effects.enter("codeTextData"); return data(code); } function data(code) { if (code === null || code === 32 || code === 96 || markdownLineEnding(code)) { effects.exit("codeTextData"); return between(code); } effects.consume(code); return data; } function sequenceClose(code) { if (code === 96) { effects.consume(code); size++; return sequenceClose; } if (size === sizeOpen) { effects.exit("codeTextSequence"); effects.exit("codeText"); return ok(code); } token.type = "codeTextData"; return data(code); } } function subtokenize(events) { const jumps = {}; let index2 = -1; let event; let lineIndex; let otherIndex; let otherEvent; let parameters; let subevents; let more; while (++index2 < events.length) { while (index2 in jumps) { index2 = jumps[index2]; } event = events[index2]; if (index2 && event[1].type === "chunkFlow" && events[index2 - 1][1].type === "listItemPrefix") { subevents = event[1]._tokenizer.events; otherIndex = 0; if (otherIndex < subevents.length && subevents[otherIndex][1].type === "lineEndingBlank") { otherIndex += 2; } if (otherIndex < subevents.length && subevents[otherIndex][1].type === "content") { while (++otherIndex < subevents.length) { if (subevents[otherIndex][1].type === "content") { break; } if (subevents[otherIndex][1].type === "chunkText") { subevents[otherIndex][1]._isInFirstContentOfListItem = true; otherIndex++; } } } } if (event[0] === "enter") { if (event[1].contentType) { Object.assign(jumps, subcontent(events, index2)); index2 = jumps[index2]; more = true; } } else if (event[1]._container) { otherIndex = index2; lineIndex = void 0; while (otherIndex--) { otherEvent = events[otherIndex]; if (otherEvent[1].type === "lineEnding" || otherEvent[1].type === "lineEndingBlank") { if (otherEvent[0] === "enter") { if (lineIndex) { events[lineIndex][1].type = "lineEndingBlank"; } otherEvent[1].type = "lineEnding"; lineIndex = otherIndex; } } else { break; } } if (lineIndex) { event[1].end = Object.assign({}, events[lineIndex][1].start); parameters = events.slice(lineIndex, index2); parameters.unshift(event); splice(events, lineIndex, index2 - lineIndex + 1, parameters); } } } return !more; } function subcontent(events, eventIndex) { const token = events[eventIndex][1]; const context = events[eventIndex][2]; let startPosition = eventIndex - 1; const startPositions = []; const tokenizer = token._tokenizer || context.parser[token.contentType](token.start); const childEvents = tokenizer.events; const jumps = []; const gaps = {}; let stream; let previous2; let index2 = -1; let current = token; let adjust = 0; let start = 0; const breaks = [start]; while (current) { while (events[++startPosition][1] !== current) { } startPositions.push(startPosition); if (!current._tokenizer) { stream = context.sliceStream(current); if (!current.next) { stream.push(null); } if (previous2) { tokenizer.defineSkip(current.start); } if (current._isInFirstContentOfListItem) { tokenizer._gfmTasklistFirstContentOfListItem = true; } tokenizer.write(stream); if (current._isInFirstContentOfListItem) { tokenizer._gfmTasklistFirstContentOfListItem = void 0; } } previous2 = current; current = current.next; } current = token; while (++index2 < childEvents.length) { if ( // Find a void token that includes a break. childEvents[index2][0] === "exit" && childEvents[index2 - 1][0] === "enter" && childEvents[index2][1].type === childEvents[index2 - 1][1].type && childEvents[index2][1].start.line !== childEvents[index2][1].end.line ) { start = index2 + 1; breaks.push(start); current._tokenizer = void 0; current.previous = void 0; current = current.next; } } tokenizer.events = []; if (current) { current._tokenizer = void 0; current.previous = void 0; } else { breaks.pop(); } index2 = breaks.length; while (index2--) { const slice = childEvents.slice(breaks[index2], breaks[index2 + 1]); const start2 = startPositions.pop(); jumps.unshift([start2, start2 + slice.length - 1]); splice(events, start2, 2, slice); } index2 = -1; while (++index2 < jumps.length) { gaps[adjust + jumps[index2][0]] = adjust + jumps[index2][1]; adjust += jumps[index2][1] - jumps[index2][0] - 1; } return gaps; } const content = { tokenize: tokenizeContent, resolve: resolveContent }; const continuationConstruct = { tokenize: tokenizeContinuation, partial: true }; function resolveContent(events) { subtokenize(events); return events; } function tokenizeContent(effects, ok) { let previous2; return chunkStart; function chunkStart(code) { effects.enter("content"); previous2 = effects.enter("chunkContent", { contentType: "content" }); return chunkInside(code); } function chunkInside(code) { if (code === null) { return contentEnd(code); } if (markdownLineEnding(code)) { return effects.check( continuationConstruct, contentContinue, contentEnd )(code); } effects.consume(code); return chunkInside; } function contentEnd(code) { effects.exit("chunkContent"); effects.exit("content"); return ok(code); } function contentContinue(code) { effects.consume(code); effects.exit("chunkContent"); previous2.next = effects.enter("chunkContent", { contentType: "content", previous: previous2 }); previous2 = previous2.next; return chunkInside; } } function tokenizeContinuation(effects, ok, nok) { const self = this; return startLookahead; function startLookahead(code) { effects.exit("chunkContent"); effects.enter("lineEnding"); effects.consume(code); effects.exit("lineEnding"); return factorySpace(effects, prefixed, "linePrefix"); } function prefixed(code) { if (code === null || markdownLineEnding(code)) { return nok(code); } const tail = self.events[self.events.length - 1]; if (!self.parser.constructs.disable.null.includes("codeIndented") && tail && tail[1].type === "linePrefix" && tail[2].sliceSerialize(tail[1], true).length >= 4) { return ok(code); } return effects.interrupt(self.parser.constructs.flow, nok, ok)(code); } } function factoryDestination(effects, ok, nok, type, literalType, literalMarkerType, rawType, stringType, max) { const limit = max || Number.POSITIVE_INFINITY; let balance = 0; return start; function start(code) { if (code === 60) { effects.enter(type); effects.enter(literalType); effects.enter(literalMarkerType); effects.consume(code); effects.exit(literalMarkerType); return enclosedBefore; } if (code === null || code === 32 || code === 41 || asciiControl(code)) { return nok(code); } effects.enter(type); effects.enter(rawType); effects.enter(stringType); effects.enter("chunkString", { contentType: "string" }); return raw(code); } function enclosedBefore(code) { if (code === 62) { effects.enter(literalMarkerType); effects.consume(code); effects.exit(literalMarkerType); effects.exit(literalType); effects.exit(type); return ok; } effects.enter(stringType); effects.enter("chunkString", { contentType: "string" }); return enclosed(code); } function enclosed(code) { if (code === 62) { effects.exit("chunkString"); effects.exit(stringType); return enclosedBefore(code); } if (code === null || code === 60 || markdownLineEnding(code)) { return nok(code); } effects.consume(code); return code === 92 ? enclosedEscape : enclosed; } function enclosedEscape(code) { if (code === 60 || code === 62 || code === 92) { effects.consume(code); return enclosed; } return enclosed(code); } function raw(code) { if (!balance && (code === null || code === 41 || markdownLineEndingOrSpace(code))) { effects.exit("chunkString"); effects.exit(stringType); effects.exit(rawType); effects.exit(type); return ok(code); } if (balance < limit && code === 40) { effects.consume(code); balance++; return raw; } if (code === 41) { effects.consume(code); balance--; return raw; } if (code === null || code === 32 || code === 40 || asciiControl(code)) { return nok(code); } effects.consume(code); return code === 92 ? rawEscape : raw; } function rawEscape(code) { if (code === 40 || code === 41 || code === 92) { effects.consume(code); return raw; } return raw(code); } } function factoryLabel(effects, ok, nok, type, markerType, stringType) { const self = this; let size = 0; let seen; return start; function start(code) { effects.enter(type); effects.enter(markerType); effects.consume(code); effects.exit(markerType); effects.enter(stringType); return atBreak; } function atBreak(code) { if (size > 999 || code === null || code === 91 || code === 93 && !seen || // To do: remove in the future once we’ve switched from // `micromark-extension-footnote` to `micromark-extension-gfm-footnote`, // which doesn’t need this. // Hidden footnotes hook. /* c8 ignore next 3 */ code === 94 && !size && "_hiddenFootnoteSupport" in self.parser.constructs) { return nok(code); } if (code === 93) { effects.exit(stringType); effects.enter(markerType); effects.consume(code); effects.exit(markerType); effects.exit(type); return ok; } if (markdownLineEnding(code)) { effects.enter("lineEnding"); effects.consume(code); effects.exit("lineEnding"); return atBreak; } effects.enter("chunkString", { contentType: "string" }); return labelInside(code); } function labelInside(code) { if (code === null || code === 91 || code === 93 || markdownLineEnding(code) || size++ > 999) { effects.exit("chunkString"); return atBreak(code); } effects.consume(code); if (!seen) seen = !markdownSpace(code); return code === 92 ? labelEscape : labelInside; } function labelEscape(code) { if (code === 91 || code === 92 || code === 93) { effects.consume(code); size++; return labelInside; } return labelInside(code); } } function factoryTitle(effects, ok, nok, type, markerType, stringType) { let marker; return start; function start(code) { if (code === 34 || code === 39 || code === 40) { effects.enter(type); effects.enter(markerType); effects.consume(code); effects.exit(markerType); marker = code === 40 ? 41 : code; return begin; } return nok(code); } function begin(code) { if (code === marker) { effects.enter(markerType); effects.consume(code); effects.exit(markerType); effects.exit(type); return ok; } effects.enter(stringType); return atBreak(code); } function atBreak(code) { if (code === marker) { effects.exit(stringType); return begin(marker); } if (code === null) { return nok(code); } if (markdownLineEnding(code)) { effects.enter("lineEnding"); effects.consume(code); effects.exit("lineEnding"); return factorySpace(effects, atBreak, "linePrefix"); } effects.enter("chunkString", { contentType: "string" }); return inside(code); } function inside(code) { if (code === marker || code === null || markdownLineEnding(code)) { effects.exit("chunkString"); return atBreak(code); } effects.consume(code); return code === 92 ? escape : inside; } function escape(code) { if (code === marker || code === 92) { effects.consume(code); return inside; } return inside(code); } } function factoryWhitespace(effects, ok) { let seen; return start; function start(code) { if (markdownLineEnding(code)) { effects.enter("lineEnding"); effects.consume(code); effects.exit("lineEnding"); seen = true; return start; } if (markdownSpace(code)) { return factorySpace( effects, start, seen ? "linePrefix" : "lineSuffix" )(code); } return ok(code); } } function normalizeIdentifier(value) { return value.replace(/[\t\n\r ]+/g, " ").replace(/^ | $/g, "").toLowerCase().toUpperCase(); } const definition = { name: "definition", tokenize: tokenizeDefinition }; const titleBefore = { tokenize: tokenizeTitleBefore, partial: true }; function tokenizeDefinition(effects, ok, nok) { const self = this; let identifier; return start; function start(code) { effects.enter("definition"); return before(code); } function before(code) { return factoryLabel.call( self, effects, labelAfter, // Note: we don’t need to reset the way `markdown-rs` does. nok, "definitionLabel", "definitionLabelMarker", "definitionLabelString" )(code); } function labelAfter(code) { identifier = normalizeIdentifier( self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) ); if (code === 58) { effects.enter("definitionMarker"); effects.consume(code); effects.exit("definitionMarker"); return markerAfter; } return nok(code); } function markerAfter(code) { return markdownLineEndingOrSpace(code) ? factoryWhitespace(effects, destinationBefore)(code) : destinationBefore(code); } function destinationBefore(code) { return factoryDestination( effects, destinationAfter, // Note: we don’t need to reset the way `markdown-rs` does. nok, "definitio