|
@ -112,7 +112,6 @@ module.exports = function list(state, startLine, endLine, silent) { |
|
|
markerCharCode, |
|
|
markerCharCode, |
|
|
markerValue, |
|
|
markerValue, |
|
|
max, |
|
|
max, |
|
|
nextLine, |
|
|
|
|
|
offset, |
|
|
offset, |
|
|
oldListIndent, |
|
|
oldListIndent, |
|
|
oldParentType, |
|
|
oldParentType, |
|
@ -126,11 +125,12 @@ module.exports = function list(state, startLine, endLine, silent) { |
|
|
terminate, |
|
|
terminate, |
|
|
terminatorRules, |
|
|
terminatorRules, |
|
|
token, |
|
|
token, |
|
|
|
|
|
nextLine = startLine, |
|
|
isTerminatingParagraph = false, |
|
|
isTerminatingParagraph = false, |
|
|
tight = true; |
|
|
tight = true; |
|
|
|
|
|
|
|
|
// if it's indented more than 3 spaces, it should be a code block
|
|
|
// if it's indented more than 3 spaces, it should be a code block
|
|
|
if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } |
|
|
if (state.sCount[nextLine] - state.blkIndent >= 4) { return false; } |
|
|
|
|
|
|
|
|
// Special case:
|
|
|
// Special case:
|
|
|
// - item 1
|
|
|
// - item 1
|
|
@ -139,8 +139,8 @@ module.exports = function list(state, startLine, endLine, silent) { |
|
|
// - item 4
|
|
|
// - item 4
|
|
|
// - this one is a paragraph continuation
|
|
|
// - this one is a paragraph continuation
|
|
|
if (state.listIndent >= 0 && |
|
|
if (state.listIndent >= 0 && |
|
|
state.sCount[startLine] - state.listIndent >= 4 && |
|
|
state.sCount[nextLine] - state.listIndent >= 4 && |
|
|
state.sCount[startLine] < state.blkIndent) { |
|
|
state.sCount[nextLine] < state.blkIndent) { |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -152,22 +152,22 @@ module.exports = function list(state, startLine, endLine, silent) { |
|
|
// This code can fail if plugins use blkIndent as well as lists,
|
|
|
// This code can fail if plugins use blkIndent as well as lists,
|
|
|
// but I hope the spec gets fixed long before that happens.
|
|
|
// 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; |
|
|
isTerminatingParagraph = true; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Detect list type and position after marker
|
|
|
// Detect list type and position after marker
|
|
|
if ((posAfterMarker = skipOrderedListMarker(state, startLine)) >= 0) { |
|
|
if ((posAfterMarker = skipOrderedListMarker(state, nextLine)) >= 0) { |
|
|
isOrdered = true; |
|
|
isOrdered = true; |
|
|
start = state.bMarks[startLine] + state.tShift[startLine]; |
|
|
start = state.bMarks[nextLine] + state.tShift[nextLine]; |
|
|
markerValue = Number(state.src.slice(start, posAfterMarker - 1)); |
|
|
markerValue = Number(state.src.slice(start, posAfterMarker - 1)); |
|
|
|
|
|
|
|
|
// If we're starting a new ordered list right after
|
|
|
// If we're starting a new ordered list right after
|
|
|
// a paragraph, it should start with 1.
|
|
|
// a paragraph, it should start with 1.
|
|
|
if (isTerminatingParagraph && markerValue !== 1) return false; |
|
|
if (isTerminatingParagraph && markerValue !== 1) return false; |
|
|
|
|
|
|
|
|
} else if ((posAfterMarker = skipBulletListMarker(state, startLine)) >= 0) { |
|
|
} else if ((posAfterMarker = skipBulletListMarker(state, nextLine)) >= 0) { |
|
|
isOrdered = false; |
|
|
isOrdered = false; |
|
|
|
|
|
|
|
|
} else { |
|
|
} else { |
|
@ -177,15 +177,15 @@ module.exports = function list(state, startLine, endLine, silent) { |
|
|
// If we're starting a new unordered list right after
|
|
|
// If we're starting a new unordered list right after
|
|
|
// a paragraph, first line should not be empty.
|
|
|
// a paragraph, first line should not be empty.
|
|
|
if (isTerminatingParagraph) { |
|
|
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
|
|
|
// For validation mode we can terminate immediately
|
|
|
if (silent) { return true; } |
|
|
if (silent) { return true; } |
|
|
|
|
|
|
|
|
|
|
|
// We should terminate list on style change. Remember first one to compare.
|
|
|
|
|
|
markerCharCode = state.src.charCodeAt(posAfterMarker - 1); |
|
|
|
|
|
|
|
|
// Start list
|
|
|
// Start list
|
|
|
listTokIdx = state.tokens.length; |
|
|
listTokIdx = state.tokens.length; |
|
|
|
|
|
|
|
@ -199,14 +199,13 @@ module.exports = function list(state, startLine, endLine, silent) { |
|
|
token = state.push('bullet_list_open', 'ul', 1); |
|
|
token = state.push('bullet_list_open', 'ul', 1); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
token.map = listLines = [ startLine, 0 ]; |
|
|
token.map = listLines = [ nextLine, 0 ]; |
|
|
token.markup = String.fromCharCode(markerCharCode); |
|
|
token.markup = String.fromCharCode(markerCharCode); |
|
|
|
|
|
|
|
|
//
|
|
|
//
|
|
|
// Iterate list items
|
|
|
// Iterate list items
|
|
|
//
|
|
|
//
|
|
|
|
|
|
|
|
|
nextLine = startLine; |
|
|
|
|
|
prevEmptyEnd = false; |
|
|
prevEmptyEnd = false; |
|
|
terminatorRules = state.md.block.ruler.getRules('list'); |
|
|
terminatorRules = state.md.block.ruler.getRules('list'); |
|
|
|
|
|
|
|
@ -217,7 +216,7 @@ module.exports = function list(state, startLine, endLine, silent) { |
|
|
pos = posAfterMarker; |
|
|
pos = posAfterMarker; |
|
|
max = state.eMarks[nextLine]; |
|
|
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) { |
|
|
while (pos < max) { |
|
|
ch = state.src.charCodeAt(pos); |
|
|
ch = state.src.charCodeAt(pos); |
|
@ -253,15 +252,15 @@ module.exports = function list(state, startLine, endLine, silent) { |
|
|
// Run subparser & write tokens
|
|
|
// Run subparser & write tokens
|
|
|
token = state.push('list_item_open', 'li', 1); |
|
|
token = state.push('list_item_open', 'li', 1); |
|
|
token.markup = String.fromCharCode(markerCharCode); |
|
|
token.markup = String.fromCharCode(markerCharCode); |
|
|
token.map = itemLines = [ startLine, 0 ]; |
|
|
token.map = itemLines = [ nextLine, 0 ]; |
|
|
if (isOrdered) { |
|
|
if (isOrdered) { |
|
|
token.info = state.src.slice(start, posAfterMarker - 1); |
|
|
token.info = state.src.slice(start, posAfterMarker - 1); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// change current state, then restore it after parser subcall
|
|
|
// change current state, then restore it after parser subcall
|
|
|
oldTight = state.tight; |
|
|
oldTight = state.tight; |
|
|
oldTShift = state.tShift[startLine]; |
|
|
oldTShift = state.tShift[nextLine]; |
|
|
oldSCount = state.sCount[startLine]; |
|
|
oldSCount = state.sCount[nextLine]; |
|
|
|
|
|
|
|
|
// - example list
|
|
|
// - example list
|
|
|
// ^ listIndent position will be here
|
|
|
// ^ listIndent position will be here
|
|
@ -272,10 +271,10 @@ module.exports = function list(state, startLine, endLine, silent) { |
|
|
state.blkIndent = indent; |
|
|
state.blkIndent = indent; |
|
|
|
|
|
|
|
|
state.tight = true; |
|
|
state.tight = true; |
|
|
state.tShift[startLine] = contentStart - state.bMarks[startLine]; |
|
|
state.tShift[nextLine] = contentStart - state.bMarks[nextLine]; |
|
|
state.sCount[startLine] = offset; |
|
|
state.sCount[nextLine] = offset; |
|
|
|
|
|
|
|
|
if (contentStart >= max && state.isEmpty(startLine + 1)) { |
|
|
if (contentStart >= max && state.isEmpty(nextLine + 1)) { |
|
|
// workaround for this case
|
|
|
// workaround for this case
|
|
|
// (list item is empty, list terminates before "foo"):
|
|
|
// (list item is empty, list terminates before "foo"):
|
|
|
// ~~~~~~~~
|
|
|
// ~~~~~~~~
|
|
@ -285,7 +284,7 @@ module.exports = function list(state, startLine, endLine, silent) { |
|
|
// ~~~~~~~~
|
|
|
// ~~~~~~~~
|
|
|
state.line = Math.min(state.line + 2, endLine); |
|
|
state.line = Math.min(state.line + 2, endLine); |
|
|
} else { |
|
|
} 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 any of list item is tight, mark list as tight
|
|
@ -294,20 +293,19 @@ module.exports = function list(state, startLine, endLine, silent) { |
|
|
} |
|
|
} |
|
|
// Item become loose if finish with empty line,
|
|
|
// Item become loose if finish with empty line,
|
|
|
// but we should filter last element, because it means list finish
|
|
|
// 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.blkIndent = state.listIndent; |
|
|
state.listIndent = oldListIndent; |
|
|
state.listIndent = oldListIndent; |
|
|
state.tShift[startLine] = oldTShift; |
|
|
state.tShift[nextLine] = oldTShift; |
|
|
state.sCount[startLine] = oldSCount; |
|
|
state.sCount[nextLine] = oldSCount; |
|
|
state.tight = oldTight; |
|
|
state.tight = oldTight; |
|
|
|
|
|
|
|
|
token = state.push('list_item_close', 'li', -1); |
|
|
token = state.push('list_item_close', 'li', -1); |
|
|
token.markup = String.fromCharCode(markerCharCode); |
|
|
token.markup = String.fromCharCode(markerCharCode); |
|
|
|
|
|
|
|
|
nextLine = startLine = state.line; |
|
|
nextLine = state.line; |
|
|
itemLines[1] = nextLine; |
|
|
itemLines[1] = nextLine; |
|
|
contentStart = state.bMarks[startLine]; |
|
|
|
|
|
|
|
|
|
|
|
if (nextLine >= endLine) { break; } |
|
|
if (nextLine >= endLine) { break; } |
|
|
|
|
|
|
|
@ -317,7 +315,7 @@ module.exports = function list(state, startLine, endLine, silent) { |
|
|
if (state.sCount[nextLine] < state.blkIndent) { break; } |
|
|
if (state.sCount[nextLine] < state.blkIndent) { break; } |
|
|
|
|
|
|
|
|
// if it's indented more than 3 spaces, it should be a code block
|
|
|
// if it's indented more than 3 spaces, it should be a code block
|
|
|
if (state.sCount[startLine] - state.blkIndent >= 4) { break; } |
|
|
if (state.sCount[nextLine] - state.blkIndent >= 4) { break; } |
|
|
|
|
|
|
|
|
// fail if terminating block found
|
|
|
// fail if terminating block found
|
|
|
terminate = false; |
|
|
terminate = false; |
|
|