liquid_cms 0.2.1.1 → 0.2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. data/CHANGELOG.rdoc +7 -0
  2. data/README.rdoc +15 -1
  3. data/TODO.rdoc +0 -2
  4. data/app/controllers/cms/assets_controller.rb +20 -6
  5. data/app/controllers/cms/components_controller.rb +11 -3
  6. data/app/controllers/cms/pages_controller.rb +15 -4
  7. data/app/helpers/cms/common_helper.rb +31 -31
  8. data/app/liquid/cms_paperclip_extension.rb +75 -3
  9. data/app/models/cms/asset.rb +1 -1
  10. data/app/models/cms/component.rb +3 -3
  11. data/app/views/cms/assets/_form.html.erb +1 -1
  12. data/app/views/cms/assets/update.js.rjs +1 -0
  13. data/app/views/cms/components/update.js.rjs +1 -0
  14. data/app/views/cms/pages/_form.html.erb +1 -1
  15. data/app/views/cms/pages/update.js.rjs +1 -0
  16. data/app/views/layouts/cms.html.erb +4 -3
  17. data/generators/liquid_cms/liquid_cms_generator.rb +1 -0
  18. data/generators/liquid_cms/templates/config/locales/cms/en.yml +4 -0
  19. data/generators/liquid_cms/templates/migration_rev2.rb +13 -0
  20. data/generators/liquid_cms/templates/public/cms/codemirror/LICENSE +16 -20
  21. data/generators/liquid_cms/templates/public/cms/codemirror/lib/codemirror.css +68 -0
  22. data/generators/liquid_cms/templates/public/cms/codemirror/lib/codemirror.js +2197 -0
  23. data/generators/liquid_cms/templates/public/cms/codemirror/lib/overlay.js +51 -0
  24. data/generators/liquid_cms/templates/public/cms/codemirror/lib/runmode.js +27 -0
  25. data/generators/liquid_cms/templates/public/cms/codemirror/mode/clike/clike.js +247 -0
  26. data/generators/liquid_cms/templates/public/cms/codemirror/mode/clike/index.html +102 -0
  27. data/generators/liquid_cms/templates/public/cms/codemirror/mode/clojure/clojure.js +207 -0
  28. data/generators/liquid_cms/templates/public/cms/codemirror/mode/clojure/index.html +85 -0
  29. data/generators/liquid_cms/templates/public/cms/codemirror/mode/coffeescript/LICENSE +22 -0
  30. data/generators/liquid_cms/templates/public/cms/codemirror/mode/coffeescript/coffeescript.js +325 -0
  31. data/generators/liquid_cms/templates/public/cms/codemirror/mode/coffeescript/index.html +722 -0
  32. data/generators/liquid_cms/templates/public/cms/codemirror/mode/css/css.js +124 -0
  33. data/generators/liquid_cms/templates/public/cms/codemirror/mode/css/index.html +56 -0
  34. data/generators/liquid_cms/templates/public/cms/codemirror/mode/diff/diff.css +3 -0
  35. data/generators/liquid_cms/templates/public/cms/codemirror/mode/diff/diff.js +13 -0
  36. data/generators/liquid_cms/templates/public/cms/codemirror/mode/diff/index.html +99 -0
  37. data/generators/liquid_cms/templates/public/cms/codemirror/mode/haskell/haskell.js +242 -0
  38. data/generators/liquid_cms/templates/public/cms/codemirror/mode/haskell/index.html +60 -0
  39. data/generators/liquid_cms/templates/public/cms/codemirror/mode/htmlmixed/htmlmixed.js +79 -0
  40. data/generators/liquid_cms/templates/public/cms/codemirror/mode/htmlmixed/index.html +52 -0
  41. data/generators/liquid_cms/templates/public/cms/codemirror/mode/javascript/index.html +78 -0
  42. data/generators/liquid_cms/templates/public/cms/codemirror/mode/javascript/javascript.js +352 -0
  43. data/generators/liquid_cms/templates/public/cms/codemirror/mode/jinja2/index.html +38 -0
  44. data/generators/liquid_cms/templates/public/cms/codemirror/mode/jinja2/jinja2.js +42 -0
  45. data/generators/liquid_cms/templates/public/cms/codemirror/mode/lua/index.html +72 -0
  46. data/generators/liquid_cms/templates/public/cms/codemirror/mode/lua/lua.js +140 -0
  47. data/generators/liquid_cms/templates/public/cms/codemirror/mode/markdown/index.html +340 -0
  48. data/generators/liquid_cms/templates/public/cms/codemirror/mode/markdown/markdown.css +10 -0
  49. data/generators/liquid_cms/templates/public/cms/codemirror/mode/markdown/markdown.js +230 -0
  50. data/generators/liquid_cms/templates/public/cms/codemirror/mode/ntriples/index.html +33 -0
  51. data/generators/liquid_cms/templates/public/cms/codemirror/mode/ntriples/ntriples.js +172 -0
  52. data/generators/liquid_cms/templates/public/cms/codemirror/mode/pascal/LICENSE +7 -0
  53. data/generators/liquid_cms/templates/public/cms/codemirror/mode/pascal/index.html +49 -0
  54. data/generators/liquid_cms/templates/public/cms/codemirror/mode/pascal/pascal.js +138 -0
  55. data/generators/liquid_cms/templates/public/cms/codemirror/mode/php/index.html +49 -0
  56. data/generators/liquid_cms/templates/public/cms/codemirror/mode/php/php.js +116 -0
  57. data/generators/liquid_cms/templates/public/cms/codemirror/mode/plsql/index.html +63 -0
  58. data/generators/liquid_cms/templates/public/cms/codemirror/mode/plsql/plsql.js +217 -0
  59. data/generators/liquid_cms/templates/public/cms/codemirror/mode/python/LICENSE.txt +21 -0
  60. data/generators/liquid_cms/templates/public/cms/codemirror/mode/python/index.html +123 -0
  61. data/generators/liquid_cms/templates/public/cms/codemirror/mode/python/python.js +320 -0
  62. data/generators/liquid_cms/templates/public/cms/codemirror/mode/r/LICENSE +24 -0
  63. data/generators/liquid_cms/templates/public/cms/codemirror/mode/r/index.html +74 -0
  64. data/generators/liquid_cms/templates/public/cms/codemirror/mode/r/r.js +141 -0
  65. data/generators/liquid_cms/templates/public/cms/codemirror/mode/rst/index.html +526 -0
  66. data/generators/liquid_cms/templates/public/cms/codemirror/mode/rst/rst.css +75 -0
  67. data/generators/liquid_cms/templates/public/cms/codemirror/mode/rst/rst.js +333 -0
  68. data/generators/liquid_cms/templates/public/cms/codemirror/mode/ruby/LICENSE +24 -0
  69. data/generators/liquid_cms/templates/public/cms/codemirror/mode/ruby/index.html +172 -0
  70. data/generators/liquid_cms/templates/public/cms/codemirror/mode/ruby/ruby.js +195 -0
  71. data/generators/liquid_cms/templates/public/cms/codemirror/mode/scheme/index.html +65 -0
  72. data/generators/liquid_cms/templates/public/cms/codemirror/mode/scheme/scheme.js +202 -0
  73. data/generators/liquid_cms/templates/public/cms/codemirror/mode/smalltalk/index.html +56 -0
  74. data/generators/liquid_cms/templates/public/cms/codemirror/mode/smalltalk/smalltalk.js +122 -0
  75. data/generators/liquid_cms/templates/public/cms/codemirror/mode/sparql/index.html +41 -0
  76. data/generators/liquid_cms/templates/public/cms/codemirror/mode/sparql/sparql.js +143 -0
  77. data/generators/liquid_cms/templates/public/cms/codemirror/mode/stex/index.html +96 -0
  78. data/generators/liquid_cms/templates/public/cms/codemirror/mode/stex/stex.js +167 -0
  79. data/generators/liquid_cms/templates/public/cms/codemirror/mode/velocity/index.html +103 -0
  80. data/generators/liquid_cms/templates/public/cms/codemirror/mode/velocity/velocity.js +146 -0
  81. data/generators/liquid_cms/templates/public/cms/codemirror/mode/xml/index.html +42 -0
  82. data/generators/liquid_cms/templates/public/cms/codemirror/mode/xml/xml.js +231 -0
  83. data/generators/liquid_cms/templates/public/cms/codemirror/mode/xmlpure/index.html +60 -0
  84. data/generators/liquid_cms/templates/public/cms/codemirror/mode/xmlpure/xmlpure.js +481 -0
  85. data/generators/liquid_cms/templates/public/cms/codemirror/mode/yaml/index.html +68 -0
  86. data/generators/liquid_cms/templates/public/cms/codemirror/mode/yaml/yaml.js +95 -0
  87. data/generators/liquid_cms/templates/public/cms/codemirror/theme/cobalt.css +17 -0
  88. data/generators/liquid_cms/templates/public/cms/codemirror/theme/default.css +19 -0
  89. data/generators/liquid_cms/templates/public/cms/codemirror/theme/eclipse.css +24 -0
  90. data/generators/liquid_cms/templates/public/cms/codemirror/theme/elegant.css +9 -0
  91. data/generators/liquid_cms/templates/public/cms/codemirror/theme/neat.css +8 -0
  92. data/generators/liquid_cms/templates/public/cms/codemirror/theme/night.css +20 -0
  93. data/generators/liquid_cms/templates/public/cms/javascripts/cms.js +1 -1
  94. data/generators/liquid_cms/templates/public/cms/javascripts/codemirror_custom.js +96 -0
  95. data/generators/liquid_cms/templates/public/cms/stylesheets/codemirror_changes.css +26 -0
  96. data/generators/liquid_cms/templates/public/cms/stylesheets/liquid.css +7 -0
  97. data/generators/liquid_cms/templates/public/cms/stylesheets/simple_form.css +0 -8
  98. data/lib/liquid_cms/version.rb +1 -1
  99. data/liquid_cms.gemspec +0 -1
  100. data/test/functional/assets_controller_test.rb +35 -20
  101. data/test/functional/components_controller_test.rb +15 -5
  102. data/test/functional/pages_controller_test.rb +19 -6
  103. data/test/rails_app/config/environment.rb +1 -1
  104. data/test/rails_app/config/locales/cms/en.yml +19 -4
  105. data/test/rails_app/db/migrate/20110511161859_create_liquid_cms_upgrade_rev2.rb +13 -0
  106. data/test/unit/asset_test.rb +1 -1
  107. metadata +100 -58
  108. data/generators/liquid_cms/templates/public/cms/codemirror/css/csscolors.css +0 -55
  109. data/generators/liquid_cms/templates/public/cms/codemirror/css/docs.css +0 -158
  110. data/generators/liquid_cms/templates/public/cms/codemirror/css/font.js +0 -15
  111. data/generators/liquid_cms/templates/public/cms/codemirror/css/jscolors.css +0 -59
  112. data/generators/liquid_cms/templates/public/cms/codemirror/css/sparqlcolors.css +0 -43
  113. data/generators/liquid_cms/templates/public/cms/codemirror/css/xmlcolors.css +0 -55
  114. data/generators/liquid_cms/templates/public/cms/codemirror/js/codemirror.js +0 -582
  115. data/generators/liquid_cms/templates/public/cms/codemirror/js/editor.js +0 -1671
  116. data/generators/liquid_cms/templates/public/cms/codemirror/js/highlight.js +0 -68
  117. data/generators/liquid_cms/templates/public/cms/codemirror/js/mirrorframe.js +0 -81
  118. data/generators/liquid_cms/templates/public/cms/codemirror/js/parsecss.js +0 -161
  119. data/generators/liquid_cms/templates/public/cms/codemirror/js/parsedummy.js +0 -32
  120. data/generators/liquid_cms/templates/public/cms/codemirror/js/parsehtmlmixed.js +0 -93
  121. data/generators/liquid_cms/templates/public/cms/codemirror/js/parsejavascript.js +0 -359
  122. data/generators/liquid_cms/templates/public/cms/codemirror/js/parsesparql.js +0 -162
  123. data/generators/liquid_cms/templates/public/cms/codemirror/js/parsexml.js +0 -291
  124. data/generators/liquid_cms/templates/public/cms/codemirror/js/select.js +0 -699
  125. data/generators/liquid_cms/templates/public/cms/codemirror/js/stringstream.js +0 -159
  126. data/generators/liquid_cms/templates/public/cms/codemirror/js/tokenize.js +0 -57
  127. data/generators/liquid_cms/templates/public/cms/codemirror/js/tokenizejavascript.js +0 -174
  128. data/generators/liquid_cms/templates/public/cms/codemirror/js/undo.js +0 -413
  129. data/generators/liquid_cms/templates/public/cms/codemirror/js/unittests.js +0 -44
  130. data/generators/liquid_cms/templates/public/cms/codemirror/js/util.js +0 -133
@@ -0,0 +1,52 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>CodeMirror 2: HTML mixed 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
+ <script src="../javascript/javascript.js"></script>
9
+ <script src="../css/css.js"></script>
10
+ <link rel="stylesheet" href="../../theme/default.css">
11
+ <script src="htmlmixed.js"></script>
12
+ <link rel="stylesheet" href="../../css/docs.css">
13
+ <style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
14
+ </head>
15
+ <body>
16
+ <h1>CodeMirror 2: HTML mixed mode</h1>
17
+ <form><textarea id="code" name="code">
18
+ <html style="color: green">
19
+ <!-- this is a comment -->
20
+ <head>
21
+ <title>Mixed HTML Example</title>
22
+ <style type="text/css">
23
+ h1 {font-family: comic sans; color: #f0f;}
24
+ div {background: yellow !important;}
25
+ body {
26
+ max-width: 50em;
27
+ margin: 1em 2em 1em 5em;
28
+ }
29
+ </style>
30
+ </head>
31
+ <body>
32
+ <h1>Mixed HTML Example</h1>
33
+ <script>
34
+ function jsFunc(arg1, arg2) {
35
+ if (arg1 && arg2) document.body.innerHTML = "achoo";
36
+ }
37
+ </script>
38
+ </body>
39
+ </html>
40
+ </textarea></form>
41
+ <script>
42
+ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: "text/html", tabMode: "indent"});
43
+ </script>
44
+
45
+ <p>The HTML mixed mode depends on the XML, JavaScript, and CSS modes.</p>
46
+
47
+ <p><strong>MIME types defined:</strong> <code>text/html</code>
48
+ (redefined, only takes effect if you load this parser after the
49
+ XML parser).</p>
50
+
51
+ </body>
52
+ </html>
@@ -0,0 +1,78 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>CodeMirror 2: JavaScript mode</title>
5
+ <link rel="stylesheet" href="../../lib/codemirror.css">
6
+ <script src="../../lib/codemirror.js"></script>
7
+ <script src="javascript.js"></script>
8
+ <link rel="stylesheet" href="../../theme/default.css">
9
+ <link rel="stylesheet" href="../../css/docs.css">
10
+ <style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
11
+ </head>
12
+ <body>
13
+ <h1>CodeMirror 2: JavaScript mode</h1>
14
+
15
+ <div><textarea id="code" name="code">
16
+ // Demo code (the actual new parser character stream implementation)
17
+
18
+ function StringStream(string) {
19
+ this.pos = 0;
20
+ this.string = string;
21
+ }
22
+
23
+ StringStream.prototype = {
24
+ done: function() {return this.pos >= this.string.length;},
25
+ peek: function() {return this.string.charAt(this.pos);},
26
+ next: function() {
27
+ if (this.pos &lt; this.string.length)
28
+ return this.string.charAt(this.pos++);
29
+ },
30
+ eat: function(match) {
31
+ var ch = this.string.charAt(this.pos);
32
+ if (typeof match == "string") var ok = ch == match;
33
+ else var ok = ch &amp;&amp; match.test ? match.test(ch) : match(ch);
34
+ if (ok) {this.pos++; return ch;}
35
+ },
36
+ eatWhile: function(match) {
37
+ var start = this.pos;
38
+ while (this.eat(match));
39
+ if (this.pos > start) return this.string.slice(start, this.pos);
40
+ },
41
+ backUp: function(n) {this.pos -= n;},
42
+ column: function() {return this.pos;},
43
+ eatSpace: function() {
44
+ var start = this.pos;
45
+ while (/\s/.test(this.string.charAt(this.pos))) this.pos++;
46
+ return this.pos - start;
47
+ },
48
+ match: function(pattern, consume, caseInsensitive) {
49
+ if (typeof pattern == "string") {
50
+ function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}
51
+ if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
52
+ if (consume !== false) this.pos += str.length;
53
+ return true;
54
+ }
55
+ }
56
+ else {
57
+ var match = this.string.slice(this.pos).match(pattern);
58
+ if (match &amp;&amp; consume !== false) this.pos += match[0].length;
59
+ return match;
60
+ }
61
+ }
62
+ };
63
+ </textarea></div>
64
+
65
+ <script>
66
+ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
67
+ lineNumbers: true,
68
+ matchBrackets: true
69
+ });
70
+ </script>
71
+
72
+ <p>JavaScript mode supports a single configuration
73
+ option, <code>json</code>, which will set the mode to expect JSON
74
+ data rather than a JavaScript program.</p>
75
+
76
+ <p><strong>MIME types defined:</strong> <code>text/javascript</code>, <code>application/json</code>.</p>
77
+ </body>
78
+ </html>
@@ -0,0 +1,352 @@
1
+ CodeMirror.defineMode("javascript", function(config, parserConfig) {
2
+ var indentUnit = config.indentUnit;
3
+ var jsonMode = parserConfig.json;
4
+
5
+ // Tokenizer
6
+
7
+ var keywords = function(){
8
+ function kw(type) {return {type: type, style: "keyword"};}
9
+ var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
10
+ var operator = kw("operator"), atom = {type: "atom", style: "atom"};
11
+ return {
12
+ "if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
13
+ "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
14
+ "var": kw("var"), "function": kw("function"), "catch": kw("catch"),
15
+ "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
16
+ "in": operator, "typeof": operator, "instanceof": operator,
17
+ "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom
18
+ };
19
+ }();
20
+
21
+ var isOperatorChar = /[+\-*&%=<>!?|]/;
22
+
23
+ function chain(stream, state, f) {
24
+ state.tokenize = f;
25
+ return f(stream, state);
26
+ }
27
+
28
+ function nextUntilUnescaped(stream, end) {
29
+ var escaped = false, next;
30
+ while ((next = stream.next()) != null) {
31
+ if (next == end && !escaped)
32
+ return false;
33
+ escaped = !escaped && next == "\\";
34
+ }
35
+ return escaped;
36
+ }
37
+
38
+ // Used as scratch variables to communicate multiple values without
39
+ // consing up tons of objects.
40
+ var type, content;
41
+ function ret(tp, style, cont) {
42
+ type = tp; content = cont;
43
+ return style;
44
+ }
45
+
46
+ function jsTokenBase(stream, state) {
47
+ var ch = stream.next();
48
+ if (ch == '"' || ch == "'")
49
+ return chain(stream, state, jsTokenString(ch));
50
+ else if (/[\[\]{}\(\),;\:\.]/.test(ch))
51
+ return ret(ch);
52
+ else if (ch == "0" && stream.eat(/x/i)) {
53
+ stream.eatWhile(/[\da-f]/i);
54
+ return ret("number", "number");
55
+ }
56
+ else if (/\d/.test(ch)) {
57
+ stream.match(/^\d*(?:\.\d*)?(?:e[+\-]?\d+)?/);
58
+ return ret("number", "number");
59
+ }
60
+ else if (ch == "/") {
61
+ if (stream.eat("*")) {
62
+ return chain(stream, state, jsTokenComment);
63
+ }
64
+ else if (stream.eat("/")) {
65
+ stream.skipToEnd();
66
+ return ret("comment", "comment");
67
+ }
68
+ else if (state.reAllowed) {
69
+ nextUntilUnescaped(stream, "/");
70
+ stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
71
+ return ret("regexp", "string");
72
+ }
73
+ else {
74
+ stream.eatWhile(isOperatorChar);
75
+ return ret("operator", null, stream.current());
76
+ }
77
+ }
78
+ else if (ch == "#") {
79
+ stream.skipToEnd();
80
+ return ret("error", "error");
81
+ }
82
+ else if (isOperatorChar.test(ch)) {
83
+ stream.eatWhile(isOperatorChar);
84
+ return ret("operator", null, stream.current());
85
+ }
86
+ else {
87
+ stream.eatWhile(/[\w\$_]/);
88
+ var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
89
+ return known ? ret(known.type, known.style, word) :
90
+ ret("variable", "variable", word);
91
+ }
92
+ }
93
+
94
+ function jsTokenString(quote) {
95
+ return function(stream, state) {
96
+ if (!nextUntilUnescaped(stream, quote))
97
+ state.tokenize = jsTokenBase;
98
+ return ret("string", "string");
99
+ };
100
+ }
101
+
102
+ function jsTokenComment(stream, state) {
103
+ var maybeEnd = false, ch;
104
+ while (ch = stream.next()) {
105
+ if (ch == "/" && maybeEnd) {
106
+ state.tokenize = jsTokenBase;
107
+ break;
108
+ }
109
+ maybeEnd = (ch == "*");
110
+ }
111
+ return ret("comment", "comment");
112
+ }
113
+
114
+ // Parser
115
+
116
+ var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
117
+
118
+ function JSLexical(indented, column, type, align, prev, info) {
119
+ this.indented = indented;
120
+ this.column = column;
121
+ this.type = type;
122
+ this.prev = prev;
123
+ this.info = info;
124
+ if (align != null) this.align = align;
125
+ }
126
+
127
+ function inScope(state, varname) {
128
+ for (var v = state.localVars; v; v = v.next)
129
+ if (v.name == varname) return true;
130
+ }
131
+
132
+ function parseJS(state, style, type, content, stream) {
133
+ var cc = state.cc;
134
+ // Communicate our context to the combinators.
135
+ // (Less wasteful than consing up a hundred closures on every call.)
136
+ cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
137
+
138
+ if (!state.lexical.hasOwnProperty("align"))
139
+ state.lexical.align = true;
140
+
141
+ while(true) {
142
+ var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
143
+ if (combinator(type, content)) {
144
+ while(cc.length && cc[cc.length - 1].lex)
145
+ cc.pop()();
146
+ if (cx.marked) return cx.marked;
147
+ if (type == "variable" && inScope(state, content)) return "variable-2";
148
+ return style;
149
+ }
150
+ }
151
+ }
152
+
153
+ // Combinator utils
154
+
155
+ var cx = {state: null, column: null, marked: null, cc: null};
156
+ function pass() {
157
+ for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
158
+ }
159
+ function cont() {
160
+ pass.apply(null, arguments);
161
+ return true;
162
+ }
163
+ function register(varname) {
164
+ var state = cx.state;
165
+ if (state.context) {
166
+ cx.marked = "def";
167
+ for (var v = state.localVars; v; v = v.next)
168
+ if (v.name == varname) return;
169
+ state.localVars = {name: varname, next: state.localVars};
170
+ }
171
+ }
172
+
173
+ // Combinators
174
+
175
+ var defaultVars = {name: "this", next: {name: "arguments"}};
176
+ function pushcontext() {
177
+ if (!cx.state.context) cx.state.localVars = defaultVars;
178
+ cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
179
+ }
180
+ function popcontext() {
181
+ cx.state.localVars = cx.state.context.vars;
182
+ cx.state.context = cx.state.context.prev;
183
+ }
184
+ function pushlex(type, info) {
185
+ var result = function() {
186
+ var state = cx.state;
187
+ state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info)
188
+ };
189
+ result.lex = true;
190
+ return result;
191
+ }
192
+ function poplex() {
193
+ var state = cx.state;
194
+ if (state.lexical.prev) {
195
+ if (state.lexical.type == ")")
196
+ state.indented = state.lexical.indented;
197
+ state.lexical = state.lexical.prev;
198
+ }
199
+ }
200
+ poplex.lex = true;
201
+
202
+ function expect(wanted) {
203
+ return function expecting(type) {
204
+ if (type == wanted) return cont();
205
+ else if (wanted == ";") return pass();
206
+ else return cont(arguments.callee);
207
+ };
208
+ }
209
+
210
+ function statement(type) {
211
+ if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
212
+ if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
213
+ if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
214
+ if (type == "{") return cont(pushlex("}"), block, poplex);
215
+ if (type == ";") return cont();
216
+ if (type == "function") return cont(functiondef);
217
+ if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
218
+ poplex, statement, poplex);
219
+ if (type == "variable") return cont(pushlex("stat"), maybelabel);
220
+ if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
221
+ block, poplex, poplex);
222
+ if (type == "case") return cont(expression, expect(":"));
223
+ if (type == "default") return cont(expect(":"));
224
+ if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
225
+ statement, poplex, popcontext);
226
+ return pass(pushlex("stat"), expression, expect(";"), poplex);
227
+ }
228
+ function expression(type) {
229
+ if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
230
+ if (type == "function") return cont(functiondef);
231
+ if (type == "keyword c") return cont(expression);
232
+ if (type == "(") return cont(pushlex(")"), expression, expect(")"), poplex, maybeoperator);
233
+ if (type == "operator") return cont(expression);
234
+ if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
235
+ if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
236
+ return cont();
237
+ }
238
+ function maybeoperator(type, value) {
239
+ if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
240
+ if (type == "operator") return cont(expression);
241
+ if (type == ";") return;
242
+ if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
243
+ if (type == ".") return cont(property, maybeoperator);
244
+ if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
245
+ }
246
+ function maybelabel(type) {
247
+ if (type == ":") return cont(poplex, statement);
248
+ return pass(maybeoperator, expect(";"), poplex);
249
+ }
250
+ function property(type) {
251
+ if (type == "variable") {cx.marked = "property"; return cont();}
252
+ }
253
+ function objprop(type) {
254
+ if (type == "variable") cx.marked = "property";
255
+ if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
256
+ }
257
+ function commasep(what, end) {
258
+ function proceed(type) {
259
+ if (type == ",") return cont(what, proceed);
260
+ if (type == end) return cont();
261
+ return cont(expect(end));
262
+ }
263
+ return function commaSeparated(type) {
264
+ if (type == end) return cont();
265
+ else return pass(what, proceed);
266
+ };
267
+ }
268
+ function block(type) {
269
+ if (type == "}") return cont();
270
+ return pass(statement, block);
271
+ }
272
+ function vardef1(type, value) {
273
+ if (type == "variable"){register(value); return cont(vardef2);}
274
+ return cont();
275
+ }
276
+ function vardef2(type, value) {
277
+ if (value == "=") return cont(expression, vardef2);
278
+ if (type == ",") return cont(vardef1);
279
+ }
280
+ function forspec1(type) {
281
+ if (type == "var") return cont(vardef1, forspec2);
282
+ if (type == ";") return pass(forspec2);
283
+ if (type == "variable") return cont(formaybein);
284
+ return pass(forspec2);
285
+ }
286
+ function formaybein(type, value) {
287
+ if (value == "in") return cont(expression);
288
+ return cont(maybeoperator, forspec2);
289
+ }
290
+ function forspec2(type, value) {
291
+ if (type == ";") return cont(forspec3);
292
+ if (value == "in") return cont(expression);
293
+ return cont(expression, expect(";"), forspec3);
294
+ }
295
+ function forspec3(type) {
296
+ if (type != ")") cont(expression);
297
+ }
298
+ function functiondef(type, value) {
299
+ if (type == "variable") {register(value); return cont(functiondef);}
300
+ if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
301
+ }
302
+ function funarg(type, value) {
303
+ if (type == "variable") {register(value); return cont();}
304
+ }
305
+
306
+ // Interface
307
+
308
+ return {
309
+ startState: function(basecolumn) {
310
+ return {
311
+ tokenize: jsTokenBase,
312
+ reAllowed: true,
313
+ cc: [],
314
+ lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
315
+ localVars: null,
316
+ context: null,
317
+ indented: 0
318
+ };
319
+ },
320
+
321
+ token: function(stream, state) {
322
+ if (stream.sol()) {
323
+ if (!state.lexical.hasOwnProperty("align"))
324
+ state.lexical.align = false;
325
+ state.indented = stream.indentation();
326
+ }
327
+ if (stream.eatSpace()) return null;
328
+ var style = state.tokenize(stream, state);
329
+ if (type == "comment") return style;
330
+ state.reAllowed = type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/);
331
+ return parseJS(state, style, type, content, stream);
332
+ },
333
+
334
+ indent: function(state, textAfter) {
335
+ if (state.tokenize != jsTokenBase) return 0;
336
+ var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,
337
+ type = lexical.type, closing = firstChar == type;
338
+ if (type == "vardef") return lexical.indented + 4;
339
+ else if (type == "form" && firstChar == "{") return lexical.indented;
340
+ else if (type == "stat" || type == "form") return lexical.indented + indentUnit;
341
+ else if (lexical.info == "switch" && !closing)
342
+ return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
343
+ else if (lexical.align) return lexical.column + (closing ? 0 : 1);
344
+ else return lexical.indented + (closing ? 0 : indentUnit);
345
+ },
346
+
347
+ electricChars: ":{}"
348
+ };
349
+ });
350
+
351
+ CodeMirror.defineMIME("text/javascript", "javascript");
352
+ CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
@@ -0,0 +1,38 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>CodeMirror 2: Jinja2 mode</title>
5
+ <link rel="stylesheet" href="../../lib/codemirror.css">
6
+ <script src="../../lib/codemirror.js"></script>
7
+ <script src="jinja2.js"></script>
8
+ <link rel="stylesheet" href="../../theme/default.css">
9
+ <style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
10
+ <link rel="stylesheet" href="../../css/docs.css">
11
+ </head>
12
+ <body>
13
+ <h1>CodeMirror 2: Jinja2 mode</h1>
14
+ <form><textarea id="code" name="code">
15
+ &lt;html style="color: green"&gt;
16
+ &lt;!-- this is a comment --&gt;
17
+ &lt;head&gt;
18
+ &lt;title&gt;Jinja2 Example&lt;/title&gt;
19
+ &lt;/head&gt;
20
+ &lt;body&gt;
21
+ &lt;ul&gt;
22
+ {# this is a comment #}
23
+ {%- for item in li -%}
24
+ &lt;li&gt;
25
+ {{ item.label }}
26
+ &lt;/li&gt;
27
+ {% endfor -%}
28
+ &lt;/ul&gt;
29
+ &lt;/body&gt;
30
+ &lt;/html&gt;
31
+ </textarea></form>
32
+ <script>
33
+ var editor =
34
+ CodeMirror.fromTextArea(document.getElementById("code"), {mode:
35
+ {name: "jinja2", htmlMode: true}});
36
+ </script>
37
+ </body>
38
+ </html>
@@ -0,0 +1,42 @@
1
+ CodeMirror.defineMode("jinja2", function(config, parserConf) {
2
+ var keywords = ["block", "endblock", "for", "endfor", "in", "true", "false",
3
+ "loop", "none", "self", "super", "if", "as", "not", "and",
4
+ "else", "import", "with", "without", "context"];
5
+ keywords = new RegExp("^((" + keywords.join(")|(") + "))\\b");
6
+
7
+ function tokenBase (stream, state) {
8
+ var ch = stream.next();
9
+ if (ch == "{") {
10
+ if (ch = stream.eat(/\{|%|#/)) {
11
+ stream.eat("-");
12
+ state.tokenize = inTag(ch);
13
+ return "tag";
14
+ }
15
+ }
16
+ }
17
+ function inTag (close) {
18
+ if (close == "{") {
19
+ close = "}";
20
+ }
21
+ return function (stream, state) {
22
+ var ch = stream.next();
23
+ if ((ch == close || (ch == "-" && stream.eat(close)))
24
+ && stream.eat("}")) {
25
+ state.tokenize = tokenBase;
26
+ return "tag";
27
+ }
28
+ if (stream.match(keywords)) {
29
+ return "keyword";
30
+ }
31
+ return close == "#" ? "comment" : "string";
32
+ };
33
+ }
34
+ return {
35
+ startState: function () {
36
+ return {tokenize: tokenBase};
37
+ },
38
+ token: function (stream, state) {
39
+ return state.tokenize(stream, state);
40
+ }
41
+ };
42
+ });
@@ -0,0 +1,72 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>CodeMirror 2: Lua mode</title>
5
+ <link rel="stylesheet" href="../../lib/codemirror.css">
6
+ <script src="../../lib/codemirror.js"></script>
7
+ <script src="lua.js"></script>
8
+ <link rel="stylesheet" href="../../theme/neat.css">
9
+ <style>.CodeMirror {border: 1px solid black;}</style>
10
+ <link rel="stylesheet" href="../../css/docs.css">
11
+ </head>
12
+ <body>
13
+ <h1>CodeMirror 2: Lua mode</h1>
14
+ <form><textarea id="code" name="code">
15
+ --[[
16
+ example useless code to show lua syntax highlighting
17
+ this is multiline comment
18
+ ]]
19
+
20
+ function blahblahblah(x)
21
+
22
+ local table = {
23
+ "asd" = 123,
24
+ "x" = 0.34,
25
+ }
26
+ if x ~= 3 then
27
+ print( x )
28
+ elseif x == "string"
29
+ my_custom_function( 0x34 )
30
+ else
31
+ unknown_function( "some string" )
32
+ end
33
+
34
+ --single line comment
35
+
36
+ end
37
+
38
+ function blablabla3()
39
+
40
+ for k,v in ipairs( table ) do
41
+ --abcde..
42
+ y=[=[
43
+ x=[[
44
+ x is a multi line string
45
+ ]]
46
+ but its definition is iside a highest level string!
47
+ ]=]
48
+ print(" \"\" ")
49
+
50
+ s = math.sin( x )
51
+ end
52
+
53
+ end
54
+ </textarea></form>
55
+ <script>
56
+ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
57
+ tabMode: "indent",
58
+ matchBrackets: true,
59
+ theme: "neat"
60
+ });
61
+ </script>
62
+
63
+ <p>Loosely based on Franciszek
64
+ Wawrzak's <a href="http://codemirror.net/1/contrib/lua">CodeMirror
65
+ 1 mode</a>. One configuration parameter is
66
+ supported, <code>specials</code>, to which you can provide an
67
+ array of strings to have those identifiers highlighted with
68
+ the <code>lua-special</code> style.</p>
69
+ <p><strong>MIME types defined:</strong> <code>text/x-lua</code>.</p>
70
+
71
+ </body>
72
+ </html>