@valueerror/ltjs-lang-fr 0.0.0-stage → 0.1.0
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/LICENSE +232 -0
- package/NOTICE +9 -0
- package/README.md +25 -2
- package/index.js +24 -0
- package/licenses/LGPL-2.1.txt +504 -0
- package/licenses/french-pos-dict.pom.xml +115 -0
- package/licenses/resource_fr_README_lexique.txt +30 -0
- package/licenses/resource_fr_hunspell_README_fr.txt +73 -0
- package/package.json +60 -4
- package/resource-root.js +4 -0
- package/resources/META-INF/org/languagetool/language-module.properties +1 -0
- package/resources/org/languagetool/resource/fr/README_lexique.txt +30 -0
- package/resources/org/languagetool/resource/fr/added.txt +477 -0
- package/resources/org/languagetool/resource/fr/added_custom.txt +4 -0
- package/resources/org/languagetool/resource/fr/compounds.txt +1443 -0
- package/resources/org/languagetool/resource/fr/confusion_sets.txt +76 -0
- package/resources/org/languagetool/resource/fr/disambiguation.xml +11391 -0
- package/resources/org/languagetool/resource/fr/fr.sor +162 -0
- package/resources/org/languagetool/resource/fr/french.dict +0 -0
- package/resources/org/languagetool/resource/fr/french.info +20 -0
- package/resources/org/languagetool/resource/fr/french_synth.dict +0 -0
- package/resources/org/languagetool/resource/fr/french_synth.info +4 -0
- package/resources/org/languagetool/resource/fr/french_tags.txt +268 -0
- package/resources/org/languagetool/resource/fr/hunspell/README_fr.txt +73 -0
- package/resources/org/languagetool/resource/fr/hunspell/ignore.txt +1551 -0
- package/resources/org/languagetool/resource/fr/hunspell/prohibit.txt +3 -0
- package/resources/org/languagetool/resource/fr/hunspell/spelling.txt +34735 -0
- package/resources/org/languagetool/resource/fr/hunspell/spelling_custom.txt +1 -0
- package/resources/org/languagetool/resource/fr/hyphenated_words.txt +12864 -0
- package/resources/org/languagetool/resource/fr/multiwords.txt +4886 -0
- package/resources/org/languagetool/resource/fr/removed.txt +5 -0
- package/resources/org/languagetool/resource/fr/removed_custom.txt +4 -0
- package/resources/org/languagetool/rules/fr/grammar.xml +151570 -0
- package/resources/org/languagetool/rules/fr/remote-rule-filters.xml +820 -0
- package/resources/org/languagetool/rules/fr/replace.txt +39 -0
- package/resources/org/languagetool/rules/fr/replace_custom.txt +7 -0
- package/resources/org/languagetool/rules/fr/style.xml +22790 -0
- package/resources/org/languagetool/rules/fr/synonyms.txt +203 -0
- package/src/lang/fr/language/BelgianFrench.js +38 -0
- package/src/lang/fr/language/CanadianFrench.js +38 -0
- package/src/lang/fr/language/French.js +478 -0
- package/src/lang/fr/language/SwissFrench.js +38 -0
- package/src/lang/fr/language/id2prioFrench.js +102 -0
- package/src/lang/fr/rules/AdvancedSynthesizerFilter.js +12 -0
- package/src/lang/fr/rules/CompoundRule.js +47 -0
- package/src/lang/fr/rules/DMYDateCheckFilter.js +31 -0
- package/src/lang/fr/rules/DateCheckFilter.js +35 -0
- package/src/lang/fr/rules/DateFilterHelper.js +55 -0
- package/src/lang/fr/rules/FindSuggestionsFilter.js +80 -0
- package/src/lang/fr/rules/FrenchLazy.js +9 -0
- package/src/lang/fr/rules/FrenchMultitokenSpeller.js +15 -0
- package/src/lang/fr/rules/FrenchNumberInWordFilter.js +29 -0
- package/src/lang/fr/rules/FrenchPartialPosTagFilter.js +29 -0
- package/src/lang/fr/rules/FrenchRepeatedWordsRule.js +76 -0
- package/src/lang/fr/rules/FrenchSuppressMisspelledSuggestionsFilter.js +12 -0
- package/src/lang/fr/rules/InterrogativeVerbFilter.js +159 -0
- package/src/lang/fr/rules/MakeContractionsFilter.js +32 -0
- package/src/lang/fr/rules/MorfologikFrenchSpellerRule.js +262 -0
- package/src/lang/fr/rules/NewYearDateFilter.js +30 -0
- package/src/lang/fr/rules/PostponedAdjectiveConcordanceFilter.js +512 -0
- package/src/lang/fr/rules/QuestionWhitespaceRule.js +171 -0
- package/src/lang/fr/rules/QuestionWhitespaceStrictRule.js +38 -0
- package/src/lang/fr/rules/SimpleReplaceRule.js +63 -0
- package/src/lang/fr/rules/SuggestionsFilter.js +29 -0
- package/src/lang/fr/rules/WordWithDeterminerFilter.js +168 -0
- package/src/lang/fr/synthesis/FrenchSynthesizer.js +36 -0
- package/src/lang/fr/tagging/FrenchHybridDisambiguator.js +28 -0
- package/src/lang/fr/tagging/FrenchTagger.js +176 -0
- package/src/lang/fr/tokenizers/FrenchWordTokenizer.js +164 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// Java: org.languagetool.tokenizers.fr.FrenchWordTokenizer
|
|
2
|
+
import { Pattern } from '@valueerror/ltjs-core/src/lib/java/regex/index.js';
|
|
3
|
+
import { StringTokenizer } from '@valueerror/ltjs-core/src/lib/java/StringTokenizer.js';
|
|
4
|
+
import { toLowerCase } from '@valueerror/ltjs-core/src/lib/java/strings.js';
|
|
5
|
+
import { NullPointerException } from '@valueerror/ltjs-core/src/lib/java/errors.js';
|
|
6
|
+
import { registerComponent, sharedComponent } from '@valueerror/ltjs-core/src/core/language/components.js';
|
|
7
|
+
import { WordTokenizer } from '@valueerror/ltjs-core/src/core/text/tokenizers/WordTokenizer.js';
|
|
8
|
+
import '../tagging/FrenchTagger.js';
|
|
9
|
+
|
|
10
|
+
const wordCharacters = '§©@€£\\$_\\p{L}\\d\\-̀-ͯ¨⁰-°%‰‱&�¬';
|
|
11
|
+
const tokenizerPattern = Pattern.compile(`[${wordCharacters}]+|[^${wordCharacters}]`);
|
|
12
|
+
|
|
13
|
+
const CI = Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE;
|
|
14
|
+
const TYPEWRITER_APOSTROPHE = Pattern.compile('([\\p{L}])\'([\\p{L}1"‘“«])', CI);
|
|
15
|
+
const TYPOGRAPHIC_APOSTROPHE = Pattern.compile('([\\p{L}])’([\\p{L}1"‘“«])', CI);
|
|
16
|
+
const NEARBY_HYPHENS = Pattern.compile('([\\p{L}])-([\\p{L}])-([\\p{L}])', CI);
|
|
17
|
+
const HYPHENS = Pattern.compile('([\\p{L}])-([\\p{L}\\d])', CI);
|
|
18
|
+
const DECIMAL_POINT = Pattern.compile('([\\d])\\.([\\d])', CI);
|
|
19
|
+
const DECIMAL_COMMA = Pattern.compile('([\\d]),([\\d])', CI);
|
|
20
|
+
const SPACE_DIGITS0 = Pattern.compile('([\\d]{4}) ', CI);
|
|
21
|
+
const SPACE_DIGITS = Pattern.compile('([\\d]) ([\\d][\\d][\\d])\\b', CI);
|
|
22
|
+
const SPACE_DIGITS2 = Pattern.compile('([\\d]) ([\\d][\\d][\\d]) ([\\d][\\d][\\d])\\b', CI);
|
|
23
|
+
|
|
24
|
+
const doNotSplit = ['mers-cov', 'mcgraw-hill', 'sars-cov-2', 'sars-cov',
|
|
25
|
+
'ph-metre', 'ph-metres', 'anti-ivg', 'anti-uv', 'anti-vih', 'al-qaïda', "c'est-à-dire", 'add-on', 'add-ons',
|
|
26
|
+
'rendez-vous', 'garde-à-vous', 'chez-eux', 'chez-moi', 'chez-nous', 'chez-soi', 'chez-toi', 'chez-vous', "m'as-tu-vu"];
|
|
27
|
+
|
|
28
|
+
const maxPatterns = 7;
|
|
29
|
+
const patterns = [
|
|
30
|
+
Pattern.compile("^(c['’]te?|m['’]as-tu-vu|c['’]est-à-dire|add-on|add-ons|rendez-vous|garde-à-vous|chez-eux|chez-moi|chez-nous|chez-soi|chez-toi|chez-vous)$", CI),
|
|
31
|
+
Pattern.compile(
|
|
32
|
+
"^([cç]['’]|j['’]|n['’]|m['’]|t['’]|s['’]|l['’]|d['’]|qu['’]|jusqu['’]|lorsqu['’]|puisqu['’]|quoiqu['’])([^\\-]*)(-ce|-elle|-t-elle|-elles|-t-elles|-en|-il|-t-il|-ils|-t-ils|-je|-la|-le|-les|-leur|-lui|-moi|-nous|-on|-t-on|-toi|-tu|-vous|-vs|-y)$",
|
|
33
|
+
CI),
|
|
34
|
+
Pattern.compile(
|
|
35
|
+
"^([cç]['’]|j['’]|n['’]|m['’]|t['’]|s['’]|l['’]|d['’]|qu['’]|jusqu['’]|lorsqu['’]|puisqu['’]|quoiqu['’])([^'’\\-].*)$",
|
|
36
|
+
CI),
|
|
37
|
+
Pattern.compile(
|
|
38
|
+
'^([^\\-\\d]+)(-ce|-t-elle|-t-elles|-elle|-elles|-en|-il|-t-il|-ils|-t-ils|-je|-la|-le|-les|-leur|-lui|-moi|-nous|-on|-t-on|-toi|-tu|-vous|-vs|-y)(-ce|-elle|-t-elle|-elles|-t-elles|-en|-il|-t-il|-ils|-t-ils|-je|-la|-le|-les|-leur|-lui|-moi|-nous|-on|-t-on|-toi|-tu|-vous|-vs|-y)$',
|
|
39
|
+
CI),
|
|
40
|
+
Pattern.compile("^([^\\-]*)(-t|-m)(['’]en|['’]y)$", CI),
|
|
41
|
+
Pattern.compile('^(.*)(-t-elle|-t-elles|-t-il|-t-ils|-t-on)$', CI),
|
|
42
|
+
Pattern.compile(
|
|
43
|
+
'^(.*)(-ce|-elle|-t-elle|-elles|-t-elles|-en|-il|-t-il|-ils|-t-ils|-je|-la|-le|-les|-leur|-lui|-moi|-nous|-on|-t-on|-toi|-tu|-vous|-vs|-y)$',
|
|
44
|
+
CI),
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
// Java: FrenchWordTokenizer
|
|
48
|
+
export class FrenchWordTokenizer extends WordTokenizer {
|
|
49
|
+
static FQCN = 'org.languagetool.tokenizers.fr.FrenchWordTokenizer';
|
|
50
|
+
|
|
51
|
+
// Java: FrenchWordTokenizer#tokenize(String)
|
|
52
|
+
tokenize(text) {
|
|
53
|
+
const l = [];
|
|
54
|
+
if (text === null || text === undefined) throw new NullPointerException('Cannot invoke "String.replace(char, char)" because "text" is null');
|
|
55
|
+
let auxText = text.replaceAll('‐', '-');
|
|
56
|
+
auxText = auxText.replaceAll('‑', '-');
|
|
57
|
+
let matcher;
|
|
58
|
+
// perf: each replacement can only match when its literal character is present (no-match replaceAll returns the input)
|
|
59
|
+
if (auxText.includes("'")) {
|
|
60
|
+
matcher = TYPEWRITER_APOSTROPHE.matcher(auxText);
|
|
61
|
+
auxText = matcher.replaceAll('$1xxFR_APOS_TYPEWxx$2');
|
|
62
|
+
}
|
|
63
|
+
if (auxText.includes('’')) {
|
|
64
|
+
matcher = TYPOGRAPHIC_APOSTROPHE.matcher(auxText);
|
|
65
|
+
auxText = matcher.replaceAll('$1xxFR_APOS_TYPOGxx$2');
|
|
66
|
+
}
|
|
67
|
+
if (auxText.includes('-')) {
|
|
68
|
+
matcher = NEARBY_HYPHENS.matcher(auxText);
|
|
69
|
+
auxText = matcher.replaceAll('$1xxFR_HYPHENxx$2xxFR_HYPHENxx$3');
|
|
70
|
+
matcher = HYPHENS.matcher(auxText);
|
|
71
|
+
auxText = matcher.replaceAll('$1xxFR_HYPHENxx$2');
|
|
72
|
+
}
|
|
73
|
+
if (auxText.includes('.')) {
|
|
74
|
+
matcher = DECIMAL_POINT.matcher(auxText);
|
|
75
|
+
auxText = matcher.replaceAll('$1xxFR_DECIMALPOINTxx$2');
|
|
76
|
+
}
|
|
77
|
+
if (auxText.includes(',')) {
|
|
78
|
+
matcher = DECIMAL_COMMA.matcher(auxText);
|
|
79
|
+
auxText = matcher.replaceAll('$1xxFR_DECIMALCOMMAxx$2');
|
|
80
|
+
}
|
|
81
|
+
if (auxText.includes(' ')) {
|
|
82
|
+
matcher = SPACE_DIGITS2.matcher(auxText);
|
|
83
|
+
auxText = matcher.replaceAll('$1xxFR_SPACExx$2xxFR_SPACExx$3');
|
|
84
|
+
matcher = SPACE_DIGITS0.matcher(auxText);
|
|
85
|
+
auxText = matcher.replaceAll('$1xxFR_SPACE0xx');
|
|
86
|
+
matcher = SPACE_DIGITS.matcher(auxText);
|
|
87
|
+
auxText = matcher.replaceAll('$1xxFR_SPACExx$2');
|
|
88
|
+
}
|
|
89
|
+
auxText = auxText.replaceAll('xxFR_SPACE0xx', ' ');
|
|
90
|
+
|
|
91
|
+
const tokenizerMatcher = tokenizerPattern.matcher(auxText);
|
|
92
|
+
while (tokenizerMatcher.find()) {
|
|
93
|
+
let s = tokenizerMatcher.group();
|
|
94
|
+
if (l.length > 0 && s.length === 1 && s.codePointAt(0) >= 0xFE00 && s.codePointAt(0) <= 0xFE0F) {
|
|
95
|
+
l[l.length - 1] = l[l.length - 1] + s;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
s = s.replaceAll('xxFR_APOS_TYPEWxx', "'")
|
|
99
|
+
.replaceAll('xxFR_APOS_TYPOGxx', '’')
|
|
100
|
+
.replaceAll('xxFR_HYPHENxx', '-')
|
|
101
|
+
.replaceAll('xxFR_DECIMALPOINTxx', '.')
|
|
102
|
+
.replaceAll('xxFR_DECIMALCOMMAxx', ',')
|
|
103
|
+
.replaceAll('xxFR_SPACExx', ' ');
|
|
104
|
+
let matchFound = false;
|
|
105
|
+
while (s.length > 1 && s.startsWith('-')) {
|
|
106
|
+
l.push('-');
|
|
107
|
+
s = s.substring(1);
|
|
108
|
+
}
|
|
109
|
+
let hyphensAtEnd = 0;
|
|
110
|
+
while (s.length > 1 && s.endsWith('-')) {
|
|
111
|
+
s = s.substring(0, s.length - 1);
|
|
112
|
+
hyphensAtEnd++;
|
|
113
|
+
}
|
|
114
|
+
let j = 0;
|
|
115
|
+
// perf: all patterns need an apostrophe or a hyphen
|
|
116
|
+
if (!s.includes('-') && !s.includes("'") && !s.includes('’')) j = maxPatterns;
|
|
117
|
+
while (j < maxPatterns && !matchFound) {
|
|
118
|
+
matcher = patterns[j].matcher(s);
|
|
119
|
+
matchFound = matcher.find();
|
|
120
|
+
j++;
|
|
121
|
+
}
|
|
122
|
+
if (matchFound) {
|
|
123
|
+
for (let i = 1; i <= matcher.groupCount(); i++) {
|
|
124
|
+
const groupStr = matcher.group(i);
|
|
125
|
+
l.push(...this.wordsToAdd(groupStr));
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
l.push(...this.wordsToAdd(s));
|
|
129
|
+
}
|
|
130
|
+
while (hyphensAtEnd > 0) {
|
|
131
|
+
l.push('-');
|
|
132
|
+
hyphensAtEnd--;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return this.joinEMailsAndUrls(l);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Java: FrenchWordTokenizer#wordsToAdd(String)
|
|
139
|
+
wordsToAdd(s) {
|
|
140
|
+
const l = [];
|
|
141
|
+
if (s === null) throw new NullPointerException('Cannot invoke "String.isEmpty()" because "s" is null');
|
|
142
|
+
if (s.length !== 0) {
|
|
143
|
+
if (!s.includes('-')) {
|
|
144
|
+
l.push(s);
|
|
145
|
+
} else {
|
|
146
|
+
let normalized = s.replaceAll('', '');
|
|
147
|
+
normalized = normalized.replaceAll('’', "'");
|
|
148
|
+
if (sharedComponent('org.languagetool.tagging.fr.FrenchTagger').tag([normalized])[0].isTagged()) {
|
|
149
|
+
l.push(s);
|
|
150
|
+
} else if (doNotSplit.includes(toLowerCase(s))) {
|
|
151
|
+
l.push(s);
|
|
152
|
+
} else {
|
|
153
|
+
const st2 = new StringTokenizer(s, '-', true);
|
|
154
|
+
while (st2.hasMoreElements()) {
|
|
155
|
+
l.push(st2.nextToken());
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return l;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
registerComponent(FrenchWordTokenizer.FQCN, () => new FrenchWordTokenizer());
|