@valueerror/ltjs-lang-en 0.0.0-stage → 0.1.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 (158) hide show
  1. package/LICENSE +232 -0
  2. package/NOTICE +10 -0
  3. package/README.md +25 -2
  4. package/index.js +34 -0
  5. package/licenses/LGPL-2.1.txt +504 -0
  6. package/licenses/english-pos-dict.pom.xml +135 -0
  7. package/licenses/resource_en_12dicts-readme.html +738 -0
  8. package/licenses/resource_en_agid-readme.txt +340 -0
  9. package/licenses/resource_en_pos-readme.txt +115 -0
  10. package/package.json +60 -4
  11. package/resource-root.js +4 -0
  12. package/resources/META-INF/org/languagetool/language-module.properties +1 -0
  13. package/resources/en-chunker.bin +0 -0
  14. package/resources/en-pos-maxent.bin +0 -0
  15. package/resources/en-token.bin +0 -0
  16. package/resources/org/languagetool/resource/en/12dicts-readme.html +738 -0
  17. package/resources/org/languagetool/resource/en/added.txt +446 -0
  18. package/resources/org/languagetool/resource/en/added_custom.txt +4 -0
  19. package/resources/org/languagetool/resource/en/agid-readme.txt +340 -0
  20. package/resources/org/languagetool/resource/en/compounds.txt +9059 -0
  21. package/resources/org/languagetool/resource/en/confusion_sets.txt +871 -0
  22. package/resources/org/languagetool/resource/en/disambiguation.xml +17238 -0
  23. package/resources/org/languagetool/resource/en/do-not-synthesize.txt +13 -0
  24. package/resources/org/languagetool/resource/en/en-US-GB.txt +4804 -0
  25. package/resources/org/languagetool/resource/en/en.sor +211 -0
  26. package/resources/org/languagetool/resource/en/english.dict +0 -0
  27. package/resources/org/languagetool/resource/en/english.info +8 -0
  28. package/resources/org/languagetool/resource/en/english_synth.dict +0 -0
  29. package/resources/org/languagetool/resource/en/english_synth.info +7 -0
  30. package/resources/org/languagetool/resource/en/english_tags.txt +88 -0
  31. package/resources/org/languagetool/resource/en/hunspell/en_AU.dict +0 -0
  32. package/resources/org/languagetool/resource/en/hunspell/en_AU.info +16 -0
  33. package/resources/org/languagetool/resource/en/hunspell/en_CA.dict +0 -0
  34. package/resources/org/languagetool/resource/en/hunspell/en_CA.info +13 -0
  35. package/resources/org/languagetool/resource/en/hunspell/en_GB.dict +0 -0
  36. package/resources/org/languagetool/resource/en/hunspell/en_GB.info +15 -0
  37. package/resources/org/languagetool/resource/en/hunspell/en_NZ.dict +0 -0
  38. package/resources/org/languagetool/resource/en/hunspell/en_NZ.info +18 -0
  39. package/resources/org/languagetool/resource/en/hunspell/en_US.dict +0 -0
  40. package/resources/org/languagetool/resource/en/hunspell/en_US.info +15 -0
  41. package/resources/org/languagetool/resource/en/hunspell/en_ZA.dict +0 -0
  42. package/resources/org/languagetool/resource/en/hunspell/en_ZA.info +16 -0
  43. package/resources/org/languagetool/resource/en/hunspell/ignore.txt +11070 -0
  44. package/resources/org/languagetool/resource/en/hunspell/prohibit.txt +383 -0
  45. package/resources/org/languagetool/resource/en/hunspell/prohibit_custom.txt +1 -0
  46. package/resources/org/languagetool/resource/en/hunspell/spelling.txt +477 -0
  47. package/resources/org/languagetool/resource/en/hunspell/spelling_custom.txt +1 -0
  48. package/resources/org/languagetool/resource/en/hunspell/spelling_en-AU.txt +34 -0
  49. package/resources/org/languagetool/resource/en/hunspell/spelling_en-CA.txt +28 -0
  50. package/resources/org/languagetool/resource/en/hunspell/spelling_en-GB.txt +44 -0
  51. package/resources/org/languagetool/resource/en/hunspell/spelling_en-NZ.txt +31 -0
  52. package/resources/org/languagetool/resource/en/hunspell/spelling_en-US.txt +41 -0
  53. package/resources/org/languagetool/resource/en/hunspell/spelling_en-ZA.txt +32 -0
  54. package/resources/org/languagetool/resource/en/hunspell/spelling_merged.txt +0 -0
  55. package/resources/org/languagetool/resource/en/multiwords.txt +8210 -0
  56. package/resources/org/languagetool/resource/en/pos-readme.txt +115 -0
  57. package/resources/org/languagetool/resource/en/removed.txt +31 -0
  58. package/resources/org/languagetool/resource/en/removed_custom.txt +4 -0
  59. package/resources/org/languagetool/resource/en/specific_case.txt +5621 -0
  60. package/resources/org/languagetool/resource/en/word_definitions.txt +1510 -0
  61. package/resources/org/languagetool/rules/en/coherency.txt +2501 -0
  62. package/resources/org/languagetool/rules/en/contractions.txt +198 -0
  63. package/resources/org/languagetool/rules/en/det_a.txt +959 -0
  64. package/resources/org/languagetool/rules/en/det_an.txt +4080 -0
  65. package/resources/org/languagetool/rules/en/diacritics.txt +1415 -0
  66. package/resources/org/languagetool/rules/en/en-AU/grammar.xml +171 -0
  67. package/resources/org/languagetool/rules/en/en-CA/grammar.xml +197 -0
  68. package/resources/org/languagetool/rules/en/en-GB/grammar.xml +555 -0
  69. package/resources/org/languagetool/rules/en/en-GB/replace.txt +104 -0
  70. package/resources/org/languagetool/rules/en/en-GB/style.xml +302 -0
  71. package/resources/org/languagetool/rules/en/en-NZ/grammar.xml +171 -0
  72. package/resources/org/languagetool/rules/en/en-NZ/replace.txt +5 -0
  73. package/resources/org/languagetool/rules/en/en-US/grammar.xml +913 -0
  74. package/resources/org/languagetool/rules/en/en-US/replace.txt +74 -0
  75. package/resources/org/languagetool/rules/en/en-US/style.xml +524 -0
  76. package/resources/org/languagetool/rules/en/grammar-l2-de.xml +227 -0
  77. package/resources/org/languagetool/rules/en/grammar-l2-fr.xml +39 -0
  78. package/resources/org/languagetool/rules/en/grammar.xml +142537 -0
  79. package/resources/org/languagetool/rules/en/redundancies.txt +866 -0
  80. package/resources/org/languagetool/rules/en/remote-rule-filters.xml +3622 -0
  81. package/resources/org/languagetool/rules/en/replace.txt +221 -0
  82. package/resources/org/languagetool/rules/en/replace_custom.txt +7 -0
  83. package/resources/org/languagetool/rules/en/replace_profanity.txt +540 -0
  84. package/resources/org/languagetool/rules/en/style.xml +12556 -0
  85. package/resources/org/languagetool/rules/en/synonyms.txt +42 -0
  86. package/resources/org/languagetool/rules/en/wordiness.txt +1061 -0
  87. package/resources/org/languagetool/rules/en/wrongWordInContext.txt +14 -0
  88. package/src/lang/en/chunking/EnglishChunkFilter.js +108 -0
  89. package/src/lang/en/chunking/EnglishChunker.js +135 -0
  90. package/src/lang/en/language/AmericanEnglish.js +73 -0
  91. package/src/lang/en/language/AustralianEnglish.js +42 -0
  92. package/src/lang/en/language/BritishEnglish.js +91 -0
  93. package/src/lang/en/language/CanadianEnglish.js +70 -0
  94. package/src/lang/en/language/English.js +398 -0
  95. package/src/lang/en/language/NewZealandEnglish.js +44 -0
  96. package/src/lang/en/language/SouthAfricanEnglish.js +40 -0
  97. package/src/lang/en/language/id2prioBritishEnglish.js +6 -0
  98. package/src/lang/en/language/id2prioEnglish.js +333 -0
  99. package/src/lang/en/rules/AbstractEnglishSpellerRule.js +677 -0
  100. package/src/lang/en/rules/AbstractEnglishSpellerRuleData.js +778 -0
  101. package/src/lang/en/rules/AdvancedSynthesizerFilter.js +12 -0
  102. package/src/lang/en/rules/AdverbFilter.js +538 -0
  103. package/src/lang/en/rules/AmericanReplaceRule.js +57 -0
  104. package/src/lang/en/rules/AvsAnData.js +37 -0
  105. package/src/lang/en/rules/AvsAnRule.js +182 -0
  106. package/src/lang/en/rules/BritishReplaceRule.js +57 -0
  107. package/src/lang/en/rules/CompoundRule.js +150 -0
  108. package/src/lang/en/rules/ConsistentApostrophesRule.js +87 -0
  109. package/src/lang/en/rules/ContractionSpellingRule.js +64 -0
  110. package/src/lang/en/rules/DateCheckFilter.js +58 -0
  111. package/src/lang/en/rules/DateFilterHelper.js +51 -0
  112. package/src/lang/en/rules/EnglishConvertToSentenceCaseFilter.js +17 -0
  113. package/src/lang/en/rules/EnglishDashRule.js +42 -0
  114. package/src/lang/en/rules/EnglishDiacriticsRule.js +67 -0
  115. package/src/lang/en/rules/EnglishMultitokenSpeller.js +15 -0
  116. package/src/lang/en/rules/EnglishNumberInWordFilter.js +38 -0
  117. package/src/lang/en/rules/EnglishPartialPosTagFilter.js +29 -0
  118. package/src/lang/en/rules/EnglishPlainEnglishRule.js +67 -0
  119. package/src/lang/en/rules/EnglishRedundancyRule.js +67 -0
  120. package/src/lang/en/rules/EnglishRepeatedWordsRule.js +212 -0
  121. package/src/lang/en/rules/EnglishSpecificCaseRule.js +47 -0
  122. package/src/lang/en/rules/EnglishSuppressMisspelledSuggestionsFilter.js +12 -0
  123. package/src/lang/en/rules/EnglishUnpairedBracketsRule.js +25 -0
  124. package/src/lang/en/rules/EnglishUnpairedQuotesRule.js +41 -0
  125. package/src/lang/en/rules/EnglishWordRepeatBeginningRule.js +107 -0
  126. package/src/lang/en/rules/EnglishWordRepeatRule.js +126 -0
  127. package/src/lang/en/rules/EnglishWrongWordInContextRule.js +50 -0
  128. package/src/lang/en/rules/FindSuggestionsFilter.js +41 -0
  129. package/src/lang/en/rules/FutureDateFilter.js +25 -0
  130. package/src/lang/en/rules/LongSentenceRule.js +19 -0
  131. package/src/lang/en/rules/MorfologikAmericanSpellerRule.js +69 -0
  132. package/src/lang/en/rules/MorfologikAustralianSpellerRule.js +45 -0
  133. package/src/lang/en/rules/MorfologikBritishSpellerRule.js +47 -0
  134. package/src/lang/en/rules/MorfologikCanadianSpellerRule.js +45 -0
  135. package/src/lang/en/rules/MorfologikNewZealandSpellerRule.js +45 -0
  136. package/src/lang/en/rules/MorfologikSouthAfricanSpellerRule.js +45 -0
  137. package/src/lang/en/rules/NewYearDateFilter.js +25 -0
  138. package/src/lang/en/rules/NewZealandReplaceRule.js +56 -0
  139. package/src/lang/en/rules/NoDisambiguationEnglishPartialPosTagFilter.js +24 -0
  140. package/src/lang/en/rules/OrdinalSuffixFilter.js +33 -0
  141. package/src/lang/en/rules/SimpleReplaceProfanityRule.js +55 -0
  142. package/src/lang/en/rules/SimpleReplaceRule.js +46 -0
  143. package/src/lang/en/rules/StyleTooOftenUsedAdjectiveRule.js +58 -0
  144. package/src/lang/en/rules/StyleTooOftenUsedNounRule.js +58 -0
  145. package/src/lang/en/rules/StyleTooOftenUsedVerbRule.js +58 -0
  146. package/src/lang/en/rules/UnitConversionRule.js +47 -0
  147. package/src/lang/en/rules/UnitConversionRuleImperial.js +57 -0
  148. package/src/lang/en/rules/UnitConversionRuleUS.js +62 -0
  149. package/src/lang/en/rules/VariantInfo.js +23 -0
  150. package/src/lang/en/rules/WordCoherencyRule.js +40 -0
  151. package/src/lang/en/rules/YMDDateCheckFilter.js +25 -0
  152. package/src/lang/en/rules/YMDNewYearDateFilter.js +25 -0
  153. package/src/lang/en/rules/translation/BeoLingusTranslator.js +357 -0
  154. package/src/lang/en/rules/translation/Inflector.js +72 -0
  155. package/src/lang/en/synthesis/EnglishSynthesizer.js +109 -0
  156. package/src/lang/en/tagging/EnglishHybridDisambiguator.js +28 -0
  157. package/src/lang/en/tagging/EnglishTagger.js +78 -0
  158. package/src/lang/en/tokenizers/EnglishWordTokenizer.js +113 -0
@@ -0,0 +1,182 @@
1
+ // org.languagetool.rules.en.AvsAnRule
2
+ import { AnalyzedToken } from '@valueerror/ltjs-core/src/core/AnalyzedToken.js';
3
+ import { AnalyzedTokenReadings } from '@valueerror/ltjs-core/src/core/AnalyzedTokenReadings.js';
4
+ import { Categories } from '@valueerror/ltjs-core/src/core/rules/model/Category.js';
5
+ import { ITSIssueType } from '@valueerror/ltjs-core/src/core/rules/model/ITSIssueType.js';
6
+ import { Example } from '@valueerror/ltjs-core/src/core/rules/model/Examples.js';
7
+ import { Rule } from '@valueerror/ltjs-core/src/core/rules/model/Rule.js';
8
+ import { RuleMatch } from '@valueerror/ltjs-core/src/core/rules/model/RuleMatch.js';
9
+ import { getUrl } from '@valueerror/ltjs-core/src/core/Tools.js';
10
+ import { isAllUppercase, isEmpty, isMixedCase, lowercaseFirstCharIfCapitalized, startsWithUppercase } from '@valueerror/ltjs-core/src/core/text/StringTools.js';
11
+ import { Character } from '@valueerror/ltjs-core/src/lib/java/Character.js';
12
+ import { JavaEnum } from '@valueerror/ltjs-core/src/lib/java/JavaEnum.js';
13
+ import { NullPointerException } from '@valueerror/ltjs-core/src/lib/java/errors.js';
14
+ import { Pattern } from '@valueerror/ltjs-core/src/lib/java/regex/index.js';
15
+ import { equalsIgnoreCase, toLowerCase } from '@valueerror/ltjs-core/src/lib/java/strings.js';
16
+ import { getWordsRequiringA, getWordsRequiringAn } from './AvsAnData.js';
17
+
18
+ const cleanupPattern = Pattern.compile('[^αa-zA-Z0-9.;,:\']');
19
+ const delimPattern = Pattern.compile('[-"“\'‘()\\[\\]]+');
20
+ const dashQuotePattern = Pattern.compile('[-\']');
21
+ const anPrefixes = Pattern.compile('^(unidentif|uni[mn])[a-z]+$', Pattern.CASE_INSENSITIVE);
22
+ const anExceptionPrefixes = Pattern.compile('^(eu|one|uni|u[rst][aeiou])[a-z]*$', Pattern.CASE_INSENSITIVE);
23
+
24
+ // Java: AvsAnRule.Determiner
25
+ export class Determiner extends JavaEnum {
26
+ static FQCN = 'org.languagetool.rules.en.AvsAnRule.Determiner';
27
+ static A = new Determiner('A', 0);
28
+ static AN = new Determiner('AN', 1);
29
+ static A_OR_AN = new Determiner('A_OR_AN', 2);
30
+ static UNKNOWN = new Determiner('UNKNOWN', 3);
31
+ }
32
+
33
+ // Java: AvsAnRule#isVowel(char)
34
+ function isVowel(c) {
35
+ const lc = Character.toLowerCase(c);
36
+ return lc === 0x61 || lc === 0x65 || lc === 0x69 || lc === 0x6f || lc === 0x75;
37
+ }
38
+
39
+ // Java: AvsAnRule
40
+ export class AvsAnRule extends Rule {
41
+ static FQCN = 'org.languagetool.rules.en.AvsAnRule';
42
+ static Determiner = Determiner;
43
+
44
+ // Java: AvsAnRule#AvsAnRule(ResourceBundle)
45
+ constructor(messages) {
46
+ super();
47
+ this.setCategory(Categories.MISC.getCategory(messages));
48
+ this.setLocQualityIssueType(ITSIssueType.Misspelling);
49
+ this.setUrl(getUrl('https://languagetool.org/insights/post/indefinite-articles/'));
50
+ this.addExamplePair(Example.wrong('The train arrived <marker>a hour</marker> ago.'),
51
+ Example.fixed('The train arrived <marker>an hour</marker> ago.'));
52
+ }
53
+
54
+ // Java: AvsAnRule#getId()
55
+ getId() {
56
+ return 'EN_A_VS_AN';
57
+ }
58
+
59
+ // Java: AvsAnRule#getDescription()
60
+ getDescription() {
61
+ return "Use of 'a' vs. 'an'";
62
+ }
63
+
64
+ // Java: AvsAnRule#estimateContextForSureMatch()
65
+ estimateContextForSureMatch() {
66
+ return 1;
67
+ }
68
+
69
+ // Java: AvsAnRule#match(AnalyzedSentence)
70
+ match(sentence) {
71
+ const ruleMatches = [];
72
+ const tokens = sentence.getTokensWithoutWhitespace();
73
+ let prevTokenIndex = 0;
74
+ let isSentenceStart;
75
+ let equalsA;
76
+ let equalsAn;
77
+ for (let i = 1; i < tokens.length; i++) { // ignoring token 0, i.e., SENT_START
78
+ const token = tokens[i];
79
+ const prevTokenStr = prevTokenIndex > 0 ? tokens[prevTokenIndex].getToken() : null;
80
+ isSentenceStart = prevTokenIndex === 1;
81
+ if (!isSentenceStart) {
82
+ equalsA = prevTokenStr === 'a';
83
+ equalsAn = prevTokenStr === 'an';
84
+ } else {
85
+ equalsA = prevTokenStr !== null && equalsIgnoreCase('a', prevTokenStr);
86
+ equalsAn = prevTokenStr !== null && equalsIgnoreCase('an', prevTokenStr);
87
+ }
88
+ if (equalsA || equalsAn) {
89
+ const determiner = AvsAnRule.getCorrectDeterminerFor(token);
90
+ let msg = null;
91
+ if (equalsA && determiner === Determiner.AN) {
92
+ const replacement = startsWithUppercase(prevTokenStr) ? 'An' : 'an';
93
+ msg = `Use <suggestion>${replacement}</suggestion> instead of '${prevTokenStr}' if the following ` +
94
+ "word starts with a vowel sound, e.g. 'an article', 'an hour'.";
95
+ } else if (equalsAn && determiner === Determiner.A) {
96
+ const replacement = startsWithUppercase(prevTokenStr) ? 'A' : 'a';
97
+ msg = `Use <suggestion>${replacement}</suggestion> instead of '${prevTokenStr}' if the following ` +
98
+ "word doesn't start with a vowel sound, e.g. 'a sentence', 'a university'.";
99
+ }
100
+ if (msg !== null) {
101
+ const match = new RuleMatch(
102
+ this, sentence, tokens[prevTokenIndex].getStartPos(), tokens[prevTokenIndex].getEndPos(),
103
+ tokens[prevTokenIndex].getStartPos(), token.getEndPos(), msg, 'Wrong article');
104
+ ruleMatches.push(match);
105
+ }
106
+ }
107
+ let nextToken = '';
108
+ if (i + 1 < tokens.length) {
109
+ nextToken = tokens[i + 1].getToken();
110
+ }
111
+ if (token.hasPosTag('DT')) {
112
+ prevTokenIndex = i;
113
+ } else if (nextToken.length > 1 && delimPattern.matcher(token.getToken()).matches()) {
114
+ // skip e.g. the quote in >>an "industry party"<<
115
+ } else {
116
+ prevTokenIndex = 0;
117
+ }
118
+ }
119
+ return this.toRuleMatchArray(ruleMatches);
120
+ }
121
+
122
+ /**
123
+ * Adds "a" or "an" to the English noun (suggestion of the proper indefinite article).
124
+ */
125
+ // Java: AvsAnRule#suggestAorAn(String)
126
+ suggestAorAn(origWord) {
127
+ const token = new AnalyzedTokenReadings(new AnalyzedToken(origWord, null, null), 0);
128
+ const determiner = AvsAnRule.getCorrectDeterminerFor(token);
129
+ if (determiner === Determiner.A || determiner === Determiner.A_OR_AN) {
130
+ return `a ${lowercaseFirstCharIfCapitalized(origWord)}`;
131
+ } else if (determiner === Determiner.AN) {
132
+ return `an ${lowercaseFirstCharIfCapitalized(origWord)}`;
133
+ }
134
+ return origWord;
135
+ }
136
+
137
+ // Java: AvsAnRule#getCorrectDeterminerFor(AnalyzedTokenReadings)
138
+ static getCorrectDeterminerFor(token) {
139
+ if (token === null || token === undefined) {
140
+ throw new NullPointerException('Cannot invoke "org.languagetool.AnalyzedTokenReadings.getToken()" because "token" is null');
141
+ }
142
+ let word = token.getToken();
143
+ let determiner = Determiner.UNKNOWN;
144
+ const parts = dashQuotePattern.split(word); // for example, in "one-way" only "one" is relevant
145
+ const anPrefix = anPrefixes.matcher(token.getToken());
146
+ const anExceptionPrefix = anExceptionPrefixes.matcher(token.getToken());
147
+ if (parts.length >= 1 && !equalsIgnoreCase(parts[0], 'a')) { // avoid false alarm on "A-levels are..."
148
+ word = parts[0];
149
+ }
150
+ if (token.isWhitespaceBefore() || word !== '-') { // e.g., 'a- or anti- are prefixes'
151
+ word = cleanupPattern.matcher(word).replaceAll(''); // e.g. >>an "industry party"<<
152
+ if (isEmpty(word)) {
153
+ return Determiner.UNKNOWN;
154
+ }
155
+ }
156
+ if (getWordsRequiringA().has(toLowerCase(word)) || getWordsRequiringA().has(word)) {
157
+ determiner = Determiner.A;
158
+ }
159
+ if (getWordsRequiringAn().has(toLowerCase(word)) || getWordsRequiringAn().has(word)) {
160
+ if (determiner === Determiner.A) {
161
+ determiner = Determiner.A_OR_AN; // e.g. for 'historical'
162
+ } else {
163
+ determiner = Determiner.AN;
164
+ }
165
+ }
166
+ if (determiner === Determiner.UNKNOWN) {
167
+ const tokenFirstChar = word.charCodeAt(0);
168
+ if (isAllUppercase(word) || isMixedCase(word)) {
169
+ // we don't know how all-uppercase words (often abbreviations) are pronounced,
170
+ // so never complain about these
171
+ determiner = Determiner.UNKNOWN;
172
+ } else if (anPrefix.find()) {
173
+ determiner = Determiner.AN;
174
+ } else if (isVowel(tokenFirstChar) && !anExceptionPrefix.find()) {
175
+ determiner = Determiner.AN;
176
+ } else {
177
+ determiner = Determiner.A;
178
+ }
179
+ }
180
+ return determiner;
181
+ }
182
+ }
@@ -0,0 +1,57 @@
1
+ // org.languagetool.rules.en.BritishReplaceRule
2
+ import { AbstractSimpleReplaceRule2 } from '@valueerror/ltjs-core/src/core/rules/AbstractSimpleReplaceRule2.js';
3
+ import { Categories } from '@valueerror/ltjs-core/src/core/rules/model/Category.js';
4
+ import { ITSIssueType } from '@valueerror/ltjs-core/src/core/rules/model/ITSIssueType.js';
5
+ import { Example } from '@valueerror/ltjs-core/src/core/rules/model/Examples.js';
6
+ import { Objects } from '@valueerror/ltjs-core/src/lib/java/Objects.js';
7
+ import { Locale } from '@valueerror/ltjs-core/src/lib/java/Locale.js';
8
+ import { BritishEnglish } from '../language/BritishEnglish.js';
9
+
10
+ const EN_GB_LOCALE = new Locale('en-GB');
11
+
12
+ // Java: BritishReplaceRule
13
+ export class BritishReplaceRule extends AbstractSimpleReplaceRule2 {
14
+ static FQCN = 'org.languagetool.rules.en.BritishReplaceRule';
15
+ static BRITISH_SIMPLE_REPLACE_RULE = 'EN_GB_SIMPLE_REPLACE';
16
+
17
+ // Java: BritishReplaceRule#getFileNames()
18
+ getFileNames() {
19
+ return [this.path];
20
+ }
21
+
22
+ // Java: BritishReplaceRule(ResourceBundle,String)
23
+ constructor(messages, path) {
24
+ super(messages, BritishEnglish.getInstance());
25
+ this.path = Objects.requireNonNull(path);
26
+ this.useSubRuleSpecificIds();
27
+ this.setCategory(Categories.STYLE.getCategory(messages));
28
+ this.setLocQualityIssueType(ITSIssueType.LocaleViolation);
29
+ this.addExamplePair(Example.wrong("We can produce <marker>drapes</marker> of any size or shape from a choice of over 500 different fabrics."),
30
+ Example.fixed("We can produce <marker>curtains</marker> of any size or shape from a choice of over 500 different fabrics."));
31
+ }
32
+
33
+ // Java: BritishReplaceRule#getId()
34
+ getId() {
35
+ return BritishReplaceRule.BRITISH_SIMPLE_REPLACE_RULE;
36
+ }
37
+
38
+ // Java: BritishReplaceRule#getDescription()
39
+ getDescription() {
40
+ return 'American words easily confused in British English: $match';
41
+ }
42
+
43
+ // Java: BritishReplaceRule#getShort()
44
+ getShort() {
45
+ return 'American word';
46
+ }
47
+
48
+ // Java: BritishReplaceRule#getMessage()
49
+ getMessage() {
50
+ return "'$match' is a common American expression. Consider using expressions more common to British English.";
51
+ }
52
+
53
+ // Java: BritishReplaceRule#getLocale()
54
+ getLocale() {
55
+ return EN_GB_LOCALE;
56
+ }
57
+ }
@@ -0,0 +1,150 @@
1
+ // org.languagetool.rules.en.CompoundRule
2
+ import { AbstractCompoundRule } from '@valueerror/ltjs-core/src/core/rules/AbstractCompoundRule.js';
3
+ import { CompoundRuleData } from '@valueerror/ltjs-core/src/core/rules/CompoundRuleData.js';
4
+ import { Rule } from '@valueerror/ltjs-core/src/core/rules/model/Rule.js';
5
+ import { Example } from '@valueerror/ltjs-core/src/core/rules/model/Examples.js';
6
+ import { PatternTokenBuilder } from '@valueerror/ltjs-core/src/core/patterns/PatternTokenBuilder.js';
7
+ import { token, tokenRegex } from '@valueerror/ltjs-core/src/core/patterns/PatternRuleBuilderHelper.js';
8
+ import { Languages } from '@valueerror/ltjs-core/src/core/Languages.js';
9
+ import '@valueerror/ltjs-core/src/core/disambiguation/DisambiguationPatternRule.js';
10
+ import { Objects } from '@valueerror/ltjs-core/src/lib/java/Objects.js';
11
+ import { getUrl } from '@valueerror/ltjs-core/src/core/Tools.js';
12
+
13
+ let compoundData = null; // Java: static to make sure this gets loaded only once
14
+ let antiPatterns = null; // Java: static ANTI_PATTERNS (built at class load, here on first use)
15
+
16
+ // Java: CompoundRule#ANTI_PATTERNS
17
+ function antiPatternsOf() {
18
+ if (antiPatterns === null) {
19
+ const AMERICAN_ENGLISH = Languages.getLanguageForShortCode('en-US');
20
+ antiPatterns = Rule.makeAntiPatterns([
21
+ [
22
+ tokenRegex("['’`´‘]"),
23
+ token('re'),
24
+ ],
25
+ [ // We well received your email
26
+ new PatternTokenBuilder().posRegex('SENT_START|CC|PCT').build(),
27
+ tokenRegex('we|you|they|I|s?he|it'),
28
+ token('well'),
29
+ new PatternTokenBuilder().posRegex('VB.*').build(),
30
+ ],
31
+ [
32
+ token('how'),
33
+ token('well'),
34
+ new PatternTokenBuilder().posRegex('VB.*').build(),
35
+ ],
36
+ [
37
+ tokenRegex('and|&'),
38
+ token('co'),
39
+ ],
40
+ [ // off-key
41
+ token('power'),
42
+ token('off'),
43
+ token('key'),
44
+ ],
45
+ [ // see saw seen
46
+ token('see'),
47
+ token('saw'),
48
+ token('seen'),
49
+ ],
50
+ [ // moving forward looking for ...
51
+ token('forward'),
52
+ token('looking'),
53
+ new PatternTokenBuilder().posRegex('IN|TO').build(),
54
+ ],
55
+ [ // Go through the store front door
56
+ token('store'),
57
+ token('front'),
58
+ tokenRegex('doors?'),
59
+ ],
60
+ [ // It goes from surface to surface
61
+ token('from'),
62
+ token('surface'),
63
+ token('to'),
64
+ token('surface'),
65
+ ],
66
+ [ // year end
67
+ tokenRegex('senior|junior'),
68
+ token('year'),
69
+ token('end'),
70
+ ],
71
+ [ // under investment
72
+ token('under'),
73
+ token('investment'),
74
+ token('banking'),
75
+ ],
76
+ [ // spring clean
77
+ token('spring'),
78
+ tokenRegex('cleans?|cleaned|cleaning'),
79
+ tokenRegex('up|the|my|our|his|her'),
80
+ ],
81
+ [ // Serie A team (A-Team)
82
+ tokenRegex('series?'),
83
+ tokenRegex('a'),
84
+ ],
85
+ [ // They had a hard time sharing their ...
86
+ token('hard'),
87
+ token('time'),
88
+ new PatternTokenBuilder().pos('VBG').build(),
89
+ ],
90
+ [ // the first ever green bond by a municipality
91
+ token('first'),
92
+ tokenRegex('ever'),
93
+ tokenRegex('green'),
94
+ ],
95
+ [ // inter-state.com
96
+ tokenRegex('.+'),
97
+ token('.'),
98
+ tokenRegex('(com|io|de|nl|co|net|org|es)'),
99
+ ],
100
+ ], AMERICAN_ENGLISH);
101
+ }
102
+ return antiPatterns;
103
+ }
104
+
105
+ // Java: CompoundRule (en)
106
+ export class CompoundRule extends AbstractCompoundRule {
107
+ static FQCN = 'org.languagetool.rules.en.CompoundRule';
108
+
109
+ // Java: CompoundRule(ResourceBundle,Language,UserConfig)
110
+ constructor(messages, english, userConfig) {
111
+ super(messages, english, userConfig,
112
+ 'This word is normally spelled with a hyphen.',
113
+ 'This word is normally spelled as one.',
114
+ 'This expression is normally spelled as one or with a hyphen.',
115
+ 'Compound');
116
+ this.english = english;
117
+ super.useSubRuleSpecificIds();
118
+ this.addExamplePair(Example.wrong('I now have a <marker>part time</marker> job.'),
119
+ Example.fixed('I now have a <marker>part-time</marker> job.'));
120
+ this.setUrl(getUrl('https://languagetool.org/insights/post/hyphen/'));
121
+ }
122
+
123
+ // Java: CompoundRule#getId()
124
+ getId() {
125
+ return 'EN_COMPOUNDS';
126
+ }
127
+
128
+ // Java: CompoundRule#getDescription()
129
+ getDescription() {
130
+ return 'Hyphenated words: $match';
131
+ }
132
+
133
+ // Java: CompoundRule#getCompoundRuleData()
134
+ getCompoundRuleData() {
135
+ if (compoundData === null) {
136
+ compoundData = new CompoundRuleData('/en/compounds.txt');
137
+ }
138
+ return compoundData;
139
+ }
140
+
141
+ // Java: CompoundRule#getAntiPatterns()
142
+ getAntiPatterns() {
143
+ return antiPatternsOf();
144
+ }
145
+
146
+ // Java: CompoundRule#isMisspelled(String)
147
+ isMisspelled(word) {
148
+ return Objects.requireNonNull(this.english.getDefaultSpellingRule()).isMisspelled(word);
149
+ }
150
+ }
@@ -0,0 +1,87 @@
1
+ // org.languagetool.rules.en.ConsistentApostrophesRule
2
+ import { TextLevelRule } from '@valueerror/ltjs-core/src/core/rules/model/TextLevelRule.js';
3
+ import { RuleMatch } from '@valueerror/ltjs-core/src/core/rules/model/RuleMatch.js';
4
+ import { Example } from '@valueerror/ltjs-core/src/core/rules/model/Examples.js';
5
+ import { getUrl } from '@valueerror/ltjs-core/src/core/Tools.js';
6
+ import { javaReplace } from '@valueerror/ltjs-core/src/lib/java/strings.js';
7
+
8
+ // Java: ConsistentApostrophesRule
9
+ export class ConsistentApostrophesRule extends TextLevelRule {
10
+ static FQCN = 'org.languagetool.rules.en.ConsistentApostrophesRule';
11
+
12
+ // Java: ConsistentApostrophesRule(ResourceBundle)
13
+ constructor(messages) {
14
+ super(messages);
15
+ this.setDefaultTempOff(); // TODO
16
+ this.setUrl(getUrl('https://languagetool.org/insights/post/punctuation-guide/#what-is-an-apostrophe'));
17
+ this.addExamplePair(Example.wrong('It\'s nice, but it <marker>doesn’t</marker> work.'),
18
+ Example.fixed('It\'s nice, but it <marker>doesn\'t</marker> work.'));
19
+ }
20
+
21
+ // Java: ConsistentApostrophesRule#getId()
22
+ getId() {
23
+ return 'EN_CONSISTENT_APOS';
24
+ }
25
+
26
+ // Java: ConsistentApostrophesRule#getDescription()
27
+ getDescription() {
28
+ return 'Checks if the two types of apostrophes (\' and ’) are used consistently in a text.';
29
+ }
30
+
31
+ // Java: ConsistentApostrophesRule#match(List)
32
+ match(sentences) {
33
+ const matches = [];
34
+ let pos = 0;
35
+ const hasTwoTypes = this.hasTwoApostropheTypes(sentences);
36
+ if (!hasTwoTypes) {
37
+ return this.toRuleMatchArray(matches);
38
+ }
39
+ for (const sentence of sentences) {
40
+ const tokens = sentence.getTokens();
41
+ for (const token of tokens) {
42
+ let message = null;
43
+ let repl = null;
44
+ if (token !== null && token.getToken().includes('\'') && !token.hasTypographicApostrophe()) {
45
+ message = 'You used a typewriter-style apostrophe here, but a typographic apostrophe elsewhere in this text.';
46
+ repl = javaReplace(token.getToken(), '\'', '’');
47
+ } else if (token !== null && token.getToken().includes('\'') && token.hasTypographicApostrophe()) {
48
+ message = 'You used a typographic apostrophe here, but a typewriter-style apostrophe elsewhere in this text.';
49
+ repl = token.getToken();
50
+ }
51
+ if (message !== null) {
52
+ const match = new RuleMatch(this, sentence, pos + token.getStartPos(), pos + token.getEndPos(),
53
+ message + ' Both are correct, but consider using the same type everywhere in your text.');
54
+ match.setSuggestedReplacement(repl);
55
+ matches.push(match);
56
+ }
57
+ }
58
+ pos += sentence.getCorrectedTextLength();
59
+ }
60
+ return this.toRuleMatchArray(matches);
61
+ }
62
+
63
+ // Java: ConsistentApostrophesRule#hasTwoApostropheTypes(List)
64
+ hasTwoApostropheTypes(sentences) {
65
+ let hasTypewriterStyle = false;
66
+ let hasTypographicStyle = false;
67
+ for (const sentence of sentences) {
68
+ const tokens = sentence.getTokens();
69
+ for (const token of tokens) {
70
+ if (token !== null && token.getToken().includes('\'') && !token.hasTypographicApostrophe()) {
71
+ hasTypewriterStyle = true;
72
+ } else if (token !== null && token.getToken().includes('\'') && token.hasTypographicApostrophe()) {
73
+ hasTypographicStyle = true;
74
+ }
75
+ if (hasTypewriterStyle && hasTypographicStyle) {
76
+ return true;
77
+ }
78
+ }
79
+ }
80
+ return false;
81
+ }
82
+
83
+ // Java: ConsistentApostrophesRule#minToCheckParagraph()
84
+ minToCheckParagraph() {
85
+ return -1;
86
+ }
87
+ }
@@ -0,0 +1,64 @@
1
+ // org.languagetool.rules.en.ContractionSpellingRule
2
+ import { AbstractSimpleReplaceRule } from '@valueerror/ltjs-core/src/core/rules/AbstractSimpleReplaceRule.js';
3
+ import { Categories } from '@valueerror/ltjs-core/src/core/rules/model/Category.js';
4
+ import { ITSIssueType } from '@valueerror/ltjs-core/src/core/rules/model/ITSIssueType.js';
5
+ import { Example } from '@valueerror/ltjs-core/src/core/rules/model/Examples.js';
6
+ import { Locale } from '@valueerror/ltjs-core/src/lib/java/Locale.js';
7
+ import { getUrl } from '@valueerror/ltjs-core/src/core/Tools.js';
8
+
9
+ let wrongWords = null; // Java: static wrongWords = loadFromPath("/en/contractions.txt")
10
+ const EN_LOCALE = new Locale('en');
11
+
12
+ // Java: ContractionSpellingRule
13
+ export class ContractionSpellingRule extends AbstractSimpleReplaceRule {
14
+ static FQCN = 'org.languagetool.rules.en.ContractionSpellingRule';
15
+ static CONTRACTION_SPELLING_RULE = 'EN_CONTRACTION_SPELLING';
16
+
17
+ // Java: ContractionSpellingRule#getWrongWords()
18
+ getWrongWords() {
19
+ if (wrongWords === null) wrongWords = AbstractSimpleReplaceRule.loadFromPath('/en/contractions.txt');
20
+ return wrongWords;
21
+ }
22
+
23
+ // Java: ContractionSpellingRule(ResourceBundle,Language)
24
+ constructor(messages, language) {
25
+ super(messages, language);
26
+ ContractionSpellingRule.prototype.getWrongWords.call(this); // Java: static initializer runs at class load
27
+ super.setCategory(Categories.TYPOS.getCategory(messages));
28
+ this.setLocQualityIssueType(ITSIssueType.Misspelling);
29
+ this.addExamplePair(Example.wrong('We <marker>havent</marker> earned anything.'),
30
+ Example.fixed("We <marker>haven't</marker> earned anything."));
31
+ this.setUrl(getUrl('https://languagetool.org/insights/post/grammar-contractions/'));
32
+ super.setCheckLemmas(false);
33
+ }
34
+
35
+ // Java: ContractionSpellingRule#getId()
36
+ getId() {
37
+ return ContractionSpellingRule.CONTRACTION_SPELLING_RULE;
38
+ }
39
+
40
+ // Java: ContractionSpellingRule#getDescription()
41
+ getDescription() {
42
+ return 'Spelling of English contractions';
43
+ }
44
+
45
+ // Java: ContractionSpellingRule#getShort()
46
+ getShort() {
47
+ return 'Spelling mistake';
48
+ }
49
+
50
+ // Java: ContractionSpellingRule#getMessage(String,List)
51
+ getMessage() {
52
+ return 'Possible spelling mistake found.';
53
+ }
54
+
55
+ // Java: ContractionSpellingRule#isCaseSensitive()
56
+ isCaseSensitive() {
57
+ return true;
58
+ }
59
+
60
+ // Java: ContractionSpellingRule#getLocale()
61
+ getLocale() {
62
+ return EN_LOCALE;
63
+ }
64
+ }
@@ -0,0 +1,58 @@
1
+ // org.languagetool.rules.en.DateCheckFilter
2
+ import { registerClass } from '@valueerror/ltjs-core/src/core/resources/ClassBroker.js';
3
+ import { Integer } from '@valueerror/ltjs-core/src/lib/java/int.js';
4
+ import { AbstractDateCheckWithSuggestionsFilter } from '@valueerror/ltjs-core/src/core/rules/AbstractDateCheckWithSuggestionsFilter.js';
5
+ import { isNumeric } from '@valueerror/ltjs-core/src/core/text/StringTools.js';
6
+ import { DateFilterHelper } from './DateFilterHelper.js';
7
+
8
+ // Java: DateCheckFilter
9
+ export class DateCheckFilter extends AbstractDateCheckWithSuggestionsFilter {
10
+ static FQCN = 'org.languagetool.rules.en.DateCheckFilter';
11
+ static JAVA_ABSTRACT = false;
12
+ static JAVA_CONSTRUCTORS = [{ params: [], text: 'public org.languagetool.rules.en.DateCheckFilter()' }];
13
+
14
+ dateFilterHelper = new DateFilterHelper();
15
+
16
+ // Java: DateCheckFilter#getCalendar()
17
+ getCalendar() {
18
+ return this.dateFilterHelper.getCalendar();
19
+ }
20
+
21
+ // Java: DateCheckFilter#getErrorMessageWrongYear()
22
+ getErrorMessageWrongYear() {
23
+ return 'This date is wrong. Did you mean "{currentYear}"?';
24
+ }
25
+
26
+ // Java: DateCheckFilter#getDayOfWeek(String) and #getDayOfWeek(Calendar) (overloads, one JS method dispatching on the argument type)
27
+ getDayOfWeek(arg) {
28
+ return this.dateFilterHelper.getDayOfWeek(arg);
29
+ }
30
+
31
+ // Java: DateCheckFilter#getMonth(String)
32
+ getMonth(monthStr) {
33
+ return this.dateFilterHelper.getMonth(monthStr);
34
+ }
35
+
36
+ // Java: DateCheckFilter#getDayStrLikeOriginal(String,String)
37
+ getDayStrLikeOriginal(day, original) {
38
+ if (isNumeric(original)) {
39
+ return day;
40
+ }
41
+ const number = Integer.parseInt(day);
42
+ if (number >= 11 && number <= 13) {
43
+ return number + 'th';
44
+ }
45
+ switch (number % 10) {
46
+ case 1:
47
+ return number + 'st';
48
+ case 2:
49
+ return number + 'nd';
50
+ case 3:
51
+ return number + 'rd';
52
+ default:
53
+ return number + 'th';
54
+ }
55
+ }
56
+ }
57
+
58
+ registerClass(DateCheckFilter.FQCN, DateCheckFilter);
@@ -0,0 +1,51 @@
1
+ // org.languagetool.rules.en.DateFilterHelper (package-private)
2
+ import { Calendar } from '@valueerror/ltjs-core/src/lib/java/Calendar.js';
3
+ import { Locale } from '@valueerror/ltjs-core/src/lib/java/Locale.js';
4
+ import { RuntimeException } from '@valueerror/ltjs-core/src/lib/java/errors.js';
5
+ import { toLowerCase } from '@valueerror/ltjs-core/src/lib/java/strings.js';
6
+ import { trimSpecialCharacters } from '@valueerror/ltjs-core/src/core/text/StringTools.js';
7
+
8
+ // Java: DateFilterHelper
9
+ export class DateFilterHelper {
10
+ static FQCN = 'org.languagetool.rules.en.DateFilterHelper';
11
+
12
+ // Java: DateFilterHelper#getCalendar()
13
+ getCalendar() {
14
+ return Calendar.getInstance(Locale.UK);
15
+ }
16
+
17
+ // Java: DateFilterHelper#getDayOfWeek(String) and #getDayOfWeek(Calendar) (overloads, one JS method dispatching on the argument type)
18
+ getDayOfWeek(arg) {
19
+ if (arg instanceof Calendar) {
20
+ return arg.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.UK);
21
+ }
22
+ const dayStr = arg;
23
+ const day = toLowerCase(trimSpecialCharacters(dayStr));
24
+ if (day.startsWith('su')) return Calendar.SUNDAY;
25
+ if (day.startsWith('mo')) return Calendar.MONDAY;
26
+ if (day.startsWith('tu')) return Calendar.TUESDAY;
27
+ if (day.startsWith('we')) return Calendar.WEDNESDAY;
28
+ if (day.startsWith('th')) return Calendar.THURSDAY;
29
+ if (day.startsWith('fr')) return Calendar.FRIDAY;
30
+ if (day.startsWith('sa')) return Calendar.SATURDAY;
31
+ throw new RuntimeException("Could not find day of week for '" + dayStr + "'");
32
+ }
33
+
34
+ // Java: DateFilterHelper#getMonth(String)
35
+ getMonth(monthStr) {
36
+ const mon = toLowerCase(trimSpecialCharacters(monthStr));
37
+ if (mon.startsWith('jan')) return 1;
38
+ if (mon.startsWith('feb')) return 2;
39
+ if (mon.startsWith('mar')) return 3;
40
+ if (mon.startsWith('apr')) return 4;
41
+ if (mon.startsWith('may')) return 5;
42
+ if (mon.startsWith('jun')) return 6;
43
+ if (mon.startsWith('jul')) return 7;
44
+ if (mon.startsWith('aug')) return 8;
45
+ if (mon.startsWith('sep')) return 9;
46
+ if (mon.startsWith('oct')) return 10;
47
+ if (mon.startsWith('nov')) return 11;
48
+ if (mon.startsWith('dec')) return 12;
49
+ throw new RuntimeException("Could not find month '" + monthStr + "'");
50
+ }
51
+ }
@@ -0,0 +1,17 @@
1
+ // org.languagetool.rules.en.EnglishConvertToSentenceCaseFilter
2
+ import { registerClass } from '@valueerror/ltjs-core/src/core/resources/ClassBroker.js';
3
+ import { ConvertToSentenceCaseFilter } from '@valueerror/ltjs-core/src/core/rules/ConvertToSentenceCaseFilter.js';
4
+
5
+ // Java: EnglishConvertToSentenceCaseFilter
6
+ export class EnglishConvertToSentenceCaseFilter extends ConvertToSentenceCaseFilter {
7
+ static FQCN = 'org.languagetool.rules.en.EnglishConvertToSentenceCaseFilter';
8
+ static JAVA_ABSTRACT = false;
9
+ static JAVA_CONSTRUCTORS = [{ params: [], text: 'public org.languagetool.rules.en.EnglishConvertToSentenceCaseFilter()' }];
10
+
11
+ // Java: EnglishConvertToSentenceCaseFilter#tokenIsException(String)
12
+ tokenIsException(s) {
13
+ return s === 'me';
14
+ }
15
+ }
16
+
17
+ registerClass(EnglishConvertToSentenceCaseFilter.FQCN, EnglishConvertToSentenceCaseFilter);