marked-footnote
Version:
A marked extension to support GFM footnotes
139 lines (137 loc) • 3.72 kB
JavaScript
function y(t, f) {
const n = {
type: "footnotes",
raw: f,
rawItems: [],
items: []
};
return {
name: "footnote",
level: "block",
childTokens: ["content"],
tokenizer(r) {
t.hasFootnotes || (this.lexer.tokens.push(n), t.tokens = this.lexer.tokens, t.hasFootnotes = !0, n.rawItems = [], n.items = []);
const s = /^\[\^([^\]\n]+)\]:(?:[ \t]+|[\n]*?|$)([^\n]*?(?:\n|$)(?:\n*?[ ]{4,}[^\n]*)*)/.exec(
r
);
if (s) {
const [a, d, c = ""] = s;
let l = c.split(`
`).reduce((i, h) => i + `
` + h.replace(/^(?:[ ]{4}|[\t])/, ""), "");
const e = l.trimEnd().split(`
`).pop();
l += // add lines after list, blockquote, codefence, and table
e && /^[ \t]*?[>\-*][ ]|[`]{3,}$|^[ \t]*?[|].+[|]$/.test(e) ? `
` : "";
const o = {
type: "footnote",
raw: a,
label: d,
refs: [],
content: this.lexer.blockTokens(l)
};
return n.rawItems.push(o), o;
}
},
renderer() {
return "";
}
};
}
function R(t, f = !1) {
let n = 0;
return {
name: "footnoteRef",
level: "inline",
tokenizer(r) {
const s = /^\[\^([^\]\n]+)\]/.exec(r);
if (s) {
const [a, d] = s, c = this.lexer.tokens[0], l = c.rawItems.filter(
(h) => h.label === d
);
if (!l.length) return;
const e = l[0], o = c.items.filter((h) => h.label === d)[0], i = {
type: "footnoteRef",
raw: a,
id: "",
label: d
};
return o ? (i.id = o.refs[0].id, o.refs.push(i)) : (n++, i.id = String(n), e.refs.push(i), c.items.push(e)), i;
}
},
renderer({ id: r, label: s }) {
n = 0;
const a = encodeURIComponent(s);
return `<sup><a id="${t}ref-${a}" href="#${t + a}" data-${t}ref aria-describedby="${t}label">${f ? `[${r}]` : r}</a></sup>`;
}
};
}
function g(t, f, n, r, s, a) {
return {
name: "footnotes",
renderer({ raw: d, items: c = [] }) {
if (c.length === 0) return "";
const l = c.reduce(
(h, { label: $, content: w, refs: F }) => {
const m = encodeURIComponent($), p = this.parser.parse(w).trimEnd(), k = p.endsWith("</p>");
let u = `<li id="${t + m}">
`;
return u += k ? p.replace(/<\/p>$/, "") : p, F.forEach((E, b) => {
const L = a.replace("{0}", $);
u += ` <a href="#${t}ref-${m}" data-${t}backref aria-label="${L}">${b > 0 ? `↩<sup>${b + 1}</sup>` : "↩"}</a>`;
}), u += k ? `</p>
` : `
`, u += `</li>
`, h + u;
},
""
);
let e = "";
n && (e += `<hr data-${f}footnotes>
`);
let o = "";
r && (o = ` class="${r}"`);
let i = "";
return s && (i = ` class="${s}"`), e += `<section${o} data-${f}footnotes>
`, e += `<h2 id="${t}label"${i}>${d.trimEnd()}</h2>
`, e += `<ol>
${l}</ol>
`, e += `</section>
`, e;
}
};
}
function T(t = {}) {
const {
prefixId: f = "footnote-",
prefixData: n = "",
description: r = "Footnotes",
refMarkers: s = !1,
footnoteDivider: a = !1,
sectionClass: d = "footnotes",
headingClass: c = "sr-only",
backRefLabel: l = "Back to reference {0}"
} = t, e = { hasFootnotes: !1, tokens: [] };
return {
extensions: [
y(e, r),
R(f, s),
g(
f,
n,
a,
d,
c,
l
)
],
walkTokens(o) {
o.type === "footnotes" && e.tokens.indexOf(o) === 0 && o.items.length && (e.tokens[0] = { type: "space", raw: "" }, e.tokens.push(o)), e.hasFootnotes && (e.hasFootnotes = !1);
}
};
}
export {
T as default
};
//# sourceMappingURL=index.js.map