const parseIndex = (input: number | string, length: number): number => { if (typeof input === 'number') { return Math.trunc(input) } const token = String(input).trim() if (token === 'end') { return length - 1 } const endOffset = token.match(/^end-(\d+)$/) if (endOffset?.[1]) { return length - 1 - Number(endOffset[1]) } return Math.trunc(Number(token)) } export function range(str: string, first: number | string, last: number | string): string { // discuss at: https://locutus.io/tcl/range/ // parity verified: Tcl 8.6 // original by: Kevin van Zonneveld (https://kvz.io) // example 1: range('Hello World', 0, 4) // returns 1: 'Hello' // example 2: range('Hello World', 6, 'end') // returns 2: 'World' // example 3: range('abcdef', 1, 'end-1') // returns 3: 'bcde' const value = String(str) const len = value.length let start = parseIndex(first, len) let end = parseIndex(last, len) if (!Number.isFinite(start)) { start = 0 } if (!Number.isFinite(end)) { end = -1 } start = Math.max(0, start) end = Math.min(len - 1, end) if (start > end || len === 0) { return '' } return value.slice(start, end + 1) }