Skip to the content

Capsid menu

app/lib/publications/entities.mjs

37 lines and 3 functions in DrDustinEdwards/dustinedwards-info, at commit 1590ba4 on 2026-10-24. This file on GitHub.

Functions

The functions of entities.mjs
FunctionLinesComplexityCoveredCRAPMutation
fromCodePoint21 to 276100%WatchCRAP 6No data: no mutants in this code
decodeEntities33 to 412100%OkCRAP 2No data: no mutants in this code
<anonymous:34>34 to 406100%WatchCRAP 6No data: no mutants in this code

Imports

It imports no other module of this repo. Imported by app/lib/cv/entries.mjs, app/lib/podcast/feed.mjs, app/lib/publications/article-json-ld.mjs, app/lib/publications/authors.mjs, app/lib/publications/citation-tags.mjs, app/lib/publications/coins.mjs, app/lib/publications/compile.mjs, app/lib/publications/exports.mjs, app/lib/publications/listing.mjs, app/lib/publications/search-inputs.mjs, app/lib/publications/twin.mjs, app/lib/seo.ts, app/routes/home.tsx, app/routes/publications.$slug.tsx, app/routes/publications.tsx.

Source

// Decoded where a person reads it, never at rest: check:machine-readable asserts no stored abstract
// contains <, which keeps registry text safe in JSON-LD and exports. One alternation in one pass, so
// &amp;lt; decodes to &lt; and stops. Unknown names are left verbatim on purpose.

const NAMED = {
  amp: "&",
  lt: "<",
  gt: ">",
  quot: '"',
  apos: "'",
};

const REFERENCE = /&(?:#(\d+)|#[xX]([0-9a-fA-F]+)|([a-zA-Z][a-zA-Z0-9]*));/g;

/**
 * String.fromCodePoint throws out of range, which would fail a render over one bad deposit.
 *
 * @param {number} code
 * @returns {string | null}
 */
function fromCodePoint(code) {
  // Zero too: &#0; is a NUL, which no reader should receive from a deposit or a feed.
  if (!Number.isInteger(code) || code < 1 || code > 0x10ffff) return null;
  // Lone surrogates are valid integers and produce unpaired halves.
  if (code >= 0xd800 && code <= 0xdfff) return null;
  return String.fromCodePoint(code);
}

/**
 * @param {string | null | undefined} text
 * @returns {string}
 */
export function decodeEntities(text) {
  return String(text ?? "").replace(REFERENCE, (whole, dec, hex, name) => {
    if (dec !== undefined) return fromCodePoint(Number(dec)) ?? whole;
    if (hex !== undefined) return fromCodePoint(Number.parseInt(hex, 16)) ?? whole;
    return Object.prototype.hasOwnProperty.call(NAMED, name)
      ? /** @type {string} */ (NAMED[/** @type {keyof NAMED} */ (name)])
      : whole;
  });
}