Index: gc_core/js/helpers.js ================================================================== --- gc_core/js/helpers.js +++ gc_core/js/helpers.js @@ -5,94 +5,95 @@ // In Firefox, there is no console.log in PromiseWorker, but there is worker.log. // In Thunderbird, you can’t access to console directly. So it’s required to pass a log function. let funcOutput = null; -function setLogOutput (func) { - funcOutput = func; -} - -function echo (obj) { - if (funcOutput !== null) { - funcOutput(obj); - } else { - console.log(obj); - } - return true; -} - -function logerror (e, bStack=false) { - let sMsg = "\n" + e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message; - if (bStack) { - sMsg += "\n--- Stack ---\n" + e.stack; - } - if (funcOutput !== null) { - funcOutput(sMsg); - } else { - console.error(sMsg); - } -} - -function inspect (o) { - let sMsg = "__inspect__: " + typeof o; - for (let sParam in o) { - sMsg += "\n" + sParam + ": " + o.sParam; - } - sMsg += "\n" + JSON.stringify(o) + "\n__end__"; - echo(sMsg); -} - - -// load ressources in workers (suggested by Mozilla extensions reviewers) -// for more options have a look here: https://gist.github.com/Noitidart/ec1e6b9a593ec7e3efed -// if not in workers, use sdk/data.load() instead -function loadFile (spf) { - try { - let xRequest; - if (typeof XMLHttpRequest !== "undefined") { - xRequest = new XMLHttpRequest(); - } - else { - // JS bullshit again… necessary for Thunderbird - let { Cc, Ci } = require("chrome"); - xRequest = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(); - xRequest.QueryInterface(Ci.nsIXMLHttpRequest); - } - xRequest.open('GET', spf, false); // 3rd arg is false for synchronous, sync is acceptable in workers - xRequest.send(); - return xRequest.responseText; - } - catch (e) { - logerror(e); - return null - } -} - - -// conversions -function objectToMap (obj) { - let m = new Map(); - for (let param in obj) { - //console.log(param + " " + obj[param]); - m.set(param, obj[param]); - } - return m; -} - -function mapToObject (m) { - let obj = {}; - for (let [k, v] of m) { - obj[k] = v; - } - return obj; -} - - -if (typeof(exports) !== 'undefined') { - exports.setLogOutput = setLogOutput; - exports.echo = echo; - exports.logerror = logerror; - exports.inspect = inspect; - exports.loadFile = loadFile; - exports.objectToMap = objectToMap; - exports.mapToObject = mapToObject; +var helpers = { + + setLogOutput: function (func) { + funcOutput = func; + }, + + echo: function (obj) { + if (funcOutput !== null) { + funcOutput(obj); + } else { + console.log(obj); + } + return true; + }, + + logerror: function (e, bStack=false) { + let sMsg = "\n" + e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message; + if (bStack) { + sMsg += "\n--- Stack ---\n" + e.stack; + } + if (funcOutput !== null) { + funcOutput(sMsg); + } else { + console.error(sMsg); + } + }, + + inspect: function (o) { + let sMsg = "__inspect__: " + typeof o; + for (let sParam in o) { + sMsg += "\n" + sParam + ": " + o.sParam; + } + sMsg += "\n" + JSON.stringify(o) + "\n__end__"; + this.echo(sMsg); + }, + + loadFile: function (spf) { + // load ressources in workers (suggested by Mozilla extensions reviewers) + // for more options have a look here: https://gist.github.com/Noitidart/ec1e6b9a593ec7e3efed + // if not in workers, use sdk/data.load() instead + try { + let xRequest; + if (typeof XMLHttpRequest !== "undefined") { + xRequest = new XMLHttpRequest(); + } + else { + // JS bullshit again… necessary for Thunderbird + let { Cc, Ci } = require("chrome"); + xRequest = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(); + xRequest.QueryInterface(Ci.nsIXMLHttpRequest); + } + xRequest.open('GET', spf, false); // 3rd arg is false for synchronous, sync is acceptable in workers + xRequest.send(); + return xRequest.responseText; + } + catch (e) { + this.logerror(e); + return null + } + }, + + // conversions + objectToMap: function (obj) { + let m = new Map(); + for (let param in obj) { + //console.log(param + " " + obj[param]); + m.set(param, obj[param]); + } + return m; + }, + + mapToObject: function (m) { + let obj = {}; + for (let [k, v] of m) { + obj[k] = v; + } + return obj; + } +} + + +if (typeof(exports) !== 'undefined') { + exports.setLogOutput = helpers.setLogOutput; + exports.echo = helpers.echo; + exports.logerror = helpers.logerror; + exports.inspect = helpers.inspect; + exports.loadFile = helpers.loadFile; + exports.objectToMap = helpers.objectToMap; + exports.mapToObject = helpers.mapToObject; } Index: gc_core/js/lang_core/gc_options.js ================================================================== --- gc_core/js/lang_core/gc_options.js +++ gc_core/js/lang_core/gc_options.js @@ -1,27 +1,31 @@ // Options for Grammalecte ${map} -function getOptions (sContext="JavaScript") { - if (dOpt.hasOwnProperty(sContext)) { - return dOpt[sContext]; - } - return dOpt["JavaScript"]; -} - -const lStructOpt = ${lStructOpt}; - -const dOpt = { - "JavaScript": new Map (${dOptJavaScript}), - "Firefox": new Map (${dOptFirefox}), - "Thunderbird": new Map (${dOptThunderbird}), -} - -const dOptLabel = ${dOptLabel}; + +const gc_options = { + getOptions: function (sContext="JavaScript") { + if (this.dOpt.hasOwnProperty(sContext)) { + return this.dOpt[sContext]; + } + return this.dOpt["JavaScript"]; + }, + + lStructOpt: ${lStructOpt}, + + dOpt: { + "JavaScript": new Map (${dOptJavaScript}), + "Firefox": new Map (${dOptFirefox}), + "Thunderbird": new Map (${dOptThunderbird}), + }, + + dOptLabel: ${dOptLabel} +} if (typeof(exports) !== 'undefined') { - exports.getOptions = getOptions; - exports.lStructOpt = lStructOpt; - exports.dOptLabel = dOptLabel; + exports.getOptions = gc_options.getOptions; + exports.lStructOpt = gc_options.lStructOpt; + exports.dOpt = gc_options.dOpt; + exports.dOptLabel = gc_options.dOptLabel; } Index: gc_core/js/lang_core/gc_rules.js ================================================================== --- gc_core/js/lang_core/gc_rules.js +++ gc_core/js/lang_core/gc_rules.js @@ -2,14 +2,16 @@ "use strict"; ${string} ${regex} -const lParagraphRules = ${paragraph_rules_JS}; +const gc_rules = { + lParagraphRules: ${paragraph_rules_JS}, -const lSentenceRules = ${sentence_rules_JS}; + lSentenceRules: ${sentence_rules_JS} +} if (typeof(exports) !== 'undefined') { - exports.lParagraphRules = lParagraphRules; - exports.lSentenceRules = lSentenceRules; + exports.lParagraphRules = gc_rules.lParagraphRules; + exports.lSentenceRules = gc_rules.lSentenceRules; } Index: gc_core/js/str_transform.js ================================================================== --- gc_core/js/str_transform.js +++ gc_core/js/str_transform.js @@ -1,60 +1,32 @@ //// STRING TRANSFORMATION -var dSimilarChars = new Map ([ - ["a", "aàâáä"], - ["à", "aàâáä"], - ["â", "aàâáä"], - ["á", "aàâáä"], - ["ä", "aàâáä"], - ["c", "cç"], - ["ç", "cç"], - ["e", "eéêèë"], - ["é", "eéêèë"], - ["ê", "eéêèë"], - ["è", "eéêèë"], - ["ë", "eéêèë"], - ["i", "iîïíì"], - ["î", "iîïíì"], - ["ï", "iîïíì"], - ["í", "iîïíì"], - ["ì", "iîïíì"], - ["o", "oôóòö"], - ["ô", "oôóòö"], - ["ó", "oôóòö"], - ["ò", "oôóòö"], - ["ö", "oôóòö"], - ["u", "uûùüú"], - ["û", "uûùüú"], - ["ù", "uûùüú"], - ["ü", "uûùüú"], - ["ú", "uûùüú"] -]); - // Note: 48 is the ASCII code for "0" -// Suffix only -function getStemFromSuffixCode (sFlex, sSfxCode) { - if (sSfxCode == "0") { - return sFlex; - } - return sSfxCode[0] == '0' ? sFlex + sSfxCode.slice(1) : sFlex.slice(0, -(sSfxCode.charCodeAt(0)-48)) + sSfxCode.slice(1); -} - -// Prefix and suffix -function getStemFromAffixCode (sFlex, sAffCode) { - if (sAffCode == "0") { - return sFlex; - } - if (!sAffCode.includes("/")) { - return "# error #"; - } - var [sPfxCode, sSfxCode] = sAffCode.split('/'); - sFlex = sPfxCode.slice(1) + sFlex.slice(sPfxCode.charCodeAt(0)-48); - return sSfxCode[0] == '0' ? sFlex + sSfxCode.slice(1) : sFlex.slice(0, -(sSfxCode.charCodeAt(0)-48)) + sSfxCode.slice(1); +var str_transform = { + getStemFromSuffixCode: function (sFlex, sSfxCode) { + // Suffix only + if (sSfxCode == "0") { + return sFlex; + } + return sSfxCode[0] == '0' ? sFlex + sSfxCode.slice(1) : sFlex.slice(0, -(sSfxCode.charCodeAt(0)-48)) + sSfxCode.slice(1); + }, + + getStemFromAffixCode: function (sFlex, sAffCode) { + // Prefix and suffix + if (sAffCode == "0") { + return sFlex; + } + if (!sAffCode.includes("/")) { + return "# error #"; + } + let [sPfxCode, sSfxCode] = sAffCode.split('/'); + sFlex = sPfxCode.slice(1) + sFlex.slice(sPfxCode.charCodeAt(0)-48); + return sSfxCode[0] == '0' ? sFlex + sSfxCode.slice(1) : sFlex.slice(0, -(sSfxCode.charCodeAt(0)-48)) + sSfxCode.slice(1); + } } if (typeof(exports) !== 'undefined') { - exports.getStemFromSuffixCode = getStemFromSuffixCode; - exports.getStemFromAffixCode = getStemFromAffixCode; + exports.getStemFromSuffixCode = str_transform.getStemFromSuffixCode; + exports.getStemFromAffixCode = str_transform.getStemFromAffixCode; } Index: gc_core/js/text.js ================================================================== --- gc_core/js/text.js +++ gc_core/js/text.js @@ -2,63 +2,64 @@ "use strict"; const helpers = require("resource://grammalecte/helpers.js"); - -function* getParagraph (sText) { - // generator: returns paragraphs of text - let iStart = 0; - let iEnd = 0; - sText = sText.replace("\r", ""); - while ((iEnd = sText.indexOf("\n", iStart)) !== -1) { - yield sText.slice(iStart, iEnd); - iStart = iEnd + 1; - } - yield sText.slice(iStart); -} - -function* wrap (sText, nWidth=80) { - // generator: returns text line by line - while (sText) { - if (sText.length >= nWidth) { - let nEnd = sText.lastIndexOf(" ", nWidth) + 1; - if (nEnd > 0) { - yield sText.slice(0, nEnd); - sText = sText.slice(nEnd); - } else { - yield sText.slice(0, nWidth); - sText = sText.slice(nWidth); - } - } else { - break; - } - } - yield sText; -} - -function getReadableError (oErr) { - // Returns an error oErr as a readable error - try { - let sResult = "\n* " + oErr['nStart'] + ":" + oErr['nEnd'] - + " # " + oErr['sLineId'] + " # " + oErr['sRuleId'] + ":\n"; - sResult += " " + oErr["sMessage"]; - if (oErr["aSuggestions"].length > 0) { - sResult += "\n > Suggestions : " + oErr["aSuggestions"].join(" | "); - } - if (oErr["URL"] !== "") { - sResult += "\n > URL: " + oErr["URL"]; - } - return sResult; - } - catch (e) { - helpers.logerror(e); - return "\n# Error. Data: " + oErr.toString(); +var text = { + getParagraph: function* (sText) { + // generator: returns paragraphs of text + let iStart = 0; + let iEnd = 0; + sText = sText.replace("\r", ""); + while ((iEnd = sText.indexOf("\n", iStart)) !== -1) { + yield sText.slice(iStart, iEnd); + iStart = iEnd + 1; + } + yield sText.slice(iStart); + }, + + wrap: function* (sText, nWidth=80) { + // generator: returns text line by line + while (sText) { + if (sText.length >= nWidth) { + let nEnd = sText.lastIndexOf(" ", nWidth) + 1; + if (nEnd > 0) { + yield sText.slice(0, nEnd); + sText = sText.slice(nEnd); + } else { + yield sText.slice(0, nWidth); + sText = sText.slice(nWidth); + } + } else { + break; + } + } + yield sText; + }, + + getReadableError: function (oErr) { + // Returns an error oErr as a readable error + try { + let sResult = "\n* " + oErr['nStart'] + ":" + oErr['nEnd'] + + " # " + oErr['sLineId'] + " # " + oErr['sRuleId'] + ":\n"; + sResult += " " + oErr["sMessage"]; + if (oErr["aSuggestions"].length > 0) { + sResult += "\n > Suggestions : " + oErr["aSuggestions"].join(" | "); + } + if (oErr["URL"] !== "") { + sResult += "\n > URL: " + oErr["URL"]; + } + return sResult; + } + catch (e) { + helpers.logerror(e); + return "\n# Error. Data: " + oErr.toString(); + } } } if (typeof(exports) !== 'undefined') { - exports.getParagraph = getParagraph; - exports.wrap = wrap; - exports.getReadableError = getReadableError; + exports.getParagraph = text.getParagraph; + exports.wrap = text.wrap; + exports.getReadableError = text.getReadableError; } Index: gc_lang/fr/modules-js/conj.js ================================================================== --- gc_lang/fr/modules-js/conj.js +++ gc_lang/fr/modules-js/conj.js @@ -6,183 +6,173 @@ ${map} let helpers = null; // module not loaded in Firefox content script -let _oData = {}; -let _lVtyp = null; -let _lTags = null; -let _dPatternConj = {}; -let _dVerb = {}; - - -if (typeof(exports) !== 'undefined') { - // used within Grammalecte library - helpers = require("resource://grammalecte/helpers.js"); - _oData = JSON.parse(helpers.loadFile("resource://grammalecte/fr/conj_data.json")); - _lVtyp = _oData.lVtyp; - _lTags = _oData.lTags; - _dPatternConj = _oData.dPatternConj; - _dVerb = _oData.dVerb; -} else { - // used within Firefox content script (conjugation panel). - // can’t load JSON from here, so we do it in ui.js and send it here. - self.port.on("provideConjData", function (sData) { - _oData = JSON.parse(sData); - _lVtyp = _oData.lVtyp; - _lTags = _oData.lTags; - _dPatternConj = _oData.dPatternConj; - _dVerb = _oData.dVerb; - }); -} - - -const _zStartVoy = new RegExp("^[aeéiouœê]"); -const _zNeedTeuph = new RegExp("[tdc]$"); - -const _dProSuj = new Map ([ [":1s", "je"], [":1ś", "je"], [":2s", "tu"], [":3s", "il"], [":1p", "nous"], [":2p", "vous"], [":3p", "ils"] ]); -const _dProObj = new Map ([ [":1s", "me "], [":1ś", "me "], [":2s", "te "], [":3s", "se "], [":1p", "nous "], [":2p", "vous "], [":3p", "se "] ]); -const _dProObjEl = new Map ([ [":1s", "m’"], [":1ś", "m’"], [":2s", "t’"], [":3s", "s’"], [":1p", "nous "], [":2p", "vous "], [":3p", "s’"] ]); -const _dImpePro = new Map ([ [":2s", "-toi"], [":1p", "-nous"], [":2p", "-vous"] ]); -const _dImpeProNeg = new Map ([ [":2s", "ne te "], [":1p", "ne nous "], [":2p", "ne vous "] ]); -const _dImpeProEn = new Map ([ [":2s", "-t’en"], [":1p", "-nous-en"], [":2p", "-vous-en"] ]); -const _dImpeProNegEn = new Map ([ [":2s", "ne t’en "], [":1p", "ne nous en "], [":2p", "ne vous en "] ]); - -const _dGroup = new Map ([ ["0", "auxiliaire"], ["1", "1ᵉʳ groupe"], ["2", "2ᵉ groupe"], ["3", "3ᵉ groupe"] ]); - -const _dTenseIdx = new Map ([ [":PQ", 0], [":Ip", 1], [":Iq", 2], [":Is", 3], [":If", 4], [":K", 5], [":Sp", 6], [":Sq", 7], [":E", 8] ]); - - -function isVerb (sVerb) { - return _dVerb.hasOwnProperty(sVerb); -} - -function getConj (sVerb, sTense, sWho) { - // returns conjugation (can be an empty string) - if (!_dVerb.hasOwnProperty(sVerb)) { - return null; - } - if (!_dPatternConj[sTense][_lTags[_dVerb[sVerb][1]][_dTenseIdx.get(sTense)]].hasOwnProperty(sWho)) { - return ""; - } - return _modifyStringWithSuffixCode(sVerb, _dPatternConj[sTense][_lTags[_dVerb[sVerb][1]][_dTenseIdx.get(sTense)]][sWho]); -} - -function hasConj (sVerb, sTense, sWho) { - // returns false if no conjugation (also if empty) else true - if (!_dVerb.hasOwnProperty(sVerb)) { - return false; - } - if (_dPatternConj[sTense][_lTags[_dVerb[sVerb][1]][_dTenseIdx.get(sTense)]].hasOwnProperty(sWho) - && _dPatternConj[sTense][_lTags[_dVerb[sVerb][1]][_dTenseIdx.get(sTense)]][sWho]) { - return true; - } - return false; -} - -function getVtyp (sVerb) { - // returns raw informations about sVerb - if (!_dVerb.hasOwnProperty(sVerb)) { - return null; - } - return _lVtyp[_dVerb[sVerb][0]]; -} - -function getSimil (sWord, sMorph, sFilter=null) { - if (!sMorph.includes(":V")) { - return new Set(); - } - let sInfi = sMorph.slice(1, sMorph.indexOf(" ")); - let tTags = _getTags(sInfi); - let aSugg = new Set(); - if (sMorph.includes(":Q") || sMorph.includes(":Y")) { - // we suggest conjugated forms - if (sMorph.includes(":V1")) { - aSugg.add(sInfi); - aSugg.add(_getConjWithTags(sInfi, tTags, ":Ip", ":3s")); - aSugg.add(_getConjWithTags(sInfi, tTags, ":Ip", ":2p")); - aSugg.add(_getConjWithTags(sInfi, tTags, ":Iq", ":1s")); - aSugg.add(_getConjWithTags(sInfi, tTags, ":Iq", ":3s")); - aSugg.add(_getConjWithTags(sInfi, tTags, ":Iq", ":3p")); - } else if (sMorph.includes(":V2")) { - aSugg.add(_getConjWithTags(sInfi, tTags, ":Ip", ":1s")); - aSugg.add(_getConjWithTags(sInfi, tTags, ":Ip", ":3s")); - } else if (sMorph.includes(":V3")) { - aSugg.add(_getConjWithTags(sInfi, tTags, ":Ip", ":1s")); - aSugg.add(_getConjWithTags(sInfi, tTags, ":Ip", ":3s")); - aSugg.add(_getConjWithTags(sInfi, tTags, ":Is", ":1s")); - aSugg.add(_getConjWithTags(sInfi, tTags, ":Is", ":3s")); - } else if (isMorph.includes(":V0a")) { - aSugg.add("eus"); - aSugg.add("eut"); - } else { - aSugg.add("étais"); - aSugg.add("était"); - } - aSugg.delete(""); - } else { - // we suggest past participles - aSugg.add(_getConjWithTags(sInfi, tTags, ":PQ", ":Q1")); - aSugg.add(_getConjWithTags(sInfi, tTags, ":PQ", ":Q2")); - aSugg.add(_getConjWithTags(sInfi, tTags, ":PQ", ":Q3")); - aSugg.add(_getConjWithTags(sInfi, tTags, ":PQ", ":Q4")); - aSugg.delete(""); - // if there is only one past participle (epi inv), unreliable. - if (aSugg.size === 1) { - aSugg.clear(); - } - if (sMorph.includes(":V1")) { - aSugg.add(sInfi); - } - } - return aSugg; -} - - -function _getTags (sVerb) { - // returns tuple of tags (usable with functions _getConjWithTags and _hasConjWithTags) - if (!_dVerb.hasOwnProperty(sVerb)) { - return null; - } - return _lTags[_dVerb[sVerb][1]]; -} - -function _getConjWithTags (sVerb, tTags, sTense, sWho) { - // returns conjugation (can be an empty string) - if (!_dPatternConj[sTense][tTags[_dTenseIdx.get(sTense)]].hasOwnProperty(sWho)) { - return ""; - } - return _modifyStringWithSuffixCode(sVerb, _dPatternConj[sTense][tTags[_dTenseIdx.get(sTense)]][sWho]); -} - -function _hasConjWithTags (tTags, sTense, sWho) { - // returns false if no conjugation (also if empty) else true - if (_dPatternConj[sTense][tTags[_dTenseIdx.get(sTense)]].hasOwnProperty(sWho) - && _dPatternConj[sTense][tTags[_dTenseIdx.get(sTense)]][sWho]) { - return true; - } - return false; -} - -function _modifyStringWithSuffixCode (sWord, sSfx) { - // returns sWord modified by sSfx - if (sSfx === "") { - return ""; - } - if (sSfx === "0") { - return sWord; - } - try { - if (sSfx[0] !== '0') { - return sWord.slice(0, -(sSfx.charCodeAt(0)-48)) + sSfx.slice(1); // 48 is the ASCII code for "0" - } else { - return sWord + sSfx.slice(1); - } - } - catch (e) { - console.log(e); - return "## erreur, code : " + sSfx + " ##"; +const conj = { + _lVtyp: null, + _lTags: null, + _dPatternConj: {}, + _dVerb: {}, + + init: function (sJSONData) { + try { + let _oData = JSON.parse(sJSONData); + this._lVtyp = _oData.lVtyp; + this._lTags = _oData.lTags; + this._dPatternConj = _oData.dPatternConj; + this._dVerb = _oData.dVerb; + } + catch (e) { + console.error(e); + } + }, + + _zStartVoy: new RegExp("^[aeéiouœê]"), + _zNeedTeuph: new RegExp("[tdc]$"), + + _dProSuj: new Map ([ [":1s", "je"], [":1ś", "je"], [":2s", "tu"], [":3s", "il"], [":1p", "nous"], [":2p", "vous"], [":3p", "ils"] ]), + _dProObj: new Map ([ [":1s", "me "], [":1ś", "me "], [":2s", "te "], [":3s", "se "], [":1p", "nous "], [":2p", "vous "], [":3p", "se "] ]), + _dProObjEl: new Map ([ [":1s", "m’"], [":1ś", "m’"], [":2s", "t’"], [":3s", "s’"], [":1p", "nous "], [":2p", "vous "], [":3p", "s’"] ]), + _dImpePro: new Map ([ [":2s", "-toi"], [":1p", "-nous"], [":2p", "-vous"] ]), + _dImpeProNeg: new Map ([ [":2s", "ne te "], [":1p", "ne nous "], [":2p", "ne vous "] ]), + _dImpeProEn: new Map ([ [":2s", "-t’en"], [":1p", "-nous-en"], [":2p", "-vous-en"] ]), + _dImpeProNegEn: new Map ([ [":2s", "ne t’en "], [":1p", "ne nous en "], [":2p", "ne vous en "] ]), + + _dGroup: new Map ([ ["0", "auxiliaire"], ["1", "1ᵉʳ groupe"], ["2", "2ᵉ groupe"], ["3", "3ᵉ groupe"] ]), + + _dTenseIdx: new Map ([ [":PQ", 0], [":Ip", 1], [":Iq", 2], [":Is", 3], [":If", 4], [":K", 5], [":Sp", 6], [":Sq", 7], [":E", 8] ]), + + isVerb: function (sVerb) { + return this._dVerb.hasOwnProperty(sVerb); + }, + + getConj: function (sVerb, sTense, sWho) { + // returns conjugation (can be an empty string) + if (!this._dVerb.hasOwnProperty(sVerb)) { + return null; + } + if (!this._dPatternConj[sTense][this._lTags[this._dVerb[sVerb][1]][this._dTenseIdx.get(sTense)]].hasOwnProperty(sWho)) { + return ""; + } + return this._modifyStringWithSuffixCode(sVerb, this._dPatternConj[sTense][this._lTags[this._dVerb[sVerb][1]][this._dTenseIdx.get(sTense)]][sWho]); + }, + + hasConj: function (sVerb, sTense, sWho) { + // returns false if no conjugation (also if empty) else true + if (!this._dVerb.hasOwnProperty(sVerb)) { + return false; + } + if (this._dPatternConj[sTense][this._lTags[this._dVerb[sVerb][1]][this._dTenseIdx.get(sTense)]].hasOwnProperty(sWho) + && this._dPatternConj[sTense][this._lTags[this._dVerb[sVerb][1]][this._dTenseIdx.get(sTense)]][sWho]) { + return true; + } + return false; + }, + + getVtyp: function (sVerb) { + // returns raw informations about sVerb + if (!this._dVerb.hasOwnProperty(sVerb)) { + return null; + } + return this._lVtyp[this._dVerb[sVerb][0]]; + }, + + getSimil: function (sWord, sMorph, sFilter=null) { + if (!sMorph.includes(":V")) { + return new Set(); + } + let sInfi = sMorph.slice(1, sMorph.indexOf(" ")); + let tTags = this._getTags(sInfi); + let aSugg = new Set(); + if (sMorph.includes(":Q") || sMorph.includes(":Y")) { + // we suggest conjugated forms + if (sMorph.includes(":V1")) { + aSugg.add(sInfi); + aSugg.add(this._getConjWithTags(sInfi, tTags, ":Ip", ":3s")); + aSugg.add(this._getConjWithTags(sInfi, tTags, ":Ip", ":2p")); + aSugg.add(this._getConjWithTags(sInfi, tTags, ":Iq", ":1s")); + aSugg.add(this._getConjWithTags(sInfi, tTags, ":Iq", ":3s")); + aSugg.add(this._getConjWithTags(sInfi, tTags, ":Iq", ":3p")); + } else if (sMorph.includes(":V2")) { + aSugg.add(this._getConjWithTags(sInfi, tTags, ":Ip", ":1s")); + aSugg.add(this._getConjWithTags(sInfi, tTags, ":Ip", ":3s")); + } else if (sMorph.includes(":V3")) { + aSugg.add(this._getConjWithTags(sInfi, tTags, ":Ip", ":1s")); + aSugg.add(this._getConjWithTags(sInfi, tTags, ":Ip", ":3s")); + aSugg.add(this._getConjWithTags(sInfi, tTags, ":Is", ":1s")); + aSugg.add(this._getConjWithTags(sInfi, tTags, ":Is", ":3s")); + } else if (isMorph.includes(":V0a")) { + aSugg.add("eus"); + aSugg.add("eut"); + } else { + aSugg.add("étais"); + aSugg.add("était"); + } + aSugg.delete(""); + } else { + // we suggest past participles + aSugg.add(this._getConjWithTags(sInfi, tTags, ":PQ", ":Q1")); + aSugg.add(this._getConjWithTags(sInfi, tTags, ":PQ", ":Q2")); + aSugg.add(this._getConjWithTags(sInfi, tTags, ":PQ", ":Q3")); + aSugg.add(this._getConjWithTags(sInfi, tTags, ":PQ", ":Q4")); + aSugg.delete(""); + // if there is only one past participle (epi inv), unreliable. + if (aSugg.size === 1) { + aSugg.clear(); + } + if (sMorph.includes(":V1")) { + aSugg.add(sInfi); + } + } + return aSugg; + }, + + _getTags: function (sVerb) { + // returns tuple of tags (usable with functions _getConjWithTags and _hasConjWithTags) + if (!this._dVerb.hasOwnProperty(sVerb)) { + return null; + } + return this._lTags[this._dVerb[sVerb][1]]; + }, + + _getConjWithTags: function (sVerb, tTags, sTense, sWho) { + // returns conjugation (can be an empty string) + if (!this._dPatternConj[sTense][tTags[this._dTenseIdx.get(sTense)]].hasOwnProperty(sWho)) { + return ""; + } + return this._modifyStringWithSuffixCode(sVerb, this._dPatternConj[sTense][tTags[this._dTenseIdx.get(sTense)]][sWho]); + }, + + _hasConjWithTags: function (tTags, sTense, sWho) { + // returns false if no conjugation (also if empty) else true + if (this._dPatternConj[sTense][tTags[this._dTenseIdx.get(sTense)]].hasOwnProperty(sWho) + && this._dPatternConj[sTense][tTags[this._dTenseIdx.get(sTense)]][sWho]) { + return true; + } + return false; + }, + + _modifyStringWithSuffixCode: function (sWord, sSfx) { + // returns sWord modified by sSfx + if (sSfx === "") { + return ""; + } + if (sSfx === "0") { + return sWord; + } + try { + if (sSfx[0] !== '0') { + return sWord.slice(0, -(sSfx.charCodeAt(0)-48)) + sSfx.slice(1); // 48 is the ASCII code for "0" + } else { + return sWord + sSfx.slice(1); + } + } + catch (e) { + console.log(e); + return "## erreur, code : " + sSfx + " ##"; + } } } class Verb { @@ -191,107 +181,107 @@ if (typeof sVerb !== "string" || sVerb === "") { throw new TypeError ("The value should be a non-empty string"); } this.sVerb = sVerb; this.sVerbAux = ""; - this._sRawInfo = getVtyp(this.sVerb); + this._sRawInfo = conj.getVtyp(this.sVerb); this.sInfo = this._readableInfo(this._sRawInfo); - this._tTags = _getTags(sVerb); - this._tTagsAux = _getTags(this.sVerbAux); + this._tTags = conj._getTags(sVerb); + this._tTagsAux = conj._getTags(this.sVerbAux); this.bProWithEn = (this._sRawInfo[5] === "e"); this.dConj = new Map ([ [":Y", new Map ([ ["label", "Infinitif"], [":Y", sVerb] ])], [":PQ", new Map ([ ["label", "Participes passés et présent"], - [":Q1", _getConjWithTags(sVerb, this._tTags, ":PQ", ":Q1")], - [":Q2", _getConjWithTags(sVerb, this._tTags, ":PQ", ":Q2")], - [":Q3", _getConjWithTags(sVerb, this._tTags, ":PQ", ":Q3")], - [":Q4", _getConjWithTags(sVerb, this._tTags, ":PQ", ":Q4")], - [":P", _getConjWithTags(sVerb, this._tTags, ":PQ", ":P")] + [":Q1", conj._getConjWithTags(sVerb, this._tTags, ":PQ", ":Q1")], + [":Q2", conj._getConjWithTags(sVerb, this._tTags, ":PQ", ":Q2")], + [":Q3", conj._getConjWithTags(sVerb, this._tTags, ":PQ", ":Q3")], + [":Q4", conj._getConjWithTags(sVerb, this._tTags, ":PQ", ":Q4")], + [":P", conj._getConjWithTags(sVerb, this._tTags, ":PQ", ":P")] ])], [":Ip", new Map ([ ["label", "Présent"], - [":1s", _getConjWithTags(sVerb, this._tTags, ":Ip", ":1s")], - [":1ś", _getConjWithTags(sVerb, this._tTags, ":Ip", ":1ś")], - [":2s", _getConjWithTags(sVerb, this._tTags, ":Ip", ":2s")], - [":3s", _getConjWithTags(sVerb, this._tTags, ":Ip", ":3s")], - [":1p", _getConjWithTags(sVerb, this._tTags, ":Ip", ":1p")], - [":2p", _getConjWithTags(sVerb, this._tTags, ":Ip", ":2p")], - [":3p", _getConjWithTags(sVerb, this._tTags, ":Ip", ":3p")] + [":1s", conj._getConjWithTags(sVerb, this._tTags, ":Ip", ":1s")], + [":1ś", conj._getConjWithTags(sVerb, this._tTags, ":Ip", ":1ś")], + [":2s", conj._getConjWithTags(sVerb, this._tTags, ":Ip", ":2s")], + [":3s", conj._getConjWithTags(sVerb, this._tTags, ":Ip", ":3s")], + [":1p", conj._getConjWithTags(sVerb, this._tTags, ":Ip", ":1p")], + [":2p", conj._getConjWithTags(sVerb, this._tTags, ":Ip", ":2p")], + [":3p", conj._getConjWithTags(sVerb, this._tTags, ":Ip", ":3p")] ])], [":Iq", new Map ([ ["label", "Imparfait"], - [":1s", _getConjWithTags(sVerb, this._tTags, ":Iq", ":1s")], - [":2s", _getConjWithTags(sVerb, this._tTags, ":Iq", ":2s")], - [":3s", _getConjWithTags(sVerb, this._tTags, ":Iq", ":3s")], - [":1p", _getConjWithTags(sVerb, this._tTags, ":Iq", ":1p")], - [":2p", _getConjWithTags(sVerb, this._tTags, ":Iq", ":2p")], - [":3p", _getConjWithTags(sVerb, this._tTags, ":Iq", ":3p")] + [":1s", conj._getConjWithTags(sVerb, this._tTags, ":Iq", ":1s")], + [":2s", conj._getConjWithTags(sVerb, this._tTags, ":Iq", ":2s")], + [":3s", conj._getConjWithTags(sVerb, this._tTags, ":Iq", ":3s")], + [":1p", conj._getConjWithTags(sVerb, this._tTags, ":Iq", ":1p")], + [":2p", conj._getConjWithTags(sVerb, this._tTags, ":Iq", ":2p")], + [":3p", conj._getConjWithTags(sVerb, this._tTags, ":Iq", ":3p")] ])], [":Is", new Map ([ ["label", "Passé simple"], - [":1s", _getConjWithTags(sVerb, this._tTags, ":Is", ":1s")], - [":2s", _getConjWithTags(sVerb, this._tTags, ":Is", ":2s")], - [":3s", _getConjWithTags(sVerb, this._tTags, ":Is", ":3s")], - [":1p", _getConjWithTags(sVerb, this._tTags, ":Is", ":1p")], - [":2p", _getConjWithTags(sVerb, this._tTags, ":Is", ":2p")], - [":3p", _getConjWithTags(sVerb, this._tTags, ":Is", ":3p")] + [":1s", conj._getConjWithTags(sVerb, this._tTags, ":Is", ":1s")], + [":2s", conj._getConjWithTags(sVerb, this._tTags, ":Is", ":2s")], + [":3s", conj._getConjWithTags(sVerb, this._tTags, ":Is", ":3s")], + [":1p", conj._getConjWithTags(sVerb, this._tTags, ":Is", ":1p")], + [":2p", conj._getConjWithTags(sVerb, this._tTags, ":Is", ":2p")], + [":3p", conj._getConjWithTags(sVerb, this._tTags, ":Is", ":3p")] ])], [":If", new Map ([ ["label", "Futur"], - [":1s", _getConjWithTags(sVerb, this._tTags, ":If", ":1s")], - [":2s", _getConjWithTags(sVerb, this._tTags, ":If", ":2s")], - [":3s", _getConjWithTags(sVerb, this._tTags, ":If", ":3s")], - [":1p", _getConjWithTags(sVerb, this._tTags, ":If", ":1p")], - [":2p", _getConjWithTags(sVerb, this._tTags, ":If", ":2p")], - [":3p", _getConjWithTags(sVerb, this._tTags, ":If", ":3p")] + [":1s", conj._getConjWithTags(sVerb, this._tTags, ":If", ":1s")], + [":2s", conj._getConjWithTags(sVerb, this._tTags, ":If", ":2s")], + [":3s", conj._getConjWithTags(sVerb, this._tTags, ":If", ":3s")], + [":1p", conj._getConjWithTags(sVerb, this._tTags, ":If", ":1p")], + [":2p", conj._getConjWithTags(sVerb, this._tTags, ":If", ":2p")], + [":3p", conj._getConjWithTags(sVerb, this._tTags, ":If", ":3p")] ])], [":Sp", new Map ([ ["label", "Présent subjonctif"], - [":1s", _getConjWithTags(sVerb, this._tTags, ":Sp", ":1s")], - [":1ś", _getConjWithTags(sVerb, this._tTags, ":Sp", ":1ś")], - [":2s", _getConjWithTags(sVerb, this._tTags, ":Sp", ":2s")], - [":3s", _getConjWithTags(sVerb, this._tTags, ":Sp", ":3s")], - [":1p", _getConjWithTags(sVerb, this._tTags, ":Sp", ":1p")], - [":2p", _getConjWithTags(sVerb, this._tTags, ":Sp", ":2p")], - [":3p", _getConjWithTags(sVerb, this._tTags, ":Sp", ":3p")] + [":1s", conj._getConjWithTags(sVerb, this._tTags, ":Sp", ":1s")], + [":1ś", conj._getConjWithTags(sVerb, this._tTags, ":Sp", ":1ś")], + [":2s", conj._getConjWithTags(sVerb, this._tTags, ":Sp", ":2s")], + [":3s", conj._getConjWithTags(sVerb, this._tTags, ":Sp", ":3s")], + [":1p", conj._getConjWithTags(sVerb, this._tTags, ":Sp", ":1p")], + [":2p", conj._getConjWithTags(sVerb, this._tTags, ":Sp", ":2p")], + [":3p", conj._getConjWithTags(sVerb, this._tTags, ":Sp", ":3p")] ])], [":Sq", new Map ([ ["label", "Imparfait subjonctif"], - [":1s", _getConjWithTags(sVerb, this._tTags, ":Sq", ":1s")], - [":1ś", _getConjWithTags(sVerb, this._tTags, ":Sq", ":1ś")], - [":2s", _getConjWithTags(sVerb, this._tTags, ":Sq", ":2s")], - [":3s", _getConjWithTags(sVerb, this._tTags, ":Sq", ":3s")], - [":1p", _getConjWithTags(sVerb, this._tTags, ":Sq", ":1p")], - [":2p", _getConjWithTags(sVerb, this._tTags, ":Sq", ":2p")], - [":3p", _getConjWithTags(sVerb, this._tTags, ":Sq", ":3p")] + [":1s", conj._getConjWithTags(sVerb, this._tTags, ":Sq", ":1s")], + [":1ś", conj._getConjWithTags(sVerb, this._tTags, ":Sq", ":1ś")], + [":2s", conj._getConjWithTags(sVerb, this._tTags, ":Sq", ":2s")], + [":3s", conj._getConjWithTags(sVerb, this._tTags, ":Sq", ":3s")], + [":1p", conj._getConjWithTags(sVerb, this._tTags, ":Sq", ":1p")], + [":2p", conj._getConjWithTags(sVerb, this._tTags, ":Sq", ":2p")], + [":3p", conj._getConjWithTags(sVerb, this._tTags, ":Sq", ":3p")] ])], [":K", new Map ([ ["label", "Conditionnel"], - [":1s", _getConjWithTags(sVerb, this._tTags, ":K", ":1s")], - [":2s", _getConjWithTags(sVerb, this._tTags, ":K", ":2s")], - [":3s", _getConjWithTags(sVerb, this._tTags, ":K", ":3s")], - [":1p", _getConjWithTags(sVerb, this._tTags, ":K", ":1p")], - [":2p", _getConjWithTags(sVerb, this._tTags, ":K", ":2p")], - [":3p", _getConjWithTags(sVerb, this._tTags, ":K", ":3p")] + [":1s", conj._getConjWithTags(sVerb, this._tTags, ":K", ":1s")], + [":2s", conj._getConjWithTags(sVerb, this._tTags, ":K", ":2s")], + [":3s", conj._getConjWithTags(sVerb, this._tTags, ":K", ":3s")], + [":1p", conj._getConjWithTags(sVerb, this._tTags, ":K", ":1p")], + [":2p", conj._getConjWithTags(sVerb, this._tTags, ":K", ":2p")], + [":3p", conj._getConjWithTags(sVerb, this._tTags, ":K", ":3p")] ])], [":E", new Map ([ ["label", "Impératif"], - [":2s", _getConjWithTags(sVerb, this._tTags, ":E", ":2s")], - [":1p", _getConjWithTags(sVerb, this._tTags, ":E", ":1p")], - [":2p", _getConjWithTags(sVerb, this._tTags, ":E", ":2p")] + [":2s", conj._getConjWithTags(sVerb, this._tTags, ":E", ":2s")], + [":1p", conj._getConjWithTags(sVerb, this._tTags, ":E", ":1p")], + [":2p", conj._getConjWithTags(sVerb, this._tTags, ":E", ":2p")] ])] ]); }; _readableInfo () { // returns readable infos this.sVerbAux = (this._sRawInfo.slice(7,8) == "e") ? "être" : "avoir"; - let sGroup = _dGroup.get(this._sRawInfo[0]); + let sGroup = conj._dGroup.get(this._sRawInfo[0]); let sInfo = ""; if (this._sRawInfo.slice(3,4) == "t") { sInfo = "transitif"; } else if (this._sRawInfo.slice(4,5) == "n") { sInfo = "transitif indirect"; @@ -323,11 +313,11 @@ } if (bPro) { if (this.bProWithEn) { sInfi = "s’en " + sInfi; } else { - sInfi = (_zStartVoy.test(sInfi)) ? "s’" + sInfi : "se " + sInfi; + sInfi = (conj._zStartVoy.test(sInfi)) ? "s’" + sInfi : "se " + sInfi; } } if (bNeg) { sInfi = "ne pas " + sInfi; } @@ -348,18 +338,18 @@ if (!this.dConj.get(":PQ").get(":P")) { return ""; } let sPartPre; if (bTpsCo) { - sPartPre = (!bPro) ? _getConjWithTags(this.sVerbAux, this._tTagsAux, ":PQ", ":P") : getConj("être", ":PQ", ":P"); + sPartPre = (!bPro) ? conj._getConjWithTags(this.sVerbAux, this._tTagsAux, ":PQ", ":P") : getConj("être", ":PQ", ":P"); } else { sPartPre = this.dConj.get(":PQ").get(":P"); } if (sPartPre === "") { return ""; } - let bEli = _zStartVoy.test(sPartPre); + let bEli = conj._zStartVoy.test(sPartPre); if (bPro) { if (this.bProWithEn) { sPartPre = "s’en " + sPartPre; } else { sPartPre = (bEli) ? "s’" + sPartPre : "se " + sPartPre; @@ -384,30 +374,30 @@ let sConj; if (!bTpsCo && bInt && sWho == ":1s" && this.dConj.get(sTemps).gl_get(":1ś", false)) { sWho = ":1ś"; } if (bTpsCo) { - sConj = (!bPro) ? _getConjWithTags(this.sVerbAux, this._tTagsAux, sTemps, sWho) : getConj("être", sTemps, sWho); + sConj = (!bPro) ? conj._getConjWithTags(this.sVerbAux, this._tTagsAux, sTemps, sWho) : getConj("être", sTemps, sWho); } else { sConj = this.dConj.get(sTemps).get(sWho); } if (sConj === "") { return ""; } - let bEli = _zStartVoy.test(sConj); + let bEli = conj._zStartVoy.test(sConj); if (bPro) { if (!this.bProWithEn) { - sConj = (bEli) ? _dProObjEl.get(sWho) + sConj : _dProObj.get(sWho) + sConj; + sConj = (bEli) ? conj._dProObjEl.get(sWho) + sConj : conj._dProObj.get(sWho) + sConj; } else { - sConj = _dProObjEl.get(sWho) + "en " + sConj; + sConj = conj._dProObjEl.get(sWho) + "en " + sConj; } } if (bNeg) { sConj = (bEli && !bPro) ? "n’" + sConj : "ne " + sConj; } if (bInt) { - if (sWho == ":3s" && !_zNeedTeuph.test(sConj)) { + if (sWho == ":3s" && !conj._zNeedTeuph.test(sConj)) { sConj += "-t"; } sConj += "-" + this._getPronom(sWho, bFem); } else { if (sWho == ":1s" && bEli && !bNeg && !bPro) { @@ -436,39 +426,39 @@ return "elle"; } } else if (sWho == ":3p" && bFem) { return "elles"; } - return _dProSuj.get(sWho); + return conj._dProSuj.get(sWho); }; imperatif (sWho, bPro, bNeg, bTpsCo, bFem) { if (!this.dConj.get(":E").get(sWho)) { return ""; } let sImpe; if (bTpsCo) { - sImpe = (!bPro) ? _getConjWithTags(this.sVerbAux, this._tTagsAux, ":E", sWho) : getConj("être", ":E", sWho); + sImpe = (!bPro) ? conj._getConjWithTags(this.sVerbAux, this._tTagsAux, ":E", sWho) : getConj("être", ":E", sWho); } else { sImpe = this.dConj.get(":E").get(sWho); } if (sImpe === "") { return ""; } - let bEli = _zStartVoy.test(sImpe); + let bEli = conj._zStartVoy.test(sImpe); if (bNeg) { if (bPro) { if (!this.bProWithEn) { - sImpe = (bEli && sWho == ":2s") ? "ne t’" + sImpe + " pas" : _dImpeProNeg.get(sWho) + sImpe + " pas"; + sImpe = (bEli && sWho == ":2s") ? "ne t’" + sImpe + " pas" : conj._dImpeProNeg.get(sWho) + sImpe + " pas"; } else { - sImpe = _dImpeProNegEn.get(sWho) + sImpe + " pas"; + sImpe = conj._dImpeProNegEn.get(sWho) + sImpe + " pas"; } } else { sImpe = (bEli) ? "n’" + sImpe + " pas" : "ne " + sImpe + " pas"; } } else if (bPro) { - sImpe = (this.bProWithEn) ? sImpe + _dImpeProEn.get(sWho) : sImpe + _dImpePro.get(sWho); + sImpe = (this.bProWithEn) ? sImpe + conj._dImpeProEn.get(sWho) : sImpe + conj._dImpePro.get(sWho); } if (bTpsCo) { return sImpe + " " + this._seekPpas(bPro, bFem, sWho.endsWith("p") || this._sRawInfo[5] == "r"); } return sImpe; @@ -488,17 +478,45 @@ } } if (typeof(exports) !== 'undefined') { - // Used for Grammalecte library. - // In content scripts, these variable are directly reachable + // used within Grammalecte library + let helpers = require("resource://grammalecte/helpers.js"); + conj.init(helpers.loadFile("resource://grammalecte/fr/conj_data.json")); +} else { + // used within Firefox content script (conjugation panel). + // can’t load JSON from here, so we do it in ui.js and send it here. + self.port.on("provideConjData", function (sJSONData) { + conj.init(sJSONData); + }); +} + + +if (typeof(exports) !== 'undefined') { + exports._lVtyp = conj._lVtyp; + exports._lTags = conj._lTags; + exports._dPatternConj = conj._dPatternConj; + exports._dVerb = conj._dVerb; + exports.init = conj.init; + exports._zStartVoy = conj._zStartVoy; + exports._zNeedTeuph = conj._zNeedTeuph; + exports._dProSuj = conj._dProSuj; + exports._dProObj = conj._dProObj; + exports._dProObjEl = conj._dProObjEl; + exports._dImpePro = conj._dImpePro; + exports._dImpeProNeg = conj._dImpeProNeg; + exports._dImpeProEn = conj._dImpeProEn; + exports._dImpeProNegEn = conj._dImpeProNegEn; + exports._dGroup = conj._dGroup; + exports._dTenseIdx = conj._dTenseIdx; + exports.isVerb = conj.isVerb; + exports.getConj = conj.getConj; + exports.hasConj = conj.hasConj; + exports.getVtyp = conj.getVtyp; + exports.getSimil = conj.getSimil; + exports._getTags = conj._getTags; + exports._getConjWithTags = conj._getConjWithTags; + exports._hasConjWithTags = conj._hasConjWithTags; + exports._modifyStringWithSuffixCode = conj._modifyStringWithSuffixCode; exports.Verb = Verb; - exports.isVerb = isVerb; - exports.getConj = getConj; - exports.hasConj = hasConj; - exports.getVtyp = getVtyp; - exports.getSimil = getSimil; - exports._getTags = _getTags; - exports._hasConjWithTags = _hasConjWithTags; - exports._getConjWithTags = _getConjWithTags; } Index: gc_lang/fr/modules-js/cregex.js ================================================================== --- gc_lang/fr/modules-js/cregex.js +++ gc_lang/fr/modules-js/cregex.js @@ -1,301 +1,348 @@ //// Grammalecte - Compiled regular expressions -///// Lemme -const zLemma = new RegExp("^>([a-zà-öø-ÿ0-9Ā-ʯ][a-zà-öø-ÿ0-9Ā-ʯ-]+)"); - -///// Masculin / féminin / singulier / pluriel -const zGender = new RegExp(":[mfe]"); -const zNumber = new RegExp(":[spi]"); - -///// Nom et adjectif -const zNA = new RegExp(":[NA]"); - -//// nombre -const zNAs = new RegExp(":[NA].*:s"); -const zNAp = new RegExp(":[NA].*:p"); -const zNAi = new RegExp(":[NA].*:i"); -const zNAsi = new RegExp(":[NA].*:[si]"); -const zNApi = new RegExp(":[NA].*:[pi]"); - -//// genre -const zNAm = new RegExp(":[NA].*:m"); -const zNAf = new RegExp(":[NA].*:f"); -const zNAe = new RegExp(":[NA].*:e"); -const zNAme = new RegExp(":[NA].*:[me]"); -const zNAfe = new RegExp(":[NA].*:[fe]"); - -//// nombre et genre -// singuilier -const zNAms = new RegExp(":[NA].*:m.*:s"); -const zNAfs = new RegExp(":[NA].*:f.*:s"); -const zNAes = new RegExp(":[NA].*:e.*:s"); -const zNAmes = new RegExp(":[NA].*:[me].*:s"); -const zNAfes = new RegExp(":[NA].*:[fe].*:s"); - -// singulier et invariable -const zNAmsi = new RegExp(":[NA].*:m.*:[si]"); -const zNAfsi = new RegExp(":[NA].*:f.*:[si]"); -const zNAesi = new RegExp(":[NA].*:e.*:[si]"); -const zNAmesi = new RegExp(":[NA].*:[me].*:[si]"); -const zNAfesi = new RegExp(":[NA].*:[fe].*:[si]"); - -// pluriel -const zNAmp = new RegExp(":[NA].*:m.*:p"); -const zNAfp = new RegExp(":[NA].*:f.*:p"); -const zNAep = new RegExp(":[NA].*:e.*:p"); -const zNAmep = new RegExp(":[NA].*:[me].*:p"); -const zNAfep = new RegExp(":[NA].*:[me].*:p"); - -// pluriel et invariable -const zNAmpi = new RegExp(":[NA].*:m.*:[pi]"); -const zNAfpi = new RegExp(":[NA].*:f.*:[pi]"); -const zNAepi = new RegExp(":[NA].*:e.*:[pi]"); -const zNAmepi = new RegExp(":[NA].*:[me].*:[pi]"); -const zNAfepi = new RegExp(":[NA].*:[fe].*:[pi]"); - -//// Divers -const zAD = new RegExp(":[AB]"); - -///// Verbe -const zVconj = new RegExp(":[123][sp]"); -const zVconj123 = new RegExp(":V[123].*:[123][sp]"); - -///// Nom | Adjectif | Verbe -const zNVconj = new RegExp(":(?:N|[123][sp])"); -const zNAVconj = new RegExp(":(?:N|A|[123][sp])"); - -///// Spécifique -const zNnotA = new RegExp(":N(?!:A)"); -const zPNnotA = new RegExp(":(?:N(?!:A)|Q)"); - -///// Noms propres -const zNP = new RegExp(":(?:M[12P]|T)"); -const zNPm = new RegExp(":(?:M[12P]|T):m"); -const zNPf = new RegExp(":(?:M[12P]|T):f"); -const zNPe = new RegExp(":(?:M[12P]|T):e"); - - -///// FONCTIONS - -function getLemmaOfMorph (sMorph) { - return zLemma.exec(sMorph)[1]; -} - -function checkAgreement (l1, l2) { - // check number agreement - if (!mbInv(l1) && !mbInv(l2)) { - if (mbSg(l1) && !mbSg(l2)) { - return false; - } - if (mbPl(l1) && !mbPl(l2)) { - return false; - } - } - // check gender agreement - if (mbEpi(l1) || mbEpi(l2)) { - return true; - } - if (mbMas(l1) && !mbMas(l2)) { - return false; - } - if (mbFem(l1) && !mbFem(l2)) { - return false; - } - return true; -} - -function checkConjVerb (lMorph, sReqConj) { - return lMorph.some(s => s.includes(sReqConj)); -} - -function getGender (lMorph) { - // returns gender of word (':m', ':f', ':e' or empty string). - let sGender = ""; - for (let sMorph of lMorph) { - let m = zGender.exec(sMorph); - if (m) { - if (!sGender) { - sGender = m[0]; - } else if (sGender != m[0]) { - return ":e"; - } - } - } - return sGender; -} - -function getNumber (lMorph) { - // returns number of word (':s', ':p', ':i' or empty string). - let sNumber = ""; - for (let sMorph of lMorph) { - let m = zNumber.exec(sWord); - if (m) { - if (!sNumber) { - sNumber = m[0]; - } else if (sNumber != m[0]) { - return ":i"; - } - } - } - return sNumber; -} - -// NOTE : isWhat (lMorph) returns true if lMorph contains nothing else than What -// mbWhat (lMorph) returns true if lMorph contains What at least once - -//// isXXX = it’s certain - -function isNom (lMorph) { - return lMorph.every(s => s.includes(":N")); -} - -function isNomNotAdj (lMorph) { - return lMorph.every(s => zNnotA.test(s)); -} - -function isAdj (lMorph) { - return lMorph.every(s => s.includes(":A")); -} - -function isNomAdj (lMorph) { - return lMorph.every(s => zNA.test(s)); -} - -function isNomVconj (lMorph) { - return lMorph.every(s => zNVconj.test(s)); -} - -function isInv (lMorph) { - return lMorph.every(s => s.includes(":i")); -} -function isSg (lMorph) { - return lMorph.every(s => s.includes(":s")); -} -function isPl (lMorph) { - return lMorph.every(s => s.includes(":p")); -} -function isEpi (lMorph) { - return lMorph.every(s => s.includes(":e")); -} -function isMas (lMorph) { - return lMorph.every(s => s.includes(":m")); -} -function isFem (lMorph) { - return lMorph.every(s => s.includes(":f")); -} - - -//// mbXXX = MAYBE XXX - -function mbNom (lMorph) { - return lMorph.some(s => s.includes(":N")); -} - -function mbAdj (lMorph) { - return lMorph.some(s => s.includes(":A")); -} - -function mbAdjNb (lMorph) { - return lMorph.some(s => zAD.test(s)); -} - -function mbNomAdj (lMorph) { - return lMorph.some(s => zNA.test(s)); -} - -function mbNomNotAdj (lMorph) { - let b = false; - for (let s of lMorph) { - if (s.includes(":A")) { - return false; - } - if (s.includes(":N")) { - b = true; - } - } - return b; -} - -function mbPpasNomNotAdj (lMorph) { - return lMorph.some(s => zPNnotA.test(s)); -} - -function mbVconj (lMorph) { - return lMorph.some(s => zVconj.test(s)); -} - -function mbVconj123 (lMorph) { - return lMorph.some(s => zVconj123.test(s)); -} - -function mbMG (lMorph) { - return lMorph.some(s => s.includes(":G")); -} - -function mbInv (lMorph) { - return lMorph.some(s => s.includes(":i")); -} -function mbSg (lMorph) { - return lMorph.some(s => s.includes(":s")); -} -function mbPl (lMorph) { - return lMorph.some(s => s.includes(":p")); -} -function mbEpi (lMorph) { - return lMorph.some(s => s.includes(":e")); -} -function mbMas (lMorph) { - return lMorph.some(s => s.includes(":m")); -} -function mbFem (lMorph) { - return lMorph.some(s => s.includes(":f")); -} - -function mbNpr (lMorph) { - return lMorph.some(s => zNP.test(s)); -} - -function mbNprMasNotFem (lMorph) { - if (lMorph.some(s => zNPf.test(s))) { - return false; - } - return lMorph.some(s => zNPm.test(s)); +var cregex = { + ///// Lemme + _zLemma: new RegExp(">([a-zà-öø-ÿ0-9Ā-ʯ][a-zà-öø-ÿ0-9Ā-ʯ-]+)"), + + ///// Masculin / féminin / singulier / pluriel + _zGender: new RegExp(":[mfe]"), + _zNumber: new RegExp(":[spi]"), + + ///// Nom et adjectif + _zNA: new RegExp(":[NA]"), + + //// nombre + _zNAs: new RegExp(":[NA].*:s"), + _zNAp: new RegExp(":[NA].*:p"), + _zNAi: new RegExp(":[NA].*:i"), + _zNAsi: new RegExp(":[NA].*:[si]"), + _zNApi: new RegExp(":[NA].*:[pi]"), + + //// genre + _zNAm: new RegExp(":[NA].*:m"), + _zNAf: new RegExp(":[NA].*:f"), + _zNAe: new RegExp(":[NA].*:e"), + _zNAme: new RegExp(":[NA].*:[me]"), + _zNAfe: new RegExp(":[NA].*:[fe]"), + + //// nombre et genre + // singuilier + _zNAms: new RegExp(":[NA].*:m.*:s"), + _zNAfs: new RegExp(":[NA].*:f.*:s"), + _zNAes: new RegExp(":[NA].*:e.*:s"), + _zNAmes: new RegExp(":[NA].*:[me].*:s"), + _zNAfes: new RegExp(":[NA].*:[fe].*:s"), + + // singulier et invariable + _zNAmsi: new RegExp(":[NA].*:m.*:[si]"), + _zNAfsi: new RegExp(":[NA].*:f.*:[si]"), + _zNAesi: new RegExp(":[NA].*:e.*:[si]"), + _zNAmesi: new RegExp(":[NA].*:[me].*:[si]"), + _zNAfesi: new RegExp(":[NA].*:[fe].*:[si]"), + + // pluriel + _zNAmp: new RegExp(":[NA].*:m.*:p"), + _zNAfp: new RegExp(":[NA].*:f.*:p"), + _zNAep: new RegExp(":[NA].*:e.*:p"), + _zNAmep: new RegExp(":[NA].*:[me].*:p"), + _zNAfep: new RegExp(":[NA].*:[me].*:p"), + + // pluriel et invariable + _zNAmpi: new RegExp(":[NA].*:m.*:[pi]"), + _zNAfpi: new RegExp(":[NA].*:f.*:[pi]"), + _zNAepi: new RegExp(":[NA].*:e.*:[pi]"), + _zNAmepi: new RegExp(":[NA].*:[me].*:[pi]"), + _zNAfepi: new RegExp(":[NA].*:[fe].*:[pi]"), + + //// Divers + _zAD: new RegExp(":[AB]"), + + ///// Verbe + _zVconj: new RegExp(":[123][sp]"), + _zVconj123: new RegExp(":V[123].*:[123][sp]"), + + ///// Nom | Adjectif | Verbe + _zNVconj: new RegExp(":(?:N|[123][sp])"), + _zNAVconj: new RegExp(":(?:N|A|[123][sp])"), + + ///// Spécifique + _zNnotA: new RegExp(":N(?!:A)"), + _zPNnotA: new RegExp(":(?:N(?!:A)|Q)"), + + ///// Noms propres + _zNP: new RegExp(":(?:M[12P]|T)"), + _zNPm: new RegExp(":(?:M[12P]|T):m"), + _zNPf: new RegExp(":(?:M[12P]|T):f"), + _zNPe: new RegExp(":(?:M[12P]|T):e"), + + + ///// FONCTIONS + + getLemmaOfMorph: function (sMorph) { + return this._zLemma.exec(sMorph)[1]; + }, + + checkAgreement: function (l1, l2) { + // check number agreement + if (!this.mbInv(l1) && !this.mbInv(l2)) { + if (this.mbSg(l1) && !this.mbSg(l2)) { + return false; + } + if (this.mbPl(l1) && !this.mbPl(l2)) { + return false; + } + } + // check gender agreement + if (this.mbEpi(l1) || this.mbEpi(l2)) { + return true; + } + if (this.mbMas(l1) && !this.mbMas(l2)) { + return false; + } + if (this.mbFem(l1) && !this.mbFem(l2)) { + return false; + } + return true; + }, + + checkConjVerb: function (lMorph, sReqConj) { + return lMorph.some(s => s.includes(sReqConj)); + }, + + getGender: function (lMorph) { + // returns gender of word (':m', ':f', ':e' or empty string). + let sGender = ""; + for (let sMorph of lMorph) { + let m = this._zGender.exec(sMorph); + if (m) { + if (!sGender) { + sGender = m[0]; + } else if (sGender != m[0]) { + return ":e"; + } + } + } + return sGender; + }, + + getNumber: function (lMorph) { + // returns number of word (':s', ':p', ':i' or empty string). + let sNumber = ""; + for (let sMorph of lMorph) { + let m = this._zNumber.exec(sWord); + if (m) { + if (!sNumber) { + sNumber = m[0]; + } else if (sNumber != m[0]) { + return ":i"; + } + } + } + return sNumber; + }, + + // NOTE : isWhat (lMorph) returns true if lMorph contains nothing else than What + // mbWhat (lMorph) returns true if lMorph contains What at least once + + //// isXXX = it’s certain + + isNom: function (lMorph) { + return lMorph.every(s => s.includes(":N")); + }, + + isNomNotAdj: function (lMorph) { + return lMorph.every(s => this._zNnotA.test(s)); + }, + + isAdj: function (lMorph) { + return lMorph.every(s => s.includes(":A")); + }, + + isNomAdj: function (lMorph) { + return lMorph.every(s => this._zNA.test(s)); + }, + + isNomVconj: function (lMorph) { + return lMorph.every(s => this._zNVconj.test(s)); + }, + + isInv: function (lMorph) { + return lMorph.every(s => s.includes(":i")); + }, + isSg: function (lMorph) { + return lMorph.every(s => s.includes(":s")); + }, + isPl: function (lMorph) { + return lMorph.every(s => s.includes(":p")); + }, + isEpi: function (lMorph) { + return lMorph.every(s => s.includes(":e")); + }, + isMas: function (lMorph) { + return lMorph.every(s => s.includes(":m")); + }, + isFem: function (lMorph) { + return lMorph.every(s => s.includes(":f")); + }, + + + //// mbXXX = MAYBE XXX + + mbNom: function (lMorph) { + return lMorph.some(s => s.includes(":N")); + }, + + mbAdj: function (lMorph) { + return lMorph.some(s => s.includes(":A")); + }, + + mbAdjNb: function (lMorph) { + return lMorph.some(s => this._zAD.test(s)); + }, + + mbNomAdj: function (lMorph) { + return lMorph.some(s => this._zNA.test(s)); + }, + + mbNomNotAdj: function (lMorph) { + let b = false; + for (let s of lMorph) { + if (s.includes(":A")) { + return false; + } + if (s.includes(":N")) { + b = true; + } + } + return b; + }, + + mbPpasNomNotAdj: function (lMorph) { + return lMorph.some(s => this._zPNnotA.test(s)); + }, + + mbVconj: function (lMorph) { + return lMorph.some(s => this._zVconj.test(s)); + }, + + mbVconj123: function (lMorph) { + return lMorph.some(s => this._zVconj123.test(s)); + }, + + mbMG: function (lMorph) { + return lMorph.some(s => s.includes(":G")); + }, + + mbInv: function (lMorph) { + return lMorph.some(s => s.includes(":i")); + }, + mbSg: function (lMorph) { + return lMorph.some(s => s.includes(":s")); + }, + mbPl: function (lMorph) { + return lMorph.some(s => s.includes(":p")); + }, + mbEpi: function (lMorph) { + return lMorph.some(s => s.includes(":e")); + }, + mbMas: function (lMorph) { + return lMorph.some(s => s.includes(":m")); + }, + mbFem: function (lMorph) { + return lMorph.some(s => s.includes(":f")); + }, + + mbNpr: function (lMorph) { + return lMorph.some(s => this._zNP.test(s)); + }, + + mbNprMasNotFem: function (lMorph) { + if (lMorph.some(s => this._zNPf.test(s))) { + return false; + } + return lMorph.some(s => this._zNPm.test(s)); + } } if (typeof(exports) !== 'undefined') { - exports.getLemmaOfMorph = getLemmaOfMorph; - exports.checkAgreement = checkAgreement; - exports.checkConjVerb = checkConjVerb; - exports.getGender = getGender; - exports.getNumber = getNumber; - exports.isNom = isNom; - exports.isNomNotAdj = isNomNotAdj; - exports.isAdj = isAdj; - exports.isNomAdj = isNomAdj; - exports.isNomVconj = isNomVconj; - exports.isInv = isInv; - exports.isSg = isSg; - exports.isPl = isPl; - exports.isEpi = isEpi; - exports.isMas = isMas; - exports.isFem = isFem; - exports.mbNom = mbNom; - exports.mbAdj = mbAdj; - exports.mbAdjNb = mbAdjNb; - exports.mbNomAdj = mbNomAdj; - exports.mbNomNotAdj = mbNomNotAdj; - exports.mbPpasNomNotAdj = mbPpasNomNotAdj; - exports.mbVconj = mbVconj; - exports.mbVconj123 = mbVconj123; - exports.mbMG = mbMG; - exports.mbInv = mbInv; - exports.mbSg = mbSg; - exports.mbPl = mbPl; - exports.mbEpi = mbEpi; - exports.mbMas = mbMas; - exports.mbFem = mbFem; - exports.mbNpr = mbNpr; - exports.mbNprMasNotFem = mbNprMasNotFem; + exports._zLemma = cregex._zLemma; + exports._zGender = cregex._zGender; + exports._zNumber = cregex._zNumber; + exports._zNA = cregex._zNA; + exports._zNAs = cregex._zNAs; + exports._zNAp = cregex._zNAp; + exports._zNAi = cregex._zNAi; + exports._zNAsi = cregex._zNAsi; + exports._zNApi = cregex._zNApi; + exports._zNAm = cregex._zNAm; + exports._zNAf = cregex._zNAf; + exports._zNAe = cregex._zNAe; + exports._zNAme = cregex._zNAme; + exports._zNAfe = cregex._zNAfe; + exports._zNAms = cregex._zNAms; + exports._zNAfs = cregex._zNAfs; + exports._zNAes = cregex._zNAes; + exports._zNAmes = cregex._zNAmes; + exports._zNAfes = cregex._zNAfes; + exports._zNAmsi = cregex._zNAmsi; + exports._zNAfsi = cregex._zNAfsi; + exports._zNAesi = cregex._zNAesi; + exports._zNAmesi = cregex._zNAmesi; + exports._zNAfesi = cregex._zNAfesi; + exports._zNAmp = cregex._zNAmp; + exports._zNAfp = cregex._zNAfp; + exports._zNAep = cregex._zNAep; + exports._zNAmep = cregex._zNAmep; + exports._zNAfep = cregex._zNAfep; + exports._zNAmpi = cregex._zNAmpi; + exports._zNAfpi = cregex._zNAfpi; + exports._zNAepi = cregex._zNAepi; + exports._zNAmepi = cregex._zNAmepi; + exports._zNAfepi = cregex._zNAfepi; + exports._zAD = cregex._zAD; + exports._zVconj = cregex._zVconj; + exports._zVconj123 = cregex._zVconj123; + exports._zNVconj = cregex._zNVconj; + exports._zNAVconj = cregex._zNAVconj; + exports._zNnotA = cregex._zNnotA; + exports._zPNnotA = cregex._zPNnotA; + exports._zNP = cregex._zNP; + exports._zNPm = cregex._zNPm; + exports._zNPf = cregex._zNPf; + exports._zNPe = cregex._zNPe; + exports.getLemmaOfMorph = cregex.getLemmaOfMorph; + exports.checkAgreement = cregex.checkAgreement; + exports.checkConjVerb = cregex.checkConjVerb; + exports.getGender = cregex.getGender; + exports.getNumber = cregex.getNumber; + exports.isNom = cregex.isNom; + exports.isNomNotAdj = cregex.isNomNotAdj; + exports.isAdj = cregex.isAdj; + exports.isNomAdj = cregex.isNomAdj; + exports.isNomVconj = cregex.isNomVconj; + exports.isInv = cregex.isInv; + exports.isSg = cregex.isSg; + exports.isPl = cregex.isPl; + exports.isEpi = cregex.isEpi; + exports.isMas = cregex.isMas; + exports.isFem = cregex.isFem; + exports.mbNom = cregex.mbNom; + exports.mbAdj = cregex.mbAdj; + exports.mbAdjNb = cregex.mbAdjNb; + exports.mbNomAdj = cregex.mbNomAdj; + exports.mbNomNotAdj = cregex.mbNomNotAdj; + exports.mbPpasNomNotAdj = cregex.mbPpasNomNotAdj; + exports.mbVconj = cregex.mbVconj; + exports.mbVconj123 = cregex.mbVconj123; + exports.mbMG = cregex.mbMG; + exports.mbInv = cregex.mbInv; + exports.mbSg = cregex.mbSg; + exports.mbPl = cregex.mbPl; + exports.mbEpi = cregex.mbEpi; + exports.mbMas = cregex.mbMas; + exports.mbFem = cregex.mbFem; + exports.mbNpr = cregex.mbNpr; + exports.mbNprMasNotFem = cregex.mbNprMasNotFem; } Index: gc_lang/fr/modules-js/mfsp.js ================================================================== --- gc_lang/fr/modules-js/mfsp.js +++ gc_lang/fr/modules-js/mfsp.js @@ -1,87 +1,89 @@ // Grammalecte "use strict"; const helpers = require("resource://grammalecte/helpers.js"); -const echo = helpers.echo; -const oData = JSON.parse(helpers.loadFile("resource://grammalecte/fr/mfsp_data.json")); +const _oData = JSON.parse(helpers.loadFile("resource://grammalecte/fr/mfsp_data.json")); // list of affix codes -const _lTagMiscPlur = oData.lTagMiscPlur; -const _lTagMasForm = oData.lTagMasForm; +const _lTagMiscPlur = _oData.lTagMiscPlur; +const _lTagMasForm = _oData.lTagMasForm; // dictionary of words with uncommon plurals (-x, -ux, english, latin and italian plurals) and tags to generate them -const _dMiscPlur = helpers.objectToMap(oData.dMiscPlur); +const _dMiscPlur = helpers.objectToMap(_oData.dMiscPlur); // dictionary of feminine forms and tags to generate masculine forms (singular and plural) -const _dMasForm = helpers.objectToMap(oData.dMasForm); - - - -function isFemForm (sWord) { - // returns True if sWord exists in _dMasForm - return _dMasForm.has(sWord); -} - -function getMasForm (sWord, bPlur) { - // returns masculine form with feminine form - if (_dMasForm.has(sWord)) { - return [ for (sTag of _whatSuffixCodes(sWord, bPlur)) _modifyStringWithSuffixCode(sWord, sTag) ]; - } - return []; -} - -function hasMiscPlural (sWord) { - // returns True if sWord exists in dMiscPlur - return _dMiscPlur.has(sWord); -} - -function getMiscPlural (sWord) { - // returns plural form with singular form - if (_dMiscPlur.has(sWord)) { - return [ for (sTag of _lTagMiscPlur[_dMiscPlur.get(sWord)].split("|")) _modifyStringWithSuffixCode(sWord, sTag) ]; - } - return []; -} - -function _whatSuffixCodes (sWord, bPlur) { - // necessary only for dMasFW - let sSfx = _lTagMasForm[_dMasForm.get(sWord)]; - if (sSfx.includes("/")) { - if (bPlur) { - return sSfx.slice(sSfx.indexOf("/")+1).split("|"); - } - return sSfx.slice(0, sSfx.indexOf("/")).split("|"); - } - return sSfx.split("|"); -} - -function _modifyStringWithSuffixCode (sWord, sSfx) { - // returns sWord modified by sSfx - if (!sWord) { - return ""; - } - if (sSfx === "0") { - return sWord; - } - try { - if (sSfx[0] !== '0') { - return sWord.slice(0, -(sSfx.charCodeAt(0)-48)) + sSfx.slice(1); // 48 is the ASCII code for "0" - } else { - return sWord + sSfx.slice(1); - } - } - catch (e) { - console.log(e); - return "## erreur, code : " + sSfx + " ##"; +const _dMasForm = helpers.objectToMap(_oData.dMasForm); + + +var mfsp = { + isFemForm: function (sWord) { + // returns True if sWord exists in _dMasForm + return _dMasForm.has(sWord); + }, + + getMasForm: function (sWord, bPlur) { + // returns masculine form with feminine form + if (_dMasForm.has(sWord)) { + return [ for (sTag of this._whatSuffixCode(sWord, bPlur)) this._modifyStringWithSuffixCode(sWord, sTag) ]; + } + return []; + }, + + hasMiscPlural: function (sWord) { + // returns True if sWord exists in dMiscPlur + return _dMiscPlur.has(sWord); + }, + + getMiscPlural: function (sWord) { + // returns plural form with singular form + if (_dMiscPlur.has(sWord)) { + return [ for (sTag of _lTagMiscPlur[_dMiscPlur.get(sWord)].split("|")) this._modifyStringWithSuffixCode(sWord, sTag) ]; + } + return []; + }, + + _whatSuffixCode: function (sWord, bPlur) { + // necessary only for dMasFW + let sSfx = _lTagMasForm[_dMasForm.get(sWord)]; + if (sSfx.includes("/")) { + if (bPlur) { + return sSfx.slice(sSfx.indexOf("/")+1).split("|"); + } + return sSfx.slice(0, sSfx.indexOf("/")).split("|"); + } + return sSfx.split("|"); + }, + + _modifyStringWithSuffixCode: function (sWord, sSfx) { + // returns sWord modified by sSfx + if (!sWord) { + return ""; + } + if (sSfx === "0") { + return sWord; + } + try { + if (sSfx[0] !== '0') { + return sWord.slice(0, -(sSfx.charCodeAt(0)-48)) + sSfx.slice(1); // 48 is the ASCII code for "0" + } else { + return sWord + sSfx.slice(1); + } + } + catch (e) { + console.log(e); + return "## erreur, code : " + sSfx + " ##"; + } } } if (typeof(exports) !== 'undefined') { - exports.isFemForm = isFemForm; - exports.getMasForm = getMasForm; - exports.hasMiscPlural = hasMiscPlural; - exports.getMiscPlural = getMiscPlural; + exports.isFemForm = mfsp.isFemForm; + exports.getMasForm = mfsp.getMasForm; + exports.hasMiscPlural = mfsp.hasMiscPlural; + exports.getMiscPlural = mfsp.getMiscPlural; + exports._whatSuffixCode = mfsp._whatSuffixCode; + exports._modifyStringWithSuffixCode = mfsp._modifyStringWithSuffixCode; } Index: gc_lang/fr/modules-js/phonet.js ================================================================== --- gc_lang/fr/modules-js/phonet.js +++ gc_lang/fr/modules-js/phonet.js @@ -1,75 +1,74 @@ // Grammalecte - Suggestion phonétique const helpers = require("resource://grammalecte/helpers.js"); -const echo = helpers.echo; - -const oData = JSON.parse(helpers.loadFile("resource://grammalecte/fr/phonet_data.json")); - -const _dWord = helpers.objectToMap(oData.dWord); -const _lSet = oData.lSet; -const _dMorph = helpers.objectToMap(oData.dMorph); - - - -function hasSimil (sWord, sPattern=null) { - // return True if there is list of words phonetically similar to sWord - if (!sWord) { - return false; - } - if (_dWord.has(sWord)) { - if (sPattern) { - return getSimil(sWord).some(sSimil => _dMorph.gl_get(sSimil, []).some(sMorph => sMorph.search(sPattern) >= 0)); - } - return true; - } - if (sWord.slice(0,1).gl_isUpperCase()) { - sWord = sWord.toLowerCase(); - if (_dWord.has(sWord)) { - if (sPattern) { - return getSimil(sWord).some(sSimil => _dMorph.gl_get(sSimil, []).some(sMorph => sMorph.search(sPattern) >= 0)); - } - return true; - } - } - return false; -} - -function getSimil (sWord) { - // return list of words phonetically similar to sWord - if (!sWord) { - return []; - } - if (_dWord.has(sWord)) { - return _lSet[_dWord.get(sWord)]; - } - if (sWord.slice(0,1).gl_isUpperCase()) { - sWord = sWord.toLowerCase(); - if (_dWord.has(sWord)) { - return _lSet[_dWord.get(sWord)]; - } - } - return []; -} - -function selectSimil (sWord, sPattern) { - // return list of words phonetically similar to sWord and whom POS is matching sPattern - if (!sPattern) { - return new Set(getSimil(sWord)); - } - let aSelect = new Set(); - for (let sSimil of getSimil(sWord)) { - for (let sMorph of _dMorph.gl_get(sSimil, [])) { - if (sMorph.search(sPattern) >= 0) { - aSelect.add(sSimil); - } - } - } - return aSelect; + +const _oData = JSON.parse(helpers.loadFile("resource://grammalecte/fr/phonet_data.json")); +const _dWord = helpers.objectToMap(_oData.dWord); +const _lSet = _oData.lSet; +const _dMorph = helpers.objectToMap(_oData.dMorph); + + +var phonet = { + hasSimil: function (sWord, sPattern=null) { + // return True if there is list of words phonetically similar to sWord + if (!sWord) { + return false; + } + if (_dWord.has(sWord)) { + if (sPattern) { + return this.getSimil(sWord).some(sSimil => _dMorph.gl_get(sSimil, []).some(sMorph => sMorph.search(sPattern) >= 0)); + } + return true; + } + if (sWord.slice(0,1).gl_isUpperCase()) { + sWord = sWord.toLowerCase(); + if (_dWord.has(sWord)) { + if (sPattern) { + return this.getSimil(sWord).some(sSimil => _dMorph.gl_get(sSimil, []).some(sMorph => sMorph.search(sPattern) >= 0)); + } + return true; + } + } + return false; + }, + + getSimil: function (sWord) { + // return list of words phonetically similar to sWord + if (!sWord) { + return []; + } + if (_dWord.has(sWord)) { + return _lSet[_dWord.get(sWord)]; + } + if (sWord.slice(0,1).gl_isUpperCase()) { + sWord = sWord.toLowerCase(); + if (_dWord.has(sWord)) { + return _lSet[_dWord.get(sWord)]; + } + } + return []; + }, + + selectSimil: function (sWord, sPattern) { + // return list of words phonetically similar to sWord and whom POS is matching sPattern + if (!sPattern) { + return new Set(this.getSimil(sWord)); + } + let aSelect = new Set(); + for (let sSimil of this.getSimil(sWord)) { + for (let sMorph of _dMorph.gl_get(sSimil, [])) { + if (sMorph.search(sPattern) >= 0) { + aSelect.add(sSimil); + } + } + } + return aSelect; + } } if (typeof(exports) !== 'undefined') { - exports.hasSimil = hasSimil; - exports.getSimil = getSimil; - exports.selectSimil = selectSimil; + exports.hasSimil = phonet.hasSimil; + exports.getSimil = phonet.getSimil; + exports.selectSimil = phonet.selectSimil; } Index: gc_lang/fr/tb/content/overlay.js ================================================================== --- gc_lang/fr/tb/content/overlay.js +++ gc_lang/fr/tb/content/overlay.js @@ -910,10 +910,11 @@ }, false); window.addEventListener("load", function (xEvent) { oDictIgniter.init(); oGrammarChecker.loadGC(); + //oGrammarChecker.fullTests(); }, false); window.addEventListener("compose-window-init", function (xEvent) { oGrammarChecker.loadUI(); oGrammarChecker.closePanel(); Index: gc_lang/fr/xpi/data/conj_panel.js ================================================================== --- gc_lang/fr/xpi/data/conj_panel.js +++ gc_lang/fr/xpi/data/conj_panel.js @@ -69,11 +69,11 @@ if (sVerb.endsWith("?")) { document.getElementById('oint').checked = true; sVerb = sVerb.slice(0,-1).trim(); } - if (!isVerb(sVerb)) { + if (!conj.isVerb(sVerb)) { document.getElementById('verb').style = "color: #BB4411;"; } else { self.port.emit("show"); document.getElementById('verb_title').textContent = sVerb; document.getElementById('verb').style = "color: #999999;";