UNPKG

entities

Version:

Encode & decode XML and HTML entities with ease & speed

70 lines (62 loc) 2.46 kB
// Adapted from https://github.com/mathiasbynens/he/blob/36afe179392226cf1b6ccdb16ebbb7a5a844d93a/src/he.js#L106-L134 /** * C1 Unicode control character reference replacements (code points 128–159). * Index i gives the replacement for code point 128+i; 0 means "no replacement". */ const c1: number[] = [ 8364, 0, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249, 338, 0, 381, 0, 0, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250, 339, 0, 382, 376, ]; /** * True for NUL, UTF-16 surrogates, and values past U+10FFFF. * @param codePoint Unicode code point to check. */ function isInvalidCodePoint(codePoint: number): boolean { return ( codePoint === 0 || (codePoint >= 0xd8_00 && codePoint <= 0xdf_ff) || codePoint > 0x10_ff_ff ); } /** * Replace the given code point with U+FFFD if it is NUL (0), a surrogate, or * outside the valid Unicode range. Code points in the C1 controls range * (128–159) are remapped to their Windows-1252 equivalents, following the * HTML spec. All other code points are returned unchanged. * @param codePoint Unicode code point to convert. */ export function replaceCodePoint(codePoint: number): number { if (isInvalidCodePoint(codePoint)) { return 0xff_fd; } if (codePoint >= 128 && codePoint <= 159) { return c1[codePoint - 128] || codePoint; } return codePoint; } /** * XML numeric character references are the referenced Unicode code point. * Invalid values still become U+FFFD; the HTML Windows-1252 C1 remap is not * applied. * @see https://www.w3.org/TR/xml/#NT-CharRef * @param codePoint Unicode code point to convert. */ export function replaceCodePointXML(codePoint: number): number { return isInvalidCodePoint(codePoint) ? 0xff_fd : codePoint; } /** * Convert the code point of a decoded numeric entity to a string, replacing * invalid values. * * Fast path for plain BMP code points: [1..0x7F] and [0xA0..0xD7FF] pass * `replaceCodePoint` unchanged (no NUL, C1 remap, surrogate, or out-of-range * handling) and fit a single charCode. 0xd760 = 0xD800 (the first surrogate) * - 0xA0. * @param codePoint Unicode code point to convert. */ export function codePointToString(codePoint: number): string { return (codePoint - 1) >>> 0 < 0x7f || (codePoint - 0xa0) >>> 0 < 0xd7_60 ? String.fromCharCode(codePoint) : String.fromCodePoint(replaceCodePoint(codePoint)); }