showdown.js 5.2 KB

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