astro-ghostcms/.pnpm-store/v3/files/93/6ea5533e96a6387b9f6dc05c909...

66 lines
1.2 KiB
Plaintext

import stripAnsi from 'strip-ansi';
import eastAsianWidth from 'eastasianwidth';
import emojiRegex from 'emoji-regex';
export default function stringWidth(string, options) {
if (typeof string !== 'string' || string.length === 0) {
return 0;
}
options = {
ambiguousIsNarrow: true,
countAnsiEscapeCodes: false,
...options,
};
if (!options.countAnsiEscapeCodes) {
string = stripAnsi(string);
}
if (string.length === 0) {
return 0;
}
const ambiguousCharacterWidth = options.ambiguousIsNarrow ? 1 : 2;
let width = 0;
for (const {segment: character} of new Intl.Segmenter().segment(string)) {
const codePoint = character.codePointAt(0);
// Ignore control characters
if (codePoint <= 0x1F || (codePoint >= 0x7F && codePoint <= 0x9F)) {
continue;
}
// Ignore combining characters
if (codePoint >= 0x3_00 && codePoint <= 0x3_6F) {
continue;
}
if (emojiRegex().test(character)) {
width += 2;
continue;
}
const code = eastAsianWidth.eastAsianWidth(character);
switch (code) {
case 'F':
case 'W': {
width += 2;
break;
}
case 'A': {
width += ambiguousCharacterWidth;
break;
}
default: {
width += 1;
}
}
}
return width;
}