index.ts 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import { TextlintKernel, TextlintKernelRule, TextlintRuleOptions } from '@textlint/kernel';
  2. import textlintToCodeMirror from 'textlint-message-to-codemirror';
  3. import textlintRuleNoUnmatchedPair from '@textlint-rule/textlint-rule-no-unmatched-pair';
  4. import textlintRuleCommonMisspellings from 'textlint-rule-common-misspellings';
  5. import textlintRuleDateWeekdayMismatch from 'textlint-rule-date-weekday-mismatch';
  6. import textlintRuleEnCapitalization from 'textlint-rule-en-capitalization';
  7. import textlintRuleJaHiraganaKeishikimeishi from 'textlint-rule-ja-hiragana-keishikimeishi';
  8. import textlintRuleJaNoAbusage from 'textlint-rule-ja-no-abusage';
  9. import textlintRuleJaNoInappropriateWords from 'textlint-rule-ja-no-inappropriate-words';
  10. import textlintRuleJaNoMixedPeriod from 'textlint-rule-ja-no-mixed-period';
  11. import textlintRuleJaNoRedundantExpression from 'textlint-rule-ja-no-redundant-expression';
  12. import textlintRuleJaUnnaturalAlphabet from 'textlint-rule-ja-unnatural-alphabet';
  13. import textlintRuleMaxComma from 'textlint-rule-max-comma';
  14. import textlintRuleMaxKanjiContinuousLen from 'textlint-rule-max-kanji-continuous-len';
  15. import textlintRuleMaxTen from 'textlint-rule-max-ten';
  16. import textlintRuleNoDoubleNegativeJa from 'textlint-rule-no-double-negative-ja';
  17. import textlintRuleNoDoubledConjunction from 'textlint-rule-no-doubled-conjunction';
  18. import textlintRuleNoDoubledJoshi from 'textlint-rule-no-doubled-joshi';
  19. import textlintRuleNoDroppingTheRa from 'textlint-rule-no-dropping-the-ra';
  20. import textlintRuleNoHankakuKana from 'textlint-rule-no-hankaku-kana';
  21. import textlintRuleNoKangxiRadicals from 'textlint-rule-no-kangxi-radicals';
  22. import textlintRuleNoMixedZenkakuAndHankakuAlphabet from 'textlint-rule-no-mixed-zenkaku-and-hankaku-alphabet';
  23. import textlintRuleNoNfd from 'textlint-rule-no-nfd';
  24. import textlintRuleNoSurrogatePair from 'textlint-rule-no-surrogate-pair';
  25. import textlintRuleNoZeroWidthSpaces from 'textlint-rule-no-zero-width-spaces';
  26. import textlintRulePeriodInListItem from 'textlint-rule-period-in-list-item';
  27. import textlintRulePreferTariTari from 'textlint-rule-prefer-tari-tari';
  28. import textlintRuleSentenceLength from 'textlint-rule-sentence-length';
  29. import textlintRuleUseSiUnits from 'textlint-rule-use-si-units';
  30. import { AsyncLinter, Annotation } from 'codemirror/addon/lint/lint';
  31. import { loggerFactory } from './utils/logger';
  32. type RulesConfigObj = {
  33. name: string,
  34. options?: unknown,
  35. }
  36. type RuleExtension = {
  37. ext: string
  38. }
  39. const ruleModulesList = {
  40. 'no-unmatched-pair': textlintRuleNoUnmatchedPair,
  41. 'common-misspellings': textlintRuleCommonMisspellings,
  42. 'date-weekday-mismatch': textlintRuleDateWeekdayMismatch,
  43. 'en-capitalization': textlintRuleEnCapitalization,
  44. 'ja-hiragana-keishikimeishi': textlintRuleJaHiraganaKeishikimeishi,
  45. 'ja-no-abusage': textlintRuleJaNoAbusage,
  46. 'ja-no-inappropriate-words': textlintRuleJaNoInappropriateWords,
  47. 'ja-no-mixed-period': textlintRuleJaNoMixedPeriod,
  48. 'ja-no-redundant-expression': textlintRuleJaNoRedundantExpression,
  49. 'ja-unnatural-alphabet': textlintRuleJaUnnaturalAlphabet,
  50. 'max-comma': textlintRuleMaxComma,
  51. 'max-kanji-continuous-len': textlintRuleMaxKanjiContinuousLen,
  52. 'max-ten': textlintRuleMaxTen,
  53. 'no-double-negative-ja': textlintRuleNoDoubleNegativeJa,
  54. 'no-doubled-conjunction': textlintRuleNoDoubledConjunction,
  55. 'no-doubled-joshi': textlintRuleNoDoubledJoshi,
  56. 'no-dropping-the-ra': textlintRuleNoDroppingTheRa,
  57. 'no-hankaku-kana': textlintRuleNoHankakuKana,
  58. 'no-kangxi-radicals': textlintRuleNoKangxiRadicals,
  59. 'no-mixed-zenkaku-and-hankaku-alphabet': textlintRuleNoMixedZenkakuAndHankakuAlphabet,
  60. 'no-nfd': textlintRuleNoNfd,
  61. 'no-surrogate-pair': textlintRuleNoSurrogatePair,
  62. 'no-zero-width-spaces': textlintRuleNoZeroWidthSpaces,
  63. 'period-in-list-item': textlintRulePeriodInListItem,
  64. 'prefer-tari-tari': textlintRulePreferTariTari,
  65. 'sentence-length': textlintRuleSentenceLength,
  66. 'use-si-units': textlintRuleUseSiUnits,
  67. };
  68. const logger = loggerFactory('growi:codemirror:codemirror-textlint');
  69. const kernel = new TextlintKernel();
  70. const textlintOption: TextlintRuleOptions<RuleExtension> = {
  71. ext: '.md',
  72. plugins: [
  73. {
  74. pluginId: 'markdown',
  75. plugin: require('textlint-plugin-markdown'),
  76. },
  77. ],
  78. };
  79. const createSetupRules = (rules, ruleOptions): TextlintKernelRule[] => (
  80. Object.keys(rules).map(ruleName => (
  81. {
  82. ruleId: ruleName,
  83. rule: rules[ruleName],
  84. options: ruleOptions[ruleName],
  85. }
  86. ))
  87. );
  88. export const createValidator = (rulesConfigArray: RulesConfigObj[]): AsyncLinter<RulesConfigObj[]> => {
  89. if (rulesConfigArray != null) {
  90. const filteredConfigArray = rulesConfigArray
  91. .filter((rule) => {
  92. if (ruleModulesList[rule.name] == null) {
  93. logger.error(`Textlint rule ${rule.name} is not installed`);
  94. }
  95. return ruleModulesList[rule.name] != null;
  96. });
  97. const rules = filteredConfigArray
  98. .reduce((rules, rule) => {
  99. rules[rule.name] = ruleModulesList[rule.name];
  100. return rules;
  101. }, {});
  102. const rulesOption = filteredConfigArray
  103. .reduce((rules, rule) => {
  104. rules[rule.name] = rule.options || {};
  105. return rules;
  106. }, {});
  107. Object.assign(
  108. textlintOption,
  109. { rules: createSetupRules(rules, rulesOption) },
  110. );
  111. }
  112. const defaultSetupRules: TextlintKernelRule[] = Object.entries(ruleModulesList)
  113. .map(ruleName => ({
  114. ruleId: ruleName[0],
  115. rule: ruleName[1],
  116. }));
  117. if (rulesConfigArray == null) {
  118. Object.assign(
  119. textlintOption,
  120. { rules: defaultSetupRules },
  121. );
  122. }
  123. return (text, callback) => {
  124. if (!text) {
  125. callback([]);
  126. return;
  127. }
  128. kernel
  129. .lintText(text, textlintOption)
  130. .then((result) => {
  131. const lintMessages = result.messages;
  132. const lintErrors: Annotation[] = lintMessages.map(textlintToCodeMirror);
  133. callback(lintErrors);
  134. });
  135. };
  136. };