@khanacademy/perseus 0.2.7 → 0.2.8

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.
Files changed (84) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +5 -0
  3. package/dist/es/index.js +3094 -5325
  4. package/dist/es/index.js.map +1 -1
  5. package/dist/index.js +13597 -15834
  6. package/dist/index.js.map +1 -1
  7. package/package.json +4 -2
  8. package/src/__tests__/perseus-markdown_test.jsx +4 -4
  9. package/src/article-renderer.jsx +3 -4
  10. package/src/components/input-with-examples.jsx +3 -4
  11. package/src/components/sortable.jsx +4 -5
  12. package/src/hint-renderer.jsx +2 -3
  13. package/src/hints-renderer.jsx +2 -3
  14. package/src/item-renderer.jsx +2 -3
  15. package/src/not-gorgon.js +1 -2
  16. package/src/perseus-markdown.jsx +1 -2
  17. package/src/renderer.jsx +2 -3
  18. package/src/widget-container.jsx +1 -1
  19. package/src/widgets/categorizer.jsx +1 -1
  20. package/src/widgets/explanation.jsx +1 -1
  21. package/src/widgets/expression.jsx +1 -1
  22. package/src/widgets/graded-group-set.jsx +1 -1
  23. package/src/widgets/graded-group.jsx +1 -1
  24. package/src/widgets/group.jsx +1 -1
  25. package/src/widgets/image.jsx +1 -1
  26. package/src/widgets/input-number.jsx +1 -1
  27. package/src/widgets/matcher.jsx +4 -1
  28. package/src/widgets/matrix.jsx +1 -1
  29. package/src/widgets/numeric-input.jsx +1 -1
  30. package/src/widgets/orderer.jsx +4 -1
  31. package/src/widgets/passage-ref-target.jsx +4 -1
  32. package/src/widgets/passage.jsx +1 -1
  33. package/src/widgets/radio/widget.jsx +1 -1
  34. package/src/widgets/sequence.jsx +4 -1
  35. package/src/widgets/sorter.jsx +4 -1
  36. package/src/widgets/table.jsx +4 -1
  37. package/src/README.md +0 -35
  38. package/src/__tests__/__snapshots__/pure-markdown_test.js.snap +0 -113
  39. package/src/__tests__/pure-markdown_test.js +0 -552
  40. package/src/gorgon/README +0 -40
  41. package/src/gorgon/__tests__/matcher_test.js +0 -497
  42. package/src/gorgon/__tests__/rule_test.js +0 -101
  43. package/src/gorgon/__tests__/rules_test.js +0 -487
  44. package/src/gorgon/__tests__/selector-parser_test.js +0 -52
  45. package/src/gorgon/__tests__/tree-transformer_test.js +0 -446
  46. package/src/gorgon/gorgon.js +0 -290
  47. package/src/gorgon/proptypes.js +0 -29
  48. package/src/gorgon/rule.js +0 -413
  49. package/src/gorgon/rules/absolute-url.js +0 -24
  50. package/src/gorgon/rules/all-rules.js +0 -72
  51. package/src/gorgon/rules/blockquoted-math.js +0 -10
  52. package/src/gorgon/rules/blockquoted-widget.js +0 -10
  53. package/src/gorgon/rules/double-spacing-after-terminal.js +0 -12
  54. package/src/gorgon/rules/extra-content-spacing.js +0 -12
  55. package/src/gorgon/rules/heading-level-1.js +0 -14
  56. package/src/gorgon/rules/heading-level-skip.js +0 -20
  57. package/src/gorgon/rules/heading-sentence-case.js +0 -11
  58. package/src/gorgon/rules/heading-title-case.js +0 -63
  59. package/src/gorgon/rules/image-alt-text.js +0 -21
  60. package/src/gorgon/rules/image-in-table.js +0 -10
  61. package/src/gorgon/rules/image-spaces-around-urls.js +0 -35
  62. package/src/gorgon/rules/image-widget.js +0 -50
  63. package/src/gorgon/rules/link-click-here.js +0 -11
  64. package/src/gorgon/rules/lint-utils.js +0 -48
  65. package/src/gorgon/rules/long-paragraph.js +0 -14
  66. package/src/gorgon/rules/math-adjacent.js +0 -10
  67. package/src/gorgon/rules/math-align-extra-break.js +0 -11
  68. package/src/gorgon/rules/math-align-linebreaks.js +0 -43
  69. package/src/gorgon/rules/math-empty.js +0 -10
  70. package/src/gorgon/rules/math-font-size.js +0 -12
  71. package/src/gorgon/rules/math-frac.js +0 -10
  72. package/src/gorgon/rules/math-nested.js +0 -11
  73. package/src/gorgon/rules/math-starts-with-space.js +0 -12
  74. package/src/gorgon/rules/math-text-empty.js +0 -10
  75. package/src/gorgon/rules/math-without-dollars.js +0 -14
  76. package/src/gorgon/rules/nested-lists.js +0 -11
  77. package/src/gorgon/rules/profanity.js +0 -10
  78. package/src/gorgon/rules/table-missing-cells.js +0 -20
  79. package/src/gorgon/rules/unbalanced-code-delimiters.js +0 -14
  80. package/src/gorgon/rules/unescaped-dollar.js +0 -10
  81. package/src/gorgon/rules/widget-in-table.js +0 -10
  82. package/src/gorgon/selector.js +0 -506
  83. package/src/gorgon/tree-transformer.js +0 -588
  84. package/src/pure-markdown.js +0 -347
@@ -1,113 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`pure markdown parser should parse titled table with unescaped dollars 1`] = `
4
- Array [
5
- Object {
6
- "table": Object {
7
- "align": Array [
8
- null,
9
- null,
10
- null,
11
- ],
12
- "cells": Array [
13
- Array [
14
- Array [
15
- Object {
16
- "content": "data 1",
17
- "type": "text",
18
- },
19
- ],
20
- Array [
21
- Object {
22
- "content": "data 2",
23
- "type": "text",
24
- },
25
- ],
26
- Array [
27
- Object {
28
- "content": "data 3",
29
- "type": "text",
30
- },
31
- ],
32
- ],
33
- Array [
34
- Array [
35
- Object {
36
- "content": "data 4",
37
- "type": "text",
38
- },
39
- ],
40
- Array [
41
- Object {
42
- "type": "unescapedDollar",
43
- },
44
- Object {
45
- "content": "data 5",
46
- "type": "text",
47
- },
48
- ],
49
- Array [
50
- Object {
51
- "content": "data 6",
52
- "type": "text",
53
- },
54
- ],
55
- ],
56
- Array [
57
- Array [
58
- Object {
59
- "content": "data 7",
60
- "type": "text",
61
- },
62
- ],
63
- Array [
64
- Object {
65
- "content": "data 8",
66
- "type": "text",
67
- },
68
- ],
69
- Array [
70
- Object {
71
- "content": "data 9",
72
- "type": "text",
73
- },
74
- ],
75
- ],
76
- ],
77
- "header": Array [
78
- Array [
79
- Object {
80
- "content": "header 1",
81
- "type": "text",
82
- },
83
- ],
84
- Array [
85
- Object {
86
- "content": "header 2",
87
- "type": "text",
88
- },
89
- ],
90
- Array [
91
- Object {
92
- "content": "header 3",
93
- "type": "text",
94
- },
95
- ],
96
- ],
97
- "type": "table",
98
- },
99
- "title": Array [
100
- Object {
101
- "content": Array [
102
- Object {
103
- "content": "Table title",
104
- "type": "text",
105
- },
106
- ],
107
- "type": "strong",
108
- },
109
- ],
110
- "type": "titledTable",
111
- },
112
- ]
113
- `;
@@ -1,552 +0,0 @@
1
- // @flow
2
- import {parse} from "../pure-markdown.js";
3
-
4
- describe("pure markdown", () => {
5
- describe("parser", () => {
6
- it.each([
7
- {
8
- content: "math $y = x + 1$",
9
- expected: [
10
- {
11
- type: "paragraph",
12
- content: [
13
- {type: "text", content: "math "},
14
- {type: "math", content: "y = x + 1"},
15
- ],
16
- },
17
- ],
18
- },
19
- {
20
- content: "hi $y = x + 1$ there",
21
- expected: [
22
- {
23
- type: "paragraph",
24
- content: [
25
- {type: "text", content: "hi "},
26
- {type: "math", content: "y = x + 1"},
27
- {type: "text", content: " there"},
28
- ],
29
- },
30
- ],
31
- },
32
- ])("should parse math", ({content, expected}) => {
33
- // Arrange, Act
34
- const parsed = parse(content);
35
-
36
- // Assert
37
- expect(parsed).toEqual(expected);
38
- });
39
-
40
- it.each([
41
- {
42
- content: "math $y = \\text{$x + 1$}$",
43
- expected: [
44
- {
45
- type: "paragraph",
46
- content: [
47
- {type: "text", content: "math "},
48
- {type: "math", content: "y = \\text{$x + 1$}"},
49
- ],
50
- },
51
- ],
52
- },
53
- {
54
- content:
55
- "math $ x^2 \\text{blah $math \\text{some $more math$} $ } $",
56
- expected: [
57
- {
58
- type: "paragraph",
59
- content: [
60
- {type: "text", content: "math "},
61
- {
62
- type: "math",
63
- content:
64
- " x^2 \\text{blah $math " +
65
- "\\text{some $more math$} $ } ",
66
- },
67
- ],
68
- },
69
- ],
70
- },
71
- ])("should parse nested math", ({content, expected}) => {
72
- // Arrange, Act
73
- const parsed = parse(content);
74
-
75
- // Assert
76
- expect(parsed).toEqual(expected);
77
- });
78
-
79
- it.each([
80
- {
81
- content: "math $\\\\$",
82
- expected: [
83
- {
84
- type: "paragraph",
85
- content: [
86
- {type: "text", content: "math "},
87
- {type: "math", content: "\\\\"},
88
- ],
89
- },
90
- ],
91
- },
92
- {
93
- content: "math $\\$$",
94
- expected: [
95
- {
96
- type: "paragraph",
97
- content: [
98
- {type: "text", content: "math "},
99
- {type: "math", content: "\\$"},
100
- ],
101
- },
102
- ],
103
- },
104
- {
105
- content: "${$",
106
- expected: [
107
- {
108
- type: "paragraph",
109
- content: [
110
- {type: "unescapedDollar"},
111
- {type: "text", content: "{"},
112
- {type: "unescapedDollar"},
113
- ],
114
- },
115
- ],
116
- },
117
- {
118
- content: "math $\\{$",
119
- expected: [
120
- {
121
- type: "paragraph",
122
- content: [
123
- {type: "text", content: "math "},
124
- {type: "math", content: "\\{"},
125
- ],
126
- },
127
- ],
128
- },
129
- {
130
- content: "hello $ escaped dollar \\$ $ not math",
131
- expected: [
132
- {
133
- type: "paragraph",
134
- content: [
135
- {type: "text", content: "hello "},
136
- {type: "math", content: " escaped dollar \\$ "},
137
- {type: "text", content: " not math"},
138
- ],
139
- },
140
- ],
141
- },
142
- {
143
- content: "$math$ not math $ oops extra dollar",
144
- expected: [
145
- {
146
- type: "paragraph",
147
- content: [
148
- {content: "math", type: "math"},
149
- {content: " not math ", type: "text"},
150
- {type: "unescapedDollar"},
151
- {content: " oops extra dollar", type: "text"},
152
- ],
153
- },
154
- ],
155
- },
156
- ])("should allow escaping in math", ({content, expected}) => {
157
- // Arrange, Act
158
- const parsed = parse(content);
159
-
160
- // Assert
161
- expect(parsed).toEqual(expected);
162
- });
163
-
164
- it.each([
165
- {
166
- content: "$x + y = 7$",
167
- expected: [
168
- {
169
- type: "blockMath",
170
- content: "x + y = 7",
171
- },
172
- ],
173
- },
174
- {
175
- content: "$x + y = 7$\nnot math",
176
- expected: [
177
- {
178
- type: "paragraph",
179
- content: [
180
- {type: "math", content: "x + y = 7"},
181
- {type: "text", content: "\nnot math"},
182
- ],
183
- },
184
- ],
185
- },
186
- {
187
- content: " $x + y = 7$ \n\n \n$3 + 5 = 7$",
188
- expected: [
189
- {
190
- type: "blockMath",
191
- content: "x + y = 7",
192
- },
193
- {
194
- type: "blockMath",
195
- content: "3 + 5 = 7",
196
- },
197
- ],
198
- },
199
- {
200
- content: " $x + y = 7$",
201
- expected: [
202
- {
203
- type: "codeBlock",
204
- content: "$x + y = 7$",
205
- lang: undefined,
206
- },
207
- ],
208
- },
209
- {
210
- content: "> $x + y = 7$",
211
- expected: [
212
- {
213
- type: "blockQuote",
214
- content: [
215
- {
216
- type: "blockMath",
217
- content: "x + y = 7",
218
- },
219
- ],
220
- },
221
- ],
222
- },
223
- ])("should parse block math", ({content, expected}) => {
224
- // Arrange, Act
225
- const parsed = parse(content);
226
-
227
- // Assert
228
- expect(parsed).toEqual(expected);
229
- });
230
-
231
- it.each([
232
- {
233
- content: "hello $ single dollar paragraph\n\n not math $",
234
- expected: [
235
- {
236
- type: "paragraph",
237
- content: [
238
- {content: "hello ", type: "text"},
239
- {type: "unescapedDollar"},
240
- {content: " single dollar paragraph", type: "text"},
241
- ],
242
- },
243
- {
244
- type: "paragraph",
245
- content: [
246
- {content: " not math ", type: "text"},
247
- {type: "unescapedDollar"},
248
- ],
249
- },
250
- ],
251
- },
252
- {
253
- content: "hello $ bad { math $",
254
- expected: [
255
- {
256
- type: "paragraph",
257
- content: [
258
- {content: "hello ", type: "text"},
259
- {type: "unescapedDollar"},
260
- {content: " bad ", type: "text"},
261
- {content: "{ math ", type: "text"},
262
- {type: "unescapedDollar"},
263
- ],
264
- },
265
- ],
266
- },
267
- ])("should break on paragraphs", ({content, expected}) => {
268
- // Arrange, Act
269
- const parsed = parse(content);
270
-
271
- // Assert
272
- expect(parsed).toEqual(expected);
273
- });
274
-
275
- it.each([
276
- {
277
- content: "[[☃ test 1]]",
278
- expected: [
279
- {
280
- type: "paragraph",
281
- content: [
282
- {
283
- type: "widget",
284
- widgetType: "test",
285
- id: "test 1",
286
- },
287
- ],
288
- },
289
- ],
290
- },
291
- {
292
- content: "[[☃ test 1]]+[[☃ input-number 2]]",
293
- expected: [
294
- {
295
- type: "paragraph",
296
- content: [
297
- {
298
- type: "widget",
299
- widgetType: "test",
300
- id: "test 1",
301
- },
302
- {
303
- type: "text",
304
- content: "+",
305
- },
306
- {
307
- type: "widget",
308
- widgetType: "input-number",
309
- id: "input-number 2",
310
- },
311
- ],
312
- },
313
- ],
314
- },
315
- {
316
- content: "*[[☃ test 2]]* [[☃ input-number 1]]",
317
- expected: [
318
- {
319
- type: "paragraph",
320
- content: [
321
- {
322
- type: "em",
323
- content: [
324
- {
325
- type: "widget",
326
- widgetType: "test",
327
- id: "test 2",
328
- },
329
- ],
330
- },
331
- {
332
- type: "text",
333
- content: " ",
334
- },
335
- {
336
- type: "widget",
337
- widgetType: "input-number",
338
- id: "input-number 1",
339
- },
340
- ],
341
- },
342
- ],
343
- },
344
- ])("should parse widget types and ids", ({content, expected}) => {
345
- // Arrange, Act
346
- const parsed = parse(content);
347
-
348
- // Assert
349
- expect(parsed).toEqual(expected);
350
- });
351
-
352
- it("should allow escaping widget identifiers", () => {
353
- // Arrange, Act
354
- const parsed = parse("\\[[☃ test 1]]");
355
-
356
- // Assert
357
- expect(parsed).toEqual([
358
- {
359
- type: "paragraph",
360
- content: [
361
- {content: "[", type: "text"},
362
- {content: "[☃ test 1", type: "text"},
363
- {content: "]", type: "text"},
364
- {content: "]", type: "text"},
365
- ],
366
- },
367
- ]);
368
- });
369
-
370
- it.each([
371
- {
372
- content: "[[☃ test 1]][[☃ test 2]]",
373
- expected: [
374
- {
375
- type: "paragraph",
376
- content: [
377
- {type: "widget", widgetType: "test", id: "test 1"},
378
- {type: "widget", widgetType: "test", id: "test 2"},
379
- ],
380
- },
381
- ],
382
- },
383
- {
384
- content: "[[☃ test 1]] [[☃ test 2]]",
385
- expected: [
386
- {
387
- type: "paragraph",
388
- content: [
389
- {type: "widget", widgetType: "test", id: "test 1"},
390
- {type: "text", content: " "},
391
- {type: "widget", widgetType: "test", id: "test 2"},
392
- ],
393
- },
394
- ],
395
- },
396
- ])(
397
- "should parse widgets next to each other as widgets",
398
- ({content, expected}) => {
399
- // Arrange, Act
400
- const parsed = parse(content);
401
-
402
- // Assert
403
- expect(parsed).toEqual(expected);
404
- },
405
- );
406
-
407
- it("should parse multiple columns", () => {
408
- // Arrange, Act
409
- const parsed = parse("hi\n\n" + "=====\n\n" + "there\n\n");
410
-
411
- // Assert
412
- expect(parsed).toEqual([
413
- {
414
- type: "columns",
415
- col1: [
416
- {
417
- type: "paragraph",
418
- content: [
419
- {
420
- type: "text",
421
- content: "hi",
422
- },
423
- ],
424
- },
425
- ],
426
- col2: [
427
- {
428
- type: "paragraph",
429
- content: [
430
- {
431
- type: "text",
432
- content: "there",
433
- },
434
- ],
435
- },
436
- ],
437
- },
438
- ]);
439
- });
440
-
441
- it.each([
442
- {
443
- content: "1. test\n\n" + "2. boo\n\n",
444
- expected: [
445
- {
446
- type: "paragraph",
447
- content: [
448
- {
449
- type: "text",
450
- content: "1",
451
- },
452
- {
453
- type: "text",
454
- content: ". test",
455
- },
456
- ],
457
- },
458
- {
459
- type: "paragraph",
460
- content: [
461
- {
462
- type: "text",
463
- content: "2",
464
- },
465
- {
466
- type: "text",
467
- content: ". boo",
468
- },
469
- ],
470
- },
471
- ],
472
- },
473
- {
474
- content: "* test\n\n" + "* boo\n\n",
475
- expected: [
476
- {
477
- type: "paragraph",
478
- content: [
479
- {
480
- type: "text",
481
- content: "* test",
482
- },
483
- ],
484
- },
485
- {
486
- type: "paragraph",
487
- content: [
488
- {
489
- type: "text",
490
- content: "* boo",
491
- },
492
- ],
493
- },
494
- ],
495
- },
496
- ])("should ignore lists in jipt mode", ({content, expected}) => {
497
- // Arrange, Act
498
- const parsed = parse(content, {isJipt: true});
499
-
500
- // Assert
501
- expect(parsed).toEqual(expected);
502
- });
503
-
504
- it.each([
505
- {
506
- content: "$",
507
- expected: [
508
- {
509
- type: "paragraph",
510
- content: [{type: "unescapedDollar"}],
511
- },
512
- ],
513
- },
514
- {
515
- content: "hello $ single dollar",
516
- expected: [
517
- {
518
- type: "paragraph",
519
- content: [
520
- {content: "hello ", type: "text"},
521
- {type: "unescapedDollar"},
522
- {content: " single dollar", type: "text"},
523
- ],
524
- },
525
- ],
526
- },
527
- ])("should detect unescaped dollars", ({content, expected}) => {
528
- // Arrange, Act
529
- const parsed = parse(content);
530
-
531
- // Assert
532
- expect(parsed).toEqual(expected);
533
- });
534
-
535
- it("should parse titled table with unescaped dollars", () => {
536
- // Arrange
537
- const content =
538
- "|| **Table title** ||\n" +
539
- "header 1 | header 2 | header 3\n" +
540
- "- | - | -\n" +
541
- "data 1 | data 2 | data 3\n" +
542
- "data 4 | $data 5 | data 6\n" +
543
- "data 7 | data 8 | data 9";
544
-
545
- // Act
546
- const parsed = parse(content);
547
-
548
- // Assert
549
- expect(parsed).toMatchSnapshot();
550
- });
551
- });
552
- });
package/src/gorgon/README DELETED
@@ -1,40 +0,0 @@
1
- Gorgon is the linter engine for Perseus. It is implemented by the
2
- following files:
3
-
4
- tree-transformer.js:
5
-
6
- This file defines a TreeTransformer class for traversing (and
7
- optionally transforming by inserting, reparenting and removing
8
- nodes) markdown parse trees. When traversing a tree, a
9
- TreeTransformer calls the function you specify on each node. This is
10
- a post-order traversal: the function is called on the way back up,
11
- not on the way down. When the function is invoked, it is passed the
12
- current node, a state object, and the concatenated content of the
13
- node and its descendants. The state object is the interesting one:
14
- it is an instance of TraversalState, which is a class defined in
15
- (but not exported by) this same file. TraversalState has an API for
16
- querying the ancestors and siblings of the current node, and also an
17
- API for replacing the current node with a new one.
18
-
19
- selector.js:
20
-
21
- This file defines the Selector class which works like a CSS selector
22
- for markdown parse trees. Selector.parse() converts strings like
23
- "heading + paragraph > text" to Selector objects. A Selector object
24
- has a match() method that tests whether a given node in a parse tree
25
- matches. The match() method takes a TraversalState object as its
26
- argument, so selectors can only be used during a TreeTransformer
27
- traversal.
28
-
29
- rule.js:
30
-
31
- This file defines the Rule class which represents a single lint
32
- rule. A Rule object has a check() method that takes the same (node,
33
- state, content) arguments that a TreeTransformer passes to the
34
- traversal callback function. Rules can have a selector, a regular
35
- expression, and a function. If a node matches the selector and its
36
- content matches the regular expression, then the function is called
37
- to check the node and return a warning message if the node does, in
38
- fact, have lint.
39
-
40
- See the individual file for additional documentation.