ledger_web 1.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 (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>