aboutsummaryrefslogtreecommitdiff
path: root/js/stmd.js
blob: efccad80ecfb9025ce9d923bb7066d84b84428b8 (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. // Constants for character codes:
  2137. var C_NEWLINE = 10;
  2138. var C_SPACE = 32;
  2139. var C_ASTERISK = 42;
  2140. var C_UNDERSCORE = 95;
  2141. var C_BACKTICK = 96;
  2142. var C_OPEN_BRACKET = 91;
  2143. var C_CLOSE_BRACKET = 93;
  2144. var C_LESSTHAN = 60;
  2145. var C_GREATERTHAN = 62;
  2146. var C_BANG = 33;
  2147. var C_BACKSLASH = 92;
  2148. var C_AMPERSAND = 38;
  2149. var C_OPEN_PAREN = 40;
  2150. var C_COLON = 58;
  2151. // Some regexps used in inline parser:
  2152. var ESCAPABLE = '[!"#$%&\'()*+,./:;<=>?@[\\\\\\]^_`{|}~-]';
  2153. var ESCAPED_CHAR = '\\\\' + ESCAPABLE;
  2154. var IN_DOUBLE_QUOTES = '"(' + ESCAPED_CHAR + '|[^"\\x00])*"';
  2155. var IN_SINGLE_QUOTES = '\'(' + ESCAPED_CHAR + '|[^\'\\x00])*\'';
  2156. var IN_PARENS = '\\((' + ESCAPED_CHAR + '|[^)\\x00])*\\)';
  2157. var REG_CHAR = '[^\\\\()\\x00-\\x20]';
  2158. var IN_PARENS_NOSP = '\\((' + REG_CHAR + '|' + ESCAPED_CHAR + ')*\\)';
  2159. var TAGNAME = '[A-Za-z][A-Za-z0-9]*';
  2160. 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)';
  2161. var ATTRIBUTENAME = '[a-zA-Z_:][a-zA-Z0-9:._-]*';
  2162. var UNQUOTEDVALUE = "[^\"'=<>`\\x00-\\x20]+";
  2163. var SINGLEQUOTEDVALUE = "'[^']*'";
  2164. var DOUBLEQUOTEDVALUE = '"[^"]*"';
  2165. var ATTRIBUTEVALUE = "(?:" + UNQUOTEDVALUE + "|" + SINGLEQUOTEDVALUE + "|" + DOUBLEQUOTEDVALUE + ")";
  2166. var ATTRIBUTEVALUESPEC = "(?:" + "\\s*=" + "\\s*" + ATTRIBUTEVALUE + ")";
  2167. var ATTRIBUTE = "(?:" + "\\s+" + ATTRIBUTENAME + ATTRIBUTEVALUESPEC + "?)";
  2168. var OPENTAG = "<" + TAGNAME + ATTRIBUTE + "*" + "\\s*/?>";
  2169. var CLOSETAG = "</" + TAGNAME + "\\s*[>]";
  2170. var OPENBLOCKTAG = "<" + BLOCKTAGNAME + ATTRIBUTE + "*" + "\\s*/?>";
  2171. var CLOSEBLOCKTAG = "</" + BLOCKTAGNAME + "\\s*[>]";
  2172. var HTMLCOMMENT = "<!--([^-]+|[-][^-]+)*-->";
  2173. var PROCESSINGINSTRUCTION = "[<][?].*?[?][>]";
  2174. var DECLARATION = "<![A-Z]+" + "\\s+[^>]*>";
  2175. var CDATA = "<!\\[CDATA\\[([^\\]]+|\\][^\\]]|\\]\\][^>])*\\]\\]>";
  2176. var HTMLTAG = "(?:" + OPENTAG + "|" + CLOSETAG + "|" + HTMLCOMMENT + "|" +
  2177. PROCESSINGINSTRUCTION + "|" + DECLARATION + "|" + CDATA + ")";
  2178. var HTMLBLOCKOPEN = "<(?:" + BLOCKTAGNAME + "[\\s/>]" + "|" +
  2179. "/" + BLOCKTAGNAME + "[\\s>]" + "|" + "[?!])";
  2180. var ENTITY = "&(?:#x[a-f0-9]{1,8}|#[0-9]{1,8}|[a-z][a-z0-9]{1,31});"
  2181. var reHtmlTag = new RegExp('^' + HTMLTAG, 'i');
  2182. var reHtmlBlockOpen = new RegExp('^' + HTMLBLOCKOPEN, 'i');
  2183. var reLinkTitle = new RegExp(
  2184. '^(?:"(' + ESCAPED_CHAR + '|[^"\\x00])*"' +
  2185. '|' +
  2186. '\'(' + ESCAPED_CHAR + '|[^\'\\x00])*\'' +
  2187. '|' +
  2188. '\\((' + ESCAPED_CHAR + '|[^)\\x00])*\\))');
  2189. var reLinkDestinationBraces = new RegExp(
  2190. '^(?:[<](?:[^<>\\n\\\\\\x00]' + '|' + ESCAPED_CHAR + '|' + '\\\\)*[>])');
  2191. var reLinkDestination = new RegExp(
  2192. '^(?:' + REG_CHAR + '+|' + ESCAPED_CHAR + '|' + IN_PARENS_NOSP + ')*');
  2193. var reEscapable = new RegExp(ESCAPABLE);
  2194. var reAllEscapedChar = new RegExp('\\\\(' + ESCAPABLE + ')', 'g');
  2195. var reEscapedChar = new RegExp('^\\\\(' + ESCAPABLE + ')');
  2196. var reAllTab = /\t/g;
  2197. var reHrule = /^(?:(?:\* *){3,}|(?:_ *){3,}|(?:- *){3,}) *$/;
  2198. var reEntityHere = new RegExp('^' + ENTITY, 'i');
  2199. var reEntity = new RegExp(ENTITY, 'gi');
  2200. // Matches a character with a special meaning in markdown,
  2201. // or a string of non-special characters. Note: we match
  2202. // clumps of _ or * or `, because they need to be handled in groups.
  2203. var reMain = /^(?:[_*`\n]+|[\[\]\\!<&*_]|(?: *[^\n `\[\]\\!<&*_]+)+|[ \n]+)/m;
  2204. // UTILITY FUNCTIONS
  2205. var entityToChar = function(m) {
  2206. var isNumeric = /^&#/.test(m);
  2207. var isHex = /^&#[Xx]/.test(m);
  2208. var uchar;
  2209. if (isNumeric) {
  2210. var num;
  2211. if (isHex) {
  2212. num = parseInt(m.slice(3,-1), 16);
  2213. } else {
  2214. num = parseInt(m.slice(2,-1), 10);
  2215. }
  2216. uchar = String.fromCharCode(num);
  2217. } else {
  2218. uchar = entities[m.slice(1,-1)];
  2219. }
  2220. return (uchar || m);
  2221. }
  2222. // Replace entities and backslash escapes with literal characters.
  2223. var unescapeEntBS = function(s) {
  2224. return s.replace(reAllEscapedChar, '$1')
  2225. .replace(reEntity, entityToChar);;
  2226. };
  2227. // Returns true if string contains only space characters.
  2228. var isBlank = function(s) {
  2229. return /^\s*$/.test(s);
  2230. };
  2231. // Normalize reference label: collapse internal whitespace
  2232. // to single space, remove leading/trailing whitespace, case fold.
  2233. var normalizeReference = function(s) {
  2234. return s.trim()
  2235. .replace(/\s+/,' ')
  2236. .toUpperCase();
  2237. };
  2238. // Attempt to match a regex in string s at offset offset.
  2239. // Return index of match or null.
  2240. var matchAt = function(re, s, offset) {
  2241. var res = s.slice(offset).match(re);
  2242. if (res) {
  2243. return offset + res.index;
  2244. } else {
  2245. return null;
  2246. }
  2247. };
  2248. // Convert tabs to spaces on each line using a 4-space tab stop.
  2249. var detabLine = function(text) {
  2250. if (text.indexOf('\t') == -1) {
  2251. return text;
  2252. } else {
  2253. var lastStop = 0;
  2254. return text.replace(reAllTab, function(match, offset) {
  2255. var result = ' '.slice((offset - lastStop) % 4);
  2256. lastStop = offset + 1;
  2257. return result;
  2258. });
  2259. }
  2260. };
  2261. // INLINE PARSER
  2262. // These are methods of an InlineParser object, defined below.
  2263. // An InlineParser keeps track of a subject (a string to be
  2264. // parsed) and a position in that subject.
  2265. // If re matches at current position in the subject, advance
  2266. // position in subject and return the match; otherwise return null.
  2267. var match = function(re) {
  2268. var match = re.exec(this.subject.slice(this.pos));
  2269. if (match) {
  2270. this.pos += match.index + match[0].length;
  2271. return match[0];
  2272. } else {
  2273. return null;
  2274. }
  2275. };
  2276. // Returns the code for the character at the current subject position, or -1
  2277. // there are no more characters.
  2278. var peek = function() {
  2279. if (this.pos < this.subject.length) {
  2280. return this.subject.charCodeAt(this.pos);
  2281. } else {
  2282. return -1;
  2283. }
  2284. };
  2285. // Parse zero or more space characters, including at most one newline
  2286. var spnl = function() {
  2287. this.match(/^ *(?:\n *)?/);
  2288. return 1;
  2289. };
  2290. // All of the parsers below try to match something at the current position
  2291. // in the subject. If they succeed in matching anything, they
  2292. // return the inline matched, advancing the subject.
  2293. // Attempt to parse backticks, returning either a backtick code span or a
  2294. // literal sequence of backticks.
  2295. var parseBackticks = function(inlines) {
  2296. var startpos = this.pos;
  2297. var ticks = this.match(/^`+/);
  2298. if (!ticks) {
  2299. return 0;
  2300. }
  2301. var afterOpenTicks = this.pos;
  2302. var foundCode = false;
  2303. var match;
  2304. while (!foundCode && (match = this.match(/`+/m))) {
  2305. if (match == ticks) {
  2306. inlines.push({ t: 'Code', c: this.subject.slice(afterOpenTicks,
  2307. this.pos - ticks.length)
  2308. .replace(/[ \n]+/g,' ')
  2309. .trim() });
  2310. return true;
  2311. }
  2312. }
  2313. // If we got here, we didn't match a closing backtick sequence.
  2314. this.pos = afterOpenTicks;
  2315. inlines.push({ t: 'Str', c: ticks });
  2316. return true;
  2317. };
  2318. // Parse a backslash-escaped special character, adding either the escaped
  2319. // character, a hard line break (if the backslash is followed by a newline),
  2320. // or a literal backslash to the 'inlines' list.
  2321. var parseBackslash = function(inlines) {
  2322. var subj = this.subject,
  2323. pos = this.pos;
  2324. if (subj.charCodeAt(pos) === C_BACKSLASH) {
  2325. if (subj.charAt(pos + 1) === '\n') {
  2326. this.pos = this.pos + 2;
  2327. inlines.push({ t: 'Hardbreak' });
  2328. } else if (reEscapable.test(subj.charAt(pos + 1))) {
  2329. this.pos = this.pos + 2;
  2330. inlines.push({ t: 'Str', c: subj.charAt(pos + 1) });
  2331. } else {
  2332. this.pos++;
  2333. inlines.push({t: 'Str', c: '\\'});
  2334. }
  2335. return true;
  2336. } else {
  2337. return false;
  2338. }
  2339. };
  2340. // Attempt to parse an autolink (URL or email in pointy brackets).
  2341. var parseAutolink = function(inlines) {
  2342. var m;
  2343. var dest;
  2344. 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
  2345. dest = m.slice(1,-1);
  2346. inlines.push(
  2347. {t: 'Link',
  2348. label: [{ t: 'Str', c: dest }],
  2349. destination: 'mailto:' + encodeURI(unescape(dest)) });
  2350. return true;
  2351. } 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))) {
  2352. dest = m.slice(1,-1);
  2353. inlines.push({
  2354. t: 'Link',
  2355. label: [{ t: 'Str', c: dest }],
  2356. destination: encodeURI(unescape(dest)) });
  2357. return true;
  2358. } else {
  2359. return false;
  2360. }
  2361. };
  2362. // Attempt to parse a raw HTML tag.
  2363. var parseHtmlTag = function(inlines) {
  2364. var m = this.match(reHtmlTag);
  2365. if (m) {
  2366. inlines.push({ t: 'Html', c: m });
  2367. return true;
  2368. } else {
  2369. return false;
  2370. }
  2371. };
  2372. // Scan a sequence of characters with code cc, and return information about
  2373. // the number of delimiters and whether they are positioned such that
  2374. // they can open and/or close emphasis or strong emphasis. A utility
  2375. // function for strong/emph parsing.
  2376. var scanDelims = function(cc) {
  2377. var numdelims = 0;
  2378. var first_close_delims = 0;
  2379. var char_before, char_after, cc_after;
  2380. var startpos = this.pos;
  2381. char_before = this.pos === 0 ? '\n' :
  2382. this.subject.charAt(this.pos - 1);
  2383. while (this.peek() === cc) {
  2384. numdelims++;
  2385. this.pos++;
  2386. }
  2387. cc_after = this.peek();
  2388. if (cc_after === -1) {
  2389. char_after = '\n';
  2390. } else {
  2391. char_after = String.fromCharCode(cc_after);
  2392. }
  2393. var can_open = numdelims > 0 && numdelims <= 3 && !(/\s/.test(char_after));
  2394. var can_close = numdelims > 0 && numdelims <= 3 && !(/\s/.test(char_before));
  2395. if (cc === C_UNDERSCORE) {
  2396. can_open = can_open && !((/[a-z0-9]/i).test(char_before));
  2397. can_close = can_close && !((/[a-z0-9]/i).test(char_after));
  2398. }
  2399. this.pos = startpos;
  2400. return { numdelims: numdelims,
  2401. can_open: can_open,
  2402. can_close: can_close };
  2403. };
  2404. var Emph = function(ils) {
  2405. return {t: 'Emph', c: ils};
  2406. }
  2407. var Strong = function(ils) {
  2408. return {t: 'Strong', c: ils};
  2409. }
  2410. var Str = function(s) {
  2411. return {t: 'Str', c: s};
  2412. }
  2413. // Attempt to parse emphasis or strong emphasis.
  2414. var parseEmphasis = function(cc,inlines) {
  2415. var startpos = this.pos;
  2416. var c ;
  2417. var first_close = 0;
  2418. c = String.fromCharCode(cc);
  2419. var numdelims;
  2420. var delimpos;
  2421. // Get opening delimiters.
  2422. res = this.scanDelims(cc);
  2423. numdelims = res.numdelims;
  2424. if (numdelims === 0) {
  2425. this.pos = startpos;
  2426. return false;
  2427. }
  2428. if (numdelims >= 4 || !res.can_open) {
  2429. this.pos += numdelims;
  2430. inlines.push(Str(this.subject.slice(startpos, startpos + numdelims)));
  2431. return true;
  2432. }
  2433. this.pos += numdelims;
  2434. var fallbackpos = this.pos;
  2435. var next_inline;
  2436. var first = [];
  2437. var second = [];
  2438. var current = first;
  2439. var state = 0;
  2440. var can_close = false;
  2441. var can_open = false;
  2442. var last_emphasis_closer = null;
  2443. if (numdelims === 3) {
  2444. state = 1;
  2445. } else if (numdelims === 2) {
  2446. state = 2;
  2447. } else if (numdelims === 1) {
  2448. state = 3;
  2449. }
  2450. while (true) {
  2451. if (this.last_emphasis_closer[c] < this.pos) {
  2452. break;
  2453. }
  2454. res = this.scanDelims(cc);
  2455. if (res) {
  2456. numdelims = res.numdelims;
  2457. can_close = res.can_close;
  2458. if (can_close) {
  2459. last_emphasis_closer = this.pos;
  2460. }
  2461. can_open = res.can_open;
  2462. switch (state) {
  2463. case 1: // ***a
  2464. if (numdelims === 3 && can_close) {
  2465. this.pos += 3;
  2466. inlines.push(Strong([Emph(first)]));
  2467. return true;
  2468. } else if (numdelims === 2 && can_close) {
  2469. this.pos += 2;
  2470. current = second;
  2471. state = can_open ? 4 : 6;
  2472. continue;
  2473. } else if (numdelims === 1 && can_close) {
  2474. this.pos += 1;
  2475. current = second;
  2476. state = can_open ? 5 : 7;
  2477. continue;
  2478. }
  2479. break;
  2480. case 2: // **a
  2481. if (numdelims === 2 && can_close) {
  2482. this.pos += 2;
  2483. inlines.push(Strong(first));
  2484. return true;
  2485. } else if (numdelims === 1 && can_open) {
  2486. this.pos += 1;
  2487. current = second;
  2488. state = 8;
  2489. continue;
  2490. }
  2491. break;
  2492. case 3: // *a
  2493. if (numdelims === 1 && can_close) {
  2494. this.pos += 1;
  2495. inlines.push(Emph(first));
  2496. return true;
  2497. } else if (numdelims === 2 && can_open) {
  2498. this.pos += 2;
  2499. current = second;
  2500. state = 9;
  2501. continue;
  2502. }
  2503. break;
  2504. case 4: // ***a**b
  2505. if (numdelims === 3 && can_close) {
  2506. this.pos += 3;
  2507. inlines.push(Strong([Emph(first.concat([Str(c+c)], second))]));
  2508. return true;
  2509. } else if (numdelims === 2 && can_close) {
  2510. this.pos += 2;
  2511. inlines.push(Strong([Str(c+c+c)].concat(
  2512. first,
  2513. [Strong(second)])));
  2514. return true;
  2515. } else if (numdelims === 1 && can_close) {
  2516. this.pos += 1;
  2517. inlines.push(Emph([Strong(first)].concat(second)));
  2518. return true;
  2519. }
  2520. break;
  2521. case 5: // ***a*b
  2522. if (numdelims === 3 && can_close) {
  2523. this.pos += 3;
  2524. inlines.push(Strong([Emph(first.concat([Str(c)], second))]));
  2525. return true;
  2526. } else if (numdelims === 2 && can_close) {
  2527. this.pos += 2;
  2528. inlines.push(Strong([Emph(first)].concat(second)));
  2529. return true;
  2530. } else if (numdelims === 1 && can_close) {
  2531. this.pos += 1;
  2532. inlines.push(Strong([Str(c+c+c)].concat(
  2533. first,
  2534. [Emph(second)])));
  2535. return true;
  2536. }
  2537. break;
  2538. case 6: // ***a** b
  2539. if (numdelims === 3 && can_close) {
  2540. this.pos += 3;
  2541. inlines.push(Strong([Emph(first.concat([Str(c+c)], second))]));
  2542. return true;
  2543. } else if (numdelims === 1 && can_close) {
  2544. this.pos += 1;
  2545. inlines.push(Emph([Strong(first)].concat(second)));
  2546. return true;
  2547. }
  2548. break;
  2549. case 7: // ***a* b
  2550. if (numdelims === 3 && can_close) {
  2551. this.pos += 3;
  2552. inlines.push(Strong([Emph(first.concat([Str(c)], second))]));
  2553. return true;
  2554. } else if (numdelims === 2 && can_close) {
  2555. this.pos += 2;
  2556. inlines.push(Strong([Emph(first)].concat(second)));
  2557. return true;
  2558. }
  2559. break;
  2560. case 8: // **a *b
  2561. if (numdelims === 3 && can_close) {
  2562. this.pos += 3;
  2563. inlines.push(Strong(first.concat([Emph(second)])));
  2564. return true;
  2565. } else if (numdelims === 2 && can_close) {
  2566. this.pos += 2;
  2567. inlines.push(Strong(first.concat([Str(c)], second)));
  2568. return true;
  2569. } else if (numdelims === 1 && can_close) {
  2570. this.pos += 1;
  2571. first.push(Emph(second));
  2572. current = first;
  2573. state = 2;
  2574. continue;
  2575. }
  2576. break;
  2577. case 9: // *a **b
  2578. if (numdelims === 3 && can_close) {
  2579. this.pos += 3;
  2580. inlines.push(Emph(first.concat([Strong(second)])));
  2581. return true;
  2582. } else if (numdelims === 2 && can_close) {
  2583. this.pos += 2;
  2584. first.push(Strong(second));
  2585. current = first;
  2586. state = 3;
  2587. continue;
  2588. } else if (numdelims === 1 && can_close) {
  2589. this.pos += 1;
  2590. inlines.push(Emph(first.concat([Str(c+c)], second)));
  2591. return true;
  2592. }
  2593. break;
  2594. default:
  2595. break;
  2596. }
  2597. }
  2598. if (!(this.parseInline(current,true))) {
  2599. break;
  2600. }
  2601. }
  2602. // we didn't match emphasis: fallback
  2603. this.pos = fallbackpos;
  2604. if (last_emphasis_closer) {
  2605. this.last_emphasis_closer[c] = last_emphasis_closer;
  2606. }
  2607. inlines.push(Str(this.subject.slice(startpos, fallbackpos)));
  2608. return true;
  2609. };
  2610. // Attempt to parse link title (sans quotes), returning the string
  2611. // or null if no match.
  2612. var parseLinkTitle = function() {
  2613. var title = this.match(reLinkTitle);
  2614. if (title) {
  2615. // chop off quotes from title and unescape:
  2616. return unescapeEntBS(title.substr(1, title.length - 2));
  2617. } else {
  2618. return null;
  2619. }
  2620. };
  2621. // Attempt to parse link destination, returning the string or
  2622. // null if no match.
  2623. var parseLinkDestination = function() {
  2624. var res = this.match(reLinkDestinationBraces);
  2625. if (res) { // chop off surrounding <..>:
  2626. return encodeURI(unescape(unescapeEntBS(res.substr(1, res.length - 2))));
  2627. } else {
  2628. res = this.match(reLinkDestination);
  2629. if (res !== null) {
  2630. return encodeURI(unescape(unescapeEntBS(res)));
  2631. } else {
  2632. return null;
  2633. }
  2634. }
  2635. };
  2636. // Attempt to parse a link label, returning number of characters parsed.
  2637. var parseLinkLabel = function() {
  2638. if (this.peek() != C_OPEN_BRACKET) {
  2639. return 0;
  2640. }
  2641. var startpos = this.pos;
  2642. var nest_level = 0;
  2643. if (this.label_nest_level > 0) {
  2644. // If we've already checked to the end of this subject
  2645. // for a label, even with a different starting [, we
  2646. // know we won't find one here and we can just return.
  2647. // This avoids lots of backtracking.
  2648. // Note: nest level 1 would be: [foo [bar]
  2649. // nest level 2 would be: [foo [bar [baz]
  2650. this.label_nest_level--;
  2651. return 0;
  2652. }
  2653. this.pos++; // advance past [
  2654. var c;
  2655. while ((c = this.peek()) && c != -1 && (c != C_CLOSE_BRACKET || nest_level > 0)) {
  2656. switch (c) {
  2657. case C_BACKTICK:
  2658. this.parseBackticks([]);
  2659. break;
  2660. case C_LESSTHAN:
  2661. this.parseAutolink([]) || this.parseHtmlTag([]) ||
  2662. this.pos++;
  2663. break;
  2664. case C_OPEN_BRACKET: // nested []
  2665. nest_level++;
  2666. this.pos++;
  2667. break;
  2668. case C_CLOSE_BRACKET: // nested []
  2669. nest_level--;
  2670. this.pos++;
  2671. break;
  2672. case C_BACKSLASH:
  2673. this.parseBackslash([]);
  2674. break;
  2675. default:
  2676. this.parseString([]);
  2677. }
  2678. }
  2679. if (c === C_CLOSE_BRACKET) {
  2680. this.label_nest_level = 0;
  2681. this.pos++; // advance past ]
  2682. return this.pos - startpos;
  2683. } else {
  2684. if (c === -1) {
  2685. this.label_nest_level = nest_level;
  2686. }
  2687. this.pos = startpos;
  2688. return 0;
  2689. }
  2690. };
  2691. // Parse raw link label, including surrounding [], and return
  2692. // inline contents. (Note: this is not a method of InlineParser.)
  2693. var parseRawLabel = function(s) {
  2694. // note: parse without a refmap; we don't want links to resolve
  2695. // in nested brackets!
  2696. return new InlineParser().parse(s.substr(1, s.length - 2), {});
  2697. };
  2698. // Attempt to parse a link. If successful, return the link.
  2699. var parseLink = function(inlines) {
  2700. var startpos = this.pos;
  2701. var reflabel;
  2702. var n;
  2703. var dest;
  2704. var title;
  2705. n = this.parseLinkLabel();
  2706. if (n === 0) {
  2707. return false;
  2708. }
  2709. var afterlabel = this.pos;
  2710. var rawlabel = this.subject.substr(startpos, n);
  2711. // if we got this far, we've parsed a label.
  2712. // Try to parse an explicit link: [label](url "title")
  2713. if (this.peek() == C_OPEN_PAREN) {
  2714. this.pos++;
  2715. if (this.spnl() &&
  2716. ((dest = this.parseLinkDestination()) !== null) &&
  2717. this.spnl() &&
  2718. // make sure there's a space before the title:
  2719. (/^\s/.test(this.subject.charAt(this.pos - 1)) &&
  2720. (title = this.parseLinkTitle() || '') || true) &&
  2721. this.spnl() &&
  2722. this.match(/^\)/)) {
  2723. inlines.push({ t: 'Link',
  2724. destination: dest,
  2725. title: title,
  2726. label: parseRawLabel(rawlabel) });
  2727. return true;
  2728. } else {
  2729. this.pos = startpos;
  2730. return false;
  2731. }
  2732. }
  2733. // If we're here, it wasn't an explicit link. Try to parse a reference link.
  2734. // first, see if there's another label
  2735. var savepos = this.pos;
  2736. this.spnl();
  2737. var beforelabel = this.pos;
  2738. n = this.parseLinkLabel();
  2739. if (n == 2) {
  2740. // empty second label
  2741. reflabel = rawlabel;
  2742. } else if (n > 0) {
  2743. reflabel = this.subject.slice(beforelabel, beforelabel + n);
  2744. } else {
  2745. this.pos = savepos;
  2746. reflabel = rawlabel;
  2747. }
  2748. // lookup rawlabel in refmap
  2749. var link = this.refmap[normalizeReference(reflabel)];
  2750. if (link) {
  2751. inlines.push({t: 'Link',
  2752. destination: link.destination,
  2753. title: link.title,
  2754. label: parseRawLabel(rawlabel) });
  2755. return true;
  2756. } else {
  2757. this.pos = startpos;
  2758. return false;
  2759. }
  2760. // Nothing worked, rewind:
  2761. this.pos = startpos;
  2762. return false;
  2763. };
  2764. // Attempt to parse an entity, return Entity object if successful.
  2765. var parseEntity = function(inlines) {
  2766. var m;
  2767. if ((m = this.match(reEntityHere))) {
  2768. inlines.push({ t: 'Str', c: entityToChar(m) });
  2769. return true;
  2770. } else {
  2771. return false;
  2772. }
  2773. };
  2774. // Parse a run of ordinary characters, or a single character with
  2775. // a special meaning in markdown, as a plain string, adding to inlines.
  2776. var parseString = function(inlines) {
  2777. var m;
  2778. if ((m = this.match(reMain))) {
  2779. inlines.push({ t: 'Str', c: m });
  2780. return true;
  2781. } else {
  2782. return false;
  2783. }
  2784. };
  2785. // Parse a newline. If it was preceded by two spaces, return a hard
  2786. // line break; otherwise a soft line break.
  2787. var parseNewline = function(inlines) {
  2788. var m = this.match(/^ *\n/);
  2789. if (m) {
  2790. if (m.length > 2) {
  2791. inlines.push({ t: 'Hardbreak' });
  2792. } else if (m.length > 0) {
  2793. inlines.push({ t: 'Softbreak' });
  2794. }
  2795. return true;
  2796. }
  2797. return false;
  2798. };
  2799. // Attempt to parse an image. If the opening '!' is not followed
  2800. // by a link, return a literal '!'.
  2801. var parseImage = function(inlines) {
  2802. if (this.match(/^!/)) {
  2803. var link = this.parseLink(inlines);
  2804. if (link) {
  2805. inlines[inlines.length - 1].t = 'Image';
  2806. return true;
  2807. } else {
  2808. inlines.push({ t: 'Str', c: '!' });
  2809. return true;
  2810. }
  2811. } else {
  2812. return false;
  2813. }
  2814. };
  2815. // Attempt to parse a link reference, modifying refmap.
  2816. var parseReference = function(s, refmap) {
  2817. this.subject = s;
  2818. this.pos = 0;
  2819. var rawlabel;
  2820. var dest;
  2821. var title;
  2822. var matchChars;
  2823. var startpos = this.pos;
  2824. var match;
  2825. // label:
  2826. matchChars = this.parseLinkLabel();
  2827. if (matchChars === 0) {
  2828. return 0;
  2829. } else {
  2830. rawlabel = this.subject.substr(0, matchChars);
  2831. }
  2832. // colon:
  2833. if (this.peek() === C_COLON) {
  2834. this.pos++;
  2835. } else {
  2836. this.pos = startpos;
  2837. return 0;
  2838. }
  2839. // link url
  2840. this.spnl();
  2841. dest = this.parseLinkDestination();
  2842. if (dest === null || dest.length === 0) {
  2843. this.pos = startpos;
  2844. return 0;
  2845. }
  2846. var beforetitle = this.pos;
  2847. this.spnl();
  2848. title = this.parseLinkTitle();
  2849. if (title === null) {
  2850. title = '';
  2851. // rewind before spaces
  2852. this.pos = beforetitle;
  2853. }
  2854. // make sure we're at line end:
  2855. if (this.match(/^ *(?:\n|$)/) === null) {
  2856. this.pos = startpos;
  2857. return 0;
  2858. }
  2859. var normlabel = normalizeReference(rawlabel);
  2860. if (!refmap[normlabel]) {
  2861. refmap[normlabel] = { destination: dest, title: title };
  2862. }
  2863. return this.pos - startpos;
  2864. };
  2865. // Parse the next inline element in subject, advancing subject position.
  2866. // If memoize is set, memoize the result.
  2867. // On success, add the result to the inlines list, and return true.
  2868. // On failure, return false.
  2869. var parseInline = function(inlines, memoize) {
  2870. var startpos = this.pos;
  2871. var origlen = inlines.length;
  2872. var memoized = memoize && this.memo[startpos];
  2873. if (memoized) {
  2874. this.pos = memoized.endpos;
  2875. Array.prototype.push.apply(inlines, memoized.inline);
  2876. return true;
  2877. }
  2878. var c = this.peek();
  2879. if (c === -1) {
  2880. return false;
  2881. }
  2882. var res;
  2883. switch(c) {
  2884. case C_NEWLINE:
  2885. case C_SPACE:
  2886. res = this.parseNewline(inlines);
  2887. break;
  2888. case C_BACKSLASH:
  2889. res = this.parseBackslash(inlines);
  2890. break;
  2891. case C_BACKTICK:
  2892. res = this.parseBackticks(inlines);
  2893. break;
  2894. case C_ASTERISK:
  2895. case C_UNDERSCORE:
  2896. res = this.parseEmphasis(c, inlines);
  2897. break;
  2898. case C_OPEN_BRACKET:
  2899. res = this.parseLink(inlines);
  2900. break;
  2901. case C_BANG:
  2902. res = this.parseImage(inlines);
  2903. break;
  2904. case C_LESSTHAN:
  2905. res = this.parseAutolink(inlines) || this.parseHtmlTag(inlines);
  2906. break;
  2907. case C_AMPERSAND:
  2908. res = this.parseEntity(inlines);
  2909. break;
  2910. default:
  2911. res = this.parseString(inlines);
  2912. break;
  2913. }
  2914. if (!res) {
  2915. this.pos += 1;
  2916. inlines.push({t: 'Str', c: String.fromCharCode(c)});
  2917. }
  2918. if (memoize) {
  2919. this.memo[startpos] = { inline: inlines.slice(origlen),
  2920. endpos: this.pos };
  2921. }
  2922. return true;
  2923. };
  2924. // Parse s as a list of inlines, using refmap to resolve references.
  2925. var parseInlines = function(s, refmap) {
  2926. this.subject = s;
  2927. this.pos = 0;
  2928. this.refmap = refmap || {};
  2929. this.memo = {};
  2930. this.last_emphasis_closer = { '*': s.length, '_': s.length };
  2931. var inlines = [];
  2932. while (this.parseInline(inlines, false)) {
  2933. }
  2934. return inlines;
  2935. };
  2936. // The InlineParser object.
  2937. function InlineParser(){
  2938. return {
  2939. subject: '',
  2940. label_nest_level: 0, // used by parseLinkLabel method
  2941. last_emphasis_closer: null, // used by parseEmphasis method
  2942. pos: 0,
  2943. refmap: {},
  2944. memo: {},
  2945. match: match,
  2946. peek: peek,
  2947. spnl: spnl,
  2948. parseBackticks: parseBackticks,
  2949. parseBackslash: parseBackslash,
  2950. parseAutolink: parseAutolink,
  2951. parseHtmlTag: parseHtmlTag,
  2952. scanDelims: scanDelims,
  2953. parseEmphasis: parseEmphasis,
  2954. parseLinkTitle: parseLinkTitle,
  2955. parseLinkDestination: parseLinkDestination,
  2956. parseLinkLabel: parseLinkLabel,
  2957. parseLink: parseLink,
  2958. parseEntity: parseEntity,
  2959. parseString: parseString,
  2960. parseNewline: parseNewline,
  2961. parseImage: parseImage,
  2962. parseReference: parseReference,
  2963. parseInline: parseInline,
  2964. parse: parseInlines
  2965. };
  2966. }
  2967. // DOC PARSER
  2968. // These are methods of a DocParser object, defined below.
  2969. var makeBlock = function(tag, start_line, start_column) {
  2970. return { t: tag,
  2971. open: true,
  2972. last_line_blank: false,
  2973. start_line: start_line,
  2974. start_column: start_column,
  2975. end_line: start_line,
  2976. children: [],
  2977. parent: null,
  2978. // string_content is formed by concatenating strings, in finalize:
  2979. string_content: "",
  2980. strings: [],
  2981. inline_content: []
  2982. };
  2983. };
  2984. // Returns true if parent block can contain child block.
  2985. var canContain = function(parent_type, child_type) {
  2986. return ( parent_type == 'Document' ||
  2987. parent_type == 'BlockQuote' ||
  2988. parent_type == 'ListItem' ||
  2989. (parent_type == 'List' && child_type == 'ListItem') );
  2990. };
  2991. // Returns true if block type can accept lines of text.
  2992. var acceptsLines = function(block_type) {
  2993. return ( block_type == 'Paragraph' ||
  2994. block_type == 'IndentedCode' ||
  2995. block_type == 'FencedCode' );
  2996. };
  2997. // Returns true if block ends with a blank line, descending if needed
  2998. // into lists and sublists.
  2999. var endsWithBlankLine = function(block) {
  3000. if (block.last_line_blank) {
  3001. return true;
  3002. }
  3003. if ((block.t == 'List' || block.t == 'ListItem') && block.children.length > 0) {
  3004. return endsWithBlankLine(block.children[block.children.length - 1]);
  3005. } else {
  3006. return false;
  3007. }
  3008. };
  3009. // Break out of all containing lists, resetting the tip of the
  3010. // document to the parent of the highest list, and finalizing
  3011. // all the lists. (This is used to implement the "two blank lines
  3012. // break of of all lists" feature.)
  3013. var breakOutOfLists = function(block, line_number) {
  3014. var b = block;
  3015. var last_list = null;
  3016. do {
  3017. if (b.t === 'List') {
  3018. last_list = b;
  3019. }
  3020. b = b.parent;
  3021. } while (b);
  3022. if (last_list) {
  3023. while (block != last_list) {
  3024. this.finalize(block, line_number);
  3025. block = block.parent;
  3026. }
  3027. this.finalize(last_list, line_number);
  3028. this.tip = last_list.parent;
  3029. }
  3030. };
  3031. // Add a line to the block at the tip. We assume the tip
  3032. // can accept lines -- that check should be done before calling this.
  3033. var addLine = function(ln, offset) {
  3034. var s = ln.slice(offset);
  3035. if (!(this.tip.open)) {
  3036. throw({ msg: "Attempted to add line (" + ln + ") to closed container." });
  3037. }
  3038. this.tip.strings.push(s);
  3039. };
  3040. // Add block of type tag as a child of the tip. If the tip can't
  3041. // accept children, close and finalize it and try its parent,
  3042. // and so on til we find a block that can accept children.
  3043. var addChild = function(tag, line_number, offset) {
  3044. while (!canContain(this.tip.t, tag)) {
  3045. this.finalize(this.tip, line_number);
  3046. }
  3047. var column_number = offset + 1; // offset 0 = column 1
  3048. var newBlock = makeBlock(tag, line_number, column_number);
  3049. this.tip.children.push(newBlock);
  3050. newBlock.parent = this.tip;
  3051. this.tip = newBlock;
  3052. return newBlock;
  3053. };
  3054. // Parse a list marker and return data on the marker (type,
  3055. // start, delimiter, bullet character, padding) or null.
  3056. var parseListMarker = function(ln, offset) {
  3057. var rest = ln.slice(offset);
  3058. var match;
  3059. var spaces_after_marker;
  3060. var data = {};
  3061. if (rest.match(reHrule)) {
  3062. return null;
  3063. }
  3064. if ((match = rest.match(/^[*+-]( +|$)/))) {
  3065. spaces_after_marker = match[1].length;
  3066. data.type = 'Bullet';
  3067. data.bullet_char = match[0][0];
  3068. } else if ((match = rest.match(/^(\d+)([.)])( +|$)/))) {
  3069. spaces_after_marker = match[3].length;
  3070. data.type = 'Ordered';
  3071. data.start = parseInt(match[1]);
  3072. data.delimiter = match[2];
  3073. } else {
  3074. return null;
  3075. }
  3076. var blank_item = match[0].length === rest.length;
  3077. if (spaces_after_marker >= 5 ||
  3078. spaces_after_marker < 1 ||
  3079. blank_item) {
  3080. data.padding = match[0].length - spaces_after_marker + 1;
  3081. } else {
  3082. data.padding = match[0].length;
  3083. }
  3084. return data;
  3085. };
  3086. // Returns true if the two list items are of the same type,
  3087. // with the same delimiter and bullet character. This is used
  3088. // in agglomerating list items into lists.
  3089. var listsMatch = function(list_data, item_data) {
  3090. return (list_data.type === item_data.type &&
  3091. list_data.delimiter === item_data.delimiter &&
  3092. list_data.bullet_char === item_data.bullet_char);
  3093. };
  3094. // Analyze a line of text and update the document appropriately.
  3095. // We parse markdown text by calling this on each line of input,
  3096. // then finalizing the document.
  3097. var incorporateLine = function(ln, line_number) {
  3098. var all_matched = true;
  3099. var last_child;
  3100. var first_nonspace;
  3101. var offset = 0;
  3102. var match;
  3103. var data;
  3104. var blank;
  3105. var indent;
  3106. var last_matched_container;
  3107. var i;
  3108. var CODE_INDENT = 4;
  3109. var container = this.doc;
  3110. var oldtip = this.tip;
  3111. // Convert tabs to spaces:
  3112. ln = detabLine(ln);
  3113. // For each containing block, try to parse the associated line start.
  3114. // Bail out on failure: container will point to the last matching block.
  3115. // Set all_matched to false if not all containers match.
  3116. while (container.children.length > 0) {
  3117. last_child = container.children[container.children.length - 1];
  3118. if (!last_child.open) {
  3119. break;
  3120. }
  3121. container = last_child;
  3122. match = matchAt(/[^ ]/, ln, offset);
  3123. if (match === null) {
  3124. first_nonspace = ln.length;
  3125. blank = true;
  3126. } else {
  3127. first_nonspace = match;
  3128. blank = false;
  3129. }
  3130. indent = first_nonspace - offset;
  3131. switch (container.t) {
  3132. case 'BlockQuote':
  3133. if (indent <= 3 && ln.charCodeAt(first_nonspace) === C_GREATERTHAN) {
  3134. offset = first_nonspace + 1;
  3135. if (ln.charCodeAt(offset) === C_SPACE) {
  3136. offset++;
  3137. }
  3138. } else {
  3139. all_matched = false;
  3140. }
  3141. break;
  3142. case 'ListItem':
  3143. if (indent >= container.list_data.marker_offset +
  3144. container.list_data.padding) {
  3145. offset += container.list_data.marker_offset +
  3146. container.list_data.padding;
  3147. } else if (blank) {
  3148. offset = first_nonspace;
  3149. } else {
  3150. all_matched = false;
  3151. }
  3152. break;
  3153. case 'IndentedCode':
  3154. if (indent >= CODE_INDENT) {
  3155. offset += CODE_INDENT;
  3156. } else if (blank) {
  3157. offset = first_nonspace;
  3158. } else {
  3159. all_matched = false;
  3160. }
  3161. break;
  3162. case 'ATXHeader':
  3163. case 'SetextHeader':
  3164. case 'HorizontalRule':
  3165. // a header can never container > 1 line, so fail to match:
  3166. all_matched = false;
  3167. break;
  3168. case 'FencedCode':
  3169. // skip optional spaces of fence offset
  3170. i = container.fence_offset;
  3171. while (i > 0 && ln.charCodeAt(offset) === C_SPACE) {
  3172. offset++;
  3173. i--;
  3174. }
  3175. break;
  3176. case 'HtmlBlock':
  3177. if (blank) {
  3178. all_matched = false;
  3179. }
  3180. break;
  3181. case 'Paragraph':
  3182. if (blank) {
  3183. container.last_line_blank = true;
  3184. all_matched = false;
  3185. }
  3186. break;
  3187. default:
  3188. }
  3189. if (!all_matched) {
  3190. container = container.parent; // back up to last matching block
  3191. break;
  3192. }
  3193. }
  3194. last_matched_container = container;
  3195. // This function is used to finalize and close any unmatched
  3196. // blocks. We aren't ready to do this now, because we might
  3197. // have a lazy paragraph continuation, in which case we don't
  3198. // want to close unmatched blocks. So we store this closure for
  3199. // use later, when we have more information.
  3200. var closeUnmatchedBlocks = function(mythis) {
  3201. // finalize any blocks not matched
  3202. while (!already_done && oldtip != last_matched_container) {
  3203. mythis.finalize(oldtip, line_number);
  3204. oldtip = oldtip.parent;
  3205. }
  3206. var already_done = true;
  3207. };
  3208. // Check to see if we've hit 2nd blank line; if so break out of list:
  3209. if (blank && container.last_line_blank) {
  3210. this.breakOutOfLists(container, line_number);
  3211. }
  3212. // Unless last matched container is a code block, try new container starts,
  3213. // adding children to the last matched container:
  3214. while (container.t != 'FencedCode' &&
  3215. container.t != 'IndentedCode' &&
  3216. container.t != 'HtmlBlock' &&
  3217. // this is a little performance optimization:
  3218. matchAt(/^[ #`~*+_=<>0-9-]/,ln,offset) !== null) {
  3219. match = matchAt(/[^ ]/, ln, offset);
  3220. if (match === null) {
  3221. first_nonspace = ln.length;
  3222. blank = true;
  3223. } else {
  3224. first_nonspace = match;
  3225. blank = false;
  3226. }
  3227. indent = first_nonspace - offset;
  3228. if (indent >= CODE_INDENT) {
  3229. // indented code
  3230. if (this.tip.t != 'Paragraph' && !blank) {
  3231. offset += CODE_INDENT;
  3232. closeUnmatchedBlocks(this);
  3233. container = this.addChild('IndentedCode', line_number, offset);
  3234. } else { // indent > 4 in a lazy paragraph continuation
  3235. break;
  3236. }
  3237. } else if (ln.charCodeAt(first_nonspace) === C_GREATERTHAN) {
  3238. // blockquote
  3239. offset = first_nonspace + 1;
  3240. // optional following space
  3241. if (ln.charCodeAt(offset) === C_SPACE) {
  3242. offset++;
  3243. }
  3244. closeUnmatchedBlocks(this);
  3245. container = this.addChild('BlockQuote', line_number, offset);
  3246. } else if ((match = ln.slice(first_nonspace).match(/^#{1,6}(?: +|$)/))) {
  3247. // ATX header
  3248. offset = first_nonspace + match[0].length;
  3249. closeUnmatchedBlocks(this);
  3250. container = this.addChild('ATXHeader', line_number, first_nonspace);
  3251. container.level = match[0].trim().length; // number of #s
  3252. // remove trailing ###s:
  3253. container.strings =
  3254. [ln.slice(offset).replace(/(?:(\\#) *#*| *#+) *$/,'$1')];
  3255. break;
  3256. } else if ((match = ln.slice(first_nonspace).match(/^`{3,}(?!.*`)|^~{3,}(?!.*~)/))) {
  3257. // fenced code block
  3258. var fence_length = match[0].length;
  3259. closeUnmatchedBlocks(this);
  3260. container = this.addChild('FencedCode', line_number, first_nonspace);
  3261. container.fence_length = fence_length;
  3262. container.fence_char = match[0][0];
  3263. container.fence_offset = first_nonspace - offset;
  3264. offset = first_nonspace + fence_length;
  3265. break;
  3266. } else if (matchAt(reHtmlBlockOpen, ln, first_nonspace) !== null) {
  3267. // html block
  3268. closeUnmatchedBlocks(this);
  3269. container = this.addChild('HtmlBlock', line_number, first_nonspace);
  3270. // note, we don't adjust offset because the tag is part of the text
  3271. break;
  3272. } else if (container.t == 'Paragraph' &&
  3273. container.strings.length === 1 &&
  3274. ((match = ln.slice(first_nonspace).match(/^(?:=+|-+) *$/)))) {
  3275. // setext header line
  3276. closeUnmatchedBlocks(this);
  3277. container.t = 'SetextHeader'; // convert Paragraph to SetextHeader
  3278. container.level = match[0][0] === '=' ? 1 : 2;
  3279. offset = ln.length;
  3280. } else if (matchAt(reHrule, ln, first_nonspace) !== null) {
  3281. // hrule
  3282. closeUnmatchedBlocks(this);
  3283. container = this.addChild('HorizontalRule', line_number, first_nonspace);
  3284. offset = ln.length - 1;
  3285. break;
  3286. } else if ((data = parseListMarker(ln, first_nonspace))) {
  3287. // list item
  3288. closeUnmatchedBlocks(this);
  3289. data.marker_offset = indent;
  3290. offset = first_nonspace + data.padding;
  3291. // add the list if needed
  3292. if (container.t !== 'List' ||
  3293. !(listsMatch(container.list_data, data))) {
  3294. container = this.addChild('List', line_number, first_nonspace);
  3295. container.list_data = data;
  3296. }
  3297. // add the list item
  3298. container = this.addChild('ListItem', line_number, first_nonspace);
  3299. container.list_data = data;
  3300. } else {
  3301. break;
  3302. }
  3303. if (acceptsLines(container.t)) {
  3304. // if it's a line container, it can't contain other containers
  3305. break;
  3306. }
  3307. }
  3308. // What remains at the offset is a text line. Add the text to the
  3309. // appropriate container.
  3310. match = matchAt(/[^ ]/, ln, offset);
  3311. if (match === null) {
  3312. first_nonspace = ln.length;
  3313. blank = true;
  3314. } else {
  3315. first_nonspace = match;
  3316. blank = false;
  3317. }
  3318. indent = first_nonspace - offset;
  3319. // First check for a lazy paragraph continuation:
  3320. if (this.tip !== last_matched_container &&
  3321. !blank &&
  3322. this.tip.t == 'Paragraph' &&
  3323. this.tip.strings.length > 0) {
  3324. // lazy paragraph continuation
  3325. this.last_line_blank = false;
  3326. this.addLine(ln, offset);
  3327. } else { // not a lazy continuation
  3328. // finalize any blocks not matched
  3329. closeUnmatchedBlocks(this);
  3330. // Block quote lines are never blank as they start with >
  3331. // and we don't count blanks in fenced code for purposes of tight/loose
  3332. // lists or breaking out of lists. We also don't set last_line_blank
  3333. // on an empty list item.
  3334. container.last_line_blank = blank &&
  3335. !(container.t == 'BlockQuote' ||
  3336. container.t == 'FencedCode' ||
  3337. (container.t == 'ListItem' &&
  3338. container.children.length === 0 &&
  3339. container.start_line == line_number));
  3340. var cont = container;
  3341. while (cont.parent) {
  3342. cont.parent.last_line_blank = false;
  3343. cont = cont.parent;
  3344. }
  3345. switch (container.t) {
  3346. case 'IndentedCode':
  3347. case 'HtmlBlock':
  3348. this.addLine(ln, offset);
  3349. break;
  3350. case 'FencedCode':
  3351. // check for closing code fence:
  3352. match = (indent <= 3 &&
  3353. ln.charAt(first_nonspace) == container.fence_char &&
  3354. ln.slice(first_nonspace).match(/^(?:`{3,}|~{3,})(?= *$)/));
  3355. if (match && match[0].length >= container.fence_length) {
  3356. // don't add closing fence to container; instead, close it:
  3357. this.finalize(container, line_number);
  3358. } else {
  3359. this.addLine(ln, offset);
  3360. }
  3361. break;
  3362. case 'ATXHeader':
  3363. case 'SetextHeader':
  3364. case 'HorizontalRule':
  3365. // nothing to do; we already added the contents.
  3366. break;
  3367. default:
  3368. if (acceptsLines(container.t)) {
  3369. this.addLine(ln, first_nonspace);
  3370. } else if (blank) {
  3371. // do nothing
  3372. } else if (container.t != 'HorizontalRule' &&
  3373. container.t != 'SetextHeader') {
  3374. // create paragraph container for line
  3375. container = this.addChild('Paragraph', line_number, first_nonspace);
  3376. this.addLine(ln, first_nonspace);
  3377. } else {
  3378. console.log("Line " + line_number.toString() +
  3379. " with container type " + container.t +
  3380. " did not match any condition.");
  3381. }
  3382. }
  3383. }
  3384. };
  3385. // Finalize a block. Close it and do any necessary postprocessing,
  3386. // e.g. creating string_content from strings, setting the 'tight'
  3387. // or 'loose' status of a list, and parsing the beginnings
  3388. // of paragraphs for reference definitions. Reset the tip to the
  3389. // parent of the closed block.
  3390. var finalize = function(block, line_number) {
  3391. var pos;
  3392. // don't do anything if the block is already closed
  3393. if (!block.open) {
  3394. return 0;
  3395. }
  3396. block.open = false;
  3397. if (line_number > block.start_line) {
  3398. block.end_line = line_number - 1;
  3399. } else {
  3400. block.end_line = line_number;
  3401. }
  3402. switch (block.t) {
  3403. case 'Paragraph':
  3404. block.string_content = block.strings.join('\n').replace(/^ */m,'');
  3405. // try parsing the beginning as link reference definitions:
  3406. while (block.string_content.charCodeAt(0) === C_OPEN_BRACKET &&
  3407. (pos = this.inlineParser.parseReference(block.string_content,
  3408. this.refmap))) {
  3409. block.string_content = block.string_content.slice(pos);
  3410. if (isBlank(block.string_content)) {
  3411. block.t = 'ReferenceDef';
  3412. break;
  3413. }
  3414. }
  3415. break;
  3416. case 'ATXHeader':
  3417. case 'SetextHeader':
  3418. case 'HtmlBlock':
  3419. block.string_content = block.strings.join('\n');
  3420. break;
  3421. case 'IndentedCode':
  3422. block.string_content = block.strings.join('\n').replace(/(\n *)*$/,'\n');
  3423. break;
  3424. case 'FencedCode':
  3425. // first line becomes info string
  3426. block.info = unescapeEntBS(block.strings[0].trim());
  3427. if (block.strings.length == 1) {
  3428. block.string_content = '';
  3429. } else {
  3430. block.string_content = block.strings.slice(1).join('\n') + '\n';
  3431. }
  3432. break;
  3433. case 'List':
  3434. block.tight = true; // tight by default
  3435. var numitems = block.children.length;
  3436. var i = 0;
  3437. while (i < numitems) {
  3438. var item = block.children[i];
  3439. // check for non-final list item ending with blank line:
  3440. var last_item = i == numitems - 1;
  3441. if (endsWithBlankLine(item) && !last_item) {
  3442. block.tight = false;
  3443. break;
  3444. }
  3445. // recurse into children of list item, to see if there are
  3446. // spaces between any of them:
  3447. var numsubitems = item.children.length;
  3448. var j = 0;
  3449. while (j < numsubitems) {
  3450. var subitem = item.children[j];
  3451. var last_subitem = j == numsubitems - 1;
  3452. if (endsWithBlankLine(subitem) && !(last_item && last_subitem)) {
  3453. block.tight = false;
  3454. break;
  3455. }
  3456. j++;
  3457. }
  3458. i++;
  3459. }
  3460. break;
  3461. default:
  3462. break;
  3463. }
  3464. this.tip = block.parent || this.top;
  3465. };
  3466. // Walk through a block & children recursively, parsing string content
  3467. // into inline content where appropriate.
  3468. var processInlines = function(block) {
  3469. switch(block.t) {
  3470. case 'Paragraph':
  3471. case 'SetextHeader':
  3472. case 'ATXHeader':
  3473. block.inline_content =
  3474. this.inlineParser.parse(block.string_content.trim(), this.refmap);
  3475. block.string_content = "";
  3476. break;
  3477. default:
  3478. break;
  3479. }
  3480. if (block.children) {
  3481. for (var i = 0; i < block.children.length; i++) {
  3482. this.processInlines(block.children[i]);
  3483. }
  3484. }
  3485. };
  3486. // The main parsing function. Returns a parsed document AST.
  3487. var parse = function(input) {
  3488. this.doc = makeBlock('Document', 1, 1);
  3489. this.tip = this.doc;
  3490. this.refmap = {};
  3491. var lines = input.replace(/\n$/,'').split(/\r\n|\n|\r/);
  3492. var len = lines.length;
  3493. for (var i = 0; i < len; i++) {
  3494. this.incorporateLine(lines[i], i+1);
  3495. }
  3496. while (this.tip) {
  3497. this.finalize(this.tip, len - 1);
  3498. }
  3499. this.processInlines(this.doc);
  3500. return this.doc;
  3501. };
  3502. // The DocParser object.
  3503. function DocParser(){
  3504. return {
  3505. doc: makeBlock('Document', 1, 1),
  3506. tip: this.doc,
  3507. refmap: {},
  3508. inlineParser: new InlineParser(),
  3509. breakOutOfLists: breakOutOfLists,
  3510. addLine: addLine,
  3511. addChild: addChild,
  3512. incorporateLine: incorporateLine,
  3513. finalize: finalize,
  3514. processInlines: processInlines,
  3515. parse: parse
  3516. };
  3517. }
  3518. // HTML RENDERER
  3519. // Helper function to produce content in a pair of HTML tags.
  3520. var inTags = function(tag, attribs, contents, selfclosing) {
  3521. var result = '<' + tag;
  3522. if (attribs) {
  3523. var i = 0;
  3524. var attrib;
  3525. while ((attrib = attribs[i]) !== undefined) {
  3526. result = result.concat(' ', attrib[0], '="', attrib[1], '"');
  3527. i++;
  3528. }
  3529. }
  3530. if (contents) {
  3531. result = result.concat('>', contents, '</', tag, '>');
  3532. } else if (selfclosing) {
  3533. result = result + ' />';
  3534. } else {
  3535. result = result.concat('></', tag, '>');
  3536. }
  3537. return result;
  3538. };
  3539. // Render an inline element as HTML.
  3540. var renderInline = function(inline) {
  3541. var attrs;
  3542. switch (inline.t) {
  3543. case 'Str':
  3544. return this.escape(inline.c);
  3545. case 'Softbreak':
  3546. return this.softbreak;
  3547. case 'Hardbreak':
  3548. return inTags('br',[],"",true) + '\n';
  3549. case 'Emph':
  3550. return inTags('em', [], this.renderInlines(inline.c));
  3551. case 'Strong':
  3552. return inTags('strong', [], this.renderInlines(inline.c));
  3553. case 'Html':
  3554. return inline.c;
  3555. case 'Link':
  3556. attrs = [['href', this.escape(inline.destination, true)]];
  3557. if (inline.title) {
  3558. attrs.push(['title', this.escape(inline.title, true)]);
  3559. }
  3560. return inTags('a', attrs, this.renderInlines(inline.label));
  3561. case 'Image':
  3562. attrs = [['src', this.escape(inline.destination, true)],
  3563. ['alt', this.escape(this.renderInlines(inline.label))]];
  3564. if (inline.title) {
  3565. attrs.push(['title', this.escape(inline.title, true)]);
  3566. }
  3567. return inTags('img', attrs, "", true);
  3568. case 'Code':
  3569. return inTags('code', [], this.escape(inline.c));
  3570. default:
  3571. console.log("Unknown inline type " + inline.t);
  3572. return "";
  3573. }
  3574. };
  3575. // Render a list of inlines.
  3576. var renderInlines = function(inlines) {
  3577. var result = '';
  3578. for (var i=0; i < inlines.length; i++) {
  3579. result = result + this.renderInline(inlines[i]);
  3580. }
  3581. return result;
  3582. };
  3583. // Render a single block element.
  3584. var renderBlock = function(block, in_tight_list) {
  3585. var tag;
  3586. var attr;
  3587. var info_words;
  3588. switch (block.t) {
  3589. case 'Document':
  3590. var whole_doc = this.renderBlocks(block.children);
  3591. return (whole_doc === '' ? '' : whole_doc + '\n');
  3592. case 'Paragraph':
  3593. if (in_tight_list) {
  3594. return this.renderInlines(block.inline_content);
  3595. } else {
  3596. return inTags('p', [], this.renderInlines(block.inline_content));
  3597. }
  3598. break;
  3599. case 'BlockQuote':
  3600. var filling = this.renderBlocks(block.children);
  3601. return inTags('blockquote', [], filling === '' ? this.innersep :
  3602. this.innersep + filling + this.innersep);
  3603. case 'ListItem':
  3604. return inTags('li', [], this.renderBlocks(block.children, in_tight_list).trim());
  3605. case 'List':
  3606. tag = block.list_data.type == 'Bullet' ? 'ul' : 'ol';
  3607. attr = (!block.list_data.start || block.list_data.start == 1) ?
  3608. [] : [['start', block.list_data.start.toString()]];
  3609. return inTags(tag, attr, this.innersep +
  3610. this.renderBlocks(block.children, block.tight) +
  3611. this.innersep);
  3612. case 'ATXHeader':
  3613. case 'SetextHeader':
  3614. tag = 'h' + block.level;
  3615. return inTags(tag, [], this.renderInlines(block.inline_content));
  3616. case 'IndentedCode':
  3617. return inTags('pre', [],
  3618. inTags('code', [], this.escape(block.string_content)));
  3619. case 'FencedCode':
  3620. info_words = block.info.split(/ +/);
  3621. attr = info_words.length === 0 || info_words[0].length === 0 ?
  3622. [] : [['class','language-' +
  3623. this.escape(info_words[0],true)]];
  3624. return inTags('pre', [],
  3625. inTags('code', attr, this.escape(block.string_content)));
  3626. case 'HtmlBlock':
  3627. return block.string_content;
  3628. case 'ReferenceDef':
  3629. return "";
  3630. case 'HorizontalRule':
  3631. return inTags('hr',[],"",true);
  3632. default:
  3633. console.log("Unknown block type " + block.t);
  3634. return "";
  3635. }
  3636. };
  3637. // Render a list of block elements, separated by this.blocksep.
  3638. var renderBlocks = function(blocks, in_tight_list) {
  3639. var result = [];
  3640. for (var i=0; i < blocks.length; i++) {
  3641. if (blocks[i].t !== 'ReferenceDef') {
  3642. result.push(this.renderBlock(blocks[i], in_tight_list));
  3643. }
  3644. }
  3645. return result.join(this.blocksep);
  3646. };
  3647. // The HtmlRenderer object.
  3648. function HtmlRenderer(){
  3649. return {
  3650. // default options:
  3651. blocksep: '\n', // space between blocks
  3652. innersep: '\n', // space between block container tag and contents
  3653. softbreak: '\n', // by default, soft breaks are rendered as newlines in HTML
  3654. // set to "<br />" to make them hard breaks
  3655. // set to " " if you want to ignore line wrapping in source
  3656. escape: function(s, preserve_entities) {
  3657. if (preserve_entities) {
  3658. return s.replace(/[&](?![#](x[a-f0-9]{1,8}|[0-9]{1,8});|[a-z][a-z0-9]{1,31};)/gi,'&amp;')
  3659. .replace(/[<]/g,'&lt;')
  3660. .replace(/[>]/g,'&gt;')
  3661. .replace(/["]/g,'&quot;');
  3662. } else {
  3663. return s.replace(/[&]/g,'&amp;')
  3664. .replace(/[<]/g,'&lt;')
  3665. .replace(/[>]/g,'&gt;')
  3666. .replace(/["]/g,'&quot;');
  3667. }
  3668. },
  3669. renderInline: renderInline,
  3670. renderInlines: renderInlines,
  3671. renderBlock: renderBlock,
  3672. renderBlocks: renderBlocks,
  3673. render: renderBlock
  3674. };
  3675. }
  3676. exports.DocParser = DocParser;
  3677. exports.HtmlRenderer = HtmlRenderer;
  3678. })(typeof exports === 'undefined' ? this.stmd = {} : exports);