@khanacademy/perseus-linter 0.2.5 → 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 (133) hide show
  1. package/.eslintrc.js +1 -0
  2. package/CHANGELOG.md +19 -0
  3. package/dist/es/index.js +643 -588
  4. package/dist/es/index.js.map +1 -1
  5. package/dist/index.d.ts +7 -2
  6. package/dist/index.js +281 -398
  7. package/dist/index.js.flow +18 -2
  8. package/dist/index.js.map +1 -1
  9. package/dist/proptypes.d.ts +9 -0
  10. package/dist/proptypes.js.flow +17 -0
  11. package/dist/rule.d.ts +170 -0
  12. package/dist/rule.js.flow +86 -0
  13. package/dist/rules/absolute-url.d.ts +3 -0
  14. package/dist/rules/absolute-url.js.flow +9 -0
  15. package/dist/rules/all-rules.d.ts +2 -0
  16. package/dist/rules/all-rules.js.flow +9 -0
  17. package/dist/rules/blockquoted-math.d.ts +3 -0
  18. package/dist/rules/blockquoted-math.js.flow +9 -0
  19. package/dist/rules/blockquoted-widget.d.ts +3 -0
  20. package/dist/rules/blockquoted-widget.js.flow +9 -0
  21. package/dist/rules/double-spacing-after-terminal.d.ts +3 -0
  22. package/dist/rules/double-spacing-after-terminal.js.flow +9 -0
  23. package/dist/rules/extra-content-spacing.d.ts +3 -0
  24. package/dist/rules/extra-content-spacing.js.flow +9 -0
  25. package/dist/rules/heading-level-1.d.ts +3 -0
  26. package/dist/rules/heading-level-1.js.flow +9 -0
  27. package/dist/rules/heading-level-skip.d.ts +3 -0
  28. package/dist/rules/heading-level-skip.js.flow +9 -0
  29. package/dist/rules/heading-sentence-case.d.ts +3 -0
  30. package/dist/rules/heading-sentence-case.js.flow +9 -0
  31. package/dist/rules/heading-title-case.d.ts +3 -0
  32. package/dist/rules/heading-title-case.js.flow +9 -0
  33. package/dist/rules/image-alt-text.d.ts +3 -0
  34. package/dist/rules/image-alt-text.js.flow +9 -0
  35. package/dist/rules/image-in-table.d.ts +3 -0
  36. package/dist/rules/image-in-table.js.flow +9 -0
  37. package/dist/rules/image-spaces-around-urls.d.ts +3 -0
  38. package/dist/rules/image-spaces-around-urls.js.flow +9 -0
  39. package/dist/rules/image-widget.d.ts +3 -0
  40. package/dist/rules/image-widget.js.flow +9 -0
  41. package/dist/rules/link-click-here.d.ts +3 -0
  42. package/dist/rules/link-click-here.js.flow +9 -0
  43. package/dist/rules/lint-utils.d.ts +2 -0
  44. package/dist/rules/lint-utils.js.flow +8 -0
  45. package/dist/rules/long-paragraph.d.ts +3 -0
  46. package/dist/rules/long-paragraph.js.flow +9 -0
  47. package/dist/rules/math-adjacent.d.ts +3 -0
  48. package/dist/rules/math-adjacent.js.flow +9 -0
  49. package/dist/rules/math-align-extra-break.d.ts +3 -0
  50. package/dist/rules/math-align-extra-break.js.flow +9 -0
  51. package/dist/rules/math-align-linebreaks.d.ts +3 -0
  52. package/dist/rules/math-align-linebreaks.js.flow +9 -0
  53. package/dist/rules/math-empty.d.ts +3 -0
  54. package/dist/rules/math-empty.js.flow +9 -0
  55. package/dist/rules/math-font-size.d.ts +3 -0
  56. package/dist/rules/math-font-size.js.flow +9 -0
  57. package/dist/rules/math-frac.d.ts +3 -0
  58. package/dist/rules/math-frac.js.flow +9 -0
  59. package/dist/rules/math-nested.d.ts +3 -0
  60. package/dist/rules/math-nested.js.flow +9 -0
  61. package/dist/rules/math-starts-with-space.d.ts +3 -0
  62. package/dist/rules/math-starts-with-space.js.flow +9 -0
  63. package/dist/rules/math-text-empty.d.ts +3 -0
  64. package/dist/rules/math-text-empty.js.flow +9 -0
  65. package/dist/rules/math-without-dollars.d.ts +3 -0
  66. package/dist/rules/math-without-dollars.js.flow +9 -0
  67. package/dist/rules/nested-lists.d.ts +3 -0
  68. package/dist/rules/nested-lists.js.flow +9 -0
  69. package/dist/rules/profanity.d.ts +3 -0
  70. package/dist/rules/profanity.js.flow +9 -0
  71. package/dist/rules/table-missing-cells.d.ts +3 -0
  72. package/dist/rules/table-missing-cells.js.flow +9 -0
  73. package/dist/rules/unbalanced-code-delimiters.d.ts +3 -0
  74. package/dist/rules/unbalanced-code-delimiters.js.flow +9 -0
  75. package/dist/rules/unescaped-dollar.d.ts +3 -0
  76. package/dist/rules/unescaped-dollar.js.flow +9 -0
  77. package/dist/rules/widget-in-table.d.ts +3 -0
  78. package/dist/rules/widget-in-table.js.flow +9 -0
  79. package/dist/selector.d.ts +108 -0
  80. package/dist/selector.js.flow +31 -0
  81. package/dist/tree-transformer.d.ts +205 -0
  82. package/dist/tree-transformer.js.flow +253 -0
  83. package/dist/types.d.ts +6 -0
  84. package/dist/types.js.flow +12 -0
  85. package/package.json +4 -4
  86. package/src/__tests__/{matcher_test.js → matcher.test.ts} +60 -60
  87. package/src/__tests__/{rule_test.js → rule.test.ts} +13 -5
  88. package/src/__tests__/{rules_test.js → rules.test.ts} +99 -39
  89. package/src/__tests__/{selector-parser_test.js → selector-parser.test.ts} +1 -2
  90. package/src/__tests__/{tree-transformer_test.js → tree-transformer.test.ts} +39 -41
  91. package/src/{index.js → index.ts} +21 -23
  92. package/src/{proptypes.js → proptypes.ts} +4 -14
  93. package/src/{rule.js → rule.ts} +45 -38
  94. package/src/rules/{absolute-url.js → absolute-url.ts} +4 -5
  95. package/src/rules/all-rules.ts +71 -0
  96. package/src/rules/{blockquoted-math.js → blockquoted-math.ts} +3 -4
  97. package/src/rules/{blockquoted-widget.js → blockquoted-widget.ts} +3 -4
  98. package/src/rules/{double-spacing-after-terminal.js → double-spacing-after-terminal.ts} +3 -4
  99. package/src/rules/{extra-content-spacing.js → extra-content-spacing.ts} +3 -4
  100. package/src/rules/{heading-level-1.js → heading-level-1.ts} +3 -4
  101. package/src/rules/{heading-level-skip.js → heading-level-skip.ts} +3 -4
  102. package/src/rules/{heading-sentence-case.js → heading-sentence-case.ts} +3 -4
  103. package/src/rules/{heading-title-case.js → heading-title-case.ts} +11 -6
  104. package/src/rules/{image-alt-text.js → image-alt-text.ts} +3 -4
  105. package/src/rules/{image-in-table.js → image-in-table.ts} +3 -4
  106. package/src/rules/{image-spaces-around-urls.js → image-spaces-around-urls.ts} +3 -4
  107. package/src/rules/{image-widget.js → image-widget.ts} +3 -4
  108. package/src/rules/{link-click-here.js → link-click-here.ts} +3 -4
  109. package/src/rules/{lint-utils.js → lint-utils.ts} +1 -2
  110. package/src/rules/{long-paragraph.js → long-paragraph.ts} +3 -4
  111. package/src/rules/{math-adjacent.js → math-adjacent.ts} +3 -4
  112. package/src/rules/{math-align-extra-break.js → math-align-extra-break.ts} +3 -4
  113. package/src/rules/{math-align-linebreaks.js → math-align-linebreaks.ts} +3 -4
  114. package/src/rules/{math-empty.js → math-empty.ts} +3 -4
  115. package/src/rules/{math-font-size.js → math-font-size.ts} +3 -4
  116. package/src/rules/{math-frac.js → math-frac.ts} +3 -4
  117. package/src/rules/{math-nested.js → math-nested.ts} +3 -4
  118. package/src/rules/{math-starts-with-space.js → math-starts-with-space.ts} +3 -4
  119. package/src/rules/{math-text-empty.js → math-text-empty.ts} +3 -4
  120. package/src/rules/{math-without-dollars.js → math-without-dollars.ts} +3 -4
  121. package/src/rules/{nested-lists.js → nested-lists.ts} +3 -4
  122. package/src/rules/{profanity.js → profanity.ts} +3 -4
  123. package/src/rules/{table-missing-cells.js → table-missing-cells.ts} +3 -4
  124. package/src/rules/{unbalanced-code-delimiters.js → unbalanced-code-delimiters.ts} +3 -4
  125. package/src/rules/{unescaped-dollar.js → unescaped-dollar.ts} +3 -4
  126. package/src/rules/{widget-in-table.js → widget-in-table.ts} +3 -4
  127. package/src/{selector.js → selector.ts} +12 -13
  128. package/src/{tree-transformer.js → tree-transformer.ts} +24 -24
  129. package/src/types.ts +7 -0
  130. package/tsconfig.json +12 -0
  131. package/tsconfig.tsbuildinfo +1 -0
  132. package/src/rules/all-rules.js +0 -72
  133. package/src/types.js +0 -10
@@ -1,12 +1,11 @@
1
- // @flow
2
- import Rule from "./rule.js";
3
- import AllRules from "./rules/all-rules.js";
4
- import TreeTransformer from "./tree-transformer.js";
1
+ import Rule from "./rule";
2
+ import AllRules from "./rules/all-rules";
3
+ import TreeTransformer from "./tree-transformer";
5
4
 
6
- export {linterContextProps, linterContextDefault} from "./proptypes.js";
7
- export type {LinterContextProps} from "./types.js";
5
+ export {linterContextProps, linterContextDefault} from "./proptypes";
6
+ export type {LinterContextProps} from "./types";
8
7
 
9
- const allLintRules: $ReadOnlyArray<$FlowFixMe> = AllRules.filter(
8
+ const allLintRules: ReadonlyArray<any> = AllRules.filter(
10
9
  (r) => r.severity < Rule.Severity.BULK_WARNING,
11
10
  );
12
11
 
@@ -37,12 +36,12 @@ export {Rule, allLintRules as rules};
37
36
  // online linting and batch linting.
38
37
  //
39
38
  export function runLinter(
40
- tree: $FlowFixMe,
41
- context: $FlowFixMe,
39
+ tree: any,
40
+ context: any,
42
41
  highlight: boolean,
43
- rules?: $ReadOnlyArray<$FlowFixMe> = allLintRules,
44
- ): $ReadOnlyArray<$FlowFixMe> {
45
- const warnings = [];
42
+ rules: ReadonlyArray<any> = allLintRules,
43
+ ): ReadonlyArray<any> {
44
+ const warnings: Array<any> = [];
46
45
  const tt = new TreeTransformer(tree);
47
46
 
48
47
  // The markdown parser often outputs adjacent text nodes. We
@@ -51,8 +50,7 @@ export function runLinter(
51
50
  if (TreeTransformer.isTextNode(node)) {
52
51
  let next = state.nextSibling();
53
52
  while (TreeTransformer.isTextNode(next)) {
54
- // $FlowFixMe[prop-missing]
55
- // $FlowFixMe[incompatible-use]
53
+ // @ts-expect-error [FEI-5003] - TS2339 - Property 'content' does not exist on type 'TreeNode'. | TS2533 - Object is possibly 'null' or 'undefined'. | TS2339 - Property 'content' does not exist on type 'TreeNode'.
56
54
  node.content += next.content;
57
55
  state.removeNextSibling();
58
56
  next = state.nextSibling();
@@ -77,14 +75,14 @@ export function runLinter(
77
75
  // issue too. But using JavaScript has its own downsides: there is
78
76
  // risk that the linter JavaScript would interfere with
79
77
  // widget-related Javascript.
80
- let tableWarnings = [];
78
+ let tableWarnings: Array<never> = [];
81
79
  let insideTable = false;
82
80
 
83
81
  // Traverse through the nodes of the parse tree. At each node, loop
84
82
  // through the array of lint rules and check whether there is a
85
83
  // lint violation at that node.
86
84
  tt.traverse((node, state, content) => {
87
- const nodeWarnings = [];
85
+ const nodeWarnings: Array<any> = [];
88
86
 
89
87
  // If our rule is only designed to be tested against a particular
90
88
  // content type and we're not in that content type, we don't need to
@@ -99,7 +97,7 @@ export function runLinter(
99
97
  const nodeContext = {
100
98
  ...context,
101
99
  stack: stack.join("."),
102
- };
100
+ } as const;
103
101
 
104
102
  applicableRules.forEach((rule) => {
105
103
  const warning = rule.check(node, state, content, nodeContext);
@@ -159,6 +157,7 @@ export function runLinter(
159
157
  // this node, then we need to save the warnings for display
160
158
  // on the table itself
161
159
  if (insideTable && nodeWarnings.length) {
160
+ // @ts-expect-error [FEI-5003] - TS2345 - Argument of type 'any' is not assignable to parameter of type 'never'.
162
161
  tableWarnings.push(...nodeWarnings);
163
162
  }
164
163
 
@@ -186,6 +185,7 @@ export function runLinter(
186
185
  // node under a new lint node and put the warnings there.
187
186
  state.replace({
188
187
  type: "lint",
188
+ // @ts-expect-error [FEI-5003] - TS2345 - Argument of type '{ type: string; content: TreeNode; message: string; ruleName: any; blockHighlight: any; insideTable: boolean; severity: any; }' is not assignable to parameter of type 'TreeNode'.
189
189
  content: node,
190
190
  message: nodeWarnings.map((w) => w.message).join("\n\n"),
191
191
  ruleName: nodeWarnings[0].rule,
@@ -219,7 +219,7 @@ export function runLinter(
219
219
  // single line, so keeping them combined in that case might
220
220
  // be the best thing, anyway.
221
221
  //
222
- // $FlowFixMe[prop-missing]
222
+ // @ts-expect-error [FEI-5003] - TS2339 - Property 'content' does not exist on type 'TreeNode'.
223
223
  const content = node.content; // Text nodes have content
224
224
  const warning = nodeWarnings[0]; // There is only one warning.
225
225
  // These are the lint boundaries within the content
@@ -228,7 +228,8 @@ export function runLinter(
228
228
  const prefix = content.substring(0, start);
229
229
  const lint = content.substring(start, end);
230
230
  const suffix = content.substring(end);
231
- const replacements = []; // What we'll replace the node with
231
+ // TODO(FEI-5003): Give this a real type.
232
+ const replacements: any[] = []; // What we'll replace the node with
232
233
 
233
234
  // The prefix text node, if there is one
234
235
  if (prefix) {
@@ -269,10 +270,7 @@ export function runLinter(
269
270
  return warnings;
270
271
  }
271
272
 
272
- export function pushContextStack(
273
- context: $FlowFixMe,
274
- name: string,
275
- ): $FlowFixMe {
273
+ export function pushContextStack(context: any, name: string): any {
276
274
  const stack = context.stack || [];
277
275
  return {
278
276
  ...context,
@@ -1,20 +1,10 @@
1
- // @flow
2
1
  // Define the shape of the linter context object that is passed through the
3
2
  // tree with additional information about what we are checking.
4
-
5
3
  import PropTypes from "prop-types";
6
4
 
7
- import type {LinterContextProps} from "./types.js";
5
+ import type {LinterContextProps} from "./types";
8
6
 
9
- export const linterContextProps: React$PropType$Primitive<{
10
- contentType?: string,
11
- highlightLint?: boolean,
12
- // eslint-disable-next-line ft-flow/no-mutable-array
13
- paths?: Array<string>,
14
- // eslint-disable-next-line ft-flow/no-mutable-array
15
- stack?: Array<string>,
16
- ...
17
- }> = PropTypes.shape({
7
+ export const linterContextProps = PropTypes.shape({
18
8
  contentType: PropTypes.string,
19
9
  highlightLint: PropTypes.bool,
20
10
  paths: PropTypes.arrayOf(PropTypes.string),
@@ -24,6 +14,6 @@ export const linterContextProps: React$PropType$Primitive<{
24
14
  export const linterContextDefault: LinterContextProps = {
25
15
  contentType: "",
26
16
  highlightLint: false,
27
- paths: ([]: $ReadOnlyArray<any>),
28
- stack: ([]: $ReadOnlyArray<any>),
17
+ paths: [] as ReadonlyArray<any>,
18
+ stack: [] as ReadonlyArray<any>,
29
19
  };
@@ -1,4 +1,3 @@
1
- // @flow
2
1
  /**
3
2
  * The Rule class represents a Perseus lint rule. A Rule instance has a check()
4
3
  * method that takes the same (node, state, content) arguments that a
@@ -124,9 +123,9 @@
124
123
 
125
124
  import {Errors, PerseusError} from "@khanacademy/perseus-error";
126
125
 
127
- import Selector from "./selector.js";
126
+ import Selector from "./selector";
128
127
 
129
- import type {TraversalState, TreeNode} from "./tree-transformer.js";
128
+ import type {TraversalState, TreeNode} from "./tree-transformer";
130
129
 
131
130
  // This represents the type returned by String.match(). It is an
132
131
  // array of strings, but also has index:number and input:string properties.
@@ -134,28 +133,29 @@ import type {TraversalState, TreeNode} from "./tree-transformer.js";
134
133
  export type PatternMatchType = any;
135
134
 
136
135
  // This is the return type of the check() method of a Rule object
137
- export type RuleCheckReturnType = ?{|
138
- rule: string,
139
- message: string,
140
- start: number,
141
- end: number,
142
- severity?: number,
143
- |};
136
+ export type RuleCheckReturnType =
137
+ | {
138
+ rule: string;
139
+ message: string;
140
+ start: number;
141
+ end: number;
142
+ severity?: number;
143
+ }
144
+ | null
145
+ | undefined;
144
146
 
145
147
  // This is the return type of the lint detection function passed as the 4th
146
148
  // argument to the Rule() constructor. It can return null or a string or an
147
149
  // object containing a string and two numbers.
148
150
  // prettier-ignore
149
151
  // (prettier formats this in a way that ka-lint does not like)
150
- export type LintTesterReturnType = ?(
151
- string
152
- | {|
153
- message: string,
154
- start: number,
155
- end: number,
156
- |});
152
+ export type LintTesterReturnType = string | {
153
+ message: string,
154
+ start: number,
155
+ end: number
156
+ } | null | undefined;
157
157
 
158
- export type LintRuleContextObject = ?Object;
158
+ export type LintRuleContextObject = any | null | undefined;
159
159
 
160
160
  // This is the type of the lint detection function that the Rule() constructor
161
161
  // expects as its fourth argument. It is passed the TraversalState object and
@@ -166,7 +166,7 @@ export type LintRuleContextObject = ?Object;
166
166
  export type LintTester = (
167
167
  state: TraversalState,
168
168
  content: string,
169
- selectorMatch: $ReadOnlyArray<TreeNode>,
169
+ selectorMatch: ReadonlyArray<TreeNode>,
170
170
  patternMatch: PatternMatchType,
171
171
  context: LintRuleContextObject,
172
172
  ) => LintTesterReturnType;
@@ -185,19 +185,19 @@ export default class Rule {
185
185
  name: string; // The name of the rule
186
186
  severity: number; // The severity of the rule
187
187
  selector: Selector; // The specified selector or the DEFAULT_SELECTOR
188
- pattern: ?RegExp; // A regular expression if one was specified
188
+ pattern: RegExp | null | undefined; // A regular expression if one was specified
189
189
  lint: LintTester; // The lint-testing function or a default
190
190
  applies: AppliesTester; // Checks to see if we should apply a rule or not
191
- message: ?string; // The error message for use with the default function
191
+ message: string | null | undefined; // The error message for use with the default function
192
192
  static DEFAULT_SELECTOR: Selector;
193
193
 
194
194
  // The comment at the top of this file has detailed docs for
195
195
  // this constructor and its arguments
196
196
  constructor(
197
- name: ?string,
198
- severity: ?number,
199
- selector: ?Selector,
200
- pattern: ?RegExp,
197
+ name: string | null | undefined,
198
+ severity: number | null | undefined,
199
+ selector: Selector | null | undefined,
200
+ pattern: RegExp | null | undefined,
201
201
  lint: LintTester | string,
202
202
  applies: AppliesTester,
203
203
  ) {
@@ -233,7 +233,7 @@ export default class Rule {
233
233
 
234
234
  // A factory method for use with rules described in JSON files
235
235
  // See the documentation at the start of this file for details.
236
- static makeRule(options: Object): Rule {
236
+ static makeRule(options: any): Rule {
237
237
  return new Rule(
238
238
  options.name,
239
239
  options.severity,
@@ -312,7 +312,7 @@ export default class Rule {
312
312
  start: error.start,
313
313
  end: error.end,
314
314
  };
315
- } catch (e) {
315
+ } catch (e: any) {
316
316
  // If the lint function threw an exception we handle that as
317
317
  // a special type of lint. We want the user to see the lint
318
318
  // warning in this case (even though it is out of their control)
@@ -339,10 +339,14 @@ ${e.stack}`,
339
339
  _defaultLintFunction(
340
340
  state: TraversalState,
341
341
  content: string,
342
- selectorMatch: $ReadOnlyArray<TreeNode>,
342
+ selectorMatch: ReadonlyArray<TreeNode>,
343
343
  patternMatch: PatternMatchType,
344
344
  context: LintRuleContextObject,
345
- ): {|end: number, message: string, start: number|} {
345
+ ): {
346
+ end: number;
347
+ message: string;
348
+ start: number;
349
+ } {
346
350
  return {
347
351
  message: this.message || "",
348
352
  start: patternMatch.index,
@@ -365,7 +369,9 @@ ${e.stack}`,
365
369
  // input "foo" ==> output /foo/
366
370
  // input "/foo/i" ==> output /foo/i
367
371
  //
368
- static makePattern(pattern: ?(RegExp | string)): ?RegExp {
372
+ static makePattern(
373
+ pattern?: RegExp | string | null,
374
+ ): RegExp | null | undefined {
369
375
  if (!pattern) {
370
376
  return null;
371
377
  }
@@ -376,7 +382,8 @@ ${e.stack}`,
376
382
  const lastSlash = pattern.lastIndexOf("/");
377
383
  const expression = pattern.substring(1, lastSlash);
378
384
  const flags = pattern.substring(lastSlash + 1);
379
- return new RegExp(expression, ((flags: any): RegExp$flags));
385
+ // @ts-expect-error [FEI-5003] - TS2713 - Cannot access 'RegExp.flags' because 'RegExp' is a type, but not a namespace. Did you mean to retrieve the type of the property 'flags' in 'RegExp' with 'RegExp["flags"]'?
386
+ return new RegExp(expression, flags as RegExp.flags);
380
387
  }
381
388
  return new RegExp(pattern);
382
389
  }
@@ -387,7 +394,7 @@ ${e.stack}`,
387
394
  // want to simulate a match on the entire content string.
388
395
  static FakePatternMatch(
389
396
  input: string,
390
- match: ?string,
397
+ match: string | null | undefined,
391
398
  index: number,
392
399
  ): PatternMatchType {
393
400
  const result: any = [match];
@@ -396,12 +403,12 @@ ${e.stack}`,
396
403
  return result;
397
404
  }
398
405
 
399
- static Severity: {|
400
- BULK_WARNING: number,
401
- ERROR: number,
402
- GUIDELINE: number,
403
- WARNING: number,
404
- |} = {
406
+ static Severity: {
407
+ BULK_WARNING: number;
408
+ ERROR: number;
409
+ GUIDELINE: number;
410
+ WARNING: number;
411
+ } = {
405
412
  ERROR: 1,
406
413
  WARNING: 2,
407
414
  GUIDELINE: 3,
@@ -1,9 +1,8 @@
1
- // @flow
2
- import Rule from "../rule.js";
1
+ import Rule from "../rule";
3
2
 
4
- import {getHostname} from "./lint-utils.js";
3
+ import {getHostname} from "./lint-utils";
5
4
 
6
- export default (Rule.makeRule({
5
+ export default Rule.makeRule({
7
6
  name: "absolute-url",
8
7
  severity: Rule.Severity.GUIDELINE,
9
8
  selector: "link, image",
@@ -21,4 +20,4 @@ https://www.khanacademy.org URL prefix.
21
20
  Use a relative URL beginning with / instead.`;
22
21
  }
23
22
  },
24
- }): Rule);
23
+ }) as Rule;
@@ -0,0 +1,71 @@
1
+ // TODO(davidflanagan):
2
+ // This should probably be converted to use import and to export
3
+ // and object that maps rule names to rules. Also, maybe this should
4
+ // be an auto-generated file with a script that updates it any time
5
+ // we add a new rule?
6
+
7
+ import AbsoluteUrl from "./absolute-url";
8
+ import BlockquotedMath from "./blockquoted-math";
9
+ import BlockquotedWidget from "./blockquoted-widget";
10
+ import DoubleSpacingAfterTerminal from "./double-spacing-after-terminal";
11
+ import ExtraContentSpacing from "./extra-content-spacing";
12
+ import HeadingLevel1 from "./heading-level-1";
13
+ import HeadingLevelSkip from "./heading-level-skip";
14
+ import HeadingSentenceCase from "./heading-sentence-case";
15
+ import HeadingTitleCase from "./heading-title-case";
16
+ import ImageAltText from "./image-alt-text";
17
+ import ImageInTable from "./image-in-table";
18
+ import ImageSpacesAroundUrls from "./image-spaces-around-urls";
19
+ import ImageWidget from "./image-widget";
20
+ import LinkClickHere from "./link-click-here";
21
+ import LongParagraph from "./long-paragraph";
22
+ import MathAdjacent from "./math-adjacent";
23
+ import MathAlignExtraBreak from "./math-align-extra-break";
24
+ import MathAlignLinebreaks from "./math-align-linebreaks";
25
+ import MathEmpty from "./math-empty";
26
+ import MathFontSize from "./math-font-size";
27
+ import MathFrac from "./math-frac";
28
+ import MathNested from "./math-nested";
29
+ import MathStartsWithSpace from "./math-starts-with-space";
30
+ import MathTextEmpty from "./math-text-empty";
31
+ import MathWithoutDollars from "./math-without-dollars";
32
+ import NestedLists from "./nested-lists";
33
+ import Profanity from "./profanity";
34
+ import TableMissingCells from "./table-missing-cells";
35
+ import UnbalancedCodeDelimiters from "./unbalanced-code-delimiters";
36
+ import UnescapedDollar from "./unescaped-dollar";
37
+ import WidgetInTable from "./widget-in-table";
38
+
39
+ export default [
40
+ AbsoluteUrl,
41
+ BlockquotedMath,
42
+ BlockquotedWidget,
43
+ DoubleSpacingAfterTerminal,
44
+ ExtraContentSpacing,
45
+ HeadingLevel1,
46
+ HeadingLevelSkip,
47
+ HeadingSentenceCase,
48
+ HeadingTitleCase,
49
+ ImageAltText,
50
+ ImageInTable,
51
+ LinkClickHere,
52
+ LongParagraph,
53
+ MathAdjacent,
54
+ MathAlignExtraBreak,
55
+ MathAlignLinebreaks,
56
+ MathEmpty,
57
+ MathFontSize,
58
+ MathFrac,
59
+ MathNested,
60
+ MathStartsWithSpace,
61
+ MathTextEmpty,
62
+ NestedLists,
63
+ TableMissingCells,
64
+ UnescapedDollar,
65
+ WidgetInTable,
66
+ Profanity,
67
+ MathWithoutDollars,
68
+ UnbalancedCodeDelimiters,
69
+ ImageSpacesAroundUrls,
70
+ ImageWidget,
71
+ ];
@@ -1,10 +1,9 @@
1
- // @flow
2
- import Rule from "../rule.js";
1
+ import Rule from "../rule";
3
2
 
4
- export default (Rule.makeRule({
3
+ export default Rule.makeRule({
5
4
  name: "blockquoted-math",
6
5
  severity: Rule.Severity.WARNING,
7
6
  selector: "blockQuote math, blockQuote blockMath",
8
7
  message: `Blockquoted math:
9
8
  math should not be indented.`,
10
- }): Rule);
9
+ }) as Rule;
@@ -1,10 +1,9 @@
1
- // @flow
2
- import Rule from "../rule.js";
1
+ import Rule from "../rule";
3
2
 
4
- export default (Rule.makeRule({
3
+ export default Rule.makeRule({
5
4
  name: "blockquoted-widget",
6
5
  severity: Rule.Severity.WARNING,
7
6
  selector: "blockQuote widget",
8
7
  message: `Blockquoted widget:
9
8
  widgets should not be indented.`,
10
- }): Rule);
9
+ }) as Rule;
@@ -1,12 +1,11 @@
1
1
  /* eslint-disable no-useless-escape */
2
- // @flow
3
- import Rule from "../rule.js";
2
+ import Rule from "../rule";
4
3
 
5
- export default (Rule.makeRule({
4
+ export default Rule.makeRule({
6
5
  name: "double-spacing-after-terminal",
7
6
  severity: Rule.Severity.BULK_WARNING,
8
7
  selector: "paragraph",
9
8
  pattern: /[.!\?] {2}/i,
10
9
  message: `Use a single space after a sentence-ending period, or
11
10
  any other kind of terminal punctuation.`,
12
- }): Rule);
11
+ }) as Rule;
@@ -1,7 +1,6 @@
1
- // @flow
2
- import Rule from "../rule.js";
1
+ import Rule from "../rule";
3
2
 
4
- export default (Rule.makeRule({
3
+ export default Rule.makeRule({
5
4
  name: "extra-content-spacing",
6
5
  selector: "paragraph",
7
6
  pattern: /\s+$/,
@@ -9,4 +8,4 @@ export default (Rule.makeRule({
9
8
  return context.contentType === "article";
10
9
  },
11
10
  message: `No extra whitespace at the end of content blocks.`,
12
- }): Rule);
11
+ }) as Rule;
@@ -1,7 +1,6 @@
1
- // @flow
2
- import Rule from "../rule.js";
1
+ import Rule from "../rule";
3
2
 
4
- export default (Rule.makeRule({
3
+ export default Rule.makeRule({
5
4
  name: "heading-level-1",
6
5
  severity: Rule.Severity.WARNING,
7
6
  selector: "heading",
@@ -11,4 +10,4 @@ export default (Rule.makeRule({
11
10
  Begin headings with two or more # characters.`;
12
11
  }
13
12
  },
14
- }): Rule);
13
+ }) as Rule;
@@ -1,7 +1,6 @@
1
- // @flow
2
- import Rule from "../rule.js";
1
+ import Rule from "../rule";
3
2
 
4
- export default (Rule.makeRule({
3
+ export default Rule.makeRule({
5
4
  name: "heading-level-skip",
6
5
  severity: Rule.Severity.WARNING,
7
6
  selector: "heading ~ heading",
@@ -17,4 +16,4 @@ this heading is level ${currentHeading.level} but
17
16
  the previous heading was level ${previousHeading.level}`;
18
17
  }
19
18
  },
20
- }): Rule);
19
+ }) as Rule;
@@ -1,11 +1,10 @@
1
- // @flow
2
- import Rule from "../rule.js";
1
+ import Rule from "../rule";
3
2
 
4
- export default (Rule.makeRule({
3
+ export default Rule.makeRule({
5
4
  name: "heading-sentence-case",
6
5
  severity: Rule.Severity.GUIDELINE,
7
6
  selector: "heading",
8
7
  pattern: /^\W*[a-z]/, // first letter is lowercase
9
8
  message: `First letter is lowercase:
10
9
  the first letter of a heading should be capitalized.`,
11
- }): Rule);
10
+ }) as Rule;
@@ -1,17 +1,22 @@
1
- // @flow
2
- import Rule from "../rule.js";
1
+ import Rule from "../rule";
3
2
 
4
3
  // These are 3-letter and longer words that we would not expect to be
5
4
  // capitalized even in a title-case heading. See
6
5
  // http://blog.apastyle.org/apastyle/2012/03/title-case-and-sentence-case-capitalization-in-apa-style.html
7
- const littleWords = {and: true, nor: true, but: true, the: true, for: true};
6
+ const littleWords = {
7
+ and: true,
8
+ nor: true,
9
+ but: true,
10
+ the: true,
11
+ for: true,
12
+ } as const;
8
13
 
9
- function isCapitalized(word) {
14
+ function isCapitalized(word: any) {
10
15
  const c = word[0];
11
16
  return c === c.toUpperCase();
12
17
  }
13
18
 
14
- export default (Rule.makeRule({
19
+ export default Rule.makeRule({
15
20
  name: "heading-title-case",
16
21
  severity: Rule.Severity.GUIDELINE,
17
22
  selector: "heading",
@@ -60,4 +65,4 @@ This heading appears to be in title-case, but should be sentence-case.
60
65
  Only capitalize the first letter and proper nouns.`;
61
66
  }
62
67
  },
63
- }): Rule);
68
+ }) as Rule;
@@ -1,7 +1,6 @@
1
- // @flow
2
- import Rule from "../rule.js";
1
+ import Rule from "../rule";
3
2
 
4
- export default (Rule.makeRule({
3
+ export default Rule.makeRule({
5
4
  name: "image-alt-text",
6
5
  severity: Rule.Severity.WARNING,
7
6
  selector: "image",
@@ -18,4 +17,4 @@ for accessibility, all images should have descriptive alt text.
18
17
  This image's alt text is only ${image.alt.length} characters long.`;
19
18
  }
20
19
  },
21
- }): Rule);
20
+ }) as Rule;
@@ -1,10 +1,9 @@
1
- // @flow
2
- import Rule from "../rule.js";
1
+ import Rule from "../rule";
3
2
 
4
- export default (Rule.makeRule({
3
+ export default Rule.makeRule({
5
4
  name: "image-in-table",
6
5
  severity: Rule.Severity.BULK_WARNING,
7
6
  selector: "table image",
8
7
  message: `Image in table:
9
8
  do not put images inside of tables.`,
10
- }): Rule);
9
+ }) as Rule;
@@ -1,7 +1,6 @@
1
- // @flow
2
- import Rule from "../rule.js";
1
+ import Rule from "../rule";
3
2
 
4
- export default (Rule.makeRule({
3
+ export default Rule.makeRule({
5
4
  name: "image-spaces-around-urls",
6
5
  severity: Rule.Severity.ERROR,
7
6
  selector: "image",
@@ -32,4 +31,4 @@ Whitespace in image URLs causes translation difficulties.`;
32
31
  }
33
32
  }
34
33
  },
35
- }): Rule);
34
+ }) as Rule;
@@ -1,5 +1,4 @@
1
- // @flow
2
- import Rule from "../rule.js";
1
+ import Rule from "../rule";
3
2
 
4
3
  // Normally we have one rule per file. But since our selector class
5
4
  // can't match specific widget types directly, this rule implements
@@ -7,7 +6,7 @@ import Rule from "../rule.js";
7
6
  // slightly increase efficiency, but it means that if there is more
8
7
  // than one problem with an image widget, the user will only see one
9
8
  // problem at a time.
10
- export default (Rule.makeRule({
9
+ export default Rule.makeRule({
11
10
  name: "image-widget",
12
11
  severity: Rule.Severity.WARNING,
13
12
  selector: "widget",
@@ -47,4 +46,4 @@ This image's alt text is only ${alt.trim().length} characters long.`;
47
46
  Don't include math expressions in image captions.`;
48
47
  }
49
48
  },
50
- }): Rule);
49
+ }) as Rule;
@@ -1,11 +1,10 @@
1
- // @flow
2
- import Rule from "../rule.js";
1
+ import Rule from "../rule";
3
2
 
4
- export default (Rule.makeRule({
3
+ export default Rule.makeRule({
5
4
  name: "link-click-here",
6
5
  severity: Rule.Severity.WARNING,
7
6
  selector: "link",
8
7
  pattern: /click here/i,
9
8
  message: `Inappropriate link text:
10
9
  Do not use the words "click here" in links.`,
11
- }): Rule);
10
+ }) as Rule;