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.
- data/.gitignore +10 -0
- data/LICENSE +7 -0
- data/README.md +140 -0
- data/Rakefile +11 -0
- data/bin/ledger_web +14 -0
- data/ledger_web.gemspec +26 -0
- data/lib/ledger_web/app.rb +69 -0
- data/lib/ledger_web/config.rb +87 -0
- data/lib/ledger_web/db/migrate/20111226180900_initial_schema.rb +38 -0
- data/lib/ledger_web/db/migrate/20111231132900_add_views.rb +37 -0
- data/lib/ledger_web/db.rb +54 -0
- data/lib/ledger_web/helpers.rb +62 -0
- data/lib/ledger_web/public/bootstrap-dropdown.js +55 -0
- data/lib/ledger_web/public/bootstrap.min.css +356 -0
- data/lib/ledger_web/public/codemirror/keymap/emacs.js +29 -0
- data/lib/ledger_web/public/codemirror/keymap/vim.js +76 -0
- data/lib/ledger_web/public/codemirror/lib/codemirror.css +104 -0
- data/lib/ledger_web/public/codemirror/lib/codemirror.js +2761 -0
- data/lib/ledger_web/public/codemirror/lib/util/dialog.css +23 -0
- data/lib/ledger_web/public/codemirror/lib/util/dialog.js +63 -0
- data/lib/ledger_web/public/codemirror/lib/util/foldcode.js +66 -0
- data/lib/ledger_web/public/codemirror/lib/util/formatting.js +291 -0
- data/lib/ledger_web/public/codemirror/lib/util/javascript-hint.js +83 -0
- data/lib/ledger_web/public/codemirror/lib/util/overlay.js +51 -0
- data/lib/ledger_web/public/codemirror/lib/util/runmode.js +27 -0
- data/lib/ledger_web/public/codemirror/lib/util/search.js +114 -0
- data/lib/ledger_web/public/codemirror/lib/util/searchcursor.js +117 -0
- data/lib/ledger_web/public/codemirror/lib/util/simple-hint.css +16 -0
- data/lib/ledger_web/public/codemirror/lib/util/simple-hint.js +66 -0
- data/lib/ledger_web/public/codemirror/mode/clike/clike.js +249 -0
- data/lib/ledger_web/public/codemirror/mode/clike/index.html +101 -0
- data/lib/ledger_web/public/codemirror/mode/clojure/clojure.js +207 -0
- data/lib/ledger_web/public/codemirror/mode/clojure/index.html +66 -0
- data/lib/ledger_web/public/codemirror/mode/coffeescript/LICENSE +22 -0
- data/lib/ledger_web/public/codemirror/mode/coffeescript/coffeescript.js +325 -0
- data/lib/ledger_web/public/codemirror/mode/coffeescript/index.html +721 -0
- data/lib/ledger_web/public/codemirror/mode/css/css.js +124 -0
- data/lib/ledger_web/public/codemirror/mode/css/index.html +55 -0
- data/lib/ledger_web/public/codemirror/mode/diff/diff.css +3 -0
- data/lib/ledger_web/public/codemirror/mode/diff/diff.js +13 -0
- data/lib/ledger_web/public/codemirror/mode/diff/index.html +99 -0
- data/lib/ledger_web/public/codemirror/mode/gfm/gfm.js +108 -0
- data/lib/ledger_web/public/codemirror/mode/gfm/index.html +47 -0
- data/lib/ledger_web/public/codemirror/mode/groovy/groovy.js +210 -0
- data/lib/ledger_web/public/codemirror/mode/groovy/index.html +71 -0
- data/lib/ledger_web/public/codemirror/mode/haskell/haskell.js +242 -0
- data/lib/ledger_web/public/codemirror/mode/haskell/index.html +60 -0
- data/lib/ledger_web/public/codemirror/mode/htmlembedded/htmlembedded.js +68 -0
- data/lib/ledger_web/public/codemirror/mode/htmlembedded/index.html +49 -0
- data/lib/ledger_web/public/codemirror/mode/htmlmixed/htmlmixed.js +83 -0
- data/lib/ledger_web/public/codemirror/mode/htmlmixed/index.html +51 -0
- data/lib/ledger_web/public/codemirror/mode/javascript/index.html +77 -0
- data/lib/ledger_web/public/codemirror/mode/javascript/javascript.js +360 -0
- data/lib/ledger_web/public/codemirror/mode/jinja2/index.html +37 -0
- data/lib/ledger_web/public/codemirror/mode/jinja2/jinja2.js +42 -0
- data/lib/ledger_web/public/codemirror/mode/lua/index.html +72 -0
- data/lib/ledger_web/public/codemirror/mode/lua/lua.js +140 -0
- data/lib/ledger_web/public/codemirror/mode/markdown/index.html +339 -0
- data/lib/ledger_web/public/codemirror/mode/markdown/markdown.js +242 -0
- data/lib/ledger_web/public/codemirror/mode/ntriples/index.html +32 -0
- data/lib/ledger_web/public/codemirror/mode/ntriples/ntriples.js +172 -0
- data/lib/ledger_web/public/codemirror/mode/pascal/LICENSE +7 -0
- data/lib/ledger_web/public/codemirror/mode/pascal/index.html +48 -0
- data/lib/ledger_web/public/codemirror/mode/pascal/pascal.js +138 -0
- data/lib/ledger_web/public/codemirror/mode/perl/LICENSE +19 -0
- data/lib/ledger_web/public/codemirror/mode/perl/index.html +62 -0
- data/lib/ledger_web/public/codemirror/mode/perl/perl.js +816 -0
- data/lib/ledger_web/public/codemirror/mode/php/index.html +48 -0
- data/lib/ledger_web/public/codemirror/mode/php/php.js +120 -0
- data/lib/ledger_web/public/codemirror/mode/plsql/index.html +62 -0
- data/lib/ledger_web/public/codemirror/mode/plsql/plsql.js +217 -0
- data/lib/ledger_web/public/codemirror/mode/python/LICENSE.txt +21 -0
- data/lib/ledger_web/public/codemirror/mode/python/index.html +122 -0
- data/lib/ledger_web/public/codemirror/mode/python/python.js +333 -0
- data/lib/ledger_web/public/codemirror/mode/r/LICENSE +24 -0
- data/lib/ledger_web/public/codemirror/mode/r/index.html +73 -0
- data/lib/ledger_web/public/codemirror/mode/r/r.js +141 -0
- data/lib/ledger_web/public/codemirror/mode/rpm/changes/changes.js +19 -0
- data/lib/ledger_web/public/codemirror/mode/rpm/changes/index.html +53 -0
- data/lib/ledger_web/public/codemirror/mode/rpm/spec/index.html +99 -0
- data/lib/ledger_web/public/codemirror/mode/rpm/spec/spec.css +5 -0
- data/lib/ledger_web/public/codemirror/mode/rpm/spec/spec.js +66 -0
- data/lib/ledger_web/public/codemirror/mode/rst/index.html +525 -0
- data/lib/ledger_web/public/codemirror/mode/rst/rst.js +326 -0
- data/lib/ledger_web/public/codemirror/mode/ruby/LICENSE +24 -0
- data/lib/ledger_web/public/codemirror/mode/ruby/index.html +171 -0
- data/lib/ledger_web/public/codemirror/mode/ruby/ruby.js +195 -0
- data/lib/ledger_web/public/codemirror/mode/rust/index.html +48 -0
- data/lib/ledger_web/public/codemirror/mode/rust/rust.js +411 -0
- data/lib/ledger_web/public/codemirror/mode/scheme/index.html +64 -0
- data/lib/ledger_web/public/codemirror/mode/scheme/scheme.js +202 -0
- data/lib/ledger_web/public/codemirror/mode/smalltalk/index.html +55 -0
- data/lib/ledger_web/public/codemirror/mode/smalltalk/smalltalk.js +139 -0
- data/lib/ledger_web/public/codemirror/mode/sparql/index.html +40 -0
- data/lib/ledger_web/public/codemirror/mode/sparql/sparql.js +143 -0
- data/lib/ledger_web/public/codemirror/mode/stex/index.html +95 -0
- data/lib/ledger_web/public/codemirror/mode/stex/stex.js +167 -0
- data/lib/ledger_web/public/codemirror/mode/tiddlywiki/index.html +183 -0
- data/lib/ledger_web/public/codemirror/mode/tiddlywiki/tiddlywiki.css +21 -0
- data/lib/ledger_web/public/codemirror/mode/tiddlywiki/tiddlywiki.js +374 -0
- data/lib/ledger_web/public/codemirror/mode/velocity/index.html +103 -0
- data/lib/ledger_web/public/codemirror/mode/velocity/velocity.js +146 -0
- data/lib/ledger_web/public/codemirror/mode/xml/index.html +44 -0
- data/lib/ledger_web/public/codemirror/mode/xml/xml.js +252 -0
- data/lib/ledger_web/public/codemirror/mode/xmlpure/index.html +59 -0
- data/lib/ledger_web/public/codemirror/mode/xmlpure/xmlpure.js +485 -0
- data/lib/ledger_web/public/codemirror/mode/yaml/index.html +67 -0
- data/lib/ledger_web/public/codemirror/mode/yaml/yaml.js +95 -0
- data/lib/ledger_web/public/codemirror/theme/cobalt.css +18 -0
- data/lib/ledger_web/public/codemirror/theme/eclipse.css +25 -0
- data/lib/ledger_web/public/codemirror/theme/elegant.css +10 -0
- data/lib/ledger_web/public/codemirror/theme/monokai.css +28 -0
- data/lib/ledger_web/public/codemirror/theme/neat.css +9 -0
- data/lib/ledger_web/public/codemirror/theme/night.css +21 -0
- data/lib/ledger_web/public/codemirror/theme/rubyblue.css +21 -0
- data/lib/ledger_web/public/jquery-1.7.1.min.js +4 -0
- data/lib/ledger_web/public/jquery.tablesorter.min.js +4 -0
- data/lib/ledger_web/public/ledger.css +14 -0
- data/lib/ledger_web/report.rb +187 -0
- data/lib/ledger_web/reports/savings_rate.erb +49 -0
- data/lib/ledger_web/version.rb +3 -0
- data/lib/ledger_web/views/error.erb +5 -0
- data/lib/ledger_web/views/help.erb +6 -0
- data/lib/ledger_web/views/layout.erb +44 -0
- data/lib/ledger_web/views/table.erb +31 -0
- data/lib/ledger_web/watcher.rb +37 -0
- data/lib/ledger_web.rb +20 -0
- metadata +229 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
CodeMirror.defineMode("css", function(config) {
|
|
2
|
+
var indentUnit = config.indentUnit, type;
|
|
3
|
+
function ret(style, tp) {type = tp; return style;}
|
|
4
|
+
|
|
5
|
+
function tokenBase(stream, state) {
|
|
6
|
+
var ch = stream.next();
|
|
7
|
+
if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("meta", stream.current());}
|
|
8
|
+
else if (ch == "/" && stream.eat("*")) {
|
|
9
|
+
state.tokenize = tokenCComment;
|
|
10
|
+
return tokenCComment(stream, state);
|
|
11
|
+
}
|
|
12
|
+
else if (ch == "<" && stream.eat("!")) {
|
|
13
|
+
state.tokenize = tokenSGMLComment;
|
|
14
|
+
return tokenSGMLComment(stream, state);
|
|
15
|
+
}
|
|
16
|
+
else if (ch == "=") ret(null, "compare");
|
|
17
|
+
else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
|
|
18
|
+
else if (ch == "\"" || ch == "'") {
|
|
19
|
+
state.tokenize = tokenString(ch);
|
|
20
|
+
return state.tokenize(stream, state);
|
|
21
|
+
}
|
|
22
|
+
else if (ch == "#") {
|
|
23
|
+
stream.eatWhile(/[\w\\\-]/);
|
|
24
|
+
return ret("atom", "hash");
|
|
25
|
+
}
|
|
26
|
+
else if (ch == "!") {
|
|
27
|
+
stream.match(/^\s*\w*/);
|
|
28
|
+
return ret("keyword", "important");
|
|
29
|
+
}
|
|
30
|
+
else if (/\d/.test(ch)) {
|
|
31
|
+
stream.eatWhile(/[\w.%]/);
|
|
32
|
+
return ret("number", "unit");
|
|
33
|
+
}
|
|
34
|
+
else if (/[,.+>*\/]/.test(ch)) {
|
|
35
|
+
return ret(null, "select-op");
|
|
36
|
+
}
|
|
37
|
+
else if (/[;{}:\[\]]/.test(ch)) {
|
|
38
|
+
return ret(null, ch);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
stream.eatWhile(/[\w\\\-]/);
|
|
42
|
+
return ret("variable", "variable");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function tokenCComment(stream, state) {
|
|
47
|
+
var maybeEnd = false, ch;
|
|
48
|
+
while ((ch = stream.next()) != null) {
|
|
49
|
+
if (maybeEnd && ch == "/") {
|
|
50
|
+
state.tokenize = tokenBase;
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
maybeEnd = (ch == "*");
|
|
54
|
+
}
|
|
55
|
+
return ret("comment", "comment");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function tokenSGMLComment(stream, state) {
|
|
59
|
+
var dashes = 0, ch;
|
|
60
|
+
while ((ch = stream.next()) != null) {
|
|
61
|
+
if (dashes >= 2 && ch == ">") {
|
|
62
|
+
state.tokenize = tokenBase;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
dashes = (ch == "-") ? dashes + 1 : 0;
|
|
66
|
+
}
|
|
67
|
+
return ret("comment", "comment");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function tokenString(quote) {
|
|
71
|
+
return function(stream, state) {
|
|
72
|
+
var escaped = false, ch;
|
|
73
|
+
while ((ch = stream.next()) != null) {
|
|
74
|
+
if (ch == quote && !escaped)
|
|
75
|
+
break;
|
|
76
|
+
escaped = !escaped && ch == "\\";
|
|
77
|
+
}
|
|
78
|
+
if (!escaped) state.tokenize = tokenBase;
|
|
79
|
+
return ret("string", "string");
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
startState: function(base) {
|
|
85
|
+
return {tokenize: tokenBase,
|
|
86
|
+
baseIndent: base || 0,
|
|
87
|
+
stack: []};
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
token: function(stream, state) {
|
|
91
|
+
if (stream.eatSpace()) return null;
|
|
92
|
+
var style = state.tokenize(stream, state);
|
|
93
|
+
|
|
94
|
+
var context = state.stack[state.stack.length-1];
|
|
95
|
+
if (type == "hash" && context == "rule") style = "atom";
|
|
96
|
+
else if (style == "variable") {
|
|
97
|
+
if (context == "rule") style = "number";
|
|
98
|
+
else if (!context || context == "@media{") style = "tag";
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (context == "rule" && /^[\{\};]$/.test(type))
|
|
102
|
+
state.stack.pop();
|
|
103
|
+
if (type == "{") {
|
|
104
|
+
if (context == "@media") state.stack[state.stack.length-1] = "@media{";
|
|
105
|
+
else state.stack.push("{");
|
|
106
|
+
}
|
|
107
|
+
else if (type == "}") state.stack.pop();
|
|
108
|
+
else if (type == "@media") state.stack.push("@media");
|
|
109
|
+
else if (context == "{" && type != "comment") state.stack.push("rule");
|
|
110
|
+
return style;
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
indent: function(state, textAfter) {
|
|
114
|
+
var n = state.stack.length;
|
|
115
|
+
if (/^\}/.test(textAfter))
|
|
116
|
+
n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1;
|
|
117
|
+
return state.baseIndent + n * indentUnit;
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
electricChars: "}"
|
|
121
|
+
};
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
CodeMirror.defineMIME("text/css", "css");
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>CodeMirror: CSS mode</title>
|
|
5
|
+
<link rel="stylesheet" href="../../lib/codemirror.css">
|
|
6
|
+
<script src="../../lib/codemirror.js"></script>
|
|
7
|
+
<script src="css.js"></script>
|
|
8
|
+
<style>.CodeMirror {background: #f8f8f8;}</style>
|
|
9
|
+
<link rel="stylesheet" href="../../doc/docs.css">
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<h1>CodeMirror: CSS mode</h1>
|
|
13
|
+
<form><textarea id="code" name="code">
|
|
14
|
+
/* Some example CSS */
|
|
15
|
+
|
|
16
|
+
@import url("something.css");
|
|
17
|
+
|
|
18
|
+
body {
|
|
19
|
+
margin: 0;
|
|
20
|
+
padding: 3em 6em;
|
|
21
|
+
font-family: tahoma, arial, sans-serif;
|
|
22
|
+
color: #000;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
#navigation a {
|
|
26
|
+
font-weight: bold;
|
|
27
|
+
text-decoration: none !important;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
h1 {
|
|
31
|
+
font-size: 2.5em;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
h2 {
|
|
35
|
+
font-size: 1.7em;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
h1:before, h2:before {
|
|
39
|
+
content: "::";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
code {
|
|
43
|
+
font-family: courier, monospace;
|
|
44
|
+
font-size: 80%;
|
|
45
|
+
color: #418A8A;
|
|
46
|
+
}
|
|
47
|
+
</textarea></form>
|
|
48
|
+
<script>
|
|
49
|
+
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<p><strong>MIME types defined:</strong> <code>text/css</code>.</p>
|
|
53
|
+
|
|
54
|
+
</body>
|
|
55
|
+
</html>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
CodeMirror.defineMode("diff", function() {
|
|
2
|
+
return {
|
|
3
|
+
token: function(stream) {
|
|
4
|
+
var ch = stream.next();
|
|
5
|
+
stream.skipToEnd();
|
|
6
|
+
if (ch == "+") return "plus";
|
|
7
|
+
if (ch == "-") return "minus";
|
|
8
|
+
if (ch == "@") return "rangeinfo";
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
CodeMirror.defineMIME("text/x-diff", "diff");
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>CodeMirror: Diff mode</title>
|
|
5
|
+
<link rel="stylesheet" href="../../lib/codemirror.css">
|
|
6
|
+
<script src="../../lib/codemirror.js"></script>
|
|
7
|
+
<script src="diff.js"></script>
|
|
8
|
+
<link rel="stylesheet" href="diff.css">
|
|
9
|
+
<style>.CodeMirror {border-top: 1px solid #ddd; border-bottom: 1px solid #ddd;}</style>
|
|
10
|
+
<link rel="stylesheet" href="../../doc/docs.css">
|
|
11
|
+
</head>
|
|
12
|
+
<body>
|
|
13
|
+
<h1>CodeMirror: Diff mode</h1>
|
|
14
|
+
<form><textarea id="code" name="code">
|
|
15
|
+
diff --git a/index.html b/index.html
|
|
16
|
+
index c1d9156..7764744 100644
|
|
17
|
+
--- a/index.html
|
|
18
|
+
+++ b/index.html
|
|
19
|
+
@@ -95,7 +95,8 @@ StringStream.prototype = {
|
|
20
|
+
<script>
|
|
21
|
+
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
|
22
|
+
lineNumbers: true,
|
|
23
|
+
- autoMatchBrackets: true
|
|
24
|
+
+ autoMatchBrackets: true,
|
|
25
|
+
+ onGutterClick: function(x){console.log(x);}
|
|
26
|
+
});
|
|
27
|
+
</script>
|
|
28
|
+
</body>
|
|
29
|
+
diff --git a/lib/codemirror.js b/lib/codemirror.js
|
|
30
|
+
index 04646a9..9a39cc7 100644
|
|
31
|
+
--- a/lib/codemirror.js
|
|
32
|
+
+++ b/lib/codemirror.js
|
|
33
|
+
@@ -399,10 +399,16 @@ var CodeMirror = (function() {
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function onMouseDown(e) {
|
|
37
|
+
- var start = posFromMouse(e), last = start;
|
|
38
|
+
+ var start = posFromMouse(e), last = start, target = e.target();
|
|
39
|
+
if (!start) return;
|
|
40
|
+
setCursor(start.line, start.ch, false);
|
|
41
|
+
if (e.button() != 1) return;
|
|
42
|
+
+ if (target.parentNode == gutter) {
|
|
43
|
+
+ if (options.onGutterClick)
|
|
44
|
+
+ options.onGutterClick(indexOf(gutter.childNodes, target) + showingFrom);
|
|
45
|
+
+ return;
|
|
46
|
+
+ }
|
|
47
|
+
+
|
|
48
|
+
if (!focused) onFocus();
|
|
49
|
+
|
|
50
|
+
e.stop();
|
|
51
|
+
@@ -808,7 +814,7 @@ var CodeMirror = (function() {
|
|
52
|
+
for (var i = showingFrom; i < showingTo; ++i) {
|
|
53
|
+
var marker = lines[i].gutterMarker;
|
|
54
|
+
if (marker) html.push('<div class="' + marker.style + '">' + htmlEscape(marker.text) + '</div>');
|
|
55
|
+
- else html.push("<div>" + (options.lineNumbers ? i + 1 : "\u00a0") + "</div>");
|
|
56
|
+
+ else html.push("<div>" + (options.lineNumbers ? i + options.firstLineNumber : "\u00a0") + "</div>");
|
|
57
|
+
}
|
|
58
|
+
gutter.style.display = "none"; // TODO test whether this actually helps
|
|
59
|
+
gutter.innerHTML = html.join("");
|
|
60
|
+
@@ -1371,10 +1377,8 @@ var CodeMirror = (function() {
|
|
61
|
+
if (option == "parser") setParser(value);
|
|
62
|
+
else if (option === "lineNumbers") setLineNumbers(value);
|
|
63
|
+
else if (option === "gutter") setGutter(value);
|
|
64
|
+
- else if (option === "readOnly") options.readOnly = value;
|
|
65
|
+
- else if (option === "indentUnit") {options.indentUnit = indentUnit = value; setParser(options.parser);}
|
|
66
|
+
- else if (/^(?:enterMode|tabMode|indentWithTabs|readOnly|autoMatchBrackets|undoDepth)$/.test(option)) options[option] = value;
|
|
67
|
+
- else throw new Error("Can't set option " + option);
|
|
68
|
+
+ else if (option === "indentUnit") {options.indentUnit = value; setParser(options.parser);}
|
|
69
|
+
+ else options[option] = value;
|
|
70
|
+
},
|
|
71
|
+
cursorCoords: cursorCoords,
|
|
72
|
+
undo: operation(undo),
|
|
73
|
+
@@ -1402,7 +1406,8 @@ var CodeMirror = (function() {
|
|
74
|
+
replaceRange: operation(replaceRange),
|
|
75
|
+
|
|
76
|
+
operation: function(f){return operation(f)();},
|
|
77
|
+
- refresh: function(){updateDisplay([{from: 0, to: lines.length}]);}
|
|
78
|
+
+ refresh: function(){updateDisplay([{from: 0, to: lines.length}]);},
|
|
79
|
+
+ getInputField: function(){return input;}
|
|
80
|
+
};
|
|
81
|
+
return instance;
|
|
82
|
+
}
|
|
83
|
+
@@ -1420,6 +1425,7 @@ var CodeMirror = (function() {
|
|
84
|
+
readOnly: false,
|
|
85
|
+
onChange: null,
|
|
86
|
+
onCursorActivity: null,
|
|
87
|
+
+ onGutterClick: null,
|
|
88
|
+
autoMatchBrackets: false,
|
|
89
|
+
workTime: 200,
|
|
90
|
+
workDelay: 300,
|
|
91
|
+
</textarea></form>
|
|
92
|
+
<script>
|
|
93
|
+
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
|
|
94
|
+
</script>
|
|
95
|
+
|
|
96
|
+
<p><strong>MIME types defined:</strong> <code>text/x-diff</code>.</p>
|
|
97
|
+
|
|
98
|
+
</body>
|
|
99
|
+
</html>
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
CodeMirror.defineMode("gfm", function(config, parserConfig) {
|
|
2
|
+
var mdMode = CodeMirror.getMode(config, "markdown");
|
|
3
|
+
var aliases = {
|
|
4
|
+
html: "htmlmixed",
|
|
5
|
+
js: "javascript",
|
|
6
|
+
json: "application/json",
|
|
7
|
+
c: "text/x-csrc",
|
|
8
|
+
"c++": "text/x-c++src",
|
|
9
|
+
java: "text/x-java",
|
|
10
|
+
csharp: "text/x-csharp",
|
|
11
|
+
"c#": "text/x-csharp",
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
// make this lazy so that we don't need to load GFM last
|
|
15
|
+
var getMode = (function () {
|
|
16
|
+
var i, modes = {}, mimes = {}, mime;
|
|
17
|
+
|
|
18
|
+
var list = CodeMirror.listModes();
|
|
19
|
+
for (i = 0; i < list.length; i++) {
|
|
20
|
+
modes[list[i]] = list[i];
|
|
21
|
+
}
|
|
22
|
+
var mimesList = CodeMirror.listMIMEs();
|
|
23
|
+
for (i = 0; i < mimesList.length; i++) {
|
|
24
|
+
mime = mimesList[i].mime;
|
|
25
|
+
mimes[mime] = mimesList[i].mime;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
for (var a in aliases) {
|
|
29
|
+
if (aliases[a] in modes || aliases[a] in mimes)
|
|
30
|
+
modes[a] = aliases[a];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return function (lang) {
|
|
34
|
+
return modes[lang] ? CodeMirror.getMode(config, modes[lang]) : null;
|
|
35
|
+
}
|
|
36
|
+
}());
|
|
37
|
+
|
|
38
|
+
function markdown(stream, state) {
|
|
39
|
+
// intercept fenced code blocks
|
|
40
|
+
if (stream.sol() && stream.match(/^```([\w+#]*)/)) {
|
|
41
|
+
// try switching mode
|
|
42
|
+
state.localMode = getMode(RegExp.$1)
|
|
43
|
+
if (state.localMode)
|
|
44
|
+
state.localState = state.localMode.startState();
|
|
45
|
+
|
|
46
|
+
state.token = local;
|
|
47
|
+
return 'code';
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return mdMode.token(stream, state.mdState);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function local(stream, state) {
|
|
54
|
+
if (stream.sol() && stream.match(/^```/)) {
|
|
55
|
+
state.localMode = state.localState = null;
|
|
56
|
+
state.token = markdown;
|
|
57
|
+
return 'code';
|
|
58
|
+
}
|
|
59
|
+
else if (state.localMode) {
|
|
60
|
+
return state.localMode.token(stream, state.localState);
|
|
61
|
+
} else {
|
|
62
|
+
stream.skipToEnd();
|
|
63
|
+
return 'code';
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// custom handleText to prevent emphasis in the middle of a word
|
|
68
|
+
// and add autolinking
|
|
69
|
+
function handleText(stream, mdState) {
|
|
70
|
+
var match;
|
|
71
|
+
if (stream.match(/^\w+:\/\/\S+/)) {
|
|
72
|
+
return 'linkhref';
|
|
73
|
+
}
|
|
74
|
+
if (stream.match(/^[^\[*\\<>` _][^\[*\\<>` ]*[^\[*\\<>` _]/)) {
|
|
75
|
+
return mdMode.getType(mdState);
|
|
76
|
+
}
|
|
77
|
+
if (match = stream.match(/^[^\[*\\<>` ]+/)) {
|
|
78
|
+
var word = match[0];
|
|
79
|
+
if (word[0] === '_' && word[word.length-1] === '_') {
|
|
80
|
+
stream.backUp(word.length);
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
return mdMode.getType(mdState);
|
|
84
|
+
}
|
|
85
|
+
if (stream.eatSpace()) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
startState: function() {
|
|
92
|
+
var mdState = mdMode.startState();
|
|
93
|
+
mdState.text = handleText;
|
|
94
|
+
return {token: markdown, mode: "markdown", mdState: mdState,
|
|
95
|
+
localMode: null, localState: null};
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
copyState: function(state) {
|
|
99
|
+
return {token: state.token, mode: state.mode, mdState: CodeMirror.copyState(mdMode, state.mdState),
|
|
100
|
+
localMode: state.localMode,
|
|
101
|
+
localState: state.localMode ? CodeMirror.copyState(state.localMode, state.localState) : null};
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
token: function(stream, state) {
|
|
105
|
+
return state.token(stream, state);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>CodeMirror: GFM mode</title>
|
|
5
|
+
<link rel="stylesheet" href="../../lib/codemirror.css">
|
|
6
|
+
<script src="../../lib/codemirror.js"></script>
|
|
7
|
+
<script src="../xml/xml.js"></script>
|
|
8
|
+
<script src="../markdown/markdown.js"></script>
|
|
9
|
+
<script src="gfm.js"></script>
|
|
10
|
+
<script src="../javascript/javascript.js"></script>
|
|
11
|
+
<link rel="stylesheet" href="../markdown/markdown.css">
|
|
12
|
+
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
|
13
|
+
<link rel="stylesheet" href="../../doc/docs.css">
|
|
14
|
+
</head>
|
|
15
|
+
<body>
|
|
16
|
+
<h1>CodeMirror: GFM mode</h1>
|
|
17
|
+
|
|
18
|
+
<!-- source: http://daringfireball.net/projects/markdown/basics.text -->
|
|
19
|
+
<form><textarea id="code" name="code">
|
|
20
|
+
Github Flavored Markdown
|
|
21
|
+
========================
|
|
22
|
+
|
|
23
|
+
Everything from markdown plus GFM features:
|
|
24
|
+
|
|
25
|
+
## Fenced code blocks
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
for (var i = 0; i < items.length; i++) {
|
|
29
|
+
console.log(items[i], i); // log them
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
See http://github.github.com/github-flavored-markdown/
|
|
34
|
+
|
|
35
|
+
</textarea></form>
|
|
36
|
+
|
|
37
|
+
<script>
|
|
38
|
+
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
|
39
|
+
mode: 'gfm',
|
|
40
|
+
lineNumbers: true,
|
|
41
|
+
matchBrackets: true,
|
|
42
|
+
theme: "default"
|
|
43
|
+
});
|
|
44
|
+
</script>
|
|
45
|
+
|
|
46
|
+
</body>
|
|
47
|
+
</html>
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
CodeMirror.defineMode("groovy", function(config, parserConfig) {
|
|
2
|
+
function words(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
|
+
var keywords = words(
|
|
8
|
+
"abstract as assert boolean break byte case catch char class const continue def default " +
|
|
9
|
+
"do double else enum extends final finally float for goto if implements import in " +
|
|
10
|
+
"instanceof int interface long native new package private protected public return " +
|
|
11
|
+
"short static strictfp super switch synchronized threadsafe throw throws transient " +
|
|
12
|
+
"try void volatile while");
|
|
13
|
+
var blockKeywords = words("catch class do else finally for if switch try while enum interface def");
|
|
14
|
+
var atoms = words("null true false this");
|
|
15
|
+
|
|
16
|
+
var curPunc;
|
|
17
|
+
function tokenBase(stream, state) {
|
|
18
|
+
var ch = stream.next();
|
|
19
|
+
if (ch == '"' || ch == "'") {
|
|
20
|
+
return startString(ch, stream, state);
|
|
21
|
+
}
|
|
22
|
+
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
|
|
23
|
+
curPunc = ch;
|
|
24
|
+
return null
|
|
25
|
+
}
|
|
26
|
+
if (/\d/.test(ch)) {
|
|
27
|
+
stream.eatWhile(/[\w\.]/);
|
|
28
|
+
if (stream.eat(/eE/)) { stream.eat(/\+\-/); stream.eatWhile(/\d/); }
|
|
29
|
+
return "number";
|
|
30
|
+
}
|
|
31
|
+
if (ch == "/") {
|
|
32
|
+
if (stream.eat("*")) {
|
|
33
|
+
state.tokenize.push(tokenComment);
|
|
34
|
+
return tokenComment(stream, state);
|
|
35
|
+
}
|
|
36
|
+
if (stream.eat("/")) {
|
|
37
|
+
stream.skipToEnd();
|
|
38
|
+
return "comment";
|
|
39
|
+
}
|
|
40
|
+
if (expectExpression(state.lastToken)) {
|
|
41
|
+
return startString(ch, stream, state);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (ch == "-" && stream.eat(">")) {
|
|
45
|
+
curPunc = "->";
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
if (/[+\-*&%=<>!?|\/~]/.test(ch)) {
|
|
49
|
+
stream.eatWhile(/[+\-*&%=<>|~]/);
|
|
50
|
+
return "operator";
|
|
51
|
+
}
|
|
52
|
+
stream.eatWhile(/[\w\$_]/);
|
|
53
|
+
if (ch == "@") { stream.eatWhile(/[\w\$_\.]/); return "meta"; }
|
|
54
|
+
if (state.lastToken == ".") return "property";
|
|
55
|
+
if (stream.eat(":")) { curPunc = "proplabel"; return "property"; }
|
|
56
|
+
var cur = stream.current();
|
|
57
|
+
if (atoms.propertyIsEnumerable(cur)) { return "atom"; }
|
|
58
|
+
if (keywords.propertyIsEnumerable(cur)) {
|
|
59
|
+
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
|
|
60
|
+
return "keyword";
|
|
61
|
+
}
|
|
62
|
+
return "word";
|
|
63
|
+
}
|
|
64
|
+
tokenBase.isBase = true;
|
|
65
|
+
|
|
66
|
+
function startString(quote, stream, state) {
|
|
67
|
+
var tripleQuoted = false;
|
|
68
|
+
if (quote != "/" && stream.eat(quote)) {
|
|
69
|
+
if (stream.eat(quote)) tripleQuoted = true;
|
|
70
|
+
else return "string";
|
|
71
|
+
}
|
|
72
|
+
function t(stream, state) {
|
|
73
|
+
var escaped = false, next, end = !tripleQuoted;
|
|
74
|
+
while ((next = stream.next()) != null) {
|
|
75
|
+
if (next == quote && !escaped) {
|
|
76
|
+
if (!tripleQuoted) { break; }
|
|
77
|
+
if (stream.match(quote + quote)) { end = true; break; }
|
|
78
|
+
}
|
|
79
|
+
if (quote == '"' && next == "$" && !escaped && stream.eat("{")) {
|
|
80
|
+
state.tokenize.push(tokenBaseUntilBrace());
|
|
81
|
+
return "string";
|
|
82
|
+
}
|
|
83
|
+
escaped = !escaped && next == "\\";
|
|
84
|
+
}
|
|
85
|
+
if (end) state.tokenize.pop();
|
|
86
|
+
return "string";
|
|
87
|
+
}
|
|
88
|
+
state.tokenize.push(t);
|
|
89
|
+
return t(stream, state);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function tokenBaseUntilBrace() {
|
|
93
|
+
var depth = 1;
|
|
94
|
+
function t(stream, state) {
|
|
95
|
+
if (stream.peek() == "}") {
|
|
96
|
+
depth--;
|
|
97
|
+
if (depth == 0) {
|
|
98
|
+
state.tokenize.pop();
|
|
99
|
+
return state.tokenize[state.tokenize.length-1](stream, state);
|
|
100
|
+
}
|
|
101
|
+
} else if (stream.peek() == "{") {
|
|
102
|
+
depth++;
|
|
103
|
+
}
|
|
104
|
+
return tokenBase(stream, state);
|
|
105
|
+
}
|
|
106
|
+
t.isBase = true;
|
|
107
|
+
return t;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function tokenComment(stream, state) {
|
|
111
|
+
var maybeEnd = false, ch;
|
|
112
|
+
while (ch = stream.next()) {
|
|
113
|
+
if (ch == "/" && maybeEnd) {
|
|
114
|
+
state.tokenize.pop();
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
maybeEnd = (ch == "*");
|
|
118
|
+
}
|
|
119
|
+
return "comment";
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function expectExpression(last) {
|
|
123
|
+
return !last || last == "operator" || last == "->" || /[\.\[\{\(,;:]/.test(last) ||
|
|
124
|
+
last == "newstatement" || last == "keyword" || last == "proplabel";
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function Context(indented, column, type, align, prev) {
|
|
128
|
+
this.indented = indented;
|
|
129
|
+
this.column = column;
|
|
130
|
+
this.type = type;
|
|
131
|
+
this.align = align;
|
|
132
|
+
this.prev = prev;
|
|
133
|
+
}
|
|
134
|
+
function pushContext(state, col, type) {
|
|
135
|
+
return state.context = new Context(state.indented, col, type, null, state.context);
|
|
136
|
+
}
|
|
137
|
+
function popContext(state) {
|
|
138
|
+
var t = state.context.type;
|
|
139
|
+
if (t == ")" || t == "]" || t == "}")
|
|
140
|
+
state.indented = state.context.indented;
|
|
141
|
+
return state.context = state.context.prev;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Interface
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
startState: function(basecolumn) {
|
|
148
|
+
return {
|
|
149
|
+
tokenize: [tokenBase],
|
|
150
|
+
context: new Context((basecolumn || 0) - config.indentUnit, 0, "top", false),
|
|
151
|
+
indented: 0,
|
|
152
|
+
startOfLine: true,
|
|
153
|
+
lastToken: null
|
|
154
|
+
};
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
token: function(stream, state) {
|
|
158
|
+
var ctx = state.context;
|
|
159
|
+
if (stream.sol()) {
|
|
160
|
+
if (ctx.align == null) ctx.align = false;
|
|
161
|
+
state.indented = stream.indentation();
|
|
162
|
+
state.startOfLine = true;
|
|
163
|
+
// Automatic semicolon insertion
|
|
164
|
+
if (ctx.type == "statement" && !expectExpression(state.lastToken)) {
|
|
165
|
+
popContext(state); ctx = state.context;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (stream.eatSpace()) return null;
|
|
169
|
+
curPunc = null;
|
|
170
|
+
var style = state.tokenize[state.tokenize.length-1](stream, state);
|
|
171
|
+
if (style == "comment") return style;
|
|
172
|
+
if (ctx.align == null) ctx.align = true;
|
|
173
|
+
|
|
174
|
+
if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
|
|
175
|
+
// Handle indentation for {x -> \n ... }
|
|
176
|
+
else if (curPunc == "->" && ctx.type == "statement" && ctx.prev.type == "}") {
|
|
177
|
+
popContext(state);
|
|
178
|
+
state.context.align = false;
|
|
179
|
+
}
|
|
180
|
+
else if (curPunc == "{") pushContext(state, stream.column(), "}");
|
|
181
|
+
else if (curPunc == "[") pushContext(state, stream.column(), "]");
|
|
182
|
+
else if (curPunc == "(") pushContext(state, stream.column(), ")");
|
|
183
|
+
else if (curPunc == "}") {
|
|
184
|
+
while (ctx.type == "statement") ctx = popContext(state);
|
|
185
|
+
if (ctx.type == "}") ctx = popContext(state);
|
|
186
|
+
while (ctx.type == "statement") ctx = popContext(state);
|
|
187
|
+
}
|
|
188
|
+
else if (curPunc == ctx.type) popContext(state);
|
|
189
|
+
else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
|
|
190
|
+
pushContext(state, stream.column(), "statement");
|
|
191
|
+
state.startOfLine = false;
|
|
192
|
+
state.lastToken = curPunc || style;
|
|
193
|
+
return style;
|
|
194
|
+
},
|
|
195
|
+
|
|
196
|
+
indent: function(state, textAfter) {
|
|
197
|
+
if (!state.tokenize[state.tokenize.length-1].isBase) return 0;
|
|
198
|
+
var firstChar = textAfter && textAfter.charAt(0), ctx = state.context;
|
|
199
|
+
if (ctx.type == "statement" && !expectExpression(state.lastToken)) ctx = ctx.prev;
|
|
200
|
+
var closing = firstChar == ctx.type;
|
|
201
|
+
if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : config.indentUnit);
|
|
202
|
+
else if (ctx.align) return ctx.column + (closing ? 0 : 1);
|
|
203
|
+
else return ctx.indented + (closing ? 0 : config.indentUnit);
|
|
204
|
+
},
|
|
205
|
+
|
|
206
|
+
electricChars: "{}"
|
|
207
|
+
};
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
CodeMirror.defineMIME("text/x-groovy", "groovy");
|