ledger_web 1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. data/.gitignore +10 -0
  2. data/LICENSE +7 -0
  3. data/README.md +140 -0
  4. data/Rakefile +11 -0
  5. data/bin/ledger_web +14 -0
  6. data/ledger_web.gemspec +26 -0
  7. data/lib/ledger_web/app.rb +69 -0
  8. data/lib/ledger_web/config.rb +87 -0
  9. data/lib/ledger_web/db/migrate/20111226180900_initial_schema.rb +38 -0
  10. data/lib/ledger_web/db/migrate/20111231132900_add_views.rb +37 -0
  11. data/lib/ledger_web/db.rb +54 -0
  12. data/lib/ledger_web/helpers.rb +62 -0
  13. data/lib/ledger_web/public/bootstrap-dropdown.js +55 -0
  14. data/lib/ledger_web/public/bootstrap.min.css +356 -0
  15. data/lib/ledger_web/public/codemirror/keymap/emacs.js +29 -0
  16. data/lib/ledger_web/public/codemirror/keymap/vim.js +76 -0
  17. data/lib/ledger_web/public/codemirror/lib/codemirror.css +104 -0
  18. data/lib/ledger_web/public/codemirror/lib/codemirror.js +2761 -0
  19. data/lib/ledger_web/public/codemirror/lib/util/dialog.css +23 -0
  20. data/lib/ledger_web/public/codemirror/lib/util/dialog.js +63 -0
  21. data/lib/ledger_web/public/codemirror/lib/util/foldcode.js +66 -0
  22. data/lib/ledger_web/public/codemirror/lib/util/formatting.js +291 -0
  23. data/lib/ledger_web/public/codemirror/lib/util/javascript-hint.js +83 -0
  24. data/lib/ledger_web/public/codemirror/lib/util/overlay.js +51 -0
  25. data/lib/ledger_web/public/codemirror/lib/util/runmode.js +27 -0
  26. data/lib/ledger_web/public/codemirror/lib/util/search.js +114 -0
  27. data/lib/ledger_web/public/codemirror/lib/util/searchcursor.js +117 -0
  28. data/lib/ledger_web/public/codemirror/lib/util/simple-hint.css +16 -0
  29. data/lib/ledger_web/public/codemirror/lib/util/simple-hint.js +66 -0
  30. data/lib/ledger_web/public/codemirror/mode/clike/clike.js +249 -0
  31. data/lib/ledger_web/public/codemirror/mode/clike/index.html +101 -0
  32. data/lib/ledger_web/public/codemirror/mode/clojure/clojure.js +207 -0
  33. data/lib/ledger_web/public/codemirror/mode/clojure/index.html +66 -0
  34. data/lib/ledger_web/public/codemirror/mode/coffeescript/LICENSE +22 -0
  35. data/lib/ledger_web/public/codemirror/mode/coffeescript/coffeescript.js +325 -0
  36. data/lib/ledger_web/public/codemirror/mode/coffeescript/index.html +721 -0
  37. data/lib/ledger_web/public/codemirror/mode/css/css.js +124 -0
  38. data/lib/ledger_web/public/codemirror/mode/css/index.html +55 -0
  39. data/lib/ledger_web/public/codemirror/mode/diff/diff.css +3 -0
  40. data/lib/ledger_web/public/codemirror/mode/diff/diff.js +13 -0
  41. data/lib/ledger_web/public/codemirror/mode/diff/index.html +99 -0
  42. data/lib/ledger_web/public/codemirror/mode/gfm/gfm.js +108 -0
  43. data/lib/ledger_web/public/codemirror/mode/gfm/index.html +47 -0
  44. data/lib/ledger_web/public/codemirror/mode/groovy/groovy.js +210 -0
  45. data/lib/ledger_web/public/codemirror/mode/groovy/index.html +71 -0
  46. data/lib/ledger_web/public/codemirror/mode/haskell/haskell.js +242 -0
  47. data/lib/ledger_web/public/codemirror/mode/haskell/index.html +60 -0
  48. data/lib/ledger_web/public/codemirror/mode/htmlembedded/htmlembedded.js +68 -0
  49. data/lib/ledger_web/public/codemirror/mode/htmlembedded/index.html +49 -0
  50. data/lib/ledger_web/public/codemirror/mode/htmlmixed/htmlmixed.js +83 -0
  51. data/lib/ledger_web/public/codemirror/mode/htmlmixed/index.html +51 -0
  52. data/lib/ledger_web/public/codemirror/mode/javascript/index.html +77 -0
  53. data/lib/ledger_web/public/codemirror/mode/javascript/javascript.js +360 -0
  54. data/lib/ledger_web/public/codemirror/mode/jinja2/index.html +37 -0
  55. data/lib/ledger_web/public/codemirror/mode/jinja2/jinja2.js +42 -0
  56. data/lib/ledger_web/public/codemirror/mode/lua/index.html +72 -0
  57. data/lib/ledger_web/public/codemirror/mode/lua/lua.js +140 -0
  58. data/lib/ledger_web/public/codemirror/mode/markdown/index.html +339 -0
  59. data/lib/ledger_web/public/codemirror/mode/markdown/markdown.js +242 -0
  60. data/lib/ledger_web/public/codemirror/mode/ntriples/index.html +32 -0
  61. data/lib/ledger_web/public/codemirror/mode/ntriples/ntriples.js +172 -0
  62. data/lib/ledger_web/public/codemirror/mode/pascal/LICENSE +7 -0
  63. data/lib/ledger_web/public/codemirror/mode/pascal/index.html +48 -0
  64. data/lib/ledger_web/public/codemirror/mode/pascal/pascal.js +138 -0
  65. data/lib/ledger_web/public/codemirror/mode/perl/LICENSE +19 -0
  66. data/lib/ledger_web/public/codemirror/mode/perl/index.html +62 -0
  67. data/lib/ledger_web/public/codemirror/mode/perl/perl.js +816 -0
  68. data/lib/ledger_web/public/codemirror/mode/php/index.html +48 -0
  69. data/lib/ledger_web/public/codemirror/mode/php/php.js +120 -0
  70. data/lib/ledger_web/public/codemirror/mode/plsql/index.html +62 -0
  71. data/lib/ledger_web/public/codemirror/mode/plsql/plsql.js +217 -0
  72. data/lib/ledger_web/public/codemirror/mode/python/LICENSE.txt +21 -0
  73. data/lib/ledger_web/public/codemirror/mode/python/index.html +122 -0
  74. data/lib/ledger_web/public/codemirror/mode/python/python.js +333 -0
  75. data/lib/ledger_web/public/codemirror/mode/r/LICENSE +24 -0
  76. data/lib/ledger_web/public/codemirror/mode/r/index.html +73 -0
  77. data/lib/ledger_web/public/codemirror/mode/r/r.js +141 -0
  78. data/lib/ledger_web/public/codemirror/mode/rpm/changes/changes.js +19 -0
  79. data/lib/ledger_web/public/codemirror/mode/rpm/changes/index.html +53 -0
  80. data/lib/ledger_web/public/codemirror/mode/rpm/spec/index.html +99 -0
  81. data/lib/ledger_web/public/codemirror/mode/rpm/spec/spec.css +5 -0
  82. data/lib/ledger_web/public/codemirror/mode/rpm/spec/spec.js +66 -0
  83. data/lib/ledger_web/public/codemirror/mode/rst/index.html +525 -0
  84. data/lib/ledger_web/public/codemirror/mode/rst/rst.js +326 -0
  85. data/lib/ledger_web/public/codemirror/mode/ruby/LICENSE +24 -0
  86. data/lib/ledger_web/public/codemirror/mode/ruby/index.html +171 -0
  87. data/lib/ledger_web/public/codemirror/mode/ruby/ruby.js +195 -0
  88. data/lib/ledger_web/public/codemirror/mode/rust/index.html +48 -0
  89. data/lib/ledger_web/public/codemirror/mode/rust/rust.js +411 -0
  90. data/lib/ledger_web/public/codemirror/mode/scheme/index.html +64 -0
  91. data/lib/ledger_web/public/codemirror/mode/scheme/scheme.js +202 -0
  92. data/lib/ledger_web/public/codemirror/mode/smalltalk/index.html +55 -0
  93. data/lib/ledger_web/public/codemirror/mode/smalltalk/smalltalk.js +139 -0
  94. data/lib/ledger_web/public/codemirror/mode/sparql/index.html +40 -0
  95. data/lib/ledger_web/public/codemirror/mode/sparql/sparql.js +143 -0
  96. data/lib/ledger_web/public/codemirror/mode/stex/index.html +95 -0
  97. data/lib/ledger_web/public/codemirror/mode/stex/stex.js +167 -0
  98. data/lib/ledger_web/public/codemirror/mode/tiddlywiki/index.html +183 -0
  99. data/lib/ledger_web/public/codemirror/mode/tiddlywiki/tiddlywiki.css +21 -0
  100. data/lib/ledger_web/public/codemirror/mode/tiddlywiki/tiddlywiki.js +374 -0
  101. data/lib/ledger_web/public/codemirror/mode/velocity/index.html +103 -0
  102. data/lib/ledger_web/public/codemirror/mode/velocity/velocity.js +146 -0
  103. data/lib/ledger_web/public/codemirror/mode/xml/index.html +44 -0
  104. data/lib/ledger_web/public/codemirror/mode/xml/xml.js +252 -0
  105. data/lib/ledger_web/public/codemirror/mode/xmlpure/index.html +59 -0
  106. data/lib/ledger_web/public/codemirror/mode/xmlpure/xmlpure.js +485 -0
  107. data/lib/ledger_web/public/codemirror/mode/yaml/index.html +67 -0
  108. data/lib/ledger_web/public/codemirror/mode/yaml/yaml.js +95 -0
  109. data/lib/ledger_web/public/codemirror/theme/cobalt.css +18 -0
  110. data/lib/ledger_web/public/codemirror/theme/eclipse.css +25 -0
  111. data/lib/ledger_web/public/codemirror/theme/elegant.css +10 -0
  112. data/lib/ledger_web/public/codemirror/theme/monokai.css +28 -0
  113. data/lib/ledger_web/public/codemirror/theme/neat.css +9 -0
  114. data/lib/ledger_web/public/codemirror/theme/night.css +21 -0
  115. data/lib/ledger_web/public/codemirror/theme/rubyblue.css +21 -0
  116. data/lib/ledger_web/public/jquery-1.7.1.min.js +4 -0
  117. data/lib/ledger_web/public/jquery.tablesorter.min.js +4 -0
  118. data/lib/ledger_web/public/ledger.css +14 -0
  119. data/lib/ledger_web/report.rb +187 -0
  120. data/lib/ledger_web/reports/savings_rate.erb +49 -0
  121. data/lib/ledger_web/version.rb +3 -0
  122. data/lib/ledger_web/views/error.erb +5 -0
  123. data/lib/ledger_web/views/help.erb +6 -0
  124. data/lib/ledger_web/views/layout.erb +44 -0
  125. data/lib/ledger_web/views/table.erb +31 -0
  126. data/lib/ledger_web/watcher.rb +37 -0
  127. data/lib/ledger_web.rb +20 -0
  128. metadata +229 -0
@@ -0,0 +1,374 @@
1
+ /***
2
+ |''Name''|tiddlywiki.js|
3
+ |''Description''|Enables TiddlyWikiy syntax highlighting using CodeMirror2|
4
+ |''Author''|PMario|
5
+ |''Version''|0.1.6|
6
+ |''Status''|''beta''|
7
+ |''Source''|[[GitHub|https://github.com/pmario/CodeMirror2/blob/tw-syntax/mode/tiddlywiki]]|
8
+ |''Documentation''|http://codemirror.tiddlyspace.com/|
9
+ |''License''|[[MIT License|http://www.opensource.org/licenses/mit-license.php]]|
10
+ |''CoreVersion''|2.5.0|
11
+ |''Requires''|codemirror.js|
12
+ |''Keywords''|syntax highlighting color code mirror codemirror|
13
+ ! Info
14
+ CoreVersion parameter is needed for TiddlyWiki only!
15
+ ***/
16
+ //{{{
17
+ CodeMirror.defineMode("tiddlywiki", function (config, parserConfig) {
18
+ var indentUnit = config.indentUnit;
19
+
20
+ // Tokenizer
21
+ var textwords = function () {
22
+ function kw(type) {
23
+ return {
24
+ type: type,
25
+ style: "text"
26
+ };
27
+ }
28
+ return {};
29
+ }();
30
+
31
+ var keywords = function () {
32
+ function kw(type) {
33
+ return { type: type, style: "macro"};
34
+ }
35
+ return {
36
+ "allTags": kw('allTags'), "closeAll": kw('closeAll'), "list": kw('list'),
37
+ "newJournal": kw('newJournal'), "newTiddler": kw('newTiddler'),
38
+ "permaview": kw('permaview'), "saveChanges": kw('saveChanges'),
39
+ "search": kw('search'), "slider": kw('slider'), "tabs": kw('tabs'),
40
+ "tag": kw('tag'), "tagging": kw('tagging'), "tags": kw('tags'),
41
+ "tiddler": kw('tiddler'), "timeline": kw('timeline'),
42
+ "today": kw('today'), "version": kw('version'), "option": kw('option'),
43
+
44
+ "with": kw('with'),
45
+ "filter": kw('filter')
46
+ };
47
+ }();
48
+
49
+ var isSpaceName = /[\w_\-]/i,
50
+ reHR = /^\-\-\-\-+$/,
51
+ reWikiCommentStart = /^\/\*\*\*$/, // /***
52
+ reWikiCommentStop = /^\*\*\*\/$/, // ***/
53
+ reBlockQuote = /^<<<$/,
54
+
55
+ reJsCodeStart = /^\/\/\{\{\{$/, // //{{{
56
+ reJsCodeStop = /^\/\/\}\}\}$/, // //}}}
57
+ reXmlCodeStart = /^<!--\{\{\{-->$/,
58
+ reXmlCodeStop = /^<!--\}\}\}-->$/,
59
+
60
+ reCodeBlockStart = /^\{\{\{$/,
61
+ reCodeBlockStop = /^\}\}\}$/,
62
+
63
+ reCodeStart = /\{\{\{/,
64
+ reUntilCodeStop = /.*?\}\}\}/;
65
+
66
+ function chain(stream, state, f) {
67
+ state.tokenize = f;
68
+ return f(stream, state);
69
+ }
70
+
71
+ // used for strings
72
+ function nextUntilUnescaped(stream, end) {
73
+ var escaped = false,
74
+ next;
75
+ while ((next = stream.next()) != null) {
76
+ if (next == end && !escaped) return false;
77
+ escaped = !escaped && next == "\\";
78
+ }
79
+ return escaped;
80
+ }
81
+
82
+ // Used as scratch variables to communicate multiple values without
83
+ // consing up tons of objects.
84
+ var type, content;
85
+
86
+ function ret(tp, style, cont) {
87
+ type = tp;
88
+ content = cont;
89
+ return style;
90
+ }
91
+
92
+ function jsTokenBase(stream, state) {
93
+ var sol = stream.sol(),
94
+ ch, tch;
95
+
96
+ state.block = false; // indicates the start of a code block.
97
+
98
+ ch = stream.peek(); // don't eat, to make match simpler
99
+
100
+ // check start of blocks
101
+ if (sol && /[<\/\*{}\-]/.test(ch)) {
102
+ if (stream.match(reCodeBlockStart)) {
103
+ state.block = true;
104
+ return chain(stream, state, twTokenCode);
105
+ }
106
+ if (stream.match(reBlockQuote)) {
107
+ return ret('quote', 'quote');
108
+ }
109
+ if (stream.match(reWikiCommentStart) || stream.match(reWikiCommentStop)) {
110
+ return ret('code', 'code');
111
+ }
112
+ if (stream.match(reJsCodeStart) || stream.match(reJsCodeStop) || stream.match(reXmlCodeStart) || stream.match(reXmlCodeStop)) {
113
+ return ret('code', 'code');
114
+ }
115
+ if (stream.match(reHR)) {
116
+ return ret('hr', 'hr');
117
+ }
118
+ } // sol
119
+ var ch = stream.next();
120
+
121
+ if (sol && /[\/\*!#;:>|]/.test(ch)) {
122
+ if (ch == "!") { // tw header
123
+ stream.skipToEnd();
124
+ return ret("header", "header");
125
+ }
126
+ if (ch == "*") { // tw list
127
+ stream.eatWhile('*');
128
+ return ret("list", "list");
129
+ }
130
+ if (ch == "#") { // tw numbered list
131
+ stream.eatWhile('#');
132
+ return ret("list", "list");
133
+ }
134
+ if (ch == ";") { // tw list
135
+ stream.eatWhile(';');
136
+ return ret("list", "list");
137
+ }
138
+ if (ch == ":") { // tw list
139
+ stream.eatWhile(':');
140
+ return ret("list", "list");
141
+ }
142
+ if (ch == ">") { // single line quote
143
+ stream.eatWhile(">");
144
+ return ret("quote", "quote");
145
+ }
146
+ if (ch == '|') {
147
+ return ret('table', 'table');
148
+ }
149
+ }
150
+
151
+ if (ch == '{' && stream.match(/\{\{/)) {
152
+ return chain(stream, state, twTokenCode);
153
+ }
154
+
155
+ // rudimentary html:// file:// link matching. TW knows much more ...
156
+ if (/[hf]/i.test(ch)) {
157
+ if (/[ti]/i.test(stream.peek()) && stream.match(/\b(ttps?|tp|ile):\/\/[\-A-Z0-9+&@#\/%?=~_|$!:,.;]*[A-Z0-9+&@#\/%=~_|$]/i)) {
158
+ return ret("link-external", "link-external");
159
+ }
160
+ }
161
+ // just a little string indicator, don't want to have the whole string covered
162
+ if (ch == '"') {
163
+ return ret('string', 'string');
164
+ }
165
+ if (/[\[\]]/.test(ch)) { // check for [[..]]
166
+ if (stream.peek() == ch) {
167
+ stream.next();
168
+ return ret('brace', 'brace');
169
+ }
170
+ }
171
+ if (ch == "@") { // check for space link. TODO fix @@...@@ highlighting
172
+ stream.eatWhile(isSpaceName);
173
+ return ret("link-external", "link-external");
174
+ }
175
+ if (/\d/.test(ch)) { // numbers
176
+ stream.eatWhile(/\d/);
177
+ return ret("number", "number");
178
+ }
179
+ if (ch == "/") { // tw invisible comment
180
+ if (stream.eat("%")) {
181
+ return chain(stream, state, twTokenComment);
182
+ }
183
+ else if (stream.eat("/")) { //
184
+ return chain(stream, state, twTokenEm);
185
+ }
186
+ }
187
+ if (ch == "_") { // tw underline
188
+ if (stream.eat("_")) {
189
+ return chain(stream, state, twTokenUnderline);
190
+ }
191
+ }
192
+ if (ch == "-") { // tw strikethrough TODO looks ugly .. different handling see below;
193
+ if (stream.eat("-")) {
194
+ return chain(stream, state, twTokenStrike);
195
+ }
196
+ }
197
+ if (ch == "'") { // tw bold
198
+ if (stream.eat("'")) {
199
+ return chain(stream, state, twTokenStrong);
200
+ }
201
+ }
202
+ if (ch == "<") { // tw macro
203
+ if (stream.eat("<")) {
204
+ return chain(stream, state, twTokenMacro);
205
+ }
206
+ }
207
+ else {
208
+ return ret(ch);
209
+ }
210
+
211
+ stream.eatWhile(/[\w\$_]/);
212
+ var word = stream.current(),
213
+ known = textwords.propertyIsEnumerable(word) && textwords[word];
214
+
215
+ return known ? ret(known.type, known.style, word) : ret("text", null, word);
216
+
217
+ } // jsTokenBase()
218
+
219
+ function twTokenString(quote) {
220
+ return function (stream, state) {
221
+ if (!nextUntilUnescaped(stream, quote)) state.tokenize = jsTokenBase;
222
+ return ret("string", "string");
223
+ };
224
+ }
225
+
226
+ // tw invisible comment
227
+ function twTokenComment(stream, state) {
228
+ var maybeEnd = false,
229
+ ch;
230
+ while (ch = stream.next()) {
231
+ if (ch == "/" && maybeEnd) {
232
+ state.tokenize = jsTokenBase;
233
+ break;
234
+ }
235
+ maybeEnd = (ch == "%");
236
+ }
237
+ return ret("comment", "comment");
238
+ }
239
+
240
+ // tw strong / bold
241
+ function twTokenStrong(stream, state) {
242
+ var maybeEnd = false,
243
+ ch;
244
+ while (ch = stream.next()) {
245
+ if (ch == "'" && maybeEnd) {
246
+ state.tokenize = jsTokenBase;
247
+ break;
248
+ }
249
+ maybeEnd = (ch == "'");
250
+ }
251
+ return ret("text", "strong");
252
+ }
253
+
254
+ // tw code
255
+ function twTokenCode(stream, state) {
256
+ var ch, sb = state.block;
257
+
258
+ if (sb && stream.current()) {
259
+ return ret("code", "code");
260
+ }
261
+
262
+ if (!sb && stream.match(reUntilCodeStop)) {
263
+ state.tokenize = jsTokenBase;
264
+ return ret("code", "code-inline");
265
+ }
266
+
267
+ if (sb && stream.sol() && stream.match(reCodeBlockStop)) {
268
+ state.tokenize = jsTokenBase;
269
+ return ret("code", "code");
270
+ }
271
+
272
+ ch = stream.next();
273
+ return (sb) ? ret("code", "code") : ret("code", "code-inline");
274
+ }
275
+
276
+ // tw em / italic
277
+ function twTokenEm(stream, state) {
278
+ var maybeEnd = false,
279
+ ch;
280
+ while (ch = stream.next()) {
281
+ if (ch == "/" && maybeEnd) {
282
+ state.tokenize = jsTokenBase;
283
+ break;
284
+ }
285
+ maybeEnd = (ch == "/");
286
+ }
287
+ return ret("text", "em");
288
+ }
289
+
290
+ // tw underlined text
291
+ function twTokenUnderline(stream, state) {
292
+ var maybeEnd = false,
293
+ ch;
294
+ while (ch = stream.next()) {
295
+ if (ch == "_" && maybeEnd) {
296
+ state.tokenize = jsTokenBase;
297
+ break;
298
+ }
299
+ maybeEnd = (ch == "_");
300
+ }
301
+ return ret("text", "underlined");
302
+ }
303
+
304
+ // tw strike through text looks ugly
305
+ // TODO just strike through the first and last 2 chars if possible.
306
+ function twTokenStrike(stream, state) {
307
+ var maybeEnd = false,
308
+ ch, nr;
309
+
310
+ while (ch = stream.next()) {
311
+ if (ch == "-" && maybeEnd) {
312
+ state.tokenize = jsTokenBase;
313
+ break;
314
+ }
315
+ maybeEnd = (ch == "-");
316
+ }
317
+ return ret("text", "line-through");
318
+ }
319
+
320
+ // macro
321
+ function twTokenMacro(stream, state) {
322
+ var ch, tmp, word, known;
323
+
324
+ if (stream.current() == '<<') {
325
+ return ret('brace', 'macro');
326
+ }
327
+
328
+ ch = stream.next();
329
+ if (!ch) {
330
+ state.tokenize = jsTokenBase;
331
+ return ret(ch);
332
+ }
333
+ if (ch == ">") {
334
+ if (stream.peek() == '>') {
335
+ stream.next();
336
+ state.tokenize = jsTokenBase;
337
+ return ret("brace", "macro");
338
+ }
339
+ }
340
+
341
+ stream.eatWhile(/[\w\$_]/);
342
+ word = stream.current();
343
+ known = keywords.propertyIsEnumerable(word) && keywords[word];
344
+
345
+ if (known) {
346
+ return ret(known.type, known.style, word);
347
+ }
348
+ else {
349
+ return ret("macro", null, word);
350
+ }
351
+ }
352
+
353
+ // Interface
354
+ return {
355
+ startState: function (basecolumn) {
356
+ return {
357
+ tokenize: jsTokenBase,
358
+ indented: 0,
359
+ level: 0
360
+ };
361
+ },
362
+
363
+ token: function (stream, state) {
364
+ if (stream.eatSpace()) return null;
365
+ var style = state.tokenize(stream, state);
366
+ return style;
367
+ },
368
+
369
+ electricChars: ""
370
+ };
371
+ });
372
+
373
+ CodeMirror.defineMIME("text/x-tiddlywiki", "tiddlywiki");
374
+ //}}}
@@ -0,0 +1,103 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>CodeMirror: Velocity mode</title>
5
+ <link rel="stylesheet" href="../../lib/codemirror.css">
6
+ <script src="../../lib/codemirror.js"></script>
7
+ <script src="velocity.js"></script>
8
+ <link rel="stylesheet" href="../../theme/night.css">
9
+ <style>.CodeMirror {border: 1px solid black;}</style>
10
+ <link rel="stylesheet" href="../../doc/docs.css">
11
+ </head>
12
+ <body>
13
+ <h1>CodeMirror: Velocity mode</h1>
14
+ <form><textarea id="code" name="code">
15
+ ## Velocity Code Demo
16
+ #*
17
+ based on PL/SQL mode by Peter Raganitsch, adapted to Velocity by Steve O'Hara ( http://www.pivotal-solutions.co.uk )
18
+ August 2011
19
+ *#
20
+
21
+ #*
22
+ This is a multiline comment.
23
+ This is the second line
24
+ *#
25
+
26
+ #[[ hello steve
27
+ This has invalid syntax that would normally need "poor man's escaping" like:
28
+
29
+ #define()
30
+
31
+ ${blah
32
+ ]]#
33
+
34
+ #include( "disclaimer.txt" "opinion.txt" )
35
+ #include( $foo $bar )
36
+
37
+ #parse( "lecorbusier.vm" )
38
+ #parse( $foo )
39
+
40
+ #evaluate( 'string with VTL #if(true)will be displayed#end' )
41
+
42
+ #define( $hello ) Hello $who #end #set( $who = "World!") $hello ## displays Hello World!
43
+
44
+ #foreach( $customer in $customerList )
45
+
46
+ $foreach.count $customer.Name
47
+
48
+ #if( $foo == ${bar})
49
+ it's true!
50
+ #break
51
+ #{else}
52
+ it's not!
53
+ #stop
54
+ #end
55
+
56
+ #if ($foreach.parent.hasNext)
57
+ $velocityCount
58
+ #end
59
+ #end
60
+
61
+ $someObject.getValues("this is a string split
62
+ across lines")
63
+
64
+ #macro( tablerows $color $somelist )
65
+ #foreach( $something in $somelist )
66
+ <tr><td bgcolor=$color>$something</td></tr>
67
+ #end
68
+ #end
69
+
70
+ #tablerows("red" ["dadsdf","dsa"])
71
+
72
+ Variable reference: #set( $monkey = $bill )
73
+ String literal: #set( $monkey.Friend = 'monica' )
74
+ Property reference: #set( $monkey.Blame = $whitehouse.Leak )
75
+ Method reference: #set( $monkey.Plan = $spindoctor.weave($web) )
76
+ Number literal: #set( $monkey.Number = 123 )
77
+ Range operator: #set( $monkey.Numbers = [1..3] )
78
+ Object list: #set( $monkey.Say = ["Not", $my, "fault"] )
79
+ Object map: #set( $monkey.Map = {"banana" : "good", "roast beef" : "bad"})
80
+
81
+ The RHS can also be a simple arithmetic expression, such as:
82
+ Addition: #set( $value = $foo + 1 )
83
+ Subtraction: #set( $value = $bar - 1 )
84
+ Multiplication: #set( $value = $foo * $bar )
85
+ Division: #set( $value = $foo / $bar )
86
+ Remainder: #set( $value = $foo % $bar )
87
+
88
+ </textarea></form>
89
+ <script>
90
+ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
91
+ tabMode: "indent",
92
+ matchBrackets: true,
93
+ theme: "night",
94
+ lineNumbers: true,
95
+ indentUnit: 4,
96
+ mode: "text/velocity"
97
+ });
98
+ </script>
99
+
100
+ <p><strong>MIME types defined:</strong> <code>text/velocity</code>.</p>
101
+
102
+ </body>
103
+ </html>
@@ -0,0 +1,146 @@
1
+ CodeMirror.defineMode("velocity", function(config) {
2
+ function parseWords(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
+
8
+ var indentUnit = config.indentUnit
9
+ var keywords = parseWords("#end #else #break #stop #[[ #]] " +
10
+ "#{end} #{else} #{break} #{stop}");
11
+ var functions = parseWords("#if #elseif #foreach #set #include #parse #macro #define #evaluate " +
12
+ "#{if} #{elseif} #{foreach} #{set} #{include} #{parse} #{macro} #{define} #{evaluate}");
13
+ var specials = parseWords("$foreach.count $foreach.hasNext $foreach.first $foreach.last $foreach.topmost $foreach.parent $velocityCount");
14
+ var isOperatorChar = /[+\-*&%=<>!?:\/|]/;
15
+ var multiLineStrings =true;
16
+
17
+ function chain(stream, state, f) {
18
+ state.tokenize = f;
19
+ return f(stream, state);
20
+ }
21
+ function tokenBase(stream, state) {
22
+ var beforeParams = state.beforeParams;
23
+ state.beforeParams = false;
24
+ var ch = stream.next();
25
+ // start of string?
26
+ if ((ch == '"' || ch == "'") && state.inParams)
27
+ return chain(stream, state, tokenString(ch));
28
+ // is it one of the special signs []{}().,;? Seperator?
29
+ else if (/[\[\]{}\(\),;\.]/.test(ch)) {
30
+ if (ch == "(" && beforeParams) state.inParams = true;
31
+ else if (ch == ")") state.inParams = false;
32
+ return null;
33
+ }
34
+ // start of a number value?
35
+ else if (/\d/.test(ch)) {
36
+ stream.eatWhile(/[\w\.]/);
37
+ return "number";
38
+ }
39
+ // multi line comment?
40
+ else if (ch == "#" && stream.eat("*")) {
41
+ return chain(stream, state, tokenComment);
42
+ }
43
+ // unparsed content?
44
+ else if (ch == "#" && stream.match(/ *\[ *\[/)) {
45
+ return chain(stream, state, tokenUnparsed);
46
+ }
47
+ // single line comment?
48
+ else if (ch == "#" && stream.eat("#")) {
49
+ stream.skipToEnd();
50
+ return "comment";
51
+ }
52
+ // variable?
53
+ else if (ch == "$") {
54
+ stream.eatWhile(/[\w\d\$_\.{}]/);
55
+ // is it one of the specials?
56
+ if (specials && specials.propertyIsEnumerable(stream.current().toLowerCase())) {
57
+ return "keyword";
58
+ }
59
+ else {
60
+ state.beforeParams = true;
61
+ return "builtin";
62
+ }
63
+ }
64
+ // is it a operator?
65
+ else if (isOperatorChar.test(ch)) {
66
+ stream.eatWhile(isOperatorChar);
67
+ return "operator";
68
+ }
69
+ else {
70
+ // get the whole word
71
+ stream.eatWhile(/[\w\$_{}]/);
72
+ var word = stream.current().toLowerCase();
73
+ // is it one of the listed keywords?
74
+ if (keywords && keywords.propertyIsEnumerable(word))
75
+ return "keyword";
76
+ // is it one of the listed functions?
77
+ if (functions && functions.propertyIsEnumerable(word) ||
78
+ stream.current().match(/^#[a-z0-9_]+ *$/i) && stream.peek()=="(") {
79
+ state.beforeParams = true;
80
+ return "keyword";
81
+ }
82
+ // default: just a "word"
83
+ return null;
84
+ }
85
+ }
86
+
87
+ function tokenString(quote) {
88
+ return function(stream, state) {
89
+ var escaped = false, next, end = false;
90
+ while ((next = stream.next()) != null) {
91
+ if (next == quote && !escaped) {
92
+ end = true;
93
+ break;
94
+ }
95
+ escaped = !escaped && next == "\\";
96
+ }
97
+ if (end) state.tokenize = tokenBase;
98
+ return "string";
99
+ };
100
+ }
101
+
102
+ function tokenComment(stream, state) {
103
+ var maybeEnd = false, ch;
104
+ while (ch = stream.next()) {
105
+ if (ch == "#" && maybeEnd) {
106
+ state.tokenize = tokenBase;
107
+ break;
108
+ }
109
+ maybeEnd = (ch == "*");
110
+ }
111
+ return "comment";
112
+ }
113
+
114
+ function tokenUnparsed(stream, state) {
115
+ var maybeEnd = 0, ch;
116
+ while (ch = stream.next()) {
117
+ if (ch == "#" && maybeEnd == 2) {
118
+ state.tokenize = tokenBase;
119
+ break;
120
+ }
121
+ if (ch == "]")
122
+ maybeEnd++;
123
+ else if (ch != " ")
124
+ maybeEnd = 0;
125
+ }
126
+ return "meta";
127
+ }
128
+ // Interface
129
+
130
+ return {
131
+ startState: function(basecolumn) {
132
+ return {
133
+ tokenize: tokenBase,
134
+ beforeParams: false,
135
+ inParams: false
136
+ };
137
+ },
138
+
139
+ token: function(stream, state) {
140
+ if (stream.eatSpace()) return null;
141
+ return state.tokenize(stream, state);
142
+ }
143
+ };
144
+ });
145
+
146
+ CodeMirror.defineMIME("text/velocity", "velocity");
@@ -0,0 +1,44 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>CodeMirror: XML mode</title>
5
+ <link rel="stylesheet" href="../../lib/codemirror.css">
6
+ <script src="../../lib/codemirror.js"></script>
7
+ <script src="xml.js"></script>
8
+ <style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
9
+ <link rel="stylesheet" href="../../doc/docs.css">
10
+ </head>
11
+ <body>
12
+ <h1>CodeMirror: XML mode</h1>
13
+ <form><textarea id="code" name="code">
14
+ &lt;html style="color: green"&gt;
15
+ &lt;!-- this is a comment --&gt;
16
+ &lt;head&gt;
17
+ &lt;title&gt;HTML Example&lt;/title&gt;
18
+ &lt;/head&gt;
19
+ &lt;body&gt;
20
+ The indentation tries to be &lt;em&gt;somewhat &amp;quot;do what
21
+ I mean&amp;quot;&lt;/em&gt;... but might not match your style.
22
+ &lt;/body&gt;
23
+ &lt;/html&gt;
24
+ </textarea></form>
25
+ <script>
26
+ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
27
+ mode: {name: "xml", alignCDATA: true},
28
+ lineNumbers: true
29
+ });
30
+ </script>
31
+ <p>The XML mode supports two configuration parameters:</p>
32
+ <dl>
33
+ <dt><code>htmlMode (boolean)</code></dt>
34
+ <dd>This switches the mode to parse HTML instead of XML. This
35
+ means attributes do not have to be quoted, and some elements
36
+ (such as <code>br</code>) do not require a closing tag.</dd>
37
+ <dt><code>alignCDATA (boolean)</code></dt>
38
+ <dd>Setting this to true will force the opening tag of CDATA
39
+ blocks to not be indented.</dd>
40
+ </dl>
41
+
42
+ <p><strong>MIME types defined:</strong> <code>application/xml</code>, <code>text/html</code>.</p>
43
+ </body>
44
+ </html>