@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.
Files changed (695) hide show
  1. package/dist/accuracy/score-case.d.ts +23 -0
  2. package/dist/accuracy/score-case.d.ts.map +1 -0
  3. package/dist/accuracy/score-case.js +63 -0
  4. package/dist/accuracy/score-case.js.map +1 -0
  5. package/dist/accuracy/score.d.ts +1 -8
  6. package/dist/accuracy/score.d.ts.map +1 -1
  7. package/dist/accuracy/score.js +1 -55
  8. package/dist/accuracy/score.js.map +1 -1
  9. package/dist/cli/arguments.d.ts +4 -290
  10. package/dist/cli/arguments.d.ts.map +1 -1
  11. package/dist/cli/arguments.js +5 -357
  12. package/dist/cli/arguments.js.map +1 -1
  13. package/dist/cli/check-command.d.ts +9 -0
  14. package/dist/cli/check-command.d.ts.map +1 -0
  15. package/dist/cli/check-command.js +95 -0
  16. package/dist/cli/check-command.js.map +1 -0
  17. package/dist/cli/cli-input.d.ts +49 -0
  18. package/dist/cli/cli-input.d.ts.map +1 -0
  19. package/dist/cli/cli-input.js +31 -0
  20. package/dist/cli/cli-input.js.map +1 -0
  21. package/dist/cli/command.d.ts +97 -0
  22. package/dist/cli/command.d.ts.map +1 -0
  23. package/dist/cli/command.js +40 -0
  24. package/dist/cli/command.js.map +1 -0
  25. package/dist/cli/commands.d.ts +7 -110
  26. package/dist/cli/commands.d.ts.map +1 -1
  27. package/dist/cli/commands.js +14 -991
  28. package/dist/cli/commands.js.map +1 -1
  29. package/dist/cli/convert-command.d.ts +6 -0
  30. package/dist/cli/convert-command.d.ts.map +1 -0
  31. package/dist/cli/convert-command.js +52 -0
  32. package/dist/cli/convert-command.js.map +1 -0
  33. package/dist/cli/environment.d.ts +1 -1
  34. package/dist/cli/environment.d.ts.map +1 -1
  35. package/dist/cli/explain-command.d.ts +6 -0
  36. package/dist/cli/explain-command.d.ts.map +1 -0
  37. package/dist/cli/explain-command.js +40 -0
  38. package/dist/cli/explain-command.js.map +1 -0
  39. package/dist/cli/explain-syllable.d.ts +10 -0
  40. package/dist/cli/explain-syllable.d.ts.map +1 -0
  41. package/dist/cli/explain-syllable.js +70 -0
  42. package/dist/cli/explain-syllable.js.map +1 -0
  43. package/dist/cli/flag-help.d.ts +18 -0
  44. package/dist/cli/flag-help.d.ts.map +1 -0
  45. package/dist/cli/flag-help.js +78 -0
  46. package/dist/cli/flag-help.js.map +1 -0
  47. package/dist/cli/flag-lists.d.ts +49 -0
  48. package/dist/cli/flag-lists.d.ts.map +1 -0
  49. package/dist/cli/flag-lists.js +58 -0
  50. package/dist/cli/flag-lists.js.map +1 -0
  51. package/dist/cli/flag-values.d.ts +44 -0
  52. package/dist/cli/flag-values.d.ts.map +1 -0
  53. package/dist/cli/flag-values.js +56 -0
  54. package/dist/cli/flag-values.js.map +1 -0
  55. package/dist/cli/flags.d.ts +193 -0
  56. package/dist/cli/flags.d.ts.map +1 -0
  57. package/dist/cli/flags.js +133 -0
  58. package/dist/cli/flags.js.map +1 -0
  59. package/dist/cli/format-options.d.ts +29 -0
  60. package/dist/cli/format-options.d.ts.map +1 -0
  61. package/dist/cli/format-options.js +72 -0
  62. package/dist/cli/format-options.js.map +1 -0
  63. package/dist/cli/global-help.d.ts +23 -0
  64. package/dist/cli/global-help.d.ts.map +1 -0
  65. package/dist/cli/global-help.js +40 -0
  66. package/dist/cli/global-help.js.map +1 -0
  67. package/dist/cli/help.d.ts +1 -1
  68. package/dist/cli/help.d.ts.map +1 -1
  69. package/dist/cli/help.js +5 -99
  70. package/dist/cli/help.js.map +1 -1
  71. package/dist/cli/html-commands.d.ts +13 -0
  72. package/dist/cli/html-commands.d.ts.map +1 -0
  73. package/dist/cli/html-commands.js +49 -0
  74. package/dist/cli/html-commands.js.map +1 -0
  75. package/dist/cli/info-command.d.ts +7 -0
  76. package/dist/cli/info-command.d.ts.map +1 -0
  77. package/dist/cli/info-command.js +39 -0
  78. package/dist/cli/info-command.js.map +1 -0
  79. package/dist/cli/lookup-commands.d.ts +10 -0
  80. package/dist/cli/lookup-commands.d.ts.map +1 -0
  81. package/dist/cli/lookup-commands.js +101 -0
  82. package/dist/cli/lookup-commands.js.map +1 -0
  83. package/dist/cli/match-command.d.ts +11 -0
  84. package/dist/cli/match-command.d.ts.map +1 -0
  85. package/dist/cli/match-command.js +76 -0
  86. package/dist/cli/match-command.js.map +1 -0
  87. package/dist/cli/number-command.d.ts +12 -0
  88. package/dist/cli/number-command.d.ts.map +1 -0
  89. package/dist/cli/number-command.js +89 -0
  90. package/dist/cli/number-command.js.map +1 -0
  91. package/dist/cli/options.d.ts +30 -0
  92. package/dist/cli/options.d.ts.map +1 -0
  93. package/dist/cli/options.js +54 -0
  94. package/dist/cli/options.js.map +1 -0
  95. package/dist/cli/run-command.d.ts +24 -0
  96. package/dist/cli/run-command.d.ts.map +1 -0
  97. package/dist/cli/run-command.js +40 -0
  98. package/dist/cli/run-command.js.map +1 -0
  99. package/dist/cli/run.d.ts +4 -42
  100. package/dist/cli/run.d.ts.map +1 -1
  101. package/dist/cli/run.js +6 -61
  102. package/dist/cli/run.js.map +1 -1
  103. package/dist/cli/script-command.d.ts +10 -0
  104. package/dist/cli/script-command.d.ts.map +1 -0
  105. package/dist/cli/script-command.js +58 -0
  106. package/dist/cli/script-command.js.map +1 -0
  107. package/dist/cli/segment-command.d.ts +11 -0
  108. package/dist/cli/segment-command.d.ts.map +1 -0
  109. package/dist/cli/segment-command.js +53 -0
  110. package/dist/cli/segment-command.js.map +1 -0
  111. package/dist/cli/slug-command.d.ts +10 -0
  112. package/dist/cli/slug-command.d.ts.map +1 -0
  113. package/dist/cli/slug-command.js +28 -0
  114. package/dist/cli/slug-command.js.map +1 -0
  115. package/dist/cli/syllable-command.d.ts +14 -0
  116. package/dist/cli/syllable-command.d.ts.map +1 -0
  117. package/dist/cli/syllable-command.js +82 -0
  118. package/dist/cli/syllable-command.js.map +1 -0
  119. package/dist/cli/system-table.d.ts +12 -0
  120. package/dist/cli/system-table.d.ts.map +1 -0
  121. package/dist/cli/system-table.js +48 -0
  122. package/dist/cli/system-table.js.map +1 -0
  123. package/dist/cli/systems.d.ts +57 -0
  124. package/dist/cli/systems.d.ts.map +1 -0
  125. package/dist/cli/systems.js +27 -0
  126. package/dist/cli/systems.js.map +1 -0
  127. package/dist/cli/transcribe-command.d.ts +18 -0
  128. package/dist/cli/transcribe-command.d.ts.map +1 -0
  129. package/dist/cli/transcribe-command.js +86 -0
  130. package/dist/cli/transcribe-command.js.map +1 -0
  131. package/dist/cli/transcribe-reading.d.ts +15 -0
  132. package/dist/cli/transcribe-reading.d.ts.map +1 -0
  133. package/dist/cli/transcribe-reading.js +90 -0
  134. package/dist/cli/transcribe-reading.js.map +1 -0
  135. package/dist/cli/transcribe-rows.d.ts +26 -0
  136. package/dist/cli/transcribe-rows.d.ts.map +1 -0
  137. package/dist/cli/transcribe-rows.js +30 -0
  138. package/dist/cli/transcribe-rows.js.map +1 -0
  139. package/dist/cli/usage-error.d.ts +9 -0
  140. package/dist/cli/usage-error.d.ts.map +1 -0
  141. package/dist/cli/usage-error.js +9 -0
  142. package/dist/cli/usage-error.js.map +1 -0
  143. package/dist/decode/alternatives.d.ts +16 -0
  144. package/dist/decode/alternatives.d.ts.map +1 -0
  145. package/dist/decode/alternatives.js +31 -0
  146. package/dist/decode/alternatives.js.map +1 -0
  147. package/dist/decode/confidence.d.ts.map +1 -1
  148. package/dist/decode/confidence.js +3 -118
  149. package/dist/decode/confidence.js.map +1 -1
  150. package/dist/decode/convert-options.d.ts +116 -0
  151. package/dist/decode/convert-options.d.ts.map +1 -0
  152. package/dist/decode/convert-options.js +2 -0
  153. package/dist/decode/convert-options.js.map +1 -0
  154. package/dist/decode/convert-pipeline.d.ts +18 -0
  155. package/dist/decode/convert-pipeline.d.ts.map +1 -0
  156. package/dist/decode/convert-pipeline.js +66 -0
  157. package/dist/decode/convert-pipeline.js.map +1 -0
  158. package/dist/decode/convert.d.ts +9 -118
  159. package/dist/decode/convert.d.ts.map +1 -1
  160. package/dist/decode/convert.js +5 -453
  161. package/dist/decode/convert.js.map +1 -1
  162. package/dist/decode/decode.d.ts +2 -15
  163. package/dist/decode/decode.d.ts.map +1 -1
  164. package/dist/decode/decode.js +2 -121
  165. package/dist/decode/decode.js.map +1 -1
  166. package/dist/decode/decoders.d.ts +32 -0
  167. package/dist/decode/decoders.d.ts.map +1 -0
  168. package/dist/decode/decoders.js +29 -0
  169. package/dist/decode/decoders.js.map +1 -0
  170. package/dist/decode/edge-context.d.ts +38 -0
  171. package/dist/decode/edge-context.d.ts.map +1 -0
  172. package/dist/decode/edge-context.js +57 -0
  173. package/dist/decode/edge-context.js.map +1 -0
  174. package/dist/decode/hint-lattice.d.ts +45 -0
  175. package/dist/decode/hint-lattice.d.ts.map +1 -0
  176. package/dist/decode/hint-lattice.js +140 -0
  177. package/dist/decode/hint-lattice.js.map +1 -0
  178. package/dist/decode/hints.d.ts +2 -45
  179. package/dist/decode/hints.d.ts.map +1 -1
  180. package/dist/decode/hints.js +1 -139
  181. package/dist/decode/hints.js.map +1 -1
  182. package/dist/decode/jiao-rule.d.ts +58 -0
  183. package/dist/decode/jiao-rule.d.ts.map +1 -0
  184. package/dist/decode/jiao-rule.js +76 -0
  185. package/dist/decode/jiao-rule.js.map +1 -0
  186. package/dist/decode/lattice-costs.d.ts +55 -0
  187. package/dist/decode/lattice-costs.d.ts.map +1 -0
  188. package/dist/decode/lattice-costs.js +90 -0
  189. package/dist/decode/lattice-costs.js.map +1 -0
  190. package/dist/decode/lattice-edges.d.ts +29 -0
  191. package/dist/decode/lattice-edges.d.ts.map +1 -0
  192. package/dist/decode/lattice-edges.js +78 -0
  193. package/dist/decode/lattice-edges.js.map +1 -0
  194. package/dist/decode/lattice-slice.d.ts +37 -0
  195. package/dist/decode/lattice-slice.d.ts.map +1 -0
  196. package/dist/decode/lattice-slice.js +43 -0
  197. package/dist/decode/lattice-slice.js.map +1 -0
  198. package/dist/decode/lattice-types.d.ts +82 -0
  199. package/dist/decode/lattice-types.d.ts.map +1 -0
  200. package/dist/decode/lattice-types.js +44 -0
  201. package/dist/decode/lattice-types.js.map +1 -0
  202. package/dist/decode/lattice.d.ts +2 -59
  203. package/dist/decode/lattice.d.ts.map +1 -1
  204. package/dist/decode/lattice.js +2 -118
  205. package/dist/decode/lattice.js.map +1 -1
  206. package/dist/decode/number-pieces.d.ts +62 -0
  207. package/dist/decode/number-pieces.d.ts.map +1 -0
  208. package/dist/decode/number-pieces.js +106 -0
  209. package/dist/decode/number-pieces.js.map +1 -0
  210. package/dist/decode/numbers.d.ts +53 -0
  211. package/dist/decode/numbers.d.ts.map +1 -0
  212. package/dist/decode/numbers.js +69 -0
  213. package/dist/decode/numbers.js.map +1 -0
  214. package/dist/decode/pieces.d.ts +78 -0
  215. package/dist/decode/pieces.d.ts.map +1 -0
  216. package/dist/decode/pieces.js +136 -0
  217. package/dist/decode/pieces.js.map +1 -0
  218. package/dist/decode/polyphone-rules.d.ts +31 -0
  219. package/dist/decode/polyphone-rules.d.ts.map +1 -0
  220. package/dist/decode/polyphone-rules.js +159 -0
  221. package/dist/decode/polyphone-rules.js.map +1 -0
  222. package/dist/decode/reading-rules.d.ts +2 -97
  223. package/dist/decode/reading-rules.d.ts.map +1 -1
  224. package/dist/decode/reading-rules.js +4 -365
  225. package/dist/decode/reading-rules.js.map +1 -1
  226. package/dist/decode/rules.d.ts +1 -17
  227. package/dist/decode/rules.d.ts.map +1 -1
  228. package/dist/decode/rules.js +1 -43
  229. package/dist/decode/rules.js.map +1 -1
  230. package/dist/decode/run-lattice.d.ts +52 -0
  231. package/dist/decode/run-lattice.d.ts.map +1 -0
  232. package/dist/decode/run-lattice.js +91 -0
  233. package/dist/decode/run-lattice.js.map +1 -0
  234. package/dist/decode/sandhi-tones.d.ts +69 -0
  235. package/dist/decode/sandhi-tones.d.ts.map +1 -0
  236. package/dist/decode/sandhi-tones.js +88 -0
  237. package/dist/decode/sandhi-tones.js.map +1 -0
  238. package/dist/decode/sandhi.d.ts +1 -1
  239. package/dist/decode/sandhi.d.ts.map +1 -1
  240. package/dist/decode/sandhi.js +1 -81
  241. package/dist/decode/sandhi.js.map +1 -1
  242. package/dist/decode/script-types.d.ts +76 -0
  243. package/dist/decode/script-types.d.ts.map +1 -0
  244. package/dist/decode/script-types.js +35 -0
  245. package/dist/decode/script-types.js.map +1 -0
  246. package/dist/decode/script-words.d.ts +32 -0
  247. package/dist/decode/script-words.d.ts.map +1 -0
  248. package/dist/decode/script-words.js +77 -0
  249. package/dist/decode/script-words.js.map +1 -0
  250. package/dist/decode/script.d.ts +3 -73
  251. package/dist/decode/script.d.ts.map +1 -1
  252. package/dist/decode/script.js +3 -109
  253. package/dist/decode/script.js.map +1 -1
  254. package/dist/decode/tan-rule.d.ts +68 -0
  255. package/dist/decode/tan-rule.d.ts.map +1 -0
  256. package/dist/decode/tan-rule.js +131 -0
  257. package/dist/decode/tan-rule.js.map +1 -0
  258. package/dist/decode/write-run.d.ts +28 -0
  259. package/dist/decode/write-run.d.ts.map +1 -0
  260. package/dist/decode/write-run.js +77 -0
  261. package/dist/decode/write-run.js.map +1 -0
  262. package/dist/dictionary/artifact-claims.d.ts +25 -0
  263. package/dist/dictionary/artifact-claims.d.ts.map +1 -0
  264. package/dist/dictionary/artifact-claims.js +47 -0
  265. package/dist/dictionary/artifact-claims.js.map +1 -0
  266. package/dist/dictionary/artifact-format.d.ts +86 -0
  267. package/dist/dictionary/artifact-format.d.ts.map +1 -0
  268. package/dist/dictionary/artifact-format.js +91 -0
  269. package/dist/dictionary/artifact-format.js.map +1 -0
  270. package/dist/dictionary/artifact-read.d.ts +34 -0
  271. package/dist/dictionary/artifact-read.d.ts.map +1 -0
  272. package/dist/dictionary/artifact-read.js +114 -0
  273. package/dist/dictionary/artifact-read.js.map +1 -0
  274. package/dist/dictionary/artifact.d.ts +4 -63
  275. package/dist/dictionary/artifact.d.ts.map +1 -1
  276. package/dist/dictionary/artifact.js +12 -229
  277. package/dist/dictionary/artifact.js.map +1 -1
  278. package/dist/dictionary/assertions.d.ts +5 -57
  279. package/dist/dictionary/assertions.d.ts.map +1 -1
  280. package/dist/dictionary/assertions.js +4 -317
  281. package/dist/dictionary/assertions.js.map +1 -1
  282. package/dist/dictionary/build-assertions.d.ts +12 -0
  283. package/dist/dictionary/build-assertions.d.ts.map +1 -0
  284. package/dist/dictionary/build-assertions.js +13 -0
  285. package/dist/dictionary/build-assertions.js.map +1 -0
  286. package/dist/dictionary/built-dictionary.d.ts +46 -0
  287. package/dist/dictionary/built-dictionary.d.ts.map +1 -0
  288. package/dist/dictionary/built-dictionary.js +97 -0
  289. package/dist/dictionary/built-dictionary.js.map +1 -0
  290. package/dist/dictionary/cedict-senses.d.ts +80 -0
  291. package/dist/dictionary/cedict-senses.d.ts.map +1 -0
  292. package/dist/dictionary/cedict-senses.js +114 -0
  293. package/dist/dictionary/cedict-senses.js.map +1 -0
  294. package/dist/dictionary/character-defaults.d.ts +26 -0
  295. package/dist/dictionary/character-defaults.d.ts.map +1 -0
  296. package/dist/dictionary/character-defaults.js +67 -0
  297. package/dist/dictionary/character-defaults.js.map +1 -0
  298. package/dist/dictionary/character-readings.d.ts +10 -0
  299. package/dist/dictionary/character-readings.d.ts.map +1 -0
  300. package/dist/dictionary/character-readings.js +25 -0
  301. package/dist/dictionary/character-readings.js.map +1 -0
  302. package/dist/dictionary/dictionary-entry.d.ts +37 -0
  303. package/dist/dictionary/dictionary-entry.d.ts.map +1 -0
  304. package/dist/dictionary/dictionary-entry.js +41 -0
  305. package/dist/dictionary/dictionary-entry.js.map +1 -0
  306. package/dist/dictionary/dictionary-readings.d.ts +56 -0
  307. package/dist/dictionary/dictionary-readings.d.ts.map +1 -0
  308. package/dist/dictionary/dictionary-readings.js +93 -0
  309. package/dist/dictionary/dictionary-readings.js.map +1 -0
  310. package/dist/dictionary/dictionary.d.ts +6 -60
  311. package/dist/dictionary/dictionary.d.ts.map +1 -1
  312. package/dist/dictionary/dictionary.js +9 -169
  313. package/dist/dictionary/dictionary.js.map +1 -1
  314. package/dist/dictionary/entry-invariants.d.ts +3 -0
  315. package/dist/dictionary/entry-invariants.d.ts.map +1 -0
  316. package/dist/dictionary/entry-invariants.js +67 -0
  317. package/dist/dictionary/entry-invariants.js.map +1 -0
  318. package/dist/dictionary/entry-lines.d.ts +35 -0
  319. package/dist/dictionary/entry-lines.d.ts.map +1 -0
  320. package/dist/dictionary/entry-lines.js +70 -0
  321. package/dist/dictionary/entry-lines.js.map +1 -0
  322. package/dist/dictionary/erhua-repair.d.ts +26 -0
  323. package/dist/dictionary/erhua-repair.d.ts.map +1 -0
  324. package/dist/dictionary/erhua-repair.js +49 -0
  325. package/dist/dictionary/erhua-repair.js.map +1 -0
  326. package/dist/dictionary/frequency-tones.d.ts +74 -0
  327. package/dist/dictionary/frequency-tones.d.ts.map +1 -0
  328. package/dist/dictionary/frequency-tones.js +128 -0
  329. package/dist/dictionary/frequency-tones.js.map +1 -0
  330. package/dist/dictionary/inventory-invariants.d.ts +3 -0
  331. package/dist/dictionary/inventory-invariants.d.ts.map +1 -0
  332. package/dist/dictionary/inventory-invariants.js +54 -0
  333. package/dist/dictionary/inventory-invariants.js.map +1 -0
  334. package/dist/dictionary/locale-candidates.d.ts +40 -0
  335. package/dist/dictionary/locale-candidates.d.ts.map +1 -0
  336. package/dist/dictionary/locale-candidates.js +77 -0
  337. package/dist/dictionary/locale-candidates.js.map +1 -0
  338. package/dist/dictionary/locale-segments.d.ts +47 -0
  339. package/dist/dictionary/locale-segments.d.ts.map +1 -0
  340. package/dist/dictionary/locale-segments.js +141 -0
  341. package/dist/dictionary/locale-segments.js.map +1 -0
  342. package/dist/dictionary/locale.d.ts +1 -21
  343. package/dist/dictionary/locale.d.ts.map +1 -1
  344. package/dist/dictionary/locale.js +9 -198
  345. package/dist/dictionary/locale.js.map +1 -1
  346. package/dist/dictionary/merge-types.d.ts +121 -0
  347. package/dist/dictionary/merge-types.d.ts.map +1 -0
  348. package/dist/dictionary/merge-types.js +35 -0
  349. package/dist/dictionary/merge-types.js.map +1 -0
  350. package/dist/dictionary/merge-word.d.ts +7 -0
  351. package/dist/dictionary/merge-word.d.ts.map +1 -0
  352. package/dist/dictionary/merge-word.js +91 -0
  353. package/dist/dictionary/merge-word.js.map +1 -0
  354. package/dist/dictionary/merge.d.ts +5 -62
  355. package/dist/dictionary/merge.d.ts.map +1 -1
  356. package/dist/dictionary/merge.js +30 -713
  357. package/dist/dictionary/merge.js.map +1 -1
  358. package/dist/dictionary/proper-noun.d.ts +28 -0
  359. package/dist/dictionary/proper-noun.d.ts.map +1 -0
  360. package/dist/dictionary/proper-noun.js +43 -0
  361. package/dist/dictionary/proper-noun.js.map +1 -0
  362. package/dist/dictionary/reading-agreement.d.ts +71 -0
  363. package/dist/dictionary/reading-agreement.d.ts.map +1 -0
  364. package/dist/dictionary/reading-agreement.js +156 -0
  365. package/dist/dictionary/reading-agreement.js.map +1 -0
  366. package/dist/dictionary/script-conversion.d.ts +28 -0
  367. package/dist/dictionary/script-conversion.d.ts.map +1 -0
  368. package/dist/dictionary/script-conversion.js +58 -0
  369. package/dist/dictionary/script-conversion.js.map +1 -0
  370. package/dist/dictionary/script-pairings.d.ts +74 -0
  371. package/dist/dictionary/script-pairings.d.ts.map +1 -0
  372. package/dist/dictionary/script-pairings.js +120 -0
  373. package/dist/dictionary/script-pairings.js.map +1 -0
  374. package/dist/dictionary/script-tables.d.ts.map +1 -1
  375. package/dist/dictionary/script-tables.js +2 -165
  376. package/dist/dictionary/script-tables.js.map +1 -1
  377. package/dist/dictionary/taiwan-reading.d.ts +8 -0
  378. package/dist/dictionary/taiwan-reading.d.ts.map +1 -0
  379. package/dist/dictionary/taiwan-reading.js +38 -0
  380. package/dist/dictionary/taiwan-reading.js.map +1 -0
  381. package/dist/dictionary/tone-invariants.d.ts +3 -0
  382. package/dist/dictionary/tone-invariants.d.ts.map +1 -0
  383. package/dist/dictionary/tone-invariants.js +64 -0
  384. package/dist/dictionary/tone-invariants.js.map +1 -0
  385. package/dist/dictionary/traditional-form.d.ts +21 -0
  386. package/dist/dictionary/traditional-form.d.ts.map +1 -0
  387. package/dist/dictionary/traditional-form.js +59 -0
  388. package/dist/dictionary/traditional-form.js.map +1 -0
  389. package/dist/dictionary/traditional-ranking.d.ts +22 -0
  390. package/dist/dictionary/traditional-ranking.d.ts.map +1 -0
  391. package/dist/dictionary/traditional-ranking.js +74 -0
  392. package/dist/dictionary/traditional-ranking.js.map +1 -0
  393. package/dist/dictionary/traditional-table.d.ts +51 -0
  394. package/dist/dictionary/traditional-table.d.ts.map +1 -0
  395. package/dist/dictionary/traditional-table.js +98 -0
  396. package/dist/dictionary/traditional-table.js.map +1 -0
  397. package/dist/dictionary/traditional.d.ts +3 -56
  398. package/dist/dictionary/traditional.d.ts.map +1 -1
  399. package/dist/dictionary/traditional.js +3 -186
  400. package/dist/dictionary/traditional.js.map +1 -1
  401. package/dist/dictionary/variant-counts.d.ts +39 -0
  402. package/dist/dictionary/variant-counts.d.ts.map +1 -0
  403. package/dist/dictionary/variant-counts.js +38 -0
  404. package/dist/dictionary/variant-counts.js.map +1 -0
  405. package/dist/dictionary/word-reading.d.ts +26 -0
  406. package/dist/dictionary/word-reading.d.ts.map +1 -0
  407. package/dist/dictionary/word-reading.js +76 -0
  408. package/dist/dictionary/word-reading.js.map +1 -0
  409. package/dist/dictionary/word-readings.d.ts +15 -0
  410. package/dist/dictionary/word-readings.d.ts.map +1 -0
  411. package/dist/dictionary/word-readings.js +38 -0
  412. package/dist/dictionary/word-readings.js.map +1 -0
  413. package/dist/format/annotate.d.ts +90 -0
  414. package/dist/format/annotate.d.ts.map +1 -0
  415. package/dist/format/annotate.js +168 -0
  416. package/dist/format/annotate.js.map +1 -0
  417. package/dist/format/html.d.ts +15 -46
  418. package/dist/format/html.d.ts.map +1 -1
  419. package/dist/format/html.js +3 -162
  420. package/dist/format/html.js.map +1 -1
  421. package/dist/format/slug-hash.d.ts +51 -0
  422. package/dist/format/slug-hash.d.ts.map +1 -0
  423. package/dist/format/slug-hash.js +74 -0
  424. package/dist/format/slug-hash.js.map +1 -0
  425. package/dist/format/slug-options.d.ts +98 -0
  426. package/dist/format/slug-options.d.ts.map +1 -0
  427. package/dist/format/slug-options.js +2 -0
  428. package/dist/format/slug-options.js.map +1 -0
  429. package/dist/format/slug-words.d.ts +27 -0
  430. package/dist/format/slug-words.d.ts.map +1 -0
  431. package/dist/format/slug-words.js +0 -0
  432. package/dist/format/slug-words.js.map +1 -0
  433. package/dist/format/slug.d.ts +3 -128
  434. package/dist/format/slug.d.ts.map +1 -1
  435. package/dist/format/slug.js +0 -0
  436. package/dist/format/slug.js.map +1 -1
  437. package/dist/grade/check-readings.d.ts +41 -0
  438. package/dist/grade/check-readings.d.ts.map +1 -0
  439. package/dist/grade/check-readings.js +36 -0
  440. package/dist/grade/check-readings.js.map +1 -0
  441. package/dist/grade/check.d.ts +4 -4
  442. package/dist/grade/check.d.ts.map +1 -1
  443. package/dist/grade/check.js +5 -270
  444. package/dist/grade/check.js.map +1 -1
  445. package/dist/grade/pair-syllables.d.ts +48 -0
  446. package/dist/grade/pair-syllables.d.ts.map +1 -0
  447. package/dist/grade/pair-syllables.js +71 -0
  448. package/dist/grade/pair-syllables.js.map +1 -0
  449. package/dist/grade/reading-syllables.d.ts +62 -0
  450. package/dist/grade/reading-syllables.d.ts.map +1 -0
  451. package/dist/grade/reading-syllables.js +58 -0
  452. package/dist/grade/reading-syllables.js.map +1 -0
  453. package/dist/grade/reading-tolerance.d.ts +72 -0
  454. package/dist/grade/reading-tolerance.d.ts.map +1 -0
  455. package/dist/grade/reading-tolerance.js +107 -0
  456. package/dist/grade/reading-tolerance.js.map +1 -0
  457. package/dist/grade/typed-reading.d.ts +28 -0
  458. package/dist/grade/typed-reading.d.ts.map +1 -0
  459. package/dist/grade/typed-reading.js +36 -0
  460. package/dist/grade/typed-reading.js.map +1 -0
  461. package/dist/numerals/numeral-parse.d.ts +32 -0
  462. package/dist/numerals/numeral-parse.d.ts.map +1 -0
  463. package/dist/numerals/numeral-parse.js +44 -0
  464. package/dist/numerals/numeral-parse.js.map +1 -0
  465. package/dist/numerals/numeral-shapes.d.ts +89 -0
  466. package/dist/numerals/numeral-shapes.d.ts.map +1 -0
  467. package/dist/numerals/numeral-shapes.js +99 -0
  468. package/dist/numerals/numeral-shapes.js.map +1 -0
  469. package/dist/numerals/numerals.d.ts.map +1 -1
  470. package/dist/numerals/numerals.js +2 -36
  471. package/dist/numerals/numerals.js.map +1 -1
  472. package/dist/numerals/read-numeral.d.ts +76 -0
  473. package/dist/numerals/read-numeral.d.ts.map +1 -0
  474. package/dist/numerals/read-numeral.js +88 -0
  475. package/dist/numerals/read-numeral.js.map +1 -0
  476. package/dist/numerals/text.d.ts +3 -37
  477. package/dist/numerals/text.d.ts.map +1 -1
  478. package/dist/numerals/text.js +3 -254
  479. package/dist/numerals/text.js.map +1 -1
  480. package/dist/numerals/time.d.ts +34 -0
  481. package/dist/numerals/time.d.ts.map +1 -0
  482. package/dist/numerals/time.js +93 -0
  483. package/dist/numerals/time.js.map +1 -0
  484. package/dist/orthography/address-grouping.d.ts +34 -0
  485. package/dist/orthography/address-grouping.d.ts.map +1 -0
  486. package/dist/orthography/address-grouping.js +52 -0
  487. package/dist/orthography/address-grouping.js.map +1 -0
  488. package/dist/orthography/grouping.d.ts +3 -87
  489. package/dist/orthography/grouping.d.ts.map +1 -1
  490. package/dist/orthography/grouping.js +4 -270
  491. package/dist/orthography/grouping.js.map +1 -1
  492. package/dist/orthography/place-grouping.d.ts +39 -0
  493. package/dist/orthography/place-grouping.d.ts.map +1 -0
  494. package/dist/orthography/place-grouping.js +83 -0
  495. package/dist/orthography/place-grouping.js.map +1 -0
  496. package/dist/orthography/word-grouping.d.ts +48 -0
  497. package/dist/orthography/word-grouping.d.ts.map +1 -0
  498. package/dist/orthography/word-grouping.js +147 -0
  499. package/dist/orthography/word-grouping.js.map +1 -0
  500. package/dist/script/conversion-format.d.ts +22 -0
  501. package/dist/script/conversion-format.d.ts.map +1 -0
  502. package/dist/script/conversion-format.js +22 -0
  503. package/dist/script/conversion-format.js.map +1 -0
  504. package/dist/script/conversion-read.d.ts +9 -0
  505. package/dist/script/conversion-read.d.ts.map +1 -0
  506. package/dist/script/conversion-read.js +69 -0
  507. package/dist/script/conversion-read.js.map +1 -0
  508. package/dist/script/conversion-write.d.ts +14 -0
  509. package/dist/script/conversion-write.d.ts.map +1 -0
  510. package/dist/script/conversion-write.js +34 -0
  511. package/dist/script/conversion-write.js.map +1 -0
  512. package/dist/script/conversion.d.ts +10 -16
  513. package/dist/script/conversion.d.ts.map +1 -1
  514. package/dist/script/conversion.js +2 -115
  515. package/dist/script/conversion.js.map +1 -1
  516. package/dist/search/candidate-narrowing.d.ts +56 -0
  517. package/dist/search/candidate-narrowing.d.ts.map +1 -0
  518. package/dist/search/candidate-narrowing.js +55 -0
  519. package/dist/search/candidate-narrowing.js.map +1 -0
  520. package/dist/search/candidate-query.d.ts +25 -0
  521. package/dist/search/candidate-query.d.ts.map +1 -0
  522. package/dist/search/candidate-query.js +28 -0
  523. package/dist/search/candidate-query.js.map +1 -0
  524. package/dist/search/candidate-writings.d.ts +24 -0
  525. package/dist/search/candidate-writings.d.ts.map +1 -0
  526. package/dist/search/candidate-writings.js +114 -0
  527. package/dist/search/candidate-writings.js.map +1 -0
  528. package/dist/search/candidates.d.ts +7 -41
  529. package/dist/search/candidates.d.ts.map +1 -1
  530. package/dist/search/candidates.js +10 -164
  531. package/dist/search/candidates.js.map +1 -1
  532. package/dist/search/match-chunks.d.ts +19 -0
  533. package/dist/search/match-chunks.d.ts.map +1 -0
  534. package/dist/search/match-chunks.js +30 -0
  535. package/dist/search/match-chunks.js.map +1 -0
  536. package/dist/search/match-ranking.d.ts +39 -0
  537. package/dist/search/match-ranking.d.ts.map +1 -0
  538. package/dist/search/match-ranking.js +51 -0
  539. package/dist/search/match-ranking.js.map +1 -0
  540. package/dist/search/match-readings.d.ts +43 -0
  541. package/dist/search/match-readings.d.ts.map +1 -0
  542. package/dist/search/match-readings.js +83 -0
  543. package/dist/search/match-readings.js.map +1 -0
  544. package/dist/search/match-scoring.d.ts +146 -0
  545. package/dist/search/match-scoring.d.ts.map +1 -0
  546. package/dist/search/match-scoring.js +114 -0
  547. package/dist/search/match-scoring.js.map +1 -0
  548. package/dist/search/match-search.d.ts +28 -0
  549. package/dist/search/match-search.d.ts.map +1 -0
  550. package/dist/search/match-search.js +128 -0
  551. package/dist/search/match-search.js.map +1 -0
  552. package/dist/search/match.d.ts +5 -36
  553. package/dist/search/match.d.ts.map +1 -1
  554. package/dist/search/match.js +2 -379
  555. package/dist/search/match.js.map +1 -1
  556. package/dist/search/reverse-index-build.d.ts +30 -0
  557. package/dist/search/reverse-index-build.d.ts.map +1 -0
  558. package/dist/search/reverse-index-build.js +72 -0
  559. package/dist/search/reverse-index-build.js.map +1 -0
  560. package/dist/search/reverse-index-format.d.ts +60 -0
  561. package/dist/search/reverse-index-format.d.ts.map +1 -0
  562. package/dist/search/reverse-index-format.js +54 -0
  563. package/dist/search/reverse-index-format.js.map +1 -0
  564. package/dist/search/reverse-index-groups.d.ts +37 -0
  565. package/dist/search/reverse-index-groups.d.ts.map +1 -0
  566. package/dist/search/reverse-index-groups.js +71 -0
  567. package/dist/search/reverse-index-groups.js.map +1 -0
  568. package/dist/search/reverse-index-passes.d.ts +78 -0
  569. package/dist/search/reverse-index-passes.d.ts.map +1 -0
  570. package/dist/search/reverse-index-passes.js +59 -0
  571. package/dist/search/reverse-index-passes.js.map +1 -0
  572. package/dist/search/reverse-index-state.d.ts +36 -0
  573. package/dist/search/reverse-index-state.d.ts.map +1 -0
  574. package/dist/search/reverse-index-state.js +95 -0
  575. package/dist/search/reverse-index-state.js.map +1 -0
  576. package/dist/search/reverse-index.d.ts +8 -67
  577. package/dist/search/reverse-index.d.ts.map +1 -1
  578. package/dist/search/reverse-index.js +4 -255
  579. package/dist/search/reverse-index.js.map +1 -1
  580. package/dist/sources/unihan-readings.d.ts +58 -0
  581. package/dist/sources/unihan-readings.d.ts.map +1 -0
  582. package/dist/sources/unihan-readings.js +95 -0
  583. package/dist/sources/unihan-readings.js.map +1 -0
  584. package/dist/sources/unihan.d.ts +6 -9
  585. package/dist/sources/unihan.d.ts.map +1 -1
  586. package/dist/sources/unihan.js +2 -85
  587. package/dist/sources/unihan.js.map +1 -1
  588. package/dist/syllable/final-tables.d.ts +23 -0
  589. package/dist/syllable/final-tables.d.ts.map +1 -0
  590. package/dist/syllable/final-tables.js +50 -0
  591. package/dist/syllable/final-tables.js.map +1 -0
  592. package/dist/syllable/inventory.d.ts +8 -42
  593. package/dist/syllable/inventory.d.ts.map +1 -1
  594. package/dist/syllable/inventory.js +9 -918
  595. package/dist/syllable/inventory.js.map +1 -1
  596. package/dist/syllable/spellings.d.ts +40 -0
  597. package/dist/syllable/spellings.d.ts.map +1 -0
  598. package/dist/syllable/spellings.js +469 -0
  599. package/dist/syllable/spellings.js.map +1 -0
  600. package/dist/syllable/syllable-parts.d.ts +31 -0
  601. package/dist/syllable/syllable-parts.d.ts.map +1 -0
  602. package/dist/syllable/syllable-parts.js +105 -0
  603. package/dist/syllable/syllable-parts.js.map +1 -0
  604. package/dist/syllable/syllable.d.ts +1 -14
  605. package/dist/syllable/syllable.d.ts.map +1 -1
  606. package/dist/syllable/syllable.js +3 -144
  607. package/dist/syllable/syllable.js.map +1 -1
  608. package/dist/syllable/written-tones.d.ts +6 -0
  609. package/dist/syllable/written-tones.d.ts.map +1 -0
  610. package/dist/syllable/written-tones.js +453 -0
  611. package/dist/syllable/written-tones.js.map +1 -0
  612. package/dist/transcription/bopomofo-parse.d.ts +42 -0
  613. package/dist/transcription/bopomofo-parse.d.ts.map +1 -0
  614. package/dist/transcription/bopomofo-parse.js +92 -0
  615. package/dist/transcription/bopomofo-parse.js.map +1 -0
  616. package/dist/transcription/bopomofo-reverse.d.ts +31 -0
  617. package/dist/transcription/bopomofo-reverse.d.ts.map +1 -0
  618. package/dist/transcription/bopomofo-reverse.js +48 -0
  619. package/dist/transcription/bopomofo-reverse.js.map +1 -0
  620. package/dist/transcription/bopomofo-symbols.d.ts +36 -0
  621. package/dist/transcription/bopomofo-symbols.d.ts.map +1 -0
  622. package/dist/transcription/bopomofo-symbols.js +41 -0
  623. package/dist/transcription/bopomofo-symbols.js.map +1 -0
  624. package/dist/transcription/bopomofo-tables.d.ts +87 -0
  625. package/dist/transcription/bopomofo-tables.d.ts.map +1 -0
  626. package/dist/transcription/bopomofo-tables.js +180 -0
  627. package/dist/transcription/bopomofo-tables.js.map +1 -0
  628. package/dist/transcription/bopomofo.d.ts +14 -32
  629. package/dist/transcription/bopomofo.d.ts.map +1 -1
  630. package/dist/transcription/bopomofo.js +5 -343
  631. package/dist/transcription/bopomofo.js.map +1 -1
  632. package/dist/transcription/gwoyeu-first-second.d.ts +36 -0
  633. package/dist/transcription/gwoyeu-first-second.d.ts.map +1 -0
  634. package/dist/transcription/gwoyeu-first-second.js +75 -0
  635. package/dist/transcription/gwoyeu-first-second.js.map +1 -0
  636. package/dist/transcription/gwoyeu-spelling.d.ts +38 -0
  637. package/dist/transcription/gwoyeu-spelling.d.ts.map +1 -0
  638. package/dist/transcription/gwoyeu-spelling.js +124 -0
  639. package/dist/transcription/gwoyeu-spelling.js.map +1 -0
  640. package/dist/transcription/gwoyeu-tables.d.ts +93 -0
  641. package/dist/transcription/gwoyeu-tables.d.ts.map +1 -0
  642. package/dist/transcription/gwoyeu-tables.js +205 -0
  643. package/dist/transcription/gwoyeu-tables.js.map +1 -0
  644. package/dist/transcription/gwoyeu-tonal-forms.d.ts +49 -0
  645. package/dist/transcription/gwoyeu-tonal-forms.d.ts.map +1 -0
  646. package/dist/transcription/gwoyeu-tonal-forms.js +89 -0
  647. package/dist/transcription/gwoyeu-tonal-forms.js.map +1 -0
  648. package/dist/transcription/gwoyeu-vowels.d.ts +51 -0
  649. package/dist/transcription/gwoyeu-vowels.d.ts.map +1 -0
  650. package/dist/transcription/gwoyeu-vowels.js +58 -0
  651. package/dist/transcription/gwoyeu-vowels.js.map +1 -0
  652. package/dist/transcription/gwoyeu.d.ts +1 -26
  653. package/dist/transcription/gwoyeu.d.ts.map +1 -1
  654. package/dist/transcription/gwoyeu.js +2 -540
  655. package/dist/transcription/gwoyeu.js.map +1 -1
  656. package/dist/transcription/ipa-symbols.d.ts +67 -0
  657. package/dist/transcription/ipa-symbols.d.ts.map +1 -0
  658. package/dist/transcription/ipa-symbols.js +135 -0
  659. package/dist/transcription/ipa-symbols.js.map +1 -0
  660. package/dist/transcription/ipa.d.ts +2 -10
  661. package/dist/transcription/ipa.d.ts.map +1 -1
  662. package/dist/transcription/ipa.js +2 -134
  663. package/dist/transcription/ipa.js.map +1 -1
  664. package/dist/transcription/wade-giles-index.d.ts +35 -0
  665. package/dist/transcription/wade-giles-index.d.ts.map +1 -0
  666. package/dist/transcription/wade-giles-index.js +110 -0
  667. package/dist/transcription/wade-giles-index.js.map +1 -0
  668. package/dist/transcription/wade-giles-parse.d.ts +36 -0
  669. package/dist/transcription/wade-giles-parse.d.ts.map +1 -0
  670. package/dist/transcription/wade-giles-parse.js +84 -0
  671. package/dist/transcription/wade-giles-parse.js.map +1 -0
  672. package/dist/transcription/wade-giles-spelling.d.ts +61 -0
  673. package/dist/transcription/wade-giles-spelling.d.ts.map +1 -0
  674. package/dist/transcription/wade-giles-spelling.js +107 -0
  675. package/dist/transcription/wade-giles-spelling.js.map +1 -0
  676. package/dist/transcription/wade-giles-syllable.d.ts +29 -0
  677. package/dist/transcription/wade-giles-syllable.d.ts.map +1 -0
  678. package/dist/transcription/wade-giles-syllable.js +90 -0
  679. package/dist/transcription/wade-giles-syllable.js.map +1 -0
  680. package/dist/transcription/wade-giles-tables.d.ts +80 -0
  681. package/dist/transcription/wade-giles-tables.d.ts.map +1 -0
  682. package/dist/transcription/wade-giles-tables.js +178 -0
  683. package/dist/transcription/wade-giles-tables.js.map +1 -0
  684. package/dist/transcription/wade-giles.d.ts +9 -60
  685. package/dist/transcription/wade-giles.d.ts.map +1 -1
  686. package/dist/transcription/wade-giles.js +6 -543
  687. package/dist/transcription/wade-giles.js.map +1 -1
  688. package/dist/transcription/yale-tables.d.ts +54 -0
  689. package/dist/transcription/yale-tables.d.ts.map +1 -0
  690. package/dist/transcription/yale-tables.js +125 -0
  691. package/dist/transcription/yale-tables.js.map +1 -0
  692. package/dist/transcription/yale.d.ts.map +1 -1
  693. package/dist/transcription/yale.js +1 -124
  694. package/dist/transcription/yale.js.map +1 -1
  695. package/package.json +1 -1
@@ -1,994 +1,17 @@
1
- import { isUncertain } from "../decode/confidence.js";
2
- import { convert, convertGreedily, convertPieces, convertPiecesGreedily, } from "../decode/convert.js";
3
- import { applySandhi } from "../decode/sandhi.js";
4
- import { segment } from "../decode/segment.js";
5
- import { check } from "../grade/check.js";
6
- import { match } from "../search/match.js";
7
- import { toCharacters } from "../script/characters.js";
8
- import { numeralHanzi, percentHanzi, readNumeralHanzi, } from "../numerals/numerals.js";
9
- import { convertToAnnotatedHtml, convertToHtml } from "../format/html.js";
10
- import { slug } from "../format/slug.js";
11
- import { toTranscription } from "../format/transcription.js";
12
- import { isBopomofo, readBopomofo, writeBopomofo, writeBopomofoWord, } from "../transcription/bopomofo.js";
13
- import { readGwoyeu, writeGwoyeu, writeGwoyeuWord, } from "../transcription/gwoyeu.js";
14
- import { readIpa, writeIpa, writeIpaWord } from "../transcription/ipa.js";
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
  */