Unified · Split
| @@ -1,4 +1,4 @@ | |||
| 1 | /* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+c+cpp+coffeescript+ruby+elixir+go+json+kotlin+lua+nginx+perl+php+python+rust+sql+typescript */ | 1 | /* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+c+cpp+coffeescript+ruby+elixir+go+json+kotlin+lua+nginx+perl+php+python+crystal+rust+sql+typescript */ |
| 2 | var _self = (typeof window !== 'undefined') | 2 | var _self = (typeof window !== 'undefined') |
| 3 | ? window // if in browser | 3 | ? window // if in browser |
| 4 | : ( | 4 | : ( |
| @@ -281,9 +281,16 @@ var _ = _self.Prism = { · 276 unmodified lines | |||
| 281 | lookbehindLength = 0, | 281 | lookbehindLength = 0, |
| 282 | alias = pattern.alias; | 282 | alias = pattern.alias; |
| 283 | 283 | ||
| 284 | if (greedy && !pattern.pattern.global) { | ||
| 285 | // Without the global flag, lastIndex won't work | ||
| 286 | var flags = pattern.pattern.toString().match(/[imuy]*$/)[0]; | ||
| 287 | pattern.pattern = RegExp(pattern.pattern.source, flags + "g"); | ||
| 288 | } | ||
| 289 | |||
| 284 | pattern = pattern.pattern || pattern; | 290 | pattern = pattern.pattern || pattern; |
| 285 | 291 | ||
| 286 | for (var i=0; i<strarr.length; i++) { // Don’t cache length as it changes during the loop | 292 | // Don’t cache length as it changes during the loop |
| 293 | for (var i=0, pos = 0; i<strarr.length; pos += (strarr[i].matchedStr || strarr[i]).length, ++i) { | ||
| 287 | 294 | ||
| 288 | var str = strarr[i]; | 295 | var str = strarr[i]; |
| 289 | 296 | ||
| @@ -303,40 +310,38 @@ var _ = _self.Prism = { · 13 unmodified lines | |||
| 303 | 310 | ||
| 304 | // Greedy patterns can override/remove up to two previously matched tokens | 311 | // Greedy patterns can override/remove up to two previously matched tokens |
| 305 | if (!match && greedy && i != strarr.length - 1) { | 312 | if (!match && greedy && i != strarr.length - 1) { |
| 306 | // Reconstruct the original text using the next two tokens | 313 | pattern.lastIndex = pos; |
| 307 | var nextToken = strarr[i + 1].matchedStr || strarr[i + 1], | 314 | match = pattern.exec(text); |
| 308 | combStr = str + nextToken; | 315 | if (!match) { |
| 309 | 316 | break; | |
| 310 | if (i < strarr.length - 2) { | ||
| 311 | combStr += strarr[i + 2].matchedStr || strarr[i + 2]; | ||
| 312 | } | 317 | } |
| 313 | 318 | ||
| 314 | // Try the pattern again on the reconstructed text | 319 | var from = match.index + (lookbehind ? match[1].length : 0), |
| 315 | pattern.lastIndex = 0; | 320 | to = match.index + match[0].length, |
| 316 | match = pattern.exec(combStr); | 321 | k = i, |
| 317 | if (!match) { | 322 | p = pos; |
| 318 | continue; | 323 | |
| 324 | for (var len = strarr.length; k < len && p < to; ++k) { | ||
| 325 | p += (strarr[k].matchedStr || strarr[k]).length; | ||
| 326 | // Move the index i to the element in strarr that is closest to from | ||
| 327 | if (from >= p) { | ||
| 328 | ++i; | ||
| 329 | pos = p; | ||
| 330 | } | ||
| 319 | } | 331 | } |
| 320 | 332 | ||
| 321 | var from = match.index + (lookbehind ? match[1].length : 0); | 333 | /* |
| 322 | // To be a valid candidate, the new match has to start inside of str | 334 | * If strarr[i] is a Token, then the match starts inside another Token, which is invalid |
| 323 | if (from >= str.length) { | 335 | * If strarr[k - 1] is greedy we are in conflict with another greedy pattern |
| 336 | */ | ||
| 337 | if (strarr[i] instanceof Token || strarr[k - 1].greedy) { | ||
| 324 | continue; | 338 | continue; |
| 325 | } | 339 | } |
| 326 | var to = match.index + match[0].length, | ||
| 327 | len = str.length + nextToken.length; | ||
| 328 | 340 | ||
| 329 | // Number of tokens to delete and replace with the new match | 341 | // Number of tokens to delete and replace with the new match |
| 330 | delNum = 3; | 342 | delNum = k - i; |
| 331 | 343 | str = text.slice(pos, p); | |
| 332 | if (to <= len) { | 344 | match.index -= pos; |
| 333 | if (strarr[i + 1].greedy) { | ||
| 334 | continue; | ||
| 335 | } | ||
| 336 | delNum = 2; | ||
| 337 | combStr = combStr.slice(0, len); | ||
| 338 | } | ||
| 339 | str = combStr; | ||
| 340 | } | 345 | } |
| 341 | 346 | ||
| 342 | if (!match) { | 347 | if (!match) { |
| @@ -447,7 +452,7 @@ Token.stringify = function(o, language, parent) { · 104 unmodified lines | |||
| 447 | attributes += (attributes ? ' ' : '') + name + '="' + (env.attributes[name] || '') + '"'; | 452 | attributes += (attributes ? ' ' : '') + name + '="' + (env.attributes[name] || '') + '"'; |
| 448 | } | 453 | } |
| 449 | 454 | ||
| 450 | return '<' + env.tag + ' class="' + env.classes.join(' ') + '" ' + attributes + '>' + env.content + '</' + env.tag + '>'; | 455 | return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + (attributes ? ' ' + attributes : '') + '>' + env.content + '</' + env.tag + '>'; |
| 451 | 456 | ||
| 452 | }; | 457 | }; |
| 453 | 458 | ||
| @@ -480,7 +485,11 @@ Token.stringify = function(o, language, parent) { · 26 unmodified lines | |||
| 480 | 485 | ||
| 481 | // if (document.addEventListener && !script.hasAttribute('data-manual')) { | 486 | // if (document.addEventListener && !script.hasAttribute('data-manual')) { |
| 482 | // if(document.readyState !== "loading") { | 487 | // if(document.readyState !== "loading") { |
| 483 | // requestAnimationFrame(_.highlightAll, 0); | 488 | // if (window.requestAnimationFrame) { |
| 489 | // window.requestAnimationFrame(_.highlightAll); | ||
| 490 | // } else { | ||
| 491 | // window.setTimeout(_.highlightAll, 16); | ||
| 492 | // } | ||
| 484 | // } | 493 | // } |
| 485 | // else { | 494 | // else { |
| 486 | // document.addEventListener('DOMContentLoaded', _.highlightAll); | 495 | // document.addEventListener('DOMContentLoaded', _.highlightAll); |
| @@ -507,7 +516,7 @@ Prism.languages.markup = { · 20 unmodified lines | |||
| 507 | 'doctype': /<!DOCTYPE[\w\W]+?>/, | 516 | 'doctype': /<!DOCTYPE[\w\W]+?>/, |
| 508 | 'cdata': /<!\[CDATA\[[\w\W]*?]]>/i, | 517 | 'cdata': /<!\[CDATA\[[\w\W]*?]]>/i, |
| 509 | 'tag': { | 518 | 'tag': { |
| 510 | pattern: /<\/?(?!\d)[^\s>\/=.$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i, | 519 | pattern: /<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i, |
| 511 | inside: { | 520 | inside: { |
| 512 | 'tag': { | 521 | 'tag': { |
| 513 | pattern: /^<\/?[^\s>\/]+/i, | 522 | pattern: /^<\/?[^\s>\/]+/i, |
| @@ -630,7 +639,8 @@ Prism.languages.javascript = Prism.languages.extend('clike', { · 116 unmodified lines | |||
| 630 | '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/, | 639 | '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/, |
| 631 | 'number': /\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/, | 640 | 'number': /\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/, |
| 632 | // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444) | 641 | // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444) |
| 633 | 'function': /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i | 642 | 'function': /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i, |
| 643 | 'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*\*?|\/|~|\^|%|\.{3}/ | ||
| 634 | }); | 644 | }); |
| 635 | 645 | ||
| 636 | Prism.languages.insertBefore('javascript', 'keyword', { | 646 | Prism.languages.insertBefore('javascript', 'keyword', { |
| @@ -1285,7 +1295,8 @@ Prism.languages.php = Prism.languages.extend('clike', { · 648 unmodified lines | |||
| 1285 | 'constant': /\b[A-Z0-9_]{2,}\b/, | 1295 | 'constant': /\b[A-Z0-9_]{2,}\b/, |
| 1286 | 'comment': { | 1296 | 'comment': { |
| 1287 | pattern: /(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/, | 1297 | pattern: /(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/, |
| 1288 | lookbehind: true | 1298 | lookbehind: true, |
| 1299 | greedy: true | ||
| 1289 | } | 1300 | } |
| 1290 | }); | 1301 | }); |
| 1291 | 1302 | ||
| @@ -1331,7 +1342,6 @@ if (Prism.languages.markup) { · 39 unmodified lines | |||
| 1331 | 1342 | ||
| 1332 | env.tokenStack = []; | 1343 | env.tokenStack = []; |
| 1333 | 1344 | ||
| 1334 | env.backupCode = env.code; | ||
| 1335 | env.code = env.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/ig, function(match) { | 1345 | env.code = env.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/ig, function(match) { |
| 1336 | env.tokenStack.push(match); | 1346 | env.tokenStack.push(match); |
| 1337 | 1347 | ||
| @@ -1339,14 +1349,6 @@ if (Prism.languages.markup) { · 1 unmodified line | |||
| 1339 | }); | 1349 | }); |
| 1340 | }); | 1350 | }); |
| 1341 | 1351 | ||
| 1342 | // Restore env.code for other plugins (e.g. line-numbers) | ||
| 1343 | Prism.hooks.add('before-insert', function(env) { | ||
| 1344 | if (env.language === 'php') { | ||
| 1345 | env.code = env.backupCode; | ||
| 1346 | delete env.backupCode; | ||
| 1347 | } | ||
| 1348 | }); | ||
| 1349 | |||
| 1350 | // Re-insert the tokens after highlighting | 1352 | // Re-insert the tokens after highlighting |
| 1351 | Prism.hooks.add('after-highlight', function(env) { | 1353 | Prism.hooks.add('after-highlight', function(env) { |
| 1352 | if (env.language !== 'php') { | 1354 | if (env.language !== 'php') { |
| @@ -1406,6 +1408,60 @@ Prism.languages.python= { · 53 unmodified lines | |||
| 1406 | 'punctuation' : /[{}[\];(),.:]/ | 1408 | 'punctuation' : /[{}[\];(),.:]/ |
| 1407 | }; | 1409 | }; |
| 1408 | 1410 | ||
| 1411 | (function(Prism) { | ||
| 1412 | Prism.languages.crystal = Prism.languages.extend('ruby', { | ||
| 1413 | keyword: [ | ||
| 1414 | /\b(?:abstract|alias|as|asm|begin|break|case|class|def|do|else|elsif|end|ensure|enum|extend|for|fun|if|ifdef|include|instance_sizeof|lib|macro|module|next|of|out|pointerof|private|protected|rescue|return|require|self|sizeof|struct|super|then|type|typeof|union|unless|until|when|while|with|yield|__DIR__|__FILE__|__LINE__)\b/, | ||
| 1415 | { | ||
| 1416 | pattern: /(\.\s*)(?:is_a|responds_to)\?/, | ||
| 1417 | lookbehind: true | ||
| 1418 | } | ||
| 1419 | ], | ||
| 1420 | |||
| 1421 | number: /\b(?:0b[01_]*[01]|0o[0-7_]*[0-7]|0x[0-9a-fA-F_]*[0-9a-fA-F]|(?:[0-9](?:[0-9_]*[0-9])?)(?:\.[0-9_]*[0-9])?(?:[eE][+-]?[0-9_]*[0-9])?)(?:_(?:[uif](?:8|16|32|64))?)?\b/, | ||
| 1422 | }); | ||
| 1423 | |||
| 1424 | var rest = Prism.util.clone(Prism.languages.crystal); | ||
| 1425 | |||
| 1426 | Prism.languages.insertBefore('crystal', 'string', { | ||
| 1427 | attribute: { | ||
| 1428 | pattern: /@\[.+?\]/, | ||
| 1429 | alias: 'attr-name', | ||
| 1430 | inside: { | ||
| 1431 | delimiter: { | ||
| 1432 | pattern: /^@\[|\]$/, | ||
| 1433 | alias: 'tag' | ||
| 1434 | }, | ||
| 1435 | rest: rest | ||
| 1436 | } | ||
| 1437 | }, | ||
| 1438 | |||
| 1439 | expansion: [ | ||
| 1440 | { | ||
| 1441 | pattern: /\{\{.+?\}\}/, | ||
| 1442 | inside: { | ||
| 1443 | delimiter: { | ||
| 1444 | pattern: /^\{\{|\}\}$/, | ||
| 1445 | alias: 'tag' | ||
| 1446 | }, | ||
| 1447 | rest: rest | ||
| 1448 | } | ||
| 1449 | }, | ||
| 1450 | { | ||
| 1451 | pattern: /\{%.+?%\}/, | ||
| 1452 | inside: { | ||
| 1453 | delimiter: { | ||
| 1454 | pattern: /^\{%|%\}$/, | ||
| 1455 | alias: 'tag' | ||
| 1456 | }, | ||
| 1457 | rest: rest | ||
| 1458 | } | ||
| 1459 | } | ||
| 1460 | ] | ||
| 1461 | }); | ||
| 1462 | |||
| 1463 | }(Prism)); | ||
| 1464 | |||
| 1409 | /* TODO | 1465 | /* TODO |
| 1410 | Add support for Markdown notation inside doc comments | 1466 | Add support for Markdown notation inside doc comments |
| 1411 | Add support for nested block comments... | 1467 | Add support for nested block comments... |