Tofu/scripts/import-recipes/odt/decodeXmlEntities.js
2026-09-18 01:41:02 +02:00

20 lines
954 B
JavaScript

import { XML_ENTITIES } from '#import-recipes/odt/XML_ENTITIES.js'
const ENTITY_PATTERN = /&(#[0-9]+|#[xX][0-9a-fA-F]+|[a-zA-Z]+);/g
const MAX_CODE_POINT = 0x10ffff
// Replaces XML character references by the characters they stand for. An
// unknown or out-of-range reference is left untouched rather than dropped:
// losing text silently would be worse than showing `&foo;` in a recipe.
export function decodeXmlEntities(text) {
if (typeof text !== 'string') return ''
return text.replace(ENTITY_PATTERN, function decodeOne(match, body) {
if (body[0] !== '#') return XML_ENTITIES[body] ?? match
const isHexadecimal = body[1] === 'x' || body[1] === 'X'
const codePoint = isHexadecimal
? Number.parseInt(body.slice(2), 16)
: Number.parseInt(body.slice(1), 10)
const inRange = Number.isInteger(codePoint) && codePoint >= 0 && codePoint <= MAX_CODE_POINT
return inRange ? String.fromCodePoint(codePoint) : match
})
}