showdown.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. var placeholder = document.getElementById('placeholder');
  2. var renderer = new showdown.Converter({simplifiedAutoLink: 'true',
  3. excludeTrailingPunctuationFromURLs: 'true',
  4. strikethrough: 'true',
  5. tables: 'true',
  6. tasklists: 'true',
  7. literalMidWordUnderscores: 'true',
  8. extensions: ['headinganchor']
  9. });
  10. var toc = []; // Table of contents as a list
  11. // Parse the html's headings and construct toc[].
  12. var parseHeadings = function(html) {
  13. toc = [];
  14. var parser = new DOMParser();
  15. var htmlDoc = parser.parseFromString(html, 'text/html');
  16. var eles = htmlDoc.querySelectorAll("h1, h2, h3, h4, h5, h6");
  17. for (var i = 0; i < eles.length; ++i) {
  18. var ele = eles[i];
  19. var level = parseInt(ele.tagName.substr(1));
  20. toc.push({
  21. level: level,
  22. anchor: ele.id,
  23. title: ele.innerHTML
  24. });
  25. }
  26. delete parser;
  27. };
  28. var markdownToHtml = function(markdown, needToc) {
  29. var html = renderer.makeHtml(markdown);
  30. // Parse the html to init toc[].
  31. parseHeadings(html);
  32. if (needToc) {
  33. return html.replace(/<p>\[TOC\]<\/p>/ig, '<div class="vnote-toc"></div>');
  34. } else {
  35. return html;
  36. }
  37. };
  38. var mdHasTocSection = function(markdown) {
  39. var n = markdown.search(/(\n|^)\[toc\]/i);
  40. return n != -1;
  41. };
  42. var highlightCodeBlocks = function(doc, enableMermaid, enableFlowchart, enableMathJax) {
  43. var codes = doc.getElementsByTagName('code');
  44. for (var i = 0; i < codes.length; ++i) {
  45. var code = codes[i];
  46. if (code.parentElement.tagName.toLowerCase() == 'pre') {
  47. if (enableMermaid && code.classList.contains('language-mermaid')) {
  48. // Mermaid code block.
  49. continue;
  50. } else if (enableFlowchart && code.classList.contains('language-flowchart')) {
  51. // Flowchart code block.
  52. continue;
  53. } else if (enableMathJax && code.classList.contains('language-mathjax')) {
  54. // MathJax code block.
  55. continue;
  56. }
  57. if (listContainsRegex(code.classList, /language-.*/)) {
  58. hljs.highlightBlock(code);
  59. }
  60. }
  61. }
  62. };
  63. var updateText = function(text) {
  64. var needToc = mdHasTocSection(text);
  65. var html = markdownToHtml(text, needToc);
  66. placeholder.innerHTML = html;
  67. handleToc(needToc);
  68. insertImageCaption();
  69. highlightCodeBlocks(document, VEnableMermaid, VEnableFlowchart, VEnableMathjax);
  70. renderMermaid('language-mermaid');
  71. renderFlowchart('language-flowchart');
  72. addClassToCodeBlock();
  73. renderCodeBlockLineNumber();
  74. // If you add new logics after handling MathJax, please pay attention to
  75. // finishLoading logic.
  76. if (VEnableMathjax) {
  77. try {
  78. MathJax.Hub.Queue(["Typeset", MathJax.Hub, placeholder, postProcessMathJax]);
  79. } catch (err) {
  80. content.setLog("err: " + err);
  81. finishLogics();
  82. }
  83. } else {
  84. finishLogics();
  85. }
  86. };
  87. var highlightText = function(text, id, timeStamp) {
  88. var html = renderer.makeHtml(text);
  89. var parser = new DOMParser();
  90. var htmlDoc = parser.parseFromString("<div id=\"showdown-container\">" + html + "</div>", 'text/html');
  91. highlightCodeBlocks(htmlDoc, false, false, false);
  92. html = htmlDoc.getElementById('showdown-container').innerHTML;
  93. delete parser;
  94. content.highlightTextCB(html, id, timeStamp);
  95. }
  96. var textToHtml = function(text) {
  97. var html = renderer.makeHtml(text);
  98. var parser = new DOMParser();
  99. var htmlDoc = parser.parseFromString("<div id=\"showdown-container\">" + html + "</div>", 'text/html');
  100. highlightCodeBlocks(htmlDoc, false, false, false);
  101. html = htmlDoc.getElementById('showdown-container').innerHTML;
  102. delete parser;
  103. var container = document.getElementById('text-to-html-div');
  104. container.innerHTML = html;
  105. html = getHtmlWithInlineStyles(container);
  106. container.innerHTML = "";
  107. content.textToHtmlCB(text, html);
  108. }