Index: gc_core/js/helpers.js ================================================================== --- gc_core/js/helpers.js +++ gc_core/js/helpers.js @@ -1,98 +1,100 @@ // HELPERS "use strict"; -// 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 = { + // 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. + funcOutput: null, + + setLogOutput: function (func) { + this.funcOutput = func; + }, + + echo: function (obj) { + if (this.funcOutput !== null) { + this.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 (this.funcOutput !== null) { + this.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') { + export.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/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();