@khanacademy/pure-markdown 2.0.0 → 2.0.2

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/es/index.js CHANGED
@@ -1,275 +1,9 @@
1
- import _extends from '@babel/runtime/helpers/extends';
2
1
  import { addLibraryVersionToPerseusDebug } from '@khanacademy/perseus-utils';
3
2
  import SimpleMarkdown from '@khanacademy/simple-markdown';
4
3
 
5
- // This file is processed by a Rollup plugin (replace) to inject the production
6
- // version number during the release build.
7
- // In dev, you'll never see the version number.
4
+ const libName="@khanacademy/pure-markdown";const libVersion="2.0.2";addLibraryVersionToPerseusDebug(libName,libVersion);
8
5
 
9
- const libName = "@khanacademy/pure-markdown";
10
- const libVersion = "2.0.0";
11
- addLibraryVersionToPerseusDebug(libName, libVersion);
12
-
13
- const rWidgetRule = /^\[\[\u2603 (([a-z-]+) ([0-9]+))\]\]/;
14
-
15
- /**
16
- * This match function matches math in `$`s, such as:
17
- *
18
- * $y = x + 1$
19
- *
20
- * It functions roughly like the following regex:
21
- * /\$([^\$]*)\$/
22
- *
23
- * Unfortunately, math may have other `$`s inside it, as
24
- * long as they are inside `{` braces `}`, mostly for
25
- * `\text{ $math$ }`.
26
- *
27
- * To parse this, we can't use a regex, since we
28
- * should support arbitrary nesting (even though
29
- * MathJax actually only supports two levels of nesting
30
- * here, which we *could* parse with a regex).
31
- *
32
- * Non-regex matchers like this are now a first-class
33
- * concept in simple-markdown. Yay!
34
- *
35
- * This can also match block-math, which is math alone in a paragraph.
36
- */
37
- const mathMatcher = (source, state, isBlock) => {
38
- const length = source.length;
39
- let index = 0;
40
-
41
- // When looking for blocks, skip over leading spaces
42
- if (isBlock) {
43
- if (state.inline) {
44
- return null;
45
- }
46
- while (index < length && source[index] === " ") {
47
- index++;
48
- }
49
- }
50
-
51
- // Our source must start with a "$"
52
- if (!(index < length && source[index] === "$")) {
53
- return null;
54
- }
55
- index++;
56
- const startIndex = index;
57
- let braceLevel = 0;
58
-
59
- // Loop through the source, looking for a closing '$'
60
- // closing '$'s only count if they are not escaped with
61
- // a `\`, and we are not in nested `{}` braces.
62
- while (index < length) {
63
- const character = source[index];
64
- if (character === "\\") {
65
- // Consume both the `\` and the escaped char as a single
66
- // token.
67
- // This is so that the second `$` in `$\\$` closes
68
- // the math expression, since the first `\` is escaping
69
- // the second `\`, but the second `\` is not escaping
70
- // the second `$`.
71
- // This also handles the case of escaping `$`s or
72
- // braces `\{`
73
- index++;
74
- } else if (braceLevel <= 0 && character === "$") {
75
- let endIndex = index + 1;
76
- if (isBlock) {
77
- // Look for two trailing newlines after the closing `$`
78
- const match = /^(?: *\n){2,}/.exec(source.slice(endIndex));
79
- // @ts-expect-error - TS2322 - Type 'number | null' is not assignable to type 'number'.
80
- endIndex = match ? endIndex + match[0].length : null;
81
- }
82
-
83
- // Return an array that looks like the results of a
84
- // regex's .exec function:
85
- // capture[0] is the whole string
86
- // capture[1] is the first "paren" match, which is the
87
- // content of the math here, as if we wrote the regex
88
- // /\$([^\$]*)\$/
89
- // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
90
- if (endIndex) {
91
- return [source.substring(0, endIndex), source.substring(startIndex, index)];
92
- }
93
- return null;
94
- } else if (character === "{") {
95
- braceLevel++;
96
- } else if (character === "}") {
97
- braceLevel--;
98
- } else if (character === "\n" && source[index - 1] === "\n") {
99
- // This is a weird case we supported in the old
100
- // math implementation--double newlines break
101
- // math. I'm preserving it for now because content
102
- // creators might have questions with single '$'s
103
- // in paragraphs...
104
- return null;
105
- }
106
- index++;
107
- }
108
-
109
- // we didn't find a closing `$`
110
- return null;
111
- };
112
- const mathMatch = (source, state) => mathMatcher(source, state, false);
113
- const blockMathMatch = (source, state) => mathMatcher(source, state, true);
114
- const TITLED_TABLE_REGEX = new RegExp("^\\|\\| +(.*) +\\|\\| *\\n" + "(" +
115
- // The simple-markdown nptable regex, without
116
- // the leading `^`
117
- // @ts-expect-error - TS2532 - Object is possibly 'undefined'.
118
- SimpleMarkdown.defaultRules.nptable.match.regex.source.substring(1) + ")");
119
- const crowdinJiptMatcher = SimpleMarkdown.blockRegex(/^(crwdns.*)\n\s*\n/);
120
- const pureMarkdownRules = _extends({}, SimpleMarkdown.defaultRules, {
121
- // NOTE: basically ignored by JIPT. wraps everything at the outer layer
122
- columns: {
123
- order: -2,
124
- match: SimpleMarkdown.blockRegex(/^([\s\S]*\n\n)={5,}\n\n([\s\S]*)/),
125
- parse: (capture, parse, state) => {
126
- return {
127
- col1: parse(capture[1], state),
128
- col2: parse(capture[2], state)
129
- };
130
- }
131
- },
132
- crowdinId: {
133
- order: -1,
134
- match: (source, state, prevCapture) => {
135
- // Only match on the just-in-place translation site
136
- if (state.isJipt) {
137
- return crowdinJiptMatcher(source, state, prevCapture);
138
- }
139
- return null;
140
- },
141
- parse: (capture, parse, state) => ({
142
- id: capture[1]
143
- })
144
- },
145
- // This is pretty much horrible, but we have a regex here to capture an
146
- // entire table + a title. capture[1] is the title. capture[2] of the
147
- // regex is a copy of the simple-markdown nptable regex. Then we turn
148
- // our capture[2] into tableCapture[0], and any further captures in
149
- // our table regex into tableCapture[1..], and we pass tableCapture to
150
- // our nptable regex
151
- titledTable: {
152
- // process immediately before nptables
153
- order: SimpleMarkdown.defaultRules.nptable.order - 0.5,
154
- match: SimpleMarkdown.blockRegex(TITLED_TABLE_REGEX),
155
- parse: (capture, parse, state) => {
156
- const title = SimpleMarkdown.parseInline(parse, capture[1], state);
157
-
158
- // Remove our [0] and [1] captures, and pass the rest to
159
- // the nptable parser
160
- const tableCapture = capture.slice(2);
161
- const table = SimpleMarkdown.defaultRules.nptable.parse(tableCapture, parse, state);
162
- return {
163
- title: title,
164
- table: table
165
- };
166
- }
167
- },
168
- widget: {
169
- order: SimpleMarkdown.defaultRules.link.order - 0.75,
170
- match: SimpleMarkdown.inlineRegex(rWidgetRule),
171
- parse: (capture, parse, state) => {
172
- return {
173
- id: capture[1],
174
- widgetType: capture[2]
175
- };
176
- }
177
- },
178
- blockMath: {
179
- order: SimpleMarkdown.defaultRules.codeBlock.order + 0.5,
180
- match: blockMathMatch,
181
- parse: (capture, parse, state) => {
182
- return {
183
- content: capture[1]
184
- };
185
- }
186
- },
187
- math: {
188
- order: SimpleMarkdown.defaultRules.link.order - 0.25,
189
- match: mathMatch,
190
- parse: (capture, parse, state) => {
191
- return {
192
- content: capture[1]
193
- };
194
- }
195
- },
196
- unescapedDollar: {
197
- order: SimpleMarkdown.defaultRules.link.order - 0.24,
198
- match: SimpleMarkdown.inlineRegex(/^(?!\\)\$/),
199
- parse: (capture, parse, state) => {
200
- return {};
201
- }
202
- },
203
- fence: _extends({}, SimpleMarkdown.defaultRules.fence, {
204
- parse: (capture, parse, state) => {
205
- const node = SimpleMarkdown.defaultRules.fence.parse(capture, parse, state);
206
-
207
- // support screenreader-only text with ```alt
208
- if (node.lang === "alt") {
209
- return {
210
- type: "codeBlock",
211
- lang: "alt",
212
- // default codeBlock parsing doesn't parse the contents.
213
- // We need to parse the contents for things like table
214
- // support :).
215
- // The \n\n is because the inside of the codeblock might
216
- // not end in double newlines for block rules, because
217
- // ordinarily we don't parse this :).
218
- content: parse(node.content + "\n\n", state)
219
- };
220
- }
221
- return node;
222
- }
223
- }),
224
- blockQuote: _extends({}, SimpleMarkdown.defaultRules.blockQuote, {
225
- // Replace the less restrictive blockquote regex from SimpleMarkdown
226
- // with a more restrictive one. The only difference should be that
227
- //
228
- // > A blockquote
229
- //
230
- // > Another blockquote
231
- //
232
- // will now match as two different blockQuotes instead of a single
233
- // blockquote with some paragraph breaks in it.
234
- //
235
- // The main motivation for doing this is to provide better support for
236
- // translators translating blockquotes with multiple paragraphs in
237
- // them. When translating articles, we split up paragraphs, translate
238
- // them separately, and then recombine them. We do this so that
239
- // translators don't have to translate an entire article at a time,
240
- // they can instead translate paragraph-by-paragraph.That system
241
- // doesn't understand blockquotes, so it will split up blockquotes into
242
- // more than one paragraph. A way to solve this would be to make that
243
- // system understand blockquotes, but then translators would have to
244
- // translate an entire, multi-paragraph blockquote at a time. Instead,
245
- // we choose to modify our blockquote matching to split up
246
- // multi-paragraph blockquotes into multiple blockquotes.
247
- //
248
- // There is also precedence for doing this splitting up in other
249
- // libraries, for instance CommonMark also splits up blockquotes with
250
- // empty lines into multiple blockquotes:
251
- // https://spec.commonmark.org/0.28/#example-205
252
- match: SimpleMarkdown.blockRegex(/^ *>[^\n]+(\n( *>)?[^\n]+)*\n{2,}/)
253
- }),
254
- // The lint rule never actually matches anything.
255
- // We check for lint after parsing, and, if we find any, we
256
- // transform the tree to add lint nodes. This rule is here
257
- // just for the react() function
258
- lint: {
259
- order: 1000,
260
- match: s => null,
261
- parse: (capture, parse, state) => ({})
262
- }
263
- });
264
-
265
- // @ts-expect-error - TS2345 - Argument of type '{ readonly columns: { readonly order: -2; readonly match: any; readonly parse: (capture: any, parse: any, state: any) => any; }; readonly crowdinId: { readonly order: -1; readonly match: (source: any, state: any, prevCapture: any) => any; readonly parse: (capture: any, parse: any, state: any) => any; }; ... 34 more ...' is not assignable to parameter of type 'ParserRules'.
266
- const builtParser = SimpleMarkdown.parserFor(pureMarkdownRules);
267
- const parse = (source, state) => {
268
- const paragraphedSource = source + "\n\n";
269
- return builtParser(paragraphedSource, _extends({}, state, {
270
- inline: false
271
- }));
272
- };
6
+ const rWidgetRule=/^\[\[\u2603 (([a-z-]+) ([0-9]+))\]\]/;const mathMatcher=(source,state,isBlock)=>{const length=source.length;let index=0;if(isBlock){if(state.inline){return null}while(index<length&&source[index]===" "){index++;}}if(!(index<length&&source[index]==="$")){return null}index++;const startIndex=index;let braceLevel=0;while(index<length){const character=source[index];if(character==="\\"){index++;}else if(braceLevel<=0&&character==="$"){let endIndex=index+1;if(isBlock){const match=/^(?: *\n){2,}/.exec(source.slice(endIndex));endIndex=match?endIndex+match[0].length:null;}if(endIndex){return [source.substring(0,endIndex),source.substring(startIndex,index)]}return null}else if(character==="{"){braceLevel++;}else if(character==="}"){braceLevel--;}else if(character==="\n"&&source[index-1]==="\n"){return null}index++;}return null};const mathMatch=(source,state)=>mathMatcher(source,state,false);const blockMathMatch=(source,state)=>mathMatcher(source,state,true);const TITLED_TABLE_REGEX=new RegExp("^\\|\\| +(.*) +\\|\\| *\\n"+"("+SimpleMarkdown.defaultRules.nptable.match.regex.source.substring(1)+")");const crowdinJiptMatcher=SimpleMarkdown.blockRegex(/^(crwdns.*)\n\s*\n/);const pureMarkdownRules={...SimpleMarkdown.defaultRules,columns:{order:-2,match:SimpleMarkdown.blockRegex(/^([\s\S]*\n\n)={5,}\n\n([\s\S]*)/),parse:(capture,parse,state)=>{return {col1:parse(capture[1],state),col2:parse(capture[2],state)}}},crowdinId:{order:-1,match:(source,state,prevCapture)=>{if(state.isJipt){return crowdinJiptMatcher(source,state,prevCapture)}return null},parse:(capture,parse,state)=>({id:capture[1]})},titledTable:{order:SimpleMarkdown.defaultRules.nptable.order-.5,match:SimpleMarkdown.blockRegex(TITLED_TABLE_REGEX),parse:(capture,parse,state)=>{const title=SimpleMarkdown.parseInline(parse,capture[1],state);const tableCapture=capture.slice(2);const table=SimpleMarkdown.defaultRules.nptable.parse(tableCapture,parse,state);return {title:title,table:table}}},widget:{order:SimpleMarkdown.defaultRules.link.order-.75,match:SimpleMarkdown.inlineRegex(rWidgetRule),parse:(capture,parse,state)=>{return {id:capture[1],widgetType:capture[2]}}},blockMath:{order:SimpleMarkdown.defaultRules.codeBlock.order+.5,match:blockMathMatch,parse:(capture,parse,state)=>{return {content:capture[1]}}},math:{order:SimpleMarkdown.defaultRules.link.order-.25,match:mathMatch,parse:(capture,parse,state)=>{return {content:capture[1]}}},unescapedDollar:{order:SimpleMarkdown.defaultRules.link.order-.24,match:SimpleMarkdown.inlineRegex(/^(?!\\)\$/),parse:(capture,parse,state)=>{return {}}},fence:{...SimpleMarkdown.defaultRules.fence,parse:(capture,parse,state)=>{const node=SimpleMarkdown.defaultRules.fence.parse(capture,parse,state);if(node.lang==="alt"){return {type:"codeBlock",lang:"alt",content:parse(node.content+"\n\n",state)}}return node}},blockQuote:{...SimpleMarkdown.defaultRules.blockQuote,match:SimpleMarkdown.blockRegex(/^ *>[^\n]+(\n( *>)?[^\n]+)*\n{2,}/)},lint:{order:1e3,match:s=>null,parse:(capture,parse,state)=>({})}};const builtParser=SimpleMarkdown.parserFor(pureMarkdownRules);const parse=(source,state)=>{const paragraphedSource=source+"\n\n";return builtParser(paragraphedSource,{...state,inline:false})};
273
7
 
274
8
  export { libVersion, parse, pureMarkdownRules };
275
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/version.ts","../../src/index.ts"],"sourcesContent":["// This file is processed by a Rollup plugin (replace) to inject the production\n// version number during the release build.\n// In dev, you'll never see the version number.\n\nimport {addLibraryVersionToPerseusDebug} from \"@khanacademy/perseus-utils\";\n\nconst libName = \"@khanacademy/pure-markdown\";\nexport const libVersion = \"__lib_version__\";\n\naddLibraryVersionToPerseusDebug(libName, libVersion);\n","/**\n * Contains markdown related functions in pure javascript,\n * extracted from perseus-markdown.jsx\n * Note that this file may be used in stand alone nodejs, thus\n * do not import anything from Perseus\n */\nexport {libVersion} from \"./version\";\n\nimport SimpleMarkdown from \"@khanacademy/simple-markdown\";\n\nconst rWidgetRule = /^\\[\\[\\u2603 (([a-z-]+) ([0-9]+))\\]\\]/;\n\n/**\n * This match function matches math in `$`s, such as:\n *\n * $y = x + 1$\n *\n * It functions roughly like the following regex:\n * /\\$([^\\$]*)\\$/\n *\n * Unfortunately, math may have other `$`s inside it, as\n * long as they are inside `{` braces `}`, mostly for\n * `\\text{ $math$ }`.\n *\n * To parse this, we can't use a regex, since we\n * should support arbitrary nesting (even though\n * MathJax actually only supports two levels of nesting\n * here, which we *could* parse with a regex).\n *\n * Non-regex matchers like this are now a first-class\n * concept in simple-markdown. Yay!\n *\n * This can also match block-math, which is math alone in a paragraph.\n */\nconst mathMatcher = (source: any, state: any, isBlock: boolean) => {\n const length = source.length;\n let index = 0;\n\n // When looking for blocks, skip over leading spaces\n if (isBlock) {\n if (state.inline) {\n return null;\n }\n while (index < length && source[index] === \" \") {\n index++;\n }\n }\n\n // Our source must start with a \"$\"\n if (!(index < length && source[index] === \"$\")) {\n return null;\n }\n\n index++;\n const startIndex = index;\n let braceLevel = 0;\n\n // Loop through the source, looking for a closing '$'\n // closing '$'s only count if they are not escaped with\n // a `\\`, and we are not in nested `{}` braces.\n while (index < length) {\n const character = source[index];\n\n if (character === \"\\\\\") {\n // Consume both the `\\` and the escaped char as a single\n // token.\n // This is so that the second `$` in `$\\\\$` closes\n // the math expression, since the first `\\` is escaping\n // the second `\\`, but the second `\\` is not escaping\n // the second `$`.\n // This also handles the case of escaping `$`s or\n // braces `\\{`\n index++;\n } else if (braceLevel <= 0 && character === \"$\") {\n let endIndex = index + 1;\n if (isBlock) {\n // Look for two trailing newlines after the closing `$`\n const match = /^(?: *\\n){2,}/.exec(source.slice(endIndex));\n // @ts-expect-error - TS2322 - Type 'number | null' is not assignable to type 'number'.\n endIndex = match ? endIndex + match[0].length : null;\n }\n\n // Return an array that looks like the results of a\n // regex's .exec function:\n // capture[0] is the whole string\n // capture[1] is the first \"paren\" match, which is the\n // content of the math here, as if we wrote the regex\n // /\\$([^\\$]*)\\$/\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n if (endIndex) {\n return [\n source.substring(0, endIndex),\n source.substring(startIndex, index),\n ];\n }\n return null;\n } else if (character === \"{\") {\n braceLevel++;\n } else if (character === \"}\") {\n braceLevel--;\n } else if (character === \"\\n\" && source[index - 1] === \"\\n\") {\n // This is a weird case we supported in the old\n // math implementation--double newlines break\n // math. I'm preserving it for now because content\n // creators might have questions with single '$'s\n // in paragraphs...\n return null;\n }\n\n index++;\n }\n\n // we didn't find a closing `$`\n return null;\n};\nconst mathMatch = (source: any, state: any): any =>\n mathMatcher(source, state, false);\nconst blockMathMatch = (source: any, state: any): any =>\n mathMatcher(source, state, true);\n\nconst TITLED_TABLE_REGEX = new RegExp(\n \"^\\\\|\\\\| +(.*) +\\\\|\\\\| *\\\\n\" +\n \"(\" +\n // The simple-markdown nptable regex, without\n // the leading `^`\n // @ts-expect-error - TS2532 - Object is possibly 'undefined'.\n SimpleMarkdown.defaultRules.nptable.match.regex.source.substring(1) +\n \")\",\n);\n\nconst crowdinJiptMatcher = SimpleMarkdown.blockRegex(/^(crwdns.*)\\n\\s*\\n/);\n\nexport const pureMarkdownRules = {\n ...SimpleMarkdown.defaultRules,\n\n // NOTE: basically ignored by JIPT. wraps everything at the outer layer\n columns: {\n order: -2,\n match: SimpleMarkdown.blockRegex(\n /^([\\s\\S]*\\n\\n)={5,}\\n\\n([\\s\\S]*)/,\n ) as any,\n parse: (capture: any, parse: any, state: any): any => {\n return {\n col1: parse(capture[1], state),\n col2: parse(capture[2], state),\n };\n },\n },\n crowdinId: {\n order: -1,\n match: (source: any, state: any, prevCapture: any): any => {\n // Only match on the just-in-place translation site\n if (state.isJipt) {\n return crowdinJiptMatcher(source, state, prevCapture);\n }\n return null;\n },\n parse: (capture: any, parse: any, state: any): any => ({\n id: capture[1],\n }),\n },\n // This is pretty much horrible, but we have a regex here to capture an\n // entire table + a title. capture[1] is the title. capture[2] of the\n // regex is a copy of the simple-markdown nptable regex. Then we turn\n // our capture[2] into tableCapture[0], and any further captures in\n // our table regex into tableCapture[1..], and we pass tableCapture to\n // our nptable regex\n titledTable: {\n // process immediately before nptables\n order: SimpleMarkdown.defaultRules.nptable.order - 0.5,\n match: SimpleMarkdown.blockRegex(TITLED_TABLE_REGEX) as any,\n parse: (capture: any, parse: any, state: any): any => {\n const title = SimpleMarkdown.parseInline(parse, capture[1], state);\n\n // Remove our [0] and [1] captures, and pass the rest to\n // the nptable parser\n const tableCapture = capture.slice(2);\n const table = SimpleMarkdown.defaultRules.nptable.parse(\n tableCapture,\n parse,\n state,\n );\n return {\n title: title,\n table: table,\n };\n },\n },\n widget: {\n order: SimpleMarkdown.defaultRules.link.order - 0.75,\n match: SimpleMarkdown.inlineRegex(rWidgetRule) as any,\n parse: (capture: any, parse: any, state: any): any => {\n return {\n id: capture[1],\n widgetType: capture[2],\n };\n },\n },\n blockMath: {\n order: (SimpleMarkdown.defaultRules.codeBlock.order + 0.5) as any,\n match: blockMathMatch,\n parse: (capture: any, parse: any, state: any): any => {\n return {\n content: capture[1],\n };\n },\n },\n math: {\n order: SimpleMarkdown.defaultRules.link.order - 0.25,\n match: mathMatch,\n parse: (capture: any, parse: any, state: any): any => {\n return {\n content: capture[1],\n };\n },\n },\n unescapedDollar: {\n order: SimpleMarkdown.defaultRules.link.order - 0.24,\n match: SimpleMarkdown.inlineRegex(/^(?!\\\\)\\$/) as any,\n parse: (capture: any, parse: any, state: any): any => {\n return {};\n },\n },\n fence: {\n ...SimpleMarkdown.defaultRules.fence,\n parse: (capture: any, parse: any, state: any): any => {\n const node = SimpleMarkdown.defaultRules.fence.parse(\n capture,\n parse,\n state,\n );\n\n // support screenreader-only text with ```alt\n if (node.lang === \"alt\") {\n return {\n type: \"codeBlock\",\n lang: \"alt\",\n // default codeBlock parsing doesn't parse the contents.\n // We need to parse the contents for things like table\n // support :).\n // The \\n\\n is because the inside of the codeblock might\n // not end in double newlines for block rules, because\n // ordinarily we don't parse this :).\n content: parse(node.content + \"\\n\\n\", state),\n };\n }\n return node;\n },\n },\n blockQuote: {\n ...SimpleMarkdown.defaultRules.blockQuote,\n // Replace the less restrictive blockquote regex from SimpleMarkdown\n // with a more restrictive one. The only difference should be that\n //\n // > A blockquote\n //\n // > Another blockquote\n //\n // will now match as two different blockQuotes instead of a single\n // blockquote with some paragraph breaks in it.\n //\n // The main motivation for doing this is to provide better support for\n // translators translating blockquotes with multiple paragraphs in\n // them. When translating articles, we split up paragraphs, translate\n // them separately, and then recombine them. We do this so that\n // translators don't have to translate an entire article at a time,\n // they can instead translate paragraph-by-paragraph.That system\n // doesn't understand blockquotes, so it will split up blockquotes into\n // more than one paragraph. A way to solve this would be to make that\n // system understand blockquotes, but then translators would have to\n // translate an entire, multi-paragraph blockquote at a time. Instead,\n // we choose to modify our blockquote matching to split up\n // multi-paragraph blockquotes into multiple blockquotes.\n //\n // There is also precedence for doing this splitting up in other\n // libraries, for instance CommonMark also splits up blockquotes with\n // empty lines into multiple blockquotes:\n // https://spec.commonmark.org/0.28/#example-205\n match: SimpleMarkdown.blockRegex(\n /^ *>[^\\n]+(\\n( *>)?[^\\n]+)*\\n{2,}/,\n ) as any,\n },\n // The lint rule never actually matches anything.\n // We check for lint after parsing, and, if we find any, we\n // transform the tree to add lint nodes. This rule is here\n // just for the react() function\n lint: {\n order: 1000,\n match: (s: any): any => null,\n parse: (capture: any, parse: any, state: any): any => ({}),\n },\n} as const;\n\n// @ts-expect-error - TS2345 - Argument of type '{ readonly columns: { readonly order: -2; readonly match: any; readonly parse: (capture: any, parse: any, state: any) => any; }; readonly crowdinId: { readonly order: -1; readonly match: (source: any, state: any, prevCapture: any) => any; readonly parse: (capture: any, parse: any, state: any) => any; }; ... 34 more ...' is not assignable to parameter of type 'ParserRules'.\nconst builtParser = SimpleMarkdown.parserFor(pureMarkdownRules);\n\nexport const parse = (source: string, state?: any): any => {\n const paragraphedSource = source + \"\\n\\n\";\n\n return builtParser(paragraphedSource, {\n ...state,\n inline: false,\n });\n};\n"],"names":["libName","libVersion","addLibraryVersionToPerseusDebug","rWidgetRule","mathMatcher","source","state","isBlock","length","index","inline","startIndex","braceLevel","character","endIndex","match","exec","slice","substring","mathMatch","blockMathMatch","TITLED_TABLE_REGEX","RegExp","SimpleMarkdown","defaultRules","nptable","regex","crowdinJiptMatcher","blockRegex","pureMarkdownRules","_extends","columns","order","parse","capture","col1","col2","crowdinId","prevCapture","isJipt","id","titledTable","title","parseInline","tableCapture","table","widget","link","inlineRegex","widgetType","blockMath","codeBlock","content","math","unescapedDollar","fence","node","lang","type","blockQuote","lint","s","builtParser","parserFor","paragraphedSource"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/version.ts","../../src/index.ts"],"sourcesContent":["// This file is processed by a Rollup plugin (replace) to inject the production\n// version number during the release build.\n// In dev, you'll never see the version number.\n\nimport {addLibraryVersionToPerseusDebug} from \"@khanacademy/perseus-utils\";\n\nconst libName = \"@khanacademy/pure-markdown\";\nexport const libVersion = \"__lib_version__\";\n\naddLibraryVersionToPerseusDebug(libName, libVersion);\n","/**\n * Contains markdown related functions in pure javascript,\n * extracted from perseus-markdown.jsx\n * Note that this file may be used in stand alone nodejs, thus\n * do not import anything from Perseus\n */\nexport {libVersion} from \"./version\";\n\nimport SimpleMarkdown from \"@khanacademy/simple-markdown\";\n\nconst rWidgetRule = /^\\[\\[\\u2603 (([a-z-]+) ([0-9]+))\\]\\]/;\n\n/**\n * This match function matches math in `$`s, such as:\n *\n * $y = x + 1$\n *\n * It functions roughly like the following regex:\n * /\\$([^\\$]*)\\$/\n *\n * Unfortunately, math may have other `$`s inside it, as\n * long as they are inside `{` braces `}`, mostly for\n * `\\text{ $math$ }`.\n *\n * To parse this, we can't use a regex, since we\n * should support arbitrary nesting (even though\n * MathJax actually only supports two levels of nesting\n * here, which we *could* parse with a regex).\n *\n * Non-regex matchers like this are now a first-class\n * concept in simple-markdown. Yay!\n *\n * This can also match block-math, which is math alone in a paragraph.\n */\nconst mathMatcher = (source: any, state: any, isBlock: boolean) => {\n const length = source.length;\n let index = 0;\n\n // When looking for blocks, skip over leading spaces\n if (isBlock) {\n if (state.inline) {\n return null;\n }\n while (index < length && source[index] === \" \") {\n index++;\n }\n }\n\n // Our source must start with a \"$\"\n if (!(index < length && source[index] === \"$\")) {\n return null;\n }\n\n index++;\n const startIndex = index;\n let braceLevel = 0;\n\n // Loop through the source, looking for a closing '$'\n // closing '$'s only count if they are not escaped with\n // a `\\`, and we are not in nested `{}` braces.\n while (index < length) {\n const character = source[index];\n\n if (character === \"\\\\\") {\n // Consume both the `\\` and the escaped char as a single\n // token.\n // This is so that the second `$` in `$\\\\$` closes\n // the math expression, since the first `\\` is escaping\n // the second `\\`, but the second `\\` is not escaping\n // the second `$`.\n // This also handles the case of escaping `$`s or\n // braces `\\{`\n index++;\n } else if (braceLevel <= 0 && character === \"$\") {\n let endIndex = index + 1;\n if (isBlock) {\n // Look for two trailing newlines after the closing `$`\n const match = /^(?: *\\n){2,}/.exec(source.slice(endIndex));\n // @ts-expect-error - TS2322 - Type 'number | null' is not assignable to type 'number'.\n endIndex = match ? endIndex + match[0].length : null;\n }\n\n // Return an array that looks like the results of a\n // regex's .exec function:\n // capture[0] is the whole string\n // capture[1] is the first \"paren\" match, which is the\n // content of the math here, as if we wrote the regex\n // /\\$([^\\$]*)\\$/\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n if (endIndex) {\n return [\n source.substring(0, endIndex),\n source.substring(startIndex, index),\n ];\n }\n return null;\n } else if (character === \"{\") {\n braceLevel++;\n } else if (character === \"}\") {\n braceLevel--;\n } else if (character === \"\\n\" && source[index - 1] === \"\\n\") {\n // This is a weird case we supported in the old\n // math implementation--double newlines break\n // math. I'm preserving it for now because content\n // creators might have questions with single '$'s\n // in paragraphs...\n return null;\n }\n\n index++;\n }\n\n // we didn't find a closing `$`\n return null;\n};\nconst mathMatch = (source: any, state: any): any =>\n mathMatcher(source, state, false);\nconst blockMathMatch = (source: any, state: any): any =>\n mathMatcher(source, state, true);\n\nconst TITLED_TABLE_REGEX = new RegExp(\n \"^\\\\|\\\\| +(.*) +\\\\|\\\\| *\\\\n\" +\n \"(\" +\n // The simple-markdown nptable regex, without\n // the leading `^`\n // @ts-expect-error - TS2532 - Object is possibly 'undefined'.\n SimpleMarkdown.defaultRules.nptable.match.regex.source.substring(1) +\n \")\",\n);\n\nconst crowdinJiptMatcher = SimpleMarkdown.blockRegex(/^(crwdns.*)\\n\\s*\\n/);\n\nexport const pureMarkdownRules = {\n ...SimpleMarkdown.defaultRules,\n\n // NOTE: basically ignored by JIPT. wraps everything at the outer layer\n columns: {\n order: -2,\n match: SimpleMarkdown.blockRegex(\n /^([\\s\\S]*\\n\\n)={5,}\\n\\n([\\s\\S]*)/,\n ) as any,\n parse: (capture: any, parse: any, state: any): any => {\n return {\n col1: parse(capture[1], state),\n col2: parse(capture[2], state),\n };\n },\n },\n crowdinId: {\n order: -1,\n match: (source: any, state: any, prevCapture: any): any => {\n // Only match on the just-in-place translation site\n if (state.isJipt) {\n return crowdinJiptMatcher(source, state, prevCapture);\n }\n return null;\n },\n parse: (capture: any, parse: any, state: any): any => ({\n id: capture[1],\n }),\n },\n // This is pretty much horrible, but we have a regex here to capture an\n // entire table + a title. capture[1] is the title. capture[2] of the\n // regex is a copy of the simple-markdown nptable regex. Then we turn\n // our capture[2] into tableCapture[0], and any further captures in\n // our table regex into tableCapture[1..], and we pass tableCapture to\n // our nptable regex\n titledTable: {\n // process immediately before nptables\n order: SimpleMarkdown.defaultRules.nptable.order - 0.5,\n match: SimpleMarkdown.blockRegex(TITLED_TABLE_REGEX) as any,\n parse: (capture: any, parse: any, state: any): any => {\n const title = SimpleMarkdown.parseInline(parse, capture[1], state);\n\n // Remove our [0] and [1] captures, and pass the rest to\n // the nptable parser\n const tableCapture = capture.slice(2);\n const table = SimpleMarkdown.defaultRules.nptable.parse(\n tableCapture,\n parse,\n state,\n );\n return {\n title: title,\n table: table,\n };\n },\n },\n widget: {\n order: SimpleMarkdown.defaultRules.link.order - 0.75,\n match: SimpleMarkdown.inlineRegex(rWidgetRule) as any,\n parse: (capture: any, parse: any, state: any): any => {\n return {\n id: capture[1],\n widgetType: capture[2],\n };\n },\n },\n blockMath: {\n order: (SimpleMarkdown.defaultRules.codeBlock.order + 0.5) as any,\n match: blockMathMatch,\n parse: (capture: any, parse: any, state: any): any => {\n return {\n content: capture[1],\n };\n },\n },\n math: {\n order: SimpleMarkdown.defaultRules.link.order - 0.25,\n match: mathMatch,\n parse: (capture: any, parse: any, state: any): any => {\n return {\n content: capture[1],\n };\n },\n },\n unescapedDollar: {\n order: SimpleMarkdown.defaultRules.link.order - 0.24,\n match: SimpleMarkdown.inlineRegex(/^(?!\\\\)\\$/) as any,\n parse: (capture: any, parse: any, state: any): any => {\n return {};\n },\n },\n fence: {\n ...SimpleMarkdown.defaultRules.fence,\n parse: (capture: any, parse: any, state: any): any => {\n const node = SimpleMarkdown.defaultRules.fence.parse(\n capture,\n parse,\n state,\n );\n\n // support screenreader-only text with ```alt\n if (node.lang === \"alt\") {\n return {\n type: \"codeBlock\",\n lang: \"alt\",\n // default codeBlock parsing doesn't parse the contents.\n // We need to parse the contents for things like table\n // support :).\n // The \\n\\n is because the inside of the codeblock might\n // not end in double newlines for block rules, because\n // ordinarily we don't parse this :).\n content: parse(node.content + \"\\n\\n\", state),\n };\n }\n return node;\n },\n },\n blockQuote: {\n ...SimpleMarkdown.defaultRules.blockQuote,\n // Replace the less restrictive blockquote regex from SimpleMarkdown\n // with a more restrictive one. The only difference should be that\n //\n // > A blockquote\n //\n // > Another blockquote\n //\n // will now match as two different blockQuotes instead of a single\n // blockquote with some paragraph breaks in it.\n //\n // The main motivation for doing this is to provide better support for\n // translators translating blockquotes with multiple paragraphs in\n // them. When translating articles, we split up paragraphs, translate\n // them separately, and then recombine them. We do this so that\n // translators don't have to translate an entire article at a time,\n // they can instead translate paragraph-by-paragraph.That system\n // doesn't understand blockquotes, so it will split up blockquotes into\n // more than one paragraph. A way to solve this would be to make that\n // system understand blockquotes, but then translators would have to\n // translate an entire, multi-paragraph blockquote at a time. Instead,\n // we choose to modify our blockquote matching to split up\n // multi-paragraph blockquotes into multiple blockquotes.\n //\n // There is also precedence for doing this splitting up in other\n // libraries, for instance CommonMark also splits up blockquotes with\n // empty lines into multiple blockquotes:\n // https://spec.commonmark.org/0.28/#example-205\n match: SimpleMarkdown.blockRegex(\n /^ *>[^\\n]+(\\n( *>)?[^\\n]+)*\\n{2,}/,\n ) as any,\n },\n // The lint rule never actually matches anything.\n // We check for lint after parsing, and, if we find any, we\n // transform the tree to add lint nodes. This rule is here\n // just for the react() function\n lint: {\n order: 1000,\n match: (s: any): any => null,\n parse: (capture: any, parse: any, state: any): any => ({}),\n },\n} as const;\n\n// @ts-expect-error - TS2345 - Argument of type '{ readonly columns: { readonly order: -2; readonly match: any; readonly parse: (capture: any, parse: any, state: any) => any; }; readonly crowdinId: { readonly order: -1; readonly match: (source: any, state: any, prevCapture: any) => any; readonly parse: (capture: any, parse: any, state: any) => any; }; ... 34 more ...' is not assignable to parameter of type 'ParserRules'.\nconst builtParser = SimpleMarkdown.parserFor(pureMarkdownRules);\n\nexport const parse = (source: string, state?: any): any => {\n const paragraphedSource = source + \"\\n\\n\";\n\n return builtParser(paragraphedSource, {\n ...state,\n inline: false,\n });\n};\n"],"names":["libName","libVersion","addLibraryVersionToPerseusDebug","rWidgetRule","mathMatcher","source","state","isBlock","length","index","inline","startIndex","braceLevel","character","endIndex","match","exec","slice","substring","mathMatch","blockMathMatch","TITLED_TABLE_REGEX","RegExp","SimpleMarkdown","defaultRules","nptable","regex","crowdinJiptMatcher","blockRegex","pureMarkdownRules","columns","order","parse","capture","col1","col2","crowdinId","prevCapture","isJipt","id","titledTable","title","parseInline","tableCapture","table","widget","link","inlineRegex","widgetType","blockMath","codeBlock","content","math","unescapedDollar","fence","node","lang","type","blockQuote","lint","s","builtParser","parserFor","paragraphedSource"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -9,284 +9,9 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
9
9
 
10
10
  var SimpleMarkdown__default = /*#__PURE__*/_interopDefaultCompat(SimpleMarkdown);
11
11
 
12
- // This file is processed by a Rollup plugin (replace) to inject the production
13
- // version number during the release build.
14
- // In dev, you'll never see the version number.
12
+ const libName="@khanacademy/pure-markdown";const libVersion="2.0.2";perseusUtils.addLibraryVersionToPerseusDebug(libName,libVersion);
15
13
 
16
- const libName = "@khanacademy/pure-markdown";
17
- const libVersion = "2.0.0";
18
- perseusUtils.addLibraryVersionToPerseusDebug(libName, libVersion);
19
-
20
- /**
21
- * Contains markdown related functions in pure javascript,
22
- * extracted from perseus-markdown.jsx
23
- * Note that this file may be used in stand alone nodejs, thus
24
- * do not import anything from Perseus
25
- */
26
- const rWidgetRule = /^\[\[\u2603 (([a-z-]+) ([0-9]+))\]\]/;
27
-
28
- /**
29
- * This match function matches math in `$`s, such as:
30
- *
31
- * $y = x + 1$
32
- *
33
- * It functions roughly like the following regex:
34
- * /\$([^\$]*)\$/
35
- *
36
- * Unfortunately, math may have other `$`s inside it, as
37
- * long as they are inside `{` braces `}`, mostly for
38
- * `\text{ $math$ }`.
39
- *
40
- * To parse this, we can't use a regex, since we
41
- * should support arbitrary nesting (even though
42
- * MathJax actually only supports two levels of nesting
43
- * here, which we *could* parse with a regex).
44
- *
45
- * Non-regex matchers like this are now a first-class
46
- * concept in simple-markdown. Yay!
47
- *
48
- * This can also match block-math, which is math alone in a paragraph.
49
- */
50
- const mathMatcher = (source, state, isBlock) => {
51
- const length = source.length;
52
- let index = 0;
53
-
54
- // When looking for blocks, skip over leading spaces
55
- if (isBlock) {
56
- if (state.inline) {
57
- return null;
58
- }
59
- while (index < length && source[index] === " ") {
60
- index++;
61
- }
62
- }
63
-
64
- // Our source must start with a "$"
65
- if (!(index < length && source[index] === "$")) {
66
- return null;
67
- }
68
- index++;
69
- const startIndex = index;
70
- let braceLevel = 0;
71
-
72
- // Loop through the source, looking for a closing '$'
73
- // closing '$'s only count if they are not escaped with
74
- // a `\`, and we are not in nested `{}` braces.
75
- while (index < length) {
76
- const character = source[index];
77
- if (character === "\\") {
78
- // Consume both the `\` and the escaped char as a single
79
- // token.
80
- // This is so that the second `$` in `$\\$` closes
81
- // the math expression, since the first `\` is escaping
82
- // the second `\`, but the second `\` is not escaping
83
- // the second `$`.
84
- // This also handles the case of escaping `$`s or
85
- // braces `\{`
86
- index++;
87
- } else if (braceLevel <= 0 && character === "$") {
88
- let endIndex = index + 1;
89
- if (isBlock) {
90
- // Look for two trailing newlines after the closing `$`
91
- const match = /^(?: *\n){2,}/.exec(source.slice(endIndex));
92
- // @ts-expect-error - TS2322 - Type 'number | null' is not assignable to type 'number'.
93
- endIndex = match ? endIndex + match[0].length : null;
94
- }
95
-
96
- // Return an array that looks like the results of a
97
- // regex's .exec function:
98
- // capture[0] is the whole string
99
- // capture[1] is the first "paren" match, which is the
100
- // content of the math here, as if we wrote the regex
101
- // /\$([^\$]*)\$/
102
- // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
103
- if (endIndex) {
104
- return [source.substring(0, endIndex), source.substring(startIndex, index)];
105
- }
106
- return null;
107
- } else if (character === "{") {
108
- braceLevel++;
109
- } else if (character === "}") {
110
- braceLevel--;
111
- } else if (character === "\n" && source[index - 1] === "\n") {
112
- // This is a weird case we supported in the old
113
- // math implementation--double newlines break
114
- // math. I'm preserving it for now because content
115
- // creators might have questions with single '$'s
116
- // in paragraphs...
117
- return null;
118
- }
119
- index++;
120
- }
121
-
122
- // we didn't find a closing `$`
123
- return null;
124
- };
125
- const mathMatch = (source, state) => mathMatcher(source, state, false);
126
- const blockMathMatch = (source, state) => mathMatcher(source, state, true);
127
- const TITLED_TABLE_REGEX = new RegExp("^\\|\\| +(.*) +\\|\\| *\\n" + "(" +
128
- // The simple-markdown nptable regex, without
129
- // the leading `^`
130
- // @ts-expect-error - TS2532 - Object is possibly 'undefined'.
131
- SimpleMarkdown__default.default.defaultRules.nptable.match.regex.source.substring(1) + ")");
132
- const crowdinJiptMatcher = SimpleMarkdown__default.default.blockRegex(/^(crwdns.*)\n\s*\n/);
133
- const pureMarkdownRules = {
134
- ...SimpleMarkdown__default.default.defaultRules,
135
- // NOTE: basically ignored by JIPT. wraps everything at the outer layer
136
- columns: {
137
- order: -2,
138
- match: SimpleMarkdown__default.default.blockRegex(/^([\s\S]*\n\n)={5,}\n\n([\s\S]*)/),
139
- parse: (capture, parse, state) => {
140
- return {
141
- col1: parse(capture[1], state),
142
- col2: parse(capture[2], state)
143
- };
144
- }
145
- },
146
- crowdinId: {
147
- order: -1,
148
- match: (source, state, prevCapture) => {
149
- // Only match on the just-in-place translation site
150
- if (state.isJipt) {
151
- return crowdinJiptMatcher(source, state, prevCapture);
152
- }
153
- return null;
154
- },
155
- parse: (capture, parse, state) => ({
156
- id: capture[1]
157
- })
158
- },
159
- // This is pretty much horrible, but we have a regex here to capture an
160
- // entire table + a title. capture[1] is the title. capture[2] of the
161
- // regex is a copy of the simple-markdown nptable regex. Then we turn
162
- // our capture[2] into tableCapture[0], and any further captures in
163
- // our table regex into tableCapture[1..], and we pass tableCapture to
164
- // our nptable regex
165
- titledTable: {
166
- // process immediately before nptables
167
- order: SimpleMarkdown__default.default.defaultRules.nptable.order - 0.5,
168
- match: SimpleMarkdown__default.default.blockRegex(TITLED_TABLE_REGEX),
169
- parse: (capture, parse, state) => {
170
- const title = SimpleMarkdown__default.default.parseInline(parse, capture[1], state);
171
-
172
- // Remove our [0] and [1] captures, and pass the rest to
173
- // the nptable parser
174
- const tableCapture = capture.slice(2);
175
- const table = SimpleMarkdown__default.default.defaultRules.nptable.parse(tableCapture, parse, state);
176
- return {
177
- title: title,
178
- table: table
179
- };
180
- }
181
- },
182
- widget: {
183
- order: SimpleMarkdown__default.default.defaultRules.link.order - 0.75,
184
- match: SimpleMarkdown__default.default.inlineRegex(rWidgetRule),
185
- parse: (capture, parse, state) => {
186
- return {
187
- id: capture[1],
188
- widgetType: capture[2]
189
- };
190
- }
191
- },
192
- blockMath: {
193
- order: SimpleMarkdown__default.default.defaultRules.codeBlock.order + 0.5,
194
- match: blockMathMatch,
195
- parse: (capture, parse, state) => {
196
- return {
197
- content: capture[1]
198
- };
199
- }
200
- },
201
- math: {
202
- order: SimpleMarkdown__default.default.defaultRules.link.order - 0.25,
203
- match: mathMatch,
204
- parse: (capture, parse, state) => {
205
- return {
206
- content: capture[1]
207
- };
208
- }
209
- },
210
- unescapedDollar: {
211
- order: SimpleMarkdown__default.default.defaultRules.link.order - 0.24,
212
- match: SimpleMarkdown__default.default.inlineRegex(/^(?!\\)\$/),
213
- parse: (capture, parse, state) => {
214
- return {};
215
- }
216
- },
217
- fence: {
218
- ...SimpleMarkdown__default.default.defaultRules.fence,
219
- parse: (capture, parse, state) => {
220
- const node = SimpleMarkdown__default.default.defaultRules.fence.parse(capture, parse, state);
221
-
222
- // support screenreader-only text with ```alt
223
- if (node.lang === "alt") {
224
- return {
225
- type: "codeBlock",
226
- lang: "alt",
227
- // default codeBlock parsing doesn't parse the contents.
228
- // We need to parse the contents for things like table
229
- // support :).
230
- // The \n\n is because the inside of the codeblock might
231
- // not end in double newlines for block rules, because
232
- // ordinarily we don't parse this :).
233
- content: parse(node.content + "\n\n", state)
234
- };
235
- }
236
- return node;
237
- }
238
- },
239
- blockQuote: {
240
- ...SimpleMarkdown__default.default.defaultRules.blockQuote,
241
- // Replace the less restrictive blockquote regex from SimpleMarkdown
242
- // with a more restrictive one. The only difference should be that
243
- //
244
- // > A blockquote
245
- //
246
- // > Another blockquote
247
- //
248
- // will now match as two different blockQuotes instead of a single
249
- // blockquote with some paragraph breaks in it.
250
- //
251
- // The main motivation for doing this is to provide better support for
252
- // translators translating blockquotes with multiple paragraphs in
253
- // them. When translating articles, we split up paragraphs, translate
254
- // them separately, and then recombine them. We do this so that
255
- // translators don't have to translate an entire article at a time,
256
- // they can instead translate paragraph-by-paragraph.That system
257
- // doesn't understand blockquotes, so it will split up blockquotes into
258
- // more than one paragraph. A way to solve this would be to make that
259
- // system understand blockquotes, but then translators would have to
260
- // translate an entire, multi-paragraph blockquote at a time. Instead,
261
- // we choose to modify our blockquote matching to split up
262
- // multi-paragraph blockquotes into multiple blockquotes.
263
- //
264
- // There is also precedence for doing this splitting up in other
265
- // libraries, for instance CommonMark also splits up blockquotes with
266
- // empty lines into multiple blockquotes:
267
- // https://spec.commonmark.org/0.28/#example-205
268
- match: SimpleMarkdown__default.default.blockRegex(/^ *>[^\n]+(\n( *>)?[^\n]+)*\n{2,}/)
269
- },
270
- // The lint rule never actually matches anything.
271
- // We check for lint after parsing, and, if we find any, we
272
- // transform the tree to add lint nodes. This rule is here
273
- // just for the react() function
274
- lint: {
275
- order: 1000,
276
- match: s => null,
277
- parse: (capture, parse, state) => ({})
278
- }
279
- };
280
-
281
- // @ts-expect-error - TS2345 - Argument of type '{ readonly columns: { readonly order: -2; readonly match: any; readonly parse: (capture: any, parse: any, state: any) => any; }; readonly crowdinId: { readonly order: -1; readonly match: (source: any, state: any, prevCapture: any) => any; readonly parse: (capture: any, parse: any, state: any) => any; }; ... 34 more ...' is not assignable to parameter of type 'ParserRules'.
282
- const builtParser = SimpleMarkdown__default.default.parserFor(pureMarkdownRules);
283
- const parse = (source, state) => {
284
- const paragraphedSource = source + "\n\n";
285
- return builtParser(paragraphedSource, {
286
- ...state,
287
- inline: false
288
- });
289
- };
14
+ const rWidgetRule=/^\[\[\u2603 (([a-z-]+) ([0-9]+))\]\]/;const mathMatcher=(source,state,isBlock)=>{const length=source.length;let index=0;if(isBlock){if(state.inline){return null}while(index<length&&source[index]===" "){index++;}}if(!(index<length&&source[index]==="$")){return null}index++;const startIndex=index;let braceLevel=0;while(index<length){const character=source[index];if(character==="\\"){index++;}else if(braceLevel<=0&&character==="$"){let endIndex=index+1;if(isBlock){const match=/^(?: *\n){2,}/.exec(source.slice(endIndex));endIndex=match?endIndex+match[0].length:null;}if(endIndex){return [source.substring(0,endIndex),source.substring(startIndex,index)]}return null}else if(character==="{"){braceLevel++;}else if(character==="}"){braceLevel--;}else if(character==="\n"&&source[index-1]==="\n"){return null}index++;}return null};const mathMatch=(source,state)=>mathMatcher(source,state,false);const blockMathMatch=(source,state)=>mathMatcher(source,state,true);const TITLED_TABLE_REGEX=new RegExp("^\\|\\| +(.*) +\\|\\| *\\n"+"("+SimpleMarkdown__default.default.defaultRules.nptable.match.regex.source.substring(1)+")");const crowdinJiptMatcher=SimpleMarkdown__default.default.blockRegex(/^(crwdns.*)\n\s*\n/);const pureMarkdownRules={...SimpleMarkdown__default.default.defaultRules,columns:{order:-2,match:SimpleMarkdown__default.default.blockRegex(/^([\s\S]*\n\n)={5,}\n\n([\s\S]*)/),parse:(capture,parse,state)=>{return {col1:parse(capture[1],state),col2:parse(capture[2],state)}}},crowdinId:{order:-1,match:(source,state,prevCapture)=>{if(state.isJipt){return crowdinJiptMatcher(source,state,prevCapture)}return null},parse:(capture,parse,state)=>({id:capture[1]})},titledTable:{order:SimpleMarkdown__default.default.defaultRules.nptable.order-.5,match:SimpleMarkdown__default.default.blockRegex(TITLED_TABLE_REGEX),parse:(capture,parse,state)=>{const title=SimpleMarkdown__default.default.parseInline(parse,capture[1],state);const tableCapture=capture.slice(2);const table=SimpleMarkdown__default.default.defaultRules.nptable.parse(tableCapture,parse,state);return {title:title,table:table}}},widget:{order:SimpleMarkdown__default.default.defaultRules.link.order-.75,match:SimpleMarkdown__default.default.inlineRegex(rWidgetRule),parse:(capture,parse,state)=>{return {id:capture[1],widgetType:capture[2]}}},blockMath:{order:SimpleMarkdown__default.default.defaultRules.codeBlock.order+.5,match:blockMathMatch,parse:(capture,parse,state)=>{return {content:capture[1]}}},math:{order:SimpleMarkdown__default.default.defaultRules.link.order-.25,match:mathMatch,parse:(capture,parse,state)=>{return {content:capture[1]}}},unescapedDollar:{order:SimpleMarkdown__default.default.defaultRules.link.order-.24,match:SimpleMarkdown__default.default.inlineRegex(/^(?!\\)\$/),parse:(capture,parse,state)=>{return {}}},fence:{...SimpleMarkdown__default.default.defaultRules.fence,parse:(capture,parse,state)=>{const node=SimpleMarkdown__default.default.defaultRules.fence.parse(capture,parse,state);if(node.lang==="alt"){return {type:"codeBlock",lang:"alt",content:parse(node.content+"\n\n",state)}}return node}},blockQuote:{...SimpleMarkdown__default.default.defaultRules.blockQuote,match:SimpleMarkdown__default.default.blockRegex(/^ *>[^\n]+(\n( *>)?[^\n]+)*\n{2,}/)},lint:{order:1e3,match:s=>null,parse:(capture,parse,state)=>({})}};const builtParser=SimpleMarkdown__default.default.parserFor(pureMarkdownRules);const parse=(source,state)=>{const paragraphedSource=source+"\n\n";return builtParser(paragraphedSource,{...state,inline:false})};
290
15
 
291
16
  exports.libVersion = libVersion;
292
17
  exports.parse = parse;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/version.ts","../src/index.ts"],"sourcesContent":["// This file is processed by a Rollup plugin (replace) to inject the production\n// version number during the release build.\n// In dev, you'll never see the version number.\n\nimport {addLibraryVersionToPerseusDebug} from \"@khanacademy/perseus-utils\";\n\nconst libName = \"@khanacademy/pure-markdown\";\nexport const libVersion = \"__lib_version__\";\n\naddLibraryVersionToPerseusDebug(libName, libVersion);\n","/**\n * Contains markdown related functions in pure javascript,\n * extracted from perseus-markdown.jsx\n * Note that this file may be used in stand alone nodejs, thus\n * do not import anything from Perseus\n */\nexport {libVersion} from \"./version\";\n\nimport SimpleMarkdown from \"@khanacademy/simple-markdown\";\n\nconst rWidgetRule = /^\\[\\[\\u2603 (([a-z-]+) ([0-9]+))\\]\\]/;\n\n/**\n * This match function matches math in `$`s, such as:\n *\n * $y = x + 1$\n *\n * It functions roughly like the following regex:\n * /\\$([^\\$]*)\\$/\n *\n * Unfortunately, math may have other `$`s inside it, as\n * long as they are inside `{` braces `}`, mostly for\n * `\\text{ $math$ }`.\n *\n * To parse this, we can't use a regex, since we\n * should support arbitrary nesting (even though\n * MathJax actually only supports two levels of nesting\n * here, which we *could* parse with a regex).\n *\n * Non-regex matchers like this are now a first-class\n * concept in simple-markdown. Yay!\n *\n * This can also match block-math, which is math alone in a paragraph.\n */\nconst mathMatcher = (source: any, state: any, isBlock: boolean) => {\n const length = source.length;\n let index = 0;\n\n // When looking for blocks, skip over leading spaces\n if (isBlock) {\n if (state.inline) {\n return null;\n }\n while (index < length && source[index] === \" \") {\n index++;\n }\n }\n\n // Our source must start with a \"$\"\n if (!(index < length && source[index] === \"$\")) {\n return null;\n }\n\n index++;\n const startIndex = index;\n let braceLevel = 0;\n\n // Loop through the source, looking for a closing '$'\n // closing '$'s only count if they are not escaped with\n // a `\\`, and we are not in nested `{}` braces.\n while (index < length) {\n const character = source[index];\n\n if (character === \"\\\\\") {\n // Consume both the `\\` and the escaped char as a single\n // token.\n // This is so that the second `$` in `$\\\\$` closes\n // the math expression, since the first `\\` is escaping\n // the second `\\`, but the second `\\` is not escaping\n // the second `$`.\n // This also handles the case of escaping `$`s or\n // braces `\\{`\n index++;\n } else if (braceLevel <= 0 && character === \"$\") {\n let endIndex = index + 1;\n if (isBlock) {\n // Look for two trailing newlines after the closing `$`\n const match = /^(?: *\\n){2,}/.exec(source.slice(endIndex));\n // @ts-expect-error - TS2322 - Type 'number | null' is not assignable to type 'number'.\n endIndex = match ? endIndex + match[0].length : null;\n }\n\n // Return an array that looks like the results of a\n // regex's .exec function:\n // capture[0] is the whole string\n // capture[1] is the first \"paren\" match, which is the\n // content of the math here, as if we wrote the regex\n // /\\$([^\\$]*)\\$/\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n if (endIndex) {\n return [\n source.substring(0, endIndex),\n source.substring(startIndex, index),\n ];\n }\n return null;\n } else if (character === \"{\") {\n braceLevel++;\n } else if (character === \"}\") {\n braceLevel--;\n } else if (character === \"\\n\" && source[index - 1] === \"\\n\") {\n // This is a weird case we supported in the old\n // math implementation--double newlines break\n // math. I'm preserving it for now because content\n // creators might have questions with single '$'s\n // in paragraphs...\n return null;\n }\n\n index++;\n }\n\n // we didn't find a closing `$`\n return null;\n};\nconst mathMatch = (source: any, state: any): any =>\n mathMatcher(source, state, false);\nconst blockMathMatch = (source: any, state: any): any =>\n mathMatcher(source, state, true);\n\nconst TITLED_TABLE_REGEX = new RegExp(\n \"^\\\\|\\\\| +(.*) +\\\\|\\\\| *\\\\n\" +\n \"(\" +\n // The simple-markdown nptable regex, without\n // the leading `^`\n // @ts-expect-error - TS2532 - Object is possibly 'undefined'.\n SimpleMarkdown.defaultRules.nptable.match.regex.source.substring(1) +\n \")\",\n);\n\nconst crowdinJiptMatcher = SimpleMarkdown.blockRegex(/^(crwdns.*)\\n\\s*\\n/);\n\nexport const pureMarkdownRules = {\n ...SimpleMarkdown.defaultRules,\n\n // NOTE: basically ignored by JIPT. wraps everything at the outer layer\n columns: {\n order: -2,\n match: SimpleMarkdown.blockRegex(\n /^([\\s\\S]*\\n\\n)={5,}\\n\\n([\\s\\S]*)/,\n ) as any,\n parse: (capture: any, parse: any, state: any): any => {\n return {\n col1: parse(capture[1], state),\n col2: parse(capture[2], state),\n };\n },\n },\n crowdinId: {\n order: -1,\n match: (source: any, state: any, prevCapture: any): any => {\n // Only match on the just-in-place translation site\n if (state.isJipt) {\n return crowdinJiptMatcher(source, state, prevCapture);\n }\n return null;\n },\n parse: (capture: any, parse: any, state: any): any => ({\n id: capture[1],\n }),\n },\n // This is pretty much horrible, but we have a regex here to capture an\n // entire table + a title. capture[1] is the title. capture[2] of the\n // regex is a copy of the simple-markdown nptable regex. Then we turn\n // our capture[2] into tableCapture[0], and any further captures in\n // our table regex into tableCapture[1..], and we pass tableCapture to\n // our nptable regex\n titledTable: {\n // process immediately before nptables\n order: SimpleMarkdown.defaultRules.nptable.order - 0.5,\n match: SimpleMarkdown.blockRegex(TITLED_TABLE_REGEX) as any,\n parse: (capture: any, parse: any, state: any): any => {\n const title = SimpleMarkdown.parseInline(parse, capture[1], state);\n\n // Remove our [0] and [1] captures, and pass the rest to\n // the nptable parser\n const tableCapture = capture.slice(2);\n const table = SimpleMarkdown.defaultRules.nptable.parse(\n tableCapture,\n parse,\n state,\n );\n return {\n title: title,\n table: table,\n };\n },\n },\n widget: {\n order: SimpleMarkdown.defaultRules.link.order - 0.75,\n match: SimpleMarkdown.inlineRegex(rWidgetRule) as any,\n parse: (capture: any, parse: any, state: any): any => {\n return {\n id: capture[1],\n widgetType: capture[2],\n };\n },\n },\n blockMath: {\n order: (SimpleMarkdown.defaultRules.codeBlock.order + 0.5) as any,\n match: blockMathMatch,\n parse: (capture: any, parse: any, state: any): any => {\n return {\n content: capture[1],\n };\n },\n },\n math: {\n order: SimpleMarkdown.defaultRules.link.order - 0.25,\n match: mathMatch,\n parse: (capture: any, parse: any, state: any): any => {\n return {\n content: capture[1],\n };\n },\n },\n unescapedDollar: {\n order: SimpleMarkdown.defaultRules.link.order - 0.24,\n match: SimpleMarkdown.inlineRegex(/^(?!\\\\)\\$/) as any,\n parse: (capture: any, parse: any, state: any): any => {\n return {};\n },\n },\n fence: {\n ...SimpleMarkdown.defaultRules.fence,\n parse: (capture: any, parse: any, state: any): any => {\n const node = SimpleMarkdown.defaultRules.fence.parse(\n capture,\n parse,\n state,\n );\n\n // support screenreader-only text with ```alt\n if (node.lang === \"alt\") {\n return {\n type: \"codeBlock\",\n lang: \"alt\",\n // default codeBlock parsing doesn't parse the contents.\n // We need to parse the contents for things like table\n // support :).\n // The \\n\\n is because the inside of the codeblock might\n // not end in double newlines for block rules, because\n // ordinarily we don't parse this :).\n content: parse(node.content + \"\\n\\n\", state),\n };\n }\n return node;\n },\n },\n blockQuote: {\n ...SimpleMarkdown.defaultRules.blockQuote,\n // Replace the less restrictive blockquote regex from SimpleMarkdown\n // with a more restrictive one. The only difference should be that\n //\n // > A blockquote\n //\n // > Another blockquote\n //\n // will now match as two different blockQuotes instead of a single\n // blockquote with some paragraph breaks in it.\n //\n // The main motivation for doing this is to provide better support for\n // translators translating blockquotes with multiple paragraphs in\n // them. When translating articles, we split up paragraphs, translate\n // them separately, and then recombine them. We do this so that\n // translators don't have to translate an entire article at a time,\n // they can instead translate paragraph-by-paragraph.That system\n // doesn't understand blockquotes, so it will split up blockquotes into\n // more than one paragraph. A way to solve this would be to make that\n // system understand blockquotes, but then translators would have to\n // translate an entire, multi-paragraph blockquote at a time. Instead,\n // we choose to modify our blockquote matching to split up\n // multi-paragraph blockquotes into multiple blockquotes.\n //\n // There is also precedence for doing this splitting up in other\n // libraries, for instance CommonMark also splits up blockquotes with\n // empty lines into multiple blockquotes:\n // https://spec.commonmark.org/0.28/#example-205\n match: SimpleMarkdown.blockRegex(\n /^ *>[^\\n]+(\\n( *>)?[^\\n]+)*\\n{2,}/,\n ) as any,\n },\n // The lint rule never actually matches anything.\n // We check for lint after parsing, and, if we find any, we\n // transform the tree to add lint nodes. This rule is here\n // just for the react() function\n lint: {\n order: 1000,\n match: (s: any): any => null,\n parse: (capture: any, parse: any, state: any): any => ({}),\n },\n} as const;\n\n// @ts-expect-error - TS2345 - Argument of type '{ readonly columns: { readonly order: -2; readonly match: any; readonly parse: (capture: any, parse: any, state: any) => any; }; readonly crowdinId: { readonly order: -1; readonly match: (source: any, state: any, prevCapture: any) => any; readonly parse: (capture: any, parse: any, state: any) => any; }; ... 34 more ...' is not assignable to parameter of type 'ParserRules'.\nconst builtParser = SimpleMarkdown.parserFor(pureMarkdownRules);\n\nexport const parse = (source: string, state?: any): any => {\n const paragraphedSource = source + \"\\n\\n\";\n\n return builtParser(paragraphedSource, {\n ...state,\n inline: false,\n });\n};\n"],"names":["libName","libVersion","addLibraryVersionToPerseusDebug","rWidgetRule","mathMatcher","source","state","isBlock","length","index","inline","startIndex","braceLevel","character","endIndex","match","exec","slice","substring","mathMatch","blockMathMatch","TITLED_TABLE_REGEX","RegExp","SimpleMarkdown","defaultRules","nptable","regex","crowdinJiptMatcher","blockRegex","pureMarkdownRules","columns","order","parse","capture","col1","col2","crowdinId","prevCapture","isJipt","id","titledTable","title","parseInline","tableCapture","table","widget","link","inlineRegex","widgetType","blockMath","codeBlock","content","math","unescapedDollar","fence","node","lang","type","blockQuote","lint","s","builtParser","parserFor","paragraphedSource"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/version.ts","../src/index.ts"],"sourcesContent":["// This file is processed by a Rollup plugin (replace) to inject the production\n// version number during the release build.\n// In dev, you'll never see the version number.\n\nimport {addLibraryVersionToPerseusDebug} from \"@khanacademy/perseus-utils\";\n\nconst libName = \"@khanacademy/pure-markdown\";\nexport const libVersion = \"__lib_version__\";\n\naddLibraryVersionToPerseusDebug(libName, libVersion);\n","/**\n * Contains markdown related functions in pure javascript,\n * extracted from perseus-markdown.jsx\n * Note that this file may be used in stand alone nodejs, thus\n * do not import anything from Perseus\n */\nexport {libVersion} from \"./version\";\n\nimport SimpleMarkdown from \"@khanacademy/simple-markdown\";\n\nconst rWidgetRule = /^\\[\\[\\u2603 (([a-z-]+) ([0-9]+))\\]\\]/;\n\n/**\n * This match function matches math in `$`s, such as:\n *\n * $y = x + 1$\n *\n * It functions roughly like the following regex:\n * /\\$([^\\$]*)\\$/\n *\n * Unfortunately, math may have other `$`s inside it, as\n * long as they are inside `{` braces `}`, mostly for\n * `\\text{ $math$ }`.\n *\n * To parse this, we can't use a regex, since we\n * should support arbitrary nesting (even though\n * MathJax actually only supports two levels of nesting\n * here, which we *could* parse with a regex).\n *\n * Non-regex matchers like this are now a first-class\n * concept in simple-markdown. Yay!\n *\n * This can also match block-math, which is math alone in a paragraph.\n */\nconst mathMatcher = (source: any, state: any, isBlock: boolean) => {\n const length = source.length;\n let index = 0;\n\n // When looking for blocks, skip over leading spaces\n if (isBlock) {\n if (state.inline) {\n return null;\n }\n while (index < length && source[index] === \" \") {\n index++;\n }\n }\n\n // Our source must start with a \"$\"\n if (!(index < length && source[index] === \"$\")) {\n return null;\n }\n\n index++;\n const startIndex = index;\n let braceLevel = 0;\n\n // Loop through the source, looking for a closing '$'\n // closing '$'s only count if they are not escaped with\n // a `\\`, and we are not in nested `{}` braces.\n while (index < length) {\n const character = source[index];\n\n if (character === \"\\\\\") {\n // Consume both the `\\` and the escaped char as a single\n // token.\n // This is so that the second `$` in `$\\\\$` closes\n // the math expression, since the first `\\` is escaping\n // the second `\\`, but the second `\\` is not escaping\n // the second `$`.\n // This also handles the case of escaping `$`s or\n // braces `\\{`\n index++;\n } else if (braceLevel <= 0 && character === \"$\") {\n let endIndex = index + 1;\n if (isBlock) {\n // Look for two trailing newlines after the closing `$`\n const match = /^(?: *\\n){2,}/.exec(source.slice(endIndex));\n // @ts-expect-error - TS2322 - Type 'number | null' is not assignable to type 'number'.\n endIndex = match ? endIndex + match[0].length : null;\n }\n\n // Return an array that looks like the results of a\n // regex's .exec function:\n // capture[0] is the whole string\n // capture[1] is the first \"paren\" match, which is the\n // content of the math here, as if we wrote the regex\n // /\\$([^\\$]*)\\$/\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n if (endIndex) {\n return [\n source.substring(0, endIndex),\n source.substring(startIndex, index),\n ];\n }\n return null;\n } else if (character === \"{\") {\n braceLevel++;\n } else if (character === \"}\") {\n braceLevel--;\n } else if (character === \"\\n\" && source[index - 1] === \"\\n\") {\n // This is a weird case we supported in the old\n // math implementation--double newlines break\n // math. I'm preserving it for now because content\n // creators might have questions with single '$'s\n // in paragraphs...\n return null;\n }\n\n index++;\n }\n\n // we didn't find a closing `$`\n return null;\n};\nconst mathMatch = (source: any, state: any): any =>\n mathMatcher(source, state, false);\nconst blockMathMatch = (source: any, state: any): any =>\n mathMatcher(source, state, true);\n\nconst TITLED_TABLE_REGEX = new RegExp(\n \"^\\\\|\\\\| +(.*) +\\\\|\\\\| *\\\\n\" +\n \"(\" +\n // The simple-markdown nptable regex, without\n // the leading `^`\n // @ts-expect-error - TS2532 - Object is possibly 'undefined'.\n SimpleMarkdown.defaultRules.nptable.match.regex.source.substring(1) +\n \")\",\n);\n\nconst crowdinJiptMatcher = SimpleMarkdown.blockRegex(/^(crwdns.*)\\n\\s*\\n/);\n\nexport const pureMarkdownRules = {\n ...SimpleMarkdown.defaultRules,\n\n // NOTE: basically ignored by JIPT. wraps everything at the outer layer\n columns: {\n order: -2,\n match: SimpleMarkdown.blockRegex(\n /^([\\s\\S]*\\n\\n)={5,}\\n\\n([\\s\\S]*)/,\n ) as any,\n parse: (capture: any, parse: any, state: any): any => {\n return {\n col1: parse(capture[1], state),\n col2: parse(capture[2], state),\n };\n },\n },\n crowdinId: {\n order: -1,\n match: (source: any, state: any, prevCapture: any): any => {\n // Only match on the just-in-place translation site\n if (state.isJipt) {\n return crowdinJiptMatcher(source, state, prevCapture);\n }\n return null;\n },\n parse: (capture: any, parse: any, state: any): any => ({\n id: capture[1],\n }),\n },\n // This is pretty much horrible, but we have a regex here to capture an\n // entire table + a title. capture[1] is the title. capture[2] of the\n // regex is a copy of the simple-markdown nptable regex. Then we turn\n // our capture[2] into tableCapture[0], and any further captures in\n // our table regex into tableCapture[1..], and we pass tableCapture to\n // our nptable regex\n titledTable: {\n // process immediately before nptables\n order: SimpleMarkdown.defaultRules.nptable.order - 0.5,\n match: SimpleMarkdown.blockRegex(TITLED_TABLE_REGEX) as any,\n parse: (capture: any, parse: any, state: any): any => {\n const title = SimpleMarkdown.parseInline(parse, capture[1], state);\n\n // Remove our [0] and [1] captures, and pass the rest to\n // the nptable parser\n const tableCapture = capture.slice(2);\n const table = SimpleMarkdown.defaultRules.nptable.parse(\n tableCapture,\n parse,\n state,\n );\n return {\n title: title,\n table: table,\n };\n },\n },\n widget: {\n order: SimpleMarkdown.defaultRules.link.order - 0.75,\n match: SimpleMarkdown.inlineRegex(rWidgetRule) as any,\n parse: (capture: any, parse: any, state: any): any => {\n return {\n id: capture[1],\n widgetType: capture[2],\n };\n },\n },\n blockMath: {\n order: (SimpleMarkdown.defaultRules.codeBlock.order + 0.5) as any,\n match: blockMathMatch,\n parse: (capture: any, parse: any, state: any): any => {\n return {\n content: capture[1],\n };\n },\n },\n math: {\n order: SimpleMarkdown.defaultRules.link.order - 0.25,\n match: mathMatch,\n parse: (capture: any, parse: any, state: any): any => {\n return {\n content: capture[1],\n };\n },\n },\n unescapedDollar: {\n order: SimpleMarkdown.defaultRules.link.order - 0.24,\n match: SimpleMarkdown.inlineRegex(/^(?!\\\\)\\$/) as any,\n parse: (capture: any, parse: any, state: any): any => {\n return {};\n },\n },\n fence: {\n ...SimpleMarkdown.defaultRules.fence,\n parse: (capture: any, parse: any, state: any): any => {\n const node = SimpleMarkdown.defaultRules.fence.parse(\n capture,\n parse,\n state,\n );\n\n // support screenreader-only text with ```alt\n if (node.lang === \"alt\") {\n return {\n type: \"codeBlock\",\n lang: \"alt\",\n // default codeBlock parsing doesn't parse the contents.\n // We need to parse the contents for things like table\n // support :).\n // The \\n\\n is because the inside of the codeblock might\n // not end in double newlines for block rules, because\n // ordinarily we don't parse this :).\n content: parse(node.content + \"\\n\\n\", state),\n };\n }\n return node;\n },\n },\n blockQuote: {\n ...SimpleMarkdown.defaultRules.blockQuote,\n // Replace the less restrictive blockquote regex from SimpleMarkdown\n // with a more restrictive one. The only difference should be that\n //\n // > A blockquote\n //\n // > Another blockquote\n //\n // will now match as two different blockQuotes instead of a single\n // blockquote with some paragraph breaks in it.\n //\n // The main motivation for doing this is to provide better support for\n // translators translating blockquotes with multiple paragraphs in\n // them. When translating articles, we split up paragraphs, translate\n // them separately, and then recombine them. We do this so that\n // translators don't have to translate an entire article at a time,\n // they can instead translate paragraph-by-paragraph.That system\n // doesn't understand blockquotes, so it will split up blockquotes into\n // more than one paragraph. A way to solve this would be to make that\n // system understand blockquotes, but then translators would have to\n // translate an entire, multi-paragraph blockquote at a time. Instead,\n // we choose to modify our blockquote matching to split up\n // multi-paragraph blockquotes into multiple blockquotes.\n //\n // There is also precedence for doing this splitting up in other\n // libraries, for instance CommonMark also splits up blockquotes with\n // empty lines into multiple blockquotes:\n // https://spec.commonmark.org/0.28/#example-205\n match: SimpleMarkdown.blockRegex(\n /^ *>[^\\n]+(\\n( *>)?[^\\n]+)*\\n{2,}/,\n ) as any,\n },\n // The lint rule never actually matches anything.\n // We check for lint after parsing, and, if we find any, we\n // transform the tree to add lint nodes. This rule is here\n // just for the react() function\n lint: {\n order: 1000,\n match: (s: any): any => null,\n parse: (capture: any, parse: any, state: any): any => ({}),\n },\n} as const;\n\n// @ts-expect-error - TS2345 - Argument of type '{ readonly columns: { readonly order: -2; readonly match: any; readonly parse: (capture: any, parse: any, state: any) => any; }; readonly crowdinId: { readonly order: -1; readonly match: (source: any, state: any, prevCapture: any) => any; readonly parse: (capture: any, parse: any, state: any) => any; }; ... 34 more ...' is not assignable to parameter of type 'ParserRules'.\nconst builtParser = SimpleMarkdown.parserFor(pureMarkdownRules);\n\nexport const parse = (source: string, state?: any): any => {\n const paragraphedSource = source + \"\\n\\n\";\n\n return builtParser(paragraphedSource, {\n ...state,\n inline: false,\n });\n};\n"],"names":["libName","libVersion","addLibraryVersionToPerseusDebug","rWidgetRule","mathMatcher","source","state","isBlock","length","index","inline","startIndex","braceLevel","character","endIndex","match","exec","slice","substring","mathMatch","blockMathMatch","TITLED_TABLE_REGEX","RegExp","SimpleMarkdown","defaultRules","nptable","regex","crowdinJiptMatcher","blockRegex","pureMarkdownRules","columns","order","parse","capture","col1","col2","crowdinId","prevCapture","isJipt","id","titledTable","title","parseInline","tableCapture","table","widget","link","inlineRegex","widgetType","blockMath","codeBlock","content","math","unescapedDollar","fence","node","lang","type","blockQuote","lint","s","builtParser","parserFor","paragraphedSource"],"mappings":"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"}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "SimpleMarkdown instance with non-react Perseus rules",
4
4
  "author": "Khan Academy",
5
5
  "license": "MIT",
6
- "version": "2.0.0",
6
+ "version": "2.0.2",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
@@ -22,11 +22,11 @@
22
22
  "dist"
23
23
  ],
24
24
  "dependencies": {
25
- "@khanacademy/perseus-utils": "2.0.0",
26
- "@khanacademy/simple-markdown": "2.0.0"
25
+ "@khanacademy/perseus-utils": "2.0.1",
26
+ "@khanacademy/simple-markdown": "2.0.2"
27
27
  },
28
28
  "devDependencies": {
29
- "perseus-build-settings": "0.6.0"
29
+ "perseus-build-settings": "0.6.1"
30
30
  },
31
31
  "peerDependencies": {},
32
32
  "keywords": [],