@khanacademy/perseus 0.2.7 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +5 -0
  3. package/dist/es/index.css +1 -436
  4. package/dist/es/index.js +3172 -5450
  5. package/dist/es/index.js.map +1 -1
  6. package/dist/index.css +1 -436
  7. package/dist/index.js +13520 -15805
  8. package/dist/index.js.map +1 -1
  9. package/package.json +4 -2
  10. package/src/__tests__/perseus-markdown_test.jsx +6 -6
  11. package/src/__tests__/renderer_test.jsx +9 -9
  12. package/src/article-renderer.jsx +4 -5
  13. package/src/components/input-with-examples.jsx +4 -5
  14. package/src/components/lint.jsx +2 -1
  15. package/src/components/sortable.jsx +6 -7
  16. package/src/hint-renderer.jsx +3 -4
  17. package/src/hints-renderer.jsx +3 -4
  18. package/src/index.js +1 -0
  19. package/src/item-renderer.jsx +4 -5
  20. package/src/jquery.mobile.vmouse.js +2 -1
  21. package/src/perseus-markdown.jsx +3 -3
  22. package/src/renderer.jsx +31 -33
  23. package/src/styles/perseus-renderer.less +1 -1
  24. package/src/{not-gorgon.js → translation-linter.js} +10 -14
  25. package/src/types.js +3 -1
  26. package/src/widget-container.jsx +1 -1
  27. package/src/widgets/__tests__/__snapshots__/definition_test.js.snap +30 -12
  28. package/src/widgets/__tests__/definition_test.js +18 -33
  29. package/src/widgets/__tests__/grapher.cypress.jsx +2 -2
  30. package/src/widgets/__tests__/interactive-graph.cypress.jsx +2 -2
  31. package/src/widgets/categorizer.jsx +1 -1
  32. package/src/widgets/definition.jsx +36 -71
  33. package/src/widgets/explanation.jsx +1 -1
  34. package/src/widgets/expression.jsx +1 -1
  35. package/src/widgets/graded-group-set.jsx +1 -1
  36. package/src/widgets/graded-group.jsx +1 -1
  37. package/src/widgets/group.jsx +1 -1
  38. package/src/widgets/image.jsx +1 -1
  39. package/src/widgets/input-number.jsx +1 -1
  40. package/src/widgets/matcher.jsx +4 -1
  41. package/src/widgets/matrix.jsx +1 -1
  42. package/src/widgets/numeric-input.jsx +1 -1
  43. package/src/widgets/orderer.jsx +4 -1
  44. package/src/widgets/passage-ref-target.jsx +4 -1
  45. package/src/widgets/passage.jsx +1 -1
  46. package/src/widgets/radio/widget.jsx +1 -1
  47. package/src/widgets/sequence.jsx +4 -1
  48. package/src/widgets/sorter.jsx +4 -1
  49. package/src/widgets/table.jsx +4 -1
  50. package/src/README.md +0 -35
  51. package/src/__tests__/__snapshots__/pure-markdown_test.js.snap +0 -113
  52. package/src/__tests__/pure-markdown_test.js +0 -552
  53. package/src/gorgon/README +0 -40
  54. package/src/gorgon/__tests__/matcher_test.js +0 -497
  55. package/src/gorgon/__tests__/rule_test.js +0 -101
  56. package/src/gorgon/__tests__/rules_test.js +0 -487
  57. package/src/gorgon/__tests__/selector-parser_test.js +0 -52
  58. package/src/gorgon/__tests__/tree-transformer_test.js +0 -446
  59. package/src/gorgon/gorgon.js +0 -290
  60. package/src/gorgon/proptypes.js +0 -29
  61. package/src/gorgon/rule.js +0 -413
  62. package/src/gorgon/rules/absolute-url.js +0 -24
  63. package/src/gorgon/rules/all-rules.js +0 -72
  64. package/src/gorgon/rules/blockquoted-math.js +0 -10
  65. package/src/gorgon/rules/blockquoted-widget.js +0 -10
  66. package/src/gorgon/rules/double-spacing-after-terminal.js +0 -12
  67. package/src/gorgon/rules/extra-content-spacing.js +0 -12
  68. package/src/gorgon/rules/heading-level-1.js +0 -14
  69. package/src/gorgon/rules/heading-level-skip.js +0 -20
  70. package/src/gorgon/rules/heading-sentence-case.js +0 -11
  71. package/src/gorgon/rules/heading-title-case.js +0 -63
  72. package/src/gorgon/rules/image-alt-text.js +0 -21
  73. package/src/gorgon/rules/image-in-table.js +0 -10
  74. package/src/gorgon/rules/image-spaces-around-urls.js +0 -35
  75. package/src/gorgon/rules/image-widget.js +0 -50
  76. package/src/gorgon/rules/link-click-here.js +0 -11
  77. package/src/gorgon/rules/lint-utils.js +0 -48
  78. package/src/gorgon/rules/long-paragraph.js +0 -14
  79. package/src/gorgon/rules/math-adjacent.js +0 -10
  80. package/src/gorgon/rules/math-align-extra-break.js +0 -11
  81. package/src/gorgon/rules/math-align-linebreaks.js +0 -43
  82. package/src/gorgon/rules/math-empty.js +0 -10
  83. package/src/gorgon/rules/math-font-size.js +0 -12
  84. package/src/gorgon/rules/math-frac.js +0 -10
  85. package/src/gorgon/rules/math-nested.js +0 -11
  86. package/src/gorgon/rules/math-starts-with-space.js +0 -12
  87. package/src/gorgon/rules/math-text-empty.js +0 -10
  88. package/src/gorgon/rules/math-without-dollars.js +0 -14
  89. package/src/gorgon/rules/nested-lists.js +0 -11
  90. package/src/gorgon/rules/profanity.js +0 -10
  91. package/src/gorgon/rules/table-missing-cells.js +0 -20
  92. package/src/gorgon/rules/unbalanced-code-delimiters.js +0 -14
  93. package/src/gorgon/rules/unescaped-dollar.js +0 -10
  94. package/src/gorgon/rules/widget-in-table.js +0 -10
  95. package/src/gorgon/selector.js +0 -506
  96. package/src/gorgon/tree-transformer.js +0 -588
  97. package/src/pure-markdown.js +0 -347
package/src/README.md DELETED
@@ -1,35 +0,0 @@
1
- # Perseus
2
-
3
- <p align="center"><img src="logo.png" alt="perseus logo" width="150px"/></p>
4
-
5
- <p align="center">Perseus Exercise Renderer</p>
6
-
7
- Perseus is Khan Academy's exercise system. This repo contains the code needed to take a problem in the perseus format and present it, allow interaction, and grade the result of a learner's work.
8
-
9
- <p align="center"><img src="sample.png" alt="sample of perseus in use" height="150px"/></p>
10
-
11
- This repo is a constellation of sub-repos for showing exercise content. Please see individual projects in in the `packages/` folder for more information about each sub-project.
12
-
13
- ## Getting started
14
-
15
- ### Prerequisites
16
-
17
- - [Node.JS v12](https://nodejs.org/download/release/v10.18.1/)
18
- - [Yarn](https://yarnpkg.com/lang/en/docs/install/)
19
-
20
- ### Installation
21
-
22
- To install perseus, you need to run the following commands:
23
-
24
- #### `yarn install`
25
-
26
- Installs project dependencies
27
-
28
- ## Contributing
29
-
30
- See [CONTRIBUTING.md](./CONTRIBUTING.md) for a walkthrough of how some
31
- of the Perseus code works and how to extend it.
32
-
33
- ## License
34
-
35
- [MIT License](http://opensource.org/licenses/MIT)
@@ -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
- });