tfrere's picture
tfrere HF Staff
refactor(backend/publisher): transformer pipeline + shared registry + shiki highlighting
7843436
Raw
History Blame Contribute Delete
1.66 kB
import { parseHTML } from "linkedom";
import type { Transformer } from "./types.js";
/**
* Add id anchors to bibliography entries so inline citations can link to them.
* citation-js outputs entries as `<div class="csl-entry">` elements; we tag each
* with `id="ref-<key>"` in the order specified by `citationData.orderedKeys`.
*/
function addBibliographyAnchors(html: string, orderedKeys: string[]): string {
const { document } = parseHTML(`<!DOCTYPE html><html><body>${html}</body></html>`);
const entries = document.querySelectorAll(".csl-entry");
entries.forEach((entry, idx) => {
const key = orderedKeys[idx] || `entry-${idx}`;
entry.setAttribute("id", `ref-${key}`);
});
return document.body.innerHTML;
}
/**
* Inject the pre-formatted bibliography HTML into the placeholder
* `<div data-type="bibliography">` left by the TipTap extension.
* Falls back to an empty-state message when there are no citations.
*/
export const bibliographyTransformer: Transformer = {
name: "bibliography",
apply(document, ctx) {
for (const div of [...document.querySelectorAll('div[data-type="bibliography"]')]) {
div.removeAttribute("renderedhtml");
if (ctx.biblioHtml) {
let enriched = ctx.biblioHtml;
if (ctx.citationData && ctx.citationData.orderedKeys.length > 0) {
enriched = addBibliographyAnchors(ctx.biblioHtml, ctx.citationData.orderedKeys);
}
div.innerHTML = `<h2 class="bibliography-title">References</h2><div class="bibliography-content">${enriched}</div>`;
} else {
div.innerHTML = `<p class="bibliography-empty">No citations</p>`;
}
}
},
};