Skip to content

Commit 2bf7f18

Browse files
Fix: issue#4 produce correct markup char.
1 parent bc91728 commit 2bf7f18

File tree

2 files changed

+117
-31
lines changed

2 files changed

+117
-31
lines changed

src/index.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,6 @@ const createFancyList = (options: MarkdownItFancyListPluginOptions) => {
275275
if (marker.hasOrdinalIndicator === true && options.allowOrdinal !== true) {
276276
return false;
277277
}
278-
const posAfterMarker = marker.bulletChar.length + 2;
279278

280279
// do not allow subsequent numbers to interrupt paragraphs
281280
if (isTerminatingParagraph && marker.start !== 1) {
@@ -285,11 +284,11 @@ const createFancyList = (options: MarkdownItFancyListPluginOptions) => {
285284
// If we're starting a new unordered list right after
286285
// a paragraph, first line should not be empty.
287286
if (isTerminatingParagraph) {
288-
if (state.skipSpaces(posAfterMarker) >= state.eMarks[startLine]) return false;
287+
if (state.skipSpaces(marker.posAfterMarker) >= state.eMarks[startLine]) return false;
289288
}
290289

291290
// We should terminate list on style change. Remember first one to compare.
292-
const markerCharCode = state.src.charCodeAt(posAfterMarker - 1);
291+
const markerCharCode = state.src.charCodeAt(marker.posAfterMarker - 1);
293292

294293
// For validation mode we can terminate immediately
295294
if (silent) { return true; }

test/index.ts

+115-28
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import * as MarkdownIt from "markdown-it";
2+
import * as Token from "markdown-it/lib/token";
23
import { markdownItFancyListPlugin, MarkdownItFancyListPluginOptions } from "../src/index";
34
import { assert } from "chai";
45
import { HtmlDiffer } from "@markedjs/html-differ";
56

67

7-
const assertMarkdownIsConvertedTo = async (expectedHtml: string, markdown: string, pluginOptions?: MarkdownItFancyListPluginOptions) => {
8+
const assertHTML = async (expectedHtml: string, markdown: string, pluginOptions?: MarkdownItFancyListPluginOptions) => {
89
const markdownConverter = new MarkdownIt("default", {
910
"typographer": true,
1011
});
@@ -16,6 +17,22 @@ const assertMarkdownIsConvertedTo = async (expectedHtml: string, markdown: strin
1617
assert.isTrue(isEqual, `Expected:\n${expectedHtml}\n\nActual:\n${actualOutput}`);
1718
};
1819

20+
const assertTokens = (expectedTokens: Partial<Token>[], markdown: string, pluginOptions?: MarkdownItFancyListPluginOptions) => {
21+
const markdownConverter = new MarkdownIt("default", {
22+
"typographer": true,
23+
});
24+
markdownConverter.use(markdownItFancyListPlugin, pluginOptions);
25+
const actualTokens = markdownConverter.parse(markdown, {});
26+
27+
assert.strictEqual(actualTokens.length, expectedTokens.length);
28+
expectedTokens.map((expectedToken, i) => {
29+
const keys = Object.keys(expectedToken);
30+
keys.map((key) => {
31+
assert.strictEqual(actualTokens[i][key], expectedToken[key], `Expected ${key} at token ${i}`);
32+
});
33+
});
34+
};
35+
1936

2037

2138
describe("markdownFancyLists", () => {
@@ -34,7 +51,7 @@ describe("markdownFancyLists", () => {
3451
<li>baz</li>
3552
</ol>
3653
`;
37-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
54+
await assertHTML(expectedHtml, markdown);
3855
});
3956

4057
it("supports lowercase alphabetical numbering", async () => {
@@ -50,7 +67,7 @@ c. baz
5067
<li>baz</li>
5168
</ol>
5269
`;
53-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
70+
await assertHTML(expectedHtml, markdown);
5471
});
5572

5673
it("supports offsets for lowercase alphabetical numbering", async () => {
@@ -66,7 +83,7 @@ d. baz
6683
<li>baz</li>
6784
</ol>
6885
`;
69-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
86+
await assertHTML(expectedHtml, markdown);
7087
});
7188

7289
it("supports uppercase alphabetical numbering", async () => {
@@ -82,7 +99,7 @@ C) baz
8299
<li>baz</li>
83100
</ol>
84101
`;
85-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
102+
await assertHTML(expectedHtml, markdown);
86103
});
87104

88105
it("supports offsets for uppercase alphabetical numbering", async () => {
@@ -98,7 +115,7 @@ D) baz
98115
<li>baz</li>
99116
</ol>
100117
`;
101-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
118+
await assertHTML(expectedHtml, markdown);
102119
});
103120

104121
it("test supports lowercase roman numbering", async () => {
@@ -114,7 +131,7 @@ iii. baz
114131
<li>baz</li>
115132
</ol>
116133
`;
117-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
134+
await assertHTML(expectedHtml, markdown);
118135
});
119136

120137
it("supports offsets for lowercase roman numbering", async () => {
@@ -130,7 +147,7 @@ vi. baz
130147
<li>baz</li>
131148
</ol>
132149
`;
133-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
150+
await assertHTML(expectedHtml, markdown);
134151
});
135152

136153
it("supports uppercase roman numbering", async () => {
@@ -146,7 +163,7 @@ III) baz
146163
<li>baz</li>
147164
</ol>
148165
`;
149-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
166+
await assertHTML(expectedHtml, markdown);
150167
});
151168

152169
it("supports offsets for uppercase roman numbering", async () => {
@@ -162,7 +179,7 @@ XIV. baz
162179
<li>baz</li>
163180
</ol>
164181
`;
165-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
182+
await assertHTML(expectedHtml, markdown);
166183
});
167184

168185
it("ignores invalid roman numerals as list marker", async () => {
@@ -176,7 +193,7 @@ VVII. baz
176193
VVI. bar
177194
VVII. baz</p>
178195
`;
179-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
196+
await assertHTML(expectedHtml, markdown);
180197
});
181198

182199
it("supports hash as list marker for subsequent items", async () => {
@@ -192,7 +209,7 @@ VVII. baz</p>
192209
<li>baz</li>
193210
</ol>
194211
`;
195-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
212+
await assertHTML(expectedHtml, markdown);
196213
});
197214

198215
it("supports hash as list marker for subsequent roman numeric marker", async () => {
@@ -208,7 +225,7 @@ i. foo
208225
<li>baz</li>
209226
</ol>
210227
`;
211-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
228+
await assertHTML(expectedHtml, markdown);
212229
});
213230

214231
it("supports hash as list marker for subsequent alphanumeric marker", async () => {
@@ -224,7 +241,7 @@ a. foo
224241
<li>baz</li>
225242
</ol>
226243
`;
227-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
244+
await assertHTML(expectedHtml, markdown);
228245
});
229246

230247
it("supports hash as list marker for initial item", async () => {
@@ -240,7 +257,7 @@ a. foo
240257
<li>baz</li>
241258
</ol>
242259
`;
243-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
260+
await assertHTML(expectedHtml, markdown);
244261
});
245262

246263
it("allows first numbers to interrupt paragraphs", async () => {
@@ -269,7 +286,7 @@ iii. a plane ticket
269286
<li>a plane ticket</li>
270287
</ol>
271288
`;
272-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
289+
await assertHTML(expectedHtml, markdown);
273290
});
274291

275292
it("does not allow subsequent numbers to interrupt paragraphs", async () => {
@@ -294,7 +311,7 @@ ii. new shoes
294311
iii. a coat
295312
iv. a plane ticket</p>
296313
`;
297-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
314+
await assertHTML(expectedHtml, markdown);
298315
});
299316

300317
it("supports nested lists", async () => {
@@ -319,7 +336,7 @@ iv. a plane ticket</p>
319336
</li>
320337
</ol>
321338
`;
322-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
339+
await assertHTML(expectedHtml, markdown);
323340
});
324341

325342
it("starts a new list when a different type of numbering is used", async () => {
@@ -341,7 +358,7 @@ ii) Second
341358
<li>Second</li>
342359
</ol>
343360
`;
344-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
361+
await assertHTML(expectedHtml, markdown);
345362
});
346363

347364
it("starts a new list when a sequence of letters is not a valid roman numeral", async () => {
@@ -357,7 +374,7 @@ A) First again
357374
<li>First again</li>
358375
</ol>
359376
`;
360-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
377+
await assertHTML(expectedHtml, markdown);
361378
});
362379

363380
it("marker is considered to be alphabetical when part of an alphabetical list", async () => {
@@ -386,7 +403,7 @@ ii) First of new list
386403
<li>First of new list</li>
387404
</ol>
388405
`;
389-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
406+
await assertHTML(expectedHtml, markdown);
390407
});
391408

392409
it("single letter roman numerals other than I are considered alphabetical without context", async () => {
@@ -423,7 +440,7 @@ M) foo
423440
<li>foo</li>
424441
</ol>
425442
`;
426-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
443+
await assertHTML(expectedHtml, markdown);
427444
});
428445

429446
it("requires two spaces after a capital letter and a period", async () => {
@@ -450,7 +467,7 @@ C. bar
450467
<li>bar</li>
451468
</ol>
452469
`;
453-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
470+
await assertHTML(expectedHtml, markdown);
454471
});
455472

456473
describe("support for ordinal indicator", () => {
@@ -465,7 +482,7 @@ C. bar
465482
2&#xBA;. bar
466483
3&#xBA;. baz</p>
467484
`;
468-
await assertMarkdownIsConvertedTo(expectedHtml, markdown);
485+
await assertHTML(expectedHtml, markdown);
469486
});
470487

471488
it("supports an ordinal indicator if enabled in options", async () => {
@@ -481,7 +498,7 @@ C. bar
481498
<li>baz</li>
482499
</ol>
483500
`;
484-
await assertMarkdownIsConvertedTo(expectedHtml, markdown, {
501+
await assertHTML(expectedHtml, markdown, {
485502
allowOrdinal: true,
486503
});
487504
});
@@ -499,7 +516,7 @@ IVº. baz
499516
<li>baz</li>
500517
</ol>
501518
`;
502-
await assertMarkdownIsConvertedTo(expectedHtml, markdown, {
519+
await assertHTML(expectedHtml, markdown, {
503520
allowOrdinal: true,
504521
});
505522
});
@@ -523,7 +540,7 @@ IVº. baz
523540
<li>Another first</li>
524541
</ol>
525542
`;
526-
await assertMarkdownIsConvertedTo(expectedHtml, markdown, {
543+
await assertHTML(expectedHtml, markdown, {
527544
allowOrdinal: true,
528545
});
529546
});
@@ -543,7 +560,77 @@ IVº. baz
543560
<li>ordinal indicator</li>
544561
</ol>
545562
`;
546-
await assertMarkdownIsConvertedTo(expectedHtml, markdown, {
563+
await assertHTML(expectedHtml, markdown, {
564+
allowOrdinal: true,
565+
});
566+
});
567+
568+
it("produces correct markup character regression for issue#4", () => {
569+
const markdown = `
570+
### title
571+
572+
a. first item
573+
#. second item
574+
575+
1) first item
576+
2) second item
577+
578+
1°. degree sign
579+
2˚. ring above
580+
3ᵒ. modifier letter small o
581+
4º. ordinal indicator
582+
`;
583+
assertTokens([
584+
{ type: "heading_open" },
585+
{ type: "inline", content: "title" },
586+
{ type: "heading_close" },
587+
{ type: "ordered_list_open" },
588+
{ type: "list_item_open", markup: "." },
589+
{ type: "paragraph_open" },
590+
{ type: "inline", content: "first item" },
591+
{ type: "paragraph_close" },
592+
{ type: "list_item_close" },
593+
{ type: "list_item_open", markup: "." },
594+
{ type: "paragraph_open" },
595+
{ type: "inline", content: "second item" },
596+
{ type: "paragraph_close" },
597+
{ type: "list_item_close" },
598+
{ type: "ordered_list_close" },
599+
{ type: "ordered_list_open" },
600+
{ type: "list_item_open", markup: ")" },
601+
{ type: "paragraph_open" },
602+
{ type: "inline", content: "first item" },
603+
{ type: "paragraph_close" },
604+
{ type: "list_item_close" },
605+
{ type: "list_item_open", markup: ")" },
606+
{ type: "paragraph_open" },
607+
{ type: "inline", content: "second item" },
608+
{ type: "paragraph_close" },
609+
{ type: "list_item_close" },
610+
{ type: "ordered_list_close" },
611+
{ type: "ordered_list_open" },
612+
{ type: "list_item_open", markup: "." },
613+
{ type: "paragraph_open" },
614+
{ type: "inline", content: "degree sign" },
615+
{ type: "paragraph_close" },
616+
{ type: "list_item_close" },
617+
{ type: "list_item_open", markup: "." },
618+
{ type: "paragraph_open" },
619+
{ type: "inline", content: "ring above" },
620+
{ type: "paragraph_close" },
621+
{ type: "list_item_close" },
622+
{ type: "list_item_open", markup: "." },
623+
{ type: "paragraph_open" },
624+
{ type: "inline", content: "modifier letter small o" },
625+
{ type: "paragraph_close" },
626+
{ type: "list_item_close" },
627+
{ type: "list_item_open", markup: "." },
628+
{ type: "paragraph_open" },
629+
{ type: "inline", content: "ordinal indicator" },
630+
{ type: "paragraph_close" },
631+
{ type: "list_item_close" },
632+
{ type: "ordered_list_close" }
633+
], markdown, {
547634
allowOrdinal: true,
548635
});
549636
});

0 commit comments

Comments
 (0)