prism.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. /* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+php+coffeescript+c+cpp+python+ruby */
  2. /**
  3. * Prism: Lightweight, robust, elegant syntax highlighting
  4. * MIT license http://www.opensource.org/licenses/mit-license.php/
  5. * @author Lea Verou http://lea.verou.me
  6. */
  7. var Prism = (function(){
  8. // Private helper vars
  9. var lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i;
  10. var _ = self.Prism = {
  11. util: {
  12. encode: function (tokens) {
  13. if (tokens instanceof Token) {
  14. return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias);
  15. } else if (_.util.type(tokens) === 'Array') {
  16. return tokens.map(_.util.encode);
  17. } else {
  18. return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
  19. }
  20. },
  21. type: function (o) {
  22. return Object.prototype.toString.call(o).match(/\[object (\w+)\]/)[1];
  23. },
  24. // Deep clone a language definition (e.g. to extend it)
  25. clone: function (o) {
  26. var type = _.util.type(o);
  27. switch (type) {
  28. case 'Object':
  29. var clone = {};
  30. for (var key in o) {
  31. if (o.hasOwnProperty(key)) {
  32. clone[key] = _.util.clone(o[key]);
  33. }
  34. }
  35. return clone;
  36. case 'Array':
  37. return o.slice();
  38. }
  39. return o;
  40. }
  41. },
  42. languages: {
  43. extend: function (id, redef) {
  44. var lang = _.util.clone(_.languages[id]);
  45. for (var key in redef) {
  46. lang[key] = redef[key];
  47. }
  48. return lang;
  49. },
  50. /**
  51. * Insert a token before another token in a language literal
  52. * As this needs to recreate the object (we cannot actually insert before keys in object literals),
  53. * we cannot just provide an object, we need anobject and a key.
  54. * @param inside The key (or language id) of the parent
  55. * @param before The key to insert before. If not provided, the function appends instead.
  56. * @param insert Object with the key/value pairs to insert
  57. * @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted.
  58. */
  59. insertBefore: function (inside, before, insert, root) {
  60. root = root || _.languages;
  61. var grammar = root[inside];
  62. if (arguments.length == 2) {
  63. insert = arguments[1];
  64. for (var newToken in insert) {
  65. if (insert.hasOwnProperty(newToken)) {
  66. grammar[newToken] = insert[newToken];
  67. }
  68. }
  69. return grammar;
  70. }
  71. var ret = {};
  72. for (var token in grammar) {
  73. if (grammar.hasOwnProperty(token)) {
  74. if (token == before) {
  75. for (var newToken in insert) {
  76. if (insert.hasOwnProperty(newToken)) {
  77. ret[newToken] = insert[newToken];
  78. }
  79. }
  80. }
  81. ret[token] = grammar[token];
  82. }
  83. }
  84. // Update references in other language definitions
  85. _.languages.DFS(_.languages, function(key, value) {
  86. if (value === root[inside] && key != inside) {
  87. this[key] = ret;
  88. }
  89. });
  90. return root[inside] = ret;
  91. },
  92. // Traverse a language definition with Depth First Search
  93. DFS: function(o, callback, type) {
  94. for (var i in o) {
  95. if (o.hasOwnProperty(i)) {
  96. callback.call(o, i, o[i], type || i);
  97. if (_.util.type(o[i]) === 'Object') {
  98. _.languages.DFS(o[i], callback);
  99. }
  100. else if (_.util.type(o[i]) === 'Array') {
  101. _.languages.DFS(o[i], callback, i);
  102. }
  103. }
  104. }
  105. }
  106. },
  107. highlightAll: function(async, callback) {
  108. var elements = document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code');
  109. for (var i=0, element; element = elements[i++];) {
  110. _.highlightElement(element, async === true, callback);
  111. }
  112. },
  113. highlightElement: function(element, async, callback) {
  114. // Find language
  115. var language, grammar, parent = element;
  116. while (parent && !lang.test(parent.className)) {
  117. parent = parent.parentNode;
  118. }
  119. if (parent) {
  120. language = (parent.className.match(lang) || [,''])[1];
  121. grammar = _.languages[language];
  122. }
  123. if (!grammar) {
  124. return;
  125. }
  126. // Set language on the element, if not present
  127. element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
  128. // Set language on the parent, for styling
  129. parent = element.parentNode;
  130. if (/pre/i.test(parent.nodeName)) {
  131. parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
  132. }
  133. var code = element.textContent;
  134. if(!code) {
  135. return;
  136. }
  137. var env = {
  138. element: element,
  139. language: language,
  140. grammar: grammar,
  141. code: code
  142. };
  143. _.hooks.run('before-highlight', env);
  144. // if (async && self.Worker) {
  145. // var worker = new Worker(_.filename);
  146. // worker.onmessage = function(evt) {
  147. // env.highlightedCode = Token.stringify(JSON.parse(evt.data), language);
  148. // _.hooks.run('before-insert', env);
  149. // env.element.innerHTML = env.highlightedCode;
  150. // callback && callback.call(env.element);
  151. // _.hooks.run('after-highlight', env);
  152. // };
  153. // worker.postMessage(JSON.stringify({
  154. // language: env.language,
  155. // code: env.code
  156. // }));
  157. // }
  158. // else {
  159. env.highlightedCode = _.highlight(env.code, env.grammar, env.language)
  160. _.hooks.run('before-insert', env);
  161. env.element.innerHTML = env.highlightedCode;
  162. callback && callback.call(element);
  163. _.hooks.run('after-highlight', env);
  164. // }
  165. },
  166. highlight: function (text, grammar, language) {
  167. var tokens = _.tokenize(text, grammar);
  168. return Token.stringify(_.util.encode(tokens), language);
  169. },
  170. tokenize: function(text, grammar, language) {
  171. var Token = _.Token;
  172. var strarr = [text];
  173. var rest = grammar.rest;
  174. if (rest) {
  175. for (var token in rest) {
  176. grammar[token] = rest[token];
  177. }
  178. delete grammar.rest;
  179. }
  180. tokenloop: for (var token in grammar) {
  181. if(!grammar.hasOwnProperty(token) || !grammar[token]) {
  182. continue;
  183. }
  184. var patterns = grammar[token];
  185. patterns = (_.util.type(patterns) === "Array") ? patterns : [patterns];
  186. for (var j = 0; j < patterns.length; ++j) {
  187. var pattern = patterns[j],
  188. inside = pattern.inside,
  189. lookbehind = !!pattern.lookbehind,
  190. lookbehindLength = 0,
  191. alias = pattern.alias;
  192. pattern = pattern.pattern || pattern;
  193. for (var i=0; i<strarr.length; i++) { // Don’t cache length as it changes during the loop
  194. var str = strarr[i];
  195. if (strarr.length > text.length) {
  196. // Something went terribly wrong, ABORT, ABORT!
  197. break tokenloop;
  198. }
  199. if (str instanceof Token) {
  200. continue;
  201. }
  202. pattern.lastIndex = 0;
  203. var match = pattern.exec(str);
  204. if (match) {
  205. if(lookbehind) {
  206. lookbehindLength = match[1].length;
  207. }
  208. var from = match.index - 1 + lookbehindLength,
  209. match = match[0].slice(lookbehindLength),
  210. len = match.length,
  211. to = from + len,
  212. before = str.slice(0, from + 1),
  213. after = str.slice(to + 1);
  214. var args = [i, 1];
  215. if (before) {
  216. args.push(before);
  217. }
  218. var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias);
  219. args.push(wrapped);
  220. if (after) {
  221. args.push(after);
  222. }
  223. Array.prototype.splice.apply(strarr, args);
  224. }
  225. }
  226. }
  227. }
  228. return strarr;
  229. },
  230. hooks: {
  231. all: {},
  232. add: function (name, callback) {
  233. var hooks = _.hooks.all;
  234. hooks[name] = hooks[name] || [];
  235. hooks[name].push(callback);
  236. },
  237. run: function (name, env) {
  238. var callbacks = _.hooks.all[name];
  239. if (!callbacks || !callbacks.length) {
  240. return;
  241. }
  242. for (var i=0, callback; callback = callbacks[i++];) {
  243. callback(env);
  244. }
  245. }
  246. }
  247. };
  248. var Token = _.Token = function(type, content, alias) {
  249. this.type = type;
  250. this.content = content;
  251. this.alias = alias;
  252. };
  253. Token.stringify = function(o, language, parent) {
  254. if (typeof o == 'string') {
  255. return o;
  256. }
  257. if (Object.prototype.toString.call(o) == '[object Array]') {
  258. return o.map(function(element) {
  259. return Token.stringify(element, language, o);
  260. }).join('');
  261. }
  262. var env = {
  263. type: o.type,
  264. content: Token.stringify(o.content, language, parent),
  265. tag: 'span',
  266. classes: ['token', o.type],
  267. attributes: {},
  268. language: language,
  269. parent: parent
  270. };
  271. if (env.type == 'comment') {
  272. env.attributes['spellcheck'] = 'true';
  273. }
  274. if (o.alias) {
  275. var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias];
  276. Array.prototype.push.apply(env.classes, aliases);
  277. }
  278. _.hooks.run('wrap', env);
  279. var attributes = '';
  280. for (var name in env.attributes) {
  281. attributes += name + '="' + (env.attributes[name] || '') + '"';
  282. }
  283. return '<' + env.tag + ' class="' + env.classes.join(' ') + '" ' + attributes + '>' + env.content + '</' + env.tag + '>';
  284. };
  285. // if (!self.document) {
  286. // if (!self.addEventListener) {
  287. // // in Node.js
  288. // return self.Prism;
  289. // }
  290. // // In worker
  291. // self.addEventListener('message', function(evt) {
  292. // var message = JSON.parse(evt.data),
  293. // lang = message.language,
  294. // code = message.code;
  295. // self.postMessage(JSON.stringify(_.util.encode(_.tokenize(code, _.languages[lang]))));
  296. // self.close();
  297. // }, false);
  298. // return self.Prism;
  299. // }
  300. // Get current script and highlight
  301. // var script = document.getElementsByTagName('script');
  302. // script = script[script.length - 1];
  303. // if (script) {
  304. // _.filename = script.src;
  305. // if (document.addEventListener && !script.hasAttribute('data-manual')) {
  306. // document.addEventListener('DOMContentLoaded', _.highlightAll);
  307. // }
  308. // }
  309. return self.Prism;
  310. })();
  311. // if (typeof module !== 'undefined' && module.exports) {
  312. // module.exports = Prism;
  313. // }
  314. // ;
  315. Prism.languages.markup = {
  316. 'comment': /<!--[\w\W]*?-->/g,
  317. 'prolog': /<\?.+?\?>/,
  318. 'doctype': /<!DOCTYPE.+?>/,
  319. 'cdata': /<!\[CDATA\[[\w\W]*?]]>/i,
  320. 'tag': {
  321. pattern: /<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/gi,
  322. inside: {
  323. 'tag': {
  324. pattern: /^<\/?[\w:-]+/i,
  325. inside: {
  326. 'punctuation': /^<\/?/,
  327. 'namespace': /^[\w-]+?:/
  328. }
  329. },
  330. 'attr-value': {
  331. pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/gi,
  332. inside: {
  333. 'punctuation': /=|>|"/g
  334. }
  335. },
  336. 'punctuation': /\/?>/g,
  337. 'attr-name': {
  338. pattern: /[\w:-]+/g,
  339. inside: {
  340. 'namespace': /^[\w-]+?:/
  341. }
  342. }
  343. }
  344. },
  345. 'entity': /\&#?[\da-z]{1,8};/gi
  346. };
  347. // Plugin to make entity title show the real entity, idea by Roman Komarov
  348. Prism.hooks.add('wrap', function(env) {
  349. if (env.type === 'entity') {
  350. env.attributes['title'] = env.content.replace(/&amp;/, '&');
  351. }
  352. });
  353. ;
  354. Prism.languages.css = {
  355. 'comment': /\/\*[\w\W]*?\*\//g,
  356. 'atrule': {
  357. pattern: /@[\w-]+?.*?(;|(?=\s*{))/gi,
  358. inside: {
  359. 'punctuation': /[;:]/g
  360. }
  361. },
  362. 'url': /url\((["']?).*?\1\)/gi,
  363. 'selector': /[^\{\}\s][^\{\};]*(?=\s*\{)/g,
  364. 'property': /(\b|\B)[\w-]+(?=\s*:)/ig,
  365. 'string': /("|')(\\?.)*?\1/g,
  366. 'important': /\B!important\b/gi,
  367. 'punctuation': /[\{\};:]/g,
  368. 'function': /[-a-z0-9]+(?=\()/ig
  369. };
  370. if (Prism.languages.markup) {
  371. Prism.languages.insertBefore('markup', 'tag', {
  372. 'style': {
  373. pattern: /<style[\w\W]*?>[\w\W]*?<\/style>/ig,
  374. inside: {
  375. 'tag': {
  376. pattern: /<style[\w\W]*?>|<\/style>/ig,
  377. inside: Prism.languages.markup.tag.inside
  378. },
  379. rest: Prism.languages.css
  380. },
  381. alias: 'language-css'
  382. }
  383. });
  384. Prism.languages.insertBefore('inside', 'attr-value', {
  385. 'style-attr': {
  386. pattern: /\s*style=("|').+?\1/ig,
  387. inside: {
  388. 'attr-name': {
  389. pattern: /^\s*style/ig,
  390. inside: Prism.languages.markup.tag.inside
  391. },
  392. 'punctuation': /^\s*=\s*['"]|['"]\s*$/,
  393. 'attr-value': {
  394. pattern: /.+/gi,
  395. inside: Prism.languages.css
  396. }
  397. },
  398. alias: 'language-css'
  399. }
  400. }, Prism.languages.markup.tag);
  401. };
  402. Prism.languages.clike = {
  403. 'comment': [
  404. {
  405. pattern: /(^|[^\\])\/\*[\w\W]*?\*\//g,
  406. lookbehind: true
  407. },
  408. {
  409. pattern: /(^|[^\\:])\/\/.*?(\r?\n|$)/g,
  410. lookbehind: true
  411. }
  412. ],
  413. 'string': /("|')(\\?.)*?\1/g,
  414. 'class-name': {
  415. pattern: /((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/ig,
  416. lookbehind: true,
  417. inside: {
  418. punctuation: /(\.|\\)/
  419. }
  420. },
  421. 'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/g,
  422. 'boolean': /\b(true|false)\b/g,
  423. 'function': {
  424. pattern: /[a-z0-9_]+\(/ig,
  425. inside: {
  426. punctuation: /\(/
  427. }
  428. },
  429. 'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,
  430. 'operator': /[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,
  431. 'ignore': /&(lt|gt|amp);/gi,
  432. 'punctuation': /[{}[\];(),.:]/g
  433. };
  434. ;
  435. Prism.languages.javascript = Prism.languages.extend('clike', {
  436. '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)\b/g,
  437. 'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g
  438. });
  439. Prism.languages.insertBefore('javascript', 'keyword', {
  440. 'regex': {
  441. pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,
  442. lookbehind: true
  443. }
  444. });
  445. if (Prism.languages.markup) {
  446. Prism.languages.insertBefore('markup', 'tag', {
  447. 'script': {
  448. pattern: /<script[\w\W]*?>[\w\W]*?<\/script>/ig,
  449. inside: {
  450. 'tag': {
  451. pattern: /<script[\w\W]*?>|<\/script>/ig,
  452. inside: Prism.languages.markup.tag.inside
  453. },
  454. rest: Prism.languages.javascript
  455. },
  456. alias: 'language-javascript'
  457. }
  458. });
  459. }
  460. ;
  461. /**
  462. * Original by Aaron Harun: http://aahacreative.com/2012/07/31/php-syntax-highlighting-prism/
  463. * Modified by Miles Johnson: http://milesj.me
  464. *
  465. * Supports the following:
  466. * - Extends clike syntax
  467. * - Support for PHP 5.3+ (namespaces, traits, generators, etc)
  468. * - Smarter constant and function matching
  469. *
  470. * Adds the following new token classes:
  471. * constant, delimiter, variable, function, package
  472. */
  473. Prism.languages.php = Prism.languages.extend('clike', {
  474. '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/ig,
  475. 'constant': /\b[A-Z0-9_]{2,}\b/g,
  476. 'comment': {
  477. pattern: /(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])(\/\/|#).*?(\r?\n|$))/g,
  478. lookbehind: true
  479. }
  480. });
  481. Prism.languages.insertBefore('php', 'keyword', {
  482. 'delimiter': /(\?>|<\?php|<\?)/ig,
  483. 'variable': /(\$\w+)\b/ig,
  484. 'package': {
  485. pattern: /(\\|namespace\s+|use\s+)[\w\\]+/g,
  486. lookbehind: true,
  487. inside: {
  488. punctuation: /\\/
  489. }
  490. }
  491. });
  492. // Must be defined after the function pattern
  493. Prism.languages.insertBefore('php', 'operator', {
  494. 'property': {
  495. pattern: /(->)[\w]+/g,
  496. lookbehind: true
  497. }
  498. });
  499. // Add HTML support of the markup language exists
  500. if (Prism.languages.markup) {
  501. // Tokenize all inline PHP blocks that are wrapped in <?php ?>
  502. // This allows for easy PHP + markup highlighting
  503. Prism.hooks.add('before-highlight', function(env) {
  504. if (env.language !== 'php') {
  505. return;
  506. }
  507. env.tokenStack = [];
  508. env.backupCode = env.code;
  509. env.code = env.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/ig, function(match) {
  510. env.tokenStack.push(match);
  511. return '{{{PHP' + env.tokenStack.length + '}}}';
  512. });
  513. });
  514. // Restore env.code for other plugins (e.g. line-numbers)
  515. Prism.hooks.add('before-insert', function(env) {
  516. if (env.language === 'php') {
  517. env.code = env.backupCode;
  518. delete env.backupCode;
  519. }
  520. });
  521. // Re-insert the tokens after highlighting
  522. Prism.hooks.add('after-highlight', function(env) {
  523. if (env.language !== 'php') {
  524. return;
  525. }
  526. for (var i = 0, t; t = env.tokenStack[i]; i++) {
  527. env.highlightedCode = env.highlightedCode.replace('{{{PHP' + (i + 1) + '}}}', Prism.highlight(t, env.grammar, 'php'));
  528. }
  529. env.element.innerHTML = env.highlightedCode;
  530. });
  531. // Wrap tokens in classes that are missing them
  532. Prism.hooks.add('wrap', function(env) {
  533. if (env.language === 'php' && env.type === 'markup') {
  534. env.content = env.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/g, "<span class=\"token php\">$1</span>");
  535. }
  536. });
  537. // Add the rules before all others
  538. Prism.languages.insertBefore('php', 'comment', {
  539. 'markup': {
  540. pattern: /<[^?]\/?(.*?)>/g,
  541. inside: Prism.languages.markup
  542. },
  543. 'php': /\{\{\{PHP[0-9]+\}\}\}/g
  544. });
  545. }
  546. ;
  547. Prism.languages.coffeescript = Prism.languages.extend('javascript', {
  548. 'comment': [
  549. /([#]{3}\s*\r?\n(.*\s*\r*\n*)\s*?\r?\n[#]{3})/g,
  550. /(\s|^)([#]{1}[^#^\r^\n]{2,}?(\r?\n|$))/g
  551. ],
  552. 'keyword': /\b(this|window|delete|class|extends|namespace|extend|ar|let|if|else|while|do|for|each|of|return|in|instanceof|new|with|typeof|try|catch|finally|null|undefined|break|continue)\b/g
  553. });
  554. Prism.languages.insertBefore('coffeescript', 'keyword', {
  555. 'function': {
  556. pattern: /[a-z|A-z]+\s*[:|=]\s*(\([.|a-z\s|,|:|{|}|\"|\'|=]*\))?\s*-&gt;/gi,
  557. inside: {
  558. 'function-name': /[_?a-z-|A-Z-]+(\s*[:|=])| @[_?$?a-z-|A-Z-]+(\s*)| /g,
  559. 'operator': /[-+]{1,2}|!|=?&lt;|=?&gt;|={1,2}|(&amp;){1,2}|\|?\||\?|\*|\//g
  560. }
  561. },
  562. 'attr-name': /[_?a-z-|A-Z-]+(\s*:)| @[_?$?a-z-|A-Z-]+(\s*)| /g
  563. });
  564. ;
  565. Prism.languages.c = Prism.languages.extend('clike', {
  566. // allow for c multiline strings
  567. 'string': /("|')([^\n\\\1]|\\.|\\\r*\n)*?\1/g,
  568. '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/g,
  569. 'operator': /[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\//g
  570. });
  571. Prism.languages.insertBefore('c', 'string', {
  572. // property class reused for macro statements
  573. 'property': {
  574. // allow for multiline macro definitions
  575. // spaces after the # character compile fine with gcc
  576. pattern: /((^|\n)\s*)#\s*[a-z]+([^\n\\]|\\.|\\\r*\n)*/gi,
  577. lookbehind: true,
  578. inside: {
  579. // highlight the path of the include statement as a string
  580. 'string': {
  581. pattern: /(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/g,
  582. lookbehind: true,
  583. }
  584. }
  585. }
  586. });
  587. delete Prism.languages.c['class-name'];
  588. delete Prism.languages.c['boolean'];;
  589. Prism.languages.cpp = Prism.languages.extend('c', {
  590. '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|delete\[\]|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|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/g,
  591. 'boolean': /\b(true|false)\b/g,
  592. '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/g
  593. });
  594. Prism.languages.insertBefore('cpp', 'keyword', {
  595. 'class-name': {
  596. pattern: /(class\s+)[a-z0-9_]+/ig,
  597. lookbehind: true,
  598. },
  599. });;
  600. Prism.languages.python= {
  601. 'comment': {
  602. pattern: /(^|[^\\])#.*?(\r?\n|$)/g,
  603. lookbehind: true
  604. },
  605. 'string': /"""[\s\S]+?"""|("|')(\\?.)*?\1/g,
  606. 'keyword' : /\b(as|assert|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/g,
  607. 'boolean' : /\b(True|False)\b/g,
  608. 'number' : /\b-?(0x)?\d*\.?[\da-f]+\b/g,
  609. 'operator' : /[-+]{1,2}|=?&lt;|=?&gt;|!|={1,2}|(&){1,2}|(&amp;){1,2}|\|?\||\?|\*|\/|~|\^|%|\b(or|and|not)\b/g,
  610. 'ignore' : /&(lt|gt|amp);/gi,
  611. 'punctuation' : /[{}[\];(),.:]/g
  612. };
  613. ;
  614. /**
  615. * Original by Samuel Flores
  616. *
  617. * Adds the following new token classes:
  618. * constant, builtin, variable, symbol, regex
  619. */
  620. Prism.languages.ruby = Prism.languages.extend('clike', {
  621. 'comment': /#[^\r\n]*(\r?\n|$)/g,
  622. '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/g,
  623. '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/,
  624. 'constant': /\b[A-Z][a-zA-Z_0-9]*[?!]?\b/g
  625. });
  626. Prism.languages.insertBefore('ruby', 'keyword', {
  627. 'regex': {
  628. pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,
  629. lookbehind: true
  630. },
  631. 'variable': /[@$]+\b[a-zA-Z_][a-zA-Z_0-9]*[?!]?\b/g,
  632. 'symbol': /:\b[a-zA-Z_][a-zA-Z_0-9]*[?!]?\b/g
  633. });
  634. ;