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,195 @@
1
+ CodeMirror.defineMode("ruby", function(config, parserConfig) {
2
+ function wordObj(words) {
3
+ var o = {};
4
+ for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
5
+ return o;
6
+ }
7
+ var keywords = wordObj([
8
+ "alias", "and", "BEGIN", "begin", "break", "case", "class", "def", "defined?", "do", "else",
9
+ "elsif", "END", "end", "ensure", "false", "for", "if", "in", "module", "next", "not", "or",
10
+ "redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless",
11
+ "until", "when", "while", "yield", "nil", "raise", "throw", "catch", "fail", "loop", "callcc",
12
+ "caller", "lambda", "proc", "public", "protected", "private", "require", "load",
13
+ "require_relative", "extend", "autoload"
14
+ ]);
15
+ var indentWords = wordObj(["def", "class", "case", "for", "while", "do", "module", "then",
16
+ "unless", "catch", "loop", "proc"]);
17
+ var dedentWords = wordObj(["end", "until"]);
18
+ var matching = {"[": "]", "{": "}", "(": ")"};
19
+ var curPunc;
20
+
21
+ function chain(newtok, stream, state) {
22
+ state.tokenize.push(newtok);
23
+ return newtok(stream, state);
24
+ }
25
+
26
+ function tokenBase(stream, state) {
27
+ curPunc = null;
28
+ if (stream.sol() && stream.match("=begin") && stream.eol()) {
29
+ state.tokenize.push(readBlockComment);
30
+ return "comment";
31
+ }
32
+ if (stream.eatSpace()) return null;
33
+ var ch = stream.next();
34
+ if (ch == "`" || ch == "'" || ch == '"' || ch == "/") {
35
+ return chain(readQuoted(ch, "string", ch == '"'), stream, state);
36
+ } else if (ch == "%") {
37
+ var style, embed = false;
38
+ if (stream.eat("s")) style = "atom";
39
+ else if (stream.eat(/[WQ]/)) { style = "string"; embed = true; }
40
+ else if (stream.eat(/[wxqr]/)) style = "string";
41
+ var delim = stream.eat(/[^\w\s]/);
42
+ if (!delim) return "operator";
43
+ if (matching.propertyIsEnumerable(delim)) delim = matching[delim];
44
+ return chain(readQuoted(delim, style, embed, true), stream, state);
45
+ } else if (ch == "#") {
46
+ stream.skipToEnd();
47
+ return "comment";
48
+ } else if (ch == "<" && stream.eat("<")) {
49
+ stream.eat("-");
50
+ stream.eat(/[\'\"\`]/);
51
+ var match = stream.match(/^\w+/);
52
+ stream.eat(/[\'\"\`]/);
53
+ if (match) return chain(readHereDoc(match[0]), stream, state);
54
+ return null;
55
+ } else if (ch == "0") {
56
+ if (stream.eat("x")) stream.eatWhile(/[\da-fA-F]/);
57
+ else if (stream.eat("b")) stream.eatWhile(/[01]/);
58
+ else stream.eatWhile(/[0-7]/);
59
+ return "number";
60
+ } else if (/\d/.test(ch)) {
61
+ stream.match(/^[\d_]*(?:\.[\d_]+)?(?:[eE][+\-]?[\d_]+)?/);
62
+ return "number";
63
+ } else if (ch == "?") {
64
+ while (stream.match(/^\\[CM]-/)) {}
65
+ if (stream.eat("\\")) stream.eatWhile(/\w/);
66
+ else stream.next();
67
+ return "string";
68
+ } else if (ch == ":") {
69
+ if (stream.eat("'")) return chain(readQuoted("'", "atom", false), stream, state);
70
+ if (stream.eat('"')) return chain(readQuoted('"', "atom", true), stream, state);
71
+ stream.eatWhile(/[\w\?]/);
72
+ return "atom";
73
+ } else if (ch == "@") {
74
+ stream.eat("@");
75
+ stream.eatWhile(/[\w\?]/);
76
+ return "variable-2";
77
+ } else if (ch == "$") {
78
+ stream.next();
79
+ stream.eatWhile(/[\w\?]/);
80
+ return "variable-3";
81
+ } else if (/\w/.test(ch)) {
82
+ stream.eatWhile(/[\w\?]/);
83
+ if (stream.eat(":")) return "atom";
84
+ return "ident";
85
+ } else if (ch == "|" && (state.varList || state.lastTok == "{" || state.lastTok == "do")) {
86
+ curPunc = "|";
87
+ return null;
88
+ } else if (/[\(\)\[\]{}\\;]/.test(ch)) {
89
+ curPunc = ch;
90
+ return null;
91
+ } else if (ch == "-" && stream.eat(">")) {
92
+ return "arrow";
93
+ } else if (/[=+\-\/*:\.^%<>~|]/.test(ch)) {
94
+ stream.eatWhile(/[=+\-\/*:\.^%<>~|]/);
95
+ return "operator";
96
+ } else {
97
+ return null;
98
+ }
99
+ }
100
+
101
+ function tokenBaseUntilBrace() {
102
+ var depth = 1;
103
+ return function(stream, state) {
104
+ if (stream.peek() == "}") {
105
+ depth--;
106
+ if (depth == 0) {
107
+ state.tokenize.pop();
108
+ return state.tokenize[state.tokenize.length-1](stream, state);
109
+ }
110
+ } else if (stream.peek() == "{") {
111
+ depth++;
112
+ }
113
+ return tokenBase(stream, state);
114
+ };
115
+ }
116
+ function readQuoted(quote, style, embed, unescaped) {
117
+ return function(stream, state) {
118
+ var escaped = false, ch;
119
+ while ((ch = stream.next()) != null) {
120
+ if (ch == quote && (unescaped || !escaped)) {
121
+ state.tokenize.pop();
122
+ break;
123
+ }
124
+ if (embed && ch == "#" && !escaped && stream.eat("{")) {
125
+ state.tokenize.push(tokenBaseUntilBrace(arguments.callee));
126
+ break;
127
+ }
128
+ escaped = !escaped && ch == "\\";
129
+ }
130
+ return style;
131
+ };
132
+ }
133
+ function readHereDoc(phrase) {
134
+ return function(stream, state) {
135
+ if (stream.match(phrase)) state.tokenize.pop();
136
+ else stream.skipToEnd();
137
+ return "string";
138
+ };
139
+ }
140
+ function readBlockComment(stream, state) {
141
+ if (stream.sol() && stream.match("=end") && stream.eol())
142
+ state.tokenize.pop();
143
+ stream.skipToEnd();
144
+ return "comment";
145
+ }
146
+
147
+ return {
148
+ startState: function() {
149
+ return {tokenize: [tokenBase],
150
+ indented: 0,
151
+ context: {type: "top", indented: -config.indentUnit},
152
+ continuedLine: false,
153
+ lastTok: null,
154
+ varList: false};
155
+ },
156
+
157
+ token: function(stream, state) {
158
+ if (stream.sol()) state.indented = stream.indentation();
159
+ var style = state.tokenize[state.tokenize.length-1](stream, state), kwtype;
160
+ if (style == "ident") {
161
+ var word = stream.current();
162
+ style = keywords.propertyIsEnumerable(stream.current()) ? "keyword"
163
+ : /^[A-Z]/.test(word) ? "tag"
164
+ : (state.lastTok == "def" || state.lastTok == "class" || state.varList) ? "def"
165
+ : "variable";
166
+ if (indentWords.propertyIsEnumerable(word)) kwtype = "indent";
167
+ else if (dedentWords.propertyIsEnumerable(word)) kwtype = "dedent";
168
+ else if (word == "if" && stream.column() == stream.indentation()) kwtype = "indent";
169
+ }
170
+ if (curPunc || (style && style != "comment")) state.lastTok = word || curPunc || style;
171
+ if (curPunc == "|") state.varList = !state.varList;
172
+
173
+ if (kwtype == "indent" || /[\(\[\{]/.test(curPunc))
174
+ state.context = {prev: state.context, type: curPunc || style, indented: state.indented};
175
+ else if ((kwtype == "dedent" || /[\)\]\}]/.test(curPunc)) && state.context.prev)
176
+ state.context = state.context.prev;
177
+
178
+ if (stream.eol())
179
+ state.continuedLine = (curPunc == "\\" || style == "operator");
180
+ return style;
181
+ },
182
+
183
+ indent: function(state, textAfter) {
184
+ if (state.tokenize[state.tokenize.length-1] != tokenBase) return 0;
185
+ var firstChar = textAfter && textAfter.charAt(0);
186
+ var ct = state.context;
187
+ var closing = ct.type == matching[firstChar] ||
188
+ ct.type == "keyword" && /^(?:end|until|else|elsif|when)\b/.test(textAfter);
189
+ return ct.indented + (closing ? 0 : config.indentUnit) +
190
+ (state.continuedLine ? config.indentUnit : 0);
191
+ }
192
+ };
193
+ });
194
+
195
+ CodeMirror.defineMIME("text/x-ruby", "ruby");
@@ -0,0 +1,48 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>CodeMirror: Rust mode</title>
5
+ <link rel="stylesheet" href="../../lib/codemirror.css">
6
+ <script src="../../lib/codemirror.js"></script>
7
+ <script src="rust.js"></script>
8
+ <link rel="stylesheet" href="../../doc/docs.css">
9
+ <style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
10
+ </head>
11
+ <body>
12
+ <h1>CodeMirror: Rust mode</h1>
13
+
14
+ <div><textarea id="code" name="code">
15
+ // Demo code.
16
+
17
+ type foo<T> = int;
18
+ tag bar {
19
+ some(int, foo<float>);
20
+ none;
21
+ }
22
+
23
+ fn check_crate(x: int) {
24
+ let v = 10;
25
+ alt foo {
26
+ 1 to 3 {
27
+ print_foo();
28
+ if x {
29
+ blah() + 10;
30
+ }
31
+ }
32
+ (x, y) { "bye" }
33
+ _ { "hi" }
34
+ }
35
+ }
36
+ </textarea></div>
37
+
38
+ <script>
39
+ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
40
+ lineNumbers: true,
41
+ matchBrackets: true,
42
+ tabMode: "indent"
43
+ });
44
+ </script>
45
+
46
+ <p><strong>MIME types defined:</strong> <code>text/x-rustsrc</code>.</p>
47
+ </body>
48
+ </html>
@@ -0,0 +1,411 @@
1
+ CodeMirror.defineMode("rust", function() {
2
+ var indentUnit = 4, altIndentUnit = 2;
3
+ var valKeywords = {
4
+ "if": "if-style", "while": "if-style", "else": "else-style",
5
+ "do": "else-style", "ret": "else-style", "fail": "else-style",
6
+ "break": "atom", "cont": "atom", "const": "let", "resource": "fn",
7
+ "let": "let", "fn": "fn", "for": "for", "alt": "alt", "obj": "fn",
8
+ "lambda": "fn", "type": "type", "tag": "tag", "mod": "mod",
9
+ "as": "op", "true": "atom", "false": "atom", "assert": "op", "check": "op",
10
+ "claim": "op", "native": "ignore", "unsafe": "ignore", "import": "else-style",
11
+ "export": "else-style", "copy": "op", "log": "op", "log_err": "op",
12
+ "use": "op", "bind": "op"
13
+ };
14
+ var typeKeywords = function() {
15
+ var keywords = {"fn": "fn", "block": "fn", "obj": "obj"};
16
+ var atoms = "bool uint int i8 i16 i32 i64 u8 u16 u32 u64 float f32 f64 str char".split(" ");
17
+ for (var i = 0, e = atoms.length; i < e; ++i) keywords[atoms[i]] = "atom";
18
+ return keywords;
19
+ }();
20
+ var operatorChar = /[+\-*&%=<>!?|\.@]/;
21
+
22
+ // Tokenizer
23
+
24
+ // Used as scratch variable to communicate multiple values without
25
+ // consing up tons of objects.
26
+ var tcat, content;
27
+ function r(tc, style) {
28
+ tcat = tc;
29
+ return style;
30
+ }
31
+
32
+ function tokenBase(stream, state) {
33
+ var ch = stream.next();
34
+ if (ch == '"') {
35
+ state.tokenize = tokenString;
36
+ return state.tokenize(stream, state);
37
+ }
38
+ if (ch == "'") {
39
+ tcat = "atom";
40
+ if (stream.eat("\\")) {
41
+ if (stream.skipTo("'")) { stream.next(); return "string"; }
42
+ else { return "error"; }
43
+ } else {
44
+ stream.next();
45
+ return stream.eat("'") ? "string" : "error";
46
+ }
47
+ }
48
+ if (ch == "/") {
49
+ if (stream.eat("/")) { stream.skipToEnd(); return "comment"; }
50
+ if (stream.eat("*")) {
51
+ state.tokenize = tokenComment(1);
52
+ return state.tokenize(stream, state);
53
+ }
54
+ }
55
+ if (ch == "#") {
56
+ if (stream.eat("[")) { tcat = "open-attr"; return null; }
57
+ stream.eatWhile(/\w/);
58
+ return r("macro", "meta");
59
+ }
60
+ if (ch == ":" && stream.match(":<")) {
61
+ return r("op", null);
62
+ }
63
+ if (ch.match(/\d/) || (ch == "." && stream.eat(/\d/))) {
64
+ var flp = false;
65
+ if (!stream.match(/^x[\da-f]+/i) && !stream.match(/^b[01]+/)) {
66
+ stream.eatWhile(/\d/);
67
+ if (stream.eat(".")) { flp = true; stream.eatWhile(/\d/); }
68
+ if (stream.match(/^e[+\-]?\d+/i)) { flp = true; }
69
+ }
70
+ if (flp) stream.match(/^f(?:32|64)/);
71
+ else stream.match(/^[ui](?:8|16|32|64)/);
72
+ return r("atom", "number");
73
+ }
74
+ if (ch.match(/[()\[\]{}:;,]/)) return r(ch, null);
75
+ if (ch == "-" && stream.eat(">")) return r("->", null);
76
+ if (ch.match(operatorChar)) {
77
+ stream.eatWhile(operatorChar);
78
+ return r("op", null);
79
+ }
80
+ stream.eatWhile(/\w/);
81
+ content = stream.current();
82
+ if (stream.match(/^::\w/)) {
83
+ stream.backUp(1);
84
+ return r("prefix", "variable-2");
85
+ }
86
+ if (state.keywords.propertyIsEnumerable(content))
87
+ return r(state.keywords[content], content.match(/true|false/) ? "atom" : "keyword");
88
+ return r("name", "variable");
89
+ }
90
+
91
+ function tokenString(stream, state) {
92
+ var ch, escaped = false;
93
+ while (ch = stream.next()) {
94
+ if (ch == '"' && !escaped) {
95
+ state.tokenize = tokenBase;
96
+ return r("atom", "string");
97
+ }
98
+ escaped = !escaped && ch == "\\";
99
+ }
100
+ // Hack to not confuse the parser when a string is split in
101
+ // pieces.
102
+ return r("op", "string");
103
+ }
104
+
105
+ function tokenComment(depth) {
106
+ return function(stream, state) {
107
+ var lastCh = null, ch;
108
+ while (ch = stream.next()) {
109
+ if (ch == "/" && lastCh == "*") {
110
+ if (depth == 1) {
111
+ state.tokenize = tokenBase;
112
+ break;
113
+ } else {
114
+ state.tokenize = tokenComment(depth - 1);
115
+ return state.tokenize(stream, state);
116
+ }
117
+ }
118
+ if (ch == "*" && lastCh == "/") {
119
+ state.tokenize = tokenComment(depth + 1);
120
+ return state.tokenize(stream, state);
121
+ }
122
+ lastCh = ch;
123
+ }
124
+ return "comment";
125
+ };
126
+ }
127
+
128
+ // Parser
129
+
130
+ var cx = {state: null, stream: null, marked: null, cc: null};
131
+ function pass() {
132
+ for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
133
+ }
134
+ function cont() {
135
+ pass.apply(null, arguments);
136
+ return true;
137
+ }
138
+
139
+ function pushlex(type, info) {
140
+ var result = function() {
141
+ var state = cx.state;
142
+ state.lexical = {indented: state.indented, column: cx.stream.column(),
143
+ type: type, prev: state.lexical, info: info};
144
+ };
145
+ result.lex = true;
146
+ return result;
147
+ }
148
+ function poplex() {
149
+ var state = cx.state;
150
+ if (state.lexical.prev) {
151
+ if (state.lexical.type == ")")
152
+ state.indented = state.lexical.indented;
153
+ state.lexical = state.lexical.prev;
154
+ }
155
+ }
156
+ function typecx() { cx.state.keywords = typeKeywords; }
157
+ function valcx() { cx.state.keywords = valKeywords; }
158
+ poplex.lex = typecx.lex = valcx.lex = true;
159
+
160
+ function commasep(comb, end) {
161
+ function more(type) {
162
+ if (type == ",") return cont(comb, more);
163
+ if (type == end) return cont();
164
+ return cont(more);
165
+ }
166
+ return function(type) {
167
+ if (type == end) return cont();
168
+ return pass(comb, more);
169
+ };
170
+ }
171
+
172
+ function block(type) {
173
+ if (type == "}") return cont();
174
+ if (type == "let") return cont(pushlex("stat", "let"), letdef1, poplex, block);
175
+ if (type == "fn") return cont(pushlex("stat"), fndef, poplex, block);
176
+ if (type == "type") return cont(pushlex("stat"), tydef, endstatement, poplex, block);
177
+ if (type == "tag") return cont(pushlex("stat"), tagdef, poplex, block);
178
+ if (type == "mod") return cont(pushlex("stat"), mod, poplex, block);
179
+ if (type == "open-attr") return cont(pushlex("]"), commasep(expression, "]"), poplex);
180
+ if (type == "ignore" || type.match(/[\]\);,]/)) return cont(block);
181
+ return pass(pushlex("stat"), expression, poplex, endstatement, block);
182
+ }
183
+ function endstatement(type) {
184
+ if (type == ";") return cont();
185
+ return pass();
186
+ }
187
+ function expression(type) {
188
+ if (type == "atom" || type == "name") return cont(maybeop);
189
+ if (type == "{") return cont(pushlex("}"), exprbrace, poplex);
190
+ if (type.match(/[\[\(]/)) return matchBrackets(type, expression);
191
+ if (type.match(/[\]\)\};,]/)) return pass();
192
+ if (type == "if-style") return cont(expression, expression);
193
+ if (type == "else-style" || type == "op") return cont(expression);
194
+ if (type == "for") return cont(pattern, maybetype, inop, expression, expression);
195
+ if (type == "alt") return cont(expression, altbody);
196
+ if (type == "fn") return cont(fndef);
197
+ if (type == "macro") return cont(macro);
198
+ return cont();
199
+ }
200
+ function maybeop(type) {
201
+ if (content == ".") return cont(maybeprop);
202
+ if (content == "::<"){return cont(typarams, maybeop);}
203
+ if (type == "op" || content == ":") return cont(expression);
204
+ if (type == "(" || type == "[") return matchBrackets(type, expression);
205
+ return pass();
206
+ }
207
+ function maybeprop(type) {
208
+ if (content.match(/^\w+$/)) {cx.marked = "variable"; return cont(maybeop);}
209
+ return pass(expression);
210
+ }
211
+ function exprbrace(type) {
212
+ if (type == "op") {
213
+ if (content == "|") return cont(blockvars, poplex, pushlex("}", "block"), block);
214
+ if (content == "||") return cont(poplex, pushlex("}", "block"), block);
215
+ }
216
+ if (content == "mutable" || (content.match(/^\w+$/) && cx.stream.peek() == ":"
217
+ && !cx.stream.match("::", false)))
218
+ return pass(record_of(expression));
219
+ return pass(block);
220
+ }
221
+ function record_of(comb) {
222
+ function ro(type) {
223
+ if (content == "mutable" || content == "with") {cx.marked = "keyword"; return cont(ro);}
224
+ if (content.match(/^\w*$/)) {cx.marked = "variable"; return cont(ro);}
225
+ if (type == ":") return cont(comb, ro);
226
+ if (type == "}") return cont();
227
+ return cont(ro);
228
+ }
229
+ return ro;
230
+ }
231
+ function blockvars(type) {
232
+ if (type == "name") {cx.marked = "def"; return cont(blockvars);}
233
+ if (type == "op" && content == "|") return cont();
234
+ return cont(blockvars);
235
+ }
236
+
237
+ function letdef1(type) {
238
+ if (type.match(/[\]\)\};]/)) return cont();
239
+ if (content == "=") return cont(expression, letdef2);
240
+ if (type == ",") return cont(letdef1);
241
+ return pass(pattern, maybetype, letdef1);
242
+ }
243
+ function letdef2(type) {
244
+ if (type.match(/[\]\)\};,]/)) return pass(letdef1);
245
+ else return pass(expression, letdef2);
246
+ }
247
+ function maybetype(type) {
248
+ if (type == ":") return cont(typecx, rtype, valcx);
249
+ return pass();
250
+ }
251
+ function inop(type) {
252
+ if (type == "name" && content == "in") {cx.marked = "keyword"; return cont();}
253
+ return pass();
254
+ }
255
+ function fndef(type) {
256
+ if (type == "name") {cx.marked = "def"; return cont(fndef);}
257
+ if (content == "<") return cont(typarams, fndef);
258
+ if (type == "{") return pass(expression);
259
+ if (type == "(") return cont(pushlex(")"), commasep(argdef, ")"), poplex, fndef);
260
+ if (type == "->") return cont(typecx, rtype, valcx, fndef);
261
+ return cont(fndef);
262
+ }
263
+ function tydef(type) {
264
+ if (type == "name") {cx.marked = "def"; return cont(tydef);}
265
+ if (content == "<") return cont(typarams, tydef);
266
+ if (content == "=") return cont(typecx, rtype, valcx);
267
+ return cont(tydef);
268
+ }
269
+ function tagdef(type) {
270
+ if (type == "name") {cx.marked = "def"; return cont(tagdef);}
271
+ if (content == "<") return cont(typarams, tagdef);
272
+ if (content == "=") return cont(typecx, rtype, valcx, endstatement);
273
+ if (type == "{") return cont(pushlex("}"), typecx, tagblock, valcx, poplex);
274
+ return cont(tagdef);
275
+ }
276
+ function tagblock(type) {
277
+ if (type == "}") return cont();
278
+ if (type == "(") return cont(pushlex(")"), commasep(rtype, ")"), poplex, tagblock);
279
+ if (content.match(/^\w+$/)) cx.marked = "def";
280
+ return cont(tagblock);
281
+ }
282
+ function mod(type) {
283
+ if (type == "name") {cx.marked = "def"; return cont(mod);}
284
+ if (type == "{") return cont(pushlex("}"), block, poplex);
285
+ return pass();
286
+ }
287
+ function typarams(type) {
288
+ if (content == ">") return cont();
289
+ if (content == ",") return cont(typarams);
290
+ return pass(rtype, typarams);
291
+ }
292
+ function argdef(type) {
293
+ if (type == "name") {cx.marked = "def"; return cont(argdef);}
294
+ if (type == ":") return cont(typecx, rtype, valcx);
295
+ return pass();
296
+ }
297
+ function rtype(type) {
298
+ if (type == "name") {cx.marked = "variable-3"; return cont(rtypemaybeparam); }
299
+ if (content == "mutable") {cx.marked = "keyword"; return cont(rtype);}
300
+ if (type == "atom") return cont(rtypemaybeparam);
301
+ if (type == "op" || type == "obj") return cont(rtype);
302
+ if (type == "fn") return cont(fntype);
303
+ if (type == "{") return cont(pushlex("{"), record_of(rtype), poplex);
304
+ return matchBrackets(type, rtype);
305
+ }
306
+ function rtypemaybeparam(type) {
307
+ if (content == "<") return cont(typarams);
308
+ return pass();
309
+ }
310
+ function fntype(type) {
311
+ if (type == "(") return cont(pushlex("("), commasep(rtype, ")"), poplex, fntype);
312
+ if (type == "->") return cont(rtype);
313
+ return pass();
314
+ }
315
+ function pattern(type) {
316
+ if (type == "name") {cx.marked = "def"; return cont(patternmaybeop);}
317
+ if (type == "atom") return cont(patternmaybeop);
318
+ if (type == "op") return cont(pattern);
319
+ if (type.match(/[\]\)\};,]/)) return pass();
320
+ return matchBrackets(type, pattern);
321
+ }
322
+ function patternmaybeop(type) {
323
+ if (type == "op" && content == ".") return cont();
324
+ if (content == "to") {cx.marked = "keyword"; return cont(pattern);}
325
+ else return pass();
326
+ }
327
+ function altbody(type) {
328
+ if (type == "{") return cont(pushlex("}", "alt"), altblock1, poplex);
329
+ return pass();
330
+ }
331
+ function altblock1(type) {
332
+ if (type == "}") return cont();
333
+ if (type == "|") return cont(altblock1);
334
+ if (content == "when") {cx.marked = "keyword"; return cont(expression, altblock2);}
335
+ if (type.match(/[\]\);,]/)) return cont(altblock1);
336
+ return pass(pattern, altblock2);
337
+ }
338
+ function altblock2(type) {
339
+ if (type == "{") return cont(pushlex("}", "alt"), block, poplex, altblock1);
340
+ else return pass(altblock1);
341
+ }
342
+
343
+ function macro(type) {
344
+ if (type.match(/[\[\(\{]/)) return matchBrackets(type, expression);
345
+ return pass();
346
+ }
347
+ function matchBrackets(type, comb) {
348
+ if (type == "[") return cont(pushlex("]"), commasep(comb, "]"), poplex);
349
+ if (type == "(") return cont(pushlex(")"), commasep(comb, ")"), poplex);
350
+ if (type == "{") return cont(pushlex("}"), commasep(comb, "}"), poplex);
351
+ return cont();
352
+ }
353
+
354
+ function parse(state, stream, style) {
355
+ var cc = state.cc;
356
+ // Communicate our context to the combinators.
357
+ // (Less wasteful than consing up a hundred closures on every call.)
358
+ cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
359
+
360
+ while (true) {
361
+ var combinator = cc.length ? cc.pop() : block;
362
+ if (combinator(tcat)) {
363
+ while(cc.length && cc[cc.length - 1].lex)
364
+ cc.pop()();
365
+ return cx.marked || style;
366
+ }
367
+ }
368
+ }
369
+
370
+ return {
371
+ startState: function() {
372
+ return {
373
+ tokenize: tokenBase,
374
+ cc: [],
375
+ lexical: {indented: -indentUnit, column: 0, type: "top", align: false},
376
+ keywords: valKeywords,
377
+ indented: 0
378
+ };
379
+ },
380
+
381
+ token: function(stream, state) {
382
+ if (stream.sol()) {
383
+ if (!state.lexical.hasOwnProperty("align"))
384
+ state.lexical.align = false;
385
+ state.indented = stream.indentation();
386
+ }
387
+ if (stream.eatSpace()) return null;
388
+ tcat = content = null;
389
+ var style = state.tokenize(stream, state);
390
+ if (style == "comment") return style;
391
+ if (!state.lexical.hasOwnProperty("align"))
392
+ state.lexical.align = true;
393
+ if (tcat == "prefix") return style;
394
+ if (!content) content = stream.current();
395
+ return parse(state, stream, style);
396
+ },
397
+
398
+ indent: function(state, textAfter) {
399
+ if (state.tokenize != tokenBase) return 0;
400
+ var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,
401
+ type = lexical.type, closing = firstChar == type;
402
+ if (type == "stat") return lexical.indented + indentUnit;
403
+ if (lexical.align) return lexical.column + (closing ? 0 : 1);
404
+ return lexical.indented + (closing ? 0 : (lexical.info == "alt" ? altIndentUnit : indentUnit));
405
+ },
406
+
407
+ electricChars: "{}"
408
+ };
409
+ });
410
+
411
+ CodeMirror.defineMIME("text/x-rustsrc", "rust");