UNPKG

tty-strings

Version:

Tools for working with strings displayed in the terminal

62 lines 2.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const stripAnsi_1 = require("./stripAnsi"); const graphemeBreak_1 = require("./graphemeBreak"); /** * Get the length of a string in grapheme clusters. ANSI escape codes will be ignored. * * @remarks * This function is an implementation of UAX #29 grapheme cluster boundary splitting: * {@link https://www.unicode.org/reports/tr29/tr29-21.html#Grapheme_Cluster_Boundaries} * * @example * ```ts * import { stringLength } from 'tty-strings'; * * // '🏳️‍🌈'.length === 6 * const len = stringLength('🏳️‍🌈'); // 1 * ``` * * @param string - Input string to measure. * @returns The length of the string in graphemes. */ function stringLength(string) { if (typeof string !== 'string') return 0; // strip all ansi control chars const str = (0, stripAnsi_1.default)(string); // check if input is an empty string after stripping ansi if (str.length === 0) return 0; // initialize character count let count = 1, // initialize array to store grapheme break properties props = [], // get first code point cp = str.codePointAt(0), // get grapheme break property of the first code point prev = (0, graphemeBreak_1.graphemeBreakProperty)(cp); // iterate through each code point in the string for (let i = cp > 0xFFFF ? 2 : 1, n = str.length; i < n; i += 1) { cp = str.codePointAt(i); // get grapheme break property of the next code point const next = (0, graphemeBreak_1.graphemeBreakProperty)(cp); // check if there is a cluster boundary between the two adjacent code points if ((0, graphemeBreak_1.shouldBreak)(props, prev, next)) { // a cluster boundry exists, increment the character count count += 1; // reset grapheme break properties array props = []; } else props.push(prev); // ignore surrogates if (cp > 0xFFFF) i += 1; prev = next; } // return the character count return count; } exports.default = stringLength; //# sourceMappingURL=stringLength.js.map