Commit a2db2b5cd10c0512ba34e375ccb4a466246553a5

Miles Johnson 2013-07-02T16:54:46

Added legit markup support

diff --git a/components/prism-clike.js b/components/prism-clike.js
index d29e3fd..449a787 100644
--- a/components/prism-clike.js
+++ b/components/prism-clike.js
@@ -20,7 +20,7 @@ Prism.languages.clike = {
 		}
 	},
 	'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,
-	'operator': /[-+]{1,2}|!|=?<|=?>|={1,2}|(&){1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,
+	'operator': /[-+]{1,2}|!|=?&lt;|=?<|=?&gt;|=?>|={1,3}|(&amp;){1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,
 	'ignore': /&(lt|gt|amp);/gi,
 	'punctuation': /[{}[\];(),.:]/g
 };
\ No newline at end of file
diff --git a/components/prism-clike.min.js b/components/prism-clike.min.js
index 7938afd..9c17ab1 100644
--- a/components/prism-clike.min.js
+++ b/components/prism-clike.min.js
@@ -1 +1 @@
-Prism.languages.clike={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])\/\/.*?(\r?\n|$))/g,lookbehind:!0},string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:class|interface|extends|implements|trait|instanceof|new)\s+)[a-z0-9_\.\\]+/ig,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/ig,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,operator:/[-+]{1,2}|!|=?&lt;|=?&gt;|={1,2}|(&amp;){1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};
\ No newline at end of file
+Prism.languages.clike={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])\/\/.*?(\r?\n|$))/g,lookbehind:!0},string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:class|interface|extends|implements|trait|instanceof|new)\s+)[a-z0-9_\.\\]+/ig,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/ig,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g, operator:/[-+]{1,2}|!|=?&lt;|=?<|=?&gt;|=?>|={1,3}|(&amp;){1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};
\ No newline at end of file
diff --git a/components/prism-php.js b/components/prism-php.js
index a4e32f1..b476a71 100644
--- a/components/prism-php.js
+++ b/components/prism-php.js
@@ -17,7 +17,7 @@ Prism.languages.php = Prism.languages.extend('clike', {
 });
 
 Prism.languages.insertBefore('php', 'keyword', {
-	'deliminator': /(\?>|\?&gt;|&lt;\?php|<\?php)/ig,
+	'deliminator': /(\?>|\?&gt;|&lt;\?php|<\?php|&lt;\?|<\?)/ig,
 	'this': /\$this/g,
 	'global': /\$_?(GLOBALS|SERVER|GET|POST|FILES|REQUEST|SESSION|ENV|COOKIE|HTTP_RAW_POST_DATA|argc|argv|php_errormsg|http_response_header)/g,
 	'variable': /(\$\w+)\b/ig,
@@ -42,4 +42,49 @@ Prism.languages.insertBefore('php', 'operator', {
 		pattern: /(-&gt;)[\w]+/g,
 		lookbehind: true
 	}
-});
\ No newline at end of file
+});
+
+if (Prism.languages.markup) {
+
+	// Tokenize all inline PHP blocks that are wrapped in <?php ?>
+	// This allows for easy PHP + markup highlighting
+	Prism.hooks.add('before-highlight', function(env) {
+		if (env.language !== 'php') {
+			return;
+		}
+
+		env.tokenStack = [];
+
+		env.code = env.code.replace(/(?:&lt;\?php|&lt;\?|<\?php|<\?)[\w\W]*?(?:\?&gt;|\?>)/ig, function(match) {
+			env.tokenStack.push(match);
+
+			return '{{{PHP' + env.tokenStack.length + '}}}';
+		});
+	});
+
+	// Re-insert the tokens after highlighting
+	Prism.hooks.add('after-highlight', function(env) {
+		if (env.language !== 'php') {
+			return;
+		}
+
+		for (var i = 0, t; t = env.tokenStack[i]; i++) {
+			env.highlightedCode = env.highlightedCode.replace('{{{PHP' + (i + 1) + '}}}', Prism.highlight(t, env.grammar, 'php'));
+		}
+
+		env.element.innerHTML = env.highlightedCode;
+	});
+
+	// Wrap tokens in classes that are missing them
+	Prism.hooks.add('wrap', function(env) {
+		if (env.language === 'php' && env.type === 'markup') {
+			env.content = env.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/, "<span class=\"token php\">$1</span>");
+		}
+	});
+
+	// Add the rules before all others
+	Prism.languages.insertBefore('php', 'comment', {
+		'markup': Prism.languages.markup.tag,
+		'php': /\{\{\{PHP[0-9]+\}\}\}/
+	});
+}
\ No newline at end of file
diff --git a/components/prism-php.min.js b/components/prism-php.min.js
index 24ebb9d..62bfb06 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|extends|private|protected|parent|static|throw|null|echo|print|trait|namespace|use|final|yield|goto)\b/ig,constant:/\b[A-Z0-9_]{2,}\b/g}); Prism.languages.insertBefore("php","keyword",{deliminator:/(\?>|\?&gt;|&lt;\?php|<\?php)/ig,"this":/\$this/g,global:/\$_?(GLOBALS|SERVER|GET|POST|FILES|REQUEST|SESSION|ENV|COOKIE|HTTP_RAW_POST_DATA|argc|argv|php_errormsg|http_response_header)/g,variable:/(\$\w+)\b/ig,scope:{pattern:/\b[\w\\]+::/g,inside:{keyword:/(static|self|parent)/,punctuation:/(::|\\)/}},"package":{pattern:/(\\|namespace\s+|use\s+)[\w\\]+/g,lookbehind:!0,inside:{punctuation:/\\/}}}); Prism.languages.insertBefore("php","operator",{property:{pattern:/(-&gt;)[\w]+/g,lookbehind:!0}});
\ 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|extends|private|protected|parent|static|throw|null|echo|print|trait|namespace|use|final|yield|goto)\b/ig,constant:/\b[A-Z0-9_]{2,}\b/g}); Prism.languages.insertBefore("php","keyword",{deliminator:/(\?>|\?&gt;|&lt;\?php|<\?php|&lt;\?|<\?)/ig,"this":/\$this/g,global:/\$_?(GLOBALS|SERVER|GET|POST|FILES|REQUEST|SESSION|ENV|COOKIE|HTTP_RAW_POST_DATA|argc|argv|php_errormsg|http_response_header)/g,variable:/(\$\w+)\b/ig,scope:{pattern:/\b[\w\\]+::/g,inside:{keyword:/(static|self|parent)/,punctuation:/(::|\\)/}},"package":{pattern:/(\\|namespace\s+|use\s+)[\w\\]+/g,lookbehind:!0,inside:{punctuation:/\\/}}}); Prism.languages.insertBefore("php","operator",{property:{pattern:/(-&gt;)[\w]+/g,lookbehind:!0}}); Prism.languages.markup&&(Prism.hooks.add("before-highlight",function(a){"php"===a.language&&(a.tokenStack=[],a.code=a.code.replace(/(?:&lt;\?php|&lt;\?|<\?php|<\?)[\w\W]*?(?:\?&gt;|\?>)/ig,function(b){a.tokenStack.push(b);return"{{{PHP"+a.tokenStack.length+"}}}"}))}),Prism.hooks.add("after-highlight",function(a){if("php"===a.language){for(var b=0,c;c=a.tokenStack[b];b++)a.highlightedCode=a.highlightedCode.replace("{{{PHP"+(b+1)+"}}}",Prism.highlight(c,a.grammar,"php"));a.element.innerHTML=a.highlightedCode}}), Prism.hooks.add("wrap",function(a){"php"===a.language&&"markup"===a.type&&(a.content=a.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/,'<span class="token php">$1</span>'))}),Prism.languages.insertBefore("php","comment",{markup:Prism.languages.markup.tag,php:/\{\{\{PHP[0-9]+\}\}\}/}));
\ No newline at end of file
diff --git a/examples.html b/examples.html
index cdb4f3a..5a44ff9 100644
--- a/examples.html
+++ b/examples.html
@@ -147,7 +147,7 @@ ol {}</code></pre>
 
 	<h2>@ rule</h2>
 	<pre><code>@media screen and (min-width: 100px) {}</code></pre>
-	
+
 	<h2>LESS variable</h2>
 	<pre><code>@main-color: red;
 .foo {
@@ -312,8 +312,7 @@ public class PrismJS {
 <section class="language-php">
 	<h1>PHP</h1>
 
-	<pre><code>&lt;?php
-namespace Prism;
+	<pre><code>namespace Prism;
 
 use Some\Child\Class;
 
@@ -352,6 +351,22 @@ class Prism extends AbstractClass implements Interface_Class {
 		return $var;
 	}
 }</code></pre>
+
+	<h2>HTML then PHP</h2>
+	<pre><code>&lt;a href="&lt;?php echo $url; ?&gt;"&gt;Link&lt;/a&gt;</code></pre>
+
+	<h2>PHP then HTML (with short tags)</h2>
+	<pre><code>&lt;? if ($var) { ?&gt;&lt;a href="#"&gt;Link&lt;/a&gt;&lt;? } ?&gt;</code></pre>
+
+	<h2>PHP &amp; HTML</h2>
+	<pre><code>&lt;?php foreach (fetchData() as $key =&gt; $value) { ?>
+	&lt;li&gt;
+		&lt;? if ($value) { ?&gt;
+			&lt;span class="class-name"&gt;&lt;?php echo $value; ?&gt;&lt;/span&gt;
+		&lt;? } ?&gt;
+	&lt;/li&gt;
+&lt;?php } ?&gt;</code></pre>
+
 </section>
 
 <section class="language-coffeescript">
@@ -488,6 +503,7 @@ X-Response-Time: 10ms
 <script src="utopia.js"></script>
 <script src="components.js"></script>
 <script src="code.js"></script>
+<script src="components/prism-php.js"></script>
 
 </body>
 </html>