UNPKG

jats-xml

Version:

Types and utilities for working with JATS in Typescript

119 lines (118 loc) 4.9 kB
import { toText } from 'myst-common'; import { doi } from 'doi-utils'; import { select, selectAll } from 'unist-util-select'; import { Tags } from 'jats-tags'; import { remove } from 'unist-util-remove'; export function findArticleId(node, pubIdType = 'doi') { if (!node) return undefined; const id = select(`[pub-id-type=${pubIdType}]`, node); if (id && toText(id)) return toText(id); const doiTag = selectAll(`${Tags.articleId},${Tags.pubId}`, node).find((t) => doi.validate(toText(t))); return toText(doiTag) || undefined; } export function processContributor(contrib) { const author = { name: `${toText(select(Tags.givenNames, contrib))} ${toText(select(Tags.surname, contrib))}`, }; const orcid = select('[contrib-id-type=orcid]', contrib); if (orcid) { author.orcid = toText(orcid).replace(/(https?:\/\/)?orcid\.org\//, ''); } const affiliationRefs = selectAll('xref[ref-type=aff]', contrib); const affiliationIds = affiliationRefs.map((xref) => xref.rid); if (affiliationIds.length > 0) { author.affiliations = affiliationIds; } const uri = select('uri', contrib); if (uri === null || uri === void 0 ? void 0 : uri['xlink:href']) { author.url = uri['xlink:href']; } // If there are no aff xrefs AND contrib is in a contrib group with affs AND those affs do not have IDs, add them as affiliations... return author; } /** * Perform standard toText, trim, remove trailing comma and semicolon * * Additionally, this returns undefined instead of empty string if node is undefined */ function toTextAndTrim(content) { const text = toText(content); if (!text) return undefined; return text.replace(/^[\s;,]+/, '').replace(/[\s;,]+$/, ''); } function markForDeletion(nodes) { nodes.forEach((node) => { if (node) node.type = '__delete__'; }); } export function processAffiliation(aff) { var _a, _b; const id = aff.id; let ror; let isni; const rorNode = select(`institution-id[institution-id-type=ror]`, aff); if (rorNode) { ror = toTextAndTrim(rorNode); } const isniNode = select(`institution-id[institution-id-type=ISNI]`, aff); if (isniNode) { isni = toTextAndTrim(isniNode); } markForDeletion(selectAll('institution-id', aff)); remove(aff, '__delete__'); const institutions = selectAll('institution', aff); const textAddress = selectAll('addr-line > text', aff); const namedContent = selectAll('named-content', aff); const departmentNode = (_a = institutions.find((inst) => inst['content-type'] === 'dept')) !== null && _a !== void 0 ? _a : namedContent.find((content) => content['content-type'] === 'organisation-division'); const addressNode = namedContent.find((content) => content['content-type'] === 'street'); const cityNode = namedContent.find((content) => content['content-type'] === 'city'); const stateNode = namedContent.find((content) => content['content-type'] === 'country-part'); const postalCodeNode = namedContent.find((content) => content['content-type'] === 'post-code'); const countryNode = (_b = select('country', aff)) !== null && _b !== void 0 ? _b : namedContent.find((content) => content['content-type'] === 'country'); markForDeletion([ ...textAddress, ...namedContent, departmentNode, addressNode, cityNode, stateNode, postalCodeNode, countryNode, ]); remove(aff, '__delete__'); const affChildren = aff.children.filter((child) => child.type !== 'label'); let institution; if (affChildren.filter((child) => ['text', 'institution-wrap', 'institution'].includes(child.type)) .length === affChildren.length) { institution = toTextAndTrim(affChildren); } else { institution = toTextAndTrim(institutions.find((inst) => inst['content-type'] !== 'dept')); } const addressLines = textAddress .map((line) => toTextAndTrim(line)) .filter((line) => !!line); let department = departmentNode ? toTextAndTrim(departmentNode) : addressLines.find((line) => line.toLowerCase().includes('department')); let address = addressNode ? toTextAndTrim(addressNode) : addressLines.find((line) => !line.toLowerCase().includes('department')); if (address && !institution) { institution = address; address = undefined; } if (department && !institution) { institution = department; department = undefined; } const city = toTextAndTrim(cityNode); const state = toTextAndTrim(stateNode); const postal_code = toTextAndTrim(postalCodeNode); const country = toTextAndTrim(countryNode); return { id, ror, isni, department, institution, address, city, state, postal_code, country }; }