prism-markup.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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. ]
  56. }
  57. },
  58. 'punctuation': /\/?>/,
  59. 'attr-name': {
  60. pattern: /[^\s>\/]+/,
  61. inside: {
  62. 'namespace': /^[^\s>\/:]+:/
  63. }
  64. }
  65. }
  66. },
  67. 'entity': [
  68. {
  69. pattern: /&[\da-z]{1,8};/i,
  70. alias: 'named-entity'
  71. },
  72. /&#x?[\da-f]{1,8};/i
  73. ]
  74. };
  75. Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
  76. Prism.languages.markup['entity'];
  77. Prism.languages.markup['doctype'].inside['internal-subset'].inside = Prism.languages.markup;
  78. // Plugin to make entity title show the real entity, idea by Roman Komarov
  79. Prism.hooks.add('wrap', function (env) {
  80. if (env.type === 'entity') {
  81. env.attributes['title'] = env.content.replace(/&amp;/, '&');
  82. }
  83. });
  84. Object.defineProperty(Prism.languages.markup.tag, 'addInlined', {
  85. /**
  86. * Adds an inlined language to markup.
  87. *
  88. * An example of an inlined language is CSS with `<style>` tags.
  89. *
  90. * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
  91. * case insensitive.
  92. * @param {string} lang The language key.
  93. * @example
  94. * addInlined('style', 'css');
  95. */
  96. value: function addInlined(tagName, lang) {
  97. var includedCdataInside = {};
  98. includedCdataInside['language-' + lang] = {
  99. pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
  100. lookbehind: true,
  101. inside: Prism.languages[lang]
  102. };
  103. includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i;
  104. var inside = {
  105. 'included-cdata': {
  106. pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
  107. inside: includedCdataInside
  108. }
  109. };
  110. inside['language-' + lang] = {
  111. pattern: /[\s\S]+/,
  112. inside: Prism.languages[lang]
  113. };
  114. var def = {};
  115. def[tagName] = {
  116. pattern: RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g, function () { return tagName; }), 'i'),
  117. lookbehind: true,
  118. greedy: true,
  119. inside: inside
  120. };
  121. Prism.languages.insertBefore('markup', 'cdata', def);
  122. }
  123. });
  124. Object.defineProperty(Prism.languages.markup.tag, 'addAttribute', {
  125. /**
  126. * Adds an pattern to highlight languages embedded in HTML attributes.
  127. *
  128. * An example of an inlined language is CSS with `style` attributes.
  129. *
  130. * @param {string} attrName The name of the tag that contains the inlined language. This name will be treated as
  131. * case insensitive.
  132. * @param {string} lang The language key.
  133. * @example
  134. * addAttribute('style', 'css');
  135. */
  136. value: function (attrName, lang) {
  137. Prism.languages.markup.tag.inside['special-attr'].push({
  138. pattern: RegExp(
  139. /(^|["'\s])/.source + '(?:' + attrName + ')' + /\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,
  140. 'i'
  141. ),
  142. lookbehind: true,
  143. inside: {
  144. 'attr-name': /^[^\s=]+/,
  145. 'attr-value': {
  146. pattern: /=[\s\S]+/,
  147. inside: {
  148. 'value': {
  149. pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,
  150. lookbehind: true,
  151. alias: [lang, 'language-' + lang],
  152. inside: Prism.languages[lang]
  153. },
  154. 'punctuation': [
  155. {
  156. pattern: /^=/,
  157. alias: 'attr-equals'
  158. },
  159. /"|'/
  160. ]
  161. }
  162. }
  163. }
  164. });
  165. }
  166. });
  167. Prism.languages.html = Prism.languages.markup;
  168. Prism.languages.mathml = Prism.languages.markup;
  169. Prism.languages.svg = Prism.languages.markup;
  170. Prism.languages.xml = Prism.languages.extend('markup', {});
  171. Prism.languages.ssml = Prism.languages.xml;
  172. Prism.languages.atom = Prism.languages.xml;
  173. Prism.languages.rss = Prism.languages.xml;