core/analyzers/tone.analyzer.ts

core/analyzers/tone.analyzer.ts is a file in Bane's Lab Content. 43 lines of code and 9 definitions.

import { COLLECTIVE_PERSON, FIRST_PERSON, SECOND_PERSON } from "#configuration/constants/tone.constants";
import { LONG_DASH, METRIC_UNITS, SEMICOLON } from "@ssot/govlab/shared/manifests/punctuation.manifest.ts";
import { countAny, digitMetricsOf, lowerWordsOf } from "#core/normalizers/word.normalizer";
import { longestOf, shapesOf } from "@ssot/govlab/shared/analyzers/sentence.analyzer.ts";
import { BANNED_TERMS } from "@ssot/govlab/shared/manifests/vocabulary.manifest.ts";
import { JOIN_CAP } from "@ssot/govlab/shared/manifests/sentence.manifest.ts";
import type { ToneMetrics } from "#types/tone.types";
import { isLabeledItem } from "#core/normalizers/sentence.normalizer";

const countPersons = function countPersons(words: readonly string[], markers: ReadonlySet<string>): number {
    return words.filter((word) => markers.has(word)).length;
};

const occurrences = function occurrences(text: string, needle: string): number {
    let count = 0;
    let from = text.indexOf(needle);
    while (from !== -1) {
        count += 1;
        from = text.indexOf(needle, from + needle.length);
    }
    return count;
};

export const measureLiterals = function measureLiterals(module: string, literals: readonly string[]): ToneMetrics {
    const joined = literals.join(" ");
    const lower = joined.toLowerCase();
    const words = lowerWordsOf(joined);
    const shapes = literals.flatMap(shapesOf);
    return {
        agentlessPassives: shapes.filter((shape) => shape.agentlessPassive).length,
        bannedTerms: countAny(lower, BANNED_TERMS),
        chainedSentences: shapes.filter((shape) => shape.joins > JOIN_CAP).length,
        collectivePerson: countPersons(words, COLLECTIVE_PERSON),
        digitMetrics: digitMetricsOf(lower, METRIC_UNITS),
        firstPerson: countPersons(words, FIRST_PERSON),
        labeledItems: literals.filter(isLabeledItem).length,
        literals: literals.length,
        longDashes: occurrences(joined, LONG_DASH),
        longestSentence: longestOf(shapes),
        module,
        secondPerson: countPersons(words, SECOND_PERSON),
        semicolons: occurrences(joined, SEMICOLON),
        sentences: shapes.length,
        words: words.length,
    };
};