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