76 lines
2.4 KiB
TypeScript
76 lines
2.4 KiB
TypeScript
/**
|
|
* Splits a string into two parts: the first line and the rest of the string.
|
|
* Returns an object indicating whether an end-of-line (EOL) character was found.
|
|
* If the string ends with a line break, `rest` is set to `undefined`.
|
|
* Supports both Unix (`\n`) and Windows (`\r\n`) line breaks.
|
|
*/
|
|
export const splitFirstLine = (str: string): SplitFirstLineResult => {
|
|
const firstEolIndex = str.indexOf('\n');
|
|
if (firstEolIndex === -1) {
|
|
return { first: str, rest: undefined, eol: false };
|
|
}
|
|
|
|
const isEolCrLf = firstEolIndex > 0 && str[firstEolIndex - 1] === '\r';
|
|
const foundEolLength = isEolCrLf ? 2 : 1;
|
|
const firstEolAtEnd = firstEolIndex === str.length - foundEolLength;
|
|
if (firstEolAtEnd) {
|
|
return { first: str, rest: undefined, eol: true };
|
|
}
|
|
|
|
const first = str.substring(0, firstEolIndex + foundEolLength);
|
|
const rest = str.substring(firstEolIndex + foundEolLength);
|
|
const eol = rest[rest.length - 1] === '\n';
|
|
return { first, rest, eol };
|
|
};
|
|
type SplitFirstLineResult = {
|
|
first: string;
|
|
rest: string | undefined;
|
|
eol: boolean;
|
|
};
|
|
|
|
|
|
/**
|
|
* Strips the last end-of-line (EOL) character from a string.
|
|
*/
|
|
export const stripLastEol = (str: string) => {
|
|
if (str.endsWith('\r\n')) {
|
|
return {
|
|
str: str.slice(0, -2),
|
|
eol: '\r\n',
|
|
}
|
|
} else if (str.endsWith('\n')) {
|
|
return {
|
|
str: str.slice(0, -1),
|
|
eol: '\n',
|
|
}
|
|
}
|
|
return { str, eol: '' };
|
|
}
|
|
|
|
|
|
/**
|
|
* Adds a given prefix to each line in the input string.
|
|
* Does not add a prefix to the very last empty line, if it exists.
|
|
* Efficiently handles strings without line breaks by returning the prefixed string.
|
|
*/
|
|
export const prefixMultiline = (str: string, prefix: string): string => {
|
|
if (str.length === 0 || str === '\n') return '';
|
|
let newlineIndex = str.indexOf('\n');
|
|
|
|
// If there is no newline, append the whole string and return
|
|
if (newlineIndex === -1 || newlineIndex === str.length - 1) {
|
|
return prefix + str;
|
|
}
|
|
|
|
let result = prefix; // Start by prefixing the first line
|
|
let start = 0;
|
|
while (newlineIndex !== -1 && newlineIndex !== str.length - 1) {
|
|
result += str.substring(start, newlineIndex + 1) + prefix;
|
|
start = newlineIndex + 1;
|
|
newlineIndex = str.indexOf('\n', start);
|
|
}
|
|
|
|
// Append the remaining part of the string after the last newline
|
|
return result + str.substring(start);
|
|
};
|