aboutsummaryrefslogtreecommitdiff
path: root/js/stmd.js
blob: 2a63d23c5c2649a6114593870546ec18f70cd48c (plain)
  1. // stmd.js - CommomMark in javascript
  2. // Copyright (C) 2014 John MacFarlane
  3. // License: BSD3.
  4. // Basic usage:
  5. //
  6. // var stmd = require('stmd');
  7. // var parser = new stmd.DocParser();
  8. // var renderer = new stmd.HtmlRenderer();
  9. // console.log(renderer.render(parser.parse('Hello *world*')));
  10. (function(exports) {
  11. var entities = { AAacute: 'Á',
  12. aacute: 'á',
  13. Abreve: 'Ă',
  14. abreve: 'ă',
  15. ac: '∾',
  16. acd: '∿',
  17. acE: '∾',
  18. Acirc: 'Â',
  19. acirc: 'â',
  20. acute: '´',
  21. Acy: 'А',
  22. acy: 'а',
  23. AElig: 'Æ',
  24. aelig: 'æ',
  25. af: '⁡',
  26. Afr: '𝔄',
  27. afr: '𝔞',
  28. Agrave: 'À',
  29. agrave: 'à',
  30. alefsym: 'ℵ',
  31. aleph: 'ℵ',
  32. Alpha: 'Α',
  33. alpha: 'α',
  34. Amacr: 'Ā',
  35. amacr: 'ā',
  36. amalg: '⨿',
  37. amp: '&',
  38. AMP: '&',
  39. andand: '⩕',
  40. And: '⩓',
  41. and: '∧',
  42. andd: '⩜',
  43. andslope: '⩘',
  44. andv: '⩚',
  45. ang: '∠',
  46. ange: '⦤',
  47. angle: '∠',
  48. angmsdaa: '⦨',
  49. angmsdab: '⦩',
  50. angmsdac: '⦪',
  51. angmsdad: '⦫',
  52. angmsdae: '⦬',
  53. angmsdaf: '⦭',
  54. angmsdag: '⦮',
  55. angmsdah: '⦯',
  56. angmsd: '∡',
  57. angrt: '∟',
  58. angrtvb: '⊾',
  59. angrtvbd: '⦝',
  60. angsph: '∢',
  61. angst: 'Å',
  62. angzarr: '⍼',
  63. Aogon: 'Ą',
  64. aogon: 'ą',
  65. Aopf: '𝔸',
  66. aopf: '𝕒',
  67. apacir: '⩯',
  68. ap: '≈',
  69. apE: '⩰',
  70. ape: '≊',
  71. apid: '≋',
  72. apos: '\'',
  73. ApplyFunction: '⁡',
  74. approx: '≈',
  75. approxeq: '≊',
  76. Aring: 'Å',
  77. aring: 'å',
  78. Ascr: '𝒜',
  79. ascr: '𝒶',
  80. Assign: '≔',
  81. ast: '*',
  82. asymp: '≈',
  83. asympeq: '≍',
  84. Atilde: 'Ã',
  85. atilde: 'ã',
  86. Auml: 'Ä',
  87. auml: 'ä',
  88. awconint: '∳',
  89. awint: '⨑',
  90. backcong: '≌',
  91. backepsilon: '϶',
  92. backprime: '‵',
  93. backsim: '∽',
  94. backsimeq: '⋍',
  95. Backslash: '∖',
  96. Barv: '⫧',
  97. barvee: '⊽',
  98. barwed: '⌅',
  99. Barwed: '⌆',
  100. barwedge: '⌅',
  101. bbrk: '⎵',
  102. bbrktbrk: '⎶',
  103. bcong: '≌',
  104. Bcy: 'Б',
  105. bcy: 'б',
  106. bdquo: '„',
  107. becaus: '∵',
  108. because: '∵',
  109. Because: '∵',
  110. bemptyv: '⦰',
  111. bepsi: '϶',
  112. bernou: 'ℬ',
  113. Bernoullis: 'ℬ',
  114. Beta: 'Β',
  115. beta: 'β',
  116. beth: 'ℶ',
  117. between: '≬',
  118. Bfr: '𝔅',
  119. bfr: '𝔟',
  120. bigcap: '⋂',
  121. bigcirc: '◯',
  122. bigcup: '⋃',
  123. bigodot: '⨀',
  124. bigoplus: '⨁',
  125. bigotimes: '⨂',
  126. bigsqcup: '⨆',
  127. bigstar: '★',
  128. bigtriangledown: '▽',
  129. bigtriangleup: '△',
  130. biguplus: '⨄',
  131. bigvee: '⋁',
  132. bigwedge: '⋀',
  133. bkarow: '⤍',
  134. blacklozenge: '⧫',
  135. blacksquare: '▪',
  136. blacktriangle: '▴',
  137. blacktriangledown: '▾',
  138. blacktriangleleft: '◂',
  139. blacktriangleright: '▸',
  140. blank: '␣',
  141. blk12: '▒',
  142. blk14: '░',
  143. blk34: '▓',
  144. block: '█',
  145. bne: '=',
  146. bnequiv: '≡',
  147. bNot: '⫭',
  148. bnot: '⌐',
  149. Bopf: '𝔹',
  150. bopf: '𝕓',
  151. bot: '⊥',
  152. bottom: '⊥',
  153. bowtie: '⋈',
  154. boxbox: '⧉',
  155. boxdl: '┐',
  156. boxdL: '╕',
  157. boxDl: '╖',
  158. boxDL: '╗',
  159. boxdr: '┌',
  160. boxdR: '╒',
  161. boxDr: '╓',
  162. boxDR: '╔',
  163. boxh: '─',
  164. boxH: '═',
  165. boxhd: '┬',
  166. boxHd: '╤',
  167. boxhD: '╥',
  168. boxHD: '╦',
  169. boxhu: '┴',
  170. boxHu: '╧',
  171. boxhU: '╨',
  172. boxHU: '╩',
  173. boxminus: '⊟',
  174. boxplus: '⊞',
  175. boxtimes: '⊠',
  176. boxul: '┘',
  177. boxuL: '╛',
  178. boxUl: '╜',
  179. boxUL: '╝',
  180. boxur: '└',
  181. boxuR: '╘',
  182. boxUr: '╙',
  183. boxUR: '╚',
  184. boxv: '│',
  185. boxV: '║',
  186. boxvh: '┼',
  187. boxvH: '╪',
  188. boxVh: '╫',
  189. boxVH: '╬',
  190. boxvl: '┤',
  191. boxvL: '╡',
  192. boxVl: '╢',
  193. boxVL: '╣',
  194. boxvr: '├',
  195. boxvR: '╞',
  196. boxVr: '╟',
  197. boxVR: '╠',
  198. bprime: '‵',
  199. breve: '˘',
  200. Breve: '˘',
  201. brvbar: '¦',
  202. bscr: '𝒷',
  203. Bscr: 'ℬ',
  204. bsemi: '⁏',
  205. bsim: '∽',
  206. bsime: '⋍',
  207. bsolb: '⧅',
  208. bsol: '\\',
  209. bsolhsub: '⟈',
  210. bull: '•',
  211. bullet: '•',
  212. bump: '≎',
  213. bumpE: '⪮',
  214. bumpe: '≏',
  215. Bumpeq: '≎',
  216. bumpeq: '≏',
  217. Cacute: 'Ć',
  218. cacute: 'ć',
  219. capand: '⩄',
  220. capbrcup: '⩉',
  221. capcap: '⩋',
  222. cap: '∩',
  223. Cap: '⋒',
  224. capcup: '⩇',
  225. capdot: '⩀',
  226. CapitalDifferentialD: 'ⅅ',
  227. caps: '∩',
  228. caret: '⁁',
  229. caron: 'ˇ',
  230. Cayleys: 'ℭ',
  231. ccaps: '⩍',
  232. Ccaron: 'Č',
  233. ccaron: 'č',
  234. Ccedil: 'Ç',
  235. ccedil: 'ç',
  236. Ccirc: 'Ĉ',
  237. ccirc: 'ĉ',
  238. Cconint: '∰',
  239. ccups: '⩌',
  240. ccupssm: '⩐',
  241. Cdot: 'Ċ',
  242. cdot: 'ċ',
  243. cedil: '¸',
  244. Cedilla: '¸',
  245. cemptyv: '⦲',
  246. cent: '¢',
  247. centerdot: '·',
  248. CenterDot: '·',
  249. cfr: '𝔠',
  250. Cfr: 'ℭ',
  251. CHcy: 'Ч',
  252. chcy: 'ч',
  253. check: '✓',
  254. checkmark: '✓',
  255. Chi: 'Χ',
  256. chi: 'χ',
  257. circ: 'ˆ',
  258. circeq: '≗',
  259. circlearrowleft: '↺',
  260. circlearrowright: '↻',
  261. circledast: '⊛',
  262. circledcirc: '⊚',
  263. circleddash: '⊝',
  264. CircleDot: '⊙',
  265. circledR: '®',
  266. circledS: 'Ⓢ',
  267. CircleMinus: '⊖',
  268. CirclePlus: '⊕',
  269. CircleTimes: '⊗',
  270. cir: '○',
  271. cirE: '⧃',
  272. cire: '≗',
  273. cirfnint: '⨐',
  274. cirmid: '⫯',
  275. cirscir: '⧂',
  276. ClockwiseContourIntegral: '∲',
  277. CloseCurlyDoubleQuote: '”',
  278. CloseCurlyQuote: '’',
  279. clubs: '♣',
  280. clubsuit: '♣',
  281. colon: ':',
  282. Colon: '∷',
  283. Colone: '⩴',
  284. colone: '≔',
  285. coloneq: '≔',
  286. comma: ',',
  287. commat: '@',
  288. comp: '∁',
  289. compfn: '∘',
  290. complement: '∁',
  291. complexes: 'ℂ',
  292. cong: '≅',
  293. congdot: '⩭',
  294. Congruent: '≡',
  295. conint: '∮',
  296. Conint: '∯',
  297. ContourIntegral: '∮',
  298. copf: '𝕔',
  299. Copf: 'ℂ',
  300. coprod: '∐',
  301. Coproduct: '∐',
  302. copy: '©',
  303. COPY: '©',
  304. copysr: '℗',
  305. CounterClockwiseContourIntegral: '∳',
  306. crarr: '↵',
  307. cross: '✗',
  308. Cross: '⨯',
  309. Cscr: '𝒞',
  310. cscr: '𝒸',
  311. csub: '⫏',
  312. csube: '⫑',
  313. csup: '⫐',
  314. csupe: '⫒',
  315. ctdot: '⋯',
  316. cudarrl: '⤸',
  317. cudarrr: '⤵',
  318. cuepr: '⋞',
  319. cuesc: '⋟',
  320. cularr: '↶',
  321. cularrp: '⤽',
  322. cupbrcap: '⩈',
  323. cupcap: '⩆',
  324. CupCap: '≍',
  325. cup: '∪',
  326. Cup: '⋓',
  327. cupcup: '⩊',
  328. cupdot: '⊍',
  329. cupor: '⩅',
  330. cups: '∪',
  331. curarr: '↷',
  332. curarrm: '⤼',
  333. curlyeqprec: '⋞',
  334. curlyeqsucc: '⋟',
  335. curlyvee: '⋎',
  336. curlywedge: '⋏',
  337. curren: '¤',
  338. curvearrowleft: '↶',
  339. curvearrowright: '↷',
  340. cuvee: '⋎',
  341. cuwed: '⋏',
  342. cwconint: '∲',
  343. cwint: '∱',
  344. cylcty: '⌭',
  345. dagger: '†',
  346. Dagger: '‡',
  347. daleth: 'ℸ',
  348. darr: '↓',
  349. Darr: '↡',
  350. dArr: '⇓',
  351. dash: '‐',
  352. Dashv: '⫤',
  353. dashv: '⊣',
  354. dbkarow: '⤏',
  355. dblac: '˝',
  356. Dcaron: 'Ď',
  357. dcaron: 'ď',
  358. Dcy: 'Д',
  359. dcy: 'д',
  360. ddagger: '‡',
  361. ddarr: '⇊',
  362. DD: 'ⅅ',
  363. dd: 'ⅆ',
  364. DDotrahd: '⤑',
  365. ddotseq: '⩷',
  366. deg: '°',
  367. Del: '∇',
  368. Delta: 'Δ',
  369. delta: 'δ',
  370. demptyv: '⦱',
  371. dfisht: '⥿',
  372. Dfr: '𝔇',
  373. dfr: '𝔡',
  374. dHar: '⥥',
  375. dharl: '⇃',
  376. dharr: '⇂',
  377. DiacriticalAcute: '´',
  378. DiacriticalDot: '˙',
  379. DiacriticalDoubleAcute: '˝',
  380. DiacriticalGrave: '`',
  381. DiacriticalTilde: '˜',
  382. diam: '⋄',
  383. diamond: '⋄',
  384. Diamond: '⋄',
  385. diamondsuit: '♦',
  386. diams: '♦',
  387. die: '¨',
  388. DifferentialD: 'ⅆ',
  389. digamma: 'ϝ',
  390. disin: '⋲',
  391. div: '÷',
  392. divide: '÷',
  393. divideontimes: '⋇',
  394. divonx: '⋇',
  395. DJcy: 'Ђ',
  396. djcy: 'ђ',
  397. dlcorn: '⌞',
  398. dlcrop: '⌍',
  399. dollar: '$',
  400. Dopf: '𝔻',
  401. dopf: '𝕕',
  402. Dot: '¨',
  403. dot: '˙',
  404. DotDot: '⃜',
  405. doteq: '≐',
  406. doteqdot: '≑',
  407. DotEqual: '≐',
  408. dotminus: '∸',
  409. dotplus: '∔',
  410. dotsquare: '⊡',
  411. doublebarwedge: '⌆',
  412. DoubleContourIntegral: '∯',
  413. DoubleDot: '¨',
  414. DoubleDownArrow: '⇓',
  415. DoubleLeftArrow: '⇐',
  416. DoubleLeftRightArrow: '⇔',
  417. DoubleLeftTee: '⫤',
  418. DoubleLongLeftArrow: '⟸',
  419. DoubleLongLeftRightArrow: '⟺',
  420. DoubleLongRightArrow: '⟹',
  421. DoubleRightArrow: '⇒',
  422. DoubleRightTee: '⊨',
  423. DoubleUpArrow: '⇑',
  424. DoubleUpDownArrow: '⇕',
  425. DoubleVerticalBar: '∥',
  426. DownArrowBar: '⤓',
  427. downarrow: '↓',
  428. DownArrow: '↓',
  429. Downarrow: '⇓',
  430. DownArrowUpArrow: '⇵',
  431. DownBreve: '̑',
  432. downdownarrows: '⇊',
  433. downharpoonleft: '⇃',
  434. downharpoonright: '⇂',
  435. DownLeftRightVector: '⥐',
  436. DownLeftTeeVector: '⥞',
  437. DownLeftVectorBar: '⥖',
  438. DownLeftVector: '↽',
  439. DownRightTeeVector: '⥟',
  440. DownRightVectorBar: '⥗',
  441. DownRightVector: '⇁',
  442. DownTeeArrow: '↧',
  443. DownTee: '⊤',
  444. drbkarow: '⤐',
  445. drcorn: '⌟',
  446. drcrop: '⌌',
  447. Dscr: '𝒟',
  448. dscr: '𝒹',
  449. DScy: 'Ѕ',
  450. dscy: 'ѕ',
  451. dsol: '⧶',
  452. Dstrok: 'Đ',
  453. dstrok: 'đ',
  454. dtdot: '⋱',
  455. dtri: '▿',
  456. dtrif: '▾',
  457. duarr: '⇵',
  458. duhar: '⥯',
  459. dwangle: '⦦',
  460. DZcy: 'Џ',
  461. dzcy: 'џ',
  462. dzigrarr: '⟿',
  463. Eacute: 'É',
  464. eacute: 'é',
  465. easter: '⩮',
  466. Ecaron: 'Ě',
  467. ecaron: 'ě',
  468. Ecirc: 'Ê',
  469. ecirc: 'ê',
  470. ecir: '≖',
  471. ecolon: '≕',
  472. Ecy: 'Э',
  473. ecy: 'э',
  474. eDDot: '⩷',
  475. Edot: 'Ė',
  476. edot: 'ė',
  477. eDot: '≑',
  478. ee: 'ⅇ',
  479. efDot: '≒',
  480. Efr: '𝔈',
  481. efr: '𝔢',
  482. eg: '⪚',
  483. Egrave: 'È',
  484. egrave: 'è',
  485. egs: '⪖',
  486. egsdot: '⪘',
  487. el: '⪙',
  488. Element: '∈',
  489. elinters: '⏧',
  490. ell: 'ℓ',
  491. els: '⪕',
  492. elsdot: '⪗',
  493. Emacr: 'Ē',
  494. emacr: 'ē',
  495. empty: '∅',
  496. emptyset: '∅',
  497. EmptySmallSquare: '◻',
  498. emptyv: '∅',
  499. EmptyVerySmallSquare: '▫',
  500. emsp13: ' ',
  501. emsp14: ' ',
  502. emsp: ' ',
  503. ENG: 'Ŋ',
  504. eng: 'ŋ',
  505. ensp: ' ',
  506. Eogon: 'Ę',
  507. eogon: 'ę',
  508. Eopf: '𝔼',
  509. eopf: '𝕖',
  510. epar: '⋕',
  511. eparsl: '⧣',
  512. eplus: '⩱',
  513. epsi: 'ε',
  514. Epsilon: 'Ε',
  515. epsilon: 'ε',
  516. epsiv: 'ϵ',
  517. eqcirc: '≖',
  518. eqcolon: '≕',
  519. eqsim: '≂',
  520. eqslantgtr: '⪖',
  521. eqslantless: '⪕',
  522. Equal: '⩵',
  523. equals: '=',
  524. EqualTilde: '≂',
  525. equest: '≟',
  526. Equilibrium: '⇌',
  527. equiv: '≡',
  528. equivDD: '⩸',
  529. eqvparsl: '⧥',
  530. erarr: '⥱',
  531. erDot: '≓',
  532. escr: 'ℯ',
  533. Escr: 'ℰ',
  534. esdot: '≐',
  535. Esim: '⩳',
  536. esim: '≂',
  537. Eta: 'Η',
  538. eta: 'η',
  539. ETH: 'Ð',
  540. eth: 'ð',
  541. Euml: 'Ë',
  542. euml: 'ë',
  543. euro: '€',
  544. excl: '!',
  545. exist: '∃',
  546. Exists: '∃',
  547. expectation: 'ℰ',
  548. exponentiale: 'ⅇ',
  549. ExponentialE: 'ⅇ',
  550. fallingdotseq: '≒',
  551. Fcy: 'Ф',
  552. fcy: 'ф',
  553. female: '♀',
  554. ffilig: 'ffi',
  555. fflig: 'ff',
  556. ffllig: 'ffl',
  557. Ffr: '𝔉',
  558. ffr: '𝔣',
  559. filig: 'fi',
  560. FilledSmallSquare: '◼',
  561. FilledVerySmallSquare: '▪',
  562. fjlig: 'f',
  563. flat: '♭',
  564. fllig: 'fl',
  565. fltns: '▱',
  566. fnof: 'ƒ',
  567. Fopf: '𝔽',
  568. fopf: '𝕗',
  569. forall: '∀',
  570. ForAll: '∀',
  571. fork: '⋔',
  572. forkv: '⫙',
  573. Fouriertrf: 'ℱ',
  574. fpartint: '⨍',
  575. frac12: '½',
  576. frac13: '⅓',
  577. frac14: '¼',
  578. frac15: '⅕',
  579. frac16: '⅙',
  580. frac18: '⅛',
  581. frac23: '⅔',
  582. frac25: '⅖',
  583. frac34: '¾',
  584. frac35: '⅗',
  585. frac38: '⅜',
  586. frac45: '⅘',
  587. frac56: '⅚',
  588. frac58: '⅝',
  589. frac78: '⅞',
  590. frasl: '⁄',
  591. frown: '⌢',
  592. fscr: '𝒻',
  593. Fscr: 'ℱ',
  594. gacute: 'ǵ',
  595. Gamma: 'Γ',
  596. gamma: 'γ',
  597. Gammad: 'Ϝ',
  598. gammad: 'ϝ',
  599. gap: '⪆',
  600. Gbreve: 'Ğ',
  601. gbreve: 'ğ',
  602. Gcedil: 'Ģ',
  603. Gcirc: 'Ĝ',
  604. gcirc: 'ĝ',
  605. Gcy: 'Г',
  606. gcy: 'г',
  607. Gdot: 'Ġ',
  608. gdot: 'ġ',
  609. ge: '≥',
  610. gE: '≧',
  611. gEl: '⪌',
  612. gel: '⋛',
  613. geq: '≥',
  614. geqq: '≧',
  615. geqslant: '⩾',
  616. gescc: '⪩',
  617. ges: '⩾',
  618. gesdot: '⪀',
  619. gesdoto: '⪂',
  620. gesdotol: '⪄',
  621. gesl: '⋛',
  622. gesles: '⪔',
  623. Gfr: '𝔊',
  624. gfr: '𝔤',
  625. gg: '≫',
  626. Gg: '⋙',
  627. ggg: '⋙',
  628. gimel: 'ℷ',
  629. GJcy: 'Ѓ',
  630. gjcy: 'ѓ',
  631. gla: '⪥',
  632. gl: '≷',
  633. glE: '⪒',
  634. glj: '⪤',
  635. gnap: '⪊',
  636. gnapprox: '⪊',
  637. gne: '⪈',
  638. gnE: '≩',
  639. gneq: '⪈',
  640. gneqq: '≩',
  641. gnsim: '⋧',
  642. Gopf: '𝔾',
  643. gopf: '𝕘',
  644. grave: '`',
  645. GreaterEqual: '≥',
  646. GreaterEqualLess: '⋛',
  647. GreaterFullEqual: '≧',
  648. GreaterGreater: '⪢',
  649. GreaterLess: '≷',
  650. GreaterSlantEqual: '⩾',
  651. GreaterTilde: '≳',
  652. Gscr: '𝒢',
  653. gscr: 'ℊ',
  654. gsim: '≳',
  655. gsime: '⪎',
  656. gsiml: '⪐',
  657. gtcc: '⪧',
  658. gtcir: '⩺',
  659. gt: '>',
  660. GT: '>',
  661. Gt: '≫',
  662. gtdot: '⋗',
  663. gtlPar: '⦕',
  664. gtquest: '⩼',
  665. gtrapprox: '⪆',
  666. gtrarr: '⥸',
  667. gtrdot: '⋗',
  668. gtreqless: '⋛',
  669. gtreqqless: '⪌',
  670. gtrless: '≷',
  671. gtrsim: '≳',
  672. gvertneqq: '≩',
  673. gvnE: '≩',
  674. Hacek: 'ˇ',
  675. hairsp: ' ',
  676. half: '½',
  677. hamilt: 'ℋ',
  678. HARDcy: 'Ъ',
  679. hardcy: 'ъ',
  680. harrcir: '⥈',
  681. harr: '↔',
  682. hArr: '⇔',
  683. harrw: '↭',
  684. Hat: '^',
  685. hbar: 'ℏ',
  686. Hcirc: 'Ĥ',
  687. hcirc: 'ĥ',
  688. hearts: '♥',
  689. heartsuit: '♥',
  690. hellip: '…',
  691. hercon: '⊹',
  692. hfr: '𝔥',
  693. Hfr: 'ℌ',
  694. HilbertSpace: 'ℋ',
  695. hksearow: '⤥',
  696. hkswarow: '⤦',
  697. hoarr: '⇿',
  698. homtht: '∻',
  699. hookleftarrow: '↩',
  700. hookrightarrow: '↪',
  701. hopf: '𝕙',
  702. Hopf: 'ℍ',
  703. horbar: '―',
  704. HorizontalLine: '─',
  705. hscr: '𝒽',
  706. Hscr: 'ℋ',
  707. hslash: 'ℏ',
  708. Hstrok: 'Ħ',
  709. hstrok: 'ħ',
  710. HumpDownHump: '≎',
  711. HumpEqual: '≏',
  712. hybull: '⁃',
  713. hyphen: '‐',
  714. Iacute: 'Í',
  715. iacute: 'í',
  716. ic: '⁣',
  717. Icirc: 'Î',
  718. icirc: 'î',
  719. Icy: 'И',
  720. icy: 'и',
  721. Idot: 'İ',
  722. IEcy: 'Е',
  723. iecy: 'е',
  724. iexcl: '¡',
  725. iff: '⇔',
  726. ifr: '𝔦',
  727. Ifr: 'ℑ',
  728. Igrave: 'Ì',
  729. igrave: 'ì',
  730. ii: 'ⅈ',
  731. iiiint: '⨌',
  732. iiint: '∭',
  733. iinfin: '⧜',
  734. iiota: '℩',
  735. IJlig: 'IJ',
  736. ijlig: 'ij',
  737. Imacr: 'Ī',
  738. imacr: 'ī',
  739. image: 'ℑ',
  740. ImaginaryI: 'ⅈ',
  741. imagline: 'ℐ',
  742. imagpart: 'ℑ',
  743. imath: 'ı',
  744. Im: 'ℑ',
  745. imof: '⊷',
  746. imped: 'Ƶ',
  747. Implies: '⇒',
  748. incare: '℅',
  749. in: '∈',
  750. infin: '∞',
  751. infintie: '⧝',
  752. inodot: 'ı',
  753. intcal: '⊺',
  754. int: '∫',
  755. Int: '∬',
  756. integers: 'ℤ',
  757. Integral: '∫',
  758. intercal: '⊺',
  759. Intersection: '⋂',
  760. intlarhk: '⨗',
  761. intprod: '⨼',
  762. InvisibleComma: '⁣',
  763. InvisibleTimes: '⁢',
  764. IOcy: 'Ё',
  765. iocy: 'ё',
  766. Iogon: 'Į',
  767. iogon: 'į',
  768. Iopf: '𝕀',
  769. iopf: '𝕚',
  770. Iota: 'Ι',
  771. iota: 'ι',
  772. iprod: '⨼',
  773. iquest: '¿',
  774. iscr: '𝒾',
  775. Iscr: 'ℐ',
  776. isin: '∈',
  777. isindot: '⋵',
  778. isinE: '⋹',
  779. isins: '⋴',
  780. isinsv: '⋳',
  781. isinv: '∈',
  782. it: '⁢',
  783. Itilde: 'Ĩ',
  784. itilde: 'ĩ',
  785. Iukcy: 'І',
  786. iukcy: 'і',
  787. Iuml: 'Ï',
  788. iuml: 'ï',
  789. Jcirc: 'Ĵ',
  790. jcirc: 'ĵ',
  791. Jcy: 'Й',
  792. jcy: 'й',
  793. Jfr: '𝔍',
  794. jfr: '𝔧',
  795. jmath: 'ȷ',
  796. Jopf: '𝕁',
  797. jopf: '𝕛',
  798. Jscr: '𝒥',
  799. jscr: '𝒿',
  800. Jsercy: 'Ј',
  801. jsercy: 'ј',
  802. Jukcy: 'Є',
  803. jukcy: 'є',
  804. Kappa: 'Κ',
  805. kappa: 'κ',
  806. kappav: 'ϰ',
  807. Kcedil: 'Ķ',
  808. kcedil: 'ķ',
  809. Kcy: 'К',
  810. kcy: 'к',
  811. Kfr: '𝔎',
  812. kfr: '𝔨',
  813. kgreen: 'ĸ',
  814. KHcy: 'Х',
  815. khcy: 'х',
  816. KJcy: 'Ќ',
  817. kjcy: 'ќ',
  818. Kopf: '𝕂',
  819. kopf: '𝕜',
  820. Kscr: '𝒦',
  821. kscr: '𝓀',
  822. lAarr: '⇚',
  823. Lacute: 'Ĺ',
  824. lacute: 'ĺ',
  825. laemptyv: '⦴',
  826. lagran: 'ℒ',
  827. Lambda: 'Λ',
  828. lambda: 'λ',
  829. lang: '⟨',
  830. Lang: '⟪',
  831. langd: '⦑',
  832. langle: '⟨',
  833. lap: '⪅',
  834. Laplacetrf: 'ℒ',
  835. laquo: '«',
  836. larrb: '⇤',
  837. larrbfs: '⤟',
  838. larr: '←',
  839. Larr: '↞',
  840. lArr: '⇐',
  841. larrfs: '⤝',
  842. larrhk: '↩',
  843. larrlp: '↫',
  844. larrpl: '⤹',
  845. larrsim: '⥳',
  846. larrtl: '↢',
  847. latail: '⤙',
  848. lAtail: '⤛',
  849. lat: '⪫',
  850. late: '⪭',
  851. lates: '⪭',
  852. lbarr: '⤌',
  853. lBarr: '⤎',
  854. lbbrk: '❲',
  855. lbrace: '{',
  856. lbrack: '[',
  857. lbrke: '⦋',
  858. lbrksld: '⦏',
  859. lbrkslu: '⦍',
  860. Lcaron: 'Ľ',
  861. lcaron: 'ľ',
  862. Lcedil: 'Ļ',
  863. lcedil: 'ļ',
  864. lceil: '⌈',
  865. lcub: '{',
  866. Lcy: 'Л',
  867. lcy: 'л',
  868. ldca: '⤶',
  869. ldquo: '“',
  870. ldquor: '„',
  871. ldrdhar: '⥧',
  872. ldrushar: '⥋',
  873. ldsh: '↲',
  874. le: '≤',
  875. lE: '≦',
  876. LeftAngleBracket: '⟨',
  877. LeftArrowBar: '⇤',
  878. leftarrow: '←',
  879. LeftArrow: '←',
  880. Leftarrow: '⇐',
  881. LeftArrowRightArrow: '⇆',
  882. leftarrowtail: '↢',
  883. LeftCeiling: '⌈',
  884. LeftDoubleBracket: '⟦',
  885. LeftDownTeeVector: '⥡',
  886. LeftDownVectorBar: '⥙',
  887. LeftDownVector: '⇃',
  888. LeftFloor: '⌊',
  889. leftharpoondown: '↽',
  890. leftharpoonup: '↼',
  891. leftleftarrows: '⇇',
  892. leftrightarrow: '↔',
  893. LeftRightArrow: '↔',
  894. Leftrightarrow: '⇔',
  895. leftrightarrows: '⇆',
  896. leftrightharpoons: '⇋',
  897. leftrightsquigarrow: '↭',
  898. LeftRightVector: '⥎',
  899. LeftTeeArrow: '↤',
  900. LeftTee: '⊣',
  901. LeftTeeVector: '⥚',
  902. leftthreetimes: '⋋',
  903. LeftTriangleBar: '⧏',
  904. LeftTriangle: '⊲',
  905. LeftTriangleEqual: '⊴',
  906. LeftUpDownVector: '⥑',
  907. LeftUpTeeVector: '⥠',
  908. LeftUpVectorBar: '⥘',
  909. LeftUpVector: '↿',
  910. LeftVectorBar: '⥒',
  911. LeftVector: '↼',
  912. lEg: '⪋',
  913. leg: '⋚',
  914. leq: '≤',
  915. leqq: '≦',
  916. leqslant: '⩽',
  917. lescc: '⪨',
  918. les: '⩽',
  919. lesdot: '⩿',
  920. lesdoto: '⪁',
  921. lesdotor: '⪃',
  922. lesg: '⋚',
  923. lesges: '⪓',
  924. lessapprox: '⪅',
  925. lessdot: '⋖',
  926. lesseqgtr: '⋚',
  927. lesseqqgtr: '⪋',
  928. LessEqualGreater: '⋚',
  929. LessFullEqual: '≦',
  930. LessGreater: '≶',
  931. lessgtr: '≶',
  932. LessLess: '⪡',
  933. lesssim: '≲',
  934. LessSlantEqual: '⩽',
  935. LessTilde: '≲',
  936. lfisht: '⥼',
  937. lfloor: '⌊',
  938. Lfr: '𝔏',
  939. lfr: '𝔩',
  940. lg: '≶',
  941. lgE: '⪑',
  942. lHar: '⥢',
  943. lhard: '↽',
  944. lharu: '↼',
  945. lharul: '⥪',
  946. lhblk: '▄',
  947. LJcy: 'Љ',
  948. ljcy: 'љ',
  949. llarr: '⇇',
  950. ll: '≪',
  951. Ll: '⋘',
  952. llcorner: '⌞',
  953. Lleftarrow: '⇚',
  954. llhard: '⥫',
  955. lltri: '◺',
  956. Lmidot: 'Ŀ',
  957. lmidot: 'ŀ',
  958. lmoustache: '⎰',
  959. lmoust: '⎰',
  960. lnap: '⪉',
  961. lnapprox: '⪉',
  962. lne: '⪇',
  963. lnE: '≨',
  964. lneq: '⪇',
  965. lneqq: '≨',
  966. lnsim: '⋦',
  967. loang: '⟬',
  968. loarr: '⇽',
  969. lobrk: '⟦',
  970. longleftarrow: '⟵',
  971. LongLeftArrow: '⟵',
  972. Longleftarrow: '⟸',
  973. longleftrightarrow: '⟷',
  974. LongLeftRightArrow: '⟷',
  975. Longleftrightarrow: '⟺',
  976. longmapsto: '⟼',
  977. longrightarrow: '⟶',
  978. LongRightArrow: '⟶',
  979. Longrightarrow: '⟹',
  980. looparrowleft: '↫',
  981. looparrowright: '↬',
  982. lopar: '⦅',
  983. Lopf: '𝕃',
  984. lopf: '𝕝',
  985. loplus: '⨭',
  986. lotimes: '⨴',
  987. lowast: '∗',
  988. lowbar: '_',
  989. LowerLeftArrow: '↙',
  990. LowerRightArrow: '↘',
  991. loz: '◊',
  992. lozenge: '◊',
  993. lozf: '⧫',
  994. lpar: '(',
  995. lparlt: '⦓',
  996. lrarr: '⇆',
  997. lrcorner: '⌟',
  998. lrhar: '⇋',
  999. lrhard: '⥭',
  1000. lrm: '‎',
  1001. lrtri: '⊿',
  1002. lsaquo: '‹',
  1003. lscr: '𝓁',
  1004. Lscr: 'ℒ',
  1005. lsh: '↰',
  1006. Lsh: '↰',
  1007. lsim: '≲',
  1008. lsime: '⪍',
  1009. lsimg: '⪏',
  1010. lsqb: '[',
  1011. lsquo: '‘',
  1012. lsquor: '‚',
  1013. Lstrok: 'Ł',
  1014. lstrok: 'ł',
  1015. ltcc: '⪦',
  1016. ltcir: '⩹',
  1017. lt: '<',
  1018. LT: '<',
  1019. Lt: '≪',
  1020. ltdot: '⋖',
  1021. lthree: '⋋',
  1022. ltimes: '⋉',
  1023. ltlarr: '⥶',
  1024. ltquest: '⩻',
  1025. ltri: '◃',
  1026. ltrie: '⊴',
  1027. ltrif: '◂',
  1028. ltrPar: '⦖',
  1029. lurdshar: '⥊',
  1030. luruhar: '⥦',
  1031. lvertneqq: '≨',
  1032. lvnE: '≨',
  1033. macr: '¯',
  1034. male: '♂',
  1035. malt: '✠',
  1036. maltese: '✠',
  1037. Map: '⤅',
  1038. map: '↦',
  1039. mapsto: '↦',
  1040. mapstodown: '↧',
  1041. mapstoleft: '↤',
  1042. mapstoup: '↥',
  1043. marker: '▮',
  1044. mcomma: '⨩',
  1045. Mcy: 'М',
  1046. mcy: 'м',
  1047. mdash: '—',
  1048. mDDot: '∺',
  1049. measuredangle: '∡',
  1050. MediumSpace: ' ',
  1051. Mellintrf: 'ℳ',
  1052. Mfr: '𝔐',
  1053. mfr: '𝔪',
  1054. mho: '℧',
  1055. micro: 'µ',
  1056. midast: '*',
  1057. midcir: '⫰',
  1058. mid: '∣',
  1059. middot: '·',
  1060. minusb: '⊟',
  1061. minus: '−',
  1062. minusd: '∸',
  1063. minusdu: '⨪',
  1064. MinusPlus: '∓',
  1065. mlcp: '⫛',
  1066. mldr: '…',
  1067. mnplus: '∓',
  1068. models: '⊧',
  1069. Mopf: '𝕄',
  1070. mopf: '𝕞',
  1071. mp: '∓',
  1072. mscr: '𝓂',
  1073. Mscr: 'ℳ',
  1074. mstpos: '∾',
  1075. Mu: 'Μ',
  1076. mu: 'μ',
  1077. multimap: '⊸',
  1078. mumap: '⊸',
  1079. nabla: '∇',
  1080. Nacute: 'Ń',
  1081. nacute: 'ń',
  1082. nang: '∠',
  1083. nap: '≉',
  1084. napE: '⩰',
  1085. napid: '≋',
  1086. napos: 'ʼn',
  1087. napprox: '≉',
  1088. natural: '♮',
  1089. naturals: 'ℕ',
  1090. natur: '♮',
  1091. nbsp: ' ',
  1092. nbump: '≎',
  1093. nbumpe: '≏',
  1094. ncap: '⩃',
  1095. Ncaron: 'Ň',
  1096. ncaron: 'ň',
  1097. Ncedil: 'Ņ',
  1098. ncedil: 'ņ',
  1099. ncong: '≇',
  1100. ncongdot: '⩭',
  1101. ncup: '⩂',
  1102. Ncy: 'Н',
  1103. ncy: 'н',
  1104. ndash: '–',
  1105. nearhk: '⤤',
  1106. nearr: '↗',
  1107. neArr: '⇗',
  1108. nearrow: '↗',
  1109. ne: '≠',
  1110. nedot: '≐',
  1111. NegativeMediumSpace: '​',
  1112. NegativeThickSpace: '​',
  1113. NegativeThinSpace: '​',
  1114. NegativeVeryThinSpace: '​',
  1115. nequiv: '≢',
  1116. nesear: '⤨',
  1117. nesim: '≂',
  1118. NestedGreaterGreater: '≫',
  1119. NestedLessLess: '≪',
  1120. NewLine: '\n',
  1121. nexist: '∄',
  1122. nexists: '∄',
  1123. Nfr: '𝔑',
  1124. nfr: '𝔫',
  1125. ngE: '≧',
  1126. nge: '≱',
  1127. ngeq: '≱',
  1128. ngeqq: '≧',
  1129. ngeqslant: '⩾',
  1130. nges: '⩾',
  1131. nGg: '⋙',
  1132. ngsim: '≵',
  1133. nGt: '≫',
  1134. ngt: '≯',
  1135. ngtr: '≯',
  1136. nGtv: '≫',
  1137. nharr: '↮',
  1138. nhArr: '⇎',
  1139. nhpar: '⫲',
  1140. ni: '∋',
  1141. nis: '⋼',
  1142. nisd: '⋺',
  1143. niv: '∋',
  1144. NJcy: 'Њ',
  1145. njcy: 'њ',
  1146. nlarr: '↚',
  1147. nlArr: '⇍',
  1148. nldr: '‥',
  1149. nlE: '≦',
  1150. nle: '≰',
  1151. nleftarrow: '↚',
  1152. nLeftarrow: '⇍',
  1153. nleftrightarrow: '↮',
  1154. nLeftrightarrow: '⇎',
  1155. nleq: '≰',
  1156. nleqq: '≦',
  1157. nleqslant: '⩽',
  1158. nles: '⩽',
  1159. nless: '≮',
  1160. nLl: '⋘',
  1161. nlsim: '≴',
  1162. nLt: '≪',
  1163. nlt: '≮',
  1164. nltri: '⋪',
  1165. nltrie: '⋬',
  1166. nLtv: '≪',
  1167. nmid: '∤',
  1168. NoBreak: '⁠',
  1169. NonBreakingSpace: ' ',
  1170. nopf: '𝕟',
  1171. Nopf: 'ℕ',
  1172. Not: '⫬',
  1173. not: '¬',
  1174. NotCongruent: '≢',
  1175. NotCupCap: '≭',
  1176. NotDoubleVerticalBar: '∦',
  1177. NotElement: '∉',
  1178. NotEqual: '≠',
  1179. NotEqualTilde: '≂',
  1180. NotExists: '∄',
  1181. NotGreater: '≯',
  1182. NotGreaterEqual: '≱',
  1183. NotGreaterFullEqual: '≧',
  1184. NotGreaterGreater: '≫',
  1185. NotGreaterLess: '≹',
  1186. NotGreaterSlantEqual: '⩾',
  1187. NotGreaterTilde: '≵',
  1188. NotHumpDownHump: '≎',
  1189. NotHumpEqual: '≏',
  1190. notin: '∉',
  1191. notindot: '⋵',
  1192. notinE: '⋹',
  1193. notinva: '∉',
  1194. notinvb: '⋷',
  1195. notinvc: '⋶',
  1196. NotLeftTriangleBar: '⧏',
  1197. NotLeftTriangle: '⋪',
  1198. NotLeftTriangleEqual: '⋬',
  1199. NotLess: '≮',
  1200. NotLessEqual: '≰',
  1201. NotLessGreater: '≸',
  1202. NotLessLess: '≪',
  1203. NotLessSlantEqual: '⩽',
  1204. NotLessTilde: '≴',
  1205. NotNestedGreaterGreater: '⪢',
  1206. NotNestedLessLess: '⪡',
  1207. notni: '∌',
  1208. notniva: '∌',
  1209. notnivb: '⋾',
  1210. notnivc: '⋽',
  1211. NotPrecedes: '⊀',
  1212. NotPrecedesEqual: '⪯',
  1213. NotPrecedesSlantEqual: '⋠',
  1214. NotReverseElement: '∌',
  1215. NotRightTriangleBar: '⧐',
  1216. NotRightTriangle: '⋫',
  1217. NotRightTriangleEqual: '⋭',
  1218. NotSquareSubset: '⊏',
  1219. NotSquareSubsetEqual: '⋢',
  1220. NotSquareSuperset: '⊐',
  1221. NotSquareSupersetEqual: '⋣',
  1222. NotSubset: '⊂',
  1223. NotSubsetEqual: '⊈',
  1224. NotSucceeds: '⊁',
  1225. NotSucceedsEqual: '⪰',
  1226. NotSucceedsSlantEqual: '⋡',
  1227. NotSucceedsTilde: '≿',
  1228. NotSuperset: '⊃',
  1229. NotSupersetEqual: '⊉',
  1230. NotTilde: '≁',
  1231. NotTildeEqual: '≄',
  1232. NotTildeFullEqual: '≇',
  1233. NotTildeTilde: '≉',
  1234. NotVerticalBar: '∤',
  1235. nparallel: '∦',
  1236. npar: '∦',
  1237. nparsl: '⫽',
  1238. npart: '∂',
  1239. npolint: '⨔',
  1240. npr: '⊀',
  1241. nprcue: '⋠',
  1242. nprec: '⊀',
  1243. npreceq: '⪯',
  1244. npre: '⪯',
  1245. nrarrc: '⤳',
  1246. nrarr: '↛',
  1247. nrArr: '⇏',
  1248. nrarrw: '↝',
  1249. nrightarrow: '↛',
  1250. nRightarrow: '⇏',
  1251. nrtri: '⋫',
  1252. nrtrie: '⋭',
  1253. nsc: '⊁',
  1254. nsccue: '⋡',
  1255. nsce: '⪰',
  1256. Nscr: '𝒩',
  1257. nscr: '𝓃',
  1258. nshortmid: '∤',
  1259. nshortparallel: '∦',
  1260. nsim: '≁',
  1261. nsime: '≄',
  1262. nsimeq: '≄',
  1263. nsmid: '∤',
  1264. nspar: '∦',
  1265. nsqsube: '⋢',
  1266. nsqsupe: '⋣',
  1267. nsub: '⊄',
  1268. nsubE: '⫅',
  1269. nsube: '⊈',
  1270. nsubset: '⊂',
  1271. nsubseteq: '⊈',
  1272. nsubseteqq: '⫅',
  1273. nsucc: '⊁',
  1274. nsucceq: '⪰',
  1275. nsup: '⊅',
  1276. nsupE: '⫆',
  1277. nsupe: '⊉',
  1278. nsupset: '⊃',
  1279. nsupseteq: '⊉',
  1280. nsupseteqq: '⫆',
  1281. ntgl: '≹',
  1282. Ntilde: 'Ñ',
  1283. ntilde: 'ñ',
  1284. ntlg: '≸',
  1285. ntriangleleft: '⋪',
  1286. ntrianglelefteq: '⋬',
  1287. ntriangleright: '⋫',
  1288. ntrianglerighteq: '⋭',
  1289. Nu: 'Ν',
  1290. nu: 'ν',
  1291. num: '#',
  1292. numero: '№',
  1293. numsp: ' ',
  1294. nvap: '≍',
  1295. nvdash: '⊬',
  1296. nvDash: '⊭',
  1297. nVdash: '⊮',
  1298. nVDash: '⊯',
  1299. nvge: '≥',
  1300. nvgt: '>',
  1301. nvHarr: '⤄',
  1302. nvinfin: '⧞',
  1303. nvlArr: '⤂',
  1304. nvle: '≤',
  1305. nvlt: '>',
  1306. nvltrie: '⊴',
  1307. nvrArr: '⤃',
  1308. nvrtrie: '⊵',
  1309. nvsim: '∼',
  1310. nwarhk: '⤣',
  1311. nwarr: '↖',
  1312. nwArr: '⇖',
  1313. nwarrow: '↖',
  1314. nwnear: '⤧',
  1315. Oacute: 'Ó',
  1316. oacute: 'ó',
  1317. oast: '⊛',
  1318. Ocirc: 'Ô',
  1319. ocirc: 'ô',
  1320. ocir: '⊚',
  1321. Ocy: 'О',
  1322. ocy: 'о',
  1323. odash: '⊝',
  1324. Odblac: 'Ő',
  1325. odblac: 'ő',
  1326. odiv: '⨸',
  1327. odot: '⊙',
  1328. odsold: '⦼',
  1329. OElig: 'Œ',
  1330. oelig: 'œ',
  1331. ofcir: '⦿',
  1332. Ofr: '𝔒',
  1333. ofr: '𝔬',
  1334. ogon: '˛',
  1335. Ograve: 'Ò',
  1336. ograve: 'ò',
  1337. ogt: '⧁',
  1338. ohbar: '⦵',
  1339. ohm: 'Ω',
  1340. oint: '∮',
  1341. olarr: '↺',
  1342. olcir: '⦾',
  1343. olcross: '⦻',
  1344. oline: '‾',
  1345. olt: '⧀',
  1346. Omacr: 'Ō',
  1347. omacr: 'ō',
  1348. Omega: 'Ω',
  1349. omega: 'ω',
  1350. Omicron: 'Ο',
  1351. omicron: 'ο',
  1352. omid: '⦶',
  1353. ominus: '⊖',
  1354. Oopf: '𝕆',
  1355. oopf: '𝕠',
  1356. opar: '⦷',
  1357. OpenCurlyDoubleQuote: '“',
  1358. OpenCurlyQuote: '‘',
  1359. operp: '⦹',
  1360. oplus: '⊕',
  1361. orarr: '↻',
  1362. Or: '⩔',
  1363. or: '∨',
  1364. ord: '⩝',
  1365. order: 'ℴ',
  1366. orderof: 'ℴ',
  1367. ordf: 'ª',
  1368. ordm: 'º',
  1369. origof: '⊶',
  1370. oror: '⩖',
  1371. orslope: '⩗',
  1372. orv: '⩛',
  1373. oS: 'Ⓢ',
  1374. Oscr: '𝒪',
  1375. oscr: 'ℴ',
  1376. Oslash: 'Ø',
  1377. oslash: 'ø',
  1378. osol: '⊘',
  1379. Otilde: 'Õ',
  1380. otilde: 'õ',
  1381. otimesas: '⨶',
  1382. Otimes: '⨷',
  1383. otimes: '⊗',
  1384. Ouml: 'Ö',
  1385. ouml: 'ö',
  1386. ovbar: '⌽',
  1387. OverBar: '‾',
  1388. OverBrace: '⏞',
  1389. OverBracket: '⎴',
  1390. OverParenthesis: '⏜',
  1391. para: '¶',
  1392. parallel: '∥',
  1393. par: '∥',
  1394. parsim: '⫳',
  1395. parsl: '⫽',
  1396. part: '∂',
  1397. PartialD: '∂',
  1398. Pcy: 'П',
  1399. pcy: 'п',
  1400. percnt: '%',
  1401. period: '.',
  1402. permil: '‰',
  1403. perp: '⊥',
  1404. pertenk: '‱',
  1405. Pfr: '𝔓',
  1406. pfr: '𝔭',
  1407. Phi: 'Φ',
  1408. phi: 'φ',
  1409. phiv: 'ϕ',
  1410. phmmat: 'ℳ',
  1411. phone: '☎',
  1412. Pi: 'Π',
  1413. pi: 'π',
  1414. pitchfork: '⋔',
  1415. piv: 'ϖ',
  1416. planck: 'ℏ',
  1417. planckh: 'ℎ',
  1418. plankv: 'ℏ',
  1419. plusacir: '⨣',
  1420. plusb: '⊞',
  1421. pluscir: '⨢',
  1422. plus: '+',
  1423. plusdo: '∔',
  1424. plusdu: '⨥',
  1425. pluse: '⩲',
  1426. PlusMinus: '±',
  1427. plusmn: '±',
  1428. plussim: '⨦',
  1429. plustwo: '⨧',
  1430. pm: '±',
  1431. Poincareplane: 'ℌ',
  1432. pointint: '⨕',
  1433. popf: '𝕡',
  1434. Popf: 'ℙ',
  1435. pound: '£',
  1436. prap: '⪷',
  1437. Pr: '⪻',
  1438. pr: '≺',
  1439. prcue: '≼',
  1440. precapprox: '⪷',
  1441. prec: '≺',
  1442. preccurlyeq: '≼',
  1443. Precedes: '≺',
  1444. PrecedesEqual: '⪯',
  1445. PrecedesSlantEqual: '≼',
  1446. PrecedesTilde: '≾',
  1447. preceq: '⪯',
  1448. precnapprox: '⪹',
  1449. precneqq: '⪵',
  1450. precnsim: '⋨',
  1451. pre: '⪯',
  1452. prE: '⪳',
  1453. precsim: '≾',
  1454. prime: '′',
  1455. Prime: '″',
  1456. primes: 'ℙ',
  1457. prnap: '⪹',
  1458. prnE: '⪵',
  1459. prnsim: '⋨',
  1460. prod: '∏',
  1461. Product: '∏',
  1462. profalar: '⌮',
  1463. profline: '⌒',
  1464. profsurf: '⌓',
  1465. prop: '∝',
  1466. Proportional: '∝',
  1467. Proportion: '∷',
  1468. propto: '∝',
  1469. prsim: '≾',
  1470. prurel: '⊰',
  1471. Pscr: '𝒫',
  1472. pscr: '𝓅',
  1473. Psi: 'Ψ',
  1474. psi: 'ψ',
  1475. puncsp: ' ',
  1476. Qfr: '𝔔',
  1477. qfr: '𝔮',
  1478. qint: '⨌',
  1479. qopf: '𝕢',
  1480. Qopf: 'ℚ',
  1481. qprime: '⁗',
  1482. Qscr: '𝒬',
  1483. qscr: '𝓆',
  1484. quaternions: 'ℍ',
  1485. quatint: '⨖',
  1486. quest: '?',
  1487. questeq: '≟',
  1488. quot: '"',
  1489. QUOT: '"',
  1490. rAarr: '⇛',
  1491. race: '∽',
  1492. Racute: 'Ŕ',
  1493. racute: 'ŕ',
  1494. radic: '√',
  1495. raemptyv: '⦳',
  1496. rang: '⟩',
  1497. Rang: '⟫',
  1498. rangd: '⦒',
  1499. range: '⦥',
  1500. rangle: '⟩',
  1501. raquo: '»',
  1502. rarrap: '⥵',
  1503. rarrb: '⇥',
  1504. rarrbfs: '⤠',
  1505. rarrc: '⤳',
  1506. rarr: '→',
  1507. Rarr: '↠',
  1508. rArr: '⇒',
  1509. rarrfs: '⤞',
  1510. rarrhk: '↪',
  1511. rarrlp: '↬',
  1512. rarrpl: '⥅',
  1513. rarrsim: '⥴',
  1514. Rarrtl: '⤖',
  1515. rarrtl: '↣',
  1516. rarrw: '↝',
  1517. ratail: '⤚',
  1518. rAtail: '⤜',
  1519. ratio: '∶',
  1520. rationals: 'ℚ',
  1521. rbarr: '⤍',
  1522. rBarr: '⤏',
  1523. RBarr: '⤐',
  1524. rbbrk: '❳',
  1525. rbrace: '}',
  1526. rbrack: ']',
  1527. rbrke: '⦌',
  1528. rbrksld: '⦎',
  1529. rbrkslu: '⦐',
  1530. Rcaron: 'Ř',
  1531. rcaron: 'ř',
  1532. Rcedil: 'Ŗ',
  1533. rcedil: 'ŗ',
  1534. rceil: '⌉',
  1535. rcub: '}',
  1536. Rcy: 'Р',
  1537. rcy: 'р',
  1538. rdca: '⤷',
  1539. rdldhar: '⥩',
  1540. rdquo: '”',
  1541. rdquor: '”',
  1542. rdsh: '↳',
  1543. real: 'ℜ',
  1544. realine: 'ℛ',
  1545. realpart: 'ℜ',
  1546. reals: 'ℝ',
  1547. Re: 'ℜ',
  1548. rect: '▭',
  1549. reg: '®',
  1550. REG: '®',
  1551. ReverseElement: '∋',
  1552. ReverseEquilibrium: '⇋',
  1553. ReverseUpEquilibrium: '⥯',
  1554. rfisht: '⥽',
  1555. rfloor: '⌋',
  1556. rfr: '𝔯',
  1557. Rfr: 'ℜ',
  1558. rHar: '⥤',
  1559. rhard: '⇁',
  1560. rharu: '⇀',
  1561. rharul: '⥬',
  1562. Rho: 'Ρ',
  1563. rho: 'ρ',
  1564. rhov: 'ϱ',
  1565. RightAngleBracket: '⟩',
  1566. RightArrowBar: '⇥',
  1567. rightarrow: '→',
  1568. RightArrow: '→',
  1569. Rightarrow: '⇒',
  1570. RightArrowLeftArrow: '⇄',
  1571. rightarrowtail: '↣',
  1572. RightCeiling: '⌉',
  1573. RightDoubleBracket: '⟧',
  1574. RightDownTeeVector: '⥝',
  1575. RightDownVectorBar: '⥕',
  1576. RightDownVector: '⇂',
  1577. RightFloor: '⌋',
  1578. rightharpoondown: '⇁',
  1579. rightharpoonup: '⇀',
  1580. rightleftarrows: '⇄',
  1581. rightleftharpoons: '⇌',
  1582. rightrightarrows: '⇉',
  1583. rightsquigarrow: '↝',
  1584. RightTeeArrow: '↦',
  1585. RightTee: '⊢',
  1586. RightTeeVector: '⥛',
  1587. rightthreetimes: '⋌',
  1588. RightTriangleBar: '⧐',
  1589. RightTriangle: '⊳',
  1590. RightTriangleEqual: '⊵',
  1591. RightUpDownVector: '⥏',
  1592. RightUpTeeVector: '⥜',
  1593. RightUpVectorBar: '⥔',
  1594. RightUpVector: '↾',
  1595. RightVectorBar: '⥓',
  1596. RightVector: '⇀',
  1597. ring: '˚',
  1598. risingdotseq: '≓',
  1599. rlarr: '⇄',
  1600. rlhar: '⇌',
  1601. rlm: '‏',
  1602. rmoustache: '⎱',
  1603. rmoust: '⎱',
  1604. rnmid: '⫮',
  1605. roang: '⟭',
  1606. roarr: '⇾',
  1607. robrk: '⟧',
  1608. ropar: '⦆',
  1609. ropf: '𝕣',
  1610. Ropf: 'ℝ',
  1611. roplus: '⨮',
  1612. rotimes: '⨵',
  1613. RoundImplies: '⥰',
  1614. rpar: ')',
  1615. rpargt: '⦔',
  1616. rppolint: '⨒',
  1617. rrarr: '⇉',
  1618. Rrightarrow: '⇛',
  1619. rsaquo: '›',
  1620. rscr: '𝓇',
  1621. Rscr: 'ℛ',
  1622. rsh: '↱',
  1623. Rsh: '↱',
  1624. rsqb: ']',
  1625. rsquo: '’',
  1626. rsquor: '’',
  1627. rthree: '⋌',
  1628. rtimes: '⋊',
  1629. rtri: '▹',
  1630. rtrie: '⊵',
  1631. rtrif: '▸',
  1632. rtriltri: '⧎',
  1633. RuleDelayed: '⧴',
  1634. ruluhar: '⥨',
  1635. rx: '℞',
  1636. Sacute: 'Ś',
  1637. sacute: 'ś',
  1638. sbquo: '‚',
  1639. scap: '⪸',
  1640. Scaron: 'Š',
  1641. scaron: 'š',
  1642. Sc: '⪼',
  1643. sc: '≻',
  1644. sccue: '≽',
  1645. sce: '⪰',
  1646. scE: '⪴',
  1647. Scedil: 'Ş',
  1648. scedil: 'ş',
  1649. Scirc: 'Ŝ',
  1650. scirc: 'ŝ',
  1651. scnap: '⪺',
  1652. scnE: '⪶',
  1653. scnsim: '⋩',
  1654. scpolint: '⨓',
  1655. scsim: '≿',
  1656. Scy: 'С',
  1657. scy: 'с',
  1658. sdotb: '⊡',
  1659. sdot: '⋅',
  1660. sdote: '⩦',
  1661. searhk: '⤥',
  1662. searr: '↘',
  1663. seArr: '⇘',
  1664. searrow: '↘',
  1665. sect: '§',
  1666. semi: ';',
  1667. seswar: '⤩',
  1668. setminus: '∖',
  1669. setmn: '∖',
  1670. sext: '✶',
  1671. Sfr: '𝔖',
  1672. sfr: '𝔰',
  1673. sfrown: '⌢',
  1674. sharp: '♯',
  1675. SHCHcy: 'Щ',
  1676. shchcy: 'щ',
  1677. SHcy: 'Ш',
  1678. shcy: 'ш',
  1679. ShortDownArrow: '↓',
  1680. ShortLeftArrow: '←',
  1681. shortmid: '∣',
  1682. shortparallel: '∥',
  1683. ShortRightArrow: '→',
  1684. ShortUpArrow: '↑',
  1685. shy: '­',
  1686. Sigma: 'Σ',
  1687. sigma: 'σ',
  1688. sigmaf: 'ς',
  1689. sigmav: 'ς',
  1690. sim: '∼',
  1691. simdot: '⩪',
  1692. sime: '≃',
  1693. simeq: '≃',
  1694. simg: '⪞',
  1695. simgE: '⪠',
  1696. siml: '⪝',
  1697. simlE: '⪟',
  1698. simne: '≆',
  1699. simplus: '⨤',
  1700. simrarr: '⥲',
  1701. slarr: '←',
  1702. SmallCircle: '∘',
  1703. smallsetminus: '∖',
  1704. smashp: '⨳',
  1705. smeparsl: '⧤',
  1706. smid: '∣',
  1707. smile: '⌣',
  1708. smt: '⪪',
  1709. smte: '⪬',
  1710. smtes: '⪬',
  1711. SOFTcy: 'Ь',
  1712. softcy: 'ь',
  1713. solbar: '⌿',
  1714. solb: '⧄',
  1715. sol: '/',
  1716. Sopf: '𝕊',
  1717. sopf: '𝕤',
  1718. spades: '♠',
  1719. spadesuit: '♠',
  1720. spar: '∥',
  1721. sqcap: '⊓',
  1722. sqcaps: '⊓',
  1723. sqcup: '⊔',
  1724. sqcups: '⊔',
  1725. Sqrt: '√',
  1726. sqsub: '⊏',
  1727. sqsube: '⊑',
  1728. sqsubset: '⊏',
  1729. sqsubseteq: '⊑',
  1730. sqsup: '⊐',
  1731. sqsupe: '⊒',
  1732. sqsupset: '⊐',
  1733. sqsupseteq: '⊒',
  1734. square: '□',
  1735. Square: '□',
  1736. SquareIntersection: '⊓',
  1737. SquareSubset: '⊏',
  1738. SquareSubsetEqual: '⊑',
  1739. SquareSuperset: '⊐',
  1740. SquareSupersetEqual: '⊒',
  1741. SquareUnion: '⊔',
  1742. squarf: '▪',
  1743. squ: '□',
  1744. squf: '▪',
  1745. srarr: '→',
  1746. Sscr: '𝒮',
  1747. sscr: '𝓈',
  1748. ssetmn: '∖',
  1749. ssmile: '⌣',
  1750. sstarf: '⋆',
  1751. Star: '⋆',
  1752. star: '☆',
  1753. starf: '★',
  1754. straightepsilon: 'ϵ',
  1755. straightphi: 'ϕ',
  1756. strns: '¯',
  1757. sub: '⊂',
  1758. Sub: '⋐',
  1759. subdot: '⪽',
  1760. subE: '⫅',
  1761. sube: '⊆',
  1762. subedot: '⫃',
  1763. submult: '⫁',
  1764. subnE: '⫋',
  1765. subne: '⊊',
  1766. subplus: '⪿',
  1767. subrarr: '⥹',
  1768. subset: '⊂',
  1769. Subset: '⋐',
  1770. subseteq: '⊆',
  1771. subseteqq: '⫅',
  1772. SubsetEqual: '⊆',
  1773. subsetneq: '⊊',
  1774. subsetneqq: '⫋',
  1775. subsim: '⫇',
  1776. subsub: '⫕',
  1777. subsup: '⫓',
  1778. succapprox: '⪸',
  1779. succ: '≻',
  1780. succcurlyeq: '≽',
  1781. Succeeds: '≻',
  1782. SucceedsEqual: '⪰',
  1783. SucceedsSlantEqual: '≽',
  1784. SucceedsTilde: '≿',
  1785. succeq: '⪰',
  1786. succnapprox: '⪺',
  1787. succneqq: '⪶',
  1788. succnsim: '⋩',
  1789. succsim: '≿',
  1790. SuchThat: '∋',
  1791. sum: '∑',
  1792. Sum: '∑',
  1793. sung: '♪',
  1794. sup1: '¹',
  1795. sup2: '²',
  1796. sup3: '³',
  1797. sup: '⊃',
  1798. Sup: '⋑',
  1799. supdot: '⪾',
  1800. supdsub: '⫘',
  1801. supE: '⫆',
  1802. supe: '⊇',
  1803. supedot: '⫄',
  1804. Superset: '⊃',
  1805. SupersetEqual: '⊇',
  1806. suphsol: '⟉',
  1807. suphsub: '⫗',
  1808. suplarr: '⥻',
  1809. supmult: '⫂',
  1810. supnE: '⫌',
  1811. supne: '⊋',
  1812. supplus: '⫀',
  1813. supset: '⊃',
  1814. Supset: '⋑',
  1815. supseteq: '⊇',
  1816. supseteqq: '⫆',
  1817. supsetneq: '⊋',
  1818. supsetneqq: '⫌',
  1819. supsim: '⫈',
  1820. supsub: '⫔',
  1821. supsup: '⫖',
  1822. swarhk: '⤦',
  1823. swarr: '↙',
  1824. swArr: '⇙',
  1825. swarrow: '↙',
  1826. swnwar: '⤪',
  1827. szlig: 'ß',
  1828. Tab: ' ',
  1829. target: '⌖',
  1830. Tau: 'Τ',
  1831. tau: 'τ',
  1832. tbrk: '⎴',
  1833. Tcaron: 'Ť',
  1834. tcaron: 'ť',
  1835. Tcedil: 'Ţ',
  1836. tcedil: 'ţ',
  1837. Tcy: 'Т',
  1838. tcy: 'т',
  1839. tdot: '⃛',
  1840. telrec: '⌕',
  1841. Tfr: '𝔗',
  1842. tfr: '𝔱',
  1843. there4: '∴',
  1844. therefore: '∴',
  1845. Therefore: '∴',
  1846. Theta: 'Θ',
  1847. theta: 'θ',
  1848. thetasym: 'ϑ',
  1849. thetav: 'ϑ',
  1850. thickapprox: '≈',
  1851. thicksim: '∼',
  1852. ThickSpace: ' ',
  1853. ThinSpace: ' ',
  1854. thinsp: ' ',
  1855. thkap: '≈',
  1856. thksim: '∼',
  1857. THORN: 'Þ',
  1858. thorn: 'þ',
  1859. tilde: '˜',
  1860. Tilde: '∼',
  1861. TildeEqual: '≃',
  1862. TildeFullEqual: '≅',
  1863. TildeTilde: '≈',
  1864. timesbar: '⨱',
  1865. timesb: '⊠',
  1866. times: '×',
  1867. timesd: '⨰',
  1868. tint: '∭',
  1869. toea: '⤨',
  1870. topbot: '⌶',
  1871. topcir: '⫱',
  1872. top: '⊤',
  1873. Topf: '𝕋',
  1874. topf: '𝕥',
  1875. topfork: '⫚',
  1876. tosa: '⤩',
  1877. tprime: '‴',
  1878. trade: '™',
  1879. TRADE: '™',
  1880. triangle: '▵',
  1881. triangledown: '▿',
  1882. triangleleft: '◃',
  1883. trianglelefteq: '⊴',
  1884. triangleq: '≜',
  1885. triangleright: '▹',
  1886. trianglerighteq: '⊵',
  1887. tridot: '◬',
  1888. trie: '≜',
  1889. triminus: '⨺',
  1890. TripleDot: '⃛',
  1891. triplus: '⨹',
  1892. trisb: '⧍',
  1893. tritime: '⨻',
  1894. trpezium: '⏢',
  1895. Tscr: '𝒯',
  1896. tscr: '𝓉',
  1897. TScy: 'Ц',
  1898. tscy: 'ц',
  1899. TSHcy: 'Ћ',
  1900. tshcy: 'ћ',
  1901. Tstrok: 'Ŧ',
  1902. tstrok: 'ŧ',
  1903. twixt: '≬',
  1904. twoheadleftarrow: '↞',
  1905. twoheadrightarrow: '↠',
  1906. Uacute: 'Ú',
  1907. uacute: 'ú',
  1908. uarr: '↑',
  1909. Uarr: '↟',
  1910. uArr: '⇑',
  1911. Uarrocir: '⥉',
  1912. Ubrcy: 'Ў',
  1913. ubrcy: 'ў',
  1914. Ubreve: 'Ŭ',
  1915. ubreve: 'ŭ',
  1916. Ucirc: 'Û',
  1917. ucirc: 'û',
  1918. Ucy: 'У',
  1919. ucy: 'у',
  1920. udarr: '⇅',
  1921. Udblac: 'Ű',
  1922. udblac: 'ű',
  1923. udhar: '⥮',
  1924. ufisht: '⥾',
  1925. Ufr: '𝔘',
  1926. ufr: '𝔲',
  1927. Ugrave: 'Ù',
  1928. ugrave: 'ù',
  1929. uHar: '⥣',
  1930. uharl: '↿',
  1931. uharr: '↾',
  1932. uhblk: '▀',
  1933. ulcorn: '⌜',
  1934. ulcorner: '⌜',
  1935. ulcrop: '⌏',
  1936. ultri: '◸',
  1937. Umacr: 'Ū',
  1938. umacr: 'ū',
  1939. uml: '¨',
  1940. UnderBar: '_',
  1941. UnderBrace: '⏟',
  1942. UnderBracket: '⎵',
  1943. UnderParenthesis: '⏝',
  1944. Union: '⋃',
  1945. UnionPlus: '⊎',
  1946. Uogon: 'Ų',
  1947. uogon: 'ų',
  1948. Uopf: '𝕌',
  1949. uopf: '𝕦',
  1950. UpArrowBar: '⤒',
  1951. uparrow: '↑',
  1952. UpArrow: '↑',
  1953. Uparrow: '⇑',
  1954. UpArrowDownArrow: '⇅',
  1955. updownarrow: '↕',
  1956. UpDownArrow: '↕',
  1957. Updownarrow: '⇕',
  1958. UpEquilibrium: '⥮',
  1959. upharpoonleft: '↿',
  1960. upharpoonright: '↾',
  1961. uplus: '⊎',
  1962. UpperLeftArrow: '↖',
  1963. UpperRightArrow: '↗',
  1964. upsi: 'υ',
  1965. Upsi: 'ϒ',
  1966. upsih: 'ϒ',
  1967. Upsilon: 'Υ',
  1968. upsilon: 'υ',
  1969. UpTeeArrow: '↥',
  1970. UpTee: '⊥',
  1971. upuparrows: '⇈',
  1972. urcorn: '⌝',
  1973. urcorner: '⌝',
  1974. urcrop: '⌎',
  1975. Uring: 'Ů',
  1976. uring: 'ů',
  1977. urtri: '◹',
  1978. Uscr: '𝒰',
  1979. uscr: '𝓊',
  1980. utdot: '⋰',
  1981. Utilde: 'Ũ',
  1982. utilde: 'ũ',
  1983. utri: '▵',
  1984. utrif: '▴',
  1985. uuarr: '⇈',
  1986. Uuml: 'Ü',
  1987. uuml: 'ü',
  1988. uwangle: '⦧',
  1989. vangrt: '⦜',
  1990. varepsilon: 'ϵ',
  1991. varkappa: 'ϰ',
  1992. varnothing: '∅',
  1993. varphi: 'ϕ',
  1994. varpi: 'ϖ',
  1995. varpropto: '∝',
  1996. varr: '↕',
  1997. vArr: '⇕',
  1998. varrho: 'ϱ',
  1999. varsigma: 'ς',
  2000. varsubsetneq: '⊊',
  2001. varsubsetneqq: '⫋',
  2002. varsupsetneq: '⊋',
  2003. varsupsetneqq: '⫌',
  2004. vartheta: 'ϑ',
  2005. vartriangleleft: '⊲',
  2006. vartriangleright: '⊳',
  2007. vBar: '⫨',
  2008. Vbar: '⫫',
  2009. vBarv: '⫩',
  2010. Vcy: 'В',
  2011. vcy: 'в',
  2012. vdash: '⊢',
  2013. vDash: '⊨',
  2014. Vdash: '⊩',
  2015. VDash: '⊫',
  2016. Vdashl: '⫦',
  2017. veebar: '⊻',
  2018. vee: '∨',
  2019. Vee: '⋁',
  2020. veeeq: '≚',
  2021. vellip: '⋮',
  2022. verbar: '|',
  2023. Verbar: '‖',
  2024. vert: '|',
  2025. Vert: '‖',
  2026. VerticalBar: '∣',
  2027. VerticalLine: '|',
  2028. VerticalSeparator: '❘',
  2029. VerticalTilde: '≀',
  2030. VeryThinSpace: ' ',
  2031. Vfr: '𝔙',
  2032. vfr: '𝔳',
  2033. vltri: '⊲',
  2034. vnsub: '⊂',
  2035. vnsup: '⊃',
  2036. Vopf: '𝕍',
  2037. vopf: '𝕧',
  2038. vprop: '∝',
  2039. vrtri: '⊳',
  2040. Vscr: '𝒱',
  2041. vscr: '𝓋',
  2042. vsubnE: '⫋',
  2043. vsubne: '⊊',
  2044. vsupnE: '⫌',
  2045. vsupne: '⊋',
  2046. Vvdash: '⊪',
  2047. vzigzag: '⦚',
  2048. Wcirc: 'Ŵ',
  2049. wcirc: 'ŵ',
  2050. wedbar: '⩟',
  2051. wedge: '∧',
  2052. Wedge: '⋀',
  2053. wedgeq: '≙',
  2054. weierp: '℘',
  2055. Wfr: '𝔚',
  2056. wfr: '𝔴',
  2057. Wopf: '𝕎',
  2058. wopf: '𝕨',
  2059. wp: '℘',
  2060. wr: '≀',
  2061. wreath: '≀',
  2062. Wscr: '𝒲',
  2063. wscr: '𝓌',
  2064. xcap: '⋂',
  2065. xcirc: '◯',
  2066. xcup: '⋃',
  2067. xdtri: '▽',
  2068. Xfr: '𝔛',
  2069. xfr: '𝔵',
  2070. xharr: '⟷',
  2071. xhArr: '⟺',
  2072. Xi: 'Ξ',
  2073. xi: 'ξ',
  2074. xlarr: '⟵',
  2075. xlArr: '⟸',
  2076. xmap: '⟼',
  2077. xnis: '⋻',
  2078. xodot: '⨀',
  2079. Xopf: '𝕏',
  2080. xopf: '𝕩',
  2081. xoplus: '⨁',
  2082. xotime: '⨂',
  2083. xrarr: '⟶',
  2084. xrArr: '⟹',
  2085. Xscr: '𝒳',
  2086. xscr: '𝓍',
  2087. xsqcup: '⨆',
  2088. xuplus: '⨄',
  2089. xutri: '△',
  2090. xvee: '⋁',
  2091. xwedge: '⋀',
  2092. Yacute: 'Ý',
  2093. yacute: 'ý',
  2094. YAcy: 'Я',
  2095. yacy: 'я',
  2096. Ycirc: 'Ŷ',
  2097. ycirc: 'ŷ',
  2098. Ycy: 'Ы',
  2099. ycy: 'ы',
  2100. yen: '¥',
  2101. Yfr: '𝔜',
  2102. yfr: '𝔶',
  2103. YIcy: 'Ї',
  2104. yicy: 'ї',
  2105. Yopf: '𝕐',
  2106. yopf: '𝕪',
  2107. Yscr: '𝒴',
  2108. yscr: '𝓎',
  2109. YUcy: 'Ю',
  2110. yucy: 'ю',
  2111. yuml: 'ÿ',
  2112. Yuml: 'Ÿ',
  2113. Zacute: 'Ź',
  2114. zacute: 'ź',
  2115. Zcaron: 'Ž',
  2116. zcaron: 'ž',
  2117. Zcy: 'З',
  2118. zcy: 'з',
  2119. Zdot: 'Ż',
  2120. zdot: 'ż',
  2121. zeetrf: 'ℨ',
  2122. ZeroWidthSpace: '​',
  2123. Zeta: 'Ζ',
  2124. zeta: 'ζ',
  2125. zfr: '𝔷',
  2126. Zfr: 'ℨ',
  2127. ZHcy: 'Ж',
  2128. zhcy: 'ж',
  2129. zigrarr: '⇝',
  2130. zopf: '𝕫',
  2131. Zopf: 'ℤ',
  2132. Zscr: '𝒵',
  2133. zscr: '𝓏',
  2134. zwj: '‍',
  2135. zwnj: '‌' };
  2136. // Some regexps used in inline parser:
  2137. var ESCAPABLE = '[!"#$%&\'()*+,./:;<=>?@[\\\\\\]^_`{|}~-]';
  2138. var ESCAPED_CHAR = '\\\\' + ESCAPABLE;
  2139. var IN_DOUBLE_QUOTES = '"(' + ESCAPED_CHAR + '|[^"\\x00])*"';
  2140. var IN_SINGLE_QUOTES = '\'(' + ESCAPED_CHAR + '|[^\'\\x00])*\'';
  2141. var IN_PARENS = '\\((' + ESCAPED_CHAR + '|[^)\\x00])*\\)';
  2142. var REG_CHAR = '[^\\\\()\\x00-\\x20]';
  2143. var IN_PARENS_NOSP = '\\((' + REG_CHAR + '|' + ESCAPED_CHAR + ')*\\)';
  2144. var TAGNAME = '[A-Za-z][A-Za-z0-9]*';
  2145. var BLOCKTAGNAME = '(?:article|header|aside|hgroup|iframe|blockquote|hr|body|li|map|button|object|canvas|ol|caption|output|col|p|colgroup|pre|dd|progress|div|section|dl|table|td|dt|tbody|embed|textarea|fieldset|tfoot|figcaption|th|figure|thead|footer|footer|tr|form|ul|h1|h2|h3|h4|h5|h6|video|script|style)';
  2146. var ATTRIBUTENAME = '[a-zA-Z_:][a-zA-Z0-9:._-]*';
  2147. var UNQUOTEDVALUE = "[^\"'=<>`\\x00-\\x20]+";
  2148. var SINGLEQUOTEDVALUE = "'[^']*'";
  2149. var DOUBLEQUOTEDVALUE = '"[^"]*"';
  2150. var ATTRIBUTEVALUE = "(?:" + UNQUOTEDVALUE + "|" + SINGLEQUOTEDVALUE + "|" + DOUBLEQUOTEDVALUE + ")";
  2151. var ATTRIBUTEVALUESPEC = "(?:" + "\\s*=" + "\\s*" + ATTRIBUTEVALUE + ")";
  2152. var ATTRIBUTE = "(?:" + "\\s+" + ATTRIBUTENAME + ATTRIBUTEVALUESPEC + "?)";
  2153. var OPENTAG = "<" + TAGNAME + ATTRIBUTE + "*" + "\\s*/?>";
  2154. var CLOSETAG = "</" + TAGNAME + "\\s*[>]";
  2155. var OPENBLOCKTAG = "<" + BLOCKTAGNAME + ATTRIBUTE + "*" + "\\s*/?>";
  2156. var CLOSEBLOCKTAG = "</" + BLOCKTAGNAME + "\\s*[>]";
  2157. var HTMLCOMMENT = "<!--([^-]+|[-][^-]+)*-->";
  2158. var PROCESSINGINSTRUCTION = "[<][?].*?[?][>]";
  2159. var DECLARATION = "<![A-Z]+" + "\\s+[^>]*>";
  2160. var CDATA = "<!\\[CDATA\\[([^\\]]+|\\][^\\]]|\\]\\][^>])*\\]\\]>";
  2161. var HTMLTAG = "(?:" + OPENTAG + "|" + CLOSETAG + "|" + HTMLCOMMENT + "|" +
  2162. PROCESSINGINSTRUCTION + "|" + DECLARATION + "|" + CDATA + ")";
  2163. var HTMLBLOCKOPEN = "<(?:" + BLOCKTAGNAME + "[\\s/>]" + "|" +
  2164. "/" + BLOCKTAGNAME + "[\\s>]" + "|" + "[?!])";
  2165. var reHtmlTag = new RegExp('^' + HTMLTAG, 'i');
  2166. var reHtmlBlockOpen = new RegExp('^' + HTMLBLOCKOPEN, 'i');
  2167. var reLinkTitle = new RegExp(
  2168. '^(?:"(' + ESCAPED_CHAR + '|[^"\\x00])*"' +
  2169. '|' +
  2170. '\'(' + ESCAPED_CHAR + '|[^\'\\x00])*\'' +
  2171. '|' +
  2172. '\\((' + ESCAPED_CHAR + '|[^)\\x00])*\\))');
  2173. var reLinkDestinationBraces = new RegExp(
  2174. '^(?:[<](?:[^<>\\n\\\\\\x00]' + '|' + ESCAPED_CHAR + '|' + '\\\\)*[>])');
  2175. var reLinkDestination = new RegExp(
  2176. '^(?:' + REG_CHAR + '+|' + ESCAPED_CHAR + '|' + IN_PARENS_NOSP + ')*');
  2177. var reEscapable = new RegExp(ESCAPABLE);
  2178. var reAllEscapedChar = new RegExp('\\\\(' + ESCAPABLE + ')', 'g');
  2179. var reEscapedChar = new RegExp('^\\\\(' + ESCAPABLE + ')');
  2180. var reAllTab = /\t/g;
  2181. var reHrule = /^(?:(?:\* *){3,}|(?:_ *){3,}|(?:- *){3,}) *$/;
  2182. // Matches a character with a special meaning in markdown,
  2183. // or a string of non-special characters. Note: we match
  2184. // clumps of _ or * or `, because they need to be handled in groups.
  2185. var reMain = /^(?:[_*`\n]+|[\[\]\\!<&*_]|(?: *[^\n `\[\]\\!<&*_]+)+|[ \n]+)/m;
  2186. // UTILITY FUNCTIONS
  2187. // Replace backslash escapes with literal characters.
  2188. var unescapeBS = function(s) {
  2189. return s.replace(reAllEscapedChar, '$1');
  2190. };
  2191. // Returns true if string contains only space characters.
  2192. var isBlank = function(s) {
  2193. return /^\s*$/.test(s);
  2194. };
  2195. // Normalize reference label: collapse internal whitespace
  2196. // to single space, remove leading/trailing whitespace, case fold.
  2197. var normalizeReference = function(s) {
  2198. return s.trim()
  2199. .replace(/\s+/,' ')
  2200. .toUpperCase();
  2201. };
  2202. // Attempt to match a regex in string s at offset offset.
  2203. // Return index of match or null.
  2204. var matchAt = function(re, s, offset) {
  2205. var res = s.slice(offset).match(re);
  2206. if (res) {
  2207. return offset + res.index;
  2208. } else {
  2209. return null;
  2210. }
  2211. };
  2212. // Convert tabs to spaces on each line using a 4-space tab stop.
  2213. var detabLine = function(text) {
  2214. if (text.indexOf('\t') == -1) {
  2215. return text;
  2216. } else {
  2217. var lastStop = 0;
  2218. return text.replace(reAllTab, function(match, offset) {
  2219. var result = ' '.slice((offset - lastStop) % 4);
  2220. lastStop = offset + 1;
  2221. return result;
  2222. });
  2223. }
  2224. };
  2225. // INLINE PARSER
  2226. // These are methods of an InlineParser object, defined below.
  2227. // An InlineParser keeps track of a subject (a string to be
  2228. // parsed) and a position in that subject.
  2229. // If re matches at current position in the subject, advance
  2230. // position in subject and return the match; otherwise return null.
  2231. var match = function(re) {
  2232. var match = re.exec(this.subject.slice(this.pos));
  2233. if (match) {
  2234. this.pos += match.index + match[0].length;
  2235. return match[0];
  2236. } else {
  2237. return null;
  2238. }
  2239. };
  2240. // Returns the character at the current subject position, or null if
  2241. // there are no more characters.
  2242. var peek = function() {
  2243. return this.subject.charAt(this.pos) || null;
  2244. };
  2245. // Parse zero or more space characters, including at most one newline
  2246. var spnl = function() {
  2247. this.match(/^ *(?:\n *)?/);
  2248. return 1;
  2249. };
  2250. // All of the parsers below try to match something at the current position
  2251. // in the subject. If they succeed in matching anything, they
  2252. // return the inline matched, advancing the subject.
  2253. // Attempt to parse backticks, returning either a backtick code span or a
  2254. // literal sequence of backticks.
  2255. var parseBackticks = function() {
  2256. var startpos = this.pos;
  2257. var ticks = this.match(/^`+/);
  2258. if (!ticks) {
  2259. return 0;
  2260. }
  2261. var afterOpenTicks = this.pos;
  2262. var foundCode = false;
  2263. var match;
  2264. while (!foundCode && (match = this.match(/`+/m))) {
  2265. if (match == ticks) {
  2266. return [{ t: 'Code', c: this.subject.slice(afterOpenTicks,
  2267. this.pos - ticks.length)
  2268. .replace(/[ \n]+/g,' ')
  2269. .trim() }];
  2270. }
  2271. }
  2272. // If we got here, we didn't match a closing backtick sequence.
  2273. this.pos = afterOpenTicks;
  2274. return [{ t: 'Str', c: ticks }];
  2275. };
  2276. // Parse a backslash-escaped special character, adding either the escaped
  2277. // character, a hard line break (if the backslash is followed by a newline),
  2278. // or a literal backslash to the 'inlines' list.
  2279. var parseBackslash = function() {
  2280. var subj = this.subject,
  2281. pos = this.pos;
  2282. if (subj.charAt(pos) === '\\') {
  2283. if (subj.charAt(pos + 1) === '\n') {
  2284. this.pos = this.pos + 2;
  2285. return [{ t: 'Hardbreak' }];
  2286. } else if (reEscapable.test(subj.charAt(pos + 1))) {
  2287. this.pos = this.pos + 2;
  2288. return [{ t: 'Str', c: subj.charAt(pos + 1) }];
  2289. } else {
  2290. this.pos++;
  2291. return [{t: 'Str', c: '\\'}];
  2292. }
  2293. } else {
  2294. return null;
  2295. }
  2296. };
  2297. // Attempt to parse an autolink (URL or email in pointy brackets).
  2298. var parseAutolink = function() {
  2299. var m;
  2300. var dest;
  2301. if ((m = this.match(/^<([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)>/))) { // email autolink
  2302. dest = m.slice(1,-1);
  2303. return [{t: 'Link',
  2304. label: [{ t: 'Str', c: dest }],
  2305. destination: 'mailto:' + encodeURI(dest) }];
  2306. } else if ((m = this.match(/^<(?:coap|doi|javascript|aaa|aaas|about|acap|cap|cid|crid|data|dav|dict|dns|file|ftp|geo|go|gopher|h323|http|https|iax|icap|im|imap|info|ipp|iris|iris.beep|iris.xpc|iris.xpcs|iris.lwz|ldap|mailto|mid|msrp|msrps|mtqp|mupdate|news|nfs|ni|nih|nntp|opaquelocktoken|pop|pres|rtsp|service|session|shttp|sieve|sip|sips|sms|snmp|soap.beep|soap.beeps|tag|tel|telnet|tftp|thismessage|tn3270|tip|tv|urn|vemmi|ws|wss|xcon|xcon-userid|xmlrpc.beep|xmlrpc.beeps|xmpp|z39.50r|z39.50s|adiumxtra|afp|afs|aim|apt|attachment|aw|beshare|bitcoin|bolo|callto|chrome|chrome-extension|com-eventbrite-attendee|content|cvs|dlna-playsingle|dlna-playcontainer|dtn|dvb|ed2k|facetime|feed|finger|fish|gg|git|gizmoproject|gtalk|hcp|icon|ipn|irc|irc6|ircs|itms|jar|jms|keyparc|lastfm|ldaps|magnet|maps|market|message|mms|ms-help|msnim|mumble|mvn|notes|oid|palm|paparazzi|platform|proxy|psyc|query|res|resource|rmi|rsync|rtmp|secondlife|sftp|sgn|skype|smb|soldat|spotify|ssh|steam|svn|teamspeak|things|udp|unreal|ut2004|ventrilo|view-source|webcal|wtai|wyciwyg|xfire|xri|ymsgr):[^<>\x00-\x20]*>/i))) {
  2307. dest = m.slice(1,-1);
  2308. return [{ t: 'Link',
  2309. label: [{ t: 'Str', c: dest }],
  2310. destination: encodeURI(dest) }];
  2311. } else {
  2312. return null;
  2313. }
  2314. };
  2315. // Attempt to parse a raw HTML tag.
  2316. var parseHtmlTag = function() {
  2317. var m = this.match(reHtmlTag);
  2318. if (m) {
  2319. return [{ t: 'Html', c: m }];
  2320. } else {
  2321. return null;
  2322. }
  2323. };
  2324. // Scan a sequence of characters == c, and return information about
  2325. // the number of delimiters and whether they are positioned such that
  2326. // they can open and/or close emphasis or strong emphasis. A utility
  2327. // function for strong/emph parsing.
  2328. var scanDelims = function(c) {
  2329. var numdelims = 0;
  2330. var first_close_delims = 0;
  2331. var char_before, char_after;
  2332. var startpos = this.pos;
  2333. char_before = this.pos === 0 ? '\n' :
  2334. this.subject.charAt(this.pos - 1);
  2335. while (this.peek() === c) {
  2336. numdelims++;
  2337. this.pos++;
  2338. }
  2339. char_after = this.peek() || '\n';
  2340. var can_open = numdelims > 0 && numdelims <= 3 && !(/\s/.test(char_after));
  2341. var can_close = numdelims > 0 && numdelims <= 3 && !(/\s/.test(char_before));
  2342. if (c === '_') {
  2343. can_open = can_open && !((/[a-z0-9]/i).test(char_before));
  2344. can_close = can_close && !((/[a-z0-9]/i).test(char_after));
  2345. }
  2346. this.pos = startpos;
  2347. return { numdelims: numdelims,
  2348. can_open: can_open,
  2349. can_close: can_close };
  2350. };
  2351. var Emph = function(ils) {
  2352. return {t: 'Emph', c: ils};
  2353. }
  2354. var Strong = function(ils) {
  2355. return {t: 'Strong', c: ils};
  2356. }
  2357. var Str = function(s) {
  2358. return {t: 'Str', c: s};
  2359. }
  2360. // Attempt to parse emphasis or strong emphasis.
  2361. var parseEmphasis = function() {
  2362. var startpos = this.pos;
  2363. var c ;
  2364. var first_close = 0;
  2365. c = this.peek();
  2366. if (!(c === '*' || c === '_')) {
  2367. return null;
  2368. }
  2369. var numdelims;
  2370. var delimpos;
  2371. var inlines = [];
  2372. // Get opening delimiters.
  2373. res = this.scanDelims(c);
  2374. numdelims = res.numdelims;
  2375. if (numdelims === 0) {
  2376. this.pos = startpos;
  2377. return null;
  2378. }
  2379. if (numdelims >= 4 || !res.can_open) {
  2380. this.pos += numdelims;
  2381. return [Str(this.subject.slice(startpos, startpos + numdelims))];
  2382. }
  2383. this.pos += numdelims;
  2384. var fallbackpos = this.pos;
  2385. var fallback = Str(this.subject.slice(startpos, fallbackpos));
  2386. var next_inline;
  2387. var first = [];
  2388. var second = [];
  2389. var current = first;
  2390. var state = 0;
  2391. var can_close = false;
  2392. var can_open = false;
  2393. var last_emphasis_closer = null;
  2394. if (numdelims === 3) {
  2395. state = 1;
  2396. } else if (numdelims === 2) {
  2397. state = 2;
  2398. } else if (numdelims === 1) {
  2399. state = 3;
  2400. }
  2401. while (true) {
  2402. if (this.last_emphasis_closer[c] < this.pos) {
  2403. break;
  2404. }
  2405. res = this.scanDelims(c);
  2406. if (res) {
  2407. numdelims = res.numdelims;
  2408. can_close = res.can_close;
  2409. if (can_close) {
  2410. last_emphasis_closer = this.pos;
  2411. }
  2412. can_open = res.can_open;
  2413. switch (state) {
  2414. case 1: // ***a
  2415. if (numdelims === 3 && can_close) {
  2416. this.pos += 3;
  2417. return [Strong([Emph(first)])];
  2418. } else if (numdelims === 2 && can_close) {
  2419. this.pos += 2;
  2420. current = second;
  2421. state = can_open ? 4 : 6;
  2422. continue;
  2423. } else if (numdelims === 1 && can_close) {
  2424. this.pos += 1;
  2425. current = second;
  2426. state = can_open ? 5 : 7;
  2427. continue;
  2428. }
  2429. break;
  2430. case 2: // **a
  2431. if (numdelims === 2 && can_close) {
  2432. this.pos += 2;
  2433. return [Strong(first)];
  2434. } else if (numdelims === 1 && can_open) {
  2435. this.pos += 1;
  2436. current = second;
  2437. state = 8;
  2438. continue;
  2439. }
  2440. break;
  2441. case 3: // *a
  2442. if (numdelims === 1 && can_close) {
  2443. this.pos += 1;
  2444. return [Emph(first)];
  2445. } else if (numdelims === 2 && can_open) {
  2446. this.pos += 2;
  2447. current = second;
  2448. state = 9;
  2449. continue;
  2450. }
  2451. break;
  2452. case 4: // ***a**b
  2453. if (numdelims === 3 && can_close) {
  2454. this.pos += 3;
  2455. return [Strong([Emph(first.concat([Str(c+c)], second))])];
  2456. } else if (numdelims === 2 && can_close) {
  2457. this.pos += 2;
  2458. return [Strong([Str(c+c+c)].concat(
  2459. first,
  2460. [Strong(second)]))];
  2461. } else if (numdelims === 1 && can_close) {
  2462. this.pos += 1;
  2463. return [Emph([Strong(first)].concat(second))];
  2464. }
  2465. break;
  2466. case 5: // ***a*b
  2467. if (numdelims === 3 && can_close) {
  2468. this.pos += 3;
  2469. return [Strong([Emph(first.concat([Str(c)], second))])];
  2470. } else if (numdelims === 2 && can_close) {
  2471. this.pos += 2;
  2472. return [Strong([Emph(first)].concat(second))];
  2473. } else if (numdelims === 1 && can_close) {
  2474. this.pos += 1;
  2475. return [Strong([Str(c+c+c)].concat(
  2476. first,
  2477. [Emph(second)]))];
  2478. }
  2479. break;
  2480. case 6: // ***a** b
  2481. if (numdelims === 3 && can_close) {
  2482. this.pos += 3;
  2483. return [Strong([Emph(first.concat([Str(c+c)], second))])];
  2484. } else if (numdelims === 1 && can_close) {
  2485. this.pos += 1;
  2486. return [Emph([Strong(first)].concat(second))];
  2487. }
  2488. break;
  2489. case 7: // ***a* b
  2490. if (numdelims === 3 && can_close) {
  2491. this.pos += 3;
  2492. return [Strong([Emph(first.concat([Str(c)], second))])];
  2493. } else if (numdelims === 2 && can_close) {
  2494. this.pos += 2;
  2495. return [Strong([Emph(first)].concat(second))];
  2496. }
  2497. break;
  2498. case 8: // **a *b
  2499. if (numdelims === 3 && can_close) {
  2500. this.pos += 3;
  2501. return [Strong(first.concat([Emph(second)]))];
  2502. } else if (numdelims === 2 && can_close) {
  2503. this.pos += 2;
  2504. return [Strong(first.concat([Str(c)], second))];
  2505. } else if (numdelims === 1 && can_close) {
  2506. this.pos += 1;
  2507. first.push(Emph(second));
  2508. current = first;
  2509. state = 2;
  2510. continue;
  2511. }
  2512. break;
  2513. case 9: // *a **b
  2514. if (numdelims === 3 && can_close) {
  2515. this.pos += 3;
  2516. return [(Emph(first.concat([Strong(second)])))];
  2517. } else if (numdelims === 2 && can_close) {
  2518. this.pos += 2;
  2519. first.push(Strong(second));
  2520. current = first;
  2521. state = 3;
  2522. continue;
  2523. } else if (numdelims === 1 && can_close) {
  2524. this.pos += 1;
  2525. return [Emph(first.concat([Str(c+c)], second))];
  2526. }
  2527. break;
  2528. default:
  2529. break;
  2530. }
  2531. }
  2532. if ((next_inline = this.parseInline(true))) {
  2533. Array.prototype.push.apply(current, next_inline);
  2534. } else {
  2535. break;
  2536. }
  2537. }
  2538. // we didn't match emphasis: fallback
  2539. this.pos = fallbackpos;
  2540. if (last_emphasis_closer) {
  2541. this.last_emphasis_closer[c] = last_emphasis_closer;
  2542. }
  2543. return [fallback];
  2544. };
  2545. // Attempt to parse link title (sans quotes), returning the string
  2546. // or null if no match.
  2547. var parseLinkTitle = function() {
  2548. var title = this.match(reLinkTitle);
  2549. if (title) {
  2550. // chop off quotes from title and unescape:
  2551. return unescapeBS(title.substr(1, title.length - 2));
  2552. } else {
  2553. return null;
  2554. }
  2555. };
  2556. // Attempt to parse link destination, returning the string or
  2557. // null if no match.
  2558. var parseLinkDestination = function() {
  2559. var res = this.match(reLinkDestinationBraces);
  2560. if (res) { // chop off surrounding <..>:
  2561. return encodeURI(unescapeBS(res.substr(1, res.length - 2)));
  2562. } else {
  2563. res = this.match(reLinkDestination);
  2564. if (res !== null) {
  2565. return encodeURI(unescapeBS(res));
  2566. } else {
  2567. return null;
  2568. }
  2569. }
  2570. };
  2571. // Attempt to parse a link label, returning number of characters parsed.
  2572. var parseLinkLabel = function() {
  2573. if (this.peek() != '[') {
  2574. return 0;
  2575. }
  2576. var startpos = this.pos;
  2577. var nest_level = 0;
  2578. if (this.label_nest_level > 0) {
  2579. // If we've already checked to the end of this subject
  2580. // for a label, even with a different starting [, we
  2581. // know we won't find one here and we can just return.
  2582. // This avoids lots of backtracking.
  2583. // Note: nest level 1 would be: [foo [bar]
  2584. // nest level 2 would be: [foo [bar [baz]
  2585. this.label_nest_level--;
  2586. return 0;
  2587. }
  2588. this.pos++; // advance past [
  2589. var c;
  2590. while ((c = this.peek()) && (c != ']' || nest_level > 0)) {
  2591. switch (c) {
  2592. case '`':
  2593. this.parseBackticks();
  2594. break;
  2595. case '<':
  2596. this.parseAutolink() || this.parseHtmlTag() ||
  2597. this.pos++;
  2598. break;
  2599. case '[': // nested []
  2600. nest_level++;
  2601. this.pos++;
  2602. break;
  2603. case ']': // nested []
  2604. nest_level--;
  2605. this.pos++;
  2606. break;
  2607. case '\\':
  2608. this.parseBackslash();
  2609. break;
  2610. default:
  2611. this.parseString();
  2612. }
  2613. }
  2614. if (c === ']') {
  2615. this.label_nest_level = 0;
  2616. this.pos++; // advance past ]
  2617. return this.pos - startpos;
  2618. } else {
  2619. if (!c) {
  2620. this.label_nest_level = nest_level;
  2621. }
  2622. this.pos = startpos;
  2623. return 0;
  2624. }
  2625. };
  2626. // Parse raw link label, including surrounding [], and return
  2627. // inline contents. (Note: this is not a method of InlineParser.)
  2628. var parseRawLabel = function(s) {
  2629. // note: parse without a refmap; we don't want links to resolve
  2630. // in nested brackets!
  2631. return new InlineParser().parse(s.substr(1, s.length - 2), {});
  2632. };
  2633. // Attempt to parse a link. If successful, return the link.
  2634. var parseLink = function() {
  2635. var startpos = this.pos;
  2636. var reflabel;
  2637. var n;
  2638. var dest;
  2639. var title;
  2640. n = this.parseLinkLabel();
  2641. if (n === 0) {
  2642. return null;
  2643. }
  2644. var afterlabel = this.pos;
  2645. var rawlabel = this.subject.substr(startpos, n);
  2646. // if we got this far, we've parsed a label.
  2647. // Try to parse an explicit link: [label](url "title")
  2648. if (this.peek() == '(') {
  2649. this.pos++;
  2650. if (this.spnl() &&
  2651. ((dest = this.parseLinkDestination()) !== null) &&
  2652. this.spnl() &&
  2653. // make sure there's a space before the title:
  2654. (/^\s/.test(this.subject.charAt(this.pos - 1)) &&
  2655. (title = this.parseLinkTitle() || '') || true) &&
  2656. this.spnl() &&
  2657. this.match(/^\)/)) {
  2658. return [{ t: 'Link',
  2659. destination: dest,
  2660. title: title,
  2661. label: parseRawLabel(rawlabel) }];
  2662. } else {
  2663. this.pos = startpos;
  2664. return null;
  2665. }
  2666. }
  2667. // If we're here, it wasn't an explicit link. Try to parse a reference link.
  2668. // first, see if there's another label
  2669. var savepos = this.pos;
  2670. this.spnl();
  2671. var beforelabel = this.pos;
  2672. n = this.parseLinkLabel();
  2673. if (n == 2) {
  2674. // empty second label
  2675. reflabel = rawlabel;
  2676. } else if (n > 0) {
  2677. reflabel = this.subject.slice(beforelabel, beforelabel + n);
  2678. } else {
  2679. this.pos = savepos;
  2680. reflabel = rawlabel;
  2681. }
  2682. // lookup rawlabel in refmap
  2683. var link = this.refmap[normalizeReference(reflabel)];
  2684. if (link) {
  2685. return [{t: 'Link',
  2686. destination: link.destination,
  2687. title: link.title,
  2688. label: parseRawLabel(rawlabel) }];
  2689. } else {
  2690. this.pos = startpos;
  2691. return null;
  2692. }
  2693. // Nothing worked, rewind:
  2694. this.pos = startpos;
  2695. return null;
  2696. };
  2697. // Attempt to parse an entity, return Entity object if successful.
  2698. var parseEntity = function() {
  2699. var m;
  2700. if ((m = this.match(/^&(?:#x[a-f0-9]{1,8}|#[0-9]{1,8}|[a-z][a-z0-9]{1,31});/i))) {
  2701. var isNumeric = /^&#/.test(m);
  2702. var isHex = /^&#[Xx]/.test(m);
  2703. var uchar;
  2704. if (isNumeric) {
  2705. var num;
  2706. if (isHex) {
  2707. num = parseInt(m.slice(3,-1), 16);
  2708. } else {
  2709. num = parseInt(m.slice(2,-1), 10);
  2710. }
  2711. uchar = String.fromCharCode(num);
  2712. } else {
  2713. uchar = entities[m.slice(1,-1)];
  2714. }
  2715. return [{ t: 'Str', c: uchar || m }];
  2716. } else {
  2717. return null;
  2718. }
  2719. };
  2720. // Parse a run of ordinary characters, or a single character with
  2721. // a special meaning in markdown, as a plain string, adding to inlines.
  2722. var parseString = function() {
  2723. var m;
  2724. if ((m = this.match(reMain))) {
  2725. return [{ t: 'Str', c: m }];
  2726. } else {
  2727. return null;
  2728. }
  2729. };
  2730. // Parse a newline. If it was preceded by two spaces, return a hard
  2731. // line break; otherwise a soft line break.
  2732. var parseNewline = function() {
  2733. var m = this.match(/^ *\n/);
  2734. if (m) {
  2735. if (m.length > 2) {
  2736. return [{ t: 'Hardbreak' }];
  2737. } else if (m.length > 0) {
  2738. return [{ t: 'Softbreak' }];
  2739. }
  2740. }
  2741. return null;
  2742. };
  2743. // Attempt to parse an image. If the opening '!' is not followed
  2744. // by a link, return a literal '!'.
  2745. var parseImage = function() {
  2746. if (this.match(/^!/)) {
  2747. var link = this.parseLink();
  2748. if (link) {
  2749. link[0].t = 'Image';
  2750. return link;
  2751. } else {
  2752. return [{ t: 'Str', c: '!' }];
  2753. }
  2754. } else {
  2755. return null;
  2756. }
  2757. };
  2758. // Attempt to parse a link reference, modifying refmap.
  2759. var parseReference = function(s, refmap) {
  2760. this.subject = s;
  2761. this.pos = 0;
  2762. var rawlabel;
  2763. var dest;
  2764. var title;
  2765. var matchChars;
  2766. var startpos = this.pos;
  2767. var match;
  2768. // label:
  2769. matchChars = this.parseLinkLabel();
  2770. if (matchChars === 0) {
  2771. return 0;
  2772. } else {
  2773. rawlabel = this.subject.substr(0, matchChars);
  2774. }
  2775. // colon:
  2776. if (this.peek() === ':') {
  2777. this.pos++;
  2778. } else {
  2779. this.pos = startpos;
  2780. return 0;
  2781. }
  2782. // link url
  2783. this.spnl();
  2784. dest = this.parseLinkDestination();
  2785. if (dest === null || dest.length === 0) {
  2786. this.pos = startpos;
  2787. return 0;
  2788. }
  2789. var beforetitle = this.pos;
  2790. this.spnl();
  2791. title = this.parseLinkTitle();
  2792. if (title === null) {
  2793. title = '';
  2794. // rewind before spaces
  2795. this.pos = beforetitle;
  2796. }
  2797. // make sure we're at line end:
  2798. if (this.match(/^ *(?:\n|$)/) === null) {
  2799. this.pos = startpos;
  2800. return 0;
  2801. }
  2802. var normlabel = normalizeReference(rawlabel);
  2803. if (!refmap[normlabel]) {
  2804. refmap[normlabel] = { destination: dest, title: title };
  2805. }
  2806. return this.pos - startpos;
  2807. };
  2808. // Parse the next inline element in subject, advancing subject position
  2809. // and returning the inline parsed.
  2810. var parseInline = function(memoize) {
  2811. var startpos = this.pos;
  2812. var memoized = memoize && this.memo[startpos];
  2813. if (memoized) {
  2814. this.pos = memoized.endpos;
  2815. return memoized.inline;
  2816. }
  2817. var c = this.peek();
  2818. if (!c) {
  2819. return null;
  2820. }
  2821. var res;
  2822. switch(c) {
  2823. case '\n':
  2824. case ' ':
  2825. res = this.parseNewline();
  2826. break;
  2827. case '\\':
  2828. res = this.parseBackslash();
  2829. break;
  2830. case '`':
  2831. res = this.parseBackticks();
  2832. break;
  2833. case '*':
  2834. case '_':
  2835. res = this.parseEmphasis();
  2836. break;
  2837. case '[':
  2838. res = this.parseLink();
  2839. break;
  2840. case '!':
  2841. res = this.parseImage();
  2842. break;
  2843. case '<':
  2844. res = this.parseAutolink() || this.parseHtmlTag();
  2845. break;
  2846. case '&':
  2847. res = this.parseEntity();
  2848. break;
  2849. default:
  2850. res = this.parseString();
  2851. break;
  2852. }
  2853. if (res === null) {
  2854. this.pos += 1;
  2855. res = [{t: 'Str', c: c}];
  2856. }
  2857. if (res && memoize) {
  2858. this.memo[startpos] = { inline: res,
  2859. endpos: this.pos };
  2860. }
  2861. return res;
  2862. };
  2863. // Parse s as a list of inlines, using refmap to resolve references.
  2864. var parseInlines = function(s, refmap) {
  2865. this.subject = s;
  2866. this.pos = 0;
  2867. this.refmap = refmap || {};
  2868. this.memo = {};
  2869. this.last_emphasis_closer = { '*': s.length, '_': s.length };
  2870. var inlines = [];
  2871. var next_inline;
  2872. while ((next_inline = this.parseInline())) {
  2873. Array.prototype.push.apply(inlines, next_inline);
  2874. }
  2875. return inlines;
  2876. };
  2877. // The InlineParser object.
  2878. function InlineParser(){
  2879. return {
  2880. subject: '',
  2881. label_nest_level: 0, // used by parseLinkLabel method
  2882. last_emphasis_closer: null, // used by parseEmphasis method
  2883. pos: 0,
  2884. refmap: {},
  2885. memo: {},
  2886. match: match,
  2887. peek: peek,
  2888. spnl: spnl,
  2889. parseBackticks: parseBackticks,
  2890. parseBackslash: parseBackslash,
  2891. parseAutolink: parseAutolink,
  2892. parseHtmlTag: parseHtmlTag,
  2893. scanDelims: scanDelims,
  2894. parseEmphasis: parseEmphasis,
  2895. parseLinkTitle: parseLinkTitle,
  2896. parseLinkDestination: parseLinkDestination,
  2897. parseLinkLabel: parseLinkLabel,
  2898. parseLink: parseLink,
  2899. parseEntity: parseEntity,
  2900. parseString: parseString,
  2901. parseNewline: parseNewline,
  2902. parseImage: parseImage,
  2903. parseReference: parseReference,
  2904. parseInline: parseInline,
  2905. parse: parseInlines
  2906. };
  2907. }
  2908. // DOC PARSER
  2909. // These are methods of a DocParser object, defined below.
  2910. var makeBlock = function(tag, start_line, start_column) {
  2911. return { t: tag,
  2912. open: true,
  2913. last_line_blank: false,
  2914. start_line: start_line,
  2915. start_column: start_column,
  2916. end_line: start_line,
  2917. children: [],
  2918. parent: null,
  2919. // string_content is formed by concatenating strings, in finalize:
  2920. string_content: "",
  2921. strings: [],
  2922. inline_content: []
  2923. };
  2924. };
  2925. // Returns true if parent block can contain child block.
  2926. var canContain = function(parent_type, child_type) {
  2927. return ( parent_type == 'Document' ||
  2928. parent_type == 'BlockQuote' ||
  2929. parent_type == 'ListItem' ||
  2930. (parent_type == 'List' && child_type == 'ListItem') );
  2931. };
  2932. // Returns true if block type can accept lines of text.
  2933. var acceptsLines = function(block_type) {
  2934. return ( block_type == 'Paragraph' ||
  2935. block_type == 'IndentedCode' ||
  2936. block_type == 'FencedCode' );
  2937. };
  2938. // Returns true if block ends with a blank line, descending if needed
  2939. // into lists and sublists.
  2940. var endsWithBlankLine = function(block) {
  2941. if (block.last_line_blank) {
  2942. return true;
  2943. }
  2944. if ((block.t == 'List' || block.t == 'ListItem') && block.children.length > 0) {
  2945. return endsWithBlankLine(block.children[block.children.length - 1]);
  2946. } else {
  2947. return false;
  2948. }
  2949. };
  2950. // Break out of all containing lists, resetting the tip of the
  2951. // document to the parent of the highest list, and finalizing
  2952. // all the lists. (This is used to implement the "two blank lines
  2953. // break of of all lists" feature.)
  2954. var breakOutOfLists = function(block, line_number) {
  2955. var b = block;
  2956. var last_list = null;
  2957. do {
  2958. if (b.t === 'List') {
  2959. last_list = b;
  2960. }
  2961. b = b.parent;
  2962. } while (b);
  2963. if (last_list) {
  2964. while (block != last_list) {
  2965. this.finalize(block, line_number);
  2966. block = block.parent;
  2967. }
  2968. this.finalize(last_list, line_number);
  2969. this.tip = last_list.parent;
  2970. }
  2971. };
  2972. // Add a line to the block at the tip. We assume the tip
  2973. // can accept lines -- that check should be done before calling this.
  2974. var addLine = function(ln, offset) {
  2975. var s = ln.slice(offset);
  2976. if (!(this.tip.open)) {
  2977. throw({ msg: "Attempted to add line (" + ln + ") to closed container." });
  2978. }
  2979. this.tip.strings.push(s);
  2980. };
  2981. // Add block of type tag as a child of the tip. If the tip can't
  2982. // accept children, close and finalize it and try its parent,
  2983. // and so on til we find a block that can accept children.
  2984. var addChild = function(tag, line_number, offset) {
  2985. while (!canContain(this.tip.t, tag)) {
  2986. this.finalize(this.tip, line_number);
  2987. }
  2988. var column_number = offset + 1; // offset 0 = column 1
  2989. var newBlock = makeBlock(tag, line_number, column_number);
  2990. this.tip.children.push(newBlock);
  2991. newBlock.parent = this.tip;
  2992. this.tip = newBlock;
  2993. return newBlock;
  2994. };
  2995. // Parse a list marker and return data on the marker (type,
  2996. // start, delimiter, bullet character, padding) or null.
  2997. var parseListMarker = function(ln, offset) {
  2998. var rest = ln.slice(offset);
  2999. var match;
  3000. var spaces_after_marker;
  3001. var data = {};
  3002. if (rest.match(reHrule)) {
  3003. return null;
  3004. }
  3005. if ((match = rest.match(/^[*+-]( +|$)/))) {
  3006. spaces_after_marker = match[1].length;
  3007. data.type = 'Bullet';
  3008. data.bullet_char = match[0][0];
  3009. } else if ((match = rest.match(/^(\d+)([.)])( +|$)/))) {
  3010. spaces_after_marker = match[3].length;
  3011. data.type = 'Ordered';
  3012. data.start = parseInt(match[1]);
  3013. data.delimiter = match[2];
  3014. } else {
  3015. return null;
  3016. }
  3017. var blank_item = match[0].length === rest.length;
  3018. if (spaces_after_marker >= 5 ||
  3019. spaces_after_marker < 1 ||
  3020. blank_item) {
  3021. data.padding = match[0].length - spaces_after_marker + 1;
  3022. } else {
  3023. data.padding = match[0].length;
  3024. }
  3025. return data;
  3026. };
  3027. // Returns true if the two list items are of the same type,
  3028. // with the same delimiter and bullet character. This is used
  3029. // in agglomerating list items into lists.
  3030. var listsMatch = function(list_data, item_data) {
  3031. return (list_data.type === item_data.type &&
  3032. list_data.delimiter === item_data.delimiter &&
  3033. list_data.bullet_char === item_data.bullet_char);
  3034. };
  3035. // Analyze a line of text and update the document appropriately.
  3036. // We parse markdown text by calling this on each line of input,
  3037. // then finalizing the document.
  3038. var incorporateLine = function(ln, line_number) {
  3039. var all_matched = true;
  3040. var last_child;
  3041. var first_nonspace;
  3042. var offset = 0;
  3043. var match;
  3044. var data;
  3045. var blank;
  3046. var indent;
  3047. var last_matched_container;
  3048. var i;
  3049. var CODE_INDENT = 4;
  3050. var container = this.doc;
  3051. var oldtip = this.tip;
  3052. // Convert tabs to spaces:
  3053. ln = detabLine(ln);
  3054. // For each containing block, try to parse the associated line start.
  3055. // Bail out on failure: container will point to the last matching block.
  3056. // Set all_matched to false if not all containers match.
  3057. while (container.children.length > 0) {
  3058. last_child = container.children[container.children.length - 1];
  3059. if (!last_child.open) {
  3060. break;
  3061. }
  3062. container = last_child;
  3063. match = matchAt(/[^ ]/, ln, offset);
  3064. if (match === null) {
  3065. first_nonspace = ln.length;
  3066. blank = true;
  3067. } else {
  3068. first_nonspace = match;
  3069. blank = false;
  3070. }
  3071. indent = first_nonspace - offset;
  3072. switch (container.t) {
  3073. case 'BlockQuote':
  3074. var matched = indent <= 3 && ln.charAt(first_nonspace) === '>';
  3075. if (matched) {
  3076. offset = first_nonspace + 1;
  3077. if (ln.charAt(offset) === ' ') {
  3078. offset++;
  3079. }
  3080. } else {
  3081. all_matched = false;
  3082. }
  3083. break;
  3084. case 'ListItem':
  3085. if (indent >= container.list_data.marker_offset +
  3086. container.list_data.padding) {
  3087. offset += container.list_data.marker_offset +
  3088. container.list_data.padding;
  3089. } else if (blank) {
  3090. offset = first_nonspace;
  3091. } else {
  3092. all_matched = false;
  3093. }
  3094. break;
  3095. case 'IndentedCode':
  3096. if (indent >= CODE_INDENT) {
  3097. offset += CODE_INDENT;
  3098. } else if (blank) {
  3099. offset = first_nonspace;
  3100. } else {
  3101. all_matched = false;
  3102. }
  3103. break;
  3104. case 'ATXHeader':
  3105. case 'SetextHeader':
  3106. case 'HorizontalRule':
  3107. // a header can never container > 1 line, so fail to match:
  3108. all_matched = false;
  3109. break;
  3110. case 'FencedCode':
  3111. // skip optional spaces of fence offset
  3112. i = container.fence_offset;
  3113. while (i > 0 && ln.charAt(offset) === ' ') {
  3114. offset++;
  3115. i--;
  3116. }
  3117. break;
  3118. case 'HtmlBlock':
  3119. if (blank) {
  3120. all_matched = false;
  3121. }
  3122. break;
  3123. case 'Paragraph':
  3124. if (blank) {
  3125. container.last_line_blank = true;
  3126. all_matched = false;
  3127. }
  3128. break;
  3129. default:
  3130. }
  3131. if (!all_matched) {
  3132. container = container.parent; // back up to last matching block
  3133. break;
  3134. }
  3135. }
  3136. last_matched_container = container;
  3137. // This function is used to finalize and close any unmatched
  3138. // blocks. We aren't ready to do this now, because we might
  3139. // have a lazy paragraph continuation, in which case we don't
  3140. // want to close unmatched blocks. So we store this closure for
  3141. // use later, when we have more information.
  3142. var closeUnmatchedBlocks = function(mythis) {
  3143. // finalize any blocks not matched
  3144. while (!already_done && oldtip != last_matched_container) {
  3145. mythis.finalize(oldtip, line_number);
  3146. oldtip = oldtip.parent;
  3147. }
  3148. var already_done = true;
  3149. };
  3150. // Check to see if we've hit 2nd blank line; if so break out of list:
  3151. if (blank && container.last_line_blank) {
  3152. this.breakOutOfLists(container, line_number);
  3153. }
  3154. // Unless last matched container is a code block, try new container starts,
  3155. // adding children to the last matched container:
  3156. while (container.t != 'FencedCode' &&
  3157. container.t != 'IndentedCode' &&
  3158. container.t != 'HtmlBlock' &&
  3159. // this is a little performance optimization:
  3160. matchAt(/^[ #`~*+_=<>0-9-]/,ln,offset) !== null) {
  3161. match = matchAt(/[^ ]/, ln, offset);
  3162. if (match === null) {
  3163. first_nonspace = ln.length;
  3164. blank = true;
  3165. } else {
  3166. first_nonspace = match;
  3167. blank = false;
  3168. }
  3169. indent = first_nonspace - offset;
  3170. if (indent >= CODE_INDENT) {
  3171. // indented code
  3172. if (this.tip.t != 'Paragraph' && !blank) {
  3173. offset += CODE_INDENT;
  3174. closeUnmatchedBlocks(this);
  3175. container = this.addChild('IndentedCode', line_number, offset);
  3176. } else { // indent > 4 in a lazy paragraph continuation
  3177. break;
  3178. }
  3179. } else if (ln.charAt(first_nonspace) === '>') {
  3180. // blockquote
  3181. offset = first_nonspace + 1;
  3182. // optional following space
  3183. if (ln.charAt(offset) === ' ') {
  3184. offset++;
  3185. }
  3186. closeUnmatchedBlocks(this);
  3187. container = this.addChild('BlockQuote', line_number, offset);
  3188. } else if ((match = ln.slice(first_nonspace).match(/^#{1,6}(?: +|$)/))) {
  3189. // ATX header
  3190. offset = first_nonspace + match[0].length;
  3191. closeUnmatchedBlocks(this);
  3192. container = this.addChild('ATXHeader', line_number, first_nonspace);
  3193. container.level = match[0].trim().length; // number of #s
  3194. // remove trailing ###s:
  3195. container.strings =
  3196. [ln.slice(offset).replace(/(?:(\\#) *#*| *#+) *$/,'$1')];
  3197. break;
  3198. } else if ((match = ln.slice(first_nonspace).match(/^`{3,}(?!.*`)|^~{3,}(?!.*~)/))) {
  3199. // fenced code block
  3200. var fence_length = match[0].length;
  3201. closeUnmatchedBlocks(this);
  3202. container = this.addChild('FencedCode', line_number, first_nonspace);
  3203. container.fence_length = fence_length;
  3204. container.fence_char = match[0][0];
  3205. container.fence_offset = first_nonspace - offset;
  3206. offset = first_nonspace + fence_length;
  3207. break;
  3208. } else if (matchAt(reHtmlBlockOpen, ln, first_nonspace) !== null) {
  3209. // html block
  3210. closeUnmatchedBlocks(this);
  3211. container = this.addChild('HtmlBlock', line_number, first_nonspace);
  3212. // note, we don't adjust offset because the tag is part of the text
  3213. break;
  3214. } else if (container.t == 'Paragraph' &&
  3215. container.strings.length === 1 &&
  3216. ((match = ln.slice(first_nonspace).match(/^(?:=+|-+) *$/)))) {
  3217. // setext header line
  3218. closeUnmatchedBlocks(this);
  3219. container.t = 'SetextHeader'; // convert Paragraph to SetextHeader
  3220. container.level = match[0][0] === '=' ? 1 : 2;
  3221. offset = ln.length;
  3222. } else if (matchAt(reHrule, ln, first_nonspace) !== null) {
  3223. // hrule
  3224. closeUnmatchedBlocks(this);
  3225. container = this.addChild('HorizontalRule', line_number, first_nonspace);
  3226. offset = ln.length - 1;
  3227. break;
  3228. } else if ((data = parseListMarker(ln, first_nonspace))) {
  3229. // list item
  3230. closeUnmatchedBlocks(this);
  3231. data.marker_offset = indent;
  3232. offset = first_nonspace + data.padding;
  3233. // add the list if needed
  3234. if (container.t !== 'List' ||
  3235. !(listsMatch(container.list_data, data))) {
  3236. container = this.addChild('List', line_number, first_nonspace);
  3237. container.list_data = data;
  3238. }
  3239. // add the list item
  3240. container = this.addChild('ListItem', line_number, first_nonspace);
  3241. container.list_data = data;
  3242. } else {
  3243. break;
  3244. }
  3245. if (acceptsLines(container.t)) {
  3246. // if it's a line container, it can't contain other containers
  3247. break;
  3248. }
  3249. }
  3250. // What remains at the offset is a text line. Add the text to the
  3251. // appropriate container.
  3252. match = matchAt(/[^ ]/, ln, offset);
  3253. if (match === null) {
  3254. first_nonspace = ln.length;
  3255. blank = true;
  3256. } else {
  3257. first_nonspace = match;
  3258. blank = false;
  3259. }
  3260. indent = first_nonspace - offset;
  3261. // First check for a lazy paragraph continuation:
  3262. if (this.tip !== last_matched_container &&
  3263. !blank &&
  3264. this.tip.t == 'Paragraph' &&
  3265. this.tip.strings.length > 0) {
  3266. // lazy paragraph continuation
  3267. this.last_line_blank = false;
  3268. this.addLine(ln, offset);
  3269. } else { // not a lazy continuation
  3270. // finalize any blocks not matched
  3271. closeUnmatchedBlocks(this);
  3272. // Block quote lines are never blank as they start with >
  3273. // and we don't count blanks in fenced code for purposes of tight/loose
  3274. // lists or breaking out of lists. We also don't set last_line_blank
  3275. // on an empty list item.
  3276. container.last_line_blank = blank &&
  3277. !(container.t == 'BlockQuote' ||
  3278. container.t == 'FencedCode' ||
  3279. (container.t == 'ListItem' &&
  3280. container.children.length === 0 &&
  3281. container.start_line == line_number));
  3282. var cont = container;
  3283. while (cont.parent) {
  3284. cont.parent.last_line_blank = false;
  3285. cont = cont.parent;
  3286. }
  3287. switch (container.t) {
  3288. case 'IndentedCode':
  3289. case 'HtmlBlock':
  3290. this.addLine(ln, offset);
  3291. break;
  3292. case 'FencedCode':
  3293. // check for closing code fence:
  3294. match = (indent <= 3 &&
  3295. ln.charAt(first_nonspace) == container.fence_char &&
  3296. ln.slice(first_nonspace).match(/^(?:`{3,}|~{3,})(?= *$)/));
  3297. if (match && match[0].length >= container.fence_length) {
  3298. // don't add closing fence to container; instead, close it:
  3299. this.finalize(container, line_number);
  3300. } else {
  3301. this.addLine(ln, offset);
  3302. }
  3303. break;
  3304. case 'ATXHeader':
  3305. case 'SetextHeader':
  3306. case 'HorizontalRule':
  3307. // nothing to do; we already added the contents.
  3308. break;
  3309. default:
  3310. if (acceptsLines(container.t)) {
  3311. this.addLine(ln, first_nonspace);
  3312. } else if (blank) {
  3313. // do nothing
  3314. } else if (container.t != 'HorizontalRule' &&
  3315. container.t != 'SetextHeader') {
  3316. // create paragraph container for line
  3317. container = this.addChild('Paragraph', line_number, first_nonspace);
  3318. this.addLine(ln, first_nonspace);
  3319. } else {
  3320. console.log("Line " + line_number.toString() +
  3321. " with container type " + container.t +
  3322. " did not match any condition.");
  3323. }
  3324. }
  3325. }
  3326. };
  3327. // Finalize a block. Close it and do any necessary postprocessing,
  3328. // e.g. creating string_content from strings, setting the 'tight'
  3329. // or 'loose' status of a list, and parsing the beginnings
  3330. // of paragraphs for reference definitions. Reset the tip to the
  3331. // parent of the closed block.
  3332. var finalize = function(block, line_number) {
  3333. var pos;
  3334. // don't do anything if the block is already closed
  3335. if (!block.open) {
  3336. return 0;
  3337. }
  3338. block.open = false;
  3339. if (line_number > block.start_line) {
  3340. block.end_line = line_number - 1;
  3341. } else {
  3342. block.end_line = line_number;
  3343. }
  3344. switch (block.t) {
  3345. case 'Paragraph':
  3346. block.string_content = block.strings.join('\n').replace(/^ */m,'');
  3347. // try parsing the beginning as link reference definitions:
  3348. while (block.string_content.charAt(0) === '[' &&
  3349. (pos = this.inlineParser.parseReference(block.string_content,
  3350. this.refmap))) {
  3351. block.string_content = block.string_content.slice(pos);
  3352. if (isBlank(block.string_content)) {
  3353. block.t = 'ReferenceDef';
  3354. break;
  3355. }
  3356. }
  3357. break;
  3358. case 'ATXHeader':
  3359. case 'SetextHeader':
  3360. case 'HtmlBlock':
  3361. block.string_content = block.strings.join('\n');
  3362. break;
  3363. case 'IndentedCode':
  3364. block.string_content = block.strings.join('\n').replace(/(\n *)*$/,'\n');
  3365. break;
  3366. case 'FencedCode':
  3367. // first line becomes info string
  3368. block.info = unescapeBS(block.strings[0].trim());
  3369. if (block.strings.length == 1) {
  3370. block.string_content = '';
  3371. } else {
  3372. block.string_content = block.strings.slice(1).join('\n') + '\n';
  3373. }
  3374. break;
  3375. case 'List':
  3376. block.tight = true; // tight by default
  3377. var numitems = block.children.length;
  3378. var i = 0;
  3379. while (i < numitems) {
  3380. var item = block.children[i];
  3381. // check for non-final list item ending with blank line:
  3382. var last_item = i == numitems - 1;
  3383. if (endsWithBlankLine(item) && !last_item) {
  3384. block.tight = false;
  3385. break;
  3386. }
  3387. // recurse into children of list item, to see if there are
  3388. // spaces between any of them:
  3389. var numsubitems = item.children.length;
  3390. var j = 0;
  3391. while (j < numsubitems) {
  3392. var subitem = item.children[j];
  3393. var last_subitem = j == numsubitems - 1;
  3394. if (endsWithBlankLine(subitem) && !(last_item && last_subitem)) {
  3395. block.tight = false;
  3396. break;
  3397. }
  3398. j++;
  3399. }
  3400. i++;
  3401. }
  3402. break;
  3403. default:
  3404. break;
  3405. }
  3406. this.tip = block.parent || this.top;
  3407. };
  3408. // Walk through a block & children recursively, parsing string content
  3409. // into inline content where appropriate.
  3410. var processInlines = function(block) {
  3411. switch(block.t) {
  3412. case 'Paragraph':
  3413. case 'SetextHeader':
  3414. case 'ATXHeader':
  3415. block.inline_content =
  3416. this.inlineParser.parse(block.string_content.trim(), this.refmap);
  3417. block.string_content = "";
  3418. break;
  3419. default:
  3420. break;
  3421. }
  3422. if (block.children) {
  3423. for (var i = 0; i < block.children.length; i++) {
  3424. this.processInlines(block.children[i]);
  3425. }
  3426. }
  3427. };
  3428. // The main parsing function. Returns a parsed document AST.
  3429. var parse = function(input) {
  3430. this.doc = makeBlock('Document', 1, 1);
  3431. this.tip = this.doc;
  3432. this.refmap = {};
  3433. var lines = input.replace(/\n$/,'').split(/\r\n|\n|\r/);
  3434. var len = lines.length;
  3435. for (var i = 0; i < len; i++) {
  3436. this.incorporateLine(lines[i], i+1);
  3437. }
  3438. while (this.tip) {
  3439. this.finalize(this.tip, len - 1);
  3440. }
  3441. this.processInlines(this.doc);
  3442. return this.doc;
  3443. };
  3444. // The DocParser object.
  3445. function DocParser(){
  3446. return {
  3447. doc: makeBlock('Document', 1, 1),
  3448. tip: this.doc,
  3449. refmap: {},
  3450. inlineParser: new InlineParser(),
  3451. breakOutOfLists: breakOutOfLists,
  3452. addLine: addLine,
  3453. addChild: addChild,
  3454. incorporateLine: incorporateLine,
  3455. finalize: finalize,
  3456. processInlines: processInlines,
  3457. parse: parse
  3458. };
  3459. }
  3460. // HTML RENDERER
  3461. // Helper function to produce content in a pair of HTML tags.
  3462. var inTags = function(tag, attribs, contents, selfclosing) {
  3463. var result = '<' + tag;
  3464. if (attribs) {
  3465. var i = 0;
  3466. var attrib;
  3467. while ((attrib = attribs[i]) !== undefined) {
  3468. result = result.concat(' ', attrib[0], '="', attrib[1], '"');
  3469. i++;
  3470. }
  3471. }
  3472. if (contents) {
  3473. result = result.concat('>', contents, '</', tag, '>');
  3474. } else if (selfclosing) {
  3475. result = result + ' />';
  3476. } else {
  3477. result = result.concat('></', tag, '>');
  3478. }
  3479. return result;
  3480. };
  3481. // Render an inline element as HTML.
  3482. var renderInline = function(inline) {
  3483. var attrs;
  3484. switch (inline.t) {
  3485. case 'Str':
  3486. return this.escape(inline.c);
  3487. case 'Softbreak':
  3488. return this.softbreak;
  3489. case 'Hardbreak':
  3490. return inTags('br',[],"",true) + '\n';
  3491. case 'Emph':
  3492. return inTags('em', [], this.renderInlines(inline.c));
  3493. case 'Strong':
  3494. return inTags('strong', [], this.renderInlines(inline.c));
  3495. case 'Html':
  3496. return inline.c;
  3497. case 'Link':
  3498. attrs = [['href', this.escape(inline.destination, true)]];
  3499. if (inline.title) {
  3500. attrs.push(['title', this.escape(inline.title, true)]);
  3501. }
  3502. return inTags('a', attrs, this.renderInlines(inline.label));
  3503. case 'Image':
  3504. attrs = [['src', this.escape(inline.destination, true)],
  3505. ['alt', this.escape(this.renderInlines(inline.label))]];
  3506. if (inline.title) {
  3507. attrs.push(['title', this.escape(inline.title, true)]);
  3508. }
  3509. return inTags('img', attrs, "", true);
  3510. case 'Code':
  3511. return inTags('code', [], this.escape(inline.c));
  3512. default:
  3513. console.log("Unknown inline type " + inline.t);
  3514. return "";
  3515. }
  3516. };
  3517. // Render a list of inlines.
  3518. var renderInlines = function(inlines) {
  3519. var result = '';
  3520. for (var i=0; i < inlines.length; i++) {
  3521. result = result + this.renderInline(inlines[i]);
  3522. }
  3523. return result;
  3524. };
  3525. // Render a single block element.
  3526. var renderBlock = function(block, in_tight_list) {
  3527. var tag;
  3528. var attr;
  3529. var info_words;
  3530. switch (block.t) {
  3531. case 'Document':
  3532. var whole_doc = this.renderBlocks(block.children);
  3533. return (whole_doc === '' ? '' : whole_doc + '\n');
  3534. case 'Paragraph':
  3535. if (in_tight_list) {
  3536. return this.renderInlines(block.inline_content);
  3537. } else {
  3538. return inTags('p', [], this.renderInlines(block.inline_content));
  3539. }
  3540. break;
  3541. case 'BlockQuote':
  3542. var filling = this.renderBlocks(block.children);
  3543. return inTags('blockquote', [], filling === '' ? this.innersep :
  3544. this.innersep + this.renderBlocks(block.children) + this.innersep);
  3545. case 'ListItem':
  3546. return inTags('li', [], this.renderBlocks(block.children, in_tight_list).trim());
  3547. case 'List':
  3548. tag = block.list_data.type == 'Bullet' ? 'ul' : 'ol';
  3549. attr = (!block.list_data.start || block.list_data.start == 1) ?
  3550. [] : [['start', block.list_data.start.toString()]];
  3551. return inTags(tag, attr, this.innersep +
  3552. this.renderBlocks(block.children, block.tight) +
  3553. this.innersep);
  3554. case 'ATXHeader':
  3555. case 'SetextHeader':
  3556. tag = 'h' + block.level;
  3557. return inTags(tag, [], this.renderInlines(block.inline_content));
  3558. case 'IndentedCode':
  3559. return inTags('pre', [],
  3560. inTags('code', [], this.escape(block.string_content)));
  3561. case 'FencedCode':
  3562. info_words = block.info.split(/ +/);
  3563. attr = info_words.length === 0 || info_words[0].length === 0 ?
  3564. [] : [['class','language-' +
  3565. this.escape(info_words[0],true)]];
  3566. return inTags('pre', [],
  3567. inTags('code', attr, this.escape(block.string_content)));
  3568. case 'HtmlBlock':
  3569. return block.string_content;
  3570. case 'ReferenceDef':
  3571. return "";
  3572. case 'HorizontalRule':
  3573. return inTags('hr',[],"",true);
  3574. default:
  3575. console.log("Unknown block type " + block.t);
  3576. return "";
  3577. }
  3578. };
  3579. // Render a list of block elements, separated by this.blocksep.
  3580. var renderBlocks = function(blocks, in_tight_list) {
  3581. var result = [];
  3582. for (var i=0; i < blocks.length; i++) {
  3583. if (blocks[i].t !== 'ReferenceDef') {
  3584. result.push(this.renderBlock(blocks[i], in_tight_list));
  3585. }
  3586. }
  3587. return result.join(this.blocksep);
  3588. };
  3589. // The HtmlRenderer object.
  3590. function HtmlRenderer(){
  3591. return {
  3592. // default options:
  3593. blocksep: '\n', // space between blocks
  3594. innersep: '\n', // space between block container tag and contents
  3595. softbreak: '\n', // by default, soft breaks are rendered as newlines in HTML
  3596. // set to "<br />" to make them hard breaks
  3597. // set to " " if you want to ignore line wrapping in source
  3598. escape: function(s, preserve_entities) {
  3599. if (preserve_entities) {
  3600. return s.replace(/[&](?![#](x[a-f0-9]{1,8}|[0-9]{1,8});|[a-z][a-z0-9]{1,31};)/gi,'&amp;')
  3601. .replace(/[<]/g,'&lt;')
  3602. .replace(/[>]/g,'&gt;')
  3603. .replace(/["]/g,'&quot;');
  3604. } else {
  3605. return s.replace(/[&]/g,'&amp;')
  3606. .replace(/[<]/g,'&lt;')
  3607. .replace(/[>]/g,'&gt;')
  3608. .replace(/["]/g,'&quot;');
  3609. }
  3610. },
  3611. renderInline: renderInline,
  3612. renderInlines: renderInlines,
  3613. renderBlock: renderBlock,
  3614. renderBlocks: renderBlocks,
  3615. render: renderBlock
  3616. };
  3617. }
  3618. exports.DocParser = DocParser;
  3619. exports.HtmlRenderer = HtmlRenderer;
  3620. })(typeof exports === 'undefined' ? this.stmd = {} : exports);