remarkable-plugin-heading-id
Version:
42 lines (41 loc) • 1.9 kB
JavaScript
import { idx, incrementIdx, resetIdx } from "../context";
import { isHeadingOpenToken } from "./utils/isHeadingOpenToken/isHeadingOpenToken";
import { isInline } from "./utils/isInline/isInline";
const headings = ["h1", "h2", "h3", "h4", "h5", "h6"];
export const remarkablePluginHeadingId = (md, options = {}) => {
const renderer = md.renderer.rules.heading_open;
const targets = options.targets ?? headings;
resetIdx();
md.renderer.rules.heading_open = (tokens, tokensIdx) => {
const headingOpenToken = tokens[tokensIdx];
if (!isHeadingOpenToken(headingOpenToken)) {
throw new Error("remarkablePluginHeadingId should take heading tag token, but got" +
JSON.stringify(headingOpenToken));
}
const defaultResult = renderer(tokens, tokensIdx);
// TODO textToken is inferred as HeadingOpenToken, but should be inferred TagToken
const textToken = tokens[tokensIdx + 1];
if (!isInline(textToken)) {
throw new Error("remarkablePluginHeadingId should take text token next to heading open token, but got" +
JSON.stringify(textToken));
}
const headingTagContent = textToken.content ?? "";
const result = (() => {
const hLevel = `h${headingOpenToken.hLevel}`;
if (!targets.includes(hLevel)) {
return defaultResult;
}
if (!options.createId) {
const result = defaultResult.replace(">", ` id="${headingTagContent}">`);
incrementIdx();
return result;
}
else {
const result = defaultResult.replace(">", ` id="${options.createId(headingOpenToken.hLevel, headingTagContent, idx)}">`);
incrementIdx();
return result;
}
})();
return result;
};
};