Grammalecte  Artifact [94bb3a1779]

Artifact 94bb3a17798a0a6a19fe39e3fad4191b677841ac074554b508e4f3c63903585c:


// JavaScript

"use strict";


${string}
${map}


//// Default Suggestions

const _dSugg = new Map ([
    ["bcp", "beaucoup"],
    ["ca", "ça"],
    ["cad", "c’est-à-dire"],
    ["cb", "combien|CB"],
    ["cdlt", "cordialement"],
    ["construirent", "construire|construisirent|construisent|construiront"],
    ["càd", "c’est-à-dire"],
    ["chai", "j’sais|je sais"],
    ["chais", "j’sais|je sais"],
    ["chui", "j’suis|je suis"],
    ["chuis", "j’suis|je suis"],
    ["dc", "de|donc"],
    ["done", "donc|donne"],
    ["email", "courriel|e-mail|émail"],
    ["emails", "courriels|e-mails"],
    ["ete", "êtes|été"],
    ["Etes-vous", "Êtes-vous"],
    ["Etiez-vous", "Étiez-vous"],
    ["Etions-vous", "Étions-nous"],
    ["loins", "loin"],
    ["mn", "min"],
    ["mns", "min"],
    ["online", "en ligne"],
    ["parce-que", "parce que"],
    ["pcq", "parce que"],
    ["pd", "pendant|pédé"],
    ["pdq", "pendant que"],
    ["pdt", "pendant"],
    ["pdtq", "pendant que"],
    ["pécunier", "pécuniaire"],
    ["pécuniers", "pécuniaires"],
    ["pk", "pourquoi"],
    ["pkoi", "pourquoi"],
    ["pq", "pourquoi|PQ"],
    ["prq", "presque"],
    ["prsq", "presque"],
    ["qcq", "quiconque"],
    ["qd", "quand"],
    ["qq", "quelque"],
    ["qqch", "quelque chose"],
    ["qqn", "quelqu’un"],
    ["qqne", "quelqu’une"],
    ["qqs", "quelques"],
    ["qqunes", "quelques-unes"],
    ["qquns", "quelques-uns"],
    ["tdq", "tandis que"],
    ["tj", "toujours"],
    ["tjs", "toujours"],
    ["tq", "tant que|tandis que"],
    ["ts", "tous"],
    ["tt", "tant|tout"],
    ["tte", "toute"],
    ["ttes", "toutes"],

    ["Iier", "Iᵉʳ"],
    ["Iière", "Iʳᵉ"],
    ["IIième", "IIᵉ"],
    ["IIIième", "IIIᵉ"],
    ["IVième", "IVᵉ"],
    ["Vième", "Vᵉ"],
    ["VIième", "VIᵉ"],
    ["VIIième", "VIIᵉ"],
    ["VIIIième", "VIIIᵉ"],
    ["IXième", "IXᵉ"],
    ["Xième", "Xᵉ"],
    ["XIième", "XIᵉ"],
    ["XIIième", "XIIᵉ"],
    ["XIIIième", "XIIIᵉ"],
    ["XIVième", "XIVᵉ"],
    ["XVième", "XVᵉ"],
    ["XVIième", "XVIᵉ"],
    ["XVIIième", "XVIIᵉ"],
    ["XVIIIième", "XVIIIᵉ"],
    ["XIXième", "XIXᵉ"],
    ["XXième", "XXᵉ"],
    ["XXIième", "XXIᵉ"],
    ["XXIIième", "XXIIᵉ"],
    ["XXIIIième", "XXIIIᵉ"],
    ["XXIVième", "XXIVᵉ"],
    ["XXVième", "XXVᵉ"],
    ["XXVIième", "XXVIᵉ"],
    ["XXVIIième", "XXVIIᵉ"],
    ["XXVIIIième", "XXVIIIᵉ"],
    ["XXIXième", "XXIXᵉ"],
    ["XXXième", "XXXᵉ"],

    ["Ier", "Iᵉʳ"],
    ["Ière", "Iʳᵉ"],
    ["IIème", "IIᵉ"],
    ["IIIème", "IIIᵉ"],
    ["IVème", "IVᵉ"],
    ["Vème", "Vᵉ"],
    ["VIème", "VIᵉ"],
    ["VIIème", "VIIᵉ"],
    ["VIIIème", "VIIIᵉ"],
    ["IXème", "IXᵉ"],
    ["Xème", "Xᵉ"],
    ["XIème", "XIᵉ"],
    ["XIIème", "XIIᵉ"],
    ["XIIIème", "XIIIᵉ"],
    ["XIVème", "XIVᵉ"],
    ["XVème", "XVᵉ"],
    ["XVIème", "XVIᵉ"],
    ["XVIIème", "XVIIᵉ"],
    ["XVIIIème", "XVIIIᵉ"],
    ["XIXème", "XIXᵉ"],
    ["XXème", "XXᵉ"],
    ["XXIème", "XXIᵉ"],
    ["XXIIème", "XXIIᵉ"],
    ["XXIIIème", "XXIIIᵉ"],
    ["XXIVème", "XXIVᵉ"],
    ["XXVème", "XXVᵉ"],
    ["XXVIème", "XXVIᵉ"],
    ["XXVIIème", "XXVIIᵉ"],
    ["XXVIIIème", "XXVIIIᵉ"],
    ["XXIXème", "XXIXᵉ"],
    ["XXXème", "XXXᵉ"]
]);



//// Lexicographer

var lexgraph_fr = {

    dSugg: _dSugg,

    // Préfixes et suffixes
    aPfx1: new Set([
        "anti", "archi", "contre", "hyper", "mé", "méta", "im", "in", "ir", "par", "proto",
        "pseudo", "pré", "re", "ré", "sans", "sous", "supra", "sur", "ultra"
    ]),

    aPfx2: new Set([
        "belgo", "franco", "génito", "gynéco", "médico", "russo"
    ]),

    // Étiquettes
    dTag: new Map([
            [':N', [" nom,", "Nom"]],
            [':A', [" adjectif,", "Adjectif"]],
            [':M1', [" prénom,", "Prénom"]],
            [':M2', [" patronyme,", "Patronyme, matronyme, nom de famille…"]],
            [':MP', [" nom propre,", "Nom propre"]],
            [':W', [" adverbe,", "Adverbe"]],
            [':J', [" interjection,", "Interjection"]],
            [':B', [" nombre,", "Nombre"]],
            [':T', [" titre,", "Titre de civilité"]],

            [':e', [" épicène", "épicène"]],
            [':m', [" masculin", "masculin"]],
            [':f', [" féminin", "féminin"]],
            [':s', [" singulier", "singulier"]],
            [':p', [" pluriel", "pluriel"]],
            [':i', [" invariable", "invariable"]],

            [':V1_', [" verbe (1ᵉʳ gr.),", "Verbe du 1ᵉʳ groupe"]],
            [':V2_', [" verbe (2ᵉ gr.),", "Verbe du 2ᵉ groupe"]],
            [':V3_', [" verbe (3ᵉ gr.),", "Verbe du 3ᵉ groupe"]],
            [':V1e', [" verbe (1ᵉʳ gr.),", "Verbe du 1ᵉʳ groupe"]],
            [':V2e', [" verbe (2ᵉ gr.),", "Verbe du 2ᵉ groupe"]],
            [':V3e', [" verbe (3ᵉ gr.),", "Verbe du 3ᵉ groupe"]],
            [':V0e', [" verbe,", "Verbe auxiliaire être"]],
            [':V0a', [" verbe,", "Verbe auxiliaire avoir"]],

            [':Y', [" infinitif,", "infinitif"]],
            [':P', [" participe présent,", "participe présent"]],
            [':Q', [" participe passé,", "participe passé"]],
            [':Ip', [" présent,", "indicatif présent"]],
            [':Iq', [" imparfait,", "indicatif imparfait"]],
            [':Is', [" passé simple,", "indicatif passé simple"]],
            [':If', [" futur,", "indicatif futur"]],
            [':K', [" conditionnel présent,", "conditionnel présent"]],
            [':Sp', [" subjonctif présent,", "subjonctif présent"]],
            [':Sq', [" subjonctif imparfait,", "subjonctif imparfait"]],
            [':E', [" impératif,", "impératif"]],

            [':1s', [" 1ʳᵉ p. sg.,", "verbe : 1ʳᵉ personne du singulier"]],
            [':1ŝ', [" présent interr. 1ʳᵉ p. sg.,", "verbe : 1ʳᵉ personne du singulier (présent interrogatif)"]],
            [':1ś', [" présent interr. 1ʳᵉ p. sg.,", "verbe : 1ʳᵉ personne du singulier (présent interrogatif)"]],
            [':2s', [" 2ᵉ p. sg.,", "verbe : 2ᵉ personne du singulier"]],
            [':3s', [" 3ᵉ p. sg.,", "verbe : 3ᵉ personne du singulier"]],
            [':1p', [" 1ʳᵉ p. pl.,", "verbe : 1ʳᵉ personne du pluriel"]],
            [':2p', [" 2ᵉ p. pl.,", "verbe : 2ᵉ personne du pluriel"]],
            [':3p', [" 3ᵉ p. pl.,", "verbe : 3ᵉ personne du pluriel"]],
            [':3p!', [" 3ᵉ p. pl.,", "verbe : 3ᵉ personne du pluriel (prononciation distinctive)"]],

            [':G', ["[mot grammatical]", "Mot grammatical"]],
            [':X', [" adverbe de négation,", "Adverbe de négation"]],
            [':U', [" adverbe interrogatif,", "Adverbe interrogatif"]],
            [':R', [" préposition,", "Préposition"]],
            [':Rv', [" préposition verbale,", "Préposition verbale"]],
            [':D', [" déterminant,", "Déterminant"]],
            [':Dd', [" déterminant démonstratif,", "Déterminant démonstratif"]],
            [':De', [" déterminant exclamatif,", "Déterminant exclamatif"]],
            [':Dp', [" déterminant possessif,", "Déterminant possessif"]],
            [':Di', [" déterminant indéfini,", "Déterminant indéfini"]],
            [':Dn', [" déterminant négatif,", "Déterminant négatif"]],
            [':Od', [" pronom démonstratif,", "Pronom démonstratif"]],
            [':Oi', [" pronom indéfini,", "Pronom indéfini"]],
            [':On', [" pronom indéfini négatif,", "Pronom indéfini négatif"]],
            [':Ot', [" pronom interrogatif,", "Pronom interrogatif"]],
            [':Or', [" pronom relatif,", "Pronom relatif"]],
            [':Ow', [" pronom adverbial,", "Pronom adverbial"]],
            [':Os', [" pronom personnel sujet,", "Pronom personnel sujet"]],
            [':Oo', [" pronom personnel objet,", "Pronom personnel objet"]],
            [':Ov', [" préverbe,", "Préverbe"]],
            [':O1', [" 1ʳᵉ pers.,", "Pronom : 1ʳᵉ personne"]],
            [':O2', [" 2ᵉ pers.,", "Pronom : 2ᵉ personne"]],
            [':O3', [" 3ᵉ pers.,", "Pronom : 3ᵉ personne"]],
            [':C', [" conjonction,", "Conjonction"]],
            [':Cc', [" conjonction de coordination,", "Conjonction de coordination"]],
            [':Cs', [" conjonction de subordination,", "Conjonction de subordination"]],

            [':ÉC', [" élément de conjonction,", "Élément de conjonction"]],
            [':ÉCs', [" élément de conjonction de subordination,", "Élément de conjonction de subordination"]],
            [':ÉN', [" élément de locution nominale,", "Élément de locution nominale"]],
            [':ÉA', [" élément de locution adjectivale,", "Élément de locution adjectivale"]],
            [':ÉV', [" élément de locution verbale,", "Élément de locution verbale"]],
            [':ÉW', [" élément de locution adverbiale,", "Élément de locution adverbiale"]],
            [':ÉR', [" élément de locution prépositive,", "Élément de locution prépositive"]],
            [':ÉJ', [" élément de locution interjective,", "Élément de locution interjective"]],

            [':Zp', [" préfixe,", "Préfixe"]],
            [':Zs', [" suffixe,", "Suffixe"]],

            [':H', ["", "<Hors-norme, inclassable>"]],

            [':@',  ["", "<Caractère non alpha-numérique>"]],
            [':@p', ["signe de ponctuation", "Signe de ponctuation"]],
            [':@s', ["signe", "Signe divers"]],

            [';S', [" : symbole (unité de mesure)", "Symbole (unité de mesure)"]],

            ['/*', ["", "Sous-dictionnaire <Commun>"]],
            ['/C', [" <classique>", "Sous-dictionnaire <Classique>"]],
            ['/M', ["", "Sous-dictionnaire <Moderne>"]],
            ['/R', [" <réforme>", "Sous-dictionnaire <Réforme 1990>"]],
            ['/A', ["", "Sous-dictionnaire <Annexe>"]],
            ['/X', ["", "Sous-dictionnaire <Contributeurs>"]]
        ]),

    dLocTag: new Map([
            [':L', "locution"],
            [':LN', "locution nominale"],
            [':LA', "locution adjectivale"],
            [':LV', "locution verbale"],
            [':LW', "locution adverbiale"],
            [':LR', "locution prépositive"],
            [':LRv', "locution prépositive verbale"],
            [':LO', "locution pronominale"],
            [':LC', "locution conjonctive"],
            [':LJ', "locution interjective"],

            [':B', " cardinale"],
            [':e', " épicène"],
            [':m', " masculine"],
            [':f', " féminine"],
            [':s', " singulière"],
            [':p', " plurielle"],
            [':i', " invariable"],
            ['/L', " (latin)"]
        ]),

    dLocVerb: new Map([
            ['i', " intransitive"],
            ['n', " transitive indirecte"],
            ['t', " transitive directe"],
            ['p', " pronominale"],
            ['m', " impersonnelle"],
        ]),

    dValues: new Map([
            ['d’', "(de), préposition ou déterminant épicène invariable"],
            ['l’', "(le/la), déterminant ou pronom personnel objet, masculin/féminin singulier"],
            ['j’', "(je), pronom personnel sujet, 1ʳᵉ pers., épicène singulier"],
            ['m’', "(me), pronom personnel objet, 1ʳᵉ pers., épicène singulier"],
            ['t’', "(te), pronom personnel objet, 2ᵉ pers., épicène singulier"],
            ['s’', "(se), pronom personnel objet, 3ᵉ pers., épicène singulier/pluriel"],
            ['n’', "(ne), adverbe de négation"],
            ['c’', "(ce), pronom démonstratif, masculin singulier/pluriel"],
            ['ç’', "(ça), pronom démonstratif, masculin singulier"],
            ['qu', "(que), conjonction de subordination"],
            ['lorsqu’', "(lorsque), conjonction de subordination"],
            ['puisqu’', "(lorsque), conjonction de subordination"],
            ['quoiqu’', "(quoique), conjonction de subordination"],
            ['jusqu’', "(jusque), préposition"],

            ['-je', " pronom personnel sujet, 1ʳᵉ pers. sing."],
            ['-tu', " pronom personnel sujet, 2ᵉ pers. sing."],
            ['-il', " pronom personnel sujet, 3ᵉ pers. masc. sing."],
            ['-iel', " pronom personnel sujet, 3ᵉ pers. sing."],
            ['-on', " pronom personnel sujet, 3ᵉ pers. sing. ou plur."],
            ['-elle', " pronom personnel sujet, 3ᵉ pers. fém. sing."],
            ['-t-il', " “t” euphonique + pronom personnel sujet, 3ᵉ pers. masc. sing."],
            ['-t-on', " “t” euphonique + pronom personnel sujet, 3ᵉ pers. sing. ou plur."],
            ['-t-elle', " “t” euphonique + pronom personnel sujet, 3ᵉ pers. fém. sing."],
            ['-t-iel', " “t” euphonique + pronom personnel sujet, 3ᵉ pers. sing."],
            ['-nous', " pronom personnel sujet/objet, 1ʳᵉ pers. plur.  ou  COI (à nous), plur."],
            ['-vous', " pronom personnel sujet/objet, 2ᵉ pers. plur.  ou  COI (à vous), plur."],
            ['-ils', " pronom personnel sujet, 3ᵉ pers. masc. plur."],
            ['-elles', " pronom personnel sujet, 3ᵉ pers. masc. plur."],
            ['-iels', " pronom personnel sujet, 3ᵉ pers. plur."],

            ["-là", " particule démonstrative (là)"],
            ["-ci", " particule démonstrative (ci)"],

            ['-le', " COD, masc. sing."],
            ['-la', " COD, fém. sing."],
            ['-les', " COD, plur."],

            ['-moi', " COI (à moi), sing."],
            ['-toi', " COI (à toi), sing."],
            ['-lui', " COI (à lui ou à elle), sing."],
            ['-nous2', " COI (à nous), plur."],
            ['-vous2', " COI (à vous), plur."],
            ['-leur', " COI (à eux ou à elles), plur."],

            ['-le-moi', " COD, masc. sing. + COI (à moi), sing."],
            ['-le-toi', " COD, masc. sing. + COI (à toi), sing."],
            ['-le-lui', " COD, masc. sing. + COI (à lui ou à elle), sing."],
            ['-le-nous', " COD, masc. sing. + COI (à nous), plur."],
            ['-le-vous', " COD, masc. sing. + COI (à vous), plur."],
            ['-le-leur', " COD, masc. sing. + COI (à eux ou à elles), plur."],

            ['-la-moi', " COD, fém. sing. + COI (à moi), sing."],
            ['-la-toi', " COD, fém. sing. + COI (à toi), sing."],
            ['-la-lui', " COD, fém. sing. + COI (à lui ou à elle), sing."],
            ['-la-nous', " COD, fém. sing. + COI (à nous), plur."],
            ['-la-vous', " COD, fém. sing. + COI (à vous), plur."],
            ['-la-leur', " COD, fém. sing. + COI (à eux ou à elles), plur."],

            ['-les-moi', " COD, plur. + COI (à moi), sing."],
            ['-les-toi', " COD, plur. + COI (à toi), sing."],
            ['-les-lui', " COD, plur. + COI (à lui ou à elle), sing."],
            ['-les-nous', " COD, plur. + COI (à nous), plur."],
            ['-les-vous', " COD, plur. + COI (à vous), plur."],
            ['-les-leur', " COD, plur. + COI (à eux ou à elles), plur."],

            ['-y', " pronom adverbial"],
            ["-m’y", " (me) pronom personnel objet + (y) pronom adverbial"],
            ["-t’y", " (te) pronom personnel objet + (y) pronom adverbial"],
            ["-s’y", " (se) pronom personnel objet + (y) pronom adverbial"],

            ['-en', " pronom adverbial"],
            ["-m’en", " (me) pronom personnel objet + (en) pronom adverbial"],
            ["-t’en", " (te) pronom personnel objet + (en) pronom adverbial"],
            ["-s’en", " (se) pronom personnel objet + (en) pronom adverbial"],

            ['.', "point"],
            ['·', "point médian"],
            ['…', "points de suspension"],
            [':', "deux-points"],
            [';', "point-virgule"],
            [',', "virgule"],
            ['?', "point d’interrogation"],
            ['!', "point d’exclamation"],
            ['(', "parenthèse ouvrante"],
            [')', "parenthèse fermante"],
            ['[', "crochet ouvrant"],
            [']', "crochet fermant"],
            ['{', "accolade ouvrante"],
            ['}', "accolade fermante"],
            ['-', "tiret"],
            ['—', "tiret cadratin"],
            ['–', "tiret demi-cadratin"],
            ['«', "guillemet ouvrant (chevrons)"],
            ['»', "guillemet fermant (chevrons)"],
            ['“', "guillemet ouvrant double"],
            ['”', "guillemet fermant double"],
            ['‘', "guillemet ouvrant"],
            ['’', "guillemet fermant"],
            ['"', "guillemets droits (déconseillé en typographie)"],
            ['/', "signe de la division"],
            ['+', "signe de l’addition"],
            ['*', "signe de la multiplication"],
            ['=', "signe de l’égalité"],
            ['<', "inférieur à"],
            ['>', "supérieur à"],
            ['⩽', "inférieur ou égal à"],
            ['⩾', "supérieur ou égal à"],
            ['%', "signe de pourcentage"],
            ['‰', "signe pour mille"],
        ]),

    oSpellChecker: null,
    oTokenizer: null,
    oLocGraph: null,

    _zPartDemForm: new RegExp("([a-zA-Zà-ö0-9À-Öø-ÿØ-ßĀ-ʯ]+)-(là|ci)$", "i"),
    _aPartDemExceptList: new Set(["celui", "celle", "ceux", "celles", "de", "jusque", "par", "marie-couche-toi"]),
    _zInterroVerb: new RegExp("([a-zA-Zà-ö0-9À-Öø-ÿØ-ßĀ-ʯ]+)(-(?:t-(?:ie?l|elle|on)|je|tu|ie?ls?|elles?|on|[nv]ous))$", "i"),
    _zImperatifVerb: new RegExp("([a-zA-Zà-ö0-9À-Öø-ÿØ-ßĀ-ʯ]+)(-(?:l(?:es?|a)-(?:moi|toi|lui|[nv]ous|leur)|y|en|[mts][’'](?:y|en)|les?|la|[mt]oi|leur|lui))$", "i"),
    _zTag: new RegExp("[:;/][a-zA-Z0-9ÑÂĴĈŔÔṼŴ!][^:;/]*", "g"),


    load: function (oSpellChecker, oTokenizer, oLocGraph) {
        this.oSpellChecker = oSpellChecker;
        this.oTokenizer = oTokenizer;
        this.oLocGraph = JSON.parse(oLocGraph);
    },

    split: function (sWord) {
        // returns an arry of strings (prefix, trimed_word, suffix)
        let sPrefix = "";
        let sSuffix = "";
        // préfixe élidé
        let m = /^([ldmtsnjcç]|lorsqu|presqu|jusqu|puisqu|quoiqu|quelqu|qu)[’'‘`ʼ]([a-zA-Zà-öÀ-Ö0-9_ø-ÿØ-ßĀ-ʯfi-st-]+)/i.exec(sWord);
        if (m) {
            sPrefix = m[1] + "’";
            sWord = m[2];
        }
        // mots composés
        m = /^([a-zA-Zà-öÀ-Ö0-9_ø-ÿØ-ßĀ-ʯfi-st-]+)(-(?:(?:les?|la)-(?:moi|toi|lui|[nv]ous|leur)|t-(?:il|elle|on)|y|en|[mts]’(?:y|en)|les?|l[aà]|[mt]oi|leur|lui|je|tu|ils?|elles?|on|[nv]ous|ce))$/i.exec(sWord);
        if (m) {
            sWord = m[1];
            sSuffix = m[2];
        }
        // split word in 3 parts: prefix, root, suffix
        return [sPrefix, sWord, sSuffix];
    },

    analyze: function (sWord) {
        // return meaning of <sWord> if found else an empty string
        sWord = sWord.toLowerCase();
        if (this.dValues.has(sWord)) {
            return this.dValues.get(sWord);
        }
        return "";
    },

    readableMorph: function (sMorph) {
        let sRes = "";
        sMorph = sMorph.replace(/:V([0-3][ea_])[itpqnmr_eaxz]+/, ":V$1");
        let m;
        while ((m = this._zTag.exec(sMorph)) !== null) {
            if (this.dTag.has(m[0])) {
                sRes += this.dTag.get(m[0])[0];
            } else {
                sRes += " [" + m[0] + "]?";
            }
        }
        if (sRes.startsWith(" verbe") && !sRes.includes("infinitif")) {
            sRes += " [" + sMorph.slice(1, sMorph.indexOf("/")) + "]";
        }
        if (!sRes) {
            return " [" + sMorph + "]: étiquettes inconnues";
        }
        return sRes.gl_trimRight(",");
    },

    setLabelsOnToken (oToken) {
        // Token: .sType, .sValue, .nStart, .nEnd, .lMorph
        let m = null;
        try {
            switch (oToken.sType) {
                case 'PUNC':
                case 'SIGN':
                    oToken["aLabels"] = [this.dValues.gl_get(oToken["sValue"], "signe de ponctuation divers")];
                    break;
                case 'NUM':
                    oToken["aLabels"] = ["nombre"];
                    break;
                case 'LINK':
                    oToken["aLabels"] = ["hyperlien"];
                    break;
                case 'TAG':
                    oToken["aLabels"] = ["étiquette (hashtag)"];
                    break;
                case 'HTML':
                    oToken["aLabels"] = ["balise HTML"];
                    break;
                case 'PSEUDOHTML':
                    oToken["aLabels"] = ["balise pseudo-HTML"];
                    break;
                case 'HTMLENTITY':
                    oToken["aLabels"] = ["entité caractère XML/HTML"];
                    break;
                case 'HOUR':
                    oToken["aLabels"] = ["heure"];
                    break;
                case 'WORD_ELIDED':
                    oToken["aLabels"] = [this.dValues.gl_get(oToken["sValue"].toLowerCase(), "préfixe élidé inconnu")];
                    break;
                case 'WORD_ORDINAL':
                    oToken["aLabels"] = ["nombre ordinal"];
                    break;
                case 'FOLDERUNIX':
                    oToken["aLabels"] = ["dossier UNIX (et dérivés)"];
                    break;
                case 'FOLDERWIN':
                    oToken["aLabels"] = ["dossier Windows"];
                    break;
                case 'WORD_ACRONYM':
                    oToken["aLabels"] = ["sigle ou acronyme"];
                    break;
                case 'WORD':
                    if (oToken.hasOwnProperty("lMorph")  &&  oToken["lMorph"].length > 0) {
                        // with morphology
                        oToken["aLabels"] = [];
                        for (let sMorph of oToken["lMorph"]) {
                            oToken["aLabels"].push(this.readableMorph(sMorph));
                        }
                        if (oToken.hasOwnProperty("sTags")) {
                            let aTags = [];
                            for (let sTag of oToken["sTags"]) {
                                if (this.dValues.has(sTag)) {
                                    aTags.push(this.dValues.get(sTag))
                                }
                            }
                            if (aTags.length > 0) {
                                oToken["aOtherLabels"] = aTags;
                            }
                        }
                    } else {
                        // no morphology, guessing
                        if (oToken["sValue"].gl_count("-") > 4) {
                            oToken["aLabels"] = ["élément complexe indéterminé"];
                        }
                        else if (m = this._zPartDemForm.exec(oToken["sValue"])) {
                            // mots avec particules démonstratives
                            oToken["aLabels"] = ["mot avec particule démonstrative"];
                        }
                        else if (m = this._zImperatifVerb.exec(oToken["sValue"])) {
                            // formes interrogatives
                            oToken["aLabels"] = ["forme verbale impérative"];
                        }
                        else if (m = this._zInterroVerb.exec(oToken["sValue"])) {
                            // formes interrogatives
                            oToken["aLabels"] = ["forme verbale interrogative"];
                        }
                        else {
                            oToken["aLabels"] = ["mot inconnu du dictionnaire"];
                        }
                    }
                    break;
                default:
                    oToken["aLabels"] = ["token de nature inconnue"];
            }
        } catch (e) {
            console.error(e);
        }
    },

    getInfoForToken: function (oToken) {
        // Token: .sType, .sValue, .nStart, .nEnd
        // return a object {sType, sValue, aLabel}
        let m = null;
        try {
            switch (oToken.sType) {
                case 'PUNC':
                case 'SIGN':
                    return {
                        sType: oToken.sType,
                        sValue: oToken.sValue,
                        aLabel: [this.dValues.gl_get(oToken.sValue, "caractère indéterminé")]
                    };
                    break;
                case 'NUM':
                    return {
                        sType: oToken.sType,
                        sValue: oToken.sValue,
                        aLabel: ["nombre"]
                    };
                    break;
                case 'LINK':
                    return {
                        sType: oToken.sType,
                        sValue: oToken.sValue.slice(0, 40) + "…",
                        aLabel: ["hyperlien"]
                    };
                    break;
                case 'TAG':
                    return {
                        sType: oToken.sType,
                        sValue: oToken.sValue,
                        aLabel: ["étiquette (hashtag)"]
                    };
                    break;
                case 'HTML':
                    return {
                        sType: oToken.sType,
                        sValue: oToken.sValue.slice(0, 40) + "…",
                        aLabel: ["balise HTML"]
                    };
                    break;
                case 'PSEUDOHTML':
                    return {
                        sType: oToken.sType,
                        sValue: oToken.sValue,
                        aLabel: ["balise pseudo-HTML"]
                    };
                    break;
                case 'HTMLENTITY':
                    return {
                        sType: oToken.sType,
                        sValue: oToken.sValue,
                        aLabel: ["entité caractère XML/HTML"]
                    };
                    break;
                case 'HOUR':
                    return {
                        sType: oToken.sType,
                        sValue: oToken.sValue,
                        aLabel: ["heure"]
                    };
                    break;
                case 'WORD_ELIDED':
                    return {
                        sType: oToken.sType,
                        sValue: oToken.sValue,
                        aLabel: [this.dValues.gl_get(oToken.sValue.toLowerCase(), "préfixe élidé inconnu")]
                    };
                    break;
                case 'WORD_ORDINAL':
                    return {
                        sType: oToken.sType,
                        sValue: oToken.sValue,
                        aLabel: ["nombre ordinal"]
                    };
                    break;
                case 'FOLDERUNIX':
                    return {
                        sType: oToken.sType,
                        sValue: oToken.sValue.slice(0, 40) + "…",
                        aLabel: ["dossier UNIX (et dérivés)"]
                    };
                    break;
                case 'FOLDERWIN':
                    return {
                        sType: oToken.sType,
                        sValue: oToken.sValue.slice(0, 40) + "…",
                        aLabel: ["dossier Windows"]
                    };
                    break;
                case 'WORD_ACRONYM':
                    return {
                        sType: oToken.sType,
                        sValue: oToken.sValue,
                        aLabel: ["Sigle ou acronyme"]
                    };
                    break;
                case 'WORD':
                    if (oToken.sValue.gl_count("-") > 4) {
                        return {
                            sType: "COMPLEX",
                            sValue: oToken.sValue,
                            aLabel: ["élément complexe indéterminé"]
                        };
                    } else if (m = this._zPartDemForm.exec(oToken.sValue)) {
                        // mots avec particules démonstratives
                        if (this._aPartDemExceptList.has(m[1].toLowerCase())) {
                            return {
                                sType: "WORD",
                                sValue: oToken.sValue,
                                aLabel: this._getMorph(oToken.sValue)
                            };
                        }
                        return {
                            sType: oToken.sType,
                            sValue: oToken.sValue,
                            aLabel: ["mot avec particule démonstrative"],
                            aSubElem: [
                                { sType: oToken.sType, sValue: m[1], aLabel: this._getMorph(m[1]) },
                                { sType: oToken.sType, sValue: m[2], aLabel: [ this._formatSuffix(m[2]) ] }
                            ]
                        };
                    } else if (m = this._zImperatifVerb.exec(oToken.sValue)) {
                        // formes interrogatives
                        return {
                            sType: oToken.sType,
                            sValue: oToken.sValue,
                            aLabel: ["forme verbale impérative"],
                            aSubElem: [
                                { sType: oToken.sType, sValue: m[1], aLabel: this._getMorph(m[1]) },
                                { sType: oToken.sType, sValue: m[2], aLabel: [ this._formatSuffix(m[2]) ] }
                            ]
                        };
                    } else if (m = this._zInterroVerb.exec(oToken.sValue)) {
                        // formes interrogatives
                        return {
                            sType: oToken.sType,
                            sValue: oToken.sValue,
                            aLabel: ["forme verbale interrogative"],
                            aSubElem: [
                                { sType: oToken.sType, sValue: m[1], aLabel: this._getMorph(m[1]) },
                                { sType: oToken.sType, sValue: m[2], aLabel: [ this._formatSuffix(m[2]) ] }
                            ]
                        };
                    } else if (this.oSpellChecker.isValidToken(oToken.sValue)) {
                        return {
                            sType: oToken.sType,
                            sValue: oToken.sValue,
                            aLabel: this._getMorph(oToken.sValue)
                        };
                    } else {
                        return {
                            sType: "UNKNOWN_WORD",
                            sValue: oToken.sValue,
                            aLabel: ["mot inconnu du dictionnaire"]
                        };
                    }
                    break;
                default:
                    return {
                        sType: oToken.sType,
                        sValue: oToken.sValue,
                        aLabel: ["token inconnu"]
                    }
            }
        } catch (e) {
            console.error(e);
        }
        return null;
    },

    _getMorph (sWord) {
        let aElem = [];
        for (let s of this.oSpellChecker.getMorph(sWord)) {
            if (s.includes(":")) aElem.push(this.readableMorph(s));
        }
        if (aElem.length == 0) {
            aElem.push("mot inconnu du dictionnaire");
        }
        return aElem;
    },

    _formatSuffix (sSuffix) {
        sSuffix = sSuffix.replace(/['’ʼ‘‛´`′‵՚ꞌꞋ]/g, "’").toLowerCase();
        if (this.dValues.has(sSuffix)) {
            return this.dValues.get(sSuffix);
        }
        return " suffixe inconnu";
    },

    getListOfTokens (sText, bInfo=true) {
        let aElem = [];
        if (sText !== "") {
            for (let oToken of this.oTokenizer.genTokens(sText)) {
                if (bInfo) {
                    let aRes = this.getInfoForToken(oToken);
                    if (aRes) {
                        aElem.push(aRes);
                    }
                } else if (oToken.sType !== "SPACE") {
                    aElem.push(oToken);
                }
            }
        }
        return aElem;
    },


    // Other functions

    filterSugg: function (aSugg) {
        return aSugg.filter((sSugg) => { return !sSugg.endsWith("è") && !sSugg.endsWith("È"); });
    }
}



if (typeof(exports) !== 'undefined') {
    exports.lexgraph_fr = lexgraph_fr;
}