@furifont/core 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +11 -0
- package/dist/index.mjs +48 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -18,6 +18,7 @@ export declare const DEFAULTS: {
|
|
|
18
18
|
/** Uses in Tatoeba's example sentences that select a word whatever its bucket: about 1,000 more words, and 50 glyphs. */
|
|
19
19
|
readonly minTatoeba: 3;
|
|
20
20
|
readonly places: true;
|
|
21
|
+
readonly untagged: true;
|
|
21
22
|
readonly isolated: true;
|
|
22
23
|
readonly isolatedMinShare: 0.8;
|
|
23
24
|
/** Sizes in em, relative to the base font. */
|
|
@@ -119,6 +120,8 @@ interface Dictionary {
|
|
|
119
120
|
form: string;
|
|
120
121
|
furigana: string;
|
|
121
122
|
}[];
|
|
123
|
+
/** Word lists kept by hand, by source name, in inline notation; like place names, they fill runs no common word claims. */
|
|
124
|
+
manual?: Record<string, string[]>;
|
|
122
125
|
}
|
|
123
126
|
/** A ruby annotation over characters `[start, end)` of a run. */
|
|
124
127
|
interface RubySpan {
|
|
@@ -154,6 +157,8 @@ export declare function formatNotation(text: string, spans: readonly RubySpan[])
|
|
|
154
157
|
export declare const RUBY_SCRIPTS: readonly ["hiragana", "katakanaOn", "hepburn"];
|
|
155
158
|
export declare const PRIORITY_TAGS: readonly ["ichi1", "ichi2", "news1", "news2", "spec1", "spec2", "gai1", "gai2"];
|
|
156
159
|
/** Easiest first. */
|
|
160
|
+
/** The dictionary's manually maintained sources, which a plan may include by name. */
|
|
161
|
+
export declare const MANUAL_SOURCES: readonly ["mahjong-yaku", "jr-stations", "yojijukugo"];
|
|
157
162
|
export declare const JLPT_LEVELS: readonly ["N5", "N4", "N3", "N2", "N1"];
|
|
158
163
|
type RubyScript = typeof RUBY_SCRIPTS[number];
|
|
159
164
|
/** Sizes in em, relative to the base font. */
|
|
@@ -200,6 +205,10 @@ export declare const PlanOptionsSchema: v.SchemaWithPipe<readonly [v.ObjectSchem
|
|
|
200
205
|
readonly skipJlpt: v.OptionalSchema<v.PicklistSchema<readonly ["N5", "N4", "N3", "N2", "N1"], undefined>, undefined>;
|
|
201
206
|
/** Annotate place names from the dictionary where no common word claims the run. */
|
|
202
207
|
readonly places: v.OptionalSchema<v.BooleanSchema<undefined>, true>;
|
|
208
|
+
/** Annotate the words of JMdict that no list ranks or tags (such as 四字熟語), where no common word, manual list or place name claims the run; each gets its first reading. */
|
|
209
|
+
readonly untagged: v.OptionalSchema<v.BooleanSchema<undefined>, true>;
|
|
210
|
+
/** The dictionary's manually maintained sources (such as `mahjong-yaku`) to annotate; all of them when left out. */
|
|
211
|
+
readonly manual: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["mahjong-yaku", "jr-stations", "yojijukugo"], undefined>, undefined>, undefined>;
|
|
203
212
|
/** Annotate a kanji alone in its run, or one no word claims after another kanji (a suffix); when off, only selectors give them ruby. */
|
|
204
213
|
readonly isolated: v.OptionalSchema<v.BooleanSchema<undefined>, true>;
|
|
205
214
|
/** A kanji alone in its run is annotated only when one reading has this share of the evidence. */
|
|
@@ -231,6 +240,8 @@ export declare const PlanOptionsSchema: v.SchemaWithPipe<readonly [v.ObjectSchem
|
|
|
231
240
|
minTatoeba: number;
|
|
232
241
|
skipJlpt?: "N5" | "N4" | "N3" | "N2" | "N1" | undefined;
|
|
233
242
|
places: boolean;
|
|
243
|
+
untagged: boolean;
|
|
244
|
+
manual?: ("mahjong-yaku" | "jr-stations" | "yojijukugo")[] | undefined;
|
|
234
245
|
isolated: boolean;
|
|
235
246
|
isolatedMinShare: number;
|
|
236
247
|
words: {
|
package/dist/index.mjs
CHANGED
|
@@ -23,6 +23,7 @@ const DEFAULTS = {
|
|
|
23
23
|
/** Uses in Tatoeba's example sentences that select a word whatever its bucket: about 1,000 more words, and 50 glyphs. */
|
|
24
24
|
minTatoeba: 3,
|
|
25
25
|
places: true,
|
|
26
|
+
untagged: true,
|
|
26
27
|
isolated: true,
|
|
27
28
|
isolatedMinShare: .8,
|
|
28
29
|
/** Sizes in em, relative to the base font. */
|
|
@@ -680,6 +681,40 @@ function addPlaces(patterns, places, skipped, ctx) {
|
|
|
680
681
|
}]);
|
|
681
682
|
}
|
|
682
683
|
}
|
|
684
|
+
/** Words of the manual sources fill the runs no common word claims, nor a skipped one; they come before place names. */
|
|
685
|
+
function addManual(patterns, manual, skipped, ctx) {
|
|
686
|
+
const names = ctx.options.manual ?? Object.keys(manual);
|
|
687
|
+
for (const notation of names.flatMap((name) => manual[name] ?? [])) {
|
|
688
|
+
const { form, spans } = parseNotation(notation);
|
|
689
|
+
for (const run of hanRuns(form, spans).filter(ctx.renderable)) {
|
|
690
|
+
if (length(run.text) === 1 || patterns.has(run.text) || skipped.has(run.text) || ctx.removed.has(run.text)) continue;
|
|
691
|
+
patterns.set(run.text, [{
|
|
692
|
+
spans: run.spans,
|
|
693
|
+
weight: 0,
|
|
694
|
+
tagged: false,
|
|
695
|
+
order: 0,
|
|
696
|
+
nf: 0,
|
|
697
|
+
jlpt: 0,
|
|
698
|
+
tags: /* @__PURE__ */ new Set(),
|
|
699
|
+
place: true
|
|
700
|
+
}]);
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
/** Words no list ranks fill the runs nothing else claims, each with its first reading: they are no evidence for the kanji's own. */
|
|
705
|
+
function addUntagged(patterns, index, skipped, ctx) {
|
|
706
|
+
for (const [text, readings] of index.runs) {
|
|
707
|
+
if (patterns.has(text) || skipped.has(text) || ctx.removed.has(text)) continue;
|
|
708
|
+
const first = [...readings.values()].filter((r) => ctx.renderable({
|
|
709
|
+
text,
|
|
710
|
+
spans: r.spans
|
|
711
|
+
})).sort((a, b) => a.order - b.order)[0];
|
|
712
|
+
if (first) patterns.set(text, [{
|
|
713
|
+
...first,
|
|
714
|
+
place: true
|
|
715
|
+
}]);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
683
718
|
/**
|
|
684
719
|
* Runs of common words, then place names and custom words; pinned readings of
|
|
685
720
|
* lone kanji are returned apart. A word is skipped whole: were only its known
|
|
@@ -700,7 +735,9 @@ function selectWords(index, dictionary, ctx) {
|
|
|
700
735
|
}));
|
|
701
736
|
if (common.length) patterns.set(text, common.map((r) => ({ ...r })));
|
|
702
737
|
}
|
|
738
|
+
if (dictionary.manual) addManual(patterns, dictionary.manual, skipped, ctx);
|
|
703
739
|
if (ctx.options.places) addPlaces(patterns, dictionary.places, skipped, ctx);
|
|
740
|
+
if (ctx.options.untagged) addUntagged(patterns, index, skipped, ctx);
|
|
704
741
|
const lonePins = /* @__PURE__ */ new Map();
|
|
705
742
|
for (const notation of ctx.options.words.add) addCustomWord(patterns, lonePins, notation, 0, ctx);
|
|
706
743
|
for (const notation of dictionary.defaults ?? []) addCustomWord(patterns, lonePins, notation, 1, ctx);
|
|
@@ -1226,6 +1263,12 @@ const PRIORITY_TAGS = [
|
|
|
1226
1263
|
"gai2"
|
|
1227
1264
|
];
|
|
1228
1265
|
/** Easiest first. */
|
|
1266
|
+
/** The dictionary's manually maintained sources, which a plan may include by name. */
|
|
1267
|
+
const MANUAL_SOURCES = [
|
|
1268
|
+
"mahjong-yaku",
|
|
1269
|
+
"jr-stations",
|
|
1270
|
+
"yojijukugo"
|
|
1271
|
+
];
|
|
1229
1272
|
const JLPT_LEVELS = [
|
|
1230
1273
|
"N5",
|
|
1231
1274
|
"N4",
|
|
@@ -1276,6 +1319,10 @@ const PlanOptionsSchema = withNfWindow(v.object({
|
|
|
1276
1319
|
skipJlpt: v.optional(v.picklist(JLPT_LEVELS)),
|
|
1277
1320
|
/** Annotate place names from the dictionary where no common word claims the run. */
|
|
1278
1321
|
places: v.optional(v.boolean(), DEFAULTS.plan.places),
|
|
1322
|
+
/** Annotate the words of JMdict that no list ranks or tags (such as 四字熟語), where no common word, manual list or place name claims the run; each gets its first reading. */
|
|
1323
|
+
untagged: v.optional(v.boolean(), DEFAULTS.plan.untagged),
|
|
1324
|
+
/** The dictionary's manually maintained sources (such as `mahjong-yaku`) to annotate; all of them when left out. */
|
|
1325
|
+
manual: v.optional(v.array(v.picklist(MANUAL_SOURCES))),
|
|
1279
1326
|
/** Annotate a kanji alone in its run, or one no word claims after another kanji (a suffix); when off, only selectors give them ruby. */
|
|
1280
1327
|
isolated: v.optional(v.boolean(), DEFAULTS.plan.isolated),
|
|
1281
1328
|
/** A kanji alone in its run is annotated only when one reading has this share of the evidence. */
|
|
@@ -1343,4 +1390,4 @@ const PlanSchema = v.object({
|
|
|
1343
1390
|
}))
|
|
1344
1391
|
});
|
|
1345
1392
|
//#endregion
|
|
1346
|
-
export { DEFAULTS, JLPT_LEVELS, MAX_READINGS, PREBUILT, PRIORITY_TAGS, PlanOptionsSchema, PlanSchema, RUBY_SCRIPTS, SELECTOR_FIRST_READING, SELECTOR_SUPPRESS, VERSION_PROBE, createFontPlanner, formatNotation, glyphName, hanRuns, isHan, isOnyomi, parseFurigana, parseNotation, resolveOptions, toHepburn, toHiragana, toKatakana, withNfWindow };
|
|
1393
|
+
export { DEFAULTS, JLPT_LEVELS, MANUAL_SOURCES, MAX_READINGS, PREBUILT, PRIORITY_TAGS, PlanOptionsSchema, PlanSchema, RUBY_SCRIPTS, SELECTOR_FIRST_READING, SELECTOR_SUPPRESS, VERSION_PROBE, createFontPlanner, formatNotation, glyphName, hanRuns, isHan, isOnyomi, parseFurigana, parseNotation, resolveOptions, toHepburn, toHiragana, toKatakana, withNfWindow };
|
package/package.json
CHANGED