@khanacademy/simple-markdown 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @khanacademy/simple-markdown
2
+
3
+ ## 0.8.1
4
+
5
+ ### Patch Changes
6
+
7
+ - ca76baa3: Move simple-markdown into perseus repo
package/README.md ADDED
@@ -0,0 +1,453 @@
1
+ simple-markdown
2
+ ===============
3
+
4
+ simple-markdown is a markdown-like parser designed for simplicity
5
+ and extensibility.
6
+
7
+ Philosophy
8
+ ----------
9
+
10
+ Most markdown-like parsers aim for [speed][marked] or
11
+ [edge case handling][CommonMark].
12
+ simple-markdown aims for extensibility and simplicity.
13
+
14
+ [marked]: https://github.com/chjj/marked
15
+ [CommonMark]: https://github.com/jgm/CommonMark
16
+
17
+ What does this mean?
18
+ Many websites using markdown-like languages have custom extensions,
19
+ such as `@`mentions or issue number linking. Unfortunately, most
20
+ markdown-like parsers don't allow extension without
21
+ forking, and can be difficult to modify even when forked.
22
+ simple-markdown is designed to allow simple addition of
23
+ custom extensions without needing to be forked.
24
+
25
+ At Khan Academy, we use simple-markdown to format
26
+ over half of our math exercises, because we need
27
+ [markdown extensions][PerseusMarkdown] for math text and
28
+ interactive widgets.
29
+
30
+ simple-markdown is [MIT licensed][LICENSE].
31
+
32
+ [LICENSE]: https://github.com/Khan/perseus/blob/master/LICENSE
33
+
34
+ Getting started
35
+ ---------------
36
+
37
+ First, let's parse and output some generic markdown using
38
+ simple-markdown.
39
+
40
+ If you want to run these examples in
41
+ node, you should run `npm install` in the simple-markdown
42
+ folder or `npm install simple-markdown` in your project's
43
+ folder. Then you can acquire the `SimpleMarkdown` variable
44
+ with:
45
+
46
+ ```javascript
47
+ import SimpleMarkdown from '@khanacademy/simple-markdown'
48
+ ```
49
+
50
+ Then let's get a basic markdown parser and outputter.
51
+ `SimpleMarkdown` provides default parsers/outputters for
52
+ generic markdown:
53
+
54
+ ```javascript
55
+ var mdParse = SimpleMarkdown.defaultBlockParse;
56
+ var mdOutput = SimpleMarkdown.defaultOutput;
57
+ ```
58
+
59
+ `mdParse` can give us a syntax tree:
60
+
61
+ ```javascript
62
+ var syntaxTree = mdParse("Here is a paragraph and an *em tag*.");
63
+ ```
64
+
65
+ Let's inspect our syntax tree:
66
+
67
+ ```javascript
68
+ // pretty-print this with 4-space indentation:
69
+ console.log(JSON.stringify(syntaxTree, null, 4));
70
+ => [
71
+ {
72
+ "content": [
73
+ {
74
+ "content": "Here is a paragraph and an ",
75
+ "type": "text"
76
+ },
77
+ {
78
+ "content": [
79
+ {
80
+ "content": "em tag",
81
+ "type": "text"
82
+ }
83
+ ],
84
+ "type": "em"
85
+ },
86
+ {
87
+ "content": ".",
88
+ "type": "text"
89
+ }
90
+ ],
91
+ "type": "paragraph"
92
+ }
93
+ ]
94
+ ```
95
+
96
+ Then to turn that into an array of React elements, we can
97
+ call `mdOutput`:
98
+
99
+ ```javascript
100
+ mdOutput(syntaxTree)
101
+ => [ { type: 'div',
102
+ key: null,
103
+ ref: null,
104
+ _owner: null,
105
+ _context: {},
106
+ _store: { validated: false, props: [Object] } } ]
107
+ ```
108
+
109
+
110
+ Adding a simple extension
111
+ -------------------------
112
+
113
+ Let's add an underline extension! To do this, we'll need to create
114
+ a new rule and then make a new parser/outputter. The next section
115
+ will explain how all of these steps work in greater detail. (To
116
+ follow along with these examples, you'll also need
117
+ [underscore][underscore].)
118
+
119
+ [underscore]: http://underscorejs.org/
120
+
121
+ First, we create a new rule. We'll look for double underscores
122
+ surrounding text.
123
+
124
+ We'll put underlines right
125
+ before `em`s, so that `__` will be parsed before `_`
126
+ for emphasis/italics.
127
+
128
+ A regex to capture this would look something
129
+ like `/^__([\s\S]+?)__(?!_)/`. This matches `__`, followed by
130
+ any content until it finds another `__` not followed by a
131
+ third `_`.
132
+
133
+ ```javascript
134
+ var underlineRule = {
135
+ // Specify the order in which this rule is to be run
136
+ order: SimpleMarkdown.defaultRules.em.order - 0.5,
137
+
138
+ // First we check whether a string matches
139
+ match: function(source) {
140
+ return /^__([\s\S]+?)__(?!_)/.exec(source);
141
+ },
142
+
143
+ // Then parse this string into a syntax node
144
+ parse: function(capture, parse, state) {
145
+ return {
146
+ content: parse(capture[1], state)
147
+ };
148
+ },
149
+
150
+ // Finally transform this syntax node into a
151
+ // React element
152
+ react: function(node, output) {
153
+ return React.DOM.u(null, output(node.content));
154
+ },
155
+
156
+ // Or an html element:
157
+ // (Note: you may only need to make one of `react:` or
158
+ // `html:`, as long as you never ask for an outputter
159
+ // for the other type.)
160
+ html: function(node, output) {
161
+ return '<u>' + output(node.content) + '</u>';
162
+ },
163
+ };
164
+ ```
165
+
166
+ Then, we need to add this rule to the other rules:
167
+
168
+ ```javascript
169
+ var rules = _.extend({}, SimpleMarkdown.defaultRules, {
170
+ underline: underlineRule
171
+ });
172
+ ```
173
+
174
+ Finally, we need to build our parser and outputters:
175
+
176
+ ```javascript
177
+ var rawBuiltParser = SimpleMarkdown.parserFor(rules);
178
+ var parse = function(source) {
179
+ var blockSource = source + "\n\n";
180
+ return rawBuiltParser(blockSource, {inline: false});
181
+ };
182
+ // You probably only need one of these: choose depending on
183
+ // whether you want react nodes or an html string:
184
+ var reactOutput = SimpleMarkdown.outputFor(rules, 'react');
185
+ var htmlOutput = SimpleMarkdown.outputFor(rules, 'html');
186
+
187
+ ```
188
+
189
+ Now we can use our custom `parse` and `output` functions to parse
190
+ markdown with underlines!
191
+
192
+ ```javascript
193
+ var syntaxTree = parse("__hello underlines__");
194
+ console.log(JSON.stringify(syntaxTree, null, 4));
195
+ => [
196
+ {
197
+ "content": [
198
+ {
199
+ "content": [
200
+ {
201
+ "content": "hello underlines",
202
+ "type": "text"
203
+ }
204
+ ],
205
+ "type": "underline"
206
+ }
207
+ ],
208
+ "type": "paragraph"
209
+ }
210
+ ]
211
+
212
+ reactOutput(syntaxTree)
213
+ => [ { type: 'div',
214
+ key: null,
215
+ ref: null,
216
+ _owner: null,
217
+ _context: {},
218
+ _store: { validated: false, props: [Object] } } ]
219
+
220
+ htmlOutput(syntaxTree)
221
+
222
+ => '<div class="paragraph"><u>hello underlines</u></div>'
223
+ ```
224
+
225
+
226
+ Basic parsing/output API
227
+ ------------------------
228
+
229
+ #### `SimpleMarkdown.defaultBlockParse(source)`
230
+
231
+ Returns a syntax tree of the result of parsing `source` with the
232
+ default markdown rules. Assumes a block scope.
233
+
234
+ #### `SimpleMarkdown.defaultInlineParse(source)`
235
+
236
+ Returns a syntax tree of the result of parsing `source` with the
237
+ default markdown rules, where `source` is assumed to be inline text.
238
+ Does not emit `<p>` elements. Useful for allowing inline markdown
239
+ formatting in one-line fields where paragraphs, lists, etc. are
240
+ disallowed.
241
+
242
+ #### `SimpleMarkdown.defaultImplicitParse(source)`
243
+
244
+ Parses `source` as block if it ends with `\n\n`, or inline if not.
245
+
246
+ #### `SimpleMarkdown.defaultOutput(syntaxTree)`
247
+
248
+ Returns React-renderable output for `syntaxTree`.
249
+
250
+ *Note: raw html output will be coming soon*
251
+
252
+
253
+ Extension Overview
254
+ ------------------
255
+
256
+ Elements in simple-markdown are generally created from rules.
257
+ For parsing, rules must specify `match` and `parse` methods.
258
+ For output, rules must specify a `react` or `html` method
259
+ (or both), depending on which outputter you create afterwards.
260
+
261
+ Here is an example rule, a slightly modified version of what
262
+ simple-markdown uses for parsing **strong** (**bold**) text:
263
+
264
+ ```javascript
265
+ strong: {
266
+ match: function(source, state, lookbehind) {
267
+ return /^\*\*([\s\S]+?)\*\*(?!\*)/.exec(source);
268
+ },
269
+ parse: function(capture, recurseParse, state) {
270
+ return {
271
+ content: recurseParse(capture[1], state)
272
+ };
273
+ },
274
+ react: function(node, recurseOutput) {
275
+ return React.DOM.strong(null, recurseOutput(node.content));
276
+ },
277
+ html: function(node, recurseOutput) {
278
+ return '<strong>' + recurseOutput(node.content) + '</strong>';
279
+ },
280
+ },
281
+ ```
282
+
283
+ Let's look at those three methods in more detail.
284
+
285
+ #### `match(source, state, lookbehind)`
286
+
287
+ simple-markdown calls your `match` function to determine whether the
288
+ upcoming markdown source matches this rule or not.
289
+
290
+ `source` is the upcoming source, beginning at the current position of
291
+ parsing (source[0] is the next character).
292
+
293
+ `state` is a mutable state object to allow for more complicated matching
294
+ and parsing. The most common field on `state` is `inline`, which all of
295
+ the default rules set to true when we are in an inline scope, and false
296
+ or undefined when we are in a block scope.
297
+
298
+ **DEPRECATED - use `state.prevCapture` instead.** `lookbehind` is the string previously captured at this parsing level, to
299
+ allow for lookbehind. For example, lists check that lookbehind ends with
300
+ `/^$|\n *$/` to ensure that lists only match at the beginning of a new
301
+ line.
302
+
303
+ If this rule matches, `match` should return an object, array, or
304
+ array-like object, which we'll call `capture`, where `capture[0]`
305
+ is the full matched source, and any other fields can be used in the
306
+ rule's `parse` function. The return value from `Regexp.prototype.exec`
307
+ fits this requirement, and the common use case is to return the result
308
+ of `someRegex.exec(source)`.
309
+
310
+ If this rule does not match, `match` should return null.
311
+
312
+ NOTE: If you are using regexes in your match function, your regex
313
+ should always begin with `^`. Regexes without leading `^`s can
314
+ cause unexpected output or infinite loops.
315
+
316
+ #### `parse(capture, recurseParse, state)`
317
+
318
+ `parse` takes the output of `match` and transforms it into a syntax
319
+ tree node object, which we'll call `node` here.
320
+
321
+ `capture` is the non-null result returned from match.
322
+
323
+ `recurseParse` is a function that can be called on sub-content and
324
+ state to recursively parse the sub-content. This returns an array.
325
+
326
+ `state` is the mutable state threading object, which can be examined
327
+ or modified, and should be passed as the third argument to any
328
+ `recurseParse` calls.
329
+
330
+ For example, to parse inline sub-content, you can add `inline: true`
331
+ to state, or `inline: false` to force block parsing (to leave the
332
+ parsing scope alone, you can just pass `state` with no modifications).
333
+ For example:
334
+
335
+ ```javascript
336
+ var innerText = capture[1];
337
+ recurseParse(innerText, _.defaults({
338
+ inline: true
339
+ }, state));
340
+ ```
341
+
342
+ `parse` should return a `node` object, which can have custom fields
343
+ that will be passed to `output`, below. The one reserved field is
344
+ `type`, which designates the type of the node, which will be used
345
+ for output. If no type is specified, simple-markdown will use the
346
+ current rule's type (the common case). If you have multiple ways
347
+ to parse a single element, it can be useful to have multiple rules
348
+ that all return nodes of the same type.
349
+
350
+ #### `react(node, recurseOutput, state)`
351
+
352
+ `react` takes a syntax tree `node` and transforms it into
353
+ React-renderable output.
354
+
355
+ `node` is the return value from `parse`, which has a type
356
+ field of the same type as the current rule, as well as any
357
+ custom fields created by `parse`.
358
+
359
+ `recurseOutput` is a function to recursively output sub-tree
360
+ nodes created by using `recurseParse` in `parse`.
361
+
362
+ `state` is the mutable state threading object, which can be
363
+ examined or modified, and should be passed as the second
364
+ argument to any recurseOutput calls.
365
+
366
+ The simple-markdown API contains several helper methods for
367
+ creating rules, as well as methods for creating parsers and
368
+ outputters from rules.
369
+
370
+ Extension API
371
+ -------------
372
+
373
+ simple-markdown includes access to the default list of rules,
374
+ as well as several functions to allow you to create parsers and
375
+ outputters from modifications of those default rules, or even
376
+ from a totally custom rule list.
377
+
378
+ These functions are separated so that you can customize
379
+ intermediate steps in the parsing/output process, if necessary.
380
+
381
+ #### `SimpleMarkdown.defaultRules`
382
+
383
+ The default rules, specified as an object, where the keys are
384
+ the rule types, and the values are objects containing `order`,
385
+ `match`, `parse`, `react`, and `html` fields (these rules can
386
+ be used for both parsing and outputting).
387
+
388
+ #### `SimpleMarkdown.parserFor(rules)`
389
+
390
+ Takes a `rules` object and returns a parser for the rule types
391
+ in the rules object, in order of increasing `order` fields,
392
+ which must be present and a finite number for each rule.
393
+ In the case of order field ties, rules are ordered
394
+ lexicographically by rule name. Each of the rules in the `rules`
395
+ object must contain a `match` and a `parse` function.
396
+
397
+ #### `SimpleMarkdown.outputFor(rules, key)`
398
+
399
+ Takes a `rules` object and a `key` that indicates which key in
400
+ the rules object is mapped to the function that generates the
401
+ output type you want. This will be `'react'` or `'html'` unless
402
+ you are defining a custom output type.
403
+
404
+ It returns a function that outputs a single syntax tree node of
405
+ any type that is in the `rules` object, given a node and a
406
+ recursive output function.
407
+
408
+ #### Putting it all together
409
+
410
+ Given a set of rules, one can create a single function
411
+ that takes an input content string and outputs a
412
+ React-renderable as follows. Note that since many rules
413
+ expect blocks to end in `"\n\n"`, we append that to source
414
+ input manually, in addition to specifying `inline: false`
415
+ (`inline: false` is technically optional for all of the
416
+ default rules, which assume `inline` is false if it is
417
+ undefined).
418
+
419
+ ```javascript
420
+ var rules = {
421
+ ...SimpleMarkdown.defaultRules,
422
+ paragraph: {
423
+ ...SimpleMarkdown.defaultRules.paragraph,
424
+ react: (node, output, state) => {
425
+ return <p key={state.key}>{output(node.content, state)}</p>;
426
+ }
427
+ }
428
+ };
429
+
430
+ var parser = SimpleMarkdown.parserFor(rules);
431
+ var reactOutput = SimpleMarkdown.outputFor(rules, 'react'));
432
+ var htmlOutput = SimpleMarkdown.outputFor(rules, 'html'));
433
+
434
+ var blockParseAndOutput = function(source) {
435
+ // Many rules require content to end in \n\n to be interpreted
436
+ // as a block.
437
+ var blockSource = source + "\n\n";
438
+ var parseTree = parser(blockSource, {inline: false});
439
+ var outputResult = htmlOutput(parseTree);
440
+ // Or for react output, use:
441
+ // var outputResult = reactOutput(parseTree);
442
+ return outputResult;
443
+ };
444
+ ```
445
+
446
+ Extension rules helper functions
447
+ --------------------------------
448
+
449
+ *Coming soon*
450
+
451
+ LICENSE
452
+ -------
453
+ MIT. See the LICENSE file for text.
@@ -0,0 +1,2 @@
1
+ var t,n,r,e,u,o,i,a,l=/\r\n?/g,c=/\t/g,f=/\f/g,p=function(t){return t.replace(l,"\n").replace(f,"").replace(c," ")},s=function(t,n){var r=t||{};if(null!=n)for(var e in n)Object.prototype.hasOwnProperty.call(n,e)&&(r[e]=n[e]);return r},h=function(t,n){var r,e=Object.keys(t).filter((function(n){var r=t[n];if(null==r||null==r.match)return!1;var e=r.order;return"number"==typeof e&&isFinite(e)||"undefined"==typeof console||console.warn("simple-markdown: Invalid order for rule `"+n+"`: "+String(e)),!0}));e.sort((function(n,r){var e=t[n],u=t[r],o=e.order,i=u.order;if(o!==i)return o-i;var a=e.quality?0:1,l=u.quality?0:1;return a!==l?a-l:n<r?-1:n>r?1:0}));var u=function n(u,o){var i=[];for(r=o=o||r;u;){var a=null,l=null,c=null,f=NaN,p=0,s=e[0],h=t[s];do{var d=h.order,g=null==o.prevCapture?"":o.prevCapture[0],m=h.match(u,o,g);if(m){var y=h.quality?h.quality(m,o,g):0;y<=f||(a=s,l=h,c=m,f=y)}p++,s=e[p],h=t[s]}while(h&&(!c||h.order===d&&h.quality));if(null==l||null==c)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 '"+e[e.length-1]+"'. It seems to not match the following source:\n"+u);if(c.index)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?");var v=l.parse(c,n,o);Array.isArray(v)?Array.prototype.push.apply(i,v):(null==v.type&&(v.type=a),i.push(v)),o.prevCapture=c,u=u.substring(o.prevCapture[0].length)}return i};return function(t,e){return(r=s(e,n)).inline||r.disableAutoBlockNewlines||(t+="\n\n"),r.prevCapture=null,u(p(t),r)}},d=function(t){var n=function(n,r,e){return r.inline?t.exec(n):null};return n.regex=t,n},g=function(t){var n=function(n,r){return r.inline?null:t.exec(n)};return n.regex=t,n},m=function(t){var n=function(n,r){return t.exec(n)};return n.regex=t,n},y="function"==typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103,v=function(t,n,r){return{$$typeof:y,type:t,key:null==n?void 0:n,ref:null,props:r,_owner:null}},S=function(t,n,r,e){r=r||{},e=void 0===e||e;var u="";for(var o in r){var i=r[o];Object.prototype.hasOwnProperty.call(r,o)&&i&&(u+=" "+_(o)+'="'+_(i)+'"')}var a="<"+t+u+">";return e?a+n+"</"+t+">":a},k={},w=function(t){if(null==t)return null;try{var n=new URL(t,"https://localhost").protocol;if(0===n.indexOf("javascript:")||0===n.indexOf("vbscript:")||0===n.indexOf("data:"))return null}catch(t){return null}return t},x=/[<>&"']/g,b={"<":"&lt;",">":"&gt;","&":"&amp;",'"':"&quot;","'":"&#x27;","/":"&#x2F;","`":"&#96;"},_=function(t){return String(t).replace(x,(function(t){return b[t]}))},E=/\\([^0-9A-Za-z\s])/g,R=function(t){return t.replace(E,"$1")},A=function(t,n,r){var e=r.inline||!1;r.inline=!0;var u=t(n,r);return r.inline=e,u},$=function(t,n,r){return{content:A(n,t[1],r)}},O=function(){return{}},T=new RegExp("^( *)((?:[*+-]|\\d+\\.)) +"),j=new RegExp("( *)((?:[*+-]|\\d+\\.)) +[^\\n]*(?:\\n(?!\\1(?:[*+-]|\\d+\\.) )[^\\n]*)*(\n|$)","gm"),P=/\n{2,}$/,C=/^ (?= *`)|(` *) $/g,q=P,F=/ *\n+$/,B=new RegExp("^( *)((?:[*+-]|\\d+\\.)) [\\s\\S]+?(?:\n{2,}(?! )(?!\\1(?:[*+-]|\\d+\\.) )\\n*|\\s*\n*$)"),N=/(?:^|\n)( *)$/,L=(t=/^ *\| *| *\| *$/g,n=/ *$/,r=/^ *-+: *$/,e=/^ *:-+: *$/,u=/^ *:-+ *$/,o=function(t){return r.test(t)?"right":e.test(t)?"center":u.test(t)?"left":null},i=function(t,r,e,u){var o=e.inTable;e.inTable=!0;var i=r(t.trim(),e);e.inTable=o;var a=[[]];return i.forEach((function(t,r){"tableSeparator"===t.type?(!u||0!==r&&r!==i.length-1)&&a.push([]):("text"!==t.type||null!=i[r+1]&&"tableSeparator"!==i[r+1].type||(t.content=t.content.replace(n,"")),a[a.length-1].push(t))})),a},{parseTable:(a=function(n){return function(r,e,u){u.inline=!0;var a=i(r[1],e,u,n),l=function(n,r,e,u){return u&&(n=n.replace(t,"")),n.trim().split("|").map(o)}(r[2],0,0,n),c=function(t,n,r,e){return t.trim().split("\n").map((function(t){return i(t,n,r,e)}))}(r[3],e,u,n);return u.inline=!1,{type:"table",header:a,align:l,cells:c}}})(!0),parseNpTable:a(!1),TABLE_REGEX:/^ *(\|.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/,NPTABLE_REGEX:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/}),I="(?:\\[[^\\]]*\\]|[^\\[\\]]|\\](?=[^\\[]*\\]))*",z="\\s*<?((?:\\([^)]*\\)|[^\\s\\\\]|\\\\.)*?)>?(?:\\s+['\"]([\\s\\S]*?)['\"])?\\s*",G=/mailto:/i,X=function(t,n,r){var e=(t[2]||t[1]).replace(/\s+/g," ").toLowerCase();if(n._defs&&n._defs[e]){var u=n._defs[e];r.target=u.target,r.title=u.title}return n._refs=n._refs||{},n._refs[e]=n._refs[e]||[],n._refs[e].push(r),r},U=0,Z={Array:{react:function(t,n,r){for(var e=r.key,u=[],o=0,i=0;o<t.length;o++,i++){r.key=""+o;var a=t[o];if("text"===a.type)for(a={type:"text",content:a.content};o+1<t.length&&"text"===t[o+1].type;o++)a.content+=t[o+1].content;u.push(n(a,r))}return r.key=e,u},html:function(t,n,r){for(var e="",u=0;u<t.length;u++){var o=t[u];if("text"===o.type)for(o={type:"text",content:o.content};u+1<t.length&&"text"===t[u+1].type;u++)o.content+=t[u+1].content;e+=n(o,r)}return e}},heading:{order:U++,match:g(/^ *(#{1,6})([^\n]+?)#* *(?:\n *)+\n/),parse:function(t){function n(n,r,e){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}((function(t,n,r){return{level:t[1].length,content:A(n,t[2].trim(),r)}})),react:function(t,n,r){return v("h"+t.level,r.key,{children:n(t.content,r)})},html:function(t,n,r){return S("h"+t.level,n(t.content,r))}},nptable:{order:U++,match:g(L.NPTABLE_REGEX),parse:L.parseNpTable,react:null,html:null},lheading:{order:U++,match:g(/^([^\n]+)\n *(=|-){3,} *(?:\n *)+\n/),parse:function(t){function n(n,r,e){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}((function(t,n,r){return{type:"heading",level:"="===t[2]?1:2,content:A(n,t[1],r)}})),react:null,html:null},hr:{order:U++,match:g(/^( *[-*_]){3,} *(?:\n *)+\n/),parse:O,react:function(t,n,r){return v("hr",r.key,k)},html:function(t,n,r){return"<hr>"}},codeBlock:{order:U++,match:g(/^(?: [^\n]+\n*)+(?:\n *)+\n/),parse:function(t){function n(n,r,e){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}((function(t,n,r){return{lang:void 0,content:t[0].replace(/^ /gm,"").replace(/\n+$/,"")}})),react:function(t,n,r){var e=t.lang?"markdown-code-"+t.lang:void 0;return v("pre",r.key,{children:v("code",null,{className:e,children:t.content})})},html:function(t,n,r){var e=t.lang?"markdown-code-"+t.lang:void 0,u=S("code",_(t.content),{class:e});return S("pre",u)}},fence:{order:U++,match:g(/^ *(`{3,}|~{3,}) *(?:(\S+) *)?\n([\s\S]+?)\n?\1 *(?:\n *)+\n/),parse:function(t){function n(n,r,e){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}((function(t,n,r){return{type:"codeBlock",lang:t[2]||void 0,content:t[3]}})),react:null,html:null},blockQuote:{order:U++,match:g(/^( *>[^\n]+(\n[^\n]+)*\n*)+\n{2,}/),parse:function(t){function n(n,r,e){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}((function(t,n,r){return{content:n(t[0].replace(/^ *> ?/gm,""),r)}})),react:function(t,n,r){return v("blockquote",r.key,{children:n(t.content,r)})},html:function(t,n,r){return S("blockquote",n(t.content,r))}},list:{order:U++,match:function(t,n){var r=null==n.prevCapture?"":n.prevCapture[0],e=N.exec(r),u=n._list||!n.inline;return e&&u?(t=e[1]+t,B.exec(t)):null},parse:function(t){function n(n,r,e){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}((function(t,n,r){var e=t[2],u=e.length>1,o=u?+e:void 0,i=t[0].replace(q,"\n").match(j),a=!1;return{ordered:u,start:o,items:i.map((function(t,e){var u=T.exec(t),o=u?u[0].length:0,l=new RegExp("^ {1,"+o+"}","gm"),c=t.replace(l,"").replace(T,""),f=e===i.length-1,p=-1!==c.indexOf("\n\n")||f&&a;a=p;var s,h=r.inline,d=r._list;r._list=!0,p?(r.inline=!1,s=c.replace(F,"\n\n")):(r.inline=!0,s=c.replace(F,""));var g=n(s,r);return r.inline=h,r._list=d,g}))}})),react:function(t,n,r){var e=t.ordered?"ol":"ul";return v(e,r.key,{start:t.start,children:t.items.map((function(t,e){return v("li",""+e,{children:n(t,r)})}))})},html:function(t,n,r){var e=t.items.map((function(t){return S("li",n(t,r))})).join(""),u=t.ordered?"ol":"ul",o={start:t.start};return S(u,e,o)}},def:{order:U++,match:g(/^ *\[([^\]]+)\]: *<?([^\s>]*)>?(?: +["(]([^\n]+)[")])? *\n(?: *\n)*/),parse:function(t){function n(n,r,e){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}((function(t,n,r){var e=t[1].replace(/\s+/g," ").toLowerCase(),u=t[2],o=t[3];return r._refs&&r._refs[e]&&r._refs[e].forEach((function(t){t.target=u,t.title=o})),r._defs=r._defs||{},r._defs[e]={target:u,title:o},{def:e,target:u,title:o}})),react:function(){return null},html:function(){return""}},table:{order:U++,match:g(L.TABLE_REGEX),parse:L.parseTable,react:function(t,n,r){var e=function(n){return null==t.align[n]?{}:{textAlign:t.align[n]}},u=t.header.map((function(t,u){return v("th",""+u,{style:e(u),scope:"col",children:n(t,r)})})),o=t.cells.map((function(t,u){return v("tr",""+u,{children:t.map((function(t,u){return v("td",""+u,{style:e(u),children:n(t,r)})}))})}));return v("table",r.key,{children:[v("thead","thead",{children:v("tr",null,{children:u})}),v("tbody","tbody",{children:o})]})},html:function(t,n,r){var e=function(n){return null==t.align[n]?"":"text-align:"+t.align[n]+";"},u=t.header.map((function(t,u){return S("th",n(t,r),{style:e(u),scope:"col"})})).join(""),o=t.cells.map((function(t){var u=t.map((function(t,u){return S("td",n(t,r),{style:e(u)})})).join("");return S("tr",u)})).join(""),i=S("thead",S("tr",u)),a=S("tbody",o);return S("table",i+a)}},newline:{order:U++,match:g(/^(?:\n *)*\n/),parse:O,react:function(t,n,r){return"\n"},html:function(t,n,r){return"\n"}},paragraph:{order:U++,match:g(/^((?:[^\n]|\n(?! *\n))+)(?:\n *)+\n/),parse:$,react:function(t,n,r){return v("div",r.key,{className:"paragraph",children:n(t.content,r)})},html:function(t,n,r){return S("div",n(t.content,r),{class:"paragraph"})}},escape:{order:U++,match:d(/^\\([^0-9A-Za-z\s])/),parse:function(t){function n(n,r,e){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}((function(t,n,r){return{type:"text",content:t[1]}})),react:null,html:null},tableSeparator:{order:U++,match:function(t,n){return n.inTable?/^ *\| */.exec(t):null},parse:function(){return{type:"tableSeparator"}},react:function(){return" | "},html:function(){return" &vert; "}},autolink:{order:U++,match:d(/^<([^: >]+:\/[^ >]+)>/),parse:function(t){function n(n,r,e){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}((function(t,n,r){return{type:"link",content:[{type:"text",content:t[1]}],target:t[1]}})),react:null,html:null},mailto:{order:U++,match:d(/^<([^ >]+@[^ >]+)>/),parse:function(t){function n(n,r,e){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}((function(t,n,r){var e=t[1],u=t[1];return G.test(u)||(u="mailto:"+u),{type:"link",content:[{type:"text",content:e}],target:u}})),react:null,html:null},url:{order:U++,match:d(/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/),parse:function(t){function n(n,r,e){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}((function(t,n,r){return{type:"link",content:[{type:"text",content:t[1]}],target:t[1],title:void 0}})),react:null,html:null},link:{order:U++,match:d(new RegExp("^\\[("+I+")\\]\\("+z+"\\)")),parse:function(t){function n(n,r,e){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}((function(t,n,r){return{content:n(t[1],r),target:R(t[2]),title:t[3]}})),react:function(t,n,r){return v("a",r.key,{href:w(t.target),title:t.title,children:n(t.content,r)})},html:function(t,n,r){var e={href:w(t.target),title:t.title};return S("a",n(t.content,r),e)}},image:{order:U++,match:d(new RegExp("^!\\[("+I+")\\]\\("+z+"\\)")),parse:function(t){function n(n,r,e){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}((function(t,n,r){return{alt:t[1],target:R(t[2]),title:t[3]}})),react:function(t,n,r){return v("img",r.key,{src:w(t.target),alt:t.alt,title:t.title})},html:function(t,n,r){var e={src:w(t.target),alt:t.alt,title:t.title};return S("img","",e,!1)}},reflink:{order:U++,match:d(new RegExp("^\\[("+I+")\\]\\s*\\[([^\\]]*)\\]")),parse:function(t){function n(n,r,e){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}((function(t,n,r){return X(t,r,{type:"link",content:n(t[1],r)})})),react:null,html:null},refimage:{order:U++,match:d(new RegExp("^!\\[("+I+")\\]\\s*\\[([^\\]]*)\\]")),parse:function(t){function n(n,r,e){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}((function(t,n,r){return X(t,r,{type:"image",alt:t[1]})})),react:null,html:null},em:{order:U,match:d(new RegExp("^\\b_((?:__|\\\\[\\s\\S]|[^\\\\_])+?)_\\b|^\\*(?=\\S)((?:\\*\\*|\\\\[\\s\\S]|\\s+(?:\\\\[\\s\\S]|[^\\s\\*\\\\]|\\*\\*)|[^\\s\\*\\\\])+?)\\*(?!\\*)")),quality:function(t){return t[0].length+.2},parse:function(t){function n(n,r,e){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}((function(t,n,r){return{content:n(t[2]||t[1],r)}})),react:function(t,n,r){return v("em",r.key,{children:n(t.content,r)})},html:function(t,n,r){return S("em",n(t.content,r))}},strong:{order:U,match:d(/^\*\*((?:\\[\s\S]|[^\\])+?)\*\*(?!\*)/),quality:function(t){return t[0].length+.1},parse:$,react:function(t,n,r){return v("strong",r.key,{children:n(t.content,r)})},html:function(t,n,r){return S("strong",n(t.content,r))}},u:{order:U++,match:d(/^__((?:\\[\s\S]|[^\\])+?)__(?!_)/),quality:function(t){return t[0].length},parse:$,react:function(t,n,r){return v("u",r.key,{children:n(t.content,r)})},html:function(t,n,r){return S("u",n(t.content,r))}},del:{order:U++,match:d(/^~~(?=\S)((?:\\[\s\S]|~(?!~)|[^\s~\\]|\s(?!~~))+?)~~/),parse:$,react:function(t,n,r){return v("del",r.key,{children:n(t.content,r)})},html:function(t,n,r){return S("del",n(t.content,r))}},inlineCode:{order:U++,match:d(/^(`+)([\s\S]*?[^`])\1(?!`)/),parse:function(t){function n(n,r,e){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}((function(t,n,r){return{content:t[2].replace(C,"$1")}})),react:function(t,n,r){return v("code",r.key,{children:t.content})},html:function(t,n,r){return S("code",_(t.content))}},br:{order:U++,match:m(/^ {2,}\n/),parse:O,react:function(t,n,r){return v("br",r.key,k)},html:function(t,n,r){return"<br>"}},text:{order:U++,match:m(/^[\s\S]+?(?=[^0-9A-Za-z\s\u00c0-\uffff]|\n\n| {2,}\n|\w+:\S|$)/),parse:function(t){function n(n,r,e){return t.apply(this,arguments)}return n.toString=function(){return t.toString()},n}((function(t,n,r){return{content:t[0]}})),react:function(t,n,r){return t.content},html:function(t,n,r){return _(t.content)}}},H=function(t,n){var r,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(!n)throw new Error("simple-markdown: outputFor: `property` must be defined. if you just upgraded, you probably need to replace `outputFor` with `reactFor`");var u=t.Array||Z.Array,o=u[n];if(!o)throw new Error("simple-markdown: outputFor: to join nodes of type `"+n+"` you must provide an `Array:` joiner rule with that type, Please see the docs for details on specifying an Array rule.");var i=o,a=function e(u,o){return r=o=o||r,Array.isArray(u)?i(u,e,o):t[u.type][n](u,e,o)},l=function(t,n){return r=s(n,e),a(t,r)};return l},D=h(Z),M=function(t,n){return(n=n||{}).inline=!1,D(t,n)},Q=function(t,n){var r=P.test(t);return(n=n||{}).inline=!r,D(t,n)},J=H(Z,"react"),K=H(Z,"html"),V=function(t,n){return J(M(t,n),n)},W={defaultRules:Z,parserFor:h,outputFor:H,inlineRegex:d,blockRegex:g,anyScopeRegex:m,parseInline:A,parseBlock:function(t,n,r){var e=r.inline||!1;r.inline=!1;var u=t(n+"\n\n",r);return r.inline=e,u},markdownToReact:V,markdownToHtml:function(t,n){return K(M(t,n),n)},ReactMarkdown:function(t){var n={};for(var r in t)"source"!==r&&Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n.children=V(t.source),v("div",null,n)},defaultBlockParse:M,defaultInlineParse:function(t,n){return(n=n||{}).inline=!0,D(t,n)},defaultImplicitParse:Q,defaultReactOutput:J,defaultHtmlOutput:K,preprocess:p,sanitizeText:_,sanitizeUrl:w,unescapeUrl:R,htmlTag:S,reactElement:v,defaultRawParse:D,ruleOutput:function(t,n){n||"undefined"==typeof console||console.warn("simple-markdown ruleOutput should take 'react' or 'html' as the second argument.");return function(r,e,u){return t[r.type][n](r,e,u)}},reactFor:function(t){return function n(r,e){if(e=e||{},Array.isArray(r)){for(var u=e.key,o=[],i=null,a=0;a<r.length;a++){e.key=""+a;var l=n(r[a],e);"string"==typeof l&&"string"==typeof i?(i+=l,o[o.length-1]=i):(o.push(l),i=l)}return e.key=u,o}return t(r,n,e)}},htmlFor:function(t){return function n(r,e){return e=e||{},Array.isArray(r)?r.map((function(t){return n(t,e)})).join(""):t(r,n,e)}},defaultParse:function(){return"undefined"!=typeof console&&console.warn("defaultParse is deprecated, please use `defaultImplicitParse`"),Q.apply(null,arguments)},defaultOutput:function(){return"undefined"!=typeof console&&console.warn("defaultOutput is deprecated, please use `defaultReactOutput`"),J.apply(null,arguments)}};export{W as default};
2
+ //# sourceMappingURL=index.js.map