aboutsummaryrefslogtreecommitdiff
path: root/imports/codemirror/mode/tiki/tiki.js
diff options
context:
space:
mode:
Diffstat (limited to 'imports/codemirror/mode/tiki/tiki.js')
-rw-r--r--imports/codemirror/mode/tiki/tiki.js316
1 files changed, 316 insertions, 0 deletions
diff --git a/imports/codemirror/mode/tiki/tiki.js b/imports/codemirror/mode/tiki/tiki.js
new file mode 100644
index 00000000..350dd51b
--- /dev/null
+++ b/imports/codemirror/mode/tiki/tiki.js
@@ -0,0 +1,316 @@
1CodeMirror.defineMode('tiki', function(config, parserConfig) {
2 function inBlock(style, terminator, returnTokenizer) {
3 return function(stream, state) {
4 while (!stream.eol()) {
5 if (stream.match(terminator)) {
6 state.tokenize = inText;
7 break;
8 }
9 stream.next();
10 }
11
12 if (returnTokenizer) state.tokenize = returnTokenizer;
13
14 return style;
15 };
16 }
17
18 function inLine(style, terminator) {
19 return function(stream, state) {
20 while(!stream.eol()) {
21 stream.next()
22 }
23 state.tokenize = inText;
24 return style;
25 };
26 }
27
28 function inText(stream, state) {
29 function chain(parser) {
30 state.tokenize = parser;
31 return parser(stream, state);
32 }
33
34 var sol = stream.sol();
35 var ch = stream.next();
36
37 //non start of line
38 switch (ch) { //switch is generally much faster than if, so it is used here
39 case "{": //plugin
40 type = stream.eat("/") ? "closeTag" : "openTag";
41 stream.eatSpace();
42 tagName = "";
43 var c;
44 while ((c = stream.eat(/[^\s\u00a0=\"\'\/?(}]/))) tagName += c;
45 state.tokenize = inPlugin;
46 return "tag";
47 break;
48 case "_": //bold
49 if (stream.eat("_")) {
50 return chain(inBlock("strong", "__", inText));
51 }
52 break;
53 case "'": //italics
54 if (stream.eat("'")) {
55 // Italic text
56 return chain(inBlock("em", "''", inText));
57 }
58 break;
59 case "(":// Wiki Link
60 if (stream.eat("(")) {
61 return chain(inBlock("variable-2", "))", inText));
62 }
63 break;
64 case "[":// Weblink
65 return chain(inBlock("variable-3", "]", inText));
66 break;
67 case "|": //table
68 if (stream.eat("|")) {
69 return chain(inBlock("comment", "||"));
70 }
71 break;
72 case "-":
73 if (stream.eat("=")) {//titleBar
74 return chain(inBlock("header string", "=-", inText));
75 } else if (stream.eat("-")) {//deleted
76 return chain(inBlock("error tw-deleted", "--", inText));
77 }
78 break;
79 case "=": //underline
80 if (stream.match("==")) {
81 return chain(inBlock("tw-underline", "===", inText));
82 }
83 break;
84 case ":":
85 if (stream.eat(":")) {
86 return chain(inBlock("comment", "::"));
87 }
88 break;
89 case "^": //box
90 return chain(inBlock("tw-box", "^"));
91 break;
92 case "~": //np
93 if (stream.match("np~")) {
94 return chain(inBlock("meta", "~/np~"));
95 }
96 break;
97 }
98
99 //start of line types
100 if (sol) {
101 switch (ch) {
102 case "!": //header at start of line
103 if (stream.match('!!!!!')) {
104 return chain(inLine("header string"));
105 } else if (stream.match('!!!!')) {
106 return chain(inLine("header string"));
107 } else if (stream.match('!!!')) {
108 return chain(inLine("header string"));
109 } else if (stream.match('!!')) {
110 return chain(inLine("header string"));
111 } else {
112 return chain(inLine("header string"));
113 }
114 break;
115 case "*": //unordered list line item, or <li /> at start of line
116 case "#": //ordered list line item, or <li /> at start of line
117 case "+": //ordered list line item, or <li /> at start of line
118 return chain(inLine("tw-listitem bracket"));
119 break;
120 }
121 }
122
123 //stream.eatWhile(/[&{]/); was eating up plugins, turned off to act less like html and more like tiki
124 return null;
125 }
126
127 var indentUnit = config.indentUnit;
128
129 // Return variables for tokenizers
130 var pluginName, type;
131 function inPlugin(stream, state) {
132 var ch = stream.next();
133 var peek = stream.peek();
134
135 if (ch == "}") {
136 state.tokenize = inText;
137 //type = ch == ")" ? "endPlugin" : "selfclosePlugin"; inPlugin
138 return "tag";
139 } else if (ch == "(" || ch == ")") {
140 return "bracket";
141 } else if (ch == "=") {
142 type = "equals";
143
144 if (peek == ">") {
145 ch = stream.next();
146 peek = stream.peek();
147 }
148
149 //here we detect values directly after equal character with no quotes
150 if (!/[\'\"]/.test(peek)) {
151 state.tokenize = inAttributeNoQuote();
152 }
153 //end detect values
154
155 return "operator";
156 } else if (/[\'\"]/.test(ch)) {
157 state.tokenize = inAttribute(ch);
158 return state.tokenize(stream, state);
159 } else {
160 stream.eatWhile(/[^\s\u00a0=\"\'\/?]/);
161 return "keyword";
162 }
163 }
164
165 function inAttribute(quote) {
166 return function(stream, state) {
167 while (!stream.eol()) {
168 if (stream.next() == quote) {
169 state.tokenize = inPlugin;
170 break;
171 }
172 }
173 return "string";
174 };
175 }
176
177 function inAttributeNoQuote() {
178 return function(stream, state) {
179 while (!stream.eol()) {
180 var ch = stream.next();
181 var peek = stream.peek();
182 if (ch == " " || ch == "," || /[ )}]/.test(peek)) {
183 state.tokenize = inPlugin;
184 break;
185 }
186 }
187 return "string";
188 };
189 }
190
191 var curState, setStyle;
192 function pass() {
193 for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
194 }
195
196 function cont() {
197 pass.apply(null, arguments);
198 return true;
199 }
200
201 function pushContext(pluginName, startOfLine) {
202 var noIndent = curState.context && curState.context.noIndent;
203 curState.context = {
204 prev: curState.context,
205 pluginName: pluginName,
206 indent: curState.indented,
207 startOfLine: startOfLine,
208 noIndent: noIndent
209 };
210 }
211
212 function popContext() {
213 if (curState.context) curState.context = curState.context.prev;
214 }
215
216 function element(type) {
217 if (type == "openPlugin") {curState.pluginName = pluginName; return cont(attributes, endplugin(curState.startOfLine));}
218 else if (type == "closePlugin") {
219 var err = false;
220 if (curState.context) {
221 err = curState.context.pluginName != pluginName;
222 popContext();
223 } else {
224 err = true;
225 }