diff --git a/lib/rules_block/list.js b/lib/rules_block/list.js index f6d7c8d..6b164d5 100644 --- a/lib/rules_block/list.js +++ b/lib/rules_block/list.js @@ -161,7 +161,7 @@ module.exports = function list(state, startLine, endLine, silent) { if ((posAfterMarker = skipOrderedListMarker(state, startLine)) >= 0) { isOrdered = true; start = state.bMarks[startLine] + state.tShift[startLine]; - markerValue = Number(state.src.substr(start, posAfterMarker - start - 1)); + 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. @@ -254,6 +254,9 @@ module.exports = function list(state, startLine, endLine, silent) { token = state.push('list_item_open', 'li', 1); token.markup = String.fromCharCode(markerCharCode); token.map = itemLines = [ startLine, 0 ]; + if (isOrdered) { + token.info = state.src.slice(start, posAfterMarker - 1); + } // change current state, then restore it after parser subcall oldTight = state.tight; @@ -330,6 +333,7 @@ module.exports = function list(state, startLine, endLine, silent) { if (isOrdered) { posAfterMarker = skipOrderedListMarker(state, nextLine); if (posAfterMarker < 0) { break; } + start = state.bMarks[nextLine] + state.tShift[nextLine]; } else { posAfterMarker = skipBulletListMarker(state, nextLine); if (posAfterMarker < 0) { break; } diff --git a/lib/token.js b/lib/token.js index 69bc277..c5fd271 100644 --- a/lib/token.js +++ b/lib/token.js @@ -88,6 +88,7 @@ function Token(type, tag, nesting) { * * - Info string for "fence" tokens * - The value "auto" for autolink "link_open" and "link_close" tokens + * - The string value of the item marker for ordered-list "list_item_open" tokens **/ this.info = ''; diff --git a/test/misc.js b/test/misc.js index 2f8712e..6850a16 100644 --- a/test/misc.js +++ b/test/misc.js @@ -362,6 +362,41 @@ describe('smartquotes', function () { }); +describe('Ordered list info', function () { + var md = markdownit(); + + function type_filter(tokens, type) { + return tokens.filter(function (t) { return t.type === type; }); + } + + it('Should mark ordered list item tokens with info', function () { + var tokens = md.parse('1. Foo\n2. Bar\n20. Fuzz'); + assert.strictEqual(type_filter(tokens, 'ordered_list_open').length, 1); + tokens = type_filter(tokens, 'list_item_open'); + assert.strictEqual(tokens.length, 3); + assert.strictEqual(tokens[0].info, '1'); + assert.strictEqual(tokens[0].markup, '.'); + assert.strictEqual(tokens[1].info, '2'); + assert.strictEqual(tokens[1].markup, '.'); + assert.strictEqual(tokens[2].info, '20'); + assert.strictEqual(tokens[2].markup, '.'); + + tokens = md.parse(' 1. Foo\n2. Bar\n 20. Fuzz\n 199. Flp'); + assert.strictEqual(type_filter(tokens, 'ordered_list_open').length, 1); + tokens = type_filter(tokens, 'list_item_open'); + assert.strictEqual(tokens.length, 4); + assert.strictEqual(tokens[0].info, '1'); + assert.strictEqual(tokens[0].markup, '.'); + assert.strictEqual(tokens[1].info, '2'); + assert.strictEqual(tokens[1].markup, '.'); + assert.strictEqual(tokens[2].info, '20'); + assert.strictEqual(tokens[2].markup, '.'); + assert.strictEqual(tokens[3].info, '199'); + assert.strictEqual(tokens[3].markup, '.'); + }); +}); + + describe('Token attributes', function () { it('.attrJoin', function () { var md = markdownit();