" + escapeHtml(tokens[idx].content) + "
";
+ return "" + escapeHtml(token.content) + "
";
};
default_rules.code_block = function(tokens, idx, options, env, slf) {
var token = tokens[idx];
@@ -3306,7 +3289,7 @@
if (type === "inline") {
result += this.renderInline(tokens[i].children, options, env);
} else if (typeof rules[type] !== "undefined") {
- result += rules[tokens[i].type](tokens, i, options, env, this);
+ result += rules[type](tokens, i, options, env, this);
} else {
result += this.renderToken(tokens, i, options, env);
}
@@ -4527,7 +4510,7 @@
return false;
}
// check the block quote marker
- if (state.src.charCodeAt(pos++) !== 62 /* > */) {
+ if (state.src.charCodeAt(pos) !== 62 /* > */) {
return false;
}
// we know that it's going to be a valid blockquote,
@@ -4535,57 +4518,10 @@
if (silent) {
return true;
}
- // set offset past spaces and ">"
- initial = offset = state.sCount[startLine] + 1;
- // skip one optional space after '>'
- if (state.src.charCodeAt(pos) === 32 /* space */) {
- // ' > test '
- // ^ -- position start of line here:
- pos++;
- initial++;
- offset++;
- adjustTab = false;
- spaceAfterMarker = true;
- } else if (state.src.charCodeAt(pos) === 9 /* tab */) {
- spaceAfterMarker = true;
- if ((state.bsCount[startLine] + offset) % 4 === 3) {
- // ' >\t test '
- // ^ -- position start of line here (tab has width===1)
- pos++;
- initial++;
- offset++;
- adjustTab = false;
- } else {
- // ' >\t test '
- // ^ -- position start of line here + shift bsCount slightly
- // to make extra space appear
- adjustTab = true;
- }
- } else {
- spaceAfterMarker = false;
- }
- oldBMarks = [ state.bMarks[startLine] ];
- state.bMarks[startLine] = pos;
- while (pos < max) {
- ch = state.src.charCodeAt(pos);
- if (isSpace$9(ch)) {
- if (ch === 9) {
- offset += 4 - (offset + state.bsCount[startLine] + (adjustTab ? 1 : 0)) % 4;
- } else {
- offset++;
- }
- } else {
- break;
- }
- pos++;
- }
- oldBSCount = [ state.bsCount[startLine] ];
- state.bsCount[startLine] = state.sCount[startLine] + 1 + (spaceAfterMarker ? 1 : 0);
- lastLineEmpty = pos >= max;
- oldSCount = [ state.sCount[startLine] ];
- state.sCount[startLine] = offset - initial;
- oldTShift = [ state.tShift[startLine] ];
- state.tShift[startLine] = pos - state.bMarks[startLine];
+ oldBMarks = [];
+ oldBSCount = [];
+ oldSCount = [];
+ oldTShift = [];
terminatorRules = state.md.block.ruler.getRules("blockquote");
oldParentType = state.parentType;
state.parentType = "blockquote";
@@ -4607,7 +4543,7 @@
// > test
// - - -
// ```
- for (nextLine = startLine + 1; nextLine < endLine; nextLine++) {
+ for (nextLine = startLine; nextLine < endLine; nextLine++) {
// check if it's outdented, i.e. it's inside list item and indented
// less than said list item:
// ```
@@ -4625,24 +4561,22 @@
if (state.src.charCodeAt(pos++) === 62 /* > */ && !isOutdented) {
// This line is inside the blockquote.
// set offset past spaces and ">"
- initial = offset = state.sCount[nextLine] + 1;
+ initial = state.sCount[nextLine] + 1;
// skip one optional space after '>'
if (state.src.charCodeAt(pos) === 32 /* space */) {
// ' > test '
// ^ -- position start of line here:
pos++;
initial++;
- offset++;
adjustTab = false;
spaceAfterMarker = true;
} else if (state.src.charCodeAt(pos) === 9 /* tab */) {
spaceAfterMarker = true;
- if ((state.bsCount[nextLine] + offset) % 4 === 3) {
+ if ((state.bsCount[nextLine] + initial) % 4 === 3) {
// ' >\t test '
// ^ -- position start of line here (tab has width===1)
pos++;
initial++;
- offset++;
adjustTab = false;
} else {
// ' >\t test '
@@ -4653,6 +4587,7 @@
} else {
spaceAfterMarker = false;
}
+ offset = initial;
oldBMarks.push(state.bMarks[nextLine]);
state.bMarks[nextLine] = pos;
while (pos < max) {
@@ -4845,9 +4780,9 @@
}
}
var list = function list(state, startLine, endLine, silent) {
- var ch, contentStart, i, indent, indentAfterMarker, initial, isOrdered, itemLines, l, listLines, listTokIdx, markerCharCode, markerValue, max, nextLine, offset, oldListIndent, oldParentType, oldSCount, oldTShift, oldTight, pos, posAfterMarker, prevEmptyEnd, start, terminate, terminatorRules, token, isTerminatingParagraph = false, tight = true;
+ var ch, contentStart, i, indent, indentAfterMarker, initial, isOrdered, itemLines, l, listLines, listTokIdx, markerCharCode, markerValue, max, offset, oldListIndent, oldParentType, oldSCount, oldTShift, oldTight, pos, posAfterMarker, prevEmptyEnd, start, terminate, terminatorRules, token, nextLine = startLine, isTerminatingParagraph = false, tight = true;
// if it's indented more than 3 spaces, it should be a code block
- if (state.sCount[startLine] - state.blkIndent >= 4) {
+ if (state.sCount[nextLine] - state.blkIndent >= 4) {
return false;
}
// Special case:
@@ -4856,7 +4791,7 @@
// - item 3
// - item 4
// - this one is a paragraph continuation
- if (state.listIndent >= 0 && state.sCount[startLine] - state.listIndent >= 4 && state.sCount[startLine] < state.blkIndent) {
+ if (state.listIndent >= 0 && state.sCount[nextLine] - state.listIndent >= 4 && state.sCount[nextLine] < state.blkIndent) {
return false;
}
// limit conditions when list can interrupt
@@ -4865,19 +4800,19 @@
// Next list item should still terminate previous list item;
// This code can fail if plugins use blkIndent as well as lists,
// but I hope the spec gets fixed long before that happens.
- if (state.sCount[startLine] >= state.blkIndent) {
+ if (state.sCount[nextLine] >= state.blkIndent) {
isTerminatingParagraph = true;
}
}
// Detect list type and position after marker
- if ((posAfterMarker = skipOrderedListMarker(state, startLine)) >= 0) {
+ if ((posAfterMarker = skipOrderedListMarker(state, nextLine)) >= 0) {
isOrdered = true;
- start = state.bMarks[startLine] + state.tShift[startLine];
+ start = state.bMarks[nextLine] + state.tShift[nextLine];
markerValue = Number(state.src.slice(start, posAfterMarker - 1));
// If we're starting a new ordered list right after
// a paragraph, it should start with 1.
if (isTerminatingParagraph && markerValue !== 1) return false;
- } else if ((posAfterMarker = skipBulletListMarker(state, startLine)) >= 0) {
+ } else if ((posAfterMarker = skipBulletListMarker(state, nextLine)) >= 0) {
isOrdered = false;
} else {
return false;
@@ -4885,14 +4820,14 @@
// If we're starting a new unordered list right after
// a paragraph, first line should not be empty.
if (isTerminatingParagraph) {
- if (state.skipSpaces(posAfterMarker) >= state.eMarks[startLine]) return false;
+ if (state.skipSpaces(posAfterMarker) >= state.eMarks[nextLine]) return false;
}
- // We should terminate list on style change. Remember first one to compare.
- markerCharCode = state.src.charCodeAt(posAfterMarker - 1);
// For validation mode we can terminate immediately
if (silent) {
return true;
}
+ // We should terminate list on style change. Remember first one to compare.
+ markerCharCode = state.src.charCodeAt(posAfterMarker - 1);
// Start list
listTokIdx = state.tokens.length;
if (isOrdered) {
@@ -4903,20 +4838,19 @@
} else {
token = state.push("bullet_list_open", "ul", 1);
}
- token.map = listLines = [ startLine, 0 ];
+ token.map = listLines = [ nextLine, 0 ];
token.markup = String.fromCharCode(markerCharCode);
// Iterate list items
- nextLine = startLine;
- prevEmptyEnd = false;
+ prevEmptyEnd = false;
terminatorRules = state.md.block.ruler.getRules("list");
oldParentType = state.parentType;
state.parentType = "list";
while (nextLine < endLine) {
pos = posAfterMarker;
max = state.eMarks[nextLine];
- initial = offset = state.sCount[nextLine] + posAfterMarker - (state.bMarks[startLine] + state.tShift[startLine]);
+ initial = offset = state.sCount[nextLine] + posAfterMarker - (state.bMarks[nextLine] + state.tShift[nextLine]);
while (pos < max) {
ch = state.src.charCodeAt(pos);
if (ch === 9) {
@@ -4946,14 +4880,14 @@
// Run subparser & write tokens
token = state.push("list_item_open", "li", 1);
token.markup = String.fromCharCode(markerCharCode);
- token.map = itemLines = [ startLine, 0 ];
+ token.map = itemLines = [ nextLine, 0 ];
if (isOrdered) {
token.info = state.src.slice(start, posAfterMarker - 1);
}
// change current state, then restore it after parser subcall
oldTight = state.tight;
- oldTShift = state.tShift[startLine];
- oldSCount = state.sCount[startLine];
+ oldTShift = state.tShift[nextLine];
+ oldSCount = state.sCount[nextLine];
// - example list
// ^ listIndent position will be here
// ^ blkIndent position will be here
@@ -4962,9 +4896,9 @@
state.listIndent = state.blkIndent;
state.blkIndent = indent;
state.tight = true;
- state.tShift[startLine] = contentStart - state.bMarks[startLine];
- state.sCount[startLine] = offset;
- if (contentStart >= max && state.isEmpty(startLine + 1)) {
+ state.tShift[nextLine] = contentStart - state.bMarks[nextLine];
+ state.sCount[nextLine] = offset;
+ if (contentStart >= max && state.isEmpty(nextLine + 1)) {
// workaround for this case
// (list item is empty, list terminates before "foo"):
// ~~~~~~~~
@@ -4973,7 +4907,7 @@
// ~~~~~~~~
state.line = Math.min(state.line + 2, endLine);
} else {
- state.md.block.tokenize(state, startLine, endLine, true);
+ state.md.block.tokenize(state, nextLine, endLine, true);
}
// If any of list item is tight, mark list as tight
if (!state.tight || prevEmptyEnd) {
@@ -4981,17 +4915,16 @@
}
// Item become loose if finish with empty line,
// but we should filter last element, because it means list finish
- prevEmptyEnd = state.line - startLine > 1 && state.isEmpty(state.line - 1);
+ prevEmptyEnd = state.line - nextLine > 1 && state.isEmpty(state.line - 1);
state.blkIndent = state.listIndent;
state.listIndent = oldListIndent;
- state.tShift[startLine] = oldTShift;
- state.sCount[startLine] = oldSCount;
+ state.tShift[nextLine] = oldTShift;
+ state.sCount[nextLine] = oldSCount;
state.tight = oldTight;
token = state.push("list_item_close", "li", -1);
token.markup = String.fromCharCode(markerCharCode);
- nextLine = startLine = state.line;
+ nextLine = state.line;
itemLines[1] = nextLine;
- contentStart = state.bMarks[startLine];
if (nextLine >= endLine) {
break;
}
@@ -5002,7 +4935,7 @@
break;
}
// if it's indented more than 3 spaces, it should be a code block
- if (state.sCount[startLine] - state.blkIndent >= 4) {
+ if (state.sCount[nextLine] - state.blkIndent >= 4) {
break;
}
// fail if terminating block found
@@ -5410,8 +5343,8 @@
return true;
};
// Paragraph
- var paragraph = function paragraph(state, startLine /*, endLine*/) {
- var content, terminate, i, l, token, oldParentType, nextLine = startLine + 1, terminatorRules = state.md.block.ruler.getRules("paragraph"), endLine = state.lineMax;
+ var paragraph = function paragraph(state, startLine, endLine) {
+ var content, terminate, i, l, token, oldParentType, nextLine = startLine + 1, terminatorRules = state.md.block.ruler.getRules("paragraph");
oldParentType = state.parentType;
state.parentType = "paragraph";
// jump line-by-line until empty one or EOF
@@ -5677,7 +5610,7 @@
// Generate tokens for input range
ParserBlock.prototype.tokenize = function(state, startLine, endLine) {
- var ok, i, rules = this.ruler.getRules(""), len = rules.length, line = startLine, hasEmptyLines = false, maxNesting = state.md.options.maxNesting;
+ var ok, i, prevLine, rules = this.ruler.getRules(""), len = rules.length, line = startLine, hasEmptyLines = false, maxNesting = state.md.options.maxNesting;
while (line < endLine) {
state.line = line = state.skipEmptyLines(line);
if (line >= endLine) {
@@ -5700,12 +5633,18 @@
// - update `state.line`
// - update `state.tokens`
// - return true
- for (i = 0; i < len; i++) {
+ prevLine = state.line;
+ for (i = 0; i < len; i++) {
ok = rules[i](state, line, endLine, false);
if (ok) {
+ if (prevLine >= state.line) {
+ throw new Error("block rule didn't increment state.line");
+ }
break;
}
}
+ // this can only happen if user disables paragraph rule
+ if (!ok) throw new Error("none of the block rules matched");
// set state.tight if we had an empty line before current tag
// i.e. latest empty line should not count
state.tight = !hasEmptyLines;
@@ -5931,7 +5870,7 @@
state.pos += openerLength;
return true;
}
- matchStart = matchEnd = pos;
+ matchEnd = pos;
// Nothing found in the cache, scan until the end of the line (or until marker is found)
while ((matchStart = state.src.indexOf("`", matchEnd)) !== -1) {
matchEnd = matchStart + 1;
@@ -6485,7 +6424,7 @@
}
if (!silent) {
token = state.push("html_inline", "", 0);
- token.content = state.src.slice(pos, pos + match[0].length);
+ token.content = match[0];
if (isLinkOpen(token.content)) state.linkLevel++;
if (isLinkClose(token.content)) state.linkLevel--;
}
@@ -6533,7 +6472,7 @@
return false;
};
// For each opening emphasis-like marker find a matching closing one
- function processDelimiters(state, delimiters) {
+ function processDelimiters(delimiters) {
var closerIdx, openerIdx, closer, opener, minOpenerIdx, newMinOpenerIdx, isOddMatch, lastJump, openersBottom = {}, max = delimiters.length;
if (!max) return;
// headerIdx is the first delimiter of the current (where closer is) delimiter run
@@ -6617,10 +6556,10 @@
}
var balance_pairs = function link_pairs(state) {
var curr, tokens_meta = state.tokens_meta, max = state.tokens_meta.length;
- processDelimiters(state, state.delimiters);
+ processDelimiters(state.delimiters);
for (curr = 0; curr < max; curr++) {
if (tokens_meta[curr] && tokens_meta[curr].delimiters) {
- processDelimiters(state, tokens_meta[curr].delimiters);
+ processDelimiters(tokens_meta[curr].delimiters);
}
}
};
@@ -6818,6 +6757,9 @@
ok = rules[i](state, true);
state.level--;
if (ok) {
+ if (pos >= state.pos) {
+ throw new Error("inline rule didn't increment state.pos");
+ }
break;
}
}
@@ -6839,17 +6781,21 @@
// Generate tokens for input range
ParserInline.prototype.tokenize = function(state) {
- var ok, i, rules = this.ruler.getRules(""), len = rules.length, end = state.posMax, maxNesting = state.md.options.maxNesting;
+ var ok, i, prevPos, rules = this.ruler.getRules(""), len = rules.length, end = state.posMax, maxNesting = state.md.options.maxNesting;
while (state.pos < end) {
// Try all possible rules.
// On success, rule should:
// - update `state.pos`
// - update `state.tokens`
// - return true
+ prevPos = state.pos;
if (state.level < maxNesting) {
for (i = 0; i < len; i++) {
ok = rules[i](state, false);
if (ok) {
+ if (prevPos >= state.pos) {
+ throw new Error("inline rule didn't increment state.pos");
+ }
break;
}
}
@@ -7490,386 +7436,6 @@
* Override to modify basic RegExp-s.
**/ LinkifyIt.prototype.onCompile = function onCompile() {};
var linkifyIt = LinkifyIt;
- /*! https://mths.be/punycode v1.4.1 by @mathias */
- /** Highest positive signed 32-bit float value */ var maxInt = 2147483647;
- // aka. 0x7FFFFFFF or 2^31-1
- /** Bootstring parameters */ var base = 36;
- var tMin = 1;
- var tMax = 26;
- var skew = 38;
- var damp = 700;
- var initialBias = 72;
- var initialN = 128;
- // 0x80
- var delimiter = "-";
- // '\x2D'
- /** Regular expressions */ var regexPunycode = /^xn--/;
- var regexNonASCII = /[^\x20-\x7E]/;
- // unprintable ASCII chars + non-ASCII chars
- var regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g;
- // RFC 3490 separators
- /** Error messages */ var errors = {
- overflow: "Overflow: input needs wider integers to process",
- "not-basic": "Illegal input >= 0x80 (not a basic code point)",
- "invalid-input": "Invalid input"
- };
- /** Convenience shortcuts */ var baseMinusTMin = base - tMin;
- var floor = Math.floor;
- var stringFromCharCode = String.fromCharCode;
- /*--------------------------------------------------------------------------*/
- /**
- * A generic error utility function.
- * @private
- * @param {String} type The error type.
- * @returns {Error} Throws a `RangeError` with the applicable error message.
- */ function error(type) {
- throw new RangeError(errors[type]);
- }
- /**
- * A generic `Array#map` utility function.
- * @private
- * @param {Array} array The array to iterate over.
- * @param {Function} callback The function that gets called for every array
- * item.
- * @returns {Array} A new array of values returned by the callback function.
- */ function map(array, fn) {
- var length = array.length;
- var result = [];
- while (length--) {
- result[length] = fn(array[length]);
- }
- return result;
- }
- /**
- * A simple `Array#map`-like wrapper to work with domain name strings or email
- * addresses.
- * @private
- * @param {String} domain The domain name or email address.
- * @param {Function} callback The function that gets called for every
- * character.
- * @returns {Array} A new string of characters returned by the callback
- * function.
- */ function mapDomain(string, fn) {
- var parts = string.split("@");
- var result = "";
- if (parts.length > 1) {
- // In email addresses, only the domain name should be punycoded. Leave
- // the local part (i.e. everything up to `@`) intact.
- result = parts[0] + "@";
- string = parts[1];
- }
- // Avoid `split(regex)` for IE8 compatibility. See #17.
- string = string.replace(regexSeparators, ".");
- var labels = string.split(".");
- var encoded = map(labels, fn).join(".");
- return result + encoded;
- }
- /**
- * Creates an array containing the numeric code points of each Unicode
- * character in the string. While JavaScript uses UCS-2 internally,
- * this function will convert a pair of surrogate halves (each of which
- * UCS-2 exposes as separate characters) into a single code point,
- * matching UTF-16.
- * @see `punycode.ucs2.encode`
- * @see "+I(e[r].content)+"
\n"},M.fence=function(e,r,t,n,s){var o,i,a,c,l,u=e[r],p=u.info?T(u.info).trim():"",h="",f="";return p&&(h=(a=p.split(/(\s+)/g))[0],f=a.slice(2).join("")),0===(o=t.highlight&&t.highlight(u.content,h,f)||I(u.content)).indexOf(""+o+"
\n"):""+o+"
\n"},M.image=function(e,r,t,n,s){var o=e[r];return o.attrs[o.attrIndex("alt")][1]=s.renderInlineAsText(o.children,t,n),s.renderToken(e,r,t)},M.hardbreak=function(e,r,t){return t.xhtmlOut?"=4))break;s=++n}return e.line=s,(o=e.push("code_block","code",0)).content=e.getLines(r,s,4+e.blkIndent,!1)+"\n",o.map=[r,e.line],!0}],["fence",function(e,r,t,n){var s,o,i,a,c,l,u,p=!1,h=e.bMarks[r]+e.tShift[r],f=e.eMarks[r];if(e.sCount[r]-e.blkIndent>=4)return!1;if(h+3>f)return!1;if(126!==(s=e.src.charCodeAt(h))&&96!==s)return!1;if(c=h,(o=(h=e.skipChars(h,s))-c)<3)return!1;if(u=e.src.slice(c,h),i=e.src.slice(h,f),96===s&&i.indexOf(String.fromCharCode(s))>=0)return!1;if(n)return!0;for(a=r;!(++a>=t)&&!((h=c=e.bMarks[a]+e.tShift[a])<(f=e.eMarks[a])&&e.sCount[a] i;n-=d[n]+1)if((o=r[n]).marker===s.marker&&o.open&&o.end<0&&(c=!1,(o.close||s.open)&&(o.length+s.length)%3==0&&(o.length%3==0&&s.length%3==0||(c=!0)),!c)){l=n>0&&!r[n-1].open?d[n-1]+1:0,d[t]=t-n+l,d[n]=l,s.open=!1,o.end=t,o.close=!1,a=-1,f=-2;break}-1!==a&&(u[s.marker][(s.open?3:0)+(s.length||0)%3]=a)}}}var tr=w.isWhiteSpace,nr=w.isPunctChar,sr=w.isMdAsciiPunct;function or(e,r,t,n){this.src=e,this.env=t,this.md=r,this.tokens=n,this.tokens_meta=Array(n.length),this.pos=0,this.posMax=this.src.length,this.level=0,this.pending="",this.pendingLevel=0,this.cache={},this.delimiters=[],this._prev_delimiters=[],this.backticks={},this.backticksScanned=!1,this.linkLevel=0}or.prototype.pushPending=function(){var e=new oe("text","",0);return e.content=this.pending,e.level=this.pendingLevel,this.tokens.push(e),this.pending="",e},or.prototype.push=function(e,r,t){this.pending&&this.pushPending();var n=new oe(e,r,t),s=null;return t<0&&(this.level--,this.delimiters=this._prev_delimiters.pop()),n.level=this.level,t>0&&(this.level++,this._prev_delimiters.push(this.delimiters),this.delimiters=[],s={delimiters:this.delimiters}),this.pendingLevel=this.level,this.tokens.push(n),this.tokens_meta.push(s),n},or.prototype.scanDelims=function(e,r){var t,n,s,o,i,a,c,l,u,p=e,h=!0,f=!0,d=this.posMax,m=this.src.charCodeAt(e);for(t=e>0?this.src.charCodeAt(e-1):32;p =4))break;s=++n}return e.line=s,(i=e.push("code_block","code",0)).content=e.getLines(r,s,4+e.blkIndent,!1)+"\n",i.map=[r,e.line],!0}],["fence",function(e,r,t,n){var s,i,o,a,c,l,u,p=!1,h=e.bMarks[r]+e.tShift[r],f=e.eMarks[r];if(e.sCount[r]-e.blkIndent>=4)return!1;if(h+3>f)return!1;if(126!==(s=e.src.charCodeAt(h))&&96!==s)return!1;if(c=h,(i=(h=e.skipChars(h,s))-c)<3)return!1;if(u=e.src.slice(c,h),o=e.src.slice(h,f),96===s&&o.indexOf(String.fromCharCode(s))>=0)return!1;if(n)return!0;for(a=r;!(++a>=t)&&!((h=c=e.bMarks[a]+e.tShift[a])<(f=e.eMarks[a])&&e.sCount[a]
\n"},I.fence=function(e,r,t,n,s){var i,o,a,c,l,u=e[r],p=u.info?z(u.info).trim():"",h="",f="";return p&&(h=(a=p.split(/(\s+)/g))[0],f=a.slice(2).join("")),0===(i=t.highlight&&t.highlight(u.content,h,f)||T(u.content)).indexOf(""+T(e[r].content)+"
\n"):""+i+"
\n"},I.image=function(e,r,t,n,s){var i=e[r];return i.attrs[i.attrIndex("alt")][1]=s.renderInlineAsText(i.children,t,n),s.renderToken(e,r,t)},I.hardbreak=function(e,r,t){return t.xhtmlOut?""+i+"
\n":"
\n"},I.softbreak=function(e,r,t){return t.breaks?t.xhtmlOut?"
\n":"
\n":"\n"},I.text=function(e,r){return T(e[r].content)},I.html_block=function(e,r){return e[r].content},I.html_inline=function(e,r){return e[r].content},R.prototype.renderAttrs=function(e){var r,t,n;if(!e.attrs)return"";for(n="",r=0,t=e.attrs.length;r