20 lines
954 B
JavaScript
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
|
|
})
|
|
}
|