UNPKG

remarkable-plugin-heading-id

Version:
42 lines (41 loc) 1.9 kB
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; }; };