@diplodoc/transform 4.74.1 → 4.75.1
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/dist/css/_yfm-only.css +27 -0
- package/dist/css/_yfm-only.css.map +3 -3
- package/dist/css/_yfm-only.min.css +1 -1
- package/dist/css/_yfm-only.min.css.map +3 -3
- package/dist/css/base.css.map +1 -1
- package/dist/css/base.min.css.map +1 -1
- package/dist/css/print.css.map +1 -1
- package/dist/css/yfm.css +27 -0
- package/dist/css/yfm.css.map +3 -3
- package/dist/css/yfm.min.css +1 -1
- package/dist/css/yfm.min.css.map +3 -3
- package/dist/js/base.js +12 -6
- package/dist/js/base.js.map +2 -2
- package/dist/js/base.min.js +1 -1
- package/dist/js/base.min.js.map +3 -3
- package/dist/js/yfm.js +12 -6
- package/dist/js/yfm.js.map +2 -2
- package/dist/js/yfm.min.js +1 -1
- package/dist/js/yfm.min.js.map +3 -3
- package/dist/scss/_table.scss +13 -0
- package/dist/scss/_tooltip.scss +12 -0
- package/lib/plugins/table/index.js +187 -15
- package/lib/plugins/table/index.js.map +1 -1
- package/lib/plugins/table/types.d.ts +1 -0
- package/lib/plugins/term/index.js +18 -4
- package/lib/plugins/term/index.js.map +1 -1
- package/package.json +1 -1
- package/src/js/tooltip/constant.ts +2 -0
- package/src/js/tooltip/tooltip.ts +14 -10
- package/src/scss/_table.scss +13 -0
- package/src/scss/_tooltip.scss +12 -0
- package/src/transform/plugins/table/index.ts +233 -20
- package/src/transform/plugins/table/types.ts +2 -0
- package/src/transform/plugins/term/index.ts +19 -3
package/src/scss/_table.scss
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
.yfm table th,
|
|
1
2
|
.yfm table td {
|
|
2
3
|
&.cell-align-top-left,
|
|
3
4
|
&.cell-align-bottom-left {
|
|
@@ -63,6 +64,18 @@
|
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
|
|
67
|
+
.yfm table tr[data-header] {
|
|
68
|
+
& > th,
|
|
69
|
+
& > td {
|
|
70
|
+
&:not([class*='cell-bg-']) {
|
|
71
|
+
background: var(
|
|
72
|
+
--yfm-color-table-head-background,
|
|
73
|
+
var(--yfm-color-table-head-background-private)
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
66
79
|
.yfm table[sticky-header] {
|
|
67
80
|
position: relative;
|
|
68
81
|
|
package/src/scss/_tooltip.scss
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
.yfm-tooltip-live-region {
|
|
2
|
+
position: absolute;
|
|
3
|
+
width: 1px;
|
|
4
|
+
height: 1px;
|
|
5
|
+
padding: 0;
|
|
6
|
+
margin: -1px;
|
|
7
|
+
overflow: hidden;
|
|
8
|
+
clip-path: inset(50%);
|
|
9
|
+
white-space: nowrap;
|
|
10
|
+
border: 0;
|
|
11
|
+
}
|
|
12
|
+
|
|
1
13
|
.yfm-tooltip {
|
|
2
14
|
position: absolute;
|
|
3
15
|
z-index: 100;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type StateBlock from 'markdown-it/lib/rules_block/state_block';
|
|
2
2
|
import type Token from 'markdown-it/lib/token';
|
|
3
3
|
import type {MarkdownItPluginCb} from '../typings';
|
|
4
|
-
import type {
|
|
4
|
+
import type {Logger} from '../../log';
|
|
5
|
+
import type {TableAttrs, YfmTablePluginOptions} from './types';
|
|
5
6
|
|
|
6
|
-
import {AttrsParser} from '@diplodoc/utils';
|
|
7
|
+
import {AttrsParser, parseMdAttrs} from '@diplodoc/utils';
|
|
7
8
|
|
|
8
9
|
const pluginName = 'yfm_table';
|
|
9
10
|
const pipeChar = 0x7c; // |
|
|
11
|
+
const colonChar = 0x3a; // :
|
|
10
12
|
const apostropheChar = 0x60; // `
|
|
11
13
|
const hashChar = 0x23; // #
|
|
12
14
|
const backSlashChar = 0x5c; // \
|
|
@@ -225,10 +227,70 @@ class StateIterator {
|
|
|
225
227
|
}
|
|
226
228
|
}
|
|
227
229
|
|
|
230
|
+
type CellData = {start: Stats; end: Stats; rawAttrs: TableAttrs};
|
|
231
|
+
type RowData = {start: number; end: number; cols: CellData[]; rawAttrs: TableAttrs};
|
|
232
|
+
|
|
228
233
|
interface RowPositions {
|
|
229
|
-
rows: [
|
|
234
|
+
rows: RowData[];
|
|
230
235
|
endOfTable: number | null;
|
|
231
236
|
pos: number;
|
|
237
|
+
tableAttrs: TableAttrs;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Parses table options from lines between #| and the first || or |#.
|
|
242
|
+
*
|
|
243
|
+
* Option line format: `|:{key="value" key2="value2"}`
|
|
244
|
+
* Multiple option lines are supported; results are merged.
|
|
245
|
+
*/
|
|
246
|
+
function parseTableAttrs(state: StateBlock, iter: StateIterator): TableAttrs {
|
|
247
|
+
const options: TableAttrs = {};
|
|
248
|
+
const {src} = state;
|
|
249
|
+
const utils = state.md.utils;
|
|
250
|
+
|
|
251
|
+
let parsing = true;
|
|
252
|
+
|
|
253
|
+
while (parsing) {
|
|
254
|
+
const lineEnd = iter.lineEnds;
|
|
255
|
+
|
|
256
|
+
// Skip leading whitespace to find first non-space char
|
|
257
|
+
let first = iter.pos;
|
|
258
|
+
while (first < lineEnd && utils.isSpace(src.charCodeAt(first))) {
|
|
259
|
+
first++;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Skip empty lines
|
|
263
|
+
if (first >= lineEnd) {
|
|
264
|
+
iter.next(lineEnd - iter.pos + 1);
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Stop if we hit row start || or table close |#
|
|
269
|
+
if (isRowOrder(src, first) || isCloseTableOrder(src, first)) {
|
|
270
|
+
parsing = false;
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Option line must start with |:
|
|
275
|
+
if (src.charCodeAt(first) !== pipeChar || src.charCodeAt(first + 1) !== colonChar) {
|
|
276
|
+
parsing = false;
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const result = parseMdAttrs(state.md, src, first + 2, lineEnd);
|
|
281
|
+
if (!result) {
|
|
282
|
+
parsing = false;
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
for (const [key, values] of Object.entries(result.attrs)) {
|
|
287
|
+
options[key] = values[values.length - 1];
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
iter.next(lineEnd - iter.pos + 1);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return options;
|
|
232
294
|
}
|
|
233
295
|
|
|
234
296
|
// eslint-disable-next-line complexity
|
|
@@ -241,13 +303,17 @@ function getTableRowPositions(
|
|
|
241
303
|
): RowPositions {
|
|
242
304
|
let endOfTable = null;
|
|
243
305
|
let tableLevel = 0;
|
|
244
|
-
let currentRow: [
|
|
306
|
+
let currentRow: CellData[] = [];
|
|
245
307
|
let colStart: Stats | null = null;
|
|
308
|
+
let pendingCellAttrs: TableAttrs = {};
|
|
246
309
|
let rowStart: number | null = null;
|
|
310
|
+
let currentRowAttrs: TableAttrs = {};
|
|
247
311
|
|
|
248
312
|
const iter = new StateIterator(state, startPosition + openTableOrder.length, startLine);
|
|
249
313
|
|
|
250
|
-
const
|
|
314
|
+
const tableAttrs = parseTableAttrs(state, iter);
|
|
315
|
+
|
|
316
|
+
const rows: RowData[] = [];
|
|
251
317
|
|
|
252
318
|
let isInsideCode = false;
|
|
253
319
|
let isInsideMath = false;
|
|
@@ -256,14 +322,21 @@ function getTableRowPositions(
|
|
|
256
322
|
|
|
257
323
|
const addRow = () => {
|
|
258
324
|
if (colStart) {
|
|
259
|
-
currentRow.push(
|
|
325
|
+
currentRow.push({start: colStart, end: iter.stats(), rawAttrs: pendingCellAttrs});
|
|
326
|
+
pendingCellAttrs = {};
|
|
260
327
|
}
|
|
261
328
|
if (currentRow.length && rowStart) {
|
|
262
|
-
rows.push(
|
|
329
|
+
rows.push({
|
|
330
|
+
start: rowStart,
|
|
331
|
+
end: iter.line,
|
|
332
|
+
cols: currentRow,
|
|
333
|
+
rawAttrs: currentRowAttrs,
|
|
334
|
+
});
|
|
263
335
|
}
|
|
264
336
|
currentRow = [];
|
|
265
337
|
colStart = null;
|
|
266
338
|
rowStart = null;
|
|
339
|
+
currentRowAttrs = {};
|
|
267
340
|
};
|
|
268
341
|
|
|
269
342
|
while (iter.pos <= endPosition) {
|
|
@@ -356,6 +429,36 @@ function getTableRowPositions(
|
|
|
356
429
|
} else {
|
|
357
430
|
iter.next(rowStartOrder.length);
|
|
358
431
|
rowStart = iter.line;
|
|
432
|
+
|
|
433
|
+
const hasRowAttrs =
|
|
434
|
+
iter.pos <= iter.lineEnds &&
|
|
435
|
+
state.src.charCodeAt(iter.pos) === colonChar &&
|
|
436
|
+
state.src.charCodeAt(iter.pos + 1) === curlyBraceOpen;
|
|
437
|
+
if (hasRowAttrs) {
|
|
438
|
+
currentRowAttrs = parseInlineAttrs(state, iter, 1);
|
|
439
|
+
} else {
|
|
440
|
+
currentRowAttrs = {};
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// skip spaces/tabs on same line only if row attrs were present, then check for first-cell attrs ::{...}
|
|
444
|
+
if (hasRowAttrs) {
|
|
445
|
+
while (
|
|
446
|
+
iter.pos <= iter.lineEnds &&
|
|
447
|
+
state.md.utils.isSpace(state.src.charCodeAt(iter.pos))
|
|
448
|
+
) {
|
|
449
|
+
iter.next(1);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
if (
|
|
453
|
+
iter.pos <= iter.lineEnds &&
|
|
454
|
+
state.src.charCodeAt(iter.pos) === colonChar &&
|
|
455
|
+
state.src.charCodeAt(iter.pos + 1) === colonChar
|
|
456
|
+
) {
|
|
457
|
+
pendingCellAttrs = parseInlineAttrs(state, iter, 2);
|
|
458
|
+
} else {
|
|
459
|
+
pendingCellAttrs = {};
|
|
460
|
+
}
|
|
461
|
+
|
|
359
462
|
colStart = iter.stats();
|
|
360
463
|
}
|
|
361
464
|
|
|
@@ -366,9 +469,20 @@ function getTableRowPositions(
|
|
|
366
469
|
|
|
367
470
|
if (isCellOrder(state.src, iter.pos)) {
|
|
368
471
|
if (colStart) {
|
|
369
|
-
currentRow.push(
|
|
472
|
+
currentRow.push({start: colStart, end: iter.stats(), rawAttrs: pendingCellAttrs});
|
|
473
|
+
pendingCellAttrs = {};
|
|
370
474
|
}
|
|
371
475
|
iter.next(cellStartOrder.length);
|
|
476
|
+
// check for cell attrs ::{...} immediately after | (no spaces allowed)
|
|
477
|
+
if (
|
|
478
|
+
iter.pos <= iter.lineEnds &&
|
|
479
|
+
state.src.charCodeAt(iter.pos) === colonChar &&
|
|
480
|
+
state.src.charCodeAt(iter.pos + 1) === colonChar
|
|
481
|
+
) {
|
|
482
|
+
pendingCellAttrs = parseInlineAttrs(state, iter, 2);
|
|
483
|
+
} else {
|
|
484
|
+
pendingCellAttrs = {};
|
|
485
|
+
}
|
|
372
486
|
colStart = iter.stats();
|
|
373
487
|
continue;
|
|
374
488
|
}
|
|
@@ -378,7 +492,20 @@ function getTableRowPositions(
|
|
|
378
492
|
|
|
379
493
|
const {pos} = iter;
|
|
380
494
|
|
|
381
|
-
return {rows, endOfTable, pos};
|
|
495
|
+
return {rows, endOfTable, pos, tableAttrs};
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
function parseInlineAttrs(state: StateBlock, iter: StateIterator, prefixLen: number): TableAttrs {
|
|
499
|
+
const result: TableAttrs = {};
|
|
500
|
+
const parsed = parseMdAttrs(state.md, state.src, iter.pos + prefixLen, iter.lineEnds);
|
|
501
|
+
if (!parsed) {
|
|
502
|
+
return result;
|
|
503
|
+
}
|
|
504
|
+
for (const [key, values] of Object.entries(parsed.attrs)) {
|
|
505
|
+
result[key] = values[0];
|
|
506
|
+
}
|
|
507
|
+
iter.next(parsed.pos - iter.pos);
|
|
508
|
+
return result;
|
|
382
509
|
}
|
|
383
510
|
|
|
384
511
|
function extractAttributes(state: StateBlock, pos: number): Record<string, string[]> {
|
|
@@ -396,9 +523,10 @@ function extractAttributes(state: StateBlock, pos: number): Record<string, strin
|
|
|
396
523
|
*
|
|
397
524
|
* @param {Token} contentToken - Search the content of this token for the class.
|
|
398
525
|
* @param {Token} tdOpenToken - Parent td_open token. Extracted class is applied to this token.
|
|
526
|
+
* @param {Logger} log - Logger instance for deprecation warnings.
|
|
399
527
|
* @returns {void}
|
|
400
528
|
*/
|
|
401
|
-
function extractAndApplyClassFromToken(contentToken: Token, tdOpenToken: Token): void {
|
|
529
|
+
function extractAndApplyClassFromToken(contentToken: Token, tdOpenToken: Token, log: Logger): void {
|
|
402
530
|
// Regex to find class attribute in any position within brackets
|
|
403
531
|
const blockRegex = /\s*\{[^}]*}$/;
|
|
404
532
|
const allAttrs = contentToken.content.match(blockRegex);
|
|
@@ -410,7 +538,12 @@ function extractAndApplyClassFromToken(contentToken: Token, tdOpenToken: Token):
|
|
|
410
538
|
const attrsClass = attrs?.class?.join(' ');
|
|
411
539
|
|
|
412
540
|
if (attrsClass) {
|
|
413
|
-
|
|
541
|
+
if (attrsClass.split(' ').some((c) => c.startsWith('cell-align-'))) {
|
|
542
|
+
log.warn(
|
|
543
|
+
`Deprecated: use align="..." inside cell attributes "::{align=\\"...\\"}" instead of .cell-align-* class in cell content "{ }"`,
|
|
544
|
+
);
|
|
545
|
+
}
|
|
546
|
+
tdOpenToken.attrJoin('class', attrsClass);
|
|
414
547
|
// remove the class from the token so that it's not propagated to tr or table level
|
|
415
548
|
let replacedContent = allAttrs[0].replace(`.${attrsClass}`, '');
|
|
416
549
|
if (replacedContent.trim() === '{}') {
|
|
@@ -420,6 +553,52 @@ function extractAndApplyClassFromToken(contentToken: Token, tdOpenToken: Token):
|
|
|
420
553
|
}
|
|
421
554
|
}
|
|
422
555
|
|
|
556
|
+
const VALID_ALIGN_VALUES: ReadonlySet<string> = new Set([
|
|
557
|
+
'top-left',
|
|
558
|
+
'top-center',
|
|
559
|
+
'top-right',
|
|
560
|
+
'center',
|
|
561
|
+
'bottom-left',
|
|
562
|
+
'bottom-right',
|
|
563
|
+
]);
|
|
564
|
+
|
|
565
|
+
function parseHeaderRows(rawAttrs: TableAttrs, log: Logger): number | null {
|
|
566
|
+
if (!('header-rows' in rawAttrs)) return null;
|
|
567
|
+
const raw = rawAttrs['header-rows'];
|
|
568
|
+
const trimmed = raw.trim();
|
|
569
|
+
const parsed = Number.parseInt(trimmed, 10);
|
|
570
|
+
if (!Number.isInteger(parsed) || parsed <= 0 || String(parsed) !== trimmed) {
|
|
571
|
+
log.warn(`Invalid table header-rows value: "${raw}"`);
|
|
572
|
+
return null;
|
|
573
|
+
}
|
|
574
|
+
return parsed;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
function applyCellAttrs(token: Token, rawAttrs: TableAttrs, log: Logger): void {
|
|
578
|
+
if ('align' in rawAttrs) {
|
|
579
|
+
const value = rawAttrs['align'];
|
|
580
|
+
if (!VALID_ALIGN_VALUES.has(value)) {
|
|
581
|
+
log.warn(`Unknown table cell align value: "${value}"`);
|
|
582
|
+
}
|
|
583
|
+
token.meta = token.meta || {};
|
|
584
|
+
token.meta.align = value;
|
|
585
|
+
token.attrSet('data-align', value);
|
|
586
|
+
if (value) {
|
|
587
|
+
token.attrJoin('class', `cell-align-${value}`);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
if ('bg' in rawAttrs) {
|
|
592
|
+
const value = rawAttrs['bg'];
|
|
593
|
+
token.meta = token.meta || {};
|
|
594
|
+
token.meta.bg = value;
|
|
595
|
+
token.attrSet('data-bg', value);
|
|
596
|
+
if (value) {
|
|
597
|
+
token.attrJoin('class', `cell-bg-${value}`);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
423
602
|
const COLSPAN_SYMBOL = '>';
|
|
424
603
|
const ROWSPAN_SYMBOL = '^';
|
|
425
604
|
|
|
@@ -539,7 +718,7 @@ const yfmTable: MarkdownItPluginCb<YfmTablePluginOptions> = (md, opts) => {
|
|
|
539
718
|
return true;
|
|
540
719
|
}
|
|
541
720
|
|
|
542
|
-
const {rows, endOfTable, pos} = getTableRowPositions(
|
|
721
|
+
const {rows, endOfTable, pos, tableAttrs} = getTableRowPositions(
|
|
543
722
|
state,
|
|
544
723
|
startPosition,
|
|
545
724
|
endPosition,
|
|
@@ -575,11 +754,19 @@ const yfmTable: MarkdownItPluginCb<YfmTablePluginOptions> = (md, opts) => {
|
|
|
575
754
|
}
|
|
576
755
|
|
|
577
756
|
token.map = [startLine, endOfTable];
|
|
757
|
+
token.meta = token.meta || {};
|
|
758
|
+
token.meta.rawAttrs = tableAttrs;
|
|
759
|
+
|
|
760
|
+
const headerRows = parseHeaderRows(tableAttrs, opts.log);
|
|
761
|
+
if (headerRows !== null) {
|
|
762
|
+
token.meta.headerRows = headerRows;
|
|
763
|
+
token.attrSet('data-header-rows', String(headerRows));
|
|
764
|
+
}
|
|
578
765
|
|
|
579
766
|
token = state.push('yfm_tbody_open', 'tbody', 1);
|
|
580
767
|
token.map = [startLine + 1, endOfTable - 1];
|
|
581
768
|
|
|
582
|
-
const maxRowLength = Math.max(...rows.map((
|
|
769
|
+
const maxRowLength = Math.max(...rows.map((row) => row.cols.length));
|
|
583
770
|
|
|
584
771
|
// cellsMaps is a 2-D map of all td_open tokens in the table.
|
|
585
772
|
// cellsMap is used to access the table cells by [row][column] coordinates
|
|
@@ -590,19 +777,38 @@ const yfmTable: MarkdownItPluginCb<YfmTablePluginOptions> = (md, opts) => {
|
|
|
590
777
|
const contentMap: string[][] = [];
|
|
591
778
|
|
|
592
779
|
for (let i = 0; i < rows.length; i++) {
|
|
593
|
-
const
|
|
780
|
+
const {
|
|
781
|
+
start: rowLineStarts,
|
|
782
|
+
end: rowLineEnds,
|
|
783
|
+
cols,
|
|
784
|
+
rawAttrs: rowRawAttrs,
|
|
785
|
+
} = rows[i];
|
|
594
786
|
cellsMap.push([]);
|
|
595
787
|
contentMap.push([]);
|
|
596
788
|
const rowLength = cols.length;
|
|
597
789
|
|
|
790
|
+
const isHeaderRow = headerRows !== null && i < headerRows;
|
|
791
|
+
const cellTag = isHeaderRow ? 'th' : 'td';
|
|
792
|
+
|
|
598
793
|
token = state.push('yfm_tr_open', 'tr', 1);
|
|
599
794
|
token.map = [rowLineStarts, rowLineEnds];
|
|
795
|
+
token.meta = token.meta || {};
|
|
796
|
+
token.meta.rawAttrs = rowRawAttrs;
|
|
797
|
+
if (isHeaderRow) {
|
|
798
|
+
token.attrSet('data-header', 'true');
|
|
799
|
+
}
|
|
600
800
|
|
|
601
801
|
for (let j = 0; j < cols.length; j++) {
|
|
602
|
-
const
|
|
603
|
-
token = state.push('yfm_td_open',
|
|
802
|
+
const {start: begin, end, rawAttrs: cellRawAttrs} = cols[j];
|
|
803
|
+
token = state.push('yfm_td_open', cellTag, 1);
|
|
604
804
|
cellsMap[i].push(token);
|
|
605
805
|
token.map = [begin.line, end.line];
|
|
806
|
+
token.meta = token.meta || {};
|
|
807
|
+
token.meta.rawAttrs = cellRawAttrs;
|
|
808
|
+
if (isHeaderRow) {
|
|
809
|
+
token.attrSet('scope', 'col');
|
|
810
|
+
}
|
|
811
|
+
applyCellAttrs(token, cellRawAttrs, opts.log);
|
|
606
812
|
|
|
607
813
|
const oldTshift = state.tShift[begin.line];
|
|
608
814
|
const oldEMark = state.eMarks[end.line];
|
|
@@ -622,7 +828,7 @@ const yfmTable: MarkdownItPluginCb<YfmTablePluginOptions> = (md, opts) => {
|
|
|
622
828
|
const content = contentToken.content.trim() || contentToken.markup.trim();
|
|
623
829
|
contentMap[i].push(content);
|
|
624
830
|
|
|
625
|
-
token = state.push('yfm_td_close',
|
|
831
|
+
token = state.push('yfm_td_close', cellTag, -1);
|
|
626
832
|
state.tokens[state.tokens.length - 1].map = [end.line, end.line + 1];
|
|
627
833
|
|
|
628
834
|
state.lineMax = oldLineMax;
|
|
@@ -631,14 +837,21 @@ const yfmTable: MarkdownItPluginCb<YfmTablePluginOptions> = (md, opts) => {
|
|
|
631
837
|
state.eMarks[end.line] = oldEMark;
|
|
632
838
|
|
|
633
839
|
const rowTokens = cellsMap[cellsMap.length - 1];
|
|
634
|
-
extractAndApplyClassFromToken(
|
|
840
|
+
extractAndApplyClassFromToken(
|
|
841
|
+
contentToken,
|
|
842
|
+
rowTokens[rowTokens.length - 1],
|
|
843
|
+
opts.log,
|
|
844
|
+
);
|
|
635
845
|
}
|
|
636
846
|
|
|
637
847
|
if (rowLength < maxRowLength) {
|
|
638
848
|
const emptyCellsCount = maxRowLength - rowLength;
|
|
639
849
|
for (let k = 0; k < emptyCellsCount; k++) {
|
|
640
|
-
token = state.push('yfm_td_open',
|
|
641
|
-
|
|
850
|
+
token = state.push('yfm_td_open', cellTag, 1);
|
|
851
|
+
if (isHeaderRow) {
|
|
852
|
+
token.attrSet('scope', 'col');
|
|
853
|
+
}
|
|
854
|
+
token = state.push('yfm_td_close', cellTag, -1);
|
|
642
855
|
}
|
|
643
856
|
}
|
|
644
857
|
|
|
@@ -251,6 +251,15 @@ function removeUnreferencedDefinitions(tokens: Token[], referencedTerms: Set<str
|
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
+
/**
|
|
255
|
+
* Eagerly initialize env.terms before the includes core rule runs
|
|
256
|
+
*/
|
|
257
|
+
function termInit(state: StateCore) {
|
|
258
|
+
if (!state.env.terms) {
|
|
259
|
+
state.env.terms = {};
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
254
263
|
const term: MarkdownItPluginCb = (md, options) => {
|
|
255
264
|
const escapeRE = md.utils.escapeRE;
|
|
256
265
|
const arrayReplaceAt = md.utils.arrayReplaceAt;
|
|
@@ -391,9 +400,12 @@ const term: MarkdownItPluginCb = (md, options) => {
|
|
|
391
400
|
}
|
|
392
401
|
}
|
|
393
402
|
|
|
394
|
-
// Remove definitions without any reference on the page
|
|
395
|
-
// Skip during linting to allow lint rules to check term definitions
|
|
396
|
-
|
|
403
|
+
// Remove definitions without any reference on the page.
|
|
404
|
+
// Skip during linting to allow lint rules to check term definitions.
|
|
405
|
+
// Skip when inside an include sub-parse (env.includes is non-empty)
|
|
406
|
+
const insideInclude = Array.isArray(state.env.includes) && state.env.includes.length > 0;
|
|
407
|
+
|
|
408
|
+
if (!isLintRun && !insideInclude) {
|
|
397
409
|
removeUnreferencedDefinitions(state.tokens, referencedTerms);
|
|
398
410
|
}
|
|
399
411
|
}
|
|
@@ -402,6 +414,10 @@ const term: MarkdownItPluginCb = (md, options) => {
|
|
|
402
414
|
alt: ['paragraph', 'reference'],
|
|
403
415
|
});
|
|
404
416
|
|
|
417
|
+
try {
|
|
418
|
+
md.core.ruler.before('includes', 'termInit', termInit);
|
|
419
|
+
} catch {}
|
|
420
|
+
|
|
405
421
|
// Register termReplace after text_join so that emphasis-split text
|
|
406
422
|
// tokens (e.g. [text](*key) where * opens a delimiter) are merged
|
|
407
423
|
// before the term regex runs. Without this, terms defined in
|