@adobe/helix-markdown-support 3.1.8 → 4.0.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.
@@ -0,0 +1,538 @@
1
+ /*
2
+ * Copyright 2022 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+ /* eslint-disable no-unused-vars,no-param-reassign */
13
+ import { text as textHandler } from 'mdast-util-to-markdown/lib/handle/text.js';
14
+ import { inlineCode } from 'mdast-util-to-markdown/lib/handle/inline-code.js';
15
+ import { code } from 'mdast-util-to-markdown/lib/handle/code.js';
16
+
17
+ import {
18
+ TYPE_BODY, TYPE_CELL, TYPE_HEADER, TYPE_FOOTER, TYPE_ROW, TYPE_TABLE,
19
+ } from './types.js';
20
+
21
+ function* distribute(size, times) {
22
+ const delta = size / times;
23
+ let len = delta;
24
+ let prevLen = 0;
25
+ for (let i = 0; i < times - 1; i += 1) {
26
+ yield [Math.round(len - prevLen), i];
27
+ prevLen = Math.round(len);
28
+ len += delta;
29
+ }
30
+ yield [Math.round(size - prevLen), times - 1];
31
+ }
32
+
33
+ function spanWidth(cols, idx, cell) {
34
+ let width = 0;
35
+ for (let i = 0; i < cell.colSpan; i += 1) {
36
+ width += cols[idx + i].width;
37
+ }
38
+ return width;
39
+ }
40
+
41
+ export function lineWrapTextHandler(node, parent, context, safeOptions) {
42
+ const textNode = {
43
+ ...node,
44
+ value: node.value.replace(/\s/g, ' '),
45
+ };
46
+ let value = textHandler(textNode, parent, context, safeOptions);
47
+ const { lineWidth } = context.options;
48
+ if (lineWidth && value.length > lineWidth) {
49
+ // check if in heading
50
+ if (context.stack.includes('headingAtx')) {
51
+ return value;
52
+ }
53
+ const lines = [];
54
+ const words = value.split(' ');
55
+ let len = safeOptions.now.column - 1;
56
+ let line = [];
57
+ for (const word of words) {
58
+ const wordLen = word.length;
59
+ if (len + wordLen > lineWidth && line.length > 0) {
60
+ lines.push(line.join(' '));
61
+ line = [];
62
+ len = 0;
63
+ }
64
+ line.push(word);
65
+ len += wordLen + 1;
66
+ }
67
+ if (line.length) {
68
+ lines.push(line.join(' '));
69
+ }
70
+ value = lines.join('\n');
71
+ }
72
+ return value;
73
+ }
74
+ // don't wrap for peek operations
75
+ lineWrapTextHandler.peek = textHandler;
76
+
77
+ class Table {
78
+ constructor() {
79
+ Object.assign(this, {
80
+ lastRow: null,
81
+ rows: [],
82
+ headerSize: 0,
83
+ footerSize: 0,
84
+ opts: {
85
+ // default desired width of a table (including delimiters)
86
+ width: 120,
87
+ // minimum cell content width (excluding delimiters)
88
+ minCellWidth: 12,
89
+ },
90
+ });
91
+ }
92
+
93
+ addHeaderRow(row) {
94
+ this.addRow(row, this.headerSize);
95
+ this.headerSize += 1;
96
+ }
97
+
98
+ addRow(cells, idx = this.rows.length - this.footerSize) {
99
+ const row = {
100
+ height: 0,
101
+ cells: [],
102
+ };
103
+ this.rows.splice(idx, 0, row);
104
+ this.lastRow = this.rows[this.rows.length - 1];
105
+ for (const cell of cells) {
106
+ this.addCell(cell, row);
107
+ }
108
+ }
109
+
110
+ addFooterRow(row) {
111
+ this.addRow(row, this.rows.length);
112
+ this.footerSize += 1;
113
+ }
114
+
115
+ addCell(cell, row) {
116
+ if (!this.lastRow) {
117
+ this.lastRow = {
118
+ height: 0,
119
+ cells: [],
120
+ };
121
+ this.rows.push(this.lastRow);
122
+ }
123
+ row = row || this.lastRow;
124
+ row.cells.push(cell);
125
+ for (let i = 1; i < cell.colSpan; i += 1) {
126
+ row.cells.push({});
127
+ }
128
+ // remember align for last span
129
+ if (cell.colSpan > 1) {
130
+ row.cells[row.cells.length - 1].align = cell.align;
131
+ }
132
+ }
133
+
134
+ renderCell(cell, context, maxWidth) {
135
+ // set line wrap to width
136
+ const oldWidth = context.options.lineWidth;
137
+ // it's easier to calculate in the padding (+2) and border (+1) here than everywhere else.
138
+ // so the column width is equal to the cell.width
139
+ context.options.lineWidth = maxWidth - 3;
140
+ context.options.minLineWidth = this.opts.minCellWidth;
141
+
142
+ // enter cell construct in order to escape unsafe characters
143
+ const exit = context.enter(TYPE_CELL);
144
+
145
+ cell.value = context.handle(cell.tree, null, context, {
146
+ before: '\n',
147
+ after: '\n',
148
+ now: { line: 1, column: 1 },
149
+ lineShift: 0,
150
+ });
151
+
152
+ exit();
153
+
154
+ context.options.lineWidth = oldWidth;
155
+ // calculate actual width and height of cell
156
+ cell.lines = cell.value.split('\n');
157
+ cell.height = cell.lines.length;
158
+ cell.width = 0;
159
+ for (const line of cell.lines) {
160
+ cell.width = Math.max(cell.width, line.length);
161
+ }
162
+ cell.width += 3;
163
+ return cell;
164
+ }
165
+
166
+ toMarkdown(context) {
167
+ // populate the matrix with the rowspans and compute max width
168
+ // (the empty cells for the colspans are already created during insert).
169
+ const cols = [];
170
+ for (let y = 0; y < this.rows.length; y += 1) {
171
+ const row = this.rows[y];
172
+ for (let x = 0; x < row.cells.length; x += 1) {
173
+ let col = cols[x];
174
+ if (!col) {
175
+ col = {
176
+ width: 3,
177
+ };
178
+ cols[x] = col;
179
+ }
180
+ const cell = row.cells[x];
181
+ if (cell.rowSpan > 1) {
182
+ // insert colspan amount of null cells below
183
+ for (let i = 1; i < cell.rowSpan; i += 1) {
184
+ const yy = i + y;
185
+ // create empty linked cells for the rows, so that it can render the lines correctly.
186
+ const empty = new Array(cell.colSpan).fill({});
187
+ empty[0] = { linked: cell };
188
+ this.rows[yy].cells.splice(x, 0, ...empty);
189
+ }
190
+ }
191
+ }
192
+ }
193
+ const numCols = cols.length;
194
+
195
+ // add empty cells if needed
196
+ for (const row of this.rows) {
197
+ for (let i = row.cells.length; i < numCols; i += 1) {
198
+ row.cells.push({ tree: { type: 'root' }, colSpan: 1, rowSpan: 1 });
199
+ }
200
+ }
201
+
202
+ // populate the columns with default max widths
203
+ for (const [d, idx] of distribute(this.opts.width, numCols)) {
204
+ cols[idx].maxWidth = d;
205
+ }
206
+
207
+ // render cells
208
+ for (const row of this.rows) {
209
+ for (let x = 0; x < row.cells.length; x += 1) {
210
+ const cell = row.cells[x];
211
+ if (cell.tree) {
212
+ // get the max width from the columns it spans
213
+ let maxWidth = 0;
214
+ for (let i = 0; i < cell.colSpan; i += 1) {
215
+ maxWidth += cols[x + i].maxWidth;
216
+ }
217
+ this.renderCell(cell, context, maxWidth);
218
+ // distribute effective cell.width among the columns it spans
219
+ for (const [avgColWidth, idx] of distribute(cell.width, cell.colSpan)) {
220
+ const col = cols[x + idx];
221
+ col.width = Math.max(col.width, avgColWidth);
222
+ }
223
+ // if valign, the col needs to be at least 4 (3 + delim) wide
224
+ if (cell.valign) {
225
+ cols[x].width = Math.max(4, cols[x].width);
226
+ }
227
+ }
228
+ }
229
+ }
230
+ // re-render cells where elements dictated the min-width (eg, large headings)
231
+ for (const row of this.rows) {
232
+ row.minHeight = 0;
233
+ row.height = 0;
234
+ for (let x = 0; x < row.cells.length; x += 1) {
235
+ const cell = row.cells[x];
236
+ if (cell.tree) {
237
+ // get the max width from the columns it spans
238
+ const width = spanWidth(cols, x, cell);
239
+ if (width >= cell.width) {
240
+ this.renderCell(cell, context, width);
241
+ // if the new cell width is bigger now (most probably due to a problem in the line
242
+ // break renderer), fix the columns.
243
+ if (cell.width > width) {
244
+ for (const [avgColWidth, idx] of distribute(cell.width, cell.colSpan)) {
245
+ const col = cols[x + idx];
246
+ col.width = Math.max(col.width, avgColWidth);
247
+ }
248
+ } else {
249
+ cell.width = width;
250
+ }
251
+ }
252
+ if (cell.rowSpan === 1) {
253
+ row.height = Math.max(row.height, cell.height);
254
+ }
255
+ }
256
+ }
257
+ }
258
+
259
+ // distribute row spans
260
+ for (let y = 0; y < this.rows.length; y += 1) {
261
+ const row = this.rows[y];
262
+ for (let x = 0; x < row.cells.length; x += 1) {
263
+ const cell = row.cells[x];
264
+ if (cell.rowSpan > 1) {
265
+ const distHeight = Math.max(cell.rowSpan, cell.height - cell.rowSpan + 1);
266
+ for (const [d, idx] of distribute(distHeight, cell.rowSpan)) {
267
+ this.rows[y + idx].height = Math.max(this.rows[y + idx].height, d);
268
+ }
269
+ }
270
+ }
271
+ }
272
+
273
+ // create grid and table
274
+ const gtVLineEnds = '+';
275
+ const gtHLineEnds = '+';
276
+ const align = {
277
+ left: { b: ':', e: '', len: 1 },
278
+ right: { b: '', e: ':', len: 1 },
279
+ center: { b: ':', e: ':', len: 2 },
280
+ justify: { b: '>', e: '<', len: 2 },
281
+ top: '^',
282
+ bottom: 'v',
283
+ middle: 'x',
284
+ };
285
+ const lines = [];
286
+ // eslint-disable-next-line no-nested-ternary
287
+ const headerIdx = this.headerSize
288
+ ? this.headerSize
289
+ : (this.footerSize ? 0 : -1);
290
+ const footerIdx = this.rows.length - this.footerSize;
291
+ for (let y = 0; y < this.rows.length; y += 1) {
292
+ const row = this.rows[y];
293
+
294
+ // first, draw the grid line
295
+ const grid = [];
296
+ const c = y === headerIdx || y === footerIdx ? '=' : '-';
297
+ let prevCell;
298
+ let pendingGrid = 0;
299
+ let pendingAlign = null;
300
+ let pendingVAlign = null;
301
+
302
+ const commitInnerGridLine = () => {
303
+ if (pendingVAlign) {
304
+ const middle = Math.floor((pendingGrid - 1) / 2);
305
+ grid.push(c.repeat(middle));
306
+ grid.push(pendingVAlign);
307
+ grid.push(c.repeat(pendingGrid - middle - 1));
308
+ } else {
309
+ grid.push(c.repeat(pendingGrid));
310
+ }
311
+ };
312
+
313
+ const commitGridLine = () => {
314
+ if (pendingGrid) {
315
+ if (pendingAlign) {
316
+ pendingGrid -= pendingAlign.len;
317
+ grid.push(pendingAlign.b);
318
+ commitInnerGridLine();
319
+ grid.push(pendingAlign.e);
320
+ } else {
321
+ commitInnerGridLine();
322
+ }
323
+ pendingGrid = 0;
324
+ }
325
+ };
326
+
327
+ for (let x = 0; x < row.cells.length; x += 1) {
328
+ let d0 = '+';
329
+ if (x === 0 && y > 0) {
330
+ d0 = gtHLineEnds;
331
+ }
332
+ if (y === 0 && x > 0) {
333
+ d0 = gtVLineEnds;
334
+ }
335
+ const cell = row.cells[x];
336
+ const col = cols[x];
337
+ if (cell.tree) {
338
+ commitGridLine();
339
+ grid.push(d0);
340
+ pendingGrid = col.width - 1;
341
+ pendingAlign = align[cell.align];
342
+ pendingVAlign = align[cell.valign];
343
+ } else if (cell.linked) {
344
+ commitGridLine();
345
+ const width = spanWidth(cols, x, cell.linked);
346
+ const text = cell.linked.lines.shift() || '';
347
+ grid.push(`| ${text.padEnd(width - 3, ' ')} `);
348
+ x += cell.linked.colSpan - 1;
349
+ } else {
350
+ pendingGrid += col.width;
351
+ }
352
+ prevCell = cell;
353
+ }
354
+ commitGridLine();
355
+
356
+ // if last col was a rowspan, draw a |
357
+ let d3 = prevCell?.linked ? '|' : gtHLineEnds;
358
+ if (y === 0) {
359
+ d3 = '+';
360
+ }
361
+ lines.push(`${grid.join('')}${d3}`);
362
+
363
+ // then draw the cells
364
+ for (let yy = 0; yy < row.height; yy += 1) {
365
+ const line = [];
366
+ for (let x = 0; x < row.cells.length; x += 1) {
367
+ let cell = row.cells[x];
368
+ if (cell.linked) {
369
+ cell = cell.linked;
370
+ }
371
+ if (cell.tree) {
372
+ const width = spanWidth(cols, x, cell);
373
+ let text = '';
374
+ if (!cell.valign
375
+ || cell.valign === 'top'
376
+ || (cell.valign === 'middle' && yy >= Math.floor(row.height - cell.height) / 2)
377
+ || (cell.valign === 'bottom' && yy >= row.height - cell.height)) {
378
+ text = cell.lines.shift() || '';
379
+ }
380
+ line.push(`| ${text.padEnd(width - 3, ' ')} `);
381
+ }
382
+ }
383
+ lines.push(`${line.join('')}|`);
384
+ }
385
+ }
386
+
387
+ // add last grid line
388
+ const grid = [];
389
+ const lastRow = this.rows[this.rows.length - 1];
390
+ for (let x = 0; x < cols.length; x += 1) {
391
+ const col = cols[x];
392
+ // if the cell above was a colspan, and we are on the last line, don't draw the `+`
393
+ const aboveCell = lastRow.cells[x];
394
+ let c = aboveCell.tree || aboveCell.linked ? gtVLineEnds : '-';
395
+ if (x === 0) {
396
+ c = '+';
397
+ }
398
+ grid.push(`${c}${'-'.repeat(col.width - 1)}`);
399
+ }
400
+ lines.push(`${grid.join('')}+`);
401
+
402
+ return lines.join('\n');
403
+ }
404
+ }
405
+
406
+ function pushTable(context, table) {
407
+ if (!context.gridTables) {
408
+ context.gridTables = [];
409
+ }
410
+ context.gridTables.push(table);
411
+ return table;
412
+ }
413
+
414
+ function popTable(context) {
415
+ return context.gridTables.pop();
416
+ }
417
+
418
+ function peekTable(context) {
419
+ return context.gridTables[context.gridTables.length - 1];
420
+ }
421
+
422
+ function handleCell(node, parent, context, safeOptions) {
423
+ return {
424
+ tree: {
425
+ type: 'root',
426
+ children: node.children,
427
+ },
428
+ colSpan: node.colSpan || 1,
429
+ rowSpan: node.rowSpan || 1,
430
+ align: node.align,
431
+ valign: node.valign,
432
+ };
433
+ }
434
+
435
+ function handleRow(node, parent, context, safeOptions) {
436
+ const row = [];
437
+ for (const child of node.children) {
438
+ if (child.type === TYPE_CELL) {
439
+ row.push(handleCell(child, node, context, safeOptions));
440
+ }
441
+ }
442
+ return row;
443
+ }
444
+
445
+ function handleHeader(node, parent, context, safeOptions) {
446
+ const table = peekTable(context);
447
+ for (const child of node.children) {
448
+ if (child.type === TYPE_ROW) {
449
+ table.addHeaderRow(handleRow(child, node, context, safeOptions));
450
+ }
451
+ }
452
+ }
453
+
454
+ function handleBody(node, parent, context, safeOptions) {
455
+ const table = peekTable(context);
456
+ for (const child of node.children) {
457
+ if (child.type === TYPE_ROW) {
458
+ table.addRow(handleRow(child, node, context, safeOptions));
459
+ }
460
+ }
461
+ }
462
+
463
+ function handleFooter(node, parent, context, safeOptions) {
464
+ const table = peekTable(context);
465
+ for (const child of node.children) {
466
+ if (child.type === TYPE_ROW) {
467
+ table.addFooterRow(handleRow(child, node, context, safeOptions));
468
+ }
469
+ }
470
+ }
471
+
472
+ function gridTable(node, parent, context, safeOptions) {
473
+ const exit = context.enter(TYPE_TABLE);
474
+
475
+ const table = pushTable(context, new Table());
476
+
477
+ for (const child of node.children) {
478
+ if (child.type === TYPE_HEADER) {
479
+ handleHeader(child, node, context, safeOptions);
480
+ } else if (child.type === TYPE_BODY) {
481
+ handleBody(child, node, context, safeOptions);
482
+ } else if (child.type === TYPE_FOOTER) {
483
+ handleFooter(child, node, context, safeOptions);
484
+ } else if (child.type === TYPE_ROW) {
485
+ table.addRow(handleRow(child, node, context, safeOptions));
486
+ } else if (child.type === TYPE_CELL) {
487
+ table.addCell(handleCell(child, node, context, safeOptions));
488
+ }
489
+ }
490
+
491
+ exit();
492
+
493
+ return popTable(context).toMarkdown(context);
494
+ }
495
+
496
+ /**
497
+ * Escapes cell delimiters in (block)) code
498
+ */
499
+ function blockCodeWithTable(node, parent, context) {
500
+ let value = code(node, parent, context);
501
+
502
+ if (context.stack.includes(TYPE_CELL)) {
503
+ value = value.replace(/[|+]/mg, '\\$&');
504
+ }
505
+
506
+ return value;
507
+ }
508
+
509
+ /**
510
+ * Escapes cell delimiters in inline code
511
+ */
512
+ function inlineCodeWithTable(node, parent, context) {
513
+ let value = inlineCode(node, parent, context);
514
+
515
+ if (context.stack.includes(TYPE_CELL)) {
516
+ value = value.replace(/[|+]/g, '\\$&');
517
+ }
518
+
519
+ return value;
520
+ }
521
+
522
+ export default function toMarkdown() {
523
+ return {
524
+ unsafe: [
525
+ // A pipe or a + in a cell must be encoded.
526
+ { character: '|', inConstruct: TYPE_CELL },
527
+ { character: '+', inConstruct: TYPE_CELL },
528
+ ],
529
+ handlers: {
530
+ // for now, we only line wrap 'text' nodes. all other would need more support in
531
+ // the default mdast-to-markdown handlers
532
+ text: lineWrapTextHandler,
533
+ gridTable,
534
+ inlineCode: inlineCodeWithTable,
535
+ code: blockCodeWithTable,
536
+ },
537
+ };
538
+ }
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright 2022 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+ export const TYPE_TABLE = 'gridTable';
13
+ export const TYPE_HEADER = 'gtHeader';
14
+ export const TYPE_BODY = 'gtBody';
15
+ export const TYPE_FOOTER = 'gtFooter';
16
+ export const TYPE_ROW = 'gtRow';
17
+ export const TYPE_CELL = 'gtCell';
package/src/index.js CHANGED
@@ -10,7 +10,6 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- export { default as remarkMatter } from './remark-matter/index.js';
14
13
  export { default as robustTables } from './mdast-robust-tables.js';
15
14
  export { default as breaksAsSpaces } from './remark-breaks-as-spaces.js';
16
15
  export { default as sanitizeHeading } from './mdast-sanitize-heading.js';
@@ -19,3 +18,5 @@ export { default as sanitizeFormats } from './mdast-sanitize-formats.js';
19
18
  export { default as fixCodeFlow } from './mdast-fix-code-flow.js';
20
19
  export { default as sanitizeLinks } from './mdast-sanitize-links.js';
21
20
  export { default as sanitizeText } from './mdast-sanitize-text.js';
21
+ export { default as imageReferences } from './mdast-image-references.js';
22
+ export { default as dereference } from './mdast-dereference.js';
@@ -10,9 +10,10 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
  import jsYaml from 'js-yaml';
13
+ import { TYPE_YAML } from './types.js';
13
14
 
14
15
  function open(token) {
15
- this.enter({ type: 'yaml', value: '', payload: {} }, token);
16
+ this.enter({ type: TYPE_YAML, value: '', payload: {} }, token);
16
17
  this.buffer();
17
18
  }
18
19
 
@@ -41,10 +42,10 @@ function value(token) {
41
42
  export default function fromMarkdown(options = {}) {
42
43
  return {
43
44
  enter: {
44
- yaml: open,
45
+ [TYPE_YAML]: open,
45
46
  },
46
47
  exit: {
47
- yaml: createClose(options),
48
+ [TYPE_YAML]: createClose(options),
48
49
  yamlValue: value,
49
50
  },
50
51
  };
@@ -9,9 +9,6 @@
9
9
  * OF ANY KIND, either express or implied. See the License for the specific language
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
- import fromMarkdown from './from-markdown.js';
13
- import toMarkdown from './to-markdown.js';
14
- import syntax from './syntax.js';
15
12
 
16
13
  /**
17
14
  * Front- and mid-matter remark plugin.
@@ -83,19 +80,5 @@ import syntax from './syntax.js';
83
80
  * @param {object} options Plugin options
84
81
  * @param {Function} options.errorHandler Function that is invoked on yaml parsing errors.
85
82
  */
86
- export default function matterPlugin(options) {
87
- const data = this.data();
88
-
89
- function add(field, value) {
90
- /* c8 ignore next 2 */
91
- if (data[field]) {
92
- data[field].push(value);
93
- } else {
94
- data[field] = [value];
95
- }
96
- }
97
-
98
- add('micromarkExtensions', syntax(options));
99
- add('fromMarkdownExtensions', fromMarkdown(options));
100
- add('toMarkdownExtensions', toMarkdown(options));
101
- }
83
+ export * from './types.js';
84
+ export { default as remarkMatter } from './remark-plugin.js';
@@ -0,0 +1,31 @@
1
+ /*
2
+ * Copyright 2018 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+ import fromMarkdown from './from-markdown.js';
13
+ import toMarkdown from './to-markdown.js';
14
+ import syntax from './syntax.js';
15
+
16
+ export default function remarkPlugin(options) {
17
+ const data = this.data();
18
+
19
+ function add(field, value) {
20
+ /* c8 ignore next 2 */
21
+ if (data[field]) {
22
+ data[field].push(value);
23
+ } else {
24
+ data[field] = [value];
25
+ }
26
+ }
27
+
28
+ add('micromarkExtensions', syntax(options));
29
+ add('fromMarkdownExtensions', fromMarkdown(options));
30
+ add('toMarkdownExtensions', toMarkdown(options));
31
+ }
@@ -14,6 +14,7 @@ import jsYaml from 'js-yaml';
14
14
  import { codes } from 'micromark-util-symbol/codes.js';
15
15
  import { types } from 'micromark-util-symbol/types.js';
16
16
  import { markdownLineEnding, markdownSpace } from 'micromark-util-character';
17
+ import { TYPE_YAML } from './types.js';
17
18
 
18
19
  const type = (v) => ((v !== undefined && v !== null) ? v.constructor : v);
19
20
 
@@ -94,7 +95,7 @@ function parse(options) {
94
95
  }
95
96
  }
96
97
 
97
- effects.enter('yaml');
98
+ effects.enter(TYPE_YAML);
98
99
 
99
100
  // after the fence `---` is detected, we are at the end of the line
100
101
  return effects.attempt(fenceConstruct, lineEnd, nok)(code);
@@ -127,7 +128,7 @@ function parse(options) {
127
128
 
128
129
  function closedFence(code) {
129
130
  // check if valid yaml
130
- const token = effects.exit('yaml');
131
+ const token = effects.exit(TYPE_YAML);
131
132
  let yamlString = self.sliceSerialize(token).trim();
132
133
  // remove fences
133
134
  yamlString = yamlString.substring(4, yamlString.length - 3).trim();
@@ -9,10 +9,12 @@
9
9
  * OF ANY KIND, either express or implied. See the License for the specific language
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
+ import { TYPE_YAML } from './types.js';
13
+
12
14
  export default function toMarkdown() {
13
15
  return {
14
16
  handlers: {
15
- yaml: (node) => `---\n${node.value.trim()}\n---`,
17
+ [TYPE_YAML]: (node) => `---\n${node.value.trim()}\n---`,
16
18
  },
17
19
  };
18
20
  }