core/normalizers/text.normalizer.ts
core/normalizers/text.normalizer.ts is a file in Bane's Lab Site. 82 lines of code and 27 definitions.
import { LINE_BREAK } from "#configuration/constants/code.constants";
import { SPACE } from "#configuration/constants/document.constants";
import type { TextPart } from "#types/markup.types";
const WHITESPACE = new Set([SPACE, LINE_BREAK, "\t", "\r"]);
const MAX_BREAKS = 2;
const FENCE_MARK = "```";
const ASCII_LIMIT = 128;
const isLetter = function isLetter(char: string): boolean {
const lower = char.toLowerCase();
return lower >= "a" && lower <= "z";
};
const isWordChar = function isWordChar(char: string): boolean {
const code = char.codePointAt(0) ?? 0;
return isLetter(char) || (char >= "0" && char <= "9") || code >= ASCII_LIMIT;
};
const isSpaced = function isSpaced(char: string): boolean {
return WHITESPACE.has(char);
};
const needsSpace = function needsSpace(last: string, next: string, elements: boolean): boolean {
if (isSpaced(last) || isSpaced(next)) {
return false;
}
return elements || (isWordChar(last) && isWordChar(next));
};
export const joinParts = function joinParts(parts: readonly TextPart[]): string {
const pieces: string[] = [];
let last = SPACE;
let previous = false;
for (const part of parts.filter((entry) => entry.text.length > 0)) {
const next = part.text.at(0) ?? SPACE;
if (needsSpace(last, next, previous && part.element)) {
pieces.push(SPACE);
}
pieces.push(part.text);
last = part.text.at(-1) ?? last;
previous = part.element;
}
return pieces.join("");
};
export const collapseSpaces = function collapseSpaces(text: string): string {
let result = "";
let pending = false;
for (const character of text) {
if (WHITESPACE.has(character)) {
pending = true;
continue;
}
result += (pending ? SPACE : "") + character;
pending = false;
}
return pending ? result + SPACE : result;
};
const trimSpaces = function trimSpaces(line: string): string {
let start = 0;
let end = line.length;
while (start < end && line.charAt(start) === SPACE) {
start += 1;
}
while (end > start && line.charAt(end - 1) === SPACE) {
end -= 1;
}
return line.slice(start, end);
};
export const collapseBreaks = function collapseBreaks(text: string): string {
const lines: string[] = [];
let fenced = false;
let blanks = 0;
for (const line of text.split(LINE_BREAK)) {
const marks = trimSpaces(line).startsWith(FENCE_MARK);
if (fenced && !marks) {
lines.push(line);
continue;
}
fenced = marks ? !fenced : fenced;
const kept = trimSpaces(line);
blanks = kept.length === 0 ? blanks + 1 : 0;
if (blanks < MAX_BREAKS) {
lines.push(kept);
}
}
return lines.join(LINE_BREAK).trim();
};