diff options
Diffstat (limited to 'imports/codemirror/mode/tiki/tiki.js')
-rw-r--r-- | imports/codemirror/mode/tiki/tiki.js | 316 |
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 @@ | |||
1 | CodeMirror.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 | } | ||