##// END OF EJS Templates
Merge pull request #2194 from minrk/clean_nan...
Merge pull request #2194 from minrk/clean_nan Clean nan/inf in json_clean. The floating point values NaN and Infinity are not part of the JSON specification and causes some parsers to throw errors. Since our usage is only for things like the display of function defaults, we can use a basic string representation ('NaN', 'inf', etc) instead.

File last commit:

r6058:ecc950ec
r8047:157d99af merge
Show More
markdown.js
246 lines | 5.9 KiB | application/javascript | JavascriptLexer
CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
var htmlMode = CodeMirror.getMode(cmCfg, { name: 'xml', htmlMode: true });
var header = 'header'
, code = 'comment'
, quote = 'quote'
, list = 'string'
, hr = 'hr'
, linktext = 'link'
, linkhref = 'string'
, em = 'em'
, strong = 'strong'
, emstrong = 'emstrong';
var hrRE = /^[*-=_]/
, ulRE = /^[*-+]\s+/
, olRE = /^[0-9]+\.\s+/
, headerRE = /^(?:\={3,}|-{3,})$/
, codeRE = /^(k:\t|\s{4,})/
, textRE = /^[^\[*_\\<>`]+/;
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);
}
// Blocks
function blockNormal(stream, state) {
if (stream.match(codeRE)) {
stream.skipToEnd();
return code;
}
if (stream.eatSpace()) {
return null;
}
if (stream.peek() === '#' || stream.match(headerRE)) {
stream.skipToEnd();
return header;
}
if (stream.eat('>')) {
state.indentation++;
return quote;
}
if (stream.peek() === '[') {
return switchInline(stream, state, footnoteLink);
}
if (hrRE.test(stream.peek())) {
var re = new RegExp('(?:\s*['+stream.peek()+']){3,}$');
if (stream.match(re, true)) {
return hr;
}
}
var match;
if (match = stream.match(ulRE, true) || stream.match(olRE, true)) {
state.indentation += match[0].length;
return list;
}
return switchInline(stream, state, state.inline);
}
function htmlBlock(stream, state) {
var style = htmlMode.token(stream, state.htmlState);
if (style === 'tag' && state.htmlState.type !== 'openTag' && !state.htmlState.context) {
state.f = inlineNormal;
state.block = blockNormal;
}
return style;
}
// Inline
function getType(state) {
return state.strong ? (state.em ? emstrong : strong)
: (state.em ? em : 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;
var ch = stream.next();
if (ch === '\\') {
stream.next();
return getType(state);
}
if (ch === '`') {
return switchInline(stream, state, inlineElement(code, '`'));
}
if (ch === '[') {
return switchInline(stream, state, linkText);
}
if (ch === '<' && stream.match(/^\w/, false)) {
stream.backUp(1);
return switchBlock(stream, state, htmlBlock);
}
var t = getType(state);
if (ch === '*' || ch === '_') {
if (stream.eat(ch)) {
return (state.strong = !state.strong) ? getType(state) : t;
}
return (state.em = !state.em) ? getType(state) : t;
}
return getType(state);
}
function linkText(stream, state) {
while (!stream.eol()) {
var ch = stream.next();
if (ch === '\\') stream.next();
if (ch === ']') {
state.inline = state.f = linkHref;
return linktext;
}
}
return linktext;
}
function linkHref(stream, state) {
stream.eatSpace();
var ch = stream.next();
if (ch === '(' || ch === '[') {
return switchInline(stream, state, inlineElement(linkhref, ch === '(' ? ')' : ']'));
}
return 'error';
}
function footnoteLink(stream, state) {
if (stream.match(/^[^\]]*\]:/, true)) {
state.f = footnoteUrl;
return linktext;
}
return switchInline(stream, state, inlineNormal);
}
function footnoteUrl(stream, state) {
stream.eatSpace();
stream.match(/^[^\s]+/, true);
state.f = state.inline = inlineNormal;
return linkhref;
}
function inlineRE(endChar) {
if (!inlineRE[endChar]) {
// match any not-escaped-non-endChar and any escaped char
// then match endChar or eol
inlineRE[endChar] = new RegExp('^(?:[^\\\\\\' + endChar + ']|\\\\.)*(?:\\' + endChar + '|$)');
}
return inlineRE[endChar];
}
function inlineElement(type, endChar, next) {
next = next || inlineNormal;
return function(stream, state) {
stream.match(inlineRE(endChar));
state.inline = state.f = next;
return type;
};
}
return {
startState: function() {
return {
f: blockNormal,
block: blockNormal,
htmlState: htmlMode.startState(),
indentation: 0,
inline: inlineNormal,
text: handleText,
em: false,
strong: false
};
},
copyState: function(s) {
return {
f: s.f,
block: s.block,
htmlState: CodeMirror.copyState(htmlMode, s.htmlState),
indentation: s.indentation,
inline: s.inline,
text: s.text,
em: s.em,
strong: s.strong
};
},
token: function(stream, state) {
if (stream.sol()) {
// Reset EM state
state.em = false;
// Reset STRONG state
state.strong = false;
state.f = state.block;
var previousIndentation = state.indentation
, currentIndentation = 0;
while (previousIndentation > 0) {
if (stream.eat(' ')) {
previousIndentation--;
currentIndentation++;
} else if (previousIndentation >= 4 && stream.eat('\t')) {
previousIndentation -= 4;
currentIndentation += 4;
} else {
break;
}
}
state.indentation = currentIndentation;
if (currentIndentation > 0) return null;
}
return state.f(stream, state);
},
getType: getType
};
});
CodeMirror.defineMIME("text/x-markdown", "markdown");