You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
4.1 KiB

  1. // Code from the repo: https://github.com/adamvleggett/drawdown
  2. //
  3. /**
  4. * drawdown.js
  5. * (c) Adam Leggett
  6. */
  7. ;function markdown(src) {
  8. var rx_lt = /</g;
  9. var rx_gt = />/g;
  10. var rx_space = /\t|\r|\uf8ff/g;
  11. var rx_escape = /\\([\\\|`*_{}\[\]()#+\-~])/g;
  12. var rx_hr = /^([*\-=_] *){3,}$/gm;
  13. var rx_blockquote = /\n *&gt; *([^]*?)(?=(\n|$){2})/g;
  14. var rx_list = /\n( *)(?:[*\-+]|((\d+)|([a-z])|[A-Z])[.)]) +([^]*?)(?=(\n|$){2})/g;
  15. var rx_listjoin = /<\/(ol|ul)>\n\n<\1>/g;
  16. var rx_highlight = /(^|[^A-Za-z\d\\])(([*_])|(~)|(\^)|(--)|(\+\+)|`)(\2?)([^<]*?)\2\8(?!\2)(?=\W|_|$)/g;
  17. var rx_code = /\n((```|~~~).*\n?([^]*?)\n?\2|(( .*?\n)+))/g;
  18. var rx_link = /((!?)\[(.*?)\]\((.*?)( ".*")?\)|\\([\\`*_{}\[\]()#+\-.!~]))/g;
  19. var rx_table = /\n(( *\|.*?\| *\n)+)/g;
  20. var rx_thead = /^.*\n( *\|( *\:?-+\:?-+\:? *\|)* *\n|)/;
  21. var rx_row = /.*\n/g;
  22. var rx_cell = /\||(.*?[^\\])\|/g;
  23. var rx_heading = /(?=^|>|\n)([>\s]*?)(#{1,6}) (.*?)( #*)? *(?=\n|$)/g;
  24. var rx_para = /(?=^|>|\n)\s*\n+([^<]+?)\n+\s*(?=\n|<|$)/g;
  25. var rx_stash = /-\d+\uf8ff/g;
  26. function replace(rex, fn) {
  27. src = src.replace(rex, fn);
  28. }
  29. function element(tag, content) {
  30. return '<' + tag + '>' + content + '</' + tag + '>';
  31. }
  32. function blockquote(src) {
  33. return src.replace(rx_blockquote, function(all, content) {
  34. return element('blockquote', blockquote(highlight(content.replace(/^ *&gt; */gm, ''))));
  35. });
  36. }
  37. function list(src) {
  38. return src.replace(rx_list, function(all, ind, ol, num, low, content) {
  39. var entry = element('li', highlight(content.split(
  40. RegExp('\n ?' + ind + '(?:(?:\\d+|[a-zA-Z])[.)]|[*\\-+]) +', 'g')).map(list).join('</li><li>')));
  41. return '\n' + (ol
  42. ? '<ol start="' + (num
  43. ? ol + '">'
  44. : parseInt(ol,36) - 9 + '" style="list-style-type:' + (low ? 'low' : 'upp') + 'er-alpha">') + entry + '</ol>'
  45. : element('ul', entry));
  46. });
  47. }
  48. function highlight(src) {
  49. return src.replace(rx_highlight, function(all, _, p1, emp, sub, sup, small, big, p2, content) {
  50. return _ + element(
  51. emp ? (p2 ? 'strong' : 'em')
  52. : sub ? (p2 ? 's' : 'sub')
  53. : sup ? 'sup'
  54. : small ? 'small'
  55. : big ? 'big'
  56. : 'code',
  57. highlight(content));
  58. });
  59. }
  60. function unesc(str) {
  61. return str.replace(rx_escape, '$1');
  62. }
  63. var stash = [];
  64. var si = 0;
  65. src = '\n' + src + '\n';
  66. replace(rx_lt, '&lt;');
  67. replace(rx_gt, '&gt;');
  68. replace(rx_space, ' ');
  69. // blockquote
  70. src = blockquote(src);
  71. // horizontal rule
  72. replace(rx_hr, '<hr/>');
  73. // list
  74. src = list(src);
  75. replace(rx_listjoin, '');
  76. // code
  77. replace(rx_code, function(all, p1, p2, p3, p4) {
  78. stash[--si] = element('pre', element('code', p3||p4.replace(/^ /gm, '')));
  79. return si + '\uf8ff';
  80. });
  81. // link or image
  82. replace(rx_link, function(all, p1, p2, p3, p4, p5, p6) {
  83. stash[--si] = p4
  84. ? p2
  85. ? '<img src="' + p4 + '" alt="' + p3 + '"/>'
  86. : '<a href="' + p4 + '">' + unesc(highlight(p3)) + '</a>'
  87. : p6;
  88. return si + '\uf8ff';
  89. });
  90. // table
  91. replace(rx_table, function(all, table) {
  92. var sep = table.match(rx_thead)[1];
  93. return '\n' + element('table',
  94. table.replace(rx_row, function(row, ri) {
  95. return row == sep ? '' : element('tr', row.replace(rx_cell, function(all, cell, ci) {
  96. return ci ? element(sep && !ri ? 'th' : 'td', unesc(highlight(cell || ''))) : ''
  97. }))
  98. })
  99. )
  100. });
  101. // heading
  102. replace(rx_heading, function(all, _, p1, p2) { return _ + element('h' + p1.length, unesc(highlight(p2))) });
  103. // paragraph
  104. replace(rx_para, function(all, content) { return element('p', unesc(highlight(content))) });
  105. // stash
  106. replace(rx_stash, function(all) { return stash[parseInt(all)] });
  107. return src.trim();
  108. };