fix(lists): fix github code blocks not being parsed inside lists

Fix ghCodeBlocks not being correctly parsed inside lists. Also, as a side
effect, fixes issues with consecutive lists and extra paragraphs being
added into lists.

Closes #142, Closes #183, Closes #184
This commit is contained in:
Estevão Soares dos Santos 2015-08-01 21:05:28 +01:00
parent 086c41de54
commit 7720c88bfc
20 changed files with 276 additions and 213 deletions

174
dist/showdown.js vendored
View File

@ -1,4 +1,4 @@
;/*! showdown 22-07-2015 */ ;/*! showdown 01-08-2015 */
(function(){ (function(){
/** /**
* Created by Tivie on 13-07-2015. * Created by Tivie on 13-07-2015.
@ -1395,14 +1395,8 @@ showdown.subParser('githubCodeBlocks', function (text, options, globals) {
text += '~0'; text += '~0';
text = text.replace(/(?:^|\n)```(.*)\n([\s\S]*?)\n```/g, function (wholeMatch, m1, m2) { text = text.replace(/(?:^|\n)```(.*)\n([\s\S]*?)\n```/g, function (wholeMatch, language, codeblock) {
var language = m1, var end = (options.omitExtraWLInCodeBlocks) ? '' : '\n';
codeblock = m2,
end = '\n';
if (options.omitExtraWLInCodeBlocks) {
end = '';
}
codeblock = showdown.subParser('encodeCode')(codeblock); codeblock = showdown.subParser('encodeCode')(codeblock);
codeblock = showdown.subParser('detab')(codeblock); codeblock = showdown.subParser('detab')(codeblock);
@ -1755,15 +1749,13 @@ showdown.subParser('italicsAndBold', function (text, options) {
showdown.subParser('lists', function (text, options, globals) { showdown.subParser('lists', function (text, options, globals) {
'use strict'; 'use strict';
var spl = '~1';
/** /**
* Process the contents of a single ordered or unordered list, splitting it * Process the contents of a single ordered or unordered list, splitting it
* into individual list items. * into individual list items.
* @param {string} listStr * @param {string} listStr
* @returns {string} * @returns {string}
*/ */
function processListItems (listStr) { function processListItems (listStr, trimTrailing) {
// The $g_list_level global keeps track of when we're inside a list. // The $g_list_level global keeps track of when we're inside a list.
// Each time we enter a list, we increment it; when we leave a list, // Each time we enter a list, we increment it; when we leave a list,
// we decrement. If it's zero, we're not in a list anymore. // we decrement. If it's zero, we're not in a list anymore.
@ -1784,7 +1776,6 @@ showdown.subParser('lists', function (text, options, globals) {
// without resorting to mind-reading. Perhaps the solution is to // without resorting to mind-reading. Perhaps the solution is to
// change the syntax rules such that sub-lists must start with a // change the syntax rules such that sub-lists must start with a
// starting cardinal number; e.g. "1." or "a.". // starting cardinal number; e.g. "1." or "a.".
globals.gListLevel++; globals.gListLevel++;
// trim trailing blank lines: // trim trailing blank lines:
@ -1793,93 +1784,96 @@ showdown.subParser('lists', function (text, options, globals) {
// attacklab: add sentinel to emulate \z // attacklab: add sentinel to emulate \z
listStr += '~0'; listStr += '~0';
var rgx = /(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+((\[(x| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm; var rgx = /(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+((\[(x| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm,
isParagraphed = (/\n[ \t]*\n(?!~0)/.test(listStr));
listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) { listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) {
checked = (checked && checked.trim() !== ''); checked = (checked && checked.trim() !== '');
var item = showdown.subParser('outdent')(m4, options, globals),
bulletStyle = '';
var item = showdown.subParser('outdent')(m4, options, globals); // Support for github tasklists
if (taskbtn && options.tasklists) {
//m1 - LeadingLine bulletStyle = ' class="task-list-item" style="list-style-type: none;"';
item = item.replace(/^[ \t]*\[(x| )?]/m, function () {
var otp = '<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"';
if (checked) {
otp += ' checked';
}
otp += '>';
return otp;
});
}
// m1 - Leading line or
// Has a double return (multi paragraph) or
// Has sublist
if (m1 || (item.search(/\n{2,}/) > -1)) { if (m1 || (item.search(/\n{2,}/) > -1)) {
item = showdown.subParser('githubCodeBlocks')(item, options, globals);
item = showdown.subParser('blockGamut')(item, options, globals); item = showdown.subParser('blockGamut')(item, options, globals);
} else { } else {
if (taskbtn && options.tasklists) {
item = item.replace(taskbtn, function () {
var otp = '<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"';
if (checked) {
otp += ' checked';
}
otp += '>';
return otp;
});
}
// Recursion for sub-lists: // Recursion for sub-lists:
item = showdown.subParser('lists')(item, options, globals); item = showdown.subParser('lists')(item, options, globals);
item = item.replace(/\n$/, ''); // chomp(item) item = item.replace(/\n$/, ''); // chomp(item)
item = showdown.subParser('spanGamut')(item, options, globals); if (isParagraphed) {
item = showdown.subParser('paragraphs')(item, options, globals);
} else {
item = showdown.subParser('spanGamut')(item, options, globals);
}
} }
item = '\n<li' + bulletStyle + '>' + item + '</li>\n';
// this is a "hack" to differentiate between ordered and unordered lists return item;
// related to issue #142
var tp = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol',
bulletStyle = '';
if (taskbtn) {
bulletStyle = ' class="task-list-item" style="list-style-type: none;"';
}
return spl + tp + '<li' + bulletStyle + '>' + item + '</li>\n';
}); });
// attacklab: strip sentinel // attacklab: strip sentinel
listStr = listStr.replace(/~0/g, ''); listStr = listStr.replace(/~0/g, '');
globals.gListLevel--; globals.gListLevel--;
if (trimTrailing) {
listStr = listStr.replace(/\s+$/, '');
}
return listStr; return listStr;
} }
/** /**
* Slit consecutive ol/ul lists (related to issue 142) * Check and parse consecutive lists (better fix for issue #142)
* @param {Array} results * @param {string} list
* @param {string} listType * @param {string} listType
* @returns {string|*} * @returns {string}
*/ */
function splitConsecutiveLists (results, listType) { function parseConsecutiveLists(list, listType, trimTrailing) {
// parsing html with regex... // check if we caught 2 or more consecutive lists by mistake
// This will surely fail if some extension decides to change paragraph markup directly // we use the counterRgx, meaning if listType is UL we look for UL and vice versa
var cthulhu = /(<p[^>]+?>|<p>|<\/p>)/img, var counterRxg = (listType === 'ul') ? /^ {0,2}\d+\.[ \t]/gm : /^ {0,2}[*+-][ \t]/gm,
holder = [[]], subLists = [],
res = '', result = '';
y = 0;
// Initialize first sublist if (list.search(counterRxg) !== -1) {
holder[0].type = listType; (function parseCL(txt) {
var pos = txt.search(counterRxg);
if (pos !== -1) {
// slice
result += '\n\n<' + listType + '>' + processListItems(txt.slice(0, pos), !!trimTrailing) + '</' + listType + '>\n\n';
for (var i = 0; i < results.length; ++i) { // invert counterType and listType
var txt = results[i].slice(2), listType = (listType === 'ul') ? 'ol' : 'ul';
nListType = results[i].slice(0, 2); counterRxg = (listType === 'ul') ? /^ {0,2}\d+\.[ \t]/gm : /^ {0,2}[*+-][ \t]/gm;
if (listType !== nListType) { //recurse
y++; parseCL(txt.slice(pos));
holder[y] = []; } else {
holder[y].type = nListType; result += '\n\n<' + listType + '>' + processListItems(txt, !!trimTrailing) + '</' + listType + '>\n\n';
listType = nListType;
}
holder[y].push(txt);
}
for (i = 0; i < holder.length; ++i) {
res += '<' + holder[i].type + '>\n';
for (var ii = 0; ii < holder[i].length; ++ii) {
if (holder[i].length > 1 && ii === holder[i].length - 1 && !cthulhu.test(holder[i][ii - 1])) {
//holder[i][ii] = holder[i][ii].replace(cthulhu, '');
} }
res += holder[i][ii]; })(list);
for (var i = 0; i < subLists.length; ++i) {
} }
res += '</' + holder[i].type + '>\n'; } else {
result = '\n\n<' + listType + '>' + processListItems(list, !!trimTrailing) + '</' + listType + '>\n\n';
} }
return res;
return result;
} }
// attacklab: add sentinel to hack around khtml/safari bug: // attacklab: add sentinel to hack around khtml/safari bug:
@ -1890,41 +1884,17 @@ showdown.subParser('lists', function (text, options, globals) {
var wholeList = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm; var wholeList = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm;
if (globals.gListLevel) { if (globals.gListLevel) {
text = text.replace(wholeList, function (wholeMatch, m1, m2) { text = text.replace(wholeList, function (wholeMatch, list, m2) {
var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol', var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol';
result = processListItems(m1); return parseConsecutiveLists(list, listType, true);
// Turn double returns into triple returns, so that we can make a
// paragraph for the last item in a list, if necessary:
//list = list.replace(/\n{2,}/g, '\n\n\n');
//result = processListItems(list);
// Trim any trailing whitespace, to put the closing `</$list_type>`
// up on the preceding line, to get it past the current stupid
// HTML block parser. This is a hack to work around the terrible
// hack that is the HTML block parser.
result = result.replace(/\s+$/, '');
var splRes = result.split(spl);
splRes.shift();
result = splitConsecutiveLists(splRes, listType);
return result;
}); });
} else { } else {
wholeList = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/g; wholeList = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm;
//wholeList = /(\n\n|^\n?)( {0,3}([*+-]|\d+\.)[ \t]+[\s\S]+?)(?=(~0)|(\n\n(?!\t| {2,}| {0,3}([*+-]|\d+\.)[ \t])))/g; //wholeList = /(\n\n|^\n?)( {0,3}([*+-]|\d+\.)[ \t]+[\s\S]+?)(?=(~0)|(\n\n(?!\t| {2,}| {0,3}([*+-]|\d+\.)[ \t])))/g;
text = text.replace(wholeList, function (wholeMatch, m1, list, m3) {
text = text.replace(wholeList, function (wholeMatch, m1, m2, m3) { var listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol';
return parseConsecutiveLists(list, listType);
// Turn double returns into triple returns, so that we can make a
// paragraph for the last item in a list, if necessary:
var list = m2.replace(/\n{2,}/g, '\n\n\n'),
//var list = (m2.slice(-2) !== '~0') ? m2 + '\n' : m2, //add a newline after the list
listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol',
result = processListItems(list),
splRes = result.split(spl);
splRes.shift();
return m1 + splitConsecutiveLists(splRes, listType) + '\n';
}); });
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{ {
"name": "showdown", "name": "showdown",
"version": "1.2.1", "version": "1.2.2",
"description": "A Markdown to HTML converter written in Javascript", "description": "A Markdown to HTML converter written in Javascript",
"author": "Estevão Santos", "author": "Estevão Santos",
"homepage": "http://showdownjs.github.io/showdown/", "homepage": "http://showdownjs.github.io/showdown/",

View File

@ -18,14 +18,8 @@ showdown.subParser('githubCodeBlocks', function (text, options, globals) {
text += '~0'; text += '~0';
text = text.replace(/(?:^|\n)```(.*)\n([\s\S]*?)\n```/g, function (wholeMatch, m1, m2) { text = text.replace(/(?:^|\n)```(.*)\n([\s\S]*?)\n```/g, function (wholeMatch, language, codeblock) {
var language = m1, var end = (options.omitExtraWLInCodeBlocks) ? '' : '\n';
codeblock = m2,
end = '\n';
if (options.omitExtraWLInCodeBlocks) {
end = '';
}
codeblock = showdown.subParser('encodeCode')(codeblock); codeblock = showdown.subParser('encodeCode')(codeblock);
codeblock = showdown.subParser('detab')(codeblock); codeblock = showdown.subParser('detab')(codeblock);

View File

@ -4,15 +4,13 @@
showdown.subParser('lists', function (text, options, globals) { showdown.subParser('lists', function (text, options, globals) {
'use strict'; 'use strict';
var spl = '~1';
/** /**
* Process the contents of a single ordered or unordered list, splitting it * Process the contents of a single ordered or unordered list, splitting it
* into individual list items. * into individual list items.
* @param {string} listStr * @param {string} listStr
* @returns {string} * @returns {string}
*/ */
function processListItems (listStr) { function processListItems (listStr, trimTrailing) {
// The $g_list_level global keeps track of when we're inside a list. // The $g_list_level global keeps track of when we're inside a list.
// Each time we enter a list, we increment it; when we leave a list, // Each time we enter a list, we increment it; when we leave a list,
// we decrement. If it's zero, we're not in a list anymore. // we decrement. If it's zero, we're not in a list anymore.
@ -33,7 +31,6 @@ showdown.subParser('lists', function (text, options, globals) {
// without resorting to mind-reading. Perhaps the solution is to // without resorting to mind-reading. Perhaps the solution is to
// change the syntax rules such that sub-lists must start with a // change the syntax rules such that sub-lists must start with a
// starting cardinal number; e.g. "1." or "a.". // starting cardinal number; e.g. "1." or "a.".
globals.gListLevel++; globals.gListLevel++;
// trim trailing blank lines: // trim trailing blank lines:
@ -42,93 +39,96 @@ showdown.subParser('lists', function (text, options, globals) {
// attacklab: add sentinel to emulate \z // attacklab: add sentinel to emulate \z
listStr += '~0'; listStr += '~0';
var rgx = /(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+((\[(x| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm; var rgx = /(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+((\[(x| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm,
isParagraphed = (/\n[ \t]*\n(?!~0)/.test(listStr));
listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) { listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) {
checked = (checked && checked.trim() !== ''); checked = (checked && checked.trim() !== '');
var item = showdown.subParser('outdent')(m4, options, globals),
bulletStyle = '';
var item = showdown.subParser('outdent')(m4, options, globals); // Support for github tasklists
if (taskbtn && options.tasklists) {
//m1 - LeadingLine bulletStyle = ' class="task-list-item" style="list-style-type: none;"';
item = item.replace(/^[ \t]*\[(x| )?]/m, function () {
var otp = '<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"';
if (checked) {
otp += ' checked';
}
otp += '>';
return otp;
});
}
// m1 - Leading line or
// Has a double return (multi paragraph) or
// Has sublist
if (m1 || (item.search(/\n{2,}/) > -1)) { if (m1 || (item.search(/\n{2,}/) > -1)) {
item = showdown.subParser('githubCodeBlocks')(item, options, globals);
item = showdown.subParser('blockGamut')(item, options, globals); item = showdown.subParser('blockGamut')(item, options, globals);
} else { } else {
if (taskbtn && options.tasklists) {
item = item.replace(taskbtn, function () {
var otp = '<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"';
if (checked) {
otp += ' checked';
}
otp += '>';
return otp;
});
}
// Recursion for sub-lists: // Recursion for sub-lists:
item = showdown.subParser('lists')(item, options, globals); item = showdown.subParser('lists')(item, options, globals);
item = item.replace(/\n$/, ''); // chomp(item) item = item.replace(/\n$/, ''); // chomp(item)
item = showdown.subParser('spanGamut')(item, options, globals); if (isParagraphed) {
item = showdown.subParser('paragraphs')(item, options, globals);
} else {
item = showdown.subParser('spanGamut')(item, options, globals);
}
} }
item = '\n<li' + bulletStyle + '>' + item + '</li>\n';
// this is a "hack" to differentiate between ordered and unordered lists return item;
// related to issue #142
var tp = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol',
bulletStyle = '';
if (taskbtn) {
bulletStyle = ' class="task-list-item" style="list-style-type: none;"';
}
return spl + tp + '<li' + bulletStyle + '>' + item + '</li>\n';
}); });
// attacklab: strip sentinel // attacklab: strip sentinel
listStr = listStr.replace(/~0/g, ''); listStr = listStr.replace(/~0/g, '');
globals.gListLevel--; globals.gListLevel--;
if (trimTrailing) {
listStr = listStr.replace(/\s+$/, '');
}
return listStr; return listStr;
} }
/** /**
* Slit consecutive ol/ul lists (related to issue 142) * Check and parse consecutive lists (better fix for issue #142)
* @param {Array} results * @param {string} list
* @param {string} listType * @param {string} listType
* @returns {string|*} * @returns {string}
*/ */
function splitConsecutiveLists (results, listType) { function parseConsecutiveLists(list, listType, trimTrailing) {
// parsing html with regex... // check if we caught 2 or more consecutive lists by mistake
// This will surely fail if some extension decides to change paragraph markup directly // we use the counterRgx, meaning if listType is UL we look for UL and vice versa
var cthulhu = /(<p[^>]+?>|<p>|<\/p>)/img, var counterRxg = (listType === 'ul') ? /^ {0,2}\d+\.[ \t]/gm : /^ {0,2}[*+-][ \t]/gm,
holder = [[]], subLists = [],
res = '', result = '';
y = 0;
// Initialize first sublist if (list.search(counterRxg) !== -1) {
holder[0].type = listType; (function parseCL(txt) {
var pos = txt.search(counterRxg);
if (pos !== -1) {
// slice
result += '\n\n<' + listType + '>' + processListItems(txt.slice(0, pos), !!trimTrailing) + '</' + listType + '>\n\n';
for (var i = 0; i < results.length; ++i) { // invert counterType and listType
var txt = results[i].slice(2), listType = (listType === 'ul') ? 'ol' : 'ul';
nListType = results[i].slice(0, 2); counterRxg = (listType === 'ul') ? /^ {0,2}\d+\.[ \t]/gm : /^ {0,2}[*+-][ \t]/gm;
if (listType !== nListType) { //recurse
y++; parseCL(txt.slice(pos));
holder[y] = []; } else {
holder[y].type = nListType; result += '\n\n<' + listType + '>' + processListItems(txt, !!trimTrailing) + '</' + listType + '>\n\n';
listType = nListType;
}
holder[y].push(txt);
}
for (i = 0; i < holder.length; ++i) {
res += '<' + holder[i].type + '>\n';
for (var ii = 0; ii < holder[i].length; ++ii) {
if (holder[i].length > 1 && ii === holder[i].length - 1 && !cthulhu.test(holder[i][ii - 1])) {
//holder[i][ii] = holder[i][ii].replace(cthulhu, '');
} }
res += holder[i][ii]; })(list);
for (var i = 0; i < subLists.length; ++i) {
} }
res += '</' + holder[i].type + '>\n'; } else {
result = '\n\n<' + listType + '>' + processListItems(list, !!trimTrailing) + '</' + listType + '>\n\n';
} }
return res;
return result;
} }
// attacklab: add sentinel to hack around khtml/safari bug: // attacklab: add sentinel to hack around khtml/safari bug:
@ -139,41 +139,17 @@ showdown.subParser('lists', function (text, options, globals) {
var wholeList = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm; var wholeList = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm;
if (globals.gListLevel) { if (globals.gListLevel) {
text = text.replace(wholeList, function (wholeMatch, m1, m2) { text = text.replace(wholeList, function (wholeMatch, list, m2) {
var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol', var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol';
result = processListItems(m1); return parseConsecutiveLists(list, listType, true);
// Turn double returns into triple returns, so that we can make a
// paragraph for the last item in a list, if necessary:
//list = list.replace(/\n{2,}/g, '\n\n\n');
//result = processListItems(list);
// Trim any trailing whitespace, to put the closing `</$list_type>`
// up on the preceding line, to get it past the current stupid
// HTML block parser. This is a hack to work around the terrible
// hack that is the HTML block parser.
result = result.replace(/\s+$/, '');
var splRes = result.split(spl);
splRes.shift();
result = splitConsecutiveLists(splRes, listType);
return result;
}); });
} else { } else {
wholeList = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/g; wholeList = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm;
//wholeList = /(\n\n|^\n?)( {0,3}([*+-]|\d+\.)[ \t]+[\s\S]+?)(?=(~0)|(\n\n(?!\t| {2,}| {0,3}([*+-]|\d+\.)[ \t])))/g; //wholeList = /(\n\n|^\n?)( {0,3}([*+-]|\d+\.)[ \t]+[\s\S]+?)(?=(~0)|(\n\n(?!\t| {2,}| {0,3}([*+-]|\d+\.)[ \t])))/g;
text = text.replace(wholeList, function (wholeMatch, m1, list, m3) {
text = text.replace(wholeList, function (wholeMatch, m1, m2, m3) { var listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol';
return parseConsecutiveLists(list, listType);
// Turn double returns into triple returns, so that we can make a
// paragraph for the last item in a list, if necessary:
var list = m2.replace(/\n{2,}/g, '\n\n\n'),
//var list = (m2.slice(-2) !== '~0') ? m2 + '\n' : m2, //add a newline after the list
listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol',
result = processListItems(list),
splRes = result.split(spl);
splRes.shift();
return m1 + splitConsecutiveLists(splRes, listType) + '\n';
}); });
} }

View File

@ -0,0 +1,15 @@
<h1 id="sometitle">some title</h1>
<ol>
<li>list item 1</li>
<li>list item 2</li>
</ol>
<blockquote>
<p>some text in a blockquote</p>
</blockquote>
<ul>
<li>another list item 1</li>
<li>another list item 2</li>
</ul>

View File

@ -0,0 +1,9 @@
# some title
1. list item 1
2. list item 2
> some text in a blockquote
* another list item 1
* another list item 2

View File

@ -0,0 +1,16 @@
<h1 id="sometitle">some title</h1>
<ol>
<li>list item 1</li>
<li>list item 2</li>
</ol>
<pre><code>some code
and some other line of code
</code></pre>
<ul>
<li>another list item 1</li>
<li>another list item 2</li>
</ul>

View File

@ -0,0 +1,13 @@
# some title
1. list item 1
2. list item 2
```
some code
and some other line of code
```
* another list item 1
* another list item 2

View File

@ -0,0 +1,15 @@
<ul>
<li><p>foo</p>
<ul>
<li><p>bazinga</p></li>
<li><p>yeah</p></li>
</ul>
</li>
<li><p>bar</p>
<ol>
<li><p>damn</p></li>
<li><p>so many paragraphs</p></li>
</ol>
</li>
<li><p>baz</p></li>
</ul>

View File

@ -0,0 +1,13 @@
- foo
- bazinga
- yeah
- bar
1. damn
2. so many paragraphs
- baz

View File

@ -45,7 +45,7 @@
</ol> </ol>
<blockquote> <blockquote>
<p>foo_bar_baz foo_bar_baz_bar_foo <em>foo_bar baz_bar</em> baz_foo</p> <p>blockquote foo_bar_baz foo_bar_baz_bar_foo <em>foo_bar baz_bar</em> baz_foo</p>
</blockquote> </blockquote>
<ul> <ul>

View File

@ -45,7 +45,7 @@ foo_bar_baz foo_bar_baz_bar_foo _foo_bar baz_bar_ baz_foo
1. foo_bar_baz foo_bar_baz_bar_foo _foo_bar baz_bar_ baz_foo 1. foo_bar_baz foo_bar_baz_bar_foo _foo_bar baz_bar_ baz_foo
2. foo_bar_baz foo_bar_baz_bar_foo _foo_bar baz_bar_ baz_foo 2. foo_bar_baz foo_bar_baz_bar_foo _foo_bar baz_bar_ baz_foo
> foo_bar_baz foo_bar_baz_bar_foo _foo_bar baz_bar_ baz_foo > blockquote foo_bar_baz foo_bar_baz_bar_foo _foo_bar baz_bar_ baz_foo
* foo_bar_baz foo_bar_baz_bar_foo _foo_bar baz_bar_ baz_foo * foo_bar_baz foo_bar_baz_bar_foo _foo_bar baz_bar_ baz_foo
* foo_bar_baz foo_bar_baz_bar_foo _foo_bar baz_bar_ baz_foo * foo_bar_baz foo_bar_baz_bar_foo _foo_bar baz_bar_ baz_foo

View File

@ -1,8 +1,12 @@
<ul> <ul>
<li>Item 1</li> <li>Item 1</li>
<li><p>Item 2</p></li> <li>Item 2</li>
</ul> </ul>
<ol> <ol>
<li><p>Item 1</p></li> <li>Item 1</li>
<li>Item 2</li> <li>Item 2</li>
</ol> </ol>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>

View File

@ -3,3 +3,6 @@
1. Item 1 1. Item 1
2. Item 2 2. Item 2
- Item 1
- Item 2

View File

@ -0,0 +1,16 @@
<ol>
<li>
<p>Hi, I am a thing</p>
<pre><code class="sh language-sh">$ git clone thing.git
dfgdfg
</code></pre></li>
<li>
<p>I am another thing!</p>
<pre><code class="sh language-sh">$ git clone other-thing.git
foobar
</code></pre></li>
</ol>

View File

@ -0,0 +1,17 @@
1. Hi, I am a thing
```sh
$ git clone thing.git
dfgdfg
```
1. I am another thing!
```sh
$ git clone other-thing.git
foobar
```

View File

@ -5,5 +5,7 @@
<li>inner par list</li> <li>inner par list</li>
</ul> </ul>
</li> </li>
<li><p>2</p></li> <li>
<p>2</p>
</li>
</ol> </ol>