@kensio/pinyinjs 1.7.4 → 1.7.5
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/accuracy/score-case.d.ts +23 -0
- package/dist/accuracy/score-case.d.ts.map +1 -0
- package/dist/accuracy/score-case.js +63 -0
- package/dist/accuracy/score-case.js.map +1 -0
- package/dist/accuracy/score.d.ts +1 -8
- package/dist/accuracy/score.d.ts.map +1 -1
- package/dist/accuracy/score.js +1 -55
- package/dist/accuracy/score.js.map +1 -1
- package/dist/cli/arguments.d.ts +4 -290
- package/dist/cli/arguments.d.ts.map +1 -1
- package/dist/cli/arguments.js +5 -357
- package/dist/cli/arguments.js.map +1 -1
- package/dist/cli/check-command.d.ts +9 -0
- package/dist/cli/check-command.d.ts.map +1 -0
- package/dist/cli/check-command.js +95 -0
- package/dist/cli/check-command.js.map +1 -0
- package/dist/cli/cli-input.d.ts +49 -0
- package/dist/cli/cli-input.d.ts.map +1 -0
- package/dist/cli/cli-input.js +31 -0
- package/dist/cli/cli-input.js.map +1 -0
- package/dist/cli/command.d.ts +97 -0
- package/dist/cli/command.d.ts.map +1 -0
- package/dist/cli/command.js +40 -0
- package/dist/cli/command.js.map +1 -0
- package/dist/cli/commands.d.ts +7 -110
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +14 -991
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/convert-command.d.ts +6 -0
- package/dist/cli/convert-command.d.ts.map +1 -0
- package/dist/cli/convert-command.js +52 -0
- package/dist/cli/convert-command.js.map +1 -0
- package/dist/cli/environment.d.ts +1 -1
- package/dist/cli/environment.d.ts.map +1 -1
- package/dist/cli/explain-command.d.ts +6 -0
- package/dist/cli/explain-command.d.ts.map +1 -0
- package/dist/cli/explain-command.js +40 -0
- package/dist/cli/explain-command.js.map +1 -0
- package/dist/cli/explain-syllable.d.ts +10 -0
- package/dist/cli/explain-syllable.d.ts.map +1 -0
- package/dist/cli/explain-syllable.js +70 -0
- package/dist/cli/explain-syllable.js.map +1 -0
- package/dist/cli/flag-help.d.ts +18 -0
- package/dist/cli/flag-help.d.ts.map +1 -0
- package/dist/cli/flag-help.js +78 -0
- package/dist/cli/flag-help.js.map +1 -0
- package/dist/cli/flag-lists.d.ts +49 -0
- package/dist/cli/flag-lists.d.ts.map +1 -0
- package/dist/cli/flag-lists.js +58 -0
- package/dist/cli/flag-lists.js.map +1 -0
- package/dist/cli/flag-values.d.ts +44 -0
- package/dist/cli/flag-values.d.ts.map +1 -0
- package/dist/cli/flag-values.js +56 -0
- package/dist/cli/flag-values.js.map +1 -0
- package/dist/cli/flags.d.ts +193 -0
- package/dist/cli/flags.d.ts.map +1 -0
- package/dist/cli/flags.js +133 -0
- package/dist/cli/flags.js.map +1 -0
- package/dist/cli/format-options.d.ts +29 -0
- package/dist/cli/format-options.d.ts.map +1 -0
- package/dist/cli/format-options.js +72 -0
- package/dist/cli/format-options.js.map +1 -0
- package/dist/cli/global-help.d.ts +23 -0
- package/dist/cli/global-help.d.ts.map +1 -0
- package/dist/cli/global-help.js +40 -0
- package/dist/cli/global-help.js.map +1 -0
- package/dist/cli/help.d.ts +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +5 -99
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/html-commands.d.ts +13 -0
- package/dist/cli/html-commands.d.ts.map +1 -0
- package/dist/cli/html-commands.js +49 -0
- package/dist/cli/html-commands.js.map +1 -0
- package/dist/cli/info-command.d.ts +7 -0
- package/dist/cli/info-command.d.ts.map +1 -0
- package/dist/cli/info-command.js +39 -0
- package/dist/cli/info-command.js.map +1 -0
- package/dist/cli/lookup-commands.d.ts +10 -0
- package/dist/cli/lookup-commands.d.ts.map +1 -0
- package/dist/cli/lookup-commands.js +101 -0
- package/dist/cli/lookup-commands.js.map +1 -0
- package/dist/cli/match-command.d.ts +11 -0
- package/dist/cli/match-command.d.ts.map +1 -0
- package/dist/cli/match-command.js +76 -0
- package/dist/cli/match-command.js.map +1 -0
- package/dist/cli/number-command.d.ts +12 -0
- package/dist/cli/number-command.d.ts.map +1 -0
- package/dist/cli/number-command.js +89 -0
- package/dist/cli/number-command.js.map +1 -0
- package/dist/cli/options.d.ts +30 -0
- package/dist/cli/options.d.ts.map +1 -0
- package/dist/cli/options.js +54 -0
- package/dist/cli/options.js.map +1 -0
- package/dist/cli/run-command.d.ts +24 -0
- package/dist/cli/run-command.d.ts.map +1 -0
- package/dist/cli/run-command.js +40 -0
- package/dist/cli/run-command.js.map +1 -0
- package/dist/cli/run.d.ts +4 -42
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +6 -61
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/script-command.d.ts +10 -0
- package/dist/cli/script-command.d.ts.map +1 -0
- package/dist/cli/script-command.js +58 -0
- package/dist/cli/script-command.js.map +1 -0
- package/dist/cli/segment-command.d.ts +11 -0
- package/dist/cli/segment-command.d.ts.map +1 -0
- package/dist/cli/segment-command.js +53 -0
- package/dist/cli/segment-command.js.map +1 -0
- package/dist/cli/slug-command.d.ts +10 -0
- package/dist/cli/slug-command.d.ts.map +1 -0
- package/dist/cli/slug-command.js +28 -0
- package/dist/cli/slug-command.js.map +1 -0
- package/dist/cli/syllable-command.d.ts +14 -0
- package/dist/cli/syllable-command.d.ts.map +1 -0
- package/dist/cli/syllable-command.js +82 -0
- package/dist/cli/syllable-command.js.map +1 -0
- package/dist/cli/system-table.d.ts +12 -0
- package/dist/cli/system-table.d.ts.map +1 -0
- package/dist/cli/system-table.js +48 -0
- package/dist/cli/system-table.js.map +1 -0
- package/dist/cli/systems.d.ts +57 -0
- package/dist/cli/systems.d.ts.map +1 -0
- package/dist/cli/systems.js +27 -0
- package/dist/cli/systems.js.map +1 -0
- package/dist/cli/transcribe-command.d.ts +18 -0
- package/dist/cli/transcribe-command.d.ts.map +1 -0
- package/dist/cli/transcribe-command.js +86 -0
- package/dist/cli/transcribe-command.js.map +1 -0
- package/dist/cli/transcribe-reading.d.ts +15 -0
- package/dist/cli/transcribe-reading.d.ts.map +1 -0
- package/dist/cli/transcribe-reading.js +90 -0
- package/dist/cli/transcribe-reading.js.map +1 -0
- package/dist/cli/transcribe-rows.d.ts +26 -0
- package/dist/cli/transcribe-rows.d.ts.map +1 -0
- package/dist/cli/transcribe-rows.js +30 -0
- package/dist/cli/transcribe-rows.js.map +1 -0
- package/dist/cli/usage-error.d.ts +9 -0
- package/dist/cli/usage-error.d.ts.map +1 -0
- package/dist/cli/usage-error.js +9 -0
- package/dist/cli/usage-error.js.map +1 -0
- package/dist/decode/alternatives.d.ts +16 -0
- package/dist/decode/alternatives.d.ts.map +1 -0
- package/dist/decode/alternatives.js +31 -0
- package/dist/decode/alternatives.js.map +1 -0
- package/dist/decode/confidence.d.ts.map +1 -1
- package/dist/decode/confidence.js +3 -118
- package/dist/decode/confidence.js.map +1 -1
- package/dist/decode/convert-options.d.ts +116 -0
- package/dist/decode/convert-options.d.ts.map +1 -0
- package/dist/decode/convert-options.js +2 -0
- package/dist/decode/convert-options.js.map +1 -0
- package/dist/decode/convert-pipeline.d.ts +18 -0
- package/dist/decode/convert-pipeline.d.ts.map +1 -0
- package/dist/decode/convert-pipeline.js +66 -0
- package/dist/decode/convert-pipeline.js.map +1 -0
- package/dist/decode/convert.d.ts +9 -118
- package/dist/decode/convert.d.ts.map +1 -1
- package/dist/decode/convert.js +5 -453
- package/dist/decode/convert.js.map +1 -1
- package/dist/decode/decode.d.ts +2 -15
- package/dist/decode/decode.d.ts.map +1 -1
- package/dist/decode/decode.js +2 -121
- package/dist/decode/decode.js.map +1 -1
- package/dist/decode/decoders.d.ts +32 -0
- package/dist/decode/decoders.d.ts.map +1 -0
- package/dist/decode/decoders.js +29 -0
- package/dist/decode/decoders.js.map +1 -0
- package/dist/decode/edge-context.d.ts +38 -0
- package/dist/decode/edge-context.d.ts.map +1 -0
- package/dist/decode/edge-context.js +57 -0
- package/dist/decode/edge-context.js.map +1 -0
- package/dist/decode/hint-lattice.d.ts +45 -0
- package/dist/decode/hint-lattice.d.ts.map +1 -0
- package/dist/decode/hint-lattice.js +140 -0
- package/dist/decode/hint-lattice.js.map +1 -0
- package/dist/decode/hints.d.ts +2 -45
- package/dist/decode/hints.d.ts.map +1 -1
- package/dist/decode/hints.js +1 -139
- package/dist/decode/hints.js.map +1 -1
- package/dist/decode/jiao-rule.d.ts +58 -0
- package/dist/decode/jiao-rule.d.ts.map +1 -0
- package/dist/decode/jiao-rule.js +76 -0
- package/dist/decode/jiao-rule.js.map +1 -0
- package/dist/decode/lattice-costs.d.ts +55 -0
- package/dist/decode/lattice-costs.d.ts.map +1 -0
- package/dist/decode/lattice-costs.js +90 -0
- package/dist/decode/lattice-costs.js.map +1 -0
- package/dist/decode/lattice-edges.d.ts +29 -0
- package/dist/decode/lattice-edges.d.ts.map +1 -0
- package/dist/decode/lattice-edges.js +78 -0
- package/dist/decode/lattice-edges.js.map +1 -0
- package/dist/decode/lattice-slice.d.ts +37 -0
- package/dist/decode/lattice-slice.d.ts.map +1 -0
- package/dist/decode/lattice-slice.js +43 -0
- package/dist/decode/lattice-slice.js.map +1 -0
- package/dist/decode/lattice-types.d.ts +82 -0
- package/dist/decode/lattice-types.d.ts.map +1 -0
- package/dist/decode/lattice-types.js +44 -0
- package/dist/decode/lattice-types.js.map +1 -0
- package/dist/decode/lattice.d.ts +2 -59
- package/dist/decode/lattice.d.ts.map +1 -1
- package/dist/decode/lattice.js +2 -118
- package/dist/decode/lattice.js.map +1 -1
- package/dist/decode/number-pieces.d.ts +62 -0
- package/dist/decode/number-pieces.d.ts.map +1 -0
- package/dist/decode/number-pieces.js +106 -0
- package/dist/decode/number-pieces.js.map +1 -0
- package/dist/decode/numbers.d.ts +53 -0
- package/dist/decode/numbers.d.ts.map +1 -0
- package/dist/decode/numbers.js +69 -0
- package/dist/decode/numbers.js.map +1 -0
- package/dist/decode/pieces.d.ts +78 -0
- package/dist/decode/pieces.d.ts.map +1 -0
- package/dist/decode/pieces.js +136 -0
- package/dist/decode/pieces.js.map +1 -0
- package/dist/decode/polyphone-rules.d.ts +31 -0
- package/dist/decode/polyphone-rules.d.ts.map +1 -0
- package/dist/decode/polyphone-rules.js +159 -0
- package/dist/decode/polyphone-rules.js.map +1 -0
- package/dist/decode/reading-rules.d.ts +2 -97
- package/dist/decode/reading-rules.d.ts.map +1 -1
- package/dist/decode/reading-rules.js +4 -365
- package/dist/decode/reading-rules.js.map +1 -1
- package/dist/decode/rules.d.ts +1 -17
- package/dist/decode/rules.d.ts.map +1 -1
- package/dist/decode/rules.js +1 -43
- package/dist/decode/rules.js.map +1 -1
- package/dist/decode/run-lattice.d.ts +52 -0
- package/dist/decode/run-lattice.d.ts.map +1 -0
- package/dist/decode/run-lattice.js +91 -0
- package/dist/decode/run-lattice.js.map +1 -0
- package/dist/decode/sandhi-tones.d.ts +69 -0
- package/dist/decode/sandhi-tones.d.ts.map +1 -0
- package/dist/decode/sandhi-tones.js +88 -0
- package/dist/decode/sandhi-tones.js.map +1 -0
- package/dist/decode/sandhi.d.ts +1 -1
- package/dist/decode/sandhi.d.ts.map +1 -1
- package/dist/decode/sandhi.js +1 -81
- package/dist/decode/sandhi.js.map +1 -1
- package/dist/decode/script-types.d.ts +76 -0
- package/dist/decode/script-types.d.ts.map +1 -0
- package/dist/decode/script-types.js +35 -0
- package/dist/decode/script-types.js.map +1 -0
- package/dist/decode/script-words.d.ts +32 -0
- package/dist/decode/script-words.d.ts.map +1 -0
- package/dist/decode/script-words.js +77 -0
- package/dist/decode/script-words.js.map +1 -0
- package/dist/decode/script.d.ts +3 -73
- package/dist/decode/script.d.ts.map +1 -1
- package/dist/decode/script.js +3 -109
- package/dist/decode/script.js.map +1 -1
- package/dist/decode/tan-rule.d.ts +68 -0
- package/dist/decode/tan-rule.d.ts.map +1 -0
- package/dist/decode/tan-rule.js +131 -0
- package/dist/decode/tan-rule.js.map +1 -0
- package/dist/decode/write-run.d.ts +28 -0
- package/dist/decode/write-run.d.ts.map +1 -0
- package/dist/decode/write-run.js +77 -0
- package/dist/decode/write-run.js.map +1 -0
- package/dist/dictionary/artifact-claims.d.ts +25 -0
- package/dist/dictionary/artifact-claims.d.ts.map +1 -0
- package/dist/dictionary/artifact-claims.js +47 -0
- package/dist/dictionary/artifact-claims.js.map +1 -0
- package/dist/dictionary/artifact-format.d.ts +86 -0
- package/dist/dictionary/artifact-format.d.ts.map +1 -0
- package/dist/dictionary/artifact-format.js +91 -0
- package/dist/dictionary/artifact-format.js.map +1 -0
- package/dist/dictionary/artifact-read.d.ts +34 -0
- package/dist/dictionary/artifact-read.d.ts.map +1 -0
- package/dist/dictionary/artifact-read.js +114 -0
- package/dist/dictionary/artifact-read.js.map +1 -0
- package/dist/dictionary/artifact.d.ts +4 -63
- package/dist/dictionary/artifact.d.ts.map +1 -1
- package/dist/dictionary/artifact.js +12 -229
- package/dist/dictionary/artifact.js.map +1 -1
- package/dist/dictionary/assertions.d.ts +5 -57
- package/dist/dictionary/assertions.d.ts.map +1 -1
- package/dist/dictionary/assertions.js +4 -317
- package/dist/dictionary/assertions.js.map +1 -1
- package/dist/dictionary/build-assertions.d.ts +12 -0
- package/dist/dictionary/build-assertions.d.ts.map +1 -0
- package/dist/dictionary/build-assertions.js +13 -0
- package/dist/dictionary/build-assertions.js.map +1 -0
- package/dist/dictionary/built-dictionary.d.ts +46 -0
- package/dist/dictionary/built-dictionary.d.ts.map +1 -0
- package/dist/dictionary/built-dictionary.js +97 -0
- package/dist/dictionary/built-dictionary.js.map +1 -0
- package/dist/dictionary/cedict-senses.d.ts +80 -0
- package/dist/dictionary/cedict-senses.d.ts.map +1 -0
- package/dist/dictionary/cedict-senses.js +114 -0
- package/dist/dictionary/cedict-senses.js.map +1 -0
- package/dist/dictionary/character-defaults.d.ts +26 -0
- package/dist/dictionary/character-defaults.d.ts.map +1 -0
- package/dist/dictionary/character-defaults.js +67 -0
- package/dist/dictionary/character-defaults.js.map +1 -0
- package/dist/dictionary/character-readings.d.ts +10 -0
- package/dist/dictionary/character-readings.d.ts.map +1 -0
- package/dist/dictionary/character-readings.js +25 -0
- package/dist/dictionary/character-readings.js.map +1 -0
- package/dist/dictionary/dictionary-entry.d.ts +37 -0
- package/dist/dictionary/dictionary-entry.d.ts.map +1 -0
- package/dist/dictionary/dictionary-entry.js +41 -0
- package/dist/dictionary/dictionary-entry.js.map +1 -0
- package/dist/dictionary/dictionary-readings.d.ts +56 -0
- package/dist/dictionary/dictionary-readings.d.ts.map +1 -0
- package/dist/dictionary/dictionary-readings.js +93 -0
- package/dist/dictionary/dictionary-readings.js.map +1 -0
- package/dist/dictionary/dictionary.d.ts +6 -60
- package/dist/dictionary/dictionary.d.ts.map +1 -1
- package/dist/dictionary/dictionary.js +9 -169
- package/dist/dictionary/dictionary.js.map +1 -1
- package/dist/dictionary/entry-invariants.d.ts +3 -0
- package/dist/dictionary/entry-invariants.d.ts.map +1 -0
- package/dist/dictionary/entry-invariants.js +67 -0
- package/dist/dictionary/entry-invariants.js.map +1 -0
- package/dist/dictionary/entry-lines.d.ts +35 -0
- package/dist/dictionary/entry-lines.d.ts.map +1 -0
- package/dist/dictionary/entry-lines.js +70 -0
- package/dist/dictionary/entry-lines.js.map +1 -0
- package/dist/dictionary/erhua-repair.d.ts +26 -0
- package/dist/dictionary/erhua-repair.d.ts.map +1 -0
- package/dist/dictionary/erhua-repair.js +49 -0
- package/dist/dictionary/erhua-repair.js.map +1 -0
- package/dist/dictionary/frequency-tones.d.ts +74 -0
- package/dist/dictionary/frequency-tones.d.ts.map +1 -0
- package/dist/dictionary/frequency-tones.js +128 -0
- package/dist/dictionary/frequency-tones.js.map +1 -0
- package/dist/dictionary/inventory-invariants.d.ts +3 -0
- package/dist/dictionary/inventory-invariants.d.ts.map +1 -0
- package/dist/dictionary/inventory-invariants.js +54 -0
- package/dist/dictionary/inventory-invariants.js.map +1 -0
- package/dist/dictionary/locale-candidates.d.ts +40 -0
- package/dist/dictionary/locale-candidates.d.ts.map +1 -0
- package/dist/dictionary/locale-candidates.js +77 -0
- package/dist/dictionary/locale-candidates.js.map +1 -0
- package/dist/dictionary/locale-segments.d.ts +47 -0
- package/dist/dictionary/locale-segments.d.ts.map +1 -0
- package/dist/dictionary/locale-segments.js +141 -0
- package/dist/dictionary/locale-segments.js.map +1 -0
- package/dist/dictionary/locale.d.ts +1 -21
- package/dist/dictionary/locale.d.ts.map +1 -1
- package/dist/dictionary/locale.js +9 -198
- package/dist/dictionary/locale.js.map +1 -1
- package/dist/dictionary/merge-types.d.ts +121 -0
- package/dist/dictionary/merge-types.d.ts.map +1 -0
- package/dist/dictionary/merge-types.js +35 -0
- package/dist/dictionary/merge-types.js.map +1 -0
- package/dist/dictionary/merge-word.d.ts +7 -0
- package/dist/dictionary/merge-word.d.ts.map +1 -0
- package/dist/dictionary/merge-word.js +91 -0
- package/dist/dictionary/merge-word.js.map +1 -0
- package/dist/dictionary/merge.d.ts +5 -62
- package/dist/dictionary/merge.d.ts.map +1 -1
- package/dist/dictionary/merge.js +30 -713
- package/dist/dictionary/merge.js.map +1 -1
- package/dist/dictionary/proper-noun.d.ts +28 -0
- package/dist/dictionary/proper-noun.d.ts.map +1 -0
- package/dist/dictionary/proper-noun.js +43 -0
- package/dist/dictionary/proper-noun.js.map +1 -0
- package/dist/dictionary/reading-agreement.d.ts +71 -0
- package/dist/dictionary/reading-agreement.d.ts.map +1 -0
- package/dist/dictionary/reading-agreement.js +156 -0
- package/dist/dictionary/reading-agreement.js.map +1 -0
- package/dist/dictionary/script-conversion.d.ts +28 -0
- package/dist/dictionary/script-conversion.d.ts.map +1 -0
- package/dist/dictionary/script-conversion.js +58 -0
- package/dist/dictionary/script-conversion.js.map +1 -0
- package/dist/dictionary/script-pairings.d.ts +74 -0
- package/dist/dictionary/script-pairings.d.ts.map +1 -0
- package/dist/dictionary/script-pairings.js +120 -0
- package/dist/dictionary/script-pairings.js.map +1 -0
- package/dist/dictionary/script-tables.d.ts.map +1 -1
- package/dist/dictionary/script-tables.js +2 -165
- package/dist/dictionary/script-tables.js.map +1 -1
- package/dist/dictionary/taiwan-reading.d.ts +8 -0
- package/dist/dictionary/taiwan-reading.d.ts.map +1 -0
- package/dist/dictionary/taiwan-reading.js +38 -0
- package/dist/dictionary/taiwan-reading.js.map +1 -0
- package/dist/dictionary/tone-invariants.d.ts +3 -0
- package/dist/dictionary/tone-invariants.d.ts.map +1 -0
- package/dist/dictionary/tone-invariants.js +64 -0
- package/dist/dictionary/tone-invariants.js.map +1 -0
- package/dist/dictionary/traditional-form.d.ts +21 -0
- package/dist/dictionary/traditional-form.d.ts.map +1 -0
- package/dist/dictionary/traditional-form.js +59 -0
- package/dist/dictionary/traditional-form.js.map +1 -0
- package/dist/dictionary/traditional-ranking.d.ts +22 -0
- package/dist/dictionary/traditional-ranking.d.ts.map +1 -0
- package/dist/dictionary/traditional-ranking.js +74 -0
- package/dist/dictionary/traditional-ranking.js.map +1 -0
- package/dist/dictionary/traditional-table.d.ts +51 -0
- package/dist/dictionary/traditional-table.d.ts.map +1 -0
- package/dist/dictionary/traditional-table.js +98 -0
- package/dist/dictionary/traditional-table.js.map +1 -0
- package/dist/dictionary/traditional.d.ts +3 -56
- package/dist/dictionary/traditional.d.ts.map +1 -1
- package/dist/dictionary/traditional.js +3 -186
- package/dist/dictionary/traditional.js.map +1 -1
- package/dist/dictionary/variant-counts.d.ts +39 -0
- package/dist/dictionary/variant-counts.d.ts.map +1 -0
- package/dist/dictionary/variant-counts.js +38 -0
- package/dist/dictionary/variant-counts.js.map +1 -0
- package/dist/dictionary/word-reading.d.ts +26 -0
- package/dist/dictionary/word-reading.d.ts.map +1 -0
- package/dist/dictionary/word-reading.js +76 -0
- package/dist/dictionary/word-reading.js.map +1 -0
- package/dist/dictionary/word-readings.d.ts +15 -0
- package/dist/dictionary/word-readings.d.ts.map +1 -0
- package/dist/dictionary/word-readings.js +38 -0
- package/dist/dictionary/word-readings.js.map +1 -0
- package/dist/format/annotate.d.ts +90 -0
- package/dist/format/annotate.d.ts.map +1 -0
- package/dist/format/annotate.js +168 -0
- package/dist/format/annotate.js.map +1 -0
- package/dist/format/html.d.ts +15 -46
- package/dist/format/html.d.ts.map +1 -1
- package/dist/format/html.js +3 -162
- package/dist/format/html.js.map +1 -1
- package/dist/format/slug-hash.d.ts +51 -0
- package/dist/format/slug-hash.d.ts.map +1 -0
- package/dist/format/slug-hash.js +74 -0
- package/dist/format/slug-hash.js.map +1 -0
- package/dist/format/slug-options.d.ts +98 -0
- package/dist/format/slug-options.d.ts.map +1 -0
- package/dist/format/slug-options.js +2 -0
- package/dist/format/slug-options.js.map +1 -0
- package/dist/format/slug-words.d.ts +27 -0
- package/dist/format/slug-words.d.ts.map +1 -0
- package/dist/format/slug-words.js +0 -0
- package/dist/format/slug-words.js.map +1 -0
- package/dist/format/slug.d.ts +3 -128
- package/dist/format/slug.d.ts.map +1 -1
- package/dist/format/slug.js +0 -0
- package/dist/format/slug.js.map +1 -1
- package/dist/grade/check-readings.d.ts +41 -0
- package/dist/grade/check-readings.d.ts.map +1 -0
- package/dist/grade/check-readings.js +36 -0
- package/dist/grade/check-readings.js.map +1 -0
- package/dist/grade/check.d.ts +4 -4
- package/dist/grade/check.d.ts.map +1 -1
- package/dist/grade/check.js +5 -270
- package/dist/grade/check.js.map +1 -1
- package/dist/grade/pair-syllables.d.ts +48 -0
- package/dist/grade/pair-syllables.d.ts.map +1 -0
- package/dist/grade/pair-syllables.js +71 -0
- package/dist/grade/pair-syllables.js.map +1 -0
- package/dist/grade/reading-syllables.d.ts +62 -0
- package/dist/grade/reading-syllables.d.ts.map +1 -0
- package/dist/grade/reading-syllables.js +58 -0
- package/dist/grade/reading-syllables.js.map +1 -0
- package/dist/grade/reading-tolerance.d.ts +72 -0
- package/dist/grade/reading-tolerance.d.ts.map +1 -0
- package/dist/grade/reading-tolerance.js +107 -0
- package/dist/grade/reading-tolerance.js.map +1 -0
- package/dist/grade/typed-reading.d.ts +28 -0
- package/dist/grade/typed-reading.d.ts.map +1 -0
- package/dist/grade/typed-reading.js +36 -0
- package/dist/grade/typed-reading.js.map +1 -0
- package/dist/numerals/numeral-parse.d.ts +32 -0
- package/dist/numerals/numeral-parse.d.ts.map +1 -0
- package/dist/numerals/numeral-parse.js +44 -0
- package/dist/numerals/numeral-parse.js.map +1 -0
- package/dist/numerals/numeral-shapes.d.ts +89 -0
- package/dist/numerals/numeral-shapes.d.ts.map +1 -0
- package/dist/numerals/numeral-shapes.js +99 -0
- package/dist/numerals/numeral-shapes.js.map +1 -0
- package/dist/numerals/numerals.d.ts.map +1 -1
- package/dist/numerals/numerals.js +2 -36
- package/dist/numerals/numerals.js.map +1 -1
- package/dist/numerals/read-numeral.d.ts +76 -0
- package/dist/numerals/read-numeral.d.ts.map +1 -0
- package/dist/numerals/read-numeral.js +88 -0
- package/dist/numerals/read-numeral.js.map +1 -0
- package/dist/numerals/text.d.ts +3 -37
- package/dist/numerals/text.d.ts.map +1 -1
- package/dist/numerals/text.js +3 -254
- package/dist/numerals/text.js.map +1 -1
- package/dist/numerals/time.d.ts +34 -0
- package/dist/numerals/time.d.ts.map +1 -0
- package/dist/numerals/time.js +93 -0
- package/dist/numerals/time.js.map +1 -0
- package/dist/orthography/address-grouping.d.ts +34 -0
- package/dist/orthography/address-grouping.d.ts.map +1 -0
- package/dist/orthography/address-grouping.js +52 -0
- package/dist/orthography/address-grouping.js.map +1 -0
- package/dist/orthography/grouping.d.ts +3 -87
- package/dist/orthography/grouping.d.ts.map +1 -1
- package/dist/orthography/grouping.js +4 -270
- package/dist/orthography/grouping.js.map +1 -1
- package/dist/orthography/place-grouping.d.ts +39 -0
- package/dist/orthography/place-grouping.d.ts.map +1 -0
- package/dist/orthography/place-grouping.js +83 -0
- package/dist/orthography/place-grouping.js.map +1 -0
- package/dist/orthography/word-grouping.d.ts +48 -0
- package/dist/orthography/word-grouping.d.ts.map +1 -0
- package/dist/orthography/word-grouping.js +147 -0
- package/dist/orthography/word-grouping.js.map +1 -0
- package/dist/script/conversion-format.d.ts +22 -0
- package/dist/script/conversion-format.d.ts.map +1 -0
- package/dist/script/conversion-format.js +22 -0
- package/dist/script/conversion-format.js.map +1 -0
- package/dist/script/conversion-read.d.ts +9 -0
- package/dist/script/conversion-read.d.ts.map +1 -0
- package/dist/script/conversion-read.js +69 -0
- package/dist/script/conversion-read.js.map +1 -0
- package/dist/script/conversion-write.d.ts +14 -0
- package/dist/script/conversion-write.d.ts.map +1 -0
- package/dist/script/conversion-write.js +34 -0
- package/dist/script/conversion-write.js.map +1 -0
- package/dist/script/conversion.d.ts +10 -16
- package/dist/script/conversion.d.ts.map +1 -1
- package/dist/script/conversion.js +2 -115
- package/dist/script/conversion.js.map +1 -1
- package/dist/search/candidate-narrowing.d.ts +56 -0
- package/dist/search/candidate-narrowing.d.ts.map +1 -0
- package/dist/search/candidate-narrowing.js +55 -0
- package/dist/search/candidate-narrowing.js.map +1 -0
- package/dist/search/candidate-query.d.ts +25 -0
- package/dist/search/candidate-query.d.ts.map +1 -0
- package/dist/search/candidate-query.js +28 -0
- package/dist/search/candidate-query.js.map +1 -0
- package/dist/search/candidate-writings.d.ts +24 -0
- package/dist/search/candidate-writings.d.ts.map +1 -0
- package/dist/search/candidate-writings.js +114 -0
- package/dist/search/candidate-writings.js.map +1 -0
- package/dist/search/candidates.d.ts +7 -41
- package/dist/search/candidates.d.ts.map +1 -1
- package/dist/search/candidates.js +10 -164
- package/dist/search/candidates.js.map +1 -1
- package/dist/search/match-chunks.d.ts +19 -0
- package/dist/search/match-chunks.d.ts.map +1 -0
- package/dist/search/match-chunks.js +30 -0
- package/dist/search/match-chunks.js.map +1 -0
- package/dist/search/match-ranking.d.ts +39 -0
- package/dist/search/match-ranking.d.ts.map +1 -0
- package/dist/search/match-ranking.js +51 -0
- package/dist/search/match-ranking.js.map +1 -0
- package/dist/search/match-readings.d.ts +43 -0
- package/dist/search/match-readings.d.ts.map +1 -0
- package/dist/search/match-readings.js +83 -0
- package/dist/search/match-readings.js.map +1 -0
- package/dist/search/match-scoring.d.ts +146 -0
- package/dist/search/match-scoring.d.ts.map +1 -0
- package/dist/search/match-scoring.js +114 -0
- package/dist/search/match-scoring.js.map +1 -0
- package/dist/search/match-search.d.ts +28 -0
- package/dist/search/match-search.d.ts.map +1 -0
- package/dist/search/match-search.js +128 -0
- package/dist/search/match-search.js.map +1 -0
- package/dist/search/match.d.ts +5 -36
- package/dist/search/match.d.ts.map +1 -1
- package/dist/search/match.js +2 -379
- package/dist/search/match.js.map +1 -1
- package/dist/search/reverse-index-build.d.ts +30 -0
- package/dist/search/reverse-index-build.d.ts.map +1 -0
- package/dist/search/reverse-index-build.js +72 -0
- package/dist/search/reverse-index-build.js.map +1 -0
- package/dist/search/reverse-index-format.d.ts +60 -0
- package/dist/search/reverse-index-format.d.ts.map +1 -0
- package/dist/search/reverse-index-format.js +54 -0
- package/dist/search/reverse-index-format.js.map +1 -0
- package/dist/search/reverse-index-groups.d.ts +37 -0
- package/dist/search/reverse-index-groups.d.ts.map +1 -0
- package/dist/search/reverse-index-groups.js +71 -0
- package/dist/search/reverse-index-groups.js.map +1 -0
- package/dist/search/reverse-index-passes.d.ts +78 -0
- package/dist/search/reverse-index-passes.d.ts.map +1 -0
- package/dist/search/reverse-index-passes.js +59 -0
- package/dist/search/reverse-index-passes.js.map +1 -0
- package/dist/search/reverse-index-state.d.ts +36 -0
- package/dist/search/reverse-index-state.d.ts.map +1 -0
- package/dist/search/reverse-index-state.js +95 -0
- package/dist/search/reverse-index-state.js.map +1 -0
- package/dist/search/reverse-index.d.ts +8 -67
- package/dist/search/reverse-index.d.ts.map +1 -1
- package/dist/search/reverse-index.js +4 -255
- package/dist/search/reverse-index.js.map +1 -1
- package/dist/sources/unihan-readings.d.ts +58 -0
- package/dist/sources/unihan-readings.d.ts.map +1 -0
- package/dist/sources/unihan-readings.js +95 -0
- package/dist/sources/unihan-readings.js.map +1 -0
- package/dist/sources/unihan.d.ts +6 -9
- package/dist/sources/unihan.d.ts.map +1 -1
- package/dist/sources/unihan.js +2 -85
- package/dist/sources/unihan.js.map +1 -1
- package/dist/syllable/final-tables.d.ts +23 -0
- package/dist/syllable/final-tables.d.ts.map +1 -0
- package/dist/syllable/final-tables.js +50 -0
- package/dist/syllable/final-tables.js.map +1 -0
- package/dist/syllable/inventory.d.ts +8 -42
- package/dist/syllable/inventory.d.ts.map +1 -1
- package/dist/syllable/inventory.js +9 -918
- package/dist/syllable/inventory.js.map +1 -1
- package/dist/syllable/spellings.d.ts +40 -0
- package/dist/syllable/spellings.d.ts.map +1 -0
- package/dist/syllable/spellings.js +469 -0
- package/dist/syllable/spellings.js.map +1 -0
- package/dist/syllable/syllable-parts.d.ts +31 -0
- package/dist/syllable/syllable-parts.d.ts.map +1 -0
- package/dist/syllable/syllable-parts.js +105 -0
- package/dist/syllable/syllable-parts.js.map +1 -0
- package/dist/syllable/syllable.d.ts +1 -14
- package/dist/syllable/syllable.d.ts.map +1 -1
- package/dist/syllable/syllable.js +3 -144
- package/dist/syllable/syllable.js.map +1 -1
- package/dist/syllable/written-tones.d.ts +6 -0
- package/dist/syllable/written-tones.d.ts.map +1 -0
- package/dist/syllable/written-tones.js +453 -0
- package/dist/syllable/written-tones.js.map +1 -0
- package/dist/transcription/bopomofo-parse.d.ts +42 -0
- package/dist/transcription/bopomofo-parse.d.ts.map +1 -0
- package/dist/transcription/bopomofo-parse.js +92 -0
- package/dist/transcription/bopomofo-parse.js.map +1 -0
- package/dist/transcription/bopomofo-reverse.d.ts +31 -0
- package/dist/transcription/bopomofo-reverse.d.ts.map +1 -0
- package/dist/transcription/bopomofo-reverse.js +48 -0
- package/dist/transcription/bopomofo-reverse.js.map +1 -0
- package/dist/transcription/bopomofo-symbols.d.ts +36 -0
- package/dist/transcription/bopomofo-symbols.d.ts.map +1 -0
- package/dist/transcription/bopomofo-symbols.js +41 -0
- package/dist/transcription/bopomofo-symbols.js.map +1 -0
- package/dist/transcription/bopomofo-tables.d.ts +87 -0
- package/dist/transcription/bopomofo-tables.d.ts.map +1 -0
- package/dist/transcription/bopomofo-tables.js +180 -0
- package/dist/transcription/bopomofo-tables.js.map +1 -0
- package/dist/transcription/bopomofo.d.ts +14 -32
- package/dist/transcription/bopomofo.d.ts.map +1 -1
- package/dist/transcription/bopomofo.js +5 -343
- package/dist/transcription/bopomofo.js.map +1 -1
- package/dist/transcription/gwoyeu-first-second.d.ts +36 -0
- package/dist/transcription/gwoyeu-first-second.d.ts.map +1 -0
- package/dist/transcription/gwoyeu-first-second.js +75 -0
- package/dist/transcription/gwoyeu-first-second.js.map +1 -0
- package/dist/transcription/gwoyeu-spelling.d.ts +38 -0
- package/dist/transcription/gwoyeu-spelling.d.ts.map +1 -0
- package/dist/transcription/gwoyeu-spelling.js +124 -0
- package/dist/transcription/gwoyeu-spelling.js.map +1 -0
- package/dist/transcription/gwoyeu-tables.d.ts +93 -0
- package/dist/transcription/gwoyeu-tables.d.ts.map +1 -0
- package/dist/transcription/gwoyeu-tables.js +205 -0
- package/dist/transcription/gwoyeu-tables.js.map +1 -0
- package/dist/transcription/gwoyeu-tonal-forms.d.ts +49 -0
- package/dist/transcription/gwoyeu-tonal-forms.d.ts.map +1 -0
- package/dist/transcription/gwoyeu-tonal-forms.js +89 -0
- package/dist/transcription/gwoyeu-tonal-forms.js.map +1 -0
- package/dist/transcription/gwoyeu-vowels.d.ts +51 -0
- package/dist/transcription/gwoyeu-vowels.d.ts.map +1 -0
- package/dist/transcription/gwoyeu-vowels.js +58 -0
- package/dist/transcription/gwoyeu-vowels.js.map +1 -0
- package/dist/transcription/gwoyeu.d.ts +1 -26
- package/dist/transcription/gwoyeu.d.ts.map +1 -1
- package/dist/transcription/gwoyeu.js +2 -540
- package/dist/transcription/gwoyeu.js.map +1 -1
- package/dist/transcription/ipa-symbols.d.ts +67 -0
- package/dist/transcription/ipa-symbols.d.ts.map +1 -0
- package/dist/transcription/ipa-symbols.js +135 -0
- package/dist/transcription/ipa-symbols.js.map +1 -0
- package/dist/transcription/ipa.d.ts +2 -10
- package/dist/transcription/ipa.d.ts.map +1 -1
- package/dist/transcription/ipa.js +2 -134
- package/dist/transcription/ipa.js.map +1 -1
- package/dist/transcription/wade-giles-index.d.ts +35 -0
- package/dist/transcription/wade-giles-index.d.ts.map +1 -0
- package/dist/transcription/wade-giles-index.js +110 -0
- package/dist/transcription/wade-giles-index.js.map +1 -0
- package/dist/transcription/wade-giles-parse.d.ts +36 -0
- package/dist/transcription/wade-giles-parse.d.ts.map +1 -0
- package/dist/transcription/wade-giles-parse.js +84 -0
- package/dist/transcription/wade-giles-parse.js.map +1 -0
- package/dist/transcription/wade-giles-spelling.d.ts +61 -0
- package/dist/transcription/wade-giles-spelling.d.ts.map +1 -0
- package/dist/transcription/wade-giles-spelling.js +107 -0
- package/dist/transcription/wade-giles-spelling.js.map +1 -0
- package/dist/transcription/wade-giles-syllable.d.ts +29 -0
- package/dist/transcription/wade-giles-syllable.d.ts.map +1 -0
- package/dist/transcription/wade-giles-syllable.js +90 -0
- package/dist/transcription/wade-giles-syllable.js.map +1 -0
- package/dist/transcription/wade-giles-tables.d.ts +80 -0
- package/dist/transcription/wade-giles-tables.d.ts.map +1 -0
- package/dist/transcription/wade-giles-tables.js +178 -0
- package/dist/transcription/wade-giles-tables.js.map +1 -0
- package/dist/transcription/wade-giles.d.ts +9 -60
- package/dist/transcription/wade-giles.d.ts.map +1 -1
- package/dist/transcription/wade-giles.js +6 -543
- package/dist/transcription/wade-giles.js.map +1 -1
- package/dist/transcription/yale-tables.d.ts +54 -0
- package/dist/transcription/yale-tables.d.ts.map +1 -0
- package/dist/transcription/yale-tables.js +125 -0
- package/dist/transcription/yale-tables.js.map +1 -0
- package/dist/transcription/yale.d.ts.map +1 -1
- package/dist/transcription/yale.js +1 -124
- package/dist/transcription/yale.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/commands.js
CHANGED
|
@@ -1,994 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
import { readWadeGiles, readWadeGilesLoosely, readWadeGilesWord, splitWadeGiles, writeWadeGiles, writeWadeGilesWord, } from "../transcription/wade-giles.js";
|
|
16
|
-
import { readYale, writeYale, writeYaleWord } from "../transcription/yale.js";
|
|
17
|
-
import { ATTESTED_SYLLABLES, DICTIONARY_SYLLABLES, } from "../syllable/inventory.js";
|
|
18
|
-
import { readWord, splitSyllables } from "../syllable/split.js";
|
|
19
|
-
import { readSyllable, writeSyllable, writeSyllableSpelling, } from "../syllable/syllable.js";
|
|
20
|
-
import { CHECK_FLAGS, checkOptions, convertOptions, CONVERT_FLAGS, htmlOptions, MATCH_FLAGS, matchQuery, SCRIPT_FLAGS, scriptFrom, scriptTarget, SLUG_FLAGS, slugOptions, transcriptionSource, transcriptionSystem, UsageError, } from "./arguments.js";
|
|
21
|
-
import { PLAIN, visibleLength } from "./colour.js";
|
|
22
|
-
import { isUncertainChoice, toScriptPieces } from "../decode/script.js";
|
|
23
|
-
/**
|
|
24
|
-
* The dictionary a command declared it needs.
|
|
25
|
-
*/
|
|
26
|
-
function dictionaryOf(input) {
|
|
27
|
-
/* c8 ignore next 3 -- loaded for every command that declares it needs one */
|
|
28
|
-
if (input.dictionary === undefined) {
|
|
29
|
-
throw new UsageError("no dictionary was loaded");
|
|
30
|
-
}
|
|
31
|
-
return input.dictionary;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Pad a column so that what follows it lines up.
|
|
35
|
-
*
|
|
36
|
-
* Padded to what a reader sees rather than to the string's length: a coloured
|
|
37
|
-
* cell carries escape sequences that take no width on screen, and `padEnd`
|
|
38
|
-
* counts them.
|
|
39
|
-
*/
|
|
40
|
-
function column(text, width) {
|
|
41
|
-
return text + " ".repeat(Math.max(0, width - visibleLength(text)));
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* A reading written out, syllable by syllable, each in its tone's colour.
|
|
45
|
-
*/
|
|
46
|
-
function written(reading, paint) {
|
|
47
|
-
return reading
|
|
48
|
-
.map((syllable) => paint(writeSyllable(syllable), syllable.tone))
|
|
49
|
-
.join(" ");
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* How settled a decoded syllable was, in one word.
|
|
53
|
-
*
|
|
54
|
-
* `locked` means no other reading was on offer, `word` that taking one would
|
|
55
|
-
* have meant breaking a dictionary word apart, and `guess` that another reading
|
|
56
|
-
* of the same characters was there for the taking. See ROADMAP.md for how often
|
|
57
|
-
* each turns out to be wrong.
|
|
58
|
-
*/
|
|
59
|
-
function stateOf(piece) {
|
|
60
|
-
const { confidence } = piece;
|
|
61
|
-
if (confidence === undefined || confidence.isLocked) {
|
|
62
|
-
return "locked";
|
|
63
|
-
}
|
|
64
|
-
return isUncertain(confidence) ? "guess" : "word";
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* What a decode rejected at one syllable, and what rejecting it saved.
|
|
68
|
-
*/
|
|
69
|
-
function alternativesOf(piece, input) {
|
|
70
|
-
const { notation } = convertOptions(input.flags);
|
|
71
|
-
return (piece.confidence?.alternatives ?? []).map((alternative) => {
|
|
72
|
-
const spelled = alternative.reading.map((syllable) => writeSyllable(syllable, notation));
|
|
73
|
-
return {
|
|
74
|
-
reading: spelled.join(""),
|
|
75
|
-
painted: spelled
|
|
76
|
-
.map((text, at) => input.paint(text, alternative.reading[at]?.tone))
|
|
77
|
-
.join(""),
|
|
78
|
-
// Rounded because a cost is a sum of frequency buckets and a per-word
|
|
79
|
-
// charge of 4.62, which lands on 24.620000000000005 often enough to be
|
|
80
|
-
// worth not putting in front of anybody.
|
|
81
|
-
cost: Math.round(alternative.cost * 100) / 100,
|
|
82
|
-
};
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Convert each text, one line in and one line out.
|
|
87
|
-
*/
|
|
88
|
-
const CONVERT = {
|
|
89
|
-
name: "convert",
|
|
90
|
-
summary: "hanzi to pinyin",
|
|
91
|
-
argument: "[text...]",
|
|
92
|
-
flags: [...CONVERT_FLAGS, "greedy", "system"],
|
|
93
|
-
needsDictionary: true,
|
|
94
|
-
run: (input) => {
|
|
95
|
-
const options = convertOptions(input.flags);
|
|
96
|
-
const isGreedy = input.flags.greedy === true;
|
|
97
|
-
const decode = isGreedy ? convertGreedily : convert;
|
|
98
|
-
const inPieces = isGreedy ? convertPiecesGreedily : convertPieces;
|
|
99
|
-
const system = systemNamed(transcriptionSystem(input.flags));
|
|
100
|
-
if (system !== undefined) {
|
|
101
|
-
// hanzi → pinyin → the system, which is the shape ROADMAP.md predicted
|
|
102
|
-
// for the whole of `transcription`. See toTranscription for why the word
|
|
103
|
-
// grouping is shared and only the join is the system's.
|
|
104
|
-
return input.texts.map((text) => {
|
|
105
|
-
const written = toTranscription(inPieces(dictionaryOf(input), text, options), (syllables) => system.word(syllables, options.notation !== "none"), { capitals: system.capitals });
|
|
106
|
-
return {
|
|
107
|
-
lines: [written],
|
|
108
|
-
data: { text, system: system.name, transcription: written },
|
|
109
|
-
};
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
return input.texts.map((text) => {
|
|
113
|
-
const pinyin = decode(dictionaryOf(input), text, options);
|
|
114
|
-
// The pieces cost a second sweep of the lattice, so they are only asked
|
|
115
|
-
// for where there is a colour to put on them.
|
|
116
|
-
const written = input.paint === PLAIN
|
|
117
|
-
? pinyin
|
|
118
|
-
: paintedPieces(inPieces(dictionaryOf(input), text, options), input);
|
|
119
|
-
return { lines: [written], data: { text, pinyin } };
|
|
120
|
-
});
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
/**
|
|
124
|
-
* A conversion's pieces joined back up, each syllable in its tone's colour.
|
|
125
|
-
*/
|
|
126
|
-
function paintedPieces(pieces, input) {
|
|
127
|
-
return pieces
|
|
128
|
-
.map((piece) => input.paint(piece.text, piece.syllable?.tone))
|
|
129
|
-
.join("");
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Convert each text to HTML, one element per syllable.
|
|
133
|
-
*/
|
|
134
|
-
const HTML = {
|
|
135
|
-
name: "html",
|
|
136
|
-
summary: "hanzi to pinyin as HTML, one element per syllable",
|
|
137
|
-
argument: "[text...]",
|
|
138
|
-
flags: [...CONVERT_FLAGS, "no-tone-classes", "no-uncertain", "no-lang"],
|
|
139
|
-
needsDictionary: true,
|
|
140
|
-
run: (input) => {
|
|
141
|
-
const options = htmlOptions(input.flags);
|
|
142
|
-
return input.texts.map((text) => {
|
|
143
|
-
const html = convertToHtml(dictionaryOf(input), text, options);
|
|
144
|
-
return { lines: [html], data: { text, html } };
|
|
145
|
-
});
|
|
146
|
-
},
|
|
147
|
-
};
|
|
148
|
-
/**
|
|
149
|
-
* Annotate each text: the hanzi, with its reading above.
|
|
150
|
-
*
|
|
151
|
-
* Uncoloured for the same reason `html` is — the classes are the hook, and a
|
|
152
|
-
* terminal escape code inside markup would be pasted into a page.
|
|
153
|
-
*/
|
|
154
|
-
const ANNOTATE = {
|
|
155
|
-
name: "annotate",
|
|
156
|
-
summary: "hanzi with its pinyin above, as ruby HTML",
|
|
157
|
-
argument: "[text...]",
|
|
158
|
-
flags: [...CONVERT_FLAGS, "no-tone-classes", "no-uncertain", "no-lang"],
|
|
159
|
-
needsDictionary: true,
|
|
160
|
-
run: (input) => {
|
|
161
|
-
const options = htmlOptions(input.flags);
|
|
162
|
-
return input.texts.map((text) => {
|
|
163
|
-
const html = convertToAnnotatedHtml(dictionaryOf(input), text, options);
|
|
164
|
-
return { lines: [html], data: { text, html } };
|
|
165
|
-
});
|
|
166
|
-
},
|
|
167
|
-
};
|
|
168
|
-
/**
|
|
169
|
-
* Split each text into the words the decoder finds in it.
|
|
170
|
-
*
|
|
171
|
-
* The words on one line, since that is what the answer is, with the reading
|
|
172
|
-
* under each so the split can be read against what it settled. A stretch that
|
|
173
|
-
* was never Han is shown as itself and marked, because it is part of the text
|
|
174
|
-
* and not part of the segmentation.
|
|
175
|
-
*/
|
|
176
|
-
const SEGMENT = {
|
|
177
|
-
name: "segment",
|
|
178
|
-
summary: "split text into words",
|
|
179
|
-
argument: "[text...]",
|
|
180
|
-
flags: [],
|
|
181
|
-
needsDictionary: true,
|
|
182
|
-
run: (input) => input.texts.map((text) => {
|
|
183
|
-
const found = segment(dictionaryOf(input), text);
|
|
184
|
-
return {
|
|
185
|
-
lines: [
|
|
186
|
-
found.map((one) => one.text).join(" / "),
|
|
187
|
-
// Unpadded, as `lookup` is and for the same reason: a hanzi column
|
|
188
|
-
// cannot be lined up by counting characters, since a terminal draws
|
|
189
|
-
// most of them two cells wide and 。 and Latin one.
|
|
190
|
-
...found.map((one) => ` ${[
|
|
191
|
-
one.text,
|
|
192
|
-
written(one.reading, input.paint),
|
|
193
|
-
one.isKnown ? one.partOfSpeech : "—",
|
|
194
|
-
]
|
|
195
|
-
.filter((cell) => cell !== "")
|
|
196
|
-
.join(" ")}`),
|
|
197
|
-
],
|
|
198
|
-
data: {
|
|
199
|
-
text,
|
|
200
|
-
words: found.map((one) => ({
|
|
201
|
-
text: one.text,
|
|
202
|
-
at: one.at,
|
|
203
|
-
reading: one.reading
|
|
204
|
-
.map((syllable) => writeSyllable(syllable))
|
|
205
|
-
.join(" "),
|
|
206
|
-
partOfSpeech: one.partOfSpeech,
|
|
207
|
-
isProperNoun: one.isProperNoun,
|
|
208
|
-
isKnown: one.isKnown,
|
|
209
|
-
})),
|
|
210
|
-
},
|
|
211
|
-
};
|
|
212
|
-
}),
|
|
213
|
-
};
|
|
214
|
-
/**
|
|
215
|
-
* A text with the matched stretches marked, for a terminal.
|
|
216
|
-
*
|
|
217
|
-
* Brackets rather than colour, because the output is as likely to be piped as
|
|
218
|
-
* read: a match is a position, and a position survives being redirected into a
|
|
219
|
-
* file where an escape sequence would only clutter it.
|
|
220
|
-
*/
|
|
221
|
-
function marked(text, ranges) {
|
|
222
|
-
const characters = toCharacters(text);
|
|
223
|
-
const opens = new Set(ranges.map((range) => range.at));
|
|
224
|
-
const closes = new Set(ranges.map((range) => range.at + range.length - 1));
|
|
225
|
-
return characters
|
|
226
|
-
.map((character, at) => `${opens.has(at) ? "[" : ""}${character}${closes.has(at) ? "]" : ""}`)
|
|
227
|
-
.join("");
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Filter texts by a pinyin query, best match first.
|
|
231
|
-
*
|
|
232
|
-
* Ranked rather than left in the order given, because ranking is what the
|
|
233
|
-
* scores are for and a filter nobody can see the order of is a filter that
|
|
234
|
-
* looks arbitrary. Every text still gets a line, matched or not, so that a run
|
|
235
|
-
* over a file says what it did with each of them.
|
|
236
|
-
*/
|
|
237
|
-
const MATCH = {
|
|
238
|
-
name: "match",
|
|
239
|
-
summary: "filter text by a pinyin query, best first",
|
|
240
|
-
argument: "[text...]",
|
|
241
|
-
flags: [...MATCH_FLAGS],
|
|
242
|
-
needsDictionary: true,
|
|
243
|
-
run: (input) => {
|
|
244
|
-
const query = matchQuery(input.flags);
|
|
245
|
-
const found = input.texts.map((text) => ({
|
|
246
|
-
text,
|
|
247
|
-
match: match(dictionaryOf(input), text, query),
|
|
248
|
-
}));
|
|
249
|
-
const ranked = [
|
|
250
|
-
...found
|
|
251
|
-
.filter((one) => one.match !== undefined)
|
|
252
|
-
.toSorted((first, second) => (second.match?.score ?? 0) - (first.match?.score ?? 0)),
|
|
253
|
-
...found.filter((one) => one.match === undefined),
|
|
254
|
-
];
|
|
255
|
-
return ranked.map((one) => {
|
|
256
|
-
if (one.match === undefined) {
|
|
257
|
-
return {
|
|
258
|
-
lines: [`${one.text} no match`],
|
|
259
|
-
data: { query, text: one.text, matched: false },
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
// Rounded for the reason `explain` rounds a cost: a score is a sum of
|
|
263
|
-
// weights and a fraction, and 6.333333333333333 in a column tells a
|
|
264
|
-
// reader nothing the first two places do not.
|
|
265
|
-
const score = Math.round(one.match.score * 100) / 100;
|
|
266
|
-
return {
|
|
267
|
-
lines: [`${marked(one.text, one.match.ranges)} ${score.toFixed(2)}`],
|
|
268
|
-
data: {
|
|
269
|
-
query,
|
|
270
|
-
text: one.text,
|
|
271
|
-
matched: true,
|
|
272
|
-
score,
|
|
273
|
-
ranges: one.match.ranges.map((range) => ({
|
|
274
|
-
at: range.at,
|
|
275
|
-
length: range.length,
|
|
276
|
-
})),
|
|
277
|
-
},
|
|
278
|
-
};
|
|
279
|
-
});
|
|
280
|
-
},
|
|
281
|
-
};
|
|
282
|
-
/**
|
|
283
|
-
* The hanzi and the pinyin typed for it, as `check` is given them.
|
|
284
|
-
*
|
|
285
|
-
* Two arguments at a terminal — `pinyinjs check 银行 yínxíng` — with everything
|
|
286
|
-
* after the first joined back up, so that unquoted pinyin with spaces in it
|
|
287
|
-
* works the way anybody would expect it to. A piped file is one pair per line,
|
|
288
|
-
* separated by a tab, since pinyin has spaces in it and the hanzi may too.
|
|
289
|
-
*/
|
|
290
|
-
function checkPairs(texts) {
|
|
291
|
-
if (texts.some((text) => text.includes("\t"))) {
|
|
292
|
-
return texts.map((text) => {
|
|
293
|
-
const [hanzi = "", ...rest] = text.split("\t");
|
|
294
|
-
return [hanzi, rest.join("\t")];
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
const [hanzi = "", ...rest] = texts;
|
|
298
|
-
return [[hanzi, rest.join(" ")]];
|
|
299
|
-
}
|
|
300
|
-
/**
|
|
301
|
-
* One checked syllable, as a line and as data.
|
|
302
|
-
*
|
|
303
|
-
* The characters, then what was expected, then what was typed, then the two
|
|
304
|
-
* verdicts. Spacing is written only where it went wrong, since `correct` on
|
|
305
|
-
* every line would bury the one that did not.
|
|
306
|
-
*/
|
|
307
|
-
function checkedSyllable(one, input) {
|
|
308
|
-
const expected = one.expected === undefined ? "" : writeSyllable(one.expected);
|
|
309
|
-
// Written only where it went wrong: `correct` on every line would bury the
|
|
310
|
-
// one that did not.
|
|
311
|
-
const spacing = one.spacing === "correct" ? undefined : one.spacing;
|
|
312
|
-
return {
|
|
313
|
-
line: ` ${column(one.source ?? "", 6)}${column(input.paint(expected, one.expected?.tone), 8)}${column(one.text, 8)}${column(one.verdict, 10)}${spacing ?? ""}`.trimEnd(),
|
|
314
|
-
data: {
|
|
315
|
-
verdict: one.verdict,
|
|
316
|
-
isCorrect: one.isCorrect,
|
|
317
|
-
...(one.spacing !== undefined && { spacing: one.spacing }),
|
|
318
|
-
...(expected !== "" && { expected }),
|
|
319
|
-
...(one.text !== "" && { typed: one.text }),
|
|
320
|
-
...(one.source !== undefined && { source: one.source }),
|
|
321
|
-
...(one.at !== undefined && { at: one.at }),
|
|
322
|
-
},
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
/**
|
|
326
|
-
* Mark typed pinyin against the text it was written for.
|
|
327
|
-
*
|
|
328
|
-
* The heading carries the answer the text converts to, because a check that
|
|
329
|
-
* says only what is wrong leaves a reader hunting for what was right.
|
|
330
|
-
*/
|
|
331
|
-
const CHECK = {
|
|
332
|
-
name: "check",
|
|
333
|
-
summary: "mark typed pinyin against the text",
|
|
334
|
-
argument: "<text> <pinyin>",
|
|
335
|
-
flags: [...CONVERT_FLAGS, ...CHECK_FLAGS],
|
|
336
|
-
needsDictionary: true,
|
|
337
|
-
run: (input) => {
|
|
338
|
-
const dictionary = dictionaryOf(input);
|
|
339
|
-
const options = checkOptions(input.flags);
|
|
340
|
-
return checkPairs(input.texts).map(([text, typed]) => {
|
|
341
|
-
if (typed === "") {
|
|
342
|
-
throw new UsageError("check needs a text and the pinyin typed for it");
|
|
343
|
-
}
|
|
344
|
-
const marked = check(dictionary, text, typed, options);
|
|
345
|
-
const score = Math.round(marked.score * 100);
|
|
346
|
-
const syllables = marked.syllables.map((one) => checkedSyllable(one, input));
|
|
347
|
-
// The answer as the conversion writes it, spacing and all, since the
|
|
348
|
-
// spacing is one of the things being marked and a reading joined by
|
|
349
|
-
// spaces would show every word broken apart.
|
|
350
|
-
const pieces = convertPieces(dictionary, text, options);
|
|
351
|
-
return {
|
|
352
|
-
lines: [
|
|
353
|
-
`${text} ${paintedPieces(pieces, input)} ${String(score)}%`,
|
|
354
|
-
...syllables.map((one) => one.line),
|
|
355
|
-
],
|
|
356
|
-
data: {
|
|
357
|
-
text,
|
|
358
|
-
typed,
|
|
359
|
-
isCorrect: marked.isCorrect,
|
|
360
|
-
score: marked.score,
|
|
361
|
-
pinyin: pieces.map((piece) => piece.text).join(""),
|
|
362
|
-
syllables: syllables.map((one) => one.data),
|
|
363
|
-
},
|
|
364
|
-
};
|
|
365
|
-
});
|
|
366
|
-
},
|
|
367
|
-
};
|
|
368
|
-
/**
|
|
369
|
-
* Write a text as a slug.
|
|
370
|
-
*
|
|
371
|
-
* Uncoloured, for the reason `html` is: a slug is a string for a machine, and
|
|
372
|
-
* colouring the tones in something meant to be pasted into a URL would be
|
|
373
|
-
* putting escape codes where they cannot go.
|
|
374
|
-
*/
|
|
375
|
-
const SLUG = {
|
|
376
|
-
name: "slug",
|
|
377
|
-
summary: "hanzi to a URL-safe slug",
|
|
378
|
-
argument: "[text...]",
|
|
379
|
-
flags: [...SLUG_FLAGS],
|
|
380
|
-
needsDictionary: true,
|
|
381
|
-
run: (input) => {
|
|
382
|
-
const options = slugOptions(input.flags);
|
|
383
|
-
return input.texts.map((text) => {
|
|
384
|
-
const written = slug(dictionaryOf(input), text, options);
|
|
385
|
-
return { lines: [written], data: { text, slug: written } };
|
|
386
|
-
});
|
|
387
|
-
},
|
|
388
|
-
};
|
|
389
|
-
/**
|
|
390
|
-
* The tables a command declared it needs.
|
|
391
|
-
*/
|
|
392
|
-
function scriptTablesOf(input) {
|
|
393
|
-
/* c8 ignore next 3 -- loaded for every command that declares it needs them */
|
|
394
|
-
if (input.scriptTables === undefined) {
|
|
395
|
-
throw new UsageError("the script conversion tables were not loaded");
|
|
396
|
-
}
|
|
397
|
-
return input.scriptTables;
|
|
398
|
-
}
|
|
399
|
-
/**
|
|
400
|
-
* Convert between 简体 and 繁體, one line in and one line out.
|
|
401
|
-
*
|
|
402
|
-
* The per-character evidence rides in the JSON rather than the lines, because
|
|
403
|
-
* the answer a person wants here is the converted text and a second column of
|
|
404
|
-
* `locked` on every character would bury it. `--json` carries what was a guess.
|
|
405
|
-
*/
|
|
406
|
-
const SCRIPT = {
|
|
407
|
-
name: "script",
|
|
408
|
-
summary: "简体 ↔ 繁體 conversion",
|
|
409
|
-
argument: "[text...]",
|
|
410
|
-
flags: [...SCRIPT_FLAGS],
|
|
411
|
-
needsDictionary: true,
|
|
412
|
-
needsScriptTables: true,
|
|
413
|
-
run: (input) => {
|
|
414
|
-
const to = scriptTarget(input.flags);
|
|
415
|
-
const from = scriptFrom(input.flags);
|
|
416
|
-
return input.texts.map((text) => {
|
|
417
|
-
const { text: written, choices } = toScriptPieces(dictionaryOf(input), scriptTablesOf(input), text, { to, ...(from !== undefined && { from }) });
|
|
418
|
-
return {
|
|
419
|
-
lines: [written],
|
|
420
|
-
data: {
|
|
421
|
-
text,
|
|
422
|
-
script: written,
|
|
423
|
-
to,
|
|
424
|
-
characters: choices.map((choice) => ({
|
|
425
|
-
from: choice.from,
|
|
426
|
-
to: choice.to,
|
|
427
|
-
evidence: choice.evidence,
|
|
428
|
-
...(choice.alternatives.length > 0 && {
|
|
429
|
-
alternatives: [...choice.alternatives],
|
|
430
|
-
}),
|
|
431
|
-
})),
|
|
432
|
-
uncertain: choices
|
|
433
|
-
.filter((choice) => isUncertainChoice(choice))
|
|
434
|
-
.map((choice) => choice.from),
|
|
435
|
-
},
|
|
436
|
-
};
|
|
437
|
-
});
|
|
438
|
-
},
|
|
439
|
-
};
|
|
440
|
-
/**
|
|
441
|
-
* One decoded syllable, as `explain` reports it.
|
|
442
|
-
*/
|
|
443
|
-
function explainSyllable(piece, input) {
|
|
444
|
-
const state = stateOf(piece);
|
|
445
|
-
const alternatives = alternativesOf(piece, input);
|
|
446
|
-
const beaten = alternatives
|
|
447
|
-
.map((alternative) => `${alternative.painted} +${alternative.cost.toFixed(1)}`)
|
|
448
|
-
.join(" ");
|
|
449
|
-
return {
|
|
450
|
-
// The state stays a word. Colour means tone in every command, including
|
|
451
|
-
// this one: two scales on one line and a reader cannot tell which is which.
|
|
452
|
-
line: ` ${column(input.paint(piece.text, piece.syllable?.tone), 8)}${column(state, 8)}${beaten}`.trimEnd(),
|
|
453
|
-
data: {
|
|
454
|
-
text: piece.text,
|
|
455
|
-
state,
|
|
456
|
-
...(piece.syllable?.tone !== undefined && { tone: piece.syllable.tone }),
|
|
457
|
-
alternatives: alternatives.map(({ reading, cost }) => ({
|
|
458
|
-
reading,
|
|
459
|
-
cost,
|
|
460
|
-
})),
|
|
461
|
-
},
|
|
462
|
-
};
|
|
463
|
-
}
|
|
464
|
-
/**
|
|
465
|
-
* Show what the decoder chose, syllable by syllable, and what it rejected.
|
|
466
|
-
*/
|
|
467
|
-
const EXPLAIN = {
|
|
468
|
-
name: "explain",
|
|
469
|
-
summary: "show each syllable, how settled it was, and what it beat",
|
|
470
|
-
argument: "[text...]",
|
|
471
|
-
flags: [...CONVERT_FLAGS],
|
|
472
|
-
needsDictionary: true,
|
|
473
|
-
run: (input) => {
|
|
474
|
-
const dictionary = dictionaryOf(input);
|
|
475
|
-
const options = convertOptions(input.flags);
|
|
476
|
-
return input.texts.map((text) => {
|
|
477
|
-
const pieces = convertPieces(dictionary, text, options);
|
|
478
|
-
const pinyin = pieces.map((piece) => piece.text).join("");
|
|
479
|
-
const syllables = pieces
|
|
480
|
-
.filter((piece) => piece.syllable !== undefined)
|
|
481
|
-
.map((piece) => explainSyllable(piece, input));
|
|
482
|
-
return {
|
|
483
|
-
lines: [
|
|
484
|
-
`${text} ${paintedPieces(pieces, input)}`,
|
|
485
|
-
...syllables.map((syllable) => syllable.line),
|
|
486
|
-
],
|
|
487
|
-
data: {
|
|
488
|
-
text,
|
|
489
|
-
pinyin,
|
|
490
|
-
syllables: syllables.map((syllable) => syllable.data),
|
|
491
|
-
},
|
|
492
|
-
};
|
|
493
|
-
});
|
|
494
|
-
},
|
|
495
|
-
};
|
|
496
|
-
/**
|
|
497
|
-
* What the dictionary holds for a word.
|
|
498
|
-
*/
|
|
499
|
-
function entryFound(dictionary, word, paint) {
|
|
500
|
-
const entry = dictionary.lookup(word);
|
|
501
|
-
if (entry === undefined) {
|
|
502
|
-
return {
|
|
503
|
-
lines: [`${word} not in the dictionary`],
|
|
504
|
-
data: { word, found: false },
|
|
505
|
-
};
|
|
506
|
-
}
|
|
507
|
-
const tags = [
|
|
508
|
-
entry.partOfSpeech,
|
|
509
|
-
entry.isProperNoun ? "proper noun" : "",
|
|
510
|
-
].filter((tag) => tag !== "");
|
|
511
|
-
const others = dictionary.readingsOf(word).slice(1);
|
|
512
|
-
return {
|
|
513
|
-
lines: [
|
|
514
|
-
`${word} ${written(entry.reading, paint)}${tags.length > 0 ? ` ${tags.join(", ")}` : ""}`,
|
|
515
|
-
...(entry.taiwanReading === undefined
|
|
516
|
-
? []
|
|
517
|
-
: [` zh-TW ${written(entry.taiwanReading, paint)}`]),
|
|
518
|
-
...(others.length > 0
|
|
519
|
-
? [
|
|
520
|
-
` also ${others
|
|
521
|
-
.map((reading) => written(reading, paint))
|
|
522
|
-
.join(", ")}`,
|
|
523
|
-
]
|
|
524
|
-
: []),
|
|
525
|
-
],
|
|
526
|
-
data: {
|
|
527
|
-
word,
|
|
528
|
-
found: true,
|
|
529
|
-
reading: written(entry.reading, PLAIN),
|
|
530
|
-
partOfSpeech: entry.partOfSpeech,
|
|
531
|
-
isProperNoun: entry.isProperNoun,
|
|
532
|
-
...(entry.taiwanReading !== undefined && {
|
|
533
|
-
taiwanReading: written(entry.taiwanReading, PLAIN),
|
|
534
|
-
}),
|
|
535
|
-
otherReadings: others.map((reading) => written(reading, PLAIN)),
|
|
536
|
-
},
|
|
537
|
-
};
|
|
538
|
-
}
|
|
539
|
-
/**
|
|
540
|
-
* Look words up in the dictionary.
|
|
541
|
-
*/
|
|
542
|
-
const LOOKUP = {
|
|
543
|
-
name: "lookup",
|
|
544
|
-
summary: "what the dictionary holds for a word",
|
|
545
|
-
argument: "<word...>",
|
|
546
|
-
flags: [],
|
|
547
|
-
needsDictionary: true,
|
|
548
|
-
run: (input) => input.texts.map((word) => entryFound(dictionaryOf(input), word, input.paint)),
|
|
549
|
-
};
|
|
550
|
-
/**
|
|
551
|
-
* One written syllable, taken apart.
|
|
552
|
-
*/
|
|
553
|
-
function syllableTaken(spelling, paint) {
|
|
554
|
-
const syllable = readSyllable(spelling);
|
|
555
|
-
/* c8 ignore next 6 -- splitSyllables only ever emits syllables that read */
|
|
556
|
-
if (syllable === undefined) {
|
|
557
|
-
return {
|
|
558
|
-
line: ` ${column(spelling, 10)}not a syllable`,
|
|
559
|
-
data: { spelling },
|
|
560
|
-
};
|
|
561
|
-
}
|
|
562
|
-
const isAttested = DICTIONARY_SYLLABLES.has(writeSyllableSpelling({ ...syllable, erhua: false }));
|
|
563
|
-
const parts = [
|
|
564
|
-
`${syllable.initial === "" ? "∅" : syllable.initial} + ${syllable.final}`,
|
|
565
|
-
syllable.tone === undefined ? "no tone" : `tone ${String(syllable.tone)}`,
|
|
566
|
-
...(syllable.erhua === true ? ["儿化"] : []),
|
|
567
|
-
];
|
|
568
|
-
const notations = {
|
|
569
|
-
marks: writeSyllable(syllable),
|
|
570
|
-
numbers: writeSyllable(syllable, "numbers"),
|
|
571
|
-
superscript: writeSyllable(syllable, "superscript"),
|
|
572
|
-
};
|
|
573
|
-
return {
|
|
574
|
-
line: ` ${column(paint(spelling, syllable.tone), 10)}${column(parts.join(", "), 22)}${column(Object.values(notations)
|
|
575
|
-
.map((written) => paint(written, syllable.tone))
|
|
576
|
-
.join(" "), 22)}${isAttested ? "" : "not attested"}`.trimEnd(),
|
|
577
|
-
data: {
|
|
578
|
-
spelling,
|
|
579
|
-
initial: syllable.initial,
|
|
580
|
-
final: syllable.final,
|
|
581
|
-
...(syllable.tone !== undefined && { tone: syllable.tone }),
|
|
582
|
-
erhua: syllable.erhua === true,
|
|
583
|
-
isAttested,
|
|
584
|
-
...notations,
|
|
585
|
-
},
|
|
586
|
-
};
|
|
587
|
-
}
|
|
588
|
-
/**
|
|
589
|
-
* Take written pinyin apart, with no dictionary at all.
|
|
590
|
-
*/
|
|
591
|
-
const SYLLABLE = {
|
|
592
|
-
name: "syllable",
|
|
593
|
-
summary: "take written pinyin apart, with no dictionary",
|
|
594
|
-
argument: "<pinyin...>",
|
|
595
|
-
flags: [],
|
|
596
|
-
needsDictionary: false,
|
|
597
|
-
run: (input) => input.texts.map((text) => {
|
|
598
|
-
const split = splitSyllables(text);
|
|
599
|
-
if (split === undefined) {
|
|
600
|
-
return {
|
|
601
|
-
lines: [`${text} not readable as pinyin`],
|
|
602
|
-
data: { text, read: false },
|
|
603
|
-
};
|
|
604
|
-
}
|
|
605
|
-
const taken = split.map((spelling) => syllableTaken(spelling, input.paint));
|
|
606
|
-
return {
|
|
607
|
-
lines: [
|
|
608
|
-
`${text} ${split
|
|
609
|
-
.map((spelling) => input.paint(spelling, readSyllable(spelling)?.tone))
|
|
610
|
-
.join(" ")}`,
|
|
611
|
-
...taken.map((syllable) => syllable.line),
|
|
612
|
-
],
|
|
613
|
-
data: {
|
|
614
|
-
text,
|
|
615
|
-
read: true,
|
|
616
|
-
syllables: taken.map((syllable) => syllable.data),
|
|
617
|
-
},
|
|
618
|
-
};
|
|
619
|
-
}),
|
|
620
|
-
};
|
|
621
|
-
/**
|
|
622
|
-
* Apply sandhi to written pinyin, with no dictionary at all.
|
|
623
|
-
*/
|
|
624
|
-
const SANDHI = {
|
|
625
|
-
name: "sandhi",
|
|
626
|
-
summary: "apply tone sandhi to written pinyin",
|
|
627
|
-
argument: "<pinyin...>",
|
|
628
|
-
flags: ["third-tone", "no-sandhi"],
|
|
629
|
-
needsDictionary: false,
|
|
630
|
-
run: (input) => {
|
|
631
|
-
const options = convertOptions(input.flags).sandhi;
|
|
632
|
-
return input.texts.map((text) => {
|
|
633
|
-
// Whitespace is the only word boundary written pinyin has, and third-tone
|
|
634
|
-
// sandhi needs it: 行長很喜歡 is `hángzhǎng hén xǐhuan`, where a scan that
|
|
635
|
-
// could not see the boundary would lower the 長 as well.
|
|
636
|
-
const words = text
|
|
637
|
-
.split(/\s+/u)
|
|
638
|
-
.filter((part) => part !== "")
|
|
639
|
-
.map((part) => readWord(part));
|
|
640
|
-
if (words.length === 0 || words.some((word) => word === undefined)) {
|
|
641
|
-
return {
|
|
642
|
-
lines: [`${text} not readable as pinyin`],
|
|
643
|
-
data: { text, read: false },
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
const read = words.filter((word) => word !== undefined);
|
|
647
|
-
const said = applySandhi(read.flat(), options, read.map((word) => word.length));
|
|
648
|
-
return {
|
|
649
|
-
lines: [`${text} ${written(said, input.paint)}`],
|
|
650
|
-
data: { text, read: true, pinyin: written(said, PLAIN) },
|
|
651
|
-
};
|
|
652
|
-
});
|
|
653
|
-
},
|
|
654
|
-
};
|
|
655
|
-
const BOPOMOFO = {
|
|
656
|
-
name: "bopomofo",
|
|
657
|
-
write: writeBopomofo,
|
|
658
|
-
separator: " ",
|
|
659
|
-
word: (syllables) => writeBopomofoWord(syllables),
|
|
660
|
-
capitals: false,
|
|
661
|
-
};
|
|
662
|
-
const WADE_GILES = {
|
|
663
|
-
name: "wade-giles",
|
|
664
|
-
write: writeWadeGiles,
|
|
665
|
-
separator: "-",
|
|
666
|
-
word: (syllables, hasTones) => writeWadeGilesWord(syllables, hasTones ? {} : { tones: "none" }),
|
|
667
|
-
capitals: true,
|
|
668
|
-
};
|
|
669
|
-
const YALE = {
|
|
670
|
-
name: "yale",
|
|
671
|
-
write: writeYale,
|
|
672
|
-
separator: "",
|
|
673
|
-
word: (syllables, hasTones) => writeYaleWord(syllables, hasTones ? {} : { tones: "none" }),
|
|
674
|
-
capitals: true,
|
|
675
|
-
};
|
|
676
|
-
const GWOYEU = {
|
|
677
|
-
name: "gwoyeu",
|
|
678
|
-
write: writeGwoyeu,
|
|
679
|
-
separator: "",
|
|
680
|
-
word: (syllables) => writeGwoyeuWord(syllables),
|
|
681
|
-
capitals: true,
|
|
682
|
-
};
|
|
683
|
-
const IPA = {
|
|
684
|
-
name: "ipa",
|
|
685
|
-
write: writeIpa,
|
|
686
|
-
separator: "",
|
|
687
|
-
word: (syllables, hasTones) => writeIpaWord(syllables, hasTones ? {} : { tones: "none" }),
|
|
688
|
-
capitals: false,
|
|
689
|
-
};
|
|
690
|
-
/**
|
|
691
|
-
* Every system `transcribe` writes a column for, for the guard above.
|
|
692
|
-
*/
|
|
693
|
-
export const SYSTEMS = [
|
|
694
|
-
BOPOMOFO,
|
|
695
|
-
WADE_GILES,
|
|
696
|
-
YALE,
|
|
697
|
-
GWOYEU,
|
|
698
|
-
IPA,
|
|
699
|
-
];
|
|
700
|
-
/**
|
|
701
|
-
* The system a `--system` or `--from` name stands for.
|
|
702
|
-
*/
|
|
703
|
-
export function systemNamed(name) {
|
|
704
|
-
return SYSTEMS.find((system) => system.name === name);
|
|
705
|
-
}
|
|
706
|
-
/**
|
|
707
|
-
* Write a run of syllables in one system, each syllable in its tone's colour.
|
|
708
|
-
*/
|
|
709
|
-
export function writtenWith(syllables, system, paint) {
|
|
710
|
-
return syllables
|
|
711
|
-
.map((syllable) => paint(system.write(syllable), syllable.tone))
|
|
712
|
-
.join(system.separator);
|
|
713
|
-
}
|
|
714
|
-
/**
|
|
715
|
-
* Write a run of syllables in every system.
|
|
716
|
-
*/
|
|
717
|
-
function transcribed(reading, flags, paint) {
|
|
718
|
-
const { notation } = convertOptions(flags);
|
|
719
|
-
const { syllables, isExact } = reading;
|
|
720
|
-
return {
|
|
721
|
-
pinyin: syllables
|
|
722
|
-
.map((syllable) => paint(writeSyllable(syllable, notation), syllable.tone))
|
|
723
|
-
.join(""),
|
|
724
|
-
bopomofo: writtenWith(syllables, BOPOMOFO, paint),
|
|
725
|
-
wadeGiles: writtenWith(syllables, WADE_GILES, paint),
|
|
726
|
-
yale: writtenWith(syllables, YALE, paint),
|
|
727
|
-
gwoyeu: writtenWith(syllables, GWOYEU, paint),
|
|
728
|
-
ipa: writtenWith(syllables, IPA, paint),
|
|
729
|
-
...(isExact !== undefined && { isExact }),
|
|
730
|
-
};
|
|
731
|
-
}
|
|
732
|
-
/**
|
|
733
|
-
* Read Wade-Giles, keeping track of which candidates were spelled exactly.
|
|
734
|
-
*
|
|
735
|
-
* Always the loose reader, because the exact one is a strict subset of it and
|
|
736
|
-
* the interesting case at a command line is the spelling that dropped its
|
|
737
|
-
* marks. Which candidates needed repairing is shown rather than hidden — that
|
|
738
|
-
* is the one thing a person looking at Wade-Giles wants to know.
|
|
739
|
-
*
|
|
740
|
-
* **A word gets one row and a syllable gets every candidate**, which is the
|
|
741
|
-
* only honest way to show both. `chu` stands for four syllables and all four
|
|
742
|
-
* fit on the screen; `maotsetung` splits five ways before any of its syllables
|
|
743
|
-
* has been chosen, so what is shown is the reading
|
|
744
|
-
* {@link readWadeGilesWord} settles on — 56.02% of markless words, by the
|
|
745
|
-
* measurement in `docs/romanization/`.
|
|
746
|
-
*/
|
|
747
|
-
function fromWadeGiles(text) {
|
|
748
|
-
const split = splitWadeGiles(text);
|
|
749
|
-
if (split !== undefined && split.length > 1) {
|
|
750
|
-
const word = readWadeGilesWord(text);
|
|
751
|
-
return word === undefined
|
|
752
|
-
? /* c8 ignore next -- a run that splits always reads */ []
|
|
753
|
-
: [
|
|
754
|
-
{
|
|
755
|
-
syllables: word,
|
|
756
|
-
isExact: split.every((spelling) => readWadeGiles(spelling).length > 0),
|
|
757
|
-
},
|
|
758
|
-
];
|
|
759
|
-
}
|
|
760
|
-
const exact = new Set(readWadeGiles(text).map((syllable) => writeSyllable(syllable)));
|
|
761
|
-
return readWadeGilesLoosely(text).map((syllable) => ({
|
|
762
|
-
syllables: [syllable],
|
|
763
|
-
isExact: exact.has(writeSyllable(syllable)),
|
|
764
|
-
}));
|
|
765
|
-
}
|
|
766
|
-
/**
|
|
767
|
-
* The systems that read back as a plain list of candidates.
|
|
768
|
-
*
|
|
769
|
-
* Wade-Giles is not among them because it has a second, looser reader to run;
|
|
770
|
-
* bopomofo is not because it needs no flag at all.
|
|
771
|
-
*/
|
|
772
|
-
const INDEXED_READERS = new Map([
|
|
773
|
-
["yale", readYale],
|
|
774
|
-
["gwoyeu", readGwoyeu],
|
|
775
|
-
["ipa", readIpa],
|
|
776
|
-
]);
|
|
777
|
-
/**
|
|
778
|
-
* Read whatever system the text is in, and say so.
|
|
779
|
-
*/
|
|
780
|
-
function transcriptions(text, flags) {
|
|
781
|
-
const from = transcriptionSource(flags);
|
|
782
|
-
if (from === "wade-giles") {
|
|
783
|
-
return fromWadeGiles(text);
|
|
784
|
-
}
|
|
785
|
-
const reader = INDEXED_READERS.get(from);
|
|
786
|
-
if (reader !== undefined) {
|
|
787
|
-
return reader(text).map((syllable) => ({ syllables: [syllable] }));
|
|
788
|
-
}
|
|
789
|
-
// Bopomofo needs no flag to be recognised: it has a script of its own, so a
|
|
790
|
-
// caller can only mean one thing by it. Wade-Giles and pinyin overlap almost
|
|
791
|
-
// entirely, so those have to be declared.
|
|
792
|
-
if (from === "bopomofo" || (from === "auto" && isBopomofo(text))) {
|
|
793
|
-
const syllable = readBopomofo(text);
|
|
794
|
-
return syllable === undefined ? [] : [{ syllables: [syllable] }];
|
|
795
|
-
}
|
|
796
|
-
const split = splitSyllables(text);
|
|
797
|
-
const syllables = (split ?? []).flatMap((spelling) => {
|
|
798
|
-
const syllable = readSyllable(spelling);
|
|
799
|
-
/* c8 ignore next -- splitSyllables only emits syllables that read */
|
|
800
|
-
return syllable === undefined ? [] : [syllable];
|
|
801
|
-
});
|
|
802
|
-
return syllables.length === 0 ? [] : [{ syllables }];
|
|
803
|
-
}
|
|
804
|
-
/**
|
|
805
|
-
* How wide each of `transcribe`'s columns is when its cells are narrow.
|
|
806
|
-
*
|
|
807
|
-
* A floor rather than the width: a whole word is wider than a syllable, and
|
|
808
|
-
* `mao-tsʻê-tung` is thirteen characters in a column sized for `ch'ü¹`. The
|
|
809
|
-
* widths are kept as a floor so that a single syllable still lines up with the
|
|
810
|
-
* next answer down when a file is piped through, and so that widening one row
|
|
811
|
-
* does not move every example in the docs.
|
|
812
|
-
*/
|
|
813
|
-
const TRANSCRIBE_WIDTHS = [12, 10, 12, 12, 10, 10, 12, 0];
|
|
814
|
-
/**
|
|
815
|
-
* Lay rows of cells out in columns, each as wide as it needs to be.
|
|
816
|
-
*/
|
|
817
|
-
function laidOut(rows) {
|
|
818
|
-
const widths = TRANSCRIBE_WIDTHS.map((floor, at) => Math.max(floor, ...rows.map((row) => {
|
|
819
|
-
// A cell needs one space after it at least, which is what the floor
|
|
820
|
-
// gives the widest syllable already. Only a cell that does not fit
|
|
821
|
-
// widens the column, and then it takes two — so a single syllable is
|
|
822
|
-
// laid out exactly as it was before words could arrive.
|
|
823
|
-
const width = visibleLength(row[at] ?? "");
|
|
824
|
-
return width + 1 > floor ? width + 2 : 0;
|
|
825
|
-
})));
|
|
826
|
-
return rows.map((row) => row
|
|
827
|
-
.map((cell, at) => column(cell, widths[at] ?? 0))
|
|
828
|
-
.join("")
|
|
829
|
-
.trimEnd());
|
|
830
|
-
}
|
|
831
|
-
/**
|
|
832
|
-
* Write pinyin in every other system, and read any of them back.
|
|
833
|
-
*
|
|
834
|
-
* Not `romanize`, for two reasons: bopomofo has a script of its own and IPA is
|
|
835
|
-
* a transcription rather than a spelling, so half the columns are not
|
|
836
|
-
* romanisations — and the input is pinyin, which already is one. *Comparison of
|
|
837
|
-
* Standard Chinese transcription systems*, the syllabary these tables are
|
|
838
|
-
* checked against, is the source of the word as well as of the columns.
|
|
839
|
-
*
|
|
840
|
-
* Needs no dictionary, for the same reason `syllable` does: a transcription is
|
|
841
|
-
* a mapping over syllables and there is nothing to look up. Several rows come
|
|
842
|
-
* back where Wade-Giles is ambiguous, which is most of it once the apostrophes
|
|
843
|
-
* and diacritics have been dropped.
|
|
844
|
-
*/
|
|
845
|
-
const TRANSCRIBE = {
|
|
846
|
-
name: "transcribe",
|
|
847
|
-
summary: "pinyin to bopomofo, Wade-Giles, Yale, GR and IPA, and back",
|
|
848
|
-
argument: "<text...>",
|
|
849
|
-
flags: ["notation", "from"],
|
|
850
|
-
needsDictionary: false,
|
|
851
|
-
run: (input) => input.texts.map((text) => {
|
|
852
|
-
const found = transcriptions(text, input.flags);
|
|
853
|
-
if (found.length === 0) {
|
|
854
|
-
return {
|
|
855
|
-
lines: [`${text} not readable`],
|
|
856
|
-
data: { text, read: false },
|
|
857
|
-
};
|
|
858
|
-
}
|
|
859
|
-
return {
|
|
860
|
-
lines: laidOut(found.map((reading, index) => {
|
|
861
|
-
const one = transcribed(reading, input.flags, input.paint);
|
|
862
|
-
return [
|
|
863
|
-
index === 0 ? text : "",
|
|
864
|
-
one.pinyin,
|
|
865
|
-
one.bopomofo,
|
|
866
|
-
one.wadeGiles,
|
|
867
|
-
one.yale,
|
|
868
|
-
one.gwoyeu,
|
|
869
|
-
one.ipa,
|
|
870
|
-
one.isExact === false ? "marks restored" : "",
|
|
871
|
-
];
|
|
872
|
-
})),
|
|
873
|
-
data: {
|
|
874
|
-
text,
|
|
875
|
-
read: true,
|
|
876
|
-
readings: found.map((reading) => transcribed(reading, input.flags, PLAIN)),
|
|
877
|
-
},
|
|
878
|
-
};
|
|
879
|
-
}),
|
|
880
|
-
};
|
|
881
|
-
/**
|
|
882
|
-
* Report what is loaded, which is the first thing to check when output looks
|
|
883
|
-
* wrong.
|
|
884
|
-
*/
|
|
885
|
-
const INFO = {
|
|
886
|
-
name: "info",
|
|
887
|
-
summary: "which dictionary is loaded, and how big it is",
|
|
888
|
-
argument: "",
|
|
889
|
-
flags: [],
|
|
890
|
-
needsDictionary: true,
|
|
891
|
-
run: (input) => {
|
|
892
|
-
const keys = dictionaryOf(input).size;
|
|
893
|
-
const directory = input.choice.directory;
|
|
894
|
-
return [
|
|
895
|
-
{
|
|
896
|
-
lines: [
|
|
897
|
-
`tier ${input.choice.tier}`,
|
|
898
|
-
`data ${directory ?? "the artifacts that shipped"}`,
|
|
899
|
-
`keys ${keys.toLocaleString("en-GB")}`,
|
|
900
|
-
`syllables ${String(ATTESTED_SYLLABLES.length)} attested, ${String(DICTIONARY_SYLLABLES.size)} spellings in the inventory`,
|
|
901
|
-
],
|
|
902
|
-
data: {
|
|
903
|
-
tier: input.choice.tier,
|
|
904
|
-
...(directory !== undefined && { data: directory }),
|
|
905
|
-
keys,
|
|
906
|
-
attestedSyllables: ATTESTED_SYLLABLES.length,
|
|
907
|
-
inventorySpellings: DICTIONARY_SYLLABLES.size,
|
|
908
|
-
},
|
|
909
|
-
},
|
|
910
|
-
];
|
|
911
|
-
},
|
|
912
|
-
};
|
|
913
|
-
/**
|
|
914
|
-
* Apply the sandhi a counted quantity takes, and only there.
|
|
915
|
-
*
|
|
916
|
-
* 一百 is said `yìbǎi`, but 110 read out is `yāo yāo líng` and never
|
|
917
|
-
* `yì yì líng`, and 3.14 is `sān diǎn yī sì`: a digit said on its own keeps its
|
|
918
|
-
* citation tone, and so does everything after the decimal point, which is read
|
|
919
|
-
* digit by digit whatever the style. So the sandhi pass runs over the counted
|
|
920
|
-
* part of the number and stops at the 点.
|
|
921
|
-
*/
|
|
922
|
-
function counted(hanzi, reading, options, sandhi) {
|
|
923
|
-
if (options.style === "digits") {
|
|
924
|
-
return reading;
|
|
925
|
-
}
|
|
926
|
-
const point = toCharacters(hanzi).indexOf("点");
|
|
927
|
-
const quantity = point === -1 ? reading.length : point;
|
|
928
|
-
return [
|
|
929
|
-
...applySandhi(reading.slice(0, quantity), sandhi),
|
|
930
|
-
...reading.slice(quantity),
|
|
931
|
-
];
|
|
932
|
-
}
|
|
933
|
-
/**
|
|
934
|
-
* Read numbers aloud, as quantities or digit by digit.
|
|
935
|
-
*
|
|
936
|
-
* Needs no dictionary, for the same reason `syllable` and `sandhi` do not:
|
|
937
|
-
* reading a number is arithmetic and a twenty-entry reading table, not a
|
|
938
|
-
* lookup. Which of the two styles a number takes is the caller's to say —
|
|
939
|
-
* 2026年 is read out digit by digit and 2026个 is counted — so the flag is
|
|
940
|
-
* where that choice lives rather than a guess about the text around it.
|
|
941
|
-
*/
|
|
942
|
-
const NUMBER = {
|
|
943
|
-
name: "number",
|
|
944
|
-
summary: "read a number as Chinese numerals",
|
|
945
|
-
argument: "<number...>",
|
|
946
|
-
flags: [
|
|
947
|
-
"notation",
|
|
948
|
-
"digits",
|
|
949
|
-
"yao",
|
|
950
|
-
"no-liang",
|
|
951
|
-
"percent",
|
|
952
|
-
"third-tone",
|
|
953
|
-
"no-sandhi",
|
|
954
|
-
],
|
|
955
|
-
needsDictionary: false,
|
|
956
|
-
run: (input) => {
|
|
957
|
-
const { notation, sandhi } = convertOptions(input.flags);
|
|
958
|
-
const options = {
|
|
959
|
-
style: input.flags.digits === true ? "digits" : "cardinal",
|
|
960
|
-
...(input.flags.yao === true && { yao: true }),
|
|
961
|
-
...(input.flags["no-liang"] === true && { liang: "never" }),
|
|
962
|
-
};
|
|
963
|
-
return input.texts.map((text) => {
|
|
964
|
-
const hanzi = input.flags.percent === true
|
|
965
|
-
? percentHanzi(text, options)
|
|
966
|
-
: numeralHanzi(text, options);
|
|
967
|
-
const reading = hanzi === undefined ? undefined : readNumeralHanzi(hanzi, options);
|
|
968
|
-
if (hanzi === undefined || reading === undefined) {
|
|
969
|
-
return {
|
|
970
|
-
lines: [`${text} not a number`],
|
|
971
|
-
data: { text, read: false },
|
|
972
|
-
};
|
|
973
|
-
}
|
|
974
|
-
const said = counted(hanzi, reading, options, sandhi);
|
|
975
|
-
const spelled = said.map((syllable) => writeSyllable(syllable, notation));
|
|
976
|
-
return {
|
|
977
|
-
lines: [
|
|
978
|
-
`${column(text, 12)}${column(hanzi, 18)}${spelled
|
|
979
|
-
.map((written, at) => input.paint(written, said[at]?.tone))
|
|
980
|
-
.join(" ")}`,
|
|
981
|
-
],
|
|
982
|
-
data: {
|
|
983
|
-
text,
|
|
984
|
-
hanzi,
|
|
985
|
-
pinyin: spelled.join(" "),
|
|
986
|
-
style: options.style,
|
|
987
|
-
},
|
|
988
|
-
};
|
|
989
|
-
});
|
|
990
|
-
},
|
|
991
|
-
};
|
|
1
|
+
import { TRANSCRIBE } from "./transcribe-command.js";
|
|
2
|
+
import { SLUG } from "./slug-command.js";
|
|
3
|
+
import { SCRIPT } from "./script-command.js";
|
|
4
|
+
import { EXPLAIN } from "./explain-command.js";
|
|
5
|
+
import { LOOKUP, SANDHI } from "./lookup-commands.js";
|
|
6
|
+
import { SYLLABLE } from "./syllable-command.js";
|
|
7
|
+
import { CHECK } from "./check-command.js";
|
|
8
|
+
import { MATCH } from "./match-command.js";
|
|
9
|
+
import { CONVERT } from "./convert-command.js";
|
|
10
|
+
import { ANNOTATE, HTML } from "./html-commands.js";
|
|
11
|
+
import { SEGMENT } from "./segment-command.js";
|
|
12
|
+
import { INFO } from "./info-command.js";
|
|
13
|
+
import { NUMBER } from "./number-command.js";
|
|
14
|
+
export { SYSTEMS, systemNamed, writtenWith, } from "./transcribe-command.js";
|
|
992
15
|
/**
|
|
993
16
|
* Every subcommand, in the order the help lists them.
|
|
994
17
|
*/
|