PinyinBase.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. import DICT_ZI from "./data/dict-zi";
  2. import DICT_PHRASES from "./data/phrases-dict";
  3. import { segment } from "./segment-web";
  4. import { toFixed } from "./format";
  5. import SurnamePinyinData from "./data/surname";
  6. import CompoundSurnamePinyinData from "./data/compound_surname";
  7. import { hasKey, convertUserOptions, combo, compact } from "./util";
  8. import { ENUM_PINYIN_MODE, ENUM_PINYIN_STYLE } from "./constant";
  9. export default class PinyinBase {
  10. STYLE_TONE = ENUM_PINYIN_STYLE.TONE;
  11. STYLE_TONE2 = ENUM_PINYIN_STYLE.TONE2;
  12. STYLE_TO3NE = ENUM_PINYIN_STYLE.TO3NE;
  13. STYLE_NORMAL = ENUM_PINYIN_STYLE.NORMAL;
  14. STYLE_INITIALS = ENUM_PINYIN_STYLE.INITIALS;
  15. STYLE_FIRST_LETTER = ENUM_PINYIN_STYLE.FIRST_LETTER;
  16. STYLE_PASSPORT = ENUM_PINYIN_STYLE.PASSPORT;
  17. MODE_NORMAL = ENUM_PINYIN_MODE.NORMAL;
  18. MODE_SURNAME = ENUM_PINYIN_MODE.SURNAME;
  19. pinyin(hans, options) {
  20. if (typeof hans !== "string") {
  21. return [];
  22. }
  23. const opt = convertUserOptions(options);
  24. let pys;
  25. if (opt.mode === ENUM_PINYIN_MODE.SURNAME) {
  26. pys = this.surname_pinyin(hans, opt);
  27. }
  28. else {
  29. if (opt.segment) {
  30. pys = this.segment_pinyin(hans, opt);
  31. }
  32. else {
  33. pys = this.normal_pinyin(hans, opt);
  34. }
  35. }
  36. if (options?.compact) {
  37. pys = compact(pys);
  38. }
  39. return pys;
  40. }
  41. normal_pinyin(hans, options) {
  42. const pys = [];
  43. let nohans = "";
  44. for (let i = 0, l = hans.length; i < l; i++) {
  45. const words = hans[i];
  46. const firstCharCode = words.charCodeAt(0);
  47. if (DICT_ZI[firstCharCode]) {
  48. if (nohans.length > 0) {
  49. pys.push([nohans]);
  50. nohans = "";
  51. }
  52. pys.push(this.single_pinyin(words, options));
  53. }
  54. else {
  55. nohans += words;
  56. }
  57. }
  58. if (nohans.length > 0) {
  59. pys.push([nohans]);
  60. nohans = "";
  61. }
  62. return pys;
  63. }
  64. single_pinyin(han, options) {
  65. if (typeof han !== "string") {
  66. return [];
  67. }
  68. if (han.length !== 1) {
  69. return this.single_pinyin(han.charAt(0), options);
  70. }
  71. const hanCode = han.charCodeAt(0);
  72. if (!DICT_ZI[hanCode]) {
  73. return [han];
  74. }
  75. const pys = DICT_ZI[hanCode].split(",");
  76. if (!options.heteronym) {
  77. return [toFixed(pys[0], options.style)];
  78. }
  79. const py_cached = {};
  80. const pinyins = [];
  81. for (let i = 0, l = pys.length; i < l; i++) {
  82. const py = toFixed(pys[i], options.style);
  83. if (hasKey(py_cached, py)) {
  84. continue;
  85. }
  86. py_cached[py] = py;
  87. pinyins.push(py);
  88. }
  89. return pinyins;
  90. }
  91. segment(hans, segmentType) {
  92. return segment(hans, segmentType);
  93. }
  94. segment_pinyin(hans, options) {
  95. const phrases = this.segment(hans, options.segment);
  96. let pys = [];
  97. let nohans = "";
  98. for (let i = 0, l = phrases.length; i < l; i++) {
  99. const words = phrases[i];
  100. const firstCharCode = words.charCodeAt(0);
  101. if (DICT_ZI[firstCharCode]) {
  102. if (nohans.length > 0) {
  103. pys.push([nohans]);
  104. nohans = "";
  105. }
  106. const newPys = words.length === 1
  107. ? this.normal_pinyin(words, options)
  108. : this.phrases_pinyin(words, options);
  109. if (options.group) {
  110. pys.push(this.groupPhrases(newPys));
  111. }
  112. else {
  113. pys = pys.concat(newPys);
  114. }
  115. }
  116. else {
  117. nohans += words;
  118. }
  119. }
  120. if (nohans.length > 0) {
  121. pys.push([nohans]);
  122. nohans = "";
  123. }
  124. return pys;
  125. }
  126. phrases_pinyin(phrases, options) {
  127. const py = [];
  128. if (hasKey(DICT_PHRASES, phrases)) {
  129. DICT_PHRASES[phrases].forEach(function (item, idx) {
  130. py[idx] = [];
  131. if (options.heteronym) {
  132. item.forEach(function (py_item, py_index) {
  133. py[idx][py_index] = toFixed(py_item, options.style);
  134. });
  135. }
  136. else {
  137. py[idx][0] = toFixed(item[0], options.style);
  138. }
  139. });
  140. }
  141. else {
  142. for (let i = 0, l = phrases.length; i < l; i++) {
  143. py.push(this.single_pinyin(phrases[i], options));
  144. }
  145. }
  146. return py;
  147. }
  148. groupPhrases(phrases) {
  149. if (phrases.length === 1) {
  150. return phrases[0];
  151. }
  152. const grouped = combo(phrases);
  153. return grouped;
  154. }
  155. surname_pinyin(hans, options) {
  156. return this.compound_surname(hans, options);
  157. }
  158. compound_surname(hans, options) {
  159. const len = hans.length;
  160. let prefixIndex = 0;
  161. let result = [];
  162. for (let i = 0; i < len; i++) {
  163. const twowords = hans.substring(i, i + 2);
  164. if (hasKey(CompoundSurnamePinyinData, twowords)) {
  165. if (prefixIndex <= i - 1) {
  166. result = result.concat(this.single_surname(hans.substring(prefixIndex, i), options));
  167. }
  168. const pys = CompoundSurnamePinyinData[twowords].map((item) => {
  169. return item.map((ch) => toFixed(ch, options.style));
  170. });
  171. result = result.concat(pys);
  172. i = i + 2;
  173. prefixIndex = i;
  174. }
  175. }
  176. result = result.concat(this.single_surname(hans.substring(prefixIndex, len), options));
  177. return result;
  178. }
  179. single_surname(hans, options) {
  180. let result = [];
  181. for (let i = 0, l = hans.length; i < l; i++) {
  182. const word = hans.charAt(i);
  183. if (hasKey(SurnamePinyinData, word)) {
  184. const pys = SurnamePinyinData[word].map((item) => {
  185. return item.map((ch) => toFixed(ch, options.style));
  186. });
  187. result = result.concat(pys);
  188. }
  189. else {
  190. result.push(this.single_pinyin(word, options));
  191. }
  192. }
  193. return result;
  194. }
  195. compare(hanA, hanB) {
  196. const pinyinA = this.pinyin(hanA);
  197. const pinyinB = this.pinyin(hanB);
  198. return String(pinyinA).localeCompare(String(pinyinB));
  199. }
  200. compact(pys) {
  201. return compact(pys);
  202. }
  203. }
  204. export function getPinyinInstance(py) {
  205. const pinyin = py.pinyin.bind(py);
  206. pinyin.compare = py.compare.bind(py);
  207. pinyin.compact = py.compact.bind(py);
  208. pinyin.STYLE_TONE = ENUM_PINYIN_STYLE.TONE;
  209. pinyin.STYLE_TONE2 = ENUM_PINYIN_STYLE.TONE2;
  210. pinyin.STYLE_TO3NE = ENUM_PINYIN_STYLE.TO3NE;
  211. pinyin.STYLE_NORMAL = ENUM_PINYIN_STYLE.NORMAL;
  212. pinyin.STYLE_INITIALS = ENUM_PINYIN_STYLE.INITIALS;
  213. pinyin.STYLE_FIRST_LETTER = ENUM_PINYIN_STYLE.FIRST_LETTER;
  214. pinyin.STYLE_PASSPORT = ENUM_PINYIN_STYLE.PASSPORT;
  215. pinyin.MODE_NORMAL = ENUM_PINYIN_MODE.NORMAL;
  216. pinyin.MODE_SURNAME = ENUM_PINYIN_MODE.SURNAME;
  217. return pinyin;
  218. }
  219. //# sourceMappingURL=PinyinBase.js.map