@khanacademy/simple-markdown 0.14.1 → 1.0.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/dist/index.js CHANGED
@@ -1,35 +1,16 @@
1
- 'use strict';
1
+ import { addLibraryVersionToPerseusDebug } from '@khanacademy/perseus-utils';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var perseusUtils = require('@khanacademy/perseus-utils');
6
-
7
- // This file is processed by a Rollup plugin (replace) to inject the production
8
3
  const libName = "@khanacademy/simple-markdown";
9
- const libVersion = "0.14.1";
10
- perseusUtils.addLibraryVersionToPerseusDebug(libName, libVersion);
11
-
12
- /* eslint-disable prefer-spread, no-regex-spaces, guard-for-in, no-console, no-var */
13
-
14
- // Type Definitions:
15
-
16
- // We want to clarify our defaultRules types a little bit more so clients can
17
- // reuse defaultRules built-ins. So we make some stronger guarantess when
18
- // we can:
19
-
20
- // End TypeScript Definitions
4
+ const libVersion = "1.0.0";
5
+ addLibraryVersionToPerseusDebug(libName, libVersion);
21
6
 
22
7
  var CR_NEWLINE_R = /\r\n?/g;
23
8
  var TAB_R = /\t/g;
24
9
  var FORMFEED_R = /\f/g;
25
-
26
- /**
27
- * Turn various whitespace into easy-to-process whitespace
28
- */
29
- var preprocess = function (source) {
10
+ var preprocess = function preprocess(source) {
30
11
  return source.replace(CR_NEWLINE_R, "\n").replace(FORMFEED_R, "").replace(TAB_R, " ");
31
12
  };
32
- var populateInitialState = function (givenState, defaultState) {
13
+ var populateInitialState = function populateInitialState(givenState, defaultState) {
33
14
  var state = givenState || {};
34
15
  if (defaultState != null) {
35
16
  for (var prop in defaultState) {
@@ -40,29 +21,7 @@ var populateInitialState = function (givenState, defaultState) {
40
21
  }
41
22
  return state;
42
23
  };
43
-
44
- /**
45
- * Creates a parser for a given set of rules, with the precedence
46
- * specified as a list of rules.
47
- *
48
- * @param {SimpleMarkdown.ParserRules} rules
49
- * an object containing
50
- * rule type -> {match, order, parse} objects
51
- * (lower order is higher precedence)
52
- * @param {SimpleMarkdown.OptionalState} [defaultState]
53
- *
54
- * @returns {SimpleMarkdown.Parser}
55
- * The resulting parse function, with the following parameters:
56
- * @source: the input source string to be parsed
57
- * @state: an optional object to be threaded through parse
58
- * calls. Allows clients to add stateful operations to
59
- * parsing, such as keeping track of how many levels deep
60
- * some nesting is. For an example use-case, see passage-ref
61
- * parsing in src/widgets/passage/passage-markdown.jsx
62
- */
63
- var parserFor = function (rules, defaultState) {
64
- // Sorts rules in order of increasing order, then
65
- // ascending rule name in case of ties.
24
+ var parserFor = function parserFor(rules, defaultState) {
66
25
  var ruleList = Object.keys(rules).filter(function (type) {
67
26
  var rule = rules[type];
68
27
  if (rule == null || rule.match == null) {
@@ -79,8 +38,6 @@ var parserFor = function (rules, defaultState) {
79
38
  var ruleB = rules[typeB];
80
39
  var orderA = ruleA.order;
81
40
  var orderB = ruleB.order;
82
-
83
- // First sort based on increasing order
84
41
  if (orderA !== orderB) {
85
42
  return orderA - orderB;
86
43
  }
@@ -88,31 +45,24 @@ var parserFor = function (rules, defaultState) {
88
45
  var secondaryOrderB = ruleB.quality ? 0 : 1;
89
46
  if (secondaryOrderA !== secondaryOrderB) {
90
47
  return secondaryOrderA - secondaryOrderB;
91
-
92
- // Then based on increasing unicode lexicographic ordering
93
48
  } else if (typeA < typeB) {
94
49
  return -1;
95
50
  } else if (typeA > typeB) {
96
51
  return 1;
97
52
  } else {
98
- // Rules should never have the same name,
99
- // but this is provided for completeness.
100
53
  return 0;
101
54
  }
102
55
  });
103
56
  var latestState;
104
- var nestedParse = function (source, state) {
57
+ var nestedParse = function nestedParse(source, state) {
105
58
  var result = [];
106
59
  state = state || latestState;
107
60
  latestState = state;
108
61
  while (source) {
109
- // store the best match, it's rule, and quality:
110
62
  var ruleType = null;
111
63
  var rule = null;
112
64
  var capture = null;
113
65
  var quality = NaN;
114
-
115
- // loop control variables:
116
66
  var i = 0;
117
67
  var currRuleType = ruleList[0];
118
68
  var currRule = rules[currRuleType];
@@ -122,65 +72,30 @@ var parserFor = function (rules, defaultState) {
122
72
  var currCapture = currRule.match(source, state, prevCaptureStr);
123
73
  if (currCapture) {
124
74
  var currQuality = currRule.quality ? currRule.quality(currCapture, state, prevCaptureStr) : 0;
125
- // This should always be true the first time because
126
- // the initial quality is NaN (that's why there's the
127
- // condition negation).
128
75
  if (!(currQuality <= quality)) {
129
- // @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'null'.
130
76
  ruleType = currRuleType;
131
- // @ts-expect-error - TS2322 - Type 'ParserRule' is not assignable to type 'null'.
132
77
  rule = currRule;
133
- // @ts-expect-error - TS2322 - Type 'Capture' is not assignable to type 'null'.
134
78
  capture = currCapture;
135
79
  quality = currQuality;
136
80
  }
137
81
  }
138
-
139
- // Move on to the next item.
140
- // Note that this makes `currRule` be the next item
141
82
  i++;
142
83
  currRuleType = ruleList[i];
143
84
  currRule = rules[currRuleType];
144
- } while (
145
- // keep looping while we're still within the ruleList
146
- currRule && (
147
- // if we don't have a match yet, continue
148
- !capture ||
149
- // or if we have a match, but the next rule is
150
- // at the same order, and has a quality measurement
151
- // functions, then this rule must have a quality
152
- // measurement function (since they are sorted before
153
- // those without), and we need to check if there is
154
- // a better quality match
155
- currRule.order === currOrder && currRule.quality));
156
-
157
- // TODO(aria): Write tests for these
85
+ } while (currRule && (!capture || currRule.order === currOrder && currRule.quality));
158
86
  if (rule == null || capture == null) {
159
87
  throw new Error("Could not find a matching rule for the below " + "content. The rule with highest `order` should " + "always match content provided to it. Check " + "the definition of `match` for '" + ruleList[ruleList.length - 1] + "'. It seems to not match the following source:\n" + source);
160
88
  }
161
- // @ts-expect-error - TS2339 - Property 'index' does not exist on type 'never'.
162
89
  if (capture.index) {
163
- // If present and non-zero, i.e. a non-^ regexp result:
164
90
  throw new Error("`match` must return a capture starting at index 0 " + "(the current parse index). Did you forget a ^ at the " + "start of the RegExp?");
165
91
  }
166
-
167
- // @ts-expect-error - TS2339 - Property 'parse' does not exist on type 'never'.
168
92
  var parsed = rule.parse(capture, nestedParse, state);
169
- // We maintain the same object here so that rules can
170
- // store references to the objects they return and
171
- // modify them later. (oops sorry! but this adds a lot
172
- // of power--see reflinks.)
173
93
  if (Array.isArray(parsed)) {
174
94
  Array.prototype.push.apply(result, parsed);
175
95
  } else {
176
96
  if (parsed == null || typeof parsed !== "object") {
177
97
  throw new Error(`parse() function returned invalid parse result: '${parsed}'`);
178
98
  }
179
-
180
- // We also let rules override the default type of
181
- // their parsed node if they would like to, so that
182
- // there can be a single output function for all links,
183
- // even if there are several rules to parse them.
184
99
  if (parsed.type == null) {
185
100
  parsed.type = ruleType;
186
101
  }
@@ -191,39 +106,29 @@ var parserFor = function (rules, defaultState) {
191
106
  }
192
107
  return result;
193
108
  };
194
- var outerParse = function (source, state) {
109
+ var outerParse = function outerParse(source, state) {
195
110
  latestState = populateInitialState(state, defaultState);
196
111
  if (!latestState.inline && !latestState.disableAutoBlockNewlines) {
197
112
  source = source + "\n\n";
198
113
  }
199
- // We store the previous capture so that match functions can
200
- // use some limited amount of lookbehind. Lists use this to
201
- // ensure they don't match arbitrary '- ' or '* ' in inline
202
- // text (see the list rule for more information). This stores
203
- // the full regex capture object, if there is one.
204
114
  latestState.prevCapture = null;
205
115
  return nestedParse(preprocess(source), latestState);
206
116
  };
207
117
  return outerParse;
208
118
  };
209
-
210
- // Creates a match function for an inline scoped element from a regex
211
- var inlineRegex = function (regex) {
212
- var match = function (source, state, prevCapture) {
119
+ var inlineRegex = function inlineRegex(regex) {
120
+ var match = function match(source, state, prevCapture) {
213
121
  if (state.inline) {
214
122
  return regex.exec(source);
215
123
  } else {
216
124
  return null;
217
125
  }
218
126
  };
219
- // @ts-expect-error - TS2339 - Property 'regex' does not exist on type '(source: string, state: State, prevCapture: string) => Capture | null | undefined'.
220
127
  match.regex = regex;
221
128
  return match;
222
129
  };
223
-
224
- // Creates a match function for a block scoped element from a regex
225
- var blockRegex = function (regex) {
226
- var match = function (source, state) {
130
+ var blockRegex = function blockRegex(regex) {
131
+ var match = function match(source, state) {
227
132
  if (state.inline) {
228
133
  return null;
229
134
  } else {
@@ -233,17 +138,15 @@ var blockRegex = function (regex) {
233
138
  match.regex = regex;
234
139
  return match;
235
140
  };
236
-
237
- // Creates a match function from a regex, ignoring block/inline scope
238
- var anyScopeRegex = function (regex) {
239
- var match = function (source, state) {
141
+ var anyScopeRegex = function anyScopeRegex(regex) {
142
+ var match = function match(source, state) {
240
143
  return regex.exec(source);
241
144
  };
242
145
  match.regex = regex;
243
146
  return match;
244
147
  };
245
148
  var TYPE_SYMBOL = typeof Symbol === "function" && Symbol.for && Symbol.for("react.element") || 0xeac7;
246
- var reactElement = function (type, key, props) {
149
+ var reactElement = function reactElement(type, key, props) {
247
150
  var element = {
248
151
  $$typeof: TYPE_SYMBOL,
249
152
  type: type,
@@ -254,22 +157,12 @@ var reactElement = function (type, key, props) {
254
157
  };
255
158
  return element;
256
159
  };
257
-
258
- /** Returns a closed HTML tag.
259
- * @param {string} tagName - Name of HTML tag (eg. "em" or "a")
260
- * @param {string} content - Inner content of tag
261
- * @param {{ [attr: string]: SimpleMarkdown.Attr }} [attributes] - Optional extra attributes of tag as an object of key-value pairs
262
- * eg. { "href": "http://google.com" }. Falsey attributes are filtered out.
263
- * @param {boolean} [isClosed] - boolean that controls whether tag is closed or not (eg. img tags).
264
- * defaults to true
265
- */
266
- var htmlTag = function (tagName, content, attributes, isClosed) {
160
+ var htmlTag = function htmlTag(tagName, content, attributes, isClosed) {
267
161
  attributes = attributes || {};
268
162
  isClosed = typeof isClosed !== "undefined" ? isClosed : true;
269
163
  var attributeString = "";
270
164
  for (var attr in attributes) {
271
165
  var attribute = attributes[attr];
272
- // Removes falsey attributes
273
166
  if (Object.prototype.hasOwnProperty.call(attributes, attr) && attribute) {
274
167
  attributeString += " " + sanitizeText(attr) + '="' + sanitizeText(attribute) + '"';
275
168
  }
@@ -282,12 +175,7 @@ var htmlTag = function (tagName, content, attributes, isClosed) {
282
175
  }
283
176
  };
284
177
  var EMPTY_PROPS = {};
285
-
286
- /**
287
- * @param {string | null | undefined} url - url to sanitize
288
- * @returns {string | null} - url if safe, or null if a safe url could not be made
289
- */
290
- var sanitizeUrl = function (url) {
178
+ var sanitizeUrl = function sanitizeUrl(url) {
291
179
  if (url == null) {
292
180
  return null;
293
181
  }
@@ -296,9 +184,7 @@ var sanitizeUrl = function (url) {
296
184
  if (prot.indexOf("javascript:") === 0 || prot.indexOf("vbscript:") === 0 || prot.indexOf("data:") === 0) {
297
185
  return null;
298
186
  }
299
- } catch {
300
- // invalid URLs should throw a TypeError
301
- // see for instance: `new URL("");`
187
+ } catch (_unused) {
302
188
  return null;
303
189
  }
304
190
  return url;
@@ -313,84 +199,54 @@ var SANITIZE_TEXT_CODES = {
313
199
  "/": "&#x2F;",
314
200
  "`": "&#96;"
315
201
  };
316
- var sanitizeText = function (text) {
202
+ var sanitizeText = function sanitizeText(text) {
317
203
  return String(text).replace(SANITIZE_TEXT_R, function (chr) {
318
204
  return SANITIZE_TEXT_CODES[chr];
319
205
  });
320
206
  };
321
207
  var UNESCAPE_URL_R = /\\([^0-9A-Za-z\s])/g;
322
- var unescapeUrl = function (rawUrlString) {
208
+ var unescapeUrl = function unescapeUrl(rawUrlString) {
323
209
  return rawUrlString.replace(UNESCAPE_URL_R, "$1");
324
210
  };
325
-
326
- /**
327
- * Parse some content with the parser `parse`, with state.inline
328
- * set to true. Useful for block elements; not generally necessary
329
- * to be used by inline elements (where state.inline is already true.
330
- */
331
- var parseInline = function (parse, content, state) {
211
+ var parseInline = function parseInline(parse, content, state) {
332
212
  var isCurrentlyInline = state.inline || false;
333
213
  state.inline = true;
334
214
  var result = parse(content, state);
335
215
  state.inline = isCurrentlyInline;
336
216
  return result;
337
217
  };
338
- var parseBlock = function (parse, content, state) {
218
+ var parseBlock = function parseBlock(parse, content, state) {
339
219
  var isCurrentlyInline = state.inline || false;
340
220
  state.inline = false;
341
221
  var result = parse(content + "\n\n", state);
342
222
  state.inline = isCurrentlyInline;
343
223
  return result;
344
224
  };
345
- var parseCaptureInline = function (capture, parse, state) {
225
+ var parseCaptureInline = function parseCaptureInline(capture, parse, state) {
346
226
  return {
347
227
  content: parseInline(parse, capture[1], state)
348
228
  };
349
229
  };
350
- var ignoreCapture = function () {
230
+ var ignoreCapture = function ignoreCapture() {
351
231
  return {};
352
232
  };
353
-
354
- // recognize a `*` `-`, `+`, `1.`, `2.`... list bullet
355
233
  var LIST_BULLET = "(?:[*+-]|\\d+\\.)";
356
- // recognize the start of a list item:
357
- // leading space plus a bullet plus a space (` * `)
358
234
  var LIST_ITEM_PREFIX = "( *)(" + LIST_BULLET + ") +";
359
235
  var LIST_ITEM_PREFIX_R = new RegExp("^" + LIST_ITEM_PREFIX);
360
- // recognize an individual list item:
361
- // * hi
362
- // this is part of the same item
363
- //
364
- // as is this, which is a new paragraph in the same item
365
- //
366
- // * but this is not part of the same item
367
236
  var LIST_ITEM_R = new RegExp(LIST_ITEM_PREFIX + "[^\\n]*(?:\\n" + "(?!\\1" + LIST_BULLET + " )[^\\n]*)*(\n|$)", "gm");
368
237
  var BLOCK_END_R = /\n{2,}$/;
369
238
  var INLINE_CODE_ESCAPE_BACKTICKS_R = /^ (?= *`)|(` *) $/g;
370
- // recognize the end of a paragraph block inside a list item:
371
- // two or more newlines at end end of the item
372
239
  var LIST_BLOCK_END_R = BLOCK_END_R;
373
240
  var LIST_ITEM_END_R = / *\n+$/;
374
- // check whether a list item has paragraphs: if it does,
375
- // we leave the newlines at the end
376
- var LIST_R = new RegExp("^( *)(" + LIST_BULLET + ") " + "[\\s\\S]+?(?:\n{2,}(?! )" + "(?!\\1" + LIST_BULLET + " )\\n*" +
377
- // the \\s*$ here is so that we can parse the inside of nested
378
- // lists, where our content might end before we receive two `\n`s
379
- "|\\s*\n*$)");
241
+ var LIST_R = new RegExp("^( *)(" + LIST_BULLET + ") " + "[\\s\\S]+?(?:\n{2,}(?! )" + "(?!\\1" + LIST_BULLET + " )\\n*" + "|\\s*\n*$)");
380
242
  var LIST_LOOKBEHIND_R = /(?:^|\n)( *)$/;
381
243
  var TABLES = function () {
382
- // predefine regexes so we don't have to create them inside functions
383
- // sure, regex literals should be fast, even inside functions, but they
384
- // aren't in all browsers.
385
244
  var TABLE_ROW_SEPARATOR_TRIM = /^ *\| *| *\| *$/g;
386
245
  var TABLE_CELL_END_TRIM = / *$/;
387
246
  var TABLE_RIGHT_ALIGN = /^ *-+: *$/;
388
247
  var TABLE_CENTER_ALIGN = /^ *:-+: *$/;
389
248
  var TABLE_LEFT_ALIGN = /^ *:-+ *$/;
390
-
391
- // TODO: This needs a real type
392
-
393
- var parseTableAlignCapture = function (alignCapture) {
249
+ var parseTableAlignCapture = function parseTableAlignCapture(alignCapture) {
394
250
  if (TABLE_RIGHT_ALIGN.test(alignCapture)) {
395
251
  return "right";
396
252
  } else if (TABLE_CENTER_ALIGN.test(alignCapture)) {
@@ -401,14 +257,14 @@ var TABLES = function () {
401
257
  return null;
402
258
  }
403
259
  };
404
- var parseTableAlign = function (source, parse, state, trimEndSeparators) {
260
+ var parseTableAlign = function parseTableAlign(source, parse, state, trimEndSeparators) {
405
261
  if (trimEndSeparators) {
406
262
  source = source.replace(TABLE_ROW_SEPARATOR_TRIM, "");
407
263
  }
408
264
  var alignText = source.trim().split("|");
409
265
  return alignText.map(parseTableAlignCapture);
410
266
  };
411
- var parseTableRow = function (source, parse, state, trimEndSeparators) {
267
+ var parseTableRow = function parseTableRow(source, parse, state, trimEndSeparators) {
412
268
  var prevInTable = state.inTable;
413
269
  state.inTable = true;
414
270
  var tableRow = parse(source.trim(), state);
@@ -416,41 +272,25 @@ var TABLES = function () {
416
272
  var cells = [[]];
417
273
  tableRow.forEach(function (node, i) {
418
274
  if (node.type === "tableSeparator") {
419
- // Filter out empty table separators at the start/end:
420
275
  if (!trimEndSeparators || i !== 0 && i !== tableRow.length - 1) {
421
- // Split the current row:
422
276
  cells.push([]);
423
277
  }
424
278
  } else {
425
279
  if (node.type === "text" && (tableRow[i + 1] == null || tableRow[i + 1].type === "tableSeparator")) {
426
280
  node.content = node.content.replace(TABLE_CELL_END_TRIM, "");
427
281
  }
428
- // @ts-expect-error - TS2345 - Argument of type 'SingleASTNode' is not assignable to parameter of type 'never'.
429
282
  cells[cells.length - 1].push(node);
430
283
  }
431
284
  });
432
285
  return cells;
433
286
  };
434
-
435
- /**
436
- * @param {string} source
437
- * @param {SimpleMarkdown.Parser} parse
438
- * @param {SimpleMarkdown.State} state
439
- * @param {boolean} trimEndSeparators
440
- * @returns {SimpleMarkdown.ASTNode[][]}
441
- */
442
- var parseTableCells = function (source, parse, state, trimEndSeparators) {
287
+ var parseTableCells = function parseTableCells(source, parse, state, trimEndSeparators) {
443
288
  var rowsText = source.trim().split("\n");
444
289
  return rowsText.map(function (rowText) {
445
290
  return parseTableRow(rowText, parse, state, trimEndSeparators);
446
291
  });
447
292
  };
448
-
449
- /**
450
- * @param {boolean} trimEndSeparators
451
- * @returns {SimpleMarkdown.SingleNodeParseFunction}
452
- */
453
- var parseTable = function (trimEndSeparators) {
293
+ var parseTable = function parseTable(trimEndSeparators) {
454
294
  return function (capture, parse, state) {
455
295
  state.inline = true;
456
296
  var header = parseTableRow(capture[1], parse, state, trimEndSeparators);
@@ -475,28 +315,13 @@ var TABLES = function () {
475
315
  var LINK_INSIDE = "(?:\\[[^\\]]*\\]|[^\\[\\]]|\\](?=[^\\[]*\\]))*";
476
316
  var LINK_HREF_AND_TITLE = "\\s*<?((?:\\([^)]*\\)|[^\\s\\\\]|\\\\.)*?)>?(?:\\s+['\"]([\\s\\S]*?)['\"])?\\s*";
477
317
  var AUTOLINK_MAILTO_CHECK_R = /mailto:/i;
478
- var parseRef = function (capture, state, refNode) {
318
+ var parseRef = function parseRef(capture, state, refNode) {
479
319
  var ref = (capture[2] || capture[1]).replace(/\s+/g, " ").toLowerCase();
480
-
481
- // We store information about previously seen defs on
482
- // state._defs (_ to deconflict with client-defined
483
- // state). If the def for this reflink/refimage has
484
- // already been seen, we can use its target/source
485
- // and title here:
486
320
  if (state._defs && state._defs[ref]) {
487
321
  var def = state._defs[ref];
488
- // `refNode` can be a link or an image. Both use
489
- // target and title properties.
490
322
  refNode.target = def.target;
491
323
  refNode.title = def.title;
492
324
  }
493
-
494
- // In case we haven't seen our def yet (or if someone
495
- // overwrites that def later on), we add this node
496
- // to the list of ref nodes for that def. Then, when
497
- // we find the def, we can modify this link/image AST
498
- // node :).
499
- // I'm sorry.
500
325
  state._refs = state._refs || {};
501
326
  state._refs[ref] = state._refs[ref] || [];
502
327
  state._refs[ref].push(refNode);
@@ -508,13 +333,7 @@ var defaultRules = {
508
333
  react: function (arr, output, state) {
509
334
  var oldKey = state.key;
510
335
  var result = [];
511
-
512
- // map output over the ast, except group any text
513
- // nodes together into a single string output.
514
336
  for (var i = 0, key = 0; i < arr.length; i++, key++) {
515
- // `key` is our numerical `state.key`, which we increment for
516
- // every output node, but don't change for joined text nodes.
517
- // (i, however, must change for joined text nodes)
518
337
  state.key = "" + i;
519
338
  var node = arr[i];
520
339
  if (node.type === "text") {
@@ -533,9 +352,6 @@ var defaultRules = {
533
352
  },
534
353
  html: function (arr, output, state) {
535
354
  var result = "";
536
-
537
- // map output over the ast, except group any text
538
- // nodes together into a single string output.
539
355
  for (var i = 0; i < arr.length; i++) {
540
356
  var node = arr[i];
541
357
  if (node.type === "text") {
@@ -664,14 +480,6 @@ var defaultRules = {
664
480
  list: {
665
481
  order: currOrder++,
666
482
  match: function (source, state) {
667
- // We only want to break into a list if we are at the start of a
668
- // line. This is to avoid parsing "hi * there" with "* there"
669
- // becoming a part of a list.
670
- // You might wonder, "but that's inline, so of course it wouldn't
671
- // start a list?". You would be correct! Except that some of our
672
- // lists can be inline, because they might be inside another list,
673
- // in which case we can parse with inline scope, but need to allow
674
- // nested lists inside this inline scope.
675
483
  var prevCaptureStr = state.prevCapture == null ? "" : state.prevCapture[0];
676
484
  var isStartOfLineCapture = LIST_LOOKBEHIND_R.exec(prevCaptureStr);
677
485
  var isListBlock = state._list || !state.inline;
@@ -686,58 +494,20 @@ var defaultRules = {
686
494
  var bullet = capture[2];
687
495
  var ordered = bullet.length > 1;
688
496
  var start = ordered ? +bullet : undefined;
689
- // @ts-expect-error - TS2322 - Type 'RegExpMatchArray | null' is not assignable to type 'string[]'.
690
497
  var items = capture[0].replace(LIST_BLOCK_END_R, "\n").match(LIST_ITEM_R);
691
-
692
- // We know this will match here, because of how the regexes are
693
- // defined
694
-
695
498
  var lastItemWasAParagraph = false;
696
499
  var itemContent = items.map(function (item, i) {
697
- // We need to see how far indented this item is:
698
500
  var prefixCapture = LIST_ITEM_PREFIX_R.exec(item);
699
501
  var space = prefixCapture ? prefixCapture[0].length : 0;
700
- // And then we construct a regex to "unindent" the subsequent
701
- // lines of the items by that amount:
702
502
  var spaceRegex = new RegExp("^ {1," + space + "}", "gm");
703
-
704
- // Before processing the item, we need a couple things
705
- var content = item
706
- // remove indents on trailing lines:
707
- .replace(spaceRegex, "")
708
- // remove the bullet:
709
- .replace(LIST_ITEM_PREFIX_R, "");
710
-
711
- // I'm not sur4 why this is necessary again?
712
-
713
- // Handling "loose" lists, like:
714
- //
715
- // * this is wrapped in a paragraph
716
- //
717
- // * as is this
718
- //
719
- // * as is this
503
+ var content = item.replace(spaceRegex, "").replace(LIST_ITEM_PREFIX_R, "");
720
504
  var isLastItem = i === items.length - 1;
721
505
  var containsBlocks = content.indexOf("\n\n") !== -1;
722
-
723
- // Any element in a list is a block if it contains multiple
724
- // newlines. The last element in the list can also be a block
725
- // if the previous item in the list was a block (this is
726
- // because non-last items in the list can end with \n\n, but
727
- // the last item can't, so we just "inherit" this property
728
- // from our previous element).
729
506
  var thisItemIsAParagraph = containsBlocks || isLastItem && lastItemWasAParagraph;
730
507
  lastItemWasAParagraph = thisItemIsAParagraph;
731
-
732
- // backup our state for restoration afterwards. We're going to
733
- // want to set state._list to true, and state.inline depending
734
- // on our list's looseness.
735
508
  var oldStateInline = state.inline;
736
509
  var oldStateList = state._list;
737
510
  state._list = true;
738
-
739
- // Parse inline if we're in a tight list, or block if we're in
740
- // a loose list.
741
511
  var adjustedContent;
742
512
  if (thisItemIsAParagraph) {
743
513
  state.inline = false;
@@ -747,8 +517,6 @@ var defaultRules = {
747
517
  adjustedContent = content.replace(LIST_ITEM_END_R, "");
748
518
  }
749
519
  var result = parse(adjustedContent, state);
750
-
751
- // Restore our state before returning
752
520
  state.inline = oldStateInline;
753
521
  state._list = oldStateList;
754
522
  return result;
@@ -783,43 +551,22 @@ var defaultRules = {
783
551
  },
784
552
  def: {
785
553
  order: currOrder++,
786
- // TODO(aria): This will match without a blank line before the next
787
- // block element, which is inconsistent with most of the rest of
788
- // simple-markdown.
789
554
  match: blockRegex(/^ *\[([^\]]+)\]: *<?([^\s>]*)>?(?: +["(]([^\n]+)[")])? *\n(?: *\n)*/),
790
555
  parse: function (capture, parse, state) {
791
556
  var def = capture[1].replace(/\s+/g, " ").toLowerCase();
792
557
  var target = capture[2];
793
558
  var title = capture[3];
794
-
795
- // Look for previous links/images using this def
796
- // If any links/images using this def have already been declared,
797
- // they will have added themselves to the state._refs[def] list
798
- // (_ to deconflict with client-defined state). We look through
799
- // that list of reflinks for this def, and modify those AST nodes
800
- // with our newly found information now.
801
- // Sorry :(.
802
559
  if (state._refs && state._refs[def]) {
803
- // `refNode` can be a link or an image
804
560
  state._refs[def].forEach(function (refNode) {
805
561
  refNode.target = target;
806
562
  refNode.title = title;
807
563
  });
808
564
  }
809
-
810
- // Add this def to our map of defs for any future links/images
811
- // In case we haven't found any or all of the refs referring to
812
- // this def yet, we add our def to the table of known defs, so
813
- // that future reflinks can modify themselves appropriately with
814
- // this information.
815
565
  state._defs = state._defs || {};
816
566
  state._defs[def] = {
817
567
  target: target,
818
568
  title: title
819
569
  };
820
-
821
- // return the relevant parsed information
822
- // for debugging only.
823
570
  return {
824
571
  def: def,
825
572
  target: target,
@@ -838,7 +585,7 @@ var defaultRules = {
838
585
  match: blockRegex(TABLES.TABLE_REGEX),
839
586
  parse: TABLES.parseTable,
840
587
  react: function (node, output, state) {
841
- var getStyle = function (colIndex) {
588
+ var getStyle = function getStyle(colIndex) {
842
589
  return node.align[colIndex] == null ? {} : {
843
590
  textAlign: node.align[colIndex]
844
591
  };
@@ -871,7 +618,7 @@ var defaultRules = {
871
618
  });
872
619
  },
873
620
  html: function (node, output, state) {
874
- var getStyle = function (colIndex) {
621
+ var getStyle = function getStyle(colIndex) {
875
622
  return node.align[colIndex] == null ? "" : "text-align:" + node.align[colIndex] + ";";
876
623
  };
877
624
  var headers = node.header.map(function (content, i) {
@@ -923,10 +670,6 @@ var defaultRules = {
923
670
  },
924
671
  escape: {
925
672
  order: currOrder++,
926
- // We don't allow escaping numbers, letters, or spaces here so that
927
- // backslashes used in plain text still get rendered. But allowing
928
- // escaping anything else provides a very flexible escape mechanism,
929
- // regardless of how this grammar is extended.
930
673
  match: inlineRegex(/^\\([^0-9A-Za-z\s])/),
931
674
  parse: function (capture, parse, state) {
932
675
  return {
@@ -950,7 +693,6 @@ var defaultRules = {
950
693
  type: "tableSeparator"
951
694
  };
952
695
  },
953
- // These shouldn't be reached, but in case they are, be reasonable:
954
696
  react: function () {
955
697
  return " | ";
956
698
  },
@@ -980,8 +722,6 @@ var defaultRules = {
980
722
  parse: function (capture, parse, state) {
981
723
  var address = capture[1];
982
724
  var target = capture[1];
983
-
984
- // Check for a `mailto:` already existing in the link:
985
725
  if (!AUTOLINK_MAILTO_CHECK_R.test(target)) {
986
726
  target = "mailto:" + target;
987
727
  }
@@ -1069,11 +809,7 @@ var defaultRules = {
1069
809
  },
1070
810
  reflink: {
1071
811
  order: currOrder++,
1072
- match: inlineRegex(new RegExp(
1073
- // The first [part] of the link
1074
- "^\\[(" + LINK_INSIDE + ")\\]" +
1075
- // The [ref] target of the link
1076
- "\\s*\\[([^\\]]*)\\]")),
812
+ match: inlineRegex(new RegExp("^\\[(" + LINK_INSIDE + ")\\]" + "\\s*\\[([^\\]]*)\\]")),
1077
813
  parse: function (capture, parse, state) {
1078
814
  return parseRef(capture, state, {
1079
815
  type: "link",
@@ -1085,11 +821,7 @@ var defaultRules = {
1085
821
  },
1086
822
  refimage: {
1087
823
  order: currOrder++,
1088
- match: inlineRegex(new RegExp(
1089
- // The first [part] of the link
1090
- "^!\\[(" + LINK_INSIDE + ")\\]" +
1091
- // The [ref] target of the link
1092
- "\\s*\\[([^\\]]*)\\]")),
824
+ match: inlineRegex(new RegExp("^!\\[(" + LINK_INSIDE + ")\\]" + "\\s*\\[([^\\]]*)\\]")),
1093
825
  parse: function (capture, parse, state) {
1094
826
  return parseRef(capture, state, {
1095
827
  type: "image",
@@ -1100,31 +832,9 @@ var defaultRules = {
1100
832
  html: null
1101
833
  },
1102
834
  em: {
1103
- order: currOrder /* same as strong/u */,
1104
- match: inlineRegex(new RegExp(
1105
- // only match _s surrounding words.
1106
- "^\\b_" + "((?:__|\\\\[\\s\\S]|[^\\\\_])+?)_" + "\\b" +
1107
- // Or match *s:
1108
- "|" +
1109
- // Only match *s that are followed by a non-space:
1110
- "^\\*(?=\\S)(" +
1111
- // Match at least one of:
1112
- "(?:" +
1113
- // - `**`: so that bolds inside italics don't close the
1114
- // italics
1115
- "\\*\\*|" +
1116
- // - escape sequence: so escaped *s don't close us
1117
- "\\\\[\\s\\S]|" +
1118
- // - whitespace: followed by a non-* (we don't
1119
- // want ' *' to close an italics--it might
1120
- // start a list)
1121
- "\\s+(?:\\\\[\\s\\S]|[^\\s\\*\\\\]|\\*\\*)|" +
1122
- // - non-whitespace, non-*, non-backslash characters
1123
- "[^\\s\\*\\\\]" + ")+?" +
1124
- // followed by a non-space, non-* then *
1125
- ")\\*(?!\\*)")),
835
+ order: currOrder,
836
+ match: inlineRegex(new RegExp("^\\b_" + "((?:__|\\\\[\\s\\S]|[^\\\\_])+?)_" + "\\b" + "|" + "^\\*(?=\\S)(" + "(?:" + "\\*\\*|" + "\\\\[\\s\\S]|" + "\\s+(?:\\\\[\\s\\S]|[^\\s\\*\\\\]|\\*\\*)|" + "[^\\s\\*\\\\]" + ")+?" + ")\\*(?!\\*)")),
1126
837
  quality: function (capture) {
1127
- // precedence by length, `em` wins ties:
1128
838
  return capture[0].length + 0.2;
1129
839
  },
1130
840
  parse: function (capture, parse, state) {
@@ -1142,10 +852,9 @@ var defaultRules = {
1142
852
  }
1143
853
  },
1144
854
  strong: {
1145
- order: currOrder /* same as em */,
855
+ order: currOrder,
1146
856
  match: inlineRegex(/^\*\*((?:\\[\s\S]|[^\\])+?)\*\*(?!\*)/),
1147
857
  quality: function (capture) {
1148
- // precedence by length, wins ties vs `u`:
1149
858
  return capture[0].length + 0.1;
1150
859
  },
1151
860
  parse: parseCaptureInline,
@@ -1159,10 +868,9 @@ var defaultRules = {
1159
868
  }
1160
869
  },
1161
870
  u: {
1162
- order: currOrder++ /* same as em&strong; increment for next rule */,
871
+ order: currOrder++,
1163
872
  match: inlineRegex(/^__((?:\\[\s\S]|[^\\])+?)__(?!_)/),
1164
873
  quality: function (capture) {
1165
- // precedence by length, loses all ties
1166
874
  return capture[0].length;
1167
875
  },
1168
876
  parse: parseCaptureInline,
@@ -1218,10 +926,6 @@ var defaultRules = {
1218
926
  },
1219
927
  text: {
1220
928
  order: currOrder++,
1221
- // Here we look for anything followed by non-symbols,
1222
- // double newlines, or double-space-newlines
1223
- // We break on any symbol characters so that this grammar
1224
- // is easy to extend without needing to modify this regex
1225
929
  match: anyScopeRegex(/^[\s\S]+?(?=[^0-9A-Za-z\s\u00c0-\uffff]|\n\n| {2,}\n|\w+:\S|$)/),
1226
930
  parse: function (capture, parse, state) {
1227
931
  return {
@@ -1236,42 +940,30 @@ var defaultRules = {
1236
940
  }
1237
941
  }
1238
942
  };
1239
-
1240
- /** (deprecated) */
1241
- var ruleOutput = function (rules, property) {
943
+ var ruleOutput = function ruleOutput(rules, property) {
1242
944
  if (!property && typeof console !== "undefined") {
1243
945
  console.warn("simple-markdown ruleOutput should take 'react' or " + "'html' as the second argument.");
1244
946
  }
1245
- var nestedRuleOutput = function (ast, outputFunc, state) {
1246
- // @ts-expect-error - TS2349 - This expression is not callable.
1247
- // Type 'unknown' has no call signatures.
947
+ var nestedRuleOutput = function nestedRuleOutput(ast, outputFunc, state) {
1248
948
  return rules[ast.type][property](ast, outputFunc, state);
1249
949
  };
1250
950
  return nestedRuleOutput;
1251
951
  };
1252
-
1253
- /** (deprecated)
1254
- */
1255
- var reactFor = function (outputFunc) {
1256
- var nestedOutput = function (ast, state) {
952
+ var reactFor = function reactFor(outputFunc) {
953
+ var nestedOutput = function nestedOutput(ast, state) {
1257
954
  state = state || {};
1258
955
  if (Array.isArray(ast)) {
1259
956
  var oldKey = state.key;
1260
957
  var result = [];
1261
-
1262
- // map nestedOutput over the ast, except group any text
1263
- // nodes together into a single string output.
1264
958
  var lastResult = null;
1265
959
  for (var i = 0; i < ast.length; i++) {
1266
960
  state.key = "" + i;
1267
961
  var nodeOut = nestedOutput(ast[i], state);
1268
962
  if (typeof nodeOut === "string" && typeof lastResult === "string") {
1269
- // @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'null'.
1270
963
  lastResult = lastResult + nodeOut;
1271
964
  result[result.length - 1] = lastResult;
1272
965
  } else {
1273
966
  result.push(nodeOut);
1274
- // @ts-expect-error - TS2322 - Type 'ReactNode' is not assignable to type 'null'.
1275
967
  lastResult = nodeOut;
1276
968
  }
1277
969
  }
@@ -1283,11 +975,8 @@ var reactFor = function (outputFunc) {
1283
975
  };
1284
976
  return nestedOutput;
1285
977
  };
1286
-
1287
- /** (deprecated)
1288
- */
1289
- var htmlFor = function (outputFunc) {
1290
- var nestedOutput = function (ast, state) {
978
+ var htmlFor = function htmlFor(outputFunc) {
979
+ var nestedOutput = function nestedOutput(ast, state) {
1291
980
  state = state || {};
1292
981
  if (Array.isArray(ast)) {
1293
982
  return ast.map(function (node) {
@@ -1299,54 +988,44 @@ var htmlFor = function (outputFunc) {
1299
988
  };
1300
989
  return nestedOutput;
1301
990
  };
1302
- var outputFor = function (rules, property) {
1303
- let defaultState = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
991
+ var outputFor = function outputFor(rules, property, defaultState = {}) {
1304
992
  if (!property) {
1305
993
  throw new Error("simple-markdown: outputFor: `property` must be " + "defined. " + "if you just upgraded, you probably need to replace `outputFor` " + "with `reactFor`");
1306
994
  }
1307
995
  var latestState;
1308
996
  var arrayRule = rules.Array || defaultRules.Array;
1309
-
1310
- // Tricks to convince tsc that this var is not null:
1311
- // @ts-expect-error - TS2538 - Type 'symbol' cannot be used as an index type.
1312
997
  var arrayRuleCheck = arrayRule[property];
1313
998
  if (!arrayRuleCheck) {
1314
- throw new Error("simple-markdown: outputFor: to join nodes of type `" +
1315
- // @ts-expect-error - TS2469 - The '+' operator cannot be applied to type 'symbol'.
1316
- property + "` you must provide an `Array:` joiner rule with that type, " + "Please see the docs for details on specifying an Array rule.");
999
+ throw new Error("simple-markdown: outputFor: to join nodes of type `" + property + "` you must provide an `Array:` joiner rule with that type, " + "Please see the docs for details on specifying an Array rule.");
1317
1000
  }
1318
1001
  var arrayRuleOutput = arrayRuleCheck;
1319
- var nestedOutput = function (ast, state) {
1002
+ var nestedOutput = function nestedOutput(ast, state) {
1320
1003
  state = state || latestState;
1321
1004
  latestState = state;
1322
1005
  if (Array.isArray(ast)) {
1323
1006
  return arrayRuleOutput(ast, nestedOutput, state);
1324
1007
  } else {
1325
- // @ts-expect-error - TS2349 - This expression is not callable.
1326
- // Type 'unknown' has no call signatures.
1327
1008
  return rules[ast.type][property](ast, nestedOutput, state);
1328
1009
  }
1329
1010
  };
1330
- var outerOutput = function (ast, state) {
1011
+ var outerOutput = function outerOutput(ast, state) {
1331
1012
  latestState = populateInitialState(state, defaultState);
1332
1013
  return nestedOutput(ast, latestState);
1333
1014
  };
1334
1015
  return outerOutput;
1335
1016
  };
1336
-
1337
- // @ts-expect-error - TS2345 - Argument of type 'DefaultRules' is not assignable to parameter of type 'ParserRules'.
1338
1017
  var defaultRawParse = parserFor(defaultRules);
1339
- var defaultBlockParse = function (source, state) {
1018
+ var defaultBlockParse = function defaultBlockParse(source, state) {
1340
1019
  state = state || {};
1341
1020
  state.inline = false;
1342
1021
  return defaultRawParse(source, state);
1343
1022
  };
1344
- var defaultInlineParse = function (source, state) {
1023
+ var defaultInlineParse = function defaultInlineParse(source, state) {
1345
1024
  state = state || {};
1346
1025
  state.inline = true;
1347
1026
  return defaultRawParse(source, state);
1348
1027
  };
1349
- var defaultImplicitParse = function (source, state) {
1028
+ var defaultImplicitParse = function defaultImplicitParse(source, state) {
1350
1029
  var isBlock = BLOCK_END_R.test(source);
1351
1030
  state = state || {};
1352
1031
  state.inline = !isBlock;
@@ -1354,16 +1033,13 @@ var defaultImplicitParse = function (source, state) {
1354
1033
  };
1355
1034
  var defaultReactOutput = outputFor(defaultRules, "react");
1356
1035
  var defaultHtmlOutput = outputFor(defaultRules, "html");
1357
- var markdownToReact = function (source, state) {
1036
+ var markdownToReact = function markdownToReact(source, state) {
1358
1037
  return defaultReactOutput(defaultBlockParse(source, state), state);
1359
1038
  };
1360
- var markdownToHtml = function (source, state) {
1039
+ var markdownToHtml = function markdownToHtml(source, state) {
1361
1040
  return defaultHtmlOutput(defaultBlockParse(source, state), state);
1362
1041
  };
1363
-
1364
- // TODO: This needs definition
1365
-
1366
- var ReactMarkdown = function (props) {
1042
+ var ReactMarkdown = function ReactMarkdown(props) {
1367
1043
  var divProps = {};
1368
1044
  for (var prop in props) {
1369
1045
  if (prop !== "source" && Object.prototype.hasOwnProperty.call(props, prop)) {
@@ -1382,7 +1058,6 @@ var SimpleMarkdown = {
1382
1058
  anyScopeRegex: anyScopeRegex,
1383
1059
  parseInline: parseInline,
1384
1060
  parseBlock: parseBlock,
1385
- // default wrappers:
1386
1061
  markdownToReact: markdownToReact,
1387
1062
  markdownToHtml: markdownToHtml,
1388
1063
  ReactMarkdown: ReactMarkdown,
@@ -1397,33 +1072,23 @@ var SimpleMarkdown = {
1397
1072
  unescapeUrl: unescapeUrl,
1398
1073
  htmlTag: htmlTag,
1399
1074
  reactElement: reactElement,
1400
- // deprecated:
1401
1075
  defaultRawParse: defaultRawParse,
1402
1076
  ruleOutput: ruleOutput,
1403
1077
  reactFor: reactFor,
1404
1078
  htmlFor: htmlFor,
1405
- defaultParse: function () {
1079
+ defaultParse: function (...args) {
1406
1080
  if (typeof console !== "undefined") {
1407
1081
  console.warn("defaultParse is deprecated, please use `defaultImplicitParse`");
1408
1082
  }
1409
- // @ts-expect-error - Argument of type 'any[]' is not assignable to parameter of type '[node: ASTNode, state?: State | null | undefined]'. Target requires 1 element(s) but source may have fewer.
1410
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
1411
- args[_key] = arguments[_key];
1412
- }
1413
1083
  return defaultImplicitParse.apply(null, args);
1414
1084
  },
1415
- defaultOutput: function () {
1085
+ defaultOutput: function (...args) {
1416
1086
  if (typeof console !== "undefined") {
1417
1087
  console.warn("defaultOutput is deprecated, please use `defaultReactOutput`");
1418
1088
  }
1419
- // @ts-expect-error - Argument of type 'any[]' is not assignable to parameter of type '[node: ASTNode, state?: State | null | undefined]'. Target requires 1 element(s) but source may have fewer.
1420
- for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
1421
- args[_key2] = arguments[_key2];
1422
- }
1423
1089
  return defaultReactOutput.apply(null, args);
1424
1090
  }
1425
1091
  };
1426
1092
 
1427
- exports["default"] = SimpleMarkdown;
1428
- exports.libVersion = libVersion;
1093
+ export { SimpleMarkdown as default, libVersion };
1429
1094
  //# sourceMappingURL=index.js.map