Comment: | merge trunk |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | fr_killtricks |
Files: | files | file ages | folders |
SHA3-256: |
ab9feb3d66db42a77d00225ed976641d |
User & Date: | olr on 2017-06-08 19:38:39 |
Other Links: | branch diff | manifest | tags |
2017-06-20
| ||
09:49 | [fr] màj: conjugaisons check-in: 6eaeac5aca user: olr tags: fr, fr_killtricks | |
2017-06-08
| ||
19:38 | merge trunk check-in: ab9feb3d66 user: olr tags: fr_killtricks | |
17:52 | [fr][build] merge genfrdic check-in: 3a75d57243 user: olr tags: trunk, fr | |
2017-06-05
| ||
08:43 | [fr] nettoyage check-in: c9dedbedb4 user: olr tags: fr, fr_killtricks | |
Modified compile_rules.py from [c24bea3108] to [20229cb495].
︙ | ︙ | |||
547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 | print("# Error. Wrong option line in:\n ") print(sLine) print(" options defined for: " + ", ".join([ t[0] for t in lOpt ])) dOptions = { "lStructOpt": lStructOpt, "dOptLabel": dOptLabel } dOptions.update({ "dOpt"+k: v for k, v in lOpt }) return dOptions, dOptPriority def make (lRules, sLang, bJavaScript): "compile rules, returns a dictionary of values" # for clarity purpose, don’t create any file here # removing comments, zeroing empty lines, creating definitions, storing tests, merging rule lines print(" parsing rules...") global dDEF lLine = [] lRuleLine = [] lTest = [] lOpt = [] for i, sLine in enumerate(lRules, 1): if sLine.startswith('#END'): break elif sLine.startswith("#"): pass elif sLine.startswith("DEF:"): m = re.match("DEF: +([a-zA-Z_][a-zA-Z_0-9]*) +(.+)$", sLine.strip()) if m: dDEF["{"+m.group(1)+"}"] = m.group(2) else: print("Error in definition: ", end="") print(sLine.strip()) elif sLine.startswith("TEST:"): lTest.append("{:<8}".format(i) + " " + sLine[5:].strip()) elif sLine.startswith("TODO:"): pass elif sLine.startswith(("OPTGROUP/", "OPTSOFTWARE:", "OPT/", "OPTLANG/", "OPTLABEL/", "OPTPRIORITY/")): lOpt.append(sLine) elif re.match("[ \t]*$", sLine): pass elif sLine.startswith((" ", "\t")): lRuleLine[len(lRuleLine)-1][1] += " " + sLine.strip() else: lRuleLine.append([i, sLine.strip()]) # generating options files print(" parsing options...") | > > > > > > > > > > > > | 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 | print("# Error. Wrong option line in:\n ") print(sLine) print(" options defined for: " + ", ".join([ t[0] for t in lOpt ])) dOptions = { "lStructOpt": lStructOpt, "dOptLabel": dOptLabel } dOptions.update({ "dOpt"+k: v for k, v in lOpt }) return dOptions, dOptPriority def printBookmark (nLevel, sComment, nLine): print(" {:>6}: {}".format(nLine, " " * nLevel + sComment)) def make (lRules, sLang, bJavaScript): "compile rules, returns a dictionary of values" # for clarity purpose, don’t create any file here # removing comments, zeroing empty lines, creating definitions, storing tests, merging rule lines print(" parsing rules...") global dDEF lLine = [] lRuleLine = [] lTest = [] lOpt = [] zBookmark = re.compile("^!!+") for i, sLine in enumerate(lRules, 1): if sLine.startswith('#END'): printBookmark(0, "BREAK BY #END", i) break elif sLine.startswith("#"): pass elif sLine.startswith("DEF:"): m = re.match("DEF: +([a-zA-Z_][a-zA-Z_0-9]*) +(.+)$", sLine.strip()) if m: dDEF["{"+m.group(1)+"}"] = m.group(2) else: print("Error in definition: ", end="") print(sLine.strip()) elif sLine.startswith("TEST:"): lTest.append("{:<8}".format(i) + " " + sLine[5:].strip()) elif sLine.startswith("TODO:"): pass elif sLine.startswith(("OPTGROUP/", "OPTSOFTWARE:", "OPT/", "OPTLANG/", "OPTLABEL/", "OPTPRIORITY/")): lOpt.append(sLine) elif re.match("[ \t]*$", sLine): pass elif sLine.startswith("!!"): m = zBookmark.search(sLine) nExMk = len(m.group(0)) if sLine[nExMk:].strip(): printBookmark(nExMk-2, sLine[nExMk:].strip(), i) elif sLine.startswith((" ", "\t")): lRuleLine[len(lRuleLine)-1][1] += " " + sLine.strip() else: lRuleLine.append([i, sLine.strip()]) # generating options files print(" parsing options...") |
︙ | ︙ |
Renamed and modified doc/build.txt [d154148022] to doc/build.md [0d772932a8].
1 |
| < > | | | | | | | | | | > | | | | < | | | | > | | > | | > | | | > | | > | | > | | | > | | | > | > | > | < | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | # How to build Grammalecte ## Required ## * Python 3.6 * Firefox Nightly * NodeJS * npm * jpm * Thunderbird ## Commands ## **Build a language** `make.py LANG` > Generate the LibreOffice extension and the package folder. > LANG is the lang code (ISO 639). > This script uses the file `config.ini` in the folder `gc_lang/LANG`. **First build** `make.py LANG -js` > This command is required to generate all necessary files. **Options** `-b --build_data` > Launch the script `build_data.py` in the folder `gc_lang/LANG`. `-d --dict` > Generate the indexable binary dictionary from the lexicon in the folder `lexicons`. `-js --javascript` > Also generate JavaScript extensions. > Without this option, only Python modules, data and extensions are generated. `-t --tests` > Run unit tests. `-i --install` > Install the LibreOffice extension. `-fx --firefox` > Launch Firefox Nightly. > Unit tests can be lanched from Firefox, with CTRL+SHIFT+F12. `-tb --thunderbird` > Launch Thunderbird. ## Examples ## Full rebuild: make.py LANG -b -d -js After modifying grammar rules: make.py LANG -t If you modify the lexicon: make.py LANG -d -js If you modify your script `build_data.py`: make.py LANG -b -js |
Modified doc/syntax.txt from [ee9590ca86] to [223b361257].
|
| < > | | | | < < < < > > | | < | > > | | | < | | | | | | > | > | | | | > > > > > | > > > > > | > | > | > | > | > | | | | | > | | | | | | > > > > > > > > > > > | | | | | | | | | | | | | | | < < < < | | | | | | | | | | | | | | | | | | | | | | | | > | > | > | > | > | | > | | | | | | | | | | | | > | | | > | | | | | | | > | > | > | > | > | > | | > | | | | | > | | | | | > | | | < | | > | | | > | | | > | | > | | > | | > | | | | > | | | | > | | | | | | | > | | | | | > | < > | > | | > | | | | | | | | | | | < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 | WRITING RULES FOR GRAMMALECTE Note: This documentation is obsolete right now. # Principles # Grammalecte is a bi-passes grammar checker engine. On the first pass, the engine checks the text paragraph by paragraph. On the second passe, the engine check the text sentence by sentence. The command to switch to the second pass is `[++]`. In each pass, you can write as many rules as you need. A rule is defined by: * [optional] flags “LCR” for the regex word boundaries and case sensitiveness * a regex pattern trigger * a list of actions (can’t be empty) * [optional] user option name for activating/disactivating the rule * [optional] rule name There is no limit to the number of actions and the type of actions a rule can launch. Each action has its own condition to be triggered. There are three kind of actions: * Error warning, with a message, and optionally suggestions, and optionally an URL * Text transformation, modifying internally the checked text * Disambiguation action, setting tags on a position The rules file for your language must be named “rules.grx”. The settings file must be named “config.ini”. All these files are simple utf-8 text file. UTF-8 is mandatory. # Rule syntax # __LCR/option(rulename)__ pattern <<- condition ->> error_suggestions # message_error|http://awebsite.net... <<- condition ~>> text_rewriting <<- condition =>> commands_for_disambiguation ... Patterns are written with the Python syntax for regular expressions: http://docs.python.org/library/re.html There can be one or several actions for each rule, executed the order they are written. Conditions are optional, i.e.: <<- ~>> replacement LCR flags means: * L: Left boundary for the regex * C: Case sensitiveness * R: Right boundary for the regex Left boundary (L): > `[` word boundary > `<` no word boundary right boundary (R): > `]` word boundary > `>` no word boundary Case sensitiveness (C): > `i` case insensitive > `s` case sensitive > `u` uppercase allowed for lowercase characters >> i.e.: "Word" becomes "W[oO][rR][dD]" Examples: __[i]__ pattern __<s]__ pattern __[u>__ pattern __<s>__ pattern User option activating/disactivating is possible with an option name placed just after the LCR flags, i.e.: __[i]/option1__ pattern __[u]/option2__ pattern __[s>/option1__ pattern __<u>/option3__ pattern __<i>/option3__ pattern Rules can be named: __[i]/option1(name1)__ pattern __[u]/option2(name2)__ pattern __[s>/option1(name3)__ pattern __<u>(name4)__ pattern __<i>(name5)__ pattern Each rule name must be unique. The LCR flags are also optional. If you don’t set these flags, the default LCR flags will be: __[i]__ Example. Report “foo” in the text and suggest "bar": foo <<- ->> bar # Use bar instead of foo. Example. Recognize and suggest missing hyphen and rewrite internally the text with the hyphen: __[s]__ foo bar <<- ->> foo-bar # Missing hyphen. <<- ~>> foo-bar ## Simple-line or multi-line rules ## Rules can be break to multiple lines by leading tabulators or spaces. You should use 4 spaces. Examples: __<s>__ pattern <<- condition ->> replacement # message <<- condition ->> suggestion # message <<- condition ~>> text_rewriting <<- =>> disambiguation __<s>__ pattern <<- condition ->> replacement # message ## Comments ## Lines beginning with # are comments. ## End of file ## With the command: #END at the beginning of a line, the compiler won’t go further. Whatever is written after will be considered as comments. ## Whitespaces at the border of patterns or suggestions ## Example: Recognize double or more spaces and suggests a single space: __<s>__ " +" <<- ->> " " # Extra space(s). ASCII " characters protect spaces in the pattern and in the replacement text. ## Pattern groups and back references ## It is usually useful to retrieve parts of the matched pattern. We simply use parenthesis in pattern to get groups with back references. Example. Suggest a word with correct quotation marks: \"(\w+)\" <<- ->> “\1” # Correct quotation marks. Example. Suggest the missing space after the !, ? or . signs: __<i]__ \b([?!.])([A-Z]+) <<- ->> \1 \2 # Missing space? Example. Back reference in messages. (fooo) bar <<- ->> foo # “\1” should be: ## Name definitions ## Grammalecte supports name definitions to simplify the description of the complex rules. Example: DEF: name pattern Usage in the rules: ({name}) (\w+) ->> "\1-\2" # Missing hyphen? ## Multiple suggestions ## Use `|` in the replacement text to add multiple suggestions: Example. Foo, FOO, Bar and BAR suggestions for the input word "foo". foo <<- ->> Foo|FOO|Bar|BAR # Did you mean: ## No suggestion ## You can display message without making suggestions. For this purpose, use a single character _ in the suggestion field. Example. No suggestion. foobar <<- ->> _ # Message ## Positioning ## Positioning is valid only for error creation and text rewriting. By default, the full pattern will be underlined with blue. You can shorten the underlined text area by specifying a back reference group of the pattern. Instead of writing ->>, write -n>> n being the number of a back reference group. Actually, ->> is similar to -0>> Example: (ying) and yang <<- -1>> yin # Did you mean: __[s]__ (Mr.) [A-Z]\w+ <<- ~1>> Mr ### Comparison ### Rule A: ying and yang <<- ->> yin and yang # Did you mean: Rule B: (ying) and yang <<- -1>> yin # Did you mean: With the rule A, the full pattern is underlined: ying and yang ^^^^^^^^^^^^^ With the rule B, only the first group is underlined: ying and yang ^^^^ ## Longer explanations with URLs ## Warning messages can contain optional URL for longer explanations. your’s <<- ->> yours # Possessive pronoun:|http://en.wikipedia.org/wiki/Possessive_pronoun # Text rewriting # Example. Replacing a string by another. Mr. [A-Z]\w+ <<- ~>> Mister WARNING: The replacing text must be shorter than the replaced text or have the same length. Breaking this rule will misplace following error reports. You have to ensure yourself the rules comply with this constraint, Grammalecte won’t do it for you. Specific commands for text rewriting: `~>> *` > replace by whitespaces `~>> @` > replace by arrobas, useful mostly at first pass, where it is advised to > check usage of punctuations and whitespaces. > @ are automatically removed at the beginning of the second pass. You can use positioning with text rewriting actions. Mr(. [A-Z]\w+) <<- ~1>> * You can also call Python expressions. __[s]__ Mr. ([a-z]\w+) <<- ~1>> =\1.upper() # Disambiguation # When Grammalecte analyses a word with morph or morphex, before requesting the POS tags to the dictionary, it checks if there is a stored marker for the position where the word is. If there is a marker, Grammalecte uses the stored data and don’t make request to the dictionary. The disambiguation commands store POS tags at the position of a word. There is 3 commands for disambiguation. `select(n, pattern)` > stores at position n only the POS tags of the word matching the pattern. `exclude(n, pattern)` > stores at position n the POS tags of the word, except those matching the pattern. `define(n, definition)` > stores at position n the POS tags in definition. Examples: =>> select(\1, "po:noun is:pl") =>> exclude(\1, "po:verb") =>> define(\1, "po:adv") =>> exclude(\1, "po:verb") and define(\2, "po:adv") and select(\3, "po:adv") Note: select, exclude and define ALWAYS return True. If select and exclude generate an empty list, no marker is set. With define, you can set a list of POS tags. Example: define(\1, "po:nom is:plur|po:adj is:sing|po:adv") This will store a list of tags at the position of the first group: ["po:nom is:plur", "po:adj is:sing", "po:adv"] # Conditions # Conditions are Python expressions, they must return a value, which will be evaluated as boolean. You can use the usual Python syntax and libraries. You can call pattern subgroups via \0, \1, \2… Example: these (\w+) <<- \1 == "man" -1>> men # Man is a singular noun. Use the plural form: You can also apply functions to subgroups like: \1.startswith("a") \3.islower() re.search("pattern", \2) ## Standard functions ## `word(n)` > catches the nth next word after the pattern (separated only by white spaces). > returns None if no word catched `word(-n)` > catches the nth next word before the pattern (separated only by white spaces). > returns None if no word catched `after(regex[, neg_regex])` > checks if the text after the pattern matches the regex. `before(regex[, neg_regex])` > checks if the text before the pattern matches the regex. `textarea(regex[, neg_regex])` > checks if the full text of the checked area (paragraph or sentence) matches the regex. `morph(n, regex[, strict=True][, noword=False])` > checks if all tags of the word in group n match the regex. > if strict = False, returns True only if one of tags matches the regex. > if there is no word at position n, returns the value of noword. `morphex(n, regex, neg_regex[, noword=False])` > checks if one of the tags of the word in group n match the regex and > if no tags matches the neg_regex. > if there is no word at position n, returns the value of noword. `option(option_name)` > returns True if option_name is activated else False Note: the analysis is done on the preprocessed text. ## Default variables ## `sCountry` > It contains the current country locale of the checked paragraph. colour <<- sCountry == "US" ->> color # Use American English spelling. # Expressions in the suggestions # Suggestions (and warning messages) started by an equal sign are Python string expressions extended with possible back references and named definitions: Example: foo\w+ ->> = '"' + \0.upper() + '"' # With uppercase letters and quoation marks All words beginning with "foo" will be recognized, and the suggestion is the uppercase form of the string with ASCII quoation marks: eg. foom ->> "FOOM". //////////////////////////////// OLD /////////////////////////////////////// = Text preprocessing and multi-passes checking = On each pass, Lightproof uses rules written in the text preprocessor to modify internally the text before checking the text. The text preprocessor is useful to simplify texts and write simplier checking rules. For example, sentences with the same grammar mistake: These “cats” are blacks. These cats are “blacks”. These cats are absolutely blacks. These stupid “cats” are all blacks. These unknown cats are as per usual blacks. Instead of writting complex rules or several rules to find mistakes for all possible cases, you can use the text preprocessor to simplify the text. To remove the chars “”, write: [“”] ->> * The * means: replace text by whitespaces. Similarly to grammar rules, you can add conditions: \w+ly <<- morph(\0, "adverb") ->> * You can also remove a group reference: these (\w+) (\w+) <<- morph(\1, "adjective") and morph(\2, "noun") -1>> * (am|are|is|were|was) (all) <<- -2>> * With these rules, you get the following sentences: These cats are blacks. These cats are blacks . These cats are blacks. These cats are blacks. These cats are blacks. These grammar mistakes can be detected with one simple rule: these +(\w+) +are +(\w+s) <<- morph(\1, "noun") and morph(\2, "plural") -2>> _ # Adjectives are invariable. Instead of replacing text with whitespaces, you can replace text with @. https?://\S+ ->> @ This is useful if at first pass you write rules to check successive whitespaces. @ are automatically removed at the second pass. You can also replace any text as you wish. Mister <<- ->> Mr (Mrs?)[.] <<- ->> \1 With the multi-passes checking and the text preprocessor, it is advised to remove or simplify the text which has been checked on the previous pass. == Pattern matching == Repeating pattern matching of a single rule continues after the previous matching, so instead of general multiword patterns, like (\w+) (\w+) <<- some_check(\1, \2) ->> \1, \2 # foo use (\w+) <<- some_check(\1, word(1)) ->> \1, # foo |
Added gc_lang/fr/build.py version [9b9cd2c271].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | # Builder for French language import os import zipfile from distutils import dir_util, file_util import helpers def build (sLang, dVars, spLangPack): "complementary build launched from make.py" createFirefoxExtension(sLang, dVars) createThunderbirdExtension(sLang, dVars, spLangPack) def createFirefoxExtension (sLang, dVars): "create extension for Firefox" print("Building extension for Firefox") helpers.createCleanFolder("_build/xpi/"+sLang) dir_util.copy_tree("gc_lang/"+sLang+"/xpi/", "_build/xpi/"+sLang) dir_util.copy_tree("grammalecte-js", "_build/xpi/"+sLang+"/grammalecte") sHTML, dProperties = _createOptionsForFirefox(dVars) dVars['optionsHTML'] = sHTML helpers.copyAndFileTemplate("_build/xpi/"+sLang+"/data/about_panel.html", "_build/xpi/"+sLang+"/data/about_panel.html", dVars) for sLocale in dProperties.keys(): spfLocale = "_build/xpi/"+sLang+"/locale/"+sLocale+".properties" if os.path.exists(spfLocale): helpers.copyAndFileTemplate(spfLocale, spfLocale, dProperties) else: print("Locale file not found: " + spfLocale) with helpers.cd("_build/xpi/"+sLang): os.system("jpm xpi") def _createOptionsForFirefox (dVars): sHTML = "" for sSection, lOpt in dVars['lStructOpt']: sHTML += '\n<div id="subsection_' + sSection + '" class="opt_subsection">\n <h2 data-l10n-id="option_'+sSection+'"></h2>\n' for lLineOpt in lOpt: for sOpt in lLineOpt: sHTML += ' <p><input type="checkbox" id="option_'+sOpt+'" /><label id="option_label_'+sOpt+'" for="option_'+sOpt+'" data-l10n-id="option_'+sOpt+'"></label></p>\n' sHTML += '</div>\n' # Creating translation data dProperties = {} for sLang in dVars['dOptLabel'].keys(): dProperties[sLang] = "\n".join( [ "option_" + sOpt + " = " + dVars['dOptLabel'][sLang][sOpt][0].replace(" [!]", " [!]") for sOpt in dVars['dOptLabel'][sLang] ] ) return sHTML, dProperties def createThunderbirdExtension (sLang, dVars, spLangPack): "create extension for Thunderbird" print("Building extension for Thunderbird") sExtensionName = dVars['tb_identifier'] + "-v" + dVars['version'] + '.xpi' spfZip = "_build/" + sExtensionName hZip = zipfile.ZipFile(spfZip, mode='w', compression=zipfile.ZIP_DEFLATED) _copyGrammalecteJSPackageInZipFile(hZip, spLangPack, dVars['js_binary_dic']) for spf in ["LICENSE.txt", "LICENSE.fr.txt"]: hZip.write(spf) dVars = _createOptionsForThunderbird(dVars) helpers.addFolderToZipAndFileFile(hZip, "gc_lang/"+sLang+"/tb", "", dVars, True) hZip.write("gc_lang/"+sLang+"/xpi/gce_worker.js", "worker/gce_worker.js") spDict = "gc_lang/"+sLang+"/xpi/data/dictionaries" for sp in os.listdir(spDict): if os.path.isdir(spDict+"/"+sp): hZip.write(spDict+"/"+sp+"/"+sp+".dic", "content/dictionaries/"+sp+"/"+sp+".dic") hZip.write(spDict+"/"+sp+"/"+sp+".aff", "content/dictionaries/"+sp+"/"+sp+".aff") hZip.close() helpers.unzip(spfZip, dVars['tb_debug_extension_path']) def _createOptionsForThunderbird (dVars): dVars['sXULTabs'] = "" dVars['sXULTabPanels'] = "" # dialog options for sSection, lOpt in dVars['lStructOpt']: dVars['sXULTabs'] += ' <tab label="&option.label.'+sSection+';"/>\n' dVars['sXULTabPanels'] += ' <tabpanel orient="vertical">\n <label class="section" value="&option.label.'+sSection+';" />\n' for lLineOpt in lOpt: for sOpt in lLineOpt: dVars['sXULTabPanels'] += ' <checkbox id="option_'+sOpt+'" class="option" label="&option.label.'+sOpt+';" />\n' dVars['sXULTabPanels'] += ' </tabpanel>\n' # translation data for sLang in dVars['dOptLabel'].keys(): dVars['gc_options_labels_'+sLang] = "\n".join( [ "<!ENTITY option.label." + sOpt + ' "' + dVars['dOptLabel'][sLang][sOpt][0] + '">' for sOpt in dVars['dOptLabel'][sLang] ] ) return dVars def _copyGrammalecteJSPackageInZipFile (hZip, spLangPack, sDicName, sAddPath=""): for sf in os.listdir("grammalecte-js"): if not os.path.isdir("grammalecte-js/"+sf): hZip.write("grammalecte-js/"+sf, sAddPath+"grammalecte-js/"+sf) for sf in os.listdir(spLangPack): if not os.path.isdir(spLangPack+"/"+sf): hZip.write(spLangPack+"/"+sf, sAddPath+spLangPack+"/"+sf) hZip.write("grammalecte-js/_dictionaries/"+sDicName, sAddPath+"grammalecte-js/_dictionaries/"+sDicName) |
Modified gc_lang/fr/build_data.py from [040b9153d1] to [9294fbef92].
︙ | ︙ | |||
24 25 26 27 28 29 30 | def __exit__ (self, etype, value, traceback): os.chdir(self.savedPath) def makeDictionaries (sp, sVersion): with cd(sp+"/dictionnaire"): | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | def __exit__ (self, etype, value, traceback): os.chdir(self.savedPath) def makeDictionaries (sp, sVersion): with cd(sp+"/dictionnaire"): os.system("genfrdic.py -s -gl -v "+sVersion) def makeConj (sp, bJS=False): print("> Conjugaisons ", end="") print("(Python et JavaScript)" if bJS else "(Python seulement)") dVerb = {} lVtyp = []; dVtyp = {}; nVtyp = 0 |
︙ | ︙ |
Modified gc_lang/fr/data/phonet_simil.txt from [049b9b49d3] to [8905288c4c].
︙ | ︙ | |||
156 157 158 159 160 161 162 163 164 165 166 167 168 169 | entrée entrées entrer entrais entrait entrez entraient envoi envois envoie envoies envoient envol envols envole envoles envolent épais épée épées équivalant équivalent équivalents errâmes Éram essai essais essaie essaies essaient essaye essayes essayent étai étais était étaient été étés étain étains éteint éteins étal étals étale étales étalent étang étangs étant étends étend être êtres hêtre hêtres eusse eusses eussent us éveil éveils éveille éveilles éveillent | > | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | entrée entrées entrer entrais entrait entrez entraient envoi envois envoie envoies envoient envol envols envole envoles envolent épais épée épées équivalant équivalent équivalents errâmes Éram essai essais essaie essaies essaient essaye essayes essayent essor essors essore essores essorent étai étais était étaient été étés étain étains éteint éteins étal étals étale étales étalent étang étangs étant étends étend être êtres hêtre hêtres eusse eusses eussent us éveil éveils éveille éveilles éveillent |
︙ | ︙ | |||
186 187 188 189 190 191 192 193 194 195 196 197 198 199 | fi fis fit fît fief fiefs fieffe fieffes fieffent fil fils file files filent filet filets filer filais filait filaient filez film films filme filmes filment filtrat filtrats filtra filtras filtrât fin fins faim faims feins feint flan flan flanc flancs flic flics flique fliques fliquent flou flous floue floues flouent foi fois foie foies font fonts fond fonds forçat forçats força forças forçât foret forets forer forais forait foraient forêt forêts | > | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | fi fis fit fît fief fiefs fieffe fieffes fieffent fil fils file files filent filet filets filer filais filait filaient filez film films filme filmes filment filtrat filtrats filtra filtras filtrât fin fins faim faims feins feint flair flairs flaire flaires flairent flan flan flanc flancs flic flics flique fliques fliquent flou flous floue floues flouent foi fois foie foies font fonts fond fonds forçat forçats força forças forçât foret forets forer forais forait foraient forêt forêts |
︙ | ︙ | |||
276 277 278 279 280 281 282 | mare mares marre marres marrent marc marcs mark marks marque marques marquent mec mecs Mecque mél mêle mêles mêlent mess messe messes meurs meurt mœurs mi mie mies mis mit mît | | | 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | mare mares marre marres marrent marc marcs mark marks marque marques marquent mec mecs Mecque mél mêle mêles mêlent mess messe messes meurs meurt mœurs mi mie mies mis mit mît mir mirs mire mires mirent myrrhe myrrhes mite mites mythe mythes mol mols mole moles molle molles môle môles mon mont monts monitorat monitorats monitora monitoras monitorât mort morts mors mords mord maure maures mot mots maux moi mois |
︙ | ︙ | |||
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 | sommeil sommeils sommeille sommeilles sommeillent sommet sommets sommer sommais sommait sommaient sommez son sons sont sonnet sonnets sonner sonnais sonnait sonnaient sonnez sors sort sorts sortie sorties sortis sortit souci soucis soucie soucies soucient soutien soutiens soutient soufflet soufflets soufflé soufflés souffler soufflais soufflait soufflaient soufflez soufre soufres souffre souffres souffrent souk souks souque souques souquent stress stresse stresses stressent substitut substituts substitue substitues substituent sui suis suit suie suies survie survies survis survit survol survols survole survoles survolent ta tas taie taies tes thé thés tain teint teints thym thyms tin tins tint teins tant temps tends tend tante tantes tente tentes tentent tapis tapit tapît tare tares tard teinte teintes teintent tinte tintes tintent test tests teste testes testent tête têtes tète tètes tètent tic tics tique tiques tiquent tir tirs tire tires tirent | > > > | 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 | sommeil sommeils sommeille sommeilles sommeillent sommet sommets sommer sommais sommait sommaient sommez son sons sont sonnet sonnets sonner sonnais sonnait sonnaient sonnez sors sort sorts sortie sorties sortis sortit souci soucis soucie soucies soucient soupir soupirs soupire soupires soupirent soutien soutiens soutient soufflet soufflets soufflé soufflés souffler soufflais soufflait soufflaient soufflez soufre soufres souffre souffres souffrent souk souks souque souques souquent stress stresse stresses stressent substitut substituts substitue substitues substituent sui suis suit suie suies su sus sue sues suent survie survies survis survit survol survols survole survoles survolent ta tas taie taies tes thé thés tain teint teints thym thyms tin tins tint teins tant temps tends tend tante tantes tente tentes tentent tapir tapirs tapirent tapis tapit tapît tare tares tard teinte teintes teintent tinte tintes tintent test tests teste testes testent tête têtes tète tètes tètent tic tics tique tiques tiquent tir tirs tire tires tirent |
︙ | ︙ |
Modified gc_lang/fr/dictionnaire/genfrdic.py from [38f9af18d9] to [5036afecd5].
︙ | ︙ | |||
547 548 549 550 551 552 553 | dVars['version'] = self.sVersion # Dictionaries files (.dic) (.aff) self.writeAffixes(spDic, dVars, nMode, bSimplified) self.writeDictionary(spDic, dVars, nMode, bSimplified) copyTemplate('orthographe', spDic, 'README_dict_fr.txt', dVars) createZipFiles(spDic, spDst, sDicName + '.zip') | | | 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 | dVars['version'] = self.sVersion # Dictionaries files (.dic) (.aff) self.writeAffixes(spDic, dVars, nMode, bSimplified) self.writeDictionary(spDic, dVars, nMode, bSimplified) copyTemplate('orthographe', spDic, 'README_dict_fr.txt', dVars) createZipFiles(spDic, spDst, sDicName + '.zip') def createLibreOfficeExtension (self, spBuild, dTplVars, lDictVars, spDestGL=""): # LibreOffice extension echo(" * Dictionnaire >> extension pour LibreOffice") dTplVars['version'] = self.sVersion sExtensionName = EXT_PREFIX_OOO + self.sVersion spExt = spBuild + '/' + sExtensionName dir_util.mkpath(spExt+'/META-INF') dir_util.mkpath(spExt+'/ui') |
︙ | ︙ | |||
586 587 588 589 590 591 592 | file_util.copy_file('césures/frhyph.tex', spExt+'/dictionaries') file_util.copy_file('césures/hyph-fr.tex', spExt+'/dictionaries') file_util.copy_file('césures/README_hyph_fr-3.0.txt', spExt+'/dictionaries') file_util.copy_file('césures/README_hyph_fr-2.9.txt', spExt+'/dictionaries') # zip createZipFiles(spExt, spBuild, sExtensionName + '.oxt') # copy to Grammalecte Project | | | | > | | | | | > | | | > | | | > | | | 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 | file_util.copy_file('césures/frhyph.tex', spExt+'/dictionaries') file_util.copy_file('césures/hyph-fr.tex', spExt+'/dictionaries') file_util.copy_file('césures/README_hyph_fr-3.0.txt', spExt+'/dictionaries') file_util.copy_file('césures/README_hyph_fr-2.9.txt', spExt+'/dictionaries') # zip createZipFiles(spExt, spBuild, sExtensionName + '.oxt') # copy to Grammalecte Project if spDestGL: echo(" extension copiée dans Grammalecte...") dir_util.copy_tree(spExt+'/dictionaries', spDestGL) def createMozillaExtensions (self, spBuild, dTplVars, lDictVars, spDestGL=""): # Mozilla extension 1 echo(" * Dictionnaire >> extension pour Mozilla") dTplVars['version'] = self.sVersion sExtensionName = EXT_PREFIX_MOZ + self.sVersion spExt = spBuild + '/' + sExtensionName dir_util.mkpath(spExt+'/dictionaries') copyTemplate('_templates/moz', spExt, 'install.rdf', dTplVars) spDict = spBuild + '/' + PREFIX_DICT_PATH + self.sVersion file_util.copy_file(spDict+'/fr-classique.dic', spExt+'/dictionaries/fr-classic.dic') file_util.copy_file(spDict+'/fr-classique.aff', spExt+'/dictionaries/fr-classic.aff') copyTemplate('orthographe', spExt, 'README_dict_fr.txt', dTplVars) createZipFiles(spExt, spBuild, sExtensionName + '.xpi') # Grammalecte if spDestGL: echo(" * Dictionnaire >> copie des dicos dans Grammalecte") for dVars in lDictVars: file_util.copy_file(spDict+'/'+dVars['asciiName']+'.dic', spDestGL+'/'+dVars['mozAsciiName']+"/"+dVars['mozAsciiName']+'.dic') file_util.copy_file(spDict+'/'+dVars['asciiName']+'.aff', spDestGL+'/'+dVars['mozAsciiName']+"/"+dVars['mozAsciiName']+'.aff') def createFileIfqForDB (self, spBuild): echo(" * Dictionnaire >> indices de fréquence pour la DB...") with open(spBuild+'/dictIdxIfq-'+self.sVersion+'.diff.txt', 'w', encoding='utf-8', newline="\n") as hDiff, \ open(spBuild+'/dictIdxIfq-'+self.sVersion+'.notes.txt', 'w', encoding='utf-8', newline="\n") as hNotes: for oEntry in self.lEntry: if oEntry.fq != oEntry.oldFq: hDiff.write("{0.iD}\t{0.fq}\n".format(oEntry)) hNotes.write("{0.lemma}/{0.flags}\t{0.oldFq} > {0.fq}\n".format(oEntry)) def createLexiconPackages (self, spBuild, version, oStatsLex, spDestGL=""): sLexName = LEX_PREFIX + version spLex = spBuild + '/' + sLexName dir_util.mkpath(spLex) # write Dicollecte lexicon self.sortLexiconByFreq() self.writeLexicon(spLex + '/' + sLexName + '.txt', version, oStatsLex) self.writeGrammarCheckerLexicon(spBuild + '/' + sLexName + '.lex', version) copyTemplate('lexique', spLex, 'README_lexique.txt', {'version': version}) # zip createZipFiles(spLex, spBuild, sLexName + '.zip') # copy GC lexicon to Grammalecte if spDestGL: file_util.copy_file(spBuild + '/' + sLexName + '.lex', spDestGL + '/French.lex') file_util.copy_file('lexique/French.tagset.txt', spDestGL) def createDictConj (self, spBuild, spDestGL=""): echo(" * Dictionnaire >> fichier de conjugaison...") with open(spBuild+'/dictConj.txt', 'w', encoding='utf-8', newline="\n") as hDst: for oEntry in self.lEntry: if oEntry.po.startswith("v"): hDst.write(oEntry.getConjugation()) if spDestGL: echo(" Fichier de conjugaison copié dans Grammalecte...") file_util.copy_file(spBuild+'/dictConj.txt', spDestGL) def createDictDecl (self, spBuild, spDestGL=""): echo(" * Dictionnaire >> fichier de déclinaison...") with open(spBuild+'/dictDecl.txt', 'w', encoding='utf-8', newline="\n") as hDst: for oEntry in self.lEntry: if re.match("[SXFWIA]", oEntry.flags) and (oEntry.po.startswith("nom") or oEntry.po.startswith("adj")): hDst.write(oEntry.getDeclination()) if spDestGL: echo(" Fichier de déclinaison copié dans Grammalecte...") file_util.copy_file(spBuild+'/dictDecl.txt', spDestGL) def generateSpellVariants (self, nReq, spBuild): if nReq < 1: nReq = 1 if nReq > 2: nReq = 2 echo(" * Lexique >> variantes par suppression... n = " + str(nReq)) with open(spBuild+'/dictSpellVariants-'+str(nReq)+'.txt', 'w', encoding='utf-8', newline="\n") as hDst: for oFlex in frozenset(self.lFlexions): |
︙ | ︙ | |||
805 806 807 808 809 810 811 | if self.err: echo("\n## Erreur dans le dictionnaire : {}".format(self.err)) echo(" dans : " + self.lemma) def __str__ (self): return "{0.lemma}/{0.flags} {1}".format(self, self.getMorph(2)) | < < < | 809 810 811 812 813 814 815 816 817 818 819 820 821 822 | if self.err: echo("\n## Erreur dans le dictionnaire : {}".format(self.err)) echo(" dans : " + self.lemma) def __str__ (self): return "{0.lemma}/{0.flags} {1}".format(self, self.getMorph(2)) def check (self): sErr = '' if self.lemma == '': sErr += 'lemme vide' if not re.match(r"[a-zA-ZéÉôÔàâÂîÎïèÈêÊÜœŒæÆçÇ0-9µåÅΩ&αβγδεζηθικλμνξοπρστυφχψωΔℓΩ_]", self.lemma): sErr += 'premier caractère inconnu: ' + self.lemma[0] if re.search(r"\s$", self.lemma): |
︙ | ︙ | |||
1075 1076 1077 1078 1079 1080 1081 | # moyenne des formes fléchies sans équivalent ou -1 self.nAKO = math.ceil(nOccur / nFlex) if nFlex > 0 else -1 def solveOccurMultipleFlexions (self, hDst, oStatsLex): sBlank = " " if self.nAKO >= 0: for oFlex in self.lFlexions: | | | 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 | # moyenne des formes fléchies sans équivalent ou -1 self.nAKO = math.ceil(nOccur / nFlex) if nFlex > 0 else -1 def solveOccurMultipleFlexions (self, hDst, oStatsLex): sBlank = " " if self.nAKO >= 0: for oFlex in self.lFlexions: if oFlex.nMulti > 0 and not oFlex.bBlocked: # on trie les entrées avec AKO et sans AKO lEntWithAKO = [] lEntNoAKO = [] for oEntry in oFlex.lMulti: if oEntry.nAKO >= 0: lEntWithAKO.append(oEntry) else: |
︙ | ︙ | |||
1099 1100 1101 1102 1103 1104 1105 | if nDiff > 0: # on peut passer à les formes fléchies à AKO hDst.write(" * {0.sFlexion}\n".format(oFlex)) hDst.write(" moyenne connue\n") for oFlexD in self.lFlexions: if oFlex.sFlexion == oFlexD.sFlexion: hDst.write(sBlank + "{2:<30} {0.sMorph:<30} {0.nOccur:>10} >> {1:>10}\n".format(oFlexD, self.nAKO, self.getShortDescr())) | | | | | | | | > > > | | 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 | if nDiff > 0: # on peut passer à les formes fléchies à AKO hDst.write(" * {0.sFlexion}\n".format(oFlex)) hDst.write(" moyenne connue\n") for oFlexD in self.lFlexions: if oFlex.sFlexion == oFlexD.sFlexion: hDst.write(sBlank + "{2:<30} {0.sMorph:<30} {0.nOccur:>10} >> {1:>10}\n".format(oFlexD, self.nAKO, self.getShortDescr())) oFlexD.setOccurAndBlock(self.nAKO) for oEntry in lEntWithAKO: hDst.write(" moyenne connue\n") for oFlexM in oEntry.lFlexions: if oFlex.sFlexion == oFlexM.sFlexion: hDst.write(sBlank + "{2:<30} {0.sMorph:<30} {0.nOccur:>10} >> {1:>10}\n".format(oFlexM, oEntry.nAKO, oEntry.getShortDescr())) oFlexM.setOccurAndBlock(oEntry.nAKO) # on répercute nDiff sur les flexions sans AKO for oEntry in lEntNoAKO: hDst.write(" sans moyenne connue\n") for oFlexM in oEntry.lFlexions: if oFlex.sFlexion == oFlexM.sFlexion: nNewOccur = oFlexM.nOccur + math.ceil((nDiff / len(lEntNoAKO)) / oFlexM.nDup) hDst.write(sBlank + "{2:<30} {0.sMorph:<30} {0.nOccur:>10} +> {1:>10}\n".format(oFlexM, nNewOccur, oEntry.getShortDescr())) oFlexM.setOccurAndBlock(nNewOccur) else: # Toutes les entrées sont avec AKO : on pondère nFlexOccur = oStatsLex.getFlexionOccur(oFlex.sFlexion) nTotAKO = self.nAKO for oEnt in oFlex.lMulti: nTotAKO += oEnt.nAKO hDst.write(" = {0.sFlexion}\n".format(oFlex)) hDst.write(" moyennes connues\n") for oFlexD in self.lFlexions: if oFlex.sFlexion == oFlexD.sFlexion: nNewOccur = math.ceil((nFlexOccur * (self.nAKO / nTotAKO)) / oFlexD.nDup) if nTotAKO else 0 hDst.write(sBlank + "{2:<30} {0.sMorph:<30} {0.nOccur:>10} %> {1:>10}\n".format(oFlexD, nNewOccur, self.getShortDescr())) oFlexD.setOccurAndBlock(nNewOccur) for oEntry in oFlex.lMulti: for oFlexM in oEntry.lFlexions: if oFlex.sFlexion == oFlexM.sFlexion: nNewOccur = math.ceil((nFlexOccur * (oEntry.nAKO / nTotAKO)) / oFlexM.nDup) if nTotAKO else 0 hDst.write(sBlank + "{2:<30} {0.sMorph:<30} {0.nOccur:>10} %> {1:>10}\n".format(oFlexM, nNewOccur, oEntry.getShortDescr())) oFlexM.setOccurAndBlock(nNewOccur) def calcFreq (self, nTot): self.fFreq = (self.nOccur * 100) / nTot self.oldFq = self.fq self.fq = getIfq(self.fFreq) class Flexion: def __init__ (self, oEntry, sFlex='', sMorph='', cDic=''): self.oEntry = oEntry self.sFlexion = sFlex self.sMorph = sMorph self.cDic = cDic self.nOccur = 0 self.bBlocked = False self.nDup = 0 # duplicates in the same entry self.nMulti = 0 # duplicates with other entries self.lMulti = [] # list of similar flexions self.fFreq = 0 self.cFq = '' self.metagfx = '' # métagraphe self.metaph2 = '' # métaphone 2 def setOccur (self, n): self.nOccur = n def setOccurAndBlock (self, n): self.nOccur = n self.bBlocked = True def calcOccur (self): self.nOccur = math.ceil((self.nOccur / (self.nMulti+1)) / self.nDup) def calcFreq (self, nTot): self.fFreq = (self.nOccur * 100) / nTot self.cFq = getIfq(self.fFreq) |
︙ | ︙ | |||
1190 1191 1192 1193 1194 1195 1196 | def __str__ (self, oStatsLex): sOccurs = '' for v in oStatsLex.dFlexions[self.sFlexion]: sOccurs += str(v) + "\t" return "{0.oEntry.iD}\t{0.sFlexion}\t{0.oEntry.sRadical}\t{0.sMorph}\t{0.metagfx}\t{0.metaph2}\t{0.oEntry.lx}\t{0.oEntry.se}\t{0.oEntry.et}\t{0.oEntry.di}{2}\t{1}{0.nOccur}\t{0.nDup}\t{0.nMulti}\t{0.fFreq:.15f}\t{0.cFq}\n".format(self, sOccurs, "/"+self.cDic if self.cDic != "*" else "") | < < < | 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 | def __str__ (self, oStatsLex): sOccurs = '' for v in oStatsLex.dFlexions[self.sFlexion]: sOccurs += str(v) + "\t" return "{0.oEntry.iD}\t{0.sFlexion}\t{0.oEntry.sRadical}\t{0.sMorph}\t{0.metagfx}\t{0.metaph2}\t{0.oEntry.lx}\t{0.oEntry.se}\t{0.oEntry.et}\t{0.oEntry.di}{2}\t{1}{0.nOccur}\t{0.nDup}\t{0.nMulti}\t{0.fFreq:.15f}\t{0.cFq}\n".format(self, sOccurs, "/"+self.cDic if self.cDic != "*" else "") @classmethod def simpleHeader (cls): return "# :POS ;LEX ~SEM =FQ /DIC\n" def getGrammarCheckerRepr (self): return "{0.sFlexion}\t{0.oEntry.lemma}\t{1}\n".format(self, self._getSimpleTags()) |
︙ | ︙ | |||
1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 | xParser = argparse.ArgumentParser() xParser.add_argument("-v", "--verdic", help="set dictionary version, i.e. 5.4", type=str, default="X.Y.z") xParser.add_argument("-m", "--mode", help="0: no tags, 1: Hunspell tags (default), 2: All tags", type=int, choices=[0, 1, 2], default=1) xParser.add_argument("-u", "--uncompress", help="do not use Hunspell compression", action="store_true") xParser.add_argument("-s", "--simplify", help="no virtual lemmas", action="store_true") xParser.add_argument("-sv", "--spellvariants", help="generate spell variants", action="store_true") xArgs = xParser.parse_args() if xArgs.simplify: xArgs.mode = 0 xArgs.uncompress = True echo("Python: " + sys.version) | > | 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 | xParser = argparse.ArgumentParser() xParser.add_argument("-v", "--verdic", help="set dictionary version, i.e. 5.4", type=str, default="X.Y.z") xParser.add_argument("-m", "--mode", help="0: no tags, 1: Hunspell tags (default), 2: All tags", type=int, choices=[0, 1, 2], default=1) xParser.add_argument("-u", "--uncompress", help="do not use Hunspell compression", action="store_true") xParser.add_argument("-s", "--simplify", help="no virtual lemmas", action="store_true") xParser.add_argument("-sv", "--spellvariants", help="generate spell variants", action="store_true") xParser.add_argument("-gl", "--grammalecte", help="copy generated files to Grammalecte folders", action="store_true") xArgs = xParser.parse_args() if xArgs.simplify: xArgs.mode = 0 xArgs.uncompress = True echo("Python: " + sys.version) |
︙ | ︙ | |||
1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 | oStatsLex.addLexFromFile('lexique/corpus_data/stats_frwikisource.txt', 'S', 'Wikisource') oStatsLex.addLexFromFile('lexique/corpus_data/stats_litterature.txt', 'L', 'Littérature') oStatsLex.write(spBuild+'/test_lex.txt') oFrenchDict.calculateStats(oStatsLex, spfStats) ### écriture des paquets echo("Création des paquets...") if not xArgs.uncompress: oFrenchDict.defineAbreviatedTags(xArgs.mode, spfStats) oFrenchDict.createFiles(spBuild, [dMODERNE, dTOUTESVAR, dCLASSIQUE, dREFORME1990], xArgs.mode, xArgs.simplify) | > > > > > > < < | > > | | | 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 | oStatsLex.addLexFromFile('lexique/corpus_data/stats_frwikisource.txt', 'S', 'Wikisource') oStatsLex.addLexFromFile('lexique/corpus_data/stats_litterature.txt', 'L', 'Littérature') oStatsLex.write(spBuild+'/test_lex.txt') oFrenchDict.calculateStats(oStatsLex, spfStats) ### écriture des paquets echo("Création des paquets...") spLexiconDestGL = "../../../lexicons" if xArgs.grammalecte else "" spLibreOfficeExtDestGL = "../oxt/Dictionnaires/dictionaries" if xArgs.grammalecte else "" spMozillaExtDestGL = "../xpi/data/dictionaries" if xArgs.grammalecte else "" spDataDestGL = "../data" if xArgs.grammalecte else "" if not xArgs.uncompress: oFrenchDict.defineAbreviatedTags(xArgs.mode, spfStats) oFrenchDict.createFiles(spBuild, [dMODERNE, dTOUTESVAR, dCLASSIQUE, dREFORME1990], xArgs.mode, xArgs.simplify) oFrenchDict.createLexiconPackages(spBuild, xArgs.verdic, oStatsLex, spLexiconDestGL) oFrenchDict.createFileIfqForDB(spBuild) oFrenchDict.createLibreOfficeExtension(spBuild, dMOZEXT, [dMODERNE, dTOUTESVAR, dCLASSIQUE, dREFORME1990], spLibreOfficeExtDestGL) oFrenchDict.createMozillaExtensions(spBuild, dMOZEXT, [dMODERNE, dTOUTESVAR, dCLASSIQUE, dREFORME1990], spMozillaExtDestGL) oFrenchDict.createDictConj(spBuild, spDataDestGL) oFrenchDict.createDictDecl(spBuild, spDataDestGL) if __name__ == '__main__': main() |
Modified gc_lang/fr/rules.grx from [ed08aa24fb] to [d8a8288ded].
︙ | ︙ | |||
41 42 43 44 45 46 47 | # Fin d’interprétation du fichier avec une ligne commençant par #END # ERREURS COURANTES # http://fr.wikipedia.org/wiki/Wikip%C3%A9dia:Fautes_d%27orthographe/Courantes | > > > > > | < < | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | # Fin d’interprétation du fichier avec une ligne commençant par #END # ERREURS COURANTES # http://fr.wikipedia.org/wiki/Wikip%C3%A9dia:Fautes_d%27orthographe/Courantes !! !! !! Options !! !! OPTGROUP/basic: typo apos, esp tab, nbsp unit, tu maj, num virg, nf chim, ocr mapos, liga OPTGROUP/gramm: conf sgpl gn OPTGROUP/verbs: infi conj ppas, imp inte vmode OPTGROUP/style: bs pleo, redon1 redon2, neg OPTGROUP/misc: date mc OPTGROUP/debug: idrule |
︙ | ︙ | |||
189 190 191 192 193 194 195 | OPTLABEL/date: Date validity. OPTLABEL/debug: Debug OPTLABEL/idrule: Display control rule identifier [!]|Display control rule identifier in the context menu message. | > > > > > | < < < < < < < < < < < < < < < < < < < < < < > > > > > > > > > > > > > > > > > > > > | < < < > > > > > > > > > > > > > > > > > > > > | | | < < < < < < < < < < < < < < < | | | < < < | > | 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | OPTLABEL/date: Date validity. OPTLABEL/debug: Debug OPTLABEL/idrule: Display control rule identifier [!]|Display control rule identifier in the context menu message. !! !! !! Définitions pour les regex !! !! DEF: avoir [aeo]\w* DEF: etre [êeésf]\w+ DEF: avoir_etre [aeêésfo]\w* DEF: aller (?:all|v|ir)\w+ DEF: ppas \w[\w-]+[éiust]e?s? DEF: infi \w[\w-]+(?:er|ir|re) DEF: w_1 \w[\w-]* DEF: w_2 \w[\w-]+ DEF: w_3 \w[\w-]+\w DEF: w_4 \w[\w-][\w-]+\w DEF: w1 \w+ DEF: w2 \w\w+ DEF: w3 \w\w\w+ DEF: w4 \w\w\w\w+ !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! PASSE 0: PARAGRAPHE PAR PARAGRAPHE !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !!! Espaces & tabulations !! !! # Espaces surnuméraires # Note : les tabulations ne sont pas soulignées dans LibreOffice. Mais l’erreur est bien présente. __<s>/tab(tab_début_ligne)__ ^[ ]+ <<- ->> "" # Espace(s) en début de ligne à supprimer : utilisez les retraits de paragraphe. __<s>/tab(tab_fin_ligne)__ [ ]+$ <<- ->> "" # Espace(s) en fin de ligne à supprimer. TEST: __tab__ {{ }}Espaces surnuméraires. ->> "" |
︙ | ︙ | |||
373 374 375 376 377 378 379 | # Tout contrôle des espaces doit se faire avant ce point. # À partir d’ici, toute règle est susceptible de supprimer des caractères et les remplacer par des espaces ou des chaînes de longueur égale. | < < < | > > > > | 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 | # Tout contrôle des espaces doit se faire avant ce point. # À partir d’ici, toute règle est susceptible de supprimer des caractères et les remplacer par des espaces ou des chaînes de longueur égale. !!! !!! !!! Processeur: efface les ponctuations gênantes (URL, sigles, abréviations, IP, heures, etc.) !!! !!! # e-mail __<i>(p_email)__ \w[\w.-]*@\w[\w.-]*\w[.]\w+ <<- ~>> * # URL __<i>(p_URL)__ |
︙ | ︙ | |||
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 | TEST: C’est le b.a.-ba du métier. TEST: qui a été le plus honnête [Rires] TEST: Marion Maréchal-Le Pen. Afin que Maréchal ne soit pas analysé comme un impératif, “Le Pen” devient “Le_Pen”. TEST: Car [je] deviendrai plus insaisissable que jamais. #TEST: des <b>{{homme}}</b> #TEST: des [b]{{femme}}[/b] # HTML __<i>/html(p_html_amp_xxx)__ &[a-zA-Z]+; <<- ~>> _ __<i>/html(p_html_lt)__ < <<- ~>> " <" __<i>/html(p_html_gt)__ > <<- ~>> > __<i>/html(p_html_amp)__ & <<- ~>> & __<i>/html(p_html_nbsp)__ <<- ~>> * __<i>/html(p_html_balise_ouvrante)__ <\w+.*?> <<- ~>> * __<i>/html(p_html_balise_fermante)__ </\w+ *> <<- ~>> * __<i>/html(p_html_pseudo_balise)__ \[/?\w+\] <<- ~>> * # LATEX __<i]/latex(p_latex1)__ \\[a-z]+ <<- ~>> * __<i>/latex(p_latex2)__ \\[,;/\\] <<- ~>> * __<s>/latex(p_latex3)__ \{(?:abstract|align|cases|center|description|enumerate|equation|figure|flush(?:left|right)|gather|minipage|multline|quot(?:ation|e)|SaveVerbatim|table|tabular|thebibliography|[vV]erbatim|verse|wrapfigure)\} <<- ~>> * | > > > > > > | < < < | | < | > | 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 | TEST: C’est le b.a.-ba du métier. TEST: qui a été le plus honnête [Rires] TEST: Marion Maréchal-Le Pen. Afin que Maréchal ne soit pas analysé comme un impératif, “Le Pen” devient “Le_Pen”. TEST: Car [je] deviendrai plus insaisissable que jamais. #TEST: des <b>{{homme}}</b> #TEST: des [b]{{femme}}[/b] !!! !!! !!! Processeur: balises HTML et LaTeX !!! !!! # HTML __<i>/html(p_html_amp_xxx)__ &[a-zA-Z]+; <<- ~>> _ __<i>/html(p_html_lt)__ < <<- ~>> " <" __<i>/html(p_html_gt)__ > <<- ~>> > __<i>/html(p_html_amp)__ & <<- ~>> & __<i>/html(p_html_nbsp)__ <<- ~>> * __<i>/html(p_html_balise_ouvrante)__ <\w+.*?> <<- ~>> * __<i>/html(p_html_balise_fermante)__ </\w+ *> <<- ~>> * __<i>/html(p_html_pseudo_balise)__ \[/?\w+\] <<- ~>> * # LATEX __<i]/latex(p_latex1)__ \\[a-z]+ <<- ~>> * __<i>/latex(p_latex2)__ \\[,;/\\] <<- ~>> * __<s>/latex(p_latex3)__ \{(?:abstract|align|cases|center|description|enumerate|equation|figure|flush(?:left|right)|gather|minipage|multline|quot(?:ation|e)|SaveVerbatim|table|tabular|thebibliography|[vV]erbatim|verse|wrapfigure)\} <<- ~>> * !! !! !!!! Typographie, virgules, espaces insécables, unités de mesure… !! !! ### Écritures épicènes invariables # Attention, lors de la deuxième passe, on se sert du désambiguïsateur __[u](typo_écriture_épicène_pluriel)__ ({w_1}[éuitsrn])[-·–—.(/]([nt]|)e[-·–—.)/]s @@0,** <<- option("typo") and not \0.endswith("·e·s") ->> \1s et \1\2es|\1\2es et \1s|\1·\2e·s # Écriture épicène brouillon. Préférez écrire lisiblement. Sinon, utilisez les points médians. |
︙ | ︙ | |||
903 904 905 906 907 908 909 | __[s]/chim(chim_molécules)__ (?:Ca(?:CO3|SO4)|CO2|(?:H2|Na2)(?:CO3|O|SO4)|[HNO]2|HNO3|Fe2O3|KMnO4|NO2|SiO2|SO[23]) <<- ->> =\0.replace("2", "₂").replace("3", "₃").replace("4", "₄") # Typographie des composés chimiques. [!] TEST: __chim__ les molécules {{CaCO3}} et {{H2O}}… | < < < > | 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 | __[s]/chim(chim_molécules)__ (?:Ca(?:CO3|SO4)|CO2|(?:H2|Na2)(?:CO3|O|SO4)|[HNO]2|HNO3|Fe2O3|KMnO4|NO2|SiO2|SO[23]) <<- ->> =\0.replace("2", "₂").replace("3", "₃").replace("4", "₄") # Typographie des composés chimiques. [!] TEST: __chim__ les molécules {{CaCO3}} et {{H2O}}… !!!! Grands nombres __[s]/num(num_grand_nombre_soudé)__ \d\d\d\d\d+ <<- not before("NF[ -]?(C|E|P|Q|X|Z|EN(?:[ -]ISO|)) *") ->> =formatNumber(\0) # Formatage des grands nombres. TEST: {{12345}} ->> 12 345 TEST: {{123456}} ->> 123 456 |
︙ | ︙ | |||
939 940 941 942 943 944 945 | <<- option("num") ->> =\0.replace(" ", " ") # Grands nombres : utilisez des espaces insécables. <<- ~>> =\0.replace(" ", "") TEST: Il a perdu {{20 000}} euros à la Bourse en un seul mois. | > | < < < < < > | | < < | < > > | < < < < < < < < < < < < < < < < < < < < > > > > > > > > > > > > > > > > > > > | < > > > > > > > > > > > > > > > > > > > > | < < < < < < < < < < < < < < < < < < < < | | < < < > | 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 | <<- option("num") ->> =\0.replace(" ", " ") # Grands nombres : utilisez des espaces insécables. <<- ~>> =\0.replace(" ", "") TEST: Il a perdu {{20 000}} euros à la Bourse en un seul mois. !!!! Dates __[i]/date(date_nombres)__ (?<!\d[ /.-])(\d\d?)[ /.-](\d\d?)[ /.-](\d\d\d+)(?![ /.-]\d) @@0,w,$ <<- not checkDate(\1, \2, \3) and not before(r"(?i)\bversions? +$") ->> _ # Cette date est invalide. <<- ~>> =\0.replace(".", "-").replace(" ", "-").replace("\/", "-") TEST: le {{29 02 2011}} TEST: le {{40-02-2011}} TEST: le {{32.03.2018}} TEST: le {{81/01/2012}} TEST: 12-12-2012 !!!! Redondances __[i]/redon1(redondances_paragraphe)__ ({w_4})[ ,.;!?:].*[ ](\1) @@0,$ <<- not morph(\1, ":(?:G|V0)|>(?:t(?:antôt|emps|rès)|loin|souvent|parfois|quelquefois|côte|petit|même) ", False) and not \1[0].isupper() -2>> _ # Dans ce paragraphe, répétition de « \1 » (à gauche). <<- __also__ -1>> _ # Dans ce paragraphe, répétition de « \1 » (à droite). TEST: __redon1__ Tu es son {{avenir}}. Et lui aussi est ton {{avenir}}. TEST: __redon1__ Car parfois il y en a. Mais parfois il n’y en a pas. !!! !!! !!! Processeur: Dernier nettoyage avant coupure du paragraphe en phrases !!! !!! # Trait d’union conditionnel (u00AD) __<i>(p_trait_union_conditionnel1)__ \w+‑\w+‑\w+ <<- ~>> =\0.replace("‑", "") __<i>(p_trait_union_conditionnel2)__ \w+‑\w+ <<- ~>> =\0.replace("‑", "") # empêcher la scission en fin de dialogue __<s>(p_fin_dialogue1)__ ([?!…][?!… ]*)[ "'”» ]*, @@0 <<- ~1>> * __<s>(p_fin_dialogue2)__ ([?!…][?!… ]*)[ "'”» ]*[a-zéèêîô] @@0 <<- ~1>> , TEST: « Je suis donc perdu ? », dit Paul. TEST: “C’est bon !”, croit savoir Marie. TEST: “Parce que… ?” finit par demander Paul. TEST: « Dans quel pays sommes-nous ? » demanda un manifestant. !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! PASSE 1: PHRASE PAR PHRASE !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! [++] !!!! Doublons (casse identique) __[s](doublon)__ ({w1}) {1,3}\1 @@0 <<- not re.search("(?i)^([nv]ous|faire|en|la|lui|donnant|œuvre|h[éoa]|hou|olé|joli|Bora|couvent|dément|sapiens|très|vroum|[0-9]+)$", \1) and not (re.search("^(?:est|une?)$", \1) and before("[’']$")) and not (\1 == "mieux" and before("(?i)qui +$")) ->> \1 # Doublon. TEST: Il y a un {{doublon doublon}}. !!!! Nombres: typographie #(\d\d\d\d)-(\d\d\d\d) <<- ->> \1–\2 # Ne pas séparer deux dates par un trait d’union, mais par un tiret demi-cadratin. __[s]/num(num_lettre_O_zéro1)__ [\dO]+[O][\dO]+ <<- not option("ocr") ->> =\0.replace("O", "0") # S’il s’agit d’un nombre, utilisez le chiffre « 0 » plutôt que la lettre « O ». __[s]/num(num_lettre_O_zéro2)__ [1-9]O <<- not option("ocr") ->> =\0.replace("O", "0") # S’il s’agit d’un nombre, utilisez le chiffre « 0 » plutôt que la lettre « O ». TEST: année {{2O11}} ->> 2011 |
︙ | ︙ | |||
1073 1074 1075 1076 1077 1078 1079 | TEST: le {{VIième}} siècle ->> VIᵉ|VIe TEST: C’est la {{3ème}} fois… ->> 3ᵉ|3e TEST: Non, la {{2è}} fois. ->> 2ᵉ|2e TEST: Le {{XXIème}} siècle. ->> XXIᵉ|XXIe TEST: le {{XXè}} siècle. ->> XXᵉ|XXe | | | | < < < > | 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 | TEST: le {{VIième}} siècle ->> VIᵉ|VIe TEST: C’est la {{3ème}} fois… ->> 3ᵉ|3e TEST: Non, la {{2è}} fois. ->> 2ᵉ|2e TEST: Le {{XXIème}} siècle. ->> XXIᵉ|XXIe TEST: le {{XXè}} siècle. ->> XXᵉ|XXe !!!! Écritures épicènes invariables __[i](d_typo_écriture_épicène_pluriel)__ ({w_1}[éuitsrn])-(?:[nt]|)e-s @@0 <<- morphex(\1, ":[NAQ]", ":G") =>> define(\1, [":N:A:Q:e:p"]) __[i](d_typo_écriture_épicène_singulier)__ ({w_2}[éuitsrn])-e @@0 <<- morph(\1, ":[NAQ]", False) =>> define(\1, [":N:A:Q:e:s"]) !!!! Dates __[i]/date(date_jour_mois_année)__ (\d\d?) (janvier|février|ma(?:rs|i)|a(?:vril|o[ûu]t)|jui(?:n|llet)|septembre|octobre|novembre|décembre) (\d\d\d+) @@0,w,$ <<- not checkDateWithString(\1, \2, \3) ->> _ # Cette date est invalide. TEST: {{29 février 2011}} |
︙ | ︙ | |||
1127 1128 1129 1130 1131 1132 1133 | __[i]/date(date_février)__ 3[01] février <<- ->> 28 février|29 février # Cette date est invalide. Il n’y a que 28 ou 29 jours en février. TEST: le {{30 février}} | < < > > | < > > | 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 | __[i]/date(date_février)__ 3[01] février <<- ->> 28 février|29 février # Cette date est invalide. Il n’y a que 28 ou 29 jours en février. TEST: le {{30 février}} !!! !!! !!! Processeur: épuration des signes inutiles et quelques simplifications !!! !!! # fin de phrase __<s>(p_fin_de_phrase)__ [.?!:;…][ .?!… »”")]*$ <<- ~>> * # début de phrase __<s>(p_début_de_phrase)__ ^ *[-–—] <<- ~>> * |
︙ | ︙ | |||
1196 1197 1198 1199 1200 1201 1202 | [A-Z][a-z]+ [A-Z][a-z]+ <<- spell(\0.replace(" ", "_")) ~>> =\0.replace(" ", "_") TEST: New York {{étaient}} {{devenue}} la plaque tournante de tous les trafics. | | < > | < | | < | 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 | [A-Z][a-z]+ [A-Z][a-z]+ <<- spell(\0.replace(" ", "_")) ~>> =\0.replace(" ", "_") TEST: New York {{étaient}} {{devenue}} la plaque tournante de tous les trafics. !! !! !!!! Traits d’union !! !! __<i]/tu(tu_t_euphonique1)__ (-t[’' ])(il|elle|on) @@0,$ <<- -1>> -t- # Pour le “t” euphonique, il faut deux traits d’union. __<i]/tu(tu_t_euphonique2)__ ( t[-’' –—])(il|elle|on) @@0,$ <<- -1>> -t- # Pour le “t” euphonique, il faut deux traits d’union. __<i]/tu(tu_t_euphonique3)__ ([- ]t[-’'])tu @@0 |
︙ | ︙ | |||
1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 | lors que? <<- not before(r"(?i)\bd[eè]s +$") ->> =\0.replace(" ", "") # Attachez les deux mots.|https://fr.wiktionary.org/wiki/lorsque TEST: Elle y arriva {{lors qu}}’elle trouva l’astuce permettant l’ouverture de la porte. TEST: Dès lors qu’on sait comment s’y prendre, aucune raison de faillir. # Dialogues __[u]/virg(virgule_dialogue_après_nom_propre)__ ([A-ZÉÈ][\w-]+) (\w+-(?:moi|toi|l(?:ui|a|e(?:ur|s|))|nous|vous|je|tu|ils|elles)) @@0,$ <<- morphex(\1, ":M", ":G") and not morph(\2, ":N", False) and isStart() -1>> \1, # Dialogue ? Ajoutez une virgule pour mettre en incise la personne à qui s’adresse la réplique. TEST: {{Maria}} donnez-vous du temps ? | > > | 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 | lors que? <<- not before(r"(?i)\bd[eè]s +$") ->> =\0.replace(" ", "") # Attachez les deux mots.|https://fr.wiktionary.org/wiki/lorsque TEST: Elle y arriva {{lors qu}}’elle trouva l’astuce permettant l’ouverture de la porte. TEST: Dès lors qu’on sait comment s’y prendre, aucune raison de faillir. !!!! Virgules # Dialogues __[u]/virg(virgule_dialogue_après_nom_propre)__ ([A-ZÉÈ][\w-]+) (\w+-(?:moi|toi|l(?:ui|a|e(?:ur|s|))|nous|vous|je|tu|ils|elles)) @@0,$ <<- morphex(\1, ":M", ":G") and not morph(\2, ":N", False) and isStart() -1>> \1, # Dialogue ? Ajoutez une virgule pour mettre en incise la personne à qui s’adresse la réplique. TEST: {{Maria}} donnez-vous du temps ? |
︙ | ︙ | |||
1632 1633 1634 1635 1636 1637 1638 | -1>> \1, # Une virgule est probablement souhaitable. TEST: Tu vas les {{donner}} Rachel. TEST: Il va la {{tuer}} Paul. TEST: Cependant les promesses n’engagent que ceux qui les croient, comme aimait à le dire Jacques Chirac. | > | > | | > < < < > > > > > | 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 | -1>> \1, # Une virgule est probablement souhaitable. TEST: Tu vas les {{donner}} Rachel. TEST: Il va la {{tuer}} Paul. TEST: Cependant les promesses n’engagent que ceux qui les croient, comme aimait à le dire Jacques Chirac. !!!! Apostrophe manquante (2) __<s>/typo(typo_apostrophe_manquante_audace2)__ ^ *([LDSNCJMTÇ] )[aeéiouhAEÉIOUHyîèêôûYÎÈÊÔÛ] @@* <<- option("mapos") -1>> =\1[:-1]+"’" # Il manque peut-être une apostrophe. TEST: __mapos__ {{L }}opinion des gens, elle s’en moquait. !!!! A / À: accentuation la préposition en début de phrase __<s]/typo(typo_À_début_phrase1)__ ^ *(A) (?!t[’-](?:ils?|elles?|on))({w_2}) @@*,$ <<- morphex(\2, ":[GNAY]", ":(?:Q|3s)|>(?:priori|post[eé]riori|contrario|capella|fortiori) ") -1>> À # S’il s’agit de la préposition « à », il faut accentuer la majuscule. __<s>/typo(typo_À_début_phrase2)__ ^ *(A) [ldnms]’ @@* <<- -1>> À # S’il s’agit de la préposition « à », il faut accentuer la majuscule. __<s>/typo(typo_À_début_phrase3)__ ^ *(A) t’(?!il |elle |ont? ) @@* <<- -1>> À # S’il s’agit de la préposition « à », il faut accentuer la majuscule. TEST: {{A}} vaincre sans péril, on triomphe sans gloire. TEST: « {{A}} partir de maintenant, ce ne sera plus comme avant. TEST: — {{A}} n’en plus pouvoir TEST: — {{A}} t’emmener loin de tout ceci. TEST: A priori, nul ne peut y parvenir sans une aide extérieure. !!! !!! !!! Désambiguïsation !!! !!! # mots grammaticaux __[i](d_dans)__ dans <<- not morph(word(-1), ":D.*:p|>[a-z]+ièmes ", False, False) =>> select(\0, ":R") # verbe |
︙ | ︙ | |||
1733 1734 1735 1736 1737 1738 1739 | TEST: il s’agit d’{{un}} {{anagramme}} TEST: nul ne sait qui arriva à ce pauvre Paul surpris par la pluie. TEST: elle finit par être très fière de son fils. | | < | | | < > > > | 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 | TEST: il s’agit d’{{un}} {{anagramme}} TEST: nul ne sait qui arriva à ce pauvre Paul surpris par la pluie. TEST: elle finit par être très fière de son fils. !! !! !!!! OCR !! !! # ? __<s]/ocr(ocr_point_interrogation)__ [ ]7 <<- after0("^(?: +[A-ZÉÈÂ(]|…|[.][.]+| *$)") ->> " ?" # Erreur de numérisation ? TEST: __ocr__ des chiffrements{{ 7}} Paul n’en sait rien. |
︙ | ︙ | |||
2369 2370 2371 2372 2373 2374 2375 | <<- \0 != "<" and \0 != ">" ->> _ # Erreur de numérisation ? Cette chaîne contient un caractère de fréquence rare. TEST: __ocr__ trouve {{l£}} temps TEST: __ocr__ elle s’{{avance*}} sur le seuil TEST: __ocr__ par beaucoup d’argent ? {{{Il}} débouche le Jack Daniels | < | > > > > | 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 | <<- \0 != "<" and \0 != ">" ->> _ # Erreur de numérisation ? Cette chaîne contient un caractère de fréquence rare. TEST: __ocr__ trouve {{l£}} temps TEST: __ocr__ elle s’{{avance*}} sur le seuil TEST: __ocr__ par beaucoup d’argent ? {{{Il}} débouche le Jack Daniels !! !! !!!! Incohérences de base !! !! ### double négation __[i](double_négation)__ pas (personne|aucune?|jamais) @@4 <<- not morph(word(-1), ":D:[me]" ,False, False) ->> \1|pas, \1 # Double négation : les mots « pas \1 » ne devraient pas se succéder. Si ces mots appartiennent à des propositions distinctes, une virgule est peut-être préférable. |
︙ | ︙ | |||
2400 2401 2402 2403 2404 2405 2406 | TEST: Au MES, rien de nouveau TEST: {{Ces}} {{cette}} canaille qui nous a donné tant de fil à retordre. TEST: Mon {{il}} est une merveille. TEST: je ne sais {{des}} {{ses}} choses. | < | > | > > | 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 | TEST: Au MES, rien de nouveau TEST: {{Ces}} {{cette}} canaille qui nous a donné tant de fil à retordre. TEST: Mon {{il}} est une merveille. TEST: je ne sais {{des}} {{ses}} choses. !! !! !!!! Style !! !! #__bs__ Mr <<- ->> M. # M. est l’usage courant pour “Monsieur”. « Mr » est l’abréviation ancienne, française. # à / en __[i]/bs(bs_en_à_ville)__ (en) A(?:gen|miens|ngers|jjacio|rles|vignon) @@0 <<- -1>> à # On utilise la préposition “à” avant les villes (à Avignon, à Arles…), la préposition “en” avant les régions (en Amérique, en Afrique…). |
︙ | ︙ | |||
2499 2500 2501 2502 2503 2504 2505 | malgré (que?) @@7 <<- not after_chk1(r" \w[\w-]+ en ([aeo][a-zû]*)", ":V0a") ->> bien \1 # Tournure populaire. Utilisez « bien que ». TEST: {{Malgré que}} je sois fou. | < < > > | > > | 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 | malgré (que?) @@7 <<- not after_chk1(r" \w[\w-]+ en ([aeo][a-zû]*)", ":V0a") ->> bien \1 # Tournure populaire. Utilisez « bien que ». TEST: {{Malgré que}} je sois fou. ######### Expressions impropres #([mts]e|[nv]ous) (rappel\w+) (de) <<- word(1) != "ne" and not morph(word(1), ":V") # -3>> _ # Expression impropre. « Se rappeler quelque chose » ou « Se souvenir de quelque chose ». #Se rappelle de l’amour #enjoindre à qqn de faire qqch !! !! !!!! Pléonasmes !! !! __[i]/pleo(pleo_abolir)__ (abol\w+) (?:absolument|entièrement|compl[èé]tement|totalement) @@0 <<- morph(\1, ">abolir ", False) ->> \1 # Pléonasme. __[i]/pleo(pleo_acculer)__ (accul\w+) aux? pieds? du mur @@0 <<- morph(\1, ">acculer ", False) ->> \1 # Pléonasme. __[i]/pleo(pleo_achever)__ (ach[eè]v\w+) (?:absolument|entièrement|compl[èé]tement|totalement) @@0 <<- morph(\1, ">achever ", False) ->> \1 # Pléonasme. __[i]/pleo(pleo_en_cours)__ actuellement en cours <<- not after(r" +de?\b") ->> en cours # Pléonasme. __[i]/pleo(pleo_en_train_de)__ (actuellement en train) d(?:e(?! nuit)|’{w_2}) @@0 <<- -1>> en train # Pléonasme. __[i]/pleo(pleo_ajouter)__ (ajout\w+) en plus @@0 <<- ->> \1 # Pléonasme. |
︙ | ︙ | |||
2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 | <<- morph(\1, ">(?:ajourner|différer|reporter) ", False) ->> \1 # Pléonasme. TEST: {{Ajourner à une date ultérieure}} ->> Ajourner TEST: {{différer à une date ultérieure}} ->> différer TEST: {{reporter à plus tard}} ->> reporter # ayants droit __[i]/sgpl(sgpl_ayants_droit)__ [ldcs]es (ayant[- ]droits?) @@4 <<- -1>> ayants droit # Au singulier : « un ayant droit ». Au pluriel : « des ayants droit ». TEST: Comment lutter contre la cupidité des {{ayant droits}} # Note: À supprimer? Graphie qui tend vers la soudure et le pluriel régulier (ayant-droit(s)) # Mon, ton, son : euphonie __[i]/gn(gn_mon_ton_son_euphonie)__ ([mts]a) +({w_2}) @@0,$ <<- morphex(\2, ">[aâeéèêiîoôuûyœæ].+:[NAQ].*:f", ":[eGW]") -1>> =\1.replace("a", "on") # Même si « \2 » est féminin, on utilise « mon/ton/son » pour faire la liaison.|http://fr.wikipedia.org/wiki/Euphonie TEST: {{ta}} aimée ->> ton TEST: {{ma}} obligée ->> mon TEST: Ce couple va donner à la France sa très importante collection qui rejoindra le musée d’Orsay | > > > > > > < | 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 | <<- morph(\1, ">(?:ajourner|différer|reporter) ", False) ->> \1 # Pléonasme. TEST: {{Ajourner à une date ultérieure}} ->> Ajourner TEST: {{différer à une date ultérieure}} ->> différer TEST: {{reporter à plus tard}} ->> reporter # ayants droit __[i]/sgpl(sgpl_ayants_droit)__ [ldcs]es (ayant[- ]droits?) @@4 <<- -1>> ayants droit # Au singulier : « un ayant droit ». Au pluriel : « des ayants droit ». TEST: Comment lutter contre la cupidité des {{ayant droits}} # Note: À supprimer? Graphie qui tend vers la soudure et le pluriel régulier (ayant-droit(s)) # Mon, ton, son : euphonie __[i]/gn(gn_mon_ton_son_euphonie)__ ([mts]a) +({w_2}) @@0,$ <<- morphex(\2, ">[aâeéèêiîoôuûyœæ].+:[NAQ].*:f", ":[eGW]") -1>> =\1.replace("a", "on") # Même si « \2 » est féminin, on utilise « mon/ton/son » pour faire la liaison.|http://fr.wikipedia.org/wiki/Euphonie TEST: {{ta}} aimée ->> ton TEST: {{ma}} obligée ->> mon TEST: Ce couple va donner à la France sa très importante collection qui rejoindra le musée d’Orsay !! !! !!!! Confusions !! !! __[s>/conf(conf_ne_n)__ [nN]e n’ <<- ->> ne m’|n’ # Incohérence. Double négation. __[s>/conf(conf_pronoms1)__ [mtMT]e ([nmst](?:’|e )) @@$ <<- ->> \1 # Incohérence. __[s>/conf(conf_pronoms2)__ [sS]e ([mst](?:’|e )) @@$ <<- ->> \1 # Incohérence. __[s>/conf(conf_de_d)__ [dD][eu] d’(?![A-ZÉÂÔÈ]) <<- ->> d’ # Incohérence. TEST: Il {{ne n’}}arrive jamais à l’heure. TEST: Ça {{me te }}prend la tête, toutes ces complications vaines. |
︙ | ︙ | |||
3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 | TEST: M’enfin, c’est absurde TEST: il est normal de ne presque pas payer des gens qui effectuent un travail TEST: j’ai l’impression de ne même pas savoir ce qu’est un « juif français ». TEST: C’que j’comprends, c’est qu’il y a des limites à ce qu’on peut supporter. TEST: la tentation pour certains médias de ne tout simplement pas rémunérer notre travail si celui-ci n’est finalement pas publié. TEST: Ne parfois pas être celui qui sabote l’ambiance. ## Incohérences avec formes verbales 1sg et 2sg sans sujet __[i](p_notre_père_qui_es_au_cieux)__ notre père (qui est? aux cieux) @@11 <<- ~1>> * __[i]/conj(conj_xxxai_sans_sujet)!3__ \w*ai(?! je) <<- ( morph(\0, ":1s") or ( before("> +$") and morph(\0, ":1s", False) ) ) and not (\0[0:1].isupper() and before0(r"\w")) | > > > > > | 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 | TEST: M’enfin, c’est absurde TEST: il est normal de ne presque pas payer des gens qui effectuent un travail TEST: j’ai l’impression de ne même pas savoir ce qu’est un « juif français ». TEST: C’que j’comprends, c’est qu’il y a des limites à ce qu’on peut supporter. TEST: la tentation pour certains médias de ne tout simplement pas rémunérer notre travail si celui-ci n’est finalement pas publié. TEST: Ne parfois pas être celui qui sabote l’ambiance. !! !! !!!! Formes verbales sans sujet !! !! ## Incohérences avec formes verbales 1sg et 2sg sans sujet __[i](p_notre_père_qui_es_au_cieux)__ notre père (qui est? aux cieux) @@11 <<- ~1>> * __[i]/conj(conj_xxxai_sans_sujet)!3__ \w*ai(?! je) <<- ( morph(\0, ":1s") or ( before("> +$") and morph(\0, ":1s", False) ) ) and not (\0[0:1].isupper() and before0(r"\w")) |
︙ | ︙ | |||
3938 3939 3940 3941 3942 3943 3944 | TEST: plus rapide que {{prévues}} ->> prévu TEST: autant d’hommes que {{prévus}} ->> prévu TEST: il y en a moins que {{prévues}} ->> prévu TEST: comme {{convenus}} ->> convenu | < > > > > > | 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 | TEST: plus rapide que {{prévues}} ->> prévu TEST: autant d’hommes que {{prévus}} ->> prévu TEST: il y en a moins que {{prévues}} ->> prévu TEST: comme {{convenus}} ->> convenu !! !! !!!! Tout, tous, toute, toutes !! !! __[i](p_fais_les_tous)__ fai(?:tes|sons|s)-(?:les|[nv]ous) (tou(?:te|)s) @@$ <<- ~1>> * __[i](p_tout_débuts_petits)__ (tout) (?:débuts|petits) @@0 <<- before(r"\b(aux|[ldmtsc]es|[nv]os|leurs) +$") ~1>> * __[i](p_les_tout_xxx)__ (?:[ldmtsc]es|[nv]os|leurs|aux) (tout) ({w_2}) @@w,$ |
︙ | ︙ | |||
4036 4037 4038 4039 4040 4041 4042 | TEST: Tout les sépare. TEST: les tout débuts du mouvement ouvrier TEST: vos tout débuts furent difficiles TEST: aux tout débuts, il y eut bien des erreurs TEST: comment les inégalités sociales impactent la santé des tout petits | | > > > > > | 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 | TEST: Tout les sépare. TEST: les tout débuts du mouvement ouvrier TEST: vos tout débuts furent difficiles TEST: aux tout débuts, il y eut bien des erreurs TEST: comment les inégalités sociales impactent la santé des tout petits !! !! !!!! Adverbes de négation !! !! __[i]/neg(ne_manquant1)__ (?:je|tu|ils?|on|elles?) ([bcdfgjklmnpqrstvwxz][\w-]*) (pas|rien|jamais|guère) @@w,$ <<- morph(\1, ":[123][sp]", False) and not (re.search("(?i)^(?:jamais|rien)$", \2) and before(r"\b(?:que?|plus|moins) ")) -1>> ne \1 # Ne … \2 : il manque l’adverbe de négation. __[i]/neg(ne_manquant2)__ |
︙ | ︙ | |||
4098 4099 4100 4101 4102 4103 4104 | TEST: déterminés à ne pas se laisser récupérer TEST: de ne pas en élire du tout TEST: Mais gare à ne pas non plus trop surestimer la menace TEST: ne jamais beaucoup bosser, c’est sa devise. | | < < > | < > > | 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 | TEST: déterminés à ne pas se laisser récupérer TEST: de ne pas en élire du tout TEST: Mais gare à ne pas non plus trop surestimer la menace TEST: ne jamais beaucoup bosser, c’est sa devise. !!! !!! !!! Processeur: épuration des adverbes, locutions adverbiales, interjections et expressions usuelles !!! !!! # Dates __[s](p_date)__ (?:[dD]epuis le|[lL]e|[dD]u|[aA]u|[jJ]usqu au|[àÀ] compter du) (?:1(?:er|ᵉʳ)|\d\d?) (?:janvier|février|mars|avril|mai|juin|juillet|ao[ûu]t|septembre|octobre|novembre|décembre|vendémiaire|brumaire|frimaire|nivôse|pluviôse|ventôse|germinal|floréal|prairial|messidor|thermidor|fructidor)(?: \d+| dernier| prochain|) <<- ~>> * __[i](p_en_l_an_de_grâce_année)__ en l’an (?:de grâce |)\d+ <<- ~>> * __[s](p_en_de_mois_année)__ |
︙ | ︙ | |||
4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 | __[i](p_sac)__ sacs? (à (?:dos|main|langer)|de (?:couchage|sport|voyage)) @@$ <<- ~1>> * __[i](p_salle)__ salles? (à manger|d’attente|de (?:bains?|conférence)) @@$ <<- ~1>> * __[i](p_sain_de_corps)__ saine?s? (d(?:e corps et d|)’esprit) @@$ <<- ~1>> * __[i](p_sclérose_en_plaques)__ scléroses? (en plaques) @@$ <<- ~1>> * __[i](p_sembler_paraitre_être)__ (sembl\w+|par[au]\w+) +(être|avoir été) +({w_2}) @@0,w,$ <<- morph(\1, ">(?:sembler|para[îi]tre) ") and morphex(\3, ":A", ":G") ~2>> * __[u](p_système)__ systèmes? (d’exploitation|D) @@$ <<- ~1>> * __[i](p_taille)__ taille (\d+) @@$ <<- ~1>> * __[i](p_tête_de_déterré)__ têtes? (de déterrée?s?) @@$ <<- ~1>> * __[i](p_tenir_compte)__ (t[eiî]\w+) +(compte) d(?:es?|u) @@0,w <<- morph(\1, ">tenir ", False) ~2>> * __[i](p_tout_un_chacun)__ (tout un) chacun @@0 <<- ~1>> * __[i](p_tour_de_passe_passe)__ tours? (de passe-passe) @@$ <<- ~1>> * __[i](p_trier_sur_le_volet)__ (tri\w+) (sur le volet) @@0,$ <<- morph(\1, ">trier ", False) ~2>> * __[i](p_tueur_à_gages)__ tueu(?:r|se)s? (à gages) @@$ <<- ~1>> * __[i](p_venir)__ (v[eiî]n\w+) ((?:on ne sait|je ne sais) (?:pas |)(?:trop |)d’où) @@0,$ <<- morph(\1, ">venir ", False) ~2>> * | > | 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 | __[i](p_sac)__ sacs? (à (?:dos|main|langer)|de (?:couchage|sport|voyage)) @@$ <<- ~1>> * __[i](p_salle)__ salles? (à manger|d’attente|de (?:bains?|conférence)) @@$ <<- ~1>> * __[i](p_sain_de_corps)__ saine?s? (d(?:e corps et d|)’esprit) @@$ <<- ~1>> * __[i](p_sclérose_en_plaques)__ scléroses? (en plaques) @@$ <<- ~1>> * __[i](p_sembler_paraitre_être)__ (sembl\w+|par[au]\w+) +(être|avoir été) +({w_2}) @@0,w,$ <<- morph(\1, ">(?:sembler|para[îi]tre) ") and morphex(\3, ":A", ":G") ~2>> * __[u](p_système)__ systèmes? (d’exploitation|D) @@$ <<- ~1>> * __[i](p_taille)__ taille (\d+) @@$ <<- ~1>> * __[i](p_taux_de_qqch)__ taux (d’(?:abstention|alcool|alphabétisation|endettement|inflation|intérêt|imposition|occupation|ouverture|œstrogène|urée|usure)|de (?:change|cholest[ée]rol|glycémie|fécondité|participation|testostérone|TVA)) @@$ <<- ~1>> * __[i](p_tête_de_déterré)__ têtes? (de déterrée?s?) @@$ <<- ~1>> * __[i](p_tenir_compte)__ (t[eiî]\w+) +(compte) d(?:es?|u) @@0,w <<- morph(\1, ">tenir ", False) ~2>> * __[i](p_tout_un_chacun)__ (tout un) chacun @@0 <<- ~1>> * __[i](p_tour_de_passe_passe)__ tours? (de passe-passe) @@$ <<- ~1>> * __[i](p_trier_sur_le_volet)__ (tri\w+) (sur le volet) @@0,$ <<- morph(\1, ">trier ", False) ~2>> * __[i](p_tueur_à_gages)__ tueu(?:r|se)s? (à gages) @@$ <<- ~1>> * __[i](p_venir)__ (v[eiî]n\w+) ((?:on ne sait|je ne sais) (?:pas |)(?:trop |)d’où) @@0,$ <<- morph(\1, ">venir ", False) ~2>> * |
︙ | ︙ | |||
4717 4718 4719 4720 4721 4722 4723 | # couleurs invariables __[i](p_couleurs_invariables)__ ({w_2}) +((?:beige|blanc|bleu|brun|châtain|cyan|gris|jaune|magenta|marron|orange|pourpre|rose|rouge|vert|violet) (?:clair|fluo|foncé|irisé|pâle|pastel|sombre|vif|tendre)) @@0,$ <<- morph(\1, ":[NAQ]", False) ~2>> * # locutions adjectivales, nominales & couleurs __[i](p_locutions_adj_nom_et_couleurs)__ | | | 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 | # couleurs invariables __[i](p_couleurs_invariables)__ ({w_2}) +((?:beige|blanc|bleu|brun|châtain|cyan|gris|jaune|magenta|marron|orange|pourpre|rose|rouge|vert|violet) (?:clair|fluo|foncé|irisé|pâle|pastel|sombre|vif|tendre)) @@0,$ <<- morph(\1, ":[NAQ]", False) ~2>> * # locutions adjectivales, nominales & couleurs __[i](p_locutions_adj_nom_et_couleurs)__ ({w_2}) +(bas(?: de gamme|se consommation)|bon (?:enfant|marché|teint|chic,? bon genre)|cl(?:é|ef) en mains?|dernier cri|fleur bleue|grand (?:public|luxe)|grandeur nature|haut(?: de gamme|e résolution)|longue (?:distance|portée|durée)|meilleur marché|numéro (?:un|deux|trois|quatre|cinq|six|sept|huit|neuf|dix(?:-sept|-huit|-neuf)|onze|douze|treize|quatorze|quinze|seize|vingt)|plein cadre|top secret|vieux jeu|open source|Créative Commons|pair à pair|pur jus|terre à terre|bleu (?:ciel|marine|roi|saphir|turquoise)|vert (?:émeraude|olive|pomme)|rouge (?:brique|carmin|écarlate|rubis|sang)|jaune sable|blond platine|gris (?:acier|anthracite|perle|souris)|noir (?:d(?:’encre|e jais)|et blanc)) @@0,$ <<- morph(\1, ":(?:N|A|Q|V0e)", False) ~2>> * # tous / tout / toute / toutes __[i](p_tout_déterminant_masculin)__ (tout) (?:le|cet?|[mts]on) @@0 <<- ~1>> * __[i](p_toute_déterminant_féminin)__ (toute) (?:la|cette|[mts]a) @@0 <<- ~1>> * __[i](p_tous_toutes_déterminant_pluriel)__ (tou(?:te|)s) (?:[ldscsmt]es|[nv]os) @@0 <<- ~1>> * |
︙ | ︙ | |||
4850 4851 4852 4853 4854 4855 4856 4857 4858 | TEST: il devenait chaque année plus grand. TEST: Elle fut dès le départ structurée ainsi. TEST: Ben voyons, c’est sûr, aucun problème ! TEST: ça peut être dans huit jours. TEST: La secrétaire d’Etat à l’égalité entre les femmes et les hommes hérite de la lutte contre les discriminations TEST: les populistes d’Europe centrale et de l’Est ont d’ores et déjà tellement réussi à compromettre les institutions de leur pays TEST: Deirdre, elle aussi légèrement ostracisée, m’interrogea. | > < > > > > > | 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 | TEST: il devenait chaque année plus grand. TEST: Elle fut dès le départ structurée ainsi. TEST: Ben voyons, c’est sûr, aucun problème ! TEST: ça peut être dans huit jours. TEST: La secrétaire d’Etat à l’égalité entre les femmes et les hommes hérite de la lutte contre les discriminations TEST: les populistes d’Europe centrale et de l’Est ont d’ores et déjà tellement réussi à compromettre les institutions de leur pays TEST: Deirdre, elle aussi légèrement ostracisée, m’interrogea. TEST: des échanges pair à pair !!! !!! !!! Désambiguïsation (deprecated) !!! !!! #__[i]__ ({avoir}) +({w_1}[eiuts]) @@0,$ # <<- morph(\1, ":V0a", False) and morphex(\1, ":Q", ":G") # =>> exclude(\2, ":A") ### Désambiguïsation par séparation de le/la/les avec la suite s’il s’agit de COD dans les syntagmes verbaux __[i>(p_astuce_je_le_la_les)__ |
︙ | ︙ | |||
4887 4888 4889 4890 4891 4892 4893 | # # //////////////////////////////////////// RÈGLES DE CONTRÔLE //////////////////////////////////////// # | | < > > > > > | 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 | # # //////////////////////////////////////// RÈGLES DE CONTRÔLE //////////////////////////////////////// # !!!! Redondances dans la phrase __[i]/redon2(redondances_phrase)__ ({w_4})[ ,].* (\1) @@0,$ <<- not morph(\1, ":(?:G|V0)|>même ", False) -2>> _ # Dans cette phrase, répétition de « \1 » (à gauche). <<- __also__ -1>> _ # Dans cette phrase, répétition de « \1 » (à droite). TEST: __redon2__ Quelle {{imposture}}, c’est d’un ennui, c’est une {{imposture}}. TEST: __redon2__ ils sont là côte à côte. TEST: __redon2__ Tu avances petit à petit, et tu réussis. TEST: __redon2__ De loin en loin, elle passe. TEST: __redon2__ Les mêmes causes produisent/produisant les mêmes effets. (répétition) !! !! !!!! Groupe nominal (1) !! !! #### 1 mot ## Usage impropre __[s](au_le_nom)__ ([aA]u le) ({w_2}) @@0,6 <<- morph(\2, ":[NAQ]", False) -1>> au # Usage impropre. Après “au”, l’article “le” est inapproprié. (Ex : Je vais à la gare, je vais au stade.) |
︙ | ︙ | |||
5454 5455 5456 5457 5458 5459 5460 | (trouv\w+) +(ça|ce(?:ci|la)) +({w_2}) @@0,w,$ <<- morph(\1, ">trouver ", False) and morphex(\3, ":A.*:(?:f|m:p)", ":(?:G|3[sp]|M[12P])") -3>> =suggMasSing(@) # Trouver \2 + [adjectif] : l’adjectif s’accorde avec “\2” (au masculin singulier). TEST: ils trouvent ça de plus en plus {{idiots}} ->> idiot | | > > > > > | 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 | (trouv\w+) +(ça|ce(?:ci|la)) +({w_2}) @@0,w,$ <<- morph(\1, ">trouver ", False) and morphex(\3, ":A.*:(?:f|m:p)", ":(?:G|3[sp]|M[12P])") -3>> =suggMasSing(@) # Trouver \2 + [adjectif] : l’adjectif s’accorde avec “\2” (au masculin singulier). TEST: ils trouvent ça de plus en plus {{idiots}} ->> idiot !! !! !!!! Groupe nominal (2) !! !! ## Sans article __[i]/gn(gn_2m_accord)__ ^ *({w_2}) +({w_2}) @@*,$ <<- ((morph(\1, ":[NAQ].*:m") and morph(\2, ":[NAQ].*:f")) or (morph(\1, ":[NAQ].*:f") and morph(\2, ":[NAQ].*:m"))) and not apposition(\1, \2) -2>> =switchGender(@) # Accord de genre erroné avec « \1 ». |
︙ | ︙ | |||
5841 5842 5843 5844 5845 5846 5847 | TEST: Des règles pas du tout {{claire}}. ->> claires TEST: Des peines à peine {{croyable}}. ->> croyables TEST: Des {{chambres}} plus ou moins fortement {{éclairé}}. TEST: Les couleurs rouge, jaune et verte ne doivent pas être utilisées TEST: des passeports américain, canadien, néerlandais, allemand et britannique. | | > > > > > | 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 | TEST: Des règles pas du tout {{claire}}. ->> claires TEST: Des peines à peine {{croyable}}. ->> croyables TEST: Des {{chambres}} plus ou moins fortement {{éclairé}}. TEST: Les couleurs rouge, jaune et verte ne doivent pas être utilisées TEST: des passeports américain, canadien, néerlandais, allemand et britannique. !! !! !!!! Groupe nominal (3) !! !! ## nombre __[i]/gn(gn_3m)__ ^ *({w_2}) +({w_2}) +({w_3}) @@*,w,$ <<- (morph(\1, ":[NAQ].*:p") and morph(\2, ":[NAQ].*:[pi]") and morph(\3, ":[NAQ].*:s")) or (morph(\1, ":[NAQ].*:s") and morph(\2, ":[NAQ].*:[si]") and morph(\3, ":[NAQ].*:p")) |
︙ | ︙ | |||
5881 5882 5883 5884 5885 5886 5887 | and not before(r"(?i)\bune? de ") -4>> =suggPlur(@) # Accord de nombre erroné avec « \1 \2 \3 » : « \4 » devrait être au pluriel. TEST: ces petites sottes {{déjantée}} | > > | > > | 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 | and not before(r"(?i)\bune? de ") -4>> =suggPlur(@) # Accord de nombre erroné avec « \1 \2 \3 » : « \4 » devrait être au pluriel. TEST: ces petites sottes {{déjantée}} !! !! !!!! Groupe nominal: Accords avec de / des / du !! !! __[i]/gn(gn_devinette1)__ (?:[lmts]a|une|cette) +{w_2} +d(?:e (?:[lmts]a|cette)|’une) +(?!des )({w_2}) +({w_2}) @@w,$ <<- morphex(\2, ":[NAQ].*:(?:m|f:p)", ":(?:G|P|[fe]:[is]|V0|3[sp])") and not apposition(\1, \2) -2>> =suggFemSing(@, True) # Accord erroné : « \2 » devrait être au féminin singulier. __[i]/gn(gn_devinette2)__ |
︙ | ︙ | |||
5938 5939 5940 5941 5942 5943 5944 | de tel(?:s? sorte(?:s|nt|)|les sorte(?:s|nt|)|le sorte(?:s|nt)) <<- ->> de telle sorte # Accord erroné. TEST: {{de telles sorte}} | < > > > > > | 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 | de tel(?:s? sorte(?:s|nt|)|les sorte(?:s|nt|)|le sorte(?:s|nt)) <<- ->> de telle sorte # Accord erroné. TEST: {{de telles sorte}} !! !! !!!! Singuliers & Pluriels !! !! #### Prépositions # Similaires à prépositions : http://www.synapse-fr.com/manuels/PP_ATTENDU.htm # attendu, compris, non-compris, y compris, entendu, excepté, ôté, ouï, passé, supposé, vu # ! problème avec l’ouïe, ouï retiré de la liste __<i]/sgpl(sgpl_prep_compris_det)__ |
︙ | ︙ | |||
6312 6313 6314 6315 6316 6317 6318 | TEST: c’est son point de {{vu}} qui prime. TEST: Son point de {{vus}} prévaudra toujours, faites-vous à cette idée ou dégagez. TEST: de mon point de {{vues}} | < > > > > > | 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 | TEST: c’est son point de {{vu}} qui prime. TEST: Son point de {{vus}} prévaudra toujours, faites-vous à cette idée ou dégagez. TEST: de mon point de {{vues}} !! !! !!!! Confusions !! !! # abuser / abusé / abusif __[i]/conf(conf_abusif)__ c’est +(abus(?:é|er)) @@$ <<- isEnd() -1>> abusif # Confusion. Concernant les actes, on parle de pratiques abusives. On abuse des choses ou des personnes. TEST: C’est {{abusé}} ! |
︙ | ︙ | |||
6742 6743 6744 6745 6746 6747 6748 | -1>> =\1.replace("escell", "écel").replace("essell", "écel") # Confusion probable si ce mot se rapporte à « \2 ». Desceller signifie briser un sceau, un cachet… Desseller signifie ôter une selle.|http://fr.wiktionary.org/wiki/déceler TEST: il y a une erreur qu’on peut {{desceller}} dans ses analyses. TEST: elle a {{dessellé}} une forte hostilité dans ses propos. | < > > > > > > > > > > > > > > > > | 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 | -1>> =\1.replace("escell", "écel").replace("essell", "écel") # Confusion probable si ce mot se rapporte à « \2 ». Desceller signifie briser un sceau, un cachet… Desseller signifie ôter une selle.|http://fr.wiktionary.org/wiki/déceler TEST: il y a une erreur qu’on peut {{desceller}} dans ses analyses. TEST: elle a {{dessellé}} une forte hostilité dans ses propos. # en train / entrain __[i]/conf(conf_en_train)__ entrain <<- morph(word(-1), ":V0e", False, False) ->> en train # Confusion. L’entrain est une fougue, une ardeur à accomplir quelque chose.|https://fr.wiktionary.org/wiki/entrain TEST: Vous êtes {{entrain}} de vaincre. # envi / envie __[i]/conf(conf_à_l_envi)__ à l’(envie) @@4 <<- not morph(word(-1), ">(?:abandonner|céder|résister) ", False) and not after("^ d(?:e |’)") -1>> envi # Locution adverbiale « à l’envi », signifiant « autant que possible ». TEST: Ils s’amusèrent à l’{{envie}} et oublièrent tous leurs soucis. TEST: Je résiste à l’envie de manger du chocolat. TEST: On ne s’intéresse pas à l’école ni à l’âge, mais aux compétences et à l’envie de partager. # et / est __[i]/conf(conf_est)__ (et) +({w_4}) *$ @@0,$ <<- before_chk1(r"(?i)^ *(?:l[ea]|ce(?:tte|t|)|mon|[nv]otre) +(\w[\w-]+\w) +$", ":[NA].*:[is]", ":G") -1>> est # Confusion probable : “et” est une conjonction de coordination. Pour le verbe être à la 3ᵉ personne du singulier, écrivez : <<- before_chk1(r"(?i)^ *(?:ton) +(\w[\w-]+\w) +$", ":N.*:[is]", ":[GA]") -1>> est # Confusion probable : “et” est une conjonction de coordination. Pour le verbe être à la 3ᵉ personne du singulier, écrivez : <<- before_chk1(r"^ *([A-ZÉÈ][\w-]+\w) +$", ":M", ":G") -1>> est # Confusion probable : “et” est une conjonction de coordination. Pour le verbe être à la 3ᵉ personne du singulier, écrivez : TEST: ce chien {{et}} malade. TEST: ton chat {{et}} cinglé. TEST: Pauline {{et}} fatiguée. TEST: ton implacable et amère ! TEST: son cristallin et aigu # faite / faîte / fait __[i]/conf(conf_faites)__ vous +(?:ne |leur |lui |nous |vous |)(faîtes?) @@$ <<- -1>> faites # Confusion. Le faîte (≠ faire) est le point culminant de quelque chose. __[i]/conf(conf_faites_vous)__ (faîtes?)[- ]vous @@0 <<- not morph(word(-1), ":D.*:[me]:[sp]", False) -1>> faites # Confusion. Le faîte (≠ faire) est le point culminant de quelque chose. __[i]/conf(conf_avoir_être_faite)__ |
︙ | ︙ | |||
7600 7601 7602 7603 7604 7605 7606 | # nouveau / nouvel # TODO | | | > > > > > | 7678 7679 7680 7681 7682 7683 7684 7685 7686 7687 7688 7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 | # nouveau / nouvel # TODO !!!! Mots composés __[i]/mc(mc_mot_composé)__ ({w2})-({w2}) @@0,$ <<- not \1.isdigit() and not \2.isdigit() and not morph(\0, ":", False) and not morph(\2, ":G", False) and spell(\1+\2) ->> \1\2 # Vous pouvez ôter le trait d’union. <<- \2 != "là" and not re.search("(?i)^(?:ex|mi|quasi|semi|non|demi|pro|anti|multi|pseudo|proto|extra)$", \1) and not \1.isdigit() and not \2.isdigit() and not morph(\2, ":G", False) and not morph(\0, ":", False) and not spell(\1+\2) ->> _ # Mot inconnu du dictionnaire.|http://www.dicollecte.org/dictionary.php?prj=fr&unknownword=on TEST: __mc__ des {{portes-avions}}. !! !! !!!! Casse: majuscules et minuscules !! !! # Les jours __[s]/maj(maj_jours_semaine)__ (?:Lundi|Mardi|Mercredi|Jeudi|Vendredi|Samedi|Dimanche) <<- before(r"[\w,] +$") ->> =\0.lower() # Pas de majuscule sur les jours de la semaine.|http://www.academie-francaise.fr/la-langue-francaise/questions-de-langue#42_strong-em-jours-de-la-semaine-pluriel-et-majuscules-em-strong |
︙ | ︙ | |||
7771 7772 7773 7774 7775 7776 7777 | TEST: J’en veux 3 {{Mètres}}. TEST: Elle en prendra vingt {{Grammes}}. | > > > > > > > > > > > > > > > > > > > > > | > > > > > < | 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 7877 7878 7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 | TEST: J’en veux 3 {{Mètres}}. TEST: Elle en prendra vingt {{Grammes}}. !! !! !! !! !! !! !! !! !! !! !!! Conjugaisons !! !! !! !! !! !! !! !! !! !! !! !! !!!! Infinitif !! !! __[i]/infi(infi_à_en)__ à en ({w_2}) @@5 <<- morphex(\1, ":V", ":Y") -1>> =suggVerbInfi(@) # Le verbe devrait être à l’infinitif. TEST: à en {{parlé}} sans cesse |
︙ | ︙ | |||
7883 7884 7885 7886 7887 7888 7889 | ((?:cess|dé[cf]|sugg[éè]r|command|essa|tent|chois|perm[eiî]t|interd)\w*) +(?:pas |plus |point |guère |jamais |peu |rien |) *(?:de +|d’)({w_2}(?:ée?s?|ez)) @@0,$ <<- morph(\1, ">(?:cesser|décider|défendre|suggérer|commander|essayer|tenter|choisir|permettre|interdire) ", False) and analysex(\2, ":(?:Q|2p)", ":M") -2>> =suggVerbInfi(@) # Le verbe devrait être à l’infinitif. TEST: cessez d’{{anesthésié}} ces gens ! | < | 7991 7992 7993 7994 7995 7996 7997 7998 7999 8000 8001 8002 8003 8004 | ((?:cess|dé[cf]|sugg[éè]r|command|essa|tent|chois|perm[eiî]t|interd)\w*) +(?:pas |plus |point |guère |jamais |peu |rien |) *(?:de +|d’)({w_2}(?:ée?s?|ez)) @@0,$ <<- morph(\1, ">(?:cesser|décider|défendre|suggérer|commander|essayer|tenter|choisir|permettre|interdire) ", False) and analysex(\2, ":(?:Q|2p)", ":M") -2>> =suggVerbInfi(@) # Le verbe devrait être à l’infinitif. TEST: cessez d’{{anesthésié}} ces gens ! ## INFINITIFS ERRONÉS __[i]/infi(infi_adjectifs_masculins_singuliers)__ ^ *(?:le|un|cet?|[mts]on|quel) (?!verbe)({w_2}) +({w_2}er) @@w,$ <<- morphex(\1, ":N.*:m:[si]", ":G") and morphex(\2, ":Y", ">aller |:(?:M|N.*:m:s)") and isNextVerb() -2>> =suggVerbPpas(\2, ":m:s") # Confusion probable : “\2” est à verbe à l’infinitif. Pour l’adjectif, écrivez : |
︙ | ︙ | |||
7917 7918 7919 7920 7921 7922 7923 | -2>> =suggVerbPpas(\2, ":p") # Confusion probable : “\2” est à verbe à l’infinitif. Pour l’adjectif, écrivez : TEST: les documents {{scanner}} ne sont pas lisibles. TEST: tes doutes {{remâcher}} deviennent difficiles à vivre. | | < < < > > > > > | 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 | -2>> =suggVerbPpas(\2, ":p") # Confusion probable : “\2” est à verbe à l’infinitif. Pour l’adjectif, écrivez : TEST: les documents {{scanner}} ne sont pas lisibles. TEST: tes doutes {{remâcher}} deviennent difficiles à vivre. !!!! Particpes présents __[i]/conj(conj_participe_présent)__ (?:ne|lui|me|te|se|nous|vous) ({w_2}ants) @@$ <<- morph(\1, ":A", False) -1>> =\1[:-1] # Un participe présent est invariable.|http://fr.wiktionary.org/wiki/participe_pr%C3%A9sent TEST: nous {{épuisants}} à la tâche pour des clopinettes, nous défaillîmes. !!! !!! !!! Processeur: simplification des substantifs !!! !!! ### @ : we remove @ we introduced after le/la/les in some cases __<s>(p_arobase)__ @ <<- ~>> * ### Avant les verbes (ôter seulement les COI!) __[i](p_ne_leur_lui)__ ne (leur|lui)(?! en) @@3 <<- ~1>> * |
︙ | ︙ | |||
8050 8051 8052 8053 8054 8055 8056 | TEST: tandis que d’autres perçoivent le bon goût de la soupe. TEST: Je me doute bien que vous avez trouvé la réponse. TEST: Nous nous doutons bien qu’il y a une entourloupe derrière cette affaire. | < < < < < | | 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 | TEST: tandis que d’autres perçoivent le bon goût de la soupe. TEST: Je me doute bien que vous avez trouvé la réponse. TEST: Nous nous doutons bien qu’il y a une entourloupe derrière cette affaire. !!!! OCR # Participes passés __[i]/ocr(ocr_être_participes_passés)__ ({etre}) +({w_2}es?) @@0,$ <<- morph(\1, ":V0e", False) >>> <<- \2.endswith("e") and morphex(\2, ":V1.*:Ip.*:[13]s", ":(?:[GM]|A)") and not before(r"(?i)\belle +(?:ne +|n’|)$") -2>> =suggVerbPpas(\2, ":m:s") # Erreur de numérisation ? |
︙ | ︙ | |||
8092 8093 8094 8095 8096 8097 8098 | TEST: __ocr__ il était sublime. TEST: __ocr__ elle avait envie de s’en sortir enfin. TEST: __ocr__ la longueur de la circonférence étant égale à… # TEST: __ocr__ vous êtes {{presses}} de monter à bord de ce train-ci. # Fonctionne avec nous serons, mais pas nous sommes (bug de JavaScript?) | | > | 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 | TEST: __ocr__ il était sublime. TEST: __ocr__ elle avait envie de s’en sortir enfin. TEST: __ocr__ la longueur de la circonférence étant égale à… # TEST: __ocr__ vous êtes {{presses}} de monter à bord de ce train-ci. # Fonctionne avec nous serons, mais pas nous sommes (bug de JavaScript?) !!!! Confusions ## guerre / guère __[i]/conf(conf_ne_pronom_pronom_verbe_guère)__ ne (?:[mts]e|la|les?|[nv]ous|lui|leur) (?:la |les? |lui |leur |l’|)\w{w_2} (?:plus |)(guerre) @@$ <<- -1>> guère # Confusion. La guerre est conflit. Pour l’adverbe signifiant “peu”, écrivez : TEST: tout ceci ne me rapporte {{guerre}} |
︙ | ︙ | |||
8152 8153 8154 8155 8156 8157 8158 | __[i]/conf(conf_aller_de_soi)__ ({aller}) +de (soi[tes]) @@0,$ <<- morph(\1, ">aller", False) and not after(" soit ") -2>> soi # Confusion.|https://fr.wiktionary.org/wiki/aller_de_soi TEST: cela ne va pas de {{soit}}. | | > > > > > > | > > | 8257 8258 8259 8260 8261 8262 8263 8264 8265 8266 8267 8268 8269 8270 8271 8272 8273 8274 8275 8276 8277 8278 8279 8280 8281 8282 8283 8284 8285 8286 8287 8288 8289 8290 8291 8292 8293 8294 8295 8296 8297 8298 8299 8300 8301 8302 8303 8304 8305 8306 8307 8308 | __[i]/conf(conf_aller_de_soi)__ ({aller}) +de (soi[tes]) @@0,$ <<- morph(\1, ">aller", False) and not after(" soit ") -2>> soi # Confusion.|https://fr.wiktionary.org/wiki/aller_de_soi TEST: cela ne va pas de {{soit}}. !!!! Adverbes après verbe # fort __[i]/sgpl(sgpl_verbe_fort)__ ({w_2}) +(forts) @@0,$ <<- morphex(\1, ":V", ":[AN].*:[me]:[pi]|>(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre|appara[îi]tre) .*:(?:[123]p|P|Q)|>(?:affirmer|trouver|croire|désirer|estime|préférer|penser|imaginer|voir|vouloir|aimer|adorer|souhaiter) ") and not morph(word(1), ":A.*:[me]:[pi]", False) -2>> fort # Confusion probable. S’il s’agit ici de l’adverbe “fort” (équivalent de “fortement”), écrivez-le au singulier. TEST: ces emmerdeurs crient bien trop {{forts}} TEST: ces animaux paraissent forts, mais ils sont faibles. TEST: ils sont forts, ces gars-là. TEST: ils se croient forts. TEST: je les imagine forts et intelligents. TEST: elles les veulent forts et astucieux. TEST: les écarts ont été plus forts en une génération TEST: Avec le même nombre de bulletins, les xénophobes apparaîtront plus forts. # bien __[i]/sgpl(sgpl_bien)__ biens <<- morphex(word(-1), ":V", ":D.*:p|:A.*:p", False) ->> bien # Confusion probable. Ici, “bien” est un adverbe, donc invariable. TEST: Ils vont {{biens}}. TEST: Elles travaillaient vraiment {{biens}}. TEST: Il ne comprenait vraiment pas très {{biens}} ces principes de base. TEST: Il a de grands biens. TEST: Ce sont des biens de peu de valeur. !! !! !!!! Infinitif !! !! __[i]/infi(infi_d_en_y)__ d’(?:en|y) +({w_2}(?:ée?s?|ai[st]?|ez)) @@$ <<- morph(\1, ":V", False) -1>> =suggVerbInfi(@) # Le verbe devrait être à l’infinitif. TEST: arrête d’y {{consacré}} autant de temps. |
︙ | ︙ | |||
8269 8270 8271 8272 8273 8274 8275 | __[i]/infi(infi_lui)__ lui ({w_2}ée?s?) @@$ <<- morph(\1, ":Q", False) -1>> =suggVerbInfi(@) # Le verbe ne devrait pas être un participe passé. TEST: lui {{mangée}} beaucoup. | | < > > > > | 8382 8383 8384 8385 8386 8387 8388 8389 8390 8391 8392 8393 8394 8395 8396 8397 8398 8399 8400 | __[i]/infi(infi_lui)__ lui ({w_2}ée?s?) @@$ <<- morph(\1, ":Q", False) -1>> =suggVerbInfi(@) # Le verbe ne devrait pas être un participe passé. TEST: lui {{mangée}} beaucoup. !! !! !!!! Participes passés: se +être +verbe !! !! __[i]/ppas(ppas_je_me_être_verbe)__ je +(?:ne +|)m(?:e +|’(?:y +|))(?:s[uo]i[st]|étai[st]|fu(?:sses?|s|t)|serai[st]?) +({w_3}) @@$ <<- morphex(\1, ":Q.*:p", ":(?:G|Q.*:[si])") and isRealEnd() and not before(r"\b[qQ]ue? +$") -1>> suggVerbPpas(\1, ":m:s") # Si ce participe passé se rapporte bien à “je”, il devrait être au singulier. TEST: je ne me suis jamais {{perdus}} |
︙ | ︙ | |||
8355 8356 8357 8358 8359 8360 8361 | TEST: ce qui s’est {{passe}}. TEST: s’y était {{consacrer}} avec enthousiasme. TEST: On s’est rencontrées lorsqu’on travaillait là-bas. TEST: des soins que je m’étais donnés. TEST: Si t’es pas contente, t’achètes pas. | | > > > > > | 8471 8472 8473 8474 8475 8476 8477 8478 8479 8480 8481 8482 8483 8484 8485 8486 8487 8488 8489 8490 | TEST: ce qui s’est {{passe}}. TEST: s’y était {{consacrer}} avec enthousiasme. TEST: On s’est rencontrées lorsqu’on travaillait là-bas. TEST: des soins que je m’étais donnés. TEST: Si t’es pas contente, t’achètes pas. !! !! !!!! Participes passés: se +laisser +adjectif !! !! __[i]/ppas(ppas_me_te_laisser_adj)__ ([mt]e|l[ae]) +(laiss\w*) +({w_3}) @@0,w,$ <<- morph(\2, ">laisser ", False) and morphex(\3, ":[AQ].*:p", ":(?:[YG]|[AQ].*:[is])") -3>> =suggSing(@) # Accord avec « \1 » : « \3 » devrait être au singulier. TEST: Elle te laisse {{épuisés}} par la tâche. |
︙ | ︙ | |||
8383 8384 8385 8386 8387 8388 8389 | TEST: elle nous laissera {{perdu}} dans nos délires. TEST: je les laisse indifférents. TEST: tu nous laisses indifférentes. TEST: ils nous laisseront étourdis. TEST: nous laisserons étourdi cet homme. | | < > > > > | 8504 8505 8506 8507 8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 8518 8519 8520 8521 8522 | TEST: elle nous laissera {{perdu}} dans nos délires. TEST: je les laisse indifférents. TEST: tu nous laisses indifférentes. TEST: ils nous laisseront étourdis. TEST: nous laisserons étourdi cet homme. !! !! !!!! Participes passés: être, avoir été, sembler (+être via pp), devenir, rester, (re)devenir, paraître + participe passé / adj !! !! __[i]/ppas(ppas_je_verbe)__ j(?:e +|’(?:y +|en +|))(?:ne +|n’|)((?:s[oue]|étai|fus|dev|re(?:dev|st)|par)\w*|a(?:ie?|vais|urais?) +été|eus(?:se|) +été) +({w_2}) @@w,$ <<- (morph(\1, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre) ", False) or \1.endswith(" été")) and morphex(\2, ":[NAQ].*:p", ":[GWYsi]") -2>> =suggSing(@) # Accord avec le sujet « je » : « \2 » devrait être au singulier. TEST: j’étais {{perdus}} ->> perdu |
︙ | ︙ | |||
8544 8545 8546 8547 8548 8549 8550 | TEST: J’{{ai été}} camper dans les Alpes. TEST: Tu {{as été}} prendre du bois. TEST: J’{{ai été}} {{chercher}} du pain. TEST: Ç’eût été prendre des vessies pour des lanternes. TEST: C’eût été foncer tête baissée dans la gueule du loup. | > > | > > | 8668 8669 8670 8671 8672 8673 8674 8675 8676 8677 8678 8679 8680 8681 8682 8683 8684 8685 8686 | TEST: J’{{ai été}} camper dans les Alpes. TEST: Tu {{as été}} prendre du bois. TEST: J’{{ai été}} {{chercher}} du pain. TEST: Ç’eût été prendre des vessies pour des lanternes. TEST: C’eût été foncer tête baissée dans la gueule du loup. !! !! !!!! Participes passés: pouvoir/sembler/paraître/vouloir/devoir/croire/déclarer/penser/dire/affirmer + être/avoir été !! !! __[i](p_risque_d_être)__ risqu\w+ +(d’)être @@* <<- ~1>> * __[i]/ppas(ppas_je_verbe_être)__ j(?:e|’(?:y|en)) +(?:ne +|n’|)((?:p[aeouûr]|s(?:embl|ouhait)|cr[ouû]|d[eouûéiî]|estim|imagin|v[eo]u|a(?:ffirm|im|dor)|risqu)\w+) +(?:être|avoir été) +({w_2}) @@w,$ <<- morph(\1, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer) ", False) |
︙ | ︙ | |||
8652 8653 8654 8655 8656 8657 8658 | TEST: elles doivent être {{fâché}} TEST: elles doivent avoir été {{attaqué}} TEST: elles peuvent avoir été {{trompé}} TEST: elles souhaitent être plus {{considérée}} | > > | > < | 8780 8781 8782 8783 8784 8785 8786 8787 8788 8789 8790 8791 8792 8793 8794 8795 8796 8797 8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 | TEST: elles doivent être {{fâché}} TEST: elles doivent avoir été {{attaqué}} TEST: elles peuvent avoir été {{trompé}} TEST: elles souhaitent être plus {{considérée}} !!!! Participes passés: accord en nombre avec la conjugaison de « être » ## Contrôle de l’ __[i]/ppas(ppas_être_accord_singulier)__ ({w_2}) +(?:qui +|)(?:ne +|n’|)(?:est|était|f[uû]t|sera(?:it|)|a(?:vait|ura|urait|it|) +été|e[uû]t +été) +({w_2}) @@0,$ <<- morphex(\2, ":[NAQ].*:p", ":[GMWYsi]") and not morph(\1, ":G", False) -2>> =suggSing(@) # Accord avec « être » : « \2 » devrait être au singulier. __[i]/ppas(ppas_être_accord_pluriel)__ ({w_2}) +(?:qui +|)(?:ne +|n’|)(?:sont|étaient|fu(?:r|ss)ent|ser(?:ont|aient)|soient|ont +été|a(?:vaient|uront|uraient|ient) +été|eu(?:r|ss)ent +été) +({w_2}) @@0,$ <<- not re.search("(?i)^légion$", \2) and morphex(\2, ":[NAQ].*:s", ":[GWYpi]") and not morph(\1, ":G", False) -2>> =suggPlur(@) # Accord avec « être » : « \2 » devrait être au pluriel. !!!! Participes passés: accord en genre avec le substantif précédent __[i]/ppas(ppas_sujet_être_accord_genre)__ (?<![dD]’)(une? |les? |la |l’|ce(?:s|t|tte|) |[mts](?:on|a|es) |[nv]os |leurs? ) *({w_2}) +(?:qui +|)(?:ne +|n’|)(?:est|étai(?:en|)t|f[uû]t|sera(?:i(?:en|)t|)|soi(?:en|)t|s(?:er|)ont|fu(?:r|ss)ent) +({w_2}) @@0,w,$ <<- not re.search("(?i)^légion$", \3) and ((morphex(\3, ":[AQ].*:f", ":[GWme]") and morphex(\2, ":m", ":[Gfe]")) or (morphex(\3, ":[AQ].*:m", ":[GWfe]") and morphex(\2, ":f", ":[Gme]"))) and not ( morph(\3, ":p", False) and morph(\2, ":s", False) ) and not morph(word(-1), ":(?:R|P|Q|Y|[123][sp])", False, False) and not before(r"\b(?:et|ou|de) +$") -3>> =switchGender(@) # Accord erroné : « \2 » et « \3 » ne sont pas accordés en genre. |
︙ | ︙ | |||
8703 8704 8705 8706 8707 8708 8709 | TEST: Éric n’est pas très {{fatiguée}}. TEST: Martine est {{marié}}. TEST: Martine n’est pas {{marié}}. TEST: Martine est très {{intelligent}}. TEST: Martine n’est pas très {{intelligent}}. | > | | 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 8845 8846 8847 8848 | TEST: Éric n’est pas très {{fatiguée}}. TEST: Martine est {{marié}}. TEST: Martine n’est pas {{marié}}. TEST: Martine est très {{intelligent}}. TEST: Martine n’est pas très {{intelligent}}. !!!! Accords avec l’adjectif précédant le pronom __[i]/ppas(ppas_adj_accord_je_tu)__ ^ *({w_2}s),? (je?|tu) @@*,$ <<- morphex(\1, ":A.*:p", ":(?:G|E|M1|W|s|i)") -1>> =suggSing(@) # Si cet adjectif se réfère au pronom « \2 », l’adjectif devrait être au singulier (et accordé en genre). TEST: {{Découragés}}, je suis parti. |
︙ | ︙ | |||
8760 8761 8762 8763 8764 8765 8766 | <<- morph(\1, "V0e", False) and \3 != "rendu" -3>> rendu # Accord erroné : dans l’expression « se rendre compte », « rendu » est invariable. <<- ~2>> _ TEST: Elles se sont {{rendues}} compte TEST: La puissance publique s’en est-elle rendu compte ? | > > > | > > | 8891 8892 8893 8894 8895 8896 8897 8898 8899 8900 8901 8902 8903 8904 8905 8906 8907 8908 8909 8910 | <<- morph(\1, "V0e", False) and \3 != "rendu" -3>> rendu # Accord erroné : dans l’expression « se rendre compte », « rendu » est invariable. <<- ~2>> _ TEST: Elles se sont {{rendues}} compte TEST: La puissance publique s’en est-elle rendu compte ? !! !! !!!! Inversion verbe/sujet !! !! __[i]/ppas(ppas_inversion_être_je)__ (?:s[ou]is|étais|fus(?:sé|)|serais?)-je +({w_2}) @@$ <<- morphex(\1, ":(?:[123][sp]|Y|[NAQ].*:p)", ":[GWsi]") -1>> =suggSing(@) # Accord avec le sujet « je » : « \1 » devrait être au singulier. __[i]/ppas(ppas_inversion_être_tu)__ (?:es|étais|fus(?:ses|)|serai?s)-tu +({w_2}) @@$ <<- morphex(\1, ":(?:[123][sp]|Y|[NAQ].*:p)", ":[GWsi]") |
︙ | ︙ | |||
8813 8814 8815 8816 8817 8818 8819 | TEST: Sont-ils vraiment {{aveugle}} TEST: Ne sommes-nous pas {{aveugle}} TEST: Est-il question de ceci ou de cela ? TEST: Est-ce former de futurs travailleurs ou bien des citoyens | < < | > > > > > | 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 8965 8966 8967 8968 8969 8970 8971 8972 8973 8974 8975 8976 8977 8978 8979 | TEST: Sont-ils vraiment {{aveugle}} TEST: Ne sommes-nous pas {{aveugle}} TEST: Est-il question de ceci ou de cela ? TEST: Est-ce former de futurs travailleurs ou bien des citoyens ## Accord et incohérences __[i]/ppas(ppas_sont)__ sont ({w_2}) @@5 <<- morphex(\1, ":[NAQ]", ":[QWGBMpi]") and not re.search("(?i)^(?:légion|nombre|cause)$", \1) and not before(r"(?i)\bce que?\b") -1>> =suggPlur(@) # Incohérence : « \1 » est au singulier. Ou vous confondez « sont » et « son », ou l’accord en nombre est incorrect. <<- __else__ and morphex(\1, ":V", ":(?:N|A|Q|W|G|3p)") and not before(r"(?i)\bce que?\b") -1>> =suggVerbPpas(\1, ":m:p") # Incohérence : « \1 » n’est pas un participe passé. TEST: après avoir mis à jour sont {{profile}}. !! !! !!!! Se croire/considérer/montrer/penser/révéler/savoir/sentir/voir/vouloir + participe passé/adj !! !! __[i]/ppas(ppas_je_me_verbe)__ je +(?:ne +|)me +((?:s[eauû]|montr|pens|rév|v[oiîe])\w+) +({w_2}) @@w,$ <<- morph(\1, ">(?:montrer|penser|révéler|savoir|sentir|voir|vouloir) ", False) and morphex(\2, ":[NAQ].*:p", ":[GWYsi]") -2>> =suggSing(@) # Accord avec le sujet « je » : « \2 » devrait être au singulier. TEST: je me savais {{implacables}} avec eux |
︙ | ︙ | |||
8957 8958 8959 8960 8961 8962 8963 | TEST: un peu de maquillage et la voilà {{jolis}} comme un cœur. TEST: les voilà pauvrement {{équipé}} pour un tel périple. TEST: une chance pour elle alors qu’il n’a pas choisi TEST: elle se révèle d’ailleurs être une alliée de taille | < > > > > > | 9096 9097 9098 9099 9100 9101 9102 9103 9104 9105 9106 9107 9108 9109 9110 9111 9112 9113 9114 | TEST: un peu de maquillage et la voilà {{jolis}} comme un cœur. TEST: les voilà pauvrement {{équipé}} pour un tel périple. TEST: une chance pour elle alors qu’il n’a pas choisi TEST: elle se révèle d’ailleurs être une alliée de taille !! !! !!!! Avoir + participes passés !! !! #__[i]/conj__ fait(s|e|es) ({w1}) <<- morph(\2, ":V") and not morph(\2, ":Y") # ->> fait \1 # Le participe passé de faire reste au masculin singulier s’il est suivi par un verbe à l’infinitif. __[i](p_les_avoir_fait_vinfi)__ les ({avoir}) +(fait) +(?:[mts](?:e +|’)|)({infi}) @@w,w,$ <<- morph(\1, ">avoir ", False) and morph(\3, ":Y", False) ~2>> _ |
︙ | ︙ | |||
9088 9089 9090 9091 9092 9093 9094 | TEST: m’avoir {{terminer}}. TEST: il m’a {{souffler}} la bonne réponse. TEST: elle t’en a {{parle}}. TEST: c’est vous qui m’avez {{convertit}}. TEST: parce que t’as envie que je le fasse | | > > > > > | 9231 9232 9233 9234 9235 9236 9237 9238 9239 9240 9241 9242 9243 9244 9245 9246 9247 9248 9249 9250 | TEST: m’avoir {{terminer}}. TEST: il m’a {{souffler}} la bonne réponse. TEST: elle t’en a {{parle}}. TEST: c’est vous qui m’avez {{convertit}}. TEST: parce que t’as envie que je le fasse !! !! !!!! COD précédent que !! !! __[i]/ppas(ppas_det_plur_COD_que_avoir)__ ([ldmtsc]es) +({w_2}) +que? +(?:j’|tu |ils? |[nv]ous |elles? |on ) *(?:ne +|n’|)({avoir}) +({w_2}[éiust]e?)(?! [mts]’) @@0,w,w,$ <<- morph(\3, ":V0a", False) and not ((re.search("^(?:décidé|essayé|tenté)$", \4) and after(" +d(?:e |’)")) or (re.search("^réussi$", \4) and after(" +à"))) and morph(\2, ":[NAQ]", False) and morphex(\4, ":V[0-3]..t.*:Q.*:s", ":[GWpi]") and not morph(word(1), ":(?:Y|Oo|D)", False) |
︙ | ︙ | |||
9157 9158 9159 9160 9161 9162 9163 | -2>> =suggVerbPpas(@, ":m:s") # Incohérence avec « \1 » : « \2 » n’est pas un participe passé. <<- __also__ and \1 == "a" and \2.endswith("r") and not before(r"(?i)\b(?:[mtn]’|il +|on +|elle +)$") -1>> à # Confusion probable : “a” est une conjugaison du verbe avoir. Pour la préposition, écrivez : TEST: Avoir {{marcher}} toute la journée m’a épuisée. | > | > | 9305 9306 9307 9308 9309 9310 9311 9312 9313 9314 9315 9316 9317 9318 9319 9320 9321 | -2>> =suggVerbPpas(@, ":m:s") # Incohérence avec « \1 » : « \2 » n’est pas un participe passé. <<- __also__ and \1 == "a" and \2.endswith("r") and not before(r"(?i)\b(?:[mtn]’|il +|on +|elle +)$") -1>> à # Confusion probable : “a” est une conjugaison du verbe avoir. Pour la préposition, écrivez : TEST: Avoir {{marcher}} toute la journée m’a épuisée. !!!! du / dû __[i]/ppas(ppas_avoir_dû_vinfi)__ ({avoir}) +(due?s?) +(?:[mts]’|)({w_2}) @@0,w,$ <<- morph(\1, ":V0a", False) and (morph(\3, ":Y") or re.search("^(?:[mtsn]e|[nv]ous|leur|lui)$", \3)) -2>> dû # Participe passé de devoir : « dû ». __[i]/ppas(ppas_avoir_pronom_du_vinfi)__ ({avoir})-(?:t-|)(?:je|tu|ils?|elles?|nous|vous) +(due?s?) +(?:[mts]’|)({w_2}) @@0,w,$ |
︙ | ︙ | |||
9198 9199 9200 9201 9202 9203 9204 | TEST: Aurait-il {{du}} {{prendre}} son repas plus tôt ? TEST: Avez-vous {{signez}} le contrat ? TEST: Ont-ils {{signer}} le contrat ? TEST: Ai-je déjà {{signez}} le contrat ? TEST: A-t-il déjà {{signer}} le contrat ? | > > | > > > | 9348 9349 9350 9351 9352 9353 9354 9355 9356 9357 9358 9359 9360 9361 9362 9363 9364 9365 9366 9367 | TEST: Aurait-il {{du}} {{prendre}} son repas plus tôt ? TEST: Avez-vous {{signez}} le contrat ? TEST: Ont-ils {{signer}} le contrat ? TEST: Ai-je déjà {{signez}} le contrat ? TEST: A-t-il déjà {{signer}} le contrat ? !! !! !!!! Participes passés avec formes interrogatives !! !! __[i]/ppas(ppas_avoir_pronom1)__ (?<![ltm]’)({avoir})[- ](?:je|tu|ils?|elles?|t-(?:ils?|elles?|on)|on) +({w2}) @@0,$ <<- morph(\1, ":V0a", False) and morphex(\2, ":(?:Y|2p|Q.*:[fp])", ":m:[si]") and \2 != "prise" and not morph(word(-1), ">(?:les|[nv]ous|en)|:[NAQ].*:[fp]", False) and not before(r"(?i)\b(?:quel(?:le|)s?|combien) ") -2>> =suggMasSing(@) # Avec « avoir », il faut un participe passé au masculin singulier. |
︙ | ︙ | |||
9279 9280 9281 9282 9283 9284 9285 9286 | TEST: se {{considérez}} comme un génie… TEST: se {{rencontrerons}} demain grands et petits. TEST: se {{crois}} élu par Dieu… TEST: avec ceux se trouvant sur leur chemin | > > > > > | > | | > > > > > > > | < < | | < | < < < < < | < | < < < | 9434 9435 9436 9437 9438 9439 9440 9441 9442 9443 9444 9445 9446 9447 9448 9449 9450 9451 9452 9453 9454 9455 9456 9457 9458 9459 9460 9461 9462 9463 9464 9465 9466 9467 9468 9469 9470 9471 9472 9473 9474 9475 9476 9477 9478 9479 9480 9481 9482 | TEST: se {{considérez}} comme un génie… TEST: se {{rencontrerons}} demain grands et petits. TEST: se {{crois}} élu par Dieu… TEST: avec ceux se trouvant sur leur chemin !!!! Confusions ou/où __[i]/conf(conf_det_nom_où_pronom)__ ^ *(?:l(?:es? +|a +|’)|[nv]o(?:s|tre) +|ce(?:t|tte|s|) +|[mts](?:es|on|a) +|des +)({w_2}) +(ou) +(?:je|tu|ils?|elles? +> +\w+|[nv]ous +> +\w+) @@w,w <<- morphex(\1, ":[NAQ]", ":G") -2>> où # Confusion probable. Pour évoquer un lieu ou un moment, écrivez :|http://fr.wiktionary.org/wiki/o%C3%B9 TEST: L’hôtel {{ou}} ils sont allés l’été dernier. !!! !!! !!! Processeur avant impératif !!! !!! __<i>(p_n_importe_qui_quoi)__ n(’)importe quo?i @@1 <<- ~1>> ` __<i](p_premier_ne_pro_per_obj1)__ ^ *ne l(?:es?|a) l(?:ui|eur) <<- ~>> > __<i](p_premier_ne_pro_per_obj2)__ ^ *ne (?:[mt]’|l(?:ui|eur) )en <<- ~>> > __<i](p_premier_ne_pro_per_obj3)__ ^ *ne (?:[mt]e|[nv]ous) (?:les?|la|en) <<- ~>> > __<i](p_premier_ne_pro_per_obj4)__ ^ *ne +(?:en|l(?:es?|a|’(?:en|y))|[mt](?:e|’(?:en|y))|[nv]ous) <<- ~>> > __<i>(p_premier_ne_pro_per_obj5)__ ^ *n’(?:en |y |) <<- ~>> > __<i>(p_premier_ne_pro_per_obj6)__ ^ *ne (?:l’|) <<- ~>> > !! !! !!!! Impératif ! !! !! # Confusions __[i]/imp(imp_confusion_2e_pers_pluriel)__ ({w_2}(?:er|ai[st]|ée?s?)) moi @@0 <<- morph(\1, ":V", False) and isStart() ->> =suggVerbTense(\1, ":E", ":2p") + "-moi" # Confusion probable. Pour l’impératif, écrivez : TEST: {{Donner moi}} une chance TEST: je vous en prie, {{prenais moi}} avec vous. |
︙ | ︙ | |||
9447 9448 9449 9450 9451 9452 9453 | TEST: {{Vient}}. TEST: {{Sert}} le plat. TEST: {{Attend}} la correction. TEST: {{Vas}} au diable ! TEST: {{Écartes}} de moi cette coupe. | > > | > > > | 9603 9604 9605 9606 9607 9608 9609 9610 9611 9612 9613 9614 9615 9616 9617 9618 9619 9620 9621 9622 | TEST: {{Vient}}. TEST: {{Sert}} le plat. TEST: {{Attend}} la correction. TEST: {{Vas}} au diable ! TEST: {{Écartes}} de moi cette coupe. !! !! !!!! Impératif: traits d’union manquants !! !! __[i]/imp(imp_union_moi_toi)__ (?<!’)({w_2}) ([mt]oi)(?! même) @@0,$ <<- morphex(\1, ":E", ":[GM]") ->> \1-\2 # S’il s’agit d’un impératif, mettez un trait d’union.|http://66.46.185.79/bdl/gabarit_bdl.asp?id=4206 TEST: {{Apportez moi}} ce dictionnaire |
︙ | ︙ | |||
9551 9552 9553 9554 9555 9556 9557 | TEST: {{allons y}}, ça pue. TEST: {{vas y}}, ce n’est pas dangereux TEST: {{convenez en}}, c’est une belle affaire malgré son prix élevé | < < > > | < > > | 9712 9713 9714 9715 9716 9717 9718 9719 9720 9721 9722 9723 9724 9725 9726 9727 9728 9729 9730 | TEST: {{allons y}}, ça pue. TEST: {{vas y}}, ce n’est pas dangereux TEST: {{convenez en}}, c’est une belle affaire malgré son prix élevé !!! !!! !!! Processeur: destruction des pronoms qui précèdent un verbe et de l’adverbe de négation “ne”. !!! !!! # Brainfuck (ici, prudence !) __[i](p_pro_per_obj01)__ ne +(?:l(?:ui|eur|a|es?)|[mts]e|[nv]ous) +(?:l(?:a|es?|ui|eur)|en|y) <<- ~>> > __[i](p_pro_per_obj02)__ ne +(?:[mts](?:e|’(?:en|y))|[nv]ous|l(?:es?|a|ui|eur|’(?:en|y))) <<- ~>> > __[i](p_pro_per_obj03)__ [mts]e +l(?:a|es?) <<- ~>> > __[i](p_pro_per_obj04)__ [nmsl]’(?:en|y) <<- ~>> > __[i](p_pro_per_obj05)__ l(?:a|es?) +(?:lui|en) <<- ~>> > |
︙ | ︙ | |||
9598 9599 9600 9601 9602 9603 9604 | __[i>(p_pro_per_obj32)__ [mts]e +l’ <<- ~>> > __[i>(p_pro_per_obj33)__ [nm]’ <<- ~>> > __[i](p_pro_per_obj34)__ [nmts]e <<- ~>> > __<s>(p_pro_per_obj35)__ > +> <<- ~>> > # Fin du Brainfuck | | < < > > > > > | 9760 9761 9762 9763 9764 9765 9766 9767 9768 9769 9770 9771 9772 9773 9774 9775 9776 9777 9778 9779 | __[i>(p_pro_per_obj32)__ [mts]e +l’ <<- ~>> > __[i>(p_pro_per_obj33)__ [nm]’ <<- ~>> > __[i](p_pro_per_obj34)__ [nmts]e <<- ~>> > __<s>(p_pro_per_obj35)__ > +> <<- ~>> > # Fin du Brainfuck !! !! !!!! Confusions !! !! #### CONFUSION a / à __[i]/conf(conf_pronom_verbe_à)__ ^ *(?:je|tu|ils?|on|elles?) +>? *({w_2}) +(a) @@w,$ <<- morph(\1, ":V", False) and \2 != "A" -2>> à # Confusion probable : “a” est une conjugaison du verbe “avoir”. Utilisez la préposition : __[i]/conf(conf_j_verbe_à)__ |
︙ | ︙ | |||
9643 9644 9645 9646 9647 9648 9649 | TEST: La révolution est crainte. TEST: Je n’en ai cure. TEST: Notre communauté vous est redevable. TEST: l’humour est affaire de culture | > > | > > | 9808 9809 9810 9811 9812 9813 9814 9815 9816 9817 9818 9819 9820 9821 9822 9823 9824 9825 9826 | TEST: La révolution est crainte. TEST: Je n’en ai cure. TEST: Notre communauté vous est redevable. TEST: l’humour est affaire de culture !! !! !!!! Infinitif !! !! __[i]/infi(infi_comment_où)__ (?:comment|où) +({w_2}(?:ée?s?|ez)) @@$ <<- morphex(\1, ":V", ":M") and not (\1.endswith("ez") and after(" +vous")) -1>> =suggVerbInfi(@) # Le verbe devrait être à l’infinitif. TEST: Comment {{pensé}} à ces choses sans perdre l’esprit. |
︙ | ︙ | |||
9747 9748 9749 9750 9751 9752 9753 | and not morph(word(-1), ":Y|>ce", False, False) and not before("(?i)ce (?:>|qu|que >) $") and not before_chk1(r"({w_2}) +> $", ":Y") and not before_chk1(r"^ *>? *(\w[\w-]+)", ":Y") -2>> =suggVerbPpas(@) # Incohérence. Après « être », le verbe ne doit pas être à l’infinitif. TEST: ils sont {{tromper}} par tous ces hypocrites. | > > | > > | 9916 9917 9918 9919 9920 9921 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 | and not morph(word(-1), ":Y|>ce", False, False) and not before("(?i)ce (?:>|qu|que >) $") and not before_chk1(r"({w_2}) +> $", ":Y") and not before_chk1(r"^ *>? *(\w[\w-]+)", ":Y") -2>> =suggVerbPpas(@) # Incohérence. Après « être », le verbe ne doit pas être à l’infinitif. TEST: ils sont {{tromper}} par tous ces hypocrites. !! !! !!!! Conjugaison !! !! ## 1sg __[i]/conj(conj_j)__ j’({w_1}) @@2 <<- morphex(\1, ":V", ":1s|>(?:en|y)") -1>> =suggVerb(@, ":1s") # Conjugaison erronée. Accord avec « je ». Le verbe devrait être à la 1ʳᵉ personne du singulier. __[i]/conj(conj_je)__ |
︙ | ︙ | |||
10380 10381 10382 10383 10384 10385 10386 | # Conjugaison erronée. Accord avec « \1 et \2 ». Le verbe devrait être à la 3ᵉ personne du pluriel. TEST: Samantha et Eva {{viennes}} demain. TEST: Samantha et Eva leur {{décrive}} une leçon. | < > > > > > | 10553 10554 10555 10556 10557 10558 10559 10560 10561 10562 10563 10564 10565 10566 10567 10568 10569 10570 10571 | # Conjugaison erronée. Accord avec « \1 et \2 ». Le verbe devrait être à la 3ᵉ personne du pluriel. TEST: Samantha et Eva {{viennes}} demain. TEST: Samantha et Eva leur {{décrive}} une leçon. !! !! !!!! Inversion verbe sujet !! !! __[i]/conj(conj_que_où_comment_verbe_sujet_sing)__ (?:que?|où|comment) +({w1}) (l(?:e(?:ur | )|a |’)|[mts](?:on|a) |ce(?:t|tte|) |[nv]otre |du ) *(?!plupart|majorité)({w1}) @@w,w,$ <<- morphex(\1, ":(?:[12]s|3p)", ":(?:3s|G|W|3p!)") and not after("^ +(?:et|ou) (?:l(?:es? |a |’|eurs? )|[mts](?:a|on|es) |ce(?:tte|ts|) |[nv]o(?:s|tre) |d(?:u|es) )") -1>> =suggVerb(@, ":3s") # Conjugaison erronée. Accord avec « \2 \3… ». Le verbe devrait être à la 3ᵉ personne du singulier. TEST: les possibilités qu’{{offrent}} le chien |
︙ | ︙ | |||
10432 10433 10434 10435 10436 10437 10438 | <<- __else__ and \1.endswith("s") and \2 != "tu" and not before(r"(?i)\btu ") -1>> puisse # Conjugaison erronée. Sujet “tu” introuvable. TEST: {{puisse}} les hommes enfin comprendre leurs erreurs. ->> puissent TEST: {{puisses}} notre ennemi trembler de peur devant notre courage. ->> puisse | | > > > > > | 10609 10610 10611 10612 10613 10614 10615 10616 10617 10618 10619 10620 10621 10622 10623 10624 10625 10626 10627 10628 | <<- __else__ and \1.endswith("s") and \2 != "tu" and not before(r"(?i)\btu ") -1>> puisse # Conjugaison erronée. Sujet “tu” introuvable. TEST: {{puisse}} les hommes enfin comprendre leurs erreurs. ->> puissent TEST: {{puisses}} notre ennemi trembler de peur devant notre courage. ->> puisse !! !! !!!! Formes interrogatives ? !! !! __[i]/inte(inte_union_xxxe_je)__ (?<![jJ]’)({w_2}[éèe]) je(?! +[nmts]’) @@0 <<- morphex(\1, ":V.*:1[sŝś]", ":[GNW]") and not before(r"(?i)\bje +>? *$") and not morph(word(1), ":(?:Oo|X|1s)", False, False) ->> =\1[:-1]+"é-je" # Forme interrogative ? Mettez un trait d’union. __[i]/inte(inte_union_xxx_je)__ (?<![jJ]’)({w_2}[is]) je(?! +[nmts]’) @@0 |
︙ | ︙ | |||
10561 10562 10563 10564 10565 10566 10567 | TEST: {{Ait}}-il arrivé à ses fins ? TEST: je n’{{avais}} pas parti avec eux. TEST: Avais-je partie liée avec lui ? TEST: il {{avait}} parti. | | > > > > > | 10743 10744 10745 10746 10747 10748 10749 10750 10751 10752 10753 10754 10755 10756 10757 10758 10759 10760 10761 10762 | TEST: {{Ait}}-il arrivé à ses fins ? TEST: je n’{{avais}} pas parti avec eux. TEST: Avais-je partie liée avec lui ? TEST: il {{avait}} parti. !! !! !!!! Modes verbaux !! !! # conditionnel / futur __[i]/vmode(vmode_j_aimerais_vinfi)__ j(?:e +|’)(aimerai|préf[éè]rerai|apprécierai|voudrai|souhaiterai) +({w_1}) @@w,$ <<- morphex(\2, ":[YX]|>y ", "R") -1>> \1s # Si vous exprimez un souhait, utilisez le conditionnel et non le futur. __[i>/vmode(vmode_j_aimerais_pronom)__ |
︙ | ︙ | |||
10675 10676 10677 10678 10679 10680 10681 | # Après « après que », le verbe s’emploie pas au subjonctif mais à l’indicatif, si l’action s’est déroulée de façon certaine. TEST: Après qu’il {{ait}} allé TEST: Après que Paul {{ait}} mangé son repas. TEST: Après qu’il {{soit}} parti, il plut. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 10862 10863 10864 10865 10866 10867 10868 10869 10870 10871 10872 10873 10874 10875 10876 10877 10878 10879 10880 10881 10882 10883 10884 10885 10886 10887 10888 10889 10890 10891 10892 10893 10894 10895 10896 10897 10898 10899 10900 10901 10902 10903 10904 10905 10906 10907 10908 10909 10910 10911 10912 10913 10914 10915 10916 10917 10918 10919 10920 10921 | # Après « après que », le verbe s’emploie pas au subjonctif mais à l’indicatif, si l’action s’est déroulée de façon certaine. TEST: Après qu’il {{ait}} allé TEST: Après que Paul {{ait}} mangé son repas. TEST: Après qu’il {{soit}} parti, il plut. !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! TESTS: Faux positifs potentiels !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !!! À trier TEST: L’homme sur le bateau de Patrick {{viens}} de temps en temps {{mangé}} chez moi. TEST: Ces marchands {{passe}} leur temps à se quereller. TEST: Ils jugeront en toute impartialité de ce cas {{délirante}}. TEST: Ils sont de manière si étonnante et si admirable {{arrivé}} à ce résultat… TEST: Les tests grand public de Jean-Paul {{montre}} des résultats surprenants. TEST: Ils ont à plusieurs reprises {{perdus}} leur sang-froid. TEST: Ces attaques à main armée {{donne}} la chair de poule. |
︙ | ︙ | |||
10714 10715 10716 10717 10718 10719 10720 | TODO: Des copains plus vieux que moi qui fumaient. TODO: Des copains plus vieux que toi qui fumaient. TODO: André Juin était un sculpteur français. TODO: La bataille de Monte Cassino révèle le génie militaire du général Juin. TODO: Les côtes sont dans leur ensemble extrêmement découpées. | < < < < | | | 10946 10947 10948 10949 10950 10951 10952 10953 10954 10955 10956 10957 10958 10959 10960 10961 10962 10963 10964 | TODO: Des copains plus vieux que moi qui fumaient. TODO: Des copains plus vieux que toi qui fumaient. TODO: André Juin était un sculpteur français. TODO: La bataille de Monte Cassino révèle le génie militaire du général Juin. TODO: Les côtes sont dans leur ensemble extrêmement découpées. !!! Indécidable TEST: Du sable fin grippe les rouages (accord avec ce qui précède). TEST: Du monde noir sortent les envahisseurs (accord avec ce qui suit). !!! Autres tests TEST: Ça a l’air de t’aller. TEST: Et je m’en sors. TEST: C’est à chacun d’entre nous de suivre le modèle d’Amos. TEST: C’est toi qui voulais y aller. TEST: je ne suis qu’une joueuse en robe de soirée. TEST: Tu ne fais qu’aggraver les choses. TEST: Que veut-il ? Vous parler du boulot. |
︙ | ︙ | |||
10783 10784 10785 10786 10787 10788 10789 10790 10791 10792 10793 10794 10795 10796 | TEST: l’herbe que la faux a couchée jaunit vite. TEST: Il a juste besoin de comprendre pourquoi ce garçon en est arrivé là et pourquoi il s’en est pris à lui. TEST: Elle prit une pose lascive. TEST: Cela a trait avec l’histoire complexe d’une nation qui a été prise en étau TEST: Enfin, les thèmes de la nouvelle réforme ont été longuement débattus. TEST: Le moral des ménages au plus haut depuis 2007 ## Version 0.5.14 TEST: par le léger tissu de rayonne qui les protégeait en ce moment. ## Version 0.5.11 TEST: Un moteur à cylindrée fixe | > > | 11011 11012 11013 11014 11015 11016 11017 11018 11019 11020 11021 11022 11023 11024 11025 11026 | TEST: l’herbe que la faux a couchée jaunit vite. TEST: Il a juste besoin de comprendre pourquoi ce garçon en est arrivé là et pourquoi il s’en est pris à lui. TEST: Elle prit une pose lascive. TEST: Cela a trait avec l’histoire complexe d’une nation qui a été prise en étau TEST: Enfin, les thèmes de la nouvelle réforme ont été longuement débattus. TEST: Le moral des ménages au plus haut depuis 2007 !!! Tests historiques ## Version 0.5.14 TEST: par le léger tissu de rayonne qui les protégeait en ce moment. ## Version 0.5.11 TEST: Un moteur à cylindrée fixe |
︙ | ︙ | |||
11557 11558 11559 11560 11561 11562 11563 | TEST: Le patron du numéro deux allemand a démissionné. TEST: Je soussigné Pierre Dupont déclare avoir pris connaissance des conditions de ce contrat. TEST: J’ai mille cent timbres. TEST: À qui mieux mieux, à qui mieux mieux TEST: L’est est loin, la gare de l’est aussi. | | > > | 11787 11788 11789 11790 11791 11792 11793 11794 11795 11796 11797 11798 11799 11800 11801 11802 11803 11804 | TEST: Le patron du numéro deux allemand a démissionné. TEST: Je soussigné Pierre Dupont déclare avoir pris connaissance des conditions de ce contrat. TEST: J’ai mille cent timbres. TEST: À qui mieux mieux, à qui mieux mieux TEST: L’est est loin, la gare de l’est aussi. !!! Tests repris de LanguageTool ## NOTE : ces textes contiennent parfois des erreurs (corrigées quand repérées par le correcteur) TEST: Au voisinage du zéro absolu de température. TEST: La couronne périphérique alterne falaises abruptes et plages. TEST: Henri VIII rencontre François Ier. TEST: à ce jour. TEST: avoir un bel avenir TEST: faire un dessin TEST: par exemple |
︙ | ︙ | |||
13623 13624 13625 13626 13627 13628 13629 | TEST: Le 29 février 2008. TEST: Le 29 février 2012. TEST: Le 29 février 2016. TEST: Le 29 février 2020. TEST: Le 29-février-2004 | < | | 13855 13856 13857 13858 13859 13860 13861 13862 13863 13864 13865 13866 13867 13868 13869 | TEST: Le 29 février 2008. TEST: Le 29 février 2012. TEST: Le 29 février 2016. TEST: Le 29 février 2020. TEST: Le 29-février-2004 !!! Le Horla, de Guy de Maupassant # Nouvelle intégrale (228 lignes) # Certains points diffèrent du texte original tiré de Wikisource : # — les paragraphes sont souvent scindés pour des raisons pratiques. # — les virgules avant les points de suspension ont été supprimées # — moyen âge -> Moyen Âge TEST: Le Horla — Guy de Maupassant TODO: 8 mai. — Quelle journée admirable ! J’ai passé toute la matinée {{étendu}} sur l’herbe, devant ma maison, sous l’énorme platane qui la couvre, l’abrite et l’ombrage tout entière. |
︙ | ︙ | |||
13996 13997 13998 13999 14000 14001 14002 | TEST: Pourquoi ce corps transparent, ce corps inconnaissable, ce corps d’Esprit, s’il devait craindre, lui aussi, les maux, les blessures, les infirmités, la destruction prématurée ? TEST: La destruction prématurée ? toute l’épouvante humaine vient d’elle ! TEST: Après l’homme le Horla. — Après celui qui peut mourir tous les jours, à toutes les heures, à toutes les minutes, par tous les accidents, est venu celui qui ne doit mourir qu’à son jour, à son heure, à sa minute, parce qu’il a touché la limite de son existence ! TEST: Non… non… sans aucun doute, sans aucun doute… il n’est pas mort… Alors… alors… il va donc falloir que je me tue, moi !… # FIN DU HORLA | < | | 14227 14228 14229 14230 14231 14232 14233 14234 14235 14236 14237 14238 14239 14240 14241 | TEST: Pourquoi ce corps transparent, ce corps inconnaissable, ce corps d’Esprit, s’il devait craindre, lui aussi, les maux, les blessures, les infirmités, la destruction prématurée ? TEST: La destruction prématurée ? toute l’épouvante humaine vient d’elle ! TEST: Après l’homme le Horla. — Après celui qui peut mourir tous les jours, à toutes les heures, à toutes les minutes, par tous les accidents, est venu celui qui ne doit mourir qu’à son jour, à son heure, à sa minute, parce qu’il a touché la limite de son existence ! TEST: Non… non… sans aucun doute, sans aucun doute… il n’est pas mort… Alors… alors… il va donc falloir que je me tue, moi !… # FIN DU HORLA !!! Double assassinat dans la rue morgue, d’Edgar Poe # Texte tiré de Wikisource # Les paragraphes ont été découpés pour réduire la longueur des tests. TEST: DOUBLE ASSASSINAT DANS LA RUE MORGUE — Edgar Poe TEST: Quelle chanson chantaient les sirènes ? quel nom Achille avait-il pris, quand il se cachait parmi les femmes ? – Questions embarrassantes, il est vrai, mais qui ne sont pas situées au-delà de toute conjecture. TEST: Sir Thomas Browne. TODO: Les facultés de l’esprit qu’on définit par le terme {{analytiques}} sont en elles-mêmes fort peu susceptibles d’analyse. TEST: Nous ne les apprécions que par leurs résultats. Ce que nous en savons, entre autres choses, c’est qu’elles sont pour celui qui les possède à un degré extraordinaire une source de jouissances des plus vives. |
︙ | ︙ | |||
14541 14542 14543 14544 14545 14546 14547 | TEST: Néanmoins, qu’il n’ait pas pu débrouiller ce mystère, il n’y a nullement lieu de s’en étonner, et cela est moins singulier qu’il ne le croit ; car, en vérité, notre ami le préfet est un peu trop fin pour être profond. Sa science n’a pas de base. TEST: Elle est tout en tête et n’a pas de corps, comme les portraits de la déesse Laverna, – ou, si vous aimez mieux, tout en tête et en épaules, comme une morue. TEST: Mais, après tout, c’est un brave homme. Je l’adore particulièrement pour un merveilleux genre de cant auquel il doit sa réputation de génie. TEST: Je veux parler de sa manie de nier ce qui est, et d’expliquer ce qui n’est pas[2]. # FIN DU DOUBLE ASSASSINAT DANS LA RUE MORGUE | | | 14771 14772 14773 14774 14775 14776 14777 14778 14779 14780 14781 14782 14783 14784 14785 | TEST: Néanmoins, qu’il n’ait pas pu débrouiller ce mystère, il n’y a nullement lieu de s’en étonner, et cela est moins singulier qu’il ne le croit ; car, en vérité, notre ami le préfet est un peu trop fin pour être profond. Sa science n’a pas de base. TEST: Elle est tout en tête et n’a pas de corps, comme les portraits de la déesse Laverna, – ou, si vous aimez mieux, tout en tête et en épaules, comme une morue. TEST: Mais, après tout, c’est un brave homme. Je l’adore particulièrement pour un merveilleux genre de cant auquel il doit sa réputation de génie. TEST: Je veux parler de sa manie de nier ce qui est, et d’expliquer ce qui n’est pas[2]. # FIN DU DOUBLE ASSASSINAT DANS LA RUE MORGUE !!! Vers Dorés, de Pythagore # Origine? TEST: Aux dieux, suivant les lois, rends de justes hommages ; TEST: Respecte le serment, les héros et les sages ; TEST: Honore tes parents, tes rois, tes bienfaiteurs ; TEST: Choisi parmi tes amis les hommes les meilleurs. TEST: Sois obligeant et doux, sois facile en affaires. TEST: Ne hais pas ton ami pour des fautes légères ; |
︙ | ︙ | |||
14641 14642 14643 14644 14645 14646 14647 | TEST: XXX. Mais abstiens-toi des aliments que je t’ai défendus. Apprends à discerner ce qui est nécessaire dans la purification et la délivrance de l’âme. Examine tout ; donne à ta raison la première place et, content de te laisser conduire, abandonne-lui les rênes. TEST: XXXI. Ainsi, quand tu auras quitté les dépouilles mortelles, tu monteras dans l’air libre ; tu deviendras un dieu immortel et la mort n’aura plus d’empire sur toi. TEST: Fin des vers dorés de Pythagore TEST: Note : Chez les Pythagoriciens, la monade ou l’unité représente Dieu-même, parce qu’elle n’est engendrée par aucun nombre, qu’elle les engendre tous, qu’elle est simple et sans aucune composition. La dyade, ou le nombre deux, est l’image de la nature créée, parce qu’elle est le premier produit de l’unité, parce qu’elle est inspirée, parce qu’ayant des parties elle peut se décomposer et se défendre. La monade et la dyade réunies forment le ternaire, et représentent l’immensité de tout ce qui existe, l’être immuable et la matière altérable et changeante. J’ignore par quelle propriété le quaternaire, le nombre quatre, est encore un emblème de la divinité. # FIN DES VERS DORÉS DE PYTHAGORE | < | | 14871 14872 14873 14874 14875 14876 14877 14878 14879 14880 14881 14882 14883 14884 14885 | TEST: XXX. Mais abstiens-toi des aliments que je t’ai défendus. Apprends à discerner ce qui est nécessaire dans la purification et la délivrance de l’âme. Examine tout ; donne à ta raison la première place et, content de te laisser conduire, abandonne-lui les rênes. TEST: XXXI. Ainsi, quand tu auras quitté les dépouilles mortelles, tu monteras dans l’air libre ; tu deviendras un dieu immortel et la mort n’aura plus d’empire sur toi. TEST: Fin des vers dorés de Pythagore TEST: Note : Chez les Pythagoriciens, la monade ou l’unité représente Dieu-même, parce qu’elle n’est engendrée par aucun nombre, qu’elle les engendre tous, qu’elle est simple et sans aucune composition. La dyade, ou le nombre deux, est l’image de la nature créée, parce qu’elle est le premier produit de l’unité, parce qu’elle est inspirée, parce qu’ayant des parties elle peut se décomposer et se défendre. La monade et la dyade réunies forment le ternaire, et représentent l’immensité de tout ce qui existe, l’être immuable et la matière altérable et changeante. J’ignore par quelle propriété le quaternaire, le nombre quatre, est encore un emblème de la divinité. # FIN DES VERS DORÉS DE PYTHAGORE !!! Épître du feu philosophique, de Jean Pontanus # Les paragraphes ont été découpés et ne correspondent pas à ceux du texte. TEST: Épître du Feu Philosophique TEST: Lettre concernant la pierre dite philosophale TEST: Jean Pontanus TEST: in Theatrum Chimicum, 1614, t. III TEST: « Nous affirmons, au contraire, — et l’on peut avoir foi en notre sincérité, — qu’il sera impossible d’obtenir le moindre succès dans l’Œuvre si l’on a pas une connaissance parfaite de ce qu’est le Vase des Philosophes ni de quelle manière il faut le fabriquer. Pontanus avoue qu’avant de connaître ce vaisseau secret il avait recommencé, sans succès, plus de deux cents fois le même travail, quoiqu’il besognât sur les matières propres et convenables, et selon la méthode régulière. L’artiste doit faire lui-même son vaisseau ; c’est une maxime de l’art. N’entreprenez rien, en conséquence, tant que vous n’aurez pas reçu toute la lumière sur cette coquille de l’œuf qualifiée secretum secretorum chez les maîtres du Moyen Âge. » TEST: — Fulcanelli, Le Mystère des Cathédrales, p. 204-205 |
︙ | ︙ |
Added helpers.py version [dc81791c7e].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | # Useful tools import os import zipfile from distutils import dir_util, file_util from string import Template class cd: "Context manager for changing the current working directory" def __init__ (self, newPath): self.newPath = os.path.expanduser(newPath) def __enter__ (self): self.savedPath = os.getcwd() os.chdir(self.newPath) def __exit__ (self, etype, value, traceback): os.chdir(self.savedPath) def unzip (spfZip, spDest, bCreatePath=False): "unzip file <spfZip> at <spfDest>" if spDest: if bCreatePath and not os.path.exists(spDest): dir_util.mkpath(spDest) print("> unzip in: "+ spDest) spInstall = os.path.abspath(spDest) if os.path.isdir(spInstall): eraseFolder(spInstall) with zipfile.ZipFile(spfZip) as hZip: hZip.extractall(spDest) else: print("# folder not found") else: print("path destination is empty") def eraseFolder (sp): "erase content of a folder" # recursive!!! for sf in os.listdir(sp): spf = sp + "/" + sf if os.path.isdir(spf): eraseFolder(spf) else: try: os.remove(spf) except: print("%s not removed" % spf) def createCleanFolder (sp): "make an empty folder or erase its content if not empty" if not os.path.exists(sp): dir_util.mkpath(sp) else: eraseFolder(sp) def fileFile (spf, dVars): "return file <spf> as a text filed with variables from <dVars>" return Template(open(spf, "r", encoding="utf-8").read()).safe_substitute(dVars) def copyAndFileTemplate (spfSrc, spfDst, dVars): "write file <spfSrc> as <spfDst> with variables filed with <dVars>" s = Template(open(spfSrc, "r", encoding="utf-8").read()).safe_substitute(dVars) open(spfDst, "w", encoding="utf-8", newline="\n").write(s) def addFolderToZipAndFileFile (hZip, spSrc, spDst, dVars, bRecursive): # recursive function spSrc = spSrc.strip("/ ") spDst = spDst.strip("/ ") for sf in os.listdir(spSrc): spfSrc = (spSrc + "/" + sf).strip("/ ") spfDst = (spDst + "/" + sf).strip("/ ") if os.path.isdir(spfSrc): if bRecursive: addFolderToZipAndFileFile(hZip, spfSrc, spfDst, dVars, bRecursive) else: if spfSrc.endswith((".css", ".js", ".xcu", ".xul", ".rdf", ".dtd", ".properties")): #print(spfSrc + " > " + spfDst) hZip.writestr(spfDst, fileFile(spfSrc, dVars)) else: #print(spfSrc + " > " + spfDst) hZip.write(spfSrc, spfDst) |
Modified make.py from [a4db34e055] to [418a36d3bb].
︙ | ︙ | |||
10 11 12 13 14 15 16 | import configparser import datetime import argparse import importlib import unittest import json | < > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import configparser import datetime import argparse import importlib import unittest import json from distutils import dir_util, file_util import dialog_bundled import compile_rules import helpers sWarningMessage = "The content of this folder is generated by code and replaced at each build.\n" def getConfig (sLang): xConfig = configparser.SafeConfigParser() xConfig.optionxform = str try: xConfig.read("gc_lang/" + sLang + "/config.ini", encoding="utf-8") except: |
︙ | ︙ | |||
153 154 155 156 157 158 159 | hZip = zipfile.ZipFile(spfZip, mode='w', compression=zipfile.ZIP_DEFLATED) # Package and parser copyGrammalectePyPackageInZipFile(hZip, spLangPack, dVars['py_binary_dic'], "pythonpath/") hZip.write("cli.py", "pythonpath/cli.py") # Extension files | | | | | | | | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | hZip = zipfile.ZipFile(spfZip, mode='w', compression=zipfile.ZIP_DEFLATED) # Package and parser copyGrammalectePyPackageInZipFile(hZip, spLangPack, dVars['py_binary_dic'], "pythonpath/") hZip.write("cli.py", "pythonpath/cli.py") # Extension files hZip.writestr("META-INF/manifest.xml", helpers.fileFile("gc_core/py/oxt/manifest.xml", dVars)) hZip.writestr("description.xml", helpers.fileFile("gc_core/py/oxt/description.xml", dVars)) hZip.writestr("Linguistic.xcu", helpers.fileFile("gc_core/py/oxt/Linguistic.xcu", dVars)) hZip.writestr("Grammalecte.py", helpers.fileFile("gc_core/py/oxt/Grammalecte.py", dVars)) for sf in dVars["extras"].split(","): hZip.writestr(sf.strip(), helpers.fileFile(spLang + '/' + sf.strip(), dVars)) if "logo" in dVars.keys() and dVars["logo"].strip(): hZip.write(spLang + '/' + dVars["logo"].strip(), dVars["logo"].strip()) ## OPTIONS # options dialog within LO/OO options panel (legacy) #hZip.writestr("pythonpath/lightproof_handler_grammalecte.py", helpers.fileFile("gc_core/py/oxt/lightproof_handler_grammalecte.py", dVars)) #lLineOptions = open(spLang + "/options.txt", "r", encoding="utf-8").readlines() #dialog_bundled.c(dVars["implname"], lLineOptions, hZip, dVars["lang"]) # options dialog hZip.writestr("pythonpath/Options.py", helpers.fileFile("gc_core/py/oxt/Options.py", dVars)) hZip.write("gc_core/py/oxt/op_strings.py", "pythonpath/op_strings.py") # options dialog within Writer options panel dVars["xdl_dialog_options"] = createDialogOptionsXDL(dVars) dVars["xcs_options"] = "\n".join([ '<prop oor:name="'+sOpt+'" oor:type="xs:string"><value></value></prop>' for sOpt in dVars["dOptPython"] ]) dVars["xcu_label_values"] = "\n".join([ '<value xml:lang="'+sLang+'">' + dVars["dOptLabel"][sLang]["__optiontitle__"] + '</value>' for sLang in dVars["dOptLabel"] ]) hZip.writestr("dialog/options_page.xdl", helpers.fileFile("gc_core/py/oxt/options_page.xdl", dVars)) hZip.writestr("dialog/OptionsDialog.xcs", helpers.fileFile("gc_core/py/oxt/OptionsDialog.xcs", dVars)) hZip.writestr("dialog/OptionsDialog.xcu", helpers.fileFile("gc_core/py/oxt/OptionsDialog.xcu", dVars)) hZip.writestr("dialog/" + dVars['lang'] + "_en.default", "") for sLangLbl, dOptLbl in dVars['dOptLabel'].items(): hZip.writestr("dialog/" + dVars['lang'] + "_" + sLangLbl + ".properties", createOptionsLabelProperties(dOptLbl)) ## ADDONS OXT print("+ OXT: ", end="") for spfSrc, spfDst in dOxt.items(): print(spfSrc, end=", ") if os.path.isdir(spLang+'/'+spfSrc): for sf in os.listdir(spLang+'/'+spfSrc): hZip.write(spLang+'/'+spfSrc+"/"+sf, spfDst+"/"+sf) else: if spfSrc.endswith(('.txt', '.py')): hZip.writestr(spfDst, helpers.fileFile(spLang+'/'+spfSrc, dVars)) else: hZip.write(spLang+'/'+spfSrc, spfDst) print() hZip.close() # Installation in Writer profile if bInstall: print("> installation in Writer") if dVars.get('unopkg', False): cmd = '"'+os.path.abspath(dVars.get('unopkg')+'" add -f '+spfZip) print(cmd) #subprocess.run(cmd) os.system(cmd) else: print("# Error: path and filename of unopkg not set in config.ini") def createServerOptions (sLang, dOptData): with open("server_options."+sLang+".ini", "w", encoding="utf-8", newline="\n") as hDst: hDst.write("# Server options. Lang: " + sLang + "\n\n[gc_options]\n") for sSection, lOpt in dOptData["lStructOpt"]: hDst.write("\n########## " + dOptData["dOptLabel"][sLang].get(sSection, sSection + "[no label found]")[0] + " ##########\n") for lLineOpt in lOpt: |
︙ | ︙ | |||
303 304 305 306 307 308 309 | "create server zip" spfZip = "_build/" + dVars['name'] + "-"+ dVars['lang'] +"-v" + dVars['version'] + '.zip' hZip = zipfile.ZipFile(spfZip, mode='w', compression=zipfile.ZIP_DEFLATED) copyGrammalectePyPackageInZipFile(hZip, spLangPack, dVars['py_binary_dic']) for spf in ["cli.py", "server.py", "bottle.py", "server_options._global.ini", "server_options."+sLang+".ini", \ "README.txt", "LICENSE.txt", "LICENSE.fr.txt"]: hZip.write(spf) | | < < < < < < < < < < | 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | "create server zip" spfZip = "_build/" + dVars['name'] + "-"+ dVars['lang'] +"-v" + dVars['version'] + '.zip' hZip = zipfile.ZipFile(spfZip, mode='w', compression=zipfile.ZIP_DEFLATED) copyGrammalectePyPackageInZipFile(hZip, spLangPack, dVars['py_binary_dic']) for spf in ["cli.py", "server.py", "bottle.py", "server_options._global.ini", "server_options."+sLang+".ini", \ "README.txt", "LICENSE.txt", "LICENSE.fr.txt"]: hZip.write(spf) hZip.writestr("setup.py", helpers.fileFile("gc_lang/fr/setup.py", dVars)) def copyGrammalectePyPackageInZipFile (hZip, spLangPack, sDicName, sAddPath=""): for sf in os.listdir("grammalecte"): if not os.path.isdir("grammalecte/"+sf): hZip.write("grammalecte/"+sf, sAddPath+"grammalecte/"+sf) for sf in os.listdir(spLangPack): if not os.path.isdir(spLangPack+"/"+sf): hZip.write(spLangPack+"/"+sf, sAddPath+spLangPack+"/"+sf) hZip.write("grammalecte/_dictionaries/"+sDicName, sAddPath+"grammalecte/_dictionaries/"+sDicName) def create (sLang, xConfig, bInstallOXT, bJavaScript): oNow = datetime.datetime.now() print("============== MAKE GRAMMALECTE [{0}] at {1.hour:>2} h {1.minute:>2} min {1.second:>2} s ==============".format(sLang, oNow)) #### READ CONFIGURATION print("> read configuration...") |
︙ | ︙ | |||
360 361 362 363 364 365 366 | sCodePlugins += "\n\n" + open(spLang+'/modules/'+sf, "r", encoding="utf-8").read() print(sf, end=", ") print() dVars["plugins"] = sCodePlugins ## CREATE GRAMMAR CHECKER PACKAGE spLangPack = "grammalecte/"+sLang | | | | 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | sCodePlugins += "\n\n" + open(spLang+'/modules/'+sf, "r", encoding="utf-8").read() print(sf, end=", ") print() dVars["plugins"] = sCodePlugins ## CREATE GRAMMAR CHECKER PACKAGE spLangPack = "grammalecte/"+sLang helpers.createCleanFolder(spLangPack) for sf in os.listdir("gc_core/py/lang_core"): if not os.path.isdir("gc_core/py/lang_core/"+sf): helpers.copyAndFileTemplate("gc_core/py/lang_core/"+sf, spLangPack+"/"+sf, dVars) print("+ Modules: ", end="") for sf in os.listdir(spLang+"/modules"): if not sf.startswith("gce_"): file_util.copy_file(spLang+"/modules/"+sf, spLangPack) print(sf, end=", ") print() |
︙ | ︙ | |||
398 399 400 401 402 403 404 | dVars["pluginsJS"] = sCodePlugins # options data struct dVars["dOptJavaScript"] = json.dumps(list(dVars["dOptJavaScript"].items())) # create folder spLangPack = "grammalecte-js/"+sLang | | | | | > | > > > | | 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | dVars["pluginsJS"] = sCodePlugins # options data struct dVars["dOptJavaScript"] = json.dumps(list(dVars["dOptJavaScript"].items())) # create folder spLangPack = "grammalecte-js/"+sLang helpers.createCleanFolder(spLangPack) # create files for sf in os.listdir("gc_core/js"): if not os.path.isdir("gc_core/js/"+sf) and sf.startswith("jsex_"): dVars[sf[5:-3]] = open("gc_core/js/"+sf, "r", encoding="utf-8").read() for sf in os.listdir("gc_core/js"): if not os.path.isdir("gc_core/js/"+sf) and not sf.startswith("jsex_"): helpers.copyAndFileTemplate("gc_core/js/"+sf, "grammalecte-js/"+sf, dVars) open("grammalecte-js/WARNING.txt", "w", encoding="utf-8", newline="\n").write(sWarningMessage) for sf in os.listdir("gc_core/js/lang_core"): if not os.path.isdir("gc_core/js/lang_core/"+sf) and sf.startswith("gc_"): helpers.copyAndFileTemplate("gc_core/js/lang_core/"+sf, spLangPack+"/"+sf, dVars) print("+ Modules: ", end="") for sf in os.listdir(spLang+"/modules-js"): if not sf.startswith("gce_"): helpers.copyAndFileTemplate(spLang+"/modules-js/"+sf, spLangPack+"/"+sf, dVars) print(sf, end=", ") print() try: build_module = importlib.import_module("gc_lang."+sLang+".build") except ImportError: print("# No complementary builder <build.py> in folder gc_lang/"+sLang) else: build_module.build(sLang, dVars, spLangPack) return dVars['version'] def main (): print("Python: " + sys.version) xParser = argparse.ArgumentParser() |
︙ | ︙ | |||
451 452 453 454 455 456 457 | if os.path.exists("gc_lang/"+sLang) and os.path.isdir("gc_lang/"+sLang): xConfig = getConfig(sLang) dVars = xConfig._sections['args'] # copy gc_core common file in Python now to be able to compile dictionary if required for sf in os.listdir("gc_core/py"): if not os.path.isdir("gc_core/py/"+sf): | | | | | | | | | 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 | if os.path.exists("gc_lang/"+sLang) and os.path.isdir("gc_lang/"+sLang): xConfig = getConfig(sLang) dVars = xConfig._sections['args'] # copy gc_core common file in Python now to be able to compile dictionary if required for sf in os.listdir("gc_core/py"): if not os.path.isdir("gc_core/py/"+sf): helpers.copyAndFileTemplate("gc_core/py/"+sf, "grammalecte/"+sf, dVars) open("grammalecte/WARNING.txt", "w", encoding="utf-8", newline="\n").write(sWarningMessage) # build data build_data_module = None if xArgs.build_data: # lang data try: build_data_module = importlib.import_module("gc_lang."+sLang+".build_data") except ImportError: print("# Error. Couldn’t import file build_data.py in folder gc_lang/"+sLang) if build_data_module: build_data_module.before('gc_lang/'+sLang, dVars, xArgs.javascript) if xArgs.dict or not os.path.exists("grammalecte/_dictionaries"): import grammalecte.dawg as fsa from grammalecte.ibdawg import IBDAWG # fsa builder oDAWG = fsa.DAWG(dVars['lexicon_src'], dVars['lang_name'], dVars['stemming_method']) dir_util.mkpath("grammalecte/_dictionaries") oDAWG.writeInfo("grammalecte/_dictionaries/" + dVars['py_binary_dic'] + ".info.txt") oDAWG.createBinary("grammalecte/_dictionaries/" + dVars['py_binary_dic'], int(dVars['fsa_method'])) if xArgs.javascript: dir_util.mkpath("grammalecte-js/_dictionaries") oDic = IBDAWG(dVars['py_binary_dic']) #oDic.writeAsJSObject("gc_lang/"+sLang+"/modules-js/dictionary.js") oDic.writeAsJSObject("grammalecte-js/_dictionaries/"+dVars['js_binary_dic']) if build_data_module: build_data_module.after('gc_lang/'+sLang, dVars, xArgs.javascript) # make sVersion = create(sLang, xConfig, xArgs.install, xArgs.javascript, ) # tests if xArgs.tests or xArgs.perf or xArgs.perf_memo: print("> Running tests") |
︙ | ︙ | |||
501 502 503 504 505 506 507 | unittest.TextTestRunner().run(xTestSuite) if xArgs.perf or xArgs.perf_memo: hDst = open("./gc_lang/"+sLang+"/perf_memo.txt", "a", encoding="utf-8", newline="\n") if xArgs.perf_memo else None tests.perf(sVersion, hDst) # Firefox if xArgs.firefox: | | | 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 | unittest.TextTestRunner().run(xTestSuite) if xArgs.perf or xArgs.perf_memo: hDst = open("./gc_lang/"+sLang+"/perf_memo.txt", "a", encoding="utf-8", newline="\n") if xArgs.perf_memo else None tests.perf(sVersion, hDst) # Firefox if xArgs.firefox: with helpers.cd("_build/xpi/"+sLang): os.system("jpm run -b nightly") # Thunderbird if xArgs.thunderbird: os.system("thunderbird -jsconsole -P debug") else: print("Folder not found: gc_lang/"+sLang) if __name__ == '__main__': main() |
Modified misc/grammalecte.sublime-syntax from [5e8bef6d14] to [f7dfed6343].
︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 30 31 | scope: punctuation.definition.comment push: line_comment # Numbers - match: '\b(-)?[0-9.]+\b' scope: constant.numeric # Keywords are if, else. # Note that blackslashes don't need to be escaped within single quoted # strings in YAML. When using single quoted strings, only single quotes # need to be escaped: this is done by using two single quotes next to each # other. - match: '\b(?:if|else|and|or|not|in)\b' scope: keyword.python | > > > > | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | scope: punctuation.definition.comment push: line_comment # Numbers - match: '\b(-)?[0-9.]+\b' scope: constant.numeric # Bookmarks - match: '^!!.*|^\[\+\+\].*' scope: bookmark # Keywords are if, else. # Note that blackslashes don't need to be escaped within single quoted # strings in YAML. When using single quoted strings, only single quotes # need to be escaped: this is done by using two single quotes next to each # other. - match: '\b(?:if|else|and|or|not|in)\b' scope: keyword.python |
︙ | ︙ |
Modified misc/grammalecte.tmTheme from [8385539529] to [7305de87f8].
︙ | ︙ | |||
51 52 53 54 55 56 57 58 59 60 61 62 63 64 | <string>comment</string> <key>settings</key> <dict> <key>foreground</key> <string>#607080</string> </dict> </dict> <dict> <key>name</key> <string>String</string> <key>scope</key> <string>string</string> <key>settings</key> <dict> | > > > > > > > > > > > > > | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | <string>comment</string> <key>settings</key> <dict> <key>foreground</key> <string>#607080</string> </dict> </dict> <dict> <key>name</key> <string>Bookmark</string> <key>scope</key> <string>bookmark</string> <key>settings</key> <dict> <key>foreground</key> <string>#A0F0FF</string> <key>background</key> <string>#0050A0</string> </dict> </dict> <dict> <key>name</key> <string>String</string> <key>scope</key> <string>string</string> <key>settings</key> <dict> |
︙ | ︙ |