UNPKG

@freeword/meta

Version:

Meta package for Freeword: exports all core types, constants, and utilities from the src/ directory.

69 lines (59 loc) 3.27 kB
import _ /**/ from 'lodash' import * as UF from '../lib/UF.ts' import type * as TY from '../types.ts' import { starlines } from '../lib/Filer.ts' import type { Wordform } from './Wordform.ts' export class LemmaDef { /** core word, eg. `accede` */ declare core: TY.Word /** word forms, */ declare wordforms: Wordform[] /** odd properties */ declare tmi: TY.AnyBag /** false if parse failed */ declare ok: boolean get words() { return _.map(this.wordforms, 'word') } get stemcores() { return _.map(this.wordforms, 'stemcore') } get suffixes() { return _.map(this.wordforms, 'suffix') } get poses() { return _.map(this.wordforms, 'pos') } get stemkinds() { return _.map(this.wordforms, 'stemkind') } get stemsplits() { return _.map(this.wordforms, 'stemsplit') } static make<RT extends LemmaDef>(this: { new(rawline: string): RT }, rawline: string): RT { return new this(rawline) as RT } parseRawLine(): this { return this } prettyA({ indent = '' }: { indent?: string } = {}): string { return indent + _.map(this.wordforms, 'pretty').join(',\n' + indent) + ',' } get pretty() { return this.prettyA({ indent: ' ' }) } static async *parseDictStar<RT extends LemmaDef>(this: { new(rawline: string): RT }, rawlines: AsyncIterable<string> | Iterable<string>): AsyncGenerator<RT, { oopsies: RT[], oopsieCount: number }> { let oopsieCount = 0 const oopsies: RT[] = [] for await (const rawline of rawlines) { const def = (this as any as LemmaDefFactory<RT>).make(rawline) as RT def.parseRawLine() if (def.ok) { yield def } else { oopsies.push(def); oopsieCount++ } if (oopsieCount >= 30) { console.error('halting at 30 oopsies: things like', _.first(oopsies)); break } } return { oopsies, oopsieCount } } static async slurpLexicon<RT extends LemmaDef>(this: { new(rawline: string): RT }, filename: string): Promise<ParseDictResult<RT>> { const { vals: defs, ret } = await UF.slurpWithResult<RT, OppsieResult<RT>>((this as any as LemmaDefFactory<RT>).parseDictStar(starlines(filename))) return { ...ret, defs } } static parseDict<RT extends LemmaDef>(this: { make: (rawline: string) => RT }, rawlines: string[]): ParseDictResult<RT> { let oopsieCount = 0 const oopsies: RT[] = [] const defs: RT[] = [] for (const rawline of rawlines) { const def = this.make(rawline) as RT def.parseRawLine() if (def.ok) { defs.push(def) } else { oopsies.push(def); oopsieCount++ } } return { oopsies, defs, oopsieCount } } } export interface OppsieResult<RT extends LemmaDef> { oopsies: RT[], oopsieCount: number } export interface ParseDictResult<RT extends LemmaDef> extends OppsieResult<RT> { defs: RT[] } export type LemmaDefFactory<RT extends LemmaDef> = { new (rawline: string): RT, make: (rawline: string) => RT, parseDictStar: (rawlines: TY.AnyIterable<string>) => AsyncGenerator<RT, OppsieResult<RT>, any> parseDict: (rawlines: string[]) => ParseDictResult<RT> }