aboutsummaryrefslogtreecommitdiff
path: root/imports/codemirror/mode/tiddlywiki/tiddlywiki.js
diff options
context:
space:
mode:
Diffstat (limited to 'imports/codemirror/mode/tiddlywiki/tiddlywiki.js')
-rwxr-xr-ximports/codemirror/mode/tiddlywiki/tiddlywiki.js374
1 files changed, 374 insertions, 0 deletions
diff --git a/imports/codemirror/mode/tiddlywiki/tiddlywiki.js b/imports/codemirror/mode/tiddlywiki/tiddlywiki.js
new file mode 100755
index 00000000..e07124c2
--- /dev/null
+++ b/imports/codemirror/mode/tiddlywiki/tiddlywiki.js
@@ -0,0 +1,374 @@
1/***
2 |''Name''|tiddlywiki.js|
3 |''Description''|Enables TiddlyWikiy syntax highlighting using CodeMirror2|
4 |''Author''|PMario|
5 |''Version''|0.1.6|
6 |''Status''|''beta''|
7 |''Source''|[[GitHub|https://github.com/pmario/CodeMirror2/blob/tw-syntax/mode/tiddlywiki]]|
8 |''Documentation''|http://codemirror.tiddlyspace.com/|
9 |''License''|[[MIT License|http://www.opensource.org/licenses/mit-license.php]]|
10 |''CoreVersion''|2.5.0|
11 |''Requires''|codemirror.js|
12 |''Keywords''|syntax highlighting color code mirror codemirror|
13 ! Info
14 CoreVersion parameter is needed for TiddlyWiki only!
15 ***/
16//{{{
17CodeMirror.defineMode("tiddlywiki", function (config, parserConfig) {
18 var indentUnit = config.indentUnit;
19
20 // Tokenizer
21 var textwords = function () {
22 function kw(type) {
23 return {
24 type: type,
25 style: "text"
26 };
27 }
28 return {};
29 }();
30
31 var keywords = function () {
32 function kw(type) {
33 return { type: type, style: "macro"};
34 }
35 return {
36 "allTags": kw('allTags'), "closeAll": kw('closeAll'), "list": kw('list'),
37 "newJournal": kw('newJournal'), "newTiddler": kw('newTiddler'),
38 "permaview": kw('permaview'), "saveChanges": kw('saveChanges'),
39 "search": kw('search'), "slider": kw('slider'), "tabs": kw('tabs'),
40 "tag": kw('tag'), "tagging": kw('tagging'), "tags": kw('tags'),
41 "tiddler": kw('tiddler'), "timeline": kw('timeline'),
42 "today": kw('today'), "version": kw('version'), "option": kw('option'),
43
44 "with": kw('with'),
45 "filter": kw('filter')
46 };
47 }();
48
49 var isSpaceName = /[\w_\-]/i,
50 reHR = /^\-\-\-\-+$/,
51 reWikiCommentStart = /^\/\*\*\*$/, // /***
52 reWikiCommentStop = /^\*\*\*\/$/, // ***/
53 reBlockQuote = /^<<<$/,
54
55 reJsCodeStart = /^\/\/\{\{\{$/, // //{{{
56 reJsCodeStop = /^\/\/\}\}\}$/, // //}}}
57 reXmlCodeStart = /^<!--\{\{\{-->$/,
58 reXmlCodeStop = /^<!--\}\}\}-->$/,
59
60 reCodeBlockStart = /^\{\{\{$/,
61 reCodeBlockStop = /^\}\}\}$/,
62
63 reCodeStart = /\{\{\{/,
64 reUntilCodeStop = /.*?\}\}\}/;
65
66 function chain(stream, state, f) {
67 state.tokenize = f;
68 return f(stream, state);
69 }
70
71 // used for strings
72 function nextUntilUnescaped(stream, end) {
73 var escaped = false,
74 next;
75 while ((next = stream.next()) != null) {
76 if (next == end && !escaped) return false;
77 escaped = !escaped && next == "\\";
78 }
79 return escaped;
80 }
81
82 // Used as scratch variables to communicate multiple values without
83 // consing up tons of objects.
84 var type, content;
85
86 function ret(tp, style, cont) {
87 type = tp;
88 content = cont;
89 return style;
90 }
91
92 function jsTokenBase(stream, state) {
93 var sol = stream.sol(),
94 ch, tch;
95
96 state.block = false; // indicates the start of a code block.
97
98 ch = stream.peek(); // don't eat, to make match simpler
99
100 // check start of blocks
101 if (sol && /[<\/\*{}\-]/.test(ch)) {
102 if (stream.match(reCodeBlockStart)) {
103 state.block = true;
104 return chain(stream, state, twTokenCode);
105 }
106 if (stream.match(reBlockQuote)) {
107 return ret('quote', 'quote');
108 }
109 if (stream.match(reWikiCommentStart) || stream.match(reWikiCommentStop)) {
110 return ret('code', 'code');
111 }
112 if (stream.match(reJsCodeStart) || stream.match(reJsCodeStop) || stream.match(reXmlCodeStart) || stream.match(reXmlCodeStop)) {
113 return ret('code', 'code');
114 }
115 if (stream.match(reHR)) {
116 return ret('hr', 'hr');
117 }
118 } // sol
119 var ch = stream.next();
120
121 if (sol && /[\/\*!#;:>|]/.test(ch)) {
122 if (ch == "!") { // tw header
123 stream.skipToEnd();
124 return ret("header", "header");
125 }
126 if (ch == "*") { // tw list
127 stream.eatWhile('*');
128 return ret("list", "list");
129 }
130 if (ch == "#") { // tw numbered list
131 stream.eatWhile('#');
132 return ret("list", "list");
133 }
134 if (ch == ";") { // tw list
135 stream.eatWhile(';');
136 return ret("list", "list");
137 }
138 if (ch == ":") { // tw list
139 stream.eatWhile(':');
140 return ret("list", "list");
141 }
142 if (ch == ">") { // single line quote
143 stream.eatWhile(">");
144 return ret("quote", "quote");
145 }
146 if (ch == '|') {
147 return ret('table', 'table');
148 }
149 }
150
151 if (ch == '{' && stream.match(/\{\{/)) {
152 return chain(stream, state, twTokenCode);
153 }
154
155 // rudimentary html:// file:// link matching. TW knows much more ...
156 if (/[hf]/i.test(ch)) {
157 if (/[ti]/i.test(stream.peek()) && stream.match(/\b(ttps?|tp|ile):\/\/[\-A-Z0-9+&@#\/%?=~_|$!:,.;]*[A-Z0-9+&@#\/%=~_|$]/i)) {
158 return ret("link-external", "link-external");
159 }
160 }
161 // just a little string indicator, don't want to have the whole string covered
162 if (ch == '"') {
163 return ret('string', 'string');
164 }
165 if (/[\[\]]/.test(ch)) { // check for [[..]]
166 if (stream.peek() == ch) {
167 stream.next();
168 return ret('brace', 'brace');
169 }
170 }
171 if (ch == "@") { // check for space link. TODO fix @@...@@ highlighting
172 stream.eatWhile(isSpaceName);
173 return ret("link-external", "link-external");
174 }
175 if (/\d/.test(ch)) { // numbers
176 stream.eatWhile(/\d/);
177 return ret("number", "number");
178 }
179 if (ch == "/") { // tw invisible comment
180 if (stream.eat("%")) {
181 return chain(stream, state, twTokenComment);
182 }
183 else if (stream.eat("/")) { //
184 return chain(stream, state, twTokenEm);
185 }
186 }
187 if (ch == "_") { // tw underline
188 if (stream.eat("_")) {
189 return chain(stream, state, twTokenUnderline);
190 }
191 }
192 if (ch == "-") { // tw strikethrough TODO looks ugly .. different handling see below;
193 if (stream.eat("-")) {
194 return chain(stream, state, twTokenStrike);
195 }
196 }
197 if (ch == "'") { // tw bold
198 if (stream.eat("'")) {
199 return chain(stream, state, twTokenStrong);
200 }
201 }
202 if (ch == "<") { // tw macro
203 if (stream.eat("<")) {
204 return chain(stream, state, twTokenMacro);
205 }
206 }
207 else {
208 return ret(ch);
209 }
210
211 stream.eatWhile(/[\w\$_]/);
212 var word = stream.current(),
213 known = textwords.propertyIsEnumerable(word) && textwords[word];
214
215 return known ? ret(known.type, known.style, word) : ret("text", null, word);