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 | 2 | var _self = (typeof window !== 'undefined') |
| 3 | 3 | ? window // if in browser |
| 4 | 4 | : ( |
| @@ -281,9 +281,16 @@ var _ = _self.Prism = { · 276 unmodified lines | ||
| 281 | 281 | lookbehindLength = 0, |
| 282 | 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 | 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 | 295 | var str = strarr[i]; |
| 289 | 296 | |
| @@ -303,40 +310,38 @@ var _ = _self.Prism = { · 13 unmodified lines | ||
| 303 | 310 | |
| 304 | 311 | // Greedy patterns can override/remove up to two previously matched tokens |
| 305 | 312 | if (!match && greedy && i != strarr.length - 1) { |
| 306 | − // Reconstruct the original text using the next two tokens | |
| 307 | − var nextToken = strarr[i + 1].matchedStr || strarr[i + 1], | |
| 308 | − combStr = str + nextToken; | |
| 309 | − | |
| 310 | − if (i < strarr.length - 2) { | |
| 311 | − combStr += strarr[i + 2].matchedStr || strarr[i + 2]; | |
| 313 | + pattern.lastIndex = pos; | |
| 314 | + match = pattern.exec(text); | |
| 315 | + if (!match) { | |
| 316 | + break; | |
| 312 | 317 | } |
| 313 | 318 | |
| 314 | − // Try the pattern again on the reconstructed text | |
| 315 | − pattern.lastIndex = 0; | |
| 316 | − match = pattern.exec(combStr); | |
| 317 | − if (!match) { | |
| 318 | − continue; | |
| 319 | + var from = match.index + (lookbehind ? match[1].length : 0), | |
| 320 | + to = match.index + match[0].length, | |
| 321 | + k = i, | |
| 322 | + p = pos; | |
| 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); | |
| 322 | − // To be a valid candidate, the new match has to start inside of str | |
| 323 | − if (from >= str.length) { | |
| 333 | + /* | |
| 334 | + * If strarr[i] is a Token, then the match starts inside another Token, which is invalid | |
| 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 | 338 | continue; |
| 325 | 339 | } |
| 326 | − var to = match.index + match[0].length, | |
| 327 | − len = str.length + nextToken.length; | |
| 328 | 340 | |
| 329 | 341 | // Number of tokens to delete and replace with the new match |
| 330 | − delNum = 3; | |
| 331 | − | |
| 332 | − if (to <= len) { | |
| 333 | − if (strarr[i + 1].greedy) { | |
| 334 | − continue; | |
| 335 | − } | |
| 336 | − delNum = 2; | |
| 337 | − combStr = combStr.slice(0, len); | |
| 338 | − } | |
| 339 | − str = combStr; | |
| 342 | + delNum = k - i; | |
| 343 | + str = text.slice(pos, p); | |
| 344 | + match.index -= pos; | |
| 340 | 345 | } |
| 341 | 346 | |
| 342 | 347 | if (!match) { |
| @@ -447,7 +452,7 @@ Token.stringify = function(o, language, parent) { · 104 unmodified lines | ||
| 447 | 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 | 486 | // if (document.addEventListener && !script.hasAttribute('data-manual')) { |
| 482 | 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 | 494 | // else { |
| 486 | 495 | // document.addEventListener('DOMContentLoaded', _.highlightAll); |
| @@ -507,7 +516,7 @@ Prism.languages.markup = { · 20 unmodified lines | ||
| 507 | 516 | 'doctype': /<!DOCTYPE[\w\W]+?>/, |
| 508 | 517 | 'cdata': /<!\[CDATA\[[\w\W]*?]]>/i, |
| 509 | 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 | 520 | inside: { |
| 512 | 521 | 'tag': { |
| 513 | 522 | pattern: /^<\/?[^\s>\/]+/i, |
| @@ -630,7 +639,8 @@ Prism.languages.javascript = Prism.languages.extend('clike', { · 116 unmodified lines | ||
| 630 | 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 | 640 | 'number': /\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/, |
| 632 | 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 | 646 | Prism.languages.insertBefore('javascript', 'keyword', { |
| @@ -1285,7 +1295,8 @@ Prism.languages.php = Prism.languages.extend('clike', { · 648 unmodified lines | ||
| 1285 | 1295 | 'constant': /\b[A-Z0-9_]{2,}\b/, |
| 1286 | 1296 | 'comment': { |
| 1287 | 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 | 1343 | env.tokenStack = []; |
| 1333 | 1344 | |
| 1334 | − env.backupCode = env.code; | |
| 1335 | 1345 | env.code = env.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/ig, function(match) { |
| 1336 | 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 | 1352 | // Re-insert the tokens after highlighting |
| 1351 | 1353 | Prism.hooks.add('after-highlight', function(env) { |
| 1352 | 1354 | if (env.language !== 'php') { |
| @@ -1406,6 +1408,60 @@ Prism.languages.python= { · 53 unmodified lines | ||
| 1406 | 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 | 1465 | /* TODO |
| 1410 | 1466 | Add support for Markdown notation inside doc comments |
| 1411 | 1467 | Add support for nested block comments... |