Check for possible pre-existing marker strings in PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
diff --git a/components/prism-php.js b/components/prism-php.js
index c7c15cf..5535640 100644
--- a/components/prism-php.js
+++ b/components/prism-php.js
@@ -67,9 +67,15 @@ if (Prism.languages.markup) {
env.backupCode = env.code;
env.code = env.code.replace(/(?:<\?php|<\?)[\s\S]*?(?:\?>|$)/ig, function(match) {
- env.tokenStack.push(match);
+ var i = env.tokenStack.length;
+ // Check for existing strings
+ while (env.backupCode.indexOf('___PHP' + i + '___') !== -1)
+ ++i;
- return '___PHP' + env.tokenStack.length + '___';
+ // Create a sparse array
+ env.tokenStack[i] = match;
+
+ return '___PHP' + i + '___';
});
// Switch the grammar to markup
@@ -93,9 +99,12 @@ if (Prism.languages.markup) {
// Switch the grammar back
env.grammar = Prism.languages.php;
- for (var i = 0, t; t = env.tokenStack[i]; i++) {
+ for (var i = 0, keys = Object.keys(env.tokenStack); i < keys.length; ++i) {
+ var k = keys[i];
+ var t = env.tokenStack[k];
+
// The replace prevents $$, $&, $`, $', $n, $nn from being interpreted as special patterns
- env.highlightedCode = env.highlightedCode.replace('___PHP' + (i + 1) + '___',
+ env.highlightedCode = env.highlightedCode.replace('___PHP' + k + '___',
"<span class=\"token php language-php\">" +
Prism.highlight(t, env.grammar, 'php').replace(/\$/g, '$$$$') +
"</span>");
diff --git a/components/prism-php.min.js b/components/prism-php.min.js
index 386bb21..5349b38 100644
--- a/components/prism-php.min.js
+++ b/components/prism-php.min.js
@@ -1 +1 @@
-Prism.languages.php=Prism.languages.extend("clike",{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,constant:/\b[A-Z0-9_]{2,}\b/,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0}}),Prism.languages.insertBefore("php","class-name",{"shell-comment":{pattern:/(^|[^\\])#.*/,lookbehind:!0,alias:"comment"}}),Prism.languages.insertBefore("php","keyword",{delimiter:{pattern:/\?>|<\?(?:php|=)?/i,alias:"important"},variable:/\$\w+\b/i,"package":{pattern:/(\\|namespace\s+|use\s+)[\w\\]+/,lookbehind:!0,inside:{punctuation:/\\/}}}),Prism.languages.insertBefore("php","operator",{property:{pattern:/(->)[\w]+/,lookbehind:!0}}),Prism.languages.markup&&(Prism.hooks.add("before-highlight",function(e){"php"===e.language&&/(?:<\?php|<\?)/gi.test(e.code)&&(e.tokenStack=[],e.backupCode=e.code,e.code=e.code.replace(/(?:<\?php|<\?)[\s\S]*?(?:\?>|$)/gi,function(a){return e.tokenStack.push(a),"___PHP"+e.tokenStack.length+"___"}),e.grammar=Prism.languages.markup)}),Prism.hooks.add("before-insert",function(e){"php"===e.language&&e.backupCode&&(e.code=e.backupCode,delete e.backupCode)}),Prism.hooks.add("after-highlight",function(e){if("php"===e.language&&e.tokenStack){e.grammar=Prism.languages.php;for(var a,n=0;a=e.tokenStack[n];n++)e.highlightedCode=e.highlightedCode.replace("___PHP"+(n+1)+"___",'<span class="token php language-php">'+Prism.highlight(a,e.grammar,"php").replace(/\$/g,"$$$$")+"</span>");e.element.innerHTML=e.highlightedCode}}));
\ No newline at end of file
+Prism.languages.php=Prism.languages.extend("clike",{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,constant:/\b[A-Z0-9_]{2,}\b/,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0}}),Prism.languages.insertBefore("php","class-name",{"shell-comment":{pattern:/(^|[^\\])#.*/,lookbehind:!0,alias:"comment"}}),Prism.languages.insertBefore("php","keyword",{delimiter:{pattern:/\?>|<\?(?:php|=)?/i,alias:"important"},variable:/\$\w+\b/i,"package":{pattern:/(\\|namespace\s+|use\s+)[\w\\]+/,lookbehind:!0,inside:{punctuation:/\\/}}}),Prism.languages.insertBefore("php","operator",{property:{pattern:/(->)[\w]+/,lookbehind:!0}}),Prism.languages.markup&&(Prism.hooks.add("before-highlight",function(e){"php"===e.language&&/(?:<\?php|<\?)/gi.test(e.code)&&(e.tokenStack=[],e.backupCode=e.code,e.code=e.code.replace(/(?:<\?php|<\?)[\s\S]*?(?:\?>|$)/gi,function(a){for(var n=e.tokenStack.length;-1!==e.backupCode.indexOf("___PHP"+n+"___");)++n;return e.tokenStack[n]=a,"___PHP"+n+"___"}),e.grammar=Prism.languages.markup)}),Prism.hooks.add("before-insert",function(e){"php"===e.language&&e.backupCode&&(e.code=e.backupCode,delete e.backupCode)}),Prism.hooks.add("after-highlight",function(e){if("php"===e.language&&e.tokenStack){e.grammar=Prism.languages.php;for(var a=0,n=Object.keys(e.tokenStack);a<n.length;++a){var t=n[a],r=e.tokenStack[t];e.highlightedCode=e.highlightedCode.replace("___PHP"+t+"___",'<span class="token php language-php">'+Prism.highlight(r,e.grammar,"php").replace(/\$/g,"$$$$")+"</span>")}e.element.innerHTML=e.highlightedCode}}));
\ No newline at end of file
diff --git a/tests/languages/markup+php/php_in_markup_feature.js b/tests/languages/markup+php/php_in_markup_feature.js
index 0dbe965..218a097 100644
--- a/tests/languages/markup+php/php_in_markup_feature.js
+++ b/tests/languages/markup+php/php_in_markup_feature.js
@@ -3,5 +3,6 @@ module.exports = {
'<div><? echo $foo; ?></div>': '<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span><span class="token php language-php"><span class="token delimiter important"><?</span> <span class="token keyword">echo</span> <span class="token variable">$foo</span><span class="token punctuation">;</span> <span class="token delimiter important">?></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>',
'<div class="<?php echo $foo; ?>">': '<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span><span class="token php language-php"><span class="token delimiter important"><?php</span> <span class="token keyword">echo</span> <span class="token variable">$foo</span><span class="token punctuation">;</span> <span class="token delimiter important">?></span></span><span class="token punctuation">"</span></span><span class="token punctuation">></span></span>',
'<div class="<? echo $foo; ?>">': '<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span><span class="token php language-php"><span class="token delimiter important"><?</span> <span class="token keyword">echo</span> <span class="token variable">$foo</span><span class="token punctuation">;</span> <span class="token delimiter important">?></span></span><span class="token punctuation">"</span></span><span class="token punctuation">></span></span>',
- '<div><?= $foo; ?></div>': '<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span><span class="token php language-php"><span class="token delimiter important"><?=</span> <span class="token variable">$foo</span><span class="token punctuation">;</span> <span class="token delimiter important">?></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>'
+ '<div><?= $foo; ?></div>': '<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span><span class="token php language-php"><span class="token delimiter important"><?=</span> <span class="token variable">$foo</span><span class="token punctuation">;</span> <span class="token delimiter important">?></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>',
+ '___PHP1___<?php 1 ?>___PHP2___ <?php 2 ?>': '___PHP1___<span class="token php language-php"><span class="token delimiter important"><?php</span> <span class="token number">1</span> <span class="token delimiter important">?></span></span>___PHP2___ <span class="token php language-php"><span class="token delimiter important"><?php</span> <span class="token number">2</span> <span class="token delimiter important">?></span></span>'
};
\ No newline at end of file