myst-cli
Version:
Command line tools for MyST
60 lines (59 loc) • 2.06 kB
JavaScript
import { InlineCite } from 'citation-js-utils';
import { RuleId } from 'myst-common';
import { selectAll } from 'unist-util-select';
import { addWarningForFile } from '../utils/addWarningForFile.js';
function pushCite(references, citeRenderer, label) {
if (!references.cite) {
references.cite = { order: [], data: {} };
}
if (!references.cite.data[label]) {
references.cite.order.push(label);
references.cite.data[label] = {
label,
enumerator: `${references.cite.order.length}`,
doi: citeRenderer[label]?.getDOI(),
html: citeRenderer[label]?.render(),
url: citeRenderer[label]?.getURL(),
};
}
return references.cite.data[label].enumerator;
}
function addCitationChildren(session, file, cite, renderer) {
const render = renderer[cite.label];
if (!render) {
cite.error = 'not found';
return false;
}
let children;
try {
children = render.inline(cite.kind === 'narrative' ? InlineCite.t : InlineCite.p, {
prefix: cite.prefix,
suffix: cite.suffix,
partial: cite.partial,
});
}
catch (error) {
addWarningForFile(session, file, `Citation failed to render for label: ${cite.label}`, 'error', {
ruleId: RuleId.citationRenders,
});
cite.error = 'rendering error';
return false;
}
if (!hasChildren(cite))
cite.children = children;
delete cite.error;
return true;
}
function hasChildren(node) {
return node.children && node.children.length > 0;
}
export function transformCitations(session, file, mdast, renderer, references) {
const citations = selectAll('cite', mdast);
citations.forEach((cite) => {
const citeLabel = cite.label;
// push cites in order of appearance in the document
const success = addCitationChildren(session, file, cite, renderer);
if (success)
cite.enumerator = pushCite(references, renderer, citeLabel);
});
}