myst-to-jats
Version:
Export from MyST Markdown to JATS
109 lines (108 loc) • 4.64 kB
JavaScript
import { selectAll } from 'unist-util-select';
const CONTAINER_KINDS = ['figure', 'table', 'code', 'quote'];
function updateInventory(node, key, idPrefix, inventory) {
var _a;
const keyInv = (_a = inventory[key]) !== null && _a !== void 0 ? _a : { count: 0, lookup: {} };
keyInv.count += 1;
const newId = typeof idPrefix === 'function' ? idPrefix(keyInv.count) : `${idPrefix}-${keyInv.count}`;
if (node.identifier) {
keyInv.lookup[node.identifier] = newId;
}
node.identifier = newId;
inventory[key] = keyInv;
}
/**
* Traverse mdast tree, find reference targets, and replace them with simple identifiers
*
* This builds a map of old identifiers to new identifiers, subsequently used
* for updating references. Modified nodes include sections, containers,
* footnotes, inlineExpressions, math, and citations.
*/
export function referenceTargetTransform(mdast, inventory, citations) {
const sections = selectAll('section', mdast);
sections.forEach((sec) => {
updateInventory(sec, 'section', 'sec', inventory);
});
const expressions = selectAll('inlineExpression', mdast);
expressions.forEach((expr) => {
updateInventory(expr, 'expression', 'expr', inventory);
});
const equations = selectAll('math', mdast);
equations.forEach((eq) => {
updateInventory(eq, 'equation', 'eq', inventory);
});
const footnotes = selectAll('footnoteDefinition', mdast);
footnotes.forEach((fn) => {
updateInventory(fn, 'footnote', 'fn', inventory);
});
const proofs = selectAll('proof', mdast);
proofs.forEach((fn) => {
updateInventory(fn, 'proof', 'stm', inventory);
});
const containers = selectAll('container', mdast);
containers.forEach((container) => {
if (!container.kind || !CONTAINER_KINDS.includes(container.kind)) {
return;
}
updateInventory(container, container.kind, container.kind, inventory);
});
if (!citations)
return;
const citationIds = Object.keys(citations);
citationIds.forEach((citationId) => {
var _a;
(_a = inventory.cite) !== null && _a !== void 0 ? _a : (inventory.cite = { count: 0, lookup: {} });
if (!inventory.cite.lookup[citationId]) {
inventory.cite.count += 1;
const newId = `ref-${inventory.cite.count}`;
inventory.cite.lookup[citationId] = newId;
citations[newId] = citations[citationId];
}
delete citations[citationId];
});
}
/**
* Use reference lookup from referenceTargetTransform to update cross references
*/
export function referenceResolutionTransform(mdast, inventory) {
var _a, _b, _c, _d, _e, _f, _g, _h;
const xrefs = selectAll('crossReference', mdast);
const lookup = {
...(_a = inventory.section) === null || _a === void 0 ? void 0 : _a.lookup,
...(_b = inventory.expression) === null || _b === void 0 ? void 0 : _b.lookup,
...(_c = inventory.equation) === null || _c === void 0 ? void 0 : _c.lookup,
...(_d = inventory.figure) === null || _d === void 0 ? void 0 : _d.lookup,
...(_e = inventory.table) === null || _e === void 0 ? void 0 : _e.lookup,
...(_f = inventory.code) === null || _f === void 0 ? void 0 : _f.lookup,
...(_g = inventory.quote) === null || _g === void 0 ? void 0 : _g.lookup,
...(_h = inventory.proof) === null || _h === void 0 ? void 0 : _h.lookup,
};
xrefs.forEach((xref) => {
if (xref.identifier && lookup[xref.identifier]) {
xref.identifier = lookup[xref.identifier];
}
});
const supplements = selectAll('supplementaryMaterial', mdast);
supplements.forEach((supp) => {
if (supp.figIdentifier && lookup[supp.figIdentifier]) {
supp.figIdentifier = lookup[supp.figIdentifier];
}
if (supp.embedIdentifier && lookup[supp.embedIdentifier]) {
supp.embedIdentifier = lookup[supp.embedIdentifier];
}
});
const footnotes = selectAll('footnoteReference', mdast);
footnotes.forEach((fn) => {
var _a;
if (fn.identifier && ((_a = inventory.footnote) === null || _a === void 0 ? void 0 : _a.lookup[fn.identifier])) {
fn.identifier = inventory.footnote.lookup[fn.identifier];
}
});
const citations = selectAll('cite', mdast);
citations.forEach((cite) => {
var _a;
if (cite.label && ((_a = inventory.cite) === null || _a === void 0 ? void 0 : _a.lookup[cite.label])) {
cite.label = inventory.cite.lookup[cite.label];
}
});
}