docusaurus-numbered-headings
Version:
A Docusaurus plugin that automatically adds numbered headings with support for ISO 2145 and USA Classic numbering conventions
86 lines (85 loc) • 3.26 kB
JavaScript
;
/**
* Remark plugin that drives per-document numbered-heading behavior via frontmatter.
*
* Wire it into your Docusaurus docs preset:
*
* const { remarkFrontmatterToggle } = require("docusaurus-numbered-headings");
* // ...
* docs: { remarkPlugins: [remarkFrontmatterToggle], ... }
*
* Then in any MDX file, control numbering with the `numbered_headings` frontmatter
* key:
*
* ---
* numbered_headings: false # disable auto-numbering on this page
* numbered_headings: "iso-2145" # force ISO 2145 (1, 1.1, 1.1.1)
* numbered_headings: "usa-classic" # force USA Classic (I, A, 1, a)
* numbered_headings: "spanish-forense" # force Spanish forensic (I, Primero.-, 1, a)
* numbered_headings: true # explicit default (same as unset)
* ---
*
* When set, the plugin wraps the document body in a `<div className="…">` carrying:
* - `disable_numbered_headings` for `false`
* - `numbered_headings_iso_2145` for `"iso-2145"`
* - `numbered_headings_usa_classic` for `"usa-classic"`
* - `numbered_headings_spanish_forense` for `"spanish-forense"`
*
* Plugin CSS recognizes those classes and applies (or suppresses) the right
* counters. The right-rail Table of Contents is scoped via `:root:has(...)`
* since it lives outside the wrapped document body.
*
* Compatible with Docusaurus 3+, which exposes parsed frontmatter on
* `file.data.frontMatter`.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.remarkFrontmatterToggle = void 0;
const TOP_LEVEL_PRESERVE = new Set(["mdxjsEsm", "yaml", "toml"]);
function classForFrontmatter(value) {
if (value === false)
return "disable_numbered_headings";
if (value === "iso-2145")
return "numbered_headings_iso_2145";
if (value === "usa-classic")
return "numbered_headings_usa_classic";
if (value === "spanish-forense")
return "numbered_headings_spanish_forense";
// `true`, `undefined`, or anything else: no override, use the global default.
return null;
}
function remarkFrontmatterToggle() {
return (tree, file) => {
var _a;
const fm = (_a = file === null || file === void 0 ? void 0 : file.data) === null || _a === void 0 ? void 0 : _a.frontMatter;
if (!fm)
return;
const wrapperClass = classForFrontmatter(fm.numbered_headings);
if (!wrapperClass)
return;
const preserved = [];
const wrapped = [];
for (const child of tree.children) {
if (TOP_LEVEL_PRESERVE.has(child.type)) {
preserved.push(child);
}
else {
wrapped.push(child);
}
}
const wrapper = {
type: "mdxJsxFlowElement",
name: "div",
attributes: [
{
type: "mdxJsxAttribute",
name: "className",
value: wrapperClass,
},
],
children: wrapped,
};
tree.children = [...preserved, wrapper];
};
}
exports.remarkFrontmatterToggle = remarkFrontmatterToggle;
exports.default = remarkFrontmatterToggle;