html-block.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. 'use strict'
  2. var openCloseTag = require('../util/html').openCloseTag
  3. module.exports = blockHtml
  4. var tab = '\t'
  5. var space = ' '
  6. var lineFeed = '\n'
  7. var lessThan = '<'
  8. var rawOpenExpression = /^<(script|pre|style)(?=(\s|>|$))/i
  9. var rawCloseExpression = /<\/(script|pre|style)>/i
  10. var commentOpenExpression = /^<!--/
  11. var commentCloseExpression = /-->/
  12. var instructionOpenExpression = /^<\?/
  13. var instructionCloseExpression = /\?>/
  14. var directiveOpenExpression = /^<![A-Za-z]/
  15. var directiveCloseExpression = />/
  16. var cdataOpenExpression = /^<!\[CDATA\[/
  17. var cdataCloseExpression = /]]>/
  18. var elementCloseExpression = /^$/
  19. var otherElementOpenExpression = new RegExp(openCloseTag.source + '\\s*$')
  20. function blockHtml(eat, value, silent) {
  21. var self = this
  22. var blocks = self.options.blocks.join('|')
  23. var elementOpenExpression = new RegExp(
  24. '^</?(' + blocks + ')(?=(\\s|/?>|$))',
  25. 'i'
  26. )
  27. var length = value.length
  28. var index = 0
  29. var next
  30. var line
  31. var offset
  32. var character
  33. var count
  34. var sequence
  35. var subvalue
  36. var sequences = [
  37. [rawOpenExpression, rawCloseExpression, true],
  38. [commentOpenExpression, commentCloseExpression, true],
  39. [instructionOpenExpression, instructionCloseExpression, true],
  40. [directiveOpenExpression, directiveCloseExpression, true],
  41. [cdataOpenExpression, cdataCloseExpression, true],
  42. [elementOpenExpression, elementCloseExpression, true],
  43. [otherElementOpenExpression, elementCloseExpression, false]
  44. ]
  45. // Eat initial spacing.
  46. while (index < length) {
  47. character = value.charAt(index)
  48. if (character !== tab && character !== space) {
  49. break
  50. }
  51. index++
  52. }
  53. if (value.charAt(index) !== lessThan) {
  54. return
  55. }
  56. next = value.indexOf(lineFeed, index + 1)
  57. next = next === -1 ? length : next
  58. line = value.slice(index, next)
  59. offset = -1
  60. count = sequences.length
  61. while (++offset < count) {
  62. if (sequences[offset][0].test(line)) {
  63. sequence = sequences[offset]
  64. break
  65. }
  66. }
  67. if (!sequence) {
  68. return
  69. }
  70. if (silent) {
  71. return sequence[2]
  72. }
  73. index = next
  74. if (!sequence[1].test(line)) {
  75. while (index < length) {
  76. next = value.indexOf(lineFeed, index + 1)
  77. next = next === -1 ? length : next
  78. line = value.slice(index + 1, next)
  79. if (sequence[1].test(line)) {
  80. if (line) {
  81. index = next
  82. }
  83. break
  84. }
  85. index = next
  86. }
  87. }
  88. subvalue = value.slice(0, index)
  89. return eat(subvalue)({type: 'html', value: subvalue})
  90. }