@khanacademy/perseus 0.2.0 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/es/index.js +2 -10
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +2 -10
- package/dist/index.js.map +1 -1
- package/package.json +26 -8
- package/src/README.md +33 -5
- package/src/index.js +1 -0
- package/src/jipt-paragraphs.js +6 -6
- package/src/mixins/provide-keypad.jsx +3 -1
- package/src/multi-items/multi-renderer.jsx +1 -0
- package/src/perseus-markdown.jsx +5 -7
- package/src/pure-markdown.js +2 -1
- package/src/renderer.jsx +1 -0
- package/src/types.js +1 -1
- package/src/util/graphie.js +1 -0
- package/src/util/interactive.js +1 -0
- package/src/widgets/__stories__/unit.stories.jsx +45 -0
- package/src/widgets/__stories__/video-transcript-link.stories.jsx +24 -0
- package/src/widgets/__tests__/renderQuestion.jsx +1 -0
- package/src/widgets/passage/passage-markdown.jsx +1 -1
- package/src/widgets/unit.jsx +2 -1
- package/README.md +0 -3
package/package.json
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
{
|
|
2
|
+
"name": "@khanacademy/perseus",
|
|
3
|
+
"description": "Core Perseus API (includes renderers and widgets)",
|
|
4
|
+
"author": "Khan Academy",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"version": "0.2.3",
|
|
2
7
|
"publishConfig": {
|
|
3
8
|
"access": "public"
|
|
4
9
|
},
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/Khan/perseus.git"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/Khan/perseus/issues"
|
|
16
|
+
},
|
|
8
17
|
"module": "dist/es/index.js",
|
|
9
18
|
"main": "dist/index.js",
|
|
10
19
|
"source": "src/index.js",
|
|
@@ -13,21 +22,25 @@
|
|
|
13
22
|
},
|
|
14
23
|
"dependencies": {
|
|
15
24
|
"@khanacademy/kmath": "0.0.5",
|
|
16
|
-
"@khanacademy/math-input": "^0.5.
|
|
25
|
+
"@khanacademy/math-input": "^0.5.1",
|
|
17
26
|
"@khanacademy/kas": "^0.2.3",
|
|
18
|
-
"
|
|
19
|
-
"
|
|
27
|
+
"@khanacademy/simple-markdown": "^0.8.1",
|
|
28
|
+
"mathquill": "git+https://git@github.com/Khan/mathquill.git#a9ae54e057c5c1acc8244a5627acbff29901d992"
|
|
20
29
|
},
|
|
21
30
|
"devDependencies": {
|
|
31
|
+
"@khanacademy/wonder-blocks-button": "2.11.5",
|
|
22
32
|
"@khanacademy/wonder-blocks-color": "^1.1.20",
|
|
23
33
|
"@khanacademy/wonder-blocks-core": "^4.3.0",
|
|
24
34
|
"@khanacademy/wonder-blocks-data": "^7.0.0",
|
|
25
35
|
"@khanacademy/wonder-blocks-dropdown": "^2.6.7",
|
|
26
36
|
"@khanacademy/wonder-blocks-i18n": "^1.2.3",
|
|
37
|
+
"@khanacademy/wonder-blocks-layout": "1.4.9",
|
|
27
38
|
"@khanacademy/wonder-blocks-link": "^3.8.5",
|
|
28
39
|
"@khanacademy/wonder-blocks-popover": "^1.1.10",
|
|
40
|
+
"@khanacademy/wonder-blocks-progress-spinner": "1.1.31",
|
|
29
41
|
"@khanacademy/wonder-blocks-spacing": "^3.0.5",
|
|
30
42
|
"@khanacademy/wonder-blocks-tooltip": "^1.3.10",
|
|
43
|
+
"@khanacademy/wonder-blocks-typography": "1.1.31",
|
|
31
44
|
"@khanacademy/wonder-stuff-core": "^0.1.2",
|
|
32
45
|
"aphrodite": "^1.2.5",
|
|
33
46
|
"classnames": "^1.1.4",
|
|
@@ -36,6 +49,7 @@
|
|
|
36
49
|
"eslint-plugin-import": "^2.26.0",
|
|
37
50
|
"intersection-observer": "^0.12.0",
|
|
38
51
|
"jquery": "^2.1.1",
|
|
52
|
+
"lodash.debounce": "^4.0.8",
|
|
39
53
|
"perseus-build-settings": "^0.0.1",
|
|
40
54
|
"prop-types": "^15.6.1",
|
|
41
55
|
"react": "16.14.0",
|
|
@@ -43,26 +57,30 @@
|
|
|
43
57
|
"underscore": "^1.4.4"
|
|
44
58
|
},
|
|
45
59
|
"peerDependencies": {
|
|
60
|
+
"@khanacademy/wonder-blocks-button": "2.11.5",
|
|
46
61
|
"@khanacademy/wonder-blocks-color": "^1.1.20",
|
|
47
62
|
"@khanacademy/wonder-blocks-core": "^4.3.0",
|
|
48
63
|
"@khanacademy/wonder-blocks-data": "^7.0.0",
|
|
49
64
|
"@khanacademy/wonder-blocks-dropdown": "^2.6.7",
|
|
50
65
|
"@khanacademy/wonder-blocks-i18n": "^1.2.3",
|
|
66
|
+
"@khanacademy/wonder-blocks-layout": "1.4.9",
|
|
51
67
|
"@khanacademy/wonder-blocks-link": "^3.8.5",
|
|
52
68
|
"@khanacademy/wonder-blocks-popover": "^1.1.10",
|
|
69
|
+
"@khanacademy/wonder-blocks-progress-spinner": "1.1.31",
|
|
53
70
|
"@khanacademy/wonder-blocks-spacing": "^3.0.5",
|
|
54
71
|
"@khanacademy/wonder-blocks-tooltip": "^1.3.10",
|
|
72
|
+
"@khanacademy/wonder-blocks-typography": "1.1.31",
|
|
55
73
|
"@khanacademy/wonder-stuff-core": "^0.1.2",
|
|
56
74
|
"aphrodite": "^1.2.5",
|
|
57
75
|
"classnames": "^1.1.4",
|
|
58
76
|
"create-react-class": "^15.6.3",
|
|
59
77
|
"intersection-observer": "^0.12.0",
|
|
60
78
|
"jquery": "^2.1.1",
|
|
79
|
+
"lodash.debounce": "^4.0.8",
|
|
61
80
|
"prop-types": "^15.6.1",
|
|
62
81
|
"react": "16.14.0",
|
|
63
82
|
"react-dom": "16.14.0",
|
|
64
83
|
"underscore": "^1.4.4"
|
|
65
84
|
},
|
|
66
|
-
"
|
|
67
|
-
"license": "MIT"
|
|
85
|
+
"keywords": []
|
|
68
86
|
}
|
package/src/README.md
CHANGED
|
@@ -1,7 +1,35 @@
|
|
|
1
|
-
|
|
1
|
+
# Perseus
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Perseus packages.
|
|
3
|
+
<p align="center"><img src="logo.png" alt="perseus logo" width="150px"/></p>
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
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)
|
package/src/index.js
CHANGED
package/src/jipt-paragraphs.js
CHANGED
|
@@ -3,21 +3,21 @@
|
|
|
3
3
|
* Paragraph parsing/splitting for article jipt i18n
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import SimpleMarkdown from "simple-markdown";
|
|
6
|
+
import SimpleMarkdown from "@khanacademy/simple-markdown";
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
import type {ParserRules} from "@khanacademy/simple-markdown";
|
|
9
|
+
|
|
10
|
+
const arrayRules: ParserRules = {
|
|
9
11
|
fence: {
|
|
10
|
-
// $FlowFixMe[prop-missing]
|
|
11
|
-
// $FlowFixMe[incompatible-use]
|
|
12
12
|
match: SimpleMarkdown.defaultRules.fence.match,
|
|
13
13
|
order: 1,
|
|
14
|
+
// $FlowFixMe[incompatible-type]
|
|
14
15
|
parse: (capture, state, parse) => capture[3],
|
|
15
16
|
},
|
|
16
17
|
paragraph: {
|
|
17
|
-
// $FlowFixMe[prop-missing]
|
|
18
|
-
// $FlowFixMe[incompatible-use]
|
|
19
18
|
match: SimpleMarkdown.defaultRules.paragraph.match,
|
|
20
19
|
order: 2,
|
|
20
|
+
// $FlowFixMe[incompatible-type]
|
|
21
21
|
parse: (capture, state, parse) => capture[1],
|
|
22
22
|
},
|
|
23
23
|
};
|
|
@@ -16,12 +16,14 @@ import PropTypes from "prop-types";
|
|
|
16
16
|
import * as React from "react";
|
|
17
17
|
import ReactDOM from "react-dom";
|
|
18
18
|
|
|
19
|
+
import type {CSSProperties} from "aphrodite";
|
|
20
|
+
|
|
19
21
|
export type KeypadProps = {|
|
|
20
22
|
// An Aphrodite style object, to be applied to the keypad container.
|
|
21
23
|
// Note that, given our awkward structure of injecting the keypad, this
|
|
22
24
|
// style won't be applied or updated dynamically. Rather, it will only
|
|
23
25
|
// be applied in `componentDidMount`.
|
|
24
|
-
keypadStyle?:
|
|
26
|
+
keypadStyle?: CSSProperties,
|
|
25
27
|
|};
|
|
26
28
|
|
|
27
29
|
export type KeypadApiOptions = {|
|
package/src/perseus-markdown.jsx
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
/* eslint-disable no-useless-escape */
|
|
1
|
+
/* eslint-disable no-useless-escape, no-prototype-builtins */
|
|
2
2
|
// @flow
|
|
3
3
|
// TODO(FEI-4465): move this into it's own package called perseus-markdown
|
|
4
|
+
import SimpleMarkdown from "@khanacademy/simple-markdown";
|
|
4
5
|
import * as i18n from "@khanacademy/wonder-blocks-i18n";
|
|
5
6
|
import * as React from "react";
|
|
6
|
-
import SimpleMarkdown from "simple-markdown";
|
|
7
7
|
import _ from "underscore";
|
|
8
8
|
|
|
9
9
|
import Lint from "./components/lint.jsx";
|
|
@@ -320,6 +320,7 @@ const inlineNodeTypes = {
|
|
|
320
320
|
};
|
|
321
321
|
|
|
322
322
|
// $FlowFixMe[prop-missing]
|
|
323
|
+
// $FlowFixMe[incompatible-call]
|
|
323
324
|
const builtParser = SimpleMarkdown.parserFor(rules);
|
|
324
325
|
const parse = (source: string, state: $FlowFixMe): $FlowFixMe => {
|
|
325
326
|
const paragraphedSource = source + "\n\n";
|
|
@@ -421,15 +422,12 @@ export default {
|
|
|
421
422
|
traverseContent: traverseContent,
|
|
422
423
|
parse: parse,
|
|
423
424
|
parseInline: inlineParser,
|
|
424
|
-
// $FlowFixMe[prop-missing]
|
|
425
425
|
reactFor: SimpleMarkdown.reactFor,
|
|
426
|
-
// $FlowFixMe[
|
|
426
|
+
// $FlowFixMe[incompatible-use]
|
|
427
427
|
ruleOutput: (SimpleMarkdown.ruleOutput(rules, "react"): $FlowFixMe),
|
|
428
|
-
// $FlowFixMe[prop-missing]
|
|
429
428
|
basicOutput: (SimpleMarkdown.reactFor(
|
|
430
|
-
// $FlowFixMe[
|
|
429
|
+
// $FlowFixMe[incompatible-use]
|
|
431
430
|
SimpleMarkdown.ruleOutput(rules, "react"),
|
|
432
431
|
): $FlowFixMe),
|
|
433
|
-
// $FlowFixMe[prop-missing]
|
|
434
432
|
sanitizeUrl: SimpleMarkdown.sanitizeUrl,
|
|
435
433
|
};
|
package/src/pure-markdown.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Contains markdown related functions in pure javascript,
|
|
4
4
|
* extracted from perseus-markdown.jsx
|
|
5
5
|
*/
|
|
6
|
-
import SimpleMarkdown from "simple-markdown";
|
|
6
|
+
import SimpleMarkdown from "@khanacademy/simple-markdown";
|
|
7
7
|
|
|
8
8
|
import Util from "./util.js";
|
|
9
9
|
|
|
@@ -334,6 +334,7 @@ export const pureMarkdownRules = {
|
|
|
334
334
|
};
|
|
335
335
|
|
|
336
336
|
// $FlowFixMe[prop-missing]
|
|
337
|
+
// $FlowFixMe[incompatible-call]
|
|
337
338
|
const builtParser = SimpleMarkdown.parserFor(pureMarkdownRules);
|
|
338
339
|
|
|
339
340
|
export const parse = (source: string, state: $FlowFixMe): $FlowFixMe => {
|
package/src/renderer.jsx
CHANGED
|
@@ -1275,6 +1275,7 @@ class Renderer extends React.Component<Props, State> {
|
|
|
1275
1275
|
{({setAssetStatus}) => (
|
|
1276
1276
|
<SvgImage
|
|
1277
1277
|
setAssetStatus={setAssetStatus}
|
|
1278
|
+
/* $FlowFixMe[incompatible-type]: sanitizeUrl() can return null */
|
|
1278
1279
|
src={PerseusMarkdown.sanitizeUrl(node.target)}
|
|
1279
1280
|
alt={node.alt}
|
|
1280
1281
|
title={node.title}
|
package/src/types.js
CHANGED
package/src/util/graphie.js
CHANGED
package/src/util/interactive.js
CHANGED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
|
|
4
|
+
import {ApiOptions} from "../../perseus-api.jsx";
|
|
5
|
+
import {OldUnitInput} from "../unit.jsx";
|
|
6
|
+
|
|
7
|
+
type StoryArgs = {||};
|
|
8
|
+
|
|
9
|
+
type Story = {|
|
|
10
|
+
title: string,
|
|
11
|
+
|};
|
|
12
|
+
|
|
13
|
+
export default ({
|
|
14
|
+
title: "Perseus/Widgets/Unit",
|
|
15
|
+
}: Story);
|
|
16
|
+
|
|
17
|
+
export const StaticRender = (args: StoryArgs): React.Node => {
|
|
18
|
+
return (
|
|
19
|
+
<OldUnitInput
|
|
20
|
+
apiOptions={{
|
|
21
|
+
...ApiOptions.defaults,
|
|
22
|
+
staticRender: true,
|
|
23
|
+
}}
|
|
24
|
+
value="2 tbsp"
|
|
25
|
+
onFocus={() => {}}
|
|
26
|
+
onBlur={() => {}}
|
|
27
|
+
onChange={({value}) => {}}
|
|
28
|
+
/>
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const NonStaticRender = (args: StoryArgs): React.Node => {
|
|
33
|
+
return (
|
|
34
|
+
<OldUnitInput
|
|
35
|
+
apiOptions={{
|
|
36
|
+
...ApiOptions.defaults,
|
|
37
|
+
staticRender: false,
|
|
38
|
+
}}
|
|
39
|
+
value="2 tbsp"
|
|
40
|
+
onFocus={() => {}}
|
|
41
|
+
onBlur={() => {}}
|
|
42
|
+
onChange={({value}) => {}}
|
|
43
|
+
/>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
|
|
4
|
+
import VideoTranscriptLink from "../video-transcript-link.jsx";
|
|
5
|
+
|
|
6
|
+
type StoryArgs = {||};
|
|
7
|
+
|
|
8
|
+
type Story = {|
|
|
9
|
+
title: string,
|
|
10
|
+
|};
|
|
11
|
+
|
|
12
|
+
export default ({
|
|
13
|
+
title: "Perseus/Components/Video Transcript Link",
|
|
14
|
+
}: Story);
|
|
15
|
+
|
|
16
|
+
export const YoutubeVideoLink = (args: StoryArgs): React.Node => {
|
|
17
|
+
return (
|
|
18
|
+
<VideoTranscriptLink location="https://www.youtube.com/watch?v=YoutubeId" />
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const SlugVideoLink = (args: StoryArgs): React.Node => {
|
|
23
|
+
return <VideoTranscriptLink location="slug-video-id" />;
|
|
24
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/* eslint-disable react/sort-comp */
|
|
2
2
|
// @flow
|
|
3
|
+
import SimpleMarkdown from "@khanacademy/simple-markdown";
|
|
3
4
|
import * as i18n from "@khanacademy/wonder-blocks-i18n";
|
|
4
5
|
import PropTypes from "prop-types";
|
|
5
6
|
import * as React from "react";
|
|
6
|
-
import SimpleMarkdown from "simple-markdown";
|
|
7
7
|
import _ from "underscore";
|
|
8
8
|
|
|
9
9
|
const START_REF_PREFIX = "start-ref-";
|
package/src/widgets/unit.jsx
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
// value?
|
|
7
7
|
import * as KAS from "@khanacademy/kas";
|
|
8
8
|
import * as i18n from "@khanacademy/wonder-blocks-i18n";
|
|
9
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
9
10
|
import lens from "hubble";
|
|
10
11
|
import $ from "jquery";
|
|
11
12
|
import * as React from "react";
|
|
@@ -81,7 +82,7 @@ type DefaultProps = {|
|
|
|
81
82
|
* shows and hides an error buddy. The error message is only shown after a
|
|
82
83
|
* rolling two second delay, but hidden immediately on further typing.
|
|
83
84
|
*/
|
|
84
|
-
class OldUnitInput extends React.Component<Props> {
|
|
85
|
+
export class OldUnitInput extends React.Component<Props> {
|
|
85
86
|
_errorTimeout: ?TimeoutID;
|
|
86
87
|
|
|
87
88
|
static defaultProps: DefaultProps = {
|
package/README.md
DELETED