@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/index.js
CHANGED
|
@@ -791,12 +791,61 @@ var DoubleSpacingAfterTerminal = Rule.makeRule({
|
|
|
791
791
|
any other kind of terminal punctuation.`
|
|
792
792
|
});
|
|
793
793
|
|
|
794
|
+
function buttonNotInButtonSet(name, set) {
|
|
795
|
+
return `Answer requires a button not found in the button sets: ${name} (in ${set})`;
|
|
796
|
+
}
|
|
797
|
+
const stringToButtonSet = {
|
|
798
|
+
"\\sqrt": "prealgebra",
|
|
799
|
+
"\\sin": "trig",
|
|
800
|
+
"\\cos": "trig",
|
|
801
|
+
"\\tan": "trig",
|
|
802
|
+
"\\log": "logarithms",
|
|
803
|
+
"\\ln": "logarithms"
|
|
804
|
+
};
|
|
805
|
+
|
|
806
|
+
/**
|
|
807
|
+
* Rule to make sure that Expression questions that require
|
|
808
|
+
* a specific math symbol to answer have that math symbol
|
|
809
|
+
* available in the keypad (desktop learners can use a keyboard,
|
|
810
|
+
* but mobile learners must use the MathInput keypad)
|
|
811
|
+
*/
|
|
812
|
+
var ExpressionWidget = Rule.makeRule({
|
|
813
|
+
name: "expression-widget",
|
|
814
|
+
severity: Rule.Severity.WARNING,
|
|
815
|
+
selector: "widget",
|
|
816
|
+
lint: function (state, content, nodes, match, context) {
|
|
817
|
+
// This rule only looks at image widgets
|
|
818
|
+
if (state.currentNode().widgetType !== "expression") {
|
|
819
|
+
return;
|
|
820
|
+
}
|
|
821
|
+
const nodeId = state.currentNode().id;
|
|
822
|
+
if (!nodeId) {
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
// If it can't find a definition for the widget it does nothing
|
|
827
|
+
const widget = context?.widgets?.[nodeId];
|
|
828
|
+
if (!widget) {
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
const answers = widget.options.answerForms;
|
|
832
|
+
const buttons = widget.options.buttonSets;
|
|
833
|
+
for (const answer of answers) {
|
|
834
|
+
for (const [str, set] of Object.entries(stringToButtonSet)) {
|
|
835
|
+
if (answer.value.includes(str) && !buttons.includes(set)) {
|
|
836
|
+
return buttonNotInButtonSet(str, set);
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
});
|
|
842
|
+
|
|
794
843
|
var ExtraContentSpacing = Rule.makeRule({
|
|
795
844
|
name: "extra-content-spacing",
|
|
796
845
|
selector: "paragraph",
|
|
797
846
|
pattern: /\s+$/,
|
|
798
847
|
applies: function (context) {
|
|
799
|
-
return context
|
|
848
|
+
return context?.contentType === "article";
|
|
800
849
|
},
|
|
801
850
|
message: `No extra whitespace at the end of content blocks.`
|
|
802
851
|
});
|
|
@@ -976,9 +1025,13 @@ var ImageWidget = Rule.makeRule({
|
|
|
976
1025
|
if (state.currentNode().widgetType !== "image") {
|
|
977
1026
|
return;
|
|
978
1027
|
}
|
|
1028
|
+
const nodeId = state.currentNode().id;
|
|
1029
|
+
if (!nodeId) {
|
|
1030
|
+
return;
|
|
1031
|
+
}
|
|
979
1032
|
|
|
980
1033
|
// If it can't find a definition for the widget it does nothing
|
|
981
|
-
const widget = context && context.widgets && context.widgets[
|
|
1034
|
+
const widget = context && context.widgets && context.widgets[nodeId];
|
|
982
1035
|
if (!widget) {
|
|
983
1036
|
return;
|
|
984
1037
|
}
|
|
@@ -1062,7 +1115,7 @@ var MathAlignLinebreaks = Rule.makeRule({
|
|
|
1062
1115
|
const index = text.indexOf("\\\\");
|
|
1063
1116
|
if (index === -1) {
|
|
1064
1117
|
// No more backslash pairs, so we found no lint
|
|
1065
|
-
return
|
|
1118
|
+
return;
|
|
1066
1119
|
}
|
|
1067
1120
|
text = text.substring(index + 2);
|
|
1068
1121
|
|
|
@@ -1163,13 +1216,17 @@ var StaticWidgetInQuestionStem = Rule.makeRule({
|
|
|
1163
1216
|
severity: Rule.Severity.WARNING,
|
|
1164
1217
|
selector: "widget",
|
|
1165
1218
|
lint: (state, content, nodes, match, context) => {
|
|
1166
|
-
if (context
|
|
1219
|
+
if (context?.contentType !== "exercise") {
|
|
1167
1220
|
return;
|
|
1168
1221
|
}
|
|
1169
1222
|
if (context.stack.includes("hint")) {
|
|
1170
1223
|
return;
|
|
1171
1224
|
}
|
|
1172
|
-
const
|
|
1225
|
+
const nodeId = state.currentNode().id;
|
|
1226
|
+
if (!nodeId) {
|
|
1227
|
+
return;
|
|
1228
|
+
}
|
|
1229
|
+
const widget = context?.widgets?.[nodeId];
|
|
1173
1230
|
if (!widget) {
|
|
1174
1231
|
return;
|
|
1175
1232
|
}
|
|
@@ -1226,7 +1283,7 @@ do not put widgets inside of tables.`
|
|
|
1226
1283
|
});
|
|
1227
1284
|
|
|
1228
1285
|
// TODO(davidflanagan):
|
|
1229
|
-
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];
|
|
1286
|
+
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];
|
|
1230
1287
|
|
|
1231
1288
|
/**
|
|
1232
1289
|
* TreeTransformer is a class for traversing and transforming trees. Create a
|
|
@@ -1773,7 +1830,7 @@ class Stack {
|
|
|
1773
1830
|
|
|
1774
1831
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
1775
1832
|
const libName = "@khanacademy/perseus-linter";
|
|
1776
|
-
const libVersion = "1.1
|
|
1833
|
+
const libVersion = "1.2.1";
|
|
1777
1834
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
1778
1835
|
|
|
1779
1836
|
// Define the shape of the linter context object that is passed through the
|