diff --git a/Makefile b/Makefile index f75a47a..0a17fba 100644 --- a/Makefile +++ b/Makefile @@ -26,9 +26,7 @@ lintfix: bundle: -rm -rf ./dist mkdir dist - microbundle --no-compress --target node --strict --name ${GLOBAL_NAME} -f modern - mv dist/${BUNDLE_NAME}.modern.js dist/${BUNDLE_NAME}.js - mv dist/${BUNDLE_NAME}.modern.js.map dist/${BUNDLE_NAME}.js.map + microbundle --no-compress --target node --strict --name ${GLOBAL_NAME} npx prepend-header 'dist/*js' support/header.js test: diff --git a/dist/markdownItFootnote.cjs b/dist/markdownItFootnote.cjs new file mode 100644 index 0000000..dc960ac --- /dev/null +++ b/dist/markdownItFootnote.cjs @@ -0,0 +1,1300 @@ +/*! markdown-it-footnote 3.0.3-10 https://github.com//GerHobbelt/markdown-it-footnote @license MIT */ + +'use strict'; + +var assert = require('assert'); + +// Process footnotes + +function anchorFnDefault(n, excludeSubId, baseInfo) { + const env = baseInfo.env; + assert.strict.ok(env != null); + let prefix = ''; + + if (typeof env.docId === 'string' && env.docId.length > 0) { + prefix = '-' + env.docId + '-'; + } + + return prefix + n; +} + +function captionFnDefault(n, baseInfo) { + //return '[' + n + ']'; + return '' + n; +} + +function headerFnDefault(category, baseInfo) { + switch (category) { + case 'aside': + return 'Side Notes'; + + case 'section': + return 'Section Notes'; + + case 'end': + return 'Endnotes'; + + default: + // used for error category, e.g. 'Error::Unused' + return category; + } +} + +function determine_footnote_symbol(idx, info, baseInfo) { + const plugin_options = baseInfo.plugin_options; + assert.strict.ok(plugin_options != null); // rule to construct the printed label: + // + // mark = labelOverride /* || info.label */ || idx; + + const label = info.labelOverride; + + if (label) { + return label; + } + + if (plugin_options.numberSequence == null || plugin_options.numberSequence.length === 0) { + return '' + idx; + } + + const len = plugin_options.numberSequence.length; + + if (idx >= len) { + // is last slot numeric or alphanumerically? + const slot = plugin_options.numberSequence[len - 1]; + + if (Number.isFinite(slot)) { + const delta = idx - len + 1; + return '' + (slot + delta); + } // non-numerical last slot --> duplicate, triplicate, etc. + + + const dupli = idx / len | 0; // = int(x mod N) + + const remainder = idx % len; + const core = plugin_options.numberSequence[remainder]; + let str = '' + core; + + for (let i = 1; i < dupli; i++) { + str += core; + } + + return str; + } + + return '' + plugin_options.numberSequence[idx]; +} + +const bunched_mode_classes = ['', 'footnote-bunched-ref-ref', 'footnote-bunched-ref-text']; + +function generateFootnoteRefHtml(id, caption, refId, bunched_footnote_ref_mode, renderInfo) { + let localOverride = renderInfo.tokens[renderInfo.idx].meta.text; + + if (localOverride) { + localOverride = `${localOverride}`; + } + + return `${localOverride || ''}${caption}` + (bunched_footnote_ref_mode !== 0 ? `${renderInfo.plugin_options.refCombiner || ''}` : ''); +} + +function generateFootnoteSectionStartHtml(renderInfo) { + const tok = renderInfo.tokens[renderInfo.idx]; + assert.strict.ok(tok != null); + assert.strict.ok(tok.meta != null); + const header = tok.markup ? `

${tok.markup}

` : ''; + let category = tok.meta.category; + assert.strict.ok(category.length > 0); // `category` can contain CSS class illegal characters, e.g. when category = 'Error::Unused': + + category = category.replace(/[^a-zA-Z0-9_-]+/g, '_'); + return `
\n'; +} + +function generateFootnoteStartHtml(id, caption, renderInfo) { + // allow both a JavaWScript --> CSS approach via `data-footnote-caption` + // and a classic CSS approach while a display:inline-block SUP presenting + // the LI 'button' instead: + return `
  • ${caption}`; +} + +function generateFootnoteEndHtml(renderInfo) { + return '
  • \n'; +} + +function generateFootnoteBackRefHtml(id, refId, renderInfo) { + const tok = renderInfo.tokens[renderInfo.idx]; + assert.strict.ok(tok != null); + assert.strict.ok(tok.meta != null); + /* ↩ with escape code to prevent display as Apple Emoji on iOS */ + + return ` \u21a9\uFE0E`; +} + +const default_plugin_options = { + // atDocumentEnd: false, -- obsoleted option of the original plugin + anchorFn: anchorFnDefault, + captionFn: captionFnDefault, + headerFn: headerFnDefault, + mkLabel: determine_footnote_symbol, + // see also https://www.editage.com/insights/footnotes-in-tables-part-1-choice-of-footnote-markers-and-their-sequence + // why asterisk/star is not part of the default footnote marker sequence. + // + // For similar reasons, we DO NOT include the section § symbol in this list. + // + // when numberSequnce is NULL/empty, a regular numerical numbering is assumed. + // Otherwise, the array is indexed; when there are more footnotes than entries in + // the numberSequence array, the entries are re-used, but doubled/trippled, etc. + // + // When the indexing in this array hits a NUMERIC value (as last entry), any higher + // footnotes are NUMBERED starting at that number. + // + // NOTE: as we can reference the same footnote from multiple spots, we do not depend + // on CSS counter() approaches by default, but providee this mechanism in the plugin + // code itself. + numberSequence: ['†', '‡', '††', '‡‡', '¶', 1], + // Overrides the footnode mode when set to one of the following: + // + // Recognized 'modes': + // '>': aside note (default for inline notes) + // ':': end node + // '=': section note (default for regular referenced notes) + // + // Also accepts these keywords: 'aside', 'section', 'end' + // + modeOverride: null, + // list section notes and endnotes in order of: + // + // 0: first *appearance* in the text + // 1: first *reference* in the text + // 2: *definition* in the text + // 3: sorted alphanumerically by *coded* label, + // i.e. *numeric* labels are sorted in numeric order (so `10` comes AFTER `7`!), + // while all others are sorted using `String.localeCompare()`. When labels have + // a *numeric leading*, e.g. `71geo` --> `71`, that part is sorted numerically first. + // + // Here 'coded label' means the label constructed from the reference ids and label overrides + // as used in the markdown source, using the expression + // labelOverride || reference || id + // which gives for these examples (assuming them to be the only definitions in your input): + // [^refA]: ... --> null || 'refA' || 1 + // [^refB LBL]: ... --> 'LBL' || 'refB' || 2 + // 4: sorted alphanumerically by *printed* label + // which is like mode 3, but now for the label as will be seen in the *output*! + sortOrder: 4, + // what to print between bunched-together footnote references, i.e. the '+' in `blabla¹⁺²` + refCombiner: ',' +}; +function footnote_plugin(md, plugin_options) { + const parseLinkLabel = md.helpers.parseLinkLabel, + isSpace = md.utils.isSpace; + plugin_options = Object.assign({}, default_plugin_options, plugin_options); + + function determine_mode(mode, default_mode) { + let override = null; + + if (plugin_options.modeOverride) { + + if ('>:='.includes(plugin_options.modeOverride)) { + override = plugin_options.modeOverride; + } + } + + if ('>:='.includes(mode)) { + return { + mode: override || mode, + fromInput: true + }; + } + + return { + mode: override || default_mode, + fromInput: false + }; + } + + function render_footnote_n(tokens, idx, excludeSubId) { + const mark = tokens[idx].meta.id; + assert.strict.ok(Number.isFinite(mark)); + assert.strict.ok(mark > 0); + let n = '' + mark; // = mark.toString(); + + assert.strict.ok(n.length > 0); + + if (!excludeSubId && tokens[idx].meta.subId > 0) { + n += '-' + tokens[idx].meta.subId; + } + + return n; + } + + function render_footnote_mark(renderInfo) { + const token = renderInfo.tokens[renderInfo.idx]; + assert.strict.ok(token != null); + assert.strict.ok(renderInfo.env.footnotes != null); + assert.strict.ok(renderInfo.env.footnotes.list != null); + const info = renderInfo.env.footnotes.list[token.meta.id]; + assert.strict.ok(info != null); + const mark = plugin_options.mkLabel(token.meta.id, info, renderInfo); + assert.strict.ok(mark.length > 0); + return mark; + } + + function render_footnote_anchor_name(renderInfo) { + const n = render_footnote_n(renderInfo.tokens, renderInfo.idx, true); + return plugin_options.anchorFn(n, true, renderInfo); + } + + function render_footnote_anchor_nameRef(renderInfo) { + const n = render_footnote_n(renderInfo.tokens, renderInfo.idx, false); + return plugin_options.anchorFn(n, false, renderInfo); + } + + function render_footnote_caption(renderInfo) { + const n = render_footnote_mark(renderInfo); + return plugin_options.captionFn(n, renderInfo); + } + + function render_footnote_ref(tokens, idx, options, env, self) { + const renderInfo = { + tokens, + idx, + options, + env, + plugin_options, + self + }; + const id = render_footnote_anchor_name(renderInfo); + const caption = render_footnote_caption(renderInfo); + const refId = render_footnote_anchor_nameRef(renderInfo); // check if multiple footnote references are bunched together: + // IFF they are, we should separate them with commas. + // + // Exception: when next token has an extra text (`meta.text`) the + // bunching together is not a problem as them the output will render + // like this: `bla1text2`, ergo a look + // like this: `bla¹text²` instead of bunched footnotes references ¹ and ² + // that would (without the extra comma injection) look like `bla¹²` instead + // of `x¹⁺²` (here '+' instead of ',' comma, but you get the idea -- there's no + // Unicode superscript-comma so that's why I used unicode superscript-plus + // in this 'ascii art' example). + // + + const next_token = tokens[idx + 1] || {}; + const next_token_meta = next_token.meta || {}; + const bunched_footnote_ref_mode = next_token.type === 'footnote_ref' ? !next_token_meta.text ? 1 : 2 : 0; + return generateFootnoteRefHtml(id, caption, refId, bunched_footnote_ref_mode, renderInfo); + } + + function render_footnote_block_open(tokens, idx, options, env, self) { + const renderInfo = { + tokens, + idx, + options, + env, + plugin_options, + self + }; + return generateFootnoteSectionStartHtml(renderInfo); + } + + function render_footnote_block_close(tokens, idx, options, env, self) { + return generateFootnoteSectionEndHtml(); + } + + function render_footnote_reference_open(tokens, idx, options, env, self) { + return ''; + } + + function render_footnote_reference_close() { + return ''; + } + + function render_footnote_mark_end_of_block() { + return ''; + } + + function render_footnote_open(tokens, idx, options, env, self) { + const renderInfo = { + tokens, + idx, + options, + env, + plugin_options, + self + }; + const id = render_footnote_anchor_name(renderInfo); + const caption = render_footnote_caption(renderInfo); // allow both a JavaScript --> CSS approach via `data-footnote-caption` + // and a classic CSS approach while a display:inline-block SUP presenting + // the LI 'button' instead: + + return generateFootnoteStartHtml(id, caption); + } + + function render_footnote_close(tokens, idx, options, env, self) { + return generateFootnoteEndHtml(); + } + + function render_footnote_anchor_backref(tokens, idx, options, env, self) { + const renderInfo = { + tokens, + idx, + options, + env, + plugin_options, + self + }; + const tok = tokens[idx]; + assert.strict.ok(tok != null); + assert.strict.ok(tok.meta != null); + const id = render_footnote_anchor_name(renderInfo); + let refId = render_footnote_n(tokens, idx, false); + refId = plugin_options.anchorFn(refId, false, renderInfo); + return generateFootnoteBackRefHtml(id, refId, renderInfo); + } + + md.renderer.rules.footnote_ref = render_footnote_ref; + md.renderer.rules.footnote_block_open = render_footnote_block_open; + md.renderer.rules.footnote_block_close = render_footnote_block_close; + md.renderer.rules.footnote_reference_open = render_footnote_reference_open; + md.renderer.rules.footnote_reference_close = render_footnote_reference_close; + md.renderer.rules.footnote_mark_end_of_block = render_footnote_mark_end_of_block; + md.renderer.rules.footnote_open = render_footnote_open; + md.renderer.rules.footnote_close = render_footnote_close; + md.renderer.rules.footnote_anchor = render_footnote_anchor_backref; + + function obtain_footnote_info_slot(env, label, at_definition) { + // inline blocks have their own *child* environment in markdown-it v10+. + // As the footnotes must live beyond the lifetime of the inline block env, + // we must patch them into the `parentState.env` for the footnote_tail + // handler to be able to access them afterwards! + while (env.parentState) { + env = env.parentState.env; + assert.strict.ok(env != null); + } + + if (!env.footnotes) { + env.footnotes = { + // map label tto ID: + refs: {}, + // store footnote info indexed by ID + list: [], + // remap ID to re-ordered ID (determines placement order for section notes and endnotes) + idMap: [0], + idMapCounter: 0, + // and a counter for the generated sections (including asides); see the demo/test which + // uses the generated `#fnsection-DDD` identifiers to hack/fix the styling, for example. + sectionCounter: 0 + }; + } // When label is NULL, this is a request from in INLINE NOTE. + // NOTE: IDs are index numbers, BUT they start at 1 instead of 0 to make life easier in check code: + + + let footnoteId; + let infoRec; // label as index: prepend ':' to avoid conflict with Object.prototype members + + if (label == null || !env.footnotes.refs[':' + label]) { + footnoteId = Math.max(1, env.footnotes.list.length); + infoRec = { + id: footnoteId, + label, + labelOverride: null, + mode: null, + content: null, + tokens: null, + count: 0 + }; + env.footnotes.list[footnoteId] = infoRec; + + if (label != null) { + env.footnotes.refs[':' + label] = footnoteId; + } + } else { + footnoteId = env.footnotes.refs[':' + label]; + infoRec = env.footnotes.list[footnoteId]; + assert.strict.ok(!!infoRec, 'expects non-NULL footnote info record'); + } + + const idMap = env.footnotes.idMap; // now check if the idMap[] has been set up already as well. This depends on + // when WE are invoked (`at_definition`) and the configured `options.sortOrder`: + + switch (plugin_options.sortOrder) { + // 0: first *appearance* in the text + default: + case 0: + // basically, this means: order as-is + if (!idMap[footnoteId]) { + idMap[footnoteId] = ++env.footnotes.idMapCounter; + } + + break; + // 1: first *reference* in the text + + case 1: + if (!at_definition && !idMap[footnoteId]) { + // first reference is now! + idMap[footnoteId] = ++env.footnotes.idMapCounter; + } + + break; + // 2: *definition* in the text + + case 2: + if (at_definition && !idMap[footnoteId]) { + // definition is now! + idMap[footnoteId] = ++env.footnotes.idMapCounter; + } + + break; + // 3: sorted alphanumerically by label (inline footnotes will end up at the top, before all other notes) + + case 3: + case 4: + // just note the footnoteId now; this must be re-ordered later when we have collected all footnotes. + // + // set it up when we get there... + break; + } + + return infoRec; + } + + function find_end_of_block_marker(state, startIndex) { + let idx, len; + const tokens = state.tokens; + + for (idx = startIndex, len = tokens.length; idx < len; idx++) { + if (tokens[idx].type === 'footnote_mark_end_of_block') { + return idx; + } + } // Punch a slot into the token stream (at the very end) + // for consistency with footnote_mark_end_of_block(): + + + const token = new state.Token('footnote_mark_end_of_block', '', 0); + token.hidden = true; + tokens.push(token); + return tokens.length - 1; + } + + function update_end_of_block_marker(state, footnoteId) { + // inject marker into parent = block level token stream to announce the advent of an (inline) footnote: + // because the markdown_it code uses a for() loop to go through the parent nodes while parsing the + // 'inline' chunks, we CANNOT safely inject a marker BEFORE the chunk, only AFTERWARDS: + const parentState = state.env.parentState; + const parentIndex = state.env.parentTokenIndex; + const markerTokenIndex = find_end_of_block_marker(parentState, parentIndex + 1); + const token = parentState.tokens[markerTokenIndex]; + + if (!token.meta) { + token.meta = { + footnote_list: [] + }; + } + + token.meta.footnote_list.push(footnoteId); + } // Mark end of paragraph/heading/whatever BLOCK (or rather: START of the next block!) + + + function footnote_mark_end_of_block(state, startLine, endLine, silent) { + if (!silent && state.tokens.length > 0) { + const token = state.push('footnote_mark_end_of_block', '', 0); + token.hidden = true; + } + + return false; + } // Process footnote block definition + + + function footnote_def(state, startLine, endLine, silent) { + let oldBMark, + oldTShift, + oldSCount, + oldParentType, + pos, + token, + initial, + offset, + ch, + posAfterColon, + start = state.bMarks[startLine] + state.tShift[startLine], + max = state.eMarks[startLine]; // line should be at least 6 chars - "[^x]: " or "[^x]:> " + + if (start + 5 > max) { + return false; + } + + if (state.src.charCodeAt(start) !== 0x5B + /* [ */ + ) { + return false; + } + + if (state.src.charCodeAt(start + 1) !== 0x5E + /* ^ */ + ) { + return false; + } + + for (pos = start + 2; pos < max; pos++) { + if (state.src.charCodeAt(pos) === 0x0A + /* LF */ + ) { + return false; + } + + if (state.src.charCodeAt(pos) === 0x5D + /* ] */ + ) { + break; + } + } + + const labelEnd = pos; + + if (pos === start + 2) { + return false; + } // no empty footnote labels + + + if (pos + 1 >= max || state.src.charCodeAt(++pos) !== 0x3A + /* : */ + ) { + return false; + } + + const mode_rec = determine_mode(state.src[pos + 1], '='); // default mode is section_note mode. + + if (mode_rec.fromInput) { + pos++; + } + + const mode = mode_rec.mode; + + if (pos + 1 >= max || state.src.charCodeAt(++pos) !== 0x20 + /* space */ + ) { + return false; + } + + if (silent) { + return true; + } + + pos++; + const labelInfo = decode_label(state.src.slice(start + 2, labelEnd), true); + + if (!labelInfo) { + return false; + } + + assert.strict.ok(!labelInfo.extraText); // Now see if we already have a footnote ID for this footnote label: + // fetch it if we have one and otherwise produce a new one so everyone + // can use this from now on. + // + // This scenario is possible when the footnote *definition* comes BEFORE + // the first actual footnote *use* (*reference*). This is UNUSUAL when people + // write texts, but it is *not impossible*, particularly now that we have + // specified-by-design that endnotes can be marked as such (`[^label]:: note text`) + // and freely mixed with sidenotes (`[^label]:> note text`) and section + // notes (`[^label]:= note text` (explicit mode) or `[^label]: note text` + // (implicit mode)), where *section notes* will placed at the spot in the text + // flow where they were *defined*. Again, highly irregular, BUT someone MAY + // feel the need to place some section note *definitions* ABOVE their first + // use point. + // + + const infoRec = obtain_footnote_info_slot(state.env, labelInfo.label, true); + + if (labelInfo.labelOverride) { + infoRec.labelOverride = labelInfo.labelOverride; + } + + infoRec.mode = mode; + infoRec.content = state.src.slice(pos, max); + token = state.push('footnote_reference_open', '', 1); + token.meta = { + id: infoRec.id + }; + token.hidden = true; + oldBMark = state.bMarks[startLine]; + oldTShift = state.tShift[startLine]; + oldSCount = state.sCount[startLine]; + oldParentType = state.parentType; + posAfterColon = pos; + initial = offset = state.sCount[startLine] + pos - (state.bMarks[startLine] + state.tShift[startLine]); + + while (pos < max) { + ch = state.src.charCodeAt(pos); + + if (isSpace(ch)) { + if (ch === 0x09) { + offset += 4 - offset % 4; + } else { + offset++; + } + } else { + break; + } + + pos++; + } + + state.tShift[startLine] = pos - posAfterColon; + state.sCount[startLine] = offset - initial; + state.bMarks[startLine] = posAfterColon; + state.blkIndent += 4; + state.parentType = 'footnote'; + + if (state.sCount[startLine] < state.blkIndent) { + state.sCount[startLine] += state.blkIndent; + } + + state.md.block.tokenize(state, startLine, endLine, true); + state.parentType = oldParentType; + state.blkIndent -= 4; + state.tShift[startLine] = oldTShift; + state.sCount[startLine] = oldSCount; + state.bMarks[startLine] = oldBMark; + token = state.push('footnote_reference_close', '', -1); + token.meta = { + id: infoRec.id + }; + return true; + } // Process inline footnotes (^[...] or ^[>...]) + + + function footnote_inline(state, silent) { + let labelStart, + labelEnd, + token, + tokens, + max = state.posMax, + start = state.pos; + + if (start + 2 >= max) { + return false; + } + + if (state.src.charCodeAt(start) !== 0x5E + /* ^ */ + ) { + return false; + } + + if (state.src.charCodeAt(start + 1) !== 0x5B + /* [ */ + ) { + return false; + } + + labelStart = start + 2; // NOTE: inline notes are automatically considered to be ASIDE notes, + // UNLESS otherwise specified! + // + // Recognized 'modes': + // '>': aside note (default for inline notes) + // ':': end node + // '=': section note (default for regular referenced notes) + // + // (Also note https://v4.chriskrycho.com/2015/academic-markdown-and-citations.html: + // our notes look like this: `[^ref]:` while Academic MarkDown references look + // like this: `[@Belawog2012]` i.e. no '^' in there. Hence these can safely co-exist.) + // + + const mode_rec = determine_mode(state.src[start + 2], '>'); // default mode is aside ~ sidenote mode. + + if (mode_rec.fromInput) { + labelStart++; + } + + const mode = mode_rec.mode; + labelEnd = parseLinkLabel(state, start + 1); // parser failed to find ']', so it's not a valid note + + if (labelEnd < 0) { + return false; + } // We found the end of the link, and know for a fact it's a valid link; + // so all that's left to do is to call tokenizer. + // + + + if (!silent) { + // WARNING: claim our footnote slot for there MAY be nested footnotes + // discovered in the next inline.parse() call below! + const infoRec = obtain_footnote_info_slot(state.env, null, true); + infoRec.mode = mode; + infoRec.count++; + token = state.push('footnote_ref', '', 0); + token.meta = { + id: infoRec.id + }; + state.md.inline.parse(state.src.slice(labelStart, labelEnd), state.md, state.env, tokens = []); // Now fill our previously claimed slot: + + infoRec.content = state.src.slice(labelStart, labelEnd); + infoRec.tokens = tokens; // inject marker into parent = block level token stream to announce the advent of an (inline) footnote: + // because the markdown_it code uses a for() loop to go through the parent nodes while parsing the + // 'inline' chunks, we CANNOT safely inject a marker BEFORE the chunk, only AFTERWARDS: + + update_end_of_block_marker(state, infoRec.id); //md.block.ruler.enable('footnote_mark_end_of_block'); + } + + state.pos = labelEnd + 1; + state.posMax = max; + return true; + } // Check if this is a valid ffootnote reference label. + // + // Also see if there's a label OVERRIDE text or marker ('@') provided. + // + // Return the parsed label record. + + + function decode_label(label, extra_text_is_labelOverride) { + var _m$; + + if (!label) { + return null; + } + + const m = label.match(/^(@?)(\S+)(?:\s+(.+))?$/); // label with OPTIONAL override text... + + if (!m) { + return null; + } + + assert.strict.ok(m[2].length > 0); + let extraText = (_m$ = m[3]) == null ? void 0 : _m$.trim(); // label [output] override? + + let override = null; + + if (m[1]) { + override = m[2]; + } + + if (extra_text_is_labelOverride && extraText) { + override = extraText; + extraText = null; + } + + return { + label: m[2], + labelOverride: override, + extraText + }; + } // Process footnote references with text ([^label ...]) + + + function footnote_ref_with_text(state, silent) { + let pos, + footnoteSubId, + token, + max = state.posMax, + start = state.pos; // should be at least 6 chars - "[^l x]" + + if (start + 5 > max) { + return false; + } + + if (state.src.charCodeAt(start) !== 0x5B + /* [ */ + ) { + return false; + } + + if (state.src.charCodeAt(start + 1) !== 0x5E + /* ^ */ + ) { + return false; + } + + for (pos = start + 2; pos < max; pos++) { + if (state.src.charCodeAt(pos) === 0x0A + /* linefeed */ + ) { + return false; + } + + if (state.src.charCodeAt(pos) === 0x5D + /* ] */ + ) { + break; + } + } + + if (pos === start + 2) { + return false; + } // no empty footnote labels + + + if (pos >= max) { + return false; + } + + pos++; + const labelInfo = decode_label(state.src.slice(start + 2, pos - 1), false); + + if (!labelInfo || !labelInfo.extraText) { + return false; + } + + assert.strict.ok(labelInfo.extraText.length > 0); + const infoRec = obtain_footnote_info_slot(state.env, labelInfo.label, false); + + if (labelInfo.labelOverride) { + infoRec.labelOverride = labelInfo.labelOverride; + } + + if (!silent) { + footnoteSubId = infoRec.count; + infoRec.count++; + token = state.push('footnote_ref', '', 0); + token.meta = { + id: infoRec.id, + subId: footnoteSubId, + text: labelInfo.extraText + }; + update_end_of_block_marker(state, infoRec.id); //md.block.ruler.enable('footnote_mark_end_of_block'); + } + + state.pos = pos; + state.posMax = max; + return true; + } // Process footnote references ([^...]) + + + function footnote_ref(state, silent) { + let pos, + footnoteSubId, + token, + max = state.posMax, + start = state.pos; // should be at least 4 chars - "[^x]" + + if (start + 3 > max) { + return false; + } + + if (state.src.charCodeAt(start) !== 0x5B + /* [ */ + ) { + return false; + } + + if (state.src.charCodeAt(start + 1) !== 0x5E + /* ^ */ + ) { + return false; + } + + for (pos = start + 2; pos < max; pos++) { + //if (state.src.charCodeAt(pos) === 0x20) { return false; } + if (state.src.charCodeAt(pos) === 0x0A) { + return false; + } + + if (state.src.charCodeAt(pos) === 0x5D + /* ] */ + ) { + break; + } + } + + if (pos === start + 2) { + return false; + } // no empty footnote labels + + + if (pos >= max) { + return false; + } + + pos++; + const labelInfo = decode_label(state.src.slice(start + 2, pos - 1), true); + + if (!labelInfo) { + return false; + } + + assert.strict.ok(!labelInfo.extraText); + const infoRec = obtain_footnote_info_slot(state.env, labelInfo.label, false); + + if (labelInfo.labelOverride) { + infoRec.labelOverride = labelInfo.labelOverride; + } + + if (!silent) { + footnoteSubId = infoRec.count; + infoRec.count++; + token = state.push('footnote_ref', '', 0); + token.meta = { + id: infoRec.id, + subId: footnoteSubId + }; + update_end_of_block_marker(state, infoRec.id); //md.block.ruler.enable('footnote_mark_end_of_block'); + } + + state.pos = pos; + state.posMax = max; + return true; + } + + function place_footnote_definitions_at(state, token_idx, footnote_id_list, category, baseInfo) { + if (footnote_id_list.length === 0) { + return; // nothing to inject... + } + + let inject_tokens = []; + assert.strict.ok(baseInfo.env.footnotes.list != null); + const footnote_spec_list = baseInfo.env.footnotes.list; + let token = new state.Token('footnote_block_open', '', 1); + token.markup = plugin_options.headerFn(category, baseInfo.env, plugin_options); + token.meta = { + sectionId: ++baseInfo.env.footnotes.sectionCounter, + category + }; + inject_tokens.push(token); + + for (const id of footnote_id_list) { + const fn = footnote_spec_list[id]; + token = new state.Token('footnote_open', '', 1); + token.meta = { + id, + category + }; + inject_tokens.push(token); + + if (fn.label == null) { + // process an inline footnote text: + token = new state.Token('paragraph_open', 'p', 1); + token.block = true; + inject_tokens.push(token); + token = new state.Token('inline', '', 0); + token.children = fn.tokens; + token.content = fn.content; + inject_tokens.push(token); + token = new state.Token('paragraph_close', 'p', -1); + token.block = true; + inject_tokens.push(token); + } else { + // process a labeled footnote: + inject_tokens = inject_tokens.concat(fn.tokens || []); + } //let lastParagraph; + //if (inject_tokens[inject_tokens.length - 1].type === 'paragraph_close') { + // lastParagraph = inject_tokens.pop(); + //} else { + // lastParagraph = null; + //} + + + const cnt = fn.count; + assert.strict.ok(cnt >= 0); + + for (let j = 0; j < cnt; j++) { + token = new state.Token('footnote_anchor', '', 0); + token.meta = { + id, + subId: j, + backrefCount: cnt, + category + }; + inject_tokens.push(token); + } //if (lastParagraph) { + // inject_tokens.push(lastParagraph); + //} + + + token = new state.Token('footnote_close', '', -1); + token.meta = { + id, + category + }; + inject_tokens.push(token); + } + + token = new state.Token('footnote_block_close', '', -1); + token.meta = { + category + }; + inject_tokens.push(token); + state.tokens.splice(token_idx, 0, ...inject_tokens); + } + + function more_footnote_reference_blocks_follow_immediately(tokens, idx) { + let tok = tokens[idx]; + + while (tok && (tok.type === 'footnote_mark_end_of_block' || tok.type === 'footnote_reference_close')) { + idx++; + tok = tokens[idx]; + } + + return tok && tok.type === 'footnote_reference_open'; + } // Glue footnote tokens into appropriate slots of token stream. + + + function footnote_tail(state, startLine, endLine, silent) { + let i, + current, + insideRef = false; + + if (!state.env.footnotes) { + // no footnotes at all? --> filter out all 'footnote_mark_end_of_block' chunks: + state.tokens = state.tokens.filter(function (tok, idx) { + return tok.type !== 'footnote_mark_end_of_block'; + }); + return; + } + + const idMap = state.env.footnotes.idMap; + const baseInfo = { + options: state.md.options, + env: state.env, + plugin_options, + self: this + }; + + function footnote_print_comparer(idA, idB) { + return idMap[idA] - idMap[idB]; + } // Rewrite the tokenstream to place the aside-footnotes and section footnotes where they need to be: + + + const footnote_spec_list = state.env.footnotes.list; // extract the tokens constituting the footnote/sidenote *content* and + // store that bunch in `refTokens[:]` instead, to be injected back into + // the tokenstream at the appropriate spots. + + state.tokens = state.tokens.filter(function (tok, idx) { + switch (tok.type) { + // filter out 'footnote_mark_end_of_block' tokens which follow BLOCKS that do not contain any + // footnote/sidenote/endnote references: + case 'footnote_mark_end_of_block': + if (!tok.meta) return false; + if (!tok.meta.footnote_list) return false; + break; + + case 'footnote_reference_open': + insideRef = true; + current = []; + return true; + + case 'footnote_reference_close': + insideRef = false; + const infoRec = footnote_spec_list[tok.meta.id]; + infoRec.tokens = current; + return true; + } + + if (insideRef) { + current.push(tok); + } + + return !insideRef; + }); // execute configured sorting/mapping (`idMap`): + + switch (plugin_options.sortOrder) { + // 0: first *appearance* in the text + default: + case 0: // 1: first *reference* in the text + + case 1: // 2: *definition* in the text + + case 2: + // order is specified in the `idMap` already. + break; + // 3: sorted alphanumerically by label (inline footnotes will end up at the top, before all other notes) + + case 3: + case 4: + // the `idMap[]` array has not been set up and must be produced + // to turn this into an alphanumerically-by-label sort order, where + // a `footnoteId` based index will produce the order of appearance. + const reIdMap = []; + + for (let i = 1; i < footnote_spec_list.length; i++) { + reIdMap[i - 1] = i; + } + + reIdMap.sort((idA, idB) => { + const infoA = footnote_spec_list[idA]; + const infoB = footnote_spec_list[idB]; + assert.strict.ok(infoA); + assert.strict.ok(infoB); // is any of these an inline footnote, i.e. without any label yet? Produce a fake label for sorting then! + // + // As stated elsewhere: inline section_notes and end_notes will end up among everyone else in this sort order mode. + + assert.strict.ok(infoA.id === idA); + assert.strict.ok(infoB.id === idB); // Split a "sort label" up into its numerical part and the tail. Note that we don't call + // it 'tail' but 'label', because we will need to compare the ENTIRE LABEL using string comparison + // when the numeric leaders are identical, so as to ensure that 'labels' such as `00000` will sort + // as 'higher' than `000`, both of which will be rated as numerically identical! + + function to_atoms(label) { + // now extract number or numerical leader part. + // + // Only accept OBVIOUS, SIMPLE NUMERIC LEADERS! This is about *legibility* + // of those numrical leaders, not a pedantic "what is possibly legally numeric" + // challenge. Hence we DO NOT accept leading +/- and only a decimal dot when + // there's a decimal number BEFORE it, such as in `5.1hack` --> `5.1`, but NOT + // `.42oz`! + // + // Do not use `nmr = +lbl` as that would treat labels such as `0xf4` as hexadecimal numbers, + // which we DO NOT want to happen. + const m = label.match(/^\d+(?:\.\d+)?/) || ['x']; + const nmr = +m[0] || Infinity; // non-numeric labels are rated NUMEICALLY HIGHER than any numerical leader. + + return { + label, + number: nmr + }; + } + + const labelA = plugin_options.sortOrder === 3 ? infoA.labelOverride || infoA.label || '' + infoA.id : plugin_options.mkLabel(infoA.id, infoA, baseInfo); + const labelB = plugin_options.sortOrder === 3 ? infoB.labelOverride || infoB.label || '' + infoB.id : plugin_options.mkLabel(infoB.id, infoB, baseInfo); + const atomA = to_atoms(labelA); + const atomB = to_atoms(labelB); + const diff = atomA.number - atomB.number; + return diff || atomA.label.localeCompare(atomB.label); // ^^^^^^^ shorthand for: + // + // if (isNaN(diff) || diff === 0) then stringcompare else numeric-difference + }); // Now turn this into a sort order map: + + for (let prio = 0; prio < reIdMap.length; prio++) { + const id = reIdMap[prio]; + idMap[id] = prio; + } + + break; + } + + let aside_list; + let section_list = new Set(); + const section_done_list = new Set(); // once a section_note has been printed, it should never appear again! + + const end_list = new Set(); + const used_list = new Set(); + let tokens = state.tokens; + + for (i = 0; i < tokens.length; i++) { + const tok = tokens[i]; + + switch (tok.type) { + case 'footnote_mark_end_of_block': + // check the gathered list of footnotes referenced in this block: + // - dump the ones which are sidenotes + // - mark the ones which are section- or end-notes. + // + // Note: make sure we don't produce duplicates in the collect sets. + { + var _tok$meta; + + aside_list = new Set(); + const refd_notes_list = ((_tok$meta = tok.meta) == null ? void 0 : _tok$meta.footnote_list) || []; + + for (const id of refd_notes_list) { + const footnote = footnote_spec_list[id]; + + switch (footnote.mode) { + case '>': + aside_list.add(id); + used_list.add(id); + break; + + case '=': + if (!section_done_list.has(id)) { + section_list.add(id); + section_done_list.add(id); + used_list.add(id); + } + + break; + + default: + case ':': + end_list.add(id); + used_list.add(id); + break; + } + } + + const aside_ids = []; + + for (const id of aside_list.values()) { + aside_ids.push(id); + } + + aside_ids.sort(footnote_print_comparer); + place_footnote_definitions_at(state, i + 1, aside_ids, 'aside', baseInfo); + tokens = state.tokens; + } + break; + + case 'footnote_reference_close': + // anywhere a footnote *definition* appeared in the original text is + // also a place to dump the section_notes gathered to date, so to speak. + // + // However, DO detect clusters of footnote definitions and MERGE them + // together: + if (more_footnote_reference_blocks_follow_immediately(tokens, i + 1)) { + continue; + } else { + const section_ids = []; + + for (const id of section_list.values()) { + section_ids.push(id); + } + + section_ids.sort(footnote_print_comparer); + place_footnote_definitions_at(state, i + 1, section_ids, 'section', baseInfo); + tokens = state.tokens; // and reset the tracking set: + + section_list = new Set(); + } + + break; + } + } // Now process the endnotes: + + + { + const end_ids = []; + + for (const id of end_list.values()) { + end_ids.push(id); + } + + end_ids.sort(footnote_print_comparer); + place_footnote_definitions_at(state, tokens.length, end_ids, 'end', baseInfo); + tokens = state.tokens; + } // Now process the unused footnotes and dump them for diagnostic purposes: + + { + const unused_ids = []; + + for (let i = 1; i < footnote_spec_list.length; i++) { + const fn = footnote_spec_list[i]; + const id = fn.id; + + if (!used_list.has(id)) { + console.error(`ERROR: footnote ID ${id} is defined but never used. Footnote will be added as an ERRONEOUS ENDNOTE to the output, so the situation is easy to diagnose!`, Object.assign({}, fn, { + tokens: '......' + })); + unused_ids.push(id); + } + } + + unused_ids.sort(footnote_print_comparer); + place_footnote_definitions_at(state, tokens.length, unused_ids, 'Error::Unused', baseInfo); //tokens = state.tokens; + } // Update state_block too as we have rewritten & REPLACED the token array earlier in this call: + // the reference `state.env.state_block.tokens` is still pointing to the OLD token array! + + state.env.state_block.tokens = state.tokens; + } // attach ourselves to the start of block handling too + + + md.block.ruler.before('table', 'footnote_mark_end_of_block', footnote_mark_end_of_block); + md.block.ruler.before('reference', 'footnote_def', footnote_def, { + alt: ['paragraph', 'reference'] + }); + md.inline.ruler.after('image', 'footnote_inline', footnote_inline); + md.inline.ruler.after('footnote_inline', 'footnote_ref_with_text', footnote_ref_with_text); + md.inline.ruler.after('footnote_ref_with_text', 'footnote_ref', footnote_ref); + md.core.ruler.after('inline', 'footnote_tail', footnote_tail); +} + +module.exports = footnote_plugin; +//# sourceMappingURL=markdownItFootnote.cjs.map diff --git a/dist/markdownItFootnote.cjs.map b/dist/markdownItFootnote.cjs.map new file mode 100644 index 0000000..f866f48 --- /dev/null +++ b/dist/markdownItFootnote.cjs.map @@ -0,0 +1 @@ +{"version":3,"file":"markdownItFootnote.cjs","sources":["../index.ts"],"sourcesContent":["// Process footnotes\n//\n\nimport { strict as assert } from 'assert';\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Renderer partials\n\n\n\ninterface FootnotePluginOptions {\n numberSequence?: Array;\n modeOverride?: string;\n sortOrder: number;\n refCombiner?: string;\n}\n\ninterface GenericInfoParameters {\n options: any; // markdown_it options object\n plugin_options: FootnotePluginOptions;\n env: any; // markdown_it environment object\n self: any; // reference to this plugin instance\n}\n\ninterface RenderInfoParameters extends GenericInfoParameters {\n tokens: Array; // array of tokens\n idx: number; // index of current token in token array\n}\n\ninterface footnoteMetaInfo {\n id: number;\n label?: string;\n labelOverride?: string;\n mode?: string;\n content?: string;\n tokens?: Array;\n count: number;\n}\n\n\n\nfunction anchorFnDefault(n: number, excludeSubId: number, baseInfo: RenderInfoParameters) {\n const env = baseInfo.env;\n assert.ok(env != null);\n let prefix = '';\n if (typeof env.docId === 'string' && env.docId.length > 0) {\n prefix = '-' + env.docId + '-';\n }\n return prefix + n;\n}\n\nfunction captionFnDefault(n, baseInfo: RenderInfoParameters) {\n //return '[' + n + ']';\n return '' + n;\n}\n\nfunction headerFnDefault(category, baseInfo: GenericInfoParameters) {\n switch (category) {\n case 'aside':\n return 'Side Notes';\n\n case 'section':\n return 'Section Notes';\n\n case 'end':\n return 'Endnotes';\n\n default: // used for error category, e.g. 'Error::Unused'\n return category;\n }\n}\n\nfunction determine_footnote_symbol(idx: number, info: footnoteMetaInfo, baseInfo: GenericInfoParameters): string {\n const plugin_options = baseInfo.plugin_options;\n assert.ok(plugin_options != null);\n\n // rule to construct the printed label:\n //\n // mark = labelOverride /* || info.label */ || idx;\n const label = info.labelOverride;\n if (label) {\n return label;\n }\n if (plugin_options.numberSequence == null || plugin_options.numberSequence.length === 0) {\n return '' + idx;\n }\n const len = plugin_options.numberSequence.length;\n if (idx >= len) {\n // is last slot numeric or alphanumerically?\n const slot = plugin_options.numberSequence[len - 1];\n if (Number.isFinite(slot)) {\n const delta = idx - len + 1;\n return '' + (slot + delta);\n }\n\n // non-numerical last slot --> duplicate, triplicate, etc.\n const dupli = (idx / len) | 0; // = int(x mod N)\n const remainder = idx % len;\n const core = plugin_options.numberSequence[remainder];\n let str = '' + core;\n for (let i = 1; i < dupli; i++) {\n str += core;\n }\n return str;\n }\n\n return '' + plugin_options.numberSequence[idx];\n}\n\n\nconst bunched_mode_classes = [ '', 'footnote-bunched-ref-ref', 'footnote-bunched-ref-text' ];\n\n\nfunction generateFootnoteRefHtml(id, caption, refId, bunched_footnote_ref_mode, renderInfo: RenderInfoParameters) {\n let localOverride = renderInfo.tokens[renderInfo.idx].meta.text;\n if (localOverride) {\n localOverride = `${ localOverride }`;\n }\n return `${ localOverride || '' }${ caption }` +\n (bunched_footnote_ref_mode !== 0 ? `${ renderInfo.plugin_options.refCombiner || '' }` : '');\n}\n\nfunction generateFootnoteSectionStartHtml(renderInfo: RenderInfoParameters) {\n const tok = renderInfo.tokens[renderInfo.idx];\n assert.ok(tok != null);\n assert.ok(tok.meta != null);\n const header = (tok.markup ? `

    ${ tok.markup }

    ` : '');\n let category = tok.meta.category;\n assert.ok(category.length > 0);\n // `category` can contain CSS class illegal characters, e.g. when category = 'Error::Unused':\n category = category.replace(/[^a-zA-Z0-9_-]+/g, '_');\n return `
    \\n';\n}\n\nfunction generateFootnoteStartHtml(id, caption, renderInfo: RenderInfoParameters) {\n // allow both a JavaWScript --> CSS approach via `data-footnote-caption`\n // and a classic CSS approach while a display:inline-block SUP presenting\n // the LI 'button' instead:\n return `
  • ${ caption }`;\n}\n\nfunction generateFootnoteEndHtml(renderInfo: RenderInfoParameters) {\n return '
  • \\n';\n}\n\nfunction generateFootnoteBackRefHtml(id, refId, renderInfo: RenderInfoParameters) {\n const tok = renderInfo.tokens[renderInfo.idx];\n assert.ok(tok != null);\n assert.ok(tok.meta != null);\n\n /* ↩ with escape code to prevent display as Apple Emoji on iOS */\n return ` \\u21a9\\uFE0E`;\n}\n\n\n\n\n/*\nref:\n return ``;\n\n\nopen:\n return `\\n';\n}\n\n*/\n\n\n\n\ninterface FootnotePluginOptions /* extends FootnotePluginOptions */ { // eslint-disable-line no-redeclare\n anchorFn: (n: number, excludeSubId: number, baseInfo: RenderInfoParameters) => string;\n captionFn: (n: number, baseInfo: RenderInfoParameters) => string;\n headerFn: (category: string, baseInfo: GenericInfoParameters) => string;\n mkLabel: (idx: number, info: footnoteMetaInfo, baseInfo: GenericInfoParameters) => string;\n}\n\n\n\n\nconst default_plugin_options: FootnotePluginOptions = {\n // atDocumentEnd: false, -- obsoleted option of the original plugin\n\n anchorFn: anchorFnDefault,\n captionFn: captionFnDefault,\n headerFn: headerFnDefault,\n mkLabel: determine_footnote_symbol,\n\n // see also https://www.editage.com/insights/footnotes-in-tables-part-1-choice-of-footnote-markers-and-their-sequence\n // why asterisk/star is not part of the default footnote marker sequence.\n //\n // For similar reasons, we DO NOT include the section § symbol in this list.\n //\n // when numberSequnce is NULL/empty, a regular numerical numbering is assumed.\n // Otherwise, the array is indexed; when there are more footnotes than entries in\n // the numberSequence array, the entries are re-used, but doubled/trippled, etc.\n //\n // When the indexing in this array hits a NUMERIC value (as last entry), any higher\n // footnotes are NUMBERED starting at that number.\n //\n // NOTE: as we can reference the same footnote from multiple spots, we do not depend\n // on CSS counter() approaches by default, but providee this mechanism in the plugin\n // code itself.\n numberSequence: [ '†', '‡', '††', '‡‡', '¶', 1 ],\n\n // Overrides the footnode mode when set to one of the following:\n //\n // Recognized 'modes':\n // '>': aside note (default for inline notes)\n // ':': end node\n // '=': section note (default for regular referenced notes)\n //\n // Also accepts these keywords: 'aside', 'section', 'end'\n //\n modeOverride: null,\n\n // list section notes and endnotes in order of:\n //\n // 0: first *appearance* in the text\n // 1: first *reference* in the text\n // 2: *definition* in the text\n // 3: sorted alphanumerically by *coded* label,\n // i.e. *numeric* labels are sorted in numeric order (so `10` comes AFTER `7`!),\n // while all others are sorted using `String.localeCompare()`. When labels have\n // a *numeric leading*, e.g. `71geo` --> `71`, that part is sorted numerically first.\n //\n // Here 'coded label' means the label constructed from the reference ids and label overrides\n // as used in the markdown source, using the expression\n // labelOverride || reference || id\n // which gives for these examples (assuming them to be the only definitions in your input):\n // [^refA]: ... --> null || 'refA' || 1\n // [^refB LBL]: ... --> 'LBL' || 'refB' || 2\n // 4: sorted alphanumerically by *printed* label\n // which is like mode 3, but now for the label as will be seen in the *output*!\n sortOrder: 4,\n\n // what to print between bunched-together footnote references, i.e. the '+' in `blabla¹⁺²`\n refCombiner: ','\n};\n\n\n\n\nexport default function footnote_plugin(md, plugin_options) {\n const parseLinkLabel = md.helpers.parseLinkLabel,\n isSpace = md.utils.isSpace;\n\n plugin_options = Object.assign({}, default_plugin_options, plugin_options);\n\n\n\n const modeOverrideMap = {\n aside: '>',\n section: '=',\n end: ':'\n };\n\n function determine_mode(mode: string, default_mode: string) {\n let override = null;\n if (plugin_options.modeOverride) {\n const mode = modeOverrideMap[plugin_options.modeOverride] || plugin_options.modeOverride;\n if ('>:='.includes(plugin_options.modeOverride)) {\n override = plugin_options.modeOverride;\n }\n }\n if ('>:='.includes(mode)) {\n return {\n mode: override || mode,\n fromInput: true\n };\n }\n return {\n mode: override || default_mode,\n fromInput: false\n };\n }\n\n function render_footnote_n(tokens, idx, excludeSubId) {\n const mark = tokens[idx].meta.id;\n assert.ok(Number.isFinite(mark));\n assert.ok(mark > 0);\n let n = '' + mark; // = mark.toString();\n assert.ok(n.length > 0);\n\n if (!excludeSubId && tokens[idx].meta.subId > 0) {\n n += '-' + tokens[idx].meta.subId;\n }\n\n return n;\n }\n\n function render_footnote_mark(renderInfo: RenderInfoParameters): string {\n const token = renderInfo.tokens[renderInfo.idx];\n assert.ok(token != null);\n assert.ok(renderInfo.env.footnotes != null);\n assert.ok(renderInfo.env.footnotes.list != null);\n const info = renderInfo.env.footnotes.list[token.meta.id];\n assert.ok(info != null);\n const mark: string = plugin_options.mkLabel(token.meta.id, info, renderInfo);\n assert.ok(mark.length > 0);\n return mark;\n }\n\n function render_footnote_anchor_name(renderInfo: RenderInfoParameters) {\n const n = render_footnote_n(renderInfo.tokens, renderInfo.idx, true);\n return plugin_options.anchorFn(n, true, renderInfo);\n }\n\n function render_footnote_anchor_nameRef(renderInfo: RenderInfoParameters) {\n const n = render_footnote_n(renderInfo.tokens, renderInfo.idx, false);\n return plugin_options.anchorFn(n, false, renderInfo);\n }\n\n function render_footnote_caption(renderInfo: RenderInfoParameters) {\n const n = render_footnote_mark(renderInfo);\n return plugin_options.captionFn(n, renderInfo);\n }\n\n function render_footnote_ref(tokens, idx, options, env, self) {\n const renderInfo: RenderInfoParameters = {\n tokens,\n idx,\n options,\n env,\n plugin_options,\n self\n };\n const id = render_footnote_anchor_name(renderInfo);\n const caption = render_footnote_caption(renderInfo);\n const refId = render_footnote_anchor_nameRef(renderInfo);\n\n // check if multiple footnote references are bunched together:\n // IFF they are, we should separate them with commas.\n //\n // Exception: when next token has an extra text (`meta.text`) the\n // bunching together is not a problem as them the output will render\n // like this: `bla1text2`, ergo a look\n // like this: `bla¹text²` instead of bunched footnotes references ¹ and ²\n // that would (without the extra comma injection) look like `bla¹²` instead\n // of `x¹⁺²` (here '+' instead of ',' comma, but you get the idea -- there's no\n // Unicode superscript-comma so that's why I used unicode superscript-plus\n // in this 'ascii art' example).\n //\n const next_token = tokens[idx + 1] || {};\n const next_token_meta = next_token.meta || {};\n const bunched_footnote_ref_mode = (next_token.type === 'footnote_ref' ? !next_token_meta.text ? 1 : 2 : 0);\n\n return generateFootnoteRefHtml(id, caption, refId, bunched_footnote_ref_mode, renderInfo);\n }\n\n function render_footnote_block_open(tokens, idx, options, env, self) {\n const renderInfo: RenderInfoParameters = {\n tokens,\n idx,\n options,\n env,\n plugin_options,\n self\n };\n return generateFootnoteSectionStartHtml(renderInfo);\n }\n\n function render_footnote_block_close(tokens, idx, options, env, self) {\n const renderInfo: RenderInfoParameters = {\n tokens,\n idx,\n options,\n env,\n plugin_options,\n self\n };\n return generateFootnoteSectionEndHtml(renderInfo);\n }\n\n function render_footnote_reference_open(tokens, idx, options, env, self) {\n return '';\n }\n\n function render_footnote_reference_close() {\n return '';\n }\n\n function render_footnote_mark_end_of_block() {\n return '';\n }\n\n function render_footnote_open(tokens, idx, options, env, self) {\n const renderInfo: RenderInfoParameters = {\n tokens,\n idx,\n options,\n env,\n plugin_options,\n self\n };\n const id = render_footnote_anchor_name(renderInfo);\n const caption = render_footnote_caption(renderInfo);\n\n // allow both a JavaScript --> CSS approach via `data-footnote-caption`\n // and a classic CSS approach while a display:inline-block SUP presenting\n // the LI 'button' instead:\n return generateFootnoteStartHtml(id, caption, renderInfo);\n }\n\n function render_footnote_close(tokens, idx, options, env, self) {\n const renderInfo: RenderInfoParameters = {\n tokens,\n idx,\n options,\n env,\n plugin_options,\n self\n };\n return generateFootnoteEndHtml(renderInfo);\n }\n\n function render_footnote_anchor_backref(tokens, idx, options, env, self) {\n const renderInfo: RenderInfoParameters = {\n tokens,\n idx,\n options,\n env,\n plugin_options,\n self\n };\n\n const tok = tokens[idx];\n assert.ok(tok != null);\n assert.ok(tok.meta != null);\n const id = render_footnote_anchor_name(renderInfo);\n let refId = render_footnote_n(tokens, idx, false);\n refId = plugin_options.anchorFn(refId, false, renderInfo);\n\n return generateFootnoteBackRefHtml(id, refId, renderInfo);\n }\n\n\n\n md.renderer.rules.footnote_ref = render_footnote_ref;\n md.renderer.rules.footnote_block_open = render_footnote_block_open;\n md.renderer.rules.footnote_block_close = render_footnote_block_close;\n md.renderer.rules.footnote_reference_open = render_footnote_reference_open;\n md.renderer.rules.footnote_reference_close = render_footnote_reference_close;\n md.renderer.rules.footnote_mark_end_of_block = render_footnote_mark_end_of_block;\n md.renderer.rules.footnote_open = render_footnote_open;\n md.renderer.rules.footnote_close = render_footnote_close;\n md.renderer.rules.footnote_anchor = render_footnote_anchor_backref;\n\n\n\n function obtain_footnote_info_slot(env, label: string|null, at_definition: boolean) {\n // inline blocks have their own *child* environment in markdown-it v10+.\n // As the footnotes must live beyond the lifetime of the inline block env,\n // we must patch them into the `parentState.env` for the footnote_tail\n // handler to be able to access them afterwards!\n while (env.parentState) {\n env = env.parentState.env;\n assert.ok(env != null);\n }\n\n if (!env.footnotes) {\n env.footnotes = {\n // map label tto ID:\n refs: {},\n // store footnote info indexed by ID\n list: [],\n // remap ID to re-ordered ID (determines placement order for section notes and endnotes)\n idMap: [ 0 ],\n idMapCounter: 0,\n\n // and a counter for the generated sections (including asides); see the demo/test which\n // uses the generated `#fnsection-DDD` identifiers to hack/fix the styling, for example.\n sectionCounter: 0\n };\n }\n\n // When label is NULL, this is a request from in INLINE NOTE.\n\n // NOTE: IDs are index numbers, BUT they start at 1 instead of 0 to make life easier in check code:\n let footnoteId;\n let infoRec: footnoteMetaInfo;\n // label as index: prepend ':' to avoid conflict with Object.prototype members\n if (label == null || !env.footnotes.refs[':' + label]) {\n footnoteId = Math.max(1, env.footnotes.list.length);\n infoRec = {\n id: footnoteId,\n label,\n labelOverride: null,\n mode: null,\n content: null,\n tokens: null,\n count: 0\n };\n env.footnotes.list[footnoteId] = infoRec;\n if (label != null) {\n env.footnotes.refs[':' + label] = footnoteId;\n }\n } else {\n footnoteId = env.footnotes.refs[':' + label];\n infoRec = env.footnotes.list[footnoteId];\n assert.ok(!!infoRec, 'expects non-NULL footnote info record');\n }\n\n const idMap = env.footnotes.idMap;\n\n // now check if the idMap[] has been set up already as well. This depends on\n // when WE are invoked (`at_definition`) and the configured `options.sortOrder`:\n switch (plugin_options.sortOrder) {\n // 0: first *appearance* in the text\n default:\n case 0:\n // basically, this means: order as-is\n if (!idMap[footnoteId]) {\n idMap[footnoteId] = ++env.footnotes.idMapCounter;\n }\n break;\n\n // 1: first *reference* in the text\n case 1:\n if (!at_definition && !idMap[footnoteId]) {\n // first reference is now!\n idMap[footnoteId] = ++env.footnotes.idMapCounter;\n }\n break;\n\n // 2: *definition* in the text\n case 2:\n if (at_definition && !idMap[footnoteId]) {\n // definition is now!\n idMap[footnoteId] = ++env.footnotes.idMapCounter;\n }\n break;\n\n // 3: sorted alphanumerically by label (inline footnotes will end up at the top, before all other notes)\n case 3:\n case 4:\n // just note the footnoteId now; this must be re-ordered later when we have collected all footnotes.\n //\n // set it up when we get there...\n break;\n }\n\n return infoRec;\n }\n\n function find_end_of_block_marker(state, startIndex) {\n let idx, len;\n const tokens = state.tokens;\n for (idx = startIndex, len = tokens.length; idx < len; idx++) {\n if (tokens[idx].type === 'footnote_mark_end_of_block') { return idx; }\n }\n\n // Punch a slot into the token stream (at the very end)\n // for consistency with footnote_mark_end_of_block():\n const token = new state.Token('footnote_mark_end_of_block', '', 0);\n token.hidden = true;\n tokens.push(token);\n return tokens.length - 1;\n }\n\n function update_end_of_block_marker(state, footnoteId) {\n // inject marker into parent = block level token stream to announce the advent of an (inline) footnote:\n // because the markdown_it code uses a for() loop to go through the parent nodes while parsing the\n // 'inline' chunks, we CANNOT safely inject a marker BEFORE the chunk, only AFTERWARDS:\n const parentState = state.env.parentState;\n const parentIndex = state.env.parentTokenIndex;\n const markerTokenIndex = find_end_of_block_marker(parentState, parentIndex + 1);\n const token = parentState.tokens[markerTokenIndex];\n if (!token.meta) {\n token.meta = {\n footnote_list: []\n };\n }\n token.meta.footnote_list.push(footnoteId);\n }\n\n // Mark end of paragraph/heading/whatever BLOCK (or rather: START of the next block!)\n function footnote_mark_end_of_block(state, startLine, endLine, silent) {\n if (!silent && state.tokens.length > 0) {\n const token = state.push('footnote_mark_end_of_block', '', 0);\n token.hidden = true;\n }\n return false;\n }\n\n\n\n // Process footnote block definition\n function footnote_def(state, startLine, endLine, silent) {\n let oldBMark, oldTShift, oldSCount, oldParentType, pos, token,\n initial, offset, ch, posAfterColon,\n start = state.bMarks[startLine] + state.tShift[startLine],\n max = state.eMarks[startLine];\n\n // line should be at least 6 chars - \"[^x]: \" or \"[^x]:> \"\n if (start + 5 > max) { return false; }\n\n if (state.src.charCodeAt(start) !== 0x5B/* [ */) { return false; }\n if (state.src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; }\n\n for (pos = start + 2; pos < max; pos++) {\n if (state.src.charCodeAt(pos) === 0x0A /* LF */) { return false; }\n if (state.src.charCodeAt(pos) === 0x5D /* ] */) {\n break;\n }\n }\n const labelEnd = pos;\n\n if (pos === start + 2) { return false; } // no empty footnote labels\n if (pos + 1 >= max || state.src.charCodeAt(++pos) !== 0x3A /* : */) { return false; }\n\n const mode_rec = determine_mode(state.src[pos + 1], '='); // default mode is section_note mode.\n if (mode_rec.fromInput) { pos++; }\n const mode = mode_rec.mode;\n\n if (pos + 1 >= max || state.src.charCodeAt(++pos) !== 0x20 /* space */) { return false; }\n if (silent) { return true; }\n pos++;\n\n const labelInfo = decode_label(state.src.slice(start + 2, labelEnd), true);\n if (!labelInfo) { return false; }\n assert.ok(!labelInfo.extraText);\n\n // Now see if we already have a footnote ID for this footnote label:\n // fetch it if we have one and otherwise produce a new one so everyone\n // can use this from now on.\n //\n // This scenario is possible when the footnote *definition* comes BEFORE\n // the first actual footnote *use* (*reference*). This is UNUSUAL when people\n // write texts, but it is *not impossible*, particularly now that we have\n // specified-by-design that endnotes can be marked as such (`[^label]:: note text`)\n // and freely mixed with sidenotes (`[^label]:> note text`) and section\n // notes (`[^label]:= note text` (explicit mode) or `[^label]: note text`\n // (implicit mode)), where *section notes* will placed at the spot in the text\n // flow where they were *defined*. Again, highly irregular, BUT someone MAY\n // feel the need to place some section note *definitions* ABOVE their first\n // use point.\n //\n const infoRec = obtain_footnote_info_slot(state.env, labelInfo.label, true);\n if (labelInfo.labelOverride) {\n infoRec.labelOverride = labelInfo.labelOverride;\n }\n infoRec.mode = mode;\n infoRec.content = state.src.slice(pos, max);\n\n token = state.push('footnote_reference_open', '', 1);\n token.meta = {\n id: infoRec.id\n };\n token.hidden = true;\n\n oldBMark = state.bMarks[startLine];\n oldTShift = state.tShift[startLine];\n oldSCount = state.sCount[startLine];\n oldParentType = state.parentType;\n\n posAfterColon = pos;\n initial = offset = state.sCount[startLine] + pos - (state.bMarks[startLine] + state.tShift[startLine]);\n\n while (pos < max) {\n ch = state.src.charCodeAt(pos);\n\n if (isSpace(ch)) {\n if (ch === 0x09) {\n offset += 4 - offset % 4;\n } else {\n offset++;\n }\n } else {\n break;\n }\n\n pos++;\n }\n\n state.tShift[startLine] = pos - posAfterColon;\n state.sCount[startLine] = offset - initial;\n\n state.bMarks[startLine] = posAfterColon;\n state.blkIndent += 4;\n state.parentType = 'footnote';\n\n if (state.sCount[startLine] < state.blkIndent) {\n state.sCount[startLine] += state.blkIndent;\n }\n\n state.md.block.tokenize(state, startLine, endLine, true);\n\n state.parentType = oldParentType;\n state.blkIndent -= 4;\n state.tShift[startLine] = oldTShift;\n state.sCount[startLine] = oldSCount;\n state.bMarks[startLine] = oldBMark;\n\n token = state.push('footnote_reference_close', '', -1);\n token.meta = {\n id: infoRec.id\n };\n\n return true;\n }\n\n\n\n // Process inline footnotes (^[...] or ^[>...])\n function footnote_inline(state, silent) {\n let labelStart,\n labelEnd,\n token,\n tokens,\n max = state.posMax,\n start = state.pos;\n\n if (start + 2 >= max) { return false; }\n if (state.src.charCodeAt(start) !== 0x5E/* ^ */) { return false; }\n if (state.src.charCodeAt(start + 1) !== 0x5B/* [ */) { return false; }\n\n labelStart = start + 2;\n\n // NOTE: inline notes are automatically considered to be ASIDE notes,\n // UNLESS otherwise specified!\n //\n // Recognized 'modes':\n // '>': aside note (default for inline notes)\n // ':': end node\n // '=': section note (default for regular referenced notes)\n //\n // (Also note https://v4.chriskrycho.com/2015/academic-markdown-and-citations.html:\n // our notes look like this: `[^ref]:` while Academic MarkDown references look\n // like this: `[@Belawog2012]` i.e. no '^' in there. Hence these can safely co-exist.)\n //\n const mode_rec = determine_mode(state.src[start + 2], '>'); // default mode is aside ~ sidenote mode.\n if (mode_rec.fromInput) {\n labelStart++;\n }\n const mode = mode_rec.mode;\n\n labelEnd = parseLinkLabel(state, start + 1);\n\n // parser failed to find ']', so it's not a valid note\n if (labelEnd < 0) { return false; }\n\n // We found the end of the link, and know for a fact it's a valid link;\n // so all that's left to do is to call tokenizer.\n //\n if (!silent) {\n // WARNING: claim our footnote slot for there MAY be nested footnotes\n // discovered in the next inline.parse() call below!\n const infoRec = obtain_footnote_info_slot(state.env, null, true);\n infoRec.mode = mode;\n infoRec.count++;\n\n token = state.push('footnote_ref', '', 0);\n token.meta = {\n id: infoRec.id\n };\n\n state.md.inline.parse(\n state.src.slice(labelStart, labelEnd),\n state.md,\n state.env,\n tokens = []\n );\n\n // Now fill our previously claimed slot:\n infoRec.content = state.src.slice(labelStart, labelEnd);\n infoRec.tokens = tokens;\n\n // inject marker into parent = block level token stream to announce the advent of an (inline) footnote:\n // because the markdown_it code uses a for() loop to go through the parent nodes while parsing the\n // 'inline' chunks, we CANNOT safely inject a marker BEFORE the chunk, only AFTERWARDS:\n update_end_of_block_marker(state, infoRec.id);\n\n //md.block.ruler.enable('footnote_mark_end_of_block');\n }\n\n state.pos = labelEnd + 1;\n state.posMax = max;\n return true;\n }\n\n\n\n // Check if this is a valid ffootnote reference label.\n //\n // Also see if there's a label OVERRIDE text or marker ('@') provided.\n //\n // Return the parsed label record.\n function decode_label(label: string, extra_text_is_labelOverride: boolean) {\n if (!label) {\n return null;\n }\n const m = label.match(/^(@?)(\\S+)(?:\\s+(.+))?$/); // label with OPTIONAL override text...\n if (!m) {\n return null;\n }\n assert.ok(m[2].length > 0);\n let extraText = m[3]?.trim();\n // label [output] override?\n let override = null;\n if (m[1]) {\n override = m[2];\n }\n if (extra_text_is_labelOverride && extraText) {\n override = extraText;\n extraText = null;\n }\n\n return {\n label: m[2],\n labelOverride: override,\n extraText\n };\n }\n\n\n\n // Process footnote references with text ([^label ...])\n function footnote_ref_with_text(state, silent) {\n let pos,\n footnoteSubId,\n token,\n max = state.posMax,\n start = state.pos;\n\n // should be at least 6 chars - \"[^l x]\"\n if (start + 5 > max) { return false; }\n\n if (state.src.charCodeAt(start) !== 0x5B/* [ */) { return false; }\n if (state.src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; }\n\n for (pos = start + 2; pos < max; pos++) {\n if (state.src.charCodeAt(pos) === 0x0A /* linefeed */) { return false; }\n if (state.src.charCodeAt(pos) === 0x5D /* ] */) {\n break;\n }\n }\n\n if (pos === start + 2) { return false; } // no empty footnote labels\n if (pos >= max) { return false; }\n pos++;\n\n const labelInfo = decode_label(state.src.slice(start + 2, pos - 1), false);\n if (!labelInfo || !labelInfo.extraText) { return false; }\n assert.ok(labelInfo.extraText.length > 0);\n\n const infoRec = obtain_footnote_info_slot(state.env, labelInfo.label, false);\n if (labelInfo.labelOverride) {\n infoRec.labelOverride = labelInfo.labelOverride;\n }\n\n if (!silent) {\n footnoteSubId = infoRec.count;\n\n infoRec.count++;\n\n token = state.push('footnote_ref', '', 0);\n token.meta = {\n id: infoRec.id,\n subId: footnoteSubId,\n text: labelInfo.extraText\n };\n\n update_end_of_block_marker(state, infoRec.id);\n\n //md.block.ruler.enable('footnote_mark_end_of_block');\n }\n\n state.pos = pos;\n state.posMax = max;\n return true;\n }\n\n\n\n // Process footnote references ([^...])\n function footnote_ref(state, silent) {\n let pos,\n footnoteSubId,\n token,\n max = state.posMax,\n start = state.pos;\n\n // should be at least 4 chars - \"[^x]\"\n if (start + 3 > max) { return false; }\n\n if (state.src.charCodeAt(start) !== 0x5B/* [ */) { return false; }\n if (state.src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; }\n\n for (pos = start + 2; pos < max; pos++) {\n //if (state.src.charCodeAt(pos) === 0x20) { return false; }\n if (state.src.charCodeAt(pos) === 0x0A) { return false; }\n if (state.src.charCodeAt(pos) === 0x5D /* ] */) {\n break;\n }\n }\n\n if (pos === start + 2) { return false; } // no empty footnote labels\n if (pos >= max) { return false; }\n pos++;\n\n const labelInfo = decode_label(state.src.slice(start + 2, pos - 1), true);\n if (!labelInfo) { return false; }\n assert.ok(!labelInfo.extraText);\n\n const infoRec = obtain_footnote_info_slot(state.env, labelInfo.label, false);\n if (labelInfo.labelOverride) {\n infoRec.labelOverride = labelInfo.labelOverride;\n }\n\n if (!silent) {\n footnoteSubId = infoRec.count;\n\n infoRec.count++;\n\n token = state.push('footnote_ref', '', 0);\n token.meta = {\n id: infoRec.id,\n subId: footnoteSubId\n };\n\n update_end_of_block_marker(state, infoRec.id);\n\n //md.block.ruler.enable('footnote_mark_end_of_block');\n }\n\n state.pos = pos;\n state.posMax = max;\n return true;\n }\n\n\n\n function place_footnote_definitions_at(state, token_idx: number, footnote_id_list, category: string, baseInfo: GenericInfoParameters) {\n if (footnote_id_list.length === 0) {\n return; // nothing to inject...\n }\n\n let inject_tokens = [];\n assert.ok(baseInfo.env.footnotes.list != null);\n const footnote_spec_list = baseInfo.env.footnotes.list;\n\n let token = new state.Token('footnote_block_open', '', 1);\n token.markup = plugin_options.headerFn(category, baseInfo.env, plugin_options);\n token.meta = {\n sectionId: ++baseInfo.env.footnotes.sectionCounter,\n category\n };\n inject_tokens.push(token);\n\n for (const id of footnote_id_list) {\n const fn = footnote_spec_list[id];\n const inject_start_index = inject_tokens.length;\n\n token = new state.Token('footnote_open', '', 1);\n token.meta = {\n id,\n category\n };\n inject_tokens.push(token);\n\n if (fn.label == null) {\n // process an inline footnote text:\n token = new state.Token('paragraph_open', 'p', 1);\n token.block = true;\n inject_tokens.push(token);\n\n token = new state.Token('inline', '', 0);\n token.children = fn.tokens;\n token.content = fn.content;\n inject_tokens.push(token);\n\n token = new state.Token('paragraph_close', 'p', -1);\n token.block = true;\n inject_tokens.push(token);\n } else {\n // process a labeled footnote:\n inject_tokens = inject_tokens.concat(fn.tokens || []);\n }\n\n //let lastParagraph;\n //if (inject_tokens[inject_tokens.length - 1].type === 'paragraph_close') {\n // lastParagraph = inject_tokens.pop();\n //} else {\n // lastParagraph = null;\n //}\n\n const cnt = fn.count;\n assert.ok(cnt >= 0);\n for (let j = 0; j < cnt; j++) {\n token = new state.Token('footnote_anchor', '', 0);\n token.meta = {\n id,\n subId: j,\n backrefCount: cnt,\n category\n };\n inject_tokens.push(token);\n }\n\n //if (lastParagraph) {\n // inject_tokens.push(lastParagraph);\n //}\n\n token = new state.Token('footnote_close', '', -1);\n token.meta = {\n id,\n category\n };\n inject_tokens.push(token);\n }\n\n token = new state.Token('footnote_block_close', '', -1);\n token.meta = {\n category\n };\n inject_tokens.push(token);\n\n state.tokens.splice(token_idx, 0, ...inject_tokens);\n }\n\n function more_footnote_reference_blocks_follow_immediately(tokens, idx) {\n let tok = tokens[idx];\n while (tok && (tok.type === 'footnote_mark_end_of_block' || tok.type === 'footnote_reference_close')) {\n idx++;\n tok = tokens[idx];\n }\n return tok && (tok.type === 'footnote_reference_open');\n }\n\n // Glue footnote tokens into appropriate slots of token stream.\n function footnote_tail(state, startLine, endLine, silent) {\n let i, l, j, t, token, current, currentRefToken,\n insideRef = false,\n refTokens = {};\n\n if (!state.env.footnotes) {\n // no footnotes at all? --> filter out all 'footnote_mark_end_of_block' chunks:\n state.tokens = state.tokens.filter(function (tok, idx) {\n return (tok.type !== 'footnote_mark_end_of_block');\n });\n return;\n }\n\n const idMap = state.env.footnotes.idMap;\n\n const baseInfo: GenericInfoParameters = {\n options: state.md.options,\n env: state.env,\n plugin_options,\n self: this\n };\n\n function footnote_print_comparer(idA, idB) {\n return idMap[idA] - idMap[idB];\n }\n\n\n // Rewrite the tokenstream to place the aside-footnotes and section footnotes where they need to be:\n const footnote_spec_list = state.env.footnotes.list;\n\n // extract the tokens constituting the footnote/sidenote *content* and\n // store that bunch in `refTokens[:]` instead, to be injected back into\n // the tokenstream at the appropriate spots.\n state.tokens = state.tokens.filter(function (tok, idx) {\n switch (tok.type) {\n // filter out 'footnote_mark_end_of_block' tokens which follow BLOCKS that do not contain any\n // footnote/sidenote/endnote references:\n case 'footnote_mark_end_of_block':\n if (!tok.meta) return false;\n if (!tok.meta.footnote_list) return false;\n break;\n\n case 'footnote_reference_open':\n insideRef = true;\n current = [];\n currentRefToken = tok;\n return true;\n\n case 'footnote_reference_close':\n insideRef = false;\n\n const infoRec = footnote_spec_list[tok.meta.id];\n infoRec.tokens = current;\n\n return true;\n }\n if (insideRef) {\n current.push(tok);\n }\n return !insideRef;\n });\n\n\n // execute configured sorting/mapping (`idMap`):\n switch (plugin_options.sortOrder) {\n // 0: first *appearance* in the text\n default:\n case 0:\n // 1: first *reference* in the text\n case 1:\n // 2: *definition* in the text\n case 2:\n // order is specified in the `idMap` already.\n break;\n\n // 3: sorted alphanumerically by label (inline footnotes will end up at the top, before all other notes)\n case 3:\n case 4:\n // the `idMap[]` array has not been set up and must be produced\n // to turn this into an alphanumerically-by-label sort order, where\n // a `footnoteId` based index will produce the order of appearance.\n const reIdMap = [];\n for (let i = 1; i < footnote_spec_list.length; i++) {\n reIdMap[i - 1] = i;\n }\n reIdMap.sort((idA, idB) => {\n const infoA = footnote_spec_list[idA];\n const infoB = footnote_spec_list[idB];\n assert.ok(infoA);\n assert.ok(infoB);\n\n // is any of these an inline footnote, i.e. without any label yet? Produce a fake label for sorting then!\n //\n // As stated elsewhere: inline section_notes and end_notes will end up among everyone else in this sort order mode.\n assert.ok(infoA.id === idA);\n assert.ok(infoB.id === idB);\n\n // Split a \"sort label\" up into its numerical part and the tail. Note that we don't call\n // it 'tail' but 'label', because we will need to compare the ENTIRE LABEL using string comparison\n // when the numeric leaders are identical, so as to ensure that 'labels' such as `00000` will sort\n // as 'higher' than `000`, both of which will be rated as numerically identical!\n function to_atoms(label) {\n // now extract number or numerical leader part.\n //\n // Only accept OBVIOUS, SIMPLE NUMERIC LEADERS! This is about *legibility*\n // of those numrical leaders, not a pedantic \"what is possibly legally numeric\"\n // challenge. Hence we DO NOT accept leading +/- and only a decimal dot when\n // there's a decimal number BEFORE it, such as in `5.1hack` --> `5.1`, but NOT\n // `.42oz`!\n //\n // Do not use `nmr = +lbl` as that would treat labels such as `0xf4` as hexadecimal numbers,\n // which we DO NOT want to happen.\n const m = label.match(/^\\d+(?:\\.\\d+)?/) || [ 'x' ];\n const nmr = +m[0] || Infinity; // non-numeric labels are rated NUMEICALLY HIGHER than any numerical leader.\n return {\n label,\n number: nmr\n };\n }\n\n const labelA = (plugin_options.sortOrder === 3 ?\n infoA.labelOverride || infoA.label || ('' + infoA.id) :\n plugin_options.mkLabel(infoA.id, infoA, baseInfo)\n );\n const labelB = (plugin_options.sortOrder === 3 ?\n infoB.labelOverride || infoB.label || ('' + infoB.id) :\n plugin_options.mkLabel(infoB.id, infoB, baseInfo)\n );\n const atomA = to_atoms(labelA);\n const atomB = to_atoms(labelB);\n const diff = atomA.number - atomB.number;\n return diff || atomA.label.localeCompare(atomB.label);\n // ^^^^^^^ shorthand for:\n //\n // if (isNaN(diff) || diff === 0) then stringcompare else numeric-difference\n });\n\n // Now turn this into a sort order map:\n for (let prio = 0; prio < reIdMap.length; prio++) {\n const id = reIdMap[prio];\n idMap[id] = prio;\n }\n break;\n }\n\n\n const inject_tokens = [];\n\n // Now go through the token stream and place the sidenotes, section_notes and endnotes where they belong:\n let aside_list;\n let section_list = new Set();\n const section_done_list = new Set(); // once a section_note has been printed, it should never appear again!\n const end_list = new Set();\n const used_list = new Set();\n\n let tokens = state.tokens;\n\n for (i = 0; i < tokens.length; i++) {\n const tok = tokens[i];\n switch (tok.type) {\n case 'footnote_mark_end_of_block':\n // check the gathered list of footnotes referenced in this block:\n // - dump the ones which are sidenotes\n // - mark the ones which are section- or end-notes.\n //\n // Note: make sure we don't produce duplicates in the collect sets.\n {\n aside_list = new Set();\n\n const refd_notes_list = (tok.meta?.footnote_list || []);\n for (const id of refd_notes_list) {\n const footnote = footnote_spec_list[id];\n\n switch (footnote.mode) {\n case '>':\n aside_list.add(id);\n used_list.add(id);\n break;\n\n case '=':\n if (!section_done_list.has(id)) {\n section_list.add(id);\n section_done_list.add(id);\n used_list.add(id);\n }\n break;\n\n default:\n case ':':\n end_list.add(id);\n used_list.add(id);\n break;\n }\n }\n\n const aside_ids = [];\n for (const id of aside_list.values()) {\n aside_ids.push(id);\n }\n aside_ids.sort(footnote_print_comparer);\n\n place_footnote_definitions_at(state, i + 1, aside_ids, 'aside', baseInfo);\n tokens = state.tokens;\n }\n break;\n\n case 'footnote_reference_close':\n // anywhere a footnote *definition* appeared in the original text is\n // also a place to dump the section_notes gathered to date, so to speak.\n //\n // However, DO detect clusters of footnote definitions and MERGE them\n // together:\n if (more_footnote_reference_blocks_follow_immediately(tokens, i + 1)) {\n continue;\n } else {\n const section_ids = [];\n for (const id of section_list.values()) {\n section_ids.push(id);\n }\n section_ids.sort(footnote_print_comparer);\n\n place_footnote_definitions_at(state, i + 1, section_ids, 'section', baseInfo);\n tokens = state.tokens;\n\n // and reset the tracking set:\n section_list = new Set();\n }\n break;\n }\n }\n\n // Now process the endnotes:\n {\n const end_ids = [];\n for (const id of end_list.values()) {\n end_ids.push(id);\n }\n end_ids.sort(footnote_print_comparer);\n\n place_footnote_definitions_at(state, tokens.length, end_ids, 'end', baseInfo);\n tokens = state.tokens;\n }\n\n // Now process the unused footnotes and dump them for diagnostic purposes:\n {\n const unused_ids = [];\n\n for (let i = 1; i < footnote_spec_list.length; i++) {\n const fn = footnote_spec_list[i];\n const id = fn.id;\n if (!used_list.has(id)) {\n console.error(`ERROR: footnote ID ${id} is defined but never used. Footnote will be added as an ERRONEOUS ENDNOTE to the output, so the situation is easy to diagnose!`, Object.assign({}, fn, { tokens: '......' }));\n unused_ids.push(id);\n }\n }\n unused_ids.sort(footnote_print_comparer);\n\n place_footnote_definitions_at(state, tokens.length, unused_ids, 'Error::Unused', baseInfo);\n //tokens = state.tokens;\n }\n\n // Update state_block too as we have rewritten & REPLACED the token array earlier in this call:\n // the reference `state.env.state_block.tokens` is still pointing to the OLD token array!\n state.env.state_block.tokens = state.tokens;\n }\n\n\n\n\n // attach ourselves to the start of block handling too\n md.block.ruler.before('table', 'footnote_mark_end_of_block', footnote_mark_end_of_block);\n\n md.block.ruler.before('reference', 'footnote_def', footnote_def, { alt: [ 'paragraph', 'reference' ] });\n md.inline.ruler.after('image', 'footnote_inline', footnote_inline);\n md.inline.ruler.after('footnote_inline', 'footnote_ref_with_text', footnote_ref_with_text);\n md.inline.ruler.after('footnote_ref_with_text', 'footnote_ref', footnote_ref);\n md.core.ruler.after('inline', 'footnote_tail', footnote_tail);\n}\n"],"names":["anchorFnDefault","n","excludeSubId","baseInfo","env","assert","ok","prefix","docId","length","captionFnDefault","headerFnDefault","category","determine_footnote_symbol","idx","info","plugin_options","label","labelOverride","numberSequence","len","slot","Number","isFinite","delta","dupli","remainder","core","str","i","bunched_mode_classes","generateFootnoteRefHtml","id","caption","refId","bunched_footnote_ref_mode","renderInfo","localOverride","tokens","meta","text","refCombiner","generateFootnoteSectionStartHtml","tok","header","markup","replace","sectionId","options","xhtmlOut","generateFootnoteSectionEndHtml","generateFootnoteStartHtml","generateFootnoteEndHtml","generateFootnoteBackRefHtml","subId","backrefCount","default_plugin_options","anchorFn","captionFn","headerFn","mkLabel","modeOverride","sortOrder","footnote_plugin","md","parseLinkLabel","helpers","isSpace","utils","Object","assign","determine_mode","mode","default_mode","override","includes","fromInput","render_footnote_n","mark","render_footnote_mark","token","footnotes","list","render_footnote_anchor_name","render_footnote_anchor_nameRef","render_footnote_caption","render_footnote_ref","self","next_token","next_token_meta","type","render_footnote_block_open","render_footnote_block_close","render_footnote_reference_open","render_footnote_reference_close","render_footnote_mark_end_of_block","render_footnote_open","render_footnote_close","render_footnote_anchor_backref","renderer","rules","footnote_ref","footnote_block_open","footnote_block_close","footnote_reference_open","footnote_reference_close","footnote_mark_end_of_block","footnote_open","footnote_close","footnote_anchor","obtain_footnote_info_slot","at_definition","parentState","refs","idMap","idMapCounter","sectionCounter","footnoteId","infoRec","Math","max","content","count","find_end_of_block_marker","state","startIndex","Token","hidden","push","update_end_of_block_marker","parentIndex","parentTokenIndex","markerTokenIndex","footnote_list","startLine","endLine","silent","footnote_def","oldBMark","oldTShift","oldSCount","oldParentType","pos","initial","offset","ch","posAfterColon","start","bMarks","tShift","eMarks","src","charCodeAt","labelEnd","mode_rec","labelInfo","decode_label","slice","extraText","sCount","parentType","blkIndent","block","tokenize","footnote_inline","labelStart","posMax","inline","parse","extra_text_is_labelOverride","m","match","trim","footnote_ref_with_text","footnoteSubId","place_footnote_definitions_at","token_idx","footnote_id_list","inject_tokens","footnote_spec_list","fn","children","concat","cnt","j","splice","more_footnote_reference_blocks_follow_immediately","footnote_tail","current","insideRef","filter","footnote_print_comparer","idA","idB","reIdMap","sort","infoA","infoB","to_atoms","nmr","Infinity","number","labelA","labelB","atomA","atomB","diff","localeCompare","prio","aside_list","section_list","Set","section_done_list","end_list","used_list","refd_notes_list","footnote","add","has","aside_ids","values","section_ids","end_ids","unused_ids","console","error","state_block","ruler","before","alt","after"],"mappings":"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"} \ No newline at end of file diff --git a/dist/markdownItFootnote.mjs b/dist/markdownItFootnote.mjs new file mode 100644 index 0000000..a369531 --- /dev/null +++ b/dist/markdownItFootnote.mjs @@ -0,0 +1,1298 @@ +/*! markdown-it-footnote 3.0.3-10 https://github.com//GerHobbelt/markdown-it-footnote @license MIT */ + +import { strict } from 'assert'; + +// Process footnotes + +function anchorFnDefault(n, excludeSubId, baseInfo) { + const env = baseInfo.env; + strict.ok(env != null); + let prefix = ''; + + if (typeof env.docId === 'string' && env.docId.length > 0) { + prefix = '-' + env.docId + '-'; + } + + return prefix + n; +} + +function captionFnDefault(n, baseInfo) { + //return '[' + n + ']'; + return '' + n; +} + +function headerFnDefault(category, baseInfo) { + switch (category) { + case 'aside': + return 'Side Notes'; + + case 'section': + return 'Section Notes'; + + case 'end': + return 'Endnotes'; + + default: + // used for error category, e.g. 'Error::Unused' + return category; + } +} + +function determine_footnote_symbol(idx, info, baseInfo) { + const plugin_options = baseInfo.plugin_options; + strict.ok(plugin_options != null); // rule to construct the printed label: + // + // mark = labelOverride /* || info.label */ || idx; + + const label = info.labelOverride; + + if (label) { + return label; + } + + if (plugin_options.numberSequence == null || plugin_options.numberSequence.length === 0) { + return '' + idx; + } + + const len = plugin_options.numberSequence.length; + + if (idx >= len) { + // is last slot numeric or alphanumerically? + const slot = plugin_options.numberSequence[len - 1]; + + if (Number.isFinite(slot)) { + const delta = idx - len + 1; + return '' + (slot + delta); + } // non-numerical last slot --> duplicate, triplicate, etc. + + + const dupli = idx / len | 0; // = int(x mod N) + + const remainder = idx % len; + const core = plugin_options.numberSequence[remainder]; + let str = '' + core; + + for (let i = 1; i < dupli; i++) { + str += core; + } + + return str; + } + + return '' + plugin_options.numberSequence[idx]; +} + +const bunched_mode_classes = ['', 'footnote-bunched-ref-ref', 'footnote-bunched-ref-text']; + +function generateFootnoteRefHtml(id, caption, refId, bunched_footnote_ref_mode, renderInfo) { + let localOverride = renderInfo.tokens[renderInfo.idx].meta.text; + + if (localOverride) { + localOverride = `${localOverride}`; + } + + return `${localOverride || ''}${caption}` + (bunched_footnote_ref_mode !== 0 ? `${renderInfo.plugin_options.refCombiner || ''}` : ''); +} + +function generateFootnoteSectionStartHtml(renderInfo) { + const tok = renderInfo.tokens[renderInfo.idx]; + strict.ok(tok != null); + strict.ok(tok.meta != null); + const header = tok.markup ? `

    ${tok.markup}

    ` : ''; + let category = tok.meta.category; + strict.ok(category.length > 0); // `category` can contain CSS class illegal characters, e.g. when category = 'Error::Unused': + + category = category.replace(/[^a-zA-Z0-9_-]+/g, '_'); + return `
    \n'; +} + +function generateFootnoteStartHtml(id, caption, renderInfo) { + // allow both a JavaWScript --> CSS approach via `data-footnote-caption` + // and a classic CSS approach while a display:inline-block SUP presenting + // the LI 'button' instead: + return `
  • ${caption}`; +} + +function generateFootnoteEndHtml(renderInfo) { + return '
  • \n'; +} + +function generateFootnoteBackRefHtml(id, refId, renderInfo) { + const tok = renderInfo.tokens[renderInfo.idx]; + strict.ok(tok != null); + strict.ok(tok.meta != null); + /* ↩ with escape code to prevent display as Apple Emoji on iOS */ + + return ` \u21a9\uFE0E`; +} + +const default_plugin_options = { + // atDocumentEnd: false, -- obsoleted option of the original plugin + anchorFn: anchorFnDefault, + captionFn: captionFnDefault, + headerFn: headerFnDefault, + mkLabel: determine_footnote_symbol, + // see also https://www.editage.com/insights/footnotes-in-tables-part-1-choice-of-footnote-markers-and-their-sequence + // why asterisk/star is not part of the default footnote marker sequence. + // + // For similar reasons, we DO NOT include the section § symbol in this list. + // + // when numberSequnce is NULL/empty, a regular numerical numbering is assumed. + // Otherwise, the array is indexed; when there are more footnotes than entries in + // the numberSequence array, the entries are re-used, but doubled/trippled, etc. + // + // When the indexing in this array hits a NUMERIC value (as last entry), any higher + // footnotes are NUMBERED starting at that number. + // + // NOTE: as we can reference the same footnote from multiple spots, we do not depend + // on CSS counter() approaches by default, but providee this mechanism in the plugin + // code itself. + numberSequence: ['†', '‡', '††', '‡‡', '¶', 1], + // Overrides the footnode mode when set to one of the following: + // + // Recognized 'modes': + // '>': aside note (default for inline notes) + // ':': end node + // '=': section note (default for regular referenced notes) + // + // Also accepts these keywords: 'aside', 'section', 'end' + // + modeOverride: null, + // list section notes and endnotes in order of: + // + // 0: first *appearance* in the text + // 1: first *reference* in the text + // 2: *definition* in the text + // 3: sorted alphanumerically by *coded* label, + // i.e. *numeric* labels are sorted in numeric order (so `10` comes AFTER `7`!), + // while all others are sorted using `String.localeCompare()`. When labels have + // a *numeric leading*, e.g. `71geo` --> `71`, that part is sorted numerically first. + // + // Here 'coded label' means the label constructed from the reference ids and label overrides + // as used in the markdown source, using the expression + // labelOverride || reference || id + // which gives for these examples (assuming them to be the only definitions in your input): + // [^refA]: ... --> null || 'refA' || 1 + // [^refB LBL]: ... --> 'LBL' || 'refB' || 2 + // 4: sorted alphanumerically by *printed* label + // which is like mode 3, but now for the label as will be seen in the *output*! + sortOrder: 4, + // what to print between bunched-together footnote references, i.e. the '+' in `blabla¹⁺²` + refCombiner: ',' +}; +function footnote_plugin(md, plugin_options) { + const parseLinkLabel = md.helpers.parseLinkLabel, + isSpace = md.utils.isSpace; + plugin_options = Object.assign({}, default_plugin_options, plugin_options); + + function determine_mode(mode, default_mode) { + let override = null; + + if (plugin_options.modeOverride) { + + if ('>:='.includes(plugin_options.modeOverride)) { + override = plugin_options.modeOverride; + } + } + + if ('>:='.includes(mode)) { + return { + mode: override || mode, + fromInput: true + }; + } + + return { + mode: override || default_mode, + fromInput: false + }; + } + + function render_footnote_n(tokens, idx, excludeSubId) { + const mark = tokens[idx].meta.id; + strict.ok(Number.isFinite(mark)); + strict.ok(mark > 0); + let n = '' + mark; // = mark.toString(); + + strict.ok(n.length > 0); + + if (!excludeSubId && tokens[idx].meta.subId > 0) { + n += '-' + tokens[idx].meta.subId; + } + + return n; + } + + function render_footnote_mark(renderInfo) { + const token = renderInfo.tokens[renderInfo.idx]; + strict.ok(token != null); + strict.ok(renderInfo.env.footnotes != null); + strict.ok(renderInfo.env.footnotes.list != null); + const info = renderInfo.env.footnotes.list[token.meta.id]; + strict.ok(info != null); + const mark = plugin_options.mkLabel(token.meta.id, info, renderInfo); + strict.ok(mark.length > 0); + return mark; + } + + function render_footnote_anchor_name(renderInfo) { + const n = render_footnote_n(renderInfo.tokens, renderInfo.idx, true); + return plugin_options.anchorFn(n, true, renderInfo); + } + + function render_footnote_anchor_nameRef(renderInfo) { + const n = render_footnote_n(renderInfo.tokens, renderInfo.idx, false); + return plugin_options.anchorFn(n, false, renderInfo); + } + + function render_footnote_caption(renderInfo) { + const n = render_footnote_mark(renderInfo); + return plugin_options.captionFn(n, renderInfo); + } + + function render_footnote_ref(tokens, idx, options, env, self) { + const renderInfo = { + tokens, + idx, + options, + env, + plugin_options, + self + }; + const id = render_footnote_anchor_name(renderInfo); + const caption = render_footnote_caption(renderInfo); + const refId = render_footnote_anchor_nameRef(renderInfo); // check if multiple footnote references are bunched together: + // IFF they are, we should separate them with commas. + // + // Exception: when next token has an extra text (`meta.text`) the + // bunching together is not a problem as them the output will render + // like this: `bla1text2`, ergo a look + // like this: `bla¹text²` instead of bunched footnotes references ¹ and ² + // that would (without the extra comma injection) look like `bla¹²` instead + // of `x¹⁺²` (here '+' instead of ',' comma, but you get the idea -- there's no + // Unicode superscript-comma so that's why I used unicode superscript-plus + // in this 'ascii art' example). + // + + const next_token = tokens[idx + 1] || {}; + const next_token_meta = next_token.meta || {}; + const bunched_footnote_ref_mode = next_token.type === 'footnote_ref' ? !next_token_meta.text ? 1 : 2 : 0; + return generateFootnoteRefHtml(id, caption, refId, bunched_footnote_ref_mode, renderInfo); + } + + function render_footnote_block_open(tokens, idx, options, env, self) { + const renderInfo = { + tokens, + idx, + options, + env, + plugin_options, + self + }; + return generateFootnoteSectionStartHtml(renderInfo); + } + + function render_footnote_block_close(tokens, idx, options, env, self) { + return generateFootnoteSectionEndHtml(); + } + + function render_footnote_reference_open(tokens, idx, options, env, self) { + return ''; + } + + function render_footnote_reference_close() { + return ''; + } + + function render_footnote_mark_end_of_block() { + return ''; + } + + function render_footnote_open(tokens, idx, options, env, self) { + const renderInfo = { + tokens, + idx, + options, + env, + plugin_options, + self + }; + const id = render_footnote_anchor_name(renderInfo); + const caption = render_footnote_caption(renderInfo); // allow both a JavaScript --> CSS approach via `data-footnote-caption` + // and a classic CSS approach while a display:inline-block SUP presenting + // the LI 'button' instead: + + return generateFootnoteStartHtml(id, caption); + } + + function render_footnote_close(tokens, idx, options, env, self) { + return generateFootnoteEndHtml(); + } + + function render_footnote_anchor_backref(tokens, idx, options, env, self) { + const renderInfo = { + tokens, + idx, + options, + env, + plugin_options, + self + }; + const tok = tokens[idx]; + strict.ok(tok != null); + strict.ok(tok.meta != null); + const id = render_footnote_anchor_name(renderInfo); + let refId = render_footnote_n(tokens, idx, false); + refId = plugin_options.anchorFn(refId, false, renderInfo); + return generateFootnoteBackRefHtml(id, refId, renderInfo); + } + + md.renderer.rules.footnote_ref = render_footnote_ref; + md.renderer.rules.footnote_block_open = render_footnote_block_open; + md.renderer.rules.footnote_block_close = render_footnote_block_close; + md.renderer.rules.footnote_reference_open = render_footnote_reference_open; + md.renderer.rules.footnote_reference_close = render_footnote_reference_close; + md.renderer.rules.footnote_mark_end_of_block = render_footnote_mark_end_of_block; + md.renderer.rules.footnote_open = render_footnote_open; + md.renderer.rules.footnote_close = render_footnote_close; + md.renderer.rules.footnote_anchor = render_footnote_anchor_backref; + + function obtain_footnote_info_slot(env, label, at_definition) { + // inline blocks have their own *child* environment in markdown-it v10+. + // As the footnotes must live beyond the lifetime of the inline block env, + // we must patch them into the `parentState.env` for the footnote_tail + // handler to be able to access them afterwards! + while (env.parentState) { + env = env.parentState.env; + strict.ok(env != null); + } + + if (!env.footnotes) { + env.footnotes = { + // map label tto ID: + refs: {}, + // store footnote info indexed by ID + list: [], + // remap ID to re-ordered ID (determines placement order for section notes and endnotes) + idMap: [0], + idMapCounter: 0, + // and a counter for the generated sections (including asides); see the demo/test which + // uses the generated `#fnsection-DDD` identifiers to hack/fix the styling, for example. + sectionCounter: 0 + }; + } // When label is NULL, this is a request from in INLINE NOTE. + // NOTE: IDs are index numbers, BUT they start at 1 instead of 0 to make life easier in check code: + + + let footnoteId; + let infoRec; // label as index: prepend ':' to avoid conflict with Object.prototype members + + if (label == null || !env.footnotes.refs[':' + label]) { + footnoteId = Math.max(1, env.footnotes.list.length); + infoRec = { + id: footnoteId, + label, + labelOverride: null, + mode: null, + content: null, + tokens: null, + count: 0 + }; + env.footnotes.list[footnoteId] = infoRec; + + if (label != null) { + env.footnotes.refs[':' + label] = footnoteId; + } + } else { + footnoteId = env.footnotes.refs[':' + label]; + infoRec = env.footnotes.list[footnoteId]; + strict.ok(!!infoRec, 'expects non-NULL footnote info record'); + } + + const idMap = env.footnotes.idMap; // now check if the idMap[] has been set up already as well. This depends on + // when WE are invoked (`at_definition`) and the configured `options.sortOrder`: + + switch (plugin_options.sortOrder) { + // 0: first *appearance* in the text + default: + case 0: + // basically, this means: order as-is + if (!idMap[footnoteId]) { + idMap[footnoteId] = ++env.footnotes.idMapCounter; + } + + break; + // 1: first *reference* in the text + + case 1: + if (!at_definition && !idMap[footnoteId]) { + // first reference is now! + idMap[footnoteId] = ++env.footnotes.idMapCounter; + } + + break; + // 2: *definition* in the text + + case 2: + if (at_definition && !idMap[footnoteId]) { + // definition is now! + idMap[footnoteId] = ++env.footnotes.idMapCounter; + } + + break; + // 3: sorted alphanumerically by label (inline footnotes will end up at the top, before all other notes) + + case 3: + case 4: + // just note the footnoteId now; this must be re-ordered later when we have collected all footnotes. + // + // set it up when we get there... + break; + } + + return infoRec; + } + + function find_end_of_block_marker(state, startIndex) { + let idx, len; + const tokens = state.tokens; + + for (idx = startIndex, len = tokens.length; idx < len; idx++) { + if (tokens[idx].type === 'footnote_mark_end_of_block') { + return idx; + } + } // Punch a slot into the token stream (at the very end) + // for consistency with footnote_mark_end_of_block(): + + + const token = new state.Token('footnote_mark_end_of_block', '', 0); + token.hidden = true; + tokens.push(token); + return tokens.length - 1; + } + + function update_end_of_block_marker(state, footnoteId) { + // inject marker into parent = block level token stream to announce the advent of an (inline) footnote: + // because the markdown_it code uses a for() loop to go through the parent nodes while parsing the + // 'inline' chunks, we CANNOT safely inject a marker BEFORE the chunk, only AFTERWARDS: + const parentState = state.env.parentState; + const parentIndex = state.env.parentTokenIndex; + const markerTokenIndex = find_end_of_block_marker(parentState, parentIndex + 1); + const token = parentState.tokens[markerTokenIndex]; + + if (!token.meta) { + token.meta = { + footnote_list: [] + }; + } + + token.meta.footnote_list.push(footnoteId); + } // Mark end of paragraph/heading/whatever BLOCK (or rather: START of the next block!) + + + function footnote_mark_end_of_block(state, startLine, endLine, silent) { + if (!silent && state.tokens.length > 0) { + const token = state.push('footnote_mark_end_of_block', '', 0); + token.hidden = true; + } + + return false; + } // Process footnote block definition + + + function footnote_def(state, startLine, endLine, silent) { + let oldBMark, + oldTShift, + oldSCount, + oldParentType, + pos, + token, + initial, + offset, + ch, + posAfterColon, + start = state.bMarks[startLine] + state.tShift[startLine], + max = state.eMarks[startLine]; // line should be at least 6 chars - "[^x]: " or "[^x]:> " + + if (start + 5 > max) { + return false; + } + + if (state.src.charCodeAt(start) !== 0x5B + /* [ */ + ) { + return false; + } + + if (state.src.charCodeAt(start + 1) !== 0x5E + /* ^ */ + ) { + return false; + } + + for (pos = start + 2; pos < max; pos++) { + if (state.src.charCodeAt(pos) === 0x0A + /* LF */ + ) { + return false; + } + + if (state.src.charCodeAt(pos) === 0x5D + /* ] */ + ) { + break; + } + } + + const labelEnd = pos; + + if (pos === start + 2) { + return false; + } // no empty footnote labels + + + if (pos + 1 >= max || state.src.charCodeAt(++pos) !== 0x3A + /* : */ + ) { + return false; + } + + const mode_rec = determine_mode(state.src[pos + 1], '='); // default mode is section_note mode. + + if (mode_rec.fromInput) { + pos++; + } + + const mode = mode_rec.mode; + + if (pos + 1 >= max || state.src.charCodeAt(++pos) !== 0x20 + /* space */ + ) { + return false; + } + + if (silent) { + return true; + } + + pos++; + const labelInfo = decode_label(state.src.slice(start + 2, labelEnd), true); + + if (!labelInfo) { + return false; + } + + strict.ok(!labelInfo.extraText); // Now see if we already have a footnote ID for this footnote label: + // fetch it if we have one and otherwise produce a new one so everyone + // can use this from now on. + // + // This scenario is possible when the footnote *definition* comes BEFORE + // the first actual footnote *use* (*reference*). This is UNUSUAL when people + // write texts, but it is *not impossible*, particularly now that we have + // specified-by-design that endnotes can be marked as such (`[^label]:: note text`) + // and freely mixed with sidenotes (`[^label]:> note text`) and section + // notes (`[^label]:= note text` (explicit mode) or `[^label]: note text` + // (implicit mode)), where *section notes* will placed at the spot in the text + // flow where they were *defined*. Again, highly irregular, BUT someone MAY + // feel the need to place some section note *definitions* ABOVE their first + // use point. + // + + const infoRec = obtain_footnote_info_slot(state.env, labelInfo.label, true); + + if (labelInfo.labelOverride) { + infoRec.labelOverride = labelInfo.labelOverride; + } + + infoRec.mode = mode; + infoRec.content = state.src.slice(pos, max); + token = state.push('footnote_reference_open', '', 1); + token.meta = { + id: infoRec.id + }; + token.hidden = true; + oldBMark = state.bMarks[startLine]; + oldTShift = state.tShift[startLine]; + oldSCount = state.sCount[startLine]; + oldParentType = state.parentType; + posAfterColon = pos; + initial = offset = state.sCount[startLine] + pos - (state.bMarks[startLine] + state.tShift[startLine]); + + while (pos < max) { + ch = state.src.charCodeAt(pos); + + if (isSpace(ch)) { + if (ch === 0x09) { + offset += 4 - offset % 4; + } else { + offset++; + } + } else { + break; + } + + pos++; + } + + state.tShift[startLine] = pos - posAfterColon; + state.sCount[startLine] = offset - initial; + state.bMarks[startLine] = posAfterColon; + state.blkIndent += 4; + state.parentType = 'footnote'; + + if (state.sCount[startLine] < state.blkIndent) { + state.sCount[startLine] += state.blkIndent; + } + + state.md.block.tokenize(state, startLine, endLine, true); + state.parentType = oldParentType; + state.blkIndent -= 4; + state.tShift[startLine] = oldTShift; + state.sCount[startLine] = oldSCount; + state.bMarks[startLine] = oldBMark; + token = state.push('footnote_reference_close', '', -1); + token.meta = { + id: infoRec.id + }; + return true; + } // Process inline footnotes (^[...] or ^[>...]) + + + function footnote_inline(state, silent) { + let labelStart, + labelEnd, + token, + tokens, + max = state.posMax, + start = state.pos; + + if (start + 2 >= max) { + return false; + } + + if (state.src.charCodeAt(start) !== 0x5E + /* ^ */ + ) { + return false; + } + + if (state.src.charCodeAt(start + 1) !== 0x5B + /* [ */ + ) { + return false; + } + + labelStart = start + 2; // NOTE: inline notes are automatically considered to be ASIDE notes, + // UNLESS otherwise specified! + // + // Recognized 'modes': + // '>': aside note (default for inline notes) + // ':': end node + // '=': section note (default for regular referenced notes) + // + // (Also note https://v4.chriskrycho.com/2015/academic-markdown-and-citations.html: + // our notes look like this: `[^ref]:` while Academic MarkDown references look + // like this: `[@Belawog2012]` i.e. no '^' in there. Hence these can safely co-exist.) + // + + const mode_rec = determine_mode(state.src[start + 2], '>'); // default mode is aside ~ sidenote mode. + + if (mode_rec.fromInput) { + labelStart++; + } + + const mode = mode_rec.mode; + labelEnd = parseLinkLabel(state, start + 1); // parser failed to find ']', so it's not a valid note + + if (labelEnd < 0) { + return false; + } // We found the end of the link, and know for a fact it's a valid link; + // so all that's left to do is to call tokenizer. + // + + + if (!silent) { + // WARNING: claim our footnote slot for there MAY be nested footnotes + // discovered in the next inline.parse() call below! + const infoRec = obtain_footnote_info_slot(state.env, null, true); + infoRec.mode = mode; + infoRec.count++; + token = state.push('footnote_ref', '', 0); + token.meta = { + id: infoRec.id + }; + state.md.inline.parse(state.src.slice(labelStart, labelEnd), state.md, state.env, tokens = []); // Now fill our previously claimed slot: + + infoRec.content = state.src.slice(labelStart, labelEnd); + infoRec.tokens = tokens; // inject marker into parent = block level token stream to announce the advent of an (inline) footnote: + // because the markdown_it code uses a for() loop to go through the parent nodes while parsing the + // 'inline' chunks, we CANNOT safely inject a marker BEFORE the chunk, only AFTERWARDS: + + update_end_of_block_marker(state, infoRec.id); //md.block.ruler.enable('footnote_mark_end_of_block'); + } + + state.pos = labelEnd + 1; + state.posMax = max; + return true; + } // Check if this is a valid ffootnote reference label. + // + // Also see if there's a label OVERRIDE text or marker ('@') provided. + // + // Return the parsed label record. + + + function decode_label(label, extra_text_is_labelOverride) { + var _m$; + + if (!label) { + return null; + } + + const m = label.match(/^(@?)(\S+)(?:\s+(.+))?$/); // label with OPTIONAL override text... + + if (!m) { + return null; + } + + strict.ok(m[2].length > 0); + let extraText = (_m$ = m[3]) == null ? void 0 : _m$.trim(); // label [output] override? + + let override = null; + + if (m[1]) { + override = m[2]; + } + + if (extra_text_is_labelOverride && extraText) { + override = extraText; + extraText = null; + } + + return { + label: m[2], + labelOverride: override, + extraText + }; + } // Process footnote references with text ([^label ...]) + + + function footnote_ref_with_text(state, silent) { + let pos, + footnoteSubId, + token, + max = state.posMax, + start = state.pos; // should be at least 6 chars - "[^l x]" + + if (start + 5 > max) { + return false; + } + + if (state.src.charCodeAt(start) !== 0x5B + /* [ */ + ) { + return false; + } + + if (state.src.charCodeAt(start + 1) !== 0x5E + /* ^ */ + ) { + return false; + } + + for (pos = start + 2; pos < max; pos++) { + if (state.src.charCodeAt(pos) === 0x0A + /* linefeed */ + ) { + return false; + } + + if (state.src.charCodeAt(pos) === 0x5D + /* ] */ + ) { + break; + } + } + + if (pos === start + 2) { + return false; + } // no empty footnote labels + + + if (pos >= max) { + return false; + } + + pos++; + const labelInfo = decode_label(state.src.slice(start + 2, pos - 1), false); + + if (!labelInfo || !labelInfo.extraText) { + return false; + } + + strict.ok(labelInfo.extraText.length > 0); + const infoRec = obtain_footnote_info_slot(state.env, labelInfo.label, false); + + if (labelInfo.labelOverride) { + infoRec.labelOverride = labelInfo.labelOverride; + } + + if (!silent) { + footnoteSubId = infoRec.count; + infoRec.count++; + token = state.push('footnote_ref', '', 0); + token.meta = { + id: infoRec.id, + subId: footnoteSubId, + text: labelInfo.extraText + }; + update_end_of_block_marker(state, infoRec.id); //md.block.ruler.enable('footnote_mark_end_of_block'); + } + + state.pos = pos; + state.posMax = max; + return true; + } // Process footnote references ([^...]) + + + function footnote_ref(state, silent) { + let pos, + footnoteSubId, + token, + max = state.posMax, + start = state.pos; // should be at least 4 chars - "[^x]" + + if (start + 3 > max) { + return false; + } + + if (state.src.charCodeAt(start) !== 0x5B + /* [ */ + ) { + return false; + } + + if (state.src.charCodeAt(start + 1) !== 0x5E + /* ^ */ + ) { + return false; + } + + for (pos = start + 2; pos < max; pos++) { + //if (state.src.charCodeAt(pos) === 0x20) { return false; } + if (state.src.charCodeAt(pos) === 0x0A) { + return false; + } + + if (state.src.charCodeAt(pos) === 0x5D + /* ] */ + ) { + break; + } + } + + if (pos === start + 2) { + return false; + } // no empty footnote labels + + + if (pos >= max) { + return false; + } + + pos++; + const labelInfo = decode_label(state.src.slice(start + 2, pos - 1), true); + + if (!labelInfo) { + return false; + } + + strict.ok(!labelInfo.extraText); + const infoRec = obtain_footnote_info_slot(state.env, labelInfo.label, false); + + if (labelInfo.labelOverride) { + infoRec.labelOverride = labelInfo.labelOverride; + } + + if (!silent) { + footnoteSubId = infoRec.count; + infoRec.count++; + token = state.push('footnote_ref', '', 0); + token.meta = { + id: infoRec.id, + subId: footnoteSubId + }; + update_end_of_block_marker(state, infoRec.id); //md.block.ruler.enable('footnote_mark_end_of_block'); + } + + state.pos = pos; + state.posMax = max; + return true; + } + + function place_footnote_definitions_at(state, token_idx, footnote_id_list, category, baseInfo) { + if (footnote_id_list.length === 0) { + return; // nothing to inject... + } + + let inject_tokens = []; + strict.ok(baseInfo.env.footnotes.list != null); + const footnote_spec_list = baseInfo.env.footnotes.list; + let token = new state.Token('footnote_block_open', '', 1); + token.markup = plugin_options.headerFn(category, baseInfo.env, plugin_options); + token.meta = { + sectionId: ++baseInfo.env.footnotes.sectionCounter, + category + }; + inject_tokens.push(token); + + for (const id of footnote_id_list) { + const fn = footnote_spec_list[id]; + token = new state.Token('footnote_open', '', 1); + token.meta = { + id, + category + }; + inject_tokens.push(token); + + if (fn.label == null) { + // process an inline footnote text: + token = new state.Token('paragraph_open', 'p', 1); + token.block = true; + inject_tokens.push(token); + token = new state.Token('inline', '', 0); + token.children = fn.tokens; + token.content = fn.content; + inject_tokens.push(token); + token = new state.Token('paragraph_close', 'p', -1); + token.block = true; + inject_tokens.push(token); + } else { + // process a labeled footnote: + inject_tokens = inject_tokens.concat(fn.tokens || []); + } //let lastParagraph; + //if (inject_tokens[inject_tokens.length - 1].type === 'paragraph_close') { + // lastParagraph = inject_tokens.pop(); + //} else { + // lastParagraph = null; + //} + + + const cnt = fn.count; + strict.ok(cnt >= 0); + + for (let j = 0; j < cnt; j++) { + token = new state.Token('footnote_anchor', '', 0); + token.meta = { + id, + subId: j, + backrefCount: cnt, + category + }; + inject_tokens.push(token); + } //if (lastParagraph) { + // inject_tokens.push(lastParagraph); + //} + + + token = new state.Token('footnote_close', '', -1); + token.meta = { + id, + category + }; + inject_tokens.push(token); + } + + token = new state.Token('footnote_block_close', '', -1); + token.meta = { + category + }; + inject_tokens.push(token); + state.tokens.splice(token_idx, 0, ...inject_tokens); + } + + function more_footnote_reference_blocks_follow_immediately(tokens, idx) { + let tok = tokens[idx]; + + while (tok && (tok.type === 'footnote_mark_end_of_block' || tok.type === 'footnote_reference_close')) { + idx++; + tok = tokens[idx]; + } + + return tok && tok.type === 'footnote_reference_open'; + } // Glue footnote tokens into appropriate slots of token stream. + + + function footnote_tail(state, startLine, endLine, silent) { + let i, + current, + insideRef = false; + + if (!state.env.footnotes) { + // no footnotes at all? --> filter out all 'footnote_mark_end_of_block' chunks: + state.tokens = state.tokens.filter(function (tok, idx) { + return tok.type !== 'footnote_mark_end_of_block'; + }); + return; + } + + const idMap = state.env.footnotes.idMap; + const baseInfo = { + options: state.md.options, + env: state.env, + plugin_options, + self: this + }; + + function footnote_print_comparer(idA, idB) { + return idMap[idA] - idMap[idB]; + } // Rewrite the tokenstream to place the aside-footnotes and section footnotes where they need to be: + + + const footnote_spec_list = state.env.footnotes.list; // extract the tokens constituting the footnote/sidenote *content* and + // store that bunch in `refTokens[:]` instead, to be injected back into + // the tokenstream at the appropriate spots. + + state.tokens = state.tokens.filter(function (tok, idx) { + switch (tok.type) { + // filter out 'footnote_mark_end_of_block' tokens which follow BLOCKS that do not contain any + // footnote/sidenote/endnote references: + case 'footnote_mark_end_of_block': + if (!tok.meta) return false; + if (!tok.meta.footnote_list) return false; + break; + + case 'footnote_reference_open': + insideRef = true; + current = []; + return true; + + case 'footnote_reference_close': + insideRef = false; + const infoRec = footnote_spec_list[tok.meta.id]; + infoRec.tokens = current; + return true; + } + + if (insideRef) { + current.push(tok); + } + + return !insideRef; + }); // execute configured sorting/mapping (`idMap`): + + switch (plugin_options.sortOrder) { + // 0: first *appearance* in the text + default: + case 0: // 1: first *reference* in the text + + case 1: // 2: *definition* in the text + + case 2: + // order is specified in the `idMap` already. + break; + // 3: sorted alphanumerically by label (inline footnotes will end up at the top, before all other notes) + + case 3: + case 4: + // the `idMap[]` array has not been set up and must be produced + // to turn this into an alphanumerically-by-label sort order, where + // a `footnoteId` based index will produce the order of appearance. + const reIdMap = []; + + for (let i = 1; i < footnote_spec_list.length; i++) { + reIdMap[i - 1] = i; + } + + reIdMap.sort((idA, idB) => { + const infoA = footnote_spec_list[idA]; + const infoB = footnote_spec_list[idB]; + strict.ok(infoA); + strict.ok(infoB); // is any of these an inline footnote, i.e. without any label yet? Produce a fake label for sorting then! + // + // As stated elsewhere: inline section_notes and end_notes will end up among everyone else in this sort order mode. + + strict.ok(infoA.id === idA); + strict.ok(infoB.id === idB); // Split a "sort label" up into its numerical part and the tail. Note that we don't call + // it 'tail' but 'label', because we will need to compare the ENTIRE LABEL using string comparison + // when the numeric leaders are identical, so as to ensure that 'labels' such as `00000` will sort + // as 'higher' than `000`, both of which will be rated as numerically identical! + + function to_atoms(label) { + // now extract number or numerical leader part. + // + // Only accept OBVIOUS, SIMPLE NUMERIC LEADERS! This is about *legibility* + // of those numrical leaders, not a pedantic "what is possibly legally numeric" + // challenge. Hence we DO NOT accept leading +/- and only a decimal dot when + // there's a decimal number BEFORE it, such as in `5.1hack` --> `5.1`, but NOT + // `.42oz`! + // + // Do not use `nmr = +lbl` as that would treat labels such as `0xf4` as hexadecimal numbers, + // which we DO NOT want to happen. + const m = label.match(/^\d+(?:\.\d+)?/) || ['x']; + const nmr = +m[0] || Infinity; // non-numeric labels are rated NUMEICALLY HIGHER than any numerical leader. + + return { + label, + number: nmr + }; + } + + const labelA = plugin_options.sortOrder === 3 ? infoA.labelOverride || infoA.label || '' + infoA.id : plugin_options.mkLabel(infoA.id, infoA, baseInfo); + const labelB = plugin_options.sortOrder === 3 ? infoB.labelOverride || infoB.label || '' + infoB.id : plugin_options.mkLabel(infoB.id, infoB, baseInfo); + const atomA = to_atoms(labelA); + const atomB = to_atoms(labelB); + const diff = atomA.number - atomB.number; + return diff || atomA.label.localeCompare(atomB.label); // ^^^^^^^ shorthand for: + // + // if (isNaN(diff) || diff === 0) then stringcompare else numeric-difference + }); // Now turn this into a sort order map: + + for (let prio = 0; prio < reIdMap.length; prio++) { + const id = reIdMap[prio]; + idMap[id] = prio; + } + + break; + } + + let aside_list; + let section_list = new Set(); + const section_done_list = new Set(); // once a section_note has been printed, it should never appear again! + + const end_list = new Set(); + const used_list = new Set(); + let tokens = state.tokens; + + for (i = 0; i < tokens.length; i++) { + const tok = tokens[i]; + + switch (tok.type) { + case 'footnote_mark_end_of_block': + // check the gathered list of footnotes referenced in this block: + // - dump the ones which are sidenotes + // - mark the ones which are section- or end-notes. + // + // Note: make sure we don't produce duplicates in the collect sets. + { + var _tok$meta; + + aside_list = new Set(); + const refd_notes_list = ((_tok$meta = tok.meta) == null ? void 0 : _tok$meta.footnote_list) || []; + + for (const id of refd_notes_list) { + const footnote = footnote_spec_list[id]; + + switch (footnote.mode) { + case '>': + aside_list.add(id); + used_list.add(id); + break; + + case '=': + if (!section_done_list.has(id)) { + section_list.add(id); + section_done_list.add(id); + used_list.add(id); + } + + break; + + default: + case ':': + end_list.add(id); + used_list.add(id); + break; + } + } + + const aside_ids = []; + + for (const id of aside_list.values()) { + aside_ids.push(id); + } + + aside_ids.sort(footnote_print_comparer); + place_footnote_definitions_at(state, i + 1, aside_ids, 'aside', baseInfo); + tokens = state.tokens; + } + break; + + case 'footnote_reference_close': + // anywhere a footnote *definition* appeared in the original text is + // also a place to dump the section_notes gathered to date, so to speak. + // + // However, DO detect clusters of footnote definitions and MERGE them + // together: + if (more_footnote_reference_blocks_follow_immediately(tokens, i + 1)) { + continue; + } else { + const section_ids = []; + + for (const id of section_list.values()) { + section_ids.push(id); + } + + section_ids.sort(footnote_print_comparer); + place_footnote_definitions_at(state, i + 1, section_ids, 'section', baseInfo); + tokens = state.tokens; // and reset the tracking set: + + section_list = new Set(); + } + + break; + } + } // Now process the endnotes: + + + { + const end_ids = []; + + for (const id of end_list.values()) { + end_ids.push(id); + } + + end_ids.sort(footnote_print_comparer); + place_footnote_definitions_at(state, tokens.length, end_ids, 'end', baseInfo); + tokens = state.tokens; + } // Now process the unused footnotes and dump them for diagnostic purposes: + + { + const unused_ids = []; + + for (let i = 1; i < footnote_spec_list.length; i++) { + const fn = footnote_spec_list[i]; + const id = fn.id; + + if (!used_list.has(id)) { + console.error(`ERROR: footnote ID ${id} is defined but never used. Footnote will be added as an ERRONEOUS ENDNOTE to the output, so the situation is easy to diagnose!`, Object.assign({}, fn, { + tokens: '......' + })); + unused_ids.push(id); + } + } + + unused_ids.sort(footnote_print_comparer); + place_footnote_definitions_at(state, tokens.length, unused_ids, 'Error::Unused', baseInfo); //tokens = state.tokens; + } // Update state_block too as we have rewritten & REPLACED the token array earlier in this call: + // the reference `state.env.state_block.tokens` is still pointing to the OLD token array! + + state.env.state_block.tokens = state.tokens; + } // attach ourselves to the start of block handling too + + + md.block.ruler.before('table', 'footnote_mark_end_of_block', footnote_mark_end_of_block); + md.block.ruler.before('reference', 'footnote_def', footnote_def, { + alt: ['paragraph', 'reference'] + }); + md.inline.ruler.after('image', 'footnote_inline', footnote_inline); + md.inline.ruler.after('footnote_inline', 'footnote_ref_with_text', footnote_ref_with_text); + md.inline.ruler.after('footnote_ref_with_text', 'footnote_ref', footnote_ref); + md.core.ruler.after('inline', 'footnote_tail', footnote_tail); +} + +export default footnote_plugin; +//# sourceMappingURL=markdownItFootnote.mjs.map diff --git a/dist/markdownItFootnote.mjs.map b/dist/markdownItFootnote.mjs.map new file mode 100644 index 0000000..4384afe --- /dev/null +++ b/dist/markdownItFootnote.mjs.map @@ -0,0 +1 @@ +{"version":3,"file":"markdownItFootnote.mjs","sources":["../index.ts"],"sourcesContent":["// Process footnotes\n//\n\nimport { strict as assert } from 'assert';\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Renderer partials\n\n\n\ninterface FootnotePluginOptions {\n numberSequence?: Array;\n modeOverride?: string;\n sortOrder: number;\n refCombiner?: string;\n}\n\ninterface GenericInfoParameters {\n options: any; // markdown_it options object\n plugin_options: FootnotePluginOptions;\n env: any; // markdown_it environment object\n self: any; // reference to this plugin instance\n}\n\ninterface RenderInfoParameters extends GenericInfoParameters {\n tokens: Array; // array of tokens\n idx: number; // index of current token in token array\n}\n\ninterface footnoteMetaInfo {\n id: number;\n label?: string;\n labelOverride?: string;\n mode?: string;\n content?: string;\n tokens?: Array;\n count: number;\n}\n\n\n\nfunction anchorFnDefault(n: number, excludeSubId: number, baseInfo: RenderInfoParameters) {\n const env = baseInfo.env;\n assert.ok(env != null);\n let prefix = '';\n if (typeof env.docId === 'string' && env.docId.length > 0) {\n prefix = '-' + env.docId + '-';\n }\n return prefix + n;\n}\n\nfunction captionFnDefault(n, baseInfo: RenderInfoParameters) {\n //return '[' + n + ']';\n return '' + n;\n}\n\nfunction headerFnDefault(category, baseInfo: GenericInfoParameters) {\n switch (category) {\n case 'aside':\n return 'Side Notes';\n\n case 'section':\n return 'Section Notes';\n\n case 'end':\n return 'Endnotes';\n\n default: // used for error category, e.g. 'Error::Unused'\n return category;\n }\n}\n\nfunction determine_footnote_symbol(idx: number, info: footnoteMetaInfo, baseInfo: GenericInfoParameters): string {\n const plugin_options = baseInfo.plugin_options;\n assert.ok(plugin_options != null);\n\n // rule to construct the printed label:\n //\n // mark = labelOverride /* || info.label */ || idx;\n const label = info.labelOverride;\n if (label) {\n return label;\n }\n if (plugin_options.numberSequence == null || plugin_options.numberSequence.length === 0) {\n return '' + idx;\n }\n const len = plugin_options.numberSequence.length;\n if (idx >= len) {\n // is last slot numeric or alphanumerically?\n const slot = plugin_options.numberSequence[len - 1];\n if (Number.isFinite(slot)) {\n const delta = idx - len + 1;\n return '' + (slot + delta);\n }\n\n // non-numerical last slot --> duplicate, triplicate, etc.\n const dupli = (idx / len) | 0; // = int(x mod N)\n const remainder = idx % len;\n const core = plugin_options.numberSequence[remainder];\n let str = '' + core;\n for (let i = 1; i < dupli; i++) {\n str += core;\n }\n return str;\n }\n\n return '' + plugin_options.numberSequence[idx];\n}\n\n\nconst bunched_mode_classes = [ '', 'footnote-bunched-ref-ref', 'footnote-bunched-ref-text' ];\n\n\nfunction generateFootnoteRefHtml(id, caption, refId, bunched_footnote_ref_mode, renderInfo: RenderInfoParameters) {\n let localOverride = renderInfo.tokens[renderInfo.idx].meta.text;\n if (localOverride) {\n localOverride = `${ localOverride }`;\n }\n return `${ localOverride || '' }${ caption }` +\n (bunched_footnote_ref_mode !== 0 ? `${ renderInfo.plugin_options.refCombiner || '' }` : '');\n}\n\nfunction generateFootnoteSectionStartHtml(renderInfo: RenderInfoParameters) {\n const tok = renderInfo.tokens[renderInfo.idx];\n assert.ok(tok != null);\n assert.ok(tok.meta != null);\n const header = (tok.markup ? `

    ${ tok.markup }

    ` : '');\n let category = tok.meta.category;\n assert.ok(category.length > 0);\n // `category` can contain CSS class illegal characters, e.g. when category = 'Error::Unused':\n category = category.replace(/[^a-zA-Z0-9_-]+/g, '_');\n return `
    \\n';\n}\n\nfunction generateFootnoteStartHtml(id, caption, renderInfo: RenderInfoParameters) {\n // allow both a JavaWScript --> CSS approach via `data-footnote-caption`\n // and a classic CSS approach while a display:inline-block SUP presenting\n // the LI 'button' instead:\n return `
  • ${ caption }`;\n}\n\nfunction generateFootnoteEndHtml(renderInfo: RenderInfoParameters) {\n return '
  • \\n';\n}\n\nfunction generateFootnoteBackRefHtml(id, refId, renderInfo: RenderInfoParameters) {\n const tok = renderInfo.tokens[renderInfo.idx];\n assert.ok(tok != null);\n assert.ok(tok.meta != null);\n\n /* ↩ with escape code to prevent display as Apple Emoji on iOS */\n return ` \\u21a9\\uFE0E`;\n}\n\n\n\n\n/*\nref:\n return ``;\n\n\nopen:\n return `\\n';\n}\n\n*/\n\n\n\n\ninterface FootnotePluginOptions /* extends FootnotePluginOptions */ { // eslint-disable-line no-redeclare\n anchorFn: (n: number, excludeSubId: number, baseInfo: RenderInfoParameters) => string;\n captionFn: (n: number, baseInfo: RenderInfoParameters) => string;\n headerFn: (category: string, baseInfo: GenericInfoParameters) => string;\n mkLabel: (idx: number, info: footnoteMetaInfo, baseInfo: GenericInfoParameters) => string;\n}\n\n\n\n\nconst default_plugin_options: FootnotePluginOptions = {\n // atDocumentEnd: false, -- obsoleted option of the original plugin\n\n anchorFn: anchorFnDefault,\n captionFn: captionFnDefault,\n headerFn: headerFnDefault,\n mkLabel: determine_footnote_symbol,\n\n // see also https://www.editage.com/insights/footnotes-in-tables-part-1-choice-of-footnote-markers-and-their-sequence\n // why asterisk/star is not part of the default footnote marker sequence.\n //\n // For similar reasons, we DO NOT include the section § symbol in this list.\n //\n // when numberSequnce is NULL/empty, a regular numerical numbering is assumed.\n // Otherwise, the array is indexed; when there are more footnotes than entries in\n // the numberSequence array, the entries are re-used, but doubled/trippled, etc.\n //\n // When the indexing in this array hits a NUMERIC value (as last entry), any higher\n // footnotes are NUMBERED starting at that number.\n //\n // NOTE: as we can reference the same footnote from multiple spots, we do not depend\n // on CSS counter() approaches by default, but providee this mechanism in the plugin\n // code itself.\n numberSequence: [ '†', '‡', '††', '‡‡', '¶', 1 ],\n\n // Overrides the footnode mode when set to one of the following:\n //\n // Recognized 'modes':\n // '>': aside note (default for inline notes)\n // ':': end node\n // '=': section note (default for regular referenced notes)\n //\n // Also accepts these keywords: 'aside', 'section', 'end'\n //\n modeOverride: null,\n\n // list section notes and endnotes in order of:\n //\n // 0: first *appearance* in the text\n // 1: first *reference* in the text\n // 2: *definition* in the text\n // 3: sorted alphanumerically by *coded* label,\n // i.e. *numeric* labels are sorted in numeric order (so `10` comes AFTER `7`!),\n // while all others are sorted using `String.localeCompare()`. When labels have\n // a *numeric leading*, e.g. `71geo` --> `71`, that part is sorted numerically first.\n //\n // Here 'coded label' means the label constructed from the reference ids and label overrides\n // as used in the markdown source, using the expression\n // labelOverride || reference || id\n // which gives for these examples (assuming them to be the only definitions in your input):\n // [^refA]: ... --> null || 'refA' || 1\n // [^refB LBL]: ... --> 'LBL' || 'refB' || 2\n // 4: sorted alphanumerically by *printed* label\n // which is like mode 3, but now for the label as will be seen in the *output*!\n sortOrder: 4,\n\n // what to print between bunched-together footnote references, i.e. the '+' in `blabla¹⁺²`\n refCombiner: ','\n};\n\n\n\n\nexport default function footnote_plugin(md, plugin_options) {\n const parseLinkLabel = md.helpers.parseLinkLabel,\n isSpace = md.utils.isSpace;\n\n plugin_options = Object.assign({}, default_plugin_options, plugin_options);\n\n\n\n const modeOverrideMap = {\n aside: '>',\n section: '=',\n end: ':'\n };\n\n function determine_mode(mode: string, default_mode: string) {\n let override = null;\n if (plugin_options.modeOverride) {\n const mode = modeOverrideMap[plugin_options.modeOverride] || plugin_options.modeOverride;\n if ('>:='.includes(plugin_options.modeOverride)) {\n override = plugin_options.modeOverride;\n }\n }\n if ('>:='.includes(mode)) {\n return {\n mode: override || mode,\n fromInput: true\n };\n }\n return {\n mode: override || default_mode,\n fromInput: false\n };\n }\n\n function render_footnote_n(tokens, idx, excludeSubId) {\n const mark = tokens[idx].meta.id;\n assert.ok(Number.isFinite(mark));\n assert.ok(mark > 0);\n let n = '' + mark; // = mark.toString();\n assert.ok(n.length > 0);\n\n if (!excludeSubId && tokens[idx].meta.subId > 0) {\n n += '-' + tokens[idx].meta.subId;\n }\n\n return n;\n }\n\n function render_footnote_mark(renderInfo: RenderInfoParameters): string {\n const token = renderInfo.tokens[renderInfo.idx];\n assert.ok(token != null);\n assert.ok(renderInfo.env.footnotes != null);\n assert.ok(renderInfo.env.footnotes.list != null);\n const info = renderInfo.env.footnotes.list[token.meta.id];\n assert.ok(info != null);\n const mark: string = plugin_options.mkLabel(token.meta.id, info, renderInfo);\n assert.ok(mark.length > 0);\n return mark;\n }\n\n function render_footnote_anchor_name(renderInfo: RenderInfoParameters) {\n const n = render_footnote_n(renderInfo.tokens, renderInfo.idx, true);\n return plugin_options.anchorFn(n, true, renderInfo);\n }\n\n function render_footnote_anchor_nameRef(renderInfo: RenderInfoParameters) {\n const n = render_footnote_n(renderInfo.tokens, renderInfo.idx, false);\n return plugin_options.anchorFn(n, false, renderInfo);\n }\n\n function render_footnote_caption(renderInfo: RenderInfoParameters) {\n const n = render_footnote_mark(renderInfo);\n return plugin_options.captionFn(n, renderInfo);\n }\n\n function render_footnote_ref(tokens, idx, options, env, self) {\n const renderInfo: RenderInfoParameters = {\n tokens,\n idx,\n options,\n env,\n plugin_options,\n self\n };\n const id = render_footnote_anchor_name(renderInfo);\n const caption = render_footnote_caption(renderInfo);\n const refId = render_footnote_anchor_nameRef(renderInfo);\n\n // check if multiple footnote references are bunched together:\n // IFF they are, we should separate them with commas.\n //\n // Exception: when next token has an extra text (`meta.text`) the\n // bunching together is not a problem as them the output will render\n // like this: `bla1text2`, ergo a look\n // like this: `bla¹text²` instead of bunched footnotes references ¹ and ²\n // that would (without the extra comma injection) look like `bla¹²` instead\n // of `x¹⁺²` (here '+' instead of ',' comma, but you get the idea -- there's no\n // Unicode superscript-comma so that's why I used unicode superscript-plus\n // in this 'ascii art' example).\n //\n const next_token = tokens[idx + 1] || {};\n const next_token_meta = next_token.meta || {};\n const bunched_footnote_ref_mode = (next_token.type === 'footnote_ref' ? !next_token_meta.text ? 1 : 2 : 0);\n\n return generateFootnoteRefHtml(id, caption, refId, bunched_footnote_ref_mode, renderInfo);\n }\n\n function render_footnote_block_open(tokens, idx, options, env, self) {\n const renderInfo: RenderInfoParameters = {\n tokens,\n idx,\n options,\n env,\n plugin_options,\n self\n };\n return generateFootnoteSectionStartHtml(renderInfo);\n }\n\n function render_footnote_block_close(tokens, idx, options, env, self) {\n const renderInfo: RenderInfoParameters = {\n tokens,\n idx,\n options,\n env,\n plugin_options,\n self\n };\n return generateFootnoteSectionEndHtml(renderInfo);\n }\n\n function render_footnote_reference_open(tokens, idx, options, env, self) {\n return '';\n }\n\n function render_footnote_reference_close() {\n return '';\n }\n\n function render_footnote_mark_end_of_block() {\n return '';\n }\n\n function render_footnote_open(tokens, idx, options, env, self) {\n const renderInfo: RenderInfoParameters = {\n tokens,\n idx,\n options,\n env,\n plugin_options,\n self\n };\n const id = render_footnote_anchor_name(renderInfo);\n const caption = render_footnote_caption(renderInfo);\n\n // allow both a JavaScript --> CSS approach via `data-footnote-caption`\n // and a classic CSS approach while a display:inline-block SUP presenting\n // the LI 'button' instead:\n return generateFootnoteStartHtml(id, caption, renderInfo);\n }\n\n function render_footnote_close(tokens, idx, options, env, self) {\n const renderInfo: RenderInfoParameters = {\n tokens,\n idx,\n options,\n env,\n plugin_options,\n self\n };\n return generateFootnoteEndHtml(renderInfo);\n }\n\n function render_footnote_anchor_backref(tokens, idx, options, env, self) {\n const renderInfo: RenderInfoParameters = {\n tokens,\n idx,\n options,\n env,\n plugin_options,\n self\n };\n\n const tok = tokens[idx];\n assert.ok(tok != null);\n assert.ok(tok.meta != null);\n const id = render_footnote_anchor_name(renderInfo);\n let refId = render_footnote_n(tokens, idx, false);\n refId = plugin_options.anchorFn(refId, false, renderInfo);\n\n return generateFootnoteBackRefHtml(id, refId, renderInfo);\n }\n\n\n\n md.renderer.rules.footnote_ref = render_footnote_ref;\n md.renderer.rules.footnote_block_open = render_footnote_block_open;\n md.renderer.rules.footnote_block_close = render_footnote_block_close;\n md.renderer.rules.footnote_reference_open = render_footnote_reference_open;\n md.renderer.rules.footnote_reference_close = render_footnote_reference_close;\n md.renderer.rules.footnote_mark_end_of_block = render_footnote_mark_end_of_block;\n md.renderer.rules.footnote_open = render_footnote_open;\n md.renderer.rules.footnote_close = render_footnote_close;\n md.renderer.rules.footnote_anchor = render_footnote_anchor_backref;\n\n\n\n function obtain_footnote_info_slot(env, label: string|null, at_definition: boolean) {\n // inline blocks have their own *child* environment in markdown-it v10+.\n // As the footnotes must live beyond the lifetime of the inline block env,\n // we must patch them into the `parentState.env` for the footnote_tail\n // handler to be able to access them afterwards!\n while (env.parentState) {\n env = env.parentState.env;\n assert.ok(env != null);\n }\n\n if (!env.footnotes) {\n env.footnotes = {\n // map label tto ID:\n refs: {},\n // store footnote info indexed by ID\n list: [],\n // remap ID to re-ordered ID (determines placement order for section notes and endnotes)\n idMap: [ 0 ],\n idMapCounter: 0,\n\n // and a counter for the generated sections (including asides); see the demo/test which\n // uses the generated `#fnsection-DDD` identifiers to hack/fix the styling, for example.\n sectionCounter: 0\n };\n }\n\n // When label is NULL, this is a request from in INLINE NOTE.\n\n // NOTE: IDs are index numbers, BUT they start at 1 instead of 0 to make life easier in check code:\n let footnoteId;\n let infoRec: footnoteMetaInfo;\n // label as index: prepend ':' to avoid conflict with Object.prototype members\n if (label == null || !env.footnotes.refs[':' + label]) {\n footnoteId = Math.max(1, env.footnotes.list.length);\n infoRec = {\n id: footnoteId,\n label,\n labelOverride: null,\n mode: null,\n content: null,\n tokens: null,\n count: 0\n };\n env.footnotes.list[footnoteId] = infoRec;\n if (label != null) {\n env.footnotes.refs[':' + label] = footnoteId;\n }\n } else {\n footnoteId = env.footnotes.refs[':' + label];\n infoRec = env.footnotes.list[footnoteId];\n assert.ok(!!infoRec, 'expects non-NULL footnote info record');\n }\n\n const idMap = env.footnotes.idMap;\n\n // now check if the idMap[] has been set up already as well. This depends on\n // when WE are invoked (`at_definition`) and the configured `options.sortOrder`:\n switch (plugin_options.sortOrder) {\n // 0: first *appearance* in the text\n default:\n case 0:\n // basically, this means: order as-is\n if (!idMap[footnoteId]) {\n idMap[footnoteId] = ++env.footnotes.idMapCounter;\n }\n break;\n\n // 1: first *reference* in the text\n case 1:\n if (!at_definition && !idMap[footnoteId]) {\n // first reference is now!\n idMap[footnoteId] = ++env.footnotes.idMapCounter;\n }\n break;\n\n // 2: *definition* in the text\n case 2:\n if (at_definition && !idMap[footnoteId]) {\n // definition is now!\n idMap[footnoteId] = ++env.footnotes.idMapCounter;\n }\n break;\n\n // 3: sorted alphanumerically by label (inline footnotes will end up at the top, before all other notes)\n case 3:\n case 4:\n // just note the footnoteId now; this must be re-ordered later when we have collected all footnotes.\n //\n // set it up when we get there...\n break;\n }\n\n return infoRec;\n }\n\n function find_end_of_block_marker(state, startIndex) {\n let idx, len;\n const tokens = state.tokens;\n for (idx = startIndex, len = tokens.length; idx < len; idx++) {\n if (tokens[idx].type === 'footnote_mark_end_of_block') { return idx; }\n }\n\n // Punch a slot into the token stream (at the very end)\n // for consistency with footnote_mark_end_of_block():\n const token = new state.Token('footnote_mark_end_of_block', '', 0);\n token.hidden = true;\n tokens.push(token);\n return tokens.length - 1;\n }\n\n function update_end_of_block_marker(state, footnoteId) {\n // inject marker into parent = block level token stream to announce the advent of an (inline) footnote:\n // because the markdown_it code uses a for() loop to go through the parent nodes while parsing the\n // 'inline' chunks, we CANNOT safely inject a marker BEFORE the chunk, only AFTERWARDS:\n const parentState = state.env.parentState;\n const parentIndex = state.env.parentTokenIndex;\n const markerTokenIndex = find_end_of_block_marker(parentState, parentIndex + 1);\n const token = parentState.tokens[markerTokenIndex];\n if (!token.meta) {\n token.meta = {\n footnote_list: []\n };\n }\n token.meta.footnote_list.push(footnoteId);\n }\n\n // Mark end of paragraph/heading/whatever BLOCK (or rather: START of the next block!)\n function footnote_mark_end_of_block(state, startLine, endLine, silent) {\n if (!silent && state.tokens.length > 0) {\n const token = state.push('footnote_mark_end_of_block', '', 0);\n token.hidden = true;\n }\n return false;\n }\n\n\n\n // Process footnote block definition\n function footnote_def(state, startLine, endLine, silent) {\n let oldBMark, oldTShift, oldSCount, oldParentType, pos, token,\n initial, offset, ch, posAfterColon,\n start = state.bMarks[startLine] + state.tShift[startLine],\n max = state.eMarks[startLine];\n\n // line should be at least 6 chars - \"[^x]: \" or \"[^x]:> \"\n if (start + 5 > max) { return false; }\n\n if (state.src.charCodeAt(start) !== 0x5B/* [ */) { return false; }\n if (state.src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; }\n\n for (pos = start + 2; pos < max; pos++) {\n if (state.src.charCodeAt(pos) === 0x0A /* LF */) { return false; }\n if (state.src.charCodeAt(pos) === 0x5D /* ] */) {\n break;\n }\n }\n const labelEnd = pos;\n\n if (pos === start + 2) { return false; } // no empty footnote labels\n if (pos + 1 >= max || state.src.charCodeAt(++pos) !== 0x3A /* : */) { return false; }\n\n const mode_rec = determine_mode(state.src[pos + 1], '='); // default mode is section_note mode.\n if (mode_rec.fromInput) { pos++; }\n const mode = mode_rec.mode;\n\n if (pos + 1 >= max || state.src.charCodeAt(++pos) !== 0x20 /* space */) { return false; }\n if (silent) { return true; }\n pos++;\n\n const labelInfo = decode_label(state.src.slice(start + 2, labelEnd), true);\n if (!labelInfo) { return false; }\n assert.ok(!labelInfo.extraText);\n\n // Now see if we already have a footnote ID for this footnote label:\n // fetch it if we have one and otherwise produce a new one so everyone\n // can use this from now on.\n //\n // This scenario is possible when the footnote *definition* comes BEFORE\n // the first actual footnote *use* (*reference*). This is UNUSUAL when people\n // write texts, but it is *not impossible*, particularly now that we have\n // specified-by-design that endnotes can be marked as such (`[^label]:: note text`)\n // and freely mixed with sidenotes (`[^label]:> note text`) and section\n // notes (`[^label]:= note text` (explicit mode) or `[^label]: note text`\n // (implicit mode)), where *section notes* will placed at the spot in the text\n // flow where they were *defined*. Again, highly irregular, BUT someone MAY\n // feel the need to place some section note *definitions* ABOVE their first\n // use point.\n //\n const infoRec = obtain_footnote_info_slot(state.env, labelInfo.label, true);\n if (labelInfo.labelOverride) {\n infoRec.labelOverride = labelInfo.labelOverride;\n }\n infoRec.mode = mode;\n infoRec.content = state.src.slice(pos, max);\n\n token = state.push('footnote_reference_open', '', 1);\n token.meta = {\n id: infoRec.id\n };\n token.hidden = true;\n\n oldBMark = state.bMarks[startLine];\n oldTShift = state.tShift[startLine];\n oldSCount = state.sCount[startLine];\n oldParentType = state.parentType;\n\n posAfterColon = pos;\n initial = offset = state.sCount[startLine] + pos - (state.bMarks[startLine] + state.tShift[startLine]);\n\n while (pos < max) {\n ch = state.src.charCodeAt(pos);\n\n if (isSpace(ch)) {\n if (ch === 0x09) {\n offset += 4 - offset % 4;\n } else {\n offset++;\n }\n } else {\n break;\n }\n\n pos++;\n }\n\n state.tShift[startLine] = pos - posAfterColon;\n state.sCount[startLine] = offset - initial;\n\n state.bMarks[startLine] = posAfterColon;\n state.blkIndent += 4;\n state.parentType = 'footnote';\n\n if (state.sCount[startLine] < state.blkIndent) {\n state.sCount[startLine] += state.blkIndent;\n }\n\n state.md.block.tokenize(state, startLine, endLine, true);\n\n state.parentType = oldParentType;\n state.blkIndent -= 4;\n state.tShift[startLine] = oldTShift;\n state.sCount[startLine] = oldSCount;\n state.bMarks[startLine] = oldBMark;\n\n token = state.push('footnote_reference_close', '', -1);\n token.meta = {\n id: infoRec.id\n };\n\n return true;\n }\n\n\n\n // Process inline footnotes (^[...] or ^[>...])\n function footnote_inline(state, silent) {\n let labelStart,\n labelEnd,\n token,\n tokens,\n max = state.posMax,\n start = state.pos;\n\n if (start + 2 >= max) { return false; }\n if (state.src.charCodeAt(start) !== 0x5E/* ^ */) { return false; }\n if (state.src.charCodeAt(start + 1) !== 0x5B/* [ */) { return false; }\n\n labelStart = start + 2;\n\n // NOTE: inline notes are automatically considered to be ASIDE notes,\n // UNLESS otherwise specified!\n //\n // Recognized 'modes':\n // '>': aside note (default for inline notes)\n // ':': end node\n // '=': section note (default for regular referenced notes)\n //\n // (Also note https://v4.chriskrycho.com/2015/academic-markdown-and-citations.html:\n // our notes look like this: `[^ref]:` while Academic MarkDown references look\n // like this: `[@Belawog2012]` i.e. no '^' in there. Hence these can safely co-exist.)\n //\n const mode_rec = determine_mode(state.src[start + 2], '>'); // default mode is aside ~ sidenote mode.\n if (mode_rec.fromInput) {\n labelStart++;\n }\n const mode = mode_rec.mode;\n\n labelEnd = parseLinkLabel(state, start + 1);\n\n // parser failed to find ']', so it's not a valid note\n if (labelEnd < 0) { return false; }\n\n // We found the end of the link, and know for a fact it's a valid link;\n // so all that's left to do is to call tokenizer.\n //\n if (!silent) {\n // WARNING: claim our footnote slot for there MAY be nested footnotes\n // discovered in the next inline.parse() call below!\n const infoRec = obtain_footnote_info_slot(state.env, null, true);\n infoRec.mode = mode;\n infoRec.count++;\n\n token = state.push('footnote_ref', '', 0);\n token.meta = {\n id: infoRec.id\n };\n\n state.md.inline.parse(\n state.src.slice(labelStart, labelEnd),\n state.md,\n state.env,\n tokens = []\n );\n\n // Now fill our previously claimed slot:\n infoRec.content = state.src.slice(labelStart, labelEnd);\n infoRec.tokens = tokens;\n\n // inject marker into parent = block level token stream to announce the advent of an (inline) footnote:\n // because the markdown_it code uses a for() loop to go through the parent nodes while parsing the\n // 'inline' chunks, we CANNOT safely inject a marker BEFORE the chunk, only AFTERWARDS:\n update_end_of_block_marker(state, infoRec.id);\n\n //md.block.ruler.enable('footnote_mark_end_of_block');\n }\n\n state.pos = labelEnd + 1;\n state.posMax = max;\n return true;\n }\n\n\n\n // Check if this is a valid ffootnote reference label.\n //\n // Also see if there's a label OVERRIDE text or marker ('@') provided.\n //\n // Return the parsed label record.\n function decode_label(label: string, extra_text_is_labelOverride: boolean) {\n if (!label) {\n return null;\n }\n const m = label.match(/^(@?)(\\S+)(?:\\s+(.+))?$/); // label with OPTIONAL override text...\n if (!m) {\n return null;\n }\n assert.ok(m[2].length > 0);\n let extraText = m[3]?.trim();\n // label [output] override?\n let override = null;\n if (m[1]) {\n override = m[2];\n }\n if (extra_text_is_labelOverride && extraText) {\n override = extraText;\n extraText = null;\n }\n\n return {\n label: m[2],\n labelOverride: override,\n extraText\n };\n }\n\n\n\n // Process footnote references with text ([^label ...])\n function footnote_ref_with_text(state, silent) {\n let pos,\n footnoteSubId,\n token,\n max = state.posMax,\n start = state.pos;\n\n // should be at least 6 chars - \"[^l x]\"\n if (start + 5 > max) { return false; }\n\n if (state.src.charCodeAt(start) !== 0x5B/* [ */) { return false; }\n if (state.src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; }\n\n for (pos = start + 2; pos < max; pos++) {\n if (state.src.charCodeAt(pos) === 0x0A /* linefeed */) { return false; }\n if (state.src.charCodeAt(pos) === 0x5D /* ] */) {\n break;\n }\n }\n\n if (pos === start + 2) { return false; } // no empty footnote labels\n if (pos >= max) { return false; }\n pos++;\n\n const labelInfo = decode_label(state.src.slice(start + 2, pos - 1), false);\n if (!labelInfo || !labelInfo.extraText) { return false; }\n assert.ok(labelInfo.extraText.length > 0);\n\n const infoRec = obtain_footnote_info_slot(state.env, labelInfo.label, false);\n if (labelInfo.labelOverride) {\n infoRec.labelOverride = labelInfo.labelOverride;\n }\n\n if (!silent) {\n footnoteSubId = infoRec.count;\n\n infoRec.count++;\n\n token = state.push('footnote_ref', '', 0);\n token.meta = {\n id: infoRec.id,\n subId: footnoteSubId,\n text: labelInfo.extraText\n };\n\n update_end_of_block_marker(state, infoRec.id);\n\n //md.block.ruler.enable('footnote_mark_end_of_block');\n }\n\n state.pos = pos;\n state.posMax = max;\n return true;\n }\n\n\n\n // Process footnote references ([^...])\n function footnote_ref(state, silent) {\n let pos,\n footnoteSubId,\n token,\n max = state.posMax,\n start = state.pos;\n\n // should be at least 4 chars - \"[^x]\"\n if (start + 3 > max) { return false; }\n\n if (state.src.charCodeAt(start) !== 0x5B/* [ */) { return false; }\n if (state.src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; }\n\n for (pos = start + 2; pos < max; pos++) {\n //if (state.src.charCodeAt(pos) === 0x20) { return false; }\n if (state.src.charCodeAt(pos) === 0x0A) { return false; }\n if (state.src.charCodeAt(pos) === 0x5D /* ] */) {\n break;\n }\n }\n\n if (pos === start + 2) { return false; } // no empty footnote labels\n if (pos >= max) { return false; }\n pos++;\n\n const labelInfo = decode_label(state.src.slice(start + 2, pos - 1), true);\n if (!labelInfo) { return false; }\n assert.ok(!labelInfo.extraText);\n\n const infoRec = obtain_footnote_info_slot(state.env, labelInfo.label, false);\n if (labelInfo.labelOverride) {\n infoRec.labelOverride = labelInfo.labelOverride;\n }\n\n if (!silent) {\n footnoteSubId = infoRec.count;\n\n infoRec.count++;\n\n token = state.push('footnote_ref', '', 0);\n token.meta = {\n id: infoRec.id,\n subId: footnoteSubId\n };\n\n update_end_of_block_marker(state, infoRec.id);\n\n //md.block.ruler.enable('footnote_mark_end_of_block');\n }\n\n state.pos = pos;\n state.posMax = max;\n return true;\n }\n\n\n\n function place_footnote_definitions_at(state, token_idx: number, footnote_id_list, category: string, baseInfo: GenericInfoParameters) {\n if (footnote_id_list.length === 0) {\n return; // nothing to inject...\n }\n\n let inject_tokens = [];\n assert.ok(baseInfo.env.footnotes.list != null);\n const footnote_spec_list = baseInfo.env.footnotes.list;\n\n let token = new state.Token('footnote_block_open', '', 1);\n token.markup = plugin_options.headerFn(category, baseInfo.env, plugin_options);\n token.meta = {\n sectionId: ++baseInfo.env.footnotes.sectionCounter,\n category\n };\n inject_tokens.push(token);\n\n for (const id of footnote_id_list) {\n const fn = footnote_spec_list[id];\n const inject_start_index = inject_tokens.length;\n\n token = new state.Token('footnote_open', '', 1);\n token.meta = {\n id,\n category\n };\n inject_tokens.push(token);\n\n if (fn.label == null) {\n // process an inline footnote text:\n token = new state.Token('paragraph_open', 'p', 1);\n token.block = true;\n inject_tokens.push(token);\n\n token = new state.Token('inline', '', 0);\n token.children = fn.tokens;\n token.content = fn.content;\n inject_tokens.push(token);\n\n token = new state.Token('paragraph_close', 'p', -1);\n token.block = true;\n inject_tokens.push(token);\n } else {\n // process a labeled footnote:\n inject_tokens = inject_tokens.concat(fn.tokens || []);\n }\n\n //let lastParagraph;\n //if (inject_tokens[inject_tokens.length - 1].type === 'paragraph_close') {\n // lastParagraph = inject_tokens.pop();\n //} else {\n // lastParagraph = null;\n //}\n\n const cnt = fn.count;\n assert.ok(cnt >= 0);\n for (let j = 0; j < cnt; j++) {\n token = new state.Token('footnote_anchor', '', 0);\n token.meta = {\n id,\n subId: j,\n backrefCount: cnt,\n category\n };\n inject_tokens.push(token);\n }\n\n //if (lastParagraph) {\n // inject_tokens.push(lastParagraph);\n //}\n\n token = new state.Token('footnote_close', '', -1);\n token.meta = {\n id,\n category\n };\n inject_tokens.push(token);\n }\n\n token = new state.Token('footnote_block_close', '', -1);\n token.meta = {\n category\n };\n inject_tokens.push(token);\n\n state.tokens.splice(token_idx, 0, ...inject_tokens);\n }\n\n function more_footnote_reference_blocks_follow_immediately(tokens, idx) {\n let tok = tokens[idx];\n while (tok && (tok.type === 'footnote_mark_end_of_block' || tok.type === 'footnote_reference_close')) {\n idx++;\n tok = tokens[idx];\n }\n return tok && (tok.type === 'footnote_reference_open');\n }\n\n // Glue footnote tokens into appropriate slots of token stream.\n function footnote_tail(state, startLine, endLine, silent) {\n let i, l, j, t, token, current, currentRefToken,\n insideRef = false,\n refTokens = {};\n\n if (!state.env.footnotes) {\n // no footnotes at all? --> filter out all 'footnote_mark_end_of_block' chunks:\n state.tokens = state.tokens.filter(function (tok, idx) {\n return (tok.type !== 'footnote_mark_end_of_block');\n });\n return;\n }\n\n const idMap = state.env.footnotes.idMap;\n\n const baseInfo: GenericInfoParameters = {\n options: state.md.options,\n env: state.env,\n plugin_options,\n self: this\n };\n\n function footnote_print_comparer(idA, idB) {\n return idMap[idA] - idMap[idB];\n }\n\n\n // Rewrite the tokenstream to place the aside-footnotes and section footnotes where they need to be:\n const footnote_spec_list = state.env.footnotes.list;\n\n // extract the tokens constituting the footnote/sidenote *content* and\n // store that bunch in `refTokens[:]` instead, to be injected back into\n // the tokenstream at the appropriate spots.\n state.tokens = state.tokens.filter(function (tok, idx) {\n switch (tok.type) {\n // filter out 'footnote_mark_end_of_block' tokens which follow BLOCKS that do not contain any\n // footnote/sidenote/endnote references:\n case 'footnote_mark_end_of_block':\n if (!tok.meta) return false;\n if (!tok.meta.footnote_list) return false;\n break;\n\n case 'footnote_reference_open':\n insideRef = true;\n current = [];\n currentRefToken = tok;\n return true;\n\n case 'footnote_reference_close':\n insideRef = false;\n\n const infoRec = footnote_spec_list[tok.meta.id];\n infoRec.tokens = current;\n\n return true;\n }\n if (insideRef) {\n current.push(tok);\n }\n return !insideRef;\n });\n\n\n // execute configured sorting/mapping (`idMap`):\n switch (plugin_options.sortOrder) {\n // 0: first *appearance* in the text\n default:\n case 0:\n // 1: first *reference* in the text\n case 1:\n // 2: *definition* in the text\n case 2:\n // order is specified in the `idMap` already.\n break;\n\n // 3: sorted alphanumerically by label (inline footnotes will end up at the top, before all other notes)\n case 3:\n case 4:\n // the `idMap[]` array has not been set up and must be produced\n // to turn this into an alphanumerically-by-label sort order, where\n // a `footnoteId` based index will produce the order of appearance.\n const reIdMap = [];\n for (let i = 1; i < footnote_spec_list.length; i++) {\n reIdMap[i - 1] = i;\n }\n reIdMap.sort((idA, idB) => {\n const infoA = footnote_spec_list[idA];\n const infoB = footnote_spec_list[idB];\n assert.ok(infoA);\n assert.ok(infoB);\n\n // is any of these an inline footnote, i.e. without any label yet? Produce a fake label for sorting then!\n //\n // As stated elsewhere: inline section_notes and end_notes will end up among everyone else in this sort order mode.\n assert.ok(infoA.id === idA);\n assert.ok(infoB.id === idB);\n\n // Split a \"sort label\" up into its numerical part and the tail. Note that we don't call\n // it 'tail' but 'label', because we will need to compare the ENTIRE LABEL using string comparison\n // when the numeric leaders are identical, so as to ensure that 'labels' such as `00000` will sort\n // as 'higher' than `000`, both of which will be rated as numerically identical!\n function to_atoms(label) {\n // now extract number or numerical leader part.\n //\n // Only accept OBVIOUS, SIMPLE NUMERIC LEADERS! This is about *legibility*\n // of those numrical leaders, not a pedantic \"what is possibly legally numeric\"\n // challenge. Hence we DO NOT accept leading +/- and only a decimal dot when\n // there's a decimal number BEFORE it, such as in `5.1hack` --> `5.1`, but NOT\n // `.42oz`!\n //\n // Do not use `nmr = +lbl` as that would treat labels such as `0xf4` as hexadecimal numbers,\n // which we DO NOT want to happen.\n const m = label.match(/^\\d+(?:\\.\\d+)?/) || [ 'x' ];\n const nmr = +m[0] || Infinity; // non-numeric labels are rated NUMEICALLY HIGHER than any numerical leader.\n return {\n label,\n number: nmr\n };\n }\n\n const labelA = (plugin_options.sortOrder === 3 ?\n infoA.labelOverride || infoA.label || ('' + infoA.id) :\n plugin_options.mkLabel(infoA.id, infoA, baseInfo)\n );\n const labelB = (plugin_options.sortOrder === 3 ?\n infoB.labelOverride || infoB.label || ('' + infoB.id) :\n plugin_options.mkLabel(infoB.id, infoB, baseInfo)\n );\n const atomA = to_atoms(labelA);\n const atomB = to_atoms(labelB);\n const diff = atomA.number - atomB.number;\n return diff || atomA.label.localeCompare(atomB.label);\n // ^^^^^^^ shorthand for:\n //\n // if (isNaN(diff) || diff === 0) then stringcompare else numeric-difference\n });\n\n // Now turn this into a sort order map:\n for (let prio = 0; prio < reIdMap.length; prio++) {\n const id = reIdMap[prio];\n idMap[id] = prio;\n }\n break;\n }\n\n\n const inject_tokens = [];\n\n // Now go through the token stream and place the sidenotes, section_notes and endnotes where they belong:\n let aside_list;\n let section_list = new Set();\n const section_done_list = new Set(); // once a section_note has been printed, it should never appear again!\n const end_list = new Set();\n const used_list = new Set();\n\n let tokens = state.tokens;\n\n for (i = 0; i < tokens.length; i++) {\n const tok = tokens[i];\n switch (tok.type) {\n case 'footnote_mark_end_of_block':\n // check the gathered list of footnotes referenced in this block:\n // - dump the ones which are sidenotes\n // - mark the ones which are section- or end-notes.\n //\n // Note: make sure we don't produce duplicates in the collect sets.\n {\n aside_list = new Set();\n\n const refd_notes_list = (tok.meta?.footnote_list || []);\n for (const id of refd_notes_list) {\n const footnote = footnote_spec_list[id];\n\n switch (footnote.mode) {\n case '>':\n aside_list.add(id);\n used_list.add(id);\n break;\n\n case '=':\n if (!section_done_list.has(id)) {\n section_list.add(id);\n section_done_list.add(id);\n used_list.add(id);\n }\n break;\n\n default:\n case ':':\n end_list.add(id);\n used_list.add(id);\n break;\n }\n }\n\n const aside_ids = [];\n for (const id of aside_list.values()) {\n aside_ids.push(id);\n }\n aside_ids.sort(footnote_print_comparer);\n\n place_footnote_definitions_at(state, i + 1, aside_ids, 'aside', baseInfo);\n tokens = state.tokens;\n }\n break;\n\n case 'footnote_reference_close':\n // anywhere a footnote *definition* appeared in the original text is\n // also a place to dump the section_notes gathered to date, so to speak.\n //\n // However, DO detect clusters of footnote definitions and MERGE them\n // together:\n if (more_footnote_reference_blocks_follow_immediately(tokens, i + 1)) {\n continue;\n } else {\n const section_ids = [];\n for (const id of section_list.values()) {\n section_ids.push(id);\n }\n section_ids.sort(footnote_print_comparer);\n\n place_footnote_definitions_at(state, i + 1, section_ids, 'section', baseInfo);\n tokens = state.tokens;\n\n // and reset the tracking set:\n section_list = new Set();\n }\n break;\n }\n }\n\n // Now process the endnotes:\n {\n const end_ids = [];\n for (const id of end_list.values()) {\n end_ids.push(id);\n }\n end_ids.sort(footnote_print_comparer);\n\n place_footnote_definitions_at(state, tokens.length, end_ids, 'end', baseInfo);\n tokens = state.tokens;\n }\n\n // Now process the unused footnotes and dump them for diagnostic purposes:\n {\n const unused_ids = [];\n\n for (let i = 1; i < footnote_spec_list.length; i++) {\n const fn = footnote_spec_list[i];\n const id = fn.id;\n if (!used_list.has(id)) {\n console.error(`ERROR: footnote ID ${id} is defined but never used. Footnote will be added as an ERRONEOUS ENDNOTE to the output, so the situation is easy to diagnose!`, Object.assign({}, fn, { tokens: '......' }));\n unused_ids.push(id);\n }\n }\n unused_ids.sort(footnote_print_comparer);\n\n place_footnote_definitions_at(state, tokens.length, unused_ids, 'Error::Unused', baseInfo);\n //tokens = state.tokens;\n }\n\n // Update state_block too as we have rewritten & REPLACED the token array earlier in this call:\n // the reference `state.env.state_block.tokens` is still pointing to the OLD token array!\n state.env.state_block.tokens = state.tokens;\n }\n\n\n\n\n // attach ourselves to the start of block handling too\n md.block.ruler.before('table', 'footnote_mark_end_of_block', footnote_mark_end_of_block);\n\n md.block.ruler.before('reference', 'footnote_def', footnote_def, { alt: [ 'paragraph', 'reference' ] });\n md.inline.ruler.after('image', 'footnote_inline', footnote_inline);\n md.inline.ruler.after('footnote_inline', 'footnote_ref_with_text', footnote_ref_with_text);\n md.inline.ruler.after('footnote_ref_with_text', 'footnote_ref', footnote_ref);\n md.core.ruler.after('inline', 'footnote_tail', footnote_tail);\n}\n"],"names":["anchorFnDefault","n","excludeSubId","baseInfo","env","assert","ok","prefix","docId","length","captionFnDefault","headerFnDefault","category","determine_footnote_symbol","idx","info","plugin_options","label","labelOverride","numberSequence","len","slot","Number","isFinite","delta","dupli","remainder","core","str","i","bunched_mode_classes","generateFootnoteRefHtml","id","caption","refId","bunched_footnote_ref_mode","renderInfo","localOverride","tokens","meta","text","refCombiner","generateFootnoteSectionStartHtml","tok","header","markup","replace","sectionId","options","xhtmlOut","generateFootnoteSectionEndHtml","generateFootnoteStartHtml","generateFootnoteEndHtml","generateFootnoteBackRefHtml","subId","backrefCount","default_plugin_options","anchorFn","captionFn","headerFn","mkLabel","modeOverride","sortOrder","footnote_plugin","md","parseLinkLabel","helpers","isSpace","utils","Object","assign","determine_mode","mode","default_mode","override","includes","fromInput","render_footnote_n","mark","render_footnote_mark","token","footnotes","list","render_footnote_anchor_name","render_footnote_anchor_nameRef","render_footnote_caption","render_footnote_ref","self","next_token","next_token_meta","type","render_footnote_block_open","render_footnote_block_close","render_footnote_reference_open","render_footnote_reference_close","render_footnote_mark_end_of_block","render_footnote_open","render_footnote_close","render_footnote_anchor_backref","renderer","rules","footnote_ref","footnote_block_open","footnote_block_close","footnote_reference_open","footnote_reference_close","footnote_mark_end_of_block","footnote_open","footnote_close","footnote_anchor","obtain_footnote_info_slot","at_definition","parentState","refs","idMap","idMapCounter","sectionCounter","footnoteId","infoRec","Math","max","content","count","find_end_of_block_marker","state","startIndex","Token","hidden","push","update_end_of_block_marker","parentIndex","parentTokenIndex","markerTokenIndex","footnote_list","startLine","endLine","silent","footnote_def","oldBMark","oldTShift","oldSCount","oldParentType","pos","initial","offset","ch","posAfterColon","start","bMarks","tShift","eMarks","src","charCodeAt","labelEnd","mode_rec","labelInfo","decode_label","slice","extraText","sCount","parentType","blkIndent","block","tokenize","footnote_inline","labelStart","posMax","inline","parse","extra_text_is_labelOverride","m","match","trim","footnote_ref_with_text","footnoteSubId","place_footnote_definitions_at","token_idx","footnote_id_list","inject_tokens","footnote_spec_list","fn","children","concat","cnt","j","splice","more_footnote_reference_blocks_follow_immediately","footnote_tail","current","insideRef","filter","footnote_print_comparer","idA","idB","reIdMap","sort","infoA","infoB","to_atoms","nmr","Infinity","number","labelA","labelB","atomA","atomB","diff","localeCompare","prio","aside_list","section_list","Set","section_done_list","end_list","used_list","refd_notes_list","footnote","add","has","aside_ids","values","section_ids","end_ids","unused_ids","console","error","state_block","ruler","before","alt","after"],"mappings":"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"} \ No newline at end of file diff --git a/dist/markdownItFootnote.js b/dist/markdownItFootnote.modern.js similarity index 100% rename from dist/markdownItFootnote.js rename to dist/markdownItFootnote.modern.js diff --git a/dist/markdownItFootnote.js.map b/dist/markdownItFootnote.modern.js.map similarity index 100% rename from dist/markdownItFootnote.js.map rename to dist/markdownItFootnote.modern.js.map diff --git a/dist/markdownItFootnote.umd.js b/dist/markdownItFootnote.umd.js new file mode 100644 index 0000000..e8ce0a7 --- /dev/null +++ b/dist/markdownItFootnote.umd.js @@ -0,0 +1,1304 @@ +/*! markdown-it-footnote 3.0.3-10 https://github.com//GerHobbelt/markdown-it-footnote @license MIT */ + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('assert')) : + typeof define === 'function' && define.amd ? define(['assert'], factory) : + (global = global || self, global.markdownitFootnote = factory(global.assert)); +}(this, (function (assert) { 'use strict'; + + // Process footnotes + + function anchorFnDefault(n, excludeSubId, baseInfo) { + const env = baseInfo.env; + assert.strict.ok(env != null); + let prefix = ''; + + if (typeof env.docId === 'string' && env.docId.length > 0) { + prefix = '-' + env.docId + '-'; + } + + return prefix + n; + } + + function captionFnDefault(n, baseInfo) { + //return '[' + n + ']'; + return '' + n; + } + + function headerFnDefault(category, baseInfo) { + switch (category) { + case 'aside': + return 'Side Notes'; + + case 'section': + return 'Section Notes'; + + case 'end': + return 'Endnotes'; + + default: + // used for error category, e.g. 'Error::Unused' + return category; + } + } + + function determine_footnote_symbol(idx, info, baseInfo) { + const plugin_options = baseInfo.plugin_options; + assert.strict.ok(plugin_options != null); // rule to construct the printed label: + // + // mark = labelOverride /* || info.label */ || idx; + + const label = info.labelOverride; + + if (label) { + return label; + } + + if (plugin_options.numberSequence == null || plugin_options.numberSequence.length === 0) { + return '' + idx; + } + + const len = plugin_options.numberSequence.length; + + if (idx >= len) { + // is last slot numeric or alphanumerically? + const slot = plugin_options.numberSequence[len - 1]; + + if (Number.isFinite(slot)) { + const delta = idx - len + 1; + return '' + (slot + delta); + } // non-numerical last slot --> duplicate, triplicate, etc. + + + const dupli = idx / len | 0; // = int(x mod N) + + const remainder = idx % len; + const core = plugin_options.numberSequence[remainder]; + let str = '' + core; + + for (let i = 1; i < dupli; i++) { + str += core; + } + + return str; + } + + return '' + plugin_options.numberSequence[idx]; + } + + const bunched_mode_classes = ['', 'footnote-bunched-ref-ref', 'footnote-bunched-ref-text']; + + function generateFootnoteRefHtml(id, caption, refId, bunched_footnote_ref_mode, renderInfo) { + let localOverride = renderInfo.tokens[renderInfo.idx].meta.text; + + if (localOverride) { + localOverride = `${localOverride}`; + } + + return `${localOverride || ''}${caption}` + (bunched_footnote_ref_mode !== 0 ? `${renderInfo.plugin_options.refCombiner || ''}` : ''); + } + + function generateFootnoteSectionStartHtml(renderInfo) { + const tok = renderInfo.tokens[renderInfo.idx]; + assert.strict.ok(tok != null); + assert.strict.ok(tok.meta != null); + const header = tok.markup ? `

    ${tok.markup}

    ` : ''; + let category = tok.meta.category; + assert.strict.ok(category.length > 0); // `category` can contain CSS class illegal characters, e.g. when category = 'Error::Unused': + + category = category.replace(/[^a-zA-Z0-9_-]+/g, '_'); + return `
    \n'; + } + + function generateFootnoteStartHtml(id, caption, renderInfo) { + // allow both a JavaWScript --> CSS approach via `data-footnote-caption` + // and a classic CSS approach while a display:inline-block SUP presenting + // the LI 'button' instead: + return `
  • ${caption}`; + } + + function generateFootnoteEndHtml(renderInfo) { + return '
  • \n'; + } + + function generateFootnoteBackRefHtml(id, refId, renderInfo) { + const tok = renderInfo.tokens[renderInfo.idx]; + assert.strict.ok(tok != null); + assert.strict.ok(tok.meta != null); + /* ↩ with escape code to prevent display as Apple Emoji on iOS */ + + return ` \u21a9\uFE0E`; + } + + const default_plugin_options = { + // atDocumentEnd: false, -- obsoleted option of the original plugin + anchorFn: anchorFnDefault, + captionFn: captionFnDefault, + headerFn: headerFnDefault, + mkLabel: determine_footnote_symbol, + // see also https://www.editage.com/insights/footnotes-in-tables-part-1-choice-of-footnote-markers-and-their-sequence + // why asterisk/star is not part of the default footnote marker sequence. + // + // For similar reasons, we DO NOT include the section § symbol in this list. + // + // when numberSequnce is NULL/empty, a regular numerical numbering is assumed. + // Otherwise, the array is indexed; when there are more footnotes than entries in + // the numberSequence array, the entries are re-used, but doubled/trippled, etc. + // + // When the indexing in this array hits a NUMERIC value (as last entry), any higher + // footnotes are NUMBERED starting at that number. + // + // NOTE: as we can reference the same footnote from multiple spots, we do not depend + // on CSS counter() approaches by default, but providee this mechanism in the plugin + // code itself. + numberSequence: ['†', '‡', '††', '‡‡', '¶', 1], + // Overrides the footnode mode when set to one of the following: + // + // Recognized 'modes': + // '>': aside note (default for inline notes) + // ':': end node + // '=': section note (default for regular referenced notes) + // + // Also accepts these keywords: 'aside', 'section', 'end' + // + modeOverride: null, + // list section notes and endnotes in order of: + // + // 0: first *appearance* in the text + // 1: first *reference* in the text + // 2: *definition* in the text + // 3: sorted alphanumerically by *coded* label, + // i.e. *numeric* labels are sorted in numeric order (so `10` comes AFTER `7`!), + // while all others are sorted using `String.localeCompare()`. When labels have + // a *numeric leading*, e.g. `71geo` --> `71`, that part is sorted numerically first. + // + // Here 'coded label' means the label constructed from the reference ids and label overrides + // as used in the markdown source, using the expression + // labelOverride || reference || id + // which gives for these examples (assuming them to be the only definitions in your input): + // [^refA]: ... --> null || 'refA' || 1 + // [^refB LBL]: ... --> 'LBL' || 'refB' || 2 + // 4: sorted alphanumerically by *printed* label + // which is like mode 3, but now for the label as will be seen in the *output*! + sortOrder: 4, + // what to print between bunched-together footnote references, i.e. the '+' in `blabla¹⁺²` + refCombiner: ',' + }; + function footnote_plugin(md, plugin_options) { + const parseLinkLabel = md.helpers.parseLinkLabel, + isSpace = md.utils.isSpace; + plugin_options = Object.assign({}, default_plugin_options, plugin_options); + + function determine_mode(mode, default_mode) { + let override = null; + + if (plugin_options.modeOverride) { + + if ('>:='.includes(plugin_options.modeOverride)) { + override = plugin_options.modeOverride; + } + } + + if ('>:='.includes(mode)) { + return { + mode: override || mode, + fromInput: true + }; + } + + return { + mode: override || default_mode, + fromInput: false + }; + } + + function render_footnote_n(tokens, idx, excludeSubId) { + const mark = tokens[idx].meta.id; + assert.strict.ok(Number.isFinite(mark)); + assert.strict.ok(mark > 0); + let n = '' + mark; // = mark.toString(); + + assert.strict.ok(n.length > 0); + + if (!excludeSubId && tokens[idx].meta.subId > 0) { + n += '-' + tokens[idx].meta.subId; + } + + return n; + } + + function render_footnote_mark(renderInfo) { + const token = renderInfo.tokens[renderInfo.idx]; + assert.strict.ok(token != null); + assert.strict.ok(renderInfo.env.footnotes != null); + assert.strict.ok(renderInfo.env.footnotes.list != null); + const info = renderInfo.env.footnotes.list[token.meta.id]; + assert.strict.ok(info != null); + const mark = plugin_options.mkLabel(token.meta.id, info, renderInfo); + assert.strict.ok(mark.length > 0); + return mark; + } + + function render_footnote_anchor_name(renderInfo) { + const n = render_footnote_n(renderInfo.tokens, renderInfo.idx, true); + return plugin_options.anchorFn(n, true, renderInfo); + } + + function render_footnote_anchor_nameRef(renderInfo) { + const n = render_footnote_n(renderInfo.tokens, renderInfo.idx, false); + return plugin_options.anchorFn(n, false, renderInfo); + } + + function render_footnote_caption(renderInfo) { + const n = render_footnote_mark(renderInfo); + return plugin_options.captionFn(n, renderInfo); + } + + function render_footnote_ref(tokens, idx, options, env, self) { + const renderInfo = { + tokens, + idx, + options, + env, + plugin_options, + self + }; + const id = render_footnote_anchor_name(renderInfo); + const caption = render_footnote_caption(renderInfo); + const refId = render_footnote_anchor_nameRef(renderInfo); // check if multiple footnote references are bunched together: + // IFF they are, we should separate them with commas. + // + // Exception: when next token has an extra text (`meta.text`) the + // bunching together is not a problem as them the output will render + // like this: `bla1text2`, ergo a look + // like this: `bla¹text²` instead of bunched footnotes references ¹ and ² + // that would (without the extra comma injection) look like `bla¹²` instead + // of `x¹⁺²` (here '+' instead of ',' comma, but you get the idea -- there's no + // Unicode superscript-comma so that's why I used unicode superscript-plus + // in this 'ascii art' example). + // + + const next_token = tokens[idx + 1] || {}; + const next_token_meta = next_token.meta || {}; + const bunched_footnote_ref_mode = next_token.type === 'footnote_ref' ? !next_token_meta.text ? 1 : 2 : 0; + return generateFootnoteRefHtml(id, caption, refId, bunched_footnote_ref_mode, renderInfo); + } + + function render_footnote_block_open(tokens, idx, options, env, self) { + const renderInfo = { + tokens, + idx, + options, + env, + plugin_options, + self + }; + return generateFootnoteSectionStartHtml(renderInfo); + } + + function render_footnote_block_close(tokens, idx, options, env, self) { + return generateFootnoteSectionEndHtml(); + } + + function render_footnote_reference_open(tokens, idx, options, env, self) { + return ''; + } + + function render_footnote_reference_close() { + return ''; + } + + function render_footnote_mark_end_of_block() { + return ''; + } + + function render_footnote_open(tokens, idx, options, env, self) { + const renderInfo = { + tokens, + idx, + options, + env, + plugin_options, + self + }; + const id = render_footnote_anchor_name(renderInfo); + const caption = render_footnote_caption(renderInfo); // allow both a JavaScript --> CSS approach via `data-footnote-caption` + // and a classic CSS approach while a display:inline-block SUP presenting + // the LI 'button' instead: + + return generateFootnoteStartHtml(id, caption); + } + + function render_footnote_close(tokens, idx, options, env, self) { + return generateFootnoteEndHtml(); + } + + function render_footnote_anchor_backref(tokens, idx, options, env, self) { + const renderInfo = { + tokens, + idx, + options, + env, + plugin_options, + self + }; + const tok = tokens[idx]; + assert.strict.ok(tok != null); + assert.strict.ok(tok.meta != null); + const id = render_footnote_anchor_name(renderInfo); + let refId = render_footnote_n(tokens, idx, false); + refId = plugin_options.anchorFn(refId, false, renderInfo); + return generateFootnoteBackRefHtml(id, refId, renderInfo); + } + + md.renderer.rules.footnote_ref = render_footnote_ref; + md.renderer.rules.footnote_block_open = render_footnote_block_open; + md.renderer.rules.footnote_block_close = render_footnote_block_close; + md.renderer.rules.footnote_reference_open = render_footnote_reference_open; + md.renderer.rules.footnote_reference_close = render_footnote_reference_close; + md.renderer.rules.footnote_mark_end_of_block = render_footnote_mark_end_of_block; + md.renderer.rules.footnote_open = render_footnote_open; + md.renderer.rules.footnote_close = render_footnote_close; + md.renderer.rules.footnote_anchor = render_footnote_anchor_backref; + + function obtain_footnote_info_slot(env, label, at_definition) { + // inline blocks have their own *child* environment in markdown-it v10+. + // As the footnotes must live beyond the lifetime of the inline block env, + // we must patch them into the `parentState.env` for the footnote_tail + // handler to be able to access them afterwards! + while (env.parentState) { + env = env.parentState.env; + assert.strict.ok(env != null); + } + + if (!env.footnotes) { + env.footnotes = { + // map label tto ID: + refs: {}, + // store footnote info indexed by ID + list: [], + // remap ID to re-ordered ID (determines placement order for section notes and endnotes) + idMap: [0], + idMapCounter: 0, + // and a counter for the generated sections (including asides); see the demo/test which + // uses the generated `#fnsection-DDD` identifiers to hack/fix the styling, for example. + sectionCounter: 0 + }; + } // When label is NULL, this is a request from in INLINE NOTE. + // NOTE: IDs are index numbers, BUT they start at 1 instead of 0 to make life easier in check code: + + + let footnoteId; + let infoRec; // label as index: prepend ':' to avoid conflict with Object.prototype members + + if (label == null || !env.footnotes.refs[':' + label]) { + footnoteId = Math.max(1, env.footnotes.list.length); + infoRec = { + id: footnoteId, + label, + labelOverride: null, + mode: null, + content: null, + tokens: null, + count: 0 + }; + env.footnotes.list[footnoteId] = infoRec; + + if (label != null) { + env.footnotes.refs[':' + label] = footnoteId; + } + } else { + footnoteId = env.footnotes.refs[':' + label]; + infoRec = env.footnotes.list[footnoteId]; + assert.strict.ok(!!infoRec, 'expects non-NULL footnote info record'); + } + + const idMap = env.footnotes.idMap; // now check if the idMap[] has been set up already as well. This depends on + // when WE are invoked (`at_definition`) and the configured `options.sortOrder`: + + switch (plugin_options.sortOrder) { + // 0: first *appearance* in the text + default: + case 0: + // basically, this means: order as-is + if (!idMap[footnoteId]) { + idMap[footnoteId] = ++env.footnotes.idMapCounter; + } + + break; + // 1: first *reference* in the text + + case 1: + if (!at_definition && !idMap[footnoteId]) { + // first reference is now! + idMap[footnoteId] = ++env.footnotes.idMapCounter; + } + + break; + // 2: *definition* in the text + + case 2: + if (at_definition && !idMap[footnoteId]) { + // definition is now! + idMap[footnoteId] = ++env.footnotes.idMapCounter; + } + + break; + // 3: sorted alphanumerically by label (inline footnotes will end up at the top, before all other notes) + + case 3: + case 4: + // just note the footnoteId now; this must be re-ordered later when we have collected all footnotes. + // + // set it up when we get there... + break; + } + + return infoRec; + } + + function find_end_of_block_marker(state, startIndex) { + let idx, len; + const tokens = state.tokens; + + for (idx = startIndex, len = tokens.length; idx < len; idx++) { + if (tokens[idx].type === 'footnote_mark_end_of_block') { + return idx; + } + } // Punch a slot into the token stream (at the very end) + // for consistency with footnote_mark_end_of_block(): + + + const token = new state.Token('footnote_mark_end_of_block', '', 0); + token.hidden = true; + tokens.push(token); + return tokens.length - 1; + } + + function update_end_of_block_marker(state, footnoteId) { + // inject marker into parent = block level token stream to announce the advent of an (inline) footnote: + // because the markdown_it code uses a for() loop to go through the parent nodes while parsing the + // 'inline' chunks, we CANNOT safely inject a marker BEFORE the chunk, only AFTERWARDS: + const parentState = state.env.parentState; + const parentIndex = state.env.parentTokenIndex; + const markerTokenIndex = find_end_of_block_marker(parentState, parentIndex + 1); + const token = parentState.tokens[markerTokenIndex]; + + if (!token.meta) { + token.meta = { + footnote_list: [] + }; + } + + token.meta.footnote_list.push(footnoteId); + } // Mark end of paragraph/heading/whatever BLOCK (or rather: START of the next block!) + + + function footnote_mark_end_of_block(state, startLine, endLine, silent) { + if (!silent && state.tokens.length > 0) { + const token = state.push('footnote_mark_end_of_block', '', 0); + token.hidden = true; + } + + return false; + } // Process footnote block definition + + + function footnote_def(state, startLine, endLine, silent) { + let oldBMark, + oldTShift, + oldSCount, + oldParentType, + pos, + token, + initial, + offset, + ch, + posAfterColon, + start = state.bMarks[startLine] + state.tShift[startLine], + max = state.eMarks[startLine]; // line should be at least 6 chars - "[^x]: " or "[^x]:> " + + if (start + 5 > max) { + return false; + } + + if (state.src.charCodeAt(start) !== 0x5B + /* [ */ + ) { + return false; + } + + if (state.src.charCodeAt(start + 1) !== 0x5E + /* ^ */ + ) { + return false; + } + + for (pos = start + 2; pos < max; pos++) { + if (state.src.charCodeAt(pos) === 0x0A + /* LF */ + ) { + return false; + } + + if (state.src.charCodeAt(pos) === 0x5D + /* ] */ + ) { + break; + } + } + + const labelEnd = pos; + + if (pos === start + 2) { + return false; + } // no empty footnote labels + + + if (pos + 1 >= max || state.src.charCodeAt(++pos) !== 0x3A + /* : */ + ) { + return false; + } + + const mode_rec = determine_mode(state.src[pos + 1], '='); // default mode is section_note mode. + + if (mode_rec.fromInput) { + pos++; + } + + const mode = mode_rec.mode; + + if (pos + 1 >= max || state.src.charCodeAt(++pos) !== 0x20 + /* space */ + ) { + return false; + } + + if (silent) { + return true; + } + + pos++; + const labelInfo = decode_label(state.src.slice(start + 2, labelEnd), true); + + if (!labelInfo) { + return false; + } + + assert.strict.ok(!labelInfo.extraText); // Now see if we already have a footnote ID for this footnote label: + // fetch it if we have one and otherwise produce a new one so everyone + // can use this from now on. + // + // This scenario is possible when the footnote *definition* comes BEFORE + // the first actual footnote *use* (*reference*). This is UNUSUAL when people + // write texts, but it is *not impossible*, particularly now that we have + // specified-by-design that endnotes can be marked as such (`[^label]:: note text`) + // and freely mixed with sidenotes (`[^label]:> note text`) and section + // notes (`[^label]:= note text` (explicit mode) or `[^label]: note text` + // (implicit mode)), where *section notes* will placed at the spot in the text + // flow where they were *defined*. Again, highly irregular, BUT someone MAY + // feel the need to place some section note *definitions* ABOVE their first + // use point. + // + + const infoRec = obtain_footnote_info_slot(state.env, labelInfo.label, true); + + if (labelInfo.labelOverride) { + infoRec.labelOverride = labelInfo.labelOverride; + } + + infoRec.mode = mode; + infoRec.content = state.src.slice(pos, max); + token = state.push('footnote_reference_open', '', 1); + token.meta = { + id: infoRec.id + }; + token.hidden = true; + oldBMark = state.bMarks[startLine]; + oldTShift = state.tShift[startLine]; + oldSCount = state.sCount[startLine]; + oldParentType = state.parentType; + posAfterColon = pos; + initial = offset = state.sCount[startLine] + pos - (state.bMarks[startLine] + state.tShift[startLine]); + + while (pos < max) { + ch = state.src.charCodeAt(pos); + + if (isSpace(ch)) { + if (ch === 0x09) { + offset += 4 - offset % 4; + } else { + offset++; + } + } else { + break; + } + + pos++; + } + + state.tShift[startLine] = pos - posAfterColon; + state.sCount[startLine] = offset - initial; + state.bMarks[startLine] = posAfterColon; + state.blkIndent += 4; + state.parentType = 'footnote'; + + if (state.sCount[startLine] < state.blkIndent) { + state.sCount[startLine] += state.blkIndent; + } + + state.md.block.tokenize(state, startLine, endLine, true); + state.parentType = oldParentType; + state.blkIndent -= 4; + state.tShift[startLine] = oldTShift; + state.sCount[startLine] = oldSCount; + state.bMarks[startLine] = oldBMark; + token = state.push('footnote_reference_close', '', -1); + token.meta = { + id: infoRec.id + }; + return true; + } // Process inline footnotes (^[...] or ^[>...]) + + + function footnote_inline(state, silent) { + let labelStart, + labelEnd, + token, + tokens, + max = state.posMax, + start = state.pos; + + if (start + 2 >= max) { + return false; + } + + if (state.src.charCodeAt(start) !== 0x5E + /* ^ */ + ) { + return false; + } + + if (state.src.charCodeAt(start + 1) !== 0x5B + /* [ */ + ) { + return false; + } + + labelStart = start + 2; // NOTE: inline notes are automatically considered to be ASIDE notes, + // UNLESS otherwise specified! + // + // Recognized 'modes': + // '>': aside note (default for inline notes) + // ':': end node + // '=': section note (default for regular referenced notes) + // + // (Also note https://v4.chriskrycho.com/2015/academic-markdown-and-citations.html: + // our notes look like this: `[^ref]:` while Academic MarkDown references look + // like this: `[@Belawog2012]` i.e. no '^' in there. Hence these can safely co-exist.) + // + + const mode_rec = determine_mode(state.src[start + 2], '>'); // default mode is aside ~ sidenote mode. + + if (mode_rec.fromInput) { + labelStart++; + } + + const mode = mode_rec.mode; + labelEnd = parseLinkLabel(state, start + 1); // parser failed to find ']', so it's not a valid note + + if (labelEnd < 0) { + return false; + } // We found the end of the link, and know for a fact it's a valid link; + // so all that's left to do is to call tokenizer. + // + + + if (!silent) { + // WARNING: claim our footnote slot for there MAY be nested footnotes + // discovered in the next inline.parse() call below! + const infoRec = obtain_footnote_info_slot(state.env, null, true); + infoRec.mode = mode; + infoRec.count++; + token = state.push('footnote_ref', '', 0); + token.meta = { + id: infoRec.id + }; + state.md.inline.parse(state.src.slice(labelStart, labelEnd), state.md, state.env, tokens = []); // Now fill our previously claimed slot: + + infoRec.content = state.src.slice(labelStart, labelEnd); + infoRec.tokens = tokens; // inject marker into parent = block level token stream to announce the advent of an (inline) footnote: + // because the markdown_it code uses a for() loop to go through the parent nodes while parsing the + // 'inline' chunks, we CANNOT safely inject a marker BEFORE the chunk, only AFTERWARDS: + + update_end_of_block_marker(state, infoRec.id); //md.block.ruler.enable('footnote_mark_end_of_block'); + } + + state.pos = labelEnd + 1; + state.posMax = max; + return true; + } // Check if this is a valid ffootnote reference label. + // + // Also see if there's a label OVERRIDE text or marker ('@') provided. + // + // Return the parsed label record. + + + function decode_label(label, extra_text_is_labelOverride) { + var _m$; + + if (!label) { + return null; + } + + const m = label.match(/^(@?)(\S+)(?:\s+(.+))?$/); // label with OPTIONAL override text... + + if (!m) { + return null; + } + + assert.strict.ok(m[2].length > 0); + let extraText = (_m$ = m[3]) == null ? void 0 : _m$.trim(); // label [output] override? + + let override = null; + + if (m[1]) { + override = m[2]; + } + + if (extra_text_is_labelOverride && extraText) { + override = extraText; + extraText = null; + } + + return { + label: m[2], + labelOverride: override, + extraText + }; + } // Process footnote references with text ([^label ...]) + + + function footnote_ref_with_text(state, silent) { + let pos, + footnoteSubId, + token, + max = state.posMax, + start = state.pos; // should be at least 6 chars - "[^l x]" + + if (start + 5 > max) { + return false; + } + + if (state.src.charCodeAt(start) !== 0x5B + /* [ */ + ) { + return false; + } + + if (state.src.charCodeAt(start + 1) !== 0x5E + /* ^ */ + ) { + return false; + } + + for (pos = start + 2; pos < max; pos++) { + if (state.src.charCodeAt(pos) === 0x0A + /* linefeed */ + ) { + return false; + } + + if (state.src.charCodeAt(pos) === 0x5D + /* ] */ + ) { + break; + } + } + + if (pos === start + 2) { + return false; + } // no empty footnote labels + + + if (pos >= max) { + return false; + } + + pos++; + const labelInfo = decode_label(state.src.slice(start + 2, pos - 1), false); + + if (!labelInfo || !labelInfo.extraText) { + return false; + } + + assert.strict.ok(labelInfo.extraText.length > 0); + const infoRec = obtain_footnote_info_slot(state.env, labelInfo.label, false); + + if (labelInfo.labelOverride) { + infoRec.labelOverride = labelInfo.labelOverride; + } + + if (!silent) { + footnoteSubId = infoRec.count; + infoRec.count++; + token = state.push('footnote_ref', '', 0); + token.meta = { + id: infoRec.id, + subId: footnoteSubId, + text: labelInfo.extraText + }; + update_end_of_block_marker(state, infoRec.id); //md.block.ruler.enable('footnote_mark_end_of_block'); + } + + state.pos = pos; + state.posMax = max; + return true; + } // Process footnote references ([^...]) + + + function footnote_ref(state, silent) { + let pos, + footnoteSubId, + token, + max = state.posMax, + start = state.pos; // should be at least 4 chars - "[^x]" + + if (start + 3 > max) { + return false; + } + + if (state.src.charCodeAt(start) !== 0x5B + /* [ */ + ) { + return false; + } + + if (state.src.charCodeAt(start + 1) !== 0x5E + /* ^ */ + ) { + return false; + } + + for (pos = start + 2; pos < max; pos++) { + //if (state.src.charCodeAt(pos) === 0x20) { return false; } + if (state.src.charCodeAt(pos) === 0x0A) { + return false; + } + + if (state.src.charCodeAt(pos) === 0x5D + /* ] */ + ) { + break; + } + } + + if (pos === start + 2) { + return false; + } // no empty footnote labels + + + if (pos >= max) { + return false; + } + + pos++; + const labelInfo = decode_label(state.src.slice(start + 2, pos - 1), true); + + if (!labelInfo) { + return false; + } + + assert.strict.ok(!labelInfo.extraText); + const infoRec = obtain_footnote_info_slot(state.env, labelInfo.label, false); + + if (labelInfo.labelOverride) { + infoRec.labelOverride = labelInfo.labelOverride; + } + + if (!silent) { + footnoteSubId = infoRec.count; + infoRec.count++; + token = state.push('footnote_ref', '', 0); + token.meta = { + id: infoRec.id, + subId: footnoteSubId + }; + update_end_of_block_marker(state, infoRec.id); //md.block.ruler.enable('footnote_mark_end_of_block'); + } + + state.pos = pos; + state.posMax = max; + return true; + } + + function place_footnote_definitions_at(state, token_idx, footnote_id_list, category, baseInfo) { + if (footnote_id_list.length === 0) { + return; // nothing to inject... + } + + let inject_tokens = []; + assert.strict.ok(baseInfo.env.footnotes.list != null); + const footnote_spec_list = baseInfo.env.footnotes.list; + let token = new state.Token('footnote_block_open', '', 1); + token.markup = plugin_options.headerFn(category, baseInfo.env, plugin_options); + token.meta = { + sectionId: ++baseInfo.env.footnotes.sectionCounter, + category + }; + inject_tokens.push(token); + + for (const id of footnote_id_list) { + const fn = footnote_spec_list[id]; + token = new state.Token('footnote_open', '', 1); + token.meta = { + id, + category + }; + inject_tokens.push(token); + + if (fn.label == null) { + // process an inline footnote text: + token = new state.Token('paragraph_open', 'p', 1); + token.block = true; + inject_tokens.push(token); + token = new state.Token('inline', '', 0); + token.children = fn.tokens; + token.content = fn.content; + inject_tokens.push(token); + token = new state.Token('paragraph_close', 'p', -1); + token.block = true; + inject_tokens.push(token); + } else { + // process a labeled footnote: + inject_tokens = inject_tokens.concat(fn.tokens || []); + } //let lastParagraph; + //if (inject_tokens[inject_tokens.length - 1].type === 'paragraph_close') { + // lastParagraph = inject_tokens.pop(); + //} else { + // lastParagraph = null; + //} + + + const cnt = fn.count; + assert.strict.ok(cnt >= 0); + + for (let j = 0; j < cnt; j++) { + token = new state.Token('footnote_anchor', '', 0); + token.meta = { + id, + subId: j, + backrefCount: cnt, + category + }; + inject_tokens.push(token); + } //if (lastParagraph) { + // inject_tokens.push(lastParagraph); + //} + + + token = new state.Token('footnote_close', '', -1); + token.meta = { + id, + category + }; + inject_tokens.push(token); + } + + token = new state.Token('footnote_block_close', '', -1); + token.meta = { + category + }; + inject_tokens.push(token); + state.tokens.splice(token_idx, 0, ...inject_tokens); + } + + function more_footnote_reference_blocks_follow_immediately(tokens, idx) { + let tok = tokens[idx]; + + while (tok && (tok.type === 'footnote_mark_end_of_block' || tok.type === 'footnote_reference_close')) { + idx++; + tok = tokens[idx]; + } + + return tok && tok.type === 'footnote_reference_open'; + } // Glue footnote tokens into appropriate slots of token stream. + + + function footnote_tail(state, startLine, endLine, silent) { + let i, + current, + insideRef = false; + + if (!state.env.footnotes) { + // no footnotes at all? --> filter out all 'footnote_mark_end_of_block' chunks: + state.tokens = state.tokens.filter(function (tok, idx) { + return tok.type !== 'footnote_mark_end_of_block'; + }); + return; + } + + const idMap = state.env.footnotes.idMap; + const baseInfo = { + options: state.md.options, + env: state.env, + plugin_options, + self: this + }; + + function footnote_print_comparer(idA, idB) { + return idMap[idA] - idMap[idB]; + } // Rewrite the tokenstream to place the aside-footnotes and section footnotes where they need to be: + + + const footnote_spec_list = state.env.footnotes.list; // extract the tokens constituting the footnote/sidenote *content* and + // store that bunch in `refTokens[:]` instead, to be injected back into + // the tokenstream at the appropriate spots. + + state.tokens = state.tokens.filter(function (tok, idx) { + switch (tok.type) { + // filter out 'footnote_mark_end_of_block' tokens which follow BLOCKS that do not contain any + // footnote/sidenote/endnote references: + case 'footnote_mark_end_of_block': + if (!tok.meta) return false; + if (!tok.meta.footnote_list) return false; + break; + + case 'footnote_reference_open': + insideRef = true; + current = []; + return true; + + case 'footnote_reference_close': + insideRef = false; + const infoRec = footnote_spec_list[tok.meta.id]; + infoRec.tokens = current; + return true; + } + + if (insideRef) { + current.push(tok); + } + + return !insideRef; + }); // execute configured sorting/mapping (`idMap`): + + switch (plugin_options.sortOrder) { + // 0: first *appearance* in the text + default: + case 0: // 1: first *reference* in the text + + case 1: // 2: *definition* in the text + + case 2: + // order is specified in the `idMap` already. + break; + // 3: sorted alphanumerically by label (inline footnotes will end up at the top, before all other notes) + + case 3: + case 4: + // the `idMap[]` array has not been set up and must be produced + // to turn this into an alphanumerically-by-label sort order, where + // a `footnoteId` based index will produce the order of appearance. + const reIdMap = []; + + for (let i = 1; i < footnote_spec_list.length; i++) { + reIdMap[i - 1] = i; + } + + reIdMap.sort((idA, idB) => { + const infoA = footnote_spec_list[idA]; + const infoB = footnote_spec_list[idB]; + assert.strict.ok(infoA); + assert.strict.ok(infoB); // is any of these an inline footnote, i.e. without any label yet? Produce a fake label for sorting then! + // + // As stated elsewhere: inline section_notes and end_notes will end up among everyone else in this sort order mode. + + assert.strict.ok(infoA.id === idA); + assert.strict.ok(infoB.id === idB); // Split a "sort label" up into its numerical part and the tail. Note that we don't call + // it 'tail' but 'label', because we will need to compare the ENTIRE LABEL using string comparison + // when the numeric leaders are identical, so as to ensure that 'labels' such as `00000` will sort + // as 'higher' than `000`, both of which will be rated as numerically identical! + + function to_atoms(label) { + // now extract number or numerical leader part. + // + // Only accept OBVIOUS, SIMPLE NUMERIC LEADERS! This is about *legibility* + // of those numrical leaders, not a pedantic "what is possibly legally numeric" + // challenge. Hence we DO NOT accept leading +/- and only a decimal dot when + // there's a decimal number BEFORE it, such as in `5.1hack` --> `5.1`, but NOT + // `.42oz`! + // + // Do not use `nmr = +lbl` as that would treat labels such as `0xf4` as hexadecimal numbers, + // which we DO NOT want to happen. + const m = label.match(/^\d+(?:\.\d+)?/) || ['x']; + const nmr = +m[0] || Infinity; // non-numeric labels are rated NUMEICALLY HIGHER than any numerical leader. + + return { + label, + number: nmr + }; + } + + const labelA = plugin_options.sortOrder === 3 ? infoA.labelOverride || infoA.label || '' + infoA.id : plugin_options.mkLabel(infoA.id, infoA, baseInfo); + const labelB = plugin_options.sortOrder === 3 ? infoB.labelOverride || infoB.label || '' + infoB.id : plugin_options.mkLabel(infoB.id, infoB, baseInfo); + const atomA = to_atoms(labelA); + const atomB = to_atoms(labelB); + const diff = atomA.number - atomB.number; + return diff || atomA.label.localeCompare(atomB.label); // ^^^^^^^ shorthand for: + // + // if (isNaN(diff) || diff === 0) then stringcompare else numeric-difference + }); // Now turn this into a sort order map: + + for (let prio = 0; prio < reIdMap.length; prio++) { + const id = reIdMap[prio]; + idMap[id] = prio; + } + + break; + } + + let aside_list; + let section_list = new Set(); + const section_done_list = new Set(); // once a section_note has been printed, it should never appear again! + + const end_list = new Set(); + const used_list = new Set(); + let tokens = state.tokens; + + for (i = 0; i < tokens.length; i++) { + const tok = tokens[i]; + + switch (tok.type) { + case 'footnote_mark_end_of_block': + // check the gathered list of footnotes referenced in this block: + // - dump the ones which are sidenotes + // - mark the ones which are section- or end-notes. + // + // Note: make sure we don't produce duplicates in the collect sets. + { + var _tok$meta; + + aside_list = new Set(); + const refd_notes_list = ((_tok$meta = tok.meta) == null ? void 0 : _tok$meta.footnote_list) || []; + + for (const id of refd_notes_list) { + const footnote = footnote_spec_list[id]; + + switch (footnote.mode) { + case '>': + aside_list.add(id); + used_list.add(id); + break; + + case '=': + if (!section_done_list.has(id)) { + section_list.add(id); + section_done_list.add(id); + used_list.add(id); + } + + break; + + default: + case ':': + end_list.add(id); + used_list.add(id); + break; + } + } + + const aside_ids = []; + + for (const id of aside_list.values()) { + aside_ids.push(id); + } + + aside_ids.sort(footnote_print_comparer); + place_footnote_definitions_at(state, i + 1, aside_ids, 'aside', baseInfo); + tokens = state.tokens; + } + break; + + case 'footnote_reference_close': + // anywhere a footnote *definition* appeared in the original text is + // also a place to dump the section_notes gathered to date, so to speak. + // + // However, DO detect clusters of footnote definitions and MERGE them + // together: + if (more_footnote_reference_blocks_follow_immediately(tokens, i + 1)) { + continue; + } else { + const section_ids = []; + + for (const id of section_list.values()) { + section_ids.push(id); + } + + section_ids.sort(footnote_print_comparer); + place_footnote_definitions_at(state, i + 1, section_ids, 'section', baseInfo); + tokens = state.tokens; // and reset the tracking set: + + section_list = new Set(); + } + + break; + } + } // Now process the endnotes: + + + { + const end_ids = []; + + for (const id of end_list.values()) { + end_ids.push(id); + } + + end_ids.sort(footnote_print_comparer); + place_footnote_definitions_at(state, tokens.length, end_ids, 'end', baseInfo); + tokens = state.tokens; + } // Now process the unused footnotes and dump them for diagnostic purposes: + + { + const unused_ids = []; + + for (let i = 1; i < footnote_spec_list.length; i++) { + const fn = footnote_spec_list[i]; + const id = fn.id; + + if (!used_list.has(id)) { + console.error(`ERROR: footnote ID ${id} is defined but never used. Footnote will be added as an ERRONEOUS ENDNOTE to the output, so the situation is easy to diagnose!`, Object.assign({}, fn, { + tokens: '......' + })); + unused_ids.push(id); + } + } + + unused_ids.sort(footnote_print_comparer); + place_footnote_definitions_at(state, tokens.length, unused_ids, 'Error::Unused', baseInfo); //tokens = state.tokens; + } // Update state_block too as we have rewritten & REPLACED the token array earlier in this call: + // the reference `state.env.state_block.tokens` is still pointing to the OLD token array! + + state.env.state_block.tokens = state.tokens; + } // attach ourselves to the start of block handling too + + + md.block.ruler.before('table', 'footnote_mark_end_of_block', footnote_mark_end_of_block); + md.block.ruler.before('reference', 'footnote_def', footnote_def, { + alt: ['paragraph', 'reference'] + }); + md.inline.ruler.after('image', 'footnote_inline', footnote_inline); + md.inline.ruler.after('footnote_inline', 'footnote_ref_with_text', footnote_ref_with_text); + md.inline.ruler.after('footnote_ref_with_text', 'footnote_ref', footnote_ref); + md.core.ruler.after('inline', 'footnote_tail', footnote_tail); + } + + return footnote_plugin; + +}))); +//# sourceMappingURL=markdownItFootnote.umd.js.map diff --git a/dist/markdownItFootnote.umd.js.map b/dist/markdownItFootnote.umd.js.map new file mode 100644 index 0000000..2db10dc --- /dev/null +++ b/dist/markdownItFootnote.umd.js.map @@ -0,0 +1 @@ +{"version":3,"file":"markdownItFootnote.umd.js","sources":["../index.ts"],"sourcesContent":["// Process footnotes\n//\n\nimport { strict as assert } from 'assert';\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Renderer partials\n\n\n\ninterface FootnotePluginOptions {\n numberSequence?: Array;\n modeOverride?: string;\n sortOrder: number;\n refCombiner?: string;\n}\n\ninterface GenericInfoParameters {\n options: any; // markdown_it options object\n plugin_options: FootnotePluginOptions;\n env: any; // markdown_it environment object\n self: any; // reference to this plugin instance\n}\n\ninterface RenderInfoParameters extends GenericInfoParameters {\n tokens: Array; // array of tokens\n idx: number; // index of current token in token array\n}\n\ninterface footnoteMetaInfo {\n id: number;\n label?: string;\n labelOverride?: string;\n mode?: string;\n content?: string;\n tokens?: Array;\n count: number;\n}\n\n\n\nfunction anchorFnDefault(n: number, excludeSubId: number, baseInfo: RenderInfoParameters) {\n const env = baseInfo.env;\n assert.ok(env != null);\n let prefix = '';\n if (typeof env.docId === 'string' && env.docId.length > 0) {\n prefix = '-' + env.docId + '-';\n }\n return prefix + n;\n}\n\nfunction captionFnDefault(n, baseInfo: RenderInfoParameters) {\n //return '[' + n + ']';\n return '' + n;\n}\n\nfunction headerFnDefault(category, baseInfo: GenericInfoParameters) {\n switch (category) {\n case 'aside':\n return 'Side Notes';\n\n case 'section':\n return 'Section Notes';\n\n case 'end':\n return 'Endnotes';\n\n default: // used for error category, e.g. 'Error::Unused'\n return category;\n }\n}\n\nfunction determine_footnote_symbol(idx: number, info: footnoteMetaInfo, baseInfo: GenericInfoParameters): string {\n const plugin_options = baseInfo.plugin_options;\n assert.ok(plugin_options != null);\n\n // rule to construct the printed label:\n //\n // mark = labelOverride /* || info.label */ || idx;\n const label = info.labelOverride;\n if (label) {\n return label;\n }\n if (plugin_options.numberSequence == null || plugin_options.numberSequence.length === 0) {\n return '' + idx;\n }\n const len = plugin_options.numberSequence.length;\n if (idx >= len) {\n // is last slot numeric or alphanumerically?\n const slot = plugin_options.numberSequence[len - 1];\n if (Number.isFinite(slot)) {\n const delta = idx - len + 1;\n return '' + (slot + delta);\n }\n\n // non-numerical last slot --> duplicate, triplicate, etc.\n const dupli = (idx / len) | 0; // = int(x mod N)\n const remainder = idx % len;\n const core = plugin_options.numberSequence[remainder];\n let str = '' + core;\n for (let i = 1; i < dupli; i++) {\n str += core;\n }\n return str;\n }\n\n return '' + plugin_options.numberSequence[idx];\n}\n\n\nconst bunched_mode_classes = [ '', 'footnote-bunched-ref-ref', 'footnote-bunched-ref-text' ];\n\n\nfunction generateFootnoteRefHtml(id, caption, refId, bunched_footnote_ref_mode, renderInfo: RenderInfoParameters) {\n let localOverride = renderInfo.tokens[renderInfo.idx].meta.text;\n if (localOverride) {\n localOverride = `${ localOverride }`;\n }\n return `${ localOverride || '' }${ caption }` +\n (bunched_footnote_ref_mode !== 0 ? `${ renderInfo.plugin_options.refCombiner || '' }` : '');\n}\n\nfunction generateFootnoteSectionStartHtml(renderInfo: RenderInfoParameters) {\n const tok = renderInfo.tokens[renderInfo.idx];\n assert.ok(tok != null);\n assert.ok(tok.meta != null);\n const header = (tok.markup ? `

    ${ tok.markup }

    ` : '');\n let category = tok.meta.category;\n assert.ok(category.length > 0);\n // `category` can contain CSS class illegal characters, e.g. when category = 'Error::Unused':\n category = category.replace(/[^a-zA-Z0-9_-]+/g, '_');\n return `
    \\n';\n}\n\nfunction generateFootnoteStartHtml(id, caption, renderInfo: RenderInfoParameters) {\n // allow both a JavaWScript --> CSS approach via `data-footnote-caption`\n // and a classic CSS approach while a display:inline-block SUP presenting\n // the LI 'button' instead:\n return `
  • ${ caption }`;\n}\n\nfunction generateFootnoteEndHtml(renderInfo: RenderInfoParameters) {\n return '
  • \\n';\n}\n\nfunction generateFootnoteBackRefHtml(id, refId, renderInfo: RenderInfoParameters) {\n const tok = renderInfo.tokens[renderInfo.idx];\n assert.ok(tok != null);\n assert.ok(tok.meta != null);\n\n /* ↩ with escape code to prevent display as Apple Emoji on iOS */\n return ` \\u21a9\\uFE0E`;\n}\n\n\n\n\n/*\nref:\n return ``;\n\n\nopen:\n return `\\n';\n}\n\n*/\n\n\n\n\ninterface FootnotePluginOptions /* extends FootnotePluginOptions */ { // eslint-disable-line no-redeclare\n anchorFn: (n: number, excludeSubId: number, baseInfo: RenderInfoParameters) => string;\n captionFn: (n: number, baseInfo: RenderInfoParameters) => string;\n headerFn: (category: string, baseInfo: GenericInfoParameters) => string;\n mkLabel: (idx: number, info: footnoteMetaInfo, baseInfo: GenericInfoParameters) => string;\n}\n\n\n\n\nconst default_plugin_options: FootnotePluginOptions = {\n // atDocumentEnd: false, -- obsoleted option of the original plugin\n\n anchorFn: anchorFnDefault,\n captionFn: captionFnDefault,\n headerFn: headerFnDefault,\n mkLabel: determine_footnote_symbol,\n\n // see also https://www.editage.com/insights/footnotes-in-tables-part-1-choice-of-footnote-markers-and-their-sequence\n // why asterisk/star is not part of the default footnote marker sequence.\n //\n // For similar reasons, we DO NOT include the section § symbol in this list.\n //\n // when numberSequnce is NULL/empty, a regular numerical numbering is assumed.\n // Otherwise, the array is indexed; when there are more footnotes than entries in\n // the numberSequence array, the entries are re-used, but doubled/trippled, etc.\n //\n // When the indexing in this array hits a NUMERIC value (as last entry), any higher\n // footnotes are NUMBERED starting at that number.\n //\n // NOTE: as we can reference the same footnote from multiple spots, we do not depend\n // on CSS counter() approaches by default, but providee this mechanism in the plugin\n // code itself.\n numberSequence: [ '†', '‡', '††', '‡‡', '¶', 1 ],\n\n // Overrides the footnode mode when set to one of the following:\n //\n // Recognized 'modes':\n // '>': aside note (default for inline notes)\n // ':': end node\n // '=': section note (default for regular referenced notes)\n //\n // Also accepts these keywords: 'aside', 'section', 'end'\n //\n modeOverride: null,\n\n // list section notes and endnotes in order of:\n //\n // 0: first *appearance* in the text\n // 1: first *reference* in the text\n // 2: *definition* in the text\n // 3: sorted alphanumerically by *coded* label,\n // i.e. *numeric* labels are sorted in numeric order (so `10` comes AFTER `7`!),\n // while all others are sorted using `String.localeCompare()`. When labels have\n // a *numeric leading*, e.g. `71geo` --> `71`, that part is sorted numerically first.\n //\n // Here 'coded label' means the label constructed from the reference ids and label overrides\n // as used in the markdown source, using the expression\n // labelOverride || reference || id\n // which gives for these examples (assuming them to be the only definitions in your input):\n // [^refA]: ... --> null || 'refA' || 1\n // [^refB LBL]: ... --> 'LBL' || 'refB' || 2\n // 4: sorted alphanumerically by *printed* label\n // which is like mode 3, but now for the label as will be seen in the *output*!\n sortOrder: 4,\n\n // what to print between bunched-together footnote references, i.e. the '+' in `blabla¹⁺²`\n refCombiner: ','\n};\n\n\n\n\nexport default function footnote_plugin(md, plugin_options) {\n const parseLinkLabel = md.helpers.parseLinkLabel,\n isSpace = md.utils.isSpace;\n\n plugin_options = Object.assign({}, default_plugin_options, plugin_options);\n\n\n\n const modeOverrideMap = {\n aside: '>',\n section: '=',\n end: ':'\n };\n\n function determine_mode(mode: string, default_mode: string) {\n let override = null;\n if (plugin_options.modeOverride) {\n const mode = modeOverrideMap[plugin_options.modeOverride] || plugin_options.modeOverride;\n if ('>:='.includes(plugin_options.modeOverride)) {\n override = plugin_options.modeOverride;\n }\n }\n if ('>:='.includes(mode)) {\n return {\n mode: override || mode,\n fromInput: true\n };\n }\n return {\n mode: override || default_mode,\n fromInput: false\n };\n }\n\n function render_footnote_n(tokens, idx, excludeSubId) {\n const mark = tokens[idx].meta.id;\n assert.ok(Number.isFinite(mark));\n assert.ok(mark > 0);\n let n = '' + mark; // = mark.toString();\n assert.ok(n.length > 0);\n\n if (!excludeSubId && tokens[idx].meta.subId > 0) {\n n += '-' + tokens[idx].meta.subId;\n }\n\n return n;\n }\n\n function render_footnote_mark(renderInfo: RenderInfoParameters): string {\n const token = renderInfo.tokens[renderInfo.idx];\n assert.ok(token != null);\n assert.ok(renderInfo.env.footnotes != null);\n assert.ok(renderInfo.env.footnotes.list != null);\n const info = renderInfo.env.footnotes.list[token.meta.id];\n assert.ok(info != null);\n const mark: string = plugin_options.mkLabel(token.meta.id, info, renderInfo);\n assert.ok(mark.length > 0);\n return mark;\n }\n\n function render_footnote_anchor_name(renderInfo: RenderInfoParameters) {\n const n = render_footnote_n(renderInfo.tokens, renderInfo.idx, true);\n return plugin_options.anchorFn(n, true, renderInfo);\n }\n\n function render_footnote_anchor_nameRef(renderInfo: RenderInfoParameters) {\n const n = render_footnote_n(renderInfo.tokens, renderInfo.idx, false);\n return plugin_options.anchorFn(n, false, renderInfo);\n }\n\n function render_footnote_caption(renderInfo: RenderInfoParameters) {\n const n = render_footnote_mark(renderInfo);\n return plugin_options.captionFn(n, renderInfo);\n }\n\n function render_footnote_ref(tokens, idx, options, env, self) {\n const renderInfo: RenderInfoParameters = {\n tokens,\n idx,\n options,\n env,\n plugin_options,\n self\n };\n const id = render_footnote_anchor_name(renderInfo);\n const caption = render_footnote_caption(renderInfo);\n const refId = render_footnote_anchor_nameRef(renderInfo);\n\n // check if multiple footnote references are bunched together:\n // IFF they are, we should separate them with commas.\n //\n // Exception: when next token has an extra text (`meta.text`) the\n // bunching together is not a problem as them the output will render\n // like this: `bla1text2`, ergo a look\n // like this: `bla¹text²` instead of bunched footnotes references ¹ and ²\n // that would (without the extra comma injection) look like `bla¹²` instead\n // of `x¹⁺²` (here '+' instead of ',' comma, but you get the idea -- there's no\n // Unicode superscript-comma so that's why I used unicode superscript-plus\n // in this 'ascii art' example).\n //\n const next_token = tokens[idx + 1] || {};\n const next_token_meta = next_token.meta || {};\n const bunched_footnote_ref_mode = (next_token.type === 'footnote_ref' ? !next_token_meta.text ? 1 : 2 : 0);\n\n return generateFootnoteRefHtml(id, caption, refId, bunched_footnote_ref_mode, renderInfo);\n }\n\n function render_footnote_block_open(tokens, idx, options, env, self) {\n const renderInfo: RenderInfoParameters = {\n tokens,\n idx,\n options,\n env,\n plugin_options,\n self\n };\n return generateFootnoteSectionStartHtml(renderInfo);\n }\n\n function render_footnote_block_close(tokens, idx, options, env, self) {\n const renderInfo: RenderInfoParameters = {\n tokens,\n idx,\n options,\n env,\n plugin_options,\n self\n };\n return generateFootnoteSectionEndHtml(renderInfo);\n }\n\n function render_footnote_reference_open(tokens, idx, options, env, self) {\n return '';\n }\n\n function render_footnote_reference_close() {\n return '';\n }\n\n function render_footnote_mark_end_of_block() {\n return '';\n }\n\n function render_footnote_open(tokens, idx, options, env, self) {\n const renderInfo: RenderInfoParameters = {\n tokens,\n idx,\n options,\n env,\n plugin_options,\n self\n };\n const id = render_footnote_anchor_name(renderInfo);\n const caption = render_footnote_caption(renderInfo);\n\n // allow both a JavaScript --> CSS approach via `data-footnote-caption`\n // and a classic CSS approach while a display:inline-block SUP presenting\n // the LI 'button' instead:\n return generateFootnoteStartHtml(id, caption, renderInfo);\n }\n\n function render_footnote_close(tokens, idx, options, env, self) {\n const renderInfo: RenderInfoParameters = {\n tokens,\n idx,\n options,\n env,\n plugin_options,\n self\n };\n return generateFootnoteEndHtml(renderInfo);\n }\n\n function render_footnote_anchor_backref(tokens, idx, options, env, self) {\n const renderInfo: RenderInfoParameters = {\n tokens,\n idx,\n options,\n env,\n plugin_options,\n self\n };\n\n const tok = tokens[idx];\n assert.ok(tok != null);\n assert.ok(tok.meta != null);\n const id = render_footnote_anchor_name(renderInfo);\n let refId = render_footnote_n(tokens, idx, false);\n refId = plugin_options.anchorFn(refId, false, renderInfo);\n\n return generateFootnoteBackRefHtml(id, refId, renderInfo);\n }\n\n\n\n md.renderer.rules.footnote_ref = render_footnote_ref;\n md.renderer.rules.footnote_block_open = render_footnote_block_open;\n md.renderer.rules.footnote_block_close = render_footnote_block_close;\n md.renderer.rules.footnote_reference_open = render_footnote_reference_open;\n md.renderer.rules.footnote_reference_close = render_footnote_reference_close;\n md.renderer.rules.footnote_mark_end_of_block = render_footnote_mark_end_of_block;\n md.renderer.rules.footnote_open = render_footnote_open;\n md.renderer.rules.footnote_close = render_footnote_close;\n md.renderer.rules.footnote_anchor = render_footnote_anchor_backref;\n\n\n\n function obtain_footnote_info_slot(env, label: string|null, at_definition: boolean) {\n // inline blocks have their own *child* environment in markdown-it v10+.\n // As the footnotes must live beyond the lifetime of the inline block env,\n // we must patch them into the `parentState.env` for the footnote_tail\n // handler to be able to access them afterwards!\n while (env.parentState) {\n env = env.parentState.env;\n assert.ok(env != null);\n }\n\n if (!env.footnotes) {\n env.footnotes = {\n // map label tto ID:\n refs: {},\n // store footnote info indexed by ID\n list: [],\n // remap ID to re-ordered ID (determines placement order for section notes and endnotes)\n idMap: [ 0 ],\n idMapCounter: 0,\n\n // and a counter for the generated sections (including asides); see the demo/test which\n // uses the generated `#fnsection-DDD` identifiers to hack/fix the styling, for example.\n sectionCounter: 0\n };\n }\n\n // When label is NULL, this is a request from in INLINE NOTE.\n\n // NOTE: IDs are index numbers, BUT they start at 1 instead of 0 to make life easier in check code:\n let footnoteId;\n let infoRec: footnoteMetaInfo;\n // label as index: prepend ':' to avoid conflict with Object.prototype members\n if (label == null || !env.footnotes.refs[':' + label]) {\n footnoteId = Math.max(1, env.footnotes.list.length);\n infoRec = {\n id: footnoteId,\n label,\n labelOverride: null,\n mode: null,\n content: null,\n tokens: null,\n count: 0\n };\n env.footnotes.list[footnoteId] = infoRec;\n if (label != null) {\n env.footnotes.refs[':' + label] = footnoteId;\n }\n } else {\n footnoteId = env.footnotes.refs[':' + label];\n infoRec = env.footnotes.list[footnoteId];\n assert.ok(!!infoRec, 'expects non-NULL footnote info record');\n }\n\n const idMap = env.footnotes.idMap;\n\n // now check if the idMap[] has been set up already as well. This depends on\n // when WE are invoked (`at_definition`) and the configured `options.sortOrder`:\n switch (plugin_options.sortOrder) {\n // 0: first *appearance* in the text\n default:\n case 0:\n // basically, this means: order as-is\n if (!idMap[footnoteId]) {\n idMap[footnoteId] = ++env.footnotes.idMapCounter;\n }\n break;\n\n // 1: first *reference* in the text\n case 1:\n if (!at_definition && !idMap[footnoteId]) {\n // first reference is now!\n idMap[footnoteId] = ++env.footnotes.idMapCounter;\n }\n break;\n\n // 2: *definition* in the text\n case 2:\n if (at_definition && !idMap[footnoteId]) {\n // definition is now!\n idMap[footnoteId] = ++env.footnotes.idMapCounter;\n }\n break;\n\n // 3: sorted alphanumerically by label (inline footnotes will end up at the top, before all other notes)\n case 3:\n case 4:\n // just note the footnoteId now; this must be re-ordered later when we have collected all footnotes.\n //\n // set it up when we get there...\n break;\n }\n\n return infoRec;\n }\n\n function find_end_of_block_marker(state, startIndex) {\n let idx, len;\n const tokens = state.tokens;\n for (idx = startIndex, len = tokens.length; idx < len; idx++) {\n if (tokens[idx].type === 'footnote_mark_end_of_block') { return idx; }\n }\n\n // Punch a slot into the token stream (at the very end)\n // for consistency with footnote_mark_end_of_block():\n const token = new state.Token('footnote_mark_end_of_block', '', 0);\n token.hidden = true;\n tokens.push(token);\n return tokens.length - 1;\n }\n\n function update_end_of_block_marker(state, footnoteId) {\n // inject marker into parent = block level token stream to announce the advent of an (inline) footnote:\n // because the markdown_it code uses a for() loop to go through the parent nodes while parsing the\n // 'inline' chunks, we CANNOT safely inject a marker BEFORE the chunk, only AFTERWARDS:\n const parentState = state.env.parentState;\n const parentIndex = state.env.parentTokenIndex;\n const markerTokenIndex = find_end_of_block_marker(parentState, parentIndex + 1);\n const token = parentState.tokens[markerTokenIndex];\n if (!token.meta) {\n token.meta = {\n footnote_list: []\n };\n }\n token.meta.footnote_list.push(footnoteId);\n }\n\n // Mark end of paragraph/heading/whatever BLOCK (or rather: START of the next block!)\n function footnote_mark_end_of_block(state, startLine, endLine, silent) {\n if (!silent && state.tokens.length > 0) {\n const token = state.push('footnote_mark_end_of_block', '', 0);\n token.hidden = true;\n }\n return false;\n }\n\n\n\n // Process footnote block definition\n function footnote_def(state, startLine, endLine, silent) {\n let oldBMark, oldTShift, oldSCount, oldParentType, pos, token,\n initial, offset, ch, posAfterColon,\n start = state.bMarks[startLine] + state.tShift[startLine],\n max = state.eMarks[startLine];\n\n // line should be at least 6 chars - \"[^x]: \" or \"[^x]:> \"\n if (start + 5 > max) { return false; }\n\n if (state.src.charCodeAt(start) !== 0x5B/* [ */) { return false; }\n if (state.src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; }\n\n for (pos = start + 2; pos < max; pos++) {\n if (state.src.charCodeAt(pos) === 0x0A /* LF */) { return false; }\n if (state.src.charCodeAt(pos) === 0x5D /* ] */) {\n break;\n }\n }\n const labelEnd = pos;\n\n if (pos === start + 2) { return false; } // no empty footnote labels\n if (pos + 1 >= max || state.src.charCodeAt(++pos) !== 0x3A /* : */) { return false; }\n\n const mode_rec = determine_mode(state.src[pos + 1], '='); // default mode is section_note mode.\n if (mode_rec.fromInput) { pos++; }\n const mode = mode_rec.mode;\n\n if (pos + 1 >= max || state.src.charCodeAt(++pos) !== 0x20 /* space */) { return false; }\n if (silent) { return true; }\n pos++;\n\n const labelInfo = decode_label(state.src.slice(start + 2, labelEnd), true);\n if (!labelInfo) { return false; }\n assert.ok(!labelInfo.extraText);\n\n // Now see if we already have a footnote ID for this footnote label:\n // fetch it if we have one and otherwise produce a new one so everyone\n // can use this from now on.\n //\n // This scenario is possible when the footnote *definition* comes BEFORE\n // the first actual footnote *use* (*reference*). This is UNUSUAL when people\n // write texts, but it is *not impossible*, particularly now that we have\n // specified-by-design that endnotes can be marked as such (`[^label]:: note text`)\n // and freely mixed with sidenotes (`[^label]:> note text`) and section\n // notes (`[^label]:= note text` (explicit mode) or `[^label]: note text`\n // (implicit mode)), where *section notes* will placed at the spot in the text\n // flow where they were *defined*. Again, highly irregular, BUT someone MAY\n // feel the need to place some section note *definitions* ABOVE their first\n // use point.\n //\n const infoRec = obtain_footnote_info_slot(state.env, labelInfo.label, true);\n if (labelInfo.labelOverride) {\n infoRec.labelOverride = labelInfo.labelOverride;\n }\n infoRec.mode = mode;\n infoRec.content = state.src.slice(pos, max);\n\n token = state.push('footnote_reference_open', '', 1);\n token.meta = {\n id: infoRec.id\n };\n token.hidden = true;\n\n oldBMark = state.bMarks[startLine];\n oldTShift = state.tShift[startLine];\n oldSCount = state.sCount[startLine];\n oldParentType = state.parentType;\n\n posAfterColon = pos;\n initial = offset = state.sCount[startLine] + pos - (state.bMarks[startLine] + state.tShift[startLine]);\n\n while (pos < max) {\n ch = state.src.charCodeAt(pos);\n\n if (isSpace(ch)) {\n if (ch === 0x09) {\n offset += 4 - offset % 4;\n } else {\n offset++;\n }\n } else {\n break;\n }\n\n pos++;\n }\n\n state.tShift[startLine] = pos - posAfterColon;\n state.sCount[startLine] = offset - initial;\n\n state.bMarks[startLine] = posAfterColon;\n state.blkIndent += 4;\n state.parentType = 'footnote';\n\n if (state.sCount[startLine] < state.blkIndent) {\n state.sCount[startLine] += state.blkIndent;\n }\n\n state.md.block.tokenize(state, startLine, endLine, true);\n\n state.parentType = oldParentType;\n state.blkIndent -= 4;\n state.tShift[startLine] = oldTShift;\n state.sCount[startLine] = oldSCount;\n state.bMarks[startLine] = oldBMark;\n\n token = state.push('footnote_reference_close', '', -1);\n token.meta = {\n id: infoRec.id\n };\n\n return true;\n }\n\n\n\n // Process inline footnotes (^[...] or ^[>...])\n function footnote_inline(state, silent) {\n let labelStart,\n labelEnd,\n token,\n tokens,\n max = state.posMax,\n start = state.pos;\n\n if (start + 2 >= max) { return false; }\n if (state.src.charCodeAt(start) !== 0x5E/* ^ */) { return false; }\n if (state.src.charCodeAt(start + 1) !== 0x5B/* [ */) { return false; }\n\n labelStart = start + 2;\n\n // NOTE: inline notes are automatically considered to be ASIDE notes,\n // UNLESS otherwise specified!\n //\n // Recognized 'modes':\n // '>': aside note (default for inline notes)\n // ':': end node\n // '=': section note (default for regular referenced notes)\n //\n // (Also note https://v4.chriskrycho.com/2015/academic-markdown-and-citations.html:\n // our notes look like this: `[^ref]:` while Academic MarkDown references look\n // like this: `[@Belawog2012]` i.e. no '^' in there. Hence these can safely co-exist.)\n //\n const mode_rec = determine_mode(state.src[start + 2], '>'); // default mode is aside ~ sidenote mode.\n if (mode_rec.fromInput) {\n labelStart++;\n }\n const mode = mode_rec.mode;\n\n labelEnd = parseLinkLabel(state, start + 1);\n\n // parser failed to find ']', so it's not a valid note\n if (labelEnd < 0) { return false; }\n\n // We found the end of the link, and know for a fact it's a valid link;\n // so all that's left to do is to call tokenizer.\n //\n if (!silent) {\n // WARNING: claim our footnote slot for there MAY be nested footnotes\n // discovered in the next inline.parse() call below!\n const infoRec = obtain_footnote_info_slot(state.env, null, true);\n infoRec.mode = mode;\n infoRec.count++;\n\n token = state.push('footnote_ref', '', 0);\n token.meta = {\n id: infoRec.id\n };\n\n state.md.inline.parse(\n state.src.slice(labelStart, labelEnd),\n state.md,\n state.env,\n tokens = []\n );\n\n // Now fill our previously claimed slot:\n infoRec.content = state.src.slice(labelStart, labelEnd);\n infoRec.tokens = tokens;\n\n // inject marker into parent = block level token stream to announce the advent of an (inline) footnote:\n // because the markdown_it code uses a for() loop to go through the parent nodes while parsing the\n // 'inline' chunks, we CANNOT safely inject a marker BEFORE the chunk, only AFTERWARDS:\n update_end_of_block_marker(state, infoRec.id);\n\n //md.block.ruler.enable('footnote_mark_end_of_block');\n }\n\n state.pos = labelEnd + 1;\n state.posMax = max;\n return true;\n }\n\n\n\n // Check if this is a valid ffootnote reference label.\n //\n // Also see if there's a label OVERRIDE text or marker ('@') provided.\n //\n // Return the parsed label record.\n function decode_label(label: string, extra_text_is_labelOverride: boolean) {\n if (!label) {\n return null;\n }\n const m = label.match(/^(@?)(\\S+)(?:\\s+(.+))?$/); // label with OPTIONAL override text...\n if (!m) {\n return null;\n }\n assert.ok(m[2].length > 0);\n let extraText = m[3]?.trim();\n // label [output] override?\n let override = null;\n if (m[1]) {\n override = m[2];\n }\n if (extra_text_is_labelOverride && extraText) {\n override = extraText;\n extraText = null;\n }\n\n return {\n label: m[2],\n labelOverride: override,\n extraText\n };\n }\n\n\n\n // Process footnote references with text ([^label ...])\n function footnote_ref_with_text(state, silent) {\n let pos,\n footnoteSubId,\n token,\n max = state.posMax,\n start = state.pos;\n\n // should be at least 6 chars - \"[^l x]\"\n if (start + 5 > max) { return false; }\n\n if (state.src.charCodeAt(start) !== 0x5B/* [ */) { return false; }\n if (state.src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; }\n\n for (pos = start + 2; pos < max; pos++) {\n if (state.src.charCodeAt(pos) === 0x0A /* linefeed */) { return false; }\n if (state.src.charCodeAt(pos) === 0x5D /* ] */) {\n break;\n }\n }\n\n if (pos === start + 2) { return false; } // no empty footnote labels\n if (pos >= max) { return false; }\n pos++;\n\n const labelInfo = decode_label(state.src.slice(start + 2, pos - 1), false);\n if (!labelInfo || !labelInfo.extraText) { return false; }\n assert.ok(labelInfo.extraText.length > 0);\n\n const infoRec = obtain_footnote_info_slot(state.env, labelInfo.label, false);\n if (labelInfo.labelOverride) {\n infoRec.labelOverride = labelInfo.labelOverride;\n }\n\n if (!silent) {\n footnoteSubId = infoRec.count;\n\n infoRec.count++;\n\n token = state.push('footnote_ref', '', 0);\n token.meta = {\n id: infoRec.id,\n subId: footnoteSubId,\n text: labelInfo.extraText\n };\n\n update_end_of_block_marker(state, infoRec.id);\n\n //md.block.ruler.enable('footnote_mark_end_of_block');\n }\n\n state.pos = pos;\n state.posMax = max;\n return true;\n }\n\n\n\n // Process footnote references ([^...])\n function footnote_ref(state, silent) {\n let pos,\n footnoteSubId,\n token,\n max = state.posMax,\n start = state.pos;\n\n // should be at least 4 chars - \"[^x]\"\n if (start + 3 > max) { return false; }\n\n if (state.src.charCodeAt(start) !== 0x5B/* [ */) { return false; }\n if (state.src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; }\n\n for (pos = start + 2; pos < max; pos++) {\n //if (state.src.charCodeAt(pos) === 0x20) { return false; }\n if (state.src.charCodeAt(pos) === 0x0A) { return false; }\n if (state.src.charCodeAt(pos) === 0x5D /* ] */) {\n break;\n }\n }\n\n if (pos === start + 2) { return false; } // no empty footnote labels\n if (pos >= max) { return false; }\n pos++;\n\n const labelInfo = decode_label(state.src.slice(start + 2, pos - 1), true);\n if (!labelInfo) { return false; }\n assert.ok(!labelInfo.extraText);\n\n const infoRec = obtain_footnote_info_slot(state.env, labelInfo.label, false);\n if (labelInfo.labelOverride) {\n infoRec.labelOverride = labelInfo.labelOverride;\n }\n\n if (!silent) {\n footnoteSubId = infoRec.count;\n\n infoRec.count++;\n\n token = state.push('footnote_ref', '', 0);\n token.meta = {\n id: infoRec.id,\n subId: footnoteSubId\n };\n\n update_end_of_block_marker(state, infoRec.id);\n\n //md.block.ruler.enable('footnote_mark_end_of_block');\n }\n\n state.pos = pos;\n state.posMax = max;\n return true;\n }\n\n\n\n function place_footnote_definitions_at(state, token_idx: number, footnote_id_list, category: string, baseInfo: GenericInfoParameters) {\n if (footnote_id_list.length === 0) {\n return; // nothing to inject...\n }\n\n let inject_tokens = [];\n assert.ok(baseInfo.env.footnotes.list != null);\n const footnote_spec_list = baseInfo.env.footnotes.list;\n\n let token = new state.Token('footnote_block_open', '', 1);\n token.markup = plugin_options.headerFn(category, baseInfo.env, plugin_options);\n token.meta = {\n sectionId: ++baseInfo.env.footnotes.sectionCounter,\n category\n };\n inject_tokens.push(token);\n\n for (const id of footnote_id_list) {\n const fn = footnote_spec_list[id];\n const inject_start_index = inject_tokens.length;\n\n token = new state.Token('footnote_open', '', 1);\n token.meta = {\n id,\n category\n };\n inject_tokens.push(token);\n\n if (fn.label == null) {\n // process an inline footnote text:\n token = new state.Token('paragraph_open', 'p', 1);\n token.block = true;\n inject_tokens.push(token);\n\n token = new state.Token('inline', '', 0);\n token.children = fn.tokens;\n token.content = fn.content;\n inject_tokens.push(token);\n\n token = new state.Token('paragraph_close', 'p', -1);\n token.block = true;\n inject_tokens.push(token);\n } else {\n // process a labeled footnote:\n inject_tokens = inject_tokens.concat(fn.tokens || []);\n }\n\n //let lastParagraph;\n //if (inject_tokens[inject_tokens.length - 1].type === 'paragraph_close') {\n // lastParagraph = inject_tokens.pop();\n //} else {\n // lastParagraph = null;\n //}\n\n const cnt = fn.count;\n assert.ok(cnt >= 0);\n for (let j = 0; j < cnt; j++) {\n token = new state.Token('footnote_anchor', '', 0);\n token.meta = {\n id,\n subId: j,\n backrefCount: cnt,\n category\n };\n inject_tokens.push(token);\n }\n\n //if (lastParagraph) {\n // inject_tokens.push(lastParagraph);\n //}\n\n token = new state.Token('footnote_close', '', -1);\n token.meta = {\n id,\n category\n };\n inject_tokens.push(token);\n }\n\n token = new state.Token('footnote_block_close', '', -1);\n token.meta = {\n category\n };\n inject_tokens.push(token);\n\n state.tokens.splice(token_idx, 0, ...inject_tokens);\n }\n\n function more_footnote_reference_blocks_follow_immediately(tokens, idx) {\n let tok = tokens[idx];\n while (tok && (tok.type === 'footnote_mark_end_of_block' || tok.type === 'footnote_reference_close')) {\n idx++;\n tok = tokens[idx];\n }\n return tok && (tok.type === 'footnote_reference_open');\n }\n\n // Glue footnote tokens into appropriate slots of token stream.\n function footnote_tail(state, startLine, endLine, silent) {\n let i, l, j, t, token, current, currentRefToken,\n insideRef = false,\n refTokens = {};\n\n if (!state.env.footnotes) {\n // no footnotes at all? --> filter out all 'footnote_mark_end_of_block' chunks:\n state.tokens = state.tokens.filter(function (tok, idx) {\n return (tok.type !== 'footnote_mark_end_of_block');\n });\n return;\n }\n\n const idMap = state.env.footnotes.idMap;\n\n const baseInfo: GenericInfoParameters = {\n options: state.md.options,\n env: state.env,\n plugin_options,\n self: this\n };\n\n function footnote_print_comparer(idA, idB) {\n return idMap[idA] - idMap[idB];\n }\n\n\n // Rewrite the tokenstream to place the aside-footnotes and section footnotes where they need to be:\n const footnote_spec_list = state.env.footnotes.list;\n\n // extract the tokens constituting the footnote/sidenote *content* and\n // store that bunch in `refTokens[:]` instead, to be injected back into\n // the tokenstream at the appropriate spots.\n state.tokens = state.tokens.filter(function (tok, idx) {\n switch (tok.type) {\n // filter out 'footnote_mark_end_of_block' tokens which follow BLOCKS that do not contain any\n // footnote/sidenote/endnote references:\n case 'footnote_mark_end_of_block':\n if (!tok.meta) return false;\n if (!tok.meta.footnote_list) return false;\n break;\n\n case 'footnote_reference_open':\n insideRef = true;\n current = [];\n currentRefToken = tok;\n return true;\n\n case 'footnote_reference_close':\n insideRef = false;\n\n const infoRec = footnote_spec_list[tok.meta.id];\n infoRec.tokens = current;\n\n return true;\n }\n if (insideRef) {\n current.push(tok);\n }\n return !insideRef;\n });\n\n\n // execute configured sorting/mapping (`idMap`):\n switch (plugin_options.sortOrder) {\n // 0: first *appearance* in the text\n default:\n case 0:\n // 1: first *reference* in the text\n case 1:\n // 2: *definition* in the text\n case 2:\n // order is specified in the `idMap` already.\n break;\n\n // 3: sorted alphanumerically by label (inline footnotes will end up at the top, before all other notes)\n case 3:\n case 4:\n // the `idMap[]` array has not been set up and must be produced\n // to turn this into an alphanumerically-by-label sort order, where\n // a `footnoteId` based index will produce the order of appearance.\n const reIdMap = [];\n for (let i = 1; i < footnote_spec_list.length; i++) {\n reIdMap[i - 1] = i;\n }\n reIdMap.sort((idA, idB) => {\n const infoA = footnote_spec_list[idA];\n const infoB = footnote_spec_list[idB];\n assert.ok(infoA);\n assert.ok(infoB);\n\n // is any of these an inline footnote, i.e. without any label yet? Produce a fake label for sorting then!\n //\n // As stated elsewhere: inline section_notes and end_notes will end up among everyone else in this sort order mode.\n assert.ok(infoA.id === idA);\n assert.ok(infoB.id === idB);\n\n // Split a \"sort label\" up into its numerical part and the tail. Note that we don't call\n // it 'tail' but 'label', because we will need to compare the ENTIRE LABEL using string comparison\n // when the numeric leaders are identical, so as to ensure that 'labels' such as `00000` will sort\n // as 'higher' than `000`, both of which will be rated as numerically identical!\n function to_atoms(label) {\n // now extract number or numerical leader part.\n //\n // Only accept OBVIOUS, SIMPLE NUMERIC LEADERS! This is about *legibility*\n // of those numrical leaders, not a pedantic \"what is possibly legally numeric\"\n // challenge. Hence we DO NOT accept leading +/- and only a decimal dot when\n // there's a decimal number BEFORE it, such as in `5.1hack` --> `5.1`, but NOT\n // `.42oz`!\n //\n // Do not use `nmr = +lbl` as that would treat labels such as `0xf4` as hexadecimal numbers,\n // which we DO NOT want to happen.\n const m = label.match(/^\\d+(?:\\.\\d+)?/) || [ 'x' ];\n const nmr = +m[0] || Infinity; // non-numeric labels are rated NUMEICALLY HIGHER than any numerical leader.\n return {\n label,\n number: nmr\n };\n }\n\n const labelA = (plugin_options.sortOrder === 3 ?\n infoA.labelOverride || infoA.label || ('' + infoA.id) :\n plugin_options.mkLabel(infoA.id, infoA, baseInfo)\n );\n const labelB = (plugin_options.sortOrder === 3 ?\n infoB.labelOverride || infoB.label || ('' + infoB.id) :\n plugin_options.mkLabel(infoB.id, infoB, baseInfo)\n );\n const atomA = to_atoms(labelA);\n const atomB = to_atoms(labelB);\n const diff = atomA.number - atomB.number;\n return diff || atomA.label.localeCompare(atomB.label);\n // ^^^^^^^ shorthand for:\n //\n // if (isNaN(diff) || diff === 0) then stringcompare else numeric-difference\n });\n\n // Now turn this into a sort order map:\n for (let prio = 0; prio < reIdMap.length; prio++) {\n const id = reIdMap[prio];\n idMap[id] = prio;\n }\n break;\n }\n\n\n const inject_tokens = [];\n\n // Now go through the token stream and place the sidenotes, section_notes and endnotes where they belong:\n let aside_list;\n let section_list = new Set();\n const section_done_list = new Set(); // once a section_note has been printed, it should never appear again!\n const end_list = new Set();\n const used_list = new Set();\n\n let tokens = state.tokens;\n\n for (i = 0; i < tokens.length; i++) {\n const tok = tokens[i];\n switch (tok.type) {\n case 'footnote_mark_end_of_block':\n // check the gathered list of footnotes referenced in this block:\n // - dump the ones which are sidenotes\n // - mark the ones which are section- or end-notes.\n //\n // Note: make sure we don't produce duplicates in the collect sets.\n {\n aside_list = new Set();\n\n const refd_notes_list = (tok.meta?.footnote_list || []);\n for (const id of refd_notes_list) {\n const footnote = footnote_spec_list[id];\n\n switch (footnote.mode) {\n case '>':\n aside_list.add(id);\n used_list.add(id);\n break;\n\n case '=':\n if (!section_done_list.has(id)) {\n section_list.add(id);\n section_done_list.add(id);\n used_list.add(id);\n }\n break;\n\n default:\n case ':':\n end_list.add(id);\n used_list.add(id);\n break;\n }\n }\n\n const aside_ids = [];\n for (const id of aside_list.values()) {\n aside_ids.push(id);\n }\n aside_ids.sort(footnote_print_comparer);\n\n place_footnote_definitions_at(state, i + 1, aside_ids, 'aside', baseInfo);\n tokens = state.tokens;\n }\n break;\n\n case 'footnote_reference_close':\n // anywhere a footnote *definition* appeared in the original text is\n // also a place to dump the section_notes gathered to date, so to speak.\n //\n // However, DO detect clusters of footnote definitions and MERGE them\n // together:\n if (more_footnote_reference_blocks_follow_immediately(tokens, i + 1)) {\n continue;\n } else {\n const section_ids = [];\n for (const id of section_list.values()) {\n section_ids.push(id);\n }\n section_ids.sort(footnote_print_comparer);\n\n place_footnote_definitions_at(state, i + 1, section_ids, 'section', baseInfo);\n tokens = state.tokens;\n\n // and reset the tracking set:\n section_list = new Set();\n }\n break;\n }\n }\n\n // Now process the endnotes:\n {\n const end_ids = [];\n for (const id of end_list.values()) {\n end_ids.push(id);\n }\n end_ids.sort(footnote_print_comparer);\n\n place_footnote_definitions_at(state, tokens.length, end_ids, 'end', baseInfo);\n tokens = state.tokens;\n }\n\n // Now process the unused footnotes and dump them for diagnostic purposes:\n {\n const unused_ids = [];\n\n for (let i = 1; i < footnote_spec_list.length; i++) {\n const fn = footnote_spec_list[i];\n const id = fn.id;\n if (!used_list.has(id)) {\n console.error(`ERROR: footnote ID ${id} is defined but never used. Footnote will be added as an ERRONEOUS ENDNOTE to the output, so the situation is easy to diagnose!`, Object.assign({}, fn, { tokens: '......' }));\n unused_ids.push(id);\n }\n }\n unused_ids.sort(footnote_print_comparer);\n\n place_footnote_definitions_at(state, tokens.length, unused_ids, 'Error::Unused', baseInfo);\n //tokens = state.tokens;\n }\n\n // Update state_block too as we have rewritten & REPLACED the token array earlier in this call:\n // the reference `state.env.state_block.tokens` is still pointing to the OLD token array!\n state.env.state_block.tokens = state.tokens;\n }\n\n\n\n\n // attach ourselves to the start of block handling too\n md.block.ruler.before('table', 'footnote_mark_end_of_block', footnote_mark_end_of_block);\n\n md.block.ruler.before('reference', 'footnote_def', footnote_def, { alt: [ 'paragraph', 'reference' ] });\n md.inline.ruler.after('image', 'footnote_inline', footnote_inline);\n md.inline.ruler.after('footnote_inline', 'footnote_ref_with_text', footnote_ref_with_text);\n md.inline.ruler.after('footnote_ref_with_text', 'footnote_ref', footnote_ref);\n md.core.ruler.after('inline', 'footnote_tail', footnote_tail);\n}\n"],"names":["anchorFnDefault","n","excludeSubId","baseInfo","env","assert","ok","prefix","docId","length","captionFnDefault","headerFnDefault","category","determine_footnote_symbol","idx","info","plugin_options","label","labelOverride","numberSequence","len","slot","Number","isFinite","delta","dupli","remainder","core","str","i","bunched_mode_classes","generateFootnoteRefHtml","id","caption","refId","bunched_footnote_ref_mode","renderInfo","localOverride","tokens","meta","text","refCombiner","generateFootnoteSectionStartHtml","tok","header","markup","replace","sectionId","options","xhtmlOut","generateFootnoteSectionEndHtml","generateFootnoteStartHtml","generateFootnoteEndHtml","generateFootnoteBackRefHtml","subId","backrefCount","default_plugin_options","anchorFn","captionFn","headerFn","mkLabel","modeOverride","sortOrder","footnote_plugin","md","parseLinkLabel","helpers","isSpace","utils","Object","assign","determine_mode","mode","default_mode","override","includes","fromInput","render_footnote_n","mark","render_footnote_mark","token","footnotes","list","render_footnote_anchor_name","render_footnote_anchor_nameRef","render_footnote_caption","render_footnote_ref","self","next_token","next_token_meta","type","render_footnote_block_open","render_footnote_block_close","render_footnote_reference_open","render_footnote_reference_close","render_footnote_mark_end_of_block","render_footnote_open","render_footnote_close","render_footnote_anchor_backref","renderer","rules","footnote_ref","footnote_block_open","footnote_block_close","footnote_reference_open","footnote_reference_close","footnote_mark_end_of_block","footnote_open","footnote_close","footnote_anchor","obtain_footnote_info_slot","at_definition","parentState","refs","idMap","idMapCounter","sectionCounter","footnoteId","infoRec","Math","max","content","count","find_end_of_block_marker","state","startIndex","Token","hidden","push","update_end_of_block_marker","parentIndex","parentTokenIndex","markerTokenIndex","footnote_list","startLine","endLine","silent","footnote_def","oldBMark","oldTShift","oldSCount","oldParentType","pos","initial","offset","ch","posAfterColon","start","bMarks","tShift","eMarks","src","charCodeAt","labelEnd","mode_rec","labelInfo","decode_label","slice","extraText","sCount","parentType","blkIndent","block","tokenize","footnote_inline","labelStart","posMax","inline","parse","extra_text_is_labelOverride","m","match","trim","footnote_ref_with_text","footnoteSubId","place_footnote_definitions_at","token_idx","footnote_id_list","inject_tokens","footnote_spec_list","fn","children","concat","cnt","j","splice","more_footnote_reference_blocks_follow_immediately","footnote_tail","current","insideRef","filter","footnote_print_comparer","idA","idB","reIdMap","sort","infoA","infoB","to_atoms","nmr","Infinity","number","labelA","labelB","atomA","atomB","diff","localeCompare","prio","aside_list","section_list","Set","section_done_list","end_list","used_list","refd_notes_list","footnote","add","has","aside_ids","values","section_ids","end_ids","unused_ids","console","error","state_block","ruler","before","alt","after"],"mappings":"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"} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 92cd60a..72a6155 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,9 +16,9 @@ "@typescript-eslint/parser": "4.28.1", "argparse": "2.0.1", "cross-env": "7.0.3", - "eslint": "7.29.0", + "eslint": "7.30.0", "microbundle": "0.13.3", - "mocha": "9.0.1", + "mocha": "9.0.2", "nyc": "15.1.0" }, "engines": { @@ -1892,6 +1892,26 @@ "prepend-header": "index.mjs" } }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -2982,24 +3002,24 @@ } }, "node_modules/chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", "dev": true, "dependencies": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "glob-parent": "~5.1.0", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" + "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { - "fsevents": "~2.3.1" + "fsevents": "~2.3.2" } }, "node_modules/chokidar/node_modules/braces": { @@ -4211,13 +4231,14 @@ } }, "node_modules/eslint": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.29.0.tgz", - "integrity": "sha512-82G/JToB9qIy/ArBzIWG9xvvwL3R86AlCjtGw+A29OMZDqhTybz/MByORSukGxeI+YPCR4coYyITKk8BFH9nDA==", + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", + "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", "dev": true, "dependencies": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.2", + "@humanwhocodes/config-array": "^0.5.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -6847,15 +6868,15 @@ } }, "node_modules/mocha": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.0.1.tgz", - "integrity": "sha512-9zwsavlRO+5csZu6iRtl3GHImAbhERoDsZwdRkdJ/bE+eVplmoxNKE901ZJ9LdSchYBjSCPbjKc5XvcAri2ylw==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.0.2.tgz", + "integrity": "sha512-FpspiWU+UT9Sixx/wKimvnpkeW0mh6ROAKkIaPokj3xZgxeRhcna/k5X57jJghEr8X+Cgu/Vegf8zCX5ugSuTA==", "dev": true, "dependencies": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.5.1", + "chokidar": "3.5.2", "debug": "4.3.1", "diff": "5.0.0", "escape-string-regexp": "4.0.0", @@ -6868,12 +6889,12 @@ "minimatch": "3.0.4", "ms": "2.1.3", "nanoid": "3.1.23", - "serialize-javascript": "5.0.1", + "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", "which": "2.0.2", "wide-align": "1.1.3", - "workerpool": "6.1.4", + "workerpool": "6.1.5", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" @@ -6967,9 +6988,9 @@ } }, "node_modules/mocha/node_modules/serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, "dependencies": { "randombytes": "^2.1.0" @@ -10518,9 +10539,9 @@ } }, "node_modules/readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "dependencies": { "picomatch": "^2.2.1" @@ -12020,9 +12041,9 @@ } }, "node_modules/workerpool": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.4.tgz", - "integrity": "sha512-jGWPzsUqzkow8HoAvqaPWTUPCrlPJaJ5tY8Iz7n1uCz3tTp6s3CDG0FF1NsX42WNlkRSW6Mr+CDZGnNoSsKa7g==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", + "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", "dev": true }, "node_modules/wrap-ansi": { @@ -13498,6 +13519,23 @@ "prepend-to-js-file": "1.3.2" } }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -14283,19 +14321,19 @@ } }, "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", "dev": true, "requires": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" + "readdirp": "~3.6.0" }, "dependencies": { "braces": { @@ -15244,13 +15282,14 @@ "dev": true }, "eslint": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.29.0.tgz", - "integrity": "sha512-82G/JToB9qIy/ArBzIWG9xvvwL3R86AlCjtGw+A29OMZDqhTybz/MByORSukGxeI+YPCR4coYyITKk8BFH9nDA==", + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", + "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", "dev": true, "requires": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.2", + "@humanwhocodes/config-array": "^0.5.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -17292,15 +17331,15 @@ } }, "mocha": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.0.1.tgz", - "integrity": "sha512-9zwsavlRO+5csZu6iRtl3GHImAbhERoDsZwdRkdJ/bE+eVplmoxNKE901ZJ9LdSchYBjSCPbjKc5XvcAri2ylw==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.0.2.tgz", + "integrity": "sha512-FpspiWU+UT9Sixx/wKimvnpkeW0mh6ROAKkIaPokj3xZgxeRhcna/k5X57jJghEr8X+Cgu/Vegf8zCX5ugSuTA==", "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.5.1", + "chokidar": "3.5.2", "debug": "4.3.1", "diff": "5.0.0", "escape-string-regexp": "4.0.0", @@ -17313,12 +17352,12 @@ "minimatch": "3.0.4", "ms": "2.1.3", "nanoid": "3.1.23", - "serialize-javascript": "5.0.1", + "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", "which": "2.0.2", "wide-align": "1.1.3", - "workerpool": "6.1.4", + "workerpool": "6.1.5", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" @@ -17374,9 +17413,9 @@ } }, "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -20065,9 +20104,9 @@ } }, "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "requires": { "picomatch": "^2.2.1" @@ -21250,9 +21289,9 @@ "dev": true }, "workerpool": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.4.tgz", - "integrity": "sha512-jGWPzsUqzkow8HoAvqaPWTUPCrlPJaJ5tY8Iz7n1uCz3tTp6s3CDG0FF1NsX42WNlkRSW6Mr+CDZGnNoSsKa7g==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", + "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", "dev": true }, "wrap-ansi": { diff --git a/package.json b/package.json index 7fe7eb7..7f94eb2 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,12 @@ "license": "MIT", "type": "module", "source": "index.ts", - "main": "dist/markdownItFootnote.js", - "types": "dist/markdownItFootnote.d.ts", + "main": "./dist/markdownItFootnote.cjs", + "module": "./dist/markdownItFootnote.mjs", + "exports": "./dist/markdownItFootnote.modern.js", + "unpkg": "./dist/markdownItFootnote.umd.js", + "umd:main": "./dist/markdownItFootnote.umd.js", + "types": "./dist/markdownItFootnote.d.ts", "engines": { "node": ">=12.21" }, @@ -40,9 +44,9 @@ "@typescript-eslint/parser": "4.28.1", "argparse": "2.0.1", "cross-env": "7.0.3", - "eslint": "7.29.0", + "eslint": "7.30.0", "microbundle": "0.13.3", - "mocha": "9.0.1", + "mocha": "9.0.2", "nyc": "15.1.0" }, "reporter": [ diff --git a/test/test.js b/test/test.js index 624767b..bcaed28 100644 --- a/test/test.js +++ b/test/test.js @@ -12,7 +12,7 @@ import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); -import plugin from '../dist/markdownitFootnote.js'; +import plugin from '../dist/markdownItFootnote.modern.js'; function N(n) { const rv = '00000' + n;