core/normalizers/word.normalizer.ts

core/normalizers/word.normalizer.ts is a file in Bane's Lab Content. 62 lines of code and 16 definitions.

import { WORD_STOPS } from "#configuration/constants/tone.constants";

export const wordsOf = function wordsOf(text: string): string[] {
    const words: string[] = [];
    let current = "";
    for (const char of text) {
        if (WORD_STOPS.has(char)) {
            if (current.length > 0) {
                words.push(current);
            }
            current = "";
        } else {
            current += char;
        }
    }
    if (current.length > 0) {
        words.push(current);
    }
    return words;
};

export const lowerWordsOf = function lowerWordsOf(text: string): string[] {
    return wordsOf(text).map((word) => word.toLowerCase());
};

const isBoundary = function isBoundary(char: string): boolean {
    return char.length === 0 || WORD_STOPS.has(char);
};

export const countTerm = function countTerm(lowerText: string, term: string): number {
    let count = 0;
    let from = lowerText.indexOf(term);
    while (from !== -1) {
        const before = from === 0 ? "" : lowerText.charAt(from - 1);
        const after = lowerText.charAt(from + term.length);
        if (isBoundary(before) && isBoundary(after)) {
            count += 1;
        }
        from = lowerText.indexOf(term, from + term.length);
    }
    return count;
};

export const countAny = function countAny(lowerText: string, terms: readonly string[]): number {
    return terms.reduce((sum, term) => sum + countTerm(lowerText, term), 0);
};

const isDigit = function isDigit(char: string): boolean {
    return char >= "0" && char <= "9";
};

const isNumeric = function isNumeric(stem: string): boolean {
    if (stem.length === 0) {
        return false;
    }
    for (const char of stem) {
        if (!isDigit(char) && char !== ".") {
            return false;
        }
    }
    return true;
};

export const isDigitMetric = function isDigitMetric(word: string, units: readonly string[]): boolean {
    const unit = units.find((held) => word.endsWith(held) && word.length > held.length);
    return unit !== undefined && isNumeric(word.slice(0, -unit.length));
};

export const digitMetricsOf = function digitMetricsOf(lowerText: string, units: readonly string[]): number {
    return lowerWordsOf(lowerText).filter((word) => isDigitMetric(word, units)).length;
};