[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 // Distributed under an MIT license: https://codemirror.net/5/LICENSE 3 4 (function(mod) { 5 if (typeof exports == "object" && typeof module == "object") // CommonJS 6 mod(require("../../lib/codemirror"), require("../xml/xml"), require("../meta")); 7 else if (typeof define == "function" && define.amd) // AMD 8 define(["../../lib/codemirror", "../xml/xml", "../meta"], mod); 9 else // Plain browser env 10 mod(CodeMirror); 11 })(function(CodeMirror) { 12 "use strict"; 13 14 CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { 15 16 var htmlMode = CodeMirror.getMode(cmCfg, "text/html"); 17 var htmlModeMissing = htmlMode.name == "null" 18 19 function getMode(name) { 20 if (CodeMirror.findModeByName) { 21 var found = CodeMirror.findModeByName(name); 22 if (found) name = found.mime || found.mimes[0]; 23 } 24 var mode = CodeMirror.getMode(cmCfg, name); 25 return mode.name == "null" ? null : mode; 26 } 27 28 // Should characters that affect highlighting be highlighted separate? 29 // Does not include characters that will be output (such as `1.` and `-` for lists) 30 if (modeCfg.highlightFormatting === undefined) 31 modeCfg.highlightFormatting = false; 32 33 // Maximum number of nested blockquotes. Set to 0 for infinite nesting. 34 // Excess `>` will emit `error` token. 35 if (modeCfg.maxBlockquoteDepth === undefined) 36 modeCfg.maxBlockquoteDepth = 0; 37 38 // Turn on task lists? ("- [ ] " and "- [x] ") 39 if (modeCfg.taskLists === undefined) modeCfg.taskLists = false; 40 41 // Turn on strikethrough syntax 42 if (modeCfg.strikethrough === undefined) 43 modeCfg.strikethrough = false; 44 45 if (modeCfg.emoji === undefined) 46 modeCfg.emoji = false; 47 48 if (modeCfg.fencedCodeBlockHighlighting === undefined) 49 modeCfg.fencedCodeBlockHighlighting = true; 50 51 if (modeCfg.fencedCodeBlockDefaultMode === undefined) 52 modeCfg.fencedCodeBlockDefaultMode = 'text/plain'; 53 54 if (modeCfg.xml === undefined) 55 modeCfg.xml = true; 56 57 // Allow token types to be overridden by user-provided token types. 58 if (modeCfg.tokenTypeOverrides === undefined) 59 modeCfg.tokenTypeOverrides = {}; 60 61 var tokenTypes = { 62 header: "header", 63 code: "comment", 64 quote: "quote", 65 list1: "variable-2", 66 list2: "variable-3", 67 list3: "keyword", 68 hr: "hr", 69 image: "image", 70 imageAltText: "image-alt-text", 71 imageMarker: "image-marker", 72 formatting: "formatting", 73 linkInline: "link", 74 linkEmail: "link", 75 linkText: "link", 76 linkHref: "string", 77 em: "em", 78 strong: "strong", 79 strikethrough: "strikethrough", 80 emoji: "builtin" 81 }; 82 83 for (var tokenType in tokenTypes) { 84 if (tokenTypes.hasOwnProperty(tokenType) && modeCfg.tokenTypeOverrides[tokenType]) { 85 tokenTypes[tokenType] = modeCfg.tokenTypeOverrides[tokenType]; 86 } 87 } 88 89 var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/ 90 , listRE = /^(?:[*\-+]|^[0-9]+([.)]))\s+/ 91 , taskListRE = /^\[(x| )\](?=\s)/i // Must follow listRE 92 , atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/ 93 , setextHeaderRE = /^ {0,3}(?:\={1,}|-{2,})\s*$/ 94 , textRE = /^[^#!\[\]*_\\<>` "'(~:]+/ 95 , fencedCodeRE = /^(~~~+|```+)[ \t]*([\w\/+#-]*)[^\n`]*$/ 96 , linkDefRE = /^\s*\[[^\]]+?\]:.*$/ // naive link-definition 97 , punctuation = /[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E42\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC9\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDF3C-\uDF3E]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]/ 98 , expandedTab = " " // CommonMark specifies tab as 4 spaces 99 100 function switchInline(stream, state, f) { 101 state.f = state.inline = f; 102 return f(stream, state); 103 } 104 105 function switchBlock(stream, state, f) { 106 state.f = state.block = f; 107 return f(stream, state); 108 } 109 110 function lineIsEmpty(line) { 111 return !line || !/\S/.test(line.string) 112 } 113 114 // Blocks 115 116 function blankLine(state) { 117 // Reset linkTitle state 118 state.linkTitle = false; 119 state.linkHref = false; 120 state.linkText = false; 121 // Reset EM state 122 state.em = false; 123 // Reset STRONG state 124 state.strong = false; 125 // Reset strikethrough state 126 state.strikethrough = false; 127 // Reset state.quote 128 state.quote = 0; 129 // Reset state.indentedCode 130 state.indentedCode = false; 131 if (state.f == htmlBlock) { 132 var exit = htmlModeMissing 133 if (!exit) { 134 var inner = CodeMirror.innerMode(htmlMode, state.htmlState) 135 exit = inner.mode.name == "xml" && inner.state.tagStart === null && 136 (!inner.state.context && inner.state.tokenize.isInText) 137 } 138 if (exit) { 139 state.f = inlineNormal; 140 state.block = blockNormal; 141 state.htmlState = null; 142 } 143 } 144 // Reset state.trailingSpace 145 state.trailingSpace = 0; 146 state.trailingSpaceNewLine = false; 147 // Mark this line as blank 148 state.prevLine = state.thisLine 149 state.thisLine = {stream: null} 150 return null; 151 } 152 153 function blockNormal(stream, state) { 154 var firstTokenOnLine = stream.column() === state.indentation; 155 var prevLineLineIsEmpty = lineIsEmpty(state.prevLine.stream); 156 var prevLineIsIndentedCode = state.indentedCode; 157 var prevLineIsHr = state.prevLine.hr; 158 var prevLineIsList = state.list !== false; 159 var maxNonCodeIndentation = (state.listStack[state.listStack.length - 1] || 0) + 3; 160 161 state.indentedCode = false; 162 163 var lineIndentation = state.indentation; 164 // compute once per line (on first token) 165 if (state.indentationDiff === null) { 166 state.indentationDiff = state.indentation; 167 if (prevLineIsList) { 168 state.list = null; 169 // While this list item's marker's indentation is less than the deepest 170 // list item's content's indentation,pop the deepest list item 171 // indentation off the stack, and update block indentation state 172 while (lineIndentation < state.listStack[state.listStack.length - 1]) { 173 state.listStack.pop(); 174 if (state.listStack.length) { 175 state.indentation = state.listStack[state.listStack.length - 1]; 176 // less than the first list's indent -> the line is no longer a list 177 } else { 178 state.list = false; 179 } 180 } 181 if (state.list !== false) { 182 state.indentationDiff = lineIndentation - state.listStack[state.listStack.length - 1] 183 } 184 } 185 } 186 187 // not comprehensive (currently only for setext detection purposes) 188 var allowsInlineContinuation = ( 189 !prevLineLineIsEmpty && !prevLineIsHr && !state.prevLine.header && 190 (!prevLineIsList || !prevLineIsIndentedCode) && 191 !state.prevLine.fencedCodeEnd 192 ); 193 194 var isHr = (state.list === false || prevLineIsHr || prevLineLineIsEmpty) && 195 state.indentation <= maxNonCodeIndentation && stream.match(hrRE); 196 197 var match = null; 198 if (state.indentationDiff >= 4 && (prevLineIsIndentedCode || state.prevLine.fencedCodeEnd || 199 state.prevLine.header || prevLineLineIsEmpty)) { 200 stream.skipToEnd(); 201 state.indentedCode = true; 202 return tokenTypes.code; 203 } else if (stream.eatSpace()) { 204 return null; 205 } else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(atxHeaderRE)) && match[1].length <= 6) { 206 state.quote = 0; 207 state.header = match[1].length; 208 state.thisLine.header = true; 209 if (modeCfg.highlightFormatting) state.formatting = "header"; 210 state.f = state.inline; 211 return getType(state); 212 } else if (state.indentation <= maxNonCodeIndentation && stream.eat('>')) { 213 state.quote = firstTokenOnLine ? 1 : state.quote + 1; 214 if (modeCfg.highlightFormatting) state.formatting = "quote"; 215 stream.eatSpace(); 216 return getType(state); 217 } else if (!isHr && !state.setext && firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(listRE))) { 218 var listType = match[1] ? "ol" : "ul"; 219 220 state.indentation = lineIndentation + stream.current().length; 221 state.list = true; 222 state.quote = 0; 223 224 // Add this list item's content's indentation to the stack 225 state.listStack.push(state.indentation); 226 // Reset inline styles which shouldn't propagate across list items 227 state.em = false; 228 state.strong = false; 229 state.code = false; 230 state.strikethrough = false; 231 232 if (modeCfg.taskLists && stream.match(taskListRE, false)) { 233 state.taskList = true; 234 } 235 state.f = state.inline; 236 if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType]; 237 return getType(state); 238 } else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(fencedCodeRE, true))) { 239 state.quote = 0; 240 state.fencedEndRE = new RegExp(match[1] + "+ *$"); 241 // try switching mode 242 state.localMode = modeCfg.fencedCodeBlockHighlighting && getMode(match[2] || modeCfg.fencedCodeBlockDefaultMode ); 243 if (state.localMode) state.localState = CodeMirror.startState(state.localMode); 244 state.f = state.block = local; 245 if (modeCfg.highlightFormatting) state.formatting = "code-block"; 246 state.code = -1 247 return getType(state); 248 // SETEXT has lowest block-scope precedence after HR, so check it after 249 // the others (code, blockquote, list...) 250 } else if ( 251 // if setext set, indicates line after ---/=== 252 state.setext || ( 253 // line before ---/=== 254 (!allowsInlineContinuation || !prevLineIsList) && !state.quote && state.list === false && 255 !state.code && !isHr && !linkDefRE.test(stream.string) && 256 (match = stream.lookAhead(1)) && (match = match.match(setextHeaderRE)) 257 ) 258 ) { 259 if ( !state.setext ) { 260 state.header = match[0].charAt(0) == '=' ? 1 : 2; 261 state.setext = state.header; 262 } else { 263 state.header = state.setext; 264 // has no effect on type so we can reset it now 265 state.setext = 0; 266 stream.skipToEnd(); 267 if (modeCfg.highlightFormatting) state.formatting = "header"; 268 } 269 state.thisLine.header = true; 270 state.f = state.inline; 271 return getType(state); 272 } else if (isHr) { 273 stream.skipToEnd(); 274 state.hr = true; 275 state.thisLine.hr = true; 276 return tokenTypes.hr; 277 } else if (stream.peek() === '[') { 278 return switchInline(stream, state, footnoteLink); 279 } 280 281 return switchInline(stream, state, state.inline); 282 } 283 284 function htmlBlock(stream, state) { 285 var style = htmlMode.token(stream, state.htmlState); 286 if (!htmlModeMissing) { 287 var inner = CodeMirror.innerMode(htmlMode, state.htmlState) 288 if ((inner.mode.name == "xml" && inner.state.tagStart === null && 289 (!inner.state.context && inner.state.tokenize.isInText)) || 290 (state.md_inside && stream.current().indexOf(">") > -1)) { 291 state.f = inlineNormal; 292 state.block = blockNormal; 293 state.htmlState = null; 294 } 295 } 296 return style; 297 } 298 299 function local(stream, state) { 300 var currListInd = state.listStack[state.listStack.length - 1] || 0; 301 var hasExitedList = state.indentation < currListInd; 302 var maxFencedEndInd = currListInd + 3; 303 if (state.fencedEndRE && state.indentation <= maxFencedEndInd && (hasExitedList || stream.match(state.fencedEndRE))) { 304 if (modeCfg.highlightFormatting) state.formatting = "code-block"; 305 var returnType; 306 if (!hasExitedList) returnType = getType(state) 307 state.localMode = state.localState = null; 308 state.block = blockNormal; 309 state.f = inlineNormal; 310 state.fencedEndRE = null; 311 state.code = 0 312 state.thisLine.fencedCodeEnd = true; 313 if (hasExitedList) return switchBlock(stream, state, state.block); 314 return returnType; 315 } else if (state.localMode) { 316 return state.localMode.token(stream, state.localState); 317 } else { 318 stream.skipToEnd(); 319 return tokenTypes.code; 320 } 321 } 322 323 // Inline 324 function getType(state) { 325 var styles = []; 326 327 if (state.formatting) { 328 styles.push(tokenTypes.formatting); 329 330 if (typeof state.formatting === "string") state.formatting = [state.formatting]; 331 332 for (var i = 0; i < state.formatting.length; i++) { 333 styles.push(tokenTypes.formatting + "-" + state.formatting[i]); 334 335 if (state.formatting[i] === "header") { 336 styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.header); 337 } 338 339 // Add `formatting-quote` and `formatting-quote-#` for blockquotes 340 // Add `error` instead if the maximum blockquote nesting depth is passed 341 if (state.formatting[i] === "quote") { 342 if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) { 343 styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.quote); 344 } else { 345 styles.push("error"); 346 } 347 } 348 } 349 } 350 351 if (state.taskOpen) { 352 styles.push("meta"); 353 return styles.length ? styles.join(' ') : null; 354 } 355 if (state.taskClosed) { 356 styles.push("property"); 357 return styles.length ? styles.join(' ') : null; 358 } 359 360 if (state.linkHref) { 361 styles.push(tokenTypes.linkHref, "url"); 362 } else { // Only apply inline styles to non-url text 363 if (state.strong) { styles.push(tokenTypes.strong); } 364 if (state.em) { styles.push(tokenTypes.em); } 365 if (state.strikethrough) { styles.push(tokenTypes.strikethrough); } 366 if (state.emoji) { styles.push(tokenTypes.emoji); } 367 if (state.linkText) { styles.push(tokenTypes.linkText); } 368 if (state.code) { styles.push(tokenTypes.code); } 369 if (state.image) { styles.push(tokenTypes.image); } 370 if (state.imageAltText) { styles.push(tokenTypes.imageAltText, "link"); } 371 if (state.imageMarker) { styles.push(tokenTypes.imageMarker); } 372 } 373 374 if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); } 375 376 if (state.quote) { 377 styles.push(tokenTypes.quote); 378 379 // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth 380 if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) { 381 styles.push(tokenTypes.quote + "-" + state.quote); 382 } else { 383 styles.push(tokenTypes.quote + "-" + modeCfg.maxBlockquoteDepth); 384 } 385 } 386 387 if (state.list !== false) { 388 var listMod = (state.listStack.length - 1) % 3; 389 if (!listMod) { 390 styles.push(tokenTypes.list1); 391 } else if (listMod === 1) { 392 styles.push(tokenTypes.list2); 393 } else { 394 styles.push(tokenTypes.list3); 395 } 396 } 397 398 if (state.trailingSpaceNewLine) { 399 styles.push("trailing-space-new-line"); 400 } else if (state.trailingSpace) { 401 styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b")); 402 } 403 404 return styles.length ? styles.join(' ') : null; 405 } 406 407 function handleText(stream, state) { 408 if (stream.match(textRE, true)) { 409 return getType(state); 410 } 411 return undefined; 412 } 413 414 function inlineNormal(stream, state) { 415 var style = state.text(stream, state); 416 if (typeof style !== 'undefined') 417 return style; 418 419 if (state.list) { // List marker (*, +, -, 1., etc) 420 state.list = null; 421 return getType(state); 422 } 423 424 if (state.taskList) { 425 var taskOpen = stream.match(taskListRE, true)[1] === " "; 426 if (taskOpen) state.taskOpen = true; 427 else state.taskClosed = true; 428 if (modeCfg.highlightFormatting) state.formatting = "task"; 429 state.taskList = false; 430 return getType(state); 431 } 432 433 state.taskOpen = false; 434 state.taskClosed = false; 435 436 if (state.header && stream.match(/^#+$/, true)) { 437 if (modeCfg.highlightFormatting) state.formatting = "header"; 438 return getType(state); 439 } 440 441 var ch = stream.next(); 442 443 // Matches link titles present on next line 444 if (state.linkTitle) { 445 state.linkTitle = false; 446 var matchCh = ch; 447 if (ch === '(') { 448 matchCh = ')'; 449 } 450 matchCh = (matchCh+'').replace(/([.?*+^\[\]\\(){}|-])/g, "\\$1"); 451 var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh; 452 if (stream.match(new RegExp(regex), true)) { 453 return tokenTypes.linkHref; 454 } 455 } 456 457 // If this block is changed, it may need to be updated in GFM mode 458 if (ch === '`') { 459 var previousFormatting = state.formatting; 460 if (modeCfg.highlightFormatting) state.formatting = "code"; 461 stream.eatWhile('`'); 462 var count = stream.current().length 463 if (state.code == 0 && (!state.quote || count == 1)) { 464 state.code = count 465 return getType(state) 466 } else if (count == state.code) { // Must be exact 467 var t = getType(state) 468 state.code = 0 469 return t 470 } else { 471 state.formatting = previousFormatting 472 return getType(state) 473 } 474 } else if (state.code) { 475 return getType(state); 476 } 477 478 if (ch === '\\') { 479 stream.next(); 480 if (modeCfg.highlightFormatting) { 481 var type = getType(state); 482 var formattingEscape = tokenTypes.formatting + "-escape"; 483 return type ? type + " " + formattingEscape : formattingEscape; 484 } 485 } 486 487 if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) { 488 state.imageMarker = true; 489 state.image = true; 490 if (modeCfg.highlightFormatting) state.formatting = "image"; 491 return getType(state); 492 } 493 494 if (ch === '[' && state.imageMarker && stream.match(/[^\]]*\](\(.*?\)| ?\[.*?\])/, false)) { 495 state.imageMarker = false; 496 state.imageAltText = true 497 if (modeCfg.highlightFormatting) state.formatting = "image"; 498 return getType(state); 499 } 500 501 if (ch === ']' && state.imageAltText) { 502 if (modeCfg.highlightFormatting) state.formatting = "image"; 503 var type = getType(state); 504 state.imageAltText = false; 505 state.image = false; 506 state.inline = state.f = linkHref; 507 return type; 508 } 509 510 if (ch === '[' && !state.image) { 511 if (state.linkText && stream.match(/^.*?\]/)) return getType(state) 512 state.linkText = true; 513 if (modeCfg.highlightFormatting) state.formatting = "link"; 514 return getType(state); 515 } 516 517 if (ch === ']' && state.linkText) { 518 if (modeCfg.highlightFormatting) state.formatting = "link"; 519 var type = getType(state); 520 state.linkText = false; 521 state.inline = state.f = stream.match(/\(.*?\)| ?\[.*?\]/, false) ? linkHref : inlineNormal 522 return type; 523 } 524 525 if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) { 526 state.f = state.inline = linkInline; 527 if (modeCfg.highlightFormatting) state.formatting = "link"; 528 var type = getType(state); 529 if (type){ 530 type += " "; 531 } else { 532 type = ""; 533 } 534 return type + tokenTypes.linkInline; 535 } 536 537 if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) { 538 state.f = state.inline = linkInline; 539 if (modeCfg.highlightFormatting) state.formatting = "link"; 540 var type = getType(state); 541 if (type){ 542 type += " "; 543 } else { 544 type = ""; 545 } 546 return type + tokenTypes.linkEmail; 547 } 548 549 if (modeCfg.xml && ch === '<' && stream.match(/^(!--|\?|!\[CDATA\[|[a-z][a-z0-9-]*(?:\s+[a-z_:.\-]+(?:\s*=\s*[^>]+)?)*\s*(?:>|$))/i, false)) { 550 var end = stream.string.indexOf(">", stream.pos); 551 if (end != -1) { 552 var atts = stream.string.substring(stream.start, end); 553 if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) state.md_inside = true; 554 } 555 stream.backUp(1); 556 state.htmlState = CodeMirror.startState(htmlMode); 557 return switchBlock(stream, state, htmlBlock); 558 } 559 560 if (modeCfg.xml && ch === '<' && stream.match(/^\/\w*?>/)) { 561 state.md_inside = false; 562 return "tag"; 563 } else if (ch === "*" || ch === "_") { 564 var len = 1, before = stream.pos == 1 ? " " : stream.string.charAt(stream.pos - 2) 565 while (len < 3 && stream.eat(ch)) len++ 566 var after = stream.peek() || " " 567 // See http://spec.commonmark.org/0.27/#emphasis-and-strong-emphasis 568 var leftFlanking = !/\s/.test(after) && (!punctuation.test(after) || /\s/.test(before) || punctuation.test(before)) 569 var rightFlanking = !/\s/.test(before) && (!punctuation.test(before) || /\s/.test(after) || punctuation.test(after)) 570 var setEm = null, setStrong = null 571 if (len % 2) { // Em 572 if (!state.em && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before))) 573 setEm = true 574 else if (state.em == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after))) 575 setEm = false 576 } 577 if (len > 1) { // Strong 578 if (!state.strong && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before))) 579 setStrong = true 580 else if (state.strong == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after))) 581 setStrong = false 582 } 583 if (setStrong != null || setEm != null) { 584 if (modeCfg.highlightFormatting) state.formatting = setEm == null ? "strong" : setStrong == null ? "em" : "strong em" 585 if (setEm === true) state.em = ch 586 if (setStrong === true) state.strong = ch 587 var t = getType(state) 588 if (setEm === false) state.em = false 589 if (setStrong === false) state.strong = false 590 return t 591 } 592 } else if (ch === ' ') { 593 if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces 594 if (stream.peek() === ' ') { // Surrounded by spaces, ignore 595 return getType(state); 596 } else { // Not surrounded by spaces, back up pointer 597 stream.backUp(1); 598 } 599 } 600 } 601 602 if (modeCfg.strikethrough) { 603 if (ch === '~' && stream.eatWhile(ch)) { 604 if (state.strikethrough) {// Remove strikethrough 605 if (modeCfg.highlightFormatting) state.formatting = "strikethrough"; 606 var t = getType(state); 607 state.strikethrough = false; 608 return t; 609 } else if (stream.match(/^[^\s]/, false)) {// Add strikethrough 610 state.strikethrough = true; 611 if (modeCfg.highlightFormatting) state.formatting = "strikethrough"; 612 return getType(state); 613 } 614 } else if (ch === ' ') { 615 if (stream.match('~~', true)) { // Probably surrounded by space 616 if (stream.peek() === ' ') { // Surrounded by spaces, ignore 617 return getType(state); 618 } else { // Not surrounded by spaces, back up pointer 619 stream.backUp(2); 620 } 621 } 622 } 623 } 624 625 if (modeCfg.emoji && ch === ":" && stream.match(/^(?:[a-z_\d+][a-z_\d+-]*|\-[a-z_\d+][a-z_\d+-]*):/)) { 626 state.emoji = true; 627 if (modeCfg.highlightFormatting) state.formatting = "emoji"; 628 var retType = getType(state); 629 state.emoji = false; 630 return retType; 631 } 632 633 if (ch === ' ') { 634 if (stream.match(/^ +$/, false)) { 635 state.trailingSpace++; 636 } else if (state.trailingSpace) { 637 state.trailingSpaceNewLine = true; 638 } 639 } 640 641 return getType(state); 642 } 643 644 function linkInline(stream, state) { 645 var ch = stream.next(); 646 647 if (ch === ">") { 648 state.f = state.inline = inlineNormal; 649 if (modeCfg.highlightFormatting) state.formatting = "link"; 650 var type = getType(state); 651 if (type){ 652 type += " "; 653 } else { 654 type = ""; 655 } 656 return type + tokenTypes.linkInline; 657 } 658 659 stream.match(/^[^>]+/, true); 660 661 return tokenTypes.linkInline; 662 } 663 664 function linkHref(stream, state) { 665 // Check if space, and return NULL if so (to avoid marking the space) 666 if(stream.eatSpace()){ 667 return null; 668 } 669 var ch = stream.next(); 670 if (ch === '(' || ch === '[') { 671 state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]"); 672 if (modeCfg.highlightFormatting) state.formatting = "link-string"; 673 state.linkHref = true; 674 return getType(state); 675 } 676 return 'error'; 677 } 678 679 var linkRE = { 680 ")": /^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/, 681 "]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\]]|\\.)*\])*?(?=\])/ 682 } 683 684 function getLinkHrefInside(endChar) { 685 return function(stream, state) { 686 var ch = stream.next(); 687 688 if (ch === endChar) { 689 state.f = state.inline = inlineNormal; 690 if (modeCfg.highlightFormatting) state.formatting = "link-string"; 691 var returnState = getType(state); 692 state.linkHref = false; 693 return returnState; 694 } 695 696 stream.match(linkRE[endChar]) 697 state.linkHref = true; 698 return getType(state); 699 }; 700 } 701 702 function footnoteLink(stream, state) { 703 if (stream.match(/^([^\]\\]|\\.)*\]:/, false)) { 704 state.f = footnoteLinkInside; 705 stream.next(); // Consume [ 706 if (modeCfg.highlightFormatting) state.formatting = "link"; 707 state.linkText = true; 708 return getType(state); 709 } 710 return switchInline(stream, state, inlineNormal); 711 } 712 713 function footnoteLinkInside(stream, state) { 714 if (stream.match(']:', true)) { 715 state.f = state.inline = footnoteUrl; 716 if (modeCfg.highlightFormatting) state.formatting = "link"; 717 var returnType = getType(state); 718 state.linkText = false; 719 return returnType; 720 } 721 722 stream.match(/^([^\]\\]|\\.)+/, true); 723 724 return tokenTypes.linkText; 725 } 726 727 function footnoteUrl(stream, state) { 728 // Check if space, and return NULL if so (to avoid marking the space) 729 if(stream.eatSpace()){ 730 return null; 731 } 732 // Match URL 733 stream.match(/^[^\s]+/, true); 734 // Check for link title 735 if (stream.peek() === undefined) { // End of line, set flag to check next line 736 state.linkTitle = true; 737 } else { // More content on line, check if link title 738 stream.match(/^(?:\s+(?:"(?:[^"\\]|\\.)+"|'(?:[^'\\]|\\.)+'|\((?:[^)\\]|\\.)+\)))?/, true); 739 } 740 state.f = state.inline = inlineNormal; 741 return tokenTypes.linkHref + " url"; 742 } 743 744 var mode = { 745 startState: function() { 746 return { 747 f: blockNormal, 748 749 prevLine: {stream: null}, 750 thisLine: {stream: null}, 751 752 block: blockNormal, 753 htmlState: null, 754 indentation: 0, 755 756 inline: inlineNormal, 757 text: handleText, 758 759 formatting: false, 760 linkText: false, 761 linkHref: false, 762 linkTitle: false, 763 code: 0, 764 em: false, 765 strong: false, 766 header: 0, 767 setext: 0, 768 hr: false, 769 taskList: false, 770 list: false, 771 listStack: [], 772 quote: 0, 773 trailingSpace: 0, 774 trailingSpaceNewLine: false, 775 strikethrough: false, 776 emoji: false, 777 fencedEndRE: null 778 }; 779 }, 780 781 copyState: function(s) { 782 return { 783 f: s.f, 784 785 prevLine: s.prevLine, 786 thisLine: s.thisLine, 787 788 block: s.block, 789 htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState), 790 indentation: s.indentation, 791 792 localMode: s.localMode, 793 localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null, 794 795 inline: s.inline, 796 text: s.text, 797 formatting: false, 798 linkText: s.linkText, 799 linkTitle: s.linkTitle, 800 linkHref: s.linkHref, 801 code: s.code, 802 em: s.em, 803 strong: s.strong, 804 strikethrough: s.strikethrough, 805 emoji: s.emoji, 806 header: s.header, 807 setext: s.setext, 808 hr: s.hr, 809 taskList: s.taskList, 810 list: s.list, 811 listStack: s.listStack.slice(0), 812 quote: s.quote, 813 indentedCode: s.indentedCode, 814 trailingSpace: s.trailingSpace, 815 trailingSpaceNewLine: s.trailingSpaceNewLine, 816 md_inside: s.md_inside, 817 fencedEndRE: s.fencedEndRE 818 }; 819 }, 820 821 token: function(stream, state) { 822 823 // Reset state.formatting 824 state.formatting = false; 825 826 if (stream != state.thisLine.stream) { 827 state.header = 0; 828 state.hr = false; 829 830 if (stream.match(/^\s*$/, true)) { 831 blankLine(state); 832 return null; 833 } 834 835 state.prevLine = state.thisLine 836 state.thisLine = {stream: stream} 837 838 // Reset state.taskList 839 state.taskList = false; 840 841 // Reset state.trailingSpace 842 state.trailingSpace = 0; 843 state.trailingSpaceNewLine = false; 844 845 if (!state.localState) { 846 state.f = state.block; 847 if (state.f != htmlBlock) { 848 var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, expandedTab).length; 849 state.indentation = indentation; 850 state.indentationDiff = null; 851 if (indentation > 0) return null; 852 } 853 } 854 } 855 return state.f(stream, state); 856 }, 857 858 innerMode: function(state) { 859 if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode}; 860 if (state.localState) return {state: state.localState, mode: state.localMode}; 861 return {state: state, mode: mode}; 862 }, 863 864 indent: function(state, textAfter, line) { 865 if (state.block == htmlBlock && htmlMode.indent) return htmlMode.indent(state.htmlState, textAfter, line) 866 if (state.localState && state.localMode.indent) return state.localMode.indent(state.localState, textAfter, line) 867 return CodeMirror.Pass 868 }, 869 870 blankLine: blankLine, 871 872 getType: getType, 873 874 blockCommentStart: "<!--", 875 blockCommentEnd: "-->", 876 closeBrackets: "()[]{}''\"\"``", 877 fold: "markdown" 878 }; 879 return mode; 880 }, "xml"); 881 882 CodeMirror.defineMIME("text/markdown", "markdown"); 883 884 CodeMirror.defineMIME("text/x-markdown", "markdown"); 885 886 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |