@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 +59 -433
- package/dist/index.js.map +1 -1
- package/package.json +15 -6
- package/dist/es/index.js +0 -1457
- package/dist/es/index.js.map +0 -1
- package/dist/shared-utils/add-library-version-to-perseus-debug.d.ts +0 -9
package/dist/index.js
CHANGED
|
@@ -1,74 +1,16 @@
|
|
|
1
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
"/": "/",
|
|
353
200
|
"`": "`"
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1467
|
-
exports.libVersion = libVersion;
|
|
1093
|
+
export { SimpleMarkdown as default, libVersion };
|
|
1468
1094
|
//# sourceMappingURL=index.js.map
|