2015-01-16 05:21:33 +08:00
|
|
|
/**
|
|
|
|
* Form HTML ordered (numbered) and unordered (bulleted) lists.
|
|
|
|
*/
|
|
|
|
showdown.subParser('lists', function (text, options, globals) {
|
2015-01-19 19:37:21 +08:00
|
|
|
'use strict';
|
|
|
|
|
2016-03-21 01:08:44 +08:00
|
|
|
text = globals.converter._dispatch('lists.before', text, options, globals);
|
2015-01-19 19:37:21 +08:00
|
|
|
/**
|
|
|
|
* Process the contents of a single ordered or unordered list, splitting it
|
|
|
|
* into individual list items.
|
2015-01-19 22:57:43 +08:00
|
|
|
* @param {string} listStr
|
2015-08-23 09:46:04 +08:00
|
|
|
* @param {boolean} trimTrailing
|
2015-06-13 21:59:14 +08:00
|
|
|
* @returns {string}
|
2015-01-19 19:37:21 +08:00
|
|
|
*/
|
2015-08-02 04:05:28 +08:00
|
|
|
function processListItems (listStr, trimTrailing) {
|
2015-01-19 19:37:21 +08:00
|
|
|
// 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,
|
|
|
|
// we decrement. If it's zero, we're not in a list anymore.
|
|
|
|
//
|
|
|
|
// We do this because when we're not inside a list, we want to treat
|
|
|
|
// something like this:
|
|
|
|
//
|
|
|
|
// I recommend upgrading to version
|
|
|
|
// 8. Oops, now this line is treated
|
|
|
|
// as a sub-list.
|
|
|
|
//
|
|
|
|
// As a single paragraph, despite the fact that the second line starts
|
|
|
|
// with a digit-period-space sequence.
|
|
|
|
//
|
|
|
|
// Whereas when we're inside a list (or sub-list), that line will be
|
|
|
|
// treated as the start of a sub-list. What a kludge, huh? This is
|
|
|
|
// an aspect of Markdown's syntax that's hard to parse perfectly
|
|
|
|
// without resorting to mind-reading. Perhaps the solution is to
|
|
|
|
// change the syntax rules such that sub-lists must start with a
|
|
|
|
// starting cardinal number; e.g. "1." or "a.".
|
|
|
|
globals.gListLevel++;
|
|
|
|
|
|
|
|
// trim trailing blank lines:
|
|
|
|
listStr = listStr.replace(/\n{2,}$/, '\n');
|
|
|
|
|
|
|
|
// attacklab: add sentinel to emulate \z
|
|
|
|
listStr += '~0';
|
2015-01-16 05:21:33 +08:00
|
|
|
|
fix(lists): enforce 4 space indentation in sublists
Acording to the spec, multi paragraph (or block) list item requires subblocks
to be indented 4 spaces (or 1 tab). Although, this is mentioned in the documentation,
Showdown didn't enforce this rule in sublists because other implementations,
such as GFM also didn't. However, in some edge cases, this led to inconsistent behavior,
as shown in issue #299. This commit makes 4 space indentation in sublists
mandatory.
BREAKING CHANGE: syntax for sublists is more restrictive. Before, sublists SHOULD be
indented by 4 spaces, but indenting 2 spaces would work. Now, sublists MUST be
indented 4 spaces or they won't work.
With this input:
```md
* one
* two
* three
```
Before (ouput):
```html
<ul>
<li>one
<ul>
<li>two
<ul><li>three</li></ul>
<li>
</ul>
</li>
<ul>
```
After (output):
```html
<ul>
<li>one</li>
<li>two
<ul><li>three</li></ul>
</li>
</ul>
```
To migrate either fix source md files or activate the option `disableForced4SpacesIndentedSublists` (coming in v1.5.0):
```md
showdown.setOption('disableForced4SpacesIndentedSublists', true);
```
2016-11-11 15:56:29 +08:00
|
|
|
var rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(~0| {0,3}([*+-]|\d+[.])[ \t]+))/gm,
|
2015-08-02 04:05:28 +08:00
|
|
|
isParagraphed = (/\n[ \t]*\n(?!~0)/.test(listStr));
|
2015-07-12 06:02:02 +08:00
|
|
|
|
2016-11-11 16:15:24 +08:00
|
|
|
// Since version 1.5, nesting sublists requires 4 spaces (or 1 tab) indentation,
|
|
|
|
// which is a syntax breaking change
|
|
|
|
// activating this option reverts to old behavior
|
|
|
|
if (options.disableForced4SpacesIndentedSublists) {
|
|
|
|
rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm;
|
|
|
|
}
|
|
|
|
|
2015-07-12 06:02:02 +08:00
|
|
|
listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) {
|
|
|
|
checked = (checked && checked.trim() !== '');
|
fix(lists): enforce 4 space indentation in sublists
Acording to the spec, multi paragraph (or block) list item requires subblocks
to be indented 4 spaces (or 1 tab). Although, this is mentioned in the documentation,
Showdown didn't enforce this rule in sublists because other implementations,
such as GFM also didn't. However, in some edge cases, this led to inconsistent behavior,
as shown in issue #299. This commit makes 4 space indentation in sublists
mandatory.
BREAKING CHANGE: syntax for sublists is more restrictive. Before, sublists SHOULD be
indented by 4 spaces, but indenting 2 spaces would work. Now, sublists MUST be
indented 4 spaces or they won't work.
With this input:
```md
* one
* two
* three
```
Before (ouput):
```html
<ul>
<li>one
<ul>
<li>two
<ul><li>three</li></ul>
<li>
</ul>
</li>
<ul>
```
After (output):
```html
<ul>
<li>one</li>
<li>two
<ul><li>three</li></ul>
</li>
</ul>
```
To migrate either fix source md files or activate the option `disableForced4SpacesIndentedSublists` (coming in v1.5.0):
```md
showdown.setOption('disableForced4SpacesIndentedSublists', true);
```
2016-11-11 15:56:29 +08:00
|
|
|
|
2015-08-02 04:05:28 +08:00
|
|
|
var item = showdown.subParser('outdent')(m4, options, globals),
|
|
|
|
bulletStyle = '';
|
2015-07-12 06:02:02 +08:00
|
|
|
|
2015-08-02 04:05:28 +08:00
|
|
|
// Support for github tasklists
|
|
|
|
if (taskbtn && options.tasklists) {
|
|
|
|
bulletStyle = ' class="task-list-item" style="list-style-type: none;"';
|
2016-04-26 22:08:50 +08:00
|
|
|
item = item.replace(/^[ \t]*\[(x|X| )?]/m, function () {
|
2015-08-02 04:05:28 +08:00
|
|
|
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;
|
|
|
|
});
|
|
|
|
}
|
fix(lists): enforce 4 space indentation in sublists
Acording to the spec, multi paragraph (or block) list item requires subblocks
to be indented 4 spaces (or 1 tab). Although, this is mentioned in the documentation,
Showdown didn't enforce this rule in sublists because other implementations,
such as GFM also didn't. However, in some edge cases, this led to inconsistent behavior,
as shown in issue #299. This commit makes 4 space indentation in sublists
mandatory.
BREAKING CHANGE: syntax for sublists is more restrictive. Before, sublists SHOULD be
indented by 4 spaces, but indenting 2 spaces would work. Now, sublists MUST be
indented 4 spaces or they won't work.
With this input:
```md
* one
* two
* three
```
Before (ouput):
```html
<ul>
<li>one
<ul>
<li>two
<ul><li>three</li></ul>
<li>
</ul>
</li>
<ul>
```
After (output):
```html
<ul>
<li>one</li>
<li>two
<ul><li>three</li></ul>
</li>
</ul>
```
To migrate either fix source md files or activate the option `disableForced4SpacesIndentedSublists` (coming in v1.5.0):
```md
showdown.setOption('disableForced4SpacesIndentedSublists', true);
```
2016-11-11 15:56:29 +08:00
|
|
|
|
2015-08-02 04:05:28 +08:00
|
|
|
// m1 - Leading line or
|
|
|
|
// Has a double return (multi paragraph) or
|
|
|
|
// Has sublist
|
2015-06-13 21:59:14 +08:00
|
|
|
if (m1 || (item.search(/\n{2,}/) > -1)) {
|
2015-08-02 04:05:28 +08:00
|
|
|
item = showdown.subParser('githubCodeBlocks')(item, options, globals);
|
2015-06-13 21:59:14 +08:00
|
|
|
item = showdown.subParser('blockGamut')(item, options, globals);
|
|
|
|
} else {
|
|
|
|
// Recursion for sub-lists:
|
|
|
|
item = showdown.subParser('lists')(item, options, globals);
|
|
|
|
item = item.replace(/\n$/, ''); // chomp(item)
|
2015-08-02 04:05:28 +08:00
|
|
|
if (isParagraphed) {
|
|
|
|
item = showdown.subParser('paragraphs')(item, options, globals);
|
|
|
|
} else {
|
|
|
|
item = showdown.subParser('spanGamut')(item, options, globals);
|
|
|
|
}
|
2015-07-12 06:02:02 +08:00
|
|
|
}
|
2016-09-29 08:12:27 +08:00
|
|
|
item = '<li' + bulletStyle + '>' + item + '</li>\n';
|
2015-08-02 04:05:28 +08:00
|
|
|
return item;
|
2015-06-13 21:59:14 +08:00
|
|
|
});
|
2015-01-16 05:21:33 +08:00
|
|
|
|
|
|
|
// attacklab: strip sentinel
|
2015-01-19 19:37:21 +08:00
|
|
|
listStr = listStr.replace(/~0/g, '');
|
|
|
|
|
|
|
|
globals.gListLevel--;
|
2015-08-02 04:05:28 +08:00
|
|
|
|
|
|
|
if (trimTrailing) {
|
|
|
|
listStr = listStr.replace(/\s+$/, '');
|
|
|
|
}
|
|
|
|
|
2015-01-19 19:37:21 +08:00
|
|
|
return listStr;
|
2015-06-13 21:59:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-08-02 04:05:28 +08:00
|
|
|
* Check and parse consecutive lists (better fix for issue #142)
|
|
|
|
* @param {string} list
|
2015-06-13 21:59:14 +08:00
|
|
|
* @param {string} listType
|
2015-08-23 09:46:04 +08:00
|
|
|
* @param {boolean} trimTrailing
|
2015-08-02 04:05:28 +08:00
|
|
|
* @returns {string}
|
2015-06-13 21:59:14 +08:00
|
|
|
*/
|
2015-08-02 04:05:28 +08:00
|
|
|
function parseConsecutiveLists(list, listType, trimTrailing) {
|
|
|
|
// check if we caught 2 or more consecutive lists by mistake
|
2016-11-09 10:54:18 +08:00
|
|
|
// we use the counterRgx, meaning if listType is UL we look for OL and vice versa
|
2016-11-11 16:15:24 +08:00
|
|
|
var olRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?\d+\.[ \t]/gm : /^ {0,3}\d+\.[ \t]/gm,
|
|
|
|
ulRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?[*+-][ \t]/gm : /^ {0,3}[*+-][ \t]/gm,
|
fix(lists): enforce 4 space indentation in sublists
Acording to the spec, multi paragraph (or block) list item requires subblocks
to be indented 4 spaces (or 1 tab). Although, this is mentioned in the documentation,
Showdown didn't enforce this rule in sublists because other implementations,
such as GFM also didn't. However, in some edge cases, this led to inconsistent behavior,
as shown in issue #299. This commit makes 4 space indentation in sublists
mandatory.
BREAKING CHANGE: syntax for sublists is more restrictive. Before, sublists SHOULD be
indented by 4 spaces, but indenting 2 spaces would work. Now, sublists MUST be
indented 4 spaces or they won't work.
With this input:
```md
* one
* two
* three
```
Before (ouput):
```html
<ul>
<li>one
<ul>
<li>two
<ul><li>three</li></ul>
<li>
</ul>
</li>
<ul>
```
After (output):
```html
<ul>
<li>one</li>
<li>two
<ul><li>three</li></ul>
</li>
</ul>
```
To migrate either fix source md files or activate the option `disableForced4SpacesIndentedSublists` (coming in v1.5.0):
```md
showdown.setOption('disableForced4SpacesIndentedSublists', true);
```
2016-11-11 15:56:29 +08:00
|
|
|
counterRxg = (listType === 'ul') ? olRgx : ulRgx,
|
|
|
|
result = '';
|
2015-08-02 04:05:28 +08:00
|
|
|
|
|
|
|
if (list.search(counterRxg) !== -1) {
|
|
|
|
(function parseCL(txt) {
|
|
|
|
var pos = txt.search(counterRxg);
|
|
|
|
if (pos !== -1) {
|
|
|
|
// slice
|
2016-09-29 08:12:27 +08:00
|
|
|
result += '\n<' + listType + '>\n' + processListItems(txt.slice(0, pos), !!trimTrailing) + '</' + listType + '>\n';
|
2015-08-02 04:05:28 +08:00
|
|
|
|
|
|
|
// invert counterType and listType
|
|
|
|
listType = (listType === 'ul') ? 'ol' : 'ul';
|
fix(lists): enforce 4 space indentation in sublists
Acording to the spec, multi paragraph (or block) list item requires subblocks
to be indented 4 spaces (or 1 tab). Although, this is mentioned in the documentation,
Showdown didn't enforce this rule in sublists because other implementations,
such as GFM also didn't. However, in some edge cases, this led to inconsistent behavior,
as shown in issue #299. This commit makes 4 space indentation in sublists
mandatory.
BREAKING CHANGE: syntax for sublists is more restrictive. Before, sublists SHOULD be
indented by 4 spaces, but indenting 2 spaces would work. Now, sublists MUST be
indented 4 spaces or they won't work.
With this input:
```md
* one
* two
* three
```
Before (ouput):
```html
<ul>
<li>one
<ul>
<li>two
<ul><li>three</li></ul>
<li>
</ul>
</li>
<ul>
```
After (output):
```html
<ul>
<li>one</li>
<li>two
<ul><li>three</li></ul>
</li>
</ul>
```
To migrate either fix source md files or activate the option `disableForced4SpacesIndentedSublists` (coming in v1.5.0):
```md
showdown.setOption('disableForced4SpacesIndentedSublists', true);
```
2016-11-11 15:56:29 +08:00
|
|
|
counterRxg = (listType === 'ul') ? olRgx : ulRgx;
|
2015-08-02 04:05:28 +08:00
|
|
|
|
|
|
|
//recurse
|
|
|
|
parseCL(txt.slice(pos));
|
|
|
|
} else {
|
2016-09-29 08:12:27 +08:00
|
|
|
result += '\n<' + listType + '>\n' + processListItems(txt, !!trimTrailing) + '</' + listType + '>\n';
|
2015-06-13 21:59:14 +08:00
|
|
|
}
|
2015-08-02 04:05:28 +08:00
|
|
|
})(list);
|
|
|
|
} else {
|
2016-09-29 08:12:27 +08:00
|
|
|
result = '\n<' + listType + '>\n' + processListItems(list, !!trimTrailing) + '</' + listType + '>\n';
|
2015-06-13 21:59:14 +08:00
|
|
|
}
|
2015-08-02 04:05:28 +08:00
|
|
|
|
|
|
|
return result;
|
2015-06-13 21:59:14 +08:00
|
|
|
}
|
2015-01-19 19:37:21 +08:00
|
|
|
|
2016-08-30 13:24:19 +08:00
|
|
|
// add sentinel to hack around khtml/safari bug:
|
2015-01-19 19:37:21 +08:00
|
|
|
// http://bugs.webkit.org/show_bug.cgi?id=11231
|
|
|
|
text += '~0';
|
|
|
|
|
|
|
|
if (globals.gListLevel) {
|
fix(lists): enforce 4 space indentation in sublists
Acording to the spec, multi paragraph (or block) list item requires subblocks
to be indented 4 spaces (or 1 tab). Although, this is mentioned in the documentation,
Showdown didn't enforce this rule in sublists because other implementations,
such as GFM also didn't. However, in some edge cases, this led to inconsistent behavior,
as shown in issue #299. This commit makes 4 space indentation in sublists
mandatory.
BREAKING CHANGE: syntax for sublists is more restrictive. Before, sublists SHOULD be
indented by 4 spaces, but indenting 2 spaces would work. Now, sublists MUST be
indented 4 spaces or they won't work.
With this input:
```md
* one
* two
* three
```
Before (ouput):
```html
<ul>
<li>one
<ul>
<li>two
<ul><li>three</li></ul>
<li>
</ul>
</li>
<ul>
```
After (output):
```html
<ul>
<li>one</li>
<li>two
<ul><li>three</li></ul>
</li>
</ul>
```
To migrate either fix source md files or activate the option `disableForced4SpacesIndentedSublists` (coming in v1.5.0):
```md
showdown.setOption('disableForced4SpacesIndentedSublists', true);
```
2016-11-11 15:56:29 +08:00
|
|
|
text = text.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,
|
|
|
|
function (wholeMatch, list, m2) {
|
|
|
|
var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol';
|
|
|
|
return parseConsecutiveLists(list, listType, true);
|
|
|
|
}
|
|
|
|
);
|
2015-01-19 19:37:21 +08:00
|
|
|
} else {
|
fix(lists): enforce 4 space indentation in sublists
Acording to the spec, multi paragraph (or block) list item requires subblocks
to be indented 4 spaces (or 1 tab). Although, this is mentioned in the documentation,
Showdown didn't enforce this rule in sublists because other implementations,
such as GFM also didn't. However, in some edge cases, this led to inconsistent behavior,
as shown in issue #299. This commit makes 4 space indentation in sublists
mandatory.
BREAKING CHANGE: syntax for sublists is more restrictive. Before, sublists SHOULD be
indented by 4 spaces, but indenting 2 spaces would work. Now, sublists MUST be
indented 4 spaces or they won't work.
With this input:
```md
* one
* two
* three
```
Before (ouput):
```html
<ul>
<li>one
<ul>
<li>two
<ul><li>three</li></ul>
<li>
</ul>
</li>
<ul>
```
After (output):
```html
<ul>
<li>one</li>
<li>two
<ul><li>three</li></ul>
</li>
</ul>
```
To migrate either fix source md files or activate the option `disableForced4SpacesIndentedSublists` (coming in v1.5.0):
```md
showdown.setOption('disableForced4SpacesIndentedSublists', true);
```
2016-11-11 15:56:29 +08:00
|
|
|
text = text.replace(/(\n\n|^\n?)(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,
|
|
|
|
function (wholeMatch, m1, list, m3) {
|
|
|
|
var listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol';
|
|
|
|
return parseConsecutiveLists(list, listType, false);
|
|
|
|
}
|
|
|
|
);
|
2015-01-19 19:37:21 +08:00
|
|
|
}
|
|
|
|
|
2016-08-30 13:24:19 +08:00
|
|
|
// strip sentinel
|
2015-01-19 19:37:21 +08:00
|
|
|
text = text.replace(/~0/, '');
|
|
|
|
|
2016-03-21 01:08:44 +08:00
|
|
|
text = globals.converter._dispatch('lists.after', text, options, globals);
|
2015-01-19 19:37:21 +08:00
|
|
|
return text;
|
2015-01-16 05:21:33 +08:00
|
|
|
});
|