alphabet.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. export var Font;
  2. (function (Font) {
  3. Font["BOLD"] = "bold";
  4. Font["BOLDFRAKTUR"] = "bold-fraktur";
  5. Font["BOLDITALIC"] = "bold-italic";
  6. Font["BOLDSCRIPT"] = "bold-script";
  7. Font["DOUBLESTRUCK"] = "double-struck";
  8. Font["DOUBLESTRUCKITALIC"] = "double-struck-italic";
  9. Font["FULLWIDTH"] = "fullwidth";
  10. Font["FRAKTUR"] = "fraktur";
  11. Font["ITALIC"] = "italic";
  12. Font["MONOSPACE"] = "monospace";
  13. Font["NORMAL"] = "normal";
  14. Font["SCRIPT"] = "script";
  15. Font["SANSSERIF"] = "sans-serif";
  16. Font["SANSSERIFITALIC"] = "sans-serif-italic";
  17. Font["SANSSERIFBOLD"] = "sans-serif-bold";
  18. Font["SANSSERIFBOLDITALIC"] = "sans-serif-bold-italic";
  19. })(Font || (Font = {}));
  20. export var Embellish;
  21. (function (Embellish) {
  22. Embellish["SUPER"] = "super";
  23. Embellish["SUB"] = "sub";
  24. Embellish["CIRCLED"] = "circled";
  25. Embellish["PARENTHESIZED"] = "parenthesized";
  26. Embellish["PERIOD"] = "period";
  27. Embellish["NEGATIVECIRCLED"] = "negative-circled";
  28. Embellish["DOUBLECIRCLED"] = "double-circled";
  29. Embellish["CIRCLEDSANSSERIF"] = "circled-sans-serif";
  30. Embellish["NEGATIVECIRCLEDSANSSERIF"] = "negative-circled-sans-serif";
  31. Embellish["COMMA"] = "comma";
  32. Embellish["SQUARED"] = "squared";
  33. Embellish["NEGATIVESQUARED"] = "negative-squared";
  34. })(Embellish || (Embellish = {}));
  35. export var Base;
  36. (function (Base) {
  37. Base["LATINCAP"] = "latinCap";
  38. Base["LATINSMALL"] = "latinSmall";
  39. Base["GREEKCAP"] = "greekCap";
  40. Base["GREEKSMALL"] = "greekSmall";
  41. Base["DIGIT"] = "digit";
  42. })(Base || (Base = {}));
  43. function num2str(num) {
  44. const str = num.toString(16).toUpperCase();
  45. return str.length > 3 ? str : ('000' + str).slice(-4);
  46. }
  47. export function makeInterval([a, b], subst) {
  48. const start = parseInt(a, 16);
  49. const end = parseInt(b, 16);
  50. const result = [];
  51. for (let i = start; i <= end; i++) {
  52. let key = num2str(i);
  53. const sub = subst[key];
  54. if (sub === false) {
  55. continue;
  56. }
  57. key = subst[key] || key;
  58. result.push(key);
  59. }
  60. return result;
  61. }
  62. function makeCharInterval(int, subst = {}) {
  63. return makeInterval(int, subst).map((x) => String.fromCodePoint(parseInt(x, 16)));
  64. }
  65. export function makeMultiInterval(ints) {
  66. let result = [];
  67. for (const int of ints) {
  68. if (Array.isArray(int)) {
  69. result = result.concat(makeCharInterval(int));
  70. continue;
  71. }
  72. result.push(String.fromCodePoint(parseInt(int, 16)));
  73. }
  74. return result;
  75. }
  76. export function makeCodeInterval(ints) {
  77. let result = [];
  78. for (const int of ints) {
  79. if (Array.isArray(int)) {
  80. result = result.concat(makeInterval(int, {}).map((x) => parseInt(x, 16)));
  81. continue;
  82. }
  83. result.push(parseInt(int, 16));
  84. }
  85. return result;
  86. }
  87. const PROTO_INTERVALS = [
  88. {
  89. interval: ['1D400', '1D419'],
  90. base: Base.LATINCAP,
  91. subst: {},
  92. capital: true,
  93. category: 'Lu',
  94. font: Font.BOLD
  95. },
  96. {
  97. interval: ['1D41A', '1D433'],
  98. base: Base.LATINSMALL,
  99. subst: {},
  100. capital: false,
  101. category: 'Ll',
  102. font: Font.BOLD
  103. },
  104. {
  105. interval: ['1D56C', '1D585'],
  106. base: Base.LATINCAP,
  107. subst: {},
  108. capital: true,
  109. category: 'Lu',
  110. font: Font.BOLDFRAKTUR
  111. },
  112. {
  113. interval: ['1D586', '1D59F'],
  114. base: Base.LATINSMALL,
  115. subst: {},
  116. capital: false,
  117. category: 'Ll',
  118. font: Font.BOLDFRAKTUR
  119. },
  120. {
  121. interval: ['1D468', '1D481'],
  122. base: Base.LATINCAP,
  123. subst: {},
  124. capital: true,
  125. category: 'Lu',
  126. font: Font.BOLDITALIC
  127. },
  128. {
  129. interval: ['1D482', '1D49B'],
  130. base: Base.LATINSMALL,
  131. subst: {},
  132. capital: false,
  133. category: 'Ll',
  134. font: Font.BOLDITALIC
  135. },
  136. {
  137. interval: ['1D4D0', '1D4E9'],
  138. base: Base.LATINCAP,
  139. subst: {},
  140. capital: true,
  141. category: 'Lu',
  142. font: Font.BOLDSCRIPT
  143. },
  144. {
  145. interval: ['1D4EA', '1D503'],
  146. base: Base.LATINSMALL,
  147. subst: {},
  148. capital: false,
  149. category: 'Ll',
  150. font: Font.BOLDSCRIPT
  151. },
  152. {
  153. interval: ['1D538', '1D551'],
  154. base: Base.LATINCAP,
  155. subst: {
  156. '1D53A': '2102',
  157. '1D53F': '210D',
  158. '1D545': '2115',
  159. '1D547': '2119',
  160. '1D548': '211A',
  161. '1D549': '211D',
  162. '1D551': '2124'
  163. },
  164. capital: true,
  165. category: 'Lu',
  166. font: Font.DOUBLESTRUCK
  167. },
  168. {
  169. interval: ['1D552', '1D56B'],
  170. base: Base.LATINSMALL,
  171. subst: {},
  172. capital: false,
  173. category: 'Ll',
  174. font: Font.DOUBLESTRUCK
  175. },
  176. {
  177. interval: ['1D504', '1D51D'],
  178. base: Base.LATINCAP,
  179. subst: {
  180. '1D506': '212D',
  181. '1D50B': '210C',
  182. '1D50C': '2111',
  183. '1D515': '211C',
  184. '1D51D': '2128'
  185. },
  186. capital: true,
  187. category: 'Lu',
  188. font: Font.FRAKTUR
  189. },
  190. {
  191. interval: ['1D51E', '1D537'],
  192. base: Base.LATINSMALL,
  193. subst: {},
  194. capital: false,
  195. category: 'Ll',
  196. font: Font.FRAKTUR
  197. },
  198. {
  199. interval: ['FF21', 'FF3A'],
  200. base: Base.LATINCAP,
  201. subst: {},
  202. capital: true,
  203. category: 'Lu',
  204. font: Font.FULLWIDTH
  205. },
  206. {
  207. interval: ['FF41', 'FF5A'],
  208. base: Base.LATINSMALL,
  209. subst: {},
  210. capital: false,
  211. category: 'Ll',
  212. font: Font.FULLWIDTH
  213. },
  214. {
  215. interval: ['1D434', '1D44D'],
  216. base: Base.LATINCAP,
  217. subst: {},
  218. capital: true,
  219. category: 'Lu',
  220. font: Font.ITALIC
  221. },
  222. {
  223. interval: ['1D44E', '1D467'],
  224. base: Base.LATINSMALL,
  225. subst: { '1D455': '210E' },
  226. capital: false,
  227. category: 'Ll',
  228. font: Font.ITALIC
  229. },
  230. {
  231. interval: ['1D670', '1D689'],
  232. base: Base.LATINCAP,
  233. subst: {},
  234. capital: true,
  235. category: 'Lu',
  236. font: Font.MONOSPACE
  237. },
  238. {
  239. interval: ['1D68A', '1D6A3'],
  240. base: Base.LATINSMALL,
  241. subst: {},
  242. capital: false,
  243. category: 'Ll',
  244. font: Font.MONOSPACE
  245. },
  246. {
  247. interval: ['0041', '005A'],
  248. base: Base.LATINCAP,
  249. subst: {},
  250. capital: true,
  251. category: 'Lu',
  252. font: Font.NORMAL
  253. },
  254. {
  255. interval: ['0061', '007A'],
  256. base: Base.LATINSMALL,
  257. subst: {},
  258. capital: false,
  259. category: 'Ll',
  260. font: Font.NORMAL
  261. },
  262. {
  263. interval: ['1D49C', '1D4B5'],
  264. base: Base.LATINCAP,
  265. subst: {
  266. '1D49D': '212C',
  267. '1D4A0': '2130',
  268. '1D4A1': '2131',
  269. '1D4A3': '210B',
  270. '1D4A4': '2110',
  271. '1D4A7': '2112',
  272. '1D4A8': '2133',
  273. '1D4AD': '211B'
  274. },
  275. capital: true,
  276. category: 'Lu',
  277. font: Font.SCRIPT
  278. },
  279. {
  280. interval: ['1D4B6', '1D4CF'],
  281. base: Base.LATINSMALL,
  282. subst: { '1D4BA': '212F', '1D4BC': '210A', '1D4C4': '2134' },
  283. capital: false,
  284. category: 'Ll',
  285. font: Font.SCRIPT
  286. },
  287. {
  288. interval: ['1D5A0', '1D5B9'],
  289. base: Base.LATINCAP,
  290. subst: {},
  291. capital: true,
  292. category: 'Lu',
  293. font: Font.SANSSERIF
  294. },
  295. {
  296. interval: ['1D5BA', '1D5D3'],
  297. base: Base.LATINSMALL,
  298. subst: {},
  299. capital: false,
  300. category: 'Ll',
  301. font: Font.SANSSERIF
  302. },
  303. {
  304. interval: ['1D608', '1D621'],
  305. base: Base.LATINCAP,
  306. subst: {},
  307. capital: true,
  308. category: 'Lu',
  309. font: Font.SANSSERIFITALIC
  310. },
  311. {
  312. interval: ['1D622', '1D63B'],
  313. base: Base.LATINSMALL,
  314. subst: {},
  315. capital: false,
  316. category: 'Ll',
  317. font: Font.SANSSERIFITALIC
  318. },
  319. {
  320. interval: ['1D5D4', '1D5ED'],
  321. base: Base.LATINCAP,
  322. subst: {},
  323. capital: true,
  324. category: 'Lu',
  325. font: Font.SANSSERIFBOLD
  326. },
  327. {
  328. interval: ['1D5EE', '1D607'],
  329. base: Base.LATINSMALL,
  330. subst: {},
  331. capital: false,
  332. category: 'Ll',
  333. font: Font.SANSSERIFBOLD
  334. },
  335. {
  336. interval: ['1D63C', '1D655'],
  337. base: Base.LATINCAP,
  338. subst: {},
  339. capital: true,
  340. category: 'Lu',
  341. font: Font.SANSSERIFBOLDITALIC
  342. },
  343. {
  344. interval: ['1D656', '1D66F'],
  345. base: Base.LATINSMALL,
  346. subst: {},
  347. capital: false,
  348. category: 'Ll',
  349. font: Font.SANSSERIFBOLDITALIC
  350. },
  351. {
  352. interval: ['0391', '03A9'],
  353. base: Base.GREEKCAP,
  354. subst: { '03A2': '03F4' },
  355. capital: true,
  356. category: 'Lu',
  357. font: Font.NORMAL
  358. },
  359. {
  360. interval: ['03B0', '03D0'],
  361. base: Base.GREEKSMALL,
  362. subst: {
  363. '03B0': '2207',
  364. '03CA': '2202',
  365. '03CB': '03F5',
  366. '03CC': '03D1',
  367. '03CD': '03F0',
  368. '03CE': '03D5',
  369. '03CF': '03F1',
  370. '03D0': '03D6'
  371. },
  372. capital: false,
  373. category: 'Ll',
  374. font: Font.NORMAL
  375. },
  376. {
  377. interval: ['1D6A8', '1D6C0'],
  378. base: Base.GREEKCAP,
  379. subst: {},
  380. capital: true,
  381. category: 'Lu',
  382. font: Font.BOLD
  383. },
  384. {
  385. interval: ['1D6C1', '1D6E1'],
  386. base: Base.GREEKSMALL,
  387. subst: {},
  388. capital: false,
  389. category: 'Ll',
  390. font: Font.BOLD
  391. },
  392. {
  393. interval: ['1D6E2', '1D6FA'],
  394. base: Base.GREEKCAP,
  395. subst: {},
  396. capital: true,
  397. category: 'Lu',
  398. font: Font.ITALIC
  399. },
  400. {
  401. interval: ['1D6FB', '1D71B'],
  402. base: Base.GREEKSMALL,
  403. subst: {},
  404. capital: false,
  405. category: 'Ll',
  406. font: Font.ITALIC
  407. },
  408. {
  409. interval: ['1D71C', '1D734'],
  410. base: Base.GREEKCAP,
  411. subst: {},
  412. capital: true,
  413. category: 'Lu',
  414. font: Font.BOLDITALIC
  415. },
  416. {
  417. interval: ['1D735', '1D755'],
  418. base: Base.GREEKSMALL,
  419. subst: {},
  420. capital: false,
  421. category: 'Ll',
  422. font: Font.BOLDITALIC
  423. },
  424. {
  425. interval: ['1D756', '1D76E'],
  426. base: Base.GREEKCAP,
  427. subst: {},
  428. capital: true,
  429. category: 'Lu',
  430. font: Font.SANSSERIFBOLD
  431. },
  432. {
  433. interval: ['1D76F', '1D78F'],
  434. base: Base.GREEKSMALL,
  435. subst: {},
  436. capital: false,
  437. category: 'Ll',
  438. font: Font.SANSSERIFBOLD
  439. },
  440. {
  441. interval: ['1D790', '1D7A8'],
  442. base: Base.GREEKCAP,
  443. subst: {},
  444. capital: true,
  445. category: 'Lu',
  446. font: Font.SANSSERIFBOLDITALIC
  447. },
  448. {
  449. interval: ['1D7A9', '1D7C9'],
  450. base: Base.GREEKSMALL,
  451. subst: {},
  452. capital: false,
  453. category: 'Ll',
  454. font: Font.SANSSERIFBOLDITALIC
  455. },
  456. {
  457. interval: ['0030', '0039'],
  458. base: Base.DIGIT,
  459. subst: {},
  460. offset: 0,
  461. category: 'Nd',
  462. font: Font.NORMAL
  463. },
  464. {
  465. interval: ['2070', '2079'],
  466. base: Base.DIGIT,
  467. subst: { 2071: '00B9', 2072: '00B2', 2073: '00B3' },
  468. offset: 0,
  469. category: 'No',
  470. font: Embellish.SUPER
  471. },
  472. {
  473. interval: ['2080', '2089'],
  474. base: Base.DIGIT,
  475. subst: {},
  476. offset: 0,
  477. category: 'No',
  478. font: Embellish.SUB
  479. },
  480. {
  481. interval: ['245F', '2473'],
  482. base: Base.DIGIT,
  483. subst: { '245F': '24EA' },
  484. offset: 0,
  485. category: 'No',
  486. font: Embellish.CIRCLED
  487. },
  488. {
  489. interval: ['3251', '325F'],
  490. base: Base.DIGIT,
  491. subst: {},
  492. offset: 21,
  493. category: 'No',
  494. font: Embellish.CIRCLED
  495. },
  496. {
  497. interval: ['32B1', '32BF'],
  498. base: Base.DIGIT,
  499. subst: {},
  500. offset: 36,
  501. category: 'No',
  502. font: Embellish.CIRCLED
  503. },
  504. {
  505. interval: ['2474', '2487'],
  506. base: Base.DIGIT,
  507. subst: {},
  508. offset: 1,
  509. category: 'No',
  510. font: Embellish.PARENTHESIZED
  511. },
  512. {
  513. interval: ['2487', '249B'],
  514. base: Base.DIGIT,
  515. subst: { 2487: '1F100' },
  516. offset: 0,
  517. category: 'No',
  518. font: Embellish.PERIOD
  519. },
  520. {
  521. interval: ['2775', '277F'],
  522. base: Base.DIGIT,
  523. subst: { 2775: '24FF' },
  524. offset: 0,
  525. category: 'No',
  526. font: Embellish.NEGATIVECIRCLED
  527. },
  528. {
  529. interval: ['24EB', '24F4'],
  530. base: Base.DIGIT,
  531. subst: {},
  532. offset: 11,
  533. category: 'No',
  534. font: Embellish.NEGATIVECIRCLED
  535. },
  536. {
  537. interval: ['24F5', '24FE'],
  538. base: Base.DIGIT,
  539. subst: {},
  540. offset: 1,
  541. category: 'No',
  542. font: Embellish.DOUBLECIRCLED
  543. },
  544. {
  545. interval: ['277F', '2789'],
  546. base: Base.DIGIT,
  547. subst: { '277F': '1F10B' },
  548. offset: 0,
  549. category: 'No',
  550. font: Embellish.CIRCLEDSANSSERIF
  551. },
  552. {
  553. interval: ['2789', '2793'],
  554. base: Base.DIGIT,
  555. subst: { 2789: '1F10C' },
  556. offset: 0,
  557. category: 'No',
  558. font: Embellish.NEGATIVECIRCLEDSANSSERIF
  559. },
  560. {
  561. interval: ['FF10', 'FF19'],
  562. base: Base.DIGIT,
  563. subst: {},
  564. offset: 0,
  565. category: 'Nd',
  566. font: Font.FULLWIDTH
  567. },
  568. {
  569. interval: ['1D7CE', '1D7D7'],
  570. base: Base.DIGIT,
  571. subst: {},
  572. offset: 0,
  573. category: 'Nd',
  574. font: Font.BOLD
  575. },
  576. {
  577. interval: ['1D7D8', '1D7E1'],
  578. base: Base.DIGIT,
  579. subst: {},
  580. offset: 0,
  581. category: 'Nd',
  582. font: Font.DOUBLESTRUCK
  583. },
  584. {
  585. interval: ['1D7E2', '1D7EB'],
  586. base: Base.DIGIT,
  587. subst: {},
  588. offset: 0,
  589. category: 'Nd',
  590. font: Font.SANSSERIF
  591. },
  592. {
  593. interval: ['1D7EC', '1D7F5'],
  594. base: Base.DIGIT,
  595. subst: {},
  596. offset: 0,
  597. category: 'Nd',
  598. font: Font.SANSSERIFBOLD
  599. },
  600. {
  601. interval: ['1D7F6', '1D7FF'],
  602. base: Base.DIGIT,
  603. subst: {},
  604. offset: 0,
  605. category: 'Nd',
  606. font: Font.MONOSPACE
  607. },
  608. {
  609. interval: ['1F101', '1F10A'],
  610. base: Base.DIGIT,
  611. subst: {},
  612. offset: 0,
  613. category: 'No',
  614. font: Embellish.COMMA
  615. },
  616. {
  617. interval: ['24B6', '24CF'],
  618. base: Base.LATINCAP,
  619. subst: {},
  620. capital: true,
  621. category: 'So',
  622. font: Embellish.CIRCLED
  623. },
  624. {
  625. interval: ['24D0', '24E9'],
  626. base: Base.LATINSMALL,
  627. subst: {},
  628. capital: false,
  629. category: 'So',
  630. font: Embellish.CIRCLED
  631. },
  632. {
  633. interval: ['1F110', '1F129'],
  634. base: Base.LATINCAP,
  635. subst: {},
  636. capital: true,
  637. category: 'So',
  638. font: Embellish.PARENTHESIZED
  639. },
  640. {
  641. interval: ['249C', '24B5'],
  642. base: Base.LATINSMALL,
  643. subst: {},
  644. capital: false,
  645. category: 'So',
  646. font: Embellish.PARENTHESIZED
  647. },
  648. {
  649. interval: ['1F130', '1F149'],
  650. base: Base.LATINCAP,
  651. subst: {},
  652. capital: true,
  653. category: 'So',
  654. font: Embellish.SQUARED
  655. },
  656. {
  657. interval: ['1F170', '1F189'],
  658. base: Base.LATINCAP,
  659. subst: {},
  660. capital: true,
  661. category: 'So',
  662. font: Embellish.NEGATIVESQUARED
  663. },
  664. {
  665. interval: ['1F150', '1F169'],
  666. base: Base.LATINCAP,
  667. subst: {},
  668. capital: true,
  669. category: 'So',
  670. font: Embellish.NEGATIVECIRCLED
  671. }
  672. ];
  673. export const INTERVALS = new Map();
  674. export function alphabetName(base, font) {
  675. const capFont = font
  676. .split('-')
  677. .map((x) => x[0].toUpperCase() + x.slice(1))
  678. .join('');
  679. return base + capFont;
  680. }
  681. for (const proto of PROTO_INTERVALS) {
  682. const key = alphabetName(proto.base, proto.font);
  683. const interval = makeCharInterval(proto.interval, proto.subst);
  684. let alphabet = INTERVALS.get(key);
  685. if (alphabet) {
  686. alphabet.unicode = alphabet.unicode.concat(interval);
  687. continue;
  688. }
  689. alphabet = proto;
  690. alphabet.unicode = interval;
  691. INTERVALS.set(key, alphabet);
  692. }