Index: gc_lang/fr/build.py
==================================================================
--- gc_lang/fr/build.py
+++ gc_lang/fr/build.py
@@ -6,14 +6,15 @@
from distutils import dir_util, file_util
import helpers
-def build (sLang, dVars, spLangPack):
+def build (sLang, dVars):
"complementary build launched from make.py"
createWebExtension(sLang, dVars)
- createThunderbirdExtension(sLang, dVars, spLangPack)
+ createThunderbirdExtension(sLang, dVars)
+ createMailExtension(sLang, dVars)
createNodeJSPackage(sLang)
def createWebExtension (sLang, dVars):
"create Web-extension"
@@ -38,27 +39,40 @@
sHTML += f'
\n'
sHTML += '\n'
return sHTML
-def createThunderbirdExtension (sLang, dVars, spLangPack):
- "create extension for Thunderbird"
+def createMailExtension (sLang, dVars):
+ "create extension for Thunderbird (as MailExtension)"
+ print("Building extension for Thunderbird (MailExtension)")
+ spfZip = "_build/" + dVars['tb_identifier'] + "-v" + dVars['version'] + '.mailext.xpi'
+ hZip = zipfile.ZipFile(spfZip, mode='w', compression=zipfile.ZIP_DEFLATED)
+ _copyGrammalecteJSPackageInZipFile(hZip, sLang)
+ for spf in ["LICENSE.txt", "LICENSE.fr.txt"]:
+ hZip.write(spf)
+ dVars = _createOptionsForThunderbird(dVars)
+ helpers.addFolderToZipAndFileFile(hZip, "gc_lang/"+sLang+"/mailext", "", dVars, True)
+ hZip.close()
+ spExtension = dVars['win_tb_debug_extension_path'] if platform.system() == "Windows" else dVars['linux_tb_debug_extension_path']
+ file_util.copy_file(spfZip, spExtension + "/" + dVars['tb_identifier']+ ".xpi") # Filename for TB is just
+ spExtension = dVars['win_tb_beta_extension_path'] if platform.system() == "Windows" else dVars['linux_tb_beta_extension_path']
+ file_util.copy_file(spfZip, spExtension + "/" + dVars['tb_identifier']+ ".xpi") # Filename for TB is just
+
+
+def createThunderbirdExtension (sLang, dVars):
+ "create extension for Thunderbird (as XUL addon)"
print("Building extension for Thunderbird")
- sExtensionName = dVars['tb_identifier'] + "-v" + dVars['version'] + '.xpi'
- spfZip = "_build/" + sExtensionName
+ spfZip = "_build/" + dVars['tb_identifier'] + "-v" + dVars['version'] + '.xpi'
hZip = zipfile.ZipFile(spfZip, mode='w', compression=zipfile.ZIP_DEFLATED)
- _copyGrammalecteJSPackageInZipFile(hZip, spLangPack)
+ _copyGrammalecteJSPackageInZipFile(hZip, sLang)
for spf in ["LICENSE.txt", "LICENSE.fr.txt"]:
hZip.write(spf)
dVars = _createOptionsForThunderbird(dVars)
helpers.addFolderToZipAndFileFile(hZip, "gc_lang/"+sLang+"/tb", "", dVars, True)
hZip.close()
- spDebugProfile = dVars['win_tb_debug_extension_path'] if platform.system() == "Windows" else dVars['linux_tb_debug_extension_path']
- helpers.unzip(spfZip, spDebugProfile)
- spfBetaExtension = dVars['win_tb_beta_extension_filepath'] if platform.system() == "Windows" else dVars['linux_tb_beta_extension_filepath']
- #helpers.unzip(spfZip, spBetaProfile)
- file_util.copy_file(spfZip, spfBetaExtension)
+ #spDebugProfile = dVars['win_tb_debug_extension_path'] if platform.system() == "Windows" else dVars['linux_tb_debug_extension_path']
+ #helpers.unzip(spfZip, spDebugProfile)
def _createOptionsForThunderbird (dVars):
dVars['sXULTabs'] = ""
dVars['sXULTabPanels'] = ""
@@ -74,24 +88,24 @@
for sLang in dVars['dOptLabel'].keys():
dVars['gc_options_labels_'+sLang] = "\n".join( [ "' for sOpt in dVars['dOptLabel'][sLang] ] )
return dVars
-def _copyGrammalecteJSPackageInZipFile (hZip, spLangPack, sAddPath=""):
+def _copyGrammalecteJSPackageInZipFile (hZip, sLang, sAddPath=""):
for sf in os.listdir("grammalecte-js"):
if not os.path.isdir("grammalecte-js/"+sf):
- hZip.write("grammalecte-js/"+sf, sAddPath+"grammalecte-js/"+sf)
+ hZip.write("grammalecte-js/"+sf, sAddPath+"grammalecte/"+sf)
for sf in os.listdir("grammalecte-js/graphspell"):
if not os.path.isdir("grammalecte-js/graphspell/"+sf):
- hZip.write("grammalecte-js/graphspell/"+sf, sAddPath+"grammalecte-js/graphspell/"+sf)
+ hZip.write("grammalecte-js/graphspell/"+sf, sAddPath+"grammalecte/graphspell/"+sf)
for sf in os.listdir("grammalecte-js/graphspell/_dictionaries"):
if not os.path.isdir("grammalecte-js/graphspell/_dictionaries/"+sf):
- hZip.write("grammalecte-js/graphspell/_dictionaries/"+sf, sAddPath+"grammalecte-js/graphspell/_dictionaries/"+sf)
- for sf in os.listdir(spLangPack):
- if not os.path.isdir(spLangPack+"/"+sf):
- hZip.write(spLangPack+"/"+sf, sAddPath+spLangPack+"/"+sf)
+ hZip.write("grammalecte-js/graphspell/_dictionaries/"+sf, sAddPath+"grammalecte/graphspell/_dictionaries/"+sf)
+ for sf in os.listdir("grammalecte-js/"+sLang):
+ if not os.path.isdir("grammalecte-js/"+sLang+"/"+sf):
+ hZip.write("grammalecte-js/"+sLang+"/"+sf, sAddPath+"grammalecte/"+sLang+"/"+sf)
def createNodeJSPackage (sLang):
helpers.createCleanFolder("_build/nodejs/"+sLang)
dir_util.copy_tree("gc_lang/"+sLang+"/nodejs/", "_build/nodejs/"+sLang)
dir_util.copy_tree("grammalecte-js", "_build/nodejs/"+sLang+"/core/grammalecte")
Index: gc_lang/fr/config.ini
==================================================================
--- gc_lang/fr/config.ini
+++ gc_lang/fr/config.ini
@@ -8,11 +8,11 @@
# always use 3 numbers for version: x.y.z
version = 1.3.2
author = Olivier R.
provider = Grammalecte.net
link = https://grammalecte.net
-description = Correcteur grammatical pour le français.
+description = Correcteur grammatical, orthographique et typographique pour le français.
extras = README_fr.txt
logo = logo.png
# main dictionary
lexicon_src = lexicons/French.lex
@@ -54,18 +54,17 @@
# Thunderbird
tb_identifier = French-GC-TB@grammalecte.net
tb_name = Grammalecte [fr]
win_tb_path = C:\Program Files (x86)\Mozilla Thunderbird\thunderbird.exe
-#win_tb_beta_path = C:\Program Files (x86)\Mozilla Thunderbird (Beta)\thunderbird.exe
-win_tb_beta_path = C:\Program Files (x86)\Mozilla Thunderbird (Beta)\thunderbird.exe
+win_tb_beta_path = C:\Program Files\Thunderbird Daily\thunderbird.exe
linux_tb_path = /usr/bin/thunderbird
linux_tb_beta_path = /usr/bin/thunderbird
-win_tb_debug_extension_path = D:\_temp\tb-debug.profile\extensions\French-GC-TB@grammalecte.net
-linux_tb_debug_extension_path = ~/tb-debug.profile/extensions/French-GC-TB@grammalecte.net
-win_tb_beta_extension_filepath = D:\_temp\tb-beta.profile\extensions\French-GC-TB@grammalecte.net.xpi
-linux_tb_beta_extension_filepath = ~/tb-beta.profile/extensions/French-GC-TB@grammalecte.net.xpi
+win_tb_debug_extension_path = D:\_temp\tb-debug.profile\extensions
+linux_tb_debug_extension_path = ~/tb-debug.profile/extensions
+win_tb_beta_extension_path = D:\_temp\tb-beta.profile\extensions
+linux_tb_beta_extension_path = ~/tb-beta.profile/extensions
# Set Thunderbird folder in your PATH variable
# Create a local profile:
# thunderbird -CreateProfile "debug _build\tb-debug.profile"
# Or you can use the GUI with:
# thunderbird -P
ADDED gc_lang/fr/mailext/README.txt
Index: gc_lang/fr/mailext/README.txt
==================================================================
--- /dev/null
+++ gc_lang/fr/mailext/README.txt
@@ -0,0 +1,14 @@
+
+= GRAMMALECTE =
+
+French grammar checker
+By Olivier R. (olivier /at/ grammalecte /dot/ net)
+
+Website: https://grammalecte.net/
+
+License: GPL 3 -- http://www.gnu.org/copyleft/gpl.html
+
+Grammalecte for Firefox is a derivative tool born from the version
+for LibreOffice written in Python.
+
+Written in JavaScript ES6/ES7.
ADDED gc_lang/fr/mailext/background.js
Index: gc_lang/fr/mailext/background.js
==================================================================
--- /dev/null
+++ gc_lang/fr/mailext/background.js
@@ -0,0 +1,204 @@
+// Background
+
+"use strict";
+
+console.log("THUNDERBIRD!!! BACKGROUND");
+
+
+const oWorkerHandler = {
+ xGCEWorker: null,
+
+ nLastTimeWorkerResponse: 0, // milliseconds since 1970-01-01
+
+ oTask: {},
+
+ start: function () {
+ this.xGCEWorker = new Worker("gce_worker.js");
+ this.xGCEWorker.onmessage = function (e) {
+ // Messages received from the Worker
+ // https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent
+ try {
+ this.nLastTimeWorkerResponse = Date.now();
+ let {sActionDone, result, dInfo, bEnd, bError} = e.data;
+ if (bError) {
+ console.log(result);
+ console.log(dInfo);
+ return;
+ }
+ switch (sActionDone) {
+ case "init":
+ storeGCOptions(result);
+ break;
+ case "parse":
+ case "parseAndSpellcheck":
+ case "parseAndSpellcheck1":
+ case "parseFull":
+ case "getListOfTokens":
+ case "getSpellSuggestions":
+ case "getVerb":
+ // send result to content script
+ if (typeof(dInfo.iReturnPort) === "number") {
+ let xPort = dConnx.get(dInfo.iReturnPort);
+ xPort.postMessage(e.data);
+ } else {
+ console.log("[background] don’t know where to send results");
+ console.log(e.data);
+ }
+ break;
+ case "textToTest":
+ case "fullTests":
+ // send result to panel
+ browser.runtime.sendMessage(e.data);
+ break;
+ case "getOptions":
+ case "getDefaultOptions":
+ case "resetOptions":
+ // send result to panel
+ storeGCOptions(result);
+ browser.runtime.sendMessage(e.data);
+ break;
+ case "setOptions":
+ case "setOption":
+ storeGCOptions(result);
+ break;
+ case "setDictionary":
+ case "setDictionaryOnOff":
+ //console.log("[background] " + sActionDone + ": " + result);
+ break;
+ default:
+ console.log("[background] Unknown command: " + sActionDone);
+ console.log(e.data);
+ }
+ }
+ catch (error) {
+ showError(error);
+ console.log(e.data);
+ }
+ };
+ },
+
+ getTimeSinceLastResponse: function () {
+ // result in seconds
+ return Math.floor((Date.now() - this.nLastTimeWorkerResponse) / 1000);
+ },
+
+ restart: function (nDelay=5) {
+ if (this.getTimeSinceLastResponse() <= nDelay) {
+ console.log("Worker not restarted. Worked ", nDelay, " seconds ago.");
+ return false;
+ }
+ if (this.xGCEWorker) {
+ this.xGCEWorker.terminate();
+ }
+ this.start();
+ oInitHandler.initGrammarChecker();
+ sendCommandToAllTabs("workerRestarted");
+ console.log("Worker restarted.");
+ return true;
+ },
+
+ addTask: function () {
+ //
+ },
+
+ closeTask: function () {
+ //
+ }
+}
+
+
+const oInitHandler = {
+
+ initUIOptions: function () {
+ browser.storage.local.get("ui_options").then(this._initUIOptions, showError);
+ browser.storage.local.get("autorefresh_option").then(this._initUIOptions, showError);
+ },
+
+ initGrammarChecker: function () {
+ browser.storage.local.get("gc_options").then(this._initGrammarChecker, showError);
+ browser.storage.local.get("personal_dictionary").then(this._setSpellingDictionaries, showError);
+ browser.storage.local.get("community_dictionary").then(this._setSpellingDictionaries, showError);
+ browser.storage.local.get("oPersonalDictionary").then(this._setSpellingDictionaries, showError); // deprecated
+ browser.storage.local.get("sc_options").then(this._initSCOptions, showError);
+ },
+
+ _initUIOptions: function (oSavedOptions) {
+ if (!oSavedOptions.hasOwnProperty("ui_options")) {
+ browser.storage.local.set({"ui_options": {
+ textarea: true,
+ editablenode: true
+ }});
+ }
+ if (!oSavedOptions.hasOwnProperty("autorefresh_option")) {
+ browser.storage.local.set({"autorefresh_option": true});
+ }
+ },
+
+ _initGrammarChecker: function (oSavedOptions) {
+ try {
+ let dOptions = (oSavedOptions.hasOwnProperty("gc_options")) ? oSavedOptions.gc_options : null;
+ if (dOptions !== null && Object.getOwnPropertyNames(dOptions).length == 0) {
+ console.log("# Error: the saved options was an empty object.");
+ dOptions = null;
+ }
+ oWorkerHandler.xGCEWorker.postMessage({
+ sCommand: "init",
+ dParam: {sExtensionPath: browser.extension.getURL(""), dOptions: dOptions, sContext: "Firefox"},
+ dInfo: {}
+ });
+ }
+ catch (e) {
+ console.log("initGrammarChecker failed");
+ showError(e);
+ }
+ },
+
+ _setSpellingDictionaries: function (oData) {
+ if (oData.hasOwnProperty("community_dictionary")) {
+ oWorkerHandler.xGCEWorker.postMessage({ sCommand: "setDictionary", dParam: { sDictionary: "community", oDict: oData["community_dictionary"] }, dInfo: {} });
+ }
+ if (oData.hasOwnProperty("personal_dictionary")) {
+ oWorkerHandler.xGCEWorker.postMessage({ sCommand: "setDictionary", dParam: { sDictionary: "personal", oDict: oData["personal_dictionary"] }, dInfo: {} });
+ }
+ },
+
+ _initSCOptions: function (oData) {
+ if (!oData.hasOwnProperty("sc_options")) {
+ browser.storage.local.set({"sc_options": {
+ community: true,
+ personal: true
+ }});
+ oWorkerHandler.xGCEWorker.postMessage({ sCommand: "setDictionaryOnOff", dParam: { sDictionary: "community", bActivate: true }, dInfo: {} });
+ oWorkerHandler.xGCEWorker.postMessage({ sCommand: "setDictionaryOnOff", dParam: { sDictionary: "personal", bActivate: true }, dInfo: {} });
+ } else {
+ oWorkerHandler.xGCEWorker.postMessage({ sCommand: "setDictionaryOnOff", dParam: { sDictionary: "community", bActivate: oData.sc_options["community"] }, dInfo: {} });
+ oWorkerHandler.xGCEWorker.postMessage({ sCommand: "setDictionaryOnOff", dParam: { sDictionary: "personal", bActivate: oData.sc_options["personal"] }, dInfo: {} });
+ }
+ }
+}
+
+// start the Worker for the GC
+oWorkerHandler.start();
+
+// init the options stuff and start the GC
+oInitHandler.initUIOptions();
+oInitHandler.initGrammarChecker();
+
+
+
+/*
+ Actions
+*/
+
+function storeGCOptions (dOptions) {
+ if (dOptions instanceof Map) {
+ dOptions = helpers.mapToObject(dOptions);
+ }
+ browser.storage.local.set({"gc_options": dOptions});
+}
+
+
+function showError (e) {
+ console.error(e);
+ //console.error(e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message);
+}
ADDED gc_lang/fr/mailext/gce_worker.js
Index: gc_lang/fr/mailext/gce_worker.js
==================================================================
--- /dev/null
+++ gc_lang/fr/mailext/gce_worker.js
@@ -0,0 +1,428 @@
+/*
+ WORKER:
+ https://developer.mozilla.org/en-US/docs/Web/API/Worker
+ https://developer.mozilla.org/en-US/docs/Web/API/DedicatedWorkerGlobalScope
+
+
+ JavaScript sucks.
+ No module available in WebExtension at the moment! :(
+ No require, no import/export.
+
+ In Worker, we have importScripts() which imports everything in this scope.
+
+ In order to use the same base of code with XUL-addon for Thunderbird and SDK-addon for Firefox,
+ all modules have been “objectified”. And while they are still imported via “require”
+ in the previous extensions, they are loaded as background scripts in WebExtension sharing
+ the same memory space…
+
+ When JavaScript become a modern language, “deobjectify” the modules…
+
+ ATM, import/export are not available by default:
+ — Chrome 60 – behind the Experimental Web Platform flag in chrome:flags.
+ — Firefox 54 – behind the dom.moduleScripts.enabled setting in about:config.
+ — Edge 15 – behind the Experimental JavaScript Features setting in about:flags.
+
+ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
+ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export
+*/
+
+"use strict";
+
+
+//console.log("[Worker] GC Engine Worker [start]");
+//console.log(self);
+
+importScripts("grammalecte/graphspell/helpers.js");
+importScripts("grammalecte/graphspell/str_transform.js");
+importScripts("grammalecte/graphspell/char_player.js");
+importScripts("grammalecte/graphspell/suggest.js");
+importScripts("grammalecte/graphspell/ibdawg.js");
+importScripts("grammalecte/graphspell/spellchecker.js");
+importScripts("grammalecte/text.js");
+importScripts("grammalecte/graphspell/tokenizer.js");
+importScripts("grammalecte/fr/conj.js");
+importScripts("grammalecte/fr/mfsp.js");
+importScripts("grammalecte/fr/phonet.js");
+importScripts("grammalecte/fr/cregex.js");
+importScripts("grammalecte/fr/gc_options.js");
+importScripts("grammalecte/fr/gc_rules.js");
+importScripts("grammalecte/fr/gc_rules_graph.js");
+importScripts("grammalecte/fr/gc_engine.js");
+importScripts("grammalecte/fr/lexicographe.js");
+importScripts("grammalecte/tests.js");
+/*
+ Warning.
+ Initialization can’t be completed at startup of the worker,
+ for we need the path of the extension to load data stored in JSON files.
+ This path is retrieved in background.js and passed with the event “init”.
+*/
+
+
+function createResponse (sActionDone, result, dInfo, bEnd, bError=false) {
+ return {
+ "sActionDone": sActionDone,
+ "result": result, // can be of any type
+ "dInfo": dInfo,
+ "bEnd": bEnd,
+ "bError": bError
+ };
+}
+
+function createErrorResult (e, sDescr="no description") {
+ return {
+ "sType": "error",
+ "sDescription": sDescr,
+ "sMessage": e.fileName + "\n" + e.name + "\nline: " + e.lineNumber + "\n" + e.message
+ };
+}
+
+function showData (e) {
+ for (let sParam in e) {
+ console.log(sParam);
+ console.log(e[sParam]);
+ }
+}
+
+
+/*
+ Message Event Object
+ https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent
+*/
+onmessage = function (e) {
+ let {sCommand, dParam, dInfo} = e.data;
+ switch (sCommand) {
+ case "init":
+ init(dParam.sExtensionPath, dParam.dOptions, dParam.sContext, dInfo);
+ break;
+ case "parse":
+ parse(dParam.sText, dParam.sCountry, dParam.bDebug, dParam.bContext, dInfo);
+ break;
+ case "parseAndSpellcheck":
+ parseAndSpellcheck(dParam.sText, dParam.sCountry, dParam.bDebug, dParam.bContext, dInfo);
+ break;
+ case "parseAndSpellcheck1":
+ parseAndSpellcheck1(dParam.sText, dParam.sCountry, dParam.bDebug, dParam.bContext, dInfo);
+ break;
+ case "parseFull":
+ parseFull(dParam.sText, dParam.sCountry, dParam.bDebug, dParam.bContext, dInfo);
+ break;
+ case "getListOfTokens":
+ getListOfTokens(dParam.sText, dInfo);
+ break;
+ case "getOptions":
+ getOptions(dInfo);
+ break;
+ case "getDefaultOptions":
+ getDefaultOptions(dInfo);
+ break;
+ case "setOptions":
+ setOptions(dParam.sOptions, dInfo);
+ break;
+ case "setOption":
+ setOption(dParam.sOptName, dParam.bValue, dInfo);
+ break;
+ case "resetOptions":
+ resetOptions(dInfo);
+ break;
+ case "textToTest":
+ textToTest(dParam.sText, dParam.sCountry, dParam.bDebug, dParam.bContext, dInfo);
+ break;
+ case "fullTests":
+ fullTests(dInfo);
+ break;
+ case "setDictionary":
+ setDictionary(dParam.sDictionary, dParam.oDict, dInfo);
+ break;
+ case "setDictionaryOnOff":
+ setDictionaryOnOff(dParam.sDictionary, dParam.bActivate, dInfo);
+ break;
+ case "getSpellSuggestions":
+ getSpellSuggestions(dParam.sWord, dInfo);
+ break;
+ case "getVerb":
+ getVerb(dParam.sVerb, dParam.bPro, dParam.bNeg, dParam.bTpsCo, dParam.bInt, dParam.bFem, dInfo);
+ break;
+ default:
+ console.log("[Worker] Unknown command: " + sCommand);
+ showData(e.data);
+ }
+}
+
+
+
+let bInitDone = false;
+
+let oSpellChecker = null;
+let oTokenizer = null;
+let oLxg = null;
+let oTest = null;
+let oLocution = null;
+
+
+/*
+ Technical note:
+ This worker don’t work as a PromiseWorker (which returns a promise), so when we send request
+ to this worker, we can’t wait the return of the answer just after the request made.
+ The answer is received by the background in another function (onmessage).
+ That’s why the full text to analyze is send in one block, but analyse is returned paragraph
+ by paragraph.
+*/
+
+function init (sExtensionPath, dOptions=null, sContext="JavaScript", dInfo={}) {
+ try {
+ if (!bInitDone) {
+ console.log("[Worker] Loading… Extension path: " + sExtensionPath);
+ conj.init(helpers.loadFile(sExtensionPath + "/grammalecte/fr/conj_data.json"));
+ phonet.init(helpers.loadFile(sExtensionPath + "/grammalecte/fr/phonet_data.json"));
+ mfsp.init(helpers.loadFile(sExtensionPath + "/grammalecte/fr/mfsp_data.json"));
+ //console.log("[Worker] Modules have been initialized…");
+ gc_engine.load(sContext, "sCSS", sExtensionPath+"grammalecte/graphspell/_dictionaries");
+ oSpellChecker = gc_engine.getSpellChecker();
+ oTest = new TestGrammarChecking(gc_engine, sExtensionPath+"/grammalecte/fr/tests_data.json");
+ oTokenizer = new Tokenizer("fr");
+ oLocution = helpers.loadFile(sExtensionPath + "/grammalecte/fr/locutions_data.json");
+ oLxg = new Lexicographe(oSpellChecker, oTokenizer, oLocution);
+ if (dOptions !== null) {
+ if (!(dOptions instanceof Map)) {
+ dOptions = helpers.objectToMap(dOptions);
+ }
+ gc_engine.setOptions(dOptions);
+ }
+ //tests();
+ bInitDone = true;
+ } else {
+ console.log("[Worker] Already initialized…")
+ }
+ // we always retrieve options from the gc_engine, for setOptions filters obsolete options
+ dOptions = helpers.mapToObject(gc_engine.getOptions());
+ postMessage(createResponse("init", dOptions, dInfo, true));
+ }
+ catch (e) {
+ console.error(e);
+ postMessage(createResponse("init", createErrorResult(e, "init failed"), dInfo, true, true));
+ }
+}
+
+
+function parse (sText, sCountry, bDebug, bContext, dInfo={}) {
+ sText = sText.replace(//g, "").normalize("NFC");
+ for (let sParagraph of text.getParagraph(sText)) {
+ let aGrammErr = gc_engine.parse(sParagraph, sCountry, bDebug, bContext);
+ postMessage(createResponse("parse", aGrammErr, dInfo, false));
+ }
+ postMessage(createResponse("parse", null, dInfo, true));
+}
+
+function parseAndSpellcheck (sText, sCountry, bDebug, bContext, dInfo={}) {
+ let i = 0;
+ sText = sText.replace(//g, "").normalize("NFC");
+ for (let sParagraph of text.getParagraph(sText)) {
+ let aGrammErr = gc_engine.parse(sParagraph, sCountry, bDebug, null, bContext);
+ let aSpellErr = oSpellChecker.parseParagraph(sParagraph);
+ postMessage(createResponse("parseAndSpellcheck", {sParagraph: sParagraph, iParaNum: i, aGrammErr: aGrammErr, aSpellErr: aSpellErr}, dInfo, false));
+ i += 1;
+ }
+ postMessage(createResponse("parseAndSpellcheck", null, dInfo, true));
+}
+
+function parseAndSpellcheck1 (sParagraph, sCountry, bDebug, bContext, dInfo={}) {
+ sParagraph = sParagraph.replace(//g, "").normalize("NFC");
+ let aGrammErr = gc_engine.parse(sParagraph, sCountry, bDebug, null, bContext);
+ let aSpellErr = oSpellChecker.parseParagraph(sParagraph);
+ postMessage(createResponse("parseAndSpellcheck1", {sParagraph: sParagraph, aGrammErr: aGrammErr, aSpellErr: aSpellErr}, dInfo, true));
+}
+
+function parseFull (sText, sCountry, bDebug, bContext, dInfo={}) {
+ let i = 0;
+ sText = sText.replace(//g, "").normalize("NFC");
+ for (let sParagraph of text.getParagraph(sText)) {
+ let lSentence = gc_engine.parse(sParagraph, sCountry, bDebug, null, bContext, true);
+ console.log("*", lSentence);
+ postMessage(createResponse("parseFull", {sParagraph: sParagraph, iParaNum: i, lSentence: lSentence}, dInfo, false));
+ i += 1;
+ }
+ postMessage(createResponse("parseFull", null, dInfo, true));
+}
+
+function getListOfTokens (sText, dInfo={}) {
+ // lexicographer
+ try {
+ sText = sText.replace(//g, "").normalize("NFC");
+ for (let sParagraph of text.getParagraph(sText)) {
+ if (sParagraph.trim() !== "") {
+ postMessage(createResponse("getListOfTokens", oLxg.getListOfTokensReduc(sParagraph, true), dInfo, false));
+ }
+ }
+ postMessage(createResponse("getListOfTokens", null, dInfo, true));
+ }
+ catch (e) {
+ console.error(e);
+ postMessage(createResponse("getListOfTokens", createErrorResult(e, "no tokens"), dInfo, true, true));
+ }
+}
+
+function getOptions (dInfo={}) {
+ let dOptions = helpers.mapToObject(gc_engine.getOptions());
+ postMessage(createResponse("getOptions", dOptions, dInfo, true));
+}
+
+function getDefaultOptions (dInfo={}) {
+ let dOptions = helpers.mapToObject(gc_engine.getDefaultOptions());
+ postMessage(createResponse("getDefaultOptions", dOptions, dInfo, true));
+}
+
+function setOptions (dOptions, dInfo={}) {
+ if (!(dOptions instanceof Map)) {
+ dOptions = helpers.objectToMap(dOptions);
+ }
+ gc_engine.setOptions(dOptions);
+ dOptions = helpers.mapToObject(gc_engine.getOptions());
+ postMessage(createResponse("setOptions", dOptions, dInfo, true));
+}
+
+function setOption (sOptName, bValue, dInfo={}) {
+ console.log(sOptName+": "+bValue);
+ if (sOptName) {
+ gc_engine.setOption(sOptName, bValue);
+ let dOptions = helpers.mapToObject(gc_engine.getOptions());
+ postMessage(createResponse("setOption", dOptions, dInfo, true));
+ }
+}
+
+function resetOptions (dInfo={}) {
+ gc_engine.resetOptions();
+ let dOptions = helpers.mapToObject(gc_engine.getOptions());
+ postMessage(createResponse("resetOptions", dOptions, dInfo, true));
+}
+
+function tests () {
+ console.log(conj.getConj("devenir", ":E", ":2s"));
+ console.log(mfsp.getMasForm("emmerdeuse", true));
+ console.log(mfsp.getMasForm("pointilleuse", false));
+ console.log(phonet.getSimil("est"));
+ let aRes = gc_engine.parse("Je suit...");
+ for (let oErr of aRes) {
+ console.log(text.getReadableError(oErr));
+ }
+}
+
+function textToTest (sText, sCountry, bDebug, bContext, dInfo={}) {
+ if (!gc_engine) {
+ postMessage(createResponse("textToTest", "# Grammar checker not loaded.", dInfo, true));
+ return;
+ }
+ sText = sText.replace(//g, "").normalize("NFC");
+ let aGrammErr = gc_engine.parse(sText, sCountry, bDebug, bContext);
+ let sMsg = "";
+ for (let oErr of aGrammErr) {
+ sMsg += text.getReadableError(oErr) + "\n";
+ }
+ if (sMsg == "") {
+ sMsg = "Aucune erreur détectée.";
+ }
+ postMessage(createResponse("textToTest", sMsg, dInfo, true));
+}
+
+function fullTests (dInfo={}) {
+ if (!gc_engine) {
+ postMessage(createResponse("fullTests", "# Grammar checker not loaded.", dInfo, true));
+ return;
+ }
+ let dMemoOptions = gc_engine.getOptions();
+ let dTestOptions = gc_engine.getDefaultOptions();
+ dTestOptions.set("nbsp", true);
+ dTestOptions.set("esp", true);
+ dTestOptions.set("unit", true);
+ dTestOptions.set("num", true);
+ gc_engine.setOptions(dTestOptions);
+ let sMsg = "";
+ for (let sRes of oTest.testParse()) {
+ sMsg += sRes + "\n";
+ console.log(sRes);
+ }
+ gc_engine.setOptions(dMemoOptions);
+ postMessage(createResponse("fullTests", sMsg, dInfo, true));
+}
+
+
+// SpellChecker
+
+function setDictionary (sDictionary, oDict, dInfo) {
+ if (!oSpellChecker) {
+ postMessage(createResponse("setDictionary", "# Error. SpellChecker not loaded.", dInfo, true));
+ return;
+ }
+ //console.log("setDictionary", sDictionary);
+ switch (sDictionary) {
+ case "main":
+ oSpellChecker.setMainDictionary(oDict);
+ break;
+ case "community":
+ oSpellChecker.setCommunityDictionary(oDict);
+ break;
+ case "personal":
+ oSpellChecker.setPersonalDictionary(oDict);
+ break;
+ default:
+ console.log("[worker] setDictionary: Unknown dictionary <"+sDictionary+">");
+ }
+ postMessage(createResponse("setDictionary", true, dInfo, true));
+}
+
+function setDictionaryOnOff (sDictionary, bActivate, dInfo) {
+ if (!oSpellChecker) {
+ postMessage(createResponse("setDictionary", "# Error. SpellChecker not loaded.", dInfo, true));
+ return;
+ }
+ //console.log("setDictionaryOnOff", sDictionary, bActivate);
+ switch (sDictionary) {
+ case "community":
+ if (bActivate) {
+ oSpellChecker.activateCommunityDictionary();
+ } else {
+ oSpellChecker.deactivateCommunityDictionary();
+ }
+ break;
+ case "personal":
+ if (bActivate) {
+ oSpellChecker.activatePersonalDictionary();
+ } else {
+ oSpellChecker.deactivatePersonalDictionary();
+ }
+ break;
+ default:
+ console.log("[worker] setDictionaryOnOff: Unknown dictionary <"+sDictionary+">");
+ }
+ postMessage(createResponse("setDictionaryOnOff", true, dInfo, true));
+}
+
+function getSpellSuggestions (sWord, dInfo) {
+ if (!oSpellChecker) {
+ postMessage(createResponse("getSpellSuggestions", "# Error. SpellChecker not loaded.", dInfo, true));
+ return;
+ }
+ let i = 0;
+ for (let aSugg of oSpellChecker.suggest(sWord)) {
+ postMessage(createResponse("getSpellSuggestions", {sWord: sWord, aSugg: aSugg, iSuggBlock: i}, dInfo, true));
+ i += 1;
+ }
+}
+
+
+// Conjugueur
+
+function getVerb (sWord, bPro, bNeg, bTpsCo, bInt, bFem, dInfo) {
+ try {
+ let oVerb = null;
+ let oConjTable = null;
+ if (conj.isVerb(sWord)) {
+ oVerb = new Verb(sWord);
+ oConjTable = oVerb.createConjTable(bPro, bNeg, bTpsCo, bInt, bFem);
+ }
+ postMessage(createResponse("getVerb", { oVerb: oVerb, oConjTable: oConjTable }, dInfo, true));
+ }
+ catch (e) {
+ console.error(e);
+ postMessage(createResponse("getVerb", createErrorResult(e, "no verb"), dInfo, true, true));
+ }
+}
ADDED gc_lang/fr/mailext/icon.png
Index: gc_lang/fr/mailext/icon.png
==================================================================
--- /dev/null
+++ gc_lang/fr/mailext/icon.png
cannot compute difference between binary files
ADDED gc_lang/fr/mailext/manifest.json
Index: gc_lang/fr/mailext/manifest.json
==================================================================
--- /dev/null
+++ gc_lang/fr/mailext/manifest.json
@@ -0,0 +1,26 @@
+{
+ "manifest_version": 2,
+ "applications": {
+ "gecko": {
+ "id": "${tb_identifier}",
+ "strict_min_version": "68.0a1"
+ }
+ },
+ "name": "${tb_name}",
+ "description": "${description}",
+ "version": "${version}",
+
+ "author": "${author}",
+ "homepage_url": "${link}",
+
+ "background": {
+ "scripts": [
+ "grammalecte-js/graphspell/helpers.js",
+ "background.js"
+ ]
+ },
+
+ "permissions": [
+ "storage"
+ ]
+}
Index: helpers.py
==================================================================
--- helpers.py
+++ helpers.py
@@ -34,11 +34,11 @@
if os.path.isdir(spInstall):
eraseFolder(spInstall)
with zipfile.ZipFile(spfZip) as hZip:
hZip.extractall(spDest)
else:
- print("# folder not found")
+ print("# folder <" + spDest + "> not found")
else:
print("path destination is empty")
def eraseFolder (sp):
@@ -94,9 +94,9 @@
spfDst = (spDst + "/" + sf).strip("/ ")
if os.path.isdir(spfSrc):
if bRecursive:
addFolderToZipAndFileFile(hZip, spfSrc, spfDst, dVars, bRecursive)
else:
- if spfSrc.endswith((".py", ".js", ".css", ".xcu", ".xul", ".rdf", ".dtd", ".properties")):
+ if spfSrc.endswith((".py", ".js", ".json", ".css", ".xcu", ".xul", ".rdf", ".dtd", ".properties")):
hZip.writestr(spfDst, fileFile(spfSrc, dVars))
else:
hZip.write(spfSrc, spfDst)
Index: make.py
==================================================================
--- make.py
+++ make.py
@@ -285,11 +285,11 @@
try:
buildjs = importlib.import_module("gc_lang."+sLang+".build")
except ImportError:
print("# No complementary builder in folder gc_lang/"+sLang)
else:
- buildjs.build(sLang, dVars, spLangPack)
+ buildjs.build(sLang, dVars)
return dVars['version']
def copyGraphspellCore (bJavaScript=False):