aboutsummaryrefslogtreecommitdiff
path: root/imports/codemirror/mode/velocity
diff options
context:
space:
mode:
authorArmen Kesablyan2012-02-22 16:26:41 -0800
committerArmen Kesablyan2012-02-22 16:26:41 -0800
commit0bd1cefea2ab350fad1a891bdc926053b799aafc (patch)
tree962f559fcc02a3dfeb297d59907e40fa153453f3 /imports/codemirror/mode/velocity
parent695bc5082f48dddf66ce31480a4faefc067b38bd (diff)
parent2d2b1af8b5c0d506fe6a1cf65614101fec145970 (diff)
downloadninja-0bd1cefea2ab350fad1a891bdc926053b799aafc.tar.gz
Merge branch 'refs/heads/master' into new-tool-icons
Diffstat (limited to 'imports/codemirror/mode/velocity')
-rwxr-xr-ximports/codemirror/mode/velocity/index.html103
-rwxr-xr-ximports/codemirror/mode/velocity/velocity.js146
2 files changed, 249 insertions, 0 deletions
diff --git a/imports/codemirror/mode/velocity/index.html b/imports/codemirror/mode/velocity/index.html
new file mode 100755
index 00000000..49dba382
--- /dev/null
+++ b/imports/codemirror/mode/velocity/index.html
@@ -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
81The RHS can also be a simple arithmetic expression, such as:
82Addition: #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>
diff --git a/imports/codemirror/mode/velocity/velocity.js b/imports/codemirror/mode/velocity/velocity.js
new file mode 100755
index 00000000..0b80c758
--- /dev/null
+++ b/imports/codemirror/mode/velocity/velocity.js
@@ -0,0 +1,146 @@
1CodeMirror.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;