Grammalecte  Check-in [607775f957]

Overview
Comment:[fx] Web API update, [cli] fix bug with the text formatter (trash commit)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk | cli
Files: files | file ages | folders
SHA3-256: 607775f957d4681811651bdb7ceaa45ca95f85913dde102ee6753c250ff7fc8c
User & Date: olr on 2020-03-21 23:42:32
Original Comment: [cli] fix bug with the text formatter
Other Links: manifest | tags
Context
2020-03-22
00:25
[core] fix getParagraphWithErrors when no errors check-in: 9d8c10bf97 user: olr tags: trunk, core
2020-03-21
23:42
[fx] Web API update, [cli] fix bug with the text formatter (trash commit) check-in: 607775f957 user: olr tags: trunk, cli
23:40
[fr] ajustements check-in: aca27e93d8 user: olr tags: trunk, fr
Changes

Modified doc/API_web.md from [d27d7a87a4] to [a6776ada80].

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98









99
100
101
102
103
104
105
62
63
64
65
66
67
68














69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100







-
-
-
-
-
-
-
-
-
-
-
-
-
-
















+
+
+
+
+
+
+
+
+








    oGrammalecteAPI.openPanelForNode("node_id")
    oGrammalecteAPI.openPanelForNode(node)

The node can be a textarea, an editable node or an iframe.
If the node is an iframe, the content won’t be modified by Grammalecte.


### Open the Grammalecte panel for any text

    oGrammalecteAPI.openPanelForText("your text")

This method won’t send back any result or modified text.


### Open the Grammalecte panel

    oGrammalecteAPI.openPanel(param)

Depending of what `param` is, this method will call `openPanelForNode()` or `openPanelForText()`.


### Prevent Grammalecte to modify the node content

If you don’t want Grammalecte to modify directly the node content, add the property: `data-grammalecte_result_via_event="true"`.

With this property, Grammalecte will send an event to the node each times the text is modified within the panel.
The text can be retrieved with:

    node.addEventListener("GrammalecteResult", function (event) {
        const detail = (typeof(event.detail) === 'string') && JSON.parse(event.detail);
        if (detail.sType  &&  detail.sType == "text") {
            let sText = detail.sText;
            ...
        }
    }


### Open the Grammalecte panel for any text

    oGrammalecteAPI.openPanelForText("your text")
    oGrammalecteAPI.openPanelForText("your text", "node_id")
    oGrammalecteAPI.openPanelForText("your text", node)

With the second parameter, Grammalecte will send an event to the node each times the text is modified within the panel.


### Parse a node and get errors

    oGrammalecteAPI.parseNode("node_id")
    oGrammalecteAPI.parseNode(node)

The node can be a textarea, an editable node or an iframe. The node must have an identifier.

Modified gc_lang/fr/webext/content_scripts/api.js from [6ff89127c7] to [5a54ca7263].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50


51







52

53
54
55
56
57
58
59
1
2
3
4
5
6
7
8
9
10
11






















12
13
14
15
16
17
18
19
20
21
22
23
24
25
26


27
28
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44











-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-















-
-
+
+

+
+
+
+
+
+
+
-
+







// JavaScript

"use strict";


const oGrammalecteAPI = {
    // functions callable from within pages
    // to be sent to the content-cript via an event “GrammalecteCall”

    sVersion: "1.0",

    openPanel: function (arg1) {
        //  Parameter: a text, a node, or the identifier of a node.
        let xNode = null;
        if (typeof(arg1) === 'string') {
            if (document.getElementById(arg1)) {
                xNode = document.getElementById(arg1);
            } else {
                this.openPanelForText(arg1);
            }
        }
        else if (arg1 instanceof HTMLElement) {
            xNode = arg1;
        }
        if (xNode) {
            if (xNode.tagName == "INPUT"  ||  xNode.tagName == "TEXTAREA"  ||  xNode.tagName == "IFRAME"  ||  xNode.isContentEditable) {
                this.openPanelForNode(xNode);
            } else {
                this.openPanelForText(xNode.innerText);
            }
        }
    },

    openPanelForNode: function (vNode) {
        //  Parameter: a HTML node or the identifier of a HTML node
        if (vNode instanceof HTMLElement) {
            let xEvent = new CustomEvent("GrammalecteCall", { detail: {sCommand: "openPanelForNode", xNode: vNode} });
            document.dispatchEvent(xEvent);
        }
        else if (typeof(vNode) === "string" && document.getElementById(vNode)) {
            let xEvent = new CustomEvent("GrammalecteCall", { detail: {sCommand: "openPanelForNode", xNode: document.getElementById(vNode)} });
            document.dispatchEvent(xEvent);
        }
        else {
            console.log("[Grammalecte API] Error: parameter is not a HTML node.");
        }
    },

    openPanelForText: function (sText) {
        //  Parameter: text to analyze
    openPanelForText: function (sText, vNode=null) {
        //  Parameter: text to analyze, and optionaly a node to send results to.
        if (typeof(sText) === "string") {
            let xNode = null;
            if (vNode instanceof HTMLElement) {
                xNode = vNode;
            }
            else if (typeof(vNode) === "string" && document.getElementById(vNode)) {
                xNode = document.getElementById(vNode);
            }
            let xEvent = new CustomEvent("GrammalecteCall", { detail: {sCommand: "openPanelForText", sText: sText} });
            let xEvent = new CustomEvent("GrammalecteCall", { detail: {sCommand: "openPanelForText", sText: sText, xNode: xNode} });
            document.dispatchEvent(xEvent);
        } else {
            console.log("[Grammalecte API] Error: parameter is not a text.");
        }
    },

    parseNode: function (vNode) {
68
69
70
71
72
73
74



















75
76
77
78
79
80
81
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







            let xEvent = new CustomEvent("GrammalecteCall", { detail: {sCommand: "parseNode", xNode: document.getElementById(vNode)} });
            document.dispatchEvent(xEvent);
        }
        else {
            console.log("[Grammalecte API] Error: parameter is not a HTML node or doesn’t have an identifier.");
        }
    },

    parseText: function (sText, vNode) {
        //  Parameter: text to analyze, and a node to send results to.
        if (typeof(sText) === "string") {
            if (vNode instanceof HTMLElement  &&  vNode.id) {
                let xEvent = new CustomEvent("GrammalecteCall", { detail: {sCommand: "parseText", sText: sText, xNode: vNode} });
                document.dispatchEvent(xEvent);
            }
            else if (typeof(vNode) === "string" && document.getElementById(vNode)) {
                let xEvent = new CustomEvent("GrammalecteCall", { detail: {sCommand: "parseText", sText: sText, xNode: document.getElementById(vNode)} });
                document.dispatchEvent(xEvent);
            }
            else {
                console.log("[Grammalecte API] Error: parameter is not a HTML node or doesn’t have an identifier.");
            }
        } else {
            console.log("[Grammalecte API] Error: parameter is not a text.");
        }
    },

    getSpellSuggestions: function (sWord, sDestination, sRequestId="") {
        /* parameters:
            - sWord (string)
            - sDestination: HTML identifier (string) -> the result will be sent as an event “GrammalecteResult” to destination node
            - sRequestId: custom identifier for the request (string) [default = ""]
        */

Modified gc_lang/fr/webext/content_scripts/init.js from [d0cd9c03ec] to [ba5504f4c4].

182
183
184
185
186
187
188
189

190
191
192
193


194
195
196
197
198
199
200
201
182
183
184
185
186
187
188

189
190



191
192

193
194
195
196
197
198
199







-
+

-
-
-
+
+
-







    },

    startGCPanel: function (what, xResultNode=null) {
        this.createGCPanel();
        this.oGCPanel.clear();
        this.oGCPanel.show();
        this.oGCPanel.showEditor();
        this.oGCPanel.start(what);
        this.oGCPanel.start(what, xResultNode);
        this.oGCPanel.startWaitIcon();
        if (what) {
            let sText = this.oGCPanel.oTextControl.getText();
            oGrammalecteBackgroundPort.parseAndSpellcheck(sText, "__GrammalectePanel__");
        let sText = this.oGCPanel.oTextControl.getText();
        oGrammalecteBackgroundPort.parseAndSpellcheck(sText, "__GrammalectePanel__");
        }
    },

    showMessage: function (sMessage) {
        this.createMessageBox();
        this.oMessageBox.show();
        this.oMessageBox.setMessage(sMessage);
    },
530
531
532
533
534
535
536
537

538
539
540
541
542
543
544
545
546
547
548
549
550
551





552
553
554
555
556
557
558
528
529
530
531
532
533
534

535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561







-
+














+
+
+
+
+







            case "openPanelForNode":
                if (oCommand.xNode) {
                    oGrammalecte.startGCPanel(oCommand.xNode);
                }
                break;
            case "openPanelForText":
                if (oCommand.sText) {
                    oGrammalecte.startGCPanel(oCommand.sText);
                    oGrammalecte.startGCPanel(oCommand.sText, oCommand.xNode);
                }
                break;
            case "parseNode":
                if (oCommand.xNode  &&  oCommand.xNode.id) {
                    if (oCommand.xNode.tagName == "TEXTAREA"  ||  oCommand.xNode.tagName == "INPUT") {
                        oGrammalecteBackgroundPort.parseAndSpellcheck(oCommand.xNode.value, oCommand.xNode.id);
                    }
                    else if (oCommand.xNode.tagName == "IFRAME") {
                        oGrammalecteBackgroundPort.parseAndSpellcheck(oCommand.xNode.contentWindow.document.body.innerText, oCommand.xNode.id);
                    }
                    else {
                        oGrammalecteBackgroundPort.parseAndSpellcheck(oCommand.xNode.innerText, oCommand.xNode.id);
                    }
                }
                break;
            case "parseText":
                if (oCommand.sText  &&  oCommand.xNode) {
                    oGrammalecteBackgroundPort.parseAndSpellcheck(oCommand.sText, oCommand.xNode.id);
                }
                break;
            case "getSpellSuggestions":
                if (oCommand.sWord) {
                    oGrammalecteBackgroundPort.getSpellSuggestions(oCommand.sWord, oCommand.sDestination, oCommand.sErrorId);
                }
                break;
            default:

Modified gc_lang/fr/webext/content_scripts/panel_gc.js from [61b25ed2ef] to [c562cfe40e].

127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142

143

144

145
146
147

148

149
150
151
152
153
154
155
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
142
143
144
145

146
147
148
149
150

151
152
153
154
155
156
157
158







-
+








+

+
-
+



+
-
+







        this.xMenu.appendChild(this.xTFButton)
        this.xMenu.appendChild(this.xEditorButton)
        this.xMenu.appendChild(this.xLxgButton)
        this.xMenu.appendChild(this.xConjButton)
        this.xPanelBar.appendChild(this.xMenu);
    }

    start (what) {
    start (what, xResultNode=null) {
        this.oTooltip.hide();
        this.bWorking = false;
        this.clear();
        this.hideMessage();
        this.resetTimer();
        if (typeof(what) === "string") {
            // text
            this.xNode = null;
            this.oTextControl.setResultNode(xResultNode);
            this.oTextControl.setText(what);
        }
        } else if (what.nodeType && what.nodeType === 1) { // 1 = Node.ELEMENT_NODE
        else if (what.nodeType && what.nodeType === 1) { // 1 = Node.ELEMENT_NODE
            // node
            this.xNode = what;
            this.oTextControl.setNode(this.xNode);
        }
        } else {
        else {
            // error
            oGrammalecte.oMessageBox.showMessage("[BUG] Analyse d’un élément inconnu…");
            console.log("[Grammalecte] Unknown element:", what);
        }
    }

    setAutoRefreshButton () {
928
929
930
931
932
933
934

935
936
937
938
939
940
941
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945







+








    constructor () {
        this.xNode = null;
        this.dParagraph = new Map();
        this.bTextArea = false;
        this.bIframe = false;
        this.bResultInEvent = false; // if true, the node content is not modified, but an event is dispatched on the node with the modified text
        this.xResultNode = null; // only useful if for text analysed without node
    }

    setNode (xNode) {
        this.clear();
        this.xNode = xNode;
        this.bResultInEvent = Boolean(xNode.dataset.grammalecte_result_via_event && xNode.dataset.grammalecte_result_via_event == "true");
        this.bTextArea = (xNode.tagName == "TEXTAREA" || xNode.tagName == "INPUT");
953
954
955
956
957
958
959







960
961
962

963


964
965
966
967
968
969
970
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974

975
976
977
978
979
980
981
982
983







+
+
+
+
+
+
+



+
-
+
+







        }
        else {
            // editable node
            oGrammalecte.oGCPanel.addMessageToGCPanel("❗ La zone de texte analysée est un champ textuel enrichi susceptible de contenir des éléments non textuels qui seront effacés lors de la correction.");
            this.loadText(this.xNode.innerText);
        }
    }

    setResultNode (xNode) {
        if (xNode instanceof HTMLElement) {
            this.xResultNode = xNode;
            this.bResultInEvent = true;
        }
    }

    setText (sText) {
        this.clear();
        if (!this.xResultNode) {
        oGrammalecte.oGCPanel.addMessageToGCPanel("⛔ Aucun champ textuel défini. Les changements ne seront pas répercutés sur la zone d’où le texte a été extrait.");
            oGrammalecte.oGCPanel.addMessageToGCPanel("⛔ Aucun champ textuel défini. Les changements ne seront pas répercutés sur la zone d’où le texte a été extrait.");
        }
        this.loadText(sText);
    }

    loadText (sText) {
        // function also used by the text formatter
        if (typeof(sText) === "string") {
            this.dParagraph.clear();
985
986
987
988
989
990
991

992
993
994
995
996
997
998
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012







+







    clear () {
        if (this.xNode !== null) {
            this.xNode.disabled = false;
            this.bTextArea = false;
            this.bIframe = false;
            this.bResultInEvent = false;
            this.xNode = null;
            this.xResultNode = null;
        }
        this.dParagraph.clear();
    }

    getText () {
        return [...this.dParagraph.values()].join("\n").normalize("NFC");
    }
1007
1008
1009
1010
1011
1012
1013

1014





1015
1016
1017
1018
1019
1020
1021
1021
1022
1023
1024
1025
1026
1027
1028

1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040







+
-
+
+
+
+
+







        }
    }

    write () {
        if (this.xNode !== null) {
            if (this.bResultInEvent) {
                const xEvent = new CustomEvent("GrammalecteResult", { detail: JSON.stringify({ sType: "text", sText: this.getText() }) });
                if (this.xNode) {
                this.xNode.dispatchEvent(xEvent);
                    this.xNode.dispatchEvent(xEvent);
                }
                else if (this.xResultNode) {
                    this.xResultNode.dispatchEvent(xEvent);
                }
                //console.log("Text sent via an event :", xEvent.detail);
            }
            else if (this.bTextArea) {
                this.xNode.value = this.getText();
            }
            else if (this.bIframe) {
                //console.log(this.getText());

Modified grammalecte-cli.py from [bdbcf2787c] to [7b2821616b].

321
322
323
324
325
326
327
328

329
330
331
332


333
334
335
336
337
338
339
340
341
342
343
344
345
346
347

348
349
350
351
352
353
354
355
356
357
321
322
323
324
325
326
327

328

329


330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345

346
347
348
349
350
351
352
353
354
355
356







-
+
-

-
-
+
+














-
+










                oGrammarChecker.gce.displayRules(sFilter)
            elif sText in ("/quit", "/q"):
                break
            elif sText.startswith("/rl"):
                # reload (todo)
                pass
            elif sText.startswith("$"):
                for sParagraph in txt.getParagraph(sText):
                for sParagraph in txt.getParagraph(sText[1:]):
                    sText = sText[1:]
                    if xArgs.textformatter:
                        sText = oTextFormatter.formatText(sParagraph)
                    lParagraphErrors, lSentences = oGrammarChecker.gce.parse(sText, bDebug=xArgs.debug, bFullInfo=True)
                        sParagraph = oTextFormatter.formatText(sParagraph)
                    lParagraphErrors, lSentences = oGrammarChecker.gce.parse(sParagraph, bDebug=xArgs.debug, bFullInfo=True)
                    echo(txt.getReadableErrors(lParagraphErrors, xArgs.width))
                    for dSentence in lSentences:
                        echo("{nStart}:{nEnd}".format(**dSentence))
                        echo("   <" + dSentence["sSentence"]+">")
                        for dToken in dSentence["lToken"]:
                            echo("    {0[nStart]:>3}:{0[nEnd]:<3} {1} {0[sType]:<14} {2} {0[sValue]:<16} {3:<10}   {4}".format(dToken, \
                                                                                                            "×" if dToken.get("bToRemove", False) else " ",
                                                                                                            "!" if dToken["sType"] == "WORD" and not dToken.get("bValidToken", False) else " ",
                                                                                                            " ".join(dToken.get("lMorph", "")), \
                                                                                                            "·".join(dToken.get("aTags", "")) ) )
                        echo(txt.getReadableErrors(dSentence["lGrammarErrors"], xArgs.width))
            else:
                for sParagraph in txt.getParagraph(sText):
                    if xArgs.textformatter:
                        sText = oTextFormatter.formatText(sParagraph)
                        sParagraph = oTextFormatter.formatText(sParagraph)
                    sRes, _ = oGrammarChecker.getParagraphWithErrors(sParagraph, bEmptyIfNoErrors=xArgs.only_when_errors, nWidth=xArgs.width, bDebug=xArgs.debug)
                    if sRes:
                        echo("\n" + sRes)
                    else:
                        echo("\nNo error found.")
            sText = _getText(sInputText)


if __name__ == '__main__':
    main()