| 
									
										
										
										
											2018-01-21 10:33:32 -05:00
										 |  |  | // CodeMirror, copyright (c) by Marijn Haverbeke and others
 | 
					
						
							| 
									
										
										
										
											2022-10-15 12:22:09 +02:00
										 |  |  | // Distributed under an MIT license: https://codemirror.net/5/LICENSE
 | 
					
						
							| 
									
										
										
										
											2018-01-21 10:33:32 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | (function(mod) { | 
					
						
							|  |  |  |   if (typeof exports == "object" && typeof module == "object") { // CommonJS
 | 
					
						
							|  |  |  |     mod(require("../../lib/codemirror")); | 
					
						
							|  |  |  |   } else if (typeof define == "function" && define.amd) { // AMD
 | 
					
						
							|  |  |  |     define(["../../lib/codemirror"], mod); | 
					
						
							|  |  |  |   } else { // Plain browser env
 | 
					
						
							|  |  |  |     mod(CodeMirror); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | })(function(CodeMirror) { | 
					
						
							|  |  |  |   "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var TOKEN_STYLES = { | 
					
						
							|  |  |  |     addition: "positive", | 
					
						
							|  |  |  |     attributes: "attribute", | 
					
						
							|  |  |  |     bold: "strong", | 
					
						
							|  |  |  |     cite: "keyword", | 
					
						
							|  |  |  |     code: "atom", | 
					
						
							|  |  |  |     definitionList: "number", | 
					
						
							|  |  |  |     deletion: "negative", | 
					
						
							|  |  |  |     div: "punctuation", | 
					
						
							|  |  |  |     em: "em", | 
					
						
							|  |  |  |     footnote: "variable", | 
					
						
							|  |  |  |     footCite: "qualifier", | 
					
						
							|  |  |  |     header: "header", | 
					
						
							|  |  |  |     html: "comment", | 
					
						
							|  |  |  |     image: "string", | 
					
						
							|  |  |  |     italic: "em", | 
					
						
							|  |  |  |     link: "link", | 
					
						
							|  |  |  |     linkDefinition: "link", | 
					
						
							|  |  |  |     list1: "variable-2", | 
					
						
							|  |  |  |     list2: "variable-3", | 
					
						
							|  |  |  |     list3: "keyword", | 
					
						
							|  |  |  |     notextile: "string-2", | 
					
						
							|  |  |  |     pre: "operator", | 
					
						
							|  |  |  |     p: "property", | 
					
						
							|  |  |  |     quote: "bracket", | 
					
						
							|  |  |  |     span: "quote", | 
					
						
							|  |  |  |     specialChar: "tag", | 
					
						
							|  |  |  |     strong: "strong", | 
					
						
							|  |  |  |     sub: "builtin", | 
					
						
							|  |  |  |     sup: "builtin", | 
					
						
							|  |  |  |     table: "variable-3", | 
					
						
							|  |  |  |     tableHeading: "operator" | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function startNewLine(stream, state) { | 
					
						
							|  |  |  |     state.mode = Modes.newLayout; | 
					
						
							|  |  |  |     state.tableHeading = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (state.layoutType === "definitionList" && state.spanningLayout && | 
					
						
							|  |  |  |         stream.match(RE("definitionListEnd"), false)) | 
					
						
							|  |  |  |       state.spanningLayout = false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function handlePhraseModifier(stream, state, ch) { | 
					
						
							|  |  |  |     if (ch === "_") { | 
					
						
							|  |  |  |       if (stream.eat("_")) | 
					
						
							|  |  |  |         return togglePhraseModifier(stream, state, "italic", /__/, 2); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         return togglePhraseModifier(stream, state, "em", /_/, 1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ch === "*") { | 
					
						
							|  |  |  |       if (stream.eat("*")) { | 
					
						
							|  |  |  |         return togglePhraseModifier(stream, state, "bold", /\*\*/, 2); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return togglePhraseModifier(stream, state, "strong", /\*/, 1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ch === "[") { | 
					
						
							|  |  |  |       if (stream.match(/\d+\]/)) state.footCite = true; | 
					
						
							|  |  |  |       return tokenStyles(state); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ch === "(") { | 
					
						
							|  |  |  |       var spec = stream.match(/^(r|tm|c)\)/); | 
					
						
							|  |  |  |       if (spec) | 
					
						
							|  |  |  |         return tokenStylesWith(state, TOKEN_STYLES.specialChar); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ch === "<" && stream.match(/(\w+)[^>]+>[^<]+<\/\1>/)) | 
					
						
							|  |  |  |       return tokenStylesWith(state, TOKEN_STYLES.html); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ch === "?" && stream.eat("?")) | 
					
						
							|  |  |  |       return togglePhraseModifier(stream, state, "cite", /\?\?/, 2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ch === "=" && stream.eat("=")) | 
					
						
							|  |  |  |       return togglePhraseModifier(stream, state, "notextile", /==/, 2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ch === "-" && !stream.eat("-")) | 
					
						
							|  |  |  |       return togglePhraseModifier(stream, state, "deletion", /-/, 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ch === "+") | 
					
						
							|  |  |  |       return togglePhraseModifier(stream, state, "addition", /\+/, 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ch === "~") | 
					
						
							|  |  |  |       return togglePhraseModifier(stream, state, "sub", /~/, 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ch === "^") | 
					
						
							|  |  |  |       return togglePhraseModifier(stream, state, "sup", /\^/, 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ch === "%") | 
					
						
							|  |  |  |       return togglePhraseModifier(stream, state, "span", /%/, 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ch === "@") | 
					
						
							|  |  |  |       return togglePhraseModifier(stream, state, "code", /@/, 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ch === "!") { | 
					
						
							|  |  |  |       var type = togglePhraseModifier(stream, state, "image", /(?:\([^\)]+\))?!/, 1); | 
					
						
							|  |  |  |       stream.match(/^:\S+/); // optional Url portion
 | 
					
						
							|  |  |  |       return type; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return tokenStyles(state); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function togglePhraseModifier(stream, state, phraseModifier, closeRE, openSize) { | 
					
						
							|  |  |  |     var charBefore = stream.pos > openSize ? stream.string.charAt(stream.pos - openSize - 1) : null; | 
					
						
							|  |  |  |     var charAfter = stream.peek(); | 
					
						
							|  |  |  |     if (state[phraseModifier]) { | 
					
						
							|  |  |  |       if ((!charAfter || /\W/.test(charAfter)) && charBefore && /\S/.test(charBefore)) { | 
					
						
							|  |  |  |         var type = tokenStyles(state); | 
					
						
							|  |  |  |         state[phraseModifier] = false; | 
					
						
							|  |  |  |         return type; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } else if ((!charBefore || /\W/.test(charBefore)) && charAfter && /\S/.test(charAfter) && | 
					
						
							|  |  |  |                stream.match(new RegExp("^.*\\S" + closeRE.source + "(?:\\W|$)"), false)) { | 
					
						
							|  |  |  |       state[phraseModifier] = true; | 
					
						
							|  |  |  |       state.mode = Modes.attributes; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return tokenStyles(state); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function tokenStyles(state) { | 
					
						
							|  |  |  |     var disabled = textileDisabled(state); | 
					
						
							|  |  |  |     if (disabled) return disabled; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var styles = []; | 
					
						
							|  |  |  |     if (state.layoutType) styles.push(TOKEN_STYLES[state.layoutType]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     styles = styles.concat(activeStyles( | 
					
						
							|  |  |  |       state, "addition", "bold", "cite", "code", "deletion", "em", "footCite", | 
					
						
							|  |  |  |       "image", "italic", "link", "span", "strong", "sub", "sup", "table", "tableHeading")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (state.layoutType === "header") | 
					
						
							|  |  |  |       styles.push(TOKEN_STYLES.header + "-" + state.header); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return styles.length ? styles.join(" ") : null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function textileDisabled(state) { | 
					
						
							|  |  |  |     var type = state.layoutType; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch(type) { | 
					
						
							|  |  |  |     case "notextile": | 
					
						
							|  |  |  |     case "code": | 
					
						
							|  |  |  |     case "pre": | 
					
						
							|  |  |  |       return TOKEN_STYLES[type]; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       if (state.notextile) | 
					
						
							|  |  |  |         return TOKEN_STYLES.notextile + (type ? (" " + TOKEN_STYLES[type]) : ""); | 
					
						
							|  |  |  |       return null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function tokenStylesWith(state, extraStyles) { | 
					
						
							|  |  |  |     var disabled = textileDisabled(state); | 
					
						
							|  |  |  |     if (disabled) return disabled; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var type = tokenStyles(state); | 
					
						
							|  |  |  |     if (extraStyles) | 
					
						
							|  |  |  |       return type ? (type + " " + extraStyles) : extraStyles; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       return type; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function activeStyles(state) { | 
					
						
							|  |  |  |     var styles = []; | 
					
						
							|  |  |  |     for (var i = 1; i < arguments.length; ++i) { | 
					
						
							|  |  |  |       if (state[arguments[i]]) | 
					
						
							|  |  |  |         styles.push(TOKEN_STYLES[arguments[i]]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return styles; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function blankLine(state) { | 
					
						
							|  |  |  |     var spanningLayout = state.spanningLayout, type = state.layoutType; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (var key in state) if (state.hasOwnProperty(key)) | 
					
						
							|  |  |  |       delete state[key]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     state.mode = Modes.newLayout; | 
					
						
							|  |  |  |     if (spanningLayout) { | 
					
						
							|  |  |  |       state.layoutType = type; | 
					
						
							|  |  |  |       state.spanningLayout = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var REs = { | 
					
						
							|  |  |  |     cache: {}, | 
					
						
							|  |  |  |     single: { | 
					
						
							|  |  |  |       bc: "bc", | 
					
						
							|  |  |  |       bq: "bq", | 
					
						
							|  |  |  |       definitionList: /- .*?:=+/, | 
					
						
							|  |  |  |       definitionListEnd: /.*=:\s*$/, | 
					
						
							|  |  |  |       div: "div", | 
					
						
							|  |  |  |       drawTable: /\|.*\|/, | 
					
						
							|  |  |  |       foot: /fn\d+/, | 
					
						
							|  |  |  |       header: /h[1-6]/, | 
					
						
							|  |  |  |       html: /\s*<(?:\/)?(\w+)(?:[^>]+)?>(?:[^<]+<\/\1>)?/, | 
					
						
							|  |  |  |       link: /[^"]+":\S/, | 
					
						
							|  |  |  |       linkDefinition: /\[[^\s\]]+\]\S+/, | 
					
						
							|  |  |  |       list: /(?:#+|\*+)/, | 
					
						
							|  |  |  |       notextile: "notextile", | 
					
						
							|  |  |  |       para: "p", | 
					
						
							|  |  |  |       pre: "pre", | 
					
						
							|  |  |  |       table: "table", | 
					
						
							|  |  |  |       tableCellAttributes: /[\/\\]\d+/, | 
					
						
							|  |  |  |       tableHeading: /\|_\./, | 
					
						
							|  |  |  |       tableText: /[^"_\*\[\(\?\+~\^%@|-]+/, | 
					
						
							|  |  |  |       text: /[^!"_=\*\[\(<\?\+~\^%@-]+/ | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     attributes: { | 
					
						
							|  |  |  |       align: /(?:<>|<|>|=)/, | 
					
						
							|  |  |  |       selector: /\([^\(][^\)]+\)/, | 
					
						
							|  |  |  |       lang: /\[[^\[\]]+\]/, | 
					
						
							|  |  |  |       pad: /(?:\(+|\)+){1,2}/, | 
					
						
							|  |  |  |       css: /\{[^\}]+\}/ | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     createRe: function(name) { | 
					
						
							|  |  |  |       switch (name) { | 
					
						
							|  |  |  |       case "drawTable": | 
					
						
							|  |  |  |         return REs.makeRe("^", REs.single.drawTable, "$"); | 
					
						
							|  |  |  |       case "html": | 
					
						
							|  |  |  |         return REs.makeRe("^", REs.single.html, "(?:", REs.single.html, ")*", "$"); | 
					
						
							|  |  |  |       case "linkDefinition": | 
					
						
							|  |  |  |         return REs.makeRe("^", REs.single.linkDefinition, "$"); | 
					
						
							|  |  |  |       case "listLayout": | 
					
						
							|  |  |  |         return REs.makeRe("^", REs.single.list, RE("allAttributes"), "*\\s+"); | 
					
						
							|  |  |  |       case "tableCellAttributes": | 
					
						
							|  |  |  |         return REs.makeRe("^", REs.choiceRe(REs.single.tableCellAttributes, | 
					
						
							|  |  |  |                                             RE("allAttributes")), "+\\."); | 
					
						
							|  |  |  |       case "type": | 
					
						
							|  |  |  |         return REs.makeRe("^", RE("allTypes")); | 
					
						
							|  |  |  |       case "typeLayout": | 
					
						
							|  |  |  |         return REs.makeRe("^", RE("allTypes"), RE("allAttributes"), | 
					
						
							|  |  |  |                           "*\\.\\.?", "(\\s+|$)"); | 
					
						
							|  |  |  |       case "attributes": | 
					
						
							|  |  |  |         return REs.makeRe("^", RE("allAttributes"), "+"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case "allTypes": | 
					
						
							|  |  |  |         return REs.choiceRe(REs.single.div, REs.single.foot, | 
					
						
							|  |  |  |                             REs.single.header, REs.single.bc, REs.single.bq, | 
					
						
							|  |  |  |                             REs.single.notextile, REs.single.pre, REs.single.table, | 
					
						
							|  |  |  |                             REs.single.para); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case "allAttributes": | 
					
						
							|  |  |  |         return REs.choiceRe(REs.attributes.selector, REs.attributes.css, | 
					
						
							|  |  |  |                             REs.attributes.lang, REs.attributes.align, REs.attributes.pad); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  |         return REs.makeRe("^", REs.single[name]); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     makeRe: function() { | 
					
						
							|  |  |  |       var pattern = ""; | 
					
						
							|  |  |  |       for (var i = 0; i < arguments.length; ++i) { | 
					
						
							|  |  |  |         var arg = arguments[i]; | 
					
						
							|  |  |  |         pattern += (typeof arg === "string") ? arg : arg.source; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return new RegExp(pattern); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     choiceRe: function() { | 
					
						
							|  |  |  |       var parts = [arguments[0]]; | 
					
						
							|  |  |  |       for (var i = 1; i < arguments.length; ++i) { | 
					
						
							|  |  |  |         parts[i * 2 - 1] = "|"; | 
					
						
							|  |  |  |         parts[i * 2] = arguments[i]; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       parts.unshift("(?:"); | 
					
						
							|  |  |  |       parts.push(")"); | 
					
						
							|  |  |  |       return REs.makeRe.apply(null, parts); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function RE(name) { | 
					
						
							|  |  |  |     return (REs.cache[name] || (REs.cache[name] = REs.createRe(name))); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var Modes = { | 
					
						
							|  |  |  |     newLayout: function(stream, state) { | 
					
						
							|  |  |  |       if (stream.match(RE("typeLayout"), false)) { | 
					
						
							|  |  |  |         state.spanningLayout = false; | 
					
						
							|  |  |  |         return (state.mode = Modes.blockType)(stream, state); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       var newMode; | 
					
						
							|  |  |  |       if (!textileDisabled(state)) { | 
					
						
							|  |  |  |         if (stream.match(RE("listLayout"), false)) | 
					
						
							|  |  |  |           newMode = Modes.list; | 
					
						
							|  |  |  |         else if (stream.match(RE("drawTable"), false)) | 
					
						
							|  |  |  |           newMode = Modes.table; | 
					
						
							|  |  |  |         else if (stream.match(RE("linkDefinition"), false)) | 
					
						
							|  |  |  |           newMode = Modes.linkDefinition; | 
					
						
							|  |  |  |         else if (stream.match(RE("definitionList"))) | 
					
						
							|  |  |  |           newMode = Modes.definitionList; | 
					
						
							|  |  |  |         else if (stream.match(RE("html"), false)) | 
					
						
							|  |  |  |           newMode = Modes.html; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return (state.mode = (newMode || Modes.text))(stream, state); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     blockType: function(stream, state) { | 
					
						
							|  |  |  |       var match, type; | 
					
						
							|  |  |  |       state.layoutType = null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (match = stream.match(RE("type"))) | 
					
						
							|  |  |  |         type = match[0]; | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         return (state.mode = Modes.text)(stream, state); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (match = type.match(RE("header"))) { | 
					
						
							|  |  |  |         state.layoutType = "header"; | 
					
						
							|  |  |  |         state.header = parseInt(match[0][1]); | 
					
						
							|  |  |  |       } else if (type.match(RE("bq"))) { | 
					
						
							|  |  |  |         state.layoutType = "quote"; | 
					
						
							|  |  |  |       } else if (type.match(RE("bc"))) { | 
					
						
							|  |  |  |         state.layoutType = "code"; | 
					
						
							|  |  |  |       } else if (type.match(RE("foot"))) { | 
					
						
							|  |  |  |         state.layoutType = "footnote"; | 
					
						
							|  |  |  |       } else if (type.match(RE("notextile"))) { | 
					
						
							|  |  |  |         state.layoutType = "notextile"; | 
					
						
							|  |  |  |       } else if (type.match(RE("pre"))) { | 
					
						
							|  |  |  |         state.layoutType = "pre"; | 
					
						
							|  |  |  |       } else if (type.match(RE("div"))) { | 
					
						
							|  |  |  |         state.layoutType = "div"; | 
					
						
							|  |  |  |       } else if (type.match(RE("table"))) { | 
					
						
							|  |  |  |         state.layoutType = "table"; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       state.mode = Modes.attributes; | 
					
						
							|  |  |  |       return tokenStyles(state); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     text: function(stream, state) { | 
					
						
							|  |  |  |       if (stream.match(RE("text"))) return tokenStyles(state); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var ch = stream.next(); | 
					
						
							|  |  |  |       if (ch === '"') | 
					
						
							|  |  |  |         return (state.mode = Modes.link)(stream, state); | 
					
						
							|  |  |  |       return handlePhraseModifier(stream, state, ch); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     attributes: function(stream, state) { | 
					
						
							|  |  |  |       state.mode = Modes.layoutLength; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (stream.match(RE("attributes"))) | 
					
						
							|  |  |  |         return tokenStylesWith(state, TOKEN_STYLES.attributes); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         return tokenStyles(state); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     layoutLength: function(stream, state) { | 
					
						
							|  |  |  |       if (stream.eat(".") && stream.eat(".")) | 
					
						
							|  |  |  |         state.spanningLayout = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       state.mode = Modes.text; | 
					
						
							|  |  |  |       return tokenStyles(state); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     list: function(stream, state) { | 
					
						
							|  |  |  |       var match = stream.match(RE("list")); | 
					
						
							|  |  |  |       state.listDepth = match[0].length; | 
					
						
							|  |  |  |       var listMod = (state.listDepth - 1) % 3; | 
					
						
							|  |  |  |       if (!listMod) | 
					
						
							|  |  |  |         state.layoutType = "list1"; | 
					
						
							|  |  |  |       else if (listMod === 1) | 
					
						
							|  |  |  |         state.layoutType = "list2"; | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         state.layoutType = "list3"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       state.mode = Modes.attributes; | 
					
						
							|  |  |  |       return tokenStyles(state); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     link: function(stream, state) { | 
					
						
							|  |  |  |       state.mode = Modes.text; | 
					
						
							|  |  |  |       if (stream.match(RE("link"))) { | 
					
						
							|  |  |  |         stream.match(/\S+/); | 
					
						
							|  |  |  |         return tokenStylesWith(state, TOKEN_STYLES.link); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return tokenStyles(state); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     linkDefinition: function(stream, state) { | 
					
						
							|  |  |  |       stream.skipToEnd(); | 
					
						
							|  |  |  |       return tokenStylesWith(state, TOKEN_STYLES.linkDefinition); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     definitionList: function(stream, state) { | 
					
						
							|  |  |  |       stream.match(RE("definitionList")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       state.layoutType = "definitionList"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (stream.match(/\s*$/)) | 
					
						
							|  |  |  |         state.spanningLayout = true; | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         state.mode = Modes.attributes; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return tokenStyles(state); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     html: function(stream, state) { | 
					
						
							|  |  |  |       stream.skipToEnd(); | 
					
						
							|  |  |  |       return tokenStylesWith(state, TOKEN_STYLES.html); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     table: function(stream, state) { | 
					
						
							|  |  |  |       state.layoutType = "table"; | 
					
						
							|  |  |  |       return (state.mode = Modes.tableCell)(stream, state); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     tableCell: function(stream, state) { | 
					
						
							|  |  |  |       if (stream.match(RE("tableHeading"))) | 
					
						
							|  |  |  |         state.tableHeading = true; | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         stream.eat("|"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       state.mode = Modes.tableCellAttributes; | 
					
						
							|  |  |  |       return tokenStyles(state); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     tableCellAttributes: function(stream, state) { | 
					
						
							|  |  |  |       state.mode = Modes.tableText; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (stream.match(RE("tableCellAttributes"))) | 
					
						
							|  |  |  |         return tokenStylesWith(state, TOKEN_STYLES.attributes); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         return tokenStyles(state); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     tableText: function(stream, state) { | 
					
						
							|  |  |  |       if (stream.match(RE("tableText"))) | 
					
						
							|  |  |  |         return tokenStyles(state); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (stream.peek() === "|") { // end of cell
 | 
					
						
							|  |  |  |         state.mode = Modes.tableCell; | 
					
						
							|  |  |  |         return tokenStyles(state); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return handlePhraseModifier(stream, state, stream.next()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   CodeMirror.defineMode("textile", function() { | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       startState: function() { | 
					
						
							|  |  |  |         return { mode: Modes.newLayout }; | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       token: function(stream, state) { | 
					
						
							|  |  |  |         if (stream.sol()) startNewLine(stream, state); | 
					
						
							|  |  |  |         return state.mode(stream, state); | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       blankLine: blankLine | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   CodeMirror.defineMIME("text/x-textile", "textile"); | 
					
						
							|  |  |  | }); |