meaw
Version:
Utilities for Unicode East Asian Width
79 lines (75 loc) • 2.15 kB
text/typescript
import type { EastAsianWidth } from "./types";
import { defs } from "./defs";
/**
* Gets the EAW property of a code point.
* @param codePoint Code point
* @return The EAW property of the code point
*/
function getEAWOfCodePointInternal(codePoint: number): EastAsianWidth {
let min = 0;
let max = defs.length - 1;
while (min !== max) {
const i = min + ((max - min) >> 1);
const [start, end, prop] = defs[i];
if (codePoint < start) {
max = i - 1;
} else if (codePoint > end) {
min = i + 1;
} else {
return prop;
}
}
return defs[min][2];
}
/**
* Gets the EAW property of a code point.
* @param codePoint Code point
* @return The EAW property of the code point
* @example
* import { getEAWOfCodePoint } from "meaw";
*
* // 0x3042 is the code point of 'あ' (U+3042)
* assert(getEAWOfCodePoint(0x3042) === "W");
*/
export function getEAWOfCodePoint(codePoint: number): EastAsianWidth | undefined {
if (!Number.isInteger(codePoint) || codePoint < 0 || 0x10ffff < codePoint) {
return undefined;
}
return getEAWOfCodePointInternal(codePoint);
}
/**
* Gets the EAW property of a character.
* @param str Character string
* @param pos Character position (in code unit) (default = 0)
* @return The EAW property of the character
* @example
* import { getEAW } from "meaw";
*
* // Narrow
* assert(getEAW("A") === "Na");
* // Wide
* assert(getEAW("あ") === "W");
* assert(getEAW("安") === "W");
* assert(getEAW("🍣") === "W");
* // Fullwidth
* assert(getEAW("A") === "F");
* // Halfwidth
* assert(getEAW("ア") === "H");
* // Ambiguous
* assert(getEAW("∀") === "A");
* assert(getEAW("→") === "A");
* assert(getEAW("Ω") === "A");
* assert(getEAW("Я") === "A");
* // Neutral
* assert(getEAW("ℵ") === "N");
*
* // character position (in code unit) can be specified
* assert(getEAW("ℵAあAア∀", 2) === "W");
*/
export function getEAW(str: string, pos: number = 0): EastAsianWidth | undefined {
const codePoint = str.codePointAt(pos);
if (codePoint === undefined) {
return undefined;
}
return getEAWOfCodePointInternal(codePoint);
}