You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
'use strict';const isFullwidthCodePoint = require('is-fullwidth-code-point');const astralRegex = require('astral-regex');const ansiStyles = require('ansi-styles');
const ESCAPES = [ '\u001B', '\u009B'];
const wrapAnsi = code => `${ESCAPES[0]}[${code}m`;
const checkAnsi = (ansiCodes, isEscapes, endAnsiCode) => { let output = []; ansiCodes = [...ansiCodes];
for (let ansiCode of ansiCodes) { const ansiCodeOrigin = ansiCode; if (ansiCode.includes(';')) { ansiCode = ansiCode.split(';')[0][0] + '0'; }
const item = ansiStyles.codes.get(Number.parseInt(ansiCode, 10)); if (item) { const indexEscape = ansiCodes.indexOf(item.toString()); if (indexEscape === -1) { output.push(wrapAnsi(isEscapes ? item : ansiCodeOrigin)); } else { ansiCodes.splice(indexEscape, 1); } } else if (isEscapes) { output.push(wrapAnsi(0)); break; } else { output.push(wrapAnsi(ansiCodeOrigin)); } }
if (isEscapes) { output = output.filter((element, index) => output.indexOf(element) === index);
if (endAnsiCode !== undefined) { const fistEscapeCode = wrapAnsi(ansiStyles.codes.get(Number.parseInt(endAnsiCode, 10))); output = output.reduce((current, next) => next === fistEscapeCode ? [next, ...current] : [...current, next], []); } }
return output.join('');};
module.exports = (string, begin, end) => { const characters = [...string]; const ansiCodes = [];
let stringEnd = typeof end === 'number' ? end : characters.length; let isInsideEscape = false; let ansiCode; let visible = 0; let output = '';
for (const [index, character] of characters.entries()) { let leftEscape = false;
if (ESCAPES.includes(character)) { const code = /\d[^m]*/.exec(string.slice(index, index + 18)); ansiCode = code && code.length > 0 ? code[0] : undefined;
if (visible < stringEnd) { isInsideEscape = true;
if (ansiCode !== undefined) { ansiCodes.push(ansiCode); } } } else if (isInsideEscape && character === 'm') { isInsideEscape = false; leftEscape = true; }
if (!isInsideEscape && !leftEscape) { visible++; }
if (!astralRegex({exact: true}).test(character) && isFullwidthCodePoint(character.codePointAt())) { visible++;
if (typeof end !== 'number') { stringEnd++; } }
if (visible > begin && visible <= stringEnd) { output += character; } else if (visible === begin && !isInsideEscape && ansiCode !== undefined) { output = checkAnsi(ansiCodes); } else if (visible >= stringEnd) { output += checkAnsi(ansiCodes, true, ansiCode); break; } }
return output;};
|