File modules/editor/codemirror/mode/tiddlywiki/tiddlywiki.js

Last commit: Sun Dec 17 01:14:09 2017 +0100	Jan Dankert	Integration eines weiteren Code-Editors: Codemirror. Demnächst müssen wir hier mal aufräumen und andere Editoren rauswerfen.
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 // Distributed under an MIT license: http://codemirror.net/LICENSE 3 4 /*** 5 |''Name''|tiddlywiki.js| 6 |''Description''|Enables TiddlyWikiy syntax highlighting using CodeMirror| 7 |''Author''|PMario| 8 |''Version''|0.1.7| 9 |''Status''|''stable''| 10 |''Source''|[[GitHub|https://github.com/pmario/CodeMirror2/blob/tw-syntax/mode/tiddlywiki]]| 11 |''Documentation''|http://codemirror.tiddlyspace.com/| 12 |''License''|[[MIT License|http://www.opensource.org/licenses/mit-license.php]]| 13 |''CoreVersion''|2.5.0| 14 |''Requires''|codemirror.js| 15 |''Keywords''|syntax highlighting color code mirror codemirror| 16 ! Info 17 CoreVersion parameter is needed for TiddlyWiki only! 18 ***/ 19 20 (function(mod) { 21 if (typeof exports == "object" && typeof module == "object") // CommonJS 22 mod(require("../../lib/codemirror")); 23 else if (typeof define == "function" && define.amd) // AMD 24 define(["../../lib/codemirror"], mod); 25 else // Plain browser env 26 mod(CodeMirror); 27 })(function(CodeMirror) { 28 "use strict"; 29 30 CodeMirror.defineMode("tiddlywiki", function () { 31 // Tokenizer 32 var textwords = {}; 33 34 var keywords = { 35 "allTags": true, "closeAll": true, "list": true, 36 "newJournal": true, "newTiddler": true, 37 "permaview": true, "saveChanges": true, 38 "search": true, "slider": true, "tabs": true, 39 "tag": true, "tagging": true, "tags": true, 40 "tiddler": true, "timeline": true, 41 "today": true, "version": true, "option": true, 42 "with": true, "filter": true 43 }; 44 45 var isSpaceName = /[\w_\-]/i, 46 reHR = /^\-\-\-\-+$/, // <hr> 47 reWikiCommentStart = /^\/\*\*\*$/, // /*** 48 reWikiCommentStop = /^\*\*\*\/$/, // ***/ 49 reBlockQuote = /^<<<$/, 50 51 reJsCodeStart = /^\/\/\{\{\{$/, // //{{{ js block start 52 reJsCodeStop = /^\/\/\}\}\}$/, // //}}} js stop 53 reXmlCodeStart = /^<!--\{\{\{-->$/, // xml block start 54 reXmlCodeStop = /^<!--\}\}\}-->$/, // xml stop 55 56 reCodeBlockStart = /^\{\{\{$/, // {{{ TW text div block start 57 reCodeBlockStop = /^\}\}\}$/, // }}} TW text stop 58 59 reUntilCodeStop = /.*?\}\}\}/; 60 61 function chain(stream, state, f) { 62 state.tokenize = f; 63 return f(stream, state); 64 } 65 66 function tokenBase(stream, state) { 67 var sol = stream.sol(), ch = stream.peek(); 68 69 state.block = false; // indicates the start of a code block. 70 71 // check start of blocks 72 if (sol && /[<\/\*{}\-]/.test(ch)) { 73 if (stream.match(reCodeBlockStart)) { 74 state.block = true; 75 return chain(stream, state, twTokenCode); 76 } 77 if (stream.match(reBlockQuote)) 78 return 'quote'; 79 if (stream.match(reWikiCommentStart) || stream.match(reWikiCommentStop)) 80 return 'comment'; 81 if (stream.match(reJsCodeStart) || stream.match(reJsCodeStop) || stream.match(reXmlCodeStart) || stream.match(reXmlCodeStop)) 82 return 'comment'; 83 if (stream.match(reHR)) 84 return 'hr'; 85 } 86 87 stream.next(); 88 if (sol && /[\/\*!#;:>|]/.test(ch)) { 89 if (ch == "!") { // tw header 90 stream.skipToEnd(); 91 return "header"; 92 } 93 if (ch == "*") { // tw list 94 stream.eatWhile('*'); 95 return "comment"; 96 } 97 if (ch == "#") { // tw numbered list 98 stream.eatWhile('#'); 99 return "comment"; 100 } 101 if (ch == ";") { // definition list, term 102 stream.eatWhile(';'); 103 return "comment"; 104 } 105 if (ch == ":") { // definition list, description 106 stream.eatWhile(':'); 107 return "comment"; 108 } 109 if (ch == ">") { // single line quote 110 stream.eatWhile(">"); 111 return "quote"; 112 } 113 if (ch == '|') 114 return 'header'; 115 } 116 117 if (ch == '{' && stream.match(/\{\{/)) 118 return chain(stream, state, twTokenCode); 119 120 // rudimentary html:// file:// link matching. TW knows much more ... 121 if (/[hf]/i.test(ch) && 122 /[ti]/i.test(stream.peek()) && 123 stream.match(/\b(ttps?|tp|ile):\/\/[\-A-Z0-9+&@#\/%?=~_|$!:,.;]*[A-Z0-9+&@#\/%=~_|$]/i)) 124 return "link"; 125 126 // just a little string indicator, don't want to have the whole string covered 127 if (ch == '"') 128 return 'string'; 129 130 if (ch == '~') // _no_ CamelCase indicator should be bold 131 return 'brace'; 132 133 if (/[\[\]]/.test(ch) && stream.match(ch)) // check for [[..]] 134 return 'brace'; 135 136 if (ch == "@") { // check for space link. TODO fix @@...@@ highlighting 137 stream.eatWhile(isSpaceName); 138 return "link"; 139 } 140 141 if (/\d/.test(ch)) { // numbers 142 stream.eatWhile(/\d/); 143 return "number"; 144 } 145 146 if (ch == "/") { // tw invisible comment 147 if (stream.eat("%")) { 148 return chain(stream, state, twTokenComment); 149 } else if (stream.eat("/")) { // 150 return chain(stream, state, twTokenEm); 151 } 152 } 153 154 if (ch == "_" && stream.eat("_")) // tw underline 155 return chain(stream, state, twTokenUnderline); 156 157 // strikethrough and mdash handling 158 if (ch == "-" && stream.eat("-")) { 159 // if strikethrough looks ugly, change CSS. 160 if (stream.peek() != ' ') 161 return chain(stream, state, twTokenStrike); 162 // mdash 163 if (stream.peek() == ' ') 164 return 'brace'; 165 } 166 167 if (ch == "'" && stream.eat("'")) // tw bold 168 return chain(stream, state, twTokenStrong); 169 170 if (ch == "<" && stream.eat("<")) // tw macro 171 return chain(stream, state, twTokenMacro); 172 173 // core macro handling 174 stream.eatWhile(/[\w\$_]/); 175 return textwords.propertyIsEnumerable(stream.current()) ? "keyword" : null 176 } 177 178 // tw invisible comment 179 function twTokenComment(stream, state) { 180 var maybeEnd = false, ch; 181 while (ch = stream.next()) { 182 if (ch == "/" && maybeEnd) { 183 state.tokenize = tokenBase; 184 break; 185 } 186 maybeEnd = (ch == "%"); 187 } 188 return "comment"; 189 } 190 191 // tw strong / bold 192 function twTokenStrong(stream, state) { 193 var maybeEnd = false, 194 ch; 195 while (ch = stream.next()) { 196 if (ch == "'" && maybeEnd) { 197 state.tokenize = tokenBase; 198 break; 199 } 200 maybeEnd = (ch == "'"); 201 } 202 return "strong"; 203 } 204 205 // tw code 206 function twTokenCode(stream, state) { 207 var sb = state.block; 208 209 if (sb && stream.current()) { 210 return "comment"; 211 } 212 213 if (!sb && stream.match(reUntilCodeStop)) { 214 state.tokenize = tokenBase; 215 return "comment"; 216 } 217 218 if (sb && stream.sol() && stream.match(reCodeBlockStop)) { 219 state.tokenize = tokenBase; 220 return "comment"; 221 } 222 223 stream.next(); 224 return "comment"; 225 } 226 227 // tw em / italic 228 function twTokenEm(stream, state) { 229 var maybeEnd = false, 230 ch; 231 while (ch = stream.next()) { 232 if (ch == "/" && maybeEnd) { 233 state.tokenize = tokenBase; 234 break; 235 } 236 maybeEnd = (ch == "/"); 237 } 238 return "em"; 239 } 240 241 // tw underlined text 242 function twTokenUnderline(stream, state) { 243 var maybeEnd = false, 244 ch; 245 while (ch = stream.next()) { 246 if (ch == "_" && maybeEnd) { 247 state.tokenize = tokenBase; 248 break; 249 } 250 maybeEnd = (ch == "_"); 251 } 252 return "underlined"; 253 } 254 255 // tw strike through text looks ugly 256 // change CSS if needed 257 function twTokenStrike(stream, state) { 258 var maybeEnd = false, ch; 259 260 while (ch = stream.next()) { 261 if (ch == "-" && maybeEnd) { 262 state.tokenize = tokenBase; 263 break; 264 } 265 maybeEnd = (ch == "-"); 266 } 267 return "strikethrough"; 268 } 269 270 // macro 271 function twTokenMacro(stream, state) { 272 if (stream.current() == '<<') { 273 return 'macro'; 274 } 275 276 var ch = stream.next(); 277 if (!ch) { 278 state.tokenize = tokenBase; 279 return null; 280 } 281 if (ch == ">") { 282 if (stream.peek() == '>') { 283 stream.next(); 284 state.tokenize = tokenBase; 285 return "macro"; 286 } 287 } 288 289 stream.eatWhile(/[\w\$_]/); 290 return keywords.propertyIsEnumerable(stream.current()) ? "keyword" : null 291 } 292 293 // Interface 294 return { 295 startState: function () { 296 return {tokenize: tokenBase}; 297 }, 298 299 token: function (stream, state) { 300 if (stream.eatSpace()) return null; 301 var style = state.tokenize(stream, state); 302 return style; 303 } 304 }; 305 }); 306 307 CodeMirror.defineMIME("text/x-tiddlywiki", "tiddlywiki"); 308 });
Download modules/editor/codemirror/mode/tiddlywiki/tiddlywiki.js
History Sun, 17 Dec 2017 01:14:09 +0100 Jan Dankert Integration eines weiteren Code-Editors: Codemirror. Demnächst müssen wir hier mal aufräumen und andere Editoren rauswerfen.