| @@ -1,4 +1,4 @@ |
| 1 | | −/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+c+cpp+coffeescript+ruby+elixir+go+php+python+rust */ |
| 1 | +/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+c+cpp+coffeescript+ruby+elixir+go+lua+php+python+rust */ |
| 2 | 2 | var _self = (typeof window !== 'undefined') |
| 3 | 3 | ? window // if in browser |
| 4 | 4 | : ( |
| @@ -155,10 +155,17 @@ var _ = _self.Prism = { · 150 unmodified lines |
| 155 | 155 | plugins: {}, |
| 156 | 156 | |
| 157 | 157 | highlightAll: function(async, callback) { |
| 158 | | − var elements = document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'); |
| 158 | + var env = { |
| 159 | + callback: callback, |
| 160 | + selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code' |
| 161 | + }; |
| 162 | + |
| 163 | + _.hooks.run("before-highlightall", env); |
| 164 | + |
| 165 | + var elements = env.elements || document.querySelectorAll(env.selector); |
| 159 | 166 | |
| 160 | 167 | for (var i=0, element; element = elements[i++];) { |
| 161 | | − _.highlightElement(element, async === true, callback); |
| 168 | + _.highlightElement(element, async === true, env.callback); |
| 162 | 169 | } |
| 163 | 170 | }, |
| 164 | 171 | |
| @@ -268,6 +275,7 @@ var _ = _self.Prism = { · 103 unmodified lines |
| 268 | 275 | var pattern = patterns[j], |
| 269 | 276 | inside = pattern.inside, |
| 270 | 277 | lookbehind = !!pattern.lookbehind, |
| 278 | + greedy = !!pattern.greedy, |
| 271 | 279 | lookbehindLength = 0, |
| 272 | 280 | alias = pattern.alias; |
| 273 | 281 | |
| @@ -288,36 +296,73 @@ var _ = _self.Prism = { · 14 unmodified lines |
| 288 | 296 | |
| 289 | 297 | pattern.lastIndex = 0; |
| 290 | 298 | |
| 291 | | − var match = pattern.exec(str); |
| 299 | + var match = pattern.exec(str), |
| 300 | + delNum = 1; |
| 301 | + |
| 302 | + // Greedy patterns can override/remove up to two previously matched tokens |
| 303 | + if (!match && greedy && i != strarr.length - 1) { |
| 304 | + // Reconstruct the original text using the next two tokens |
| 305 | + var nextToken = strarr[i + 1].matchedStr || strarr[i + 1], |
| 306 | + combStr = str + nextToken; |
| 307 | + |
| 308 | + if (i < strarr.length - 2) { |
| 309 | + combStr += strarr[i + 2].matchedStr || strarr[i + 2]; |
| 310 | + } |
| 292 | 311 | |
| 293 | | − if (match) { |
| 294 | | − if(lookbehind) { |
| 295 | | − lookbehindLength = match[1].length; |
| 312 | + // Try the pattern again on the reconstructed text |
| 313 | + pattern.lastIndex = 0; |
| 314 | + match = pattern.exec(combStr); |
| 315 | + if (!match) { |
| 316 | + continue; |
| 296 | 317 | } |
| 297 | 318 | |
| 298 | | − var from = match.index - 1 + lookbehindLength, |
| 299 | | − match = match[0].slice(lookbehindLength), |
| 300 | | − len = match.length, |
| 301 | | − to = from + len, |
| 302 | | − before = str.slice(0, from + 1), |
| 303 | | − after = str.slice(to + 1); |
| 319 | + var from = match.index + (lookbehind ? match[1].length : 0); |
| 320 | + // To be a valid candidate, the new match has to start inside of str |
| 321 | + if (from >= str.length) { |
| 322 | + continue; |
| 323 | + } |
| 324 | + var to = match.index + match[0].length, |
| 325 | + len = str.length + nextToken.length; |
| 304 | 326 | |
| 305 | | − var args = [i, 1]; |
| 327 | + // Number of tokens to delete and replace with the new match |
| 328 | + delNum = 3; |
| 306 | 329 | |
| 307 | | − if (before) { |
| 308 | | − args.push(before); |
| 330 | + if (to <= len) { |
| 331 | + delNum = 2; |
| 332 | + combStr = combStr.slice(0, len); |
| 309 | 333 | } |
| 334 | + str = combStr; |
| 335 | + } |
| 310 | 336 | |
| 311 | | − var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias); |
| 337 | + if (!match) { |
| 338 | + continue; |
| 339 | + } |
| 312 | 340 | |
| 313 | | − args.push(wrapped); |
| 341 | + if(lookbehind) { |
| 342 | + lookbehindLength = match[1].length; |
| 343 | + } |
| 314 | 344 | |
| 315 | | − if (after) { |
| 316 | | − args.push(after); |
| 317 | | − } |
| 345 | + var from = match.index + lookbehindLength, |
| 346 | + match = match[0].slice(lookbehindLength), |
| 347 | + to = from + match.length, |
| 348 | + before = str.slice(0, from), |
| 349 | + after = str.slice(to); |
| 350 | + |
| 351 | + var args = [i, delNum]; |
| 318 | 352 | |
| 319 | | − Array.prototype.splice.apply(strarr, args); |
| 353 | + if (before) { |
| 354 | + args.push(before); |
| 320 | 355 | } |
| 356 | + |
| 357 | + var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias, match); |
| 358 | + |
| 359 | + args.push(wrapped); |
| 360 | + |
| 361 | + if (after) { |
| 362 | + args.push(after); |
| 363 | + } |
| 364 | + |
| 365 | + Array.prototype.splice.apply(strarr, args); |
| 321 | 366 | } |
| 322 | 367 | } |
| 323 | 368 | } |
| @@ -350,10 +395,12 @@ var _ = _self.Prism = { · 26 unmodified lines |
| 350 | 395 | } |
| 351 | 396 | }; |
| 352 | 397 | |
| 353 | | −var Token = _.Token = function(type, content, alias) { |
| 398 | +var Token = _.Token = function(type, content, alias, matchedStr) { |
| 354 | 399 | this.type = type; |
| 355 | 400 | this.content = content; |
| 356 | 401 | this.alias = alias; |
| 402 | + // Copy of the full string this token was created from |
| 403 | + this.matchedStr = matchedStr || null; |
| 357 | 404 | }; |
| 358 | 405 | |
| 359 | 406 | Token.stringify = function(o, language, parent) { |
| @@ -549,7 +596,10 @@ Prism.languages.clike = { · 189 unmodified lines |
| 549 | 596 | lookbehind: true |
| 550 | 597 | } |
| 551 | 598 | ], |
| 552 | | − 'string': /(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, |
| 599 | + 'string': { |
| 600 | + pattern: /(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, |
| 601 | + greedy: true |
| 602 | + }, |
| 553 | 603 | 'class-name': { |
| 554 | 604 | pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i, |
| 555 | 605 | lookbehind: true, |
| @@ -575,13 +625,14 @@ Prism.languages.javascript = Prism.languages.extend('clike', { · 19 unmodified lines |
| 575 | 625 | Prism.languages.insertBefore('javascript', 'keyword', { |
| 576 | 626 | 'regex': { |
| 577 | 627 | pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/, |
| 578 | | − lookbehind: true |
| 628 | + lookbehind: true, |
| 629 | + greedy: true |
| 579 | 630 | } |
| 580 | 631 | }); |
| 581 | 632 | |
| 582 | 633 | Prism.languages.insertBefore('javascript', 'class-name', { |
| 583 | 634 | 'template-string': { |
| 584 | | − pattern: /`(?:\\`|\\?[^`])*`/, |
| 635 | + pattern: /`(?:\\\\|\\?[^\\])*?`/, |
| 585 | 636 | inside: { |
| 586 | 637 | 'interpolation': { |
| 587 | 638 | pattern: /\$\{[^}]+\}/, |
| @@ -950,6 +1001,23 @@ Prism.languages.go = Prism.languages.extend('clike', { · 362 unmodified lines |
| 950 | 1001 | }); |
| 951 | 1002 | delete Prism.languages.go['class-name']; |
| 952 | 1003 | |
| 1004 | +Prism.languages.lua = { |
| 1005 | + 'comment': /^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m, |
| 1006 | + // \z may be used to skip the following space |
| 1007 | + 'string': /(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[\s\S]))*\1|\[(=*)\[[\s\S]*?\]\2\]/, |
| 1008 | + 'number': /\b0x[a-f\d]+\.?[a-f\d]*(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|\.?\d*(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i, |
| 1009 | + '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/, |
| 1010 | + 'function': /(?!\d)\w+(?=\s*(?:[({]))/, |
| 1011 | + 'operator': [ |
| 1012 | + /[-+*%^&|#]|\/\/?|<[<=]?|>[>=]?|[=~]=?/, |
| 1013 | + { |
| 1014 | + // Match ".." but don't break "..." |
| 1015 | + pattern: /(^|[^.])\.\.(?!\.)/, |
| 1016 | + lookbehind: true |
| 1017 | + } |
| 1018 | + ], |
| 1019 | + 'punctuation': /[\[\](){},;]|\.+|:+/ |
| 1020 | +}; |
| 953 | 1021 | /** |
| 954 | 1022 | * Original by Aaron Harun: http://aahacreative.com/2012/07/31/php-syntax-highlighting-prism/ |
| 955 | 1023 | * Modified by Miles Johnson: http://milesj.me |