mirror of
https://github.com/Horizontal42/summarum.git
synced 2026-11-10 15:42:01 +03:00
stop '5 min' from losing the minute unit to the min() aggregate
registerCoreVocab() registers "min" as the aggregate function name before registerUnits() registers it as the minute abbreviation, and first-registration-wins means the unit phrase never lands. "5 min" silently became either plain "5" or got overwritten by a MIN of the preceding block. Disambiguate right after tokenizing: "min"/"мин" immediately after a number can only mean minutes.
This commit is contained in:
parent
741ea16e40
commit
881fb4809a
2 changed files with 30 additions and 1 deletions
|
|
@ -291,4 +291,15 @@ describe("regression 2026-08-12", () => {
|
|||
expect(r[1]).toBeNull();
|
||||
expect(r[2]).toBe("4");
|
||||
});
|
||||
|
||||
it("'5 min' means 5 minutes, not the min() aggregate", () => {
|
||||
expect(calc("5 min")).toBe("5 min");
|
||||
expect(calc("5 мин")).toBe("5 min");
|
||||
});
|
||||
it("standalone 'min'/'max' aggregate lines still work", () => {
|
||||
const r = eng.evaluateDocument("10\n20\n5\nmin").map((x) => x.text);
|
||||
expect(r).toEqual(["10", "20", "5", "5"]);
|
||||
const r2 = eng.evaluateDocument("10\n20\n5\nmax").map((x) => x.text);
|
||||
expect(r2).toEqual(["10", "20", "5", "20"]);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ export function tokenize(line: string, reg: Registry, dateOrder: DateOrder = "dm
|
|||
tokens.push({ t: "word", raw: lx.raw, ...span });
|
||||
i++;
|
||||
}
|
||||
return disambiguateIn(tokens, reg, line);
|
||||
return disambiguateMinAgg(disambiguateIn(tokens, reg, line), reg, line);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -138,3 +138,21 @@ function disambiguateIn(tokens: Token[], reg: Registry, line: string): Token[] {
|
|||
return tk;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* "5 min": the "min" aggregate keyword (registered first, so it wins the
|
||||
* phrase in the registry) collides with the minute unit's "min"/"мин"
|
||||
* abbreviation. Right after a number it can only mean minutes — the
|
||||
* standalone `min` aggregate line has no preceding number to collide with.
|
||||
*/
|
||||
function disambiguateMinAgg(tokens: Token[], reg: Registry, line: string): Token[] {
|
||||
const minute = reg.unitsById.get("minute");
|
||||
if (!minute) return tokens;
|
||||
return tokens.map((tk, i) => {
|
||||
if (tk.t !== "agg" || tk.name !== "min") return tk;
|
||||
const raw = line.slice(tk.start, tk.end).toLowerCase();
|
||||
if (raw !== "min" && raw !== "мин") return tk;
|
||||
if (tokens[i - 1]?.t !== "num") return tk;
|
||||
return { t: "unit", unit: minute, start: tk.start, end: tk.end } as Token;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue