markdown-to-jsx 6.10.0 → 6.11.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/README.md +53 -2
- 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 +123 -86
- 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);
|
|
@@ -716,6 +729,9 @@ export function compiler(markdown, options) {
|
|
|
716
729
|
options = options || {};
|
|
717
730
|
options.overrides = options.overrides || {};
|
|
718
731
|
options.slugify = options.slugify || slugify;
|
|
732
|
+
options.namedCodesToUnicode = options.namedCodesToUnicode
|
|
733
|
+
? {...namedCodesToUnicode, ...options.namedCodesToUnicode}
|
|
734
|
+
: namedCodesToUnicode;
|
|
719
735
|
|
|
720
736
|
const createElementFn = options.createElement || React.createElement;
|
|
721
737
|
|
|
@@ -811,6 +827,10 @@ export function compiler(markdown, options) {
|
|
|
811
827
|
: undefined;
|
|
812
828
|
}
|
|
813
829
|
|
|
830
|
+
function stripHtmlComments(html) {
|
|
831
|
+
return html.replace(/<!--[\s\S]*?(?:-->)/g, '')
|
|
832
|
+
}
|
|
833
|
+
|
|
814
834
|
/* istanbul ignore next */
|
|
815
835
|
if (process.env.NODE_ENV !== 'production') {
|
|
816
836
|
if (typeof markdown !== 'string') {
|
|
@@ -1010,47 +1030,6 @@ export function compiler(markdown, options) {
|
|
|
1010
1030
|
},
|
|
1011
1031
|
},
|
|
1012
1032
|
|
|
1013
|
-
htmlBlock: {
|
|
1014
|
-
/**
|
|
1015
|
-
* find the first matching end tag and process the interior
|
|
1016
|
-
*/
|
|
1017
|
-
match: anyScopeRegex(HTML_BLOCK_ELEMENT_R),
|
|
1018
|
-
order: PARSE_PRIORITY_HIGH,
|
|
1019
|
-
parse(capture, parse, state) {
|
|
1020
|
-
const [, whitespace] = capture[3].match(HTML_LEFT_TRIM_AMOUNT_R);
|
|
1021
|
-
const trimmer = new RegExp(`^${whitespace}`, 'gm');
|
|
1022
|
-
const trimmed = capture[3].replace(trimmer, '');
|
|
1023
|
-
|
|
1024
|
-
const parseFunc = containsBlockSyntax(trimmed)
|
|
1025
|
-
? parseBlock
|
|
1026
|
-
: parseInline;
|
|
1027
|
-
|
|
1028
|
-
const tagName = capture[1].toLowerCase();
|
|
1029
|
-
const noInnerParse =
|
|
1030
|
-
DO_NOT_PROCESS_HTML_ELEMENTS.indexOf(tagName) !== -1;
|
|
1031
|
-
|
|
1032
|
-
return {
|
|
1033
|
-
attrs: attrStringToMap(capture[2]),
|
|
1034
|
-
/**
|
|
1035
|
-
* if another html block is detected within, parse as block,
|
|
1036
|
-
* otherwise parse as inline to pick up any further markdown
|
|
1037
|
-
*/
|
|
1038
|
-
content: noInnerParse ? capture[3] : parseFunc(parse, trimmed, state),
|
|
1039
|
-
|
|
1040
|
-
noInnerParse,
|
|
1041
|
-
|
|
1042
|
-
tag: noInnerParse ? tagName : capture[1]
|
|
1043
|
-
};
|
|
1044
|
-
},
|
|
1045
|
-
react(node, output, state) {
|
|
1046
|
-
return (
|
|
1047
|
-
<node.tag key={state.key} {...node.attrs}>
|
|
1048
|
-
{node.noInnerParse ? node.content : output(node.content, state)}
|
|
1049
|
-
</node.tag>
|
|
1050
|
-
);
|
|
1051
|
-
},
|
|
1052
|
-
},
|
|
1053
|
-
|
|
1054
1033
|
htmlComment: {
|
|
1055
1034
|
match: anyScopeRegex(HTML_COMMENT_R),
|
|
1056
1035
|
order: PARSE_PRIORITY_HIGH,
|
|
@@ -1060,23 +1039,6 @@ export function compiler(markdown, options) {
|
|
|
1060
1039
|
react: renderNothing,
|
|
1061
1040
|
},
|
|
1062
1041
|
|
|
1063
|
-
htmlSelfClosing: {
|
|
1064
|
-
/**
|
|
1065
|
-
* find the first matching end tag and process the interior
|
|
1066
|
-
*/
|
|
1067
|
-
match: anyScopeRegex(HTML_SELF_CLOSING_ELEMENT_R),
|
|
1068
|
-
order: PARSE_PRIORITY_HIGH,
|
|
1069
|
-
parse(capture /*, parse, state*/) {
|
|
1070
|
-
return {
|
|
1071
|
-
attrs: attrStringToMap(capture[2] || ''),
|
|
1072
|
-
tag: capture[1],
|
|
1073
|
-
};
|
|
1074
|
-
},
|
|
1075
|
-
react(node, output, state) {
|
|
1076
|
-
return <node.tag {...node.attrs} key={state.key} />;
|
|
1077
|
-
},
|
|
1078
|
-
},
|
|
1079
|
-
|
|
1080
1042
|
image: {
|
|
1081
1043
|
match: simpleInlineRegex(IMAGE_R),
|
|
1082
1044
|
order: PARSE_PRIORITY_HIGH,
|
|
@@ -1408,6 +1370,21 @@ export function compiler(markdown, options) {
|
|
|
1408
1370
|
},
|
|
1409
1371
|
},
|
|
1410
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
|
+
|
|
1411
1388
|
text: {
|
|
1412
1389
|
// Here we look for anything followed by non-symbols,
|
|
1413
1390
|
// double newlines, or double-space-newlines
|
|
@@ -1420,8 +1397,8 @@ export function compiler(markdown, options) {
|
|
|
1420
1397
|
content: capture[0]
|
|
1421
1398
|
// nbsp -> unicode equivalent for named chars
|
|
1422
1399
|
.replace(HTML_CHAR_CODE_R, (full, inner) => {
|
|
1423
|
-
return namedCodesToUnicode[inner]
|
|
1424
|
-
? namedCodesToUnicode[inner]
|
|
1400
|
+
return options.namedCodesToUnicode[inner]
|
|
1401
|
+
? options.namedCodesToUnicode[inner]
|
|
1425
1402
|
: full;
|
|
1426
1403
|
}),
|
|
1427
1404
|
};
|
|
@@ -1518,10 +1495,70 @@ export function compiler(markdown, options) {
|
|
|
1518
1495
|
// };
|
|
1519
1496
|
// });
|
|
1520
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
|
+
|
|
1521
1558
|
const parser = parserFor(rules);
|
|
1522
1559
|
const emitter = reactFor(ruleOutput(rules));
|
|
1523
1560
|
|
|
1524
|
-
const jsx = compile(markdown);
|
|
1561
|
+
const jsx = compile(stripHtmlComments(markdown));
|
|
1525
1562
|
|
|
1526
1563
|
if (footnotes.length) {
|
|
1527
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.0",
|
|
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": {
|