liquid_cms 0.3.0.1 → 0.3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. data/CHANGELOG.rdoc +5 -1
  2. data/Gemfile.lock +1 -1
  3. data/README.rdoc +5 -1
  4. data/app/helpers/cms/common_helper.rb +1 -0
  5. data/app/views/cms/pages/_page.html.erb +2 -1
  6. data/app/views/layouts/cms.html.erb +2 -1
  7. data/lib/generators/liquid_cms/templates/public/cms/codemirror/LICENSE +2 -2
  8. data/lib/generators/liquid_cms/templates/public/cms/codemirror/css/csscolors.css +12 -8
  9. data/lib/generators/liquid_cms/templates/public/cms/codemirror/css/docs.css +123 -29
  10. data/lib/generators/liquid_cms/templates/public/cms/codemirror/csstest.html +1 -1
  11. data/lib/generators/liquid_cms/templates/public/cms/codemirror/htmltest.html +1 -1
  12. data/lib/generators/liquid_cms/templates/public/cms/codemirror/index.html +232 -179
  13. data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/codemirror.js +211 -65
  14. data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/editor.js +360 -194
  15. data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/mirrorframe.js +1 -1
  16. data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/parsecss.js +11 -7
  17. data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/parsejavascript.js +14 -5
  18. data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/parsesparql.js +1 -1
  19. data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/select.js +140 -87
  20. data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/stringstream.js +5 -0
  21. data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/tokenizejavascript.js +1 -1
  22. data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/undo.js +7 -7
  23. data/lib/generators/liquid_cms/templates/public/cms/codemirror/manual.html +148 -52
  24. data/lib/generators/liquid_cms/templates/public/cms/codemirror/story.html +631 -614
  25. data/lib/generators/liquid_cms/templates/public/cms/stylesheets/styles.css +7 -7
  26. data/lib/liquid_cms/version.rb +1 -1
  27. metadata +4 -26
  28. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/lua/LICENSE +0 -32
  29. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/lua/css/luacolors.css +0 -63
  30. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/lua/index.html +0 -68
  31. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/lua/js/parselua.js +0 -253
  32. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/php/LICENSE +0 -37
  33. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/php/css/phpcolors.css +0 -114
  34. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/php/index.html +0 -292
  35. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/php/js/parsephp.js +0 -371
  36. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/php/js/parsephphtmlmixed.js +0 -90
  37. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/php/js/tokenizephp.js +0 -1006
  38. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/plsql/LICENSE +0 -22
  39. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/plsql/css/plsqlcolors.css +0 -57
  40. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/plsql/index.html +0 -67
  41. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/plsql/js/parseplsql.js +0 -233
  42. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/python/LICENSE +0 -32
  43. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/python/css/pythoncolors.css +0 -58
  44. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/python/index.html +0 -141
  45. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/python/js/parsepython.js +0 -542
  46. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/sql/LICENSE +0 -22
  47. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/sql/css/sqlcolors.css +0 -57
  48. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/sql/index.html +0 -56
  49. data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/sql/js/parsesql.js +0 -211
@@ -1,292 +0,0 @@
1
- <!--
2
- Copyright (c) 2008-2009 Yahoo! Inc. All rights reserved.
3
- The copyrights embodied in the content of this file are licensed by
4
- Yahoo! Inc. under the BSD (revised) open source license
5
-
6
- @author Dan Vlad Dascalescu <dandv@yahoo-inc.com>
7
-
8
- -->
9
-
10
-
11
- <html xmlns="http://www.w3.org/1999/xhtml">
12
- <head>
13
- <script src="../../js/codemirror.js" type="text/javascript"></script>
14
- <title>CodeMirror: PHP+HTML+JavaScript+CSS mixed-mode demonstration</title>
15
- <link rel="stylesheet" type="text/css" href="../../css/docs.css"/>
16
- </head>
17
- <body style="padding: 20px;">
18
-
19
- <p>This is a complex demonstration of the <b>PHP+HTML+JavaScript+CSS mixed-mode
20
- syntax highlight</b> capabilities of <a href="../../index.html">CodeMirror</a>.
21
- &lt;?php ... ?> tags use the PHP parser, &lt;script> tags use the JavaScript
22
- parser, and &lt;style> tags use the CSS parser. The rest of the content is
23
- parsed using the XML parser in HTML mode.</p>
24
-
25
- <p>Features of the PHP parser:
26
- <ul>
27
- <li>special "deprecated" style for PHP4 keywords like 'var'
28
- <li>support for PHP 5.3 keywords: 'namespace', 'use'
29
- <li>911 predefined constants, 1301 predefined functions, 105 predeclared classes
30
- from a typical PHP installation in a LAMP environment
31
- <li>new feature: syntax error flagging, thus enabling strict parsing of:
32
- <ol>
33
- <li>function definitions with explicitly or implicitly typed arguments and default values
34
- <li>modifiers (public, static etc.) applied to method and member definitions
35
- <li>foreach(array_expression as $key [=> $value]) loops
36
- </ol>
37
- <li>differentiation between single-quoted strings and double-quoted interpolating strings
38
- </ul>
39
- </p>
40
-
41
- <div style="border: 1px solid black; padding: 3px; background-color: #F8F8F8">
42
- <textarea id="code" cols="120" rows="30">
43
- The "root" parser is XML in HTML mode.
44
- Next, we can switch into PHP mode, for example. This is
45
- <?php echo 'text output by';
46
- ?>
47
- PHP. </b>
48
- On the line above, we just had an XML syntax error due to the </b> tag not being opened.
49
-
50
- <?xml version='1.0' encoding='UTF-8' standalone='yes'?> HTML text will follow
51
- <html>
52
- <head>
53
- <title>Similarly, the 'script' tag will switch to the JavaScript parser:</title>
54
- <script type="text/javascript">
55
- // Press enter inside the object and your new line will be suitably
56
- // indented.
57
- var keyBindings = {
58
- enter: "newline-and-indent",
59
- tab: "reindent-selection",
60
- ctrl_enter: "reparse-buffer",
61
- ctrl_z: "undo",
62
- ctrl_y: "redo",
63
- ctrl_backspace: "undo-for-safari-which-stupidly-enough-blocks-ctrl-z"
64
- };
65
-
66
- // Press tab on the next line and the wrong indentation will be fixed.
67
- var regex = /foo|bar/i;
68
-
69
- function example(x) {
70
- // Local variables get a different colour than global ones.
71
- var y = 44.4;
72
- return x + y - z;
73
- }
74
- </script>
75
- <style>
76
- /* Some example CSS */
77
-
78
- @import url("something.css");
79
-
80
- body {
81
- margin: 0;
82
- padding: 3em 6em;
83
- font-family: tahoma, arial, sans-serif;
84
- color: #000;
85
- }
86
-
87
- #navigation a {
88
- font-weight: bold;
89
- text-decoration: none !important;
90
- }
91
-
92
- h1 {
93
- font-size: 2.5em;
94
- }
95
-
96
- h1:before, h2:before {
97
- content: "::";
98
- }
99
-
100
- code {
101
- font-family: courier, monospace;
102
- font-size: 80%;
103
- color: #418A8A;
104
- }
105
- </style>
106
- </head>
107
-
108
- <body>
109
-
110
- The PHP code below contains some deliberate errors. Play with the editor by fixing them
111
- and observing how the highlight changes.
112
-
113
- <?php
114
- namespace A;
115
- namespace A::B::C;
116
- namespace A::::B;
117
- namespace A::B::C::;
118
- namespace A::B::C::D x;
119
- self::range($row['lft'], $row['rgt'])); // error: extra ')'
120
- $a = (b() + 4) 5 foo; // error: missing operators
121
- self::$var;
122
- $parent = self::range($max + 1, $max + 1);
123
- $row[attributes][$attribute_name] = $attribute_value;
124
- $row[attributes()][$attribute_name] = $attribute_value;
125
- $row[attributes(5)][$attribute_name] = $attribute_value;
126
- $row[$attributes()][$attribute_name] = $attribute_value;
127
- abstract class 5 extends foo implements echo {
128
- private function domainObjectBuilder() {
129
- return $this->use_domain_object_builder
130
- ? $this->domain()->objectBuilder()
131
- : null;
132
- }
133
-
134
- const $myconst = 'some string';
135
- $array[myconst] = 4;
136
- // this is a single-line C++-style comment
137
- # this is a single-line shell-style comment
138
- private var $a = __FILE__;
139
- protected static $b = timezone_transitions_get('some parameter here');
140
- global $g = isset("string");
141
- static $s = hash_update_file; // warning: predefined function non-call
142
- function mike ($var) $foo;
143
- mike(A::func(param));
144
- func($b $c); // error: function parameters must be comma-separated
145
- foo bar; // error: no operator
146
- $baz $quux; // error: no operator
147
- public abstract function loadPageXML(util_FilePath $filename, $merge=0+$foo, $x, $y=3) {
148
- $newrow[$key] = $val;
149
- $newresult[] = $row;
150
- $state = $row['c'] == 1;
151
- $attribute_values[$attribute_name] = null;
152
- $row['attributes'][$attribute_name] = $attribute_value;
153
- $result[$row['element']][$row['attribute']] = $row['value'];
154
- $sql = "multiline string
155
- line2 is special - it'll interpolate variables like $state and method calls
156
- {$this->cache->add($key, 5)} and maybe \"more\"
157
-
158
- line5";
159
- $sql = 'multiline string
160
- single quoting means no \'interpolation\' like "$start" or method call
161
- {$this->cache->add($key, 5)} will happen
162
-
163
- line5';
164
- $bitpattern = 1 << 2;
165
- $bitpattern <<= 3;
166
- $incorrect = <<< 5 EOSTRING // FIXME: CodeMirror update bug: add a letter before 5 and notice that syntax is not updated until EOF, even with continuousScanning: 500
167
- error: the identifier must conform to the identifier rules
168
- EOSTRING;
169
- $sql = <<< EOSQL
170
- SELECT attribute, element, value
171
- FROM attribute_values
172
- WHERE dimension = ?
173
- EOSQL;
174
- $this->lr_cache->add($key, self::range($row['lft'], $row['rgt']));
175
- $composite_string = <<<EOSTRING
176
- some lines here
177
- EOSTRING
178
- . 'something extra';
179
- $page_lft = ($domain->name() == 'page') ? $start + 1 : $page_start + 1;
180
- echo "This is class foo";
181
- echo "a = ".$this ->a[2+3*$array["foo"]]."";
182
- echo "b = {$this->b}"; // FIXME: highlight interpolation in strings
183
- }
184
- final function makecoffee error($types = array("cappuccino"), $coffeeMaker = NULL) {
185
- $out_of_way_amount = $max - $child->left() + 1;
186
- $absolute_pos = $child->left() - $move->width();
187
- $varfunc(1, 'x');
188
- $varfunc(1, 'x') + foo() - 5;
189
- $funcarray[$i]('param1', $param2);
190
- $lr[$domain_name] = $this->get_left_and_right($domain,
191
- $dimension_name,
192
- $element_name);
193
- $domain_list = is_null($domain) ?
194
- r3_Domain::names() :
195
- array($domain->name());
196
- foreach (r3_Domain::names() as $domain_name) {
197
- $placeholders = 'distance LIKE '
198
- . implode(array_fill(1, $num_distances, '?'),
199
- ' OR distance LIKE ');
200
-
201
- }
202
- return $this->target*$this->trans+myfunc(__METHOD__);
203
- /*
204
- echo 'This is a test'; /* This comment will cause a problem */
205
- */
206
- }
207
- switch( $type ) {
208
- case "r3core_AddTemplateToTargetEvent":
209
- $this->notifyAddTemplateToTarget( $genevent );
210
- break;
211
- case "r3core_GenerateTargetEvent" $this:
212
- for($i=0; $i<=this->method(); $i++) {
213
- echo 'Syntax "highlighting"';
214
- }
215
- try {
216
- foreach($array xor $loader->parse_fn($filename) as $key => value) {
217
- namespace r3;
218
- }
219
- } catch( Exception $e ) {
220
- /** restore the backup
221
- */
222
- $this->loadAll($tmp, $event, true);
223
- // `php -l` doesn't complain at all at this (it assumes string constants):
224
- this + makes * no - sense;
225
- }
226
-
227
- break;
228
-
229
- default moo:
230
- throw new r3_util_Exception( get_class( $genevent ) . " does not map" );
231
- }
232
-
233
-
234
- };
235
-
236
- ?>
237
-
238
- <r3:cphp>
239
- php("works", $here, 2);
240
- </r3:cphp>
241
-
242
- <r4:cphp>
243
- class foo {
244
- // a comment
245
- var $a;
246
- var $b;
247
- };
248
- </r4:cphp>
249
-
250
- <h1>This is an <?php # echo 'simple';?> example.</h1>
251
- <p>The header above will say 'This is an example'.</p>
252
- <h1>This is an <?php // echo 'simple';?> example.</h1>
253
-
254
- <?php echo; ?>
255
- <body>
256
-
257
- <?php echo "<html>
258
- <head>
259
- <script>
260
- var foo = 'bar';
261
- </script>
262
- <style>
263
- span.test {font-family: arial, 'lucida console', sans-serif}
264
- </style>
265
- </head>
266
- <body>
267
- <!-- comment -->
268
- </body>
269
- </html>"; ?>
270
-
271
- </body>
272
- </html>
273
-
274
-
275
- </textarea>
276
- </div>
277
-
278
- <script type="text/javascript">
279
- var editor = CodeMirror.fromTextArea('code', {
280
- height: "350px",
281
- parserfile: ["parsexml.js", "parsecss.js", "tokenizejavascript.js", "parsejavascript.js",
282
- "../contrib/php/js/tokenizephp.js", "../contrib/php/js/parsephp.js",
283
- "../contrib/php/js/parsephphtmlmixed.js"],
284
- stylesheet: ["../../css/xmlcolors.css", "../../css/jscolors.css", "../../css/csscolors.css", "css/phpcolors.css"],
285
- path: "../../js/",
286
- continuousScanning: 500
287
- });
288
- </script>
289
-
290
-
291
- </body>
292
- </html>
@@ -1,371 +0,0 @@
1
- /*
2
- Copyright (c) 2008-2009 Yahoo! Inc. All rights reserved.
3
- The copyrights embodied in the content of this file are licensed by
4
- Yahoo! Inc. under the BSD (revised) open source license
5
-
6
- @author Dan Vlad Dascalescu <dandv@yahoo-inc.com>
7
-
8
-
9
- Parse function for PHP. Makes use of the tokenizer from tokenizephp.js.
10
- Based on parsejavascript.js by Marijn Haverbeke.
11
-
12
-
13
- Features:
14
- + special "deprecated" style for PHP4 keywords like 'var'
15
- + support for PHP 5.3 keywords: 'namespace', 'use'
16
- + 911 predefined constants, 1301 predefined functions, 105 predeclared classes
17
- from a typical PHP installation in a LAMP environment
18
- + new feature: syntax error flagging, thus enabling strict parsing of:
19
- + function definitions with explicitly or implicitly typed arguments and default values
20
- + modifiers (public, static etc.) applied to method and member definitions
21
- + foreach(array_expression as $key [=> $value]) loops
22
- + differentiation between single-quoted strings and double-quoted interpolating strings
23
-
24
- */
25
-
26
-
27
- // add the Array.indexOf method for JS engines that don't support it (e.g. IE)
28
- // code from https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Global_Objects/Array/IndexOf
29
- if (!Array.prototype.indexOf)
30
- {
31
- Array.prototype.indexOf = function(elt /*, from*/)
32
- {
33
- var len = this.length;
34
-
35
- var from = Number(arguments[1]) || 0;
36
- from = (from < 0)
37
- ? Math.ceil(from)
38
- : Math.floor(from);
39
- if (from < 0)
40
- from += len;
41
-
42
- for (; from < len; from++)
43
- {
44
- if (from in this &&
45
- this[from] === elt)
46
- return from;
47
- }
48
- return -1;
49
- };
50
- }
51
-
52
-
53
- var PHPParser = Editor.Parser = (function() {
54
- // Token types that can be considered to be atoms, part of operator expressions
55
- var atomicTypes = {
56
- "atom": true, "number": true, "variable": true, "string": true
57
- };
58
- // Constructor for the lexical context objects.
59
- function PHPLexical(indented, column, type, align, prev, info) {
60
- // indentation at start of this line
61
- this.indented = indented;
62
- // column at which this scope was opened
63
- this.column = column;
64
- // type of scope ('stat' (statement), 'form' (special form), '[', '{', or '(')
65
- this.type = type;
66
- // '[', '{', or '(' blocks that have any text after their opening
67
- // character are said to be 'aligned' -- any lines below are
68
- // indented all the way to the opening character.
69
- if (align != null)
70
- this.align = align;
71
- // Parent scope, if any.
72
- this.prev = prev;
73
- this.info = info;
74
- }
75
-
76
- // PHP indentation rules
77
- function indentPHP(lexical) {
78
- return function(firstChars) {
79
- var firstChar = firstChars && firstChars.charAt(0), type = lexical.type;
80
- var closing = firstChar == type;
81
- if (type == "form" && firstChar == "{")
82
- return lexical.indented;
83
- else if (type == "stat" || type == "form")
84
- return lexical.indented + indentUnit;
85
- else if (lexical.info == "switch" && !closing)
86
- return lexical.indented + (/^(?:case|default)\b/.test(firstChars) ? indentUnit : 2 * indentUnit);
87
- else if (lexical.align)
88
- return lexical.column - (closing ? 1 : 0);
89
- else
90
- return lexical.indented + (closing ? 0 : indentUnit);
91
- };
92
- }
93
-
94
- // The parser-iterator-producing function itself.
95
- function parsePHP(input, basecolumn) {
96
- // Wrap the input in a token stream
97
- var tokens = tokenizePHP(input);
98
- // The parser state. cc is a stack of actions that have to be
99
- // performed to finish the current statement. For example we might
100
- // know that we still need to find a closing parenthesis and a
101
- // semicolon. Actions at the end of the stack go first. It is
102
- // initialized with an infinitely looping action that consumes
103
- // whole statements.
104
- var cc = [statements];
105
- // The lexical scope, used mostly for indentation.
106
- var lexical = new PHPLexical((basecolumn || 0) - indentUnit, 0, "block", false);
107
- // Current column, and the indentation at the start of the current
108
- // line. Used to create lexical scope objects.
109
- var column = 0;
110
- var indented = 0;
111
- // Variables which are used by the mark, cont, and pass functions
112
- // below to communicate with the driver loop in the 'next' function.
113
- var consume, marked;
114
-
115
- // The iterator object.
116
- var parser = {next: next, copy: copy};
117
-
118
- // parsing is accomplished by calling next() repeatedly
119
- function next(){
120
- // Start by performing any 'lexical' actions (adjusting the
121
- // lexical variable), or the operations below will be working
122
- // with the wrong lexical state.
123
- while(cc[cc.length - 1].lex)
124
- cc.pop()();
125
-
126
- // Fetch the next token.
127
- var token = tokens.next();
128
-
129
- // Adjust column and indented.
130
- if (token.type == "whitespace" && column == 0)
131
- indented = token.value.length;
132
- column += token.value.length;
133
- if (token.content == "\n"){
134
- indented = column = 0;
135
- // If the lexical scope's align property is still undefined at
136
- // the end of the line, it is an un-aligned scope.
137
- if (!("align" in lexical))
138
- lexical.align = false;
139
- // Newline tokens get an indentation function associated with
140
- // them.
141
- token.indentation = indentPHP(lexical);
142
- }
143
- // No more processing for meaningless tokens.
144
- if (token.type == "whitespace" || token.type == "comment"
145
- || token.type == "string_not_terminated" )
146
- return token;
147
- // When a meaningful token is found and the lexical scope's
148
- // align is undefined, it is an aligned scope.
149
- if (!("align" in lexical))
150
- lexical.align = true;
151
-
152
- // Execute actions until one 'consumes' the token and we can
153
- // return it. 'marked' is used to change the style of the current token.
154
- while(true) {
155
- consume = marked = false;
156
- // Take and execute the topmost action.
157
- var action = cc.pop();
158
- action(token);
159
-
160
- if (consume){
161
- if (marked)
162
- token.style = marked;
163
- // Here we differentiate between local and global variables.
164
- return token;
165
- }
166
- }
167
- return 1; // Firebug workaround for http://code.google.com/p/fbug/issues/detail?id=1239#c1
168
- }
169
-
170
- // This makes a copy of the parser state. It stores all the
171
- // stateful variables in a closure, and returns a function that
172
- // will restore them when called with a new input stream. Note
173
- // that the cc array has to be copied, because it is contantly
174
- // being modified. Lexical objects are not mutated, so they can
175
- // be shared between runs of the parser.
176
- function copy(){
177
- var _lexical = lexical, _cc = cc.concat([]), _tokenState = tokens.state;
178
-
179
- return function copyParser(input){
180
- lexical = _lexical;
181
- cc = _cc.concat([]); // copies the array
182
- column = indented = 0;
183
- tokens = tokenizePHP(input, _tokenState);
184
- return parser;
185
- };
186
- }
187
-
188
- // Helper function for pushing a number of actions onto the cc
189
- // stack in reverse order.
190
- function push(fs){
191
- for (var i = fs.length - 1; i >= 0; i--)
192
- cc.push(fs[i]);
193
- }
194
- // cont and pass are used by the action functions to add other
195
- // actions to the stack. cont will cause the current token to be
196
- // consumed, pass will leave it for the next action.
197
- function cont(){
198
- push(arguments);
199
- consume = true;
200
- }
201
- function pass(){
202
- push(arguments);
203
- consume = false;
204
- }
205
- // Used to change the style of the current token.
206
- function mark(style){
207
- marked = style;
208
- }
209
- // Add a lyer of style to the current token, for example syntax-error
210
- function mark_add(style){
211
- marked = marked + ' ' + style;
212
- }
213
-
214
- // Push a new lexical context of the given type.
215
- function pushlex(type, info) {
216
- var result = function pushlexing() {
217
- lexical = new PHPLexical(indented, column, type, null, lexical, info)
218
- };
219
- result.lex = true;
220
- return result;
221
- }
222
- // Pop off the current lexical context.
223
- function poplex(){
224
- lexical = lexical.prev;
225
- }
226
- poplex.lex = true;
227
- // The 'lex' flag on these actions is used by the 'next' function
228
- // to know they can (and have to) be ran before moving on to the
229
- // next token.
230
-
231
- // Creates an action that discards tokens until it finds one of
232
- // the given type. This will ignore (and recover from) syntax errors.
233
- function expect(wanted){
234
- return function expecting(token){
235
- if (token.type == wanted) cont(); // consume the token
236
- else {
237
- cont(arguments.callee); // continue expecting() - call itself
238
- }
239
- };
240
- }
241
-
242
- // Require a specific token type, or one of the tokens passed in the 'wanted' array
243
- // Used to detect blatant syntax errors. 'execute' is used to pass extra code
244
- // to be executed if the token is matched. For example, a '(' match could
245
- // 'execute' a cont( compasep(funcarg), require(")") )
246
- function require(wanted, execute){
247
- return function requiring(token){
248
- var ok;
249
- var type = token.type;
250
- if (typeof(wanted) == "string")
251
- ok = (type == wanted) -1;
252
- else
253
- ok = wanted.indexOf(type);
254
- if (ok >= 0) {
255
- if (execute && typeof(execute[ok]) == "function")
256
- execute[ok](token);
257
- cont(); // just consume the token
258
- }
259
- else {
260
- if (!marked) mark(token.style);
261
- mark_add("syntax-error");
262
- cont(arguments.callee);
263
- }
264
- };
265
- }
266
-
267
- // Looks for a statement, and then calls itself.
268
- function statements(token){
269
- return pass(statement, statements);
270
- }
271
- // Dispatches various types of statements based on the type of the current token.
272
- function statement(token){
273
- var type = token.type;
274
- if (type == "keyword a") cont(pushlex("form"), expression, statement, poplex);
275
- else if (type == "keyword b") cont(pushlex("form"), statement, poplex);
276
- else if (type == "{") cont(pushlex("}"), block, poplex);
277
- else if (type == "function") funcdef();
278
- // technically, "class implode {...}" is correct, but we'll flag that as an error because it overrides a predefined function
279
- else if (type == "class") cont(require("t_string"), expect("{"), pushlex("}"), block, poplex);
280
- else if (type == "foreach") cont(pushlex("form"), require("("), pushlex(")"), expression, require("as"), require("variable"), /* => $value */ expect(")"), poplex, statement, poplex);
281
- else if (type == "for") cont(pushlex("form"), require("("), pushlex(")"), expression, require(";"), expression, require(";"), expression, require(")"), poplex, statement, poplex);
282
- // public final function foo(), protected static $bar;
283
- else if (type == "modifier") cont(require(["modifier", "variable", "function"], [null, null, funcdef]));
284
- else if (type == "switch") cont(pushlex("form"), require("("), expression, require(")"), pushlex("}", "switch"), require([":", "{"]), block, poplex, poplex);
285
- else if (type == "case") cont(expression, require(":"));
286
- else if (type == "default") cont(require(":"));
287
- else if (type == "catch") cont(pushlex("form"), require("("), require("t_string"), require("variable"), require(")"), statement, poplex);
288
- else if (type == "const") cont(require("t_string")); // 'const static x=5' is a syntax error
289
- // technically, "namespace implode {...}" is correct, but we'll flag that as an error because it overrides a predefined function
290
- else if (type == "namespace") cont(namespacedef, require(";"));
291
- // $variables may be followed by operators, () for variable function calls, or [] subscripts
292
- else pass(pushlex("stat"), expression, require(";"), poplex);
293
- }
294
- // Dispatch expression types.
295
- function expression(token){
296
- var type = token.type;
297
- if (atomicTypes.hasOwnProperty(type)) cont(maybeoperator);
298
- else if (type == "<<<") cont(require("string"), maybeoperator); // heredoc/nowdoc
299
- else if (type == "t_string") cont(maybe_double_colon, maybeoperator);
300
- else if (type == "keyword c") cont(expression);
301
- // function call or parenthesized expression: $a = ($b + 1) * 2;
302
- else if (type == "(") cont(pushlex(")"), commasep(expression), require(")"), poplex, maybeoperator);
303
- else if (type == "operator") cont(expression);
304
- }
305
- // Called for places where operators, function calls, or subscripts are
306
- // valid. Will skip on to the next action if none is found.
307
- function maybeoperator(token){
308
- var type = token.type;
309
- if (type == "operator") {
310
- if (token.content == "?") cont(expression, require(":"), expression); // ternary operator
311
- else cont(expression);
312
- }
313
- else if (type == "(") cont(pushlex(")"), expression, commasep(expression), require(")"), poplex, maybeoperator /* $varfunc() + 3 */);
314
- else if (type == "[") cont(pushlex("]"), expression, require("]"), maybeoperator /* for multidimensional arrays, or $func[$i]() */, poplex);
315
- }
316
- // A regular use of the double colon to specify a class, as in self::func() or myclass::$var;
317
- // Differs from `namespace` or `use` in that only one class can be the parent; chains (A::B::$var) are a syntax error.
318
- function maybe_double_colon(token) {
319
- if (token.type == "t_double_colon")
320
- // A::$var, A::func(), A::const
321
- cont(require(["t_string", "variable"]), maybeoperator);
322
- else {
323
- // a t_string wasn't followed by ::, such as in a function call: foo()
324
- pass(expression)
325
- }
326
- }
327
- // the declaration or definition of a function
328
- function funcdef() {
329
- cont(require("t_string"), require("("), pushlex(")"), commasep(funcarg), require(")"), poplex, block);
330
- }
331
- // Parses a comma-separated list of the things that are recognized
332
- // by the 'what' argument.
333
- function commasep(what){
334
- function proceed(token) {
335
- if (token.type == ",") cont(what, proceed);
336
- }
337
- return function commaSeparated() {
338
- pass(what, proceed);
339
- };
340
- }
341
- // Look for statements until a closing brace is found.
342
- function block(token) {
343
- if (token.type == "}") cont();
344
- else pass(statement, block);
345
- }
346
- function maybedefaultparameter(token){
347
- if (token.content == "=") cont(expression);
348
- }
349
- // support for default arguments: http://us.php.net/manual/en/functions.arguments.php#functions.arguments.default
350
- function funcarg(token){
351
- // function foo(myclass $obj) {...}
352
- if (token.type == "t_string") cont(require("variable"), maybedefaultparameter);
353
- // function foo($string) {...}
354
- else if (token.type == "variable") cont(maybedefaultparameter);
355
- }
356
-
357
- // A namespace definition or use
358
- function maybe_double_colon_def(token) {
359
- if (token.type == "t_double_colon")
360
- cont(namespacedef);
361
- }
362
- function namespacedef(token) {
363
- pass(require("t_string"), maybe_double_colon_def);
364
- }
365
-
366
- return parser;
367
- }
368
-
369
- return {make: parsePHP, electricChars: "{}:"};
370
-
371
- })();