@peaceroad/markdown-it-table-ex 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +285 -172
- package/package.json +3 -3
package/index.js
CHANGED
|
@@ -56,6 +56,84 @@ const hasInlineRule = (md, name) => {
|
|
|
56
56
|
return false;
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
+
const createNewlineToken = (Token) => {
|
|
60
|
+
const token = new Token('text', '', 0);
|
|
61
|
+
token.content = '\n';
|
|
62
|
+
return token;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const setInlineText = (inline, Token, text) => {
|
|
66
|
+
inline.content = text;
|
|
67
|
+
const textToken = new Token('text', '', 0);
|
|
68
|
+
textToken.content = text;
|
|
69
|
+
textToken.level = 0;
|
|
70
|
+
inline.children = [textToken];
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const removeHeaderCellAt = (tokens, openIdx) => {
|
|
74
|
+
if (!tokens[openIdx] || tokens[openIdx].type !== 'th_open') return;
|
|
75
|
+
let deleteCount = 3;
|
|
76
|
+
const next = tokens[openIdx + 3];
|
|
77
|
+
if (next && next.type === 'text' && next.content === '\n') {
|
|
78
|
+
deleteCount += 1;
|
|
79
|
+
}
|
|
80
|
+
tokens.splice(openIdx, deleteCount);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const findFirstHeaderThPos = (tokens, tableOpenIdx, allowFallback) => {
|
|
84
|
+
let inThead = false;
|
|
85
|
+
for (let i = tableOpenIdx + 1; i < tokens.length; i++) {
|
|
86
|
+
const type = tokens[i].type;
|
|
87
|
+
if (type === 'table_close') break;
|
|
88
|
+
if (type === 'thead_open') {
|
|
89
|
+
inThead = true;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (!inThead) continue;
|
|
93
|
+
if (type === 'thead_close') break;
|
|
94
|
+
if (type !== 'th_open') continue;
|
|
95
|
+
const inline = tokens[i + 1];
|
|
96
|
+
if (inline && (inline.content === '' || isStrongWrappedInline(inline, allowFallback))) {
|
|
97
|
+
return i;
|
|
98
|
+
}
|
|
99
|
+
return -1;
|
|
100
|
+
}
|
|
101
|
+
return -1;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const findFirstHeaderCellPos = (tokens, tableOpenIdx) => {
|
|
105
|
+
let inThead = false;
|
|
106
|
+
for (let i = tableOpenIdx + 1; i < tokens.length; i++) {
|
|
107
|
+
const type = tokens[i].type;
|
|
108
|
+
if (type === 'table_close') break;
|
|
109
|
+
if (type === 'thead_open') {
|
|
110
|
+
inThead = true;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (!inThead) continue;
|
|
114
|
+
if (type === 'thead_close') break;
|
|
115
|
+
if (type === 'th_open') return i;
|
|
116
|
+
}
|
|
117
|
+
return -1;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const createColgroupRegexes = (colgroupWithNoAsterisk) => {
|
|
121
|
+
if (colgroupWithNoAsterisk) {
|
|
122
|
+
return {
|
|
123
|
+
singleHeaderGroup: /^([^::]+)(?::\s*|: +)/,
|
|
124
|
+
singleHeaderStrip: /^[^::]+(?::\s*|: +)(.*)$/,
|
|
125
|
+
multiHeaderGroup: /^([^::]+)(?::\s*|: +)/,
|
|
126
|
+
multiHeaderStrip: /^[^::]+(?::\s*|: +)(.*)$/
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
singleHeaderGroup: /^\*\*([^*::]+)[::]\*\*\s*/,
|
|
131
|
+
singleHeaderStrip: /^\*\*[^*::]+[::]\*\*\s*(.*)$/,
|
|
132
|
+
multiHeaderGroup: /^\*\*([^*::]+)[::]\*\*/,
|
|
133
|
+
multiHeaderStrip: /^\*\*[^*::]+[::]\*\*\s*(.*)$/
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
|
|
59
137
|
const createTokenTemplate = (tokenType, tag, nesting, level) => ({
|
|
60
138
|
type: tokenType,
|
|
61
139
|
tag: tag,
|
|
@@ -213,24 +291,28 @@ const removeStrongWrappers = (inline, allowFallback) => {
|
|
|
213
291
|
|
|
214
292
|
const addTheadThScope = (state, theadVar, allowFallback) => {
|
|
215
293
|
const tokens = state.tokens;
|
|
216
|
-
let firstThPos = theadVar.
|
|
217
|
-
let j = theadVar.i +
|
|
218
|
-
|
|
294
|
+
let firstThPos = theadVar.firstThPos;
|
|
295
|
+
let j = theadVar.i + 1;
|
|
296
|
+
let isFirstRow = true;
|
|
297
|
+
let firstRowFirstThSeen = false;
|
|
219
298
|
while (j < tokens.length) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
299
|
+
const tokenType = tokens[j].type;
|
|
300
|
+
if (tokenType === 'th_open') {
|
|
301
|
+
tokens[j].attrSet('scope', 'col');
|
|
302
|
+
if (isFirstRow && !firstRowFirstThSeen) {
|
|
303
|
+
firstRowFirstThSeen = true;
|
|
223
304
|
const inline = tokens[j + 1];
|
|
224
|
-
const content = inline.content;
|
|
305
|
+
const content = inline && typeof inline.content === 'string' ? inline.content : '';
|
|
225
306
|
if (content === '' || isStrongWrappedInline(inline, allowFallback)) {
|
|
226
|
-
firstThPos = j
|
|
227
|
-
// Only remove strong tags from the first th content for matrix processing
|
|
228
|
-
// The actual removal will be done in changeTdToTh if matrix conditions are met
|
|
307
|
+
firstThPos = j;
|
|
229
308
|
}
|
|
230
309
|
}
|
|
310
|
+
} else if (tokenType === 'tr_close' && isFirstRow) {
|
|
311
|
+
isFirstRow = false;
|
|
312
|
+
} else if (tokenType === 'thead_close') {
|
|
313
|
+
break;
|
|
231
314
|
}
|
|
232
|
-
|
|
233
|
-
j++
|
|
315
|
+
j++;
|
|
234
316
|
}
|
|
235
317
|
return {i: j, firstThPos: firstThPos}
|
|
236
318
|
}
|
|
@@ -278,7 +360,7 @@ const checkTbody = (state, tbodyVar, allowFallback) => {
|
|
|
278
360
|
return { i: j, isAllFirstTh: isAllFirstTh, tbodyFirstThPoses: tbodyFirstThPoses}
|
|
279
361
|
}
|
|
280
362
|
|
|
281
|
-
const setColgroup = (state, tableOpenIdx, opt, allowFallback) => {
|
|
363
|
+
const setColgroup = (state, tableOpenIdx, opt, allowFallback, regexes) => {
|
|
282
364
|
const tokens = state.tokens;
|
|
283
365
|
const Token = state.Token;
|
|
284
366
|
|
|
@@ -310,12 +392,8 @@ const setColgroup = (state, tableOpenIdx, opt, allowFallback) => {
|
|
|
310
392
|
headerCount: 0
|
|
311
393
|
};
|
|
312
394
|
|
|
313
|
-
const colgroupMatchReg =
|
|
314
|
-
|
|
315
|
-
: /^\*\*([^*::]+)[::]\*\*\s*/;
|
|
316
|
-
const origColgroupMatchReg = opt.colgroupWithNoAsterisk
|
|
317
|
-
? /^[^::]+(?::|:)\s*(.*)$/
|
|
318
|
-
: /^\*\*[^*::]+[::]\*\*\s*(.*)$/;
|
|
395
|
+
const colgroupMatchReg = regexes.singleHeaderGroup;
|
|
396
|
+
const origColgroupMatchReg = regexes.singleHeaderStrip;
|
|
319
397
|
|
|
320
398
|
let thIdx = tr1 + 1;
|
|
321
399
|
const origThInfos = [];
|
|
@@ -375,7 +453,7 @@ const setColgroup = (state, tableOpenIdx, opt, allowFallback) => {
|
|
|
375
453
|
if (hasSpan) {
|
|
376
454
|
const insertTokens = [
|
|
377
455
|
new Token('colgroup_open', 'colgroup', 1),
|
|
378
|
-
|
|
456
|
+
createNewlineToken(Token)
|
|
379
457
|
];
|
|
380
458
|
|
|
381
459
|
for (let i = 0; i < groupData.spans.length; i++) {
|
|
@@ -385,13 +463,13 @@ const setColgroup = (state, tableOpenIdx, opt, allowFallback) => {
|
|
|
385
463
|
}
|
|
386
464
|
insertTokens.push(
|
|
387
465
|
colOpen,
|
|
388
|
-
|
|
466
|
+
createNewlineToken(Token)
|
|
389
467
|
);
|
|
390
468
|
}
|
|
391
469
|
|
|
392
470
|
insertTokens.push(
|
|
393
471
|
new Token('colgroup_close', 'colgroup', -1),
|
|
394
|
-
|
|
472
|
+
createNewlineToken(Token)
|
|
395
473
|
);
|
|
396
474
|
|
|
397
475
|
tokens.splice(tableOpenIdx + 1, 0, ...insertTokens);
|
|
@@ -399,7 +477,6 @@ const setColgroup = (state, tableOpenIdx, opt, allowFallback) => {
|
|
|
399
477
|
// Update indices
|
|
400
478
|
const offset = insertTokens.length;
|
|
401
479
|
tr1 += offset;
|
|
402
|
-
theadClose += offset;
|
|
403
480
|
trCloseIdx += offset;
|
|
404
481
|
}
|
|
405
482
|
|
|
@@ -407,14 +484,14 @@ const setColgroup = (state, tableOpenIdx, opt, allowFallback) => {
|
|
|
407
484
|
|
|
408
485
|
// Create new rows more efficiently
|
|
409
486
|
const newTr1 = [
|
|
410
|
-
|
|
487
|
+
createNewlineToken(Token),
|
|
411
488
|
new Token('tr_open', 'tr', 1),
|
|
412
|
-
|
|
489
|
+
createNewlineToken(Token)
|
|
413
490
|
];
|
|
414
491
|
|
|
415
492
|
const newTr2 = [
|
|
416
493
|
new Token('tr_open', 'tr', 1),
|
|
417
|
-
|
|
494
|
+
createNewlineToken(Token)
|
|
418
495
|
];
|
|
419
496
|
|
|
420
497
|
let thPtr = 0;
|
|
@@ -437,15 +514,14 @@ const setColgroup = (state, tableOpenIdx, opt, allowFallback) => {
|
|
|
437
514
|
thInline.children = Array.isArray(origInline.children) ? origInline.children : [];
|
|
438
515
|
if (cellMap) thInline.map = cellMap;
|
|
439
516
|
} else {
|
|
440
|
-
thInline
|
|
441
|
-
thInline.children = [];
|
|
517
|
+
setInlineText(thInline, Token, '');
|
|
442
518
|
}
|
|
443
519
|
|
|
444
520
|
newTr1.push(
|
|
445
521
|
thOpen,
|
|
446
522
|
thInline,
|
|
447
523
|
new Token('th_close', 'th', -1),
|
|
448
|
-
|
|
524
|
+
createNewlineToken(Token)
|
|
449
525
|
);
|
|
450
526
|
thPtr++;
|
|
451
527
|
} else {
|
|
@@ -458,15 +534,14 @@ const setColgroup = (state, tableOpenIdx, opt, allowFallback) => {
|
|
|
458
534
|
if (cellMap) thOpen.map = cellMap;
|
|
459
535
|
|
|
460
536
|
const thInline = new Token('inline', '', 0);
|
|
461
|
-
thInline
|
|
462
|
-
thInline.children = [{ type: 'text', content: groupNames[i], level: 0 }];
|
|
537
|
+
setInlineText(thInline, Token, groupNames[i]);
|
|
463
538
|
if (cellMap) thInline.map = cellMap;
|
|
464
539
|
|
|
465
540
|
newTr1.push(
|
|
466
541
|
thOpen,
|
|
467
542
|
thInline,
|
|
468
543
|
new Token('th_close', 'th', -1),
|
|
469
|
-
|
|
544
|
+
createNewlineToken(Token)
|
|
470
545
|
);
|
|
471
546
|
|
|
472
547
|
// Second row: each item in the group
|
|
@@ -488,15 +563,14 @@ const setColgroup = (state, tableOpenIdx, opt, allowFallback) => {
|
|
|
488
563
|
} else if (hasLeadingStrongMarker(origInline, allowFallback)) {
|
|
489
564
|
match = orig.match(origColgroupMatchReg);
|
|
490
565
|
}
|
|
491
|
-
th2Inline
|
|
492
|
-
th2Inline.children = [{ type: 'text', content: th2Inline.content, level: 0 }];
|
|
566
|
+
setInlineText(th2Inline, Token, match ? match[1] : orig);
|
|
493
567
|
if (subMap) th2Inline.map = subMap;
|
|
494
568
|
|
|
495
569
|
newTr2.push(
|
|
496
570
|
th2Open,
|
|
497
571
|
th2Inline,
|
|
498
572
|
new Token('th_close', 'th', -1),
|
|
499
|
-
|
|
573
|
+
createNewlineToken(Token)
|
|
500
574
|
);
|
|
501
575
|
thPtr++;
|
|
502
576
|
}
|
|
@@ -505,12 +579,12 @@ const setColgroup = (state, tableOpenIdx, opt, allowFallback) => {
|
|
|
505
579
|
|
|
506
580
|
newTr1.push(
|
|
507
581
|
new Token('tr_close', 'tr', -1),
|
|
508
|
-
|
|
582
|
+
createNewlineToken(Token)
|
|
509
583
|
);
|
|
510
584
|
|
|
511
585
|
newTr2.push(
|
|
512
586
|
new Token('tr_close', 'tr', -1),
|
|
513
|
-
|
|
587
|
+
createNewlineToken(Token)
|
|
514
588
|
);
|
|
515
589
|
|
|
516
590
|
// Clean up newlines before insertion
|
|
@@ -525,40 +599,6 @@ const setColgroup = (state, tableOpenIdx, opt, allowFallback) => {
|
|
|
525
599
|
|
|
526
600
|
tokens.splice(tr1, trCloseIdx - tr1 + 1, ...newTr1, ...newTr2);
|
|
527
601
|
|
|
528
|
-
// Handle tbody th conversion
|
|
529
|
-
let tbodyOpen = -1, tbodyClose = -1;
|
|
530
|
-
for (let i = theadClose + 1; i < tokens.length; i++) {
|
|
531
|
-
if (tokens[i].type === 'tbody_open') {
|
|
532
|
-
tbodyOpen = i;
|
|
533
|
-
} else if (tbodyOpen >= 0 && tokens[i].type === 'tbody_close') {
|
|
534
|
-
tbodyClose = i;
|
|
535
|
-
break;
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
if (tbodyOpen >= 0 && tbodyClose > tbodyOpen) {
|
|
540
|
-
let j = tbodyOpen + 1;
|
|
541
|
-
while (j < tbodyClose) {
|
|
542
|
-
if (tokens[j].type === 'tr_open') {
|
|
543
|
-
const tdIdx = j + 1;
|
|
544
|
-
if (tokens[tdIdx].type === 'td_open') {
|
|
545
|
-
const inline = tokens[tdIdx + 1];
|
|
546
|
-
if (inline && typeof inline.content === 'string' &&
|
|
547
|
-
isStrongWrappedInline(inline, allowFallback)) {
|
|
548
|
-
tokens[tdIdx].type = 'th_open';
|
|
549
|
-
tokens[tdIdx].tag = 'th';
|
|
550
|
-
tokens[tdIdx].attrSet('scope', 'row');
|
|
551
|
-
removeStrongWrappers(inline, allowFallback);
|
|
552
|
-
if (tokens[tdIdx + 2].type === 'td_close') {
|
|
553
|
-
tokens[tdIdx + 2].type = 'th_close';
|
|
554
|
-
tokens[tdIdx + 2].tag = 'th';
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
j++;
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
602
|
return;
|
|
563
603
|
}
|
|
564
604
|
|
|
@@ -567,116 +607,169 @@ const setColgroup = (state, tableOpenIdx, opt, allowFallback) => {
|
|
|
567
607
|
// Calculate group names and colspan for multi-row case
|
|
568
608
|
const groupData = {
|
|
569
609
|
spans: [],
|
|
570
|
-
rawNames: []
|
|
610
|
+
rawNames: [],
|
|
611
|
+
headerCount: 0
|
|
571
612
|
};
|
|
572
|
-
const groupMatchReg =
|
|
613
|
+
const groupMatchReg = regexes.multiHeaderGroup;
|
|
614
|
+
const groupStripReg = regexes.multiHeaderStrip;
|
|
573
615
|
|
|
616
|
+
const firstRowCells = [];
|
|
617
|
+
let firstRowClose = -1;
|
|
574
618
|
let thIdx = tr1 + 1;
|
|
575
|
-
while (thIdx < tokens.length
|
|
619
|
+
while (thIdx < tokens.length) {
|
|
620
|
+
if (tokens[thIdx].type === 'th_open') {
|
|
621
|
+
firstRowCells.push(thIdx);
|
|
622
|
+
} else if (tokens[thIdx].type === 'tr_close') {
|
|
623
|
+
firstRowClose = thIdx;
|
|
624
|
+
break;
|
|
625
|
+
}
|
|
626
|
+
thIdx++;
|
|
627
|
+
}
|
|
628
|
+
if (firstRowClose < 0 || firstRowCells.length === 0) return;
|
|
629
|
+
|
|
630
|
+
const secondRowCells = [];
|
|
631
|
+
let secondRowClose = -1;
|
|
632
|
+
thIdx = tr2 + 1;
|
|
633
|
+
while (thIdx < tokens.length) {
|
|
576
634
|
if (tokens[thIdx].type === 'th_open') {
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
635
|
+
secondRowCells.push(thIdx);
|
|
636
|
+
} else if (tokens[thIdx].type === 'tr_close') {
|
|
637
|
+
secondRowClose = thIdx;
|
|
638
|
+
break;
|
|
639
|
+
}
|
|
640
|
+
thIdx++;
|
|
641
|
+
}
|
|
642
|
+
if (secondRowClose < 0 || secondRowCells.length === 0) return;
|
|
643
|
+
|
|
644
|
+
for (let i = 0; i < firstRowCells.length; i++) {
|
|
645
|
+
const inline = tokens[firstRowCells[i] + 1];
|
|
646
|
+
const content = inline && typeof inline.content === 'string' ? inline.content : '';
|
|
647
|
+
let match = null;
|
|
648
|
+
if (opt.colgroupWithNoAsterisk) {
|
|
649
|
+
if (content.indexOf(':') !== -1 || content.indexOf(':') !== -1) {
|
|
582
650
|
match = content.match(groupMatchReg);
|
|
583
651
|
}
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
groupData.spans.push(1);
|
|
594
|
-
}
|
|
652
|
+
} else if (hasLeadingStrongMarker(inline, allowFallback)) {
|
|
653
|
+
match = content.match(groupMatchReg);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
if (match) {
|
|
657
|
+
const group = match[1].trim();
|
|
658
|
+
const lastGroup = groupData.rawNames[groupData.rawNames.length - 1];
|
|
659
|
+
if (groupData.rawNames.length > 0 && lastGroup === group) {
|
|
660
|
+
groupData.spans[groupData.spans.length - 1]++;
|
|
595
661
|
} else {
|
|
596
|
-
groupData.rawNames.push(
|
|
662
|
+
groupData.rawNames.push(group);
|
|
597
663
|
groupData.spans.push(1);
|
|
598
664
|
}
|
|
665
|
+
groupData.headerCount++;
|
|
666
|
+
} else {
|
|
667
|
+
groupData.rawNames.push(null);
|
|
668
|
+
groupData.spans.push(1);
|
|
599
669
|
}
|
|
600
|
-
thIdx++;
|
|
601
670
|
}
|
|
602
671
|
|
|
603
|
-
|
|
604
|
-
const groupStripReg = /^\*\*[^*:]+:\*\*\s*(.*)$/;
|
|
672
|
+
if (groupData.headerCount < 2) return;
|
|
605
673
|
|
|
606
|
-
// Generate colgroup if needed
|
|
607
674
|
const hasSpan = groupData.spans.some(span => span > 1);
|
|
608
|
-
|
|
609
|
-
|
|
675
|
+
|
|
676
|
+
// Add colspan/rowspan to thead and strip group prefixes in the second row.
|
|
677
|
+
const firstRowRemove = [];
|
|
678
|
+
const secondRowRemove = [];
|
|
679
|
+
let firstPtr = 0;
|
|
680
|
+
let secondPtr = 0;
|
|
681
|
+
for (let groupIdx = 0; groupIdx < groupData.spans.length; groupIdx++) {
|
|
682
|
+
const span = groupData.spans[groupIdx];
|
|
683
|
+
const groupName = groupData.rawNames[groupIdx];
|
|
684
|
+
const firstOpen = firstRowCells[firstPtr];
|
|
685
|
+
if (typeof firstOpen !== 'number' || !tokens[firstOpen] || tokens[firstOpen].type !== 'th_open') {
|
|
686
|
+
break;
|
|
687
|
+
}
|
|
688
|
+
const firstInline = tokens[firstOpen + 1];
|
|
689
|
+
|
|
690
|
+
if (groupName === null) {
|
|
691
|
+
tokens[firstOpen].attrSet('rowspan', '2');
|
|
692
|
+
tokens[firstOpen].attrSet('scope', 'col');
|
|
693
|
+
removeStrongWrappers(firstInline, allowFallback);
|
|
694
|
+
const secondOpen = secondRowCells[secondPtr];
|
|
695
|
+
if (typeof secondOpen === 'number') {
|
|
696
|
+
secondRowRemove.push(secondOpen);
|
|
697
|
+
secondPtr += 1;
|
|
698
|
+
}
|
|
699
|
+
firstPtr += 1;
|
|
700
|
+
continue;
|
|
701
|
+
}
|
|
610
702
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
703
|
+
if (span > 1) {
|
|
704
|
+
tokens[firstOpen].attrSet('colspan', span.toString());
|
|
705
|
+
}
|
|
706
|
+
tokens[firstOpen].attrSet('scope', 'col');
|
|
707
|
+
if (firstInline) {
|
|
708
|
+
setInlineText(firstInline, Token, groupName);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
for (let i = 1; i < span; i++) {
|
|
712
|
+
const extraFirst = firstRowCells[firstPtr + i];
|
|
713
|
+
if (typeof extraFirst === 'number') {
|
|
714
|
+
firstRowRemove.push(extraFirst);
|
|
615
715
|
}
|
|
616
|
-
insertTokens.push(colOpen, new Token('col_close', 'col', -1));
|
|
617
716
|
}
|
|
618
717
|
|
|
619
|
-
|
|
620
|
-
|
|
718
|
+
for (let i = 0; i < span; i++) {
|
|
719
|
+
const secondOpen = secondRowCells[secondPtr + i];
|
|
720
|
+
if (typeof secondOpen !== 'number' || !tokens[secondOpen] || tokens[secondOpen].type !== 'th_open') {
|
|
721
|
+
continue;
|
|
722
|
+
}
|
|
723
|
+
tokens[secondOpen].attrSet('scope', 'col');
|
|
724
|
+
const secondInline = tokens[secondOpen + 1];
|
|
725
|
+
if (!secondInline || typeof secondInline.content !== 'string') continue;
|
|
726
|
+
const secondContent = secondInline.content;
|
|
727
|
+
let secondMatch = null;
|
|
728
|
+
if (opt.colgroupWithNoAsterisk) {
|
|
729
|
+
if (secondContent.indexOf(':') !== -1 || secondContent.indexOf(':') !== -1) {
|
|
730
|
+
secondMatch = secondContent.match(groupStripReg);
|
|
731
|
+
}
|
|
732
|
+
} else if (hasLeadingStrongMarker(secondInline, allowFallback)) {
|
|
733
|
+
secondMatch = secondContent.match(groupStripReg);
|
|
734
|
+
}
|
|
735
|
+
if (secondMatch) {
|
|
736
|
+
setInlineText(secondInline, Token, secondMatch[1]);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
secondPtr += span;
|
|
741
|
+
firstPtr += span;
|
|
621
742
|
}
|
|
622
743
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
}
|
|
641
|
-
t2++;
|
|
642
|
-
}
|
|
643
|
-
groupIdx++;
|
|
644
|
-
} else {
|
|
645
|
-
// Group cell
|
|
646
|
-
if (groupData.spans[groupIdx] > 1) {
|
|
647
|
-
tokens[th1].attrSet('colspan', groupData.spans[groupIdx].toString());
|
|
648
|
-
}
|
|
649
|
-
tokens[th1].attrSet('scope', 'col');
|
|
650
|
-
tokens[th1 + 1].content = groupNames[groupIdx];
|
|
651
|
-
|
|
652
|
-
// Process corresponding ths in second row
|
|
653
|
-
let count = 0, t2 = th2;
|
|
654
|
-
while (t2 < tokens.length && tokens[t2].type !== 'tr_close' && count < groupData.spans[groupIdx]) {
|
|
655
|
-
if (tokens[t2].type === 'th_open') {
|
|
656
|
-
tokens[t2].attrSet('scope', 'col');
|
|
657
|
-
// Remove group name part from content
|
|
658
|
-
const t2Inline = tokens[t2 + 1];
|
|
659
|
-
const t2content = t2Inline.content;
|
|
660
|
-
let t2match = null;
|
|
661
|
-
if (hasLeadingStrongMarker(t2Inline, allowFallback)) {
|
|
662
|
-
t2match = t2content.match(groupStripReg);
|
|
663
|
-
}
|
|
664
|
-
if (t2match) {
|
|
665
|
-
tokens[t2 + 1].content = t2match[1];
|
|
666
|
-
}
|
|
667
|
-
count++;
|
|
668
|
-
}
|
|
669
|
-
t2++;
|
|
670
|
-
}
|
|
671
|
-
th2 = t2;
|
|
672
|
-
groupIdx++;
|
|
744
|
+
if (firstRowRemove.length || secondRowRemove.length) {
|
|
745
|
+
const removeTargets = firstRowRemove.concat(secondRowRemove).sort((a, b) => b - a);
|
|
746
|
+
for (let i = 0; i < removeTargets.length; i++) {
|
|
747
|
+
removeHeaderCellAt(tokens, removeTargets[i]);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// Insert colgroup after header edits so index calculations above remain stable.
|
|
752
|
+
if (hasSpan) {
|
|
753
|
+
const insertTokens = [
|
|
754
|
+
new Token('colgroup_open', 'colgroup', 1),
|
|
755
|
+
createNewlineToken(Token)
|
|
756
|
+
];
|
|
757
|
+
for (let i = 0; i < groupData.spans.length; i++) {
|
|
758
|
+
const colOpen = new Token('col_open', 'col', 1);
|
|
759
|
+
if (groupData.spans[i] > 1) {
|
|
760
|
+
colOpen.attrPush(['span', groupData.spans[i]]);
|
|
673
761
|
}
|
|
762
|
+
insertTokens.push(colOpen, createNewlineToken(Token));
|
|
674
763
|
}
|
|
675
|
-
|
|
764
|
+
insertTokens.push(
|
|
765
|
+
new Token('colgroup_close', 'colgroup', -1),
|
|
766
|
+
createNewlineToken(Token)
|
|
767
|
+
);
|
|
768
|
+
tokens.splice(tableOpenIdx + 1, 0, ...insertTokens);
|
|
676
769
|
}
|
|
677
770
|
};
|
|
678
771
|
|
|
679
|
-
const tableEx = (state, opt) => {
|
|
772
|
+
const tableEx = (state, opt, regexes) => {
|
|
680
773
|
const tokens = state.tokens;
|
|
681
774
|
let tokenLength = tokens.length;
|
|
682
775
|
const allowStrongFallback = !hasInlineRule(state.md, 'strong_ja');
|
|
@@ -688,7 +781,7 @@ const tableEx = (state, opt) => {
|
|
|
688
781
|
continue;
|
|
689
782
|
}
|
|
690
783
|
|
|
691
|
-
|
|
784
|
+
let tableOpenIdx = idx;
|
|
692
785
|
|
|
693
786
|
if (opt.wrapper) {
|
|
694
787
|
const wrapperStartToken = new state.Token('div_open', 'div', 1);
|
|
@@ -696,11 +789,10 @@ const tableEx = (state, opt) => {
|
|
|
696
789
|
if (Array.isArray(tokens[idx].map)) {
|
|
697
790
|
wrapperStartToken.map = tokens[idx].map.slice();
|
|
698
791
|
}
|
|
699
|
-
|
|
700
|
-
linebreakToken.content = '\n';
|
|
701
|
-
tokens.splice(idx, 0, wrapperStartToken, linebreakToken);
|
|
792
|
+
tokens.splice(idx, 0, wrapperStartToken, createNewlineToken(state.Token));
|
|
702
793
|
tokenLength += 2;
|
|
703
794
|
idx += 2;
|
|
795
|
+
tableOpenIdx = idx;
|
|
704
796
|
}
|
|
705
797
|
|
|
706
798
|
let theadVar = {
|
|
@@ -712,27 +804,50 @@ const tableEx = (state, opt) => {
|
|
|
712
804
|
if (hasThead) {
|
|
713
805
|
theadVar = addTheadThScope(state, theadVar, allowStrongFallback);
|
|
714
806
|
idx = theadVar.i + 1;
|
|
807
|
+
const hadMatrixAnchor = Number.isInteger(theadVar.firstThPos) && theadVar.firstThPos >= 0;
|
|
715
808
|
if (opt.colgroup) {
|
|
716
809
|
const beforeLength = tokens.length;
|
|
717
|
-
setColgroup(state, tableOpenIdx, opt, allowStrongFallback);
|
|
810
|
+
setColgroup(state, tableOpenIdx, opt, allowStrongFallback, regexes);
|
|
718
811
|
tokenLength += tokens.length - beforeLength;
|
|
719
812
|
}
|
|
813
|
+
if (opt.matrix) {
|
|
814
|
+
let firstThPos = findFirstHeaderThPos(tokens, tableOpenIdx, allowStrongFallback);
|
|
815
|
+
if (firstThPos < 0 && hadMatrixAnchor) {
|
|
816
|
+
firstThPos = findFirstHeaderCellPos(tokens, tableOpenIdx);
|
|
817
|
+
}
|
|
818
|
+
theadVar.firstThPos = firstThPos;
|
|
819
|
+
}
|
|
720
820
|
}
|
|
721
821
|
|
|
722
822
|
if (opt.matrix) {
|
|
823
|
+
let tbodyOpenPos = -1;
|
|
824
|
+
for (let i = tableOpenIdx + 1; i < tokenLength; i++) {
|
|
825
|
+
const type = tokens[i].type;
|
|
826
|
+
if (type === 'tbody_open') {
|
|
827
|
+
tbodyOpenPos = i;
|
|
828
|
+
break;
|
|
829
|
+
}
|
|
830
|
+
if (type === 'table_close') {
|
|
831
|
+
break;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
|
|
723
835
|
let tbodyVar = {
|
|
724
|
-
i:
|
|
836
|
+
i: tbodyOpenPos,
|
|
725
837
|
isAllFirstTh: false,
|
|
726
838
|
tbodyFirstThPoses: [],
|
|
727
839
|
};
|
|
728
840
|
|
|
729
|
-
const hasTbody =
|
|
841
|
+
const hasTbody = tbodyVar.i >= 0;
|
|
730
842
|
if (hasTbody) {
|
|
731
843
|
tbodyVar = checkTbody(state, tbodyVar, allowStrongFallback);
|
|
732
844
|
idx = tbodyVar.i + 1;
|
|
733
845
|
}
|
|
734
846
|
|
|
735
|
-
|
|
847
|
+
const hasMatrixAnchor = hasThead
|
|
848
|
+
? Number.isInteger(theadVar.firstThPos) && theadVar.firstThPos >= 0
|
|
849
|
+
: true;
|
|
850
|
+
if (hasMatrixAnchor && tbodyVar.isAllFirstTh) {
|
|
736
851
|
const firstTdPoses = [...tbodyVar.tbodyFirstThPoses];
|
|
737
852
|
if (hasThead) {
|
|
738
853
|
firstTdPoses.unshift(theadVar.firstThPos);
|
|
@@ -746,9 +861,7 @@ const tableEx = (state, opt) => {
|
|
|
746
861
|
if (tokens[idx].type === 'table_close') {
|
|
747
862
|
if (opt.wrapper) {
|
|
748
863
|
const wrapperEndToken = new state.Token('div_close', 'div', -1);
|
|
749
|
-
|
|
750
|
-
linebreakToken.content = '\n';
|
|
751
|
-
tokens.splice(idx + 1, 0, wrapperEndToken, linebreakToken);
|
|
864
|
+
tokens.splice(idx + 1, 0, wrapperEndToken, createNewlineToken(state.Token));
|
|
752
865
|
tokenLength += 2;
|
|
753
866
|
idx += 2;
|
|
754
867
|
}
|
|
@@ -761,17 +874,17 @@ const tableEx = (state, opt) => {
|
|
|
761
874
|
};
|
|
762
875
|
|
|
763
876
|
const mditTableEx = (md, option) => {
|
|
764
|
-
|
|
877
|
+
const baseOpt = {
|
|
765
878
|
matrix: true,
|
|
766
879
|
wrapper: false,
|
|
767
880
|
colgroup: false,
|
|
768
881
|
colgroupWithNoAsterisk: false
|
|
769
882
|
};
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
883
|
+
const userOpt = (option && typeof option === 'object') ? option : {};
|
|
884
|
+
const opt = Object.assign({}, baseOpt, userOpt);
|
|
885
|
+
const regexes = createColgroupRegexes(opt.colgroupWithNoAsterisk);
|
|
773
886
|
md.core.ruler.after('replacements', 'table-ex', (state) => {
|
|
774
|
-
tableEx(state, opt);
|
|
887
|
+
tableEx(state, opt, regexes);
|
|
775
888
|
});
|
|
776
889
|
}
|
|
777
890
|
export default mditTableEx
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peaceroad/markdown-it-table-ex",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "A markdown-it plugin. Add matrix and wrapper notation for table processing.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"author": "peaceroad <peaceroad@gmail.com>",
|
|
17
17
|
"license": "MIT",
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@peaceroad/markdown-it-figure-with-p-caption": "^0.
|
|
20
|
-
"@peaceroad/markdown-it-strong-ja": "^0.
|
|
19
|
+
"@peaceroad/markdown-it-figure-with-p-caption": "^0.16.0",
|
|
20
|
+
"@peaceroad/markdown-it-strong-ja": "^0.7.2",
|
|
21
21
|
"markdown-it": "^14.1.0",
|
|
22
22
|
"markdown-it-multimd-table": "^4.2.3"
|
|
23
23
|
}
|