+ definition_list: {
+ enter: (e) => {
+ const attributes = e.attributes ?? {};
+ if (
+ (attributes.class ?? "").split(/\s/gu).includes(
+ "timeline",
+ )
+ ) {
+ const years = new Map();
+ for (
+ const { children: [{ children: termChildren }, defn] }
+ of e.children
+ ) {
+ const { label, year } = (() => {
+ if (termChildren.length != 1) {
+ return { label: termChildren, year: termChildren };
+ } else {
+ const str = termChildren[0];
+ if (str.tag != "str") {
+ return {
+ label: termChildren,
+ year: termChildren,
+ };
+ } else {
+ const { text } = str;
+ return {
+ label: text,
+ year:
+ /^([0-9X]{4})(?:-[0-9X]{2}(?:-[0-9X]{2})?)?$/u
+ .exec(text)?.[1] ?? text,
+ };
+ }
+ }
+ })();
+ const yearList = (() => {
+ const result = {
+ tag: "bullet_list",
+ tight: false,
+ style: "-",
+ children: [],
+ };
+ if (years.has(year)) {
+ const yearMap = years.get(year);
+ if (yearMap.has(label)) {
+ return yearMap.get(label);
+ } else {
+ yearMap.set(label, result);
+ return result;
+ }
+ } else {
+ years.set(year, new Map([[label, result]]));
+ return result;
+ }
+ })();
+ const misc = { tag: "list_item", children: [] };
+ for (const child of defn.children) {
+ if (child.tag == "bullet_list") {
+ yearList.children.push(...child.children);
+ } else {
+ misc.children.push(child);
+ }
+ }
+ if (misc.children.length > 0) {
+ yearList.children.unshift(misc);
+ } else {
+ /* do nothing */
+ }
+ }
+ const sorted = [...years].sort(([a], [b]) =>
+ typeof a != "string" || isNaN(a) ||
+ typeof b != "string" || isNaN(b) || +a == +b
+ ? 0
+ : 1 - 2 * (+a < b)
+ );
+ sorted.forEach((pair) =>
+ pair[1] = [...pair[1]].sort(([a], [b]) =>
+ 1 - 2 * (a < b)
+ )
+ );
+ return {
+ tag: "div",
+ attributes,
+ children: sorted.flatMap(([year, yearDef]) => [
+ rawBlock`<details open="">`,
+ rawBlock`<summary>`,
+ ...(Array.isArray(year) ? year : [str`${year}`]),
+ rawBlock`</summary>`,
+ rawBlock`<dl>`,
+ ...yearDef.map(([label, list]) => ({
+ tag: "div",
+ children: [
+ rawBlock`<dt>`,
+ ...(Array.isArray(label) ? label : [str`${label}`]),
+ rawBlock`</dt>`,
+ rawBlock`<dd>`,
+ list,
+ rawBlock`</dd>`,
+ ],
+ })),
+ rawBlock`</dl>`,
+ rawBlock`</details>`,
+ ]),
+ };
+ } else {
+ /* do nothing */
+ }
+ },
+ exit: (_) => {},
+ },