Path: blob/master/web-gui/buildyourownbotnet/assets/js/codemirror/mode/markdown/markdown.js
1294 views
CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {12var htmlFound = CodeMirror.modes.hasOwnProperty("xml");3var htmlMode = CodeMirror.getMode(cmCfg, htmlFound ? {name: "xml", htmlMode: true} : "text/plain");4var aliases = {5html: "htmlmixed",6js: "javascript",7json: "application/json",8c: "text/x-csrc",9"c++": "text/x-c++src",10java: "text/x-java",11csharp: "text/x-csharp",12"c#": "text/x-csharp",13scala: "text/x-scala"14};1516var getMode = (function () {17var i, modes = {}, mimes = {}, mime;1819var list = [];20for (var m in CodeMirror.modes)21if (CodeMirror.modes.propertyIsEnumerable(m)) list.push(m);22for (i = 0; i < list.length; i++) {23modes[list[i]] = list[i];24}25var mimesList = [];26for (var m in CodeMirror.mimeModes)27if (CodeMirror.mimeModes.propertyIsEnumerable(m))28mimesList.push({mime: m, mode: CodeMirror.mimeModes[m]});29for (i = 0; i < mimesList.length; i++) {30mime = mimesList[i].mime;31mimes[mime] = mimesList[i].mime;32}3334for (var a in aliases) {35if (aliases[a] in modes || aliases[a] in mimes)36modes[a] = aliases[a];37}3839return function (lang) {40return modes[lang] ? CodeMirror.getMode(cmCfg, modes[lang]) : null;41};42}());4344// Should characters that affect highlighting be highlighted separate?45// Does not include characters that will be output (such as `1.` and `-` for lists)46if (modeCfg.highlightFormatting === undefined)47modeCfg.highlightFormatting = false;4849// Maximum number of nested blockquotes. Set to 0 for infinite nesting.50// Excess `>` will emit `error` token.51if (modeCfg.maxBlockquoteDepth === undefined)52modeCfg.maxBlockquoteDepth = 0;5354// Should underscores in words open/close em/strong?55if (modeCfg.underscoresBreakWords === undefined)56modeCfg.underscoresBreakWords = true;5758// Turn on fenced code blocks? ("```" to start/end)59if (modeCfg.fencedCodeBlocks === undefined) modeCfg.fencedCodeBlocks = false;6061// Turn on task lists? ("- [ ] " and "- [x] ")62if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;6364var codeDepth = 0;6566var header = 'header'67, code = 'comment'68, quote = 'quote'69, list1 = 'variable-2'70, list2 = 'variable-3'71, list3 = 'keyword'72, hr = 'hr'73, image = 'tag'74, formatting = 'formatting'75, linkinline = 'link'76, linkemail = 'link'77, linktext = 'link'78, linkhref = 'string'79, em = 'em'80, strong = 'strong';8182var hrRE = /^([*\-=_])(?:\s*\1){2,}\s*$/83, ulRE = /^[*\-+]\s+/84, olRE = /^[0-9]+\.\s+/85, taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE86, atxHeaderRE = /^#+/87, setextHeaderRE = /^(?:\={1,}|-{1,})$/88, textRE = /^[^#!\[\]*_\\<>` "'(]+/;8990function switchInline(stream, state, f) {91state.f = state.inline = f;92return f(stream, state);93}9495function switchBlock(stream, state, f) {96state.f = state.block = f;97return f(stream, state);98}99100101// Blocks102103function blankLine(state) {104// Reset linkTitle state105state.linkTitle = false;106// Reset EM state107state.em = false;108// Reset STRONG state109state.strong = false;110// Reset state.quote111state.quote = 0;112if (!htmlFound && state.f == htmlBlock) {113state.f = inlineNormal;114state.block = blockNormal;115}116// Reset state.trailingSpace117state.trailingSpace = 0;118state.trailingSpaceNewLine = false;119// Mark this line as blank120state.thisLineHasContent = false;121return null;122}123124function blockNormal(stream, state) {125126var sol = stream.sol();127128var prevLineIsList = (state.list !== false);129if (state.list !== false && state.indentationDiff >= 0) { // Continued list130if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block131state.indentation -= state.indentationDiff;132}133state.list = null;134} else if (state.list !== false && state.indentation > 0) {135state.list = null;136state.listDepth = Math.floor(state.indentation / 4);137} else if (state.list !== false) { // No longer a list138state.list = false;139state.listDepth = 0;140}141142var match = null;143if (state.indentationDiff >= 4) {144state.indentation -= 4;145stream.skipToEnd();146return code;147} else if (stream.eatSpace()) {148return null;149} else if (match = stream.match(atxHeaderRE)) {150state.header = match[0].length <= 6 ? match[0].length : 6;151if (modeCfg.highlightFormatting) state.formatting = "header";152state.f = state.inline;153return getType(state);154} else if (state.prevLineHasContent && (match = stream.match(setextHeaderRE))) {155state.header = match[0].charAt(0) == '=' ? 1 : 2;156if (modeCfg.highlightFormatting) state.formatting = "header";157state.f = state.inline;158return getType(state);159} else if (stream.eat('>')) {160state.indentation++;161state.quote = sol ? 1 : state.quote + 1;162if (modeCfg.highlightFormatting) state.formatting = "quote";163stream.eatSpace();164return getType(state);165} else if (stream.peek() === '[') {166return switchInline(stream, state, footnoteLink);167} else if (stream.match(hrRE, true)) {168return hr;169} else if ((!state.prevLineHasContent || prevLineIsList) && (stream.match(ulRE, false) || stream.match(olRE, false))) {170var listType = null;171if (stream.match(ulRE, true)) {172listType = 'ul';173} else {174stream.match(olRE, true);175listType = 'ol';176}177state.indentation += 4;178state.list = true;179state.listDepth++;180if (modeCfg.taskLists && stream.match(taskListRE, false)) {181state.taskList = true;182}183state.f = state.inline;184if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];185return getType(state);186} else if (modeCfg.fencedCodeBlocks && stream.match(/^```([\w+#]*)/, true)) {187// try switching mode188state.localMode = getMode(RegExp.$1);189if (state.localMode) state.localState = state.localMode.startState();190switchBlock(stream, state, local);191if (modeCfg.highlightFormatting) state.formatting = "code-block";192state.code = true;193return getType(state);194}195196return switchInline(stream, state, state.inline);197}198199function htmlBlock(stream, state) {200var style = htmlMode.token(stream, state.htmlState);201if ((htmlFound && !state.htmlState.tagName && !state.htmlState.context) ||202(state.md_inside && stream.current().indexOf(">") > -1)) {203state.f = inlineNormal;204state.block = blockNormal;205state.htmlState = null;206}207return style;208}209210function local(stream, state) {211if (stream.sol() && stream.match(/^```/, true)) {212state.localMode = state.localState = null;213state.f = inlineNormal;214state.block = blockNormal;215if (modeCfg.highlightFormatting) state.formatting = "code-block";216state.code = true;217var returnType = getType(state);218state.code = false;219return returnType;220} else if (state.localMode) {221return state.localMode.token(stream, state.localState);222} else {223stream.skipToEnd();224return code;225}226}227228// Inline229function getType(state) {230var styles = [];231232if (state.formatting) {233styles.push(formatting);234235if (typeof state.formatting === "string") state.formatting = [state.formatting];236237for (var i = 0; i < state.formatting.length; i++) {238styles.push(formatting + "-" + state.formatting[i]);239240if (state.formatting[i] === "header") {241styles.push(formatting + "-" + state.formatting[i] + state.header);242}243244// Add `formatting-quote` and `formatting-quote-#` for blockquotes245// Add `error` instead if the maximum blockquote nesting depth is passed246if (state.formatting[i] === "quote") {247if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {248styles.push(formatting + "-" + state.formatting[i] + "-" + state.quote);249} else {250styles.push("error");251}252}253}254}255256if (state.taskOpen) {257styles.push("meta");258return styles.length ? styles.join(' ') : null;259}260if (state.taskClosed) {261styles.push("property");262return styles.length ? styles.join(' ') : null;263}264265if (state.linkHref) {266styles.push(linkhref);267return styles.length ? styles.join(' ') : null;268}269270if (state.strong) { styles.push(strong); }271if (state.em) { styles.push(em); }272273if (state.linkText) { styles.push(linktext); }274275if (state.code) { styles.push(code); }276277if (state.header) { styles.push(header); styles.push(header + state.header); }278279if (state.quote) {280styles.push(quote);281282// Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth283if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {284styles.push(quote + "-" + state.quote);285} else {286styles.push(quote + "-" + modeCfg.maxBlockquoteDepth);287}288}289290if (state.list !== false) {291var listMod = (state.listDepth - 1) % 3;292if (!listMod) {293styles.push(list1);294} else if (listMod === 1) {295styles.push(list2);296} else {297styles.push(list3);298}299}300301if (state.trailingSpaceNewLine) {302styles.push("trailing-space-new-line");303} else if (state.trailingSpace) {304styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b"));305}306307return styles.length ? styles.join(' ') : null;308}309310function handleText(stream, state) {311if (stream.match(textRE, true)) {312return getType(state);313}314return undefined;315}316317function inlineNormal(stream, state) {318var style = state.text(stream, state);319if (typeof style !== 'undefined')320return style;321322if (state.list) { // List marker (*, +, -, 1., etc)323state.list = null;324return getType(state);325}326327if (state.taskList) {328var taskOpen = stream.match(taskListRE, true)[1] !== "x";329if (taskOpen) state.taskOpen = true;330else state.taskClosed = true;331if (modeCfg.highlightFormatting) state.formatting = "task";332state.taskList = false;333return getType(state);334}335336state.taskOpen = false;337state.taskClosed = false;338339if (state.header && stream.match(/^#+$/, true)) {340if (modeCfg.highlightFormatting) state.formatting = "header";341return getType(state);342}343344// Get sol() value now, before character is consumed345var sol = stream.sol();346347var ch = stream.next();348349if (state.escape) {350state.escape = false;351return getType(state);352}353354if (ch === '\\') {355if (modeCfg.highlightFormatting) state.formatting = "escape";356state.escape = true;357return getType(state);358}359360// Matches link titles present on next line361if (state.linkTitle) {362state.linkTitle = false;363var matchCh = ch;364if (ch === '(') {365matchCh = ')';366}367matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");368var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;369if (stream.match(new RegExp(regex), true)) {370return linkhref;371}372}373374// If this block is changed, it may need to be updated in GFM mode375if (ch === '`') {376var previousFormatting = state.formatting;377if (modeCfg.highlightFormatting) state.formatting = "code";378var t = getType(state);379var before = stream.pos;380stream.eatWhile('`');381var difference = 1 + stream.pos - before;382if (!state.code) {383codeDepth = difference;384state.code = true;385return getType(state);386} else {387if (difference === codeDepth) { // Must be exact388state.code = false;389return t;390}391state.formatting = previousFormatting;392return getType(state);393}394} else if (state.code) {395return getType(state);396}397398if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {399stream.match(/\[[^\]]*\]/);400state.inline = state.f = linkHref;401return image;402}403404if (ch === '[' && stream.match(/.*\](\(| ?\[)/, false)) {405state.linkText = true;406if (modeCfg.highlightFormatting) state.formatting = "link";407return getType(state);408}409410if (ch === ']' && state.linkText) {411if (modeCfg.highlightFormatting) state.formatting = "link";412var type = getType(state);413state.linkText = false;414state.inline = state.f = linkHref;415return type;416}417418if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) {419state.f = state.inline = linkInline;420if (modeCfg.highlightFormatting) state.formatting = "link";421var type = getType(state);422if (type){423type += " ";424} else {425type = "";426}427return type + linkinline;428}429430if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) {431state.f = state.inline = linkInline;432if (modeCfg.highlightFormatting) state.formatting = "link";433var type = getType(state);434if (type){435type += " ";436} else {437type = "";438}439return type + linkemail;440}441442if (ch === '<' && stream.match(/^\w/, false)) {443if (stream.string.indexOf(">") != -1) {444var atts = stream.string.substring(1,stream.string.indexOf(">"));445if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) {446state.md_inside = true;447}448}449stream.backUp(1);450state.htmlState = CodeMirror.startState(htmlMode);451return switchBlock(stream, state, htmlBlock);452}453454if (ch === '<' && stream.match(/^\/\w*?>/)) {455state.md_inside = false;456return "tag";457}458459var ignoreUnderscore = false;460if (!modeCfg.underscoresBreakWords) {461if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) {462var prevPos = stream.pos - 2;463if (prevPos >= 0) {464var prevCh = stream.string.charAt(prevPos);465if (prevCh !== '_' && prevCh.match(/(\w)/, false)) {466ignoreUnderscore = true;467}468}469}470}471if (ch === '*' || (ch === '_' && !ignoreUnderscore)) {472if (sol && stream.peek() === ' ') {473// Do nothing, surrounded by newline and space474} else if (state.strong === ch && stream.eat(ch)) { // Remove STRONG475if (modeCfg.highlightFormatting) state.formatting = "strong";476var t = getType(state);477state.strong = false;478return t;479} else if (!state.strong && stream.eat(ch)) { // Add STRONG480state.strong = ch;481if (modeCfg.highlightFormatting) state.formatting = "strong";482return getType(state);483} else if (state.em === ch) { // Remove EM484if (modeCfg.highlightFormatting) state.formatting = "em";485var t = getType(state);486state.em = false;487return t;488} else if (!state.em) { // Add EM489state.em = ch;490if (modeCfg.highlightFormatting) state.formatting = "em";491return getType(state);492}493} else if (ch === ' ') {494if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces495if (stream.peek() === ' ') { // Surrounded by spaces, ignore496return getType(state);497} else { // Not surrounded by spaces, back up pointer498stream.backUp(1);499}500}501}502503if (ch === ' ') {504if (stream.match(/ +$/, false)) {505state.trailingSpace++;506} else if (state.trailingSpace) {507state.trailingSpaceNewLine = true;508}509}510511return getType(state);512}513514function linkInline(stream, state) {515var ch = stream.next();516517if (ch === ">") {518state.f = state.inline = inlineNormal;519if (modeCfg.highlightFormatting) state.formatting = "link";520var type = getType(state);521if (type){522type += " ";523} else {524type = "";525}526return type + linkinline;527}528529stream.match(/^[^>]+/, true);530531return linkinline;532}533534function linkHref(stream, state) {535// Check if space, and return NULL if so (to avoid marking the space)536if(stream.eatSpace()){537return null;538}539var ch = stream.next();540if (ch === '(' || ch === '[') {541state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]");542if (modeCfg.highlightFormatting) state.formatting = "link-string";543state.linkHref = true;544return getType(state);545}546return 'error';547}548549function getLinkHrefInside(endChar) {550return function(stream, state) {551var ch = stream.next();552553if (ch === endChar) {554state.f = state.inline = inlineNormal;555if (modeCfg.highlightFormatting) state.formatting = "link-string";556var returnState = getType(state);557state.linkHref = false;558return returnState;559}560561if (stream.match(inlineRE(endChar), true)) {562stream.backUp(1);563}564565state.linkHref = true;566return getType(state);567};568}569570function footnoteLink(stream, state) {571if (stream.match(/^[^\]]*\]:/, false)) {572state.f = footnoteLinkInside;573stream.next(); // Consume [574if (modeCfg.highlightFormatting) state.formatting = "link";575state.linkText = true;576return getType(state);577}578return switchInline(stream, state, inlineNormal);579}580581function footnoteLinkInside(stream, state) {582if (stream.match(/^\]:/, true)) {583state.f = state.inline = footnoteUrl;584if (modeCfg.highlightFormatting) state.formatting = "link";585var returnType = getType(state);586state.linkText = false;587return returnType;588}589590stream.match(/^[^\]]+/, true);591592return linktext;593}594595function footnoteUrl(stream, state) {596// Check if space, and return NULL if so (to avoid marking the space)597if(stream.eatSpace()){598return null;599}600// Match URL601stream.match(/^[^\s]+/, true);602// Check for link title603if (stream.peek() === undefined) { // End of line, set flag to check next line604state.linkTitle = true;605} else { // More content on line, check if link title606stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);607}608state.f = state.inline = inlineNormal;609return linkhref;610}611612var savedInlineRE = [];613function inlineRE(endChar) {614if (!savedInlineRE[endChar]) {615// Escape endChar for RegExp (taken from http://stackoverflow.com/a/494122/526741)616endChar = (endChar+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");617// Match any non-endChar, escaped character, as well as the closing618// endChar.619savedInlineRE[endChar] = new RegExp('^(?:[^\\\\]|\\\\.)*?(' + endChar + ')');620}621return savedInlineRE[endChar];622}623624var mode = {625startState: function() {626return {627f: blockNormal,628629prevLineHasContent: false,630thisLineHasContent: false,631632block: blockNormal,633htmlState: null,634indentation: 0,635636inline: inlineNormal,637text: handleText,638639escape: false,640formatting: false,641linkText: false,642linkHref: false,643linkTitle: false,644em: false,645strong: false,646header: 0,647taskList: false,648list: false,649listDepth: 0,650quote: 0,651trailingSpace: 0,652trailingSpaceNewLine: false653};654},655656copyState: function(s) {657return {658f: s.f,659660prevLineHasContent: s.prevLineHasContent,661thisLineHasContent: s.thisLineHasContent,662663block: s.block,664htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState),665indentation: s.indentation,666667localMode: s.localMode,668localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null,669670inline: s.inline,671text: s.text,672escape: false,673formatting: false,674linkTitle: s.linkTitle,675em: s.em,676strong: s.strong,677header: s.header,678taskList: s.taskList,679list: s.list,680listDepth: s.listDepth,681quote: s.quote,682trailingSpace: s.trailingSpace,683trailingSpaceNewLine: s.trailingSpaceNewLine,684md_inside: s.md_inside685};686},687688token: function(stream, state) {689690// Reset state.formatting691state.formatting = false;692693if (stream.sol()) {694var forceBlankLine = stream.match(/^\s*$/, true) || state.header;695696// Reset state.header697state.header = 0;698699if (forceBlankLine) {700state.prevLineHasContent = false;701return blankLine(state);702} else {703state.prevLineHasContent = state.thisLineHasContent;704state.thisLineHasContent = true;705}706707// Reset state.escape708state.escape = false;709710// Reset state.taskList711state.taskList = false;712713// Reset state.code714state.code = false;715716// Reset state.trailingSpace717state.trailingSpace = 0;718state.trailingSpaceNewLine = false;719720state.f = state.block;721var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;722var difference = Math.floor((indentation - state.indentation) / 4) * 4;723if (difference > 4) difference = 4;724var adjustedIndentation = state.indentation + difference;725state.indentationDiff = adjustedIndentation - state.indentation;726state.indentation = adjustedIndentation;727if (indentation > 0) return null;728}729return state.f(stream, state);730},731732innerMode: function(state) {733if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode};734if (state.localState) return {state: state.localState, mode: state.localMode};735return {state: state, mode: mode};736},737738blankLine: blankLine,739740getType: getType741};742return mode;743}, "xml");744745CodeMirror.defineMIME("text/x-markdown", "markdown");746747748