Grammalecte  Check-in [30b9f4680e]

Overview
Comment:[core][build] color rework
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk | core | build
Files: files | file ages | folders
SHA3-256: 30b9f4680e9aecaa6a69640b33873a2c3193ecdfd3d5bbb376054542c8fbce2d
User & Date: olr on 2018-09-25 11:10:18
Other Links: manifest | tags
Context
2018-09-25
12:02
[lo] paramater for colors check-in: 1249b779da user: olr tags: trunk, lo
11:10
[core][build] color rework check-in: 30b9f4680e user: olr tags: trunk, core, build
11:08
[fr] couleurs et faux positifs divers check-in: 52b44d5fa6 user: olr tags: trunk, fr
Changes

Modified compile_rules.py from [c923230bdf] to [6c0309c95b].

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
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







-
+

-
+


-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
-
-
-
-
+
+
+







sWORDLIMITRIGHT = r"(?![\w–-])"      # r"\b(?!-—)"       seems slower


def convertRGBToInteger (r, g, b):
    return (r & 255) << 16 | (g & 255) << 8 | (b & 255)


def convertHSLToInteger (h, s, l):
def convertHSLToRBG (h, s, l):
    r, g, b = colorsys.hls_to_rgb(h/360, l/100, s/100)
    return convertRGBToInteger(round(r*255), round(g*255), round(b*255))
    return [round(r*255), round(g*255), round(b*255)]


def createColors (lOptColor):
    dAppColor = {}
    for sApp, dOptColor in lOptColor:
        if sApp == "Writer":
            dAppColor["dOptColor"+sApp] = { sKey: convertHSLToInteger(*aColor)  for sKey, aColor in dOptColor.items() }
def createColors (dColor):
    dColorType = {
        "sCSS": {},     # dictionary of colors as strings for HTML/CSS (example: hsl(0, 50%, 50%))
        "aRGB": {},     # dictionary of colors as RGB tuple
        "nInt": {}      # dictionary of colors as integer values (for Writer)
    }
    for sKey, aHSL in dColor.items():
        elif sApp in ("Firefox", "Thunderbird"):
            dAppColor["dOptColor"+sApp] = { sKey: "hsl({}, {}%, {}%)".format(*aColor)  for sKey, aColor in dOptColor.items() }
        dColorType["sCSS"][sKey] = "hsl({}, {}%, {}%)".format(*aHSL)
        else:
            dAppColor["dOptColor"+sApp] = dOptColor
    #print(dAppColor)
    return dAppColor
        dColorType["aRGB"][sKey] = convertHSLToRBG(*aHSL)
        dColorType["nInt"][sKey] = convertRGBToInteger(*dColorType["aRGB"][sKey])
    return dColorType


def prepareFunction (s):
    "convert simple rule syntax to a string of Python code"
    s = s.replace("__also__", "bCondMemo")
    s = s.replace("__else__", "not bCondMemo")
    s = re.sub(r"isStart *\(\)", 'before("^ *$|, *$")', s)
408
409
410
411
412
413
414

415
416
417
418
419
420
421
422
423
424
425
426
427
428
429


430
431
432
433




434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450

451



452
453
454
455
456
457
458
459
460
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428


429
430
431
432
433

434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455

456
457
458
459

460
461
462
463
464
465
466







+













-
-
+
+



-
+
+
+
+

















+
-
+
+
+

-







def prepareOptions (lOptionLines):
    "returns a dictionary with data about options"
    sLang = ""
    sDefaultUILang = ""
    lStructOpt = []
    lOpt = []
    lOptColor = []
    dColor = {}
    dOptLabel = {}
    dOptPriority = {}
    for sLine in lOptionLines:
        sLine = sLine.strip()
        if sLine.startswith("OPTGROUP/"):
            m = re.match("OPTGROUP/([a-z0-9]+):(.+)$", sLine)
            lStructOpt.append( (m.group(1), list(map(str.split, m.group(2).split(",")))) )
        elif sLine.startswith("OPTSOFTWARE:"):
            lOpt = [ [s, {}]  for s in sLine[12:].strip().split() ]  # don’t use tuples (s, {}), because unknown to JS
        elif sLine.startswith("OPT/"):
            m = re.match("OPT/([a-z0-9]+):(.+)$", sLine)
            for i, sOpt in enumerate(m.group(2).split()):
                lOpt[i][1][m.group(1)] = eval(sOpt)
        elif sLine.startswith("OPTCOLORSOFTWARE:"):
            lOptColor = [ [s, {}]  for s in sLine[17:].strip().split() ]  # don’t use tuples (s, {}), because unknown to JS
        elif sLine.startswith("OPTCOLORTHEME:"):
            lOptColor = [ [s, {}]  for s in sLine[14:].strip().split() ]  # don’t use tuples (s, {}), because unknown to JS
        elif sLine.startswith("OPTCOLOR/"):
            m = re.match("OPTCOLOR/([a-z0-9]+):(.+)$", sLine)
            for i, sColor in enumerate(m.group(2).split()):
                lOptColor[i][1][m.group(1)] = [ int(s) for s in sColor.split(",") ]
                lOptColor[i][1][m.group(1)] = sColor
        elif sLine.startswith("COLOR/"):
            m = re.match("COLOR/([a-z0-9]+):(.+)$", sLine)
            dColor[m.group(1)] = [ int(s) for s in m.group(2).strip().split(",") ]
        elif sLine.startswith("OPTPRIORITY/"):
            m = re.match("OPTPRIORITY/([a-z0-9]+): *([0-9])$", sLine)
            dOptPriority[m.group(1)] = int(m.group(2))
        elif sLine.startswith("OPTLANG/"):
            m = re.match("OPTLANG/([a-z][a-z](?:_[A-Z][A-Z]|)):(.+)$", sLine)
            sLang = m.group(1)[:2]
            dOptLabel[sLang] = { "__optiontitle__": m.group(2).strip() }
        elif sLine.startswith("OPTDEFAULTUILANG:"):
            m = re.match("OPTDEFAULTUILANG: *([a-z][a-z](?:_[A-Z][A-Z]|))$", sLine)
            sDefaultUILang = m.group(1)[:2]
        elif sLine.startswith("OPTLABEL/"):
            m = re.match("OPTLABEL/([a-z0-9]+):(.+)$", sLine)
            dOptLabel[sLang][m.group(1)] = list(map(str.strip, m.group(2).split("|")))  if "|" in m.group(2)  else  [m.group(2).strip(), ""]
        else:
            print("# Error. Wrong option line in:\n  ")
            print(sLine)
    print("  options defined for: " + ", ".join([ t[0] for t in lOpt ]))
    dOptions = {
    dOptions = { "lStructOpt": lStructOpt, "dOptLabel": dOptLabel, "sDefaultUILang": sDefaultUILang }
        "lStructOpt": lStructOpt, "dOptLabel": dOptLabel, "sDefaultUILang": sDefaultUILang, \
        "dColorType": createColors(dColor), "dOptColor": { s: d  for s, d in lOptColor }
    }
    dOptions.update({ "dOpt"+k: v  for k, v in lOpt })
    dOptions.update(createColors(lOptColor))
    return dOptions, dOptPriority


def printBookmark (nLevel, sComment, nLine):
    "print bookmark within the rules file"
    print("  {:>6}:  {}".format(nLine, "  " * nLevel + sComment))

497
498
499
500
501
502
503
504

505
506
507
508
509
510
511
503
504
505
506
507
508
509

510
511
512
513
514
515
516
517







-
+







        elif sLine.startswith("TEST:"):
            # test
            lTest.append("{:<8}".format(i) + "  " + sLine[5:].strip())
        elif sLine.startswith("TODO:"):
            # todo
            pass
        elif sLine.startswith(("OPTGROUP/", "OPTSOFTWARE:", "OPT/", \
                                "OPTCOLORSOFTWARE:", "OPTCOLOR/", \
                                "COLOR/", "OPTCOLORTHEME:", "OPTCOLOR/", \
                                "OPTLANG/", "OPTDEFAULTUILANG:", \
                                "OPTLABEL/", "OPTPRIORITY/")):
            # options
            lOpt.append(sLine)
        elif sLine.startswith("!!"):
            # bookmark
            m = re.match("!!+", sLine)

Modified gc_core/js/lang_core/gc_options.js from [c30eb8d096] to [7c4c47e8f5].

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
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







-
-
-
+
+
+
+
+
+
+
+
+
+

+
+
-
+
+










-
-
-
+
+
+
-
-










+



    getOptions: function (sContext="JavaScript") {
        if (this.dOpt.hasOwnProperty(sContext)) {
            return this.dOpt[sContext];
        }
        return this.dOpt["JavaScript"];
    },

    getOptionsColors: function (sContext="JavaScript") {
        if (this.dOptColor.hasOwnProperty(sContext)) {
            return this.dOptColor[sContext];
    getOptionsColors: function (sTheme="Default", sColorType="aRGB") {
        let dOptColor = (this.dOptColor.hasOwnProperty()) ? this.dOptColor[sTheme] : this.dOptColor["Default"];
        let dColorType = (this.dColorType.hasOwnProperty(sColorType)) ? this.dColorType[sColorType] : this.dColorType["aRGB"];
        let dColor = {};
        try {
            for (let [sOpt, sColor] of Object.entries(this.dOptColor)) {
                dColor[sOpt] = dColorType[sColor];
            }
            console.log(dColor);
            return dColor;
        }
        catch (e) {
            console.error(e);
        return this.dOptColor["JavaScript"];
            return {}
        }
    },

    lStructOpt: ${lStructOpt},

    dOpt: {
        "JavaScript": new Map (${dOptJavaScript}),
        "Firefox": new Map (${dOptFirefox}),
        "Thunderbird": new Map (${dOptThunderbird}),
    },

    dOptColor: {
        "JavaScript": new Map (${dOptColorJavaScript}),
        "Firefox": new Map (${dOptColorFirefox}),
    dColorType: ${dColorType},

    dOptColor: ${dOptColor},
        "Thunderbird": new Map (${dOptColorThunderbird}),
    },

    dOptLabel: ${dOptLabel}
}


if (typeof(exports) !== 'undefined') {
	exports.getOptions = gc_options.getOptions;
    exports.getOptionsColors = gc_options.getOptionsColors;
	exports.lStructOpt = gc_options.lStructOpt;
    exports.dOpt = gc_options.dOpt;
    exports.dColorType = gc_options.dColorType;
    exports.dOptColor = gc_options.dOptColor;
	exports.dOptLabel = gc_options.dOptLabel;
}

Modified gc_core/py/lang_core/gc_engine.py from [b1e910dee6] to [10f4857be2].

41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56

57
58
59
60

61
62
63
64
65

66
67
68
69
70
71
72
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75







+








-
+




+





+







# Modules
_rules = None                               # module gc_rules
_rules_graph = None                         # module gc_rules_graph

# Data
_sAppContext = ""                           # what software is running
_dOptions = None
_dOptionsColors = None
_oSpellChecker = None
_oTokenizer = None
_aIgnoredRules = set()



#### Initialization

def load (sContext="Python"):
def load (sContext="Python", sColorType="aRGB"):
    "initialization of the grammar checker"
    global _oSpellChecker
    global _sAppContext
    global _dOptions
    global _dOptionsColors
    global _oTokenizer
    try:
        _oSpellChecker = SpellChecker("${lang}", "${dic_main_filename_py}", "${dic_extended_filename_py}", "${dic_community_filename_py}", "${dic_personal_filename_py}")
        _sAppContext = sContext
        _dOptions = dict(gc_options.getOptions(sContext))   # duplication necessary, to be able to reset to default
        _dOptionsColors = gc_options.getOptionsColors(sContext, sColorType)
        _oTokenizer = _oSpellChecker.getTokenizer()
        _oSpellChecker.activateStorage()
    except:
        traceback.print_exc()


def getSpellChecker ():
607
608
609
610
611
612
613
614

615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635

636
637
638
639

640
641
642
643
644
645
646
647
648
649

650
651
652

653
654

655
656
657
658
659
660
661
662
663

664
665
666
667
668
669
670
610
611
612
613
614
615
616

617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637

638
639
640
641

642
643
644
645
646
647
648
649
650
651

652
653
654

655
656

657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674







-
+




















-
+



-
+









-
+


-
+

-
+









+







            lSugg = list(map(str.capitalize, lSugg))
        # Message
        sMessage = globals()[sMsg[1:]](sText, m)  if sMsg[0:1] == "="  else  m.expand(sMsg)
        if bShowRuleId:
            sMessage += "  # " + sLineId + " # " + sRuleId
        #
        if _bWriterError:
            return self._createErrorForWriter(nStart, nEnd - nStart, sRuleId, sMessage, lSugg, sURL)
            return self._createErrorForWriter(nStart, nEnd - nStart, sRuleId, sOption, sMessage, lSugg, sURL)
        else:
            return self._createErrorAsDict(nStart, nEnd, sLineId, sRuleId, sOption, sMessage, lSugg, sURL, bContext)

    def _createErrorFromTokens (self, sSugg, nTokenOffset, nLastToken, iFirstToken, nStart, nEnd, sLineId, sRuleId, bCaseSvty, sMsg, sURL, bShowRuleId, sOption, bContext):
        # suggestions
        if sSugg[0:1] == "=":
            sSugg = globals()[sSugg[1:]](self.lToken, nTokenOffset, nLastToken)
            lSugg = sSugg.split("|")  if sSugg  else []
        elif sSugg == "_":
            lSugg = []
        else:
            lSugg = self._expand(sSugg, nTokenOffset, nLastToken).split("|")
        if bCaseSvty and lSugg and self.lToken[iFirstToken]["sValue"][0:1].isupper():
            lSugg = list(map(lambda s: s[0:1].upper()+s[1:], lSugg))
        # Message
        sMessage = globals()[sMsg[1:]](self.lToken, nTokenOffset, nLastToken)  if sMsg[0:1] == "="  else self._expand(sMsg, nTokenOffset, nLastToken)
        if bShowRuleId:
            sMessage += "  " + sLineId + " # " + sRuleId
        #
        if _bWriterError:
            return self._createErrorForWriter(nStart, nEnd - nStart, sRuleId, sMessage, lSugg, sURL)
            return self._createErrorForWriter(nStart, nEnd - nStart, sRuleId, sOption, sMessage, lSugg, sURL)
        else:
            return self._createErrorAsDict(nStart, nEnd, sLineId, sRuleId, sOption, sMessage, lSugg, sURL, bContext)

    def _createErrorForWriter (self, nStart, nLen, sRuleId, sMessage, lSugg, sURL):
    def _createErrorForWriter (self, nStart, nLen, sRuleId, sOption, sMessage, lSugg, sURL):
        xErr = SingleProofreadingError()    # uno.createUnoStruct( "com.sun.star.linguistic2.SingleProofreadingError" )
        xErr.nErrorStart = nStart
        xErr.nErrorLength = nLen
        xErr.nErrorType = PROOFREADING
        xErr.aRuleIdentifier = sRuleId
        xErr.aShortComment = sMessage   # sMessage.split("|")[0]     # in context menu
        xErr.aFullComment = sMessage    # sMessage.split("|")[-1]    # in dialog
        xErr.aSuggestions = tuple(lSugg)
        #xPropertyLineType = PropertyValue(Name="LineType", Value=5) # DASH or WAVE
        #xPropertyLineColor = PropertyValue(Name="LineColor", Value=getRGB("FFAA00"))
        xPropertyLineColor = PropertyValue(Name="LineColor", Value=_dOptionsColors.get(sOption, 33023))
        if sURL:
            xPropertyURL = PropertyValue(Name="FullCommentURL", Value=sURL)
            xErr.aProperties = (xPropertyURL,)
            xErr.aProperties = (xPropertyURL, xPropertyLineColor)
        else:
            xErr.aProperties = ()
            xErr.aProperties = (xPropertyLineColor,)
        return xErr

    def _createErrorAsDict (self, nStart, nEnd, sLineId, sRuleId, sOption, sMessage, lSugg, sURL, bContext):
        dErr = {
            "nStart": nStart,
            "nEnd": nEnd,
            "sLineId": sLineId,
            "sRuleId": sRuleId,
            "sType": sOption  if sOption  else "notype",
            "aColor": _dOptionsColors.get(sOption, [100, 100, 255]),
            "sMessage": sMessage,
            "aSuggestions": lSugg,
            "URL": sURL
        }
        if bContext:
            dErr['sUnderlined'] = self.sText0[nStart:nEnd]
            dErr['sBefore'] = self.sText0[max(0,nStart-80):nStart]

Modified gc_core/py/lang_core/gc_options.py from [f5b1b8c491] to [d511603a82].

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
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





+
+










-
-
-
+
+
+


-
-
-
-
-
+
+
+
+
+
+
+
+
+





-
+





-
+
-
-
-
-
+
+


"""
Grammar checker default options
"""

# generated code, do not edit

import traceback

def getUI (sLang):
    "returns dictionary of UI labels"
    if sLang in _dOptLabel:
        return _dOptLabel[sLang]
    return _dOptLabel["fr"]


def getOptions (sContext="Python"):
    "returns dictionary of options"
    if sContext in dOpt:
        return dOpt[sContext]
    return dOpt["Python"]
    if sContext in _dOpt:
        return _dOpt[sContext]
    return _dOpt["Python"]


def getOptionsColors (sContext="Python"):
    "returns dictionary of options"
    if sContext in dOptColor:
        return dOptColor[sContext]
    return dOptColor["Python"]
def getOptionsColors (sTheme="Default", sColorType="aRGB"):
    "returns dictionary of options colors"
    dOptColor = _dOptColor[sTheme]  if sTheme in _dOptColor  else  _dOptColor["Default"]
    dColorType = _dColorType[sColorType]  if sColorType in _dColorType  else _dColorType["aRGB"]
    try:
        return {  sOpt: dColorType[sColor] for sOpt, sColor in dOptColor.items() }
    except:
        traceback.print_exc()
        return {}


lStructOpt = ${lStructOpt}


dOpt = {
_dOpt = {
    "Python": ${dOptPython},
    "Server": ${dOptServer},
    "Writer": ${dOptWriter}
}

dOptColor = {
_dColorType= ${dColorType}
    "Python": ${dOptColorPython},
    "Server": ${dOptColorServer},
    "Writer": ${dOptColorWriter}
}

_dOptColor = ${dOptColor}

_dOptLabel = ${dOptLabel}

Modified gc_lang/fr/webext/content_scripts/panel_gc.css from [a76956d409] to [4ec3ab92b0].

64
65
66
67
68
69
70
71

72
73
74
75
76
77
78
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78







-
+







}
div.grammalecte_paragraph_actions .grammalecte_red:hover {
    background-color: hsl(0, 50%, 40%);
    color: hsl(0, 0%, 100%);
}


/* 
/*
    TOOLTIP
*/
img#grammalecte_tooltip_arrow {
    position: absolute;
    display: none;
}

261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279












280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297












298
299
300
301
302
303
304
261
262
263
264
265
266
267












268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285












286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304







-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+






-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+







mark.grammalecte_error_WORD:hover {
    background-color: hsl(0, 60%, 40%);
    color: hsl(0, 0%, 100%);
    box-shadow: 0px 0px 0px 3px hsla(0, 50%, 50%, 0.2);
}

/* elems */
mark.grammalecte_error_typo, 
mark.grammalecte_error_esp, 
mark.grammalecte_error_nbsp, 
mark.grammalecte_error_eif, 
mark.grammalecte_error_maj, 
mark.grammalecte_error_virg, 
mark.grammalecte_error_tu, 
mark.grammalecte_error_num, 
mark.grammalecte_error_unit, 
mark.grammalecte_error_nf, 
mark.grammalecte_error_liga, 
mark.grammalecte_error_mapos, 
mark.grammalecte_error_typo,
mark.grammalecte_error_esp,
mark.grammalecte_error_nbsp,
mark.grammalecte_error_eif,
mark.grammalecte_error_maj,
mark.grammalecte_error_virg,
mark.grammalecte_error_tu,
mark.grammalecte_error_num,
mark.grammalecte_error_unit,
mark.grammalecte_error_nf,
mark.grammalecte_error_liga,
mark.grammalecte_error_mapos,
mark.grammalecte_error_chim {
    background-color: hsl(30, 70%, 50%);
    color: hsl(30, 10%, 96%);
    /*text-decoration: underline wavy hsl(30, 70%, 50%);*/
}

mark.grammalecte_error_typo:hover, 
mark.grammalecte_error_esp:hover, 
mark.grammalecte_error_nbsp:hover, 
mark.grammalecte_error_eif:hover, 
mark.grammalecte_error_maj:hover, 
mark.grammalecte_error_virg:hover, 
mark.grammalecte_error_tu:hover, 
mark.grammalecte_error_num:hover, 
mark.grammalecte_error_unit:hover, 
mark.grammalecte_error_nf:hover, 
mark.grammalecte_error_liga:hover, 
mark.grammalecte_error_mapos:hover, 
mark.grammalecte_error_typo:hover,
mark.grammalecte_error_esp:hover,
mark.grammalecte_error_nbsp:hover,
mark.grammalecte_error_eif:hover,
mark.grammalecte_error_maj:hover,
mark.grammalecte_error_virg:hover,
mark.grammalecte_error_tu:hover,
mark.grammalecte_error_num:hover,
mark.grammalecte_error_unit:hover,
mark.grammalecte_error_nf:hover,
mark.grammalecte_error_liga:hover,
mark.grammalecte_error_mapos:hover,
mark.grammalecte_error_chim:hover {
    background-color: hsl(30, 80%, 45%);
    color: hsl(30, 10%, 96%);
    box-shadow: 0px 0px 0px 3px hsla(30, 50%, 50%, 0.2);
}

/* elems */
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
358
359
360
361

362
363
364
365
366
367
368
369
370
371
372
373
374
375







376
377
378
379
380
381
382
383
384
385
386
387
388







389
390
391
392
393
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
358
359
360

361
362
363
364
365
366
367
368







369
370
371
372
373
374
375
376
377
378
379
380
381







382
383
384
385
386
387
388
389
390
391
392
393







-
-
-
-
-
+
+
+
+
+






-
-
-
-
-
+
+
+
+
+







-
+






-
+







-
-
-
-
-
-
-
+
+
+
+
+
+
+






-
-
-
-
-
-
-
+
+
+
+
+
+
+





mark.grammalecte_error_sgpl:hover {
    background-color: hsl(210, 60%, 40%);
    color: hsl(210, 10%, 96%);
    box-shadow: 0px 0px 0px 3px hsla(210, 50%, 50%, 0.2);
}

/* elems */
mark.grammalecte_error_conj, 
mark.grammalecte_error_infi, 
mark.grammalecte_error_imp, 
mark.grammalecte_error_inte, 
mark.grammalecte_error_ppas, 
mark.grammalecte_error_conj,
mark.grammalecte_error_infi,
mark.grammalecte_error_imp,
mark.grammalecte_error_inte,
mark.grammalecte_error_ppas,
mark.grammalecte_error_vmode  {
    background-color: hsl(300, 30%, 40%);
    color: hsl(300, 10%, 96%);
    /*text-decoration: underline wavy hsl(300, 40%, 40%);*/
}

mark.grammalecte_error_conj:hover, 
mark.grammalecte_error_infi:hover, 
mark.grammalecte_error_imp:hover, 
mark.grammalecte_error_inte:hover, 
mark.grammalecte_error_ppas:hover, 
mark.grammalecte_error_conj:hover,
mark.grammalecte_error_infi:hover,
mark.grammalecte_error_imp:hover,
mark.grammalecte_error_inte:hover,
mark.grammalecte_error_ppas:hover,
mark.grammalecte_error_vmode:hover {
    background-color: hsl(300, 40%, 30%);
    color: hsl(300, 10%, 96%);
    box-shadow: 0px 0px 0px 3px hsla(300, 50%, 50%, 0.2);
}

/* elems */
mark.grammalecte_error_conf, 
mark.grammalecte_error_conf,
mark.grammalecte_error_ocr {
    background-color: hsl(270, 40%, 30%);
    color: hsl(270, 10%, 96%);
    /*text-decoration: underline wavy hsl(270, 40%, 30%);*/
}

mark.grammalecte_error_conf:hover, 
mark.grammalecte_error_conf:hover,
mark.grammalecte_error_ocr:hover {
    background-color: hsl(270, 50%, 20%);
    color: hsl(270, 10%, 96%);
    box-shadow: 0px 0px 0px 3px hsla(270, 50%, 50%, 0.2);
}

/* elems */
mark.grammalecte_error_bs, 
mark.grammalecte_error_pleo, 
mark.grammalecte_error_neg, 
mark.grammalecte_error_redon1, 
mark.grammalecte_error_redon2, 
mark.grammalecte_error_mc, 
mark.grammalecte_error_date, 
mark.grammalecte_error_bs,
mark.grammalecte_error_pleo,
mark.grammalecte_error_neg,
mark.grammalecte_error_redon1,
mark.grammalecte_error_redon2,
mark.grammalecte_error_mc,
mark.grammalecte_error_date,
mark.grammalecte_error_notype {
    background-color: hsl(180, 50%, 40%);
    color: hsl(180, 10%, 96%);
    /*text-decoration: underline wavy hsl(180, 50%, 40%);*/
}

mark.grammalecte_error_bs:hover, 
mark.grammalecte_error_pleo:hover, 
mark.grammalecte_error_neg:hover, 
mark.grammalecte_error_redon1:hover, 
mark.grammalecte_error_redon2:hover, 
mark.grammalecte_error_mc:hover, 
mark.grammalecte_error_date:hover, 
mark.grammalecte_error_bs:hover,
mark.grammalecte_error_pleo:hover,
mark.grammalecte_error_neg:hover,
mark.grammalecte_error_redon1:hover,
mark.grammalecte_error_redon2:hover,
mark.grammalecte_error_mc:hover,
mark.grammalecte_error_date:hover,
mark.grammalecte_error_notype:hover {
    background-color: hsl(180, 60%, 30%);
    color: hsl(180, 10%, 96%);
    box-shadow: 0px 0px 0px 3px hsla(180, 50%, 50%, 0.2);
}