Index: gc_core/js/helpers.js ================================================================== --- gc_core/js/helpers.js +++ gc_core/js/helpers.js @@ -5,94 +5,96 @@ // 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.funcOutput = helpers.funcOutput; + 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/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/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();