File manager - Edit - /home/newsbmcs.com/public_html/static/img/logo/markdown.tar
Back
markdown.js 0000644 00000075154 15030342556 0006743 0 ustar 00 // CodeMirror, copyright (c) by Marijn Haverbeke and others // Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS mod(require("../../lib/codemirror"), require("../xml/xml"), require("../meta")); else if (typeof define == "function" && define.amd) // AMD define(["../../lib/codemirror", "../xml/xml", "../meta"], mod); else // Plain browser env mod(CodeMirror); })(function(CodeMirror) { "use strict"; CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { var htmlMode = CodeMirror.getMode(cmCfg, "text/html"); var htmlModeMissing = htmlMode.name == "null" function getMode(name) { if (CodeMirror.findModeByName) { var found = CodeMirror.findModeByName(name); if (found) name = found.mime || found.mimes[0]; } var mode = CodeMirror.getMode(cmCfg, name); return mode.name == "null" ? null : mode; } // Should characters that affect highlighting be highlighted separate? // Does not include characters that will be output (such as `1.` and `-` for lists) if (modeCfg.highlightFormatting === undefined) modeCfg.highlightFormatting = false; // Maximum number of nested blockquotes. Set to 0 for infinite nesting. // Excess `>` will emit `error` token. if (modeCfg.maxBlockquoteDepth === undefined) modeCfg.maxBlockquoteDepth = 0; // Turn on task lists? ("- [ ] " and "- [x] ") if (modeCfg.taskLists === undefined) modeCfg.taskLists = false; // Turn on strikethrough syntax if (modeCfg.strikethrough === undefined) modeCfg.strikethrough = false; if (modeCfg.emoji === undefined) modeCfg.emoji = false; if (modeCfg.fencedCodeBlockHighlighting === undefined) modeCfg.fencedCodeBlockHighlighting = true; if (modeCfg.fencedCodeBlockDefaultMode === undefined) modeCfg.fencedCodeBlockDefaultMode = 'text/plain'; if (modeCfg.xml === undefined) modeCfg.xml = true; // Allow token types to be overridden by user-provided token types. if (modeCfg.tokenTypeOverrides === undefined) modeCfg.tokenTypeOverrides = {}; var tokenTypes = { header: "header", code: "comment", quote: "quote", list1: "variable-2", list2: "variable-3", list3: "keyword", hr: "hr", image: "image", imageAltText: "image-alt-text", imageMarker: "image-marker", formatting: "formatting", linkInline: "link", linkEmail: "link", linkText: "link", linkHref: "string", em: "em", strong: "strong", strikethrough: "strikethrough", emoji: "builtin" }; for (var tokenType in tokenTypes) { if (tokenTypes.hasOwnProperty(tokenType) && modeCfg.tokenTypeOverrides[tokenType]) { tokenTypes[tokenType] = modeCfg.tokenTypeOverrides[tokenType]; } } var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/ , listRE = /^(?:[*\-+]|^[0-9]+([.)]))\s+/ , taskListRE = /^\[(x| )\](?=\s)/i // Must follow listRE , atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/ , setextHeaderRE = /^ {0,3}(?:\={1,}|-{2,})\s*$/ , textRE = /^[^#!\[\]*_\\<>` "'(~:]+/ , fencedCodeRE = /^(~~~+|```+)[ \t]*([\w\/+#-]*)[^\n`]*$/ , linkDefRE = /^\s*\[[^\]]+?\]:.*$/ // naive link-definition , 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]/ , expandedTab = " " // CommonMark specifies tab as 4 spaces function switchInline(stream, state, f) { state.f = state.inline = f; return f(stream, state); } function switchBlock(stream, state, f) { state.f = state.block = f; return f(stream, state); } function lineIsEmpty(line) { return !line || !/\S/.test(line.string) } // Blocks function blankLine(state) { // Reset linkTitle state state.linkTitle = false; state.linkHref = false; state.linkText = false; // Reset EM state state.em = false; // Reset STRONG state state.strong = false; // Reset strikethrough state state.strikethrough = false; // Reset state.quote state.quote = 0; // Reset state.indentedCode state.indentedCode = false; if (state.f == htmlBlock) { var exit = htmlModeMissing if (!exit) { var inner = CodeMirror.innerMode(htmlMode, state.htmlState) exit = inner.mode.name == "xml" && inner.state.tagStart === null && (!inner.state.context && inner.state.tokenize.isInText) } if (exit) { state.f = inlineNormal; state.block = blockNormal; state.htmlState = null; } } // Reset state.trailingSpace state.trailingSpace = 0; state.trailingSpaceNewLine = false; // Mark this line as blank state.prevLine = state.thisLine state.thisLine = {stream: null} return null; } function blockNormal(stream, state) { var firstTokenOnLine = stream.column() === state.indentation; var prevLineLineIsEmpty = lineIsEmpty(state.prevLine.stream); var prevLineIsIndentedCode = state.indentedCode; var prevLineIsHr = state.prevLine.hr; var prevLineIsList = state.list !== false; var maxNonCodeIndentation = (state.listStack[state.listStack.length - 1] || 0) + 3; state.indentedCode = false; var lineIndentation = state.indentation; // compute once per line (on first token) if (state.indentationDiff === null) { state.indentationDiff = state.indentation; if (prevLineIsList) { state.list = null; // While this list item's marker's indentation is less than the deepest // list item's content's indentation,pop the deepest list item // indentation off the stack, and update block indentation state while (lineIndentation < state.listStack[state.listStack.length - 1]) { state.listStack.pop(); if (state.listStack.length) { state.indentation = state.listStack[state.listStack.length - 1]; // less than the first list's indent -> the line is no longer a list } else { state.list = false; } } if (state.list !== false) { state.indentationDiff = lineIndentation - state.listStack[state.listStack.length - 1] } } } // not comprehensive (currently only for setext detection purposes) var allowsInlineContinuation = ( !prevLineLineIsEmpty && !prevLineIsHr && !state.prevLine.header && (!prevLineIsList || !prevLineIsIndentedCode) && !state.prevLine.fencedCodeEnd ); var isHr = (state.list === false || prevLineIsHr || prevLineLineIsEmpty) && state.indentation <= maxNonCodeIndentation && stream.match(hrRE); var match = null; if (state.indentationDiff >= 4 && (prevLineIsIndentedCode || state.prevLine.fencedCodeEnd || state.prevLine.header || prevLineLineIsEmpty)) { stream.skipToEnd(); state.indentedCode = true; return tokenTypes.code; } else if (stream.eatSpace()) { return null; } else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(atxHeaderRE)) && match[1].length <= 6) { state.quote = 0; state.header = match[1].length; state.thisLine.header = true; if (modeCfg.highlightFormatting) state.formatting = "header"; state.f = state.inline; return getType(state); } else if (state.indentation <= maxNonCodeIndentation && stream.eat('>')) { state.quote = firstTokenOnLine ? 1 : state.quote + 1; if (modeCfg.highlightFormatting) state.formatting = "quote"; stream.eatSpace(); return getType(state); } else if (!isHr && !state.setext && firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(listRE))) { var listType = match[1] ? "ol" : "ul"; state.indentation = lineIndentation + stream.current().length; state.list = true; state.quote = 0; // Add this list item's content's indentation to the stack state.listStack.push(state.indentation); // Reset inline styles which shouldn't propagate aross list items state.em = false; state.strong = false; state.code = false; state.strikethrough = false; if (modeCfg.taskLists && stream.match(taskListRE, false)) { state.taskList = true; } state.f = state.inline; if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType]; return getType(state); } else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(fencedCodeRE, true))) { state.quote = 0; state.fencedEndRE = new RegExp(match[1] + "+ *$"); // try switching mode state.localMode = modeCfg.fencedCodeBlockHighlighting && getMode(match[2] || modeCfg.fencedCodeBlockDefaultMode ); if (state.localMode) state.localState = CodeMirror.startState(state.localMode); state.f = state.block = local; if (modeCfg.highlightFormatting) state.formatting = "code-block"; state.code = -1 return getType(state); // SETEXT has lowest block-scope precedence after HR, so check it after // the others (code, blockquote, list...) } else if ( // if setext set, indicates line after ---/=== state.setext || ( // line before ---/=== (!allowsInlineContinuation || !prevLineIsList) && !state.quote && state.list === false && !state.code && !isHr && !linkDefRE.test(stream.string) && (match = stream.lookAhead(1)) && (match = match.match(setextHeaderRE)) ) ) { if ( !state.setext ) { state.header = match[0].charAt(0) == '=' ? 1 : 2; state.setext = state.header; } else { state.header = state.setext; // has no effect on type so we can reset it now state.setext = 0; stream.skipToEnd(); if (modeCfg.highlightFormatting) state.formatting = "header"; } state.thisLine.header = true; state.f = state.inline; return getType(state); } else if (isHr) { stream.skipToEnd(); state.hr = true; state.thisLine.hr = true; return tokenTypes.hr; } else if (stream.peek() === '[') { return switchInline(stream, state, footnoteLink); } return switchInline(stream, state, state.inline); } function htmlBlock(stream, state) { var style = htmlMode.token(stream, state.htmlState); if (!htmlModeMissing) { var inner = CodeMirror.innerMode(htmlMode, state.htmlState) if ((inner.mode.name == "xml" && inner.state.tagStart === null && (!inner.state.context && inner.state.tokenize.isInText)) || (state.md_inside && stream.current().indexOf(">") > -1)) { state.f = inlineNormal; state.block = blockNormal; state.htmlState = null; } } return style; } function local(stream, state) { var currListInd = state.listStack[state.listStack.length - 1] || 0; var hasExitedList = state.indentation < currListInd; var maxFencedEndInd = currListInd + 3; if (state.fencedEndRE && state.indentation <= maxFencedEndInd && (hasExitedList || stream.match(state.fencedEndRE))) { if (modeCfg.highlightFormatting) state.formatting = "code-block"; var returnType; if (!hasExitedList) returnType = getType(state) state.localMode = state.localState = null; state.block = blockNormal; state.f = inlineNormal; state.fencedEndRE = null; state.code = 0 state.thisLine.fencedCodeEnd = true; if (hasExitedList) return switchBlock(stream, state, state.block); return returnType; } else if (state.localMode) { return state.localMode.token(stream, state.localState); } else { stream.skipToEnd(); return tokenTypes.code; } } // Inline function getType(state) { var styles = []; if (state.formatting) { styles.push(tokenTypes.formatting); if (typeof state.formatting === "string") state.formatting = [state.formatting]; for (var i = 0; i < state.formatting.length; i++) { styles.push(tokenTypes.formatting + "-" + state.formatting[i]); if (state.formatting[i] === "header") { styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.header); } // Add `formatting-quote` and `formatting-quote-#` for blockquotes // Add `error` instead if the maximum blockquote nesting depth is passed if (state.formatting[i] === "quote") { if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) { styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.quote); } else { styles.push("error"); } } } } if (state.taskOpen) { styles.push("meta"); return styles.length ? styles.join(' ') : null; } if (state.taskClosed) { styles.push("property"); return styles.length ? styles.join(' ') : null; } if (state.linkHref) { styles.push(tokenTypes.linkHref, "url"); } else { // Only apply inline styles to non-url text if (state.strong) { styles.push(tokenTypes.strong); } if (state.em) { styles.push(tokenTypes.em); } if (state.strikethrough) { styles.push(tokenTypes.strikethrough); } if (state.emoji) { styles.push(tokenTypes.emoji); } if (state.linkText) { styles.push(tokenTypes.linkText); } if (state.code) { styles.push(tokenTypes.code); } if (state.image) { styles.push(tokenTypes.image); } if (state.imageAltText) { styles.push(tokenTypes.imageAltText, "link"); } if (state.imageMarker) { styles.push(tokenTypes.imageMarker); } } if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); } if (state.quote) { styles.push(tokenTypes.quote); // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) { styles.push(tokenTypes.quote + "-" + state.quote); } else { styles.push(tokenTypes.quote + "-" + modeCfg.maxBlockquoteDepth); } } if (state.list !== false) { var listMod = (state.listStack.length - 1) % 3; if (!listMod) { styles.push(tokenTypes.list1); } else if (listMod === 1) { styles.push(tokenTypes.list2); } else { styles.push(tokenTypes.list3); } } if (state.trailingSpaceNewLine) { styles.push("trailing-space-new-line"); } else if (state.trailingSpace) { styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b")); } return styles.length ? styles.join(' ') : null; } function handleText(stream, state) { if (stream.match(textRE, true)) { return getType(state); } return undefined; } function inlineNormal(stream, state) { var style = state.text(stream, state); if (typeof style !== 'undefined') return style; if (state.list) { // List marker (*, +, -, 1., etc) state.list = null; return getType(state); } if (state.taskList) { var taskOpen = stream.match(taskListRE, true)[1] === " "; if (taskOpen) state.taskOpen = true; else state.taskClosed = true; if (modeCfg.highlightFormatting) state.formatting = "task"; state.taskList = false; return getType(state); } state.taskOpen = false; state.taskClosed = false; if (state.header && stream.match(/^#+$/, true)) { if (modeCfg.highlightFormatting) state.formatting = "header"; return getType(state); } var ch = stream.next(); // Matches link titles present on next line if (state.linkTitle) { state.linkTitle = false; var matchCh = ch; if (ch === '(') { matchCh = ')'; } matchCh = (matchCh+'').replace(/([.?*+^\[\]\\(){}|-])/g, "\\$1"); var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh; if (stream.match(new RegExp(regex), true)) { return tokenTypes.linkHref; } } // If this block is changed, it may need to be updated in GFM mode if (ch === '`') { var previousFormatting = state.formatting; if (modeCfg.highlightFormatting) state.formatting = "code"; stream.eatWhile('`'); var count = stream.current().length if (state.code == 0 && (!state.quote || count == 1)) { state.code = count return getType(state) } else if (count == state.code) { // Must be exact var t = getType(state) state.code = 0 return t } else { state.formatting = previousFormatting return getType(state) } } else if (state.code) { return getType(state); } if (ch === '\\') { stream.next(); if (modeCfg.highlightFormatting) { var type = getType(state); var formattingEscape = tokenTypes.formatting + "-escape"; return type ? type + " " + formattingEscape : formattingEscape; } } if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) { state.imageMarker = true; state.image = true; if (modeCfg.highlightFormatting) state.formatting = "image"; return getType(state); } if (ch === '[' && state.imageMarker && stream.match(/[^\]]*\](\(.*?\)| ?\[.*?\])/, false)) { state.imageMarker = false; state.imageAltText = true if (modeCfg.highlightFormatting) state.formatting = "image"; return getType(state); } if (ch === ']' && state.imageAltText) { if (modeCfg.highlightFormatting) state.formatting = "image"; var type = getType(state); state.imageAltText = false; state.image = false; state.inline = state.f = linkHref; return type; } if (ch === '[' && !state.image) { if (state.linkText && stream.match(/^.*?\]/)) return getType(state) state.linkText = true; if (modeCfg.highlightFormatting) state.formatting = "link"; return getType(state); } if (ch === ']' && state.linkText) { if (modeCfg.highlightFormatting) state.formatting = "link"; var type = getType(state); state.linkText = false; state.inline = state.f = stream.match(/\(.*?\)| ?\[.*?\]/, false) ? linkHref : inlineNormal return type; } if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) { state.f = state.inline = linkInline; if (modeCfg.highlightFormatting) state.formatting = "link"; var type = getType(state); if (type){ type += " "; } else { type = ""; } return type + tokenTypes.linkInline; } if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) { state.f = state.inline = linkInline; if (modeCfg.highlightFormatting) state.formatting = "link"; var type = getType(state); if (type){ type += " "; } else { type = ""; } return type + tokenTypes.linkEmail; } if (modeCfg.xml && ch === '<' && stream.match(/^(!--|\?|!\[CDATA\[|[a-z][a-z0-9-]*(?:\s+[a-z_:.\-]+(?:\s*=\s*[^>]+)?)*\s*(?:>|$))/i, false)) { var end = stream.string.indexOf(">", stream.pos); if (end != -1) { var atts = stream.string.substring(stream.start, end); if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) state.md_inside = true; } stream.backUp(1); state.htmlState = CodeMirror.startState(htmlMode); return switchBlock(stream, state, htmlBlock); } if (modeCfg.xml && ch === '<' && stream.match(/^\/\w*?>/)) { state.md_inside = false; return "tag"; } else if (ch === "*" || ch === "_") { var len = 1, before = stream.pos == 1 ? " " : stream.string.charAt(stream.pos - 2) while (len < 3 && stream.eat(ch)) len++ var after = stream.peek() || " " // See http://spec.commonmark.org/0.27/#emphasis-and-strong-emphasis var leftFlanking = !/\s/.test(after) && (!punctuation.test(after) || /\s/.test(before) || punctuation.test(before)) var rightFlanking = !/\s/.test(before) && (!punctuation.test(before) || /\s/.test(after) || punctuation.test(after)) var setEm = null, setStrong = null if (len % 2) { // Em if (!state.em && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before))) setEm = true else if (state.em == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after))) setEm = false } if (len > 1) { // Strong if (!state.strong && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before))) setStrong = true else if (state.strong == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after))) setStrong = false } if (setStrong != null || setEm != null) { if (modeCfg.highlightFormatting) state.formatting = setEm == null ? "strong" : setStrong == null ? "em" : "strong em" if (setEm === true) state.em = ch if (setStrong === true) state.strong = ch var t = getType(state) if (setEm === false) state.em = false if (setStrong === false) state.strong = false return t } } else if (ch === ' ') { if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces if (stream.peek() === ' ') { // Surrounded by spaces, ignore return getType(state); } else { // Not surrounded by spaces, back up pointer stream.backUp(1); } } } if (modeCfg.strikethrough) { if (ch === '~' && stream.eatWhile(ch)) { if (state.strikethrough) {// Remove strikethrough if (modeCfg.highlightFormatting) state.formatting = "strikethrough"; var t = getType(state); state.strikethrough = false; return t; } else if (stream.match(/^[^\s]/, false)) {// Add strikethrough state.strikethrough = true; if (modeCfg.highlightFormatting) state.formatting = "strikethrough"; return getType(state); } } else if (ch === ' ') { if (stream.match(/^~~/, true)) { // Probably surrounded by space if (stream.peek() === ' ') { // Surrounded by spaces, ignore return getType(state); } else { // Not surrounded by spaces, back up pointer stream.backUp(2); } } } } if (modeCfg.emoji && ch === ":" && stream.match(/^(?:[a-z_\d+][a-z_\d+-]*|\-[a-z_\d+][a-z_\d+-]*):/)) { state.emoji = true; if (modeCfg.highlightFormatting) state.formatting = "emoji"; var retType = getType(state); state.emoji = false; return retType; } if (ch === ' ') { if (stream.match(/^ +$/, false)) { state.trailingSpace++; } else if (state.trailingSpace) { state.trailingSpaceNewLine = true; } } return getType(state); } function linkInline(stream, state) { var ch = stream.next(); if (ch === ">") { state.f = state.inline = inlineNormal; if (modeCfg.highlightFormatting) state.formatting = "link"; var type = getType(state); if (type){ type += " "; } else { type = ""; } return type + tokenTypes.linkInline; } stream.match(/^[^>]+/, true); return tokenTypes.linkInline; } function linkHref(stream, state) { // Check if space, and return NULL if so (to avoid marking the space) if(stream.eatSpace()){ return null; } var ch = stream.next(); if (ch === '(' || ch === '[') { state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]"); if (modeCfg.highlightFormatting) state.formatting = "link-string"; state.linkHref = true; return getType(state); } return 'error'; } var linkRE = { ")": /^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/, "]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\]]|\\.)*\])*?(?=\])/ } function getLinkHrefInside(endChar) { return function(stream, state) { var ch = stream.next(); if (ch === endChar) { state.f = state.inline = inlineNormal; if (modeCfg.highlightFormatting) state.formatting = "link-string"; var returnState = getType(state); state.linkHref = false; return returnState; } stream.match(linkRE[endChar]) state.linkHref = true; return getType(state); }; } function footnoteLink(stream, state) { if (stream.match(/^([^\]\\]|\\.)*\]:/, false)) { state.f = footnoteLinkInside; stream.next(); // Consume [ if (modeCfg.highlightFormatting) state.formatting = "link"; state.linkText = true; return getType(state); } return switchInline(stream, state, inlineNormal); } function footnoteLinkInside(stream, state) { if (stream.match(/^\]:/, true)) { state.f = state.inline = footnoteUrl; if (modeCfg.highlightFormatting) state.formatting = "link"; var returnType = getType(state); state.linkText = false; return returnType; } stream.match(/^([^\]\\]|\\.)+/, true); return tokenTypes.linkText; } function footnoteUrl(stream, state) { // Check if space, and return NULL if so (to avoid marking the space) if(stream.eatSpace()){ return null; } // Match URL stream.match(/^[^\s]+/, true); // Check for link title if (stream.peek() === undefined) { // End of line, set flag to check next line state.linkTitle = true; } else { // More content on line, check if link title stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true); } state.f = state.inline = inlineNormal; return tokenTypes.linkHref + " url"; } var mode = { startState: function() { return { f: blockNormal, prevLine: {stream: null}, thisLine: {stream: null}, block: blockNormal, htmlState: null, indentation: 0, inline: inlineNormal, text: handleText, formatting: false, linkText: false, linkHref: false, linkTitle: false, code: 0, em: false, strong: false, header: 0, setext: 0, hr: false, taskList: false, list: false, listStack: [], quote: 0, trailingSpace: 0, trailingSpaceNewLine: false, strikethrough: false, emoji: false, fencedEndRE: null }; }, copyState: function(s) { return { f: s.f, prevLine: s.prevLine, thisLine: s.thisLine, block: s.block, htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState), indentation: s.indentation, localMode: s.localMode, localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null, inline: s.inline, text: s.text, formatting: false, linkText: s.linkText, linkTitle: s.linkTitle, linkHref: s.linkHref, code: s.code, em: s.em, strong: s.strong, strikethrough: s.strikethrough, emoji: s.emoji, header: s.header, setext: s.setext, hr: s.hr, taskList: s.taskList, list: s.list, listStack: s.listStack.slice(0), quote: s.quote, indentedCode: s.indentedCode, trailingSpace: s.trailingSpace, trailingSpaceNewLine: s.trailingSpaceNewLine, md_inside: s.md_inside, fencedEndRE: s.fencedEndRE }; }, token: function(stream, state) { // Reset state.formatting state.formatting = false; if (stream != state.thisLine.stream) { state.header = 0; state.hr = false; if (stream.match(/^\s*$/, true)) { blankLine(state); return null; } state.prevLine = state.thisLine state.thisLine = {stream: stream} // Reset state.taskList state.taskList = false; // Reset state.trailingSpace state.trailingSpace = 0; state.trailingSpaceNewLine = false; if (!state.localState) { state.f = state.block; if (state.f != htmlBlock) { var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, expandedTab).length; state.indentation = indentation; state.indentationDiff = null; if (indentation > 0) return null; } } } return state.f(stream, state); }, innerMode: function(state) { if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode}; if (state.localState) return {state: state.localState, mode: state.localMode}; return {state: state, mode: mode}; }, indent: function(state, textAfter, line) { if (state.block == htmlBlock && htmlMode.indent) return htmlMode.indent(state.htmlState, textAfter, line) if (state.localState && state.localMode.indent) return state.localMode.indent(state.localState, textAfter, line) return CodeMirror.Pass }, blankLine: blankLine, getType: getType, blockCommentStart: "<!--", blockCommentEnd: "-->", closeBrackets: "()[]{}''\"\"``", fold: "markdown" }; return mode; }, "xml"); CodeMirror.defineMIME("text/markdown", "markdown"); CodeMirror.defineMIME("text/x-markdown", "markdown"); }); test.js 0000644 00000113736 15030342556 0006077 0 ustar 00 // CodeMirror, copyright (c) by Marijn Haverbeke and others // Distributed under an MIT license: https://codemirror.net/LICENSE (function() { var config = {tabSize: 4, indentUnit: 2} var mode = CodeMirror.getMode(config, "markdown"); function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } var modeHighlightFormatting = CodeMirror.getMode(config, {name: "markdown", highlightFormatting: true}); function FT(name) { test.mode(name, modeHighlightFormatting, Array.prototype.slice.call(arguments, 1)); } var modeMT_noXml = CodeMirror.getMode(config, {name: "markdown", xml: false}); function MT_noXml(name) { test.mode(name, modeMT_noXml, Array.prototype.slice.call(arguments, 1)); } var modeMT_noFencedHighlight = CodeMirror.getMode(config, {name: "markdown", fencedCodeBlockHighlighting: false}); function MT_noFencedHighlight(name) { test.mode(name, modeMT_noFencedHighlight, Array.prototype.slice.call(arguments, 1)); } var modeAtxNoSpace = CodeMirror.getMode(config, {name: "markdown", allowAtxHeaderWithoutSpace: true}); function AtxNoSpaceTest(name) { test.mode(name, modeAtxNoSpace, Array.prototype.slice.call(arguments, 1)); } var modeOverrideClasses = CodeMirror.getMode(config, { name: "markdown", strikethrough: true, emoji: true, tokenTypeOverrides: { "header" : "override-header", "code" : "override-code", "quote" : "override-quote", "list1" : "override-list1", "list2" : "override-list2", "list3" : "override-list3", "hr" : "override-hr", "image" : "override-image", "imageAltText": "override-image-alt-text", "imageMarker": "override-image-marker", "linkInline" : "override-link-inline", "linkEmail" : "override-link-email", "linkText" : "override-link-text", "linkHref" : "override-link-href", "em" : "override-em", "strong" : "override-strong", "strikethrough" : "override-strikethrough", "emoji" : "override-emoji" }}); function TokenTypeOverrideTest(name) { test.mode(name, modeOverrideClasses, Array.prototype.slice.call(arguments, 1)); } var modeFormattingOverride = CodeMirror.getMode(config, { name: "markdown", highlightFormatting: true, tokenTypeOverrides: { "formatting" : "override-formatting" }}); function FormatTokenTypeOverrideTest(name) { test.mode(name, modeFormattingOverride, Array.prototype.slice.call(arguments, 1)); } var modeET = CodeMirror.getMode(config, {name: "markdown", emoji: true}); function ET(name) { test.mode(name, modeET, Array.prototype.slice.call(arguments, 1)); } FT("formatting_emAsterisk", "[em&formatting&formatting-em *][em foo][em&formatting&formatting-em *]"); FT("formatting_emUnderscore", "[em&formatting&formatting-em _][em foo][em&formatting&formatting-em _]"); FT("formatting_strongAsterisk", "[strong&formatting&formatting-strong **][strong foo][strong&formatting&formatting-strong **]"); FT("formatting_strongUnderscore", "[strong&formatting&formatting-strong __][strong foo][strong&formatting&formatting-strong __]"); FT("formatting_codeBackticks", "[comment&formatting&formatting-code `][comment foo][comment&formatting&formatting-code `]"); FT("formatting_doubleBackticks", "[comment&formatting&formatting-code ``][comment foo ` bar][comment&formatting&formatting-code ``]"); FT("formatting_atxHeader", "[header&header-1&formatting&formatting-header&formatting-header-1 # ][header&header-1 foo # bar ][header&header-1&formatting&formatting-header&formatting-header-1 #]"); FT("formatting_setextHeader", "[header&header-1 foo]", "[header&header-1&formatting&formatting-header&formatting-header-1 =]"); FT("formatting_blockquote", "[quote"e-1&formatting&formatting-quote&formatting-quote-1 > ][quote"e-1 foo]"); FT("formatting_list", "[variable-2&formatting&formatting-list&formatting-list-ul - ][variable-2 foo]"); FT("formatting_list", "[variable-2&formatting&formatting-list&formatting-list-ol 1. ][variable-2 foo]"); FT("formatting_link", "[link&formatting&formatting-link [][link foo][link&formatting&formatting-link ]]][string&formatting&formatting-link-string&url (][string&url http://example.com/][string&formatting&formatting-link-string&url )]"); FT("formatting_linkReference", "[link&formatting&formatting-link [][link foo][link&formatting&formatting-link ]]][string&formatting&formatting-link-string&url [][string&url bar][string&formatting&formatting-link-string&url ]]]", "[link&formatting&formatting-link [][link bar][link&formatting&formatting-link ]]:] [string&url http://example.com/]"); FT("formatting_linkWeb", "[link&formatting&formatting-link <][link http://example.com/][link&formatting&formatting-link >]"); FT("formatting_linkEmail", "[link&formatting&formatting-link <][link user@example.com][link&formatting&formatting-link >]"); FT("formatting_escape", "[formatting-escape \\*]"); FT("formatting_image", "[formatting&formatting-image&image&image-marker !][formatting&formatting-image&image&image-alt-text&link [[][image&image-alt-text&link alt text][formatting&formatting-image&image&image-alt-text&link ]]][formatting&formatting-link-string&string&url (][url&string http://link.to/image.jpg][formatting&formatting-link-string&string&url )]"); FT("codeBlock", "[comment&formatting&formatting-code-block ```css]", "[tag foo]", "[comment&formatting&formatting-code-block ```]"); MT("plainText", "foo"); // Don't style single trailing space MT("trailingSpace1", "foo "); // Two or more trailing spaces should be styled with line break character MT("trailingSpace2", "foo[trailing-space-a ][trailing-space-new-line ]"); MT("trailingSpace3", "foo[trailing-space-a ][trailing-space-b ][trailing-space-new-line ]"); MT("trailingSpace4", "foo[trailing-space-a ][trailing-space-b ][trailing-space-a ][trailing-space-new-line ]"); // Code blocks using 4 spaces (regardless of CodeMirror.tabSize value) MT("codeBlocksUsing4Spaces", " [comment foo]"); // Code blocks using 4 spaces with internal indentation MT("codeBlocksUsing4SpacesIndentation", " [comment bar]", " [comment hello]", " [comment world]", " [comment foo]", "bar"); // Code blocks should end even after extra indented lines MT("codeBlocksWithTrailingIndentedLine", " [comment foo]", " [comment bar]", " [comment baz]", " ", "hello"); // Code blocks using 1 tab (regardless of CodeMirror.indentWithTabs value) MT("codeBlocksUsing1Tab", "\t[comment foo]"); // No code blocks directly after paragraph // http://spec.commonmark.org/0.19/#example-65 MT("noCodeBlocksAfterParagraph", "Foo", " Bar"); MT("codeBlocksAfterATX", "[header&header-1 # foo]", " [comment code]"); MT("codeBlocksAfterSetext", "[header&header-2 foo]", "[header&header-2 ---]", " [comment code]"); MT("codeBlocksAfterFencedCode", "[comment ```]", "[comment foo]", "[comment ```]", " [comment code]"); // Inline code using backticks MT("inlineCodeUsingBackticks", "foo [comment `bar`]"); // Block code using single backtick (shouldn't work) MT("blockCodeSingleBacktick", "[comment `]", "[comment foo]", "[comment `]"); // Unclosed backticks // Instead of simply marking as CODE, it would be nice to have an // incomplete flag for CODE, that is styled slightly different. MT("unclosedBackticks", "foo [comment `bar]"); // Per documentation: "To include a literal backtick character within a // code span, you can use multiple backticks as the opening and closing // delimiters" MT("doubleBackticks", "[comment ``foo ` bar``]"); // Tests based on Dingus // http://daringfireball.net/projects/markdown/dingus // // Multiple backticks within an inline code block MT("consecutiveBackticks", "[comment `foo```bar`]"); // Multiple backticks within an inline code block with a second code block MT("consecutiveBackticks", "[comment `foo```bar`] hello [comment `world`]"); // Unclosed with several different groups of backticks MT("unclosedBackticks", "[comment ``foo ``` bar` hello]"); // Closed with several different groups of backticks MT("closedBackticks", "[comment ``foo ``` bar` hello``] world"); // info string cannot contain backtick, thus should result in inline code MT("closingFencedMarksOnSameLine", "[comment ``` code ```] foo"); // atx headers // http://daringfireball.net/projects/markdown/syntax#header MT("atxH1", "[header&header-1 # foo]"); MT("atxH2", "[header&header-2 ## foo]"); MT("atxH3", "[header&header-3 ### foo]"); MT("atxH4", "[header&header-4 #### foo]"); MT("atxH5", "[header&header-5 ##### foo]"); MT("atxH6", "[header&header-6 ###### foo]"); // http://spec.commonmark.org/0.19/#example-24 MT("noAtxH7", "####### foo"); // http://spec.commonmark.org/0.19/#example-25 MT("noAtxH1WithoutSpace", "#5 bolt"); // CommonMark requires a space after # but most parsers don't AtxNoSpaceTest("atxNoSpaceAllowed_H1NoSpace", "[header&header-1 #foo]"); AtxNoSpaceTest("atxNoSpaceAllowed_H4NoSpace", "[header&header-4 ####foo]"); AtxNoSpaceTest("atxNoSpaceAllowed_H1Space", "[header&header-1 # foo]"); // Inline styles should be parsed inside headers MT("atxH1inline", "[header&header-1 # foo ][header&header-1&em *bar*]"); MT("atxIndentedTooMuch", "[header&header-1 # foo]", " [comment # bar]"); // disable atx inside blockquote until we implement proper blockquote inner mode // TODO: fix to be CommonMark-compliant MT("atxNestedInsideBlockquote", "[quote"e-1 > # foo]"); MT("atxAfterBlockquote", "[quote"e-1 > foo]", "[header&header-1 # bar]"); // Setext headers - H1, H2 // Per documentation, "Any number of underlining =’s or -’s will work." // http://daringfireball.net/projects/markdown/syntax#header // Ideally, the text would be marked as `header` as well, but this is // not really feasible at the moment. So, instead, we're testing against // what works today, to avoid any regressions. // // Check if single underlining = works MT("setextH1", "[header&header-1 foo]", "[header&header-1 =]"); // Check if 3+ ='s work MT("setextH1", "[header&header-1 foo]", "[header&header-1 ===]"); // Check if single underlining - should not be interpreted // as it might lead to an empty list: // https://spec.commonmark.org/0.28/#setext-heading-underline MT("setextH2Single", "foo", "-"); // Check if 3+ -'s work MT("setextH2", "[header&header-2 foo]", "[header&header-2 ---]"); // http://spec.commonmark.org/0.19/#example-45 MT("setextH2AllowSpaces", "[header&header-2 foo]", " [header&header-2 ---- ]"); // http://spec.commonmark.org/0.19/#example-44 MT("noSetextAfterIndentedCodeBlock", " [comment foo]", "[hr ---]"); MT("setextAfterFencedCode", "[comment ```]", "[comment foo]", "[comment ```]", "[header&header-2 bar]", "[header&header-2 ---]"); MT("setextAferATX", "[header&header-1 # foo]", "[header&header-2 bar]", "[header&header-2 ---]"); // http://spec.commonmark.org/0.19/#example-51 MT("noSetextAfterQuote", "[quote"e-1 > foo]", "[hr ---]", "", "[quote"e-1 > foo]", "[quote"e-1 bar]", "[hr ---]"); MT("noSetextAfterList", "[variable-2 - foo]", "[hr ---]"); MT("noSetextAfterList_listContinuation", "[variable-2 - foo]", "bar", "[hr ---]"); MT("setextAfterList_afterIndentedCode", "[variable-2 - foo]", "", " [comment bar]", "[header&header-2 baz]", "[header&header-2 ---]"); MT("setextAfterList_afterFencedCodeBlocks", "[variable-2 - foo]", "", " [comment ```]", " [comment bar]", " [comment ```]", "[header&header-2 baz]", "[header&header-2 ---]"); MT("setextAfterList_afterHeader", "[variable-2 - foo]", " [variable-2&header&header-1 # bar]", "[header&header-2 baz]", "[header&header-2 ---]"); MT("setextAfterList_afterHr", "[variable-2 - foo]", "", " [hr ---]", "[header&header-2 bar]", "[header&header-2 ---]"); MT("setext_nestedInlineMarkup", "[header&header-1 foo ][em&header&header-1 *bar*]", "[header&header-1 =]"); MT("setext_linkDef", "[link [[aaa]]:] [string&url http://google.com 'title']", "[hr ---]"); // currently, looks max one line ahead, thus won't catch valid CommonMark // markup MT("setext_oneLineLookahead", "foo", "[header&header-1 bar]", "[header&header-1 =]"); // ensure we regard space after a single dash as a list MT("setext_emptyList", "foo", "[variable-2 - ]", "foo"); // Single-line blockquote with trailing space MT("blockquoteSpace", "[quote"e-1 > foo]"); // Single-line blockquote MT("blockquoteNoSpace", "[quote"e-1 >foo]"); // No blank line before blockquote MT("blockquoteNoBlankLine", "foo", "[quote"e-1 > bar]"); MT("blockquoteNested", "[quote"e-1 > foo]", "[quote"e-1 >][quote"e-2 > foo]", "[quote"e-1 >][quote"e-2 >][quote"e-3 > foo]"); // ensure quote-level is inferred correctly even if indented MT("blockquoteNestedIndented", " [quote"e-1 > foo]", " [quote"e-1 >][quote"e-2 > foo]", " [quote"e-1 >][quote"e-2 >][quote"e-3 > foo]"); // ensure quote-level is inferred correctly even if indented MT("blockquoteIndentedTooMuch", "foo", " > bar"); // Single-line blockquote followed by normal paragraph MT("blockquoteThenParagraph", "[quote"e-1 >foo]", "", "bar"); // Multi-line blockquote (lazy mode) MT("multiBlockquoteLazy", "[quote"e-1 >foo]", "[quote"e-1 bar]"); // Multi-line blockquote followed by normal paragraph (lazy mode) MT("multiBlockquoteLazyThenParagraph", "[quote"e-1 >foo]", "[quote"e-1 bar]", "", "hello"); // Multi-line blockquote (non-lazy mode) MT("multiBlockquote", "[quote"e-1 >foo]", "[quote"e-1 >bar]"); // Multi-line blockquote followed by normal paragraph (non-lazy mode) MT("multiBlockquoteThenParagraph", "[quote"e-1 >foo]", "[quote"e-1 >bar]", "", "hello"); // disallow lists inside blockquote for now because it causes problems outside blockquote // TODO: fix to be CommonMark-compliant MT("listNestedInBlockquote", "[quote"e-1 > - foo]"); // disallow fenced blocks inside blockquote because it causes problems outside blockquote // TODO: fix to be CommonMark-compliant MT("fencedBlockNestedInBlockquote", "[quote"e-1 > ```]", "[quote"e-1 > code]", "[quote"e-1 > ```]", // ensure we still allow inline code "[quote"e-1 > ][quote"e-1&comment `code`]"); // Header with leading space after continued blockquote (#3287, negative indentation) MT("headerAfterContinuedBlockquote", "[quote"e-1 > foo]", "[quote"e-1 bar]", "", " [header&header-1 # hello]"); // Check list types MT("listAsterisk", "foo", "bar", "", "[variable-2 * foo]", "[variable-2 * bar]"); MT("listPlus", "foo", "bar", "", "[variable-2 + foo]", "[variable-2 + bar]"); MT("listDash", "foo", "bar", "", "[variable-2 - foo]", "[variable-2 - bar]"); MT("listNumber", "foo", "bar", "", "[variable-2 1. foo]", "[variable-2 2. bar]"); MT("listFromParagraph", "foo", "[variable-2 1. bar]", "[variable-2 2. hello]"); // List after hr MT("listAfterHr", "[hr ---]", "[variable-2 - bar]"); // List after header MT("listAfterHeader", "[header&header-1 # foo]", "[variable-2 - bar]"); // hr after list MT("hrAfterList", "[variable-2 - foo]", "[hr -----]"); MT("hrAfterFencedCode", "[comment ```]", "[comment code]", "[comment ```]", "[hr ---]"); // allow hr inside lists // (require prev line to be empty or hr, TODO: non-CommonMark-compliant) MT("hrInsideList", "[variable-2 - foo]", "", " [hr ---]", " [hr ---]", "", " [comment ---]"); MT("consecutiveHr", "[hr ---]", "[hr ---]", "[hr ---]"); // Formatting in lists (*) MT("listAsteriskFormatting", "[variable-2 * ][variable-2&em *foo*][variable-2 bar]", "[variable-2 * ][variable-2&strong **foo**][variable-2 bar]", "[variable-2 * ][variable-2&em&strong ***foo***][variable-2 bar]", "[variable-2 * ][variable-2&comment `foo`][variable-2 bar]"); // Formatting in lists (+) MT("listPlusFormatting", "[variable-2 + ][variable-2&em *foo*][variable-2 bar]", "[variable-2 + ][variable-2&strong **foo**][variable-2 bar]", "[variable-2 + ][variable-2&em&strong ***foo***][variable-2 bar]", "[variable-2 + ][variable-2&comment `foo`][variable-2 bar]"); // Formatting in lists (-) MT("listDashFormatting", "[variable-2 - ][variable-2&em *foo*][variable-2 bar]", "[variable-2 - ][variable-2&strong **foo**][variable-2 bar]", "[variable-2 - ][variable-2&em&strong ***foo***][variable-2 bar]", "[variable-2 - ][variable-2&comment `foo`][variable-2 bar]"); // Formatting in lists (1.) MT("listNumberFormatting", "[variable-2 1. ][variable-2&em *foo*][variable-2 bar]", "[variable-2 2. ][variable-2&strong **foo**][variable-2 bar]", "[variable-2 3. ][variable-2&em&strong ***foo***][variable-2 bar]", "[variable-2 4. ][variable-2&comment `foo`][variable-2 bar]"); // Paragraph lists MT("listParagraph", "[variable-2 * foo]", "", "[variable-2 * bar]"); // Multi-paragraph lists // // 4 spaces MT("listMultiParagraph", "[variable-2 * foo]", "", "[variable-2 * bar]", "", " [variable-2 hello]"); // 4 spaces, extra blank lines (should still be list, per Dingus) MT("listMultiParagraphExtra", "[variable-2 * foo]", "", "[variable-2 * bar]", "", "", " [variable-2 hello]"); // 4 spaces, plus 1 space (should still be list, per Dingus) MT("listMultiParagraphExtraSpace", "[variable-2 * foo]", "", "[variable-2 * bar]", "", " [variable-2 hello]", "", " [variable-2 world]"); // 1 tab MT("listTab", "[variable-2 * foo]", "", "[variable-2 * bar]", "", "\t[variable-2 hello]"); // No indent MT("listNoIndent", "[variable-2 * foo]", "", "[variable-2 * bar]", "", "hello"); MT("listCommonMarkIndentationCode", "[variable-2 * Code blocks also affect]", " [variable-3 * The next level starts where the contents start.]", " [variable-3 * Anything less than that will keep the item on the same level.]", " [variable-3 * Each list item can indent the first level further and further.]", " [variable-3 * For the most part, this makes sense while writing a list.]", " [keyword * This means two items with same indentation can be different levels.]", " [keyword * Each level has an indent requirement that can change between items.]", " [keyword * A list item that meets this will be part of the next level.]", " [variable-3 * Otherwise, it will be part of the level where it does meet this.]", " [variable-2 * World]"); // should handle nested and un-nested lists MT("listCommonMark_MixedIndents", "[variable-2 * list1]", " [variable-2 list1]", " [variable-2&header&header-1 # heading still part of list1]", " [variable-2 text after heading still part of list1]", "", " [comment indented codeblock]", " [variable-2 list1 after code block]", " [variable-3 * list2]", // amount of spaces on empty lines between lists doesn't matter " ", // extra empty lines irrelevant "", "", " [variable-3 indented text part of list2]", " [keyword * list3]", "", " [variable-3 text at level of list2]", "", " [variable-2 de-indented text part of list1 again]", "", " [variable-2&comment ```]", " [comment code]", " [variable-2&comment ```]", "", " [variable-2 text after fenced code]"); // should correctly parse numbered list content indentation MT("listCommonMark_NumeberedListIndent", "[variable-2 1000. list with base indent of 6]", "", " [variable-2 text must be indented 6 spaces at minimum]", "", " [variable-2 9-spaces indented text still part of list]", "", " [comment indented codeblock starts at 10 spaces]", "", " [comment text indented by 5 spaces no longer belong to list]"); // should consider tab as 4 spaces MT("listCommonMark_TabIndented", "[variable-2 * list]", "\t[variable-3 * list2]", "", "\t\t[variable-3 part of list2]"); MT("listAfterBlockquote", "[quote"e-1 > foo]", "[variable-2 - bar]"); // shouldn't create sublist if it's indented more than allowed MT("nestedListIndentedTooMuch", "[variable-2 - foo]", " [variable-2 - bar]"); MT("listIndentedTooMuchAfterParagraph", "foo", " - bar"); // Blockquote MT("blockquote", "[variable-2 * foo]", "", "[variable-2 * bar]", "", " [variable-2"e"e-1 > hello]"); // Code block MT("blockquoteCode", "[variable-2 * foo]", "", "[variable-2 * bar]", "", " [comment > hello]", "", " [variable-2 world]"); // Code block followed by text MT("blockquoteCodeText", "[variable-2 * foo]", "", " [variable-2 bar]", "", " [comment hello]", "", " [variable-2 world]"); // Nested list MT("listAsteriskNested", "[variable-2 * foo]", "", " [variable-3 * bar]"); MT("listPlusNested", "[variable-2 + foo]", "", " [variable-3 + bar]"); MT("listDashNested", "[variable-2 - foo]", "", " [variable-3 - bar]"); MT("listNumberNested", "[variable-2 1. foo]", "", " [variable-3 2. bar]"); MT("listMixed", "[variable-2 * foo]", "", " [variable-3 + bar]", "", " [keyword - hello]", "", " [variable-2 1. world]"); MT("listBlockquote", "[variable-2 * foo]", "", " [variable-3 + bar]", "", " [quote"e-1&variable-3 > hello]"); MT("listCode", "[variable-2 * foo]", "", " [variable-3 + bar]", "", " [comment hello]"); // Code with internal indentation MT("listCodeIndentation", "[variable-2 * foo]", "", " [comment bar]", " [comment hello]", " [comment world]", " [comment foo]", " [variable-2 bar]"); // List nesting edge cases MT("listNested", "[variable-2 * foo]", "", " [variable-3 * bar]", "", " [variable-3 hello]" ); MT("listNested", "[variable-2 * foo]", "", " [variable-3 * bar]", "", " [keyword * foo]" ); // Code followed by text MT("listCodeText", "[variable-2 * foo]", "", " [comment bar]", "", "hello"); // Following tests directly from official Markdown documentation // http://daringfireball.net/projects/markdown/syntax#hr MT("hrSpace", "[hr * * *]"); MT("hr", "[hr ***]"); MT("hrLong", "[hr *****]"); MT("hrSpaceDash", "[hr - - -]"); MT("hrDashLong", "[hr ---------------------------------------]"); //Images MT("Images", "[image&image-marker !][image&image-alt-text&link [[alt text]]][string&url (http://link.to/image.jpg)]") //Images with highlight alt text MT("imageEm", "[image&image-marker !][image&image-alt-text&link [[][image-alt-text&em&image&link *alt text*][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)]"); MT("imageStrong", "[image&image-marker !][image&image-alt-text&link [[][image-alt-text&strong&image&link **alt text**][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)]"); MT("imageEmStrong", "[image&image-marker !][image&image-alt-text&link [[][image&image-alt-text&em&strong&link ***alt text***][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)]"); // Inline link with title MT("linkTitle", "[link [[foo]]][string&url (http://example.com/ \"bar\")] hello"); // Inline link without title MT("linkNoTitle", "[link [[foo]]][string&url (http://example.com/)] bar"); // Inline link with image MT("linkImage", "[link [[][link&image&image-marker !][link&image&image-alt-text&link [[alt text]]][string&url (http://link.to/image.jpg)][link ]]][string&url (http://example.com/)] bar"); // Inline link with Em MT("linkEm", "[link [[][link&em *foo*][link ]]][string&url (http://example.com/)] bar"); // Inline link with Strong MT("linkStrong", "[link [[][link&strong **foo**][link ]]][string&url (http://example.com/)] bar"); // Inline link with EmStrong MT("linkEmStrong", "[link [[][link&em&strong ***foo***][link ]]][string&url (http://example.com/)] bar"); MT("multilineLink", "[link [[foo]", "[link bar]]][string&url (https://foo#_a)]", "should not be italics") // Image with title MT("imageTitle", "[image&image-marker !][image&image-alt-text&link [[alt text]]][string&url (http://example.com/ \"bar\")] hello"); // Image without title MT("imageNoTitle", "[image&image-marker !][image&image-alt-text&link [[alt text]]][string&url (http://example.com/)] bar"); // Image with asterisks MT("imageAsterisks", "[image&image-marker !][image&image-alt-text&link [[ ][image&image-alt-text&em&link *alt text*][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)] bar"); // Not a link. Should be normal text due to square brackets being used // regularly in text, especially in quoted material, and no space is allowed // between square brackets and parentheses (per Dingus). MT("notALink", "[link [[foo]]] (bar)"); // Reference-style links MT("linkReference", "[link [[foo]]][string&url [[bar]]] hello"); // Reference-style links with Em MT("linkReferenceEm", "[link [[][link&em *foo*][link ]]][string&url [[bar]]] hello"); // Reference-style links with Strong MT("linkReferenceStrong", "[link [[][link&strong **foo**][link ]]][string&url [[bar]]] hello"); // Reference-style links with EmStrong MT("linkReferenceEmStrong", "[link [[][link&em&strong ***foo***][link ]]][string&url [[bar]]] hello"); // Reference-style links with optional space separator (per documentation) // "You can optionally use a space to separate the sets of brackets" MT("linkReferenceSpace", "[link [[foo]]] [string&url [[bar]]] hello"); // Should only allow a single space ("...use *a* space...") MT("linkReferenceDoubleSpace", "[link [[foo]]] [link [[bar]]] hello"); // Reference-style links with implicit link name MT("linkImplicit", "[link [[foo]]][string&url [[]]] hello"); // @todo It would be nice if, at some point, the document was actually // checked to see if the referenced link exists // Link label, for reference-style links (taken from documentation) MT("labelNoTitle", "[link [[foo]]:] [string&url http://example.com/]"); MT("labelIndented", " [link [[foo]]:] [string&url http://example.com/]"); MT("labelSpaceTitle", "[link [[foo bar]]:] [string&url http://example.com/ \"hello\"]"); MT("labelDoubleTitle", "[link [[foo bar]]:] [string&url http://example.com/ \"hello\"] \"world\""); MT("labelTitleDoubleQuotes", "[link [[foo]]:] [string&url http://example.com/ \"bar\"]"); MT("labelTitleSingleQuotes", "[link [[foo]]:] [string&url http://example.com/ 'bar']"); MT("labelTitleParentheses", "[link [[foo]]:] [string&url http://example.com/ (bar)]"); MT("labelTitleInvalid", "[link [[foo]]:] [string&url http://example.com/] bar"); MT("labelLinkAngleBrackets", "[link [[foo]]:] [string&url <http://example.com/> \"bar\"]"); MT("labelTitleNextDoubleQuotes", "[link [[foo]]:] [string&url http://example.com/]", "[string \"bar\"] hello"); MT("labelTitleNextSingleQuotes", "[link [[foo]]:] [string&url http://example.com/]", "[string 'bar'] hello"); MT("labelTitleNextParentheses", "[link [[foo]]:] [string&url http://example.com/]", "[string (bar)] hello"); MT("labelTitleNextMixed", "[link [[foo]]:] [string&url http://example.com/]", "(bar\" hello"); MT("labelEscape", "[link [[foo \\]] ]]:] [string&url http://example.com/]"); MT("labelEscapeColon", "[link [[foo \\]]: bar]]:] [string&url http://example.com/]"); MT("labelEscapeEnd", "\\[[foo\\]]: http://example.com/"); MT("linkWeb", "[link <http://example.com/>] foo"); MT("linkWebDouble", "[link <http://example.com/>] foo [link <http://example.com/>]"); MT("linkEmail", "[link <user@example.com>] foo"); MT("linkEmailDouble", "[link <user@example.com>] foo [link <user@example.com>]"); MT("emAsterisk", "[em *foo*] bar"); MT("emUnderscore", "[em _foo_] bar"); MT("emInWordAsterisk", "foo[em *bar*]hello"); MT("emInWordUnderscore", "foo_bar_hello"); // Per documentation: "...surround an * or _ with spaces, it’ll be // treated as a literal asterisk or underscore." MT("emEscapedBySpaceIn", "foo [em _bar _ hello_] world"); MT("emEscapedBySpaceOut", "foo _ bar [em _hello_] world"); MT("emEscapedByNewline", "foo", "_ bar [em _hello_] world"); // Unclosed emphasis characters // Instead of simply marking as EM / STRONG, it would be nice to have an // incomplete flag for EM and STRONG, that is styled slightly different. MT("emIncompleteAsterisk", "foo [em *bar]"); MT("emIncompleteUnderscore", "foo [em _bar]"); MT("strongAsterisk", "[strong **foo**] bar"); MT("strongUnderscore", "[strong __foo__] bar"); MT("emStrongAsterisk", "[em *foo][em&strong **bar*][strong hello**] world"); MT("emStrongUnderscore", "[em _foo ][em&strong __bar_][strong hello__] world"); // "...same character must be used to open and close an emphasis span."" MT("emStrongMixed", "[em _foo][em&strong **bar*hello__ world]"); MT("emStrongMixed", "[em *foo ][em&strong __bar_hello** world]"); MT("linkWithNestedParens", "[link [[foo]]][string&url (bar(baz))]") // These characters should be escaped: // \ backslash // ` backtick // * asterisk // _ underscore // {} curly braces // [] square brackets // () parentheses // # hash mark // + plus sign // - minus sign (hyphen) // . dot // ! exclamation mark MT("escapeBacktick", "foo \\`bar\\`"); MT("doubleEscapeBacktick", "foo \\\\[comment `bar\\\\`]"); MT("escapeAsterisk", "foo \\*bar\\*"); MT("doubleEscapeAsterisk", "foo \\\\[em *bar\\\\*]"); MT("escapeUnderscore", "foo \\_bar\\_"); MT("doubleEscapeUnderscore", "foo \\\\[em _bar\\\\_]"); MT("escapeHash", "\\# foo"); MT("doubleEscapeHash", "\\\\# foo"); MT("escapeNewline", "\\", "[em *foo*]"); // Class override tests TokenTypeOverrideTest("overrideHeader1", "[override-header&override-header-1 # Foo]"); TokenTypeOverrideTest("overrideHeader2", "[override-header&override-header-2 ## Foo]"); TokenTypeOverrideTest("overrideHeader3", "[override-header&override-header-3 ### Foo]"); TokenTypeOverrideTest("overrideHeader4", "[override-header&override-header-4 #### Foo]"); TokenTypeOverrideTest("overrideHeader5", "[override-header&override-header-5 ##### Foo]"); TokenTypeOverrideTest("overrideHeader6", "[override-header&override-header-6 ###### Foo]"); TokenTypeOverrideTest("overrideCode", "[override-code `foo`]"); TokenTypeOverrideTest("overrideCodeBlock", "[override-code ```]", "[override-code foo]", "[override-code ```]"); TokenTypeOverrideTest("overrideQuote", "[override-quote&override-quote-1 > foo]", "[override-quote&override-quote-1 > bar]"); TokenTypeOverrideTest("overrideQuoteNested", "[override-quote&override-quote-1 > foo]", "[override-quote&override-quote-1 >][override-quote&override-quote-2 > bar]", "[override-quote&override-quote-1 >][override-quote&override-quote-2 >][override-quote&override-quote-3 > baz]"); TokenTypeOverrideTest("overrideLists", "[override-list1 - foo]", "", " [override-list2 + bar]", "", " [override-list3 * baz]", "", " [override-list1 1. qux]", "", " [override-list2 - quux]"); TokenTypeOverrideTest("overrideHr", "[override-hr * * *]"); TokenTypeOverrideTest("overrideImage", "[override-image&override-image-marker !][override-image&override-image-alt-text&link [[alt text]]][override-link-href&url (http://link.to/image.jpg)]"); TokenTypeOverrideTest("overrideLinkText", "[override-link-text [[foo]]][override-link-href&url (http://example.com)]"); TokenTypeOverrideTest("overrideLinkEmailAndInline", "[override-link-email <][override-link-inline foo@example.com>]"); TokenTypeOverrideTest("overrideEm", "[override-em *foo*]"); TokenTypeOverrideTest("overrideStrong", "[override-strong **foo**]"); TokenTypeOverrideTest("overrideStrikethrough", "[override-strikethrough ~~foo~~]"); TokenTypeOverrideTest("overrideEmoji", "[override-emoji :foo:]"); FormatTokenTypeOverrideTest("overrideFormatting", "[override-formatting-escape \\*]"); // Tests to make sure GFM-specific things aren't getting through MT("taskList", "[variable-2 * ][link&variable-2 [[ ]]][variable-2 bar]"); MT("fencedCodeBlocks", "[comment ```]", "[comment foo]", "", "[comment bar]", "[comment ```]", "baz"); MT("fencedCodeBlocks_invalidClosingFence_trailingText", "[comment ```]", "[comment foo]", "[comment ``` must not have trailing text]", "[comment baz]"); MT("fencedCodeBlocks_invalidClosingFence_trailingTabs", "[comment ```]", "[comment foo]", "[comment ```\t]", "[comment baz]"); MT("fencedCodeBlocks_validClosingFence", "[comment ```]", "[comment foo]", // may have trailing spaces "[comment ``` ]", "baz"); MT("fencedCodeBlocksInList_closingFenceIndented", "[variable-2 - list]", " [variable-2&comment ```]", " [comment foo]", " [variable-2&comment ```]", " [variable-2 baz]"); MT("fencedCodeBlocksInList_closingFenceIndentedTooMuch", "[variable-2 - list]", " [variable-2&comment ```]", " [comment foo]", " [comment ```]", " [comment baz]"); MT("fencedCodeBlockModeSwitching", "[comment ```javascript]", "[variable foo]", "", "[comment ```]", "bar"); MT_noFencedHighlight("fencedCodeBlock_noHighlight", "[comment ```javascript]", "[comment foo]", "[comment ```]"); MT("fencedCodeBlockModeSwitchingObjc", "[comment ```objective-c]", "[keyword @property] [variable NSString] [operator *] [variable foo];", "[comment ```]", "bar"); MT("fencedCodeBlocksMultipleChars", "[comment `````]", "[comment foo]", "[comment ```]", "[comment foo]", "[comment `````]", "bar"); MT("fencedCodeBlocksTildes", "[comment ~~~]", "[comment foo]", "[comment ~~~]", "bar"); MT("fencedCodeBlocksTildesMultipleChars", "[comment ~~~~~]", "[comment ~~~]", "[comment foo]", "[comment ~~~~~]", "bar"); MT("fencedCodeBlocksMultipleChars", "[comment `````]", "[comment foo]", "[comment ```]", "[comment foo]", "[comment `````]", "bar"); MT("fencedCodeBlocksMixed", "[comment ~~~]", "[comment ```]", "[comment foo]", "[comment ~~~]", "bar"); MT("fencedCodeBlocksAfterBlockquote", "[quote"e-1 > foo]", "[comment ```]", "[comment bar]", "[comment ```]"); // fencedCode indented too much should act as simple indentedCode // (hence has no highlight formatting) FT("tooMuchIndentedFencedCode", " [comment ```]", " [comment code]", " [comment ```]"); MT("autoTerminateFencedCodeWhenLeavingList", "[variable-2 - list1]", " [variable-3 - list2]", " [variable-3&comment ```]", " [comment code]", " [variable-3 - list2]", " [variable-2&comment ```]", " [comment code]", "[quote"e-1 > foo]"); // Tests that require XML mode MT("xmlMode", "[tag&bracket <][tag div][tag&bracket >]", " *foo*", " [tag&bracket <][tag http://github.com][tag&bracket />]", "[tag&bracket </][tag div][tag&bracket >]", "[link <http://github.com/>]"); MT("xmlModeWithMarkdownInside", "[tag&bracket <][tag div] [attribute markdown]=[string 1][tag&bracket >]", "[em *foo*]", "[link <http://github.com/>]", "[tag </div>]", "[link <http://github.com/>]", "[tag&bracket <][tag div][tag&bracket >]", "[tag&bracket </][tag div][tag&bracket >]"); MT("xmlModeLineBreakInTags", "[tag&bracket <][tag div] [attribute id]=[string \"1\"]", " [attribute class]=[string \"sth\"][tag&bracket >]xxx", "[tag&bracket </][tag div][tag&bracket >]"); MT("xmlModeCommentWithBlankLine", "[comment <!-- Hello]", "", "[comment World -->]"); MT("xmlModeCDATA", "[atom <![CDATA[ Hello]", "", "[atom FooBar]", "[atom Test ]]]]>]"); MT("xmlModePreprocessor", "[meta <?php] [meta echo '1234'; ?>]"); MT_noXml("xmlHighlightDisabled", "<div>foo</div>"); // Tests Emojis ET("emojiDefault", "[builtin :foobar:]"); ET("emojiTable", " :--:"); })(); index.html 0000644 00000030751 15030342556 0006552 0 ustar 00 <!doctype html> <title>CodeMirror: Markdown mode</title> <meta charset="utf-8"/> <link rel=stylesheet href="../../doc/docs.css"> <link rel="stylesheet" href="../../lib/codemirror.css"> <script src="../../lib/codemirror.js"></script> <script src="../../addon/edit/continuelist.js"></script> <script src="../xml/xml.js"></script> <script src="../javascript/javascript.js"></script> <script src="markdown.js"></script> <style> .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;} .cm-s-default .cm-trailing-space-a:before, .cm-s-default .cm-trailing-space-b:before {position: absolute; content: "\00B7"; color: #777;} .cm-s-default .cm-trailing-space-new-line:before {position: absolute; content: "\21B5"; color: #777;} </style> <div id=nav> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a> <ul> <li><a href="../../index.html">Home</a> <li><a href="../../doc/manual.html">Manual</a> <li><a href="https://github.com/codemirror/codemirror">Code</a> </ul> <ul> <li><a href="../index.html">Language modes</a> <li><a class=active href="#">Markdown</a> </ul> </div> <article> <h2>Markdown mode</h2> <form><textarea id="code" name="code"> Markdown: Basics ================ <ul id="ProjectSubmenu"> <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li> <li><a class="selected" title="Markdown Basics">Basics</a></li> <li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li> <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li> <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li> </ul> Getting the Gist of Markdown's Formatting Syntax ------------------------------------------------ This page offers a brief overview of what it's like to use Markdown. The [syntax page] [s] provides complete, detailed documentation for every feature, but Markdown should be very easy to pick up simply by looking at a few examples of it in action. The examples on this page are written in a before/after style, showing example syntax and the HTML output produced by Markdown. It's also helpful to simply try Markdown out; the [Dingus] [d] is a web application that allows you type your own Markdown-formatted text and translate it to XHTML. **Note:** This document is itself written using Markdown; you can [see the source for it by adding '.text' to the URL] [src]. [s]: /projects/markdown/syntax "Markdown Syntax" [d]: /projects/markdown/dingus "Markdown Dingus" [src]: /projects/markdown/basics.text ## Paragraphs, Headers, Blockquotes ## A paragraph is simply one or more consecutive lines of text, separated by one or more blank lines. (A blank line is any line that looks like a blank line -- a line containing nothing but spaces or tabs is considered blank.) Normal paragraphs should not be indented with spaces or tabs. Markdown offers two styles of headers: *Setext* and *atx*. Setext-style headers for `<h1>` and `<h2>` are created by "underlining" with equal signs (`=`) and hyphens (`-`), respectively. To create an atx-style header, you put 1-6 hash marks (`#`) at the beginning of the line -- the number of hashes equals the resulting HTML header level. Blockquotes are indicated using email-style '`>`' angle brackets. Markdown: A First Level Header ==================== A Second Level Header --------------------- Now is the time for all good men to come to the aid of their country. This is just a regular paragraph. The quick brown fox jumped over the lazy dog's back. ### Header 3 > This is a blockquote. > > This is the second paragraph in the blockquote. > > ## This is an H2 in a blockquote Output: <h1>A First Level Header</h1> <h2>A Second Level Header</h2> <p>Now is the time for all good men to come to the aid of their country. This is just a regular paragraph.</p> <p>The quick brown fox jumped over the lazy dog's back.</p> <h3>Header 3</h3> <blockquote> <p>This is a blockquote.</p> <p>This is the second paragraph in the blockquote.</p> <h2>This is an H2 in a blockquote</h2> </blockquote> ### Phrase Emphasis ### Markdown uses asterisks and underscores to indicate spans of emphasis. Markdown: Some of these words *are emphasized*. Some of these words _are emphasized also_. Use two asterisks for **strong emphasis**. Or, if you prefer, __use two underscores instead__. Output: <p>Some of these words <em>are emphasized</em>. Some of these words <em>are emphasized also</em>.</p> <p>Use two asterisks for <strong>strong emphasis</strong>. Or, if you prefer, <strong>use two underscores instead</strong>.</p> ## Lists ## Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`, `+`, and `-`) as list markers. These three markers are interchangable; this: * Candy. * Gum. * Booze. this: + Candy. + Gum. + Booze. and this: - Candy. - Gum. - Booze. all produce the same output: <ul> <li>Candy.</li> <li>Gum.</li> <li>Booze.</li> </ul> Ordered (numbered) lists use regular numbers, followed by periods, as list markers: 1. Red 2. Green 3. Blue Output: <ol> <li>Red</li> <li>Green</li> <li>Blue</li> </ol> If you put blank lines between items, you'll get `<p>` tags for the list item text. You can create multi-paragraph list items by indenting the paragraphs by 4 spaces or 1 tab: * A list item. With multiple paragraphs. * Another item in the list. Output: <ul> <li><p>A list item.</p> <p>With multiple paragraphs.</p></li> <li><p>Another item in the list.</p></li> </ul> ### Links ### Markdown supports two styles for creating links: *inline* and *reference*. With both styles, you use square brackets to delimit the text you want to turn into a link. Inline-style links use parentheses immediately after the link text. For example: This is an [example link](http://example.com/). Output: <p>This is an <a href="http://example.com/"> example link</a>.</p> Optionally, you may include a title attribute in the parentheses: This is an [example link](http://example.com/ "With a Title"). Output: <p>This is an <a href="http://example.com/" title="With a Title"> example link</a>.</p> Reference-style links allow you to refer to your links by names, which you define elsewhere in your document: I get 10 times more traffic from [Google][1] than from [Yahoo][2] or [MSN][3]. [1]: http://google.com/ "Google" [2]: http://search.yahoo.com/ "Yahoo Search" [3]: http://search.msn.com/ "MSN Search" Output: <p>I get 10 times more traffic from <a href="http://google.com/" title="Google">Google</a> than from <a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p> The title attribute is optional. Link names may contain letters, numbers and spaces, but are *not* case sensitive: I start my morning with a cup of coffee and [The New York Times][NY Times]. [ny times]: http://www.nytimes.com/ Output: <p>I start my morning with a cup of coffee and <a href="http://www.nytimes.com/">The New York Times</a>.</p> ### Images ### Image syntax is very much like link syntax. Inline (titles are optional):  Reference-style: ![alt text][id] [id]: /path/to/img.jpg "Title" Both of the above examples produce the same output: <img src="/path/to/img.jpg" alt="alt text" title="Title" /> ### Code ### In a regular paragraph, you can create code span by wrapping text in backtick quotes. Any ampersands (`&`) and angle brackets (`<` or `>`) will automatically be translated into HTML entities. This makes it easy to use Markdown to write about HTML example code: I strongly recommend against using any `<blink>` tags. I wish SmartyPants used named entities like `&mdash;` instead of decimal-encoded entites like `&#8212;`. Output: <p>I strongly recommend against using any <code>&lt;blink&gt;</code> tags.</p> <p>I wish SmartyPants used named entities like <code>&amp;mdash;</code> instead of decimal-encoded entites like <code>&amp;#8212;</code>.</p> To specify an entire block of pre-formatted code, indent every line of the block by 4 spaces or 1 tab. Just like with code spans, `&`, `<`, and `>` characters will be escaped automatically. Markdown: If you want your page to validate under XHTML 1.0 Strict, you've got to put paragraph tags in your blockquotes: <blockquote> <p>For example.</p> </blockquote> Output: <p>If you want your page to validate under XHTML 1.0 Strict, you've got to put paragraph tags in your blockquotes:</p> <pre><code>&lt;blockquote&gt; &lt;p&gt;For example.&lt;/p&gt; &lt;/blockquote&gt; </code></pre> ## Fenced code blocks (and syntax highlighting) ```javascript for (var i = 0; i < items.length; i++) { console.log(items[i], i); // log them } ``` </textarea></form> <script> var editor = CodeMirror.fromTextArea(document.getElementById("code"), { mode: 'markdown', lineNumbers: true, theme: "default", extraKeys: {"Enter": "newlineAndIndentContinueMarkdownList"} }); </script> <p>If you also want support <code>strikethrough</code>, <code>emoji</code> and few other goodies, check out <a href="../gfm/index.html">Github-Flavored Markdown mode</a>.</p> <p>Optionally depends on other modes for properly highlighted code blocks, and XML mode for properly highlighted inline XML blocks.</p> <p>Markdown mode supports these options:</p> <ul> <li> <d1> <dt><code>highlightFormatting: boolean</code></dt> <dd>Whether to separately highlight markdown meta characterts (<code>*[]()</code>etc.) (default: <code>false</code>).</dd> </d1> </li> <li> <d1> <dt><code>maxBlockquoteDepth: boolean</code></dt> <dd>Maximum allowed blockquote nesting (default: <code>0</code> - infinite nesting).</dd> </d1> </li> <li> <d1> <dt><code>xml: boolean</code></dt> <dd>Whether to highlight inline XML (default: <code>true</code>).</dd> </d1> </li> <li> <d1> <dt><code>fencedCodeBlockHighlighting: boolean</code></dt> <dd>Whether to syntax-highlight fenced code blocks, if given mode is included, or fencedCodeBlockDefaultMode is set (default: <code>true</code>).</dd> </d1> </li> <li> <d1> <dt><code>fencedCodeBlockDefaultMode: string</code></dt> <dd>Mode to use for fencedCodeBlockHighlighting, if given mode is not included.</dd> </d1> </li> <li> <d1> <dt><code>tokenTypeOverrides: Object</code></dt> <dd>When you want to override default token type names (e.g. <code>{code: "code"}</code>).</dd> </d1> </li> <li> <d1> <dt><code>allowAtxHeaderWithoutSpace: boolean</code></dt> <dd>Allow lazy headers without whitespace between hashtag and text (default: <code>false</code>).</dd> </d1> </li> </ul> <p><strong>MIME types defined:</strong> <code>text/x-markdown</code>.</p> <p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#markdown_*">normal</a>, <a href="../../test/index.html#verbose,markdown_*">verbose</a>.</p> </article>
| ver. 1.4 |
Github
|
.
| PHP 8.2.28 | Generation time: 0.02 |
proxy
|
phpinfo
|
Settings