70 lines
2.4 KiB
JavaScript
70 lines
2.4 KiB
JavaScript
import isFullwidthCodePoint from "is-fullwidth-code-point";
|
|
import { ESCAPES, getEndCode, linkStartCodePrefix, linkStartCodePrefixCharCodes, } from "./ansiCodes.js";
|
|
function findNumberIndex(str) {
|
|
for (let index = 0; index < str.length; index++) {
|
|
const charCode = str.charCodeAt(index);
|
|
if (charCode >= 48 && charCode <= 57) {
|
|
return index;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
function parseLinkCode(string, offset) {
|
|
string = string.slice(offset);
|
|
for (let index = 1; index < linkStartCodePrefixCharCodes.length; index++) {
|
|
if (string.charCodeAt(index) !== linkStartCodePrefixCharCodes[index]) {
|
|
return undefined;
|
|
}
|
|
}
|
|
// This is a link code (with or without the URL part). Find the end of it.
|
|
const endIndex = string.indexOf("\x07", linkStartCodePrefix.length);
|
|
if (endIndex === -1)
|
|
return undefined;
|
|
return string.slice(0, endIndex + 1);
|
|
}
|
|
function parseAnsiCode(string, offset) {
|
|
string = string.slice(offset, offset + 19);
|
|
const startIndex = findNumberIndex(string);
|
|
if (startIndex !== -1) {
|
|
let endIndex = string.indexOf("m", startIndex);
|
|
if (endIndex === -1) {
|
|
endIndex = string.length;
|
|
}
|
|
return string.slice(0, endIndex + 1);
|
|
}
|
|
}
|
|
export function tokenize(str, endChar = Number.POSITIVE_INFINITY) {
|
|
const ret = [];
|
|
let index = 0;
|
|
let visible = 0;
|
|
while (index < str.length) {
|
|
const codePoint = str.codePointAt(index);
|
|
if (ESCAPES.has(codePoint)) {
|
|
// TODO: We should probably decide on the next character ("[" or "]") which code path to take.
|
|
const code = parseLinkCode(str, index) || parseAnsiCode(str, index);
|
|
if (code) {
|
|
ret.push({
|
|
type: "ansi",
|
|
code,
|
|
endCode: getEndCode(code),
|
|
});
|
|
index += code.length;
|
|
continue;
|
|
}
|
|
}
|
|
const fullWidth = isFullwidthCodePoint(codePoint);
|
|
const character = String.fromCodePoint(codePoint);
|
|
ret.push({
|
|
type: "char",
|
|
value: character,
|
|
fullWidth,
|
|
});
|
|
index += character.length;
|
|
visible += fullWidth ? 2 : character.length;
|
|
if (visible >= endChar) {
|
|
break;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
//# sourceMappingURL=tokenize.js.map
|