prism.js 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229
  1. /* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+c+cpp+coffeescript+ruby+elixir+go+lua+nginx+php+python+rust+typescript */
  2. var _self = (typeof window !== 'undefined')
  3. ? window // if in browser
  4. : (
  5. (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
  6. ? self // if in worker
  7. : {} // if in node js
  8. );
  9. /**
  10. * Prism: Lightweight, robust, elegant syntax highlighting
  11. * MIT license http://www.opensource.org/licenses/mit-license.php/
  12. * @author Lea Verou http://lea.verou.me
  13. */
  14. var Prism = (function(){
  15. // Private helper vars
  16. var lang = /\blang(?:uage)?-(\w+)\b/i;
  17. var uniqueId = 0;
  18. var _ = _self.Prism = {
  19. util: {
  20. encode: function (tokens) {
  21. if (tokens instanceof Token) {
  22. return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias);
  23. } else if (_.util.type(tokens) === 'Array') {
  24. return tokens.map(_.util.encode);
  25. } else {
  26. return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
  27. }
  28. },
  29. type: function (o) {
  30. return Object.prototype.toString.call(o).match(/\[object (\w+)\]/)[1];
  31. },
  32. objId: function (obj) {
  33. if (!obj['__id']) {
  34. Object.defineProperty(obj, '__id', { value: ++uniqueId });
  35. }
  36. return obj['__id'];
  37. },
  38. // Deep clone a language definition (e.g. to extend it)
  39. clone: function (o) {
  40. var type = _.util.type(o);
  41. switch (type) {
  42. case 'Object':
  43. var clone = {};
  44. for (var key in o) {
  45. if (o.hasOwnProperty(key)) {
  46. clone[key] = _.util.clone(o[key]);
  47. }
  48. }
  49. return clone;
  50. case 'Array':
  51. // Check for existence for IE8
  52. return o.map && o.map(function(v) { return _.util.clone(v); });
  53. }
  54. return o;
  55. }
  56. },
  57. languages: {
  58. extend: function (id, redef) {
  59. var lang = _.util.clone(_.languages[id]);
  60. for (var key in redef) {
  61. lang[key] = redef[key];
  62. }
  63. return lang;
  64. },
  65. /**
  66. * Insert a token before another token in a language literal
  67. * As this needs to recreate the object (we cannot actually insert before keys in object literals),
  68. * we cannot just provide an object, we need anobject and a key.
  69. * @param inside The key (or language id) of the parent
  70. * @param before The key to insert before. If not provided, the function appends instead.
  71. * @param insert Object with the key/value pairs to insert
  72. * @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted.
  73. */
  74. insertBefore: function (inside, before, insert, root) {
  75. root = root || _.languages;
  76. var grammar = root[inside];
  77. if (arguments.length == 2) {
  78. insert = arguments[1];
  79. for (var newToken in insert) {
  80. if (insert.hasOwnProperty(newToken)) {
  81. grammar[newToken] = insert[newToken];
  82. }
  83. }
  84. return grammar;
  85. }
  86. var ret = {};
  87. for (var token in grammar) {
  88. if (grammar.hasOwnProperty(token)) {
  89. if (token == before) {
  90. for (var newToken in insert) {
  91. if (insert.hasOwnProperty(newToken)) {
  92. ret[newToken] = insert[newToken];
  93. }
  94. }
  95. }
  96. ret[token] = grammar[token];
  97. }
  98. }
  99. // Update references in other language definitions
  100. _.languages.DFS(_.languages, function(key, value) {
  101. if (value === root[inside] && key != inside) {
  102. this[key] = ret;
  103. }
  104. });
  105. return root[inside] = ret;
  106. },
  107. // Traverse a language definition with Depth First Search
  108. DFS: function(o, callback, type, visited) {
  109. visited = visited || {};
  110. for (var i in o) {
  111. if (o.hasOwnProperty(i)) {
  112. callback.call(o, i, o[i], type || i);
  113. if (_.util.type(o[i]) === 'Object' && !visited[_.util.objId(o[i])]) {
  114. visited[_.util.objId(o[i])] = true;
  115. _.languages.DFS(o[i], callback, null, visited);
  116. }
  117. else if (_.util.type(o[i]) === 'Array' && !visited[_.util.objId(o[i])]) {
  118. visited[_.util.objId(o[i])] = true;
  119. _.languages.DFS(o[i], callback, i, visited);
  120. }
  121. }
  122. }
  123. }
  124. },
  125. plugins: {},
  126. highlightAll: function(async, callback) {
  127. var env = {
  128. callback: callback,
  129. selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
  130. };
  131. _.hooks.run("before-highlightall", env);
  132. var elements = env.elements || document.querySelectorAll(env.selector);
  133. for (var i=0, element; element = elements[i++];) {
  134. _.highlightElement(element, async === true, env.callback);
  135. }
  136. },
  137. highlightElement: function(element, async, callback) {
  138. // Find language
  139. var language, grammar, parent = element;
  140. while (parent && !lang.test(parent.className)) {
  141. parent = parent.parentNode;
  142. }
  143. if (parent) {
  144. language = (parent.className.match(lang) || [,''])[1];
  145. grammar = _.languages[language];
  146. }
  147. // Set language on the element, if not present
  148. element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
  149. // Set language on the parent, for styling
  150. parent = element.parentNode;
  151. if (/pre/i.test(parent.nodeName)) {
  152. parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
  153. }
  154. var code = element.textContent;
  155. var env = {
  156. element: element,
  157. language: language,
  158. grammar: grammar,
  159. code: code
  160. };
  161. if (!code || !grammar) {
  162. _.hooks.run('complete', env);
  163. return;
  164. }
  165. _.hooks.run('before-highlight', env);
  166. // if (async && _self.Worker) {
  167. // var worker = new Worker(_.filename);
  168. // worker.onmessage = function(evt) {
  169. // env.highlightedCode = evt.data;
  170. // _.hooks.run('before-insert', env);
  171. // env.element.innerHTML = env.highlightedCode;
  172. // callback && callback.call(env.element);
  173. // _.hooks.run('after-highlight', env);
  174. // _.hooks.run('complete', env);
  175. // };
  176. // worker.postMessage(JSON.stringify({
  177. // language: env.language,
  178. // code: env.code,
  179. // immediateClose: true
  180. // }));
  181. // }
  182. // else {
  183. env.highlightedCode = _.highlight(env.code, env.grammar, env.language);
  184. _.hooks.run('before-insert', env);
  185. env.element.innerHTML = env.highlightedCode;
  186. callback && callback.call(element);
  187. _.hooks.run('after-highlight', env);
  188. _.hooks.run('complete', env);
  189. // }
  190. },
  191. highlight: function (text, grammar, language) {
  192. var tokens = _.tokenize(text, grammar);
  193. return Token.stringify(_.util.encode(tokens), language);
  194. },
  195. tokenize: function(text, grammar, language) {
  196. var Token = _.Token;
  197. var strarr = [text];
  198. var rest = grammar.rest;
  199. if (rest) {
  200. for (var token in rest) {
  201. grammar[token] = rest[token];
  202. }
  203. delete grammar.rest;
  204. }
  205. tokenloop: for (var token in grammar) {
  206. if(!grammar.hasOwnProperty(token) || !grammar[token]) {
  207. continue;
  208. }
  209. var patterns = grammar[token];
  210. patterns = (_.util.type(patterns) === "Array") ? patterns : [patterns];
  211. for (var j = 0; j < patterns.length; ++j) {
  212. var pattern = patterns[j],
  213. inside = pattern.inside,
  214. lookbehind = !!pattern.lookbehind,
  215. greedy = !!pattern.greedy,
  216. lookbehindLength = 0,
  217. alias = pattern.alias;
  218. pattern = pattern.pattern || pattern;
  219. for (var i=0; i<strarr.length; i++) { // Don’t cache length as it changes during the loop
  220. var str = strarr[i];
  221. if (strarr.length > text.length) {
  222. // Something went terribly wrong, ABORT, ABORT!
  223. break tokenloop;
  224. }
  225. if (str instanceof Token) {
  226. continue;
  227. }
  228. pattern.lastIndex = 0;
  229. var match = pattern.exec(str),
  230. delNum = 1;
  231. // Greedy patterns can override/remove up to two previously matched tokens
  232. if (!match && greedy && i != strarr.length - 1) {
  233. // Reconstruct the original text using the next two tokens
  234. var nextToken = strarr[i + 1].matchedStr || strarr[i + 1],
  235. combStr = str + nextToken;
  236. if (i < strarr.length - 2) {
  237. combStr += strarr[i + 2].matchedStr || strarr[i + 2];
  238. }
  239. // Try the pattern again on the reconstructed text
  240. pattern.lastIndex = 0;
  241. match = pattern.exec(combStr);
  242. if (!match) {
  243. continue;
  244. }
  245. var from = match.index + (lookbehind ? match[1].length : 0);
  246. // To be a valid candidate, the new match has to start inside of str
  247. if (from >= str.length) {
  248. continue;
  249. }
  250. var to = match.index + match[0].length,
  251. len = str.length + nextToken.length;
  252. // Number of tokens to delete and replace with the new match
  253. delNum = 3;
  254. if (to <= len) {
  255. if (strarr[i + 1].greedy) {
  256. continue;
  257. }
  258. delNum = 2;
  259. combStr = combStr.slice(0, len);
  260. }
  261. str = combStr;
  262. }
  263. if (!match) {
  264. continue;
  265. }
  266. if(lookbehind) {
  267. lookbehindLength = match[1].length;
  268. }
  269. var from = match.index + lookbehindLength,
  270. match = match[0].slice(lookbehindLength),
  271. to = from + match.length,
  272. before = str.slice(0, from),
  273. after = str.slice(to);
  274. var args = [i, delNum];
  275. if (before) {
  276. args.push(before);
  277. }
  278. var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias, match, greedy);
  279. args.push(wrapped);
  280. if (after) {
  281. args.push(after);
  282. }
  283. Array.prototype.splice.apply(strarr, args);
  284. }
  285. }
  286. }
  287. return strarr;
  288. },
  289. hooks: {
  290. all: {},
  291. add: function (name, callback) {
  292. var hooks = _.hooks.all;
  293. hooks[name] = hooks[name] || [];
  294. hooks[name].push(callback);
  295. },
  296. run: function (name, env) {
  297. var callbacks = _.hooks.all[name];
  298. if (!callbacks || !callbacks.length) {
  299. return;
  300. }
  301. for (var i=0, callback; callback = callbacks[i++];) {
  302. callback(env);
  303. }
  304. }
  305. }
  306. };
  307. var Token = _.Token = function(type, content, alias, matchedStr, greedy) {
  308. this.type = type;
  309. this.content = content;
  310. this.alias = alias;
  311. // Copy of the full string this token was created from
  312. this.matchedStr = matchedStr || null;
  313. this.greedy = !!greedy;
  314. };
  315. Token.stringify = function(o, language, parent) {
  316. if (typeof o == 'string') {
  317. return o;
  318. }
  319. if (_.util.type(o) === 'Array') {
  320. return o.map(function(element) {
  321. return Token.stringify(element, language, o);
  322. }).join('');
  323. }
  324. var env = {
  325. type: o.type,
  326. content: Token.stringify(o.content, language, parent),
  327. tag: 'span',
  328. classes: ['token', o.type],
  329. attributes: {},
  330. language: language,
  331. parent: parent
  332. };
  333. if (env.type == 'comment') {
  334. env.attributes['spellcheck'] = 'true';
  335. }
  336. if (o.alias) {
  337. var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias];
  338. Array.prototype.push.apply(env.classes, aliases);
  339. }
  340. _.hooks.run('wrap', env);
  341. var attributes = '';
  342. for (var name in env.attributes) {
  343. attributes += (attributes ? ' ' : '') + name + '="' + (env.attributes[name] || '') + '"';
  344. }
  345. return '<' + env.tag + ' class="' + env.classes.join(' ') + '" ' + attributes + '>' + env.content + '</' + env.tag + '>';
  346. };
  347. // if (!_self.document) {
  348. // if (!_self.addEventListener) {
  349. // // in Node.js
  350. // return _self.Prism;
  351. // }
  352. // // In worker
  353. // _self.addEventListener('message', function(evt) {
  354. // var message = JSON.parse(evt.data),
  355. // lang = message.language,
  356. // code = message.code,
  357. // immediateClose = message.immediateClose;
  358. // _self.postMessage(_.highlight(code, _.languages[lang], lang));
  359. // if (immediateClose) {
  360. // _self.close();
  361. // }
  362. // }, false);
  363. // return _self.Prism;
  364. // }
  365. // //Get current script and highlight
  366. // var script = document.currentScript || [].slice.call(document.getElementsByTagName("script")).pop();
  367. // if (script) {
  368. // _.filename = script.src;
  369. // if (document.addEventListener && !script.hasAttribute('data-manual')) {
  370. // document.addEventListener('DOMContentLoaded', _.highlightAll);
  371. // }
  372. // }
  373. return _self.Prism;
  374. })();
  375. if (typeof module !== 'undefined' && module.exports) {
  376. module.exports = Prism;
  377. }
  378. // hack for components to work correctly in node.js
  379. if (typeof global !== 'undefined') {
  380. global.Prism = Prism;
  381. }
  382. ;
  383. Prism.languages.markup = {
  384. 'comment': /<!--[\w\W]*?-->/,
  385. 'prolog': /<\?[\w\W]+?\?>/,
  386. 'doctype': /<!DOCTYPE[\w\W]+?>/,
  387. 'cdata': /<!\[CDATA\[[\w\W]*?]]>/i,
  388. 'tag': {
  389. pattern: /<\/?(?!\d)[^\s>\/=.$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i,
  390. inside: {
  391. 'tag': {
  392. pattern: /^<\/?[^\s>\/]+/i,
  393. inside: {
  394. 'punctuation': /^<\/?/,
  395. 'namespace': /^[^\s>\/:]+:/
  396. }
  397. },
  398. 'attr-value': {
  399. pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,
  400. inside: {
  401. 'punctuation': /[=>"']/
  402. }
  403. },
  404. 'punctuation': /\/?>/,
  405. 'attr-name': {
  406. pattern: /[^\s>\/]+/,
  407. inside: {
  408. 'namespace': /^[^\s>\/:]+:/
  409. }
  410. }
  411. }
  412. },
  413. 'entity': /&#?[\da-z]{1,8};/i
  414. };
  415. // Plugin to make entity title show the real entity, idea by Roman Komarov
  416. Prism.hooks.add('wrap', function(env) {
  417. if (env.type === 'entity') {
  418. env.attributes['title'] = env.content.replace(/&amp;/, '&');
  419. }
  420. });
  421. Prism.languages.xml = Prism.languages.markup;
  422. Prism.languages.html = Prism.languages.markup;
  423. Prism.languages.mathml = Prism.languages.markup;
  424. Prism.languages.svg = Prism.languages.markup;
  425. Prism.languages.css = {
  426. 'comment': /\/\*[\w\W]*?\*\//,
  427. 'atrule': {
  428. pattern: /@[\w-]+?.*?(;|(?=\s*\{))/i,
  429. inside: {
  430. 'rule': /@[\w-]+/
  431. // See rest below
  432. }
  433. },
  434. 'url': /url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,
  435. 'selector': /[^\{\}\s][^\{\};]*?(?=\s*\{)/,
  436. 'string': /("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/,
  437. 'property': /(\b|\B)[\w-]+(?=\s*:)/i,
  438. 'important': /\B!important\b/i,
  439. 'function': /[-a-z0-9]+(?=\()/i,
  440. 'punctuation': /[(){};:]/
  441. };
  442. Prism.languages.css['atrule'].inside.rest = Prism.util.clone(Prism.languages.css);
  443. if (Prism.languages.markup) {
  444. Prism.languages.insertBefore('markup', 'tag', {
  445. 'style': {
  446. pattern: /(<style[\w\W]*?>)[\w\W]*?(?=<\/style>)/i,
  447. lookbehind: true,
  448. inside: Prism.languages.css,
  449. alias: 'language-css'
  450. }
  451. });
  452. Prism.languages.insertBefore('inside', 'attr-value', {
  453. 'style-attr': {
  454. pattern: /\s*style=("|').*?\1/i,
  455. inside: {
  456. 'attr-name': {
  457. pattern: /^\s*style/i,
  458. inside: Prism.languages.markup.tag.inside
  459. },
  460. 'punctuation': /^\s*=\s*['"]|['"]\s*$/,
  461. 'attr-value': {
  462. pattern: /.+/i,
  463. inside: Prism.languages.css
  464. }
  465. },
  466. alias: 'language-css'
  467. }
  468. }, Prism.languages.markup.tag);
  469. };
  470. Prism.languages.clike = {
  471. 'comment': [
  472. {
  473. pattern: /(^|[^\\])\/\*[\w\W]*?\*\//,
  474. lookbehind: true
  475. },
  476. {
  477. pattern: /(^|[^\\:])\/\/.*/,
  478. lookbehind: true
  479. }
  480. ],
  481. 'string': {
  482. pattern: /(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
  483. greedy: true
  484. },
  485. 'class-name': {
  486. pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,
  487. lookbehind: true,
  488. inside: {
  489. punctuation: /(\.|\\)/
  490. }
  491. },
  492. 'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
  493. 'boolean': /\b(true|false)\b/,
  494. 'function': /[a-z0-9_]+(?=\()/i,
  495. 'number': /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,
  496. 'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,
  497. 'punctuation': /[{}[\];(),.:]/
  498. };
  499. Prism.languages.javascript = Prism.languages.extend('clike', {
  500. 'keyword': /\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,
  501. 'number': /\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,
  502. // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
  503. 'function': /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i
  504. });
  505. Prism.languages.insertBefore('javascript', 'keyword', {
  506. 'regex': {
  507. pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,
  508. lookbehind: true,
  509. greedy: true
  510. }
  511. });
  512. Prism.languages.insertBefore('javascript', 'class-name', {
  513. 'template-string': {
  514. pattern: /`(?:\\\\|\\?[^\\])*?`/,
  515. greedy: true,
  516. inside: {
  517. 'interpolation': {
  518. pattern: /\$\{[^}]+\}/,
  519. inside: {
  520. 'interpolation-punctuation': {
  521. pattern: /^\$\{|\}$/,
  522. alias: 'punctuation'
  523. },
  524. rest: Prism.languages.javascript
  525. }
  526. },
  527. 'string': /[\s\S]+/
  528. }
  529. }
  530. });
  531. if (Prism.languages.markup) {
  532. Prism.languages.insertBefore('markup', 'tag', {
  533. 'script': {
  534. pattern: /(<script[\w\W]*?>)[\w\W]*?(?=<\/script>)/i,
  535. lookbehind: true,
  536. inside: Prism.languages.javascript,
  537. alias: 'language-javascript'
  538. }
  539. });
  540. }
  541. Prism.languages.js = Prism.languages.javascript;
  542. Prism.languages.c = Prism.languages.extend('clike', {
  543. 'keyword': /\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,
  544. 'operator': /\-[>-]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|?\||[~^%?*\/]/,
  545. 'number': /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)[ful]*\b/i
  546. });
  547. Prism.languages.insertBefore('c', 'string', {
  548. 'macro': {
  549. // allow for multiline macro definitions
  550. // spaces after the # character compile fine with gcc
  551. pattern: /(^\s*)#\s*[a-z]+([^\r\n\\]|\\.|\\(?:\r\n?|\n))*/im,
  552. lookbehind: true,
  553. alias: 'property',
  554. inside: {
  555. // highlight the path of the include statement as a string
  556. 'string': {
  557. pattern: /(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/,
  558. lookbehind: true
  559. },
  560. // highlight macro directives as keywords
  561. 'directive': {
  562. pattern: /(#\s*)\b(define|elif|else|endif|error|ifdef|ifndef|if|import|include|line|pragma|undef|using)\b/,
  563. lookbehind: true,
  564. alias: 'keyword'
  565. }
  566. }
  567. },
  568. // highlight predefined macros as constants
  569. 'constant': /\b(__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|stdin|stdout|stderr)\b/
  570. });
  571. delete Prism.languages.c['class-name'];
  572. delete Prism.languages.c['boolean'];
  573. Prism.languages.cpp = Prism.languages.extend('c', {
  574. 'keyword': /\b(alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,
  575. 'boolean': /\b(true|false)\b/,
  576. 'operator': /[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|:{1,2}|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\/|\b(and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/
  577. });
  578. Prism.languages.insertBefore('cpp', 'keyword', {
  579. 'class-name': {
  580. pattern: /(class\s+)[a-z0-9_]+/i,
  581. lookbehind: true
  582. }
  583. });
  584. (function(Prism) {
  585. // Ignore comments starting with { to privilege string interpolation highlighting
  586. var comment = /#(?!\{).+/,
  587. interpolation = {
  588. pattern: /#\{[^}]+\}/,
  589. alias: 'variable'
  590. };
  591. Prism.languages.coffeescript = Prism.languages.extend('javascript', {
  592. 'comment': comment,
  593. 'string': [
  594. // Strings are multiline
  595. /'(?:\\?[^\\])*?'/,
  596. {
  597. // Strings are multiline
  598. pattern: /"(?:\\?[^\\])*?"/,
  599. inside: {
  600. 'interpolation': interpolation
  601. }
  602. }
  603. ],
  604. 'keyword': /\b(and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,
  605. 'class-member': {
  606. pattern: /@(?!\d)\w+/,
  607. alias: 'variable'
  608. }
  609. });
  610. Prism.languages.insertBefore('coffeescript', 'comment', {
  611. 'multiline-comment': {
  612. pattern: /###[\s\S]+?###/,
  613. alias: 'comment'
  614. },
  615. // Block regexp can contain comments and interpolation
  616. 'block-regex': {
  617. pattern: /\/{3}[\s\S]*?\/{3}/,
  618. alias: 'regex',
  619. inside: {
  620. 'comment': comment,
  621. 'interpolation': interpolation
  622. }
  623. }
  624. });
  625. Prism.languages.insertBefore('coffeescript', 'string', {
  626. 'inline-javascript': {
  627. pattern: /`(?:\\?[\s\S])*?`/,
  628. inside: {
  629. 'delimiter': {
  630. pattern: /^`|`$/,
  631. alias: 'punctuation'
  632. },
  633. rest: Prism.languages.javascript
  634. }
  635. },
  636. // Block strings
  637. 'multiline-string': [
  638. {
  639. pattern: /'''[\s\S]*?'''/,
  640. alias: 'string'
  641. },
  642. {
  643. pattern: /"""[\s\S]*?"""/,
  644. alias: 'string',
  645. inside: {
  646. interpolation: interpolation
  647. }
  648. }
  649. ]
  650. });
  651. Prism.languages.insertBefore('coffeescript', 'keyword', {
  652. // Object property
  653. 'property': /(?!\d)\w+(?=\s*:(?!:))/
  654. });
  655. }(Prism));
  656. /**
  657. * Original by Samuel Flores
  658. *
  659. * Adds the following new token classes:
  660. * constant, builtin, variable, symbol, regex
  661. */
  662. (function(Prism) {
  663. Prism.languages.ruby = Prism.languages.extend('clike', {
  664. 'comment': /#(?!\{[^\r\n]*?\}).*/,
  665. 'keyword': /\b(alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/
  666. });
  667. var interpolation = {
  668. pattern: /#\{[^}]+\}/,
  669. inside: {
  670. 'delimiter': {
  671. pattern: /^#\{|\}$/,
  672. alias: 'tag'
  673. },
  674. rest: Prism.util.clone(Prism.languages.ruby)
  675. }
  676. };
  677. Prism.languages.insertBefore('ruby', 'keyword', {
  678. 'regex': [
  679. {
  680. pattern: /%r([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1[gim]{0,3}/,
  681. inside: {
  682. 'interpolation': interpolation
  683. }
  684. },
  685. {
  686. pattern: /%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/,
  687. inside: {
  688. 'interpolation': interpolation
  689. }
  690. },
  691. {
  692. // Here we need to specifically allow interpolation
  693. pattern: /%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/,
  694. inside: {
  695. 'interpolation': interpolation
  696. }
  697. },
  698. {
  699. pattern: /%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/,
  700. inside: {
  701. 'interpolation': interpolation
  702. }
  703. },
  704. {
  705. pattern: /%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/,
  706. inside: {
  707. 'interpolation': interpolation
  708. }
  709. },
  710. {
  711. pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,
  712. lookbehind: true
  713. }
  714. ],
  715. 'variable': /[@$]+[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/,
  716. 'symbol': /:[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/
  717. });
  718. Prism.languages.insertBefore('ruby', 'number', {
  719. 'builtin': /\b(Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|File|Fixnum|Fload|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,
  720. 'constant': /\b[A-Z][a-zA-Z_0-9]*(?:[?!]|\b)/
  721. });
  722. Prism.languages.ruby.string = [
  723. {
  724. pattern: /%[qQiIwWxs]?([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1/,
  725. inside: {
  726. 'interpolation': interpolation
  727. }
  728. },
  729. {
  730. pattern: /%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/,
  731. inside: {
  732. 'interpolation': interpolation
  733. }
  734. },
  735. {
  736. // Here we need to specifically allow interpolation
  737. pattern: /%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/,
  738. inside: {
  739. 'interpolation': interpolation
  740. }
  741. },
  742. {
  743. pattern: /%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/,
  744. inside: {
  745. 'interpolation': interpolation
  746. }
  747. },
  748. {
  749. pattern: /%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/,
  750. inside: {
  751. 'interpolation': interpolation
  752. }
  753. },
  754. {
  755. pattern: /("|')(#\{[^}]+\}|\\(?:\r?\n|\r)|\\?.)*?\1/,
  756. inside: {
  757. 'interpolation': interpolation
  758. }
  759. }
  760. ];
  761. }(Prism));
  762. Prism.languages.elixir = {
  763. // Negative look-ahead is needed for string interpolation
  764. // Negative look-behind is needed to avoid highlighting markdown headers in
  765. // multi-line doc strings
  766. 'comment': {
  767. pattern: /(^|[^#])#(?![{#]).*/m,
  768. lookbehind: true
  769. },
  770. // ~r"""foo""", ~r'''foo''', ~r/foo/, ~r|foo|, ~r"foo", ~r'foo', ~r(foo), ~r[foo], ~r{foo}, ~r<foo>
  771. 'regex': /~[rR](?:("""|'''|[\/|"'])(?:\\.|(?!\1)[^\\])+\1|\((?:\\\)|[^)])+\)|\[(?:\\\]|[^\]])+\]|\{(?:\\\}|[^}])+\}|<(?:\\>|[^>])+>)[uismxfr]*/,
  772. 'string': [
  773. {
  774. // ~s"""foo""", ~s'''foo''', ~s/foo/, ~s|foo|, ~s"foo", ~s'foo', ~s(foo), ~s[foo], ~s{foo}, ~s<foo>
  775. pattern: /~[cCsSwW](?:("""|'''|[\/|"'])(?:\\.|(?!\1)[^\\])+\1|\((?:\\\)|[^)])+\)|\[(?:\\\]|[^\]])+\]|\{(?:\\\}|#\{[^}]+\}|[^}])+\}|<(?:\\>|[^>])+>)[csa]?/,
  776. inside: {
  777. // See interpolation below
  778. }
  779. },
  780. {
  781. pattern: /("""|''')[\s\S]*?\1/,
  782. inside: {
  783. // See interpolation below
  784. }
  785. },
  786. {
  787. // Multi-line strings are allowed
  788. pattern: /("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/,
  789. inside: {
  790. // See interpolation below
  791. }
  792. }
  793. ],
  794. 'atom': {
  795. // Look-behind prevents bad highlighting of the :: operator
  796. pattern: /(^|[^:]):\w+/,
  797. lookbehind: true,
  798. alias: 'symbol'
  799. },
  800. // Look-ahead prevents bad highlighting of the :: operator
  801. 'attr-name': /\w+:(?!:)/,
  802. 'capture': {
  803. // Look-behind prevents bad highlighting of the && operator
  804. pattern: /(^|[^&])&(?:[^&\s\d()][^\s()]*|(?=\())/,
  805. lookbehind: true,
  806. alias: 'function'
  807. },
  808. 'argument': {
  809. // Look-behind prevents bad highlighting of the && operator
  810. pattern: /(^|[^&])&\d+/,
  811. lookbehind: true,
  812. alias: 'variable'
  813. },
  814. 'attribute': {
  815. pattern: /@[\S]+/,
  816. alias: 'variable'
  817. },
  818. 'number': /\b(?:0[box][a-f\d_]+|\d[\d_]*)(?:\.[\d_]+)?(?:e[+-]?[\d_]+)?\b/i,
  819. 'keyword': /\b(?:after|alias|and|case|catch|cond|def(?:callback|exception|impl|module|p|protocol|struct)?|do|else|end|fn|for|if|import|not|or|require|rescue|try|unless|use|when)\b/,
  820. 'boolean': /\b(?:true|false|nil)\b/,
  821. 'operator': [
  822. /\bin\b|&&?|\|[|>]?|\\\\|::|\.\.\.?|\+\+?|-[->]?|<[-=>]|>=|!==?|\B!|=(?:==?|[>~])?|[*\/^]/,
  823. {
  824. // We don't want to match <<
  825. pattern: /([^<])<(?!<)/,
  826. lookbehind: true
  827. },
  828. {
  829. // We don't want to match >>
  830. pattern: /([^>])>(?!>)/,
  831. lookbehind: true
  832. }
  833. ],
  834. 'punctuation': /<<|>>|[.,%\[\]{}()]/
  835. };
  836. Prism.languages.elixir.string.forEach(function(o) {
  837. o.inside = {
  838. 'interpolation': {
  839. pattern: /#\{[^}]+\}/,
  840. inside: {
  841. 'delimiter': {
  842. pattern: /^#\{|\}$/,
  843. alias: 'punctuation'
  844. },
  845. rest: Prism.util.clone(Prism.languages.elixir)
  846. }
  847. }
  848. };
  849. });
  850. Prism.languages.go = Prism.languages.extend('clike', {
  851. 'keyword': /\b(break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,
  852. 'builtin': /\b(bool|byte|complex(64|128)|error|float(32|64)|rune|string|u?int(8|16|32|64|)|uintptr|append|cap|close|complex|copy|delete|imag|len|make|new|panic|print(ln)?|real|recover)\b/,
  853. 'boolean': /\b(_|iota|nil|true|false)\b/,
  854. 'operator': /[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,
  855. 'number': /\b(-?(0x[a-f\d]+|(\d+\.?\d*|\.\d+)(e[-+]?\d+)?)i?)\b/i,
  856. 'string': /("|'|`)(\\?.|\r|\n)*?\1/
  857. });
  858. delete Prism.languages.go['class-name'];
  859. Prism.languages.lua = {
  860. 'comment': /^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m,
  861. // \z may be used to skip the following space
  862. 'string': /(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[\s\S]))*\1|\[(=*)\[[\s\S]*?\]\2\]/,
  863. 'number': /\b0x[a-f\d]+\.?[a-f\d]*(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|\.?\d*(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i,
  864. 'keyword': /\b(?:and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,
  865. 'function': /(?!\d)\w+(?=\s*(?:[({]))/,
  866. 'operator': [
  867. /[-+*%^&|#]|\/\/?|<[<=]?|>[>=]?|[=~]=?/,
  868. {
  869. // Match ".." but don't break "..."
  870. pattern: /(^|[^.])\.\.(?!\.)/,
  871. lookbehind: true
  872. }
  873. ],
  874. 'punctuation': /[\[\](){},;]|\.+|:+/
  875. };
  876. Prism.languages.nginx = Prism.languages.extend('clike', {
  877. 'comment': {
  878. pattern: /(^|[^"{\\])#.*/,
  879. lookbehind: true
  880. },
  881. 'keyword': /\b(?:CONTENT_|DOCUMENT_|GATEWAY_|HTTP_|HTTPS|if_not_empty|PATH_|QUERY_|REDIRECT_|REMOTE_|REQUEST_|SCGI|SCRIPT_|SERVER_|http|server|events|location|include|accept_mutex|accept_mutex_delay|access_log|add_after_body|add_before_body|add_header|addition_types|aio|alias|allow|ancient_browser|ancient_browser_value|auth|auth_basic|auth_basic_user_file|auth_http|auth_http_header|auth_http_timeout|autoindex|autoindex_exact_size|autoindex_localtime|break|charset|charset_map|charset_types|chunked_transfer_encoding|client_body_buffer_size|client_body_in_file_only|client_body_in_single_buffer|client_body_temp_path|client_body_timeout|client_header_buffer_size|client_header_timeout|client_max_body_size|connection_pool_size|create_full_put_path|daemon|dav_access|dav_methods|debug_connection|debug_points|default_type|deny|devpoll_changes|devpoll_events|directio|directio_alignment|disable_symlinks|empty_gif|env|epoll_events|error_log|error_page|expires|fastcgi_buffer_size|fastcgi_buffers|fastcgi_busy_buffers_size|fastcgi_cache|fastcgi_cache_bypass|fastcgi_cache_key|fastcgi_cache_lock|fastcgi_cache_lock_timeout|fastcgi_cache_methods|fastcgi_cache_min_uses|fastcgi_cache_path|fastcgi_cache_purge|fastcgi_cache_use_stale|fastcgi_cache_valid|fastcgi_connect_timeout|fastcgi_hide_header|fastcgi_ignore_client_abort|fastcgi_ignore_headers|fastcgi_index|fastcgi_intercept_errors|fastcgi_keep_conn|fastcgi_max_temp_file_size|fastcgi_next_upstream|fastcgi_no_cache|fastcgi_param|fastcgi_pass|fastcgi_pass_header|fastcgi_read_timeout|fastcgi_redirect_errors|fastcgi_send_timeout|fastcgi_split_path_info|fastcgi_store|fastcgi_store_access|fastcgi_temp_file_write_size|fastcgi_temp_path|flv|geo|geoip_city|geoip_country|google_perftools_profiles|gzip|gzip_buffers|gzip_comp_level|gzip_disable|gzip_http_version|gzip_min_length|gzip_proxied|gzip_static|gzip_types|gzip_vary|if|if_modified_since|ignore_invalid_headers|image_filter|image_filter_buffer|image_filter_jpeg_quality|image_filter_sharpen|image_filter_transparency|imap_capabilities|imap_client_buffer|include|index|internal|ip_hash|keepalive|keepalive_disable|keepalive_requests|keepalive_timeout|kqueue_changes|kqueue_events|large_client_header_buffers|limit_conn|limit_conn_log_level|limit_conn_zone|limit_except|limit_rate|limit_rate_after|limit_req|limit_req_log_level|limit_req_zone|limit_zone|lingering_close|lingering_time|lingering_timeout|listen|location|lock_file|log_format|log_format_combined|log_not_found|log_subrequest|map|map_hash_bucket_size|map_hash_max_size|master_process|max_ranges|memcached_buffer_size|memcached_connect_timeout|memcached_next_upstream|memcached_pass|memcached_read_timeout|memcached_send_timeout|merge_slashes|min_delete_depth|modern_browser|modern_browser_value|mp4|mp4_buffer_size|mp4_max_buffer_size|msie_padding|msie_refresh|multi_accept|open_file_cache|open_file_cache_errors|open_file_cache_min_uses|open_file_cache_valid|open_log_file_cache|optimize_server_names|override_charset|pcre_jit|perl|perl_modules|perl_require|perl_set|pid|pop3_auth|pop3_capabilities|port_in_redirect|post_action|postpone_output|protocol|proxy|proxy_buffer|proxy_buffer_size|proxy_buffering|proxy_buffers|proxy_busy_buffers_size|proxy_cache|proxy_cache_bypass|proxy_cache_key|proxy_cache_lock|proxy_cache_lock_timeout|proxy_cache_methods|proxy_cache_min_uses|proxy_cache_path|proxy_cache_use_stale|proxy_cache_valid|proxy_connect_timeout|proxy_cookie_domain|proxy_cookie_path|proxy_headers_hash_bucket_size|proxy_headers_hash_max_size|proxy_hide_header|proxy_http_version|proxy_ignore_client_abort|proxy_ignore_headers|proxy_intercept_errors|proxy_max_temp_file_size|proxy_method|proxy_next_upstream|proxy_no_cache|proxy_pass|proxy_pass_error_message|proxy_pass_header|proxy_pass_request_body|proxy_pass_request_headers|proxy_read_timeout|proxy_redirect|proxy_redirect_errors|proxy_send_lowat|proxy_send_timeout|proxy_set_body|proxy_set_header|proxy_ssl_session_reuse|proxy_store|proxy_store_access|proxy_temp_file_write_size|proxy_temp_path|proxy_timeout|proxy_upstream_fail_timeout|proxy_upstream_max_fails|random_index|read_ahead|real_ip_header|recursive_error_pages|request_pool_size|reset_timedout_connection|resolver|resolver_timeout|return|rewrite|root|rtsig_overflow_events|rtsig_overflow_test|rtsig_overflow_threshold|rtsig_signo|satisfy|satisfy_any|secure_link_secret|send_lowat|send_timeout|sendfile|sendfile_max_chunk|server|server_name|server_name_in_redirect|server_names_hash_bucket_size|server_names_hash_max_size|server_tokens|set|set_real_ip_from|smtp_auth|smtp_capabilities|so_keepalive|source_charset|split_clients|ssi|ssi_silent_errors|ssi_types|ssi_value_length|ssl|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_client_certificate|ssl_crl|ssl_dhparam|ssl_engine|ssl_prefer_server_ciphers|ssl_protocols|ssl_session_cache|ssl_session_timeout|ssl_verify_client|ssl_verify_depth|starttls|stub_status|sub_filter|sub_filter_once|sub_filter_types|tcp_nodelay|tcp_nopush|timeout|timer_resolution|try_files|types|types_hash_bucket_size|types_hash_max_size|underscores_in_headers|uninitialized_variable_warn|upstream|use|user|userid|userid_domain|userid_expires|userid_name|userid_p3p|userid_path|userid_service|valid_referers|variables_hash_bucket_size|variables_hash_max_size|worker_connections|worker_cpu_affinity|worker_priority|worker_processes|worker_rlimit_core|worker_rlimit_nofile|worker_rlimit_sigpending|working_directory|xclient|xml_entities|xslt_entities|xslt_stylesheet|xslt_types)\b/i,
  882. });
  883. Prism.languages.insertBefore('nginx', 'keyword', {
  884. 'variable': /\$[a-z_]+/i
  885. });
  886. /**
  887. * Original by Aaron Harun: http://aahacreative.com/2012/07/31/php-syntax-highlighting-prism/
  888. * Modified by Miles Johnson: http://milesj.me
  889. *
  890. * Supports the following:
  891. * - Extends clike syntax
  892. * - Support for PHP 5.3+ (namespaces, traits, generators, etc)
  893. * - Smarter constant and function matching
  894. *
  895. * Adds the following new token classes:
  896. * constant, delimiter, variable, function, package
  897. */
  898. Prism.languages.php = Prism.languages.extend('clike', {
  899. 'keyword': /\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i,
  900. 'constant': /\b[A-Z0-9_]{2,}\b/,
  901. 'comment': {
  902. pattern: /(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/,
  903. lookbehind: true
  904. }
  905. });
  906. // Shell-like comments are matched after strings, because they are less
  907. // common than strings containing hashes...
  908. Prism.languages.insertBefore('php', 'class-name', {
  909. 'shell-comment': {
  910. pattern: /(^|[^\\])#.*/,
  911. lookbehind: true,
  912. alias: 'comment'
  913. }
  914. });
  915. Prism.languages.insertBefore('php', 'keyword', {
  916. 'delimiter': /\?>|<\?(?:php)?/i,
  917. 'variable': /\$\w+\b/i,
  918. 'package': {
  919. pattern: /(\\|namespace\s+|use\s+)[\w\\]+/,
  920. lookbehind: true,
  921. inside: {
  922. punctuation: /\\/
  923. }
  924. }
  925. });
  926. // Must be defined after the function pattern
  927. Prism.languages.insertBefore('php', 'operator', {
  928. 'property': {
  929. pattern: /(->)[\w]+/,
  930. lookbehind: true
  931. }
  932. });
  933. // Add HTML support of the markup language exists
  934. if (Prism.languages.markup) {
  935. // Tokenize all inline PHP blocks that are wrapped in <?php ?>
  936. // This allows for easy PHP + markup highlighting
  937. Prism.hooks.add('before-highlight', function(env) {
  938. if (env.language !== 'php') {
  939. return;
  940. }
  941. env.tokenStack = [];
  942. env.backupCode = env.code;
  943. env.code = env.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/ig, function(match) {
  944. env.tokenStack.push(match);
  945. return '{{{PHP' + env.tokenStack.length + '}}}';
  946. });
  947. });
  948. // Restore env.code for other plugins (e.g. line-numbers)
  949. Prism.hooks.add('before-insert', function(env) {
  950. if (env.language === 'php') {
  951. env.code = env.backupCode;
  952. delete env.backupCode;
  953. }
  954. });
  955. // Re-insert the tokens after highlighting
  956. Prism.hooks.add('after-highlight', function(env) {
  957. if (env.language !== 'php') {
  958. return;
  959. }
  960. for (var i = 0, t; t = env.tokenStack[i]; i++) {
  961. // The replace prevents $$, $&, $`, $', $n, $nn from being interpreted as special patterns
  962. env.highlightedCode = env.highlightedCode.replace('{{{PHP' + (i + 1) + '}}}', Prism.highlight(t, env.grammar, 'php').replace(/\$/g, '$$$$'));
  963. }
  964. env.element.innerHTML = env.highlightedCode;
  965. });
  966. // Wrap tokens in classes that are missing them
  967. Prism.hooks.add('wrap', function(env) {
  968. if (env.language === 'php' && env.type === 'markup') {
  969. env.content = env.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/g, "<span class=\"token php\">$1</span>");
  970. }
  971. });
  972. // Add the rules before all others
  973. Prism.languages.insertBefore('php', 'comment', {
  974. 'markup': {
  975. pattern: /<[^?]\/?(.*?)>/,
  976. inside: Prism.languages.markup
  977. },
  978. 'php': /\{\{\{PHP[0-9]+\}\}\}/
  979. });
  980. }
  981. ;
  982. Prism.languages.python= {
  983. 'triple-quoted-string': {
  984. pattern: /"""[\s\S]+?"""|'''[\s\S]+?'''/,
  985. alias: 'string'
  986. },
  987. 'comment': {
  988. pattern: /(^|[^\\])#.*/,
  989. lookbehind: true
  990. },
  991. 'string': /("|')(?:\\?.)*?\1/,
  992. 'function' : {
  993. pattern: /((?:^|\s)def[ \t]+)[a-zA-Z_][a-zA-Z0-9_]*(?=\()/g,
  994. lookbehind: true
  995. },
  996. 'class-name': {
  997. pattern: /(\bclass\s+)[a-z0-9_]+/i,
  998. lookbehind: true
  999. },
  1000. 'keyword' : /\b(?:as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/,
  1001. 'boolean' : /\b(?:True|False)\b/,
  1002. 'number' : /\b-?(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,
  1003. 'operator' : /[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/,
  1004. 'punctuation' : /[{}[\];(),.:]/
  1005. };
  1006. /* TODO
  1007. Add support for Markdown notation inside doc comments
  1008. Add support for nested block comments...
  1009. Match closure params even when not followed by dash or brace
  1010. Add better support for macro definition
  1011. */
  1012. Prism.languages.rust = {
  1013. 'comment': [
  1014. {
  1015. pattern: /(^|[^\\])\/\*[\w\W]*?\*\//,
  1016. lookbehind: true
  1017. },
  1018. {
  1019. pattern: /(^|[^\\:])\/\/.*/,
  1020. lookbehind: true
  1021. }
  1022. ],
  1023. 'string': [
  1024. /b?r(#*)"(?:\\?.)*?"\1/,
  1025. /b?("|')(?:\\?.)*?\1/
  1026. ],
  1027. 'keyword': /\b(?:abstract|alignof|as|be|box|break|const|continue|crate|do|else|enum|extern|false|final|fn|for|if|impl|in|let|loop|match|mod|move|mut|offsetof|once|override|priv|pub|pure|ref|return|sizeof|static|self|struct|super|true|trait|type|typeof|unsafe|unsized|use|virtual|where|while|yield)\b/,
  1028. 'attribute': {
  1029. pattern: /#!?\[.+?\]/,
  1030. alias: 'attr-name'
  1031. },
  1032. 'function': [
  1033. /[a-z0-9_]+(?=\s*\()/i,
  1034. // Macros can use parens or brackets
  1035. /[a-z0-9_]+!(?=\s*\(|\[)/i
  1036. ],
  1037. 'macro-rules': {
  1038. pattern: /[a-z0-9_]+!/i,
  1039. alias: 'function'
  1040. },
  1041. // Hex, oct, bin, dec numbers with visual separators and type suffix
  1042. 'number': /\b-?(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(\d(_?\d)*)?\.?\d(_?\d)*([Ee][+-]?\d+)?)(?:_?(?:[iu](?:8|16|32|64)?|f32|f64))?\b/,
  1043. // Closure params should not be confused with bitwise OR |
  1044. 'closure-params': {
  1045. pattern: /\|[^|]*\|(?=\s*[{-])/,
  1046. inside: {
  1047. 'punctuation': /[\|:,]/,
  1048. 'operator': /[&*]/
  1049. }
  1050. },
  1051. 'punctuation': /[{}[\];(),:]|\.+|->/,
  1052. 'operator': /[-+*\/%!^=]=?|@|&[&=]?|\|[|=]?|<<?=?|>>?=?/
  1053. };
  1054. Prism.languages.typescript = Prism.languages.extend('javascript', {
  1055. 'keyword': /\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield|module|declare|constructor|string|Function|any|number|boolean|Array|enum)\b/
  1056. });