Grammalecte  Check-in [cfbaf0ad4e]

Overview
Comment:[graphspell] tokenizer: exclude underscore from WORD token [fr] ajustements, écriture inclusive
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk | fr | major_change | graphspell
Files: files | file ages | folders
SHA3-256: cfbaf0ad4e6eb9bb2951e63158c5ea7a24b00774656467fbe82a30510f4bc52a
User & Date: olr on 2020-10-01 14:50:13
Other Links: manifest | tags
Context
2020-10-02
09:32
[graphspell] tokenizer: token UNDERSCORE check-in: e2313363fe user: olr tags: trunk, graphspell
2020-10-01
14:50
[graphspell] tokenizer: exclude underscore from WORD token [fr] ajustements, écriture inclusive check-in: cfbaf0ad4e user: olr tags: trunk, fr, major_change, graphspell
2020-09-30
16:19
[fr] update tests check-in: ec053526e5 user: olr tags: trunk, fr
Changes

Modified gc_lang/fr/modules-js/gce_suggestions.js from [0b731f6b4f] to [3ee9926088].

667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688

689
690
        return "st";
    }
    return "_";
}


const _dNormalizedCharsForInclusiveWriting = new Map([
    ['(', '_'],  [')', '_'],
    ['.', '_'],  ['·', '_'],  ['•', '_'],
    ['–', '_'],  ['—', '_'],
    ['/', '_']
]);

function normalizeInclusiveWriting (sToken) {
    let sRes = "";
    for (let c of sToken) {
        if (_dNormalizedCharsForInclusiveWriting.has(c)) {
            sRes += _dNormalizedCharsForInclusiveWriting.get(c);
        } else {
            sRes += c;
        }
    }

    return sRes;
}







|
|
|
|











>


667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
        return "st";
    }
    return "_";
}


const _dNormalizedCharsForInclusiveWriting = new Map([
    ['(', '·'],  [')', '·'],
    ['.', '·'],  ['·', '·'],  ['•', '·'],
    ['–', '·'],  ['—', '·'],
    ['/', '·']
]);

function normalizeInclusiveWriting (sToken) {
    let sRes = "";
    for (let c of sToken) {
        if (_dNormalizedCharsForInclusiveWriting.has(c)) {
            sRes += _dNormalizedCharsForInclusiveWriting.get(c);
        } else {
            sRes += c;
        }
    }
    sRes = sRes.replace("èr·", "er·").replace("ÈR·", "ER·");
    return sRes;
}

Modified gc_lang/fr/modules/gce_suggestions.py from [5701f141a0] to [0e43053b7b].

525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
        return "st"
    return "_"




_xNormalizedCharsForInclusiveWriting = str.maketrans({
    '(': '_',  ')': '_',
    '.': '_',  '·': '_',  '•': '_',
    '–': '_',  '—': '_',
    '/': '_'
})


def normalizeInclusiveWriting (sToken):
    "typography: replace word separators used in inclusive writing by underscore (_)"
    return sToken.translate(_xNormalizedCharsForInclusiveWriting)







|
|
|
|





|
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
        return "st"
    return "_"




_xNormalizedCharsForInclusiveWriting = str.maketrans({
    '(': '·',  ')': '·',
    '.': '·',  '·': '·',  '•': '·',
    '–': '·',  '—': '·',
    '/': '·'
})


def normalizeInclusiveWriting (sToken):
    "typography: replace word separators used in inclusive writing by underscore (_)"
    return sToken.translate(_xNormalizedCharsForInclusiveWriting).replace("èr·", "er·").replace("ÈR·", "ER·")

Modified gc_lang/fr/perf_memo.txt from [e113d352f1] to [5cb40c8830].

31
32
33
34
35
36
37

1.9.0       2020.04.20 19:57    1.51183     0.369546    0.25681     0.0734314   0.0764396   0.0785668   0.183922    0.103674    0.0185812   0.002099    (NFC normalization)
1.9.2       2020.05.12 08:43    1.62465     0.398831    0.273012    0.0810811   0.080937    0.0845885   0.204133    0.114146    0.0212864   0.0029547
1.12.2      2020.09.09 13:34    1.50568     0.374504    0.233108    0.0798712   0.0804466   0.0769674   0.171519    0.0945132   0.0165344   0.0019474
1.12.2      2020.09.09 13:35    1.41094     0.359093    0.236443    0.06968     0.0734418   0.0738087   0.169371    0.0946279   0.0167106   0.0019773
1.12.2      2020.09.11 19:16    1.35297     0.330545    0.221731    0.0666998   0.0692539   0.0701707   0.160564    0.0891676   0.015807    0.0045998
1.12.2      2020.09.30 14:50    1.37531     0.330381    0.226012    0.0668063   0.0690574   0.0694727   0.160282    0.0929373   0.0176629   0.0019713
1.12.2      2020.09.30 17:01    1.37168     0.329009    0.248127    0.0670758   0.0701238   0.0910568   0.170556    0.093876    0.0168925   0.0020051








>
31
32
33
34
35
36
37
38
1.9.0       2020.04.20 19:57    1.51183     0.369546    0.25681     0.0734314   0.0764396   0.0785668   0.183922    0.103674    0.0185812   0.002099    (NFC normalization)
1.9.2       2020.05.12 08:43    1.62465     0.398831    0.273012    0.0810811   0.080937    0.0845885   0.204133    0.114146    0.0212864   0.0029547
1.12.2      2020.09.09 13:34    1.50568     0.374504    0.233108    0.0798712   0.0804466   0.0769674   0.171519    0.0945132   0.0165344   0.0019474
1.12.2      2020.09.09 13:35    1.41094     0.359093    0.236443    0.06968     0.0734418   0.0738087   0.169371    0.0946279   0.0167106   0.0019773
1.12.2      2020.09.11 19:16    1.35297     0.330545    0.221731    0.0666998   0.0692539   0.0701707   0.160564    0.0891676   0.015807    0.0045998
1.12.2      2020.09.30 14:50    1.37531     0.330381    0.226012    0.0668063   0.0690574   0.0694727   0.160282    0.0929373   0.0176629   0.0019713
1.12.2      2020.09.30 17:01    1.37168     0.329009    0.248127    0.0670758   0.0701238   0.0910568   0.170556    0.093876    0.0168925   0.0020051
1.12.2      2020.10.01 11:18    1.36493     0.34176     0.24473     0.0691607   0.0720002   0.0903613   0.170067    0.0934571   0.0174357   0.0019585   

Modified gc_lang/fr/rules.grx from [42e8c93b4a] to [339e0d4e7e].

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
    ([A-Z][.][A-Z][.](?:[A-Z][.])*) +[A-ZÉÀÂÊÎÈÔ]  @@0  <<- ~1>> =\1.replace(".", "")+"."
__[s>(p_sigle2)__
    [a-zA-Z][.][a-zA-Z][.](?:[a-zA-Z][.])*
        <<- not re.search("(?i)^(?:i\\.e\\.|s\\.[tv]\\.p\\.|e\\.g\\.|a\\.k\\.a\\.|c\\.q\\.f\\.d\\.|b\\.a\\.|n\\.b\\.)$", \0) >>>
        <<- \0.__len__() == 4 ->> =\0.replace(".", "").upper() + "|" + \0[0:2] + " " + \0[2:4]
        && Sigle. Il est recommandé d’ôter les points pour les sigles. (S’il s’agit d’un prénom et d’un nom, mettez un espace.)|https://fr.wikipedia.org/wiki/Sigle#Typographie
        <<- __else__ ->> =\0.replace(".", "").upper()                                               && Sigle. Il est recommandé d’ôter les points pour les sigles.|https://fr.wikipedia.org/wiki/Sigle#Typographie
        <<- \0 != "b.a." ~>> =\0.replace(".", "_")
__[s>(p_sigle3)__
    J[.]-[A-Z][.] <<- ~>> =\0.replace(".", "").replace("-","")

# Mr et MM
__[s>(p_M_point)__
    (M[.]) (?:[A-ZÉÈÎ]\w*|l[e'’])  @@0 <<- ~1>> Mr
__[s>(p_MM_point)__
    MM[.] <<- ~>> "MM "
__[s>(p_Mr_Mgr_Mme_point)__
    M(?:r|gr|me) [A-ZÉ]([.])(?=\W+[a-zéèêâîïû]) @@$ <<- ~1>> *

# Patronyme réduit à une seule lettre
__[s](p_prénom_lettre_point_patronyme)__
    ([A-ZÉÈÂÎ][\w-]+)[  ][A-ZÉÈÂ]([.])[  ]([A-ZÉÈÂ][\w-]+) @@0,*,$
    <<- morph(\1, ":M[12]") and (morph(\3, ":(?:M[12]|V)") or not spell(\3)) ~2>> *
__[s>(p_prénom_lettre_point)__
    ([A-ZÉÈÂÎ][\w-]+)[  ][A-ZÉÈÂ]([.]) @@0,$
    <<- morph(\1, ":M[12]") and after("^\\W+[a-zéèêîïâ]") ~2>> _

# Patronymes composés avec Le/La/Les
__[s](p_patronyme_composé_avec_le_la_les)__
    [A-ZÉÈÂÎ][\w-]+[-–—]L(?:es?|a) [A-ZÉÈÂÎ][\w-]+ <<- ~>> =\0.replace(" ", "_")

# IP
__[s](p_adresse_IP)__
    \d+[.:]\d+[.:]\d+[.:]\d+  <<- ~>> *

# Arborescence
__[s>(p_arborescence_Linux_Mac)__







|





|















|







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
    ([A-Z][.][A-Z][.](?:[A-Z][.])*) +[A-ZÉÀÂÊÎÈÔ]  @@0  <<- ~1>> =\1.replace(".", "")+"."
__[s>(p_sigle2)__
    [a-zA-Z][.][a-zA-Z][.](?:[a-zA-Z][.])*
        <<- not re.search("(?i)^(?:i\\.e\\.|s\\.[tv]\\.p\\.|e\\.g\\.|a\\.k\\.a\\.|c\\.q\\.f\\.d\\.|b\\.a\\.|n\\.b\\.)$", \0) >>>
        <<- \0.__len__() == 4 ->> =\0.replace(".", "").upper() + "|" + \0[0:2] + " " + \0[2:4]
        && Sigle. Il est recommandé d’ôter les points pour les sigles. (S’il s’agit d’un prénom et d’un nom, mettez un espace.)|https://fr.wikipedia.org/wiki/Sigle#Typographie
        <<- __else__ ->> =\0.replace(".", "").upper()                                               && Sigle. Il est recommandé d’ôter les points pour les sigles.|https://fr.wikipedia.org/wiki/Sigle#Typographie
        <<- \0 != "b.a." ~>> =\0.replace(".", "-")
__[s>(p_sigle3)__
    J[.]-[A-Z][.] <<- ~>> =\0.replace(".", "").replace("-","")

# Mr et MM
__[s>(p_M_point)__
    (M[.]) (?:[A-ZÉÈÎ]\w*|l[ae'’])  @@0 <<- ~1>> Mr
__[s>(p_MM_point)__
    MM[.] <<- ~>> "MM "
__[s>(p_Mr_Mgr_Mme_point)__
    M(?:r|gr|me) [A-ZÉ]([.])(?=\W+[a-zéèêâîïû]) @@$ <<- ~1>> *

# Patronyme réduit à une seule lettre
__[s](p_prénom_lettre_point_patronyme)__
    ([A-ZÉÈÂÎ][\w-]+)[  ][A-ZÉÈÂ]([.])[  ]([A-ZÉÈÂ][\w-]+) @@0,*,$
    <<- morph(\1, ":M[12]") and (morph(\3, ":(?:M[12]|V)") or not spell(\3)) ~2>> *
__[s>(p_prénom_lettre_point)__
    ([A-ZÉÈÂÎ][\w-]+)[  ][A-ZÉÈÂ]([.]) @@0,$
    <<- morph(\1, ":M[12]") and after("^\\W+[a-zéèêîïâ]") ~2>> _

# Patronymes composés avec Le/La/Les
__[s](p_patronyme_composé_avec_le_la_les)__
    [A-ZÉÈÂÎ][\w-]+[-–—]L(?:es?|a) [A-ZÉÈÂÎ][\w-]+ <<- ~>> =\0.replace(" ", "-")

# IP
__[s](p_adresse_IP)__
    \d+[.:]\d+[.:]\d+[.:]\d+  <<- ~>> *

# Arborescence
__[s>(p_arborescence_Linux_Mac)__
787
788
789
790
791
792
793

794
795
796
797
798
799
800
801
802

803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843


844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879

880
881


882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
__[i](eepi_écriture_épicène_tous_toutes)__
    tous?[.(/·•⋅–—-]te[.)/·•⋅–—-]?s
        <<- option("eepi") ->> tous et toutes|toutes et tous
        && Écriture épicène dystypographique et imprononçable. À des fins de lisibilité, il est préférable d’éviter l’abus de graphies épicènes trop complexes.
        <<- ~>> =normalizeInclusiveWriting(\0)

TEST: {{tou.tes}} sont là.                                              ->> tous et toutes|toutes et tous



__[i](eepi_écriture_épicène_ceux_celles)__
    c[./·•⋅–—-]?eux?[./·•⋅–—-]elles
        <<- option("eepi") ->> ceux et celles|celles et ceux
        && Écriture épicène dystypographique et imprononçable. À des fins de lisibilité, il est préférable d’éviter l’abus de graphies épicènes trop complexes.
        <<- ~>> =normalizeInclusiveWriting(\0)

TEST: avec {{ceux.elles}} qui viendront                                 ->> ceux et celles|celles et ceux



__[u](eepi_écriture_épicène_pluriel_eur_divers)__
    ({w_2})eurs?[.(/·•⋅–—-][tdp]?(rice|euse|se|[oe]resse)[.)/·•⋅–—-]?s  @@0,**
        <<- option("eepi") and \2 != "se" ->> \1eurs et \1\2s|\1\2s et \1eurs
        && Écriture épicène dystypographique et imprononçable. À des fins de lisibilité, il est préférable d’éviter l’abus de graphies épicènes trop complexes.
        <<- option("eepi") and \2 == "se" ->> \1eurs et \1euses|\1euses et \1eurs
        && Écriture épicène dystypographique et imprononçable. À des fins de lisibilité, il est préférable d’éviter l’abus de graphies épicènes trop complexes.
        <<- ~>> =normalizeInclusiveWriting(\0)

TEST: travaillons avec les {{instituteur.trice.s}}                          ->> instituteurs et institutrices|institutrices et instituteurs
TEST: La communauté des {{développeur·se·s}} open source                    ->> développeurs et développeuses|développeuses et développeurs


__[u](eepi_écriture_épicène_pluriel_eux_euses)__
    ({w_2})eux[.(/·•⋅–—-](?:[tdsi]?euse|se)[.)/·•⋅–—-]?s  @@0
        <<- option("eepi") ->> \1eux et \1euses|\1euses et \1eux
        && Écriture épicène dystypographique et imprononçable. À des fins de lisibilité, il est préférable d’éviter l’abus de graphies épicènes trop complexes.
        <<- ~>> =normalizeInclusiveWriting(\0)

TEST: {{nombreux·ses}} sont les profs qui s’indignent de cette situation.   ->> nombreux et nombreuses|nombreuses et nombreux


__[u](eepi_écriture_épicène_pluriel_if_ive)__
    ({w_2})ifs?[.(/·•⋅–—-][std]?i?ve[.)/·•⋅–—-]?s  @@0
        <<- option("eepi") ->> \1ifs et \1ives|\1ives et \1ifs
        && Écriture épicène dystypographique et imprononçable. À des fins de lisibilité, il est préférable d’éviter l’abus de graphies épicènes trop complexes.
        <<- ~>> =normalizeInclusiveWriting(\0)

TEST: {{inclusif.ive.s}}                                                ->> inclusifs et inclusives|inclusives et inclusifs
TEST: {{offensif.ve.s}}                                                 ->> offensifs et offensives|offensives et offensifs


__[u](eepi_écriture_épicène_pluriel_er_ère)__
    ({w_2})[eè]rs?[.(/·•⋅–—-]i?è?re[.)/·•⋅–—-]?s  @@0
        <<- option("eepi") and not re.search("[rR]·[eE]·[sS]$", \0) ->> \1ers et \1ères|\1ères et \1ers|\1er·e·s
        && Écriture épicène dystypographique et imprononçable. À des fins de lisibilité, il est préférable d’éviter l’abus de graphies épicènes trop complexes.
        <<- ~>> =normalizeInclusiveWriting(\0)

TEST: les {{conseiller.ière.s}}                                         ->> conseillers et conseillères|conseillères et conseillers|conseiller·e·s
#TEST: les {{artificièr.e.s}}                                            ->> artificiers et artificières|artificières et artificiers




__[u](eepi_écriture_épicène_pluriel_aux_ales)__
    ({w_2})aux[.(/·•⋅–—-][tnmcpbd]?a?le[.)/·•⋅–—-]?s  @@0
        <<- option("eepi") ->> \1al·e·s|\1aux et \1ales|\1ales et \1aux
        && Écriture épicène dystypographique et imprononçable. Pour ce cas, il peut être intéressant de faire comme si le pluriel masculin était régulier, ce qui rend l’ensemble prononçable…
        <<- ~>> =normalizeInclusiveWriting(\0)

TEST: {{locaux·ales}}                                                   ->> local·e·s|locaux et locales|locales et locaux
TEST: LOCAL·E·S
TEST: amical·e·s


__[u](eepi_écriture_épicène_pluriel_e)__
    ({w_1}[éuitsrnldf])[-·–—.•⋅(/]([ntlf]?e)[-·–—.•⋅)/]?s  @@0,**
        <<- not (\0.endswith(".Les") or \0.endswith(".Tes")) >>>
        <<- ~>> =normalizeInclusiveWriting(\0)
        <<- option("eepi") and not \0.endswith("les") and not \0.endswith("LES") and not re.search("(?i)·[ntlf]?e·s$", \0) >>>
        <<- \1.endswith("s") or \1.endswith("S") ->> \1·\2·s|\1 et \1\2s|\1\2s et \1                && Écriture épicène. Utilisez les points médians ou écrivez en toutes lettres.
        <<- __else__ ->> \1·\2·s|\1s et \1\2s|\1\2s et \1s                                          && Écriture épicène. Utilisez les points médians ou écrivez en toutes lettres.

TEST: nous sommes {{déconsidéré-e-s}}.
TEST: serons-nous toujours {{perdu.e.s}}.
TEST: les illustres {{inconnu(e)s}}.
TEST: la situation des {{salarié/e/s}}.
TEST: des {{Iranien-ne-s}} sont venues                                  ->> Iranien·ne·s|Iraniens et Iraniennes|Iraniennes et Iraniens
TEST: rendez-vous avec des {{écrivain(e)s}}                             ->> écrivain·e·s|écrivains et écrivaines|écrivaines et écrivains
TEST: Avec les {{Berlinois.e.s}}                                        ->> Berlinois·e·s|Berlinois et Berlinoises|Berlinoises et Berlinois
TEST: la graphie “{{militant(e)s}}”.
TEST: ces militant·e·s {{acharné}}.
TEST: chez les {{immortel.le.s}}
TEST: Nous sommes {{tombé.es}} par hasard
TEST: Nous avons été {{révolté.es}} de cette novlangue politique
TEST: Pour survivre, nous sommes {{devenu.es}} des archéologues.
TEST: {{enthousiasmé.es}} par un tri collectif de noix
TEST: IMMORTEL·LE·S

TEST: Berlinois·e·s
TEST: Iranien·ne·s




__[i](eepi_écriture_épicène_singulier)__
    ({w_1}[éuitsrnldf])([-·–—.•⋅/][ntl]?e|[(][ntl]?e[)])  @@0,$
        <<- not (\0.endswith(".Le") or \0.endswith(".Ne") or \0.endswith(".De"))
            and not ((\0.endswith("-le") or \0.endswith("-Le") or \0.endswith("-LE")) and not (\1.endswith("l") or \1.endswith("L"))) >>>
        <<- ~>> =normalizeInclusiveWriting(\0)
        <<- option("eepi") and re.search("^[uU][nN][-–—.•⋅/][eE]$", \0) ->> un·e|un ou une|une ou un                    && Écriture épicène. Utilisez les points médians ou écrivez en toutes lettres.
        <<- __else__ and option("eepi") and not re.search("(?i)·[ntl]?e$", \2) ->> =\1+"·"+\2[1:].rstrip(")")           && Écriture épicène. Utilisez un point médian.

TEST: je suis {{déconsidéré.e}} par ma hiérarchie.                      ->> déconsidéré·e
TEST: il faut en parler à l’{{auteur(e)}} et à son agent.               ->> auteur·e
TEST: le ou la {{patron/ne}}                                            ->> patron·ne
TEST: Totalement {{con(ne)}}                                            ->> con·ne
TEST: un ou une {{intellectuel.le}}                                     ->> intellectuel·le
TEST: {{un/e}} immortel·le                                              ->> un·e|un ou une|une ou un
TEST: INTELLECTUEL·LE
TEST: électricien·ne
TEST: Épuisé·e
TEST: un·e idiot·e


__[i](typo_écriture_invariable)__
    ({w_3})([-·–—.•⋅/]s|[(]s[)])  @@0,$
        <<- ~>> =normalizeInclusiveWriting(\0)
        <<- option("typo") and option("eepi") and not \0.endswith("·s") and not (\0.endswith("/s") and morph(\1, ";S"))
        ->> \1·s                                                                                    && Écriture invariable. Utilisez un point médian.

TEST: la ou les {{fille(s)}}                                            ->> fille·s
TEST: le ou les patron·s
TEST: combien de rad/s



!!
!!
!!!! Majuscules manquantes                                                                        !!
!!
!!







>









>


|











|








|









|
|
|



|
|
>
>


|






|
|


|
|


|

















|
>
|
|
>
>
















|
|
|












<







787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919

920
921
922
923
924
925
926
__[i](eepi_écriture_épicène_tous_toutes)__
    tous?[.(/·•⋅–—-]te[.)/·•⋅–—-]?s
        <<- option("eepi") ->> tous et toutes|toutes et tous
        && Écriture épicène dystypographique et imprononçable. À des fins de lisibilité, il est préférable d’éviter l’abus de graphies épicènes trop complexes.
        <<- ~>> =normalizeInclusiveWriting(\0)

TEST: {{tou.tes}} sont là.                                              ->> tous et toutes|toutes et tous
TEST: {{tou·tes}} sont là.                                              ->> tous et toutes|toutes et tous


__[i](eepi_écriture_épicène_ceux_celles)__
    c[./·•⋅–—-]?eux?[./·•⋅–—-]elles
        <<- option("eepi") ->> ceux et celles|celles et ceux
        && Écriture épicène dystypographique et imprononçable. À des fins de lisibilité, il est préférable d’éviter l’abus de graphies épicènes trop complexes.
        <<- ~>> =normalizeInclusiveWriting(\0)

TEST: avec {{ceux.elles}} qui viendront                                 ->> ceux et celles|celles et ceux
TEST: {{c·eux·elles}}                                                   ->> ceux et celles|celles et ceux


__[i](eepi_écriture_épicène_pluriel_eur_divers)__
    ({w_2})eurs?[.(/·•⋅–—-][tdp]?(rice|euse|se|[oe]resse)[.)/·•⋅–—-]?s  @@0,**
        <<- option("eepi") and \2 != "se" ->> \1eurs et \1\2s|\1\2s et \1eurs
        && Écriture épicène dystypographique et imprononçable. À des fins de lisibilité, il est préférable d’éviter l’abus de graphies épicènes trop complexes.
        <<- option("eepi") and \2 == "se" ->> \1eurs et \1euses|\1euses et \1eurs
        && Écriture épicène dystypographique et imprononçable. À des fins de lisibilité, il est préférable d’éviter l’abus de graphies épicènes trop complexes.
        <<- ~>> =normalizeInclusiveWriting(\0)

TEST: travaillons avec les {{instituteur.trice.s}}                          ->> instituteurs et institutrices|institutrices et instituteurs
TEST: La communauté des {{développeur·se·s}} open source                    ->> développeurs et développeuses|développeuses et développeurs


__[i](eepi_écriture_épicène_pluriel_eux_euses)__
    ({w_2})eux[.(/·•⋅–—-](?:[tdsi]?euse|se)[.)/·•⋅–—-]?s  @@0
        <<- option("eepi") ->> \1eux et \1euses|\1euses et \1eux
        && Écriture épicène dystypographique et imprononçable. À des fins de lisibilité, il est préférable d’éviter l’abus de graphies épicènes trop complexes.
        <<- ~>> =normalizeInclusiveWriting(\0)

TEST: {{nombreux·ses}} sont les profs qui s’indignent de cette situation.   ->> nombreux et nombreuses|nombreuses et nombreux


__[i](eepi_écriture_épicène_pluriel_if_ive)__
    ({w_2})ifs?[.(/·•⋅–—-][std]?i?ve[.)/·•⋅–—-]?s  @@0
        <<- option("eepi") ->> \1ifs et \1ives|\1ives et \1ifs
        && Écriture épicène dystypographique et imprononçable. À des fins de lisibilité, il est préférable d’éviter l’abus de graphies épicènes trop complexes.
        <<- ~>> =normalizeInclusiveWriting(\0)

TEST: {{inclusif.ive.s}}                                                ->> inclusifs et inclusives|inclusives et inclusifs
TEST: {{offensif.ve.s}}                                                 ->> offensifs et offensives|offensives et offensifs


__[i](eepi_écriture_épicène_pluriel_er_ère)__
    ({w_2})[eè]rs?[.(/·•⋅–—-](?:i?è?re|e)[.)/·•⋅–—-]?s  @@0
        <<- option("eepi") and not re.search("[eE][rR]·[eE]·[sS]$", \0) ->> \1er·e·s|\1ers et \1ères|\1ères et \1ers
        && Écriture épicène dystypographique et imprononçable. À des fins de lisibilité, il est préférable d’éviter l’abus de graphies épicènes trop complexes.
        <<- ~>> =normalizeInclusiveWriting(\0)

TEST: les {{conseiller.ière.s}}                                         ->> conseiller·e·s|conseillers et conseillères|conseillères et conseillers
TEST: les {{artificièr.e.s}}                                            ->> artificier·e·s|artificiers et artificières|artificières et artificiers
TEST: les {{artificièr·e·s}}                                            ->> artificier·e·s|artificiers et artificières|artificières et artificiers
TEST: les artificier·e·s


__[i](eepi_écriture_épicène_pluriel_aux_ales)__
    ({w_2})aux[.(/·•⋅–—-][tnmcpbd]?a?le[.)/·•⋅–—-]?s  @@0
        <<- option("eepi") ->> \1al·e·s|\1aux et \1ales|\1ales et \1aux
        && Écriture épicène dystypographique et imprononçable. Pour ce cas, il peut être intéressant de faire comme si le pluriel masculin était régulier, ce qui rend l’ensemble prononçable…
        <<- ~>> =normalizeInclusiveWriting(\0)

TEST: {{locaux·ales}}                                                   ->> local·e·s|locaux et locales|locales et locaux
TEST: NOUS SOMMES LOCAL·E·S
TEST: nous sommes amical·e·s


__[i](eepi_écriture_épicène_pluriel_e)__
    ({w_1}[éuitsnldf])[-·–—.•⋅(/]([ntlf]?e)[-·–—.•⋅)/]?s  @@0,**
        <<- not (\0.endswith(".Les") or \0.endswith(".Tes")) >>>
        <<- ~>> =normalizeInclusiveWriting(\0)
        <<- option("eepi") and not \0.endswith("les") and not \0.endswith("LES") and not re.search("·[ntlfNTLF]?[eE]·[sS]$", \0) >>>
        <<- \1.endswith("s") or \1.endswith("S") ->> \1·\2·s|\1 et \1\2s|\1\2s et \1                && Écriture épicène. Utilisez les points médians ou écrivez en toutes lettres.
        <<- __else__ ->> \1·\2·s|\1s et \1\2s|\1\2s et \1s                                          && Écriture épicène. Utilisez les points médians ou écrivez en toutes lettres.

TEST: nous sommes {{déconsidéré-e-s}}.
TEST: serons-nous toujours {{perdu.e.s}}.
TEST: les illustres {{inconnu(e)s}}.
TEST: la situation des {{salarié/e/s}}.
TEST: des {{Iranien-ne-s}} sont venues                                  ->> Iranien·ne·s|Iraniens et Iraniennes|Iraniennes et Iraniens
TEST: rendez-vous avec des {{écrivain(e)s}}                             ->> écrivain·e·s|écrivains et écrivaines|écrivaines et écrivains
TEST: Avec les {{Berlinois.e.s}}                                        ->> Berlinois·e·s|Berlinois et Berlinoises|Berlinoises et Berlinois
TEST: la graphie “{{militant(e)s}}”.
TEST: ces militant·e·s {{acharné}}.
TEST: chez les {{immortel.le.s}}
TEST: Nous sommes {{tombé.es}} par hasard
TEST: Nous avons été {{révolté.es}} de cette novlangue politique
TEST: Pour survivre, nous sommes {{devenu.es}} des archéologues.
TEST: {{enthousiasmé.es}} par un tri collectif de noix
TEST: LES IMMORTEL·LE·S
TEST: les mortel·le·s
TEST: des Berlinois·e·s
TEST: les Iranien·ne·s
TEST: les chef·fe·s
TEST: nos descendant·e·s


__[i](eepi_écriture_épicène_singulier)__
    ({w_1}[éuitsrnldf])([-·–—.•⋅/][ntl]?e|[(][ntl]?e[)])  @@0,$
        <<- not (\0.endswith(".Le") or \0.endswith(".Ne") or \0.endswith(".De"))
            and not ((\0.endswith("-le") or \0.endswith("-Le") or \0.endswith("-LE")) and not (\1.endswith("l") or \1.endswith("L"))) >>>
        <<- ~>> =normalizeInclusiveWriting(\0)
        <<- option("eepi") and re.search("^[uU][nN][-–—.•⋅/][eE]$", \0) ->> un·e|un ou une|une ou un                    && Écriture épicène. Utilisez les points médians ou écrivez en toutes lettres.
        <<- __else__ and option("eepi") and not re.search("(?i)·[ntl]?e$", \2) ->> =\1+"·"+\2[1:].rstrip(")")           && Écriture épicène. Utilisez un point médian.

TEST: je suis {{déconsidéré.e}} par ma hiérarchie.                      ->> déconsidéré·e
TEST: il faut en parler à l’{{auteur(e)}} et à son agent.               ->> auteur·e
TEST: le ou la {{patron/ne}}                                            ->> patron·ne
TEST: Totalement {{con(ne)}}                                            ->> con·ne
TEST: un ou une {{intellectuel.le}}                                     ->> intellectuel·le
TEST: {{un/e}} immortel·le                                              ->> un·e|un ou une|une ou un
TEST: UN OU UNE INTELLECTUEL·LE
TEST: un ou une électricien·ne
TEST: femme ou homme épuisé·e
TEST: un·e idiot·e


__[i](typo_écriture_invariable)__
    ({w_3})([-·–—.•⋅/]s|[(]s[)])  @@0,$
        <<- ~>> =normalizeInclusiveWriting(\0)
        <<- option("typo") and option("eepi") and not \0.endswith("·s") and not (\0.endswith("/s") and morph(\1, ";S"))
        ->> \1·s                                                                                    && Écriture invariable. Utilisez un point médian.

TEST: la ou les {{fille(s)}}                                            ->> fille·s
TEST: le ou les patron·s
TEST: combien de rad/s



!!
!!
!!!! Majuscules manquantes                                                                        !!
!!
!!
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
TEST: __ocr__ il le jura sur {{1a}} tête de sa mère
TEST: __ocr__ {{1c}} chat du voinsin est idiot
TEST: __ocr__ {{[e}} chien a faim


__[i]/conf(conf_1e_1a_1es)__
    [1[\]][ea]s?
        <<- \0.endswith("e") and (morph(word(1), ":(?:N.*:[me]:[si]|V)", ":G") or morph(word(-1), ">ne/")) ->> le       && Erreur de frappe ?
        <<- \0.endswith("a") and (morph(word(1), ":(?:N.*:[fe]:[si]|V)", ":G") or morph(word(-1), ">ne/")) ->> la       && Erreur de frappe ?
        <<- \0.endswith("es") and (morph(word(1), ":(?:N.*:[pi]|V)", ":G") or morph(word(-1), ">ne/")) ->> les          && Erreur de frappe ?

TEST: {{1e}} marginal                                           ->> le
TEST: {{1a}} venue des problèmes                                ->> la
TEST: {{1es}} enfants sont au lit                               ->> les
TEST: Je… ne {{1e}}… crois pas…









|
|
|







1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
TEST: __ocr__ il le jura sur {{1a}} tête de sa mère
TEST: __ocr__ {{1c}} chat du voinsin est idiot
TEST: __ocr__ {{[e}} chien a faim


__[i]/conf(conf_1e_1a_1es)__
    [1[\]][ea]s?
        <<- \0.endswith("e") and (morph(word(1), ":(?:[NA].*:[me]:[si]|V)", ":G") or morph(word(-1), ">ne/")) ->> le       && Erreur de frappe ?
        <<- \0.endswith("a") and (morph(word(1), ":(?:[NA].*:[fe]:[si]|V)", ":G") or morph(word(-1), ">ne/")) ->> la       && Erreur de frappe ?
        <<- \0.endswith("es") and (morph(word(1), ":(?:[NA].*:[pi]|V)", ":G") or morph(word(-1), ">ne/")) ->> les          && Erreur de frappe ?

TEST: {{1e}} marginal                                           ->> le
TEST: {{1a}} venue des problèmes                                ->> la
TEST: {{1es}} enfants sont au lit                               ->> les
TEST: Je… ne {{1e}}… crois pas…


1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
__[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
TEST: {{3O}} (chiffre avec un O).                                         ->> 30


!!!! Écritures épicènes invariables                                                               !!

__[i](d_eepi_écriture_épicène_pluriel)__
    ({w_1}[éuitsrn])_(?:[nt]|)e_s  @@0
        <<- morph(\1, ":[NAQ]", ":G") =>> define(\1, ":N:A:Q:e:p")

__[i](d_eepi_écriture_épicène_singulier)__
    ({w_2}[éuitsrn])_e  @@0
        <<- morph(\1, ":[NAQ]") =>> define(\1, ":N:A:Q:e:s")


!!!! Purge des références aux notes                                                               !!

# les références aux notes
__<s>(p_exposants)__
    [¹²³⁴⁵⁶⁷⁸⁹⁰]+
        <<- ~>> *







<
<
<
<
<
<
<
<
<
<







1606
1607
1608
1609
1610
1611
1612










1613
1614
1615
1616
1617
1618
1619
__[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
TEST: {{3O}} (chiffre avec un O).                                         ->> 30













!!!! Purge des références aux notes                                                               !!

# les références aux notes
__<s>(p_exposants)__
    [¹²³⁴⁵⁶⁷⁸⁹⁰]+
        <<- ~>> *
2387
2388
2389
2390
2391
2392
2393











































2394
2395
2396
2397
2398
2399
2400
        <<- ~2:0>> ␣
        <<- =>> define(\2, ":MP:e:s")

    ~^[A-ZÀÂÉÈÊÎÔ]. Airways
        <<- ~>> ␣
        <<- =>> define(\2, ":MP:e:i")













































__immunités__
    il y a
    il n’ y a
        <<- !-1>>

    à l’ arrache







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
        <<- ~2:0>> ␣
        <<- =>> define(\2, ":MP:e:s")

    ~^[A-ZÀÂÉÈÊÎÔ]. Airways
        <<- ~>> ␣
        <<- =>> define(\2, ":MP:e:i")


__écritures_épicènes_invariables__
    [tous|tou]  ·  tes
    [tous|tou]  ·  te  ·  s
        <<- ~>> ␣

    c · [eu|eux]  ·  [elles|celles]
    [ceu|ceux]  ·  [elles|celles]
        <<- ~>> ␣

    *WORD  ·  e  ·  s
    *WORD  ·  [ce|rice|drice|price|trice]   ·  s
    *WORD  ·  [fe|ffe] ·  s
    *WORD  ·  [le|ale|bale|cale|dale|male|nale|pale|tale]  ·  s
    *WORD  ·  [ne|ane|ène|ine|nne|enne]  ·  s
    *WORD  ·  [ire|ière|ère|re]  ·  s
    *WORD  ·  [se|euse|ieuse|deuse|peuse|teuse]  ·  s
    *WORD  ·  [eresse|oresse] ·  s
    *WORD  ·  [ve|ive|dive|sive|tive]  ·  s
    *WORD  ·  [te|ate|ète|ite|tte] ·  s
    *WORD  ·  es
    *WORD  ·  [ces|rices|drices|prices|trices]
    *WORD  ·  [fes|ffes]
    *WORD  ·  [les|ales|bales|cales|dales|males|nales|pales|tales]
    *WORD  ·  [nes|anes|ènes|ines|nnes|ennes]
    *WORD  ·  [res|ires|ières|ères]
    *WORD  ·  [ses|euses|ieuses|deuses|peuses|teuses]
    *WORD  ·  [eresses|oresses]
    *WORD  ·  [ves|ives|dives|sives|tives]
    *WORD  ·  [tes|ates|ètes|ites|ttes]
        <<- ~>> ␣
        <<- morph(\1, ":[NAQ]", ":G") =>> define(\1, ":N:A:Q:e:p")

    *WORD  ·  [e|fe|le|ne|se|te]
        <<- not value(>1, "|·|") >>>
        <<- ~>> ␣
        <<- morph(\1, ":[NAQ]", ":G") =>> define(\1, ":N:A:Q:e:s")

    *WORD  ·  s
        <<- not value(<1, "|·|") >>>
        <<- ~>> ␣
        <<- morph(\1, ":[NAQ]", ":G") =>> define(\1, ":N:A:Q:e:p")


__immunités__
    il y a
    il n’ y a
        <<- !-1>>

    à l’ arrache

Modified graphspell-js/spellchecker.js from [1483d1a455] to [d92500050c].

226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
        return aSpellErr;
    }

    // IBDAWG functions

    isValidToken (sToken) {
        // checks if sToken is valid (if there is hyphens in sToken, sToken is split, each part is checked)
        sToken = sToken.gl_trim("_");
        if (this.oMainDic.isValidToken(sToken)) {
            return true;
        }
        if (this.bCommunityDic && this.oCommunityDic.isValidToken(sToken)) {
            return true;
        }
        if (this.bPersonalDic && this.oPersonalDic.isValidToken(sToken)) {







<







226
227
228
229
230
231
232

233
234
235
236
237
238
239
        return aSpellErr;
    }

    // IBDAWG functions

    isValidToken (sToken) {
        // checks if sToken is valid (if there is hyphens in sToken, sToken is split, each part is checked)

        if (this.oMainDic.isValidToken(sToken)) {
            return true;
        }
        if (this.bCommunityDic && this.oCommunityDic.isValidToken(sToken)) {
            return true;
        }
        if (this.bPersonalDic && this.oPersonalDic.isValidToken(sToken)) {
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
            return true;
        }
        return false;
    }

    getMorph (sWord) {
        // retrieves morphologies list, different casing allowed
        sWord = sWord.gl_trim("_");
        if (this.bStorage && this._dMorphologies.has(sWord)) {
            return this._dMorphologies.get(sWord);
        }
        let lMorph = this.oMainDic.getMorph(sWord);
        if (this.bCommunityDic) {
            lMorph.push(...this.oCommunityDic.getMorph(sWord));
        }
        if (this.bPersonalDic) {
            lMorph.push(...this.oPersonalDic.getMorph(sWord));
        }
        if (this.bStorage) {
            this._dMorphologies.set(sWord, lMorph);
            this._dLemmas.set(sWord, Array.from(new Set(this.getMorph(sWord).map((sMorph) => { return sMorph.slice(1, sMorph.indexOf("/")); }))));
            //console.log(sWord, this._dLemmas.get(sWord));
        }
        return lMorph;
    }

    getLemma (sWord) {
        // retrieves lemmas
        sWord = sWord.gl_trim("_");
        if (this.bStorage) {
            if (!this._dLemmas.has(sWord)) {
                this.getMorph(sWord);
            }
            return this._dLemmas.get(sWord);
        }
        return Array.from(new Set(this.getMorph(sWord).map((sMorph) => { return sMorph.slice(1, sMorph.indexOf("/")); })));
    }

    * suggest (sWord, nSuggLimit=10) {
        // generator: returns 1, 2 or 3 lists of suggestions
        sWord = sWord.gl_trim("_");
        if (this.lexicographer) {
            if (this.lexicographer.dSugg.has(sWord)) {
                yield this.lexicographer.dSugg.get(sWord).split("|");
            } else if (sWord.gl_isTitle() && this.lexicographer.dSugg.has(sWord.toLowerCase())) {
                let lRes = this.lexicographer.dSugg.get(sWord.toLowerCase()).split("|");
                yield lRes.map((sSugg) => { return sSugg.slice(0,1).toUpperCase() + sSugg.slice(1); });
            } else {







<




















<











<







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
            return true;
        }
        return false;
    }

    getMorph (sWord) {
        // retrieves morphologies list, different casing allowed

        if (this.bStorage && this._dMorphologies.has(sWord)) {
            return this._dMorphologies.get(sWord);
        }
        let lMorph = this.oMainDic.getMorph(sWord);
        if (this.bCommunityDic) {
            lMorph.push(...this.oCommunityDic.getMorph(sWord));
        }
        if (this.bPersonalDic) {
            lMorph.push(...this.oPersonalDic.getMorph(sWord));
        }
        if (this.bStorage) {
            this._dMorphologies.set(sWord, lMorph);
            this._dLemmas.set(sWord, Array.from(new Set(this.getMorph(sWord).map((sMorph) => { return sMorph.slice(1, sMorph.indexOf("/")); }))));
            //console.log(sWord, this._dLemmas.get(sWord));
        }
        return lMorph;
    }

    getLemma (sWord) {
        // retrieves lemmas

        if (this.bStorage) {
            if (!this._dLemmas.has(sWord)) {
                this.getMorph(sWord);
            }
            return this._dLemmas.get(sWord);
        }
        return Array.from(new Set(this.getMorph(sWord).map((sMorph) => { return sMorph.slice(1, sMorph.indexOf("/")); })));
    }

    * suggest (sWord, nSuggLimit=10) {
        // generator: returns 1, 2 or 3 lists of suggestions

        if (this.lexicographer) {
            if (this.lexicographer.dSugg.has(sWord)) {
                yield this.lexicographer.dSugg.get(sWord).split("|");
            } else if (sWord.gl_isTitle() && this.lexicographer.dSugg.has(sWord.toLowerCase())) {
                let lRes = this.lexicographer.dSugg.get(sWord.toLowerCase()).split("|");
                yield lRes.map((sSugg) => { return sSugg.slice(0,1).toUpperCase() + sSugg.slice(1); });
            } else {

Modified graphspell-js/tokenizer.js from [2ede633a83] to [4d88fd06ec].

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
            [/^[#@][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-st_-]+/, 'TAG'],
            [/^<[a-zA-Z]+.*?>|^<\/[a-zA-Z]+ *>/, 'HTML'],
            [/^\[\/?[a-zA-Z]+\]/, 'PSEUDOHTML'],
            [/^&\w+;(?:\w+;|)/, 'HTMLENTITY'],
            [/^\d\d?[h:]\d\d(?:[m:]\d\ds?|)\b/, 'HOUR'],
            [/^\d+(?:[.,]\d+|)/, 'NUM'],
            [/^[&%‰€$+±=*/<>⩾⩽#|×¥£§¢¬÷@-]/, 'SIGN'],
            [/^[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-stᴀ-ᶿ_]+(?:[’'`-][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-stᴀ-ᶿ_]+)*/, 'WORD'],
            [/^\S/, 'OTHER']
        ],
    "fr":
        [
            [/^[   \t]+/, 'SPACE'],
            [/^\/(?:~|bin|boot|dev|etc|home|lib|mnt|opt|root|sbin|tmp|usr|var|Bureau|Documents|Images|Musique|Public|Téléchargements|Vidéos)(?:\/[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-st_.()-]+)*/, 'FOLDERUNIX'],
            [/^[a-zA-Z]:\\(?:Program Files(?: \(x86\)|)|[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-st.()]+)(?:\\[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-st_.()-]+)*/, 'FOLDERWIN'],
            [/^[,.;:!?…«»“”‘’"(){}\[\]·–—¿¡]/, 'PUNC'],
            [/^[A-Z][.][A-Z][.](?:[A-Z][.])*/, 'WORD_ACRONYM'],
            [/^(?:https?:\/\/|www[.]|[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-st_-]+[@.][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-st_-]{2,}[@.])[a-zA-Z0-9][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-st_.\/?&!%=+*"'@$#-]+/, 'LINK'],
            [/^[#@][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-st_-]+/, 'TAG'],
            [/^<[a-zA-Z]+.*?>|^<\/[a-zA-Z]+ *>/, 'HTML'],
            [/^\[\/?[a-zA-Z]+\]/, 'PSEUDOHTML'],
            [/^&\w+;(?:\w+;|)/, 'HTMLENTITY'],
            [/^(?:l|d|n|m|t|s|j|c|ç|lorsqu|puisqu|jusqu|quoiqu|qu|presqu|quelqu)['’ʼ‘‛´`′‵՚ꞌꞋ]/i, 'WORD_ELIDED'],
            [/^\d\d?[h:]\d\d(?:[m:]\d\ds?|)\b/, 'HOUR'],
            [/^\d+(?:ers?\b|res?\b|è[rm]es?\b|i[èe][mr]es?\b|de?s?\b|nde?s?\b|ès?\b|es?\b|ᵉʳˢ?|ʳᵉˢ?|ᵈᵉ?ˢ?|ⁿᵈᵉ?ˢ?|ᵉˢ?)/, 'WORD_ORDINAL'],
            [/^\d+(?:[.,]\d+|)/, 'NUM'],
            [/^[&%‰€$+±=*/<>⩾⩽#|×¥£§¢¬÷@-]/, 'SIGN'],
            [/^[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-stᴀ-ᶿ\u0300-\u036fᵉʳˢⁿᵈ_]+(?:[’'`-][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-stᴀ-ᶿ\u0300-\u036fᵉʳˢⁿᵈ_]+)*/, 'WORD'],
            [/^\S/, 'OTHER'],
        ]
};


class Tokenizer {








|



















|







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
            [/^[#@][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-st_-]+/, 'TAG'],
            [/^<[a-zA-Z]+.*?>|^<\/[a-zA-Z]+ *>/, 'HTML'],
            [/^\[\/?[a-zA-Z]+\]/, 'PSEUDOHTML'],
            [/^&\w+;(?:\w+;|)/, 'HTMLENTITY'],
            [/^\d\d?[h:]\d\d(?:[m:]\d\ds?|)\b/, 'HOUR'],
            [/^\d+(?:[.,]\d+|)/, 'NUM'],
            [/^[&%‰€$+±=*/<>⩾⩽#|×¥£§¢¬÷@-]/, 'SIGN'],
            [/^[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-stᴀ-ᶿ\u0300-\u036fᵉʳˢⁿᵈ]+(?:[’'`-][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-stᴀ-ᶿ\u0300-\u036fᵉʳˢⁿᵈ]+)*/, 'WORD'],
            [/^\S/, 'OTHER']
        ],
    "fr":
        [
            [/^[   \t]+/, 'SPACE'],
            [/^\/(?:~|bin|boot|dev|etc|home|lib|mnt|opt|root|sbin|tmp|usr|var|Bureau|Documents|Images|Musique|Public|Téléchargements|Vidéos)(?:\/[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-st_.()-]+)*/, 'FOLDERUNIX'],
            [/^[a-zA-Z]:\\(?:Program Files(?: \(x86\)|)|[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-st.()]+)(?:\\[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-st_.()-]+)*/, 'FOLDERWIN'],
            [/^[,.;:!?…«»“”‘’"(){}\[\]·–—¿¡]/, 'PUNC'],
            [/^[A-Z][.][A-Z][.](?:[A-Z][.])*/, 'WORD_ACRONYM'],
            [/^(?:https?:\/\/|www[.]|[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-st_-]+[@.][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-st_-]{2,}[@.])[a-zA-Z0-9][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-st_.\/?&!%=+*"'@$#-]+/, 'LINK'],
            [/^[#@][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-st_-]+/, 'TAG'],
            [/^<[a-zA-Z]+.*?>|^<\/[a-zA-Z]+ *>/, 'HTML'],
            [/^\[\/?[a-zA-Z]+\]/, 'PSEUDOHTML'],
            [/^&\w+;(?:\w+;|)/, 'HTMLENTITY'],
            [/^(?:l|d|n|m|t|s|j|c|ç|lorsqu|puisqu|jusqu|quoiqu|qu|presqu|quelqu)['’ʼ‘‛´`′‵՚ꞌꞋ]/i, 'WORD_ELIDED'],
            [/^\d\d?[h:]\d\d(?:[m:]\d\ds?|)\b/, 'HOUR'],
            [/^\d+(?:ers?\b|res?\b|è[rm]es?\b|i[èe][mr]es?\b|de?s?\b|nde?s?\b|ès?\b|es?\b|ᵉʳˢ?|ʳᵉˢ?|ᵈᵉ?ˢ?|ⁿᵈᵉ?ˢ?|ᵉˢ?)/, 'WORD_ORDINAL'],
            [/^\d+(?:[.,]\d+|)/, 'NUM'],
            [/^[&%‰€$+±=*/<>⩾⩽#|×¥£§¢¬÷@-]/, 'SIGN'],
            [/^[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-stᴀ-ᶿ\u0300-\u036fᵉʳˢⁿᵈ]+(?:[’'`-][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯff-stᴀ-ᶿ\u0300-\u036fᵉʳˢⁿᵈ]+)*/, 'WORD'],
            [/^\S/, 'OTHER'],
        ]
};


class Tokenizer {

Modified graphspell/spellchecker.py from [4dd679e9ae] to [3d385eb49e].

209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
        return dWord


    # IBDAWG functions

    def isValidToken (self, sToken):
        "checks if sToken is valid (if there is hyphens in sToken, sToken is split, each part is checked)"
        sToken = sToken.strip("_")
        if self.oMainDic.isValidToken(sToken):
            return True
        if self.bCommunityDic and self.oCommunityDic.isValidToken(sToken):
            return True
        if self.bPersonalDic and self.oPersonalDic.isValidToken(sToken):
            return True
        return False







<







209
210
211
212
213
214
215

216
217
218
219
220
221
222
        return dWord


    # IBDAWG functions

    def isValidToken (self, sToken):
        "checks if sToken is valid (if there is hyphens in sToken, sToken is split, each part is checked)"

        if self.oMainDic.isValidToken(sToken):
            return True
        if self.bCommunityDic and self.oCommunityDic.isValidToken(sToken):
            return True
        if self.bPersonalDic and self.oPersonalDic.isValidToken(sToken):
            return True
        return False
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
            return True
        if self.bPersonalDic and self.oPersonalDic.lookup(sWord):
            return True
        return False

    def getMorph (self, sWord):
        "retrieves morphologies list, different casing allowed"
        sWord = sWord.strip("_")
        if self.bStorage and sWord in self._dMorphologies:
            return self._dMorphologies[sWord]
        lMorph = self.oMainDic.getMorph(sWord)
        if self.bCommunityDic:
            lMorph.extend(self.oCommunityDic.getMorph(sWord))
        if self.bPersonalDic:
            lMorph.extend(self.oPersonalDic.getMorph(sWord))
        if self.bStorage:
            self._dMorphologies[sWord] = lMorph
            self._dLemmas[sWord] = { s[1:s.find("/")]  for s in lMorph }
        return lMorph

    def getLemma (self, sWord):
        "retrieves lemmas"
        sWord = sWord.strip("_")
        if self.bStorage:
            if sWord not in self._dLemmas:
                self.getMorph(sWord)
            return self._dLemmas[sWord]
        return { s[1:s.find("/")]  for s in self.getMorph(sWord) }

    def suggest (self, sWord, nSuggLimit=10):
        "generator: returns 1, 2 or 3 lists of suggestions"
        sWord = sWord.strip("_")
        if self.lexicographer:
            if sWord in self.lexicographer.dSugg:
                yield self.lexicographer.dSugg[sWord].split("|")
            elif sWord.istitle() and sWord.lower() in self.lexicographer.dSugg:
                lRes = self.lexicographer.dSugg[sWord.lower()].split("|")
                yield list(map(lambda sSugg: sSugg[0:1].upper()+sSugg[1:], lRes))
            else:







<














<








<







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
            return True
        if self.bPersonalDic and self.oPersonalDic.lookup(sWord):
            return True
        return False

    def getMorph (self, sWord):
        "retrieves morphologies list, different casing allowed"

        if self.bStorage and sWord in self._dMorphologies:
            return self._dMorphologies[sWord]
        lMorph = self.oMainDic.getMorph(sWord)
        if self.bCommunityDic:
            lMorph.extend(self.oCommunityDic.getMorph(sWord))
        if self.bPersonalDic:
            lMorph.extend(self.oPersonalDic.getMorph(sWord))
        if self.bStorage:
            self._dMorphologies[sWord] = lMorph
            self._dLemmas[sWord] = { s[1:s.find("/")]  for s in lMorph }
        return lMorph

    def getLemma (self, sWord):
        "retrieves lemmas"

        if self.bStorage:
            if sWord not in self._dLemmas:
                self.getMorph(sWord)
            return self._dLemmas[sWord]
        return { s[1:s.find("/")]  for s in self.getMorph(sWord) }

    def suggest (self, sWord, nSuggLimit=10):
        "generator: returns 1, 2 or 3 lists of suggestions"

        if self.lexicographer:
            if sWord in self.lexicographer.dSugg:
                yield self.lexicographer.dSugg[sWord].split("|")
            elif sWord.istitle() and sWord.lower() in self.lexicographer.dSugg:
                lRes = self.lexicographer.dSugg[sWord.lower()].split("|")
                yield list(map(lambda sSugg: sSugg[0:1].upper()+sSugg[1:], lRes))
            else:

Modified graphspell/tokenizer.py from [5243432861] to [3a068b8368].

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
            r'(?P<LINK>(?:https?://|www[.]|\w+[@.]\w\w+[@.])\w[\w./?&!%=+*"\'@$#-]+)',
            r'(?P<HASHTAG>[#@][\w-]+)',
            r'(?P<HTML><\w+.*?>|</\w+ *>)',
            r'(?P<PSEUDOHTML>\[/?\w+\])',
            r'(?P<HOUR>\d\d?[h:]\d\d(?:[m:]\d\ds?|)\b)',
            r'(?P<NUM>\d+(?:[.,]\d+))',
            r'(?P<SIGN>[&%‰€$+±=*/<>⩾⩽#|×¥£§¢¬÷@-])',
            r"(?P<WORD>[\w\u0300-\u036f]+(?:[’'`-][\w\u0300-\u036f]+)*)",        # with combining diacritics
            r"(?P<OTHER>\S)"
        ),
    "fr":
        (
            r'(?P<FOLDERUNIX>/(?:bin|boot|dev|etc|home|lib|mnt|opt|root|sbin|tmp|usr|var|Bureau|Documents|Images|Musique|Public|Téléchargements|Vidéos)(?:/[\w.()-]+)*)',
            r'(?P<FOLDERWIN>[a-zA-Z]:\\(?:Program Files(?: [(]x86[)]|)|[\w.()]+)(?:\\[\w.()-]+)*)',
            r'(?P<PUNC>[][,.;:!?…«»“”‘’"(){}·–—¿¡])',
            r'(?P<WORD_ACRONYM>[A-Z][.][A-Z][.](?:[A-Z][.])*)',
            r'(?P<LINK>(?:https?://|www[.]|\w+[@.]\w\w+[@.])\w[\w./?&!%=+*"\'@$#-]+)',
            r'(?P<HASHTAG>[#@][\w-]+)',
            r'(?P<HTML><\w+.*?>|</\w+ *>)',
            r'(?P<PSEUDOHTML>\[/?\w+\])',
            r"(?P<WORD_ELIDED>(?:l|d|n|m|t|s|j|c|ç|lorsqu|puisqu|jusqu|quoiqu|qu|presqu|quelqu)['’ʼ‘‛´`′‵՚ꞌꞋ])",
            r'(?P<WORD_ORDINAL>\d+(?:ers?|res?|è[rm]es?|i[èe][mr]es?|de?s?|nde?s?|ès?|es?|ᵉʳˢ?|ʳᵉˢ?|ᵈᵉ?ˢ?|ⁿᵈᵉ?ˢ?|ᵉˢ?)\b)',
            r'(?P<HOUR>\d\d?[h:]\d\d(?:[m:]\d\ds?|)\b)',
            r'(?P<NUM>\d+(?:[.,]\d+|))',
            r'(?P<SIGN>[&%‰€$+±=*/<>⩾⩽#|×¥£¢§¬÷@-])',
            r"(?P<WORD>[\w\u0300-\u036f]+(?:[’'`-][\w\u0300-\u036f]+)*)",        # with combining diacritics
            r"(?P<OTHER>\S)"
        )
}


class Tokenizer:
    "Tokenizer: transforms a text in a list of tokens"







|

















|







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
            r'(?P<LINK>(?:https?://|www[.]|\w+[@.]\w\w+[@.])\w[\w./?&!%=+*"\'@$#-]+)',
            r'(?P<HASHTAG>[#@][\w-]+)',
            r'(?P<HTML><\w+.*?>|</\w+ *>)',
            r'(?P<PSEUDOHTML>\[/?\w+\])',
            r'(?P<HOUR>\d\d?[h:]\d\d(?:[m:]\d\ds?|)\b)',
            r'(?P<NUM>\d+(?:[.,]\d+))',
            r'(?P<SIGN>[&%‰€$+±=*/<>⩾⩽#|×¥£§¢¬÷@-])',
            r"(?P<WORD>(?:(?!_)[\w\u0300-\u036f])+(?:[’'`-](?:(?!_)[\w\u0300-\u036f])+)*)",        # with combining diacritics
            r"(?P<OTHER>\S)"
        ),
    "fr":
        (
            r'(?P<FOLDERUNIX>/(?:bin|boot|dev|etc|home|lib|mnt|opt|root|sbin|tmp|usr|var|Bureau|Documents|Images|Musique|Public|Téléchargements|Vidéos)(?:/[\w.()-]+)*)',
            r'(?P<FOLDERWIN>[a-zA-Z]:\\(?:Program Files(?: [(]x86[)]|)|[\w.()]+)(?:\\[\w.()-]+)*)',
            r'(?P<PUNC>[][,.;:!?…«»“”‘’"(){}·–—¿¡])',
            r'(?P<WORD_ACRONYM>[A-Z][.][A-Z][.](?:[A-Z][.])*)',
            r'(?P<LINK>(?:https?://|www[.]|\w+[@.]\w\w+[@.])\w[\w./?&!%=+*"\'@$#-]+)',
            r'(?P<HASHTAG>[#@][\w-]+)',
            r'(?P<HTML><\w+.*?>|</\w+ *>)',
            r'(?P<PSEUDOHTML>\[/?\w+\])',
            r"(?P<WORD_ELIDED>(?:l|d|n|m|t|s|j|c|ç|lorsqu|puisqu|jusqu|quoiqu|qu|presqu|quelqu)['’ʼ‘‛´`′‵՚ꞌꞋ])",
            r'(?P<WORD_ORDINAL>\d+(?:ers?|res?|è[rm]es?|i[èe][mr]es?|de?s?|nde?s?|ès?|es?|ᵉʳˢ?|ʳᵉˢ?|ᵈᵉ?ˢ?|ⁿᵈᵉ?ˢ?|ᵉˢ?)\b)',
            r'(?P<HOUR>\d\d?[h:]\d\d(?:[m:]\d\ds?|)\b)',
            r'(?P<NUM>\d+(?:[.,]\d+|))',
            r'(?P<SIGN>[&%‰€$+±=*/<>⩾⩽#|×¥£¢§¬÷@-])',
            r"(?P<WORD>(?:(?!_)[\w\u0300-\u036f])+(?:[’'`-](?:(?!_)[\w\u0300-\u036f])+)*)",        # with combining diacritics
            r"(?P<OTHER>\S)"
        )
}


class Tokenizer:
    "Tokenizer: transforms a text in a list of tokens"