prism-markup.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. Prism.languages.markup = {
  2. 'comment': {
  3. pattern: /<!--(?:(?!<!--)[\s\S])*?-->/,
  4. greedy: true
  5. },
  6. 'prolog': {
  7. pattern: /<\?[\s\S]+?\?>/,
  8. greedy: true
  9. },
  10. 'doctype': {
  11. // https://www.w3.org/TR/xml/#NT-doctypedecl
  12. pattern: /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,
  13. greedy: true,
  14. inside: {
  15. 'internal-subset': {
  16. pattern: /(^[^\[]*\[)[\s\S]+(?=\]>$)/,
  17. lookbehind: true,
  18. greedy: true,
  19. inside: null // see below
  20. },
  21. 'string': {
  22. pattern: /"[^"]*"|'[^']*'/,
  23. greedy: true
  24. },
  25. 'punctuation': /^<!|>$|[[\]]/,
  26. 'doctype-tag': /^DOCTYPE/i,
  27. 'name': /[^\s<>'"]+/
  28. }
  29. },
  30. 'cdata': {
  31. pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
  32. greedy: true
  33. },
  34. 'tag': {
  35. pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,
  36. greedy: true,
  37. inside: {
  38. 'tag': {
  39. pattern: /^<\/?[^\s>\/]+/,
  40. inside: {
  41. 'punctuation': /^<\/?/,
  42. 'namespace': /^[^\s>\/:]+:/
  43. }
  44. },
  45. 'special-attr': [],
  46. 'attr-value': {
  47. pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,
  48. inside: {
  49. 'punctuation': [
  50. {
  51. pattern: /^=/,
  52. alias: 'attr-equals'
  53. },
  54. {
  55. pattern: /^(\s*)["']|["']$/,
  56. lookbehind: true
  57. }
  58. ]
  59. }
  60. },
  61. 'punctuation': /\/?>/,
  62. 'attr-name': {
  63. pattern: /[^\s>\/]+/,
  64. inside: {
  65. 'namespace': /^[^\s>\/:]+:/
  66. }
  67. }
  68. }
  69. },
  70. 'entity': [
  71. {
  72. pattern: /&[\da-z]{1,8};/i,
  73. alias: 'named-entity'
  74. },
  75. /&#x?[\da-f]{1,8};/i
  76. ]
  77. };
  78. Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
  79. Prism.languages.markup['entity'];
  80. Prism.languages.markup['doctype'].inside['internal-subset'].inside = Prism.languages.markup;
  81. // Plugin to make entity title show the real entity, idea by Roman Komarov
  82. Prism.hooks.add('wrap', function (env) {
  83. if (env.type === 'entity') {
  84. env.attributes['title'] = env.content.replace(/&amp;/, '&');
  85. }
  86. });
  87. Object.defineProperty(Prism.languages.markup.tag, 'addInlined', {
  88. /**
  89. * Adds an inlined language to markup.
  90. *
  91. * An example of an inlined language is CSS with `<style>` tags.
  92. *
  93. * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
  94. * case insensitive.
  95. * @param {string} lang The language key.
  96. * @example
  97. * addInlined('style', 'css');
  98. */
  99. value: function addInlined(tagName, lang) {
  100. var includedCdataInside = {};
  101. includedCdataInside['language-' + lang] = {
  102. pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
  103. lookbehind: true,
  104. inside: Prism.languages[lang]
  105. };
  106. includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i;
  107. var inside = {
  108. 'included-cdata': {
  109. pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
  110. inside: includedCdataInside
  111. }
  112. };
  113. inside['language-' + lang] = {
  114. pattern: /[\s\S]+/,
  115. inside: Prism.languages[lang]
  116. };
  117. var def = {};
  118. def[tagName] = {
  119. pattern: RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g, function () { return tagName; }), 'i'),
  120. lookbehind: true,
  121. greedy: true,
  122. inside: inside
  123. };
  124. Prism.languages.insertBefore('markup', 'cdata', def);
  125. }
  126. });
  127. Object.defineProperty(Prism.languages.markup.tag, 'addAttribute', {
  128. /**
  129. * Adds an pattern to highlight languages embedded in HTML attributes.
  130. *
  131. * An example of an inlined language is CSS with `style` attributes.
  132. *
  133. * @param {string} attrName The name of the tag that contains the inlined language. This name will be treated as
  134. * case insensitive.
  135. * @param {string} lang The language key.
  136. * @example
  137. * addAttribute('style', 'css');
  138. */
  139. value: function (attrName, lang) {
  140. Prism.languages.markup.tag.inside['special-attr'].push({
  141. pattern: RegExp(
  142. /(^|["'\s])/.source + '(?:' + attrName + ')' + /\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,
  143. 'i'
  144. ),
  145. lookbehind: true,
  146. inside: {
  147. 'attr-name': /^[^\s=]+/,
  148. 'attr-value': {
  149. pattern: /=[\s\S]+/,
  150. inside: {
  151. 'value': {
  152. pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,
  153. lookbehind: true,
  154. alias: [lang, 'language-' + lang],
  155. inside: Prism.languages[lang]
  156. },
  157. 'punctuation': [
  158. {
  159. pattern: /^=/,
  160. alias: 'attr-equals'
  161. },
  162. /"|'/
  163. ]
  164. }
  165. }
  166. }
  167. });
  168. }
  169. });
  170. Prism.languages.html = Prism.languages.markup;
  171. Prism.languages.mathml = Prism.languages.markup;
  172. Prism.languages.svg = Prism.languages.markup;
  173. Prism.languages.xml = Prism.languages.extend('markup', {});
  174. Prism.languages.ssml = Prism.languages.xml;
  175. Prism.languages.atom = Prism.languages.xml;
  176. Prism.languages.rss = Prism.languages.xml;