prism-pug.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. (function(Prism) {
  2. // TODO:
  3. // - Add CSS highlighting inside <style> tags
  4. // - Add support for multi-line code blocks
  5. // - Add support for interpolation #{} and !{}
  6. // - Add support for tag interpolation #[]
  7. // - Add explicit support for plain text using |
  8. // - Add support for markup embedded in plain text
  9. Prism.languages.pug = {
  10. // Multiline stuff should appear before the rest
  11. // This handles both single-line and multi-line comments
  12. 'comment': {
  13. pattern: /(^([\t ]*))\/\/.*(?:(?:\r?\n|\r)\2[\t ]+.+)*/m,
  14. lookbehind: true
  15. },
  16. // All the tag-related part is in lookbehind
  17. // so that it can be highlighted by the "tag" pattern
  18. 'multiline-script': {
  19. pattern: /(^([\t ]*)script\b.*\.[\t ]*)(?:(?:\r?\n|\r(?!\n))(?:\2[\t ]+.+|\s*?(?=\r?\n|\r)))+/m,
  20. lookbehind: true,
  21. inside: Prism.languages.javascript
  22. },
  23. // See at the end of the file for known filters
  24. 'filter': {
  25. pattern: /(^([\t ]*)):.+(?:(?:\r?\n|\r(?!\n))(?:\2[\t ]+.+|\s*?(?=\r?\n|\r)))+/m,
  26. lookbehind: true,
  27. inside: {
  28. 'filter-name': {
  29. pattern: /^:[\w-]+/,
  30. alias: 'variable'
  31. }
  32. }
  33. },
  34. 'multiline-plain-text': {
  35. pattern: /(^([\t ]*)[\w\-#.]+\.[\t ]*)(?:(?:\r?\n|\r(?!\n))(?:\2[\t ]+.+|\s*?(?=\r?\n|\r)))+/m,
  36. lookbehind: true
  37. },
  38. 'markup': {
  39. pattern: /(^[\t ]*)<.+/m,
  40. lookbehind: true,
  41. inside: Prism.languages.markup
  42. },
  43. 'doctype': {
  44. pattern: /((?:^|\n)[\t ]*)doctype(?: .+)?/,
  45. lookbehind: true
  46. },
  47. // This handle all conditional and loop keywords
  48. 'flow-control': {
  49. pattern: /(^[\t ]*)(?:if|unless|else|case|when|default|each|while)\b(?: .+)?/m,
  50. lookbehind: true,
  51. inside: {
  52. 'each': {
  53. pattern: /^each .+? in\b/,
  54. inside: {
  55. 'keyword': /\b(?:each|in)\b/,
  56. 'punctuation': /,/
  57. }
  58. },
  59. 'branch': {
  60. pattern: /^(?:if|unless|else|case|when|default|while)\b/,
  61. alias: 'keyword'
  62. },
  63. rest: Prism.languages.javascript
  64. }
  65. },
  66. 'keyword': {
  67. pattern: /(^[\t ]*)(?:block|extends|include|append|prepend)\b.+/m,
  68. lookbehind: true
  69. },
  70. 'mixin': [
  71. // Declaration
  72. {
  73. pattern: /(^[\t ]*)mixin .+/m,
  74. lookbehind: true,
  75. inside: {
  76. 'keyword': /^mixin/,
  77. 'function': /\w+(?=\s*\(|\s*$)/,
  78. 'punctuation': /[(),.]/
  79. }
  80. },
  81. // Usage
  82. {
  83. pattern: /(^[\t ]*)\+.+/m,
  84. lookbehind: true,
  85. inside: {
  86. 'name': {
  87. pattern: /^\+\w+/,
  88. alias: 'function'
  89. },
  90. rest: Prism.languages.javascript
  91. }
  92. }
  93. ],
  94. 'script': {
  95. pattern: /(^[\t ]*script(?:(?:&[^(]+)?\([^)]+\))*[\t ]+).+/m,
  96. lookbehind: true,
  97. inside: Prism.languages.javascript
  98. },
  99. 'plain-text': {
  100. pattern: /(^[\t ]*(?!-)[\w\-#.]*[\w\-](?:(?:&[^(]+)?\([^)]+\))*\/?[\t ]+).+/m,
  101. lookbehind: true
  102. },
  103. 'tag': {
  104. pattern: /(^[\t ]*)(?!-)[\w\-#.]*[\w\-](?:(?:&[^(]+)?\([^)]+\))*\/?:?/m,
  105. lookbehind: true,
  106. inside: {
  107. 'attributes': [
  108. {
  109. pattern: /&[^(]+\([^)]+\)/,
  110. inside: Prism.languages.javascript
  111. },
  112. {
  113. pattern: /\([^)]+\)/,
  114. inside: {
  115. 'attr-value': {
  116. pattern: /(=\s*)(?:\{[^}]*\}|[^,)\r\n]+)/,
  117. lookbehind: true,
  118. inside: Prism.languages.javascript
  119. },
  120. 'attr-name': /[\w-]+(?=\s*!?=|\s*[,)])/,
  121. 'punctuation': /[!=(),]+/
  122. }
  123. }
  124. ],
  125. 'punctuation': /:/,
  126. 'attr-id': /#[\w\-]+/,
  127. 'attr-class': /\.[\w\-]+/
  128. }
  129. },
  130. 'code': [
  131. {
  132. pattern: /(^[\t ]*(?:-|!?=)).+/m,
  133. lookbehind: true,
  134. inside: Prism.languages.javascript
  135. }
  136. ],
  137. 'punctuation': /[.\-!=|]+/
  138. };
  139. var filter_pattern = /(^([\t ]*)):{{filter_name}}(?:(?:\r?\n|\r(?!\n))(?:\2[\t ]+.+|\s*?(?=\r?\n|\r)))+/.source;
  140. // Non exhaustive list of available filters and associated languages
  141. var filters = [
  142. {filter:'atpl',language:'twig'},
  143. {filter:'coffee',language:'coffeescript'},
  144. 'ejs',
  145. 'handlebars',
  146. 'less',
  147. 'livescript',
  148. 'markdown',
  149. {filter:'sass',language:'scss'},
  150. 'stylus'
  151. ];
  152. var all_filters = {};
  153. for (var i = 0, l = filters.length; i < l; i++) {
  154. var filter = filters[i];
  155. filter = typeof filter === 'string' ? {filter: filter, language: filter} : filter;
  156. if (Prism.languages[filter.language]) {
  157. all_filters['filter-' + filter.filter] = {
  158. pattern: RegExp(filter_pattern.replace('{{filter_name}}', function () { return filter.filter; }), 'm'),
  159. lookbehind: true,
  160. inside: {
  161. 'filter-name': {
  162. pattern: /^:[\w-]+/,
  163. alias: 'variable'
  164. },
  165. rest: Prism.languages[filter.language]
  166. }
  167. }
  168. }
  169. }
  170. Prism.languages.insertBefore('pug', 'filter', all_filters);
  171. }(Prism));