@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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Core Perseus API (includes renderers and widgets)",
4
4
  "author": "Khan Academy",
5
5
  "license": "MIT",
6
- "version": "0.2.7",
6
+ "version": "0.3.1",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
@@ -22,8 +22,10 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "@khanacademy/kmath": "^0.0.5",
25
- "@khanacademy/math-input": "^0.5.2",
26
25
  "@khanacademy/kas": "^0.2.4",
26
+ "@khanacademy/math-input": "^0.5.2",
27
+ "@khanacademy/perseus-linter": "^0.2.0",
28
+ "@khanacademy/pure-markdown": "^0.1.0",
27
29
  "@khanacademy/simple-markdown": "^0.8.3",
28
30
  "mathquill": "git+https://git@github.com/Khan/mathquill.git#a9ae54e057c5c1acc8244a5627acbff29901d992"
29
31
  },
@@ -1,6 +1,6 @@
1
1
  // @flow
2
- import Gorgon from "../gorgon/gorgon.js"; // The linter engine
3
- import {linterContextDefault} from "../gorgon/proptypes.js";
2
+ import * as PerseusLinter from "@khanacademy/perseus-linter";
3
+
4
4
  import PerseusMarkdown from "../perseus-markdown.jsx";
5
5
 
6
6
  const {parse, basicOutput, characterCount} = PerseusMarkdown;
@@ -565,14 +565,14 @@ describe("perseus markdown", () => {
565
565
  "data 4 | $data 5 | data 6\n" +
566
566
  "data 7 | data 8 | data 9";
567
567
  const context = {
568
- ...linterContextDefault,
568
+ ...PerseusLinter.linterContextDefault,
569
569
  content,
570
570
  widgets: {},
571
571
  };
572
572
 
573
573
  // Act
574
574
  const parsedWithLint = parse(content);
575
- Gorgon.runLinter(parsedWithLint, context, true);
575
+ PerseusLinter.runLinter(parsedWithLint, context, true);
576
576
 
577
577
  // Assert
578
578
  expect(parsedWithLint).toMatchSnapshot();
@@ -650,14 +650,14 @@ describe("perseus markdown", () => {
650
650
  "data 4 | $data 5 | data 6\n" +
651
651
  "data 7 | data 8 | data 9";
652
652
  const context = {
653
- ...linterContextDefault,
653
+ ...PerseusLinter.linterContextDefault,
654
654
  content,
655
655
  widgets: {},
656
656
  };
657
657
 
658
658
  // Act
659
659
  const parsedWithLint = parse(content);
660
- Gorgon.runLinter(parsedWithLint, context, true);
660
+ PerseusLinter.runLinter(parsedWithLint, context, true);
661
661
 
662
662
  const output = PerseusMarkdown.basicOutput(parsedWithLint);
663
663
 
@@ -31,15 +31,15 @@ import type {
31
31
  PerseusInputNumberWidgetOptions,
32
32
  } from "../perseus-types.js";
33
33
 
34
- // NOTE(jeremy): We can't use an automatic mock for not-gorgon, because one of
35
- // it's "instance" methods is created using `debounce` and Jest doesn't provide
36
- // a mocked instance method for it (I suspect that Jest doesn't see that
37
- // symbol as an instance method).
34
+ // NOTE(jeremy): We can't use an automatic mock for the translation linter,
35
+ // because one of it's "instance" methods is created using `debounce` and Jest
36
+ // doesn't provide a mocked instance method for it (I suspect that Jest doesn't
37
+ // see that symbol as an instance method).
38
38
  const mockRunLinter = jest.fn();
39
39
  const mockApplyLintErrors = jest.fn();
40
- jest.mock("../not-gorgon.js", () => {
41
- // We mock the NotGorgon constructor here setting things up so we can
42
- // spy/verify calls to instances of NotGorgon
40
+ jest.mock("../translation-linter.js", () => {
41
+ // We mock the TranslationLinter constructor here setting things up so we
42
+ // can spy/verify calls to instances of TranslationLinter
43
43
  return function () {
44
44
  return {
45
45
  runLinter: mockRunLinter,
@@ -106,7 +106,7 @@ describe("renderer", () => {
106
106
  });
107
107
  });
108
108
 
109
- describe("linting (NotGorgon)", () => {
109
+ describe("linting (TranslationLinter)", () => {
110
110
  const extraProps = {
111
111
  linterContext: {
112
112
  contentType: "exercise",
@@ -165,7 +165,7 @@ describe("renderer", () => {
165
165
 
166
166
  // Assert
167
167
  expect(renderer.state.jiptContent).toBeNull();
168
- expect(renderer.state.notGorgonLintErrors).toHaveLength(0);
168
+ expect(renderer.state.translationLintErrors).toHaveLength(0);
169
169
  expect(renderer.state.lastUsedWidgetId).toBeNull();
170
170
 
171
171
  expect(renderer.state.widgetInfo).toStrictEqual(question1.widgets);
@@ -5,12 +5,11 @@
5
5
  * composed of multiple (Renderer) sections concatenated together.
6
6
  */
7
7
 
8
+ import * as PerseusLinter from "@khanacademy/perseus-linter";
8
9
  import classNames from "classnames";
9
10
  import PropTypes from "prop-types";
10
11
  import * as React from "react";
11
12
 
12
- import Gorgon from "./gorgon/gorgon.js";
13
- import {linterContextProps, linterContextDefault} from "./gorgon/proptypes.js";
14
13
  import ProvideKeypad from "./mixins/provide-keypad.jsx";
15
14
  import {ClassNames as ApiClassNames, ApiOptions} from "./perseus-api.jsx";
16
15
  import Renderer from "./renderer.jsx";
@@ -38,14 +37,14 @@ class ArticleRenderer extends React.Component<$FlowFixMe, $FlowFixMe> {
38
37
 
39
38
  // Whether to use the new Bibliotron styles for articles
40
39
  useNewStyles: PropTypes.bool,
41
- linterContext: linterContextProps,
40
+ linterContext: PerseusLinter.linterContextProps,
42
41
  legacyPerseusLint: PropTypes.arrayOf(PropTypes.string),
43
42
  };
44
43
 
45
44
  static defaultProps: $FlowFixMe = {
46
45
  apiOptions: {},
47
46
  useNewStyles: false,
48
- linterContext: linterContextDefault,
47
+ linterContext: PerseusLinter.linterContextDefault,
49
48
  };
50
49
 
51
50
  constructor(props: $FlowFixMe) {
@@ -198,7 +197,7 @@ class ArticleRenderer extends React.Component<$FlowFixMe, $FlowFixMe> {
198
197
  );
199
198
  },
200
199
  }}
201
- linterContext={Gorgon.pushContextStack(
200
+ linterContext={PerseusLinter.pushContextStack(
202
201
  this.props.linterContext,
203
202
  "article",
204
203
  )}
@@ -1,11 +1,10 @@
1
1
  /* eslint-disable react/sort-comp */
2
2
  // @flow
3
+ import * as PerseusLinter from "@khanacademy/perseus-linter";
3
4
  import PropTypes from "prop-types";
4
5
  import * as React from "react";
5
6
  import _ from "underscore";
6
7
 
7
- import Gorgon from "../gorgon/gorgon.js";
8
- import {linterContextProps, linterContextDefault} from "../gorgon/proptypes.js";
9
8
  import {ClassNames as ApiClassNames} from "../perseus-api.jsx";
10
9
  import Renderer from "../renderer.jsx";
11
10
  import Util from "../util.js";
@@ -38,7 +37,7 @@ class InputWithExamples extends React.Component<$FlowFixMe, $FlowFixMe> {
38
37
 
39
38
  // A unique string identifying this InputWithExamples
40
39
  id: PropTypes.string.isRequired,
41
- linterContext: linterContextProps,
40
+ linterContext: PerseusLinter.linterContextProps,
42
41
  };
43
42
 
44
43
  static defaultProps: $FlowFixMe = {
@@ -47,7 +46,7 @@ class InputWithExamples extends React.Component<$FlowFixMe, $FlowFixMe> {
47
46
  onFocus: function () {},
48
47
  onBlur: function () {},
49
48
  disabled: false,
50
- linterContext: linterContextDefault,
49
+ linterContext: PerseusLinter.linterContextDefault,
51
50
  };
52
51
 
53
52
  state: $FlowFixMe = {
@@ -179,7 +178,7 @@ class InputWithExamples extends React.Component<$FlowFixMe, $FlowFixMe> {
179
178
  <div id={this._getUniqueId()}>
180
179
  <Renderer
181
180
  content={examplesContent}
182
- linterContext={Gorgon.pushContextStack(
181
+ linterContext={PerseusLinter.pushContextStack(
183
182
  this.props.linterContext,
184
183
  "input-with-examples",
185
184
  )}
@@ -1,7 +1,8 @@
1
1
  // @flow
2
2
  /**
3
3
  * This component renders "lint" nodes in a markdown parse tree. Lint nodes
4
- * are inserted into the tree by the Gorgon linter (see src/gorgon/gorgon.js).
4
+ * are inserted into the tree by the Perseus linter (see
5
+ * perseus-linter/src/index).
5
6
  *
6
7
  * This component serves multiple purposes
7
8
  *
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable @babel/no-invalid-this, react/forbid-prop-types, react/no-unsafe, react/sort-comp */
2
2
  // @flow
3
+ import * as PerseusLinter from "@khanacademy/perseus-linter";
3
4
  import {CircularSpinner} from "@khanacademy/wonder-blocks-progress-spinner";
4
5
  import {StyleSheet, css} from "aphrodite";
5
6
  import $ from "jquery";
@@ -9,8 +10,6 @@ import ReactDOM from "react-dom";
9
10
  import _ from "underscore";
10
11
 
11
12
  import {getDependencies} from "../dependencies.js";
12
- import Gorgon from "../gorgon/gorgon.js";
13
- import {linterContextProps, linterContextDefault} from "../gorgon/proptypes.js";
14
13
  import {ClassNames as ApiClassNames} from "../perseus-api.jsx";
15
14
  import Renderer from "../renderer.jsx";
16
15
  import Util from "../util.js";
@@ -96,13 +95,13 @@ class Draggable extends React.Component<DraggableProps, DraggableState> {
96
95
  onMouseUp: PropTypes.func.isRequired,
97
96
  onRender: PropTypes.func.isRequired,
98
97
  type: PropTypes.oneOf([STATIC, DRAGGING, ANIMATING, DISABLED]),
99
- linterContext: linterContextProps,
98
+ linterContext: PerseusLinter.linterContextProps,
100
99
  };
101
100
 
102
101
  static defaultProps = {
103
102
  includePadding: true,
104
103
  type: STATIC,
105
- linterContext: linterContextDefault,
104
+ linterContext: PerseusLinter.linterContextDefault,
106
105
  };
107
106
 
108
107
  state: DraggableState = {
@@ -215,7 +214,7 @@ class Draggable extends React.Component<DraggableProps, DraggableState> {
215
214
  >
216
215
  <Renderer
217
216
  content={this.props.content}
218
- linterContext={Gorgon.pushContextStack(
217
+ linterContext={PerseusLinter.pushContextStack(
219
218
  this.props.linterContext,
220
219
  "draggable",
221
220
  )}
@@ -423,7 +422,7 @@ class Sortable extends React.Component<SortableProps, SortableState> {
423
422
  onMeasure: function () {},
424
423
  margin: 5,
425
424
  onChange: function () {},
426
- linterContext: linterContextDefault,
425
+ linterContext: PerseusLinter.linterContextDefault,
427
426
  waitForKatexLoad: true,
428
427
  };
429
428
 
@@ -619,7 +618,7 @@ class Sortable extends React.Component<SortableProps, SortableState> {
619
618
  includePadding={this.props.padding}
620
619
  margin={isLast && isStatic ? 0 : margin}
621
620
  endPosition={item.endPosition}
622
- linterContext={Gorgon.pushContextStack(
621
+ linterContext={PerseusLinter.pushContextStack(
623
622
  this.props.linterContext,
624
623
  "sortable",
625
624
  )}
@@ -1,11 +1,10 @@
1
1
  // @flow
2
+ import * as PerseusLinter from "@khanacademy/perseus-linter";
2
3
  import * as i18n from "@khanacademy/wonder-blocks-i18n";
3
4
  import {StyleSheet, css} from "aphrodite";
4
5
  import classnames from "classnames";
5
6
  import * as React from "react";
6
7
 
7
- import Gorgon from "./gorgon/gorgon.js";
8
- import {linterContextDefault} from "./gorgon/proptypes.js";
9
8
  import Renderer from "./renderer.jsx";
10
9
  import {
11
10
  baseUnitPx,
@@ -36,7 +35,7 @@ type DefaultProps = {|
36
35
  /* Renders just a hint preview */
37
36
  class HintRenderer extends React.Component<Props> {
38
37
  static defaultProps: DefaultProps = {
39
- linterContext: linterContextDefault,
38
+ linterContext: PerseusLinter.linterContextDefault,
40
39
  };
41
40
 
42
41
  getSerializedState: () => void = () => {
@@ -116,7 +115,7 @@ class HintRenderer extends React.Component<Props> {
116
115
  images={hint.images}
117
116
  apiOptions={rendererApiOptions}
118
117
  findExternalWidgets={this.props.findExternalWidgets}
119
- linterContext={Gorgon.pushContextStack(
118
+ linterContext={PerseusLinter.pushContextStack(
120
119
  this.props.linterContext,
121
120
  "hint",
122
121
  )}
@@ -1,4 +1,5 @@
1
1
  // @flow
2
+ import * as PerseusLinter from "@khanacademy/perseus-linter";
2
3
  import * as i18n from "@khanacademy/wonder-blocks-i18n";
3
4
  import {StyleSheet, css} from "aphrodite";
4
5
  import classnames from "classnames";
@@ -6,8 +7,6 @@ import * as React from "react";
6
7
  import ReactDOM from "react-dom";
7
8
  import _ from "underscore";
8
9
 
9
- import Gorgon from "./gorgon/gorgon.js";
10
- import {linterContextDefault} from "./gorgon/proptypes.js";
11
10
  import HintRenderer from "./hint-renderer.jsx";
12
11
  import {ApiOptions} from "./perseus-api.jsx";
13
12
  import typeof Renderer from "./renderer.jsx";
@@ -43,7 +42,7 @@ type State = {|
43
42
  // eslint-disable-next-line react/no-unsafe
44
43
  class HintsRenderer extends React.Component<Props, State> {
45
44
  static defaultProps: DefaultProps = {
46
- linterContext: linterContextDefault,
45
+ linterContext: PerseusLinter.linterContextDefault,
47
46
  };
48
47
 
49
48
  // The isFinalHelpPage property determines if the user has requested help
@@ -181,7 +180,7 @@ class HintsRenderer extends React.Component<Props, State> {
181
180
  key={"hintRenderer" + i}
182
181
  apiOptions={apiOptions}
183
182
  findExternalWidgets={this.props.findExternalWidgets}
184
- linterContext={Gorgon.pushContextStack(
183
+ linterContext={PerseusLinter.pushContextStack(
185
184
  this.props.linterContext,
186
185
  "hints[" + i + "]",
187
186
  )}
package/src/index.js CHANGED
@@ -115,6 +115,7 @@ export type {
115
115
  RendererInterface,
116
116
  Version,
117
117
  VideoData,
118
+ VideoKind,
118
119
  WidgetDict,
119
120
  WidgetExports,
120
121
  WidgetInfo,
@@ -1,12 +1,11 @@
1
1
  /* eslint-disable react/no-unsafe */
2
2
  // @flow
3
+ import * as PerseusLinter from "@khanacademy/perseus-linter";
3
4
  import $ from "jquery";
4
5
  import * as React from "react";
5
6
  import * as ReactDOM from "react-dom";
6
7
  import _ from "underscore";
7
8
 
8
- import Gorgon from "./gorgon/gorgon.js";
9
- import {linterContextDefault} from "./gorgon/proptypes.js";
10
9
  import HintsRenderer from "./hints-renderer.jsx";
11
10
  import Objective from "./interactive2/objective_.js";
12
11
  import ProvideKeypad from "./mixins/provide-keypad.jsx";
@@ -88,7 +87,7 @@ class ItemRenderer extends React.Component<Props, State> {
88
87
  initialHintsVisible: 0,
89
88
  workAreaSelector: "#workarea",
90
89
  reviewMode: false,
91
- linterContext: linterContextDefault,
90
+ linterContext: PerseusLinter.linterContextDefault,
92
91
  };
93
92
 
94
93
  constructor(props: Props) {
@@ -209,7 +208,7 @@ class ItemRenderer extends React.Component<Props, State> {
209
208
  questionCompleted={this.state.questionCompleted}
210
209
  reviewMode={this.props.reviewMode}
211
210
  savedState={this.props.savedState}
212
- linterContext={Gorgon.pushContextStack(
211
+ linterContext={PerseusLinter.pushContextStack(
213
212
  this.props.linterContext,
214
213
  "question",
215
214
  )}
@@ -227,7 +226,7 @@ class ItemRenderer extends React.Component<Props, State> {
227
226
  hints={this.props.item.hints}
228
227
  hintsVisible={this.state.hintsVisible}
229
228
  apiOptions={apiOptions}
230
- linterContext={Gorgon.pushContextStack(
229
+ linterContext={PerseusLinter.pushContextStack(
231
230
  this.props.linterContext,
232
231
  "hints",
233
232
  )}
@@ -21,6 +21,7 @@
21
21
  //
22
22
  // The current version exposes the following virtual events to jQuery bind methods:
23
23
  // "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel"
24
+ import $ from "jquery";
24
25
 
25
26
  (function ($, window, document, undefined) {
26
27
  if (typeof $ === "undefined") {
@@ -542,4 +543,4 @@
542
543
  true,
543
544
  );
544
545
  }
545
- })(window.jQuery, window, document);
546
+ })($, window, document);
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable no-useless-escape, no-prototype-builtins */
2
2
  // @flow
3
- // TODO(FEI-4465): move this into it's own package called perseus-markdown
3
+ import {pureMarkdownRules} from "@khanacademy/pure-markdown";
4
4
  import SimpleMarkdown from "@khanacademy/simple-markdown";
5
5
  import * as i18n from "@khanacademy/wonder-blocks-i18n";
6
6
  import * as React from "react";
@@ -8,7 +8,6 @@ import _ from "underscore";
8
8
 
9
9
  import Lint from "./components/lint.jsx";
10
10
  import {getDependencies} from "./dependencies.js";
11
- import {pureMarkdownRules} from "./pure-markdown.js";
12
11
 
13
12
  const rules = {
14
13
  ...pureMarkdownRules,
@@ -111,7 +110,8 @@ const rules = {
111
110
  } else if (node.table.type === "lint") {
112
111
  // The `table` in this node is actually a `lint` node,
113
112
  // not the expected `table` node. This is due to the linter
114
- // implementation "reparenting" the `table` node, see gorgon.js
113
+ // implementation "reparenting" the `table` node, see
114
+ // perseus-linter/src/index.js
115
115
  if (node.table.content?.type === "table") {
116
116
  // And the `content` of this lint node is the `table` node
117
117
  // which we actually want to render. Thus, we perform
package/src/renderer.jsx CHANGED
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable react/no-unsafe */
2
2
  // @flow
3
+ import * as PerseusLinter from "@khanacademy/perseus-linter";
3
4
  import classNames from "classnames";
4
5
  import $ from "jquery";
5
6
  import * as React from "react";
@@ -13,17 +14,15 @@ import ZoomableTeX from "./components/zoomable-tex.jsx";
13
14
  import Zoomable from "./components/zoomable.jsx";
14
15
  import {getDependencies} from "./dependencies.js";
15
16
  import ErrorBoundary from "./error-boundary.jsx";
16
- import Gorgon from "./gorgon/gorgon.js"; // The linter engine
17
- import {linterContextDefault} from "./gorgon/proptypes.js";
18
17
  import InteractionTracker from "./interaction-tracker.js";
19
18
  import Objective from "./interactive2/objective_.js";
20
19
  import JiptParagraphs from "./jipt-paragraphs.js";
21
20
  import {Errors, Log} from "./logging/log.js";
22
- import NotGorgon from "./not-gorgon.js"; // The i18n linter
23
21
  import {ClassNames as ApiClassNames, ApiOptions} from "./perseus-api.jsx";
24
22
  import {PerseusError} from "./perseus-error.js";
25
23
  import PerseusMarkdown from "./perseus-markdown.jsx";
26
24
  import QuestionParagraph from "./question-paragraph.jsx";
25
+ import TranslationLinter from "./translation-linter.js";
27
26
  import Util from "./util.js";
28
27
  import preprocessTex from "./util/katex-preprocess.js";
29
28
  import WidgetContainer from "./widget-container.jsx";
@@ -171,7 +170,7 @@ type Props = {|
171
170
  |};
172
171
 
173
172
  type State = {|
174
- notGorgonLintErrors: $ReadOnlyArray<string>,
173
+ translationLintErrors: $ReadOnlyArray<string>,
175
174
  widgetInfo: $ReadOnly<{|[id: string]: ?WidgetInfo|}>,
176
175
  widgetProps: $ReadOnly<{|[id: string]: ?$FlowFixMe|}>,
177
176
  jiptContent: any,
@@ -210,7 +209,7 @@ class Renderer extends React.Component<Props, State> {
210
209
  _isTwoColumn: boolean;
211
210
 
212
211
  // The i18n linter.
213
- _notGorgon: NotGorgon;
212
+ _translationLinter: TranslationLinter;
214
213
 
215
214
  lastRenderedMarkdown: React.Element<PerseusDependencies["KatexProvider"]>;
216
215
  reuseMarkdown: boolean;
@@ -234,20 +233,20 @@ class Renderer extends React.Component<Props, State> {
234
233
  reviewMode: false,
235
234
  serializedState: null,
236
235
  onSerializedStateUpdated: () => {},
237
- linterContext: linterContextDefault,
236
+ linterContext: PerseusLinter.linterContextDefault,
238
237
  };
239
238
 
240
239
  constructor(props: Props, context: Context) {
241
240
  super(props, context);
242
- this._notGorgon = new NotGorgon();
241
+ this._translationLinter = new TranslationLinter();
243
242
 
244
243
  this.state = {
245
244
  jiptContent: null,
246
245
 
247
- // NotGorgon is async and currently does not contain a location.
248
- // This is a list of error strings NotGorgon detected on its last
249
- // run.
250
- notGorgonLintErrors: [],
246
+ // TranslationLinter is async and currently does not contain a
247
+ // location. This is a list of error strings TranslationLinter
248
+ // detected on its last run.
249
+ translationLintErrors: [],
251
250
 
252
251
  // The ID of the last widget the user interacted with. We'll
253
252
  // use this to set the `isLastUsedWidget` flag on the
@@ -276,9 +275,9 @@ class Renderer extends React.Component<Props, State> {
276
275
  if (this.props.linterContext.highlightLint) {
277
276
  // Get i18n lint errors asynchronously. If there are lint errors,
278
277
  // this component will be rerendered.
279
- this._notGorgon.runLinter(
278
+ this._translationLinter.runLinter(
280
279
  this.props.content,
281
- this.handleNotGorgonLintErrors,
280
+ this.handletranslationLintErrors,
282
281
  );
283
282
  }
284
283
  }
@@ -344,8 +343,8 @@ class Renderer extends React.Component<Props, State> {
344
343
  !newJipt &&
345
344
  oldContent === newContent &&
346
345
  _.isEqual(
347
- this.state.notGorgonLintErrors,
348
- nextState.notGorgonLintErrors,
346
+ this.state.translationLintErrors,
347
+ nextState.translationLintErrors,
349
348
  ) &&
350
349
  // If we are running the linter then we need to know when
351
350
  // widgets have changed because we need for force the linter to
@@ -392,9 +391,9 @@ class Renderer extends React.Component<Props, State> {
392
391
  if (this.props.linterContext.highlightLint) {
393
392
  // Get i18n lint errors asynchronously. If lint errors have changed
394
393
  // since the last run, this component will be rerendered.
395
- this._notGorgon.runLinter(
394
+ this._translationLinter.runLinter(
396
395
  this.props.content,
397
- this.handleNotGorgonLintErrors,
396
+ this.handletranslationLintErrors,
398
397
  );
399
398
  }
400
399
  }
@@ -538,7 +537,7 @@ class Renderer extends React.Component<Props, State> {
538
537
  type={type}
539
538
  initialProps={this.getWidgetProps(id)}
540
539
  shouldHighlight={shouldHighlight}
541
- linterContext={Gorgon.pushContextStack(
540
+ linterContext={PerseusLinter.pushContextStack(
542
541
  this.props.linterContext,
543
542
  "widget",
544
543
  )}
@@ -1781,18 +1780,17 @@ class Renderer extends React.Component<Props, State> {
1781
1780
  return examples[0];
1782
1781
  };
1783
1782
 
1784
- // NotGorgon callback
1785
- handleNotGorgonLintErrors: (lintErrors: $ReadOnlyArray<string>) => void = (
1786
- lintErrors: $ReadOnlyArray<string>,
1787
- ) => {
1788
- if (!this._isMounted) {
1789
- return;
1790
- }
1783
+ // TranslationLinter callback
1784
+ handletranslationLintErrors: (lintErrors: $ReadOnlyArray<string>) => void =
1785
+ (lintErrors: $ReadOnlyArray<string>) => {
1786
+ if (!this._isMounted) {
1787
+ return;
1788
+ }
1791
1789
 
1792
- this.setState({
1793
- notGorgonLintErrors: lintErrors,
1794
- });
1795
- };
1790
+ this.setState({
1791
+ translationLintErrors: lintErrors,
1792
+ });
1793
+ };
1796
1794
 
1797
1795
  render(): React.Node {
1798
1796
  const apiOptions = this.getApiOptions();
@@ -1886,12 +1884,12 @@ class Renderer extends React.Component<Props, State> {
1886
1884
  ...this.props.linterContext,
1887
1885
  };
1888
1886
 
1889
- Gorgon.runLinter(parsedMarkdown, context, true);
1887
+ PerseusLinter.runLinter(parsedMarkdown, context, true);
1890
1888
 
1891
- // Apply the lint errors from the last NotGorgon run.
1889
+ // Apply the lint errors from the last TranslationLinter run.
1892
1890
  // TODO(joshuan): Support overlapping dots.
1893
- this._notGorgon.applyLintErrors(parsedMarkdown, [
1894
- ...this.state.notGorgonLintErrors,
1891
+ this._translationLinter.applyLintErrors(parsedMarkdown, [
1892
+ ...this.state.translationLintErrors,
1895
1893
  ...(this.props.legacyPerseusLint || []),
1896
1894
  ]);
1897
1895
  }
@@ -1004,4 +1004,4 @@
1004
1004
  }
1005
1005
  }
1006
1006
 
1007
- @import (inline) "../../../math-input/dist/index.css";
1007
+ @import "../../../math-input/less/main.less";
@@ -1,17 +1,13 @@
1
1
  // @flow
2
+ import {Rule} from "@khanacademy/perseus-linter";
2
3
  import {debounce} from "underscore";
3
4
 
4
- import Rule from "./gorgon/rule.js";
5
-
6
5
  /**
7
- * NotGorgon asynchronously calls Khan Academy's poentry linter.
6
+ * TranslationLinter asynchronously calls Khan Academy's poentry linter.
8
7
  *
9
8
  * The poentry linter checks for issues that prevent content from being
10
- * translated. This linter is KA-specific and so NotGorgon does not do anything
11
- * in non-KA environments.
12
- *
13
- * NotGorgon is named as such because it is not Gorgon, Perseus' built-in
14
- * linter.
9
+ * translated. This linter is KA-specific and so TranslationLinter does not do
10
+ * anything in non-KA environments.
15
11
  */
16
12
 
17
13
  // A LintCB is called once the linter has been run.
@@ -21,7 +17,7 @@ type LintCB = (errors: $ReadOnlyArray<string>) => void;
21
17
  // last call. The timer is reset if the lint is called during the wait.
22
18
  const DEBOUNCE_TIMEOUT = 1000;
23
19
 
24
- export default class NotGorgon {
20
+ export default class TranslationLinter {
25
21
  // To avoid linting when nothing has changed.
26
22
  previousContent: ?string = null;
27
23
 
@@ -102,17 +98,17 @@ export default class NotGorgon {
102
98
 
103
99
  /**
104
100
  * Applies an array of errors generated by linters without position
105
- * information (NotGorgon and the legacy getSaveWarnings()) to the top
106
- * of a Perseus tree.
101
+ * information (TranslationLinter and the legacy getSaveWarnings()) to the
102
+ * top of a Perseus tree.
107
103
  */
108
104
  applyLintErrors(
109
105
  parsedMarkdown: any,
110
- notGorgonLintErrors: $ReadOnlyArray<string>,
106
+ translationLintErrors: $ReadOnlyArray<string>,
111
107
  ) {
112
108
  // These lint errors do not have position data associated with
113
109
  // them, so we just plop them at the top.
114
- if (notGorgonLintErrors.length) {
115
- const errorText = notGorgonLintErrors.join("\n\n");
110
+ if (translationLintErrors.length) {
111
+ const errorText = translationLintErrors.join("\n\n");
116
112
  parsedMarkdown.unshift({
117
113
  content: {
118
114
  type: "text",
package/src/types.js CHANGED
@@ -359,6 +359,8 @@ type InitialRequestUrlInterface = {|
359
359
  protocol: string,
360
360
  |};
361
361
 
362
+ export type VideoKind = "YOUTUBE_ID" | "READABLE_ID";
363
+
362
364
  // An object for dependency injection, to allow different clients
363
365
  // to provide different methods for logging, translation, network
364
366
  // requests, etc.
@@ -392,7 +394,7 @@ export type PerseusDependencies = {|
392
394
  // framework.
393
395
  useVideo(
394
396
  id: string,
395
- kind: "YOUTUBE_ID" | "READABLE_ID",
397
+ kind: VideoKind,
396
398
  ): Result<{|
397
399
  video: ?VideoData,
398
400
  |}>,
@@ -1,10 +1,10 @@
1
1
  /* eslint-disable react/no-unsafe, react/sort-comp */
2
2
  // @flow
3
+ import {linterContextDefault} from "@khanacademy/perseus-linter";
3
4
  import classNames from "classnames";
4
5
  import * as React from "react";
5
6
  import ReactDOM from "react-dom";
6
7
 
7
- import {linterContextDefault} from "./gorgon/proptypes.js";
8
8
  import {zIndexInteractiveComponent} from "./styles/constants.js";
9
9
  import {containerSizeClass, getClassFromWidth} from "./util/sizing-utils.js";
10
10
  import * as Widgets from "./widgets.js";