liquid_cms 0.2.1.1 → 0.2.2.0

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 (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,85 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>CodeMirror 2: Clojure mode</title>
5
+ <link rel="stylesheet" href="../../lib/codemirror.css">
6
+ <script src="../../lib/codemirror.js"></script>
7
+ <script src="clojure.js"></script>
8
+ <link rel="stylesheet" href="../../theme/default.css">
9
+ <style>.CodeMirror {background: #f8f8f8;}</style>
10
+ <link rel="stylesheet" href="../../css/docs.css">
11
+ </head>
12
+ <body>
13
+ <h1>CodeMirror 2: Clojure mode</h1>
14
+ <form><textarea id="code" name="code">
15
+ ; Conway's Game of Life, from http://rosettacode.org/wiki/Conway%27s_Game_of_Life#Clojure
16
+ (defstruct grid :w :h :cells)
17
+
18
+ (defn get-cell
19
+ "Returns the value at x,y. The grid is treated as a torus, such that both x and
20
+ y coordinates will wrap around if greater than width and height respectively."
21
+ [grid x y]
22
+ (let [x (mod x (:w grid))
23
+ y (mod y (:h grid))]
24
+ (-> grid :cells (nth y) (nth x))))
25
+
26
+ (defn neighbors
27
+ "Returns a lazy sequence of all neighbors of the specified cell."
28
+ [grid x y]
29
+ (for [j [(dec y) y (inc y)]
30
+ i [(dec x) x (inc x)]
31
+ :when (not (and (= i x) (= j y)))]
32
+ (get-cell grid i j)))
33
+
34
+ (defn evolve-cell
35
+ "Returns the new state of the specifed cell."
36
+ [grid x y]
37
+ (let [c (get-cell grid x y)
38
+ n (reduce + (neighbors grid x y))]
39
+ (if (or (and (zero? c) (= 3 n))
40
+ (and (= 1 c) (or (= 2 n) (= 3 n))))
41
+ 1 0)))
42
+
43
+ (defn evolve-grid
44
+ "Returns a new grid whose cells have all been evolved."
45
+ [grid]
46
+ (assoc grid :cells
47
+ (vec (for [y (range (:h grid))]
48
+ (vec (for [x (range (:w grid))]
49
+ (evolve-cell grid x y)))))))
50
+
51
+ (defn generations [grid]
52
+ "Returns a lazy sequence of the grid, and all subsequent generations."
53
+ (iterate evolve-grid grid))
54
+
55
+ (defn make-grid [w h & row-patterns]
56
+ (let [cells (vec (for [rp row-patterns]
57
+ (vec (mapcat #(take %1 (repeat %2)) rp (cycle [0 1])))))]
58
+ (if (and (= h (count cells))
59
+ (every? #(= w (count %)) cells))
60
+ (struct grid w h cells)
61
+ (throw (IllegalArgumentException. "Resulting cells do not match expected width/height.")))))
62
+
63
+ (defn display-row [row]
64
+ (do (dorun (map print (map #(if (zero? %) " . " "[X]") row))) (println)))
65
+
66
+ (defn display-grid [grid]
67
+ (dorun (map display-row (:cells grid))))
68
+
69
+ (defn display-grids [grids]
70
+ (dorun
71
+ (interleave
72
+ (repeatedly println)
73
+ (map display-grid grids))))
74
+
75
+ (def blinker (make-grid 5 5 [5] [5] [1 3 1] [5] [5]))
76
+ (display-grids (take 3 (generations blinker)))
77
+ </textarea></form>
78
+ <script>
79
+ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
80
+ </script>
81
+
82
+ <p><strong>MIME types defined:</strong> <code>text/x-clojure</code>.</p>
83
+
84
+ </body>
85
+ </html>
@@ -0,0 +1,22 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2011 Jeff Pickhardt
4
+ Modified from the Python CodeMirror mode, Copyright (c) 2010 Timothy Farrell
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
@@ -0,0 +1,325 @@
1
+ /**
2
+ * Link to the project's GitHub page:
3
+ * https://github.com/pickhardt/coffeescript-codemirror-mode
4
+ */
5
+ CodeMirror.defineMode('coffeescript', function(conf) {
6
+ var ERRORCLASS = 'error';
7
+
8
+ function wordRegexp(words) {
9
+ return new RegExp("^((" + words.join(")|(") + "))\\b");
10
+ }
11
+
12
+ var singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!\?]");
13
+ var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]');
14
+ var doubleOperators = new RegExp("^((\->)|(\=>)|(\\+\\+)|(\\+\\=)|(\\-\\-)|(\\-\\=)|(\\*\\*)|(\\*\\=)|(\\/\\/)|(\\/\\=)|(==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//))");
15
+ var doubleDelimiters = new RegExp("^((\\.\\.)|(\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
16
+ var tripleDelimiters = new RegExp("^((\\.\\.\\.)|(//=)|(>>=)|(<<=)|(\\*\\*=))");
17
+ var identifiers = new RegExp("^[_A-Za-z][_A-Za-z0-9]*");
18
+
19
+ var wordOperators = wordRegexp(['and', 'or', 'not',
20
+ 'is', 'isnt', 'in',
21
+ 'instanceof', 'typeof']);
22
+ var indentKeywords = ['for', 'while', 'loop', 'if', 'unless', 'else',
23
+ 'switch', 'try', 'catch', 'finally', 'class'];
24
+ var commonKeywords = ['break', 'by', 'continue', 'debugger', 'delete',
25
+ 'do', 'in', 'of', 'new', 'return', 'then',
26
+ 'this', 'throw', 'when', 'until'];
27
+
28
+ var keywords = wordRegexp(indentKeywords.concat(commonKeywords));
29
+
30
+ indentKeywords = wordRegexp(indentKeywords);
31
+
32
+
33
+ var stringPrefixes = new RegExp("^('{3}|\"{3}|['\"])");
34
+ var regexPrefixes = new RegExp("^(/{3}|/)");
35
+ var commonConstants = ['Infinity', 'NaN', 'undefined', 'null', 'true', 'false', 'on', 'off', 'yes', 'no'];
36
+ var constants = wordRegexp(commonConstants);
37
+
38
+ // Tokenizers
39
+ function tokenBase(stream, state) {
40
+ // Handle scope changes
41
+ if (stream.sol()) {
42
+ var scopeOffset = state.scopes[0].offset;
43
+ if (stream.eatSpace()) {
44
+ var lineOffset = stream.indentation();
45
+ if (lineOffset > scopeOffset) {
46
+ return 'indent';
47
+ } else if (lineOffset < scopeOffset) {
48
+ return 'dedent';
49
+ }
50
+ return null;
51
+ } else {
52
+ if (scopeOffset > 0) {
53
+ dedent(stream, state);
54
+ }
55
+ }
56
+ }
57
+ if (stream.eatSpace()) {
58
+ return null;
59
+ }
60
+
61
+ var ch = stream.peek();
62
+
63
+ // Handle comments
64
+ if (ch === '#') {
65
+ stream.skipToEnd();
66
+ return 'comment';
67
+ }
68
+
69
+ // Handle number literals
70
+ if (stream.match(/^-?[0-9\.]/, false)) {
71
+ var floatLiteral = false;
72
+ // Floats
73
+ if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
74
+ floatLiteral = true;
75
+ }
76
+ if (stream.match(/^-?\d+\.\d*/)) {
77
+ floatLiteral = true;
78
+ }
79
+ if (stream.match(/^-?\.\d+/)) {
80
+ floatLiteral = true;
81
+ }
82
+ if (floatLiteral) {
83
+ return 'number';
84
+ }
85
+ // Integers
86
+ var intLiteral = false;
87
+ // Hex
88
+ if (stream.match(/^-?0x[0-9a-f]+/i)) {
89
+ intLiteral = true;
90
+ }
91
+ // Decimal
92
+ if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
93
+ intLiteral = true;
94
+ }
95
+ // Zero by itself with no other piece of number.
96
+ if (stream.match(/^-?0(?![\dx])/i)) {
97
+ intLiteral = true;
98
+ }
99
+ if (intLiteral) {
100
+ return 'number';
101
+ }
102
+ }
103
+
104
+ // Handle strings
105
+ if (stream.match(stringPrefixes)) {
106
+ state.tokenize = tokenFactory(stream.current(), 'string');
107
+ return state.tokenize(stream, state);
108
+ }
109
+ // Handle regex literals
110
+ if (stream.match(regexPrefixes)) {
111
+ if (stream.current() != '/' || stream.match(/^.*\//, false)) { // prevent highlight of division
112
+ state.tokenize = tokenFactory(stream.current(), 'string-2');
113
+ return state.tokenize(stream, state);
114
+ } else {
115
+ stream.backUp(1);
116
+ }
117
+ }
118
+
119
+ // Handle operators and delimiters
120
+ if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) {
121
+ return 'punctuation';
122
+ }
123
+ if (stream.match(doubleOperators)
124
+ || stream.match(singleOperators)
125
+ || stream.match(wordOperators)) {
126
+ return 'operator';
127
+ }
128
+ if (stream.match(singleDelimiters)) {
129
+ return 'punctuation';
130
+ }
131
+
132
+ if (stream.match(constants)) {
133
+ return 'atom';
134
+ }
135
+
136
+ if (stream.match(keywords)) {
137
+ return 'keyword';
138
+ }
139
+
140
+ if (stream.match(identifiers)) {
141
+ return 'variable';
142
+ }
143
+
144
+ // Handle non-detected items
145
+ stream.next();
146
+ return ERRORCLASS;
147
+ }
148
+
149
+ function tokenFactory(delimiter, outclass) {
150
+ var delim_re = new RegExp(delimiter);
151
+ var singleline = delimiter.length == 1;
152
+
153
+ return function tokenString(stream, state) {
154
+ while (!stream.eol()) {
155
+ stream.eatWhile(/[^'"\/\\]/);
156
+ if (stream.eat('\\')) {
157
+ stream.next();
158
+ if (singleline && stream.eol()) {
159
+ return outclass;
160
+ }
161
+ } else if (stream.match(delim_re)) {
162
+ state.tokenize = tokenBase;
163
+ return outclass;
164
+ } else {
165
+ stream.eat(/['"\/]/);
166
+ }
167
+ }
168
+ if (singleline) {
169
+ if (conf.mode.singleLineStringErrors) {
170
+ outclass = ERRORCLASS
171
+ } else {
172
+ state.tokenize = tokenBase;
173
+ }
174
+ }
175
+ return outclass;
176
+ };
177
+ }
178
+
179
+ function indent(stream, state, type) {
180
+ type = type || 'coffee';
181
+ var indentUnit = 0;
182
+ if (type === 'coffee') {
183
+ for (var i = 0; i < state.scopes.length; i++) {
184
+ if (state.scopes[i].type === 'coffee') {
185
+ indentUnit = state.scopes[i].offset + conf.indentUnit;
186
+ break;
187
+ }
188
+ }
189
+ } else {
190
+ indentUnit = stream.column() + stream.current().length;
191
+ }
192
+ state.scopes.unshift({
193
+ offset: indentUnit,
194
+ type: type
195
+ });
196
+ }
197
+
198
+ function dedent(stream, state) {
199
+ if (state.scopes.length == 1) return;
200
+ if (state.scopes[0].type === 'coffee') {
201
+ var _indent = stream.indentation();
202
+ var _indent_index = -1;
203
+ for (var i = 0; i < state.scopes.length; ++i) {
204
+ if (_indent === state.scopes[i].offset) {
205
+ _indent_index = i;
206
+ break;
207
+ }
208
+ }
209
+ if (_indent_index === -1) {
210
+ return true;
211
+ }
212
+ while (state.scopes[0].offset !== _indent) {
213
+ state.scopes.shift();
214
+ }
215
+ return false
216
+ } else {
217
+ state.scopes.shift();
218
+ return false;
219
+ }
220
+ }
221
+
222
+ function tokenLexer(stream, state) {
223
+ var style = state.tokenize(stream, state);
224
+ var current = stream.current();
225
+
226
+ // Handle '.' connected identifiers
227
+ if (current === '.') {
228
+ style = state.tokenize(stream, state);
229
+ current = stream.current();
230
+ if (style === 'variable') {
231
+ return 'variable';
232
+ } else {
233
+ return ERRORCLASS;
234
+ }
235
+ }
236
+
237
+ // Handle properties
238
+ if (current === '@') {
239
+ style = state.tokenize(stream, state);
240
+ current = stream.current();
241
+ if (style === 'variable') {
242
+ return 'variable-2';
243
+ } else {
244
+ return ERRORCLASS;
245
+ }
246
+ }
247
+
248
+ // Handle scope changes.
249
+ if (current === 'return') {
250
+ state.dedent += 1;
251
+ }
252
+ if (((current === '->' || current === '=>') &&
253
+ !state.lambda &&
254
+ state.scopes[0].type == 'coffee' &&
255
+ stream.peek() === '')
256
+ || style === 'indent') {
257
+ indent(stream, state);
258
+ }
259
+ var delimiter_index = '[({'.indexOf(current);
260
+ if (delimiter_index !== -1) {
261
+ indent(stream, state, '])}'.slice(delimiter_index, delimiter_index+1));
262
+ }
263
+ if (indentKeywords.exec(current)){
264
+ indent(stream, state);
265
+ }
266
+ if (current == 'then'){
267
+ dedent(stream, state);
268
+ }
269
+
270
+
271
+ if (style === 'dedent') {
272
+ if (dedent(stream, state)) {
273
+ return ERRORCLASS;
274
+ }
275
+ }
276
+ delimiter_index = '])}'.indexOf(current);
277
+ if (delimiter_index !== -1) {
278
+ if (dedent(stream, state)) {
279
+ return ERRORCLASS;
280
+ }
281
+ }
282
+ if (state.dedent > 0 && stream.eol() && state.scopes[0].type == 'coffee') {
283
+ if (state.scopes.length > 1) state.scopes.shift();
284
+ state.dedent -= 1;
285
+ }
286
+
287
+ return style;
288
+ }
289
+
290
+ var external = {
291
+ startState: function(basecolumn) {
292
+ return {
293
+ tokenize: tokenBase,
294
+ scopes: [{offset:basecolumn || 0, type:'coffee'}],
295
+ lastToken: null,
296
+ lambda: false,
297
+ dedent: 0
298
+ };
299
+ },
300
+
301
+ token: function(stream, state) {
302
+ var style = tokenLexer(stream, state);
303
+
304
+ state.lastToken = {style:style, content: stream.current()};
305
+
306
+ if (stream.eol() && stream.lambda) {
307
+ state.lambda = false;
308
+ }
309
+
310
+ return style;
311
+ },
312
+
313
+ indent: function(state, textAfter) {
314
+ if (state.tokenize != tokenBase) {
315
+ return 0;
316
+ }
317
+
318
+ return state.scopes[0].offset;
319
+ }
320
+
321
+ };
322
+ return external;
323
+ });
324
+
325
+ CodeMirror.defineMIME('text/x-coffeescript', 'coffeescript');