@milkdown/preset-gfm 7.15.5 → 7.16.0
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/lib/index.js +11 -309
- package/lib/index.js.map +1 -1
- package/lib/node/table/command.d.ts.map +1 -1
- package/lib/node/table/utils/get-all-cells-in-table.d.ts.map +1 -1
- package/lib/node/table/utils/get-cells-in-col.d.ts.map +1 -1
- package/lib/node/table/utils/get-cells-in-row.d.ts.map +1 -1
- package/lib/node/table/utils/index.d.ts +0 -3
- package/lib/node/table/utils/index.d.ts.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -9
- package/src/node/table/command.ts +12 -36
- package/src/node/table/utils/get-all-cells-in-table.ts +1 -3
- package/src/node/table/utils/get-cells-in-col.ts +1 -3
- package/src/node/table/utils/get-cells-in-row.ts +1 -3
- package/src/node/table/utils/index.ts +0 -3
- package/lib/node/table/utils/convert-rows-to-table.d.ts +0 -3
- package/lib/node/table/utils/convert-rows-to-table.d.ts.map +0 -1
- package/lib/node/table/utils/convert-table-to-rows.d.ts +0 -3
- package/lib/node/table/utils/convert-table-to-rows.d.ts.map +0 -1
- package/lib/node/table/utils/find-table.d.ts +0 -3
- package/lib/node/table/utils/find-table.d.ts.map +0 -1
- package/lib/node/table/utils/get-selection-range-in-col.d.ts +0 -4
- package/lib/node/table/utils/get-selection-range-in-col.d.ts.map +0 -1
- package/lib/node/table/utils/get-selection-range-in-row.d.ts +0 -4
- package/lib/node/table/utils/get-selection-range-in-row.d.ts.map +0 -1
- package/lib/node/table/utils/move-col.d.ts +0 -10
- package/lib/node/table/utils/move-col.d.ts.map +0 -1
- package/lib/node/table/utils/move-row-in-array-of-rows.d.ts +0 -3
- package/lib/node/table/utils/move-row-in-array-of-rows.d.ts.map +0 -1
- package/lib/node/table/utils/move-row.d.ts +0 -10
- package/lib/node/table/utils/move-row.d.ts.map +0 -1
- package/lib/node/table/utils/transpose.d.ts +0 -2
- package/lib/node/table/utils/transpose.d.ts.map +0 -1
- package/src/node/table/utils/convert-rows-to-table.ts +0 -43
- package/src/node/table/utils/convert-table-to-rows.ts +0 -65
- package/src/node/table/utils/find-table.ts +0 -10
- package/src/node/table/utils/get-selection-range-in-col.ts +0 -86
- package/src/node/table/utils/get-selection-range-in-row.ts +0 -86
- package/src/node/table/utils/move-col.ts +0 -73
- package/src/node/table/utils/move-row-in-array-of-rows.ts +0 -29
- package/src/node/table/utils/move-row.ts +0 -71
- package/src/node/table/utils/transpose.ts +0 -26
package/lib/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { expectDomTypeError } from "@milkdown/exception";
|
|
|
2
2
|
import { paragraphSchema, listItemSchema } from "@milkdown/preset-commonmark";
|
|
3
3
|
import { InputRule } from "@milkdown/prose/inputrules";
|
|
4
4
|
import { $markAttr, $markSchema, $inputRule, $useKeymap, $command, $nodeSchema, $prose, $remark } from "@milkdown/utils";
|
|
5
|
-
import { tableNodes, TableMap, CellSelection, goToNextCell, isInTable, deleteTable, deleteColumn, deleteRow, selectedRect, addColumnBefore, addColumnAfter, setCellAttr, columnResizing, tableEditing } from "@milkdown/prose/tables";
|
|
5
|
+
import { tableNodes, findTable, TableMap, CellSelection, goToNextCell, isInTable, moveTableRow, moveTableColumn, deleteTable, deleteColumn, deleteRow, selectedRect, addColumnBefore, addColumnAfter, setCellAttr, columnResizing, tableEditing } from "@milkdown/prose/tables";
|
|
6
6
|
import { commandsCtx } from "@milkdown/core";
|
|
7
7
|
import { markRule, findParentNodeClosestToPos, cloneTr, findParentNodeType } from "@milkdown/prose";
|
|
8
8
|
import { toggleMark } from "@milkdown/prose/commands";
|
|
@@ -286,11 +286,6 @@ function createTable(ctx, rowsCount = 3, colsCount = 3) {
|
|
|
286
286
|
);
|
|
287
287
|
return tableSchema.type(ctx).create(null, rows);
|
|
288
288
|
}
|
|
289
|
-
function findTable($pos) {
|
|
290
|
-
return findParentNodeClosestToPos(
|
|
291
|
-
(node) => node.type.spec.tableRole === "table"
|
|
292
|
-
)($pos);
|
|
293
|
-
}
|
|
294
289
|
function getCellsInCol(columnIndexes, selection) {
|
|
295
290
|
const table = findTable(selection.$from);
|
|
296
291
|
if (!table) return void 0;
|
|
@@ -382,278 +377,6 @@ function addRowWithAlignment(ctx, tr, { map, tableStart, table }, row) {
|
|
|
382
377
|
tr.insert(rowPos, tableRowSchema.type(ctx).create(null, cells));
|
|
383
378
|
return tr;
|
|
384
379
|
}
|
|
385
|
-
function convertRowsToTable(tableNode, arrayOfNodes) {
|
|
386
|
-
const rowsPM = [];
|
|
387
|
-
const map = TableMap.get(tableNode);
|
|
388
|
-
for (let rowIndex = 0; rowIndex < map.height; rowIndex++) {
|
|
389
|
-
const row = tableNode.child(rowIndex);
|
|
390
|
-
const rowCells = [];
|
|
391
|
-
for (let colIndex = 0; colIndex < map.width; colIndex++) {
|
|
392
|
-
if (!arrayOfNodes[rowIndex][colIndex]) continue;
|
|
393
|
-
const cellPos = map.map[rowIndex * map.width + colIndex];
|
|
394
|
-
const cell = arrayOfNodes[rowIndex][colIndex];
|
|
395
|
-
const oldCell = tableNode.nodeAt(cellPos);
|
|
396
|
-
const newCell = oldCell.type.createChecked(
|
|
397
|
-
Object.assign({}, cell.attrs),
|
|
398
|
-
cell.content,
|
|
399
|
-
cell.marks
|
|
400
|
-
);
|
|
401
|
-
rowCells.push(newCell);
|
|
402
|
-
}
|
|
403
|
-
rowsPM.push(row.type.createChecked(row.attrs, rowCells, row.marks));
|
|
404
|
-
}
|
|
405
|
-
const newTable = tableNode.type.createChecked(
|
|
406
|
-
tableNode.attrs,
|
|
407
|
-
rowsPM,
|
|
408
|
-
tableNode.marks
|
|
409
|
-
);
|
|
410
|
-
return newTable;
|
|
411
|
-
}
|
|
412
|
-
function convertTableToRows(tableNode) {
|
|
413
|
-
const map = TableMap.get(tableNode);
|
|
414
|
-
const rows = [];
|
|
415
|
-
const rowCount = map.height;
|
|
416
|
-
const colCount = map.width;
|
|
417
|
-
for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
|
|
418
|
-
const row = [];
|
|
419
|
-
for (let colIndex = 0; colIndex < colCount; colIndex++) {
|
|
420
|
-
let cellIndex = rowIndex * colCount + colIndex;
|
|
421
|
-
let cellPos = map.map[cellIndex];
|
|
422
|
-
if (rowIndex > 0) {
|
|
423
|
-
const topCellIndex = cellIndex - colCount;
|
|
424
|
-
const topCellPos = map.map[topCellIndex];
|
|
425
|
-
if (cellPos === topCellPos) {
|
|
426
|
-
row.push(null);
|
|
427
|
-
continue;
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
if (colIndex > 0) {
|
|
431
|
-
const leftCellIndex = cellIndex - 1;
|
|
432
|
-
const leftCellPos = map.map[leftCellIndex];
|
|
433
|
-
if (cellPos === leftCellPos) {
|
|
434
|
-
row.push(null);
|
|
435
|
-
continue;
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
if (!cellPos) {
|
|
439
|
-
row.push(null);
|
|
440
|
-
} else {
|
|
441
|
-
row.push(tableNode.nodeAt(cellPos));
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
rows.push(row);
|
|
445
|
-
}
|
|
446
|
-
return rows;
|
|
447
|
-
}
|
|
448
|
-
function getSelectionRangeInRow(tr, startRowIndex, endRowIndex = startRowIndex) {
|
|
449
|
-
let startIndex = startRowIndex;
|
|
450
|
-
let endIndex = endRowIndex;
|
|
451
|
-
for (let i = startRowIndex; i >= 0; i--) {
|
|
452
|
-
const cells = getCellsInRow(i, tr.selection);
|
|
453
|
-
if (cells) {
|
|
454
|
-
cells.forEach((cell) => {
|
|
455
|
-
const maybeEndIndex = cell.node.attrs.rowspan + i - 1;
|
|
456
|
-
if (maybeEndIndex >= startIndex) {
|
|
457
|
-
startIndex = i;
|
|
458
|
-
}
|
|
459
|
-
if (maybeEndIndex > endIndex) {
|
|
460
|
-
endIndex = maybeEndIndex;
|
|
461
|
-
}
|
|
462
|
-
});
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
for (let i = startRowIndex; i <= endIndex; i++) {
|
|
466
|
-
const cells = getCellsInRow(i, tr.selection);
|
|
467
|
-
if (cells) {
|
|
468
|
-
cells.forEach((cell) => {
|
|
469
|
-
const maybeEndIndex = cell.node.attrs.rowspan + i - 1;
|
|
470
|
-
if (cell.node.attrs.rowspan > 1 && maybeEndIndex > endIndex) {
|
|
471
|
-
endIndex = maybeEndIndex;
|
|
472
|
-
}
|
|
473
|
-
});
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
const indexes = [];
|
|
477
|
-
for (let i = startIndex; i <= endIndex; i++) {
|
|
478
|
-
const maybeCells = getCellsInRow(i, tr.selection);
|
|
479
|
-
if (maybeCells && maybeCells.length > 0) {
|
|
480
|
-
indexes.push(i);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
startIndex = indexes[0];
|
|
484
|
-
endIndex = indexes[indexes.length - 1];
|
|
485
|
-
const firstSelectedRowCells = getCellsInRow(startIndex, tr.selection);
|
|
486
|
-
const firstColumnCells = getCellsInCol(0, tr.selection);
|
|
487
|
-
if (!firstSelectedRowCells || !firstColumnCells) {
|
|
488
|
-
return;
|
|
489
|
-
}
|
|
490
|
-
const $anchor = tr.doc.resolve(
|
|
491
|
-
firstSelectedRowCells[firstSelectedRowCells.length - 1].pos
|
|
492
|
-
);
|
|
493
|
-
let headCell;
|
|
494
|
-
for (let i = endIndex; i >= startIndex; i--) {
|
|
495
|
-
const rowCells = getCellsInRow(i, tr.selection);
|
|
496
|
-
if (rowCells && rowCells.length > 0) {
|
|
497
|
-
for (let j = firstColumnCells.length - 1; j >= 0; j--) {
|
|
498
|
-
if (firstColumnCells[j].pos === rowCells[0].pos) {
|
|
499
|
-
headCell = rowCells[0];
|
|
500
|
-
break;
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
if (headCell) {
|
|
504
|
-
break;
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
if (!headCell) {
|
|
509
|
-
return;
|
|
510
|
-
}
|
|
511
|
-
const $head = tr.doc.resolve(headCell.pos);
|
|
512
|
-
return { $anchor, $head, indexes };
|
|
513
|
-
}
|
|
514
|
-
function moveRowInArrayOfRows(rows, indexesOrigin, indexesTarget, directionOverride) {
|
|
515
|
-
const direction = indexesOrigin[0] > indexesTarget[0] ? -1 : 1;
|
|
516
|
-
const rowsExtracted = rows.splice(indexesOrigin[0], indexesOrigin.length);
|
|
517
|
-
const positionOffset = rowsExtracted.length % 2 === 0 ? 1 : 0;
|
|
518
|
-
let target;
|
|
519
|
-
{
|
|
520
|
-
target = direction === -1 ? indexesTarget[0] : indexesTarget[indexesTarget.length - 1] - positionOffset;
|
|
521
|
-
}
|
|
522
|
-
rows.splice(target, 0, ...rowsExtracted);
|
|
523
|
-
return rows;
|
|
524
|
-
}
|
|
525
|
-
function moveRow(moveRowParams) {
|
|
526
|
-
const { tr, origin, target, select, pos } = moveRowParams;
|
|
527
|
-
const $pos = tr.doc.resolve(pos);
|
|
528
|
-
const table = findTable($pos);
|
|
529
|
-
if (!table) return false;
|
|
530
|
-
const indexesOriginRow = getSelectionRangeInRow(tr, origin)?.indexes;
|
|
531
|
-
const indexesTargetRow = getSelectionRangeInRow(tr, target)?.indexes;
|
|
532
|
-
if (!indexesOriginRow || !indexesTargetRow) return false;
|
|
533
|
-
if (indexesOriginRow.includes(target)) return false;
|
|
534
|
-
const newTable = moveTableRow(
|
|
535
|
-
table.node,
|
|
536
|
-
indexesOriginRow,
|
|
537
|
-
indexesTargetRow
|
|
538
|
-
);
|
|
539
|
-
tr.replaceWith(table.pos, table.pos + table.node.nodeSize, newTable);
|
|
540
|
-
if (!select) return true;
|
|
541
|
-
const map = TableMap.get(newTable);
|
|
542
|
-
const start = table.start;
|
|
543
|
-
const index = target;
|
|
544
|
-
const lastCell = map.positionAt(index, map.width - 1, newTable);
|
|
545
|
-
const $lastCell = tr.doc.resolve(start + lastCell);
|
|
546
|
-
const firstCell = map.positionAt(index, 0, newTable);
|
|
547
|
-
const $firstCell = tr.doc.resolve(start + firstCell);
|
|
548
|
-
tr.setSelection(CellSelection.rowSelection($lastCell, $firstCell));
|
|
549
|
-
return true;
|
|
550
|
-
}
|
|
551
|
-
function moveTableRow(table, indexesOrigin, indexesTarget, direction) {
|
|
552
|
-
let rows = convertTableToRows(table);
|
|
553
|
-
rows = moveRowInArrayOfRows(rows, indexesOrigin, indexesTarget);
|
|
554
|
-
return convertRowsToTable(table, rows);
|
|
555
|
-
}
|
|
556
|
-
function getSelectionRangeInCol(tr, startColIndex, endColIndex = startColIndex) {
|
|
557
|
-
let startIndex = startColIndex;
|
|
558
|
-
let endIndex = endColIndex;
|
|
559
|
-
for (let i = startColIndex; i >= 0; i--) {
|
|
560
|
-
const cells = getCellsInCol(i, tr.selection);
|
|
561
|
-
if (cells) {
|
|
562
|
-
cells.forEach((cell) => {
|
|
563
|
-
const maybeEndIndex = cell.node.attrs.colspan + i - 1;
|
|
564
|
-
if (maybeEndIndex >= startIndex) {
|
|
565
|
-
startIndex = i;
|
|
566
|
-
}
|
|
567
|
-
if (maybeEndIndex > endIndex) {
|
|
568
|
-
endIndex = maybeEndIndex;
|
|
569
|
-
}
|
|
570
|
-
});
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
for (let i = startColIndex; i <= endIndex; i++) {
|
|
574
|
-
const cells = getCellsInCol(i, tr.selection);
|
|
575
|
-
if (cells) {
|
|
576
|
-
cells.forEach((cell) => {
|
|
577
|
-
const maybeEndIndex = cell.node.attrs.colspan + i - 1;
|
|
578
|
-
if (cell.node.attrs.colspan > 1 && maybeEndIndex > endIndex) {
|
|
579
|
-
endIndex = maybeEndIndex;
|
|
580
|
-
}
|
|
581
|
-
});
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
const indexes = [];
|
|
585
|
-
for (let i = startIndex; i <= endIndex; i++) {
|
|
586
|
-
const maybeCells = getCellsInCol(i, tr.selection);
|
|
587
|
-
if (maybeCells && maybeCells.length > 0) {
|
|
588
|
-
indexes.push(i);
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
startIndex = indexes[0];
|
|
592
|
-
endIndex = indexes[indexes.length - 1];
|
|
593
|
-
const firstSelectedColumnCells = getCellsInCol(startIndex, tr.selection);
|
|
594
|
-
const firstRowCells = getCellsInRow(0, tr.selection);
|
|
595
|
-
if (!firstSelectedColumnCells || !firstRowCells) {
|
|
596
|
-
return;
|
|
597
|
-
}
|
|
598
|
-
const $anchor = tr.doc.resolve(
|
|
599
|
-
firstSelectedColumnCells[firstSelectedColumnCells.length - 1].pos
|
|
600
|
-
);
|
|
601
|
-
let headCell;
|
|
602
|
-
for (let i = endIndex; i >= startIndex; i--) {
|
|
603
|
-
const columnCells = getCellsInCol(i, tr.selection);
|
|
604
|
-
if (columnCells && columnCells.length > 0) {
|
|
605
|
-
for (let j = firstRowCells.length - 1; j >= 0; j--) {
|
|
606
|
-
if (firstRowCells[j].pos === columnCells[0].pos) {
|
|
607
|
-
headCell = columnCells[0];
|
|
608
|
-
break;
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
if (headCell) {
|
|
612
|
-
break;
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
if (!headCell) {
|
|
617
|
-
return;
|
|
618
|
-
}
|
|
619
|
-
const $head = tr.doc.resolve(headCell.pos);
|
|
620
|
-
return { $anchor, $head, indexes };
|
|
621
|
-
}
|
|
622
|
-
function transpose(array) {
|
|
623
|
-
return array[0].map((_, i) => array.map((column) => column[i]));
|
|
624
|
-
}
|
|
625
|
-
function moveCol(moveColParams) {
|
|
626
|
-
const { tr, origin, target, select, pos } = moveColParams;
|
|
627
|
-
const $pos = tr.doc.resolve(pos);
|
|
628
|
-
const table = findTable($pos);
|
|
629
|
-
if (!table) return false;
|
|
630
|
-
const indexesOriginColumn = getSelectionRangeInCol(tr, origin)?.indexes;
|
|
631
|
-
const indexesTargetColumn = getSelectionRangeInCol(tr, target)?.indexes;
|
|
632
|
-
if (!indexesOriginColumn || !indexesTargetColumn) return false;
|
|
633
|
-
if (indexesOriginColumn.includes(target)) return false;
|
|
634
|
-
const newTable = moveTableCol(
|
|
635
|
-
table.node,
|
|
636
|
-
indexesOriginColumn,
|
|
637
|
-
indexesTargetColumn
|
|
638
|
-
);
|
|
639
|
-
tr.replaceWith(table.pos, table.pos + table.node.nodeSize, newTable);
|
|
640
|
-
if (!select) return true;
|
|
641
|
-
const map = TableMap.get(newTable);
|
|
642
|
-
const start = table.start;
|
|
643
|
-
const index = target;
|
|
644
|
-
const lastCell = map.positionAt(map.height - 1, index, newTable);
|
|
645
|
-
const $lastCell = tr.doc.resolve(start + lastCell);
|
|
646
|
-
const firstCell = map.positionAt(0, index, newTable);
|
|
647
|
-
const $firstCell = tr.doc.resolve(start + firstCell);
|
|
648
|
-
tr.setSelection(CellSelection.colSelection($lastCell, $firstCell));
|
|
649
|
-
return true;
|
|
650
|
-
}
|
|
651
|
-
function moveTableCol(table, indexesOrigin, indexesTarget, direction) {
|
|
652
|
-
let rows = transpose(convertTableToRows(table));
|
|
653
|
-
rows = moveRowInArrayOfRows(rows, indexesOrigin, indexesTarget);
|
|
654
|
-
rows = transpose(rows);
|
|
655
|
-
return convertRowsToTable(table, rows);
|
|
656
|
-
}
|
|
657
380
|
function getAllCellsInTable(selection) {
|
|
658
381
|
const table = findTable(selection.$from);
|
|
659
382
|
if (!table) return;
|
|
@@ -739,20 +462,11 @@ withMeta(insertTableCommand, {
|
|
|
739
462
|
});
|
|
740
463
|
const moveRowCommand = $command(
|
|
741
464
|
"MoveRow",
|
|
742
|
-
() => ({ from, to, pos } = {}) => (
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
target: to ?? 0,
|
|
748
|
-
pos: pos ?? state.selection.from,
|
|
749
|
-
select: true
|
|
750
|
-
})) {
|
|
751
|
-
dispatch?.(tr);
|
|
752
|
-
return true;
|
|
753
|
-
}
|
|
754
|
-
return false;
|
|
755
|
-
}
|
|
465
|
+
() => ({ from, to, pos } = {}) => moveTableRow({
|
|
466
|
+
from: from ?? 0,
|
|
467
|
+
to: to ?? 0,
|
|
468
|
+
pos
|
|
469
|
+
})
|
|
756
470
|
);
|
|
757
471
|
withMeta(moveRowCommand, {
|
|
758
472
|
displayName: "Command<moveRowCommand>",
|
|
@@ -760,20 +474,11 @@ withMeta(moveRowCommand, {
|
|
|
760
474
|
});
|
|
761
475
|
const moveColCommand = $command(
|
|
762
476
|
"MoveCol",
|
|
763
|
-
() => ({ from, to, pos } = {}) => (
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
target: to ?? 0,
|
|
769
|
-
pos: pos ?? state.selection.from,
|
|
770
|
-
select: true
|
|
771
|
-
})) {
|
|
772
|
-
dispatch?.(tr);
|
|
773
|
-
return true;
|
|
774
|
-
}
|
|
775
|
-
return false;
|
|
776
|
-
}
|
|
477
|
+
() => ({ from, to, pos } = {}) => moveTableColumn({
|
|
478
|
+
from: from ?? 0,
|
|
479
|
+
to: to ?? 0,
|
|
480
|
+
pos
|
|
481
|
+
})
|
|
777
482
|
);
|
|
778
483
|
withMeta(moveColCommand, {
|
|
779
484
|
displayName: "Command<moveColCommand>",
|
|
@@ -1317,7 +1022,6 @@ export {
|
|
|
1317
1022
|
deleteSelectedCellsCommand,
|
|
1318
1023
|
exitTable,
|
|
1319
1024
|
extendListItemSchemaForTask,
|
|
1320
|
-
findTable,
|
|
1321
1025
|
footnoteDefinitionSchema,
|
|
1322
1026
|
footnoteReferenceSchema,
|
|
1323
1027
|
getAllCellsInTable,
|
|
@@ -1332,9 +1036,7 @@ export {
|
|
|
1332
1036
|
keepTableAlignPlugin,
|
|
1333
1037
|
keymap,
|
|
1334
1038
|
markInputRules,
|
|
1335
|
-
moveCol,
|
|
1336
1039
|
moveColCommand,
|
|
1337
|
-
moveRow,
|
|
1338
1040
|
moveRowCommand,
|
|
1339
1041
|
plugins,
|
|
1340
1042
|
remarkGFMPlugin,
|