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.
		
		
		
		
		
			
		
			
				
					
					
						
							59 lines
						
					
					
						
							1.3 KiB
						
					
					
				
			
		
		
	
	
							59 lines
						
					
					
						
							1.3 KiB
						
					
					
				'use strict'; | 
						|
const isFullwidthCodePoint = require('is-fullwidth-code-point'); | 
						|
const astralRegex = require('astral-regex'); | 
						|
const ansiStyles = require('ansi-styles'); | 
						|
 | 
						|
const ESCAPES = [ | 
						|
	'\u001B', | 
						|
	'\u009B' | 
						|
]; | 
						|
 | 
						|
const END_CODE = 39; | 
						|
 | 
						|
const wrapAnsi = code => `${ESCAPES[0]}[${code}m`; | 
						|
 | 
						|
module.exports = (str, begin, end) => { | 
						|
	const arr = [...str.normalize()]; | 
						|
 | 
						|
	end = typeof end === 'number' ? end : arr.length; | 
						|
 | 
						|
	let insideEscape = false; | 
						|
	let escapeCode = null; | 
						|
	let visible = 0; | 
						|
	let output = ''; | 
						|
 | 
						|
	for (const [i, x] of arr.entries()) { | 
						|
		let leftEscape = false; | 
						|
 | 
						|
		if (ESCAPES.includes(x)) { | 
						|
			insideEscape = true; | 
						|
			const code = /\d[^m]*/.exec(str.slice(i, i + 18)); | 
						|
			escapeCode = code === END_CODE ? null : code; | 
						|
		} else if (insideEscape && x === 'm') { | 
						|
			insideEscape = false; | 
						|
			leftEscape = true; | 
						|
		} | 
						|
 | 
						|
		if (!insideEscape && !leftEscape) { | 
						|
			++visible; | 
						|
		} | 
						|
 | 
						|
		if (!astralRegex({exact: true}).test(x) && isFullwidthCodePoint(x.codePointAt())) { | 
						|
			++visible; | 
						|
		} | 
						|
 | 
						|
		if (visible > begin && visible <= end) { | 
						|
			output += x; | 
						|
		} else if (visible === begin && !insideEscape && escapeCode !== null && escapeCode !== END_CODE) { | 
						|
			output += wrapAnsi(escapeCode); | 
						|
		} else if (visible >= end) { | 
						|
			if (escapeCode !== null) { | 
						|
				output += wrapAnsi(ansiStyles.codes.get(parseInt(escapeCode, 10)) || END_CODE); | 
						|
			} | 
						|
 | 
						|
			break; | 
						|
		} | 
						|
	} | 
						|
 | 
						|
	return output; | 
						|
};
 | 
						|
 |