@furifont/core 0.1.0 → 0.1.2
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 +351 -0
- package/dist/index.mjs +1233 -0
- package/package.json +1 -1
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
//#region src/defaults.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Every default of a build, and how the prebuilt fonts are built, in one place.
|
|
5
|
+
* Config files, the CLI, the studio and `scripts/build-fonts.ts` all read it, so
|
|
6
|
+
* a change here reaches them together. What an option means is in `schema.ts`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const DEFAULTS: {
|
|
9
|
+
/** What a plan does when a config leaves an option out. */
|
|
10
|
+
readonly plan: {
|
|
11
|
+
readonly family: "Furifont Sans";
|
|
12
|
+
readonly rubyScript: "hiragana";
|
|
13
|
+
/** Newspaper frequency buckets, nf01 to nf48: the window of words that get ruby. All of them: it adds about 400 glyphs. */
|
|
14
|
+
readonly nfMin: 1;
|
|
15
|
+
readonly nfMax: 48;
|
|
16
|
+
/** JMdict priority tags that select a word whatever its bucket: the first tier of each list, which JMdict marks as common. */
|
|
17
|
+
readonly selectTags: readonly ["ichi1", "news1", "spec1", "gai1"];
|
|
18
|
+
readonly places: true;
|
|
19
|
+
readonly isolated: true;
|
|
20
|
+
readonly isolatedMinShare: 0.8;
|
|
21
|
+
/** Sizes in em, relative to the base font. */
|
|
22
|
+
readonly metrics: {
|
|
23
|
+
readonly rubyScale: 0.5;
|
|
24
|
+
readonly rubyGap: 0.05;
|
|
25
|
+
readonly compressionFloor: 0.8;
|
|
26
|
+
readonly maxRubyWidth: 1.6;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
/** What the CLI adds to a plan: where the glyphs are drawn, and what is written. */
|
|
30
|
+
readonly build: {
|
|
31
|
+
readonly base: "Source Han Sans JP VF";
|
|
32
|
+
readonly formats: readonly ["otf", "woff2"];
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
/** The prebuilt fonts, which each release carries; the site serves their variable WOFF2s. */
|
|
36
|
+
export declare const PREBUILT: {
|
|
37
|
+
/** Each Source Han face in each ruby script. The first is the default family. */
|
|
38
|
+
readonly fonts: readonly [{
|
|
39
|
+
readonly family: "Furifont Sans";
|
|
40
|
+
readonly base: "Source Han Sans JP";
|
|
41
|
+
readonly face: "sans";
|
|
42
|
+
readonly rubyScript: "hiragana";
|
|
43
|
+
}, {
|
|
44
|
+
readonly family: "Furifont Sans Romaji";
|
|
45
|
+
readonly base: "Source Han Sans JP";
|
|
46
|
+
readonly face: "sans";
|
|
47
|
+
readonly rubyScript: "hepburn";
|
|
48
|
+
}, {
|
|
49
|
+
readonly family: "Furifont Serif";
|
|
50
|
+
readonly base: "Source Han Serif JP";
|
|
51
|
+
readonly face: "serif";
|
|
52
|
+
readonly rubyScript: "hiragana";
|
|
53
|
+
}, {
|
|
54
|
+
readonly family: "Furifont Serif Romaji";
|
|
55
|
+
readonly base: "Source Han Serif JP";
|
|
56
|
+
readonly face: "serif";
|
|
57
|
+
readonly rubyScript: "hepburn";
|
|
58
|
+
}];
|
|
59
|
+
/** The static weights of the release, each of the base's weights by name. Bold is the variable font's. */
|
|
60
|
+
readonly weights: readonly [{
|
|
61
|
+
readonly style: "Regular";
|
|
62
|
+
readonly weight: 400;
|
|
63
|
+
}];
|
|
64
|
+
/**
|
|
65
|
+
* Every weight in one font, from the base's variable font (`<base> VF`). It
|
|
66
|
+
* is named apart, `<family> VF`, so it installs beside the static weights.
|
|
67
|
+
*/
|
|
68
|
+
readonly variable: {
|
|
69
|
+
readonly style: "VF";
|
|
70
|
+
readonly weights: readonly [250, 900];
|
|
71
|
+
};
|
|
72
|
+
/** Options set on every prebuilt font over the defaults above, such as `{ nfMax: 24 }`. */
|
|
73
|
+
readonly options: {};
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* The sequence, 。 and VS1, a page measures to tell which version of Furifont
|
|
77
|
+
* it has: the font maps it to an empty glyph two ems wide plus the revision in
|
|
78
|
+
* ems (`0.1.2`, revision 0.102, is 2.102 ems). A font from before it draws the
|
|
79
|
+
* 。 alone, an em wide at most.
|
|
80
|
+
*/
|
|
81
|
+
export declare const VERSION_PROBE: {
|
|
82
|
+
readonly base: 12290;
|
|
83
|
+
readonly selector: 65024;
|
|
84
|
+
};
|
|
85
|
+
//#endregion
|
|
86
|
+
//#region src/dictionary.d.ts
|
|
87
|
+
/** One (written form, reading) pair, as compiled by `@furifont/dictionary`. */
|
|
88
|
+
interface DictionaryEntry {
|
|
89
|
+
form: string;
|
|
90
|
+
/** JmdictFurigana alignment: `0:に;1:ほん`, or `0-1:きょう` for a reading spanning characters. */
|
|
91
|
+
furigana: string;
|
|
92
|
+
/** The form's newspaper frequency bucket (nf01..nf48), 0 when unranked. */
|
|
93
|
+
nf: number;
|
|
94
|
+
/** The reading's JMdict priority tags, space separated; empty for uncommon readings. */
|
|
95
|
+
priority: string;
|
|
96
|
+
/** Position of the reading among the form's readings, in JMdict order. */
|
|
97
|
+
order: number;
|
|
98
|
+
/** `来る`-type verb, whose kanji reads differently as it conjugates. */
|
|
99
|
+
conjugatesReading?: boolean;
|
|
100
|
+
/** The JLPT level whose word list has this pair: 5 for N5 down to 1 for N1. */
|
|
101
|
+
jlpt?: number;
|
|
102
|
+
}
|
|
103
|
+
interface Dictionary {
|
|
104
|
+
entries: DictionaryEntry[];
|
|
105
|
+
/** Kanji to its on'yomi, in hiragana. */
|
|
106
|
+
onyomi: Record<string, string[]>;
|
|
107
|
+
/** Source datasets and the version each was compiled from. */
|
|
108
|
+
sources: Record<string, string>;
|
|
109
|
+
/** Written forms never to annotate, such as 月, whose reading alone is a guess; users' removals add to them. */
|
|
110
|
+
bare?: string[];
|
|
111
|
+
/** Curated default readings in inline notation, for words the data ranks wrong; pins override them. */
|
|
112
|
+
defaults?: string[];
|
|
113
|
+
/** Place names, each with the one reading to show; common words take precedence over them. */
|
|
114
|
+
places?: {
|
|
115
|
+
form: string;
|
|
116
|
+
furigana: string;
|
|
117
|
+
}[];
|
|
118
|
+
}
|
|
119
|
+
/** A ruby annotation over characters `[start, end)` of a run. */
|
|
120
|
+
interface RubySpan {
|
|
121
|
+
start: number;
|
|
122
|
+
end: number;
|
|
123
|
+
ruby: string;
|
|
124
|
+
}
|
|
125
|
+
/** A maximal sequence of Han characters with its reading, the unit a shaper sees. */
|
|
126
|
+
interface HanRun {
|
|
127
|
+
text: string;
|
|
128
|
+
spans: RubySpan[];
|
|
129
|
+
}
|
|
130
|
+
export declare function isHan(char: string): boolean;
|
|
131
|
+
export declare function parseFurigana(furigana: string): RubySpan[];
|
|
132
|
+
/**
|
|
133
|
+
* Splits a form into its Han runs. Browsers itemize text by script before
|
|
134
|
+
* shaping, so a font only ever sees one run at a time: okurigana and other
|
|
135
|
+
* kana are never visible as context. Runs with an unannotated kanji or an
|
|
136
|
+
* annotation leaking outside the run are dropped.
|
|
137
|
+
*/
|
|
138
|
+
export declare function hanRuns(form: string, spans: readonly RubySpan[]): HanRun[];
|
|
139
|
+
/**
|
|
140
|
+
* Parses the inline notation for custom words: `日[に]本[ほん]` for one reading
|
|
141
|
+
* per kanji, `今日[きょう]` for a reading over several kanji, kana as written.
|
|
142
|
+
*/
|
|
143
|
+
export declare function parseNotation(notation: string): {
|
|
144
|
+
form: string;
|
|
145
|
+
spans: RubySpan[];
|
|
146
|
+
};
|
|
147
|
+
export declare function formatNotation(text: string, spans: readonly RubySpan[]): string;
|
|
148
|
+
//#endregion
|
|
149
|
+
//#region src/schema.d.ts
|
|
150
|
+
export declare const RUBY_SCRIPTS: readonly ["hiragana", "katakanaOn", "hepburn"];
|
|
151
|
+
export declare const PRIORITY_TAGS: readonly ["ichi1", "ichi2", "news1", "news2", "spec1", "spec2", "gai1", "gai2"];
|
|
152
|
+
/** Easiest first. */
|
|
153
|
+
export declare const JLPT_LEVELS: readonly ["N5", "N4", "N3", "N2", "N1"];
|
|
154
|
+
type RubyScript = typeof RUBY_SCRIPTS[number];
|
|
155
|
+
/** Sizes in em, relative to the base font. */
|
|
156
|
+
declare const RubyMetricsSchema: v.ObjectSchema<{
|
|
157
|
+
/** Ruby size relative to the base characters. */
|
|
158
|
+
readonly rubyScale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0.2, undefined>, v.MaxValueAction<number, 0.8, undefined>]>, 0.5>;
|
|
159
|
+
/** Space between the top of the em box and the bottom of the ruby. */
|
|
160
|
+
readonly rubyGap: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 0.5, undefined>]>, 0.05>;
|
|
161
|
+
/** Ruby is squeezed horizontally down to this scale before it may overhang. */
|
|
162
|
+
readonly compressionFloor: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0.3, undefined>, v.MaxValueAction<number, 1, undefined>]>, 0.8>;
|
|
163
|
+
/** Widest a ruby may get, overhanging its base symmetrically. */
|
|
164
|
+
readonly maxRubyWidth: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>, v.MaxValueAction<number, 3, undefined>]>, 1.6>;
|
|
165
|
+
}, undefined>;
|
|
166
|
+
type RubyMetrics = v.InferOutput<typeof RubyMetricsSchema>;
|
|
167
|
+
/** `schema`, checking that its frequency window `nfMin..nfMax` holds a bucket; for schemas that extend the options too. */
|
|
168
|
+
export declare function withNfWindow<T extends v.GenericSchema<unknown, {
|
|
169
|
+
nfMin: number;
|
|
170
|
+
nfMax: number;
|
|
171
|
+
}>>(schema: T): v.SchemaWithPipe<readonly [T, v.CheckAction<v.InferOutput<T>, string>]>;
|
|
172
|
+
export declare const PlanOptionsSchema: v.SchemaWithPipe<readonly [v.ObjectSchema<{
|
|
173
|
+
readonly family: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.NonEmptyAction<string, undefined>, v.CheckAction<string, "Source is a reserved font name of the base font">]>, "Furifont Sans">;
|
|
174
|
+
readonly rubyScript: v.OptionalSchema<v.PicklistSchema<readonly ["hiragana", "katakanaOn", "hepburn"], undefined>, "hiragana">;
|
|
175
|
+
/**
|
|
176
|
+
* Words whose newspaper frequency bucket is below this stay bare: the most
|
|
177
|
+
* common ones, which a reader knows. Tags don't bring them back.
|
|
178
|
+
*/
|
|
179
|
+
readonly nfMin: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>, v.MaxValueAction<number, 48, undefined>]>, 1>;
|
|
180
|
+
/** Words whose newspaper frequency bucket is at most this are annotated. */
|
|
181
|
+
readonly nfMax: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>, v.MaxValueAction<number, 48, undefined>]>, 48>;
|
|
182
|
+
/**
|
|
183
|
+
* JMdict priority tags that select a word whatever its frequency bucket:
|
|
184
|
+
* `spec1` catches words like 日本 that the newspaper ranking misses.
|
|
185
|
+
*/
|
|
186
|
+
readonly selectTags: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["ichi1", "ichi2", "news1", "news2", "spec1", "spec2", "gai1", "gai2"], undefined>, undefined>, () => ("ichi1" | "news1" | "spec1" | "gai1")[]>;
|
|
187
|
+
/** Words on the JLPT lists of this level and every easier one stay bare. */
|
|
188
|
+
readonly skipJlpt: v.OptionalSchema<v.PicklistSchema<readonly ["N5", "N4", "N3", "N2", "N1"], undefined>, undefined>;
|
|
189
|
+
/** Annotate place names from the dictionary where no common word claims the run. */
|
|
190
|
+
readonly places: v.OptionalSchema<v.BooleanSchema<undefined>, true>;
|
|
191
|
+
/** Annotate a kanji alone in its run; when off, only selectors give it ruby. */
|
|
192
|
+
readonly isolated: v.OptionalSchema<v.BooleanSchema<undefined>, true>;
|
|
193
|
+
/** A kanji alone in its run is annotated only when one reading has this share of the evidence. */
|
|
194
|
+
readonly isolatedMinShare: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0.5, undefined>, v.MaxValueAction<number, 1, undefined>]>, 0.8>;
|
|
195
|
+
readonly words: v.OptionalSchema<v.ObjectSchema<{
|
|
196
|
+
/** Extra words in inline notation, `日[に]本[ほん]`. */
|
|
197
|
+
readonly add: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, readonly []>;
|
|
198
|
+
/** Written forms never to annotate. */
|
|
199
|
+
readonly remove: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, readonly []>;
|
|
200
|
+
/** Readings to make the default, in inline notation. */
|
|
201
|
+
readonly pin: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, readonly []>;
|
|
202
|
+
}, undefined>, {}>;
|
|
203
|
+
readonly metrics: v.OptionalSchema<v.ObjectSchema<{
|
|
204
|
+
/** Ruby size relative to the base characters. */
|
|
205
|
+
readonly rubyScale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0.2, undefined>, v.MaxValueAction<number, 0.8, undefined>]>, 0.5>;
|
|
206
|
+
/** Space between the top of the em box and the bottom of the ruby. */
|
|
207
|
+
readonly rubyGap: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 0.5, undefined>]>, 0.05>;
|
|
208
|
+
/** Ruby is squeezed horizontally down to this scale before it may overhang. */
|
|
209
|
+
readonly compressionFloor: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0.3, undefined>, v.MaxValueAction<number, 1, undefined>]>, 0.8>;
|
|
210
|
+
/** Widest a ruby may get, overhanging its base symmetrically. */
|
|
211
|
+
readonly maxRubyWidth: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>, v.MaxValueAction<number, 3, undefined>]>, 1.6>;
|
|
212
|
+
}, undefined>, {}>;
|
|
213
|
+
}, undefined>, v.CheckAction<{
|
|
214
|
+
family: string;
|
|
215
|
+
rubyScript: "hiragana" | "hepburn" | "katakanaOn";
|
|
216
|
+
nfMin: number;
|
|
217
|
+
nfMax: number;
|
|
218
|
+
selectTags: ("ichi1" | "news1" | "spec1" | "gai1" | "ichi2" | "news2" | "spec2" | "gai2")[];
|
|
219
|
+
skipJlpt?: "N5" | "N4" | "N3" | "N2" | "N1" | undefined;
|
|
220
|
+
places: boolean;
|
|
221
|
+
isolated: boolean;
|
|
222
|
+
isolatedMinShare: number;
|
|
223
|
+
words: {
|
|
224
|
+
add: string[];
|
|
225
|
+
remove: string[];
|
|
226
|
+
pin: string[];
|
|
227
|
+
};
|
|
228
|
+
metrics: {
|
|
229
|
+
rubyScale: number;
|
|
230
|
+
rubyGap: number;
|
|
231
|
+
compressionFloor: number;
|
|
232
|
+
maxRubyWidth: number;
|
|
233
|
+
};
|
|
234
|
+
}, string>]>;
|
|
235
|
+
type PlanOptions = v.InferOutput<typeof PlanOptionsSchema>;
|
|
236
|
+
type PlanOptionsInput = v.InferInput<typeof PlanOptionsSchema>;
|
|
237
|
+
export declare function resolveOptions(input?: PlanOptionsInput): PlanOptions;
|
|
238
|
+
/**
|
|
239
|
+
* The contract between the planner and the compiler. The compiler makes no
|
|
240
|
+
* decision about readings: it draws what `glyphs` describes and compiles `fea`.
|
|
241
|
+
* In `fea`, base characters are named `uniXXXX` / `uXXXXX` after their codepoint.
|
|
242
|
+
*/
|
|
243
|
+
export declare const PlanSchema: v.ObjectSchema<{
|
|
244
|
+
readonly version: v.LiteralSchema<1, undefined>;
|
|
245
|
+
readonly names: v.ObjectSchema<{
|
|
246
|
+
readonly family: v.StringSchema<undefined>;
|
|
247
|
+
readonly description: v.StringSchema<undefined>;
|
|
248
|
+
}, undefined>;
|
|
249
|
+
readonly metrics: v.ObjectSchema<{
|
|
250
|
+
readonly rubyScale: v.NumberSchema<undefined>;
|
|
251
|
+
readonly rubyGap: v.NumberSchema<undefined>;
|
|
252
|
+
readonly compressionFloor: v.NumberSchema<undefined>;
|
|
253
|
+
readonly maxRubyWidth: v.NumberSchema<undefined>;
|
|
254
|
+
}, undefined>;
|
|
255
|
+
/** Base characters the rules name; each must be in the base font's cmap. */
|
|
256
|
+
readonly codepoints: v.ArraySchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1114111, undefined>]>, undefined>;
|
|
257
|
+
/**
|
|
258
|
+
* Base + variation selector sequences to map in `cmap` format 14, each to an
|
|
259
|
+
* empty glyph named `name`, with the base's advance: the rules replace it.
|
|
260
|
+
*/
|
|
261
|
+
readonly variants: v.ArraySchema<v.ObjectSchema<{
|
|
262
|
+
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, undefined>]>;
|
|
263
|
+
readonly base: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1114111, undefined>]>;
|
|
264
|
+
readonly selector: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1114111, undefined>]>;
|
|
265
|
+
}, undefined>, undefined>;
|
|
266
|
+
readonly glyphs: v.ArraySchema<v.ObjectSchema<{
|
|
267
|
+
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, undefined>]>;
|
|
268
|
+
/** The base characters drawn side by side; more than one makes a ligature. */
|
|
269
|
+
readonly bases: v.SchemaWithPipe<readonly [v.ArraySchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1114111, undefined>]>, undefined>, v.MinLengthAction<number[], 1, undefined>]>;
|
|
270
|
+
/** Ruby text drawn above characters `[start, end)` of `bases`. */
|
|
271
|
+
readonly ruby: v.ArraySchema<v.ObjectSchema<{
|
|
272
|
+
readonly start: v.NumberSchema<undefined>;
|
|
273
|
+
readonly end: v.NumberSchema<undefined>;
|
|
274
|
+
readonly text: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.NonEmptyAction<string, undefined>]>;
|
|
275
|
+
}, undefined>, undefined>;
|
|
276
|
+
}, undefined>, undefined>;
|
|
277
|
+
readonly fea: v.StringSchema<undefined>;
|
|
278
|
+
/** Subset the base font to these codepoints before building (live previews). */
|
|
279
|
+
readonly subset: v.OptionalSchema<v.ArraySchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1114111, undefined>]>, undefined>, undefined>;
|
|
280
|
+
/** Shaping checks the compiler runs on its output: `text` must shape to `glyphs`. */
|
|
281
|
+
readonly smoke: v.ArraySchema<v.ObjectSchema<{
|
|
282
|
+
readonly text: v.StringSchema<undefined>;
|
|
283
|
+
readonly glyphs: v.ArraySchema<v.StringSchema<undefined>, undefined>;
|
|
284
|
+
}, undefined>, undefined>;
|
|
285
|
+
}, undefined>;
|
|
286
|
+
type Plan = v.InferOutput<typeof PlanSchema>;
|
|
287
|
+
type PlanGlyph = Plan['glyphs'][number];
|
|
288
|
+
//#endregion
|
|
289
|
+
//#region src/glyphs.d.ts
|
|
290
|
+
export declare function glyphName(codepoint: number): string;
|
|
291
|
+
//#endregion
|
|
292
|
+
//#region src/kana.d.ts
|
|
293
|
+
export declare function toKatakana(hiragana: string): string;
|
|
294
|
+
export declare function toHiragana(katakana: string): string;
|
|
295
|
+
/**
|
|
296
|
+
* Whether `reading` is one of the kanji's on'yomi as it surfaces inside a word:
|
|
297
|
+
* as listed, with its first kana voiced (rendaku), or with a final く/き/ち/つ
|
|
298
|
+
* turned into っ (sokuon), e.g. 学 ガク surfacing as がっ in 学校.
|
|
299
|
+
*/
|
|
300
|
+
export declare function isOnyomi(reading: string, onyomi: readonly string[]): boolean;
|
|
301
|
+
/**
|
|
302
|
+
* Modified Hepburn with macrons (きょう → kyō, おおきい → ōkii). `following` is
|
|
303
|
+
* the kana written after this one in the word, so a trailing っ can double
|
|
304
|
+
* the next consonant (学 がっ before こう → gak).
|
|
305
|
+
*/
|
|
306
|
+
export declare function toHepburn(kana: string, following?: string): string;
|
|
307
|
+
//#endregion
|
|
308
|
+
//#region src/planner.d.ts
|
|
309
|
+
/** VS225: shows the kanji before it without ruby. */
|
|
310
|
+
export declare const SELECTOR_SUPPRESS = 917984;
|
|
311
|
+
/** VS226: reading 1 of the kanji (or word) before it; VS227 reading 2, and so on. */
|
|
312
|
+
export declare const SELECTOR_FIRST_READING = 917985;
|
|
313
|
+
/** The IVD leaves VS225..VS240 unregistered: one to suppress, fifteen readings. */
|
|
314
|
+
export declare const MAX_READINGS = 15;
|
|
315
|
+
interface PlanReport {
|
|
316
|
+
stats: {
|
|
317
|
+
patterns: number;
|
|
318
|
+
places: number;
|
|
319
|
+
ambiguous: number;
|
|
320
|
+
isolated: number;
|
|
321
|
+
protectedAnnotated: number;
|
|
322
|
+
protectedBare: number;
|
|
323
|
+
glyphs: number;
|
|
324
|
+
rules: number;
|
|
325
|
+
};
|
|
326
|
+
/**
|
|
327
|
+
* The lists variation selectors index into, VS226 being the first entry,
|
|
328
|
+
* and `salt` 1 the same entry through `font-feature-settings`.
|
|
329
|
+
* Words list their readings in inline notation, the default first. `lone`
|
|
330
|
+
* is the reading a kanji alone in its run shows without a selector.
|
|
331
|
+
*/
|
|
332
|
+
ivs: {
|
|
333
|
+
kanji: Record<string, string[]>;
|
|
334
|
+
words: Record<string, string[]>;
|
|
335
|
+
lone: Record<string, string>;
|
|
336
|
+
/** Whether the font maps `salt` n to the selector n after a run's first kanji: fonts built before it do not, and a preview does not. */
|
|
337
|
+
salt: boolean;
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
interface PlanResult {
|
|
341
|
+
plan: Plan;
|
|
342
|
+
report: PlanReport;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Indexes the dictionary once into Han runs, then plans fonts from it. Every
|
|
346
|
+
* decision about readings happens here: which words get ruby, which reading
|
|
347
|
+
* is the default, which longer words must be protected from a shorter match.
|
|
348
|
+
*/
|
|
349
|
+
export declare function createFontPlanner(dictionary: Dictionary): (options: PlanOptions, coverage: ReadonlySet<number>, previewText?: string) => PlanResult;
|
|
350
|
+
//#endregion
|
|
351
|
+
export type { Dictionary, DictionaryEntry, HanRun, Plan, PlanGlyph, PlanOptions, PlanOptionsInput, PlanReport, PlanResult, RubyMetrics, RubyScript, RubySpan };
|