@khanacademy/perseus-linter 1.1.0 → 1.2.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.
- package/dist/es/index.js +71 -18
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +64 -7
- package/dist/index.js.map +1 -1
- package/dist/rule.d.ts +24 -8
- package/dist/rules/expression-widget.d.ts +9 -0
- package/dist/tree-transformer.d.ts +2 -0
- package/package.json +3 -3
package/dist/es/index.js
CHANGED
|
@@ -2,18 +2,13 @@ import { PerseusError, Errors, addLibraryVersionToPerseusDebug } from '@khanacad
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
|
|
4
4
|
function _extends() {
|
|
5
|
-
_extends = Object.assign ? Object.assign.bind() : function (
|
|
6
|
-
for (var
|
|
7
|
-
var
|
|
8
|
-
for (var
|
|
9
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
10
|
-
target[key] = source[key];
|
|
11
|
-
}
|
|
12
|
-
}
|
|
5
|
+
return _extends = Object.assign ? Object.assign.bind() : function (n) {
|
|
6
|
+
for (var e = 1; e < arguments.length; e++) {
|
|
7
|
+
var t = arguments[e];
|
|
8
|
+
for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
|
|
13
9
|
}
|
|
14
|
-
return
|
|
15
|
-
};
|
|
16
|
-
return _extends.apply(this, arguments);
|
|
10
|
+
return n;
|
|
11
|
+
}, _extends.apply(null, arguments);
|
|
17
12
|
}
|
|
18
13
|
|
|
19
14
|
/* eslint-disable no-useless-escape */
|
|
@@ -804,12 +799,62 @@ var DoubleSpacingAfterTerminal = Rule.makeRule({
|
|
|
804
799
|
any other kind of terminal punctuation.`
|
|
805
800
|
});
|
|
806
801
|
|
|
802
|
+
function buttonNotInButtonSet(name, set) {
|
|
803
|
+
return `Answer requires a button not found in the button sets: ${name} (in ${set})`;
|
|
804
|
+
}
|
|
805
|
+
const stringToButtonSet = {
|
|
806
|
+
"\\sqrt": "prealgebra",
|
|
807
|
+
"\\sin": "trig",
|
|
808
|
+
"\\cos": "trig",
|
|
809
|
+
"\\tan": "trig",
|
|
810
|
+
"\\log": "logarithms",
|
|
811
|
+
"\\ln": "logarithms"
|
|
812
|
+
};
|
|
813
|
+
|
|
814
|
+
/**
|
|
815
|
+
* Rule to make sure that Expression questions that require
|
|
816
|
+
* a specific math symbol to answer have that math symbol
|
|
817
|
+
* available in the keypad (desktop learners can use a keyboard,
|
|
818
|
+
* but mobile learners must use the MathInput keypad)
|
|
819
|
+
*/
|
|
820
|
+
var ExpressionWidget = Rule.makeRule({
|
|
821
|
+
name: "expression-widget",
|
|
822
|
+
severity: Rule.Severity.WARNING,
|
|
823
|
+
selector: "widget",
|
|
824
|
+
lint: function (state, content, nodes, match, context) {
|
|
825
|
+
var _context$widgets;
|
|
826
|
+
// This rule only looks at image widgets
|
|
827
|
+
if (state.currentNode().widgetType !== "expression") {
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
const nodeId = state.currentNode().id;
|
|
831
|
+
if (!nodeId) {
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
// If it can't find a definition for the widget it does nothing
|
|
836
|
+
const widget = context == null || (_context$widgets = context.widgets) == null ? void 0 : _context$widgets[nodeId];
|
|
837
|
+
if (!widget) {
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
840
|
+
const answers = widget.options.answerForms;
|
|
841
|
+
const buttons = widget.options.buttonSets;
|
|
842
|
+
for (const answer of answers) {
|
|
843
|
+
for (const [str, set] of Object.entries(stringToButtonSet)) {
|
|
844
|
+
if (answer.value.includes(str) && !buttons.includes(set)) {
|
|
845
|
+
return buttonNotInButtonSet(str, set);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
});
|
|
851
|
+
|
|
807
852
|
var ExtraContentSpacing = Rule.makeRule({
|
|
808
853
|
name: "extra-content-spacing",
|
|
809
854
|
selector: "paragraph",
|
|
810
855
|
pattern: /\s+$/,
|
|
811
856
|
applies: function (context) {
|
|
812
|
-
return context.contentType === "article";
|
|
857
|
+
return (context == null ? void 0 : context.contentType) === "article";
|
|
813
858
|
},
|
|
814
859
|
message: `No extra whitespace at the end of content blocks.`
|
|
815
860
|
});
|
|
@@ -989,9 +1034,13 @@ var ImageWidget = Rule.makeRule({
|
|
|
989
1034
|
if (state.currentNode().widgetType !== "image") {
|
|
990
1035
|
return;
|
|
991
1036
|
}
|
|
1037
|
+
const nodeId = state.currentNode().id;
|
|
1038
|
+
if (!nodeId) {
|
|
1039
|
+
return;
|
|
1040
|
+
}
|
|
992
1041
|
|
|
993
1042
|
// If it can't find a definition for the widget it does nothing
|
|
994
|
-
const widget = context && context.widgets && context.widgets[
|
|
1043
|
+
const widget = context && context.widgets && context.widgets[nodeId];
|
|
995
1044
|
if (!widget) {
|
|
996
1045
|
return;
|
|
997
1046
|
}
|
|
@@ -1075,7 +1124,7 @@ var MathAlignLinebreaks = Rule.makeRule({
|
|
|
1075
1124
|
const index = text.indexOf("\\\\");
|
|
1076
1125
|
if (index === -1) {
|
|
1077
1126
|
// No more backslash pairs, so we found no lint
|
|
1078
|
-
return
|
|
1127
|
+
return;
|
|
1079
1128
|
}
|
|
1080
1129
|
text = text.substring(index + 2);
|
|
1081
1130
|
|
|
@@ -1177,13 +1226,17 @@ var StaticWidgetInQuestionStem = Rule.makeRule({
|
|
|
1177
1226
|
selector: "widget",
|
|
1178
1227
|
lint: (state, content, nodes, match, context) => {
|
|
1179
1228
|
var _context$widgets;
|
|
1180
|
-
if (context.contentType !== "exercise") {
|
|
1229
|
+
if ((context == null ? void 0 : context.contentType) !== "exercise") {
|
|
1181
1230
|
return;
|
|
1182
1231
|
}
|
|
1183
1232
|
if (context.stack.includes("hint")) {
|
|
1184
1233
|
return;
|
|
1185
1234
|
}
|
|
1186
|
-
const
|
|
1235
|
+
const nodeId = state.currentNode().id;
|
|
1236
|
+
if (!nodeId) {
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1239
|
+
const widget = context == null || (_context$widgets = context.widgets) == null ? void 0 : _context$widgets[nodeId];
|
|
1187
1240
|
if (!widget) {
|
|
1188
1241
|
return;
|
|
1189
1242
|
}
|
|
@@ -1240,7 +1293,7 @@ do not put widgets inside of tables.`
|
|
|
1240
1293
|
});
|
|
1241
1294
|
|
|
1242
1295
|
// TODO(davidflanagan):
|
|
1243
|
-
var AllRules = [AbsoluteUrl, BlockquotedMath, BlockquotedWidget, DoubleSpacingAfterTerminal, ExtraContentSpacing, HeadingLevel1, HeadingLevelSkip, HeadingSentenceCase, HeadingTitleCase, ImageAltText, ImageInTable, LinkClickHere, LongParagraph, MathAdjacent, MathAlignExtraBreak, MathAlignLinebreaks, MathEmpty, MathFontSize, MathFrac, MathNested, MathStartsWithSpace, MathTextEmpty, NestedLists, StaticWidgetInQuestionStem, TableMissingCells, UnescapedDollar, WidgetInTable, MathWithoutDollars, UnbalancedCodeDelimiters, ImageSpacesAroundUrls, ImageWidget];
|
|
1296
|
+
var AllRules = [AbsoluteUrl, BlockquotedMath, BlockquotedWidget, DoubleSpacingAfterTerminal, ExpressionWidget, ExtraContentSpacing, HeadingLevel1, HeadingLevelSkip, HeadingSentenceCase, HeadingTitleCase, ImageAltText, ImageInTable, LinkClickHere, LongParagraph, MathAdjacent, MathAlignExtraBreak, MathAlignLinebreaks, MathEmpty, MathFontSize, MathFrac, MathNested, MathStartsWithSpace, MathTextEmpty, NestedLists, StaticWidgetInQuestionStem, TableMissingCells, UnescapedDollar, WidgetInTable, MathWithoutDollars, UnbalancedCodeDelimiters, ImageSpacesAroundUrls, ImageWidget];
|
|
1244
1297
|
|
|
1245
1298
|
/**
|
|
1246
1299
|
* TreeTransformer is a class for traversing and transforming trees. Create a
|
|
@@ -1781,7 +1834,7 @@ class Stack {
|
|
|
1781
1834
|
|
|
1782
1835
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
1783
1836
|
const libName = "@khanacademy/perseus-linter";
|
|
1784
|
-
const libVersion = "1.1
|
|
1837
|
+
const libVersion = "1.2.1";
|
|
1785
1838
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
1786
1839
|
|
|
1787
1840
|
// Define the shape of the linter context object that is passed through the
|