UNPKG

jats-utils

Version:

Utility functions for working with JATS in Typescript

129 lines (128 loc) 4.19 kB
import { toText } from 'myst-common'; import { select } from 'unist-util-select'; export function convertToUnist(node) { switch (node.type) { case 'element': { const { name, attributes, elements } = node; const children = elements === null || elements === void 0 ? void 0 : elements.map(convertToUnist).filter((n) => !!n); const { type, ...attrs } = attributes !== null && attributes !== void 0 ? attributes : {}; if (type !== undefined) attrs._type = type; const next = { type: name !== null && name !== void 0 ? name : 'unknown', ...attrs }; if (name === 'code') { next.value = elements === null || elements === void 0 ? void 0 : elements[0].text; } else if (children) next.children = children; return next; } case 'text': { const { attributes, text } = node; return { type: 'text', ...attributes, value: String(text).replace(/\n(\s+)$/, ''), }; } case 'cdata': { const { attributes, cdata } = node; return { type: 'cdata', ...attributes, cdata: String(cdata).trim(), }; } case 'comment': { const { comment } = node; return { type: 'comment', value: String(comment) }; } case 'instruction': { // For example: // <?properties manuscript?> becomes: // { type: 'instruction', name: 'properties', instruction: 'manuscript' } return undefined; } default: console.log(node); throw new Error(`found ${node.type} ${node.name}`); } } export function convertToXml(node) { const { type, ...rest } = node; switch (type) { case 'text': { const { value, ...attributes } = rest; return { type: 'text', attributes, text: value }; } case 'code': { const { value, ...attributes } = rest; return { type: 'element', name: type, attributes, elements: [{ type: 'text', text: value }] }; } case 'comment': { return { type: 'comment', comment: rest.value }; } case 'cdata': { const { cdata, ...attributes } = rest; return { type: 'cdata', attributes, cdata }; } default: { const { children, _type, ...attributes } = rest; if (_type !== undefined) attributes.type = _type; return { type: 'element', name: type, attributes, elements: children === null || children === void 0 ? void 0 : children.map(convertToXml) }; } } } export function escapeForXML(text) { return text.replace(/&(?!amp;)/g, '&amp;').replace(/</g, '&lt;'); } const MonthLookup = { jan: 0, january: 0, feb: 1, february: 1, mar: 2, march: 2, apr: 3, april: 3, may: 4, jun: 5, june: 5, jul: 6, july: 6, aug: 7, august: 7, sep: 8, sept: 8, september: 8, oct: 9, october: 9, nov: 10, november: 10, dec: 11, december: 11, }; export function toDate(date) { if (!date) return; const isoDate = date['iso-8601-date']; if (isoDate) return new Date(isoDate); const year = Number(toText(select('year', date))); if (!year || Number.isNaN(year)) return; const monthText = toText(select('month', date)); const monthTextNumber = Number(monthText); const month = Number.isNaN(monthTextNumber) ? MonthLookup[monthText] : monthTextNumber - 1; if (month == null) return new Date(Date.UTC(year, 0)); const day = Number(toText(select('day', date))); if (!day || Number.isNaN(day)) return new Date(Date.UTC(year, month)); return new Date(Date.UTC(year, month, day)); } export function formatDate(date) { if (!date) return; return new Intl.DateTimeFormat('en-US', { dateStyle: 'long', timeZone: 'UTC' }).format(date); }