Entities.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. /*************************************************************
  2. *
  3. * Copyright (c) 2017-2022 The MathJax Consortium
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /**
  18. * @fileoverview Converts named entities to unicode characters
  19. *
  20. * @author dpvc@mathjax.org (Davide Cervone)
  21. */
  22. import {retryAfter} from './Retries.js';
  23. import {asyncLoad} from './AsyncLoad.js';
  24. import {OptionList} from './Options.js';
  25. /**
  26. * The type for lists of entities
  27. */
  28. export type EntityList = {[name: string]: string};
  29. /**
  30. * Options controlling the process of conversion
  31. */
  32. export const options: OptionList = {
  33. loadMissingEntities: true // True means load entity files dynamically if needed
  34. };
  35. /**
  36. * The entity name-to-value translation table
  37. * (basic math entities -- others are loaded from external files)
  38. */
  39. export const entities: EntityList = {
  40. ApplyFunction: '\u2061',
  41. Backslash: '\u2216',
  42. Because: '\u2235',
  43. Breve: '\u02D8',
  44. Cap: '\u22D2',
  45. CenterDot: '\u00B7',
  46. CircleDot: '\u2299',
  47. CircleMinus: '\u2296',
  48. CirclePlus: '\u2295',
  49. CircleTimes: '\u2297',
  50. Congruent: '\u2261',
  51. ContourIntegral: '\u222E',
  52. Coproduct: '\u2210',
  53. Cross: '\u2A2F',
  54. Cup: '\u22D3',
  55. CupCap: '\u224D',
  56. Dagger: '\u2021',
  57. Del: '\u2207',
  58. Delta: '\u0394',
  59. Diamond: '\u22C4',
  60. DifferentialD: '\u2146',
  61. DotEqual: '\u2250',
  62. DoubleDot: '\u00A8',
  63. DoubleRightTee: '\u22A8',
  64. DoubleVerticalBar: '\u2225',
  65. DownArrow: '\u2193',
  66. DownLeftVector: '\u21BD',
  67. DownRightVector: '\u21C1',
  68. DownTee: '\u22A4',
  69. Downarrow: '\u21D3',
  70. Element: '\u2208',
  71. EqualTilde: '\u2242',
  72. Equilibrium: '\u21CC',
  73. Exists: '\u2203',
  74. ExponentialE: '\u2147',
  75. FilledVerySmallSquare: '\u25AA',
  76. ForAll: '\u2200',
  77. Gamma: '\u0393',
  78. Gg: '\u22D9',
  79. GreaterEqual: '\u2265',
  80. GreaterEqualLess: '\u22DB',
  81. GreaterFullEqual: '\u2267',
  82. GreaterLess: '\u2277',
  83. GreaterSlantEqual: '\u2A7E',
  84. GreaterTilde: '\u2273',
  85. Hacek: '\u02C7',
  86. Hat: '\u005E',
  87. HumpDownHump: '\u224E',
  88. HumpEqual: '\u224F',
  89. Im: '\u2111',
  90. ImaginaryI: '\u2148',
  91. Integral: '\u222B',
  92. Intersection: '\u22C2',
  93. InvisibleComma: '\u2063',
  94. InvisibleTimes: '\u2062',
  95. Lambda: '\u039B',
  96. Larr: '\u219E',
  97. LeftAngleBracket: '\u27E8',
  98. LeftArrow: '\u2190',
  99. LeftArrowRightArrow: '\u21C6',
  100. LeftCeiling: '\u2308',
  101. LeftDownVector: '\u21C3',
  102. LeftFloor: '\u230A',
  103. LeftRightArrow: '\u2194',
  104. LeftTee: '\u22A3',
  105. LeftTriangle: '\u22B2',
  106. LeftTriangleEqual: '\u22B4',
  107. LeftUpVector: '\u21BF',
  108. LeftVector: '\u21BC',
  109. Leftarrow: '\u21D0',
  110. Leftrightarrow: '\u21D4',
  111. LessEqualGreater: '\u22DA',
  112. LessFullEqual: '\u2266',
  113. LessGreater: '\u2276',
  114. LessSlantEqual: '\u2A7D',
  115. LessTilde: '\u2272',
  116. Ll: '\u22D8',
  117. Lleftarrow: '\u21DA',
  118. LongLeftArrow: '\u27F5',
  119. LongLeftRightArrow: '\u27F7',
  120. LongRightArrow: '\u27F6',
  121. Longleftarrow: '\u27F8',
  122. Longleftrightarrow: '\u27FA',
  123. Longrightarrow: '\u27F9',
  124. Lsh: '\u21B0',
  125. MinusPlus: '\u2213',
  126. NestedGreaterGreater: '\u226B',
  127. NestedLessLess: '\u226A',
  128. NotDoubleVerticalBar: '\u2226',
  129. NotElement: '\u2209',
  130. NotEqual: '\u2260',
  131. NotExists: '\u2204',
  132. NotGreater: '\u226F',
  133. NotGreaterEqual: '\u2271',
  134. NotLeftTriangle: '\u22EA',
  135. NotLeftTriangleEqual: '\u22EC',
  136. NotLess: '\u226E',
  137. NotLessEqual: '\u2270',
  138. NotPrecedes: '\u2280',
  139. NotPrecedesSlantEqual: '\u22E0',
  140. NotRightTriangle: '\u22EB',
  141. NotRightTriangleEqual: '\u22ED',
  142. NotSubsetEqual: '\u2288',
  143. NotSucceeds: '\u2281',
  144. NotSucceedsSlantEqual: '\u22E1',
  145. NotSupersetEqual: '\u2289',
  146. NotTilde: '\u2241',
  147. NotVerticalBar: '\u2224',
  148. Omega: '\u03A9',
  149. OverBar: '\u203E',
  150. OverBrace: '\u23DE',
  151. PartialD: '\u2202',
  152. Phi: '\u03A6',
  153. Pi: '\u03A0',
  154. PlusMinus: '\u00B1',
  155. Precedes: '\u227A',
  156. PrecedesEqual: '\u2AAF',
  157. PrecedesSlantEqual: '\u227C',
  158. PrecedesTilde: '\u227E',
  159. Product: '\u220F',
  160. Proportional: '\u221D',
  161. Psi: '\u03A8',
  162. Rarr: '\u21A0',
  163. Re: '\u211C',
  164. ReverseEquilibrium: '\u21CB',
  165. RightAngleBracket: '\u27E9',
  166. RightArrow: '\u2192',
  167. RightArrowLeftArrow: '\u21C4',
  168. RightCeiling: '\u2309',
  169. RightDownVector: '\u21C2',
  170. RightFloor: '\u230B',
  171. RightTee: '\u22A2',
  172. RightTeeArrow: '\u21A6',
  173. RightTriangle: '\u22B3',
  174. RightTriangleEqual: '\u22B5',
  175. RightUpVector: '\u21BE',
  176. RightVector: '\u21C0',
  177. Rightarrow: '\u21D2',
  178. Rrightarrow: '\u21DB',
  179. Rsh: '\u21B1',
  180. Sigma: '\u03A3',
  181. SmallCircle: '\u2218',
  182. Sqrt: '\u221A',
  183. Square: '\u25A1',
  184. SquareIntersection: '\u2293',
  185. SquareSubset: '\u228F',
  186. SquareSubsetEqual: '\u2291',
  187. SquareSuperset: '\u2290',
  188. SquareSupersetEqual: '\u2292',
  189. SquareUnion: '\u2294',
  190. Star: '\u22C6',
  191. Subset: '\u22D0',
  192. SubsetEqual: '\u2286',
  193. Succeeds: '\u227B',
  194. SucceedsEqual: '\u2AB0',
  195. SucceedsSlantEqual: '\u227D',
  196. SucceedsTilde: '\u227F',
  197. SuchThat: '\u220B',
  198. Sum: '\u2211',
  199. Superset: '\u2283',
  200. SupersetEqual: '\u2287',
  201. Supset: '\u22D1',
  202. Therefore: '\u2234',
  203. Theta: '\u0398',
  204. Tilde: '\u223C',
  205. TildeEqual: '\u2243',
  206. TildeFullEqual: '\u2245',
  207. TildeTilde: '\u2248',
  208. UnderBar: '\u005F',
  209. UnderBrace: '\u23DF',
  210. Union: '\u22C3',
  211. UnionPlus: '\u228E',
  212. UpArrow: '\u2191',
  213. UpDownArrow: '\u2195',
  214. UpTee: '\u22A5',
  215. Uparrow: '\u21D1',
  216. Updownarrow: '\u21D5',
  217. Upsilon: '\u03A5',
  218. Vdash: '\u22A9',
  219. Vee: '\u22C1',
  220. VerticalBar: '\u2223',
  221. VerticalTilde: '\u2240',
  222. Vvdash: '\u22AA',
  223. Wedge: '\u22C0',
  224. Xi: '\u039E',
  225. amp: '\u0026',
  226. acute: '\u00B4',
  227. aleph: '\u2135',
  228. alpha: '\u03B1',
  229. amalg: '\u2A3F',
  230. and: '\u2227',
  231. ang: '\u2220',
  232. angmsd: '\u2221',
  233. angsph: '\u2222',
  234. ape: '\u224A',
  235. backprime: '\u2035',
  236. backsim: '\u223D',
  237. backsimeq: '\u22CD',
  238. beta: '\u03B2',
  239. beth: '\u2136',
  240. between: '\u226C',
  241. bigcirc: '\u25EF',
  242. bigodot: '\u2A00',
  243. bigoplus: '\u2A01',
  244. bigotimes: '\u2A02',
  245. bigsqcup: '\u2A06',
  246. bigstar: '\u2605',
  247. bigtriangledown: '\u25BD',
  248. bigtriangleup: '\u25B3',
  249. biguplus: '\u2A04',
  250. blacklozenge: '\u29EB',
  251. blacktriangle: '\u25B4',
  252. blacktriangledown: '\u25BE',
  253. blacktriangleleft: '\u25C2',
  254. bowtie: '\u22C8',
  255. boxdl: '\u2510',
  256. boxdr: '\u250C',
  257. boxminus: '\u229F',
  258. boxplus: '\u229E',
  259. boxtimes: '\u22A0',
  260. boxul: '\u2518',
  261. boxur: '\u2514',
  262. bsol: '\u005C',
  263. bull: '\u2022',
  264. cap: '\u2229',
  265. check: '\u2713',
  266. chi: '\u03C7',
  267. circ: '\u02C6',
  268. circeq: '\u2257',
  269. circlearrowleft: '\u21BA',
  270. circlearrowright: '\u21BB',
  271. circledR: '\u00AE',
  272. circledS: '\u24C8',
  273. circledast: '\u229B',
  274. circledcirc: '\u229A',
  275. circleddash: '\u229D',
  276. clubs: '\u2663',
  277. colon: '\u003A',
  278. comp: '\u2201',
  279. ctdot: '\u22EF',
  280. cuepr: '\u22DE',
  281. cuesc: '\u22DF',
  282. cularr: '\u21B6',
  283. cup: '\u222A',
  284. curarr: '\u21B7',
  285. curlyvee: '\u22CE',
  286. curlywedge: '\u22CF',
  287. dagger: '\u2020',
  288. daleth: '\u2138',
  289. ddarr: '\u21CA',
  290. deg: '\u00B0',
  291. delta: '\u03B4',
  292. digamma: '\u03DD',
  293. div: '\u00F7',
  294. divideontimes: '\u22C7',
  295. dot: '\u02D9',
  296. doteqdot: '\u2251',
  297. dotplus: '\u2214',
  298. dotsquare: '\u22A1',
  299. dtdot: '\u22F1',
  300. ecir: '\u2256',
  301. efDot: '\u2252',
  302. egs: '\u2A96',
  303. ell: '\u2113',
  304. els: '\u2A95',
  305. empty: '\u2205',
  306. epsi: '\u03B5',
  307. epsiv: '\u03F5',
  308. erDot: '\u2253',
  309. eta: '\u03B7',
  310. eth: '\u00F0',
  311. flat: '\u266D',
  312. fork: '\u22D4',
  313. frown: '\u2322',
  314. gEl: '\u2A8C',
  315. gamma: '\u03B3',
  316. gap: '\u2A86',
  317. gimel: '\u2137',
  318. gnE: '\u2269',
  319. gnap: '\u2A8A',
  320. gne: '\u2A88',
  321. gnsim: '\u22E7',
  322. gt: '\u003E',
  323. gtdot: '\u22D7',
  324. harrw: '\u21AD',
  325. hbar: '\u210F',
  326. hellip: '\u2026',
  327. hookleftarrow: '\u21A9',
  328. hookrightarrow: '\u21AA',
  329. imath: '\u0131',
  330. infin: '\u221E',
  331. intcal: '\u22BA',
  332. iota: '\u03B9',
  333. jmath: '\u0237',
  334. kappa: '\u03BA',
  335. kappav: '\u03F0',
  336. lEg: '\u2A8B',
  337. lambda: '\u03BB',
  338. lap: '\u2A85',
  339. larrlp: '\u21AB',
  340. larrtl: '\u21A2',
  341. lbrace: '\u007B',
  342. lbrack: '\u005B',
  343. le: '\u2264',
  344. leftleftarrows: '\u21C7',
  345. leftthreetimes: '\u22CB',
  346. lessdot: '\u22D6',
  347. lmoust: '\u23B0',
  348. lnE: '\u2268',
  349. lnap: '\u2A89',
  350. lne: '\u2A87',
  351. lnsim: '\u22E6',
  352. longmapsto: '\u27FC',
  353. looparrowright: '\u21AC',
  354. lowast: '\u2217',
  355. loz: '\u25CA',
  356. lt: '\u003C',
  357. ltimes: '\u22C9',
  358. ltri: '\u25C3',
  359. macr: '\u00AF',
  360. malt: '\u2720',
  361. mho: '\u2127',
  362. mu: '\u03BC',
  363. multimap: '\u22B8',
  364. nLeftarrow: '\u21CD',
  365. nLeftrightarrow: '\u21CE',
  366. nRightarrow: '\u21CF',
  367. nVDash: '\u22AF',
  368. nVdash: '\u22AE',
  369. natur: '\u266E',
  370. nearr: '\u2197',
  371. nharr: '\u21AE',
  372. nlarr: '\u219A',
  373. not: '\u00AC',
  374. nrarr: '\u219B',
  375. nu: '\u03BD',
  376. nvDash: '\u22AD',
  377. nvdash: '\u22AC',
  378. nwarr: '\u2196',
  379. omega: '\u03C9',
  380. omicron: '\u03BF',
  381. or: '\u2228',
  382. osol: '\u2298',
  383. period: '\u002E',
  384. phi: '\u03C6',
  385. phiv: '\u03D5',
  386. pi: '\u03C0',
  387. piv: '\u03D6',
  388. prap: '\u2AB7',
  389. precnapprox: '\u2AB9',
  390. precneqq: '\u2AB5',
  391. precnsim: '\u22E8',
  392. prime: '\u2032',
  393. psi: '\u03C8',
  394. quot: '\u0022',
  395. rarrtl: '\u21A3',
  396. rbrace: '\u007D',
  397. rbrack: '\u005D',
  398. rho: '\u03C1',
  399. rhov: '\u03F1',
  400. rightrightarrows: '\u21C9',
  401. rightthreetimes: '\u22CC',
  402. ring: '\u02DA',
  403. rmoust: '\u23B1',
  404. rtimes: '\u22CA',
  405. rtri: '\u25B9',
  406. scap: '\u2AB8',
  407. scnE: '\u2AB6',
  408. scnap: '\u2ABA',
  409. scnsim: '\u22E9',
  410. sdot: '\u22C5',
  411. searr: '\u2198',
  412. sect: '\u00A7',
  413. sharp: '\u266F',
  414. sigma: '\u03C3',
  415. sigmav: '\u03C2',
  416. simne: '\u2246',
  417. smile: '\u2323',
  418. spades: '\u2660',
  419. sub: '\u2282',
  420. subE: '\u2AC5',
  421. subnE: '\u2ACB',
  422. subne: '\u228A',
  423. supE: '\u2AC6',
  424. supnE: '\u2ACC',
  425. supne: '\u228B',
  426. swarr: '\u2199',
  427. tau: '\u03C4',
  428. theta: '\u03B8',
  429. thetav: '\u03D1',
  430. tilde: '\u02DC',
  431. times: '\u00D7',
  432. triangle: '\u25B5',
  433. triangleq: '\u225C',
  434. upsi: '\u03C5',
  435. upuparrows: '\u21C8',
  436. veebar: '\u22BB',
  437. vellip: '\u22EE',
  438. weierp: '\u2118',
  439. xi: '\u03BE',
  440. yen: '\u00A5',
  441. zeta: '\u03B6',
  442. zigrarr: '\u21DD',
  443. //
  444. // Needed by TeX input jax
  445. nbsp: '\u00A0',
  446. rsquo: '\u2019',
  447. lsquo: '\u2018'
  448. };
  449. /**
  450. * The files that have been loaded
  451. */
  452. const loaded: {[name: string]: boolean} = {};
  453. /**
  454. * Used by entity files to add more entities to the table
  455. *
  456. * @param {EntityList} additions The entities to add
  457. * @param {string} file The name of the file that they came from
  458. */
  459. export function add(additions: EntityList, file: string) {
  460. Object.assign(entities, additions);
  461. loaded[file] = true;
  462. }
  463. /**
  464. * Used to remove an entity from the list, if needed
  465. *
  466. * @param {string} entity The name of the entity to remove
  467. */
  468. export function remove(entity: string) {
  469. delete entities[entity];
  470. }
  471. /**
  472. * @param {string} text The text whose entities are to be replaced
  473. * @return {string} The text with entries replaced
  474. */
  475. export function translate(text: string): string {
  476. return text.replace(/&([a-z][a-z0-9]*|#(?:[0-9]+|x[0-9a-f]+));/ig, replace);
  477. }
  478. /**
  479. * Returns the unicode character for an entity, if found
  480. * If not, loads an entity file to see if it is there (and retries after loading)
  481. * Otherwire, returns the original entity string
  482. *
  483. * @param {string} match The complete entity being replaced
  484. * @param {string} entity The name of the entity to be replaced
  485. * @return {string} The unicode character for the entity, or the entity name (if none found)
  486. */
  487. function replace(match: string, entity: string): string {
  488. if (entity.charAt(0) === '#') {
  489. return numeric(entity.slice(1));
  490. }
  491. if (entities[entity]) {
  492. return entities[entity];
  493. }
  494. if (options['loadMissingEntities']) {
  495. let file = (entity.match(/^[a-zA-Z](fr|scr|opf)$/) ? RegExp.$1 : entity.charAt(0).toLowerCase());
  496. if (!loaded[file]) {
  497. loaded[file] = true;
  498. retryAfter(asyncLoad('./util/entities/' + file + '.js'));
  499. }
  500. }
  501. return match;
  502. }
  503. /**
  504. * @param {string} entity The character code point as a string
  505. * @return {string} The character(s) with the given code point
  506. */
  507. export function numeric(entity: string): string {
  508. let n = (entity.charAt(0) === 'x' ?
  509. parseInt(entity.slice(1), 16) :
  510. parseInt(entity));
  511. return String.fromCodePoint(n);
  512. }