markdown-to-jsx 6.10.1 → 6.11.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/README.md +22 -3
- package/dist/cjs.js +1 -1
- package/dist/cjs.js.map +1 -1
- package/dist/esm.js +1 -1
- package/dist/esm.js.map +1 -1
- package/index.js +119 -85
- package/package.json +2 -2
package/index.js
CHANGED
|
@@ -167,11 +167,12 @@ const REFERENCE_LINK_R = /^\[([^\]]*)\] ?\[([^\]]*)\]/;
|
|
|
167
167
|
const SQUARE_BRACKETS_R = /(\[|\])/g;
|
|
168
168
|
const SHOULD_RENDER_AS_BLOCK_R = /(\n|^[-*]\s|^#|^ {2,}|^-{2,}|^>\s)/;
|
|
169
169
|
const TAB_R = /\t/g;
|
|
170
|
+
const TABLE_SEPARATOR_R = /^ *\| */;
|
|
170
171
|
const TABLE_TRIM_PIPES = /(^ *\||\| *$)/g;
|
|
172
|
+
const TABLE_CELL_END_TRIM = / *$/;
|
|
171
173
|
const TABLE_CENTER_ALIGN = /^ *:-+: *$/;
|
|
172
174
|
const TABLE_LEFT_ALIGN = /^ *:-+ *$/;
|
|
173
175
|
const TABLE_RIGHT_ALIGN = /^ *-+: *$/;
|
|
174
|
-
const TABLE_ROW_SPLIT = / *\| */;
|
|
175
176
|
|
|
176
177
|
const TEXT_BOLD_R = /^([*_])\1((?:\[.*?\][([].*?[)\]]|<.*?>(?:.*?<.*?>)?|`.*?`|~+.*?~+|.)*?)\1\1(?!\1)/;
|
|
177
178
|
const TEXT_EMPHASIZED_R = /^([*_])((?:\[.*?\][([].*?[)\]]|<.*?>(?:.*?<.*?>)?|`.*?`|~+.*?~+|.)*?)\1(?!\1)/;
|
|
@@ -179,7 +180,7 @@ const TEXT_STRIKETHROUGHED_R = /^~~((?:\[.*?\]|<.*?>(?:.*?<.*?>)?|`.*?`|.)*?)~~/
|
|
|
179
180
|
|
|
180
181
|
const TEXT_ESCAPED_R = /^\\([^0-9A-Za-z\s])/;
|
|
181
182
|
const TEXT_PLAIN_R = /^[\s\S]+?(?=[^0-9A-Z\s\u00c0-\uffff&;.()'"]|\d+\.|\n\n| {2,}\n|\w+:\S|$)/i;
|
|
182
|
-
const TRIM_NEWLINES_AND_TRAILING_WHITESPACE_R = /(^\n
|
|
183
|
+
const TRIM_NEWLINES_AND_TRAILING_WHITESPACE_R = /(^\n+|\n+$|\s+$)/g;
|
|
183
184
|
|
|
184
185
|
const HTML_LEFT_TRIM_AMOUNT_R = /^([ \t]*)/;
|
|
185
186
|
|
|
@@ -287,46 +288,56 @@ function parseTableAlignCapture(alignCapture) {
|
|
|
287
288
|
return null;
|
|
288
289
|
}
|
|
289
290
|
|
|
290
|
-
function
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
291
|
+
function parseTableRow(source, parse, state) {
|
|
292
|
+
const prevInTable = state.inTable;
|
|
293
|
+
state.inTable = true;
|
|
294
|
+
const tableRow = parse(source.trim(), state);
|
|
295
|
+
state.inTable = prevInTable;
|
|
296
|
+
|
|
297
|
+
let cells = [[]];
|
|
298
|
+
tableRow.forEach(function(node, i) {
|
|
299
|
+
if (node.type === 'tableSeparator') {
|
|
300
|
+
// Filter out empty table separators at the start/end:
|
|
301
|
+
if (i !== 0 && i !== tableRow.length - 1) {
|
|
302
|
+
// Split the current row:
|
|
303
|
+
cells.push([]);
|
|
304
|
+
}
|
|
305
|
+
} else {
|
|
306
|
+
if (node.type === 'text' && (
|
|
307
|
+
tableRow[i + 1] == null ||
|
|
308
|
+
tableRow[i + 1].type === 'tableSeparator'
|
|
309
|
+
)) {
|
|
310
|
+
node.content = node.content.replace(TABLE_CELL_END_TRIM, "");
|
|
311
|
+
}
|
|
312
|
+
cells[cells.length - 1].push(node);
|
|
313
|
+
}
|
|
298
314
|
});
|
|
315
|
+
return cells;
|
|
299
316
|
}
|
|
300
317
|
|
|
301
|
-
function parseTableAlign(
|
|
302
|
-
const alignText =
|
|
318
|
+
function parseTableAlign(source /*, parse, state*/) {
|
|
319
|
+
const alignText = source
|
|
303
320
|
.replace(TABLE_TRIM_PIPES, '')
|
|
304
|
-
.
|
|
305
|
-
.split(TABLE_ROW_SPLIT);
|
|
321
|
+
.split('|');
|
|
306
322
|
|
|
307
323
|
return alignText.map(parseTableAlignCapture);
|
|
308
324
|
}
|
|
309
325
|
|
|
310
|
-
function parseTableCells(
|
|
311
|
-
const rowsText =
|
|
326
|
+
function parseTableCells(source, parse, state) {
|
|
327
|
+
const rowsText = source
|
|
312
328
|
.trim()
|
|
313
329
|
.split('\n');
|
|
314
330
|
|
|
315
331
|
return rowsText.map(function(rowText) {
|
|
316
|
-
|
|
317
|
-
.replace(TABLE_TRIM_PIPES, '')
|
|
318
|
-
.split(TABLE_ROW_SPLIT)
|
|
319
|
-
.map(function(text) {
|
|
320
|
-
return parse(text.trim(), state);
|
|
321
|
-
});
|
|
332
|
+
return parseTableRow(rowText, parse, state);
|
|
322
333
|
});
|
|
323
334
|
}
|
|
324
335
|
|
|
325
336
|
function parseTable(capture, parse, state) {
|
|
326
337
|
state.inline = true;
|
|
327
|
-
const header =
|
|
328
|
-
const align = parseTableAlign(capture, parse, state);
|
|
329
|
-
const cells = parseTableCells(capture, parse, state);
|
|
338
|
+
const header = parseTableRow(capture[1], parse, state);
|
|
339
|
+
const align = parseTableAlign(capture[2], parse, state);
|
|
340
|
+
const cells = parseTableCells(capture[3], parse, state);
|
|
330
341
|
state.inline = false;
|
|
331
342
|
|
|
332
343
|
return {
|
|
@@ -374,6 +385,8 @@ function attributeValueToJSXPropValue(key, value) {
|
|
|
374
385
|
|
|
375
386
|
return styles;
|
|
376
387
|
}, {});
|
|
388
|
+
} else if (key === 'href') {
|
|
389
|
+
return sanitizeUrl(value)
|
|
377
390
|
} else if (value.match(INTERPOLATION_R)) {
|
|
378
391
|
// return as a string and let the consumer decide what to do with it
|
|
379
392
|
value = value.slice(1, value.length - 1);
|
|
@@ -805,7 +818,7 @@ export function compiler(markdown, options) {
|
|
|
805
818
|
{ key: index }
|
|
806
819
|
);
|
|
807
820
|
}
|
|
808
|
-
} else {
|
|
821
|
+
} else if (raw !== 'style') {
|
|
809
822
|
map[ATTRIBUTE_TO_JSX_PROP_MAP[raw] || raw] = true;
|
|
810
823
|
}
|
|
811
824
|
|
|
@@ -814,6 +827,10 @@ export function compiler(markdown, options) {
|
|
|
814
827
|
: undefined;
|
|
815
828
|
}
|
|
816
829
|
|
|
830
|
+
function stripHtmlComments(html) {
|
|
831
|
+
return html.replace(/<!--[\s\S]*?(?:-->)/g, '')
|
|
832
|
+
}
|
|
833
|
+
|
|
817
834
|
/* istanbul ignore next */
|
|
818
835
|
if (process.env.NODE_ENV !== 'production') {
|
|
819
836
|
if (typeof markdown !== 'string') {
|
|
@@ -1013,47 +1030,6 @@ export function compiler(markdown, options) {
|
|
|
1013
1030
|
},
|
|
1014
1031
|
},
|
|
1015
1032
|
|
|
1016
|
-
htmlBlock: {
|
|
1017
|
-
/**
|
|
1018
|
-
* find the first matching end tag and process the interior
|
|
1019
|
-
*/
|
|
1020
|
-
match: anyScopeRegex(HTML_BLOCK_ELEMENT_R),
|
|
1021
|
-
order: PARSE_PRIORITY_HIGH,
|
|
1022
|
-
parse(capture, parse, state) {
|
|
1023
|
-
const [, whitespace] = capture[3].match(HTML_LEFT_TRIM_AMOUNT_R);
|
|
1024
|
-
const trimmer = new RegExp(`^${whitespace}`, 'gm');
|
|
1025
|
-
const trimmed = capture[3].replace(trimmer, '');
|
|
1026
|
-
|
|
1027
|
-
const parseFunc = containsBlockSyntax(trimmed)
|
|
1028
|
-
? parseBlock
|
|
1029
|
-
: parseInline;
|
|
1030
|
-
|
|
1031
|
-
const tagName = capture[1].toLowerCase();
|
|
1032
|
-
const noInnerParse =
|
|
1033
|
-
DO_NOT_PROCESS_HTML_ELEMENTS.indexOf(tagName) !== -1;
|
|
1034
|
-
|
|
1035
|
-
return {
|
|
1036
|
-
attrs: attrStringToMap(capture[2]),
|
|
1037
|
-
/**
|
|
1038
|
-
* if another html block is detected within, parse as block,
|
|
1039
|
-
* otherwise parse as inline to pick up any further markdown
|
|
1040
|
-
*/
|
|
1041
|
-
content: noInnerParse ? capture[3] : parseFunc(parse, trimmed, state),
|
|
1042
|
-
|
|
1043
|
-
noInnerParse,
|
|
1044
|
-
|
|
1045
|
-
tag: noInnerParse ? tagName : capture[1]
|
|
1046
|
-
};
|
|
1047
|
-
},
|
|
1048
|
-
react(node, output, state) {
|
|
1049
|
-
return (
|
|
1050
|
-
<node.tag key={state.key} {...node.attrs}>
|
|
1051
|
-
{node.noInnerParse ? node.content : output(node.content, state)}
|
|
1052
|
-
</node.tag>
|
|
1053
|
-
);
|
|
1054
|
-
},
|
|
1055
|
-
},
|
|
1056
|
-
|
|
1057
1033
|
htmlComment: {
|
|
1058
1034
|
match: anyScopeRegex(HTML_COMMENT_R),
|
|
1059
1035
|
order: PARSE_PRIORITY_HIGH,
|
|
@@ -1063,23 +1039,6 @@ export function compiler(markdown, options) {
|
|
|
1063
1039
|
react: renderNothing,
|
|
1064
1040
|
},
|
|
1065
1041
|
|
|
1066
|
-
htmlSelfClosing: {
|
|
1067
|
-
/**
|
|
1068
|
-
* find the first matching end tag and process the interior
|
|
1069
|
-
*/
|
|
1070
|
-
match: anyScopeRegex(HTML_SELF_CLOSING_ELEMENT_R),
|
|
1071
|
-
order: PARSE_PRIORITY_HIGH,
|
|
1072
|
-
parse(capture /*, parse, state*/) {
|
|
1073
|
-
return {
|
|
1074
|
-
attrs: attrStringToMap(capture[2] || ''),
|
|
1075
|
-
tag: capture[1],
|
|
1076
|
-
};
|
|
1077
|
-
},
|
|
1078
|
-
react(node, output, state) {
|
|
1079
|
-
return <node.tag {...node.attrs} key={state.key} />;
|
|
1080
|
-
},
|
|
1081
|
-
},
|
|
1082
|
-
|
|
1083
1042
|
image: {
|
|
1084
1043
|
match: simpleInlineRegex(IMAGE_R),
|
|
1085
1044
|
order: PARSE_PRIORITY_HIGH,
|
|
@@ -1411,6 +1370,21 @@ export function compiler(markdown, options) {
|
|
|
1411
1370
|
},
|
|
1412
1371
|
},
|
|
1413
1372
|
|
|
1373
|
+
tableSeparator: {
|
|
1374
|
+
match: function(source, state) {
|
|
1375
|
+
if (!state.inTable) {
|
|
1376
|
+
return null;
|
|
1377
|
+
}
|
|
1378
|
+
return TABLE_SEPARATOR_R.exec(source);
|
|
1379
|
+
},
|
|
1380
|
+
order: PARSE_PRIORITY_HIGH,
|
|
1381
|
+
parse: function() {
|
|
1382
|
+
return { type: 'tableSeparator' };
|
|
1383
|
+
},
|
|
1384
|
+
// These shouldn't be reached, but in case they are, be reasonable:
|
|
1385
|
+
react() { return ' | '; }
|
|
1386
|
+
},
|
|
1387
|
+
|
|
1414
1388
|
text: {
|
|
1415
1389
|
// Here we look for anything followed by non-symbols,
|
|
1416
1390
|
// double newlines, or double-space-newlines
|
|
@@ -1521,10 +1495,70 @@ export function compiler(markdown, options) {
|
|
|
1521
1495
|
// };
|
|
1522
1496
|
// });
|
|
1523
1497
|
|
|
1498
|
+
if (options.disableParsingRawHTML !== true) {
|
|
1499
|
+
rules.htmlBlock = {
|
|
1500
|
+
/**
|
|
1501
|
+
* find the first matching end tag and process the interior
|
|
1502
|
+
*/
|
|
1503
|
+
match: anyScopeRegex(HTML_BLOCK_ELEMENT_R),
|
|
1504
|
+
order: PARSE_PRIORITY_HIGH,
|
|
1505
|
+
parse(capture, parse, state) {
|
|
1506
|
+
const [, whitespace] = capture[3].match(HTML_LEFT_TRIM_AMOUNT_R);
|
|
1507
|
+
const trimmer = new RegExp(`^${whitespace}`, 'gm');
|
|
1508
|
+
const trimmed = capture[3].replace(trimmer, '');
|
|
1509
|
+
|
|
1510
|
+
const parseFunc = containsBlockSyntax(trimmed)
|
|
1511
|
+
? parseBlock
|
|
1512
|
+
: parseInline;
|
|
1513
|
+
|
|
1514
|
+
const tagName = capture[1].toLowerCase();
|
|
1515
|
+
const noInnerParse =
|
|
1516
|
+
DO_NOT_PROCESS_HTML_ELEMENTS.indexOf(tagName) !== -1;
|
|
1517
|
+
|
|
1518
|
+
return {
|
|
1519
|
+
attrs: attrStringToMap(capture[2]),
|
|
1520
|
+
/**
|
|
1521
|
+
* if another html block is detected within, parse as block,
|
|
1522
|
+
* otherwise parse as inline to pick up any further markdown
|
|
1523
|
+
*/
|
|
1524
|
+
content: noInnerParse ? capture[3] : parseFunc(parse, trimmed, state),
|
|
1525
|
+
|
|
1526
|
+
noInnerParse,
|
|
1527
|
+
|
|
1528
|
+
tag: noInnerParse ? tagName : capture[1]
|
|
1529
|
+
};
|
|
1530
|
+
},
|
|
1531
|
+
react(node, output, state) {
|
|
1532
|
+
return (
|
|
1533
|
+
<node.tag key={state.key} {...node.attrs}>
|
|
1534
|
+
{node.noInnerParse ? node.content : output(node.content, state)}
|
|
1535
|
+
</node.tag>
|
|
1536
|
+
);
|
|
1537
|
+
},
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
rules.htmlSelfClosing = {
|
|
1541
|
+
/**
|
|
1542
|
+
* find the first matching end tag and process the interior
|
|
1543
|
+
*/
|
|
1544
|
+
match: anyScopeRegex(HTML_SELF_CLOSING_ELEMENT_R),
|
|
1545
|
+
order: PARSE_PRIORITY_HIGH,
|
|
1546
|
+
parse(capture /*, parse, state*/) {
|
|
1547
|
+
return {
|
|
1548
|
+
attrs: attrStringToMap(capture[2] || ''),
|
|
1549
|
+
tag: capture[1],
|
|
1550
|
+
};
|
|
1551
|
+
},
|
|
1552
|
+
react(node, output, state) {
|
|
1553
|
+
return <node.tag {...node.attrs} key={state.key} />;
|
|
1554
|
+
},
|
|
1555
|
+
};
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1524
1558
|
const parser = parserFor(rules);
|
|
1525
1559
|
const emitter = reactFor(ruleOutput(rules));
|
|
1526
1560
|
|
|
1527
|
-
const jsx = compile(markdown);
|
|
1561
|
+
const jsx = compile(stripHtmlComments(markdown));
|
|
1528
1562
|
|
|
1529
1563
|
if (footnotes.length) {
|
|
1530
1564
|
jsx.props.children.push(
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Convert markdown to JSX with ease for React and React-like projects. Super lightweight and highly configurable.",
|
|
4
4
|
"homepage": "https://probablyup.github.io/markdown-to-jsx",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "6.
|
|
6
|
+
"version": "6.11.1",
|
|
7
7
|
"engines": {
|
|
8
8
|
"node": ">= 4"
|
|
9
9
|
},
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"size-limit": [
|
|
91
91
|
{
|
|
92
92
|
"path": "dist/cjs.js",
|
|
93
|
-
"limit": "5.
|
|
93
|
+
"limit": "5.28 kB"
|
|
94
94
|
}
|
|
95
95
|
],
|
|
96
96
|
"jest": {
|