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