Skip to content

Commit 534876b

Browse files
committed
add simple PHP mode
1 parent 4c90a70 commit 534876b

File tree

5 files changed

+128
-2
lines changed

5 files changed

+128
-2
lines changed

index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ <h3>Available modes:</h3>
7979
<li><a href="mode/css/">CSS</a></li>
8080
<li><a href="mode/htmlmixed/">Mixed-mode HTML</a></li>
8181
<li><a href="mode/clike/">Simple mode for C-like languages (C, C++, Java)</a></li>
82+
<li><a href="mode/php/">PHP</a></li>
8283
<li><a href="mode/diff/">Diff</a></li>
8384
</ul>
8485

lib/codemirror.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
position: absolute; left: 0; top: 0;
1010
background-color: #f7f7f7;
1111
border-right: 1px solid #eee;
12-
min-width: 1.2em;
12+
min-width: 2em;
1313
height: 100%;
1414
}
1515
.CodeMirror-gutter-text {

mode/php/index.html

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<title>CodeMirror 2: PHP mode</title>
5+
<link rel="stylesheet" href="../../lib/codemirror.css">
6+
<script src="../../lib/codemirror.js"></script>
7+
<script src="../xml/xml.js"></script>
8+
<link rel="stylesheet" href="../xml/xml.css">
9+
<script src="../javascript/javascript.js"></script>
10+
<link rel="stylesheet" href="../javascript/javascript.css">
11+
<script src="../css/css.js"></script>
12+
<link rel="stylesheet" href="../css/css.css">
13+
<script src="../clike/clike.js"></script>
14+
<link rel="stylesheet" href="../clike/clike.css">
15+
<script src="php.js"></script>
16+
<style type="text/css">
17+
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
18+
</style>
19+
</head>
20+
<body style="max-width: 70em; margin-left: 2em; font-family: tahoma, arial, sans-serif;">
21+
<h1>CodeMirror 2: PHP mode</h1>
22+
23+
<form><textarea id="code" name="code">
24+
<?php
25+
function hello($who) {
26+
return "Hello " . $who;
27+
}
28+
?>
29+
<p>The program says <?= hello("World") ?>.</p>
30+
<script>
31+
alert("And here is some JS code"); // also colored
32+
</script>
33+
</textarea></form>
34+
35+
<script>
36+
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
37+
lineNumbers: true,
38+
matchBrackets: true,
39+
mode: "application/x-httpd-php"
40+
});
41+
</script>
42+
43+
<p>...</p>
44+
45+
<p><strong>MIME types defined:</strong> <code>application/x-httpd-php</code>.</p>
46+
</body>
47+
</html>

mode/php/php.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
(function() {
2+
function keywords(str) {
3+
var obj = {}, words = str.split(" ");
4+
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
5+
return obj;
6+
}
7+
var phpKeywords =
8+
keywords("abstract and array as break case catch cfunction class clone const continue declare " +
9+
"default do else elseif enddeclare endfor endforeach endif endswitch endwhile extends " +
10+
"final for foreach function global goto if implements interface instanceof namespace " +
11+
"new or private protected public static switch throw try use var while xor");
12+
13+
CodeMirror.defineMode("php", function(config, parserConfig) {
14+
var htmlMode = CodeMirror.getMode(config, "text/html");
15+
var jsMode = CodeMirror.getMode(config, "text/javascript");
16+
var cssMode = CodeMirror.getMode(config, "text/css");
17+
var phpMode = CodeMirror.getMode(config, {name: "clike", keywords: phpKeywords});
18+
19+
function dispatch(stream, state) { // TODO open PHP inside text/css
20+
var cur = state.context[0];
21+
if (cur.mode == htmlMode) {
22+
var style = htmlMode.token(stream, cur.state);
23+
if (style == "xml-processing")
24+
state.context.unshift({mode: phpMode, state: state.php, close: /^\?>/});
25+
else if (style == "xml-tag" && stream.current() == ">" && cur.state.context) {
26+
if (/^script$/i.test(cur.state.context.tagName))
27+
state.context.unshift({mode: jsMode,
28+
state: jsMode.startState(htmlMode.indent(cur.state, "")),
29+
close: /^<\/\s*script\s*>/i});
30+
else if (/^style$/i.test(cur.state.context.tagName))
31+
state.context.unshift({mode: cssMode,
32+
state: cssMode.startState(htmlMode.indent(cur.state, "")),
33+
close: /^<\/\s*style\s*>/i});
34+
}
35+
return style;
36+
}
37+
else if (stream.match(cur.close, false)) {
38+
state.context.shift();
39+
return dispatch(stream, state);
40+
}
41+
else return cur.mode.token(stream, cur.state);
42+
}
43+
44+
return {
45+
startState: function() {
46+
var html = htmlMode.startState();
47+
return {html: html,
48+
php: phpMode.startState(),
49+
context: [{mode: htmlMode, state: html, close: null}]};
50+
},
51+
52+
copyState: function(state) {
53+
var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html),
54+
php = state.php, phpNew = CodeMirror.copyState(phpMode, php), contextNew = [];
55+
for (var i = 0; i < state.context.length; ++i) {
56+
var context = state.context[i], cstate = context.state;
57+
if (cstate == html) cstate = htmlNew;
58+
else if (cstate == php) cstate = phpNew;
59+
else cstate = CodeMirror.copyState(context.mode, cstate);
60+
contextNew.push({mode: context.mode, state: cstate, close: context.close});
61+
}
62+
return {html: htmlNew, php: phpNew, context: contextNew};
63+
},
64+
65+
token: dispatch,
66+
67+
indent: function(state, textAfter) {
68+
var cur = state.context[0];
69+
return cur.mode.indent(cur.state, textAfter);
70+
},
71+
72+
electricChars: "/{}:"
73+
}
74+
});
75+
})();
76+
77+
CodeMirror.defineMIME("application/x-httpd-php", "php");

mode/xml/xml.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
3333
}
3434
else if (stream.eat("?")) {
3535
stream.eatWhile(/[\w\._\-]/);
36-
return chain(inBlock("xml-processing", "?>"));
36+
state.tokenize = inBlock("xml-processing", "?>");
37+
return "xml-processing";
3738
}
3839
else {
3940
type = stream.eat("/") ? "closeTag" : "openTag";

0 commit comments

Comments
 (0)