hashHTMLBlocks.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. showdown.subParser('hashHTMLBlocks', function (text, options, globals) {
  2. 'use strict';
  3. // attacklab: Double up blank lines to reduce lookaround
  4. text = text.replace(/\n/g, '\n\n');
  5. // Hashify HTML blocks:
  6. // We only want to do this for block-level HTML tags, such as headers,
  7. // lists, and tables. That's because we still want to wrap <p>s around
  8. // "paragraphs" that are wrapped in non-block-level tags, such as anchors,
  9. // phrase emphasis, and spans. The list of tags we're looking for is
  10. // hard-coded:
  11. //var block_tags_a =
  12. // 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del|style|section|header|footer|nav|article|aside';
  13. // var block_tags_b =
  14. // 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|style|section|header|footer|nav|article|aside';
  15. // First, look for nested blocks, e.g.:
  16. // <div>
  17. // <div>
  18. // tags for inner block must be indented.
  19. // </div>
  20. // </div>
  21. //
  22. // The outermost tags must start at the left margin for this to match, and
  23. // the inner nested divs must be indented.
  24. // We need to do this before the next, more liberal match, because the next
  25. // match will start at the first `<div>` and stop at the first `</div>`.
  26. // attacklab: This regex can be expensive when it fails.
  27. /*
  28. var text = text.replace(/
  29. ( // save in $1
  30. ^ // start of line (with /m)
  31. <($block_tags_a) // start tag = $2
  32. \b // word break
  33. // attacklab: hack around khtml/pcre bug...
  34. [^\r]*?\n // any number of lines, minimally matching
  35. </\2> // the matching end tag
  36. [ \t]* // trailing spaces/tabs
  37. (?=\n+) // followed by a newline
  38. ) // attacklab: there are sentinel newlines at end of document
  39. /gm,function(){...}};
  40. */
  41. text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b[^\r]*?\n<\/\2>[ \t]*(?=\n+))/gm,
  42. showdown.subParser('hashElement')(text, options, globals));
  43. //
  44. // Now match more liberally, simply from `\n<tag>` to `</tag>\n`
  45. //
  46. /*
  47. var text = text.replace(/
  48. ( // save in $1
  49. ^ // start of line (with /m)
  50. <($block_tags_b) // start tag = $2
  51. \b // word break
  52. // attacklab: hack around khtml/pcre bug...
  53. [^\r]*? // any number of lines, minimally matching
  54. </\2> // the matching end tag
  55. [ \t]* // trailing spaces/tabs
  56. (?=\n+) // followed by a newline
  57. ) // attacklab: there are sentinel newlines at end of document
  58. /gm,function(){...}};
  59. */
  60. text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|style|section|header|footer|nav|article|aside|address|audio|canvas|figure|hgroup|output|video)\b[^\r]*?<\/\2>[ \t]*(?=\n+)\n)/gm,
  61. showdown.subParser('hashElement')(text, options, globals));
  62. // Special case just for <hr />. It was easier to make a special case than
  63. // to make the other regex more complicated.
  64. /*
  65. text = text.replace(/
  66. ( // save in $1
  67. \n\n // Starting after a blank line
  68. [ ]{0,3}
  69. (<(hr) // start tag = $2
  70. \b // word break
  71. ([^<>])*? //
  72. \/?>) // the matching end tag
  73. [ \t]*
  74. (?=\n{2,}) // followed by a blank line
  75. )
  76. /g,showdown.subParser('hashElement')(text, options, globals));
  77. */
  78. text = text.replace(/(\n[ ]{0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,
  79. showdown.subParser('hashElement')(text, options, globals));
  80. // Special case for standalone HTML comments:
  81. /*
  82. text = text.replace(/
  83. ( // save in $1
  84. \n\n // Starting after a blank line
  85. [ ]{0,3} // attacklab: g_tab_width - 1
  86. <!
  87. (--[^\r]*?--\s*)+
  88. >
  89. [ \t]*
  90. (?=\n{2,}) // followed by a blank line
  91. )
  92. /g,showdown.subParser('hashElement')(text, options, globals));
  93. */
  94. text = text.replace(/(\n\n[ ]{0,3}<!(--[^\r]*?--\s*)+>[ \t]*(?=\n{2,}))/g,
  95. showdown.subParser('hashElement')(text, options, globals));
  96. // PHP and ASP-style processor instructions (<?...?> and <%...%>)
  97. /*
  98. text = text.replace(/
  99. (?:
  100. \n\n // Starting after a blank line
  101. )
  102. ( // save in $1
  103. [ ]{0,3} // attacklab: g_tab_width - 1
  104. (?:
  105. <([?%]) // $2
  106. [^\r]*?
  107. \2>
  108. )
  109. [ \t]*
  110. (?=\n{2,}) // followed by a blank line
  111. )
  112. /g,showdown.subParser('hashElement')(text, options, globals));
  113. */
  114. text = text.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,
  115. showdown.subParser('hashElement')(text, options, globals));
  116. // attacklab: Undo double lines (see comment at top of this function)
  117. text = text.replace(/\n\n/g, '\n');
  118. return text;
  119. });