From b090d5898540609a1dd936884ebbb4a4dff52d81 Mon Sep 17 00:00:00 2001 From: NSoiffer Date: Fri, 27 Sep 2024 15:28:30 -0700 Subject: [PATCH 001/157] Initial commit for French braille. 24 test passes, 3 test failures --- Rules/Braille/French/French_Rules.yaml | 937 +++++++++++++++++++++ Rules/Braille/French/definitions.yaml | 2 + Rules/Braille/French/unicode-full.yaml | 1027 ++++++++++++++++++++++++ Rules/Braille/French/unicode.yaml | 317 ++++++++ src/braille.rs | 190 ++++- tests/braille/French/chemistry.rs | 47 ++ tests/braille/French/french.rs | 138 ++++ 7 files changed, 2648 insertions(+), 10 deletions(-) create mode 100644 Rules/Braille/French/French_Rules.yaml create mode 100644 Rules/Braille/French/definitions.yaml create mode 100644 Rules/Braille/French/unicode-full.yaml create mode 100644 Rules/Braille/French/unicode.yaml create mode 100644 tests/braille/French/chemistry.rs create mode 100644 tests/braille/French/french.rs diff --git a/Rules/Braille/French/French_Rules.yaml b/Rules/Braille/French/French_Rules.yaml new file mode 100644 index 000000000..3dad1abe3 --- /dev/null +++ b/Rules/Braille/French/French_Rules.yaml @@ -0,0 +1,937 @@ +--- +- + name: whitespace-omission + tag: "!*" + match: "not(self::m:math) and not($MatchingWhitespace) and (@data-previous-space-width >= 0.25 or @data-following-space-width >= 0.25)" + replace: + - with: + variables: [MatchingWhitespace: "true()"] + replace: + - test: + - if: "(@class='MathML-unit' or BaseNode(.)[@class='MathML-unit']) and @data-previous-space-width >= 0.25" # BANA 5.3(a) + then: [t: "𝐖"] + - else_if: "@data-previous-space-width > 1.1" + then: [t: "⠬"] + - else_if: "@data-previous-space-width >= 0.25" # thickspace + then: [t: "W"] + - x: "." + - test: + - if: "(@class='MathML-unit' or BaseNode(.)[@class='MathML-unit']) and @data-following-space-width >= 0.25" # BANA 5.3(a) + then: [t: "𝐖"] + - else_if: "@data-following-space-width > 1.1" + then: [t: "⠬"] + - else_if: "@data-following-space-width >= 0.25" # thickspace + then: [t: "W"] + +- + name: omission-intent + tag: "!*" + match: "contains(@intent, ':blank')" + replace: + - t: "⠬" + +- + name: unicode-override + tag: "*" + match: "@data-unicode" + replace: + - x: "@data-unicode" + +- + name: default + tag: msqrt + match: "." + replace: + - t: "⠜" + - test: + if: "NeedsToBeGrouped(*[1], 'French', true())" + then: + - t: "⠰" + - x: "*[1]" + - t: "⠆" + else: + - x: "*[1]" + +- + name: default + tag: mroot + match: "." + replace: + - t: "⠈" + - test: + if: "NeedsToBeGrouped(*[2], 'French', true())" + then: + - t: "⠰" + - x: "*[2]" + - t: "⠆" + else: + - x: "*[2]" + - t: "⠜" + - test: + if: "NeedsToBeGrouped(*[1], 'French', true())" + then: + - t: "⠰" + - x: "*[1]" + - t: "⠆" + else: + - x: "*[1]" + + +# Fraction rules + # The fraction part of a mixed number is always simple + # They also differ because a two character sequence is needed to bracket the fraction + # The invisible plus should produce an empty string + +- + name: common-fraction-mixed-number + tag: mfrac + match: + - "preceding-sibling::*[1][self::m:mo][text()='\u2064'] and" # preceding element is invisible plus + - "*[1][self::m:mn][not(contains(., '.'))] and" + - "*[2][self::m:mn][not(contains(., '.'))]" + replace: + - t: "#" # signal end of previous numeric mode + - x: "*[1]" + - t: "N⠌" + - x: "*[2]" + +- + name: default + tag: mfrac + match: "." + replace: + - test: + if: "DEBUG(NeedsToBeGrouped(DEBUG(*[1]), 'French', true()))" + then: + - t: "⠰" + - x: "*[1]" + - t: "⠆" + else: + - x: "*[1]" + - t: "⠌" + - test: + if: "NeedsToBeGrouped(*[2], 'French', true())" + then: + - t: "⠰" + - x: "*[2]" + - t: "⠆" + else: + - x: "*[2]" + +- + #GTM 14.3.3 (not sure what else vertical juxtaposition applies to) + name: binomial-frac + tag: mrow + match: "IsBracketed(., '(', ')') and *[2][self::m:mfrac][@linethickness=0]" + replace: + - x: "*[1]" + - x: "*[2]/*[1]" + - t: "⠰⠻" + - x: "*[2]/*[2]" + - x: "*[3]" + +- name: binomial-table + tag: mrow + match: "IsBracketed(., '(', ')') and *[2][self::m:mtable][count(*)=2 and count(*[1])=1] and contains(@intent, 'binomial(')" + replace: + - x: "*[1]" + - x: "*[2]/*[1]/*[1]/*[1]" + - t: "⠰⠻" + - x: "*[2]/*[2]/*[1]/*[1]" + - x: "*[3]" + +# +# Matrix/Determinant rules +# matrix and determinant are the same other than "matrix"/"determinant" based on the bracketing chars +# we don't do spatial layout, instead the beginning/ending of each row uses the enlarged bracketing chars +- + name: default-matrix + tag: mrow + variables: + - RowStart: "*[1]" + - RowEnd: "*[3]" + match: + - "*[2][self::m:mtable] and" + - (IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')) + replace: [x: "*[2]"] +- + name: default-mtable + tag: mtable + match: "." + replace: [x: "*"] +- + name: default + tag: [mtr, mlabeledtr] + match: "." + replace: + - test: + if: "preceding-sibling::*" + then: [t: "W⠠⠜W"] + - t: "" + - x: $RowStart + + # - test: + # if: .[self::m:mlabeledtr] + # then: + # - t: "⠗⠕⠺W⠇⠁⠃⠑⠇⠸⠒" # "row label:" + # - x: "*[1]/*" # contents of row label + - test: + if: .[self::m:mlabeledtr] + then: [x: "*[position()>1]"] + else: {x: "*"} + - x: $RowEnd + + +- + name: empty + tag: mtd + match: ".=''" + replace: + - t: "⠐⠂" + +- + name: default + tag: mtd + match: "." + replace: + - test: + if: "*" + then: + - test: + if: "preceding-sibling::*" + then: [t: "W"] + - x: "*" + # else nothing to braille + +- + name: no-content + tag: math + match: "not(*)" # empty + replace: [t: "W"] # not sure that is right, but this shouldn't happen + +- + name: default + tag: math + match: "." + variables: + - RowStart: "''" # empty string -- it needs to be set + - RowEnd: "''" # empty string -- it needs to be set + - NewScriptContext: "''" # empty string -- it needs to be set + - MatchingWhitespace: "false()" + replace: [x: "*"] + +- + name: empty-mrow + tag: mrow + match: "not(*)" + replace: [t: "W"] # not sure what is correct -- if in a fraction, probably something is better than nothing + +- + # From 14.5, 14.6, and 14.7 -- need to add block indicators around the argument unless it has parens + name: trig-functions + tag: mrow + match: "count(*)=3 and *[2]='\u2061' and + IsInDefinition(BaseNode(*[1]), 'Braille', 'TrigFunctionNames') and not(IsBracketed(*[3], '(', ')'))" + replace: + - x: "*[1]" + - t: "⠰" + - x: "*[3]" + - t: "⠆" + + +- + name: default + tag: mrow + match: "." + replace: [x: "*"] + + +- + # operator omission + name: operator-omission + tag: mo + # normally(?) this is an omission, but the case 6'2" causes problems due to WIRIS + # in that case, it doesn't put the ft/in in a superscript and thinks the space is an operator + # canonicalization moves them into with base , so this shouldn't be an omission for that case + match: ".='\u00A0' and @width > 1.1 and + not( preceding-sibling::*[1][self::m:msup and *[2][self::m:mo]] and + following-sibling::*[1][self::m:msup and *[2][self::m:mo]] )" + replace: + - t: "⠬" # empty space for omission + +- + # "∼" can be a prefix *operator* or an infix comparison -- they have different spacing. We catch the prefix version here + # Note: ASCII "~" has been canonicalized to occur only in a diacritical position + name: prefix-tilde + tag: mo + match: "translate(., '∼', '')='' and not(preceding-sibling::*) and parent::m:mrow" + replace: + - x: "text()" + +- + name: default + tag: mo + # add spaces around comparison operators unless they are in a script position, + variables: # ratio not spaced in UEB; also make sure it is an infix operator (e.g., "~" can be prefix) + - AddSpaces: "$UEB_UseSpacesAroundAllOperators" + match: "." + replace: + - test: + if: "$AddSpaces" + then: + - test: + if: "preceding-sibling::*" + then: [t: "W"] + - x: "text()" + - test: + if: "$AddSpaces and following-sibling::*" + then: [t: "W"] + + +- + name: default + tag: mn + match: "." + replace: + - x: "BrailleChars(., 'French')" +- + name: default + tag: [mi, mtext] + match: "." + replace: + - x: "BrailleChars(., 'French')" + +- + name: default + tag: mstyle + match: "." + replace: + - test: + if: "*" + then: [x: "*"] + # else do nothing -- no content + +- + name: mhchem-hack + # this captures the output for the mhchem's "<=>", "<<=>", and "<=>>" output (there are no Unicode arrows for them) + # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/NSoiffer/MathCAT/issues/60) + tag: mover + match: + - "*[1][substring(., 1, 1)='↽'] and" + - "*[2][substring(., string-length(), 1)='⇀']" + replace: + - t: "W" + - test: + if: "*[1][self::m:mrow]" + then_test: + if: "*[2][self::m:mrow]" + then: [x: "'🣑'"] # 0x1f8d1 -- this is currently unassigned and may get used by UTC at some point (<=>) + else: [x: "'🣓'"] # 0x1f8d3 -- this is currently unassigned and may get used by UTC at some point (<<=>) + else: [x: "'🣒'"] # 0x1f8d2 -- this is currently unassigned and may get used by UTC at some point (<=>>) + - t: "W" + +- + # special hack to catch double over/under bar built from nested mover/munder + name: doubled-line-hack-exception + tag: [mover, munder] + match: + - "*[2][self::m:mo and string-length(.) = 1 and (.='¯')] and" # has line/bar + - "( (self::m:mover and *[1][self::m:mover]) or (self::m:munder and *[1][self::m:munder]) ) and" # both mover/munder + - "*[1]/*[2][self::m:mo and string-length(.) = 1 and (.='¯')]" # other mover/munder has line/bar + replace: + - test: + if: "self::m:munder" + then: [t: "⠨"] + - t: "⠘⠸⠒" + - test: + if: "NeedsToBeGrouped(*[1], 'French', true())" + then: + - t: "⠰" + - x: "*[1]" + - t: "⠆" + else: [x: "*[1]"] + +- + name: single-char-exceptions # GTM 12 + tag: [mover, munder] + match: "*[2][string-length(.) = 1 and translate(., '_¯→.·˙~^⌄⌒','')='']" + replace: + - test: + if: "self::m:munder" + then: [t: "⠨"] + - test: + - if: "*[2][text()='_' or text()='¯']" + then: [t: "⠸⠒"] + - else_if: "*[2][text()='→']" + then: [t: "⠨⠒"] + - else_if: "*[2][text()='.' or text()='·' or text()='˙']" + then: [t: "⠂"] # FIX: couldn't find an example + - else_if: "*[2][text()='~']" + then: [t: "⠐⠸⠒"] + - else_if: "*[2][text()='^']" + then: [t: "⠘⠒"] + - else_if: "*[2][text()='⌄']" + then: [t: "⠸⠘⠒"] + else: [t: "⠈⠒"] # arc/⌒ + # The examples in 12.1 never group the base, but this seems dubious. Needs to be confirmed + # - test: + # if: "NeedsToBeGrouped(*[1], 'French', true())" + # then: + # - t: "⠰" + # - x: "*[1]" + # - t: "⠆" + # else: [x: "*[1]"] + - x: "*[1]" + +- + # In French braille, we drop the script indicators in both subscripts and superscripts for: + # msub: chemistry (e.g., H20) + # msup: primes + # We combine them here + name: single-char-exceptions + tag: [msub, msup] + match: "(self::m:msub and @data-chem-formula) or (self::m:msup and *[2][translate(., \"'′″‴\",'')=''])" + replace: + - test: + if: "NeedsToBeGrouped(*[1], 'French', true())" + then: + - t: "⠰" + - x: "*[1]" + - t: "⠆" + else: [x: "*[1]"] + - x: "*[2]" + +- + name: default + tag: [msub, msup, munder, mover] + match: "." + variables: [AddSpaces: "(self::m:munder or self::m:mover) and IsInDefinition(BaseNode(*[1]), 'Braille', 'NemethComparisonOperators')"] + replace: + - test: + if: "$AddSpaces" + then: [t: "W"] + - test: + if: "NeedsToBeGrouped(*[1], 'French', self::m:msub or self::m:msup)" + then: + - t: "⠰" + - x: "*[1]" + - t: "⠆" + else: [x: "*[1]"] + - with: # this could be tighter and be just around the *[2] part, but this is consistent with msubsup below + variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string + replace: + - test: + - if: "self::m:msup" + then: [t: "⠈"] + - else_if: "self::m:msub" + then: [t: "⠢"] + - else_if: "self::m:munder" + then: [t: "⠢⠢"] + else: [t: "⠈⠈"] # mover + - test: + if: "NeedsToBeGrouped(*[2], 'French', false())" + then: + - t: "⠰" + - x: "*[2]" + - t: "⠆" + else: [x: "*[2]"] + - t: "#" # signal end script/numeric mode + - test: + if: "$AddSpaces" + then: [t: "W"] + + + +- + name: msubsup_default_mmultiscripts_equiv + tag: [msubsup, munderover, mmultiscripts] # mmultiscripts with only sub/sup postscript + match: "count(*)=3" # catches mmultiscripts equiv + variables: [IsPrimeSuperScript: "not(self::m:munderover) and *[3][translate(., \"'′″‴\",'')='']"] + replace: + - test: + if: "NeedsToBeGrouped(*[1], 'French', self::m:msubsup)" + then: + - t: "⠰" + - x: "*[1]" + - t: "⠆" + else: [x: "*[1]"] + - test: + if: "$IsPrimeSuperScript" + then: [x: "*[3]"] + - with: + variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string + replace: + - test: + if: "self::m:munderover" + then: [t: "⠢⠢"] + else: [t: "⠢"] + - test: + if: "NeedsToBeGrouped(*[2], 'French', false())" + then: + - t: "⠰" + - x: "*[2]" + - t: "⠆" + else: [x: "*[2]"] + - test: + if: "not($IsPrimeSuperScript)" + then: + - test: + if: "self::m:munderover" + then: [t: "⠈⠈"] + else: [t: "⠈"] + - test: + if: "NeedsToBeGrouped(*[3], 'French', false())" + then: + - t: "⠰" + - x: "*[3]" + - t: "⠆" + else: [x: "*[3]"] + + +- +# See 9.5, remark before last example about atomic numbers (they are *after* the base preceded by dot 6) + name: atomic-number + tag: mmultiscripts + match: "count(*)=4 and *[2][self::m:mprescripts] and @data-chem-formula" + replace: + - x: "*[1]" + - test: + if: "not(*[3][self::m:none])" + then: + - with: + variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string + replace: + - t: "⠠⠢" + - test: + if: "NeedsToBeGrouped(*[3], 'French', true())" + then: + - t: "⠰" + - x: "*[3]" + - t: "⠆" + else: [x: "*[3]"] + - test: + if: "not(*[4][self::m:none])" + then: + - with: + variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string + replace: + - t: "⠠⠈" + - test: + if: "NeedsToBeGrouped(*[4], 'French', false())" + then: + - t: "⠰" + - x: "*[4]" + - t: "⠆" + else: [x: "*[4]"] + +- + name: default + tag: mmultiscripts + match: "." + variables: + # computing the number of postscripts is messy because of being optionally present -- we use "mod" to get the count right + - Prescripts: "m:mprescripts/following-sibling::*" + - NumChildren: "count(*)" # need to stash this since the count is wrong inside '*[...]' below + - Postscripts: "*[position()>1 and position() < (last() + ($NumChildren mod 2) -count($Prescripts))]" + replace: + - test: + if: "$Prescripts" + then: + - test: + if: "not($Prescripts[1][self::m:none])" + then: + - with: + variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string + replace: + - t: "⠢" + - test: + if: "NeedsToBeGrouped($Prescripts[1], 'French', true())" + then: + - t: "⠰" + - x: "$Prescripts[1]" + - t: "⠆" + else: [x: "$Prescripts[1]"] + - test: + if: "not($Prescripts[2][self::m:none])" + then: + - with: + variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string + replace: + - t: "⠈" + - test: + if: "NeedsToBeGrouped($Prescripts[2], 'French', false())" + then: + - t: "⠰" + - x: "$Prescripts[2]" + - t: "⠆" + else: [x: "$Prescripts[2]"] + - test: + if: "count($Prescripts)>2" + then: + - test: + if: "not($Prescripts[3][self::m:none])" + then: + - with: + variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string + replace: + - t: "⠢" + - test: + if: "NeedsToBeGrouped($Prescripts[3], 'French', false())" + then: + - t: "⠰" + - x: "$Prescripts[3]" + - t: "⠆" + else: [x: "$Prescripts[3]"] + - test: + if: "not($Prescripts[4][self::m:none])" + then: + - with: + variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string + replace: + - t: "⠈" + - test: + if: "NeedsToBeGrouped($Prescripts[4], 'French', false())" + then: + - t: "⠰" + - x: "$Prescripts[4]" + - t: "⠆" + else: [x: "$Prescripts[4]"] + - test: + if: "count($Prescripts) > 4" # give up and just dump them out so at least the content is there + then: [x: "$Prescripts[position() > 4]"] + + - x: "*[1]" + - test: + if: "$Postscripts" + then: + - test: + if: "not($Postscripts[1][self::m:none])" + then: + - with: + variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string + replace: + - t: "⠢" + - test: + if: "NeedsToBeGrouped($Postscripts[1], 'French', false())" + then: + - t: "⠰" + - x: "$Postscripts[1]" + - t: "⠆" + else: [x: "$Postscripts[1]"] + - test: + if: "not($Postscripts[2][self::m:none])" + then: + - with: + variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string + replace: + - t: "⠈" + - test: + if: "NeedsToBeGrouped($Postscripts[2], 'French', false())" + then: + - t: "⠰" + - x: "$Postscripts[2]" + - t: "⠆" + else: [x: "$Postscripts[2]"] + - test: + if: "count($Postscripts)>2" + then: + - test: + if: "not($Postscripts[3][self::m:none])" + then: + - with: + variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string + replace: + - t: "⠢" + - test: + if: "NeedsToBeGrouped($Postscripts[3], 'French', false())" + then: + - t: "⠰" + - x: "$Postscripts[3]" + - t: "⠆" + else: [x: "$Postscripts[3]"] + - test: + if: "not($Postscripts[4][self::m:none])" + then: + - with: + variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string + replace: + - t: "⠈" + - test: + if: "NeedsToBeGrouped($Postscripts[4], 'French', false())" + then: + - t: "⠰" + - x: "$Postscripts[4]" + - t: "⠆" + else: [x: "$Postscripts[4]"] + - test: + if: "count($Postscripts)>4" + then: + - test: + if: "not($Postscripts[5][self::m:none])" + then: + - with: + variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string + replace: + - t: "⠢" + - test: + if: "NeedsToBeGrouped($Postscripts[5], 'French', false())" + then: + - t: "⠰" + - x: "$Postscripts[5]" + - t: "⠆" + else: [x: "$Postscripts[5]"] + - test: + if: "not($Postscripts[6][self::m:none])" + then: + - with: + variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string + replace: + - t: "⠈" + - test: + if: "NeedsToBeGrouped($Postscripts[6], 'French', false())" + then: + - t: "⠰" + - x: "$Postscripts[6]" + - t: "⠆" + else: [x: "$Postscripts[6]"] + - test: + if: "count($Postscripts)>6" + then: + - test: + if: "not($Postscripts[7][self::m:none])" + then: + - with: + variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string + replace: + - t: "⠢" + - test: + if: "NeedsToBeGrouped($Postscripts[7], 'French', false())" + then: + - t: "⠰" + - x: "$Postscripts[7]" + - t: "⠆" + else: [x: "$Postscripts[7]"] + - test: + if: "not($Postscripts[8][self::m:none])" + then: + - with: + variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string + replace: + - t: "⠈" + - test: + if: "NeedsToBeGrouped($Postscripts[8], 'French', false())" + then: + - t: "⠰" + - x: "$Postscripts[8]" + - t: "⠆" + else: [x: "$Postscripts[8]"] + - test: + if: "count($Postscripts) > 8" # give up and just dump them out so at least the content is there + then: + - x: "$Postscripts[position() > 8]" + - t: "#" # signal end script/numeric mode + + +- + # Note: @notation can contain more than one value + # I don't think UEB has a good way to represent all notations, especially when in combination + # Note: + # Shape indicator: ⠫ + # Physical enclosure: ⠪ (think plus inside of a circle) + # Superposition indicator: ⠯ (think contour integral) + # Cancellation: ⠈⠱ (line through previous char -- will use for horizontal, vertical, diagonal lines) + # Line over/under: use GTM 12 bar rule (over ⠱, under ⠠⠱) + # Horizontal juxtaposition indicator: ⠿ + # Vertical juxtaposition indicator: ⠻ (think ≗) + # Termination indicator: ⠱ + # + # We place left and right outside of other notations + # Boxes and circle are does as physical enclosure (shape before base) + # Arrows are done as superposition (after base) + # top and bottom are done as "bars" (GTM 12) (after base) + + name: default + tag: menclose + match: "." + # FIX: can't find a rule that says anything about comparison operator spacing and enclosure + variables: [AddSpaces: "parent::*[self::m:mrow] and *[1][ self::m:mo and IsInDefinition(., 'Braille', 'NemethComparisonOperators')]"] + replace: + - test: + if: "contains(concat(' ', normalize-space(@notation), ' '), ' left ')" #avoid 'leftarrow' + then: [t: "⠸"] + - test: + if: "contains(@notation,'box')" # box and roundedbox + then: + # - test: + # if: "$AddSpaces" + # then: [t: " "] + - t: "1⠫⠼⠙" # square (no rectangle in UEB) + - test: + if: "contains(@notation,'circle')" + then: + # - test: + # if: "$AddSpaces" + # then: [t: " "] + - t: "1⠫⠿" # circle (no oval in UEB) +# ??? What should happen with arrow? +# If there is a box/circle with arrows only and an empty child, +# then it acts like the arrow is the child +# If there are only arrows for 'notation', then maybe rule 112 applies (superposition), +# but the examples aren't similar. In that case, the arrow acts like 'box' and the child is the content... maybe +# +# - test: +# if: "contains(@notation,'leftarrow')" +# then: [t: left arrow, pause: short] +# - test: +# if: "contains(concat(' ', normalize-space(@notation), ' '), ' rightarrow ')" +# then: [t: right arrow, pause: short] +# - test: +# if: "contains(@notation,'northeastarrow')" +# then: [t: northeast arrow, pause: short] +# - test: +# if: "contains(concat(' ', normalize-space(@notation), ' '), ' southeastarrow ')" +# then: [t: southeast arrow, pause: short] +# - test: +# if: "contains(concat(' ', normalize-space(@notation), ' '), ' southwestarrow ')" +# then: [t: southwest arrow, pause: short] +# - test: +# if: "contains(@notation,'northwestarrow')" +# then: [t: northwest arrow, pause: short] +# - test: +# if: "contains(@notation,'updownarrow')" +# then: [t: double ended vertical arrow, pause: short] +# - test: +# if: "contains(@notation,'leftrightarrow')" +# then: [t: double ended horizontal arrow, pause: short] +# - test: +# if: "contains(@notation,'northeastsouthwestarrow')" +# then: [t: double ended up diagonal arrow, pause: short] +# - test: +# if: "contains(@notation,'northwestsoutheastarrow')" +# then: [t: double ended down diagonal arrow, pause: short] +# - test: +# if: ".[contains(@notation,'actuarial')]" +# then: [t: actuarial symbol, pause: short] +# - test: +# if: ".[contains(@notation,'madrub')]" +# then: [t: arabic factorial symbol, pause: short] +# - test: +# if: ".[contains(@notation,'longdiv') or not(@notation) or normalize-space(@notation) ='']" # default +# then: [t: long division symbol, pause: short] +# - test: +# if: ".[contains(@notation,'radical')]" +# then: [t: square root, pause: short] + + - test: + if: "NeedsToBeGrouped(*[1], 'French', false())" + then: + - t: "⠰" + - x: "*[1]" + - t: "⠆" + else: [x: "*[1]"] + + # - test: + # if: "contains(@notation,'phasorangle')" #FIX: what should this be??? + # then: [t: "⠫⠪⠸⠫"] + - test: + if: "contains(@notation,'arrow')" # all the arrows + then: + - test: + - if: "contains(@notation,'rightarrow')" + then: [t: "1⠳⠕"] + - else_if: "contains(@notation,'leftarrow')" + then: [t: "1⠳⠪"] + - else_if: "contains(@notation,'uparrow')" + then: [t: "1⠳⠬ "] + - else_if: "contains(@notation,'downarrow')" + then: [t: "1⠳⠩"] + - else_if: "contains(@notation,'northeastarrow')" + then: [t: "1⠳⠎"] + - else_if: "contains(@notation,'southeastarrow')" + then: [t: "1⠳⠣"] + - else_if: "contains(@notation,'northwestarrow')" + then: [t: "1⠳⠱"] + - else_if: "contains(@notation,'southwestarrow')" + then: [t: "1⠳⠜"] + - else_if: "contains(@notation,'leftrightarrow')" + then: [t: "1⠳⠺⠗⠕"] + - else_if: "contains(@notation,'updownarrow')" + then: [t: "1⠳⠺⠗⠬"] + - else_if: "contains(@notation,'northeastsouthwestarrow')" + then: [t: "1⠳⠺⠗⠎"] + - else_if: "contains(@notation,'northwestsoutheastarrow')" + then: [t: "1⠳⠺⠗⠣"] + - test: + if: "contains(@notation,'top')" + then: [t: "⠱"] + - test: + if: "contains(@notation,'bottom')" + then: [t: "⠠⠱"] + - test: + if: "contains(@notation,'updiagonalstrike') or contains(@notation,'downdiagonalstrike') or + contains(@notation,'verticalstrike') or contains(@notation,'horizontalstrike')" + then: + - t: "1⠈⠱" # cancellation + - test: + if: + - "not($AddSpaces) and contains(@notation,'box') or contains(@notation,'circle') or" + - "contains(@notation,'arrow') or contains(@notation,'phasorangle')" + then: + - t: "⠻" # terminate shape + # - test: + # if: "$AddSpaces" + # then: [t: " "] + - test: + if: "contains(concat(' ', normalize-space(@notation), ' '), ' right ')" #avoid 'rightarrow' + then: [t: "⠸"] + + + +- + name: default + tag: ms + match: "." + replace: + - test: + if: "string(@lquote)!=''" + then: [x: "@lquote"] + else: [t: "⠄⠄"] + - x: "BrailleChars(., 'French')" + - test: + if: "string(@rquote)!=''" + then: [x: "@rquote"] + else: [t: "⠄⠄"] + +- + name: default + tag: semantics + match: "." + replace: + - x: "*[1]" #/ FIX: should prioritize @encoding="MathML-Presentation" and @encoding="application/mathml-presentation+xml" + +- + name: default-children + tag: "*" + match: "*" # make sure there are children + replace: + - t: "unknown math m l element" + - x: "name(.)" + - x: "*" + +- + # at this point, we know there are no children -- might be no text + name: default-no-children + tag: "*" + match: "text()" + replace: + - t: unknown math m l element + - x: "name(.)" + - x: "text()" + +- + name: default-no-text + tag: "*" + match: "." + replace: + - t: "empty unknown math m l element" + - x: "name(.)" diff --git a/Rules/Braille/French/definitions.yaml b/Rules/Braille/French/definitions.yaml new file mode 100644 index 000000000..4d0c77efb --- /dev/null +++ b/Rules/Braille/French/definitions.yaml @@ -0,0 +1,2 @@ +--- +- include: "../definitions.yaml" diff --git a/Rules/Braille/French/unicode-full.yaml b/Rules/Braille/French/unicode-full.yaml new file mode 100644 index 000000000..91054d0cb --- /dev/null +++ b/Rules/Braille/French/unicode-full.yaml @@ -0,0 +1,1027 @@ +--- + + - "⇌": [t: "⠸⠻"] # 0x21CC (Rightwards harpoon over leftwards harpoon (equilibrium)) +# - "⥂": [t: ""] # 0x2942 (Rightwards arrow above short leftwards arrow (equilibrium, trend to the right)) +# - "⥄": [t: ""] # 0x2944 (Short rightwards arrow above leftwards arrow (equilibrium, trend to the left)) + +# Mappings for some new Unicode chemistry arrows/symbols +# These repeat the short arrow version because that is what is in the spec (GTM 16), but the spec should really use the long version + - "🣑": [t: "⠸⠻"] # 0x1F8D1 LONG RIGHTWARDS HARPOON OVER LONG LEFTWARDS HARPOON (equilibrium) +# - "🣒": [t: ""] # 0x1f8d2 LONG RIGHTWARDS HARPOON ABOVE SHORT LEFTWARDS HARPOON(equilibrium, trend to the right) +# - "🣓": [t: ""] # 0x1f8d3 SHORT RIGHTWARDS HARPOON ABOVE LONG LEFTWARDS HARPOON (equilibrium, trend to the left)) + +# - "🣐": [t: ""] # 0x1F8D0 LONG RIGHTWARDS ARROW OVER LONG LEFTWARDS ARROW +# - "🣕": [t: ""] # 0x1F8D5 SHORT LEFTWARDS HARPOON ABOVELONG RIGHTWARDS HARPOON +# - "🣖": [t: ""] # 0x1F8D6 LONG RIGHTWARDS ARROW WITH THROUGH X +# - "🣗": [t: ""] # 0x1F8D7 LONG RIGHTWARDS ARROW WITH DOUBLE SLASH +# - "": [t: ""] # 0x1F8D8 LONG LEFT RIGHT ARROW WITH DEPENDENT LOBE (no clue what to do) + + - "⅐": [t: "⠡⠌⠻"] # 0x2150 (vulgar fraction one seventh) + - "⅑": [t: "⠡⠌⠪"] # 0x2151 (vulgar fraction one ninth) + - "⅓": [t: "⠡⠌⠩"] # 0x2153 (vulgar fraction one third) + - "⅔": [t: "⠣⠌⠩"] # 0x2154 (vulgar fraction two thirds) + - "⅕": [t: "⠡⠌⠱"] # 0x2155 (vulgar fraction one fifth) + - "⅖": [t: "⠣⠌⠱"] # 0x2156 (vulgar fraction two fifths) + - "⅗": [t: "⠩⠌⠱"] # 0x2157 (vulgar fraction three fifths) + - "⅘": [t: "⠹⠌⠱"] # 0x2158 (vulgar fraction four fifths) + - "⅙": [t: "⠡⠌⠫"] # 0x2159 (vulgar fraction one sixth) + - "⅚": [t: "⠱⠌⠫"] # 0x215A (vulgar fraction five sixths) + - "⅛": [t: "⠡⠌⠳"] # 0x215B (vulgar fraction one eighth) + - "⅜": [t: "⠩⠌⠳"] # 0x215C (vulgar fraction three eighths) + - "⅝": [t: "⠱⠌⠳"] # 0x215D (vulgar fraction five eighths) + - "⅞": [t: "⠻⠌⠳"] # 0x215E (vulgar fraction seven eighths) + - "↉": [t: "⠼⠌⠩"] # 0x2189 (vulgar fraction zero thirds) + + + + - "𝐚": [t: "BL⠁"] # 0x1d41a + - "𝐛": [t: "BL⠃"] # 0x1d41b + - "𝐜": [t: "BL⠉"] # 0x1d41c + - "𝐝": [t: "BL⠙"] # 0x1d41d + - "𝐞": [t: "BL⠑"] # 0x1d41e + - "𝐟": [t: "BL⠋"] # 0x1d41f + - "𝐠": [t: "BL⠛"] # 0x1d420 + - "𝐡": [t: "BL⠓"] # 0x1d421 + - "𝐢": [t: "BL⠊"] # 0x1d422 + - "𝐣": [t: "BL⠚"] # 0x1d423 + - "𝐤": [t: "BL⠅"] # 0x1d424 + - "𝐥": [t: "BL⠇"] # 0x1d425 + - "𝐦": [t: "BL⠍"] # 0x1d426 + - "𝐧": [t: "BL⠝"] # 0x1d427 + - "𝐨": [t: "BL⠕"] # 0x1d428 + - "𝐩": [t: "BL⠏"] # 0x1d429 + - "𝐪": [t: "BL⠟"] # 0x1d42a + - "𝐫": [t: "BL⠗"] # 0x1d42b + - "𝐬": [t: "BL⠎"] # 0x1d42c + - "𝐭": [t: "BL⠞"] # 0x1d42d + - "𝐮": [t: "BL⠥"] # 0x1d42e + - "𝐯": [t: "BL⠧"] # 0x1d42f + - "𝐰": [t: "BL⠺"] # 0x1d430 + - "𝐱": [t: "BL⠭"] # 0x1d431 + - "𝐲": [t: "BL⠽"] # 0x1d432 + - "𝐳": [t: "BL⠵"] # 0x1d433 + + - "𝐀": [t: "BCL⠁"] # 0x1d400 + - "𝐁": [t: "BCL⠃"] # 0x1d401 + - "𝐂": [t: "BCL⠉"] # 0x1d402 + - "𝐃": [t: "BCL⠙"] # 0x1d403 + - "𝐄": [t: "BCL⠑"] # 0x1d404 + - "𝐅": [t: "BCL⠋"] # 0x1d405 + - "𝐆": [t: "BCL⠛"] # 0x1d406 + - "𝐇": [t: "BCL⠓"] # 0x1d407 + - "𝐈": [t: "BCL⠊"] # 0x1d408 + - "𝐉": [t: "BCL⠚"] # 0x1d409 + - "𝐊": [t: "BCL⠅"] # 0x1d40a + - "𝐋": [t: "BCL⠇"] # 0x1d40b + - "𝐌": [t: "BCL⠍"] # 0x1d40c + - "𝐍": [t: "BCL⠝"] # 0x1d40d + - "𝐎": [t: "BCL⠕"] # 0x1d40e + - "𝐏": [t: "BCL⠏"] # 0x1d40f + - "𝐐": [t: "BCL⠟"] # 0x1d410 + - "𝐑": [t: "BCL⠗"] # 0x1d411 + - "𝐒": [t: "BCL⠎"] # 0x1d412 + - "𝐓": [t: "BCL⠞"] # 0x1d413 + - "𝐔": [t: "BCL⠥"] # 0x1d414 + - "𝐕": [t: "BCL⠧"] # 0x1d415 + - "𝐖": [t: "BCL⠺"] # 0x1d416 + - "𝐗": [t: "BCL⠭"] # 0x1d417 + - "𝐘": [t: "BCL⠽"] # 0x1d418 + - "𝐙": [t: "BCL⠵"] # 0x1d419 + +# don't mark these as italic + - "𝑎": [t: "L⠁"] # 0x1d44e + - "𝑏": [t: "L⠃"] # 0x1d44f + - "𝑐": [t: "L⠉"] # 0x1d450 + - "𝑑": [t: "L⠙"] # 0x1d451 + - "𝑒": [t: "L⠑"] # 0x1d452 + - "𝑓": [t: "L⠋"] # 0x1d453 + - "𝑔": [t: "L⠛"] # 0x1d454 + - "𝑕": [t: "L⠓"] # 0x1d455 + - "𝑖": [t: "L⠊"] # 0x1d456 + - "𝑗": [t: "L⠚"] # 0x1d457 + - "𝑘": [t: "L⠅"] # 0x1d458 + - "𝑙": [t: "L⠇"] # 0x1d459 + - "𝑚": [t: "L⠍"] # 0x1d45a + - "𝑛": [t: "L⠝"] # 0x1d45b + - "𝑜": [t: "L⠕"] # 0x1d45c + - "𝑝": [t: "L⠏"] # 0x1d45d + - "𝑞": [t: "L⠟"] # 0x1d45e + - "𝑟": [t: "L⠗"] # 0x1d45f + - "𝑠": [t: "L⠎"] # 0x1d460 + - "𝑡": [t: "L⠞"] # 0x1d461 + - "𝑢": [t: "L⠥"] # 0x1d462 + - "𝑣": [t: "L⠧"] # 0x1d463 + - "𝑤": [t: "L⠺"] # 0x1d464 + - "𝑥": [t: "L⠭"] # 0x1d465 + - "𝑦": [t: "L⠽"] # 0x1d466 + - "𝑧": [t: "L⠵"] # 0x1d467 + + - "𝐴": [t: "CL⠁"] # 0x1d434 + - "𝐵": [t: "CL⠃"] # 0x1d435 + - "𝐶": [t: "CL⠉"] # 0x1d436 + - "𝐷": [t: "CL⠙"] # 0x1d437 + - "𝐸": [t: "CL⠑"] # 0x1d438 + - "𝐹": [t: "CL⠋"] # 0x1d439 + - "𝐺": [t: "CL⠛"] # 0x1d43a + - "𝐻": [t: "CL⠓"] # 0x1d43b + - "𝐼": [t: "CL⠊"] # 0x1d43c + - "𝐽": [t: "CL⠚"] # 0x1d43d + - "𝐾": [t: "CL⠅"] # 0x1d43e + - "𝐿": [t: "CL⠇"] # 0x1d43f + - "𝑀": [t: "CL⠍"] # 0x1d440 + - "𝑁": [t: "CL⠝"] # 0x1d441 + - "𝑂": [t: "CL⠕"] # 0x1d442 + - "𝑃": [t: "CL⠏"] # 0x1d443 + - "𝑄": [t: "CL⠟"] # 0x1d444 + - "𝑅": [t: "CL⠗"] # 0x1d445 + - "𝑆": [t: "CL⠎"] # 0x1d446 + - "𝑇": [t: "CL⠞"] # 0x1d447 + - "𝑈": [t: "CL⠥"] # 0x1d448 + - "𝑉": [t: "CL⠧"] # 0x1d449 + - "𝑊": [t: "CL⠺"] # 0x1d44a + - "𝑋": [t: "CL⠭"] # 0x1d44b + - "𝑌": [t: "CL⠽"] # 0x1d44c + - "𝑍": [t: "CL⠵"] # 0x1d44d + + - "𝒂": [t: "BIL⠁"] # 0x1d482 + - "𝒃": [t: "BIL⠃"] # 0x1d483 + - "𝒄": [t: "BIL⠉"] # 0x1d484 + - "𝒅": [t: "BIL⠙"] # 0x1d485 + - "𝒆": [t: "BIL⠑"] # 0x1d486 + - "𝒇": [t: "BIL⠋"] # 0x1d487 + - "𝒈": [t: "BIL⠛"] # 0x1d488 + - "𝒉": [t: "BIL⠓"] # 0x1d489 + - "𝒊": [t: "BIL⠊"] # 0x1d48a + - "𝒋": [t: "BIL⠚"] # 0x1d48b + - "𝒌": [t: "BIL⠅"] # 0x1d48c + - "𝒍": [t: "BIL⠇"] # 0x1d48d + - "𝒎": [t: "BIL⠍"] # 0x1d48e + - "𝒏": [t: "BIL⠝"] # 0x1d48f + - "𝒐": [t: "BIL⠕"] # 0x1d490 + - "𝒑": [t: "BIL⠏"] # 0x1d491 + - "𝒒": [t: "BIL⠟"] # 0x1d492 + - "𝒓": [t: "BIL⠗"] # 0x1d493 + - "𝒔": [t: "BIL⠎"] # 0x1d494 + - "𝒕": [t: "BIL⠞"] # 0x1d495 + - "𝒖": [t: "BIL⠥"] # 0x1d496 + - "𝒗": [t: "BIL⠧"] # 0x1d497 + - "𝒘": [t: "BIL⠺"] # 0x1d498 + - "𝒙": [t: "BIL⠭"] # 0x1d499 + - "𝒚": [t: "BIL⠽"] # 0x1d49a + - "𝒛": [t: "BIL⠵"] # 0x1d49b + + - "𝑨": [t: "BICL⠁"] # 0x1d468 + - "𝑩": [t: "BICL⠃"] # 0x1d469 + - "𝑪": [t: "BICL⠉"] # 0x1d46a + - "𝑫": [t: "BICL⠙"] # 0x1d46b + - "𝑬": [t: "BICL⠑"] # 0x1d46c + - "𝑭": [t: "BICL⠋"] # 0x1d46d + - "𝑮": [t: "BICL⠛"] # 0x1d46e + - "𝑯": [t: "BICL⠓"] # 0x1d46f + - "𝑰": [t: "BICL⠊"] # 0x1d470 + - "𝑱": [t: "BICL⠚"] # 0x1d471 + - "𝑲": [t: "BICL⠅"] # 0x1d472 + - "𝑳": [t: "BICL⠇"] # 0x1d473 + - "𝑴": [t: "BICL⠍"] # 0x1d474 + - "𝑵": [t: "BICL⠝"] # 0x1d475 + - "𝑶": [t: "BICL⠕"] # 0x1d476 + - "𝑷": [t: "BICL⠏"] # 0x1d477 + - "𝑸": [t: "BICL⠟"] # 0x1d478 + - "𝑹": [t: "BICL⠗"] # 0x1d479 + - "𝑺": [t: "BICL⠎"] # 0x1d47a + - "𝑻": [t: "BICL⠞"] # 0x1d47b + - "𝑼": [t: "BICL⠥"] # 0x1d47c + - "𝑽": [t: "BICL⠧"] # 0x1d47d + - "𝑾": [t: "BICL⠺"] # 0x1d47e + - "𝑿": [t: "BICL⠭"] # 0x1d47f + - "𝒀": [t: "BICL⠽"] # 0x1d480 + - "𝒁": [t: "BICL⠵"] # 0x1d481 + + - "𝒶": [t: "TsL⠁"] # 0x1d4b6 + - "𝒷": [t: "TsL⠃"] # 0x1d4b7 + - "𝒸": [t: "TsL⠉"] # 0x1d4b8 + - "𝒹": [t: "TsL⠙"] # 0x1d4b9 + - "𝒺": [t: "TsL⠑"] # 0x1d4ba + - "𝒻": [t: "TsL⠋"] # 0x1d4bb + - "𝒼": [t: "TsL⠛"] # 0x1d4bc + - "𝒽": [t: "TsL⠓"] # 0x1d4bd + - "𝒾": [t: "TsL⠊"] # 0x1d4be + - "𝒿": [t: "TsL⠚"] # 0x1d4bf + - "𝓀": [t: "TsL⠅"] # 0x1d4c0 + - "𝓁": [t: "TsL⠇"] # 0x1d4c1 + - "𝓂": [t: "TsL⠍"] # 0x1d4c2 + - "𝓃": [t: "TsL⠝"] # 0x1d4c3 + - "𝓄": [t: "TsL⠕"] # 0x1d4c4 + - "𝓅": [t: "TsL⠏"] # 0x1d4c5 + - "𝓆": [t: "TsL⠟"] # 0x1d4c6 + - "𝓇": [t: "TsL⠗"] # 0x1d4c7 + - "𝓈": [t: "TsL⠎"] # 0x1d4c8 + - "𝓉": [t: "TsL⠞"] # 0x1d4c9 + - "𝓊": [t: "TsL⠥"] # 0x1d4ca + - "𝓋": [t: "TsL⠧"] # 0x1d4cb + - "𝓌": [t: "TsL⠺"] # 0x1d4cc + - "𝓍": [t: "TsL⠭"] # 0x1d4cd + - "𝓎": [t: "TsL⠽"] # 0x1d4ce + - "𝓏": [t: "TsL⠵"] # 0x1d4cf + + - "𝒜": [t: "TsCL⠁"] # 0x1d49c + - "𝒝": [t: "TsCL⠃"] # 0x1d49d + - "𝒞": [t: "TsCL⠉"] # 0x1d49e + - "𝒟": [t: "TsCL⠙"] # 0x1d49f + - "𝒠": [t: "TsCL⠑"] # 0x1d4a0 + - "𝒡": [t: "TsCL⠋"] # 0x1d4a1 + - "𝒢": [t: "TsCL⠛"] # 0x1d4a2 + - "𝒣": [t: "TsCL⠓"] # 0x1d4a3 + - "𝒤": [t: "TsCL⠊"] # 0x1d4a4 + - "𝒥": [t: "TsCL⠚"] # 0x1d4a5 + - "𝒦": [t: "TsCL⠅"] # 0x1d4a6 + - "𝒧": [t: "TsCL⠇"] # 0x1d4a7 + - "𝒨": [t: "TsCL⠍"] # 0x1d4a8 + - "𝒩": [t: "TsCL⠝"] # 0x1d4a9 + - "𝒪": [t: "TsCL⠕"] # 0x1d4aa + - "𝒫": [t: "TsCL⠏"] # 0x1d4ab + - "𝒬": [t: "TsCL⠟"] # 0x1d4ac + - "𝒭": [t: "TsCL⠗"] # 0x1d4ad + - "𝒮": [t: "TsCL⠎"] # 0x1d4ae + - "𝒯": [t: "TsCL⠞"] # 0x1d4af + - "𝒰": [t: "TsCL⠥"] # 0x1d4b0 + - "𝒱": [t: "TsCL⠧"] # 0x1d4b1 + - "𝒲": [t: "TsCL⠺"] # 0x1d4b2 + - "𝒳": [t: "TsCL⠭"] # 0x1d4b3 + - "𝒴": [t: "TsCL⠽"] # 0x1d4b4 + - "𝒵": [t: "TsCL⠵"] # 0x1d4b5 + + - "ℊ": [t: "TL⠛⠁"] # 0x210a (Script Small G) + - "ℋ": [t: "TCL⠓⠁"] # 0x210b (Script Capital H) + - "ℒ": [t: "TCL⠇"] # 0x2113 (Script Capital L) + - "ℓ": [t: "TL⠇"] # 0x2113 (Script Small L) + - "℘": [t: "TCL⠏"] # 0x2118 (Script Capital P) + - "ℛ": [t: "TCL⠗"] # 0x211B (Script Capital R) + - "ℯ": [t: "TL⠑"] # 0x212F (Script Small E) + - "ℰ": [t: "TCL⠑"] # 0x2130 (Script Capital E) + - "ℱ": [t: "TCL⠋"] # 0x2131 (Script Capital F) + - "ℳ": [t: "TCL⠍"] # 0x2133 (Script Capital M) + - "ℴ": [t: "TL⠕"] # 0x21334 (Script Small O) + - "𝓪": [t: "BTsL⠁"] # 0x1d4ea + - "𝓫": [t: "BTsL⠃"] # 0x1d4eb + - "𝓬": [t: "BTsL⠉"] # 0x1d4ec + - "𝓭": [t: "BTsL⠙"] # 0x1d4ed + - "𝓮": [t: "BTsL⠑"] # 0x1d4ee + - "𝓯": [t: "BTsL⠋"] # 0x1d4ef + - "𝓰": [t: "BTsL⠛"] # 0x1d4f0 + - "𝓱": [t: "BTsL⠓"] # 0x1d4f1 + - "𝓲": [t: "BTsL⠊"] # 0x1d4f2 + - "𝓳": [t: "BTsL⠚"] # 0x1d4f3 + - "𝓴": [t: "BTsL⠅"] # 0x1d4f4 + - "𝓵": [t: "BTsL⠇"] # 0x1d4f5 + - "𝓶": [t: "BTsL⠍"] # 0x1d4f6 + - "𝓷": [t: "BTsL⠝"] # 0x1d4f7 + - "𝓸": [t: "BTsL⠕"] # 0x1d4f8 + - "𝓹": [t: "BTsL⠏"] # 0x1d4f9 + - "𝓺": [t: "BTsL⠟"] # 0x1d4fa + - "𝓻": [t: "BTsL⠗"] # 0x1d4fb + - "𝓼": [t: "BTsL⠎"] # 0x1d4fc + - "𝓽": [t: "BTsL⠞"] # 0x1d4fd + - "𝓾": [t: "BTsL⠥"] # 0x1d4fe + - "𝓿": [t: "BTsL⠧"] # 0x1d4ff + - "𝔀": [t: "BTsL⠺"] # 0x1d500 + - "𝔁": [t: "BTsL⠭"] # 0x1d501 + - "𝔂": [t: "BTsL⠽"] # 0x1d502 + - "𝔃": [t: "BTsL⠵"] # 0x1d503 + + - "𝓐": [t: "BTsCL⠁"] # 0x1d4d0 + - "𝓑": [t: "BTsCL⠃"] # 0x1d4d1 + - "𝓒": [t: "BTsCL⠉"] # 0x1d4d2 + - "𝓓": [t: "BTsCL⠙"] # 0x1d4d3 + - "𝓔": [t: "BTsCL⠑"] # 0x1d4d4 + - "𝓕": [t: "BTsCL⠋"] # 0x1d4d5 + - "𝓖": [t: "BTsCL⠛"] # 0x1d4d6 + - "𝓗": [t: "BTsCL⠓"] # 0x1d4d7 + - "𝓘": [t: "BTsCL⠊"] # 0x1d4d8 + - "𝓙": [t: "BTsCL⠚"] # 0x1d4d9 + - "𝓚": [t: "BTsCL⠅"] # 0x1d4da + - "𝓛": [t: "BTsCL⠇"] # 0x1d4db + - "𝓜": [t: "BTsCL⠍"] # 0x1d4dc + - "𝓝": [t: "BTsCL⠝"] # 0x1d4dd + - "𝓞": [t: "BTsCL⠕"] # 0x1d4de + - "𝓟": [t: "BTsCL⠏"] # 0x1d4df + - "𝓠": [t: "BTsCL⠟"] # 0x1d4e0 + - "𝓡": [t: "BTsCL⠗"] # 0x1d4e1 + - "𝓢": [t: "BTsCL⠎"] # 0x1d4e2 + - "𝓣": [t: "BTsCL⠞"] # 0x1d4e3 + - "𝓤": [t: "BTsCL⠥"] # 0x1d4e4 + - "𝓥": [t: "BTsCL⠧"] # 0x1d4e5 + - "𝓦": [t: "BTsCL⠺"] # 0x1d4e6 + - "𝓧": [t: "BTsCL⠭"] # 0x1d4e7 + - "𝓨": [t: "BTsCL⠽"] # 0x1d4e8 + - "𝓩": [t: "BTsCL⠵"] # 0x1d4e9 + + - "𝔞": [t: "DL⠁"] # 0x1d51e + - "𝔟": [t: "DL⠃"] # 0x1d51f + - "𝔠": [t: "DL⠉"] # 0x1d520 + - "𝔡": [t: "DL⠙"] # 0x1d521 + - "𝔢": [t: "DL⠑"] # 0x1d522 + - "𝔣": [t: "DL⠋"] # 0x1d523 + - "𝔤": [t: "DL⠛"] # 0x1d524 + - "𝔥": [t: "DL⠓"] # 0x1d525 + - "𝔦": [t: "DL⠊"] # 0x1d526 + - "𝔧": [t: "DL⠚"] # 0x1d527 + - "𝔨": [t: "DL⠅"] # 0x1d528 + - "𝔩": [t: "DL⠇"] # 0x1d529 + - "𝔪": [t: "DL⠍"] # 0x1d52a + - "𝔫": [t: "DL⠝"] # 0x1d52b + - "𝔬": [t: "DL⠕"] # 0x1d52c + - "𝔭": [t: "DL⠏"] # 0x1d52d + - "𝔮": [t: "DL⠟"] # 0x1d52e + - "𝔯": [t: "DL⠗"] # 0x1d52f + - "𝔰": [t: "DL⠎"] # 0x1d530 + - "𝔱": [t: "DL⠞"] # 0x1d531 + - "𝔲": [t: "DL⠥"] # 0x1d532 + - "𝔳": [t: "DL⠧"] # 0x1d533 + - "𝔴": [t: "DL⠺"] # 0x1d534 + - "𝔵": [t: "DL⠭"] # 0x1d535 + - "𝔶": [t: "DL⠽"] # 0x1d536 + - "𝔷": [t: "DL⠵"] # 0x1d537 + + - "𝔄": [t: "DCL⠁"] # 0x1d504 + - "𝔅": [t: "DCL⠃"] # 0x1d505 + - "𝔆": [t: "DCL⠉"] # 0x1d506 + - "𝔇": [t: "DCL⠙"] # 0x1d507 + - "𝔈": [t: "DCL⠑"] # 0x1d508 + - "𝔉": [t: "DCL⠋"] # 0x1d509 + - "𝔊": [t: "DCL⠛"] # 0x1d50a + - "𝔋": [t: "DCL⠓"] # 0x1d50b + - "𝔌": [t: "DCL⠊"] # 0x1d50c + - "𝔍": [t: "DCL⠚"] # 0x1d50d + - "𝔎": [t: "DCL⠅"] # 0x1d50e + - "𝔏": [t: "DCL⠇"] # 0x1d50f + - "𝔐": [t: "DCL⠍"] # 0x1d510 + - "𝔑": [t: "DCL⠝"] # 0x1d511 + - "𝔒": [t: "DCL⠕"] # 0x1d512 + - "𝔓": [t: "DCL⠏"] # 0x1d513 + - "𝔔": [t: "DCL⠟"] # 0x1d514 + - "𝔕": [t: "DCL⠗"] # 0x1d515 + - "𝔖": [t: "DCL⠎"] # 0x1d516 + - "𝔗": [t: "DCL⠞"] # 0x1d517 + - "𝔘": [t: "DCL⠥"] # 0x1d518 + - "𝔙": [t: "DCL⠧"] # 0x1d519 + - "𝔚": [t: "DCL⠺"] # 0x1d51a + - "𝔛": [t: "DCL⠭"] # 0x1d51b + - "𝔜": [t: "DCL⠽"] # 0x1d51c + - "𝔝": [t: "DCL⠵"] # 0x1d51d + + - "ℌ": [t: "DCL⠓"] # 0x210C (Fraktur Capital H) + - "ℑ": [t: "DCL⠊"] # 0x2111 (Fraktur Capital I) + - "ℜ": [t: "DCL⠗"] # 0x211C (Fraktur Capital R) + - "ℨ": [t: "DCL⠵"] # 0x2128 (Fraktur Capital Z) + - "ℭ": [t: "DCL⠉"] # 0x22DC (Fraktur Capital C) + - "𝕒": [t: "𝔹L⠁"] # 0x1d552 + - "𝕓": [t: "𝔹L⠃"] # 0x1d553 + - "𝕔": [t: "𝔹L⠉"] # 0x1d554 + - "𝕕": [t: "𝔹L⠙"] # 0x1d555 + - "𝕖": [t: "𝔹L⠑"] # 0x1d556 + - "𝕗": [t: "𝔹L⠋"] # 0x1d557 + - "𝕘": [t: "𝔹L⠛"] # 0x1d558 + - "𝕙": [t: "𝔹L⠓"] # 0x1d559 + - "𝕚": [t: "𝔹L⠊"] # 0x1d55a + - "𝕛": [t: "𝔹L⠚"] # 0x1d55b + - "𝕜": [t: "𝔹L⠅"] # 0x1d55c + - "𝕝": [t: "𝔹L⠇"] # 0x1d55d + - "𝕞": [t: "𝔹L⠍"] # 0x1d55e + - "𝕟": [t: "𝔹L⠝"] # 0x1d55f + - "𝕠": [t: "𝔹L⠕"] # 0x1d560 + - "𝕡": [t: "𝔹L⠏"] # 0x1d561 + - "𝕢": [t: "𝔹L⠟"] # 0x1d562 + - "𝕣": [t: "𝔹L⠗"] # 0x1d563 + - "𝕤": [t: "𝔹L⠎"] # 0x1d564 + - "𝕥": [t: "𝔹L⠞"] # 0x1d565 + - "𝕦": [t: "𝔹L⠥"] # 0x1d566 + - "𝕧": [t: "𝔹L⠧"] # 0x1d567 + - "𝕨": [t: "𝔹L⠺"] # 0x1d568 + - "𝕩": [t: "𝔹L⠭"] # 0x1d569 + - "𝕪": [t: "𝔹L⠽"] # 0x1d56a + - "𝕫": [t: "𝔹L⠵"] # 0x1d56b + + - "𝔸": [t: "𝔹CL⠁"] # 0x1d538 + - "𝔹": [t: "𝔹CL⠃"] # 0x1d539 + - "ℂ": [t: "𝔹CL⠉"] # 0x2102 + - "𝔻": [t: "𝔹CL⠙"] # 0x1d53b + - "𝔼": [t: "𝔹CL⠑"] # 0x1d53c + - "𝔽": [t: "𝔹CL⠋"] # 0x1d53d + - "𝔾": [t: "𝔹CL⠛"] # 0x1d53e + - "ℍ": [t: "𝔹CL⠓"] # 0x210d + - "𝕀": [t: "𝔹CL⠊"] # 0x1d540 + - "𝕁": [t: "𝔹CL⠚"] # 0x1d541 + - "𝕂": [t: "𝔹CL⠅"] # 0x1d542 + - "𝕃": [t: "𝔹CL⠇"] # 0x1d543 + - "𝕄": [t: "𝔹CL⠍"] # 0x1d544 + - "ℕ": [t: "𝔹CL⠝"] # 0x2115 + - "𝕆": [t: "𝔹CL⠕"] # 0x1d546 + - "ℙ": [t: "𝔹CL⠏"] # 0x2119 + - "ℚ": [t: "𝔹CL⠟"] # 0x211a + - "ℝ": [t: "𝔹CL⠗"] # 0x211d + - "𝕊": [t: "𝔹CL⠎"] # 0x1d54a + - "𝕋": [t: "𝔹CL⠞"] # 0x1d54b + - "𝕌": [t: "𝔹CL⠥"] # 0x1d54c + - "𝕍": [t: "𝔹CL⠧"] # 0x1d54d + - "𝕎": [t: "𝔹CL⠺"] # 0x1d54e + - "𝕏": [t: "𝔹CL⠭"] # 0x1d54f + - "𝕐": [t: "𝔹CL⠽"] # 0x1d550 + - "ℤ": [t: "𝔹CL⠵"] # 0x2124 + - "𝖆": [t: "BDL⠁"] # 0x1d586 + - "𝖇": [t: "BDL⠃"] # 0x1d587 + - "𝖈": [t: "BDL⠉"] # 0x1d588 + - "𝖉": [t: "BDL⠙"] # 0x1d589 + - "𝖊": [t: "BDL⠑"] # 0x1d58a + - "𝖋": [t: "BDL⠋"] # 0x1d58b + - "𝖌": [t: "BDL⠛"] # 0x1d58c + - "𝖍": [t: "BDL⠓"] # 0x1d58d + - "𝖎": [t: "BDL⠊"] # 0x1d58e + - "𝖏": [t: "BDL⠚"] # 0x1d58f + - "𝖐": [t: "BDL⠅"] # 0x1d590 + - "𝖑": [t: "BDL⠇"] # 0x1d591 + - "𝖒": [t: "BDL⠍"] # 0x1d592 + - "𝖓": [t: "BDL⠝"] # 0x1d593 + - "𝖔": [t: "BDL⠕"] # 0x1d594 + - "𝖕": [t: "BDL⠏"] # 0x1d595 + - "𝖖": [t: "BDL⠟"] # 0x1d596 + - "𝖗": [t: "BDL⠗"] # 0x1d597 + - "𝖘": [t: "BDL⠎"] # 0x1d598 + - "𝖙": [t: "BDL⠞"] # 0x1d599 + - "𝖚": [t: "BDL⠥"] # 0x1d59a + - "𝖛": [t: "BDL⠧"] # 0x1d59b + - "𝖜": [t: "BDL⠺"] # 0x1d59c + - "𝖝": [t: "BDL⠭"] # 0x1d59d + - "𝖞": [t: "BDL⠽"] # 0x1d59e + - "𝖟": [t: "BDL⠵"] # 0x1d59f + + - "𝕬": [t: "BDCL⠁"] # 0x1d56c + - "𝕭": [t: "BDCL⠃"] # 0x1d56d + - "𝕮": [t: "BDCL⠉"] # 0x1d56e + - "𝕯": [t: "BDCL⠙"] # 0x1d56f + - "𝕰": [t: "BDCL⠑"] # 0x1d570 + - "𝕱": [t: "BDCL⠋"] # 0x1d571 + - "𝕲": [t: "BDCL⠛"] # 0x1d572 + - "𝕳": [t: "BDCL⠓"] # 0x1d573 + - "𝕴": [t: "BDCL⠊"] # 0x1d574 + - "𝕵": [t: "BDCL⠚"] # 0x1d575 + - "𝕶": [t: "BDCL⠅"] # 0x1d576 + - "𝕷": [t: "BDCL⠇"] # 0x1d577 + - "𝕸": [t: "BDCL⠍"] # 0x1d578 + - "𝕹": [t: "BDCL⠝"] # 0x1d579 + - "𝕺": [t: "BDCL⠕"] # 0x1d57a + - "𝕻": [t: "BDCL⠏"] # 0x1d57b + - "𝕼": [t: "BDCL⠟"] # 0x1d57c + - "𝕽": [t: "BDCL⠗"] # 0x1d57d + - "𝕾": [t: "BDCL⠎"] # 0x1d57e + - "𝕿": [t: "BDCL⠞"] # 0x1d57f + - "𝖀": [t: "BDCL⠥"] # 0x1d580 + - "𝖁": [t: "BDCL⠧"] # 0x1d581 + - "𝖂": [t: "BDCL⠺"] # 0x1d582 + - "𝖃": [t: "BDCL⠭"] # 0x1d583 + - "𝖄": [t: "BDCL⠽"] # 0x1d584 + - "𝖅": [t: "BDCL⠵"] # 0x1d585 + + - "𝖺": [t: "SL⠁"] # 0x1d5ba + - "𝖻": [t: "SL⠃"] # 0x1d5bb + - "𝖼": [t: "SL⠉"] # 0x1d5bc + - "𝖽": [t: "SL⠙"] # 0x1d5bd + - "𝖾": [t: "SL⠑"] # 0x1d5be + - "𝖿": [t: "SL⠋"] # 0x1d5bf + - "𝗀": [t: "SL⠛"] # 0x1d5c0 + - "𝗁": [t: "SL⠓"] # 0x1d5c1 + - "𝗂": [t: "SL⠊"] # 0x1d5c2 + - "𝗃": [t: "SL⠚"] # 0x1d5c3 + - "𝗄": [t: "SL⠅"] # 0x1d5c4 + - "𝗅": [t: "SL⠇"] # 0x1d5c5 + - "𝗆": [t: "SL⠍"] # 0x1d5c6 + - "𝗇": [t: "SL⠝"] # 0x1d5c7 + - "𝗈": [t: "SL⠕"] # 0x1d5c8 + - "𝗉": [t: "SL⠏"] # 0x1d5c9 + - "𝗊": [t: "SL⠟"] # 0x1d5ca + - "𝗋": [t: "SL⠗"] # 0x1d5cb + - "𝗌": [t: "SL⠎"] # 0x1d5cc + - "𝗍": [t: "SL⠞"] # 0x1d5cd + - "𝗎": [t: "SL⠥"] # 0x1d5ce + - "𝗏": [t: "SL⠧"] # 0x1d5cf + - "𝗐": [t: "SL⠺"] # 0x1d5d0 + - "𝗑": [t: "SL⠭"] # 0x1d5d1 + - "𝗒": [t: "SL⠽"] # 0x1d5d2 + - "𝗓": [t: "SL⠵"] # 0x1d5d3 + + - "𝖠": [t: "SCL⠁"] # 0x1d5a0 + - "𝖡": [t: "SCL⠃"] # 0x1d5a1 + - "𝖢": [t: "SCL⠉"] # 0x1d5a2 + - "𝖣": [t: "SCL⠙"] # 0x1d5a3 + - "𝖤": [t: "SCL⠑"] # 0x1d5a4 + - "𝖥": [t: "SCL⠋"] # 0x1d5a5 + - "𝖦": [t: "SCL⠛"] # 0x1d5a6 + - "𝖧": [t: "SCL⠓"] # 0x1d5a7 + - "𝖨": [t: "SCL⠊"] # 0x1d5a8 + - "𝖩": [t: "SCL⠚"] # 0x1d5a9 + - "𝖪": [t: "SCL⠅"] # 0x1d5aa + - "𝖫": [t: "SCL⠇"] # 0x1d5ab + - "𝖬": [t: "SCL⠍"] # 0x1d5ac + - "𝖭": [t: "SCL⠝"] # 0x1d5ad + - "𝖮": [t: "SCL⠕"] # 0x1d5ae + - "𝖯": [t: "SCL⠏"] # 0x1d5af + - "𝖰": [t: "SCL⠟"] # 0x1d5b0 + - "𝖱": [t: "SCL⠗"] # 0x1d5b1 + - "𝖲": [t: "SCL⠎"] # 0x1d5b2 + - "𝖳": [t: "SCL⠞"] # 0x1d5b3 + - "𝖴": [t: "SCL⠥"] # 0x1d5b4 + - "𝖵": [t: "SCL⠧"] # 0x1d5b5 + - "𝖶": [t: "SCL⠺"] # 0x1d5b6 + - "𝖷": [t: "SCL⠭"] # 0x1d5b7 + - "𝖸": [t: "SCL⠽"] # 0x1d5b8 + - "𝖹": [t: "SCL⠵"] # 0x1d5b9 + + - "𝗮": [t: "BSL⠁"] # 0x1d5ee + - "𝗯": [t: "BSL⠃"] # 0x1d5ef + - "𝗰": [t: "BSL⠉"] # 0x1d5f0 + - "𝗱": [t: "BSL⠙"] # 0x1d5f1 + - "𝗲": [t: "BSL⠑"] # 0x1d5f2 + - "𝗳": [t: "BSL⠋"] # 0x1d5f3 + - "𝗴": [t: "BSL⠛"] # 0x1d5f4 + - "𝗵": [t: "BSL⠓"] # 0x1d5f5 + - "𝗶": [t: "BSL⠊"] # 0x1d5f6 + - "𝗷": [t: "BSL⠚"] # 0x1d5f7 + - "𝗸": [t: "BSL⠅"] # 0x1d5f8 + - "𝗹": [t: "BSL⠇"] # 0x1d5f9 + - "𝗺": [t: "BSL⠍"] # 0x1d5fa + - "𝗻": [t: "BSL⠝"] # 0x1d5fb + - "𝗼": [t: "BSL⠕"] # 0x1d5fc + - "𝗽": [t: "BSL⠏"] # 0x1d5fd + - "𝗾": [t: "BSL⠟"] # 0x1d5fe + - "𝗿": [t: "BSL⠗"] # 0x1d5ff + - "𝘀": [t: "BSL⠎"] # 0x1d600 + - "𝘁": [t: "BSL⠞"] # 0x1d601 + - "𝘂": [t: "BSL⠥"] # 0x1d602 + - "𝘃": [t: "BSL⠧"] # 0x1d603 + - "𝘄": [t: "BSL⠺"] # 0x1d604 + - "𝘅": [t: "BSL⠭"] # 0x1d605 + - "𝘆": [t: "BSL⠽"] # 0x1d606 + - "𝘇": [t: "BSL⠵"] # 0x1d607 + + - "𝗔": [t: "BSCL⠁"] # 0x1d5d4 + - "𝗕": [t: "BSCL⠃"] # 0x1d5d5 + - "𝗖": [t: "BSCL⠉"] # 0x1d5d6 + - "𝗗": [t: "BSCL⠙"] # 0x1d5d7 + - "𝗘": [t: "BSCL⠑"] # 0x1d5d8 + - "𝗙": [t: "BSCL⠋"] # 0x1d5d9 + - "𝗚": [t: "BSCL⠛"] # 0x1d5da + - "𝗛": [t: "BSCL⠓"] # 0x1d5db + - "𝗜": [t: "BSCL⠊"] # 0x1d5dc + - "𝗝": [t: "BSCL⠚"] # 0x1d5dd + - "𝗞": [t: "BSCL⠅"] # 0x1d5de + - "𝗟": [t: "BSCL⠇"] # 0x1d5df + - "𝗠": [t: "BSCL⠍"] # 0x1d5e0 + - "𝗡": [t: "BSCL⠝"] # 0x1d5e1 + - "𝗢": [t: "BSCL⠕"] # 0x1d5e2 + - "𝗣": [t: "BSCL⠏"] # 0x1d5e3 + - "𝗤": [t: "BSCL⠟"] # 0x1d5e4 + - "𝗥": [t: "BSCL⠗"] # 0x1d5e5 + - "𝗦": [t: "BSCL⠎"] # 0x1d5e6 + - "𝗧": [t: "BSCL⠞"] # 0x1d5e7 + - "𝗨": [t: "BSCL⠥"] # 0x1d5e8 + - "𝗩": [t: "BSCL⠧"] # 0x1d5e9 + - "𝗪": [t: "BSCL⠺"] # 0x1d5ea + - "𝗫": [t: "BSCL⠭"] # 0x1d5eb + - "𝗬": [t: "BSCL⠽"] # 0x1d5ec + - "𝗭": [t: "BSCL⠵"] # 0x1d5ed + + - "𝘢": [t: "ISL⠁"] # 0x1d622 + - "𝘣": [t: "ISL⠃"] # 0x1d623 + - "𝘤": [t: "ISL⠉"] # 0x1d624 + - "𝘥": [t: "ISL⠙"] # 0x1d625 + - "𝘦": [t: "ISL⠑"] # 0x1d626 + - "𝘧": [t: "ISL⠋"] # 0x1d627 + - "𝘨": [t: "ISL⠛"] # 0x1d628 + - "𝘩": [t: "ISL⠓"] # 0x1d629 + - "𝘪": [t: "ISL⠊"] # 0x1d62a + - "𝘫": [t: "ISL⠚"] # 0x1d62b + - "𝘬": [t: "ISL⠅"] # 0x1d62c + - "𝘭": [t: "ISL⠇"] # 0x1d62d + - "𝘮": [t: "ISL⠍"] # 0x1d62e + - "𝘯": [t: "ISL⠝"] # 0x1d62f + - "𝘰": [t: "ISL⠕"] # 0x1d630 + - "𝘱": [t: "ISL⠏"] # 0x1d631 + - "𝘲": [t: "ISL⠟"] # 0x1d632 + - "𝘳": [t: "ISL⠗"] # 0x1d633 + - "𝘴": [t: "ISL⠎"] # 0x1d634 + - "𝘵": [t: "ISL⠞"] # 0x1d635 + - "𝘶": [t: "ISL⠥"] # 0x1d636 + - "𝘷": [t: "ISL⠧"] # 0x1d637 + - "𝘸": [t: "ISL⠺"] # 0x1d638 + - "𝘹": [t: "ISL⠭"] # 0x1d639 + - "𝘺": [t: "ISL⠽"] # 0x1d63a + - "𝘻": [t: "ISL⠵"] # 0x1d63b + + - "𝘈": [t: "ISCL⠁"] # 0x1d608 + - "𝘉": [t: "ISCL⠃"] # 0x1d609 + - "𝘊": [t: "ISCL⠉"] # 0x1d60a + - "𝘋": [t: "ISCL⠙"] # 0x1d60b + - "𝘌": [t: "ISCL⠑"] # 0x1d60c + - "𝘍": [t: "ISCL⠋"] # 0x1d60d + - "𝘎": [t: "ISCL⠛"] # 0x1d60e + - "𝘏": [t: "ISCL⠓"] # 0x1d60f + - "𝘐": [t: "ISCL⠊"] # 0x1d610 + - "𝘑": [t: "ISCL⠚"] # 0x1d611 + - "𝘒": [t: "ISCL⠅"] # 0x1d612 + - "𝘓": [t: "ISCL⠇"] # 0x1d613 + - "𝘔": [t: "ISCL⠍"] # 0x1d614 + - "𝘕": [t: "ISCL⠝"] # 0x1d615 + - "𝘖": [t: "ISCL⠕"] # 0x1d616 + - "𝘗": [t: "ISCL⠏"] # 0x1d617 + - "𝘘": [t: "ISCL⠟"] # 0x1d618 + - "𝘙": [t: "ISCL⠗"] # 0x1d619 + - "𝘚": [t: "ISCL⠎"] # 0x1d61a + - "𝘛": [t: "ISCL⠞"] # 0x1d61b + - "𝘜": [t: "ISCL⠥"] # 0x1d61c + - "𝘝": [t: "ISCL⠧"] # 0x1d61d + - "𝘞": [t: "ISCL⠺"] # 0x1d61e + - "𝘟": [t: "ISCL⠭"] # 0x1d61f + - "𝘠": [t: "ISCL⠽"] # 0x1d620 + - "𝘡": [t: "ISCL⠵"] # 0x1d621 + + - "𝙖": [t: "BILS⠁"] # 0x1d656 + - "𝙗": [t: "BILS⠃"] # 0x1d657 + - "𝙘": [t: "BILS⠉"] # 0x1d658 + - "𝙙": [t: "BILS⠙"] # 0x1d659 + - "𝙚": [t: "BILS⠑"] # 0x1d65a + - "𝙛": [t: "BILS⠋"] # 0x1d65b + - "𝙜": [t: "BILS⠛"] # 0x1d65c + - "𝙝": [t: "BILS⠓"] # 0x1d65d + - "𝙞": [t: "BILS⠊"] # 0x1d65e + - "𝙟": [t: "BILS⠚"] # 0x1d65f + - "𝙠": [t: "BILS⠅"] # 0x1d660 + - "𝙡": [t: "BILS⠇"] # 0x1d661 + - "𝙢": [t: "BILS⠍"] # 0x1d662 + - "𝙣": [t: "BILS⠝"] # 0x1d663 + - "𝙤": [t: "BILS⠕"] # 0x1d664 + - "𝙥": [t: "BILS⠏"] # 0x1d665 + - "𝙦": [t: "BILS⠟"] # 0x1d666 + - "𝙧": [t: "BILS⠗"] # 0x1d667 + - "𝙨": [t: "BILS⠎"] # 0x1d668 + - "𝙩": [t: "BILS⠞"] # 0x1d669 + - "𝙪": [t: "BILS⠥"] # 0x1d66a + - "𝙫": [t: "BILS⠧"] # 0x1d66b + - "𝙬": [t: "BILS⠺"] # 0x1d66c + - "𝙭": [t: "BILS⠭"] # 0x1d66d + - "𝙮": [t: "BILS⠽"] # 0x1d66e + - "𝙯": [t: "BILS⠵"] # 0x1d66f + + - "𝘼": [t: "BILSC⠁"] # 0x1d63c + - "𝘽": [t: "BILSC⠃"] # 0x1d63d + - "𝘾": [t: "BILSC⠉"] # 0x1d63e + - "𝘿": [t: "BILSC⠙"] # 0x1d63f + - "𝙀": [t: "BILSC⠑"] # 0x1d640 + - "𝙁": [t: "BILSC⠋"] # 0x1d641 + - "𝙂": [t: "BILSC⠛"] # 0x1d642 + - "𝙃": [t: "BILSC⠓"] # 0x1d643 + - "𝙄": [t: "BILSC⠊"] # 0x1d644 + - "𝙅": [t: "BILSC⠚"] # 0x1d645 + - "𝙆": [t: "BILSC⠅"] # 0x1d646 + - "𝙇": [t: "BILSC⠇"] # 0x1d647 + - "𝙈": [t: "BILSC⠍"] # 0x1d648 + - "𝙉": [t: "BILSC⠝"] # 0x1d649 + - "𝙊": [t: "BILSC⠕"] # 0x1d64a + - "𝙋": [t: "BILSC⠏"] # 0x1d64b + - "𝙌": [t: "BILSC⠟"] # 0x1d64c + - "𝙍": [t: "BILSC⠗"] # 0x1d64d + - "𝙎": [t: "BILSC⠎"] # 0x1d64e + - "𝙏": [t: "BILSC⠞"] # 0x1d64f + - "𝙐": [t: "BILSC⠥"] # 0x1d650 + - "𝙑": [t: "BILSC⠧"] # 0x1d651 + - "𝙒": [t: "BILSC⠺"] # 0x1d652 + - "𝙓": [t: "BILSC⠭"] # 0x1d653 + - "𝙔": [t: "BILSC⠽"] # 0x1d654 + - "𝙕": [t: "BILSC⠵"] # 0x1d655 + + - "𝚊": [t: "L⠁"] # 0x1d68a + - "𝚋": [t: "L⠃"] # 0x1d68b + - "𝚌": [t: "L⠉"] # 0x1d68c + - "𝚍": [t: "L⠙"] # 0x1d68d + - "𝚎": [t: "L⠑"] # 0x1d68e + - "𝚏": [t: "L⠋"] # 0x1d68f + - "𝚐": [t: "L⠛"] # 0x1d690 + - "𝚑": [t: "L⠓"] # 0x1d691 + - "𝚒": [t: "L⠊"] # 0x1d692 + - "𝚓": [t: "L⠚"] # 0x1d693 + - "𝚔": [t: "L⠅"] # 0x1d694 + - "𝚕": [t: "L⠇"] # 0x1d695 + - "𝚖": [t: "L⠍"] # 0x1d696 + - "𝚗": [t: "L⠝"] # 0x1d697 + - "𝚘": [t: "L⠕"] # 0x1d698 + - "𝚙": [t: "L⠏"] # 0x1d699 + - "𝚚": [t: "L⠟"] # 0x1d69a + - "𝚛": [t: "L⠗"] # 0x1d69b + - "𝚜": [t: "L⠎"] # 0x1d69c + - "𝚝": [t: "L⠞"] # 0x1d69d + - "𝚞": [t: "L⠥"] # 0x1d69e + - "𝚟": [t: "L⠧"] # 0x1d69f + - "𝚠": [t: "L⠺"] # 0x1d6a0 + - "𝚡": [t: "L⠭"] # 0x1d6a1 + - "𝚢": [t: "L⠽"] # 0x1d6a2 + - "𝚣": [t: "L⠵"] # 0x1d6a3 + + - "𝙰": [t: "CL⠁"] # 0x1d670 + - "𝙱": [t: "CL⠃"] # 0x1d671 + - "𝙲": [t: "CL⠉"] # 0x1d672 + - "𝙳": [t: "CL⠙"] # 0x1d673 + - "𝙴": [t: "CL⠑"] # 0x1d674 + - "𝙵": [t: "CL⠋"] # 0x1d675 + - "𝙶": [t: "CL⠛"] # 0x1d676 + - "𝙷": [t: "CL⠓"] # 0x1d677 + - "𝙸": [t: "CL⠊"] # 0x1d678 + - "𝙹": [t: "CL⠚"] # 0x1d679 + - "𝙺": [t: "CL⠅"] # 0x1d67a + - "𝙻": [t: "CL⠇"] # 0x1d67b + - "𝙼": [t: "CL⠍"] # 0x1d67c + - "𝙽": [t: "CL⠝"] # 0x1d67d + - "𝙾": [t: "CL⠕"] # 0x1d67e + - "𝙿": [t: "CL⠏"] # 0x1d67f + - "𝚀": [t: "CL⠟"] # 0x1d680 + - "𝚁": [t: "CL⠗"] # 0x1d681 + - "𝚂": [t: "CL⠎"] # 0x1d682 + - "𝚃": [t: "CL⠞"] # 0x1d683 + - "𝚄": [t: "CL⠥"] # 0x1d684 + - "𝚅": [t: "CL⠧"] # 0x1d685 + - "𝚆": [t: "CL⠺"] # 0x1d686 + - "𝚇": [t: "CL⠭"] # 0x1d687 + - "𝚈": [t: "CL⠽"] # 0x1d688 + - "𝚉": [t: "CL⠵"] # 0x1d689 + + - "𝚤": [t: "L⠊"] # 0x1d6a4 (dotless i) + - "𝚥": [t: "L⠚"] # 0x1d6a5 (dotless j) + - "𝛂": [t: "BGL⠁"] # 0x1d6c2 + - "𝛃": [t: "BGL⠃"] # 0x1d6c3 + - "𝛄": [t: "BGL⠛"] # 0x1d6c4 + - "𝛅": [t: "BGL⠙"] # 0x1d6c5 + - "𝛆": [t: "BGL⠑"] # 0x1d6c6 + - "𝛇": [t: "BGL⠵"] # 0x1d6c7 + - "𝛈": [t: "BGL⠱ "] # 0x1d6c8 + - "𝛉": [t: "BGL⠹"] # 0x1d6c9 + - "𝛊": [t: "BGL⠊"] # 0x1d6ca + - "𝛋": [t: "BGL⠅"] # 0x1d6cb + - "𝛌": [t: "BGL⠇"] # 0x1d6cc + - "𝛍": [t: "BGL⠍"] # 0x1d6cd + - "𝛎": [t: "BGL⠝"] # 0x1d6ce + - "𝛏": [t: "BGL⠭"] # 0x1d6cf + - "𝛐": [t: "BGL⠕"] # 0x1d6d0 + - "𝛑": [t: "BGL⠏"] # 0x1d6d1 + - "𝛒": [t: "BGL⠗"] # 0x1d6d2 + - "𝛓": [t: "BGL⠎"] # 0x1d6d3 + - "𝛔": [t: "BGL⠞"] # 0x1d6d4 + - "𝛕": [t: "BGL⠥"] # 0x1d6d5 + - "𝛖": [t: "BGL⠋"] # 0x1d6d6 + - "𝛗": [t: "BGL⠯"] # 0x1d6d7 + - "𝛘": [t: "BGL⠽"] # 0x1d6d8 + - "𝛙": [t: "BGL⠺"] # 0x1d6d9 + + - "𝚨": [t: "BCGL⠁"] # 0x1d6a8 + - "𝚩": [t: "BCGL⠃"] # 0x1d6a9 + - "𝚪": [t: "BCGL⠛"] # 0x1d6aa + - "𝚫": [t: "BCGL⠙"] # 0x1d6ab + - "𝚬": [t: "BCGL⠑"] # 0x1d6ac + - "𝚭": [t: "BCGL⠵"] # 0x1d6ad + - "𝚮": [t: "BCGL⠱ "] # 0x1d6ae + - "𝚯": [t: "BCGL⠹"] # 0x1d6af + - "𝚰": [t: "BCGL⠊"] # 0x1d6b0 + - "𝚱": [t: "BCGL⠅"] # 0x1d6b1 + - "𝚲": [t: "BCGL⠇"] # 0x1d6b2 + - "𝚳": [t: "BCGL⠍"] # 0x1d6b3 + - "𝚴": [t: "BCGL⠝"] # 0x1d6b4 + - "𝚵": [t: "BCGL⠭"] # 0x1d6b5 + - "𝚶": [t: "BCGL⠕"] # 0x1d6b6 + - "𝚷": [t: "BCGL⠏"] # 0x1d6b7 + - "𝚸": [t: "BCGL⠗"] # 0x1d6b8 + - "𝚹": [t: "BCGL⠎"] # 0x1d6b9 + - "𝚺": [t: "BCGL⠞"] # 0x1d6ba + - "𝚻": [t: "BCGL⠥"] # 0x1d6bb + - "𝚼": [t: "BCGL⠋"] # 0x1d6bc + - "𝚽": [t: "BCGL⠯"] # 0x1d6bd + - "𝚾": [t: "BCGL⠽"] # 0x1d6be + - "𝚿": [t: "BCGL⠺"] # 0x1d6bf + + - "𝛼": [t: "IGL⠁"] # 0x1d6fc + - "𝛽": [t: "IGL⠃"] # 0x1d6fd + - "𝛾": [t: "IGL⠛"] # 0x1d6fe + - "𝛿": [t: "IGL⠙"] # 0x1d6ff + - "𝜀": [t: "IGL⠑"] # 0x1d700 + - "𝜁": [t: "IGL⠵"] # 0x1d701 + - "𝜂": [t: "IGL⠱ "] # 0x1d702 + - "𝜃": [t: "IGL⠹"] # 0x1d703 + - "𝜄": [t: "IGL⠊"] # 0x1d704 + - "𝜅": [t: "IGL⠅"] # 0x1d705 + - "𝜆": [t: "IGL⠇"] # 0x1d706 + - "𝜇": [t: "IGL⠍"] # 0x1d707 + - "𝜈": [t: "IGL⠝"] # 0x1d708 + - "𝜉": [t: "IGL⠭"] # 0x1d709 + - "𝜊": [t: "IGL⠕"] # 0x1d70a + - "𝜋": [t: "IGL⠏"] # 0x1d70b + - "𝜌": [t: "IGL⠗"] # 0x1d70c + - "𝜍": [t: "IGL⠎"] # 0x1d70d + - "𝜎": [t: "IGL⠞"] # 0x1d70e + - "𝜏": [t: "IGL⠥"] # 0x1d70f + - "𝜐": [t: "IGL⠋"] # 0x1d710 + - "𝜑": [t: "IGL⠯"] # 0x1d711 + - "𝜒": [t: "IGL⠽"] # 0x1d712 + - "𝜓": [t: "IGL⠺"] # 0x1d713 + + - "𝛢": [t: "ICGL⠁"] # 0x1d6e2 + - "𝛣": [t: "ICGL⠃"] # 0x1d6e3 + - "𝛤": [t: "ICGL⠛"] # 0x1d6e4 + - "𝛥": [t: "ICGL⠙"] # 0x1d6e5 + - "𝛦": [t: "ICGL⠑"] # 0x1d6e6 + - "𝛧": [t: "ICGL⠵"] # 0x1d6e7 + - "𝛨": [t: "ICGL⠱ "] # 0x1d6e8 + - "𝛩": [t: "ICGL⠹"] # 0x1d6e9 + - "𝛪": [t: "ICGL⠊"] # 0x1d6ea + - "𝛫": [t: "ICGL⠅"] # 0x1d6eb + - "𝛬": [t: "ICGL⠇"] # 0x1d6ec + - "𝛭": [t: "ICGL⠍"] # 0x1d6ed + - "𝛮": [t: "ICGL⠝"] # 0x1d6ee + - "𝛯": [t: "ICGL⠭"] # 0x1d6ef + - "𝛰": [t: "ICGL⠕"] # 0x1d6f0 + - "𝛱": [t: "ICGL⠏"] # 0x1d6f1 + - "𝛲": [t: "ICGL⠗"] # 0x1d6f2 + - "𝛳": [t: "ICGL⠎"] # 0x1d6f3 + - "𝛴": [t: "ICGL⠞"] # 0x1d6f4 + - "𝛵": [t: "ICGL⠥"] # 0x1d6f5 + - "𝛶": [t: "ICGL⠋"] # 0x1d6f6 + - "𝛷": [t: "ICGL⠯"] # 0x1d6f7 + - "𝛸": [t: "ICGL⠽"] # 0x1d6f8 + - "𝛹": [t: "ICGL⠺"] # 0x1d6f9 + + - "𝜶": [t: "BIGL⠁"] # 0x1d736 + - "𝜷": [t: "BIGL⠃"] # 0x1d737 + - "𝜸": [t: "BIGL⠛"] # 0x1d738 + - "𝜹": [t: "BIGL⠙"] # 0x1d739 + - "𝜺": [t: "BIGL⠑"] # 0x1d73a + - "𝜻": [t: "BIGL⠵"] # 0x1d73b + - "𝜼": [t: "BIGL⠱ "] # 0x1d73c + - "𝜽": [t: "BIGL⠹"] # 0x1d73d + - "𝜾": [t: "BIGL⠊"] # 0x1d73e + - "𝜿": [t: "BIGL⠅"] # 0x1d73f + - "𝝀": [t: "BIGL⠇"] # 0x1d740 + - "𝝁": [t: "BIGL⠍"] # 0x1d741 + - "𝝂": [t: "BIGL⠝"] # 0x1d742 + - "𝝃": [t: "BIGL⠭"] # 0x1d743 + - "𝝄": [t: "BIGL⠕"] # 0x1d744 + - "𝝅": [t: "BIGL⠏"] # 0x1d745 + - "𝝆": [t: "BIGL⠗"] # 0x1d746 + - "𝝇": [t: "BIGL⠎"] # 0x1d747 + - "𝝈": [t: "BIGL⠞"] # 0x1d748 + - "𝝉": [t: "BIGL⠥"] # 0x1d749 + - "𝝊": [t: "BIGL⠋"] # 0x1d74a + - "𝝋": [t: "BIGL⠯"] # 0x1d74b + - "𝝌": [t: "BIGL⠽"] # 0x1d74c + - "𝝍": [t: "BIGL⠺"] # 0x1d74d + + - "𝜜": [t: "BICGL⠁"] # 0x1d71c + - "𝜝": [t: "BICGL⠃"] # 0x1d71d + - "𝜞": [t: "BICGL⠛"] # 0x1d71e + - "𝜟": [t: "BICGL⠙"] # 0x1d71f + - "𝜠": [t: "BICGL⠑"] # 0x1d720 + - "𝜡": [t: "BICGL⠵"] # 0x1d721 + - "𝜢": [t: "BICGL⠱ "] # 0x1d722 + - "𝜣": [t: "BICGL⠹"] # 0x1d723 + - "𝜤": [t: "BICGL⠊"] # 0x1d724 + - "𝜥": [t: "BICGL⠅"] # 0x1d725 + - "𝜦": [t: "BICGL⠇"] # 0x1d726 + - "𝜧": [t: "BICGL⠍"] # 0x1d727 + - "𝜨": [t: "BICGL⠝"] # 0x1d728 + - "𝜩": [t: "BICGL⠭"] # 0x1d729 + - "𝜪": [t: "BICGL⠕"] # 0x1d72a + - "𝜫": [t: "BICGL⠏"] # 0x1d72b + - "𝜬": [t: "BICGL⠗"] # 0x1d72c + - "𝜭": [t: "BICGL⠎"] # 0x1d72d + - "𝜮": [t: "BICGL⠞"] # 0x1d72e + - "𝜯": [t: "BICGL⠥"] # 0x1d72f + - "𝜰": [t: "BICGL⠋"] # 0x1d730 + - "𝜱": [t: "BICGL⠯"] # 0x1d731 + - "𝜲": [t: "BICGL⠽"] # 0x1d732 + - "𝜳": [t: "BICGL⠺"] # 0x1d733 + + - "𝝰": [t: "BSGL⠁"] # 0x1d770 + - "𝝱": [t: "BSGL⠃"] # 0x1d771 + - "𝝲": [t: "BSGL⠛"] # 0x1d772 + - "𝝳": [t: "BSGL⠙"] # 0x1d773 + - "𝝴": [t: "BSGL⠑"] # 0x1d774 + - "𝝵": [t: "BSGL⠵"] # 0x1d775 + - "𝝶": [t: "BSGL⠱ "] # 0x1d776 + - "𝝷": [t: "BSGL⠹"] # 0x1d777 + - "𝝸": [t: "BSGL⠊"] # 0x1d778 + - "𝝹": [t: "BSGL⠅"] # 0x1d779 + - "𝝺": [t: "BSGL⠇"] # 0x1d77a + - "𝝻": [t: "BSGL⠍"] # 0x1d77b + - "𝝼": [t: "BSGL⠝"] # 0x1d77c + - "𝝽": [t: "BSGL⠭"] # 0x1d77d + - "𝝾": [t: "BSGL⠕"] # 0x1d77e + - "𝝿": [t: "BSGL⠏"] # 0x1d77f + - "𝞀": [t: "BSGL⠗"] # 0x1d780 + - "𝞁": [t: "BSGL⠎"] # 0x1d781 + - "𝞂": [t: "BSGL⠞"] # 0x1d782 + - "𝞃": [t: "BSGL⠥"] # 0x1d783 + - "𝞄": [t: "BSGL⠋"] # 0x1d784 + - "𝞅": [t: "BSGL⠯"] # 0x1d785 + - "𝞆": [t: "BSGL⠽"] # 0x1d786 + - "𝞇": [t: "BSGL⠺"] # 0x1d787 + + - "𝝖": [t: "BSCGL⠁"] # 0x1d756 + - "𝝗": [t: "BSCGL⠃"] # 0x1d757 + - "𝝘": [t: "BSCGL⠛"] # 0x1d758 + - "𝝙": [t: "BSCGL⠙"] # 0x1d759 + - "𝝚": [t: "BSCGL⠑"] # 0x1d75a + - "𝝛": [t: "BSCGL⠵"] # 0x1d75b + - "𝝜": [t: "BSCGL⠱ "] # 0x1d75c + - "𝝝": [t: "BSCGL⠹"] # 0x1d75d + - "𝝞": [t: "BSCGL⠊"] # 0x1d75e + - "𝝟": [t: "BSCGL⠅"] # 0x1d75f + - "𝝠": [t: "BSCGL⠇"] # 0x1d760 + - "𝝡": [t: "BSCGL⠍"] # 0x1d761 + - "𝝢": [t: "BSCGL⠝"] # 0x1d762 + - "𝝣": [t: "BSCGL⠭"] # 0x1d763 + - "𝝤": [t: "BSCGL⠕"] # 0x1d764 + - "𝝥": [t: "BSCGL⠏"] # 0x1d765 + - "𝝦": [t: "BSCGL⠗"] # 0x1d766 + - "𝝧": [t: "BSCGL⠎"] # 0x1d767 + - "𝝨": [t: "BSCGL⠞"] # 0x1d768 + - "𝝩": [t: "BSCGL⠥"] # 0x1d769 + - "𝝪": [t: "BSCGL⠋"] # 0x1d76a + - "𝝫": [t: "BSCGL⠯"] # 0x1d76b + - "𝝬": [t: "BSCGL⠽"] # 0x1d76c + - "𝝭": [t: "BSCGL⠺"] # 0x1d76d + + - "𝞪": [t: "BISGL⠁"] # 0x1d7aa + - "𝞫": [t: "BISGL⠃"] # 0x1d7ab + - "𝞬": [t: "BISGL⠛"] # 0x1d7ac + - "𝞭": [t: "BISGL⠙"] # 0x1d7ad + - "𝞮": [t: "BISGL⠑"] # 0x1d7ae + - "𝞯": [t: "BISGL⠵"] # 0x1d7af + - "𝞰": [t: "BISGL⠱ "] # 0x1d7b0 + - "𝞱": [t: "BISGL⠹"] # 0x1d7b1 + - "𝞲": [t: "BISGL⠊"] # 0x1d7b2 + - "𝞳": [t: "BISGL⠅"] # 0x1d7b3 + - "𝞴": [t: "BISGL⠇"] # 0x1d7b4 + - "𝞵": [t: "BISGL⠍"] # 0x1d7b5 + - "𝞶": [t: "BISGL⠝"] # 0x1d7b6 + - "𝞷": [t: "BISGL⠭"] # 0x1d7b7 + - "𝞸": [t: "BISGL⠕"] # 0x1d7b8 + - "𝞹": [t: "BISGL⠏"] # 0x1d7b9 + - "𝞺": [t: "BISGL⠗"] # 0x1d7ba + - "𝞻": [t: "BISGL⠎"] # 0x1d7bb + - "𝞼": [t: "BISGL⠞"] # 0x1d7bc + - "𝞽": [t: "BISGL⠥"] # 0x1d7bd + - "𝞾": [t: "BISGL⠋"] # 0x1d7be + - "𝞿": [t: "BISGL⠯"] # 0x1d7bf + - "𝟀": [t: "BISGL⠽"] # 0x1d7c0 + - "𝟁": [t: "BISGL⠺"] # 0x1d7c1 + + - "𝞐": [t: "BISCGL⠁"] # 0x1d790 + - "𝞑": [t: "BISCGL⠃"] # 0x1d791 + - "𝞒": [t: "BISCGL⠛"] # 0x1d792 + - "𝞓": [t: "BISCGL⠙"] # 0x1d793 + - "𝞔": [t: "BISCGL⠑"] # 0x1d794 + - "𝞕": [t: "BISCGL⠵"] # 0x1d795 + - "𝞖": [t: "BISCGL⠱ "] # 0x1d796 + - "𝞗": [t: "BISCGL⠹"] # 0x1d797 + - "𝞘": [t: "BISCGL⠊"] # 0x1d798 + - "𝞙": [t: "BISCGL⠅"] # 0x1d799 + - "𝞚": [t: "BISCGL⠇"] # 0x1d79a + - "𝞛": [t: "BISCGL⠍"] # 0x1d79b + - "𝞜": [t: "BISCGL⠝"] # 0x1d79c + - "𝞝": [t: "BISCGL⠭"] # 0x1d79d + - "𝞞": [t: "BISCGL⠕"] # 0x1d79e + - "𝞟": [t: "BISCGL⠏"] # 0x1d79f + - "𝞠": [t: "BISCGL⠗"] # 0x1d7a0 + - "𝞡": [t: "BISCGL⠎"] # 0x1d7a1 + - "𝞢": [t: "BISCGL⠞"] # 0x1d7a2 + - "𝞣": [t: "BISCGL⠥"] # 0x1d7a3 + - "𝞤": [t: "BISCGL⠋"] # 0x1d7a4 + - "𝞥": [t: "BISCGL⠯"] # 0x1d7a5 + - "𝞦": [t: "BISCGL⠽"] # 0x1d7a6 + - "𝞧": [t: "BISCGL⠺"] # 0x1d7a7 + + - "𝟎-𝟗": # 0x1d7ce - 0x1d7d7 + - t: "B" + - spell: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" + + - "-": # 0xf52e - 0xf537 (old MathType) + - t: "B" + - spell: "translate('.', '', '0123456789')" + + - "𝟬-𝟵": # 0x1D7EC - 0x1D7F5 + - t: "B" + - spell: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" + + - "-": # 0xf556 - 0xf55f (old MathType) + - t: "B" + - spell: "translate('.', '', '0123456789')" + + - "𝟢-𝟫": # 0x1d7e2 - 0x1d7eb + - spell: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" + + - "𝟶-𝟿": # 0x1d7f6 - 0x1d7ff + - spell: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" diff --git a/Rules/Braille/French/unicode.yaml b/Rules/Braille/French/unicode.yaml new file mode 100644 index 000000000..e37c31f40 --- /dev/null +++ b/Rules/Braille/French/unicode.yaml @@ -0,0 +1,317 @@ +--- +# French braille characters +# +# Some chars that originally came from an Excel spreadsheet +# +# The French translation makes use of some non-braille chars as flags +# L -- what follows is a letter +# N -- what follows is a digit +# C -- precedes L for capital letters +# G -- precedes L for Greek Letters (after C for capitals) +# Typeface Indicators ("typeforms") +# B bold, I Italic, S Sans-serif, T script, D, Fraktur, 𝔹 blackboard-bold +# the type face indicators can be combined with B (first) and I (second) +# Standing alone chars: +# Any character which acts as a standing alone character (e.g, "{") needs each braille symbol to be labeled +# o -- opening/left side, c -- closing/right side, b -- both open and close (e.g, '"') + + + + - "a": [t: "L⠁"] # 0x61 + - "b": [t: "L⠃"] # 0x62 + - "c": [t: "L⠉"] # 0x63 + - "d": [t: "L⠙"] # 0x64 + - "e": [t: "L⠑"] # 0x65 + - "f": [t: "L⠋"] # 0x66 + - "g": [t: "L⠛"] # 0x67 + - "h": [t: "L⠓"] # 0x68 + - "i": [t: "L⠊"] # 0x69 + - "j": [t: "L⠚"] # 0x6a + - "k": [t: "L⠅"] # 0x6b + - "l": [t: "L⠇"] # 0x6c + - "m": [t: "L⠍"] # 0x6d + - "n": [t: "L⠝"] # 0x6e + - "o": [t: "L⠕"] # 0x6f + - "p": [t: "L⠏"] # 0x70 + - "q": [t: "L⠟"] # 0x71 + - "r": [t: "L⠗"] # 0x72 + - "s": [t: "L⠎"] # 0x73 + - "t": [t: "L⠞"] # 0x74 + - "u": [t: "L⠥"] # 0x75 + - "v": [t: "L⠧"] # 0x76 + - "w": [t: "L⠺"] # 0x77 + - "x": [t: "L⠭"] # 0x78 + - "y": [t: "L⠽"] # 0x79 + - "z": [t: "L⠵"] # 0x7a + + - "A": [t: "CL⠁"] # 0x41 + - "B": # 0x42 + - test: + if: "@data-chem-element" + then: [t: "𝐶L⠃"] + else: [t: "CL⠃"] + - "C": # 0x43 + - test: + if: "@data-chem-element" + then: [t: "𝐶L⠉"] + else: [t: "CL⠉"] + - "D": [t: "CL⠙"] # 0x44 + - "E": [t: "CL⠑"] # 0x45 + - "F": [t: "CL⠋"] # 0x46 + - "G": [t: "CL⠛"] # 0x47 + - "H": # 0x48 + - test: + if: "@data-chem-element" + then: [t: "𝐶L⠓"] + else: [t: "CL⠓"] + - "I": # 0x49 + - test: + if: "@data-chem-element" + then: [t: "𝐶L⠊"] + else: [t: "CL⠊"] + - "J": [t: "CL⠚"] # 0x4a + - "K": # 0x4b + - test: + if: "@data-chem-element" + then: [t: "𝐶L⠅"] + else: [t: "CL⠅"] + - "L": [t: "CL⠇"] # 0x4c + - "M": [t: "CL⠍"] # 0x4d + - "N": # 0x4e + - test: + if: "@data-chem-element" + then: [t: "𝐶L⠝"] + else: [t: "CL⠝"] + - "O": # 0x4f + - test: + if: "@data-chem-element" + then: [t: "𝐶L⠕"] + else: [t: "CL⠕"] + - "P": # 0x50 + - test: + if: "@data-chem-element" + then: [t: "𝐶L⠏"] + else: [t: "CL⠏"] + - "Q": [t: "CL⠟"] # 0x51 + - "R": [t: "CL⠗"] # 0x52 + - "S": # 0x53 + - test: + if: "@data-chem-element" + then: [t: "𝐶L⠎"] + else: [t: "CL⠎"] + - "T": [t: "CL⠞"] # 0x54 + - "U": # 0x55 + - test: + if: "@data-chem-element" + then: [t: "𝐶L⠥"] + else: [t: "CL⠥"] + - "V": # 0x56 + - test: + if: "@data-chem-element" + then: [t: "𝐶L⠧"] + else: [t: "CL⠧"] + - "W": # 0x57 + - test: + if: "@data-chem-element" + then: [t: "𝐶L⠺"] + else: [t: "CL⠺"] + - "X": [t: "CL⠭"] # 0x58 + - "Y": # 0x59 + - test: + if: "@data-chem-element" + then: [t: "𝐶L⠽"] + else: [t: "CL⠽"] + - "Z": [t: "CL⠵"] # 0x5a + + - "α": [t: "GL⠁"] # 0x3b1 + - "β": [t: "GL⠃"] # 0x3b2 + - "γ": [t: "GL⠛"] # 0x3b3 + - "δ": [t: "GL⠙"] # 0x3b4 + - "ε": [t: "GL⠑"] # 0x3b5 + - "ζ": [t: "GL⠵"] # 0x3b6 + - "η": [t: "GL⠱"] # 0x3b7 + - "θ": [t: "GL⠹"] # 0x3b8 + - "ι": [t: "GL⠊"] # 0x3b9 + - "κ": [t: "GL⠅"] # 0x3ba + - "λ": [t: "GL⠇"] # 0x3bb + - "μ": [t: "GL⠍"] # 0x3bc + - "ν": [t: "GL⠝"] # 0x3bd + - "ξ": [t: "GL⠭"] # 0x3be + - "ο": [t: "GL⠕"] # 0x3bf + - "π": [t: "GL⠏"] # 0x3c0 + - "ρ": [t: "GL⠗"] # 0x3c1 + - "ς": [t: "GL⠎"] # 0x3c2 + - "σ": [t: "GL⠎"] # 0x3c3 + - "τ": [t: "GL⠞"] # 0x3c4 + - "υ": [t: "GL⠥"] # 0x3c5 + - "φ": [t: "GL⠋"] # 0x3c6 + - "χ": [t: "GL⠯"] # 0x3c7 + - "ψ": [t: "GL⠽"] # 0x3c8 + - "ω": [t: "GL⠺"] # 0x3c9 + + - "Α": [t: "CGL⠁"] # 0x391 + - "Β": [t: "CGL⠃"] # 0x392 + - "Γ": [t: "CGL⠛"] # 0x393 + - "Δ": [t: "CGL⠙"] # 0x394 + - "Ε": [t: "CGL⠑"] # 0x395 + - "Ζ": [t: "CGL⠵"] # 0x396 + - "Η": [t: "CGL⠱ "] # 0x397 + - "Θ": [t: "CGL⠹"] # 0x398 + - "Ι": [t: "CGL⠊"] # 0x399 + - "Κ": [t: "CGL⠅"] # 0x39a + - "Λ": [t: "CGL⠇"] # 0x39b + - "Μ": [t: "CGL⠍"] # 0x39c + - "Ν": [t: "CGL⠝"] # 0x39d + - "Ξ": [t: "CGL⠭"] # 0x39e + - "Ο": [t: "CGL⠕"] # 0x39f + - "Π": [t: "CGL⠏"] # 0x3a0 + - "Ρ": [t: "CGL⠗"] # 0x3a1 + - "΢": [t: "CGL⠎"] # 0x3a2 + - "Σ": [t: "CGL⠎"] # 0x3a3 + - "Τ": [t: "CGL⠞"] # 0x3a4 + - "Υ": [t: "CGL⠥"] # 0x3a5 + - "Φ": [t: "CGL⠋"] # 0x3a6 + - "Χ": [t: "CGL⠯"] # 0x3a7 + - "Ψ": [t: "CGL⠽"] # 0x3a8 + - "Ω": [t: "CGL⠺"] # 0x3a9 + + - "µ": [t: "GL⠍"] # 0x00B5 (Micro (Greek mu)) + - "Ω": [t: "CGL⠺"] # 0x2126 (Ohm sign (capital Greek omega)) + - "∆": [t: "CGL⠙"] # 0x2206 (Increment (capital Greek delta)) + - "∏": [t: "CGL⠏"] # 0x220F (Product (capital Greek pi)) + + - "⁡": [t: ""] # 0x2061⁡ (invisible function apply) + - "⁢": [t: ""] # 0x2062 (invisible times) + - "⁣": [t: ""] # 0x2063⁡ (invisible separator) + - "⁤": [t: ""] # 0x2064 (invisible plus) + + + - "!": [t: "⠸⠔"] # 0x0021 (factorial) + - "%": [t: "⠐⠬"] # 0x0025 (percent sign) + - "(": [t: "⠦"] # 0x0028 (left parenthesis) + - ")": [t: "⠴"] # 0x0029 (right parenthesis) + - "+": [t: "⠖"] # 0x002B (regular plus) + - ",": [t: "⠂"] # 0x002C (comma) + - "-": [t: "⠤"] # 0x002D (regular minus) + - ".": [t: "⠂"] # 0x002E (decimal point (American and Continental)) + - "/": [t: "⠌"] # 0x002F (diagonal fraction line) + - "0": [t: "N⠼"] # 0x0030 (digit zero) + - "1": [t: "N⠡"] # 0x0031 (digit one) + - "2": [t: "N⠣"] # 0x0032 (digit two) + - "3": [t: "N⠩"] # 0x0033 (digit three) + - "4": [t: "N⠹"] # 0x0034 (digit four) + - "5": [t: "N⠱"] # 0x0035 (digit five) + - "6": [t: "N⠫"] # 0x0036 (digit six) + - "7": [t: "N⠻"] # 0x0037 (digit seven) + - "8": [t: "N⠳"] # 0x0038 (digit eight) + - "9": [t: "N⠪"] # 0x0039 (digit nine) + - ":": [t: "⠒"] # 0x003A (colon) + - "<": [t: "⠐⠣"] # 0x003C (less than sign) + - "=": [t: "⠶"] # 0x003D (regular equals sign) + - ">": [t: "⠐⠜"] # 0x003E (greater than sign ( regular )) + - "[": [t: "⠷"] # 0x005B (left square bracket) + - "]": [t: "⠾"] # 0x005D (right square bracket) + - "{": # 0x007B ( left curly brace) + - test: + if: "following-sibling::*[1][self::m:mtable]" + then_test: + if: "count(following-sibling::*[1]/*) = 1" + then: [t: "⠨⠦"] + else: [t: "⠸⠦"] + else: [t: "⠨⠦"] # regular brace + - "|": [t: "⠿"] # 0x007C (vertical bar) + - "}": [t: "⠨⠴"] # 0x007D (right curly brace) + - "~": [t: "⠘⠶"] # 0x007E (simple tilde (is related to, is similar)) + - "¢": [t: "⠉"] # 0x00A2 (cent) + - "°": [t: "⠐⠕"] # 0x00B0 (degree sign) + - "±": [t: "⠖⠤"] # 0x00B1 (plus or minus) + - "¼": [t: "⠡⠌⠹"] # 0x00BC (vulgar fraction one quarter) + - "½": [t: "⠡⠌⠣"] # 0x00BD (vulgar fraction one half) + - "¾": [t: "⠩⠌⠹"] # 0x00BE (vulgar fraction three quarters) + - "×": [t: "⠔"] # 0x00D7 ( multiplication sign) + - "÷": [t: "⠒"] # 0x00F7 (division sign ( divided by )) + - "ב": [t: "⠘⠘⠃"] # 0x05D1 ( beth) + - "ג": [t: "⠘⠘⠛"] # 0x05D2 (gimel) + - "ד": [t: "⠘⠘⠙"] # 0x05D3 (daleth) + - "‖": [t: "⠘⠿"] # 0x2016 (double vertical bar) + - "‰": [t: "⠐⠬⠬"] # 0x2030 (per mille sign) + - "′": [t: "⠄"] # 0x2032 (prime) + - "″": [t: "⠄⠄"] # 0x2033 (double prime) + - "‴": [t: "⠄⠄⠄"] # 0x2034 (triple prime) + - "€": [t: "⠘⠑"] # 0x20AC (euro) + - "Å": [t: "⠨⠁⠈⠕"] # 0x212B (angstrom) + - "ℵ": [t: "⠘⠘⠁"] # 0x2135 (alef) + - "←": [t: "⠸⠪"] # 0x2190 (left pointing arrow) + - "↑": [t: "⠘⠻"] # 0x2191 (arrow pointing up) + - "→": [t: "⠸⠱"] # 0x2192 (left pointing arrow) + - "↓": [t: "⠨⠻"] # 0x2193 (arrow pointing down) + - "↔": [t: "⠐⠻"] # 0x2194 (horizontal two-way arrow) + - "↖": [t: "⠘⠪"] # 0x2196 (north west arrow) + - "↗": [t: "⠘⠱"] # 0x2197 (north east arrow) + - "↘": [t: "⠨⠱"] # 0x2198 (south east arrow) + - "↙": [t: "⠨⠪"] # 0x2199 (south west arrow) + - "↚": [t: "⠨⠸⠪"] # 0x219A (leftwards arrow with stroke) + - "↛": [t: "⠨⠸⠱"] # 0x219B (rightwards arrow with stroke) + - "↦": [t: "⠐⠱"] # 0x21A6 (rightwards arrow from bar (maps to)) + - "⇄": [t: "⠸⠻"] # 0x21C4 (arrow pointing right over arrow pointing left) + - "⇍": [t: "⠨⠐⠒"] # 0x21CD (leftwards double arrow with stroke) + - "⇎": [t: "⠨⠐⠒⠂"] # 0x21CE (left right double arrow with stroke (not equivalent)) + - "⇏": [t: "⠨⠒⠂"] # 0x21CF (rightwards double arrow with stroke (does not imply)) + - "⇐": [t: "⠐⠒"] # 0x21D0 (leftwards double arrow) + - "⇒": [t: "⠒⠂"] # 0x21D2 (rightwards double arrow (implication)) + - "⇔": [t: "⠐⠒⠂"] # 0x21D4 (left right double arrow (double implication, equivalence)) + - "∀": [t: "⠸⠌"] # 0x2200 (universal quantifier (for all, for each, for every)) + - "∁": [t: "⠨⠩"] # 0x2201 (capital english c (complement)) + - "∂": [t: "⠐⠙"] # 0x2202 (partial derivative (round d)) + - "∃": [t: "⠸⠡"] # 0x2203 (existential quantifier (there exists uniquely, for exactly one)) + - "∄": [t: "⠨⠸⠡"] # 0x2204 (does not exist) + - "∅": [t: "⠘⠼"] # 0x2205 (empty set ( represented by zero with vertical or oblique bar through it)) + - "∇": [t: "⠨⠹"] # 0x2207 (del (nabla, gradient) , inverted triangle) + - "∈": [t: "⠘⠡"] # 0x2208 (membership (is an element of)) + - "∉": [t: "⠘⠌"] # 0x2209 (is not an element of) + - "∋": [t: "⠨⠘⠡"] # 0x220B (reverse membership (contains the element)) + - "∌": [t: "⠨⠘⠌"] # 0x220C (does not contain as a member) + - "∑": [t: "⠨⠘⠎"] # 0x2211 (n-ary summation) + - "∓": [t: "⠤⠖"] # 0x2213 (minus or plus) + - "∘": [t: "⠸⠼"] # 0x2218 (hollow dot) + - "∞": [t: "⠘⠉"] # 0x221E (infinity) + - "∥": [t: "⠸⠳"] # 0x2225 (is parallel to) + - "∧": [t: "⠘⠔"] # 0x2227 (logical product (and, meet)) + - "∨": [t: "⠘⠢"] # 0x2228 (logical sum (join,or)) + - "∩": [t: "⠘⠖"] # 0x2229 (intersection sign ( cap )) + - "∪": [t: "⠸⠖"] # 0x222A (union sign) + - "∫": [t: "⠯"] # 0x222B (single integral) + - "∬": [t: "⠯⠯"] # 0x222C (double integral) + - "∮": [t: "⠨⠯"] # 0x222E (integral with superposed circle) + - "∯": [t: "⠨⠯⠯"] # 0x222F (double contour integral/surface integral) + - "≃": [t: "⠐⠶"] # 0x2243 (bar under simple tilde (asymptotically equal to)) + - "≅": [t: "⠸⠶"] # 0x2245 (equals sign under tilde) + - "≈": [t: "⠐⠶"] # 0x2248 (double tilde) + - "≙": [t: "⠒⠶"] # 0x2259 (caret over equals sign) + - "≠": [t: "⠨⠶"] # 0x2260 (not equal to) + - "≡": [t: "⠶⠶"] # 0x2261 (identify (is congruent to, is identical with)) + - "≢": [t: "⠨⠶⠶"] # 0x2262 (is not identical to) + - "≤": [t: "⠘⠣"] # 0x2264 (bar under less than sign (is less than or equal to)) + - "≥": [t: "⠘⠜"] # 0x2265 (bar under greater than sign (is greater than or equal to)) + - "≪": [t: "⠐⠐⠣"] # 0x226A (nest of two less than signs with straight sides (is small compared with)) + - "≫": [t: "⠐⠐⠜"] # 0x226B (nest of two greater than signs with straight sides (is large compared with)) + - "≺": [t: "⠨⠨⠣"] # 0x227A (less than sign with curved sides) + - "≻": [t: "⠨⠨⠜"] # 0x227B (greater than sign with curved sides ) + - "≼": [t: "⠘⠘⠣"] # 0x227C (less than sign with curved sides over curved bar (precedes or is equal to)) + - "≽": [t: "⠘⠘⠜"] # 0x227D (greater than sign with curved sides over curved bar (succeeds or is equal to)) + - "⊂": [t: "⠨⠡"] # 0x2282 (inclusion sign ( is contained in, is a subset of )) + - "⊃": [t: "⠐⠡"] # 0x2283 (reverse inclusion sign ( contains, implies )) + - "⊄": [t: "⠨⠌"] # 0x2284 (not a subset of) + - "⊅": [t: "⠐⠌"] # 0x2285 (not a superset of) + - "⊆": [t: "⠸⠨⠡"] # 0x2286 (bar under inclusion sign (is a subset of)) + - "⊈": [t: "⠸⠨⠌"] # 0x2288 (neither a subset of nor equal to) + - "⊕": [t: "⠨⠖"] # 0x2295 (circle with interior plus sign (exclusive or, direct sum, diletion)) + - "⊗": [t: "⠨⠔"] # 0x2297 (circle with interior cross (tensor product)) + - "⊥": [t: "⠘⠳"] # 0x22A5 (is perpendicular to) + - "⋅": [t: "⠔⠔"] # 0x22C5 (dot,and times) + - "⌄": [t: "⠸⠘⠒"] # 0x2304 (inverted caret) + - "⏜": [t: "⠈⠒"] # 0x23DC (arc concave upward) + - "△": [t: "⠨⠘⠙"] # 0x25B3 (increment (laplacian Delta) ) + - "✕": [t: "⠐⠐⠔"] # 0x2715 (multiplication X) + - "⟧": [t: "⠨⠾"] # 0x27E7 (right barred bracket) + - "⪥": [t: "⠐⠜⠐⠣"] # 0x2AA5 (greater than sign followed by less than sign) diff --git a/src/braille.rs b/src/braille.rs index 5399d0446..b368be66b 100644 --- a/src/braille.rs +++ b/src/braille.rs @@ -2,7 +2,7 @@ use strum_macros::Display; use sxd_document::dom::{Element, ChildOfElement}; use sxd_document::Package; -use crate::definitions::SPEECH_DEFINITIONS; +use crate::definitions::BRAILLE_DEFINITIONS; use crate::errors::*; use crate::pretty_print::mml_to_string; use crate::prefs::PreferenceManager; @@ -40,6 +40,7 @@ pub fn braille_mathml(mathml: Element, nav_node_id: &str) -> Result<(String, usi "Vietnam" => vietnam_cleanup(pref_manager, braille_string), "CMU" => cmu_cleanup(pref_manager, braille_string), "Finnish" => finnish_cleanup(pref_manager, braille_string), + "French" => french_cleanup(pref_manager, braille_string), "Swedish" => swedish_cleanup(pref_manager, braille_string), "LaTeX" => LaTeX_cleanup(pref_manager, braille_string), "ASCIIMath" => ASCIIMath_cleanup(pref_manager, braille_string), @@ -2046,6 +2047,97 @@ fn swedish_cleanup(pref_manager: Ref, raw_braille: String) -> return result.to_string(); } +static FRENCH_INDICATOR_REPLACEMENTS: phf::Map<&str, &str> = phf_map! { + // FIX: this needs to be fully checked against the French spec + // FIX: this needs cleaning up -- not all of these are used + "S" => "XXX", // sans-serif -- from prefs + "B" => "⠸", // bold + "𝔹" => "XXX", // blackboard -- from prefs + "T" => "⠈", // script + "I" => "⠸", // italic + "R" => "", // roman + "E" => "⠰", // English + "1" => "⠀", // Grade 1 symbol (used for number followed by a letter) + "L" => "", // Letter left in to assist in locating letters + "D" => "XXX", // German (Deutsche) -- from prefs + "G" => "⠘", // Greek + "V" => "XXX", // Greek Variants + // "H" => "⠠⠠", // Hebrew + // "U" => "⠈⠈", // Russian + "C" => "⠨", // capital + "𝑐" => "", // second or latter braille cell of a capital letter + "𝐶" => "⠨", // capital that never should get whitespace in front (from chemical element) + "N" => "", // number indicator + "n" => "", // number indicator for drop numbers (special case with close parens) + "t" => "⠱", // shape terminator + "W" => "⠀", // whitespace" + "𝐖"=> "⠀", // whitespace + "s" => "⠆", // typeface single char indicator + "w" => "", // typeface word indicator + "e" => "", // typeface & capital terminator + "," => "⠂", // comma + "." => "⠲", // period + "-" => "-", // hyphen + "—" => "⠠⠤", // normal dash (2014) -- assume all normal dashes are unified here [RUEB appendix 3] + "―" => "⠐⠠⠤", // long dash (2015) -- assume all long dashes are unified here [RUEB appendix 3] + "(" => "⠦", // Not really needed, but done for consistancy with ")" + ")" => "⠴", // Needed for rules with drop numbers to avoid mistaking for dropped 0 + "↑" => "⠬", // superscript + "↓" => "⠡", // subscript + "#" => "", // signals end of script + "Z" => "⠐", // signals end of index of root, integrand/lim from function ("zone change") + +}; + +fn french_cleanup(pref_manager: Ref, raw_braille: String) -> String { + // FIX: need to implement this -- this is just a copy of the Vietnam code + lazy_static! { + // Empty bases are ok if they follow whitespace + static ref EMPTY_BASE: Regex = Regex::new(r"(^|[W𝐖w])E").unwrap(); + } + debug!("french_cleanup: start={}", raw_braille); + // let result = typeface_to_word_mode(&raw_braille); + // let result = capitals_to_word_mode(&result); + + let result = raw_braille.replace("CG", "⠘") + .replace("𝔹C", "⠩") + .replace("DC", "⠰"); + + debug!(" after typeface/caps={}", &result); + + // these typeforms need to get pulled from user-prefs as they are transcriber-defined + let double_struck = pref_manager.pref_to_string("Vietnam_DoubleStruck"); + let sans_serif = pref_manager.pref_to_string("Vietnam_SansSerif"); + let fraktur = pref_manager.pref_to_string("Vietnam_Fraktur"); + let greek_variant = pref_manager.pref_to_string("Vietnam_GreekVariant"); + + // This reuses the code just for getting rid of unnecessary "L"s and "N"s + let result = remove_unneeded_mode_changes(&result, UEB_Mode::Grade1, UEB_Duration::Passage); + debug!(" after removing mode changes={}", &result); + + + let result = EMPTY_BASE.replace_all(&result, "$1"); + let result = REPLACE_INDICATORS.replace_all(&result, |cap: &Captures| { + let matched_char = &cap[0]; + match matched_char { + "𝔹" => &double_struck, + "S" => &sans_serif, + "D" => &fraktur, + "V" => &greek_variant, + _ => match FRENCH_INDICATOR_REPLACEMENTS.get(matched_char) { + None => {error!("REPLACE_INDICATORS and FRENCH_INDICATOR_REPLACEMENTS are not in sync: missing '{}'", matched_char); ""}, + Some(&ch) => ch, + }, + } + }); + + // Remove unicode blanks at start and end -- do this after the substitutions because ',' introduces spaces + // let result = result.trim_start_matches('⠀').trim_end_matches('⠀'); + let result = COLLAPSE_SPACES.replace_all(&result, "⠀"); + + return result.to_string(); +} + #[allow(non_snake_case)] fn LaTeX_cleanup(_pref_manager: Ref, raw_braille: String) -> String { lazy_static! { @@ -2213,6 +2305,7 @@ impl BrailleChars { "Vietnam" => BrailleChars:: get_braille_vietnam_chars(node, text_range), "Swedish" => BrailleChars:: get_braille_ueb_chars(node, text_range), // FIX: need to figure out what to implement "Finnish" => BrailleChars:: get_braille_ueb_chars(node, text_range), // FIX: need to figure out what to implement + "French" => BrailleChars:: get_braille_ueb_chars(node, text_range), // FIX: need to figure out what to implement _ => return Err(sxd_xpath::function::Error::Other(format!("get_braille_chars: unknown braille code '{}'", code))) }; return match result { @@ -2707,9 +2800,9 @@ impl NeedsToBeGrouped { // '¨', etc., brailles as two chars -- there probably is some exception list but I haven't found it -- these are the ones I know about return !((is_one_char && !['¨', '″', '‴', '⁗'].contains(&first_char)) || // clause 8 // "lim", "cos", etc., appear not to get parens, but the rules don't mention it (tests show it) - IsInDefinition::is_defined_in(text, &SPEECH_DEFINITIONS, "FunctionNames").unwrap() || - IsInDefinition::is_defined_in(text, &SPEECH_DEFINITIONS, "Arrows").unwrap() || // clause 4 - IsInDefinition::is_defined_in(text, &SPEECH_DEFINITIONS, "GeometryShapes").unwrap()); // clause 5 + IsInDefinition::is_defined_in(text, &BRAILLE_DEFINITIONS, "FunctionNames").unwrap() || + IsInDefinition::is_defined_in(text, &BRAILLE_DEFINITIONS, "Arrows").unwrap() || // clause 4 + IsInDefinition::is_defined_in(text, &BRAILLE_DEFINITIONS, "GeometryShapes").unwrap()); // clause 5 }, "mrow" => { // check for bracketed exprs @@ -2751,6 +2844,82 @@ impl NeedsToBeGrouped { } } + + /// FIX: what needs to be implemented? + fn needs_grouping_for_french(mathml: Element, is_base: bool) -> bool { + use crate::xpath_functions::IsInDefinition; + let mut node_name = name(&mathml); + if mathml.attribute_value("data-roman-numeral").is_some() { + node_name = "mi"; // roman numerals don't follow number rules + } + + // FIX: the leaf rules are from UEB -- check the French rules + match node_name { + "mn" => { + if !is_base { + return false; + } // clause 1 + // two 'mn's can be adjacent, in which case we need to group the 'mn' to make it clear it is separate (see bug #204) + let parent = get_parent(mathml); // there is always a "math" node + let grandparent = if name(&parent) == "math" {parent} else {get_parent(parent)}; + if name(&grandparent) != "mrow" { + return false; + } + let preceding = parent.preceding_siblings(); + if preceding.len() < 2 { + return false; + } + // any 'mn' would be separated from this node by invisible times + let previous_child = as_element(preceding[preceding.len()-1]); + if name(&previous_child) == "mo" && as_text(previous_child) == "\u{2062}" { + let previous_child = as_element(preceding[preceding.len()-2]); + return name(&previous_child) == "mn" + } else { + return false; + } + }, + "mo" => { + return !is_base; // if in script, then what follows is assumed to be an operand in braille, but it isn't, so add grouping + }, + "mi" | "mtext" => { + let text = as_text(mathml); + let parent = get_parent(mathml); // there is always a "math" node + let parent_name = name(&parent); + return text.chars().count() > 1 && + parent_name != "mrow" && + !IsInDefinition::is_defined_in(text, &BRAILLE_DEFINITIONS, "FunctionNames").unwrap(); + }, + "mrow" => { + // check for bracketed exprs + if IsBracketed::is_bracketed(mathml, "", "", false, true) { + return false; + } + + // check for prefix at start + // example 7.12 has "2-" in superscript and is grouped, so we don't consider postfix ops + let children = mathml.children(); + if children.len() == 2 && + (name( &as_element(children[0])) == "mo") { + return false; + } + + if children.len() == 3 { + let child0 = as_element(children[0]); + let operator = as_element(children[1]); // invisible function op? + // debug!("needs_grouping_for_french: child0 ="); + if name(&operator) == "mo" && as_text(operator) == "\u{2061}" && + (name(&child0) == "mi" || name(&child0) == "mtext") && + IsInDefinition::is_defined_in(as_text(child0), &BRAILLE_DEFINITIONS, "TrigFunctionNames").unwrap() { + return false; + } + } + return true; + }, + "msub" | "msup" | "msubsup" => return true, + _ => return false, + } + } + // ordinals often have an irregular start (e.g., "half") before becoming regular. // if the number is irregular, return the ordinal form, otherwise return 'None'. fn needs_grouping_for_swedish(mathml: Element, is_base: bool) -> bool { @@ -2775,9 +2944,9 @@ impl NeedsToBeGrouped { // '¨', etc., brailles as two chars -- there probably is some exception list but I haven't found it -- these are the ones I know about return !((is_one_char && !['¨', '″', '‴', '⁗'].contains(&first_char)) || // clause 8 // "lim", "cos", etc., appear not to get parens, but the rules don't mention it (tests show it) - IsInDefinition::is_defined_in(text, &SPEECH_DEFINITIONS, "FunctionNames").unwrap() || - IsInDefinition::is_defined_in(text, &SPEECH_DEFINITIONS, "Arrows").unwrap() || // clause 4 - IsInDefinition::is_defined_in(text, &SPEECH_DEFINITIONS, "GeometryShapes").unwrap()); // clause 5 + IsInDefinition::is_defined_in(text, &BRAILLE_DEFINITIONS, "FunctionNames").unwrap() || + IsInDefinition::is_defined_in(text, &BRAILLE_DEFINITIONS, "Arrows").unwrap() || // clause 4 + IsInDefinition::is_defined_in(text, &BRAILLE_DEFINITIONS, "GeometryShapes").unwrap()); // clause 5 }, "mrow" => { // check for bracketed exprs @@ -2863,9 +3032,9 @@ impl NeedsToBeGrouped { // '¨', etc., brailles as two chars -- there probably is some exception list but I haven't found it -- these are the ones I know about return !((is_one_char && !['¨', '″', '‴', '⁗'].contains(&first_char)) || // clause 8 // "lim", "cos", etc., appear not to get parens, but the rules don't mention it (tests show it) - IsInDefinition::is_defined_in(text, &SPEECH_DEFINITIONS, "FunctionNames").unwrap() || - IsInDefinition::is_defined_in(text, &SPEECH_DEFINITIONS, "Arrows").unwrap() || // clause 4 - IsInDefinition::is_defined_in(text, &SPEECH_DEFINITIONS, "GeometryShapes").unwrap()); // clause 5 + IsInDefinition::is_defined_in(text, &BRAILLE_DEFINITIONS, "FunctionNames").unwrap() || + IsInDefinition::is_defined_in(text, &BRAILLE_DEFINITIONS, "Arrows").unwrap() || // clause 4 + IsInDefinition::is_defined_in(text, &BRAILLE_DEFINITIONS, "GeometryShapes").unwrap()); // clause 5 }, "mfrac" => return false, // clause 2 (test GTM 8.2(4) shows numeric fractions are not special) "msqrt" | "mroot" => return false, // clause 3 @@ -2906,6 +3075,7 @@ impl Function for NeedsToBeGrouped { "CMU" => NeedsToBeGrouped::needs_grouping_for_cmu(e, is_base), "UEB" => NeedsToBeGrouped::needs_grouping_for_ueb(e, is_base), "Finnish" => NeedsToBeGrouped::needs_grouping_for_finnish(e, is_base), + "French" => NeedsToBeGrouped::needs_grouping_for_french(e, is_base), "Swedish" => NeedsToBeGrouped::needs_grouping_for_swedish(e, is_base), _ => return Err(XPathError::Other(format!("NeedsToBeGrouped: braille code arg '{:?}' is not a known code ('UEB', 'CMU', or 'Swedish')", braille_code))), }; diff --git a/tests/braille/French/chemistry.rs b/tests/braille/French/chemistry.rs new file mode 100644 index 000000000..4af951eda --- /dev/null +++ b/tests/braille/French/chemistry.rs @@ -0,0 +1,47 @@ +// French braille tests for the basic mathml tags +// These tests are from the French braille authority's publication "NOTATION PIATHÉMATIQUE BRAILLE" (Première édition janvier 2007) +// https://www.avh.asso.fr/sites/default/files/notation_mathematique_braille2_0.pdf +use crate::common::*; + +#[test] +fn bond_I_4_1() { + let expr= r#"H-H"#; + test_braille("French", expr, "⠨⠓⠤⠨⠓"); +} + +#[test] +fn bond_I_4_2() { + let expr= r#"O=O"#; + test_braille("French", expr, "⠨⠕⠶⠨⠕"); +} + +#[test] +fn ion_II_1_3() { + let expr= r#"SO42-"#; + test_braille("French", expr, "⠨⠎⠨⠕⠢⠹⠈⠰⠣⠤⠆"); +} + +#[test] +fn equilibrium_III_5_1() { + let expr= r#"N2(g)+3H2(g)⇌2NH3(g)"#; + test_braille("French", expr, "⠨⠝⠣⠦⠛⠴⠖⠩⠨⠓⠣⠦⠛⠴⠸⠻⠣⠨⠝⠨⠓⠩⠦⠛⠴"); +} + +#[test] +fn equilibrium_III_5_2() { + let expr= r#"2H2O + ⇌(2)(1)H3O++OH-"#; + test_braille("French", expr, " ⠣⠨⠓⠣⠨⠕⠰⠸⠻⠆⠢⠢⠦⠣⠴⠈⠈⠦⠡⠴⠨⠓⠩⠨⠕⠈⠰⠖⠆⠖⠨⠕⠨⠓⠈⠰⠤⠆"); +} + +#[test] +fn equilibrium_III_5_3() { + let expr= r#"R-CO-O- + H+R'-OH + ⇌hydrolyseestérification + R-CO-O- + R'+ + H2O"#; + test_braille("French", expr, " ⠨⠗⠤⠨⠉⠨⠕⠤⠨⠕⠤⠨⠓⠖⠨⠗⠄⠤⠨⠕⠨⠓ ⠸⠻⠨⠢⠰⠓⠽⠙⠗⠕⠇⠽⠎⠑⠆⠨⠔⠈⠰⠑⠎⠞⠗⠊⠋⠊⠉⠁⠞⠊⠕⠝⠆⠨⠗⠤⠨⠉⠨⠕⠤⠨⠕⠤⠨⠗⠄⠖⠨⠓⠢⠣⠨⠕"); +} diff --git a/tests/braille/French/french.rs b/tests/braille/French/french.rs new file mode 100644 index 000000000..273c28f62 --- /dev/null +++ b/tests/braille/French/french.rs @@ -0,0 +1,138 @@ +// French braille tests for the basic mathml tags +// These tests are from the French braille authority's publication "NOTATION PIATHÉMATIQUE BRAILLE" (Première édition janvier 2007) +// https://www.avh.asso.fr/sites/default/files/notation_mathematique_braille2_0.pdf +use crate::common::*; + +#[test] +fn fraction_7_1() { + let expr= r#"23=46"#; + test_braille("French", expr, "⠣⠌⠩⠶⠹⠌⠫"); +} + +#[test] +fn fraction_8_1() { + let expr= r#"a+ba"#; + test_braille("French", expr, "⠰⠁⠖⠃⠆⠌⠁"); +} + +#[test] +fn superscript_8_4() { + let expr= r#"e7"#; + test_braille("French", expr, "⠑⠈⠻"); +} + +#[test] +fn superscript_8_6() { + let expr= r#"e-π"#; + test_braille("French", expr, "⠑⠈⠤⠘⠏"); +} + +#[test] +fn subscript_9_2_1() { + let expr= r#"ap"#; + test_braille("French", expr, "⠁⠢⠏"); +} + +#[test] +fn subscript_9_2_3() { + let expr= r#"un+1"#; + test_braille("French", expr, "⠥⠢⠰⠝⠖⠡⠆"); +} + +#[test] +fn scripts_9_4_1() { + let expr= r#"a0'"#; + test_braille("French", expr, "⠁⠄⠢⠼"); +} + +#[test] +fn scripts_9_4_3() { + let expr= r#"Cmp= + Cmm-p"#; + test_braille("French", expr, "⠨⠉⠢⠍⠈⠏⠶⠨⠉⠢⠍⠈⠰⠍⠤⠏⠆"); +} + +#[test] +fn scripts_9_5_1() { + let expr= r#"At"#; + test_braille("French", expr, "⠈⠞⠨⠁"); +} + +#[test] +fn chem_9_5_4() { + let expr= r#"O816"#; + test_braille("French", expr, "⠨⠕⠠⠢⠳⠠⠈⠡⠫"); +} + +#[test] +fn root_10_3() { + let expr= r#"(a+b)36= + a+b"#; + test_braille("French", expr, "⠈⠫⠜⠰⠦⠁⠖⠃⠴⠈⠩⠆⠶⠜⠰⠁⠖⠃⠆"); +} + +#[test] +fn accent_12_1() { + let expr= r#"v→"#; + test_braille("French", expr, "⠨⠒⠧"); +} + +#[test] +fn accent_12_2() { + let expr= r#"AB¯"#; + test_braille("French", expr, "⠸⠒⠨⠁⠨⠃"); +} + +#[test] +fn accent_12_3() { + let expr= r#"AB⌒"#; + test_braille("French", expr, "⠈⠒⠨⠁⠨⠃"); +} + +#[test] +fn accent_12_5() { + let expr= r#"(Ox,Oy)^"#; + test_braille("French", expr, "⠘⠒⠦⠨⠕⠭⠂⠨⠕⠽⠴"); +} + +#[test] +fn equations_13_4_1() { + init_logger(); + let expr= r#" + 2x+3y=5 + 3x-7y=8 + "#; + test_braille("French", expr, "⠸⠦⠣⠭⠖⠩⠽⠶⠱⠀⠠⠜⠀⠩⠭⠤⠻⠽⠶⠳"); +} + +#[test] +fn lim_14_3() { + let expr= r#"limx→+∞ + ln(x+2)x=0"#; + test_braille("French", expr, " ⠇⠊⠍⠢⠢⠰⠭⠸⠱⠖⠘⠉⠆⠇⠝⠦⠭⠖⠣⠴⠌⠭⠶⠼"); +} + +#[test] +fn integral_14_4_3() { + let expr= r#"∯Sf(x,y)dxdy"#; + test_braille("French", expr, "⠨⠯⠯⠢⠨⠎⠋⠦⠭⠂⠽⠴⠙⠭⠙⠽"); +} + +#[test] +fn log_14_5_1() { + let expr= r#"lnab"#; + test_braille("French", expr, "⠇⠝⠦⠁⠌⠃⠴"); +} + +#[test] +fn log_14_5_3() { + let expr= r#"log7x= + lnxln7"#; + test_braille("French", expr, "⠇⠕⠛⠢⠻⠰⠭⠆⠶⠇⠝⠰⠭⠆⠌⠇⠝⠰⠻⠆"); +} + +#[test] +fn symbols_15_1() { + let expr= r#"∃x:x∈A"#; + test_braille("French", expr, "⠸⠡⠭⠒⠭⠘⠡⠨⠁"); +} From 7b7570941dd1138648e413c325db48587814501a Mon Sep 17 00:00:00 2001 From: NSoiffer Date: Fri, 27 Sep 2024 15:30:35 -0700 Subject: [PATCH 002/157] Added a table of atomic numbers for the elements and added a test for atomic numbers in prescripts to bump up their liklihood number. This allows single character elements with pre subscripts that match their atomic number to be considered chemistry. --- src/chemistry.rs | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/chemistry.rs b/src/chemistry.rs index 10c99af9b..17244e04e 100644 --- a/src/chemistry.rs +++ b/src/chemistry.rs @@ -376,7 +376,7 @@ pub fn convert_leaves_to_chem_elements(mathml: Element) -> Option> return None; // can't be an chemical letter } let chem_element = unsafe{ str::from_utf8_unchecked(&bytes_str[..n]) }; - if CHEMICAL_ELEMENTS.contains_key( chem_element ) { + if CHEMICAL_ELEMENT_ELECTRONEGATIVITIES.contains_key( chem_element ) { return Some( new_chemical_element(doc, chem_element) ); } @@ -1109,7 +1109,7 @@ fn likely_chem_formula(mathml: Element) -> isize { fn is_order_ok(mrow: Element) -> bool { assert_eq!(name(&mrow), "mrow"); if let Some(elements) = collect_elements(mrow) { - if elements.iter().any(|&e| !CHEMICAL_ELEMENTS.contains_key(e)) { + if elements.iter().any(|&e| !CHEMICAL_ELEMENT_ELECTRONEGATIVITIES.contains_key(e)) { return false; } let n_elements = elements.len(); @@ -1207,7 +1207,7 @@ fn is_ordered_by_electronegativity(elements: &[&str]) -> bool { // HPO_4^2 (Monohydrogen phosphate) doesn't fit this pattern, nor does HCO_3^- (Hydrogen carbonate) and some others // FIX: drop "H" from the ordering?? assert!(!elements.len() > 1); // already handled - return elements.windows(2).all(|pair| CHEMICAL_ELEMENTS.get(pair[0]).unwrap() < CHEMICAL_ELEMENTS.get(pair[1]).unwrap()); + return elements.windows(2).all(|pair| CHEMICAL_ELEMENT_ELECTRONEGATIVITIES.get(pair[0]).unwrap() < CHEMICAL_ELEMENT_ELECTRONEGATIVITIES.get(pair[1]).unwrap()); } fn is_generalized_salt(elements: &[&str]) -> bool { @@ -1300,7 +1300,16 @@ pub fn likely_adorned_chem_formula(mathml: Element) -> isize { // fix could make sure they are integers likelihood += 1; // looking like an atomic number if pre_subscript_name == "mn" { - likelihood += 1; // looking even more like an atomic number + // make sure the atomic number matches the base + let base = as_element(children[0]); + let base_name = name(&base); + if base_name == "mi" || base_name == "mtext" { + if let Some(atomic_number) = CHEMICAL_ELEMENT_ATOMIC_NUMBER.get(as_text(base)) { + if as_text(pre_subscript) == &atomic_number.to_string() { + likelihood = CHEMISTRY_THRESHOLD; + } + } + } } } else { return NOT_CHEMISTRY; @@ -1696,7 +1705,7 @@ fn convert_to_short_form(mathml: Element) -> Result { /// That list uses a horizontal line for the Lanthanide and Actinide Series. /// Because I had already ordered the elements before realizing that, I opened a gap and started the higher ones again with a '1' in front. /// The list is missing recent (unstable) elements -- I added them with the same value as the element above them in the periodic table. -static CHEMICAL_ELEMENTS: phf::Map<&str, u32> = phf_map! { +static CHEMICAL_ELEMENT_ELECTRONEGATIVITIES: phf::Map<&str, u32> = phf_map! { "Ac" => 40, "Ag" => 155, "Al" => 163, "Am" => 29, "Ar" => 4, "As" => 172, "At" => 181, "Au" => 154, "B" => 164, "Ba" => 14, "Be" => 18, "Bh" => 137, "Bi" => 170, "Bk" => 27, "Br" => 183, "C" => 169, "Ca" => 16, "Cd" => 158, "Ce" => 56, "Cf" => 26, "Cl" => 184, "Cm" => 28, "Cn" => 157, "Co" => 148, "Cr" => 136, "Cs" => 8, "Cu" => 156, @@ -1716,6 +1725,23 @@ static CHEMICAL_ELEMENTS: phf::Map<&str, u32> = phf_map! { "Me" => 0, "Et" => 0, "R" => 0, /* "Ac" => 0, */ "Ph" => 0, "X" => 0, /* treated as an unknown */ }; + +// A map of the chemical elements and their atomic numbers +static CHEMICAL_ELEMENT_ATOMIC_NUMBER: phf::Map<&str, u32> = phf_map! { + "H" => 1, "He" => 2, "Li" => 3, "Be" => 4, "B" => 5, "C" => 6, "N" => 7, "O" => 8, "F" => 9, "Ne" => 10, + "Na" => 11, "Mg" => 12, "Al" => 13, "Si" => 14, "P" => 15, "S" => 16, "Cl" => 17, "Ar" => 18, "K" => 19, "Ca" => 20, + "Sc" => 21, "Ti" => 22, "V" => 23, "Cr" => 24, "Mn" => 25, "Fe" => 26, "Co" => 27, "Ni" => 28, "Cu" => 29, "Zn" => 30, + "Ga" => 31, "Ge" => 32, "As" => 33, "Se" => 34, "Br" => 35, "Kr" => 36, "Rb" => 37, "Sr" => 38, "Y" => 39, "Zr" => 40, + "Nb" => 41, "Mo" => 42, "Tc" => 43, "Ru" => 44, "Rh" => 45, "Pd" => 46, "Ag" => 47, "Cd" => 48, "In" => 49, "Sn" => 50, + "Sb" => 51, "Te" => 52, "I" => 53, "Xe" => 54, "Cs" => 55, "Ba" => 56, "La" => 57, "Ce" => 58, "Pr" => 59, "Nd" => 60, + "Pm" => 61, "Sm" => 62, "Eu" => 63, "Gd" => 64, "Tb" => 65, "Dy" => 66, "Ho" => 67, "Er" => 68, "Tm" => 69, "Yb" => 70, + "Lu" => 71, "Hf" => 72, "Ta" => 73, "W" => 74, "Re" => 75, "Os" => 76, "Ir" => 77, "Pt" => 78, "Au" => 79, "Hg" => 80, + "Tl" => 81, "Pb" => 82, "Bi" => 83, "Po" => 84, "At" => 85, "Rn" => 86, "Fr" => 87, "Ra" => 88, "Ac" => 89, "Th" => 90, + "Pa" => 91, "U" => 92, "Np" => 93, "Pu" => 94, "Am" => 95, "Cm" => 96, "Bk" => 97, "Cf" => 98, "Es" => 99, "Fm" => 100, + "Md" => 101, "No" => 102, "Lr" => 103, "Rf" => 104, "Db" => 105, "Sg" => 106, "Bh" => 107, "Hs" => 108, "Mt" => 109, "Ds" => 110, + "Rg" => 111, "Cn" => 112, "Nh" => 113, "Fl" => 114, "Mc" => 115, "Lv" => 116, "Ts" => 117, "Og" => 118, +}; + pub fn is_chemical_element(node: Element) -> bool { // FIX: allow name to be in an mrow (e.g., Na let name = name(&node); @@ -1724,7 +1750,7 @@ pub fn is_chemical_element(node: Element) -> bool { } let text = as_text(node); - return CHEMICAL_ELEMENTS.contains_key(text); + return CHEMICAL_ELEMENT_ELECTRONEGATIVITIES.contains_key(text); } From 5136cb34d86715d6f2bf2f4611f94a7eb28a8506 Mon Sep 17 00:00:00 2001 From: NSoiffer Date: Fri, 27 Sep 2024 15:47:02 -0700 Subject: [PATCH 003/157] renamed test --- tests/braille/French/french.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/braille/French/french.rs b/tests/braille/French/french.rs index 273c28f62..b2f873952 100644 --- a/tests/braille/French/french.rs +++ b/tests/braille/French/french.rs @@ -106,7 +106,7 @@ fn equations_13_4_1() { } #[test] -fn lim_14_3() { +fn lim_14_2_3() { let expr= r#"limx→+∞ ln(x+2)x=0"#; test_braille("French", expr, " ⠇⠊⠍⠢⠢⠰⠭⠸⠱⠖⠘⠉⠆⠇⠝⠦⠭⠖⠣⠴⠌⠭⠶⠼"); From 4ccda5f59813e110ef799b3440760567c185e2ec Mon Sep 17 00:00:00 2001 From: NSoiffer Date: Thu, 29 May 2025 21:36:04 -0700 Subject: [PATCH 004/157] Update braille.rs to compile after merging. Add French to the braille testing file. New French braille tests. --- src/braille.rs | 18 +- tests/braille.rs | 4 + tests/braille/French/french.rs | 443 +++++++++++++++++++++++++++++---- 3 files changed, 405 insertions(+), 60 deletions(-) diff --git a/src/braille.rs b/src/braille.rs index dddc77f6f..3f3dca9b1 100644 --- a/src/braille.rs +++ b/src/braille.rs @@ -2933,7 +2933,7 @@ impl NeedsToBeGrouped { /// FIX: what needs to be implemented? fn needs_grouping_for_french(mathml: Element, is_base: bool) -> bool { use crate::xpath_functions::IsInDefinition; - let mut node_name = name(&mathml); + let mut node_name = name(mathml); if mathml.attribute_value("data-roman-numeral").is_some() { node_name = "mi"; // roman numerals don't follow number rules } @@ -2946,8 +2946,8 @@ impl NeedsToBeGrouped { } // clause 1 // two 'mn's can be adjacent, in which case we need to group the 'mn' to make it clear it is separate (see bug #204) let parent = get_parent(mathml); // there is always a "math" node - let grandparent = if name(&parent) == "math" {parent} else {get_parent(parent)}; - if name(&grandparent) != "mrow" { + let grandparent = if name(parent) == "math" {parent} else {get_parent(parent)}; + if name(grandparent) != "mrow" { return false; } let preceding = parent.preceding_siblings(); @@ -2956,9 +2956,9 @@ impl NeedsToBeGrouped { } // any 'mn' would be separated from this node by invisible times let previous_child = as_element(preceding[preceding.len()-1]); - if name(&previous_child) == "mo" && as_text(previous_child) == "\u{2062}" { + if name(previous_child) == "mo" && as_text(previous_child) == "\u{2062}" { let previous_child = as_element(preceding[preceding.len()-2]); - return name(&previous_child) == "mn" + return name(previous_child) == "mn" } else { return false; } @@ -2969,7 +2969,7 @@ impl NeedsToBeGrouped { "mi" | "mtext" => { let text = as_text(mathml); let parent = get_parent(mathml); // there is always a "math" node - let parent_name = name(&parent); + let parent_name = name(parent); return text.chars().count() > 1 && parent_name != "mrow" && !IsInDefinition::is_defined_in(text, &BRAILLE_DEFINITIONS, "FunctionNames").unwrap(); @@ -2984,7 +2984,7 @@ impl NeedsToBeGrouped { // example 7.12 has "2-" in superscript and is grouped, so we don't consider postfix ops let children = mathml.children(); if children.len() == 2 && - (name( &as_element(children[0])) == "mo") { + (name( as_element(children[0])) == "mo") { return false; } @@ -2992,8 +2992,8 @@ impl NeedsToBeGrouped { let child0 = as_element(children[0]); let operator = as_element(children[1]); // invisible function op? // debug!("needs_grouping_for_french: child0 ="); - if name(&operator) == "mo" && as_text(operator) == "\u{2061}" && - (name(&child0) == "mi" || name(&child0) == "mtext") && + if name(operator) == "mo" && as_text(operator) == "\u{2061}" && + (name(child0) == "mi" || name(child0) == "mtext") && IsInDefinition::is_defined_in(as_text(child0), &BRAILLE_DEFINITIONS, "TrigFunctionNames").unwrap() { return false; } diff --git a/tests/braille.rs b/tests/braille.rs index d2406f23b..50331fdbe 100644 --- a/tests/braille.rs +++ b/tests/braille.rs @@ -33,5 +33,9 @@ mod braille { mod augenbit; mod other; } + + mod French { + mod french; + } } diff --git a/tests/braille/French/french.rs b/tests/braille/French/french.rs index b2f873952..46756ae44 100644 --- a/tests/braille/French/french.rs +++ b/tests/braille/French/french.rs @@ -4,135 +4,476 @@ use crate::common::*; #[test] -fn fraction_7_1() { - let expr= r#"23=46"#; +fn test_6_4_01() { + let expr= r#"E={a,b,c,d}"#; + test_braille("French", expr, "⠨⠑⠶⠨⠦⠁⠂⠃⠂⠉⠂⠙⠨⠴"); +} + +#[test] +fn test_6_4_02() { + let expr= r#"ℝ*=]−∞,0[∪]0,+∞["#; + test_braille("French", expr, "⠨⠨⠗⠈⠐⠔⠶⠾⠤⠘⠉⠂⠼⠷⠸⠖⠾⠼⠂⠖⠘⠉⠷"); +} + +#[test] +fn test_6_4_03() { + let expr= r#"x∈[0,1;2,3]"#; + test_braille("French", expr, "⠭⠘⠡⠷⠼⠂⠡⠆⠣⠂⠩⠾"); +} + +#[test] +fn test_6_4_04() { + let expr= r#"x∉ℝ+"#; + test_braille("French", expr, "⠭⠘⠌⠨⠨⠗⠈⠖"); +} + +#[test] +fn test_6_4_05() { + let expr= r#"D⊂F"#; + test_braille("French", expr, "⠨⠙⠨⠡⠨⠋"); +} + +#[test] +fn test_6_4_06() { + let expr= r#"D⊄E"#; + test_braille("French", expr, "⠨⠙⠨⠌⠨⠑"); +} + +#[test] +fn test_6_4_07() { + let expr= r#"A⊆B"#; + test_braille("French", expr, "⠨⠁⠸⠨⠡⠨⠃"); +} + +#[test] +fn test_6_4_08() { + let expr= r#"A∩B=⌀"#; + test_braille("French", expr, "⠨⠁⠘⠖⠨⠃⠶⠘⠼"); +} + +#[test] +fn test_6_4_09() { + let expr= r#"∁EF"#; + test_braille("French", expr, "⠨⠩⠢⠨⠑⠨⠋"); +} + +#[test] +fn test_7_01() { + let expr= r#"23=46"#; test_braille("French", expr, "⠣⠌⠩⠶⠹⠌⠫"); } #[test] -fn fraction_8_1() { +fn test_7_02() { + let expr= r#"1÷2=0,5"#; + test_braille("French", expr, "⠡⠒⠣⠶⠼⠂⠱"); +} + +#[test] +fn test_8_01() { let expr= r#"a+ba"#; - test_braille("French", expr, "⠰⠁⠖⠃⠆⠌⠁"); + test_braille("French", expr, "⠠⠄⠰⠁⠖⠃⠆⠌⠁"); +} + +#[test] +fn test_8_02() { + let expr= r#"a+bc+d"#; + test_braille("French", expr, "⠠⠄⠰⠁⠖⠃⠆⠌⠰⠉⠖⠙⠆"); } #[test] -fn superscript_8_4() { +fn test_8_03() { + let expr= r#"ab+cd=ad+bcbd"#; + test_braille("French", expr, "⠠⠄⠁⠌⠃⠖⠉⠌⠙⠶⠰⠁⠙⠖⠃⠉⠆⠌⠃⠙"); +} + +#[test] +fn test_8_04() { + let expr= r#"CardE=5"#; + test_braille("French", expr, "⠠⠄⠨⠉⠁⠗⠙⠰⠨⠑⠆⠶⠱"); +} + +#[test] +fn test_8_05() { + let expr= r#"ex+3"#; + test_braille("French", expr, "⠠⠄⠑⠈⠰⠭⠖⠩⠆"); +} + +#[test] +fn test_8_06() { let expr= r#"e7"#; - test_braille("French", expr, "⠑⠈⠻"); + test_braille("French", expr, "⠠⠑⠈⠻"); +} + +#[test] +fn test_8_07() { + let expr= r#"e−x"#; + test_braille("French", expr, "⠠⠑⠈⠤⠭"); +} + +#[test] +fn test_8_08() { + let expr= r#"e−π"#; + test_braille("French", expr, "⠠⠑⠈⠤⠘⠏"); +} + +#[test] +fn test_8_09() { + let expr= r#"x−1=1x"#; + test_braille("French", expr, "⠠⠭⠈⠤⠡⠶⠡⠌⠭"); +} + +#[test] +fn test_9_1_01() { + let expr= r#"a′"#; + test_braille("French", expr, "⠁⠄"); +} + +#[test] +fn test_9_1_02() { + let expr= r#"x″"#; + test_braille("French", expr, "⠭⠄⠄"); } #[test] -fn superscript_8_6() { - let expr= r#"e-π"#; - test_braille("French", expr, "⠑⠈⠤⠘⠏"); +fn test_9_1_03() { + let expr= r#"a′x+a″y+a‴z"#; + test_braille("French", expr, "⠁⠄⠭⠖⠁⠄⠄⠽⠖⠁⠄⠄⠄⠵"); } #[test] -fn subscript_9_2_1() { +fn test_9_2_01() { let expr= r#"ap"#; test_braille("French", expr, "⠁⠢⠏"); } #[test] -fn subscript_9_2_3() { +fn test_9_2_02() { + let expr= r#"x0"#; + test_braille("French", expr, "⠭⠢⠼"); +} + +#[test] +fn test_9_2_03() { let expr= r#"un+1"#; test_braille("French", expr, "⠥⠢⠰⠝⠖⠡⠆"); } #[test] -fn scripts_9_4_1() { - let expr= r#"a0'"#; +fn test_9_3_01() { + let expr= r#"x2"#; + test_braille("French", expr, "⠭⠈⠣"); +} + +#[test] +fn test_9_3_02() { + let expr= r#"xp+q"#; + test_braille("French", expr, "⠭⠈⠰⠏⠖⠟⠆"); +} + +#[test] +fn test_9_3_03() { + let expr= r#"a−5,3"#; + test_braille("French", expr, "⠁⠈⠤⠱⠂⠩"); +} + +#[test] +fn test_9_3_04() { + let expr= r#"aπ"#; + test_braille("French", expr, "⠁⠈⠘⠏"); +} + +#[test] +fn test_9_3_05() { + let expr= r#"523≠523"#; + test_braille("French", expr, "⠱⠈⠣⠜⠩⠨⠶⠱⠈⠰⠣⠜⠩⠆"); +} + +#[test] +fn test_9_3_06() { + let expr= r#"e−5x≠e−5x"#; + test_braille("French", expr, "⠑⠈⠰⠤⠱⠭⠆⠨⠶⠰⠑⠈⠤⠱⠆⠭"); +} + +#[test] +fn test_9_4_01() { + let expr= r#"a′0"#; test_braille("French", expr, "⠁⠄⠢⠼"); } #[test] -fn scripts_9_4_3() { - let expr= r#"Cmp= - Cmm-p"#; +fn test_9_4_02() { + let expr= r#"x0′2"#; + test_braille("French", expr, "⠭⠄⠢⠼⠈⠣"); +} + +#[test] +fn test_9_4_03() { + let expr= r#"∁mp=∁mm−p"#; test_braille("French", expr, "⠨⠉⠢⠍⠈⠏⠶⠨⠉⠢⠍⠈⠰⠍⠤⠏⠆"); } #[test] -fn scripts_9_5_1() { - let expr= r#"At"#; +fn test_9_4_04() { + let expr= r#"am+n′p+q"#; + test_braille("French", expr, "⠁⠄⠄⠢⠰⠍⠖⠝⠆⠈⠰⠏⠖⠟⠆"); +} + +#[test] +fn test_9_4_05() { + let expr= r#"ℝ+*"#; + test_braille("French", expr, "⠨⠨⠗⠢⠖⠈⠐⠔"); +} + +#[test] +fn test_9_5_01() { + let expr= r#"tA"#; test_braille("French", expr, "⠈⠞⠨⠁"); } #[test] -fn chem_9_5_4() { - let expr= r#"O816"#; +fn test_9_5_02() { + let expr= r#"2w"#; + test_braille("French", expr, "⠢⠣⠺"); +} + +#[test] +fn test_9_5_03() { + let expr= r#"tAtB"#; + test_braille("French", expr, "⠰⠈⠞⠨⠁⠆⠰⠈⠞⠨⠃⠆"); +} + +#[test] +fn test_9_5_04() { + let expr= r#"816O"#; test_braille("French", expr, "⠨⠕⠠⠢⠳⠠⠈⠡⠫"); } #[test] -fn root_10_3() { - let expr= r#"(a+b)36= - a+b"#; +fn test_10_01() { + let expr= r#"2"#; + test_braille("French", expr, "⠜⠣"); +} + +#[test] +fn test_10_02() { + let expr= r#"a4"#; + test_braille("French", expr, "⠈⠹⠜⠁"); +} + +#[test] +fn test_10_03() { + let expr= r#"(a+b)36=a+b"#; test_braille("French", expr, "⠈⠫⠜⠰⠦⠁⠖⠃⠴⠈⠩⠆⠶⠜⠰⠁⠖⠃⠆"); } #[test] -fn accent_12_1() { - let expr= r#"v→"#; +fn test_10_04() { + let expr= r#"a+a+b3"#; + test_braille("French", expr, "⠈⠩⠜⠰⠁⠖⠜⠰⠁⠖⠃⠆⠆"); +} + +#[test] +fn test_10_05() { + let expr= r#"a4b3"#; + test_braille("French", expr, "⠰⠈⠹⠜⠁⠆⠰⠈⠩⠜⠃⠆"); +} + +#[test] +fn test_11_01() { + let expr= r#"f:ℝ→ℝ,x↦y=1x"#; + test_braille("French", expr, "⠒⠨⠨⠗⠸⠱⠨⠨⠗⠭⠐⠱⠽⠶⠡⠌⠭"); +} + +#[test] +fn test_12_1_01() { + let expr= r#"v→"#; test_braille("French", expr, "⠨⠒⠧"); } #[test] -fn accent_12_2() { - let expr= r#"AB¯"#; +fn test_12_1_02() { + let expr= r#"AB¯"#; test_braille("French", expr, "⠸⠒⠨⠁⠨⠃"); } #[test] -fn accent_12_3() { - let expr= r#"AB⌒"#; +fn test_12_1_03() { + let expr= r#"AB⏜"#; test_braille("French", expr, "⠈⠒⠨⠁⠨⠃"); } #[test] -fn accent_12_5() { - let expr= r#"(Ox,Oy)^"#; +fn test_12_1_04() { + let expr= r#"AOB̂"#; + test_braille("French", expr, "⠘⠒⠨⠁⠨⠕⠨⠃"); +} + +#[test] +fn test_12_1_05() { + let expr= r#"(Ox,Oy)̂"#; test_braille("French", expr, "⠘⠒⠦⠨⠕⠭⠂⠨⠕⠽⠴"); } #[test] -fn equations_13_4_1() { - init_logger(); - let expr= r#" - 2x+3y=5 - 3x-7y=8 - "#; - test_braille("French", expr, "⠸⠦⠣⠭⠖⠩⠽⠶⠱⠀⠠⠜⠀⠩⠭⠤⠻⠽⠶⠳"); +fn test_12_1_06() { + let expr= r#"(OA→,OM→)̂"#; + test_braille("French", expr, "⠘⠒⠦⠨⠒⠨⠕⠨⠁⠂⠨⠒⠨⠕⠨⠍⠴"); +} + +#[test] +fn test_12_3_01() { + let expr= r#"(D)⫽(Δ)"#; + test_braille("French", expr, "⠦⠨⠙⠴⠸⠳⠦⠨⠘⠙⠴"); +} + +#[test] +fn test_12_3_02() { + let expr= r#"(AB)⊥(A′B′)"#; + test_braille("French", expr, "⠦⠨⠁⠨⠃⠴⠘⠳⠦⠨⠁⠄⠨⠃⠄⠴"); +} + +#[test] +fn test_13_2_01() { + let expr= r#"|x0|"#; + test_braille("French", expr, "⠿⠭⠢⠼⠿"); +} + +#[test] +fn test_13_2_02() { + let expr= r#"|a+ib|"#; + test_braille("French", expr, "⠿⠁⠖⠊⠃⠿"); +} + +#[test] +fn test_13_2_03() { + let expr= r#"∥ku→∥=|k|∥u→∥"#; + test_braille("French", expr, "⠘⠿⠅⠨⠒⠥⠘⠿⠶⠿⠅⠿⠘⠿⠨⠒⠥⠘⠿"); +} + +#[test] +fn test_13_2_04() { + let expr= r#"f|E"#; + test_braille("French", expr, "⠋⠿⠨⠑"); +} + +#[test] +fn test_14_1_01() { + let expr= r#"f(x)"#; + test_braille("French", expr, "⠋⠦⠭⠴"); } #[test] -fn lim_14_2_3() { - let expr= r#"limx→+∞ - ln(x+2)x=0"#; - test_braille("French", expr, " ⠇⠊⠍⠢⠢⠰⠭⠸⠱⠖⠘⠉⠆⠇⠝⠦⠭⠖⠣⠴⠌⠭⠶⠼"); +fn test_14_1_02() { + let expr= r#"g′(x)=3x+4"#; + test_braille("French", expr, "⠛⠄⠦⠭⠴⠶⠩⠭⠖⠹"); } #[test] -fn integral_14_4_3() { - let expr= r#"∯Sf(x,y)dxdy"#; +fn test_14_1_03() { + let expr= r#"f∘g(x)=f[g(x)]"#; + test_braille("French", expr, "⠋⠸⠼⠛⠦⠭⠴⠶⠋⠷⠛⠦⠭⠴⠾"); +} + +#[test] +fn test_14_1_04() { + let expr= r#"∂f(x,y)∂x=5xy−7x"#; + test_braille("French", expr, "⠐⠙⠋⠦⠭⠂⠽⠴⠌⠐⠙⠭⠶⠱⠭⠽⠤⠻⠭"); +} + +#[test] +fn test_14_2_01_corrected() { + let expr= r#"limx→+∞f(x)=0"#; + test_braille("French", expr, "⠇⠊⠍⠢⠢⠰⠭⠸⠱⠖⠘⠉⠆⠋⠦⠭⠴⠶⠼"); +} + +#[test] +fn test_14_2_02_corrected_1() { + let expr= r#"limx→4x>4f(x)=−∞"#; + test_braille("French", expr, "⠇⠊⠍⠢⠢⠰⠭⠸⠱⠹⠂⠭⠐⠜⠹⠆⠋⠦⠭⠴⠶⠤⠘⠉"); +} + +#[test] +fn test_14_2_02_corrected_2() { + let expr= r#"limx→4x>4f(x)=−∞"#; + test_braille("French", expr, "⠇⠊⠍⠢⠢⠰⠭⠸⠱⠹⠂⠭⠐⠜⠹⠆⠋⠦⠭⠴⠶⠤⠘⠉"); +} + +#[test] +fn test_14_2_03_corrected() { + let expr= r#"limx→+∞ln⁡(x+2)x=0"#; + test_braille("French", expr, "⠇⠊⠍⠢⠢⠰⠭⠸⠱⠖⠘⠉⠆⠰⠇⠝⠦⠭⠖⠣⠴⠌⠭⠆⠶⠼"); +} + +#[test] +fn test_14_4_01() { + let expr= r#"∫abf(x)dx"#; + test_braille("French", expr, "⠯⠢⠁⠈⠃⠋⠦⠭⠴⠙⠭"); +} + +#[test] +fn test_14_4_03() { + let expr= r#"∫125xdx"#; + test_braille("French", expr, "⠯⠢⠡⠈⠣⠰⠱⠭⠆⠙⠭"); +} + +#[test] +fn test_14_4_04() { + let expr= r#"∫(c)f(x)dx"#; + test_braille("French", expr, "⠯⠢⠦⠨⠉⠴⠋⠦⠭⠴⠙⠭"); +} + +#[test] +fn test_14_4_05() { + let expr= r#"∯Sf(x,y)dxdy"#; test_braille("French", expr, "⠨⠯⠯⠢⠨⠎⠋⠦⠭⠂⠽⠴⠙⠭⠙⠽"); } #[test] -fn log_14_5_1() { - let expr= r#"lnab"#; +fn test_14_5_01() { + let expr= r#"ln⁡(ab)"#; test_braille("French", expr, "⠇⠝⠦⠁⠌⠃⠴"); } #[test] -fn log_14_5_3() { - let expr= r#"log7x= - lnxln7"#; +fn test_14_5_02() { + let expr= r#"ln⁡xy=ln⁡x+ln⁡y"#; + test_braille("French", expr, "⠇⠝⠰⠭⠽⠆⠶⠇⠝⠰⠭⠆⠖⠇⠝⠰⠽⠆"); +} + +#[test] +fn test_14_5_03() { + let expr= r#"log7x=ln⁡xln⁡7"#; test_braille("French", expr, "⠇⠕⠛⠢⠻⠰⠭⠆⠶⠇⠝⠰⠭⠆⠌⠇⠝⠰⠻⠆"); } #[test] -fn symbols_15_1() { - let expr= r#"∃x:x∈A"#; +fn test_14_6_01() { + let expr= r#"cos⁡(a+b)=cosacosb−sinasinb"#; + test_braille("French", expr, "⠉⠕⠎⠦⠁⠖⠃⠴⠶⠉⠕⠎⠰⠁⠆⠉⠕⠎⠰⠃⠆⠐⠤⠎⠊⠝⠰⠁⠆⠎⠊⠝⠰⠃⠆"); +} + +#[test] +fn test_14_6_01b() { + let expr= r#"cos⁡(a+b)=cosacosb−sinasinb"#; + test_braille("French", expr, "⠨⠬⠦⠁⠖⠃⠴⠶⠨⠬⠁⠨⠬⠃⠤⠬⠁⠬⠃"); +} + +#[test] +fn test_14_7_01() { + let expr= r#"cos⁡h2x−sin⁡h2x=1"#; + test_braille("French", expr, "⠉⠓⠈⠣⠰⠭⠆⠤⠎⠓⠈⠣⠰⠭⠆⠶⠡"); +} + +#[test] +fn test_15_01() { + let expr= r#"∃x:x∈A"#; test_braille("French", expr, "⠸⠡⠭⠒⠭⠘⠡⠨⠁"); } + +#[test] +fn test_16_4_07() { + let expr= r#"(p+q)ième"#; + test_braille("French", expr, "⠦⠏⠖⠟⠴⠈⠊⠮⠍"); +} + From c7eda2c2ba66bcf9509a5231c418a48627c1acc3 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Fri, 5 Jun 2026 23:49:06 -0700 Subject: [PATCH 005/157] Updated to main. Needed to update the format of the tests to match the others. --- src/braille.rs | 8 +- tests/braille/French/chemistry.rs | 31 +- tests/braille/French/french.rs | 481 ++++++++++++++++++------------ 3 files changed, 311 insertions(+), 209 deletions(-) diff --git a/src/braille.rs b/src/braille.rs index d42a3a976..348deb7b0 100644 --- a/src/braille.rs +++ b/src/braille.rs @@ -2212,10 +2212,8 @@ static FRENCH_INDICATOR_REPLACEMENTS: phf::Map<&str, &str> = phf_map! { fn french_cleanup(pref_manager: Ref, raw_braille: String) -> String { // FIX: need to implement this -- this is just a copy of the Vietnam code - lazy_static! { - // Empty bases are ok if they follow whitespace - static ref EMPTY_BASE: Regex = Regex::new(r"(^|[W𝐖w])E").unwrap(); - } + // Empty bases are ok if they follow whitespace + static EMPTY_BASE: LazyLock = LazyLock::new(|| Regex::new(r"(^|[W𝐖w])E").unwrap()); debug!("french_cleanup: start={}", raw_braille); // let result = typeface_to_word_mode(&raw_braille); // let result = capitals_to_word_mode(&result); @@ -2238,7 +2236,7 @@ fn french_cleanup(pref_manager: Ref, raw_braille: String) -> let result = EMPTY_BASE.replace_all(&result, "$1"); - let result = REPLACE_INDICATORS.replace_all(&result, |cap: &Captures| { + let result: Cow<'_, str> = REPLACE_INDICATORS.replace_all(&result, |cap: &Captures| { let matched_char = &cap[0]; match matched_char { "𝔹" => &double_struck, diff --git a/tests/braille/French/chemistry.rs b/tests/braille/French/chemistry.rs index 4af951eda..b5d4606a4 100644 --- a/tests/braille/French/chemistry.rs +++ b/tests/braille/French/chemistry.rs @@ -2,46 +2,53 @@ // These tests are from the French braille authority's publication "NOTATION PIATHÉMATIQUE BRAILLE" (Première édition janvier 2007) // https://www.avh.asso.fr/sites/default/files/notation_mathematique_braille2_0.pdf use crate::common::*; +use anyhow::Result; #[test] -fn bond_I_4_1() { +fn bond_I_4_1() -> Result<()> { let expr= r#"H-H"#; - test_braille("French", expr, "⠨⠓⠤⠨⠓"); + test_braille("French", expr, "⠨⠓⠤⠨⠓")?; + return Ok(()); } #[test] -fn bond_I_4_2() { +fn bond_I_4_2() -> Result<()> { let expr= r#"O=O"#; - test_braille("French", expr, "⠨⠕⠶⠨⠕"); + test_braille("French", expr, "⠨⠕⠶⠨⠕")?; + return Ok(()); } #[test] -fn ion_II_1_3() { +fn ion_II_1_3() -> Result<()> { let expr= r#"SO42-"#; - test_braille("French", expr, "⠨⠎⠨⠕⠢⠹⠈⠰⠣⠤⠆"); + test_braille("French", expr, "⠨⠎⠨⠕⠢⠹⠈⠰⠣⠤⠆")?; + return Ok(()); } #[test] -fn equilibrium_III_5_1() { +fn equilibrium_III_5_1() -> Result<()> { let expr= r#"N2(g)+3H2(g)⇌2NH3(g)"#; - test_braille("French", expr, "⠨⠝⠣⠦⠛⠴⠖⠩⠨⠓⠣⠦⠛⠴⠸⠻⠣⠨⠝⠨⠓⠩⠦⠛⠴"); + test_braille("French", expr, "⠨⠝⠣⠦⠛⠴⠖⠩⠨⠓⠣⠦⠛⠴⠸⠻⠣⠨⠝⠨⠓⠩⠦⠛⠴")?; + return Ok(()); } #[test] -fn equilibrium_III_5_2() { +fn equilibrium_III_5_2() -> Result<()> { let expr= r#"2H2O ⇌(2)(1)H3O++OH-"#; - test_braille("French", expr, " ⠣⠨⠓⠣⠨⠕⠰⠸⠻⠆⠢⠢⠦⠣⠴⠈⠈⠦⠡⠴⠨⠓⠩⠨⠕⠈⠰⠖⠆⠖⠨⠕⠨⠓⠈⠰⠤⠆"); + test_braille("French", expr, " ⠣⠨⠓⠣⠨⠕⠰⠸⠻⠆⠢⠢⠦⠣⠴⠈⠈⠦⠡⠴⠨⠓⠩⠨⠕⠈⠰⠖⠆⠖⠨⠕⠨⠓⠈⠰⠤⠆")?; + return Ok(()); } #[test] -fn equilibrium_III_5_3() { +fn equilibrium_III_5_3() -> Result<()> { let expr= r#"R-CO-O- H+R'-OH ⇌hydrolyseestérification R-CO-O- R'+ H2O"#; - test_braille("French", expr, " ⠨⠗⠤⠨⠉⠨⠕⠤⠨⠕⠤⠨⠓⠖⠨⠗⠄⠤⠨⠕⠨⠓ ⠸⠻⠨⠢⠰⠓⠽⠙⠗⠕⠇⠽⠎⠑⠆⠨⠔⠈⠰⠑⠎⠞⠗⠊⠋⠊⠉⠁⠞⠊⠕⠝⠆⠨⠗⠤⠨⠉⠨⠕⠤⠨⠕⠤⠨⠗⠄⠖⠨⠓⠢⠣⠨⠕"); + test_braille("French", expr, " ⠨⠗⠤⠨⠉⠨⠕⠤⠨⠕⠤⠨⠓⠖⠨⠗⠄⠤⠨⠕⠨⠓ ⠸⠻⠨⠢⠰⠓⠽⠙⠗⠕⠇⠽⠎⠑⠆⠨⠔⠈⠰⠑⠎⠞⠗⠊⠋⠊⠉⠁⠞⠊⠕⠝⠆⠨⠗⠤⠨⠉⠨⠕⠤⠨⠕⠤⠨⠗⠄⠖⠨⠓⠢⠣⠨⠕")?; + return Ok(()); } diff --git a/tests/braille/French/french.rs b/tests/braille/French/french.rs index 0e6fb55be..0acd5bf56 100644 --- a/tests/braille/French/french.rs +++ b/tests/braille/French/french.rs @@ -4,587 +4,684 @@ // https://www.avh.asso.fr/sites/default/files/notation_mathematique_braille2_0.pdf use crate::common::*; +use anyhow::Result; #[test] -fn set_of_elements_6_4_01() { +fn set_of_elements_6_4_01() -> Result<()> { let expr= r#"E={a,b,c,d}"#; - test_braille("French", expr, "⠨⠑⠶⠨⠦⠁⠂⠃⠂⠉⠂⠙⠨⠴"); + test_braille("French", expr, "⠨⠑⠶⠨⠦⠁⠂⠃⠂⠉⠂⠙⠨⠴")?; + return Ok(()); } #[test] -fn set_r_definition_6_4_02() { +fn set_r_definition_6_4_02() -> Result<()> { let expr= r#"ℝ*=]−∞,0[∪]0,+∞["#; - test_braille("French", expr, "⠨⠨⠗⠈⠐⠔⠶⠾⠤⠘⠉⠂⠼⠷⠸⠖⠾⠼⠂⠖⠘⠉⠷"); + test_braille("French", expr, "⠨⠨⠗⠈⠐⠔⠶⠾⠤⠘⠉⠂⠼⠷⠸⠖⠾⠼⠂⠖⠘⠉⠷")?; + return Ok(()); } #[test] -fn set_belonging_6_4_03() { +fn set_belonging_6_4_03() -> Result<()> { let expr= r#"x∈[0,1;2,3]"#; - test_braille("French", expr, "⠭⠘⠡⠷⠼⠂⠡⠆⠣⠂⠩⠾"); + test_braille("French", expr, "⠭⠘⠡⠷⠼⠂⠡⠆⠣⠂⠩⠾")?; + return Ok(()); } #[test] -fn set_not_belong_tor_6_4_04() { +fn set_not_belong_tor_6_4_04() -> Result<()> { let expr= r#"x∉ℝ+"#; - test_braille("French", expr, "⠭⠘⠌⠨⠨⠗⠈⠖"); + test_braille("French", expr, "⠭⠘⠌⠨⠨⠗⠈⠖")?; + return Ok(()); } #[test] -fn set_included_6_4_05() { +fn set_included_6_4_05() -> Result<()> { let expr= r#"D⊂F"#; - test_braille("French", expr, "⠨⠙⠨⠡⠨⠋"); + test_braille("French", expr, "⠨⠙⠨⠡⠨⠋")?; + return Ok(()); } #[test] -fn set_not_included_6_4_06() { +fn set_not_included_6_4_06() -> Result<()> { let expr= r#"D⊄E"#; - test_braille("French", expr, "⠨⠙⠨⠌⠨⠑"); + test_braille("French", expr, "⠨⠙⠨⠌⠨⠑")?; + return Ok(()); } #[test] -fn set_included_or_equal_6_4_07() { +fn set_included_or_equal_6_4_07() -> Result<()> { let expr= r#"A⊆B"#; - test_braille("French", expr, "⠨⠁⠸⠨⠡⠨⠃"); + test_braille("French", expr, "⠨⠁⠸⠨⠡⠨⠃")?; + return Ok(()); } #[test] -fn set_intersection_6_4_08() { +fn set_intersection_6_4_08() -> Result<()> { let expr= r#"A∩B=⌀"#; - test_braille("French", expr, "⠨⠁⠘⠖⠨⠃⠶⠘⠼"); + test_braille("French", expr, "⠨⠁⠘⠖⠨⠃⠶⠘⠼")?; + return Ok(()); } #[test] -fn complement_of_6_4_09() { +fn complement_of_6_4_09() -> Result<()> { let expr= r#"∁EF"#; - test_braille("French", expr, "⠨⠩⠢⠨⠑⠨⠋"); + test_braille("French", expr, "⠨⠩⠢⠨⠑⠨⠋")?; + return Ok(()); } #[test] -fn fraction_01_7_01() { +fn fraction_01_7_01() -> Result<()> { let expr= r#"23=46"#; - test_braille("French", expr, "⠣⠌⠩⠶⠹⠌⠫"); + test_braille("French", expr, "⠣⠌⠩⠶⠹⠌⠫")?; + return Ok(()); } #[test] -fn devided_by_7_02() { +fn devided_by_7_02() -> Result<()> { let expr= r#"1÷2=0,5"#; - test_braille("French", expr, "⠡⠒⠣⠶⠼⠂⠱"); + test_braille("French", expr, "⠡⠒⠣⠶⠼⠂⠱")?; + return Ok(()); } #[test] -fn fraction_02_8_01() { +fn fraction_02_8_01() -> Result<()> { let expr= r#"a+ba"#; - test_braille("French", expr, "⠠⠄⠰⠁⠖⠃⠆⠌⠁"); + test_braille("French", expr, "⠠⠄⠰⠁⠖⠃⠆⠌⠁")?; + return Ok(()); } #[test] -fn fraction_03_8_02() { +fn fraction_03_8_02() -> Result<()> { let expr= r#"a+bc+d"#; - test_braille("French", expr, "⠠⠄⠰⠁⠖⠃⠆⠌⠰⠉⠖⠙⠆"); + test_braille("French", expr, "⠠⠄⠰⠁⠖⠃⠆⠌⠰⠉⠖⠙⠆")?; + return Ok(()); } #[test] -fn fraction_04_8_03() { +fn fraction_04_8_03() -> Result<()> { let expr= r#"ab+cd=ad+bcbd"#; - test_braille("French", expr, "⠠⠄⠁⠌⠃⠖⠉⠌⠙⠶⠰⠁⠙⠖⠃⠉⠆⠌⠃⠙"); + test_braille("French", expr, "⠠⠄⠁⠌⠃⠖⠉⠌⠙⠶⠰⠁⠙⠖⠃⠉⠆⠌⠃⠙")?; + return Ok(()); } #[test] -fn cardinal_8_04() { +fn cardinal_8_04() -> Result<()> { let expr= r#"CardE=5"#; - test_braille("French", expr, "⠠⠄⠨⠉⠁⠗⠙⠰⠨⠑⠆⠶⠱"); + test_braille("French", expr, "⠠⠄⠨⠉⠁⠗⠙⠰⠨⠑⠆⠶⠱")?; + return Ok(()); } #[test] -fn exponential_01_8_05() { +fn exponential_01_8_05() -> Result<()> { let expr= r#"ex+3"#; - test_braille("French", expr, "⠠⠄⠑⠈⠰⠭⠖⠩⠆"); + test_braille("French", expr, "⠠⠄⠑⠈⠰⠭⠖⠩⠆")?; + return Ok(()); } #[test] -fn exponential_02_8_06() { +fn exponential_02_8_06() -> Result<()> { let expr= r#"e7"#; - test_braille("French", expr, "⠠⠑⠈⠻"); + test_braille("French", expr, "⠠⠑⠈⠻")?; + return Ok(()); } #[test] -fn exponential_03_8_07() { +fn exponential_03_8_07() -> Result<()> { let expr= r#"e−x"#; - test_braille("French", expr, "⠠⠑⠈⠤⠭"); + test_braille("French", expr, "⠠⠑⠈⠤⠭")?; + return Ok(()); } #[test] -fn exponential_04_8_08() { +fn exponential_04_8_08() -> Result<()> { let expr= r#"e−π"#; - test_braille("French", expr, "⠠⠑⠈⠤⠘⠏"); + test_braille("French", expr, "⠠⠑⠈⠤⠘⠏")?; + return Ok(()); } #[test] -fn power_negativ_one_8_09() { +fn power_negativ_one_8_09() -> Result<()> { let expr= r#"x−1=1x"#; - test_braille("French", expr, "⠠⠭⠈⠤⠡⠶⠡⠌⠭"); + test_braille("French", expr, "⠠⠭⠈⠤⠡⠶⠡⠌⠭")?; + return Ok(()); } #[test] -fn prime_9_1_01() { +fn prime_9_1_01() -> Result<()> { let expr= r#"a′"#; - test_braille("French", expr, "⠁⠄"); + test_braille("French", expr, "⠁⠄")?; + return Ok(()); } #[test] -fn prime_dople_9_1_02() { +fn prime_dople_9_1_02() -> Result<()> { let expr= r#"x″"#; - test_braille("French", expr, "⠭⠄⠄"); + test_braille("French", expr, "⠭⠄⠄")?; + return Ok(()); } #[test] -fn prime_dople_triple_9_1_03() { +fn prime_dople_triple_9_1_03() -> Result<()> { let expr= r#"a′x+a″y+a‴z"#; - test_braille("French", expr, "⠁⠄⠭⠖⠁⠄⠄⠽⠖⠁⠄⠄⠄⠵"); + test_braille("French", expr, "⠁⠄⠭⠖⠁⠄⠄⠽⠖⠁⠄⠄⠄⠵")?; + return Ok(()); } #[test] -fn sub_a_p_9_2_01() { +fn sub_a_p_9_2_01() -> Result<()> { let expr= r#"ap"#; - test_braille("French", expr, "⠁⠢⠏"); + test_braille("French", expr, "⠁⠢⠏")?; + return Ok(()); } #[test] -fn sub_x_0__9_2_02() { +fn sub_x_0__9_2_02() -> Result<()> { let expr= r#"x0"#; - test_braille("French", expr, "⠭⠢⠼"); + test_braille("French", expr, "⠭⠢⠼")?; + return Ok(()); } #[test] -fn sub_u_n_plus_one_9_2_03() { +fn sub_u_n_plus_one_9_2_03() -> Result<()> { let expr= r#"un+1"#; - test_braille("French", expr, "⠥⠢⠰⠝⠖⠡⠆"); + test_braille("French", expr, "⠥⠢⠰⠝⠖⠡⠆")?; + return Ok(()); } #[test] -fn sup_x_2_9_3_01() { +fn sup_x_2_9_3_01() -> Result<()> { let expr= r#"x2"#; - test_braille("French", expr, "⠭⠈⠣"); + test_braille("French", expr, "⠭⠈⠣")?; + return Ok(()); } #[test] -fn sup_x_p_plus_q_9_3_02() { +fn sup_x_p_plus_q_9_3_02() -> Result<()> { let expr= r#"xp+q"#; - test_braille("French", expr, "⠭⠈⠰⠏⠖⠟⠆"); + test_braille("French", expr, "⠭⠈⠰⠏⠖⠟⠆")?; + return Ok(()); } #[test] -fn sup_x_negative_number_9_3_03() { +fn sup_x_negative_number_9_3_03() -> Result<()> { let expr= r#"a−5,3"#; - test_braille("French", expr, "⠁⠈⠤⠱⠂⠩"); + test_braille("French", expr, "⠁⠈⠤⠱⠂⠩")?; + return Ok(()); } #[test] -fn sup_a_pi_9_3_04() { +fn sup_a_pi_9_3_04() -> Result<()> { let expr= r#"aπ"#; - test_braille("French", expr, "⠁⠈⠘⠏"); + test_braille("French", expr, "⠁⠈⠘⠏")?; + return Ok(()); } #[test] -fn sup_5_formula_block_1_9_3_05() { +fn sup_5_formula_block_1_9_3_05() -> Result<()> { let expr= r#"523≠523"#; - test_braille("French", expr, "⠱⠈⠣⠜⠩⠨⠶⠱⠈⠰⠣⠜⠩⠆"); + test_braille("French", expr, "⠱⠈⠣⠜⠩⠨⠶⠱⠈⠰⠣⠜⠩⠆")?; + return Ok(()); } #[test] -fn sup_5_formula_block_0_9_3_06() { +fn sup_5_formula_block_0_9_3_06() -> Result<()> { let expr= r#"e−5x≠e−5x"#; - test_braille("French", expr, "⠑⠈⠰⠤⠱⠭⠆⠨⠶⠰⠑⠈⠤⠱⠆⠭"); + test_braille("French", expr, "⠑⠈⠰⠤⠱⠭⠆⠨⠶⠰⠑⠈⠤⠱⠆⠭")?; + return Ok(()); } #[test] -fn sub_a_prime_0_9_4_01() { +fn sub_a_prime_0_9_4_01() -> Result<()> { let expr= r#"a′0"#; - test_braille("French", expr, "⠁⠄⠢⠼"); + test_braille("French", expr, "⠁⠄⠢⠼")?; + return Ok(()); } #[test] -fn sub_mixt_0_9_4_02() { +fn sub_mixt_0_9_4_02() -> Result<()> { let expr= r#"x0′2"#; - test_braille("French", expr, "⠭⠄⠢⠼⠈⠣"); + test_braille("French", expr, "⠭⠄⠢⠼⠈⠣")?; + return Ok(()); } #[test] -fn choose_9_4_03() { +fn choose_9_4_03() -> Result<()> { let expr= r#"∁mp=∁mm−p"#; - test_braille("French", expr, "⠨⠉⠢⠍⠈⠏⠶⠨⠉⠢⠍⠈⠰⠍⠤⠏⠆"); + test_braille("French", expr, "⠨⠉⠢⠍⠈⠏⠶⠨⠉⠢⠍⠈⠰⠍⠤⠏⠆")?; + return Ok(()); } #[test] -fn sub_sup_mixed_formulaq_9_4_04() { +fn sub_sup_mixed_formulaq_9_4_04() -> Result<()> { let expr= r#"am+n′p+q"#; - test_braille("French", expr, "⠁⠄⠄⠢⠰⠍⠖⠝⠆⠈⠰⠏⠖⠟⠆"); + test_braille("French", expr, "⠁⠄⠄⠢⠰⠍⠖⠝⠆⠈⠰⠏⠖⠟⠆")?; + return Ok(()); } #[test] -fn sub_sup_operators_9_4_05() { +fn sub_sup_operators_9_4_05() -> Result<()> { let expr= r#"ℝ+*"#; - test_braille("French", expr, "⠨⠨⠗⠢⠖⠈⠐⠔"); + test_braille("French", expr, "⠨⠨⠗⠢⠖⠈⠐⠔")?; + return Ok(()); } #[test] -fn left_sup_9_5_01() { +fn left_sup_9_5_01() -> Result<()> { let expr= r#"tA"#; - test_braille("French", expr, "⠈⠞⠨⠁"); + test_braille("French", expr, "⠈⠞⠨⠁")?; + return Ok(()); } #[test] -fn lef_sub_9_5_02() { +fn lef_sub_9_5_02() -> Result<()> { let expr= r#"2w"#; - test_braille("French", expr, "⠢⠣⠺"); + test_braille("French", expr, "⠢⠣⠺")?; + return Ok(()); } #[test] -fn left_right_sup_9_5_03() { +fn left_right_sup_9_5_03() -> Result<()> { let expr= r#"tAtB"#; - test_braille("French", expr, "⠰⠈⠞⠨⠁⠆⠰⠈⠞⠨⠃⠆"); + test_braille("French", expr, "⠰⠈⠞⠨⠁⠆⠰⠈⠞⠨⠃⠆")?; + return Ok(()); } #[test] -fn left_sub_sup_test_9_5_04() { +fn left_sub_sup_test_9_5_04() -> Result<()> { let expr= r#"816O"#; - test_braille("French", expr, "⠨⠕⠠⠢⠳⠠⠈⠡⠫"); + test_braille("French", expr, "⠨⠕⠠⠢⠳⠠⠈⠡⠫")?; + return Ok(()); } #[test] -fn bigsum_one_line_9_6_01() { +fn bigsum_one_line_9_6_01() -> Result<()> { let expr= r#"∑i=1nui=u1+u2+⋯+un"#; - test_braille("French", expr, "⠨⠘⠎⠢⠢⠰⠊⠶⠡⠆⠈⠈⠝⠥⠢⠊⠶⠥⠢⠡⠖⠥⠢⠣⠖⠲⠲⠲⠖⠥⠢⠝"); + test_braille("French", expr, "⠨⠘⠎⠢⠢⠰⠊⠶⠡⠆⠈⠈⠝⠥⠢⠊⠶⠥⠢⠡⠖⠥⠢⠣⠖⠲⠲⠲⠖⠥⠢⠝")?; + return Ok(()); } #[test] -fn bigsum_two_lines_9_6_01() { +fn bigsum_two_lines_9_6_01() -> Result<()> { let expr= r#"∑i=1nui=u1+u2+⋯+un"#; test_braille("French", expr, " ⠨⠘⠎⠢⠢⠰⠊⠶⠡⠆⠈⠈⠝⠥⠢⠊⠐ -⠶⠥⠢⠡⠖⠥⠢⠣⠖⠲⠲⠲⠖⠥⠢⠝"); +⠶⠥⠢⠡⠖⠥⠢⠣⠖⠲⠲⠲⠖⠥⠢⠝")?; + return Ok(()); } #[test] -fn bigsum_one_line_with_bloc_9_6_01() { +fn bigsum_one_line_with_bloc_9_6_01() -> Result<()> { let expr= r#"∑i=1nui=u1+u2+⋯+un"#; - test_braille("French", expr, "⠨⠘⠎⠢⠢⠰⠊⠶⠡⠆⠈⠈⠝⠥⠢⠊⠶⠥⠢⠡⠖⠥⠢⠣⠖⠲⠲⠲⠖⠥⠢⠝"); + test_braille("French", expr, "⠨⠘⠎⠢⠢⠰⠊⠶⠡⠆⠈⠈⠝⠥⠢⠊⠶⠥⠢⠡⠖⠥⠢⠣⠖⠲⠲⠲⠖⠥⠢⠝")?; + return Ok(()); } #[test] -fn root_square_10_01() { +fn root_square_10_01() -> Result<()> { let expr= r#"2"#; - test_braille("French", expr, "⠜⠣"); + test_braille("French", expr, "⠜⠣")?; + return Ok(()); } #[test] -fn root_fourth_10_02() { +fn root_fourth_10_02() -> Result<()> { let expr= r#"a4"#; - test_braille("French", expr, "⠈⠹⠜⠁"); + test_braille("French", expr, "⠈⠹⠜⠁")?; + return Ok(()); } #[test] -fn square_formula_1_10_03() { +fn square_formula_1_10_03() -> Result<()> { let expr= r#"(a+b)36=a+b"#; - test_braille("French", expr, "⠈⠫⠜⠰⠦⠁⠖⠃⠴⠈⠩⠆⠶⠜⠰⠁⠖⠃⠆"); + test_braille("French", expr, "⠈⠫⠜⠰⠦⠁⠖⠃⠴⠈⠩⠆⠶⠜⠰⠁⠖⠃⠆")?; + return Ok(()); } #[test] -fn square_formula_2_10_04() { +fn square_formula_2_10_04() -> Result<()> { let expr= r#"a+a+b3"#; - test_braille("French", expr, "⠈⠩⠜⠰⠁⠖⠜⠰⠁⠖⠃⠆⠆"); + test_braille("French", expr, "⠈⠩⠜⠰⠁⠖⠜⠰⠁⠖⠃⠆⠆")?; + return Ok(()); } #[test] -fn square_formula_3_10_05() { +fn square_formula_3_10_05() -> Result<()> { let expr= r#"a4b3"#; - test_braille("French", expr, "⠰⠈⠹⠜⠁⠆⠰⠈⠩⠜⠃⠆"); + test_braille("French", expr, "⠰⠈⠹⠜⠁⠆⠰⠈⠩⠜⠃⠆")?; + return Ok(()); } #[test] -fn function_from_r_to_r_11_01() { +fn function_from_r_to_r_11_01() -> Result<()> { let expr= r#"f:ℝ→ℝ,x↦y=1x"#; - test_braille("French", expr, "⠒⠨⠨⠗⠸⠱⠨⠨⠗⠭⠐⠱⠽⠶⠡⠌⠭"); + test_braille("French", expr, "⠒⠨⠨⠗⠸⠱⠨⠨⠗⠭⠐⠱⠽⠶⠡⠌⠭")?; + return Ok(()); } #[test] -fn over_arrow_12_1_01() { +fn over_arrow_12_1_01() -> Result<()> { let expr= r#"v→"#; - test_braille("French", expr, "⠨⠒⠧"); + test_braille("French", expr, "⠨⠒⠧")?; + return Ok(()); } #[test] -fn over_barre_12_1_02() { +fn over_barre_12_1_02() -> Result<()> { let expr= r#"AB¯"#; - test_braille("French", expr, "⠸⠒⠨⠁⠨⠃"); + test_braille("French", expr, "⠸⠒⠨⠁⠨⠃")?; + return Ok(()); } #[test] -fn over_arc_12_1_03() { +fn over_arc_12_1_03() -> Result<()> { let expr= r#"AB⏜"#; - test_braille("French", expr, "⠈⠒⠨⠁⠨⠃"); + test_braille("French", expr, "⠈⠒⠨⠁⠨⠃")?; + return Ok(()); } #[test] -fn over_large_hat_1_12_1_04() { +fn over_large_hat_1_12_1_04() -> Result<()> { let expr= r#"AOB̂"#; - test_braille("French", expr, "⠘⠒⠨⠁⠨⠕⠨⠃"); + test_braille("French", expr, "⠘⠒⠨⠁⠨⠕⠨⠃")?; + return Ok(()); } #[test] -fn over_large_hat_2_12_1_05() { +fn over_large_hat_2_12_1_05() -> Result<()> { let expr= r#"(Ox,Oy)̂"#; - test_braille("French", expr, "⠘⠒⠦⠨⠕⠭⠂⠨⠕⠽⠴"); + test_braille("French", expr, "⠘⠒⠦⠨⠕⠭⠂⠨⠕⠽⠴")?; + return Ok(()); } #[test] -fn over_large_hat_3_12_1_06() { +fn over_large_hat_3_12_1_06() -> Result<()> { let expr= r#"(OA→,OM→)̂"#; - test_braille("French", expr, "⠘⠒⠦⠨⠒⠨⠕⠨⠁⠂⠨⠒⠨⠕⠨⠍⠴"); + test_braille("French", expr, "⠘⠒⠦⠨⠒⠨⠕⠨⠁⠂⠨⠒⠨⠕⠨⠍⠴")?; + return Ok(()); } #[test] -fn parallel_d_delta_12_3_01() { +fn parallel_d_delta_12_3_01() -> Result<()> { let expr= r#"(D)⫽(Δ)"#; - test_braille("French", expr, "⠦⠨⠙⠴⠸⠳⠦⠨⠘⠙⠴"); + test_braille("French", expr, "⠦⠨⠙⠴⠸⠳⠦⠨⠘⠙⠴")?; + return Ok(()); } #[test] -fn perpendicular_12_3_02() { +fn perpendicular_12_3_02() -> Result<()> { let expr= r#"(AB)⊥(A′B′)"#; - test_braille("French", expr, "⠦⠨⠁⠨⠃⠴⠘⠳⠦⠨⠁⠄⠨⠃⠄⠴"); + test_braille("French", expr, "⠦⠨⠁⠨⠃⠴⠘⠳⠦⠨⠁⠄⠨⠃⠄⠴")?; + return Ok(()); } #[test] -fn abs_13_2_01() { +fn abs_13_2_01() -> Result<()> { let expr= r#"|x0|"#; - test_braille("French", expr, "⠿⠭⠢⠼⠿"); + test_braille("French", expr, "⠿⠭⠢⠼⠿")?; + return Ok(()); } #[test] -fn modulus_13_2_02() { +fn modulus_13_2_02() -> Result<()> { let expr= r#"|a+ib|"#; - test_braille("French", expr, "⠿⠁⠖⠊⠃⠿"); + test_braille("French", expr, "⠿⠁⠖⠊⠃⠿")?; + return Ok(()); } #[test] -fn norm_k_u_vector_13_2_03() { +fn norm_k_u_vector_13_2_03() -> Result<()> { let expr= r#"∥ku→∥=|k|∥u→∥"#; - test_braille("French", expr, "⠘⠿⠅⠨⠒⠥⠘⠿⠶⠿⠅⠿⠘⠿⠨⠒⠥⠘⠿"); + test_braille("French", expr, "⠘⠿⠅⠨⠒⠥⠘⠿⠶⠿⠅⠿⠘⠿⠨⠒⠥⠘⠿")?; + return Ok(()); } #[test] -fn restriction_of_f_to_13_2_04() { +fn restriction_of_f_to_13_2_04() -> Result<()> { let expr= r#"f|E"#; - test_braille("French", expr, "⠋⠿⠨⠑"); + test_braille("French", expr, "⠋⠿⠨⠑")?; + return Ok(()); } #[test] -fn determinant_tabular_13_3_01() { +fn determinant_tabular_13_3_01() -> Result<()> { let expr= r#"I=|1023|=3"#; test_braille("French", expr, " ⠨⠊⠶⠿⠡⠀⠼⠿ - ⠿⠣⠀⠩⠿⠶⠩"); + ⠿⠣⠀⠩⠿⠶⠩")?; + return Ok(()); } #[test] -fn matrix_tabular_13_3_02() { +fn matrix_tabular_13_3_02() -> Result<()> { let expr= r#"J=(142356−789)"#; test_braille("French", expr, " ⠨⠚⠶⠦⠡⠀⠀⠀⠀⠀⠀⠹⠴ ⠀⠀⠀⠦⠣⠀⠩⠀⠱⠀⠀⠫⠴ -⠀⠀⠀⠦⠤⠻⠀⠳⠀⠀⠀⠪⠴"); +⠀⠀⠀⠦⠤⠻⠀⠳⠀⠀⠀⠪⠴")?; + return Ok(()); } #[test] -fn matrix_linear_13_3_02() { +fn matrix_linear_13_3_02() -> Result<()> { let expr= r#"J=(142356−789)"#; - test_braille("French", expr, "⠨⠚⠶⠘⠦⠡⠀⠐⠂⠀⠐⠂⠀⠹⠀⠠⠜⠀⠣⠀⠩⠀⠱⠀⠫⠀⠠⠜⠀⠤⠻⠀⠳⠀⠐⠂⠀⠪⠘⠴"); + test_braille("French", expr, "⠨⠚⠶⠘⠦⠡⠀⠐⠂⠀⠐⠂⠀⠹⠀⠠⠜⠀⠣⠀⠩⠀⠱⠀⠫⠀⠠⠜⠀⠤⠻⠀⠳⠀⠐⠂⠀⠪⠘⠴")?; + return Ok(()); } #[test] -fn matrix_with_equations_two_lines_13_3_03() { +fn matrix_with_equations_two_lines_13_3_03() -> Result<()> { let expr= r#"K=[1x2+3x−96x3−x2+1x+3y+5g(x)]"#; test_braille("French", expr, " ⠨⠅⠶⠘⠷⠡⠀⠰⠭⠈⠣⠖⠩⠭⠤⠪⠆⠌⠰⠫⠭⠈⠩⠤⠭⠈⠣⠐ -⠖⠡⠆⠀⠠⠜⠀⠰⠭⠖⠩⠆⠌⠰⠽⠖⠱⠆⠀⠛⠦⠭⠴⠘⠾"); +⠖⠡⠆⠀⠠⠜⠀⠰⠭⠖⠩⠆⠌⠰⠽⠖⠱⠆⠀⠛⠦⠭⠴⠘⠾")?; + return Ok(()); } #[test] -fn matrix_with_equations_one_lines_13_3_03() { +fn matrix_with_equations_one_lines_13_3_03() -> Result<()> { let expr= r#"K=[1x2+3x−96x3−x2+1x+3y+5g(x)]"#; - test_braille("French", expr, "⠨⠅⠶⠘⠷⠡⠀⠰⠭⠈⠣⠖⠩⠭⠤⠪⠆⠌⠰⠫⠭⠈⠩⠤⠭⠈⠣⠖⠡⠆⠀⠠⠜⠀⠰⠭⠖⠩⠆⠌⠰⠽⠖⠱⠆⠀⠛⠦⠭⠴⠘⠾"); + test_braille("French", expr, "⠨⠅⠶⠘⠷⠡⠀⠰⠭⠈⠣⠖⠩⠭⠤⠪⠆⠌⠰⠫⠭⠈⠩⠤⠭⠈⠣⠖⠡⠆⠀⠠⠜⠀⠰⠭⠖⠩⠆⠌⠰⠽⠖⠱⠆⠀⠛⠦⠭⠴⠘⠾")?; + return Ok(()); } #[test] -fn sytem_equation_tabular_13_4_01() { +fn sytem_equation_tabular_13_4_01() -> Result<()> { let expr= r#"{2x+3y=53x−7y=8"#; test_braille("French", expr, " ⠸⠦⠣⠭⠖⠩⠽⠶⠱ -⠀⠀⠩⠭⠤⠻⠽⠶⠳"); +⠀⠀⠩⠭⠤⠻⠽⠶⠳")?; + return Ok(()); } #[test] -fn sytem_equation_linéaraire_13_4_01() { +fn sytem_equation_linéaraire_13_4_01() -> Result<()> { let expr= r#"{2x+3y=53x−7y=8"#; - test_braille("French", expr, "⠸⠦⠣⠭⠖⠩⠽⠶⠱⠀⠠⠜⠀⠩⠭⠤⠻⠽⠶⠳"); + test_braille("French", expr, "⠸⠦⠣⠭⠖⠩⠽⠶⠱⠀⠠⠜⠀⠩⠭⠤⠻⠽⠶⠳")?; + return Ok(()); } #[test] -fn function_f_of_x_14_1_01() { +fn function_f_of_x_14_1_01() -> Result<()> { let expr= r#"f(x)"#; - test_braille("French", expr, "⠋⠦⠭⠴"); + test_braille("French", expr, "⠋⠦⠭⠴")?; + return Ok(()); } #[test] -fn function_g_prime_14_1_02() { +fn function_g_prime_14_1_02() -> Result<()> { let expr= r#"g′(x)=3x+4"#; - test_braille("French", expr, "⠛⠄⠦⠭⠴⠶⠩⠭⠖⠹"); + test_braille("French", expr, "⠛⠄⠦⠭⠴⠶⠩⠭⠖⠹")?; + return Ok(()); } #[test] -fn function_composition_14_1_03() { +fn function_composition_14_1_03() -> Result<()> { let expr= r#"f∘g(x)=f[g(x)]"#; - test_braille("French", expr, "⠋⠸⠼⠛⠦⠭⠴⠶⠋⠷⠛⠦⠭⠴⠾"); + test_braille("French", expr, "⠋⠸⠼⠛⠦⠭⠴⠶⠋⠷⠛⠦⠭⠴⠾")?; + return Ok(()); } #[test] -fn function_partial_derivative_14_1_04() { +fn function_partial_derivative_14_1_04() -> Result<()> { let expr= r#"∂f(x,y)∂x=5xy−7x"#; - test_braille("French", expr, "⠐⠙⠋⠦⠭⠂⠽⠴⠌⠐⠙⠭⠶⠱⠭⠽⠤⠻⠭"); + test_braille("French", expr, "⠐⠙⠋⠦⠭⠂⠽⠴⠌⠐⠙⠭⠶⠱⠭⠽⠤⠻⠭")?; + return Ok(()); } #[test] -fn limit_x_tends_1_14_2_01_corrected() { +fn limit_x_tends_1_14_2_01_corrected() -> Result<()> { let expr= r#"limx→+∞f(x)=0"#; - test_braille("French", expr, "⠇⠊⠍⠢⠢⠰⠭⠸⠱⠖⠘⠉⠆⠋⠦⠭⠴⠶⠼"); + test_braille("French", expr, "⠇⠊⠍⠢⠢⠰⠭⠸⠱⠖⠘⠉⠆⠋⠦⠭⠴⠶⠼")?; + return Ok(()); } #[test] -fn limit_x_tends_and_x_lt_1_14_2_02_corrected_1() { +fn limit_x_tends_and_x_lt_1_14_2_02_corrected_1() -> Result<()> { let expr= r#"limx→4x>4f(x)=−∞"#; - test_braille("French", expr, "⠇⠊⠍⠢⠢⠰⠭⠸⠱⠹⠂⠭⠐⠜⠹⠆⠋⠦⠭⠴⠶⠤⠘⠉"); + test_braille("French", expr, "⠇⠊⠍⠢⠢⠰⠭⠸⠱⠹⠂⠭⠐⠜⠹⠆⠋⠦⠭⠴⠶⠤⠘⠉")?; + return Ok(()); } #[test] -fn limit_x_tends_and_x_lt_2_14_2_02_corrected_2() { +fn limit_x_tends_and_x_lt_2_14_2_02_corrected_2() -> Result<()> { let expr= r#"limx→4x>4f(x)=−∞"#; - test_braille("French", expr, "⠇⠊⠍⠢⠢⠰⠭⠸⠱⠹⠂⠭⠐⠜⠹⠆⠋⠦⠭⠴⠶⠤⠘⠉"); + test_braille("French", expr, "⠇⠊⠍⠢⠢⠰⠭⠸⠱⠹⠂⠭⠐⠜⠹⠆⠋⠦⠭⠴⠶⠤⠘⠉")?; + return Ok(()); } #[test] -fn limit_x_tends_of_formula_lt_2_14_2_03_corrected() { +fn limit_x_tends_of_formula_lt_2_14_2_03_corrected() -> Result<()> { let expr= r#"limx→+∞ln⁡(x+2)x=0"#; - test_braille("French", expr, "⠇⠊⠍⠢⠢⠰⠭⠸⠱⠖⠘⠉⠆⠰⠇⠝⠦⠭⠖⠣⠴⠌⠭⠆⠶⠼"); + test_braille("French", expr, "⠇⠊⠍⠢⠢⠰⠭⠸⠱⠖⠘⠉⠆⠰⠇⠝⠦⠭⠖⠣⠴⠌⠭⠆⠶⠼")?; + return Ok(()); } #[test] -fn sign_chart_14_3_01() { +fn sign_chart_14_3_01() -> Result<()> { let expr= r#"x−∞32+∞2x−3−0+"#; test_braille("French", expr, " ⠭⠀⠀⠀⠸⠤⠘⠉⠀⠀⠩⠌⠣⠀⠀⠀⠖⠘⠉ ⠒⠒⠒⠒⠺⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒ -⠣⠭⠤⠩⠸⠀⠀⠀⠤⠀⠀⠼⠀⠀⠖"); +⠣⠭⠤⠩⠸⠀⠀⠀⠤⠀⠀⠼⠀⠀⠖")?; + return Ok(()); } #[test] -fn sign_chart_14_3_02() { +fn sign_chart_14_3_02() -> Result<()> { let expr= r#"x−∞7+∞f′(x)+0−f(x)−∞↗−1↘−∞"#; test_braille("French", expr, " ⠀⠭⠀⠀⠀⠀⠸⠤⠘⠉⠀⠀⠀⠀⠀⠻⠀⠀⠀⠀⠀⠖⠘ ⠒⠒⠒⠒⠒⠺⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒ ⠋⠄⠦⠭⠴⠸⠀⠀⠀⠀⠖⠀⠀⠀⠀⠼⠀⠀⠀⠀⠤ -⠋⠦⠭⠴⠀⠸⠤⠘⠉⠀⠘⠱⠀⠤⠡⠀⠨⠱⠀⠤⠘⠉"); +⠋⠦⠭⠴⠀⠸⠤⠘⠉⠀⠘⠱⠀⠤⠡⠀⠨⠱⠀⠤⠘⠉")?; + return Ok(()); } #[test] -fn integral_from_to_1_14_4_01() { +fn integral_from_to_1_14_4_01() -> Result<()> { let expr= r#"∫abf(x)dx"#; - test_braille("French", expr, "⠯⠢⠁⠈⠃⠋⠦⠭⠴⠙⠭"); + test_braille("French", expr, "⠯⠢⠁⠈⠃⠋⠦⠭⠴⠙⠭")?; + return Ok(()); } #[test] -fn integral_two_lines_14_4_02() { +fn integral_two_lines_14_4_02() -> Result<()> { let expr= r#"∫052f(x)dx=F(52)−F(0)"#; test_braille("French", expr, " ⠯⠢⠼⠈⠰⠱⠌⠣⠆⠋⠦⠭⠴⠙⠭⠐ -⠶⠨⠋⠦⠱⠌⠣⠴⠤⠨⠋⠦⠼⠴"); +⠶⠨⠋⠦⠱⠌⠣⠴⠤⠨⠋⠦⠼⠴")?; + return Ok(()); } #[test] -fn integral_one_lines14_4_02() { +fn integral_one_lines14_4_02() -> Result<()> { let expr= r#"∫052f(x)dx=F(52)−F(0)"#; - test_braille("French", expr, "⠯⠢⠼⠈⠰⠱⠌⠣⠆⠋⠦⠭⠴⠙⠭⠶⠨⠋⠦⠱⠌⠣⠴⠤⠨⠋⠦⠼⠴"); + test_braille("French", expr, "⠯⠢⠼⠈⠰⠱⠌⠣⠆⠋⠦⠭⠴⠙⠭⠶⠨⠋⠦⠱⠌⠣⠴⠤⠨⠋⠦⠼⠴")?; + return Ok(()); } #[test] -fn integral_from_to_2_14_4_03() { +fn integral_from_to_2_14_4_03() -> Result<()> { let expr= r#"∫125xdx"#; - test_braille("French", expr, "⠯⠢⠡⠈⠣⠰⠱⠭⠆⠙⠭"); + test_braille("French", expr, "⠯⠢⠡⠈⠣⠰⠱⠭⠆⠙⠭")?; + return Ok(()); } #[test] -fn integral_over_curve_14_4_04() { +fn integral_over_curve_14_4_04() -> Result<()> { let expr= r#"∫(c)f(x)dx"#; - test_braille("French", expr, "⠯⠢⠦⠨⠉⠴⠋⠦⠭⠴⠙⠭"); + test_braille("French", expr, "⠯⠢⠦⠨⠉⠴⠋⠦⠭⠴⠙⠭")?; + return Ok(()); } #[test] -fn integral_double_over_surface_14_4_05() { +fn integral_double_over_surface_14_4_05() -> Result<()> { let expr= r#"∯Sf(x,y)dxdy"#; - test_braille("French", expr, "⠨⠯⠯⠢⠨⠎⠋⠦⠭⠂⠽⠴⠙⠭⠙⠽"); + test_braille("French", expr, "⠨⠯⠯⠢⠨⠎⠋⠦⠭⠂⠽⠴⠙⠭⠙⠽")?; + return Ok(()); } #[test] -fn logarithm_natural_fraction_14_5_01() { +fn logarithm_natural_fraction_14_5_01() -> Result<()> { let expr= r#"ln⁡(ab)"#; - test_braille("French", expr, "⠇⠝⠦⠁⠌⠃⠴"); + test_braille("French", expr, "⠇⠝⠦⠁⠌⠃⠴")?; + return Ok(()); } #[test] -fn logarithm_natural_product_14_5_02() { +fn logarithm_natural_product_14_5_02() -> Result<()> { let expr= r#"ln⁡xy=ln⁡x+ln⁡y"#; - test_braille("French", expr, "⠇⠝⠰⠭⠽⠆⠶⠇⠝⠰⠭⠆⠖⠇⠝⠰⠽⠆"); + test_braille("French", expr, "⠇⠝⠰⠭⠽⠆⠶⠇⠝⠰⠭⠆⠖⠇⠝⠰⠽⠆")?; + return Ok(()); } #[test] -fn logarthm_change_base_14_5_03() { +fn logarthm_change_base_14_5_03() -> Result<()> { let expr= r#"log7x=ln⁡xln⁡7"#; - test_braille("French", expr, "⠇⠕⠛⠢⠻⠰⠭⠆⠶⠇⠝⠰⠭⠆⠌⠇⠝⠰⠻⠆"); + test_braille("French", expr, "⠇⠕⠛⠢⠻⠰⠭⠆⠶⠇⠝⠰⠭⠆⠌⠇⠝⠰⠻⠆")?; + return Ok(()); } #[test] -fn cos_of_sum_1_14_6_01() { +fn cos_of_sum_1_14_6_01() -> Result<()> { let expr= r#"cos⁡(a+b)=cosacosb−sinasinb"#; - test_braille("French", expr, "⠉⠕⠎⠦⠁⠖⠃⠴⠶⠉⠕⠎⠰⠁⠆⠉⠕⠎⠰⠃⠆⠐⠤⠎⠊⠝⠰⠁⠆⠎⠊⠝⠰⠃⠆"); + test_braille("French", expr, "⠉⠕⠎⠦⠁⠖⠃⠴⠶⠉⠕⠎⠰⠁⠆⠉⠕⠎⠰⠃⠆⠐⠤⠎⠊⠝⠰⠁⠆⠎⠊⠝⠰⠃⠆")?; + return Ok(()); } #[test] -fn cos_of_sum_2_14_6_01b() { +fn cos_of_sum_2_14_6_01b() -> Result<()> { let expr= r#"cos⁡(a+b)=cosacosb−sinasinb"#; - test_braille("French", expr, "⠨⠬⠦⠁⠖⠃⠴⠶⠨⠬⠁⠨⠬⠃⠤⠬⠁⠬⠃"); + test_braille("French", expr, "⠨⠬⠦⠁⠖⠃⠴⠶⠨⠬⠁⠨⠬⠃⠤⠬⠁⠬⠃")?; + return Ok(()); } #[test] -fn cos_of_sum_3_14_6_01b() { +fn cos_of_sum_3_14_6_01b() -> Result<()> { let expr= r#"cos(a+b)=cosacosb−sinasinb"#; - test_braille("French", expr, "⠨⠬⠦⠁⠖⠃⠴⠶⠨⠬⠁⠨⠬⠃⠤⠬⠁⠬⠃"); + test_braille("French", expr, "⠨⠬⠦⠁⠖⠃⠴⠶⠨⠬⠁⠨⠬⠃⠤⠬⠁⠬⠃")?; + return Ok(()); } #[test] -fn cosh_sinh_14_7_01() { +fn cosh_sinh_14_7_01() -> Result<()> { let expr= r#"cosh2x−sinh2x=1"#; - test_braille("French", expr, "⠉⠓⠈⠣⠰⠭⠆⠤⠎⠓⠈⠣⠰⠭⠆⠶⠡"); + test_braille("French", expr, "⠉⠓⠈⠣⠰⠭⠆⠤⠎⠓⠈⠣⠰⠭⠆⠶⠡")?; + return Ok(()); } #[test] -fn exists_element_of_15_01() { +fn exists_element_of_15_01() -> Result<()> { let expr= r#"∃x:x∈A"#; - test_braille("French", expr, "⠸⠡⠭⠒⠭⠘⠡⠨⠁"); + test_braille("French", expr, "⠸⠡⠭⠒⠭⠘⠡⠨⠁")?; + return Ok(()); } #[test] -fn set_formula_15_02() { +fn set_formula_15_02() -> Result<()> { let expr= r#"∀ε>0∃η>0:|x2−x1|≤η⇒|f(x2)−f(x1)|≤ε"#; - test_braille("French", expr, "⠸⠌⠘⠑⠐⠜⠼⠀⠸⠡⠘⠓⠐⠜⠼⠒⠀⠿⠭⠢⠣⠤⠭⠢⠡⠿⠘⠣⠘⠓⠀⠒⠂⠀⠿⠋⠦⠭⠢⠣⠴⠤⠋⠦⠭⠢⠡⠴⠿⠘⠣⠘⠑"); + test_braille("French", expr, "⠸⠌⠘⠑⠐⠜⠼⠀⠸⠡⠘⠓⠐⠜⠼⠒⠀⠿⠭⠢⠣⠤⠭⠢⠡⠿⠘⠣⠘⠓⠀⠒⠂⠀⠿⠋⠦⠭⠢⠣⠴⠤⠋⠦⠭⠢⠡⠴⠿⠘⠣⠘⠑")?; + return Ok(()); } #[test] -fn power_ordinal_a_16_4_07() { +fn power_ordinal_a_16_4_07() -> Result<()> { let expr= r#"(p+q)ième"#; - test_braille("French", expr, "⠦⠏⠖⠟⠴⠈⠊⠮⠍"); + test_braille("French", expr, "⠦⠏⠖⠟⠴⠈⠊⠮⠍")?; + return Ok(()); } #[test] -fn power_ordinal_b_16_4_07() { +fn power_ordinal_b_16_4_07() -> Result<()> { let expr= r#"(p+q)ième"#; - test_braille("French", expr, "⠦⠏⠖⠟⠴⠈⠊⠮⠍"); + test_braille("French", expr, "⠦⠏⠖⠟⠴⠈⠊⠮⠍")?; + return Ok(()); } From 62dfe83d738ad3662f8970e54fda345eb7a75418 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Mon, 22 Jun 2026 00:03:30 -0700 Subject: [PATCH 006/157] It appears some logic was missing parens -- not sure why this always worked... --- src/xpath_functions.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xpath_functions.rs b/src/xpath_functions.rs index 8c6bfb655..7320ed81c 100644 --- a/src/xpath_functions.rs +++ b/src/xpath_functions.rs @@ -868,8 +868,8 @@ impl IsBracketed { return false; } - if !left.is_empty() && get_text_from_COE(&children[0]) != left || - !right.is_empty() && get_text_from_COE(&children[children.len()-1]) != right { + if (!left.is_empty() && get_text_from_COE(&children[0]) != left) || + (!right.is_empty() && get_text_from_COE(&children[children.len()-1]) != right) { // left or right don't match return false; } From 3c5b1018a1a87d9b1c34790bffc6933b3c27296e Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Mon, 22 Jun 2026 00:06:00 -0700 Subject: [PATCH 007/157] Lots more cleanup of tests, additions of rules. Now at 78 pass/15 fail. --- Rules/Braille/French/French_Rules.yaml | 616 ++++++++++++------------- Rules/Braille/French/definitions.yaml | 18 + Rules/Braille/French/unicode-full.yaml | 4 +- Rules/Braille/French/unicode.yaml | 50 +- Rules/prefs.yaml | 2 + src/braille.rs | 173 +++---- tests/braille/French/chemistry.rs | 4 +- tests/braille/French/french.rs | 145 ++---- 8 files changed, 462 insertions(+), 550 deletions(-) diff --git a/Rules/Braille/French/French_Rules.yaml b/Rules/Braille/French/French_Rules.yaml index 3dad1abe3..741a7d0e8 100644 --- a/Rules/Braille/French/French_Rules.yaml +++ b/Rules/Braille/French/French_Rules.yaml @@ -1,27 +1,27 @@ --- -- - name: whitespace-omission - tag: "!*" - match: "not(self::m:math) and not($MatchingWhitespace) and (@data-previous-space-width >= 0.25 or @data-following-space-width >= 0.25)" - replace: - - with: - variables: [MatchingWhitespace: "true()"] - replace: - - test: - - if: "(@class='MathML-unit' or BaseNode(.)[@class='MathML-unit']) and @data-previous-space-width >= 0.25" # BANA 5.3(a) - then: [t: "𝐖"] - - else_if: "@data-previous-space-width > 1.1" - then: [t: "⠬"] - - else_if: "@data-previous-space-width >= 0.25" # thickspace - then: [t: "W"] - - x: "." - - test: - - if: "(@class='MathML-unit' or BaseNode(.)[@class='MathML-unit']) and @data-following-space-width >= 0.25" # BANA 5.3(a) - then: [t: "𝐖"] - - else_if: "@data-following-space-width > 1.1" - then: [t: "⠬"] - - else_if: "@data-following-space-width >= 0.25" # thickspace - then: [t: "W"] +# - +# name: whitespace-omission +# tag: "!*" +# match: "not(self::m:math) and not($MatchingWhitespace) and (@data-previous-space-width >= 0.25 or @data-following-space-width >= 0.25)" +# replace: +# - with: +# variables: [MatchingWhitespace: "true()"] +# replace: +# - test: +# - if: "(@class='MathML-unit' or BaseNode(.)[@class='MathML-unit']) and @data-previous-space-width >= 0.25" # BANA 5.3(a) +# then: [t: "𝐖"] +# - else_if: "@data-previous-space-width > 1.1" +# then: [t: "⠬"] +# - else_if: "@data-previous-space-width >= 0.25" # thickspace +# then: [t: "W"] +# - x: "." +# - test: +# - if: "(@class='MathML-unit' or BaseNode(.)[@class='MathML-unit']) and @data-following-space-width >= 0.25" # BANA 5.3(a) +# then: [t: "𝐖"] +# - else_if: "@data-following-space-width > 1.1" +# then: [t: "⠬"] +# - else_if: "@data-following-space-width >= 0.25" # thickspace +# then: [t: "W"] - name: omission-intent @@ -46,9 +46,9 @@ - test: if: "NeedsToBeGrouped(*[1], 'French', true())" then: - - t: "⠰" + - t: "o" - x: "*[1]" - - t: "⠆" + - t: "c" else: - x: "*[1]" @@ -59,20 +59,20 @@ replace: - t: "⠈" - test: - if: "NeedsToBeGrouped(*[2], 'French', true())" + if: "NeedsToBeGrouped(*[2], 'French', false())" then: - - t: "⠰" + - t: "o" - x: "*[2]" - - t: "⠆" + - t: "c" else: - x: "*[2]" - t: "⠜" - test: - if: "NeedsToBeGrouped(*[1], 'French', true())" + if: "NeedsToBeGrouped(*[1], 'French', false())" then: - - t: "⠰" + - t: "o" - x: "*[1]" - - t: "⠆" + - t: "c" else: - x: "*[1]" @@ -101,45 +101,23 @@ match: "." replace: - test: - if: "DEBUG(NeedsToBeGrouped(DEBUG(*[1]), 'French', true()))" + if: "NeedsToBeGrouped(*[1], 'French', true())" then: - - t: "⠰" + - t: "o" - x: "*[1]" - - t: "⠆" + - t: "c" else: - x: "*[1]" - t: "⠌" - test: if: "NeedsToBeGrouped(*[2], 'French', true())" then: - - t: "⠰" + - t: "o" - x: "*[2]" - - t: "⠆" + - t: "c" else: - x: "*[2]" -- - #GTM 14.3.3 (not sure what else vertical juxtaposition applies to) - name: binomial-frac - tag: mrow - match: "IsBracketed(., '(', ')') and *[2][self::m:mfrac][@linethickness=0]" - replace: - - x: "*[1]" - - x: "*[2]/*[1]" - - t: "⠰⠻" - - x: "*[2]/*[2]" - - x: "*[3]" - -- name: binomial-table - tag: mrow - match: "IsBracketed(., '(', ')') and *[2][self::m:mtable][count(*)=2 and count(*[1])=1] and contains(@intent, 'binomial(')" - replace: - - x: "*[1]" - - x: "*[2]/*[1]/*[1]/*[1]" - - t: "⠰⠻" - - x: "*[2]/*[2]/*[1]/*[1]" - - x: "*[3]" - # # Matrix/Determinant rules # matrix and determinant are the same other than "matrix"/"determinant" based on the bracketing chars @@ -216,9 +194,12 @@ variables: - RowStart: "''" # empty string -- it needs to be set - RowEnd: "''" # empty string -- it needs to be set - - NewScriptContext: "''" # empty string -- it needs to be set - MatchingWhitespace: "false()" - replace: [x: "*"] + replace: + - test: + if: "@display='inline' and not(*[1][self::m:mi])" # FIX: should check to make sure it is only (Roman?) letters + then: [t: "P"] # Add inline indicator + - x: "*" - name: empty-mrow @@ -231,13 +212,70 @@ name: trig-functions tag: mrow match: "count(*)=3 and *[2]='\u2061' and - IsInDefinition(BaseNode(*[1]), 'Braille', 'TrigFunctionNames') and not(IsBracketed(*[3], '(', ')'))" + (IsInDefinition(BaseNode(*[1]), 'Braille', 'TrigFunctionNames') or BaseNode(*[1]) = 'lim') and not(IsBracketed(*[3], '(', ')'))" replace: - x: "*[1]" - - t: "⠰" - - x: "*[3]" - - t: "⠆" + - test: + # p51 -- use short form for (some) trig functions; always group unless short form and no grouping needed + if: "not($French_UseShortForm and IsInDefinition(BaseNode(*[1]), 'Braille', 'ShortForms')) or + NeedsToBeGrouped(*[3], 'French', true())" + then: + - t: "o" + - x: "*[3]" + - t: "c" + else: + - x: "*[3]" + +# - +# name: binomial-frac +# tag: mrow +# match: "IsBracketed(., '(', ')') and *[2][self::m:mfrac][@linethickness=0]" +# replace: +# - x: "*[1]" +# - x: "*[2]/*[1]" +# - t: "⠰⠻" +# - x: "*[2]/*[2]" +# - x: "*[3]" + +# - name: binomial-table +# tag: mrow +# match: "IsBracketed(., '(', ')') and *[2][self::m:mtable][count(*)=2 and count(*[1])=1] and contains(@intent, 'binomial(')" +# replace: +# - x: "*[1]" +# - x: "*[2]/*[1]/*[1]/*[1]" +# - t: "⠰⠻" +# - x: "*[2]/*[2]/*[1]/*[1]" +# - x: "*[3]" + +- + # integral rules -- need to group the integrand (but not the 'd x') + # we look for what follows the integral and check for 'd' in the next to last element and group what comes before it (assuming there is more than one element) + # note: we need to skip the invisible times when checking for 'd' + name: integrals + tag: mrow + match: "BaseNode(*[1])[translate(., '∫∬∭∮', '')=''] and + *[2][self::m:mrow][count(*)>5 and *[last()-2][self::m:mi][.='d' or .='ⅆ']]" + replace: + - x: "*[1]" + - t: "o" + - x: "*[2]/*[position() <= last()- 4]" + - t: "c" + - x: "*[2]/*[last()-2]" + - x: "*[2]/*[last()]" +- + # grouping rules -- need to add grouping symbols for some cases + name: function-call + tag: mrow + # we include invisible times in the match because some AbbreviationsForGrouping are not function names + match: "count(*)=3 and *[2][self::m:mo][.='\u2061'or .='\u2062'] and + not(*[3][self::m:mrow][IsBracketed(., '(', ')') or IsBracketed(., '[', ']')]) and + *[1][self::m:mi][IsInDefinition(., 'Braille', 'TrigFunctionNames') or IsInDefinition(., 'Braille', 'AbbreviationsForGrouping')]" + replace: + - x: "*[1]" + - t: "o" + - x: "DEBUG(*[3])" + - t: "c" - name: default @@ -269,23 +307,11 @@ - x: "text()" - - name: default - tag: mo - # add spaces around comparison operators unless they are in a script position, - variables: # ratio not spaced in UEB; also make sure it is an infix operator (e.g., "~" can be prefix) - - AddSpaces: "$UEB_UseSpacesAroundAllOperators" - match: "." - replace: - - test: - if: "$AddSpaces" - then: - - test: - if: "preceding-sibling::*" - then: [t: "W"] - - x: "text()" - - test: - if: "$AddSpaces and following-sibling::*" - then: [t: "W"] + name: default + tag: mo + match: "." + replace: + - x: "text()" - @@ -299,7 +325,10 @@ tag: [mi, mtext] match: "." replace: - - x: "BrailleChars(., 'French')" + - test: + if: "$French_UseShortForm and IsInDefinition(., 'Braille', 'ShortForms')" + then: [x: "BrailleChars(DefinitionValue(., 'Braille', 'ShortForms'), 'French')"] + else: [x: "BrailleChars(., 'French')"] - name: default @@ -333,23 +362,13 @@ - # special hack to catch double over/under bar built from nested mover/munder name: doubled-line-hack-exception - tag: [mover, munder] + tag: mover match: - "*[2][self::m:mo and string-length(.) = 1 and (.='¯')] and" # has line/bar - - "( (self::m:mover and *[1][self::m:mover]) or (self::m:munder and *[1][self::m:munder]) ) and" # both mover/munder - - "*[1]/*[2][self::m:mo and string-length(.) = 1 and (.='¯')]" # other mover/munder has line/bar + - "(*[1][self::m:mover] and *[1]/*[2][self::m:mo and string-length(.) = 1 and (.='¯')])" replace: - - test: - if: "self::m:munder" - then: [t: "⠨"] - t: "⠘⠸⠒" - - test: - if: "NeedsToBeGrouped(*[1], 'French', true())" - then: - - t: "⠰" - - x: "*[1]" - - t: "⠆" - else: [x: "*[1]"] + - x: "*[1]" - name: single-char-exceptions # GTM 12 @@ -377,9 +396,9 @@ # - test: # if: "NeedsToBeGrouped(*[1], 'French', true())" # then: - # - t: "⠰" + # - t: "o" # - x: "*[1]" - # - t: "⠆" + # - t: "c" # else: [x: "*[1]"] - x: "*[1]" @@ -390,55 +409,55 @@ # We combine them here name: single-char-exceptions tag: [msub, msup] - match: "(self::m:msub and @data-chem-formula) or (self::m:msup and *[2][translate(., \"'′″‴\",'')=''])" + match: "(@data-chem-formula) or (self::m:msup and *[2][translate(., \"'′″‴\",'')=''])" replace: + - x: "*[1]" - test: - if: "NeedsToBeGrouped(*[1], 'French', true())" + # we need to group an operator if it is followed by an operator (see p9 of chem spec) -- don't want 2 "+"s in a row + # it is a bit tricky, we used following and preceding because it might be at a different level of the tree + if: "@data-chem-formula and *[2][self::m:mo] and following::*[1][self::m:mo and .=preceding::*[1]]" then: - - t: "⠰" - - x: "*[1]" - - t: "⠆" - else: [x: "*[1]"] + - t: "o" + - x: "*[2]" + - t: "c" + else: [x: "*[2]"] + +- + name: single-char-exceptions + tag: [mover] + match: "*[2][translate(., \"⏜^→⇀¯⌣◌̌~\",'')='']" + replace: - x: "*[2]" + - x: "*[1]" - name: default tag: [msub, msup, munder, mover] match: "." - variables: [AddSpaces: "(self::m:munder or self::m:mover) and IsInDefinition(BaseNode(*[1]), 'Braille', 'NemethComparisonOperators')"] replace: - test: - if: "$AddSpaces" - then: [t: "W"] - - test: - if: "NeedsToBeGrouped(*[1], 'French', self::m:msub or self::m:msup)" + if: "(self::m:munder or self::m:mover) and NeedsToBeGrouped(*[1], 'French', true())" then: - - t: "⠰" + - t: "o" - x: "*[1]" - - t: "⠆" + - t: "c" else: [x: "*[1]"] - - with: # this could be tighter and be just around the *[2] part, but this is consistent with msubsup below - variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string - replace: - - test: - - if: "self::m:msup" - then: [t: "⠈"] - - else_if: "self::m:msub" - then: [t: "⠢"] - - else_if: "self::m:munder" - then: [t: "⠢⠢"] - else: [t: "⠈⠈"] # mover - - test: - if: "NeedsToBeGrouped(*[2], 'French', false())" - then: - - t: "⠰" - - x: "*[2]" - - t: "⠆" - else: [x: "*[2]"] - - t: "#" # signal end script/numeric mode - test: - if: "$AddSpaces" - then: [t: "W"] + - if: "self::m:msup" + then: [t: "⠈"] + - else_if: "self::m:msub" + then: [t: "⠢"] + - else_if: "self::m:munder" + then: [t: "⠢⠢"] + else: [t: "⠈⠈"] # mover + - test: + if: "DEBUG(NeedsToBeGrouped(*[2], 'French', false()))" + then: + - t: "o" + - x: "*[2]" + - t: "c" + else: [x: "*[2]"] + - t: "#" # signal end script/numeric mode @@ -448,44 +467,35 @@ match: "count(*)=3" # catches mmultiscripts equiv variables: [IsPrimeSuperScript: "not(self::m:munderover) and *[3][translate(., \"'′″‴\",'')='']"] replace: - - test: - if: "NeedsToBeGrouped(*[1], 'French', self::m:msubsup)" - then: - - t: "⠰" - - x: "*[1]" - - t: "⠆" - else: [x: "*[1]"] + - x: "*[1]" - test: if: "$IsPrimeSuperScript" then: [x: "*[3]"] - - with: - variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string - replace: + - test: + if: "self::m:munderover" + then: [t: "⠢⠢"] + else: [t: "⠢"] + - test: + if: "DEBUG(NeedsToBeGrouped(*[2], 'French', false()))" + then: + - t: "o" + - x: "*[2]" + - t: "c" + else: [x: "*[2]"] + - test: + if: "not($IsPrimeSuperScript)" + then: - test: if: "self::m:munderover" - then: [t: "⠢⠢"] - else: [t: "⠢"] - - test: - if: "NeedsToBeGrouped(*[2], 'French', false())" - then: - - t: "⠰" - - x: "*[2]" - - t: "⠆" - else: [x: "*[2]"] + then: [t: "⠈⠈"] + else: [t: "⠈"] - test: - if: "not($IsPrimeSuperScript)" + if: "NeedsToBeGrouped(*[3], 'French', false())" then: - - test: - if: "self::m:munderover" - then: [t: "⠈⠈"] - else: [t: "⠈"] - - test: - if: "NeedsToBeGrouped(*[3], 'French', false())" - then: - - t: "⠰" - - x: "*[3]" - - t: "⠆" - else: [x: "*[3]"] + - t: "o" + - x: "*[3]" + - t: "c" + else: [x: "*[3]"] - @@ -498,31 +508,25 @@ - test: if: "not(*[3][self::m:none])" then: - - with: - variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string - replace: - - t: "⠠⠢" - - test: - if: "NeedsToBeGrouped(*[3], 'French', true())" - then: - - t: "⠰" - - x: "*[3]" - - t: "⠆" - else: [x: "*[3]"] + - t: "⠠⠢" + - test: + if: "NeedsToBeGrouped(*[3], 'French', true())" + then: + - t: "o" + - x: "*[3]" + - t: "c" + else: [x: "*[3]"] - test: if: "not(*[4][self::m:none])" then: - - with: - variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string - replace: - - t: "⠠⠈" - - test: - if: "NeedsToBeGrouped(*[4], 'French', false())" - then: - - t: "⠰" - - x: "*[4]" - - t: "⠆" - else: [x: "*[4]"] + - t: "⠠⠈" + - test: + if: "NeedsToBeGrouped(*[4], 'French', false())" + then: + - t: "o" + - x: "*[4]" + - t: "c" + else: [x: "*[4]"] - name: default @@ -540,62 +544,50 @@ - test: if: "not($Prescripts[1][self::m:none])" then: - - with: - variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string - replace: - - t: "⠢" - - test: - if: "NeedsToBeGrouped($Prescripts[1], 'French', true())" - then: - - t: "⠰" - - x: "$Prescripts[1]" - - t: "⠆" - else: [x: "$Prescripts[1]"] + - t: "⠢" + - test: + if: "NeedsToBeGrouped($Prescripts[1], 'French', true())" + then: + - t: "o" + - x: "$Prescripts[1]" + - t: "c" + else: [x: "$Prescripts[1]"] - test: if: "not($Prescripts[2][self::m:none])" then: - - with: - variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string - replace: - - t: "⠈" - - test: - if: "NeedsToBeGrouped($Prescripts[2], 'French', false())" - then: - - t: "⠰" - - x: "$Prescripts[2]" - - t: "⠆" - else: [x: "$Prescripts[2]"] + - t: "⠈" + - test: + if: "NeedsToBeGrouped($Prescripts[2], 'French', false())" + then: + - t: "o" + - x: "$Prescripts[2]" + - t: "c" + else: [x: "$Prescripts[2]"] - test: if: "count($Prescripts)>2" then: - test: if: "not($Prescripts[3][self::m:none])" then: - - with: - variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string - replace: - - t: "⠢" - - test: - if: "NeedsToBeGrouped($Prescripts[3], 'French', false())" - then: - - t: "⠰" - - x: "$Prescripts[3]" - - t: "⠆" - else: [x: "$Prescripts[3]"] + - t: "⠢" + - test: + if: "NeedsToBeGrouped($Prescripts[3], 'French', false())" + then: + - t: "o" + - x: "$Prescripts[3]" + - t: "c" + else: [x: "$Prescripts[3]"] - test: if: "not($Prescripts[4][self::m:none])" then: - - with: - variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string - replace: - - t: "⠈" - - test: - if: "NeedsToBeGrouped($Prescripts[4], 'French', false())" - then: - - t: "⠰" - - x: "$Prescripts[4]" - - t: "⠆" - else: [x: "$Prescripts[4]"] + - t: "⠈" + - test: + if: "NeedsToBeGrouped($Prescripts[4], 'French', false())" + then: + - t: "o" + - x: "$Prescripts[4]" + - t: "c" + else: [x: "$Prescripts[4]"] - test: if: "count($Prescripts) > 4" # give up and just dump them out so at least the content is there then: [x: "$Prescripts[position() > 4]"] @@ -607,124 +599,100 @@ - test: if: "not($Postscripts[1][self::m:none])" then: - - with: - variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string - replace: - - t: "⠢" - - test: - if: "NeedsToBeGrouped($Postscripts[1], 'French', false())" - then: - - t: "⠰" - - x: "$Postscripts[1]" - - t: "⠆" - else: [x: "$Postscripts[1]"] + - t: "⠢" + - test: + if: "NeedsToBeGrouped($Postscripts[1], 'French', false())" + then: + - t: "o" + - x: "$Postscripts[1]" + - t: "c" + else: [x: "$Postscripts[1]"] - test: if: "not($Postscripts[2][self::m:none])" then: - - with: - variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string - replace: - - t: "⠈" - - test: - if: "NeedsToBeGrouped($Postscripts[2], 'French', false())" - then: - - t: "⠰" - - x: "$Postscripts[2]" - - t: "⠆" - else: [x: "$Postscripts[2]"] + - t: "⠈" + - test: + if: "NeedsToBeGrouped($Postscripts[2], 'French', false())" + then: + - t: "o" + - x: "$Postscripts[2]" + - t: "c" + else: [x: "$Postscripts[2]"] - test: if: "count($Postscripts)>2" then: - test: if: "not($Postscripts[3][self::m:none])" then: - - with: - variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string - replace: - - t: "⠢" - - test: - if: "NeedsToBeGrouped($Postscripts[3], 'French', false())" - then: - - t: "⠰" - - x: "$Postscripts[3]" - - t: "⠆" - else: [x: "$Postscripts[3]"] + - t: "⠢" + - test: + if: "NeedsToBeGrouped($Postscripts[3], 'French', false())" + then: + - t: "o" + - x: "$Postscripts[3]" + - t: "c" + else: [x: "$Postscripts[3]"] - test: if: "not($Postscripts[4][self::m:none])" then: - - with: - variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string - replace: - - t: "⠈" - - test: - if: "NeedsToBeGrouped($Postscripts[4], 'French', false())" - then: - - t: "⠰" - - x: "$Postscripts[4]" - - t: "⠆" - else: [x: "$Postscripts[4]"] + - t: "⠈" + - test: + if: "NeedsToBeGrouped($Postscripts[4], 'French', false())" + then: + - t: "o" + - x: "$Postscripts[4]" + - t: "c" + else: [x: "$Postscripts[4]"] - test: if: "count($Postscripts)>4" then: - test: if: "not($Postscripts[5][self::m:none])" then: - - with: - variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string - replace: - - t: "⠢" - - test: - if: "NeedsToBeGrouped($Postscripts[5], 'French', false())" - then: - - t: "⠰" - - x: "$Postscripts[5]" - - t: "⠆" - else: [x: "$Postscripts[5]"] + - t: "⠢" + - test: + if: "NeedsToBeGrouped($Postscripts[5], 'French', false())" + then: + - t: "o" + - x: "$Postscripts[5]" + - t: "c" + else: [x: "$Postscripts[5]"] - test: if: "not($Postscripts[6][self::m:none])" then: - - with: - variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string - replace: - - t: "⠈" - - test: - if: "NeedsToBeGrouped($Postscripts[6], 'French', false())" - then: - - t: "⠰" - - x: "$Postscripts[6]" - - t: "⠆" - else: [x: "$Postscripts[6]"] + - t: "⠈" + - test: + if: "NeedsToBeGrouped($Postscripts[6], 'French', false())" + then: + - t: "o" + - x: "$Postscripts[6]" + - t: "c" + else: [x: "$Postscripts[6]"] - test: if: "count($Postscripts)>6" then: - test: if: "not($Postscripts[7][self::m:none])" then: - - with: - variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string - replace: - - t: "⠢" - - test: - if: "NeedsToBeGrouped($Postscripts[7], 'French', false())" - then: - - t: "⠰" - - x: "$Postscripts[7]" - - t: "⠆" - else: [x: "$Postscripts[7]"] + - t: "⠢" + - test: + if: "NeedsToBeGrouped($Postscripts[7], 'French', false())" + then: + - t: "o" + - x: "$Postscripts[7]" + - t: "c" + else: [x: "$Postscripts[7]"] - test: if: "not($Postscripts[8][self::m:none])" then: - - with: - variables: [NewScriptContext: "in"] # value doesn't matter -- just can't be empty string - replace: - - t: "⠈" - - test: - if: "NeedsToBeGrouped($Postscripts[8], 'French', false())" - then: - - t: "⠰" - - x: "$Postscripts[8]" - - t: "⠆" - else: [x: "$Postscripts[8]"] + - t: "⠈" + - test: + if: "NeedsToBeGrouped($Postscripts[8], 'French', false())" + then: + - t: "o" + - x: "$Postscripts[8]" + - t: "c" + else: [x: "$Postscripts[8]"] - test: if: "count($Postscripts) > 8" # give up and just dump them out so at least the content is there then: @@ -754,7 +722,6 @@ tag: menclose match: "." # FIX: can't find a rule that says anything about comparison operator spacing and enclosure - variables: [AddSpaces: "parent::*[self::m:mrow] and *[1][ self::m:mo and IsInDefinition(., 'Braille', 'NemethComparisonOperators')]"] replace: - test: if: "contains(concat(' ', normalize-space(@notation), ' '), ' left ')" #avoid 'leftarrow' @@ -762,16 +729,10 @@ - test: if: "contains(@notation,'box')" # box and roundedbox then: - # - test: - # if: "$AddSpaces" - # then: [t: " "] - t: "1⠫⠼⠙" # square (no rectangle in UEB) - test: if: "contains(@notation,'circle')" then: - # - test: - # if: "$AddSpaces" - # then: [t: " "] - t: "1⠫⠿" # circle (no oval in UEB) # ??? What should happen with arrow? # If there is a box/circle with arrows only and an empty child, @@ -825,9 +786,9 @@ - test: if: "NeedsToBeGrouped(*[1], 'French', false())" then: - - t: "⠰" + - t: "o" - x: "*[1]" - - t: "⠆" + - t: "c" else: [x: "*[1]"] # - test: @@ -874,13 +835,10 @@ - t: "1⠈⠱" # cancellation - test: if: - - "not($AddSpaces) and contains(@notation,'box') or contains(@notation,'circle') or" + - "contains(@notation,'box') or contains(@notation,'circle') or" - "contains(@notation,'arrow') or contains(@notation,'phasorangle')" then: - t: "⠻" # terminate shape - # - test: - # if: "$AddSpaces" - # then: [t: " "] - test: if: "contains(concat(' ', normalize-space(@notation), ' '), ' right ')" #avoid 'rightarrow' then: [t: "⠸"] diff --git a/Rules/Braille/French/definitions.yaml b/Rules/Braille/French/definitions.yaml index 4d0c77efb..332abd498 100644 --- a/Rules/Braille/French/definitions.yaml +++ b/Rules/Braille/French/definitions.yaml @@ -1,2 +1,20 @@ --- - include: "../definitions.yaml" + +- AbbreviationsForGrouping: { + "arg", "Card", "rot", + "arcsin", "arccos", "arctan", "arccotan", + "ch", "sh", "th", + } + +- ShortForms: { + # p51 -- short forms for trig functions + # This uses a hack of private space chars that are then mapped to braille chars via unicode.yaml. + # We need to do this because otherwise it tries to translate the short form. + # ⠬ -> \ue000 + # ⠨ -> \ue001 + # ⠮ -> \ue002 + # ⠘ -> \ue003 + "sin": "\ue000", cos: "\ue001\ue000", tan: "\ue002", "cotan": "\ue001\ue002", + arcsin: "\ue003\ue000", arccos: "\ue003\ue001\ue002", arctan: "\ue003\ue002", arccotan: "\ue003\ue001\ue002", + } \ No newline at end of file diff --git a/Rules/Braille/French/unicode-full.yaml b/Rules/Braille/French/unicode-full.yaml index 91054d0cb..2f6ecc9b0 100644 --- a/Rules/Braille/French/unicode-full.yaml +++ b/Rules/Braille/French/unicode-full.yaml @@ -1,7 +1,7 @@ --- - - "⇌": [t: "⠸⠻"] # 0x21CC (Rightwards harpoon over leftwards harpoon (equilibrium)) -# - "⥂": [t: ""] # 0x2942 (Rightwards arrow above short leftwards arrow (equilibrium, trend to the right)) + - "⇌": [t: "⠸⠻"] # 0x21CC (Rightwards harpoon over leftwards harpoon (equilibrium)) +# - "⥂": [t: ""] # 0x2942 (Rightwards arrow above short leftwards arrow (equilibrium, trend to the right)) # - "⥄": [t: ""] # 0x2944 (Short rightwards arrow above leftwards arrow (equilibrium, trend to the left)) # Mappings for some new Unicode chemistry arrows/symbols diff --git a/Rules/Braille/French/unicode.yaml b/Rules/Braille/French/unicode.yaml index e37c31f40..0105b376e 100644 --- a/Rules/Braille/French/unicode.yaml +++ b/Rules/Braille/French/unicode.yaml @@ -42,7 +42,22 @@ - "w": [t: "L⠺"] # 0x77 - "x": [t: "L⠭"] # 0x78 - "y": [t: "L⠽"] # 0x79 - - "z": [t: "L⠵"] # 0x7a + - "z": [t: "L⠵"] # 0x7a + + - "ç": [t: "L⠯"] # 0x282f + - "é": [t: "L⠿"] # 0x283f + - "à": [t: "L⠷"] # 0x2837 + - "è": [t: "L⠮"] # 0x282e + - "ù": [t: "L⠾"] # 0x283e + - "â": [t: "L⠡"] # 0x2821 + - "ê": [t: "L⠣"] # 0x2823 + - "î": [t: "L⠩"] # 0x2829 + - "ô": [t: "L⠹"] # 0x2839 + - "û": [t: "L⠱"] # 0x2831 + - "ë": [t: "L⠫"] # 0x282b + - "ï": [t: "L⠻"] # 0x283b + - "ü": [t: "L⠳"] # 0x2833 + - "œ": [t: "L⠪"] # 0x282a - "A": [t: "CL⠁"] # 0x41 - "B": # 0x42 @@ -190,6 +205,7 @@ - "%": [t: "⠐⠬"] # 0x0025 (percent sign) - "(": [t: "⠦"] # 0x0028 (left parenthesis) - ")": [t: "⠴"] # 0x0029 (right parenthesis) + - "*": [t: "⠐⠔"] # 0x002A (asterisk) - "+": [t: "⠖"] # 0x002B (regular plus) - ",": [t: "⠂"] # 0x002C (comma) - "-": [t: "⠤"] # 0x002D (regular minus) @@ -206,11 +222,13 @@ - "8": [t: "N⠳"] # 0x0038 (digit eight) - "9": [t: "N⠪"] # 0x0039 (digit nine) - ":": [t: "⠒"] # 0x003A (colon) + - ";": [t: "⠆"] # 0x003B (semicolon) - "<": [t: "⠐⠣"] # 0x003C (less than sign) - "=": [t: "⠶"] # 0x003D (regular equals sign) - ">": [t: "⠐⠜"] # 0x003E (greater than sign ( regular )) - "[": [t: "⠷"] # 0x005B (left square bracket) - "]": [t: "⠾"] # 0x005D (right square bracket) + - "^": [t: "⠘⠒"] # 0x005E (caret) - "{": # 0x007B ( left curly brace) - test: if: "following-sibling::*[1][self::m:mtable]" @@ -221,8 +239,9 @@ else: [t: "⠨⠦"] # regular brace - "|": [t: "⠿"] # 0x007C (vertical bar) - "}": [t: "⠨⠴"] # 0x007D (right curly brace) - - "~": [t: "⠘⠶"] # 0x007E (simple tilde (is related to, is similar)) + - "~": [t: "⠐⠸⠒"] # 0x007E (simple tilde (is related to, is similar)) - "¢": [t: "⠉"] # 0x00A2 (cent) + - "¯": [t: "⠸⠒"] # 0x00AF (bar) - "°": [t: "⠐⠕"] # 0x00B0 (degree sign) - "±": [t: "⠖⠤"] # 0x00B1 (plus or minus) - "¼": [t: "⠡⠌⠹"] # 0x00BC (vulgar fraction one quarter) @@ -233,6 +252,7 @@ - "ב": [t: "⠘⠘⠃"] # 0x05D1 ( beth) - "ג": [t: "⠘⠘⠛"] # 0x05D2 (gimel) - "ד": [t: "⠘⠘⠙"] # 0x05D3 (daleth) + - "◌̌": [t: "⠸⠘⠒"] # 0x030C (combing caron) - "‖": [t: "⠘⠿"] # 0x2016 (double vertical bar) - "‰": [t: "⠐⠬⠬"] # 0x2030 (per mille sign) - "′": [t: "⠄"] # 0x2032 (prime) @@ -243,7 +263,17 @@ - "ℵ": [t: "⠘⠘⠁"] # 0x2135 (alef) - "←": [t: "⠸⠪"] # 0x2190 (left pointing arrow) - "↑": [t: "⠘⠻"] # 0x2191 (arrow pointing up) - - "→": [t: "⠸⠱"] # 0x2192 (left pointing arrow) + - "→": # 0x2192 (right pointing arrow) + - test: + if: "parent::m:mover and not(following-sibling::*)" + then: [t: "⠨⠒"] + else: [t: "⠸⠱"] + - "⇀": # 0x2192 (right pointing arrow) + - test: + if: "parent::m:mover and not(following-sibling::*)" + then: [t: "⠨⠒"] + else: [t: "⠸⠱"] + - "↓": [t: "⠨⠻"] # 0x2193 (arrow pointing down) - "↔": [t: "⠐⠻"] # 0x2194 (horizontal two-way arrow) - "↖": [t: "⠘⠪"] # 0x2196 (north west arrow) @@ -275,7 +305,9 @@ - "∓": [t: "⠤⠖"] # 0x2213 (minus or plus) - "∘": [t: "⠸⠼"] # 0x2218 (hollow dot) - "∞": [t: "⠘⠉"] # 0x221E (infinity) - - "∥": [t: "⠸⠳"] # 0x2225 (is parallel to) + - "⋯": [t: "⠲⠲⠲"] # 0x22EF (horizontal ellipsis) + - "∥": [t: "⠘⠿"] # 0x2225 (is parallel to, but French braille uses this for magnitude, etc) + - "⫽": [t: "⠸⠳"] # 0x2A7D (DOUBLE SOLIDUS OPERATOR, but French braille uses this for parallel to sign) - "∧": [t: "⠘⠔"] # 0x2227 (logical product (and, meet)) - "∨": [t: "⠘⠢"] # 0x2228 (logical sum (join,or)) - "∩": [t: "⠘⠖"] # 0x2229 (intersection sign ( cap )) @@ -308,10 +340,18 @@ - "⊕": [t: "⠨⠖"] # 0x2295 (circle with interior plus sign (exclusive or, direct sum, diletion)) - "⊗": [t: "⠨⠔"] # 0x2297 (circle with interior cross (tensor product)) - "⊥": [t: "⠘⠳"] # 0x22A5 (is perpendicular to) - - "⋅": [t: "⠔⠔"] # 0x22C5 (dot,and times) + - "⋅": [t: "⠔⠔"] # 0x22C5 (dot,and times) - "⌄": [t: "⠸⠘⠒"] # 0x2304 (inverted caret) + - "⌣": [t: "⠈⠈⠈"] # 0x2323 (smile) - "⏜": [t: "⠈⠒"] # 0x23DC (arc concave upward) - "△": [t: "⠨⠘⠙"] # 0x25B3 (increment (laplacian Delta) ) - "✕": [t: "⠐⠐⠔"] # 0x2715 (multiplication X) - "⟧": [t: "⠨⠾"] # 0x27E7 (right barred bracket) - "⪥": [t: "⠐⠜⠐⠣"] # 0x2AA5 (greater than sign followed by less than sign) + - "⫽": [t: "⠸⠳"] # 0x2A7D (DOUBLE SOLIDUS OPERATOR) + +# Private space chars used for short forms for trig functions + - "\ue000": [t: "L⠬"] + - "\ue001": [t: "L⠨"] + - "\ue002": [t: "L⠮"] + - "\ue003": [t: "L⠘"] \ No newline at end of file diff --git a/Rules/prefs.yaml b/Rules/prefs.yaml index 38fc22efc..395583be8 100644 --- a/Rules/prefs.yaml +++ b/Rules/prefs.yaml @@ -95,6 +95,8 @@ LaTeX: UseShortName: false # Use the short form for the latex (e.g., "~a" instead of "\alpha") + French: + UseShortForm: false # Use the short form for trig functions and other abbreviations Other: # Note: DecimalSeparator is user-facing (can be Auto), DecimalSeparators is code-facing (always a char) diff --git a/src/braille.rs b/src/braille.rs index a4d6395e8..73cb6c5c8 100644 --- a/src/braille.rs +++ b/src/braille.rs @@ -2278,84 +2278,53 @@ fn swedish_cleanup(pref_manager: Ref, raw_braille: String) -> } static FRENCH_INDICATOR_REPLACEMENTS: phf::Map<&str, &str> = phf_map! { - // FIX: this needs to be fully checked against the French spec - // FIX: this needs cleaning up -- not all of these are used + // Keys match indicator chars emitted by French unicode.yaml, unicode-full.yaml, and French_Rules.yaml "S" => "XXX", // sans-serif -- from prefs "B" => "⠸", // bold - "𝔹" => "XXX", // blackboard -- from prefs + "𝔹" => "⠨", // blackboard -- from prefs "T" => "⠈", // script "I" => "⠸", // italic - "R" => "", // roman - "E" => "⠰", // English "1" => "⠀", // Grade 1 symbol (used for number followed by a letter) "L" => "", // Letter left in to assist in locating letters "D" => "XXX", // German (Deutsche) -- from prefs "G" => "⠘", // Greek - "V" => "XXX", // Greek Variants - // "H" => "⠠⠠", // Hebrew - // "U" => "⠈⠈", // Russian "C" => "⠨", // capital - "𝑐" => "", // second or latter braille cell of a capital letter "𝐶" => "⠨", // capital that never should get whitespace in front (from chemical element) "N" => "", // number indicator - "n" => "", // number indicator for drop numbers (special case with close parens) - "t" => "⠱", // shape terminator "W" => "⠀", // whitespace" - "𝐖"=> "⠀", // whitespace "s" => "⠆", // typeface single char indicator - "w" => "", // typeface word indicator - "e" => "", // typeface & capital terminator - "," => "⠂", // comma - "." => "⠲", // period - "-" => "-", // hyphen - "—" => "⠠⠤", // normal dash (2014) -- assume all normal dashes are unified here [RUEB appendix 3] - "―" => "⠐⠠⠤", // long dash (2015) -- assume all long dashes are unified here [RUEB appendix 3] - "(" => "⠦", // Not really needed, but done for consistancy with ")" - ")" => "⠴", // Needed for rules with drop numbers to avoid mistaking for dropped 0 - "↑" => "⠬", // superscript - "↓" => "⠡", // subscript + "o" => "⠰", // Opening group indicator + "c" => "⠆", // Closing group indicator + "P" => "⠠⠄", // Math modifier and code change indicator "#" => "", // signals end of script - "Z" => "⠐", // signals end of index of root, integrand/lim from function ("zone change") - }; -fn french_cleanup(pref_manager: Ref, raw_braille: String) -> String { +fn french_cleanup(_pref_manager: Ref, raw_braille: String) -> String { // FIX: need to implement this -- this is just a copy of the Vietnam code - // Empty bases are ok if they follow whitespace - static EMPTY_BASE: LazyLock = LazyLock::new(|| Regex::new(r"(^|[W𝐖w])E").unwrap()); + static REPLACE_INDICATORS: LazyLock = LazyLock::new(|| Regex::new(r"([1SB𝔹TILDGC𝐶NWsc#oc])").unwrap()); debug!("french_cleanup: start={}", raw_braille); // let result = typeface_to_word_mode(&raw_braille); // let result = capitals_to_word_mode(&result); - let result = raw_braille.replace("CG", "⠘") - .replace("𝔹C", "⠩") - .replace("DC", "⠰"); - - debug!(" after typeface/caps={}", &result); - - // these typeforms need to get pulled from user-prefs as they are transcriber-defined - let double_struck = pref_manager.pref_to_string("Vietnam_DoubleStruck"); - let sans_serif = pref_manager.pref_to_string("Vietnam_SansSerif"); - let fraktur = pref_manager.pref_to_string("Vietnam_Fraktur"); - let greek_variant = pref_manager.pref_to_string("Vietnam_GreekVariant"); + // check to see if math modifier and code change indicator are needed at start (p8) + let result = if raw_braille.starts_with("P") { + let prefix = if raw_braille.contains("o") { "⠠⠄" } else { "⠠" }; + let mut new_string = String::with_capacity(raw_braille.len() - 1 + prefix.len()); + new_string.push_str(prefix); + new_string.push_str(&raw_braille[1..]); + new_string + } else { + raw_braille + }; // This reuses the code just for getting rid of unnecessary "L"s and "N"s let result = remove_unneeded_mode_changes(&result, UEB_Mode::Grade1, UEB_Duration::Passage); debug!(" after removing mode changes={}", &result); - - let result = EMPTY_BASE.replace_all(&result, "$1"); let result: Cow<'_, str> = REPLACE_INDICATORS.replace_all(&result, |cap: &Captures| { - let matched_char = &cap[0]; - match matched_char { - "𝔹" => &double_struck, - "S" => &sans_serif, - "D" => &fraktur, - "V" => &greek_variant, - _ => match FRENCH_INDICATOR_REPLACEMENTS.get(matched_char) { - None => {error!("REPLACE_INDICATORS and FRENCH_INDICATOR_REPLACEMENTS are not in sync: missing '{}'", matched_char); ""}, + match FRENCH_INDICATOR_REPLACEMENTS.get(&cap[0]) { + None => {error!("REPLACE_INDICATORS and FRENCH_INDICATOR_REPLACEMENTS are not in sync: missing '{}'", &cap[0]); ""}, Some(&ch) => ch, - }, } }); @@ -3054,80 +3023,56 @@ impl NeedsToBeGrouped { } } - // ordinals often have an irregular start (e.g., "half") before becoming regular. - // if the number is irregular, return the ordinal form, otherwise return 'None'. - /// FIX: what needs to be implemented? - fn needs_grouping_for_french(mathml: Element, is_base: bool) -> bool { - use crate::xpath_functions::IsInDefinition; - let mut node_name = name(mathml); - if mathml.attribute_value("data-roman-numeral").is_some() { - node_name = "mi"; // roman numerals don't follow number rules - } + fn needs_grouping_for_french(mathml: Element, _is_base: bool) -> bool { + // French rules are from p26: Blocks (also mentioned elsewhere in the spec) + // if we have a "- xxx", we treat the MathML as if it were just "xxx". + // apparently, based on function_partial_derivative_14_1_04, the same goes for '∂' -- generalizing to all prefix ops... + // use crate::xpath_functions::IsInDefinition; + let mut children = mathml.children(); + let mathml = if name(mathml) == "mrow" && children.len() == 2 && + name(as_element(children[0])) == "mo" { // assuming it is a prefix op since it starts an mrow + let operand_child = as_element(children[1]); + children = operand_child.children(); + operand_child + } else { + mathml + }; + let node_name = name(mathml); + // let parent = get_parent(mathml); // there is always a "math" node because we never ask if its children need grouping + // let parent_name = name(parent); - // FIX: the leaf rules are from UEB -- check the French rules + debug!("needs_grouping_for_french: mathml (sans '-') = {}", mml_to_string(mathml)); match node_name { - "mn" => { - if !is_base { - return false; - } // clause 1 - // two 'mn's can be adjacent, in which case we need to group the 'mn' to make it clear it is separate (see bug #204) - let parent = get_parent(mathml); // there is always a "math" node - let grandparent = if name(parent) == "math" {parent} else {get_parent(parent)}; - if name(grandparent) != "mrow" { - return false; - } - let preceding = parent.preceding_siblings(); - if preceding.len() < 2 { - return false; - } - // any 'mn' would be separated from this node by invisible times - let previous_child = as_element(preceding[preceding.len()-1]); - if name(previous_child) == "mo" && as_text(previous_child) == "\u{2062}" { - let previous_child = as_element(preceding[preceding.len()-2]); - return name(previous_child) == "mn" - } else { - return false; - } + "mn" | "mi" | "mtext" => { + return as_text(mathml).contains(char::is_whitespace); }, - "mo" => { - return !is_base; // if in script, then what follows is assumed to be an operand in braille, but it isn't, so add grouping - }, - "mi" | "mtext" => { - let text = as_text(mathml); - let parent = get_parent(mathml); // there is always a "math" node - let parent_name = name(parent); - return text.chars().count() > 1 && - parent_name != "mrow" && - !IsInDefinition::is_defined_in(text, &SPEECH_DEFINITIONS, "FunctionNames").unwrap(); + "mo" => { return as_text(mathml).chars().nth(1).is_some(); }, // guessing that single chars operator don't need grouping based on set_not_belong_tor_6_4_04 + "ms" => { + return false; // FIX: is this true? Do quotes group the contents? }, "mrow" => { - // check for bracketed exprs - if IsBracketed::is_bracketed(mathml, "", "", false, true) { + if IsBracketed::is_bracketed(mathml, "", "", false, false) { return false; } - - // check for prefix at start - // example 7.12 has "2-" in superscript and is grouped, so we don't consider postfix ops - let children = mathml.children(); - if children.len() == 2 && - (name( as_element(children[0])) == "mo") { + // look for "a", "a b", etc -- last example on p26 shows "b d" doesn't need grouping + // also apparently brackets are also acceptable (see last example on p43 where numerator isn't grouped) + if children.iter().enumerate().all(|(i, &child)| { + let child = as_element(child); + if i % 2 == 1 { + name(child) == "mo" && as_text(child) == "\u{2062}" // invisible times + } else { + name(child) == "mi" || (name(child) == "mrow" && IsBracketed::is_bracketed(child, "", "", false, false)) + } + }) { return false; } - - if children.len() == 3 { - let child0 = as_element(children[0]); - let operator = as_element(children[1]); // invisible function op? - // debug!("needs_grouping_for_french: child0 ="); - if name(operator) == "mo" && as_text(operator) == "\u{2061}" && - (name(child0) == "mi" || name(child0) == "mtext") && - IsInDefinition::is_defined_in(as_text(child0), &SPEECH_DEFINITIONS, "TrigFunctionNames").unwrap() { - return false; - } - } - return true; + return !( + children.len() == 3 && + name(as_element(children[0])) == "mi" && // maybe don't need this check? E.g, sin^2 x. + name(as_element(children[1])) == "mo" && as_text(as_element(children[1])) == "\u{2061}" + ); }, - "msub" | "msup" | "msubsup" => return true, - _ => return false, + _ => return true, } } diff --git a/tests/braille/French/chemistry.rs b/tests/braille/French/chemistry.rs index b5d4606a4..4eedcda3a 100644 --- a/tests/braille/French/chemistry.rs +++ b/tests/braille/French/chemistry.rs @@ -37,7 +37,7 @@ fn equilibrium_III_5_2() -> Result<()> { let expr= r#"2H2O ⇌(2)(1)H3O++OH-"#; - test_braille("French", expr, " ⠣⠨⠓⠣⠨⠕⠰⠸⠻⠆⠢⠢⠦⠣⠴⠈⠈⠦⠡⠴⠨⠓⠩⠨⠕⠈⠰⠖⠆⠖⠨⠕⠨⠓⠈⠰⠤⠆")?; + test_braille("French", expr, "⠣⠨⠓⠣⠨⠕⠰⠸⠻⠆⠢⠢⠦⠣⠴⠈⠈⠦⠡⠴⠨⠓⠩⠨⠕⠈⠰⠖⠆⠖⠨⠕⠨⠓⠈⠰⠤⠆")?; return Ok(()); } @@ -49,6 +49,6 @@ fn equilibrium_III_5_3() -> Result<()> { R-CO-O- R'+ H2O"#; - test_braille("French", expr, " ⠨⠗⠤⠨⠉⠨⠕⠤⠨⠕⠤⠨⠓⠖⠨⠗⠄⠤⠨⠕⠨⠓ ⠸⠻⠨⠢⠰⠓⠽⠙⠗⠕⠇⠽⠎⠑⠆⠨⠔⠈⠰⠑⠎⠞⠗⠊⠋⠊⠉⠁⠞⠊⠕⠝⠆⠨⠗⠤⠨⠉⠨⠕⠤⠨⠕⠤⠨⠗⠄⠖⠨⠓⠢⠣⠨⠕")?; + test_braille("French", expr, "⠨⠗⠤⠨⠉⠨⠕⠤⠨⠕⠤⠨⠓⠖⠨⠗⠄⠤⠨⠕⠨⠓ ⠸⠻⠨⠢⠰⠓⠽⠙⠗⠕⠇⠽⠎⠑⠆⠨⠔⠈⠰⠑⠎⠞⠗⠊⠋⠊⠉⠁⠞⠊⠕⠝⠆⠨⠗⠤⠨⠉⠨⠕⠤⠨⠕⠤⠨⠗⠄⠖⠨⠓⠢⠣⠨⠕")?; return Ok(()); } diff --git a/tests/braille/French/french.rs b/tests/braille/French/french.rs index 0acd5bf56..d0c073128 100644 --- a/tests/braille/French/french.rs +++ b/tests/braille/French/french.rs @@ -57,7 +57,7 @@ fn set_included_or_equal_6_4_07() -> Result<()> { #[test] fn set_intersection_6_4_08() -> Result<()> { - let expr= r#"A∩B=⌀"#; + let expr= r#"A∩B=∅"#; test_braille("French", expr, "⠨⠁⠘⠖⠨⠃⠶⠘⠼")?; return Ok(()); } @@ -85,63 +85,63 @@ fn devided_by_7_02() -> Result<()> { #[test] fn fraction_02_8_01() -> Result<()> { - let expr= r#"a+ba"#; + let expr= r#"a+ba"#; test_braille("French", expr, "⠠⠄⠰⠁⠖⠃⠆⠌⠁")?; return Ok(()); } #[test] fn fraction_03_8_02() -> Result<()> { - let expr= r#"a+bc+d"#; + let expr= r#"a+bc+d"#; test_braille("French", expr, "⠠⠄⠰⠁⠖⠃⠆⠌⠰⠉⠖⠙⠆")?; return Ok(()); } #[test] fn fraction_04_8_03() -> Result<()> { - let expr= r#"ab+cd=ad+bcbd"#; + let expr= r#"ab+cd=ad+bcbd"#; test_braille("French", expr, "⠠⠄⠁⠌⠃⠖⠉⠌⠙⠶⠰⠁⠙⠖⠃⠉⠆⠌⠃⠙")?; return Ok(()); } #[test] fn cardinal_8_04() -> Result<()> { - let expr= r#"CardE=5"#; + let expr= r#"CardE=5"#; test_braille("French", expr, "⠠⠄⠨⠉⠁⠗⠙⠰⠨⠑⠆⠶⠱")?; return Ok(()); } #[test] fn exponential_01_8_05() -> Result<()> { - let expr= r#"ex+3"#; + let expr= r#"ex+3"#; test_braille("French", expr, "⠠⠄⠑⠈⠰⠭⠖⠩⠆")?; return Ok(()); } #[test] fn exponential_02_8_06() -> Result<()> { - let expr= r#"e7"#; + let expr= r#"e7"#; test_braille("French", expr, "⠠⠑⠈⠻")?; return Ok(()); } #[test] fn exponential_03_8_07() -> Result<()> { - let expr= r#"e−x"#; + let expr= r#"e−x"#; test_braille("French", expr, "⠠⠑⠈⠤⠭")?; return Ok(()); } #[test] fn exponential_04_8_08() -> Result<()> { - let expr= r#"e−π"#; + let expr= r#"e−π"#; test_braille("French", expr, "⠠⠑⠈⠤⠘⠏")?; return Ok(()); } #[test] fn power_negativ_one_8_09() -> Result<()> { - let expr= r#"x−1=1x"#; + let expr= r#"x−1=1x"#; test_braille("French", expr, "⠠⠭⠈⠤⠡⠶⠡⠌⠭")?; return Ok(()); } @@ -239,7 +239,7 @@ fn sub_a_prime_0_9_4_01() -> Result<()> { #[test] fn sub_mixt_0_9_4_02() -> Result<()> { - let expr= r#"x0′2"#; + let expr= r#"x′02"#; test_braille("French", expr, "⠭⠄⠢⠼⠈⠣")?; return Ok(()); } @@ -281,7 +281,7 @@ fn lef_sub_9_5_02() -> Result<()> { #[test] fn left_right_sup_9_5_03() -> Result<()> { - let expr= r#"tAtB"#; + let expr= r#"AtBt"#; test_braille("French", expr, "⠰⠈⠞⠨⠁⠆⠰⠈⠞⠨⠃⠆")?; return Ok(()); } @@ -295,21 +295,7 @@ fn left_sub_sup_test_9_5_04() -> Result<()> { #[test] fn bigsum_one_line_9_6_01() -> Result<()> { - let expr= r#"∑i=1nui=u1+u2+⋯+un"#; - test_braille("French", expr, "⠨⠘⠎⠢⠢⠰⠊⠶⠡⠆⠈⠈⠝⠥⠢⠊⠶⠥⠢⠡⠖⠥⠢⠣⠖⠲⠲⠲⠖⠥⠢⠝")?; - return Ok(()); -} -#[test] -fn bigsum_two_lines_9_6_01() -> Result<()> { - let expr= r#"∑i=1nui=u1+u2+⋯+un"#; - test_braille("French", expr, " -⠨⠘⠎⠢⠢⠰⠊⠶⠡⠆⠈⠈⠝⠥⠢⠊⠐ -⠶⠥⠢⠡⠖⠥⠢⠣⠖⠲⠲⠲⠖⠥⠢⠝")?; - return Ok(()); -} -#[test] -fn bigsum_one_line_with_bloc_9_6_01() -> Result<()> { - let expr= r#"∑i=1nui=u1+u2+⋯+un"#; + let expr= r#"∑i=1nui=u1+u2+⋯+un"#; test_braille("French", expr, "⠨⠘⠎⠢⠢⠰⠊⠶⠡⠆⠈⠈⠝⠥⠢⠊⠶⠥⠢⠡⠖⠥⠢⠣⠖⠲⠲⠲⠖⠥⠢⠝")?; return Ok(()); } @@ -439,23 +425,12 @@ fn restriction_of_f_to_13_2_04() -> Result<()> { return Ok(()); } -#[test] -fn determinant_tabular_13_3_01() -> Result<()> { - let expr= r#"I=|1023|=3"#; - test_braille("French", expr, " -⠨⠊⠶⠿⠡⠀⠼⠿ - ⠿⠣⠀⠩⠿⠶⠩")?; - return Ok(()); -} -#[test] -fn matrix_tabular_13_3_02() -> Result<()> { - let expr= r#"J=(142356−789)"#; - test_braille("French", expr, " -⠨⠚⠶⠦⠡⠀⠀⠀⠀⠀⠀⠹⠴ -⠀⠀⠀⠦⠣⠀⠩⠀⠱⠀⠀⠫⠴ -⠀⠀⠀⠦⠤⠻⠀⠳⠀⠀⠀⠪⠴")?; - return Ok(()); -} +// #[test] +// fn determinant_tabular_13_3_01() -> Result<()> { +// let expr= r#"I=|1023|=3"#; +// test_braille("French", expr, "not correct⠨⠊⠶⠿⠡⠀⠼⠿ ⠿⠣⠀⠩⠿⠶⠩")?; +// return Ok(()); +// } #[test] fn matrix_linear_13_3_02() -> Result<()> { let expr= r#"J=(142356−789)"#; @@ -463,28 +438,12 @@ fn matrix_linear_13_3_02() -> Result<()> { return Ok(()); } #[test] -fn matrix_with_equations_two_lines_13_3_03() -> Result<()> { - let expr= r#"K=[1x2+3x−96x3−x2+1x+3y+5g(x)]"#; - test_braille("French", expr, " -⠨⠅⠶⠘⠷⠡⠀⠰⠭⠈⠣⠖⠩⠭⠤⠪⠆⠌⠰⠫⠭⠈⠩⠤⠭⠈⠣⠐ -⠖⠡⠆⠀⠠⠜⠀⠰⠭⠖⠩⠆⠌⠰⠽⠖⠱⠆⠀⠛⠦⠭⠴⠘⠾")?; - return Ok(()); -} -#[test] fn matrix_with_equations_one_lines_13_3_03() -> Result<()> { let expr= r#"K=[1x2+3x−96x3−x2+1x+3y+5g(x)]"#; test_braille("French", expr, "⠨⠅⠶⠘⠷⠡⠀⠰⠭⠈⠣⠖⠩⠭⠤⠪⠆⠌⠰⠫⠭⠈⠩⠤⠭⠈⠣⠖⠡⠆⠀⠠⠜⠀⠰⠭⠖⠩⠆⠌⠰⠽⠖⠱⠆⠀⠛⠦⠭⠴⠘⠾")?; return Ok(()); } #[test] -fn sytem_equation_tabular_13_4_01() -> Result<()> { - let expr= r#"{2x+3y=53x−7y=8"#; - test_braille("French", expr, " -⠸⠦⠣⠭⠖⠩⠽⠶⠱ -⠀⠀⠩⠭⠤⠻⠽⠶⠳")?; - return Ok(()); -} -#[test] fn sytem_equation_linéaraire_13_4_01() -> Result<()> { let expr= r#"{2x+3y=53x−7y=8"#; test_braille("French", expr, "⠸⠦⠣⠭⠖⠩⠽⠶⠱⠀⠠⠜⠀⠩⠭⠤⠻⠽⠶⠳")?; @@ -546,26 +505,26 @@ fn limit_x_tends_of_formula_lt_2_14_2_03_corrected() -> Result<()> { return Ok(()); } -#[test] -fn sign_chart_14_3_01() -> Result<()> { - let expr= r#"x−∞32+∞2x−3−0+"#; - test_braille("French", expr, " -⠭⠀⠀⠀⠸⠤⠘⠉⠀⠀⠩⠌⠣⠀⠀⠀⠖⠘⠉ -⠒⠒⠒⠒⠺⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒ -⠣⠭⠤⠩⠸⠀⠀⠀⠤⠀⠀⠼⠀⠀⠖")?; - return Ok(()); -} - -#[test] -fn sign_chart_14_3_02() -> Result<()> { - let expr= r#"x−∞7+∞f′(x)+0−f(x)−∞↗−1↘−∞"#; - test_braille("French", expr, " -⠀⠭⠀⠀⠀⠀⠸⠤⠘⠉⠀⠀⠀⠀⠀⠻⠀⠀⠀⠀⠀⠖⠘ -⠒⠒⠒⠒⠒⠺⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒ -⠋⠄⠦⠭⠴⠸⠀⠀⠀⠀⠖⠀⠀⠀⠀⠼⠀⠀⠀⠀⠤ -⠋⠦⠭⠴⠀⠸⠤⠘⠉⠀⠘⠱⠀⠤⠡⠀⠨⠱⠀⠤⠘⠉")?; - return Ok(()); -} +// #[test] +// fn sign_chart_14_3_01() -> Result<()> { +// let expr= r#"x−∞32+∞2x−3−0+"#; +// test_braille("French", expr, " +// ⠭⠀⠀⠀⠸⠤⠘⠉⠀⠀⠩⠌⠣⠀⠀⠀⠖⠘⠉ +// ⠒⠒⠒⠒⠺⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒ +// ⠣⠭⠤⠩⠸⠀⠀⠀⠤⠀⠀⠼⠀⠀⠖")?; +// return Ok(()); +// } + +// #[test] +// fn sign_chart_14_3_02() -> Result<()> { +// let expr= r#"x−∞7+∞f′(x)+0−f(x)−∞↗−1↘−∞"#; +// test_braille("French", expr, " +// ⠀⠭⠀⠀⠀⠀⠸⠤⠘⠉⠀⠀⠀⠀⠀⠻⠀⠀⠀⠀⠀⠖⠘ +// ⠒⠒⠒⠒⠒⠺⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒ +// ⠋⠄⠦⠭⠴⠸⠀⠀⠀⠀⠖⠀⠀⠀⠀⠼⠀⠀⠀⠀⠤ +// ⠋⠦⠭⠴⠀⠸⠤⠘⠉⠀⠘⠱⠀⠤⠡⠀⠨⠱⠀⠤⠘⠉")?; +// return Ok(()); +// } #[test] fn integral_from_to_1_14_4_01() -> Result<()> { let expr= r#"∫abf(x)dx"#; @@ -576,9 +535,7 @@ fn integral_from_to_1_14_4_01() -> Result<()> { #[test] fn integral_two_lines_14_4_02() -> Result<()> { let expr= r#"∫052f(x)dx=F(52)−F(0)"#; - test_braille("French", expr, " -⠯⠢⠼⠈⠰⠱⠌⠣⠆⠋⠦⠭⠴⠙⠭⠐ -⠶⠨⠋⠦⠱⠌⠣⠴⠤⠨⠋⠦⠼⠴")?; + test_braille("French", expr, "⠯⠢⠼⠈⠰⠱⠌⠣⠆⠋⠦⠭⠴⠙⠭⠶⠨⠋⠦⠱⠌⠣⠴⠤⠨⠋⠦⠼⠴")?; return Ok(()); } #[test] @@ -597,7 +554,7 @@ fn integral_from_to_2_14_4_03() -> Result<()> { #[test] fn integral_over_curve_14_4_04() -> Result<()> { - let expr= r#"∫(c)f(x)dx"#; + let expr= r#"∫(C)f(x)dx"#; test_braille("French", expr, "⠯⠢⠦⠨⠉⠴⠋⠦⠭⠴⠙⠭")?; return Ok(()); } @@ -625,32 +582,24 @@ fn logarithm_natural_product_14_5_02() -> Result<()> { #[test] fn logarthm_change_base_14_5_03() -> Result<()> { - let expr= r#"log7x=ln⁡xln⁡7"#; + let expr: &str= r#"log7x=ln⁡xln⁡7"#; test_braille("French", expr, "⠇⠕⠛⠢⠻⠰⠭⠆⠶⠇⠝⠰⠭⠆⠌⠇⠝⠰⠻⠆")?; return Ok(()); } #[test] fn cos_of_sum_1_14_6_01() -> Result<()> { - let expr= r#"cos⁡(a+b)=cosacosb−sinasinb"#; - test_braille("French", expr, "⠉⠕⠎⠦⠁⠖⠃⠴⠶⠉⠕⠎⠰⠁⠆⠉⠕⠎⠰⠃⠆⠐⠤⠎⠊⠝⠰⠁⠆⠎⠊⠝⠰⠃⠆")?; + let expr= r#"cos(a+b)=cosacosb−sinasinb"#; + test_braille("French", expr, "⠉⠕⠎⠦⠁⠖⠃⠴⠶⠉⠕⠎⠰⠁⠆⠉⠕⠎⠰⠃⠆⠤⠎⠊⠝⠰⠁⠆⠎⠊⠝⠰⠃⠆")?; return Ok(()); } #[test] fn cos_of_sum_2_14_6_01b() -> Result<()> { - let expr= r#"cos⁡(a+b)=cosacosb−sinasinb"#; - test_braille("French", expr, "⠨⠬⠦⠁⠖⠃⠴⠶⠨⠬⠁⠨⠬⠃⠤⠬⠁⠬⠃")?; - return Ok(()); -} - -#[test] -fn cos_of_sum_3_14_6_01b() -> Result<()> { let expr= r#"cos(a+b)=cosacosb−sinasinb"#; - test_braille("French", expr, "⠨⠬⠦⠁⠖⠃⠴⠶⠨⠬⠁⠨⠬⠃⠤⠬⠁⠬⠃")?; + test_braille_prefs("French", vec![("French_UseShortForm", "true")], expr, "⠨⠬⠦⠁⠖⠃⠴⠶⠨⠬⠁⠨⠬⠃⠤⠬⠁⠬⠃")?; return Ok(()); } - #[test] fn cosh_sinh_14_7_01() -> Result<()> { let expr= r#"cosh2x−sinh2x=1"#; @@ -674,14 +623,14 @@ fn set_formula_15_02() -> Result<()> { #[test] fn power_ordinal_a_16_4_07() -> Result<()> { let expr= r#"(p+q)ième"#; - test_braille("French", expr, "⠦⠏⠖⠟⠴⠈⠊⠮⠍")?; + test_braille("French", expr, "⠦⠏⠖⠟⠴⠈⠊⠮⠍⠑")?; return Ok(()); } #[test] fn power_ordinal_b_16_4_07() -> Result<()> { let expr= r#"(p+q)ième"#; - test_braille("French", expr, "⠦⠏⠖⠟⠴⠈⠊⠮⠍")?; + test_braille("French", expr, "⠦⠏⠖⠟⠴⠈⠊⠮⠍⠑")?; return Ok(()); } From fffcc7320d3cab2aaaca75413015e15c301056eb Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Mon, 22 Jun 2026 00:18:26 -0700 Subject: [PATCH 008/157] fix clippy warning --- src/braille.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/braille.rs b/src/braille.rs index 73cb6c5c8..8dd8fb5f3 100644 --- a/src/braille.rs +++ b/src/braille.rs @@ -2307,11 +2307,11 @@ fn french_cleanup(_pref_manager: Ref, raw_braille: String) -> // let result = capitals_to_word_mode(&result); // check to see if math modifier and code change indicator are needed at start (p8) - let result = if raw_braille.starts_with("P") { + let result = if let Some(stripped) = raw_braille.strip_prefix("P") { let prefix = if raw_braille.contains("o") { "⠠⠄" } else { "⠠" }; - let mut new_string = String::with_capacity(raw_braille.len() - 1 + prefix.len()); + let mut new_string = String::with_capacity(stripped.len() + prefix.len()); new_string.push_str(prefix); - new_string.push_str(&raw_braille[1..]); + new_string.push_str(stripped); new_string } else { raw_braille From de9751dbf8d2e78666e1a127ec92703914fedba9 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 25 Jun 2026 00:43:43 -0700 Subject: [PATCH 009/157] More fixes for French braille. Now at 89 correct, 8 fail, with most of the failures being open questions. --- Rules/Braille/French/French_Rules.yaml | 244 ++++++++++--------------- Rules/Braille/French/definitions.yaml | 13 +- Rules/Braille/French/unicode.yaml | 42 +++-- src/braille.rs | 182 ++++++++++++++++-- tests/braille/French/french.rs | 56 ++++-- tests/common/mod.rs | 3 + 6 files changed, 357 insertions(+), 183 deletions(-) diff --git a/Rules/Braille/French/French_Rules.yaml b/Rules/Braille/French/French_Rules.yaml index 741a7d0e8..5d224216f 100644 --- a/Rules/Braille/French/French_Rules.yaml +++ b/Rules/Braille/French/French_Rules.yaml @@ -1,27 +1,19 @@ --- -# - -# name: whitespace-omission -# tag: "!*" -# match: "not(self::m:math) and not($MatchingWhitespace) and (@data-previous-space-width >= 0.25 or @data-following-space-width >= 0.25)" -# replace: -# - with: -# variables: [MatchingWhitespace: "true()"] -# replace: -# - test: -# - if: "(@class='MathML-unit' or BaseNode(.)[@class='MathML-unit']) and @data-previous-space-width >= 0.25" # BANA 5.3(a) -# then: [t: "𝐖"] -# - else_if: "@data-previous-space-width > 1.1" -# then: [t: "⠬"] -# - else_if: "@data-previous-space-width >= 0.25" # thickspace -# then: [t: "W"] -# - x: "." -# - test: -# - if: "(@class='MathML-unit' or BaseNode(.)[@class='MathML-unit']) and @data-following-space-width >= 0.25" # BANA 5.3(a) -# then: [t: "𝐖"] -# - else_if: "@data-following-space-width > 1.1" -# then: [t: "⠬"] -# - else_if: "@data-following-space-width >= 0.25" # thickspace -# then: [t: "W"] +- + name: whitespace-omission + tag: "!*" + match: "not(self::m:math) and not($MatchingWhitespace) and (@data-previous-space-width >= 0.35 or @data-following-space-width >= 0.35)" + replace: + - with: + variables: [MatchingWhitespace: "true()"] + replace: + - test: + - if: "@class='MathML-unit' or BaseNode(.)[@class='MathML-unit'] or @data-previous-space-width >= 0.35" # BANA 5.3(a) + then: [t: "W"] + - x: "." + - test: + - if: "@class='MathML-unit' or BaseNode(.)[@class='MathML-unit'] or @data-following-space-width >= 0.35" # BANA 5.3(a) + then: [t: "W"] - name: omission-intent @@ -38,12 +30,12 @@ - x: "@data-unicode" - - name: default - tag: msqrt - match: "." - replace: - - t: "⠜" - - test: + name: default + tag: msqrt + match: "." + replace: + - t: "b⠜" + - test: if: "NeedsToBeGrouped(*[1], 'French', true())" then: - t: "o" @@ -51,13 +43,15 @@ - t: "c" else: - x: "*[1]" + - t: "e" - name: default tag: mroot match: "." replace: - - t: "⠈" + - t: "b" + - t: "L⠈" # this ("L") is a hack -- it allows the optional group indicators to be added if needed before the mroot - test: if: "NeedsToBeGrouped(*[2], 'French', false())" then: @@ -75,6 +69,7 @@ - t: "c" else: - x: "*[1]" + - t: "e" # Fraction rules @@ -83,23 +78,25 @@ # The invisible plus should produce an empty string - - name: common-fraction-mixed-number - tag: mfrac - match: + name: common-fraction-mixed-number + tag: mfrac + match: - "preceding-sibling::*[1][self::m:mo][text()='\u2064'] and" # preceding element is invisible plus - "*[1][self::m:mn][not(contains(., '.'))] and" - "*[2][self::m:mn][not(contains(., '.'))]" - replace: - - t: "#" # signal end of previous numeric mode - - x: "*[1]" - - t: "N⠌" - - x: "*[2]" + replace: + - t: "b" + - x: "*[1]" + - t: "N⠌" + - x: "*[2]" + - t: "e" - name: default tag: mfrac match: "." replace: + - t: "b" - test: if: "NeedsToBeGrouped(*[1], 'French', true())" then: @@ -117,26 +114,13 @@ - t: "c" else: - x: "*[2]" - -# -# Matrix/Determinant rules -# matrix and determinant are the same other than "matrix"/"determinant" based on the bracketing chars -# we don't do spatial layout, instead the beginning/ending of each row uses the enlarged bracketing chars -- - name: default-matrix - tag: mrow - variables: - - RowStart: "*[1]" - - RowEnd: "*[3]" - match: - - "*[2][self::m:mtable] and" - - (IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')) - replace: [x: "*[2]"] + - t: "e" - name: default-mtable tag: mtable match: "." - replace: [x: "*"] + replace: + - x: "*" - name: default tag: [mtr, mlabeledtr] @@ -145,8 +129,6 @@ - test: if: "preceding-sibling::*" then: [t: "W⠠⠜W"] - - t: "" - - x: $RowStart # - test: # if: .[self::m:mlabeledtr] @@ -157,15 +139,9 @@ if: .[self::m:mlabeledtr] then: [x: "*[position()>1]"] else: {x: "*"} - - x: $RowEnd - - -- - name: empty - tag: mtd - match: ".=''" - replace: - - t: "⠐⠂" + - test: + if: "following-sibling::* " + then: [t: "W"] - name: default @@ -173,13 +149,12 @@ match: "." replace: - test: - if: "*" - then: - - test: - if: "preceding-sibling::*" - then: [t: "W"] - - x: "*" - # else nothing to braille + if: "preceding-sibling::*" + then: [t: "W"] + - test: + if: "*[1][self::m:mtext and .=' ']" # empty or non-breaking space (canonicalized to this) + then: [t: "⠐⠂"] + else: [x: "*"] - name: no-content @@ -192,8 +167,6 @@ tag: math match: "." variables: - - RowStart: "''" # empty string -- it needs to be set - - RowEnd: "''" # empty string -- it needs to be set - MatchingWhitespace: "false()" replace: - test: @@ -208,34 +181,15 @@ replace: [t: "W"] # not sure what is correct -- if in a fraction, probably something is better than nothing - - # From 14.5, 14.6, and 14.7 -- need to add block indicators around the argument unless it has parens - name: trig-functions - tag: mrow - match: "count(*)=3 and *[2]='\u2061' and - (IsInDefinition(BaseNode(*[1]), 'Braille', 'TrigFunctionNames') or BaseNode(*[1]) = 'lim') and not(IsBracketed(*[3], '(', ')'))" - replace: - - x: "*[1]" - - test: - # p51 -- use short form for (some) trig functions; always group unless short form and no grouping needed - if: "not($French_UseShortForm and IsInDefinition(BaseNode(*[1]), 'Braille', 'ShortForms')) or - NeedsToBeGrouped(*[3], 'French', true())" - then: - - t: "o" - - x: "*[3]" - - t: "c" - else: - - x: "*[3]" - -# - -# name: binomial-frac -# tag: mrow -# match: "IsBracketed(., '(', ')') and *[2][self::m:mfrac][@linethickness=0]" -# replace: -# - x: "*[1]" -# - x: "*[2]/*[1]" -# - t: "⠰⠻" -# - x: "*[2]/*[2]" -# - x: "*[3]" + name: binomial-frac + tag: mrow + match: "IsBracketed(., '(', ')') and *[2][self::m:mfrac][@linethickness=0]" + replace: + - t: "⠘⠦" # large left parenthesis + - x: "*[2]/*[1]" + - t: "⠠⠜" + - x: "*[2]/*[2]" + - t: "⠘⠴" # large right parenthesis # - name: binomial-table # tag: mrow @@ -263,18 +217,39 @@ - x: "*[2]/*[last()-2]" - x: "*[2]/*[last()]" +# - +# # From 14.5, 14.6, and 14.7 -- need to add block indicators around the argument unless it has parens +# name: trig-functions +# tag: mrow +# match: "count(*)=3 and *[2]='\u2061' and +# (IsInDefinition(BaseNode(*[1]), 'Braille', 'TrigFunctionNames') or BaseNode(*[1]) = 'lim') and not(IsBracketed(*[3], '(', ')'))" +# replace: +# - x: "*[1]" +# - test: +# # p51 -- use short form for (some) trig functions; always group unless short form and no grouping needed +# if: "not($French_UseShortForm and IsInDefinition(BaseNode(*[1]), 'Braille', 'ShortForms')) or +# NeedsToBeGrouped(*[3], 'French', true())" +# then: +# - t: "o" +# - x: "*[3]" +# - t: "c" +# else: +# - x: "*[3]" + - # grouping rules -- need to add grouping symbols for some cases + # From 14.5, 14.6, and 14.7 -- need to add block indicators around the argument unless it has parens name: function-call tag: mrow # we include invisible times in the match because some AbbreviationsForGrouping are not function names match: "count(*)=3 and *[2][self::m:mo][.='\u2061'or .='\u2062'] and not(*[3][self::m:mrow][IsBracketed(., '(', ')') or IsBracketed(., '[', ']')]) and - *[1][self::m:mi][IsInDefinition(., 'Braille', 'TrigFunctionNames') or IsInDefinition(., 'Braille', 'AbbreviationsForGrouping')]" + BaseNode(*[1])[self::m:mi][not($French_UseShortForm and IsInDefinition(., 'Braille', 'ShortForms')) and + (IsInDefinition(., 'Braille', 'TrigFunctionNames') or IsInDefinition(., 'Braille', 'AbbreviationsForGrouping'))]" replace: - x: "*[1]" - t: "o" - - x: "DEBUG(*[3])" + - x: "*[3]" - t: "c" - @@ -327,7 +302,14 @@ replace: - test: if: "$French_UseShortForm and IsInDefinition(., 'Braille', 'ShortForms')" - then: [x: "BrailleChars(DefinitionValue(., 'Braille', 'ShortForms'), 'French')"] + then: + - with: + variables: [Replacement: "DefinitionValue(., 'Braille', 'ShortForms')"] + replace: + - test: + if: "translate(substring($Replacement, 1, 1), 'abcdefghijklmnopqrstuvwxyz', '')=''" + then: [x: "BrailleChars($Replacement, 'French')"] + else: [x: "$Replacement"] else: [x: "BrailleChars(., 'French')"] - @@ -370,38 +352,6 @@ - t: "⠘⠸⠒" - x: "*[1]" -- - name: single-char-exceptions # GTM 12 - tag: [mover, munder] - match: "*[2][string-length(.) = 1 and translate(., '_¯→.·˙~^⌄⌒','')='']" - replace: - - test: - if: "self::m:munder" - then: [t: "⠨"] - - test: - - if: "*[2][text()='_' or text()='¯']" - then: [t: "⠸⠒"] - - else_if: "*[2][text()='→']" - then: [t: "⠨⠒"] - - else_if: "*[2][text()='.' or text()='·' or text()='˙']" - then: [t: "⠂"] # FIX: couldn't find an example - - else_if: "*[2][text()='~']" - then: [t: "⠐⠸⠒"] - - else_if: "*[2][text()='^']" - then: [t: "⠘⠒"] - - else_if: "*[2][text()='⌄']" - then: [t: "⠸⠘⠒"] - else: [t: "⠈⠒"] # arc/⌒ - # The examples in 12.1 never group the base, but this seems dubious. Needs to be confirmed - # - test: - # if: "NeedsToBeGrouped(*[1], 'French', true())" - # then: - # - t: "o" - # - x: "*[1]" - # - t: "c" - # else: [x: "*[1]"] - - x: "*[1]" - - # In French braille, we drop the script indicators in both subscripts and superscripts for: # msub: chemistry (e.g., H20) @@ -435,6 +385,7 @@ tag: [msub, msup, munder, mover] match: "." replace: + - t: "b" - test: if: "(self::m:munder or self::m:mover) and NeedsToBeGrouped(*[1], 'French', true())" then: @@ -451,13 +402,13 @@ then: [t: "⠢⠢"] else: [t: "⠈⠈"] # mover - test: - if: "DEBUG(NeedsToBeGrouped(*[2], 'French', false()))" + if: "NeedsToBeGrouped(*[2], 'French', false())" then: - t: "o" - x: "*[2]" - t: "c" else: [x: "*[2]"] - - t: "#" # signal end script/numeric mode + - t: "e" @@ -476,7 +427,7 @@ then: [t: "⠢⠢"] else: [t: "⠢"] - test: - if: "DEBUG(NeedsToBeGrouped(*[2], 'French', false()))" + if: "NeedsToBeGrouped(*[2], 'French', false())" then: - t: "o" - x: "*[2]" @@ -504,6 +455,7 @@ tag: mmultiscripts match: "count(*)=4 and *[2][self::m:mprescripts] and @data-chem-formula" replace: + - t: "b" - x: "*[1]" - test: if: "not(*[3][self::m:none])" @@ -527,7 +479,7 @@ - x: "*[4]" - t: "c" else: [x: "*[4]"] - + - t: "e" - name: default tag: mmultiscripts @@ -538,6 +490,10 @@ - NumChildren: "count(*)" # need to stash this since the count is wrong inside '*[...]' below - Postscripts: "*[position()>1 and position() < (last() + ($NumChildren mod 2) -count($Prescripts))]" replace: + - test: + if: "$Prescripts" + then: [t: "o"] + else: [t: "b"] - test: if: "$Prescripts" then: @@ -697,8 +653,10 @@ if: "count($Postscripts) > 8" # give up and just dump them out so at least the content is there then: - x: "$Postscripts[position() > 8]" - - t: "#" # signal end script/numeric mode - + - test: + if: "$Prescripts" + then: [t: "c"] + else: [t: "e"] - # Note: @notation can contain more than one value diff --git a/Rules/Braille/French/definitions.yaml b/Rules/Braille/French/definitions.yaml index 332abd498..8a611c06a 100644 --- a/Rules/Braille/French/definitions.yaml +++ b/Rules/Braille/French/definitions.yaml @@ -3,8 +3,12 @@ - AbbreviationsForGrouping: { "arg", "Card", "rot", + "sin", "cos", "tan", "cotan", "arcsin", "arccos", "arctan", "arccotan", - "ch", "sh", "th", + "ch", "sh", "th", "cosh", "sinh", "tanh", "coth", + "argsh", "argch", "argth", "argcoth", + "arsinh", "arcosh", "artanh", "arcoth", + "lim", } - ShortForms: { @@ -15,6 +19,9 @@ # ⠨ -> \ue001 # ⠮ -> \ue002 # ⠘ -> \ue003 - "sin": "\ue000", cos: "\ue001\ue000", tan: "\ue002", "cotan": "\ue001\ue002", - arcsin: "\ue003\ue000", arccos: "\ue003\ue001\ue002", arctan: "\ue003\ue002", arccotan: "\ue003\ue001\ue002", + "sin": "\ue000", "cos": "\ue001\ue000", "tan": "\ue002", "cotan": "\ue001\ue002", + "arcsin": "\ue003\ue000", "arccos": "\ue003\ue001\ue002", "arctan": "\ue003\ue002", "arccotan": "\ue003\ue001\ue002", + + "cosh": "ch", "sinh": "sh", "tanh": "th", "coth": "coth", + "arsinh": "argsh", "arcosh": "argch", "artanh": "argth", "arcoth": "argcoth", } \ No newline at end of file diff --git a/Rules/Braille/French/unicode.yaml b/Rules/Braille/French/unicode.yaml index 0105b376e..f7e23239b 100644 --- a/Rules/Braille/French/unicode.yaml +++ b/Rules/Braille/French/unicode.yaml @@ -144,7 +144,7 @@ - "δ": [t: "GL⠙"] # 0x3b4 - "ε": [t: "GL⠑"] # 0x3b5 - "ζ": [t: "GL⠵"] # 0x3b6 - - "η": [t: "GL⠱"] # 0x3b7 + - "η": [t: "GL⠓"] # 0x3b7 - "θ": [t: "GL⠹"] # 0x3b8 - "ι": [t: "GL⠊"] # 0x3b9 - "κ": [t: "GL⠅"] # 0x3ba @@ -203,8 +203,17 @@ - "!": [t: "⠸⠔"] # 0x0021 (factorial) - "%": [t: "⠐⠬"] # 0x0025 (percent sign) - - "(": [t: "⠦"] # 0x0028 (left parenthesis) - - ")": [t: "⠴"] # 0x0029 (right parenthesis) + - "(": # 0x0028 (left parenthesis) + - test: + if: "parent::m:mrow/*[self::m:mtable]" + then: [t: "⠘⠦"] + else: [t: "⠦"] + - ")": # 0x0029 (right parenthesis) + - test: + if: "parent::m:mrow/*[self::m:mtable]" + then: [t: "⠘⠴"] + else: [t: "⠴"] + - "*": [t: "⠐⠔"] # 0x002A (asterisk) - "+": [t: "⠖"] # 0x002B (regular plus) - ",": [t: "⠂"] # 0x002C (comma) @@ -226,20 +235,30 @@ - "<": [t: "⠐⠣"] # 0x003C (less than sign) - "=": [t: "⠶"] # 0x003D (regular equals sign) - ">": [t: "⠐⠜"] # 0x003E (greater than sign ( regular )) - - "[": [t: "⠷"] # 0x005B (left square bracket) - - "]": [t: "⠾"] # 0x005D (right square bracket) + - "[": # 0x005B (left square bracket) + - test: + if: "parent::m:mrow/*[self::m:mtable]" + then: [t: "⠘⠷"] + else: [t: "⠷"] + - "]": # 0x005B (left square bracket) + - test: + if: "parent::m:mrow/*[self::m:mtable]" + then: [t: "⠘⠾"] + else: [t: "⠾"] - "^": [t: "⠘⠒"] # 0x005E (caret) - "{": # 0x007B ( left curly brace) - test: - if: "following-sibling::*[1][self::m:mtable]" - then_test: - if: "count(following-sibling::*[1]/*) = 1" - then: [t: "⠨⠦"] - else: [t: "⠸⠦"] + if: "parent::m:mrow/*[self::m:mtable] or (following-sibling::*[1][self::m:mtable] and count(following-sibling::*[1]/*) = 1)" + then: [t: "⠸⠦"] else: [t: "⠨⠦"] # regular brace - "|": [t: "⠿"] # 0x007C (vertical bar) - - "}": [t: "⠨⠴"] # 0x007D (right curly brace) + - "}": # 0x007D (right curly brace)) + - test: + if: "parent::m:mrow/*[self::m:mtable]" + then: [t: "⠸⠴"] + else: [t: "⠨⠴"] - "~": [t: "⠐⠸⠒"] # 0x007E (simple tilde (is related to, is similar)) + - " ": [t: "W"] # 0x00A0 (non-breaking space) - "¢": [t: "⠉"] # 0x00A2 (cent) - "¯": [t: "⠸⠒"] # 0x00AF (bar) - "°": [t: "⠐⠕"] # 0x00B0 (degree sign) @@ -348,7 +367,6 @@ - "✕": [t: "⠐⠐⠔"] # 0x2715 (multiplication X) - "⟧": [t: "⠨⠾"] # 0x27E7 (right barred bracket) - "⪥": [t: "⠐⠜⠐⠣"] # 0x2AA5 (greater than sign followed by less than sign) - - "⫽": [t: "⠸⠳"] # 0x2A7D (DOUBLE SOLIDUS OPERATOR) # Private space chars used for short forms for trig functions - "\ue000": [t: "L⠬"] diff --git a/src/braille.rs b/src/braille.rs index 8dd8fb5f3..d1b429686 100644 --- a/src/braille.rs +++ b/src/braille.rs @@ -2295,33 +2295,175 @@ static FRENCH_INDICATOR_REPLACEMENTS: phf::Map<&str, &str> = phf_map! { "s" => "⠆", // typeface single char indicator "o" => "⠰", // Opening group indicator "c" => "⠆", // Closing group indicator + "b" => "⠰", // Optional opening group indicator + "e" => "⠆", // Optional closing group indicator "P" => "⠠⠄", // Math modifier and code change indicator - "#" => "", // signals end of script }; +/// Remove optional group indicators `b`/`e` when not needed; promote to mandatory `o`/`c` when they are. +/// Optional pairs nest like parentheses. Resolve outer pairs before inner ones. +/// A pair is kept when its content ends with a letter/number (`L`/`N` + braille) before `e`, and a +/// letter/number follows the next `b` (or directly) after `e`. +fn remove_optional_group_indicators(braille: &str) -> String { + let chars: Vec = braille.chars().collect(); + let mut stack: Vec = Vec::new(); + let mut pairs: Vec<(usize, usize)> = Vec::new(); + + for (i, &ch) in chars.iter().enumerate() { + if ch == 'b' { + stack.push(i); + } else if ch == 'e' { + if let Some(b_idx) = stack.pop() { + pairs.push((b_idx, i)); + } + } + } + + let mut convert_to_oc = vec![false; chars.len()]; + let mut remove = vec![false; chars.len()]; + + for (b_idx, e_idx) in pairs.into_iter().rev() { + let needed = letter_or_number_before_e(b_idx, e_idx, &chars, &remove, &convert_to_oc) + && letter_or_number_after_b(e_idx, &chars, &remove, &convert_to_oc); + if needed { + convert_to_oc[b_idx] = true; + convert_to_oc[e_idx] = true; + } else { + remove[b_idx] = true; + remove[e_idx] = true; + } + } + + let mut result = String::with_capacity(braille.len()); + for (i, &ch) in chars.iter().enumerate() { + if remove[i] { + continue; + } + if convert_to_oc[i] { + result.push(if ch == 'b' { 'o' } else { 'c' }); + } else { + result.push(ch); + } + } + return result; +} + +fn is_letter_or_number_start(chars: &[char], i: usize, remove: &[bool]) -> bool { + if i + 1 >= chars.len() || remove[i] { + return false; + } + if chars[i] != 'L' && chars[i] != 'N' { + return false; + } + return !remove[i + 1] && !is_optional_group_or_mode_marker(chars[i + 1]); +} + +fn is_optional_group_or_mode_marker(ch: char) -> bool { + return matches!(ch, 'b' | 'e' | 'o' | 'c' | 'L' | 'N' | 'W' | 'P' | 'C' | '1' | '#'); +} + +fn letter_or_number_before_e( + b_idx: usize, + e_idx: usize, + chars: &[char], + remove: &[bool], + convert_to_oc: &[bool], +) -> bool { + let mut i = e_idx; + while i > b_idx { + i -= 1; + if remove[i] { + continue; + } + if chars[i] == 'e' && !convert_to_oc[i] { + continue; + } + if chars[i] == 'e' && convert_to_oc[i] { + continue; + } + if chars[i] == 'L' || chars[i] == 'N' { + return true; + } + if i > b_idx { + let mut j = i; + loop { + if j <= b_idx { + return false; + } + j -= 1; + if remove[j] { + continue; + } + if chars[j] == 'e' && !convert_to_oc[j] { + continue; + } + if chars[j] == 'e' && convert_to_oc[j] { + continue; + } + return chars[j] == 'L' || chars[j] == 'N'; + } + } + return false; + } + return false; +} + +fn letter_or_number_after_b( + e_idx: usize, + chars: &[char], + remove: &[bool], + convert_to_oc: &[bool], +) -> bool { + let mut i = e_idx + 1; + while i < chars.len() { + if remove[i] { + i += 1; + continue; + } + if chars[i] == 'e' && convert_to_oc[i] { + i += 1; + continue; + } + if chars[i] == 'b' { + return is_letter_or_number_start(chars, i + 1, remove); + } + return is_letter_or_number_start(chars, i, remove); + } + return false; +} + fn french_cleanup(_pref_manager: Ref, raw_braille: String) -> String { // FIX: need to implement this -- this is just a copy of the Vietnam code - static REPLACE_INDICATORS: LazyLock = LazyLock::new(|| Regex::new(r"([1SB𝔹TILDGC𝐶NWsc#oc])").unwrap()); + static REPLACE_INDICATORS: LazyLock = LazyLock::new(|| Regex::new(r"([1SB𝔹TILDGC𝐶NWscocbe])").unwrap()); debug!("french_cleanup: start={}", raw_braille); // let result = typeface_to_word_mode(&raw_braille); // let result = capitals_to_word_mode(&result); + let result = remove_optional_group_indicators(&raw_braille); // check to see if math modifier and code change indicator are needed at start (p8) - let result = if let Some(stripped) = raw_braille.strip_prefix("P") { - let prefix = if raw_braille.contains("o") { "⠠⠄" } else { "⠠" }; + let result = if let Some(stripped) = result.strip_prefix('P') { + let prefix = if result.contains('o') { "⠠⠄" } else { "⠠" }; let mut new_string = String::with_capacity(stripped.len() + prefix.len()); new_string.push_str(prefix); new_string.push_str(stripped); new_string } else { - raw_braille + result }; // This reuses the code just for getting rid of unnecessary "L"s and "N"s let result = remove_unneeded_mode_changes(&result, UEB_Mode::Grade1, UEB_Duration::Passage); debug!(" after removing mode changes={}", &result); - let result: Cow<'_, str> = REPLACE_INDICATORS.replace_all(&result, |cap: &Captures| { + // remove any grouping pair at the start or end -- we ensure they are a pair but making sure there is no "o" inside the string + let result = if result.starts_with('o') && result.ends_with('c') && !result[1..result.len() - 1].contains('o') { + // Remove the first and last characters by slicing + &result[1..result.len() - 1] + } else { + &result + }; + + let result: Cow<'_, str> = REPLACE_INDICATORS.replace_all(result, |cap: &Captures| { match FRENCH_INDICATOR_REPLACEMENTS.get(&cap[0]) { None => {error!("REPLACE_INDICATORS and FRENCH_INDICATOR_REPLACEMENTS are not in sync: missing '{}'", &cap[0]); ""}, Some(&ch) => ch, @@ -2376,7 +2518,7 @@ fn ASCIIMath_cleanup(_pref_manager: Ref, raw_braille: String) /************** Braille xpath functionality ***************/ use crate::canonicalize::{as_element, as_text, name}; -use crate::xpath_functions::{is_leaf, validate_one_node, IsBracketed}; +use crate::xpath_functions::{IsBracketed, is_leaf, validate_one_node}; use std::result::Result as StdResult; use sxd_document::dom::ParentOfChild; use sxd_xpath::function::Error as XPathError; @@ -3027,21 +3169,19 @@ impl NeedsToBeGrouped { // French rules are from p26: Blocks (also mentioned elsewhere in the spec) // if we have a "- xxx", we treat the MathML as if it were just "xxx". // apparently, based on function_partial_derivative_14_1_04, the same goes for '∂' -- generalizing to all prefix ops... + // Grouping is also needed if what follows (w/o regard to structure) is a digit or letter. // use crate::xpath_functions::IsInDefinition; - let mut children = mathml.children(); + let children = mathml.children(); let mathml = if name(mathml) == "mrow" && children.len() == 2 && name(as_element(children[0])) == "mo" { // assuming it is a prefix op since it starts an mrow - let operand_child = as_element(children[1]); - children = operand_child.children(); - operand_child + as_element(children[1]) } else { mathml }; - let node_name = name(mathml); - // let parent = get_parent(mathml); // there is always a "math" node because we never ask if its children need grouping - // let parent_name = name(parent); debug!("needs_grouping_for_french: mathml (sans '-') = {}", mml_to_string(mathml)); + let node_name = name(mathml); + let children = mathml.children(); match node_name { "mn" | "mi" | "mtext" => { return as_text(mathml).contains(char::is_whitespace); @@ -3376,4 +3516,18 @@ mod tests { assert_eq!("⠭⠔⠝", braille, "Grade1"); return Ok( () ); } + + #[test] + fn french_remove_optional_group_indicators() { + assert_eq!(remove_optional_group_indicators("bLxe+"), "Lx+"); + assert_eq!(remove_optional_group_indicators("bLxeLy"), "oLxcLy"); + assert_eq!(remove_optional_group_indicators("bLxbe+NeLz"), "oLx+NcLz"); + // inner e is followed by outer e, then L — resolve outer pair first + assert_eq!(remove_optional_group_indicators("bbLx+NeeLy"), "ooLx+NccLy"); + // adjacent pairs: second is removed first, then first sees L after it + assert_eq!( + remove_optional_group_indicators("bL⠈N⠹⠜L⠁ebL⠈N⠩⠜L⠃e"), + "oL⠈N⠹⠜L⠁cL⠈N⠩⠜L⠃" + ); + } } diff --git a/tests/braille/French/french.rs b/tests/braille/French/french.rs index d0c073128..a799b8ed7 100644 --- a/tests/braille/French/french.rs +++ b/tests/braille/French/french.rs @@ -6,6 +6,35 @@ use crate::common::*; use anyhow::Result; +#[test] +fn binomial_nk_01() -> Result<()> { + let expr= r#"(nk)"#; + test_braille("French", expr, "⠘⠦⠝⠠⠜⠅⠘⠴")?; + return Ok(()); +} + +#[test] +fn binomial_5_2_02() -> Result<()> { + let expr= r#"(52)"#; + test_braille("French", expr, "⠘⠦⠱⠠⠜⠣⠘⠴")?; + return Ok(()); +} + +#[test] +fn binomial_symmetry_03() -> Result<()> { + let expr= r#"(nk)=(nn−k)"#; + test_braille("French", expr, "⠘⠦⠝⠠⠜⠅⠘⠴⠶⠘⠦⠝⠠⠜⠝⠤⠅⠘⠴")?; + return Ok(()); +} + +#[test] +fn binomial_pascal_04() -> Result<()> { + let expr= r#"(nk)=(n−1k−1)+(n−1k)"#; + test_braille("French", expr, "⠘⠦⠝⠠⠜⠅⠘⠴⠶⠘⠦⠝⠤⠡⠠⠜⠅⠤⠡⠘⠴⠖⠘⠦⠝⠤⠡⠠⠜⠅⠘⠴")?; + return Ok(()); +} + + #[test] fn set_of_elements_6_4_01() -> Result<()> { let expr= r#"E={a,b,c,d}"#; @@ -246,14 +275,18 @@ fn sub_mixt_0_9_4_02() -> Result<()> { #[test] fn choose_9_4_03() -> Result<()> { - let expr= r#"∁mp=∁mm−p"#; + let expr= r#"Cmp=Cmm−p"#; test_braille("French", expr, "⠨⠉⠢⠍⠈⠏⠶⠨⠉⠢⠍⠈⠰⠍⠤⠏⠆")?; return Ok(()); } #[test] fn sub_sup_mixed_formulaq_9_4_04() -> Result<()> { - let expr= r#"am+n′p+q"#; + let expr= r#" + a′' + m+n + p+q + "#; test_braille("French", expr, "⠁⠄⠄⠢⠰⠍⠖⠝⠆⠈⠰⠏⠖⠟⠆")?; return Ok(()); } @@ -273,7 +306,7 @@ fn left_sup_9_5_01() -> Result<()> { } #[test] -fn lef_sub_9_5_02() -> Result<()> { +fn left_sub_9_5_02() -> Result<()> { let expr= r#"2w"#; test_braille("French", expr, "⠢⠣⠺")?; return Ok(()); @@ -281,7 +314,7 @@ fn lef_sub_9_5_02() -> Result<()> { #[test] fn left_right_sup_9_5_03() -> Result<()> { - let expr= r#"AtBt"#; + let expr: &str= r#"AtBt"#; test_braille("French", expr, "⠰⠈⠞⠨⠁⠆⠰⠈⠞⠨⠃⠆")?; return Ok(()); } @@ -336,8 +369,8 @@ fn square_formula_3_10_05() -> Result<()> { #[test] fn function_from_r_to_r_11_01() -> Result<()> { - let expr= r#"f:ℝ→ℝ,x↦y=1x"#; - test_braille("French", expr, "⠒⠨⠨⠗⠸⠱⠨⠨⠗⠭⠐⠱⠽⠶⠡⠌⠭")?; + let expr= r#"f:ℝ→ℝ,x↦y=1x"#; + test_braille("French", expr, "⠋⠒⠨⠨⠗⠸⠱⠨⠨⠗⠭⠐⠱⠽⠶⠡⠌⠭")?; return Ok(()); } @@ -486,7 +519,7 @@ fn limit_x_tends_1_14_2_01_corrected() -> Result<()> { #[test] fn limit_x_tends_and_x_lt_1_14_2_02_corrected_1() -> Result<()> { - let expr= r#"limx→4x>4f(x)=−∞"#; + let expr= r#"limx→4x>4f(x)=−∞"#; test_braille("French", expr, "⠇⠊⠍⠢⠢⠰⠭⠸⠱⠹⠂⠭⠐⠜⠹⠆⠋⠦⠭⠴⠶⠤⠘⠉")?; return Ok(()); } @@ -554,14 +587,14 @@ fn integral_from_to_2_14_4_03() -> Result<()> { #[test] fn integral_over_curve_14_4_04() -> Result<()> { - let expr= r#"∫(C)f(x)dx"#; + let expr= r#"∫(C)f(x)dx"#; test_braille("French", expr, "⠯⠢⠦⠨⠉⠴⠋⠦⠭⠴⠙⠭")?; return Ok(()); } #[test] fn integral_double_over_surface_14_4_05() -> Result<()> { - let expr= r#"∯Sf(x,y)dxdy"#; + let expr= r#"∯Sf(x,y)dxdy"#; test_braille("French", expr, "⠨⠯⠯⠢⠨⠎⠋⠦⠭⠂⠽⠴⠙⠭⠙⠽")?; return Ok(()); } @@ -603,7 +636,8 @@ fn cos_of_sum_2_14_6_01b() -> Result<()> { #[test] fn cosh_sinh_14_7_01() -> Result<()> { let expr= r#"cosh2x−sinh2x=1"#; - test_braille("French", expr, "⠉⠓⠈⠣⠰⠭⠆⠤⠎⠓⠈⠣⠰⠭⠆⠶⠡")?; + test_braille_prefs("French", vec![("French_UseShortForm", "true")], expr, "⠉⠓⠈⠣⠰⠭⠆⠤⠎⠓⠈⠣⠰⠭⠆⠶⠡")?; + return Ok(()); } @@ -616,7 +650,7 @@ fn exists_element_of_15_01() -> Result<()> { #[test] fn set_formula_15_02() -> Result<()> { - let expr= r#"∀ε>0∃η>0:|x2−x1|≤η⇒|f(x2)−f(x1)|≤ε"#; + let expr= r#"∀ε>0∃η>0:|x2−x1|≤η⇒|f(x2)−f(x1)|≤ε"#; test_braille("French", expr, "⠸⠌⠘⠑⠐⠜⠼⠀⠸⠡⠘⠓⠐⠜⠼⠒⠀⠿⠭⠢⠣⠤⠭⠢⠡⠿⠘⠣⠘⠓⠀⠒⠂⠀⠿⠋⠦⠭⠢⠣⠴⠤⠋⠦⠭⠢⠡⠴⠿⠘⠣⠘⠑")?; return Ok(()); } diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 13dfbeb45..618eeb294 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -142,6 +142,7 @@ pub fn test_braille(code: &str, mathml: &str, braille: &str) -> Result<()> { // log::debug!("\nsetting Language"); match code { "Vietnam" => set_preference("Language", "vi").unwrap(), + "French" => set_preference("Language", "fr").unwrap(), "CMU" => set_preference("Language", "es").unwrap(), _ => set_preference("Language", "en").unwrap(), } @@ -169,6 +170,7 @@ pub fn test_braille_prefs(code: &str, test_prefs: Vec<(&str, &str)>, mathml: &st // log::debug!("\nsetting Language"); match code { "Vietnam" => set_preference("Language", "vi").unwrap(), + "French" => set_preference("Language", "fr").unwrap(), "CMU" => set_preference("Language", "es").unwrap(), _ => set_preference("Language", "en").unwrap(), } @@ -273,6 +275,7 @@ pub fn test_from_braille(code: &str, mathml: &str, braille: &str) -> Result<()> // log::debug!("\nsetting Language"); match code { "Vietnam" => set_preference("Language", "vi").unwrap(), + "French" => set_preference("Language", "fr").unwrap(), "CMU" => set_preference("Language", "es").unwrap(), _ => set_preference("Language", "en").unwrap(), } From f9ba42ab0235810afd6c282b3501e4eb2d9e4caf Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 25 Jun 2026 14:41:50 -0700 Subject: [PATCH 010/157] pass through braille chars as is --- src/speech.rs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/speech.rs b/src/speech.rs index 2545d308a..e97da7e0c 100644 --- a/src/speech.rs +++ b/src/speech.rs @@ -2822,18 +2822,21 @@ impl<'c, 's:'c, 'r, 'm:'c> SpeechRulesWithContext<'c, 's,'m> { unicode = rules.unicode_full.borrow(); replacements = unicode.get( &ch_as_u32 ); if replacements.is_none() { - self.translate_count = 0; // not in loop - // debug!("*** Did not find unicode {} for char '{}'/{:#06x}", rules.name, ch, ch_as_u32); - if rules.translate_single_chars_only || ch.is_ascii() { // speech or if braille, avoid loop (ASCII remains ASCII if not found) - return Ok(self.escape_string_for_safety(String::from(ch))); - } else { // braille -- must turn into braille dots - // Emulate what NVDA does: generate (including single quotes) '\xhhhh' or '\yhhhhhh' - let ch_as_int = ch as u32; - let prefix_indicator = if ch_as_int < 1<<16 {'x'} else {'y'}; - return self.replace_chars( &format!("'\\{prefix_indicator}{:06x}'", ch_as_int), mathml); + self.translate_count = 0; // not in loop + // debug!("*** Did not find unicode {} for char '{}'/{:#06x}", rules.name, ch, ch_as_u32); + if rules.translate_single_chars_only || ch.is_ascii() { // speech or if braille, avoid loop (ASCII remains ASCII if not found) + return Ok(self.escape_string_for_safety(String::from(ch))); + } else { + let ch_as_int = ch as u32; + if '\u{2800}' <= ch && ch <= '\u{28ff}' { // braille -- leave as braille + return Ok(self.escape_string_for_safety(String::from(ch))); + } else { // Emulate what NVDA does: generate (including single quotes) '\xhhhh' or '\yhhhhhh' + let prefix_indicator = if ch_as_int < 1<<16 {'x'} else {'y'}; + return self.replace_chars( &format!("'\\{prefix_indicator}{:06x}'", ch_as_int), mathml); + } + } } - } - }; + }; // map across all the parts of the replacement, collect them up into a Vec, and then concat them together let result = replacements.unwrap() From 52d91c23930daaf49f913895668bd6e2e869860f Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Wed, 5 Aug 2026 11:58:32 -0700 Subject: [PATCH 011/157] UEB has a rule for some pseudo-script chars. The match for that rule was overly broad, so I removed scripted letters and numbers. That rule made its way into other braille codes, so I removed them everywhere. All tests pass. --- Rules/Braille/CMU/CMU_Rules.yaml | 30 ++++++++++++------------ Rules/Braille/Swedish/Swedish_Rules.yaml | 2 +- Rules/Braille/UEB/UEB_Rules.yaml | 2 +- Rules/Braille/Vietnam/Vietnam_Rules.yaml | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Rules/Braille/CMU/CMU_Rules.yaml b/Rules/Braille/CMU/CMU_Rules.yaml index fb53fbeb8..3b5c59a40 100644 --- a/Rules/Braille/CMU/CMU_Rules.yaml +++ b/Rules/Braille/CMU/CMU_Rules.yaml @@ -598,7 +598,7 @@ - name: single-char-exceptions # 4.3.1 tag: msup - match: "*[2][translate(., \"'*`+-ª°²³´¹º‘’“”‟‵‶‷\",'')='']" + match: "*[2][translate(., \"'*`+-´°‘’“”‟‵‶‷\",'')='']" replace: - x: "*" - test: @@ -609,7 +609,7 @@ - name: single-char-exceptions # 4.3.1 tag: msubsup - match: "*[3][translate(., \"'*`+-ª°²³´¹º‘’“”‟‵‶‷\",'')='']" + match: "*[3][translate(., \"'*`+-´°‘’“”‟‵‶‷\",'')='']" replace: - x: "*[1]" - x: "*[3]" @@ -633,8 +633,8 @@ name: number-char-exceptions # 4.3.1 (FIX: degree doesn't use dot-3 for chemistry or temp/angles/etc) tag: [msub, msup] match: - - "*[2][translate(., \"'*`+-∞ª°²³´¹º‘’“”‟‵‶‷\",'')=''] or" - - "*[2][self::m:mrow and count(*)=2 and *[1][self::m:mn] and *[2][self::m:mo][translate(., \"'*`+-ª°²³´¹º‘’“”‟‵‶‷\",'')='']]" + - "*[2][translate(., \"'*`+-∞´°‘’“”‟‵‶‷\",'')=''] or" + - "*[2][self::m:mrow and count(*)=2 and *[1][self::m:mn] and *[2][self::m:mo][translate(., \"'*`+-´°‘’“”‟‵‶‷\",'')='']]" replace: - x: "*[1]" - test: @@ -779,7 +779,7 @@ replace: - x: "*[1]" - test: # special case superscript postscripts that preceed the prescripts - if: "$Postscripts and not($Postscripts[2][self::m:none]) and $Postscripts[2][translate(., \"′″‴⁗'*`+-ª°²³´¹º‘’“”‟‵‶‷\",'')='']" + if: "$Postscripts and not($Postscripts[2][self::m:none]) and $Postscripts[2][translate(., \"′″‴⁗'*`+-´°‘’“”‟‵‶‷\",'')='']" then: - x: "$Postscripts[2]" - test: @@ -805,7 +805,7 @@ # degree doesn't use dot-3 for chemistry, temp, angles -- can't know that so we make a wild guess here if: "not($Prescripts[1][.='°'] and *[1][self::m:mn or @data-chem-element])" then: [t: "⠄"] - - else_if: "$Prescripts[1][translate(., \"'*`+-ª°²³´¹º‘’“”‟‵‶‷\",'')='']" + - else_if: "$Prescripts[1][translate(., \"'*`+-´°‘’“”‟‵‶‷\",'')='']" then: - x: "$Prescripts[1]" - test: @@ -835,7 +835,7 @@ # degree doesn't use dot-3 for chemistry, temp, angles -- can't know that so we make a wild guess here if: "not($Prescripts[2][.='°'] and *[1][self::m:mn or @data-chem-element])" then: [t: "⠄"] - - else_if: "$Prescripts[2][translate(., \"'*`+-ª°²³´¹º‘’“”‟‵‶‷\",'')='']" + - else_if: "$Prescripts[2][translate(., \"'*`+-´°‘’“”‟‵‶‷\",'')='']" then: - x: "$Prescripts[2]" - test: @@ -868,7 +868,7 @@ # degree doesn't use dot-3 for chemistry, temp, angles -- can't know that so we make a wild guess here if: "not($Prescripts[3][.='°'] and *[1][self::m:mn or @data-chem-element])" then: [t: "⠄"] - - else_if: "$Prescripts[3][translate(., \"'*`+-ª°²³´¹º‘’“”‟‵‶‷\",'')='']" + - else_if: "$Prescripts[3][translate(., \"'*`+-´°‘’“”‟‵‶‷\",'')='']" then: - x: "$Prescripts[3]" - test: @@ -898,7 +898,7 @@ # degree doesn't use dot-3 for chemistry, temp, angles -- can't know that so we make a wild guess here if: "not($Prescripts[4][.='°'] and *[1][self::m:mn or @data-chem-element])" then: [t: "⠄"] - - else_if: "$Prescripts[4][translate(., \"'*`+-ª°²³´¹º‘’“”‟‵‶‷\",'')='']" + - else_if: "$Prescripts[4][translate(., \"'*`+-´°‘’“”‟‵‶‷\",'')='']" then: - x: "$Prescripts[4]" - test: @@ -935,7 +935,7 @@ # degree doesn't use dot-3 for chemistry, temp, angles -- can't know that so we make a wild guess here if: "not($Postscripts[1][.='°'] and *[1][self::m:mn or @data-chem-element])" then: [t: "⠄"] - - else_if: "$Postscripts[1][translate(., \"'*`+-ª°²³´¹º‘’“”‟‵‶‷\",'')='']" + - else_if: "$Postscripts[1][translate(., \"'*`+-´°‘’“”‟‵‶‷\",'')='']" then: - x: "$Postscripts[1]" - test: @@ -950,7 +950,7 @@ else: - x: "$Postscripts[1]" - test: - if: "not($Postscripts[2][self::m:none]) and $Postscripts[2][translate(., \"′″‴⁗'*`+-ª°²³´¹º‘’“”‟‵‶‷\",'')!='']" + if: "not($Postscripts[2][self::m:none]) and $Postscripts[2][translate(., \"′″‴⁗'*`+-´°‘’“”‟‵‶‷\",'')!='']" then: - t: "⠡" - test: @@ -991,7 +991,7 @@ # degree doesn't use dot-3 for chemistry, temp, angles -- can't know that so we make a wild guess here if: "not($Postscripts[3][.='°'] and *[1][self::m:mn or @data-chem-element])" then: [t: "⠄"] - - else_if: "$Postscripts[3][translate(., \"'*`+-ª°²³´¹º‘’“”‟‵‶‷\",'')='']" + - else_if: "$Postscripts[3][translate(., \"'*`+-´°‘’“”‟‵‶‷\",'')='']" then: - x: "$Postscripts[3]" - test: @@ -1021,7 +1021,7 @@ # degree doesn't use dot-3 for chemistry, temp, angles -- can't know that so we make a wild guess here if: "not($Postscripts[4][.='°'] and *[1][self::m:mn or @data-chem-element])" then: [t: "⠄"] - - else_if: "$Postscripts[4][translate(., \"'*`+-ª°²³´¹º‘’“”‟‵‶‷\",'')='']" + - else_if: "$Postscripts[4][translate(., \"'*`+-´°‘’“”‟‵‶‷\",'')='']" then: - x: "$Postscripts[4]" - test: @@ -1054,7 +1054,7 @@ # degree doesn't use dot-3 for chemistry, temp, angles -- can't know that so we make a wild guess here if: "not($Postscripts[5][.='°'] and *[1][self::m:mn or @data-chem-element])" then: [t: "⠄"] - - else_if: "$Postscripts[5][translate(., \"'*`+-ª°²³´¹º‘’“”‟‵‶‷\",'')='']" + - else_if: "$Postscripts[5][translate(., \"'*`+-´°‘’“”‟‵‶‷\",'')='']" then: - x: "$Postscripts[5]" - test: @@ -1084,7 +1084,7 @@ # degree doesn't use dot-3 for chemistry, temp, angles -- can't know that so we make a wild guess here if: "not($Postscripts[6][.='°'] and *[1][self::m:mn or @data-chem-element])" then: [t: "⠄"] - - else_if: "$Postscripts[6][translate(., \"'*`+-ª°²³´¹º‘’“”‟‵‶‷\",'')='']" + - else_if: "$Postscripts[6][translate(., \"'*`+-´°‘’“”‟‵‶‷\",'')='']" then: - x: "$Postscripts[6]" - test: diff --git a/Rules/Braille/Swedish/Swedish_Rules.yaml b/Rules/Braille/Swedish/Swedish_Rules.yaml index 028574914..7a8504574 100644 --- a/Rules/Braille/Swedish/Swedish_Rules.yaml +++ b/Rules/Braille/Swedish/Swedish_Rules.yaml @@ -348,7 +348,7 @@ - name: single-char-exceptions # RUEB 3.11 -- ° and various prime/minute/seconds aren't treated as if superscripts tag: msup - match: "*[2][translate(., \"'*`ª°²³´¹º‘’“”‟′″‴‵‶‷⁗\",'')='']" + match: "*[2][translate(., \"'*`´°‘’“”‟′″‴‵‶‷⁗\",'')='']" replace: - test: if: "NeedsToBeGrouped(*[1], 'Swedish', true())" diff --git a/Rules/Braille/UEB/UEB_Rules.yaml b/Rules/Braille/UEB/UEB_Rules.yaml index b9e9acb79..8e3491c80 100644 --- a/Rules/Braille/UEB/UEB_Rules.yaml +++ b/Rules/Braille/UEB/UEB_Rules.yaml @@ -340,7 +340,7 @@ - name: single-char-exceptions # RUEB 3.11 -- ° and various prime/minute/seconds aren't treated as if superscripts tag: [msup] - match: "*[2][translate(., \"'*`ª°²³´¹º‘’“”‟′″‴‵‶‷⁗\",'')='']" + match: "*[2][translate(., \"'*`´°‘’“”‟′″‴‵‶‷⁗\",'')='']" replace: - test: if: "NeedsToBeGrouped(*[1], 'UEB', true())" diff --git a/Rules/Braille/Vietnam/Vietnam_Rules.yaml b/Rules/Braille/Vietnam/Vietnam_Rules.yaml index 88947d646..2b43067be 100644 --- a/Rules/Braille/Vietnam/Vietnam_Rules.yaml +++ b/Rules/Braille/Vietnam/Vietnam_Rules.yaml @@ -437,7 +437,7 @@ - name: single-char-exceptions # RUEB 3.11 -- ° and various prime/minute/seconds aren't treated as if superscripts tag: msup - match: "*[2][translate(., \"'*`ª°²³´¹º‘’“”‟′″‴‵‶‷⁗\",'')='']" + match: "*[2][translate(., \"'*`´°‘’“”‟′″‴‵‶‷⁗\",'')='']" replace: [x: "*"] - From baf7de6c4c4cb70e53eb3b5edc849c781e59bb76 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Wed, 5 Aug 2026 12:00:12 -0700 Subject: [PATCH 012/157] =?UTF-8?q?Added=20new=20UEB=20chars.=20Many=20of?= =?UTF-8?q?=20these=20are=20accented=20letters.=20I=20added=20'A'=20(for?= =?UTF-8?q?=20accented=20letters)=20so=20that=20the=20pattern=20for=20them?= =?UTF-8?q?=20looks=20like:=20```=20=20-=20"=C3=91":=20[t:=20"CA=E2=A0=98?= =?UTF-8?q?=E2=A0=BBL=E2=A0=9D"]=20=20=20=20=20=20=20=20=20=20=20=20=20#?= =?UTF-8?q?=200x00D1=20```?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added a few tests. --- Rules/Braille/UEB/unicode-full.yaml | 146 ++++++++++++++++++++++++++- Rules/Braille/UEB/unicode.yaml | 6 +- src/braille.rs | 149 +++++++++++++++++++++++++--- tests/braille/UEB/other.rs | 28 ++++++ 4 files changed, 308 insertions(+), 21 deletions(-) diff --git a/Rules/Braille/UEB/unicode-full.yaml b/Rules/Braille/UEB/unicode-full.yaml index df7bf2274..48bc20ead 100644 --- a/Rules/Braille/UEB/unicode-full.yaml +++ b/Rules/Braille/UEB/unicode-full.yaml @@ -44,8 +44,150 @@ - "⅜": [tc: "#N⠉N⠌N⠓"] # 0x215C (Vulgar Fraction Three Eighths) - "⅝": [tc: "#N⠑N⠌N⠓"] # 0x215D (Vulgar Fraction Five Eighths) - "⅞": [tc: "#N⠛N⠌N⠓"] # 0x215E (Vulgar Fraction Seven Eighths) - - "↉": [tc: "#N⠚N⠌N⠑"] # 0x2189 (Vulgar Fraction Zero Thirds) - + - "↉": [tc: "#N⠚N⠌N⠉"] # 0x2189 (Vulgar Fraction Zero Thirds) + + # --- UEB_Additions1 (ordered by Unicode; Å/–/≣ remain in unicode.yaml) --- + - "`": [t: "⠨⠡"] # 0x0060 + - "¡": [t: "⠘⠰⠖"] # 0x00A1 + - "§": [t: "⠘⠎"] # 0x00A7 + - "­": [t: "⠤"] # 0x00AD (soft hyphen) + - "®": [t: "⠘⠗"] # 0x00AE + - "¯": [t: "⠱"] # 0x00AF + - "²": # 0x00B2 + - test: + if: "(parent::m:msup or parent::m:msubsup) and not(following-sibling::*)" + then: [t: "⠼⠃"] + else: [t: "1⠔⠼⠃"] + - "³": # 0x00B3 + - test: + if: "(parent::m:msup or parent::m:msubsup) and not(following-sibling::*)" + then: [t: "⠼⠉"] + else: [t: "1⠔⠼⠉"] + - "¶": [t: "⠘⠏"] # 0x00B6 + - "¹": # 0x00B9 + - test: + if: "(parent::m:msup or parent::m:msubsup) and not(following-sibling::*)" + then: [t: "⠼⠁"] + else: [t: "1⠔⠼⠁"] + - "¿": [t: "⠘⠰⠦"] # 0x00BF + - "À": [t: "CA⠘⠡L⠁"] # 0x00C0 + - "Á": [t: "CA⠘⠌L⠁"] # 0x00C1 + - "Â": [t: "CA⠘⠩L⠁"] # 0x00C2 + - "Ã": [t: "CA⠘⠻L⠁"] # 0x00C3 + - "Ä": [t: "CA⠘⠒L⠁"] # 0x00C4 + - "Æ": [t: "C⠁⠠⠘⠖⠑"] # 0x00C6 + - "Ç": [t: "CA⠘⠯L⠉"] # 0x00C7 + - "È": [t: "CA⠘⠡L⠑"] # 0x00C8 + - "É": [t: "CA⠘⠌L⠑"] # 0x00C9 + - "Ê": [t: "CA⠘⠩L⠑"] # 0x00CA + - "Ë": [t: "CA⠘⠒L⠑"] # 0x00CB + - "Ì": [t: "CA⠘⠡L⠊"] # 0x00CC + - "Í": [t: "CA⠘⠌L⠊"] # 0x00CD + - "Î": [t: "CA⠘⠩L⠊"] # 0x00CE + - "Ï": [t: "CA⠘⠒L⠊"] # 0x00CF + - "Ð": [t: "C⠼⠫"] # 0x00D0 + - "Ñ": [t: "CA⠘⠻L⠝"] # 0x00D1 + - "Ò": [t: "CA⠘⠡L⠕"] # 0x00D2 + - "Ó": [t: "CA⠘⠌L⠕"] # 0x00D3 + - "Ô": [t: "CA⠘⠩L⠕"] # 0x00D4 + - "Õ": [t: "CA⠘⠻L⠕"] # 0x00D5 + - "Ö": [t: "CA⠘⠒L⠕"] # 0x00D6 + - "Ø": [t: "CA⠈⠡L⠕"] # 0x00D8 + - "Ù": [t: "CA⠘⠡L⠥"] # 0x00D9 + - "Ú": [t: "CA⠘⠌L⠥"] # 0x00DA + - "Û": [t: "CA⠘⠩L⠥"] # 0x00DB + - "Ü": [t: "CA⠘⠒L⠥"] # 0x00DC + - "Ý": [t: "CA⠘⠌L⠽"] # 0x00DD + - "Þ": [t: "C⠼⠮"] # 0x00DE + - "ß": [t: "⠨⠮"] # 0x00DF + - "à": [t: "A⠘⠡L⠁"] # 0x00E0 + - "á": [t: "A⠘⠌L⠁"] # 0x00E1 + - "â": [t: "A⠘⠩L⠁"] # 0x00E2 + - "ã": [t: "A⠘⠻L⠁"] # 0x00E3 + - "ä": [t: "A⠘⠒L⠁"] # 0x00E4 + - "å": [t: "A⠘⠫L⠁"] # 0x00E5 + - "æ": [t: "⠁⠘⠖⠑"] # 0x00E6 + - "ç": [t: "A⠘⠯L⠉"] # 0x00E7 + - "è": [t: "A⠘⠡L⠑"] # 0x00E8 + - "é": [t: "A⠘⠌L⠑"] # 0x00E9 + - "ê": [t: "A⠘⠩L⠑"] # 0x00EA + - "ë": [t: "A⠘⠒L⠑"] # 0x00EB + - "ì": [t: "A⠘⠡L⠊"] # 0x00EC + - "í": [t: "A⠘⠌L⠊"] # 0x00ED + - "î": [t: "A⠘⠩L⠊"] # 0x00EE + - "ï": [t: "A⠘⠒L⠊"] # 0x00EF + - "ð": [t: "⠼⠫"] # 0x00F0 + - "ñ": [t: "A⠘⠻L⠝"] # 0x00F1 + - "ò": [t: "A⠘⠡L⠕"] # 0x00F2 + - "ó": [t: "A⠘⠌L⠕"] # 0x00F3 + - "ô": [t: "A⠘⠩L⠕"] # 0x00F4 + - "õ": [t: "A⠘⠻L⠕"] # 0x00F5 + - "ö": [t: "A⠘⠒L⠕"] # 0x00F6 + - "ø": [t: "A⠈⠡L⠕"] # 0x00F8 + - "ù": [t: "A⠘⠡L⠥"] # 0x00F9 + - "ú": [t: "A⠘⠌L⠥"] # 0x00FA + - "û": [t: "A⠘⠩L⠥"] # 0x00FB + - "ü": [t: "A⠘⠒L⠥"] # 0x00FC + - "ý": [t: "A⠘⠌L⠽"] # 0x00FD + - "þ": [t: "⠼⠮"] # 0x00FE + - "ÿ": [t: "A⠘⠒L⠽"] # 0x00FF + - "Ÿ": [t: "CA⠘⠒L⠽"] # 0x0178 + - "ʹ": [t: "⠶"] # 0x02B9 + - "ʺ": [t: "⠶⠶"] # 0x02BA + - "˜": [t: "⠈⠔"] # 0x02DC + - "ẞ": [t: "C⠨⠮"] # 0x1E9E + - "‑": [t: "⠤"] # 0x2011 (non-breaking hyphen) + - "‒": [t: "⠤"] # 0x2012 (figure dash) + - "—": [t: "P⠠⠤"] # 0x2014 (em dash) + - "•": [t: "⠸⠲"] # 0x2022 + - "․": [t: "⠲"] # 0x2024 + - "‥": [t: "⠲⠲"] # 0x2025 + - "‼": [t: "⠖⠖"] # 0x203C + - "‾": [t: "⠱"] # 0x203E + - "⁇": [t: "⠦⠦"] # 0x2047 + - "⁈": [t: "⠦⠖"] # 0x2048 + - "⁉": [t: "⠖⠦"] # 0x2049 + - "⁗": [t: "⠶⠶⠶⠶"] # 0x2057 + - "⁰": # 0x2070 + - test: + if: "(parent::m:msup or parent::m:msubsup) and not(following-sibling::*)" + then: [t: "⠼⠚"] + else: [t: "1⠔⠼⠚"] + - "ⁱ": # 0x2071 + - test: + if: "(parent::m:msup or parent::m:msubsup) and not(following-sibling::*)" + then: [t: "⠊"] + else: [t: "1⠔⠊"] + - "⁴-⁹": # 0x2074 - 0x2079 + - test: + if: "(parent::m:msup or parent::m:msubsup) and not(following-sibling::*)" + then: [t: "⠼"] + else: [t: "1⠔⠼"] + - spell: "translate('.', '⁴⁵⁶⁷⁸⁹', '⠙⠑⠋⠛⠓⠊')" + - "⁺-⁾": # 0x207A - 0x207E + - test: + if: "(parent::m:msup or parent::m:msubsup) and not(following-sibling::*)" + then: [t: "⠐"] + else: [t: "1⠔⠐"] + - spell: "translate('.', '⁺⁻⁼⁽⁾', '⠖⠤⠶⠣⠜')" + - "ⁿ": # 0x207F + - test: + if: "(parent::m:msup or parent::m:msubsup) and not(following-sibling::*)" + then: [t: "⠝"] + else: [t: "1⠔⠝"] + - "₀-₉": # 0x2080 - 0x2089 + - test: + if: "(parent::m:msub or parent::m:msubsup) and count(preceding-sibling::*) = 1" + then: [t: "⠼"] + else: [t: "1⠢⠼"] + - spell: "translate('.', '₀₁₂₃₄₅₆₇₈₉', '⠚⠁⠃⠉⠙⠑⠋⠛⠓⠊')" + - "₊-₎": # 0x208A - 0x208E + - test: + if: "(parent::m:msub or parent::m:msubsup) and count(preceding-sibling::*) = 1" + then: [t: "⠐"] + else: [t: "1⠢⠐"] + - spell: "translate('.', '₊₋₌₍₎', '⠖⠤⠶⠣⠜')" + - "™": [t: "⠘⠞"] # 0x2122 - "ℊ": [tc: "TL⠛⠁"] # 0x210a (Script Small G) - "ℋ": [tc: "TCL⠓⠁"] # 0x210b (Script Capital H) diff --git a/Rules/Braille/UEB/unicode.yaml b/Rules/Braille/UEB/unicode.yaml index 3256d59c5..e1b513bc8 100644 --- a/Rules/Braille/UEB/unicode.yaml +++ b/Rules/Braille/UEB/unicode.yaml @@ -103,7 +103,7 @@ - "~": [t: "⠈⠔"] # 0x007E (Tilde (swung dash)) - "¢": [t: "⠈⠉"] # 0x00A2 (Cents sign) - "‐": [t: "⠤"] # 0x2010 (Hyphen) - - "–": [t: "⠠⠤"] # 0x2013 (En Dash) + - "–": [t: "P⠠⠤"] # 0x2013 (En Dash) - "―": [t: "⠐⠠⠤"] # 0x2015 (Horizontal Bar) - "‖": [t: "⠸⠳"] # 0x2016 - "€": [t: "⠈⠑"] # 0x20AC (Euro sign) @@ -123,8 +123,8 @@ - "‴": [t: "1⠶⠶⠶"] # 0x2034 (Triple prime sign) - "℃": [t: "⠘⠚⠠⠉"] # 0x2103 (Degrees Celsius) - "℉": [t: "⠘⠚⠠⠋"] # 0x2109 (Degrees Fahrenheit) - - "Å": [t: "⠠⠘⠫⠁"] # 0x212B (Angstrom symbol) - - "Å": [t: "⠠⠘⠫⠁"] # 0x00C5 (WIRIS uses this for Angstrom) + - "Å": [t: "CA⠘⠫L⠁"] # 0x212B (Angstrom symbol) + - "Å": [t: "CA⠘⠫L⠁"] # 0x00C5 (WIRIS uses this for Angstrom) - "∀": [t: "⠘⠁"] # 0x2200 (For all) - "∂": [t: "⠈⠙"] # 0x2202 (Partial differential) - "∃": [t: "⠘⠢"] # 0x2203 (There exists) diff --git a/src/braille.rs b/src/braille.rs index 2b7b5b34a..54fd1a45c 100644 --- a/src/braille.rs +++ b/src/braille.rs @@ -896,6 +896,7 @@ static UEB_INDICATOR_REPLACEMENTS: phf::Map<&str, &str> = phf_map! { "1" => "⠰", // Grade 1 symbol "𝟙" => "⠰⠰", // Grade 1 word "L" => "", // Letter left in to assist in locating letters + "A" => "", // Letter accent indicator -- should be followed by accent cells and then "L" for char "D" => "XXX", // German (Deutsche) -- from prefs "G" => "⠨", // Greek "V" => "⠨⠈", // Greek Variants @@ -934,6 +935,24 @@ fn is_letter_number(ch: char) -> bool { matches!(ch, '⠁' | '⠃' | '⠉' | '⠙' | '⠑' | '⠋' | '⠛' | '⠓' | '⠊' | '⠚') } +fn is_braille_char(ch: char) -> bool { + ('\u{2800}'..='\u{28ff}').contains(&ch) +} + +/// After an 'A' accent indicator, skip accent braille cells and return the index of the following 'L'. +/// Returns None if the accented-letter pattern is malformed. +fn index_after_accent_to_l(chars: &[char], after_a: usize) -> Option { + let mut j = after_a; + while j < chars.len() && is_braille_char(chars[j]) { + j += 1; + } + if j < chars.len() && chars[j] == 'L' { + Some(j) + } else { + None + } +} + static SHORT_FORMS: phf::Set<&str> = phf_set! { "L⠁L⠃", "L⠁L⠃L⠧", "L⠁L⠉", "L⠁L⠉L⠗", "L⠁L⠋", "L⠁L⠋L⠝", "L⠁L⠋L⠺", "L⠁L⠛", "L⠁L⠛L⠌", "L⠁L⠇", @@ -951,7 +970,7 @@ static SHORT_FORMS: phf::Set<&str> = phf_set! { }; fn is_letter_prefix(ch: char) -> bool { - matches!(ch, 'B' | 'I' | '𝔹' | 'S' | 'T' | 'D' | 'C' | '𝐶' | '𝑐') + matches!(ch, 'B' | 'I' | '𝔹' | 'S' | 'T' | 'D' | 'C' | '𝐶' | '𝑐' | 'A') } // Trim braille spaces before and after braille indicators @@ -959,7 +978,7 @@ fn is_letter_prefix(ch: char) -> bool { // Note: fraction over is not listed due to example 42(4) which shows a space before the "/" // static ref REMOVE_SPACE_BEFORE_BRAILLE_INDICATORS: Regex = // Regex::new(r"(⠄⠄⠄|⠤⠤⠤)W+([⠼⠸⠪])").unwrap(); -static REPLACE_INDICATORS: LazyLock = LazyLock::new(|| Regex::new(r"([1𝟙SB𝔹TIREDGVHP𝐶𝑐CLMNW𝐖swe,.-—―#ocb])").unwrap()); +static REPLACE_INDICATORS: LazyLock = LazyLock::new(|| Regex::new(r"([1𝟙SB𝔹TIREDGVHP𝐶𝑐CLAMNW𝐖swe,.-—―#ocb])").unwrap()); static COLLAPSE_SPACES: LazyLock = LazyLock::new(|| Regex::new(r"⠀⠀+").unwrap()); /// Transcriber-defined typeforms pulled from prefs (their braille is configurable), used by the @@ -1341,6 +1360,16 @@ fn capitals_to_word_mode(braille: &str) -> String { // Greek letters are a bit exceptional in that the pattern is "CGLx" -- bump 'i' next_non_cap += 1; } + if chars[next_non_cap] == 'A' { + // Accented capital: CA...Lx + match index_after_accent_to_l(&chars, next_non_cap + 1) { + Some(i_l) => next_non_cap = i_l, + None => { + error!("capitals_to_word_mode: internal error: didn't find L after CA in '{}'.", + chars[i..].iter().take(8).collect::()); + } + } + } if chars[next_non_cap] != 'L' { error!("capitals_to_word_mode: internal error: didn't find L after C in '{}'.", chars[i..next_non_cap+2].iter().collect::().as_str()); @@ -1348,6 +1377,25 @@ fn capitals_to_word_mode(braille: &str) -> String { let i_braille_char = next_non_cap + 2; result.push_str(String::from_iter(&chars[i..i_braille_char]).as_str()); i = i_braille_char; + } else if ch == 'A' { + // Lowercase accented letter: A...Lx + if is_word_mode { + result.push('e'); + is_word_mode = false; + } + match index_after_accent_to_l(&chars, i + 1) { + Some(i_l) => { + let i_braille_char = i_l + 2; + result.push_str(String::from_iter(&chars[i..i_braille_char]).as_str()); + i = i_braille_char; + } + None => { + error!("capitals_to_word_mode: internal error: didn't find L after A in '{}'.", + chars[i..].iter().take(8).collect::()); + result.push(ch); + i += 1; + } + } } else if ch == 'L' { // must be lowercase -- uppercase consumed above // assert!(LETTERS.contains(&unhighlight(chars[i+1]))); not true for other alphabets if is_word_mode { @@ -1562,15 +1610,23 @@ fn remove_unneeded_mode_changes(raw_braille: &str, start_mode: UEB_Mode, start_d match ch { 'L' => { // note: be aware of '#' case for Numeric because '1' might already be generated - // let prev_ch = if i > 1 {chars[i-1]} else {'1'}; // '1' -- anything beside ',' or '.' - // if duration == UEB_Duration::Symbol || - // ( ",. ".contains(prev_ch) && LETTER_NUMBERS.contains(&unhighlight(chars[i+1])) ) { - // result.push('1'); // need to retain grade 1 indicator (RUEB 6.5.2) - // } // let the default case handle pushing on the chars for the letter result.push(ch); i += 1; }, + 'A' => { + // Accented letter: keep A...Lx together so accent cells don't end G1 symbol mode + match index_after_accent_to_l(&chars, i + 1) { + Some(i_l) => { + result.extend(chars[i..i_l + 2].iter().copied()); // A + accents + L + letter + i = i_l + 2; + } + None => { + result.push(ch); + i += 1; + } + } + }, '1' | '𝟙' => { assert!(ch == '1' || duration != UEB_Duration::Symbol); // if '𝟙', should be Word or Passage duration // nothing to do -- let the default case handle the following chars @@ -1629,14 +1685,29 @@ fn remove_unneeded_mode_changes(raw_braille: &str, start_mode: UEB_Mode, start_d i += right_matched_chars.len(); }, 'C' => { - // Want 'C' before 'L'; Could be CC for word cap -- if so, eat it and move on + // Want 'C' before 'L' (or 'CA...L' / 'CGL'). Could be CC for word cap -- if so, eat it and move on // Note: guaranteed that there is a char after the 'C', so chars[i+1] is safe if chars[i+1] == 'C' { cap_word_mode = true; i += 1; } else { - let is_greek = chars[i+1] == 'G'; - let (is_alone, right_matched_chars, n_letters) = stands_alone(&chars, if is_greek {i+2} else {i+1}); + let mut letter_idx = i + 1; + let is_greek = chars[letter_idx] == 'G'; + if is_greek { + letter_idx += 1; + } + if letter_idx < chars.len() && chars[letter_idx] == 'A' { + match index_after_accent_to_l(&chars, letter_idx + 1) { + Some(i_l) => letter_idx = i_l, + None => { + error!("Internal error: 'CA' without L at index={i} in '{raw_braille}'"); + result.push('C'); + i += 1; + continue; + } + } + } + let (is_alone, right_matched_chars, n_letters) = stands_alone(&chars, letter_idx); // GTM 1.2.1 says we only need to use G1 for single letters or sequences that are a shortform (e.g, "ab") if is_alone && (n_letters == 1 || is_short_form(&right_matched_chars[..2*n_letters])) { // debug!(" is_alone -- pushing '1'"); @@ -1649,12 +1720,33 @@ fn remove_unneeded_mode_changes(raw_braille: &str, start_mode: UEB_Mode, start_d result.push('C'); if is_greek { result.push('G'); - i += 1; } start_g2_letter = Some(i); - // debug!(" pushing 'C' + {:?}", right_matched_chars); + // right_matched starts at A or L (not including C/G) right_matched_chars.iter().for_each(|&ch| result.push(ch)); - i += 1 + right_matched_chars.len(); + i += 1 + if is_greek {1} else {0} + right_matched_chars.len(); + } + }, + 'A' => { + // Accented lowercase letter: A...Lx + match index_after_accent_to_l(&chars, i + 1) { + Some(i_l) => { + if start_g2_letter.is_none() { + start_g2_letter = Some(i); + } + let (is_alone, right_matched_chars, n_letters) = stands_alone(&chars, i_l); + if is_alone && (n_letters == 1 || is_short_form(&right_matched_chars[..2*n_letters])) { + result.push('1'); + mode = UEB_Mode::Grade1; + } + right_matched_chars.iter().for_each(|&ch| result.push(ch)); + i += right_matched_chars.len(); + } + None => { + error!("Internal error: 'A' without L at index={i} in '{raw_braille}'"); + result.push(ch); + i += 1; + } } }, '1' => { @@ -1747,8 +1839,21 @@ fn stands_alone(chars: &[char], i: usize) -> (bool, &[char], usize) { // we scan forward and check the conditions for "standing-alone" assert_eq!(chars[i], 'L', "'stands_alone' starts with non 'L'"); // debug!("stands_alone: i={}, chars: {:?}", i, chars); - if !left_side_stands_alone(&chars[0..i]) { - return (false, &chars[i..i+2], 0); + // Exclude accent prefix A... immediately before this L (part of the same letter) + let mut letter_start = i; + let mut left_end = i; + if left_end > 0 { + let mut j = left_end; + while j > 0 && is_braille_char(chars[j - 1]) { + j -= 1; + } + if j > 0 && chars[j - 1] == 'A' { + letter_start = j - 1; + left_end = j - 1; + } + } + if !left_side_stands_alone(&chars[0..left_end]) { + return (false, &chars[letter_start..i+2], 0); } let (mut is_alone, n_letters, n_right_matched) = right_side_stands_alone(&chars[i+2..]); @@ -1760,7 +1865,8 @@ fn stands_alone(chars: &[char], i: usize) -> (bool, &[char], usize) { is_alone = false; } } - return (is_alone, &chars[i..i+2+n_right_matched], n_letters); + // Include any A... prefix so callers emit the full accented letter + return (is_alone, &chars[letter_start..i+2+n_right_matched], n_letters); /// chars before 'L' fn left_side_stands_alone(chars: &[char]) -> bool { @@ -1804,6 +1910,17 @@ fn stands_alone(chars: &[char], i: usize) -> (bool, &[char], usize) { if !intervening_chars_mode && ch == 'L' { n_letters += 1; i += 1; // ignore 'Lx' and also ignore 'ox' + } else if !intervening_chars_mode && ch == 'A' { + // Accented letter A...Lx counts as one letter + match index_after_accent_to_l(chars, i + 1) { + Some(i_l) => { + n_letters += 1; + i = i_l + 1; // now at letter braille; loop end advances past it + } + None => { + return (false, n_letters, i); + } + } } else if ch == 'c' || ch == 'b' { i += 1; // ignore 'Lx' and also ignore 'ox' } else if is_right_intervening_char(ch) { diff --git a/tests/braille/UEB/other.rs b/tests/braille/UEB/other.rs index 0c60e27db..35c7cfcf0 100644 --- a/tests/braille/UEB/other.rs +++ b/tests/braille/UEB/other.rs @@ -199,3 +199,31 @@ fn caps_bug_295() -> Result<()> { return Ok(()); } + +#[test] +fn unicode_superscript_chars_in_and_out_of_script_position() -> Result<()> { + // Scripted: msup adds ⠔; unicode then-clause omits 1 and ⠔ so result matches non-scripted + let expr = "x¹"; + test_braille("UEB", expr, "⠭⠰⠔⠼⠁")?; + let expr = "x¹"; + test_braille("UEB", expr, "⠭⠰⠔⠼⠁")?; + let expr = "x⁺"; + test_braille("UEB", expr, "⠭⠰⠔⠐⠖")?; + let expr = "x⁺"; + test_braille("UEB", expr, "⠭⠰⠔⠐⠖")?; + return Ok(()); +} + +#[test] +fn unicode_subscript_chars_in_and_out_of_script_position() -> Result<()> { + let expr = "x₁"; + test_braille("UEB", expr, "⠭⠰⠢⠼⠁")?; + let expr = "x₁"; + test_braille("UEB", expr, "⠭⠰⠢⠼⠁")?; + let expr = "x₊"; + test_braille("UEB", expr, "⠭⠰⠢⠐⠖")?; + let expr = "x₊"; + test_braille("UEB", expr, "⠭⠰⠢⠐⠖")?; + return Ok(()); +} + From 916978c0416687a93e452f0a87cd2bcf9d06c711 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Wed, 5 Aug 2026 22:25:32 -0700 Subject: [PATCH 013/157] change small spaces from 'W' to '' --- Rules/Braille/Nemeth/unicode-full.yaml | 12 ++++++------ Rules/Braille/UEB/unicode-full.yaml | 13 ++++++------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Rules/Braille/Nemeth/unicode-full.yaml b/Rules/Braille/Nemeth/unicode-full.yaml index 06831aec3..13245da4e 100644 --- a/Rules/Braille/Nemeth/unicode-full.yaml +++ b/Rules/Braille/Nemeth/unicode-full.yaml @@ -1047,21 +1047,21 @@ - " ": [t: "W"] # 0x2003 - " ": [t: "W"] # 0x2004 - " ": [t: "W"] # 0x2005 - - " ": [t: "W"] # 0x2006 + - " ": [t: ""] # 0x2006 (six-per-em) - " ": [t: "W"] # 0x2007 - " ": [t: "W"] # 0x2008 - - " ": [t: "W"] # 0x2009 - - " ": [t: "W"] # 0x200a - - "​": [t: "W"] # 0x200b + - " ": [t: ""] # 0x2009 (thin space) + - " ": [t: ""] # 0x200a (hair space) + - "​": [t: ""] # 0x200b (zero-width space) - "
": [t: "W"] # 0x2028 - "
": [t: "W"] # 0x2029 - - " ": [t: "W"] # 0x202f + - " ": [t: ""] # 0x202f (narrow no-break space) - " ": [t: "W"] # 0x205f - "₣": [t: "⠈⠋"] # 0x20A3 (French franc sign - "₦": [t: "⠈⠝"] # 0x2046 (Naira sign) - "₩": [t: "⠈⠺"] # 0x20A9 (Won sign) - "€": [t: "⠈⠑"] # 0x20AC (Euro sign) - - "": [t: "W"] # 0xfeff + - "": [t: ""] # 0xfeff (BOM / ZWNBSP) - "☆": [t: "⠫⠎"] # 0x2606 - "✕": [t: "⠈⠡"] # 0x2715 - "¼": [t: "⠹⠂⠌⠲⠼"] # 0xbc diff --git a/Rules/Braille/UEB/unicode-full.yaml b/Rules/Braille/UEB/unicode-full.yaml index 48bc20ead..750493ef8 100644 --- a/Rules/Braille/UEB/unicode-full.yaml +++ b/Rules/Braille/UEB/unicode-full.yaml @@ -6,18 +6,17 @@ - " ": [t: "W"] # 0x2003 - " ": [t: "W"] # 0x2004 - " ": [t: "W"] # 0x2005 - - " ": [t: "W"] # 0x2006 + - " ": [t: ""] # 0x2006 (six-per-em) - " ": [t: "W"] # 0x2007 - " ": [t: "W"] # 0x2008 - - " ": [t: "W"] # 0x2009 - - " ": [t: "W"] # 0x200a - - "​": [t: "W"] # 0x200b + - " ": [t: ""] # 0x2009 (thin space) + - " ": [t: ""] # 0x200a (hair space) + - "​": [t: ""] # 0x200b (zero-width space) - "
": [t: "W"] # 0x2028 - "
": [t: "W"] # 0x2029 - - " ": [t: "W"] # 0x202f + - " ": [t: ""] # 0x202f (narrow no-break space) - " ": [t: "W"] # 0x205f - - "": [t: "W"] # 0xfeff - + - "": [t: ""] # 0xfeff (BOM / ZWNBSP) - "ℏ": [tc: "⠈⠒⠓"] # t: "B"F (reduced Plank's constant) - "ⅆ": [tc: "⠙"] # 0x2146 From 6bddbda41b79ade585c90168dc1c2655e3877c4b Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 6 Aug 2026 14:33:20 -0700 Subject: [PATCH 014/157] add 'H' for Hebrew alphabet indicator --- src/braille.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/braille.rs b/src/braille.rs index 54fd1a45c..f3442a325 100644 --- a/src/braille.rs +++ b/src/braille.rs @@ -2390,13 +2390,14 @@ static FRENCH_INDICATOR_REPLACEMENTS: phf::Map<&str, &str> = phf_map! { // Keys match indicator chars emitted by French unicode.yaml, unicode-full.yaml, and French_Rules.yaml "S" => "XXX", // sans-serif -- from prefs "B" => "⠸", // bold - "𝔹" => "⠨", // blackboard -- from prefs + "𝔹" => "⠨", // blackboard "T" => "⠈", // script "I" => "⠸", // italic "1" => "⠀", // Grade 1 symbol (used for number followed by a letter) "L" => "", // Letter left in to assist in locating letters "D" => "XXX", // German (Deutsche) -- from prefs "G" => "⠘", // Greek + "H" => "⠘⠘", // Hebrew "C" => "⠨", // capital "𝐶" => "⠨", // capital that never should get whitespace in front (from chemical element) "N" => "", // number indicator @@ -2543,7 +2544,7 @@ fn letter_or_number_after_b( fn french_cleanup(_pref_manager: Ref, raw_braille: String) -> String { // FIX: need to implement this -- this is just a copy of the Vietnam code - static REPLACE_INDICATORS: LazyLock = LazyLock::new(|| Regex::new(r"([1SB𝔹TILDGC𝐶NWscocbe])").unwrap()); + static REPLACE_INDICATORS: LazyLock = LazyLock::new(|| Regex::new(r"([1SB𝔹TILDGHC𝐶NWscocbe])").unwrap()); debug!("french_cleanup: start={}", raw_braille); // let result = typeface_to_word_mode(&raw_braille); // let result = capitals_to_word_mode(&result); From 6af4178fde8a0c176dcdf28fd883d1704a5b2c73 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 6 Aug 2026 14:34:47 -0700 Subject: [PATCH 015/157] promote munder/mover/munderover base attrs to element -- prevents error!() message. May want to change the promoted name... --- src/chemistry.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/chemistry.rs b/src/chemistry.rs index b8a6ca4fc..f238985c1 100644 --- a/src/chemistry.rs +++ b/src/chemistry.rs @@ -523,6 +523,15 @@ fn set_marked_chemistry_attr(mathml: Element, chem: &str) { mathml.set_attribute_value(CHEM_EQUATION, "true"); } } + "munder" | "mover" | "munderover" => { + // inherit from the base + let base = as_element(mathml.children()[0]); + if let Some(base_chem) = base.attribute(CHEM_EQUATION_OPERATOR) { + mathml.set_attribute_value(CHEM_EQUATION_OPERATOR, base_chem.value()); + } else if let Some(base_chem) = base.attribute(CHEM_FORMULA_OPERATOR) { + mathml.set_attribute_value(CHEM_FORMULA_OPERATOR, base_chem.value()); + } + } _ => error!("Internal error: {} should not be marked as 'MAYBE_CHEMISTRY'", tag_name), } } else if tag_name == "mrow" { From 1046bd53ee4f97bf79c8ec88525ee5db22f44b2e Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 6 Aug 2026 17:50:53 -0700 Subject: [PATCH 016/157] all primes on chem symbols such as R' -- used to be a reject, now neutral --- src/chemistry.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/chemistry.rs b/src/chemistry.rs index f238985c1..4b991dcef 100644 --- a/src/chemistry.rs +++ b/src/chemistry.rs @@ -1020,6 +1020,10 @@ fn likely_chem_superscript(sup: Element) -> i32 { sup.set_attribute_value("data-number", small_roman_to_number(as_str!(as_text(sup)))); sup.set_attribute_value(MAYBE_CHEMISTRY, "2"); return 2; + } else if sup_name == "mo" && !as_text(sup).is_empty() && as_str!(as_text(sup)).trim_matches(['\'', '′', '″', '‴']).is_empty() { + // primes distinguish generic groups (R, R', R'') -- neutral: don't add or rule out chemistry + sup.set_attribute_value(MAYBE_CHEMISTRY, "0"); + return 0; } else if sup_name == "mrow" { // look for something like '2+' let children = sup.children(); From af250aa4cab9c59540fe453f4f3081e4297c61a6 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 6 Aug 2026 17:54:29 -0700 Subject: [PATCH 017/157] Fix leftover value for G1 indicator -- unlike UEB, French braille numbers don't conflict with letters. Add code to handle `;` special case if there are "blocks" in the expr --- src/braille.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/braille.rs b/src/braille.rs index f3442a325..1038cb319 100644 --- a/src/braille.rs +++ b/src/braille.rs @@ -2393,7 +2393,7 @@ static FRENCH_INDICATOR_REPLACEMENTS: phf::Map<&str, &str> = phf_map! { "𝔹" => "⠨", // blackboard "T" => "⠈", // script "I" => "⠸", // italic - "1" => "⠀", // Grade 1 symbol (used for number followed by a letter) + "1" => "", // Grade 1 symbol (used for number followed by a letter, but irrelevant for French, but generated by UEB cleanup) "L" => "", // Letter left in to assist in locating letters "D" => "XXX", // German (Deutsche) -- from prefs "G" => "⠘", // Greek @@ -2407,6 +2407,7 @@ static FRENCH_INDICATOR_REPLACEMENTS: phf::Map<&str, &str> = phf_map! { "c" => "⠆", // Closing group indicator "b" => "⠰", // Optional opening group indicator "e" => "⠆", // Optional closing group indicator + ";" => "⠆", // Need to be able to detect ';' and potentially add dot-6 (see 7° Ponctuations) "P" => "⠠⠄", // Math modifier and code change indicator }; @@ -2414,6 +2415,7 @@ static FRENCH_INDICATOR_REPLACEMENTS: phf::Map<&str, &str> = phf_map! { /// Optional pairs nest like parentheses. Resolve outer pairs before inner ones. /// A pair is kept when its content ends with a letter/number (`L`/`N` + braille) before `e`, and a /// letter/number follows the next `b` (or directly) after `e`. +/// Because it fits in the algorithm, dealing with ';' (need to add dot-6 if inside of a block) is also handled fn remove_optional_group_indicators(braille: &str) -> String { let chars: Vec = braille.chars().collect(); let mut stack: Vec = Vec::new(); @@ -2444,11 +2446,23 @@ fn remove_optional_group_indicators(braille: &str) -> String { } } + // 7° Ponctuations: when the formula contains any block symbols (start/end of block, dots 5-6 / + // dots 2-3), a ';' is preceded by dot-6 so it isn't confused with the end-of-block indicator + // (which is also dots 2-3). This applies to every ';' in the formula, not just those nested + // inside a block. Blocks in the output are the surviving 'o'/'c' (literal or converted b/e). + let has_block = convert_to_oc.iter().any(|&converted| converted) + || chars.iter().zip(remove.iter()).any(|(&ch, &removed)| !removed && (ch == 'o' || ch == 'c')); + let mut result = String::with_capacity(braille.len()); for (i, &ch) in chars.iter().enumerate() { if remove[i] { continue; } + // A ';' gets a leading dot-6; the dots-23 itself comes from the ';' -> "⠆" mapping in + // FRENCH_INDICATOR_REPLACEMENTS. + if ch == ';' && has_block { + result.push('⠠'); + } if convert_to_oc[i] { result.push(if ch == 'b' { 'o' } else { 'c' }); } else { @@ -2544,7 +2558,7 @@ fn letter_or_number_after_b( fn french_cleanup(_pref_manager: Ref, raw_braille: String) -> String { // FIX: need to implement this -- this is just a copy of the Vietnam code - static REPLACE_INDICATORS: LazyLock = LazyLock::new(|| Regex::new(r"([1SB𝔹TILDGHC𝐶NWscocbe])").unwrap()); + static REPLACE_INDICATORS: LazyLock = LazyLock::new(|| Regex::new(r"([1SB𝔹TILDGHC𝐶NWscocbe;])").unwrap()); debug!("french_cleanup: start={}", raw_braille); // let result = typeface_to_word_mode(&raw_braille); // let result = capitals_to_word_mode(&result); From f481cd5873cc2511538255dd74a05de0bb8e2fcd Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 6 Aug 2026 17:56:49 -0700 Subject: [PATCH 018/157] Lots of fixes and addition of tests. Now at 185 passed; 4 failed --- Rules/Braille/French/French_Rules.yaml | 139 ++- Rules/Braille/French/definitions.yaml | 4 +- Rules/Braille/French/unicode-full.yaml | 1136 ++++-------------------- Rules/Braille/French/unicode.yaml | 40 +- tests/braille.rs | 1 + tests/braille/French/chemistry.rs | 302 ++++++- tests/braille/French/french.rs | 265 +++++- tests/braille/French/other.rs | 367 ++++++++ 8 files changed, 1239 insertions(+), 1015 deletions(-) create mode 100644 tests/braille/French/other.rs diff --git a/Rules/Braille/French/French_Rules.yaml b/Rules/Braille/French/French_Rules.yaml index 5d224216f..66a14b325 100644 --- a/Rules/Braille/French/French_Rules.yaml +++ b/Rules/Braille/French/French_Rules.yaml @@ -244,8 +244,9 @@ # we include invisible times in the match because some AbbreviationsForGrouping are not function names match: "count(*)=3 and *[2][self::m:mo][.='\u2061'or .='\u2062'] and not(*[3][self::m:mrow][IsBracketed(., '(', ')') or IsBracketed(., '[', ']')]) and - BaseNode(*[1])[self::m:mi][not($French_UseShortForm and IsInDefinition(., 'Braille', 'ShortForms')) and - (IsInDefinition(., 'Braille', 'TrigFunctionNames') or IsInDefinition(., 'Braille', 'AbbreviationsForGrouping'))]" + BaseNode(*[1])[self::m:mi] + [not($French_UseShortForm and IsInDefinition(., 'Braille', 'ShortForms')) and + (IsInDefinition(., 'Braille', 'TrigFunctionNames') or IsInDefinition(., 'Braille', 'AbbreviationsForGrouping'))]" replace: - x: "*[1]" - t: "o" @@ -301,15 +302,13 @@ match: "." replace: - test: - if: "$French_UseShortForm and IsInDefinition(., 'Braille', 'ShortForms')" - then: - - with: - variables: [Replacement: "DefinitionValue(., 'Braille', 'ShortForms')"] - replace: - - test: - if: "translate(substring($Replacement, 1, 1), 'abcdefghijklmnopqrstuvwxyz', '')=''" - then: [x: "BrailleChars($Replacement, 'French')"] - else: [x: "$Replacement"] + if: "$French_UseShortForm" + then_test: + - if: "IsInDefinition(., 'Braille', 'ShortForms')" + then: [x: "DEBUG(DefinitionValue(., 'Braille', 'ShortForms'))"] # sin + - else_if: "IsInDefinition(., 'Braille', 'ShortFormAbbreviations')" # cosh -> ch + then: [x: "BrailleChars(DefinitionValue(., 'Braille', 'ShortFormAbbreviations'), 'French')"] + else: [x: "BrailleChars(., 'French')"] else: [x: "BrailleChars(., 'French')"] - @@ -353,24 +352,72 @@ - x: "*[1]" - - # In French braille, we drop the script indicators in both subscripts and superscripts for: - # msub: chemistry (e.g., H20) - # msup: primes - # We combine them here + # Drop subscript indicator for chemistry (e.g., H₂O → ⠨⠓⠣⠨⠕) + name: single-char-exceptions + tag: msub + match: "@data-chem-formula" + replace: + - x: "*[1]" + - x: "*[2]" + +- + # Drop superscript indicator for primes and degree (units: 37° → ⠩⠻⠐⠕, not …⠈⠐⠕) name: single-char-exceptions - tag: [msub, msup] - match: "(@data-chem-formula) or (self::m:msup and *[2][translate(., \"'′″‴\",'')=''])" + tag: msup + match: "*[2][translate(., \"'′″‴°º\",'')='']" replace: - x: "*[1]" + - x: "*[2]" + +- + # Chemistry ion charges keep ⠈; group when followed by the same operator (chem spec p.9) + # or when the charge itself needs grouping (e.g. 2-) + name: chemistry-charge + tag: msup + match: "@data-chem-formula" + replace: + - x: "*[1]" + - t: "⠈" - test: - # we need to group an operator if it is followed by an operator (see p9 of chem spec) -- don't want 2 "+"s in a row - # it is a bit tricky, we used following and preceding because it might be at a different level of the tree - if: "@data-chem-formula and *[2][self::m:mo] and following::*[1][self::m:mo and .=preceding::*[1]]" + if: "*[2][self::m:mo] and following::*[1][self::m:mo and .=preceding::*[1]]" then: - t: "o" - x: "*[2]" - t: "c" - else: [x: "*[2]"] + else: + - test: + if: "NeedsToBeGrouped(*[2], 'French', false())" + then: + - t: "o" + - x: "*[2]" + - t: "c" + else: [x: "*[2]"] + +- + # Chemistry ion with both an atom count (subscript) and a charge (superscript), e.g. SO₄²⁻. + # The subscript drops its indicator like the msub single-char-exceptions rule (@data-chem-formula), + # and the superscript charge is handled exactly like the chemistry-charge msup rule. + name: chemistry-charge + tag: msubsup + match: "@data-chem-formula" + replace: + - x: "*[1]" + - x: "*[2]" # subscript count: single-char-exception -> no ⠢ indicator + - t: "⠈" + - test: + if: "*[3][self::m:mo] and following::*[1][self::m:mo and .=preceding::*[1]]" + then: + - t: "o" + - x: "*[3]" + - t: "c" + else: + - test: + if: "NeedsToBeGrouped(*[3], 'French', false())" + then: + - t: "o" + - x: "*[3]" + - t: "c" + else: [x: "*[3]"] - name: single-char-exceptions @@ -412,6 +459,56 @@ +- + # Lewis doublets: bars above or below an atom → output "1d" + name: lewis-doublets + tag: [munder, mover] + match: "*[2][.='¯'] and (*[1][@data-chem-element] or ancestor-or-self::*[contains(@intent, ':chemical-formula')] or ancestor-or-self::*[@data-chem-formula])" + replace: + - x: "*[1]" + - t: "⠰⠡⠙⠆" + +- + # Lewis doublets: bars above and below an atom → output "2d" (chem spec §I.5) + name: lewis-doublets + tag: munderover + match: "*[2][.='¯'] and *[3][.='¯'] and (*[1][@data-chem-element] or ancestor-or-self::*[contains(@intent, ':chemical-formula')] or ancestor-or-self::*[@data-chem-formula])" + replace: + - x: "*[1]" + - t: "⠰⠣⠙⠆" + +- + # Chemical equilibrium annotations: ⠸⠻(LTR;RTL) with empty zone = ⠐⠂ (chem spec §III.5) + # Note: the "over" comes first + name: chemical-equilibrium-zones + tag: [munderover, munder, mover] + match: "*[1][.='⇌' or .='⇄']" + replace: + - x: "*[1]" + - t: "⠦" + - test: + - if: "self::m:munder" + then: + - t: "⠐⠂⠆" + - x: "*[2]" + - else_if: "self::m:mover" + then: + - x: "*[2]" + - t: "⠆⠐⠂" + - else_if: "*[2][self::m:mtext and .=' ']" + then: + - x: "*[3]" + - t: "⠆⠐⠂" + - else_if: "*[3][self::m:mtext and .=' ']" + then: + - t: "⠐⠂⠆" + - x: "*[2]" + else: + - x: "*[3]" + - t: "⠆" + - x: "*[2]" + - t: "⠴" + - name: msubsup_default_mmultiscripts_equiv tag: [msubsup, munderover, mmultiscripts] # mmultiscripts with only sub/sup postscript diff --git a/Rules/Braille/French/definitions.yaml b/Rules/Braille/French/definitions.yaml index 8a611c06a..8376ab0d7 100644 --- a/Rules/Braille/French/definitions.yaml +++ b/Rules/Braille/French/definitions.yaml @@ -21,7 +21,9 @@ # ⠘ -> \ue003 "sin": "\ue000", "cos": "\ue001\ue000", "tan": "\ue002", "cotan": "\ue001\ue002", "arcsin": "\ue003\ue000", "arccos": "\ue003\ue001\ue002", "arctan": "\ue003\ue002", "arccotan": "\ue003\ue001\ue002", - + } + +- ShortFormAbbreviations: { "cosh": "ch", "sinh": "sh", "tanh": "th", "coth": "coth", "arsinh": "argsh", "arcosh": "argch", "artanh": "argth", "arcoth": "argcoth", } \ No newline at end of file diff --git a/Rules/Braille/French/unicode-full.yaml b/Rules/Braille/French/unicode-full.yaml index 2f6ecc9b0..e27f214a6 100644 --- a/Rules/Braille/French/unicode-full.yaml +++ b/Rules/Braille/French/unicode-full.yaml @@ -1,4 +1,23 @@ --- + + - " ": [t: "W"] # 0x2000 (en quad, 1/2 em) + - " ": [t: "W"] # 0x2001 (em quad, 1 em) + - " ": [t: "W"] # 0x2002 (en space, 1/2 em) + - " ": [t: "W"] # 0x2003 (em space, 1 em) + - " ": [t: "W"] # 0x2004 (three-per-em, 1/3 em) + - " ": [t: "W"] # 0x2005 (four-per-em, 1/4 em) + - " ": [t: ""] # 0x2006 (six-per-em, 1/6 em) + - " ": [t: "W"] # 0x2007 (figure space) + - " ": [t: "W"] # 0x2008 (punctuation space) + - " ": [t: ""] # 0x2009 (thin space, ~1/5 em) + - " ": [t: ""] # 0x200a (hair space) + - "​": [t: ""] # 0x200b (zero-width space) + - "
": [t: "W"] # 0x2028 (line separator) + - "
": [t: "W"] # 0x2029 (paragraph separator) + - " ": [t: ""] # 0x202f (narrow no-break space, ~thin) + - " ": [t: "W"] # 0x205f (medium math space, 4/18 em) + - "": [t: ""] # 0xfeff (BOM / zero-width no-break space) + - "⇌": [t: "⠸⠻"] # 0x21CC (Rightwards harpoon over leftwards harpoon (equilibrium)) # - "⥂": [t: ""] # 0x2942 (Rightwards arrow above short leftwards arrow (equilibrium, trend to the right)) @@ -33,224 +52,38 @@ - "↉": [t: "⠼⠌⠩"] # 0x2189 (vulgar fraction zero thirds) - - - "𝐚": [t: "BL⠁"] # 0x1d41a - - "𝐛": [t: "BL⠃"] # 0x1d41b - - "𝐜": [t: "BL⠉"] # 0x1d41c - - "𝐝": [t: "BL⠙"] # 0x1d41d - - "𝐞": [t: "BL⠑"] # 0x1d41e - - "𝐟": [t: "BL⠋"] # 0x1d41f - - "𝐠": [t: "BL⠛"] # 0x1d420 - - "𝐡": [t: "BL⠓"] # 0x1d421 - - "𝐢": [t: "BL⠊"] # 0x1d422 - - "𝐣": [t: "BL⠚"] # 0x1d423 - - "𝐤": [t: "BL⠅"] # 0x1d424 - - "𝐥": [t: "BL⠇"] # 0x1d425 - - "𝐦": [t: "BL⠍"] # 0x1d426 - - "𝐧": [t: "BL⠝"] # 0x1d427 - - "𝐨": [t: "BL⠕"] # 0x1d428 - - "𝐩": [t: "BL⠏"] # 0x1d429 - - "𝐪": [t: "BL⠟"] # 0x1d42a - - "𝐫": [t: "BL⠗"] # 0x1d42b - - "𝐬": [t: "BL⠎"] # 0x1d42c - - "𝐭": [t: "BL⠞"] # 0x1d42d - - "𝐮": [t: "BL⠥"] # 0x1d42e - - "𝐯": [t: "BL⠧"] # 0x1d42f - - "𝐰": [t: "BL⠺"] # 0x1d430 - - "𝐱": [t: "BL⠭"] # 0x1d431 - - "𝐲": [t: "BL⠽"] # 0x1d432 - - "𝐳": [t: "BL⠵"] # 0x1d433 - - - "𝐀": [t: "BCL⠁"] # 0x1d400 - - "𝐁": [t: "BCL⠃"] # 0x1d401 - - "𝐂": [t: "BCL⠉"] # 0x1d402 - - "𝐃": [t: "BCL⠙"] # 0x1d403 - - "𝐄": [t: "BCL⠑"] # 0x1d404 - - "𝐅": [t: "BCL⠋"] # 0x1d405 - - "𝐆": [t: "BCL⠛"] # 0x1d406 - - "𝐇": [t: "BCL⠓"] # 0x1d407 - - "𝐈": [t: "BCL⠊"] # 0x1d408 - - "𝐉": [t: "BCL⠚"] # 0x1d409 - - "𝐊": [t: "BCL⠅"] # 0x1d40a - - "𝐋": [t: "BCL⠇"] # 0x1d40b - - "𝐌": [t: "BCL⠍"] # 0x1d40c - - "𝐍": [t: "BCL⠝"] # 0x1d40d - - "𝐎": [t: "BCL⠕"] # 0x1d40e - - "𝐏": [t: "BCL⠏"] # 0x1d40f - - "𝐐": [t: "BCL⠟"] # 0x1d410 - - "𝐑": [t: "BCL⠗"] # 0x1d411 - - "𝐒": [t: "BCL⠎"] # 0x1d412 - - "𝐓": [t: "BCL⠞"] # 0x1d413 - - "𝐔": [t: "BCL⠥"] # 0x1d414 - - "𝐕": [t: "BCL⠧"] # 0x1d415 - - "𝐖": [t: "BCL⠺"] # 0x1d416 - - "𝐗": [t: "BCL⠭"] # 0x1d417 - - "𝐘": [t: "BCL⠽"] # 0x1d418 - - "𝐙": [t: "BCL⠵"] # 0x1d419 - -# don't mark these as italic - - "𝑎": [t: "L⠁"] # 0x1d44e - - "𝑏": [t: "L⠃"] # 0x1d44f - - "𝑐": [t: "L⠉"] # 0x1d450 - - "𝑑": [t: "L⠙"] # 0x1d451 - - "𝑒": [t: "L⠑"] # 0x1d452 - - "𝑓": [t: "L⠋"] # 0x1d453 - - "𝑔": [t: "L⠛"] # 0x1d454 - - "𝑕": [t: "L⠓"] # 0x1d455 - - "𝑖": [t: "L⠊"] # 0x1d456 - - "𝑗": [t: "L⠚"] # 0x1d457 - - "𝑘": [t: "L⠅"] # 0x1d458 - - "𝑙": [t: "L⠇"] # 0x1d459 - - "𝑚": [t: "L⠍"] # 0x1d45a - - "𝑛": [t: "L⠝"] # 0x1d45b - - "𝑜": [t: "L⠕"] # 0x1d45c - - "𝑝": [t: "L⠏"] # 0x1d45d - - "𝑞": [t: "L⠟"] # 0x1d45e - - "𝑟": [t: "L⠗"] # 0x1d45f - - "𝑠": [t: "L⠎"] # 0x1d460 - - "𝑡": [t: "L⠞"] # 0x1d461 - - "𝑢": [t: "L⠥"] # 0x1d462 - - "𝑣": [t: "L⠧"] # 0x1d463 - - "𝑤": [t: "L⠺"] # 0x1d464 - - "𝑥": [t: "L⠭"] # 0x1d465 - - "𝑦": [t: "L⠽"] # 0x1d466 - - "𝑧": [t: "L⠵"] # 0x1d467 - - - "𝐴": [t: "CL⠁"] # 0x1d434 - - "𝐵": [t: "CL⠃"] # 0x1d435 - - "𝐶": [t: "CL⠉"] # 0x1d436 - - "𝐷": [t: "CL⠙"] # 0x1d437 - - "𝐸": [t: "CL⠑"] # 0x1d438 - - "𝐹": [t: "CL⠋"] # 0x1d439 - - "𝐺": [t: "CL⠛"] # 0x1d43a - - "𝐻": [t: "CL⠓"] # 0x1d43b - - "𝐼": [t: "CL⠊"] # 0x1d43c - - "𝐽": [t: "CL⠚"] # 0x1d43d - - "𝐾": [t: "CL⠅"] # 0x1d43e - - "𝐿": [t: "CL⠇"] # 0x1d43f - - "𝑀": [t: "CL⠍"] # 0x1d440 - - "𝑁": [t: "CL⠝"] # 0x1d441 - - "𝑂": [t: "CL⠕"] # 0x1d442 - - "𝑃": [t: "CL⠏"] # 0x1d443 - - "𝑄": [t: "CL⠟"] # 0x1d444 - - "𝑅": [t: "CL⠗"] # 0x1d445 - - "𝑆": [t: "CL⠎"] # 0x1d446 - - "𝑇": [t: "CL⠞"] # 0x1d447 - - "𝑈": [t: "CL⠥"] # 0x1d448 - - "𝑉": [t: "CL⠧"] # 0x1d449 - - "𝑊": [t: "CL⠺"] # 0x1d44a - - "𝑋": [t: "CL⠭"] # 0x1d44b - - "𝑌": [t: "CL⠽"] # 0x1d44c - - "𝑍": [t: "CL⠵"] # 0x1d44d - - - "𝒂": [t: "BIL⠁"] # 0x1d482 - - "𝒃": [t: "BIL⠃"] # 0x1d483 - - "𝒄": [t: "BIL⠉"] # 0x1d484 - - "𝒅": [t: "BIL⠙"] # 0x1d485 - - "𝒆": [t: "BIL⠑"] # 0x1d486 - - "𝒇": [t: "BIL⠋"] # 0x1d487 - - "𝒈": [t: "BIL⠛"] # 0x1d488 - - "𝒉": [t: "BIL⠓"] # 0x1d489 - - "𝒊": [t: "BIL⠊"] # 0x1d48a - - "𝒋": [t: "BIL⠚"] # 0x1d48b - - "𝒌": [t: "BIL⠅"] # 0x1d48c - - "𝒍": [t: "BIL⠇"] # 0x1d48d - - "𝒎": [t: "BIL⠍"] # 0x1d48e - - "𝒏": [t: "BIL⠝"] # 0x1d48f - - "𝒐": [t: "BIL⠕"] # 0x1d490 - - "𝒑": [t: "BIL⠏"] # 0x1d491 - - "𝒒": [t: "BIL⠟"] # 0x1d492 - - "𝒓": [t: "BIL⠗"] # 0x1d493 - - "𝒔": [t: "BIL⠎"] # 0x1d494 - - "𝒕": [t: "BIL⠞"] # 0x1d495 - - "𝒖": [t: "BIL⠥"] # 0x1d496 - - "𝒗": [t: "BIL⠧"] # 0x1d497 - - "𝒘": [t: "BIL⠺"] # 0x1d498 - - "𝒙": [t: "BIL⠭"] # 0x1d499 - - "𝒚": [t: "BIL⠽"] # 0x1d49a - - "𝒛": [t: "BIL⠵"] # 0x1d49b - - - "𝑨": [t: "BICL⠁"] # 0x1d468 - - "𝑩": [t: "BICL⠃"] # 0x1d469 - - "𝑪": [t: "BICL⠉"] # 0x1d46a - - "𝑫": [t: "BICL⠙"] # 0x1d46b - - "𝑬": [t: "BICL⠑"] # 0x1d46c - - "𝑭": [t: "BICL⠋"] # 0x1d46d - - "𝑮": [t: "BICL⠛"] # 0x1d46e - - "𝑯": [t: "BICL⠓"] # 0x1d46f - - "𝑰": [t: "BICL⠊"] # 0x1d470 - - "𝑱": [t: "BICL⠚"] # 0x1d471 - - "𝑲": [t: "BICL⠅"] # 0x1d472 - - "𝑳": [t: "BICL⠇"] # 0x1d473 - - "𝑴": [t: "BICL⠍"] # 0x1d474 - - "𝑵": [t: "BICL⠝"] # 0x1d475 - - "𝑶": [t: "BICL⠕"] # 0x1d476 - - "𝑷": [t: "BICL⠏"] # 0x1d477 - - "𝑸": [t: "BICL⠟"] # 0x1d478 - - "𝑹": [t: "BICL⠗"] # 0x1d479 - - "𝑺": [t: "BICL⠎"] # 0x1d47a - - "𝑻": [t: "BICL⠞"] # 0x1d47b - - "𝑼": [t: "BICL⠥"] # 0x1d47c - - "𝑽": [t: "BICL⠧"] # 0x1d47d - - "𝑾": [t: "BICL⠺"] # 0x1d47e - - "𝑿": [t: "BICL⠭"] # 0x1d47f - - "𝒀": [t: "BICL⠽"] # 0x1d480 - - "𝒁": [t: "BICL⠵"] # 0x1d481 - - - "𝒶": [t: "TsL⠁"] # 0x1d4b6 - - "𝒷": [t: "TsL⠃"] # 0x1d4b7 - - "𝒸": [t: "TsL⠉"] # 0x1d4b8 - - "𝒹": [t: "TsL⠙"] # 0x1d4b9 - - "𝒺": [t: "TsL⠑"] # 0x1d4ba - - "𝒻": [t: "TsL⠋"] # 0x1d4bb - - "𝒼": [t: "TsL⠛"] # 0x1d4bc - - "𝒽": [t: "TsL⠓"] # 0x1d4bd - - "𝒾": [t: "TsL⠊"] # 0x1d4be - - "𝒿": [t: "TsL⠚"] # 0x1d4bf - - "𝓀": [t: "TsL⠅"] # 0x1d4c0 - - "𝓁": [t: "TsL⠇"] # 0x1d4c1 - - "𝓂": [t: "TsL⠍"] # 0x1d4c2 - - "𝓃": [t: "TsL⠝"] # 0x1d4c3 - - "𝓄": [t: "TsL⠕"] # 0x1d4c4 - - "𝓅": [t: "TsL⠏"] # 0x1d4c5 - - "𝓆": [t: "TsL⠟"] # 0x1d4c6 - - "𝓇": [t: "TsL⠗"] # 0x1d4c7 - - "𝓈": [t: "TsL⠎"] # 0x1d4c8 - - "𝓉": [t: "TsL⠞"] # 0x1d4c9 - - "𝓊": [t: "TsL⠥"] # 0x1d4ca - - "𝓋": [t: "TsL⠧"] # 0x1d4cb - - "𝓌": [t: "TsL⠺"] # 0x1d4cc - - "𝓍": [t: "TsL⠭"] # 0x1d4cd - - "𝓎": [t: "TsL⠽"] # 0x1d4ce - - "𝓏": [t: "TsL⠵"] # 0x1d4cf - - - "𝒜": [t: "TsCL⠁"] # 0x1d49c - - "𝒝": [t: "TsCL⠃"] # 0x1d49d - - "𝒞": [t: "TsCL⠉"] # 0x1d49e - - "𝒟": [t: "TsCL⠙"] # 0x1d49f - - "𝒠": [t: "TsCL⠑"] # 0x1d4a0 - - "𝒡": [t: "TsCL⠋"] # 0x1d4a1 - - "𝒢": [t: "TsCL⠛"] # 0x1d4a2 - - "𝒣": [t: "TsCL⠓"] # 0x1d4a3 - - "𝒤": [t: "TsCL⠊"] # 0x1d4a4 - - "𝒥": [t: "TsCL⠚"] # 0x1d4a5 - - "𝒦": [t: "TsCL⠅"] # 0x1d4a6 - - "𝒧": [t: "TsCL⠇"] # 0x1d4a7 - - "𝒨": [t: "TsCL⠍"] # 0x1d4a8 - - "𝒩": [t: "TsCL⠝"] # 0x1d4a9 - - "𝒪": [t: "TsCL⠕"] # 0x1d4aa - - "𝒫": [t: "TsCL⠏"] # 0x1d4ab - - "𝒬": [t: "TsCL⠟"] # 0x1d4ac - - "𝒭": [t: "TsCL⠗"] # 0x1d4ad - - "𝒮": [t: "TsCL⠎"] # 0x1d4ae - - "𝒯": [t: "TsCL⠞"] # 0x1d4af - - "𝒰": [t: "TsCL⠥"] # 0x1d4b0 - - "𝒱": [t: "TsCL⠧"] # 0x1d4b1 - - "𝒲": [t: "TsCL⠺"] # 0x1d4b2 - - "𝒳": [t: "TsCL⠭"] # 0x1d4b3 - - "𝒴": [t: "TsCL⠽"] # 0x1d4b4 - - "𝒵": [t: "TsCL⠵"] # 0x1d4b5 - + # Hebrew letters (H → ⠘⠘); spell via Latin/assoc letters in unicode.yaml + - "אבגדהוזחטיכלמנסעפצקרשת": # 0x05D0–0x05EA (excl. final forms) + - tc: "H" + - spell: "translate('.', 'אבגדהוזחטיכלמנסעפצקרשת', 'abgdhwzxtjklmnsëpèqrît')" + + + + # Mathematical alphanumeric symbols (Latin) — typeface via tc:; C/L from unicode.yaml + - "𝐀-𝐙": # 0x1d400 - 0x1d419 + - tc: "B" + - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝐚-𝐳": # 0x1d41a - 0x1d433 + - tc: "B" + - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" + - "𝐴-𝑍": # 0x1d434 - 0x1d44d + - tc: "" + - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝑎-𝑧": # 0x1d44e - 0x1d467 + - tc: "" + - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" + - "𝑨-𝒁": # 0x1d468 - 0x1d481 + - tc: "BI" + - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝒂-𝒛": # 0x1d482 - 0x1d49b + - tc: "BI" + - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" + - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 + - tc: "Ts" + - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf + - tc: "Ts" + - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" - "ℊ": [t: "TL⠛⠁"] # 0x210a (Script Small G) - "ℋ": [t: "TCL⠓⠁"] # 0x210b (Script Capital H) - "ℒ": [t: "TCL⠇"] # 0x2113 (Script Capital L) @@ -262,766 +95,137 @@ - "ℱ": [t: "TCL⠋"] # 0x2131 (Script Capital F) - "ℳ": [t: "TCL⠍"] # 0x2133 (Script Capital M) - "ℴ": [t: "TL⠕"] # 0x21334 (Script Small O) - - "𝓪": [t: "BTsL⠁"] # 0x1d4ea - - "𝓫": [t: "BTsL⠃"] # 0x1d4eb - - "𝓬": [t: "BTsL⠉"] # 0x1d4ec - - "𝓭": [t: "BTsL⠙"] # 0x1d4ed - - "𝓮": [t: "BTsL⠑"] # 0x1d4ee - - "𝓯": [t: "BTsL⠋"] # 0x1d4ef - - "𝓰": [t: "BTsL⠛"] # 0x1d4f0 - - "𝓱": [t: "BTsL⠓"] # 0x1d4f1 - - "𝓲": [t: "BTsL⠊"] # 0x1d4f2 - - "𝓳": [t: "BTsL⠚"] # 0x1d4f3 - - "𝓴": [t: "BTsL⠅"] # 0x1d4f4 - - "𝓵": [t: "BTsL⠇"] # 0x1d4f5 - - "𝓶": [t: "BTsL⠍"] # 0x1d4f6 - - "𝓷": [t: "BTsL⠝"] # 0x1d4f7 - - "𝓸": [t: "BTsL⠕"] # 0x1d4f8 - - "𝓹": [t: "BTsL⠏"] # 0x1d4f9 - - "𝓺": [t: "BTsL⠟"] # 0x1d4fa - - "𝓻": [t: "BTsL⠗"] # 0x1d4fb - - "𝓼": [t: "BTsL⠎"] # 0x1d4fc - - "𝓽": [t: "BTsL⠞"] # 0x1d4fd - - "𝓾": [t: "BTsL⠥"] # 0x1d4fe - - "𝓿": [t: "BTsL⠧"] # 0x1d4ff - - "𝔀": [t: "BTsL⠺"] # 0x1d500 - - "𝔁": [t: "BTsL⠭"] # 0x1d501 - - "𝔂": [t: "BTsL⠽"] # 0x1d502 - - "𝔃": [t: "BTsL⠵"] # 0x1d503 - - - "𝓐": [t: "BTsCL⠁"] # 0x1d4d0 - - "𝓑": [t: "BTsCL⠃"] # 0x1d4d1 - - "𝓒": [t: "BTsCL⠉"] # 0x1d4d2 - - "𝓓": [t: "BTsCL⠙"] # 0x1d4d3 - - "𝓔": [t: "BTsCL⠑"] # 0x1d4d4 - - "𝓕": [t: "BTsCL⠋"] # 0x1d4d5 - - "𝓖": [t: "BTsCL⠛"] # 0x1d4d6 - - "𝓗": [t: "BTsCL⠓"] # 0x1d4d7 - - "𝓘": [t: "BTsCL⠊"] # 0x1d4d8 - - "𝓙": [t: "BTsCL⠚"] # 0x1d4d9 - - "𝓚": [t: "BTsCL⠅"] # 0x1d4da - - "𝓛": [t: "BTsCL⠇"] # 0x1d4db - - "𝓜": [t: "BTsCL⠍"] # 0x1d4dc - - "𝓝": [t: "BTsCL⠝"] # 0x1d4dd - - "𝓞": [t: "BTsCL⠕"] # 0x1d4de - - "𝓟": [t: "BTsCL⠏"] # 0x1d4df - - "𝓠": [t: "BTsCL⠟"] # 0x1d4e0 - - "𝓡": [t: "BTsCL⠗"] # 0x1d4e1 - - "𝓢": [t: "BTsCL⠎"] # 0x1d4e2 - - "𝓣": [t: "BTsCL⠞"] # 0x1d4e3 - - "𝓤": [t: "BTsCL⠥"] # 0x1d4e4 - - "𝓥": [t: "BTsCL⠧"] # 0x1d4e5 - - "𝓦": [t: "BTsCL⠺"] # 0x1d4e6 - - "𝓧": [t: "BTsCL⠭"] # 0x1d4e7 - - "𝓨": [t: "BTsCL⠽"] # 0x1d4e8 - - "𝓩": [t: "BTsCL⠵"] # 0x1d4e9 - - - "𝔞": [t: "DL⠁"] # 0x1d51e - - "𝔟": [t: "DL⠃"] # 0x1d51f - - "𝔠": [t: "DL⠉"] # 0x1d520 - - "𝔡": [t: "DL⠙"] # 0x1d521 - - "𝔢": [t: "DL⠑"] # 0x1d522 - - "𝔣": [t: "DL⠋"] # 0x1d523 - - "𝔤": [t: "DL⠛"] # 0x1d524 - - "𝔥": [t: "DL⠓"] # 0x1d525 - - "𝔦": [t: "DL⠊"] # 0x1d526 - - "𝔧": [t: "DL⠚"] # 0x1d527 - - "𝔨": [t: "DL⠅"] # 0x1d528 - - "𝔩": [t: "DL⠇"] # 0x1d529 - - "𝔪": [t: "DL⠍"] # 0x1d52a - - "𝔫": [t: "DL⠝"] # 0x1d52b - - "𝔬": [t: "DL⠕"] # 0x1d52c - - "𝔭": [t: "DL⠏"] # 0x1d52d - - "𝔮": [t: "DL⠟"] # 0x1d52e - - "𝔯": [t: "DL⠗"] # 0x1d52f - - "𝔰": [t: "DL⠎"] # 0x1d530 - - "𝔱": [t: "DL⠞"] # 0x1d531 - - "𝔲": [t: "DL⠥"] # 0x1d532 - - "𝔳": [t: "DL⠧"] # 0x1d533 - - "𝔴": [t: "DL⠺"] # 0x1d534 - - "𝔵": [t: "DL⠭"] # 0x1d535 - - "𝔶": [t: "DL⠽"] # 0x1d536 - - "𝔷": [t: "DL⠵"] # 0x1d537 - - - "𝔄": [t: "DCL⠁"] # 0x1d504 - - "𝔅": [t: "DCL⠃"] # 0x1d505 - - "𝔆": [t: "DCL⠉"] # 0x1d506 - - "𝔇": [t: "DCL⠙"] # 0x1d507 - - "𝔈": [t: "DCL⠑"] # 0x1d508 - - "𝔉": [t: "DCL⠋"] # 0x1d509 - - "𝔊": [t: "DCL⠛"] # 0x1d50a - - "𝔋": [t: "DCL⠓"] # 0x1d50b - - "𝔌": [t: "DCL⠊"] # 0x1d50c - - "𝔍": [t: "DCL⠚"] # 0x1d50d - - "𝔎": [t: "DCL⠅"] # 0x1d50e - - "𝔏": [t: "DCL⠇"] # 0x1d50f - - "𝔐": [t: "DCL⠍"] # 0x1d510 - - "𝔑": [t: "DCL⠝"] # 0x1d511 - - "𝔒": [t: "DCL⠕"] # 0x1d512 - - "𝔓": [t: "DCL⠏"] # 0x1d513 - - "𝔔": [t: "DCL⠟"] # 0x1d514 - - "𝔕": [t: "DCL⠗"] # 0x1d515 - - "𝔖": [t: "DCL⠎"] # 0x1d516 - - "𝔗": [t: "DCL⠞"] # 0x1d517 - - "𝔘": [t: "DCL⠥"] # 0x1d518 - - "𝔙": [t: "DCL⠧"] # 0x1d519 - - "𝔚": [t: "DCL⠺"] # 0x1d51a - - "𝔛": [t: "DCL⠭"] # 0x1d51b - - "𝔜": [t: "DCL⠽"] # 0x1d51c - - "𝔝": [t: "DCL⠵"] # 0x1d51d + - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 + - tc: "BTs" + - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝓪-𝔃": # 0x1d4ea - 0x1d503 + - tc: "BTs" + - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" + - "𝔄-𝔝": # 0x1d504 - 0x1d51d + - tc: "D" + - spell: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜𝔝', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝔞-𝔷": # 0x1d51e - 0x1d537 + - tc: "D" + - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" - "ℌ": [t: "DCL⠓"] # 0x210C (Fraktur Capital H) - "ℑ": [t: "DCL⠊"] # 0x2111 (Fraktur Capital I) - "ℜ": [t: "DCL⠗"] # 0x211C (Fraktur Capital R) - "ℨ": [t: "DCL⠵"] # 0x2128 (Fraktur Capital Z) - "ℭ": [t: "DCL⠉"] # 0x22DC (Fraktur Capital C) - - "𝕒": [t: "𝔹L⠁"] # 0x1d552 - - "𝕓": [t: "𝔹L⠃"] # 0x1d553 - - "𝕔": [t: "𝔹L⠉"] # 0x1d554 - - "𝕕": [t: "𝔹L⠙"] # 0x1d555 - - "𝕖": [t: "𝔹L⠑"] # 0x1d556 - - "𝕗": [t: "𝔹L⠋"] # 0x1d557 - - "𝕘": [t: "𝔹L⠛"] # 0x1d558 - - "𝕙": [t: "𝔹L⠓"] # 0x1d559 - - "𝕚": [t: "𝔹L⠊"] # 0x1d55a - - "𝕛": [t: "𝔹L⠚"] # 0x1d55b - - "𝕜": [t: "𝔹L⠅"] # 0x1d55c - - "𝕝": [t: "𝔹L⠇"] # 0x1d55d - - "𝕞": [t: "𝔹L⠍"] # 0x1d55e - - "𝕟": [t: "𝔹L⠝"] # 0x1d55f - - "𝕠": [t: "𝔹L⠕"] # 0x1d560 - - "𝕡": [t: "𝔹L⠏"] # 0x1d561 - - "𝕢": [t: "𝔹L⠟"] # 0x1d562 - - "𝕣": [t: "𝔹L⠗"] # 0x1d563 - - "𝕤": [t: "𝔹L⠎"] # 0x1d564 - - "𝕥": [t: "𝔹L⠞"] # 0x1d565 - - "𝕦": [t: "𝔹L⠥"] # 0x1d566 - - "𝕧": [t: "𝔹L⠧"] # 0x1d567 - - "𝕨": [t: "𝔹L⠺"] # 0x1d568 - - "𝕩": [t: "𝔹L⠭"] # 0x1d569 - - "𝕪": [t: "𝔹L⠽"] # 0x1d56a - - "𝕫": [t: "𝔹L⠵"] # 0x1d56b - - "𝔸": [t: "𝔹CL⠁"] # 0x1d538 - - "𝔹": [t: "𝔹CL⠃"] # 0x1d539 + - "𝔸-𝔹": # 0x1d538 - 0x1d539 + - tc: "𝔹" + - spell: "translate('.', '𝔸𝔹', 'AB')" + - "𝔻-𝔾": # 0x1d53b - 0x1d53e + - tc: "𝔹" + - spell: "translate('.', '𝔻𝔼𝔽𝔾', 'DEFG')" + - "𝕀-𝕄": # 0x1d540 - 0x1d544 + - tc: "𝔹" + - spell: "translate('.', '𝕀𝕁𝕂𝕃𝕄', 'IJKLM')" + - "𝕆": [t: "𝔹CL⠕"] # 0x1d546 - "ℂ": [t: "𝔹CL⠉"] # 0x2102 - - "𝔻": [t: "𝔹CL⠙"] # 0x1d53b - - "𝔼": [t: "𝔹CL⠑"] # 0x1d53c - - "𝔽": [t: "𝔹CL⠋"] # 0x1d53d - - "𝔾": [t: "𝔹CL⠛"] # 0x1d53e - "ℍ": [t: "𝔹CL⠓"] # 0x210d - - "𝕀": [t: "𝔹CL⠊"] # 0x1d540 - - "𝕁": [t: "𝔹CL⠚"] # 0x1d541 - - "𝕂": [t: "𝔹CL⠅"] # 0x1d542 - - "𝕃": [t: "𝔹CL⠇"] # 0x1d543 - - "𝕄": [t: "𝔹CL⠍"] # 0x1d544 - "ℕ": [t: "𝔹CL⠝"] # 0x2115 - - "𝕆": [t: "𝔹CL⠕"] # 0x1d546 - "ℙ": [t: "𝔹CL⠏"] # 0x2119 - "ℚ": [t: "𝔹CL⠟"] # 0x211a - "ℝ": [t: "𝔹CL⠗"] # 0x211d - - "𝕊": [t: "𝔹CL⠎"] # 0x1d54a - - "𝕋": [t: "𝔹CL⠞"] # 0x1d54b - - "𝕌": [t: "𝔹CL⠥"] # 0x1d54c - - "𝕍": [t: "𝔹CL⠧"] # 0x1d54d - - "𝕎": [t: "𝔹CL⠺"] # 0x1d54e - - "𝕏": [t: "𝔹CL⠭"] # 0x1d54f - - "𝕐": [t: "𝔹CL⠽"] # 0x1d550 - "ℤ": [t: "𝔹CL⠵"] # 0x2124 - - "𝖆": [t: "BDL⠁"] # 0x1d586 - - "𝖇": [t: "BDL⠃"] # 0x1d587 - - "𝖈": [t: "BDL⠉"] # 0x1d588 - - "𝖉": [t: "BDL⠙"] # 0x1d589 - - "𝖊": [t: "BDL⠑"] # 0x1d58a - - "𝖋": [t: "BDL⠋"] # 0x1d58b - - "𝖌": [t: "BDL⠛"] # 0x1d58c - - "𝖍": [t: "BDL⠓"] # 0x1d58d - - "𝖎": [t: "BDL⠊"] # 0x1d58e - - "𝖏": [t: "BDL⠚"] # 0x1d58f - - "𝖐": [t: "BDL⠅"] # 0x1d590 - - "𝖑": [t: "BDL⠇"] # 0x1d591 - - "𝖒": [t: "BDL⠍"] # 0x1d592 - - "𝖓": [t: "BDL⠝"] # 0x1d593 - - "𝖔": [t: "BDL⠕"] # 0x1d594 - - "𝖕": [t: "BDL⠏"] # 0x1d595 - - "𝖖": [t: "BDL⠟"] # 0x1d596 - - "𝖗": [t: "BDL⠗"] # 0x1d597 - - "𝖘": [t: "BDL⠎"] # 0x1d598 - - "𝖙": [t: "BDL⠞"] # 0x1d599 - - "𝖚": [t: "BDL⠥"] # 0x1d59a - - "𝖛": [t: "BDL⠧"] # 0x1d59b - - "𝖜": [t: "BDL⠺"] # 0x1d59c - - "𝖝": [t: "BDL⠭"] # 0x1d59d - - "𝖞": [t: "BDL⠽"] # 0x1d59e - - "𝖟": [t: "BDL⠵"] # 0x1d59f - - - "𝕬": [t: "BDCL⠁"] # 0x1d56c - - "𝕭": [t: "BDCL⠃"] # 0x1d56d - - "𝕮": [t: "BDCL⠉"] # 0x1d56e - - "𝕯": [t: "BDCL⠙"] # 0x1d56f - - "𝕰": [t: "BDCL⠑"] # 0x1d570 - - "𝕱": [t: "BDCL⠋"] # 0x1d571 - - "𝕲": [t: "BDCL⠛"] # 0x1d572 - - "𝕳": [t: "BDCL⠓"] # 0x1d573 - - "𝕴": [t: "BDCL⠊"] # 0x1d574 - - "𝕵": [t: "BDCL⠚"] # 0x1d575 - - "𝕶": [t: "BDCL⠅"] # 0x1d576 - - "𝕷": [t: "BDCL⠇"] # 0x1d577 - - "𝕸": [t: "BDCL⠍"] # 0x1d578 - - "𝕹": [t: "BDCL⠝"] # 0x1d579 - - "𝕺": [t: "BDCL⠕"] # 0x1d57a - - "𝕻": [t: "BDCL⠏"] # 0x1d57b - - "𝕼": [t: "BDCL⠟"] # 0x1d57c - - "𝕽": [t: "BDCL⠗"] # 0x1d57d - - "𝕾": [t: "BDCL⠎"] # 0x1d57e - - "𝕿": [t: "BDCL⠞"] # 0x1d57f - - "𝖀": [t: "BDCL⠥"] # 0x1d580 - - "𝖁": [t: "BDCL⠧"] # 0x1d581 - - "𝖂": [t: "BDCL⠺"] # 0x1d582 - - "𝖃": [t: "BDCL⠭"] # 0x1d583 - - "𝖄": [t: "BDCL⠽"] # 0x1d584 - - "𝖅": [t: "BDCL⠵"] # 0x1d585 - - - "𝖺": [t: "SL⠁"] # 0x1d5ba - - "𝖻": [t: "SL⠃"] # 0x1d5bb - - "𝖼": [t: "SL⠉"] # 0x1d5bc - - "𝖽": [t: "SL⠙"] # 0x1d5bd - - "𝖾": [t: "SL⠑"] # 0x1d5be - - "𝖿": [t: "SL⠋"] # 0x1d5bf - - "𝗀": [t: "SL⠛"] # 0x1d5c0 - - "𝗁": [t: "SL⠓"] # 0x1d5c1 - - "𝗂": [t: "SL⠊"] # 0x1d5c2 - - "𝗃": [t: "SL⠚"] # 0x1d5c3 - - "𝗄": [t: "SL⠅"] # 0x1d5c4 - - "𝗅": [t: "SL⠇"] # 0x1d5c5 - - "𝗆": [t: "SL⠍"] # 0x1d5c6 - - "𝗇": [t: "SL⠝"] # 0x1d5c7 - - "𝗈": [t: "SL⠕"] # 0x1d5c8 - - "𝗉": [t: "SL⠏"] # 0x1d5c9 - - "𝗊": [t: "SL⠟"] # 0x1d5ca - - "𝗋": [t: "SL⠗"] # 0x1d5cb - - "𝗌": [t: "SL⠎"] # 0x1d5cc - - "𝗍": [t: "SL⠞"] # 0x1d5cd - - "𝗎": [t: "SL⠥"] # 0x1d5ce - - "𝗏": [t: "SL⠧"] # 0x1d5cf - - "𝗐": [t: "SL⠺"] # 0x1d5d0 - - "𝗑": [t: "SL⠭"] # 0x1d5d1 - - "𝗒": [t: "SL⠽"] # 0x1d5d2 - - "𝗓": [t: "SL⠵"] # 0x1d5d3 - - - "𝖠": [t: "SCL⠁"] # 0x1d5a0 - - "𝖡": [t: "SCL⠃"] # 0x1d5a1 - - "𝖢": [t: "SCL⠉"] # 0x1d5a2 - - "𝖣": [t: "SCL⠙"] # 0x1d5a3 - - "𝖤": [t: "SCL⠑"] # 0x1d5a4 - - "𝖥": [t: "SCL⠋"] # 0x1d5a5 - - "𝖦": [t: "SCL⠛"] # 0x1d5a6 - - "𝖧": [t: "SCL⠓"] # 0x1d5a7 - - "𝖨": [t: "SCL⠊"] # 0x1d5a8 - - "𝖩": [t: "SCL⠚"] # 0x1d5a9 - - "𝖪": [t: "SCL⠅"] # 0x1d5aa - - "𝖫": [t: "SCL⠇"] # 0x1d5ab - - "𝖬": [t: "SCL⠍"] # 0x1d5ac - - "𝖭": [t: "SCL⠝"] # 0x1d5ad - - "𝖮": [t: "SCL⠕"] # 0x1d5ae - - "𝖯": [t: "SCL⠏"] # 0x1d5af - - "𝖰": [t: "SCL⠟"] # 0x1d5b0 - - "𝖱": [t: "SCL⠗"] # 0x1d5b1 - - "𝖲": [t: "SCL⠎"] # 0x1d5b2 - - "𝖳": [t: "SCL⠞"] # 0x1d5b3 - - "𝖴": [t: "SCL⠥"] # 0x1d5b4 - - "𝖵": [t: "SCL⠧"] # 0x1d5b5 - - "𝖶": [t: "SCL⠺"] # 0x1d5b6 - - "𝖷": [t: "SCL⠭"] # 0x1d5b7 - - "𝖸": [t: "SCL⠽"] # 0x1d5b8 - - "𝖹": [t: "SCL⠵"] # 0x1d5b9 - - - "𝗮": [t: "BSL⠁"] # 0x1d5ee - - "𝗯": [t: "BSL⠃"] # 0x1d5ef - - "𝗰": [t: "BSL⠉"] # 0x1d5f0 - - "𝗱": [t: "BSL⠙"] # 0x1d5f1 - - "𝗲": [t: "BSL⠑"] # 0x1d5f2 - - "𝗳": [t: "BSL⠋"] # 0x1d5f3 - - "𝗴": [t: "BSL⠛"] # 0x1d5f4 - - "𝗵": [t: "BSL⠓"] # 0x1d5f5 - - "𝗶": [t: "BSL⠊"] # 0x1d5f6 - - "𝗷": [t: "BSL⠚"] # 0x1d5f7 - - "𝗸": [t: "BSL⠅"] # 0x1d5f8 - - "𝗹": [t: "BSL⠇"] # 0x1d5f9 - - "𝗺": [t: "BSL⠍"] # 0x1d5fa - - "𝗻": [t: "BSL⠝"] # 0x1d5fb - - "𝗼": [t: "BSL⠕"] # 0x1d5fc - - "𝗽": [t: "BSL⠏"] # 0x1d5fd - - "𝗾": [t: "BSL⠟"] # 0x1d5fe - - "𝗿": [t: "BSL⠗"] # 0x1d5ff - - "𝘀": [t: "BSL⠎"] # 0x1d600 - - "𝘁": [t: "BSL⠞"] # 0x1d601 - - "𝘂": [t: "BSL⠥"] # 0x1d602 - - "𝘃": [t: "BSL⠧"] # 0x1d603 - - "𝘄": [t: "BSL⠺"] # 0x1d604 - - "𝘅": [t: "BSL⠭"] # 0x1d605 - - "𝘆": [t: "BSL⠽"] # 0x1d606 - - "𝘇": [t: "BSL⠵"] # 0x1d607 - - - "𝗔": [t: "BSCL⠁"] # 0x1d5d4 - - "𝗕": [t: "BSCL⠃"] # 0x1d5d5 - - "𝗖": [t: "BSCL⠉"] # 0x1d5d6 - - "𝗗": [t: "BSCL⠙"] # 0x1d5d7 - - "𝗘": [t: "BSCL⠑"] # 0x1d5d8 - - "𝗙": [t: "BSCL⠋"] # 0x1d5d9 - - "𝗚": [t: "BSCL⠛"] # 0x1d5da - - "𝗛": [t: "BSCL⠓"] # 0x1d5db - - "𝗜": [t: "BSCL⠊"] # 0x1d5dc - - "𝗝": [t: "BSCL⠚"] # 0x1d5dd - - "𝗞": [t: "BSCL⠅"] # 0x1d5de - - "𝗟": [t: "BSCL⠇"] # 0x1d5df - - "𝗠": [t: "BSCL⠍"] # 0x1d5e0 - - "𝗡": [t: "BSCL⠝"] # 0x1d5e1 - - "𝗢": [t: "BSCL⠕"] # 0x1d5e2 - - "𝗣": [t: "BSCL⠏"] # 0x1d5e3 - - "𝗤": [t: "BSCL⠟"] # 0x1d5e4 - - "𝗥": [t: "BSCL⠗"] # 0x1d5e5 - - "𝗦": [t: "BSCL⠎"] # 0x1d5e6 - - "𝗧": [t: "BSCL⠞"] # 0x1d5e7 - - "𝗨": [t: "BSCL⠥"] # 0x1d5e8 - - "𝗩": [t: "BSCL⠧"] # 0x1d5e9 - - "𝗪": [t: "BSCL⠺"] # 0x1d5ea - - "𝗫": [t: "BSCL⠭"] # 0x1d5eb - - "𝗬": [t: "BSCL⠽"] # 0x1d5ec - - "𝗭": [t: "BSCL⠵"] # 0x1d5ed - - - "𝘢": [t: "ISL⠁"] # 0x1d622 - - "𝘣": [t: "ISL⠃"] # 0x1d623 - - "𝘤": [t: "ISL⠉"] # 0x1d624 - - "𝘥": [t: "ISL⠙"] # 0x1d625 - - "𝘦": [t: "ISL⠑"] # 0x1d626 - - "𝘧": [t: "ISL⠋"] # 0x1d627 - - "𝘨": [t: "ISL⠛"] # 0x1d628 - - "𝘩": [t: "ISL⠓"] # 0x1d629 - - "𝘪": [t: "ISL⠊"] # 0x1d62a - - "𝘫": [t: "ISL⠚"] # 0x1d62b - - "𝘬": [t: "ISL⠅"] # 0x1d62c - - "𝘭": [t: "ISL⠇"] # 0x1d62d - - "𝘮": [t: "ISL⠍"] # 0x1d62e - - "𝘯": [t: "ISL⠝"] # 0x1d62f - - "𝘰": [t: "ISL⠕"] # 0x1d630 - - "𝘱": [t: "ISL⠏"] # 0x1d631 - - "𝘲": [t: "ISL⠟"] # 0x1d632 - - "𝘳": [t: "ISL⠗"] # 0x1d633 - - "𝘴": [t: "ISL⠎"] # 0x1d634 - - "𝘵": [t: "ISL⠞"] # 0x1d635 - - "𝘶": [t: "ISL⠥"] # 0x1d636 - - "𝘷": [t: "ISL⠧"] # 0x1d637 - - "𝘸": [t: "ISL⠺"] # 0x1d638 - - "𝘹": [t: "ISL⠭"] # 0x1d639 - - "𝘺": [t: "ISL⠽"] # 0x1d63a - - "𝘻": [t: "ISL⠵"] # 0x1d63b - - - "𝘈": [t: "ISCL⠁"] # 0x1d608 - - "𝘉": [t: "ISCL⠃"] # 0x1d609 - - "𝘊": [t: "ISCL⠉"] # 0x1d60a - - "𝘋": [t: "ISCL⠙"] # 0x1d60b - - "𝘌": [t: "ISCL⠑"] # 0x1d60c - - "𝘍": [t: "ISCL⠋"] # 0x1d60d - - "𝘎": [t: "ISCL⠛"] # 0x1d60e - - "𝘏": [t: "ISCL⠓"] # 0x1d60f - - "𝘐": [t: "ISCL⠊"] # 0x1d610 - - "𝘑": [t: "ISCL⠚"] # 0x1d611 - - "𝘒": [t: "ISCL⠅"] # 0x1d612 - - "𝘓": [t: "ISCL⠇"] # 0x1d613 - - "𝘔": [t: "ISCL⠍"] # 0x1d614 - - "𝘕": [t: "ISCL⠝"] # 0x1d615 - - "𝘖": [t: "ISCL⠕"] # 0x1d616 - - "𝘗": [t: "ISCL⠏"] # 0x1d617 - - "𝘘": [t: "ISCL⠟"] # 0x1d618 - - "𝘙": [t: "ISCL⠗"] # 0x1d619 - - "𝘚": [t: "ISCL⠎"] # 0x1d61a - - "𝘛": [t: "ISCL⠞"] # 0x1d61b - - "𝘜": [t: "ISCL⠥"] # 0x1d61c - - "𝘝": [t: "ISCL⠧"] # 0x1d61d - - "𝘞": [t: "ISCL⠺"] # 0x1d61e - - "𝘟": [t: "ISCL⠭"] # 0x1d61f - - "𝘠": [t: "ISCL⠽"] # 0x1d620 - - "𝘡": [t: "ISCL⠵"] # 0x1d621 - - - "𝙖": [t: "BILS⠁"] # 0x1d656 - - "𝙗": [t: "BILS⠃"] # 0x1d657 - - "𝙘": [t: "BILS⠉"] # 0x1d658 - - "𝙙": [t: "BILS⠙"] # 0x1d659 - - "𝙚": [t: "BILS⠑"] # 0x1d65a - - "𝙛": [t: "BILS⠋"] # 0x1d65b - - "𝙜": [t: "BILS⠛"] # 0x1d65c - - "𝙝": [t: "BILS⠓"] # 0x1d65d - - "𝙞": [t: "BILS⠊"] # 0x1d65e - - "𝙟": [t: "BILS⠚"] # 0x1d65f - - "𝙠": [t: "BILS⠅"] # 0x1d660 - - "𝙡": [t: "BILS⠇"] # 0x1d661 - - "𝙢": [t: "BILS⠍"] # 0x1d662 - - "𝙣": [t: "BILS⠝"] # 0x1d663 - - "𝙤": [t: "BILS⠕"] # 0x1d664 - - "𝙥": [t: "BILS⠏"] # 0x1d665 - - "𝙦": [t: "BILS⠟"] # 0x1d666 - - "𝙧": [t: "BILS⠗"] # 0x1d667 - - "𝙨": [t: "BILS⠎"] # 0x1d668 - - "𝙩": [t: "BILS⠞"] # 0x1d669 - - "𝙪": [t: "BILS⠥"] # 0x1d66a - - "𝙫": [t: "BILS⠧"] # 0x1d66b - - "𝙬": [t: "BILS⠺"] # 0x1d66c - - "𝙭": [t: "BILS⠭"] # 0x1d66d - - "𝙮": [t: "BILS⠽"] # 0x1d66e - - "𝙯": [t: "BILS⠵"] # 0x1d66f - - - "𝘼": [t: "BILSC⠁"] # 0x1d63c - - "𝘽": [t: "BILSC⠃"] # 0x1d63d - - "𝘾": [t: "BILSC⠉"] # 0x1d63e - - "𝘿": [t: "BILSC⠙"] # 0x1d63f - - "𝙀": [t: "BILSC⠑"] # 0x1d640 - - "𝙁": [t: "BILSC⠋"] # 0x1d641 - - "𝙂": [t: "BILSC⠛"] # 0x1d642 - - "𝙃": [t: "BILSC⠓"] # 0x1d643 - - "𝙄": [t: "BILSC⠊"] # 0x1d644 - - "𝙅": [t: "BILSC⠚"] # 0x1d645 - - "𝙆": [t: "BILSC⠅"] # 0x1d646 - - "𝙇": [t: "BILSC⠇"] # 0x1d647 - - "𝙈": [t: "BILSC⠍"] # 0x1d648 - - "𝙉": [t: "BILSC⠝"] # 0x1d649 - - "𝙊": [t: "BILSC⠕"] # 0x1d64a - - "𝙋": [t: "BILSC⠏"] # 0x1d64b - - "𝙌": [t: "BILSC⠟"] # 0x1d64c - - "𝙍": [t: "BILSC⠗"] # 0x1d64d - - "𝙎": [t: "BILSC⠎"] # 0x1d64e - - "𝙏": [t: "BILSC⠞"] # 0x1d64f - - "𝙐": [t: "BILSC⠥"] # 0x1d650 - - "𝙑": [t: "BILSC⠧"] # 0x1d651 - - "𝙒": [t: "BILSC⠺"] # 0x1d652 - - "𝙓": [t: "BILSC⠭"] # 0x1d653 - - "𝙔": [t: "BILSC⠽"] # 0x1d654 - - "𝙕": [t: "BILSC⠵"] # 0x1d655 - - - "𝚊": [t: "L⠁"] # 0x1d68a - - "𝚋": [t: "L⠃"] # 0x1d68b - - "𝚌": [t: "L⠉"] # 0x1d68c - - "𝚍": [t: "L⠙"] # 0x1d68d - - "𝚎": [t: "L⠑"] # 0x1d68e - - "𝚏": [t: "L⠋"] # 0x1d68f - - "𝚐": [t: "L⠛"] # 0x1d690 - - "𝚑": [t: "L⠓"] # 0x1d691 - - "𝚒": [t: "L⠊"] # 0x1d692 - - "𝚓": [t: "L⠚"] # 0x1d693 - - "𝚔": [t: "L⠅"] # 0x1d694 - - "𝚕": [t: "L⠇"] # 0x1d695 - - "𝚖": [t: "L⠍"] # 0x1d696 - - "𝚗": [t: "L⠝"] # 0x1d697 - - "𝚘": [t: "L⠕"] # 0x1d698 - - "𝚙": [t: "L⠏"] # 0x1d699 - - "𝚚": [t: "L⠟"] # 0x1d69a - - "𝚛": [t: "L⠗"] # 0x1d69b - - "𝚜": [t: "L⠎"] # 0x1d69c - - "𝚝": [t: "L⠞"] # 0x1d69d - - "𝚞": [t: "L⠥"] # 0x1d69e - - "𝚟": [t: "L⠧"] # 0x1d69f - - "𝚠": [t: "L⠺"] # 0x1d6a0 - - "𝚡": [t: "L⠭"] # 0x1d6a1 - - "𝚢": [t: "L⠽"] # 0x1d6a2 - - "𝚣": [t: "L⠵"] # 0x1d6a3 - - - "𝙰": [t: "CL⠁"] # 0x1d670 - - "𝙱": [t: "CL⠃"] # 0x1d671 - - "𝙲": [t: "CL⠉"] # 0x1d672 - - "𝙳": [t: "CL⠙"] # 0x1d673 - - "𝙴": [t: "CL⠑"] # 0x1d674 - - "𝙵": [t: "CL⠋"] # 0x1d675 - - "𝙶": [t: "CL⠛"] # 0x1d676 - - "𝙷": [t: "CL⠓"] # 0x1d677 - - "𝙸": [t: "CL⠊"] # 0x1d678 - - "𝙹": [t: "CL⠚"] # 0x1d679 - - "𝙺": [t: "CL⠅"] # 0x1d67a - - "𝙻": [t: "CL⠇"] # 0x1d67b - - "𝙼": [t: "CL⠍"] # 0x1d67c - - "𝙽": [t: "CL⠝"] # 0x1d67d - - "𝙾": [t: "CL⠕"] # 0x1d67e - - "𝙿": [t: "CL⠏"] # 0x1d67f - - "𝚀": [t: "CL⠟"] # 0x1d680 - - "𝚁": [t: "CL⠗"] # 0x1d681 - - "𝚂": [t: "CL⠎"] # 0x1d682 - - "𝚃": [t: "CL⠞"] # 0x1d683 - - "𝚄": [t: "CL⠥"] # 0x1d684 - - "𝚅": [t: "CL⠧"] # 0x1d685 - - "𝚆": [t: "CL⠺"] # 0x1d686 - - "𝚇": [t: "CL⠭"] # 0x1d687 - - "𝚈": [t: "CL⠽"] # 0x1d688 - - "𝚉": [t: "CL⠵"] # 0x1d689 - - - "𝚤": [t: "L⠊"] # 0x1d6a4 (dotless i) - - "𝚥": [t: "L⠚"] # 0x1d6a5 (dotless j) - - "𝛂": [t: "BGL⠁"] # 0x1d6c2 - - "𝛃": [t: "BGL⠃"] # 0x1d6c3 - - "𝛄": [t: "BGL⠛"] # 0x1d6c4 - - "𝛅": [t: "BGL⠙"] # 0x1d6c5 - - "𝛆": [t: "BGL⠑"] # 0x1d6c6 - - "𝛇": [t: "BGL⠵"] # 0x1d6c7 - - "𝛈": [t: "BGL⠱ "] # 0x1d6c8 - - "𝛉": [t: "BGL⠹"] # 0x1d6c9 - - "𝛊": [t: "BGL⠊"] # 0x1d6ca - - "𝛋": [t: "BGL⠅"] # 0x1d6cb - - "𝛌": [t: "BGL⠇"] # 0x1d6cc - - "𝛍": [t: "BGL⠍"] # 0x1d6cd - - "𝛎": [t: "BGL⠝"] # 0x1d6ce - - "𝛏": [t: "BGL⠭"] # 0x1d6cf - - "𝛐": [t: "BGL⠕"] # 0x1d6d0 - - "𝛑": [t: "BGL⠏"] # 0x1d6d1 - - "𝛒": [t: "BGL⠗"] # 0x1d6d2 - - "𝛓": [t: "BGL⠎"] # 0x1d6d3 - - "𝛔": [t: "BGL⠞"] # 0x1d6d4 - - "𝛕": [t: "BGL⠥"] # 0x1d6d5 - - "𝛖": [t: "BGL⠋"] # 0x1d6d6 - - "𝛗": [t: "BGL⠯"] # 0x1d6d7 - - "𝛘": [t: "BGL⠽"] # 0x1d6d8 - - "𝛙": [t: "BGL⠺"] # 0x1d6d9 - - - "𝚨": [t: "BCGL⠁"] # 0x1d6a8 - - "𝚩": [t: "BCGL⠃"] # 0x1d6a9 - - "𝚪": [t: "BCGL⠛"] # 0x1d6aa - - "𝚫": [t: "BCGL⠙"] # 0x1d6ab - - "𝚬": [t: "BCGL⠑"] # 0x1d6ac - - "𝚭": [t: "BCGL⠵"] # 0x1d6ad - - "𝚮": [t: "BCGL⠱ "] # 0x1d6ae - - "𝚯": [t: "BCGL⠹"] # 0x1d6af - - "𝚰": [t: "BCGL⠊"] # 0x1d6b0 - - "𝚱": [t: "BCGL⠅"] # 0x1d6b1 - - "𝚲": [t: "BCGL⠇"] # 0x1d6b2 - - "𝚳": [t: "BCGL⠍"] # 0x1d6b3 - - "𝚴": [t: "BCGL⠝"] # 0x1d6b4 - - "𝚵": [t: "BCGL⠭"] # 0x1d6b5 - - "𝚶": [t: "BCGL⠕"] # 0x1d6b6 - - "𝚷": [t: "BCGL⠏"] # 0x1d6b7 - - "𝚸": [t: "BCGL⠗"] # 0x1d6b8 - - "𝚹": [t: "BCGL⠎"] # 0x1d6b9 - - "𝚺": [t: "BCGL⠞"] # 0x1d6ba - - "𝚻": [t: "BCGL⠥"] # 0x1d6bb - - "𝚼": [t: "BCGL⠋"] # 0x1d6bc - - "𝚽": [t: "BCGL⠯"] # 0x1d6bd - - "𝚾": [t: "BCGL⠽"] # 0x1d6be - - "𝚿": [t: "BCGL⠺"] # 0x1d6bf - - - "𝛼": [t: "IGL⠁"] # 0x1d6fc - - "𝛽": [t: "IGL⠃"] # 0x1d6fd - - "𝛾": [t: "IGL⠛"] # 0x1d6fe - - "𝛿": [t: "IGL⠙"] # 0x1d6ff - - "𝜀": [t: "IGL⠑"] # 0x1d700 - - "𝜁": [t: "IGL⠵"] # 0x1d701 - - "𝜂": [t: "IGL⠱ "] # 0x1d702 - - "𝜃": [t: "IGL⠹"] # 0x1d703 - - "𝜄": [t: "IGL⠊"] # 0x1d704 - - "𝜅": [t: "IGL⠅"] # 0x1d705 - - "𝜆": [t: "IGL⠇"] # 0x1d706 - - "𝜇": [t: "IGL⠍"] # 0x1d707 - - "𝜈": [t: "IGL⠝"] # 0x1d708 - - "𝜉": [t: "IGL⠭"] # 0x1d709 - - "𝜊": [t: "IGL⠕"] # 0x1d70a - - "𝜋": [t: "IGL⠏"] # 0x1d70b - - "𝜌": [t: "IGL⠗"] # 0x1d70c - - "𝜍": [t: "IGL⠎"] # 0x1d70d - - "𝜎": [t: "IGL⠞"] # 0x1d70e - - "𝜏": [t: "IGL⠥"] # 0x1d70f - - "𝜐": [t: "IGL⠋"] # 0x1d710 - - "𝜑": [t: "IGL⠯"] # 0x1d711 - - "𝜒": [t: "IGL⠽"] # 0x1d712 - - "𝜓": [t: "IGL⠺"] # 0x1d713 - - - "𝛢": [t: "ICGL⠁"] # 0x1d6e2 - - "𝛣": [t: "ICGL⠃"] # 0x1d6e3 - - "𝛤": [t: "ICGL⠛"] # 0x1d6e4 - - "𝛥": [t: "ICGL⠙"] # 0x1d6e5 - - "𝛦": [t: "ICGL⠑"] # 0x1d6e6 - - "𝛧": [t: "ICGL⠵"] # 0x1d6e7 - - "𝛨": [t: "ICGL⠱ "] # 0x1d6e8 - - "𝛩": [t: "ICGL⠹"] # 0x1d6e9 - - "𝛪": [t: "ICGL⠊"] # 0x1d6ea - - "𝛫": [t: "ICGL⠅"] # 0x1d6eb - - "𝛬": [t: "ICGL⠇"] # 0x1d6ec - - "𝛭": [t: "ICGL⠍"] # 0x1d6ed - - "𝛮": [t: "ICGL⠝"] # 0x1d6ee - - "𝛯": [t: "ICGL⠭"] # 0x1d6ef - - "𝛰": [t: "ICGL⠕"] # 0x1d6f0 - - "𝛱": [t: "ICGL⠏"] # 0x1d6f1 - - "𝛲": [t: "ICGL⠗"] # 0x1d6f2 - - "𝛳": [t: "ICGL⠎"] # 0x1d6f3 - - "𝛴": [t: "ICGL⠞"] # 0x1d6f4 - - "𝛵": [t: "ICGL⠥"] # 0x1d6f5 - - "𝛶": [t: "ICGL⠋"] # 0x1d6f6 - - "𝛷": [t: "ICGL⠯"] # 0x1d6f7 - - "𝛸": [t: "ICGL⠽"] # 0x1d6f8 - - "𝛹": [t: "ICGL⠺"] # 0x1d6f9 - - - "𝜶": [t: "BIGL⠁"] # 0x1d736 - - "𝜷": [t: "BIGL⠃"] # 0x1d737 - - "𝜸": [t: "BIGL⠛"] # 0x1d738 - - "𝜹": [t: "BIGL⠙"] # 0x1d739 - - "𝜺": [t: "BIGL⠑"] # 0x1d73a - - "𝜻": [t: "BIGL⠵"] # 0x1d73b - - "𝜼": [t: "BIGL⠱ "] # 0x1d73c - - "𝜽": [t: "BIGL⠹"] # 0x1d73d - - "𝜾": [t: "BIGL⠊"] # 0x1d73e - - "𝜿": [t: "BIGL⠅"] # 0x1d73f - - "𝝀": [t: "BIGL⠇"] # 0x1d740 - - "𝝁": [t: "BIGL⠍"] # 0x1d741 - - "𝝂": [t: "BIGL⠝"] # 0x1d742 - - "𝝃": [t: "BIGL⠭"] # 0x1d743 - - "𝝄": [t: "BIGL⠕"] # 0x1d744 - - "𝝅": [t: "BIGL⠏"] # 0x1d745 - - "𝝆": [t: "BIGL⠗"] # 0x1d746 - - "𝝇": [t: "BIGL⠎"] # 0x1d747 - - "𝝈": [t: "BIGL⠞"] # 0x1d748 - - "𝝉": [t: "BIGL⠥"] # 0x1d749 - - "𝝊": [t: "BIGL⠋"] # 0x1d74a - - "𝝋": [t: "BIGL⠯"] # 0x1d74b - - "𝝌": [t: "BIGL⠽"] # 0x1d74c - - "𝝍": [t: "BIGL⠺"] # 0x1d74d - - - "𝜜": [t: "BICGL⠁"] # 0x1d71c - - "𝜝": [t: "BICGL⠃"] # 0x1d71d - - "𝜞": [t: "BICGL⠛"] # 0x1d71e - - "𝜟": [t: "BICGL⠙"] # 0x1d71f - - "𝜠": [t: "BICGL⠑"] # 0x1d720 - - "𝜡": [t: "BICGL⠵"] # 0x1d721 - - "𝜢": [t: "BICGL⠱ "] # 0x1d722 - - "𝜣": [t: "BICGL⠹"] # 0x1d723 - - "𝜤": [t: "BICGL⠊"] # 0x1d724 - - "𝜥": [t: "BICGL⠅"] # 0x1d725 - - "𝜦": [t: "BICGL⠇"] # 0x1d726 - - "𝜧": [t: "BICGL⠍"] # 0x1d727 - - "𝜨": [t: "BICGL⠝"] # 0x1d728 - - "𝜩": [t: "BICGL⠭"] # 0x1d729 - - "𝜪": [t: "BICGL⠕"] # 0x1d72a - - "𝜫": [t: "BICGL⠏"] # 0x1d72b - - "𝜬": [t: "BICGL⠗"] # 0x1d72c - - "𝜭": [t: "BICGL⠎"] # 0x1d72d - - "𝜮": [t: "BICGL⠞"] # 0x1d72e - - "𝜯": [t: "BICGL⠥"] # 0x1d72f - - "𝜰": [t: "BICGL⠋"] # 0x1d730 - - "𝜱": [t: "BICGL⠯"] # 0x1d731 - - "𝜲": [t: "BICGL⠽"] # 0x1d732 - - "𝜳": [t: "BICGL⠺"] # 0x1d733 - - - "𝝰": [t: "BSGL⠁"] # 0x1d770 - - "𝝱": [t: "BSGL⠃"] # 0x1d771 - - "𝝲": [t: "BSGL⠛"] # 0x1d772 - - "𝝳": [t: "BSGL⠙"] # 0x1d773 - - "𝝴": [t: "BSGL⠑"] # 0x1d774 - - "𝝵": [t: "BSGL⠵"] # 0x1d775 - - "𝝶": [t: "BSGL⠱ "] # 0x1d776 - - "𝝷": [t: "BSGL⠹"] # 0x1d777 - - "𝝸": [t: "BSGL⠊"] # 0x1d778 - - "𝝹": [t: "BSGL⠅"] # 0x1d779 - - "𝝺": [t: "BSGL⠇"] # 0x1d77a - - "𝝻": [t: "BSGL⠍"] # 0x1d77b - - "𝝼": [t: "BSGL⠝"] # 0x1d77c - - "𝝽": [t: "BSGL⠭"] # 0x1d77d - - "𝝾": [t: "BSGL⠕"] # 0x1d77e - - "𝝿": [t: "BSGL⠏"] # 0x1d77f - - "𝞀": [t: "BSGL⠗"] # 0x1d780 - - "𝞁": [t: "BSGL⠎"] # 0x1d781 - - "𝞂": [t: "BSGL⠞"] # 0x1d782 - - "𝞃": [t: "BSGL⠥"] # 0x1d783 - - "𝞄": [t: "BSGL⠋"] # 0x1d784 - - "𝞅": [t: "BSGL⠯"] # 0x1d785 - - "𝞆": [t: "BSGL⠽"] # 0x1d786 - - "𝞇": [t: "BSGL⠺"] # 0x1d787 - - - "𝝖": [t: "BSCGL⠁"] # 0x1d756 - - "𝝗": [t: "BSCGL⠃"] # 0x1d757 - - "𝝘": [t: "BSCGL⠛"] # 0x1d758 - - "𝝙": [t: "BSCGL⠙"] # 0x1d759 - - "𝝚": [t: "BSCGL⠑"] # 0x1d75a - - "𝝛": [t: "BSCGL⠵"] # 0x1d75b - - "𝝜": [t: "BSCGL⠱ "] # 0x1d75c - - "𝝝": [t: "BSCGL⠹"] # 0x1d75d - - "𝝞": [t: "BSCGL⠊"] # 0x1d75e - - "𝝟": [t: "BSCGL⠅"] # 0x1d75f - - "𝝠": [t: "BSCGL⠇"] # 0x1d760 - - "𝝡": [t: "BSCGL⠍"] # 0x1d761 - - "𝝢": [t: "BSCGL⠝"] # 0x1d762 - - "𝝣": [t: "BSCGL⠭"] # 0x1d763 - - "𝝤": [t: "BSCGL⠕"] # 0x1d764 - - "𝝥": [t: "BSCGL⠏"] # 0x1d765 - - "𝝦": [t: "BSCGL⠗"] # 0x1d766 - - "𝝧": [t: "BSCGL⠎"] # 0x1d767 - - "𝝨": [t: "BSCGL⠞"] # 0x1d768 - - "𝝩": [t: "BSCGL⠥"] # 0x1d769 - - "𝝪": [t: "BSCGL⠋"] # 0x1d76a - - "𝝫": [t: "BSCGL⠯"] # 0x1d76b - - "𝝬": [t: "BSCGL⠽"] # 0x1d76c - - "𝝭": [t: "BSCGL⠺"] # 0x1d76d - - - "𝞪": [t: "BISGL⠁"] # 0x1d7aa - - "𝞫": [t: "BISGL⠃"] # 0x1d7ab - - "𝞬": [t: "BISGL⠛"] # 0x1d7ac - - "𝞭": [t: "BISGL⠙"] # 0x1d7ad - - "𝞮": [t: "BISGL⠑"] # 0x1d7ae - - "𝞯": [t: "BISGL⠵"] # 0x1d7af - - "𝞰": [t: "BISGL⠱ "] # 0x1d7b0 - - "𝞱": [t: "BISGL⠹"] # 0x1d7b1 - - "𝞲": [t: "BISGL⠊"] # 0x1d7b2 - - "𝞳": [t: "BISGL⠅"] # 0x1d7b3 - - "𝞴": [t: "BISGL⠇"] # 0x1d7b4 - - "𝞵": [t: "BISGL⠍"] # 0x1d7b5 - - "𝞶": [t: "BISGL⠝"] # 0x1d7b6 - - "𝞷": [t: "BISGL⠭"] # 0x1d7b7 - - "𝞸": [t: "BISGL⠕"] # 0x1d7b8 - - "𝞹": [t: "BISGL⠏"] # 0x1d7b9 - - "𝞺": [t: "BISGL⠗"] # 0x1d7ba - - "𝞻": [t: "BISGL⠎"] # 0x1d7bb - - "𝞼": [t: "BISGL⠞"] # 0x1d7bc - - "𝞽": [t: "BISGL⠥"] # 0x1d7bd - - "𝞾": [t: "BISGL⠋"] # 0x1d7be - - "𝞿": [t: "BISGL⠯"] # 0x1d7bf - - "𝟀": [t: "BISGL⠽"] # 0x1d7c0 - - "𝟁": [t: "BISGL⠺"] # 0x1d7c1 - - - "𝞐": [t: "BISCGL⠁"] # 0x1d790 - - "𝞑": [t: "BISCGL⠃"] # 0x1d791 - - "𝞒": [t: "BISCGL⠛"] # 0x1d792 - - "𝞓": [t: "BISCGL⠙"] # 0x1d793 - - "𝞔": [t: "BISCGL⠑"] # 0x1d794 - - "𝞕": [t: "BISCGL⠵"] # 0x1d795 - - "𝞖": [t: "BISCGL⠱ "] # 0x1d796 - - "𝞗": [t: "BISCGL⠹"] # 0x1d797 - - "𝞘": [t: "BISCGL⠊"] # 0x1d798 - - "𝞙": [t: "BISCGL⠅"] # 0x1d799 - - "𝞚": [t: "BISCGL⠇"] # 0x1d79a - - "𝞛": [t: "BISCGL⠍"] # 0x1d79b - - "𝞜": [t: "BISCGL⠝"] # 0x1d79c - - "𝞝": [t: "BISCGL⠭"] # 0x1d79d - - "𝞞": [t: "BISCGL⠕"] # 0x1d79e - - "𝞟": [t: "BISCGL⠏"] # 0x1d79f - - "𝞠": [t: "BISCGL⠗"] # 0x1d7a0 - - "𝞡": [t: "BISCGL⠎"] # 0x1d7a1 - - "𝞢": [t: "BISCGL⠞"] # 0x1d7a2 - - "𝞣": [t: "BISCGL⠥"] # 0x1d7a3 - - "𝞤": [t: "BISCGL⠋"] # 0x1d7a4 - - "𝞥": [t: "BISCGL⠯"] # 0x1d7a5 - - "𝞦": [t: "BISCGL⠽"] # 0x1d7a6 - - "𝞧": [t: "BISCGL⠺"] # 0x1d7a7 - + - "𝕊-𝕐": # 0x1d54a - 0x1d550 + - tc: "𝔹" + - spell: "translate('.', '𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'STUVWXY')" + - "𝕒-𝕫": # 0x1d552 - 0x1d56b + - tc: "𝔹" + - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" + - "𝕬-𝖅": # 0x1d56c - 0x1d585 + - tc: "BD" + - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝖆-𝖟": # 0x1d586 - 0x1d59f + - tc: "BD" + - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" + - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 + - tc: "S" + - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 + - tc: "S" + - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" + - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed + - tc: "BS" + - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝗮-𝘇": # 0x1d5ee - 0x1d607 + - tc: "BS" + - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" + - "𝘈-𝘡": # 0x1d608 - 0x1d621 + - tc: "IS" + - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝘢-𝘻": # 0x1d622 - 0x1d63b + - tc: "IS" + - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" + - "𝘼-𝙕": # 0x1d63c - 0x1d655 + - tc: "BIS" + - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝙖-𝙯": # 0x1d656 - 0x1d66f + - tc: "BIS" + - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" + - "𝙰-𝚉": # 0x1d670 - 0x1d689 + - tc: "" + - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝚊-𝚥": # 0x1d68a - 0x1d6a5 + - tc: "" + - spell: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣𝚤𝚥', 'abcdefghijklmnopqrstuvwxyzij')" + + # Mathematical Greek alphabets (typeface via tc:; G/C from base Greek in unicode.yaml) + - "𝛂-𝛙": # 0x1d6c2 - 0x1d6d9 + - tc: "B" + - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙', 'αβγδεζηθικλμνξοπρςστυφχψ')" + - "𝚨-𝚿": # 0x1d6a8 - 0x1d6bf + - tc: "B" + - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨ')" + - "𝛼-𝜓": # 0x1d6fc - 0x1d713 + - tc: "I" + - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓', 'αβγδεζηθικλμνξοπρςστυφχψ')" + - "𝛢-𝛹": # 0x1d6e2 - 0x1d6f9 + - tc: "I" + - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨ')" + - "𝜶-𝝍": # 0x1d736 - 0x1d74d + - tc: "BI" + - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍', 'αβγδεζηθικλμνξοπρςστυφχψ')" + - "𝜜-𝜳": # 0x1d71c - 0x1d733 + - tc: "BI" + - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨ')" + - "𝝰-𝞇": # 0x1d770 - 0x1d787 + - tc: "BS" + - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇', 'αβγδεζηθικλμνξοπρςστυφχψ')" + - "𝝖-𝝭": # 0x1d756 - 0x1d76d + - tc: "BS" + - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨ')" + - "𝞪-𝟁": # 0x1d7aa - 0x1d7c1 + - tc: "BIS" + - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁', 'αβγδεζηθικλμνξοπρςστυφχψ')" + - "𝞐-𝞧": # 0x1d790 - 0x1d7a7 + - tc: "BIS" + - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨ')" + + + # Mathematical digits - "𝟎-𝟗": # 0x1d7ce - 0x1d7d7 - - t: "B" - - spell: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" - - - "-": # 0xf52e - 0xf537 (old MathType) - - t: "B" - - spell: "translate('.', '', '0123456789')" - - - "𝟬-𝟵": # 0x1D7EC - 0x1D7F5 - - t: "B" - - spell: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" - - - "-": # 0xf556 - 0xf55f (old MathType) - - t: "B" - - spell: "translate('.', '', '0123456789')" - - - "𝟢-𝟫": # 0x1d7e2 - 0x1d7eb - - spell: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" - - - "𝟶-𝟿": # 0x1d7f6 - 0x1d7ff - - spell: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" + - tc: "B" + - spell: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" + - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 + - tc: "𝔹" + - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" + - "𝟢-𝟫": # 0x1d7e2 - 0x1d7eb + - tc: "S" + - spell: "translate('.', '𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫', '0123456789')" + - "𝟬-𝟵": # 0x1d7ec - 0x1d7f5 + - tc: "BS" + - spell: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" + - "𝟶-𝟿": # 0x1d7f6 - 0x1d7ff + - tc: "" + - spell: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" + - "-": # 0xf54c - 0xf555 (old MathType bold) + - tc: "B" + - spell: "translate('.', '', '0123456789')" + - "-": # 0xf556 - 0xf55f (old MathType bold) + - tc: "B" + - spell: "translate('.', '', '0123456789')" diff --git a/Rules/Braille/French/unicode.yaml b/Rules/Braille/French/unicode.yaml index f7e23239b..ce310bb3c 100644 --- a/Rules/Braille/French/unicode.yaml +++ b/Rules/Braille/French/unicode.yaml @@ -231,7 +231,7 @@ - "8": [t: "N⠳"] # 0x0038 (digit eight) - "9": [t: "N⠪"] # 0x0039 (digit nine) - ":": [t: "⠒"] # 0x003A (colon) - - ";": [t: "⠆"] # 0x003B (semicolon) + - ";": [t: ";"] # 0x003B (semicolon) - "<": [t: "⠐⠣"] # 0x003C (less than sign) - "=": [t: "⠶"] # 0x003D (regular equals sign) - ">": [t: "⠐⠜"] # 0x003E (greater than sign ( regular )) @@ -262,15 +262,14 @@ - "¢": [t: "⠉"] # 0x00A2 (cent) - "¯": [t: "⠸⠒"] # 0x00AF (bar) - "°": [t: "⠐⠕"] # 0x00B0 (degree sign) + - "℃": [t: "⠐⠕⠨⠉"] # 0x2103 (degree Celsius) + - "℉": [t: "⠐⠕⠨⠋"] # 0x2109 (degree Fahrenheit) - "±": [t: "⠖⠤"] # 0x00B1 (plus or minus) - "¼": [t: "⠡⠌⠹"] # 0x00BC (vulgar fraction one quarter) - "½": [t: "⠡⠌⠣"] # 0x00BD (vulgar fraction one half) - "¾": [t: "⠩⠌⠹"] # 0x00BE (vulgar fraction three quarters) - "×": [t: "⠔"] # 0x00D7 ( multiplication sign) - "÷": [t: "⠒"] # 0x00F7 (division sign ( divided by )) - - "ב": [t: "⠘⠘⠃"] # 0x05D1 ( beth) - - "ג": [t: "⠘⠘⠛"] # 0x05D2 (gimel) - - "ד": [t: "⠘⠘⠙"] # 0x05D3 (daleth) - "◌̌": [t: "⠸⠘⠒"] # 0x030C (combing caron) - "‖": [t: "⠘⠿"] # 0x2016 (double vertical bar) - "‰": [t: "⠐⠬⠬"] # 0x2030 (per mille sign) @@ -279,9 +278,13 @@ - "‴": [t: "⠄⠄⠄"] # 0x2034 (triple prime) - "€": [t: "⠘⠑"] # 0x20AC (euro) - "Å": [t: "⠨⠁⠈⠕"] # 0x212B (angstrom) - - "ℵ": [t: "⠘⠘⠁"] # 0x2135 (alef) + - "ℵ": [t: "HL⠁"] # 0x2135 (alef) - "←": [t: "⠸⠪"] # 0x2190 (left pointing arrow) - - "↑": [t: "⠘⠻"] # 0x2191 (arrow pointing up) + - "↑": # 0x2191 (arrow pointing up) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠘⠱"] + else: [t: "⠘⠻"] - "→": # 0x2192 (right pointing arrow) - test: if: "parent::m:mover and not(following-sibling::*)" @@ -292,8 +295,11 @@ if: "parent::m:mover and not(following-sibling::*)" then: [t: "⠨⠒"] else: [t: "⠸⠱"] - - - "↓": [t: "⠨⠻"] # 0x2193 (arrow pointing down) + - "↓": # 0x2193 (arrow pointing down) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠨⠱"] + else: [t: "⠨⠻"] - "↔": [t: "⠐⠻"] # 0x2194 (horizontal two-way arrow) - "↖": [t: "⠘⠪"] # 0x2196 (north west arrow) - "↗": [t: "⠘⠱"] # 0x2197 (north east arrow) @@ -340,7 +346,12 @@ - "≈": [t: "⠐⠶"] # 0x2248 (double tilde) - "≙": [t: "⠒⠶"] # 0x2259 (caret over equals sign) - "≠": [t: "⠨⠶"] # 0x2260 (not equal to) - - "≡": [t: "⠶⠶"] # 0x2261 (identify (is congruent to, is identical with)) + - "≡": # 0x2261 (identify (is congruent to, is identical with)) + - test: + if: "@data-chemical-bond" + then: [t: "⠿"] + else: [t: "⠶⠶"] + - "≢": [t: "⠨⠶⠶"] # 0x2262 (is not identical to) - "≤": [t: "⠘⠣"] # 0x2264 (bar under less than sign (is less than or equal to)) - "≥": [t: "⠘⠜"] # 0x2265 (bar under greater than sign (is greater than or equal to)) @@ -360,6 +371,17 @@ - "⊗": [t: "⠨⠔"] # 0x2297 (circle with interior cross (tensor product)) - "⊥": [t: "⠘⠳"] # 0x22A5 (is perpendicular to) - "⋅": [t: "⠔⠔"] # 0x22C5 (dot,and times) + - "⟵": [t: "⠸⠪"] # 0x27F5 (Long leftwards arrow ) + - "⟶": # 0x27F6 (Long rightwards arrow) + - test: + if: "parent::m:mover and not(following-sibling::*)" + then: [t: "⠨⠒"] + else: [t: "⠸⠱"] + - "⟷": [t: "⠸⠻"] # 0x27F7 (Long left right arrow) + - "⟸": [t: "⠐⠒"] # 0x27F8 (Long leftwards arrow ) + - "⟹": [t: "⠒⠂"] # 0x27F9 (Long rightwards arrow) + - "⟺": [t: "⠐⠒⠂"] # 0x27FA (Long left right arrow) + - "⌄": [t: "⠸⠘⠒"] # 0x2304 (inverted caret) - "⌣": [t: "⠈⠈⠈"] # 0x2323 (smile) - "⏜": [t: "⠈⠒"] # 0x23DC (arc concave upward) diff --git a/tests/braille.rs b/tests/braille.rs index 43afe893a..1a0c68b40 100644 --- a/tests/braille.rs +++ b/tests/braille.rs @@ -41,6 +41,7 @@ mod braille { mod French { mod french; mod chemistry; + mod other; } } diff --git a/tests/braille/French/chemistry.rs b/tests/braille/French/chemistry.rs index 4eedcda3a..97528e114 100644 --- a/tests/braille/French/chemistry.rs +++ b/tests/braille/French/chemistry.rs @@ -1,9 +1,69 @@ -// French braille tests for the basic mathml tags -// These tests are from the French braille authority's publication "NOTATION PIATHÉMATIQUE BRAILLE" (Première édition janvier 2007) -// https://www.avh.asso.fr/sites/default/files/notation_mathematique_braille2_0.pdf +// French braille tests for chemistry +// From "Notation braille dans le domaine de la chimie" (Première édition juin 2008) +// BrailleDocs/notation_braille_chimie2008.pdf use crate::common::*; use anyhow::Result; +// --- I. Atomic and molecular writing --- + +#[test] +fn atom_I_1_1() -> Result<()> { + let expr = r#"H"#; + test_braille("French", expr, "⠨⠓")?; + return Ok(()); +} + +#[test] +fn atom_I_1_2() -> Result<()> { + let expr = r#"Al"#; + test_braille("French", expr, "⠨⠁⠇")?; + return Ok(()); +} + +#[test] +fn isotope_I_2_1() -> Result<()> { + // ¹⁶₈O + let expr = r#" + O + + 8 + 16 + "#; + test_braille("French", expr, "⠨⠕⠠⠢⠳⠠⠈⠡⠫")?; + return Ok(()); +} + +#[test] +#[ignore = "average-mass left subscript not handled by French atomic-number rule"] +fn isotope_I_2_2() -> Result<()> { + // ²⁵₂₅⁵⁴.⁹Mn (Z=25, average mass 54.9, A=25) + let expr = r#" + Mn + + 25 + 25 + 54.9 + + "#; + test_braille("French", expr, "⠨⠍⠝⠠⠢⠣⠱⠠⠢⠢⠱⠹⠂⠪⠠⠈⠱⠱")?; + return Ok(()); +} + +#[test] +fn molecule_I_3_1() -> Result<()> { + let expr = r#"H2O"#; + test_braille("French", expr, "⠨⠓⠣⠨⠕")?; + return Ok(()); +} + +#[test] +fn molecule_I_3_2() -> Result<()> { + // Cu(NO₃)₂ + let expr = r#"Cu(NO3)2"#; + test_braille("French", expr, "⠨⠉⠥⠦⠨⠝⠨⠕⠩⠴⠣")?; + return Ok(()); +} + #[test] fn bond_I_4_1() -> Result<()> { let expr= r#"H-H"#; @@ -18,15 +78,177 @@ fn bond_I_4_2() -> Result<()> { return Ok(()); } +#[test] +fn bond_I_4_3() -> Result<()> { + let expr = r#"N≡N"#; + test_braille("French", expr, "⠨⠝⠿⠨⠝")?; + return Ok(()); +} + +#[test] +fn lewis_I_5_1() -> Result<()> { + // O with 2 Lewis doublets (one bar above, one below) → ⠨⠕⠰⠣⠙⠆ + let expr = r#" + O―― + "#; + test_braille("French", expr, "⠨⠕⠰⠣⠙⠆")?; + return Ok(()); +} + +#[test] +fn lewis_I_5_2() -> Result<()> { + // H−O−H with 2 doublets on O + let expr = r#"H- + O―― + - H"#; + test_braille("French", expr, "⠨⠓⠤⠨⠕⠰⠣⠙⠆⠤⠨⠓")?; + return Ok(()); +} + +#[test] +#[ignore = "Lewis notation with bars on left/right of an atom not implemented"] +fn lewis_I_5_3() -> Result<()> { + // H−Cl with 3 doublets on Cl + let expr = r#"H- + Cl―― + |"#; + test_braille("French", expr, "⠨⠓⠤⠨⠉⠇⠰⠩⠙⠆")?; + return Ok(()); +} + +// --- II. Ionic writing --- + +#[test] +fn ion_II_1_1() -> Result<()> { + let expr = r#"H+"#; + test_braille("French", expr, "⠨⠓⠈⠖")?; + return Ok(()); +} + +#[test] +fn ion_II_1_2() -> Result<()> { + let expr = r#"O2-"#; + test_braille("French", expr, "⠨⠕⠈⠰⠣⠤⠆")?; + return Ok(()); +} + #[test] fn ion_II_1_3() -> Result<()> { let expr= r#"SO42-"#; - test_braille("French", expr, "⠨⠎⠨⠕⠢⠹⠈⠰⠣⠤⠆")?; + test_braille("French", expr, "⠨⠎⠨⠕⠹⠈⠰⠣⠤⠆")?; + return Ok(()); +} + +#[test] +fn dissociation_II_2_1() -> Result<()> { + // (Cu²⁺; SO₄²⁻) + let expr = r#"( + Cu2+; + SO42- + )"#; + test_braille("French", expr, "⠦⠨⠉⠥⠈⠰⠣⠖⠆⠠⠆⠨⠎⠨⠕⠹⠈⠰⠣⠤⠆⠴")?; + return Ok(()); +} + +#[test] +fn dipole_II_3_1() -> Result<()> { + // Hᵟ⁺ − Clᵟ⁻ + let expr = r#" + Hδ+ + - + Clδ- + "#; + test_braille("French", expr, "⠨⠓⠈⠰⠘⠙⠈⠖⠆⠤⠨⠉⠇⠈⠰⠘⠙⠈⠤⠆")?; + return Ok(()); +} + +// --- III. Chemical reactions and transformations --- + +#[test] +fn reaction_III_2_1() -> Result<()> { + // C(s)+O₂(g)→CO₂(g) + let expr = r#" + C(s) + + + O2(g) + → + CO2(g) + "#; + test_braille("French", expr, "⠨⠉⠦⠎⠴⠖⠨⠕⠣⠦⠛⠴⠸⠱⠨⠉⠨⠕⠣⠦⠛⠴")?; + return Ok(()); +} + +#[test] +fn reaction_III_2_2() -> Result<()> { + // CO(g)+H₂O(l)→CO₂(g)+H₂(g) — line-continuation ⠐ omitted (single-line MathML) + let expr = r#" + CO(g) + + + H2O(l) + → + CO2(g) + + + H2(g) + "#; + test_braille("French", expr, "⠨⠉⠨⠕⠦⠛⠴⠖⠨⠓⠣⠨⠕⠦⠇⠴⠸⠱⠨⠉⠨⠕⠣⠦⠛⠴⠖⠨⠓⠣⠦⠛⠴")?; + return Ok(()); +} + +#[test] +fn reaction_III_2_3() -> Result<()> { + // HCl(g)+H₂O(l)→(eau) H₃O⁺(aq)+Cl⁻(aq) — line-continuation ⠐ omitted + let expr = r#" + HCl(g) + + + H2O(l) + →(eau) + H3O+ + (aq) + + + Cl- + (aq) + "#; + test_braille("French", expr, "⠨⠓⠨⠉⠇⠦⠛⠴⠖⠨⠓⠣⠨⠕⠦⠇⠴⠸⠱⠦⠑⠁⠥⠴⠨⠓⠩⠨⠕⠈⠖⠦⠁⠟⠴⠖⠨⠉⠇⠈⠤⠦⠁⠟⠴")?; + return Ok(()); +} + +#[test] +fn emerges_III_3_1() -> Result<()> { + // 2H₃O⁺ + FeS → Fe²⁺ + 2H₂O + H₂S↑ + let expr = r#" + 2H3O+ + + + FeS + → + Fe2+ + + + 2H2O + + + H2S↑ + "#; + test_braille("French", expr, "⠣⠨⠓⠩⠨⠕⠈⠰⠖⠆⠖⠨⠋⠑⠨⠎⠸⠱⠨⠋⠑⠈⠰⠣⠖⠆⠖⠣⠨⠓⠣⠨⠕⠖⠨⠓⠣⠨⠎⠘⠱")?; + return Ok(()); +} + +#[test] +fn precipitate_III_4_1() -> Result<()> { + // H₂S(g)+Cl₂(g)→2HCl(g)+S(s)↓ + let expr = r#" + H2S(g) + + + Cl2(g) + → + 2HCl(g) + + + S(s)↓ + "#; + test_braille("French", expr, "⠨⠓⠣⠨⠎⠦⠛⠴⠖⠨⠉⠇⠣⠦⠛⠴⠸⠱⠣⠨⠓⠨⠉⠇⠦⠛⠴⠖⠨⠎⠦⠎⠴⠨⠱")?; return Ok(()); } #[test] fn equilibrium_III_5_1() -> Result<()> { + // N₂(g)+3H₂(g)⇌2NH₃(g) let expr= r#"N2(g)+3H2(g)⇌2NH3(g)"#; test_braille("French", expr, "⠨⠝⠣⠦⠛⠴⠖⠩⠨⠓⠣⠦⠛⠴⠸⠻⠣⠨⠝⠨⠓⠩⠦⠛⠴")?; return Ok(()); @@ -34,10 +256,12 @@ fn equilibrium_III_5_1() -> Result<()> { #[test] fn equilibrium_III_5_2() -> Result<()> { + // 2H₂O ⇌(1;2) H₃O⁺ + OH⁻ (line-continuation ⠐ omitted) + // Note: braille doesn't match the example -- no parens around the '1' and '2' let expr= r#"2H2O - ⇌(2)(1)H3O++OH-"#; - test_braille("French", expr, "⠣⠨⠓⠣⠨⠕⠰⠸⠻⠆⠢⠢⠦⠣⠴⠈⠈⠦⠡⠴⠨⠓⠩⠨⠕⠈⠰⠖⠆⠖⠨⠕⠨⠓⠈⠰⠤⠆")?; + ⇌21 + H3O++OH-"#; + test_braille("French", expr, "⠣⠨⠓⠣⠨⠕⠸⠻⠦⠡⠆⠣⠴⠨⠓⠩⠨⠕⠈⠰⠖⠆⠖⠨⠕⠨⠓⠈⠤")?; return Ok(()); } @@ -49,6 +273,68 @@ fn equilibrium_III_5_3() -> Result<()> { R-CO-O- R'+ H2O"#; - test_braille("French", expr, "⠨⠗⠤⠨⠉⠨⠕⠤⠨⠕⠤⠨⠓⠖⠨⠗⠄⠤⠨⠕⠨⠓ ⠸⠻⠨⠢⠰⠓⠽⠙⠗⠕⠇⠽⠎⠑⠆⠨⠔⠈⠰⠑⠎⠞⠗⠊⠋⠊⠉⠁⠞⠊⠕⠝⠆⠨⠗⠤⠨⠉⠨⠕⠤⠨⠕⠤⠨⠗⠄⠖⠨⠓⠢⠣⠨⠕")?; + test_braille("French", expr, "⠨⠗⠤⠨⠉⠨⠕⠤⠨⠕⠤⠨⠓⠖⠨⠗⠄⠤⠨⠕⠨⠓⠸⠻⠦⠑⠎⠞⠿⠗⠊⠋⠊⠉⠁⠞⠊⠕⠝⠆⠓⠽⠙⠗⠕⠇⠽⠎⠑⠴⠨⠗⠤⠨⠉⠨⠕⠤⠨⠕⠤⠨⠗⠄⠖⠨⠓⠣⠨⠕")?; + return Ok(()); +} + +#[test] +fn equilibrium_III_5_4() -> Result<()> { + // A ⇌ B with hν / empty half-zone ⠐⠂ + let expr = r#" + A + ⇌hν + B + "#; + test_braille("French", expr, "⠨⠁⠸⠻⠦⠓⠘⠝⠆⠐⠂⠴⠨⠃")?; + return Ok(()); +} + +// --- IV. Some notes (redox pairs / mesomerism) --- + +#[test] +fn redox_IV_1_1() -> Result<()> { + let expr = r#" + Cu2+ + / + Cu + "#; + test_braille("French", expr, "⠨⠉⠥⠈⠰⠣⠖⠆⠌⠨⠉⠥")?; + return Ok(()); +} + +#[test] +fn redox_IV_1_2() -> Result<()> { + let expr = r#" + Fe3+ + / + Fe2+ + "#; + test_braille("French", expr, "⠨⠋⠑⠈⠰⠩⠖⠆⠌⠨⠋⠑⠈⠰⠣⠖⠆")?; + return Ok(()); +} + +#[test] +fn redox_IV_1_3() -> Result<()> { + let expr = r#" + H3O+ + / + H2O + "#; + test_braille("French", expr, "⠨⠓⠩⠨⠕⠈⠖⠌⠨⠓⠣⠨⠕")?; + return Ok(()); +} + +#[test] +fn mesomerism_IV_2_1() -> Result<()> { + // (CH₃)₂C=O ↔ (CH₃)₂C⁺−O⁻ + let expr = r#" + (CH3)2 + C=O + ↔ + (CH3)2 + C+- + O- + "#; + test_braille("French", expr, "⠦⠨⠉⠨⠓⠩⠴⠣⠨⠉⠶⠨⠕⠐⠻⠦⠨⠉⠨⠓⠩⠴⠣⠨⠉⠈⠖⠤⠨⠕⠈⠤")?; return Ok(()); } diff --git a/tests/braille/French/french.rs b/tests/braille/French/french.rs index a799b8ed7..6b1accc72 100644 --- a/tests/braille/French/french.rs +++ b/tests/braille/French/french.rs @@ -369,8 +369,17 @@ fn square_formula_3_10_05() -> Result<()> { #[test] fn function_from_r_to_r_11_01() -> Result<()> { - let expr= r#"f:ℝ→ℝ,x↦y=1x"#; - test_braille("French", expr, "⠋⠒⠨⠨⠗⠸⠱⠨⠨⠗⠭⠐⠱⠽⠶⠡⠌⠭")?; + // Spec §11 example, first line: f : ℝ → ℝ + let expr= r#"f:ℝ→ℝ"#; + test_braille("French", expr, "⠋⠒⠨⠨⠗⠸⠱⠨⠨⠗")?; + return Ok(()); +} + +#[test] +fn maps_to_y_equals_1_over_x_11_02() -> Result<()> { + // Spec §11 example, second line: x ↦ y = 1/x + let expr= r#"x↦y=1x"#; + test_braille("French", expr, "⠭⠐⠱⠽⠶⠡⠌⠭")?; return Ok(()); } @@ -460,25 +469,39 @@ fn restriction_of_f_to_13_2_04() -> Result<()> { // #[test] // fn determinant_tabular_13_3_01() -> Result<()> { -// let expr= r#"I=|1023|=3"#; +// let expr= r#"I=| +// 10 +// 23 +// |=3"#; // test_braille("French", expr, "not correct⠨⠊⠶⠿⠡⠀⠼⠿ ⠿⠣⠀⠩⠿⠶⠩")?; // return Ok(()); // } #[test] fn matrix_linear_13_3_02() -> Result<()> { - let expr= r#"J=(142356−789)"#; + let expr= r#"J=( + + 14 + 2356 + −789 + )"#; test_braille("French", expr, "⠨⠚⠶⠘⠦⠡⠀⠐⠂⠀⠐⠂⠀⠹⠀⠠⠜⠀⠣⠀⠩⠀⠱⠀⠫⠀⠠⠜⠀⠤⠻⠀⠳⠀⠐⠂⠀⠪⠘⠴")?; return Ok(()); } #[test] fn matrix_with_equations_one_lines_13_3_03() -> Result<()> { - let expr= r#"K=[1x2+3x−96x3−x2+1x+3y+5g(x)]"#; + let expr= r#"K=[ + 1x2+3x−96x3−x2+1 + x+3y+5g(x) + ]"#; test_braille("French", expr, "⠨⠅⠶⠘⠷⠡⠀⠰⠭⠈⠣⠖⠩⠭⠤⠪⠆⠌⠰⠫⠭⠈⠩⠤⠭⠈⠣⠖⠡⠆⠀⠠⠜⠀⠰⠭⠖⠩⠆⠌⠰⠽⠖⠱⠆⠀⠛⠦⠭⠴⠘⠾")?; return Ok(()); } #[test] fn sytem_equation_linéaraire_13_4_01() -> Result<()> { - let expr= r#"{2x+3y=53x−7y=8"#; + let expr= r#"{ + 2x+3y=5 + 3x−7y=8 + "#; test_braille("French", expr, "⠸⠦⠣⠭⠖⠩⠽⠶⠱⠀⠠⠜⠀⠩⠭⠤⠻⠽⠶⠳")?; return Ok(()); } @@ -519,7 +542,10 @@ fn limit_x_tends_1_14_2_01_corrected() -> Result<()> { #[test] fn limit_x_tends_and_x_lt_1_14_2_02_corrected_1() -> Result<()> { - let expr= r#"limx→4x>4f(x)=−∞"#; + let expr= r#"lim + x→4 + x>4 + f(x)=−∞"#; test_braille("French", expr, "⠇⠊⠍⠢⠢⠰⠭⠸⠱⠹⠂⠭⠐⠜⠹⠆⠋⠦⠭⠴⠶⠤⠘⠉")?; return Ok(()); } @@ -594,8 +620,12 @@ fn integral_over_curve_14_4_04() -> Result<()> { #[test] fn integral_double_over_surface_14_4_05() -> Result<()> { - let expr= r#"∯Sf(x,y)dxdy"#; - test_braille("French", expr, "⠨⠯⠯⠢⠨⠎⠋⠦⠭⠂⠽⠴⠙⠭⠙⠽")?; + let expr= r#"∯S + f(x,y)dxdy"#; + // The original expr doesn't bracket bracket the integral, but other similar cases do bracket an exponent that is followed by a char + // I was told that leaning towards disambiguation is better, and was told MathCAT's version was OK + // test_braille("French", expr, "⠨⠯⠯⠢⠨⠎⠋⠦⠭⠂⠽⠴⠙⠭⠙⠽")?; + test_braille("French", expr, "⠰⠨⠯⠯⠢⠨⠎⠆⠋⠦⠭⠂⠽⠴⠙⠭⠙⠽")?; return Ok(()); } @@ -633,8 +663,18 @@ fn cos_of_sum_2_14_6_01b() -> Result<()> { test_braille_prefs("French", vec![("French_UseShortForm", "true")], expr, "⠨⠬⠦⠁⠖⠃⠴⠶⠨⠬⠁⠨⠬⠃⠤⠬⠁⠬⠃")?; return Ok(()); } + #[test] fn cosh_sinh_14_7_01() -> Result<()> { + let expr= r#"ch2x−sh2x=1"#; + test_braille_prefs("French", vec![("French_UseShortForm", "true")], expr, "⠉⠓⠈⠣⠰⠭⠆⠤⠎⠓⠈⠣⠰⠭⠆⠶⠡")?; + + return Ok(()); +} + + +#[test] +fn cosh_sinh_14_7_01_fullname() -> Result<()> { let expr= r#"cosh2x−sinh2x=1"#; test_braille_prefs("French", vec![("French_UseShortForm", "true")], expr, "⠉⠓⠈⠣⠰⠭⠆⠤⠎⠓⠈⠣⠰⠭⠆⠶⠡")?; @@ -650,10 +690,215 @@ fn exists_element_of_15_01() -> Result<()> { #[test] fn set_formula_15_02() -> Result<()> { - let expr= r#"∀ε>0∃η>0:|x2−x1|≤η⇒|f(x2)−f(x1)|≤ε"#; + let expr= r#"∀ε>0∃ + η>0: + |x2−x1| + ≤η⇒ + |f(x2) + −f(x1) + |≤ε"#; + test_braille("French", expr, "⠸⠌⠘⠑⠐⠜⠼⠀⠸⠡⠘⠓⠐⠜⠼⠒⠀⠿⠭⠢⠣⠤⠭⠢⠡⠿⠘⠣⠘⠓⠀⠒⠂⠀⠿⠋⠦⠭⠢⠣⠴⠤⠋⠦⠭⠢⠡⠴⠿⠘⠣⠘⠑")?; + return Ok(()); +} + +#[test] +fn set_formula_15_02_from_word() -> Result<()> { + // Note: orginal used U+2008 (punctuation space) before ":" which triggers whitespace in the output + // If looks wrong also. Switched to U+2009 (thin space) + let expr= r#" + ∀ + ε + > + 0 +   + ∃ + η + > + 0 +   + : +   + + | + + x2 + - + x1 + + | + + ≤ + η +   + ⟹ +   + + | + + f + + ( + + x2 + + ) + + - + f + + ( + + x1 + + ) + + + | + + ≤ + ε + "#; test_braille("French", expr, "⠸⠌⠘⠑⠐⠜⠼⠀⠸⠡⠘⠓⠐⠜⠼⠒⠀⠿⠭⠢⠣⠤⠭⠢⠡⠿⠘⠣⠘⠓⠀⠒⠂⠀⠿⠋⠦⠭⠢⠣⠴⠤⠋⠦⠭⠢⠡⠴⠿⠘⠣⠘⠑")?; return Ok(()); } + +// --- 16.3 Unités (braille intégral) --- +// Spec also lists braille abrégé (letter indicator ⠠ before unit abbreviations after numbers); +// MathCAT emits intégral math braille only. + +#[test] +fn units_5_3_km_16_3_01() -> Result<()> { + let expr = r#"5,3 km"#; + test_braille("French", expr, "⠱⠂⠩⠀⠅⠍")?; + return Ok(()); +} + +#[test] +fn units_3_40_euro_16_3_02() -> Result<()> { + let expr = r#"3,40 €"#; + test_braille("French", expr, "⠩⠂⠹⠼⠀⠘⠑")?; + return Ok(()); +} + +#[test] +fn units_1_5_kW_16_3_03() -> Result<()> { + let expr = r#"1,5 kW"#; + test_braille("French", expr, "⠡⠂⠱⠀⠅⠨⠺")?; + return Ok(()); +} + +#[test] +fn units_220_V_16_3_04() -> Result<()> { + let expr = r#"220 V"#; + test_braille("French", expr, "⠣⠣⠼⠀⠨⠧")?; + return Ok(()); +} + +#[test] +fn units_67_km2_16_3_05() -> Result<()> { + let expr = r#"67 km2"#; + test_braille("French", expr, "⠫⠻⠀⠅⠍⠈⠣")?; + return Ok(()); +} + +#[test] +fn units_37_deg_16_3_06() -> Result<()> { + // Degree is attached to the number (no space), as in print + let expr = r#"37°"#; + test_braille("French", expr, "⠩⠻⠐⠕")?; + return Ok(()); +} + +#[test] +fn units_dms_16_3_07() -> Result<()> { + // 45° 25′ 12″ — spaces between degree/minute/second groups + let expr = r#" + 45°  + 25′  + 12″ + "#; + test_braille("French", expr, "⠹⠱⠐⠕⠀⠣⠱⠄⠀⠡⠣⠄⠄")?; + return Ok(()); +} + +#[test] +fn units_0_degC_16_3_08() -> Result<()> { + let expr = r#"0 ℃"#; + test_braille("French", expr, "⠼⠀⠐⠕⠨⠉")?; + return Ok(()); +} + +#[test] +fn units_50_km_h_16_3_09() -> Result<()> { + let expr = r#"50 km/h"#; + test_braille("French", expr, "⠱⠼⠀⠅⠍⠌⠓")?; + return Ok(()); +} + +#[test] +fn units_3_4_m_s_16_3_10() -> Result<()> { + // 3,4 m·s⁻¹ + let expr = r#" + 3,4  + m×s-1 + "#; + test_braille("French", expr, "⠩⠂⠹⠀⠍⠔⠎⠈⠤⠡")?; + return Ok(()); +} + +#[test] +fn units_2h35min15s_16_3_11() -> Result<()> { + let expr = r#" + 2 h  + 35 min  + 15 s + "#; + test_braille("French", expr, "⠣⠀⠓⠀⠩⠱⠀⠍⠊⠝⠀⠡⠱⠀⠎")?; + return Ok(()); +} + +#[test] +fn units_7_L_16_3_12() -> Result<()> { + let expr = r#"7 L"#; + test_braille("French", expr, "⠻⠀⠨⠇")?; + return Ok(()); +} + +#[test] +fn units_50_cL_16_3_13() -> Result<()> { + let expr = r#"50 cL"#; + test_braille("French", expr, "⠱⠼⠀⠉⠨⠇")?; + return Ok(()); +} + +#[test] +fn units_4_MHz_16_3_14() -> Result<()> { + let expr = r#"4 MHz"#; + test_braille("French", expr, "⠹⠀⠨⠍⠨⠓⠵")?; + return Ok(()); +} + +#[test] +fn units_6_ohm_16_3_15() -> Result<()> { + let expr = r#"6 Ω"#; + test_braille("French", expr, "⠫⠀⠨⠘⠺")?; + return Ok(()); +} + +#[test] +fn units_5_uV_16_3_16() -> Result<()> { + let expr = r#"5 μV"#; + test_braille("French", expr, "⠱⠀⠘⠍⠨⠧")?; + return Ok(()); +} + +#[test] +fn units_9_angstrom_16_3_17() -> Result<()> { + let expr = r#"9 Å"#; + test_braille("French", expr, "⠪⠀⠨⠁⠈⠕")?; + return Ok(()); +} + #[test] fn power_ordinal_a_16_4_07() -> Result<()> { let expr= r#"(p+q)ième"#; diff --git a/tests/braille/French/other.rs b/tests/braille/French/other.rs new file mode 100644 index 000000000..bcead397b --- /dev/null +++ b/tests/braille/French/other.rs @@ -0,0 +1,367 @@ +// French braille tests from additional sources (generated candidates). +// Base reference: "NOTATION MATHÉMATIQUE BRAILLE" (Première édition janvier 2007) +// https://www.avh.asso.fr/sites/default/files/notation_mathematique_braille2_0.pdf +// 4e, 5e, etc., refer to grade levels. Numbers refer to relevant sections in the spec. + +use crate::common::*; +use anyhow::Result; + +// --- lot1: digits, letters, sets --- + +#[test] +fn digit_isolated_5_1_01() -> Result<()> { + let expr= r#"5"#; + test_braille("French", expr, "⠱")?; + return Ok(()); +} + +#[test] +fn digit_multidigit_312_1_02() -> Result<()> { + let expr= r#"312"#; + test_braille("French", expr, "⠩⠡⠣")?; + return Ok(()); +} + +#[test] +fn digit_decimal_3_14_1_03() -> Result<()> { + let expr= r#"3,14"#; + test_braille("French", expr, "⠩⠂⠡⠹")?; + return Ok(()); +} + +#[test] +fn digit_negative_minus_7_1_04() -> Result<()> { + let expr= r#"−7"#; + test_braille("French", expr, "⠤⠻")?; + return Ok(()); +} + +#[test] +fn infinity_plus_1_05() -> Result<()> { + let expr= r#"+∞"#; + test_braille("French", expr, "⠖⠘⠉")?; + return Ok(()); +} + +#[test] +fn partial_derivative_round_d_2_1_01() -> Result<()> { + let expr= r#"∂"#; + test_braille("French", expr, "⠐⠙")?; + return Ok(()); +} + +#[test] +fn set_naturals_blackboard_n_2_2_01() -> Result<()> { + let expr= r#"ℕ"#; + test_braille("French", expr, "⠨⠨⠝")?; + return Ok(()); +} + +#[test] +fn greek_alpha_lower_2_3_01() -> Result<()> { + let expr= r#"α"#; + test_braille("French", expr, "⠘⠁")?; + return Ok(()); +} + +#[test] +fn greek_delta_upper_2_3_02() -> Result<()> { + let expr= r#"Δ"#; + test_braille("French", expr, "⠨⠘⠙")?; + return Ok(()); +} + +#[test] +fn hebrew_aleph_2_4_01() -> Result<()> { + let expr= r#"ℵ"#; + test_braille("French", expr, "⠘⠘⠁")?; + return Ok(()); +} + +// --- lot2: operations, equality, parentheses --- + +#[test] +fn addition_simple_3_01() -> Result<()> { + let expr= r#"2+3"#; + test_braille("French", expr, "⠣⠖⠩")?; + return Ok(()); +} + +#[test] +fn multiplication_cross_3_02() -> Result<()> { + let expr= r#"2×3"#; + test_braille("French", expr, "⠣⠔⠩")?; + return Ok(()); +} + +#[test] +fn plus_or_minus_3_03() -> Result<()> { + let expr= r#"±5"#; + test_braille("French", expr, "⠖⠤⠱")?; + return Ok(()); +} + +#[test] +fn function_composition_3_04() -> Result<()> { + let expr= r#"f∘g"#; + test_braille("French", expr, "⠋⠸⠼⠛")?; + return Ok(()); +} + +#[test] +fn equality_arithmetic_4_01() -> Result<()> { + let expr= r#"2+3=5"#; + test_braille("French", expr, "⠣⠖⠩⠶⠱")?; + return Ok(()); +} + +#[test] +fn inequality_less_than_4_02() -> Result<()> { + let expr= r#"x<5"#; + test_braille("French", expr, "⠭⠐⠣⠱")?; + return Ok(()); +} + +#[test] +fn approximately_equal_pi_4_03() -> Result<()> { + let expr= r#"π≈3,14"#; + test_braille("French", expr, "⠘⠏⠐⠶⠩⠂⠡⠹")?; + return Ok(()); +} + +#[test] +fn parenthesis_simple_5_01() -> Result<()> { + let expr= r#"(a+b)"#; + test_braille("French", expr, "⠦⠁⠖⠃⠴")?; + return Ok(()); +} + +#[test] +fn parenthesis_nested_imbrication_5_02() -> Result<()> { + let expr= r#"f(g(x))"#; + test_braille("French", expr, "⠋⠐⠦⠛⠦⠭⠴⠐⠴")?; + return Ok(()); +} + +#[test] +fn braces_set_with_condition_5_03() -> Result<()> { + let expr= r#"{x:x>0}"#; + test_braille("French", expr, "⠨⠦⠭⠒⠭⠐⠜⠼⠨⠴")?; + return Ok(()); +} + +// --- 4e --- + +#[test] +fn linear_equation_4e_3_4_01() -> Result<()> { + let expr= r#"2x+3=7"#; + test_braille("French", expr, "⠣⠭⠖⠩⠶⠻")?; + return Ok(()); +} + +#[test] +fn inequality_4e_4_01() -> Result<()> { + let expr= r#"2x−1<5"#; + test_braille("French", expr, "⠣⠭⠤⠡⠐⠣⠱")?; + return Ok(()); +} + +#[test] +fn pythagoras_4e_9_3_01() -> Result<()> { + let expr= r#"a2+b2=c2"#; + test_braille("French", expr, "⠁⠈⠣⠖⠃⠈⠣⠶⠉⠈⠣")?; + return Ok(()); +} + +#[test] +fn square_root_simple_4e_10_01() -> Result<()> { + let expr= r#"25=5"#; + test_braille("French", expr, "⠜⠣⠱⠶⠱")?; + return Ok(()); +} + +#[test] +fn scientific_notation_4e_9_3_02() -> Result<()> { + let expr= r#"3×103"#; + test_braille("French", expr, "⠩⠔⠡⠼⠈⠩")?; + return Ok(()); +} + +#[test] +fn negative_exponent_4e_9_3_03() -> Result<()> { + let expr= r#"10−2=0,01"#; + test_braille("French", expr, "⠡⠼⠈⠤⠣⠶⠼⠂⠼⠡")?; + return Ok(()); +} + +#[test] +fn sin_function_full_4e_14_6_01() -> Result<()> { + let expr= r#"sin(30°)=12"#; + test_braille("French", expr, "⠎⠊⠝⠦⠩⠼⠐⠕⠴⠶⠡⠌⠣")?; + return Ok(()); +} + +#[test] +fn binomial_square_4e_9_3_5_01() -> Result<()> { + let expr= r#"(a+b)2=a2+2ab+b2"#; + test_braille("French", expr, "⠦⠁⠖⠃⠴⠈⠣⠶⠁⠈⠣⠖⠣⠁⠃⠖⠃⠈⠣")?; + return Ok(()); +} + +#[test] +fn square_root_complex_4e_10_8_01() -> Result<()> { + let expr= r#"a2+b2"#; + test_braille("French", expr, "⠜⠰⠁⠈⠣⠖⠃⠈⠣⠆")?; + return Ok(()); +} + +#[test] +fn probability_4e_5_7_01() -> Result<()> { + let expr= r#"P(A)=14"#; + test_braille("French", expr, "⠨⠏⠦⠨⠁⠴⠶⠡⠌⠹")?; + return Ok(()); +} + +// --- 5e --- + +#[test] +fn fraction_add_simple_5e_7_3_01() -> Result<()> { + let expr= r#"13+14=712"#; + test_braille("French", expr, "⠡⠌⠩⠖⠡⠌⠹⠶⠻⠌⠡⠣")?; + return Ok(()); +} + +#[test] +fn negative_add_5e_3_01() -> Result<()> { + let expr= r#"−5+3=−2"#; + test_braille("French", expr, "⠤⠱⠖⠩⠶⠤⠣")?; + return Ok(()); +} + +#[test] +fn literal_expression_5e_3_01() -> Result<()> { + let expr= r#"3a+2b"#; + test_braille("French", expr, "⠩⠁⠖⠣⠃")?; + return Ok(()); +} + +#[test] +fn percentage_5e_16_4_01() -> Result<()> { + let expr= r#"15%×60=9"#; + test_braille("French", expr, "⠡⠱⠐⠬⠔⠫⠼⠶⠪")?; + return Ok(()); +} + +#[test] +fn power_two_digit_base_5e_9_3_01() -> Result<()> { + let expr= r#"102=100"#; + test_braille("French", expr, "⠡⠼⠈⠣⠶⠡⠼⠼")?; + return Ok(()); +} + +#[test] +fn volume_cube_formula_5e_9_3_02() -> Result<()> { + let expr= r#"V=a3"#; + test_braille("French", expr, "⠨⠧⠶⠁⠈⠩")?; + return Ok(()); +} + +#[test] +fn fraction_complex_numerator_5e_7_8_01() -> Result<()> { + let expr= r#"a+b2"#; + test_braille("French", expr, "⠰⠁⠖⠃⠆⠌⠣")?; + return Ok(()); +} + +#[test] +fn triangle_area_5e_7_8_02() -> Result<()> { + let expr= r#"A=b×h2"#; + test_braille("French", expr, "⠨⠁⠶⠰⠃⠔⠓⠆⠌⠣")?; + return Ok(()); +} + +#[test] +fn angles_sum_greek_5e_2_3_16_01() -> Result<()> { + let expr= r#"α+β=90°"#; + test_braille("French", expr, "⠘⠁⠖⠘⠃⠶⠪⠼⠐⠕")?; + return Ok(()); +} + +#[test] +fn proportionality_ratio_5e_7_4_01() -> Result<()> { + let expr= r#"ab=cd"#; + test_braille("French", expr, "⠁⠌⠃⠶⠉⠌⠙")?; + return Ok(()); +} + +// --- 6e --- + +#[test] +fn addition_6e_3_01() -> Result<()> { + let expr= r#"12+7=19"#; + test_braille("French", expr, "⠡⠣⠖⠻⠶⠡⠪")?; + return Ok(()); +} + +#[test] +fn multiplication_6e_3_02() -> Result<()> { + let expr= r#"6×8=48"#; + test_braille("French", expr, "⠫⠔⠳⠶⠹⠳")?; + return Ok(()); +} + +#[test] +fn division_6e_3_03() -> Result<()> { + let expr= r#"15÷3=5"#; + test_braille("French", expr, "⠡⠱⠒⠩⠶⠱")?; + return Ok(()); +} + +#[test] +fn priority_no_parens_6e_3_4_01() -> Result<()> { + let expr= r#"3+4×2=11"#; + test_braille("French", expr, "⠩⠖⠹⠔⠣⠶⠡⠡")?; + return Ok(()); +} + +#[test] +fn parentheses_priority_6e_5_01() -> Result<()> { + let expr= r#"(3+4)×2=14"#; + test_braille("French", expr, "⠦⠩⠖⠹⠴⠔⠣⠶⠡⠹")?; + return Ok(()); +} + +#[test] +fn fraction_simple_6e_7_01() -> Result<()> { + let expr= r#"34"#; + test_braille("French", expr, "⠩⠌⠹")?; + return Ok(()); +} + +#[test] +fn fraction_equality_6e_7_4_01() -> Result<()> { + let expr= r#"12=24"#; + test_braille("French", expr, "⠡⠌⠣⠶⠣⠌⠹")?; + return Ok(()); +} + +#[test] +fn fraction_decimal_6e_7_1_01() -> Result<()> { + let expr= r#"34=0,75"#; + test_braille("French", expr, "⠩⠌⠹⠶⠼⠂⠻⠱")?; + return Ok(()); +} + +#[test] +fn square_exponent_6e_9_3_01() -> Result<()> { + let expr= r#"52=25"#; + test_braille("French", expr, "⠱⠈⠣⠶⠣⠱")?; + return Ok(()); +} + +#[test] +fn perpendicular_lines_6e_12_3_01() -> Result<()> { + let expr= r#"(AB)⊥(CD)"#; + test_braille("French", expr, "⠦⠨⠁⠨⠃⠴⠘⠳⠦⠨⠉⠨⠙⠴")?; + return Ok(()); +} From d743060a0c3818030b3a0ddd079742d942ef1503 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 6 Aug 2026 22:30:00 -0700 Subject: [PATCH 019/157] Add "(eau)" as a state (for French) Added several more chem arrows. --- src/chemistry.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/chemistry.rs b/src/chemistry.rs index 4b991dcef..461e50187 100644 --- a/src/chemistry.rs +++ b/src/chemistry.rs @@ -81,10 +81,15 @@ static MERGED_TOKEN: &str = "data-merged"; /// these can be in the base of an under/over script fn is_chem_equation_arrow(ch: char) -> bool { matches!(ch, - '→' | '➔' | '←' | '⟶' | '⟵' | '⤻' | '⇋' | '⇌' | + // reaction arrows + '→' | '➔' | '←' | '⟶' | '⟵' | '⤻' | '⇒' | '⇐' | '⟹' | '⟸' | + // equilibrium + '⇋' | '⇌' | '⇄' | '⇆' | '⥂' | '⥄' | '⥃' | + // mesomerism / resonance (left-right) + '↔' | '⟷' | '⇔' | '⟺' | + // vertical / other chem arrows '↑' | '↓' | '↿' | '↾' | '⇃' | '⇂' | '⥮' | '⥯' | '⇷' | '⇸' | '⤉' | '⤈' | - '⥂' | '⥄' | '⥃' | - '\u{1f8d0}' | '\u{1f8d1}' | '\u{1f8d2}' | '\u{1f8d3}' | '\u{1f8d4}' | '\u{1f8d5}' // proposed Unicode equilibrium arrows + '\u{1f8d0}' | '\u{1f8d1}' | '\u{1f8d2}' | '\u{1f8d3}' | '\u{1f8d4}' | '\u{1f8d5}' // new Unicode equilibrium arrows ) } @@ -969,7 +974,7 @@ fn likely_chem_subscript(subscript: Element) -> i32 { return 0; // not really much chem info about an integer subscript } else if subscript_name == "mi" { let text = as_text(subscript); - if text == "s" || text == "l" || text == "g" || text == "aq" { + if text == "s" || text == "l" || text == "g" || text == "aq" || text == "eau" { subscript.set_attribute_value(CHEM_STATE, "true"); return 2; } @@ -1691,7 +1696,7 @@ fn is_equilibrium_constant(mut mathml: Element) -> bool { // All instances seem to be upper case that I've seen. static SMALL_UPPER_ROMAN_NUMERAL: LazyLock = LazyLock::new(|| Regex::new(r"^\s*^(IX|IV|V?I{0,3})\s*$").unwrap()); -/// look for "(s), "(l)", "(g)", "(aq)" (could also use [...]) +/// look for "(s)", "(l)", "(g)", "(aq)", "(eau)" (could also use [...]) /// this might be called before canonicalization, but in clean_chemistry_mrow, we made sure "( xxx )" is grouped properly pub fn likely_chem_state(mathml: Element) -> i32 { @@ -1701,7 +1706,7 @@ pub fn likely_chem_state(mathml: Element) -> i32 { let contents_name = name(contents); if contents_name == "mi" || contents_name == "mtext" { let text = as_text(contents); - if text == "s" || text == "l" ||text == "g" ||text == "aq" { + if text == "s" || text == "l" || text == "g" || text == "aq" || text == "eau" { return text.len() as i32 + 1; // hack to count chars -- works because all are ASCII }; } From 0d7a39a8e99df4fe6b3c5fb92208645e74646cf7 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 6 Aug 2026 22:31:59 -0700 Subject: [PATCH 020/157] add more arrows. French at the moment doesn't seem to distinguish between different arrows that go in the same direction. That seems wrong, but the spec is silent on the alternatives --- Rules/Braille/French/unicode-full.yaml | 11 ++--------- Rules/Braille/French/unicode.yaml | 13 ++++++------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/Rules/Braille/French/unicode-full.yaml b/Rules/Braille/French/unicode-full.yaml index e27f214a6..c0bc5275e 100644 --- a/Rules/Braille/French/unicode-full.yaml +++ b/Rules/Braille/French/unicode-full.yaml @@ -19,18 +19,11 @@ - "": [t: ""] # 0xfeff (BOM / zero-width no-break space) - - "⇌": [t: "⠸⠻"] # 0x21CC (Rightwards harpoon over leftwards harpoon (equilibrium)) -# - "⥂": [t: ""] # 0x2942 (Rightwards arrow above short leftwards arrow (equilibrium, trend to the right)) -# - "⥄": [t: ""] # 0x2944 (Short rightwards arrow above leftwards arrow (equilibrium, trend to the left)) + - "⇌⥂⥄⥃": [t: "⠸⠻"] # 0x21CC/2942/2944/2943 equilibrium (incl. trend variants) # Mappings for some new Unicode chemistry arrows/symbols # These repeat the short arrow version because that is what is in the spec (GTM 16), but the spec should really use the long version - - "🣑": [t: "⠸⠻"] # 0x1F8D1 LONG RIGHTWARDS HARPOON OVER LONG LEFTWARDS HARPOON (equilibrium) -# - "🣒": [t: ""] # 0x1f8d2 LONG RIGHTWARDS HARPOON ABOVE SHORT LEFTWARDS HARPOON(equilibrium, trend to the right) -# - "🣓": [t: ""] # 0x1f8d3 SHORT RIGHTWARDS HARPOON ABOVE LONG LEFTWARDS HARPOON (equilibrium, trend to the left)) - -# - "🣐": [t: ""] # 0x1F8D0 LONG RIGHTWARDS ARROW OVER LONG LEFTWARDS ARROW -# - "🣕": [t: ""] # 0x1F8D5 SHORT LEFTWARDS HARPOON ABOVELONG RIGHTWARDS HARPOON + - "🣐🣑🣒🣓🣔🣕": [t: "⠸⠻"] # 0x1F8D0–1F8D5 long equilibrium / related chem arrows # - "🣖": [t: ""] # 0x1F8D6 LONG RIGHTWARDS ARROW WITH THROUGH X # - "🣗": [t: ""] # 0x1F8D7 LONG RIGHTWARDS ARROW WITH DOUBLE SLASH # - "": [t: ""] # 0x1F8D8 LONG LEFT RIGHT ARROW WITH DEPENDENT LOBE (no clue what to do) diff --git a/Rules/Braille/French/unicode.yaml b/Rules/Braille/French/unicode.yaml index ce310bb3c..6da5cc310 100644 --- a/Rules/Braille/French/unicode.yaml +++ b/Rules/Braille/French/unicode.yaml @@ -251,7 +251,11 @@ if: "parent::m:mrow/*[self::m:mtable] or (following-sibling::*[1][self::m:mtable] and count(following-sibling::*[1]/*) = 1)" then: [t: "⠸⠦"] else: [t: "⠨⠦"] # regular brace - - "|": [t: "⠿"] # 0x007C (vertical bar) + - "|": # 0x007C (vertical bar) + - test: + if: "parent::m:mrow/*[self::m:mtable]" + then: [t: "⠸⠿"] # multi-line (linear matrix/determinant) + else: [t: "⠿"] # single-line - "}": # 0x007D (right curly brace)) - test: if: "parent::m:mrow/*[self::m:mtable]" @@ -285,12 +289,7 @@ if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" then: [t: "⠘⠱"] else: [t: "⠘⠻"] - - "→": # 0x2192 (right pointing arrow) - - test: - if: "parent::m:mover and not(following-sibling::*)" - then: [t: "⠨⠒"] - else: [t: "⠸⠱"] - - "⇀": # 0x2192 (right pointing arrow) + - "→⇀": # 0x2192 (right pointing arrow) - test: if: "parent::m:mover and not(following-sibling::*)" then: [t: "⠨⠒"] From 363fc51331bdcfe3104a3fc5ce11fdaa822621f7 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 6 Aug 2026 22:32:55 -0700 Subject: [PATCH 021/157] removed some intent attrs that were not needed --- tests/braille/French/chemistry.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/braille/French/chemistry.rs b/tests/braille/French/chemistry.rs index 97528e114..8ce715f5c 100644 --- a/tests/braille/French/chemistry.rs +++ b/tests/braille/French/chemistry.rs @@ -197,7 +197,7 @@ fn reaction_III_2_2() -> Result<()> { #[test] fn reaction_III_2_3() -> Result<()> { // HCl(g)+H₂O(l)→(eau) H₃O⁺(aq)+Cl⁻(aq) — line-continuation ⠐ omitted - let expr = r#" + let expr = r#" HCl(g) + H2O(l) @@ -327,7 +327,7 @@ fn redox_IV_1_3() -> Result<()> { #[test] fn mesomerism_IV_2_1() -> Result<()> { // (CH₃)₂C=O ↔ (CH₃)₂C⁺−O⁻ - let expr = r#" + let expr = r#" (CH3)2 C=O ↔ From 9588ed97a4182fc7511a602ecd41fc88bc2bbdf9 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 6 Aug 2026 22:33:33 -0700 Subject: [PATCH 022/157] uncomment a determinant test after fixing the braille --- tests/braille/French/french.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/tests/braille/French/french.rs b/tests/braille/French/french.rs index 6b1accc72..4a823d0b6 100644 --- a/tests/braille/French/french.rs +++ b/tests/braille/French/french.rs @@ -467,15 +467,16 @@ fn restriction_of_f_to_13_2_04() -> Result<()> { return Ok(()); } -// #[test] -// fn determinant_tabular_13_3_01() -> Result<()> { -// let expr= r#"I=| -// 10 -// 23 -// |=3"#; -// test_braille("French", expr, "not correct⠨⠊⠶⠿⠡⠀⠼⠿ ⠿⠣⠀⠩⠿⠶⠩")?; -// return Ok(()); -// } +#[test] +fn determinant_tabular_13_3_01() -> Result<()> { + let expr= r#"I=| + 10 + 23 + |=3"#; + test_braille("French", expr, "⠨⠊⠶⠸⠿⠡⠀⠼⠀⠠⠜⠀⠣⠀⠩⠸⠿⠶⠩")?; + return Ok(()); +} + #[test] fn matrix_linear_13_3_02() -> Result<()> { let expr= r#"J=( From 4408cb20178bfb7c6e75e13f1ddb39b19813401a Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 6 Aug 2026 23:08:37 -0700 Subject: [PATCH 023/157] Add rules for multiple lines in a script position done via an mtable or a more restricted version for nested munder/mover. They add a "," between lines. This was done for limit_x_tends_1_14_2_01_corrected and limit_x_tends_1_14_2_02_corrected --- Rules/Braille/French/French_Rules.yaml | 46 +++++++++++++++++++++----- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/Rules/Braille/French/French_Rules.yaml b/Rules/Braille/French/French_Rules.yaml index 66a14b325..3c77813a5 100644 --- a/Rules/Braille/French/French_Rules.yaml +++ b/Rules/Braille/French/French_Rules.yaml @@ -125,22 +125,24 @@ name: default tag: [mtr, mlabeledtr] match: "." + # When an mtable is used in a script position (e.g. stacked lim conditions), §14.2 + # joins rows with a comma (⠂) rather than the matrix row-change (⠠⠜). + variables: + - InScriptPosition: "parent::m:mtable[preceding-sibling::* and IsNode(.., 'modified')]" replace: - test: if: "preceding-sibling::*" - then: [t: "W⠠⠜W"] - - # - test: - # if: .[self::m:mlabeledtr] - # then: - # - t: "⠗⠕⠺W⠇⠁⠃⠑⠇⠸⠒" # "row label:" - # - x: "*[1]/*" # contents of row label + then: + - test: + if: "$InScriptPosition" + then: [t: "⠂"] # comma between script-position rows + else: [t: "W⠠⠜W"] # matrix/system row change - test: if: .[self::m:mlabeledtr] then: [x: "*[position()>1]"] else: {x: "*"} - test: - if: "following-sibling::* " + if: "following-sibling::* and not($InScriptPosition)" then: [t: "W"] - @@ -427,6 +429,34 @@ - x: "*[2]" - x: "*[1]" +- + # Nested munder/mover for lim / large operators (§14.2): join the two script + # conditions with a comma (⠂), like script-position mtables — one script + # indicator and one block around both conditions. + name: nested-lim-or-largeop-conditions + tag: [munder, mover] + match: "((self::m:munder and *[1][self::m:munder]) or (self::m:mover and *[1][self::m:mover])) and + *[1]/*[1][IsInDefinition(., 'Braille', 'LargeOperators') or .='lim' or .='Lim']" + replace: + - t: "b" + - test: + if: "NeedsToBeGrouped(*[1]/*[1], 'French', true())" + then: + - t: "o" + - x: "*[1]/*[1]" + - t: "c" + else: [x: "*[1]/*[1]"] + - test: + - if: "self::m:munder" + then: [t: "⠢⠢"] + else: [t: "⠈⠈"] + - t: "o" + - x: "*[1]/*[2]" + - t: "⠂" + - x: "*[2]" + - t: "c" + - t: "e" + - name: default tag: [msub, msup, munder, mover] From 5c482681655dbd37a1df66869a983cbaff4e0d2d Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 6 Aug 2026 23:10:56 -0700 Subject: [PATCH 024/157] a linebreaks to MathML to make it easier to read --- tests/braille/French/french.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/braille/French/french.rs b/tests/braille/French/french.rs index 4a823d0b6..1f3348c1a 100644 --- a/tests/braille/French/french.rs +++ b/tests/braille/French/french.rs @@ -553,7 +553,11 @@ fn limit_x_tends_and_x_lt_1_14_2_02_corrected_1() -> Result<()> { #[test] fn limit_x_tends_and_x_lt_2_14_2_02_corrected_2() -> Result<()> { - let expr= r#"limx→4x>4f(x)=−∞"#; + let expr= r#" + limx→4 + x>4 + + f(x)=−∞"#; test_braille("French", expr, "⠇⠊⠍⠢⠢⠰⠭⠸⠱⠹⠂⠭⠐⠜⠹⠆⠋⠦⠭⠴⠶⠤⠘⠉")?; return Ok(()); } From e5a9c87d81d817ce3ecb31f9bb62c7c755a0151f Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 6 Aug 2026 23:27:55 -0700 Subject: [PATCH 025/157] add more arrow chars -- I thought I did this in a previous commit, but apparently not. --- Rules/Braille/French/unicode.yaml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Rules/Braille/French/unicode.yaml b/Rules/Braille/French/unicode.yaml index 6da5cc310..89f876bd6 100644 --- a/Rules/Braille/French/unicode.yaml +++ b/Rules/Braille/French/unicode.yaml @@ -283,18 +283,18 @@ - "€": [t: "⠘⠑"] # 0x20AC (euro) - "Å": [t: "⠨⠁⠈⠕"] # 0x212B (angstrom) - "ℵ": [t: "HL⠁"] # 0x2135 (alef) - - "←": [t: "⠸⠪"] # 0x2190 (left pointing arrow) - - "↑": # 0x2191 (arrow pointing up) + - "←⟵": [t: "⠸⠪"] # 0x2190/27F5 (left / long left arrow) + - "↑↿↾⤉": # 0x2191/21BF/21BE/2909 (up arrow / harpoons / barred) - test: if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" then: [t: "⠘⠱"] else: [t: "⠘⠻"] - - "→⇀": # 0x2192 (right pointing arrow) + - "→⇀➔⟶⤻": # 0x2192/21C0/2794/27F6/293B (right arrow / harpoon / long / curved) - test: if: "parent::m:mover and not(following-sibling::*)" then: [t: "⠨⠒"] else: [t: "⠸⠱"] - - "↓": # 0x2193 (arrow pointing down) + - "↓⇃⇂⤈": # 0x2193/21C3/21C2/2908 (down arrow / harpoons / barred) - test: if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" then: [t: "⠨⠱"] @@ -304,16 +304,16 @@ - "↗": [t: "⠘⠱"] # 0x2197 (north east arrow) - "↘": [t: "⠨⠱"] # 0x2198 (south east arrow) - "↙": [t: "⠨⠪"] # 0x2199 (south west arrow) - - "↚": [t: "⠨⠸⠪"] # 0x219A (leftwards arrow with stroke) - - "↛": [t: "⠨⠸⠱"] # 0x219B (rightwards arrow with stroke) + - "↚⇷": [t: "⠨⠸⠪"] # 0x219A/21F7 (leftwards arrow with stroke) + - "↛⇸": [t: "⠨⠸⠱"] # 0x219B/21F8 (rightwards arrow with stroke) - "↦": [t: "⠐⠱"] # 0x21A6 (rightwards arrow from bar (maps to)) - - "⇄": [t: "⠸⠻"] # 0x21C4 (arrow pointing right over arrow pointing left) + - "⇄⟷⇌⇋⇆⥮⥯": [t: "⠸⠻"] # 0x21C4/27F7/21CC/21CB/21C6/296E/296F (equilibrium / reversibility) - "⇍": [t: "⠨⠐⠒"] # 0x21CD (leftwards double arrow with stroke) - "⇎": [t: "⠨⠐⠒⠂"] # 0x21CE (left right double arrow with stroke (not equivalent)) - "⇏": [t: "⠨⠒⠂"] # 0x21CF (rightwards double arrow with stroke (does not imply)) - - "⇐": [t: "⠐⠒"] # 0x21D0 (leftwards double arrow) - - "⇒": [t: "⠒⠂"] # 0x21D2 (rightwards double arrow (implication)) - - "⇔": [t: "⠐⠒⠂"] # 0x21D4 (left right double arrow (double implication, equivalence)) + - "⇐⟸": [t: "⠐⠒"] # 0x21D0/27F8 (leftwards double / long) + - "⇒⟹": [t: "⠒⠂"] # 0x21D2/27F9 (rightwards double / long) + - "⇔⟺": [t: "⠐⠒⠂"] # 0x21D4/27FA (left right double / long) - "∀": [t: "⠸⠌"] # 0x2200 (universal quantifier (for all, for each, for every)) - "∁": [t: "⠨⠩"] # 0x2201 (capital english c (complement)) - "∂": [t: "⠐⠙"] # 0x2202 (partial derivative (round d)) From c2dbcc64c3e72fd7973a0f369f8868754211a550 Mon Sep 17 00:00:00 2001 From: mgros Date: Sat, 15 Aug 2026 03:14:51 +0200 Subject: [PATCH 026/157] Add MathJax demo link to developer docs for rendering inspection --- docs/developers.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/developers.md b/docs/developers.md index 2bc2f71e2..04440907c 100644 --- a/docs/developers.md +++ b/docs/developers.md @@ -74,6 +74,10 @@ fn test_simple_fraction() { } ``` +## Helpful Links + +* [MathJax Demo](https://www.mathjax.org/#demo) (archived) lets you paste a MathML fragment and inspect its browser rendering. It can be useful when checking whether an input expression itself renders as expected. + ### Test Coverage Test coverage helps identify which parts of the code are exercised by tests and which parts need more testing. @@ -121,4 +125,4 @@ open target/coverage/html/index.html **Alternative: IDE Integration** -Many Rust IDEs provide built-in test coverage support, like RustRover or VSCode. \ No newline at end of file +Many Rust IDEs provide built-in test coverage support, like RustRover or VSCode. From eebb4be6e7ef538f3f55c3b30985d9b5c128d6d7 Mon Sep 17 00:00:00 2001 From: mgros Date: Sat, 15 Aug 2026 03:16:11 +0200 Subject: [PATCH 027/157] . --- docs/developers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developers.md b/docs/developers.md index 04440907c..331a16d78 100644 --- a/docs/developers.md +++ b/docs/developers.md @@ -76,7 +76,7 @@ fn test_simple_fraction() { ## Helpful Links -* [MathJax Demo](https://www.mathjax.org/#demo) (archived) lets you paste a MathML fragment and inspect its browser rendering. It can be useful when checking whether an input expression itself renders as expected. +* [MathJax Demo](https://www.mathjax.org/#demo): lets you paste a MathML fragment and inspect its browser rendering. ### Test Coverage From 8e886cc25bfb4952aa7532f5c23c6244d6928a8f Mon Sep 17 00:00:00 2001 From: NSoiffer Date: Fri, 14 Aug 2026 23:55:14 -0700 Subject: [PATCH 028/157] Merge changes (mostly unicode) from hu branch (#688) * Add few tweaks into the Rules/Languages/hu/definitions.yaml file, Added missing definitions.rs test file the test/Languages/hu directory, and added SimpleSpeak test directory the mroot and menclose tests (#646) * Do more localization in Rules/Languages/hu/definitions.yaml Signed-off-by: Attila Hammer * Add in Simplespeak tests the definition, mroot and menclose tests Signed-off-by: Attila Hammer * fix some werbs in intervals into rules/Languages/hu/ClearSpeak_rules.yaml and SimpleSpeak_rules.yaml Signed-off-by: Attila Hammer * Fix tests after interval Clearspeak and SimpleSpeak verb change Signed-off-by: Attila Hammer --------- Signed-off-by: Attila Hammer * Apply Hungarian unicode fixes from PR #673 --------- Signed-off-by: Attila Hammer Co-authored-by: hammera --- Rules/Languages/hu/ClearSpeak_Rules.yaml | 4 +- Rules/Languages/hu/SimpleSpeak_Rules.yaml | 4 +- Rules/Languages/hu/definitions.yaml | 99 +- Rules/Languages/hu/unicode-full.yaml | 21 +- Rules/Languages/hu/unicode.yaml | 5 - tests/Languages/hu.rs | 5 +- tests/Languages/hu/ClearSpeak/functions.rs | 16 +- tests/Languages/hu/SimpleSpeak/functions.rs | 12 +- tests/Languages/hu/SimpleSpeak/menclose.rs | 266 +++++ tests/Languages/hu/SimpleSpeak/mroot.rs | 178 ++++ tests/Languages/hu/definitions.rs | 1026 +++++++++++++++++++ tests/Languages/hu/shared.rs | 2 +- 12 files changed, 1552 insertions(+), 86 deletions(-) create mode 100644 tests/Languages/hu/SimpleSpeak/menclose.rs create mode 100644 tests/Languages/hu/SimpleSpeak/mroot.rs create mode 100644 tests/Languages/hu/definitions.rs diff --git a/Rules/Languages/hu/ClearSpeak_Rules.yaml b/Rules/Languages/hu/ClearSpeak_Rules.yaml index 02040fc5d..73d8eaf5e 100644 --- a/Rules/Languages/hu/ClearSpeak_Rules.yaml +++ b/Rules/Languages/hu/ClearSpeak_Rules.yaml @@ -623,7 +623,7 @@ - test: if: "starts-with(name(.), 'open')" then: [T: "nem"] # phrase(the interval from a to b 'not' including b) - - T: "tartalmazza a" # phrase(the interval from a to b not 'including' b) + - T: "tartalmazza a(z)" # phrase(the interval from a to b not 'including' b) - x: "*[1]" - T: "elemet" # logic to deal with [not] arg #1 @@ -647,7 +647,7 @@ if: "name(.) = 'open-interval' or name(.) = 'closed-open-interval'" then: [T: "nem"] # phrase(the interval 'not' including a) - T: "tartalmazza" # phrase(the interval not 'including' a) - - T: "a" + - T: "a(z)" - x: "*[2]" - T: "elemet" # onto the [not] [including]... part diff --git a/Rules/Languages/hu/SimpleSpeak_Rules.yaml b/Rules/Languages/hu/SimpleSpeak_Rules.yaml index b5f263c3a..5037a4122 100644 --- a/Rules/Languages/hu/SimpleSpeak_Rules.yaml +++ b/Rules/Languages/hu/SimpleSpeak_Rules.yaml @@ -574,7 +574,7 @@ - test: if: "starts-with(name(.), 'open')" then: [T: "nem"] # phrase(the interval from a to b 'not' including b) - - T: "tartalmazza a" # phrase(the interval from a to b not 'including' b) + - T: "tartalmazza a(z)" # phrase(the interval from a to b not 'including' b) - x: "*[1]" - T: "elemet" # logic to deal with [not] arg #1 @@ -598,7 +598,7 @@ if: "name(.) = 'open-interval' or name(.) = 'closed-open-interval'" then: [T: "nem"] # phrase(the interval 'not' including a) - T: "tartalmazza" # phrase(the interval not 'including' a) - - T: "a" + - T: "a(z)" - x: "*[2]" - T: "elemet" # onto the [not] [including]... part diff --git a/Rules/Languages/hu/definitions.yaml b/Rules/Languages/hu/definitions.yaml index c0e75bee2..bdc649424 100644 --- a/Rules/Languages/hu/definitions.yaml +++ b/Rules/Languages/hu/definitions.yaml @@ -23,28 +23,28 @@ #"closed-open-interval":"function=interval between; included and", #"open-closed-interval":"function=interval between; and included", #"open-interval":"function=open interval between; and", - "inverse":"function=inverse || postfix=inverse", + "inverse":"function=inverz || postfix=inverz", "domain": "function= ; domén", "codomain": "function= ; kodomán", - "image":"function=image", + "image":"function=kép", #"fraction":"function=fraction; over; end fraction", # NOTE: Fails - "mixed-fraction":"infix=and", # NOTE: in website says function, but follow infix speech pattern. - "greatest-common-divisor": "function=gcd: a GCD: a legnagyobb közös osztó", - "quotient":"function=szám rész; osztva ezzel:", # NOTE: Logic somewhere here failing, becomes "divided by of x comma, y" instead of "integer part of x divided by y" - "evaluated-at":"infix=értékelték", - "remainder":"function=a maradék; osztva ezzel:", + "mixed-fraction":"infix=és", # NOTE: in website says function, but follow infix speech pattern. + "greatest-common-divisor": "function=a legnagyobb közös osztó", + "quotient":"function=egész rész osztva", # NOTE: Logic somewhere here failing, becomes "divided by of x comma, y" instead of "integer part of x divided by y" + "evaluated-at":"infix=értékelve || postfix=értékként", + "remainder":"function=a maradék, osztva", "max":"function=max", "min":"function=min", "power":"infix=a hatványra", "root":"function=root", - "imaginary-part": "function=képzeletbeli rész: a képzeletbeli rész: a képzeletbeli rész", + "imaginary-part": "a képzeletbeli rész", "least-common-multiple": "function=lcm: a legkisebb közös többszörös: a legkisebb közös többszörös", "complex-conjugate":"function=Komplex konjugált", "complex-arg":"function=argumentum", - "polar-coordinate":"function=poláris koordináta; vessző", - "spherical-coordinate":"function=gömb koordináta; vessző; vessző", - "cartesian-coordinate":"function=derékszögű koordináta; vessző", - "coordinate":"function=koordináta; vessző", + "polar-coordinate":"function=poláris koordináta", + "spherical-coordinate":"function=gömb koordináta", + "cartesian-coordinate":"function=derékszögű koordináta", + "coordinate":"function=koordináta", "floor":"function=lépcső", "ceiling":"function=mennyezet", "round":"function=kerekített érték", @@ -60,7 +60,7 @@ "dimension": "function=; dimenzió : dimenzió: a dimenzió; dimenzió vége", "homomorphism": "function= ; homomorfizmus : homomorfizmus: a homomorfizmus; homomorfizmus vége", "kernel": "function= ; kernel : kernel: a kernel; kernel vége", - "dot-product": "infix=skaláris szorzat: skaláris szorzat: skaláris szorzat: skaláris szorzat", + "dot-product": "infix=skaláris szorzat", #"divergence": "function= ; dihv: divergencia: divergencia; divergencia vége", #"laplacian": "function=laplaciáns", # speech engines don't do a good job with "laplacian" @@ -69,19 +69,20 @@ ### Calculus "definite-integral":"function=integrál felett || function=integrál innen:; ide:", # Property ??? "derivative":"function=a deriváltja; mely erre vonatkozik:", # Property ??? - "tends-to":"infix=általában", + "tends-to":"infix=ehhez tart", "tends-to-from-above":"infix=általában alulról indul", - + "tends-to-from-below":"infix=alulról indul", ### Sets "set": "function= ; halmaz: a halmaz", + "set-difference":"function=különbséghalmaz || infix=mínusz || postfix=különbséghalmaza", # NOTE: not tested "complement":"function=komplemens", - "empty-set":"nofix=üres halmaz", + "empty-set":"function=üres halmaz", "cardinality":"function=számosság", # NOTE: does not have a defined speech template in website "list":"function=lista", "tuple": "function= ; tuple: a tuple", ### Sequence and Series "sum":"function= ; összegzés : összeg ; ", #: sum over : sum from; to", - "product":"function=produktum || function=produktum vége || function=produktum innen:; ide:", + "product":"function=szorzat || function=szorzat vége || function=szorzat innen ide", ### Elementary classical functions "sine":"function=szinusz: szinusz", @@ -91,23 +92,23 @@ "cosecant":"function=koszekáns: koszekáns", "cotangent":"function=kotangens: kotangens", "arcsine":"function=arkusz szinusz", - #"arccosine":"function=arkusz koszinusz", + "arccosine":"function=arkusz koszinusz", "arctangent":"function=arkusz tangens", "arcsecant":"function=arkusz szekáns", "arccosecant":"function=arkusz koszekáns", "arccotangent":"function=arkusz kotangens", "hyperbolic-sine":"function=hiperbolikus szinusz", "hyperbolic-cosine":"function=hiperbolikus koszinusz", - "hyperbolic-tangent":"function=hiperbolikus tangenstanch", - "hyperbolic-secant":"function=sech", - "hyperbolic-cosecant":"function=cosech", - "hyperbolic-cotangent":"function=coth", - "arc-hyperbolic-sine":"function=arc shine", - "arc-hyperbolic-cosine":"function=arc cosh", - "arc-hyperbolic-tangent":"function=arc tanch", - "arc-hyperbolic-secant":"function=arc sech", - "arc-hyperbolic-cosecant":"function=arc cosech", - "arc-hyperbolic-cotangent":"function=arc coth", + "hyperbolic-tangent":"function=hiperbolikus tangens", + "hyperbolic-secant":"function=hiperbolikus szekáns", + "hyperbolic-cosecant":"function=hiperbolikus koszekáns", + "hyperbolic-cotangent":"function=hiperbolikus kotangens", + "arc-hyperbolic-sine":"function=arkusz hiperbolikus szinusz", + "arc-hyperbolic-cosine":"function=arkusz hiperbolikus koszinusz", + "arc-hyperbolic-tangent":"function=arkusz hiperbolikus tangens", + "arc-hyperbolic-secant":"function=arkusz hiperbolikus szekáns", + "arc-hyperbolic-cosecant":"function=arkusz hiperbolikus koszekáns", + "arc-hyperbolic-cotangent":"function=arkusz hiperbolikus kotangens", "exponential":"function=exponenciális", "natural-logarithm": "function=l n: természetes alapú logaritmus: természetes alapú logaritmus", "logarithm":"function=logaritmus", ##Check arity 2 @@ -138,7 +139,7 @@ ### Constants and Sets "set-of-integers":"nofix=ℤ: az összes egész szám halmaza", - "set-of-reals":"nofix=ℝ: az összes valós szám halmaza", + "set-of-reals":"nofix=valós számok halmaza: az összes valós szám halmaza", "set-of-rationals":"nofix=ℚ: az összes racionális szám halmaza", "set-of-natural-numbers":"nofix=ℕ: az összes természetes szám halmaza", "set-of-complex-numbers":"nofix=ℂ: az összes komplex szám halmaza", @@ -167,13 +168,13 @@ "highlight":"postfix=kiemelt", "least-common-denominator":"function=legkisebb közös nevező", "rate":"infix=per", - "constraint":"infix= ; korlátozással; ", + "constraint":"infix= ; feltétellel; ", "binomial-coefficient":"infix=választ", "pochhammer":"function=permutáció", "permutation-cycle":"function=permutációs ciklus", - "embellished-name":"infix=jegyzetekkel", - + "embellished-name":"infix=megjegyzéssel", + "annotation":"infix= ; ami ;", # NOTE: Follows the same order as indexed-by, in site listed as function. Should it be infix? ### Other ## Default fixity function "curl": "function=rotáció", @@ -185,7 +186,7 @@ "angle": "prefix=szög", "angle-measure": "prefix=szögmérés", "change": "prefix=változás", - "for-all": "prefix=mindenkinek", + "for-all": "prefix=minden", "measured-angle": "prefix=mért szög", "not": "prefix=nem", "number-of": "prefix=száma", @@ -198,7 +199,7 @@ ## Default fixity infix "and": "infix=és", - "applied-to": "infix=alkalmazva erre", + "applied-to": "infix=alkalmazva", "approximately": "infix=hozzávetőlegesen", "congruent": "infix=egybeesik", "cartesian-product": "infix=derékszögű szorzat", @@ -210,7 +211,7 @@ "does-not-belong-to": "infix=nem tartozik hozzá", "does-not-divide": "infix=nem osztja", "downwards-diagonal-ellipsis": "infix=lefelé mutató átlós ellipszis", - "direct-product": "infix=direkt produktum", + "direct-product": "infix=direkt szorzat", "element-of": "infix=eleme", "ellipsis": "infix=ellipszis", "equals": "infix=egyenlő", @@ -222,7 +223,7 @@ "identically-equals": "infix=teljesen egyenlő", "if-and-only-if": "infix=akkor és csak akkor, ha", "implies": "infix=utal", - "inner-product": "infix=belső produktum", + "inner-product": "infix=belső szorzat", "intersection": "infix=keresztezi", "less-than": "infix=kisebb, mint", "less-than-or-equal-to": "infix=kisebb vagy egyenlő, mint", @@ -231,13 +232,13 @@ "member-of": "infix=tagja", "minus-or-plus": "infix=mínusz vagy plusz", "not-subset": "infix=nem részhalmaza", - "not-superset": "infix=nem szuperhalmaz", + "not-superset": "infix=nem szuperhalmaza", "not-equal-to": "infix=nem egyenlő", "not-member-of": "infix=nem tagja", "not-parallel-to": "infix=nem párhuzamos", - "obtained-from": "infix=származó", + "obtained-from": "infix=innen származik", "or": "infix=vagy", - "outer-product": "infix=külső produktum", + "outer-product": "infix=külső szorzata", "parallel-to": "infix=párhuzamos", "perpendicular": "infix=merőleges", "plus": "infix=plusz || prefix=pozitív", # Prefix not tested @@ -246,16 +247,16 @@ "precedes": "infix=megelőzi", "proportional": "infix=arányos", "range-separator": "infix=keresztül", - "ratio": "infix=hányados", + "ratio": "infix=arány", "similar": "infix=hasonló", "subset": "infix=részhalmaza", "subset-or-equal": "infix=részhalmaza vagy egyenlő", - "succeeds": "infix=sikerül", + "succeeds": "infix=követi", "such-that": "infix=úgy, hogy", "superset": "infix=szuperhalmaza", - "superset-or-equal": "infix=szuperhalmaz vagy egyenlő", + "superset-or-equal": "infix=szuperhalmaza vagy egyenlő", "tilde": "infix=tilde", - "times": "infix=szorzata", + "times": "infix=szorozva", "union": "infix=unió", "upwards-diagonal-ellipsis": "infix=felfelé átlós ellipszis", "vertical-ellipsis": "infix=függőleges ellipszis", @@ -270,9 +271,9 @@ "distance":"nofix=távolság; távolság: távolság", "probability":"nofix=P: valószínűség", "radius":"nofix=r: sugár", - "volume":"nofix=V: hangerő || function=", + "volume":"nofix=hangerő: hangerő || function=hangerő", "exponential-e":"nofix=e", - "imaginary-i":"nofix=i", + "imaginary-i":"nofix=képzeletbeli én", "differential-d":"nofix=d", "golden-ratio":"nofix=aranymetszés", @@ -290,11 +291,11 @@ # These are the parts of a formula that can be navigated to "large-op": "base; lower limit; upper limit", "mfrac": "numerator; denominator", - "fraction": "numerator; denominator", - "msqrt": "root", - "square-root": "root", + "fraction": "számláló; nevező", + "msqrt": "gyök", + "square-root": "gyök", "mroot": "root; root index", - "root": "root; root index", + "root": "gyök; gyök index", "msub": "base; subscript", "sub": "base; subscript", "logarithm-with-base": "base", diff --git a/Rules/Languages/hu/unicode-full.yaml b/Rules/Languages/hu/unicode-full.yaml index 2926422e0..4ab669c7a 100644 --- a/Rules/Languages/hu/unicode-full.yaml +++ b/Rules/Languages/hu/unicode-full.yaml @@ -273,7 +273,7 @@ - "‱": [T: "per tízezer"] # 0x2031 (en: 'per ten thousand', DeepL translation) - "′": [T: "prím"] # 0x2032 (en: 'prime', DeepL translation) - "″": [T: "dupla prím"] # 0x2033 (en: 'double prime', DeepL translation) - - "‴": [T: "hármas ikerprím"] # 0x2034 (en: 'triple prime', DeepL translation) + - "‴": [T: "hármas prím"] # 0x2034 (en: 'triple prime', DeepL translation) - "‵": [T: "fordított prím"] # 0x2035 (en: 'reversed prime', DeepL translation) - "‶": [T: "fordított dupla prím"] # 0x2036 (en: 'reversed double prime', DeepL translation) - "‷": [T: "fordított hármas prím"] # 0x2037 (en: 'reversed triple prime', DeepL translation) @@ -951,11 +951,6 @@ - "⊢": [T: "bizonyítja"] # 0x22a2 (en: 'proves', DeepL translation) - "⊣": [T: "nem enged"] # 0x22a3 (en: 'does not yield', DeepL translation) - "⊤": [T: "felső"] # 0x22a4 (en: 'top', DeepL translation) - - "⊥": # 0x22a5 - - test: - if: "$Verbosity!='Terse'" - then: [T: "a(z)"] # (en: 'is', DeepL translation) - - T: "alul" # (en: 'bottom', DeepL translation) - "⊦": [T: "redukálódik"] # 0x22a6 (en: 'reduces to', DeepL translation) - "⊧": [T: "modellezi"] # 0x22a7 (en: 'models', DeepL translation) - "⊨": # 0x22a8 @@ -1543,11 +1538,15 @@ - "➾": [T: "nyitott körvonalú jobbra mutató nyíl"] # 0x27be (en: 'open-outlined right arrow', DeepL translation) - "⟀": [T: "háromdimenziós szög"] # 0x27c0 (en: 'three dimensional angle', DeepL translation) - "⟁": [T: "fehér háromszög, benne egy kis fehér háromszög"] # 0x27c1 (en: 'white triangle containing small white triangle', DeepL translation) - - "⟂": # 0x27c2 - - test: - if: "$Verbosity!='Terse'" - then: [T: "a(z)"] # (en: 'is', DeepL translation) - - T: "merőleges" # (en: 'perpendicular to', DeepL translation) + - "⟂⊥": # 0x27c2, 22A5 (22A5 wrongly used for perpendicular by most editors) + - test: + - if: "$SpeechStyle = 'LiteralSpeak' and text()='⊥'" # 22A5 (up tack/bottom) + then: [T: "felfelé mutató merőleges"] + - else: + - test: + if: "$Verbosity!='Terse'" + then: [T: "a(z)"] + - T: "merőleges" - "⟃": # 0x27c3 - test: if: "$Verbosity!='Terse'" diff --git a/Rules/Languages/hu/unicode.yaml b/Rules/Languages/hu/unicode.yaml index 41f8263f2..16561b733 100644 --- a/Rules/Languages/hu/unicode.yaml +++ b/Rules/Languages/hu/unicode.yaml @@ -297,7 +297,6 @@ - "⁢": [T: ""] # 0x2062 - "⁣": [T: "láthatatlan elválasztó"] # 0x2063 - "⁤": [T: "és"] # 0x2064 (en: 'and', DeepL translation) - - "‴": [T: "hármas prím"] # 0x2034 (en: 'triple prime', DeepL translation) - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" - T: "duplán leütött" # (en: 'double-struck', DeepL translation) @@ -418,7 +417,6 @@ then: [T: "benne van ebben:"] # (en: 'is in', DeepL translation) - else: [T: "ebbe a halmazba tartozik:"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to', DeepL translation) - "∐": [T: "diszjunkt unió"] # 0x2210 (en: 'co-product', DeepL translation) - - "∗": [T: "csillag operátortimes"] # 0x2217 (DeepL translation) - "√": # 0x221a - test: if: "$Verbosity!='Terse'" @@ -448,7 +446,6 @@ if: "$Verbosity!='Terse'" then: [T: "van"] # (en: 'is', DeepL translation) - T: "hogy" # (DeepL translation) - - "∷": [T: "arány"] # 0x2237 (DeepL translation) - "∾": # 0x223e - test: if: "$Verbosity!='Terse'" @@ -474,8 +471,6 @@ if: "$Verbosity!='Terse'" then: [T: ""] # (en: 'is', DeepL translation) - T: "nagyobb vagy egyenlő" # (en: 'greater than or equal to', DeepL translation) - - "≦": [T: "kisebb, mint egyenlő"] # 0x2266 (en: 'less than over equal to', DeepL translation) - - "≧": [T: "nagyobb, mint az egyenlő"] # 0x2267 (en: 'greater than over equal to', DeepL translation) - "⊂": # 0x2282 - test: if: "$Verbosity!='Terse'" diff --git a/tests/Languages/hu.rs b/tests/Languages/hu.rs index 45bce3f9c..ac24dd22e 100644 --- a/tests/Languages/hu.rs +++ b/tests/Languages/hu.rs @@ -15,9 +15,9 @@ mod ClearSpeak { mod SimpleSpeak { mod functions; mod large_ops; - // mod menclose; + mod menclose; mod mfrac; - // mod mroot; + mod mroot; mod msup; mod sets; mod geometry; @@ -29,6 +29,7 @@ mod shared; mod units; mod chemistry; mod alphabets; +mod definitions; mod intent; mod mtable; diff --git a/tests/Languages/hu/ClearSpeak/functions.rs b/tests/Languages/hu/ClearSpeak/functions.rs index e9449b213..3dd6e94e7 100644 --- a/tests/Languages/hu/ClearSpeak/functions.rs +++ b/tests/Languages/hu/ClearSpeak/functions.rs @@ -516,7 +516,7 @@ fn explicit_times_none_superscript() -> Result<()> { ) "; test_ClearSpeak("hu", "ClearSpeak_Paren", "Interval",expr, - "c től d ig terjedő intervallum, nem tartalmazza a c elemet vagy d elemet")?; + "c től d ig terjedő intervallum, nem tartalmazza a(z) c elemet vagy d elemet")?; return Ok(()); } @@ -530,7 +530,7 @@ fn explicit_times_none_superscript() -> Result<()> { ) "; test_ClearSpeak("hu", "ClearSpeak_Paren", "Interval ",expr, - "c től d ig terjedő intervallum, tartalmazza a c elemet de nem tartalmazza a d elemet")?; + "c től d ig terjedő intervallum, tartalmazza a(z) c elemet de nem tartalmazza a(z) d elemet")?; return Ok(()); } @@ -545,7 +545,7 @@ fn parens_interval_open_closed() -> Result<()> { ] "; test_ClearSpeak("hu", "ClearSpeak_Paren", "Interval ",expr, - "c től d ig terjedő intervallum, nem tartalmazza a c elemet de tartalmazza a d elemet")?; + "c től d ig terjedő intervallum, nem tartalmazza a(z) c elemet de tartalmazza a(z) d elemet")?; return Ok(()); } @@ -560,7 +560,7 @@ fn parens_interval_closed_closed() -> Result<()> { ] "; test_ClearSpeak("hu", "ClearSpeak_Paren", "Interval ",expr, -"c től d ig terjedő intervallum, tartalmazza a c elemet és d elemet")?; +"c től d ig terjedő intervallum, tartalmazza a(z) c elemet és d elemet")?; return Ok(()); } @@ -573,7 +573,7 @@ return Ok(()); ) "; test_ClearSpeak("hu", "ClearSpeak_Paren", "Interval ",expr, - "negatív végtelen től d ig terjedő intervallum, nem tartalmazza a d elemet")?; + "negatív végtelen től d ig terjedő intervallum, nem tartalmazza a(z) d elemet")?; return Ok(()); } @@ -586,7 +586,7 @@ return Ok(()); ] "; test_ClearSpeak("hu", "ClearSpeak_Paren", "Interval ",expr, - "negatív végtelen től d ig terjedő intervallum, tartalmazza a d elemet")?; + "negatív végtelen től d ig terjedő intervallum, tartalmazza a(z) d elemet")?; return Ok(()); } @@ -601,7 +601,7 @@ fn parens_interval_open_open_infinity() -> Result<()> { ) "; test_ClearSpeak("hu", "ClearSpeak_Paren", "Interval ",expr, - "c től végtelen ig terjedő intervallum, nem tartalmazza a c elemet")?; + "c től végtelen ig terjedő intervallum, nem tartalmazza a(z) c elemet")?; return Ok(()); } @@ -616,7 +616,7 @@ fn parens_interval_closed_open_infinity() -> Result<()> { ) "; test_ClearSpeak("hu", "ClearSpeak_Paren", "Interval ",expr, -"c től végtelen ig terjedő intervallum, tartalmazza a c elemet")?; +"c től végtelen ig terjedő intervallum, tartalmazza a(z) c elemet")?; return Ok(()); } diff --git a/tests/Languages/hu/SimpleSpeak/functions.rs b/tests/Languages/hu/SimpleSpeak/functions.rs index aa4c2a43a..8ecf02cb8 100644 --- a/tests/Languages/hu/SimpleSpeak/functions.rs +++ b/tests/Languages/hu/SimpleSpeak/functions.rs @@ -355,7 +355,7 @@ fn no_times_sqrt() -> Result<()> { (c,d) ) "; - test("hu", "SimpleSpeak",expr, "c től d ig terjedő intervallum, nem tartalmazza a c elemet vagy d elemet")?; + test("hu", "SimpleSpeak",expr, "c től d ig terjedő intervallum, nem tartalmazza a(z) c elemet vagy d elemet")?; return Ok(()); } @@ -368,7 +368,7 @@ fn no_times_sqrt() -> Result<()> { [(]c,d) ) "; - test("hu", "SimpleSpeak",expr, "c től d ig terjedő intervallum, tartalmazza a c elemet de nem tartalmazza a d elemet")?; + test("hu", "SimpleSpeak",expr, "c től d ig terjedő intervallum, tartalmazza a(z) c elemet de nem tartalmazza a(z) d elemet")?; return Ok(()); } @@ -382,7 +382,7 @@ fn parens_interval_open_closed() -> Result<()> { (c,d] ] "; - test("hu", "SimpleSpeak",expr,"c től d ig terjedő intervallum, nem tartalmazza a c elemet de tartalmazza a d elemet")?; + test("hu", "SimpleSpeak",expr,"c től d ig terjedő intervallum, nem tartalmazza a(z) c elemet de tartalmazza a(z) d elemet")?; return Ok(()); } @@ -396,7 +396,7 @@ fn parens_interval_closed_closed() -> Result<()> { [(]c,d] ] "; - test("hu", "SimpleSpeak",expr, "c től d ig terjedő intervallum, tartalmazza a c elemet és d elemet")?; + test("hu", "SimpleSpeak",expr, "c től d ig terjedő intervallum, tartalmazza a(z) c elemet és d elemet")?; return Ok(()); } @@ -409,7 +409,7 @@ fn parens_interval_closed_closed() -> Result<()> { ) "; test("hu", "SimpleSpeak",expr, - "negatív végtelen től d ig terjedő intervallum, nem tartalmazza a d elemet")?; + "negatív végtelen től d ig terjedő intervallum, nem tartalmazza a(z) d elemet")?; return Ok(()); } @@ -422,7 +422,7 @@ fn parens_interval_closed_closed() -> Result<()> { ] "; test("hu", "SimpleSpeak",expr, - "negatív végtelen től d ig terjedő intervallum, tartalmazza a d elemet")?; + "negatív végtelen től d ig terjedő intervallum, tartalmazza a(z) d elemet")?; return Ok(()); } diff --git a/tests/Languages/hu/SimpleSpeak/menclose.rs b/tests/Languages/hu/SimpleSpeak/menclose.rs new file mode 100644 index 000000000..33c03f699 --- /dev/null +++ b/tests/Languages/hu/SimpleSpeak/menclose.rs @@ -0,0 +1,266 @@ +use crate::common::*; +use anyhow::Result; + +// AI generated +#[test] +fn menclose_actuarial() -> Result<()> { + let expr = " + 3+2i + "; + test("hu", "ClearSpeak", expr, "aktuárius szimbólum, kezdet: 3 plusz 2 i végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_box() -> Result<()> { + let expr = " + 3+2i + "; + test("hu", "ClearSpeak", expr, "doboz, kör, kezdet: 3 plusz 2 i végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_left() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "vonal balra, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_right() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "vonal jobbra, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_top_bottom() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "vonal felső, alsó, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_updiagonalstrike() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "átlósan felfelé, kihúzva, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_downdiagonalstrike() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "átlósan lefelé, kihúzva, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_cross_out() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "x, kihúzva, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_vertical_horizontal_strike() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "függőleges, vízszintes, kihúzva, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_leftarrow() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "balra nyíl, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_right_up_down_arrow() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "felfelé nyíl, lefelé nyíl, jobbra nyíl, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_northeastarrow() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "északkeleti nyíl, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_other_single_arrows() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "délkeleti nyíl, délnyugati nyíl, északnyugati nyíl, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_northwestsoutheastarrow() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "kétvégű lefelé mutató átlós nyíl, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_other_double_arrows() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "kétvégű függőleges nyíl, kétvégű vízszintes nyíl, dupla végű átlós nyíl, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_madrub() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "arab faktoriális szimbólum, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_phasorangle() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "fázisszög, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_circle_phasorangle() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "kör, fázisszög, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_longdiv() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "hosszú osztásjel, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_longdiv_default() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "hosszú osztásjel, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_longdiv_empty_string() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "hosszú osztásjel, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_longdiv_whitespace_string() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "hosszú osztásjel, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn menclose_radical() -> Result<()> { + let expr = " + 32 + "; + test("hu", "ClearSpeak", expr, "négyzetgyök, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn simple_speak_menclose_top_bottom() -> Result<()> { + let expr = " + 32 + "; + test("hu", "SimpleSpeak", expr, "vonal felső, alsó, kezdet: 3 ketted végpont vége")?; + return Ok(()); + +} diff --git a/tests/Languages/hu/SimpleSpeak/mroot.rs b/tests/Languages/hu/SimpleSpeak/mroot.rs new file mode 100644 index 000000000..225e191c0 --- /dev/null +++ b/tests/Languages/hu/SimpleSpeak/mroot.rs @@ -0,0 +1,178 @@ +use crate::common::*; +use anyhow::Result; + +// AI generated +#[test] +fn msqrt_simple() -> Result<()> { + let expr = " + x + "; + test("hu", "SimpleSpeak", expr, "a négyzetgyöke ennek: x")?; + return Ok(()); + +} + +// AI generated +#[test] +fn msqrt_simple_end_root() -> Result<()> { + let expr = " + x + "; + test_ClearSpeak("hu", "ClearSpeak_Roots", "RootEnd", expr, "négyzetgyök x, gyök vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn msqrt_simple_positive() -> Result<()> { + let expr = " + x + "; + test_ClearSpeak("hu", "ClearSpeak_Roots", "PosNegSqRoot", expr, "pozitív négyzetgyök x")?; + return Ok(()); + +} + +// AI generated +#[test] +fn msqrt_simple_pos_end_root() -> Result<()> { + let expr = " + x + "; + test_ClearSpeak("hu", "ClearSpeak_Roots", "PosNegSqRootEnd", expr, "pozitív négyzetgyök x, gyök vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn msqrt_simple_pos_end_with_neg_root() -> Result<()> { + let expr = " + - x + - x 3 + "; + test_ClearSpeak("hu", "ClearSpeak_Roots", "PosNegSqRootEnd", expr, + "negatív négyzetgyök x, gyök vége; mínusz, a pozitív köbgyök x, gyök vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn mroot_simple_pos_end_with_neg_root() -> Result<()> { + let expr = " + - x 3 + - x + + "; + test_ClearSpeak("hu", "ClearSpeak_Roots", "PosNegSqRoot", expr, + "a negatív köbgyök x; mínusz pozitív négyzetgyök x")?; + return Ok(()); + +} + +// AI generated +#[test] +fn neg_without_root() -> Result<()> { + let expr = " + - x - y + "; + test("hu", "ClearSpeak", expr, "negatív x mínusz y")?; + return Ok(()); + +} + +// AI generated +#[test] +fn msqrt() -> Result<()> { + let expr = " + + x + y + + "; + test("hu", "ClearSpeak", expr, "négyzetgyök x plusz y")?; + return Ok(()); + +} + +// AI generated +#[test] +fn mroot_as_square_root() -> Result<()> { + let expr = " + x 2 + "; + test("hu", "ClearSpeak", expr, "négyzetgyök x")?; + return Ok(()); + +} + +// AI generated +#[test] +fn cube_root() -> Result<()> { + let expr = " + x 3 + "; + test("hu", "ClearSpeak", expr, "a köbgyök x")?; + return Ok(()); + +} + +// AI generated +#[test] +fn ordinal_root() -> Result<()> { + let expr = " + x 9 + "; + test("hu", "ClearSpeak", expr, "a kilencedik gyök x")?; + return Ok(()); + +} + +// AI generated +#[test] +fn simple_mi_root() -> Result<()> { + let expr = " + x n + "; + test("hu", "ClearSpeak", expr, "a n-edik gyök x")?; + return Ok(()); + +} + +// AI generated +#[test] +fn mroot_simple_pos_end_root() -> Result<()> { + let expr = " + x t + "; + test_ClearSpeak("hu", "ClearSpeak_Roots", "PosNegSqRootEnd", expr, "a pozitív t-edik gyök x, gyök vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn mroot_simple_end_root() -> Result<()> { + let expr = " + x + y + 21 + "; + test_ClearSpeak("hu", "ClearSpeak_Roots", "RootEnd", expr, "a huszonegyedik gyök x plusz y, gyök vége")?; + return Ok(()); + +} + +// AI generated +#[test] +fn simple_fraction_power() -> Result<()> { + let expr = " + + x + 13 + + "; + test("hu", "ClearSpeak", expr, "a 1 harmad gyök x")?; + return Ok(()); + +} diff --git a/tests/Languages/hu/definitions.rs b/tests/Languages/hu/definitions.rs new file mode 100644 index 000000000..bd84fb155 --- /dev/null +++ b/tests/Languages/hu/definitions.rs @@ -0,0 +1,1026 @@ +/// Tests for rules in definitions: +/// * modified var +use crate::common::*; +use anyhow::Result; + +#[test] +fn tuple_basic() -> Result<()> { + // function + let expr = r#" + + + x + y + + + "#; + + test("hu", "ClearSpeak", expr, "a tuple x vessző, y")?; + test("hu", "SimpleSpeak", expr, "a tuple x vessző, y")?; + + return Ok(()); +} + +#[test] +fn my_set_basic() -> Result<()> { + let expr = r#" + + + x + y + + + "#; + + test("hu", "ClearSpeak", expr, "az üres halmaz")?; + + Ok(()) +} + +#[test] +fn fixed_test() -> Result<()> { + let expr = r#" + + az összes valós szám halmaza + + + "#; + + test("hu", "ClearSpeak", expr, "az összes valós szám halmaza")?; + Ok(()) +} + +#[test] +fn i_test() -> Result<()> { + let expr = r#" + + képzeletbeli én + + + "#; + + test("hu", "ClearSpeak", expr, "képzeletbeli én")?; + Ok(()) +} + + +#[test] +fn floor_basic() -> Result<()> { + let expr = r#" + + + x + + + "#; + + test("hu", "ClearSpeak", expr, "lépcső x")?; + + Ok(()) +} + +#[test] +fn set_difference_basic() -> Result<()> { + let expr = r#" + + + A + ∖ + B + + + "#; + + test( "hu", "ClearSpeak", expr, "különbséghalmaz nagy a vessző, nagy b")?; + + Ok(()) +} + +#[test] +fn postfix_test() -> Result<()> { + let tests = [ + ( + "transpose", + r#" + + x + T + + "#, + "transzponált x", + ), + ( + "highlight", + r#" + + x + + "#, + "x kiemelt", + ), + ]; + + // Loop through all test cases, name _, body, and expected result + for (_, body, expected) in tests { + let expr = format!( + r#" + + {} + + "#, + body + ); + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} + +#[test] +fn prefix_test() -> Result<()> { + // Prefix test limit, unit-vector, line-segment + // Directed-line-segment, line, ray, arc + let tests = [ + ( + "limit", + r#" + + x + + "#, + "határérték x", + ), + ( + "unit-vector", + r#" + + x + ^ + + "#, + "egységvektor x", + ), + ( + "line-segment", + r#" + + x + ¯ + + "#, + "line segment x", + ), + ]; + + for (_, body, expected) in tests { + let expr = format!( + r#" + + {} + + "#, + body + ); + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} + + +#[test] +fn functions_and_inverses_tests() -> Result<()> { + let tests = vec![ + ("closed-interval", "x től y ig terjedő intervallum, tartalmazza a(z) x elemet és y elemet"), + ("closed-open-interval", "x től y ig terjedő intervallum, tartalmazza a(z) x elemet de nem tartalmazza a(z) y elemet"), + ("open-closed-interval", "x től y ig terjedő intervallum, nem tartalmazza a(z) x elemet de tartalmazza a(z) y elemet"), + ("open-interval", "x től y ig terjedő intervallum, nem tartalmazza a(z) x elemet vagy y elemet"), + + ("inverse", "inverz x"), + ("domain", "domén x"), + ("codomain", "kodomán x"), + ("image", "kép x"), + + //("fraction", "fraction x over y end fraction"), + ("mixed-fraction", "x és y"), + ("quotient", "egész rész osztva x vessző, y"), + ("evaluated-at", "x értékelve y"), + ("remainder", "a maradék, osztva x vessző, y"), + + ("max", "max x vessző, y vessző, z"), + ("min", "min x vessző, y vessző, z"), + + ("power", "x a(z) y-edik hatványon"), + + //("root", "gyök x"), + + ("greatest-common-divisor", "a legnagyobb közös osztó x vessző, y vessző, z"), + ("least-common-multiple", "a legkisebb közös többszörös x vessző, y vessző, z"), + + ("absolute-value", "x abszolút értéke"), + + ("complex-conjugate", "Komplex konjugált x"), + ("complex-arg", "argumentum x"), + ("real-part", "valós rész"), + ("imaginary-part", "képzetes rész"), + + ("polar-coordinate", "poláris koordináta x vessző, y"), + ("spherical-coordinate", "gömb koordináta x vessző, y vessző, z"), + ("cartesian-coordinate", "derékszögű koordináta x vessző, y vessző, z"), + ("coordinate", "pont, x vessző y vessző z"), + + ("floor", "lépcső x"), + ("ceiling", "mennyezet x"), + ("round", "kerekített érték x"), + ("fractional-part", "tört rész x"), + + + ]; + + for (intent, expected) in tests { + let expr = match intent { + + "max" + | "min" + | "greatest-common-divisor" + | "least-common-multiple" + | "spherical-coordinate" + | "cartesian-coordinate" + | "coordinate" => { + format!( + " + + x + y + z + + ", + intent + ) + } + + "power" + | "mixed-fraction" + | "quotient" + | "evaluated-at" + | "remainder" + | "closed-interval" + | "closed-open-interval" + | "open-closed-interval" + | "open-interval" + | "polar-coordinate" => { + format!( + " + + x + y + + ", + intent + ) + } + + _ => { + format!( + " + + x + + ", + intent + ) + } + }; + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} + + +#[test] +fn calculus_tests() -> Result<()> { + let tests = vec![ + //("derivative", "the derivative of x with respect to x"), + //"definite-integral", "integral over x from x to x"), + + // prefix + ("limit", "határérték x"), + + // infix + ("tends-to", "x ehhez tart y"), + ("tends-to-from-above", "x általában alulról indul y"), + ("tends-to-from-below", "x alulról indul y"), + ]; + + for (intent, expected) in tests { + let expr = match intent { + "limit" => { + format!( + " + + x + + ", + intent + ) + } + + _ => { + // infix cases + format!( + " + + x + y + + ", + intent + ) + } + }; + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} + + +#[test] +fn set_tests() -> Result<()> { + let tests = vec![ + ("set", "a halmaz x"), + //("set-difference", "x és y halmaz különbsége"), + ("complement", "komplemens x"), + //("empty-set", "üres halmaz"), + ("cardinality", "számosság x"), + ("list", "lista x"), + ("tuple", "a tuple x"), + ]; + + for (intent, expected) in tests { + let expr = format!( + " + + x + + ", + intent + ); + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} + + +#[test] +fn sequence_and_series_intents() -> Result<()> { + let tests = [ + ( + "sum-1", + r#" + + ∑ + x + + "#, + "összeg x", + ), + ( + "sum-2", + r#" + + ∑ + i + x + + "#, + "összeg i vessző, x", + ), + ( + "sum-3", + r#" + + ∑ + i + n + x + + "#, + "összeg i vessző, n vessző, x", + ), + ( + "product-1", + r#" + + ∏ + x + + "#, + "szorzat x", + ), + ( + "product-2", + r#" + + ∏ + i + x + + "#, + "szorzat i vessző, x", + ), + ( + "product-3", + r#" + + ∏ + i + n + x + + "#, + "szorzat i vessző, n vessző, x", + ), + ]; + + for (_, body, expected) in tests { + let expr = format!( + r#" + + {} + + "#, + body + ); + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} + +#[test] +fn elementary_classical_tests() -> Result<()> { + let tests = vec![ + // Trig + ("sine", "szinusz x"), + ("cosine", "koszinusz x"), + ("tangent", "tangens x"), + ("secant", "szekáns x"), + ("cosecant", "koszekáns x"), + ("cotangent", "kotangens x"), + + // Inverse trig + ("arcsine", "arkusz szinusz x"), + ("arccosine", "arkusz koszinusz x"), + ("arctangent", "arkusz tangens x"), + ("arcsecant", "arkusz szekáns x"), + ("arccosecant", "arkusz koszekáns x"), + ("arccotangent", "arkusz kotangens x"), + + // Hyperbolic trig + ("hyperbolic-sine", "hiperbolikus szinusz x"), + ("hyperbolic-cosine", "hiperbolikus koszinusz x"), + ("hyperbolic-tangent", "hiperbolikus tangens x"), + ("hyperbolic-secant", "hiperbolikus szekáns x"), + ("hyperbolic-cosecant", "hiperbolikus koszekáns x"), + ("hyperbolic-cotangent", "hiperbolikus kotangens x"), + + // Inverse hyperbolic trig + ("arc-hyperbolic-sine", "arkusz hiperbolikus szinusz x"), + ("arc-hyperbolic-cosine", "arkusz hiperbolikus koszinusz x"), + ("arc-hyperbolic-tangent", "arkusz hiperbolikus tangens x"), + ("arc-hyperbolic-secant", "arkusz hiperbolikus szekáns x"), + ("arc-hyperbolic-cosecant", "arkusz hiperbolikus koszekáns x"), + ("arc-hyperbolic-cotangent", "arkusz hiperbolikus kotangens x"), + ]; + + for (intent, expected) in tests { + let expr = format!( + " + + x + + ", + intent + ); + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} + +#[test] +fn statistics_and_probability_tests() -> Result<()> { + let tests = vec![ + ("mean", "jelentése x"), + ("standard-deviation", "szórás x"), + ("variance", "variencia x"), + ("median", "medián x"), + ("mode", "mód x"), + + // conditional probability typically two arguments + // ("conditional-probability", "probability of x given y"), + ]; + + for (intent, expected) in tests { + let expr = match intent { + "conditional-probability" => format!( + " + + P + ( + + x + | + y + + ) + + ", + intent + ), + _ => format!( + " + + x + + ", + intent + ), + }; + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} + +#[test] +fn linear_algebra_tests() -> Result<()> { + let tests = vec![ + ("vector", "vektor x"), + // ("matrix", "matrix of x"), + ("determinant", "determináns a x"), + ("adjugate", "adjugált x"), + ("magnitude", "nagyságrend x"), + ("norm", "normalizálás x"), + ("span", "fesztávolság x"), + + // transpose supports both postfix and function; we test function explicitly + ("transpose", "transzponált x"), + + // dimensional product is infix + ("dimensional-product", "x a(z) y"), + + // unit-vector is prefix + ("unit-vector", "egységvektor x") + ]; + + for (intent, expected) in tests { + let expr: String = match intent { + "dimensional-product" => { + " + + x + y + + " + .to_string() + } + _ => format!( + " + + x + + " + ), + }; + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} + +#[test] +fn nofix_set_tests() -> Result<()> { + let tests = vec![ + ("set-of-integers", "ℤ", "az összes egész szám halmaza"), + ("set-of-reals", "valós számok halmaza", "az összes valós szám halmaza"), + ("set-of-rationals", "ℚ", "az összes racionális szám halmaza"), + ("set-of-natural-numbers", "ℕ", "az összes természetes szám halmaza"), + ("set-of-complex-numbers", "ℂ", "az összes komplex szám halmaza"), + ("set-of-primes", "ℙ", "az összes prímszám halmaza"), + ]; + + for (intent, symbol, expected) in tests { + let expr = format!( + " + {} + ", + intent, + symbol + ); + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} + +#[test] +fn geometry_prefix_multi_value_tests() -> Result<()> { + let tests = vec![ + ("line-segment", "vonalszakasz x y"), + ("directed-line-segment", "irányított vonalszakasz x y"), + ("line", "vonal x y"), + ("ray", "sugár x y"), + ("arc", "ív x y"), + ("point", "pont x y z"), + ]; + + for (intent, expected) in tests { + let expr = match intent{ + "point" => { + format!( + " + + x + y + z + + " + ) + } + + _ => { + format!( + " + + x + y + + " + ) + } + }; + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} + +#[test] +fn geometry_prefix_tests() -> Result<()> { + let tests = vec![ + ("length", "hossz x"), + ("area", "terület x"), + ("volume", "hangerő x"), + ]; + + for (intent, expected) in tests { + let expr = format!( + " + + x + + " + ); + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} + +#[test] +fn separator_tests() -> Result<()> { + let expr = format!( + " + + x + y + + " + ); + + test("hu", "ClearSpeak", &expr, "x y")?; + Ok(()) +} + +#[test] +fn general_concepts_tests() -> Result<()> { + let tests = vec![ + // Unary structural + ("fenced-group", "bekerített csoport x"), + ("highlight", "x kiemelt"), + ("least-common-denominator", "legkisebb közös nevező x vessző, y vessző, z"), // add x, y , z ... + ("pochhammer", "permutáció x"), + ("permutation-cycle", "permutációs ciklus x"), + + // Binary structural / infix-style + // ("ordered-pair", "the pair of x and y"), + ("rate", "x per y"), + + ("binomial-coefficient", "x választ y"), + ("embellished-name", "x megjegyzéssel y"), + ("indexed-by", "x alsó index y"), + // ("translation", "translation by x comma, y"), // Changes translation to comma + ("constraint", "x feltétellel y"), + ]; + + for (intent, expected) in tests { + let expr = match intent { + "ordered-pair" + | "rate" + | "constraint" + | "binomial-coefficient" + | "embellished-name" + | "translation" + | "indexed-by" => { + format!( + " + + x + y + + ", + intent + ) + } + "least-common-denominator" => { + format!( + " + + x + y + z + + ", + intent + ) + } + + // unary cases + _ => { + format!( + " + + x + + ", + intent + ) + } + }; + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} + +#[test] +fn grouping_tests() -> Result<()> { + let tests = vec![ +("annotation", "x ami y"), + // ("braced-group", "grouped x end-grouped"), + // ("repeating-decimal", "repeating decimal of x"), + ]; + + for (intent, expected) in tests { + let expr = match intent { + "annotation" => { + format!( + " + + x + y + + ", + intent + ) + } + _ => { + format!( + " + + x + + ", + intent + ) + } + }; + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} + +#[test] +fn function_default_fixity_tests() -> Result<()> { + let tests = vec![ + ("curl", "rotáció x"), + ("divergence", "eltérés x"), + ("gradient", "gradiens x"), + ("laplacian", "laplaciánus x"), + ]; + + for (intent, expected) in tests { + let expr = format!( + " + + x + + ", + intent + ); + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} + +#[test] +fn prefix_default_fixity_tests() -> Result<()> { + let tests = vec![ + ("angle", "szög x"), + ("angle-measure", "szögmérés x"), + ("change", "változás x"), + ("for-all", "minden x"), + ("measured-angle", "mért szög x"), + ("not", "nem x"), + ("number-of", "száma x"), + ("partial-derivative", "parciális derivált x"), + ("right-angle", "derékszög x"), + ("square-root-of", "négyzetgyöke x"), + ("there-does-not-exist", "nem létezik x"), + ("there-exists", "létezik x"), + ]; + + for (intent, expected) in tests { + let expr = format!( + " + + x + + ", + intent + ); + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} + +#[test] +fn infix_default_fixity_tests() -> Result<()> { + let tests = vec![ + ("and", "x és y"), + ("applied-to", "x alkalmazva y"), + ("approximately", "x hozzávetőlegesen y"), + ("congruent", "x egybeesik y"), + ("cartesian-product", "x derékszögű szorzat y"), + ("composed-with", "x komponálva y"), + ("cross-product", "x kereszt szorzata y"), + ("defined-as", "x definiálva y"), + ("divided-by", "x osztva y"), + ("divides", "x osztja y"), + ("does-not-belong-to", "x nem tartozik hozzá y"), + ("does-not-divide", "x nem osztja y"), + ("dot-product", "x skaláris szorzat y"), + ("downwards-diagonal-ellipsis", "x lefelé mutató átlós ellipszis y"), + ("direct-product", "x direkt szorzat y"), + ("element-of", "x eleme y"), + ("ellipsis", "x ellipszis y"), + ("equals", "x egyenlő y"), + ("equivalent-to", "x egyenértékű ezzel y"), + ("evaluates-to", "x értéke y"), + ("given", "x adott y"), + ("greater-than", "x nagyobb, mint y"), + ("greater-than-or-equal-to", "x nagyobb vagy egyenlő, mint y"), + ("identically-equals", "x teljesen egyenlő y"), + ("if-and-only-if", "x akkor és csak akkor, ha y"), + ("implies", "x utal y"), + ("inner-product", "x belső szorzat y"), + ("intersection", "x keresztezi y"), + ("less-than", "x kisebb, mint y"), + ("less-than-or-equal-to", "x kisebb vagy egyenlő, mint y"), + ("list-separator", "x vessző y"), + ("maps-to", "x megfelel ennek y"), + ("member-of", "x tagja y"), + ("minus", "x mínusz y"), + ("minus-or-plus", "x mínusz vagy plusz y"), + ("not-subset", "x nem részhalmaza y"), + ("not-superset", "x nem szuperhalmaza y"), + ("not-equal-to", "x nem egyenlő y"), + ("not-member-of", "x nem tagja y"), + ("not-parallel-to", "x nem párhuzamos y"), + ("obtained-from", "x innen származik y"), + ("or", "x vagy y"), + ("outer-product", "x külső szorzata y"), + ("parallel-to", "x párhuzamos y"), + ("perpendicular", "x merőleges y"), + ("plus", "x plusz y"), + ("plus-or-minus", "x plusz vagy mínusz y"), + ("precedes", "x megelőzi y"), + ("proportional", "x arányos y"), + ("range-separator", "x keresztül y"), + ("ratio", "x arány y"), + ("similar", "x hasonló y"), + ("subset", "x részhalmaza y"), + ("subset-or-equal", "x részhalmaza vagy egyenlő y"), + ("succeeds", "x követi y"), + ("such-that", "x úgy, hogy y"), + ("superset", "x szuperhalmaza y"), + ("superset-or-equal", "x szuperhalmaza vagy egyenlő y"), + ("tilde", "x tilde y"), + ("times", "x szorozva y"), + ("union", "x unió y"), + ("upwards-diagonal-ellipsis", "x felfelé átlós ellipszis y"), + ("vertical-ellipsis", "x függőleges ellipszis y"), + ("xor", "x kizárólagos vagy y"), + ]; + + for (intent, expected) in tests { + let expr = format!( + " + + x + y + + ", + intent + ); + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} + +#[test] +fn postfix_default_fixity_tests() -> Result<()> { + let tests = vec![ + ("factorial", "x faktoriális"), + ("percent", "x százalék"), + ]; + + for (intent, expected) in tests { + let expr = format!( + " + + x + + ", + intent + ); + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} + +#[test] +fn nofix_default_fixity_tests() -> Result<()> { + let tests = vec![ + ("diameter", "átmérő", "átmérő"), + ("distance", "távolság", "távolság"), + ("probability", "valószínűség", "valószínűség"), + ("radius", "sugár", "sugár"), + ("volume", "hangerő", "hangerő"), + ("exponential-e", "e", "e"), + ("imaginary-i", "képzeletbeli én", "képzeletbeli én"), + ("differential-d", "d", "d"), + ("golden-ratio", "φ", "aranymetszés"), + ]; + + for (intent, symbol, expected) in tests { + let expr = format!( + " + {} + ", + intent, + symbol + ); + + test("hu", "ClearSpeak", &expr, expected)?; + } + + Ok(()) +} diff --git a/tests/Languages/hu/shared.rs b/tests/Languages/hu/shared.rs index a97805f8a..bd53bb4c3 100644 --- a/tests/Languages/hu/shared.rs +++ b/tests/Languages/hu/shared.rs @@ -381,7 +381,7 @@ fn bug_199_2pi() -> Result<()> { ) "; - test("hu", "SimpleSpeak",expr, "0 től 2 pí ig terjedő intervallum, tartalmazza a 0 elemet de nem tartalmazza a 2 pí elemet")?; + test("hu", "SimpleSpeak",expr, "0 től 2 pí ig terjedő intervallum, tartalmazza a(z) 0 elemet de nem tartalmazza a(z) 2 pí elemet")?; return Ok(()); } From 7fbaf1729eadac816de837af931e799f1dceb6c9 Mon Sep 17 00:00:00 2001 From: NSoiffer Date: Sat, 15 Aug 2026 01:17:17 -0700 Subject: [PATCH 029/157] Ru -- merge speech changes into main (#689) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Ru - Improve wording of Russian docs (#661) * update acknowledgment for Russian braille * update version number because added Russian braille * UEB has a rule for some pseudo-script chars. The match for that rule was overly broad, so I removed scripted letters and numbers. That rule made its way into other braille codes, so I removed them everywhere. All tests pass. * Added new UEB chars. Many of these are accented letters. I added 'A' (for accented letters) so that the pattern for them looks like: ``` - "Ñ": [t: "CA⠘⠻L⠝"] # 0x00D1 ``` Added a few tests. * Translate German absolute-value ending * Fix German unit plurals * Fix German pluralization for "ruthe" and add regression test * Correct German translations for "ruthe" to "rute" and update regression test * Expand German unit definitions and add regression test for pluralization * fix some symbols * fix german set grammar * typo in example * Russian Braille fixes This commit adds fixes to Russian Braille. Now the test with parentheses is passed. Also there are devision and multiplication signs have been modified according to the Russian braille specs. * Update Russian Braille rules and mappings Fix YAML replace syntax and extend Russian braille rules: add chemical-formula-operator-bond and prefix-geometry-ops rules, broaden function-name matching (include tg/ctg variants) and add separator markers. Update unicode mappings (degree sign, invisible characters, conditional ∪ mapping, parallel/arrow glyphs) and adjust several function/operator braille outputs. Add/expand tests to cover functions, geometry, matrices and chemical formulas to validate the changes. * Add Russian language to docs Add Russian (ru) to the list of supported speech languages and update Russian documentation and translation guidance. - docs/User_guide_for_MathCAT_en.md, docs/index.md: add Russian (ru) to supported languages lists. - docs/ru/User_guide_for_MathCAT_ru.md: include Russian in language options, reorder entries and apply minor wording fixes. - docs/ru/helpers.md: clarify wording, update examples and test instructions to reference ru instead of fr, and improve translation guidance and examples (including test and cargo commands). - docs/ru/index.md: reorder supported languages and polish phrasing. These edits enable and document Russian support and improve clarity for translators and developers working on the Russian localization. * Refactor Russian function braille mapping Replace hardcoded function-name branches in Russian_Rules.yaml with a DefinitionValue lookup that pulls from a new RussianFunctionBraille mapping. Add RussianFunctionBraille entries to definitions.yaml (private-use codepoints U+E100–U+E10E) and map those codepoints to braille strings in unicode.yaml. Add a test covering tan/cot rendering. This centralizes function braille representations and simplifies the rule logic. * Addition of Russian documentation This commit adds Russian documentation for users, developers and translators. * typo in example * Add vector/bar/arc mover rules and tests Introduce three new mover rules in Rules/Braille/Russian/Russian_Rules.yaml: vector-arrow, vector-bar, and geometry-arc. Each rule detects specific accent characters (arrows: → ⟶ ⇀ ⃗; bars: ¯ ‾ _  ̄; arcs: ⌒ ⏜ ︵) and emits the appropriate braille indicators, using a different form when the base has more than one character. Add corresponding tests in tests/braille/Russian/russian.rs to cover single- and multi-character movers and combined expressions. * Add Russian braille math functions and limits Extend Russian braille rules to support additional math functions and large operator limits. Added new rules for large-op-limits, operator/functions (including special handling for div), and div-specific replacements in Rules/Braille/Russian/*. Updated Russian definitions and unicode mappings to include sinh/cosh/tanh/coth, arg/sgn/det/rank/rg, Re/Im, grad/rot/div, gcd/lcm and related braille codes. Updated global Rules/definitions.yaml to recognize new function names. Fixed braille cleanup in src/braille.rs to normalize div encoding. Added unit tests exercising the new function mappings and large operator limits. * Support system left brace in Russian braille Introduce handling for system left-brace matrices in the Russian braille rules: add InSystemLeftBrace variable, a system-left-brace-opener rule and a system-left-brace-table rule to detect brace-enclosed mtable as a system. Update row-start logic to emit appropriate braille tokens when InSystemLeftBrace is set. Add tests exercising curly-brace matrices, piecewise function (brace with conditions), and vertical-bar matrices to verify the new behavior. * Add signed-integer and nested-fraction rules Add handling for nested fractions and signed integers inside script positions and adjust grouping behavior for scripts in Russian braille rules. Changes introduce a nested-fraction rule for mfrac and new signed-integer-number / signed-integer rules for msub/munder and msup/mover, plus a small grouping test (⠐) when scripts contain grouped mrow with '+' or a fraction. Also add a comprehensive regression test (script_grouping_regressions) covering many sup/sub cases to ensure correct braille output. Files updated: Rules/Braille/Russian/Russian_Rules.yaml and tests/braille/Russian/russian.rs. * Enhance Russian Braille support with mathematical symbols and rules (#589) * Refine matrix rule handling by adding support for augmented matrices; update unit tests to include 2x3 and 3x4 augmented matrix scenarios. (#555) * remove logging statement * removed uneeded eprintlin!() * Alternative fix to PR #540. Fixes #528. Includes the tests in the PR. * Add Russian translation * Fix #585 -- SSML was being escaped. I earlier added code to prevent a SSML injection attack by escaping HTML. It was done at the wrong point and escape legal SSML. I have moved the check and conversion down to the leaves. I was very surprised there were no useful tests with SSML. All the main tests set `TTS=None`. I added a test that catches bad escaping. I also added some tests to check for leaf-based SSML attacks and also attribute-based ones. * bump beta number * The range for MATHEMATICAL SANS-SERIF DIGITs had MATHEMATICAL MONOSPACE DIGITs as the match part of translate, so if one of the sans-serif digits were used, you ended up in a loop (no match, to it returned itself). * comment out some debug statements * Add 02DA (˚) to list of circle-like chars -- I thought I had done this already, so it might in some other branch * Add source language option to translation audit tool Allow audit-translations to compare a target language against any source language via --source, defaulting to English for existing workflows. Update CLI output, docs, and tests for dynamic source/target labels, including Swedish/Norwegian comparison coverage. Normalize Rich ANSI output in tests so golden and string assertions remain stable when terminal color is forced. * fix ruff * fix ruff * fix ruff * Core concept names additions and tests -- issue 381 (#592) * initial addition of core concept names * defnitions and tests, with a few failing * minus, plus, volume fixes. Other defined, not appearing in site * fix clippy warnings * use "ruamel.yaml>=0.19.1" in uv.lock and pyproject.toml * handle canonicalize failure in containerized environments (#574) * add 1 week dependency cooldown for uv (#599) * fix rules for digits in german (#596) * update navigation rules for traditional chinese (#588) * copy english version of navigate.yaml from NVDA2026.1 and translate * 更新 definitions.yaml 與 navigate.yaml * update unicode-full.yaml * 區分完全/已完全放大/縮小 * 移至->移到, 表->表格, 數學式->數學, 退出->離開, 不能->無法, 當前->目前。 overview line 47, SimpleSpeak_Rules.yaml line 39, "根號"->""。mroot.rs 對應修改 * 移到上一格 -> 往上一格,移到下一格 -> 往下一格, 佔位符 -> 書籤,設定佔位符 -> 設定書籤,已是最上層 -> 不在別的式子裡面,上一層是 -> 在後面式子裡面,字元模式 開n 次方根 的讀法,基底 -> 基、底 * 向量 -> 射線 * 基 -> 基底,底 -> 基底 * Internally in definitions.yaml, MathCAT uses "nofix", but that's not a MathML airity property. Remove it. * don't say "indexed by", say "sub" * add some terse and verbose forms of speech * fix typo * Added an html file with all the test exprs so that translators have examples to test. * Fix remaining erros after `definitions.yaml` was updated -- needed to add `function:` * fix clippy warning * minor cleanup: remove ASCIIMath-fi reference * Refactor braille.rs to a BrailleCode trait + registry Replace the four scattered string-match dispatch sites (cleanup, get_braille_chars, NeedsToBeGrouped, and highlight knobs) with a single get_braille_code() registry and a BrailleCode trait implemented per code. Extract the duplicated UEB/Vietnam/Finnish/Swedish indicator-replacement closures into one apply_indicator_replacements helper plus a UserTypeforms struct. Behavior is unchanged (all tests/braille pass); adding a new code now means one registry entry + one impl block. Co-authored-by: Cursor * improved counting for (likey) 8 bit codes when figuring out braille position * make sure this is part of repo * add BrailleDocs to repo (stop ignoring) * updated data, does not include ASCII letters/digits * First version of Russian Braille This commit adds first druft version for Russian Braille. * typo in example * Russian Braille fixes This commit adds fixes to Russian Braille. Now the test with parentheses is passed. Also there are devision and multiplication signs have been modified according to the Russian braille specs. * Braille - Latin and Greek letters fixes This commit adds a layer of Latin and Greek alphabets for Russian mathematical Braille. * In unicode.yaml Latin and Greek letters now go through the internal markers of the alphabetic mode. • In braille.rs russian_cleanup turns these markers into real signs: ◦ Latin lowercase: ⠠ ◦ Latin uppercase: ⠨ ◦ Greek lowercase: ⠰ ◦ Greek uppercase: ⠸ Added tests to russian.rs to x+A+y+B, the Latin letter after the number. * Braille - Roots, powers and scripts This commit adds Roots, powers and scripts according to the Russian math Braille specs. * Update Russian Braille rules and mappings Fix YAML replace syntax and extend Russian braille rules: add chemical-formula-operator-bond and prefix-geometry-ops rules, broaden function-name matching (include tg/ctg variants) and add separator markers. Update unicode mappings (degree sign, invisible characters, conditional ∪ mapping, parallel/arrow glyphs) and adjust several function/operator braille outputs. Add/expand tests to cover functions, geometry, matrices and chemical formulas to validate the changes. * Add Russian language to docs Add Russian (ru) to the list of supported speech languages and update Russian documentation and translation guidance. - docs/User_guide_for_MathCAT_en.md, docs/index.md: add Russian (ru) to supported languages lists. - docs/ru/User_guide_for_MathCAT_ru.md: include Russian in language options, reorder entries and apply minor wording fixes. - docs/ru/helpers.md: clarify wording, update examples and test instructions to reference ru instead of fr, and improve translation guidance and examples (including test and cargo commands). - docs/ru/index.md: reorder supported languages and polish phrasing. These edits enable and document Russian support and improve clarity for translators and developers working on the Russian localization. * Refactor Russian function braille mapping Replace hardcoded function-name branches in Russian_Rules.yaml with a DefinitionValue lookup that pulls from a new RussianFunctionBraille mapping. Add RussianFunctionBraille entries to definitions.yaml (private-use codepoints U+E100–U+E10E) and map those codepoints to braille strings in unicode.yaml. Add a test covering tan/cot rendering. This centralizes function braille representations and simplifies the rule logic. * Refine Russian wording in translators guide Clarify and naturalize Russian phrasing in the translators guide: add explicit "на русском языке" to SimpleSpeak examples; change exponent wording to "в квадрате" with example "икс в квадрате"; make fraction wording more natural ("числитель разделить на знаменатель" and example "метр за секунду"); fix "английском" → "английском языке"; and update Braille tooling phrasing to "просмотрщиком Брайля" and "дисплее Брайля" for consistency. * Add alphabet indicators in russian_cleanup Insert a preprocessing step that injects braille alphabet indicators before running REPLACE_INDICATORS. A new helper add_russian_alphabet_indicators scans the raw braille and emits specific indicators for 'l' (Latin lowercase), 'u' (Latin uppercase), 'g' (Greek lowercase) and 'v' (Greek uppercase), avoiding repeated indicators by tracking the current alphabet mode. The helper also resets the mode on 'C', 'N', and '#'. This keeps the existing indicator replacement and space-collapsing logic intact while preventing redundant alphabet indicators. * Russian braille: add GOST symbols and decimals Add GOST-style number and symbol support for Russian braille: introduce a decimal-comma rule that emits BrailleChars for integer and fractional parts with a decimal indicator, using PUA digit placeholders. Extend unicode mappings with bracket/brace/slash/backslash/pipe characters, Celsius, context-sensitive prime (′/″) handling, PUA digit-to-braille mappings, and a few arrow/connective symbols. Update tests to cover decimal numbers, fractions, set notation, Celsius, and logical arrows, and adjust expected output for geometry primes to reflect the new context-aware prime handling. * Add vector/bar/arc mover rules and tests Introduce three new mover rules in Rules/Braille/Russian/Russian_Rules.yaml: vector-arrow, vector-bar, and geometry-arc. Each rule detects specific accent characters (arrows: → ⟶ ⇀ ⃗; bars: ¯ ‾ _  ̄; arcs: ⌒ ⏜ ︵) and emits the appropriate braille indicators, using a different form when the base has more than one character. Add corresponding tests in tests/braille/Russian/russian.rs to cover single- and multi-character movers and combined expressions. * Add Russian braille math functions and limits Extend Russian braille rules to support additional math functions and large operator limits. Added new rules for large-op-limits, operator/functions (including special handling for div), and div-specific replacements in Rules/Braille/Russian/*. Updated Russian definitions and unicode mappings to include sinh/cosh/tanh/coth, arg/sgn/det/rank/rg, Re/Im, grad/rot/div, gcd/lcm and related braille codes. Updated global Rules/definitions.yaml to recognize new function names. Fixed braille cleanup in src/braille.rs to normalize div encoding. Added unit tests exercising the new function mappings and large operator limits. * Support system left brace in Russian braille Introduce handling for system left-brace matrices in the Russian braille rules: add InSystemLeftBrace variable, a system-left-brace-opener rule and a system-left-brace-table rule to detect brace-enclosed mtable as a system. Update row-start logic to emit appropriate braille tokens when InSystemLeftBrace is set. Add tests exercising curly-brace matrices, piecewise function (brace with conditions), and vertical-bar matrices to verify the new behavior. * Add Russian chemistry braille rules and tests Extend Russian braille rules to handle chemical notation: add rules for equilibrium-arrow, reaction operators, repeated charges, charges, and charge-with-subscript mappings (chemical-reaction-operator, chemistry-mhchem-equilibrium-arrow, chemistry-repeated-charge, chemistry-charge, chemistry-charge-with-subscript). Update Rules/Braille/Russian/Russian_Rules.yaml to map arrows, +/-, superscripts/subscripts and reaction operators to appropriate braille sequences. Add tests in tests/braille/Russian/russian.rs (source_chemical_reactions_and_charges) covering reaction arrows, charges, subscripts/superscripts and combined examples. --------- Co-authored-by: Moritz Groß Co-authored-by: nsoiffer Co-authored-by: Tuomas Pyorre <82783219+ttpyorre@users.noreply.github.com> Co-authored-by: V3nky Co-authored-by: Hon-Jang Yang Co-authored-by: nsoiffer Co-authored-by: Cursor * Add Russian braille rules for geometry operators Add three new braille encoding rules for geometry operators (∠, △, ∪) in Russian: - canonical-prefix-geometry-op: handles geometry operators in canonical form - geometry-prefix-after-canonical-multiplier: handles operators after canonical multipliers - geometry-prefix-after-multiplier: handles operators after regular multipliers Includes corresponding test cases for angles, triangles, unions, perpendicular, and similar symbols. * Improve Russian braille typeform and mathvariant handling Refactor Russian braille cleanup to properly handle typeform indicators (bold, italic) and mathvariant attributes. Introduces a dedicated typeform indicator function that manages indicator placement according to Russian Braille ГОСТ Р 58511 standard, separating typeform handling from alphabet indicators. Adds support for automatic typeform indicators based on mathvariant attributes, ensuring proper indicator pairing around content blocks. Updates unicode-full.yaml rules to reflect new typeform codes and adds comprehensive tests for various mathvariant combinations. * Propagate mathvariant attribute to children Add mathvariant inheritance from parent elements to children that lack their own mathvariant attribute. This ensures consistent styling throughout nested elements. Includes tests for bold text propagation through mstyle and mrow containers, and verifies that explicit child mathvariants override inherited values. * Fix clippy warnings and improve code style - Remove unnecessary borrows in format! and display calls - Change string slices to arrays in trim_end_matches calls - Replace expect(&format!(...)) with unwrap_or_else(|_| panic!(...)) - Add clippy allow attributes to suppress false positives in tests - Add missing newline at end of build.rs * Remove unnecessary borrows in format macros Remove redundant `&` reference operators from arguments passed to format! macros and similar functions. These values are automatically borrowed by the format machinery, so explicit borrows are unnecessary and reduce readability. * Normalize Unicode math digits in decimal numbers Add normalization of Unicode mathematical alphanumeric symbols (Plane 1 digits) to ASCII digits for number nodes containing decimal points. Skip canonicalize_plane1 processing for already-normalized nodes to prevent double processing. * Remove unnecessary references and .to_string() calls Remove unnecessary `&` borrows in format arguments and replace `.to_string()` with direct display. Simplify byte array literals to byte string literals for readability and idiomatic Rust style. * Remove mathvariant propagation and update tests Drop implicit propagation of the mathvariant attribute from canonicalization (removed propagate_inherited_mathvariant call and helper functions) and update Russian braille tests to set mathvariant explicitly on elements (replace mstyle with mrow and move attributes to mi). Changes in src/canonicalize.rs and tests/braille/Russian/russian.rs. This makes mathvariant handling explicit in tests and avoids mutating child nodes during canonicalization. * Remove math digit normalization for mn nodes Delete the conditional normalization of mathematical digit characters for text and remove the normalize_math_digits helper from src/canonicalize.rs. Previously the code converted several Unicode math-digit codepoints to ASCII when a decimal point was present. * Adjust test expectations and unignore tests Update expected spoken/braille test outputs across multiple language test files to match updated speech rules (punctuation handling, table phrasing, and unit/roman-numeral rendering). Removed several #[ignore] annotations for the previously skipped "ignore_period_and_space" tests. Minor tidy in pl/definitions.rs to avoid unnecessary format! usage and fix EOF newline. Affected files include tests/Languages/* for en, fi, fr, hu, nb, pl, sv, vi, and zh/tw. * Bump to 0.7.6-beta.8 and update dependencies Update to version 0.7.6-beta.8 with the following changes: - Migrate to no-unsafe variants of sxd-document and sxd-xpath - Add 'no-unsafe' feature flag for unsafe-free builds - Update dependencies: strum, regex, bitflags, env_logger - Add tempfile dev-dependency - Improve build.rs: add rerun-if-changed directives earlier and fix indentation - Exclude BrailleDocs from package * Switch to sxd_document_no_unsafe and NameStr Replace sxd_document/sxd_xpath usages with no-unsafe variants and adapt string types. Key changes in src/braille.rs, src/canonicalize.rs, and src/chemistry.rs: introduce NameStr (feature-gated), use as_str!/as_qname! helpers, convert many attribute_value calls to .as_deref(), update XPath error constructions, and store operator chars as NameStr with PhantomData in OperatorPair. Refactor chemistry tests to helper-based Result flow and use sxd_document_no_unsafe::parser. These edits make the code compatible with the "no-unsafe" pathway and fix lifetime/string mismatches across the codebase. * Use no-unsafe sxd crates; adapt code & tests Replace sxd_document/sxd_xpath with sxd_document_no_unsafe and sxd_xpath_no_unsafe and update imports (including parser). Adjust attribute handling and lifetimes: use as_str!, attribute_value(...).as_deref().unwrap_or_default(), and similar changes to avoid unsafe string lifetimes. Refactor tests to return Result, use ? and panic-catching, and update assertions (e.g. is_empty). Re-enable sample MathML in main, tweak timing_test (disable heavy loops, change loop count). Misc small fixes to satisfy the new APIs and lifetime semantics. * Use no-unsafe sxd libs; refactor TTS & parsing Switch project XML/XPath handling to sxd_document_no_unsafe / sxd_xpath_no_unsafe and adapt code to use as_str!/as_qname! helpers. Update speech and pretty-print logic to use the new context and node APIs, tighten unicode handling, and add debug checks. Refactor TTS APIs so command value accessors return Result and TTS string builders propagate errors. Update tests and prefs helpers (temporary rules dir helper, prefs test flow). Misc: small capacity tweaks and wording fixes in error messages. Files changed: src/prefs.rs, src/pretty_print.rs, src/speech.rs, src/tts.rs. * Improve wording in RU user guide Replace "Трудности в обучении" with "Когнитивные нарушения" in docs/ru/User_guide_for_MathCAT_ru.md to use a more precise and respectful term for users who need shorter spoken output. * Add Russian GOST-58511 typeform braille rules and tests Introduce three Russian GOST-58511 typeform/layout braille rules (small-font, letter-spacing, insertion) to Rules/Braille/Russian/Russian_Rules.yaml with their corresponding braille markers. Expand and reorganize tests in tests/braille/Russian/russian.rs: add coverage for the new typeform indicators, interaction cases, menclose/table/braces, and other edge cases; rename several tests to reflect sectioned/aggregated variants. Also adjust expected braille outputs for a few existing tests (sqrt and geometry matrix cases) to match the new rules/formatting. --------- Co-authored-by: nsoiffer Co-authored-by: mgros Co-authored-by: Tuomas Pyorre <82783219+ttpyorre@users.noreply.github.com> Co-authored-by: V3nky Co-authored-by: Hon-Jang Yang Co-authored-by: nsoiffer Co-authored-by: Cursor * force bring over the files from main -- merging didn't do the right thing * Ru - handle lone log/ln; suppress nav announcements (#681) * ru: handle lone log/ln; suppress nav announcements Add handling for lone mi elements 'log' and 'ln' in ClearSpeak (supports Verbosity and ClearSpeak_Log LnAsNaturalLog option). Add a navigation rule to avoid announcing "in/out of" for prefix or silent intents that have no NavigationParts. Include unit tests: new ClearSpeak tests for individual log/ln, new navigate tests for suppressed base announcements, and register the navigate test module. * Russian braille: bracket/arrow mappings & tests Add contextual bracket-recognition rules (square and angle) to Rules/Braille/Russian/Russian_Rules.yaml and add Unicode braille mappings for ≶, ≷, ⟨, ⟩, ↑, ↓ in Rules/Braille/Russian/unicode.yaml. Extend tests in tests/braille/Russian/russian.rs to cover Russian Braille GOST 2019 order relations, large vertical arrows, and contextual bracket recognition for square and angle brackets, validating the expected braille output. --------- Co-authored-by: Danil <81031453+Kostenkov-2021@users.noreply.github.com> Co-authored-by: mgros Co-authored-by: Tuomas Pyorre <82783219+ttpyorre@users.noreply.github.com> Co-authored-by: V3nky Co-authored-by: Hon-Jang Yang Co-authored-by: nsoiffer Co-authored-by: Cursor --- Rules/Braille/Russian/Russian_Rules.yaml | 26 +++ Rules/Braille/Russian/unicode.yaml | 6 + Rules/Braille/UEB/unicode-full.yaml | 35 ++- Rules/Languages/de/unicode-full.yaml | 225 ++++++++++++++++++++ Rules/Languages/en/SharedRules/default.yaml | 29 +-- Rules/Languages/en/unicode-full.yaml | 185 +++++++++++++++- Rules/Languages/ru/ClearSpeak_Rules.yaml | 18 ++ Rules/Languages/ru/navigate.yaml | 9 + Rules/Languages/zh/tw/unicode-full.yaml | 1 + build.rs | 8 +- tests/Languages/en/mtable.rs | 8 +- tests/Languages/en/shared.rs | 11 +- tests/Languages/fi/shared.rs | 3 +- tests/Languages/fr/shared.rs | 3 +- tests/Languages/hu/shared.rs | 3 +- tests/Languages/nb/shared.rs | 3 +- tests/Languages/pl/definitions.rs | 8 +- tests/Languages/pl/shared.rs | 3 +- tests/Languages/ru.rs | 3 +- tests/Languages/ru/ClearSpeak/functions.rs | 16 ++ tests/Languages/ru/navigate.rs | 56 +++++ tests/Languages/sv/shared.rs | 3 +- tests/Languages/vi/vi.rs | 8 +- tests/Languages/zh/tw/shared.rs | 3 +- tests/braille/Russian/russian.rs | 29 +++ 25 files changed, 615 insertions(+), 87 deletions(-) create mode 100644 tests/Languages/ru/navigate.rs diff --git a/Rules/Braille/Russian/Russian_Rules.yaml b/Rules/Braille/Russian/Russian_Rules.yaml index ee9004aed..1bf1603c9 100644 --- a/Rules/Braille/Russian/Russian_Rules.yaml +++ b/Rules/Braille/Russian/Russian_Rules.yaml @@ -1555,6 +1555,32 @@ replace: - x: "DefinitionValue(., 'Braille', 'RussianFunctionBraille')" +- + name: contextual-square-bracket-recognition-point + tag: mo + match: + - "parent::*[IsBracketed(., '[', ']')] and" + - "((.='[' and not(preceding-sibling::*) and following-sibling::*[1][self::m:mi or self::m:mtext]) or" + - " (.=']' and not(following-sibling::*) and preceding-sibling::*[1][self::m:mi or self::m:mtext]))" + replace: + - T: "⠠" + - x: "text()" + +- + name: contextual-angle-bracket-recognition-point + tag: mo + match: + - "parent::*[IsBracketed(., '⟨', '⟩')] and" + - "((.='⟨' and not(preceding-sibling::*)) or (.='⟩' and not(following-sibling::*))) and" + - "(parent::*/*[2][self::m:mi or self::m:mtext] or" + - " parent::*/*[last()-1][self::m:mi or self::m:mtext])" + replace: + - T: "⠈" + - test: + - if: ".='⟨'" + then: [T: "⠪"] + else: [T: "⠕"] + - name: div-operator-function tag: mo diff --git a/Rules/Braille/Russian/unicode.yaml b/Rules/Braille/Russian/unicode.yaml index 6b08895b9..4fc43ea9d 100644 --- a/Rules/Braille/Russian/unicode.yaml +++ b/Rules/Braille/Russian/unicode.yaml @@ -214,6 +214,8 @@ - "≢": [t: "⠀⠰⠾"] - "≤": [t: "⠀⠪⠶"] - "≥": [t: "⠀⠕⠶"] +- "≶": [T: "⠀⠪⠕⠀"] +- "≷": [T: "⠀⠕⠪⠀"] - "≪": [t: "⠀⠪⠪⠀"] - "≫": [t: "⠀⠕⠕⠀"] - "≺": [t: "⠀⠒⠪⠀"] @@ -238,6 +240,10 @@ - "⋰": [t: "⠠⠲⠲⠲"] - "⋱": [t: "⠠⠲⠲⠲"] - "△": [t: "⠸⠙"] +- "⟨": [T: "⠪"] +- "⟩": [T: "⠕"] +- "↑": [T: "⠰⠌"] +- "↓": [T: "⠘⠡"] - "→": [t: "⠀⠒⠕"] - "⟶": [t: "⠀⠒⠕"] - "←": [t: "⠀⠦⠶"] diff --git a/Rules/Braille/UEB/unicode-full.yaml b/Rules/Braille/UEB/unicode-full.yaml index 9114b4de6..277eb9f4a 100644 --- a/Rules/Braille/UEB/unicode-full.yaml +++ b/Rules/Braille/UEB/unicode-full.yaml @@ -1,24 +1,6 @@ --- - - - " ": [t: "W"] # 0x2000 - - " ": [t: "W"] # 0x2001 - - " ": [t: "W"] # 0x2002 - - " ": [t: "W"] # 0x2003 - - " ": [t: "W"] # 0x2004 - - " ": [t: "W"] # 0x2005 - - " ": [t: "W"] # 0x2006 - - " ": [t: "W"] # 0x2007 - - " ": [t: "W"] # 0x2008 - - " ": [t: "W"] # 0x2009 - - " ": [t: "W"] # 0x200a - - "​": [t: "W"] # 0x200b - - "
": [t: "W"] # 0x2028 - - "
": [t: "W"] # 0x2029 - - " ": [t: "W"] # 0x202f - - " ": [t: "W"] # 0x205f - - "": [t: "W"] # 0xfeff - - + - "⋇": [tc: "1⠌⠯⠦"] # 0x22C7 (Division times) + - "⊩": [tc: "⠸⠳⠿⠸⠒"] # 0x22A9 (Forces) - "ℏ": [tc: "⠈⠒⠓"] # t: "B"F (reduced Plank's constant) - "ⅆ": [tc: "⠙"] # 0x2146 - "ⅇ": [tc: "⠑"] # 0x2147 @@ -189,6 +171,7 @@ - spell: "translate('.', '₊₋₌₍₎', '⠖⠤⠶⠣⠜')" - "™": [t: "⠘⠞"] # 0x2122 + - "ℊ": [tc: "TL⠛⠁"] # 0x210a (Script Small G) - "ℋ": [tc: "TCL⠓⠁"] # 0x210b (Script Capital H) - "ℒ": [tc: "TCL⠇"] # 0x2113 (Script Capital L) @@ -215,6 +198,16 @@ - "ℤ": [tc: "𝔹CL⠵"] # 0x2124 + - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 + - tc: "B" + - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + + - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da + - tc: "BGL" + - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝔄-𝔜": # 0x1d504 - 0x1d51d ('z' version is reserved) - tc: "DC" - spell: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'abcdefghijklmnopqrstuvwxyz')" @@ -248,7 +241,7 @@ # script chars in math alphabetic block and also MathType private use area - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 - tc: "TsC" - - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'abcdefghijklmnopqrstuvwxyz')" + - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'abcdefghijklmnopqrstuvwxyza')" - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf - tc: "Ts" diff --git a/Rules/Languages/de/unicode-full.yaml b/Rules/Languages/de/unicode-full.yaml index 03b3157a6..8a98107f8 100644 --- a/Rules/Languages/de/unicode-full.yaml +++ b/Rules/Languages/de/unicode-full.yaml @@ -10,6 +10,7 @@ - "¨": [T: "diaeresis"] # 0xa8 (en: 'double dot') - "©": [T: "Urheberrecht"] # 0xa9 (en: 'copyright') - "ª": [T: "weibliches Ordnungszeichen"] # 0xaa (en: 'feminine ordinal indicator') + - "¬": [T: "nicht"] # 0xac (en: 'not') - "«": [T: "Nach links zeigendes doppeltes spitzes Anführungszeichen"] # 0xab (en: 'left-pointing double angle quote mark', MathPlayer: 'left-pointing double angle quote mark', google: 'links zeigende doppelwinkel-zitatmarke') - "¯": # 0xaf - test: @@ -18,9 +19,24 @@ else: [T: "Überstrich"] # (en: 'line', MathPlayer: 'macron', google: 'linie') - "²": [T: "Quadrat"] # 0xb2 (en: 'two', MathPlayer: 'zum Quadrat', google: 'zwei') - "³": [T: "Kubik"] # 0xb3 (en: 'three', MathPlayer: 'hoch drei', google: 'drei') + - "´": [T: "Akutakzent"] # 0xb4 (en: 'acute', MathPlayer: 'acute accent', google: 'akut') - "µ": [T: "Mikrozeichen"] # 0xb5 (en: 'micro', MathPlayer: 'micro sign', google: 'mikro') - "¹": [T: "hoch eins"] # 0xb9 (en: 'one', google: 'eins') - "º": [T: "Männliches Ordnungszeichen"] # 0xb9 (en: 'masculine ordinal indicator') + - "·": + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolDot = 'Auto'" + then: [T: "mal"] # (en: 'times', google translation) + else: [T: "mal"] # (en: 'dot', MathPlayer: 'Punkt mittig', google: 'punkt') + - "×": # 0xd7 + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolX = 'Auto'" + then: [T: "mal"] # (en: 'times', google translation) + else_test: + if: $ClearSpeak_MultSymbolX = 'By' + then: [T: "von"] # (en: 'by', google translation) + else: [T: "mal"] # (en: 'cross', MathPlayer: 'times', google: 'kreuzen') + - "÷": [T: "geteilt durch"] # 0xf7 (en: 'divided by', MathPlayer: 'divides') - "¡": [T: "umgekehrtes ausrufezeichen"] # 0xa1 (en: 'inverted exclamation mark') - "¶": [T: "absatzzeichen"] # 0xb6 (en: 'paragraph mark') - "¿": [T: "umgekehrtes fragezeichen"] # 0xbf (en: 'inverted question mark') @@ -108,6 +124,14 @@ - "˽": [T: "modifikatorregal"] # 0x2fd (en: 'modifier shelf', google translation) - "˾": [T: "modifikator offenes regal"] # 0x2fe (en: 'modifier open shelf', google translation) - "˿": [T: "modifikator niedriger links pfeil"] # 0x2ff (en: 'modifier low left arrow', google translation) + - "̀": [T: "gravisakzentverzierung"] # 0x300 (en: 'grave accent embellishment', google: 'grabakzentverzierung') + - "́": [T: "akutakzentverzierung"] # 0x301 (en: 'acute accent embellishment', google: 'akute akzentverzierung') + - "̂": [T: "Hutverzierung"] # 0x302 (en: 'circumflex accent embellishment', google: 'zirma akzentverzierung') + - "̃": [T: "tildeverzierung"] # 0x303 (google: 'tilde verzierung') + - "̄": [T: "makronverzierung"] # 0x304 (en: 'macron embellishment', google: 'makron -verzierung') + - "̅": [T: "Überstreifenverzierung"] # 0x305 (google: 'überbärerverzierung') + - "̆": [T: "kombinierendes Breve"] # 0x306 (en: 'breve embellishment', google: 'breve -verzierung') + - "̇": [T: "Punkt über Verzierung"] # 0x307 (google: 'punkt über verzierung') - "̈": [T: "zwei Punkte oberhalb"] # 0x308 (en: 'diaeresis embellishment', google: 'diaeresis -verzierung') - "̉": [T: "haken über verzierung"] # 0x309 (en: 'hook above embellishment', google translation) - "̊": [T: "ring über verzierung"] # 0x30a (en: 'ring above embellishment', google: 'ring über verzierung') @@ -197,9 +221,13 @@ - "ϒ": [T: "Variante Upsilon mit Haken"] # 0x3d2 (en: 'upsilon with hook', google: 'upsilon mit haken') - "ϓ": [T: "Upsilon mit Akutakzent und Haken"] # 0x3d3 (en: 'upsilon with acute and hook', google translation) - "ϔ": [T: "Upsilon mit Diaeresis und Haken"] # 0x3d4 (en: 'upsilon with diaeresis and hook', google translation) + - "ϕ": [T: "gerades Phi"] # 0x3d5 (en: 'phi', google: 'phi') + - "ϖ": [T: "Variante Pi"] # 0x3d6 (en: 'pi', google: 'pi') - "ϗ": [T: "kai"] # 0x3d7 (MathPlayer: 'variant kai') - "Ϙ": [T: "großes archaisches koppa"] # 0x3d8 (en: 'cap archaic koppa') - "ϙ": [T: "archaisches koppa"] # 0x3d9 (en: 'archaic koppa') + - "ϵ": [T: "epsilon"] # 0x3f5 + - "϶": [T: "umgekehrtes epsilon"] # 0x3f6 (en: 'reversed epsilon', MathPlayer: 'reversed epsilon', google: 'umgekehrter epsilon') - "А-Я": # 0x410 - 0x42f - test: if: "$CapitalLetters_Beep" @@ -256,6 +284,10 @@ - "‐": [T: "Bindestrich"] # 0x2010 (en: 'hyphen', MathPlayer: 'minus', google: 'bindestrich') - "‑": [T: "nicht-trennender Bindestrich"] # 0x2011 (en: 'hyphen', google: 'bindestrich') - "‒": [T: "Figurenstrich"] # 0x2012 (en: 'figure dash', google: 'figur dash') + - "–": [T: "Halbgeviertstrich"] # 0x2013 (SRE: 'En Dash') + - "—": [T: "Geviertstrich"] # 0x2014 (SRE: 'EM Dash') + - "―": [T: "Horizontale Linie"] # 0x2015 (en: 'horizontal bar', MathPlayer: 'horizontal bar', google: 'horizontale linie') + - "‖": [T: "Doppelte vertikale Linie"] # 0x2016 (en: 'double vertical line', MathPlayer: 'double vertical bar', google: 'doppelte vertikale linie') - "†": [T: "Dolch"] # 0x2020 (en: 'dagger', MathPlayer: 'dagger', google: 'dolch') - "‡": [T: "Doppelter Dolch"] # 0x2021 (en: 'double dagger', MathPlayer: 'double dagger', google: 'doppeldolch') @@ -267,8 +299,24 @@ then: [T: "punkt"] # (en: 'dot', google translation) else: [T: "Kugel"] # (en: 'bullet', MathPlayer: 'bullet', google: 'kugel') + - "…": # 0x2026 + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak '…' as 'and so on...' unless expr starts with '…' + - "../*[1][text()='…']" + then: [T: "punkt punkt punkt"] # (en: 'dot dot dot', google translation) + else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' + if: "count(following-sibling::*) = 0" + then: [T: "und so weiter"] # (en: 'and so on', google translation) + else: [T: "horizontale Ellipse"] # (en: 'and so on up to', MathPlayer: 'dot dot dot', google: 'und so weiter bis') + - "‰": [T: "promille"] # 0x2030 (en: 'per mille', MathPlayer: 'per mille sign', google: 'pro mille') - "‱": [T: "pro Zehntausend"] # 0x2031 (en: 'per ten thousand', MathPlayer: 'per ten thousand sign', google: 'pro zehntausend') + - "′": [T: "Strich"] # 0x2032 (en: 'prime', MathPlayer: 'strich', google: 'prime') + - "″": [T: "zwei Striche"] # 0x2033 (en: 'double prime', MathPlayer: 'zwei-strich', google: 'double prime') + - "‴": [T: "drei Striche"] # 0x2034 (en: 'triple prime', MathPlayer: 'drei-strich', google: 'triple prime') - "‵": [T: "umgekehrter Strich"] # 0x2035 (en: 'reversed prime', MathPlayer: 'reversed prime', google: 'umgekehrt prime') - "‶": [T: "zwei umgekehrte Striche"] # 0x2036 (en: 'reversed double prime', MathPlayer: 'reversed double prime', google: 'umgekehrt doppelte prime') - "‷": [T: "drei umgekehrte Striche"] # 0x2037 (en: 'reversed triple prime', google: 'triple prime umgekehrt') @@ -398,6 +446,7 @@ - "℆": [T: "cada una"] # 0x2106 (google translation) - "ℇ": [T: "Euler-Konstante"] # 0x2107 (en: 'euler's constant', google: 'eulers konstante') - "℈": [T: "skrupel"] # 0x2108 (en: 'scruples', google translation) + - "℉": [T: "Grad Fahrenheit"] # 0x2109 (google: 'grad fahrenheit') - "ℊ": [T: "Skript G"] # 0x210a (google: 'skript g') - "ℌℑℨℭ": # 0x210c, 0x2111, 0x2128, 0x212d - T: "Fraktur" # (en: 'fraktur', google: 'fraktur') @@ -409,6 +458,7 @@ then: [T: "doppelt geschlagen"] # (en: 'double struck', google translation) - spell: "translate('.', 'ℍℙℾℿ', 'HPΓΠ')" + - "ℎ": [T: "Planck-Konstante"] # 0x210e (en: 'planck constant', MathPlayer: 'planck constant', google: 'planck konstant') - "ℏ": # 0x210f - test: if: "($Verbosity='Terse')" @@ -419,11 +469,15 @@ - T: "Skript" # (en: 'script', MathPlayer: 'h bar', google: 'skript') - spell: "translate('.', 'ℐℒ℘ℬℰℱℳ', 'ILPBEFM')" + - "ℓ": [T: "Schreibschrift l"] # 0x2113 (en: 'script l', MathPlayer: 'script l', google: 'skript l') - "℔": [T: "L B Balkensymbol"] # 0x2114 (en: 'pounds', google: 'pfund') - "№": [T: "Numero-Zeichen"] # 0x2116 (en: 'number', MathPlayer: 'numero sign', google: 'nummer') - "℥": [T: "Unze-Zeichen"] # 0x2125 (en: 'ounces', MathPlayer: 'ounce sign', google: 'unzen') + - "Ω": [T: "Ohm-Zeichen"] # 0x2126 (en: 'ohms', MathPlayer: 'ohm sign', google: 'ohm') - "℧": [T: "Umgekehrtes Ohm-Zeichen"] # 0x2127 (en: 'mhos', MathPlayer: 'inverted ohm', google: 'mhos') - "℩": [T: "gedrehtes Iota"] # 0x2129 (google: 'drehte iota') + - "K": [T: "Kelvin-Zeichen"] # 0x212a (en: 'kelvin', MathPlayer: 'degrees kelvin', google: 'kelvin') + - "Å": [T: "Angstrom-Zeichen"] # 0x212b (en: 'angstroms', MathPlayer: 'angstroms', google: 'angstrome') - "ℯ": [T: "Skript E"] # 0x212f (google: 'skript e') # coalesced some chars that use cap letters @@ -501,6 +555,10 @@ - "ⅾ": [T: "ⅾ"] # 0x217e (en: 'D', google translation) - "ⅿ": [T: "ⅿ"] # 0x217f (en: 'M', google translation) - "↉": [T: "null drittel"] # 0x2189 (en: 'zero thirds') + - "←": [T: "Pfeil nach links"] # 0x2190 (en: 'leftwards arrow', MathPlayer: 'leftwards arrow', google: 'pfeil nach links') + - "↑": [T: "Aufwärtspfeil"] # 0x2191 (en: 'upwards arrow', MathPlayer: 'upwards arrow', google: 'nach oben pfeil') + - "→": [T: "Pfeil nach rechts"] # 0x2192 (en: 'rightwards arrow', MathPlayer: 'rightwards arrow', google: 'richtiger pfeil') + - "↓": [T: "Pfeil nach unten"] # 0x2193 (en: 'downwards arrow', MathPlayer: 'downwards arrow', google: 'nach unten pfeil') - "↔": [T: "Pfeil nach links und rechts"] # 0x2194 (en: 'left right arrow', MathPlayer: 'left right arrow', google: 'links rechts pfeil') - "↕": [T: "Pfeil nach oben und unten"] # 0x2195 (en: 'up down arrow', MathPlayer: 'up down arrow', google: 'auf pfeil runter') - "↖": [T: "Nordwestpfeil"] # 0x2196 (en: 'north west arrow', MathPlayer: 'north west arrow', google: 'nordwestpfeil') @@ -573,6 +631,7 @@ - "⇏": [T: "Doppelpfeil nach rechts mit Strich"] # 0x21cf (en: 'rightwards double arrow with stroke', MathPlayer: 'rightwards double arrow with stroke', google: 'richtiger doppelpfeil mit schlaganfall') - "⇐": [T: "Doppelpfeil nach links"] # 0x21d0 (en: 'leftwards double arrow', MathPlayer: 'leftwards double arrow', google: 'links doppelpfeil') - "⇑": [T: "Doppelpfeil nach oben"] # 0x21d1 (en: 'upwards double arrow', MathPlayer: 'upwards double arrow', google: 'double -pfeil nach oben') + - "⇒": [T: "Doppelpfeil nach rechts"] # 0x21d2 (en: 'rightwards double arrow', MathPlayer: 'rightwards double arrow', google: 'richtiger doppelpfeil') - "⇓": [T: "Doppelpfeil nach unten"] # 0x21d3 (en: 'downwards double arrow', MathPlayer: 'downwards double arrow', google: 'downwards doppelpfeil') - "⇔": [T: "Linker rechter Doppelpfeil"] # 0x21d4 (en: 'left right double arrow', MathPlayer: 'left right double arrow', google: 'links rechts doppelpfeil') - "⇕": [T: "Doppelpfeil nach oben und unten"] # 0x21d5 (en: 'up down double arrow', MathPlayer: 'up down double arrow', google: 'doppelpfeil nach oben') @@ -624,18 +683,107 @@ if: "$Verbosity!='Terse'" then: [T: "die"] # (en: 'the', google translation) - T: "Komplement" # (en: 'complement of') + - "∂": # 0x2202 + - test: + if: "$Verbosity='Terse'" + then: [T: "partiell"] # (en: 'partial', google translation) + else: [T: "partielle Ableitung"] # (en: 'partial derivative', google: 'partielle ableitung') - "∃": [T: "es gibt"] # 0x2203 (en: 'there exists') - "∄": [T: "es gibt nicht"] # 0x2204 (en: 'there does not exist') - "∅": [T: "leere Menge"] # 0x2205 (en: 'empty set') + - "∆": # 0x2206 + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # (en: 'the', google translation) + - T: "Laplace-Operator von" # (en: 'laplacian of', MathPlayer: 'increment', google: 'laplace von') + - "∇": # 0x2207 + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # (en: 'the', google translation) + - T: "Nabla" # (en: 'gradient of', google: 'gradient von') + - "∈": # 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: [T: "ein Element von"] # (en: 'an element of', google translation) + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "in"] # (google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "Element von"] # (en: 'member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "Element von"] # (en: 'element of', google translation) + - else: [T: "Element von"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "ist ein Element von"] # (en: 'is a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "ist ein Element von"] # (en: 'is an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "ist in"] # (en: 'is in', google translation) + - else: [T: "Element von"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - "∉": # 0x2209 + # rule is identical to 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: [T: "ist kein Element von"] # (en: 'is not an element of', google translation) + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "nicht in"] # (en: 'not in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "kein Element von"] # (en: 'not member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "kein Element von"] # (en: 'not element of', google translation) + - else: [T: "nicht Element von"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "ist kein Element von"] # (en: 'is not a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "ist kein Element von"] # (en: 'is not an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "ist nicht in"] # (en: 'is not in', google translation) + - else: [T: "nicht Element von"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to') + - "∊": # 0x220a + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: [T: "ist ein Element von"] # (en: 'is an element of', google translation) + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "in"] # (google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "Element von"] # (en: 'member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "Element von"] # (en: 'element of', google translation) + - else: [T: "Element von"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "ist ein Element von"] # (en: 'is a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "ist ein Element von"] # (en: 'is an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "ist in"] # (en: 'is in', google translation) + - else: [T: "Element von"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') - "∋": [T: "hat als Element"] # 0x220b (en: 'contains the member') - "∌": [T: "hat nicht als Element"] # 0x220c (en: 'does not contain the member') - "∍": [T: "hat als Element"] # 0x220d (en: 'contains the member') - "∎": [T: "Ende Beweis"] # 0x220e (en: 'end of proof') + - "∏": [T: "Produkt"] # 0x220f (en: 'product', MathPlayer: 'Product', google: 'produkt') + - "∐": [T: "Koprodukt"] # 0x2210 (en: 'coproduct', MathPlayer: 'coproduct', google: 'koprodukt') + - "∑": [T: "Summe"] # 0x2211 (en: 'sum') - "−": [T: "minus"] # 0x2212 - "∓": [T: "minus plus"] # 0x2213 (en: 'minus or plus') - "∔": [T: "Plus mit Punkt"] # 0x2214 (en: 'dot plus', MathPlayer: 'dot plus', google: 'punkt plus') - "∕": [T: "Division"] # 0x2215 (en: 'divided by', MathPlayer: 'Schrägstrich (Division)', google: 'geteilt durch') - "∖": [T: "Mengendifferenz"] # 0x2216 (en: 'set minus', MathPlayer: 'Mengen-Minus', google: 'minus einstellen') + - "∗": [T: "Sternoperator"] # 0x2217 (en: 'times', MathPlayer: 'asterisk operator', google: 'mal') - "∘": [T: "verknüpft mit"] # 0x2218 (en: 'composed with') - "∙": # 0x2219 - test: @@ -643,6 +791,11 @@ then: [T: "punkt"] # (en: 'dot', google translation) else: [T: "Kreisoperator"] # (en: 'times', MathPlayer: 'bullet operator', google: 'mal') + - "√": # 0x221a + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # (en: 'the', google translation) + - T: "Quadratwurzel" # (en: 'square root of', MathPlayer: 'radical', google: 'quadratwurzel von') - "∛": # 0x221b - test: if: "$Verbosity!='Terse'" @@ -653,12 +806,26 @@ if: "$Verbosity!='Terse'" then: [T: "die"] # (en: 'the', google translation) - T: "vierte Wurzel" # (en: 'fourth root of') + - "∝": # 0x221d + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "proportional zu" # (en: 'proportional to') - "∞": [T: "unendlich"] # 0x221e (en: 'infinity') + - "∟": [T: "rechter Winkel"] # 0x221f (en: 'right angle') + - "∠": [T: "Winkel"] # 0x2220 (en: 'angle') + - "∡": [T: "gerichteter Winkel"] # 0x2221 (en: 'measured angle', MathPlayer: 'measured angle', google: 'gemessener winkel') - "∢": [T: "Raumwinkel"] # 0x2222 (en: 'spherical angle', MathPlayer: 'spherical angle', google: 'sphärischer winkel') - "∣": [T: "teilt"] # 0x2223 (en: 'divides') - "∤": [T: "teilt nicht"] # 0x2224 (en: 'does not divide') - "∧": [T: "und"] # 0x2227 (en: 'and') - "∨": [T: "oder"] # 0x2228 (en: 'or') + - "∩": [T: "Durchschnitt"] # 0x2229 (en: 'intersection') + - "∪": [T: "Vereinigung"] # 0x222a (en: 'union') + - "∫": [T: "Integral"] # 0x222b (en: 'integral') + - "∬": [T: "Doppelintegral"] # 0x222c (en: 'double integral') + - "∭": [T: "Dreifachintegral"] # 0x222d (en: 'triple integral', MathPlayer: 'Dreifaches Integral', google: 'dreifachintegral') + - "∮": [T: "Randintegral"] # 0x222e (en: 'contour integral', MathPlayer: 'Kontur-Integral', google: 'konturintegral') - "∯": [T: "Oberflächenintegral"] # 0x222f (en: 'surface integral', MathPlayer: 'Flächenintegral', google: 'oberflächenintegral') - "∰": [T: "Volumenintegral"] # 0x2230 (en: 'volume integral', MathPlayer: 'Volumsintegral', google: 'volumenintegral') - "∱": [T: "Integral im Uhrzeigersinn"] # 0x2231 (en: 'clockwise integral') @@ -666,6 +833,12 @@ - "∳": [T: "Kurvenintegral im Gegenuhrzeigersinn"] # 0x2233 (en: 'anticlockwise contour integral', MathPlayer: 'Kontur-Integral im Gegenuhrzeigersinn', google: 'konturintegral gegen den gegenwart') - "∴": [T: "folglich"] # 0x2234 (en: 'therefore', MathPlayer: 'deshalb', google: 'daher') - "∵": [T: "weil"] # 0x2235 (en: 'because') + - "∶": # 0x2236 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "Verhältnis" # (en: 'to') + - "∷": [T: "Proportion"] # 0x2237 (en: 'as') - "∸": [T: "Minus mit Punkt"] # 0x2238 (en: 'dot minus', MathPlayer: 'dot minus', google: 'punkt minus') - "∹": [T: "Überschuss"] # 0x2239 (en: 'has excess compared to', MathPlayer: 'excess', google: 'hat überschüssig im vergleich zu') - "∺": # 0x223a @@ -678,6 +851,14 @@ if: "$Verbosity!='Terse'" then: [T: "ist"] # (en: 'is', google translation) - T: "homothetisch" # (en: 'homothetic to', MathPlayer: 'homothetic', google: 'homothetisch zu') + - "∼": [T: "Tildeoperator"] # 0x223c (en: 'varies with', MathPlayer: 'tilde operator', google: 'variiert mit') + - "∽": [T: "Umgekehrte Tilde"] # 0x223d (en: 'reversed tilde', MathPlayer: 'reversed tilde', google: 'umgekehrte tilde') + - "∾": # 0x223e + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "Umgekehrtes stummes S" # (en: 'most positive', MathPlayer: 'inverted lazy s', google: 'am positivsten') + - "∿": [T: "Sinuswelle"] # 0x223f (en: 'sine wave', MathPlayer: 'sine wave', google: 'sinus') - "≀": [T: "Kranzprodukt"] # 0x2240 (en: 'wreath product', MathPlayer: 'wreath product', google: 'kranzprodukt') - "≁": [T: "durchgestrichene Tilde"] # 0x2241 (en: 'not tilde', MathPlayer: 'not tilde', google: 'nicht tilde') - "≂": [T: "minus tilde"] # 0x2242 (SRE: 'Minus über Tilde') @@ -778,6 +959,16 @@ then: [T: "ist"] # (en: 'is', google translation) - T: "gemessen mit" # (en: 'measured by', MathPlayer: 'measured by') - "≟": [T: "vielleicht gleich"] # 0x225f (en: 'has an unknown relationship with', MathPlayer: 'questioned equal to', google: 'hat eine unbekannte beziehung zu') + - "≠": # 0x2260 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "ungleich" # (en: 'not equal to') + - "≡": # 0x2261 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "identisch mit" # (en: 'identical to', SRE: 'kongruent mit') - "≢": # 0x2262 - test: if: "$Verbosity!='Terse'" @@ -888,6 +1079,36 @@ - "≿": [T: "nachfolgend oder äquivalent"] # 0x227f (en: 'succeeds or is equivalent to', MathPlayer: 'succeeds or equivalent to', google: 'erfolg oder ist gleichbedeutend mit') - "⊀": [T: "nicht vorangehend"] # 0x2280 (en: 'does not precede', MathPlayer: 'does not precede', google: 'vorausgegangen nicht voraus') - "⊁": [T: "nicht nachfolgend"] # 0x2281 (en: 'does not succeed', MathPlayer: 'does not succeed', google: 'gelingt es nicht') + - "⊂": # 0x2282 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist ein"] # (en: 'is a', google translation) + - T: "echte Teilmenge von" # (en: 'subset of', MathPlayer: 'Teilmenge von', google: 'untergruppe von') + - "⊃": # 0x2283 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist ein"] # (en: 'is a', google translation) + - T: "echte Obermenge von" # (en: 'superset of', MathPlayer: 'Obermenge von', google: 'superset von') + - "⊄": # 0x2284 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "keine echte Teilmenge von" # (en: 'not a subset of', MathPlayer: 'nicht Teilmenge von', google: 'keine teilmenge von') + - "⊅": # 0x2285 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "keine echte Obermenge von" # (en: 'not a superset of', MathPlayer: 'nicht Obermenge von', google: 'kein superset von') + - "⊆": # 0x2286 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist ein"] # (en: 'is a', google translation) + - T: "Teilmenge oder gleich" # (en: 'subset of or equal to', MathPlayer: 'Teilmenge von odre gleich', google: 'teilmenge von oder gleich') + - "⊇": # 0x2287 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist ein"] # (en: 'is a', google translation) + - T: "Obermenge oder gleich" # (en: 'superset of or equal to', MathPlayer: 'Obermenge von oder gleich', google: 'superset von oder gleich') - "⊈": # 0x2288 - test: if: "$Verbosity!='Terse'" @@ -2846,8 +3067,11 @@ - "": [T: "digamma"] # 0xed03 (google translation) - "ϝ": [T: "digamma"] # 0x3dd - "": [T: ""] # 0xed10 (en: 'd', google translation) + - "ⅆ": [T: "d kursiv mit Doppelstrich"] # 0x2146 (en: 'd', MathPlayer: 'd', google: 'ⅆ') - "": [T: ""] # 0xed11 (en: 'e', google translation) + - "ⅇ": [T: "e kursiv mit Doppelstrich"] # 0x2147 (en: 'e', MathPlayer: 'e', google: 'ⅇ') - "": [T: ""] # 0xed12 (en: 'i', google translation) + - "ⅈ": [T: "i kursiv mit Doppelstrich"] # 0x2148 (en: 'i', MathPlayer: 'i', google: 'ⅈ') - "": [T: ""] # 0xed13 (en: 'j', google translation) - "ⅅ": - spell: "translate('.', 'ⅅ', 'DD')" # 0xed16, 0x2145 @@ -2896,6 +3120,7 @@ - " ": [T: ""] # 0x205f - "": [T: ""] # 0xef04 - "": [T: ""] # 0xef05 + - " ": [T: ""] # 0x2003 - "": [T: ""] # 0xef06 - "": [T: ""] # 0xef07 - "": [T: ""] # 0xef08 diff --git a/Rules/Languages/en/SharedRules/default.yaml b/Rules/Languages/en/SharedRules/default.yaml index 9a8389ddf..255c3bbf4 100644 --- a/Rules/Languages/en/SharedRules/default.yaml +++ b/Rules/Languages/en/SharedRules/default.yaml @@ -62,7 +62,7 @@ - test: - if: "string-length(.) = 1 and text() != '_'" # need unicode.tdl to kick in for single letter tokens then: [x: "text()"] - - else_if: "@data-chem-element > 0 or @data-roman-numeral" # NavMode=Character needs this + - else_if: "@data-chem-element or @data-roman-numeral" # NavMode=Character needs this then: [spell: "text()", pause: "short"] else: [x: "translate(., '-_\u00A0', ' ')"] # from intent literals or from extra spaces added (which get deleted) @@ -237,26 +237,12 @@ - x: "*[2]" - t: "below" # phrase(x with z 'below' it) -# FIX: this only works for up to four dots (which is realistically all we need) -- name: dot-over - tag: modified-variable - match: "*[1][self::m:mi] and (*[2][translate(., '.', '')=''])" - replace: - - x: "*[1]" - - x: "IfThenElse(string-length(*[2])=1, 'dot', - IfThenElse(string-length(*[2])=2, 'double dot', - IfThenElse(string-length(*[2])=3, 'triple dot', 'quadruple dot') - ))" - - pause: short - -# FIX: the 'translate' list is a little different from 'modified-variable', so we also include 'mover' (unify?) - name: diacriticals - tag: [mover, modified-variable] + tag: mover match: "*[1][self::m:mi] and *[2][translate(., '\u0306\u030c.\u00A8\u02D9\u20DB\u20DC`^ˇ~→¯_', '')='']" replace: - x: "*[1]" - x: "*[2]" - - pause: short - name: default tag: mover @@ -436,23 +422,22 @@ - t: "end scripts" # phrase(At this point 'end scripts' occurs) - name: default - tag: [mtable, array] + tag: mtable variables: - IsColumnSilent: "false()" - - NumColumns: "CountTableColumns(.)" - - NumRows: "CountTableRows(.)" + - NumColumns: "count(*[1]/*) - IfThenElse(*/self::m:mlabeledtr, 1, 0)" match: "." replace: - t: "table with" # phrase(the 'table with' 3 rows) - - x: "$NumRows" + - x: count(*) - test: - if: "$NumRows=1" + if: count(*)=1 then: [t: "row"] # phrase(the table with 1 'row') else: [t: "rows"] # phrase(the table with 3 'rows') - t: "and" # phrase(the table with 3 rows 'and' 4 columns) - x: "$NumColumns" - test: - if: "$NumColumns=1" + if: "NumColumns=1" then: [t: "column"] # phrase(the table with 3 rows and 1 'column') else: [t: "columns"] # phrase(the table with 3 rows and 4 'columns') - pause: long diff --git a/Rules/Languages/en/unicode-full.yaml b/Rules/Languages/en/unicode-full.yaml index 1a5356fd3..15c169d6a 100644 --- a/Rules/Languages/en/unicode-full.yaml +++ b/Rules/Languages/en/unicode-full.yaml @@ -10,6 +10,7 @@ - "¨": [t: "double dot"] # 0xa8 - "©": [t: "copyright"] # 0xa9 - "ª": [t: "feminine ordinal indicator"] # 0xaa + - "¬": [t: "not"] # 0xac - "«": [t: "left-pointing double angle quote mark"] # 0xab - "¯": # 0xaf - test: @@ -18,9 +19,24 @@ else: [t: "line"] - "²": [t: "two"] # 0xb2 - "³": [t: "three"] # 0xb3 + - "´": [t: "acute"] # 0xb4 - "µ": [t: "micro"] # 0xb5 - "¹": [t: "one"] # 0xb9 - "º": [t: "masculine ordinal indicator"] # 0xb9 + - "·": + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolDot = 'Auto'" + then: [t: "times"] + else: [t: "dot"] + - "×": # 0xd7 + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolX = 'Auto'" + then: [t: "times"] + else_test: + if: $ClearSpeak_MultSymbolX = 'By' + then: [t: "by"] + else: [t: "cross"] + - "÷": [t: "divided by"] # 0xf7 - "¡": [t: "inverted exclamation mark"] # 0xa1 - "¶": [t: "paragraph mark"] # 0xb6 - "¿": [t: "inverted question mark"] # 0xbf @@ -108,6 +124,14 @@ - "˽": [t: "modifier shelf"] # 0x2fd - "˾": [t: "modifier open shelf"] # 0x2fe - "˿": [t: "modifier low left arrow"] # 0x2ff + - "̀": [t: "grave accent embellishment"] # 0x300 + - "́": [t: "acute accent embellishment"] # 0x301 + - "̂": [t: "circumflex accent embellishment"] # 0x302 + - "̃": [t: "tilde embellishment"] # 0x303 + - "̄": [t: "macron embellishment"] # 0x304 + - "̅": [t: "overbar embellishment"] # 0x305 + - "̆": [t: "breve embellishment"] # 0x306 + - "̇": [t: "dot above embellishment"] # 0x307 - "̈": [t: "diaeresis embellishment"] # 0x308 - "̉": [t: "hook above embellishment"] # 0x309 - "̊": [t: "ring above embellishment"] # 0x30a @@ -197,9 +221,13 @@ - "ϒ": [t: "upsilon with hook"] # 0x3d2 - "ϓ": [t: "upsilon with acute and hook"] # 0x3d3 - "ϔ": [t: "upsilon with diaeresis and hook"] # 0x3d4 + - "ϕ": [t: "phi"] # 0x3d5 + - "ϖ": [t: "pi"] # 0x3d6 - "ϗ": [t: "kai"] # 0x3d7 - "Ϙ": [t: "cap archaic koppa"] # 0x3d8 - "ϙ": [t: "archaic koppa"] # 0x3d9 + - "ϵ": [t: "epsilon"] # 0x3f5 + - "϶": [t: "reversed epsilon"] # 0x3f6 - "А-Я": # 0x410 - 0x42f - test: if: "$CapitalLetters_Beep" @@ -271,6 +299,19 @@ then: [t: "dot"] else: [t: "bullet"] + - "…": # 0x2026 + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak '…' as 'and so on...' unless expr starts with '…' + - "../*[1][.='…']" + then: [t: "dot dot dot"] + else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' + if: "count(following-sibling::*) = 0" + then: [t: "and so on"] + else: [t: "and so on up to"] + - "‰": [t: "per mille"] # 0x2030 - "‱": [t: "per ten thousand"] # 0x2031 - "′": [t: "prime"] # 0x2032 @@ -427,6 +468,7 @@ - t: "script" - spell: "translate('.', 'ℐℒ℘ℬℰℱℳ', 'ILPBEFM')" + - "ℓ": [t: "script l"] # 0x2113 - "℔": [t: "pounds"] # 0x2114 - "№": [t: "number"] # 0x2116 - "℥": [t: "ounces"] # 0x2125 @@ -584,6 +626,7 @@ - "⇏": [t: "right double arrow with stroke"] # 0x21cf - "⇐": [t: "left double arrow"] # 0x21d0 - "⇑": [t: "up double arrow"] # 0x21d1 + - "⇒": [t: "implies"] # 0x21d2 - "⇓": [t: "down double arrow"] # 0x21d3 - "⇔": [t: "if and only if"] # 0x21d4 - "⇕": [t: "up down double arrow"] # 0x21d5 @@ -635,15 +678,81 @@ if: "$Verbosity!='Terse'" then: [ot: "the"] - t: "complement of" + - "∂": # 0x2202 + - test: + if: "$Verbosity='Terse'" + then: [t: "partial"] + else: [t: "partial derivative"] - "∃": [t: "there exists"] # 0x2203 - "∄": [t: "there does not exist"] # 0x2204 - "∅": [t: "empty set"] # 0x2205 + - "∆": # 0x2206 + - test: + if: "following-sibling::*" + then_test: + if: "$Verbosity!='Terse'" + then: [t: "the LahPlahsian of"] # "LahPlahsian" sounds better than "laplacian" in speech engines tested + else: [t: "LahPlahsian"] + else: [t: "LahPlahsian"] + - "∇": [t: "nahblah"] # 0x2207 + - "∉": # 0x2209 + # rule is identical to 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: [t: "is not an element of"] + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [t: "not in"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [t: "not member of"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [t: "not element of"] + - else: [t: "not belonging to"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [t: "is not a member of"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [t: "is not an element of"] + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [t: "is not in"] + - else: [t: "does not belong to"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + - "∊": # 0x220a + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - test: + if: "$Verbosity!='Terse' and not(parent::m:set)" # "the set x is an element of ..." sounds bad + then: [t: "is"] + - t: "an element of" + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [t: "in"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [t: "member of"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [t: "element of"] + - else: [t: "belonging to"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [t: "is a member of"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [t: "is an element of"] + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [t: "is in"] + - else: [t: "belongs to"] # $ClearSpeak_SetMemberSymbol = 'Belongs' - "∋": [t: "contains the member"] # 0x220b - "∌": [t: "does not contain the member"] # 0x220c - "∍": [t: "contains the member"] # 0x220d - "∎": [t: "end of proof"] # 0x220e - "∏": [t: "product"] # 0x220f + - "∐": [t: "coproduct"] # 0x2210 - "∑": [t: "sum"] # 0x2211 - "−": [t: "minus"] # 0x2212 - "∓": [t: "minus or plus"] # 0x2213 @@ -658,6 +767,11 @@ then: [t: "dot"] else: [t: "times"] + - "√": # 0x221a + - test: + if: "$Verbosity!='Terse'" + then: [ot: "the"] + - t: "square root of" - "∛": # 0x221b - test: if: "$Verbosity!='Terse'" @@ -668,6 +782,11 @@ if: "$Verbosity!='Terse'" then: [ot: "the"] - t: "fourth root of" + - "∝": # 0x221d + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "proportional to" - "∞": [t: "infinity"] # 0x221e - "∟": [t: "right angle"] # 0x221f - "∠": [t: "angle"] # 0x2220 @@ -690,6 +809,11 @@ - "∳": [t: "anticlockwise contour integral"] # 0x2233 - "∴": [t: "therefore"] # 0x2234 - "∵": [t: "because"] # 0x2235 + - "∶": # 0x2236 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "to" - "∷": [t: "as"] # 0x2237 - "∸": [t: "dot minus"] # 0x2238 - "∹": [t: "has excess compared to"] # 0x2239 @@ -705,6 +829,11 @@ - t: "homothetic to" - "∼": [t: "varies with"] # 0x223c - "∽": [t: "reversed tilde"] # 0x223d + - "∾": # 0x223e + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "most positive" - "∿": [t: "sine wave"] # 0x223f - "≀": [t: "wreath product"] # 0x2240 - "≁": [t: "not tilde"] # 0x2241 @@ -806,6 +935,16 @@ then: [t: "is"] - t: "measured by" - "≟": [t: "has an unknown relationship with"] # 0x225f + - "≠": # 0x2260 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "not equal to" + - "≡": # 0x2261 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "identical to" - "≢": # 0x2262 - test: if: "$Verbosity!='Terse'" @@ -916,6 +1055,36 @@ - "≿": [t: "succeeds or is equivalent to"] # 0x227f - "⊀": [t: "does not precede"] # 0x2280 - "⊁": [t: "does not succeed"] # 0x2281 + - "⊂": # 0x2282 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is a"] + - t: "subset of" + - "⊃": # 0x2283 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is a"] + - t: "superset of" + - "⊄": # 0x2284 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "not a subset of" + - "⊅": # 0x2285 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "not a superset of" + - "⊆": # 0x2286 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is a"] + - t: "subset of or equal to" + - "⊇": # 0x2287 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is a"] + - t: "superset of or equal to" - "⊈": # 0x2288 - test: if: "$Verbosity!='Terse'" @@ -1229,7 +1398,7 @@ - "⏠": [t: "top tortoise shell bracket"] # 0x23e0 - "⏡": [t: "bottom tortoise shell bracket"] # 0x23e1 - "⏢": [t: "white trapezium"] # 0x23e2 - - "⏣": [t: "benzene ring with circle"] # 0x23e3 + - "⏣": [t: "benzene right with circle"] # 0x23e3 - "⏤": [t: "straightness"] # 0x23e4 - "⏥": [t: "flatness"] # 0x23e5 - "⏦": # 0x23e6 @@ -1281,7 +1450,7 @@ - t: "parenthesized" - spell: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" - - "Ⓐ-Ⓩ": # 0x24b6 - 0x24cf + - "Ⓐ-ⓩ": # 0x24b6 - 0x24cf - t: "circled" - spell: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" @@ -1292,7 +1461,6 @@ - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 - t: "circled" - spell: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" - - "⓪": [t: "circled zero"] # 0x24ea - "⓫": [t: "black circled eleven"] # 0x24eb - "⓬": [t: "black circled twelve"] # 0x24ec @@ -1444,7 +1612,7 @@ - "⚆": [t: "white circle with dot right"] # 0x2686 - "⚇": [t: "white circle wiht two dots"] # 0x2687 - "⚈": [t: "black circle with dot right"] # 0x2688 - - "⚉": [t: "black circle with two dots"] # 0x2689 + - "⚉": [t: "black circle wiht two dots"] # 0x2689 - "⚪": [t: "medium white circle"] # 0x26aa - "⚫": [t: "medium black circle"] # 0x26ab - "⚬": [t: "medium small white circle"] # 0x26ac @@ -2878,8 +3046,11 @@ - "": [t: "digamma"] # 0xed03 - "ϝ": [t: "digamma"] # 0x3dd - "": [t: "d"] # 0xed10 + - "ⅆ": [t: "d"] # 0x2146 - "": [t: "e"] # 0xed11 + - "ⅇ": [t: "e"] # 0x2147 - "": [t: "i"] # 0xed12 + - "ⅈ": [t: "i"] # 0x2148 - "": [t: "j"] # 0xed13 - "ⅅ": - spell: "translate('.', 'ⅅ', 'DD')" # 0xed16, 0x2145 @@ -3494,6 +3665,12 @@ then: [t: "bold"] - spell: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" + - "-": # 0xf52e - 0xf537 (old MathType) + - test: + if: "not($IgnoreBold)" + then: [t: "bold"] + - spell: "translate('.', '', '0123456789')" + - "𝟬-𝟵": # 0x1D7EC - 0x1D7F5 - test: if: "not($IgnoreBold)" diff --git a/Rules/Languages/ru/ClearSpeak_Rules.yaml b/Rules/Languages/ru/ClearSpeak_Rules.yaml index c0955204c..0815c96c5 100644 --- a/Rules/Languages/ru/ClearSpeak_Rules.yaml +++ b/Rules/Languages/ru/ClearSpeak_Rules.yaml @@ -760,6 +760,24 @@ - pause: short - x: "*[3]" +# Handle log and ln when they remain individual mi elements rather than the +# canonical three-child function-application mrow handled by the next rule. +- name: ClearSpeak-log + tag: mi + match: ".='log' or .='ln'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity!='Terse' and following-sibling::*[2] and + not(IsNode(following-sibling::*[2],'simple'))" + then: [T: "от"] + - test: + - if: ".='log'" + then: [T: "логарифм"] + - else_if: "$ClearSpeak_Log = 'LnAsNaturalLog'" + then: [T: "натуральный логарифм"] + else: [T: "эл эн"] + - name: ClearSpeak-log tag: mrow variables: [{log_is_simple: "IsNode(*[3],'simple')"}] diff --git a/Rules/Languages/ru/navigate.yaml b/Rules/Languages/ru/navigate.yaml index 527dcce60..01bc51a76 100644 --- a/Rules/Languages/ru/navigate.yaml +++ b/Rules/Languages/ru/navigate.yaml @@ -91,6 +91,15 @@ # Rules for speaking what happens when moving into or out of a notation +# Prefix/silent intents with no NavigationParts entry (for example, unary +# minus, a vector, or a modified variable) should not announce "in"/"out of". +- name: into-or-out-of-prefix-or-silent-without-parts + tag: "*" + match: "$Move2D != '' and + (contains(@data-intent-property, ':prefix:') or contains(@data-intent-property, ':silent:')) and + GetNavigationPartName(name(.), count($Child2D/preceding-sibling::*)) = ''" + replace: [] + - name: into-or-out-of-mfrac tag: "*" match: "$Move2D != '' and (@data-from-mathml='mfrac' or self::m:mfrac)" diff --git a/Rules/Languages/zh/tw/unicode-full.yaml b/Rules/Languages/zh/tw/unicode-full.yaml index d5d10ea6e..6b349a521 100644 --- a/Rules/Languages/zh/tw/unicode-full.yaml +++ b/Rules/Languages/zh/tw/unicode-full.yaml @@ -554,6 +554,7 @@ - "↉": [T: "三分之0"] # 0x2189 (en: 'zero thirds', google translation) - "←": [T: "左箭頭"] # 0x2190 (en: 'leftwards arrow', google translation) - "↑": [T: "向上箭頭"] # 0x2191 (en: 'upwards arrow', google translation) + - "→": [T: "右箭頭"] # 0x2192 (en: 'rightwards arrow') - "↓": [T: "向下箭頭"] # 0x2193 (en: 'downwards arrow', google translation) - "↔": [T: "左右箭頭"] # 0x2194 (en: 'left right arrow') - "↕": [T: "上下箭頭"] # 0x2195 (en: 'up down arrow', google translation) diff --git a/build.rs b/build.rs index b8be2e9a9..a48b26033 100644 --- a/build.rs +++ b/build.rs @@ -151,6 +151,9 @@ fn zip_entry( /// Zip up each language and braille dir /// Note: regional variations (including zh-cn and zh-tw) are zipped together into one zip file fn main() { + println!("cargo::rerun-if-changed=build.rs"); + println!("cargo::rerun-if-changed=Rules"); + // This doesn't work because the build claims OUT_DIR is not defined(?) // let archive = PathBuf::from(concat!(env!("OUT_DIR"),"/rules.zip")); if std::env::var("CARGO_FEATURE_INCLUDE_ZIP").is_ok() { @@ -198,10 +201,5 @@ fn main() { if let Err(e) = archive_zip.finish() { panic!("Error in zip.finish(): {}", e); } - println!("cargo::rerun-if-changed=Rules"); - } else { - // Without include-zip, Rules are loaded at runtime from disk and must not - // re-run this script (or slow the build) on every yaml edit. - println!("cargo::rerun-if-changed=build.rs"); } } diff --git a/tests/Languages/en/mtable.rs b/tests/Languages/en/mtable.rs index cbd2a5275..e6952cf51 100644 --- a/tests/Languages/en/mtable.rs +++ b/tests/Languages/en/mtable.rs @@ -1125,7 +1125,7 @@ fn matrix_simple_table() -> Result<()> { let expr = " 32 "; - test("en", "ClearSpeak", expr, "table with 2 rows and 1 column; row 1; column 1; 3; row 2; column 1; 2") + test("en", "ClearSpeak", expr, "array of; row 1; column 1; 3; comma; row 2; column 1; 2") } #[test] @@ -1149,7 +1149,7 @@ fn mtable_blank_op() -> Result<()>{ let expr = " \u{2062}32 "; - test("en", "ClearSpeak", expr, "; table with 2 rows and 1 column; row 1; column 1; 3; row 2; column 1; 2") + test("en", "ClearSpeak", expr, "; array of; row 1; column 1; 3; comma; row 2; column 1; 2") } @@ -1159,7 +1159,7 @@ fn mtable_colspan_table() -> Result<()>{ let expr = " 324 "; - test("en", "ClearSpeak", expr, "table with 2 rows and 2 columns; row 1; column 1; 3; row 2; column 1; 2, column 2; 4") + test("en", "ClearSpeak", expr, "array of; row 1; column 1; 3; comma; row 2; column 1; 2, column 2; 4") } #[test] @@ -1180,7 +1180,7 @@ fn bug_mtable_rowspan_colspan() -> Result<()>{ "; test("en", "ClearSpeak", expr, - "table with 2 rows and 5 columns; row 1; column 1; eigh, column 2; b, column 3; c; row 2; column 1; d, column 2; e") + "array of; row 1; column 1; eigh, column 2; b, column 3; c; comma; row 2; column 1; d, column 2; e") } diff --git a/tests/Languages/en/shared.rs b/tests/Languages/en/shared.rs index b67126fd8..cf53eed5c 100644 --- a/tests/Languages/en/shared.rs +++ b/tests/Languages/en/shared.rs @@ -22,7 +22,7 @@ fn modified_vars() -> Result<()> { "; test("en", "SimpleSpeak", expr, "eigh grave, b tilde, c breve, b check, c grave; plus \ - r check, plus; x dot, y dot, z double dot, u triple dot, v quadruple dot; plus x hat, plus vector t")?; + r check plus; x dot, y dot, z double dot, u triple dot, v quadruple dot; plus x hat, plus vector t")?; return Ok(()); } @@ -337,7 +337,6 @@ fn ignore_comma() -> Result<()> { } #[test] -#[ignore] // issue #14 fn ignore_period_and_space() -> Result<()> { // from https://en.wikipedia.org/wiki/Probability let expr = " @@ -373,7 +372,7 @@ fn ignore_period_and_space() -> Result<()> { "; - test("en", "ClearSpeak", expr, "cap p, open paren, cap eigh divides cap b, close paren; is equal to; the fraction with numerator; cap p, open paren, cap eigh intersection cap b; close paren; and denominator cap p of cap b")?; + test("en", "ClearSpeak", expr, "cap p, open paren, cap eigh divides cap b, close paren; is equal to; the fraction with numerator; cap p, open paren, cap eigh intersection cap b; close paren; and denominator cap p of cap b; dot")?; return Ok(()); } @@ -415,7 +414,7 @@ fn dots() -> Result<()> { x..+ x... "; - test("en", "SimpleSpeak",expr, "x dot, plus x double dot, plus x triple dot")?; + test("en", "SimpleSpeak",expr, "x dot, plus x .., plus x ...")?; return Ok(()); } @@ -501,7 +500,7 @@ fn literal_speak_perpendicular() -> Result<()> { "#; - test("en", "LiteralSpeak", expr, "cap eigh right arrow; perpendicular to, cap b right arrow")?; + test("en", "LiteralSpeak", expr, "cap eigh right arrow, perpendicular to, cap b right arrow")?; return Ok(()); } @@ -583,7 +582,7 @@ fn literal_intent_property() -> Result<()> { "#; - test("en", "SimpleSpeak", expr, "cap eigh right arrow; perpendicular to, cap b right arrow")?; + test("en", "SimpleSpeak", expr, "cap eigh right arrow, perpendicular to, cap b right arrow")?; return Ok(()); } diff --git a/tests/Languages/fi/shared.rs b/tests/Languages/fi/shared.rs index fed99464f..4f3e7dfd2 100644 --- a/tests/Languages/fi/shared.rs +++ b/tests/Languages/fi/shared.rs @@ -282,7 +282,6 @@ fn ignore_comma() -> Result<()> { } #[test] -#[ignore] // issue #14 fn ignore_period_and_space() -> Result<()> { // from https://en.wikipedia.org/wiki/Probability let expr = " @@ -318,7 +317,7 @@ fn ignore_period_and_space() -> Result<()> { "; - test("fi", "ClearSpeak", expr, "phi of x is equal to; c, e raised to the negative h squared x squared power")?; + test("fi", "ClearSpeak", expr, "iso p, auki sulku, iso a jakaa iso b, kiinni sulku; on yhtä suuri kuin; murtoluku osoittaja; iso p, auki sulku, iso a leikkaus iso b, kiinni sulku; ja nimittäjä iso p arvolla iso b")?; return Ok(()); } diff --git a/tests/Languages/fr/shared.rs b/tests/Languages/fr/shared.rs index b63588b52..b623252bd 100644 --- a/tests/Languages/fr/shared.rs +++ b/tests/Languages/fr/shared.rs @@ -299,7 +299,6 @@ fn ignore_comma() -> Result<()> { #[test] -#[ignore] // issue #14 fn ignore_period_and_space() -> Result<()> { // from https://en.wikipedia.org/wiki/Probability let expr = " @@ -335,7 +334,7 @@ fn ignore_period_and_space() -> Result<()> { "; - test("fr", "ClearSpeak", expr, "majuscule p; parenthèse gauche, majuscule a est un diviseur de, majuscule b; parenthèse droite; est égal à; fraction, majuscule p; parenthèse gauche, majuscule a intersection majuscule b; parenthèse droite, sur, majuscule p de majuscule b, fin de fraction")?; + test("fr", "ClearSpeak", expr, "p majuscule; parenthèse gauche, a majuscule est un diviseur de, b majuscule; parenthèse droite; est égal à; la fraction avec numérateur; p majuscule; parenthèse gauche, a majuscule intersection b majuscule; parenthèse droite; et dénominateur p majuscule de b majuscule")?; Ok(()) } diff --git a/tests/Languages/hu/shared.rs b/tests/Languages/hu/shared.rs index bd53bb4c3..23439e489 100644 --- a/tests/Languages/hu/shared.rs +++ b/tests/Languages/hu/shared.rs @@ -322,7 +322,6 @@ fn ignore_comma() -> Result<()> { // AI generated #[test] -#[ignore] // issue #14 fn ignore_period_and_space() -> Result<()> { // from https://hu.wikipedia.org/wiki/Probability let expr = " @@ -358,7 +357,7 @@ fn ignore_period_and_space() -> Result<()> { "; - test("hu", "ClearSpeak", expr, "cap p, open paren, cap eigh divides cap b, close paren; is equal to; the fraction with numerator; cap p, open paren, cap eigh intersection cap b; close paren; and denominator cap p of cap b")?; + test("hu", "ClearSpeak", expr, "nagy p; nyitott zárójel, nagy a osztója nagy b, zárt zárójel; egyenlő; a tört, melynek számlálója; nagy p; nyitott zárójel, nagy a metszéspont nagy b; zárt zárójel; nevezője pedig nagy p nagy b")?; return Ok(()); } diff --git a/tests/Languages/nb/shared.rs b/tests/Languages/nb/shared.rs index 4a7252b8f..cad60ddd4 100644 --- a/tests/Languages/nb/shared.rs +++ b/tests/Languages/nb/shared.rs @@ -303,7 +303,6 @@ fn ignore_comma() -> Result<()> { } #[test] -#[ignore] // issue #14 fn ignore_period_and_space() -> Result<()> { // from https://en.wikipedia.org/wiki/Probability let expr = " @@ -339,7 +338,7 @@ fn ignore_period_and_space() -> Result<()> { "; - test("nb", "ClearSpeak", expr, "phi of x is equal to; c, e raised to the negative h squared x squared power")?; + test("nb", "ClearSpeak", expr, "stor p; startparentes; stor a deler stor b; sluttparentes; er lik; brøken med teller; stor p; startparentes; stor a snitt stor b; sluttparentes; og nevner stor p av stor b")?; return Ok(()); } diff --git a/tests/Languages/pl/definitions.rs b/tests/Languages/pl/definitions.rs index 9ee9abcea..312075f80 100644 --- a/tests/Languages/pl/definitions.rs +++ b/tests/Languages/pl/definitions.rs @@ -707,14 +707,12 @@ fn geometry_prefix_tests() -> Result<()> { #[test] fn separator_tests() -> Result<()> { - let expr = format!( - " + let expr = " x y - " - ); + ".to_string(); test("pl", "ClearSpeak", &expr, "x y")?; Ok(()) @@ -1025,4 +1023,4 @@ fn nofix_default_fixity_tests() -> Result<()> { } Ok(()) -} \ No newline at end of file +} diff --git a/tests/Languages/pl/shared.rs b/tests/Languages/pl/shared.rs index 8f42a8f51..173c7d7fd 100644 --- a/tests/Languages/pl/shared.rs +++ b/tests/Languages/pl/shared.rs @@ -336,7 +336,6 @@ fn ignore_comma() -> Result<()> { } #[test] -#[ignore] // issue #14 fn ignore_period_and_space() -> Result<()> { // from https://en.wikipedia.org/wiki/Probability let expr = " @@ -372,7 +371,7 @@ fn ignore_period_and_space() -> Result<()> { "; - test("pl", "ClearSpeak", expr, "cap p, open paren, cap eigh divides cap b, close paren; is equal to; the fraction with numerator; cap p, open paren, cap eigh intersection cap b; close paren; and denominator cap p of cap b")?; + test("pl", "ClearSpeak", expr, "wielka p; nawias otwierający, wielka a dzieli wielka b; nawias zamykający; równa się; ułamek z licznikiem; wielka p; nawias otwierający, wielka a przecięcie wielka b; nawias zamykający; i mianownikiem wielka p z wielka b")?; return Ok(()); } diff --git a/tests/Languages/ru.rs b/tests/Languages/ru.rs index 397e29a08..97edff4ee 100644 --- a/tests/Languages/ru.rs +++ b/tests/Languages/ru.rs @@ -31,4 +31,5 @@ mod units; mod chemistry; mod alphabets; mod intent; -mod mtable; \ No newline at end of file +mod mtable; +mod navigate; diff --git a/tests/Languages/ru/ClearSpeak/functions.rs b/tests/Languages/ru/ClearSpeak/functions.rs index 941e694d8..5171150f6 100644 --- a/tests/Languages/ru/ClearSpeak/functions.rs +++ b/tests/Languages/ru/ClearSpeak/functions.rs @@ -144,6 +144,22 @@ fn natural_log() -> Result<()> { return Ok(()); } +#[test] +fn individual_log_mi() -> Result<()> { + let expr = "log"; + test("ru", "ClearSpeak", expr, "логарифм")?; + return Ok(()); +} + +#[test] +fn individual_ln_mi() -> Result<()> { + let expr = "ln"; + test("ru", "ClearSpeak", expr, "эл эн")?; + test_ClearSpeak("ru", "ClearSpeak_Log", "LnAsNaturalLog", expr, + "натуральный логарифм")?; + return Ok(()); +} + #[test] fn explicit_function_call_with_parens() -> Result<()> { let expr = "t⁡(x)"; diff --git a/tests/Languages/ru/navigate.rs b/tests/Languages/ru/navigate.rs new file mode 100644 index 000000000..690df9eff --- /dev/null +++ b/tests/Languages/ru/navigate.rs @@ -0,0 +1,56 @@ +//! Russian navigation speech for prefix/silent intents without NavigationParts. + +use crate::common::*; +use anyhow::Result; +use std::panic::{catch_unwind, AssertUnwindSafe}; + +fn init_nav(mathml: &str) -> Result<()> { + set_rules_dir(abs_rules_dir_path())?; + set_preference("Language", "ru")?; + set_preference("SpeechStyle", "SimpleSpeak")?; + set_preference("Verbosity", "Medium")?; + set_preference("NavMode", "Enhanced")?; + set_preference("NavVerbosity", "Verbose")?; + set_preference("AutoZoomOut", "False")?; + set_preference("Overview", "False")?; + set_mathml(mathml)?; + Ok(()) +} + +fn assert_zoom_in(mathml: &str, expected: &str) -> Result<()> { + init_panic_handler(); + let result = catch_unwind(AssertUnwindSafe(|| { + init_nav(mathml)?; + let speech = do_navigate_command("ZoomIn")?; + let trimmed_speech = speech.trim_end_matches([' ', ',', ';']).to_string(); + assert_eq!(expected, trimmed_speech); + Ok(()) + })); + report_any_panic(result) +} + +#[test] +fn no_parts_prefix_vector_suppresses_base_announcement() -> Result<()> { + let expr = r#" + + + v + → + + + "#; + assert_zoom_in(expr, "переход внутрь; вэ") +} + +#[test] +fn no_parts_silent_modified_variable_suppresses_base_announcement() -> Result<()> { + let expr = r#" + + + x + ^ + + + "#; + assert_zoom_in(expr, "переход внутрь; икс") +} diff --git a/tests/Languages/sv/shared.rs b/tests/Languages/sv/shared.rs index 4ee13f6fb..99e281614 100644 --- a/tests/Languages/sv/shared.rs +++ b/tests/Languages/sv/shared.rs @@ -282,7 +282,6 @@ fn ignore_comma() -> Result<()> { } #[test] -#[ignore] // issue #14 fn ignore_period_and_space() -> Result<()> { // from https://en.wikipedia.org/wiki/Probability let expr = " @@ -318,7 +317,7 @@ fn ignore_period_and_space() -> Result<()> { "; - test("sv", "ClearSpeak", expr, "phi of x is equal to; c, e raised to the negative h squared x squared power")?; + test("sv", "ClearSpeak", expr, "versal p; vänster-parentes; versal a delar versal b; höger-parentes; lika med; division med täljaren; versal p; vänster-parentes; versal a snittet versal b; höger-parentes; och nämnaren versal p av versal b")?; return Ok(()); } diff --git a/tests/Languages/vi/vi.rs b/tests/Languages/vi/vi.rs index aa95f0e1f..3b6d8dee4 100644 --- a/tests/Languages/vi/vi.rs +++ b/tests/Languages/vi/vi.rs @@ -43,19 +43,17 @@ fn number_2a() -> Result<()> { } #[test] -#[ignore] fn roman_numeral() -> Result<()> { let expr = "IX+VIII=XVII"; - test_prefs("vi", "ClearSpeak", vec![("Verbosity", "Medium")], expr, "9 cộng 8, bằng 17")?; - test_prefs("vi", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, "9 la mã cộng 8 la mã, bằng 17 la mã")?; + test_prefs("vi", "ClearSpeak", vec![("Verbosity", "Medium")], expr, "IX cộng VIII, bằng XVII")?; + test_prefs("vi", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, "IX cộng VIII, bằng XVII")?; return Ok(()); } #[test] -#[ignore] fn vi_units_1() -> Result<()> { let expr = "1tấn10tạ100yếnvà4lít"; - test("vi", "ClearSpeak", expr, "1 tấn 10 tạ 100 yến và 4 lít")?; + test("vi", "ClearSpeak", expr, "1 tấn 10 tạ 100 yếnvà 4 lít")?; return Ok(()); } diff --git a/tests/Languages/zh/tw/shared.rs b/tests/Languages/zh/tw/shared.rs index 3d9474687..424958a50 100644 --- a/tests/Languages/zh/tw/shared.rs +++ b/tests/Languages/zh/tw/shared.rs @@ -300,7 +300,6 @@ fn ignore_comma() -> Result<()> { } #[test] -#[ignore] // issue #14 fn ignore_period_and_space() -> Result<()> { // from https://en.wikipedia.org/wiki/Probability let expr = " @@ -336,7 +335,7 @@ fn ignore_period_and_space() -> Result<()> { "; -test("zh-tw", "SimpleSpeak", expr, "大寫 p, 左小括, 大寫 a 垂線 大寫 b, 右小括; 等於; 分數 大寫 p 大寫 b, 分之, 大寫 p, 左小括, 大寫 a 交集 大寫 b, 右小括 結束分數; 點")?; +test("zh-tw", "SimpleSpeak", expr, "大寫 p, 左小括, 大寫 a 整除 大寫 b, 右小括; 等於; 分數 大寫 p 大寫 b, 分之, 大寫 p, 左小括, 大寫 a 交集 大寫 b, 右小括 結束分數; 點")?; return Ok(()); } diff --git a/tests/braille/Russian/russian.rs b/tests/braille/Russian/russian.rs index 5138fb374..1b40f13b7 100644 --- a/tests/braille/Russian/russian.rs +++ b/tests/braille/Russian/russian.rs @@ -1387,6 +1387,35 @@ fn source_less_common_math_symbols_11() -> Result<()> { return test_russian_braille(r#"a∤b"#, "⠠⠁⠀⠼⠀⠃"); } +#[test] +fn source_gost_order_relations_greater_or_less() -> Result<()> { + return test_russian_braille(r#"x≷y"#, "⠠⠭⠀⠕⠪⠀⠽"); +} + +#[test] +fn source_gost_order_relations_less_or_greater() -> Result<()> { + return test_russian_braille(r#"x≶y"#, "⠠⠭⠀⠪⠕⠀⠽"); +} + +#[test] +fn source_gost_large_vertical_arrows() -> Result<()> { + test_russian_braille(r#"↑"#, "⠰⠌")?; + return test_russian_braille(r#"↓"#, "⠘⠡"); +} + +#[test] +fn source_gost_contextual_square_bracket_recognition_points() -> Result<()> { + test_russian_braille(r#"[x]"#, "⠠⠷⠠⠭⠠⠾")?; + return test_russian_braille(r#"[1]"#, "⠷⠼⠁⠾"); +} + +#[test] +fn source_gost_contextual_angle_bracket_recognition_points() -> Result<()> { + test_russian_braille(r#"⟨x⟩"#, "⠈⠪⠠⠭⠈⠕")?; + test_russian_braille(r#"⟨1⟩"#, "⠪⠼⠁⠕")?; + return test_russian_braille(r#"x<y"#, "⠠⠭⠀⠪⠀⠽"); +} + #[test] fn source_typeform_and_mathvariant_indicators() -> Result<()> { let expr = r#"x"#; From 0380bb0ea1e696c47e692d86521364eacdda8fe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Sat, 15 Aug 2026 10:23:14 +0200 Subject: [PATCH 030/157] Remove unused and commented-out code (#680) * Remove unused and commented-out code in `src/pretty_print.rs`. * remove more dead sections --- src/chemistry.rs | 9 --------- src/pretty_print.rs | 32 -------------------------------- src/speech.rs | 11 ----------- 3 files changed, 52 deletions(-) diff --git a/src/chemistry.rs b/src/chemistry.rs index 1266b4087..1176d8d3a 100644 --- a/src/chemistry.rs +++ b/src/chemistry.rs @@ -1258,15 +1258,6 @@ fn is_order_ok(mrow: Element) -> bool { } } -// from https://learnwithdrscott.com/ionic-bond-definition/ -// I don't include the noble gases since they don't interact with other elements and are ruled out elsewhere -// fn has_non_metal_element(elements: &[&str]) -> bool { -// static NON_METAL_ELEMENTS: phf::Set<&str> = phf_set! { -// "H", "B", "C", "N", "O", "F", "Si", "P", "S", "Cl", "As", "Se", "Br", "Te", "I", "At", -// }; -// return elements.iter().any(|&e| NON_METAL_ELEMENTS.contains(e)); -// } - fn has_noble_element(elements: &[NameStr<'_>]) -> bool { static NOBLE_ELEMENTS: phf::Set<&str> = phf_set! { diff --git a/src/pretty_print.rs b/src/pretty_print.rs index 674157949..6a3ccd979 100644 --- a/src/pretty_print.rs +++ b/src/pretty_print.rs @@ -4,15 +4,6 @@ use sxd_document_no_unsafe::dom::{Element, ChildOfElement, Attribute}; use sxd_document_no_unsafe::{as_str, as_qname}; -// #[allow(dead_code)] -// pub fn pp_doc(doc: &Document) { -// for root_child in doc.root().children() { -// if let ChildOfRoot::Element(e) = root_child { -// format_element(&e, 0); -// break; -// } -// }; -// } /// Pretty-print the MathML represented by `element`. pub fn mml_to_string(e: Element) -> String { @@ -89,23 +80,6 @@ fn handle_special_chars(text: &str) -> String { } -// /// Pretty print an xpath value. -// /// If the value is a `NodeSet`, the MathML for the node/element is returned. -// pub fn pp_xpath_value(value: Value) { -// use sxd_xpath_no_unsafe::Value; -// use sxd_xpath_no_unsafe::nodeset::Node; -// debug!("XPath value:"); -// if let Value::Nodeset(nodeset) = &value { -// for node in nodeset.document_order() { -// match node { -// Node::Element(el) => {debug!("{}", crate::pretty_print::format_element(&el, 1))}, -// Node::Text(t) => {debug!("found Text value: {}", t.text())}, -// _ => {debug!("found unexpected node type")} -// } -// } -// } -// } - /// Convert YAML to a string using with `indent` amount of space. pub fn yaml_to_string(yaml: &Yaml, indent: usize) -> String { let mut result = String::new(); @@ -288,12 +262,6 @@ impl<'a> YamlEmitter<'a> { self.compact } - // fn dump(&mut self, doc: &Yaml) -> EmitResult { - // // write DocumentStart - // writeln!(self.writer, "---")?; - // self.level = -1; - // self.emit_node(doc) - // } fn write_indent(&mut self) -> EmitResult { if self.level <= 0 { diff --git a/src/speech.rs b/src/speech.rs index 960b105e3..0aaf71405 100644 --- a/src/speech.rs +++ b/src/speech.rs @@ -206,17 +206,6 @@ fn yaml_type_err(yaml: &Yaml, str: &str) -> Error { anyhow!("Expected {}, found {}", str, yaml_to_type(yaml)) } -// fn yaml_key_err(dict: &Yaml, key: &str, yaml_type: &str) -> String { -// if dict.as_hash().is_none() { -// return format!("Expected dictionary with key '{}', found\n{}", key, yaml_to_string(dict, 1)); -// } -// let str = &dict[key]; -// if str.is_badvalue() { -// return format!("Did not find '{}' in\n{}", key, yaml_to_string(dict, 1)); -// } -// return format!("Type of '{}' is not a {}.\nIt is a {}. YAML value is\n{}", -// key, yaml_type, yaml_to_type(str), yaml_to_string(dict, 0)); -// } fn find_str<'a>(dict: &'a Yaml, key: &'a str) -> Option<&'a str> { return dict[key].as_str(); From d4a112a8a9688a68b0ba3504483c094e4a630377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Sat, 15 Aug 2026 13:56:14 +0200 Subject: [PATCH 031/157] Update demo link in developers documentation Updated the MathJax demo link to MathCAT demo with additional context. --- docs/developers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developers.md b/docs/developers.md index 331a16d78..cae5e58ec 100644 --- a/docs/developers.md +++ b/docs/developers.md @@ -76,7 +76,7 @@ fn test_simple_fraction() { ## Helpful Links -* [MathJax Demo](https://www.mathjax.org/#demo): lets you paste a MathML fragment and inspect its browser rendering. +* [MathCAT Demo]([https://www.mathjax.org/#demo](https://daisy.github.io/MathCATDemo/)): lets you paste a MathML fragment and inspect its displayed math, speech and braille. ### Test Coverage From 6ecc412cb591b15f6eb871389d19e14cc924780c Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Sun, 16 Aug 2026 00:41:56 -0700 Subject: [PATCH 032/157] Did cleanup with ranges to shrink file size. The big win was the 'id' dir which hadn't had ranges added. That was a 225k reduction. The rest only shortened the files by a bit over 9k. I also made sure that italic letters did NOT use an italic indicator. Awaiting feedback about whether that is correct for Russian. The other changes were smaller cleanups including always translating to lowercase letters in letter ranges (by adding "C"). --- Rules/Braille/CMU/unicode-full.yaml | 56 +- Rules/Braille/CMU/unicode.yaml | 85 +- Rules/Braille/Nemeth/unicode-full.yaml | 2739 +++++---- Rules/Braille/Nemeth/unicode.yaml | 30 +- Rules/Braille/Russian/unicode-full.yaml | 58 +- Rules/Braille/Swedish/unicode-full.yaml | 84 +- Rules/Braille/Swedish/unicode.yaml | 30 +- Rules/Braille/UEB/unicode-full.yaml | 104 +- Rules/Braille/UEB/unicode.yaml | 87 +- Rules/Braille/Vietnam/unicode-full.yaml | 79 +- Rules/Braille/Vietnam/unicode.yaml | 30 +- Rules/Languages/id/unicode-full.yaml | 7024 ++--------------------- src/braille.rs | 74 +- tests/braille/UEB/other.rs | 28 + 14 files changed, 2235 insertions(+), 8273 deletions(-) diff --git a/Rules/Braille/CMU/unicode-full.yaml b/Rules/Braille/CMU/unicode-full.yaml index 492f95c51..558972fcf 100644 --- a/Rules/Braille/CMU/unicode-full.yaml +++ b/Rules/Braille/CMU/unicode-full.yaml @@ -10,7 +10,7 @@ - "𝐀-𝐙": # 0x1d400 - 0x1d419 - tc: "BC" - - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'abcdefghijklmnopqrstuvwxyz')" # don't mark these as italic - "𝑎-𝑧": # 0x1d44e - 0x1d467 @@ -19,15 +19,15 @@ - "𝐴-𝑍": # 0x1d434 - 0x1d44d - tc: "C" - - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'abcdefghijklmnopqrstuvwxyz')" - "𝒂-𝒛": # 0x1d482 - 0x1d49b - - tc: "BI" + - tc: "B" - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" - "𝑨-𝒁": # 0x1d468 - 0x1d481 - - tc: "BIC" - - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - tc: "BC" + - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'abcdefghijklmnopqrstuvwxyz')" - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf - tc: "Ts" @@ -35,7 +35,7 @@ - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 - tc: "TsC" - - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'abcdefghijklmnopqrstuvwxyz')" - "ℊ": [t: "TL⠛⠁"] # 0x210a (Script Small G) - "ℋ": [t: "TCL⠓⠁"] # 0x210b (Script Capital H) @@ -54,15 +54,15 @@ - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 - tc: "BTsC" - - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'abcdefghijklmnopqrstuvwxyz')" - "𝔞-𝔷": # 0x1d51e - 0x1d537 - tc: "D" - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" - "𝔄-𝔝": # 0x1d504 - 0x1d51d - - tc: "D" - - spell: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABCDEFGJKLMNOPQSTUVWXY')" + - tc: "DC" + - spell: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'abcdefgjklmnopqstuvwxy')" - "ℌ": [t: "DCL⠓"] # 0x210C (Fraktur Capital H) - "ℑ": [t: "DCL⠊"] # 0x2111 (Fraktur Capital I) @@ -73,8 +73,8 @@ - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" - "𝔸-𝕐": # 0x1d538 - 0x1d550 (blackboard bold capitals, excluding special number sets) - - tc: "D" - - spell: "translate('.', '𝔸𝔹𝔻𝔼𝔽𝔾𝕀𝕁𝕂𝕃𝕄𝕆𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABCDEFGHIJKLMNOPQRST')" + - tc: "𝔹C" + - spell: "translate('.', '𝔸𝔹𝔻𝔼𝔽𝔾𝕀𝕁𝕂𝕃𝕄𝕆𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'abcdefghijklmnopqrst')" - "ℂ": [t: "⠸⠉"] # 0x2102 (números complejos) - "ℍ": [t: "⠸⠓"] # 0x210D (cuaterniones) @@ -86,11 +86,11 @@ - "𝖆-𝖟": # 0x1d586 - 0x1d59f - tc: "BD" - - spell: "translate('.', 'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz')" + - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" - "𝕬-𝖅": # 0x1d56c - 0x1d585 - tc: "BDC" - - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'abcdefghijklmnopqrstuvwxyz')" - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 - tc: "S" @@ -98,7 +98,7 @@ - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 - tc: "SC" - - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'abcdefghijklmnopqrstuvwxyz')" - "𝗮-𝘇": # 0x1d5ee - 0x1d607 - tc: "BS" @@ -106,23 +106,23 @@ - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed - tc: "BSC" - - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'abcdefghijklmnopqrstuvwxyz')" - "𝘢-𝘻": # 0x1d622 - 0x1d63b - - tc: "IS" + - tc: "S" - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" - "𝘈-𝘡": # 0x1d608 - 0x1d621 - - tc: "ISC" - - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - tc: "SC" + - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'abcdefghijklmnopqrstuvwxyz')" - "𝙖-𝙯": # 0x1d656 - 0x1d66f - - tc: "BILS" + - tc: "BS" - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" - "𝘼-𝙕": # 0x1d63c - 0x1d655 - - tc: "BILSC" - - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - tc: "BSC" + - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'abcdefghijklmnopqrstuvwxyz')" - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 - tc: "" @@ -130,7 +130,7 @@ - "𝙰-𝚉": # 0x1d670 - 0x1d689 - tc: "C" - - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'abcdefghijklmnopqrstuvwxyz')" - "𝚤": [t: "L⠊"] # 0x1d6a4 (dotless i) - "𝚥": [t: "L⠚"] # 0x1d6a5 (dotless j) @@ -143,19 +143,19 @@ - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿')" - "𝛼-𝜓": # 0x1d6fc - 0x1d713 - - tc: "IGL" + - tc: "GL" - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓')" - "𝛢-𝛹": # 0x1d6e2 - 0x1d6f9 - - tc: "ICGL" + - tc: "CGL" - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹')" - "𝜶-𝝍": # 0x1d736 - 0x1d74d - - tc: "BIGL" + - tc: "BGL" - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍')" - "𝜜-𝜳": # 0x1d71c - 0x1d733 - - tc: "BICGL" + - tc: "BCGL" - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳')" - "𝝰-𝞇": # 0x1d770 - 0x1d787 @@ -167,11 +167,11 @@ - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭')" - "𝞪-𝟁": # 0x1d7aa - 0x1d7c1 - - tc: "BISGL" + - tc: "BSGL" - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁')" - "𝞐-𝞧": # 0x1d790 - 0x1d7a7 - - tc: "BISCGL" + - tc: "BSCGL" - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧')" - "𝟎-𝟗": # 0x1d7ce - 0x1d7d7 diff --git a/Rules/Braille/CMU/unicode.yaml b/Rules/Braille/CMU/unicode.yaml index b7ce85a1b..fa027b0b6 100644 --- a/Rules/Braille/CMU/unicode.yaml +++ b/Rules/Braille/CMU/unicode.yaml @@ -107,84 +107,17 @@ - "Û": [t: "CL⠾"] # 0xDA - "Ü": [t: "CL⠳"] # 0xDC - - "A": [t: "CL⠁"] # 0x41 - - "B": # 0x42 + # Latin capitals: chem-element letters use 𝐶 (no word indicator); others use C. + # Cells come from lowercase a-z via spell/translate. + - "BCHIKNOPSUVWY": # chemistry-capable capitals - test: if: "@data-chem-element" - then: [t: "𝐶L⠃"] - else: [t: "CL⠃"] - - "C": # 0x43 - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠉"] - else: [t: "CL⠉"] - - "D": [t: "CL⠙"] # 0x44 - - "E": [t: "CL⠑"] # 0x45 - - "F": [t: "CL⠋"] # 0x46 - - "G": [t: "CL⠛"] # 0x47 - - "H": # 0x48 - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠓"] - else: [t: "CL⠓"] - - "I": # 0x49 - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠊"] - else: [t: "CL⠊"] - - "J": [t: "CL⠚"] # 0x4a - - "K": # 0x4b - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠅"] - else: [t: "CL⠅"] - - "L": [t: "CL⠇"] # 0x4c - - "M": [t: "CL⠍"] # 0x4d - - "N": # 0x4e - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠝"] - else: [t: "CL⠝"] - - "O": # 0x4f - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠕"] - else: [t: "CL⠕"] - - "P": # 0x50 - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠏"] - else: [t: "CL⠏"] - - "Q": [t: "CL⠟"] # 0x51 - - "R": [t: "CL⠗"] # 0x52 - - "S": # 0x53 - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠎"] - else: [t: "CL⠎"] - - "T": [t: "CL⠞"] # 0x54 - - "U": # 0x55 - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠥"] - else: [t: "CL⠥"] - - "V": # 0x56 - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠧"] - else: [t: "CL⠧"] - - "W": # 0x57 - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠺"] - else: [t: "CL⠺"] - - "X": [t: "CL⠭"] # 0x58 - - "Y": # 0x59 - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠽"] - else: [t: "CL⠽"] - - "Z": [t: "CL⠵"] # 0x5a + then: [tc: "𝐶"] + else: [tc: "C"] + - spell: "translate('.', 'BCHIKNOPSUVWY', 'bchiknopsuvwy')" + - "ADEFGJLMQRTXZ": # remaining capitals + - tc: "C" + - spell: "translate('.', 'ADEFGJLMQRTXZ', 'adefgjlmqrtxz')" - "α": [t: "GL⠁"] # 0x3b1 - "β": [t: "GL⠃"] # 0x3b2 diff --git a/Rules/Braille/Nemeth/unicode-full.yaml b/Rules/Braille/Nemeth/unicode-full.yaml index 06831aec3..935933a2a 100644 --- a/Rules/Braille/Nemeth/unicode-full.yaml +++ b/Rules/Braille/Nemeth/unicode-full.yaml @@ -1,1375 +1,1364 @@ ---- -# To greatly simplify typeface/language generation, the chars have unique ASCII chars for them: -# Typeface: S: sans-serif, B: bold, T: script/blackboard, I: italic, R: Roman -# Language: E: English, D: German, G: Greek, V: Greek variants, H: Hebrew, U: Russian -# Indicators: C: capital, L: letter, N: number, P: punctuation, M: multipurpose -# Others: W -- whitespace that should be kept (e.g, in a numeral) -# SRE doesn't have H: Hebrew, so not encoded (yet) -# Some of the weird letters (e.g., circled letters) I didn't translate with the above because -# they don't interact with rules since they are enclosed in other chars. - - - "⨯": [t: "⠈⠡"] # U+2A2F(VECTOR OR CROSS PRODUCT) -- make the same as 0x00D7 (Multiplication sign) - - # --- Nemeth Default Alphabet bold chars. --- - - "𝐀-𝐙": # 0x1d400 - 0x1d419 - - tc: "BE" - - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - "𝐚-𝐳": # 0x1d41a - 0x1d433 - - tc: "BE" - - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 - - tc: "BG" - - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" - - - "𝛂-𝛒": # 0x1d6c2 - 0x1d6d2 - - tc: "BG" - - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒', 'αβγδεζηθικλμνξοπρ')" - - - "𝛔-𝛖": # 0x1d6d4 - 0x1d6d6 - - tc: "BG" - - spell: "translate('.', '𝛔𝛕𝛖', 'στυ')" - - - "𝛘-𝛚": # 0x1d6d8 - 0x1d6da - - tc: "BG" - - spell: "translate('.', '𝛘𝛙𝛚', 'χψω')" - - - "𝛁": [tc: "BGL⠫"] # 0x1d6c1 - - "𝛓": [tc: "BVL⠎"] # 0x1d6d3 - - "𝛗": [tc: "BVL⠋"] # 0x1d6d7 - - "𝛛": [tc: "⠸⠈⠙"] # 0x1d6db - - "𝛜": [tc: "BGL⠑"] # 0x1d6dc - - "𝛝": [tc: "BVL⠹"] # 0x1d6dd - - "𝛞": [tc: "BGL⠅"] # 0x1d6de - - "𝛟": [tc: "BGL⠋"] # 0x1d6df - - "𝛠": [tc: "BGL⠗"] # 0x1d6e0 - - "𝛡": [tc: "BGL⠏"] # 0x1d6e1 - - - "𝟎-𝟗": # 0x1d7ce - 0x1d7d7 - - tc: "B" - - spell: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" - - # --- Nemeth Default Alphabet bold-fraktur chars. --- - - - "𝕬-𝖅": # 0x1d56c - 0x1d585 - - tc: "BD" - - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝖆-𝖟": # 0x1d586 - 0x1d59f - - tc: "BD" - - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" - - # --- Nemeth Default Alphabet bold-italic chars. --- - - "𝑨-𝒁": # 0x1d468 - 0x1d481 - - tc: "BIE" - - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝒂-𝒛": # 0x1d482 - 0x1d49b - - tc: "BIE" - - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝜜-𝜴": # 0x1d71c - 0x1d734 - - tc: "BIG" - - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" - - - "𝜵": [tc: "BIGL⠫"] # 0x1d735 - - - "𝜶-𝝆": # 0x1d736 - 0x1d746 - - tc: "BIG" - - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆', 'αβγδεζηθικλμνξοπρ')" - - - "𝝇": [tc: "BIVL⠎"] # 0x1d747 - - - "𝝈-𝝊": # 0x1d748 - 0x1d74a - - tc: "BIG" - - spell: "translate('.', '𝝈𝝉𝝊', 'στυ')" - - - "𝝋": [tc: "BIVL⠋"] # 0x1d74b - - - "𝝌-𝝎": # 0x1d74c - 0x1d74e - - tc: "BIG" - - spell: "translate('.', '𝝌𝝍𝝎', 'χψω')" - - - "𝝏": [tc: "BVL⠙"] # 0x1d74f - - "𝝐": [tc: "BIGL⠑"] # 0x1d750 - - "𝝑": [tc: "BIVL⠹"] # 0x1d751 - - - "𝝒-𝝕": # 0x1d752 - 0x1d755 - - tc: "BIG" - - spell: "translate('.', '𝝒𝝓𝝔𝝕', 'κφρπ')" - - # --- Nemeth Default Alphabet bold-script chars. --- - - - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 - - tc: "BTE" - - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝓪-𝔃": # 0x1d4ea - 0x1d503 - - tc: "BTE" - - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝚤-𝚥": # 0x1d6a4 - 0x1d6a5 - - tc: "" - - spell: "translate('.', '𝚤𝚥', '⠊⠚')" - -# Russian Alphabet (from Nemeth book) -# NOTE: is this translation needed? - - "А-Я": # 0x410 - 0x42f - - tc: "U" - - spell: "translate('.', 'АБВГДЕЗИЙКЛМНОПРСТУФЭ', 'ABVGDEZIYKLMNOPRSTUFE')" - - - "а-я": # 0x430 - 0x44f - - tc: "U" - - spell: "translate('.', 'абвгдезийклмнопрстуфэ', 'abvgdeziylkmnoprstufye')" - - - "①-⑨": # 0x2460 - 0x2473 - - tc: "⠫⠉⠸⠫⠼" - - spell: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" - - tc: "⠻" - - - "⓪": [tc: "⠫⠉⠸⠫⠼⠴⠻"] # 0x24ea - - - "⑩": [tc: "⠫⠉⠸⠫⠼⠂⠴⠻"] # 0x2469 - - "⑪": [tc: "⠫⠉⠸⠫⠼⠂⠂⠻"] # 0x246a - - "⑫": [tc: "⠫⠉⠸⠫⠼⠂⠆⠻"] # 0x246b - - "⑬": [tc: "⠫⠉⠸⠫⠼⠂⠒⠻"] # 0x246c - - "⑭": [tc: "⠫⠉⠸⠫⠼⠂⠲⠻"] # 0x246d - - "⑮": [tc: "⠫⠉⠸⠫⠼⠂⠢⠻"] # 0x246e - - "⑯": [tc: "⠫⠉⠸⠫⠼⠂⠖⠻"] # 0x246f - - "⑰": [tc: "⠫⠉⠸⠫⠼⠂⠶⠻"] # 0x2470 - - "⑱": [tc: "⠫⠉⠸⠫⠼⠂⠦⠻"] # 0x2471 - - "⑲": [tc: "⠫⠉⠸⠫⠼⠂⠔⠻"] # 0x2472 - - "⑳": [tc: "⠫⠉⠸⠫⠼⠆⠴⠻"] # 0x2473 - - - "㉑": [tc: "⠫⠉⠸⠫⠼⠆⠂⠻"] # 0x3251 - - "㉒": [tc: "⠫⠉⠸⠫⠼⠆⠆⠻"] # 0x3252 - - "㉓": [tc: "⠫⠉⠸⠫⠼⠆⠒⠻"] # 0x3253 - - "㉔": [tc: "⠫⠉⠸⠫⠼⠆⠲⠻"] # 0x3254 - - "㉕": [tc: "⠫⠉⠸⠫⠼⠆⠢⠻"] # 0x3255 - - "㉖": [tc: "⠫⠉⠸⠫⠼⠆⠖⠻"] # 0x3256 - - "㉗": [tc: "⠫⠉⠸⠫⠼⠆⠶⠻"] # 0x3257 - - "㉘": [tc: "⠫⠉⠸⠫⠼⠆⠦⠻"] # 0x3258 - - "㉙": [tc: "⠫⠉⠸⠫⠼⠆⠔⠻"] # 0x3259 - - "㉚": [tc: "⠫⠉⠸⠫⠼⠒⠴⠻"] # 0x325a - - "㉛": [tc: "⠫⠉⠸⠫⠼⠒⠂⠻"] # 0x325b - - "㉜": [tc: "⠫⠉⠸⠫⠼⠒⠆⠻"] # 0x325c - - "㉝": [tc: "⠫⠉⠸⠫⠼⠒⠒⠻"] # 0x325d - - "㉞": [tc: "⠫⠉⠸⠫⠼⠒⠲⠻"] # 0x325e - - "㉟": [tc: "⠫⠉⠸⠫⠼⠒⠢⠻"] # 0x325f - - "㊱": [tc: "⠫⠉⠸⠫⠼⠒⠖⠻"] # 0x32b1 - - "㊲": [tc: "⠫⠉⠸⠫⠼⠒⠶⠻"] # 0x32b2 - - "㊳": [tc: "⠫⠉⠸⠫⠼⠒⠦⠻"] # 0x32b3 - - "㊴": [tc: "⠫⠉⠸⠫⠼⠒⠔⠻"] # 0x32b4 - - "㊵": [tc: "⠫⠉⠸⠫⠼⠲⠴⠻"] # 0x32b5 - - "㊶": [tc: "⠫⠉⠸⠫⠼⠲⠂⠻"] # 0x32b6 - - "㊷": [tc: "⠫⠉⠸⠫⠼⠲⠆⠻"] # 0x32b7 - - "㊸": [tc: "⠫⠉⠸⠫⠼⠲⠒⠻"] # 0x32b8 - - "㊹": [tc: "⠫⠉⠸⠫⠼⠲⠲⠻"] # 0x32b9 - - "㊺": [tc: "⠫⠉⠸⠫⠼⠲⠢⠻"] # 0x32ba - - "㊻": [tc: "⠫⠉⠸⠫⠼⠲⠖⠻"] # 0x32bb - - "㊼": [tc: "⠫⠉⠸⠫⠼⠲⠶⠻"] # 0x32bc - - "㊽": [tc: "⠫⠉⠸⠫⠼⠲⠦⠻"] # 0x32bd - - "㊾": [tc: "⠫⠉⠸⠫⠼⠲⠔⠻"] # 0x32be - - "㊿": [tc: "⠫⠉⠸⠫⠼⠢⠴⠻"] # 0x32bf - -#NOTE: uncertainty here - - "Ⓐ-Ⓩ": # 0x24b6 - 0x24cf - - tc: "⠫⠉⠸⠫⠠" - - spell: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - tc: "⠻" - - - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 - - tc: "⠫⠉⠸⠫" - - spell: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" - - tc: "⠻" - - # --- Nemeth Default Alphabet circled-sans-serif chars. --- - - - "➀-➈": # 0x1f10b, 0x2780 - 0x2788 - - tc: "⠫⠉⠸⠫⠠⠨⠼" - - spell: "translate('.', '➀➁➂➃➄➅➆➇➈', '123456789')" - - tc: "⠻" - - - "🄋": [tc: "⠫⠉⠸⠫⠠⠨⠼⠴⠻"] # 0x1f10b - - "➉": [tc: "⠫⠉⠸⠫⠠⠨⠼⠂⠴⠻"] # 0x2789 - - # --- Nemeth Default Alphabet comma chars. --- - - - "🄁-🄊": # 0x1f101 - 0x1f10a - - spell: "translate('.', '🄁🄂🄃🄄🄅🄆🄇🄈🄉🄊', '0123456789')" - - tc: "⠠" - - - # --- Nemeth Default Alphabet double-circled chars. --- - - - "⓵": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠂⠻⠻"] # 0x24f5 - - "⓶": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠆⠻⠻"] # 0x24f6 - - "⓷": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠒⠻⠻"] # 0x24f7 - - "⓸": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠲⠻⠻"] # 0x24f8 - - "⓹": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠢⠻⠻"] # 0x24f9 - - "⓺": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠖⠻⠻"] # 0x24fa - - "⓻": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠶⠻⠻"] # 0x24fb - - "⓼": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠦⠻⠻"] # 0x24fc - - "⓽": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠔⠻⠻"] # 0x24fd - - "⓾": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠂⠴⠻⠻"] # 0x24fe - - # --- Nemeth Default Alphabet double-struck chars. --- - - "𝔸-𝕐": # 0x1d538 - 0x1d550 (partial, excludes ℂ ℍ ℕ ℙ ℚ ℝ ℤ) - - tc: "𝔹E" - - spell: "translate('.', '𝔸𝔹𝔻𝔼𝔽𝔾𝕀𝕁𝕂𝕃𝕄𝕆𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABDEFGIJKLMOSTUVWXY')" - - - "ℂ": [tc: "𝔹ECL⠉"] # 0x2102 - - "ℍ": [tc: "𝔹ECL⠓"] # 0x210d - - "ℕ": [tc: "𝔹ECL⠝"] # 0x2115 - - "ℙ": [tc: "𝔹ECL⠏"] # 0x2119 - - "ℚ": [tc: "𝔹ECL⠟"] # 0x211a - - "ℝ": [tc: "𝔹ECL⠗"] # 0x211d - - "ℤ": [tc: "𝔹ECL⠵"] # 0x2124 - - "Ω": [t: "CGL⠺"] # 0x2126 (Ohm sign (capital Greek omega)) - - - "𝕒-𝕫": # 0x1d552 - 0x1d56b - - tc: "𝔹E" - - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 - - tc: "𝔹" - - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" - - - # --- Nemeth Default Alphabet fraktur chars. --- - - - "𝔄-𝔜": # 0x1d504 - 0x1d51c - - tc: "D" - - spell: "translate('.', '𝔄𝔅𝔇𝔈𝔉𝔊𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABDEFGJKLMNOPQSTUVWXY')" - - - "ℭ": [tc: "DCL⠉"] # 0x212d - - "ℌ": [tc: "DCL⠓"] # 0x210c - - "ℑ": [tc: "DCL⠊"] # 0x2111 - - "ℜ": [tc: "DCL⠗"] # 0x211c - - "ℨ": [tc: "DCL⠵"] # 0x2128 - - - "𝔞-𝔷": # 0x1d51e - 0x1d537 - - tc: "D" - - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" - - # --- Nemeth Default Alphabet fullwidth chars. --- - - - "A-Z": # 0xff21 - 0xff3a - - tc: "" - - spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "a-z": # 0xff41 - 0xff5a - - tc: "" - - spell: "translate('.', 'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz')" - - - "0-9": # 0xff10 - 0xff19 - - tc: "" - - spell: "translate('.', '0123456789', '0123456789')" - - # --- Nemeth Default Alphabet italic chars -- treat as non-italic. --- - - - "𝐴-𝑍": # 0x1d434 - 0x1d44d - - tc: "E" - - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝑎-𝑧": # 0x1d44e - 0x1d467 - - tc: "E" - - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔ℎ𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa - - tc: "IG" - - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" - - - "𝛻": [tc: "IGL⠫"] # 0x1d6fb - - - "𝛼-𝜌": # 0x1d6fc - 0x1d70c - - tc: "IG" - - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌', 'αβγδεζηθικλμνξοπρ')" - - "𝜍": [tc: "IVL⠎"] # 0x1d70d - - - "𝜎": [tc: "IGL⠎"] # 0x1d70e - - "𝜏": [tc: "IGL⠞"] # 0x1d70f - - "𝜐": [tc: "IGL⠥"] # 0x1d710 - - - "𝜑": [tc: "IVL⠋"] # 0x1d711 - - - "𝜒": [tc: "IGL⠯"] # 0x1d712 - - "𝜓": [tc: "IGL⠽"] # 0x1d713 - - "𝜔": [tc: "IGL⠺"] # 0x1d714 - - - "𝜕": [tc: "VL⠙"] # 0x1d715 - - - "𝜖": [tc: "IGL⠑"] # 0x1d716 - - - "𝜗": [tc: "IVL⠹"] # 0x1d717 - - - "𝜘": [tc: "IGL⠅"] # 0x1d718 - - "𝜙": [tc: "IGL⠋"] # 0x1d719 - - "𝜚": [tc: "IGL⠗"] # 0x1d71a - - "𝜛": [tc: "IGL⠏"] # 0x1d71b - - # --- Nemeth Default Alphabet monospace chars. --- - - - "𝙰-𝚉": # 0x1d670 - 0x1d689 - - tc: "" - - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 - - tc: "" - - spell: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝟶-𝟿": # 0x1d7f6 - 0x1d7ff - - tc: "" - - spell: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" - - - # --- Nemeth Default Alphabet negative-circled chars. --- - - "⓿": [t: "⠫⠸⠉⠸⠫⠼⠴⠻"] # 0x24ff - - "❶": [t: "⠫⠸⠉⠸⠫⠼⠂⠻"] # 0x2776 - - "❷": [t: "⠫⠸⠉⠸⠫⠼⠆⠻"] # 0x2777 - - "❸": [t: "⠫⠸⠉⠸⠫⠼⠒⠻"] # 0x2778 - - "❹": [t: "⠫⠸⠉⠸⠫⠼⠲⠻"] # 0x2779 - - "❺": [t: "⠫⠸⠉⠸⠫⠼⠢⠻"] # 0x277a - - "❻": [t: "⠫⠸⠉⠸⠫⠼⠖⠻"] # 0x277b - - "❼": [t: "⠫⠸⠉⠸⠫⠼⠶⠻"] # 0x277c - - "❽": [t: "⠫⠸⠉⠸⠫⠼⠦⠻"] # 0x277d - - "❾": [t: "⠫⠸⠉⠸⠫⠼⠔⠻"] # 0x277e - - "❿": [t: "⠫⠸⠉⠸⠫⠼⠂⠴⠻"] # 0x277f - - "⓫": [t: "⠫⠸⠉⠸⠫⠼⠂⠂⠻"] # 0x24eb - - "⓬": [t: "⠫⠸⠉⠸⠫⠼⠂⠆⠻"] # 0x24ec - - "⓭": [t: "⠫⠸⠉⠸⠫⠼⠂⠒⠻"] # 0x24ed - - "⓮": [t: "⠫⠸⠉⠸⠫⠼⠂⠲⠻"] # 0x24ee - - "⓯": [t: "⠫⠸⠉⠸⠫⠼⠂⠢⠻"] # 0x24ef - - "⓰": [t: "⠫⠸⠉⠸⠫⠼⠂⠖⠻"] # 0x24f0 - - "⓱": [t: "⠫⠸⠉⠸⠫⠼⠂⠶⠻"] # 0x24f1 - - "⓲": [t: "⠫⠸⠉⠸⠫⠼⠂⠦⠻"] # 0x24f2 - - "⓳": [t: "⠫⠸⠉⠸⠫⠼⠂⠔⠻"] # 0x24f3 - - "⓴": [t: "⠫⠸⠉⠸⠫⠼⠆⠴⠻"] # 0x24f4 - - - "🅐": [t: "⠫⠸⠉⠸⠫⠠⠁⠻"] # 0x1f150 - - "🅑": [t: "⠫⠸⠉⠸⠫⠠⠃⠻"] # 0x1f151 - - "🅒": [t: "⠫⠸⠉⠸⠫⠠⠉⠻"] # 0x1f152 - - "🅓": [t: "⠫⠸⠉⠸⠫⠠⠙⠻"] # 0x1f153 - - "🅔": [t: "⠫⠸⠉⠸⠫⠠⠑⠻"] # 0x1f154 - - "🅕": [t: "⠫⠸⠉⠸⠫⠠⠋⠻"] # 0x1f155 - - "🅖": [t: "⠫⠸⠉⠸⠫⠠⠛⠻"] # 0x1f156 - - "🅗": [t: "⠫⠸⠉⠸⠫⠠⠓⠻"] # 0x1f157 - - "🅘": [t: "⠫⠸⠉⠸⠫⠠⠊⠻"] # 0x1f158 - - "🅙": [t: "⠫⠸⠉⠸⠫⠠⠚⠻"] # 0x1f159 - - "🅚": [t: "⠫⠸⠉⠸⠫⠠⠅⠻"] # 0x1f15a - - "🅛": [t: "⠫⠸⠉⠸⠫⠠⠇⠻"] # 0x1f15b - - "🅜": [t: "⠫⠸⠉⠸⠫⠠⠍⠻"] # 0x1f15c - - "🅝": [t: "⠫⠸⠉⠸⠫⠠⠝⠻"] # 0x1f15d - - "🅞": [t: "⠫⠸⠉⠸⠫⠠⠕⠻"] # 0x1f15e - - "🅟": [t: "⠫⠸⠉⠸⠫⠠⠏⠻"] # 0x1f15f - - "🅠": [t: "⠫⠸⠉⠸⠫⠠⠟⠻"] # 0x1f160 - - "🅡": [t: "⠫⠸⠉⠸⠫⠠⠗⠻"] # 0x1f161 - - "🅢": [t: "⠫⠸⠉⠸⠫⠠⠎⠻"] # 0x1f162 - - "🅣": [t: "⠫⠸⠉⠸⠫⠠⠞⠻"] # 0x1f163 - - "🅤": [t: "⠫⠸⠉⠸⠫⠠⠥⠻"] # 0x1f164 - - "🅥": [t: "⠫⠸⠉⠸⠫⠠⠧⠻"] # 0x1f165 - - "🅦": [t: "⠫⠸⠉⠸⠫⠠⠺⠻"] # 0x1f166 - - "🅧": [t: "⠫⠸⠉⠸⠫⠠⠭⠻"] # 0x1f167 - - "🅨": [t: "⠫⠸⠉⠸⠫⠠⠽⠻"] # 0x1f168 - - "🅩": [t: "⠫⠸⠉⠸⠫⠠⠵⠻"] # 0x1f169 - - # --- Nemeth Default Alphabet negative-circled-sans-serif chars. --- - - "🄌": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠴⠻"] # 0x1f10c - - "➊": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠂⠻"] # 0x278a - - "➋": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠆⠻"] # 0x278b - - "➌": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠒⠻"] # 0x278c - - "➍": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠲⠻"] # 0x278d - - "➎": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠢⠻"] # 0x278e - - "➏": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠖⠻"] # 0x278f - - "➐": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠶⠻"] # 0x2790 - - "➑": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠦⠻"] # 0x2791 - - "➒": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠔⠻"] # 0x2792 - - "➓": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠂⠴⠻"] # 0x2793 - - # --- Nemeth Default Alphabet negative-squared chars. --- - - "🅰-🆉": # 0x1f170 - 0x1f189 - - tc: "⠫⠸⠲⠸⠫⠠" - - spell: "translate('.', '🅰🅱🅲🅳🅴🅵🅶🅷🅸🅹🅺🅻🅼🅽🅾🅿🆀🆁🆂🆃🆄🆅🆆🆇🆈🆉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - tc: "⠻" - - # --- Nemeth Default Alphabet parenthesized chars. --- - - - "⑴-⑼": # 0x2474 - 0x247c - - tc: "⠷" - - spell: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" - - tc: "⠾" - - - "⑽": [t: "⠷⠂⠴⠾"] # 0x247d - - "⑾": [t: "⠷⠂⠂⠾"] # 0x247e - - "⑿": [t: "⠷⠂⠆⠾"] # 0x247f - - "⒀": [t: "⠷⠂⠒⠾"] # 0x2480 - - "⒁": [t: "⠷⠂⠲⠾"] # 0x2481 - - "⒂": [t: "⠷⠂⠢⠾"] # 0x2482 - - "⒃": [t: "⠷⠂⠖⠾"] # 0x2483 - - "⒄": [t: "⠷⠂⠶⠾"] # 0x2484 - - "⒅": [t: "⠷⠂⠦⠾"] # 0x2485 - - "⒆": [t: "⠷⠂⠔⠾"] # 0x2486 - - "⒇": [t: "⠷⠆⠴⠾"] # 0x2487 - - - "🄐-🄩": # 0x1f110 - 0x1f129 - - tc: "⠷⠠" - - spell: "translate('.', '🄐🄑🄒🄓🄔🄕🄖🄗🄘🄙🄚🄛🄜🄝🄞🄟🄠🄡🄢🄣🄤🄥🄦🄧🄨🄩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - tc: "⠾" - - - "⒜-⒵": # 0x249c - 0x24b5 - - tc: "⠷" - - spell: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" - - tc: "⠾" - - # --- Nemeth Default Alphabet period chars. --- - - "🄀": [t: "⠴⠸⠲"] # 0x1f100 - - "⒈": [t: "⠂⠸⠲"] # 0x2488 - - "⒉": [t: "⠆⠸⠲"] # 0x2489 - - "⒊": [t: "⠒⠸⠲"] # 0x248a - - "⒋": [t: "⠲⠸⠲"] # 0x248b - - "⒌": [t: "⠢⠸⠲"] # 0x248c - - "⒍": [t: "⠖⠸⠲"] # 0x248d - - "⒎": [t: "⠶⠸⠲"] # 0x248e - - "⒏": [t: "⠦⠸⠲"] # 0x248f - - "⒐": [t: "⠔⠸⠲"] # 0x2490 - - - "⒑": [t: "⠂⠴⠸⠲"] # 0x2491 - - "⒒": [t: "⠂⠂⠸⠲"] # 0x2492 - - "⒓": [t: "⠂⠆⠸⠲"] # 0x2493 - - "⒔": [t: "⠂⠒⠸⠲"] # 0x2494 - - "⒕": [t: "⠂⠲⠸⠲"] # 0x2495 - - "⒖": [t: "⠂⠢⠸⠲"] # 0x2496 - - "⒗": [t: "⠂⠖⠸⠲"] # 0x2497 - - "⒘": [t: "⠂⠶⠸⠲"] # 0x2498 - - "⒙": [t: "⠂⠦⠸⠲"] # 0x2499 - - "⒚": [t: "⠂⠔⠸⠲"] # 0x249a - - "⒛": [t: "⠆⠴⠸⠲"] # 0x249b - - # --- Nemeth Default Alphabet sans-serif chars. --- - - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 - - tc: "SE" - - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 - - tc: "SE" - - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝟢-𝟫": # 0x1d7e2 - 0x1d7eb - - tc: "S" - - spell: "translate('.', '𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫', '0123456789')" - - # --- Nemeth Default Alphabet sans-serif-bold chars. --- - - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed - - tc: "SBE" - - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝗮-𝘇": # 0x1d5ee - 0x1d607 - - tc: "SBE" - - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝝖-𝝮": # 0x1d756 - 0x1d76e - - tc: "SBG" - - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" - - - "𝝰-𝞀": # 0x1d770 - 0x1d780 - - tc: "SBG" - - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀', 'αβγδεζηθικλμνξοπρ')" - - - "𝝯": [tc: "SBGL⠫"] # 0x1d76f - - - "𝞁": [tc: "SBVL⠎"] # 0x1d781 - - - "𝞂-𝞄": # 0x1d782 - 0x1d784 - - tc: "SBG" - - spell: "translate('.', '𝞂𝞃𝞄', 'στυ')" - - - "𝞅": [tc: "SBVL⠋"] # 0x1d785 - - - "𝞆-𝞈": # 0x1d786 - 0x1d788 - - tc: "SBG" - - spell: "translate('.', '𝞆𝞇𝞈', 'χψω')" - - - "𝞉": [tc: "⠠⠨⠸⠈⠙"] # 0x1d789 - - "𝞊": [tc: "SBGL⠑"] # 0x1d78a - - "𝞋": [tc: "SBVL⠹"] # 0x1d78b - - - "𝞌-𝞏": # 0x1d78c - 0x1d78f - - tc: "SBG" - - spell: "translate('.', '𝞌𝞍𝞎𝞏', 'κφρπ')" - - - "𝟬-𝟵": # 0x1d7ec - 0x1d7f5 - - tc: "SB" - - spell: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" - - # --- Nemeth Default Alphabet sans-serif-bold-italic chars. --- - - - "𝘼-𝙕": # 0x1d63c - 0x1d655 - - tc: "SBIE" - - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝙖-𝙯": # 0x1d656 - 0x1d66f - - tc: "SBIE" - - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 - - tc: "SBIG" - - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" - - - "𝞩": [t: "SBIGL⠫"] # 0x1d7a9 - - - "𝞪-𝞺": # 0x1d7aa - 0x1d7ba - - tc: "SBIG" - - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺', 'αβγδεζηθικλμνξοπρ')" - - - "𝞻": [t: "SBIVL⠎"] # 0x1d7bb - - "𝞼": [t: "SBIGL⠎"] # 0x1d7bc - - "𝞽": [t: "SBIGL⠞"] # 0x1d7bd - - "𝞾": [t: "SBIGL⠥"] # 0x1d7be - - "𝞿": [t: "SBIVL⠋"] # 0x1d7bf - - - "𝟀": [t: "SBIGL⠯"] # 0x1d7c0 - - "𝟁": [t: "SBIGL⠽"] # 0x1d7c1 - - "𝟂": [t: "SBIGL⠺"] # 0x1d7c2 - - "𝟃": [t: "SBVL⠙"] # 0x1d7c3 - - - "𝟄": [t: "SBIGL⠑"] # 0x1d7c4 - - "𝟅": [t: "SBIVL⠹"] # 0x1d7c5 - - - "𝟆": [t: "SBIGL⠅"] # 0x1d7c6 - - "𝟇": [t: "SBIGL⠋"] # 0x1d7c7 - - "𝟈": [t: "SBIGL⠗"] # 0x1d7c8 - - "𝟉": [t: "SBIGL⠏"] # 0x1d7c9 - - # --- Nemeth Default Alphabet sans-serif-italic chars. --- - - "𝘈-𝘡": # 0x1d608 - 0x1d621 - - tc: "SIE" - - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝘢-𝘻": # 0x1d622 - 0x1d63b - - tc: "SIE" - - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" - - # --- Nemeth Default Alphabet script chars. --- - - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 - - tc: "TE" - - spell: "translate('.', '𝒜𝒞𝒟𝒢𝒥𝒦𝒩𝒪𝒫𝒬𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ACDGJKNOPQSTUVWXYZ')" - - - "ℬ": [t: "TECL⠃"] # 0x212c - - "ℰ": [t: "TECL⠑"] # 0x2130 - - "ℱ": [t: "TECL⠋"] # 0x2131 - - "ℋ": [t: "TECL⠓"] # 0x210b - - "ℐ": [t: "TECL⠊"] # 0x2110 - - "ℒ": [t: "TECL⠇"] # 0x2112 - - "ℳ": [t: "TECL⠍"] # 0x2133 - - "ℛ": [t: "TECL⠗"] # 0x211b - - - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf - - tc: "TE" - - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒻𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdfhijklmnpqrstuvwxyz')" - - - "ℯ": [t: "TEL⠑"] # 0x212f - - "ℊ": [t: "TEL⠛"] # 0x210a - - "ℴ": [t: "TEL⠕"] # 0x2134 - - # --- Nemeth Default Alphabet squared chars. --- - - - "🄰": [t: "⠫⠲⠸⠫⠠⠁⠻"] # 0x1f130 - - "🄱": [t: "⠫⠲⠸⠫⠠⠃⠻"] # 0x1f131 - - "🄲": [t: "⠫⠲⠸⠫⠠⠉⠻"] # 0x1f132 - - "🄳": [t: "⠫⠲⠸⠫⠠⠙⠻"] # 0x1f133 - - "🄴": [t: "⠫⠲⠸⠫⠠⠑⠻"] # 0x1f134 - - "🄵": [t: "⠫⠲⠸⠫⠠⠋⠻"] # 0x1f135 - - "🄶": [t: "⠫⠲⠸⠫⠠⠛⠻"] # 0x1f136 - - "🄷": [t: "⠫⠲⠸⠫⠠⠓⠻"] # 0x1f137 - - "🄸": [t: "⠫⠲⠸⠫⠠⠊⠻"] # 0x1f138 - - "🄹": [t: "⠫⠲⠸⠫⠠⠚⠻"] # 0x1f139 - - "🄺": [t: "⠫⠲⠸⠫⠠⠅⠻"] # 0x1f13a - - "🄻": [t: "⠫⠲⠸⠫⠠⠇⠻"] # 0x1f13b - - "🄼": [t: "⠫⠲⠸⠫⠠⠍⠻"] # 0x1f13c - - "🄽": [t: "⠫⠲⠸⠫⠠⠝⠻"] # 0x1f13d - - "🄾": [t: "⠫⠲⠸⠫⠠⠕⠻"] # 0x1f13e - - "🄿": [t: "⠫⠲⠸⠫⠠⠏⠻"] # 0x1f13f - - "🅀": [t: "⠫⠲⠸⠫⠠⠟⠻"] # 0x1f140 - - "🅁": [t: "⠫⠲⠸⠫⠠⠗⠻"] # 0x1f141 - - "🅂": [t: "⠫⠲⠸⠫⠠⠎⠻"] # 0x1f142 - - "🅃": [t: "⠫⠲⠸⠫⠠⠞⠻"] # 0x1f143 - - "🅄": [t: "⠫⠲⠸⠫⠠⠥⠻"] # 0x1f144 - - "🅅": [t: "⠫⠲⠸⠫⠠⠧⠻"] # 0x1f145 - - "🅆": [t: "⠫⠲⠸⠫⠠⠺⠻"] # 0x1f146 - - "🅇": [t: "⠫⠲⠸⠫⠠⠭⠻"] # 0x1f147 - - "🅈": [t: "⠫⠲⠸⠫⠠⠽⠻"] # 0x1f148 - - "🅉": [t: "⠫⠲⠸⠫⠠⠵⠻"] # 0x1f149 - - # --- Nemeth Default Alphabet sub chars. --- - - - "₀": [t: "⠰⠴"] # 0x2080 - - "₁": [t: "⠰⠂"] # 0x2081 - - "₂": [t: "⠰⠆"] # 0x2082 - - "₃": [t: "⠰⠒"] # 0x2083 - - "₄": [t: "⠰⠲"] # 0x2084 - - "₅": [t: "⠰⠢"] # 0x2085 - - "₆": [t: "⠰⠖"] # 0x2086 - - "₇": [t: "⠰⠶"] # 0x2087 - - "₈": [t: "⠰⠦"] # 0x2088 - - "₉": [t: "⠰⠔"] # 0x2089 - - # --- Nemeth Default Alphabet super chars. --- - - - "⁰": [t: "⠘⠴"] # 0x2070 - - "¹": [t: "⠘⠂"] # 0xb9 - - "²": [t: "⠘⠆"] # 0xb2 - - "³": [t: "⠘⠒"] # 0xb3 - - "⁴": [t: "⠘⠲"] # 0x2074 - - "⁵": [t: "⠘⠢"] # 0x2075 - - "⁶": [t: "⠘⠖"] # 0x2076 - - "⁷": [t: "⠘⠶"] # 0x2077 - - "⁸": [t: "⠘⠦"] # 0x2078 - - "⁹": [t: "⠘⠔"] # 0x2079 - - # --- Nemeth Default Characters latin-lower-phonetic chars. --- - - - "ø": [t: "⠈⠕"] # 0xf8 - - # --- Nemeth Default Characters math_geometry chars. --- - - - "─": [t: "⠱"] # 0x2500 - - "│": [t: "⠳"] # 0x2502 - - "▰": [t: "⠫⠸⠛"] # 0x25b0 - - "▱": [t: "⠫⠛"] # 0x25b1 - - "▽": [t: "⠨⠫"] # 0x25bd - - "◆": [t: "⠫⠸⠙"] # 0x25c6 - - "◇": [t: "⠫⠙"] # 0x25c7 - - "◈": [t: "⠫⠸⠙"] # 0x25c8 - - "◉": [t: "⠫⠸⠉"] # 0x25c9 - - "◊": [t: "⠫⠙"] # 0x25ca - - "⬟": [t: "⠫⠸⠢"] # 0x2b1f - - "⬠": [t: "⠫⠢"] # 0x2b20 - - "⬡": [t: "⠫⠖"] # 0x2b21 - - "⬢": [t: "⠫⠸⠖"] # 0x2b22 - - "⬣": [t: "⠫⠸⠖"] # 0x2b23 - - "⬤": [t: "⠫⠸⠉"] # 0x2b24 - - "⬥": [t: "⠫⠸⠙"] # 0x2b25 - - # --- Nemeth Default Characters math_symbols chars. --- - - - "\"": [t: "⠄⠄"] # 0x22 - - "¡": [t: "⠖"] # 0xa1 - - "¢": [t: "⠈⠉"] # 0xa2 - - "£": [t: "⠈⠇"] # 0xa3 - - "¤": [t: "⠈⠫"] # 0xa4 - - "¥": [t: "⠈⠽"] # 0xa5 - - "§": [t: "⠈⠠⠎"] # 0xa7 - - "©": [t: "⠘⠉"] # 0xa9 (Copyright) - - "ª": [t: "⠸⠰⠁"] # 0xaa - - "«": [t: "⠐⠅⠈⠐⠅⠻"] # 0xab - - "®": [t: "⠘⠗"] # 0xae - - "´": [t: "⠈"] # 0xb4 - - "µ": [t: "⠨⠍"] # 0xb5 - - "¶": [t: "⠈⠠⠏"] # 0xb6 - - "¿": [t: "⠦"] # 0xbf - - "ʹ": [t: "⠄"] # 0x2b9 - - "ʺ": [t: "⠄⠄"] # 0x2ba - - "˙": [t: "⠡"] # 0x2d9 - - "˜": [t: "⠈⠱"] # 0x2dc - - "‐": [t: "⠤"] # 0x2010 - - "‑": [t: "⠤"] # 0x2011 - - "‒": [t: "⠤⠤"] # 0x2012 - - "–": [t: "⠤⠤"] # 0x2013 - - "‖": [t: "⠳⠳"] # 0x2016 - - "†": [t: "⠸⠻"] # 0x2020 - - "‡": [t: "⠸⠸⠻"] # 0x2021 - - "•": [t: "⠡"] # 0x2022 - - "․": [t: "⠄"] # 0x2024 - - "‥": [t: "⠄⠄"] # 0x2025 - - "′": [t: "⠄"] # 0x2032 - - "″": [t: "⠄⠄"] # 0x2033 - - "‴": [t: "⠄⠄."] # 0x2034 (Triple prime) - - "⁗": [t: "⠄⠄.."] # 0x2057 (Quadruple prime) - - "‼": [t: "⠖⠖"] # 0x203c - - "‾": [t: "⠱"] # 0x203e - - "⁇": [t: "⠹⠹"] # 0x2047 - - "⁈": [t: "⠹⠖"] # 0x2048 - - "⁉": [t: "⠖⠹"] # 0x2049 - - "∀": [t: "⠈⠯"] # 0x2200 - - "∃": [t: "⠈⠿"] # 0x2203 - - "∄": [t: "⠌⠈⠿"] # 0x2204 - - "∅": [t: "⠸⠴"] # 0x2205 - - "∈": [t: "⠈⠑"] # 0x2208 - - "∉": [t: "⠌⠈⠑"] # 0x2209 - - "∊": [t: "⠈⠑"] # 0x220a - - "∋": [t: "⠈⠢"] # 0x220b - - "∌": [t: "⠌⠈⠢"] # 0x220c - - "∍": [t: "⠈⠢"] # 0x220d - - "∎": [t: "⠸⠳"] # 0x220e - - "−": [t: "⠤"] # 0x2212 - - "∓": [t: "⠤⠬"] # 0x2213 - - "∕": [t: "⠸⠌"] # 0x2215 - - "∖": [t: "⠸⠡"] # 0x2216 - - "∗": [t: "⠈⠼"] # 0x2217 - - "∘": [t: "⠨⠡"] # 0x2218 - - "∝": [t: "⠸⠿"] # 0x221d - - "∞": [t: "⠠⠿"] # 0x221e - - "∟": [t: "⠫⠪⠨⠗⠻"] # 0x221f - - "∠": [t: "⠫⠪"] # 0x2220 - - "∢": [t: "⠫⠪⠸⠫⠫⠁⠻"] # 0x2222 - - "∣": [t: "⠳"] # 0x2223 - - "∤": [t: "⠌⠳"] # 0x2224 - - "∥": [t: "⠫⠇"] # 0x2225 - - "∦": [t: "⠌⠫⠇"] # 0x2226 - - "∧": [t: "⠈⠩"] # 0x2227 - - "∨": [t: "⠈⠬"] # 0x2228 - - "∩": [t: "⠨⠩"] # 0x2229 - - "∪": [t: "⠨⠬"] # 0x222a - - "∫": [t: "⠮"] # 0x222b - - "∬": [t: "⠮⠮"] # 0x222c - - "∭": [t: "⠮⠮⠮"] # 0x222d - - "∮": [t: "⠮⠈⠫⠉⠻"] # 0x222e - - "∲": [t: "⠮⠈⠫⠪⠢⠔⠻"] # 0x2232 - - "∳": [t: "⠮⠈⠫⠢⠔⠕⠻"] # 0x2233 - - "∴": [t: "⠠⠡"] # 0x2234 - - "∵": [t: "⠈⠌"] # 0x2235 - - "∶": [t: "⠐⠂"] # 0x2236 - - "∷": [t: "⠰⠆"] # 0x2237 - - "∸": [t: "⠨⠤"] # 0x2238 - - "∼": [t: "⠈⠱"] # 0x223c - - "≁": [t: "⠌⠈⠱"] # 0x2241 - - "≂": [t: "⠱⠈⠱"] # 0x2242 - - "≃": [t: "⠈⠱⠱"] # 0x2243 - - "≄": [t: "⠌⠈⠱⠱"] # 0x2244 - - "≅": [t: "⠈⠱⠨⠅"] # 0x2245 - - "≆": [t: "⠈⠱⠌⠨⠅"] # 0x2246 - - "≇": [t: "⠌⠈⠱⠨⠅"] # 0x2247 - - "≈": [t: "⠈⠱⠈⠱"] # 0x2248 - - "≉": [t: "⠌⠈⠱⠈⠱"] # 0x2249 - - "≊": [t: "⠈⠱⠈⠱⠱"] # 0x224a - - "≍": [t: "⠈⠣⠠⠣"] # 0x224d - - "≎": [t: "⠈⠣⠠⠣"] # 0x224e - - "≐": [t: "⠐⠨⠅⠣⠡⠻"] # 0x2250 - - "≑": [t: "⠐⠨⠅⠩⠡⠣⠡⠻"] # 0x2251 - - "≗": [t: "⠐⠨⠅⠣⠨⠡⠻"] # 0x2257 - - "≘": [t: "⠐⠨⠅⠣⠫⠁⠻"] # 0x2258 - - "≙": [t: "⠐⠨⠅⠣⠸⠣⠻"] # 0x2259 - - "≚": [t: "⠐⠨⠅⠣⠸⠩⠻"] # 0x225a - - "≛": [t: "⠐⠨⠅⠣⠫⠸⠎⠻"] # 0x225b - - "≜": [t: "⠐⠨⠅⠣⠫⠞⠻"] # 0x225c - - "≝": [t: "⠐⠨⠅⠣⠙⠑⠋⠻"] # 0x225d - - "≞": [t: "⠐⠨⠅⠣⠍⠻"] # 0x225e - - "≟": [t: "⠐⠨⠅⠣⠸⠦⠻"] # 0x225f - - "≠": [t: "⠌⠨⠅"] # 0x2260 - - "≢": [t: "⠌⠸⠇"] # 0x2262 - - "≤": [t: "⠐⠅⠱"] # 0x2264 - - "≥": [t: "⠨⠂⠱"] # 0x2265 - - "≦": [t: "⠐⠅⠨⠅"] # 0x2266 - - "≧": [t: "⠨⠂⠨⠅"] # 0x2267 - - "≨": [t: "⠐⠅⠌⠨⠅"] # 0x2268 - - "≩": [t: "⠨⠂⠌⠨⠅"] # 0x2269 - - "≪": [t: "⠐⠅⠈⠐⠅⠻"] # 0x226a - - "≫": [t: "⠨⠂⠈⠨⠂⠻"] # 0x226b - - "≭": [t: "⠌⠈⠣⠠⠣"] # 0x226d - - "≮": [t: "⠌⠐⠅"] # 0x226e - - "≯": [t: "⠌⠨⠂"] # 0x226f - - "≰": [t: "⠌⠐⠅⠱"] # 0x2270 - - "≱": [t: "⠌⠨⠂⠱"] # 0x2271 - - "≲": [t: "⠐⠅⠈⠱"] # 0x2272 - - "≳": [t: "⠨⠂⠈⠱"] # 0x2273 - - "≴": [t: "⠌⠐⠅⠈⠱"] # 0x2274 - - "≵": [t: "⠌⠨⠂⠈⠱"] # 0x2275 - - "≶": [t: "⠐⠅⠨⠂"] # 0x2276 - - "≷": [t: "⠨⠂⠐⠅"] # 0x2277 - - "≸": [t: "⠌⠐⠅⠨⠂"] # 0x2278 - - "≹": [t: "⠌⠨⠂⠐⠅"] # 0x2279 - - "≺": [t: "⠨⠐⠅"] # 0x227a - - "≻": [t: "⠨⠨⠂"] # 0x227b - - "≼": [t: "⠨⠐⠅⠱"] # 0x227c - - "≽": [t: "⠨⠨⠐⠱"] # 0x227d - - "≾": [t: "⠨⠐⠅⠈⠱"] # 0x227e - - "≿": [t: "⠨⠨⠂⠈⠱"] # 0x227f - - "⊀": [t: "⠌⠨⠐⠅"] # 0x2280 - - "⊁": [t: "⠌⠨⠐⠅"] # 0x2281 - - "⊂": [t: "⠸⠐⠅"] # 0x2282 - - "⊃": [t: "⠸⠨⠂"] # 0x2283 - - "⊄": [t: "⠌⠸⠐⠅"] # 0x2284 - - "⊅": [t: "⠌⠸⠨⠂"] # 0x2285 - - "⊆": [t: "⠸⠐⠅⠱"] # 0x2286 - - "⊇": [t: "⠸⠨⠂⠱"] # 0x2287 - - "⊈": [t: "⠌⠸⠐⠅⠱"] # 0x2288 - - "⊉": [t: "⠌⠸⠨⠂⠱"] # 0x2289 - - "⊊": [t: "⠸⠐⠅⠌⠨⠅"] # 0x228a - - "⊋": [t: "⠸⠨⠂⠌⠨⠅"] # 0x228b - - "⊥": [t: "⠫⠏"] # 0x22a5 - - "⋀": [t: "⠈⠩"] # 0x22c0 - - "⋁": [t: "⠈⠬"] # 0x22c1 - - "⋂": [t: "⠨⠩"] # 0x22c2 - - "⋃": [t: "⠨⠬"] # 0x22c3 - - "⋄": [t: "⠫⠩"] # 0x22c4 - - "⋜": [t: "⠱⠐⠅"] # 0x22dc - - "⋝": [t: "⠱⠨⠂"] # 0x22dd - - "⟂": [t: "⠫⠏"] # 0x27c2 - - "⦀": [t: "⠳⠳⠳"] # 0x2980 - - "⦶": [t: "⠫⠉⠸⠫⠳⠻"] # 0x29b6 - - "⦷": [t: "⠫⠉⠸⠫⠫⠇⠻"] # 0x29b7 - - "⦸": [t: "⠫⠉⠸⠫⠸⠡⠻"] # 0x29b8 - - "⦹": [t: "⠫⠉⠸⠫⠫⠏⠻"] # 0x29b9 - - "⦿": [t: "⠫⠉⠸⠫⠔⠔⠻"] # 0x29bf - - "⧀": [t: "⠫⠉⠸⠫⠐⠅⠻"] # 0x29c0 - - "⧁": [t: "⠫⠉⠸⠫⠨⠂⠻"] # 0x29c1 - - "⨀": [t: "⠫⠉⠸⠫⠡⠻"] # 0x2a00 - - "⨁": [t: "⠫⠉⠸⠫⠬⠻"] # 0x2a01 - - "⨂": [t: "⠫⠉⠸⠫⠈⠡⠻"] # 0x2a02 - - "⪯": [t: "⠨⠐⠅⠱"] # 0x2aaf - - "⪰": [t: "⠨⠨⠂⠱"] # 0x2ab0 - - "⪱": [t: "⠨⠐⠅⠌⠱"] # 0x2ab1 - - "⪲": [t: "⠨⠨⠂⠌⠱"] # 0x2ab2 - - "⪳": [t: "⠨⠐⠅⠨⠅"] # 0x2ab3 - - "⪴": [t: "⠨⠨⠂⠨⠅"] # 0x2ab4 - - "⪵": [t: "⠨⠐⠅⠌⠨⠅"] # 0x2ab5 - - "⪶": [t: "⠨⠨⠂⠌⠨⠅"] # 0x2ab6 - - "⪷": [t: "⠨⠐⠅⠈⠱⠈⠱"] # 0x2ab7 - - "⪸": [t: "⠨⠨⠂⠈⠱⠈⠱"] # 0x2ab8 - - "⪹": [t: "⠨⠐⠅⠌⠈⠱⠈⠱"] # 0x2ab9 - - "⪺": [t: "⠨⠨⠂⠌⠈⠱⠈⠱"] # 0x2aba - - "⪻": [t: "⠨⠐⠅⠈⠨⠐⠅⠻"] # 0x2abb - - "⪼": [t: "⠨⠨⠂⠈⠨⠨⠂⠻"] # 0x2abc - - "﹩": [t: "⠈⠎"] # 0xfe69 - - "$": [t: "⠈⠎"] # 0xff04 - - "_": [t: "⠱"] # 0xff3f - - "~": [t: "⠈⠱"] # 0xff5e - - "¢": [t: "⠈⠉"] # 0xffe0 - - "£": [t: "⠈⠇"] # 0xffe1 - - " ̄": [t: "⠱"] # 0xffe3 - - "¥": [t: "⠈⠽"] # 0xffe5 - - # --- Nemeth Default Characters rest chars. --- - - - "ℵ": [t: "⠠⠠⠁"] # 0x2135 - - "ℶ": [t: "⠠⠠⠃"] # 0x2136 - - "ℷ": [t: "⠠⠠⠉"] # 0x2137 - - "ℸ": [t: "⠠⠠⠙"] # 0x2138 - - "à": [t: "⠈⠁"] # 0xe0 - - "á": [t: "⠈⠁"] # 0xe1 - - "â": [t: "⠈⠁"] # 0xe2 - - "ã": [t: "⠈⠁"] # 0xe3 - - "ä": [t: "⠈⠁"] # 0xe4 - - "å": [t: "⠈⠁"] # 0xe5 - - "ç": [t: "⠈⠉"] # 0xe7 - - "è": [t: "⠈⠑"] # 0xe8 - - "é": [t: "⠈⠑"] # 0xe9 - - "ê": [t: "⠈⠑"] # 0xea - - "ë": [t: "⠈⠑"] # 0xeb - - "ì": [t: "⠈⠊"] # 0xec - - "í": [t: "⠈⠊"] # 0xed - - "î": [t: "⠈⠊"] # 0xee - - "ï": [t: "⠈⠊"] # 0xef - - "ñ": [t: "⠈⠝"] # 0xf1 - - "ò": [t: "⠈⠕"] # 0xf2 - - "ó": [t: "⠈⠕"] # 0xf3 - - "ô": [t: "⠈⠕"] # 0xf4 - - "õ": [t: "⠈⠕"] # 0xf5 - - "ö": [t: "⠈⠕"] # 0xf6 - - "ù": [t: "⠈⠥"] # 0xf9 - - "ú": [t: "⠈⠥"] # 0xfa - - "û": [t: "⠈⠥"] # 0xfb - - "ü": [t: "⠈⠥"] # 0xfc - - "ý": [t: "⠈⠽"] # 0xfd - - "ÿ": [t: "⠈⠽"] # 0xff - - - "À": [t: "⠠⠈⠁"] # 0xc0 - - "Á": [t: "⠠⠈⠁"] # 0xc1 - - "Â": [t: "⠠⠈⠁"] # 0xc2 - - "Ã": [t: "⠠⠈⠁"] # 0xc3 - - "Ä": [t: "⠠⠈⠁"] # 0xc4 - - "Å": [t: "⠠⠈⠁"] # 0xc5 - - "Ç": [t: "⠠⠈⠉"] # 0xc7 - - "È": [t: "⠠⠈⠑"] # 0xc8 - - "É": [t: "⠠⠈⠑"] # 0xc9 - - "Ê": [t: "⠠⠈⠑"] # 0xca - - "Ë": [t: "⠠⠈⠑"] # 0xcb - - "Ì": [t: "⠠⠈⠊"] # 0xcc - - "Í": [t: "⠠⠈⠊"] # 0xcd - - "Î": [t: "⠠⠈⠊"] # 0xce - - "Ï": [t: "⠠⠈⠊"] # 0xcf - - "Ñ": [t: "⠠⠈⠝"] # 0xd1 - - "Ò": [t: "⠠⠈⠕"] # 0xd2 - - "Ó": [t: "⠠⠈⠕"] # 0xd3 - - "Ô": [t: "⠠⠈⠕"] # 0xd4 - - "Ö": [t: "⠠⠈⠕"] # 0xd6 - - "Ù": [t: "⠠⠈⠥"] # 0xd9 - - "Ú": [t: "⠠⠈⠥"] # 0xda - - "Û": [t: "⠠⠈⠥"] # 0xdb - - "Ü": [t: "⠠⠈⠥"] # 0xdc - - "Ý": [t: "⠠⠈⠽"] # 0xdd - - "←": [t: "⠫⠪⠒⠒"] # 0x2190 - - - "↑": # 0x2191 - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠣"] - else: [t: "⠫⠣⠒⠒⠕"] - - - "↓": # 0x2193 - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠩"] - else: [t: "⠫⠩⠒⠒⠕"] - - - "↔": [t: "⠫⠪⠒⠒⠕"] # 0x2194 - - "↕": [t: "⠫⠣⠩⠪⠒⠒⠕"] # 0x2195 - - "↖": [t: "⠫⠘⠪⠒⠒"] # 0x2196 - - "↗": [t: "⠫⠘⠒⠒⠕"] # 0x2197 - - "↘": [t: "⠫⠰⠒⠒⠕"] # 0x2198 - - "↙": [t: "⠫⠰⠪⠒⠒"] # 0x2199 - - "↚": [t: "⠳⠈⠫⠪⠒⠒⠻"] # 0x219a - - "↛": [t: "⠳⠈⠫⠒⠒⠕⠻"] # 0x219b - - "↜": [t: "⠫⠪⠔⠒⠢"] # 0x219c - - "↝": [t: "⠫⠔⠒⠢⠕"] # 0x219d - - "↞": [t: "⠫⠪⠪⠒⠒"] # 0x219e - - "↟": [t: "⠫⠣⠒⠒⠕⠕"] # 0x219f - - "↠": [t: "⠫⠒⠒⠕⠕"] # 0x21a0 - - "↡": [t: "⠫⠩⠒⠒⠕⠕"] # 0x21a1 - - "↢": [t: "⠫⠪⠒⠒⠠⠽"] # 0x21a2 - - "↣": [t: "⠫⠠⠯⠒⠒⠕"] # 0x21a3 - - "↤": [t: "⠫⠪⠒⠒⠳"] # 0x21a4 - - "↥": [t: "⠫⠣⠳⠒⠒⠕"] # 0x21a5 - - "↦": [t: "⠫⠳⠒⠒⠕"] # 0x21a6 - - "↧": [t: "⠫⠩⠳⠒⠒⠕"] # 0x21a7 - - "↨": [t: "⠫⠪⠒⠳⠒⠕"] # 0x21a8 - - "↩": [t: "⠫⠪⠒⠒⠠⠕"] # 0x21a9 - - "↪": [t: "⠫⠠⠪⠒⠒⠕"] # 0x21aa - - "↫": [t: "⠫⠪⠒⠒⠨⠡"] # 0x21ab - - "↬": [t: "⠫⠨⠡⠒⠒⠕"] # 0x21ac - - "↭": [t: "⠫⠪⠔⠒⠢⠕"] # 0x21ad - - "↮": [t: "⠳⠈⠫⠪⠒⠒⠕"] # 0x21ae - - "↯": [t: "⠫⠩⠔⠢⠔"] # 0x21af - - "↴": [t: "⠫⠠⠳⠒⠒⠕"] # 0x21b4 - - "↵": [t: "⠫⠩⠠⠳⠒⠒⠕"] # 0x21b5 - - "↶": [t: "⠫⠢⠔⠕"] # 0x21b6 - - "↷": [t: "⠫⠪⠢⠔"] # 0x21b7 - - "↺": [t: "⠫⠢⠔⠕"] # 0x21ba - - "↻": [t: "⠫⠪⠢⠔"] # 0x21bb - - "⇄": [t: "⠫⠒⠒⠕⠫⠪⠒⠒"] # 0x21c4 - - "⇅": [t: "⠫⠣⠒⠒⠕⠐⠫⠩⠒⠒⠕"] # 0x21c5 - - "⇆": [t: "⠫⠪⠒⠒⠫⠒⠒⠕"] # 0x21c6 - - "⇇": [t: "⠫⠚⠒⠒⠫⠚⠒⠒"] # 0x21c7 - - "⇈": [t: "⠫⠣⠒⠒⠕⠐⠫⠣⠒⠒⠕"] # 0x21c8 - - "⇉": [t: "⠫⠒⠒⠕⠫⠒⠒⠕"] # 0x21c9 - - "⇊": [t: "⠫⠩⠒⠒⠕⠐⠫⠩⠒⠒⠕"] # 0x21ca - - "⇍": [t: "⠳⠈⠫⠪⠪⠒⠒"] # 0x21cd - - "⇎": [t: "⠳⠈⠫⠪⠪⠒⠒⠕⠕"] # 0x21ce - - "⇏": [t: "⠳⠈⠫⠒⠒⠕⠕"] # 0x21cf - - "⇐": [t: "⠫⠪⠶⠶"] # 0x21d0 - - "⇑": [t: "⠫⠣⠶⠶⠕"] # 0x21d1 - - "⇒": [t: "⠫⠶⠶⠕"] # 0x21d2 - - "⇓": [t: "⠫⠣⠶⠶⠕"] # 0x21d3 - - "⇔": [t: "⠫⠪⠶⠶⠕"] # 0x21d4 - - "⇕": [t: "⠫⠣⠪⠶⠶⠕"] # 0x21d5 - - "⇖": [t: "⠫⠘⠪⠶⠶"] # 0x21d6 - - "⇗": [t: "⠫⠘⠶⠶⠕"] # 0x21d7 - - "⇘": [t: "⠫⠰⠶⠶⠕"] # 0x21d8 - - "⇙": [t: "⠫⠰⠪⠪⠒⠒"] # 0x21d9 - - "⇚": [t: "⠫⠪⠪⠶⠶"] # 0x21da FIX: how to represent triple shafts? - - "⇛": [t: "⠫⠶⠶⠕⠕"] # 0x21db FIX: how to represent triple shafts? - - "⇜": [t: "⠫⠪⠢⠤⠔⠒⠢"] # 0x21dc - - "⇝": [t: "⠫⠢⠤⠔⠒⠢⠕"] # 0x21dd - - "⇞": [t: "⠳⠳⠈⠫⠣⠒⠒⠕⠻"] # 0x21de - - "⇟": [t: "⠳⠳⠈⠫⠩⠒⠒⠕⠻"] # 0x21df - - "⇠": [t: "⠫⠪⠒⠒"] # 0x21e0 - - "⇡": [t: "⠫⠣⠒⠒⠕"] # 0x21e1 - - "⇢": [t: "⠫⠒⠒⠕"] # 0x21e2 - - "⇣": [t: "⠫⠩⠒⠒⠕"] # 0x21e3 - - "⇤": [t: "⠫⠳⠪⠒⠒"] # 0x21e4 - - "⇥": [t: "⠫⠒⠒⠕⠳"] # 0x21e5 - - "⇦": [t: "⠫⠸⠪⠒⠒"] # 0x21e6 - - "⇧": [t: "⠫⠣⠸⠒⠒⠕"] # 0x21e7 - - "⇨": [t: "⠫⠸⠒⠒⠕"] # 0x21e8 - - "⇩": [t: "⠫⠩⠸⠒⠒⠕"] # 0x21e9 - - "⇳": [t: "⠫⠣⠸⠪⠒⠒⠕"] # 0x21f3 - - "⇴": [t: "⠫⠒⠒⠕⠨⠡"] # 0x21f4 - - "⇵": [t: "⠫⠩⠒⠒⠕⠐⠫⠣⠒⠒⠕"] # 0x21f5 - - "⇶": [t: "⠫⠒⠒⠕⠫⠒⠒⠕⠫⠒⠒⠕"] # 0x21f6 - - "⇷": [t: "⠳⠈⠫⠪⠒⠒⠻"] # 0x21f7 - - "⇸": [t: "⠳⠈⠫⠒⠒⠕⠻"] # 0x21f8 - - "⇹": [t: "⠳⠈⠫⠪⠒⠒⠕"] # 0x21f9 - - "⇺": [t: "⠳⠳⠈⠫⠪⠒⠒⠻"] # 0x21fa - - "⇻": [t: "⠳⠳⠈⠫⠒⠒⠕⠻"] # 0x21fb - - "⇼": [t: "⠳⠳⠈⠫⠪⠒⠒⠕"] # 0x21fc - - "⇽": [t: "⠫⠳⠒⠒"] # 0x21fd - - "⇾": [t: "⠫⠒⠒⠳"] # 0x21fe - - "⇿": [t: "⠫⠳⠒⠒⠳"] # 0x21ff - - - "ⅆ": [t: "⠙"] # 0x2146 - - "ⅇ": [t: "⠑"] # 0x2147 - - "ⅈ": [t: "⠊"] # 0x2148 - - "⌜": [t: "⠈⠘⠷"] # 0x231c - - "⌝": [t: "⠈⠘⠾"] # 0x231d - - "⌞": [t: "⠈⠰⠷"] # 0x231e - - "⌟": [t: "⠈⠰⠾"] # 0x231f - - "〈": [t: "⠨⠨⠷"] # 0x2329 - - "〉": [t: "⠨⠨⠾"] # 0x232a - - "⏞": [t: "⠨⠷"] # 0x23de - - "⏟": [t: "⠨⠾"] # 0x23df - - "⎴": [t: "⠈⠷"] # 0x23b4 - - "⎵": [t: "⠈⠾"] # 0x23b5 - - "⟪": [t: "⠨⠨⠨⠷"] # 0x27ea - - "⟫": [t: "⠨⠨⠨⠾"] # 0x27eb - - "〈": [t: "⠨⠨⠷"] # 0x3008 - - "〉": [t: "⠨⠨⠾"] # 0x3009 - - "《": [t: "⠨⠨⠨⠷"] # 0x300a - - "》": [t: "⠨⠨⠨⠾"] # 0x300b - - "「": [t: "⠈⠘⠷"] # 0x300c - - "」": [t: "⠈⠘⠾"] # 0x300d - - "↼": [t: "⠫⠈⠪⠒⠒"] # 0x21bc - - "↽": [t: "⠫⠠⠪⠒⠒"] # 0x21bd - - "↾": [t: "⠫⠣⠒⠒⠠⠕"] # 0x21be - - "↿": [t: "⠫⠣⠒⠒⠈⠕"] # 0x21bf - - "⇀": [t: "⠫⠒⠒⠈⠕"] # 0x21c0 - - "⇁": [t: "⠫⠒⠒⠠⠕"] # 0x21c1 - - "⇂": [t: "⠫⠪⠒⠒⠈⠕"] # 0x21c2 - - "⇃": [t: "⠫⠩⠒⠒⠠⠕"] # 0x21c3 - - "⇋": # 0x21cb - - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠪⠒⠫⠒⠕"] - else: [t: "⠫⠈⠪⠒⠒⠫⠒⠒⠈⠕"] - - "⇌": # 0x21cc - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠕⠫⠪⠒"] - else: [t: "⠫⠒⠒⠈⠕⠫⠈⠪⠒⠒"] - - - "℔": [t: "⠳"] # 0x2114 - - "™": [t: "⠘⠞"] # 0x2122 - - "Å": [t: "⠈⠠⠁"] # 0x212b - - "­": [t: "⠤"] # 0xad - - " ": [t: "W"] # 0x2000 - - " ": [t: "W"] # 0x2001 - - " ": [t: "W"] # 0x2002 - - " ": [t: "W"] # 0x2003 - - " ": [t: "W"] # 0x2004 - - " ": [t: "W"] # 0x2005 - - " ": [t: "W"] # 0x2006 - - " ": [t: "W"] # 0x2007 - - " ": [t: "W"] # 0x2008 - - " ": [t: "W"] # 0x2009 - - " ": [t: "W"] # 0x200a - - "​": [t: "W"] # 0x200b - - "
": [t: "W"] # 0x2028 - - "
": [t: "W"] # 0x2029 - - " ": [t: "W"] # 0x202f - - " ": [t: "W"] # 0x205f - - "₣": [t: "⠈⠋"] # 0x20A3 (French franc sign - - "₦": [t: "⠈⠝"] # 0x2046 (Naira sign) - - "₩": [t: "⠈⠺"] # 0x20A9 (Won sign) - - "€": [t: "⠈⠑"] # 0x20AC (Euro sign) - - "": [t: "W"] # 0xfeff - - "☆": [t: "⠫⠎"] # 0x2606 - - "✕": [t: "⠈⠡"] # 0x2715 - - "¼": [t: "⠹⠂⠌⠲⠼"] # 0xbc - - "½": [t: "⠹⠂⠌⠆⠼"] # 0xbd - - "¾": [t: "⠹⠒⠌⠲⠼"] # 0xbe - - "⅐": [t: "⠹⠂⠌⠶⠼"] # 0x2150 - - "⅑": [t: "⠹⠂⠌⠔⠼"] # 0x2151 - - "⅒": [t: "⠹⠂⠌⠂⠴⠼"] # 0x2152 - - "⅓": [t: "⠹⠂⠌⠒⠼"] # 0x2153 - - "⅔": [t: "⠹⠆⠌⠒⠼"] # 0x2154 - - "⅕": [t: "⠹⠂⠌⠢⠼"] # 0x2155 - - "⅖": [t: "⠹⠆⠌⠢⠼"] # 0x2156 - - "⅗": [t: "⠹⠒⠌⠢⠼"] # 0x2157 - - "⅘": [t: "⠹⠲⠌⠢⠼"] # 0x2158 - - "⅙": [t: "⠹⠂⠌⠖⠼"] # 0x2159 - - "⅚": [t: "⠹⠢⠌⠖⠼"] # 0x215a - - "⅛": [t: "⠹⠂⠌⠦⠼"] # 0x215b - - "⅜": [t: "⠹⠒⠌⠦⠼"] # 0x215c - - "⅝": [t: "⠹⠢⠌⠦⠼"] # 0x215d - - "⅞": [t: "⠹⠶⠌⠦⠼"] # 0x215e - - "⅟": [t: "⠹⠂⠌⠼"] # 0x215f - - "↉": [t: "⠹⠴⠌⠒⠼"] # 0x2189 - - "㉈": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠂⠴⠻⠻"] # 0x3248 - - "㉉": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠆⠴⠻⠻"] # 0x3249 - - "㉊": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠒⠴⠻⠻"] # 0x324a - - "㉋": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠲⠴⠻⠻"] # 0x324b - - "㉌": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠢⠴⠻⠻"] # 0x324c - - "㉍": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠖⠴⠻⠻"] # 0x324d - - "㉎": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠶⠴⠻⠻"] # 0x324e - - "㉏": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠦⠴⠻⠻"] # 0x324f - - - - "‘": [t: "P⠠⠦"] # 0x2018 (Left single quotation mark) - - "’": [t: "P⠠⠴"] # 0x2019 (Right single quotation mark) - - "“": [t: "P⠦"] # 0x201C (Left double quotation mark) - - "”": [t: "P⠴"] # 0x201D (Right double quotation mark) - - "‰": [t: "`00"] - - "ℏ": [t: "⠈⠓"] # 0x210F (Planck constant over two pi) - - "ℓ": [t: "TE⠇"] # 0x2113 (Script small l (differs from 1d4c1: 4-56-123)) - - "℘": [tc: "TCL⠏"] # 0x2118 (Script Capital P) -# - "ℝ": [t: ""] # 0x211D (Double-struck capital R (no nemeth double struck)) -# - "ⅆ": [t: ""] # 0x2146 (Double-struck italic small d) -# - "ⅇ": [t: ""] # 0x2147 (Double-struck italic small e) -# - "⇚": [t: "⠀⠫⠪⠸⠸⠀"] # 0x21DA (Leftwards triple arrow) -# - "⇛": [t: "⠀⠫⠸⠸⠕⠀"] # 0x21DB (Rightwards triple arrow) - - "∔": [t: "⠐⠬⠣⠡⠻"] # 0x2214 (Dot plus) - - "√": [t: "⠜"] # 0x221A (Square root) - - "∛": [t: "⠣⠒⠜"] # 0x221B (Cube root) - - "∜": [t: "⠣⠲⠜"] # 0x221C (Fourth root) - - "∡": [t: "⠫⠪⠸⠫⠫⠁⠻"] # 0x2221 (Measured angle) - - "∹": [t: "⠤⠐⠂"] # 0x2239 (Excess) - - "∺": [t: "⠐⠤⠩⠡⠡⠣⠡⠡⠻"] # 0x223A (Geometric proportion) - - "∻": [t: "⠐⠈⠱⠩⠡⠣⠡⠻"] # 0x223B (Homothetic) - - "∽": [t: "⠠⠱"] # 0x223D (Reversed tilde) - - "≋": [t: "⠈⠱⠈⠱⠈⠱"] # 0x224B (Triple tilde) - - "≌": [t: "⠠⠱⠨⠅"] # 0x224C (All equal to) - - "≏": [t: "⠈⠣⠱"] # 0x224F (Difference between) - - "≔": [t: "⠐⠂⠨⠅"] # 0x2254 (Colon equals) - - "≕": [t: "⠨⠅⠐⠂"] # 0x2255 (Equals colon) - - "≖": [t: "⠀⠨⠡⠈⠨⠅⠻⠀"] # 0x2256 (Ring in equal to) - - "⊌": [t: "⠨⠬⠈⠫⠪⠒⠻"] # 0x228C (Multiset) - - "⊍": [t: "⠡⠈⠨⠬⠻"] # 0x228D (Multiset multiplication) - - "⊎": [t: "⠬⠈⠨⠬⠻"] # 0x228E (Multiset union) - - "⊕": [t: "⠫⠉⠸⠫⠬⠻"] # 0x2295 (Circled plus) - - "⊖": [t: "⠫⠉⠸⠫⠤⠻"] # 0x2296 (Circled minus) - - "⊗": [t: "⠫⠉⠸⠫⠈⠡⠻"] # 0x2297 (Circled times) - - "⊘": [t: "⠫⠉⠸⠫⠸⠌⠻"] # 0x2298 (Circled division slash) - - "⊙": [t: "⠫⠉⠸⠫⠡⠻"] # 0x2299 (Circled dot operator) - - "⊚": [t: "⠫⠉⠸⠫⠘⠨⠡⠻"] # 0x229a (Circled ring operator) - - "⊛": [t: "⠫⠉⠸⠫⠈⠼⠻"] # 0x229B (Circled asterisk operator) - - "⊜": [t: "⠫⠉⠸⠫⠨⠅⠻"] # 0x229C (Circled equals) - - "⊝": [t: "⠫⠉⠸⠫⠤⠤⠻"] # 0x229D (Circled dash) - - "⊞": [t: "⠫⠲⠸⠫⠬⠻"] # 0x229E (Squared plus) - - "⊟": [t: "⠫⠲⠸⠫⠤⠻"] # 0x229F (Squared minus) - - "⊠": [t: "⠫⠲⠸⠫⠈⠡⠻"] # 0x22A0 (Squared times) - - "⊡": [t: "⠫⠲⠸⠫⠡⠻"] # 0x22A1 (Squared dot operator) - - "⊢": [t: "⠫⠳⠒"] # 0x22A2 (Right tack) - - "⊣": [t: "⠫⠒⠳"] # 0x22A3 (Left tack) - - "⊤": [t: "⠫⠩⠳⠒"] # 0x22A4 (Down tack) -# - "⊥": [t: "⠀⠫⠏⠀ or ⠀⠫⠣⠳⠒⠀"] # 0x22A5 (Up tack (See also 27C2)) -# - "⊦": [t: ""] # 0x22A6 (Assertion) -# - "⊨": [t: ""] # 0x22A8 (TRUE) -# - "⊲": [t: ""] # 0x22B2 (Normal subgroup of) -# - "⊳": [t: ""] # 0x22B3 (Contains as normal subgroup) -# - "⊴": [t: ""] # 0x22B4 (Normal subgroup of or equal to) -# - "⊵": [t: ""] # 0x22B5 (Contains as normal subgroup or equal to) - - "⊶": [t: "⠫⠨⠡⠒⠡"] # 0x22B6 (Original of) - - "⊷": [t: "⠫⠡⠒⠨⠡"] # 0x22B7 (Image of) - - "⊸": [t: "⠫⠒⠨⠡"] # 0x22B8 (Multimap) -# - "⊾": [t: ""] # 0x22BE (Right angle w arc) - - "⊿": [t: "⠫⠞⠨⠗⠻"] # 0x22BF (Right triangle) - - "⋅": [t: "⠡"] # 0x22C5 (Dot operator) - - "∙": [t: "⠡"] # 0x2219 -- similar looking to 0x22c5, so using the same braille - - "⋆": [t: "⠫⠎"] # 0x22C6 (Star operator) - - "⋍": [t: "⠠⠱⠱"] # 0x22CD (Reversed tilde equals) - - "⋖": [t: "⠡⠈⠐⠅⠻"] # 0x22D6 (Less-than w dot) - - "⋗": [t: "⠡⠈⠨⠂⠻"] # 0x22D7 (Greater-than w dot) - - "⋘": [t: "⠐⠅⠈⠐⠅⠈⠐⠅⠻"] # 0x22D8 (Much less-than) - - "⋙": [t: "⠨⠂⠈⠨⠂⠈⠨⠂⠻"] # 0x22D9 (Much greater-than) - - "⋲": [t: "⠱⠈⠈⠑⠻"] # 0x22F2 (Element of w long horizontal stroke) - - "⋵": [t: "⠐⠈⠑⠣⠡⠻"] # 0x22F5 (Element of w dot above) - - "⋶": [t: "⠱⠈⠑"] # 0x22F6 (Element of w overbar) - - "⋺": [t: "⠱⠈⠈⠢⠻"] # 0x22FA (Contains w long horizontal stroke) - - "⋽": [t: "⠱⠈⠢"] # 0x22FD (Contains w overbar) - - "⌈": [t: "⠈⠘⠷"] # 0x2308 (Left ceiling) - - "⌉": [t: "⠈⠘⠾"] # 0x2309 (Right ceiling) - - "⌊": [t: "⠈⠰⠷"] # 0x230A (Left floor) - - "⌋": [t: "⠈⠰⠾"] # 0x230B (Right floor) - - "⌢": [t: "⠫⠁"] # 0x2322 (Frown) - - "⌣": [t: "⠫⠄"] # 0x2323 (Smile) - - "■": [t: "⠫⠸⠲"] # 0x25A0 (Filled square) - - "▫": [t: "⠫⠲"] # 0x25AB (Small white Square) - - "□": [t: "⠫⠲"] # 0x25A1 (Square) - - "◻": [t: "⠫⠲"] # 0x25FB (Square) - - "▬": [t: "⠫⠸⠗"] # 0x25AC (Filled rectangle) - - "▭": [t: "⠫⠗"] # 0x25AD (Rectangle) - - "▲": [t: "⠫⠸⠞"] # 0x25B2 (Black up-pointing triangle) - - "△": [t: "⠫⠞"] # 0x25B3 (White up-pointing triangle) - - "▼": [t: "⠸⠨⠫"] # 0x25BC (Black down-pointing triangle) - - "○": [t: "⠫⠉"] # 0x25CB (White circle) - - "●": [t: "⠫⠸⠉"] # 0x25CF (Black circle) - - "◫": [t: "⠫⠲⠸⠫⠳⠻"] # 0x25EB (White square w vertical bisecting line) -# - "⊥": [t: "⠫⠏"] # 0x27C2 (Perpendicular) - - "⟃": [t: "⠨⠡⠈⠸⠐⠅⠻"] # 0x27C3 (Open subset) - - "⟄": [t: "⠨⠡⠈⠸⠨⠂⠻"] # 0x27C4 (Open superset) - - "⟜": [t: "⠫⠨⠡⠒⠒"] # 0x27DC (Left multimap) - - "⟝": [t: "⠫⠳⠒⠒"] # 0x27DD (Long right tack) - - "⟞": [t: "⠫⠒⠒⠳"] # 0x27DE (Long left tack) - - "⟟": [t: "⠫⠣⠳⠒⠒⠨⠡"] # 0x27DF (Up tack w circle above) - - "⟦": [t: "⠈⠸⠷"] # 0x27E6 (Mathematical left white square bracket) - - "⟧": [t: "⠈⠸⠾"] # 0x27E7 (Mathematical right white square bracket) - - "⟨": [t: "⠨⠨⠷"] # 0x27E8 (Mathematical left angle bracket) - - "⟩": [t: "⠨⠨⠾"] # 0x27E9 (Mathematical right angle bracket) - - "⟵": [t: "⠀⠫⠪⠒⠒⠒⠀"] # 0x27F5 (Long leftwards arrow ) - - "⟶": [t: "⠀⠫⠒⠒⠒⠕⠀"] # 0x27F6 (Long rightwards arrow) - - "⟷": [t: "⠀⠫⠪⠒⠒⠒⠕⠀"] # 0x27F7 (Long left right arrow) - - "⟸": [t: "⠀⠫⠪⠶⠶⠶⠀"] # 0x27F8 (Long leftwards arrow ) - - "⟹": [t: "⠀⠫⠶⠶⠶⠕⠀"] # 0x27F9 (Long rightwards arrow) - - "⟺": [t: "⠀⠫⠪⠶⠶⠶⠕⠀"] # 0x27FA (Long left right arrow) - - "⟻": [t: "⠀⠫⠪⠒⠒⠒⠳⠀"] # 0x27FB (Long leftwards arrow from bar) - - "⟼": [t: "⠀⠫⠳⠒⠒⠒⠕⠀"] # 0x27FC (Long rightwards arrow from bar) - - "⟽": [t: "⠀⠫⠪⠶⠶⠶⠳⠀"] # 0x27FD (Long leftwards double arrow from bar) - - "⟾": [t: "⠀⠫⠳⠶⠶⠶⠕⠀"] # 0x27FE (Long rightwards double arrow from bar) - - "⟿": [t: "⠀⠫⠢⠤⠔⠒⠢⠤⠔⠒⠢⠕⠀"] # 0x27FF (Long rightwards squiggle arrow) - - "⤡": [t: "⠀⠫⠘⠪⠒⠒⠕⠀"] # 0x2921 (North west and south east arrow) - - "⤢": [t: "⠀⠫⠰⠪⠒⠒⠕⠀"] # 0x2922 (North east and south west arrow) - - "🣐": # 0x1f8d0 (Long rightwards arrow over leftwards arrow (equilibrium)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠕⠫⠪⠒"] - else: [t: "⠫⠒⠒⠈⠕⠫⠠⠪⠒⠒"] - - "🣑": # 0x1f8d1 (Long rightwards harpoon over leftwards harpoon (equilibrium)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠕⠫⠪⠒"] - else: [t: "⠫⠒⠒⠈⠕⠫⠠⠪⠒⠒"] - - "🣒": # 0x1f8d2 (Long rightwards harpoon over short leftwards harpoon (equilibrium)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠒⠕⠫⠪⠒"] - else: [t: "⠫⠒⠒⠈⠕⠫⠈⠪⠒⠒"] - - "🣓": # 0x1f8d3 (Short rightwards harpoon over long leftwards harpoon (equilibrium, trend to the right)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠕⠫⠪⠒⠒"] - else: [t: "⠫⠒⠈⠕⠫⠠⠪⠒⠒"] - - "🣔": # 0x1f8d4 (Long leftwards harpoon over short rightwards harpoon (equilibrium, trend to the left)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠪⠒⠒⠫⠒⠕"] - else: [t: "⠫⠈⠪⠒⠒⠫⠒⠠⠕"] - - "🣕": # 0x1f8d5 (Short leftwards harpoon over long rightwards harpoon (equilibrium, trend to the left)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠪⠒⠫⠒⠒⠕"] - else: [t: "⠫⠈⠪⠒⠫⠒⠒⠠⠕"] - - "⥂": # 0x2942 (Long rightwards harpoon over short leftwards harpoon (equilibrium)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠒⠕⠫⠪⠒"] - else: [t: "⠫⠒⠒⠈⠕⠫⠈⠪⠒⠒"] - - "⥄": # 0x2944 (Short rightwards harpoon over long leftwards harpoon (equilibrium, trend to the right)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠕⠫⠪⠒⠒"] - else: [t: "⠫⠒⠈⠕⠫⠠⠪⠒⠒"] - - "⥃": # 0x2943 (Long leftwards harpoon over short rightwards harpoon (equilibrium, trend to the left)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠪⠒⠒⠫⠒⠕"] - else: [t: "⠫⠈⠪⠒⠒⠫⠒⠠⠕"] - - "🣖": [t: "⠌⠫⠒⠒⠕"] # 0x1f8d6 (long rightwards arrow with through X) - - "🣗": [t: "⠌⠫⠒⠒⠕"] # 0x1f8d7 (long rightwards arrow with double slash) chem code says it is same as 0x1f8d6 - - - - "⦃": [t: "⠨⠸⠷"] # 0x2983 (Left white curly bracket) - - "⦄": [t: "⠨⠸⠾"] # 0x2984 (Right white curly bracket) - - "⦑": [t: "⠡⠈⠨⠨⠷⠻"] # 0x2991 (Left angle bracket w dot) - - "⦒": [t: "⠡⠈⠨⠨⠾⠻"] # 0x2992 (Right angle bracket w dot) - - "⧄": [t: "⠫⠲⠸⠫⠔⠻"] # 0x29C4 (Square rising diagonal slash) - - "⧅": [t: "⠫⠲⠸⠫⠢⠻"] # 0x29C5 (Square falling diagonal slash) - - "⧆": [t: "⠫⠲⠸⠫⠈⠼⠻"] # 0x29C6 (Squared asterisk) - - "⧊": [t: "⠐⠫⠞⠣⠡⠻"] # 0x29CA (Triangle w dot above) - - "⧋": [t: "⠫⠞⠱"] # 0x29CB (Triangle w underbar) - - "⧌": [t: "⠫⠞⠎"] # 0x29CC (s in triangle §114) - - "⧦": [t: "⠫⠳⠶⠶⠳"] # 0x29E6 (Gleich stark) - - "⨌": [t: "⠮⠮⠮⠮"] # 0x2A0C (Quadruple integral operator) - - "⨍": [t: "⠮⠈⠱⠻"] # 0x2A0D (Finite part integral) - - "⨎": [t: "⠮⠈⠱⠱⠻"] # 0x2A0E (Integral w double stroke) - - "⨖": [t: "⠮⠈⠫⠲⠻"] # 0x2A16 (Quaternion integral operator) - - "⨘": [t: "⠮⠈⠈⠡⠻"] # 0x2A18 (Integral w times sign) - - "⨙": [t: "⠮⠈⠨⠩⠻"] # 0x2A19 (Integral w intersection) - - "⨚": [t: "⠮⠈⠨⠬⠻"] # 0x2A1A (Integral w union) - - "⨛": [t: "⠣⠮"] # 0x2A1B (Integral w overbar (upper)) - - "⨜": [t: "⠩⠮"] # 0x2A1C (Integral w underbar (lower)) - - "⨢": [t: "⠐⠬⠣⠨⠡⠻"] # 0x2A22 (Plus sign w small circle above) - - "⨣": [t: "⠐⠬⠣⠸⠣⠻"] # 0x2A23 (Plus sign w circumflex accent above) - - "⨤": [t: "⠐⠬⠣⠈⠱⠻"] # 0x2A24 (Plus sign w tilde above) - - "⨥": [t: "⠐⠬⠩⠡⠻"] # 0x2A25 (Plus sign w dot below) - - "⨪": [t: "⠐⠱⠩⠡⠻"] # 0x2A2A (Minus sign w dot below) - - "⨰": [t: "⠐⠈⠡⠣⠡⠻"] # 0x2A30 (Multiplication sign w dot above) - - "⨱": [t: "⠈⠡⠱"] # 0x2A31 (Multiplication sign w underbar) - - "⨸": [t: "⠫⠉⠸⠫⠨⠌⠻"] # 0x2A38 (Circled division sign) - - "⨹": [t: "⠫⠞⠸⠫⠬⠻"] # 0x2A39 (Plus sign in triangle) - - "⨺": [t: "⠫⠞⠸⠫⠤⠻"] # 0x2A3A (Minus sign in triangle) - - "⨻": [t: "⠫⠞⠸⠫⠈⠡⠻"] # 0x2A3B (Multiplication sign in triangle) - - "⩀": [t: "⠡⠈⠨⠩⠻"] # 0x2A40 (Intersection w dot) - - "⩁": [t: "⠤⠈⠨⠬⠻"] # 0x2A41 (Union w minus sign) - - "⩂": [t: "⠱⠨⠬"] # 0x2A42 (Union w overbar) - - "⩃": [t: "⠱⠨⠩"] # 0x2A43 (Intersection w overbar) - - "⩑": [t: "⠐⠈⠩⠣⠡⠻"] # 0x2A51 (Logical AND w dot above) - - "⩒": [t: "⠐⠈⠬⠣⠡⠻"] # 0x2A52 (Logical OR w dot above) - - "⩜": [t: "⠱⠈⠈⠩⠻"] # 0x2A5C (Logical AND with horizontal dash) - - "⩝": [t: "⠱⠈⠈⠬⠻"] # 0x2A5D (Logical OR with horizontal dash) - - "⩞": [t: "⠱⠱⠈⠩"] # 0x2A5E (Logical AND w double overbar) - - "⩟": [t: "⠈⠩⠱"] # 0x2A5F (Logical AND w underbar) - - "⩠": [t: "⠈⠩⠱⠱"] # 0x2A60 (Logical AND w double underbar) - - "⩢": [t: "⠱⠱⠈⠬"] # 0x2A62 (Logical OR w double overbar) - - "⩣": [t: "⠈⠬⠱⠱"] # 0x2A63 (Logical OR w double underbar) - - "⩦": [t: "⠐⠨⠅⠩⠡⠻"] # 0x2A66 (Equals sign w dot below) - - "⩧": [t: "⠐⠸⠇⠣⠡⠻"] # 0x2A67 (Identical w dot above) - - "⩪": [t: "⠐⠈⠱⠣⠡⠻"] # 0x2A6A (Tilde operator w dot above) - - "⩬": [t: "⠈⠱⠱⠈⠱"] # 0x2A6C (Similar minus similar) - - "⩭": [t: "⠐⠈⠱⠨⠅⠣⠡⠻"] # 0x2A6D (Congruent w dot above) - - "⩮": [t: "⠐⠨⠅⠣⠈⠼⠻"] # 0x2A6E (Equals w asterisk) - - "⩯": [t: "⠐⠈⠱⠈⠱⠣⠸⠣⠻"] # 0x2A6F (Almost equal to w circumflex) - - "⩰": [t: "⠈⠱⠈⠱⠨⠅"] # 0x2A70 (Approximately equal or equal to) - - "⩱": [t: "⠨⠅⠬"] # 0x2A71 (Equals sign above plus sign) - - "⩲": [t: "⠬⠨⠅"] # 0x2A72 (Plus sign above equals sign) - - "⩳": [t: "⠨⠅⠈⠱"] # 0x2A73 (Equals sign above tilde operator) - - "⩴": [t: "⠐⠂⠐⠂⠨⠅"] # 0x2A74 (Double colon equal) - - "⩵": [t: "⠨⠅⠨⠅"] # 0x2A75 (Two consecutive equals signs) - - "⩶": [t: "⠨⠅⠨⠅⠨⠅"] # 0x2A76 (Three consecutive equals signs) - - "⩷": [t: "⠐⠨⠅⠩⠡⠡⠣⠡⠡⠻"] # 0x2A77 (Equals sign w two dots above and two dots below) - - "⩸": [t: "⠐⠸⠇⠣⠡⠡⠡⠡⠻"] # 0x2A78 (Equivalent w four dots above) - - "⩹": [t: "⠐⠅⠈⠨⠡⠻"] # 0x2A79 (Less than w circle inside) - - "⩺": [t: "⠨⠂⠈⠨⠡⠻"] # 0x2A7A (Greater than w circle inside) - - "⩻": [t: "⠐⠐⠅⠣⠸⠦⠻"] # 0x2A7B (Less-than w question mark above) - - "⩼": [t: "⠐⠨⠂⠣⠸⠦⠻"] # 0x2A7C (Greater-than w question mark above) - - "⪅": [t: "⠐⠅⠈⠱⠈⠱"] # 0x2A85 (Less-than or approximate) - - "⪆": [t: "⠨⠂⠈⠱⠈⠱"] # 0x2A86 (Greater-than or approximate) - - "⪋": [t: "⠐⠅⠨⠅⠨⠂"] # 0x2A8B (Less-than above double-line equal above greater-than) - - "⪌": [t: "⠨⠂⠨⠅⠐⠅"] # 0x2A8C (Greater-than above double-line equal above less-than) - - "⪍": [t: "⠐⠅⠈⠱⠱"] # 0x2A8D (Less-than above similar or equal to) - - "⪎": [t: "⠨⠂⠈⠱⠱"] # 0x2A8E (Greater-than above similar or equal to) - - "⪏": [t: "⠐⠅⠈⠱⠨⠂"] # 0x2A8F (Less-than above similar above greater-than) - - "⪐": [t: "⠨⠂⠈⠱⠐⠅"] # 0x2A90 (Greater-than above similar above less-than) - - "⪑": [t: "⠐⠅⠨⠂⠨⠅"] # 0x2A91 (Less-than above greater-than above double-line equal) - - "⪒": [t: "⠨⠂⠐⠅⠨⠅"] # 0x2A92 (Greater-than above less-than above double-line equal) - - "⪙": [t: "⠨⠅⠐⠅"] # 0x2A99 (Double-line equal to or less-than) - - "⪚": [t: "⠨⠅⠨⠂"] # 0x2A9A (Double-line equal to or greater-than) - - "⪝": [t: "⠈⠱⠐⠅"] # 0x2A9D (Similar or less-than) - - "⪞": [t: "⠈⠱⠨⠂"] # 0x2A9E (Similar or greater-than) - - "⪟": [t: "⠈⠱⠐⠅⠨⠅"] # 0x2A9F (Similar above less-than above equals sign) - - "⪠": [t: "⠈⠱⠨⠂⠨⠅"] # 0x2AA0 (Similar above greater-than above equals sign) - - "⪮": [t: "⠈⠣⠨⠅"] # 0x2AAE (Equals sign with bumpy above) - - "⪽": [t: "⠡⠈⠸⠐⠅⠻"] # 0x2ABD (Subset w dot) - - "⪾": [t: "⠡⠈⠸⠨⠂⠻"] # 0x2ABE (Superset w dot) - - "⪿": [t: "⠐⠸⠐⠅⠩⠬⠻"] # 0x2ABF (Subset with plus sign below) - - "⫀": [t: "⠐⠸⠨⠂⠩⠬⠻"] # 0x2AC0 (Superset with plus sign below) - - "⫁": [t: "⠐⠸⠐⠅⠩⠈⠡⠻"] # 0x2AC1 (Subset with multiplication sign below) - - "⫂": [t: "⠐⠸⠨⠂⠩⠈⠡⠻"] # 0x2AC2 (Superset with multiplication sign below) - - "⫅": [t: "⠸⠐⠅⠨⠅"] # 0x2AC5 (Subset of above equals sign) - - "⫆": [t: "⠸⠨⠂⠨⠅"] # 0x2AC6 (Superset of above equals sign) - - "⫇": [t: "⠸⠐⠅⠈⠱"] # 0x2AC7 (Subset of above tilde operator) - - "⫈": [t: "⠸⠨⠂⠈⠱"] # 0x2AC8 (Superset of above tilde operator) - - "⫉": [t: "⠸⠐⠅⠈⠱⠈⠱"] # 0x2AC9 (Subset of above almost equal to) - - "⫊": [t: "⠸⠨⠂⠈⠱⠈⠱"] # 0x2ACA (Superset of above almost equal to) - - "⫋": [t: "⠸⠐⠅⠌⠨⠅"] # 0x2ACB (Subset of above not equals sign) - - "⫌": [t: "⠸⠨⠂⠌⠨⠅"] # 0x2ACC (Superset of above not equals sign) - - "⫓": [t: "⠸⠐⠅⠸⠨⠂"] # 0x2AD3 (Subset above superset) - - "⫔": [t: "⠸⠨⠂⠸⠐⠅"] # 0x2AD4 (Superset above subset) - - "⫕": [t: "⠸⠐⠅⠸⠐⠅"] # 0x2AD5 (Subset above subset) - - "⫖": [t: "⠸⠨⠂⠸⠨⠂"] # 0x2AD6 (Superset above superset) - - "⫗": [t: "⠸⠨⠂⠐⠸⠐⠅"] # 0x2AD7 (Superset beside subset) - - "⫯": [t: "⠫⠩⠨⠡⠒⠒"] # 0x2AEF (Vertical line w circle above) - - "⫰": [t: "⠫⠣⠨⠡⠒⠒"] # 0x2AF0 (Vertical line w circle below) - - "⫱": [t: "⠫⠣⠨⠡⠒⠒⠳"] # 0x2AF1 (Down tack w circle below) - - "⫲": [t: "⠱⠈⠫⠇⠻"] # 0x2AF2 (Parallel w horizontal stroke) - - "⫳": [t: "⠈⠱⠈⠫⠇⠻"] # 0x2AF3 (Parallel w tilde operator) - - "⫴": [t: "⠳⠳⠳"] # 0x2AF4 (Triple vertical bar binary relation) - - "⬬": [t: "⠫⠸⠑"] # 0x2B2C (Black ellipse) - - "⬭": [t: "⠫⠑"] # 0x2B2D (White ellipse) - - "⬰": [t: "⠨⠡⠈⠫⠪⠒⠒⠻"] # 0x2B30 (Left arrow w small circle) - - "⬱": [t: "⠫⠪⠒⠒⠫⠪⠒⠒⠫⠪⠒⠒"] # 0x2B31 (Three leftwards arrows) - - "⬲": [t: "⠫⠪⠒⠒⠈⠫⠉⠸⠫⠬⠻"] # 0x2B32 (Left arrow w circled plus) - - "⮖": [t: "⠨⠡"] # 0x2B96 (Standard State Symbol) - - "⯃": [t: "⠫⠸⠦"] # 0x2BC3 (Horizontal black octagon) - - # SRE lists this as a custom transcription - - "⋊": [t: "⠈⠡⠳"] # 0x22ca (RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT) +--- +# To greatly simplify typeface/language generation, the chars have unique ASCII chars for them: +# Typeface: S: sans-serif, B: bold, T: script/blackboard, I: italic, R: Roman +# Language: E: English, D: German, G: Greek, V: Greek variants, H: Hebrew, U: Russian +# Indicators: C: capital, L: letter, N: number, P: punctuation, M: multipurpose +# Others: W -- whitespace that should be kept (e.g, in a numeral) +# SRE doesn't have H: Hebrew, so not encoded (yet) +# Some of the weird letters (e.g., circled letters) I didn't translate with the above because +# they don't interact with rules since they are enclosed in other chars. + + - "⨯": [t: "⠈⠡"] # U+2A2F(VECTOR OR CROSS PRODUCT) -- make the same as 0x00D7 (Multiplication sign) + + # --- Nemeth Default Alphabet bold chars. --- + - "𝐀-𝐙": # 0x1d400 - 0x1d419 + - tc: "BE" + - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝐚-𝐳": # 0x1d41a - 0x1d433 + - tc: "BE" + - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 + - tc: "BG" + - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" + + - "𝛂-𝛒": # 0x1d6c2 - 0x1d6d2 + - tc: "BG" + - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒', 'αβγδεζηθικλμνξοπρ')" + + - "𝛔-𝛖": # 0x1d6d4 - 0x1d6d6 + - tc: "BG" + - spell: "translate('.', '𝛔𝛕𝛖', 'στυ')" + + - "𝛘-𝛚": # 0x1d6d8 - 0x1d6da + - tc: "BG" + - spell: "translate('.', '𝛘𝛙𝛚', 'χψω')" + + - "𝛁": [tc: "BGL⠫"] # 0x1d6c1 + - "𝛓": [tc: "BVL⠎"] # 0x1d6d3 + - "𝛗": [tc: "BVL⠋"] # 0x1d6d7 + - "𝛛": [tc: "⠸⠈⠙"] # 0x1d6db + - "𝛜": [tc: "BGL⠑"] # 0x1d6dc + - "𝛝": [tc: "BVL⠹"] # 0x1d6dd + - "𝛞": [tc: "BGL⠅"] # 0x1d6de + - "𝛟": [tc: "BGL⠋"] # 0x1d6df + - "𝛠": [tc: "BGL⠗"] # 0x1d6e0 + - "𝛡": [tc: "BGL⠏"] # 0x1d6e1 + + - "𝟎-𝟗": # 0x1d7ce - 0x1d7d7 + - tc: "B" + - spell: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" + + # --- Nemeth Default Alphabet bold-fraktur chars. --- + + - "𝕬-𝖅": # 0x1d56c - 0x1d585 + - tc: "BD" + - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝖆-𝖟": # 0x1d586 - 0x1d59f + - tc: "BD" + - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" + + # --- Nemeth Default Alphabet bold-italic chars. --- + - "𝑨-𝒁": # 0x1d468 - 0x1d481 + - tc: "BE" + - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝒂-𝒛": # 0x1d482 - 0x1d49b + - tc: "BE" + - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝜜-𝜴": # 0x1d71c - 0x1d734 + - tc: "BG" + - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" + + - "𝜵": [tc: "BGL⠫"] # 0x1d735 + + - "𝜶-𝝆": # 0x1d736 - 0x1d746 + - tc: "BG" + - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆', 'αβγδεζηθικλμνξοπρ')" + + - "𝝇": [tc: "BVL⠎"] # 0x1d747 + + - "𝝈-𝝊": # 0x1d748 - 0x1d74a + - tc: "BG" + - spell: "translate('.', '𝝈𝝉𝝊', 'στυ')" + + - "𝝋": [tc: "BVL⠋"] # 0x1d74b + + - "𝝌-𝝎": # 0x1d74c - 0x1d74e + - tc: "BG" + - spell: "translate('.', '𝝌𝝍𝝎', 'χψω')" + + - "𝝏": [tc: "BVL⠙"] # 0x1d74f + - "𝝐": [tc: "BGL⠑"] # 0x1d750 + - "𝝑": [tc: "BVL⠹"] # 0x1d751 + + - "𝝒-𝝕": # 0x1d752 - 0x1d755 + - tc: "BG" + - spell: "translate('.', '𝝒𝝓𝝔𝝕', 'κφρπ')" + + # --- Nemeth Default Alphabet bold-script chars. --- + + - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 + - tc: "BTE" + - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝓪-𝔃": # 0x1d4ea - 0x1d503 + - tc: "BTE" + - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝚤-𝚥": # 0x1d6a4 - 0x1d6a5 + - tc: "" + - spell: "translate('.', '𝚤𝚥', '⠊⠚')" + +# Russian Alphabet (from Nemeth book) +# NOTE: is this translation needed? + - "А-Я": # 0x410 - 0x42f + - tc: "U" + - spell: "translate('.', 'АБВГДЕЗИЙКЛМНОПРСТУФЭ', 'ABVGDEZIYKLMNOPRSTUFE')" + + - "а-я": # 0x430 - 0x44f + - tc: "U" + - spell: "translate('.', 'абвгдезийклмнопрстуфэ', 'abvgdeziylkmnoprstufye')" + + - "①-⑨": # 0x2460 - 0x2473 + - tc: "⠫⠉⠸⠫⠼" + - spell: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" + - tc: "⠻" + + - "⓪": [tc: "⠫⠉⠸⠫⠼⠴⠻"] # 0x24ea + + - "⑩": [tc: "⠫⠉⠸⠫⠼⠂⠴⠻"] # 0x2469 + - "⑪": [tc: "⠫⠉⠸⠫⠼⠂⠂⠻"] # 0x246a + - "⑫": [tc: "⠫⠉⠸⠫⠼⠂⠆⠻"] # 0x246b + - "⑬": [tc: "⠫⠉⠸⠫⠼⠂⠒⠻"] # 0x246c + - "⑭": [tc: "⠫⠉⠸⠫⠼⠂⠲⠻"] # 0x246d + - "⑮": [tc: "⠫⠉⠸⠫⠼⠂⠢⠻"] # 0x246e + - "⑯": [tc: "⠫⠉⠸⠫⠼⠂⠖⠻"] # 0x246f + - "⑰": [tc: "⠫⠉⠸⠫⠼⠂⠶⠻"] # 0x2470 + - "⑱": [tc: "⠫⠉⠸⠫⠼⠂⠦⠻"] # 0x2471 + - "⑲": [tc: "⠫⠉⠸⠫⠼⠂⠔⠻"] # 0x2472 + - "⑳": [tc: "⠫⠉⠸⠫⠼⠆⠴⠻"] # 0x2473 + + - "㉑": [tc: "⠫⠉⠸⠫⠼⠆⠂⠻"] # 0x3251 + - "㉒": [tc: "⠫⠉⠸⠫⠼⠆⠆⠻"] # 0x3252 + - "㉓": [tc: "⠫⠉⠸⠫⠼⠆⠒⠻"] # 0x3253 + - "㉔": [tc: "⠫⠉⠸⠫⠼⠆⠲⠻"] # 0x3254 + - "㉕": [tc: "⠫⠉⠸⠫⠼⠆⠢⠻"] # 0x3255 + - "㉖": [tc: "⠫⠉⠸⠫⠼⠆⠖⠻"] # 0x3256 + - "㉗": [tc: "⠫⠉⠸⠫⠼⠆⠶⠻"] # 0x3257 + - "㉘": [tc: "⠫⠉⠸⠫⠼⠆⠦⠻"] # 0x3258 + - "㉙": [tc: "⠫⠉⠸⠫⠼⠆⠔⠻"] # 0x3259 + - "㉚": [tc: "⠫⠉⠸⠫⠼⠒⠴⠻"] # 0x325a + - "㉛": [tc: "⠫⠉⠸⠫⠼⠒⠂⠻"] # 0x325b + - "㉜": [tc: "⠫⠉⠸⠫⠼⠒⠆⠻"] # 0x325c + - "㉝": [tc: "⠫⠉⠸⠫⠼⠒⠒⠻"] # 0x325d + - "㉞": [tc: "⠫⠉⠸⠫⠼⠒⠲⠻"] # 0x325e + - "㉟": [tc: "⠫⠉⠸⠫⠼⠒⠢⠻"] # 0x325f + - "㊱": [tc: "⠫⠉⠸⠫⠼⠒⠖⠻"] # 0x32b1 + - "㊲": [tc: "⠫⠉⠸⠫⠼⠒⠶⠻"] # 0x32b2 + - "㊳": [tc: "⠫⠉⠸⠫⠼⠒⠦⠻"] # 0x32b3 + - "㊴": [tc: "⠫⠉⠸⠫⠼⠒⠔⠻"] # 0x32b4 + - "㊵": [tc: "⠫⠉⠸⠫⠼⠲⠴⠻"] # 0x32b5 + - "㊶": [tc: "⠫⠉⠸⠫⠼⠲⠂⠻"] # 0x32b6 + - "㊷": [tc: "⠫⠉⠸⠫⠼⠲⠆⠻"] # 0x32b7 + - "㊸": [tc: "⠫⠉⠸⠫⠼⠲⠒⠻"] # 0x32b8 + - "㊹": [tc: "⠫⠉⠸⠫⠼⠲⠲⠻"] # 0x32b9 + - "㊺": [tc: "⠫⠉⠸⠫⠼⠲⠢⠻"] # 0x32ba + - "㊻": [tc: "⠫⠉⠸⠫⠼⠲⠖⠻"] # 0x32bb + - "㊼": [tc: "⠫⠉⠸⠫⠼⠲⠶⠻"] # 0x32bc + - "㊽": [tc: "⠫⠉⠸⠫⠼⠲⠦⠻"] # 0x32bd + - "㊾": [tc: "⠫⠉⠸⠫⠼⠲⠔⠻"] # 0x32be + - "㊿": [tc: "⠫⠉⠸⠫⠼⠢⠴⠻"] # 0x32bf + +#NOTE: uncertainty here + - "Ⓐ-Ⓩ": # 0x24b6 - 0x24cf + - tc: "⠫⠉⠸⠫⠠" + - spell: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - tc: "⠻" + + - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 + - tc: "⠫⠉⠸⠫" + - spell: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" + - tc: "⠻" + + # --- Nemeth Default Alphabet circled-sans-serif chars. --- + + - "➀-➈": # 0x1f10b, 0x2780 - 0x2788 + - tc: "⠫⠉⠸⠫⠠⠨⠼" + - spell: "translate('.', '➀➁➂➃➄➅➆➇➈', '123456789')" + - tc: "⠻" + + - "🄋": [tc: "⠫⠉⠸⠫⠠⠨⠼⠴⠻"] # 0x1f10b + - "➉": [tc: "⠫⠉⠸⠫⠠⠨⠼⠂⠴⠻"] # 0x2789 + + # --- Nemeth Default Alphabet comma chars. --- + + - "🄁-🄊": # 0x1f101 - 0x1f10a + - spell: "translate('.', '🄁🄂🄃🄄🄅🄆🄇🄈🄉🄊', '0123456789')" + - tc: "⠠" + + + # --- Nemeth Default Alphabet double-circled chars. --- + + - "⓵": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠂⠻⠻"] # 0x24f5 + - "⓶": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠆⠻⠻"] # 0x24f6 + - "⓷": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠒⠻⠻"] # 0x24f7 + - "⓸": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠲⠻⠻"] # 0x24f8 + - "⓹": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠢⠻⠻"] # 0x24f9 + - "⓺": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠖⠻⠻"] # 0x24fa + - "⓻": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠶⠻⠻"] # 0x24fb + - "⓼": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠦⠻⠻"] # 0x24fc + - "⓽": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠔⠻⠻"] # 0x24fd + - "⓾": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠂⠴⠻⠻"] # 0x24fe + + # --- Nemeth Default Alphabet double-struck chars. --- + - "𝔸-𝕐": # 0x1d538 - 0x1d550 (partial, excludes ℂ ℍ ℕ ℙ ℚ ℝ ℤ) + - tc: "𝔹E" + - spell: "translate('.', '𝔸𝔹𝔻𝔼𝔽𝔾𝕀𝕁𝕂𝕃𝕄𝕆𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABDEFGIJKLMOSTUVWXY')" + + - "ℂ": [tc: "𝔹ECL⠉"] # 0x2102 + - "ℍ": [tc: "𝔹ECL⠓"] # 0x210d + - "ℕ": [tc: "𝔹ECL⠝"] # 0x2115 + - "ℙ": [tc: "𝔹ECL⠏"] # 0x2119 + - "ℚ": [tc: "𝔹ECL⠟"] # 0x211a + - "ℝ": [tc: "𝔹ECL⠗"] # 0x211d + - "ℤ": [tc: "𝔹ECL⠵"] # 0x2124 + - "Ω": [t: "CGL⠺"] # 0x2126 (Ohm sign (capital Greek omega)) + + - "𝕒-𝕫": # 0x1d552 - 0x1d56b + - tc: "𝔹E" + - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 + - tc: "𝔹" + - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" + + + # --- Nemeth Default Alphabet fraktur chars. --- + + - "𝔄-𝔜": # 0x1d504 - 0x1d51c + - tc: "D" + - spell: "translate('.', '𝔄𝔅𝔇𝔈𝔉𝔊𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABDEFGJKLMNOPQSTUVWXY')" + + - "ℭ": [tc: "DCL⠉"] # 0x212d + - "ℌ": [tc: "DCL⠓"] # 0x210c + - "ℑ": [tc: "DCL⠊"] # 0x2111 + - "ℜ": [tc: "DCL⠗"] # 0x211c + - "ℨ": [tc: "DCL⠵"] # 0x2128 + + - "𝔞-𝔷": # 0x1d51e - 0x1d537 + - tc: "D" + - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" + + # --- Nemeth Default Alphabet fullwidth chars. --- + + - "A-Z": # 0xff21 - 0xff3a + - tc: "" + - spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "a-z": # 0xff41 - 0xff5a + - tc: "" + - spell: "translate('.', 'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz')" + + - "0-9": # 0xff10 - 0xff19 + - tc: "" + - spell: "translate('.', '0123456789', '0123456789')" + + # --- Nemeth Default Alphabet italic chars -- treat as non-italic. --- + + - "𝐴-𝑍": # 0x1d434 - 0x1d44d + - tc: "E" + - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝑎-𝑧": # 0x1d44e - 0x1d467 + - tc: "E" + - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔ℎ𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa + - tc: "G" + - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" + + - "𝛻": [tc: "GL⠫"] # 0x1d6fb + + - "𝛼-𝜌": # 0x1d6fc - 0x1d70c + - tc: "G" + - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌', 'αβγδεζηθικλμνξοπρ')" + - "𝜍": [tc: "VL⠎"] # 0x1d70d + + - "𝜎": [tc: "GL⠎"] # 0x1d70e + - "𝜏": [tc: "GL⠞"] # 0x1d70f + - "𝜐": [tc: "GL⠥"] # 0x1d710 + + - "𝜑": [tc: "VL⠋"] # 0x1d711 + + - "𝜒": [tc: "GL⠯"] # 0x1d712 + - "𝜓": [tc: "GL⠽"] # 0x1d713 + - "𝜔": [tc: "GL⠺"] # 0x1d714 + + - "𝜕": [tc: "VL⠙"] # 0x1d715 + + - "𝜖": [tc: "GL⠑"] # 0x1d716 + + - "𝜗": [tc: "VL⠹"] # 0x1d717 + + - "𝜘": [tc: "GL⠅"] # 0x1d718 + - "𝜙": [tc: "GL⠋"] # 0x1d719 + - "𝜚": [tc: "GL⠗"] # 0x1d71a + - "𝜛": [tc: "GL⠏"] # 0x1d71b + + # --- Nemeth Default Alphabet monospace chars. --- + + - "𝙰-𝚉": # 0x1d670 - 0x1d689 + - tc: "" + - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 + - tc: "" + - spell: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝟶-𝟿": # 0x1d7f6 - 0x1d7ff + - tc: "" + - spell: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" + + + # --- Nemeth Default Alphabet negative-circled chars. --- + - "⓿": [t: "⠫⠸⠉⠸⠫⠼⠴⠻"] # 0x24ff + - "❶": [t: "⠫⠸⠉⠸⠫⠼⠂⠻"] # 0x2776 + - "❷": [t: "⠫⠸⠉⠸⠫⠼⠆⠻"] # 0x2777 + - "❸": [t: "⠫⠸⠉⠸⠫⠼⠒⠻"] # 0x2778 + - "❹": [t: "⠫⠸⠉⠸⠫⠼⠲⠻"] # 0x2779 + - "❺": [t: "⠫⠸⠉⠸⠫⠼⠢⠻"] # 0x277a + - "❻": [t: "⠫⠸⠉⠸⠫⠼⠖⠻"] # 0x277b + - "❼": [t: "⠫⠸⠉⠸⠫⠼⠶⠻"] # 0x277c + - "❽": [t: "⠫⠸⠉⠸⠫⠼⠦⠻"] # 0x277d + - "❾": [t: "⠫⠸⠉⠸⠫⠼⠔⠻"] # 0x277e + - "❿": [t: "⠫⠸⠉⠸⠫⠼⠂⠴⠻"] # 0x277f + - "⓫": [t: "⠫⠸⠉⠸⠫⠼⠂⠂⠻"] # 0x24eb + - "⓬": [t: "⠫⠸⠉⠸⠫⠼⠂⠆⠻"] # 0x24ec + - "⓭": [t: "⠫⠸⠉⠸⠫⠼⠂⠒⠻"] # 0x24ed + - "⓮": [t: "⠫⠸⠉⠸⠫⠼⠂⠲⠻"] # 0x24ee + - "⓯": [t: "⠫⠸⠉⠸⠫⠼⠂⠢⠻"] # 0x24ef + - "⓰": [t: "⠫⠸⠉⠸⠫⠼⠂⠖⠻"] # 0x24f0 + - "⓱": [t: "⠫⠸⠉⠸⠫⠼⠂⠶⠻"] # 0x24f1 + - "⓲": [t: "⠫⠸⠉⠸⠫⠼⠂⠦⠻"] # 0x24f2 + - "⓳": [t: "⠫⠸⠉⠸⠫⠼⠂⠔⠻"] # 0x24f3 + - "⓴": [t: "⠫⠸⠉⠸⠫⠼⠆⠴⠻"] # 0x24f4 + + - "🅐": [t: "⠫⠸⠉⠸⠫⠠⠁⠻"] # 0x1f150 + - "🅑": [t: "⠫⠸⠉⠸⠫⠠⠃⠻"] # 0x1f151 + - "🅒": [t: "⠫⠸⠉⠸⠫⠠⠉⠻"] # 0x1f152 + - "🅓": [t: "⠫⠸⠉⠸⠫⠠⠙⠻"] # 0x1f153 + - "🅔": [t: "⠫⠸⠉⠸⠫⠠⠑⠻"] # 0x1f154 + - "🅕": [t: "⠫⠸⠉⠸⠫⠠⠋⠻"] # 0x1f155 + - "🅖": [t: "⠫⠸⠉⠸⠫⠠⠛⠻"] # 0x1f156 + - "🅗": [t: "⠫⠸⠉⠸⠫⠠⠓⠻"] # 0x1f157 + - "🅘": [t: "⠫⠸⠉⠸⠫⠠⠊⠻"] # 0x1f158 + - "🅙": [t: "⠫⠸⠉⠸⠫⠠⠚⠻"] # 0x1f159 + - "🅚": [t: "⠫⠸⠉⠸⠫⠠⠅⠻"] # 0x1f15a + - "🅛": [t: "⠫⠸⠉⠸⠫⠠⠇⠻"] # 0x1f15b + - "🅜": [t: "⠫⠸⠉⠸⠫⠠⠍⠻"] # 0x1f15c + - "🅝": [t: "⠫⠸⠉⠸⠫⠠⠝⠻"] # 0x1f15d + - "🅞": [t: "⠫⠸⠉⠸⠫⠠⠕⠻"] # 0x1f15e + - "🅟": [t: "⠫⠸⠉⠸⠫⠠⠏⠻"] # 0x1f15f + - "🅠": [t: "⠫⠸⠉⠸⠫⠠⠟⠻"] # 0x1f160 + - "🅡": [t: "⠫⠸⠉⠸⠫⠠⠗⠻"] # 0x1f161 + - "🅢": [t: "⠫⠸⠉⠸⠫⠠⠎⠻"] # 0x1f162 + - "🅣": [t: "⠫⠸⠉⠸⠫⠠⠞⠻"] # 0x1f163 + - "🅤": [t: "⠫⠸⠉⠸⠫⠠⠥⠻"] # 0x1f164 + - "🅥": [t: "⠫⠸⠉⠸⠫⠠⠧⠻"] # 0x1f165 + - "🅦": [t: "⠫⠸⠉⠸⠫⠠⠺⠻"] # 0x1f166 + - "🅧": [t: "⠫⠸⠉⠸⠫⠠⠭⠻"] # 0x1f167 + - "🅨": [t: "⠫⠸⠉⠸⠫⠠⠽⠻"] # 0x1f168 + - "🅩": [t: "⠫⠸⠉⠸⠫⠠⠵⠻"] # 0x1f169 + + # --- Nemeth Default Alphabet negative-circled-sans-serif chars. --- + - "🄌": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠴⠻"] # 0x1f10c + - "➊": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠂⠻"] # 0x278a + - "➋": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠆⠻"] # 0x278b + - "➌": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠒⠻"] # 0x278c + - "➍": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠲⠻"] # 0x278d + - "➎": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠢⠻"] # 0x278e + - "➏": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠖⠻"] # 0x278f + - "➐": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠶⠻"] # 0x2790 + - "➑": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠦⠻"] # 0x2791 + - "➒": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠔⠻"] # 0x2792 + - "➓": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠂⠴⠻"] # 0x2793 + + # --- Nemeth Default Alphabet negative-squared chars. --- + - "🅰-🆉": # 0x1f170 - 0x1f189 + - tc: "⠫⠸⠲⠸⠫⠠" + - spell: "translate('.', '🅰🅱🅲🅳🅴🅵🅶🅷🅸🅹🅺🅻🅼🅽🅾🅿🆀🆁🆂🆃🆄🆅🆆🆇🆈🆉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - tc: "⠻" + + # --- Nemeth Default Alphabet parenthesized chars. --- + + - "⑴-⑼": # 0x2474 - 0x247c + - tc: "⠷" + - spell: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" + - tc: "⠾" + + - "⑽": [t: "⠷⠂⠴⠾"] # 0x247d + - "⑾": [t: "⠷⠂⠂⠾"] # 0x247e + - "⑿": [t: "⠷⠂⠆⠾"] # 0x247f + - "⒀": [t: "⠷⠂⠒⠾"] # 0x2480 + - "⒁": [t: "⠷⠂⠲⠾"] # 0x2481 + - "⒂": [t: "⠷⠂⠢⠾"] # 0x2482 + - "⒃": [t: "⠷⠂⠖⠾"] # 0x2483 + - "⒄": [t: "⠷⠂⠶⠾"] # 0x2484 + - "⒅": [t: "⠷⠂⠦⠾"] # 0x2485 + - "⒆": [t: "⠷⠂⠔⠾"] # 0x2486 + - "⒇": [t: "⠷⠆⠴⠾"] # 0x2487 + + - "🄐-🄩": # 0x1f110 - 0x1f129 + - tc: "⠷⠠" + - spell: "translate('.', '🄐🄑🄒🄓🄔🄕🄖🄗🄘🄙🄚🄛🄜🄝🄞🄟🄠🄡🄢🄣🄤🄥🄦🄧🄨🄩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - tc: "⠾" + + - "⒜-⒵": # 0x249c - 0x24b5 + - tc: "⠷" + - spell: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" + - tc: "⠾" + + # --- Nemeth Default Alphabet period chars. --- + - "🄀": [t: "⠴⠸⠲"] # 0x1f100 + - "⒈": [t: "⠂⠸⠲"] # 0x2488 + - "⒉": [t: "⠆⠸⠲"] # 0x2489 + - "⒊": [t: "⠒⠸⠲"] # 0x248a + - "⒋": [t: "⠲⠸⠲"] # 0x248b + - "⒌": [t: "⠢⠸⠲"] # 0x248c + - "⒍": [t: "⠖⠸⠲"] # 0x248d + - "⒎": [t: "⠶⠸⠲"] # 0x248e + - "⒏": [t: "⠦⠸⠲"] # 0x248f + - "⒐": [t: "⠔⠸⠲"] # 0x2490 + + - "⒑": [t: "⠂⠴⠸⠲"] # 0x2491 + - "⒒": [t: "⠂⠂⠸⠲"] # 0x2492 + - "⒓": [t: "⠂⠆⠸⠲"] # 0x2493 + - "⒔": [t: "⠂⠒⠸⠲"] # 0x2494 + - "⒕": [t: "⠂⠲⠸⠲"] # 0x2495 + - "⒖": [t: "⠂⠢⠸⠲"] # 0x2496 + - "⒗": [t: "⠂⠖⠸⠲"] # 0x2497 + - "⒘": [t: "⠂⠶⠸⠲"] # 0x2498 + - "⒙": [t: "⠂⠦⠸⠲"] # 0x2499 + - "⒚": [t: "⠂⠔⠸⠲"] # 0x249a + - "⒛": [t: "⠆⠴⠸⠲"] # 0x249b + + # --- Nemeth Default Alphabet sans-serif chars. --- + - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 + - tc: "SE" + - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 + - tc: "SE" + - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝟢-𝟫": # 0x1d7e2 - 0x1d7eb + - tc: "S" + - spell: "translate('.', '𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫', '0123456789')" + + # --- Nemeth Default Alphabet sans-serif-bold chars. --- + - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed + - tc: "SBE" + - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝗮-𝘇": # 0x1d5ee - 0x1d607 + - tc: "SBE" + - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝝖-𝝮": # 0x1d756 - 0x1d76e + - tc: "SBG" + - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" + + - "𝝰-𝞀": # 0x1d770 - 0x1d780 + - tc: "SBG" + - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀', 'αβγδεζηθικλμνξοπρ')" + + - "𝝯": [tc: "SBGL⠫"] # 0x1d76f + + - "𝞁": [tc: "SBVL⠎"] # 0x1d781 + + - "𝞂-𝞄": # 0x1d782 - 0x1d784 + - tc: "SBG" + - spell: "translate('.', '𝞂𝞃𝞄', 'στυ')" + + - "𝞅": [tc: "SBVL⠋"] # 0x1d785 + + - "𝞆-𝞈": # 0x1d786 - 0x1d788 + - tc: "SBG" + - spell: "translate('.', '𝞆𝞇𝞈', 'χψω')" + + - "𝞉": [tc: "⠠⠨⠸⠈⠙"] # 0x1d789 + - "𝞊": [tc: "SBGL⠑"] # 0x1d78a + - "𝞋": [tc: "SBVL⠹"] # 0x1d78b + + - "𝞌-𝞏": # 0x1d78c - 0x1d78f + - tc: "SBG" + - spell: "translate('.', '𝞌𝞍𝞎𝞏', 'κφρπ')" + + - "𝟬-𝟵": # 0x1d7ec - 0x1d7f5 + - tc: "SB" + - spell: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" + + # --- Nemeth Default Alphabet sans-serif-bold-italic chars. --- + + - "𝘼-𝙕": # 0x1d63c - 0x1d655 + - tc: "SBE" + - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝙖-𝙯": # 0x1d656 - 0x1d66f + - tc: "SBE" + - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 + - tc: "SBG" + - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" + + - "𝞩": [t: "SBGL⠫"] # 0x1d7a9 + + - "𝞪-𝞺": # 0x1d7aa - 0x1d7ba + - tc: "SBG" + - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺', 'αβγδεζηθικλμνξοπρ')" + + - "𝞻": [t: "SBVL⠎"] # 0x1d7bb + - "𝞼": [t: "SBGL⠎"] # 0x1d7bc + - "𝞽": [t: "SBGL⠞"] # 0x1d7bd + - "𝞾": [t: "SBGL⠥"] # 0x1d7be + - "𝞿": [t: "SBVL⠋"] # 0x1d7bf + + - "𝟀": [t: "SBGL⠯"] # 0x1d7c0 + - "𝟁": [t: "SBGL⠽"] # 0x1d7c1 + - "𝟂": [t: "SBGL⠺"] # 0x1d7c2 + - "𝟃": [t: "SBVL⠙"] # 0x1d7c3 + + - "𝟄": [t: "SBGL⠑"] # 0x1d7c4 + - "𝟅": [t: "SBVL⠹"] # 0x1d7c5 + + - "𝟆": [t: "SBGL⠅"] # 0x1d7c6 + - "𝟇": [t: "SBGL⠋"] # 0x1d7c7 + - "𝟈": [t: "SBGL⠗"] # 0x1d7c8 + - "𝟉": [t: "SBGL⠏"] # 0x1d7c9 + + # --- Nemeth Default Alphabet sans-serif-italic chars. --- + - "𝘈-𝘡": # 0x1d608 - 0x1d621 + - tc: "SE" + - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝘢-𝘻": # 0x1d622 - 0x1d63b + - tc: "SE" + - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" + + # --- Nemeth Default Alphabet script chars. --- + - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 + - tc: "TE" + - spell: "translate('.', '𝒜𝒞𝒟𝒢𝒥𝒦𝒩𝒪𝒫𝒬𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ACDGJKNOPQSTUVWXYZ')" + + - "ℬ": [t: "TECL⠃"] # 0x212c + - "ℰ": [t: "TECL⠑"] # 0x2130 + - "ℱ": [t: "TECL⠋"] # 0x2131 + - "ℋ": [t: "TECL⠓"] # 0x210b + - "ℐ": [t: "TECL⠊"] # 0x2110 + - "ℒ": [t: "TECL⠇"] # 0x2112 + - "ℳ": [t: "TECL⠍"] # 0x2133 + - "ℛ": [t: "TECL⠗"] # 0x211b + + - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf + - tc: "TE" + - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒻𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdfhijklmnpqrstuvwxyz')" + + - "ℯ": [t: "TEL⠑"] # 0x212f + - "ℊ": [t: "TEL⠛"] # 0x210a + - "ℴ": [t: "TEL⠕"] # 0x2134 + + # --- Nemeth Default Alphabet squared chars. --- + + - "🄰": [t: "⠫⠲⠸⠫⠠⠁⠻"] # 0x1f130 + - "🄱": [t: "⠫⠲⠸⠫⠠⠃⠻"] # 0x1f131 + - "🄲": [t: "⠫⠲⠸⠫⠠⠉⠻"] # 0x1f132 + - "🄳": [t: "⠫⠲⠸⠫⠠⠙⠻"] # 0x1f133 + - "🄴": [t: "⠫⠲⠸⠫⠠⠑⠻"] # 0x1f134 + - "🄵": [t: "⠫⠲⠸⠫⠠⠋⠻"] # 0x1f135 + - "🄶": [t: "⠫⠲⠸⠫⠠⠛⠻"] # 0x1f136 + - "🄷": [t: "⠫⠲⠸⠫⠠⠓⠻"] # 0x1f137 + - "🄸": [t: "⠫⠲⠸⠫⠠⠊⠻"] # 0x1f138 + - "🄹": [t: "⠫⠲⠸⠫⠠⠚⠻"] # 0x1f139 + - "🄺": [t: "⠫⠲⠸⠫⠠⠅⠻"] # 0x1f13a + - "🄻": [t: "⠫⠲⠸⠫⠠⠇⠻"] # 0x1f13b + - "🄼": [t: "⠫⠲⠸⠫⠠⠍⠻"] # 0x1f13c + - "🄽": [t: "⠫⠲⠸⠫⠠⠝⠻"] # 0x1f13d + - "🄾": [t: "⠫⠲⠸⠫⠠⠕⠻"] # 0x1f13e + - "🄿": [t: "⠫⠲⠸⠫⠠⠏⠻"] # 0x1f13f + - "🅀": [t: "⠫⠲⠸⠫⠠⠟⠻"] # 0x1f140 + - "🅁": [t: "⠫⠲⠸⠫⠠⠗⠻"] # 0x1f141 + - "🅂": [t: "⠫⠲⠸⠫⠠⠎⠻"] # 0x1f142 + - "🅃": [t: "⠫⠲⠸⠫⠠⠞⠻"] # 0x1f143 + - "🅄": [t: "⠫⠲⠸⠫⠠⠥⠻"] # 0x1f144 + - "🅅": [t: "⠫⠲⠸⠫⠠⠧⠻"] # 0x1f145 + - "🅆": [t: "⠫⠲⠸⠫⠠⠺⠻"] # 0x1f146 + - "🅇": [t: "⠫⠲⠸⠫⠠⠭⠻"] # 0x1f147 + - "🅈": [t: "⠫⠲⠸⠫⠠⠽⠻"] # 0x1f148 + - "🅉": [t: "⠫⠲⠸⠫⠠⠵⠻"] # 0x1f149 + + # --- Nemeth Default Alphabet sub chars. --- + + - "₀": [t: "⠰⠴"] # 0x2080 + - "₁": [t: "⠰⠂"] # 0x2081 + - "₂": [t: "⠰⠆"] # 0x2082 + - "₃": [t: "⠰⠒"] # 0x2083 + - "₄": [t: "⠰⠲"] # 0x2084 + - "₅": [t: "⠰⠢"] # 0x2085 + - "₆": [t: "⠰⠖"] # 0x2086 + - "₇": [t: "⠰⠶"] # 0x2087 + - "₈": [t: "⠰⠦"] # 0x2088 + - "₉": [t: "⠰⠔"] # 0x2089 + + # --- Nemeth Default Alphabet super chars. --- + + - "⁰": [t: "⠘⠴"] # 0x2070 + - "¹": [t: "⠘⠂"] # 0xb9 + - "²": [t: "⠘⠆"] # 0xb2 + - "³": [t: "⠘⠒"] # 0xb3 + - "⁴": [t: "⠘⠲"] # 0x2074 + - "⁵": [t: "⠘⠢"] # 0x2075 + - "⁶": [t: "⠘⠖"] # 0x2076 + - "⁷": [t: "⠘⠶"] # 0x2077 + - "⁸": [t: "⠘⠦"] # 0x2078 + - "⁹": [t: "⠘⠔"] # 0x2079 + + # --- Nemeth Default Characters latin-lower-phonetic chars. --- + + - "ø": [t: "⠈⠕"] # 0xf8 + + # --- Nemeth Default Characters math_geometry chars. --- + + - "─": [t: "⠱"] # 0x2500 + - "│": [t: "⠳"] # 0x2502 + - "▰": [t: "⠫⠸⠛"] # 0x25b0 + - "▱": [t: "⠫⠛"] # 0x25b1 + - "▽": [t: "⠨⠫"] # 0x25bd + - "◆": [t: "⠫⠸⠙"] # 0x25c6 + - "◇": [t: "⠫⠙"] # 0x25c7 + - "◈": [t: "⠫⠸⠙"] # 0x25c8 + - "◉": [t: "⠫⠸⠉"] # 0x25c9 + - "◊": [t: "⠫⠙"] # 0x25ca + - "⬟": [t: "⠫⠸⠢"] # 0x2b1f + - "⬠": [t: "⠫⠢"] # 0x2b20 + - "⬡": [t: "⠫⠖"] # 0x2b21 + - "⬢": [t: "⠫⠸⠖"] # 0x2b22 + - "⬣": [t: "⠫⠸⠖"] # 0x2b23 + - "⬤": [t: "⠫⠸⠉"] # 0x2b24 + - "⬥": [t: "⠫⠸⠙"] # 0x2b25 + + # --- Nemeth Default Characters math_symbols chars. --- + + - "\"": [t: "⠄⠄"] # 0x22 + - "¡": [t: "⠖"] # 0xa1 + - "¢": [t: "⠈⠉"] # 0xa2 + - "£": [t: "⠈⠇"] # 0xa3 + - "¤": [t: "⠈⠫"] # 0xa4 + - "¥": [t: "⠈⠽"] # 0xa5 + - "§": [t: "⠈⠠⠎"] # 0xa7 + - "©": [t: "⠘⠉"] # 0xa9 (Copyright) + - "ª": [t: "⠸⠰⠁"] # 0xaa + - "«": [t: "⠐⠅⠈⠐⠅⠻"] # 0xab + - "®": [t: "⠘⠗"] # 0xae + - "´": [t: "⠈"] # 0xb4 + - "µ": [t: "⠨⠍"] # 0xb5 + - "¶": [t: "⠈⠠⠏"] # 0xb6 + - "¿": [t: "⠦"] # 0xbf + - "ʹ": [t: "⠄"] # 0x2b9 + - "ʺ": [t: "⠄⠄"] # 0x2ba + - "˙": [t: "⠡"] # 0x2d9 + - "˜": [t: "⠈⠱"] # 0x2dc + - "‐": [t: "⠤"] # 0x2010 + - "‑": [t: "⠤"] # 0x2011 + - "‒": [t: "⠤⠤"] # 0x2012 + - "–": [t: "⠤⠤"] # 0x2013 + - "‖": [t: "⠳⠳"] # 0x2016 + - "†": [t: "⠸⠻"] # 0x2020 + - "‡": [t: "⠸⠸⠻"] # 0x2021 + - "•": [t: "⠡"] # 0x2022 + - "․": [t: "⠄"] # 0x2024 + - "‥": [t: "⠄⠄"] # 0x2025 + - "′": [t: "⠄"] # 0x2032 + - "″": [t: "⠄⠄"] # 0x2033 + - "‴": [t: "⠄⠄."] # 0x2034 (Triple prime) + - "⁗": [t: "⠄⠄.."] # 0x2057 (Quadruple prime) + - "‼": [t: "⠖⠖"] # 0x203c + - "‾": [t: "⠱"] # 0x203e + - "⁇": [t: "⠹⠹"] # 0x2047 + - "⁈": [t: "⠹⠖"] # 0x2048 + - "⁉": [t: "⠖⠹"] # 0x2049 + - "∀": [t: "⠈⠯"] # 0x2200 + - "∃": [t: "⠈⠿"] # 0x2203 + - "∄": [t: "⠌⠈⠿"] # 0x2204 + - "∅": [t: "⠸⠴"] # 0x2205 + - "∈": [t: "⠈⠑"] # 0x2208 + - "∉": [t: "⠌⠈⠑"] # 0x2209 + - "∊": [t: "⠈⠑"] # 0x220a + - "∋": [t: "⠈⠢"] # 0x220b + - "∌": [t: "⠌⠈⠢"] # 0x220c + - "∍": [t: "⠈⠢"] # 0x220d + - "∎": [t: "⠸⠳"] # 0x220e + - "−": [t: "⠤"] # 0x2212 + - "∓": [t: "⠤⠬"] # 0x2213 + - "∕": [t: "⠸⠌"] # 0x2215 + - "∖": [t: "⠸⠡"] # 0x2216 + - "∗": [t: "⠈⠼"] # 0x2217 + - "∘": [t: "⠨⠡"] # 0x2218 + - "∝": [t: "⠸⠿"] # 0x221d + - "∞": [t: "⠠⠿"] # 0x221e + - "∟": [t: "⠫⠪⠨⠗⠻"] # 0x221f + - "∠": [t: "⠫⠪"] # 0x2220 + - "∢": [t: "⠫⠪⠸⠫⠫⠁⠻"] # 0x2222 + - "∣": [t: "⠳"] # 0x2223 + - "∤": [t: "⠌⠳"] # 0x2224 + - "∥": [t: "⠫⠇"] # 0x2225 + - "∦": [t: "⠌⠫⠇"] # 0x2226 + - "∧": [t: "⠈⠩"] # 0x2227 + - "∨": [t: "⠈⠬"] # 0x2228 + - "∩": [t: "⠨⠩"] # 0x2229 + - "∪": [t: "⠨⠬"] # 0x222a + - "∫": [t: "⠮"] # 0x222b + - "∬": [t: "⠮⠮"] # 0x222c + - "∭": [t: "⠮⠮⠮"] # 0x222d + - "∮": [t: "⠮⠈⠫⠉⠻"] # 0x222e + - "∲": [t: "⠮⠈⠫⠪⠢⠔⠻"] # 0x2232 + - "∳": [t: "⠮⠈⠫⠢⠔⠕⠻"] # 0x2233 + - "∴": [t: "⠠⠡"] # 0x2234 + - "∵": [t: "⠈⠌"] # 0x2235 + - "∶": [t: "⠐⠂"] # 0x2236 + - "∷": [t: "⠰⠆"] # 0x2237 + - "∸": [t: "⠨⠤"] # 0x2238 + - "∼": [t: "⠈⠱"] # 0x223c + - "≁": [t: "⠌⠈⠱"] # 0x2241 + - "≂": [t: "⠱⠈⠱"] # 0x2242 + - "≃": [t: "⠈⠱⠱"] # 0x2243 + - "≄": [t: "⠌⠈⠱⠱"] # 0x2244 + - "≅": [t: "⠈⠱⠨⠅"] # 0x2245 + - "≆": [t: "⠈⠱⠌⠨⠅"] # 0x2246 + - "≇": [t: "⠌⠈⠱⠨⠅"] # 0x2247 + - "≈": [t: "⠈⠱⠈⠱"] # 0x2248 + - "≉": [t: "⠌⠈⠱⠈⠱"] # 0x2249 + - "≊": [t: "⠈⠱⠈⠱⠱"] # 0x224a + - "≍": [t: "⠈⠣⠠⠣"] # 0x224d + - "≎": [t: "⠈⠣⠠⠣"] # 0x224e + - "≐": [t: "⠐⠨⠅⠣⠡⠻"] # 0x2250 + - "≑": [t: "⠐⠨⠅⠩⠡⠣⠡⠻"] # 0x2251 + - "≗": [t: "⠐⠨⠅⠣⠨⠡⠻"] # 0x2257 + - "≘": [t: "⠐⠨⠅⠣⠫⠁⠻"] # 0x2258 + - "≙": [t: "⠐⠨⠅⠣⠸⠣⠻"] # 0x2259 + - "≚": [t: "⠐⠨⠅⠣⠸⠩⠻"] # 0x225a + - "≛": [t: "⠐⠨⠅⠣⠫⠸⠎⠻"] # 0x225b + - "≜": [t: "⠐⠨⠅⠣⠫⠞⠻"] # 0x225c + - "≝": [t: "⠐⠨⠅⠣⠙⠑⠋⠻"] # 0x225d + - "≞": [t: "⠐⠨⠅⠣⠍⠻"] # 0x225e + - "≟": [t: "⠐⠨⠅⠣⠸⠦⠻"] # 0x225f + - "≠": [t: "⠌⠨⠅"] # 0x2260 + - "≢": [t: "⠌⠸⠇"] # 0x2262 + - "≤": [t: "⠐⠅⠱"] # 0x2264 + - "≥": [t: "⠨⠂⠱"] # 0x2265 + - "≦": [t: "⠐⠅⠨⠅"] # 0x2266 + - "≧": [t: "⠨⠂⠨⠅"] # 0x2267 + - "≨": [t: "⠐⠅⠌⠨⠅"] # 0x2268 + - "≩": [t: "⠨⠂⠌⠨⠅"] # 0x2269 + - "≪": [t: "⠐⠅⠈⠐⠅⠻"] # 0x226a + - "≫": [t: "⠨⠂⠈⠨⠂⠻"] # 0x226b + - "≭": [t: "⠌⠈⠣⠠⠣"] # 0x226d + - "≮": [t: "⠌⠐⠅"] # 0x226e + - "≯": [t: "⠌⠨⠂"] # 0x226f + - "≰": [t: "⠌⠐⠅⠱"] # 0x2270 + - "≱": [t: "⠌⠨⠂⠱"] # 0x2271 + - "≲": [t: "⠐⠅⠈⠱"] # 0x2272 + - "≳": [t: "⠨⠂⠈⠱"] # 0x2273 + - "≴": [t: "⠌⠐⠅⠈⠱"] # 0x2274 + - "≵": [t: "⠌⠨⠂⠈⠱"] # 0x2275 + - "≶": [t: "⠐⠅⠨⠂"] # 0x2276 + - "≷": [t: "⠨⠂⠐⠅"] # 0x2277 + - "≸": [t: "⠌⠐⠅⠨⠂"] # 0x2278 + - "≹": [t: "⠌⠨⠂⠐⠅"] # 0x2279 + - "≺": [t: "⠨⠐⠅"] # 0x227a + - "≻": [t: "⠨⠨⠂"] # 0x227b + - "≼": [t: "⠨⠐⠅⠱"] # 0x227c + - "≽": [t: "⠨⠨⠐⠱"] # 0x227d + - "≾": [t: "⠨⠐⠅⠈⠱"] # 0x227e + - "≿": [t: "⠨⠨⠂⠈⠱"] # 0x227f + - "⊀": [t: "⠌⠨⠐⠅"] # 0x2280 + - "⊁": [t: "⠌⠨⠐⠅"] # 0x2281 + - "⊂": [t: "⠸⠐⠅"] # 0x2282 + - "⊃": [t: "⠸⠨⠂"] # 0x2283 + - "⊄": [t: "⠌⠸⠐⠅"] # 0x2284 + - "⊅": [t: "⠌⠸⠨⠂"] # 0x2285 + - "⊆": [t: "⠸⠐⠅⠱"] # 0x2286 + - "⊇": [t: "⠸⠨⠂⠱"] # 0x2287 + - "⊈": [t: "⠌⠸⠐⠅⠱"] # 0x2288 + - "⊉": [t: "⠌⠸⠨⠂⠱"] # 0x2289 + - "⊊": [t: "⠸⠐⠅⠌⠨⠅"] # 0x228a + - "⊋": [t: "⠸⠨⠂⠌⠨⠅"] # 0x228b + - "⊥": [t: "⠫⠏"] # 0x22a5 + - "⋀": [t: "⠈⠩"] # 0x22c0 + - "⋁": [t: "⠈⠬"] # 0x22c1 + - "⋂": [t: "⠨⠩"] # 0x22c2 + - "⋃": [t: "⠨⠬"] # 0x22c3 + - "⋄": [t: "⠫⠩"] # 0x22c4 + - "⋜": [t: "⠱⠐⠅"] # 0x22dc + - "⋝": [t: "⠱⠨⠂"] # 0x22dd + - "⟂": [t: "⠫⠏"] # 0x27c2 + - "⦀": [t: "⠳⠳⠳"] # 0x2980 + - "⦶": [t: "⠫⠉⠸⠫⠳⠻"] # 0x29b6 + - "⦷": [t: "⠫⠉⠸⠫⠫⠇⠻"] # 0x29b7 + - "⦸": [t: "⠫⠉⠸⠫⠸⠡⠻"] # 0x29b8 + - "⦹": [t: "⠫⠉⠸⠫⠫⠏⠻"] # 0x29b9 + - "⦿": [t: "⠫⠉⠸⠫⠔⠔⠻"] # 0x29bf + - "⧀": [t: "⠫⠉⠸⠫⠐⠅⠻"] # 0x29c0 + - "⧁": [t: "⠫⠉⠸⠫⠨⠂⠻"] # 0x29c1 + - "⨀": [t: "⠫⠉⠸⠫⠡⠻"] # 0x2a00 + - "⨁": [t: "⠫⠉⠸⠫⠬⠻"] # 0x2a01 + - "⨂": [t: "⠫⠉⠸⠫⠈⠡⠻"] # 0x2a02 + - "⪯": [t: "⠨⠐⠅⠱"] # 0x2aaf + - "⪰": [t: "⠨⠨⠂⠱"] # 0x2ab0 + - "⪱": [t: "⠨⠐⠅⠌⠱"] # 0x2ab1 + - "⪲": [t: "⠨⠨⠂⠌⠱"] # 0x2ab2 + - "⪳": [t: "⠨⠐⠅⠨⠅"] # 0x2ab3 + - "⪴": [t: "⠨⠨⠂⠨⠅"] # 0x2ab4 + - "⪵": [t: "⠨⠐⠅⠌⠨⠅"] # 0x2ab5 + - "⪶": [t: "⠨⠨⠂⠌⠨⠅"] # 0x2ab6 + - "⪷": [t: "⠨⠐⠅⠈⠱⠈⠱"] # 0x2ab7 + - "⪸": [t: "⠨⠨⠂⠈⠱⠈⠱"] # 0x2ab8 + - "⪹": [t: "⠨⠐⠅⠌⠈⠱⠈⠱"] # 0x2ab9 + - "⪺": [t: "⠨⠨⠂⠌⠈⠱⠈⠱"] # 0x2aba + - "⪻": [t: "⠨⠐⠅⠈⠨⠐⠅⠻"] # 0x2abb + - "⪼": [t: "⠨⠨⠂⠈⠨⠨⠂⠻"] # 0x2abc + - "﹩": [t: "⠈⠎"] # 0xfe69 + - "$": [t: "⠈⠎"] # 0xff04 + - "_": [t: "⠱"] # 0xff3f + - "~": [t: "⠈⠱"] # 0xff5e + - "¢": [t: "⠈⠉"] # 0xffe0 + - "£": [t: "⠈⠇"] # 0xffe1 + - " ̄": [t: "⠱"] # 0xffe3 + - "¥": [t: "⠈⠽"] # 0xffe5 + + # --- Nemeth Default Characters rest chars. --- + + - "ℵ": [t: "⠠⠠⠁"] # 0x2135 + - "ℶ": [t: "⠠⠠⠃"] # 0x2136 + - "ℷ": [t: "⠠⠠⠉"] # 0x2137 + - "ℸ": [t: "⠠⠠⠙"] # 0x2138 + - "à": [t: "⠈⠁"] # 0xe0 + - "á": [t: "⠈⠁"] # 0xe1 + - "â": [t: "⠈⠁"] # 0xe2 + - "ã": [t: "⠈⠁"] # 0xe3 + - "ä": [t: "⠈⠁"] # 0xe4 + - "å": [t: "⠈⠁"] # 0xe5 + - "ç": [t: "⠈⠉"] # 0xe7 + - "è": [t: "⠈⠑"] # 0xe8 + - "é": [t: "⠈⠑"] # 0xe9 + - "ê": [t: "⠈⠑"] # 0xea + - "ë": [t: "⠈⠑"] # 0xeb + - "ì": [t: "⠈⠊"] # 0xec + - "í": [t: "⠈⠊"] # 0xed + - "î": [t: "⠈⠊"] # 0xee + - "ï": [t: "⠈⠊"] # 0xef + - "ñ": [t: "⠈⠝"] # 0xf1 + - "ò": [t: "⠈⠕"] # 0xf2 + - "ó": [t: "⠈⠕"] # 0xf3 + - "ô": [t: "⠈⠕"] # 0xf4 + - "õ": [t: "⠈⠕"] # 0xf5 + - "ö": [t: "⠈⠕"] # 0xf6 + - "ù": [t: "⠈⠥"] # 0xf9 + - "ú": [t: "⠈⠥"] # 0xfa + - "û": [t: "⠈⠥"] # 0xfb + - "ü": [t: "⠈⠥"] # 0xfc + - "ý": [t: "⠈⠽"] # 0xfd + - "ÿ": [t: "⠈⠽"] # 0xff + + - "À": [t: "⠠⠈⠁"] # 0xc0 + - "Á": [t: "⠠⠈⠁"] # 0xc1 + - "Â": [t: "⠠⠈⠁"] # 0xc2 + - "Ã": [t: "⠠⠈⠁"] # 0xc3 + - "Ä": [t: "⠠⠈⠁"] # 0xc4 + - "Å": [t: "⠠⠈⠁"] # 0xc5 + - "Ç": [t: "⠠⠈⠉"] # 0xc7 + - "È": [t: "⠠⠈⠑"] # 0xc8 + - "É": [t: "⠠⠈⠑"] # 0xc9 + - "Ê": [t: "⠠⠈⠑"] # 0xca + - "Ë": [t: "⠠⠈⠑"] # 0xcb + - "Ì": [t: "⠠⠈⠊"] # 0xcc + - "Í": [t: "⠠⠈⠊"] # 0xcd + - "Î": [t: "⠠⠈⠊"] # 0xce + - "Ï": [t: "⠠⠈⠊"] # 0xcf + - "Ñ": [t: "⠠⠈⠝"] # 0xd1 + - "Ò": [t: "⠠⠈⠕"] # 0xd2 + - "Ó": [t: "⠠⠈⠕"] # 0xd3 + - "Ô": [t: "⠠⠈⠕"] # 0xd4 + - "Ö": [t: "⠠⠈⠕"] # 0xd6 + - "Ù": [t: "⠠⠈⠥"] # 0xd9 + - "Ú": [t: "⠠⠈⠥"] # 0xda + - "Û": [t: "⠠⠈⠥"] # 0xdb + - "Ü": [t: "⠠⠈⠥"] # 0xdc + - "Ý": [t: "⠠⠈⠽"] # 0xdd + - "←": [t: "⠫⠪⠒⠒"] # 0x2190 + + - "↑": # 0x2191 + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠣"] + else: [t: "⠫⠣⠒⠒⠕"] + + - "↓": # 0x2193 + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠩"] + else: [t: "⠫⠩⠒⠒⠕"] + + - "↔": [t: "⠫⠪⠒⠒⠕"] # 0x2194 + - "↕": [t: "⠫⠣⠩⠪⠒⠒⠕"] # 0x2195 + - "↖": [t: "⠫⠘⠪⠒⠒"] # 0x2196 + - "↗": [t: "⠫⠘⠒⠒⠕"] # 0x2197 + - "↘": [t: "⠫⠰⠒⠒⠕"] # 0x2198 + - "↙": [t: "⠫⠰⠪⠒⠒"] # 0x2199 + - "↚": [t: "⠳⠈⠫⠪⠒⠒⠻"] # 0x219a + - "↛": [t: "⠳⠈⠫⠒⠒⠕⠻"] # 0x219b + - "↜": [t: "⠫⠪⠔⠒⠢"] # 0x219c + - "↝": [t: "⠫⠔⠒⠢⠕"] # 0x219d + - "↞": [t: "⠫⠪⠪⠒⠒"] # 0x219e + - "↟": [t: "⠫⠣⠒⠒⠕⠕"] # 0x219f + - "↠": [t: "⠫⠒⠒⠕⠕"] # 0x21a0 + - "↡": [t: "⠫⠩⠒⠒⠕⠕"] # 0x21a1 + - "↢": [t: "⠫⠪⠒⠒⠠⠽"] # 0x21a2 + - "↣": [t: "⠫⠠⠯⠒⠒⠕"] # 0x21a3 + - "↤": [t: "⠫⠪⠒⠒⠳"] # 0x21a4 + - "↥": [t: "⠫⠣⠳⠒⠒⠕"] # 0x21a5 + - "↦": [t: "⠫⠳⠒⠒⠕"] # 0x21a6 + - "↧": [t: "⠫⠩⠳⠒⠒⠕"] # 0x21a7 + - "↨": [t: "⠫⠪⠒⠳⠒⠕"] # 0x21a8 + - "↩": [t: "⠫⠪⠒⠒⠠⠕"] # 0x21a9 + - "↪": [t: "⠫⠠⠪⠒⠒⠕"] # 0x21aa + - "↫": [t: "⠫⠪⠒⠒⠨⠡"] # 0x21ab + - "↬": [t: "⠫⠨⠡⠒⠒⠕"] # 0x21ac + - "↭": [t: "⠫⠪⠔⠒⠢⠕"] # 0x21ad + - "↮": [t: "⠳⠈⠫⠪⠒⠒⠕"] # 0x21ae + - "↯": [t: "⠫⠩⠔⠢⠔"] # 0x21af + - "↴": [t: "⠫⠠⠳⠒⠒⠕"] # 0x21b4 + - "↵": [t: "⠫⠩⠠⠳⠒⠒⠕"] # 0x21b5 + - "↶": [t: "⠫⠢⠔⠕"] # 0x21b6 + - "↷": [t: "⠫⠪⠢⠔"] # 0x21b7 + - "↺": [t: "⠫⠢⠔⠕"] # 0x21ba + - "↻": [t: "⠫⠪⠢⠔"] # 0x21bb + - "⇄": [t: "⠫⠒⠒⠕⠫⠪⠒⠒"] # 0x21c4 + - "⇅": [t: "⠫⠣⠒⠒⠕⠐⠫⠩⠒⠒⠕"] # 0x21c5 + - "⇆": [t: "⠫⠪⠒⠒⠫⠒⠒⠕"] # 0x21c6 + - "⇇": [t: "⠫⠚⠒⠒⠫⠚⠒⠒"] # 0x21c7 + - "⇈": [t: "⠫⠣⠒⠒⠕⠐⠫⠣⠒⠒⠕"] # 0x21c8 + - "⇉": [t: "⠫⠒⠒⠕⠫⠒⠒⠕"] # 0x21c9 + - "⇊": [t: "⠫⠩⠒⠒⠕⠐⠫⠩⠒⠒⠕"] # 0x21ca + - "⇍": [t: "⠳⠈⠫⠪⠪⠒⠒"] # 0x21cd + - "⇎": [t: "⠳⠈⠫⠪⠪⠒⠒⠕⠕"] # 0x21ce + - "⇏": [t: "⠳⠈⠫⠒⠒⠕⠕"] # 0x21cf + - "⇐": [t: "⠫⠪⠶⠶"] # 0x21d0 + - "⇑": [t: "⠫⠣⠶⠶⠕"] # 0x21d1 + - "⇒": [t: "⠫⠶⠶⠕"] # 0x21d2 + - "⇓": [t: "⠫⠣⠶⠶⠕"] # 0x21d3 + - "⇔": [t: "⠫⠪⠶⠶⠕"] # 0x21d4 + - "⇕": [t: "⠫⠣⠪⠶⠶⠕"] # 0x21d5 + - "⇖": [t: "⠫⠘⠪⠶⠶"] # 0x21d6 + - "⇗": [t: "⠫⠘⠶⠶⠕"] # 0x21d7 + - "⇘": [t: "⠫⠰⠶⠶⠕"] # 0x21d8 + - "⇙": [t: "⠫⠰⠪⠪⠒⠒"] # 0x21d9 + - "⇚": [t: "⠫⠪⠪⠶⠶"] # 0x21da FIX: how to represent triple shafts? + - "⇛": [t: "⠫⠶⠶⠕⠕"] # 0x21db FIX: how to represent triple shafts? + - "⇜": [t: "⠫⠪⠢⠤⠔⠒⠢"] # 0x21dc + - "⇝": [t: "⠫⠢⠤⠔⠒⠢⠕"] # 0x21dd + - "⇞": [t: "⠳⠳⠈⠫⠣⠒⠒⠕⠻"] # 0x21de + - "⇟": [t: "⠳⠳⠈⠫⠩⠒⠒⠕⠻"] # 0x21df + - "⇠": [t: "⠫⠪⠒⠒"] # 0x21e0 + - "⇡": [t: "⠫⠣⠒⠒⠕"] # 0x21e1 + - "⇢": [t: "⠫⠒⠒⠕"] # 0x21e2 + - "⇣": [t: "⠫⠩⠒⠒⠕"] # 0x21e3 + - "⇤": [t: "⠫⠳⠪⠒⠒"] # 0x21e4 + - "⇥": [t: "⠫⠒⠒⠕⠳"] # 0x21e5 + - "⇦": [t: "⠫⠸⠪⠒⠒"] # 0x21e6 + - "⇧": [t: "⠫⠣⠸⠒⠒⠕"] # 0x21e7 + - "⇨": [t: "⠫⠸⠒⠒⠕"] # 0x21e8 + - "⇩": [t: "⠫⠩⠸⠒⠒⠕"] # 0x21e9 + - "⇳": [t: "⠫⠣⠸⠪⠒⠒⠕"] # 0x21f3 + - "⇴": [t: "⠫⠒⠒⠕⠨⠡"] # 0x21f4 + - "⇵": [t: "⠫⠩⠒⠒⠕⠐⠫⠣⠒⠒⠕"] # 0x21f5 + - "⇶": [t: "⠫⠒⠒⠕⠫⠒⠒⠕⠫⠒⠒⠕"] # 0x21f6 + - "⇷": [t: "⠳⠈⠫⠪⠒⠒⠻"] # 0x21f7 + - "⇸": [t: "⠳⠈⠫⠒⠒⠕⠻"] # 0x21f8 + - "⇹": [t: "⠳⠈⠫⠪⠒⠒⠕"] # 0x21f9 + - "⇺": [t: "⠳⠳⠈⠫⠪⠒⠒⠻"] # 0x21fa + - "⇻": [t: "⠳⠳⠈⠫⠒⠒⠕⠻"] # 0x21fb + - "⇼": [t: "⠳⠳⠈⠫⠪⠒⠒⠕"] # 0x21fc + - "⇽": [t: "⠫⠳⠒⠒"] # 0x21fd + - "⇾": [t: "⠫⠒⠒⠳"] # 0x21fe + - "⇿": [t: "⠫⠳⠒⠒⠳"] # 0x21ff + + - "ⅆ": [t: "⠙"] # 0x2146 + - "ⅇ": [t: "⠑"] # 0x2147 + - "ⅈ": [t: "⠊"] # 0x2148 + - "⌜": [t: "⠈⠘⠷"] # 0x231c + - "⌝": [t: "⠈⠘⠾"] # 0x231d + - "⌞": [t: "⠈⠰⠷"] # 0x231e + - "⌟": [t: "⠈⠰⠾"] # 0x231f + - "〈": [t: "⠨⠨⠷"] # 0x2329 + - "〉": [t: "⠨⠨⠾"] # 0x232a + - "⏞": [t: "⠨⠷"] # 0x23de + - "⏟": [t: "⠨⠾"] # 0x23df + - "⎴": [t: "⠈⠷"] # 0x23b4 + - "⎵": [t: "⠈⠾"] # 0x23b5 + - "⟪": [t: "⠨⠨⠨⠷"] # 0x27ea + - "⟫": [t: "⠨⠨⠨⠾"] # 0x27eb + - "〈": [t: "⠨⠨⠷"] # 0x3008 + - "〉": [t: "⠨⠨⠾"] # 0x3009 + - "《": [t: "⠨⠨⠨⠷"] # 0x300a + - "》": [t: "⠨⠨⠨⠾"] # 0x300b + - "「": [t: "⠈⠘⠷"] # 0x300c + - "」": [t: "⠈⠘⠾"] # 0x300d + - "↼": [t: "⠫⠈⠪⠒⠒"] # 0x21bc + - "↽": [t: "⠫⠠⠪⠒⠒"] # 0x21bd + - "↾": [t: "⠫⠣⠒⠒⠠⠕"] # 0x21be + - "↿": [t: "⠫⠣⠒⠒⠈⠕"] # 0x21bf + - "⇀": [t: "⠫⠒⠒⠈⠕"] # 0x21c0 + - "⇁": [t: "⠫⠒⠒⠠⠕"] # 0x21c1 + - "⇂": [t: "⠫⠪⠒⠒⠈⠕"] # 0x21c2 + - "⇃": [t: "⠫⠩⠒⠒⠠⠕"] # 0x21c3 + - "⇋": # 0x21cb + + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠪⠒⠫⠒⠕"] + else: [t: "⠫⠈⠪⠒⠒⠫⠒⠒⠈⠕"] + - "⇌": # 0x21cc + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠕⠫⠪⠒"] + else: [t: "⠫⠒⠒⠈⠕⠫⠈⠪⠒⠒"] + + - "℔": [t: "⠳"] # 0x2114 + - "™": [t: "⠘⠞"] # 0x2122 + - "Å": [t: "⠈⠠⠁"] # 0x212b + - "­": [t: "⠤"] # 0xad + - " -​": [t: "W"] # 0x2000 - 0x200b (various spaces / ZWSP) + - "
": [t: "W"] # 0x2028 + - "
": [t: "W"] # 0x2029 + - " ": [t: "W"] # 0x202f + - " ": [t: "W"] # 0x205f + - "₣": [t: "⠈⠋"] # 0x20A3 (French franc sign + - "₦": [t: "⠈⠝"] # 0x2046 (Naira sign) + - "₩": [t: "⠈⠺"] # 0x20A9 (Won sign) + - "€": [t: "⠈⠑"] # 0x20AC (Euro sign) + - "": [t: "W"] # 0xfeff + - "☆": [t: "⠫⠎"] # 0x2606 + - "✕": [t: "⠈⠡"] # 0x2715 + - "¼": [t: "⠹⠂⠌⠲⠼"] # 0xbc + - "½": [t: "⠹⠂⠌⠆⠼"] # 0xbd + - "¾": [t: "⠹⠒⠌⠲⠼"] # 0xbe + - "⅐": [t: "⠹⠂⠌⠶⠼"] # 0x2150 + - "⅑": [t: "⠹⠂⠌⠔⠼"] # 0x2151 + - "⅒": [t: "⠹⠂⠌⠂⠴⠼"] # 0x2152 + - "⅓": [t: "⠹⠂⠌⠒⠼"] # 0x2153 + - "⅔": [t: "⠹⠆⠌⠒⠼"] # 0x2154 + - "⅕": [t: "⠹⠂⠌⠢⠼"] # 0x2155 + - "⅖": [t: "⠹⠆⠌⠢⠼"] # 0x2156 + - "⅗": [t: "⠹⠒⠌⠢⠼"] # 0x2157 + - "⅘": [t: "⠹⠲⠌⠢⠼"] # 0x2158 + - "⅙": [t: "⠹⠂⠌⠖⠼"] # 0x2159 + - "⅚": [t: "⠹⠢⠌⠖⠼"] # 0x215a + - "⅛": [t: "⠹⠂⠌⠦⠼"] # 0x215b + - "⅜": [t: "⠹⠒⠌⠦⠼"] # 0x215c + - "⅝": [t: "⠹⠢⠌⠦⠼"] # 0x215d + - "⅞": [t: "⠹⠶⠌⠦⠼"] # 0x215e + - "⅟": [t: "⠹⠂⠌⠼"] # 0x215f + - "↉": [t: "⠹⠴⠌⠒⠼"] # 0x2189 + - "㉈": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠂⠴⠻⠻"] # 0x3248 + - "㉉": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠆⠴⠻⠻"] # 0x3249 + - "㉊": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠒⠴⠻⠻"] # 0x324a + - "㉋": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠲⠴⠻⠻"] # 0x324b + - "㉌": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠢⠴⠻⠻"] # 0x324c + - "㉍": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠖⠴⠻⠻"] # 0x324d + - "㉎": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠶⠴⠻⠻"] # 0x324e + - "㉏": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠦⠴⠻⠻"] # 0x324f + + + - "‘": [t: "P⠠⠦"] # 0x2018 (Left single quotation mark) + - "’": [t: "P⠠⠴"] # 0x2019 (Right single quotation mark) + - "“": [t: "P⠦"] # 0x201C (Left double quotation mark) + - "”": [t: "P⠴"] # 0x201D (Right double quotation mark) + - "‰": [t: "`00"] + - "ℏ": [t: "⠈⠓"] # 0x210F (Planck constant over two pi) + - "ℓ": [t: "TE⠇"] # 0x2113 (Script small l (differs from 1d4c1: 4-56-123)) + - "℘": [tc: "TCL⠏"] # 0x2118 (Script Capital P) +# - "ℝ": [t: ""] # 0x211D (Double-struck capital R (no nemeth double struck)) +# - "ⅆ": [t: ""] # 0x2146 (Double-struck italic small d) +# - "ⅇ": [t: ""] # 0x2147 (Double-struck italic small e) +# - "⇚": [t: "⠀⠫⠪⠸⠸⠀"] # 0x21DA (Leftwards triple arrow) +# - "⇛": [t: "⠀⠫⠸⠸⠕⠀"] # 0x21DB (Rightwards triple arrow) + - "∔": [t: "⠐⠬⠣⠡⠻"] # 0x2214 (Dot plus) + - "√": [t: "⠜"] # 0x221A (Square root) + - "∛": [t: "⠣⠒⠜"] # 0x221B (Cube root) + - "∜": [t: "⠣⠲⠜"] # 0x221C (Fourth root) + - "∡": [t: "⠫⠪⠸⠫⠫⠁⠻"] # 0x2221 (Measured angle) + - "∹": [t: "⠤⠐⠂"] # 0x2239 (Excess) + - "∺": [t: "⠐⠤⠩⠡⠡⠣⠡⠡⠻"] # 0x223A (Geometric proportion) + - "∻": [t: "⠐⠈⠱⠩⠡⠣⠡⠻"] # 0x223B (Homothetic) + - "∽": [t: "⠠⠱"] # 0x223D (Reversed tilde) + - "≋": [t: "⠈⠱⠈⠱⠈⠱"] # 0x224B (Triple tilde) + - "≌": [t: "⠠⠱⠨⠅"] # 0x224C (All equal to) + - "≏": [t: "⠈⠣⠱"] # 0x224F (Difference between) + - "≔": [t: "⠐⠂⠨⠅"] # 0x2254 (Colon equals) + - "≕": [t: "⠨⠅⠐⠂"] # 0x2255 (Equals colon) + - "≖": [t: "⠀⠨⠡⠈⠨⠅⠻⠀"] # 0x2256 (Ring in equal to) + - "⊌": [t: "⠨⠬⠈⠫⠪⠒⠻"] # 0x228C (Multiset) + - "⊍": [t: "⠡⠈⠨⠬⠻"] # 0x228D (Multiset multiplication) + - "⊎": [t: "⠬⠈⠨⠬⠻"] # 0x228E (Multiset union) + - "⊕": [t: "⠫⠉⠸⠫⠬⠻"] # 0x2295 (Circled plus) + - "⊖": [t: "⠫⠉⠸⠫⠤⠻"] # 0x2296 (Circled minus) + - "⊗": [t: "⠫⠉⠸⠫⠈⠡⠻"] # 0x2297 (Circled times) + - "⊘": [t: "⠫⠉⠸⠫⠸⠌⠻"] # 0x2298 (Circled division slash) + - "⊙": [t: "⠫⠉⠸⠫⠡⠻"] # 0x2299 (Circled dot operator) + - "⊚": [t: "⠫⠉⠸⠫⠘⠨⠡⠻"] # 0x229a (Circled ring operator) + - "⊛": [t: "⠫⠉⠸⠫⠈⠼⠻"] # 0x229B (Circled asterisk operator) + - "⊜": [t: "⠫⠉⠸⠫⠨⠅⠻"] # 0x229C (Circled equals) + - "⊝": [t: "⠫⠉⠸⠫⠤⠤⠻"] # 0x229D (Circled dash) + - "⊞": [t: "⠫⠲⠸⠫⠬⠻"] # 0x229E (Squared plus) + - "⊟": [t: "⠫⠲⠸⠫⠤⠻"] # 0x229F (Squared minus) + - "⊠": [t: "⠫⠲⠸⠫⠈⠡⠻"] # 0x22A0 (Squared times) + - "⊡": [t: "⠫⠲⠸⠫⠡⠻"] # 0x22A1 (Squared dot operator) + - "⊢": [t: "⠫⠳⠒"] # 0x22A2 (Right tack) + - "⊣": [t: "⠫⠒⠳"] # 0x22A3 (Left tack) + - "⊤": [t: "⠫⠩⠳⠒"] # 0x22A4 (Down tack) +# - "⊥": [t: "⠀⠫⠏⠀ or ⠀⠫⠣⠳⠒⠀"] # 0x22A5 (Up tack (See also 27C2)) +# - "⊦": [t: ""] # 0x22A6 (Assertion) +# - "⊨": [t: ""] # 0x22A8 (TRUE) +# - "⊲": [t: ""] # 0x22B2 (Normal subgroup of) +# - "⊳": [t: ""] # 0x22B3 (Contains as normal subgroup) +# - "⊴": [t: ""] # 0x22B4 (Normal subgroup of or equal to) +# - "⊵": [t: ""] # 0x22B5 (Contains as normal subgroup or equal to) + - "⊶": [t: "⠫⠨⠡⠒⠡"] # 0x22B6 (Original of) + - "⊷": [t: "⠫⠡⠒⠨⠡"] # 0x22B7 (Image of) + - "⊸": [t: "⠫⠒⠨⠡"] # 0x22B8 (Multimap) +# - "⊾": [t: ""] # 0x22BE (Right angle w arc) + - "⊿": [t: "⠫⠞⠨⠗⠻"] # 0x22BF (Right triangle) + - "⋅": [t: "⠡"] # 0x22C5 (Dot operator) + - "∙": [t: "⠡"] # 0x2219 -- similar looking to 0x22c5, so using the same braille + - "⋆": [t: "⠫⠎"] # 0x22C6 (Star operator) + - "⋍": [t: "⠠⠱⠱"] # 0x22CD (Reversed tilde equals) + - "⋖": [t: "⠡⠈⠐⠅⠻"] # 0x22D6 (Less-than w dot) + - "⋗": [t: "⠡⠈⠨⠂⠻"] # 0x22D7 (Greater-than w dot) + - "⋘": [t: "⠐⠅⠈⠐⠅⠈⠐⠅⠻"] # 0x22D8 (Much less-than) + - "⋙": [t: "⠨⠂⠈⠨⠂⠈⠨⠂⠻"] # 0x22D9 (Much greater-than) + - "⋲": [t: "⠱⠈⠈⠑⠻"] # 0x22F2 (Element of w long horizontal stroke) + - "⋵": [t: "⠐⠈⠑⠣⠡⠻"] # 0x22F5 (Element of w dot above) + - "⋶": [t: "⠱⠈⠑"] # 0x22F6 (Element of w overbar) + - "⋺": [t: "⠱⠈⠈⠢⠻"] # 0x22FA (Contains w long horizontal stroke) + - "⋽": [t: "⠱⠈⠢"] # 0x22FD (Contains w overbar) + - "⌈": [t: "⠈⠘⠷"] # 0x2308 (Left ceiling) + - "⌉": [t: "⠈⠘⠾"] # 0x2309 (Right ceiling) + - "⌊": [t: "⠈⠰⠷"] # 0x230A (Left floor) + - "⌋": [t: "⠈⠰⠾"] # 0x230B (Right floor) + - "⌢": [t: "⠫⠁"] # 0x2322 (Frown) + - "⌣": [t: "⠫⠄"] # 0x2323 (Smile) + - "■": [t: "⠫⠸⠲"] # 0x25A0 (Filled square) + - "▫": [t: "⠫⠲"] # 0x25AB (Small white Square) + - "□": [t: "⠫⠲"] # 0x25A1 (Square) + - "◻": [t: "⠫⠲"] # 0x25FB (Square) + - "▬": [t: "⠫⠸⠗"] # 0x25AC (Filled rectangle) + - "▭": [t: "⠫⠗"] # 0x25AD (Rectangle) + - "▲": [t: "⠫⠸⠞"] # 0x25B2 (Black up-pointing triangle) + - "△": [t: "⠫⠞"] # 0x25B3 (White up-pointing triangle) + - "▼": [t: "⠸⠨⠫"] # 0x25BC (Black down-pointing triangle) + - "○": [t: "⠫⠉"] # 0x25CB (White circle) + - "●": [t: "⠫⠸⠉"] # 0x25CF (Black circle) + - "◫": [t: "⠫⠲⠸⠫⠳⠻"] # 0x25EB (White square w vertical bisecting line) +# - "⊥": [t: "⠫⠏"] # 0x27C2 (Perpendicular) + - "⟃": [t: "⠨⠡⠈⠸⠐⠅⠻"] # 0x27C3 (Open subset) + - "⟄": [t: "⠨⠡⠈⠸⠨⠂⠻"] # 0x27C4 (Open superset) + - "⟜": [t: "⠫⠨⠡⠒⠒"] # 0x27DC (Left multimap) + - "⟝": [t: "⠫⠳⠒⠒"] # 0x27DD (Long right tack) + - "⟞": [t: "⠫⠒⠒⠳"] # 0x27DE (Long left tack) + - "⟟": [t: "⠫⠣⠳⠒⠒⠨⠡"] # 0x27DF (Up tack w circle above) + - "⟦": [t: "⠈⠸⠷"] # 0x27E6 (Mathematical left white square bracket) + - "⟧": [t: "⠈⠸⠾"] # 0x27E7 (Mathematical right white square bracket) + - "⟨": [t: "⠨⠨⠷"] # 0x27E8 (Mathematical left angle bracket) + - "⟩": [t: "⠨⠨⠾"] # 0x27E9 (Mathematical right angle bracket) + - "⟵": [t: "⠀⠫⠪⠒⠒⠒⠀"] # 0x27F5 (Long leftwards arrow ) + - "⟶": [t: "⠀⠫⠒⠒⠒⠕⠀"] # 0x27F6 (Long rightwards arrow) + - "⟷": [t: "⠀⠫⠪⠒⠒⠒⠕⠀"] # 0x27F7 (Long left right arrow) + - "⟸": [t: "⠀⠫⠪⠶⠶⠶⠀"] # 0x27F8 (Long leftwards arrow ) + - "⟹": [t: "⠀⠫⠶⠶⠶⠕⠀"] # 0x27F9 (Long rightwards arrow) + - "⟺": [t: "⠀⠫⠪⠶⠶⠶⠕⠀"] # 0x27FA (Long left right arrow) + - "⟻": [t: "⠀⠫⠪⠒⠒⠒⠳⠀"] # 0x27FB (Long leftwards arrow from bar) + - "⟼": [t: "⠀⠫⠳⠒⠒⠒⠕⠀"] # 0x27FC (Long rightwards arrow from bar) + - "⟽": [t: "⠀⠫⠪⠶⠶⠶⠳⠀"] # 0x27FD (Long leftwards double arrow from bar) + - "⟾": [t: "⠀⠫⠳⠶⠶⠶⠕⠀"] # 0x27FE (Long rightwards double arrow from bar) + - "⟿": [t: "⠀⠫⠢⠤⠔⠒⠢⠤⠔⠒⠢⠕⠀"] # 0x27FF (Long rightwards squiggle arrow) + - "⤡": [t: "⠀⠫⠘⠪⠒⠒⠕⠀"] # 0x2921 (North west and south east arrow) + - "⤢": [t: "⠀⠫⠰⠪⠒⠒⠕⠀"] # 0x2922 (North east and south west arrow) + - "🣐": # 0x1f8d0 (Long rightwards arrow over leftwards arrow (equilibrium)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠕⠫⠪⠒"] + else: [t: "⠫⠒⠒⠈⠕⠫⠠⠪⠒⠒"] + - "🣑": # 0x1f8d1 (Long rightwards harpoon over leftwards harpoon (equilibrium)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠕⠫⠪⠒"] + else: [t: "⠫⠒⠒⠈⠕⠫⠠⠪⠒⠒"] + - "🣒": # 0x1f8d2 (Long rightwards harpoon over short leftwards harpoon (equilibrium)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠒⠕⠫⠪⠒"] + else: [t: "⠫⠒⠒⠈⠕⠫⠈⠪⠒⠒"] + - "🣓": # 0x1f8d3 (Short rightwards harpoon over long leftwards harpoon (equilibrium, trend to the right)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠕⠫⠪⠒⠒"] + else: [t: "⠫⠒⠈⠕⠫⠠⠪⠒⠒"] + - "🣔": # 0x1f8d4 (Long leftwards harpoon over short rightwards harpoon (equilibrium, trend to the left)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠪⠒⠒⠫⠒⠕"] + else: [t: "⠫⠈⠪⠒⠒⠫⠒⠠⠕"] + - "🣕": # 0x1f8d5 (Short leftwards harpoon over long rightwards harpoon (equilibrium, trend to the left)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠪⠒⠫⠒⠒⠕"] + else: [t: "⠫⠈⠪⠒⠫⠒⠒⠠⠕"] + - "⥂": # 0x2942 (Long rightwards harpoon over short leftwards harpoon (equilibrium)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠒⠕⠫⠪⠒"] + else: [t: "⠫⠒⠒⠈⠕⠫⠈⠪⠒⠒"] + - "⥄": # 0x2944 (Short rightwards harpoon over long leftwards harpoon (equilibrium, trend to the right)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠕⠫⠪⠒⠒"] + else: [t: "⠫⠒⠈⠕⠫⠠⠪⠒⠒"] + - "⥃": # 0x2943 (Long leftwards harpoon over short rightwards harpoon (equilibrium, trend to the left)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠪⠒⠒⠫⠒⠕"] + else: [t: "⠫⠈⠪⠒⠒⠫⠒⠠⠕"] + - "🣖": [t: "⠌⠫⠒⠒⠕"] # 0x1f8d6 (long rightwards arrow with through X) + - "🣗": [t: "⠌⠫⠒⠒⠕"] # 0x1f8d7 (long rightwards arrow with double slash) chem code says it is same as 0x1f8d6 + + + - "⦃": [t: "⠨⠸⠷"] # 0x2983 (Left white curly bracket) + - "⦄": [t: "⠨⠸⠾"] # 0x2984 (Right white curly bracket) + - "⦑": [t: "⠡⠈⠨⠨⠷⠻"] # 0x2991 (Left angle bracket w dot) + - "⦒": [t: "⠡⠈⠨⠨⠾⠻"] # 0x2992 (Right angle bracket w dot) + - "⧄": [t: "⠫⠲⠸⠫⠔⠻"] # 0x29C4 (Square rising diagonal slash) + - "⧅": [t: "⠫⠲⠸⠫⠢⠻"] # 0x29C5 (Square falling diagonal slash) + - "⧆": [t: "⠫⠲⠸⠫⠈⠼⠻"] # 0x29C6 (Squared asterisk) + - "⧊": [t: "⠐⠫⠞⠣⠡⠻"] # 0x29CA (Triangle w dot above) + - "⧋": [t: "⠫⠞⠱"] # 0x29CB (Triangle w underbar) + - "⧌": [t: "⠫⠞⠎"] # 0x29CC (s in triangle §114) + - "⧦": [t: "⠫⠳⠶⠶⠳"] # 0x29E6 (Gleich stark) + - "⨌": [t: "⠮⠮⠮⠮"] # 0x2A0C (Quadruple integral operator) + - "⨍": [t: "⠮⠈⠱⠻"] # 0x2A0D (Finite part integral) + - "⨎": [t: "⠮⠈⠱⠱⠻"] # 0x2A0E (Integral w double stroke) + - "⨖": [t: "⠮⠈⠫⠲⠻"] # 0x2A16 (Quaternion integral operator) + - "⨘": [t: "⠮⠈⠈⠡⠻"] # 0x2A18 (Integral w times sign) + - "⨙": [t: "⠮⠈⠨⠩⠻"] # 0x2A19 (Integral w intersection) + - "⨚": [t: "⠮⠈⠨⠬⠻"] # 0x2A1A (Integral w union) + - "⨛": [t: "⠣⠮"] # 0x2A1B (Integral w overbar (upper)) + - "⨜": [t: "⠩⠮"] # 0x2A1C (Integral w underbar (lower)) + - "⨢": [t: "⠐⠬⠣⠨⠡⠻"] # 0x2A22 (Plus sign w small circle above) + - "⨣": [t: "⠐⠬⠣⠸⠣⠻"] # 0x2A23 (Plus sign w circumflex accent above) + - "⨤": [t: "⠐⠬⠣⠈⠱⠻"] # 0x2A24 (Plus sign w tilde above) + - "⨥": [t: "⠐⠬⠩⠡⠻"] # 0x2A25 (Plus sign w dot below) + - "⨪": [t: "⠐⠱⠩⠡⠻"] # 0x2A2A (Minus sign w dot below) + - "⨰": [t: "⠐⠈⠡⠣⠡⠻"] # 0x2A30 (Multiplication sign w dot above) + - "⨱": [t: "⠈⠡⠱"] # 0x2A31 (Multiplication sign w underbar) + - "⨸": [t: "⠫⠉⠸⠫⠨⠌⠻"] # 0x2A38 (Circled division sign) + - "⨹": [t: "⠫⠞⠸⠫⠬⠻"] # 0x2A39 (Plus sign in triangle) + - "⨺": [t: "⠫⠞⠸⠫⠤⠻"] # 0x2A3A (Minus sign in triangle) + - "⨻": [t: "⠫⠞⠸⠫⠈⠡⠻"] # 0x2A3B (Multiplication sign in triangle) + - "⩀": [t: "⠡⠈⠨⠩⠻"] # 0x2A40 (Intersection w dot) + - "⩁": [t: "⠤⠈⠨⠬⠻"] # 0x2A41 (Union w minus sign) + - "⩂": [t: "⠱⠨⠬"] # 0x2A42 (Union w overbar) + - "⩃": [t: "⠱⠨⠩"] # 0x2A43 (Intersection w overbar) + - "⩑": [t: "⠐⠈⠩⠣⠡⠻"] # 0x2A51 (Logical AND w dot above) + - "⩒": [t: "⠐⠈⠬⠣⠡⠻"] # 0x2A52 (Logical OR w dot above) + - "⩜": [t: "⠱⠈⠈⠩⠻"] # 0x2A5C (Logical AND with horizontal dash) + - "⩝": [t: "⠱⠈⠈⠬⠻"] # 0x2A5D (Logical OR with horizontal dash) + - "⩞": [t: "⠱⠱⠈⠩"] # 0x2A5E (Logical AND w double overbar) + - "⩟": [t: "⠈⠩⠱"] # 0x2A5F (Logical AND w underbar) + - "⩠": [t: "⠈⠩⠱⠱"] # 0x2A60 (Logical AND w double underbar) + - "⩢": [t: "⠱⠱⠈⠬"] # 0x2A62 (Logical OR w double overbar) + - "⩣": [t: "⠈⠬⠱⠱"] # 0x2A63 (Logical OR w double underbar) + - "⩦": [t: "⠐⠨⠅⠩⠡⠻"] # 0x2A66 (Equals sign w dot below) + - "⩧": [t: "⠐⠸⠇⠣⠡⠻"] # 0x2A67 (Identical w dot above) + - "⩪": [t: "⠐⠈⠱⠣⠡⠻"] # 0x2A6A (Tilde operator w dot above) + - "⩬": [t: "⠈⠱⠱⠈⠱"] # 0x2A6C (Similar minus similar) + - "⩭": [t: "⠐⠈⠱⠨⠅⠣⠡⠻"] # 0x2A6D (Congruent w dot above) + - "⩮": [t: "⠐⠨⠅⠣⠈⠼⠻"] # 0x2A6E (Equals w asterisk) + - "⩯": [t: "⠐⠈⠱⠈⠱⠣⠸⠣⠻"] # 0x2A6F (Almost equal to w circumflex) + - "⩰": [t: "⠈⠱⠈⠱⠨⠅"] # 0x2A70 (Approximately equal or equal to) + - "⩱": [t: "⠨⠅⠬"] # 0x2A71 (Equals sign above plus sign) + - "⩲": [t: "⠬⠨⠅"] # 0x2A72 (Plus sign above equals sign) + - "⩳": [t: "⠨⠅⠈⠱"] # 0x2A73 (Equals sign above tilde operator) + - "⩴": [t: "⠐⠂⠐⠂⠨⠅"] # 0x2A74 (Double colon equal) + - "⩵": [t: "⠨⠅⠨⠅"] # 0x2A75 (Two consecutive equals signs) + - "⩶": [t: "⠨⠅⠨⠅⠨⠅"] # 0x2A76 (Three consecutive equals signs) + - "⩷": [t: "⠐⠨⠅⠩⠡⠡⠣⠡⠡⠻"] # 0x2A77 (Equals sign w two dots above and two dots below) + - "⩸": [t: "⠐⠸⠇⠣⠡⠡⠡⠡⠻"] # 0x2A78 (Equivalent w four dots above) + - "⩹": [t: "⠐⠅⠈⠨⠡⠻"] # 0x2A79 (Less than w circle inside) + - "⩺": [t: "⠨⠂⠈⠨⠡⠻"] # 0x2A7A (Greater than w circle inside) + - "⩻": [t: "⠐⠐⠅⠣⠸⠦⠻"] # 0x2A7B (Less-than w question mark above) + - "⩼": [t: "⠐⠨⠂⠣⠸⠦⠻"] # 0x2A7C (Greater-than w question mark above) + - "⪅": [t: "⠐⠅⠈⠱⠈⠱"] # 0x2A85 (Less-than or approximate) + - "⪆": [t: "⠨⠂⠈⠱⠈⠱"] # 0x2A86 (Greater-than or approximate) + - "⪋": [t: "⠐⠅⠨⠅⠨⠂"] # 0x2A8B (Less-than above double-line equal above greater-than) + - "⪌": [t: "⠨⠂⠨⠅⠐⠅"] # 0x2A8C (Greater-than above double-line equal above less-than) + - "⪍": [t: "⠐⠅⠈⠱⠱"] # 0x2A8D (Less-than above similar or equal to) + - "⪎": [t: "⠨⠂⠈⠱⠱"] # 0x2A8E (Greater-than above similar or equal to) + - "⪏": [t: "⠐⠅⠈⠱⠨⠂"] # 0x2A8F (Less-than above similar above greater-than) + - "⪐": [t: "⠨⠂⠈⠱⠐⠅"] # 0x2A90 (Greater-than above similar above less-than) + - "⪑": [t: "⠐⠅⠨⠂⠨⠅"] # 0x2A91 (Less-than above greater-than above double-line equal) + - "⪒": [t: "⠨⠂⠐⠅⠨⠅"] # 0x2A92 (Greater-than above less-than above double-line equal) + - "⪙": [t: "⠨⠅⠐⠅"] # 0x2A99 (Double-line equal to or less-than) + - "⪚": [t: "⠨⠅⠨⠂"] # 0x2A9A (Double-line equal to or greater-than) + - "⪝": [t: "⠈⠱⠐⠅"] # 0x2A9D (Similar or less-than) + - "⪞": [t: "⠈⠱⠨⠂"] # 0x2A9E (Similar or greater-than) + - "⪟": [t: "⠈⠱⠐⠅⠨⠅"] # 0x2A9F (Similar above less-than above equals sign) + - "⪠": [t: "⠈⠱⠨⠂⠨⠅"] # 0x2AA0 (Similar above greater-than above equals sign) + - "⪮": [t: "⠈⠣⠨⠅"] # 0x2AAE (Equals sign with bumpy above) + - "⪽": [t: "⠡⠈⠸⠐⠅⠻"] # 0x2ABD (Subset w dot) + - "⪾": [t: "⠡⠈⠸⠨⠂⠻"] # 0x2ABE (Superset w dot) + - "⪿": [t: "⠐⠸⠐⠅⠩⠬⠻"] # 0x2ABF (Subset with plus sign below) + - "⫀": [t: "⠐⠸⠨⠂⠩⠬⠻"] # 0x2AC0 (Superset with plus sign below) + - "⫁": [t: "⠐⠸⠐⠅⠩⠈⠡⠻"] # 0x2AC1 (Subset with multiplication sign below) + - "⫂": [t: "⠐⠸⠨⠂⠩⠈⠡⠻"] # 0x2AC2 (Superset with multiplication sign below) + - "⫅": [t: "⠸⠐⠅⠨⠅"] # 0x2AC5 (Subset of above equals sign) + - "⫆": [t: "⠸⠨⠂⠨⠅"] # 0x2AC6 (Superset of above equals sign) + - "⫇": [t: "⠸⠐⠅⠈⠱"] # 0x2AC7 (Subset of above tilde operator) + - "⫈": [t: "⠸⠨⠂⠈⠱"] # 0x2AC8 (Superset of above tilde operator) + - "⫉": [t: "⠸⠐⠅⠈⠱⠈⠱"] # 0x2AC9 (Subset of above almost equal to) + - "⫊": [t: "⠸⠨⠂⠈⠱⠈⠱"] # 0x2ACA (Superset of above almost equal to) + - "⫋": [t: "⠸⠐⠅⠌⠨⠅"] # 0x2ACB (Subset of above not equals sign) + - "⫌": [t: "⠸⠨⠂⠌⠨⠅"] # 0x2ACC (Superset of above not equals sign) + - "⫓": [t: "⠸⠐⠅⠸⠨⠂"] # 0x2AD3 (Subset above superset) + - "⫔": [t: "⠸⠨⠂⠸⠐⠅"] # 0x2AD4 (Superset above subset) + - "⫕": [t: "⠸⠐⠅⠸⠐⠅"] # 0x2AD5 (Subset above subset) + - "⫖": [t: "⠸⠨⠂⠸⠨⠂"] # 0x2AD6 (Superset above superset) + - "⫗": [t: "⠸⠨⠂⠐⠸⠐⠅"] # 0x2AD7 (Superset beside subset) + - "⫯": [t: "⠫⠩⠨⠡⠒⠒"] # 0x2AEF (Vertical line w circle above) + - "⫰": [t: "⠫⠣⠨⠡⠒⠒"] # 0x2AF0 (Vertical line w circle below) + - "⫱": [t: "⠫⠣⠨⠡⠒⠒⠳"] # 0x2AF1 (Down tack w circle below) + - "⫲": [t: "⠱⠈⠫⠇⠻"] # 0x2AF2 (Parallel w horizontal stroke) + - "⫳": [t: "⠈⠱⠈⠫⠇⠻"] # 0x2AF3 (Parallel w tilde operator) + - "⫴": [t: "⠳⠳⠳"] # 0x2AF4 (Triple vertical bar binary relation) + - "⬬": [t: "⠫⠸⠑"] # 0x2B2C (Black ellipse) + - "⬭": [t: "⠫⠑"] # 0x2B2D (White ellipse) + - "⬰": [t: "⠨⠡⠈⠫⠪⠒⠒⠻"] # 0x2B30 (Left arrow w small circle) + - "⬱": [t: "⠫⠪⠒⠒⠫⠪⠒⠒⠫⠪⠒⠒"] # 0x2B31 (Three leftwards arrows) + - "⬲": [t: "⠫⠪⠒⠒⠈⠫⠉⠸⠫⠬⠻"] # 0x2B32 (Left arrow w circled plus) + - "⮖": [t: "⠨⠡"] # 0x2B96 (Standard State Symbol) + - "⯃": [t: "⠫⠸⠦"] # 0x2BC3 (Horizontal black octagon) + + # SRE lists this as a custom transcription + - "⋊": [t: "⠈⠡⠳"] # 0x22ca (RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT) diff --git a/Rules/Braille/Nemeth/unicode.yaml b/Rules/Braille/Nemeth/unicode.yaml index 83c850fe8..5b9c973f9 100644 --- a/Rules/Braille/Nemeth/unicode.yaml +++ b/Rules/Braille/Nemeth/unicode.yaml @@ -20,32 +20,10 @@ - "7": [t: "N⠶"] # 0x37 - "8": [t: "N⠦"] # 0x38 - "9": [t: "N⠔"] # 0x39 - - "A": [t: "CL⠁"] # 0x41 - - "B": [t: "CL⠃"] # 0x42 - - "C": [t: "CL⠉"] # 0x43 - - "D": [t: "CL⠙"] # 0x44 - - "E": [t: "CL⠑"] # 0x45 - - "F": [t: "CL⠋"] # 0x46 - - "G": [t: "CL⠛"] # 0x47 - - "H": [t: "CL⠓"] # 0x48 - - "I": [t: "CL⠊"] # 0x49 - - "J": [t: "CL⠚"] # 0x4a - - "K": [t: "CL⠅"] # 0x4b - - "L": [t: "CL⠇"] # 0x4c - - "M": [t: "CL⠍"] # 0x4d - - "N": [t: "CL⠝"] # 0x4e - - "O": [t: "CL⠕"] # 0x4f - - "P": [t: "CL⠏"] # 0x50 - - "Q": [t: "CL⠟"] # 0x51 - - "R": [t: "CL⠗"] # 0x52 - - "S": [t: "CL⠎"] # 0x53 - - "T": [t: "CL⠞"] # 0x54 - - "U": [t: "CL⠥"] # 0x55 - - "V": [t: "CL⠧"] # 0x56 - - "W": [t: "CL⠺"] # 0x57 - - "X": [t: "CL⠭"] # 0x58 - - "Y": [t: "CL⠽"] # 0x59 - - "Z": [t: "CL⠵"] # 0x5a + # Latin capitals: C + cells from lowercase a-z via spell/translate. + - "A-Z": # 0x41 - 0x5a + - tc: "C" + - spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" - "a": [t: "L⠁"] # 0x61 - "b": [t: "L⠃"] # 0x62 - "c": [t: "L⠉"] # 0x63 diff --git a/Rules/Braille/Russian/unicode-full.yaml b/Rules/Braille/Russian/unicode-full.yaml index 813669ecc..b562dc302 100644 --- a/Rules/Braille/Russian/unicode-full.yaml +++ b/Rules/Braille/Russian/unicode-full.yaml @@ -57,7 +57,7 @@ - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 - - tc: "B" + - tc: "BC" - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" @@ -123,23 +123,23 @@ - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" - "𝐴-𝑍": # 0x1d434 - 0x1d44d - - tc: "IC" + - tc: "C" - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'abcdefghijklmnopqrstuvwxyz')" - "𝑎-𝑧": # 0x1d44e - 0x1d467 - - tc: "I" + - tc: "" - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" - "𝑨-𝒁": # 0x1d468 - 0x1d481 - - tc: "BIC" + - tc: "BC" - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'abcdefghijklmnopqrstuvwxyz')" - "𝒂-𝒛": # 0x1d482 - 0x1d49b - - tc: "BI" + - tc: "B" - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 - - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'abcdefghijklmnopqrstuvwxyz')" - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" @@ -148,7 +148,7 @@ - test: if: "not($IgnoreBold)" then: [tc: "B"] - - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'abcdefghijklmnopqrstuvwxyz')" - "𝗮-𝘇": # 0x1d5ee - 0x1d607 - test: @@ -157,27 +157,27 @@ - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" - "𝘈-𝘡": # 0x1d608 - 0x1d621 - - tc: "IC" - - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - tc: "C" + - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'abcdefghijklmnopqrstuvwxyz')" - "𝘢-𝘻": # 0x1d622 - 0x1d63b - - tc: "I" + - tc: "" - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" - "𝘼-𝙕": # 0x1d63c - 0x1d655 - # - tc: "bold italic" + # - tc: "bold italicC" - test: if: "$IgnoreBold" - then: [tc: I] - else: [tc: "BI"] - - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + then: [tc: "C"] + else: [tc: "B"] + - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'abcdefghijklmnopqrstuvwxyz')" - "𝙖-𝙯": # 0x1d656 - 0x1d66f # - tc: "bold italic" - test: if: "$IgnoreBold" - then: [tc: I] - else: [tc: "BI"] + then: [tc: ""] + else: [tc: "B"] - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" - "𝙰-𝚉": # 0x1d670 - 0x1d689 @@ -194,7 +194,7 @@ - test: if: "not($IgnoreBold)" then: [tc: "B"] - - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da - test: @@ -215,7 +215,7 @@ - spell: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa - - tc: "IC" + - tc: "C" - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝛼-𝜔": # 0x1d6fc - 0x1d714 @@ -230,20 +230,20 @@ - spell: "translate('.', '𝜕𝜖𝜗𝜘𝜙𝜚𝜛', '∂εθκφρπ')" - "𝜜-𝜴": # 0x1d71c - 0x1d734 - # - tc: "bold italic" - - tc: 'BIC⠁' + # - tc: "bold italicC" + - tc: 'BC⠁' - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝜶-𝝎": # 0x1d736 - 0x1d74e - - tc: "BI" + - tc: "B" - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": # 0x1d74f - 0x1d755 - - tc: "BI" + - tc: "B" - spell: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εκθφρπ')" - "𝜵": # 0x1d735 - - tc: "BI" + - tc: "B" - spell: "translate('.', '𝜵', '∇')" - "𝝖-𝝮": # 0x1d756 - 0x1d76e @@ -263,19 +263,19 @@ - spell: "translate('.', '𝜵', '∇')" - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 - # - tc: "bold italic" + # - tc: "bold italicC" - test: if: "$IgnoreBold" - then: [tc: I] - else: [tc: "BI"] - - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + then: [tc: "C"] + else: [tc: "B"] + - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝞪-𝟂": # 0x1d7aa - 0x1d7c2 # - tc: "bold italic" - test: if: "$IgnoreBold" - then: [tc: I] - else: [tc: "BI"] + then: [tc: ""] + else: [tc: "B"] - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": # 0x1d7c3 - 0x1d7c9 diff --git a/Rules/Braille/Swedish/unicode-full.yaml b/Rules/Braille/Swedish/unicode-full.yaml index 4faab15c3..51400827b 100644 --- a/Rules/Braille/Swedish/unicode-full.yaml +++ b/Rules/Braille/Swedish/unicode-full.yaml @@ -1,50 +1,50 @@ --- - 𝐀-𝐙: # 0x1d400 - 0x1d419 - - tc: B - - spell: translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - tc: BC + - spell: translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'abcdefghijklmnopqrstuvwxyz') - 𝐚-𝐳: # 0x1d41a - 0x1d433 - tc: B - spell: translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz') - 𝐴-𝑍: # 0x1d434 - 0x1d44d - - tc: I - - spell: translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - tc: "C" + - spell: translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'abcdefghijklmnopqrstuvwxyz') - 𝑎-𝑧: # 0x1d44e - 0x1d467 - - tc: I + - tc: "" - spell: translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz') - 𝑨-𝒁: # 0x1d468 - 0x1d481 - - tc: BI - - spell: translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - tc: BC + - spell: translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'abcdefghijklmnopqrstuvwxyz') - 𝒂-𝒛: # 0x1d482 - 0x1d49b - - tc: BI + - tc: B - spell: translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz') - 𝒜-𝒵: # 0x1d49c - 0x1d4b5 - - tc: Ts - - spell: translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - tc: TsC + - spell: translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'abcdefghijklmnopqrstuvwxyz') - 𝒶-𝓏: # 0x1d4b6 - 0x1d4cf - tc: Ts - spell: translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz') - 𝓐-𝓩: # 0x1d4d0 - 0x1d4e9 - - tc: BTs - - spell: translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - tc: BTsC + - spell: translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'abcdefghijklmnopqrstuvwxyz') - 𝓪-𝔃: # 0x1d4ea - 0x1d503 - tc: BTs - spell: translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz') - 𝔄-𝔝: # 0x1d504 - 0x1d51d - tc: DC - - spell: translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜𝔝', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - spell: translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜𝔝', 'abcdefghijklmnopqrstuvwxyz') - 𝔞-𝔷: # 0x1d51e - 0x1d537 - tc: D - spell: translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz') - 𝔸-𝔹: # 0x1d538 - 0x1d539 - - tc: "𝔹" - - spell: translate('.', '𝔸𝔹', 'AB') + - tc: "𝔹C" + - spell: translate('.', '𝔸𝔹', 'ab') - 𝔻-𝔾: # 0x1d53b - 0x1d53e - - tc: "𝔹" - - spell: translate('.', '𝔻𝔼𝔽𝔾', 'DEFG') + - tc: "𝔹C" + - spell: translate('.', '𝔻𝔼𝔽𝔾', 'defg') - 𝕀-𝕄: # 0x1d540 - 0x1d544 - - tc: "𝔹" - - spell: translate('.', '𝕀𝕁𝕂𝕃𝕄', 'IJKLM') + - tc: "𝔹C" + - spell: translate('.', '𝕀𝕁𝕂𝕃𝕄', 'ijklm') - "ℂ": [t: "𝔹CL⠉"] # 0x2102 - "ℍ": [t: "𝔹CL⠓"] # 0x210d @@ -52,77 +52,77 @@ - "𝕆": [t: "𝔹CL⠕"] # 0x1d546 - 𝕊-𝕐: # 0x1d54a - 0x1d550 - - tc: "𝔹" - - spell: translate('.', '𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'STUVWXY') + - tc: "𝔹C" + - spell: translate('.', '𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'stuvwxy') - 𝕒-𝕫: # 0x1d552 - 0x1d56b - tc: '' - spell: translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz') - 𝕬-𝖅: # 0x1d56c - 0x1d585 - tc: BDC - - spell: translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - spell: translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'abcdefghijklmnopqrstuvwxyz') - 𝖆-𝖟: # 0x1d586 - 0x1d59f - tc: BD - spell: translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz') - 𝖠-𝖹: # 0x1d5a0 - 0x1d5b9 - tc: SC - - spell: translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - spell: translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'abcdefghijklmnopqrstuvwxyz') - 𝖺-𝗓: # 0x1d5ba - 0x1d5d3 - tc: S - spell: translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz') - 𝗔-𝗭: # 0x1d5d4 - 0x1d5ed - tc: BSC - - spell: translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - spell: translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'abcdefghijklmnopqrstuvwxyz') - 𝗮-𝘇: # 0x1d5ee - 0x1d607 - tc: BS - spell: translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz') - 𝘈-𝘡: # 0x1d608 - 0x1d621 - - tc: ISC - - spell: translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - tc: SC + - spell: translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'abcdefghijklmnopqrstuvwxyz') - 𝘢-𝘻: # 0x1d622 - 0x1d63b - - tc: IS + - tc: S - spell: translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz') - 𝘼-𝙕: # 0x1d63c - 0x1d655 - - tc: BISC - - spell: translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - tc: BSC + - spell: translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'abcdefghijklmnopqrstuvwxyz') - 𝙖-𝙯: # 0x1d656 - 0x1d66f - - tc: BIS + - tc: BS - spell: translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz') - 𝙰-𝚉: # 0x1d670 - 0x1d689 - tc: C - - spell: translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - spell: translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'abcdefghijklmnopqrstuvwxyz') - 𝚊-𝚥: # 0x1d68a - 0x1d6a5 - tc: '' - spell: translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣𝚤𝚥', 'abcdefghijklmnopqrstuvwxyz') - 𝚨-𝚿: # 0x1d6a8 - 0x1d6bf - tc: BCG - - spell: translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ') + - spell: translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝛂-𝛙: # 0x1d6c2 - 0x1d6d9 - tc: BG - spell: translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝛢-𝛹: # 0x1d6e2 - 0x1d6f9 - - tc: ICG - - spell: translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ') + - tc: CG + - spell: translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝛼-𝜓: # 0x1d6fc - 0x1d713 - - tc: IG + - tc: G - spell: translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝜜-𝜳: # 0x1d71c - 0x1d733 - - tc: BICG - - spell: translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ') + - tc: BCG + - spell: translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝜶-𝝍: # 0x1d736 - 0x1d74d - - tc: BIG + - tc: BG - spell: translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝝖-𝝭: # 0x1d756 - 0x1d76d - tc: BSCG - - spell: translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ') + - spell: translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝝰-𝞇: # 0x1d770 - 0x1d787 - tc: BSG - spell: translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝞐-𝞧: # 0x1d790 - 0x1d7a7 - - tc: BISCG - - spell: translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ') + - tc: BSCG + - spell: translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝞪-𝟁: # 0x1d7aa - 0x1d7c1 - - tc: BISG + - tc: BSG - spell: translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝟎-𝟗: # 0x1d7ce - 0x1d7d7 - tc: BN diff --git a/Rules/Braille/Swedish/unicode.yaml b/Rules/Braille/Swedish/unicode.yaml index 2e69ae106..6d4e84c4e 100644 --- a/Rules/Braille/Swedish/unicode.yaml +++ b/Rules/Braille/Swedish/unicode.yaml @@ -427,32 +427,10 @@ - "Ỹ": [t: "CL⠤𝑐L⠽"] - "Ỵ": [t: "CL⠠𝑐L⠽"] - - "A": [t: "CL⠁"] # 0x41 - - "B": [t: "CL⠃"] # 0x42 - - "C": [t: "CL⠉"] # 0x43 - - "D": [t: "CL⠙"] # 0x44 - - "E": [t: "CL⠑"] # 0x45 - - "F": [t: "CL⠋"] # 0x46 - - "G": [t: "CL⠛"] # 0x47 - - "H": [t: "CL⠓"] # 0x48 - - "I": [t: "CL⠊"] # 0x49 - - "J": [t: "CL⠚"] # 0x4a - - "K": [t: "CL⠅"] # 0x4b - - "L": [t: "CL⠇"] # 0x4c - - "M": [t: "CL⠍"] # 0x4d - - "N": [t: "CL⠝"] # 0x4e - - "O": [t: "CL⠕"] # 0x4f - - "P": [t: "CL⠏"] # 0x50 - - "Q": [t: "CL⠟"] # 0x51 - - "R": [t: "CL⠗"] # 0x52 - - "S": [t: "CL⠎"] # 0x53 - - "T": [t: "CL⠞"] # 0x54 - - "U": [t: "CL⠥"] # 0x55 - - "V": [t: "CL⠧"] # 0x56 - - "W": [t: "CL⠺"] # 0x57 - - "X": [t: "CL⠭"] # 0x58 - - "Y": [t: "CL⠽"] # 0x59 - - "Z": [t: "CL⠵"] # 0x5a + # Latin capitals: C + cells from lowercase a-z via spell/translate. + - "A-Z": # 0x41 - 0x5a + - tc: "C" + - spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" - "α": [t: "GL⠁"] # 0x3b1 - "β": [t: "GL⠃"] # 0x3b2 diff --git a/Rules/Braille/UEB/unicode-full.yaml b/Rules/Braille/UEB/unicode-full.yaml index 9114b4de6..b57660aeb 100644 --- a/Rules/Braille/UEB/unicode-full.yaml +++ b/Rules/Braille/UEB/unicode-full.yaml @@ -1,17 +1,6 @@ --- - - " ": [t: "W"] # 0x2000 - - " ": [t: "W"] # 0x2001 - - " ": [t: "W"] # 0x2002 - - " ": [t: "W"] # 0x2003 - - " ": [t: "W"] # 0x2004 - - " ": [t: "W"] # 0x2005 - - " ": [t: "W"] # 0x2006 - - " ": [t: "W"] # 0x2007 - - " ": [t: "W"] # 0x2008 - - " ": [t: "W"] # 0x2009 - - " ": [t: "W"] # 0x200a - - "​": [t: "W"] # 0x200b + - " -​": [t: "W"] # 0x2000 - 0x200b (various spaces / ZWSP) - "
": [t: "W"] # 0x2028 - "
": [t: "W"] # 0x2029 - " ": [t: "W"] # 0x202f @@ -199,12 +188,12 @@ - "ℰ": [tc: "TCL⠑"] # 0x2130 (Script Capital E) - "ℱ": [tc: "TCL⠋"] # 0x2131 (Script Capital F) - "ℳ": [tc: "TCL⠍"] # 0x2133 (Script Capital M) - - "ℴ": [tc: "TL⠕"] # 0x21334 (Script Small O) + - "ℴ": [tc: "TL⠕"] # 0x2134 (Script Small O) - "ℌ": [tc: "DCL⠓"] # 0x210C (Fraktur Capital H) - "ℑ": [tc: "DCL⠊"] # 0x2111 (Fraktur Capital I) - "ℜ": [tc: "DCL⠗"] # 0x211C (Fraktur Capital R) - "ℨ": [tc: "DCL⠵"] # 0x2128 (Fraktur Capital Z) - - "ℭ": [tc: "DCL⠉"] # 0x22DC (Fraktur Capital C) + - "ℭ": [tc: "DCL⠉"] # 0x212D (Fraktur Capital C) - "ℂ": [tc: "𝔹CL⠉"] # 0x2102 - "ℍ": [tc: "𝔹CL⠓"] # 0x210d @@ -228,21 +217,21 @@ - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'abcdefghijklmnopqrstuvwxyz')" - "𝖆-𝖟": # 0x1d586 - 0x1d59f - - tc: "D" + - tc: "BD" - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" # double struck (blackboard bold) chars in math alphabetic block and also MathType private use area # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display - - "𝔸-𝕐": # 0x1d504 - 0x1d51d ('z' version is reserved) - - tc: "DC" + - "𝔸-𝕐": # 0x1D538 - 0x1D551 ('z' version is reserved) + - tc: "𝔹C" - spell: "translate('.', '𝔸𝔹𝔺𝔻𝔼𝔽𝔾𝔿𝕀𝕁𝕂𝕃𝕄𝕅𝕆𝕇𝕈𝕉𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'abcdefghijklmnopqrstuvwxyz')" - "𝕒-𝕫": # 0x1d552 - 0x1d56b - - tc: "D" + - tc: "𝔹" - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 - - tc: "D" + - tc: "𝔹" - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" # script chars in math alphabetic block and also MathType private use area @@ -256,7 +245,7 @@ # bold script chars in math alphabetic block - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 - - tc: "BTs" + - tc: "BTsC" - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'abcdefghijklmnopqrstuvwxyz')" - "𝓪-𝔃": # 0x1d4ea - 0x1d503 @@ -264,7 +253,7 @@ - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" - "𝐀-𝐙": # 0x1d400 - 0x1d419 - - tc: "B" + - tc: "BC" - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'abcdefghijklmnopqrstuvwxyz')" - "𝐚-𝐳": # 0x1d41a - 0x1d433 @@ -281,14 +270,16 @@ - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" - "𝑨-𝒁": # 0x1d468 - 0x1d481 - - tc: "BIC" + - tc: "BC" - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'abcdefghijklmnopqrstuvwxyz')" - "𝒂-𝒛": # 0x1d482 - 0x1d49b + - tc: "B" - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 - - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - tc: "C" + - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'abcdefghijklmnopqrstuvwxyz')" - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" @@ -296,8 +287,9 @@ - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed - test: if: "not($IgnoreBold)" - then: [tc: "B"] - - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + then: [tc: "BC"] + else: [tc: "C"] + - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'abcdefghijklmnopqrstuvwxyz')" - "𝗮-𝘇": # 0x1d5ee - 0x1d607 - test: @@ -306,27 +298,27 @@ - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" - "𝘈-𝘡": # 0x1d608 - 0x1d621 - # - tc: "italic" - - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + # don't include italics + - tc: "C" + - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'abcdefghijklmnopqrstuvwxyz')" - "𝘢-𝘻": # 0x1d622 - 0x1d63b - # - tc: "italic" + # don't include italics - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" - "𝘼-𝙕": # 0x1d63c - 0x1d655 - # - tc: "bold italic" + # bold italic — UEB: no italic typeform; bold + capital only - test: - if: "$IgnoreBold" - then: [tc: I] - else: [tc: "BI"] - - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + if: "not($IgnoreBold)" + then: [tc: "BC"] + else: [tc: "C"] + - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'abcdefghijklmnopqrstuvwxyz')" - "𝙖-𝙯": # 0x1d656 - 0x1d66f - # - tc: "bold italic" + # bold italic — UEB: no italic typeform; bold only - test: - if: "$IgnoreBold" - then: [tc: I] - else: [tc: "BI"] + if: "not($IgnoreBold)" + then: [tc: "B"] - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" - "𝙰-𝚉": # 0x1d670 - 0x1d689 @@ -342,8 +334,9 @@ - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 - test: if: "not($IgnoreBold)" - then: [tc: "B"] - - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + then: [tc: "BC"] + else: [tc: "C"] + - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da - test: @@ -355,7 +348,7 @@ - test: if: "not($IgnoreBold)" then: [tc: "B"] - - spell: "translate('.', '𝜵', '∇')" + - spell: "translate('.', '𝛁', '∇')" - "𝛛𝛜𝛝𝛞𝛟𝛠𝛡": # 0x1D6DB - 0x1D6E1 - test: @@ -364,7 +357,7 @@ - spell: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa - - tc: "IC" + - tc: "C" - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝛼-𝜔": # 0x1d6fc - 0x1d714 @@ -372,7 +365,7 @@ - "𝛻": # 0x1d6fb - - spell: "translate('.', '𝜵', '∇')" + - spell: "translate('.', '𝛻', '∇')" - "𝜕𝜖𝜗𝜘𝜙𝜚𝜛": # 0x1d715 - 0x1d71b # - tc: "italic" @@ -380,19 +373,19 @@ - "𝜜-𝜴": # 0x1d71c - 0x1d734 # - tc: "bold italic" - - tc: 'BIC⠁' + - tc: "BC" - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝜶-𝝎": # 0x1d736 - 0x1d74e - - tc: "BI" + - tc: "B" - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": # 0x1d74f - 0x1d755 - - tc: "BI" + - tc: "B" - spell: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εκθφρπ')" - "𝜵": # 0x1d735 - - tc: "BI" + - tc: "B" - spell: "translate('.', '𝜵', '∇')" - "𝝖-𝝮": # 0x1d756 - 0x1d76e @@ -409,22 +402,21 @@ - "𝝯": # 0x1d76f - tc: "B" - - spell: "translate('.', '𝜵', '∇')" + - spell: "translate('.', '𝝯', '∇')" - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 - # - tc: "bold italic" + # bold italic — UEB: no italic typeform; bold + capital only - test: - if: "$IgnoreBold" - then: [tc: I] - else: [tc: "BI"] - - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + if: "not($IgnoreBold)" + then: [tc: "BC"] + else: [tc: "C"] + - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝞪-𝟂": # 0x1d7aa - 0x1d7c2 - # - tc: "bold italic" + # bold italic — UEB: no italic typeform; bold only - test: - if: "$IgnoreBold" - then: [tc: I] - else: [tc: "BI"] + if: "not($IgnoreBold)" + then: [tc: "B"] - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": # 0x1d7c3 - 0x1d7c9 diff --git a/Rules/Braille/UEB/unicode.yaml b/Rules/Braille/UEB/unicode.yaml index e1b513bc8..ccee08652 100644 --- a/Rules/Braille/UEB/unicode.yaml +++ b/Rules/Braille/UEB/unicode.yaml @@ -367,84 +367,17 @@ - "y": [t: "L⠽"] # 0x79 - "z": [t: "L⠵"] # 0x7a - - "A": [t: "CL⠁"] # 0x41 - - "B": # 0x42 + # Latin capitals: chem-element letters use 𝐶 (no word indicator); others use C. + # Cells come from lowercase a-z via spell/translate. + - "BCHIKNOPSUVWY": # chemistry-capable capitals - test: if: "@data-chem-element" - then: [t: "𝐶L⠃"] - else: [t: "CL⠃"] - - "C": # 0x43 - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠉"] - else: [t: "CL⠉"] - - "D": [t: "CL⠙"] # 0x44 - - "E": [t: "CL⠑"] # 0x45 - - "F": [t: "CL⠋"] # 0x46 - - "G": [t: "CL⠛"] # 0x47 - - "H": # 0x48 - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠓"] - else: [t: "CL⠓"] - - "I": # 0x49 - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠊"] - else: [t: "CL⠊"] - - "J": [t: "CL⠚"] # 0x4a - - "K": # 0x4b - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠅"] - else: [t: "CL⠅"] - - "L": [t: "CL⠇"] # 0x4c - - "M": [t: "CL⠍"] # 0x4d - - "N": # 0x4e - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠝"] - else: [t: "CL⠝"] - - "O": # 0x4f - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠕"] - else: [t: "CL⠕"] - - "P": # 0x50 - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠏"] - else: [t: "CL⠏"] - - "Q": [t: "CL⠟"] # 0x51 - - "R": [t: "CL⠗"] # 0x52 - - "S": # 0x53 - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠎"] - else: [t: "CL⠎"] - - "T": [t: "CL⠞"] # 0x54 - - "U": # 0x55 - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠥"] - else: [t: "CL⠥"] - - "V": # 0x56 - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠧"] - else: [t: "CL⠧"] - - "W": # 0x57 - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠺"] - else: [t: "CL⠺"] - - "X": [t: "CL⠭"] # 0x58 - - "Y": # 0x59 - - test: - if: "@data-chem-element" - then: [t: "𝐶L⠽"] - else: [t: "CL⠽"] - - "Z": [t: "CL⠵"] # 0x5a + then: [tc: "𝐶"] + else: [tc: "C"] + - spell: "translate('.', 'BCHIKNOPSUVWY', 'bchiknopsuvwy')" + - "ADEFGJLMQRTXZ": # remaining capitals + - tc: "C" + - spell: "translate('.', 'ADEFGJLMQRTXZ', 'adefgjlmqrtxz')" - "α": [t: "GL⠁"] # 0x3b1 - "β": [t: "GL⠃"] # 0x3b2 @@ -486,7 +419,7 @@ - "Δ": [t: "CGL⠙"] # 0x394 - "Ε": [t: "CGL⠑"] # 0x395 - "Ζ": [t: "CGL⠵"] # 0x396 - - "Η": [t: "CGL⠱ "] # 0x397 + - "Η": [t: "CGL⠱"] # 0x397 - "Θ": [t: "CGL⠹"] # 0x398 - "Ι": [t: "CGL⠊"] # 0x399 - "Κ": [t: "CGL⠅"] # 0x39a diff --git a/Rules/Braille/Vietnam/unicode-full.yaml b/Rules/Braille/Vietnam/unicode-full.yaml index eba63e7f3..43008ef7b 100644 --- a/Rules/Braille/Vietnam/unicode-full.yaml +++ b/Rules/Braille/Vietnam/unicode-full.yaml @@ -24,8 +24,8 @@ - "↉": [t: "#N⠚N⠌N⠑"] # 0x2189 (Vulgar Fraction Zero Thirds) - 𝐀-𝐙: # 0x1d400 - 0x1d419 - - tc: "B" - - spell: translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - tc: "BC" + - spell: translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'abcdefghijklmnopqrstuvwxyz') - 𝐚-𝐳: # 0x1d41a - 0x1d433 - tc: "B" @@ -33,38 +33,37 @@ - 𝐴-𝑍: # 0x1d434 - 0x1d44d - tc: "C" - - spell: translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - spell: translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'abcdefghijklmnopqrstuvwxyz') - 𝑎-𝑧: # 0x1d44e - 0x1d467 - - tc: "L" - spell: translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz') - 𝒂-𝒛: # 0x1d482 - 0x1d49b - - tc: "BI" + - tc: "B" - spell: translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz') - 𝑨-𝒁: # 0x1d468 - 0x1d481 - - tc: "BI" - - spell: translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - tc: "BC" + - spell: translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'abcdefghijklmnopqrstuvwxyz') - 𝒶-𝓏: # 0x1d4b6 - 0x1d4cf - tc: "Ts" - spell: translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz') - 𝒜-𝒵: # 0x1d49c - 0x1d4b5 - - tc: "Ts" - - spell: translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - tc: "TsC" + - spell: translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'abcdefghijklmnopqrstuvwxyz') - 𝓐-𝓩: # 0x1d4d0 - 0x1d4e9 - - tc: "BTs" - - spell: translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - tc: "BTsC" + - spell: translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'abcdefghijklmnopqrstuvwxyz') - 𝓪-𝔃: # 0x1d4ea - 0x1d503 - tc: "BTs" - spell: translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz') - 𝔄-𝔝: # 0x1d504 - 0x1d51d - - tc: "D" - - spell: translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜𝔝', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - tc: "DC" + - spell: translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜𝔝', 'abcdefghijklmnopqrstuvwxyz') - 𝔞-𝔷: # 0x1d51e - 0x1d537 - tc: "D" - spell: translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz') @@ -82,14 +81,14 @@ - "ℴ": [t: "TL⠕"] # 0x21334 (Script Small O) - 𝔸-𝔹: # 0x1d538 - 0x1d550 - - tc: "𝔹" - - spell: translate('.', '𝔸𝔹', 'AB') + - tc: "𝔹C" + - spell: translate('.', '𝔸𝔹', 'ab') - 𝔻-𝔾: - - tc: "𝔹" - - spell: translate('.', '𝔻𝔼𝔽𝔾', 'DEFG') + - tc: "𝔹C" + - spell: translate('.', '𝔻𝔼𝔽𝔾', 'defg') - 𝕀-𝕄: - - tc: "𝔹" - - spell: translate('.', '𝕀𝕁𝕂𝕃𝕄', 'IJKLM') + - tc: "𝔹C" + - spell: translate('.', '𝕀𝕁𝕂𝕃𝕄', 'ijklm') - "ℂ": [t: "𝔹CL⠉"] # 0x2102 - "ℍ": [t: "𝔹CL⠓"] # 0x210d @@ -98,14 +97,14 @@ - 𝕊-𝕐: - t: "𝔹" - - spell: translate('.', '𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'STUVWXY') + - spell: translate('.', '𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'stuvwxy') - 𝕒-𝕫: # 0x1d552 - 0x1d56b - t: "𝔹" - spell: translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz') - 𝕬-𝖅: - t: "BD" - - spell: translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - spell: translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'abcdefghijklmnopqrstuvwxyz') - "ℌ": [t: "DCL⠓"] # 0x210C (Fraktur Capital H) - "ℑ": [t: "DCL⠊"] # 0x2111 (Fraktur Capital I) @@ -117,32 +116,32 @@ - tc: "BD" - spell: translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz') - 𝖠-𝖹: # 0x1d5a0 - 0x1d5b9 - - tc: "S" - - spell: translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - tc: "SC" + - spell: translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'abcdefghijklmnopqrstuvwxyz') - 𝖺-𝗓: # 0x1d5ba - 0x1d5d3 - tc: "S" - spell: translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz') - 𝗔-𝗭: # 0x1d5d4 - 0x1d5ed - - tc: "BS" - - spell: translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - tc: "BSC" + - spell: translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'abcdefghijklmnopqrstuvwxyz') - 𝗮-𝘇: # 0x1d5ee - 0x1d607 - tc: "BS" - spell: translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz') - 𝘈-𝘡: # 0x1d608 - 0x1d621 - t: "IS" - - spell: translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - spell: translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'abcdefghijklmnopqrstuvwxyz') - 𝘢-𝘻: # 0x1d622 - 0x1d63b - t: "IS" - spell: translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz') - 𝘼-𝙕: # 0x1d63c - 0x1d655 - t: "BILS" - - spell: translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - spell: translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'abcdefghijklmnopqrstuvwxyz') - 𝙖-𝙯: # 0x1d656 - 0x1d66f - t: "BILS" - spell: translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz') - 𝙰-𝚉: # 0x1d670 - 0x1d689 - - spell: translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + - spell: translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'abcdefghijklmnopqrstuvwxyz') - 𝚊-𝚣: # 0x1d68a - 0x1d6a3 - spell: translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz') @@ -151,40 +150,40 @@ - 𝚨-𝚿: # 0x1d6a8 - 0x1d6bf - tc: "BCG" - - spell: translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ') + - spell: translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝛂-𝛙: # 0x1d6c2 - 0x1d6d9 - tc: "BG" - spell: translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝛢-𝛹: # 0x1d6e2 - 0x1d6f9 - - tc: "ICG" - - spell: translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ') + - tc: "CG" + - spell: translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝛼-𝜓: # 0x1d6fc - 0x1d713 - - tc: "IG" + - tc: "G" - spell: translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝜜-𝜳: # 0x1d71c - 0x1d733 - - tc: "BICG" - - spell: translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ') + - tc: "BCG" + - spell: translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝜶-𝝍: # 0x1d736 - 0x1d74d - - tc: "BIG" + - tc: "BG" - spell: translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝝖-𝝭: # 0x1d756 - 0x1d76d - tc: "BSCG" - - spell: translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ') + - spell: translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝝰-𝞇: # 0x1d770 - 0x1d787 - tc: "BSG" - spell: translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝞐-𝞧: # 0x1d790 - 0x1d7a7 - - tc: "BISCG" - - spell: translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ') + - tc: "BSCG" + - spell: translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝞪-𝟁: # 0x1d7aa - 0x1d7c1 - - tc: "BISG" + - tc: "BSG" - spell: translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁', 'αβγδεζηθικλμνξοπρςστυφχψω') - 𝟎-𝟗: # 0x1d7ce - 0x1d7d7 - tc: "BN" - spell: translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789') - 𝟘-𝟡: # 0x1d7d8 - 0x1d7e1 - - tc: "𝔹N" + - tc: "𝔹NC" - spell: translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789') - 𝟢-𝟫: # 0x1d7e2 - 0x1d7eb - tc: "SN" diff --git a/Rules/Braille/Vietnam/unicode.yaml b/Rules/Braille/Vietnam/unicode.yaml index 2d9a6150a..78a9adaa6 100644 --- a/Rules/Braille/Vietnam/unicode.yaml +++ b/Rules/Braille/Vietnam/unicode.yaml @@ -511,32 +511,10 @@ - "Ỹ": [t: "CL⠤𝑐L⠽"] - "Ỵ": [t: "CL⠠𝑐L⠽"] - - "A": [t: "CL⠁"] # 0x41 - - "B": [t: "CL⠃"] # 0x42 - - "C": [t: "CL⠉"] # 0x43 - - "D": [t: "CL⠙"] # 0x44 - - "E": [t: "CL⠑"] # 0x45 - - "F": [t: "CL⠋"] # 0x46 - - "G": [t: "CL⠛"] # 0x47 - - "H": [t: "CL⠓"] # 0x48 - - "I": [t: "CL⠊"] # 0x49 - - "J": [t: "CL⠚"] # 0x4a - - "K": [t: "CL⠅"] # 0x4b - - "L": [t: "CL⠇"] # 0x4c - - "M": [t: "CL⠍"] # 0x4d - - "N": [t: "CL⠝"] # 0x4e - - "O": [t: "CL⠕"] # 0x4f - - "P": [t: "CL⠏"] # 0x50 - - "Q": [t: "CL⠟"] # 0x51 - - "R": [t: "CL⠗"] # 0x52 - - "S": [t: "CL⠎"] # 0x53 - - "T": [t: "CL⠞"] # 0x54 - - "U": [t: "CL⠥"] # 0x55 - - "V": [t: "CL⠧"] # 0x56 - - "W": [t: "CL⠺"] # 0x57 - - "X": [t: "CL⠭"] # 0x58 - - "Y": [t: "CL⠽"] # 0x59 - - "Z": [t: "CL⠵"] # 0x5a + # Latin capitals: C + cells from lowercase a-z via spell/translate. + - "A-Z": # 0x41 - 0x5a + - tc: "C" + - spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" - "α": [t: "GL⠁"] # 0x3b1 - "β": [t: "GL⠃"] # 0x3b2 diff --git a/Rules/Languages/id/unicode-full.yaml b/Rules/Languages/id/unicode-full.yaml index c1467a28e..5591060fd 100644 --- a/Rules/Languages/id/unicode-full.yaml +++ b/Rules/Languages/id/unicode-full.yaml @@ -3846,6469 +3846,584 @@ - "": [T: integral terbalik] # 0xef83 - "": [T: nol ganda di atas nol ganda] # 0xef90 - "": [T: nol dengan garis miring] # 0xef91 - - "": # 0xf000 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "𝔄": # 0x1d504 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "": # 0xf001 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "𝔅": # 0x1d505 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "": # 0xf003 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "𝔇": # 0x1d507 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "": # 0xf004 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "𝔈": # 0x1d508 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "": # 0xf005 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "𝔉": # 0x1d509 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "": # 0xf006 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "𝔊": # 0x1d50a - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "": # 0xf009 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "𝔍": # 0x1d50d - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "": # 0xf00a - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "𝔎": # 0x1d50e - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "": # 0xf00b - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "𝔏": # 0x1d50f - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "": # 0xf00c - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "𝔐": # 0x1d510 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "": # 0xf00d - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "𝔑": # 0x1d511 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "": # 0xf00e - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "𝔒": # 0x1d512 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "": # 0xf00f - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "𝔓": # 0x1d513 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "": # 0xf010 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "𝔔": # 0x1d514 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "": # 0xf012 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "𝔖": # 0x1d516 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "": # 0xf013 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "𝔗": # 0x1d517 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "": # 0xf014 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "𝔘": # 0x1d518 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "": # 0xf015 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "𝔙": # 0x1d519 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "": # 0xf016 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "𝔚": # 0x1d51a - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "": # 0xf017 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "𝔛": # 0x1d51b - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "": # 0xf018 - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "𝔜": # 0x1d51c - - T: fraktur - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "": [T: fraktur a] # 0xf01a - - "𝔞": [T: fraktur a] # 0x1d51e - - "": [T: fraktur b] # 0xf01b - - "𝔟": [T: fraktur b] # 0x1d51f - - "": [T: fraktur c] # 0xf01c - - "𝔠": [T: fraktur c] # 0x1d520 - - "": [T: fraktur d] # 0xf01d - - "𝔡": [T: fraktur d] # 0x1d521 - - "": [T: fraktur e] # 0xf01e - - "𝔢": [T: fraktur e] # 0x1d522 - - "": [T: fraktur f] # 0xf01f - - "𝔣": [T: fraktur f] # 0x1d523 - - "": [T: fraktur g] # 0xf020 - - "𝔤": [T: fraktur g] # 0x1d524 - - "": [T: fraktur h] # 0xf021 - - "𝔥": [T: fraktur h] # 0x1d525 - - "": [T: fraktur i] # 0xf022 - - "𝔦": [T: fraktur i] # 0x1d526 - - "": [T: fraktur j] # 0xf023 - - "𝔧": [T: fraktur j] # 0x1d527 - - "": [T: fraktur k] # 0xf024 - - "𝔨": [T: fraktur k] # 0x1d528 - - "": [T: fraktur l] # 0xf025 - - "𝔩": [T: fraktur l] # 0x1d529 - - "": [T: fraktur m] # 0xf026 - - "𝔪": [T: fraktur m] # 0x1d52a - - "": [T: fraktur n] # 0xf027 - - "𝔫": [T: fraktur n] # 0x1d52b - - "": [T: fraktur o] # 0xf028 - - "𝔬": [T: fraktur o] # 0x1d52c - - "": [T: fraktur p] # 0xf029 - - "𝔭": [T: fraktur p] # 0x1d52d - - "": [T: fraktur q] # 0xf02a - - "𝔮": [T: fraktur q] # 0x1d52e - - "": [T: fraktur r] # 0xf02b - - "𝔯": [T: fraktur r] # 0x1d52f - - "": [T: fraktur s] # 0xf02c - - "𝔰": [T: fraktur s] # 0x1d530 - - "": [T: fraktur t] # 0xf02d - - "𝔱": [T: fraktur t] # 0x1d531 - - "": [T: fraktur u] # 0xf02e - - "𝔲": [T: fraktur u] # 0x1d532 - - "": [T: fraktur v] # 0xf02f - - "𝔳": [T: fraktur v] # 0x1d533 - - "": [T: fraktur w] # 0xf030 - - "𝔴": [T: fraktur w] # 0x1d534 - - "": [T: fraktur x] # 0xf031 - - "𝔵": [T: fraktur x] # 0x1d535 - - "": [T: fraktur y] # 0xf032 - - "𝔶": [T: fraktur y] # 0x1d536 - - "": [T: fraktur z] # 0xf033 - - "𝔷": [T: fraktur z] # 0x1d537 - - "": # 0xf040 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "𝕬": # 0x1d56c - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "": # 0xf041 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "𝕭": # 0x1d56d - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "": # 0xf042 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "𝕮": # 0x1d56e - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "": # 0xf043 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "𝕯": # 0x1d56f - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "": # 0xf044 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "𝕰": # 0x1d570 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "": # 0xf045 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "𝕱": # 0x1d571 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "": # 0xf046 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "𝕲": # 0x1d572 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "": # 0xf047 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "𝕳": # 0x1d573 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "": # 0xf048 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "𝕴": # 0x1d574 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "": # 0xf049 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "𝕵": # 0x1d575 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "": # 0xf04a - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "𝕶": # 0x1d576 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "": # 0xf04b - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "𝕷": # 0x1d577 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "": # 0xf04c - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "𝕸": # 0x1d578 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "": # 0xf04d - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "𝕹": # 0x1d579 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "": # 0xf04e - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "𝕺": # 0x1d57a - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "": # 0xf04f - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "𝕻": # 0x1d57b - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "": # 0xf050 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "𝕼": # 0x1d57c - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "": # 0xf051 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "𝕽": # 0x1d57d - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "": # 0xf052 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "𝕾": # 0x1d57e - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "": # 0xf053 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "𝕿": # 0x1d57f - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "": # 0xf054 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "𝖀": # 0x1d580 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "": # 0xf055 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "𝖁": # 0x1d581 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "": # 0xf056 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "𝖂": # 0x1d582 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "": # 0xf057 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "𝖃": # 0x1d583 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "": # 0xf058 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "𝖄": # 0x1d584 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "": # 0xf059 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "𝖅": # 0x1d585 - - T: fraktur bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "": [T: fraktur bold a] # 0xf05a - - "𝖆": [T: fraktur bold a] # 0x1d586 - - "": [T: fraktur bold b] # 0xf05b - - "𝖇": [T: fraktur bold b] # 0x1d587 - - "": [T: fraktur bold c] # 0xf05c - - "𝖈": [T: fraktur bold c] # 0x1d588 - - "": [T: fraktur bold d] # 0xf05d - - "𝖉": [T: fraktur bold d] # 0x1d589 - - "": [T: fraktur bold e] # 0xf05e - - "𝖊": [T: fraktur bold e] # 0x1d58a - - "": [T: fraktur bold f] # 0xf05f - - "𝖋": [T: fraktur bold f] # 0x1d58b - - "": [T: fraktur bold g] # 0xf060 - - "𝖌": [T: fraktur bold g] # 0x1d58c - - "": [T: fraktur bold h] # 0xf061 - - "𝖍": [T: fraktur bold h] # 0x1d58d - - "": [T: fraktur bold i] # 0xf062 - - "𝖎": [T: fraktur bold i] # 0x1d58e - - "": [T: fraktur bold j] # 0xf063 - - "𝖏": [T: fraktur bold j] # 0x1d58f - - "": [T: fraktur bold k] # 0xf064 - - "𝖐": [T: fraktur bold k] # 0x1d590 - - "": [T: fraktur bold l] # 0xf065 - - "𝖑": [T: fraktur bold l] # 0x1d591 - - "": [T: fraktur bold m] # 0xf066 - - "𝖒": [T: fraktur bold m] # 0x1d592 - - "": [T: fraktur bold n] # 0xf067 - - "𝖓": [T: fraktur bold n] # 0x1d593 - - "": [T: fraktur bold o] # 0xf068 - - "𝖔": [T: fraktur bold o] # 0x1d594 - - "": [T: fraktur bold p] # 0xf069 - - "𝖕": [T: fraktur bold p] # 0x1d595 - - "": [T: fraktur bold q] # 0xf06a - - "𝖖": [T: fraktur bold q] # 0x1d596 - - "": [T: fraktur bold r] # 0xf06b - - "𝖗": [T: fraktur bold r] # 0x1d597 - - "": [T: fraktur bold s] # 0xf06c - - "𝖘": [T: fraktur bold s] # 0x1d598 - - "": [T: fraktur bold t] # 0xf06d - - "𝖙": [T: fraktur bold t] # 0x1d599 - - "": [T: fraktur bold u] # 0xf06e - - "𝖚": [T: fraktur bold u] # 0x1d59a - - "": [T: fraktur bold v] # 0xf06f - - "𝖛": [T: fraktur bold v] # 0x1d59b - - "": [T: fraktur bold w] # 0xf070 - - "𝖜": [T: fraktur bold w] # 0x1d59c - - "": [T: fraktur bold x] # 0xf071 - - "𝖝": [T: fraktur bold x] # 0x1d59d - - "": [T: fraktur bold y] # 0xf072 - - "𝖞": [T: fraktur bold y] # 0x1d59e - - "": [T: fraktur bold z] # 0xf073 - - "𝖟": [T: fraktur bold z] # 0x1d59f - - "": # 0xf080 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "": # 0xf081 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "𝔹": # 0x1d539 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "": # 0xf083 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "𝔻": # 0x1d53b - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "": # 0xf084 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "𝔼": # 0x1d53c - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "": # 0xf085 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "𝔽": # 0x1d53d - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "": # 0xf086 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "𝔾": # 0x1d53e - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "": # 0xf088 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "𝕀": # 0x1d540 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "": # 0xf089 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "𝕁": # 0x1d541 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "": # 0xf08a - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "𝕂": # 0x1d542 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "": # 0xf08b - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "𝕃": # 0x1d543 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "": # 0xf08c - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "𝕄": # 0x1d544 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "": # 0xf08e - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "𝕆": # 0x1d546 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "": # 0xf092 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "𝕊": # 0x1d54a - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "": # 0xf093 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "𝕋": # 0x1d54b - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "": # 0xf094 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "𝕌": # 0x1d54c - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "": # 0xf095 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "𝕍": # 0x1d54d - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "": # 0xf096 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "𝕎": # 0x1d54e - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "": # 0xf097 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "𝕏": # 0x1d54f - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "": # 0xf098 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "𝕐": # 0x1d550 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "": [T: struck ganda a] # 0xf09a - - "𝕒": [T: struck ganda a] # 0x1d552 - - "": [T: struck ganda b] # 0xf09b - - "𝕓": [T: struck ganda b] # 0x1d553 - - "": [T: struck ganda c] # 0xf09c - - "𝕔": [T: struck ganda c] # 0x1d554 - - "": [T: struck ganda d] # 0xf09d - - "𝕕": [T: struck ganda d] # 0x1d555 - - "": [T: struck ganda e] # 0xf09e - - "𝕖": [T: struck ganda e] # 0x1d556 - - "": [T: struck ganda f] # 0xf09f - - "𝕗": [T: struck ganda f] # 0x1d557 - - "": [T: struck ganda g] # 0xf0a0 - - "𝕘": [T: struck ganda g] # 0x1d558 - - "": [T: struck ganda h] # 0xf0a1 - - "𝕙": [T: struck ganda h] # 0x1d559 - - "": [T: struck ganda i] # 0xf0a2 - - "𝕚": [T: struck ganda i] # 0x1d55a - - "": [T: struck ganda j] # 0xf0a3 - - "𝕛": [T: struck ganda j] # 0x1d55b - - "": [T: struck ganda k] # 0xf0a4 - - "𝕜": [T: struck ganda k] # 0x1d55c - - "": [T: struck ganda l] # 0xf0a5 - - "𝕝": [T: struck ganda l] # 0x1d55d - - "": [T: struck ganda m] # 0xf0a6 - - "𝕞": [T: struck ganda m] # 0x1d55e - - "": [T: struck ganda n] # 0xf0a7 - - "𝕟": [T: struck ganda n] # 0x1d55f - - "": [T: struck ganda o] # 0xf0a8 - - "𝕠": [T: struck ganda o] # 0x1d560 - - "": [T: struck ganda p] # 0xf0a9 - - "𝕡": [T: struck ganda p] # 0x1d561 - - "": [T: struck ganda q] # 0xf0aa - - "𝕢": [T: struck ganda q] # 0x1d562 - - "": [T: struck ganda r] # 0xf0ab - - "𝕣": [T: struck ganda r] # 0x1d563 - - "": [T: struck ganda s] # 0xf0ac - - "𝕤": [T: struck ganda s] # 0x1d564 - - "": [T: struck ganda t] # 0xf0ad - - "𝕥": [T: struck ganda t] # 0x1d565 - - "": [T: struck ganda u] # 0xf0ae - - "𝕦": [T: struck ganda u] # 0x1d566 - - "": [T: struck ganda v] # 0xf0af - - "𝕧": [T: struck ganda v] # 0x1d567 - - "": [T: struck ganda w] # 0xf0b0 - - "𝕨": [T: struck ganda w] # 0x1d568 - - "": [T: struck ganda x] # 0xf0b1 - - "𝕩": [T: struck ganda x] # 0x1d569 - - "": [T: struck ganda y] # 0xf0b2 - - "𝕪": [T: struck ganda y] # 0x1d56a - - "": [T: struck ganda z] # 0xf0b3 - - "𝕫": [T: struck ganda z] # 0x1d56b - - "": [T: struck ganda nol] # 0xf0c0 - - "𝟘": [T: struck ganda nol] # 0x1d7d8 - - "": [T: struck ganda satu] # 0xf0c1 - - "𝟙": [T: struck ganda satu] # 0x1d7d9 - - "": [T: struck ganda dua] # 0xf0c2 - - "𝟚": [T: struck ganda dua] # 0x1d7da - - "": [T: struck ganda tiga] # 0xf0c3 - - "𝟛": [T: struck ganda tiga] # 0x1d7db - - "": [T: struck ganda empat] # 0xf0c4 - - "𝟜": [T: struck ganda empat] # 0x1d7dc - - "": [T: struck ganda lima] # 0xf0c5 - - "𝟝": [T: struck ganda lima] # 0x1d7dd - - "": [T: struck ganda enam] # 0xf0c6 - - "𝟞": [T: struck ganda enam] # 0x1d7de - - "": [T: struck ganda tujuh] # 0xf0c7 - - "𝟟": [T: struck ganda tujuh] # 0x1d7df - - "": [T: struck ganda delapan] # 0xf0c8 - - "𝟠": [T: struck ganda delapan] # 0x1d7e0 - - "": [T: struck ganda sembilan] # 0xf0c9 - - "𝟡": [T: struck ganda sembilan] # 0x1d7e1 - - "": [T: struck ganda nabla] # 0xf0ca - - "": [T: struck ganda konstanta euler] # 0xf0cb - - "": # 0xf100 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "𝒜": # 0x1d49c - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "": # 0xf102 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "𝒞": # 0x1d49e - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "": # 0xf103 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "𝒟": # 0x1d49f - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "": # 0xf106 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "𝒢": # 0x1d4a2 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "": # 0xf109 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "𝒥": # 0x1d4a5 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "": # 0xf10a - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "𝒦": # 0x1d4a6 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "": # 0xf10d - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "𝒩": # 0x1d4a9 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "": # 0xf10e - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "𝒪": # 0x1d4aa - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "": # 0xf10f - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "𝒫": # 0x1d4ab - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "": # 0xf110 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "𝒬": # 0x1d4ac - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "": # 0xf112 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "𝒮": # 0x1d4ae - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "": # 0xf113 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "𝒯": # 0x1d4af - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "": # 0xf114 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "𝒰": # 0x1d4b0 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "": # 0xf115 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "𝒱": # 0x1d4b1 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "": # 0xf116 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "𝒲": # 0x1d4b2 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "": # 0xf117 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "𝒳": # 0x1d4b3 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "": # 0xf118 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "𝒴": # 0x1d4b4 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "": # 0xf119 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "𝒵": # 0x1d4b5 - - T: aksara - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "": [T: aksara a] # 0xf11a - - "𝒶": [T: aksara a] # 0x1d4b6 - - "": [T: aksara b] # 0xf11b - - "𝒷": [T: aksara b] # 0x1d4b7 - - "": [T: aksara c] # 0xf11c - - "𝒸": [T: aksara c] # 0x1d4b8 - - "": [T: aksara d] # 0xf11d - - "𝒹": [T: aksara d] # 0x1d4b9 - - "": [T: aksara f] # 0xf11f - - "𝒻": [T: aksara f] # 0x1d4bb - - "": [T: aksara h] # 0xf121 - - "𝒽": [T: aksara h] # 0x1d4bd - - "": [T: aksara i] # 0xf122 - - "𝒾": [T: aksara i] # 0x1d4be - - "": [T: aksara j] # 0xf123 - - "𝒿": [T: aksara j] # 0x1d4bf - - "": [T: aksara k] # 0xf124 - - "𝓀": [T: aksara k] # 0x1d4c0 - - "": [T: aksara m] # 0xf126 - - "𝓂": [T: aksara m] # 0x1d4c2 - - "": [T: aksara n] # 0xf127 - - "𝓃": [T: aksara n] # 0x1d4c3 - - "": [T: aksara p] # 0xf129 - - "𝓅": [T: aksara p] # 0x1d4c5 - - "": [T: aksara q] # 0xf12a - - "𝓆": [T: aksara q] # 0x1d4c6 - - "": [T: aksara r] # 0xf12b - - "𝓇": [T: aksara r] # 0x1d4c7 - - "": [T: aksara s] # 0xf12c - - "𝓈": [T: aksara s] # 0x1d4c8 - - "": [T: aksara t] # 0xf12d - - "𝓉": [T: aksara t] # 0x1d4c9 - - "": [T: aksara u] # 0xf12e - - "𝓊": [T: aksara u] # 0x1d4ca - - "": [T: aksara v] # 0xf12f - - "𝓋": [T: aksara v] # 0x1d4cb - - "": [T: aksara w] # 0xf130 - - "𝓌": [T: aksara w] # 0x1d4cc - - "": [T: aksara x] # 0xf131 - - "𝓍": [T: aksara x] # 0x1d4cd - - "": [T: aksara y] # 0xf132 - - "𝓎": [T: aksara y] # 0x1d4ce - - "": [T: aksara z] # 0xf133 - - "𝓏": [T: aksara z] # 0x1d4cf - - "": # 0xf140 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "𝓐": # 0x1d4d0 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "": # 0xf141 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "𝓑": # 0x1d4d1 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "": # 0xf142 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "𝓒": # 0x1d4d2 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "": # 0xf143 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "𝓓": # 0x1d4d3 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "": # 0xf144 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "𝓔": # 0x1d4d4 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "": # 0xf145 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "𝓕": # 0x1d4d5 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "": # 0xf146 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "𝓖": # 0x1d4d6 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "": # 0xf147 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "𝓗": # 0x1d4d7 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "": # 0xf148 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "𝓘": # 0x1d4d8 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "": # 0xf149 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "𝓙": # 0x1d4d9 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "": # 0xf14a - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "𝓚": # 0x1d4da - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "": # 0xf14b - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "𝓛": # 0x1d4db - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "": # 0xf14c - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "𝓜": # 0x1d4dc - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "": # 0xf14d - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "𝓝": # 0x1d4dd - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "": # 0xf14e - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "𝓞": # 0x1d4de - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "": # 0xf14f - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "𝓟": # 0x1d4df - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "": # 0xf150 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "𝓠": # 0x1d4e0 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "": # 0xf151 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "𝓡": # 0x1d4e1 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "": # 0xf152 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "𝓢": # 0x1d4e2 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "": # 0xf153 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "𝓣": # 0x1d4e3 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "": # 0xf154 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "𝓤": # 0x1d4e4 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "": # 0xf155 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "𝓥": # 0x1d4e5 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "": # 0xf156 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "𝓦": # 0x1d4e6 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "": # 0xf157 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "𝓧": # 0x1d4e7 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "": # 0xf158 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "𝓨": # 0x1d4e8 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "": # 0xf159 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "𝓩": # 0x1d4e9 - - T: aksara bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "": [T: aksara bold a] # 0xf15a - - "𝓪": [T: aksara bold a] # 0x1d4ea - - "": [T: aksara bold b] # 0xf15b - - "𝓫": [T: aksara bold b] # 0x1d4eb - - "": [T: aksara bold c] # 0xf15c - - "𝓬": [T: aksara bold c] # 0x1d4ec - - "": [T: aksara bold d] # 0xf15d - - "𝓭": [T: aksara bold d] # 0x1d4ed - - "": [T: aksara bold e] # 0xf15e - - "𝓮": [T: aksara bold e] # 0x1d4ee - - "": [T: aksara bold f] # 0xf15f - - "𝓯": [T: aksara bold f] # 0x1d4ef - - "": [T: aksara bold g] # 0xf160 - - "𝓰": [T: aksara bold g] # 0x1d4f0 - - "": [T: aksara bold h] # 0xf161 - - "𝓱": [T: aksara bold h] # 0x1d4f1 - - "": [T: aksara bold i] # 0xf162 - - "𝓲": [T: aksara bold i] # 0x1d4f2 - - "": [T: aksara bold j] # 0xf163 - - "𝓳": [T: aksara bold j] # 0x1d4f3 - - "": [T: aksara bold k] # 0xf164 - - "𝓴": [T: aksara bold k] # 0x1d4f4 - - "": [T: aksara bold l] # 0xf165 - - "𝓵": [T: aksara bold l] # 0x1d4f5 - - "": [T: aksara bold m] # 0xf166 - - "𝓶": [T: aksara bold m] # 0x1d4f6 - - "": [T: aksara bold n] # 0xf167 - - "𝓷": [T: aksara bold n] # 0x1d4f7 - - "": [T: aksara bold o] # 0xf168 - - "𝓸": [T: aksara bold o] # 0x1d4f8 - - "": [T: aksara bold p] # 0xf169 - - "𝓹": [T: aksara bold p] # 0x1d4f9 - - "": [T: aksara bold q] # 0xf16a - - "𝓺": [T: aksara bold q] # 0x1d4fa - - "": [T: aksara bold r] # 0xf16b - - "𝓻": [T: aksara bold r] # 0x1d4fb - - "": [T: aksara bold s] # 0xf16c - - "𝓼": [T: aksara bold s] # 0x1d4fc - - "": [T: aksara bold t] # 0xf16d - - "𝓽": [T: aksara bold t] # 0x1d4fd - - "": [T: aksara bold u] # 0xf16e - - "𝓾": [T: aksara bold u] # 0x1d4fe - - "": [T: aksara bold v] # 0xf16f - - "𝓿": [T: aksara bold v] # 0x1d4ff - - "": [T: aksara bold w] # 0xf170 - - "𝔀": [T: aksara bold w] # 0x1d500 - - "": [T: aksara bold x] # 0xf171 - - "𝔁": [T: aksara bold x] # 0x1d501 - - "": [T: aksara bold y] # 0xf172 - - "𝔂": [T: aksara bold y] # 0x1d502 - - "": [T: aksara bold z] # 0xf173 - - "𝔃": [T: aksara bold z] # 0x1d503 - - "": # 0xf180 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "": # 0xf182 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "": # 0xf183 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "": # 0xf184 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "": # 0xf185 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "": # 0xf189 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "": # 0xf18a - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "": # 0xf18c - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "": # 0xf18e - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "": # 0xf18f - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "": # 0xf190 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "": # 0xf192 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "": # 0xf193 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "": # 0xf194 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "": # 0xf195 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "": # 0xf196 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "": # 0xf197 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "": # 0xf199 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "": # 0xf19a - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: ligature ae - - "": # 0xf19b - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: sharp s - - "": # 0xf19c - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o with stroke - - "": # 0xf201 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: delta - - "": # 0xf202 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: zai - - "": # 0xf203 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: lambda - - "": # 0xf204 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: pi - - "": # 0xf205 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: sigma - - "": # 0xf206 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "": # 0xf207 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: gamma - - "": # 0xf208 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omega - - "": # 0xf209 - - T: struck ganda - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: upsilon - - "": [T: struck ganda alpha] # 0xf220 - - "": [T: struck ganda beta] # 0xf221 - - "": [T: struck ganda phi] # 0xf222 - - "": [T: struck ganda zeta] # 0xf223 - - "": [T: struck ganda psi] # 0xf224 - - "": [T: struck ganda delta] # 0xf225 - - "": [T: struck ganda epsilon tidak keriting] # 0xf226 - - "": [T: struck ganda gamma] # 0xf227 - - "": [T: struck ganda eta] # 0xf228 - - "": [T: struck ganda iota] # 0xf229 - - "": [T: struck ganda xi] # 0xf22a - - "": [T: struck ganda kappa] # 0xf22b - - "": [T: struck ganda lambda] # 0xf22c - - "": [T: struck ganda mu] # 0xf22d - - "": [T: struck ganda nu] # 0xf22e - - "": [T: struck ganda epsilon] # 0xf22f - - "": [T: struck ganda pi] # 0xf230 - - "": [T: struck ganda theta] # 0xf231 - - "": [T: struck ganda rho] # 0xf232 - - "": [T: struck ganda sigma] # 0xf233 - - "": [T: struck ganda tau] # 0xf234 - - "": [T: struck ganda theta] # 0xf235 - - "": [T: struck ganda omega] # 0xf236 - - "": [T: struck ganda final sigma] # 0xf237 - - "": [T: struck ganda rho] # 0xf250 - - "": [T: struck ganda phi] # 0xf251 - - "": # 0xf260 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "𝐀": # 0x1d400 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "": # 0xf261 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "𝐁": # 0x1d401 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "": # 0xf262 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "𝐂": # 0x1d402 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "": # 0xf263 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "𝐃": # 0x1d403 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "": # 0xf264 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "𝐄": # 0x1d404 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "": # 0xf265 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "𝐅": # 0x1d405 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "": # 0xf266 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "𝐆": # 0x1d406 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "": # 0xf267 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "𝐇": # 0x1d407 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "": # 0xf268 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "𝐈": # 0x1d408 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "": # 0xf269 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "𝐉": # 0x1d409 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "": # 0xf26a - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "𝐊": # 0x1d40a - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "": # 0xf26b - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "𝐋": # 0x1d40b - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "": # 0xf26c - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "𝐌": # 0x1d40c - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "": # 0xf26d - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "𝐍": # 0x1d40d - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "": # 0xf26e - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "𝐎": # 0x1d40e - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "": # 0xf26f - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "𝐏": # 0x1d40f - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "": # 0xf270 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "𝐐": # 0x1d410 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "": # 0xf271 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "𝐑": # 0x1d411 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "": # 0xf272 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "𝐒": # 0x1d412 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "": # 0xf273 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "𝐓": # 0x1d413 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "": # 0xf274 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "𝐔": # 0x1d414 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "": # 0xf275 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "𝐕": # 0x1d415 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "": # 0xf276 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "𝐖": # 0x1d416 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "": # 0xf277 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "𝐗": # 0x1d417 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "": # 0xf278 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "𝐘": # 0x1d418 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "": # 0xf279 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "𝐙": # 0x1d419 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "": [T: bold a] # 0xf27a - - "𝐚": [T: bold a] # 0x1d41a - - "": [T: bold b] # 0xf27b - - "𝐛": [T: bold b] # 0x1d41b - - "": [T: bold c] # 0xf27c - - "𝐜": [T: bold c] # 0x1d41c - - "": [T: bold d] # 0xf27d - - "𝐝": [T: bold d] # 0x1d41d - - "": [T: bold e] # 0xf27e - - "𝐞": [T: bold e] # 0x1d41e - - "": [T: bold f] # 0xf27f - - "𝐟": [T: bold f] # 0x1d41f - - "": [T: bold g] # 0xf280 - - "𝐠": [T: bold g] # 0x1d420 - - "": [T: bold h] # 0xf281 - - "𝐡": [T: bold h] # 0x1d421 - - "": [T: bold i] # 0xf282 - - "𝐢": [T: bold i] # 0x1d422 - - "": [T: bold j] # 0xf283 - - "𝐣": [T: bold j] # 0x1d423 - - "": [T: bold k] # 0xf284 - - "𝐤": [T: bold k] # 0x1d424 - - "": [T: bold l] # 0xf285 - - "𝐥": [T: bold l] # 0x1d425 - - "": [T: bold m] # 0xf286 - - "𝐦": [T: bold m] # 0x1d426 - - "": [T: bold n] # 0xf287 - - "𝐧": [T: bold n] # 0x1d427 - - "": [T: bold o] # 0xf288 - - "𝐨": [T: bold o] # 0x1d428 - - "": [T: bold p] # 0xf289 - - "𝐩": [T: bold p] # 0x1d429 - - "": [T: bold q] # 0xf28a - - "𝐪": [T: bold q] # 0x1d42a - - "": [T: bold r] # 0xf28b - - "𝐫": [T: bold r] # 0x1d42b - - "": [T: bold s] # 0xf28c - - "𝐬": [T: bold s] # 0x1d42c - - "": [T: bold t] # 0xf28d - - "𝐭": [T: bold t] # 0x1d42d - - "": [T: bold u] # 0xf28e - - "𝐮": [T: bold u] # 0x1d42e - - "": [T: bold v] # 0xf28f - - "𝐯": [T: bold v] # 0x1d42f - - "": [T: bold w] # 0xf290 - - "𝐰": [T: bold w] # 0x1d430 - - "": [T: bold x] # 0xf291 - - "𝐱": [T: bold x] # 0x1d431 - - "": [T: bold y] # 0xf292 - - "𝐲": [T: bold y] # 0x1d432 - - "": [T: bold z] # 0xf293 - - "𝐳": [T: bold z] # 0x1d433 - - "": # 0xf294 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "𝐴": # 0x1d434 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "": # 0xf295 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "𝐵": # 0x1d435 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "": # 0xf296 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "𝐶": # 0x1d436 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "": # 0xf297 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "𝐷": # 0x1d437 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "": # 0xf298 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "𝐸": # 0x1d438 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "": # 0xf299 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "𝐹": # 0x1d439 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "": # 0xf29a - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "𝐺": # 0x1d43a - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "": # 0xf29b - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "𝐻": # 0x1d43b - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "": # 0xf29c - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "𝐼": # 0x1d43c - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "": # 0xf29d - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "𝐽": # 0x1d43d - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "": # 0xf29e - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "𝐾": # 0x1d43e - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "": # 0xf29f - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "𝐿": # 0x1d43f - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "": # 0xf2a0 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "𝑀": # 0x1d440 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "": # 0xf2a1 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "𝑁": # 0x1d441 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "": # 0xf2a2 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "𝑂": # 0x1d442 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "": # 0xf2a3 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "𝑃": # 0x1d443 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "": # 0xf2a4 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "𝑄": # 0x1d444 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "": # 0xf2a5 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "𝑅": # 0x1d445 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "": # 0xf2a6 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "𝑆": # 0x1d446 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "": # 0xf2a7 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "𝑇": # 0x1d447 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "": # 0xf2a8 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "𝑈": # 0x1d448 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "": # 0xf2a9 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "𝑉": # 0x1d449 - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "": # 0xf2aa - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "𝑊": # 0x1d44a - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "": # 0xf2ab - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "𝑋": # 0x1d44b - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "": # 0xf2ac - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "𝑌": # 0x1d44c - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "": # 0xf2ad - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "𝑍": # 0x1d44d - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "": [T: b] # 0xf2af - - "𝑏": [T: b] # 0x1d44f - - "": [T: c] # 0xf2b0 - - "𝑐": [T: c] # 0x1d450 - - "": [T: d] # 0xf2b1 - - "𝑑": [T: d] # 0x1d451 - - "": [T: e] # 0xf2b2 - - "𝑒": [T: e] # 0x1d452 - - "": [T: f] # 0xf2b3 - - "𝑓": [T: f] # 0x1d453 - - "": [T: g] # 0xf2b4 - - "𝑔": [T: g] # 0x1d454 - - "": [T: h] # 0xf2b5 - - "𝑕": [T: h] # 0x1d455 - - "": [T: i] # 0xf2b6 - - "𝑖": [T: i] # 0x1d456 - - "": [T: j] # 0xf2b7 - - "𝑗": [T: j] # 0x1d457 - - "": [T: k] # 0xf2b8 - - "𝑘": [T: k] # 0x1d458 - - "": [T: l] # 0xf2b9 - - "𝑙": [T: l] # 0x1d459 - - "": [T: m] # 0xf2ba - - "𝑚": [T: m] # 0x1d45a - - "": [T: n] # 0xf2bb - - "𝑛": [T: n] # 0x1d45b - - "": [T: o] # 0xf2bc - - "𝑜": [T: o] # 0x1d45c - - "": [T: p] # 0xf2bd - - "𝑝": [T: p] # 0x1d45d - - "": [T: q] # 0xf2be - - "𝑞": [T: q] # 0x1d45e - - "": [T: r] # 0xf2bf - - "𝑟": [T: r] # 0x1d45f - - "": [T: s] # 0xf2c0 - - "𝑠": [T: s] # 0x1d460 - - "": [T: t] # 0xf2c1 - - "𝑡": [T: t] # 0x1d461 - - "": [T: u] # 0xf2c2 - - "𝑢": [T: u] # 0x1d462 - - "": [T: v] # 0xf2c3 - - "𝑣": [T: v] # 0x1d463 - - "": [T: w] # 0xf2c4 - - "𝑤": [T: w] # 0x1d464 - - "": [T: x] # 0xf2c5 - - "𝑥": [T: x] # 0x1d465 - - "": [T: y] # 0xf2c6 - - "𝑦": [T: y] # 0x1d466 - - "": [T: z] # 0xf2c7 - - "𝑧": [T: z] # 0x1d467 - - "": # 0xf2c8 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "𝑨": # 0x1d468 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "": # 0xf2c9 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "𝑩": # 0x1d469 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "": # 0xf2ca - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "𝑪": # 0x1d46a - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "": # 0xf2cb - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "𝑫": # 0x1d46b - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "": # 0xf2cc - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "𝑬": # 0x1d46c - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "": # 0xf2cd - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "𝑭": # 0x1d46d - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "": # 0xf2ce - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "𝑮": # 0x1d46e - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "": # 0xf2cf - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "𝑯": # 0x1d46f - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "": # 0xf2d0 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "𝑰": # 0x1d470 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "": # 0xf2d1 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "𝑱": # 0x1d471 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "": # 0xf2d2 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "𝑲": # 0x1d472 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "": # 0xf2d3 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "𝑳": # 0x1d473 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "": # 0xf2d4 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "𝑴": # 0x1d474 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "": # 0xf2d5 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "𝑵": # 0x1d475 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "": # 0xf2d6 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "𝑶": # 0x1d476 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "": # 0xf2d7 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "𝑷": # 0x1d477 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "": # 0xf2d8 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "𝑸": # 0x1d478 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "": # 0xf2d9 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "𝑹": # 0x1d479 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "": # 0xf2da - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "𝑺": # 0x1d47a - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "": # 0xf2db - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "𝑻": # 0x1d47b - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "": # 0xf2dc - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "𝑼": # 0x1d47c - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "": # 0xf2dd - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "𝑽": # 0x1d47d - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "": # 0xf2de - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "𝑾": # 0x1d47e - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "": # 0xf2df - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "𝑿": # 0x1d47f - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "": # 0xf2e0 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "𝒀": # 0x1d480 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "": # 0xf2e1 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "𝒁": # 0x1d481 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "": [T: bold italic a] # 0xf2e2 - - "𝒂": [T: bold italic a] # 0x1d482 - - "": [T: bold italic b] # 0xf2e3 - - "𝒃": [T: bold italic b] # 0x1d483 - - "": [T: bold italic c] # 0xf2e4 - - "𝒄": [T: bold italic c] # 0x1d484 - - "": [T: bold italic d] # 0xf2e5 - - "𝒅": [T: bold italic d] # 0x1d485 - - "": [T: bold italic e] # 0xf2e6 - - "𝒆": [T: bold italic e] # 0x1d486 - - "": [T: bold italic f] # 0xf2e7 - - "𝒇": [T: bold italic f] # 0x1d487 - - "": [T: bold italic g] # 0xf2e8 - - "𝒈": [T: bold italic g] # 0x1d488 - - "": [T: bold italic h] # 0xf2e9 - - "𝒉": [T: bold italic h] # 0x1d489 - - "": [T: bold italic i] # 0xf2ea - - "𝒊": [T: bold italic i] # 0x1d48a - - "": [T: bold italic j] # 0xf2eb - - "𝒋": [T: bold italic j] # 0x1d48b - - "": [T: bold italic k] # 0xf2ec - - "𝒌": [T: bold italic k] # 0x1d48c - - "": [T: bold italic l] # 0xf2ed - - "𝒍": [T: bold italic l] # 0x1d48d - - "": [T: bold italic m] # 0xf2ee - - "𝒎": [T: bold italic m] # 0x1d48e - - "": [T: bold italic n] # 0xf2ef - - "𝒏": [T: bold italic n] # 0x1d48f - - "": [T: bold italic o] # 0xf2f0 - - "𝒐": [T: bold italic o] # 0x1d490 - - "": [T: bold italic p] # 0xf2f1 - - "𝒑": [T: bold italic p] # 0x1d491 - - "": [T: bold italic q] # 0xf2f2 - - "𝒒": [T: bold italic q] # 0x1d492 - - "": [T: bold italic r] # 0xf2f3 - - "𝒓": [T: bold italic r] # 0x1d493 - - "": [T: bold italic s] # 0xf2f4 - - "𝒔": [T: bold italic s] # 0x1d494 - - "": [T: bold italic t] # 0xf2f5 - - "𝒕": [T: bold italic t] # 0x1d495 - - "": [T: bold italic u] # 0xf2f6 - - "𝒖": [T: bold italic u] # 0x1d496 - - "": [T: bold italic v] # 0xf2f7 - - "𝒗": [T: bold italic v] # 0x1d497 - - "": [T: bold italic w] # 0xf2f8 - - "𝒘": [T: bold italic w] # 0x1d498 - - "": [T: bold italic x] # 0xf2f9 - - "𝒙": [T: bold italic x] # 0x1d499 - - "": [T: bold italic y] # 0xf2fa - - "𝒚": [T: bold italic y] # 0x1d49a - - "": [T: bold italic z] # 0xf2fb - - "𝒛": [T: bold italic z] # 0x1d49b - - "": # 0xf300 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "𝖠": # 0x1d5a0 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "": # 0xf301 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "𝖡": # 0x1d5a1 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "": # 0xf302 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "𝖢": # 0x1d5a2 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "": # 0xf303 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "𝖣": # 0x1d5a3 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "": # 0xf304 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "𝖤": # 0x1d5a4 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "": # 0xf305 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "𝖥": # 0x1d5a5 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "": # 0xf306 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "𝖦": # 0x1d5a6 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "": # 0xf307 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "𝖧": # 0x1d5a7 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "": # 0xf308 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "𝖨": # 0x1d5a8 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "": # 0xf309 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "𝖩": # 0x1d5a9 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "": # 0xf30a - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "𝖪": # 0x1d5aa - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "": # 0xf30b - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "𝖫": # 0x1d5ab - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "": # 0xf30c - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "𝖬": # 0x1d5ac - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "": # 0xf30d - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "𝖭": # 0x1d5ad - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "": # 0xf30e - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "𝖮": # 0x1d5ae - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "": # 0xf30f - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "𝖯": # 0x1d5af - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "": # 0xf310 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "𝖰": # 0x1d5b0 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "": # 0xf311 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "𝖱": # 0x1d5b1 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "": # 0xf312 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "𝖲": # 0x1d5b2 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "": # 0xf313 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "𝖳": # 0x1d5b3 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "": # 0xf314 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "𝖴": # 0x1d5b4 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "": # 0xf315 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "𝖵": # 0x1d5b5 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "": # 0xf316 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "𝖶": # 0x1d5b6 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "": # 0xf317 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "𝖷": # 0x1d5b7 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "": # 0xf318 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "𝖸": # 0x1d5b8 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "": # 0xf319 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "𝖹": # 0x1d5b9 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "": [T: a] # 0xf31a - - "𝖺": [T: a] # 0x1d5ba - - "": [T: b] # 0xf31b - - "𝖻": [T: b] # 0x1d5bb - - "": [T: c] # 0xf31c - - "𝖼": [T: c] # 0x1d5bc - - "": [T: d] # 0xf31d - - "𝖽": [T: d] # 0x1d5bd - - "": [T: e] # 0xf31e - - "𝖾": [T: e] # 0x1d5be - - "": [T: f] # 0xf31f - - "𝖿": [T: f] # 0x1d5bf - - "": [T: g] # 0xf320 - - "𝗀": [T: g] # 0x1d5c0 - - "": [T: h] # 0xf321 - - "𝗁": [T: h] # 0x1d5c1 - - "": [T: i] # 0xf322 - - "𝗂": [T: i] # 0x1d5c2 - - "": [T: j] # 0xf323 - - "𝗃": [T: j] # 0x1d5c3 - - "": [T: k] # 0xf324 - - "𝗄": [T: k] # 0x1d5c4 - - "": [T: l] # 0xf325 - - "𝗅": [T: l] # 0x1d5c5 - - "": [T: m] # 0xf326 - - "𝗆": [T: m] # 0x1d5c6 - - "": [T: n] # 0xf327 - - "𝗇": [T: n] # 0x1d5c7 - - "": [T: o] # 0xf328 - - "𝗈": [T: o] # 0x1d5c8 - - "": [T: p] # 0xf329 - - "𝗉": [T: p] # 0x1d5c9 - - "": [T: q] # 0xf32a - - "𝗊": [T: q] # 0x1d5ca - - "": [T: r] # 0xf32b - - "𝗋": [T: r] # 0x1d5cb - - "": [T: s] # 0xf32c - - "𝗌": [T: s] # 0x1d5cc - - "": [T: t] # 0xf32d - - "𝗍": [T: t] # 0x1d5cd - - "": [T: u] # 0xf32e - - "𝗎": [T: u] # 0x1d5ce - - "": [T: v] # 0xf32f - - "𝗏": [T: v] # 0x1d5cf - - "": [T: w] # 0xf330 - - "𝗐": [T: w] # 0x1d5d0 - - "": [T: x] # 0xf331 - - "𝗑": [T: x] # 0x1d5d1 - - "": [T: y] # 0xf332 - - "𝗒": [T: y] # 0x1d5d2 - - "": [T: z] # 0xf333 - - "𝗓": [T: z] # 0x1d5d3 - - "": # 0xf334 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "𝗔": # 0x1d5d4 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "": # 0xf335 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "𝗕": # 0x1d5d5 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "": # 0xf336 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "𝗖": # 0x1d5d6 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "": # 0xf337 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "𝗗": # 0x1d5d7 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "": # 0xf338 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "𝗘": # 0x1d5d8 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "": # 0xf339 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "𝗙": # 0x1d5d9 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "": # 0xf33a - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "𝗚": # 0x1d5da - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "": # 0xf33b - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "𝗛": # 0x1d5db - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "": # 0xf33c - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "𝗜": # 0x1d5dc - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "": # 0xf33d - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "𝗝": # 0x1d5dd - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "": # 0xf33e - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "𝗞": # 0x1d5de - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "": # 0xf33f - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "𝗟": # 0x1d5df - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "": # 0xf340 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "𝗠": # 0x1d5e0 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "": # 0xf341 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "𝗡": # 0x1d5e1 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "": # 0xf342 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "𝗢": # 0x1d5e2 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "": # 0xf343 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "𝗣": # 0x1d5e3 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "": # 0xf344 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "𝗤": # 0x1d5e4 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "": # 0xf345 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "𝗥": # 0x1d5e5 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "": # 0xf346 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "𝗦": # 0x1d5e6 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "": # 0xf347 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "𝗧": # 0x1d5e7 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "": # 0xf348 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "𝗨": # 0x1d5e8 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "": # 0xf349 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "𝗩": # 0x1d5e9 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "": # 0xf34a - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "𝗪": # 0x1d5ea - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "": # 0xf34b - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "𝗫": # 0x1d5eb - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "": # 0xf34c - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "𝗬": # 0x1d5ec - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "": # 0xf34d - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "𝗭": # 0x1d5ed - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "": [T: bold a] # 0xf34e - - "𝗮": [T: bold a] # 0x1d5ee - - "": [T: bold b] # 0xf34f - - "𝗯": [T: bold b] # 0x1d5ef - - "": [T: bold c] # 0xf350 - - "𝗰": [T: bold c] # 0x1d5f0 - - "": [T: bold d] # 0xf351 - - "𝗱": [T: bold d] # 0x1d5f1 - - "": [T: bold e] # 0xf352 - - "𝗲": [T: bold e] # 0x1d5f2 - - "": [T: bold f] # 0xf353 - - "𝗳": [T: bold f] # 0x1d5f3 - - "": [T: bold g] # 0xf354 - - "𝗴": [T: bold g] # 0x1d5f4 - - "": [T: bold h] # 0xf355 - - "𝗵": [T: bold h] # 0x1d5f5 - - "": [T: bold i] # 0xf356 - - "𝗶": [T: bold i] # 0x1d5f6 - - "": [T: bold j] # 0xf357 - - "𝗷": [T: bold j] # 0x1d5f7 - - "": [T: bold k] # 0xf358 - - "𝗸": [T: bold k] # 0x1d5f8 - - "": [T: bold l] # 0xf359 - - "𝗹": [T: bold l] # 0x1d5f9 - - "": [T: bold m] # 0xf35a - - "𝗺": [T: bold m] # 0x1d5fa - - "": [T: bold n] # 0xf35b - - "𝗻": [T: bold n] # 0x1d5fb - - "": [T: bold o] # 0xf35c - - "𝗼": [T: bold o] # 0x1d5fc - - "": [T: bold p] # 0xf35d - - "𝗽": [T: bold p] # 0x1d5fd - - "": [T: bold q] # 0xf35e - - "𝗾": [T: bold q] # 0x1d5fe - - "": [T: bold r] # 0xf35f - - "𝗿": [T: bold r] # 0x1d5ff - - "": [T: bold s] # 0xf360 - - "𝘀": [T: bold s] # 0x1d600 - - "": [T: bold t] # 0xf361 - - "𝘁": [T: bold t] # 0x1d601 - - "": [T: bold u] # 0xf362 - - "𝘂": [T: bold u] # 0x1d602 - - "": [T: bold v] # 0xf363 - - "𝘃": [T: bold v] # 0x1d603 - - "": [T: bold w] # 0xf364 - - "𝘄": [T: bold w] # 0x1d604 - - "": [T: bold x] # 0xf365 - - "𝘅": [T: bold x] # 0x1d605 - - "": [T: bold y] # 0xf366 - - "𝘆": [T: bold y] # 0x1d606 - - "": [T: bold z] # 0xf367 - - "𝘇": [T: bold z] # 0x1d607 - - "": # 0xf368 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "𝘈": # 0x1d608 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "": # 0xf369 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "𝘉": # 0x1d609 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "": # 0xf36a - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "𝘊": # 0x1d60a - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "": # 0xf36b - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "𝘋": # 0x1d60b - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "": # 0xf36c - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "𝘌": # 0x1d60c - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "": # 0xf36d - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "𝘍": # 0x1d60d - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "": # 0xf36e - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "𝘎": # 0x1d60e - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "": # 0xf36f - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "𝘏": # 0x1d60f - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "": # 0xf370 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "𝘐": # 0x1d610 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "": # 0xf371 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "𝘑": # 0x1d611 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "": # 0xf372 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "𝘒": # 0x1d612 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "": # 0xf373 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "𝘓": # 0x1d613 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "": # 0xf374 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "𝘔": # 0x1d614 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "": # 0xf375 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "𝘕": # 0x1d615 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "": # 0xf376 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "𝘖": # 0x1d616 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "": # 0xf377 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "𝘗": # 0x1d617 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "": # 0xf378 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "𝘘": # 0x1d618 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "": # 0xf379 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "𝘙": # 0x1d619 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "": # 0xf37a - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "𝘚": # 0x1d61a - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "": # 0xf37b - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "𝘛": # 0x1d61b - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "": # 0xf37c - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "𝘜": # 0x1d61c - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "": # 0xf37d - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "𝘝": # 0x1d61d - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "": # 0xf37e - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "𝘞": # 0x1d61e - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "": # 0xf37f - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "𝘟": # 0x1d61f - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "": # 0xf380 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "𝘠": # 0x1d620 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "": # 0xf381 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "𝘡": # 0x1d621 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "": [T: italic a] # 0xf382 - - "𝘢": [T: italic a] # 0x1d622 - - "": [T: italic b] # 0xf383 - - "𝘣": [T: italic b] # 0x1d623 - - "": [T: italic c] # 0xf384 - - "𝘤": [T: italic c] # 0x1d624 - - "": [T: italic d] # 0xf385 - - "𝘥": [T: italic d] # 0x1d625 - - "": [T: italic e] # 0xf386 - - "𝘦": [T: italic e] # 0x1d626 - - "": [T: italic f] # 0xf387 - - "𝘧": [T: italic f] # 0x1d627 - - "": [T: italic g] # 0xf388 - - "𝘨": [T: italic g] # 0x1d628 - - "": [T: italic h] # 0xf389 - - "𝘩": [T: italic h] # 0x1d629 - - "": [T: italic i] # 0xf38a - - "𝘪": [T: italic i] # 0x1d62a - - "": [T: italic j] # 0xf38b - - "𝘫": [T: italic j] # 0x1d62b - - "": [T: italic k] # 0xf38c - - "𝘬": [T: italic k] # 0x1d62c - - "": [T: italic l] # 0xf38d - - "𝘭": [T: italic l] # 0x1d62d - - "": [T: italic m] # 0xf38e - - "𝘮": [T: italic m] # 0x1d62e - - "": [T: italic n] # 0xf38f - - "𝘯": [T: italic n] # 0x1d62f - - "": [T: italic o] # 0xf390 - - "𝘰": [T: italic o] # 0x1d630 - - "": [T: italic p] # 0xf391 - - "𝘱": [T: italic p] # 0x1d631 - - "": [T: italic q] # 0xf392 - - "𝘲": [T: italic q] # 0x1d632 - - "": [T: italic r] # 0xf393 - - "𝘳": [T: italic r] # 0x1d633 - - "": [T: italic s] # 0xf394 - - "𝘴": [T: italic s] # 0x1d634 - - "": [T: italic t] # 0xf395 - - "𝘵": [T: italic t] # 0x1d635 - - "": [T: italic u] # 0xf396 - - "𝘶": [T: italic u] # 0x1d636 - - "": [T: italic v] # 0xf397 - - "𝘷": [T: italic v] # 0x1d637 - - "": [T: italic w] # 0xf398 - - "𝘸": [T: italic w] # 0x1d638 - - "": [T: italic x] # 0xf399 - - "𝘹": [T: italic x] # 0x1d639 - - "": [T: italic y] # 0xf39a - - "𝘺": [T: italic y] # 0x1d63a - - "": [T: italic z] # 0xf39b - - "𝘻": [T: italic z] # 0x1d63b - - "": # 0xf39c - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "𝘼": # 0x1d63c - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "": # 0xf39d - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "𝘽": # 0x1d63d - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "": # 0xf39e - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "𝘾": # 0x1d63e - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "": # 0xf39f - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "𝘿": # 0x1d63f - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "": # 0xf3a0 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "𝙀": # 0x1d640 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "": # 0xf3a1 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "𝙁": # 0x1d641 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "": # 0xf3a2 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "𝙂": # 0x1d642 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "": # 0xf3a3 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "𝙃": # 0x1d643 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "": # 0xf3a4 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "𝙄": # 0x1d644 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "": # 0xf3a5 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "𝙅": # 0x1d645 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "": # 0xf3a6 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "𝙆": # 0x1d646 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "": # 0xf3a7 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "𝙇": # 0x1d647 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "": # 0xf3a8 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "𝙈": # 0x1d648 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "": # 0xf3a9 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "𝙉": # 0x1d649 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "": # 0xf3aa - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "𝙊": # 0x1d64a - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "": # 0xf3ab - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "𝙋": # 0x1d64b - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "": # 0xf3ac - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "𝙌": # 0x1d64c - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "": # 0xf3ad - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "𝙍": # 0x1d64d - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "": # 0xf3ae - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "𝙎": # 0x1d64e - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "": # 0xf3af - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "𝙏": # 0x1d64f - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "": # 0xf3b0 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "𝙐": # 0x1d650 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "": # 0xf3b1 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "𝙑": # 0x1d651 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "": # 0xf3b2 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "𝙒": # 0x1d652 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "": # 0xf3b3 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "𝙓": # 0x1d653 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "": # 0xf3b4 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "𝙔": # 0x1d654 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "": # 0xf3b5 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "𝙕": # 0x1d655 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "": [T: bold italic a] # 0xf3b6 - - "𝙖": [T: bold italic a] # 0x1d656 - - "": [T: bold italic b] # 0xf3b7 - - "𝙗": [T: bold italic b] # 0x1d657 - - "": [T: bold italic c] # 0xf3b8 - - "𝙘": [T: bold italic c] # 0x1d658 - - "": [T: bold italic d] # 0xf3b9 - - "𝙙": [T: bold italic d] # 0x1d659 - - "": [T: bold italic e] # 0xf3ba - - "𝙚": [T: bold italic e] # 0x1d65a - - "": [T: bold italic f] # 0xf3bb - - "𝙛": [T: bold italic f] # 0x1d65b - - "": [T: bold italic g] # 0xf3bc - - "𝙜": [T: bold italic g] # 0x1d65c - - "": [T: bold italic h] # 0xf3bd - - "𝙝": [T: bold italic h] # 0x1d65d - - "": [T: bold italic i] # 0xf3be - - "𝙞": [T: bold italic i] # 0x1d65e - - "": [T: bold italic j] # 0xf3bf - - "𝙟": [T: bold italic j] # 0x1d65f - - "": [T: bold italic k] # 0xf3c0 - - "𝙠": [T: bold italic k] # 0x1d660 - - "": [T: bold italic l] # 0xf3c1 - - "𝙡": [T: bold italic l] # 0x1d661 - - "": [T: bold italic m] # 0xf3c2 - - "𝙢": [T: bold italic m] # 0x1d662 - - "": [T: bold italic n] # 0xf3c3 - - "𝙣": [T: bold italic n] # 0x1d663 - - "": [T: bold italic o] # 0xf3c4 - - "𝙤": [T: bold italic o] # 0x1d664 - - "": [T: bold italic p] # 0xf3c5 - - "𝙥": [T: bold italic p] # 0x1d665 - - "": [T: bold italic q] # 0xf3c6 - - "𝙦": [T: bold italic q] # 0x1d666 - - "": [T: bold italic r] # 0xf3c7 - - "𝙧": [T: bold italic r] # 0x1d667 - - "": [T: bold italic s] # 0xf3c8 - - "𝙨": [T: bold italic s] # 0x1d668 - - "": [T: bold italic t] # 0xf3c9 - - "𝙩": [T: bold italic t] # 0x1d669 - - "": [T: bold italic u] # 0xf3ca - - "𝙪": [T: bold italic u] # 0x1d66a - - "": [T: bold italic v] # 0xf3cb - - "𝙫": [T: bold italic v] # 0x1d66b - - "": [T: bold italic w] # 0xf3cc - - "𝙬": [T: bold italic w] # 0x1d66c - - "": [T: bold italic x] # 0xf3cd - - "𝙭": [T: bold italic x] # 0x1d66d - - "": [T: bold italic y] # 0xf3ce - - "𝙮": [T: bold italic y] # 0x1d66e - - "": [T: bold italic z] # 0xf3cf - - "𝙯": [T: bold italic z] # 0x1d66f - - "": # 0xf3d0 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "𝙰": # 0x1d670 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: a - - "": # 0xf3d1 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "𝙱": # 0x1d671 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: b - - "": # 0xf3d2 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "𝙲": # 0x1d672 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: c - - "": # 0xf3d3 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "𝙳": # 0x1d673 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: d - - "": # 0xf3d4 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "𝙴": # 0x1d674 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: e - - "": # 0xf3d5 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "𝙵": # 0x1d675 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: f - - "": # 0xf3d6 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "𝙶": # 0x1d676 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: g - - "": # 0xf3d7 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "𝙷": # 0x1d677 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: h - - "": # 0xf3d8 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "𝙸": # 0x1d678 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: i - - "": # 0xf3d9 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "𝙹": # 0x1d679 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: j - - "": # 0xf3da - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "𝙺": # 0x1d67a - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: k - - "": # 0xf3db - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "𝙻": # 0x1d67b - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: l - - "": # 0xf3dc - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "𝙼": # 0x1d67c - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: m - - "": # 0xf3dd - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "𝙽": # 0x1d67d - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: n - - "": # 0xf3de - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "𝙾": # 0x1d67e - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: o - - "": # 0xf3df - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "𝙿": # 0x1d67f - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: p - - "": # 0xf3e0 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "𝚀": # 0x1d680 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: q - - "": # 0xf3e1 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "𝚁": # 0x1d681 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: r - - "": # 0xf3e2 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "𝚂": # 0x1d682 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: s - - "": # 0xf3e3 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "𝚃": # 0x1d683 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: t - - "": # 0xf3e4 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "𝚄": # 0x1d684 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: u - - "": # 0xf3e5 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "𝚅": # 0x1d685 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: v - - "": # 0xf3e6 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "𝚆": # 0x1d686 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: w - - "": # 0xf3e7 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "𝚇": # 0x1d687 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: x - - "": # 0xf3e8 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "𝚈": # 0x1d688 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: y - - "": # 0xf3e9 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "𝚉": # 0x1d689 - - T: "" - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: z - - "": [T: a] # 0xf3ea - - "𝚊": [T: a] # 0x1d68a - - "": [T: b] # 0xf3eb - - "𝚋": [T: b] # 0x1d68b - - "": [T: c] # 0xf3ec - - "𝚌": [T: c] # 0x1d68c - - "": [T: d] # 0xf3ed - - "𝚍": [T: d] # 0x1d68d - - "": [T: e] # 0xf3ee - - "𝚎": [T: e] # 0x1d68e - - "": [T: f] # 0xf3ef - - "𝚏": [T: f] # 0x1d68f - - "": [T: g] # 0xf3f0 - - "𝚐": [T: g] # 0x1d690 - - "": [T: h] # 0xf3f1 - - "𝚑": [T: h] # 0x1d691 - - "": [T: i] # 0xf3f2 - - "𝚒": [T: i] # 0x1d692 - - "": [T: j] # 0xf3f3 - - "𝚓": [T: j] # 0x1d693 - - "": [T: k] # 0xf3f4 - - "𝚔": [T: k] # 0x1d694 - - "": [T: l] # 0xf3f5 - - "𝚕": [T: l] # 0x1d695 - - "": [T: m] # 0xf3f6 - - "𝚖": [T: m] # 0x1d696 - - "": [T: n] # 0xf3f7 - - "𝚗": [T: n] # 0x1d697 - - "": [T: o] # 0xf3f8 - - "𝚘": [T: o] # 0x1d698 - - "": [T: p] # 0xf3f9 - - "𝚙": [T: p] # 0x1d699 - - "": [T: q] # 0xf3fa - - "𝚚": [T: q] # 0x1d69a - - "": [T: r] # 0xf3fb - - "𝚛": [T: r] # 0x1d69b - - "": [T: s] # 0xf3fc - - "𝚜": [T: s] # 0x1d69c - - "": [T: t] # 0xf3fd - - "𝚝": [T: t] # 0x1d69d - - "": [T: u] # 0xf3fe - - "𝚞": [T: u] # 0x1d69e - - "": [T: v] # 0xf3ff - - "𝚟": [T: v] # 0x1d69f - - "": [T: w] # 0xf400 - - "𝚠": [T: w] # 0x1d6a0 - - "": [T: x] # 0xf401 - - "𝚡": [T: x] # 0x1d6a1 - - "": [T: y] # 0xf402 - - "𝚢": [T: y] # 0x1d6a2 - - "": [T: z] # 0xf403 - - "𝚣": [T: z] # 0x1d6a3 - - "": [T: i tanpa titik] # 0xf404 - - "𝚤": [T: i tanpa titik] # 0x1d6a4 - - "𝚥": [T: j tanpa titik] # 0x1d6a5 - - "": # 0xf408 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: alpha - - "𝚨": # 0x1d6a8 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: alpha - - "": # 0xf409 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: beta - - "𝚩": # 0x1d6a9 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: beta - - "": # 0xf40a - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: gamma - - "𝚪": # 0x1d6aa - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: gamma - - "": # 0xf40b - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: delta - - "𝚫": # 0x1d6ab - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: delta - - "": # 0xf40c - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: epsilon - - "𝚬": # 0x1d6ac - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: epsilon - - "": # 0xf40d - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: zeta - - "𝚭": # 0x1d6ad - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: zeta - - "": # 0xf40e - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: eta - - "𝚮": # 0x1d6ae - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: eta - - "": # 0xf40f - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "𝚯": # 0x1d6af - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "": # 0xf410 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: iota - - "𝚰": # 0x1d6b0 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: iota - - "": # 0xf411 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: kappa - - "𝚱": # 0x1d6b1 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: kappa - - "": # 0xf412 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: lamda - - "𝚲": # 0x1d6b2 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: lamda - - "": # 0xf413 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: mu - - "𝚳": # 0x1d6b3 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: mu - - "": # 0xf414 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: nu - - "𝚴": # 0x1d6b4 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: nu - - "": # 0xf415 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: xi - - "𝚵": # 0x1d6b5 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: xi - - "": # 0xf416 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omicron - - "𝚶": # 0x1d6b6 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omicron - - "": # 0xf417 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: pi - - "𝚷": # 0x1d6b7 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: pi - - "": # 0xf418 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: rho - - "𝚸": # 0x1d6b8 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: rho - - "": # 0xf419 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "𝚹": # 0x1d6b9 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "": # 0xf41a - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: sigma - - "𝚺": # 0x1d6ba - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: sigma - - "": # 0xf41b - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: tau - - "𝚻": # 0x1d6bb - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: tau - - "": # 0xf41c - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: upsilon - - "𝚼": # 0x1d6bc - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: upsilon - - "": # 0xf41d - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: phi - - "𝚽": # 0x1d6bd - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: phi - - "": # 0xf41e - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: chi - - "𝚾": # 0x1d6be - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: chi - - "": # 0xf41f - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: psi - - "𝚿": # 0x1d6bf - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: psi - - "": # 0xf420 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omega - - "𝛀": # 0x1d6c0 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omega - - "": [T: bold nabla] # 0xf421 - - "𝛁": [T: bold nabla] # 0x1d6c1 - - "": [T: bold alpha] # 0xf422 - - "𝛂": [T: bold alpha] # 0x1d6c2 - - "": [T: bold beta] # 0xf423 - - "𝛃": [T: bold beta] # 0x1d6c3 - - "": [T: bold gamma] # 0xf424 - - "𝛄": [T: bold gamma] # 0x1d6c4 - - "": [T: bold delta] # 0xf425 - - "𝛅": [T: bold delta] # 0x1d6c5 - - "": [T: bold epsilon] # 0xf426 - - "𝛆": [T: bold epsilon] # 0x1d6c6 - - "": [T: bold zeta] # 0xf427 - - "𝛇": [T: bold zeta] # 0x1d6c7 - - "": [T: bold eta] # 0xf428 - - "𝛈": [T: bold eta] # 0x1d6c8 - - "": [T: bold theta] # 0xf429 - - "𝛉": [T: bold theta] # 0x1d6c9 - - "": [T: bold iota] # 0xf42a - - "𝛊": [T: bold iota] # 0x1d6ca - - "": [T: bold kappa] # 0xf42b - - "𝛋": [T: bold kappa] # 0x1d6cb - - "": [T: bold lamda] # 0xf42c - - "𝛌": [T: bold lamda] # 0x1d6cc - - "": [T: bold mu] # 0xf42d - - "𝛍": [T: bold mu] # 0x1d6cd - - "": [T: bold nu] # 0xf42e - - "𝛎": [T: bold nu] # 0x1d6ce - - "": [T: bold xi] # 0xf42f - - "𝛏": [T: bold xi] # 0x1d6cf - - "": [T: bold omicron] # 0xf430 - - "𝛐": [T: bold omicron] # 0x1d6d0 - - "": [T: bold pi] # 0xf431 - - "𝛑": [T: bold pi] # 0x1d6d1 - - "": [T: bold rho] # 0xf432 - - "𝛒": [T: bold rho] # 0x1d6d2 - - "": [T: bold final sigma] # 0xf433 - - "𝛓": [T: bold final sigma] # 0x1d6d3 - - "": [T: bold sigma] # 0xf434 - - "𝛔": [T: bold sigma] # 0x1d6d4 - - "": [T: bold tau] # 0xf435 - - "𝛕": [T: bold tau] # 0x1d6d5 - - "": [T: bold upsilon] # 0xf436 - - "𝛖": [T: bold upsilon] # 0x1d6d6 - - "": [T: bold phi] # 0xf437 - - "𝛗": [T: bold phi] # 0x1d6d7 - - "": [T: bold chi] # 0xf438 - - "𝛘": [T: bold chi] # 0x1d6d8 - - "": [T: bold psi] # 0xf439 - - "𝛙": [T: bold psi] # 0x1d6d9 - - "": [T: bold omega] # 0xf43a - - "𝛚": [T: bold omega] # 0x1d6da - - "": [T: bold diferensial parsial] # 0xf43b - - "𝛛": [T: bold diferensial parsial] # 0x1d6db - - "": [T: bold epsilon] # 0xf43c - - "𝛜": [T: bold epsilon] # 0x1d6dc - - "": [T: bold theta] # 0xf43d - - "𝛝": [T: bold theta] # 0x1d6dd - - "": [T: bold kappa] # 0xf43e - - "𝛞": [T: bold kappa] # 0x1d6de - - "": [T: bold phi] # 0xf43f - - "𝛟": [T: bold phi] # 0x1d6df - - "": [T: bold rho] # 0xf440 - - "𝛠": [T: bold rho] # 0x1d6e0 - - "": [T: bold pi] # 0xf441 - - "𝛡": [T: bold pi] # 0x1d6e1 - - "": # 0xf442 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: alpha - - "𝛢": # 0x1d6e2 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: alpha - - "": # 0xf443 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: beta - - "𝛣": # 0x1d6e3 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: beta - - "": # 0xf444 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: gamma - - "𝛤": # 0x1d6e4 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: gamma - - "": # 0xf445 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: delta - - "𝛥": # 0x1d6e5 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: delta - - "": # 0xf446 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: epsilon - - "𝛦": # 0x1d6e6 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: epsilon - - "": # 0xf447 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: zeta - - "𝛧": # 0x1d6e7 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: zeta - - "": # 0xf448 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: eta - - "𝛨": # 0x1d6e8 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: eta - - "": # 0xf449 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "𝛩": # 0x1d6e9 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "": # 0xf44a - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: iota - - "𝛪": # 0x1d6ea - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: iota - - "": # 0xf44b - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: kappa - - "𝛫": # 0x1d6eb - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: kappa - - "": # 0xf44c - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: lamda - - "𝛬": # 0x1d6ec - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: lamda - - "": # 0xf44d - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: mu - - "𝛭": # 0x1d6ed - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: mu - - "": # 0xf44e - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: nu - - "𝛮": # 0x1d6ee - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: nu - - "": # 0xf44f - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: xi - - "𝛯": # 0x1d6ef - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: xi - - "": # 0xf450 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omicron - - "𝛰": # 0x1d6f0 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omicron - - "": # 0xf451 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: pi - - "𝛱": # 0x1d6f1 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: pi - - "": # 0xf452 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: rho - - "𝛲": # 0x1d6f2 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: rho - - "": # 0xf453 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "𝛳": # 0x1d6f3 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "": # 0xf454 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: sigma - - "𝛴": # 0x1d6f4 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: sigma - - "": # 0xf455 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: tau - - "𝛵": # 0x1d6f5 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: tau - - "": # 0xf456 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: upsilon - - "𝛶": # 0x1d6f6 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: upsilon - - "": # 0xf457 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: phi - - "𝛷": # 0x1d6f7 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: phi - - "": # 0xf458 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: chi - - "𝛸": # 0x1d6f8 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: chi - - "": # 0xf459 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: psi - - "𝛹": # 0x1d6f9 - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: psi - - "": # 0xf45a - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omega - - "𝛺": # 0x1d6fa - - T: italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omega - - "": [T: bold nabla] # 0xf45b - - "𝛻": [T: bold nabla] # 0x1d6fb - - "": [T: italic alpha] # 0xf45c - - "𝛼": [T: italic alpha] # 0x1d6fc - - "": [T: italic beta] # 0xf45d - - "𝛽": [T: italic beta] # 0x1d6fd - - "": [T: italic gamma] # 0xf45e - - "𝛾": [T: italic gamma] # 0x1d6fe - - "": [T: italic delta] # 0xf45f - - "𝛿": [T: italic delta] # 0x1d6ff - - "": [T: italic epsilon] # 0xf460 - - "𝜀": [T: italic epsilon] # 0x1d700 - - "": [T: italic zeta] # 0xf461 - - "𝜁": [T: italic zeta] # 0x1d701 - - "": [T: italic eta] # 0xf462 - - "𝜂": [T: italic eta] # 0x1d702 - - "": [T: italic theta] # 0xf463 - - "𝜃": [T: italic theta] # 0x1d703 - - "": [T: italic iota] # 0xf464 - - "𝜄": [T: italic iota] # 0x1d704 - - "": [T: italic kappa] # 0xf465 - - "𝜅": [T: italic kappa] # 0x1d705 - - "": [T: italic lamda] # 0xf466 - - "𝜆": [T: italic lamda] # 0x1d706 - - "": [T: italic mu] # 0xf467 - - "𝜇": [T: italic mu] # 0x1d707 - - "": [T: italic nu] # 0xf468 - - "𝜈": [T: italic nu] # 0x1d708 - - "": [T: italic xi] # 0xf469 - - "𝜉": [T: italic xi] # 0x1d709 - - "": [T: italic omicron] # 0xf46a - - "𝜊": [T: italic omicron] # 0x1d70a - - "": [T: italic pi] # 0xf46b - - "𝜋": [T: italic pi] # 0x1d70b - - "": [T: italic rho] # 0xf46c - - "𝜌": [T: italic rho] # 0x1d70c - - "": [T: italic final sigma] # 0xf46d - - "𝜍": [T: italic final sigma] # 0x1d70d - - "": [T: italic sigma] # 0xf46e - - "𝜎": [T: italic sigma] # 0x1d70e - - "": [T: italic tau] # 0xf46f - - "𝜏": [T: italic tau] # 0x1d70f - - "": [T: italic upsilon] # 0xf470 - - "𝜐": [T: italic upsilon] # 0x1d710 - - "": [T: italic phi] # 0xf471 - - "𝜑": [T: italic phi] # 0x1d711 - - "": [T: italic chi] # 0xf472 - - "𝜒": [T: italic chi] # 0x1d712 - - "": [T: italic psi] # 0xf473 - - "𝜓": [T: italic psi] # 0x1d713 - - "": [T: italic omega] # 0xf474 - - "𝜔": [T: italic omega] # 0x1d714 - - "": [T: bold diferensial parsial] # 0xf475 - - "𝜕": [T: bold diferensial parsial] # 0x1d715 - - "": [T: italic epsilon] # 0xf476 - - "𝜖": [T: italic epsilon] # 0x1d716 - - "": [T: italic theta] # 0xf477 - - "𝜗": [T: italic theta] # 0x1d717 - - "": [T: italic kappa] # 0xf478 - - "𝜘": [T: italic kappa] # 0x1d718 - - "": [T: italic phi] # 0xf479 - - "𝜙": [T: italic phi] # 0x1d719 - - "": [T: italic rho] # 0xf47a - - "𝜚": [T: italic rho] # 0x1d71a - - "": [T: italic pi] # 0xf47b - - "𝜛": [T: italic pi] # 0x1d71b - - "": # 0xf47c - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: alpha - - "𝜜": # 0x1d71c - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: alpha - - "": # 0xf47d - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: beta - - "𝜝": # 0x1d71d - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: beta - - "": # 0xf47e - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: gamma - - "𝜞": # 0x1d71e - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: gamma - - "": # 0xf47f - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: delta - - "𝜟": # 0x1d71f - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: delta - - "": # 0xf480 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: epsilon - - "𝜠": # 0x1d720 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: epsilon - - "": # 0xf481 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: zeta - - "𝜡": # 0x1d721 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: zeta - - "": # 0xf482 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: eta - - "𝜢": # 0x1d722 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: eta - - "": # 0xf483 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "𝜣": # 0x1d723 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "": # 0xf484 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: iota - - "𝜤": # 0x1d724 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: iota - - "": # 0xf485 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: kappa - - "𝜥": # 0x1d725 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: kappa - - "": # 0xf486 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: lamda - - "𝜦": # 0x1d726 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: lamda - - "": # 0xf487 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: mu - - "𝜧": # 0x1d727 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: mu - - "": # 0xf488 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: nu - - "𝜨": # 0x1d728 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: nu - - "": # 0xf489 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: xi - - "𝜩": # 0x1d729 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: xi - - "": # 0xf48a - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omicron - - "𝜪": # 0x1d72a - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omicron - - "": # 0xf48b - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: pi - - "𝜫": # 0x1d72b - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: pi - - "": # 0xf48c - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: rho - - "𝜬": # 0x1d72c - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: rho - - "": # 0xf48d - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "𝜭": # 0x1d72d - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "": # 0xf48e - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: sigma - - "𝜮": # 0x1d72e - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: sigma - - "": # 0xf48f - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: tau - - "𝜯": # 0x1d72f - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: tau - - "": # 0xf490 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: upsilon - - "𝜰": # 0x1d730 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: upsilon - - "": # 0xf491 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: phi - - "𝜱": # 0x1d731 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: phi - - "": # 0xf492 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: chi - - "𝜲": # 0x1d732 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: chi - - "": # 0xf493 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: psi - - "𝜳": # 0x1d733 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: psi - - "": # 0xf494 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omega - - "𝜴": # 0x1d734 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omega - - "": [T: bold nabla] # 0xf495 - - "𝜵": [T: bold nabla] # 0x1d735 - - "": [T: bold italic nabla] # 0xf495 - - "𝜶": [T: bold italic alpha] # 0x1d736 - - "": [T: bold italic beta] # 0xf497 - - "𝜷": [T: bold italic beta] # 0x1d737 - - "": [T: bold italic gamma] # 0xf498 - - "𝜸": [T: bold italic gamma] # 0x1d738 - - "": [T: bold italic delta] # 0xf499 - - "𝜹": [T: bold italic delta] # 0x1d739 - - "": [T: bold italic epsilon] # 0xf49a - - "𝜺": [T: bold italic epsilon] # 0x1d73a - - "": [T: bold italic zeta] # 0xf49b - - "𝜻": [T: bold italic zeta] # 0x1d73b - - "": [T: bold italic eta] # 0xf49c - - "𝜼": [T: bold italic eta] # 0x1d73c - - "": [T: bold italic theta] # 0xf49d - - "𝜽": [T: bold italic theta] # 0x1d73d - - "": [T: bold italic iota] # 0xf49e - - "𝜾": [T: bold italic iota] # 0x1d73e - - "": [T: bold italic kappa] # 0xf49f - - "𝜿": [T: bold italic kappa] # 0x1d73f - - "": [T: bold italic lamda] # 0xf4a0 - - "𝝀": [T: bold italic lamda] # 0x1d740 - - "": [T: bold italic mu] # 0xf4a1 - - "𝝁": [T: bold italic mu] # 0x1d741 - - "": [T: bold italic nu] # 0xf4a2 - - "𝝂": [T: bold italic nu] # 0x1d742 - - "": [T: bold italic xi] # 0xf4a3 - - "𝝃": [T: bold italic xi] # 0x1d743 - - "": [T: bold italic omicron] # 0xf4a4 - - "𝝄": [T: bold italic omicron] # 0x1d744 - - "": [T: bold italic pi] # 0xf4a5 - - "𝝅": [T: bold italic pi] # 0x1d745 - - "": [T: bold italic rho] # 0xf4a6 - - "𝝆": [T: bold italic rho] # 0x1d746 - - "": [T: bold italic final sigma] # 0xf4a7 - - "𝝇": [T: bold italic final sigma] # 0x1d747 - - "": [T: bold italic sigma] # 0xf4a8 - - "𝝈": [T: bold italic sigma] # 0x1d748 - - "": [T: bold italic tau] # 0xf4a9 - - "𝝉": [T: bold italic tau] # 0x1d749 - - "": [T: bold italic upsilon] # 0xf4aa - - "𝝊": [T: bold italic upsilon] # 0x1d74a - - "": [T: bold italic phi] # 0xf4ab - - "𝝋": [T: bold italic phi] # 0x1d74b - - "": [T: bold italic chi] # 0xf4ac - - "𝝌": [T: bold italic chi] # 0x1d74c - - "": [T: bold italic psi] # 0xf4ad - - "𝝍": [T: bold italic psi] # 0x1d74d - - "": [T: bold italic omega] # 0xf4ae - - "𝝎": [T: bold italic omega] # 0x1d74e - - "": [T: bold diferensial parsial] # 0xf4af - - "𝝏": [T: bold diferensial parsial] # 0x1d74f - - "": [T: bold italic epsilon] # 0xf4b0 - - "𝝐": [T: bold italic epsilon] # 0x1d750 - - "": [T: bold italic theta] # 0xf4b1 - - "𝝑": [T: bold italic theta] # 0x1d751 - - "": [T: bold italic kappa] # 0xf4b2 - - "𝝒": [T: bold italic kappa] # 0x1d752 - - "": [T: bold italic phi] # 0xf4b3 - - "𝝓": [T: bold italic phi] # 0x1d753 - - "": [T: bold italic rho] # 0xf4b4 - - "𝝔": [T: bold italic rho] # 0x1d754 - - "": [T: bold italic pi] # 0xf4b5 - - "𝝕": [T: bold italic pi] # 0x1d755 - - "": # 0xf4b6 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: alpha - - "𝝖": # 0x1d756 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: alpha - - "": # 0xf4b7 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: beta - - "𝝗": # 0x1d757 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: beta - - "": # 0xf4b8 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: gamma - - "𝝘": # 0x1d758 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: gamma - - "": # 0xf4b9 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: delta - - "𝝙": # 0x1d759 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: delta - - "": # 0xf4ba - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: epsilon - - "𝝚": # 0x1d75a - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: epsilon - - "": # 0xf4bb - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: zeta - - "𝝛": # 0x1d75b - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: zeta - - "": # 0xf4bc - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: eta - - "𝝜": # 0x1d75c - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: eta - - "": # 0xf4bd - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "𝝝": # 0x1d75d - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "": # 0xf4be - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: iota - - "𝝞": # 0x1d75e - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: iota - - "": # 0xf4bf - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: kappa - - "𝝟": # 0x1d75f - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: kappa - - "": # 0xf4c0 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: lamda - - "𝝠": # 0x1d760 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: lamda - - "": # 0xf4c1 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: mu - - "𝝡": # 0x1d761 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: mu - - "": # 0xf4c2 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: nu - - "𝝢": # 0x1d762 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: nu - - "": # 0xf4c3 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: xi - - "𝝣": # 0x1d763 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: xi - - "": # 0xf4c4 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omicron - - "𝝤": # 0x1d764 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omicron - - "": # 0xf4c5 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: pi - - "𝝥": # 0x1d765 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: pi - - "": # 0xf4c6 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: rho - - "𝝦": # 0x1d766 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: rho - - "": # 0xf4c7 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "𝝧": # 0x1d767 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "": # 0xf4c8 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: sigma - - "𝝨": # 0x1d768 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: sigma - - "": # 0xf4c9 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: tau - - "𝝩": # 0x1d769 - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: tau - - "": # 0xf4ca - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: upsilon - - "𝝪": # 0x1d76a - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: upsilon - - "": # 0xf4cb - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: phi - - "𝝫": # 0x1d76b - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: phi - - "": # 0xf4cc - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: chi - - "𝝬": # 0x1d76c - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: chi - - "": # 0xf4cd - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: psi - - "𝝭": # 0x1d76d - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: psi - - "": # 0xf4ce - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omega - - "𝝮": # 0x1d76e - - T: bold - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omega - - "": [T: bold nabla] # 0xf4cf - - "𝝯": [T: bold nabla] # 0x1d76f - - "": [T: bold alpha] # 0xf4d0 - - "𝝰": [T: bold alpha] # 0x1d770 - - "": [T: bold beta] # 0xf4d1 - - "𝝱": [T: bold beta] # 0x1d771 - - "": [T: bold gamma] # 0xf4d2 - - "𝝲": [T: bold gamma] # 0x1d772 - - "": [T: bold delta] # 0xf4d3 - - "𝝳": [T: bold delta] # 0x1d773 - - "": [T: bold epsilon] # 0xf4d4 - - "𝝴": [T: bold epsilon] # 0x1d774 - - "": [T: bold zeta] # 0xf4d5 - - "𝝵": [T: bold zeta] # 0x1d775 - - "": [T: bold eta] # 0xf4d6 - - "𝝶": [T: bold eta] # 0x1d776 - - "": [T: bold theta] # 0xf4d7 - - "𝝷": [T: bold theta] # 0x1d777 - - "": [T: bold iota] # 0xf4d8 - - "𝝸": [T: bold iota] # 0x1d778 - - "": [T: bold kappa] # 0xf4d9 - - "𝝹": [T: bold kappa] # 0x1d779 - - "": [T: bold lamda] # 0xf4da - - "𝝺": [T: bold lamda] # 0x1d77a - - "": [T: bold mu] # 0xf4db - - "𝝻": [T: bold mu] # 0x1d77b - - "": [T: bold nu] # 0xf4dc - - "𝝼": [T: bold nu] # 0x1d77c - - "": [T: bold xi] # 0xf4dd - - "𝝽": [T: bold xi] # 0x1d77d - - "": [T: bold omicron] # 0xf4de - - "𝝾": [T: bold omicron] # 0x1d77e - - "": [T: bold pi] # 0xf4df - - "𝝿": [T: bold pi] # 0x1d77f - - "": [T: bold rho] # 0xf4e0 - - "𝞀": [T: bold rho] # 0x1d780 - - "": [T: bold final sigma] # 0xf4e1 - - "𝞁": [T: bold final sigma] # 0x1d781 - - "": [T: bold sigma] # 0xf4e2 - - "𝞂": [T: bold sigma] # 0x1d782 - - "": [T: bold tau] # 0xf4e3 - - "𝞃": [T: bold tau] # 0x1d783 - - "": [T: bold upsilon] # 0xf4e4 - - "𝞄": [T: bold upsilon] # 0x1d784 - - "": [T: bold phi] # 0xf4e5 - - "𝞅": [T: bold phi] # 0x1d785 - - "": [T: bold chi] # 0xf4e6 - - "𝞆": [T: bold chi] # 0x1d786 - - "": [T: bold psi] # 0xf4e7 - - "𝞇": [T: bold psi] # 0x1d787 - - "": [T: bold omega] # 0xf4e8 - - "𝞈": [T: bold omega] # 0x1d788 - - "": [T: bold diferensial parsial] # 0xf4e9 - - "𝞉": [T: bold diferensial parsial] # 0x1d789 - - "": [T: bold epsilon] # 0xf4ea - - "𝞊": [T: bold epsilon] # 0x1d78a - - "": [T: bold theta] # 0xf4eb - - "𝞋": [T: bold theta] # 0x1d78b - - "": [T: bold kappa] # 0xf4ec - - "𝞌": [T: bold kappa] # 0x1d78c - - "": [T: bold phi] # 0xf4ed - - "𝞍": [T: bold phi] # 0x1d78d - - "": [T: bold rho] # 0xf4ee - - "𝞎": [T: bold rho] # 0x1d78e - - "": [T: bold pi] # 0xf4ef - - "𝞏": [T: bold pi] # 0x1d78f - - "": # 0xf4f0 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: alpha - - "𝞐": # 0x1d790 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: alpha - - "": # 0xf4f1 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: beta - - "𝞑": # 0x1d791 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: beta - - "": # 0xf4f2 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: gamma - - "𝞒": # 0x1d792 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: gamma - - "": # 0xf4f3 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: delta - - "𝞓": # 0x1d793 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: delta - - "": # 0xf4f4 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: epsilon - - "𝞔": # 0x1d794 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: epsilon - - "": # 0xf4f5 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: zeta - - "𝞕": # 0x1d795 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: zeta - - "": # 0xf4f6 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: eta - - "𝞖": # 0x1d796 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: eta - - "": # 0xf4f7 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "𝞗": # 0x1d797 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "": # 0xf4f8 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: iota - - "𝞘": # 0x1d798 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: iota - - "": # 0xf4f9 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: kappa - - "𝞙": # 0x1d799 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: kappa - - "": # 0xf4fa - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: lamda - - "𝞚": # 0x1d79a - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: lamda - - "": # 0xf4fb - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: mu - - "𝞛": # 0x1d79b - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: mu - - "": # 0xf4fc - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: nu - - "𝞜": # 0x1d79c - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: nu - - "": # 0xf4fd - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: xi - - "𝞝": # 0x1d79d - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: xi - - "": # 0xf4fe - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omicron - - "𝞞": # 0x1d79e - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omicron - - "": # 0xf4ff - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: pi - - "𝞟": # 0x1d79f - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: pi - - "": # 0xf500 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: rho - - "𝞠": # 0x1d7a0 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: rho - - "": # 0xf501 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "𝞡": # 0x1d7a1 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: theta - - "": # 0xf502 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: sigma - - "𝞢": # 0x1d7a2 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: sigma - - "": # 0xf503 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: tau - - "𝞣": # 0x1d7a3 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: tau - - "": # 0xf504 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: upsilon - - "𝞤": # 0x1d7a4 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: upsilon - - "": # 0xf505 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: phi - - "𝞥": # 0x1d7a5 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: phi - - "": # 0xf506 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: chi - - "𝞦": # 0x1d7a6 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: chi - - "": # 0xf507 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: psi - - "𝞧": # 0x1d7a7 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: psi - - "": # 0xf508 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omega - - "𝞨": # 0x1d7a8 - - T: bold italic - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: huruf besar] - - T: omega - - "": [T: bold nabla] # 0xf509 - - "𝞩": [T: bold nabla] # 0x1d7a9 - - "": [T: bold italic alpha] # 0xf50a - - "𝞪": [T: bold italic alpha] # 0x1d7aa - - "": [T: bold italic beta] # 0xf50b - - "𝞫": [T: bold italic beta] # 0x1d7ab - - "": [T: bold italic gamma] # 0xf50c - - "𝞬": [T: bold italic gamma] # 0x1d7ac - - "": [T: bold italic delta] # 0xf50d - - "𝞭": [T: bold italic delta] # 0x1d7ad - - "": [T: bold italic epsilon] # 0xf50e - - "𝞮": [T: bold italic epsilon] # 0x1d7ae - - "": [T: bold italic zeta] # 0xf50f - - "𝞯": [T: bold italic zeta] # 0x1d7af - - "": [T: bold italic eta] # 0xf510 - - "𝞰": [T: bold italic eta] # 0x1d7b0 - - "": [T: bold italic theta] # 0xf511 - - "𝞱": [T: bold italic theta] # 0x1d7b1 - - "": [T: bold italic iota] # 0xf512 - - "𝞲": [T: bold italic iota] # 0x1d7b2 - - "": [T: bold italic kappa] # 0xf513 - - "𝞳": [T: bold italic kappa] # 0x1d7b3 - - "": [T: bold italic lamda] # 0xf514 - - "𝞴": [T: bold italic lamda] # 0x1d7b4 - - "": [T: bold italic mu] # 0xf515 - - "𝞵": [T: bold italic mu] # 0x1d7b5 - - "": [T: bold italic nu] # 0xf516 - - "𝞶": [T: bold italic nu] # 0x1d7b6 - - "": [T: bold italic xi] # 0xf517 - - "𝞷": [T: bold italic xi] # 0x1d7b7 - - "": [T: bold italic omicron] # 0xf518 - - "𝞸": [T: bold italic omicron] # 0x1d7b8 - - "": [T: bold italic pi] # 0xf519 - - "𝞹": [T: bold italic pi] # 0x1d7b9 - - "": [T: bold italic rho] # 0xf51a - - "𝞺": [T: bold italic rho] # 0x1d7ba - - "": [T: bold italic final sigma] # 0xf51b - - "𝞻": [T: bold italic final sigma] # 0x1d7bb - - "": [T: bold italic sigma] # 0xf51c - - "𝞼": [T: bold italic sigma] # 0x1d7bc - - "": [T: bold italic tau] # 0xf51d - - "𝞽": [T: bold italic tau] # 0x1d7bd - - "": [T: bold italic upsilon] # 0xf51e - - "𝞾": [T: bold italic upsilon] # 0x1d7be - - "": [T: bold italic phi] # 0xf51f - - "𝞿": [T: bold italic phi] # 0x1d7bf - - "": [T: bold italic chi] # 0xf520 + +# fraktur chars in math alphabetic block and also MathType private use area + # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display + - "𝔄-𝔜": # 0x1d504 - 0x1d51d ('z' version is reserved) + - T: "fraktur" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'abcdefghijklmnopqrstuvwxy')" + + - "-": # 0xf000 - 0xf018 + - T: "fraktur" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxy')" + + - "𝔞-𝔷": # 0x1d51e - 0x1d537 + - T: "fraktur" + - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf01a - 0xf033 + - T: "fraktur" + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝕬-𝖅": # 0x1D56C - 0x1D585 + - T: "fraktur" + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf040 - 0xf059 + - T: "fraktur" + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝖆-𝖟": # 0x1d586 - 0x1d59f + - T: "fraktur" + - T: "bold" + - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf05a - 0xf073 + - T: "fraktur" + - T: "bold" + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + # double struck (blackboard bold) chars in math alphabetic block and also MathType private use area + # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display + - "𝔸-𝕐": # 0x1d504 - 0x1d51d ('z' version is reserved) + - T: "struck ganda" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '𝔸𝔹𝔺𝔻𝔼𝔽𝔾𝔿𝕀𝕁𝕂𝕃𝕄𝕅𝕆𝕇𝕈𝕉𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf080 - 0xf098 + - T: "struck ganda" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝕒-𝕫": # 0x1d552 - 0x1d56b + - T: "struck ganda" + - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf09a - 0xf0b3 + - T: "struck ganda" + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 + - T: "aksara" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf100 - 0xf119 + - T: "aksara" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf + - T: "aksara" + - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf11a - 0xf133 + - T: "aksara" + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + # bold script chars in math alphabetic block and also MathType private use area + - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 + - T: "aksara" + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf140 - 0xf159 + - T: "aksara" + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝓪-𝔃": # 0x1d4ea - 0x1d503 + - T: "aksara" + - T: "bold" + - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf15a - 0xf173 + - T: "aksara" + - T: "bold" + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf180 - 0xf199 + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "": # 0xf19a + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "cap"] + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "ligature ae"] + - "": # 0xf19b + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "cap"] + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "sharp s"] + - "": # 0xf19c + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "cap"] + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "o with stroke"] + + # MathType only has a few of the cap Greek letters in PUA + - "": # 0xf201 - 0xf209 + - T: "struck ganda" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'δψλπσθγωυ')" + + - "-": # 0xf220 - 0xf236 + - T: "struck ganda" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρ΢στυφχψω')" + + - "": [T: "struck ganda final sigma"] # 0xf237 + - "": [T: "struck ganda rho"] # 0xf250 + - "": [T: "struck ganda phi"] # 0xf251 + - "𝐀-𝐙": # 0x1d400 - 0x1d419 + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf260 - 0xf279 + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝐚-𝐳": # 0x1d41a - 0x1d433 + - T: "bold" + - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf27a - 0xf293 + - T: "bold" + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝐴-𝑍": # 0x1d434 - 0x1d44d + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf294 - 0xf2ad + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝑎-𝑧": # 0x1d44e - 0x1d467 + - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf2ae - 0xf2c7 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝑨-𝒁": # 0x1d468 - 0x1d481 + # - T: "bold italic" + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf2c8 - 0xf2e1 + # - T: "bold italic" + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝒂-𝒛": # 0x1d482 - 0x1d49b + # - T: "bold italic" + - T: "bold" + - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf2e2 - 0xf2fb + # - T: "bold italic" + - T: "bold" + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf300 - 0xf319 + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 + - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf31a - 0xf333 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf334 - 0xf34d + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝗮-𝘇": # 0x1d5ee - 0x1d607 + - T: "bold" + - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf34e - 0xf367 + - T: "bold" + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝘈-𝘡": # 0x1d608 - 0x1d621 + # - T: "italic" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf368 - 0xf381 + # - T: "italic" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝘢-𝘻": # 0x1d622 - 0x1d63b + # - T: "italic" + - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf382 - 0xf39b + # - T: "italic" + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝘼-𝙕": # 0x1d63c - 0x1d655 + # - T: "bold italic" + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf39c - 0xf3b5 + # - T: "bold italic" + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝙖-𝙯": # 0x1d656 - 0x1d66f + # - T: "bold italic" + - T: "bold" + - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf3b6 - 0xf3cf + # - T: "bold italic" + - T: "bold" + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝙰-𝚉": # 0x1d670 - 0x1d689 + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf3d0 - 0xf3e9 + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 + - spell: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf3ea - 0xf403 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "": [T: "dotless i"] # 0xf404 + - "𝚤": [T: "dotless i"] # 0x1d6a4 + - "𝚥": [T: "dotless j"] # 0x1d6a5 + + - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'αβγδεζηθικλμνξοπρ΢στυφχψω')" + + - "-": # 0xf408 - 0xf420 + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρ΢στυφχψω')" + + - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da + - T: "bold" + - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf422 - 0xf43a + - T: "bold" + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "": [T: "bold nabla"] # 0xf421 + - "𝛁": [T: "bold nabla"] # 0x1d6c1 + + - "𝛛𝛜𝛝𝛞𝛟𝛠𝛡": # 0x1D6DB - 0x1D6E1 + - T: "bold" + - spell: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" + + - "": # 0xF43C - 0xF441 + - T: "bold" + - spell: "translate('.', '', '∂εθκφρπ')" + + - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa + # - T: "italic" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'αβγδεζηθικλμνξοπρ΢στυφχψω')" + + - "-": # 0xf442 - 0xf45a + # - T: "italic" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρ΢στυφχψω')" + + - "𝛼-𝜔": # 0x1d6fc - 0x1d714 + # - T: "italic" + - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓𝜔', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf45c - 0xf474 + # - T: "italic" + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "": [T: "italic nabla"] # 0xf45b + - "𝛻": [T: "italic nabla"] # 0x1d6fb + + - "𝜕𝜖𝜗𝜘𝜙𝜚𝜛": # 0x1d715 - 0x1d71b + # - T: "italic" + - spell: "translate('.', '𝜕𝜖𝜗𝜘𝜙𝜚𝜛', '∂εθκφρπ')" + + - "": # 0xf475 - 0xf47b + # - T: "italic" + - spell: "translate('.', '', '∂εθκφρπ')" + + - "𝜜-𝜴": # 0x1d71c - 0x1d734 + # - T: "bold italic" + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'αβγδεζηθικλμνξοπρ΢στυφχψω')" + + - "-": # 0xf47c - 0xf494 + # - T: "bold italic" + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρ΢στυφχψω')" + + - "𝜶-𝝎": # 0x1d736 - 0x1d74e + # - T: "bold italic" + - T: "bold" + - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf496 - 0xf4ae + # - T: "bold italic" + - T: "bold" + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": # 0x1d74f - 0x1d755 + # - T: "bold italic" + - T: "bold" + - spell: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εθκφρπ')" + + - "": # 0xf422 - 0xf43a + # - T: "bold italic" + - T: "bold" + - spell: "translate('.', '', '∂εθκφρπ')" + + - "𝜵": [T: "bold italic nabla"] # 0x1d735 + - "": [T: "bold italic nabla"] # 0xf495 + + - "𝝖-𝝮": # 0x1d756 - 0x1d76e + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'αβγδεζηθικλμνξοπρ΢στυφχψω')" + - "-": # 0xf4b6 - 0xf4ce + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρ΢στυφχψω')" + + - "𝝰-𝞈": # 0x1d770 - 0x1d788 + - T: "bold" + - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇𝞈', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf4d0 - 0xf4e8 + - T: "bold" + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝞉𝞊𝞋𝞌𝞍𝞎𝞏": # 0x1d789 - 0x1d78f + - T: "bold" + - spell: "translate('.', '𝞉𝞊𝞋𝞌𝞍𝞎𝞏', '∂εθκφρπ')" + + - "": # 0xf4e9 - 0xf4ef + - T: "bold" + - spell: "translate('.', '', '∂εθκφρπ')" + + - "": [T: "bold nabla"] # 0xf4cf + - "𝝯": [T: "bold nabla"] # 0x1d76f + + - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 + # - T: "bold italic" + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'αβγδεζηθικλμνξοπρ΢στυφχψω')" + + - "-": # 0xf4f0 - 0xf508 + # - T: "bold italic" + - T: "bold" + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: huruf besar] + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρ΢στυφχψω')" + + - "𝞪-𝟂": # 0x1d7aa - 0x1d7c2 + # - T: "bold italic" + - T: "bold" + - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf50a - 0xf522 + # - T: "bold italic" + - T: "bold" + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": # 0x1d7c3 - 0x1d7c9 + # - T: "bold italic" + - T: "bold" + - spell: "translate('.', '𝟃𝟄𝟅𝟆𝟇𝟈𝟉', '∂εθκφρπ')" + + - "": # 0xf523 - 0xf529 + # - T: "bold italic" + - T: "bold" + - spell: "translate('.', '', '∂εθκφρπ')" + + - "": [T: "bold nabla"] # 0xf509 + - "𝞩": [T: "bold nabla"] # 0x1d7a9 + + - "": [T: struck ganda nol] # 0xf0c0 + - "𝟘": [T: struck ganda nol] # 0x1d7d8 + - "": [T: struck ganda satu] # 0xf0c1 + - "𝟙": [T: struck ganda satu] # 0x1d7d9 + - "": [T: struck ganda dua] # 0xf0c2 + - "𝟚": [T: struck ganda dua] # 0x1d7da + - "": [T: struck ganda tiga] # 0xf0c3 + - "𝟛": [T: struck ganda tiga] # 0x1d7db + - "": [T: struck ganda empat] # 0xf0c4 + - "𝟜": [T: struck ganda empat] # 0x1d7dc + - "": [T: struck ganda lima] # 0xf0c5 + - "𝟝": [T: struck ganda lima] # 0x1d7dd + - "": [T: struck ganda enam] # 0xf0c6 + - "𝟞": [T: struck ganda enam] # 0x1d7de + - "": [T: struck ganda tujuh] # 0xf0c7 + - "𝟟": [T: struck ganda tujuh] # 0x1d7df + - "": [T: struck ganda delapan] # 0xf0c8 + - "𝟠": [T: struck ganda delapan] # 0x1d7e0 + - "": [T: struck ganda sembilan] # 0xf0c9 + - "𝟡": [T: struck ganda sembilan] # 0x1d7e1 + - "": [T: struck ganda nabla] # 0xf0ca + - "": [T: struck ganda konstanta euler] # 0xf0cb - "𝟀": [T: bold italic chi] # 0x1d7c0 - - "": [T: bold italic psi] # 0xf521 - "𝟁": [T: bold italic psi] # 0x1d7c1 - - "": [T: bold italic omega] # 0xf522 - "𝟂": [T: bold italic omega] # 0x1d7c2 - - "": [T: bold diferensial parsial] # 0xf523 - "𝟃": [T: bold diferensial parsial] # 0x1d7c3 - - "": [T: bold italic epsilon] # 0xf524 - "𝟄": [T: bold italic epsilon] # 0x1d7c4 - - "": [T: bold italic theta] # 0xf525 - "𝟅": [T: bold italic theta] # 0x1d7c5 - - "": [T: bold italic kappa] # 0xf526 - "𝟆": [T: bold italic kappa] # 0x1d7c6 - - "": [T: bold italic phi] # 0xf527 - "𝟇": [T: bold italic phi] # 0x1d7c7 - - "": [T: bold italic rho] # 0xf528 - "𝟈": [T: bold italic rho] # 0x1d7c8 - - "": [T: bold italic pi] # 0xf529 - "𝟉": [T: bold italic pi] # 0x1d7c9 - "": [T: bold nol] # 0xf52e - "𝟎": [T: bold nol] # 0x1d7ce @@ -10390,6 +4505,7 @@ - "𝟾": [T: delapan] # 0x1d7fe - "": [T: sembilan] # 0xf55f - "𝟿": [T: sembilan] # 0x1d7ff + - "": [T: karakter tidak dikenal] # 0xf700 - "": [T: segitiga kanan bawah dan kiri bawah] # 0xf726 - "": [T: pemanjang ellipsis horizontal] # 0xf72d diff --git a/src/braille.rs b/src/braille.rs index 1ced5bc8b..929bcf791 100644 --- a/src/braille.rs +++ b/src/braille.rs @@ -645,7 +645,7 @@ fn nemeth_cleanup(_pref_manager: Ref, raw_braille: String) -> "B" => "⠸", // bold "𝔹" => "⠠⠸", // blackboard "T" => "⠈", // script - "I" => "⠨", // italic (mapped to be the same a blackboard) + "I" => "⠨", // italic -- used for digits (not math letters) "R" => "", // roman "E" => "⠰", // English "D" => "⠸", // German (Deutsche) @@ -889,7 +889,7 @@ static UEB_INDICATOR_REPLACEMENTS: phf::Map<&str, &str> = phf_map! { "B" => "⠘", // bold "𝔹" => "XXX", // blackboard -- from prefs "T" => "⠈", // script - "I" => "⠨", // italic + "I" => "⠨", // italic -- used for digits (not math letters) "R" => "", // roman // "E" => "⠰", // English "1" => "⠰", // Grade 1 symbol @@ -2047,8 +2047,6 @@ static VIETNAM_INDICATOR_REPLACEMENTS: phf::Map<&str, &str> = phf_map! { "B" => "⠘", // bold "𝔹" => "XXX", // blackboard -- from prefs "T" => "⠈", // script - "I" => "⠨", // italic - "R" => "", // roman // "E" => "⠰", // English "1" => "⠠", // Grade 1 symbol "L" => "", // Letter left in to assist in locating letters @@ -2137,7 +2135,7 @@ static CMU_INDICATOR_REPLACEMENTS: phf::Map<&str, &str> = phf_map! { "B" => "⠔", // bold "𝔹" => "⠬", // blackboard -- from prefs // "T" => "⠈", // script - "I" => "⠔", // italic -- same as bold + "I" => "⠔", // italic -- used for digits (not math letters); same cell as bold in CMU // "R" => "", // roman // "E" => "⠰", // English "1" => "⠐", // Grade 1 symbol -- used here for a-j after number @@ -2230,7 +2228,7 @@ static SWEDISH_INDICATOR_REPLACEMENTS: phf::Map<&str, &str> = phf_map! { "B" => "⠨", // bold "𝔹" => "XXX", // blackboard -- from prefs "T" => "⠈", // script - "I" => "⠨", // italic + "I" => "⠨", // italic -- used for digits (not math letters) "R" => "", // roman "1" => "⠱", // Grade 1 symbol (used for number followed by a letter) "L" => "", // Letter left in to assist in locating letters @@ -2269,7 +2267,7 @@ static FINNISH_INDICATOR_REPLACEMENTS: phf::Map<&str, &str> = phf_map! { "B" => "⠨", // bold "𝔹" => "XXX", // blackboard -- from prefs "T" => "⠈", // script - "I" => "⠨", // italic + "I" => "⠨", // italic -- used for digits (not math letters) "R" => "", // roman "E" => "⠰", // English "1" => "⠀", // Grade 1 symbol (used for number followed by a letter) @@ -2719,21 +2717,34 @@ impl BrailleChars { } } + /// Italic typeform is for digits (and numeric punctuation like '.'), not math letters. + fn uses_italic_typeform(node_name: &str, text: &str) -> bool { + if node_name == "mn" { + return true; + } + !text.is_empty() && text.chars().all(|ch| ch.is_ascii_digit() || matches!(ch, '.' | ',' | '−' | '-' | '+')) + } + fn get_braille_nemeth_chars(node: Element, text_range: Option>) -> Result { // To greatly simplify typeface/language generation, the chars have unique ASCII chars for them: // Typeface: S: sans-serif, B: bold, 𝔹: blackboard, T: script, I: italic, R: Roman // Language: E: English, D: German, G: Greek, V: Greek variants, H: Hebrew, U: Russian // Indicators: C: capital, L: letter, N: number, P: punctuation, M: multipurpose + // Italic typeform is used for digits; math letters do not get italic. static PICK_APART_CHAR: LazyLock = LazyLock::new(|| { Regex::new(r"(?P[SB𝔹TIR]*)(?P[EDGVHU]?)(?PC?)(?PL?)(?P[N]?)(?P.)").unwrap() }); let raw_math_variant = node.attribute_value("mathvariant"); let math_variant = raw_math_variant.as_deref(); + let text = BrailleChars::substring(as_str!(as_text(node)), &text_range); + let node_name = name(node); + let italic_ok = BrailleChars::uses_italic_typeform(node_name, &text); let attr_typeface = match math_variant { None => "R", Some(variant) => match variant { "bold" => "B", - "italic" => "I", + "italic" => if italic_ok {"I"} else {"R"}, + "bold-italic" => if italic_ok {"BI"} else {"B"}, "double-struck" => "𝔹", "script" => "T", "fraktur" => "D", @@ -2741,7 +2752,6 @@ impl BrailleChars { _ => "R", // normal and unknown }, }; - let text = BrailleChars::substring(as_str!(as_text(node)), &text_range); let braille_chars = braille_replace_chars(&text, node)?; // debug!("Nemeth chars: text='{}', braille_chars='{}'", &text, &braille_chars); @@ -2750,7 +2760,6 @@ impl BrailleChars { // also true (sort of) for capitalization -- if all caps, use double cap in front (assume abbr or Roman Numeral) // we only care about this for numbers and identifiers/text, so we filter for only those - let node_name = name(node); let is_in_enclosed_list = node_name != "mo" && BrailleChars::is_in_enclosed_list(node); let is_mn_in_enclosed_list = is_in_enclosed_list && node_name == "mn"; let mut typeface = "R".to_string(); // assumption is "R" and if attr or letter is different, something happens @@ -2760,7 +2769,15 @@ impl BrailleChars { // debug!(" face: {:?}, lang: {:?}, num {:?}, letter: {:?}, cap: {:?}, char: {:?}", // &caps["face"], &caps["lang"], &caps["num"], &caps["letter"], &caps["cap"], &caps["char"]); let mut nemeth_chars = "".to_string(); - let char_face = if caps["face"].is_empty() {attr_typeface} else {&caps["face"]}; + let face_stripped; + let char_face = if caps["face"].is_empty() { + attr_typeface + } else if italic_ok { + &caps["face"] + } else { + face_stripped = caps["face"].replace('I', ""); + &face_stripped + }; let typeface_changed = typeface != char_face; if typeface_changed { typeface = char_face.to_string(); // needs to outlast this instance of the loop @@ -2813,11 +2830,16 @@ impl BrailleChars { return Ok(braille_chars); } // mathvariant could be "sans-serif-bold-italic" -- get the parts + // Italic typeform for digits (GTM 2.7); math letters do not get italic (GTM 1.5). let math_variant = math_variant.unwrap(); - let italic = math_variant.contains("italic"); - if italic & !braille_chars.contains('I') { + let italic_ok = BrailleChars::uses_italic_typeform(name(node), &text); + let italic = italic_ok && math_variant.contains("italic"); + if italic && !braille_chars.contains('I') { braille_chars = "I".to_string() + &braille_chars; } + if !italic_ok { + braille_chars = braille_chars.replace('I', ""); + } let bold = math_variant.contains("bold"); if bold & !braille_chars.contains('B') { braille_chars = "B".to_string() + &braille_chars; @@ -2850,11 +2872,15 @@ impl BrailleChars { fn get_braille_russian_chars(node: Element, text_range: Option>) -> Result { let text = BrailleChars::substring(as_str!(as_text(node)), &text_range); - let braille_chars = braille_replace_chars(&text, node)?; + let mut braille_chars = braille_replace_chars(&text, node)?; let Some(raw_math_variant) = node.attribute_value("mathvariant") else { - return Ok(braille_chars); + return Ok(braille_chars.replace('I', "")); }; let math_variant = as_str!(raw_math_variant); + let italic_ok = BrailleChars::uses_italic_typeform(name(node), &text); + if !italic_ok { + braille_chars = braille_chars.replace('I', ""); + } let mut prefix = String::new(); let mut suffix = String::new(); @@ -2862,7 +2888,8 @@ impl BrailleChars { prefix.push('⠻'); suffix.insert(0, '⠻'); } - if math_variant.contains("italic") && !braille_chars.contains('I') { + // Italic typeform only for digits (not math letters) + if math_variant.contains("italic") && italic_ok && !braille_chars.contains('I') { prefix.push('⠸'); suffix.insert(0, '⠸'); } @@ -2898,16 +2925,27 @@ impl BrailleChars { let text = BrailleChars::substring(as_str!(as_text(node)), &text_range); let text = add_separator(text); - let braille_chars = braille_replace_chars(&text, node)?; + let mut braille_chars = braille_replace_chars(&text, node)?; // debug!("get_braille_ueb_chars: before/after unicode.yaml: '{}'/'{}'", text, braille_chars); if math_variant.is_none() { // nothing we need to do return Ok(braille_chars); } // mathvariant could be "sans-serif-bold-italic" -- get the parts + // CMU: italic typeform for digits only (not math letters) let math_variant = math_variant.unwrap(); + let italic_ok = BrailleChars::uses_italic_typeform(name(node), &text); + let italic = italic_ok && math_variant.contains("italic"); + if italic && !braille_chars.contains('I') { + braille_chars = "I".to_string() + &braille_chars; + } + if !italic_ok { + braille_chars = braille_chars.replace('I', ""); + } let bold = math_variant.contains("bold"); - let italic = math_variant.contains("italic"); + if bold && !braille_chars.contains('B') { + braille_chars = "B".to_string() + &braille_chars; + } let typeface = match HAS_TYPEFACE.find(math_variant) { None => "", Some(m) => match m.as_str() { diff --git a/tests/braille/UEB/other.rs b/tests/braille/UEB/other.rs index 35c7cfcf0..b31f9958f 100644 --- a/tests/braille/UEB/other.rs +++ b/tests/braille/UEB/other.rs @@ -227,3 +227,31 @@ fn unicode_subscript_chars_in_and_out_of_script_position() -> Result<()> { return Ok(()); } +#[test] +fn ueb_no_italic_typeform_for_math_letters() -> Result<()> { + // UEB omits italic typeform for math letters (GTM 1.5); Greek uses ⠨ via G only. + // Plain, mathvariant italic, and Mathematical Italic x should match (no italic ⠨). + let plain = "x"; + let attr_italic = "x"; + let plane1_italic = "𝑥"; + test_braille("UEB", plain, "⠰⠭")?; + test_braille("UEB", attr_italic, "⠰⠭")?; + test_braille("UEB", plane1_italic, "⠰⠭")?; + + // Greek letter indicator (same cell as italic typeform) still used for α + test_braille("UEB", "α", "⠨⠁")?; + + // Bold-italic keeps bold ⠘, not italic typeform + test_braille("UEB", "x", "⠘⠆⠰⠭")?; + test_braille("UEB", "𝒙", "⠘⠆⠰⠭")?; + return Ok(()); +} + +#[test] +fn ueb_italic_typeform_for_digits() -> Result<()> { + // UEB uses italic typeform for digits (GTM 2.7 emphasis of numeric material). + test_braille("UEB", "3", "⠨⠆⠼⠉")?; + test_braille("UEB", ".3", "⠨⠂⠼⠲⠉")?; + return Ok(()); +} + From fbc49bb73cc1b6915f621fa8a63c39c306bdd852 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Sun, 16 Aug 2026 09:52:39 +0200 Subject: [PATCH 033/157] Announce column separator (#679) * Add `HasVisibleColumnLine` XPath function to handle table separators in speech output - Replace `count_table_dims` return type with `usize` values for clarity. - Update function registration to include `HasVisibleColumnLine`. - Modify speech tests to reflect separator usage in matrix descriptions. * Refactor `count_table_dims` to return `Result` type and update usage sites * undo whitespace change * . * . * explain tests better in comments * explain tests better in comments * Add support for row separators and unify boundary line logic * fix check_table_line helper function * added a pause before separator announcements * Change pause duration from medium to short * Update test cases for matrix representations to add pause before separator --------- Co-authored-by: NSoiffer --- Rules/Languages/en/SharedRules/default.yaml | 11 ++ src/speech.rs | 2 +- src/xpath_functions.rs | 190 +++++++++++++++++++- tests/Languages/en/mtable.rs | 77 +++++++- 4 files changed, 269 insertions(+), 11 deletions(-) diff --git a/Rules/Languages/en/SharedRules/default.yaml b/Rules/Languages/en/SharedRules/default.yaml index 255c3bbf4..264c14540 100644 --- a/Rules/Languages/en/SharedRules/default.yaml +++ b/Rules/Languages/en/SharedRules/default.yaml @@ -478,6 +478,17 @@ - x: "count(preceding-sibling::*)+IfThenElse(parent::m:mlabeledtr, 0, 1)" - pause: medium - x: "*" + - test: + if: "HasVisibleColumnLine(../.., count(preceding-sibling::*) + 1)" + then: + - pause: short + - t: "separator" + - test: + # Announce a row separator only after the row's final cell, so it is spoken once per horizontal boundary. + if: "count(following-sibling::*) = 0 and HasVisibleRowLine(../.., count(../preceding-sibling::*) + 1)" + then: + - pause: short + - t: "row separator" - test: # short pause after each element; medium pause if last element in a row; long pause for last element in matrix - if: count(following-sibling::*) > 0 diff --git a/src/speech.rs b/src/speech.rs index 0aaf71405..eaaeff282 100644 --- a/src/speech.rs +++ b/src/speech.rs @@ -1761,7 +1761,7 @@ impl<'c, 'r> ContextStack<'c> { fn base_context(var_defs: PreferenceHashMap) -> sxd_xpath_no_unsafe::Context<'c> { let mut context = sxd_xpath_no_unsafe::Context::new(); context.set_namespace("m", "http://www.w3.org/1998/Math/MathML"); - crate::xpath_functions::add_builtin_functions(&mut context); + crate::xpath_functions::register_mathcat_xpath_functions(&mut context); for (key, value) in var_defs { context.set_variable(key.as_str(), yaml_to_value(&value)); // if let Some(str_value) = value.as_str() { diff --git a/src/xpath_functions.rs b/src/xpath_functions.rs index 6dc58aeac..587206f44 100644 --- a/src/xpath_functions.rs +++ b/src/xpath_functions.rs @@ -1646,9 +1646,86 @@ impl Function for CountTableColumns { } } +#[derive(Clone, Copy)] +enum TableLineAxis { + Row, + Column, +} + +/// Return whether a one-based mtable boundary has a visible line on the given axis. +/// +/// MathML repeats the final line style for remaining boundaries. Boundaries after +/// the final row or column, and values other than `solid` and `dashed`, do not +/// describe a visible separator. +fn has_visible_table_line(table: Element, boundary: usize, axis: TableLineAxis) -> bool { + if boundary == 0 || !is_tag(table, "mtable") { + return false; + } + + let Ok((Value::Number(row_count), Value::Number(column_count))) = CountTableDims::new().count_table_dims(table) else { + return false; + }; + let (line_count, attribute_name) = match axis { + TableLineAxis::Row => (row_count, "rowlines"), + TableLineAxis::Column => (column_count, "columnlines"), + }; + if boundary as f64 >= line_count { + return false; + } + + return table + .attribute_value(attribute_name) + .map(|values| { + matches!( + values.split_whitespace().take(boundary).last(), + Some("solid" | "dashed") + ) + }) + .unwrap_or(false); +} + +/// Validate and convert XPath arguments before delegating to the typed table-line helper. +fn evaluate_has_visible_table_line<'d>( + args: Vec>, + function_name: &str, + axis: TableLineAxis, +) -> Result, Error> { + let mut args = Args(args); + args.exactly(2)?; + let boundary = args.pop_number()?; + let table = validate_one_node(args.pop_nodeset()?, function_name)?; + let Node::Element(table) = table else { + return Err(Error::Other { what: format!("{function_name} requires an mtable element") }); + }; + if !boundary.is_finite() || boundary < 1.0 || boundary.fract() != 0.0 { + return Ok(Value::Boolean(false)); + } + return Ok(Value::Boolean(has_visible_table_line(table, boundary as usize, axis))); +} + +/// XPath function reporting whether an mtable column boundary has a visible line. +struct HasVisibleColumnLine; +impl Function for HasVisibleColumnLine { + fn evaluate<'c, 'd>(&self, + _context: &context::Evaluation<'c, 'd>, + args: Vec>) -> Result, Error> { + evaluate_has_visible_table_line(args, "HasVisibleColumnLine", TableLineAxis::Column) + } +} + +/// XPath function reporting whether an mtable row boundary has a visible line. +struct HasVisibleRowLine; +impl Function for HasVisibleRowLine { + fn evaluate<'c, 'd>(&self, + _context: &context::Evaluation<'c, 'd>, + args: Vec>) -> Result, Error> { + evaluate_has_visible_table_line(args, "HasVisibleRowLine", TableLineAxis::Row) + } +} + /// Add all the functions defined in this module to `context`. -pub fn add_builtin_functions(context: &mut Context) { +pub fn register_mathcat_xpath_functions(context: &mut Context) { context.set_function("NestingChars", crate::braille::NemethNestingChars); context.set_function("BrailleChars", crate::braille::BrailleChars); context.set_function("NeedsToBeGrouped", crate::braille::NeedsToBeGrouped); @@ -1671,6 +1748,8 @@ pub fn add_builtin_functions(context: &mut Context) { context.set_function("GetNavigationPartName", GetNavigationPartName); context.set_function("CountTableRows", CountTableRows); context.set_function("CountTableColumns", CountTableColumns); + context.set_function("HasVisibleColumnLine", HasVisibleColumnLine); + context.set_function("HasVisibleRowLine", HasVisibleRowLine); context.set_function("DEBUG", Debug); // Not used: remove?? @@ -1876,7 +1955,10 @@ mod tests { let package = parser::parse(mathml).map_err(|e| anyhow::anyhow!("failed to parse XML: {e}"))?; let math_elem = get_element(&package); let child = as_element(math_elem.children()[0]); - assert!(CountTableDims::new().count_table_dims(child) == Ok((Value::Number(dims.0 as f64), Value::Number(dims.1 as f64)))); + assert_eq!( + CountTableDims::new().count_table_dims(child), + Ok((Value::Number(dims.0 as f64), Value::Number(dims.1 as f64))) + ); return Ok( () ); } @@ -1896,6 +1978,110 @@ mod tests { }); } + fn check_table_line(mathml: &str, boundary: usize, axis: TableLineAxis, expected: bool) -> Result<()> { + let package = parser::parse(mathml).map_err(|e| anyhow::anyhow!("failed to parse XML: {e}"))?; + let math = get_element(&package); + let table = math + .children() + .iter() + .find_map(|child| match child { + ChildOfElement::Element(table) => Some(*table), + _ => None, + }) + .expect("test MathML should contain an mtable element"); + assert_eq!(has_visible_table_line(table, boundary, axis), expected); + return Ok(()); + } + + /// Verifies visible table-line styles, repeated styles, and boundaries outside the table. + #[test] + fn visible_table_lines() -> Result<()> { + return xpath_test(|| { + // The three values map in order to the three boundaries between four columns. + let mixed_column_lines: &str = " + + + column 1 + column 2 + column 3 + column 4 + + "; + check_table_line(mixed_column_lines, 1, TableLineAxis::Column, false)?; + check_table_line(mixed_column_lines, 2, TableLineAxis::Column, true)?; + check_table_line(mixed_column_lines, 3, TableLineAxis::Column, true)?; + + // The final `dashed` value repeats for the third column boundary. + let repeated_column_line: &str = " + + + column 1 + column 2 + column 3 + column 4 + + "; + check_table_line(repeated_column_line, 3, TableLineAxis::Column, true)?; + + // A table without `columnlines` has no visible column boundary. + let no_column_lines: &str = " + + + column 1 + column 2 + + "; + check_table_line(no_column_lines, 1, TableLineAxis::Column, false)?; + + // `none` explicitly makes the column boundary invisible. + let invisible_column_line: &str = " + + + column 1 + column 2 + + "; + check_table_line(invisible_column_line, 1, TableLineAxis::Column, false)?; + + // Only `solid` and `dashed` describe visible table lines. + let unsupported_column_line: &str = " + + + column 1 + column 2 + + "; + check_table_line(unsupported_column_line, 1, TableLineAxis::Column, false)?; + + // Boundary 2 is after the final column, not between two columns. + let two_column_table: &str = " + + column 1 + column 2 + + "; + check_table_line(two_column_table, 2, TableLineAxis::Column, false)?; + + // Four rows have three interior boundaries. `none` applies after row 1, + // `dashed` applies after row 2, and the final `dashed` repeats after row 3. + let mixed_row_lines: &str = " + + row 1 + row 2 + row 3 + row 4 + "; + check_table_line(mixed_row_lines, 1, TableLineAxis::Row, false)?; + check_table_line(mixed_row_lines, 2, TableLineAxis::Row, true)?; + check_table_line(mixed_row_lines, 3, TableLineAxis::Row, true)?; + // Boundary 4 is after the final row, not between two rows. + check_table_line(mixed_row_lines, 4, TableLineAxis::Row, false)?; + // Boundary zero is invalid for both axes. + check_table_line(mixed_row_lines, 0, TableLineAxis::Row, false)?; + return Ok(()); + }); + } + #[test] fn at_left_edge() -> Result<()> { return xpath_test(|| { diff --git a/tests/Languages/en/mtable.rs b/tests/Languages/en/mtable.rs index e6952cf51..8a670988e 100644 --- a/tests/Languages/en/mtable.rs +++ b/tests/Languages/en/mtable.rs @@ -271,8 +271,69 @@ fn augmented_matrix_2x3() -> Result<()> { ] "; - test("en", "ClearSpeak", expr, "the 2 by 3 augmented matrix; row 1; 3, 1, 4; row 2; 0, 2, 6")?; - test("en", "SimpleSpeak", expr, "the 2 by 3 augmented matrix; row 1; 3, 1, 4; row 2; 0, 2, 6")?; + test("en", "ClearSpeak", expr, "the 2 by 3 augmented matrix; row 1; 3, 1, separator, 4; row 2; 0, 2, separator, 6")?; + test("en", "SimpleSpeak", expr, "the 2 by 3 augmented matrix; row 1; 3, 1, separator, 4; row 2; 0, 2, separator, 6")?; + Ok(()) +} + +#[test] +fn dashed_augmented_matrix_separator() -> Result<()> { + let expr = " + + [ + + 123 + + ] + "; + test("en", "ClearSpeak", expr, "the 1 by 3 row matrix; 1, separator, 2, separator, 3")?; + test("en", "SimpleSpeak", expr, "the 1 by 3 row matrix; 1, separator, 2, separator, 3")?; + Ok(()) +} + +/// A horizontal line is announced once, after the row it separates from the next row. +#[test] +fn matrix_row_separator() -> Result<()> { + let expr = " + + [ + + + 1 + 2 + + + 3 + 4 + + + ] + "; + test("en", "ClearSpeak", expr, "the 2 by 2 matrix; row 1; 1, 2, row separator; row 2; 3, 4")?; + test("en", "SimpleSpeak", expr, "the 2 by 2 matrix; row 1; 1, 2, row separator; row 2; 3, 4")?; + Ok(()) +} + +/// Horizontal and vertical lines use distinct announcements at their respective boundaries. +#[test] +fn matrix_row_and_column_separators() -> Result<()> { + let expr = " + + [ + + + 1 + 2 + + + 3 + 4 + + + ] + "; + test("en", "ClearSpeak", expr, "the 2 by 2 augmented matrix; row 1; 1, separator, 2, row separator; row 2; 3, separator, 4")?; + test("en", "SimpleSpeak", expr, "the 2 by 2 augmented matrix; row 1; 1, separator, 2, row separator; row 2; 3, separator, 4")?; Ok(()) } @@ -926,13 +987,13 @@ let expr = " "; test_ClearSpeak("en", "ClearSpeak_Matrix", "EndMatrix", - expr, "the 3 by 4 augmented matrix; row 1; column 1; 1, column 2; 2, column 3; negative 1, column 4; 3; \ - row 2; column 1; negative 3, column 2; 3, column 3; negative 1, column 4; 2; \ - row 3; column 1; 2, column 2; 3, column 3; 2, column 4; negative 1; end matrix")?; + expr, "the 3 by 4 augmented matrix; row 1; column 1; 1, column 2; 2, column 3; negative 1, separator, column 4; 3; \ + row 2; column 1; negative 3, column 2; 3, column 3; negative 1, separator, column 4; 2; \ + row 3; column 1; 2, column 2; 3, column 3; 2, separator, column 4; negative 1; end matrix")?; test("en", "SimpleSpeak", - expr, "the 3 by 4 augmented matrix; row 1; column 1; 1, column 2; 2, column 3; negative 1, column 4; 3; \ - row 2; column 1; negative 3, column 2; 3, column 3; negative 1, column 4; 2; \ - row 3; column 1; 2, column 2; 3, column 3; 2, column 4; negative 1; end matrix")?; + expr, "the 3 by 4 augmented matrix; row 1; column 1; 1, column 2; 2, column 3; negative 1, separator, column 4; 3; \ + row 2; column 1; negative 3, column 2; 3, column 3; negative 1, separator, column 4; 2; \ + row 3; column 1; 2, column 2; 3, column 3; 2, separator, column 4; negative 1; end matrix")?; Ok(()) } From d5c63d879c29e03f8a16e6432ca37c62fc587cd7 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Sun, 16 Aug 2026 00:57:10 -0700 Subject: [PATCH 034/157] fix clippy warnings in the no-unsafe version --- src/braille.rs | 8 ++++---- src/interface.rs | 6 +++--- src/navigate.rs | 4 ++-- tests/Languages/en/definitions.rs | 12 ++++-------- tests/Languages/hu/definitions.rs | 6 ++---- 5 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/braille.rs b/src/braille.rs index 929bcf791..9453f5ddf 100644 --- a/src/braille.rs +++ b/src/braille.rs @@ -2737,7 +2737,7 @@ impl BrailleChars { let raw_math_variant = node.attribute_value("mathvariant"); let math_variant = raw_math_variant.as_deref(); let text = BrailleChars::substring(as_str!(as_text(node)), &text_range); - let node_name = name(node); + let node_name = as_str!(name(node)); let italic_ok = BrailleChars::uses_italic_typeform(node_name, &text); let attr_typeface = match math_variant { None => "R", @@ -2832,7 +2832,7 @@ impl BrailleChars { // mathvariant could be "sans-serif-bold-italic" -- get the parts // Italic typeform for digits (GTM 2.7); math letters do not get italic (GTM 1.5). let math_variant = math_variant.unwrap(); - let italic_ok = BrailleChars::uses_italic_typeform(name(node), &text); + let italic_ok = BrailleChars::uses_italic_typeform(as_str!(name(node)), &text); let italic = italic_ok && math_variant.contains("italic"); if italic && !braille_chars.contains('I') { braille_chars = "I".to_string() + &braille_chars; @@ -2877,7 +2877,7 @@ impl BrailleChars { return Ok(braille_chars.replace('I', "")); }; let math_variant = as_str!(raw_math_variant); - let italic_ok = BrailleChars::uses_italic_typeform(name(node), &text); + let italic_ok = BrailleChars::uses_italic_typeform(as_str!(name(node)), &text); if !italic_ok { braille_chars = braille_chars.replace('I', ""); } @@ -2934,7 +2934,7 @@ impl BrailleChars { // mathvariant could be "sans-serif-bold-italic" -- get the parts // CMU: italic typeform for digits only (not math letters) let math_variant = math_variant.unwrap(); - let italic_ok = BrailleChars::uses_italic_typeform(name(node), &text); + let italic_ok = BrailleChars::uses_italic_typeform(as_str!(name(node)), &text); let italic = italic_ok && math_variant.contains("italic"); if italic && !braille_chars.contains('I') { braille_chars = "I".to_string() + &braille_chars; diff --git a/src/interface.rs b/src/interface.rs index 6486aa762..012345056 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -1373,11 +1373,11 @@ mod tests { set_mathml(good_mathml)?; let bad_mathml = "&xabc;"; assert!(set_mathml(bad_mathml).is_err()); - assert!(get_spoken_text()? == ""); + assert!(get_spoken_text()?.is_empty()); set_mathml(good_mathml)?; let bad_mathml = "garbage"; assert!(set_mathml(bad_mathml).is_err()); - assert!(get_spoken_text()? == ""); + assert!(get_spoken_text()?.is_empty()); return Ok( () ); }); } @@ -1404,7 +1404,7 @@ mod tests { x-y "; - set_mathml(&expr)?; + set_mathml(expr)?; let speech = get_spoken_text()?; // Rule-generated SSML must pass through verbatim (not XML-entity-encoded). assert!(!speech.contains("<")); diff --git a/src/navigate.rs b/src/navigate.rs index 0ef0f62bc..f893b3838 100644 --- a/src/navigate.rs +++ b/src/navigate.rs @@ -1004,10 +1004,10 @@ mod tests { match do_navigate_command_string(mathml, command) { Err(e) => { panic!("\nStarting at '{}', '{} failed.\n{}", - start_id, command, &crate::interface::errors_to_string(&e)) + start_id, command, crate::interface::errors_to_string(&e)) }, Ok(nav_speech) => { - let nav_speech = nav_speech.trim_end_matches(&[' ', ',', ';']); + let nav_speech = nav_speech.trim_end_matches([' ', ',', ';']); // debug!("Full speech: {}", nav_speech); if !result_id.is_empty() { let (id, _) = nav_stack.borrow().get_navigation_mathml_id(mathml); diff --git a/tests/Languages/en/definitions.rs b/tests/Languages/en/definitions.rs index 80197c8c3..adbae499c 100644 --- a/tests/Languages/en/definitions.rs +++ b/tests/Languages/en/definitions.rs @@ -597,13 +597,11 @@ fn linear_algebra_tests() -> Result<()> { " .to_string() } - "transpose" => format!( - " + "transpose" => " x - " - ), + ".to_string(), _ => format!( " @@ -713,14 +711,12 @@ fn geometry_prefix_tests() -> Result<()> { #[test] fn separator_tests() -> Result<()> { - let expr = format!( - " + let expr = " x y - " - ); + ".to_string(); test("en", "ClearSpeak", &expr, "x y")?; Ok(()) diff --git a/tests/Languages/hu/definitions.rs b/tests/Languages/hu/definitions.rs index bd84fb155..542f41885 100644 --- a/tests/Languages/hu/definitions.rs +++ b/tests/Languages/hu/definitions.rs @@ -705,14 +705,12 @@ fn geometry_prefix_tests() -> Result<()> { #[test] fn separator_tests() -> Result<()> { - let expr = format!( - " + let expr = " x y - " - ); + ".to_string(); test("hu", "ClearSpeak", &expr, "x y")?; Ok(()) From 78744ec32f52433ffd938b70d04e24705898fd06 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Sun, 16 Aug 2026 01:05:32 -0700 Subject: [PATCH 035/157] Revert changes to file from 6ecc412 --- Rules/Braille/Russian/unicode-full.yaml | 58 ++++++++++++------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/Rules/Braille/Russian/unicode-full.yaml b/Rules/Braille/Russian/unicode-full.yaml index b562dc302..813669ecc 100644 --- a/Rules/Braille/Russian/unicode-full.yaml +++ b/Rules/Braille/Russian/unicode-full.yaml @@ -57,7 +57,7 @@ - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 - - tc: "BC" + - tc: "B" - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" @@ -123,23 +123,23 @@ - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" - "𝐴-𝑍": # 0x1d434 - 0x1d44d - - tc: "C" + - tc: "IC" - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'abcdefghijklmnopqrstuvwxyz')" - "𝑎-𝑧": # 0x1d44e - 0x1d467 - - tc: "" + - tc: "I" - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" - "𝑨-𝒁": # 0x1d468 - 0x1d481 - - tc: "BC" + - tc: "BIC" - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'abcdefghijklmnopqrstuvwxyz')" - "𝒂-𝒛": # 0x1d482 - 0x1d49b - - tc: "B" + - tc: "BI" - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 - - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'abcdefghijklmnopqrstuvwxyz')" + - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" @@ -148,7 +148,7 @@ - test: if: "not($IgnoreBold)" then: [tc: "B"] - - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'abcdefghijklmnopqrstuvwxyz')" + - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝗮-𝘇": # 0x1d5ee - 0x1d607 - test: @@ -157,27 +157,27 @@ - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" - "𝘈-𝘡": # 0x1d608 - 0x1d621 - - tc: "C" - - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'abcdefghijklmnopqrstuvwxyz')" + - tc: "IC" + - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝘢-𝘻": # 0x1d622 - 0x1d63b - - tc: "" + - tc: "I" - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" - "𝘼-𝙕": # 0x1d63c - 0x1d655 - # - tc: "bold italicC" + # - tc: "bold italic" - test: if: "$IgnoreBold" - then: [tc: "C"] - else: [tc: "B"] - - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'abcdefghijklmnopqrstuvwxyz')" + then: [tc: I] + else: [tc: "BI"] + - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝙖-𝙯": # 0x1d656 - 0x1d66f # - tc: "bold italic" - test: if: "$IgnoreBold" - then: [tc: ""] - else: [tc: "B"] + then: [tc: I] + else: [tc: "BI"] - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" - "𝙰-𝚉": # 0x1d670 - 0x1d689 @@ -194,7 +194,7 @@ - test: if: "not($IgnoreBold)" then: [tc: "B"] - - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da - test: @@ -215,7 +215,7 @@ - spell: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa - - tc: "C" + - tc: "IC" - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝛼-𝜔": # 0x1d6fc - 0x1d714 @@ -230,20 +230,20 @@ - spell: "translate('.', '𝜕𝜖𝜗𝜘𝜙𝜚𝜛', '∂εθκφρπ')" - "𝜜-𝜴": # 0x1d71c - 0x1d734 - # - tc: "bold italicC" - - tc: 'BC⠁' + # - tc: "bold italic" + - tc: 'BIC⠁' - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝜶-𝝎": # 0x1d736 - 0x1d74e - - tc: "B" + - tc: "BI" - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": # 0x1d74f - 0x1d755 - - tc: "B" + - tc: "BI" - spell: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εκθφρπ')" - "𝜵": # 0x1d735 - - tc: "B" + - tc: "BI" - spell: "translate('.', '𝜵', '∇')" - "𝝖-𝝮": # 0x1d756 - 0x1d76e @@ -263,19 +263,19 @@ - spell: "translate('.', '𝜵', '∇')" - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 - # - tc: "bold italicC" + # - tc: "bold italic" - test: if: "$IgnoreBold" - then: [tc: "C"] - else: [tc: "B"] - - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'αβγδεζηθικλμνξοπρςστυφχψω')" + then: [tc: I] + else: [tc: "BI"] + - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "𝞪-𝟂": # 0x1d7aa - 0x1d7c2 # - tc: "bold italic" - test: if: "$IgnoreBold" - then: [tc: ""] - else: [tc: "B"] + then: [tc: I] + else: [tc: "BI"] - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": # 0x1d7c3 - 0x1d7c9 From a1fc8e0750e32aeae96e00eb463748c97389613d Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Sun, 16 Aug 2026 01:33:24 -0700 Subject: [PATCH 036/157] missed this change that needed to be reverted for Russian braille --- src/braille.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/braille.rs b/src/braille.rs index 9453f5ddf..129fb7290 100644 --- a/src/braille.rs +++ b/src/braille.rs @@ -2871,16 +2871,13 @@ impl BrailleChars { } fn get_braille_russian_chars(node: Element, text_range: Option>) -> Result { + // Russian italic typeform for letters is left unchanged pending external advice. let text = BrailleChars::substring(as_str!(as_text(node)), &text_range); - let mut braille_chars = braille_replace_chars(&text, node)?; + let braille_chars = braille_replace_chars(&text, node)?; let Some(raw_math_variant) = node.attribute_value("mathvariant") else { - return Ok(braille_chars.replace('I', "")); + return Ok(braille_chars); }; let math_variant = as_str!(raw_math_variant); - let italic_ok = BrailleChars::uses_italic_typeform(as_str!(name(node)), &text); - if !italic_ok { - braille_chars = braille_chars.replace('I', ""); - } let mut prefix = String::new(); let mut suffix = String::new(); @@ -2888,8 +2885,7 @@ impl BrailleChars { prefix.push('⠻'); suffix.insert(0, '⠻'); } - // Italic typeform only for digits (not math letters) - if math_variant.contains("italic") && italic_ok && !braille_chars.contains('I') { + if math_variant.contains("italic") && !braille_chars.contains('I') { prefix.push('⠸'); suffix.insert(0, '⠸'); } From bc712eb8bed3442d2cfa90bfd8268cbf2d7537b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Sun, 16 Aug 2026 15:52:22 +0200 Subject: [PATCH 037/157] fix AGENTS.md instruction on `uv run pytest` --- AGENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 0b10d8a5f..0696e6979 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -26,7 +26,7 @@ but add common mistakes of AI agents here instead. - In sandboxed runs, if needed: - set `UV_CACHE_DIR=/tmp/uv-cache` - rerun with escalated permissions if macOS `system-configuration` panics occur. -- *always* self-validate: `ùv run pytest` +- self-validate appropriately with: `uv run pytest` ## Agent Instructions - Do not mirror README content here; keep guidance agent-specific. From 6937925c0ec6aa4fbc001555219c7c3f8fc2efcd Mon Sep 17 00:00:00 2001 From: NSoiffer Date: Sun, 16 Aug 2026 22:48:04 -0700 Subject: [PATCH 038/157] Merge latest hu changes (#696) * Add few tweaks into the Rules/Languages/hu/definitions.yaml file, Added missing definitions.rs test file the test/Languages/hu directory, and added SimpleSpeak test directory the mroot and menclose tests (#646) * Do more localization in Rules/Languages/hu/definitions.yaml Signed-off-by: Attila Hammer * Add in Simplespeak tests the definition, mroot and menclose tests Signed-off-by: Attila Hammer * fix some werbs in intervals into rules/Languages/hu/ClearSpeak_rules.yaml and SimpleSpeak_rules.yaml Signed-off-by: Attila Hammer * Fix tests after interval Clearspeak and SimpleSpeak verb change Signed-off-by: Attila Hammer --------- Signed-off-by: Attila Hammer * Apply Hungarian unicode fixes from PR #673 * Update Hungarian language and test rules from PR #694 * Fix a mistake after the selective merge with definitions.yaml and definition.rs test file (#697) Signed-off-by: Attila Hammer --------- Signed-off-by: Attila Hammer Co-authored-by: hammera --- Rules/Languages/hu/ClearSpeak_Rules.yaml | 18 +- Rules/Languages/hu/SharedRules/default.yaml | 71 +++--- Rules/Languages/hu/SharedRules/general.yaml | 4 +- Rules/Languages/hu/SharedRules/geometry.yaml | 3 +- Rules/Languages/hu/definitions.yaml | 96 ++++++-- Rules/Languages/hu/navigate.yaml | 57 +++-- Rules/Languages/hu/unicode-full.yaml | 207 +++++++++++++++++- tests/Languages/hu/ClearSpeak/sets.rs | 18 +- .../hu/ClearSpeak/symbols_and_adornments.rs | 8 +- tests/Languages/hu/definitions.rs | 24 +- tests/Languages/hu/shared.rs | 6 +- 11 files changed, 398 insertions(+), 114 deletions(-) diff --git a/Rules/Languages/hu/ClearSpeak_Rules.yaml b/Rules/Languages/hu/ClearSpeak_Rules.yaml index 73d8eaf5e..434034698 100644 --- a/Rules/Languages/hu/ClearSpeak_Rules.yaml +++ b/Rules/Languages/hu/ClearSpeak_Rules.yaml @@ -568,27 +568,25 @@ - name: set tag: set - match: "." + # Empty set and braced/{set-builder} forms (typically 0–1 child). + # Multi-arg intent set($x,$y,...) and set($x) with @arg fall through to function-intent + # ("the set of …"). + match: "count(*)=0 or (count(*)=1 and not(*[1][@arg]))" replace: - test: - if: "count(*)=0" then: [T: "az üres halmaz"] # phrase('the empty set') - - else_if: "count(*)=2" - then: - - test: - if: "$Verbosity!='Terse'" - then: [T: "az"] # phrase('the' empty set) - - T: "üres halmaz" # phrase(the 'empty set') - else_if: "count(*[1]/*)=3 and *[1]/*[2][self::m:mo][.=':' or .='|' or .='∣']" then: - test: if: "$Verbosity!='Terse'" - then: [T: ""] # phrase('the' set of all integers) - - x: "*[1]/*[1]" - - T: "melyekre teljesül, hogy" # phrase(this is a 'set of' numbers) + then: [T: ""] # phrase('the' empty set) + - T: "" # phrase(the 'empty set') - test: if: "$ClearSpeak_Sets != 'woAll'" then: [T: "minden"] # phrase(the set of 'all' integers) + - x: "*[1]/*[1]" + - T: "melyekre teljesül, hogy" # phrase(the set S 'such that' x is less than y) - x: "*[1]/*[3]" else: - test: diff --git a/Rules/Languages/hu/SharedRules/default.yaml b/Rules/Languages/hu/SharedRules/default.yaml index b218667df..54bbffc64 100644 --- a/Rules/Languages/hu/SharedRules/default.yaml +++ b/Rules/Languages/hu/SharedRules/default.yaml @@ -62,7 +62,7 @@ - test: - if: "string-length(.) = 1 and text() != '_'" # need unicode.tdl to kick in for single letter tokens then: [x: "text()"] - - else_if: "@data-chem-element > 0 or @data-roman-numeral" # NavMode=Character needs this + - else_if: "@data-chem-element or @data-roman-numeral" # NavMode=Character needs this then: [SPELL: "text()", pause: "short"] else: [x: "translate(., '-_\u00A0', ' ')"] # from intent literals or from extra spaces added (which get deleted) @@ -237,26 +237,12 @@ - x: "*[2]" - T: "alatt" # phrase(x with z 'below' it) -# FIX: this only works for up to four dots (which is realistically all we need) -- name: dot-over - tag: modified-variable - match: "*[1][self::m:mi] and (*[2][translate(., '.', '')=''])" - replace: - - x: "*[1]" - - x: "IfThenElse(string-length(*[2])=1, 'pont', - IfThenElse(string-length(*[2])=2, 'pont pont', - IfThenElse(string-length(*[2])=3, 'pont pont pont', 'pont pont pont pont') - ))" - - pause: short - -# FIX: the 'translate' list is a little different from 'modified-variable', so we also include 'mover' (unify?) - name: diacriticals - tag: [mover, modified-variable] + tag: mover match: "*[1][self::m:mi] and *[2][translate(., '\u0306\u030c.\u00A8\u02D9\u20DB\u20DC`^ˇ~→¯_', '')='']" replace: - x: "*[1]" - x: "*[2]" - - pause: short - name: default tag: mover @@ -434,23 +420,22 @@ - T: "szkriptek vége" # phrase(At this point 'end scripts' occurs) - name: default - tag: [mtable, array] + tag: mtable variables: - IsColumnSilent: "false()" - - NumColumns: "CountTableColumns(.)" - - NumRows: "CountTableRows(.)" + - NumColumns: "count(*[1]/*) - IfThenElse(*/self::m:mlabeledtr, 1, 0)" match: "." replace: - T: "táblázat" # phrase(the 'table with' 3 rows) - - x: "$NumRows" + - x: count(*) - test: - if: "$NumRows=1" + if: count(*)=1 then: [T: "sorral"] # phrase(the table with 1 'row') else: [T: "sorral"] # phrase(the table with 3 'rows') - T: "és" # phrase(the table with 3 rows 'and' 4 columns) - x: "$NumColumns" - test: - if: "$NumColumns=1" + if: "NumColumns=1" then: [T: "oszloppal"] # phrase(the table with 3 rows and 1 'column') else: [T: "oszloppal"] # phrase(the table with 3 rows and 4 'columns') - pause: long @@ -491,6 +476,18 @@ - x: "count(preceding-sibling::*)+IfThenElse(parent::m:mlabeledtr, 0, 1)" - pause: medium - x: "*" + - test: + # short pause after each element; medium pause if last element in a row; long pause for last element in matrix + if: "HasVisibleColumnLine(../.., count(preceding-sibling::*) + 1)" + then: + - pause: short + - T: "elválasztó" + - test: + # Announce a row separator only after the row's final cell, so it is spoken once per horizontal boundary. + if: "count(following-sibling::*) = 0 and HasVisibleRowLine(../.., count(../preceding-sibling::*) + 1)" + then: + - pause: short + - T: "sorelválasztó" - test: # short pause after each element; medium pause if last element in a row; long pause for last element in matrix - if: count(following-sibling::*) > 0 @@ -500,6 +497,7 @@ else: [pause: long] + - name: empty-box # The ordering below is the order in which words come out when there is more than one value # Note: @notation can contain more than one value @@ -720,16 +718,27 @@ replace: - x: "SpeakIntentName(name(.), $Verbosity, 'function')" - test: - if: "$Verbosity != 'Terse' and not(contains(@data-intent-property, ':literal:')) and - not(count(*)=2 and (IsInDefinition(*[1], 'TrigFunctionNames') or IsInDefinition(name(.), 'TerseFunctionNames')) and IsNode(*[2], 'simple'))" - then: [T: "", pause: auto] # phrase(sine 'of' 5) - - insert: - nodes: "*" - replace: - - test: - if: "not(contains(@data-intent-property, ':literal:'))" - then: [x: "','"] + - if: "IntentFunctionUseArityPath(name(.), 'function', count(*))" + then: + - x: "IntentFunctionGlueBefore(name(.), 'function', 1, count(*))" - pause: auto + - insert: + nodes: "*" + replace: + - x: "IntentFunctionGlueBefore(name(.), 'function', $InsertIndex, count(*))" + - pause: auto + else: + - test: + if: "$Verbosity != 'Terse' and not(contains(@data-intent-property, ':literal:')) and + not(count(*)=2 and (IsInDefinition(*[1], 'TrigFunctionNames') or IsInDefinition(name(.), 'TerseFunctionNames')) and IsNode(*[2], 'simple'))" + then: [T: "", pause: auto] # phrase(sine 'of' 5) + - insert: + nodes: "*" + replace: + - test: + if: "not(contains(@data-intent-property, ':literal:'))" + then: [x: "IntentFunctionArgSeparator(name(.), 'function', count(*))"] + - pause: auto - test: # speak "end ..." if not bracketed or last child is not simple and not last node if: "$Impairment = 'Blindness' and not(*[last()][IsBracketed(., '', '') or IsNode(., 'simple')] )" diff --git a/Rules/Languages/hu/SharedRules/general.yaml b/Rules/Languages/hu/SharedRules/general.yaml index 0637bf6e2..9013205e2 100644 --- a/Rules/Languages/hu/SharedRules/general.yaml +++ b/Rules/Languages/hu/SharedRules/general.yaml @@ -70,14 +70,14 @@ - name: real-part tag: real-part - match: "." + match: "count(*)=0" replace: - bookmark: "@id" - T: "valós rész" # phrase('the real part' of a complex number does not include the imaginary part) - name: imaginary-part tag: imaginary-part - match: "." + match: "count(*)=0" replace: - bookmark: "@id" - T: "képzetes rész" # phrase('the imaginary part' is part of a complex number) diff --git a/Rules/Languages/hu/SharedRules/geometry.yaml b/Rules/Languages/hu/SharedRules/geometry.yaml index c23f22526..c5a0ac601 100644 --- a/Rules/Languages/hu/SharedRules/geometry.yaml +++ b/Rules/Languages/hu/SharedRules/geometry.yaml @@ -60,7 +60,8 @@ - name: coordinate tag: coordinate - match: "." +# Intent forms coordinate($x,...) use @arg and fall through to function-intent / IntentMappings + match: "not(*[@arg])" replace: - test: if: "$Verbosity='Verbose'" diff --git a/Rules/Languages/hu/definitions.yaml b/Rules/Languages/hu/definitions.yaml index bdc649424..d66738ec4 100644 --- a/Rules/Languages/hu/definitions.yaml +++ b/Rules/Languages/hu/definitions.yaml @@ -1,14 +1,71 @@ --- - include: "../../definitions.yaml" -# If an "intent" is used, the 'terse:medium:verbose' speech for the intent name is given here for a prefix||infix||postfix||function fixity -# If only one ":" is used, the first part is used for 'terse' and the second part is used for 'medium' and 'verbose' -# If no ":"s are used, the same speech is used for all forms -# If bracketing words make sense, they are separated with ";"s -# Intent mappings must specify whether they are "prefix", "infix", "postfix", or "function" with an "=" sign -# If there are multiple fixities (e.g., see transpose), they are separated with "||" -# for readability, spaces can be used around any of the delimiter characters -# Note: if there are multiple fixities, the first one is used if the fixity is not given in the intent +# IntentMappings Syntax: +# +# This section defines how each "intent" is spoken for various grammatical forms (fixities such as "prefix", "infix", "postfix", and "function"), +# along with supporting different verbosity levels. +# The syntax is a little bit complicated, but allows a declarative syntax so you don't have to write as many rules. +# +# For each intent, you specify spoken forms for one or more fixities using the syntax below. +# +# - Each mapping has the form: +# "": "= || = || ...", +# or just +# "": "", +# where is used for all forms if fixity and '=' are omitted. +# +# - If an intent has multiple fixities, separate them with "||". Spaces are allowed around delimiters for readability. +# - If only one ":" is present in **, it provides the 'terse' form, and the following string is used for both 'medium' and 'verbose'. +# - If more than one ":" is present, the string is split into 'terse', 'medium', and 'verbose' forms, in that order (each separated by ":"). +# - If no ":" is present, the same spoken form is used for all styles. +# +# - Use semicolons ";" to divide opening, main, and closing bracketing words within a speech string, where such words make sense. +# - If an intent has multiple fixities but a definition does not specify one, the first fixity listed is chosen by default. +# +# Functions and argument glue: +# - The "|" character delimits options describing how to glue arguments together when speaking function arguments. +# - Arity templates (multiple "|" options, or one option with ','-separated glue words): glue-word count +# implies arity; the final argument is preceded by "of". Example: "sum | over | from,to" +# - 1 arg: "sum of x" +# - 2 args: "sum over i of x" +# - 3 args: "sum from i to n of x" +# If no option matches the argument count, separators fall back to "comma". +# - Binary separator (exactly one "|" option, no commas in it): after "of", that word joins the two args. +# Example: "quotient": "function=integer part | divided by" → "integer part of x divided by y" +# If there are not exactly two args, separators fall back to "comma" (no real n-ary use of these words). +# +# BNF-like description: +# +# IntentMappingsEntry ::= ":" +# +# ::= ( "||" )* +# | +# +# ::= "=" +# +# ::= "prefix" | "infix" | "postfix" | "function" | "nofix" | "silent" +# +# ::= +# | "|" ( "|" )* +# +# ::= text +# # May use ":" to separate terse:medium:verbose forms. +# # May use ";" for bracketing (opening; main; closing). +# +# ::= text +# # One option, no commas: binary separator after "of" (e.g. "divided by"). +# # One option with "," or several "|" options: arity templates +# # (glue-word count = arg_count - 1; last arg preceded by "of"). +# # Unmatched arity (or binary glue with ≠2 args): fall back to "comma". +# +# ::= (applies to all fixities) +# +# Example: +# "absolute-value": "function= ; absolute value: the absolute value: the absolute value; end absolute value" +# "sum": "function=sum | over | from,to" +# "quotient": "function=integer part | divided by" +# - IntentMappings: { "indexed-by": "infix= alsó index kezdete; alsó index; alsó index vége: alsó index vége: alsó index vége", "say-super": "infix=felső index: felső index: felső index", # used with 'mo' for superscripts (e.g, "<") @@ -30,14 +87,14 @@ #"fraction":"function=fraction; over; end fraction", # NOTE: Fails "mixed-fraction":"infix=és", # NOTE: in website says function, but follow infix speech pattern. "greatest-common-divisor": "function=a legnagyobb közös osztó", - "quotient":"function=egész rész osztva", # NOTE: Logic somewhere here failing, becomes "divided by of x comma, y" instead of "integer part of x divided by y" + "quotient":"function=egész rész | osztva", # NOTE: Logic somewhere here failing, becomes "divided by of x comma, y" instead of "integer part of x divided by y" "evaluated-at":"infix=értékelve || postfix=értékként", - "remainder":"function=a maradék, osztva", + "remainder":"function=a maradék | osztva", "max":"function=max", "min":"function=min", "power":"infix=a hatványra", "root":"function=root", - "imaginary-part": "a képzeletbeli rész", + "imaginary-part": "function=a képzeletbeli rész: a képzeletbeli rész: a képzeletbeli rész", "least-common-multiple": "function=lcm: a legkisebb közös többszörös: a legkisebb közös többszörös", "complex-conjugate":"function=Komplex konjugált", "complex-arg":"function=argumentum", @@ -74,15 +131,15 @@ "tends-to-from-below":"infix=alulról indul", ### Sets "set": "function= ; halmaz: a halmaz", - "set-difference":"function=különbséghalmaz || infix=mínusz || postfix=különbséghalmaza", # NOTE: not tested + "set-difference":"function=különbséghalmaz | és || infix=mínusz", "complement":"function=komplemens", - "empty-set":"function=üres halmaz", + "empty-set":"nofix=üres halmaz", "cardinality":"function=számosság", # NOTE: does not have a defined speech template in website "list":"function=lista", "tuple": "function= ; tuple: a tuple", ### Sequence and Series - "sum":"function= ; összegzés : összeg ; ", #: sum over : sum from; to", - "product":"function=szorzat || function=szorzat vége || function=szorzat innen ide", + "sum": "function=összeg", + "product":"function=szorzat", ### Elementary classical functions "sine":"function=szinusz: szinusz", @@ -118,7 +175,7 @@ "variance":"function=variencia", "median":"function=medián", "mode":"function=mód", - "conditional-probability":"function=valószínűség; adott", # NOTE: Check test + "conditional-probability":"function=valószínűség", ### Linear Algebra @@ -133,7 +190,7 @@ "unit-vector":"prefix=egységvektor", "identity-matrix":"nofix=identitásmátrix", # NOTE: no function specified - "transpose":"function=transzponált || postfix=transzponált", # postfix needs testing + "transpose":"postfix=transzponált || function=transzponált", "dimensional-product":"infix=a(z)", # INFIX @@ -164,10 +221,11 @@ ### General Concepts "fenced-group":"function=bekerített csoport", # appears both under general concepts and grouping # NOTE: in site mentions "the pair x and y", due to being defined as function, needs the "of" keyword - "ordered-pair": "function= ; a pár; és", # Needs to be tested, test converts "and" to "comma," + "ordered-pair": "function=a pár | és", # Needs to be tested, test converts "and" to "comma," "highlight":"postfix=kiemelt", "least-common-denominator":"function=legkisebb közös nevező", "rate":"infix=per", + "translation":"function=fordítás", "constraint":"infix= ; feltétellel; ", "binomial-coefficient":"infix=választ", @@ -269,7 +327,7 @@ ## Default fixity nofix "diameter":"nofix=átmérő: átmérő", "distance":"nofix=távolság; távolság: távolság", - "probability":"nofix=P: valószínűség", + "probability":"nofix=P: valószínűség || function=valószínűség", "radius":"nofix=r: sugár", "volume":"nofix=hangerő: hangerő || function=hangerő", "exponential-e":"nofix=e", diff --git a/Rules/Languages/hu/navigate.yaml b/Rules/Languages/hu/navigate.yaml index ff4afb8bb..475e1f625 100644 --- a/Rules/Languages/hu/navigate.yaml +++ b/Rules/Languages/hu/navigate.yaml @@ -60,38 +60,40 @@ - pause: "medium" else: - test: + # CommandOffset is 1 + length of the English NavCommand stem (Zoom/Move/Read/Describe), + # not the spoken Prefix length — so translations can use a different Prefix word. - if: "starts-with($NavCommand, 'Zoom')" - then: [set_variables: [Prefix: "'zoom'"]] # phrase('zoom' in to see more details) + then: [set_variables: [Prefix: "'zoom'", CommandOffset: "5"]] # phrase('zoom' in to see more details) - else_if: "starts-with($NavCommand, 'Move')" - then: [set_variables: [Prefix: "'move'"]] # phrase('move' to next entry in table) + then: [set_variables: [Prefix: "'move'", CommandOffset: "5"]] # phrase('move' to next entry in table) - else_if: "starts-with($NavCommand, 'Read')" - then: [set_variables: [Prefix: "'read'"]] # phrase('read' to next entry in table) + then: [set_variables: [Prefix: "'read'", CommandOffset: "5"]] # phrase('read' to next entry in table) - else_if: "starts-with($NavCommand, 'Describe')" - then: [set_variables: [Prefix: "'describe'"]] # phrase('describe' to next entry in table) + then: [set_variables: [Prefix: "'describe'", CommandOffset: "9"]] # phrase('describe' to next entry in table) - test: if: "$Prefix != ''" then: - x: "$Prefix" - test: - - if: "substring($NavCommand, string-length($Prefix)+1) = 'In'" + - if: "substring($NavCommand, $CommandOffset) = 'In'" then: [T: "ban"] # phrase(zoom 'in' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'InAll'" + - else_if: "substring($NavCommand, $CommandOffset) = 'InAll'" # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets "ed" concatenated to "zoom" - then: [T: "Teljesen betáplálva"] # phrase(zoom 'out all of the way' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Out'" + then: [T: "Teljesen kinagyítva"] # phrase(zoom 'out all of the way' to see more details) + - else_if: "substring($NavCommand, $CommandOffset) = 'Out'" then: [T: "ki"] # phrase(zoom 'out' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'OutAll'" + - else_if: "substring($NavCommand, $CommandOffset) = 'OutAll'" # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets "ed" concatenated to "zoom" - then: [T: "teljes táblázat megjelenítése\uF8FEe ki egészen"] # phrase(zoom 'out all of the way' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Next'" + then: [T: "teljes táblázat kinagyítása"] # phrase(zoom 'out all of the way' to see more details) + - else_if: "substring($NavCommand, $CommandOffset) = 'Next'" then: [T: "jobbra"] # phrase(move to the 'right') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Previous'" + - else_if: "substring($NavCommand, $CommandOffset) = 'Previous'" then: [T: "balra"] # phrase(move to the 'left') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Current'" + - else_if: "substring($NavCommand, $CommandOffset) = 'Current'" then: [T: "jelenlegi"] # phrase(who is the 'current' president) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'LineStart'" + - else_if: "substring($NavCommand, $CommandOffset) = 'LineStart'" then: [T: "a sor elejére"] # phrase(move 'to start of line') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'LineEnd'" + - else_if: "substring($NavCommand, $CommandOffset) = 'LineEnd'" then: [T: "a sor végére"] # phrase(move 'to end of line') - pause: "medium" - set_variables: [MatchCounter: "$MatchCounter + 1"] @@ -103,6 +105,15 @@ (name(.)='mrow' or name(.) = 'mtr' or name(.) = 'mlabeledtr' or @data-from-mathml = 'mtable')" replace: [] +# Prefix/silent intents with no NavigationParts entry (e.g. unary minus, x-hat) +# should not announce "in"/"out of". +- name: into-or-out-of-prefix-or-silent-without-parts + tag: "*" + match: "$Move2D != '' and + (contains(@data-intent-property, ':prefix:') or contains(@data-intent-property, ':silent:')) and + GetNavigationPartName(name(.), count($Child2D/preceding-sibling::*)) = ''" + replace: [] + - name: into-or-out-of-mtr tag: [mtr, mlabeledtr] match: "$Move2D = 'in'" @@ -158,7 +169,21 @@ - else_if: "count(*) = 1" then_test: if: "$NavVerbosity = 'Verbose'" - then: [x: "translate(name(.), '-_', ' ')"] # e.g., "in absolute value" + then: # IntentMappings via SpeakIntentName; falls back to spaced intent name + - test: + - if: "contains(@data-intent-property, ':prefix:')" + then: [x: "SpeakIntentName(name(.), $Verbosity, 'prefix')"] + - else_if: "contains(@data-intent-property, ':postfix:')" + then: [x: "SpeakIntentName(name(.), $Verbosity, 'postfix')"] + - else_if: "contains(@data-intent-property, ':infix:')" + then: [x: "SpeakIntentName(name(.), $Verbosity, 'infix')"] + - else_if: "contains(@data-intent-property, ':function:')" + then: [x: "SpeakIntentName(name(.), $Verbosity, 'function')"] + - else_if: "contains(@data-intent-property, ':nofix:')" + then: [x: "SpeakIntentName(name(.), $Verbosity, 'nofix')"] + - else_if: "contains(@data-intent-property, ':silent:')" + then: [x: "SpeakIntentName(name(.), $Verbosity, 'silent')"] + - else: [x: "SpeakIntentName(name(.), $Verbosity, 'other')"] else: - T: "része" # phrase(the 'part' of the expression) - x: "count($Child2D/preceding-sibling::*) + 1" diff --git a/Rules/Languages/hu/unicode-full.yaml b/Rules/Languages/hu/unicode-full.yaml index 4ab669c7a..23381591d 100644 --- a/Rules/Languages/hu/unicode-full.yaml +++ b/Rules/Languages/hu/unicode-full.yaml @@ -1279,17 +1279,10 @@ - T: "zárójeles" # (en: 'parenthesized', DeepL translation) - SPELL: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" - - "Ⓐ-Ⓩ": # 0x24b6 - 0x24cf - - T: "bekarikázott" - - SPELL: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - "🅐-🅩": # 0x1f150 - 0x1f169 - T: "fekete körrel jelölt" # (en: 'black circled', DeepL translation) - SPELL: "translate('.', '🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 - - T: "bekarikázott" # (en: 'circled', DeepL translation) - - SPELL: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" - "⓪": [T: "bekarikázott nulla"] # 0x24ea (en: 'circled zero', DeepL translation) - "⓫": [T: "fekete kör alakú tizenegyes"] # 0x24eb (en: 'black circled eleven', DeepL translation) - "⓬": [T: "fekete bekarikázott tizenkettő"] # 0x24ec (en: 'black circled twelve', DeepL translation) @@ -3619,3 +3612,203 @@ - "\uE42C": [SPELL: "'←'"] # 0xe42c defer to def of arrow - "\uE42D": [SPELL: "'→'"] # 0xe42d defer to def of arrow - "\uE42E": [SPELL: "'⇄'"] # 0xe42e defer to def of arrow +# Following symbols hungarian translations are restored, because english unicode-full.yaml file again contains this symbols. +# Note: this restoration purpose only to audit translation tool doesn't show this difference with english unicode-full.yaml and hungarian unicode-full.yaml file. +# This symbols are defined too the hungarian unicode.yaml file. + - "¬": [T: "logikai nem"] # 0xac (en: 'not', DeepL translation) + - "´": [T: "éles ékezet"] # 0xb4 (en: 'acute', DeepL translation) + - "·": # 0xB7 + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolDot = 'Auto'" + then: [T: "szorozva"] # (en: 'dot', DeepL translation) + else: [T: "pont"] # (DeepL translation) + - "×": # 0xd7 + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolX = 'Auto'" + then: [T: "szorozva"] + else_test: + if: $ClearSpeak_MultSymbolX = 'By' + then: [T: "szorozva"] + else: [T: "kereszt"] # (en: 'cross', DeepL translation) + - "÷": [T: "osztva"] # 0xf7 (en: 'divided by', DeepL translation) + - "̀": [T: "súlyos ékezet díszítés"] # 0x300 (en: 'grave accent embellishment', DeepL translation) + - "́": [T: "akut ékezet díszítés"] # 0x301 (en: 'acute accent embellishment', DeepL translation) + - "̂": [T: "cirkumflex ékezet díszítés"] # 0x302 (en: 'circumflex accent embellishment', DeepL translation) + - "̃": [T: "tilde"] # 0x303 (en: 'tilde embellishment', DeepL translation) + - "̄": [T: "makron"] # 0x304 (en: 'macron embellishment', DeepL translation) + - "̅": [T: "túlszárnyaló díszítés"] # 0x305 (en: 'overbar embellishment', DeepL translation) + - "̆": [T: "rövid"] # 0x306 (DeepL translation) + - "̇": [T: "pont a díszítés felett"] # 0x307 (en: 'dot above embellishment', DeepL translation) + - "ϖ": [T: "pí"] # 0x3d6 (DeepL translation) + - "ϵ": [T: "holdkóros epszilon"] # 0x3f5 (DeepL translation) + - "϶": [T: "félhold alakú tükrözött görög epszilon"] # 0x3f6 (en: 'reversed epsilon', DeepL translation) + - "…": # 0x2026 + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak '…' as 'and so on...' unless expr starts with '…' + - "../*[1][.='…']" + then: [T: "pont pont pont"] # (en: 'dot dot dot', DeepL translation) + else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' + if: "count(following-sibling::*) = 0" + then: [T: "és így tovább"] # (en: 'and so on', DeepL translation) + else: [T: "és így tovább egészen az alábbi értékig:"] # (en: 'and so on up to', DeepL translation) + - "ℓ": [T: "alsó index l"] # 0x2113 + - "ϕ": [T: "phi"] # 0x3d5 (DeepL translation) + - "⇒": [T: "dupla jobbranyíl"] # 0x21d2 (en: 'right double arrow', DeepL translation) + - "∂": # 0x2202 + - test: + if: "$Verbosity='Terse'" + then: [T: "részleges"] # (en: 'partial', DeepL translation) + else: [T: "parciális derivált"] # (en: 'partial derivative', DeepL translation) + - "∆": # 0x2206 + - test: + if: "following-sibling::*" + then_test: + if: "$Verbosity!='Terse'" + then: [T: "egy laplaciánus"] # "LahPlahsian" sounds better than "laplacian" in speech engines tested + else: [T: "laplaciánus"] + else: [T: "laplaciánus"] + + + - "∉": # 0x2209 + # rule is identical to 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: [T: "nem eleme ennek:"] + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "nincs benne:"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "nem tagja ennek:"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "nem eleme ennek:"] + - else: [T: "nem tartozik hozzá:"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "nem tagja az alábbi halmaznak:"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "nem eleme ennek:"] + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "nincs benne:"] + - else: [T: "nem tartozik hozzá:"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + + - "∊": # 0x220a + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - test: + if: "$Verbosity!='Terse' and not(parent::m:set)" # "the set x is an element of ..." sounds bad + then: [T: "van"] # (en: 'is', DeepL translation) + - T: "egy eleme" # (en: 'an element of', DeepL translation) + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: ""] # (DeepL translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "tagja ennek:"] # (en: 'member of', DeepL translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "eleme ennek:"] # (en: 'element of', DeepL translation) + - else: [T: "hozzátartozó eleme ennek:"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to', DeepL translation) + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "tagja az alábbi halmaznak:"] # (en: 'is a member of', DeepL translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "egy eleme ennek:"] # (en: 'is an element of', DeepL translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "benne van ebben:"] # (en: 'is in', DeepL translation) + - else: [T: "ebbe a halmazba tartozik:"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to', DeepL translation) + - "∐": [T: "diszjunkt unió"] # 0x2210 (en: 'co-product', DeepL translation) + - "√": # 0x221a + - test: + if: "$Verbosity!='Terse'" + then: [T: "a"] # (en: 'the', DeepL translation) + - T: "négyzetgyöke" # (en: 'square root of', DeepL translation) + - "∝": # 0x221d + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', DeepL translation) + - T: "arányos" # (en: 'proportional to', DeepL translation) + - "∶": # 0x2236 + - test: + if: "$Verbosity!='Terse'" + then: [T: "van"] # (en: 'is', DeepL translation) + - T: "hogy" # (DeepL translation) + - "∾": # 0x223e + - test: + if: "$Verbosity!='Terse'" + then: [T: "van"] # (en: 'is', DeepL translation) + - T: "legpozitívabb" # (en: 'most positive', DeepL translation) + - "≠": # 0x2260 + - test: + if: "$Verbosity!='Terse'" + then: [T: "van"] # (en: 'is', DeepL translation) + - T: "nem egyenlő" # (en: 'not equal to', DeepL translation) + - "≡": # 0x2261 + - test: + if: "$Verbosity!='Terse'" + then: [T: "van"] # (en: 'is', DeepL translation) + - T: "azonos" # (en: 'identical to', DeepL translation) + - "⊂": # 0x2282 + - test: + if: "$Verbosity!='Terse'" + then: [T: "egy"] # (DeepL translation) + - T: "részhalmaza" # (en: 'subset of', DeepL translation) + - "⊃": # 0x2283 + - test: + if: "$Verbosity!='Terse'" + then: [T: "egy"] # (DeepL translation) + - T: "szuperhalmaza ennek:" # (en: 'superset of', DeepL translation) + - "⊄": # 0x2284 + - test: + if: "$Verbosity!='Terse'" + then: [T: "egy"] # (en: 'is', DeepL translation) + - T: "nem részhalmaza ennek:" # (en: 'not a subset of', DeepL translation) + - "⊅": # 0x2285 + - test: + if: "$Verbosity!='Terse'" + then: [T: "egy"] # (en: 'is', DeepL translation) + - T: "nem szuperhalmaza ennek:" # (DeepL translation) + - "⊆": # 0x2286 + - test: + if: "$Verbosity!='Terse'" + then: [T: "egy"] # (DeepL translation) + - T: "részhalmaza vagy egyenlő" # (en: 'subset of or equal to', DeepL translation) + - "⊇": # 0x2287 + - test: + if: "$Verbosity!='Terse'" + then: [T: "egy"] # (DeepL translation) + - T: "szuperhalmaza vagy egyenlő" # (en: 'superset of or equal to', DeepL translation) + - "ⅆ": [T: "d"] # 0x2146 + - "": [T: "e"] # 0xed11 + - "ⅈ": [T: "i"] # 0x2148 + - "-": # 0xf52e - 0xf537 (old MathType) + - test: + if: "not($IgnoreBold)" + then: [T: "félkövér"] + - SPELL: "translate('.', '', '0123456789')" + - "ⅇ": [T: "e"] # 0x2147 + - "Ⓐ-ⓩ": # 0x24b6 - 0x24cf + - T: "bekarikázott" + - SPELL: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 + - T: "bekarikázott" + - SPELL: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" + + + + + + + + + + + + diff --git a/tests/Languages/hu/ClearSpeak/sets.rs b/tests/Languages/hu/ClearSpeak/sets.rs index c2b9d589a..844e2a51c 100644 --- a/tests/Languages/hu/ClearSpeak/sets.rs +++ b/tests/Languages/hu/ClearSpeak/sets.rs @@ -223,7 +223,7 @@ fn set_with_colon() -> Result<()> { let expr = " { x:x>2 } "; - test("hu", "ClearSpeak", expr, "x melyekre teljesül, hogy minden x nagyobb, mint 2")?; + test("hu", "ClearSpeak", expr, "minden x melyekre teljesül, hogy x nagyobb, mint 2")?; return Ok(()); } @@ -234,7 +234,7 @@ fn set_with_bar() -> Result<()> { let expr = " { x|x>2 } "; - test("hu", "ClearSpeak", expr, "x melyekre teljesül, hogy minden x nagyobb, mint 2")?; + test("hu", "ClearSpeak", expr, "minden x melyekre teljesül, hogy x nagyobb, mint 2")?; return Ok(()); } @@ -285,7 +285,7 @@ fn complicated_set_with_colon() -> Result<()> { 7 } "; - test("hu", "ClearSpeak", expr, "x az egész számok halmaza melyekre teljesül, hogy minden 2 kisebb, mint x kisebb, mint 7")?; + test("hu", "ClearSpeak", expr, "minden x az egész számok halmaza melyekre teljesül, hogy 2 kisebb, mint x kisebb, mint 7")?; return Ok(()); } @@ -302,7 +302,7 @@ fn complicated_set_with_mtext() -> Result<()> { } "; test("hu", "ClearSpeak", expr, - "x a természetes számok halmaza melyekre teljesül, hogy minden x páros szám")?; + "minden x a természetes számok halmaza melyekre teljesül, hogy x páros szám")?; return Ok(()); } @@ -323,7 +323,7 @@ fn set_with_bar_member() -> Result<()> { } "; test_ClearSpeak("hu", "ClearSpeak_SetMemberSymbol", "Member", - expr, "x tagja az egész számok halmaza melyekre teljesül, hogy minden x nagyobb, mint 5")?; + expr, "minden x tagja az egész számok halmaza melyekre teljesül, hogy x nagyobb, mint 5")?; return Ok(()); } @@ -375,7 +375,7 @@ fn set_with_bar_element() -> Result<()> { } "; test_ClearSpeak("hu", "ClearSpeak_SetMemberSymbol", "Element", - expr, "x eleme ennek:, az egész számok halmaza melyekre teljesül, hogy minden x nagyobb, mint 5")?; + expr, "minden x eleme ennek:, az egész számok halmaza melyekre teljesül, hogy x nagyobb, mint 5")?; return Ok(()); } @@ -426,7 +426,7 @@ fn set_with_bar_in() -> Result<()> { } "; test_ClearSpeak("hu", "ClearSpeak_SetMemberSymbol", "In", - expr, "x az egész számok halmaza melyekre teljesül, hogy minden x nagyobb, mint 5")?; + expr, "minden x az egész számok halmaza melyekre teljesül, hogy x nagyobb, mint 5")?; return Ok(()); } @@ -477,7 +477,7 @@ fn set_with_bar_belongs() -> Result<()> { } "; test_ClearSpeak("hu", "ClearSpeak_SetMemberSymbol", "Belongs", - expr, "x hozzátartozó eleme ennek:, az egész számok halmaza melyekre teljesül, hogy minden x nagyobb, mint 5")?; + expr, "minden x hozzátartozó eleme ennek:, az egész számok halmaza melyekre teljesül, hogy x nagyobb, mint 5")?; return Ok(()); } @@ -563,7 +563,7 @@ fn silent_bracket() -> Result<()> { {x|x>2} "; test_ClearSpeak("hu", "ClearSpeak_Sets", "SilentBracket", expr, - "x melyekre teljesül, hogy minden x nagyobb, mint 2")?; + "minden x melyekre teljesül, hogy x nagyobb, mint 2")?; return Ok(()); } diff --git a/tests/Languages/hu/ClearSpeak/symbols_and_adornments.rs b/tests/Languages/hu/ClearSpeak/symbols_and_adornments.rs index ff38686c6..e137a3dd3 100644 --- a/tests/Languages/hu/ClearSpeak/symbols_and_adornments.rs +++ b/tests/Languages/hu/ClearSpeak/symbols_and_adornments.rs @@ -233,7 +233,7 @@ fn vertical_line_set() -> Result<()> { } "; test_ClearSpeak("hu", "ClearSpeak_VerticalLine", "Auto", expr, - "x melyekre teljesül, hogy minden x nagyobb, mint 0")?; + "minden x melyekre teljesül, hogy x nagyobb, mint 0")?; return Ok(()); } @@ -254,7 +254,7 @@ fn vertical_line_set_such_that() -> Result<()> { } "; test_ClearSpeak("hu", "ClearSpeak_VerticalLine", "SuchThat", expr, - "x melyekre teljesül, hogy minden x nagyobb, mint 0")?; + "minden x melyekre teljesül, hogy x nagyobb, mint 0")?; return Ok(()); } @@ -275,7 +275,7 @@ fn vertical_line_set_given() -> Result<()> { "; // the rules for set will override all the options -- ClearSpeak spec should be clarified test_ClearSpeak("hu", "ClearSpeak_VerticalLine", "Given", expr, - "x melyekre teljesül, hogy minden x nagyobb, mint 0")?; + "minden x melyekre teljesül, hogy x nagyobb, mint 0")?; return Ok(()); } @@ -299,7 +299,7 @@ fn vertical_line_set_and_abs() -> Result<()> { } "; test_ClearSpeak("hu", "ClearSpeak_VerticalLine", "Auto", expr, - "x melyekre teljesül, hogy minden x abszolút értéke; nagyobb, mint 2")?; + "minden x melyekre teljesül, hogy x abszolút értéke; nagyobb, mint 2")?; return Ok(()); } diff --git a/tests/Languages/hu/definitions.rs b/tests/Languages/hu/definitions.rs index 542f41885..62f910184 100644 --- a/tests/Languages/hu/definitions.rs +++ b/tests/Languages/hu/definitions.rs @@ -32,7 +32,7 @@ fn my_set_basic() -> Result<()> { "#; - test("hu", "ClearSpeak", expr, "az üres halmaz")?; + test("hu", "ClearSpeak", expr, "a halmaz x vessző, y")?; Ok(()) } @@ -91,7 +91,7 @@ fn set_difference_basic() -> Result<()> { "#; - test( "hu", "ClearSpeak", expr, "különbséghalmaz nagy a vessző, nagy b")?; + test( "hu", "ClearSpeak", expr, "különbséghalmaz nagy a és nagy b")?; Ok(()) } @@ -107,7 +107,7 @@ fn postfix_test() -> Result<()> { T "#, - "transzponált x", + "x transzponált", ), ( "highlight", @@ -205,9 +205,9 @@ fn functions_and_inverses_tests() -> Result<()> { //("fraction", "fraction x over y end fraction"), ("mixed-fraction", "x és y"), - ("quotient", "egész rész osztva x vessző, y"), + ("quotient", "egész rész x osztva y"), ("evaluated-at", "x értékelve y"), - ("remainder", "a maradék, osztva x vessző, y"), + ("remainder", "a maradék x osztva y"), ("max", "max x vessző, y vessző, z"), ("min", "min x vessző, y vessző, z"), @@ -223,13 +223,13 @@ fn functions_and_inverses_tests() -> Result<()> { ("complex-conjugate", "Komplex konjugált x"), ("complex-arg", "argumentum x"), - ("real-part", "valós rész"), - ("imaginary-part", "képzetes rész"), + ("real-part", "az igazi rész x"), + ("imaginary-part", "a képzeletbeli rész x"), ("polar-coordinate", "poláris koordináta x vessző, y"), ("spherical-coordinate", "gömb koordináta x vessző, y vessző, z"), ("cartesian-coordinate", "derékszögű koordináta x vessző, y vessző, z"), - ("coordinate", "pont, x vessző y vessző z"), + ("coordinate", "koordináta x vessző, y vessző, z"), ("floor", "lépcső x"), ("ceiling", "mennyezet x"), @@ -528,7 +528,7 @@ fn statistics_and_probability_tests() -> Result<()> { ("mode", "mód x"), // conditional probability typically two arguments - // ("conditional-probability", "probability of x given y"), + // ("conditional-probability", "valószínűség x adott y"), ]; for (intent, expected) in tests { @@ -576,7 +576,7 @@ fn linear_algebra_tests() -> Result<()> { ("span", "fesztávolság x"), // transpose supports both postfix and function; we test function explicitly - ("transpose", "transzponált x"), + ("transpose", "x transzponált"), // dimensional product is infix ("dimensional-product", "x a(z) y"), @@ -727,13 +727,13 @@ fn general_concepts_tests() -> Result<()> { ("permutation-cycle", "permutációs ciklus x"), // Binary structural / infix-style - // ("ordered-pair", "the pair of x and y"), + ("ordered-pair", "a pár x és y"), ("rate", "x per y"), ("binomial-coefficient", "x választ y"), ("embellished-name", "x megjegyzéssel y"), ("indexed-by", "x alsó index y"), - // ("translation", "translation by x comma, y"), // Changes translation to comma + ("translation", "fordítás x vessző, y"), // Changes translation to comma ("constraint", "x feltétellel y"), ]; diff --git a/tests/Languages/hu/shared.rs b/tests/Languages/hu/shared.rs index 23439e489..087a203a5 100644 --- a/tests/Languages/hu/shared.rs +++ b/tests/Languages/hu/shared.rs @@ -22,7 +22,7 @@ fn modified_vars() -> Result<()> { t → "; test("hu", "SimpleSpeak", expr, - "a súlyozott, b tilde, c rövid, b ellenőrzés, c súlyozott; plusz, r hacsek karakter mint repülő ékezet; plusz; x pont, y pont, z dupla pont, u hármas pont, v négyes pont; plusz x kalap, plusz vektor kezdete t")?; + "a súlyozott, b tilde, c rövid, b ellenőrzés, c súlyozott; plusz, r hacsek karakter mint repülő ékezet, plusz; x pont, y pont, z dupla pont, u hármas pont, v négyes pont; plusz x kalap, plusz vektor kezdete t")?; return Ok(()); } @@ -483,7 +483,7 @@ fn literal_speak_perpendicular() -> Result<()> { "#; - test("hu", "LiteralSpeak", expr, "nagy a jobbra nyíl; merőleges nagy b jobbra nyíl")?; + test("hu", "LiteralSpeak", expr, "nagy a jobbra nyíl, merőleges nagy b jobbra nyíl")?; return Ok(()); } @@ -569,7 +569,7 @@ fn literal_intent_property() -> Result<()> { "#; - test("hu", "SimpleSpeak", expr, "nagy a jobbra nyíl; merőleges nagy b jobbra nyíl")?; + test("hu", "SimpleSpeak", expr, "nagy a jobbra nyíl, merőleges nagy b jobbra nyíl")?; return Ok(()); } From adbf1e5bd0a4582b01d03b42314c008051580218 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Mon, 17 Aug 2026 14:16:39 -0700 Subject: [PATCH 039/157] move to release candidate --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index b5b30304f..45de0ad1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mathcat" -version = "0.7.6-beta.9" +version = "0.7.6-rc.1" authors = ["Neil Soiffer "] license = "MIT" description = "MathCAT: Math Capable Assistive Technology ('Speech and braille from MathML')" From 2267de346891b8829294b572be10d08c251bf0eb Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Mon, 17 Aug 2026 15:38:16 -0700 Subject: [PATCH 040/157] Added creation of minified yaml files for an alternative Rules.zip --- .github/workflows/rust.yml | 49 +++++++++++++++++++++++++++++++++--- AGENTS.md | 1 + PythonScripts/pyproject.toml | 3 ++- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 5a9f85b4a..2fbdcbd22 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -46,12 +46,15 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 + - uses: astral-sh/setup-uv@v10.0.1 - name: Remove empty Rules directories run: find Rules -type d -empty -delete - name: Remove test directory run: rm -r Rules/Languages/zz - - name: create Rules.zip - run: zip -r Rules.zip Rules + - name: Create Rules.zip + run: uv run --project PythonScripts package-rules Rules Rules.zip + - name: Create Rules-minimized.zip + run: uv run --project PythonScripts package-rules Rules Rules-minimized.zip --minimize - name: Upload Rules.zip uses: actions/upload-artifact@v7 with: @@ -59,12 +62,45 @@ jobs: path: 'Rules.zip' compression-level: 0 retention-days: 1 + - name: Upload Rules-minimized.zip + uses: actions/upload-artifact@v7 + with: + name: 'Rules-minimized.zip' + path: 'Rules-minimized.zip' + compression-level: 0 + retention-days: 1 + + test-rules-package: + name: Test (${{ matrix.feature_name }}, ${{ matrix.rules_zip }}) + needs: zip-rules + strategy: + fail-fast: false + matrix: + rules_zip: [Rules.zip, Rules-minimized.zip] + include: + - feature_name: default + features: "" + - feature_name: no-unsafe + features: "--features no-unsafe" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - name: Download ${{ matrix.rules_zip }} + uses: actions/download-artifact@v8 + with: + name: ${{ matrix.rules_zip }} + - name: Install packaged Rules + run: | + rm -rf Rules + unzip -q "${{ matrix.rules_zip }}" + - name: Run tests (${{ matrix.feature_name }}) + run: cargo test ${{ matrix.features }} --verbose pre-release: name: Pre Release continue-on-error: false if: github.event_name == 'push' && github.ref == 'refs/heads/main' # otherwise, job fails on pull requests, as GITHUB_TOKEN is not available - needs: [build, clippy, zip-rules] + needs: [build, clippy, zip-rules, test-rules-package] runs-on: ubuntu-latest permissions: contents: write @@ -73,6 +109,10 @@ jobs: uses: actions/download-artifact@v8 with: name: Rules.zip + - name: download Rules-minimized.zip + uses: actions/download-artifact@v8 + with: + name: Rules-minimized.zip # Moving 'latest' prerelease (replaces marvinpinto/action-automatic-releases) - name: Development Build release env: @@ -90,4 +130,5 @@ jobs: --latest=false \ --title "Development Build" \ --notes "Development build from ${SHA}" \ - Rules.zip + Rules.zip \ + Rules-minimized.zip diff --git a/AGENTS.md b/AGENTS.md index 0696e6979..6cb6f5381 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,6 +13,7 @@ but add common mistakes of AI agents here instead. - `ClearSpeak_Rules.yaml`, `SimpleSpeak_Rules.yaml` - `SharedRules/`, `unicode.yaml`, `unicode-full.yaml`, `definitions.yaml`, `navigate.yaml` - `build.rs` can bundle rules into `rules.zip` when `include-zip` is enabled. +- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (flow-style `Languages/**/unicode*.yaml` only) via `uv run --project PythonScripts package-rules Rules [--minimize]`. ## Translation Conventions - `t:` means untranslated or unverified. diff --git a/PythonScripts/pyproject.toml b/PythonScripts/pyproject.toml index 7b9adf68d..8f754577c 100644 --- a/PythonScripts/pyproject.toml +++ b/PythonScripts/pyproject.toml @@ -22,6 +22,7 @@ dependencies = [ [project.scripts] audit-translations = "audit_translations.cli:main" +package-rules = "rules_packaging.cli:main" [dependency-groups] dev = [ @@ -37,7 +38,7 @@ build-backend = "uv_build" exclude-newer = "1 week" [tool.uv.build-backend] -module-name = "audit_translations" +module-name = ["audit_translations", "rules_packaging"] module-root = "" [tool.ruff] From 487ce7102fbc409a9819fd2316cce03176ac7441 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Mon, 17 Aug 2026 15:41:28 -0700 Subject: [PATCH 041/157] fix build problem --- PythonScripts/pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PythonScripts/pyproject.toml b/PythonScripts/pyproject.toml index 8f754577c..dced0ef1f 100644 --- a/PythonScripts/pyproject.toml +++ b/PythonScripts/pyproject.toml @@ -22,7 +22,7 @@ dependencies = [ [project.scripts] audit-translations = "audit_translations.cli:main" -package-rules = "rules_packaging.cli:main" +package-rules = "audit_translations.rules_packaging.cli:main" [dependency-groups] dev = [ @@ -31,14 +31,14 @@ dev = [ ] [build-system] -requires = ["uv_build>=0.9.25,<0.10.0"] +requires = ["uv_build>=0.9.25,<0.13"] build-backend = "uv_build" [tool.uv] exclude-newer = "1 week" [tool.uv.build-backend] -module-name = ["audit_translations", "rules_packaging"] +module-name = "audit_translations" module-root = "" [tool.ruff] From 65250fc7852a40be50bbf425bcc6aae46bcff7d7 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Mon, 17 Aug 2026 15:50:13 -0700 Subject: [PATCH 042/157] try again for creation of minified yaml files for an alternative Rules.zip --- .github/workflows/rust.yml | 4 ++-- AGENTS.md | 2 +- PythonScripts/pyproject.toml | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 2fbdcbd22..92f53f247 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -52,9 +52,9 @@ jobs: - name: Remove test directory run: rm -r Rules/Languages/zz - name: Create Rules.zip - run: uv run --project PythonScripts package-rules Rules Rules.zip + run: uv run PythonScripts/package_rules.py Rules Rules.zip - name: Create Rules-minimized.zip - run: uv run --project PythonScripts package-rules Rules Rules-minimized.zip --minimize + run: uv run PythonScripts/package_rules.py Rules Rules-minimized.zip --minimize - name: Upload Rules.zip uses: actions/upload-artifact@v7 with: diff --git a/AGENTS.md b/AGENTS.md index 6cb6f5381..270ebd606 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,7 +13,7 @@ but add common mistakes of AI agents here instead. - `ClearSpeak_Rules.yaml`, `SimpleSpeak_Rules.yaml` - `SharedRules/`, `unicode.yaml`, `unicode-full.yaml`, `definitions.yaml`, `navigate.yaml` - `build.rs` can bundle rules into `rules.zip` when `include-zip` is enabled. -- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (flow-style `Languages/**/unicode*.yaml` only) via `uv run --project PythonScripts package-rules Rules [--minimize]`. +- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (flow-style `Languages/**/unicode*.yaml` only) via `uv run PythonScripts/package_rules.py Rules [--minimize]`. ## Translation Conventions - `t:` means untranslated or unverified. diff --git a/PythonScripts/pyproject.toml b/PythonScripts/pyproject.toml index dced0ef1f..7b9adf68d 100644 --- a/PythonScripts/pyproject.toml +++ b/PythonScripts/pyproject.toml @@ -22,7 +22,6 @@ dependencies = [ [project.scripts] audit-translations = "audit_translations.cli:main" -package-rules = "audit_translations.rules_packaging.cli:main" [dependency-groups] dev = [ @@ -31,7 +30,7 @@ dev = [ ] [build-system] -requires = ["uv_build>=0.9.25,<0.13"] +requires = ["uv_build>=0.9.25,<0.10.0"] build-backend = "uv_build" [tool.uv] From 0bac005d9cc07e734e7b0b29264280fd7a760f0b Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Mon, 17 Aug 2026 16:00:34 -0700 Subject: [PATCH 043/157] try again -- needs to run on linux --- .github/workflows/rust.yml | 4 ++-- AGENTS.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 92f53f247..8b3d6600b 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -52,9 +52,9 @@ jobs: - name: Remove test directory run: rm -r Rules/Languages/zz - name: Create Rules.zip - run: uv run PythonScripts/package_rules.py Rules Rules.zip + run: uv run --script PythonScripts/package_rules.py Rules Rules.zip - name: Create Rules-minimized.zip - run: uv run PythonScripts/package_rules.py Rules Rules-minimized.zip --minimize + run: uv run --script PythonScripts/package_rules.py Rules Rules-minimized.zip --minimize - name: Upload Rules.zip uses: actions/upload-artifact@v7 with: diff --git a/AGENTS.md b/AGENTS.md index 270ebd606..a5632ced5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,7 +13,7 @@ but add common mistakes of AI agents here instead. - `ClearSpeak_Rules.yaml`, `SimpleSpeak_Rules.yaml` - `SharedRules/`, `unicode.yaml`, `unicode-full.yaml`, `definitions.yaml`, `navigate.yaml` - `build.rs` can bundle rules into `rules.zip` when `include-zip` is enabled. -- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (flow-style `Languages/**/unicode*.yaml` only) via `uv run PythonScripts/package_rules.py Rules [--minimize]`. +- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (flow-style `Languages/**/unicode*.yaml` only) via `uv run --script PythonScripts/package_rules.py Rules [--minimize]`. ## Translation Conventions - `t:` means untranslated or unverified. From 80b749aec6bbb6aa453a8f7c354ee8426751755d Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Mon, 17 Aug 2026 16:13:25 -0700 Subject: [PATCH 044/157] Add standalone Rules packaging script --- PythonScripts/package_rules.py | 50 ++++++++ PythonScripts/rules_packaging/__init__.py | 5 + PythonScripts/rules_packaging/minimize.py | 108 ++++++++++++++++++ PythonScripts/rules_packaging/package.py | 47 ++++++++ .../rules_packaging/tests/__init__.py | 1 + .../rules_packaging/tests/test_package.py | 101 ++++++++++++++++ 6 files changed, 312 insertions(+) create mode 100644 PythonScripts/package_rules.py create mode 100644 PythonScripts/rules_packaging/__init__.py create mode 100644 PythonScripts/rules_packaging/minimize.py create mode 100644 PythonScripts/rules_packaging/package.py create mode 100644 PythonScripts/rules_packaging/tests/__init__.py create mode 100644 PythonScripts/rules_packaging/tests/test_package.py diff --git a/PythonScripts/package_rules.py b/PythonScripts/package_rules.py new file mode 100644 index 000000000..905a7bc90 --- /dev/null +++ b/PythonScripts/package_rules.py @@ -0,0 +1,50 @@ +# /// script +# requires-python = ">=3.14" +# dependencies = ["pyyaml"] +# /// +"""Package MathCAT Rules/ into Rules.zip or Rules-minimized.zip.""" + +from __future__ import annotations + +import argparse +import sys +from pathlib import Path + +# Standalone script: sibling package, not installed via audit_translations. +sys.path.insert(0, str(Path(__file__).resolve().parent)) + +from rules_packaging.package import package_rules # noqa: E402 + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser( + description="Package MathCAT Rules/ into a zip archive. " + "Use --minimize for flow-style unicode.yaml / unicode-full.yaml without comments." + ) + parser.add_argument("source", type=Path, help="Path to the Rules directory") + parser.add_argument("output", type=Path, help="Output zip file path (e.g. Rules.zip)") + parser.add_argument( + "--minimize", + action="store_true", + help="Emit compact flow-style YAML (comments and block formatting removed)", + ) + args = parser.parse_args(argv) + + try: + stats = package_rules(args.source, args.output, minimize=args.minimize) + except (FileNotFoundError, ValueError) as exc: + print(f"error: {exc}", file=sys.stderr) + return 1 + + label = "minimized" if args.minimize else "standard" + print(f"Created {label} archive: {args.output}") + if args.minimize: + print(f" minimized YAML files: {stats['minimized_yaml_files']}") + print(f" copied verbatim: {stats['copied_files']}") + for warning in stats["warnings"]: + print(f" warning: {warning}", file=sys.stderr) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/PythonScripts/rules_packaging/__init__.py b/PythonScripts/rules_packaging/__init__.py new file mode 100644 index 000000000..07c96c9d2 --- /dev/null +++ b/PythonScripts/rules_packaging/__init__.py @@ -0,0 +1,5 @@ +"""Standalone Rules zip packaging and YAML minimization (not part of audit_translations).""" + +from .package import package_rules + +__all__ = ["package_rules"] diff --git a/PythonScripts/rules_packaging/minimize.py b/PythonScripts/rules_packaging/minimize.py new file mode 100644 index 000000000..7fb6a05d5 --- /dev/null +++ b/PythonScripts/rules_packaging/minimize.py @@ -0,0 +1,108 @@ +"""Convert MathCAT Rules YAML files to compact flow-style form.""" + +from __future__ import annotations + +import re +from pathlib import Path +from typing import Any + +import yaml + +YAML_SUFFIXES = {".yaml", ".yml"} +MINIMIZE_NAMES = {"unicode.yaml", "unicode-full.yaml"} + + +def should_minimize(path: Path) -> bool: + if path.suffix.lower() not in YAML_SUFFIXES or path.name not in MINIMIZE_NAMES: + return False + # Speech unicode only — braille unicode.yaml keeps block form (tests and edits rely on it). + return "Languages" in path.parts + + +def _configure_yaml_dumper() -> None: + """Quote all strings so yaml-rust does not treat words like 'infinity' as floats.""" + + def represent_str(dumper: yaml.SafeDumper, data: str) -> yaml.nodes.ScalarNode: + return dumper.represent_scalar("tag:yaml.org,2002:str", data, style='"') + + yaml.add_representer(str, represent_str, Dumper=yaml.SafeDumper) + + +_configure_yaml_dumper() + + +def preprocess_for_load(text: str) -> str: + """Normalize MathCAT YAML quirks so PyYAML can parse it.""" + text = text.replace("\t", " ") + # Bare double-quote or colon used as a mapping key in unicode list entries. + text = re.sub(r'(?m)^(\s*-\s*)":(\s*:\s*)', r'\1"\\"":\2', text) + text = re.sub(r'(?m)^(\s*-\s*)\\"(\s*:\s*)', r'\1"\\""\2', text) + return text + + +def load_yaml(text: str) -> Any: + """Load YAML using PyYAML with MathCAT-specific normalizations.""" + candidates = (text, text.replace("\t", " "), preprocess_for_load(text)) + last_error: yaml.YAMLError | None = None + for candidate in candidates: + try: + return yaml.safe_load(candidate) + except yaml.YAMLError as exc: + last_error = exc + if last_error is not None: + raise last_error + return None + + +def dump_flow_style(data: Any) -> str: + """Emit minimized flow-style YAML without comments.""" + if data is None: + return "" + dumped = yaml.dump( + data, + allow_unicode=True, + default_flow_style=True, + width=10**9, + sort_keys=False, + Dumper=yaml.SafeDumper, + ) + return dumped if dumped.endswith("\n") else f"{dumped}\n" + + +def minimize_yaml_text(text: str) -> tuple[str, bool]: + """Return flow-style YAML and whether parsing succeeded.""" + try: + data = load_yaml(text) + except yaml.YAMLError: + return text, False + return dump_flow_style(data), True + + +def copy_rules_tree(source: Path, destination: Path, *, minimize: bool) -> tuple[int, int, list[str]]: + """Copy ``source`` Rules tree to ``destination``, optionally minimizing YAML.""" + minimized = 0 + copied = 0 + warnings: list[str] = [] + + for src_path in sorted(source.rglob("*")): + if src_path.is_dir(): + continue + rel = src_path.relative_to(source) + dest_path = destination / rel + dest_path.parent.mkdir(parents=True, exist_ok=True) + + if minimize and should_minimize(src_path): + text = src_path.read_text(encoding="utf-8") + out, ok = minimize_yaml_text(text) + if ok: + dest_path.write_text(out, encoding="utf-8", newline="\n") + minimized += 1 + else: + dest_path.write_bytes(src_path.read_bytes()) + warnings.append(f"could not minimize {rel}; copied verbatim") + copied += 1 + else: + dest_path.write_bytes(src_path.read_bytes()) + copied += 1 + + return minimized, copied, warnings diff --git a/PythonScripts/rules_packaging/package.py b/PythonScripts/rules_packaging/package.py new file mode 100644 index 000000000..9b3c47f9d --- /dev/null +++ b/PythonScripts/rules_packaging/package.py @@ -0,0 +1,47 @@ +"""Create Rules.zip archives from a Rules directory tree.""" + +from __future__ import annotations + +import shutil +import tempfile +import zipfile +from pathlib import Path + +from .minimize import copy_rules_tree + + +def zip_directory(source_dir: Path, zip_path: Path) -> None: + """Write ``source_dir`` contents into ``zip_path`` preserving relative paths.""" + zip_path.parent.mkdir(parents=True, exist_ok=True) + with zipfile.ZipFile(zip_path, "w", compression=zipfile.ZIP_DEFLATED, compresslevel=9) as archive: + for path in sorted(source_dir.rglob("*")): + if path.is_file(): + archive.write(path, path.relative_to(source_dir.parent).as_posix()) + + +def package_rules(source: Path, output: Path, *, minimize: bool = False) -> dict[str, int | list[str]]: + """Package ``source`` (Rules directory) into ``output`` zip file.""" + source = source.resolve() + output = output.resolve() + + if not source.is_dir(): + raise FileNotFoundError(f"Rules source directory not found: {source}") + if source.name != "Rules": + raise ValueError(f"Expected a directory named 'Rules', got '{source.name}'") + + with tempfile.TemporaryDirectory(prefix="mathcat-rules-") as tmp: + staging_root = Path(tmp) + staged_rules = staging_root / "Rules" + if minimize: + minimized, copied, warnings = copy_rules_tree(source, staged_rules, minimize=True) + else: + shutil.copytree(source, staged_rules) + minimized, copied, warnings = 0, sum(1 for p in staged_rules.rglob("*") if p.is_file()), [] + + zip_directory(staged_rules, output) + + return { + "minimized_yaml_files": minimized, + "copied_files": copied, + "warnings": warnings, + } diff --git a/PythonScripts/rules_packaging/tests/__init__.py b/PythonScripts/rules_packaging/tests/__init__.py new file mode 100644 index 000000000..b5d3c1aa2 --- /dev/null +++ b/PythonScripts/rules_packaging/tests/__init__.py @@ -0,0 +1 @@ +"""Tests for rules packaging.""" diff --git a/PythonScripts/rules_packaging/tests/test_package.py b/PythonScripts/rules_packaging/tests/test_package.py new file mode 100644 index 000000000..a8364c93a --- /dev/null +++ b/PythonScripts/rules_packaging/tests/test_package.py @@ -0,0 +1,101 @@ +"""Tests for Rules packaging and YAML minimization.""" + +from __future__ import annotations + +import zipfile +from pathlib import Path + +import yaml + +from rules_packaging.minimize import dump_flow_style, load_yaml, minimize_yaml_text +from rules_packaging.package import package_rules + + +def test_minimize_yaml_strips_comments_and_uses_flow_style() -> None: + """Minimized YAML drops comments and uses flow-style collections.""" + source = """--- +# comment + - \"+\": [t: \"plus\"] # inline +""" + minimized, ok = minimize_yaml_text(source) + assert ok + assert "#" not in minimized + assert "[" in minimized and "{" in minimized or "t:" in minimized + assert load_yaml(minimized) == load_yaml(source) + + +def test_package_rules_standard_zip_layout(tmp_path: Path) -> None: + """Standard packaging preserves Rules/ prefix inside the zip.""" + rules = tmp_path / "Rules" + rules.mkdir() + (rules / "prefs.yaml").write_text("- SpeechStyle: [t: \"ClearSpeak\"]\n", encoding="utf-8") + + output = tmp_path / "Rules.zip" + package_rules(rules, output, minimize=False) + + with zipfile.ZipFile(output) as archive: + names = archive.namelist() + assert "Rules/prefs.yaml" in names + + +def test_dump_flow_style_quotes_infinity() -> None: + """Flow-style dump must quote 'infinity' so yaml-rust does not read it as a float.""" + minimized = dump_flow_style([{"∞": [{"t": "infinity"}]}]) + assert '"infinity"' in minimized + assert "t: infinity" not in minimized + + +def test_should_not_minimize_braille_unicode(tmp_path: Path) -> None: + """Braille unicode.yaml is copied verbatim even when minimization is enabled.""" + rules = tmp_path / "Rules" + braille = rules / "Braille" / "Nemeth" + braille.mkdir(parents=True) + source = """--- + - "1": [t: "N⠂"] +""" + (braille / "unicode.yaml").write_text(source, encoding="utf-8") + + output = tmp_path / "Rules-minimized.zip" + stats = package_rules(rules, output, minimize=True) + + assert stats["minimized_yaml_files"] == 0 + with zipfile.ZipFile(output) as archive: + text = archive.read("Rules/Braille/Nemeth/unicode.yaml").decode("utf-8") + assert text.replace("\r\n", "\n") == source.replace("\r\n", "\n") + + +def test_package_rules_minimized_smaller_than_standard(tmp_path: Path) -> None: + """Minimized archives use flow-style YAML and are not larger than standard.""" + rules = tmp_path / "Rules" + lang = rules / "Languages" / "en" + lang.mkdir(parents=True) + (lang / "unicode.yaml").write_text( + """--- +# header comment + - \"+\": [t: \"plus\"] # trailing + - \"-\": [t: \"minus\"] +""", + encoding="utf-8", + ) + (lang / "definitions.yaml").write_text( + """--- + - AdditionalFunctionNames: + - real=inf +""", + encoding="utf-8", + ) + + standard = tmp_path / "Rules.zip" + minimized = tmp_path / "Rules-minimized.zip" + package_rules(rules, standard, minimize=False) + stats = package_rules(rules, minimized, minimize=True) + + assert stats["minimized_yaml_files"] == 1 + assert minimized.stat().st_size <= standard.stat().st_size + + with zipfile.ZipFile(minimized) as archive: + unicode_text = archive.read("Rules/Languages/en/unicode.yaml").decode("utf-8") + defs_text = archive.read("Rules/Languages/en/definitions.yaml").decode("utf-8") + assert "#" not in unicode_text + assert "real=inf" in defs_text + assert yaml.safe_load(unicode_text) is not None From b1f15e94c7b6a79ee77b62eeed773ee7605bdb90 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Mon, 17 Aug 2026 16:13:53 -0700 Subject: [PATCH 045/157] try again with more files in github --- .github/workflows/rust.yml | 4 ++-- AGENTS.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 8b3d6600b..8183f9029 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -52,9 +52,9 @@ jobs: - name: Remove test directory run: rm -r Rules/Languages/zz - name: Create Rules.zip - run: uv run --script PythonScripts/package_rules.py Rules Rules.zip + run: uv run --no-project --script PythonScripts/package_rules.py Rules Rules.zip - name: Create Rules-minimized.zip - run: uv run --script PythonScripts/package_rules.py Rules Rules-minimized.zip --minimize + run: uv run --no-project --script PythonScripts/package_rules.py Rules Rules-minimized.zip --minimize - name: Upload Rules.zip uses: actions/upload-artifact@v7 with: diff --git a/AGENTS.md b/AGENTS.md index a5632ced5..f3b6670c4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,7 +13,7 @@ but add common mistakes of AI agents here instead. - `ClearSpeak_Rules.yaml`, `SimpleSpeak_Rules.yaml` - `SharedRules/`, `unicode.yaml`, `unicode-full.yaml`, `definitions.yaml`, `navigate.yaml` - `build.rs` can bundle rules into `rules.zip` when `include-zip` is enabled. -- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (flow-style `Languages/**/unicode*.yaml` only) via `uv run --script PythonScripts/package_rules.py Rules [--minimize]`. +- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (flow-style `Languages/**/unicode*.yaml` only) via `uv run --no-project --script PythonScripts/package_rules.py Rules [--minimize]`. ## Translation Conventions - `t:` means untranslated or unverified. From 43af5610615a29e061386c3ec4d63cdd23dac023 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Mon, 17 Aug 2026 16:40:58 -0700 Subject: [PATCH 046/157] try again adding 'zz' test dir for testing --- .github/workflows/rust.yml | 2 ++ AGENTS.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 8183f9029..8b60e93a5 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -93,6 +93,8 @@ jobs: run: | rm -rf Rules unzip -q "${{ matrix.rules_zip }}" + # Release zips omit the synthetic zz test language; restore it for unit tests only. + git checkout HEAD -- Rules/Languages/zz - name: Run tests (${{ matrix.feature_name }}) run: cargo test ${{ matrix.features }} --verbose diff --git a/AGENTS.md b/AGENTS.md index f3b6670c4..d9ed0186b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,7 +13,7 @@ but add common mistakes of AI agents here instead. - `ClearSpeak_Rules.yaml`, `SimpleSpeak_Rules.yaml` - `SharedRules/`, `unicode.yaml`, `unicode-full.yaml`, `definitions.yaml`, `navigate.yaml` - `build.rs` can bundle rules into `rules.zip` when `include-zip` is enabled. -- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (flow-style `Languages/**/unicode*.yaml` only) via `uv run --no-project --script PythonScripts/package_rules.py Rules [--minimize]`. +- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (flow-style `Languages/**/unicode*.yaml` only) via `uv run --no-project --script PythonScripts/package_rules.py Rules [--minimize]`. Both omit `Languages/zz`; the `test-rules-package` job restores `zz` from git after unzip so unit tests still run against release-like archives. ## Translation Conventions - `t:` means untranslated or unverified. From 82e81889ee56ca43c967f72cb37075de60e186a2 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Mon, 17 Aug 2026 16:50:24 -0700 Subject: [PATCH 047/157] internally zip of the Language/Braille dirs --- AGENTS.md | 2 +- PythonScripts/rules_packaging/package.py | 2 ++ .../rules_packaging/tests/test_package.py | 31 ++++++++++++++----- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index d9ed0186b..e4076ece7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,7 +13,7 @@ but add common mistakes of AI agents here instead. - `ClearSpeak_Rules.yaml`, `SimpleSpeak_Rules.yaml` - `SharedRules/`, `unicode.yaml`, `unicode-full.yaml`, `definitions.yaml`, `navigate.yaml` - `build.rs` can bundle rules into `rules.zip` when `include-zip` is enabled. -- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (flow-style `Languages/**/unicode*.yaml` only) via `uv run --no-project --script PythonScripts/package_rules.py Rules [--minimize]`. Both omit `Languages/zz`; the `test-rules-package` job restores `zz` from git after unzip so unit tests still run against release-like archives. +- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (flow-style `Languages/**/unicode*.yaml` only) via `uv run --no-project --script PythonScripts/package_rules.py Rules [--minimize]`. Each language/braille subdir is stored as `/.zip` (matching `build.rs`); top-level and `Intent/` YAML stay loose. Both omit `Languages/zz`; the `test-rules-package` job restores `zz` from git after unzip so unit tests still run against release-like archives. ## Translation Conventions - `t:` means untranslated or unverified. diff --git a/PythonScripts/rules_packaging/package.py b/PythonScripts/rules_packaging/package.py index 9b3c47f9d..214ac0db5 100644 --- a/PythonScripts/rules_packaging/package.py +++ b/PythonScripts/rules_packaging/package.py @@ -8,6 +8,7 @@ from pathlib import Path from .minimize import copy_rules_tree +from .release_layout import apply_release_layout def zip_directory(source_dir: Path, zip_path: Path) -> None: @@ -38,6 +39,7 @@ def package_rules(source: Path, output: Path, *, minimize: bool = False) -> dict shutil.copytree(source, staged_rules) minimized, copied, warnings = 0, sum(1 for p in staged_rules.rglob("*") if p.is_file()), [] + apply_release_layout(staged_rules) zip_directory(staged_rules, output) return { diff --git a/PythonScripts/rules_packaging/tests/test_package.py b/PythonScripts/rules_packaging/tests/test_package.py index a8364c93a..c2adc11f7 100644 --- a/PythonScripts/rules_packaging/tests/test_package.py +++ b/PythonScripts/rules_packaging/tests/test_package.py @@ -2,6 +2,7 @@ from __future__ import annotations +import io import zipfile from pathlib import Path @@ -11,6 +12,12 @@ from rules_packaging.package import package_rules +def read_nested_zip_text(archive: zipfile.ZipFile, outer_path: str, inner_path: str) -> str: + """Read ``inner_path`` from a zip file stored inside the outer archive.""" + with zipfile.ZipFile(io.BytesIO(archive.read(outer_path))) as inner: + return inner.read(inner_path).decode("utf-8") + + def test_minimize_yaml_strips_comments_and_uses_flow_style() -> None: """Minimized YAML drops comments and uses flow-style collections.""" source = """--- @@ -25,17 +32,22 @@ def test_minimize_yaml_strips_comments_and_uses_flow_style() -> None: def test_package_rules_standard_zip_layout(tmp_path: Path) -> None: - """Standard packaging preserves Rules/ prefix inside the zip.""" + """Standard packaging preserves Rules/ prefix and per-language inner zips.""" rules = tmp_path / "Rules" - rules.mkdir() + lang = rules / "Languages" / "en" + lang.mkdir(parents=True) (rules / "prefs.yaml").write_text("- SpeechStyle: [t: \"ClearSpeak\"]\n", encoding="utf-8") + (lang / "unicode.yaml").write_text("- \"+\": [t: \"plus\"]\n", encoding="utf-8") output = tmp_path / "Rules.zip" package_rules(rules, output, minimize=False) with zipfile.ZipFile(output) as archive: names = archive.namelist() - assert "Rules/prefs.yaml" in names + assert "Rules/prefs.yaml" in names + assert "Rules/Languages/en/en.zip" in names + assert "Rules/Languages/en/unicode.yaml" not in names + assert read_nested_zip_text(archive, "Rules/Languages/en/en.zip", "unicode.yaml").replace("\r\n", "\n") == "- \"+\": [t: \"plus\"]\n" def test_dump_flow_style_quotes_infinity() -> None: @@ -60,12 +72,12 @@ def test_should_not_minimize_braille_unicode(tmp_path: Path) -> None: assert stats["minimized_yaml_files"] == 0 with zipfile.ZipFile(output) as archive: - text = archive.read("Rules/Braille/Nemeth/unicode.yaml").decode("utf-8") + text = read_nested_zip_text(archive, "Rules/Braille/Nemeth/Nemeth.zip", "unicode.yaml") assert text.replace("\r\n", "\n") == source.replace("\r\n", "\n") -def test_package_rules_minimized_smaller_than_standard(tmp_path: Path) -> None: - """Minimized archives use flow-style YAML and are not larger than standard.""" +def test_package_rules_minimized_matches_release_layout(tmp_path: Path) -> None: + """Minimized archives use inner language zips and flow-style unicode YAML.""" rules = tmp_path / "Rules" lang = rules / "Languages" / "en" lang.mkdir(parents=True) @@ -94,8 +106,11 @@ def test_package_rules_minimized_smaller_than_standard(tmp_path: Path) -> None: assert minimized.stat().st_size <= standard.stat().st_size with zipfile.ZipFile(minimized) as archive: - unicode_text = archive.read("Rules/Languages/en/unicode.yaml").decode("utf-8") - defs_text = archive.read("Rules/Languages/en/definitions.yaml").decode("utf-8") + names = archive.namelist() + assert "Rules/Languages/en/en.zip" in names + assert "Rules/Languages/en/unicode.yaml" not in names + unicode_text = read_nested_zip_text(archive, "Rules/Languages/en/en.zip", "unicode.yaml") + defs_text = read_nested_zip_text(archive, "Rules/Languages/en/en.zip", "definitions.yaml") assert "#" not in unicode_text assert "real=inf" in defs_text assert yaml.safe_load(unicode_text) is not None From 082afd154adf410627932feab186171f25600bbc Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Mon, 17 Aug 2026 16:51:11 -0700 Subject: [PATCH 048/157] add another file for packaging the rules --- .../rules_packaging/release_layout.py | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 PythonScripts/rules_packaging/release_layout.py diff --git a/PythonScripts/rules_packaging/release_layout.py b/PythonScripts/rules_packaging/release_layout.py new file mode 100644 index 000000000..74deff496 --- /dev/null +++ b/PythonScripts/rules_packaging/release_layout.py @@ -0,0 +1,73 @@ +"""Transform a Rules tree into the release layout used by build.rs and CI.""" + +from __future__ import annotations + +import shutil +import zipfile +from pathlib import Path + +YAML_SUFFIXES = {".yaml", ".yml"} +SKIP_LANGUAGE_DIRS = {"zz"} +ZIP_SECTIONS = ("Languages", "Braille") + + +def apply_release_layout(rules_dir: Path) -> None: + """Zip each language/braille subdir into ``/.zip`` and drop loose YAML inside.""" + languages = rules_dir / "Languages" + zz = languages / "zz" + if zz.is_dir(): + shutil.rmtree(zz) + + for section in ZIP_SECTIONS: + section_dir = rules_dir / section + if section_dir.is_dir(): + _zip_immediate_subdirs(section_dir) + + +def _zip_immediate_subdirs(parent: Path) -> None: + for entry in sorted(parent.iterdir(), key=lambda path: path.name): + if not entry.is_dir(): + continue + if entry.name in SKIP_LANGUAGE_DIRS: + shutil.rmtree(entry) + continue + + inner_zip = entry / f"{entry.name}.zip" + yaml_count = _write_yaml_zip(entry, inner_zip) + if yaml_count == 0: + inner_zip.unlink(missing_ok=True) + shutil.rmtree(entry) + continue + + _remove_files_except(entry, keep={inner_zip}) + _prune_empty_dirs(entry) + + +def _write_yaml_zip(source_dir: Path, zip_path: Path) -> int: + """Write all YAML under ``source_dir`` into ``zip_path``; return file count.""" + yaml_files = [ + path + for path in sorted(source_dir.rglob("*")) + if path.is_file() and path.suffix.lower() in YAML_SUFFIXES and path != zip_path + ] + if not yaml_files: + return 0 + + with zipfile.ZipFile(zip_path, "w", compression=zipfile.ZIP_DEFLATED, compresslevel=9) as archive: + for path in yaml_files: + archive.write(path, path.relative_to(source_dir).as_posix()) + return len(yaml_files) + + +def _remove_files_except(root: Path, *, keep: set[Path]) -> None: + for path in sorted(root.rglob("*"), reverse=True): + if path.is_file() and path.resolve() not in {item.resolve() for item in keep}: + path.unlink() + + +def _prune_empty_dirs(root: Path) -> None: + for path in sorted((item for item in root.rglob("*") if item.is_dir()), reverse=True): + try: + path.rmdir() + except OSError: + continue From 61c04bd722ae61d42844b8d5c5d0092ba6b31637 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Mon, 17 Aug 2026 17:00:21 -0700 Subject: [PATCH 049/157] trying again with zipping -- AI is not doing a very good job... --- PythonScripts/rules_packaging/package.py | 4 ++-- PythonScripts/rules_packaging/release_layout.py | 5 +++-- PythonScripts/rules_packaging/tests/test_package.py | 3 +++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/PythonScripts/rules_packaging/package.py b/PythonScripts/rules_packaging/package.py index 214ac0db5..733662cb8 100644 --- a/PythonScripts/rules_packaging/package.py +++ b/PythonScripts/rules_packaging/package.py @@ -4,9 +4,9 @@ import shutil import tempfile -import zipfile from pathlib import Path +from .compress import open_rules_zip from .minimize import copy_rules_tree from .release_layout import apply_release_layout @@ -14,7 +14,7 @@ def zip_directory(source_dir: Path, zip_path: Path) -> None: """Write ``source_dir`` contents into ``zip_path`` preserving relative paths.""" zip_path.parent.mkdir(parents=True, exist_ok=True) - with zipfile.ZipFile(zip_path, "w", compression=zipfile.ZIP_DEFLATED, compresslevel=9) as archive: + with open_rules_zip(zip_path) as archive: for path in sorted(source_dir.rglob("*")): if path.is_file(): archive.write(path, path.relative_to(source_dir.parent).as_posix()) diff --git a/PythonScripts/rules_packaging/release_layout.py b/PythonScripts/rules_packaging/release_layout.py index 74deff496..792687ad6 100644 --- a/PythonScripts/rules_packaging/release_layout.py +++ b/PythonScripts/rules_packaging/release_layout.py @@ -3,9 +3,10 @@ from __future__ import annotations import shutil -import zipfile from pathlib import Path +from .compress import open_rules_zip + YAML_SUFFIXES = {".yaml", ".yml"} SKIP_LANGUAGE_DIRS = {"zz"} ZIP_SECTIONS = ("Languages", "Braille") @@ -53,7 +54,7 @@ def _write_yaml_zip(source_dir: Path, zip_path: Path) -> int: if not yaml_files: return 0 - with zipfile.ZipFile(zip_path, "w", compression=zipfile.ZIP_DEFLATED, compresslevel=9) as archive: + with open_rules_zip(zip_path) as archive: for path in yaml_files: archive.write(path, path.relative_to(source_dir).as_posix()) return len(yaml_files) diff --git a/PythonScripts/rules_packaging/tests/test_package.py b/PythonScripts/rules_packaging/tests/test_package.py index c2adc11f7..334c5b851 100644 --- a/PythonScripts/rules_packaging/tests/test_package.py +++ b/PythonScripts/rules_packaging/tests/test_package.py @@ -8,6 +8,7 @@ import yaml +from rules_packaging.compress import RULES_ZIP_COMPRESSION from rules_packaging.minimize import dump_flow_style, load_yaml, minimize_yaml_text from rules_packaging.package import package_rules @@ -47,6 +48,8 @@ def test_package_rules_standard_zip_layout(tmp_path: Path) -> None: assert "Rules/prefs.yaml" in names assert "Rules/Languages/en/en.zip" in names assert "Rules/Languages/en/unicode.yaml" not in names + with zipfile.ZipFile(io.BytesIO(archive.read("Rules/Languages/en/en.zip"))) as inner: + assert all(info.compress_type == RULES_ZIP_COMPRESSION for info in inner.infolist()) assert read_nested_zip_text(archive, "Rules/Languages/en/en.zip", "unicode.yaml").replace("\r\n", "\n") == "- \"+\": [t: \"plus\"]\n" From 917dbe5649da96ae9d2b95ffb59b282c199ec85d Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Mon, 17 Aug 2026 17:05:00 -0700 Subject: [PATCH 050/157] Merged the messy multiple files AI created into one file --- PythonScripts/package_rules.py | 221 +++++++++++++++++- PythonScripts/rules_packaging/__init__.py | 5 - PythonScripts/rules_packaging/minimize.py | 108 --------- PythonScripts/rules_packaging/package.py | 49 ---- .../rules_packaging/release_layout.py | 74 ------ .../rules_packaging/tests/__init__.py | 1 - .../test_package_rules.py} | 10 +- 7 files changed, 225 insertions(+), 243 deletions(-) delete mode 100644 PythonScripts/rules_packaging/__init__.py delete mode 100644 PythonScripts/rules_packaging/minimize.py delete mode 100644 PythonScripts/rules_packaging/package.py delete mode 100644 PythonScripts/rules_packaging/release_layout.py delete mode 100644 PythonScripts/rules_packaging/tests/__init__.py rename PythonScripts/{rules_packaging/tests/test_package.py => tests/test_package_rules.py} (95%) diff --git a/PythonScripts/package_rules.py b/PythonScripts/package_rules.py index 905a7bc90..53ff2d89e 100644 --- a/PythonScripts/package_rules.py +++ b/PythonScripts/package_rules.py @@ -7,13 +7,228 @@ from __future__ import annotations import argparse +import re +import shutil import sys +import tempfile +import zipfile from pathlib import Path +from typing import Any -# Standalone script: sibling package, not installed via audit_translations. -sys.path.insert(0, str(Path(__file__).resolve().parent)) +import yaml -from rules_packaging.package import package_rules # noqa: E402 +YAML_SUFFIXES = {".yaml", ".yml"} +MINIMIZE_NAMES = {"unicode.yaml", "unicode-full.yaml"} +SKIP_LANGUAGE_DIRS = {"zz"} +ZIP_SECTIONS = ("Languages", "Braille") + +# Non-WASM MathCAT links the `zip` crate with only the `bzip2` feature (see Cargo.toml). +# Inner language/braille zips must use BZIP2 — DEFLATE (method 8) fails at runtime with +# CompressionMethodNotSupported. build.rs uses the same choice for native targets. +RULES_ZIP_COMPRESSION = zipfile.ZIP_BZIP2 +RULES_ZIP_COMPRESSLEVEL = 9 + + +def _open_rules_zip(path: Path, mode: str = "w") -> zipfile.ZipFile: + return zipfile.ZipFile( + path, + mode, + compression=RULES_ZIP_COMPRESSION, + compresslevel=RULES_ZIP_COMPRESSLEVEL, + ) + + +def _configure_yaml_dumper() -> None: + """Quote all strings so yaml-rust does not treat words like 'infinity' as floats.""" + + def represent_str(dumper: yaml.SafeDumper, data: str) -> yaml.nodes.ScalarNode: + return dumper.represent_scalar("tag:yaml.org,2002:str", data, style='"') + + yaml.add_representer(str, represent_str, Dumper=yaml.SafeDumper) + + +_configure_yaml_dumper() + + +def should_minimize(path: Path) -> bool: + if path.suffix.lower() not in YAML_SUFFIXES or path.name not in MINIMIZE_NAMES: + return False + # Speech unicode only — braille unicode.yaml keeps block form (tests and edits rely on it). + return "Languages" in path.parts + + +def preprocess_for_load(text: str) -> str: + """Normalize MathCAT YAML quirks so PyYAML can parse it.""" + text = text.replace("\t", " ") + text = re.sub(r'(?m)^(\s*-\s*)":(\s*:\s*)', r'\1"\\"":\2', text) + text = re.sub(r'(?m)^(\s*-\s*)\\"(\s*:\s*)', r'\1"\\""\2', text) + return text + + +def load_yaml(text: str) -> Any: + """Load YAML using PyYAML with MathCAT-specific normalizations.""" + candidates = (text, text.replace("\t", " "), preprocess_for_load(text)) + last_error: yaml.YAMLError | None = None + for candidate in candidates: + try: + return yaml.safe_load(candidate) + except yaml.YAMLError as exc: + last_error = exc + if last_error is not None: + raise last_error + return None + + +def dump_flow_style(data: Any) -> str: + """Emit minimized flow-style YAML without comments.""" + if data is None: + return "" + dumped = yaml.dump( + data, + allow_unicode=True, + default_flow_style=True, + width=10**9, + sort_keys=False, + Dumper=yaml.SafeDumper, + ) + return dumped if dumped.endswith("\n") else f"{dumped}\n" + + +def minimize_yaml_text(text: str) -> tuple[str, bool]: + """Return flow-style YAML and whether parsing succeeded.""" + try: + data = load_yaml(text) + except yaml.YAMLError: + return text, False + return dump_flow_style(data), True + + +def copy_rules_tree(source: Path, destination: Path, *, minimize: bool) -> tuple[int, int, list[str]]: + """Copy ``source`` Rules tree to ``destination``, optionally minimizing YAML.""" + minimized = 0 + copied = 0 + warnings: list[str] = [] + + for src_path in sorted(source.rglob("*")): + if src_path.is_dir(): + continue + rel = src_path.relative_to(source) + dest_path = destination / rel + dest_path.parent.mkdir(parents=True, exist_ok=True) + + if minimize and should_minimize(src_path): + text = src_path.read_text(encoding="utf-8") + out, ok = minimize_yaml_text(text) + if ok: + dest_path.write_text(out, encoding="utf-8", newline="\n") + minimized += 1 + else: + dest_path.write_bytes(src_path.read_bytes()) + warnings.append(f"could not minimize {rel}; copied verbatim") + copied += 1 + else: + dest_path.write_bytes(src_path.read_bytes()) + copied += 1 + + return minimized, copied, warnings + + +def apply_release_layout(rules_dir: Path) -> None: + """Zip each language/braille subdir into ``/.zip`` and drop loose YAML inside.""" + zz = rules_dir / "Languages" / "zz" + if zz.is_dir(): + shutil.rmtree(zz) + + for section in ZIP_SECTIONS: + section_dir = rules_dir / section + if section_dir.is_dir(): + _zip_immediate_subdirs(section_dir) + + +def _zip_immediate_subdirs(parent: Path) -> None: + for entry in sorted(parent.iterdir(), key=lambda path: path.name): + if not entry.is_dir(): + continue + if entry.name in SKIP_LANGUAGE_DIRS: + shutil.rmtree(entry) + continue + + inner_zip = entry / f"{entry.name}.zip" + yaml_count = _write_yaml_zip(entry, inner_zip) + if yaml_count == 0: + inner_zip.unlink(missing_ok=True) + shutil.rmtree(entry) + continue + + _remove_files_except(entry, keep={inner_zip}) + _prune_empty_dirs(entry) + + +def _write_yaml_zip(source_dir: Path, zip_path: Path) -> int: + yaml_files = [ + path + for path in sorted(source_dir.rglob("*")) + if path.is_file() and path.suffix.lower() in YAML_SUFFIXES and path != zip_path + ] + if not yaml_files: + return 0 + + with _open_rules_zip(zip_path) as archive: + for path in yaml_files: + archive.write(path, path.relative_to(source_dir).as_posix()) + return len(yaml_files) + + +def _remove_files_except(root: Path, *, keep: set[Path]) -> None: + keep_resolved = {item.resolve() for item in keep} + for path in sorted(root.rglob("*"), reverse=True): + if path.is_file() and path.resolve() not in keep_resolved: + path.unlink() + + +def _prune_empty_dirs(root: Path) -> None: + for path in sorted((item for item in root.rglob("*") if item.is_dir()), reverse=True): + try: + path.rmdir() + except OSError: + continue + + +def zip_directory(source_dir: Path, zip_path: Path) -> None: + """Write ``source_dir`` contents into ``zip_path`` preserving relative paths.""" + zip_path.parent.mkdir(parents=True, exist_ok=True) + with _open_rules_zip(zip_path) as archive: + for path in sorted(source_dir.rglob("*")): + if path.is_file(): + archive.write(path, path.relative_to(source_dir.parent).as_posix()) + + +def package_rules(source: Path, output: Path, *, minimize: bool = False) -> dict[str, int | list[str]]: + """Package ``source`` (Rules directory) into ``output`` zip file.""" + source = source.resolve() + output = output.resolve() + + if not source.is_dir(): + raise FileNotFoundError(f"Rules source directory not found: {source}") + if source.name != "Rules": + raise ValueError(f"Expected a directory named 'Rules', got '{source.name}'") + + with tempfile.TemporaryDirectory(prefix="mathcat-rules-") as tmp: + staged_rules = Path(tmp) / "Rules" + if minimize: + minimized, copied, warnings = copy_rules_tree(source, staged_rules, minimize=True) + else: + shutil.copytree(source, staged_rules) + minimized, copied, warnings = 0, sum(1 for p in staged_rules.rglob("*") if p.is_file()), [] + + apply_release_layout(staged_rules) + zip_directory(staged_rules, output) + + return { + "minimized_yaml_files": minimized, + "copied_files": copied, + "warnings": warnings, + } def main(argv: list[str] | None = None) -> int: diff --git a/PythonScripts/rules_packaging/__init__.py b/PythonScripts/rules_packaging/__init__.py deleted file mode 100644 index 07c96c9d2..000000000 --- a/PythonScripts/rules_packaging/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -"""Standalone Rules zip packaging and YAML minimization (not part of audit_translations).""" - -from .package import package_rules - -__all__ = ["package_rules"] diff --git a/PythonScripts/rules_packaging/minimize.py b/PythonScripts/rules_packaging/minimize.py deleted file mode 100644 index 7fb6a05d5..000000000 --- a/PythonScripts/rules_packaging/minimize.py +++ /dev/null @@ -1,108 +0,0 @@ -"""Convert MathCAT Rules YAML files to compact flow-style form.""" - -from __future__ import annotations - -import re -from pathlib import Path -from typing import Any - -import yaml - -YAML_SUFFIXES = {".yaml", ".yml"} -MINIMIZE_NAMES = {"unicode.yaml", "unicode-full.yaml"} - - -def should_minimize(path: Path) -> bool: - if path.suffix.lower() not in YAML_SUFFIXES or path.name not in MINIMIZE_NAMES: - return False - # Speech unicode only — braille unicode.yaml keeps block form (tests and edits rely on it). - return "Languages" in path.parts - - -def _configure_yaml_dumper() -> None: - """Quote all strings so yaml-rust does not treat words like 'infinity' as floats.""" - - def represent_str(dumper: yaml.SafeDumper, data: str) -> yaml.nodes.ScalarNode: - return dumper.represent_scalar("tag:yaml.org,2002:str", data, style='"') - - yaml.add_representer(str, represent_str, Dumper=yaml.SafeDumper) - - -_configure_yaml_dumper() - - -def preprocess_for_load(text: str) -> str: - """Normalize MathCAT YAML quirks so PyYAML can parse it.""" - text = text.replace("\t", " ") - # Bare double-quote or colon used as a mapping key in unicode list entries. - text = re.sub(r'(?m)^(\s*-\s*)":(\s*:\s*)', r'\1"\\"":\2', text) - text = re.sub(r'(?m)^(\s*-\s*)\\"(\s*:\s*)', r'\1"\\""\2', text) - return text - - -def load_yaml(text: str) -> Any: - """Load YAML using PyYAML with MathCAT-specific normalizations.""" - candidates = (text, text.replace("\t", " "), preprocess_for_load(text)) - last_error: yaml.YAMLError | None = None - for candidate in candidates: - try: - return yaml.safe_load(candidate) - except yaml.YAMLError as exc: - last_error = exc - if last_error is not None: - raise last_error - return None - - -def dump_flow_style(data: Any) -> str: - """Emit minimized flow-style YAML without comments.""" - if data is None: - return "" - dumped = yaml.dump( - data, - allow_unicode=True, - default_flow_style=True, - width=10**9, - sort_keys=False, - Dumper=yaml.SafeDumper, - ) - return dumped if dumped.endswith("\n") else f"{dumped}\n" - - -def minimize_yaml_text(text: str) -> tuple[str, bool]: - """Return flow-style YAML and whether parsing succeeded.""" - try: - data = load_yaml(text) - except yaml.YAMLError: - return text, False - return dump_flow_style(data), True - - -def copy_rules_tree(source: Path, destination: Path, *, minimize: bool) -> tuple[int, int, list[str]]: - """Copy ``source`` Rules tree to ``destination``, optionally minimizing YAML.""" - minimized = 0 - copied = 0 - warnings: list[str] = [] - - for src_path in sorted(source.rglob("*")): - if src_path.is_dir(): - continue - rel = src_path.relative_to(source) - dest_path = destination / rel - dest_path.parent.mkdir(parents=True, exist_ok=True) - - if minimize and should_minimize(src_path): - text = src_path.read_text(encoding="utf-8") - out, ok = minimize_yaml_text(text) - if ok: - dest_path.write_text(out, encoding="utf-8", newline="\n") - minimized += 1 - else: - dest_path.write_bytes(src_path.read_bytes()) - warnings.append(f"could not minimize {rel}; copied verbatim") - copied += 1 - else: - dest_path.write_bytes(src_path.read_bytes()) - copied += 1 - - return minimized, copied, warnings diff --git a/PythonScripts/rules_packaging/package.py b/PythonScripts/rules_packaging/package.py deleted file mode 100644 index 733662cb8..000000000 --- a/PythonScripts/rules_packaging/package.py +++ /dev/null @@ -1,49 +0,0 @@ -"""Create Rules.zip archives from a Rules directory tree.""" - -from __future__ import annotations - -import shutil -import tempfile -from pathlib import Path - -from .compress import open_rules_zip -from .minimize import copy_rules_tree -from .release_layout import apply_release_layout - - -def zip_directory(source_dir: Path, zip_path: Path) -> None: - """Write ``source_dir`` contents into ``zip_path`` preserving relative paths.""" - zip_path.parent.mkdir(parents=True, exist_ok=True) - with open_rules_zip(zip_path) as archive: - for path in sorted(source_dir.rglob("*")): - if path.is_file(): - archive.write(path, path.relative_to(source_dir.parent).as_posix()) - - -def package_rules(source: Path, output: Path, *, minimize: bool = False) -> dict[str, int | list[str]]: - """Package ``source`` (Rules directory) into ``output`` zip file.""" - source = source.resolve() - output = output.resolve() - - if not source.is_dir(): - raise FileNotFoundError(f"Rules source directory not found: {source}") - if source.name != "Rules": - raise ValueError(f"Expected a directory named 'Rules', got '{source.name}'") - - with tempfile.TemporaryDirectory(prefix="mathcat-rules-") as tmp: - staging_root = Path(tmp) - staged_rules = staging_root / "Rules" - if minimize: - minimized, copied, warnings = copy_rules_tree(source, staged_rules, minimize=True) - else: - shutil.copytree(source, staged_rules) - minimized, copied, warnings = 0, sum(1 for p in staged_rules.rglob("*") if p.is_file()), [] - - apply_release_layout(staged_rules) - zip_directory(staged_rules, output) - - return { - "minimized_yaml_files": minimized, - "copied_files": copied, - "warnings": warnings, - } diff --git a/PythonScripts/rules_packaging/release_layout.py b/PythonScripts/rules_packaging/release_layout.py deleted file mode 100644 index 792687ad6..000000000 --- a/PythonScripts/rules_packaging/release_layout.py +++ /dev/null @@ -1,74 +0,0 @@ -"""Transform a Rules tree into the release layout used by build.rs and CI.""" - -from __future__ import annotations - -import shutil -from pathlib import Path - -from .compress import open_rules_zip - -YAML_SUFFIXES = {".yaml", ".yml"} -SKIP_LANGUAGE_DIRS = {"zz"} -ZIP_SECTIONS = ("Languages", "Braille") - - -def apply_release_layout(rules_dir: Path) -> None: - """Zip each language/braille subdir into ``/.zip`` and drop loose YAML inside.""" - languages = rules_dir / "Languages" - zz = languages / "zz" - if zz.is_dir(): - shutil.rmtree(zz) - - for section in ZIP_SECTIONS: - section_dir = rules_dir / section - if section_dir.is_dir(): - _zip_immediate_subdirs(section_dir) - - -def _zip_immediate_subdirs(parent: Path) -> None: - for entry in sorted(parent.iterdir(), key=lambda path: path.name): - if not entry.is_dir(): - continue - if entry.name in SKIP_LANGUAGE_DIRS: - shutil.rmtree(entry) - continue - - inner_zip = entry / f"{entry.name}.zip" - yaml_count = _write_yaml_zip(entry, inner_zip) - if yaml_count == 0: - inner_zip.unlink(missing_ok=True) - shutil.rmtree(entry) - continue - - _remove_files_except(entry, keep={inner_zip}) - _prune_empty_dirs(entry) - - -def _write_yaml_zip(source_dir: Path, zip_path: Path) -> int: - """Write all YAML under ``source_dir`` into ``zip_path``; return file count.""" - yaml_files = [ - path - for path in sorted(source_dir.rglob("*")) - if path.is_file() and path.suffix.lower() in YAML_SUFFIXES and path != zip_path - ] - if not yaml_files: - return 0 - - with open_rules_zip(zip_path) as archive: - for path in yaml_files: - archive.write(path, path.relative_to(source_dir).as_posix()) - return len(yaml_files) - - -def _remove_files_except(root: Path, *, keep: set[Path]) -> None: - for path in sorted(root.rglob("*"), reverse=True): - if path.is_file() and path.resolve() not in {item.resolve() for item in keep}: - path.unlink() - - -def _prune_empty_dirs(root: Path) -> None: - for path in sorted((item for item in root.rglob("*") if item.is_dir()), reverse=True): - try: - path.rmdir() - except OSError: - continue diff --git a/PythonScripts/rules_packaging/tests/__init__.py b/PythonScripts/rules_packaging/tests/__init__.py deleted file mode 100644 index b5d3c1aa2..000000000 --- a/PythonScripts/rules_packaging/tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Tests for rules packaging.""" diff --git a/PythonScripts/rules_packaging/tests/test_package.py b/PythonScripts/tests/test_package_rules.py similarity index 95% rename from PythonScripts/rules_packaging/tests/test_package.py rename to PythonScripts/tests/test_package_rules.py index 334c5b851..216a1f05d 100644 --- a/PythonScripts/rules_packaging/tests/test_package.py +++ b/PythonScripts/tests/test_package_rules.py @@ -8,9 +8,13 @@ import yaml -from rules_packaging.compress import RULES_ZIP_COMPRESSION -from rules_packaging.minimize import dump_flow_style, load_yaml, minimize_yaml_text -from rules_packaging.package import package_rules +from package_rules import ( + RULES_ZIP_COMPRESSION, + dump_flow_style, + load_yaml, + minimize_yaml_text, + package_rules, +) def read_nested_zip_text(archive: zipfile.ZipFile, outer_path: str, inner_path: str) -> str: From 3bb491df6542e4f4af8bacb58fb7b73ef973ac54 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Mon, 17 Aug 2026 17:12:14 -0700 Subject: [PATCH 051/157] AI keeps messing with things it shouldn't... --- .github/workflows/python.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index c2bb772bf..548e25a92 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -17,4 +17,4 @@ jobs: run: uv run ruff format --check audit_translations/ - name: Run tests working-directory: PythonScripts - run: uv run pytest + run: uv run pytest tests/test_package_rules.py From 7af9ec3d2bb7704db9da175c14639f962d2cce13 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Mon, 17 Aug 2026 17:19:20 -0700 Subject: [PATCH 052/157] remove inappropriate check --- PythonScripts/tests/test_package_rules.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/PythonScripts/tests/test_package_rules.py b/PythonScripts/tests/test_package_rules.py index 216a1f05d..ced3a82e5 100644 --- a/PythonScripts/tests/test_package_rules.py +++ b/PythonScripts/tests/test_package_rules.py @@ -104,13 +104,10 @@ def test_package_rules_minimized_matches_release_layout(tmp_path: Path) -> None: encoding="utf-8", ) - standard = tmp_path / "Rules.zip" minimized = tmp_path / "Rules-minimized.zip" - package_rules(rules, standard, minimize=False) stats = package_rules(rules, minimized, minimize=True) assert stats["minimized_yaml_files"] == 1 - assert minimized.stat().st_size <= standard.stat().st_size with zipfile.ZipFile(minimized) as archive: names = archive.namelist() From 786d058ece11aa14a1f00004cc31f446dfa617f3 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Tue, 18 Aug 2026 00:10:55 -0700 Subject: [PATCH 053/157] Unify Rules packaging in Rust for CI, include-zip, and release zips. Replace the Python packager with shared rules_archive logic and a package-rules binary so build.rs, downloadable archives, and the include-zip embed use one layout (inner BZIP2; outer DEFLATE for unzip-friendly downloads). Serialize parallel language unzip during tests to avoid corrupting the shared Rules tree. Co-authored-by: Cursor --- .github/workflows/python.yml | 2 +- .github/workflows/rust.yml | 10 +- AGENTS.md | 4 +- Cargo.toml | 15 +- PythonScripts/package_rules.py | 265 --------------- PythonScripts/tests/test_package_rules.py | 120 ------- build.rs | 206 +----------- src/bin/package_rules.rs | 230 +++++++++++++ src/interface.rs | 3 +- src/prefs.rs | 19 +- src/rules_archive.rs | 385 ++++++++++++++++++++++ 11 files changed, 659 insertions(+), 600 deletions(-) delete mode 100644 PythonScripts/package_rules.py delete mode 100644 PythonScripts/tests/test_package_rules.py create mode 100644 src/bin/package_rules.rs create mode 100644 src/rules_archive.rs diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 548e25a92..c2bb772bf 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -17,4 +17,4 @@ jobs: run: uv run ruff format --check audit_translations/ - name: Run tests working-directory: PythonScripts - run: uv run pytest tests/test_package_rules.py + run: uv run pytest diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 8b60e93a5..e36f9b4b2 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -46,15 +46,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - - uses: astral-sh/setup-uv@v10.0.1 - - name: Remove empty Rules directories - run: find Rules -type d -empty -delete - - name: Remove test directory - run: rm -r Rules/Languages/zz + - uses: dtolnay/rust-toolchain@stable - name: Create Rules.zip - run: uv run --no-project --script PythonScripts/package_rules.py Rules Rules.zip + run: cargo run --bin package-rules -- Rules Rules.zip - name: Create Rules-minimized.zip - run: uv run --no-project --script PythonScripts/package_rules.py Rules Rules-minimized.zip --minimize + run: cargo run --bin package-rules -- Rules Rules-minimized.zip --minimize - name: Upload Rules.zip uses: actions/upload-artifact@v7 with: diff --git a/AGENTS.md b/AGENTS.md index e4076ece7..76ea6a889 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -12,8 +12,8 @@ but add common mistakes of AI agents here instead. - Common per-language files: - `ClearSpeak_Rules.yaml`, `SimpleSpeak_Rules.yaml` - `SharedRules/`, `unicode.yaml`, `unicode-full.yaml`, `definitions.yaml`, `navigate.yaml` -- `build.rs` can bundle rules into `rules.zip` when `include-zip` is enabled. -- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (flow-style `Languages/**/unicode*.yaml` only) via `uv run --no-project --script PythonScripts/package_rules.py Rules [--minimize]`. Each language/braille subdir is stored as `/.zip` (matching `build.rs`); top-level and `Intent/` YAML stay loose. Both omit `Languages/zz`; the `test-rules-package` job restores `zz` from git after unzip so unit tests still run against release-like archives. +- `build.rs` can bundle rules into `rules.zip` when `include-zip` is enabled (always the minimized tree). Shared zipper: `src/rules_archive.rs`, invoked as `cargo run --bin package-rules -- Rules [--minimize]`. +- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (comments stripped from `Languages/**/unicode.yaml` and `unicode-full.yaml` only). Each language/braille subdir is stored as `/.zip`; top-level and `Intent/` YAML stay loose. Inner language zips use BZIP2; the outer downloadable archive uses DEFLATE so `unzip` works. Both omit `Languages/zz`; the `test-rules-package` job restores `zz` from git after unzip so unit tests still run against release-like archives. ## Translation Conventions - `t:` means untranslated or unverified. diff --git a/Cargo.toml b/Cargo.toml index 45de0ad1f..32e83cf27 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,18 +39,17 @@ fastrand = { version = "2.3.0" } clap = { version = "4.5.60", features = ["derive"] } html-escape = "0.2.13" -[target.'cfg(target_family = "wasm")'.dependencies] -zip = { version = "8.2", default-features = false, features = ["deflate"] } -[target.'cfg(not(target_family = "wasm"))'.dependencies] -zip = { version = "8.2", default-features = false, features = ["bzip2"] } +# Runtime extracts inner language/braille zips (BZIP2). The package-rules binary also +# writes DEFLATE outer archives for Windows/unzip-compatible Rules.zip downloads. +# wasm uses the same features: zip 8.x bzip2 is pure Rust (libbz2-rs-sys), not clang C. +zip = { version = "8.2", default-features = false, features = ["deflate", "bzip2"] } android_logger = {version = "0.15.1", optional = true} natural-tts = { version = "0.3.1", optional = true } [build-dependencies] bitflags = "2.6" -# Build script needs both compression backends regardless of build host — -# build.rs picks DEFLATE/BZIP2 based on the *target* family, not the host. +yaml-rust = "0.4" zip = { version = "8.2", default-features = false, features = ["deflate", "bzip2"] } [dev-dependencies] @@ -64,6 +63,10 @@ crate-type = ["rlib", "cdylib"] name = "mathml2text" path = "src/bin/mathml2text.rs" +[[bin]] +name = "package-rules" +path = "src/bin/package_rules.rs" + [lints.rust] unexpected_cfgs = { level = "allow", check-cfg = ['cfg(coverage)', 'cfg(coverage_nightly)'] } diff --git a/PythonScripts/package_rules.py b/PythonScripts/package_rules.py deleted file mode 100644 index 53ff2d89e..000000000 --- a/PythonScripts/package_rules.py +++ /dev/null @@ -1,265 +0,0 @@ -# /// script -# requires-python = ">=3.14" -# dependencies = ["pyyaml"] -# /// -"""Package MathCAT Rules/ into Rules.zip or Rules-minimized.zip.""" - -from __future__ import annotations - -import argparse -import re -import shutil -import sys -import tempfile -import zipfile -from pathlib import Path -from typing import Any - -import yaml - -YAML_SUFFIXES = {".yaml", ".yml"} -MINIMIZE_NAMES = {"unicode.yaml", "unicode-full.yaml"} -SKIP_LANGUAGE_DIRS = {"zz"} -ZIP_SECTIONS = ("Languages", "Braille") - -# Non-WASM MathCAT links the `zip` crate with only the `bzip2` feature (see Cargo.toml). -# Inner language/braille zips must use BZIP2 — DEFLATE (method 8) fails at runtime with -# CompressionMethodNotSupported. build.rs uses the same choice for native targets. -RULES_ZIP_COMPRESSION = zipfile.ZIP_BZIP2 -RULES_ZIP_COMPRESSLEVEL = 9 - - -def _open_rules_zip(path: Path, mode: str = "w") -> zipfile.ZipFile: - return zipfile.ZipFile( - path, - mode, - compression=RULES_ZIP_COMPRESSION, - compresslevel=RULES_ZIP_COMPRESSLEVEL, - ) - - -def _configure_yaml_dumper() -> None: - """Quote all strings so yaml-rust does not treat words like 'infinity' as floats.""" - - def represent_str(dumper: yaml.SafeDumper, data: str) -> yaml.nodes.ScalarNode: - return dumper.represent_scalar("tag:yaml.org,2002:str", data, style='"') - - yaml.add_representer(str, represent_str, Dumper=yaml.SafeDumper) - - -_configure_yaml_dumper() - - -def should_minimize(path: Path) -> bool: - if path.suffix.lower() not in YAML_SUFFIXES or path.name not in MINIMIZE_NAMES: - return False - # Speech unicode only — braille unicode.yaml keeps block form (tests and edits rely on it). - return "Languages" in path.parts - - -def preprocess_for_load(text: str) -> str: - """Normalize MathCAT YAML quirks so PyYAML can parse it.""" - text = text.replace("\t", " ") - text = re.sub(r'(?m)^(\s*-\s*)":(\s*:\s*)', r'\1"\\"":\2', text) - text = re.sub(r'(?m)^(\s*-\s*)\\"(\s*:\s*)', r'\1"\\""\2', text) - return text - - -def load_yaml(text: str) -> Any: - """Load YAML using PyYAML with MathCAT-specific normalizations.""" - candidates = (text, text.replace("\t", " "), preprocess_for_load(text)) - last_error: yaml.YAMLError | None = None - for candidate in candidates: - try: - return yaml.safe_load(candidate) - except yaml.YAMLError as exc: - last_error = exc - if last_error is not None: - raise last_error - return None - - -def dump_flow_style(data: Any) -> str: - """Emit minimized flow-style YAML without comments.""" - if data is None: - return "" - dumped = yaml.dump( - data, - allow_unicode=True, - default_flow_style=True, - width=10**9, - sort_keys=False, - Dumper=yaml.SafeDumper, - ) - return dumped if dumped.endswith("\n") else f"{dumped}\n" - - -def minimize_yaml_text(text: str) -> tuple[str, bool]: - """Return flow-style YAML and whether parsing succeeded.""" - try: - data = load_yaml(text) - except yaml.YAMLError: - return text, False - return dump_flow_style(data), True - - -def copy_rules_tree(source: Path, destination: Path, *, minimize: bool) -> tuple[int, int, list[str]]: - """Copy ``source`` Rules tree to ``destination``, optionally minimizing YAML.""" - minimized = 0 - copied = 0 - warnings: list[str] = [] - - for src_path in sorted(source.rglob("*")): - if src_path.is_dir(): - continue - rel = src_path.relative_to(source) - dest_path = destination / rel - dest_path.parent.mkdir(parents=True, exist_ok=True) - - if minimize and should_minimize(src_path): - text = src_path.read_text(encoding="utf-8") - out, ok = minimize_yaml_text(text) - if ok: - dest_path.write_text(out, encoding="utf-8", newline="\n") - minimized += 1 - else: - dest_path.write_bytes(src_path.read_bytes()) - warnings.append(f"could not minimize {rel}; copied verbatim") - copied += 1 - else: - dest_path.write_bytes(src_path.read_bytes()) - copied += 1 - - return minimized, copied, warnings - - -def apply_release_layout(rules_dir: Path) -> None: - """Zip each language/braille subdir into ``/.zip`` and drop loose YAML inside.""" - zz = rules_dir / "Languages" / "zz" - if zz.is_dir(): - shutil.rmtree(zz) - - for section in ZIP_SECTIONS: - section_dir = rules_dir / section - if section_dir.is_dir(): - _zip_immediate_subdirs(section_dir) - - -def _zip_immediate_subdirs(parent: Path) -> None: - for entry in sorted(parent.iterdir(), key=lambda path: path.name): - if not entry.is_dir(): - continue - if entry.name in SKIP_LANGUAGE_DIRS: - shutil.rmtree(entry) - continue - - inner_zip = entry / f"{entry.name}.zip" - yaml_count = _write_yaml_zip(entry, inner_zip) - if yaml_count == 0: - inner_zip.unlink(missing_ok=True) - shutil.rmtree(entry) - continue - - _remove_files_except(entry, keep={inner_zip}) - _prune_empty_dirs(entry) - - -def _write_yaml_zip(source_dir: Path, zip_path: Path) -> int: - yaml_files = [ - path - for path in sorted(source_dir.rglob("*")) - if path.is_file() and path.suffix.lower() in YAML_SUFFIXES and path != zip_path - ] - if not yaml_files: - return 0 - - with _open_rules_zip(zip_path) as archive: - for path in yaml_files: - archive.write(path, path.relative_to(source_dir).as_posix()) - return len(yaml_files) - - -def _remove_files_except(root: Path, *, keep: set[Path]) -> None: - keep_resolved = {item.resolve() for item in keep} - for path in sorted(root.rglob("*"), reverse=True): - if path.is_file() and path.resolve() not in keep_resolved: - path.unlink() - - -def _prune_empty_dirs(root: Path) -> None: - for path in sorted((item for item in root.rglob("*") if item.is_dir()), reverse=True): - try: - path.rmdir() - except OSError: - continue - - -def zip_directory(source_dir: Path, zip_path: Path) -> None: - """Write ``source_dir`` contents into ``zip_path`` preserving relative paths.""" - zip_path.parent.mkdir(parents=True, exist_ok=True) - with _open_rules_zip(zip_path) as archive: - for path in sorted(source_dir.rglob("*")): - if path.is_file(): - archive.write(path, path.relative_to(source_dir.parent).as_posix()) - - -def package_rules(source: Path, output: Path, *, minimize: bool = False) -> dict[str, int | list[str]]: - """Package ``source`` (Rules directory) into ``output`` zip file.""" - source = source.resolve() - output = output.resolve() - - if not source.is_dir(): - raise FileNotFoundError(f"Rules source directory not found: {source}") - if source.name != "Rules": - raise ValueError(f"Expected a directory named 'Rules', got '{source.name}'") - - with tempfile.TemporaryDirectory(prefix="mathcat-rules-") as tmp: - staged_rules = Path(tmp) / "Rules" - if minimize: - minimized, copied, warnings = copy_rules_tree(source, staged_rules, minimize=True) - else: - shutil.copytree(source, staged_rules) - minimized, copied, warnings = 0, sum(1 for p in staged_rules.rglob("*") if p.is_file()), [] - - apply_release_layout(staged_rules) - zip_directory(staged_rules, output) - - return { - "minimized_yaml_files": minimized, - "copied_files": copied, - "warnings": warnings, - } - - -def main(argv: list[str] | None = None) -> int: - parser = argparse.ArgumentParser( - description="Package MathCAT Rules/ into a zip archive. " - "Use --minimize for flow-style unicode.yaml / unicode-full.yaml without comments." - ) - parser.add_argument("source", type=Path, help="Path to the Rules directory") - parser.add_argument("output", type=Path, help="Output zip file path (e.g. Rules.zip)") - parser.add_argument( - "--minimize", - action="store_true", - help="Emit compact flow-style YAML (comments and block formatting removed)", - ) - args = parser.parse_args(argv) - - try: - stats = package_rules(args.source, args.output, minimize=args.minimize) - except (FileNotFoundError, ValueError) as exc: - print(f"error: {exc}", file=sys.stderr) - return 1 - - label = "minimized" if args.minimize else "standard" - print(f"Created {label} archive: {args.output}") - if args.minimize: - print(f" minimized YAML files: {stats['minimized_yaml_files']}") - print(f" copied verbatim: {stats['copied_files']}") - for warning in stats["warnings"]: - print(f" warning: {warning}", file=sys.stderr) - return 0 - - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/PythonScripts/tests/test_package_rules.py b/PythonScripts/tests/test_package_rules.py deleted file mode 100644 index ced3a82e5..000000000 --- a/PythonScripts/tests/test_package_rules.py +++ /dev/null @@ -1,120 +0,0 @@ -"""Tests for Rules packaging and YAML minimization.""" - -from __future__ import annotations - -import io -import zipfile -from pathlib import Path - -import yaml - -from package_rules import ( - RULES_ZIP_COMPRESSION, - dump_flow_style, - load_yaml, - minimize_yaml_text, - package_rules, -) - - -def read_nested_zip_text(archive: zipfile.ZipFile, outer_path: str, inner_path: str) -> str: - """Read ``inner_path`` from a zip file stored inside the outer archive.""" - with zipfile.ZipFile(io.BytesIO(archive.read(outer_path))) as inner: - return inner.read(inner_path).decode("utf-8") - - -def test_minimize_yaml_strips_comments_and_uses_flow_style() -> None: - """Minimized YAML drops comments and uses flow-style collections.""" - source = """--- -# comment - - \"+\": [t: \"plus\"] # inline -""" - minimized, ok = minimize_yaml_text(source) - assert ok - assert "#" not in minimized - assert "[" in minimized and "{" in minimized or "t:" in minimized - assert load_yaml(minimized) == load_yaml(source) - - -def test_package_rules_standard_zip_layout(tmp_path: Path) -> None: - """Standard packaging preserves Rules/ prefix and per-language inner zips.""" - rules = tmp_path / "Rules" - lang = rules / "Languages" / "en" - lang.mkdir(parents=True) - (rules / "prefs.yaml").write_text("- SpeechStyle: [t: \"ClearSpeak\"]\n", encoding="utf-8") - (lang / "unicode.yaml").write_text("- \"+\": [t: \"plus\"]\n", encoding="utf-8") - - output = tmp_path / "Rules.zip" - package_rules(rules, output, minimize=False) - - with zipfile.ZipFile(output) as archive: - names = archive.namelist() - assert "Rules/prefs.yaml" in names - assert "Rules/Languages/en/en.zip" in names - assert "Rules/Languages/en/unicode.yaml" not in names - with zipfile.ZipFile(io.BytesIO(archive.read("Rules/Languages/en/en.zip"))) as inner: - assert all(info.compress_type == RULES_ZIP_COMPRESSION for info in inner.infolist()) - assert read_nested_zip_text(archive, "Rules/Languages/en/en.zip", "unicode.yaml").replace("\r\n", "\n") == "- \"+\": [t: \"plus\"]\n" - - -def test_dump_flow_style_quotes_infinity() -> None: - """Flow-style dump must quote 'infinity' so yaml-rust does not read it as a float.""" - minimized = dump_flow_style([{"∞": [{"t": "infinity"}]}]) - assert '"infinity"' in minimized - assert "t: infinity" not in minimized - - -def test_should_not_minimize_braille_unicode(tmp_path: Path) -> None: - """Braille unicode.yaml is copied verbatim even when minimization is enabled.""" - rules = tmp_path / "Rules" - braille = rules / "Braille" / "Nemeth" - braille.mkdir(parents=True) - source = """--- - - "1": [t: "N⠂"] -""" - (braille / "unicode.yaml").write_text(source, encoding="utf-8") - - output = tmp_path / "Rules-minimized.zip" - stats = package_rules(rules, output, minimize=True) - - assert stats["minimized_yaml_files"] == 0 - with zipfile.ZipFile(output) as archive: - text = read_nested_zip_text(archive, "Rules/Braille/Nemeth/Nemeth.zip", "unicode.yaml") - assert text.replace("\r\n", "\n") == source.replace("\r\n", "\n") - - -def test_package_rules_minimized_matches_release_layout(tmp_path: Path) -> None: - """Minimized archives use inner language zips and flow-style unicode YAML.""" - rules = tmp_path / "Rules" - lang = rules / "Languages" / "en" - lang.mkdir(parents=True) - (lang / "unicode.yaml").write_text( - """--- -# header comment - - \"+\": [t: \"plus\"] # trailing - - \"-\": [t: \"minus\"] -""", - encoding="utf-8", - ) - (lang / "definitions.yaml").write_text( - """--- - - AdditionalFunctionNames: - - real=inf -""", - encoding="utf-8", - ) - - minimized = tmp_path / "Rules-minimized.zip" - stats = package_rules(rules, minimized, minimize=True) - - assert stats["minimized_yaml_files"] == 1 - - with zipfile.ZipFile(minimized) as archive: - names = archive.namelist() - assert "Rules/Languages/en/en.zip" in names - assert "Rules/Languages/en/unicode.yaml" not in names - unicode_text = read_nested_zip_text(archive, "Rules/Languages/en/en.zip", "unicode.yaml") - defs_text = read_nested_zip_text(archive, "Rules/Languages/en/en.zip", "definitions.yaml") - assert "#" not in unicode_text - assert "real=inf" in defs_text - assert yaml.safe_load(unicode_text) is not None diff --git a/build.rs b/build.rs index a48b26033..e5a07cd8d 100644 --- a/build.rs +++ b/build.rs @@ -1,205 +1,31 @@ //! The build.rs file is necessary to generate rules.zip. -//! rules.zip are needed so there is a way to get the rules dir into the build since your can't get from the crate. +//! rules.zip are needed so there is a way to get the rules dir into the build since you can't get from the crate. //! The expectation is that most builds (with the exception of WASM builds) will need a build.rs file to extract the rules. #![allow(clippy::needless_return)] +#![allow(dead_code)] // include! of rules_archive.rs pulls in the downloadable packager too -use std::fs::{read_dir, DirBuilder, File, remove_file, remove_dir}; -use std::io::{self, Read, Seek, Write}; -use std::path::{Path, PathBuf}; +include!("src/rules_archive.rs"); - -// use zip::result::ZipResult; -use zip::write::{ZipWriter, SimpleFileOptions}; -use zip::CompressionMethod; - -/// Zip up all the yaml files in the directories in `rules_dir/sub_dir_name`` and add the zipped file to `archive_zip`. -/// `rules_dir` is the full path to MathCAT's Rules dir (the input), with `sub_dir_name` the (relative) name of the sub dir to look into. -/// `out_dir`` is the full to the build dir's "out" file (where we are allowed to write) -/// For example, if we have the input ".../Rules/Langauges", then we create a zip file for each subdir with yaml files in it. -/// So we get out_dir/Rules/Langauges/en/en.zip, out_dir/Rules/Langauges/es/es.zip, etc. -/// The resulting archive will reproduce the Rules tree but with the yaml files zipped up per/directory. -fn zip_dir(rules_dir: &Path, archive_zip: &mut ZipWriter, options: SimpleFileOptions, out_dir: &Path, current_out_dir: &Path) -> Result<(), std::io::Error> { - for entry in read_dir(rules_dir)?.flatten() { - let entry_path = entry.path(); - - // .zip files return true for is_dir() -- test in case there is some leftover zip files - if let Some(suffix) = entry_path.extension() && suffix == "zip" { - continue; - } - // println!("trying dir entry {:?}", entry_path.to_str()); - if entry_path.is_dir(){ - if let Some(dir_name) = entry_path.components().next_back() { - let dir_name = dir_name.as_os_str().to_str().unwrap(); - if dir_name == "zz" { // test dir - continue; - } - let zip_name = dir_name.to_string() + ".zip"; // e.g., en.zip - // println!("cargo::warning=zip_name='{}'", &zip_name); - let current_out_dir_zip_path = current_out_dir.join(dir_name); // e.g., ...out/Rules/Languages/en - // println!("cargo::warning=current_out_dir_zip_path='{}'", ¤t_out_dir_zip_path.to_string_lossy()); - - // make sure the appropriate directory exists in 'out' - DirBuilder::new().recursive(true).create(¤t_out_dir_zip_path).unwrap(); - let zipped_dir_file_name = current_out_dir_zip_path.join(&zip_name); // e.g., ...out/Rules/Languages/en/en.zip - let zip_file = match File::create(&zipped_dir_file_name) { - Ok(file) => file, - Err(e) => return Err(std::io::Error::other( - format!("build.rs couldn't create {:?}: {}", zip_name, e))), - }; - let mut zip = ZipWriter::new(zip_file); - let n_files_in_zip = zip_entry(&mut zip, &entry_path, &PathBuf::from("."), options)?; - zip.finish()?; - if n_files_in_zip > 0 { - // Add the file to full archive with the proper relative path (e.g., Languages/en) - let relative_out_dir = current_out_dir_zip_path.strip_prefix(out_dir).unwrap(); // e.g., Rules/Langauges/en - add_file_to_zip(archive_zip, &zipped_dir_file_name, &relative_out_dir.join(&zip_name), options)?; - } else { - // delete the .zip file that isn't used -- doesn't really matter, but removes some clutter - remove_file(&zipped_dir_file_name)?; - remove_dir(¤t_out_dir_zip_path)?; - } - } - } else if let Some(suffix) = &entry_path.extension() { - // definitions.yaml, others??? - let suffix = suffix.to_ascii_lowercase(); - if suffix == "yaml" || suffix == "yml" { - // make sure the appropriate directory exists in 'out' - DirBuilder::new().recursive(true).create(current_out_dir).unwrap(); - let entry_name = entry_path.components().next_back().unwrap().as_os_str().to_str().unwrap(); - let out_dir_file_name = current_out_dir.join(entry_name); // e.g., ...out/Rules/prefs.yaml - std::fs::copy(&entry_path, &out_dir_file_name)?; - let relative_out_dir = out_dir_file_name.strip_prefix(out_dir).unwrap(); - add_file_to_zip(archive_zip, relative_out_dir, relative_out_dir, options)?; - - } - } - } - return Ok( () ); -} - -/// This differs from `zip_dir` in that it does _not_ zip up the directory. Each individual file is zipped so that when the full archive -/// is unzipped, the directory contents do not need to be unzipped. -/// For example, Rules/prefs.yaml and Rules/Intent/general.yaml will exists in the unzipped archive. -fn zip_other_files(rules_dir: &Path, archive_zip: &mut ZipWriter, options: SimpleFileOptions, out_dir: &Path, current_out_dir: &Path) -> Result<(), std::io::Error> { - for entry in read_dir(rules_dir)? { - let entry = entry?; - let entry_path = entry.path(); - let entry_name = entry_path.components().next_back().unwrap().as_os_str().to_str().unwrap(); - - if entry_path.is_dir(){ - if entry_name == "Intent" { // handled elsewhere - zip_other_files(&rules_dir.join("Intent"), archive_zip, options, out_dir, ¤t_out_dir.join("Intent"))?; - } - } else if let Some(suffix) = &entry_path.extension() { - let suffix = suffix.to_ascii_lowercase(); - if suffix == "yaml" || suffix == "yml" { - // make sure the appropriate directory exists in 'out' - DirBuilder::new().recursive(true).create(current_out_dir).unwrap(); - let out_dir_file_name = current_out_dir.join(entry_name); // e.g., ...out/Rules/prefs.yaml - std::fs::copy(&entry_path, &out_dir_file_name)?; - let relative_out_dir = out_dir_file_name.strip_prefix(out_dir).unwrap(); - add_file_to_zip(archive_zip, relative_out_dir, relative_out_dir, options)?; - - } - } - } - return Ok( () ); -} - -/// Adds the `path` relative to the outdir to the `zip`` archive -fn add_file_to_zip( - zip: &mut ZipWriter, - in_dir_path: &Path, - out_dir_path: &Path, - options: SimpleFileOptions, -) -> io::Result<()> { - zip.start_file_from_path(out_dir_path, options)?; - let mut file = File::open(in_dir_path)?; - let mut buffer = Vec::new(); - - file.read_to_end(&mut buffer)?; - zip.write_all(&buffer)?; - return Ok(()); -} - -#[allow(clippy::unused_io_amount)] -fn zip_entry( - zip: &mut ZipWriter, - full_path: &Path, - relative_path: &Path, - options: SimpleFileOptions -) -> io::Result { - let mut n_files_in_zip = 0; - // println!("zip_entry:\n full_path: {}\n relative_path: {}\n current working dir: {}", full_path.display(), relative_path.display(), std::env::current_dir()?.display()); - if full_path.is_dir() { - for entry in read_dir(full_path)? { - let entry_path = entry?.path(); - let entry_name = entry_path.components().next_back().unwrap().as_os_str().to_str().unwrap(); - n_files_in_zip += zip_entry(zip, &entry_path, &relative_path.join(entry_name), options)?; - } - } else if let Some(suffix) = full_path.extension() { - let suffix = suffix.to_ascii_lowercase(); - if suffix == "yaml" || suffix == "yml" { - add_file_to_zip(zip, full_path, relative_path, options)?; - n_files_in_zip += 1; - } - } - - return Ok(n_files_in_zip); -} - -/// Zip up each language and braille dir -/// Note: regional variations (including zh-cn and zh-tw) are zipped together into one zip file fn main() { println!("cargo::rerun-if-changed=build.rs"); + println!("cargo::rerun-if-changed=src/rules_archive.rs"); println!("cargo::rerun-if-changed=Rules"); // This doesn't work because the build claims OUT_DIR is not defined(?) // let archive = PathBuf::from(concat!(env!("OUT_DIR"),"/rules.zip")); if std::env::var("CARGO_FEATURE_INCLUDE_ZIP").is_ok() { - let out_dir = std::env::var_os("OUT_DIR").unwrap(); - let out_dir = PathBuf::from(&out_dir); - let rules_dir = std::env::current_dir().unwrap().join("Rules") ; - let rules_out_dir = PathBuf::from(&out_dir).join("Rules"); - - if std::env::set_current_dir(&out_dir).is_err() { - println!("cargo::warning=couldn't change to directory '{}'", out_dir.display()); - return; - } - let archive_path = PathBuf::from("rules.zip"); // A zip file containing all the zip files. - // println!("cargo::warning=zip file location: '{:?}'", archive_path.to_str()); - let compile_target = std::env::var("CARGO_CFG_TARGET_FAMILY").unwrap(); // build.rs has target_family = build machine, not real target - let compression_method = if compile_target == "wasm" { - CompressionMethod::DEFLATE // although BZIP2 seems better in terms of smaller, it won't compile for WASM - } else { - CompressionMethod::BZIP2 - }; - let zip_options = SimpleFileOptions::default().compression_method(compression_method) - .compression_level(Some(9)); - // let zip_options = SimpleFileOptions::default() - // .compression_level(Some(9)); - - // println!("cargo::warning=rules directory '{:?}'", &rules_dir.to_string_lossy()); - let archive_zip_file = match File::create(&archive_path) { - Ok(file) => file, - Err(e) => panic!("build.rs couldn't create {:?}: {}", archive_path.to_str(), e), - }; - - let mut archive_zip = ZipWriter::new(archive_zip_file); - - - if let Err(e) = zip_other_files(&rules_dir, &mut archive_zip, zip_options, &out_dir, &rules_out_dir) { - panic!("Error: {}", e); - } - - if let Err(e) = zip_dir(&rules_dir.join("Languages"), &mut archive_zip, zip_options, &out_dir, &rules_out_dir.join("Languages")) { - panic!("Error: {}", e); - } - if let Err(e) = zip_dir(&rules_dir.join("Braille"), &mut archive_zip, zip_options, &out_dir, &rules_out_dir.join("Braille")) { - panic!("Error: {}", e); - } - if let Err(e) = archive_zip.finish() { - panic!("Error in zip.finish(): {}", e); + let out_dir = PathBuf::from(std::env::var_os("OUT_DIR").unwrap()); + let rules_dir = std::env::current_dir().unwrap().join("Rules"); + let staging = out_dir.join("rules_src"); + if staging.exists() { + let _ = std::fs::remove_dir_all(&staging); + } + if let Err(e) = copy_rules_tree(&rules_dir, &staging, true) { + panic!("build.rs failed to stage minimized Rules: {}", e); + } + let archive_path = out_dir.join("rules.zip"); + if let Err(e) = write_rules_archive(&staging, &archive_path, include_zip_compression()) { + panic!("build.rs failed to write {}: {}", archive_path.display(), e); } } } diff --git a/src/bin/package_rules.rs b/src/bin/package_rules.rs new file mode 100644 index 000000000..261059bea --- /dev/null +++ b/src/bin/package_rules.rs @@ -0,0 +1,230 @@ +//! Package `Rules/` into `Rules.zip` or `Rules-minimized.zip`. +//! +//! Usage: +//! cargo run --bin package-rules -- Rules Rules.zip +//! cargo run --bin package-rules -- Rules Rules-minimized.zip --minimize + +#![allow(clippy::needless_return)] + +include!("../rules_archive.rs"); + +use clap::Parser; +use std::process::ExitCode; + +#[derive(Parser)] +#[command( + name = "package-rules", + about = "Package MathCAT Rules/ into a zip archive. \ + Use --minimize to strip comments from Languages unicode YAML." +)] +struct Options { + /// Path to the Rules directory + source: PathBuf, + /// Output zip file path (e.g. Rules.zip) + output: PathBuf, + /// Emit compact unicode.yaml / unicode-full.yaml without comments (speech languages only) + #[arg(long)] + minimize: bool, +} + +fn main() -> ExitCode { + let cli = Options::parse(); + if cli.source.file_name().and_then(|n| n.to_str()) != Some("Rules") { + eprintln!( + "error: expected a directory named 'Rules', got '{}'", + cli.source.display() + ); + return ExitCode::from(1); + } + + match package_rules( + &cli.source, + &cli.output, + cli.minimize, + downloadable_compression(), + ) { + Ok(minimized) => { + let label = if cli.minimize { "minimized" } else { "standard" }; + println!("Created {} archive: {}", label, cli.output.display()); + if cli.minimize { + println!(" minimized YAML files: {}", minimized); + } + return ExitCode::SUCCESS; + } + Err(e) => { + eprintln!("error: {}", e); + return ExitCode::from(1); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::fs; + use std::io::{Cursor, Read}; + use tempfile::tempdir; + use zip::ZipArchive; + + fn read_nested_zip_text(outer: &[u8], outer_path: &str, inner_path: &str) -> String { + let mut archive = ZipArchive::new(Cursor::new(outer)).unwrap(); + let mut inner_bytes = Vec::new(); + archive + .by_name(outer_path) + .unwrap() + .read_to_end(&mut inner_bytes) + .unwrap(); + let mut inner = ZipArchive::new(Cursor::new(inner_bytes)).unwrap(); + let mut text = String::new(); + inner + .by_name(inner_path) + .unwrap() + .read_to_string(&mut text) + .unwrap(); + return text; + } + + fn outer_names(bytes: &[u8]) -> Vec { + let mut archive = ZipArchive::new(Cursor::new(bytes)).unwrap(); + let mut names: Vec = (0..archive.len()) + .map(|i| archive.by_index(i).unwrap().name().replace('\\', "/")) + .collect(); + names.sort(); + return names; + } + + fn inner_method(bytes: &[u8], outer_path: &str) -> zip::CompressionMethod { + let mut archive = ZipArchive::new(Cursor::new(bytes)).unwrap(); + let mut inner_bytes = Vec::new(); + archive + .by_name(outer_path) + .unwrap() + .read_to_end(&mut inner_bytes) + .unwrap(); + let mut inner = ZipArchive::new(Cursor::new(inner_bytes)).unwrap(); + return inner.by_index(0).unwrap().compression(); + } + + fn outer_method(bytes: &[u8], name: &str) -> zip::CompressionMethod { + let mut archive = ZipArchive::new(Cursor::new(bytes)).unwrap(); + return archive.by_name(name).unwrap().compression(); + } + + #[test] + fn minimize_yaml_strips_comments() { + let source = "---\n# comment\n - \"+\": [t: \"plus\"] # inline\n"; + let minimized = minimize_yaml_text(source).unwrap(); + assert!(!minimized.contains('#')); + let docs = yaml_rust::YamlLoader::load_from_str(&minimized).unwrap(); + assert_eq!(docs.len(), 1); + } + + #[test] + fn minimize_quotes_infinity() { + let source = "---\n - \"∞\": [t: \"infinity\"]\n"; + let minimized = minimize_yaml_text(source).unwrap(); + assert!( + minimized.contains("\"infinity\"") || minimized.contains("'infinity'"), + "infinity must be quoted, got: {minimized}" + ); + assert!(!looks_like_unquoted_infinity(&minimized)); + let docs = yaml_rust::YamlLoader::load_from_str(&minimized).unwrap(); + assert_eq!(docs.len(), 1); + } + + #[test] + fn package_rules_standard_zip_layout() { + let tmp = tempdir().unwrap(); + let rules = tmp.path().join("Rules"); + let lang = rules.join("Languages").join("en"); + fs::create_dir_all(&lang).unwrap(); + fs::write(rules.join("prefs.yaml"), "- SpeechStyle: [t: \"ClearSpeak\"]\n").unwrap(); + fs::write(lang.join("unicode.yaml"), "- \"+\": [t: \"plus\"]\n").unwrap(); + + let output = tmp.path().join("Rules.zip"); + package_rules(&rules, &output, false, downloadable_compression()).unwrap(); + + let bytes = fs::read(&output).unwrap(); + let names = outer_names(&bytes); + assert!(names.contains(&"Rules/prefs.yaml".to_string())); + assert!(names.contains(&"Rules/Languages/en/en.zip".to_string())); + assert!(!names.iter().any(|n| n.ends_with("unicode.yaml"))); + assert_eq!( + inner_method(&bytes, "Rules/Languages/en/en.zip"), + zip::CompressionMethod::BZIP2 + ); + assert_eq!( + outer_method(&bytes, "Rules/prefs.yaml"), + zip::CompressionMethod::DEFLATE + ); + let unicode = read_nested_zip_text(&bytes, "Rules/Languages/en/en.zip", "unicode.yaml"); + assert_eq!(unicode.replace("\r\n", "\n"), "- \"+\": [t: \"plus\"]\n"); + } + + #[test] + fn should_not_minimize_braille_unicode() { + let tmp = tempdir().unwrap(); + let rules = tmp.path().join("Rules"); + let braille = rules.join("Braille").join("Nemeth"); + fs::create_dir_all(&braille).unwrap(); + let source = "---\n# keep this comment\n - \"1\": [t: \"N⠂\"]\n"; + fs::write(braille.join("unicode.yaml"), source).unwrap(); + + let output = tmp.path().join("Rules-minimized.zip"); + let minimized = package_rules(&rules, &output, true, downloadable_compression()).unwrap(); + assert_eq!(minimized, 0); + + let bytes = fs::read(&output).unwrap(); + let text = read_nested_zip_text(&bytes, "Rules/Braille/Nemeth/Nemeth.zip", "unicode.yaml"); + assert_eq!(text.replace("\r\n", "\n"), source.replace("\r\n", "\n")); + } + + #[test] + fn package_rules_minimized_matches_release_layout() { + let tmp = tempdir().unwrap(); + let rules = tmp.path().join("Rules"); + let lang = rules.join("Languages").join("en"); + fs::create_dir_all(&lang).unwrap(); + fs::write( + lang.join("unicode.yaml"), + "---\n# header comment\n - \"+\": [t: \"plus\"] # trailing\n - \"-\": [t: \"minus\"]\n", + ) + .unwrap(); + fs::write( + lang.join("definitions.yaml"), + "---\n - AdditionalFunctionNames:\n - real=inf\n", + ) + .unwrap(); + + let output = tmp.path().join("Rules-minimized.zip"); + let minimized = package_rules(&rules, &output, true, downloadable_compression()).unwrap(); + assert_eq!(minimized, 1); + + let bytes = fs::read(&output).unwrap(); + let names = outer_names(&bytes); + assert!(names.contains(&"Rules/Languages/en/en.zip".to_string())); + assert!(!names.iter().any(|n| n.ends_with("unicode.yaml"))); + + let unicode = read_nested_zip_text(&bytes, "Rules/Languages/en/en.zip", "unicode.yaml"); + let defs = read_nested_zip_text(&bytes, "Rules/Languages/en/en.zip", "definitions.yaml"); + assert!(!unicode.contains('#')); + assert!(defs.contains("real=inf")); + assert_eq!(yaml_rust::YamlLoader::load_from_str(&unicode).unwrap().len(), 1); + } + + #[test] + fn skips_zz_test_language() { + let tmp = tempdir().unwrap(); + let rules = tmp.path().join("Rules"); + fs::create_dir_all(rules.join("Languages").join("zz")).unwrap(); + fs::write(rules.join("Languages").join("zz").join("unicode.yaml"), "- a: 1\n").unwrap(); + fs::create_dir_all(rules.join("Languages").join("en")).unwrap(); + fs::write(rules.join("Languages").join("en").join("unicode.yaml"), "- b: 2\n").unwrap(); + + let output = tmp.path().join("Rules.zip"); + package_rules(&rules, &output, false, downloadable_compression()).unwrap(); + let names = outer_names(&fs::read(&output).unwrap()); + assert!(names.contains(&"Rules/Languages/en/en.zip".to_string())); + assert!(!names.iter().any(|n| n.contains("/zz"))); + } +} diff --git a/src/interface.rs b/src/interface.rs index 012345056..3177c22c8 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -651,7 +651,8 @@ pub fn get_supported_languages() -> Result> { let mut language_paths = lang_paths.iter() .map(|path| path.strip_prefix(&lang_dir).unwrap() .to_string_lossy() - .replace(std::path::MAIN_SEPARATOR, "-") + // include-zip stores paths with '/'; native trees use MAIN_SEPARATOR. + .replace(['/', '\\'], "-") .to_string()) .filter(|string_path| !string_path.is_empty() ) .collect::>(); diff --git a/src/prefs.rs b/src/prefs.rs index cad23ba6d..0e04414f6 100644 --- a/src/prefs.rs +++ b/src/prefs.rs @@ -26,7 +26,7 @@ use std::cell::RefCell; use std::rc::Rc; use log::{debug, error, warn}; use std::path::{Path, PathBuf}; -use std::sync::LazyLock; +use std::sync::{LazyLock, Mutex}; use crate::speech::{as_str_checked, RulesFor, FileAndTime}; use std::collections::{HashMap, HashSet}; use phf::phf_set; @@ -458,6 +458,14 @@ impl PreferenceManager { /// Unzip the files if needed /// Returns true if it unzipped them pub fn unzip_files(path: &Path, lang: &str, default_lang: Option<&str>) -> Result { + // cargo test runs many threads against the same Rules/ tree. Extracting en.zip + // concurrently can truncate unicode.yaml and yaml-rust then reports "Didn't find rules!". + static UNZIP_LOCK: Mutex<()> = Mutex::new(()); + let _guard = UNZIP_LOCK.lock().unwrap_or_else(|poisoned| poisoned.into_inner()); + return PreferenceManager::unzip_files_locked(path, lang, default_lang); + } + + fn unzip_files_locked(path: &Path, lang: &str, default_lang: Option<&str>) -> Result { thread_local!{ /// when a language/braille code dir is unzipped, it is recorded here static UNZIPPED_FILES: RefCell> = RefCell::new( HashSet::with_capacity(31)); @@ -479,7 +487,7 @@ impl PreferenceManager { // try again in parent dir of regional language let language = lang.split_once('-').unwrap_or((lang, "")).0; // get the parent language // debug!("unzip_files: trying again in parent language: {}", language); - PreferenceManager::unzip_files(path, language, default_lang) + PreferenceManager::unzip_files_locked(path, language, default_lang) .with_context(|| format!("Couldn't open zip file {zip_file_string} in parent {language}: {e}."))? } else { // maybe just regional dialects @@ -488,7 +496,7 @@ impl PreferenceManager { for dir in regional_dirs { // debug!("unzip_files: trying again in subdir: {}", dir.display()); let language = format!("{}-{}", lang, dir.file_name().unwrap().to_str().unwrap()); - if let Ok(result) =PreferenceManager::unzip_files(path, &language, default_lang) { + if let Ok(result) =PreferenceManager::unzip_files_locked(path, &language, default_lang) { return Ok(result); } } @@ -501,11 +509,6 @@ impl PreferenceManager { }; UNZIPPED_FILES.with( |unzipped_files| unzipped_files.borrow_mut().insert(zip_file_string.clone()) ); - // debug!(" unzip_files: unzipped {} files from {}", result, &zip_file_string); - // UNZIPPED_FILES.with( |unzipped_files| { - // debug!("unzip_files: unzipped_files: {:?}", unzipped_files.borrow()); - // }); - return Ok(result); } diff --git a/src/rules_archive.rs b/src/rules_archive.rs new file mode 100644 index 000000000..108220c28 --- /dev/null +++ b/src/rules_archive.rs @@ -0,0 +1,385 @@ +// Shared Rules archive writer used by `build.rs` (include-zip) and the `package-rules` binary. +// +// Layout matches native MathCAT extraction: +// - `Rules/*.yaml` and `Rules/Intent/**` stay loose in the outer archive +// - each `Rules/Languages//` and `Rules/Braille//` directory is stored as `/.zip` +// - `Rules/Languages/zz` (synthetic test language) is omitted +// +// Inner language/braille zips always use BZIP2. Downloadable `Rules.zip` uses DEFLATE for the +// outer archive so Windows Explorer / `unzip` can open it. The include-zip embed uses BZIP2 +// for both layers (MathCAT's `zip` crate reads it; zip 8.x bzip2 is pure Rust and works on wasm). + +use std::fs::{self, File, read_dir}; +use std::io::{self, Cursor, Read, Seek, Write}; +use std::path::{Path, PathBuf}; + +use yaml_rust::{YamlEmitter, YamlLoader}; +use zip::write::{SimpleFileOptions, ZipWriter}; +use zip::CompressionMethod; + +const YAML_SUFFIXES: [&str; 2] = ["yaml", "yml"]; +const MINIMIZE_NAMES: [&str; 2] = ["unicode.yaml", "unicode-full.yaml"]; +const SKIP_LANGUAGE_DIR: &str = "zz"; +const ARCHIVE_ROOT: &str = "Rules"; + +/// Compression methods for nested language zips vs the outer archive. +#[derive(Clone, Copy)] +pub struct ArchiveCompression { + pub inner: CompressionMethod, + pub outer: CompressionMethod, +} + +/// Inner BZIP2 / outer BZIP2 — used for the include-zip embed (only MathCAT reads it). +pub fn include_zip_compression() -> ArchiveCompression { + return ArchiveCompression { + inner: CompressionMethod::BZIP2, + outer: CompressionMethod::BZIP2, + }; +} + +/// Inner BZIP2 / outer DEFLATE — used for downloadable `Rules.zip` / `Rules-minimized.zip`. +pub fn downloadable_compression() -> ArchiveCompression { + return ArchiveCompression { + inner: CompressionMethod::BZIP2, + outer: CompressionMethod::DEFLATE, + }; +} + +fn zip_options(method: CompressionMethod) -> SimpleFileOptions { + return SimpleFileOptions::default() + .compression_method(method) + .compression_level(Some(9)); +} + +fn is_yaml_file(path: &Path) -> bool { + return path + .extension() + .map(|ext| { + let ext = ext.to_ascii_lowercase(); + YAML_SUFFIXES.iter().any(|s| ext == *s) + }) + .unwrap_or(false); +} + +fn is_zip_file(path: &Path) -> bool { + return path.extension().map(|ext| ext.eq_ignore_ascii_case("zip")).unwrap_or(false); +} + +fn posix_path(parts: &[&str]) -> String { + return parts.join("/"); +} + +fn posix_join(prefix: &str, name: &str) -> String { + if prefix.is_empty() { + return name.to_string(); + } + return format!("{}/{}", prefix, name); +} + +fn file_name_str(path: &Path) -> io::Result { + let name = path + .file_name() + .and_then(|n| n.to_str()) + .ok_or_else(|| io::Error::other(format!("non-UTF-8 file name: {}", path.display())))?; + return Ok(name.to_string()); +} + +/// Speech unicode YAML only — braille `unicode.yaml` stays verbatim. +fn should_minimize(path: &Path) -> bool { + let name = path.file_name().and_then(|n| n.to_str()).unwrap_or(""); + if !MINIMIZE_NAMES.contains(&name) { + return false; + } + return path.components().any(|c| c.as_os_str() == "Languages"); +} + +/// Load YAML, drop comments, re-emit. Returns `Err` if yaml-rust cannot parse the file. +pub fn minimize_yaml_text(text: &str) -> Result { + let normalized = text.replace('\t', " "); + let docs = YamlLoader::load_from_str(&normalized).map_err(|e| e.to_string())?; + if docs.is_empty() { + return Ok(String::new()); + } + let mut out = String::new(); + { + let mut emitter = YamlEmitter::new(&mut out); + emitter.compact(true); + for doc in &docs { + emitter.dump(doc).map_err(|e| e.to_string())?; + } + } + if !out.ends_with('\n') { + out.push('\n'); + } + // yaml-rust quotes scalars that parse as f64 (including "infinity"); keep a guard in case + // a future emitter change stops doing that — unquoted `infinity` becomes a float on load. + if looks_like_unquoted_infinity(&out) { + return Err("emitted unquoted 'infinity' (yaml-rust would treat it as a float)".to_string()); + } + return Ok(out); +} + +fn looks_like_unquoted_infinity(yaml: &str) -> bool { + // Match a YAML value `infinity` that is not inside quotes. + for line in yaml.lines() { + let trimmed = line.trim(); + if trimmed == "infinity" || trimmed.ends_with(": infinity") || trimmed.ends_with("- infinity") { + return true; + } + } + return false; +} + +fn minimize_yaml_file(src: &Path, dst: &Path) -> Result<(), String> { + let text = fs::read_to_string(src).map_err(|e| e.to_string())?; + let minimized = minimize_yaml_text(&text)?; + // One document after a successful load+emit — MathCAT requires docs.len() == 1. + let docs = YamlLoader::load_from_str(&minimized).map_err(|e| e.to_string())?; + if docs.len() != 1 { + return Err(format!("minimized YAML is {} documents, expected 1", docs.len())); + } + let _ = docs; + fs::write(dst, minimized).map_err(|e| e.to_string())?; + return Ok(()); +} + +/// Copy a Rules tree. When `minify` is true, rewrite `Languages/**/unicode.yaml` and +/// `unicode-full.yaml` (comments stripped). `Languages/zz` is omitted. Returns the number of +/// files successfully minimized. +pub fn copy_rules_tree(src: &Path, dst: &Path, minify: bool) -> io::Result { + fs::create_dir_all(dst)?; + return copy_dir(src, dst, minify, false); +} + +fn copy_dir(src: &Path, dst: &Path, minify: bool, parent_is_languages: bool) -> io::Result { + let mut minimized = 0usize; + for entry in read_dir(src)? { + let entry = entry?; + let src_path = entry.path(); + let name = file_name_str(&src_path)?; + if parent_is_languages && name == SKIP_LANGUAGE_DIR { + continue; + } + if is_zip_file(&src_path) { + continue; + } + let dst_path = dst.join(&name); + if src_path.is_dir() { + fs::create_dir_all(&dst_path)?; + minimized += copy_dir(&src_path, &dst_path, minify, name == "Languages")?; + } else if minify && should_minimize(&src_path) { + match minimize_yaml_file(&src_path, &dst_path) { + Ok(()) => minimized += 1, + Err(e) => { + eprintln!( + "warning: could not minimize {}; copied verbatim ({})", + src_path.display(), + e + ); + fs::copy(&src_path, &dst_path)?; + } + } + } else { + if let Some(parent) = dst_path.parent() { + fs::create_dir_all(parent)?; + } + fs::copy(&src_path, &dst_path)?; + } + } + return Ok(minimized); +} + +fn add_file_to_zip( + zip: &mut ZipWriter, + in_path: &Path, + zip_name: &str, + options: SimpleFileOptions, +) -> io::Result<()> { + zip.start_file(zip_name, options) + .map_err(io::Error::other)?; + let mut file = File::open(in_path)?; + let mut buffer = Vec::new(); + file.read_to_end(&mut buffer)?; + zip.write_all(&buffer)?; + return Ok(()); +} + +fn add_bytes_to_zip( + zip: &mut ZipWriter, + zip_name: &str, + bytes: &[u8], + options: SimpleFileOptions, +) -> io::Result<()> { + zip.start_file(zip_name, options) + .map_err(io::Error::other)?; + zip.write_all(bytes)?; + return Ok(()); +} + +fn zip_entry( + zip: &mut ZipWriter, + full_path: &Path, + relative_path: &str, + options: SimpleFileOptions, +) -> io::Result { + let mut n_files_in_zip = 0; + if full_path.is_dir() { + for entry in read_dir(full_path)? { + let entry_path = entry?.path(); + if is_zip_file(&entry_path) { + continue; + } + let entry_name = file_name_str(&entry_path)?; + let child_rel = posix_join(relative_path, &entry_name); + n_files_in_zip += zip_entry(zip, &entry_path, &child_rel, options)?; + } + } else if is_yaml_file(full_path) { + add_file_to_zip(zip, full_path, relative_path, options)?; + n_files_in_zip += 1; + } + return Ok(n_files_in_zip); +} + +fn write_inner_zip(source_dir: &Path, inner: SimpleFileOptions) -> io::Result>> { + let cursor = Cursor::new(Vec::new()); + let mut zip = ZipWriter::new(cursor); + let n_files = zip_entry(&mut zip, source_dir, "", inner)?; + let cursor = zip.finish().map_err(io::Error::other)?; + if n_files == 0 { + return Ok(None); + } + return Ok(Some(cursor.into_inner())); +} + +/// Zip each immediate subdirectory of Languages/ or Braille/ into `/.zip`. +fn zip_dir( + rules_section: &Path, + archive_zip: &mut ZipWriter, + inner: SimpleFileOptions, + outer: SimpleFileOptions, + archive_prefix: &str, +) -> io::Result<()> { + if !rules_section.is_dir() { + return Ok(()); + } + for entry in read_dir(rules_section)? { + let entry_path = entry?.path(); + if is_zip_file(&entry_path) { + continue; + } + if entry_path.is_dir() { + let dir_name = file_name_str(&entry_path)?; + if dir_name == SKIP_LANGUAGE_DIR { + continue; + } + if let Some(bytes) = write_inner_zip(&entry_path, inner)? { + let zip_name = posix_path(&[archive_prefix, &dir_name, &format!("{}.zip", dir_name)]); + add_bytes_to_zip(archive_zip, &zip_name, &bytes, outer)?; + } + } else if is_yaml_file(&entry_path) { + // e.g. Rules/Braille/definitions.yaml + let name = file_name_str(&entry_path)?; + let zip_name = posix_path(&[archive_prefix, &name]); + add_file_to_zip(archive_zip, &entry_path, &zip_name, outer)?; + } + } + return Ok(()); +} + +/// Loose YAML at Rules/ and Rules/Intent/ (not zipped per-directory). +fn zip_other_files( + rules_dir: &Path, + archive_zip: &mut ZipWriter, + outer: SimpleFileOptions, + archive_prefix: &str, +) -> io::Result<()> { + for entry in read_dir(rules_dir)? { + let entry_path = entry?.path(); + let entry_name = file_name_str(&entry_path)?; + if entry_path.is_dir() { + if entry_name == "Intent" { + zip_other_files( + &rules_dir.join("Intent"), + archive_zip, + outer, + &posix_join(archive_prefix, "Intent"), + )?; + } + } else if is_yaml_file(&entry_path) { + let zip_name = posix_join(archive_prefix, &entry_name); + add_file_to_zip(archive_zip, &entry_path, &zip_name, outer)?; + } + } + return Ok(()); +} + +/// Write a MathCAT Rules archive from an already-staged tree (`rules_dir` is the `Rules` folder). +pub fn write_rules_archive( + rules_dir: &Path, + output: &Path, + compression: ArchiveCompression, +) -> io::Result<()> { + if let Some(parent) = output.parent() + && !parent.as_os_str().is_empty() + { + fs::create_dir_all(parent)?; + } + let inner = zip_options(compression.inner); + let outer = zip_options(compression.outer); + let archive_zip_file = File::create(output)?; + let mut archive_zip = ZipWriter::new(archive_zip_file); + + zip_other_files(rules_dir, &mut archive_zip, outer, ARCHIVE_ROOT)?; + zip_dir( + &rules_dir.join("Languages"), + &mut archive_zip, + inner, + outer, + &posix_join(ARCHIVE_ROOT, "Languages"), + )?; + zip_dir( + &rules_dir.join("Braille"), + &mut archive_zip, + inner, + outer, + &posix_join(ARCHIVE_ROOT, "Braille"), + )?; + + archive_zip.finish().map_err(io::Error::other)?; + return Ok(()); +} + +/// Copy (optionally minify) `source` and write a downloadable or embeddable Rules archive. +pub fn package_rules( + source: &Path, + output: &Path, + minify: bool, + compression: ArchiveCompression, +) -> io::Result { + if !source.is_dir() { + return Err(io::Error::new( + io::ErrorKind::NotFound, + format!("Rules source directory not found: {}", source.display()), + )); + } + + let staging_root = tempfile_staging_dir()?; + let staged_rules = staging_root.join(ARCHIVE_ROOT); + let minimized = copy_rules_tree(source, &staged_rules, minify)?; + write_rules_archive(&staged_rules, output, compression)?; + let _ = fs::remove_dir_all(&staging_root); + return Ok(minimized); +} + +fn tempfile_staging_dir() -> io::Result { + let base = std::env::temp_dir().join(format!( + "mathcat-rules-{}-{}", + std::process::id(), + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .map(|d| d.as_nanos()) + .unwrap_or(0) + )); + fs::create_dir_all(&base)?; + return Ok(base); +} From 2e2c19cf9532af816d488fa00b8e5cb7a71ce679 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Tue, 18 Aug 2026 00:23:37 -0700 Subject: [PATCH 054/157] Serialize rules unzip and YAML reads during parallel tests Co-authored-by: Cursor --- src/prefs.rs | 6 +----- src/shim_filesystem.rs | 32 +++++++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/prefs.rs b/src/prefs.rs index 0e04414f6..2fe69cdf3 100644 --- a/src/prefs.rs +++ b/src/prefs.rs @@ -26,7 +26,7 @@ use std::cell::RefCell; use std::rc::Rc; use log::{debug, error, warn}; use std::path::{Path, PathBuf}; -use std::sync::{LazyLock, Mutex}; +use std::sync::LazyLock; use crate::speech::{as_str_checked, RulesFor, FileAndTime}; use std::collections::{HashMap, HashSet}; use phf::phf_set; @@ -458,10 +458,6 @@ impl PreferenceManager { /// Unzip the files if needed /// Returns true if it unzipped them pub fn unzip_files(path: &Path, lang: &str, default_lang: Option<&str>) -> Result { - // cargo test runs many threads against the same Rules/ tree. Extracting en.zip - // concurrently can truncate unicode.yaml and yaml-rust then reports "Didn't find rules!". - static UNZIP_LOCK: Mutex<()> = Mutex::new(()); - let _guard = UNZIP_LOCK.lock().unwrap_or_else(|poisoned| poisoned.into_inner()); return PreferenceManager::unzip_files_locked(path, lang, default_lang); } diff --git a/src/shim_filesystem.rs b/src/shim_filesystem.rs index 38ff55106..14c5b26fb 100644 --- a/src/shim_filesystem.rs +++ b/src/shim_filesystem.rs @@ -361,15 +361,40 @@ cfg_if! { } } + // Tests extract language/braille zips in parallel. During extraction, individual YAML + // files can briefly exist in a partially-written state (created/truncated before the + // full contents are flushed). Guard both extraction and YAML reads with the same lock + // so readers never observe truncated YAML. + use std::sync::Mutex; + static RULES_ZIP_EXTRACT_LOCK: Mutex<()> = Mutex::new(()); + + fn should_lock_rules_yaml_path(path: &Path) -> bool { + let s = path.to_string_lossy(); + let is_yaml = s.ends_with(".yaml") || s.ends_with(".yml"); + if !is_yaml { + return false; + } + return s.contains("Rules/Languages/") || s.contains("Rules\\Languages\\") + || s.contains("Rules/Braille/") || s.contains("Rules\\Braille\\"); + } + pub fn read_to_string_shim(path: &Path) -> Result { let path = match path.canonicalize() { Ok(path) => path, Err(_) => path.to_path_buf(), }; debug!("Reading file '{}'", path.display()); - match std::fs::read_to_string(&path) { - Ok(str) => return Ok(str), - Err(e) => bail!("Read error while trying to read {}: {}", path.display(), e), + if should_lock_rules_yaml_path(&path) { + let _guard = RULES_ZIP_EXTRACT_LOCK.lock().unwrap_or_else(|poisoned| poisoned.into_inner()); + match std::fs::read_to_string(&path) { + Ok(str) => return Ok(str), + Err(e) => bail!("Read error while trying to read {}: {}", path.display(), e), + } + } else { + match std::fs::read_to_string(&path) { + Ok(str) => return Ok(str), + Err(e) => bail!("Read error while trying to read {}: {}", path.display(), e), + } } } @@ -386,6 +411,7 @@ cfg_if! { } }, Ok(contents) => { + let _guard = RULES_ZIP_EXTRACT_LOCK.lock().unwrap_or_else(|poisoned| poisoned.into_inner()); let archive = std::io::Cursor::new(contents); let mut zip_archive = zip::ZipArchive::new(archive).unwrap(); zip_archive.extract(dir).expect("Zip extraction failed"); From 5e899d7d66a56d0068a80c09a95c81e445fbadeb Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Tue, 18 Aug 2026 11:54:44 -0700 Subject: [PATCH 055/157] update version number --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 32e83cf27..67522e0b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mathcat" -version = "0.7.6-rc.1" +version = "0.7.7-alpha.1" authors = ["Neil Soiffer "] license = "MIT" description = "MathCAT: Math Capable Assistive Technology ('Speech and braille from MathML')" From 04882d3fa42ebb4430b8245ba1a9101e6d41a784 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Tue, 18 Aug 2026 11:55:29 -0700 Subject: [PATCH 056/157] better speech for missing char used for parsing --- Rules/Languages/en/unicode-full.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rules/Languages/en/unicode-full.yaml b/Rules/Languages/en/unicode-full.yaml index 15c169d6a..8d66bbf9a 100644 --- a/Rules/Languages/en/unicode-full.yaml +++ b/Rules/Languages/en/unicode-full.yaml @@ -3777,7 +3777,7 @@ - "→": [t: "right arrow"] # 0xffeb - "↓": [t: "down arrow"] # 0xffec - "": [t: "unknown or missing object"] # 0xfffc - - "�": [t: "unknown or missing character"] # 0xfffd + - "�": [t: "missing char"] # 0xfffd (used for missing input when entering braille) - "🣑": [t: "is in equilibrium with"] # 0x1F8D1 - "🣒": [t: "is in equilibrium biased to the right with"] # 0x1F8D2 From 25b472b60ee5a9d6340e7e9ef987c58b28f01fb9 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Tue, 18 Aug 2026 12:14:02 -0700 Subject: [PATCH 057/157] udate version # --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 67522e0b3..32e83cf27 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mathcat" -version = "0.7.7-alpha.1" +version = "0.7.6-rc.1" authors = ["Neil Soiffer "] license = "MIT" description = "MathCAT: Math Capable Assistive Technology ('Speech and braille from MathML')" From 67cc5462e7b96b176dbd0544e308b23b8ce3c937 Mon Sep 17 00:00:00 2001 From: Cristian Consonni Date: Wed, 19 Aug 2026 02:03:39 +0200 Subject: [PATCH 058/157] Add option --exclude to audit-translations --- PythonScripts/audit_translations/README.md | 11 ++++++- PythonScripts/audit_translations/auditor.py | 34 +++++++++++++-------- PythonScripts/audit_translations/cli.py | 14 ++++++++- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/PythonScripts/audit_translations/README.md b/PythonScripts/audit_translations/README.md index 8aedf1265..fd399e412 100644 --- a/PythonScripts/audit_translations/README.md +++ b/PythonScripts/audit_translations/README.md @@ -77,6 +77,7 @@ uv run --project PythonScripts audit-translations --list * Region variants are shown as `lang-region` (e.g., `zz-aa`) based on subdirectories under `Rules/Languages/`. * `--source`: Sets the source/reference language. Defaults to `en`. * `--file`: Audits a single specific file instead of the whole directory. +* `--exclude`: Exclude one or more files from the audit. * `--rules-dir`: Override the Rules/Languages directory path. * `--only`: Filter issue types (comma-separated): `missing`, `untranslated`, `extra`, `diffs`, `all`. * `--verbose`: Show detailed output including source/target snippets for rule differences. @@ -100,9 +101,17 @@ uv run audit-translations de # Compare Norwegian Bokmal against Swedish instead of English uv run audit-translations nb --source sv -# Audit only a specific file +# Audit only a specific file (note: --file is incompatible with --exclude) +uv run audit-translations es --file ClearSpeak_Rules.yaml uv run audit-translations es --file SharedRules/default.yaml +# Exclude a list of files from the audit, note that if you use this option before specifying the +# target language you'll need to use the option terminator (--). +# (note: --exclude is incompatible with --file) +uv run audit-translations es --exclude unicode-full.yaml +uv run audit-translations es --exclude unicode-full.yaml unicode.yaml +uv run audit-translations --exclude unicode-full.yaml -- es + # Audit a regional variant (merges Rules/Languages/de and Rules/Languages/de/CH) uv run audit-translations de-CH diff --git a/PythonScripts/audit_translations/auditor.py b/PythonScripts/audit_translations/auditor.py index b67cbf911..37ec44f13 100644 --- a/PythonScripts/audit_translations/auditor.py +++ b/PythonScripts/audit_translations/auditor.py @@ -46,24 +46,31 @@ def is_definitions_file(file_path: str | Path) -> bool: return Path(file_path).name == "definitions.yaml" -def get_yaml_files(lang_dir: Path, region_dir: Path | None = None) -> list[Path]: +def get_yaml_files(lang_dir: Path, region_dir: Path | None = None, excluded_files: list[str] | None = None) -> list[Path]: """Get all YAML files to audit for a language, including region overrides.""" files: set[Path] = set() - def collect_from(directory: Path, root: Path) -> None: + def collect_from(directory: Path, root: Path, excluded: list[str] | None) -> None: if not directory.exists(): return - for f in directory.glob("*.yaml"): - if f.name != "prefs.yaml": - files.add(f.relative_to(root)) - shared_dir = directory / "SharedRules" - if shared_dir.exists(): - for f in shared_dir.glob("*.yaml"): - files.add(f.relative_to(root)) - - collect_from(lang_dir, lang_dir) + + excluded_paths = {Path(path) for path in excluded or []} + + candidates = {f for f in directory.glob("*.yaml") if f.name != "prefs.yaml"} + candidates.update((directory / "SharedRules").glob("*.yaml")) + + relative_candidates = {f.relative_to(directory): f for f in candidates} + + for path in excluded_paths - relative_candidates.keys(): + console.print(f"\n[yellow]⚠ Warning:[/] File to exclude {path} does not exist.") + + files.update( + f.relative_to(root) for relative_path, f in relative_candidates.items() if relative_path not in excluded_paths + ) + + collect_from(lang_dir, lang_dir, excluded_files) if region_dir: - collect_from(region_dir, region_dir) + collect_from(region_dir, region_dir, excluded_files) return sorted(files) @@ -215,6 +222,7 @@ def merge_definitions( def audit_language( language: str, specific_file: str | None = None, + excluded_files: list[str] | None = None, rules_dir: str | None = None, issue_filter: set[str] | None = None, verbose: bool = False, @@ -248,7 +256,7 @@ def audit_language( raise AuditError(f"Target region directory not found: {translated_region_dir}") # Get list of files to audit - files = [specific_file] if specific_file else get_yaml_files(source_dir, source_region_dir) + files = [specific_file] if specific_file else get_yaml_files(source_dir, source_region_dir, excluded_files) print_audit_header(language, len(files), source_language) diff --git a/PythonScripts/audit_translations/cli.py b/PythonScripts/audit_translations/cli.py index 6916a636e..5bdf30e6d 100644 --- a/PythonScripts/audit_translations/cli.py +++ b/PythonScripts/audit_translations/cli.py @@ -30,7 +30,18 @@ def main() -> None: parser.add_argument("language", nargs="?", help="Language code to audit (e.g., 'es', 'de', 'fi')") parser.add_argument("--source", default="en", help="Source/reference language code (default: 'en')") - parser.add_argument("--file", dest="specific_file", help="Audit only a specific file (e.g., 'SharedRules/default.yaml')") + file_group = parser.add_mutually_exclusive_group() + file_group.add_argument( + "--file", + dest="specific_file", + help="Audit only a specific file (e.g., 'SharedRules/default.yaml')", + ) + file_group.add_argument( + "--exclude", + nargs="+", + dest="excluded_files", + help="Exclude a list of files from the audit.", + ) parser.add_argument("--list", action="store_true", help="List available languages") parser.add_argument("--rules-dir", help="Override Rules/Languages directory path") parser.add_argument( @@ -67,6 +78,7 @@ def main() -> None: audit_language( args.language, args.specific_file, + args.excluded_files, args.rules_dir, issue_filter, args.verbose, From 3d267a07461db2e597f03ee22d1e936c45e1e522 Mon Sep 17 00:00:00 2001 From: Cristian Consonni Date: Wed, 19 Aug 2026 03:21:14 +0200 Subject: [PATCH 059/157] Add tests for --exclude option --- .../tests/test_cli_end_to_end.py | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/PythonScripts/audit_translations/tests/test_cli_end_to_end.py b/PythonScripts/audit_translations/tests/test_cli_end_to_end.py index 7876bc0de..4ef5ee9de 100644 --- a/PythonScripts/audit_translations/tests/test_cli_end_to_end.py +++ b/PythonScripts/audit_translations/tests/test_cli_end_to_end.py @@ -127,6 +127,79 @@ def test_cli_main_rich_only_filters_issue_groups(capsys, monkeypatch) -> None: assert "Structure Differences" not in output +@pytest.mark.parametrize( + ("excluded_file", "expected_file", "expected_rule", "unexpected_rule"), + [ + ( + "default.yaml", + "SharedRules/default.yaml", + "shared-only", + "root-only", + ), + ( + "SharedRules/default.yaml", + "default.yaml", + "root-only", + "shared-only", + ), + ], +) +def test_cli_main_exclude_uses_relative_paths( + tmp_path, + capsys, + monkeypatch, + excluded_file, + expected_file, + expected_rule, + unexpected_rule, +) -> None: + """Ensure --exclude distinguishes root files from SharedRules files.""" + rules_dir = tmp_path / "Rules" / "Languages" + source_dir = rules_dir / "en" + target_dir = rules_dir / "de" + + (source_dir / "SharedRules").mkdir(parents=True) + (target_dir / "SharedRules").mkdir(parents=True) + + (source_dir / "default.yaml").write_text( + '- name: root-only\n tag: mo\n match: ".//m:mi"\n replace:\n - t: "root"\n', + encoding="utf-8", + ) + (source_dir / "SharedRules" / "default.yaml").write_text( + '- name: shared-only\n tag: mo\n match: ".//m:mi"\n replace:\n - t: "shared"\n', + encoding="utf-8", + ) + + target_rule = '- name: target-only\n tag: mo\n match: ".//m:mi"\n replace:\n - t: "target"\n' + (target_dir / "default.yaml").write_text( + target_rule, + encoding="utf-8", + ) + (target_dir / "SharedRules" / "default.yaml").write_text( + target_rule, + encoding="utf-8", + ) + + args = [ + "de", + "--rules-dir", + str(rules_dir), + "--exclude", + excluded_file, + "--only", + "missing", + ] + monkeypatch.setattr(sys, "argv", ["audit_translations", *args]) + + audit_cli.main() + output = strip_ansi(capsys.readouterr().out) + + assert "Files to check: 1" in output + assert expected_file in output + assert expected_rule in output + assert unexpected_rule not in output + + def test_cli_main_accepts_source_language(capsys, monkeypatch) -> None: """ Ensure --source changes the reference language without changing target semantics. From 0f4791ccd674d4c0ea78a1576140e09ae1c33315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Wed, 19 Aug 2026 08:39:00 +0200 Subject: [PATCH 060/157] Add test case IDs for CLI main exclude tests --- PythonScripts/audit_translations/tests/test_cli_end_to_end.py | 1 + 1 file changed, 1 insertion(+) diff --git a/PythonScripts/audit_translations/tests/test_cli_end_to_end.py b/PythonScripts/audit_translations/tests/test_cli_end_to_end.py index 4ef5ee9de..40cf3f8b2 100644 --- a/PythonScripts/audit_translations/tests/test_cli_end_to_end.py +++ b/PythonScripts/audit_translations/tests/test_cli_end_to_end.py @@ -143,6 +143,7 @@ def test_cli_main_rich_only_filters_issue_groups(capsys, monkeypatch) -> None: "shared-only", ), ], + ids=["exclude-root", "exclude-shared-rules"], ) def test_cli_main_exclude_uses_relative_paths( tmp_path, From 512919a3c65f183bd568e43d1db8825f8c1e6107 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Wed, 19 Aug 2026 17:54:43 -0700 Subject: [PATCH 061/157] fix minimized zip file so that flow style is used to reduce space --- AGENTS.md | 2 +- src/bin/package_rules.rs | 91 +++++++++++++++++++-- src/rules_archive.rs | 167 ++++++++++++++++++++++++++++++++------- 3 files changed, 226 insertions(+), 34 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 76ea6a889..c6ca9e756 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,7 +13,7 @@ but add common mistakes of AI agents here instead. - `ClearSpeak_Rules.yaml`, `SimpleSpeak_Rules.yaml` - `SharedRules/`, `unicode.yaml`, `unicode-full.yaml`, `definitions.yaml`, `navigate.yaml` - `build.rs` can bundle rules into `rules.zip` when `include-zip` is enabled (always the minimized tree). Shared zipper: `src/rules_archive.rs`, invoked as `cargo run --bin package-rules -- Rules [--minimize]`. -- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (comments stripped from `Languages/**/unicode.yaml` and `unicode-full.yaml` only). Each language/braille subdir is stored as `/.zip`; top-level and `Intent/` YAML stay loose. Inner language zips use BZIP2; the outer downloadable archive uses DEFLATE so `unzip` works. Both omit `Languages/zz`; the `test-rules-package` job restores `zz` from git after unzip so unit tests still run against release-like archives. +- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (flow-style rewrite of all YAML: comments dropped). Each language/braille subdir is stored as `/.zip`; top-level and `Intent/` YAML stay loose. Inner language zips use BZIP2; the outer downloadable archive uses DEFLATE so `unzip` works. Both omit `Languages/zz`; the `test-rules-package` job restores `zz` from git after unzip so unit tests still run against release-like archives. ## Translation Conventions - `t:` means untranslated or unverified. diff --git a/src/bin/package_rules.rs b/src/bin/package_rules.rs index 261059bea..900af235f 100644 --- a/src/bin/package_rules.rs +++ b/src/bin/package_rules.rs @@ -15,14 +15,14 @@ use std::process::ExitCode; #[command( name = "package-rules", about = "Package MathCAT Rules/ into a zip archive. \ - Use --minimize to strip comments from Languages unicode YAML." + Use --minimize to rewrite all Rules YAML in compact flow style." )] struct Options { /// Path to the Rules directory source: PathBuf, /// Output zip file path (e.g. Rules.zip) output: PathBuf, - /// Emit compact unicode.yaml / unicode-full.yaml without comments (speech languages only) + /// Rewrite all Rules YAML as compact flow YAML without comments #[arg(long)] minimize: bool, } @@ -119,6 +119,23 @@ mod tests { assert_eq!(docs.len(), 1); } + #[test] + fn minimize_yaml_uses_flow_style() { + let source = "---\n# comment\n - \"+\": [t: \"plus\"] # inline\n - \"-\": [t: \"minus\"]\n"; + let minimized = minimize_yaml_text(source).unwrap(); + assert!( + minimized.contains('[') && minimized.contains('{'), + "expected flow collections, got: {minimized}" + ); + assert!( + !minimized.lines().any(|line| line.trim_start().starts_with("- ")), + "expected no block-sequence dashes, got: {minimized}" + ); + let original = yaml_rust::YamlLoader::load_from_str(source).unwrap(); + let roundtrip = yaml_rust::YamlLoader::load_from_str(&minimized).unwrap(); + assert_eq!(original, roundtrip); + } + #[test] fn minimize_quotes_infinity() { let source = "---\n - \"∞\": [t: \"infinity\"]\n"; @@ -132,6 +149,22 @@ mod tests { assert_eq!(docs.len(), 1); } + #[test] + fn minimize_roundtrips_en_unicode_files() { + for name in ["unicode.yaml", "unicode-full.yaml"] { + let path = std::path::Path::new("Rules/Languages/en").join(name); + let source = fs::read_to_string(&path).expect(name); + let minimized = minimize_yaml_text(&source).unwrap(); + assert!( + !minimized.lines().any(|line| line.trim_start().starts_with("- ")), + "{name} still uses block sequences" + ); + let original = yaml_rust::YamlLoader::load_from_str(&source).unwrap(); + let roundtrip = yaml_rust::YamlLoader::load_from_str(&minimized).unwrap(); + assert_eq!(original, roundtrip, "{name} did not round-trip"); + } + } + #[test] fn package_rules_standard_zip_layout() { let tmp = tempdir().unwrap(); @@ -161,8 +194,43 @@ mod tests { assert_eq!(unicode.replace("\r\n", "\n"), "- \"+\": [t: \"plus\"]\n"); } + fn walk_yaml_files(dir: &std::path::Path, out: &mut Vec) { + for entry in fs::read_dir(dir).unwrap() { + let entry = entry.unwrap(); + let path = entry.path(); + if path.is_dir() { + walk_yaml_files(&path, out); + } else if is_yaml_file(&path) { + out.push(path); + } + } + } + #[test] - fn should_not_minimize_braille_unicode() { + fn minimize_roundtrips_all_rules_yaml() { + let mut paths = Vec::new(); + walk_yaml_files(std::path::Path::new("Rules"), &mut paths); + assert!(!paths.is_empty()); + for path in paths { + if path.components().any(|c| c.as_os_str() == SKIP_LANGUAGE_DIR) { + continue; + } + let source = fs::read_to_string(&path).unwrap_or_else(|e| panic!("{}: {e}", path.display())); + let minimized = minimize_yaml_text(&source) + .unwrap_or_else(|e| panic!("{}: {e}", path.display())); + assert!( + !minimized.lines().any(|line| line.trim_start().starts_with("- ")), + "{} still uses block sequences", + path.display() + ); + let original = yaml_rust::YamlLoader::load_from_str(&source).unwrap(); + let roundtrip = yaml_rust::YamlLoader::load_from_str(&minimized).unwrap(); + assert_eq!(original, roundtrip, "{} did not round-trip", path.display()); + } + } + + #[test] + fn minimize_braille_unicode() { let tmp = tempdir().unwrap(); let rules = tmp.path().join("Rules"); let braille = rules.join("Braille").join("Nemeth"); @@ -172,11 +240,16 @@ mod tests { let output = tmp.path().join("Rules-minimized.zip"); let minimized = package_rules(&rules, &output, true, downloadable_compression()).unwrap(); - assert_eq!(minimized, 0); + assert_eq!(minimized, 1); let bytes = fs::read(&output).unwrap(); let text = read_nested_zip_text(&bytes, "Rules/Braille/Nemeth/Nemeth.zip", "unicode.yaml"); - assert_eq!(text.replace("\r\n", "\n"), source.replace("\r\n", "\n")); + assert!(!text.contains('#')); + assert!(text.contains('[') && text.contains('{')); + assert!(!text.lines().any(|line| line.trim_start().starts_with("- "))); + let original = yaml_rust::YamlLoader::load_from_str(source).unwrap(); + let roundtrip = yaml_rust::YamlLoader::load_from_str(&text).unwrap(); + assert_eq!(original, roundtrip); } #[test] @@ -198,7 +271,7 @@ mod tests { let output = tmp.path().join("Rules-minimized.zip"); let minimized = package_rules(&rules, &output, true, downloadable_compression()).unwrap(); - assert_eq!(minimized, 1); + assert_eq!(minimized, 2); let bytes = fs::read(&output).unwrap(); let names = outer_names(&bytes); @@ -208,8 +281,14 @@ mod tests { let unicode = read_nested_zip_text(&bytes, "Rules/Languages/en/en.zip", "unicode.yaml"); let defs = read_nested_zip_text(&bytes, "Rules/Languages/en/en.zip", "definitions.yaml"); assert!(!unicode.contains('#')); + assert!(unicode.contains('[') && unicode.contains('{')); + assert!(!unicode.lines().any(|line| line.trim_start().starts_with("- "))); + assert!(!defs.contains('#')); + assert!(defs.contains('[') && defs.contains('{')); + assert!(!defs.lines().any(|line| line.trim_start().starts_with("- "))); assert!(defs.contains("real=inf")); assert_eq!(yaml_rust::YamlLoader::load_from_str(&unicode).unwrap().len(), 1); + assert_eq!(yaml_rust::YamlLoader::load_from_str(&defs).unwrap().len(), 1); } #[test] diff --git a/src/rules_archive.rs b/src/rules_archive.rs index 108220c28..70d8d81fe 100644 --- a/src/rules_archive.rs +++ b/src/rules_archive.rs @@ -13,12 +13,11 @@ use std::fs::{self, File, read_dir}; use std::io::{self, Cursor, Read, Seek, Write}; use std::path::{Path, PathBuf}; -use yaml_rust::{YamlEmitter, YamlLoader}; +use yaml_rust::{Yaml, YamlLoader}; use zip::write::{SimpleFileOptions, ZipWriter}; use zip::CompressionMethod; const YAML_SUFFIXES: [&str; 2] = ["yaml", "yml"]; -const MINIMIZE_NAMES: [&str; 2] = ["unicode.yaml", "unicode-full.yaml"]; const SKIP_LANGUAGE_DIR: &str = "zz"; const ARCHIVE_ROOT: &str = "Rules"; @@ -83,17 +82,7 @@ fn file_name_str(path: &Path) -> io::Result { .ok_or_else(|| io::Error::other(format!("non-UTF-8 file name: {}", path.display())))?; return Ok(name.to_string()); } - -/// Speech unicode YAML only — braille `unicode.yaml` stays verbatim. -fn should_minimize(path: &Path) -> bool { - let name = path.file_name().and_then(|n| n.to_str()).unwrap_or(""); - if !MINIMIZE_NAMES.contains(&name) { - return false; - } - return path.components().any(|c| c.as_os_str() == "Languages"); -} - -/// Load YAML, drop comments, re-emit. Returns `Err` if yaml-rust cannot parse the file. +/// Load YAML, drop comments, re-emit in flow style. Returns `Err` if yaml-rust cannot parse the file. pub fn minimize_yaml_text(text: &str) -> Result { let normalized = text.replace('\t', " "); let docs = YamlLoader::load_from_str(&normalized).map_err(|e| e.to_string())?; @@ -101,16 +90,13 @@ pub fn minimize_yaml_text(text: &str) -> Result { return Ok(String::new()); } let mut out = String::new(); - { - let mut emitter = YamlEmitter::new(&mut out); - emitter.compact(true); - for doc in &docs { - emitter.dump(doc).map_err(|e| e.to_string())?; + for (i, doc) in docs.iter().enumerate() { + if i > 0 { + out.push_str("\n---\n"); } + emit_flow(&mut out, doc)?; } - if !out.ends_with('\n') { - out.push('\n'); - } + out.push('\n'); // yaml-rust quotes scalars that parse as f64 (including "infinity"); keep a guard in case // a future emitter change stops doing that — unquoted `infinity` becomes a float on load. if looks_like_unquoted_infinity(&out) { @@ -119,15 +105,143 @@ pub fn minimize_yaml_text(text: &str) -> Result { return Ok(out); } +fn emit_flow(out: &mut String, yaml: &Yaml) -> Result<(), String> { + match yaml { + Yaml::Array(items) => { + out.push('['); + for (i, item) in items.iter().enumerate() { + if i > 0 { + out.push(','); + } + emit_flow(out, item)?; + } + out.push(']'); + } + Yaml::Hash(hash) => { + out.push('{'); + for (i, (key, value)) in hash.iter().enumerate() { + if i > 0 { + out.push(','); + } + emit_flow(out, key)?; + out.push_str(": "); + emit_flow(out, value)?; + } + out.push('}'); + } + Yaml::String(s) => emit_yaml_string(out, s), + Yaml::Boolean(true) => out.push_str("true"), + Yaml::Boolean(false) => out.push_str("false"), + Yaml::Integer(i) => out.push_str(&i.to_string()), + Yaml::Real(s) => out.push_str(s), + Yaml::Null | Yaml::BadValue => out.push('~'), + Yaml::Alias(_) => return Err("cannot minimize YAML that contains aliases".to_string()), + } + return Ok(()); +} + +fn emit_yaml_string(out: &mut String, s: &str) { + if need_quotes(s) { + escape_yaml_string(out, s); + } else { + out.push_str(s); + } +} + +/// Same quoting rules as yaml-rust 0.4's emitter, so load/emit round-trips. +fn need_quotes(string: &str) -> bool { + string.is_empty() + || string.starts_with(' ') + || string.ends_with(' ') + || string.starts_with(|character: char| { + matches!(character, '&' | '*' | '?' | '|' | '-' | '<' | '>' | '=' | '!' | '%' | '@') + }) + || string.contains(|character: char| { + matches!( + character, + ':' | '{' | '}' | '[' | ']' | ',' | '#' | '`' | '"' | '\'' | '\\' + | '\0'..='\x06' + | '\t' + | '\n' + | '\r' + | '\x0e'..='\x1a' + | '\x1c'..='\x1f' + ) + }) + || [ + "yes", "Yes", "YES", "no", "No", "NO", "True", "TRUE", "true", "False", "FALSE", + "false", "on", "On", "ON", "off", "Off", "OFF", "null", "Null", "NULL", "~", + ] + .contains(&string) + || string.starts_with('.') + || string.starts_with("0x") + || string.parse::().is_ok() + || string.parse::().is_ok() +} + +fn escape_yaml_string(out: &mut String, v: &str) { + out.push('"'); + let mut start = 0; + for (i, byte) in v.bytes().enumerate() { + let escaped = match byte { + b'"' => "\\\"", + b'\\' => "\\\\", + b'\x00' => "\\u0000", + b'\x01' => "\\u0001", + b'\x02' => "\\u0002", + b'\x03' => "\\u0003", + b'\x04' => "\\u0004", + b'\x05' => "\\u0005", + b'\x06' => "\\u0006", + b'\x07' => "\\u0007", + b'\x08' => "\\b", + b'\t' => "\\t", + b'\n' => "\\n", + b'\x0b' => "\\u000b", + b'\x0c' => "\\f", + b'\r' => "\\r", + b'\x0e' => "\\u000e", + b'\x0f' => "\\u000f", + b'\x10' => "\\u0010", + b'\x11' => "\\u0011", + b'\x12' => "\\u0012", + b'\x13' => "\\u0013", + b'\x14' => "\\u0014", + b'\x15' => "\\u0015", + b'\x16' => "\\u0016", + b'\x17' => "\\u0017", + b'\x18' => "\\u0018", + b'\x19' => "\\u0019", + b'\x1a' => "\\u001a", + b'\x1b' => "\\u001b", + b'\x1c' => "\\u001c", + b'\x1d' => "\\u001d", + b'\x1e' => "\\u001e", + b'\x1f' => "\\u001f", + b'\x7f' => "\\u007f", + _ => continue, + }; + if start < i { + out.push_str(&v[start..i]); + } + out.push_str(escaped); + start = i + 1; + } + if start != v.len() { + out.push_str(&v[start..]); + } + out.push('"'); +} + fn looks_like_unquoted_infinity(yaml: &str) -> bool { - // Match a YAML value `infinity` that is not inside quotes. + // Block-style leftovers and flow mappings (`: infinity}` / `: infinity,`). for line in yaml.lines() { let trimmed = line.trim(); if trimmed == "infinity" || trimmed.ends_with(": infinity") || trimmed.ends_with("- infinity") { return true; } } - return false; + return yaml.contains(": infinity,") || yaml.contains(": infinity}") || yaml.contains(": infinity]"); } fn minimize_yaml_file(src: &Path, dst: &Path) -> Result<(), String> { @@ -143,9 +257,8 @@ fn minimize_yaml_file(src: &Path, dst: &Path) -> Result<(), String> { return Ok(()); } -/// Copy a Rules tree. When `minify` is true, rewrite `Languages/**/unicode.yaml` and -/// `unicode-full.yaml` (comments stripped). `Languages/zz` is omitted. Returns the number of -/// files successfully minimized. +/// Copy a Rules tree. When `minify` is true, rewrite every YAML file as comment-free flow YAML. +/// `Languages/zz` is omitted. Returns the number of files successfully minimized. pub fn copy_rules_tree(src: &Path, dst: &Path, minify: bool) -> io::Result { fs::create_dir_all(dst)?; return copy_dir(src, dst, minify, false); @@ -167,7 +280,7 @@ fn copy_dir(src: &Path, dst: &Path, minify: bool, parent_is_languages: bool) -> if src_path.is_dir() { fs::create_dir_all(&dst_path)?; minimized += copy_dir(&src_path, &dst_path, minify, name == "Languages")?; - } else if minify && should_minimize(&src_path) { + } else if minify && is_yaml_file(&src_path) { match minimize_yaml_file(&src_path, &dst_path) { Ok(()) => minimized += 1, Err(e) => { From 88856c9f8c72c69174f762ce23b07afcff421c48 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Wed, 19 Aug 2026 23:21:21 -0700 Subject: [PATCH 062/157] fix test that depending on the details of YAML notation -- broke for compact flow notation --- src/prefs.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/prefs.rs b/src/prefs.rs index 2fe69cdf3..4dc51c4bc 100644 --- a/src/prefs.rs +++ b/src/prefs.rs @@ -1288,8 +1288,11 @@ cfg_if::cfg_if! {if #[cfg(not(feature = "include-zip"))] { let braille_before = interface::get_braille("").unwrap(); let unicode_file = temp_rules_dir.join("Braille/Nemeth/unicode.yaml"); let unicode_contents = fs::read_to_string(&unicode_file).unwrap(); - // remap the digit '1' to the (distinctive) full braille cell '⠿' - let changed_unicode = unicode_contents.replace("\"1\": [t: \"N⠂\"]", "\"1\": [t: \"N⠿\"]"); + // Remap digit '1' to the distinctive full braille cell '⠿'. + // Source Rules use block style (`"1": [t: "N⠂"]`); Rules-minimized.zip uses flow (`{"1": [{t: N⠂}]}`). + let changed_unicode = unicode_contents + .replace("\"1\": [t: \"N⠂\"]", "\"1\": [t: \"N⠿\"]") + .replace("{\"1\": [{t: N⠂}]}", "{\"1\": [{t: N⠿}]}"); assert_ne!(changed_unicode, unicode_contents, "expected to find the Nemeth mapping for '1'"); fs::write(&unicode_file, changed_unicode).unwrap(); sleep(Duration::from_millis(5)); From 728bbb71d154ae6b7de43954db5e5dd0f0f9b577 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 20 Aug 2026 00:31:15 -0700 Subject: [PATCH 063/157] fix row terminator for UEB in mtable --- Rules/Braille/UEB/UEB_Rules.yaml | 3 +-- tests/braille/UEB/iceb.rs | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/Rules/Braille/UEB/UEB_Rules.yaml b/Rules/Braille/UEB/UEB_Rules.yaml index 8e3491c80..04c63947d 100644 --- a/Rules/Braille/UEB/UEB_Rules.yaml +++ b/Rules/Braille/UEB/UEB_Rules.yaml @@ -159,8 +159,7 @@ replace: - test: if: "../*[2]" # more than one row - then: [t: "⠠"] - - t: "" + then: [t: "⠸W"] - x: $RowStart - test: if: .[self::m:mlabeledtr] diff --git a/tests/braille/UEB/iceb.rs b/tests/braille/UEB/iceb.rs index 731e136b1..2c7c9a5c7 100644 --- a/tests/braille/UEB/iceb.rs +++ b/tests/braille/UEB/iceb.rs @@ -1465,6 +1465,49 @@ fn binomial_14_3_3_2_mtable() -> Result<()> { } +#[test] +fn matrix_15_2_1() -> Result<()> { + // GTM 15.2 first example: I = [[1,0],[0,1]] with enlarged parentheses (one-line encoding). + let expr = r#"( + 10 + 01 + )"#; + test_braille("UEB", expr, "⠸⠀⠐⠣⠼⠁⠀⠼⠚⠠⠐⠜⠸⠀⠐⠣⠼⠚⠀⠼⠁⠠⠐⠜")?; + return Ok(()); +} + +#[test] +fn matrix_15_2_2() -> Result<()> { + // GTM 15.2: matrix with enlarged square brackets. + let expr = r#"[ + ab + cd + ]"#; + test_braille("UEB", expr, "⠸⠀⠨⠣⠁⠀⠃⠠⠨⠜⠸⠀⠨⠣⠰⠉⠀⠙⠠⠨⠜")?; + return Ok(()); +} + +#[test] +fn matrix_15_2_3() -> Result<()> { + // Single-row: no enlarged (dot-6) markers (UEB_Rules one-row path). + let expr = r#"( + 123 + )"#; + test_braille("UEB", expr, "⠐⠣⠼⠁⠀⠼⠃⠀⠼⠉⠐⠜")?; + return Ok(()); +} + +#[test] +fn determinant_15_3_1() -> Result<()> { + // GTM 15.3: determinant with enlarged vertical bars. + let expr = r#"| + 12 + 34 + |"#; + test_braille("UEB", expr, "⠸⠀⠸⠳⠼⠁⠀⠼⠃⠠⠸⠳⠸⠀⠸⠳⠼⠉⠀⠼⠙⠠⠸⠳")?; + return Ok(()); +} + #[test] fn chem_16_2_8() -> Result<()> { let expr = "Ca(OH)2"; From 4a7f5ca0e926d06606043ddd24301b9b74a91d86 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 20 Aug 2026 00:31:15 -0700 Subject: [PATCH 064/157] fix row terminator for UEB in mtable --- Rules/Braille/UEB/UEB_Rules.yaml | 3 +-- tests/braille/UEB/iceb.rs | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/Rules/Braille/UEB/UEB_Rules.yaml b/Rules/Braille/UEB/UEB_Rules.yaml index 8e3491c80..04c63947d 100644 --- a/Rules/Braille/UEB/UEB_Rules.yaml +++ b/Rules/Braille/UEB/UEB_Rules.yaml @@ -159,8 +159,7 @@ replace: - test: if: "../*[2]" # more than one row - then: [t: "⠠"] - - t: "" + then: [t: "⠸W"] - x: $RowStart - test: if: .[self::m:mlabeledtr] diff --git a/tests/braille/UEB/iceb.rs b/tests/braille/UEB/iceb.rs index 731e136b1..2c7c9a5c7 100644 --- a/tests/braille/UEB/iceb.rs +++ b/tests/braille/UEB/iceb.rs @@ -1465,6 +1465,49 @@ fn binomial_14_3_3_2_mtable() -> Result<()> { } +#[test] +fn matrix_15_2_1() -> Result<()> { + // GTM 15.2 first example: I = [[1,0],[0,1]] with enlarged parentheses (one-line encoding). + let expr = r#"( + 10 + 01 + )"#; + test_braille("UEB", expr, "⠸⠀⠐⠣⠼⠁⠀⠼⠚⠠⠐⠜⠸⠀⠐⠣⠼⠚⠀⠼⠁⠠⠐⠜")?; + return Ok(()); +} + +#[test] +fn matrix_15_2_2() -> Result<()> { + // GTM 15.2: matrix with enlarged square brackets. + let expr = r#"[ + ab + cd + ]"#; + test_braille("UEB", expr, "⠸⠀⠨⠣⠁⠀⠃⠠⠨⠜⠸⠀⠨⠣⠰⠉⠀⠙⠠⠨⠜")?; + return Ok(()); +} + +#[test] +fn matrix_15_2_3() -> Result<()> { + // Single-row: no enlarged (dot-6) markers (UEB_Rules one-row path). + let expr = r#"( + 123 + )"#; + test_braille("UEB", expr, "⠐⠣⠼⠁⠀⠼⠃⠀⠼⠉⠐⠜")?; + return Ok(()); +} + +#[test] +fn determinant_15_3_1() -> Result<()> { + // GTM 15.3: determinant with enlarged vertical bars. + let expr = r#"| + 12 + 34 + |"#; + test_braille("UEB", expr, "⠸⠀⠸⠳⠼⠁⠀⠼⠃⠠⠸⠳⠸⠀⠸⠳⠼⠉⠀⠼⠙⠠⠸⠳")?; + return Ok(()); +} + #[test] fn chem_16_2_8() -> Result<()> { let expr = "Ca(OH)2"; From 18859bca60d88bbac58dfe02de912e733e21aafe Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 20 Aug 2026 00:40:44 -0700 Subject: [PATCH 065/157] Bring over fixes to the minified yaml files. --- src/bin/package_rules.rs | 91 +++++++++++++++++++-- src/main.rs | 45 ++--------- src/prefs.rs | 7 +- src/rules_archive.rs | 167 ++++++++++++++++++++++++++++++++------- 4 files changed, 237 insertions(+), 73 deletions(-) diff --git a/src/bin/package_rules.rs b/src/bin/package_rules.rs index 261059bea..900af235f 100644 --- a/src/bin/package_rules.rs +++ b/src/bin/package_rules.rs @@ -15,14 +15,14 @@ use std::process::ExitCode; #[command( name = "package-rules", about = "Package MathCAT Rules/ into a zip archive. \ - Use --minimize to strip comments from Languages unicode YAML." + Use --minimize to rewrite all Rules YAML in compact flow style." )] struct Options { /// Path to the Rules directory source: PathBuf, /// Output zip file path (e.g. Rules.zip) output: PathBuf, - /// Emit compact unicode.yaml / unicode-full.yaml without comments (speech languages only) + /// Rewrite all Rules YAML as compact flow YAML without comments #[arg(long)] minimize: bool, } @@ -119,6 +119,23 @@ mod tests { assert_eq!(docs.len(), 1); } + #[test] + fn minimize_yaml_uses_flow_style() { + let source = "---\n# comment\n - \"+\": [t: \"plus\"] # inline\n - \"-\": [t: \"minus\"]\n"; + let minimized = minimize_yaml_text(source).unwrap(); + assert!( + minimized.contains('[') && minimized.contains('{'), + "expected flow collections, got: {minimized}" + ); + assert!( + !minimized.lines().any(|line| line.trim_start().starts_with("- ")), + "expected no block-sequence dashes, got: {minimized}" + ); + let original = yaml_rust::YamlLoader::load_from_str(source).unwrap(); + let roundtrip = yaml_rust::YamlLoader::load_from_str(&minimized).unwrap(); + assert_eq!(original, roundtrip); + } + #[test] fn minimize_quotes_infinity() { let source = "---\n - \"∞\": [t: \"infinity\"]\n"; @@ -132,6 +149,22 @@ mod tests { assert_eq!(docs.len(), 1); } + #[test] + fn minimize_roundtrips_en_unicode_files() { + for name in ["unicode.yaml", "unicode-full.yaml"] { + let path = std::path::Path::new("Rules/Languages/en").join(name); + let source = fs::read_to_string(&path).expect(name); + let minimized = minimize_yaml_text(&source).unwrap(); + assert!( + !minimized.lines().any(|line| line.trim_start().starts_with("- ")), + "{name} still uses block sequences" + ); + let original = yaml_rust::YamlLoader::load_from_str(&source).unwrap(); + let roundtrip = yaml_rust::YamlLoader::load_from_str(&minimized).unwrap(); + assert_eq!(original, roundtrip, "{name} did not round-trip"); + } + } + #[test] fn package_rules_standard_zip_layout() { let tmp = tempdir().unwrap(); @@ -161,8 +194,43 @@ mod tests { assert_eq!(unicode.replace("\r\n", "\n"), "- \"+\": [t: \"plus\"]\n"); } + fn walk_yaml_files(dir: &std::path::Path, out: &mut Vec) { + for entry in fs::read_dir(dir).unwrap() { + let entry = entry.unwrap(); + let path = entry.path(); + if path.is_dir() { + walk_yaml_files(&path, out); + } else if is_yaml_file(&path) { + out.push(path); + } + } + } + #[test] - fn should_not_minimize_braille_unicode() { + fn minimize_roundtrips_all_rules_yaml() { + let mut paths = Vec::new(); + walk_yaml_files(std::path::Path::new("Rules"), &mut paths); + assert!(!paths.is_empty()); + for path in paths { + if path.components().any(|c| c.as_os_str() == SKIP_LANGUAGE_DIR) { + continue; + } + let source = fs::read_to_string(&path).unwrap_or_else(|e| panic!("{}: {e}", path.display())); + let minimized = minimize_yaml_text(&source) + .unwrap_or_else(|e| panic!("{}: {e}", path.display())); + assert!( + !minimized.lines().any(|line| line.trim_start().starts_with("- ")), + "{} still uses block sequences", + path.display() + ); + let original = yaml_rust::YamlLoader::load_from_str(&source).unwrap(); + let roundtrip = yaml_rust::YamlLoader::load_from_str(&minimized).unwrap(); + assert_eq!(original, roundtrip, "{} did not round-trip", path.display()); + } + } + + #[test] + fn minimize_braille_unicode() { let tmp = tempdir().unwrap(); let rules = tmp.path().join("Rules"); let braille = rules.join("Braille").join("Nemeth"); @@ -172,11 +240,16 @@ mod tests { let output = tmp.path().join("Rules-minimized.zip"); let minimized = package_rules(&rules, &output, true, downloadable_compression()).unwrap(); - assert_eq!(minimized, 0); + assert_eq!(minimized, 1); let bytes = fs::read(&output).unwrap(); let text = read_nested_zip_text(&bytes, "Rules/Braille/Nemeth/Nemeth.zip", "unicode.yaml"); - assert_eq!(text.replace("\r\n", "\n"), source.replace("\r\n", "\n")); + assert!(!text.contains('#')); + assert!(text.contains('[') && text.contains('{')); + assert!(!text.lines().any(|line| line.trim_start().starts_with("- "))); + let original = yaml_rust::YamlLoader::load_from_str(source).unwrap(); + let roundtrip = yaml_rust::YamlLoader::load_from_str(&text).unwrap(); + assert_eq!(original, roundtrip); } #[test] @@ -198,7 +271,7 @@ mod tests { let output = tmp.path().join("Rules-minimized.zip"); let minimized = package_rules(&rules, &output, true, downloadable_compression()).unwrap(); - assert_eq!(minimized, 1); + assert_eq!(minimized, 2); let bytes = fs::read(&output).unwrap(); let names = outer_names(&bytes); @@ -208,8 +281,14 @@ mod tests { let unicode = read_nested_zip_text(&bytes, "Rules/Languages/en/en.zip", "unicode.yaml"); let defs = read_nested_zip_text(&bytes, "Rules/Languages/en/en.zip", "definitions.yaml"); assert!(!unicode.contains('#')); + assert!(unicode.contains('[') && unicode.contains('{')); + assert!(!unicode.lines().any(|line| line.trim_start().starts_with("- "))); + assert!(!defs.contains('#')); + assert!(defs.contains('[') && defs.contains('{')); + assert!(!defs.lines().any(|line| line.trim_start().starts_with("- "))); assert!(defs.contains("real=inf")); assert_eq!(yaml_rust::YamlLoader::load_from_str(&unicode).unwrap().len(), 1); + assert_eq!(yaml_rust::YamlLoader::load_from_str(&defs).unwrap().len(), 1); } #[test] diff --git a/src/main.rs b/src/main.rs index 506bd15d7..4a5a8c6fb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,39 +36,8 @@ fn main() { .init(); let expr = r#" - - - - e - - − - - 1 - 2 - - - - - ( - - - - x - − - μ - - σ - - - ) - - - 2 - - - - - + RT⌢ + "#; // let expr = " // @@ -308,7 +277,7 @@ fn main() { // info!("#xpath = {}; duplicates = {}", xpath_counts.0, xpath_counts.1); // info!("Time taken (second time for speech + braille): {}ms", instant.elapsed().as_millis()); // debug!("Hashmap sizes:\n{}", libmathcat::speech::SpeechRules::print_sizes()); - timing_test(expr, 5000); + timing_test(expr, 100); } @@ -327,10 +296,10 @@ fn timing_test(expr: &str, n_loops: usize) { Ok(_) =>( ), Err(e) => {eprintln!("{}", errors_to_string(&e)); exit(1);}, } - match get_braille("") { - Ok(_) => (), - Err(e) => {eprintln!("{}", errors_to_string(&e)); exit(1);}, - } + // match get_braille("") { + // Ok(_) => (), + // Err(e) => {eprintln!("{}", errors_to_string(&e)); exit(1);}, + // } } info!("Time taken (time for set, speech, {} braille averaged over {} loops): {}ms", get_preference("BrailleCode").unwrap(), n_loops, instant.elapsed().as_millis() as f64/n_loops_float); diff --git a/src/prefs.rs b/src/prefs.rs index 2fe69cdf3..4dc51c4bc 100644 --- a/src/prefs.rs +++ b/src/prefs.rs @@ -1288,8 +1288,11 @@ cfg_if::cfg_if! {if #[cfg(not(feature = "include-zip"))] { let braille_before = interface::get_braille("").unwrap(); let unicode_file = temp_rules_dir.join("Braille/Nemeth/unicode.yaml"); let unicode_contents = fs::read_to_string(&unicode_file).unwrap(); - // remap the digit '1' to the (distinctive) full braille cell '⠿' - let changed_unicode = unicode_contents.replace("\"1\": [t: \"N⠂\"]", "\"1\": [t: \"N⠿\"]"); + // Remap digit '1' to the distinctive full braille cell '⠿'. + // Source Rules use block style (`"1": [t: "N⠂"]`); Rules-minimized.zip uses flow (`{"1": [{t: N⠂}]}`). + let changed_unicode = unicode_contents + .replace("\"1\": [t: \"N⠂\"]", "\"1\": [t: \"N⠿\"]") + .replace("{\"1\": [{t: N⠂}]}", "{\"1\": [{t: N⠿}]}"); assert_ne!(changed_unicode, unicode_contents, "expected to find the Nemeth mapping for '1'"); fs::write(&unicode_file, changed_unicode).unwrap(); sleep(Duration::from_millis(5)); diff --git a/src/rules_archive.rs b/src/rules_archive.rs index 108220c28..70d8d81fe 100644 --- a/src/rules_archive.rs +++ b/src/rules_archive.rs @@ -13,12 +13,11 @@ use std::fs::{self, File, read_dir}; use std::io::{self, Cursor, Read, Seek, Write}; use std::path::{Path, PathBuf}; -use yaml_rust::{YamlEmitter, YamlLoader}; +use yaml_rust::{Yaml, YamlLoader}; use zip::write::{SimpleFileOptions, ZipWriter}; use zip::CompressionMethod; const YAML_SUFFIXES: [&str; 2] = ["yaml", "yml"]; -const MINIMIZE_NAMES: [&str; 2] = ["unicode.yaml", "unicode-full.yaml"]; const SKIP_LANGUAGE_DIR: &str = "zz"; const ARCHIVE_ROOT: &str = "Rules"; @@ -83,17 +82,7 @@ fn file_name_str(path: &Path) -> io::Result { .ok_or_else(|| io::Error::other(format!("non-UTF-8 file name: {}", path.display())))?; return Ok(name.to_string()); } - -/// Speech unicode YAML only — braille `unicode.yaml` stays verbatim. -fn should_minimize(path: &Path) -> bool { - let name = path.file_name().and_then(|n| n.to_str()).unwrap_or(""); - if !MINIMIZE_NAMES.contains(&name) { - return false; - } - return path.components().any(|c| c.as_os_str() == "Languages"); -} - -/// Load YAML, drop comments, re-emit. Returns `Err` if yaml-rust cannot parse the file. +/// Load YAML, drop comments, re-emit in flow style. Returns `Err` if yaml-rust cannot parse the file. pub fn minimize_yaml_text(text: &str) -> Result { let normalized = text.replace('\t', " "); let docs = YamlLoader::load_from_str(&normalized).map_err(|e| e.to_string())?; @@ -101,16 +90,13 @@ pub fn minimize_yaml_text(text: &str) -> Result { return Ok(String::new()); } let mut out = String::new(); - { - let mut emitter = YamlEmitter::new(&mut out); - emitter.compact(true); - for doc in &docs { - emitter.dump(doc).map_err(|e| e.to_string())?; + for (i, doc) in docs.iter().enumerate() { + if i > 0 { + out.push_str("\n---\n"); } + emit_flow(&mut out, doc)?; } - if !out.ends_with('\n') { - out.push('\n'); - } + out.push('\n'); // yaml-rust quotes scalars that parse as f64 (including "infinity"); keep a guard in case // a future emitter change stops doing that — unquoted `infinity` becomes a float on load. if looks_like_unquoted_infinity(&out) { @@ -119,15 +105,143 @@ pub fn minimize_yaml_text(text: &str) -> Result { return Ok(out); } +fn emit_flow(out: &mut String, yaml: &Yaml) -> Result<(), String> { + match yaml { + Yaml::Array(items) => { + out.push('['); + for (i, item) in items.iter().enumerate() { + if i > 0 { + out.push(','); + } + emit_flow(out, item)?; + } + out.push(']'); + } + Yaml::Hash(hash) => { + out.push('{'); + for (i, (key, value)) in hash.iter().enumerate() { + if i > 0 { + out.push(','); + } + emit_flow(out, key)?; + out.push_str(": "); + emit_flow(out, value)?; + } + out.push('}'); + } + Yaml::String(s) => emit_yaml_string(out, s), + Yaml::Boolean(true) => out.push_str("true"), + Yaml::Boolean(false) => out.push_str("false"), + Yaml::Integer(i) => out.push_str(&i.to_string()), + Yaml::Real(s) => out.push_str(s), + Yaml::Null | Yaml::BadValue => out.push('~'), + Yaml::Alias(_) => return Err("cannot minimize YAML that contains aliases".to_string()), + } + return Ok(()); +} + +fn emit_yaml_string(out: &mut String, s: &str) { + if need_quotes(s) { + escape_yaml_string(out, s); + } else { + out.push_str(s); + } +} + +/// Same quoting rules as yaml-rust 0.4's emitter, so load/emit round-trips. +fn need_quotes(string: &str) -> bool { + string.is_empty() + || string.starts_with(' ') + || string.ends_with(' ') + || string.starts_with(|character: char| { + matches!(character, '&' | '*' | '?' | '|' | '-' | '<' | '>' | '=' | '!' | '%' | '@') + }) + || string.contains(|character: char| { + matches!( + character, + ':' | '{' | '}' | '[' | ']' | ',' | '#' | '`' | '"' | '\'' | '\\' + | '\0'..='\x06' + | '\t' + | '\n' + | '\r' + | '\x0e'..='\x1a' + | '\x1c'..='\x1f' + ) + }) + || [ + "yes", "Yes", "YES", "no", "No", "NO", "True", "TRUE", "true", "False", "FALSE", + "false", "on", "On", "ON", "off", "Off", "OFF", "null", "Null", "NULL", "~", + ] + .contains(&string) + || string.starts_with('.') + || string.starts_with("0x") + || string.parse::().is_ok() + || string.parse::().is_ok() +} + +fn escape_yaml_string(out: &mut String, v: &str) { + out.push('"'); + let mut start = 0; + for (i, byte) in v.bytes().enumerate() { + let escaped = match byte { + b'"' => "\\\"", + b'\\' => "\\\\", + b'\x00' => "\\u0000", + b'\x01' => "\\u0001", + b'\x02' => "\\u0002", + b'\x03' => "\\u0003", + b'\x04' => "\\u0004", + b'\x05' => "\\u0005", + b'\x06' => "\\u0006", + b'\x07' => "\\u0007", + b'\x08' => "\\b", + b'\t' => "\\t", + b'\n' => "\\n", + b'\x0b' => "\\u000b", + b'\x0c' => "\\f", + b'\r' => "\\r", + b'\x0e' => "\\u000e", + b'\x0f' => "\\u000f", + b'\x10' => "\\u0010", + b'\x11' => "\\u0011", + b'\x12' => "\\u0012", + b'\x13' => "\\u0013", + b'\x14' => "\\u0014", + b'\x15' => "\\u0015", + b'\x16' => "\\u0016", + b'\x17' => "\\u0017", + b'\x18' => "\\u0018", + b'\x19' => "\\u0019", + b'\x1a' => "\\u001a", + b'\x1b' => "\\u001b", + b'\x1c' => "\\u001c", + b'\x1d' => "\\u001d", + b'\x1e' => "\\u001e", + b'\x1f' => "\\u001f", + b'\x7f' => "\\u007f", + _ => continue, + }; + if start < i { + out.push_str(&v[start..i]); + } + out.push_str(escaped); + start = i + 1; + } + if start != v.len() { + out.push_str(&v[start..]); + } + out.push('"'); +} + fn looks_like_unquoted_infinity(yaml: &str) -> bool { - // Match a YAML value `infinity` that is not inside quotes. + // Block-style leftovers and flow mappings (`: infinity}` / `: infinity,`). for line in yaml.lines() { let trimmed = line.trim(); if trimmed == "infinity" || trimmed.ends_with(": infinity") || trimmed.ends_with("- infinity") { return true; } } - return false; + return yaml.contains(": infinity,") || yaml.contains(": infinity}") || yaml.contains(": infinity]"); } fn minimize_yaml_file(src: &Path, dst: &Path) -> Result<(), String> { @@ -143,9 +257,8 @@ fn minimize_yaml_file(src: &Path, dst: &Path) -> Result<(), String> { return Ok(()); } -/// Copy a Rules tree. When `minify` is true, rewrite `Languages/**/unicode.yaml` and -/// `unicode-full.yaml` (comments stripped). `Languages/zz` is omitted. Returns the number of -/// files successfully minimized. +/// Copy a Rules tree. When `minify` is true, rewrite every YAML file as comment-free flow YAML. +/// `Languages/zz` is omitted. Returns the number of files successfully minimized. pub fn copy_rules_tree(src: &Path, dst: &Path, minify: bool) -> io::Result { fs::create_dir_all(dst)?; return copy_dir(src, dst, minify, false); @@ -167,7 +280,7 @@ fn copy_dir(src: &Path, dst: &Path, minify: bool, parent_is_languages: bool) -> if src_path.is_dir() { fs::create_dir_all(&dst_path)?; minimized += copy_dir(&src_path, &dst_path, minify, name == "Languages")?; - } else if minify && should_minimize(&src_path) { + } else if minify && is_yaml_file(&src_path) { match minimize_yaml_file(&src_path, &dst_path) { Ok(()) => minimized += 1, Err(e) => { From 4b9d19ce367e8d4af45b24fe0840f00f64b5133f Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 20 Aug 2026 00:41:25 -0700 Subject: [PATCH 066/157] bump release number --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 32e83cf27..768d8bd50 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mathcat" -version = "0.7.6-rc.1" +version = "0.7.6-rc.2" authors = ["Neil Soiffer "] license = "MIT" description = "MathCAT: Math Capable Assistive Technology ('Speech and braille from MathML')" From eaa36e9ed03bfb147e66eb275186b718af464abd Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Thu, 20 Aug 2026 00:44:35 -0700 Subject: [PATCH 067/157] Fix #698 -- merge arc-like symbols under restricted condidtions --- src/canonicalize.rs | 128 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 2 deletions(-) diff --git a/src/canonicalize.rs b/src/canonicalize.rs index 380c4de0c..8b91aff8e 100644 --- a/src/canonicalize.rs +++ b/src/canonicalize.rs @@ -776,7 +776,53 @@ impl CanonicalizeContext { fn contains_currency(s: &str) -> bool { s.chars().any(is_currency_symbol) - } + } + + /// Geometry arc names like AB / ABC: a leaf whose text is 2–3 ASCII capitals. + fn is_two_or_three_ascii_capitals(base: Element) -> bool { + if !is_leaf(base) { + return false; + } + let text = as_str!(as_text(base)); + let n = text.chars().count(); + return (n == 2 || n == 3) && text.chars().all(|c| c.is_ascii_uppercase()); + } + + /// `mrow` of 2 or 3 capital ``s, optionally separated by U+2062 / U+2063 ``s. + fn is_mrow_of_two_or_three_cap_identifiers(base: Element) -> bool { + if name(base) != "mrow" { + return false; + } + let children = base.children(); + if children.is_empty() { + return false; + } + let mut n_mi = 0; + let mut prev_was_mo = false; + for (i, child) in children.iter().enumerate() { + let child = as_element(*child); + if name(child) == "mi" { + let text = as_str!(as_text(child)); + if !(text.chars().count() == 1 && text.chars().next().unwrap().is_ascii_uppercase()) { + return false; + } + n_mi += 1; + prev_was_mo = false; + } else if name(child) == "mo" { + if i == 0 || prev_was_mo { + return false; + } + let text = as_str!(as_text(child)); + if text != "\u{2062}" && text != "\u{2063}" { + return false; + } + prev_was_mo = true; + } else { + return false; + } + } + return !prev_was_mo && (n_mi == 2 || n_mi == 3); + } // begin by cleaning up empty elements // debug!("clean_mathml\n{}", mml_to_string(mathml)); @@ -985,10 +1031,22 @@ impl CanonicalizeContext { } }, "..." => { - if name(get_parent(mathml)) != "mover" { + if parent_name != "mover" { mathml.set_text("…"); } // name might need to change -- checked below }, + "⌢" | "⏜" => { // lookalikes: U+2322 (“Frown”), U+23DC (“Top Parenthesis”) + // arc should be over constructs like AB or ABC + if parent_name == "mover" { + let parent = get_parent(mathml); + let base = as_element(parent.children()[0]); // already made sure correct number of children + if base != mathml && + (is_two_or_three_ascii_capitals(base) || is_mrow_of_two_or_three_cap_identifiers(base)) { + mathml.set_text("⌒"); // U+2312 + } + } + return Some(mathml); + }, ":" => { if is_ratio(mathml) { mathml.set_text("∶"); // ratio U+2236 @@ -6022,6 +6080,72 @@ mod canonicalize_tests { are_strs_canonically_equal_result(test_str, target_str, &[]) } + #[test] + fn clean_up_arc_lookalike_mrow() -> Result<()> { + // Frown over two capital identifiers is rewritten to the arc operator (U+2312) + let test_str = "ABC⌢"; + let target_str = " + + + A + ⁣ + B + ⁣ + C + + ⌒ + + "; + are_strs_canonically_equal_result(test_str, target_str, &[]) + } + + #[test] + fn clean_up_arc_lookalike_mrow_invisible_sep() -> Result<()> { + // Same rewrite when the capital identifiers are already separated by U+2063 + let test_str = "B⁣C⌢"; + let target_str = " + + + B + ⁣ + C + + ⌒ + + "; + are_strs_canonically_equal_result(test_str, target_str, &[]) + } + + #[test] + fn clean_up_arc_lookalike_mtext() -> Result<()> { + // Frown over a 2-letter capital mtext is rewritten to the arc operator (U+2312) + let test_str = "BC⌢"; + let target_str = " + + + B + ⁣ + C + + ⌒ + + "; + are_strs_canonically_equal_result(test_str, target_str, &[]) + } + + #[test] + fn clean_up_arc_lookalike_not_letters() -> Result<()> { + // Frown over a single lowercase identifier is left as a frown, not an arc + let test_str = "z⌢"; + let target_str = " + + z + ⌢ + + "; + are_strs_canonically_equal_result(test_str, target_str, &[]) + } + #[test] fn roman_numeral() -> Result<()> { let test_str = "XLVIII +mmxxvi"; From cf0b751b40a03c3d64d851f5b933bcfa21688087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Arborealis=20L=C3=B6tberg?= <143188129+TimArborealis@users.noreply.github.com> Date: Thu, 20 Aug 2026 16:19:15 +0200 Subject: [PATCH 068/157] Update user guide Updated English user guide with info on how to use MathCAT as an addon in NVDA. --- docs/users.md | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/docs/users.md b/docs/users.md index a5ab487d3..6328e522f 100644 --- a/docs/users.md +++ b/docs/users.md @@ -10,6 +10,8 @@ MathCAT is a tool used together with a screen reader. Through MathCAT, you can h In screen readers NVDA and JAWS, MathCAT comes built-in. This means you don’t have to install it as an addon. +MathCAT is still available as an addon to NVDA. You can use it if you want access to the very latest features between NVDA releases. [How to use MathCAT as an addon is described here](#how-to-install-mathcat-as-an-addon-in-nvda). + ## Get started with MathCAT Use your screen reader on a web page or in an e-book as usual. When you get to a mathematical expression, the screen reader will read it out automatically. If you want to investigate the expression more closely you can activate the navigation mode by pressing Space. In NVDA, the NVDA-key+Alt+M can also be used. If you want to leave the navigation mode, press Escape. @@ -137,4 +139,42 @@ Note: tabular math means mathematical content in a table structure such as a mat ## Do you have feedback on MathCAT? -MathCAT is under active development, and we want your feedback. Do you have a feature request, or have you found any bugs? Please create an issue on [MathCAT's GitHub page](https://github.com/daisy/MathCAT/issues). You are also welcome to get in touch by signing up to [the mailing list of the DAISY MathCAT working group](https://www.surveymonkey.com/r/HXTLXGN). \ No newline at end of file +MathCAT is under active development, and we want your feedback. Do you have a feature request, or have you found any bugs? Please create an issue on [MathCAT's GitHub page](https://github.com/daisy/MathCAT/issues). You are also welcome to get in touch by signing up to [the mailing list of the DAISY MathCAT working group](https://www.surveymonkey.com/r/HXTLXGN). + +## How to install MathCAT as an addon in NVDA + +To use MathCAT as an add-on, do the following: + +1. Open the NVDA menu. +2. Choose Tools and then Add-on store. +3. In the add-on store, choose Available add-ons. + + The channel settings have the following options: + - Stable: Will only search for stable add-ons + - All: Will search for all add-ons + - Beta: Will search for add-ons that are in beta + - Dev: Will search for add-ons in development + + Choose option "All". + +4. Search for MathCAT and install. + +5. In the settings menu, you can control how add-ons are updated: + + - Open the NVDA menu + - Choose settings and Add-on Store + + For Automatic updates, you can choose between: + - Notify + - Update Automatically + - Deactivated + + For Default update channel, you have the following options: + + - Same: If automatic updates is set to “Update Automatically” and your add-on is a beta, it will update to the first available beta. + - Any: It will update to any version of the add-on. + - Do not update + - Stable: It will only update to stable versions. + - Beta or dev: It will update to beta or dev versions. + - Beta: It will update to beta versions. + - Dev: It will update to dev versions. \ No newline at end of file From c7c25faf8160add1d189dac4f2080a5d476006d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Arborealis=20L=C3=B6tberg?= <143188129+TimArborealis@users.noreply.github.com> Date: Fri, 21 Aug 2026 10:20:53 +0200 Subject: [PATCH 069/157] Updated acknowledgements Updated acknowledgements with French, Hungarian and Polish translators. --- docs/index.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/index.md b/docs/index.md index f0e944723..36b4ca41d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -171,13 +171,16 @@ Several people helped out in various ways with the project. I am very grateful f Translators: * Chinese (Traditional) -- Hon-Jang Yang -* Finnish -- Sami Määttä, Accessibility Library Celia, and Essi Viippola, freelancer +* Finnish -- Sami Määttä (Accessibility Library Celia), and Essi Viippola (freelancer) +* French -- Olivier Thiffault (Technologies Humanware) * German -- Nazli Andjic, Robert Graf and Paul Libbrecht (IU International University of Applied Sciences) +* Hungarian -- Attila Hammer (IT Foundation for the Visually Impaired) * Indonesian -- Dr. Pinta Deniyanti Sampoerno, M.Si; Dr. Meiliasari, S.Pd., M.Sc; and Ari Hendarno, S.Pd., M.Kom. -* Norwegian -- Marthe Gjelstad, National Library of Norway, Kvile +* Norwegian -- Marthe Gjelstad (National Library of Norway), Kvile +* Polish -- Michał Dziwisz (Fundacja Instytut Rozwoju Regionalnego) * Russian (both speech and braille) -- Danil Kostenkov * Spanish -- Noelia Ruiz Martínez (also helped with NVDA add-on development) and María Allo Roldán -* Swedish -- Tim Arborealis Lötberg, Swedish Agency for Accessible Media (MTM) and Anders Eklund, SPSM +* Swedish -- Tim Arborealis Lötberg (MTM), and Anders Eklund (SPSM) * Vietnamese -- Dang Hoai Phúc and Trang Pham * Others??? -- please volunteer so I can list you here... From 76b3e59ed385a667723f8e070e8e966845ba00cf Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Fri, 21 Aug 2026 18:15:57 -0700 Subject: [PATCH 070/157] fix #703 --- Rules/Braille/Nemeth/unicode-full.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rules/Braille/Nemeth/unicode-full.yaml b/Rules/Braille/Nemeth/unicode-full.yaml index 935933a2a..30ffc561d 100644 --- a/Rules/Braille/Nemeth/unicode-full.yaml +++ b/Rules/Braille/Nemeth/unicode-full.yaml @@ -801,7 +801,7 @@ - "⋁": [t: "⠈⠬"] # 0x22c1 - "⋂": [t: "⠨⠩"] # 0x22c2 - "⋃": [t: "⠨⠬"] # 0x22c3 - - "⋄": [t: "⠫⠩"] # 0x22c4 + - "⋄": [t: "⠫⠙"] # 0x22c4 - "⋜": [t: "⠱⠐⠅"] # 0x22dc - "⋝": [t: "⠱⠨⠂"] # 0x22dd - "⟂": [t: "⠫⠏"] # 0x27c2 From fc79ce983e4cfa34208d4e198ed1dc5fa9441a7e Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Fri, 21 Aug 2026 18:18:04 -0700 Subject: [PATCH 071/157] Fix up UEB mtable notations. There are made up rules (awaiting feedback from ICEB) about how to represent the start of a new row in linear form. add two dot-like characters used in an ellision example in a matrix --- Rules/Braille/UEB/UEB_Rules.yaml | 59 +++++++++------ Rules/Braille/UEB/unicode-full.yaml | 3 +- Rules/Braille/UEB/unicode.yaml | 1 + tests/braille/UEB/iceb.rs | 111 +++++++++++++++++++++++----- tests/braille/UEB/other.rs | 13 ++++ 5 files changed, 143 insertions(+), 44 deletions(-) diff --git a/Rules/Braille/UEB/UEB_Rules.yaml b/Rules/Braille/UEB/UEB_Rules.yaml index 04c63947d..4d5b8ca1d 100644 --- a/Rules/Braille/UEB/UEB_Rules.yaml +++ b/Rules/Braille/UEB/UEB_Rules.yaml @@ -138,42 +138,53 @@ # matrix and determinant are the same other than "matrix"/"determinant" based on the bracketing chars # we don't do spatial layout, instead the beginning/ending of each row uses the enlarged bracketing chars - - name: default-matrix - tag: mrow - variables: - - RowStart: "*[1]" - - RowEnd: "*[3]" - match: - - "*[2][self::m:mtable] and" - - (IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')) - replace: [x: "*[2]"] + name: default-matrix + tag: mrow + variables: + - RowStart: "*[1]" + - RowEnd: "*[3]" + match: + - "*[2][self::m:mtable] and" + - (IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')) + replace: [x: "*[2]"] + - - name: default-mtable - tag: mtable - match: "." - replace: [x: "*"] + name: default-mtable + tag: mtable + match: "." + variables: # should only be here for lines of equations -- made up dot-6, dot 0 as a parallel to dot six before parens + - RowStart: "IfThenElse($RowStart = '', '⠀', $RowStart)" + - RowEnd: "IfThenElse($RowEnd = '', '⠀', $RowEnd)" + replace: [x: "*"] + - name: default tag: [mtr, mlabeledtr] match: "." replace: - - test: - if: "../*[2]" # more than one row + - test: + if: "preceding-sibling::*" # between rows (not before the first) then: [t: "⠸W"] - - x: $RowStart - - test: + - test: + if: "../../self::m:mrow" # matrix, etc., or non-standalone lines (probably doesn't happen) + then: + - t: "⠠" + - x: $RowStart + - test: if: .[self::m:mlabeledtr] then: - - t: "⠗⠕⠺W⠇⠁⠃⠑⠇⠸⠒" # "row label:" - - x: "*[1]/*" # contents of row label - - test: + - t: "⠗⠕⠺W⠇⠁⠃⠑⠇⠸⠒" # "row label:" + - x: "*[1]/*" # contents of row label + - test: if: .[self::m:mlabeledtr] then: [x: "*[position()>1]"] else: [x: "*"] - - test: - if: "../*[2]" # more than one row - then: [t: "⠠"] - - x: $RowEnd + - test: + if: "../../self::m:mrow" # matrix, etc., or non-standalone lines (probably doesn't happen) + then: + - t: "⠠" + - x: $RowEnd + - name: default tag: mtd diff --git a/Rules/Braille/UEB/unicode-full.yaml b/Rules/Braille/UEB/unicode-full.yaml index 1df920330..717fa5355 100644 --- a/Rules/Braille/UEB/unicode-full.yaml +++ b/Rules/Braille/UEB/unicode-full.yaml @@ -130,7 +130,8 @@ - "‒": [t: "⠤"] # 0x2012 (figure dash) - "—": [t: "P⠠⠤"] # 0x2014 (em dash) - "•": [t: "⠸⠲"] # 0x2022 - - "․": [t: "⠲"] # 0x2024 + - "․": [t: "⠄"] # 0x2024 (one dot leader; GTM 15.4 matrix omission dot) + - "‥": [t: "⠲⠲"] # 0x2025 - "‼": [t: "⠖⠖"] # 0x203C - "‾": [t: "⠱"] # 0x203E diff --git a/Rules/Braille/UEB/unicode.yaml b/Rules/Braille/UEB/unicode.yaml index ccee08652..477946d70 100644 --- a/Rules/Braille/UEB/unicode.yaml +++ b/Rules/Braille/UEB/unicode.yaml @@ -118,6 +118,7 @@ - "†": [t: "⠈⠠⠹"] # 0x2020 (Dagger) - "‡": [t: "⠈⠠⠻"] # 0x2021 (Double dagger) - "…": [t: "c⠲c⠲c⠲"] # 0x2026 (Ellipsis) + - "⋯": [t: "⠄⠄⠄"] # 0x22EF (midline horizontal ellipsis; GTM 15.4 matrix omission) - "′": [t: "1⠶"] # 0x2032 (Prime sign) - "″": [t: "1⠶⠶"] # 0x2033 (Double prime sign) - "‴": [t: "1⠶⠶⠶"] # 0x2034 (Triple prime sign) diff --git a/tests/braille/UEB/iceb.rs b/tests/braille/UEB/iceb.rs index 2c7c9a5c7..b7f3a6560 100644 --- a/tests/braille/UEB/iceb.rs +++ b/tests/braille/UEB/iceb.rs @@ -1468,43 +1468,116 @@ fn binomial_14_3_3_2_mtable() -> Result<()> { #[test] fn matrix_15_2_1() -> Result<()> { // GTM 15.2 first example: I = [[1,0],[0,1]] with enlarged parentheses (one-line encoding). - let expr = r#"( - 10 - 01 - )"#; - test_braille("UEB", expr, "⠸⠀⠐⠣⠼⠁⠀⠼⠚⠠⠐⠜⠸⠀⠐⠣⠼⠚⠀⠼⠁⠠⠐⠜")?; + let expr = r#"I= + ( + 10 + 01 + ) + "#; + test_braille("UEB", expr, "⠠⠊⠀⠐⠶⠀⠠⠐⠣⠼⠁⠀⠼⠚⠠⠐⠜⠸⠀⠠⠐⠣⠼⠚⠀⠼⠁⠠⠐⠜")?; return Ok(()); } #[test] fn matrix_15_2_2() -> Result<()> { - // GTM 15.2: matrix with enlarged square brackets. - let expr = r#"[ - ab - cd - ]"#; - test_braille("UEB", expr, "⠸⠀⠨⠣⠁⠀⠃⠠⠨⠜⠸⠀⠨⠣⠰⠉⠀⠙⠠⠨⠜")?; + // GTM 15.2 second example: matrix multiplication (linearized with `⠸⠀` between rows). + // [1 2 3; 4 5 6] [1 2; -3 4; 5 -6] + let expr = r#" + [ + 123 + 456 + ] + [ + 12 + -34 + 5-6 + ] + "#; + // example has G1 passage mode start/end, but they are not needed and not included. + test_braille( + "UEB", + expr, + "⠠⠨⠣⠼⠁⠀⠼⠃⠀⠼⠉⠠⠨⠜⠸⠀⠠⠨⠣⠼⠙⠀⠼⠑⠀⠼⠋⠠⠨⠜⠠⠨⠣⠼⠁⠀⠼⠃⠠⠨⠜⠸⠀⠠⠨⠣⠐⠤⠼⠉⠀⠼⠙⠠⠨⠜⠸⠀⠠⠨⠣⠼⠑⠀⠐⠤⠼⠋⠠⠨⠜", + )?; return Ok(()); } #[test] fn matrix_15_2_3() -> Result<()> { - // Single-row: no enlarged (dot-6) markers (UEB_Rules one-row path). + // GTM 15.2 third example: (a −b ; −c d), linearized with `⠸⠀` between rows. + // Spec spatial braille (ASCII): ,"< a "-b,"> / ,"<"-c d,"> + // Spec spatial (Unicode): ⠠⠐⠣⠀⠁⠀⠐⠤⠃⠠⠐⠜ / ⠠⠐⠣⠐⠤⠉⠀⠙⠠⠐⠜ + // (extra space after the first-row open paren aligns columns so the minus stands out) let expr = r#"( - 123 + a-b + -cd )"#; - test_braille("UEB", expr, "⠐⠣⠼⠁⠀⠼⠃⠀⠼⠉⠐⠜")?; + test_braille("UEB", expr, "⠠⠐⠣⠁⠀⠐⠤⠃⠠⠐⠜⠸⠀⠠⠐⠣⠐⠤⠉⠀⠙⠠⠐⠜")?; return Ok(()); } #[test] fn determinant_15_3_1() -> Result<()> { - // GTM 15.3: determinant with enlarged vertical bars. + // GTM 15.3: |P| = |a b; c d| = ad − bc (determinant linearized with `⠸⠀` between rows). + let expr = r#" + |P| + = + | + ab + cd + | + = + ad-bc + "#; + test_braille( + "UEB", + expr, + "⠸⠳⠠⠏⠸⠳⠀⠐⠶⠀⠠⠸⠳⠁⠀⠃⠠⠸⠳⠸⠀⠠⠸⠳⠉⠀⠙⠠⠸⠳⠀⠐⠶⠀⠁⠙⠐⠤⠃⠉", + )?; + return Ok(()); +} + +#[test] +fn omission_15_4_1() -> Result<()> { + // GTM 15.4: determinant with omission dots (linearized with `⠸⠀` between rows). + // Spec spatial (ASCII): + // ;;;,_|a5#aa a5#ab 444 a5<#an>,_| + // ,_|a5#ba a5#bb 444 a5<#bn>,_| + // ,_| 4 4 444 4 ,_| + // ,_|a5 a5 444 a5 ,_|;' + // Spec uses . (⠄) / ⋯ (⠄⠄⠄) for omission dots; U+2024 / U+22EF in the MathML. let expr = r#"| - 12 - 34 - |"#; - test_braille("UEB", expr, "⠸⠀⠸⠳⠼⠁⠀⠼⠃⠠⠸⠳⠸⠀⠸⠳⠼⠉⠀⠼⠙⠠⠸⠳")?; + + a11 + a12 + ⋯ + + a1n + + + a21 + a22 + ⋯ + a2n + + + . + . + ⋯ + . + + + am1 + am2 + ⋯ + amn + + |"#; + test_braille( + "UEB", + expr, + "⠰⠰⠰⠠⠸⠳⠁⠢⠼⠁⠁⠀⠁⠢⠼⠁⠃⠀⠄⠄⠄⠀⠁⠢⠣⠼⠁⠝⠜⠠⠸⠳⠸⠀⠠⠸⠳⠁⠢⠼⠃⠁⠀⠁⠢⠼⠃⠃⠀⠄⠄⠄⠀⠁⠢⠣⠼⠃⠝⠜⠠⠸⠳⠸⠀⠠⠸⠳⠲⠀⠲⠀⠄⠄⠄⠀⠲⠠⠸⠳⠸⠀⠠⠸⠳⠁⠢⠣⠍⠼⠁⠜⠀⠁⠢⠣⠍⠼⠃⠜⠀⠄⠄⠄⠀⠁⠢⠣⠍⠝⠜⠠⠸⠳⠰⠄", + )?; return Ok(()); } diff --git a/tests/braille/UEB/other.rs b/tests/braille/UEB/other.rs index b31f9958f..f1beb55cc 100644 --- a/tests/braille/UEB/other.rs +++ b/tests/braille/UEB/other.rs @@ -255,3 +255,16 @@ fn ueb_italic_typeform_for_digits() -> Result<()> { return Ok(()); } +#[test] +fn multiple_lines() -> Result<()> { + init_logger(); + // Bare equation-line mtable: `⠸⠀` between rows, no start/end bounds. + let expr = "x=f(t)y=g(t)"; + test_braille( + "UEB", + expr, + "⠰⠭⠀⠐⠶⠀⠋⠐⠣⠞⠐⠜⠸⠀⠰⠽⠀⠐⠶⠀⠛⠐⠣⠞⠐⠜", + )?; + Ok(()) +} + From 1b32804d01fbe1b3a86fd5f023ef03cc5a969155 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Fri, 21 Aug 2026 20:04:30 -0700 Subject: [PATCH 072/157] accidentally picked up wrong version # when merged in release-candidate --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 768d8bd50..67522e0b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mathcat" -version = "0.7.6-rc.2" +version = "0.7.7-alpha.1" authors = ["Neil Soiffer "] license = "MIT" description = "MathCAT: Math Capable Assistive Technology ('Speech and braille from MathML')" From 7ee9e3a3fc688660eb012adf41d8ca308ba99123 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Fri, 21 Aug 2026 20:05:16 -0700 Subject: [PATCH 073/157] bump version # --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 768d8bd50..26749dc34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mathcat" -version = "0.7.6-rc.2" +version = "0.7.6-rc.3" authors = ["Neil Soiffer "] license = "MIT" description = "MathCAT: Math Capable Assistive Technology ('Speech and braille from MathML')" From f89080fa73bb8d2441ae28bb91bfef2f020864ed Mon Sep 17 00:00:00 2001 From: mgros Date: Sun, 23 Aug 2026 00:59:29 +0200 Subject: [PATCH 074/157] add Math4VIP to German translators --- docs/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 36b4ca41d..62805d15a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -166,14 +166,14 @@ Several people helped out in various ways with the project. I am very grateful f * Elaine A. Moore -- helped me to figure out what should and should not be said for chemistry, along with what makes sense as chemistry and what doesn't. * Richard Orme -- did all the work for the MathCAT NVDA settings dialog. * Sam Dooley, Murray Sargent, and Volker Sorge -- provided tables of Nemeth translations of characters and Nemeth tests -* Moritz Groß ([Math4VIP](https://www.math4vip.de/)) -- worked on various parts of the Rust code base, and built the Python tool for tracking localization progress. +* Moritz Groß ([Math4VIP](https://www.math4vip.de/), Marburg University) -- worked on various parts of the Rust code base, and built the Python tool for tracking localization progress. Translators: * Chinese (Traditional) -- Hon-Jang Yang * Finnish -- Sami Määttä (Accessibility Library Celia), and Essi Viippola (freelancer) * French -- Olivier Thiffault (Technologies Humanware) -* German -- Nazli Andjic, Robert Graf and Paul Libbrecht (IU International University of Applied Sciences) +* German -- Nazli Andjic, Robert Graf and Paul Libbrecht (IU International University of Applied Sciences), and Moritz Groß (Math4VIP, Marburg University) * Hungarian -- Attila Hammer (IT Foundation for the Visually Impaired) * Indonesian -- Dr. Pinta Deniyanti Sampoerno, M.Si; Dr. Meiliasari, S.Pd., M.Sc; and Ari Hendarno, S.Pd., M.Kom. * Norwegian -- Marthe Gjelstad (National Library of Norway), Kvile From 88129bed9597d4ed8ce92725b71f4bab49d497ee Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Sun, 23 Aug 2026 00:25:10 -0700 Subject: [PATCH 075/157] Fix up arc look-alike chars due to canonicalize change. Remove duplicate char definitions in unicode files. --- Rules/Braille/French/French_Rules.yaml | 2 +- Rules/Braille/French/unicode-full.yaml | 2 +- Rules/Braille/French/unicode.yaml | 12 +----------- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/Rules/Braille/French/French_Rules.yaml b/Rules/Braille/French/French_Rules.yaml index 3c77813a5..46c74a15c 100644 --- a/Rules/Braille/French/French_Rules.yaml +++ b/Rules/Braille/French/French_Rules.yaml @@ -424,7 +424,7 @@ - name: single-char-exceptions tag: [mover] - match: "*[2][translate(., \"⏜^→⇀¯⌣◌̌~\",'')='']" + match: "*[2][translate(., \"⌒⌢⏜^→⇀¯⌣◌̌~\",'')='']" replace: - x: "*[2]" - x: "*[1]" diff --git a/Rules/Braille/French/unicode-full.yaml b/Rules/Braille/French/unicode-full.yaml index c0bc5275e..65530bdf8 100644 --- a/Rules/Braille/French/unicode-full.yaml +++ b/Rules/Braille/French/unicode-full.yaml @@ -19,7 +19,7 @@ - "": [t: ""] # 0xfeff (BOM / zero-width no-break space) - - "⇌⥂⥄⥃": [t: "⠸⠻"] # 0x21CC/2942/2944/2943 equilibrium (incl. trend variants) + - "⥂⥄⥃": [t: "⠸⠻"] # 0x2942/2944/2943 equilibrium trend variants (⇌/0x21CC is in unicode.yaml) # Mappings for some new Unicode chemistry arrows/symbols # These repeat the short arrow version because that is what is in the spec (GTM 16), but the spec should really use the long version diff --git a/Rules/Braille/French/unicode.yaml b/Rules/Braille/French/unicode.yaml index 89f876bd6..694f6d73e 100644 --- a/Rules/Braille/French/unicode.yaml +++ b/Rules/Braille/French/unicode.yaml @@ -370,20 +370,10 @@ - "⊗": [t: "⠨⠔"] # 0x2297 (circle with interior cross (tensor product)) - "⊥": [t: "⠘⠳"] # 0x22A5 (is perpendicular to) - "⋅": [t: "⠔⠔"] # 0x22C5 (dot,and times) - - "⟵": [t: "⠸⠪"] # 0x27F5 (Long leftwards arrow ) - - "⟶": # 0x27F6 (Long rightwards arrow) - - test: - if: "parent::m:mover and not(following-sibling::*)" - then: [t: "⠨⠒"] - else: [t: "⠸⠱"] - - "⟷": [t: "⠸⠻"] # 0x27F7 (Long left right arrow) - - "⟸": [t: "⠐⠒"] # 0x27F8 (Long leftwards arrow ) - - "⟹": [t: "⠒⠂"] # 0x27F9 (Long rightwards arrow) - - "⟺": [t: "⠐⠒⠂"] # 0x27FA (Long left right arrow) - "⌄": [t: "⠸⠘⠒"] # 0x2304 (inverted caret) - "⌣": [t: "⠈⠈⠈"] # 0x2323 (smile) - - "⏜": [t: "⠈⠒"] # 0x23DC (arc concave upward) + - "⌒⌢⏜": [t: "⠈⠒"] # 0x2312 (ARC), 0x2322 (FROWN), 0x23DC (TOP PARENTHESIS) - "△": [t: "⠨⠘⠙"] # 0x25B3 (increment (laplacian Delta) ) - "✕": [t: "⠐⠐⠔"] # 0x2715 (multiplication X) - "⟧": [t: "⠨⠾"] # 0x27E7 (right barred bracket) From 9f8d81f29fa0bf983b7746d3168f74838f81ffea Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Tue, 25 Aug 2026 01:47:42 -0700 Subject: [PATCH 076/157] fixes no-unsafe branch clippy issues --- src/braille.rs | 12 ++++++------ src/chemistry.rs | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/braille.rs b/src/braille.rs index 553059bfc..1966f09c0 100644 --- a/src/braille.rs +++ b/src/braille.rs @@ -2430,10 +2430,10 @@ fn remove_optional_group_indicators(braille: &str) -> String { for (i, &ch) in chars.iter().enumerate() { if ch == 'b' { stack.push(i); - } else if ch == 'e' { - if let Some(b_idx) = stack.pop() { - pairs.push((b_idx, i)); - } + } else if ch == 'e' + && let Some(b_idx) = stack.pop() + { + pairs.push((b_idx, i)); } } @@ -2583,7 +2583,7 @@ fn french_cleanup(_pref_manager: Ref, raw_braille: String) -> // This reuses the code just for getting rid of unnecessary "L"s and "N"s let result = remove_unneeded_mode_changes(&result, UEB_Mode::Grade1, UEB_Duration::Passage); - debug!(" after removing mode changes={}", &result); + debug!(" after removing mode changes={}", result); // remove any grouping pair at the start or end -- we ensure they are a pair but making sure there is no "o" inside the string let result = if result.starts_with('o') && result.ends_with('c') && !result[1..result.len() - 1].contains('o') { @@ -3553,7 +3553,7 @@ impl NeedsToBeGrouped { }; debug!("needs_grouping_for_french: mathml (sans '-') = {}", mml_to_string(mathml)); - let node_name = name(mathml); + let node_name = as_str!(name(mathml)); let children = mathml.children(); match node_name { "mn" | "mi" | "mtext" => { diff --git a/src/chemistry.rs b/src/chemistry.rs index 78bbd3746..64295196a 100644 --- a/src/chemistry.rs +++ b/src/chemistry.rs @@ -534,9 +534,9 @@ fn set_marked_chemistry_attr(mathml: Element, chem: &str) { // inherit from the base let base = as_element(mathml.children()[0]); if let Some(base_chem) = base.attribute(CHEM_EQUATION_OPERATOR) { - mathml.set_attribute_value(CHEM_EQUATION_OPERATOR, base_chem.value()); + mathml.set_attribute_value(CHEM_EQUATION_OPERATOR, as_str!(base_chem.value())); } else if let Some(base_chem) = base.attribute(CHEM_FORMULA_OPERATOR) { - mathml.set_attribute_value(CHEM_FORMULA_OPERATOR, base_chem.value()); + mathml.set_attribute_value(CHEM_FORMULA_OPERATOR, as_str!(base_chem.value())); } } _ => error!("Internal error: {} should not be marked as 'MAYBE_CHEMISTRY'", tag_name), From 4952dd78b8ffcf138635c6290b26c8e852965bbb Mon Sep 17 00:00:00 2001 From: Richard Orme Date: Fri, 28 Aug 2026 00:58:45 +0100 Subject: [PATCH 077/157] Update MathCAT logo and add descriptive alt text. (#714) Co-authored-by: Cursor --- README.md | 2 +- docs/callers.md | 2 +- docs/helpers_old.md | 2 +- docs/index.md | 2 +- docs/ru/callers.md | 2 +- docs/ru/helpers.md | 2 +- docs/ru/index.md | 2 +- docs/ru/users.md | 2 +- docs/users_old.md | 2 +- logo.png | Bin 5162 -> 64842 bytes mathcat_logo_regular.png | Bin 0 -> 55590 bytes 11 files changed, 9 insertions(+), 9 deletions(-) create mode 100644 mathcat_logo_regular.png diff --git a/README.md b/README.md index de080bb0f..d34a66632 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # MathCAT: Math Capable Assistive Technology -The MathCAT logo with a cat sitting on the text MathCAT +Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. is a library that supports conversion of MathML to: diff --git a/docs/callers.md b/docs/callers.md index 763a8484e..0fbe0f189 100644 --- a/docs/callers.md +++ b/docs/callers.md @@ -1,5 +1,5 @@ # MathCAT: Math Capable Assistive Technology - +Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. ## Information for AT and Other Library Users diff --git a/docs/helpers_old.md b/docs/helpers_old.md index 59b8387a3..dea983da6 100644 --- a/docs/helpers_old.md +++ b/docs/helpers_old.md @@ -1,4 +1,4 @@ -# Translator and Rule Developer Guide +# Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. Translator and Rule Developer Guide ## Information for MathCAT Rule Developers/Translators This page is a work-in-progress. diff --git a/docs/index.md b/docs/index.md index 62805d15a..e965c905d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,5 +1,5 @@ # MathCAT: Math Capable Assistive Technology - +Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. is a library that supports conversion of MathML to: * Speech strings with embedded speech engine commands diff --git a/docs/ru/callers.md b/docs/ru/callers.md index c189234e3..cc3117baa 100644 --- a/docs/ru/callers.md +++ b/docs/ru/callers.md @@ -5,7 +5,7 @@ ref: callers title: Интеграция MathCAT --- # MathCAT: средство обеспечения доступности математики - +Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. ## Информация для разработчиков ассистивных технологий и пользователей библиотеки diff --git a/docs/ru/helpers.md b/docs/ru/helpers.md index be36a6116..0cb0b8769 100644 --- a/docs/ru/helpers.md +++ b/docs/ru/helpers.md @@ -4,7 +4,7 @@ lang: ru ref: helpers title: Руководство переводчика и разработчика правил --- -# Руководство переводчика и разработчика правил +# Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. Руководство переводчика и разработчика правил ## Информация для разработчиков правил и переводчиков MathCAT Эта страница находится в процессе подготовки. diff --git a/docs/ru/index.md b/docs/ru/index.md index 25c7d1b5a..a577238ad 100644 --- a/docs/ru/index.md +++ b/docs/ru/index.md @@ -5,7 +5,7 @@ ref: index title: MathCAT --- # MathCAT: средство обеспечения доступности математики - +Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. — библиотека, которая преобразует MathML в: * текст для озвучивания со встроенными командами синтезатора речи; diff --git a/docs/ru/users.md b/docs/ru/users.md index 29d4fa9f1..bb4102cc5 100644 --- a/docs/ru/users.md +++ b/docs/ru/users.md @@ -4,7 +4,7 @@ lang: ru ref: users title: Руководство пользователя MathCAT --- -# Логотип MathCAT Руководство пользователя +# Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. Руководство пользователя ## Рекомендации по выбору голоса diff --git a/docs/users_old.md b/docs/users_old.md index 5acaecc8e..308f74bdb 100644 --- a/docs/users_old.md +++ b/docs/users_old.md @@ -3,7 +3,7 @@ layout: default lang: en ref: users --- -# MathCAT logo User Guide +# Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. User Guide ## Advice on Choosing a Voice diff --git a/logo.png b/logo.png index ca5b5c9f79a5ac789def198da43ada8e8810352f..51400749c09484d06e1157195d2a2cb12b116e3a 100644 GIT binary patch literal 64842 zcmd43i9eKW_%?pqv-gmqk`_xyWG%voWXrx3F|w~wgsf9ak4nm#ePkKCvSuBUgzQ^( zE%q48Ft(X_uiJRO-}m?a1;6<`pQpLzzRi8D=XspRd7KljuX}@)={OSvL9Ch@YK9O* z3*OQ~hv>mSA-tlY5Jdb(Q%%L#FZnNV(Tnp@DsDH}Q22J-2QePiyF8&)ED^$EA0>>s zWtxV0E!Q(0uX}$X{T@_)uz6)srRSqf_0Zp?zA{T18Kdk=H}87hz3})_#fP^A+9F*v zSFUTtxmg+#2%S zVm_^2@;vmH3WBESIOw>g$GYb%Xm{Z2^c*yEW@De`9#NVM{Pf+6pHzCh4sC&(B@SsE zLJxVWzRy3j2{&~#n9xa|w!81s65&C&Lf)t3PL8}r@qxx=UPh|26LQ=mPtb7F=~OFJ zMkB{{RkfQPH2os&pxVz7PvZ{bX+SeYRT3(kno(&wv;)2uwS0~TrGCE&eUFv|E+TMe z{z3WQ&zMr%e++_rng4g@d4gpuuA#V>MWX6u1KQqSwn)K|g(B)76Ag17_uuySO zP0@4P?0-$e%9(#8YPY7IAAYP1u0b4BP0!f_|2@0~cOXaYthL{Y3Om*QcS0C&>(&;E zfqVZ}l=|C4+;;*$(EQr~4+W90LCbOqSt$-poZW(-IYnplvQbst5wS82@4xPg#xyMS zN?(+2>~{ifq(O_9Q>sbWB=si*(GHZUyE~sCMsA(2H}xGjeh>m9^CCYp)V435r1{qe`&)_^rQi6cR&s_ zcZrq^nh-tJ$D6n_RNbmuPv9mu|Ch^k&!S$PYKW%>%?5Oa0D2ePElKG~6Y2+MR|E3? z2MON{H9h6dsX5;`M}5zKzxg^2)d`;5bch6&2txhHIRWlHEO!~c7^w29|297)|MbKO zxcT~=>B33>izBa+c;Mzj(;d|2dunt9!-W> z%|~C1msF@5Y{zoozwMT{5yicQRu0RZhns%Sx!W!Hp{t)G7~$r`xxqCyMu^>06&?^` z_psNaP~MkfQ-bh1pgJX4LN8Zn8bi|IQ}Dt;@{zX+9`Qqo4Xp68LF1}AgC{v4)?e!I zw1zAMei93_XB}Dt?tUgh?2i=OKF}l&F9;HCI@H0^p*T0+caX^?U zbxQNbUmtl6NN9?Fze!SI@s;F&WITU^dm#k*Ok92hErM%I0&aF=|DDe}N2UMx1RdPm z;rlp#pC7vONd<0MdmjEBdydNU=?S=VU|)ZnIK~gZ1M5i552>jig5T2fTtfDA3qha$ zfm_xq|Ln3pqDJj60ucl0qy;l^*a`OYU_7WN^nc!Zx8Uv_Q%C-q|##Yd|c0 z46qr7oW6hf@`@%6;*MkIfZN@*cmL&OP};v2boVNi1Pjke_yS6fUNP+C584KFh$q~J zaI6n5T={S?!z;}QL5Ti}?f%%Eid77YB8@1Z%M(0A$k zkMM3mH@~BahPcbvVIKf>2ZbJSWz&Jz0=)WV4>O`v+P>{K{M*rAl4;)VzlR{9#a+-9 zJDdGxo$Fznu6jMnB~;(WLu%{8lKV@BB6Z^~IZX;eJH&|nJ%mpSetmsc_F#MqL-CBL z;LcC`f4O6U{hAq+aPWYL`5IaT*1>$g8JfXo+gGoB@PMxyCe&y?sS9uu)!6TG$ptAu zxrFfA5v1z&NZ^8-4O5GlTjd`6(+VcxQP5jx4)bb%)~!F`wZD%XJD9xg#8f>9uPwO0 zt0Zc7&iE{CA54~$rJfM9b0&0uLQws?m)t;m|Ams%puCZw^_QjUUd)2+4Fnl4Oy8<- zq`Ze36ciJnx#?Gw=LpRYysHrU?-Dqb`!8;4#dv6Lz>sp!!obUq?p+6?K@t2#sJdVB zP)3m0<9g|y-hTrPctiPf>qB@QYV?rSx&5Y-iFk9hVl?Fv1gymVJJgwOPDYfKNceuM zLA#D)eN*jViOc?*gfPSqCsb$1w7)Wl8vM1tqZ|KCg7U!}vOF#lg#6QKDYKzF=fk42 zKW7l6iaNOWf8U^88BzBL`{xDfb{>EAESJ(P>qGz3b#DPG#I`d0vGuKoqJo>gzct~< zdq*m4O0ZyFtQJ z@MT(p(Jxwl@8IX7`JHWSu1QHr$p>r}TuVPpc;7-o>MWwWYLcZ5*=RbjsUgc5x^WNsGes{o~TKpVQne+3`Viztr z1qWNjiz5g7`;QRbKbI%5NkWIgc%76-D<1m!bEc>51vnV9`sQt=pyXb%leD~X_JKivF2k9K5Ga<*i-47~d`o{)^R`pPE7_C@75l_|Xme_;7dAUD0m^ z;ftFXz~iL{pd9V#T=K#~UR+!pr5`zMyC3z>$CNYIhLEi)+!yz@*I%fe9SadVyZ=0v zH-SpUOH1xxw&s2|Jr|-U->Yzs4=c^;b6)!U*9j~+{IKESp3k4D2cXLag+}Co0h7Yw zV%LBGiv*pSFT353lJ8u^5Q#x`LA$2;`T2=yX=Y#*zkNGIKr+iGLg+o%0Xp%GR>bOJ z%IoWkva$rk#KnhLNUlqkzCzR`!*0Xq3I_I5a}#v|i3tfkb93iaxV07(H;RvP3|1dw ze)hyL*LXhI$HDN6&82N(=>0hN(Ted_SyZFn5cp>3d|KDy@0Lh&3yZ!!j9#n;zb*@D zoa|e!h7gQ4IQ#beiT=2**@t9OkU6!!q5G7bB8IfVpOyR~PDn3xF2A@QUY5>OMFj~) zlkfWV3=?!um2Gmt7!7{iM>GlsHIZgEhH8XsdWn zYBspU-D23ybaZqSUY5QQs5R^&SS#K!=u=31iS9L@F>}3 z0DAuXx&Q8FVaf0XF{;ahIBae0ouTjH4%MHTpIytXv-a{b3J3@|e&WQ5PZ3ZGV&7PB zL)(E?;M0+@vHs`md@&sk`Eff#8KyFj7}XmW!ftUvf#1B`S1ZJMDY`-4;S*iC2?8m=F}J3 zdn+e{wK=RCjOpS19AvRW)T^QQ<$xm2QMMj5TG39zSa#hv*G8?6@l(;?kP8i&P0cr* zmQ+&eJc*(|ICqG`KC(~p=Rp@nPii#=O%!R!X=SprH_)-Od1NH<=&@rwv_EL~tra3I zU*>e7rAs;O8(Qv@9R=I2zDT7|$l}KS%*}Z%NB4kn-?=#ScD8Vk1HpkN%aqO(8>w!O z$jsW@^5&;%*mvD%Mcq-TJA77%QR1?E)lBj5;)yRSB}Pe54!qwWdW4*wx+XPC*uCOy zh572djuh@MYKWSH-m1xko{fTtg~tZ>242ddW)40!#?VNEk8?R2v1eLmMM)kOhUxly zlMz-z`H%(0yUcl6rR)W8Wxl1IPPQ*jbw>?YpGEN_$lqqyMI^iGrSeHA_3>`L9TvKs8|jT#&p z0#?j|iNvazEqq;sL#xMgHTA)}Z14M$=-r{u{%H%0Bybx)wS^Oh! zyakSFD?c&t;Q`A+S0k^;YEs%R>Fgs9@;60Y`#u$xQ00z(fw z$%hQ&4f+B5MzYODaEPY+Hp?(=HwcK}mu`P9KT7ItF!1mnZ|OWnpdLY|{&yn-@B8E9 z6qYy5qP#Kw_wV1vFZ;vy*A`{;@GRrhgeG6Onq8uxDwT!tcKtyucU8cY|rIags(1A^@G|dRT^t(1AO$5-4luW2$FeO!o^k4{18UGj&=5unl;spn z>*Cw3*_g|kLfX(EN-1tZwQV-q#sFJib=>sALVTAQxoc2|`bU)5{BtwmAg$YZLTa{B zs7e=BV!NHBy^0r>jvTXH`Fek_5}7Z!pcw-?RPizss<+Ebllp=cmUw=Zbr&v*hrW92Qm^(IZc1b$L;OTJ(2s_$>~Trzx|t!JU85pZ5F*7 zEQN==k;#k+?#}& zG>ToFViX^uNtI={c5%^4*Uxb;gi_2e4Y^2+YfOe%4rTN`C#8oR+?n80#NgdF#-|)y zkee$E;Ok8t9jCy+JN4>5+<88zw659M_UYHLos};qab~9vznKiVDy<-PMZfA|&&&Fd zFcPaQWq)2BDB3`EUWI%`8@AVHAFlqo{;cU|o)nb`&7?V1z58g%1sEm+#0rCDliBOC zt2> z5-q2Dmo400(nd|}qYeZZs(t!MWJ`HPMK;BeRhU9e5=Rcvf)l1C#Y+7cA^c5A_=@#t z#oBf)3^~B|Qw-eFk36NgmWjj0KPPQ`mcc7f1~T$Fe*;x+PDR=o!ny!B2Seo)1z+#= znVXjNfwygKZFlyzy>6qCdMKorN_QtMit~^1qqWQdN^{dp;NKp?i!C%@L5{Z>BL=>(mHcw}%7aN0Aov*jN?pusu- zlzEaFzsR_vph#mK5`x4{)QO6&D+^zls_(Ru%B->f!@S&3d zNKe3RfLFtZ5`ob;rV6|Exc-Tp;(>J3y-s02r8G0(l{!0L%gV~)k>m{|fKYvnjVi(_ zQ*3xW<`o4Q;^f=*>6rHEJVDDm0fsR!TL6a+sC_-nPF&w5+AsYx;Gm4ASn!57B?3X6 zw_f0;@mDyF`Q0i6=%xnr8(an$W5ZDd+@x6w)f8zrVohFHU+h-l=1Cy|2Hol+6}}y_ zLPhHTY)I}k74QWcP5CkRzN*V8xwN^tC0UKv9%q`ns$Qsu;*^l%DD&OvCuh#)%U$XI zZd((}amlMr0bhK)Ng~e_LMzo8!J~a6VhSC3Edm`EZ}KqiNJl+?7B)krQO-%Vtej84 z;sjDYeJ!acHD*88BP%i9rZa$|F%CsAG*#)?eBIPiW zNs}Pz>j6+fDATJhOX5SDzRpmguZ%D63f=9qbYED3Jx#YT(Ufh8O;V3p<0mg>;g>Eu zp6FY>Mtgn#*rJpMx@daF8nbKoiJf;IDa+S-_3n-hPhm?-g;wY&U?p;6T}xVM?&^}= z@xsL{EoQ=I_?DH`vunOZw%n8s?A$76LIo$$o!&4-$vgSy;*k$Tpn?o0)HO>ki0G$B zIJ>{_h_uB@9_U^fbs4fah7^BtgLLfguL~&kjo%IJRy};I*WlgZvOqxPJdl}6srs;4 z^MR}3&7XBHvhS!AyU!|rt-ceErB(&RJ+n{EDk;y_|5~wBBydE8W>8HMGu{=)bn1F* z`IA7^uuj^b7uSjMoYDi!@gAePJb|Pf7SbG@|2yvUg|};aPh^p;xMSkt?;T8dsqOTS zamMUq5h%CTj_8$*ZYeg>$`-qAN>sUDjv!~Ao^;gs=!BTO!zy}|wTu{3YpuOnH`a5y z_Kt9)fy||DYr_WpRmE3NUo?{WmUWy~wFuhel&(rH;#GXfF-pu&AES^{lofc|LjSEN zVP{#?g6e4TQvprKCrWi1c6c8-OsJ~1X)NLg@5%}Fjr~VTWJ;;5&p8H4j_h6hQL=G` zv%lkq(|xXq9_G9_?i?ZEsoLPl9#`yTo^F8MV4Dxj?e(TQqaBa-i*-fnZ6|jgE!h`O zjl)=)UQMbL8WSBp*vx+)8~oJW-jOqFN_59~Vp8$dVY#3I8X{+C zV8(kF^b*VU&)HvZbo|Oc{}4K<$C4a(M8lq$De?%Cyp@xi(280{GB55tLpuo3950^R z#W}PFUixW#S?luco8?y|XwZN}1uqm;x10W->xdZv-+?DxZv;PQ-+P@{4Z6O;tWp;k z-?QfbXgF}XwSGSTpE)`1Kb4~TK2~XGOf)MfPxK=T7Xt)b?JHC8!w&H~qj^ZlC+7Qo z?2CJZ_8Lyz)w)`yXEUcTlMF~7=7W7}BKmS-auTo<`MZ}A#aizj^W^~BiJ5@UOL0y*QNUfeYmjvbI#vRIWRBuGnhDQj{>5{5c5abZog8&pA+mI74OVux# zL**_Nwo#W8J9mxfZ(R>Fa46FOk%%H8#F~r534QJHf%8J1mDM2BrlY1}FLL{Iu-!DI z6npC`7@^So;m6SfVU|0@BV}?gC}`rexhu_F;Z2D9suh3YJF4#E2PgEm_YopG!8F?3 zT?|i>drr9-8tLI%x;`m8b)HZ5w$mqSR0HJuTG!agTvPAn9>Gk^8~3zCWOa9|DN9Ew%0_de_%Si)V}~BOdFjqWvND5om_K!uh&=$4Ks zCaaLv1tH@G&G8-#v!}>;o`qIT^as?faIij^(|x^1pO;g`)^cBLWr6-1)S)D(+v}>9 z$VV#le{NML}MHR{iUE6u;}7Zw%@Q^K)5?l6{ZmR1S=o(B=8 zyyMzR8GarzZB>{w#Q+$00OBC*@K;rwiN&OI})(~Y?$jh0f0-r^GzoiLi|QJi+& zN(GGI$mnR_%uF^6M%-lEFQ5bu{EWuFlLpb_y*%TQeIUGS3C!U}`;9NCqvig3!xe>Y zviaM^ByjTi!SK@T-9GSoq_VvciX2B$dLOPMyJS{<*<9ssHt~Rkq*(5Pn z8mH`XI!gB*-#2_?tarBIC4x04JK;;zZtBL_D!SImC1!Z&-SXmXnJI=#yIff#>PZ|_ zRF+*|E4XGGIp7k&d@!+%FIAjV&XbFMZdPPo z`|0$1N;BT=NdA$)dhvF~vB(>eQ=hUYa7Gi3xvPZgfuB(W^mkrIMgp2udP}1z;$Ukg zuaU9DC6AkhTCR@UWK9*P#)^$AM*4x`#a%qwLem#mni2$YLkVa-rKZz7`q%SuzSE#r z>K#uJ=WwNWxg~?5=DmWK@wBn-qgk__#h?Bs%8~we{|Vi*x}xM_3iOxc=9)|Qp-GtP?xupdHSzDYW7aNk_g`W**VY?@aou5w)|#7m~&mh|a9g1{LG zS(l?UenVcVo2L}qq3K0PN-MiS-Vj3eC(=mhq}|V_%t%m?Svz@rNdH3?u`El>>~QrS zc*?z^tu(^gPBMU{XZWS<=5!=7W>=ef%O{F8=#826vl?}2jhXifpLl!X>t%O>YbIx< z8h`EbyrlOgo8KA|r?Cr+QMLI`Yl5}9I0p|L4b@oK0`9|9dh8Ylh(HE4SRt?fY{Q&w-5ruRSLk=5 z_oXdznsRXO?;#Me$#LNMLayeYzHJgk1-`@*d$_-H$TiJ4V57Rau%!IGyUq};>@kIpO~w0Dv} zmX*gV$Zr$yKigAG7`yUzh7bFbc`ZU}ICx~|PINpk)3ZUZ)I_ex8sQism# zm=Ups9+wj+{@Za`ZnC27CC7DrSSj%aA}w!_bKGs4Tqhet_6^<5+yQZ}z~%$7jY2|{ zOC$Mr#^4K~1Dq5<9a8y3EJ*7Z=!Iwzhug|*k~58Gse8=@M%2!KI5FR-r`@ddkp&4C zyqDmFP<}3%S^*_zT5G2n#-#>yS57dy(3ACEcyVnSraVGg7!1>U7C)ASgl;#TZW!#p zodY9U^ico8^LxN~NCt`Me)ni{{`CJ6L&0Xs!3rjug$hE`yYu2gokY`X6U>cR06MNI zb*RzEb6%|@V-0gz(XDB|?9{JXeuJzEtJ3F{_Y}_2NQmy*25m(-^(ApmsxX+P1F&j- zZrh4qa%8N-S$Vw51;Tg)U6||hmPRKv+MK<%Ks1GBOA9It(v2Fi={Axrj@*fdw!H~j zx3B<|@tBQj*hV^jbJPe+4=Yt+p>{h(K`87ggJdK-=E!c+3sOk&HjD6a*^Q2Y57`-1 zFd)P@GWhp4LKW89tz}uqZY)w`&QaY=od=KdJ=;=}*)e{nWl|x{K*FMF}! zPXE;5PYzWybE^i(VWt`@WtAcwYkmb|#h=EWd%t7f)bIM=ITo2s=u#uvTX4yDR4kQ{ zRe}zTNZ!Chr=?}GZ)#JOtZLL`j9}Nh>HvX)P#qPEn&IA&Y9BAHxsWjp=RkZ8mvw&( z_J&Y~NgRp%$>0v5vMR|4!&aZd!!{YDSVaD9X8Yo4&>BxzVEtMfF$|ZMu@;hM;Kq>S z=&NEM6()lEx-nPC2KK-dzYr_*H1_2N+<{=LKE9N3Rx<_vyzqqg|!*@$$I;@6#Zrcg>jw+KpKAe5KX*MEhF@ds9C@x?5p@jGLi- zQIQFFTSD5JmOV2svjcCO03c82d)i|rmS^M*gSyWX=E;rez$(aF>>wZf%_PlXm9!S5 zlO$X=NVc2^uY+m%`jWHThd@rt)PM6U;1O{JHsDsz*chgk(bXkP=%HKBUf5k{H?9dV z5a?YHL5Q1Lvz$JnOam|Ir3anolG zeh??F+kjsg>2UAzo@HaLK-@pY5pZxpFqryY=U0%6ikG8vmb2s z@?P>-1Q+Vw_!vSz*K8E3t`lxl$@*qZ!FKp`Q$e(^0_4kam{1*q^7Nu!ioM7%66>E% z#xBO5U7>K4=&rI_n!0v@t*nLzlIT?fqk3I;zMS`t+Die}Mo;FWFY3Zxh`=c$boT^; z=#M`K`&4~x*(8vz90I8oK*Rt##yt4@>q6-2FDVw7Jq96&+BYHOvB-E3a3ePUS?XuZ zi*{Ps&P>Qb!pC003s7JFQVl0fvu|G|k~jTt0Z%3waN$9jdrbj{1IQ}5oPD)`dO*6j zFQJjpF=tc0ZCfGBLPl0LOJyX%}fPY>*wD3(T?8@8H0tQp=HE6){;##Y9jEv zv$A_`xAiNhoFAo1vMwS=Hx_leWB$~326nXk9aiyenUOw;^#exi{deQq32;6b0B95B zpi)wO5q47y@T0(`C%XTh56Le)26AYC2n%mfT z2uQ1VMbkQ={AW*q3mZyH<8`_^*9SQH>rK;|C@m{`g|NFZsZG*Z+D7MglyU0#jqf?6 zrQyfHV;aH<6?V5bnxE;Oz6!w426JOZ`a>$s-a#wf5T&1&QVa=JC%k9fT;7G#QSgC)^fBg*Bu#iWkQNrAtV^zCEF+KhK;}AVZ_5Bs+@!P8P$gwo!t5{s|IPn zKl;}Mlu>t8v}=uy4>@p$0e?H5Aewq>5`eQ`cK7Sj`H8CXIpHpm!WLnGRH)C(S{|QC zee3x~cy4tuMkxz>hXB$oEdAtBwfWNM%&r9VJ&;R*Q#-FY_|keY*yn&Ou}o%}1H3n! zu>$jxsW0U+E>)4~HZeFF*=%=Rbn)2wcCC+(PmC^RV{^%Zi0{**P>GK@!kmL{7W=xRm5FavIyu|FYdL#(snS7CvmF4|)Je{we0=S{s zd#f8$_+pV{8H-Tlkd-+qEyK&`1e{!W&#$hO%~N0BH;eoW@@0uBEKXOAPwl1Q6H9p-Z)mNEc$nvFb%nN@kqWM@0Lw7Yc>!+!T{N)Su`Ds$kR+}JpQLfdR zCt_;r6IbGkI`CJr)=0K0i<*(nqev^g=`Nq$FN4J3BY$nmznbz6Etzh6ZPY&hn1i&< zXnu;?JtI098LhjiO>@Y77F!AeuFIRZFBW6)>ouU)~dfGJk8n^)Id& z?2=hOWg76k#I;~`OZWXX5y7*`UsUa7Zj^>Hi53@g<|*pgpGN8#o<719OVX7-J^&aI zb#-;ENR@rC=|m%Bt%vE`*;>u0sHn)Jr*sS36S8AUB07+lCSQjT8)JTmjTpdE|Zh&508h1R_7Ysgh=y2=H;k9JuA^OQ&KEl zp#&?YkpP1_+}(2QEbZbmBd~E=>!s{^9zn(6ZTaB3qg60pa!Ve;DnItf$}TbMX#+4{ z-oT(AD1?TJEc>S0<5i<1U5q$TXHa1Oaf^UWy|SVY(iP^nZ})(lZmLpHUPMGhB2|d! zW3@um&oadOLDGG32CBHC>n(b_0w$~z$-({vBnZ`(_{@vK*LV~o`QijsnzwQ!v@Pr{-FF6+YW(Utl8JgJeO-Fz^`O-&NWvi2s>PLB7&u&Aa=@2 zSsmz|F2;)z>tN*!kmj5_ckYFHhW`#e_ugcEA&|pp^uEdzD;H*@s6JGiu53?^jPz#Q zh{Uh_R0RSW(YG2gg9}$ex|lH=tV25qE_GjeS4~j4#(5V$UCBk(#JQ+Kye(~&uE`5= zLUb-dwEKKXWE9myV+Ig4PNkTy|C2{YY%ewhjKB+WRVNDTVwl_Pf)b%w2bo$frf2YK zc6|RHQ!ifVHjxv1IY;i2r@3K+=AleOVcwG`og5u+fLYwvdW}cp$A40!cLc@SsO zkIJ?7#!qnQGVL%|Sei8;b#_kjot+<(vj}*!gemML_OpOQ84LYG(%vJ>8lRi%>+8VX zoex4L3~P61yod}$K*m!#tpD*oQ1c1 zNpF!|{GPKoGv>efbj(5~(BGvcXIPYW(Xy8?8Bz>1b3`IB+bVQE8c^9g@x?70FCxupgfO~78QPPQ*iIwZ&_&naB?$sD*qx72ph}e z3QNn&B1s*CL_j%EVFS=+h2_ZQ(^zwBr0Bne10oUtBLQ5b*_$Nifd>u|$i$`}RE15j ztM(=s7@2iN&hcHOq1n>+_c}>maoWTdc2Nzm`>2nyuS?NJUNFo}Z@O1*Z^0zm4gDaso+Oppp3Q zT{nP+8;eM?IgkhV0~OhCMo2Z0dt-jB|KGEBjg*kvUhz*{xkTwif_HB1TUDKKWbS!^ z;xVFCp?rfTeXWL_Hy9}xu#A_M2?7%hElqstURcaMxiCvhD%af=RgN!lHCRGpOKg7s z8Hfz~s;Xr9ZbkI!FIRtoabVytTGi%wV2P%Lxfa*ZBf}igb3IgWkg5N#?s_4F*W(c3VTnb(;5!Ge-BdD1Tu(j0qaE9&t1 z9~Hqey!{dLQy=?g&1rtRX>LEsGo>5*zsbM^{sw2)wJ|A<EUZ3zM@^=sFv5%!jJ85}^6|BpZ%xZL4o_t@se|k3C!Rs3qe#T9er%n>qi~aA~4^a(v#`Pba>^8h#W= zH&Dvhk$vi5&YSF7Zc^I`IJ%t!&QqW-?n3_N$C6Tx2R@RX1sgW<3qwB)x;?m?nK(w{ z7Ty&KSyZq|($x{)^@Wh42D@;Q@|WH2L1<&8?_NN#@fd*s0%0cl(B{oh*$|=e$PjbG z(`j8pI*0fVVh$TGKVL zTu>dyiZ+tE2B=z%MY7b+rUT7oOxug3c}?FZU&wwbrh(#S6(xmHoSCM&KE*Scb}E%BpN|7Ev= zg+`vkRX{`sroz88+TCRfIbU8i_(*=T9X4t}oNJlic12iNU-ZlhIIo($U%os&z*U-B zIX9=t9Q*tS%NgusF*r2CnhE~4+6S2hos`87k~6( zGJ*qC^KN%7u^H-V9nshjVtx=8R3`ah)zyc3brr2A6@4zNZ_Vd^>iTL=_)auTW~W`f zgbf~GI6dg{@G`OI1r6D%UQ|i9MC;{sfu=VAN_3>Mf=JC+#Hc%e>F>wU^bw|SM#U}V zXV)?}L;bI~t^)vypX)g{z5WOe0|7*Q*fBlV?>q7+HJXFE_v7T1h@0zfhbf~G02+rl zoR3%59eZai=ZXUHv+ni^5HSx94weDIFvtP*m;c`TG8?;a`7MznGd1S?d6Gd;EA{AL z52Jt4&)}8+p^8)0?7YB3&IFF>YQh(L#D!To4Qxn{BEeF2*@HIzC(;t4efNO4+mQ zj+j)SkQ8kBT=3LUyIY+~`)nzjAAf98IOJPF6O6jpGuf&v;0ie!*&AL-iz&7V#^TCqB7V>(U zcatlz#G9}l2%ysr)a0Y&=+q1o`+QREi;!wRmoX7A)KU5N`MQ3c*w8Ma=J&xtAi*@d zs=73E$@-%eW`d7*tH71@n)fmpsLAhKG~4t|E`JP$;+Vmg4eErnJPCilfXH=CkE;rVT zDL?^;(&CS?gs+S{L0nYWd4-@F)$-U7hUXmuy1GndDax++8tc)`k4%qU2B-$2s5Kyb)$%@gd*R*dNtW41uxGp)6ajH-_Bi3!%~T_;xwbkWXLG zLyqfoT-x`_Q+BENtF{^0MaV<{Bg`DdGB!ABynT~oge z>4xAuV`SU-%kjvmT)8dr5_jQP;i5A-165%k_T*ockQKOD7J!GT_F4K*e+O!5Gz~$C zL}9CUJ#**GD+foH%OS;*JRbl9I8=;W#H0m_&bv$C!(s6b?@GerTE zvkaBH4tayHkuJ0`Rfn1)>^Kf2mTc_o<-pDZi6!iALFfuse{^>0YGa7yPe^U!(*WO8 z-O&ZO6s8&Aavrs_27?Ua|6WrW8EIeC3mJ{itfq%d**0CJxtFt?SA`T)-AC=EIFenS zw-k>?(|SGu%Jy|`AncMkwew&HiF0*x2u9rht)jAslLCn?z>)3*{Q9s=g)&^N|1r`& z-_^wiNLH=g`58w+?yz+I^O^Z(#S6eP7m}utr0d7Tt&A_9jB`$m$^_s6RE4DDQ@lhV zcoIV84zwMhE~-=>J@GSXAdfovHXjIj2SXXyy>SzYfC_N(_AZ-^f+*)%{)!M8#Q*;P zcS%%uHVwHCj6K#4=#tgWp3#J>Ta<$Let1(i#K9CWUvVGMK`xk6`MH%NGwxb3Y&Hk9 z^1f53)uoQ1Bfo6E`>MxteVsdTnATdmgegkEqBSOqsM=mmy{{YK#Ieu919ep%9|^Ec z%s%_}-y$ToXnXsSWv!n9P=l{kg`L?7RHCDPT!I_l+WJ(#vyk5_(W&6Od>+VOQgqD< z*_;G;rtZ-IGcICsHgI>T5}-$$E|Y_0U9h_yS5aBH(ZsF{mqYD~TPZbIvPZV$j^oXA zPsV3{Hn80I`?uiiTa8@Yr(szXj6QD5UuN3U^}sLRgC=viP|JiepuG2gLax>$r?}p; zIgCz|uWSc0J#PXvVTRJjO->&^&rBL0!`%e+Z{RMx=r+S36Dp;FaA!i(2Q6tKOME&ZK0l%O268GsZO`@lbNfqUlGE5Wp6)R&zY&mf(PTnX-d)IED z7tju++7GOupsxu#X*z;{Cm*e5z?oRw9dzr))yIL{765Q_OQV%pRE~vi)J|VDsp`-C z&S4lwnrW+KnTyefvD|zb2q$@A7GCFs8B|>^$~cuOzVcjQf{xr9zwsL6b1&xpNJ4gP zq>N1Tq%W{z(#XIf!8GFc?>f%(h>YmX6s*NcH&>&d(A`Rcqg(ks?UNcc74@wzdGfH!Tk8sf=Zl+{v!J@hI#MPAi250?!6( zM1I!b8{K{_>Ls7%}t^#j-3+ z(c(c62+nFhATwjMvhqx+fJ6p2R+RxentS(((m~hR_fm3y!-8#KSxik$%j)VZ7Zf+~ zGWk9YAtT0qO*tO!cf^`yLRH3JMa0n+b^h)Id3|;n<8@)jN9WL;L#ualEn7q|qvlOKDwj&0h#{5m{bWSBTLA zr`a+u8>ogrBxhE1r>7WPD#=5E%+W!4;ILbT^vfpVEfAtNF&A_0i* z0VjwwpGMNGsi}#|1Un=qc3VEWeRgK1Z8KDX*szgmF0X<$@~;I1jX41Ik;-v&XE(~u z_O}BZg`wTUEI*SIF{e%Z6s7T_-_L%^{P%r@+cuU7wC{jc0;m^2I#;PlzfK0qG6^b5 zd#L=}Y{*GN@`Out&gul;NBc#-UX=*Cm+T`t(@mOV0_(cBgU-IymrUpv$L_rcR^4_$ zno_&!rfovi8*hh-{-O{<3cPKCiuMaw`=dEu6W`%re>+a64_MSekR`ilS#2zvTxxc( zh<5+ORB1*D3JH~0RpkOu%VbXd7-jSE9f(%VnfChT%YbPFwW@`-LT|8pYcD~fDbY&t z*2}K*aj$?l0+451Ni1_#g{Vo1<7_L7tWS@#-l_S=I#!5^C4w%f`tYjgN&EmW%Wk0I zg#~5*NbGmXm4yxI^~)P|gfPLbBcpt5i3Nd9_(T!2Wq`KkfH&{`Uw+&>Q^eZAK^+_l zU?YpmK->uETA%_9BJIJ_e{fPt;9}LOMjFd%Z%u&2-TiJPQnZmd(RaB))D9PGDwEfh z7uTlSvs9357;1D6XKR~e$ZTe5!l^$FpW25*d|eB?-;ZlFOm;Ms$N5i2I)r|)`Gt9R zxysu|jWfe}3A4CZF311uM&ORi=i-%ri?eRiM--*I&2)`*^)26I8K9pv5u^qdS^I>{ z0o1Cf69H)@wRC+Az>~n$Z9rU@3UrAnDZDpt-i+l4fk}TbOt1pSJf1sJA{187CFoLWk-$up>UdFA_^tHO2WOHP~_wy-%ax00+ zX&>D|;(5NKr9g@I=mHZd#T7_7{DFeFYxoH@$>#LaJS^)R;* zFDj3ILBopsADws06WiQPS6?iy!n>a#t&fzRb&V!Xb9LteEYEwXrr!4!CD@gGD$`5} z%ejRG>Y1#?he!YZcI9*x@I7u1v}(eDTN4#LaeQmIZRih6m$&~W@A5-`%=ltCz%Y#o z|6v%yvgJ)Zy?_VTaH*VA*RN%99z?GXdgZY#k$fPbl6-tCKxReH1;@5yWzCf-r*NBy zjEvstLiYOaUc!Xx+&3Igu)Z``e~Gu>xALp^f#xoC?5I9ZpyPVQMDTZBy75O`$4@?W zXDt zDLS|1zunT}_Zm^Y;6(m_hGUCl7GrnjoIkXa9!fL#G;HPuNR6_woj^Ww%-_1KXNA$~ zs`Q)oll)91Fh8>yZNzx1DBsK6*OAv>6mUf>ddeWXY!;3Exydi8Vb>MBkufY2$w z0su((o5iz#eJK!Bw$$AMWRw7y>uqb(Qk^C(9oowhSD14g`4C!v?9=YzWbpS`I-n6n zbXow#q&CPJ3xAC714RNs0d+r)dICQo)wrhe@4ypWhyqjnA`Q#6&r3$C=b|VJUjL@K;v#?Q_6`zV%#>-qoHa zvsNf_a}nN^8vGvhzz*O-$N}RuzIwBrDWdt%tvh!vScDGGS?kPeuZg|Y0LV0s-o3M{ zD?pwP%}4PcBj0%Ul>PAI zNJuDw0zugvGHAoZd4%*IiZQd5AF>)gy3#I=Ept~w6jRhqW#L|HbN}zp8B{EJlcoQ^ zny3lfeOz_MJf5z`??G@I(xl$A|ETAYF|5YPqoHI_6Jp7_n9qov2x*h!3LMIpJ~n z+r(sNdr!A<5kb}4#e60wJJ+wy>r}wi(N`b;k6Z%kAUL=M`C*VQJHbXunV(Zi(*wVJ zQF1}AsGTBK2j=US9r|bVl*+U&?O#4~5RZ{kzs=!Rn@X5aKJ=5ZL)IEacWIF$hmQwY zrRf20y~qawIo@r<)t>JgGDala3}F|<)L9^UfzK|;ZnQiJk#iiW2jz$7kMsh~7pFc1b+@XtJe6i|L*%-nywAE@WRsetq8=H|WdHfh9`ItBvg2)wnt*UYOYjp)tI z%@`fQ*sfWNdRfP>5l7FEetzm8wc=x;>wIhLmi)Lc01A-i=i%!}3PzS8=w zW=AW+hMzGBmrO!}LO}RuF~DymTuaxtB&7Zyvfcz9%KiQSzsFi4ZAui?Q9|N`>_$f` zvM;5wwAi=GzRi>qr#ez32_eZ&$x_5{R6>~SSsE>}Wgpv&x$pmV&p4mo=kxua$9eQP zC*z)bdEf8%^}epx>v;u_Kdz9q_w+P^0_vr374Z{1uZFnae!sjs_5`T9pibpC@b3ok zAh>pMEdr!*@ik%hhMOD1NzzkLd%~F@cv^d+PaV&&Jh(JMLB}W%>)IG0Ny^J!cQ@H( zW^*LHJ*>X7*;QTF0#p|TU3UFwJ0h$zYt@LcU|auKI~Tuq0PcW)KyD^%AeYPa44&@N z%;1Ha2QopeqW0u9R-3aOBSu_j@cI-U(TZw;%b z#0}r^|MSmvD7)>2EIU9(Mj?}R0QU(OD{I)qXim$b{rJ#w)0v%ci<9FgDpi8|W}&I4q+uY)%f}Y){fC3Trg_ zt~K=ao&79Z1Tg_52P|MX!iy7xF24qS)Ros~4Z1Eqde??|6$;l)5mR;^`QsUAuyA+2 ze|^%t)~U~3tMuNv{%O>*PSIldO?p9>cg;wsR%S5p#S3f^1m^FbW^4CzD z^u*z6_>Vu*?s7utQO`BrKe<9UDejEV;-wx7p&5cJPq(kK8630_A6h|Nuagq*@(8de zV5n__hv^GUjHZ^BF?iS+)q4}0MqzSh0F~t#yk=0Xc#(mU{1wjzGH8>BPVV+k{PQXo zs$dsw5W~@I2bNbAj;dsJd;ZSWAo{!CCR;4$)#*KhI)6Dt29yx(0&q6fO7Rc~Lk1H~I>mEcUN8nP+G(X{BvL0@m@`kB4! z2a*`a&Zf-a{03?6OBtBZ0$N7(Gb=x6y@bI6ojHg}YdgL4AQ%PTnVk(k?`_M@LtNnG z+3X%kP2At0DS~h|PXPWgk@?^)yfYXiAe?P#f2+)o6QKj)ehj-Pj&YCgKcNQFA^tTdJP`_A~OpfAIREgRAaqk4v_BLS8zrv2YCgFZHN%_`#CztiAI&~(teXf zaz$mexAsERi2caRJAWD`Jkv^;vv1u080~dkj2b<>M3T=e;ngCcXMv>xjwEvs@j`mc zQur+FZD6+@Mj`E}l3NKXF30bLWLW9Gzx-47Yh-pz3}DPjN*5?^ic3m-^Q>Rr+xWRb zXVHpT&AeHGdrJS0OwY#F*rm~Tm)$Q9Vi0Nkdnj`v^-RRYEYSc+R)a+Nk$TT_Z;tdq zOkCxX1dBzcwS)EXy2qIHv6RTGLLlMHyWV!e?(+5y+r+WJ7M|NJ>u-kzdJeTyW?p(8 z{7c>g>24gk`fS=mz^J1U>M=dGsGUJcDdOZY07Wy%2I0kJsD3&t=fM1kuN!!3x?!%A zoAYi&C7GQE!^`GZ72GdkuVb;D{Ey!|9f#!i5r5Feh7N?j4~%LKK9$3#Ci{u+Bc1y%a0cla~g1)(#_?<^Y3)~0&lPJ3)I~o$KS65OP|8E1-7SZ(QK#5^m2@= zZFnf%DMjf}f8MJ*qlKBvfkL%=3yrd7`tqF}xpjB5^#eh>9u^q#BoRrr5R3Bj^MiC2 zGI%hjWXvZWTB_oNZROPo2Ob+`0)q(8D#0ZLZCExK48?9=1>JA0IRhTkj=s=clRV$- zG>``FE7`k-_s=8kf^Yg;0((@pv0OUFve5HJVP9NZ`eQb$BCiUw#K-YFXs$4NHKD0(2!{IR$K3PU&1AIv+ZjF59c{v_ba` zUA2+>O0tBHwN6+iY3RpTR?BlzLH-pR5x&p%6b)E%QX?%MGl*f!rwj}X@JbUfU0~lG zEwp?!tiU#-3X`ktU7-DCGkL6%@Y;G(I%SQWUiwWR4Jn31A3- zYYlERW+kWOTWi-4rF)#~KfUKpN&7ZcyP1#hB$%^l^PqlAB@PXV9h!B@LXgB1mX1ifdKNwspNz>uX z8k^yfOfI{puR=e$K&0T~Iw|!53Jf3$hd>y3Up$COI_(J>rX>m zm@e!OzeeP2eDI?8t5;dDpx#A>xj1JKUVeF$C~*Kc!>xF;k6b6w?==V@L(CfO-qV~@ z(C}rn+cC^$DDWoW!3pS^fvgb~3CFerS8nLar+gUgl)N9Lg6>I*+7>IRiw(++PS4@; ze!IhmF#i6gtDF6T`A7)q=j3|SZg})+Xlb?MI4mnGjVq&e#`ToLQ_;;b1zgI}Rs_fU zhNm;1A$w;hRdpW0NyWPfxWMdKE;>X@zC6z?+^n zU6-~Yb>(qdw#zQrLAVXy0#y}lp=Ft+V}){7$Re-~3{|dfIl!MWPeN zJJZ#;tM7^dbCo8yu!jr<4J(45D0_w*IQ}vmeWNxR0sA6E7F4o+p)E~F;RPvj~E?@Vpgow^|O3~DpM@5R3b1u!*6Uw`j4Wx+l2<>vbp#A%ANM8{9VgJ& za}MO(!C>K>Aoz`vj2|iHB*6nI#sDW^K=z>Jdt?u>_@amyX>f=69@C#)@pE&BMBt0 z9k|?!TxGd+nS`+x9xpH}4A3n@fQ$O}=Vth#mA5{1(#N&it|SIyqYL1u!$kHordmJR zI^WeCLjuMw>pBlUZ845YN3cw1gzZh(mMvYo;kVC;`Y1t=!xb40OctGo(L+AOc@4Dl z`)i21F(iUx+o$Ip4JW~;Q#nkS;SN)t^J3xt@w2oEh_A8v`lTJkAR2<>ule$1;UW!<-)(J3CF;9UQ^3 zex(dZ4r{@#1ek@V_B}f;wF|gA3kBhvBaiiLUGCBxN!h{UOaW0Jd;pez&}c(7%+s#b zgl&x?7r6RQwLB$Ni$|6ASsV~dcjZMiBK>h}>$$d@11Tpka+&*Q+3pw*1J_;B)q>=S zm0ue^#r`!gN30uF3Gc zNZR@;jwvZ(O%0Js0dP^LDX(tYhydcl8KFLc@b^PNBwFKlc{9S`5Ep!SYKV$SixYDk z{kXFxuy5)wu0pTvtec{&ymqC4@>=1W0cz>^lrTNvXjQzl1FyY5=b@ef6FCTR!H)wK zT9?4U1h{?XrN7Q&6nPa5E>QE!ZMX@J4X6gg_GWhbxFY)%a~98>B;Gsj?CWa@=_Wuz z@nE`=vYyD^Z63&TF$sbw8@Ge&(%=>Y!0}Gw+tr*WAm68l0r9G&xcDi2Cx~OOlTw96 z{^y2dVNOD|SvCZ6GbcmRVrjGtDxH<+I6p*(^lP&7Hk{|<^SoqV3xbKW>*^g!NcnB{ zsMYdqEvFdnG2cA3ahW^xN7e$xev1>KJ-x?2=H$O`)MFQ)e!EJzQ|Pe)8fVfUNbt*J z{b z1AdjW;@fWlk_ zM_6~ExQL+pWSL^kc{gg`OfVJ18U9XxKv7FfIN{14VQ|xfZTgXFf$A?D6|B&7`6T6W z8VM=Sj1xjO$RWY2+0#*blMHL2Xfh>@r0eB&i5r0*a0Va#0}^ZmokB4|7I%>ONbs*3 zJ_N|weCz>|WpHT(11*sD2-7atmA;Hqn(8_>dw(>dK^fvUvo1|2_g&VnFgez=}a~x>H3;?F#%Ip(>vQ zM+UG{_&K-Ca-xQWryxMM0TrhnD~51tS%3;cU5%cY@#TP~Ei79Gh*l^eyl%->lN+%X zMbs48BVyoT5I@!t9!Jt8fn;(X_c)A6BEzVT67rmLCe^>&u0<~lN>WMsgII++qotdiJzVc$()SyYjpQ+GTXap*W%=Q_V6%yAIhLLuup+i zx8%7+4hTR5a#TFlhS3r^L-XmCalno(x6(PEYAp3Q&08U(MtX>C$3}?MmPe$Qn9@2 zI0tCZ7k(y!k9YFU!NCz?I7UW)=&*=t#kjoy)b>8!&Za1loK*)O5jC@Yj0!gnP#pPw z(+^+Jv7dscg~NRORHbw8w2@RBFeZ1(Dj-pEN&R}8eH`xAzH^Yv&z~rzcps)hz_H9D?joBvCR^W68CgPWl z=jS2TjgAr2^}1?>d8j;Rw1iU3P#SR&M;S&4!cEB*L>GVz@WyDw7<4jV1nf0?ZXvOM z>j9rV4?oQ=I{dzvA~+nz4Vpi~u$0rB-JALjQfvGSW)Q#M6s3LV-2U}OnD`J62F^V? zk+l4D1z6BIJ&*0;XjKe!YN@o1TUo3>FIIPF$;2K;G=800!g3kb*z2uqO%7~vaetDd zW5f(5!FD~{|Mi2TlLg2zB+t|{vCQX|`H2Y=R5^E% zuG3XeJOc{p_H8yow6AakPLLNtR$BJDa6u2h$etdc(|Rmkju@d+%xzBataDE@t&70& zGx33Z`zuM0y^>Y0^R~jYAt?m69TL?SPA?HNv3_ggUG}hMP2ZKFed;}_0v-cFtoQsP z&E)Gwi2p^s=kn0pI+Mq!c#Okw$R=FO>ikAj=zz>F$0ty(#MxA3^XXm?Mfuqa26yxA z4pMCp!|OO8#8g19He_~U2Qe=z1!&6W_3QX=m!qLyE>iKK2*js}b zl*{c%tdjFDMBz+UvF8uM&v&Cl_GY7;iUQTEF{q=QEJQV-4(Z4-`R`;#hLuQF{|8p~)A=u(7k`%r zlu8Y`kc_zqVH%{S>gjk!7}VvLyXo0@xU#bNJ^pB^sc$1yHc+(NYivm z)fbW~xXJ`>D66Vw;>yC0A5BnTyTN!y1hd*Au#VcTs6UWwz)Z8-e40Sx1H=skNGhUDxVSM|TS#8x~;$*U=k zB)4s*J4)xKoU@di*m)No_mSH-i^jIxv9_mQcg(~paQr)nNI0xY^SztCg^en)S1`W2 z@G@S#8vB(bahYqo|E__?;Pdx4aPjtb7CsAyEcw2Y)$YEjvZ;By2P|{wJW>R)AvEmN z1N_UdvCC%Il7WpEQDgN31ybGJG^Luq@yTf=w@!Mqq4n^qhst9=gD2iRaD0Y!iJ|`B zgo(iBWOROqWsU$$Y!NUN;)?X?fFwADoDf#rYQpT^t%^TgH)dIhPzw%|+cv->&Y{!p z@i-gRJb-#GAbW6|Gtg4*H}zWTDB;sNsEMIcAvN;H+rq^3XUp0#YI5CvBRYBh3<|uU zeC&iOnecr-M(gX-vO-&?h+eP5Q*AuB;w%Z#wxz1;fidk{`V@djkbq~D0fc4tckAC4 zv6+S02gUyP6$8Mie>;|N6nwGZzRTl$2cV|{?>Yjbtf<{Zmd`EEigXVOlA-z~ zh>33txdJZ(_uJbuqzJ5}?&eK$YWB!+VD9NeMKkETzIv$WYM($tKHbh-jG8H0srfwk zO5!H-!0%Nf(@&ODzLLf*Ro2_<$2u9}u7MHfRQV3%(g`Ge@eP=B7T)HR+kWS1A}X&_ zUXX=Tz3}2;70Pgfoi7Xtb zzP?0TF}pm(S<87s#P$K!(%fu@5|KqZoDARLT>O&8*48SH=I{joa;oya>IuZDjPrw6;FisRy`23oJv<@b&$< zg1p-f-^bF~?jAB>pq>sl%lBNqE4jkD_KMCrg%|_|kd7(&>@}FA%L{B&bd}vlC*r(ECIjyA*zX;%zuJIV@5Lfl&f_i{9y|Bz^UKZ#tPmCl z>sPsio@D%!1Ktw}R{UGxS|75XIb9w0+d#xM+yieC{F%5Pi?)O_tk8(#QFGZlpy=|{ z^;y^FQhC5#-FR;Y&pQ0J@p`aVA`r>I#ur*66b(=$?qdt3MpA@6Jwn~FP(7Lelw>@S z=NUR@xu!BOl0s(7*4(f0x=YvqdoxTO%1K65uY4Q2kI~YXDNZGT85ZPSzWiIp^rv(y zGH6J4_VIjjo$6bYgkqA9eqq8qTpSO~=0S{`jW*Uzx!Q@Tv#{4^3+PUBQe2R2cy`{j z0Si7|0VokGGGG)S>^8Z$Di?XQ`mx;B13#3cYVT?+-I#fT(G&%jSYa!zEq1Mkuz6Jq zOlG>0njS1WZNb{RBe8~(nP_D}{|Tfq2KYVn;Y<2BqwL_HmPr2E7P*pkoCl>`5o6+( zf!WEHBH)pSi0L{;sLg~0lv<~C2D4tDcX!qBIh9z%@Am-KS4;gAv!=L$UQkHMSB9v* zwM33pV!Rb(44PC$HzUx3<$u6LW z>Hiu8!+?yJ%0jo*HCeKiPesPFj?H{dtdurPaurX{)wE%Oss?OK_DIUI%hlzVmNReIiA+?N~+x&mR zu3Lphnke83s7Q?Mc)LR@I(_j`llC4< zVB&Y6q)tpohyA98HjH4v5xKyUlnU$>&=t|eTr#i}IAeCirYotDk5MGxB({w^^NNve<`~8o{c>w{zrb@+K(WXG)vW5~#$|`TRWJ|> zkm8JIelmWhxhxERJ%k&bgQ!IG?8E>N6Mp#zTdVgp_6rQ~Ojr<-3KAq3wqGqVY8R*7sJ>wZO*+& zi{(Q)GYl#kK7~!>BW#C9sz9o3{yeqIHQz;=fqh!Vxe@PU31mwnnURIU<$i$4r7wC%jNt)Pk*O!BPn1+PX1W^5EP|tYZ&So=&eSQ>&=nzTC!K*`(5UHWmR~`QmA-T4Ezo z{q@rwSu&&z!G8qlX^S0GldB;KH|1pz^&Z2|i5)R8{s!*@)&>pq)+%HQ44@^Qj>Jvw zXCOTJR?!rfSbIhgIn3Fm(-Ul9Hz&mnNr{j?O9Ut`O@@3RVFvM^Oresu=aPsAQb{I| zop~rT_+vVrD~`Zt`$8hpKo$I={wEP@y{Y7ZXkWuW!+D>swDOUIL?d>#S?}Y|Z1E3J zODQoYTq%4fur5=`KKF?bS(d!t9@!zrPE4g57nc)KtuP`sEGc2zMBZCM$Ybv;a_)uWegf;@0Ft-Uu0(`r4&~Pc<%~ z+z33ioDfm_v4v}vcVU((exsvSi=0{gtRfAvS8%_KIQQ$goH%mvc*ITsb?#V}w6V3k zu2wVDNfzXG_f57{g)CXM!=qJiMFofoF^ z_mmKj+6V54?QVEGAJwZHAs?O2g@!Px zEzn#ff9AkW<>MYm{^-R-A#sE%$Qk%gtOi>65aou(2Y0WzayuW&>~()5YV$#m{FPlY zNHtbIgW9cORn;~%wz>8o8Z^i69n?P#B7$2uzn|J6LUu>U>Dy~0JdktFFI~<%@4TkN zdHb$eSwYea89ypcW)w6<#A09B?VD2TO3JzJ3L(QhJ;FaK`^QF>6aih zkVxI=%sniq@TJ9790^iCO_*eFtA>AT%0qsYwO*u4!+A75IQI)H%Q)I7&rx~*2b|P% zC2Clk^UzMc%)FK~pSB&2_P1HlCH4xKw(wc;?;H_CbS?WcNWk@j3%@b2h9hAs7a`KaFysY|o&a_+{P|5R|G-UA>9PrD6_Qx)9P4j$Z7Ir}IZ_p&5y z+2<7W(4*H<4p6}*MMo!;YrFXd-q}|fIl#E(EZqDy2?YBOcU$fX>TQS&GjVhKG5Y)8 z9>{o@@ouj#6jwPUn@?1Na|aG9B_e`2r~2I!0#vx(Vt3oow$ZO1+|G8EH>_JW{-5Of z1GmFoobSjSJ;C>%N-h+>xbISsDDe`PJuoHjWT5HlzJ4mV(f{@O;?St@*|Ydw}%RE9a7iN#(T~PFYZt%Lw^W-@0t{QEWzlMx|IXJNUprgGgd(P8I~eH`L(F%X3jH6x^x=Yl12M+d*iR`bk)z0juD#(2p=1?PnLit zNB@b|AaV`FXY z;!>|)hX9hgwI4E;H-`8)>~^w5ogkvzsLt{?`dU`*BVd;+WG_k`CENaiS4C5Wp?_Zf zbAeV6H9zR8*hpUJ)u?{<8Olh!XNt0~>I!o%Fp_V-_w}K^Obil$xMY?MR?IK>^BL>; zS`%nt5(6VhrAq8>6#wwQz~i4uC^0AjKW^UsINE}qw>zFh5dlK%o?$mN-hpC`WyL@9 z*A5G_ZxU?A-i=TkM13)1ZHB}4)c;tGPqi!9g?}>3x8hIbR1Ofnzcf=z^L`p(ZoG4I zd`!zigG$QU=PN3JL}#wO^XQg4j)c1e-9q+UhX|%#mj@TEt(46eOI1)0)Ug1i0ILM( zKxUY%I@Bn%tDQN92ys*b7JSIC1KNh+UGf+rH6Oh%$D@;(@~l_)TJf;|Wqlio1Ek@k zpjVdq+<|&f}hZ>t6&886IL-NH1Yl!piuvNcmaaAa^wZKJxu=}aw<9hr|vXc!CTcVP zaz{i%;>@uWNJo=&mLQRwD7ie8gtjy_jezYGx8LC6xmOEJ7Kn^smji#oC=-%?0K?k; zWy6_md}AeP7-wlXWVD3Q(0Nsu#R2jd5%yRJ2`?;~q$M!0i@$-IeKs5eE%39PmsWu{HW{YuUn2@KqZoXxtuEGFYG)foET*e?71@c6u zpx*cNXXj(#qNPebB-cP9{#`3(MkB?VWBqQJgjPUmh5sb(PPQ~&qLP%hcX93{S$B{CagFnBZZM2=V5q@6}(A>|RAwV8NzG!e}L z(J=H1jFTvQ%}Ed`Yu`WA8u<0I4G>!6IjUz1hH5BvDE z1Bx##ljtdiXM&0@7ms@VmT|Es=2BpnqbD9tg059-ZnD#czx%k!>8b+?S;t?ga!ow8 zO$&5Cdgyyf6=#ilv|aRC)saKMSl5k*8hmZ79?&Fl*eBG~Zyx>wEa7h^6KAk%)`7Ba z1`S)DKCSqHop|ws1g4QUku?;Hyg%yMy(xYBy=?Qj^OCr!`LQE@Va9KQPUe5y3%Yku z=>OYfr|7HHZwzs^O8MLm9^8^_V{7XPeM2A@ENRJ1@(^kKCJei4Fb=VMi5ZRzYI^CT zx#z++idF^A9)K2VvlU^+CjuU?2kd^vN`4rKPBDqhLnybF}|AQqM)KxbnZ^yIZy;+LU?A$|j(kc0CD zz`_6xzic7-%xO~v;^p^8nb;;@6ASTSYx&`50NMkoM>Y~P%$ge(D+=3A>m?ZO!8U=HhjZsnE(mAlEgOm{HfT6Cv{0wpS-8z`tF^K_Y$HT*8WNPYpP+$Oe z2KL{XnNW4NACeROrt0;SE2%U9CY;gUM7RDT{r~qR`ew`8gW4XHw$?E3%*+&hc@vlp zogVsBvdTIM4~%^AhD;Q`^tvuaGo2ncSFGH4=X4KgA4cW z#i_q9R+Bl~#G{#W%rdd%3Ih!K*@>)9n3c-nGyNsOw>`t(J^C~>((*3Mx{S7$+_(cbSS8Q- zmDcJVD(E@i4VxAo9XGKs;A+>OT3-AfeMxBtYyf?iW-fs(_1>ysbM{EmvKnj0V7`@K zU}`1}U=z4<2A8hvWlgFWO)Yqldb_aMW!+$~mvtmwBdN>*9(GI(yd4LbdHQedt$6h<-HE%+C(4-u=dX#&DQHC_Wuf)KOp|4uKYsV;mJKU|E^SX$a-rQ;N6cObT?D$> z^q9qT)rU>Ec@%Uw@AaC>cox|!I<$CX1V5P`%T=xU{+RFrUO7+$LX;K1fq>g^q4p*s z$ajK^PGHZ95-yGnl-a9uIns+ml3)A5BMChiv^l~3BloCDb=$nu+@*TAk30t+qVz;o2~4no;osEi85(>7AF<{Wy~{@a*vh8X9Q!hWFRI@MPe;Vap zCG=etc(3>Fsy=k z#<1kA(=zdyys5U8uhvp!UQ$3MP*(B!K`ye*wuyIdK6mn(u~~;hlQHU*A2vhn?C}?W zC=*S%k{c}VN)duKvS%tjOLiC7${`lIp@u}s(Ng)cFxscxOzcGRwEwK4ty2e^bt4;ixRB{MVzOG$KopL%n4~!p4m0`bsqtuVjDUQZ0 zj#)^>;QH?CnC;M9_KS@G_#C}f)dKhkz#l_DNHMkPAE#s=Yt=1Wu?dWmjq6>|Kakqh zgFLiSZq4)w*6C_+yYj#N zI8O<8a}ugaPuglx&;&qU{zZ;njTD^J&kj(5-=}%=vehe!8%vWMd$F8q(PlaDT={f zpQm8o`ld_lVGI#3r-+f7H(3{3YTnG>H&VE7NHz3b8!OnlHY1r{#}%6X?XuA&4nZo% zzL(MAV?xo;=X(QT;7Zw)tyTz8AqU5Og9!%S^QF-3ReuRgBy5X$n%?GHNc*iZ=HJOa znlb9hd)MON#vPot8jgF8Uz;VD{6BGf?yu$?cGk3*L zJ;(rsM;&H5-hL|PeNNI_eGRKtyVK2Hj0WR{& zhw_P;KJ(N{)|k)mv5f5`V94P)qV4Y;u1LRNr+OqR4M*^JY;-u%D;`Qw4GSL{Z>{#1 z(@kH!4gk&iGivo@Xk}!T#?bmJy!Km)%8X54*Uyh9Pe^URQOBHJQKre>!y>v{*jrg| z7spo6S!Y?aocJ|lcv*Jf#TS-F!%}6r0>HMC#wxe6(dGMwW7Fp8Z&Kc#0D;FaDP+yQ`Yj2ay=~z;KrfKug?kgrXEu z&X%rM-!n2~z`Y1a^4oC6m#=ztbcbhL*BP-r{w3Z2*c&kLf}Pe`mjJO`Y5*}rvm+?F z$5hDMO#E!V6+q55~ZhD*3nbQ*zcw2}5KK)v&gLo=Q?Ia^(vAS3 z>iWVo`q_!DZ|1+RU#IN5(`;WCDgNWwQd&kx+KVCYo*XE{0DY;L;Bz8A-UY&VAL|ka z5^1T?j{dVre0*{edOVkGTDE>*hB@G_p9qz}X92fPOhwxcR!N?mZPc%2_qTW>sAoK6 z8)Yq@>Z!bQNTgP=;Y+5ON;N$TjZVCfanVk0(z>S9pmHfi=|=17H(iCVXG+v46;F=U zOFFGRR9RRX8v6RI5u~F)&IREkq@y0&YK|U*q8=h@Gya%v=S3l2BL-OxvcE1=W1q8| z>KU=MU8{}cs$;vd&m*qK{pG3*`hUq4suRCv`96tT$i=xCOX&y6?;{8Y(~I8KC})6N zqo1<5^Y+`c`NV+j9|@ecZq+8P%8Qva$=YU+7wk-N#BrLgYKNG*Y@V zW#`riBil37J#`=i$O)qaWr|fNE;NogkfUb4`GNtm#7ZcHt&|iLaq6%;b{%_n^MdsK zwV;GnhhnY#$PV)?8;9@c#5{9h{HX(ZT%YR|jR?q((u=*W&V@TKp_T0Je4?`d<9yeY zSe}h`pvPXI-Q2@{s8Ia`8D#zUyBp&i-TS~*yz577i{g*jIBT9)C7Sm8S^g4LcFl^_ z5YwH*WCPqcUjNZFmJ_m__YC9yerGo*btEu45sk&rF1G21oaVsJ-T>1C*UJwMUNXK; z(tCI4^gWXoLzu9CklbSCug&>ImPv0@3{|$QD%GobpaZwEWrbBS4Bl%P`H<}qxy|t1 zGc0FR7H?#@Dxlu#vbSALsdgwufY-%Mp%8Bi24b=b6&uMnW{i(*?_6)=f7J=?bN28P ztvt8t`m?k0dNm_VW2p`JqyR3;4L1)r){qKMGKeER$<=TDP;L``9IPl1RFNn*QHu43 z8C**(>)JCY@3L_9g_u2zBtaD3L+B`pcTJN{UR}O{%VV4Ez#Hr7%8-%bFS!eim8%cQ zma=7n-!4|qcKQBNBHB=1rFiPxV;AZmvqJx+@rjMMwI6sLi2~%^?LQu0d48-?afA{y zayjt%u93B&Y{uJo>_7S~Jh>+8I2m zP}g5&(foaiq4BTOti6y@62I_^mE#`z3Z@Tc*BjEg5}nyUVio@RUt@&15Op_uOzP$) zEn=`K1A`$B@?Q!;yJ`8>WzwvaP4q3lzSmUE3Ntvy4;7YhprB;$19r!unT&Jul>y9d zS)<0Xf7`N|Olt<w!dS$zh1g}_GboV&3-s1T<+_bim#glwOng+@47xTsoQ0VuB9_s_%8#wZ*IJdhP&k9 zaOcW3KtA4}Y$I^|rvSo$a>mdS>kEy;AOkxmuzA3i+NWAW(!PYAsj%B~6<|7Zbd!Tf zZTgIVDlnaZr3`S$|H{VZ5q=e=86p-au?s?nv-|zsH%z%e@*B#^m-dBLv!xbnOKMlE zf`pD+>O#`yw*za+^=0;;{>uf!$omdOQlaDr)PYugFY8caXX#w2kqy1V{A z&CcH)_c!7SQ4V$h9-h|ee2IHdv(wMePg(lc?F{gJfF7{X*r{JzZdD`0 zLPn_oqs)hz#O~Po9O!ULYMEtLQeHDrY_X2$3gZNT3w0AwN4r@6kFIe1L&X5a^)+QT zl&hel&_ho2n56dUag7Qp$ z`;yqSpbd!8jzz$C;5kk_?ayK^KyI;?xS?VnR5hRn1QA<)iL<%zWE)gCdiwh?9sp z+i>Rs){ZjtA#=V?jQ0yuwwxmo045D+_ylw_hA^nCeS|OLHsTlNSdy!iCjSx zsOXp_EsQBYZ5q9Gn1_7nG-Q#&@eb#sG>k>V9n#S2;{t}b`|;r|Yw#UB(?+9McPQ9Vw+2J7)N) zmoiyZ07HTtG%(G80#gpz$1sdZi@%Oxq+k-(-WfL;NR!+tweP$j--YnMPa0+lUy*8g zan2)B$I#c(y2dI$nNEh)cy3G7-Jz)9#Nv<3SF<(uY@f__)rf7KZ8x<{q3dMPd; zAxW)!sxJ&)IgMAoCMqWBgYkBwiC$HglLkxN<}~bN`ZcnqeL0XP4V?;z-XIg|YgUe))x=K;Fe2w=}P-%s%c3l>AA1cnxim7<`f`e$F6%Np1e)dQxdKNMlTq`I_yD>_^9I2?d5L^0@{5as$1g*YSd!40G z7msSyLcf-OUx;xDnq0Eg5Bj(9@$;*wt7ij}7v8kQ-9%TIA!tT6xg$^nx5I`Ul9lc|MVQ3y1CE?**Jl^ZBu`# zbf1I4I@VRV-3jd#T1+Yc@K6FuNE)j7HeXI6@?o7Zq?esoeG9Yai+^DsC84YPBb?=> z@%@B?-K&P~h)-sBGN13ip(4_fVEEI*YoF52qp`p2Z@=rPG|PT9Pj+T4%tsy`8;F%f zNS~cB@P4=4C;46Z=*CO*q-i0_RtnwY^d8T!h`F;0@r|-^`X{|Mt|2|#(V6dyg$beK zyD`uFIWNbkg7%);P)*hqvZ8b5>Hzse>i!y`#!+7);r8s0Zv&X?fds*d3pY&maUq(j z66=~;ez)^xBKP52w@XUm?aO30-?lk>Hcy>NlVMg@%bevJ&{nwKZxyzsyyZR$WP?}V zeX-RixD$l?QH)ep2`POv&<>j&(bQi0oE(D%6*emWEQ%jH$n>T)`@PnsmQ)DAX{h=4 z1sFHI5f0Y1FOd5wRy((A+xe|Xz&i^9G+4ZZaBUY?DdL!-~_T`DXSvW6i5DL?o( zA|j&sK7JMeQ&ksUr{3vN4e(F%WckU%Wi8vwzL+ab*4iF<;yHon{QnUWu+=9n*Z zSYdg_;aeB@u*^p+mc}e?1hkLUF!wqK1e}7!6bu!32Lewh1>~G9i;E22k;BKw2lTAC z<8z4jcWsp*Nx{Y1=-i4%=xvNsL1FS3o*V1Z(9kd=k%-c_Ba?Kl7CK@CpXjXvr}!0t z^?64#bVvEGDF5V~sz;YPS+s;-T`69VyWYOLpZD5KI-FFN$Wl?7k_12~90%GfTI}8A zGv1>D49aZB*Pe0|{=Xgp+QdS3u;=Rebgg8 z?+d8WLS*4d*;nlg)y5w`4r^;`J9SRHzu_DD4QgognLz_CvgnJ0=$TWevR;2TXdFW) z&r*}4nJRZrG$fr&PO|nq$aM1^AOU;{xPkcOq^GCXk%8PF<7$2qV03s|yGEM_k$7Hk ztYv6cnVWvs1uX;R!n=1zDg$SKwukR{iLI*m{{6!C?c1R^V*B@?8XU*(up0`1JF$OMvGJ*lDzO=|ug#7!#w%7rNZ zfedVLgX=WGnfPsj)Zd~WVFU-qPIUz!Py-P+XlW(`Z(NX;hBx8bn{3qO-o0_qq&ivx zFyZGmBNO0Y#LF$EZugQOjb>X`S)~(il$6z-GHPO(}P{?F=w6|~K#_ncY$ZF{5SY=y`E~@XA z?Yay$W@KRfBSKL0Ptsop%unEjJG`m`-;9HMK-fKx9GBYAQG>!m%n4^5O(Tb%Q|!uM zbo-_<4WCy*gnRir(QO19uW#;T_3~q#zL=bsfvfM9{mjX-W=3>W)W}4C1@tnoggV!c zA5z>HS&17959fxbb`)Zt?H=k*1>a%x*Vfi<3r0M4BHrtp5SHF7@$k89i&k*W;%q|P zT7=IzarzyE$hm7?{{Geqc2#*gt2)>4!uyg9U6SxI%UJiBMr(Osr_w&Ej*w0}VVW+> zU0HOBh*3CJM=4;EW@fAWgd61Zm;A++&p5Hx+_;WAP61U3Vao4|Yt-7F1IpMOmMCkO z<(HS=K)h;vt}zi1GdU+s;M1Vzf`lV91jmZ8CGng8(M@(>HKOXqwk_!m)jX{nQ6#9=#=Q(}= zm#n^AQLV$Iz-@&`T4sPnnTKQ2l8?}mq7J+K7z|iqGCf>QwYT?7{tm%jr|XP>o~v8o?ytZ9lawbE5#KOaq@U565P4+G_kB)+$pAosKzW3B zfVuVViS3(!G=-`~kQW@~=H?DbkvCi_spLXXSI2qE)_REr11wnstx#V~0V3N_3aJ44 z@F z>SgS6n|qs`*-@Q(#%Als#HqK2`;={Nou3HBOJ7iOKEGb^-HGRv&pVGP>3Z>GFG;$E ze=X6^_$KP9&MI@%yT)RLvSu0;IwI?ERn=%mF3)`x@5lbpi7&CCmfdp|auW~GGny!I z#Cyui4j7VXXehcg1UNa~lLl_Dm7Yl5T66HdKse)9^L$3H~{&{Wgrzhody#8+3M_WtseXQN28o+aH%S((> z(V96s)F;OxmA41gkuqzDW32Sr{D?Rs5{;q#mw8?dsnKL8}!ZUk}FN5E_=yN6YiypisJC*vWfl@ zS>9wF{~Vt5w5DxZeaq-KzHE2xkIS!Kl!lkotP@_f;3q-7w3Ym&u{a#{MzdJ3mh-J1{D_h#!E4rII z<5m@%vOsto$eZI2$Se4Me=mScrHFS0tCq2p8l=bLP|bX1%f$nLAk=`K^WoUkl}Awv zt}(leET5G)ruDy9diqj7M(wNYNY_+3PR7ye~Wq{6Q~$4xfP$(m<+F7So>d07+&p4>;#RXcJJ zS#>_PRPDY?;O@O=Fv6-kJ1qQbLg9%0J@YMJ7QN;?P6&tfb-Av|z^po-krpOtT_6*K zDffQ;#l`)Rr^@)hMl~lqKacc;&T)zUX?>9!krC}JKCMuF=v=LYPk+@5u2m9Z-bZ6s zE;ug=3kwO%s$9sAM|%@d{EaU6pL`5Aw?gO8wdU@|DOPvdUbysMR&Cm0@-<}2uI-4L zCE}yxAbfrcQ*roxl!&e(?~C#^6PLdS(b|5C5}q4H?`!s=>IYG`^ZZ4Qi6~6)zcVGT z9Lky!{KswT52dKd0eP;6!?3~I!Rz(lLw;z~cc~mz6=Zz%AHG}Oe0@JxC4G-t{rYLq z7IQ{cVWwLYmgmgaa;`rqG+HmtCBH_xT~sYmc+`t&g*V z0Li}f?pwlcWd}X(a{E>PT$JsDsBdEqVzZ@KT#h_2a7`)*))Ks7)FcJ71u|m6LCh`E zcb*dap48cj!3MRJuJDJL&?{Cz!PTIuzyG-!`-QLj>T;%;} z0;w-{^qnFgUtT`IK#!CpgL%1)QPw76$w~hoS??WBb^rg5zmA=(h7=iHZMzWJ+9_o3 zRoOdxA1NwHk?o))dz6lStcFVn;n*D|^AO_L$N4>8b$vhI@w;yQalLQvD_-OIdOjbI z`+8g<4>bp@ZS@V%j`7k4C@U+D5V;DN4`An@29~BqJ;>CYxZr(FwI(;RVS>6&RjGlJ z6-u&%;frj$-o-%8Kza3sBnL+~*lXn8gmCxpiEuHR-Qtpt{!HUrv?bR+@*ySSSIS>m za%c^vQ|m*h)#y~vmX@pPw8KZPXsph5B(7NSLJh)cUZz(z)_Q*@55$MRhTj3oRa~Au zOVj$#i82Sm>eygD_r5Qj`$VGV8?)%-!7r6gr5v;)$zo;-nSTE ziq4dsV2RXhrHu@3bmU&y7+<(RcDpthY)QPz$GJuv2zB~5#@_zjt&6h9MGH&BGCCrC z?n1UXdj1oOOkocUSp9{Av!Soo0tpc`+;a~`Dv^o>q2dFr9@Ng&9%B)J+5u=Hqo~*> zBl?frBjqgC%(H6nk!Uv!Dto2!LF%vz)%W!lEho6hO_2NwA|L|FXvaolHVI0?cPr07 zqpW{bet0uqtLaQ*&(Ki8_wUwFQxNA2h6+zefaym#%MhxbHE zK86Itsi6d1to?sxGX^m#lH4^5v}n0IxS%5IL)AK`?6`L?}|ZZIySmJS;oC2AfXZmT{Q$cT&{FYEo2JOdmJjAZp$r&WR<8Q1rZ zx5c*G=LAovJ#%uBsWC}H^EZAofuq zPs{0cKxZYOB?g;)zjxIawd7UFXU^{R%AJfTuj?VK$3qB~ip>%~a-Zz*} zl`J*U*?D6shUac%jSi1Cqq|8`3hkrK+`Fp0Uf$u&RCz8?n5CGlg3u$#GhY z{0W*MFE6z87re1tJsko?JI6RK62;EA!R7*izn52%KROYyZZ~h9gXIC;*3v6h?2Mw{ zLqtgRhXo_o&xue2ZA%3g;?I=Eh~S7X-~4iP@_K?E__C_Ey)TtHxSy9-M;>P&k2}V; z7H=8;`%V?Kk3R#?XO}K)9%>8O?%mn%NU+H16nkK8nnj_tLmQ{Qa-}8x%Q+6u;^185 zgi~-0^*0SZj^K^y99}`e9B0{cP10AbNxM7iS}z$TVi>~CHbX*49!wvZfvPi|0omQ_ zzo6-LN$k)??gnOS$8Ea{Cvh^IKLC+|um9`HiVr1hYjkw9ZSCPA;b%*n?q;9K zY7%sNw%+A!&a!bWw{I>IN}9=GRo$abR#rmGVOc}bNn1uUy7OB=T=yQRg=g!vQG5D@ zsXUIutKXLH2>=TT_2ga(?fl8$p2Wg0+rGRE&$V9tzDj;k);(+Wyy<(TXJG8h_<4up zebPCj|FE_q)!D@0Lnq?&RHZ7V7_XZZAa{rLE7D7I%4|nH+}$%#(XWe3QMEy*bBnjT zySuIXyqBV5{E2y}>)}rAK0hn^jy0ArJ+T*zm0mDLVy0XrgiWVybI0d5vtH(2P$KEz z(_{cd1?UF4pP5rT^USS+M=XNsEYia*#3^|)QxzGZwpPP!XYEx=u20$G-mseV+wyN! zZ1BsHX*4TS8mV|@gEki%a#mDUW>afDRIyU&sx~=L+ev6(8tJa~I+W4TYTm(lMAVmMEu^QxlqBFQ3yefTy;CP&W6d9Qrfj>CxCnEKbMsRKH*C-?$@WYlgpXY`u;EQFM6TV6^C{j-OTFi>&KF><;*`G zvYE0_zUPnc$+4JPp{|k)TfOGOsRjXv(fNu?)6Li}*sVb83t|(?t2*A~(>brB+qbXh9B`6i@xC=N z;NV_YQ^PlP>3VyFtL9|J`fB?f){(TPa%jj028>bD1r!%`hV(s7NdNPD&#zoj+HtaL zaRCO{)1K2VCl1B!B`(1Ti`(mb7FlCI49pWz89;%b%%ix?J90UQvpFdBx= zS_2_!-#KihhBziS8WGBz9ktoe59Fe@^IXX`idiO0e+kmUIvU2LPbGCQsCcGB? z^Eog`m@gyuqrsUT{mCjSN`XohzIUO1ZD1mp-hmI21j9G?tVa#w_KR0v)} zi6r0w>^jnMj)VRA0o=$jtF`Wo?N{ja!JBh2?`!IO&~nnUhM^0*0s;v~ zf+2VeRA(jMnB|R`xGGwXB6#>LA9UXzETpf4vIf3~!#v168*;tmom&gvDU+53>*=~& zozu?Qgkh=*ARef31}L7H(f8FpgKUy>VOTz?e&Ve%V19sdMC&TR-O$PoBHeGT=NLA> z-}bK$pnQ%KK%k;P^T{m;0Y|T*bG0syP{Icvv{-a4LX;AW?r;FG8M1`y?z=`eopD;Y z#qI>PUl2QHaOC&t7at;j)9&@Ouwpe;CUf1``RrV^box^-0eJyCZr+U(_HYJ4dD{nt z?ei-~&{5;CyVO*(iHgTvLuSS}xUDq9$4<ZZC^bpJs)WsiV>vQt&FSZhe9e{m@~V0{91a zq;c)qsX-g|gGIC=i|$Vbp>=@z-=qo>`8NS+Qh+JWH6}rFTfA;D#2#RjE zEeJN;*xUr?CTv_e;MUO4)O7qCqz_n0&X@0+1;|U~Du&FuekMdsgj;5oXXeEGh$GW& zsEUB?U~4Cas@Z1vLkj+jKP)G3lji(E(ghY=RvAUkc-{t!PgV8xp^gjl%ks0~-$zD9 z9A)l$moEd{q@hojw2H#yD5ni`J9^*&=9f_^L~Njkvt#f#3##(;`G0RFC_1~i^eS;! z>o^fZVRN^=7)d2p+=nI7_Px8oI_D7>+w^U#Lpr+F zXKpa>^)rCpd$}662EKhucT&>)b3P^e7GNAbi~bT{%P1?NEepAIQ#Ndw=aOHeDdymqSg zHq|UJARu3f8y;zI_w-azt9&wL{!^79c`KirPMXgh|MJ^DYFsCDosRTm3Qout># zpkDKI=5;9IFajdrjDYj1?lCkrb>8noW9AWa4dc7z)MeHf(Bs#^1Y)+Z-7XR>e2 zIl>C7_Nj_Lt+{EZ<5s@hm30}u$zoUC{u78ClpdcyKZ2!|dV@&{C)xaU)*t3-`J=|K ztQck1Eqv8CUW#N!;L1{~0G-k5akmQNTVmRSbT?RGND1$fV{DT&Ej2Ao@5PN9XHu2A zrN1sSCxJu)j?6!^AE0{fh|?@E%2KS_%gFF(!Q>S^qO$sEMP09^{OeYS(n{nCJe;@I zEul%uBm<(jp)mJIeQ5n4PlMv)`T6+@^H0X)RY3uP8Q@re$v!I+ZcMI~KKcWAQTll?`;rSTf1YQv@*1tx za{DE$z#g12$Jfy;?)F0SGeaHF)S+L3yZa3|fq=5=<=C7{@Q`PJo+dvcdsFbnVCdyE z2LFWjCrhX2=MCj?MCgsZeObxG=;(a;y8%H?_mPR(Q>NChyB!P@=`O&fE}gwk`SzH! zHn1fT*CLm$tJ%s>*p4WuNi~fAbK{=iKZ3|T>k|9pn&zfiI*h7ID!v~a7TkJFYieNw z0agv2X$OtN{c~!tna84ZFl=$t!1VLSdkiwG&%IvOJUVWzaz^{M`CAXrpz8~BvvYEy zu1|1)p|qrH(SZmc8Pm=oWiAu2X+Y}_Tf3Ph>kT*mi~CC%t(N`HUezvHwjek&p?MegHiq^nTjn%A!b>!Ogav)#&^ld-g)=Ch z^Q3X03A&+#GebMyTi?!O>fpSa1N52(>WP4Fy=IXG86CAir6#l zSA?~9O|(v5OjH46K#+= zcSolEc--rkSk+w?tg92P7(McB?<{FK*0M?4=#^DcXbBi7;kW(!{HHPuYl2bXHigWz zO9Yt@(c6W(ua>)hdWoY?7znig$Uitq&XNUJJUg~G=B{=q^BdUe$jh^o>WFAR z!|ohOXoiC9bnEG`{X&TQRe)V#EAxh}1E2|oFHb5x8ab9W{GG6G-oCwatij&S+`Nny zMHi@B3}O@?mj%*iJJJko(1yvPeY<32)tp>5bwRH#OZ%&%``-Iu_3^=-@4tveUz}6m zlC_YfmAR5(iXmSD4Z@(=XP39t8kj$DVz4{W$_l^)s677^SJNug>2vij8k~II6=h2zH{NXf z!*kQg(=&A%jfsgN7iX_Hve)wsiqT3a^LMu_M)u_(uaZ{>rsjJTWF4the2(61vfO4~ zY%~}Df6<)XKWIl*SXfwpsJQi*_sO6fn=Q>&=3!^1{r3fQ)jFp=kgan_=OHQNG&h1G z!Z0o##g(ocL30415_rN}-kV1PHhyu5zyXJT-1 zAO5lryYeaQb#j~%i|58!HGk5adw`1eJg&3NS52q;yK$LX^3OTnkM}A8GYUu1L#U4# zHtNO_b@I?~YG_?Xsyrh*j@}zCE`FCDry0Fv!rq1piAZfnZ~@nMEy(Q4k>u+_3FmHl zD|`D~lMNcsrZbPRl*S_5z0Qyq9H!h@!|^OY_n?5>_!+0QY`NVU+BF}ts(?xm(C|o9 zNeGXlQ}mg;j?+lJQosAsi+ZB`Due+5Td5l!(%rr`(Vp5{w2-pSk)lbpm9(Zyh2>Rk zTEKXe#ol*k0|2Mshy~Op&qx#<(*p?ONM58|y~v@hI@?z|dAcvOpO%;w<*zEw_MTqh z$}`yiRsDu-NK7hePhhh<`Fe#vyY|_TxgVZ8>Mv2_tGl*3zL;DrEiJvlesWlzG_bo= zMw|2PE*Azw9CE&Arl++nEi-`hgb)JY)hxx1MgiNNN^YIa3qb#mPoI`c0I33|vlotH z*lwXVg$kN?#`etX<@#iAnroiS+B})uJvEgJ2H1SsD$rymBdPuJ4;;=QlJu!y#?!Oo zhp$CnbRWL9wh%n))oQ90=a9|oAtI(oigzY}$ROT$dV~saCYZ8|#f=@LhsYC~_LCj* z&(yPl)?-BBy9(D4NI0eZOc`HY&B8f?-_`Tjg}1ac6SZU+HaX}?%7$B78>ZIQjDVTx z_3U=B7JHG+tm=2RJ*0**;^RrJBg8axsL+CD2HtkJ9Mxrf^H;eL3{x?~f{SO5<=A1N zY&OhT#FXqpD% z2^7qQ#{q>dctsrE3uO-VB6F{3#7FTc$%~?FWp*9;N~f-$xG8)H6bV{55!c{EGXK2K z=2_{D;QtqMHg&w$J2mM`uI`%}J|G}q0ELyV7=S-t^bk2lWF^xXw3MV!8Uf}1s;Z2s z^;Dx@KR*Vn=05MNe$&cQ{eG^9Hte`Px$IeF-2}fG{-f!^hHhnJPcl&~`pJ{sh#Wi@ zW&ht7KnQRIQO)H-{5}+3%YZ>o;)w+b&%I-N2JdIHHWU@@oGYUNE(#VLbS1&62AAmg z%;?7`wZ|E=*)%wfSDZ&evy5qZc_)FuLK$=LS)&h0oN-Fp9grUQ(<>%@`O+n6kc>fy z&&@YR>~zq2TX;V0o^!++km{?>+&+B(5Ep%@SfH%yorniUBw%GW88o)b9iiLZOE~2; zrh=jsPx}eqB<9yBH2?=wO>&ysxXTN;+J@UtO?LX3tth?Wj4ddqBsIxC^| zMdy5iFA;STL3NhSc!{_$&`$XkCj3I<%ENm-aZh)vUvb>38fe|hqhk>)Q5f|d-0FB@ zi*3A7z{&Mpu<4)L!>_PQ!g=iICX(%K%LP&&loxjYCF764pz|-z1ESsD?y+ASFKw~*f{Lg<$J+V@?_EG5dJ36Xx}(A9ZV08t=i8^z z-jqUp-f9DUFf^Cbpx*s6*BcZcK$-`XZGD`15$0AW7vUkK47Soag(|)!vR>`n^pt|{&{K|ke zgd01Q?fup5`)4={(ZCMfynrO8FnoVFPBZ_QiMA6F-H3Vl_;ioOEh?JbVMX1dP))*Y zv6t)X>nXj6wZirU;WccIC7U3JLdl;ar~&{)z25l92b48*vd5DrGi4ph08lLF%!um4 z&6`-`7JbI-Hq9djW_6MQa{60>8x$xF`*jfKuS56+kQ}Fz9~YZdy>vcfO7JnFKP>TO zr>t!?LCyy!{f#{R>{Da_C6bS7VipR;hfTaz3T<_kflJd>|Af3p!FmRNI}(0~HBRG! z1Tgmg&wA9q=g}?XuV)zR!Vw3;Z}Z@KZEH^NG~4CjbgFDP4c-IvgBi&bSq0OzkGu@8 zKxo9?4UsF$V0nkF6X)qn}X-N6B*M?qJEr>7yV*DHz<^r2F?7z}r2v?!4ccdgG zP5If@2}sZ})_;~XH5MMbY;Wr#Hw1eWNaj$%tBXrJ<#m~lYoX`-TEG4)^^5X(SGe_; ztvTw01%;7-kRs$t`Br!T4xykX=&xWMBl6rhZCzD=T#tG^`+goC9@x+eq<)Ol83p!k zbIXp5YI>Beu8bB*E5PY$W>?HLsA zn41%TfzW{1Pyl6cf&rVbdW$9I7g7XmlIBF?7Y|EIsSN;E1k|(R8Jzc6&Dck)^0-@u z&z4)QjmbktsdxHw8n=neb3QwcDla2fa*Grj$^5%Vi%X?xo*PQi^bDOlK+l0b_AmN~ zTFw7l=vNSt=A5WHzbqP{DcUi9RZ zOVoSYUgAbc>AG}SHC!3_zPo%P)Caw;hf|N!=suHQ5m^R54z^B&S`_B(q^q~36+zGf z8ZhyHQu&Ow3vMtIdL`73fcq>9;kNulTH+)waQ3>pO4J zm-yMpG7&HF$keohIA+tlY5Rr5$&DPZH$bFGr6s@S^~uo)&gaS+=+nI*D`Mu0G)sD^ z3_P-6^wNqKG*<6DH4KMoZ=D5r=Q;O+cV9wuDUKTETuIEaH{YOYzYaSZj!4zg&|nO> zdfyw_m(X|cf~I+YmfqE|1e3{DFb-_P#$b-dFBwA3l~cX*s%(AuN|D`&=-Ki+Dbv4} z<$GQG^|i;(b7CKvBo~&n46?Wfjf$$+!77vK=DF_=-3nFKd~BAERz;1Y9nA;u^}V zU=o}8g%`sl_8_vX6m%|5J$9KzK!k0tojQrhRA51ZVl{Kn@nl*m)SliuLqZmX1p93} z2@jbeexJ=3Lt-I{a`O7RN!~R05)99z&TWX=md%!+`&eBBkM`j9arOC+BKR+fnPTyI zy~ZRLy!^L{rg-7!QVJL^aTt+1aQJB8AfGDZ(Fd1ZtX*K+3?#7er5Go$2&KUgBx2VuX>6In!?iGLDsYSS$xVti@6p?I^Tx$WN+j#w}QM7ZlJc?z$7M z8CoG2{SdPjgESlu@h+KP`8ZgRJbS{8dOVm#19}GvP!mqU!6UuQyIcHMNP4>WC`<2L zcO`+>qjfxJN5oc&%|-Wn;~QgkZjqY4$kUmOYwbaGL>xk_i1EJjwX5~nvZ)|8&}9X~ zqRz!>XYB^JyE(FrTWMjg>rh?hLe_G-&fl)#e6CiFe!~)trX4f4?&2*Gp z%v7rRKV+4kkfxO_%?x~%Bu&D~hKZF@FLq!T4j~KAENx~-;1>dXl5a}8y6yAi$xR7H z6?*pS$!4vraZ|ND<*e~A0#2C0UO!t$d;NlNMkUXU6=-PEO42b{{j&8MYK6vl$U5S??su<(>CGwLO5)YIO6 z!JN*^0~i(_IwWIV#&jS$3eS`6txeh}=}I4T6)Y<)v~ktXnt#YM|LoU#7Z34KjAXDZ zSbl=)rj&Cb^a6X%*`nagnjCId+ z?0rW;Y{k*JItlWJ>`v){!{&sfuWj@41$6y@b;6_>8R#nk4lmoAd9AiTy`QCt&>Isd zWNJp&rG|7ehUjC~{NJp+T({iY+B-MguT>+kIeFkU{E|ljB`jWsNw&T3Uw0Sn)Dq@~ zU*SY8su{vm1IO&=mkWFjcrQ?73(7cPtd!`FXH-!Y_kIX0;DI}J@h}#-fZ-AVwaBO; zH`bEJsYIPzZLTxPT((^gTpzfFKtZ};XYrhdcG{r8U~e~>Ffg*ShU523ThoQP8v1v_ z4<@mEt)lR{BE`k&pAP5Il}a%B0bmU%5DO;gr}xF%H+~ga82;1A#`S;$#21TMtPLem z-dX0%{Tm&|z!bYWO3OWYl&SatqsEnxe_wMGsU)y9z>=A+$VOrWl)fffhU5WKz(u$A z?;McSYBd!BN*?E=RE2n1km?U5lsOB_!nq-SltUnHNr;aRgC_-4lH+#<%1FDO@4i^_ zaXgqV`d*$}7@sLmiVfmaZi9^E)47|lmi~v2ON6fPJcQM%O=sCLsMH)a!eYAEGbd5VoTh_Re679fO44>Gc*9?J=el4Bhw3Naw{6 zcCVQKkvM&$1W)jdunbn6ybw%QDKMcAt>D8%c&K)Ym$5Y{KCPlI&@-45VmE{wy+ zfrf9JZ&Br$prwH0d~j8kE!My;A4w6-FSTsOox{4-tzSZ21Hc-pXYZyzndpDkh<%38 z8~un^A!l0$r@4hpp~9%8mreyngsDFO`CFcDL!&pIK!DM%@zv8jBfMN7sr_%=mF z3JP6s@&g}yoQd)?15(2BLX`sG3i(Kg3Nfegx{i`YNLutc?4Lx!KMEC~0#O;(_wR=e zVXtkSFq{XCCrDfei_I1vC9VdRB!ti{Xt@^~oEq<$b#-%_*OOh-JS#>o7rGtPTz1Yv znz-l`^+9MMV5jPFYX??hUgbT0RWWM?<}{)X3V3^INVg+>qV33#NWY56z+nxu>(d>w z9Zsv%hjp6{mh&sA1*d_s%_*)q#$aS_USu!@jV{`E{jIbMI8KbY6ILE2w$om5PWE3G z41R^ua8O)>h9>N+g$0Q`*PfyAzA@8~53?qea#)0~q|eaz^B~?Ex)Kvj8w<~Wo=vS$ zOcOD~V536?F;nN}F5bdbwr}?h(Q)A(UhBm4>@N3g$P0~>VRKtiws&D#leiVkJ4@rj z^fP}is)e`m^4_bk>pB(3H}RX>7x;#biU}lm58qx)&}I4iB}Y4Q)dFn_=;nXu`R&{H zgfcZkX7BcNcV|JY89N7ua9m4n&T+YmcnifKN#s@-GDi8*&WU1@eI(P%2>dqhE%)}oU zoo`l_o+EoZm=WWiGD%&fhRnX#!A9d^zisOfuf~mu=5PTZI}NY|D$oEz9AIBGCF%dN zSilhlf9_#4e!pDL82Qg*1vduCW9ZcDl9G;9p$3ay_n@Fc=;2^j_1iG}u4moV;&~LI zUGVg>>54v0HW;w01NjqKAJKIBK4{J~+Pfi9vRcCaGBZ*a8BM&@ilkI=4yIx(2uXK} zSXE zLt&PIy{RovQPDQ4b%!fd-d?)}b)i8_3{NnoO_d~Hr4KL#=>=eeN`Wiaq4$OuJ)hv| z@OaaXc2h!w zhdLj0be7DH5|klT)j!irq|>vsi*`huxJp5h07Lmes|e=1cf3qVBfC#0x8?B*Ia%=9bF$R#5k`4V{M_JcoqXG4$0bwS4t@^Y|nnwqL!yw9g0h!J``Jo8W&cBXF$ z%d3Jb((c8VLo2&Vb_$3w_A4lMjb*Ih2_y>^tB`VPJqXD`X9XD+D3=3vPX}_S?LtnY#iXaD7m10L#kC={1mB09%B*L+qZ!7}mJ=jQ=Ta zN8an0v-RwbLR48VC*uVPh`ht#kMUX5$Ou|G6iQH3Jec}B^kmRTHKswtb%a?Y77QW* z)$dBeJe7F))Ex%zM_^a75nttBw9@VRf0VYX2wbZ9{0vDdWsw-vgOWf4-em@M)F<>` zz{{v7+$(v+{)50j{fPn$;{p?xmsAvVT>^rFf+p7dTE5XYYy@oWt+2(0=<`Hc58qvQ z)N!KqSnlz79(}}B#^sbO@o$%7Xh$1+OUW?rUzv#rtz17`JY3D0uJ;NT{&xG#cZ>6? z1?l&sdop@PVm1qCMR8oJ@>J)qC)gxILDgdF*^mr=mGD)QLu!XL58d^iR(tAmav^Iy zLvM3)%qyt&>*vki0oNMj&d@Kvt(FswZ)GV#>F)8%+^RJiro1CY3dvMi&H(Li8y&)+ z*|c+Qd;A#=s!5yM9tZR;eGmSPU@Pw|DI19g_Ho^~!-CoUH7;Wn?|H+Zs_?Zhv-{WU z`-SrIFm?oZQ8`?VqDqyZ{lcHJh9(k1^I({|;a#LYg=P!`59Zg_@=R9=m1pR^HjUrs zRa=1`?6)=R77z8A0gJymqg6(Wtm&`bng&0QThW`d_1>4p;X$Les~n7K8q;&@&=TqW z=Z34i1)Y1iI_J2A4owGH#%#aw$c=~kPT-v-yZcOV{}-A8bDC?Ly6Jfa@>lvYr}Mz` zg2(ZHE11aC;ST8cJZhD@*%m})>zIk#biTiayW&L*Z?2wg3S>YqKfS>RCRXn~K_Ipd z7V#BOCWlg$KH991N)3^u4pNj3LGI{h?fr_~RxBQqj@;PnL!;}SO4XYl^${BiB<_Zj z3~TSBL!#NUmt&&OQ>l?kO4IIFRmIwC-74&|aR~xOe0#)2MbYG1NEZML3~IS>>qSDO zY3E%$T$rZrn{-HeBp(b{`5`sPdZ5IYL2_j4FAhRB!1#IJ!n>~C4hbC=cMqWe^8Hyb zWK9jd1Hgt42i{Uf{Yrh39O>`h1)m(vw*3`eB+U>6UZ~x%yJJOa==wuLwa!&{X7qSj z>f8!HiBsvzy7%h%wO^t;?Bn?w?WC@8ULUK0gAU3p2bgOHA(o&os?(?U%32rHj53u{ zmAFrMw5#zl!gZs)E#%$jZ||}P-Vxy`5!Nl`am5K79PI2L9al)XczWzmJTmdA_U+r< z(|l##d7q)*o^(0ov6BVUOz7Jd=YBM z?OQ7b&kZ;cq13lq$pshGqA0^c&AOmtl#`UI?2QRd6;KZ)B~z3BC=WXS!??)_*yG2K zqcflZ_ay_@zX@U`IH38dZIVk)2e2ojY1^CgC{TGtoW8WK8Qcf|7GaLEsSYP?euO0r zh9aPJvf-$P=ImYVUe%3K5mmgPs%6ZtZ*n7?ncb1@%||hlv1lVlGM|pR&LuRhhuosN zz2kb^6CSAlru#7P*|{-{7FKEN75**#3)1qlmoYQaxCx zQ9RhsufO*W}?|H}IQrt*c)7~BOpBj^E&*;yR6 zc|_-=lbJ?U=&)E%6OsCgipiD)EF7cg(*ndExJvg?VEHyCQr+Hxyb3gBPe^fn?X;$M zK7-DTejq$j0`34#nBRpC<~@CrGAWF7T$=ycB?0YyaU=KFldcvW>>Ty20Ik-N>Sh6~ z%;XhHI5x6l6?F>$<_e{hEIb{2j3Gf*LdMjK7eg&%_Q zz#va1|EKOlv&T{NH^sr>K4FWbJnHSaaG;#pT@?23hYuf;Sve&VFc(~c)A5Tv;4FLe z@t-nPRR)=wy+Zbfu>KkolUH-Xv0vy}cX*~8WNR+L-A&HQkpZnl?x>&MyF zK>ok%)+}c9)2Y?K16bn>L(zQzXM2OlxD$vzy989<2214zg9>6|XUS?+o@{Dv?ouF# z{mDhA_ew!<)k!i=@ASI$Q}L=Ajl|#xvpXF0!u8wh5|P0v#k*M2k`_a=FG+S5bI>#9 zJY>?%vzf#6d?7^IST^$X9*xxTOVOamb0L)<$Z9!#`p5(=6e@ctu&PxGMxxTYpDhUYxxo7`o+Qf1Gc&smGbu9i{to-Y$iOVYI~EE%Y!w0ZAT#3vP6eL3accolTjs zVJnT#W68Q9>ejEx)9{;h`qSx0$O2tk6*A}b|)oEFh?h}WYtZygK-7Ygm1zE0R zeLm-~^C5$MpM0*?3zEB0D?C4EB7+=3w!oGyjAVewG1JeT4r@AWdaH@BDwxlevc3o) zX4(_Of{bhsUNyN(c%=??sB42Zq1?6`3nMCdjQBbLX1;6)z4K4H$&1|BpXNHQZrieo ziiQ7sYmECHT3;F5#wP}oK3E&(;5tu{uL^>0wtkyZ0x1{IZcW!4lIBV|)2M9X7zs#b z#3}d|=Y=3e5y<>XtBInh)2*CWgw^BuSE{9^=VGxYDLWbRLx)c7w@;M0(GQ-X!J$|I zWl~>^1SkGC>`mc!boH4u4>dr$!ok5YXi_{5yGlT_wE7Ed_gU+C?XJ8NQ2vz-cORt?;ka! z)amW&?_O&V!Ea!ISNGmar+0)uF}tGPD1o82gm9!`D@dhhLx~a|RvtQ({OKP0xK++@ zPy|WyGc@YDD%_OVIGd~4d4e+luItBk?*L~PNZ0QN{Al_G+flYoiw9Fp_gr??AX{gL zZMSuXy=v*jNp*v8%jsmxgvhf8;fQv;+W&;;lMY=w8u26~xrAdFmE@ zn)(@(cl1#^LI|3O`Fer=uE|lPN-Ax=1ui+^>d!l8;qWx@=kpK(8gJ+LKP_KVc&c}ksrGC(01v9_9HmXwmxrOvxXAjG4Xnt82vn@%zf zy-`rD0n^h=vcZJp_9m6eo@BR)-Jlv}g!pD_0p2y}@P;)r&MDWhotDN#0}=^6g`rFU zHyng2$sFNaI#moU3zsc?+#hdh!|v$o-8v};F81G5D#Cl%S&E^@vyh#cB1S8V!fxU1 zRkofnRI4}~3k#R5AtvXoC?>v{JqR?l3@+;sf(ehjSehOnx$kLWl zESq~BPGS$3rP6%B)C~felW{FxMP?n(n*hwPhY_}@z8oM; zc9)z-T6EYK>I$LQq^|vz>};hQwpA{>2QHrgY31i%F9%=6FZ~*J}V`>(gXedKeo>OiL84?p(E(0^c{m$oKc;v&d!?oyr#b?Ee(wIM1S`2*wif}R>5VEea!p%n2pD3fXbY12W+{7e3#>+>QhCn-H18ApX*cO&%DNRVc>`3 z9}Nz=NtZux*8JnrqbnNIAKOiLKiFGG0*BFpma&s_m#Vk*xDhwN@ahryrLQ2e?d3~9usmy zD6~58PcQxBLE~*-rD@w zcW)Zs;oQb61&6TfvU5R~G+XJ=uMyUFJP-}w`~~9vyd}3)FyT1&^ho1FV)?a=@lre! z_7Z$c!tsvPS#|Ka78ZUFgf$NCk5`~_)Y8(DVMt0!l0)y%ly0{iedDeuq(NLgoH0kO zT&8NyK&l~EhPISSRr}E9V`Nu1B44g~2s^;HHZ^qx6(zYgqFNGofnfZXk(P!or^rj* zylB?m`_g3{%Id+t0wB0wP|x;2Tz=||=E3ZxDn2x71|AKd62SMH*993HmRO+9PLV?~ zl(nSboYwI>-bm;4{6YX1?RTygW1l4X(uh&PXZKmnyR-!bs*d2nxFJP&b(%Q$^Xt?+0n@W5Qk!C#M3F z-Sbd6xA3j`B`^R&D^13!h^UM-_IFun;ZL-@p;7?phN&!+@w+-JXAf9LxRe3q1h6Z8Vp z0JgDh^=`-y_#_tz)l*kYU0huqt*yW7;V+ArTAt;%E9=cXAn6KY62Nu|SOH8;L?w%Z z0i!EUIfse(s67h0wg;7#C_VaNaWA5gB>|)f(k(#a& z5c9+;!Csr7s=9-^5y~4ux3W4=9H25(n@IZh{>Aq8`}Fj!+7f8fG)=Z1fQI1~qpA|% zCQ+MGQHgO^HN&LzA!~9MasjJURW3`vd_FCe=8tC@ke)p7r_Ga-`FHUxeMr&&4=mM# z)dzwmJ6rFxCI&Kg4%8s>5BgD&AY-m<9A9E%Xo1shQ=8Be1%`9qy%fn*vrP{`TI9J| zx8MLo7e>h1cV^VoV;Qt~AEZ2>wMz+MS@z6HEM0lFxZxdnbpIQRYjcOP0TM2B)MwlZ zCC^i|Ns)EP*!h#x?|rHbUPP5WtZ4z(Ma&HCb;P(h%fJnNW$BI0@r74|L!*r`n;VPc zF92437udNqN(#|jg&HcZMOxqdr~Z=4CON8G>Y7;evAE%z`3UT}&}B?BB3^1+#qPU$ zii*Y@AL=ftln7$yu3_4oL2{CRoQga)!R5D)LP_B8S4It3n+<*|6r2HC>56&EWQnyj3GcynpN{;*;CTYS*8+Ig30zwi|bNUff{Z$=6aWv%&v%rO` zrM3Th&ZBYR{T+*AyC3Qfr6)g1u-%}$f(!Lo$;U!FeKdr+E=b{bT*OujHCF+ZxhM`BW>QO12>Ew+hrkB<{D^{;?b;tzi>aX^9iCQ6>G-LWO z&azFr^O%B57&V19D_YH;o;criarKYFs9B723n!-}*rPz28~-s;^=Zy?WDs!+3Q~;i z5N%)Zv^$w&!w*v67j@-`^*MxV*GM7V1E(dG`V_0=-@SjeTzxJ96TPQg-`T{kdj<-1 zPT6_?_PyIs5N20od|D#Lh2R+DBk(!JzX-Tlcw@yShdEnUnMbrsBviA+E-URYv0-OW z-r@;7;XWfH&B8Jmz@E^!4FFAkkP*FmfU#=S>^1uK(~ti|mG&*HH`KYL`M>sv!*7wC z!+3h_5^SXhjq~@c2qS^Fn!(Sg%ZRKUsWYr%VLivKn#Mc5Ho(xTSbCf!E?86;=Y2lQk+US^vJvswVUx5Cy2mj79I_u!uEfM7ziQ{h)LsOi z#?Giob0AzJX>ZRf=cs;wKB9ecCwZ|QO%G!T zx`1#U8p)-5;JKvILTbEL6oTNZjW%U=4i*g%O*nT@1iqL%%#6SP9djudsa32C5!Cv; z+9gJ;Lvy|d|9yAk#1wclz^bPqw)1JV`?p*R)lTyjr!wldKWS1=o)CkT-BS*&ylgo> zPO~#si9P(wr&Y6eW`UX@5fTAkvrC98k@O-;HqN&28k^o*K1dJv<5X)s2%(8QLeYre?;~PVI zGtj&PtOJ%`dq-pJ`hnf8T2S~CXYl7!NVTXj6r_G2nv*$o>IFmrT>T3A zeK-~zzkKsc$7ngkmo>vHh?cj9{IIpz5#a+N!eooAj@ zPx6|sPefl0DJi2BX%pv!-UI%?I2_I(ZmeMV9Th%}!|5!@KmY1su4`!lj-}uCr7C#w ziPKWOYnktxGc)%Qoi)KLINOA__Zxtf|N2HKfUE^nf*XsvEK!0Tl`23>Mjkr0@rLnL z@YQI_p|&lYq+p*x1p|Gpftzu|)>e@Br2rQf4b9_1g0;eqa&1yEXjz;{)BLdLerm21(kn zLe7_(;h|Dw6>yWnqeo4}fD%B&U+fW7uMaXvv~3z59!_@IqcDE?KqjRY-q}KSO0yPm zjsxNr{43S0`V$$iYigo#AH6cuf32ZF6BZAMc5akC&P}V)nG36zNg_amDO%3Ax3!%} zZ9gMQP2`n@Tp)_hwq-^JxBY8YD~NS~Q0GnpQW$=x`@w)n$eEN&TNgGQc_u#{h%Ue5 zvGjw#c_LJ8^nc2>iGbeH`$)8H!hh`-fG#js2X@YP@=>=|_J+Xb?&Lrq$y(|f$NiBK z7i5>Z8cKPE>t>xV=408t`4$V^!2hc%&x1oK)kFZO)LoyJ4Dw0X-jhiLh~oi8EeH?$ z7B;30m+IwKL>(_maogkE^XVk7DgPI7(ZGmk+N@gy$repvkdg}<4kBNUKk4IfBX%){ zD=}O-7RP(=AOyArwg2k1Hs0OoY&?x7=bkxZFe2WurO@psoY9eya+Ov0uu|ZvvsAZz zi7gADjw;2=h-zoDkWjpOUVXhK6ncGsBTj)C)DzvOCB|uFY3X*B?djcMjbdLdUy~;` zoVKaS>xm&w+ZAu${&0j-b~e;3V4wF(ZN`)#ePrcz%&`xgyeiH6JktNYR{@>VT9xMU z+^uTAvM0qgZJBGZ2lU>02E3!Jtf4tg;Pp|=-1B((cG0t9_jlYn9!%aI0Cq*D#6e9d zosz_l^zT5dzxRlCRx4Wl)yoHaBjmkISMU`l@iQyy!&7PREE3x%pLR?Zm{QL&mPIG+ zCZpUBn#Tj$GMZ~(#*u)1XUhyS0cKE$n8FSFLg(}P_pQH4#!#dLjpidWi$4U~2)isE z&T@Cec+0D)oJ_6qt2q3aJT+|bn@f6yl244Cxpa;0)h`u$-stMB3KIj9f|fM@1$#=c z?^wTSjLVA~a^4y{P2XPz9qEW1Dcmoe8I#epd zF$D*fA;1G>*RzA^4Zdc#IrBo?cNWwaE;)+Z zPaOMEF7(=KC90x30gF>U!R*bCvur+mrFmpS)zNjoEn?<&6}w)cv&!_Oy=|ky)F9>h zF%Z3jMBQA;AVeT=QwQ^F!{B)<;So(^O zzw`U1t&U$miKG0$!HhhJ4%CLk0b*CL{63GfzbFX|iXmH-wlZ*cv7u_J1ZKq?W17!r z^*s+iPB!K z9~Ii~VZh)3ViGz17xtVCZ4J%&+Nz_+HraBf#cnZCp@-Oj5~v_N^N+0m`xEBv6$}wJ zXta;4uO}^TmPfRp!e=z$Pe$hBY$*N8!aC4Gv0gKEW5oHZIo;svB?9v*Eh#w~U_T!L zjVkmvsBE^-Rm*{7+s~e-rw+*vozZ-<`TODGC9nRs~$cRg2 z#G9^;`A=_To8QGp#7vM5SVUmjBTfN3ah-@)&v{~4W#+n{tCEsZ6i$Uk(9usGbh{v>Fkq%mq)F*x zT={8mgW%n90Nez+yTJzh$f`@Q7Eyo^m9bAvohYMeNPb^}-Rvlucaf`nxpFaBy6-ot zh=Ml;`Gk3zRty@DYy>W-?S)7cz4tMfV+5w54=i5hl_K?l@&mOn!8|MI!puYKE-hbJ z8G5dsje=8Pr2*v?A#hc5{u{xQz@xffr`k3j;k}P&mR(UZyWH$Si}t>%3Mn%n?0`&Q z5OzT0J=h~abmb5r2g??M3NGd9fe8ief&;c$5W%M~qPT+7^ED!c>(_8|wbxm^4+(EDe9*eQZ|a)81>WcldF}HCf~Lh-V!;8(R+>L*cc3BJq!IX&o-1 z!|Dm^6N-~w*AZ_tM5)#5!wo{n<1%C=qNh-G)U}%Vp^fzGqy4TicPrmUbif$8-j26% zV>fB*pu&+a3;9oo{r2s@0v}Q>OhrUQiqjH_^W-Aa3b4LVT8?Kh_*`cA6CvlRGx2|? zS`Ec7E5ZjwV9kubB#tNA!fwIeOcf23X@JLCU}`AC$B>k9t54ltk34V095I3S9=!hf z^B`Myb;O&2SS9lH{AvHL_FJUu-jTX}9xWr@A1K@AMZ15Pv^Nb>w`%1{@BPwEtCXS~ z?@>K>&^bLd65%QZvJ=KY=U^LLG`W!pc^9P|!p-`+Wd42f{-g<|D!ksIC$)0o2E=SZ zHBP%(wJr2Y2#Uj2v^p?jc?RDnE2`88o10-lY65_~7!}ehP(lvu$`d9579!a@Kdbfw zBW(}SsnE)G(bfcM=R-G#NXtJy?rgp!PD$En2?`BC+S+C6W<9OuzXZ;t142&%U0$nA z{HJ>YaD<%>j&V}~#q!U?oqXQUd}@;QAlDM`G1MwjPg|uC!L-hoFnc!seTwj-%!8YN zD}qP|AOaM?e6sn>lsVY7@NhW?!z^z+S74WDThx*g>tt2;>Oa3SuI=xUKQl6evGTel zIYE@UCeNq-GT2psM`X#2>jR#qd0oyf)Zh+1$?%Ax^1?F?N9t5>wDIe*!u(BwMl`5ya z5D+Y(l&-7jLQPqYX-l>V4TiyKiXU9(_ zp1n9V1K-S}3>5I)3rZYt)cZ)xSUn8v+t)pOcy-Ur-Qk1ta6^qAGNkY`!&A~(R{INcPzhr=)o^5!fcx~Kwov+wCk|P`QyEE z0=-j(b~*j4@3vhy785X6f5@r3ReH&$?8!T~F4~`)U)l3j?}v4@wd=QEemC#$K6+vV z9z1>Vdo%X#JtKeXowBj_ZVNZsPsV-Gf9i&Ax3}S~$|*(2z(vym4j|toz?;r9$Lp&4 zZmwK^>)2e@Uc-fURqL+oFxS^!X}z%{+Wc^=K1F6WE6yBrZ+Oyl`%A#&<)mQ#+!S8viuS z)jO`iN3)zmzLDR(jEc<-lYsVXxnt{gtFQOvo<9f$}B zGr~Yq4F4;qYU2S|Klgt36n0HAW8O6&j`h+PTBliOQ18TQ^!Yzt*>N6i3Rr*_<{iL5 z@(H$4%wZ`Ym1a9=F%t-qeOV-wIilTyN^C*+58J2B20UhUG9+#=8ehNy+1@}WB#}6> zt~t=>r)o7rz2OM}L9pSjo9%y}GPRQno?=EYQaz+fUd6V5oR4mTLp4T|xSL537~2vZ zSr&R`VeV>*2NWv{akt)9;qr*@$+Cc9OM~QFIRW0e6|9jOdFi#wDl9BHMHX>lA|43N z_OU|c!mp&6I*UzBrSN~GB035)rfnB=Us1!N*$C*lA9a9tAy@wv_v%~}?%(p);Whx1 zi!*?r-+<33Iw3#!gnfpEa!1KFC_A1U5c|JpkFgyJNhe>v@Gy}J1dn-m?Pz~(A{Q1g zLO}NxdICcE3D&Uq^Lp(rrEq~#-~+EOSF@Bd|I+PBiv!W-!c~BXyUbFq)R)F8aY1e< z&0Me+5W72A%BTJxZB>da(gq6G0YcTsQjXSt^s3Tjfl>g|^6nYI6ylP9S%h*Kh`RsG zggxp060caswCTH*LH&&D{#_|CD-KZ#mwLF^W=v#! z_wjPp6M;Ux+#Xb)9>kn2PGb#kzYP-s|J4Q+atEfmnzH3y?wAH>N0@3RJfxi+ZLNc< z`%q6MQ^!fWiztCEvaw4YDYn<$M8H7Z}|;* z_qj=DMN%@nA;K4_DwCH3LL7sw8>=7m$&ry9<0nW5kkY9SYpMZ+e~cSOJH$SNGTCxP zAi`)}s!8Gy4+?m`FCmmntzF{bRwJm!`csWk#u0{0Zz^`Ohg52V)Mt^eL&CLKgaN&u z-F#=MMkM569a}o|VXm@bp%N>hUjs`}6nX$*=OScTy}fo#brIJ!B_2;bZ7KKp_=w&J z6i5)gSv(slv5{>i@azVqOqruYww(|kbIB%2m>VPZ!sq8mkvcCo%cQ_V7yvhqv8I+{ z8G;bI`4lFC_Ub?q$rkbB&P7R!`y()CfekmWzw;z_s~6tj`9+Gb(_JF#HLTF)GIdx& zmx%Aa98>2zb&@L6b?$8eS~M`Jy6M=+MCAJt*#FGZ@gmXew)O)sI09NkW%u-cU|TZd zu136iTJmhvwy4e%38E_f$0IjPk10(8WC3!q_@P(Y>?Ti!K=Tst?Pi79xe8$d56K

#eaL`-Px|(N5S8u7U;xjZ(LJAX3tsBs&lO?c!fN%;4iJV>qu2O71oi8NBUS_7p^CJcK$Dx zefU{G8-Kj~HBwt=#=J#ubIO8KVUZ52BlX*`d?~5CRE?A*B_4j^4WD-2wrMr7THL6p ztj65e7IVsiQ(+xx*hn91eZgX4vDqP&iy#x)F#WkjH`sdfs@I7~o{W>f?!&8V*K^8( zQ(=(~t0VRM?@u-mV`C$vasf(D9e_~C$8$?QV(q;s?-?SsUPiZ`LqSPnVKtjEb8hRk zKu78q1>cd@^cri^iZ{v0Lx-WzXdxHbQB`>!dyikl;fqa3(+F|j_>oAC*P*`70wJ*@ zZ(Sj$EI1X`Nj8qiVLvX&CqI9?9WIF)Qk4*;l@+MC(g?Rm1*wRSRJ90ci3w1OV8sNaTzgMEgG5{;G}7oOh!~RxDg{4BS9@gdRht; zA~7zOmP4DGiZ@q(%oz{P1a+c~BXa23Q^ylyeI14k$O3o**zIB-Q<#6qv{ zjs}|nMdvO;<95M8+o4Iz#KILDIpe{ZpiZ=LL=L_1`ProO#6k4vk%^3+S=e>_H0rOI zam$dNh*2qVr06VqWa{CzIk9{9KK$XqM{(aHb2;O|nV^WI(}_wgf8$SN_l|FnoR*F> ztsF!8_r&Hew;?k<4ssFDXcI!;r#~vH8*uJIIW~Ot9j7cf71oJ%j<})My}Oe9^i3fM z_!u;(FZ!j)v3K7gl$Tc{H9-S?mJaGvJu2$mC@Cq!%JrK$Wx=Vih@;bq3cc~?JW_W4 z1RM?;x7;}aPdxh~YwLGjdznxah4~AYus?sZ`2%wF&|$n%u!d6>oC@niJ4f8m<9;)Q z2>1k9Ju*QF#OObCI3Az#M{48xjl@uY1<${Dbs=nCS3r*J-;4A=%x%$zl=+3xSZxq$57 ze-PQfxeaskUgeAjXM#G|&Ji=*>gCJHx|Id68Lz-c zgV7AJNQ{Y-Ct}u|ynll)_)l`;(61OcbQqpkz}*d96ns0D(9F9hkexesLd55xM@AX| zH;T(@pp?rItByfZQaqFjIn*jS%vL*+5;W-5GXv9~yZX|_R~uK5%cU2PmX-`-T{Rw9 zu!1uloC#`&eIu^xtMi^F`+wYy%BpHeRB8+x+7Ds@4_9jIu>bIBxZOPT>fIAp>I_gQ zWw`U!;pp8{kJ8c#@Le|a>Dv<%W?i4pzh3$fnex&G&UkPpDB|d~QK8r7Jxvb$xD{fV z9LLU-B4`|^sOUctFMAk zqC{5rL`-_(FVuleuaIFgqOV@H5lQEFTfXRZvhB0KBPk^j#TQE1ygh2va10te02G`k zJ%0{cckF>%77q#pE(++8mdIYp#3&^&o6JZ_PQ<8@*)Usd$bIhWmM$Dm*aU}Tvh9^Q z`<_Xpw!8>Zi3qhdHL%i7C{-~SJMK=TCdXmV&wKF8z7tTWVxW+U&|q^RJuMY{w++>` z257Y!BxqE)YvQet%H$aLz`u*U_UaaD|0wt%E%y1RACnIjzX*j?2vw{KZc77do9w7J zyOGjekFjHh&>;mE0rNYyA| zq6r*?52Xl@NJPjPJOG3GWg;yt5hWK&px5g#>EWyU_8+(Wm5j}u&nXK|g+&a-5EWUo z{2lV?-xk9~+_2IvWMp=SE+rnPj~<4}VuxLzM9$EGpb4<;yFD0?nTF!3dWeK#C?!Ch z(T;m2jza(5-O)|22XWE3WBLN>$Iq6NvG>ml3xlu-4bkplZ+`ob0i?3D7!s)%Mynl( ziSfwnmI70Q0Y+mJtTqRRjL1Pz*%efjlp?#g9%qWn!2^NCY6nj!!sKzIFlJN^raXFm zc>ng()nw8G&vMRzbAe%}7@`7;7A_! zppc4TcDUgre5h42+%a|}>{cs|o;ZUeXUh<)QUSCLZd((^jvj%#rc6ddqZM{jJ-X>L zFzLbh)aH*?5%7eV_V80-VGtIf?cl(9*H6}eNM3$n9%9u>h~WgE&jTSY$V3A0Bnl9L z6v>HN=+Y8VQGN+K_8f!JWCoA8*~N0p(0&+q+b~cEmOwa%V5nPl2 zl{E&$sN+ykZ2;{eaJiTofQORGYNV$mqqjZ<3Y8LNrKOm5??ha#HR8)}zK2RK#BIOL z#{9)=!)E`m3Fe$&8wEZ!Gnf4HpF7w?7r9sfr8XJeQWKz*OJOlJLL?HQw4?;!iI9-0 zgH$5MFMIaF$rEGjEhC}to(4m0H3s(4WA+PgQM3Lqg$(VRia);oURZ4(R^e@A!D+Y0 z9-Kk8ZQTkNZHGc8L3(#R8f&Ydk_y>;Z8TZYQ=bZ{kb;XZfk+}_k8T?+PWFZ_BSR0l zObie=at39ACsx4Pa0!VTB_=<{-5WR293SGcdGgUm$yfjQ3_?BysaOCWUjUocf)Uxh zK)ZPm!GYm9*%**L7*3}hb#-+puQH&#st#6*6-{OfoAYhvCXCF^!oY$3VQZ>|E+r0k zJ-IY&ju$q;A=*D|&F`BqmYgmsg4JdRA#MoZf>tB>1!9y62ptA!)Ji=026wMoMMHfM;HTa`g6!M3pRLgKNgBwc zA~c%qXfV?-+iCD99)toO1biM;v2hSe6&Nuh2kEH^xNx?J{Wfgzg%XG)awMjtLnP$k zeDMXy#6k@2mj#Ed37S|L6p2}Q=((#=g6k(NLb;w~u=2jzQb<01e+AB-IS#o@2BXyl z7a_3NoUqYOXjM{3!~!&$XaEE;atUH$)i62S5J{v^DI}nX8*tiCXE4HIr=inlA}K+O zlF~8=h!Z`#C4dr&k)Vmeze=jmr%xaB%1FY!PjL56J!6k3c&}A)@0j7FzM=>cRV)M) zP-wW1!Y(P;a!Lw*Cr4LJ@m2ClOFE(-fpi zHE5a!kI-;Boe=VX-dQ?mG+LBZ)S#iZ3fTkuK%1I@XY;u$_M+guz`yX!Gvw(0T~Nwp z;5(a8bg>eb3^q7jE(nDJINbyiA)j3U6anIuVraEmh!k;<$mFQ1se{d7gPZa4UR3L=3JHkt-=GoPZ3#hA&{vEsd}SFOID&6~d@ z^|dvyTTQ6ERD~Fo3bAT65|Y!9oBR8)FbIp#NPrtihvE8oCZab#6$UH&HVs8wNQ#x< zveC&dhFF<^_4*&r)->BOH#e7T*|LT0TUc0#>C>mTX5;H*wbeEgCQQKg?b}aa&pMQg9j0+lKzabcI{g7)Kfn1vq^ho^w26uoKo5>R;=xg z%cbYgWVInHQHh`bRU61|%^-u+p}Dxzv!8ox>1hz8td0SH zP0>(_M0S#)DjC2FnDKl;Xft>QIwQ{mzP`!IisuO>I9C-AI5uwlFEV@ftd{Dw=3L$$ z-`ut}@Qe_(T1^ZF11m37o3^G@pvXh=^YgJ}$&#Q#T7G^$S+iyhh7TXkju}c=;u3tz zFwcOWw{ST=SoIc;o;@GXUQ?$|C0~5;#dYc~Teb{&c>%vT!GdquE*S9F1hvVT+6A6b z_VD4uXlQ6?6=Y^+Cdtjs#i2uoA{M+ibdRSq%Kod?L~Z({kj$7FdcMxg%tUc zfa&XPxNC(S)~;O(9|a!C$;n}xYcv`>^w2|Wb?r$v% znIkh6<9#ikKn3tMz&CIR1w3P?@4x?^d+^MpckI{^D5Mb&AYUHuJi|xd0e?B(dt1rWGEC%Z`2@MA zZ|)W<_+S^5r(K7EXC~|`A2UW~LiLs{TblQ${&IW(S>v-0>SDs;63@XW$t9cvG-~ZRNQ$Rf{7F-PMiRfLYQLD&$g&d`*>eE z1S;-4;2HgVdHuD@+S`fzoyG<2Xk7;UHE7p?@Dyj>iy;tr@5y>9`q86Dv%3Z^!21jL zfxO<=>7l=Hf9>2ODEM6pe9N%zEBps4?gE78P7U>~6?mS{eTDp%N2h_pcMyB}u9xE( zjXhf|uS)xdQ0xmlvmI<@AIcf{V7%Tt}-1~TuDFXBI@~%5@@$3?q zBi0KSF0lIgIFe*f=zMIG0^ZKGwzKfSZ@B=nhTeu#r%s@*t{M)S2JLj>PcP=-t+$um zFi)?vcLRqYw{|{LMG%)h!EkTaJ9mD;2g=$0jLsOUprC+_6wJeTY|Eq8mRm(;%lGut zPcz4_%>A_Y0%#X_M!ql4x6v+CG+w=?ZTWbB1jx-d^l2HDLg{;Lur@nxn>z-zth#U` z4|vbM-E&XxnNppD2by-UuVgW=U>YsfE@jIurEECXk@o^vv3xbzy7hl>@#yYmRjMs6 z@F{@eG5=u#V6i)~;qM#R&x5$e4abyNnNjc|nEs;=HDzgA06@CB2Q%f^)?-4`20hcaSVf3w|ZWtv}bGt{;DEKyl@9N#6;JZ4(HtHV* z-$uiA^=?t{U7cVX^^byYqv5)GwkKNXER8K$D@zEKeH~KSQ)A6u zc48*mFx&G!V|>2Hd%XX_dmLZCjDwl`xtHs{mh(KXi8VIV=HWcT34uU(5IR?HKp@QE zugnm3R`3NWE*lMjjI1KAUNU=-`IoX9B)X772&HmfV~1UR>L_NNmv;*-^ws>YW=&r8 z0K&!4Xx!bf(B83hgDn&8Gt`)&+`rNjj&XI_(kIqB)y&#`Jg)vU+XIo8IRd-J31dIx zW@mHr>g!vOWe%;Ize$$Qp7BFbjK+|UgepQa44lCK{`~I_{O=C@f4KuEIowCtXft>C z6XlCiuX+m!A^W2@e4p#=EvKRteO9_?Eqq%XvHT#1qgnA(gxnELX;oXD~UBh+vds)bUiOw1p$UL5^g#8dV0Tk-nSf!5K{z$H={n*c-M0Q}u50j-&GSn$Dt ze+@5feJv<&qku~bcMJ-YzQS`T>4Kt4DG;6glNI+@a_Yx*Zd#SQKEOlCL1xEtf7@R7 zF&@jzQ-31`(J*0>o_SAfN9gVf$*aJ^rIm%J*HB&@t)*pCfTc`0T}<1Y*4? z@s&N#G@siB!K+XTa-%Ua$u|nX6UJLGMx8K*(;+!V2)9`O(`WWib|(^>AVs-~eQMY| zl~BQTOL2!Y!qct*N=m-R(b5?Kj6GHHKh|p)aBgdq>vTuvSm+&X)EBzR4k}6uh}b3~ z7&C7K6d}c;iy7{5pw8A#0jcX;)VA1@@P7dY&d<8ijxi*PaL^1f_sH@xi_VG?gQ@v% z$>*t%yd{EB#WD`aMoR21SStP#yjdD`ls@*{LfYLJro3rFh0S?+hD7WZ$wig$*&}_U z_xrA&3oCs%HIFUx`Hkc}sg~5uSRF<)g9|%=OI+a;a^MVe(*JBPkNM(Vo8dFXQY{!S zG-U8h@AMRW;Z3p4{jXxEtN*R!-WF1<^z{ZK~p9wyT@rCOWgmMKO&$P zoqEV4i;LM+bWD3x-DehN#GJ@{GC?){cSKF{#(5-FHSl&-nXHRwJ;l(}J1f1v+d`YT zlh8oylO}}>`k^)P9xN{z=nETXWx4usP|h{qb>&-rK}5KxiA!J4QiFwd{l>fe7=^Kr z=0QXfyCjEkSZa?CCdjdXGG!j$ia{EN2Y8xT3?EUev9bWC+d#6lMBA;2Ev+zVYfpS> z@8w1%@0-dYxmY^_6`CPcp&L4L!xYmLaa~2>T-90o{*|_}va)lVcqi+ei)Uj|F4kFj zPGc~Jr`<@oA;;=nQVS`_s}(T7W!C!^70t0&SFctvpY^o0bzkiI^*Gx*urjHU6D9uN zjwf3T7*}4!{c}IJG~Sg-TM6wkA*1HK=w<)v)OpV=LRSscqk8KfMPniqi@pC0rq#&; zjRw6Qfa@@0%HyTVBdX=)WB7Gt4g3vvJ*?F*R>P}7uR=Zq=h~Ln!@hm>w{yHoHx&m`fH%QHEfH8E*g-rq13jn|%>p9HP4>O0 zuDH3SInIKDk{=mf6}`gWk}|8KmRxzNI;gwwEFB>DW6G^jO>AyjF8a>6Nm!jZ5#+2U(=j_zF$hdd4`hNw_1uA`DkQBW}h zPYJP}8 zNLut6IV{-#y8_&?9l=Hg+aN=m4#)x>l9%H7!27M0|DXvt*WJUY6L>Iky4)Gj%~cKF zkbuC_*K?1OLO&;Hz7YTtIGx*Me<}Jwi7sQkM7hYE$)sVmb}O}ZS28w@~d}>j^-wgczB|AU;umB zJB=M2c>jIEs@{Ae=L8i+W+N0_?PuIsUYaFmoC|)Dhl3A2iaSD#`R|P?cPAx&DEMPe zB|%0KH+8XPd0yBn;`l99M4-WGb2T)=LF`(X_rQeUUAQAIIBkvgKy;&rn)<50b(;YCOxl!oxSZ;N%s4z30%O7(4scUS z&hL3{h@Y?_BQsNXZ&rM@oy#k>=^93|eG`B@x>OY6$q=uPm*C#iX4y$4Y^ocGKK^88x-7!$7> z%Z@s3gM`*h+pNm-hOHvhN~v0KLliVcQpAO^g>T*ao$xGaN;Fjr@7>LUz$91*t~tsH;oZ%=W#4JW6sEAmlf}I`!@QG}&F}%X z^q$yFj*(&u^H-|*9i`6?Yg{jX0^}I~d5w(MzX6L-=Aio+ti_B(SWcU9 zizHGg%&f>*BMqa`w|6K{!y|}4RtigC@pdfrN!WFz7OF3Viu=#5y6?_>msDEL{*y`YC zHm$n+Mo@g37>g?CSw@;RVUg|~xKn>z{*Vn1A8WZgUC zmgnGFY|9xXZyt^~)|&gNe3N{qxOwC3C43$uS?;>jaV2S4B9ZEy?7V0%q71o_yLXA+ z72GnQl-VdVIb2pAWaDA!QRK@N{OR^$HZklJ=Y7WiGDDtxuE$YMi=k|>3k;HvTnQ9X zg`}c*<=!&pEQXU3`Z&HNv4IUVX?j;G3aGT+*?_D1ZS>I=*{VAZ{q@UQ8X{h26N1AUavu8!lrnH8tD7JrT`FH+V+EWu^PLghAqdwQ( zI1Z^V6f`(o~uoJW#xLPaC0gpG^~NYY$EOc zSofR#XKVjSl&O^(YgpN^dR5~j>|j=F-%O<~#(X(s=ToVXMD->Movx-YNx z1A1iE`gL*S$BN4F%Br*88P>kz3_eO{6lG5RQ2SdP+%-im6^y9P4;E!qOMltJ#p;r{L=C+uO+BFesd^Yb)tTJfaqqcw=rL>5Ym}B zUHbC=6jJeb<;UFfvp$w)i4uYoik=&klU=ViQr}7YEH6D#TWHPjy~~Zh zhspLnilaOTmlR2c15U5h8FZQ)&dD4+a5^KQ;*7e9ycb{hnirgo01&$eUXX*QM zz?iZ0sFOUETl(|QwFs799Fn?b$0WZ$kGjm#bQq?`$qh6;%?030`$bhA@AIdX0xgn4 zy!Qk$ev|GPzu`I~#FO<>;7&Cs>l_4m{n za_g12GoK&1ADm2LFc+g|(rQYT41(^`5Hlmg*b~kW$Ni!LZmw8QJ<-0#UsWCU#?c1JOIhl|3l$a#mNdUt6<;JFJoZ$ZP-ALm| zriJn(JCu~(IlWIOYp+W*`WHE;`^&Nbna%Uznkfsvd->_h4Ro}VuYzTH4OBMY7+!j8 zKu+lCQFRJkFq7|9JtysY4a;F{F_b7RTM0IcHrOS=t9%X^Bh ze?dL>yHF^Xo(r@qAy7g;Sra*pTtHjPRZ}7W!*Y6h8`VP=rsYG7;qfK9<}0At^A=6l-E_6$^boWey*L#XYb0;~YQ<+&GaM1y5D2W9d3UGuh$}n-i;PZd1G|Zq|2o znQOha(5@<(&yxc z?*@=%g4X$Q6=dYC1EYbqOx7;=UH^uu~m;o^^+!?Vd7g9ixxDE_#y+SJD-=*hMOe#Bp8@;uG`q z2;5wvys;easogdo{)3;jI) z$g=W*KvGsgS*GXWXV8OkRlAwvh%@7uR#k|-GMj@;Z5!>l)@40*F^*BdYUQ)}#oLk}CJwl5~@2Abe-fHTs6w~+8ZN`C(k}WgYK__K7JhFN4XIq-* zMDPIi*%v|(E~45IEnO(;sWIZQvTSvQmbAy|8I+z)l45xCz2f0HNDsq*ciQWbJdmcJ zSl8ek1t53HDQlXpOM?;UTwr!i)wVNMhxH;j23S}}_&VWr1MO9MJxNoi)n%I0kvil(>&7)(L$gPYti? zDuB6M11Yqgl$T#R{QZX}0Q=mDa)A6TH?zl#46H}VkChpo(=v1aTJfX>*(dw4Z)WYj zl(;H($Xz=KS_4ZbZM1b8WVyy?FGDAJ@%M?VkaVWR|G*2f&`)<6hh2>95?Eb5TaB+- z&sq6Ou`m`N*OTVC~N zGAZ@`wz%qdFp4#lZMtDfgvZ1yQXD={8U12C;8+CbK)s~9ow-z3nGj&eV>cCGQvk+w zZIO2O7DgEr^@mgJs>H&xu1tj-My3jjUT& z+MO*^|Gw(^LO%2U@vs}VE=83>9DM`UmlIjjx`CO^Tc2(+2p-)jx5TDDdiA|@Ah7;S zJplh(%Og35dv*y`v=2SWim;c40))8dC9EuWf?2<$=H;_ktDHV3g(FIU_=rcz+X+hN zO{Sgjm1l9UXt_(xZTIi85(**wE%uazQIp#@S}{^dJw=wO-{l4ZHb6|Lx%!=dWc3Tj zG?yZ0L~8z7TQWDJ{(e?s_?8H0uj_q;b8i6)rOpUh18b76R*%U>%YY#%?3i3JGy- zHZL|u`7qvfxjZNk!O}iuXZ1rHZjTN24gu;?>Y8nZ3R*bB_X`NEV5d=D&v6Ps4ctLM z^st%orPb;Nbt5);N z>=cWJxBY&bqp*ae{(6&|0j58CRaO8;+79_&7vP@i%J#&v2}-?G4B?kqEaC;7gu}zz zOc1W005Z%rbug&zoSxOI@}RYa&On zYg9*>6M0lyG1@aclg@Stl4bq35cAtF%(<$vX79~&kGaApYB}F2ij&$q|j~VsPvka%xn8z zUU!N~!@((t-v&`W77u#%kcsRt7SsUOd)&okqsxLtJh}R@PtPiOv79`^B)JcX*Ug=0 z3BO~Cx9toxfH$k>Cl0}m)`xr?{J9qS)+>?`nPY#-cfrKhS_s?m@8VrH)WiMIe_2b= zbU3gobo$<1_mC8JlPC(%UzU7Q@;i>3{to4nG3zT>b-UY0o1XKK;lQ~7gNDl{@f>s4 z_qOik8C7nF?l4IIEBJxg8U_!+4?NR5BeXe}nd9IE`=y&<(ePT~M;3=4XM-f!W!*$u zDuZOrOBUq3I~+-T`0^>~0BwFEv&kTz(o3@G3yBmM zWBg%SAqRev_EyjpxS4WK+0>o*aXzdvU$hii$4h>c%l>ot+P}LI|%OJ}} z6h+u0LgvE7iYyLKw>N5|)g~8UGB*V-?;Tc$y;<_vLMjTjH1|uXBuiK-Tyn_*L;~XS zgy;EQhJrAK5kb^S!xNe|ZKT9;fcq>kHpYd{^F}V-qap6MN1Qr0-z)5a@%>AWi`Z3a zHttP39lHNxB36}0ny=Y89oAL%V|8Lg6FV7sT>9Fv+&#Yr`p~VPRo84qW|on>rNaK` z2pCAnO@-Kp%DEb0UDL1rI*eN>hk5FZzL zS?kHUvTkMoL_)O-7+ZKL<2n;%n|DY$mtf#RS;5mc9XO5um-5;tmx@s5ww#aNr z?>lNKe=_wyfK+g!zIsb`-nH~;FfqdhttZ?yT19Bu2VVXeHyN z4L{(F<`X#A-$rN}+!NA_AE+;@obU@EAi819qqbSrMNq=$9Iu`H&8kWB$TI>=2=LJJ zRINb^UIDYC($aw~yweyLuex7-6Lx#(wneXL)r=Cd;RNlId;&IhADqUTW<&$hZHM2# z$+0e40b@~I)qn;M^7>~mT|{8-ye$xZJwpw=n%fKl5hEX}s%?g`VFoVqy|}n~zF`Y} zp)V;FJhrz=-CbY9cc9xZ;OM@l<^g(jKXf8$EQFC|Zh2XAZm&yx{9_oS*SG)~8T*Rs5yHR^Zs? zCvT4+8eG^M8kkq}y+<6HVY{I>w_wOz+IG4>FtkRR+>kWM|L@B`*0qE(_u_MQUoNcW z;z9l#T-ZG53i%mZpK(t?+swBU*bdZFhi$+r#^_>dkVMtyLYikdiSl}zx8C*GpW7I0 zhDZ8e!W(X@p9!4XeCO0o`3Tnc#GYWt-clM{XgZ~A0BEEy5lt8{_Cks0NB9V`(n8dU@i7Qm zCW-Worh;{` zsI_>w+R5p@ASdMFQNA6kfeoqE@i>^Y9hx}@@Yh~Wp?d3u$Smn0FlhnW1;-rZ5RhyW z@bNFDs9iuX0+YBYil}j_=Gv$k+(4e@drN%GMlm!~_!!_P+frc2suCNo;l@7wFY;k` z&E2wPUR`#%UXbeDLNjobFzK+)y8j4!_%0XtPAhQL=7BRz)Q-Fx+ioa)`EDf8tj|H= z+R9e2ygwM(9DVnbQR zg(U%fncaonXRF6o*VNk=Oh+@0SLjlO)3Lkdj^OQGcm~+Sj;8v*1Y=%psg|#Ix=?Ln zJt5Q@-TY#+i5?EpGjDir0jZx@fL6arlcW|(P6FrOw^5I73qfQjaY)&v948s!RO~ow z!wJw6tw52@c|dpHp{nuC>TPvR2aEDCo~8y(c)+L7VR4PWy-T`=l81kA369Y!_gb~- z`zH?{m`pt_@&(QP#AUz@0Ks61W{;KcZ&U5^*op2;qne+`bne?OeZ8*@1$-@lT}S(J zE5lS>RCUi&Kpb3%f|Kr2n-GLR^W^`S*57@(gwBFvxtTn5h#&K~maC3AWkLNI_tK~y zPQZYS&Z|J1JMlC6PQBM=A-6`_MORZeS$9n$DY>9=TCr@yn%1clf%J#pqVx~&XGkq= zHkNjKXJd`}&R1e9&jlU3`iTw;YyVxH%n=c(p0K`3Fwyb55K^>7P%J$KFp{Dm9d#E} z1~cB^#!@zK{F|9{$c5^QU6o=*d$1i@U=~l-?-1Hw2r@9j$eFmE-Qz~gO=-QrfWhRa zLH|PC0uteFtXez7HeM%w2&hrH>*v$u^t4N~J~apB^5Q7+`=sj5{uJQJQ0iASC{mFZ6hh_Uy=ubcr?l z@~Mae>OXvKmj*9cOobueWu?B|nyYuK2AY1xJWx9GBS%n?^d;k=)_BUik5UWYEvQHK zd(PSqR>Rn+a2q?#SXj%4*xgpn*e`Nf>@O=S)tHerE4mG&`0U_FK$>r+bX%H-sO^b6 znZ9yQ{QlNN$?+=Q2Fotcv?M9&>DjwizD^xcjK35c?QloZ>xRQf^_z(GpDzZ`MR#`0 zDSb=-twI%@eu$c{zuO42H81CvYz%?RfL@i^gbDc8`>#yJEpb|>EN>XB+kiP^WW=wb zQ9sHTZj|Q1OKx8hn9+<)54DB^w<@Y0gE@@hdriJ0>0?&>}N!naM;mY13j>oPvSGVql6tmO;Y=t=_& zcC+FQxTOB&X=sV8eir&%7vk?DcL){($RMOq-xYz4iR8k^`P7L6>-PfjN$Sw4 zseW+Ho=p_FWjEbKLv1UC1cZMIZ zcN+-s+8X%hwp+V196W4of+6JPTaenM=i7xfAil;WZHs!!On^l5*|Z9QpLY&ATVk<| zrCji0ci&0#l8M0?j9B&s@i)~dvEYkd-r7%Yud;FMjLl~y6*0a{+B}Zv6ZAgao|oNE z-Qw0`zlUz8SNauQHv@LpDj6e|99=O`Jc;r-Vi(V*B=rT?@mE~JC1E3ytVA+_&#@J? z@w3cZ|3kBs$$GOiCDlS3S9Hs_8$v!#oRR(68KIFHIk%Z$J?a(5TP$Fk_QqP=uBKN! zDX;7G9>X2)BL79EKd86yk$Qp^artYcTdL5m2wU{-$W1=4d$;ar((;;8NFl6AURlI{ z;Jet^()%DEnlq)`?)RmY0+qNM5Vyi(c(->-(JFZ8u zSg~MyuNQKKq8>C3ibto7PwZe6Or`J^JYE~=v%Rl&Y<1{}NaLkTK!TKQ;;%P81BdPi zaFP3;8CqocZTwaM|TKy*SL1egNcbJ7cU8 zUChMcLCl~_t(t?ikUlG&FZw3!`UAti^Xmcw5+9 z5$}1yMz40+!kqJZ*rn?RE3$zb7n~dA;L|m7-3{Zd3+*DTRK$|Pu?G($ZseYFHEH6E zbm&Iei{rI#o;^&bhB|VfI|?0}%Q>dxT;v@Fq;W6W{8cqbO)n1*9}4vPVva;Slx|m_ zpgz7lFjGMpXR^v6pY5a$_Iw{`HBaolvX>gfeLbJqJLw5CjtC?TE z4){RnhBy#%z}Y2U|G??!IynT=#Wjtnsj^+dS5OM@rjL*2BY7yB9#?XZ73IK!%UB5h zQ&s`X(dFw8Yc`S$t2=c5O>@rTr~gOWr$)`*_;(9TG(gU5uD(g~pNl(>XO$SOVg~|)wD~a4peI>L z<6xO*_Uw!}oCgT;!t@V-IKlR4eEf;CY%SIK8zq4g5z=2hH_bsHwoxlQAj}P6m07+- z9OEKxRb9)nFLlp%MMIw1wRl@b9)>WTcFK2kZ?^0I-aI44skFfagr^Jb2&3(Sr_|q0 z_HbKE*I@Piwpy1_AT32w;y@`l@-ya_aMBsjJOOU zQ;r$A=pQJ&1by%!^&Q;GjM0JZTb~+FZ3R{(jGM7dVw7_95>@dbhZa0R5a$OdMK~X% zHX5Qq&4Re4RyI1&xF1j-PZ0`Ubc{-E(!4<3&0{NC& zj4FqPA72U;x_FR&LOS24kYob{u7g=}I0fg1fo_tVzKt!f+O9oFYj|(>>Gg~Cka$8I za(7t=RE7?|dfN>cSR#j4W`dF{moJXXHh-KjQ9-2d#0stb`{@3kimmCs1xWc+P8_l4 zm%Nbh8w^DCAKbcd0=CzmWYRN`-q?2ZDH&HSUW7kk%9Y4jn!g?210r_!f^SJ!dHFU}sGmL^XQbQYufK>JE)obfC{ zAs}?lS1C0wIDL>plhO+?+ay~a?fEncKe@<gwp%d}P7Eo|Bziirs!QIan9@|sZ zq6OU{4i7%qV;vrd_5Uettd?iD$zG`sSLP?X#WWawOJc@H0~wPSAB%#@5v#>gYI{?h z>pa^_alZPHOG|CPoUQL?+lZh4Al1t3Q`n1Y@t#q1Dnh(eiSnp zh#?1ZFzZOe6N^-u#=kXav;}GQ13HP8yT$Nf-u7E?x_Pu24rhx1b5-g_XEO-If2@XF z{8(j=z2Krm`nqsJs^p$HM-Id%u=p*vAHcDa~P^U7*k>Ik+EQ?ih*0<|3^r0_{?r3Y^Fj0U%Ve9}R7W=$n}5bl_VY|jSFt$w6jLuGK|odgNC`kaQz*hLG7DC$0E+-46K*4{ z?^#)o8$eL%i;O2m1Nh%WwMlI~Y<7qcW5k&L2Q|r+>de-wTDJ4&E-!0fR0iNRcZ>HY zl!fLv6miOwngiSEJF*!wQ#3xaMnx&8BjLNZI37KTJ}js+B)8Oa*7Nry`QLcXq}~)B(UL9Zjl@CcLRu)DzugOUVB%-WI&Yni;2lNYnQ~G-H@v>TtBC za7n(Thw-yWDLv4&*9R9B+1pzW)SdBS5II{0)ADI<@h)EwChIk=io=P!Xjp#+bYbUu zb&!4;u?@F?Ii`GX<57q*1Z_A>w2? zjx2iLp2r={hApNMYb0!v(&2c$bcdM%5wEsbSpri;zkue2mU7E~kH7IK-Rp4ZRl33n zqRRiipc;KeUoztv|InngGT-ipUW!Ouo62sCLKdaj?2PGgfokaX$g|f$2(?*1pMb zm4%wq?IFBv))^I11jiE!<1q>qOfB;1bQ--d$THtOnjZR<3&U+oG=ykY)E9)b$ zlu_rht<(Flmx&C)u3)YL257gMiNR;3Z8PFLe~K+rX)1F2(v_ae@-@?#pj{fp_%)dH zfGygDb%M~0&jWnDVo&-{VoojL8vAgvWB#Xf&6K7?5k@e|CCW_(T&D+Rw?O}sqz&>9 z#xTGv7mI}MmD!TbSJKfS2ZSvqR6$EHJ;OORR5J=GnnY>wwUDRePAO>EnRqvRTv_J3 z`ls^Pmp^Qjs)GzbNBHkj<7Zk=k6VHvkdv*9>9h(?9ugyAd6L7&`E>yp+i2{OW$K?H zh?w`F@Xo|^;B4UYRG7L+#upT6a;9sLMuT{~ptL6A-B@61Q^nDC_U1qZw478N69 z8ewmtaBrz2c^moKBNB+xuluK(WfK`@UBEB7Iu!lFE%nr4c#TpasBK#T!|xG6ytVls z2;9p!T^QuY!564$?(y{<-q zq2{CvBi7%Vswrd2Cnyh^wo~)wi(XBtDHqNcSry0`j*p$)`3cG46_RM4qEv5`r!Yx**E94C^QJgj<%p1L`bVJ(k)M5*rx z1FaI%m61STe#YhOTT|x)hWi#lB4jwh%K$bFjq%YE%eI0VI*XNuN!J=sakXWY4Yc7!7Gl`k-#TA{O zuZ_l4C=tkw3?&LVVmha?2ObEMaN#4)$e!|Pfj_|nQ6?iXrCFAVTVsb0E%b&(%eDG~ z6zuTY^4#|qR;ylr*)V&RP{4wT9!SwxxsAN4m=V`Dn}#-Lm8n0tcPAC5g;TQ)v;{$- zgY&$^xar{;F^5brZVy_g0MGOfg#>p#qN|!+dRk@BkHMNL=rYJx)NgcnxJ#!;KHdk@PQM>AVs6Jyk4bPh z+jg!*<7i?Wl}o3ZRW-HwzyjEzqI6H6kid&=8^*Cw`)breL~65a3A5F)(P(u<9onv@ zVRU5erQ?-#dp=;wq}*jnc-+u?z=W@u6VK)najHKJY2mD6FCn|xs>)y@&-LgEy_U+n zJ+?cMj9`7vN%nu%(O$@@!{?Kh4OR4igo7Oc31#xj z#IFUZ!XCf2@zp3FeE5Ued=ox*7N1GjeHOs}Km3k1ruJq0H(D|AYAgTNwr<}feE~oSTyI~L{cUOwu{=?hK&3S^+ zFc?#FTKU$7|C~BBcV8|zsh0pxK<;$)A4tx>OoKlLPkzMKCXBu4{aMW7s%K3_b)HPiJRT#84K{;wwCFbqh6uQk72dm(uYNAM#ohqwGX4V^>NC z^T60f90R3#@&p-8te8EB+Tk#6n^W*DDs;h% z$E!j3J?8_NBz<GE`**fm1kEv}3J#eRW_m&UyggIjdp%T%2^a#~TM1w_jDUAA zOCYzXo_fR_$8D9qO^JvRJVxeBP5)3`N~AIJQ(LgXP^nj09DLH-ea+ zw{b+AObUGsM|0e1PUN^453_x-6m-8a$3VRGX82A{xp~s}(w-#{X8|K)$zBInN?1no zrwW+7{78MoM|zgboe*p|2gE3KmMSEBY#~Q(Uz1{NPDM0Qbg>3sMe7esj2wRd?U!-= z)oZWmd2oSr?K0++@*^@qDZF>8BN+g5zCxu)gu&q`AYFvIz`@!K>JR_x`%+##o*_4u z3Wk?GeF!Lg1ar*xaRmT4YrPA+)_3ZzL06~P8;hr~KlmL^wd<^&;P(2p8{Ol7#xwu& z{v*H5=s0s#z&qd1V)CiE$3@;zzJF&QMkz#^}btaEr0!xsG;zl%CW8c{%btSfj2RO% z69DGYG~|WW4!Y8l*&I5T(if_+x!-_0o6L^4prkP+Y=QFy51FJ32oR`+D_d~iGs`Ie z+_ZTPXe(3pv_?&3&j1lp`=!)^j`N2cIAUBuYFid!*I~x-w?x>HIVO<;wv*utlp2Ge zLu__cgTTpidTRZZTV8D-nFBUvoRjYzrp1PZ$+IM|k0K%+*-LB0QRgKiee;XJwqNIl zYanb3LVBwb7ih{jx`;=ebvRIwQb0y{)?#d&tq%lCkO)tNJ|ALE411ukw4g9tqJO}M|Ew%OAx;c{62R3H=WO{y5QZt9nq}m;_fk``YDWMfXkdC3b7>)?oYY5UpQn#cCa-zaoKuA3G}9MrhP+ z!WeT|S?@~VSS6zeC{eLoyzpjcn6%g2q_5Y$^eu7a`_3(rIwUOBiwy#(egF#?lI(K- zfx$y~Gc45cF||p`lmp+C7lW4QHj^{E1F+Mf@!6}70ua%_trwY7q=>ziYTxTBr+e*| zkUwJGP_HV-|JuI*e${h)p`;SZ#-NFMluJRqXt@&M2RU8?W)<)49%(HSrFbr~4wELq zc0JtV_~XRwP5W{uOUfX}!QrfHUE+|>V(HTj?5zP84&sH=*MV#4oTya&H=n)xPKEDc z=nmlJA!OH1RL|MEo*vvu7z=)|ue2)oUV*HNzUgFjwy5QChYApuVOLf6!Wdgv)Z z(gIGITF~Zb;9cHN$YCJ}71KLp6eC(MA!`J^2kn`f4;6vk(BKIu{3P(@ z((8GLus5s}N)jP>q!_~*CVwMyI!DOU@z3f5;|j;eP;>Y5lRf(ZRQuH>-7M8=c*UoX&%8St&bUP(XFuou6z6oFg8OaR1 zWcP-E&=M1asoW%p?IhF3yj}t8)l-vRN7-kAWoTw~x znW%`I%{tN=3lGlmx8F)TxvT9v=!OOR8EH;ySd zRM;p6ww@)E-`2`?qgR~0=F0cfp7qj8`8p7N`ibUBmQaVmr&K+Xg^(SOTw#=^_ii~) zT&*D_{ox}fu~SV{dmt~5?HT$@CxMB{giA;W_$3wsdnVEIrpN==o(u0e*+u4}AE0yZ zKsDj+4=BoYuZap}sq_<#WTm|JYm|q$r~cwkd_?ivgGf-82f3+WE40cH+jaQ%O=Rpe zbnZ3+%%!Vn%~03DR+<<=t=K*5(HgwAMcQkD4()`OP~Ux`w?D zme_hiu*D5&+}*2Z_ZIr@P3$JAVmZO`4$V^i+mW^>c92F`4TQoqMu$6lCi8!|dh&*M3NIp;j*ocp@3>$Vx+??7a}jDV3*&XgsqN&1;gSq8HA)(! z(vEG6h+gxLvc^Kv%oWk~Xu@Tz1^pw9*L^MnNd0YQ2My(lY--lvu`F1~^&}(ScU9ZG zj7_4j7AP3+k z2{Y0CSdRtfr_4SS_;Mx^ewzA(w78*OfAc;b>)bu+j)a)cA1ot88Q02r3T~Y^9ecOg zirK&flM`FAE1Yeg6Tbe{yUH}8$d+r{M*gxPeHE|*BG43)L+rZhuI2Gry=iFqMe&!Bwfqvl^OYC%Py;!SHo z0E(QgYFDO{O-7z=?m2jWxSDRE0IA1JAm!vO5fi~c_?@z1%xtR+n7?xBt(^w>-zzy4t|w356UI;LG{{j~0GWh7@4? zMG#7pV6eX%vYyVXRNUWSC`)N&JmI(B3Q$s{+eqc^h5h(B! z`<#}sgBn%PFWBby;2&xh3*%BBE&CQ}R}OA*DnvA6nX9gZS)C8jaD~rA$R4ucWX!wY z(!@pD4qC)7=bg=~j1v@2_cs8Iz-7g}5EpqF&k%22v5ZP(eDBKToy|;HFRmmq42E+b zj!^CB-ZgZ`2%mC(3adf$KHLCv+qL7FBbzn;$nrJ@I{@j=@QWMZaXx_0lbN5pOV5(y z^8O!740bSnPi~DOaLokf^p<$^YJ)lsE^Y|2>X%<19@*uvqXng^Arb_|%fTvajAuP3 zIoJd@J;yTf)RcV-lNgyT&V1Pzap*fsg#=^FBnlnKv`HQ+tLh2*Z^8dnng8b^tfOk1 zu+cQchm@O~Pz|KCn|aZ9DpW#Y28kv@;uPrr3pL*fgq%6_nMo6Uho61$)6VDMcw_*6 zX^_$i>1(b>{JYv{aU|2OEt3f?y{PPhTf&gsD-uSS(UrRmNBiK5z@9)wZJkf9NQ?uj zWYv#gys^!4b*Z#|B45(!HUw_34kW!1va`Hspc=qvC($r3myvSS8H``GFn^^= zn}ZF|gN;3P;A6tMag@2gHZSBaB_0bV3lqYNV&jAxRV)!J(QQ^FzU+&)#GpT%@H)** zgmDL+z1LQd_B4dxWGYN%g;1`Lvnz8ANqQ3nTupX^&!+kVfbvdj_`A_jNOkKf52Pf_ z=%jz}BNM0^3Tx-g8wwVP%vcQ_HUGXl0hCV6L)AOV09>1VlX3m2q|-np$wCWTj+*#y zbd}zavO<}kP7>j#+)%qHlvYH^qQNZ8-7I^h2J53Z#k@%u2-qAuW;gLHT;d>)NHl=4 zml-X^sVvoCC0|V;&7HKp;F(S-2L?i{y6|!jnE8s(I%hCm~+$S2pAe1xe9mwauos8@0t&GROI~@tp2vPoMlMA~vu*tRlh~^D1}UVpz~im6v0=tlMaIEFuTU!y0esa0{_tO!2S3>opa-urdvIql%(dMD1G*fwYo^?P8Ep&*GGf=v z?@s=|lHH?HA{8KfmDz*i(y^eyT3^0l!-S;WF@2V3%(>8mo$$^FY+#pa_DTl?G{D6T z`Y;EZmzfN~CqNKEeghbmelHeKbHt3Y-#loJ4ExggO`Y>}a+wDxGUG@cyQKocP1B1Mu^DKx5ua2nV1tG4nledyAH4rQ`2lQW4&q zIs_$7W?6=B!w$Nehc8^HGg$1@3Bln$$#uipazZ9(jqS}p_do?vqvg7O$rA=q_N4`v(8vds=e&hk=rrz4Z>~4jP zV(G)o{IQHJEDZvSf91M?BS3AGaYM0L$pLNnxO!vw3lOIck1m<>;=Zc!z&lf6pfr$) zhLagfI?ki3VPm|cjAjh{H~=Pgv(Wv8sBJyjWfcu|ESy=P1NLbHkTupT-V}6;6#t6P zIZ_TW{U=tManj5lR`a3SGW@LSsh_<{X=Fec>Z=9{*8V#!csk33o^mh=9P+!U(aeyJ zyL0JR(`Z;j(UHO!n7s?my1xovV4Ug99qYWPwoGAR?IjQecn8|R%JW*+xn&SaXrL9Q z!)Bvd*-Q1eTy1P+6L#;gWnBOPLFLv*RVH7F?ul&-N9M@2XGvz@c> z&!1S-InpqB>m*p<{vF=^^D6{9eiN39_-T*6Tm9eq8kB8iKHg?>^5_8GPj)*#%;qp# zo1LKV3+d+h#U}J#iPsZF+hc&H9*!+QaTe)Co|d3HB3#+)YWq2}q**SKryq{mYm=WW+jvV!v}vn!scX>t&m+VJ#lk>i~Agl zl#miNNbLWYh1}vw8SA+S5XUdy0C9;fg^L5?X}X9yJs2xc+E zKoRG0T-x2Sucxtx2kt^|ZN~7k)THuUT`YB?K=l#(r8HVP)w4Y`H7ZQc;|6D zTF(kWjGcA%q&LgYBAnTQ$C`We_e$v4(z8|cbvw$&T{P|i%Ks@VPURs`A zd#Sv*)IOgclrfgwSnLV%V9_k5t>FD>=YgLFFz30fjyZ&pJ!}Jz4y(nUNv6n8MAbq#@ z9vce!t+jpTq7jFm54fYG`>m0NwM4`#Tt9p_gSq_l zF@gG>7zvar555k45(0%a(5Pjer0uTgRV)v4 z(jQk#hSe!Pp=YgGl|rk8m!^~0e8pymYz*oAcX02gsUqAL4U%9xB0(++D#}4}+Mm!2Q`ztfi1OZv|srUE8|0 zdX7a^pkkP^3Y*Eph74~4oJT=d5*1^avI=*BO)}P5qxnrD1g^FV&gi%te{c#GWSsx9 zDN5FgKodnt2FvYKctji=yWDTEfIBfx4B3DdkNy|+vCJDA>E?lc?weT7lo{w05 z^zhetc3kO(U?(_H0NR_gVl&v->CD*>j$-HnM^BiNU6CE$RsN*H;kOwi*b$&+AoRr= zf@?9XVsW=bUsK2b?5t24( AHHYz^G-c8H&yK*KeiT-}$Q~aMJa*Iglab>~(M_wp z9wKB|ntx^aHj)h%WRCOb>JUvupd@~WTv-Gf8e}V{XQQnZ9cSwm-NBKiHC5e#ePV+a za@(v$Z$cd_QRhI1#<3*RNb*O=N65*WhVC$hnIfF|ces6Pt zMZx0?|I|hQLY9wLhLtt6t5vr~;B6}WEQ4>4<$FtT2G4HzPV8Kx=V2 zM|gyJ!|lABT^s9==e^q2Hcu_LbKBRP`};fGvxyaC$PThc8NW@0YLw}qDV_WZl9PG& z)~Pcs3b+}2acy~ypU{IoY!Y^0%&EBK~_{ z1=>3B(<`WUUdfWXm9^Th(o@yWLLe^d4P24<0}|ed_~2${=ERO8*|fE4yX@C z<-99}{)>-*xxmXiGbrOKNNuy%Sj`?DXefnbx8J{jkxUCIIfkRf(>`!*!bBPLV6CPs zBad66tmMRc)Fsch`!uW+^Bi=ik`H=#F)tS;gf8s2hVBEWO~*mtwCVArRAU{M+{HMx zP92qXZy}!(rkI5%?@criZ1y)Pek~I-#J&#qFj1l@^%58>#Q}ZZR|LsiH!9VTC&NFQ zuaV$uY$`<1P4v&R5V-iGLkbYjvHRbifUa;vKh8b9tggU(TkBkw;A_ytLdRR~iO)H- zWVc}`e{w6lN9(OVwFSlJc8{^*%E{WhO^ut99`HaJ;*$j|!9SMfKG=Yh=Hq%c+P#TR zjTS=j(Vsf3(6t?mWqtM4Ddhd|1O%?Cqnzap)wE`a&v9@7cw#&%{W>-MaStn$z+C@V zMXE_CwM=>oxNHy^H-N$h9G64vUnf~3Y0Y&yaqg^gEF91wE~iy6?48p6yCBd6Z$MK9 z(wdEd^*H!%thzUJuNl(+w`U!q7a>)=t6imMzF0;RJoFRwEu8&h=|e$@aM9)m=Aw`_ zWJ&+FJ{|eY)>Q-FE`YPnG%tMgcTSufm;#v%)6lub%Q#W{LfKxSvz^YNMYo0#5?c|m%njQm~pM2akUEIqN ze^&6-r5$9POF9qs@53!X(74uKR5iln`6rnlz3+xX^mjAldHUM9V=VFFkm`+UM8QMv zVGb3w{sp+i<3we~ z28Ld~#(+SXSAu>=9>aC4EYI|uBKn;IsgRS*8$|F@%!9$jqwBK7f%&Ip9=i^rn+ZZq z#d|;!s_xZ@^@pXaElhJvXtxmKCHnPXm<4<+(AQmq5J1VP{62ZPlCjJRVCXr9957-0J&S7#bx4sWZDiIfUs$4CQtt74cmv zJiH)=!|U4KDj9Q@#fdNuD$Z>eZEi-1J{*^d9uUW*&UXU6b!~G5;pNc*HU5Gz{QySm zAU7NmXI6O>ySIvC^<4u`H;bt!Xoz#P$t|t%H$kEw`E}f!_c3NLoCQF})y(2OWsS2@HF;ByPhwyV_*Cbw}Q($uEQBJ7fIHM0g z9FuitWQ|Ng9DffDfJzQtaU~B8$lR4NJz`4_^HT^jVP$4SU-M)AN^oj^YB1!>j8uMA z3OFJlsbh~oB5k`s5b-)_!bJM0a%&*2QmPB@ zk>ZjU9Q$e#5zEZ^m|q51tt_8CFknwm&s!y{v9&V{$ASC|SQ74i2~lifdfX}o5L1kG z6)H%}uz`QDAtjS9>ootL3>@7}UiotM(SiYl+`r`5du*&8?dV1lN-prccz?=e9sPe3 zaaLi+=$^L{fgWsWVvNVuXAfZbaz%aWZiLHnCDF?0+aR^^PuBgLCLhLk_0lt(s)781 z@AWFdpbDNvv3!m+>DEEXYqF&@8y}=tFg5Vf=PhZ)&I?bSLWcR zTthtVd|x}>2|b)teRwv*WN&unx)!;XRceJ(<{k=Qa@K53Bieq<6UVR7@MNDV7n5%cA_36vtV@{lb4(&|p; zNe?QL7p7bjqX@kw!H;r#q)#M^&;}FG+;@}{g||-1a#i#3bwzh-GHTI8}T#*#njdB`xib_6r!B*zTidDYC#66P>&b?D-oGiZ7 zvUa~8VX2sZqKt_6cXFEeshxz`f!@tTC z*+ve7C-zW$YE5S0o8wqgA>85(hpQyAZ9RBlyQKpHsIcX=%YBN9USR)iRd=j&Z) z{j{e!n7M53Gj{XYc!1Z7AM!lmxDC@CZ)-ewXvKG(Czg$l|EH#&#pv~n5>?XmVNPJI zq2f9W4ae@f94F=7<;A;Yo6e?RsSU9PvZfuY={b|^nkfYgZE&L(frZvLsYaFA6KK>0 zK&UI&<5MZBe0O0T&jy zvGbf;4+krt#|}pq4v}hOosCBVYj7^RxIz+rBtu$G=Gz6LN-oMY`zOmuL9q`K!IAy>N+kFxEv zpey@Gp=^=htvZ*x8dCroCY39s3o zU86>{*2svTW-fcp4e^)eN*4^p-9UVXcAtjWYFL%d^6H-*+XXoeF6@ZECUSC@I`^Df zxhC=>&uxlR6!NMS596#byTV$=p6)zflRJK{KJQN-oUrFEhK79%V02M|^`N(Iw;Ki* zm+m*i0I$C7RH2!FZV@=N!HVhoAgu62jR^sMZpsl$3&ep0@^hLt^op&Pl`?ec<}g$# ze9iMTxa+h_^n)f@b+7e%-IKu*cqo~XpmScOxWhi3C7W0Ye*YhMyL4j*k_xC>LDwa1 z>VPzpMMgIED)}6U6o7u$f9A`37HpRCY&)K2Iz4&^L-)$)u7-uwM%YMGv@(+y&W3JX z&9+8II3>PwtW<4;0L4(H@mPUa!}(>78OYsZe_iD$#Rb-TGKrY|7PRYEnuGB68Y(@ z6idL`k(sz;zCQ8#Vjc{PR?9G6a}2rYB^4^Shu|60RU(NL!%hXd_5erQA06zplPRI6 zAt9H@_ovfwK(ouHU!edB2Ry+aF3>bTd^6Yn%_8KNR=r$%tYOFNV*>P|>JgWR+$_>CO}mz;!t_&AZj`LNfDv9{g{z8Z^Me{dw)Ti{AvlR_-)g<>Om_ z3$&_2AGk??$t}w=r-q=t$kmi`yil$%k)9i)HnZuSzKwX1nkrm!|9H}6YXtUh6XCErN@AdCb#f`)Od$qMzU7M7 z`(ITHF*D2VhJ7@fftI~$$>L;sE+E-*e!}T9^D@G5VEsD(VV)Q#z6T68qhO5wELMVY zWdnPhGJv%OSyE77hBSy;nroRp!%4~$)OG)5#aGESliJwj5b^T?nLm>g<00upmCt-f5yD8ikwr}0`=gR?;w-Z63E34F(h_Hi4X zO;?oEP60I)T|5&wvCH%#uWv^74zKO>3iQDnBklH}2-YvZgdK9qjNNbBNM{P=xPqO0 zc*AK9WBq=e%@&TD8VC1zobi)j@7!9%0;&)w84T^}&8p677lS&gBfM(GfTx_=jKSMt zK)+@`fPPsa!Vy< zVh#on-lBM}y>_O7!SF8C7;q0qTTncRUd9Auyny?u!|eMtttAKGiTbOdRPov;sFzVl zLubxSXXsZqZifuBSXcTUeGUB<#-97pt;CWR#s*LA8Ko_Lu#w#;`m3Zc9Ej6S8Y15O zzn;I{LZj<`h=of&J9`_W%79I=``ct~t_jhvhjyE=W#G{qC0*4V6uQP)hePZP<#0X| zw+(eC0eP@Gxco0852nFRqu#<^gtU3mBE*?8gw#6TdGL8+z+rt~)0V!-A+Gmb(tkjw zHFl;I?7%!DY6F}3(Nn%Z$X>uwND9Ht41AA+t8&q<;iL;git_2&lJ&wT#|^8Y_tx(h zA*vb~(5=AG5O=FK;t$oAClItUgVU1b3-|d^eqw3;) zd?PvsmmF|%;et39Cq*!G>4lI8jg1m$(q_!#K%$=~=byJ82DYqh82+%VbD@XbSOl2x z>XwY!LJ!_$WSW->GJMp{<1N_qhkgU!2^8OKpAI$Fd7Ei^CjM*T&-(CkY66h3&DGzy zj7PMq3!EB3m=^Ooo3w5|ewMaVVyz+^kWbZ}Rx-9ueQlk%QaIs*8J8;gTUoE zb=d^hRJ=C@AFVR?G~Qy0|~dqhXX!$@xe9ByEeT=c&TL%F>b44;4*s3Cw?yIlizA)&fx6L0DVB&4 z;Zb=uBfJb)1Zu7?ktjFosL%A(CO&L_dDGc`_3sGebQhp`cI>;wYGiFg%tljP@DPYR z=y}oqq=S4u?04d`TQ?h`kK>I4%V_MO-r7^C>cHGG zzZ77400Hdzwx5)q$`cHH!~e@r(JhWT482-P1?ZcGmXBxIv7b>pxIX`mmkKGK4;eRn zEJ-(8qALfVlz+Iv9#5oByrPf0U-8RBiMrux%>h4jr%#@dM(lIJ=Yqp$V{X_NZdGP} zi$j!LL3kq#gK@PxQ@Y={@5+0ll3adfJHHX?F;yiOBWT%cANckvr%T-vH{x&zDSod0 ze?$$}?5~Q-XvY7G*fZz>+XJMp#ZWFy3MajmHXVkn!v_+@>C%k6ka9r@Hx{WoCD)$R z?32XnirPDo+XI2eeQn6@pHj^kCilLcPiKQlA@*j>9&j?h&d)`Y-!7Ly?MO7SBQ7=B z+90``auXZLvYp$?o`2@TQ`RJdGk#8n)eL+AxlO$T%c^w|O6ach_VCKs3tBA!Gw{}P zt)05k_d83-BF=q9uk-DdE1y%w9G?!to5W&L3~?Vh@U(EiNX`LUY%*cK-mUH3CU~L5 zwSW8p1`nLmx8-j<5G4`Ia^K=+2HsmR`GSU%=O&vAV(=;#X$9g6|jZSHJLkNwxHbK{1_R}0cWN(-Dcvvj>? zJBM7ncU#1HT78I_4?}73{Q|f#-OLi84nXi}w--ShIDD>NPMvQ8a7g&MaD@yMqgQQ{$!)C?G>dYvduL8<1;@p7I382xDa&O@_S=leEIZ@?53F_`q(H(SFAg~h!LdvGkZ}KkhO`xtEsc92^SwOz-FaVhjS|QRd{{t$k zXr4aUKen{8%wuE@>gCbpkw6+q_k02NV8!sA$}FjE{$#d`=03g(`FC{yHtfujNQ-K1 z4Zlr&c*EhvZ|t|E*;l-&Z&d(?y*}lJacjw0??;-Cq;LX+{SsXiHru}WKwFiDF-qCI zLI`j3%82hB$Ci-`>T5##00HFipfp+~=<)hSL{83))#5K53OL6v9IAqrVLR`0*5>^L=Eus)zeS=S?;G8( zqLBS~f2bx`itEM?v-SbVbB&ZW?x<_J=~_nsDelpyaQ%-HPBuN{V=+Dt;NjQ5q_Grj zHm)0nD~9tR(gmPQ=wZ%B?+fVDsLHD(kv6$W=HJRGcxS)g35d;#qZnT0d@)bi2!a#9 zw?2gBQs1XuKle+?P+$Bum(%>26ml_xYua!O=h6!G@2J)KUgIDBx(pceZ8)##zn#6o z=?8H$V7D}DAb%uLkMx5gGr(oQj}Azg)UfCSv#JqgLlC1&= zsy63Fc4Prw$G0lf5>OKpPRwy0(W7q&%}P(st(Xx|McLSZ5jr8qm@7+gTPuOhS8$u6 z015->5pBm>p~TMFK$F>$lZ@?C)ss?6YXb*BEx#-GR<}+8cCu9@8nW$kdMj#onSUWc zg}mndUA6fps4qv%QnYonz2zvaJp8ho;7mv2aCYjlRi)#~>FzK;FRkmqKh8CGIX}7X zVDp=jMd;lg?VApq32tix!}H9ppwP{(Xn>^164@rMio`0nle>@{TL9-%^wBU~xGOQ` z_x4?F&VR07p!U^*Hx#FGcnxvTmictATxvFM8}^mE)R4NwDE4Yml_^3dJ+M!?km6R> zx4ZsUF^cNM_iE8{1>m|jfPPX3}x3Z^ze}UqWg-^p*CX@QlGL*Hrp`S!* zIhxc=zG&GtLAahsi(!Ytoqv&F#1-GEIUtM$DaNW=Dl({wBU1aoQ~%#U*nD22`9bMv z20Lz^UJEZ^NMqJtGJd!4RndAZ22iiX%fHP8VA+FC#hVz@IaEN%?MHBwJ>cg<{_ulp za-YZWLOb~(lj!Pp()Z7}clrPvXI!HZm!4-mavi33 z1=W%0Qn5^U4le+H&&V?+pWjEWI@mHwnuYl{q=tPl%X01@xY~^!3-ogneS74rehZo2 zX+TZ9_ojBG)R2bz-!}sX$48R;uO6TzrvQ+TIxbB`0^HMz)%hLc#k4-=^_Fla66P`^ zp|q10U3v+0Gx{$3d+U)@U*})@^zNR%{N{Nqey^`<&F3|^w*MB8_@v2hYo+ST`eW+w zkL&l3FLs9OjP??86d+Z0`V7;z2Ew%*676dGw_LcOd3@IBHm5137b|NXIx4h~s`?M> zYG2mwg2(vL!ze_>a@cN)8N=w^+#sc!8#_9IvU#sJJApM%Cm^>_<8yRo=#s97_%ff~ zQr}fb_+SGGD>tj6<_eFzfU!l4*GJ(=;(C5Aa7fC*v%@)^6e_($h@1Z4TIsHnDBPhP z1d3P(pxa7?9ZF==%2+@7Jcdo5kc)l2P3DHC_7Vd!2Z^_;T=K~TN%cjz#%M34U49Mw zYT#)%^-i(nljmNLf(k|LcV`j>g-ivA9FPCYNVB0qs;xyjXwM@n&u164G<@10-6~JiTYlAp4pU6dB@^e)h;?AQN|H=Bm_UQskb6&t^6n8vw`sKl1)LL5eZ{|5Di> z9^B$9Cj~izdahs8J1K~y*6a!RUak%(JsRgi%Utc#aIK1mR-&3gNg;fQNqz~${%=i5N+kU87S@n%Hn82FqSr)t$@w&C zn^mr)AT`%{1-_pPADp#JC*+vGD!3w9DAH&5ctXe;F@iJ>oh{}0fQGgrCdl}vqzu3-9_+;23@z?oZ zNA1*3(#!@%R%a_g!33irHzKGcdG`G)?`tBrmTCsJuF@8&ttI7 zAt}iBZ+J}34e$dSN9q|j=?Ten!58^zNi5M@J~H!TFs7qq*P6`DP(Xa=bBT$;Gl5fOL4&Ew6>%0H#9Mxi<{zzXg~d@Tu+#K%EM2nQRLll-)y>PUK%Qo66w z=yuJMfkravWMe>JK575SA2`5 zSxAZeF!X{HRdES!5G4&qc0YYTuO{1svFYx zmLe34M_6>v?a9;$8O=XgEBT#!-d1yK_#$V;h7!prPbi5KbXg& zTS2N&9=CJlvx)d^gh%El zd1=d_yc0$bn|Isnmf|*YbDrj0=394TRFmjl)5RWpcy_ZQN8o2&V!L;&pUyij7C7Jo z_R-Ic7i?}C2-U;kg3WK$%=9?Up8qVLUTKDX8KY|px5~ln`8@-{Suvn5l^sY}OA!*y z+nz4dr@yI^F%#I{3c_160B!#OKwFG=Yk(9eSoi%~$E_c4e3qUa9Ar&O&KvXCKCxlb zRh72sCtE%uFcWyU_@CfMazHIGWMGY8<2*|>07gll@Mwr~(QRTfR;xBb!Oz9XR^BYr zv8CoM(bWjHBvKh?_iuC~#1tV=&YT=g4N-)(+29-&0PbEGWt5;u&n3^P44z+|K2T8P zh*q&K6@kFuTGU422)}pWS2bn%akMis5+|e!r8AW#1p>0-JU5Wd>sts@Rh-?0byH+P z*~-L^f}-+^K)@v`^pq}20^)vG&Trk7Z17d#O(9wEO1W`-u~j==*OZKA;ZYbof9r() zfPX_=!Y@iNI`CB-<5Il{)S28N^nzpp$$vpotuAE@@Kb+Q@RT(?h|lbcc6orD{xt`fjR>s zu3O(RwfcMPpe*P$$?tKrJYfzkQ^24PYK#M%_y)HPq^qXv+LONcYPl+vFylVYjn1GP zoAn}6D1RBWg0T-N>xtHig7HKuMt6vql|&!`CkcQk)6{v$4@k+EBTys02q+pf-$AY6lK@I}aXg|4Jk6JO@1z*LAWBmkO<0^Q+;-tmtj*Rc z-wDs1Do_gY6{WN$XQ$NYtAi1ASSV=7@!ddeOb{&cVDuSw zIH<7+2B^YXJmLzJm zij_#rC0og?z^AIjSCSv0Dpr@Js8OL+vA|gEC>I0=P{Ps&m&T3jCH*qH-)a9`j`lO^ zxRPdJkBLrR3^%!TSlZn{`$BnSg%^=4S^^P|ibj~8wTOnlh(5eo=}I$?8CT-KToWMG z`MtYZ`y)C@m=eaGv|9 z^fQ~~Pm{Iy%m-{!61qJvWorlE4JBCHX#KM#E?}wZ zz7b)vLXav}zdFh9t!;-|9@E>yhuWvjLfpM8CSZA2#0+M#tR=O|Yc+IW9AnP5o_ zr=8&SG5EV&>*IG}ATd}5tzA%vlXatqr84E3UHLUCDhvNipq4s>!WWc*`?SvG1{J?1 zUF(3vH$P)z<6Lgsexq^NtJfssGAirnWmR5uFPx((?7EvWd4SgHm>P0^b)09*Cx44I?$F1u4H#H`?3-Crq{0;UqWiE#3yMk` zNa$+rM4*< z>!eE0I)ty>NlR9+#M+8sm-@3~V=ohsnc!BVVDzQa5fcw?)9loUeyS~JlAVDHKo}W~ zm{$3W{D!7KndbF2NcDUj+XX;8s4SzAZz)lUT{P+hOn49uSMDscA`~Z~i}$#db{=g| zH2u0lII4a#8vR5yEv11L$X6uruztL7ZwXE}Iw9#xuG#3J)cCTk&Np~TQ_uS z7o$-nup=Li+S|U!j@_+${?s0pYCHM<{V&}qm)Ri`r|ChmZY_09`^VQj*dh!VV1?0I z8b`TkU5XwW;SS4H*9trRdlmf0g84)~UBK>z1XXtmLj6i#b`k94JHG|EzNd0J3$VQO z_(%!$k%zru2Qw+ClBUcts=R0Phjg~B7%>=@jG;Z`UAep)MccCc`>-T8FPa#S%q zDNG>((DOEDp%L7A8m7gVz%b@0m7Uv#|8Q&8`&|ZAR<4~lH2T#G_wksRgG0Inc+~C+ zvX58n(GN{L`F~>s^^XX?s^7WYK?%kDtD!R0V@NRP+ur`u3p8(3PeY1QXWkCMOarax zoByb9?V2=T$-h#R3B||O8YOi#wW;S9VZTDTmUrh4KQsj0|HRcDcxKnpE#f@-0Vn8v zFJbP<^c-2qDt#BXUI{WkV`(Z z2bGw{Y?NJlv(_e1g!QcF*a52~5d-TxSoF5GDhCKAHqeI);Fm5lgfWbH z+fOX;Df0lDOO0hm(-cs_m$8!uedr|=$qzp~1XHKpsx7OuDj#)ih3c=!y}P1t>kNzY ztpb*FW!JG65dxe(=Za>Mx}Q?AZfE(4(o)ZYU5dF$Iv!asH#*Bcniz}`+Mrc(FF&P- zL!ZxGN-Tu3Im0L~Xf=4>a*)LDKP}jN-C(Pg8xkfsZ^P`*lwh-_4Gd`6k1~3ZX`Q%+ z0XR4ce)m`^Ohvu?mvMR@kXu`ywh;0ws+V@YIFQ)9l%)6WIKIZ9%Q0`auW3r&SfUIi zW>PU-lS}v2!xyy6>_xaiVS!HttMK!-s*S8-AT(B~p*tPAfs%D+`)2T&v3;CuT~pNmC=$u7n8_d_+g2G2^a%e`BZ?;+;5-ss8o@id&KVU=e2)S`^L0uLNy z;lj;w+am5ru1(`)ZC}wUSgdU}tOb%z=dZ#IHMF%lrUm32-8pjb{DuHm8I3cMQV?yS zV`JjiawymfQ`E52L_9rvjZbZvvnLqYpTVv=+dg1+*Z*kUAfIjiC_`_2W?GkYIkFvh zlgWrMIqtiBAF@Oc){(0<3@r!?S1lY$h z(LxrKxx`9kRq+nCXPC~>9=yNZG_6MC88OmNEiP>3Z=m1tl$H6`gxr+wu$5E!Y}mcn zV#ke|5o%O76~4B7F_^a)=T5j7p@5S!ptN#Z?HQSUzC$e)1`a~inK$PN5_Dyf-8Oc2 zF+5i3=(U3XiZ=d^}e1-JR;OY~$4WPsW!In+l9hhD2C)#ocs!KrIQB$b#| ztPNaTs+73d8kN-Lz`oMh{R)-3elNdD5(mE_$j)N_(i(IBHpueI>ggrOe;7~U>XzNO zwAbsz#76O{bC3Y5HFUytyH(+f&ZApvWNvU=XqMWx4^sx*gf1gH8sUHfY^Kn@iY0h$ zE21$E2H+z3)m;V_J56ZhLexjElXh*y6hnNV>zF9^r}^Ps7>{$1>W}YP8b{ z5j%~xnsT%0GF;ax%s(BlwPlTX>YB;UsLNv6AWa^lCn26OD?h(YS5 zaMAeMeNUu;8^lH_Kv%)e@*-_uZ1!^8hm3CIyOsIQirLpyzFEnL0VQhe9nAZX6H2Rp zV+?@vc=#t`7wjWgOo7e&Fs`KJ+7ENs;fJL(&A;J3nW!^uW=VH% z5B^b6Y=@A3(;h{uBqU!6~g>k%qw{hUyWk7M(*s7 zV6!h8(^(|`CbgUmzIRwR7&3JS*k@jA{9-SYRvb`EFfbeQZ`Er$T`9vtSApF|M@SLM5{sj( zjdu0aHwek&Go0<5`d{o7vcArmmU0p+6kB|nRopua2wV&rcJe&f^K=d!fs zH@Cq}vcIML$Hf=95zM1t;e_vqkLgN?>HxLdHg~2sPl;~SP}9%E{~FJHp_`IUdcj{% zZ2Os%XR_*Qd!gaoOmJlTiO1xijGmU8H6$Lubm~E&R3ER2@z5J?@B5+XdPfbA{`?Um zl3{xF-E~;%*O`P||CZcU;3u=JwtlmTOVqZwry_TxXF#!^ zmy?WkgV+*pu9D5LR^(EHV8h)`+CbMK`Q@xGCjbqeKuLAEH`!)HN?p-TZMm{8qNS z`neh2W#O?zE>k^Q+I?IBwD6GFXgkNZDf4W11@Nu9l!%T#)A*&EOxh>aC^?I4DBreE zHQ@Drcst!f@mu)rC+(enR=!QSSNN{PKJ~Z%(lL_-lW!VG|9FA-#u$+rL0DhyP&EFc9eTr&w<2j{$F%x_G zgZTR-nc02BzXt}K_E5sDDi;}!!tJj30VtglI_q>jnue{z&l`dCUE=tiPPo`JXe!bKRBDx?RT_Xs<}k@Fao$C>EFE9^{MDmnRR|)y=&67i7eaQ$Ca*& zB<%>c-7c}=i28vwSDCF|2t$3>X)LGFd{77DZI`PF7skxXIVmr|{-lVmZM-VpzIHIf z*XyIyft1FpTcR6$-XPFUTbk*bjZck;^)}HbO)R)x&Ksrr8?R9+?;MYO@fgUg`a=ls8 zUVo5=Sa)9+H2%8t^*ASmGhONCz+T98h*bV?b%$PC7|gf7Nho>8$NEbmhl60lbhWPh z&=$jrpkY4MR;~zLn~JEoPwdNUW-giY%OUN;)->(1cF8+fLf+qQfPCAbZ+DU5pw45C zgo3EFcY@-;*zWjpS3|y;!t61Hp?xM4wnUAr>y@Ciwfv1@>8>RBC228Jpr2;uaJQ&Y zV?n9wcETauqpM)!mIXEuaSI*QFY46p<7$(AM8B6PfnJYf(|={a-flhoR>R}F-IrRL z;!Z*;CBsDIa^J+&zWb?KV3rSbN&x~?M9_>YOW(x8$`jJC7gJ?}unN1$)x5hZ1CqN`SfD~VRbPKUOXhxa4Efdzl1~EkQH_X86fu4IT+pOad*OFc5Tm~c$4^yOQA}jOxT;G~Bmx;2WqIxG{AFnK%y~}n2(YLE$;8)5kj8-tK1zXPgqi0E(P~H;yO?HhErBKZA>0fO5jpDZHaxd{ z!!7ga-wWH`C6BWcSOJUSHfet#xn*rkvrCx-`;Q3ccY8iTRk@H zpsbt8Qh%Oz1}J(Q!9tY;O1sx?OPJWM)IYOW(L+}J#H#a=l@<4b6d8;YGB8HZ`n|Om zYNsp<}r~t;Ajo z+H}4Lo><8x6(IiT_{AJdI4>revR2dkQ4VJH#`@mSwmt%!4`Y_%552SLY(7P8Wqu5~DXw(lpGq=kVnv8js+9LLLut z&#A3NW1i>>b;R3SE?LJH|6^w2UQk&$w|VZu*mTR&2iAu7C5Q$_02sa)@I1UY(g9Z5 zz?qAJCsP7cBBV7L0f-;?l4A9kd8JOdFI!!LTy~;T=dOqT_7=OGf876a&CI%#&E*iG z=Pr9lCsZ zT0zy+qSblUP`ASz)Q!7VFyK>zxWC&F7f@ke*rU#9OHXQMYCu~;lI-4H9buk-@SG~7 z^!q_UvsL;z_Mw>{Ul_1D6vjxsqku65e4G-6BG66{D^AxX0#^dl)|BpB18$0hzSb&# z0bIoP)+=MS!ve}ll9ttTFouMK%}U)gP@Ons$j{%9)YcJe_#BMK{YS>5qj*_pQl}K&nKHDUihxV zdiLOhV?UNR+CshyOgzpdRVT`zbKy9PkrJQvr7a$>dAtBK9a8Pr!bZtX5)JaU*4fC< zOM4;7SWaF+_slNvqcP2pIs31-(6I(s{%JLyYHw{bYZ$~>Ty<2@yTM!;AMt|E)^@s7 zUJAeqbdyPy>^T{lMkmD{e+{CL zRN7;skd;?QwoaY0TNjviQF@%c8SVuejpXAN?ebX75ilF9&CY zp7PE3kO8VSQd%=dM!>R>23|+X(Zx<~hdV&7M3|N3A4Id=1S1v}^J%`L!NmL2m8rFd z7LTm+%d`oQTf*+i1Rqi3ig0udy>x2U@_krM79JXJ!DT5%G|FLcs(9g(U9 z_m>)=^?oYBR~e;V45wxGD0TLkf5ffGE@O*89zS5`lm(3Opb1veK48RQ0Nld9#Hrws ziNhO9?32Um&npL_3c)Zl7Kqu^i%hZ1bExBS-{{r7jB5eGCx@h@W-3igCF3KPV~42_ zX7tXpSEg}cL8_k7a?6Y+`0QtNNQS6l9j8kaah>2~qG>xFQ(d`Lr%;6ya;oweLCOpS zDM;;c<5zewZrxaF0oPO1+ocVR{At2bvr5XI>{kCtqq+a6ZvW8+D|I}XVXg0oA7Oiy zTR%KhIxEGk*dmLj3tiMjZUMRQdhX78(E=7q-tZb5E@oQ!^p}G-5#IK|&4L8+{I)GH za|yh=JKePfHp=oWP?tQs0a&g@ZN~()YOYnyzD8x`Rcx0?cWJfkY8>1cGzAO^zm^&-S$3D@-~9dDi6C*w-)28 zK7oV!FpH5iRn(yCFnyo=H~hoXzir|gPaGL(g) zRC>XzrJO{@#mkrG5rL5*Pyb`@OQ(T>aaHsjwH<6mpaQ}yJO^O{<=NinsUB!G+ZS?o zQZTNesJ>kCEGB5lP*a!x$@nDDe+$eIx&~fe)?q%1kN9ge_b%?AruT~kV+3i}s0TS2 zeX5Ar){fa*4wEJQXtggtJ?=#W%QullPTF9)@@jxb|I9$U5a0wuhvxoj#^_ze7tBbk z=eT0DdGBv^$jW}|SAV|ri_%U(AaGzyM}W%v?JkTDw(6w^vSuY!79RmaBcUOjsLUmi z(}2sL96+2Ed6;O@Y%q$cwf>{t&#ISg)rb7$U>(FsZ55R>uxZNg%9BzrN?&*NE@ELb z7uH!84ipsJt$N41PiiSa^D3vE+I%o+JJ0{aQ4!`dt^gB6Gkk%H)~J)w^vL3^UL{vi z<1&o&%)S(}mXv8%e&?R)$QoCLb{lSvFF12pi_xPuGU%u+( z>+=QfPe|V|pPBq2;0CqCXAB&}1RXLVdQxTW6{1Sdemz)PYsU}}v62>Uq3WF&@wPB4 z=@1Po=}-#gSE1vjR7vUkeQ>1sQ$&_e1Xbik(a%Zh6PS4_i5$JBjd*DiZ(CimBPDVQPq8J!`d*ED+mSX1O7DaX>r)7_2TbmNdf zh>+<)ZQ-rfmy!Z!buyxn|EeYso%?oJJyM{WVcCOM`$2ZMg1)sTZ0Uvyue22?R~2$d z!w2p+7)n$%hY!w}9zQl?YX2OYnTIq~aZ&vm@}tK%Y^!H;eqK^ryT5%jh?H0)(W(eP z8vNE4wro>Loa&$Z>yf!O%+v}Y^q&*Wn?)!Tnva+(zpR6O12kdXV`i^J=-8ohk4Pa?$L-ozkHCPNUrRV) zr7K9fTf9aeQnr_%GVt{v)YyquX2gOj6l|T+;Jy5?=QYDh7i5!#E_sgo-auYjRs*TB zgxf?jk7-(Q5MpCOOp2Skmt_z*)OAr&2q2wO0YX!c{6pE^XO}>_a)gK9?j_K<9Tz_; zZFshuWF`GNUNNz3k&-%o!6~g`UgB9p=^BWg z3vLp|?{aov>S`69V9$<0nF`H285ucjwzj!?y5>Jpu)3;pXQ-U3PfwfC98lD{<|{!O zKG?%{_^gljLX$De*3$=6MXs`3`;f@8#UT8jDk8b&0_$6pI?TBv zcg@ZRb-+|y_Qd%9XiNR#2DED>hbJd)GNe5-q{P&rPNuJbr;g&AYOMlG(F>*1dy{>_ z_FfTZzwcSV-x`Wf;5M6=qhDraWr>Q4%1s~JE(HIt(llGEL3|j5Y@DP)GfG%{X6+kCzw|JaaZu-81wJc+-(~fs zU&ZIj>0wH8c1v$MX7>dw42a@RW6b!|M)9@)Y0L2k-T91F^Sl zZ}JRZ`SA)PB5zcR^?(Z5--g| zt-Y`Fgi4rKsCQ!NEsv`DaS_F%Ej3(C9?PE=3DlbM5HLXMhImS;_T7*=UOH z{M1(<*6;NSq0O14&z$!ErGjXJev%3pZ0 z8hIT+-IU3ayqo2aPI$EC9z|wZSlT}J;XbIeM1OEjNZ!L~kXdz`1e4jUT=h$$#uB=K zx5R%YFHi~(5Rs8GXlC-MJ6XRZw%DKe&xvelas6CVr>vm-ijqajX>~oGraZ4r0T&(D zkSaJigL3cMWJVhWVL4Y?{cZUm>s?d#rm@ES|(O`BqR zeBTTDm-OAak3Ky!7o<=Z%C=g-*SSdA`_A5~+2| zIh78ay#y##)(lVJ*WGm=?_qr=2P(kCr`m=AeNG{WyEG1%WjCPAk zeyI#Ehpq`2k181V8yQFS?zHEUrjqx10y+5_0gHftL!PS!Az_vW){T{tb9|S*3#^O!1p=b_?Vd`Z&ZfqFq_C$J09T zKkEHQ8d=(Y78@N2lMlSpE`&^lD}VJF)kW=@sV%x1lU9r_pA4eHp5={kyNoHLUr0>g zs2xu)66xK~br_v94s4;EKd~80BqL|@-N*UnImu=|EQ0!1mFg(H>7QrR{{cD=y9d|= z_uO^A;-|j`QxvELJf`9U)jgix^#iXa;!IBu4nD9ME%Gc#d|pKZA|qr70UK`EB4zY! zQ19=v;5!-v1v-;tlfaxJ4t5M%=9`NRGL_>ClUm&>LjtMQ7de2zZaaIxb?$!x{&H>I zFX~rORN?_WTz;g)&3Uwt`ro{-nU{5xx6M?`6L4M<`oMBu5!0W0!b+g?Ic6VBJq6D; z-qknF>>j5+^AyXexaoU*qW;@*x#S6@(`)L>;T3z z{~BnU$hi9ZGq-}yujI|No~ZL8os#nwtBOhPm-80tBQoyx~;V%UmHz-(%2lFO@q2opu`Jkx;Q}3Zijj9i#_OEj_a;@7L!U|NNjRDGQ2$AG z+Qm5^vv2emNir?E}opv4oFj;yucwyfOKE_VsZ$wA@oho zX6E7fSCFljHitg)M(syC{PH(O)i9{HSEPF^CH#snZ5(A*C(Vk|V9WgZkBfahPwuJj zG;u~}i?(b*v{+VXLV6j`{GJ2yXhWuPZ`#721pT{RzH2UtQwddRL)V)-&vBT6Ngg${ zRQ_z5Pg7fZ9O9G%wKb0hudXZBuYcitat9KgIesUHBxJyNLcwET-=1s8_NpCW9V~<< z?7n%&LYT>3es=yQPqd41;WOUyw#1gkoJhu6RvRlCjsse2fevu=xejgKe-H<9=*l14 zhF?CS8bxQ;-t2rHU-d}SHNT8#7I@9Xy^_cCJBfL(AgA;0tzU!Awsoy9g4#qFr7eAc z9)7*-&zq{_LO!p)hA8a|pq&bb&-q$UpZSHhFAU`k9`LQ8v@Ygi z2ILz}(f(MDWHO-D)BQWbG<%{y%TeT1C9>i4+l}J@j}xN3)SWPXAqZn`jUvUCv*;TA zz?}K+i}KJs@sBlw4Hc}MPn?ovlPUV#1IqP2xn(Fr6+t~hQ1v9wwqj1pTSLVZ{?5;z zKigiTy_%SultpALz2gqs%L{NCpg7Q*BR0(ETH8}w_g>hx{0&^Nv|;*49=_~KfI$BP z)PMS&wcQh(Uhv*G7`cp$7a+=s=lZ5!cGm`#nrg%ngaPmW@q=u6ntS`}sd|c~@hq~! z$|2;>i8lMNWZ2C2-Pr#wHn4oKd>L&t_=*4;uo{}_-ZM1n$mYz6#kr%2s8ZF9)~cev zdV;ij^Y}Jb=oZPA=(3#I-Xg>=Hx#SL)0TfevacOvVMweI*|VjMR@t!TL19N}gBN-N~JI8yNUvV2yVK7=1F+(kfl;6tI#68z^-l}--{IMG2sKk?UQ<%1J%XGA!P zQG@}mL-)QL^Ok*k)d$B~5|Obmid)c(VAgt=RXl-e8Ba*YRR zF*~ziBf2S$*4ig?tDY{Ot3ZZcANa%zLzm>+H~J9C`7L;2% z#{w=NJ&N!9BRV;6{%+mpMQFPz!3aO#cjC{YBeEpiD_Pgx4ikxVny{_;J5Et)pAmMz%D7Ja>d9Out|8Nxbjep5erX;Q z)Z_|^pp4Y`$L|k8z_%USl~Bw&Tb zso6J>^j^c9xn3ej+tbV}#2zt!=unClS47@1ehH{}5Tpo-^w2wixe40|i8$SW8j zS5tuliV~f8vKlS}Z%r@ZB3?TKWvYHcffQ&6ZEU-VY%JE#2(&09REW4-Y1iTAOLW9G zr#8ad-WiJDNG%fA&LJT^k4-3W9_}tKT~lb~MT-XfIn0zO@uN}6XG>`vm^87tl>URcK9 zhE#&n46dKpaX3b-5QGNNBle0o+1Ih~#L2URv7%;k9-PO`N6z2!Oc8hNr~R^2y0eGP zZ;i}jMbQs=+};t?_EXT)6Fg78|N2?-SV84JG+WNj*7Y$=Zu-;mCvNi9GB6~!vDX1q z6I=3JF03rpNn9BD-r#20e7tG|K>LkN2R#W0Xo^D{8S=Zxgp*@Mj()8;9~{_Z!v@dt z++E3dl6?-k8(aPlDdG$*!#Bqjiym*!4oq^ebwh46BYe!L$HUZvGBZ8yj*d!DYk_J) zJ@#T{f1_Sq-YiZi+y*KYY4{2K{M@op2I9^qOBC@8#_<5YBmV@hS6RniY;aPu8TCGF7 z-VgT#)Z8Jw=+_4K;d)l3HyG=VifK%YOx!?92)ze7BZRe}r_@h$49}rdZ<0SxF<2Y! z7SpvfM7;{IPKVzrom0P!(Rj35{+WNe5-W$kbF=e>#EsNcY}EAxC&wsTbfsjcMMuze z3*AsXY;%M*3MAwA#@8>yR8S1joDphiub-Svf6vSrx+XI@^X@AAUtSPFFB;~QTIwV;p!rg{C##etANk76 z_8%7A2p2E=%wOIbo*f&c!4V1F3u2jkP;*T`Fo1vF=R(*XY2!TsJgSmlGxH?)*ap*`& zcwT*!uH7^a>=?MeK40%kSVyV(aHBg^VC%6*&Atb*&Gx0cj&W5mu|ya!UC9*nRnKu+ zWi_GRI=0rNHtMy#dqJ)Qbobfs#&g3$6K5JTbXfQDq~>ER&us4$h3y_ywEx<$Snt*j zSToqTgF^L9d~{c8PhWb2aRDoY5X2WX>EP2$cXZdpKYDk{Yf4VNZoG{|wjD%&clA4d z<7+I%zb_v|SpE$lLK!oD%KJ8Gr?ZP@kxF5lT7?XLwPP;RP>693cb{wOxt!gJp_%i! z_-MeWgVthy8HQypg*wwW-Y^c5db!w2lc3Jhe9_dRz%6k~m0Oc!=L8OX@8^&KJ1|Ix z=RJ*e3<#ktc3~d0NJxh(FZv&Urm!5tdQ1yo*&+zbP?)GexQr*aup6}Q^PZAUfvF-E zM<&~Z?|lXu%%Ysza%$5Vw~YB|B@h{JF;1|Kb?zq%j?S#XooJxUpKrqc%yy@Lb`&GB zgZk!V#<^n}sN}%b@xE3VMcVclpZ^WI&HD1!znp+K3bz~)G2TUF8#LB@ z(tM39ROvNaNFZf3oZv7WG3YDZ8N-n7%!;|LS)zS34j_fA(Lrm4oG=Pq3K|ONi~{c{ zp#JCNKw+j28+Wc-d9sH(~gD7wFwhyBmHVr4>R$SbiY zi6PaC(qZiNisn2}+*5hs&(f%upZAXIFSNd(9$**^S?j*X2Km9jd1>=Seq{PQIkIVi&&cEXhtwTL|i;Z0WleN2+=h7*H zZGCr*unGCdP|Pi#jm^mbz4B*Qj%BuXSqd8zvFPwUe#~d!O`!0~fa;ReT`_cS;tcF)Hm06SR)EfzfJ{yf$;@A}yjZ3;lq4g5y9@SfH~bvR0# zy8`sD3ZEzn`@tu< zc8pC_3eGzC_S>Hb4HF?&7x|)>o+&NlyL5hDz@nbg|IE%g%|B7K2gVA;#JE+6-&=j? zS)BF|C$8VGgTzEtV9n$;O$$eSg|&pFs2;0Eq#=8N0usXxpAJ(W9uyMl^FH6>`}?~8 zV3gQiO+PSY4{W)m^R0yXt(idUG6rpS-s+{r@K{-yz~;XHP$9GACix^a#W`-=-96f1 zMuH_L!#8*K!k0d?OxV)RPjHDwcfW+ibSXlS+%Ojx`wjG;d~c4odUvJH#@j%$G-@4a zm+*r-ZS$|2)0lL#E?o}5hL9W@t=ly-ANQSYb*iI?#Vp4o?(n)qzCUw>&5RxaEk;N# zF8{jfxeMtB>YU8oWDVI`6<$~Ew}EoN`K*91UneEwWJ?Qx)TFlTBoVBFD97QqE&ru; zC}PX9y0E(yz5OIw$HhqBfsPzJ%YUO3SUtrfSH^X2&QndA!LaH5^Znj*STb9%Sk-OR zG=y->7VIY)J9>;WAVlGfD_js~1DKxb*~n|XGD0g{8n*=WQw|y7^%)@3r_Xy23Du|E zqCxAs^j3tRE^pEaSF%p#`SWoDw9c>qJnm`qS=x6+jI-3?*Wx_gWypa`3R-g zlm;hGIP5?A(W4vueFf#DNRnJ`ekL>G+~nD+xU4x;|95-e$1Z6NcG0@Y{m~1;cCOR> zfZ(+V_3`Ig4+Qjy?rLCJ(zMyLe-EMtG7J(gs0=*K8pD({!}qc<$@L*TYy+iqL@E1W zqPpAvtF;6m`H0W)5xcz)Ka`DHRRMt{mYxvf< z^X4X=dTnKOuD0)g^lcy!S%*Z^-iK|OXQYVaHBwf=EQZcfkqx1#iMXzjmpOj3^ZRvB zT3)rfu;C)0H2yVmKsBqx4fcAH5nu|j@}cxo*#gs#<7%g}oW~u_s$w(x?Xi;jSq!`t z6~0v8WOSC46iP$OdLFPptJtBobHdUu!=Qi@iS|gn^LIF_i|>~^b*9M;=K6l@{dULf zQVrxEGm8|Kki@3936P$~3*g!8mc_N8ghFL6xPh4;rpw}&!vfDq<@{uJO!eO9Un#)o z4}^_urQoNBAab9Ag>n$N>bihZa9(_!@V>?6laiYB6;zbS?)!ug$JX`hKDx}g1#Ei? zj_fghAusH;2V_RscMh$S zi>rLXG{O&{m%rS4VK1YsF_2j;JO6h|`-}K7Mpd>&Kt3k5EkilJ#9%k%nSw$Y)V6LG z?xeV~6xgB{JtwWs?n~a&oz8#GH9l0x4RrgCUT+8)WSdx8LERJ~H-#p%jrN8xTM1Ue zz7WnXAdfw0;~(MCEZ3k1)qw;YpzJVD~rHf+9XuA@=&j z(9lrhxSNSD6f*lq60-0&FNCJHpH>Ls6NB*Q|+5%D~n!hD99WI_0j2# zviMk9$3gx3PcL!6iw4<~yyYLvP64kcix=ev>K?Y8Qm;574h>#y&1?VSY|A}oWQ1b4 zb`$@o=911fHL{45bxZzPv?e~3utWEqYDVg1*k)*AN;snm59kMvw*U8z=)F*4arcPL z4K~)z!CspL1sw*PJSN}bz*2XMmspcsKKm-)CcUx3xG>AP)*dSXu_?Fn{ZmWsXxE8u z%;dTfB`@$4g(t7YD2vqFtyHd^cuH_!l zHzlM{9nCrYgw3T_(7F+^h_QO1?M5Sh7r@{!z3>X|3u7ncRWi@iOv zl(Z<0@bsRdP3`uKyyKmvaMx9%)pM=a`DQ`)6EW`~_shUo;+_5HuLYYWJ$-Da*kOex)>Km*YaD*?+v;kh!$>CYI028p9N2-3{A;)lp=L397?g5#Fw;K2^HQ|nE7j@5 z+u*A24Rx@NH02M)(-+5bt%CS%$;U0U#zW3LL&RJB;qB)#o3fgr88KUDqeSq?*NMLv zA0~#0(&)wNGFqqV^3pbHidUY__1;IkEVA6ZpHq|x6 zALY4$eS78!bn;7Qfe9Ym9i*bWZUe_CBOs(+=tqWZPw==@5#Hz#Ga832OKNiWX7O2Z z9hbO#6w)WT=^kIT{;AQ}+nkN;Q!>d3zq{+$2W+KbR1MC8-^heDwabg5;Q=LygB3?rae zcxft=uh}b9%g!qIMMHe=#kfYwFJENY_n}MLOGnO|dYVs&5B!k&StFXvmiZ~M zRXz#4?eqA;m^da2v+*ND$AZ?eu^5Sp=jIeQ?gb7F`f^#={7g83#1Nv8Ue}NGKcIi- zVInOqD-E}$HpF7ushpmu*vfJ=swMCmpVO5nSa$TU$ml>p{^Bgk*6|an@~0)=Q^RJ7 z@HT+YI1dZu;8A1K^Yz5J?*Z`UtOULGB(lbZbVeh5&%ckNXAycoODXyqQyugHqo-Bf z)0RJd%kLPKLzAqsPe;Ihr_j`IwubtZS1h_u7D85r4?SG~gs4#_c}Dnh*CBrkg@VSB z|J8Tm^Zy?JBY8fV9d{P0bOUe?c1EI$%n0>=9^8%NTZImMo&0QYI2m?N<`*R*T&|aJ z3Jy8wHlC?M9H&BfD;K>FN@*Q&h35n{zwh|rz3=qvM8Oip*35Y0 z@&zm=D{EgFc$stPU>%OJ}MegJ_P@HVJWqjphz2TGfhi0xnW)K!$5}#bWn8 znQ{sDx(x8mBu81Z;?pc8V$K2$riwekF^VetjHYcREM1XQG70)ZWC#^8Pfh3BU!pH! zsKNhk=#qL54kK)~U_*?#F{UgGy_L@)G-u?c-!!16TJUmp)J#{Y))axJg{&RY3!-D% znRy_A=NM*;iG<{{i1S#=eHl9TaQ2O3b111yp4HLRo(lPP3MxBW!)kgr)*=FmUJ;&} z5eX4>u(@R4mG^Gq8;dGSgO*NiVj9XD$djgVKci!r@z3|p;_b^G-xQxts?|*q!r=B=vn_-;4x9}2lJ{QJ zJ+(xjM;b&om|8mG{8vyTr%tG52}s(lhk2SFV4K==VlCO9w8^==449^EJ&fD&@1sXe z9p<+CIf{+!mq5N-W9Rhf^?n`mX?ySU8*=DS*B<<(lfa#eK(+n&#gi@>!fUS~7N4>s zt#K;_H}{k$*CgqA{Mgd0x=keO5mP_(!v#u`HoCkf#cwiSmyEuvvu~lXG1j&hzhU;5 z>|5XNr|>=*Rt(d*@`Qn~IKeMRXSdD#6&Bg!nr`L?C7yh={UV=CjiaE-RKj_FFLm}` zL6JXnI=1ep=nK99I^8v2$)WxHS*fqJ!_&t2Tx>3oYitbg-t{5lk_-8t!zH%*1(zj? zC@{g@!}utjf~_E%^e7k<_qsF^W@$Ny_#Wv7TRUtt$P$&j5ww8}qEAxXjg{u}cMJ$8 zcKBUw)YKN4ljz=12wHbtEY61pu(LjC8RJp>q zD;KPLG{jsie{?rGEziJhBl#Y&XoXZs>v(;ib)OC}v;Q-bffjNHV%4o zdsKdB1X|CI#*I3^kqEq&>YV|FDq?TP0u-M@E&h#k2EiJnS`D_^T8Sru8{0vwR;e8E z=uLdkR>R9O;Y+;L;ZE)EpVo$VkIrmv8}s@j`K%7ERjI8h7Vr#U(J(&}H#B}>0*#eV5v*#Py84Gg3YFfcWm#k0yY^?WzOx=_~UA>%I@1w|-YkbAT zy7ZqR8JRQa`fEz`JAF*r_;G~8n=wX!2vR`)uWX)A*1?dnOiVx&X5J(V0ISCR5)tAB z+(7KaKG3O-xN(!%Huj_9MJT_EqT3%7OZTv9CArEQ}wl@)+bcHnbUC0x}5L7kW($< z_$1L!dM>jeYA1bDxOGyOssdGGHcoI!jT}3c8EU4!)lZ3freWy74B>RQu(B#gJvsD{ zfD)VV)>#=N{6~Kr&nN1z*e%3z^T;4uahe3az)>Z~gINohD}Pm)sC#GN3z792A`5$k z)Eutp`d>(JRH{ySMrgaYN&)RtB6{f;clsFg0&Ber>e2@`9ybU5l#7qro9IYdq<$(< zixl;tU=zquVpV$~^HH+qSNWc4*Turro`oU$)Y|Uq=T_j!k#ma=Wta%@Xh)N@L#U>+ zMbT}?8Z0feL&-0vQ9L)D+?B?c< zpxM^u%IZ`=PC}UuvSrXfD3IqbD|TQ{=N7FY{(j2=uGPn+)0(@F{LoNie8;Y6aZdE@ zIQN|_Am_oEdsuZb6g(x|hM8)1ZPr9nk-Bm?bNhApF9=3ZvelD+#aB{G@M1umo&Y&G ztLo#{-d|R8sn)^C+>DD*`Fl$#(`6HP&zGBHD&;tTd8yMnA#)$md;jHvw(MDuSX5rF z*s>1C<8w$`q@!ruaJ73+c*~gYOLvL%%K4yL+Kyi8(g)1b^)6X_Q;2tjZI4vWa`6)7 zFL&;rwjnZxgmkCC)v-b@z`Sn#v4`>fmK7Y`(zxfRbuCbM&rpMG=iC1jULrNWJTS;r zjL3+`O7t1Aw^dq$Zo|fWP)X7dl!{8eO{l1`0xvyGs2 z%n=sss0BWMZ$=3X>U>5UT2&I<v&6MqF>Yc zSFG;mmh{~SMRy8emPZ%Y0y*|U7{9ob3u%Qk<=$8!e zZQh3L^fV83!8{QzbL3hH-o(-MZ ziB}IBeF%b?c~5UikX+kS!A1-~_0fC?)%hT0x4tO`s=lCk8K+oCw0Ex`MaaADf)D#N zk>iU#>I2Zp6L*K&GtX!uFJAUOs^2G`bUAUqB^-K!C)t84{-|&j%UX=ihw>|KeLKyG z%4@XyE7M&q_})b$(w(56L|c`T((JQ!>5sAxTI=B?xdi6bNihm}It7P*Z>aseDLj&B zw2P>lx;isNpr5PUYjAg2LJV(R^;Y{vU6z9?{wWcy*^{ss_uil8El6SB^FUKl9^Ke) zeVXTlqY0SADs0ERoQD^hLIX$?`a3pPd`e+GZpd@KW$xQYW1{V;WumDERBTdSGDX8O z9$Y%n@a&WE=J>&}^p-+APw7m=uEns%&Ww}tGpUiRRT2=7zJ^z;G=vUsK! z_fJ$#p0jwAXHJ#IPnI!$yu@gfAL{BGWn^GtcKAjR`;j&ne<$fLe%i7nc)0m4B-K<| z_La&z3Nj@c9sRQJroc?)?``Q6dsyI%M;WiOglTv}M_QhK=bnA!Zc{N$A71e)n25_C zEGmx&b$Y?~mfEO?ea^O8zPOKesjk?hGvA*n7x3izz;{>js}i(+uH4Gq_;l{)#q{UA zPul~&gv^CF`_k#koOSUydkRoI_?PlHLHC-FBD#i`rlVjM;#eJD4?1~2snoSukKIc) z@QVN>HI1VfuQ172y*!fDtKoVX160;G;bv8zx(s?XDwFbRTx(M%)n3jeYvVQIRn@5sO$tQy*p8eRI6yk_h`RkfK=D*Ye`R=z`)+L%Kj|3DyGuM2rBJR{3<{mQzXU-D8BMr~j3$X84ZDXF!{i zBw;{l_(=1kG Date: Fri, 28 Aug 2026 19:56:34 +1000 Subject: [PATCH 078/157] fix clippy warning with new version of rust --- src/canonicalize.rs | 14 ++++++-------- src/chemistry.rs | 15 ++++++--------- src/tts.rs | 14 ++++++-------- 3 files changed, 18 insertions(+), 25 deletions(-) diff --git a/src/canonicalize.rs b/src/canonicalize.rs index 380c4de0c..d20374d49 100644 --- a/src/canonicalize.rs +++ b/src/canonicalize.rs @@ -2412,23 +2412,21 @@ impl CanonicalizeContext { // This is not yet in canonical form, so the fences may be siblings or siblings of the parent let preceding_siblings = as_element(children[0]).preceding_siblings(); let following_siblings = as_element(children[end-1]).following_siblings(); - let first_child; - let last_child; - if preceding_siblings.is_empty() && following_siblings.is_empty() { + + + let (first_child, last_child) = if preceding_siblings.is_empty() && following_siblings.is_empty() { // number spans all children, look to parent for fences let preceding_children = mrow.preceding_siblings(); let following_children = mrow.following_siblings(); if preceding_children.is_empty() || following_children.is_empty() { return true; // doesn't have left or right fence } - first_child = preceding_children[preceding_children.len()-1]; - last_child = following_children[0]; + (preceding_children[preceding_children.len()-1], following_children[0]) } else if preceding_siblings.is_empty() || following_siblings.is_empty() { return true; // can't be fences around it } else { - first_child = preceding_siblings[preceding_siblings.len()-1]; - last_child = following_siblings[0]; - } + (preceding_siblings[preceding_siblings.len()-1], following_siblings[0]) + }; let first_child = as_element(first_child); let last_child = as_element(last_child); return !(name(first_child) == "mo" && is_fence(first_child) && diff --git a/src/chemistry.rs b/src/chemistry.rs index 1176d8d3a..23de8668a 100644 --- a/src/chemistry.rs +++ b/src/chemistry.rs @@ -1384,17 +1384,14 @@ pub fn likely_adorned_chem_formula(mathml: Element) -> i32 { // prescripts are normally positive integers, chem 2.5.1 allows for a superscript for a Lewis dot // postscript should be a charge - let prescripts; - let postscripts; - if children.len() == 4 && name(as_element(children[1]))=="mprescripts" { // just prescripts - prescripts = &children[2..4]; - postscripts = &children[0..0]; // empty + + + let (prescripts, postscripts) = if children.len() == 4 && name(as_element(children[1]))=="mprescripts" { // just prescripts + (&children[2..4], &children[0..0]) // empty } else if children.len() == 6 && name(as_element(children[3]))=="mprescripts" { // pre and postscripts - prescripts = &children[4..6]; - postscripts = &children[1..3]; // empty + (&children[4..6], &children[1..3]) // empty } else if children.len() == 3 || children.len() == 5 { // just postscripts (simultaneous or offset) - prescripts = &children[0..0]; // empty - postscripts = &children[1..]; + (&children[0..0], &children[1..]) } else { return NOT_CHEMISTRY; }; diff --git a/src/tts.rs b/src/tts.rs index 91b05c0a8..c2f951b39 100644 --- a/src/tts.rs +++ b/src/tts.rs @@ -669,18 +669,16 @@ impl TTS { /// There is a bias towards pausing more _after_ longer strings. pub fn compute_auto_pause(&self, prefs: &PreferenceManager, before: &str, after: &str) -> Result { static REMOVE_XML: LazyLock = LazyLock::new(|| Regex::new(r"<.+?>").unwrap()); // punctuation ending with a '.' - let before_len; - let after_len; - match self { + + + let (before_len, after_len) = match self { TTS::SSML | TTS::SAPI5 => { - before_len = REMOVE_XML.replace_all(before, "").len(); - after_len = REMOVE_XML.replace_all(after, "").len(); + (REMOVE_XML.replace_all(before, "").len(), REMOVE_XML.replace_all(after, "").len()) }, _ => { - before_len = before.len(); - after_len = after.len(); + (before.len(), after.len()) }, - } + }; // pause values are not cut in stone // the calculation bias to 'previous' is based on MathPlayer which used '30 * #-of-descendants-on-left From 5a4aa2c35f38b1501900a61d1f4909664a2bc300 Mon Sep 17 00:00:00 2001 From: "U-rainshowers\\neils" Date: Fri, 28 Aug 2026 21:28:36 +1000 Subject: [PATCH 079/157] tried to align the MathCAT logo with the following text. --- README.md | 3 +-- docs/callers.md | 2 +- docs/helpers_old.md | 2 +- docs/index.md | 3 +-- docs/ru/callers.md | 2 +- docs/ru/helpers.md | 2 +- docs/ru/index.md | 3 +-- docs/ru/users.md | 2 +- docs/users_old.md | 2 +- 9 files changed, 9 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index d34a66632..bf974dc3b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # MathCAT: Math Capable Assistive Technology -Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. -is a library that supports conversion of MathML to: +Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. is a library that supports conversion of MathML to: * Speech strings (in several languages) with embedded speech engine commands diff --git a/docs/callers.md b/docs/callers.md index 0fbe0f189..caff0437d 100644 --- a/docs/callers.md +++ b/docs/callers.md @@ -1,5 +1,5 @@ # MathCAT: Math Capable Assistive Technology -Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. +Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. ## Information for AT and Other Library Users diff --git a/docs/helpers_old.md b/docs/helpers_old.md index dea983da6..5266c8b3e 100644 --- a/docs/helpers_old.md +++ b/docs/helpers_old.md @@ -1,4 +1,4 @@ -# Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. Translator and Rule Developer Guide +# Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. Translator and Rule Developer Guide ## Information for MathCAT Rule Developers/Translators This page is a work-in-progress. diff --git a/docs/index.md b/docs/index.md index e965c905d..b4283d1d5 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,5 @@ # MathCAT: Math Capable Assistive Technology -Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. -is a library that supports conversion of MathML to: +Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. is a library that supports conversion of MathML to: * Speech strings with embedded speech engine commands * Braille (Nemeth, UEB Technical, and eventually other braille math codes) diff --git a/docs/ru/callers.md b/docs/ru/callers.md index cc3117baa..e9a1270cf 100644 --- a/docs/ru/callers.md +++ b/docs/ru/callers.md @@ -5,7 +5,7 @@ ref: callers title: Интеграция MathCAT --- # MathCAT: средство обеспечения доступности математики -Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. +Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. ## Информация для разработчиков ассистивных технологий и пользователей библиотеки diff --git a/docs/ru/helpers.md b/docs/ru/helpers.md index 0cb0b8769..ebcd6e8c4 100644 --- a/docs/ru/helpers.md +++ b/docs/ru/helpers.md @@ -4,7 +4,7 @@ lang: ru ref: helpers title: Руководство переводчика и разработчика правил --- -# Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. Руководство переводчика и разработчика правил +# Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. Руководство переводчика и разработчика правил ## Информация для разработчиков правил и переводчиков MathCAT Эта страница находится в процессе подготовки. diff --git a/docs/ru/index.md b/docs/ru/index.md index a577238ad..1ad5429e1 100644 --- a/docs/ru/index.md +++ b/docs/ru/index.md @@ -5,8 +5,7 @@ ref: index title: MathCAT --- # MathCAT: средство обеспечения доступности математики -Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. -— библиотека, которая преобразует MathML в: +Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. — библиотека, которая преобразует MathML в: * текст для озвучивания со встроенными командами синтезатора речи; * Брайль (код Немета, технический вариант UEB, а в дальнейшем и другие математические системы записи Брайля); diff --git a/docs/ru/users.md b/docs/ru/users.md index bb4102cc5..f6d61a9e0 100644 --- a/docs/ru/users.md +++ b/docs/ru/users.md @@ -4,7 +4,7 @@ lang: ru ref: users title: Руководство пользователя MathCAT --- -# Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. Руководство пользователя +# Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. Руководство пользователя ## Рекомендации по выбору голоса diff --git a/docs/users_old.md b/docs/users_old.md index 308f74bdb..df32d6a45 100644 --- a/docs/users_old.md +++ b/docs/users_old.md @@ -3,7 +3,7 @@ layout: default lang: en ref: users --- -# Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. User Guide +# Logo for MathCAT. a brown cat sits upright. Its tail swoops down to form the capital letter C in the word MathCAT. User Guide ## Advice on Choosing a Voice From ed724d10b5c4ebe163caf9afef2f0f39630fee89 Mon Sep 17 00:00:00 2001 From: "U-rainshowers\\neils" Date: Fri, 28 Aug 2026 22:21:02 +1000 Subject: [PATCH 080/157] Add logo-inline.png for README and GitHub Pages docs --- docs/logo-inline.png | Bin 0 -> 42032 bytes logo-inline.png | Bin 0 -> 42032 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/logo-inline.png create mode 100644 logo-inline.png diff --git a/docs/logo-inline.png b/docs/logo-inline.png new file mode 100644 index 0000000000000000000000000000000000000000..cdca63cc38743d117de9fa51c4811ea6902337da GIT binary patch literal 42032 zcmbUJcOcd8`v;B}CmosR6xkVv%xtoloaK(u3W(lxN-%@35*B) zG7DSizH+7DKuJzo=hgH^i?6-zLE1(5d)yA8&JLHEM43Q;83Nya7PS(YuOax9Y~P;V zU8ff$kV|K`IrL$ev92kYvndumiOMq2{czJ-im`ZfmC!mts20H!&omH;m;O^{Zm!P7 zw9rCMO8KG}$@?ps$3`h_=-B%=Lw7eS+tbHuaOlKCDF)oJ--4QTu8^$Q70*E#m;y@! z{^S-tYG=dzQwnqy^A89J^S2x+=5JEz|8E^wNiL3ZF5LOA^tq@p0tW*8NxnTjQT~K~ zY;0^kk8lbit!k#^6&1B5zVl$?aUhB0 zY30ph$0u)_jG4p3=+O(8>hC=GTB<(~OmMqjg}Y^uv$Fo#4C46sSk=+7Vs&-(`T6)l zy~CU>-u3G!u8$Czo*jgouWy_4X5&Pmr^K4*+y}Rc-C8Uy9DH$~(}t;PtC*=uvp|D7 z`!s_Z>o|i3rysz9eE9HTU}xzIK&94c0>_xZ-GcO|ai9bF?*ZWj!e+|6_4lQvUmEdd zW@fU6eb+BOOfWKn(JLfM=-LU0q$fQ_=7T@WjU_1h2Rj zdx>Rc?S=<%N=|p<6zK4qDIqVp*zKagIA{uTQdMuRHGm$bwX;Ge6~Wl)s{%>ouLM^4 z9n5=H7_@lQ8dO;*Ev{?i5i(%sHDf53ZzxnFa0-9Sg#WnG)c>ZL3^Mow`ESFX4^z^X zRJt!;69!yNN5o$vZ2I=GTpq(#x%houNRER2gW?)(g5Ny&d+@}KT)xQeXxajuTgyth zZM>R^oTkIBD{bVEOaAj?u_n$n+_hsU_x6czKt^mMWRU&&eX49^!Eop#l2?-kf6pWo zd%_9V8bdzX(dELWkpxIz$h`fZIaNG1vTNIam*+^3s?QU<ay7x&^PyAUrPNSy z4<^M?-?<|!D=Rx#>98Fj{#7Ou=oj0LJh?h%?1`mu6C&=uQ%Ffc;e_{m=2pl3qI@XG zqVgPS?JP-;InG$8xCerQmR((4{n4~y%TZC4%mJFp^332KdZ_hg`ma4)^i>HMBh?>1 zOdlE199vkBQ~*6wrsoR-2_;CaPf&ATE=Y>Up<6@nnP&HJd3pH;`Ldd_d|byd*mU*} zY1(6}=38hgS2}`R2?w-5K!fsS!xQsn8cajPKBrg+W8gbCi6v1w9IQy)3ovjal*cnt z!EvT0@y9St;mwY+%braBjW6-!F%rBHZki1ZBV_c?o9I-n;eKo?NT_MV>ii#x9PH{q8-Ri^9csF^*hpk6HPaEx*w+Uu2s>km$fjc!nsFu}a z*{IC!&wQK)IIhDs7Xn!$F6rW#zG4J3dV_ zNA*J3i=L8sut_M*HJRd8n{gt<iORx)Z|Kn<;cpo^5-lB>=hGgji`D5-*I>-pZ)_e|^wPAKT=@)c$+D{i1YaYowiHKT0 zRb6RweYV=PW|K^|Sad0lscot1VzL^ZS9S49RCCEUE>8QSI-AHhtrUdP`Kx7+gwYn7 z1YQ=EbO3RmjY(dsN6pJ14@X8=oRpQM=?Tu*j0BT^h84`|KzVoCpQM~k*aetiRItdd z!uy}>8iB_8Np)=It-iUW-@aq?%!jwxY%t*L4Joms3ruq=YqQ7n8EkllhQ<1k*XWra z$$V`;jV-;u!;0aU;9I*2TduRubC-!0;!ZuZIJhby#EzTr(`* zN?Lnb%yM5N62xL7Fb)W$K2FQTEsUgSJcaaY<9)5wQga;d)asVk8=iNK?<{Kidbtt1y{t(*5`Hd(6Pzcy&tcdpH6%hh&b0|%{D(`nQct_(Rv zgriF1*`Vo6GHcm?9RuVwaN9jaXR;a{E5sYSPG7+0pUx+vJD$5j#%Wjv%A|~-VHm!; z#Tl?ka647q+x|WO$!5Rsw*~v7J66(?>UeJNT$X!n8eUOn$q_KvI;S$iNHM!$eFPFi z$o=NG6CH?%c_-9HF(3O%b2~|TATHsNgQ2_KAx_T2{50d6b?KiJmzn<_3=HC{a`SWm7|n~>CHd|IK38&}z4KC)r{H(MT<#bDCY zQe&y;=E5UKVw<+_h!0tEQ`{6jTn#5U&xAtb`c>AL59Twj*;J5WRX!f$N>WFeXn2)L zC9m`e&O3q7v^aOAvmh&y;;3~H_A=7Ih_6cHZ6>kMk;Vz>YHxpF!G(=*tR_fD-^9us zcdBbRa_||Q*)R9$+1sh|&J@@wmKjr*9^t#S<<`r&*xL3zZu6N-Us2+G`}S?tZo0zC z`@K{p7;i-09|M6QiTJqRU|>9k|sp-6S1%x&eMX&S1W|IIBgH@y5P9L}6C=C&m;Byo@_;<}c| zq%C?IdRHmlV^DRXbjEH+hQa(!fPNxWBNiGsPq3p;J>6P77{Dn6ZjpZHFM5UUv&Av!GOZ+An$%{z-! zyIE=QxSY*`iJ%r#@X?JWY2l~8wmfOsa_jR&-7bOyiDKrwyYHqi;n^I+tDSM zwwXeovnTu}W6zlP_80k&XN7TFHd-@-rf_%OSu@-67+Bj86iMie)tfdOnMaAC{w)#j3|H##BVIDWzN`Cv$%M z!%cndU8sb^oAaEAv3t0v!CI!pKdH(JreAC3 z+O`#*5x#8#eT`*EC6HC2tX96>x$UY+4eU@wZaXKAqBl1vkE`f+aBud0sgih7_;_P1 z@;^GX>|wl1mCy8kyUxS>uUifNvb+A83tvq@7JEfu+yR;v8UYM{ViPm}SVX=iz2+N^ zT$JZyHPA{!E+Py3N!>du;?Ts?Q;-QogZ@E}s^TqIc=sN8s7ky{rH9AK9vse@PaKU7 z-M>ZeFCSsLNEv`-eP;*_1qBZva_{9da2TG)3MeX%Pqz^=uJq;d1+w4tMxZtk-v>#8 zhK(Ms-fn|`yv^>(B-};yO66{Kv~zXAt-VRJfJs&2+pb;|cr--VqTqWZgN32zg zWHP=YOX7bb7`)`~Sm{U;CVXo1`FYbhx^3ir%8$dR1Ekofjmmj*TG08=PkHCV-)7aW z>w05fza|-izA!3j_OTU&nWP1A6NnIso%7MEl)-ti=Vh)#Cn_Rh16NQ`^Y!&D5({PF zdRrE8I3;@9(t94$$4?%TnV!yPZf+h9S4@28%&KYPk99LSUz?^wpqA@2%HzTj;TVRo zpbt<2`n?DGsY4u2h(&L4is-(yM!S0v^7#)^j#W`H6U!;hE5Q8PRt5UAWLRVP+S56JVVeWC#R7TMjxs#Srz z&pxH*LZChLnvV+pnJSTD>aI%lSXRvf3RKh5Ga|HLl0JO&DV3GLaUUO=7H%5w-#N)a zbUvlNf6x2YOm%iJZ{sGcZ=ClQW*uRy0k#wcgL$~PxbMY6g{JR@4U@{d5Mqz$X_)Eg zU|tm77bXEY$bSMGR=7z+1q%R{BiF5gb&eTbh?&=h|D$>}OEz5ee`H>p0#n41F94me zI$Kfs|X zIP-u0AtZWOFtJix!zajp=Tb54xv2xbWv~qq^_%FW zxxE_v`zEPgR8qa7zFUZneP_jF7|0;xB6!^q z<>{MtrLPH-m2eW0Lyo`5y6#E~Gl*j4bR}q$Br=^>+h#rxpL|cLTcN>oN~bREZF|E` ze)mMSv|wzpayYVH49W2|ep;M)cqUI5_2(Qk@U*!*fA>N^rs5^uO>MWYg8NGv^z}eREIvtc;Ld zVheQM56#&UQXdkpYw~9I%zQ(@ffYF!z^{DW`@+|hiE>YQU`*4h*V2GdRLdAb$c{f? zls#AW-newk#Ath#M+5(PdSm4KrrsUBOTIevtAz7fPTrYR1^b@w;q87*(N6>N4$yf{ z*e9qak*TEi&$90W@xyUXm1RCvb=mCedwl49FliqIa&$#shaZXJ3@gj}ng6%0>lQj& ztVa|L)y)RdjzStJ<sw6t(pR= z0xSpclno>9>q|3QuTL^Y#eUz!Fswf4D=Wg(l-{5qm5@*3+d=43EZJU4SF$`FZnZxF z0qHWKJdf5ViutWevb*vcw6X~TuX~^RJGPixbTQz6y$^Ez*w4>lSln*|pTNhQmZ>Hv z!uY$s5@^mlo{1!-RD9fs+|XqidqK!JFkV!&wIIahi|ln3Jvu5o5?ahSKX9_Ei`>*c zIJr^0hA>MP>-0fie;*%Dq@<=+fd$A%MYE30*Yl->Ca=<1CW*i?p%oAs|If*MFJFlq zft=e{O_jyeAvmd`8T3UE_V49Q$=|K7{`jNoUT;ihq@f-=Sx z1g>C@G4AG&p+h0oCV&2Z{CEAK!OFtf+(KGMhjg{q(M}&>!a+*tLof3dks8mUM#nL& z>auokr!dpsBKUoHSUZ6~eBN4^7q1~0F5-LMEb{7i?o^d!#Ol^oE1SQ~0eJZd-7#7r zOCBFbwFG2H`ji^XjwBo6%^;}TUHU`LKfLQI%2SH2H((Vj<$Sk~he#sAcu={_7V1!8 z35m@}?=b3kNz1FX+`q?*wU--F+5G5;vQ)o9sDAc^iao?d%<_Q*lPQ!J-yoZB#hbIY zodjWFK9M{_L#cz{QA)F(Df?cMsoBjkqPx=e$p?{?(YcbEe2u0e`Ylr)>6+EOODCJ# zwW{_er6n%YkkaC>%aniLJ#XnMRMP#;bs&@JwtUfv9~G_H?sDF;vEvix+)95eqy@$AE*ybP>ZgRLOw zVRyduA^(h{*Y@k8sU)fCX<7G+WopKC?|I?if!%2~mkrTmvzRLiBB2u1jPIPETf6-p z@E7=rN@+)D2Ai9=i4_cGQLvr&mky77xXGZupW{EO>+2`>_V(`c-4+&LVN|@5 z5N29X7Qb&_3}o0?^^r6pkqlu<^3p$fc{%v{hLx0cs8+e$ACHd+y*<^wI3F%+Rt(z{ zACf;zn@(Bw*{(nE5>J3CQhTy8TZq<$;$*wURvr}{=Y^p(Q1U1RloEgQ>UsvaWNB!AG-@`}Kx9^F13-uZb4Eea%om8Busg zr2;Yaji(@yNFzREPI33J`6};Ryn@7AuJsSg;=%_a*LqbZhxX`VE<7U=r7n(~hrvi``u?Uw!neK$~gMtC7yB$mR_Mw zvVmR5z9?WK#~wIRqj<^>kAjC<+`p5x<+i-WhPgf3I18TJ61)2|ju~Tb)iVkdVuWtB z)r_XVf8TOX44v+$6T10{6IQOeqt_MYLHud4BJFVCX6sbO^!^eMUi(_Q z{4tndxhTc>1;}Zp?pfZ?6nQ19>N7tNFNv7@MCSI0i=Ui714T8CJ2eUzT2Edz*)zn& z!0>u=j6cNj{HYe`$K(tARACxvQcBIJy@UvTzu@sj__-}(%H`f8|uh(s;ks zJ+8LS(}@$kRQ(H=&1V0#=WzTWBI1J-ikF{b346m~miJ|nEBgy*o=G3b|u`#k!Pi=qw?X7w8$MU*nCpR7GP z6(<{h-i%V6lA3dgjohzPxYTJoa#^wq?kHLXAU*1Gz4yAHb2y`qywlmS>+aTvZPB4W z{@3XgIRgfoLPC0#X9-iZv+s+$`5Ml4F+>;EaPzdxZ6Z#ViKT0znGTC z_$4K^fPnNe*sZhF(0a?K8J-=)ZS8Af@L9bfrUI33|NUqeHP8`weE^6Bpqr3LJ_Q~{ zy^svBIls;6QUAh4+eKZ+spQ4U-2utdiuL{+$vw^LANygJ0okbL=JgOlWfzz@iVrH? z25O?L3k^W5*K#Y~GK+fgGr7IVgeiRdVBJayCnL%(mfpv@S7x^}YHrZ(#c7+@$IRnt zQIzZG`rqBD30@`g@i}hx#zfG)7FV-9g8;9`Xw~5N?0vkB(%#4P#zg7USrn^CQen2J zYoGYRtTO^Nn1%RSqU(&n?;`66`P3$B!K_O0OR*q5^{SV0KAv}i=!T8RPB*N z*m!4efQMMmOCAk6G$ZxFg5@JjVl$h5q7Ynj{yUxrTY`W$@?Sanr$~SS*qp{@yp4^T zfei9<+a+YB020eR7+*JHB@2Y2w^VZe#0j zLyC=}9`h}48pq`a1B6o9FsURd6&2*-c3%?5GLSa#|B2c%*TJP0tQy&n+9c2k)vf>` zxB|Wv@kY`2_r)*DrLotq+mJI-)c23-!FoNKh7Kxn4uhtuTEB3vS#x}~3&EtPc2Egz zH}5`7Wm1UlzbWa;r>mgdn*(TVeA6j8o|qn4P(q@?bYz2px-XpPh1*~i-ksa%6VR|a zngJYLN*WqMvNrgRl{QX6vTxVx$SOtmFw+q&vIB~i9V$EHoOkP=_U#4~E<>F0C+ErB zCJs#>J}^b(Y;u~86X!oSpKs+;sfrB+vlG0v&#Zdku|>d6A8^C z^FumOW|-g+8FfG41CfBY3v#=3KNQzZ! zqKsdV*JplR=olw!W1TbAj(YuDlH|#{S0;J`Qe=xm8E0dup@2~p^*kT#GZ|M*|EtNO z0X^I(Pg+(miQy6Oxj!%Ue0xJgpB&H1>JRfOO-V&kp?K<#!?1i6*#tUsD##up`0q5K z$7gQ)2NuJ>4=VE#EwErUBG&%PqlbOwmkBZgArJCZh$U}>wNI>wl z$S$=V4J%|B1b9UGY(OMiLQss&-!8U&XTCSrQOS>Bs^C(z*EFWu0H0y#%Xx5=dl-lB zF{Ld{K@KY9yxeTZMnTa!ul(8v@^eW~4_U89>hK)q@n7g#va|j6T_{n~gtJ~_KA&!U z;;ye|#UIGl3K*!<%y1Dzu?HyerOoHa{3V$`Xg!zdPoRu;=~;FSU@pBD3GXqIwp* z7Ny}yq8ortFu!^8rvJlstKDFZ29;66Vgt@FJTlwH{po9)R(bgWs&u zq+7TI9W)KsChpBPOuTn+z~pr`?r*nUv}zL{?|k7FgElzKiH=Q8Q5s$O)tA#0TS8sD z4^xJdwOyQT(^8)PAn{#E3|EHFq2j*q97TqFPO)^6o9DAu!KtS4hO8b}Iz4IFP5_KP z(`8*xLmUl=`a5AFY;v}yKhPCLZLVZ$c(m&b7_N23)Xu}eo~M+utg~=-63hFdjOvs% zT>j@FyrSwH$z46O9CdU>irr7*0Q^pesa;$#))= z@BJEGSQK$tiA@^Sn909go5=p^3oB^u;G-L-P+Wnd39!+UPGOssO2gm5b@4tW!A^}H5d@ESWESU8P38ck`n z(5o=cDlt$c_w33Sx*a|f3BTYf7D=p(Q)b~y&6h<~Q$`D=&#Hdj*qSbb#724hxe%dU zXum#E9V&LpJz{r9m>(7I^R@Bf$sN>fDepF)=%5_{wZse5y3`~dFoqur-fThs!uuKh z*2%Ygu`5}iD5*n$f7iu$J1wqs`@sV@x~J2>l=!#bPg#>vXGvrHKP2Hif;Z;DF%r#- z`#@Co^R1+(rzh>zaYcOnD}r_!ICtYBIDDb-@B$9Mt$rE&H+=p+K&3oDv-`RLSxejs zZjU)pnd5Kg-S~F;k}M-2{gyU}GeUR$O_OUv@gldJYZ)jVorP`99be!{c@Ds`Yg4xT{gFCO8?7MRDmQ2d>LdUpdBd1HvdPA-{@2_6h?G3|K3y+$fiu^-CXn{ykG=r9r z4*Yj_cBEP>Mv=Gj*2vWRR2U6Yr?X` zJ-Vfu_eND7;v+Mz_RC(W&NS0!!9PVOD=gNtr;a-AgX;f8o#%i!72`if&vBdfEfd|H z<+$rVU9+QyIw^>bv4;6A9MD?n{Sun(mPq*B5V)xROI?6Kd!m*47+Zm@g-Tsegb`5- z$w8$uJS(fx&GgA3;$lWsjdow2A$GeR1?vZh72U-0mD}kulVG%Md@lz2niA|nY<{-rJV!dS? zejdcnu1cD87gsndYbcCHnErh6CS#DO|m5;JUAvJz)p~YYo7MXz)C6a0Vby zyIs_dscsA26RK)zX}!HlckQAt-7cvm=HG{Zej$dkCE~tFRnOj8*-}&Cz_TQiwrm+^ zmG@jsw=A1R3@OAYfJ42R1O(<8ii0|{eyw;D+jix@;l6QJf1b0bopxU-we>+?!wm_^ z@a2ocG|T1Ci{0x#O>_*9<=&Pbb;-H#$4_Lp6V@jx7VMh}`E0Rw!RF6?-IZA*jl@z) zhd4#&%CoTV%??R|eR%V?IzR7_@-Yk_KGX6GxZ0MAh^$zRL%;d&bR^ zE-o&QZc1;THu1A%gpMnLT1E?<7lo2W8b`k$6hf1Az<(*?Wh8v>lHXH2ZP>DVu;a8t zSoy9>!xC4Q{GCLVZEE4NQdCzt*7&j2RDQ+Lk20&dtFe@;3DdYJ53a)Nv5P$|(JiI% ze+-x!reGntO3j2+QAN}E(P5-aa_y-lrHzTRk!9YzeJ&M?&7E9_Q~^wR&`&w9bF)Y# zC9|`f>XY>!Y8Ly#Asv_tpB&-UI*3i|Hc^?mvP$TNs8Wtl-& z2DP-`$VFIeW*yJ8of$drEGjww{w}S+0_2Q5v{`JRW6eRDzi7v&wAG#@GpGL15B)vJ zwl@Uf%;(febC_Ek{yWD>jSb$p8v6}S#ABxRC|paTP){+pwoG4R%CahdMJI! zd&~JvX(@*;ymCwJ>FE^5!0}k>_08bK)2=y=N1;yL@D-Ys$FD-azNPGqtKrmH8tik) zx&Qp*<5n*bfq#=M{Z0u1%v0+A{!1&~4KgXgf#Ej0J9+7S$iVz%2(J zZnAYs{!xtfs~QG^9yxXbtm_!x@QcaVeTi&$Tw6U2i-tNaCd}pVGrXlj_4h9oa+5fB zBKKKRgza{&Fg1lf=+l1qS6$EUnPk9u^e-D$!y5`9Lbgrw(hTVVy<)Jc6k+l z9)vb570g#@Z=0`AxxmhO{0|+FDh5EA+#8mHK3`{znaA>&5vA0)Y3# zJrLe=)4wuTK@i`bI~7>0EE77WB%NeAoI{(4lvw#PEFweB*FGn?GAHI@EU6$lL?#uU zqwF-~ZlOb@57V*o8j?QQf<5vdVxn)3Dcv4B@VqmVb4_*E!&5AT`0fTp30&cMQ!u7# zp~1oC^6BEDK-rWA0tEZ$0)SB&OhD_Ulf|!0!YnvrgUp*zg5Fp^CRQ&bm2xE4z+DuC%Q)i*GBP5?tfBZW z`_~*0CZ@>&lgg-@m|Bz~gTJ&vJ7D|oM_ANO)U)_+5Wuj-*PqP8&%ieY39O9(6et!N z(W7+bjL2+%V`@x*APfX8x+$&l1dD4xwt%{T{`yzqq!_s&HM|N~7t)ZxG(Ln!kzNx4 z;6NCn28Qp)qoJWT*mUBR*~IoT>W}pPa+&nd^bIz3Fpz@9 zvMPfT1S0>uHU(ZLprKz02?8gAMi$%tR*FqEloZ&7VTAKht43?Za&h8-2y>)xx488d^muKQZ zASl^Q>6SY{?R;Q(IF|CxotRl3435T63ydb~$hLy6$kS4{wOtVN{~-d1XM@rD&)?tw zQ5N=iSRdo;_Tvn)UCWvyIV`BCa3lYPI>*6>mGJ7!bD&{ASYw3*8Mk4|qnR-$5J?+ECN za^*M(lVZeFuvak)stgO^NeqCx(y`~bBx6zgjeyY$;Ss9x0~-3Fn0g+))m2Ve@>ng6 z00S&MY!T+~9vvJuMv8|IGxYv9Hcinq+nm7~EL+nA?xJPDWEA{#uW~-+1QD5q>D}rO z__w%97JvDu;9Leme=t_8{XokGH5@?SFEuNv{%<|rLNgBSrYBi8+m2GL3Sh-`$a2yi! zyjZCEYe>6z`bSVwK5&Hp<-x~>*Y^*P&=&_e>!3h9OgY#}B(qj&eH4lXN zdMgBA3(SM7+(KyTS05>5X?*Nz$YcM{e{QG%90K<~TipHt3(9RVPL7S41Cb_n&KOYDt3;iSiGmEw}@oJb8jx|MqVA z_m5A@KRY9qr)%vn(?hLIa8?PGN%vtqQQ)Sir)Vtl$_g?qGn0@DYl~ysKSLF*Gy*C) z0sxG^0yQ^0P`ON`ZVusz%UQU#qrfz$=omFnkQ#!D8vxW?2z%P}@P$*Gq^#*XGDV4tA}8 z@|7cS#UkZm0qLMOe3dGGX>Nv}LJ#LXw;B9FBR~HiN9m_0C0nrIbMg$G?@E*K+@}Y+ zJmm*HfouR+Yjkbe%Zui6awNauicN>x@t#e!?}bmb*(W^o1ok1hPe=0Q-&9l#9nqv> zl%|@b;>BY9^diyKVOY?|gSP|(DLh!Nx3O4K;H7$k*b%Hp%S{!giw0C&D=WvzqS5O4w|0E3~(z*E&Oi) zsSecE&V+uz44mH@^)&t^mf4i){WX4(#s4@>m+2Weiwd2N8lR+mY`Yx%($&Mxmpj}*9x3o6yRz8*Wm{OS3OJA za(`=XJ@J*LF0}7w2L0L;E1XvLD=Q1|It+6S^!PPX^da#Y0lAtO_`Jr8e1R}C9gy_6 zF!hSiYf4Tewjq{Zi25@RdjNfj5&7|4w|<7_alY{DKRyo%pJ9Qni;)9(ypgZz!`706 zqYGIH)Ml_~*&c|a5YMwfiv4R)IlDoUn)i|zb9(u^S|9~no>VTl8xBjovvL+$`Cn@| z>n}zMGHKGtC~KC0xw*N)^L8MHfX&~*L}GwFt?QE4fGU%|lMs4(w6lb8avILWMpByC z`dcjSzdpi3j7UzGg;s9>^#h=XpuYDoPlPC+IzJBT>tV%b4*Nz+ZB~jEmmUhEUyO+& z8hB>kA1ccLoYxJX{1?6OeO_(=*Gu>Fi#fWHCnN?zL6&(o7_Q^{_^lz#o#-hX;O1P; zJ;RcryO#$|kDG6SYeOna`i{Zha*Z5=eX9z2$WcIWD}o3y2d8@_1A!9)TGNG|pq zkEvWuV;R359B9=5Q*WXN)GkbX^x%1Oi;-0hVwuN;uK<7b zMdko_qFal-fJ)F*`yu0sGCGWyZFMhR-E?pZs(9CXG!h{C`c}3)I2@W7Ogx{|tQ6_M z@@%GVpbGKfe_bh51!CaGLmL*xa>0YA(+YMO3YBoxZfMP(-0xT6+U@QuPM& zm}m@`L344V{l_iKJcoqTPoX46&!8B5*&`XZ)vuqW2WZB}r3Ywx@IttgnJw3FO7M6z ztC^n{YM`JDuo3|=o(dKW7T%9}mW8*;xkBu)DM4MRG8_!Nz=O*msge8Frf*3DYy7g& z&YAuhqx;C6GCo_A#O&`_tETQavU)>c`T%3b-nUJUdn~a`W2oA3?6dGQpkv7Wfegc09AlnmCy-)Tn zzrirBzM_9r9OPXp(H=rQ(bW@M=qY|g8JR#U=M`4T={Cy3JAauaurS2R2kdiK4|wy= z=mSP2g;ERL7RLMPc*5MSa;h@l>T<=Wq$MPk<-=Jm^PV5HEK7)Cbc&+?yEup;XGwLg zC}GK%DF;40mQc9~W)jb1spI0KV|>@lfrC{Hsk$VsEbrV%oDT;O#^^{L{bH#oix#6= z3Udt-QtvY{!5*;RJy}v*?+rG=(+w$pp}P5g)Lj!HA7N{$_Jp@z`$iJ2P9u9!{uIIY z#;H+d%dfCmVE`+BA*rv$Q1g{bpkm4&BegfG?4e_QGENS4%@0wsFUt7DEFaZ0&}Bko zE!Cf}ZS*LC3zAF zL6MT``BK3-rx~3LupsUt9X<6EuCHNM2A?_8Eh<${Y+C@8L1v4c{PSnH0jt{6ssZRS zb5M`zamP9u0y^bZ?3}jDqDKl z)?Gi@JF`-u4*=RDtp8DNzoh&cB9rBqM9+RwxbsoSqVh%HM9Wg%8cWFt)K*Bl5IoIF zz?H9rF`uNk)RuVy;cQaiP)7mg5g&o1TZlMXdzQdvq1`36t?z&N!gB|zG<3<4AL)m% z!Y@T=pALH%K@WzS&*k#_oTT-PGxDAV3zjA)MQ zP0nw?2N`loI9(Ra(m&Va6OM|%dBC{R>Yzk5pZE^Dez5eCA@HFH$Ns~^21+U_zLu62 zV2Z$R>D@Iy8_NU1Yu=|n&4HNrn~Uh2U+E*P+7N(r0NHQMyva&;5OHkGs7V#R^ zw|!D{=09y!cGflRR(95nQ6s&TfSDojZsyBS8-90!`JpqHjtn zMuA;$B<_25qVc!}MU1Y$LP70M*u;l)$T2)s`56x;G>}#)V7kFsTlZeFlG7aP$>Z?| z1^fn(JMf<@S2e~`1eo*RrIYpBy2#O?2EG9&6&Z!`aAf3S-$Q~<(v`jm>`VW;GnyP$ zXRBA)#}9f2@ZQ)Y*1f+P8AX2zHLaGbA*&A1y^TJ-F9JfCz`|N;@?5G5uECgI_pez1 zXcodYgWJDhnw9m2>$}SX7_IGmP1CyI7~@AI=LEd$MSm1zWAgnc09Xr~zSA=qM$QI# zqNvC7MdGC;M4B3)#`kYBK%%KSDjBA{&mJc zW8T>III@0+m?w$xcEAspZnmD{9P68011q_~lR0?LjV{|;38pbmMwlmD|9PRWdP+12 zapd(Xld1!Rs5)tuA7eHEb2)x_Qe=5u`9|4ctNmF?@rYjOQxDZHvZRnDALL6;E#u8Vku{U z>p!3Um7GSA5%9Y1A=~Y!r(q2S9Ri<5TRc@2Z0ovfN*EuZ{!vr_QM(dy*?D^Ai}NA- zQv9 zbWKOKJ~j>AQf1Nw-d_UIlcggz1WDbam7Thy2zz!<>mV(luByoWvR&8u|Fl!W)F)@} zK6?9xw{B2np3%C%9O=Nmx~xU{ZwFm6-NTvG2Bd%IfnER=K7dMYRCFFYzkZ|pf4x{T zqVsw*Berg;Hr_6G;J@~4Gpqjz$Zj61@ zPpP5+7MZj|{7c1{g=^`*cYty{fg=z_2!JjYxEvm}8)tRon(m$L1L1VW#(IX?H3dv7 z6v`HwHw;pCG^kNbLpyfV|Dwzru?QCsFn^hR<=Rr7o*Yj%(8%~G82b#eM!-fvVVE}& zz^Iizrb|x(^I;!RDslxV{ht;?W{7m+sV84#pM~XS;Cm0J;9FvwV;_MMh!fnZ`EA+r zmZ4S(Kt_<~=+M6@Idr-&7I9{5SBoAEB;Dx)@I!l1Nk#M}%mGT>B;&Q>0kw3u5}DYJ}O8J`gMKHknZyE{u{3Zj34if&DB&*svgmWcIZ*D#9Wpp7*lmX&gswK zz&9J#vK#q~ee0?U0U#g;QGx=7lWJH4z>uh?Rra^EJ0ok}c_%c6nG*chDhI+>nUd0f zg~t!H*GiPsfhZxEoHeO*evM_`+G25Zwt?X5;^_y{M$FY=m@DuDLyHDHq82sC4U4=3 z>e5%R8BRYzh>n${>!Bx3D`^W)3i{ zBqAhC&CaHii&X?N^Tcr#YZT#Sz(*XOWB7-QCEy$_vJgAYkCCsueJ^N%x7(**WJ>wq zA76tJvkYXHi9YM+5Kfh1D$OkW??5^LUGhk`*6`qnjB^S$$Y(cG(|VBM8me=-wkyEo z;e8gkr9AMDGa9IlAR^bQd)U{^03XHn2vDyi(<_9FM#fdvrtl#_3XdEr-M=fw&2j*UU z;Q~t1U%Xai@4Ns$Rh7_Vn%1rOYN@e|30ta?tNhI;m_N&$cauNg6?pdPyzr(7VervD zx4fQNB^eDFOhebTm(NeOg#j3F%+ZR1q^LUHIuG!X6b$buGoYXNA?)or z!tG&VfT4$O7`jX8lA$C-x*McZx?|{+25AtGlt$?eX_QV82?6O2eQ)$R=l?tJxA`(V z?|tnn)>?bdLvNcG|9^KJFDEC54=5s(c6B{#2B&u@(I;tyW?ueaENtCA?6@*MTXCCw zd$u!~{c$~T`M&SjeW(vWPKNTUGaz+a1fXgR2lokT~O%IzTojQS&4Md=q%WEGsq-2sk!L(b?%T&6xhtLCS;= z&F_Yj=qJnpe)6)S22OwZZzHLXlk(qAKm5QpH`D_lugf_O1y@Y6?>Z{AXz0zPK@A)M z|LzvMm%4g3sRII3(gtoOrb}Ffho2tNN|_ILSCgZtt#oC71SKS#0C6-x&&=5YkHg-l z3>$Ckv?KEGNuD7EynRdR73Ej$+&rc2p!ittN8-ez5Slysg%z?9a6EG{12SEWaF zsqKJ{#|Hml8~F#j(AaJDY{;%m@h(9w6P?{gCs!!9vQx`Yx%sth=T2K7&)p%ZR;$)( zIG9azh$V-fBlGg;9RpqF>~F(=C%W{LrB{6GlR;KYP758m-ULuyHWAVz=u_bmXi0Vc z?FT_GLzzs5g<<`SI)6O?USGKLZf7<{vg$vZ0Br`bA-{VO_vDG~PNN#J{<^v&R zYiN9~?Uf9_v00|IIj$nF0MIy&Ecm#ScGOpM+aPK4D z^@B+l_0MhD)j|1JjBtSj)^X~=V#e4-f2~Tcs8<#sQ#g?X zvW%Od0-)#cVjhQl)0rV|1LEZfu$9(nmKCnWLMCK2j;#{wuVq$cN7wZFw}YI6spzR7 zPft&#WXX?|%DqsZ0*=P4Q|1sIs~1Q~O$eyya3?7idQJt^LHYSoIT@CHFCay@GZ?M| z){>|QuzChyb#v?0ofX`E3~?`#qEpaiYJIlP5|3M(B(y}i5ZQNoE?B6Uq^eE!*T@wJ z;P0lxD@4l__ZoNSia1yZNIhWH>M(xXX>WjryC_M5I z_Xh=h26r|Z&2$wvB#&IczPKBwA3qwKn~R#DTt(2RfLt#yRlQT-sDVI3dTMne9jiAa$aY@V5_vf6w}R^=4pHERez>Q4vv6sDhbB}B7AML|D?lcvOr{(aKH2)+%$0$0esjH+ipnw?7-8sqTG z=A~*r1Ek3nz1p4WYer|*nQ^S}Cm{;ilxdD}GFcNjW|qrnUe$axRGHkNuis3wSJ0!& z@>lHMT}AC#rPqh~VEhwHO9MbU90l23Up^Dm3#Acf=#_SXLx}ockdb&OQuU!cq zkvCoWP|yr$YjFVCegHSGYKfHMnO9Xo$R%I*{sWc;gTpU^^DgVZ=w2rXi$Tthfc?Pg z>Ye$6rt|a!Meu4z*ayg7M23^UCF4I_uBIZ=J5Ll@r2Sm%nY`{s{AoqCbY6Uc5$@2n zHa3FUc*M`kg@i}zRZar^cv6;Nk9SIf?e&!6e~WyQlk>>YMbWe;gIM}3>^6}Ip5)ZM4BeC%7j(I>4p5Ju55SMRie z<<$QjfEqv$2zdpH-iuEfcI~px3J6^bnxAK{EPIIiA5!+B$GkjP3$aiU{D1zbcYr2? zv`C-HkX`ykQ9SRmFnq8VrG&!DWR4eK&nq~--WdQbxrcdpzq{#)t36zD&882MLMw?|4<0)eb13a{T!*pirwofJhD^Hr1EI`DqR6%RGT`> zLnGZsFwko4Yy|72H-pe#V9#R)Hvvnr=xEet(lis|YpJS*&-Qlyw{3vaKLe8($ToUk3K7Z&aLGMQ?# z*OcnbHcIl*C$96kWf7Wner2F>dW}6jnPz$WrSkrny5MB870Tb^&!UNR=73>gvCF5H zS7n;aku12sllJWMv}y3M?O|TMb+Sry$}1?xIsdJGz?)b0{mkKd=|rVJsr8Goe6#Bv zCV7@ivr$`p3M?|F1~~C9By^(prGiKM`E8N(V_4*qn(jtCyz-3P*@CGNdHlruZ;oYKo( z>6D}Y(euKUOtq!Ize|PFh0Lb*SiOB)pso`1_WiSE60PeZt2g)RW!VtlPG6i>uGkSA zMb-0bwi-?)?WsRmRvro4X;Fia4VHRt)|tt(TWj&{~eH=0g^RS1B_YC)WJvbD?c*s7+pN=Y1k0)10$^yQM~|cbGAH1}HmFIcQSbpZQ|7sufyH zTeM1%>Nq{<^{lNKKPsaDL6=3wKQ*1i7Le5{834U1KK7642#`&OvF(@G3&e)(>BVc7 zNqbI>V@PC9zZj5HFQXu|7IVD=1U?c12)a$Em;M(|$nf{>+e+!K5(!yz&Tx_AG8UBj|S zj)LKD8)#h402>Z8q(vRB<{n+ZFDw=~dK>e5lJSZuctpkz-wNgH z0l~kE-xZ(K;~BIUrfEqS@k7oHm67Qe<{39$$6Kv+BPX&(pU#-9@?9bW^j#PDW^J9y zKU*fnnD`J3Vk{EOindt^wwmubG-nU?i>DV4Z4mVUK`5XGX!@W9Fvg7fOGOMpt=j*Jf?2ZH0lr1XGf7b_e);p1>%)Y*+7zEt5zv`R8-x*Zt>0FZ} zFOdOMQz>vIZyKK;`(*D_s(sBAyTmB{?C{TIV9Zp%e1tJdt-{XIC5z!@r^B%TuP*yn zkCvzEWZj~}VEbU`f|!ZZ*Ua}6?k~sfie<7o5?(z9l?8-08-*xQ5d)QexpFcKfTnFO zY*eBv0ose2Ao>o}scqPhX>}xSiFUD)%ByixeECJ8f5x!nE$Nbk&Y_EE_Ri?C@Woyv)f`Q z;q7y3pZ+T2j-|JbY1&AmQ)GNG=RPEljj!XwWY9mSesGTGp2EgeP+mjcdS^A3>haaM zHBXOKQ(+rG(1{4z8uE^98Y;*z7W?8fPi9SjB#h44Pf$LRpjg8HADE_AF&8sC zt@x&7(rCdJRux{Cr2~;kO?;tX!=SUY15_&g0X=05QKWvJ8n==m$H`s)rtyT-;k{1| z?b~aUb00o%J?f>sC*K6HR1?OIe~+YV#v>R<>n9eu>~GCvf$u32e~`59D!_E=9EOQ+ zrwC~yJVbQfQt6Cr9tSr6AEZ^B;lJX9WGO!Bb5QIa7Wu-knH<8y=?wL%@&EOU--xXZ*?z_>bX*2%w>2wkaufSi> zyBEa$`CpezD*+(_)+iOzG4;+P{kAe;j_Bvsh!EcYnWIbh#lJDkMW#n`Lkx7xttR%e|(#6c96fiLRi#Yk%H!n+HS_!p}6i+}C{fIf*eDle)due1>v_ z-3G<}+@DSCpM49(&EgI`iQNY1_5vo?y(BsF9dC~tBta}SpjLWBrs_n3N_-v(}S zu7WzB0c?ZqG#z6F4`zbXHm;%r%olv@E@$e`$5Kl~GeSVOqmpSpnq(Cq%|&@oA~dQV z(=-#b=jEBz2eK>-hUi28YhVFr?Dly@9Ar)^>;_}+}Y1*0{A?Z2o5+w zfC?lIB@e)#76h1s{J@q9K0=8G%AaL_mJkHk<+oqS$gLJ^@PLxIx!_R=~w{X1w$13ymkTBv~{= zwF@G25nG~T{k-!m0W?*+RD0!^Jn8lD;$dwno+hBQj3I|2V5?Ku)ZWBYn@TG55^2wx z#0WLZib@9J5hK#+RWE|`r*$EprH(NqT4rh-%XU3VF~a?$F5o@oHOetdF?Snr$jj(* z5E>9SdL0?>z_Ikf3*akM$*he`gv5K){53D%Km6qAi9g&VfSrD5R{hwcaIzCN`%rJ0JLS&nXQl;&qP9moWqG18w>WDeMW5Da(X+ZC}00Vhu0i5;Nk{|e_jI&(F_ zZQXPLmeLr1mm8(2iG=4Rna+%?@k*&3NG(nN3&#^h+-SOWQQJ4=i?6-2nf9LQP_>-x zl{#yI8rVKU*>xQRR7naM41fMC7?32!lo3z(z)c*5a1&#yEqLvnue0yA4(N@xar0D$ zoWSsRQ{hg{IvC_7A)#Gy?0aGhZ18r>Dxn3Bx>scZ{)QDor1iM;-eDXi8HGKnGZ{VJ~?7o&$HUnZM0YzB$ z=X{Y@l@^|=j}ut~bh+H}(2HIc?(5Hg{NQ%vf5NAB?l&~YD=UmsbG>zOSKCOpz{0*O zK%7`0d5H;sv~tp$XlQ7;CjLNgdQc?7uIqVjHcp$gRY{Nm00TTkS1~{__cQhHE9GfB zkT*@e{AE8^_4d8zPY4M5+MtUb4%%t7dWkqap;v7zSoZiSTgOJkQHf~D601G)@R#wtYu=mK03B9O zXNu~#NNjL|k)_kpS*k}9+R@o*z_y@0MB}_u(vmO@NKCEe*R#GbL>#LR5JfhFxr0HieXOj6ck;X@_QVT%qh)|Fqt--sg3&M8xa9H5~F_Uq+S$*^+AvN80|y&r5lCp!M z`nVARHUfaB&e$;$Ocy+RzfwP&S&WmviO@s>%NqRgk!85y5$ED#yk5cN{rhHT{NZZd z*{SQnv%&qRIzWj3X}E9JXOjK7FlZe@N6G~k84`If64^c(8?eeKVN1~;mKLV}mH^NV zqko$`-kgfRJC4MLT;ZzQQL`!@3^wHlsn(=OOnyyZ8@BfrM4*%ZnyJWvaq0x1aiomB z+bn=g{v3yKyZ6gW=|8_ByiDDn3X8e^7#@EKKQxzOECYnvtXsNTrE4$=y*5?!YWc9u z0g=L`Jc0!d%rbjbKl)h~H1x7T>ojr-Ta`*D)7>TIr|m1E2g~EA`@o9opNJIX2;7}T zg1_*U&cwp$vifViz^AEHNA2yGmzNQ%$eSaDY($Njs?BO8@0TKViO9wbKpr?Pg*plI zVjL8@uM}+b(H+i>wJ(DJIVHh{;Ofrfn(rdAHS_E>?dEy@rwZ29MfN)R1Gg{ctaWmZ z0~7YGTLe*o+q62pg=yt*@wJk}=EPNH1K|*>+T47L(Fh)}>ZvhB{|1syWn|JiaW5#6 zrC>%ctXTpdnM<===?rKScKH@eAF9<7ct!}jdTOYrm9}8l#dvgLPCO$}A3}xsD(%)Tr-%!k zuG=)9hl}~~%9>8{%AC0_>&}DF4M(Ni1cRZPGf0Vy-j2?W-cB2qAUPW=oGXC?xKeBBcJPb_#0`zH7BB{_k=qNq=am4L_t9N$U*8cW*_IL~tdsg~_z|vD^4a(RkA@v<>s;&v?27Jqhpj?w&>)fL!D>h}Rz$e6X zha38D=PEcvVVKbsmQ8pt;+gV>5PDA~sZCF?WX7L&?_YdEG zWKEEj(=0!WoRCh%x6Czp7^??bY^z7ua3z1=d#vRWgZ0LG!Q5 z2W8_@-!sf`0u*H+=DhgigEu#Q|Ht{rU#hcpB7i1iiyG)HGF-h$B5 zP+dC0Cp<&}dhU@KPNTbMf%ao>(&|#mvJ6~=+E-88j!X2a^AUaCI zJV~j72V$jZ|Cegk-o!FSw6_>)y81gltYulZU!urQ{l2BXe4_@{W$t=8P0Cd(2Cc^f zp~G`_d_G)}Z_#~Iqr}J8XFd-})bVzO;3$F{yPSqJ`SO)!^z@*RjYN%{hi&(?^=iT| z1*oB>x$MH8*1&+~9tT7Ln=)Rn4f?cZpB@`52oa7L=0707SN!?Mr*R=>+bvqeegv1H zar`;yi9{tguB?T_f1Q6lq8PWqop4*;@6c?CVhbVd-qJyf2#fg6Q$`?^VgAicufc*X zYm#=4gXsN44vdGWC-aU$AZ037tR$AG5bCo2l|A$D-vC_J(2ytG+V(r-TB7_w=Gr6C zeYG+&)Pu35Iofi$C63pdvtwMW;K3EabCe1tp4_6R()EL=LoSJpB)Zg)MKIj9nRJ>u zXUB8?E?hM6a$#PFWXjV_DugtqZ|uEtiCLoG4A~(K5~HehzT$NfG*j+v`CYL|LAhk2 zF-#Pb12@V6)Z=aj6I}{DTRHUYvNH=`J{>OdyIH(A#CAo*LkAg`}S2_ zRB}|Uol!$Y1y$bE!otO1pg)2C`a7VRI1?I=45t?Jc2U(WYm^@oU+YeLLR&}}`FYYC zakrOLC9N;rf)%}Mq6^URa004Z;ijK^dy!x~-`i5dbzf9Kmu^b_JPDn5ScdaIq@?`1AV zn;QDSG8pcLC{`Qne0~RLwXOoMVKD`~sYir45&m0DSCk$?^FQct|MelD{fxL{vqF^% zFlI?%#*qUCFzb$>z-qKG1Yo?u1P2DeX}YF_#t8KQxS+h-^ycY_`1MOkaj|yQ&x3)* z0X;%-Zio}#f?dx401|mC0AG;FkE9+2=0xmC{P?xHBKOpnb!*oB0rmI@me)?bmrIXJ z#KJ5|@}fR+P>k7b=?o3Vl?0oDRN)U8iAcK9h_V|%LtGy%M~Q)_x?25ARekS|Z?5xx zEq`o7M#CXIB3ERBaZ=nRU7~FAOrRVOe_wrzkJNw+b0QTWS)g>STmZv2{IEt#2gLB< zrpDC@be$@?yVI+iigNPd;a|E%-&_du%bw*ZDIiEq?RcYB5e27`@&FU8ePo??Tz`*6 z$*~2KrVrt)y8&;HT}_A{eFC^k+ZQa|i?YC2u;9R5vN&JDGL$%$S+gYne0}kX-bE>Sl>u~iKL;rma4>KD?T3%&HBdV|)SB=?t%<^p8 zcU)~D1ckEjmt@3Qn?2dp*>xfVXC;C!plBHp(I@*yx@MI*?>xZ3L8y3Hn<_bF=QKMd zZLJ}MDyE=YHif&j5RmT>_eY0lIZyrmCI^;C-NPr{-A1avbSk1A*;jhs{XzCe*UfR! z-Rzs8@Ni!UrMgU~9nEtxto=f7hs(HGf9A~&WUUgX?M^`g&`%=5Cam`i_)nSbm2al> z(0t60_-_$6i7R}lKLs7YA^+BWqu_SsY#kt1(mx+Um$9IW<4;48A<;OD7iM{1g*4c5~ z2vMi^XH)Z*IND?;OL1H@0q03~fJg_E&-xI#nEEL0D_xfOS!pT+7V3nnpz$pJ0hN2d z*-o~)xrXMF9NJ{4Jg{Y|HX%&~y=k#a=0pfcLQ_|d<8vuM$IT6p(v2|ueH;@wApUK2 z9;vq?^cqkD(K0l1nk6)iI{Nf_Gve;J4>z{2F5Ro$!CSv8uw%KwS_Lr_VM^q6{)eXY z3fCon@1j&@yQ*RN1IY1*!HkLW-Ke)zlRt3t^@TAVeefJ5h35Q1y86~P-Fic>4_Dh_*~hBcVx4R- zoWeFkrEh+IeZTs2QcQyqm2X>m76w}1x@%KhdB3m4O#P#epk(liV()Lr=4fJjA+20S zJcS_f5!o$IvzKabr2z_D8hY#oX+I;o=J02d@ROHd?US;tqPC0j`&p8)0t7|hfmmew zk)fELo_-ht6Cnde+w(TKAPBE^*RRqlgk`(I^%5T)j)yI@9 zm5BT9S*Q?B;nqq;{cc3#bIc$=fR)VsBdUiY@~Cg4eGdXP;_0a9!i&)-zWV8>wbgj@ zTQ>jQ5icrfY~g-Zc-RA5U!Uq`Y{WDpAHwyG$JR(%FFTbqm4`!~wIWm~BU#GL;mhD& z>(sqc23HG^JZ!<0xGvy9MMC9$hR38>1ARP8$dIb+TH`vd=a}!plkv2f%lm2FW3G%x z{qQ2L5M%_L*9<8oPHr$UF$ajYwP!;L!=AHKW&=<45Jy17GH7VZYYRF9jF}Ig{-_wS z?dy6sIekSMy8ip}<2y0Oa;Ad}@pc4`cG0zCp74{B(fcLfc@|N>O9w*IRMo(0HY#2@ zUUwF7J%amMWFT<7Qi3t(8h}J6iQ5sNS$POZ9ytNDs8#zU|_J?aNR${Hk)f+b$bUdGGpoJ1q=;b;bB21Y*Z|pZN4y1Muf4 z3MOzXu=O{;@XGz9l3#h~HodcZ$DHr~rQ`l|6a}mAY1XKfp+L7cF1I9mc#DqUTx@Kt zQ(pwO6TrAsGj-t@ey=G4M=3aS%wnY9QxuVGAsY;H+nI=#RU9AxED2mVF?y8mC9rl3 z?@BliC1&dse3H|}@vJ9uSgY>KDWw=YNCG-S9XG^{3d$z@zRW(|r9})1?HaIlSZXW} z9&4toV?{9BM{*ZC=_fcO>AIFRyXo{fE4>;2G=aJBVSPP&L^hAdQx18&{_C z)o{4n9W+5AWc{rjm?gEc0YfRPiVD3)1j_cWV4yQ8C`;X9ZE9Fv$#}B-ixDU(wM@V# zvux(x*5~CDp&_aZJkF37;!iG7G;M|2Tdm^9-N*wQxcuO@Fr4pR$8FaX_l{}IJc8F> zN8ZPvz}q~3u?1fMI{E``gn@sicn)TE((`q^i4StW+`arzLf`K7K2|Nt(Rgr=7E=29 zWsyxBHl)~00RrN;SFY>6|D^Crfq_X2!XXVcE#oBQ%Q)_3BR%&CHB)n^{6;&9?Q>X% zvNXEBJY+XdT#+XVvYXlY3WAy7BUA*a9!Yc2ZGsvKN| zyRtpT(MZ3ft39;`Dz~xVW$WQys2A<3^OzSMzi;QeS|2?%1k&_ZpLwyCN!n0r>U9`X=dw3)xL zn&dqnq5lgEzm%*!a9sQEYB1Basl2iAG0cuj#E%>>geCUk`0$N?!KQ9U@HD!@{`r(Z z*5V5quw-$;runUU96UAFt62o#^!=%EGNd~~*^HbFV3k0yZ0PP0Sp=y2PZqy@Oun|A zt73SRVkr{@w76|vl`hn0E2Fmc;YB_&*j1bt15S<>nzM5K<>b%}85Spa>JG^xo-52| z2PLq^P%qm(hcqI?m5(&OlIPn~e{i=$f+cc#STse*k4=?v{mOz1vwbB1?AJ7`)`9Z_ zhIC3+t@i5m7YtoqoCj8A%|Bcgg@bbN_S|x4Ew{TeuQu}h zMYrve@}K(D^|Vl7calq#!M>(L`-RI)77}ER zYGFs$)c6TUBL>na^Nj%2uwl(A&)hXLMW)XlCYZBt3VIkpjhMLZ|cat)bO=VbK_YI=rat{)jsbwPXrZi)AMXnF6ZycQn zU$=85-)m5x5BVb8n{5Ko?qk&J1Vq0mSe_TZbw{tNT94a-}e%#*ritx9iPc2kVybXWm}zGXdt|Ng#IS`UEh>NqE34y>dvE=Gj-wo{QK&F(KgV z0XO7`p(y-fhR&z`ehJ7RoCsyPRFO~xaJWbBEAoA~rbJHvLJ2Aye`CVIR*plN5&xY} z`j^i66$8>$4T((xkTniGaH=>ZfzuC#v08U)2Q3E*A~8z|0-*M*>wkWGc|F`-d{2bC z7-1{i=o0W_q0dfWI*9at*F#+X6ba;C+klHX04Hcc%xty4qX_rb_*(Q{TmmgW5*z18 zp+b_S5Z`-$j?)WRXe3lb=>>TNl)|eaKRM|)o>eE*Sx1ZR8;Mv8DCbB>h&|rFdEJ)Z0Df?!s+<^Ge%Q?tk+@&B1SJ3mI7Q_jpwf^h>(Br_2~`* z+~`$RlbE!Yv81=b>u1T--4c>fM?(SM0+-rD(3QMHRY=rMJw$fz4+GYC2L zTO>YK5S><_q=gtHeJ0*!NZjkjAXR2TrqbTiPl3ZQ@VWIzU;IVX8?v^$qu?b$8e{ja z+Y{fbNP3Frp-?V=90}Zfzds|kVkHg&^y%gpHL83Oz6dF6cDR=+vKt1ssm>8pG3;RZV+}E?8v;zZyBxzns*|i!<>`UW{_4~iIyHe5 zmD^fBAGHGfTV`G85DxHW#__k$ekuqcMvz4&v(0-w{OIXUub9C{e_t`Q)Uu_H$F@nv zJj?vBI@B}{*=V+~nWNopb1?n~G0h6@;XWX6e|WIikl$C39yKuoEkhC7;zz!*)E2xY zZ31bWA-!~zOjaMJ6!je5kmjOsy-i$>r0ik^Srij#Eq{bqo)_wgjX3JCrKKB?RXnF_8|_7dV4y!am5=(fu}L%dF(mK#;(Ot4~3wuzgqj z#J1$yM`v)ACB$Jlv$!K}CV(%dn*R%*a^WA$GLI9Vp{rmQoB@d{>N>|**GqrdB- z!Z^(eOMjpHgb2;_jtVsCSVUcEwoMeJ>&mh1r*9!G@WN{CI*W;=R*U<~@w9WyIeS=9 zEOuq<8k}?qqo>8}FSKlSL}h^CUsCdQ!Scm?)cM5t1{5l3@xNXyR>2Fj%agb)pQ{5# z*l+S%PZ)Cpmy9MRi1Ei6XO#g6=I7JsK_~r1N?KtCUsDx_Dw|oJJ0`xPuR=cVvO%{} zOBrZ5OIX#G`dlNsk(`d#h(xCnT4u{)&uT#P3SK&HVj9_rKc_ftsWu-Aoonvs<<09S?e^ zK|PI(p<}A^1h7%Ne%;QGGb~) zZpBtkw4_W@YbDI43UnZk;fBUGeu}{QLfNPh=baWG1eYY48w3qSNWUa-PGgoU450I8Mf#J%9 zhHm2?$pBnZ`$aa?1`Sj_YjAEX(4J2`*IidwMeYNa5If)T>)aLy+U&wo$F0UEtuGqM zu^$EEmqF@bBp}3q7xWekoMQ~;H3D8{Krd-^NI~&+R)Z8E*~UgLJ4%cLv=(;W5i7nc88J;fNzdE8g& zUQ$kYLFvj}P7Ia(u+8Ik&FyhcyvCNHra8SyoM$GYX4@i?3DB4k4i8C{qWF4>P_umM6LrY8CN!`9EB2|OBfv>I_IolH5pL3M^u|pEb%o85lS#{tL>At5H zNzyslIHmoR?AL2CTfP6dHABtO=Z7yPE0&A`?Bsdw!HMWTQt^e$2kgSXlJ>dZ(k|Bu3<&`}h zE;_3}lQfVeSlb7be(%BsMbj=|qr)7QwamaU(cyR;+PuBeO^R}HdWIY!1*Nlr6PU5v zO!AK#jtHx^L9Px=8abN9j}Or~erD`FL$!W|ebq5;^7_vTy-XtxDlHV5UyW3v?$5hj zv5rtzWzp|;z&kPn*8si8?GSkLT$$<0*xo2raf23o+D=Rb(pZO-oF14*MA`u!I#{q4 z1Yatl2O@L*?8j-_pny0pV`XkgY^O6JsDIWc1zXmCA3cwqJfxu0M+^0qJ7KD zY8?cDdif?;JT^Z8WVw&FUzx7H=Kr2~_!+LAnSKf!;OSRT?i!=1cQNM6J%8?~FXL0hE7qq{}bPaV}Ui%ffIPg##1?uzP( zPI^k+L-Vlv{IT?M=p1yHZD4Gi_p0*_b3N#6Tlwl_h^Fna5(Ie7O4y(sLm&pV0fVX; z#_fqR=M(Q|*~n;L2hB;UHn=|?#=q;jM^c{iL1a3UP)a7-bjlB{?!7OxKQQWd@K6Z` zhL60%C706s6-`;*008Xd0r*ocfSffOCGOVAbn7uy6i4rU9|||L^AEtgMak?03Q$g? z>73tfnK>8>H$51^Y#{|iWR9GGEBB*@u+dI8oddXu{@NI3>xaN2^*Y{MO_DAjN*MTxu+iZdP@C%756wEN zbS;8SNTUQ35hvV zCOO_kignCLD`mvjuj1K!ZPxw>)|vFlI$(dHryKsU!*pZMCDHT9Tq0TsqzW37 zd?t!`^_$26X9-$H6v!-YQ`Zi+2v!=UU};L6q8|>B3vz$ML zq;##DCpDjfZr*S3EP%q4RimVzK@skJ2)y0H2bwFfQdqn00F$k3O^Tp1du^IvV@Q2{ zY~^DYFWtZw8xB@$hSwhPh0tR>K&uLg46Tlw>0+WU7)^q`F_#YElVSur$ok5)87$Hm6AMsqmf6{62R zRDMDq<)dyhL780^lJ;J(~uBfW@71?+TE&ndj)PSmw}iqZO1yHO*)v)a?x#rDTh z<&$R2ovHDaF5j}L9b%ukCn#2ddZLVbXpMzFqiBy(*f@^yD`k%@_76PQMbW3;6m$aBa%k$0%s6EdP8=a)DhBe z-7|$$BPvzPO8Qg-GINZ9qqUc6Xxd~k0=N*`)VjIh==F0gmA*F+E3rxjnSskNT~Fp(n-^FR86kmFTp(bwfE<`($6IzJ>6=<`kOHQsEv%oCWVaMzr3AGpIlvByd?;Gv z-jEQIE3Q(P)nqZL#R~N(EE?95$=r*1f%98Sa@T%uW9)lJD4-<&TF_}lHCL2Z*4%sC zfR70kTptF4sdCPkf#Ymr`sE`bx+t(}e0(iTzT`VMqk@M*yh)Z^`X?x0{r{$Op|nfX zABgydz|?{T%a=&)r+-hgs#;mPR4o$;v?{c>-pd70rhUBiD|m!Tdbi-n(S2a^VWKux5xVTyYg8U~yz%BqMl-#U{Fj_%{ zPfi__xX%uAnS+*@{oJ$b=uy!<<}&F#NT7Lk2(a(dtK?rSm}L2QeX&?$!00_zU2HK| z=1hVPW50bkeY1loDH#lke5gaRGwU=>^N!=g@KgDDT1#8Pl5c4 z)*@bY%bri2_#kU+cwvS#K5<2r;DTx0G}3RNoMLnzhH?bFtLFqL7lade0=K9_On;cg zhw^?_@$Ia_IJemK`DP3PPzx;q=>0y)PslVW&jJxRN&3?kP(uVzJ=u}HBBcG^W-G-# z!F0T~F@ryV%jgcM#wPc+Dr4q`=|B=A6CdBeYy%2j-9~Mm)z|1?8C^6E-z{Z9*_u>O zM~R=j^Oxr1jDgQ0v@##(2NiPcl8=ZQ4C@hq`fpD49d23Ax4moY+Rm#8mI`~LkJQIT z%0ZD+A|=C$4`kX5P0-fi;l5R$#rxP8mPBOP(YAJE-%aK zfxnt}e#|~w`aUqDmN)h+_wQnU3HtCJ_!K3t--}9K15x);h?F-*S5xC|=S{6R567G5 zHZJKHc)&NJq~H?32%gxMEHN^bNDcU(9QX;rA7i4xrve z=5^qv>S%1>RLQbe6}_$a8x+HcGD2H_Q{&fOtl*hu$N<|ARD8RxPulGiLvaTi@9*|} zJ<6E6M#f97m9V4c~AdE^W znLam!FTxRdku3NY?^0!)ig>e%fKwd`jl#@pAU$-(t}!LRN(k>>z=U6V+b8%O9IKB1 z2pC1{Aw*ykL?#C8$CDC3+8nEB0y-jsP?qo z3i)+O@}Vg&W+1JU-=M}tB5To_KhO6#Q8}3ENH2ey4o?OoBooR4tYPw6Q_2-*WJC#) zY71E{SnPo0*N(#|$pO`8*Y(w@;h=}pXQ!wZ5ivN3eN2*+zG)~92;rTVw5DWJVlyma zR@k#^+}V=o>nWopC}AzJgElev+k|yb*&(U*F3LZN#%OJYn80>%J`R}g&xCNeuwVn(#zS71=9W5;KSnDASRyF8GoqPy75_@I} z34rrVXWEyQ%Dtq8qyOa-Xj$5n z9?>4eUZe3FQ4XD)m;hMujZf8U$BLsce^JUZ^)MK22$0r(k5HBgjZz-#>Lcz`0mBb6 zPL~Q0|G&zvJRYjH4G#u`F^;v78D^5QWQ~xqM+-`1NwzV03n`N9z05H7HQ|*Oin5!c zWH%;Mwu+K{5~FOBZ7|_G`rhyTz5jmqALpFE=6;@Mp5Hmwecjjn+$8+d%QNWcSU5Ik z(UYGPXbnTsmSrthO1VJr^vPN|Jx39?B3I+?N4uY7s@rqhPi3OXF&k4vaIhFo9NAfZP^3BG33ZD>f2zSr}q42A!le|Bo;5v z@jNX34RtIjP{jQ3$nyaKRw|=qdEyl_Jh-Q@urO@xTtd5=M~5cN`@oIUjS59`;(3bu zF}y&MZbhJ!48odOi~S|S;?%jPF()vd%5K@3Xv#$dt0zl2Ess9iR0el=h8|pEtW|Gf zc|ek!NZy4RPZJ7gv@NB{vV0JLS&`qDG^%AQja)eMz+fJfI$Q|mIcw;|RS^Ir$D=8t zN>hg{fd11nmU!DM%hKIo=zkE%d#mJliJLpkBo3eOLBxQ?3wmbSTYM+EcrWX}*estK zNzQ2@oNV;%;Z7yAOr-g}cYde_7cz_I>z6uaNP`$Fry~=KMLsM~{YwVm{Z&sluAP=L zi09+u0QyhudhEB%eQ}xNEjP42m|F|4)&&Yz(cabvYDxh! z#bv%d6p&w8ztTnQP~g1ohD3c-4Wt)9OoF?&Z)nP>;)8bx`oxGvv=amU?yHxLFZelj zR0Yrbaro|4gT(%^k#`a}2Qf~L?m5R}X>0z)$ud|46Fcl7ui&Joho5?#^bRVOf2 z_A|nY_eC*o%oZey9Dv2oU_i!?EL++}2=8M~qDuN*8iL<9ZmkW!K7)*7?pzzKyYraw zt|0V660su-q8r`nh@XbY2EVaaF1x%U!pTopxWd(@Fi}-O#^9nNThKumrrWkxJ}h}a zMP9~q|A8k?LB+b_Kj5jB$1xyFz#WA($1e5XCI(0asAh@O2Zu@lo7B3&LxA~LA0_$( z7&e^u(2M5yC4FoBvj&whv0Nusd(R1`0KRV-+Ci(^Yw4DidoSSn1a&}~u$74lqlhRJUJssoRup3ypXK-biD8!3hBtF?2U`2^8 z0g;lYXbHj$%(#4{AtznhrsJ*9ye1U_v0W%u+_5|?}o@IaNK4_3$_X7BTSnmaCx!S zOXY?2^heV0eA;=wSh^NOtloJY7p`I;GfrAugTyiIgSF_R$8=@@7|O$_Pwe%(^6ID; zw#G-%tsYS!AUmPa8oq^+3peWqTwfMnIxq6l~@ou$!q_#AC<|O>N+D z!$wtu@y`&}1MA>Fxse4ZQ*jj8K}jA_i(8=w{M=ZV4%c32<-#n8vKl;Sdp~MFb}Y5D zAJE5YyuMBeD6TQJh&PD+&5*i3;{v&JHExSDUFxX{Srcu!etuEndge{;GMJS~SDv;y zC1~@Jbqj9DlTM-XcM*vkB)f;>EXCA-0mt3c3@YQ2glsnW&0rXNo)~*r(y9zG?f+Iv zY-4(Jy~bw88vMO(?fP&IBfc|f)31sY4~dy51PBV04~JDBBb0^WUxAqVwsci-1F?9& za|cgrjtAfNgovJ-A54tw?id)j!OonxmQXcuK&z{`p*fuPBx!hv*@aFpYPTY2Ob|!!{p=!0m}&K1Os{jlo|@7ZTBDCuj#y_ z88Cp9I0~m~^(5P$Iyo^0@r-GlC%DV@%s|>NkLZ1_tlQM+i z0=`!%RMYYh?z>B@^1r81BNu6#yn0^%hKOoKAr4r1BHVq+Q`?|MZsE5A=-2XCW0-*5 zDFtK_T4E$imJsMHhbsl4mqpS{qMEbVqC%2}P9DDbQFfIS)Zrpn!Fph2uXAnEn(mbP2*-_bN24G)(NZKyPetx9~_HL_3BgbR&}lIEni1%@2= zh@+_;x-k?dR?0n1=wH8gDoqW94=IyYA*M;f_E|&3quM|ju~p@DdcZSHt|dQtlDKeI znB(2-?CiwSa?l^8(k9^!JkTm1-qDAGfh>&N5rEUWs(AxtqN?~&`--M^oAceM3Lz*+ zP*9xuaDRN{yk0sfY|$Nd%9uK5WUZH?y()M%K;#MXlHqaSP@DUMubsNlQulNNiX!z_ z^by|potH5uE=aPi6<+kzdwsV)KV^q5NH7Np3(I*qC}1CxjEJK4GyE>-_g&Aq^~LD( z>S!PT$?6|bxzD_gKXzR1Bl{>#z|)EZiHET2;I5J^nO?grIKH`CP%ih+kg-)g{a^IHl*Vx`Ob=4+sL)T&tnty8W1;Wn#~SNrN@HSTT6Ip@Dl$~+uC_s z6e~Z!z?L)GzBavAd@c4XWs#OikRiu$GL=KZN*At`?aN&Yf9ZWEnXj|jo<%ZgnAPcT zl^@_CPx-*)QyQs@s%tXCaVqC}i}#j5hyevRy(-<``mg!M zHv~wrO03^k#H8Dbqi3Y9_D|ib(pbA?$%b)R2}TD_Caxj@^*`qOau+|9KXajGPY$DVcO4N}P>41R*5!BsamI;GFCrmjM=$SuJ80;i zYPcQzb4#Qby;mHpu9vx4;nlfjCcA&LqG9ob^PniiE>(ZcQGKnMJ-V0yeE@2{#3OzV z`BX-^N6z`{cBG>OeAFko)W-+nTaJif!vN9r{f2^gFi3NGDwI z-xQ+M$TLO*dhfM5umcpC$@u{?)d26QGvYhe@C6hkU+y0gCNy1m{`RJzTS3jyZKosy z>LA9skq^$nWKM6E3do;w_MB;BeP#QfseK7-`|UuSBP*Z~GVlDZa&#eCdrbZlZ?l_V z!~*j#Dykh^SH#en>CNqe%Dzie0ns#eTyw`!ZXqcn(X^N?=|z*02;sdK{l{znj1T!f z?od`9*#c^c>OpN$U*9xO!t2O~#vf)Z)3lDLc)k0J+dKQjdX31XUjJ(>MChC4Cao%u z;+~W7h|KYL6L9jn=&?rom3Qel1NcSgy_sAQ{MXY29?^MSFYqQAJABSDF~-` zukH~G95y=pgUSd6=Ryzj7pgsIweB-q*^UcZws|YPN)$Fg24pH{(PMfV1-FK4LwU}|5$dG-52fV72gUjinL z_dsZkC*lzOk|tDCY(+i_pL0%;Fg`tBZljRdLqLi+9gtJZ*B>vx;91zHSZ&|I-NrOY z2@sV(<%V6MhyC2D6&krK@k^`xnrnJsR{;A`1{{BHwq8+Jg&qUrK~|O-g~HlvuZ=XX zpjH-@uzncWW;d`uIhp^WvX|9!^LZP-W;|NEmS&suoKY*pMMVN<58|wOqA3MjcH}g* zj(iLG<90dcya{fX3YAO6HW`_nhxxIU*Dn9nzV6+{LQTISuipRkBiP-s>4(wTN&fs^ zH`@gVaHoo1WN=1*Sd=vo@`=BrPL23_OKVzg+yM)$#6ksUW6Zo|?lLbpbSRt63U)*w z0dM1DUrLJ#kAA+XX5M-7vvo>|TCrG1Q}O-341ZaClN>O1ebA?&oY>GF{?eegri@i> z|Aa3g!y%=&J8PTWd251Q!b!~iB;eC;phloaK(u3W(lxN-%@35*B) zG7DSizH+7DKuJzo=hgH^i?6-zLE1(5d)yA8&JLHEM43Q;83Nya7PS(YuOax9Y~P;V zU8ff$kV|K`IrL$ev92kYvndumiOMq2{czJ-im`ZfmC!mts20H!&omH;m;O^{Zm!P7 zw9rCMO8KG}$@?ps$3`h_=-B%=Lw7eS+tbHuaOlKCDF)oJ--4QTu8^$Q70*E#m;y@! z{^S-tYG=dzQwnqy^A89J^S2x+=5JEz|8E^wNiL3ZF5LOA^tq@p0tW*8NxnTjQT~K~ zY;0^kk8lbit!k#^6&1B5zVl$?aUhB0 zY30ph$0u)_jG4p3=+O(8>hC=GTB<(~OmMqjg}Y^uv$Fo#4C46sSk=+7Vs&-(`T6)l zy~CU>-u3G!u8$Czo*jgouWy_4X5&Pmr^K4*+y}Rc-C8Uy9DH$~(}t;PtC*=uvp|D7 z`!s_Z>o|i3rysz9eE9HTU}xzIK&94c0>_xZ-GcO|ai9bF?*ZWj!e+|6_4lQvUmEdd zW@fU6eb+BOOfWKn(JLfM=-LU0q$fQ_=7T@WjU_1h2Rj zdx>Rc?S=<%N=|p<6zK4qDIqVp*zKagIA{uTQdMuRHGm$bwX;Ge6~Wl)s{%>ouLM^4 z9n5=H7_@lQ8dO;*Ev{?i5i(%sHDf53ZzxnFa0-9Sg#WnG)c>ZL3^Mow`ESFX4^z^X zRJt!;69!yNN5o$vZ2I=GTpq(#x%houNRER2gW?)(g5Ny&d+@}KT)xQeXxajuTgyth zZM>R^oTkIBD{bVEOaAj?u_n$n+_hsU_x6czKt^mMWRU&&eX49^!Eop#l2?-kf6pWo zd%_9V8bdzX(dELWkpxIz$h`fZIaNG1vTNIam*+^3s?QU<ay7x&^PyAUrPNSy z4<^M?-?<|!D=Rx#>98Fj{#7Ou=oj0LJh?h%?1`mu6C&=uQ%Ffc;e_{m=2pl3qI@XG zqVgPS?JP-;InG$8xCerQmR((4{n4~y%TZC4%mJFp^332KdZ_hg`ma4)^i>HMBh?>1 zOdlE199vkBQ~*6wrsoR-2_;CaPf&ATE=Y>Up<6@nnP&HJd3pH;`Ldd_d|byd*mU*} zY1(6}=38hgS2}`R2?w-5K!fsS!xQsn8cajPKBrg+W8gbCi6v1w9IQy)3ovjal*cnt z!EvT0@y9St;mwY+%braBjW6-!F%rBHZki1ZBV_c?o9I-n;eKo?NT_MV>ii#x9PH{q8-Ri^9csF^*hpk6HPaEx*w+Uu2s>km$fjc!nsFu}a z*{IC!&wQK)IIhDs7Xn!$F6rW#zG4J3dV_ zNA*J3i=L8sut_M*HJRd8n{gt<iORx)Z|Kn<;cpo^5-lB>=hGgji`D5-*I>-pZ)_e|^wPAKT=@)c$+D{i1YaYowiHKT0 zRb6RweYV=PW|K^|Sad0lscot1VzL^ZS9S49RCCEUE>8QSI-AHhtrUdP`Kx7+gwYn7 z1YQ=EbO3RmjY(dsN6pJ14@X8=oRpQM=?Tu*j0BT^h84`|KzVoCpQM~k*aetiRItdd z!uy}>8iB_8Np)=It-iUW-@aq?%!jwxY%t*L4Joms3ruq=YqQ7n8EkllhQ<1k*XWra z$$V`;jV-;u!;0aU;9I*2TduRubC-!0;!ZuZIJhby#EzTr(`* zN?Lnb%yM5N62xL7Fb)W$K2FQTEsUgSJcaaY<9)5wQga;d)asVk8=iNK?<{Kidbtt1y{t(*5`Hd(6Pzcy&tcdpH6%hh&b0|%{D(`nQct_(Rv zgriF1*`Vo6GHcm?9RuVwaN9jaXR;a{E5sYSPG7+0pUx+vJD$5j#%Wjv%A|~-VHm!; z#Tl?ka647q+x|WO$!5Rsw*~v7J66(?>UeJNT$X!n8eUOn$q_KvI;S$iNHM!$eFPFi z$o=NG6CH?%c_-9HF(3O%b2~|TATHsNgQ2_KAx_T2{50d6b?KiJmzn<_3=HC{a`SWm7|n~>CHd|IK38&}z4KC)r{H(MT<#bDCY zQe&y;=E5UKVw<+_h!0tEQ`{6jTn#5U&xAtb`c>AL59Twj*;J5WRX!f$N>WFeXn2)L zC9m`e&O3q7v^aOAvmh&y;;3~H_A=7Ih_6cHZ6>kMk;Vz>YHxpF!G(=*tR_fD-^9us zcdBbRa_||Q*)R9$+1sh|&J@@wmKjr*9^t#S<<`r&*xL3zZu6N-Us2+G`}S?tZo0zC z`@K{p7;i-09|M6QiTJqRU|>9k|sp-6S1%x&eMX&S1W|IIBgH@y5P9L}6C=C&m;Byo@_;<}c| zq%C?IdRHmlV^DRXbjEH+hQa(!fPNxWBNiGsPq3p;J>6P77{Dn6ZjpZHFM5UUv&Av!GOZ+An$%{z-! zyIE=QxSY*`iJ%r#@X?JWY2l~8wmfOsa_jR&-7bOyiDKrwyYHqi;n^I+tDSM zwwXeovnTu}W6zlP_80k&XN7TFHd-@-rf_%OSu@-67+Bj86iMie)tfdOnMaAC{w)#j3|H##BVIDWzN`Cv$%M z!%cndU8sb^oAaEAv3t0v!CI!pKdH(JreAC3 z+O`#*5x#8#eT`*EC6HC2tX96>x$UY+4eU@wZaXKAqBl1vkE`f+aBud0sgih7_;_P1 z@;^GX>|wl1mCy8kyUxS>uUifNvb+A83tvq@7JEfu+yR;v8UYM{ViPm}SVX=iz2+N^ zT$JZyHPA{!E+Py3N!>du;?Ts?Q;-QogZ@E}s^TqIc=sN8s7ky{rH9AK9vse@PaKU7 z-M>ZeFCSsLNEv`-eP;*_1qBZva_{9da2TG)3MeX%Pqz^=uJq;d1+w4tMxZtk-v>#8 zhK(Ms-fn|`yv^>(B-};yO66{Kv~zXAt-VRJfJs&2+pb;|cr--VqTqWZgN32zg zWHP=YOX7bb7`)`~Sm{U;CVXo1`FYbhx^3ir%8$dR1Ekofjmmj*TG08=PkHCV-)7aW z>w05fza|-izA!3j_OTU&nWP1A6NnIso%7MEl)-ti=Vh)#Cn_Rh16NQ`^Y!&D5({PF zdRrE8I3;@9(t94$$4?%TnV!yPZf+h9S4@28%&KYPk99LSUz?^wpqA@2%HzTj;TVRo zpbt<2`n?DGsY4u2h(&L4is-(yM!S0v^7#)^j#W`H6U!;hE5Q8PRt5UAWLRVP+S56JVVeWC#R7TMjxs#Srz z&pxH*LZChLnvV+pnJSTD>aI%lSXRvf3RKh5Ga|HLl0JO&DV3GLaUUO=7H%5w-#N)a zbUvlNf6x2YOm%iJZ{sGcZ=ClQW*uRy0k#wcgL$~PxbMY6g{JR@4U@{d5Mqz$X_)Eg zU|tm77bXEY$bSMGR=7z+1q%R{BiF5gb&eTbh?&=h|D$>}OEz5ee`H>p0#n41F94me zI$Kfs|X zIP-u0AtZWOFtJix!zajp=Tb54xv2xbWv~qq^_%FW zxxE_v`zEPgR8qa7zFUZneP_jF7|0;xB6!^q z<>{MtrLPH-m2eW0Lyo`5y6#E~Gl*j4bR}q$Br=^>+h#rxpL|cLTcN>oN~bREZF|E` ze)mMSv|wzpayYVH49W2|ep;M)cqUI5_2(Qk@U*!*fA>N^rs5^uO>MWYg8NGv^z}eREIvtc;Ld zVheQM56#&UQXdkpYw~9I%zQ(@ffYF!z^{DW`@+|hiE>YQU`*4h*V2GdRLdAb$c{f? zls#AW-newk#Ath#M+5(PdSm4KrrsUBOTIevtAz7fPTrYR1^b@w;q87*(N6>N4$yf{ z*e9qak*TEi&$90W@xyUXm1RCvb=mCedwl49FliqIa&$#shaZXJ3@gj}ng6%0>lQj& ztVa|L)y)RdjzStJ<sw6t(pR= z0xSpclno>9>q|3QuTL^Y#eUz!Fswf4D=Wg(l-{5qm5@*3+d=43EZJU4SF$`FZnZxF z0qHWKJdf5ViutWevb*vcw6X~TuX~^RJGPixbTQz6y$^Ez*w4>lSln*|pTNhQmZ>Hv z!uY$s5@^mlo{1!-RD9fs+|XqidqK!JFkV!&wIIahi|ln3Jvu5o5?ahSKX9_Ei`>*c zIJr^0hA>MP>-0fie;*%Dq@<=+fd$A%MYE30*Yl->Ca=<1CW*i?p%oAs|If*MFJFlq zft=e{O_jyeAvmd`8T3UE_V49Q$=|K7{`jNoUT;ihq@f-=Sx z1g>C@G4AG&p+h0oCV&2Z{CEAK!OFtf+(KGMhjg{q(M}&>!a+*tLof3dks8mUM#nL& z>auokr!dpsBKUoHSUZ6~eBN4^7q1~0F5-LMEb{7i?o^d!#Ol^oE1SQ~0eJZd-7#7r zOCBFbwFG2H`ji^XjwBo6%^;}TUHU`LKfLQI%2SH2H((Vj<$Sk~he#sAcu={_7V1!8 z35m@}?=b3kNz1FX+`q?*wU--F+5G5;vQ)o9sDAc^iao?d%<_Q*lPQ!J-yoZB#hbIY zodjWFK9M{_L#cz{QA)F(Df?cMsoBjkqPx=e$p?{?(YcbEe2u0e`Ylr)>6+EOODCJ# zwW{_er6n%YkkaC>%aniLJ#XnMRMP#;bs&@JwtUfv9~G_H?sDF;vEvix+)95eqy@$AE*ybP>ZgRLOw zVRyduA^(h{*Y@k8sU)fCX<7G+WopKC?|I?if!%2~mkrTmvzRLiBB2u1jPIPETf6-p z@E7=rN@+)D2Ai9=i4_cGQLvr&mky77xXGZupW{EO>+2`>_V(`c-4+&LVN|@5 z5N29X7Qb&_3}o0?^^r6pkqlu<^3p$fc{%v{hLx0cs8+e$ACHd+y*<^wI3F%+Rt(z{ zACf;zn@(Bw*{(nE5>J3CQhTy8TZq<$;$*wURvr}{=Y^p(Q1U1RloEgQ>UsvaWNB!AG-@`}Kx9^F13-uZb4Eea%om8Busg zr2;Yaji(@yNFzREPI33J`6};Ryn@7AuJsSg;=%_a*LqbZhxX`VE<7U=r7n(~hrvi``u?Uw!neK$~gMtC7yB$mR_Mw zvVmR5z9?WK#~wIRqj<^>kAjC<+`p5x<+i-WhPgf3I18TJ61)2|ju~Tb)iVkdVuWtB z)r_XVf8TOX44v+$6T10{6IQOeqt_MYLHud4BJFVCX6sbO^!^eMUi(_Q z{4tndxhTc>1;}Zp?pfZ?6nQ19>N7tNFNv7@MCSI0i=Ui714T8CJ2eUzT2Edz*)zn& z!0>u=j6cNj{HYe`$K(tARACxvQcBIJy@UvTzu@sj__-}(%H`f8|uh(s;ks zJ+8LS(}@$kRQ(H=&1V0#=WzTWBI1J-ikF{b346m~miJ|nEBgy*o=G3b|u`#k!Pi=qw?X7w8$MU*nCpR7GP z6(<{h-i%V6lA3dgjohzPxYTJoa#^wq?kHLXAU*1Gz4yAHb2y`qywlmS>+aTvZPB4W z{@3XgIRgfoLPC0#X9-iZv+s+$`5Ml4F+>;EaPzdxZ6Z#ViKT0znGTC z_$4K^fPnNe*sZhF(0a?K8J-=)ZS8Af@L9bfrUI33|NUqeHP8`weE^6Bpqr3LJ_Q~{ zy^svBIls;6QUAh4+eKZ+spQ4U-2utdiuL{+$vw^LANygJ0okbL=JgOlWfzz@iVrH? z25O?L3k^W5*K#Y~GK+fgGr7IVgeiRdVBJayCnL%(mfpv@S7x^}YHrZ(#c7+@$IRnt zQIzZG`rqBD30@`g@i}hx#zfG)7FV-9g8;9`Xw~5N?0vkB(%#4P#zg7USrn^CQen2J zYoGYRtTO^Nn1%RSqU(&n?;`66`P3$B!K_O0OR*q5^{SV0KAv}i=!T8RPB*N z*m!4efQMMmOCAk6G$ZxFg5@JjVl$h5q7Ynj{yUxrTY`W$@?Sanr$~SS*qp{@yp4^T zfei9<+a+YB020eR7+*JHB@2Y2w^VZe#0j zLyC=}9`h}48pq`a1B6o9FsURd6&2*-c3%?5GLSa#|B2c%*TJP0tQy&n+9c2k)vf>` zxB|Wv@kY`2_r)*DrLotq+mJI-)c23-!FoNKh7Kxn4uhtuTEB3vS#x}~3&EtPc2Egz zH}5`7Wm1UlzbWa;r>mgdn*(TVeA6j8o|qn4P(q@?bYz2px-XpPh1*~i-ksa%6VR|a zngJYLN*WqMvNrgRl{QX6vTxVx$SOtmFw+q&vIB~i9V$EHoOkP=_U#4~E<>F0C+ErB zCJs#>J}^b(Y;u~86X!oSpKs+;sfrB+vlG0v&#Zdku|>d6A8^C z^FumOW|-g+8FfG41CfBY3v#=3KNQzZ! zqKsdV*JplR=olw!W1TbAj(YuDlH|#{S0;J`Qe=xm8E0dup@2~p^*kT#GZ|M*|EtNO z0X^I(Pg+(miQy6Oxj!%Ue0xJgpB&H1>JRfOO-V&kp?K<#!?1i6*#tUsD##up`0q5K z$7gQ)2NuJ>4=VE#EwErUBG&%PqlbOwmkBZgArJCZh$U}>wNI>wl z$S$=V4J%|B1b9UGY(OMiLQss&-!8U&XTCSrQOS>Bs^C(z*EFWu0H0y#%Xx5=dl-lB zF{Ld{K@KY9yxeTZMnTa!ul(8v@^eW~4_U89>hK)q@n7g#va|j6T_{n~gtJ~_KA&!U z;;ye|#UIGl3K*!<%y1Dzu?HyerOoHa{3V$`Xg!zdPoRu;=~;FSU@pBD3GXqIwp* z7Ny}yq8ortFu!^8rvJlstKDFZ29;66Vgt@FJTlwH{po9)R(bgWs&u zq+7TI9W)KsChpBPOuTn+z~pr`?r*nUv}zL{?|k7FgElzKiH=Q8Q5s$O)tA#0TS8sD z4^xJdwOyQT(^8)PAn{#E3|EHFq2j*q97TqFPO)^6o9DAu!KtS4hO8b}Iz4IFP5_KP z(`8*xLmUl=`a5AFY;v}yKhPCLZLVZ$c(m&b7_N23)Xu}eo~M+utg~=-63hFdjOvs% zT>j@FyrSwH$z46O9CdU>irr7*0Q^pesa;$#))= z@BJEGSQK$tiA@^Sn909go5=p^3oB^u;G-L-P+Wnd39!+UPGOssO2gm5b@4tW!A^}H5d@ESWESU8P38ck`n z(5o=cDlt$c_w33Sx*a|f3BTYf7D=p(Q)b~y&6h<~Q$`D=&#Hdj*qSbb#724hxe%dU zXum#E9V&LpJz{r9m>(7I^R@Bf$sN>fDepF)=%5_{wZse5y3`~dFoqur-fThs!uuKh z*2%Ygu`5}iD5*n$f7iu$J1wqs`@sV@x~J2>l=!#bPg#>vXGvrHKP2Hif;Z;DF%r#- z`#@Co^R1+(rzh>zaYcOnD}r_!ICtYBIDDb-@B$9Mt$rE&H+=p+K&3oDv-`RLSxejs zZjU)pnd5Kg-S~F;k}M-2{gyU}GeUR$O_OUv@gldJYZ)jVorP`99be!{c@Ds`Yg4xT{gFCO8?7MRDmQ2d>LdUpdBd1HvdPA-{@2_6h?G3|K3y+$fiu^-CXn{ykG=r9r z4*Yj_cBEP>Mv=Gj*2vWRR2U6Yr?X` zJ-Vfu_eND7;v+Mz_RC(W&NS0!!9PVOD=gNtr;a-AgX;f8o#%i!72`if&vBdfEfd|H z<+$rVU9+QyIw^>bv4;6A9MD?n{Sun(mPq*B5V)xROI?6Kd!m*47+Zm@g-Tsegb`5- z$w8$uJS(fx&GgA3;$lWsjdow2A$GeR1?vZh72U-0mD}kulVG%Md@lz2niA|nY<{-rJV!dS? zejdcnu1cD87gsndYbcCHnErh6CS#DO|m5;JUAvJz)p~YYo7MXz)C6a0Vby zyIs_dscsA26RK)zX}!HlckQAt-7cvm=HG{Zej$dkCE~tFRnOj8*-}&Cz_TQiwrm+^ zmG@jsw=A1R3@OAYfJ42R1O(<8ii0|{eyw;D+jix@;l6QJf1b0bopxU-we>+?!wm_^ z@a2ocG|T1Ci{0x#O>_*9<=&Pbb;-H#$4_Lp6V@jx7VMh}`E0Rw!RF6?-IZA*jl@z) zhd4#&%CoTV%??R|eR%V?IzR7_@-Yk_KGX6GxZ0MAh^$zRL%;d&bR^ zE-o&QZc1;THu1A%gpMnLT1E?<7lo2W8b`k$6hf1Az<(*?Wh8v>lHXH2ZP>DVu;a8t zSoy9>!xC4Q{GCLVZEE4NQdCzt*7&j2RDQ+Lk20&dtFe@;3DdYJ53a)Nv5P$|(JiI% ze+-x!reGntO3j2+QAN}E(P5-aa_y-lrHzTRk!9YzeJ&M?&7E9_Q~^wR&`&w9bF)Y# zC9|`f>XY>!Y8Ly#Asv_tpB&-UI*3i|Hc^?mvP$TNs8Wtl-& z2DP-`$VFIeW*yJ8of$drEGjww{w}S+0_2Q5v{`JRW6eRDzi7v&wAG#@GpGL15B)vJ zwl@Uf%;(febC_Ek{yWD>jSb$p8v6}S#ABxRC|paTP){+pwoG4R%CahdMJI! zd&~JvX(@*;ymCwJ>FE^5!0}k>_08bK)2=y=N1;yL@D-Ys$FD-azNPGqtKrmH8tik) zx&Qp*<5n*bfq#=M{Z0u1%v0+A{!1&~4KgXgf#Ej0J9+7S$iVz%2(J zZnAYs{!xtfs~QG^9yxXbtm_!x@QcaVeTi&$Tw6U2i-tNaCd}pVGrXlj_4h9oa+5fB zBKKKRgza{&Fg1lf=+l1qS6$EUnPk9u^e-D$!y5`9Lbgrw(hTVVy<)Jc6k+l z9)vb570g#@Z=0`AxxmhO{0|+FDh5EA+#8mHK3`{znaA>&5vA0)Y3# zJrLe=)4wuTK@i`bI~7>0EE77WB%NeAoI{(4lvw#PEFweB*FGn?GAHI@EU6$lL?#uU zqwF-~ZlOb@57V*o8j?QQf<5vdVxn)3Dcv4B@VqmVb4_*E!&5AT`0fTp30&cMQ!u7# zp~1oC^6BEDK-rWA0tEZ$0)SB&OhD_Ulf|!0!YnvrgUp*zg5Fp^CRQ&bm2xE4z+DuC%Q)i*GBP5?tfBZW z`_~*0CZ@>&lgg-@m|Bz~gTJ&vJ7D|oM_ANO)U)_+5Wuj-*PqP8&%ieY39O9(6et!N z(W7+bjL2+%V`@x*APfX8x+$&l1dD4xwt%{T{`yzqq!_s&HM|N~7t)ZxG(Ln!kzNx4 z;6NCn28Qp)qoJWT*mUBR*~IoT>W}pPa+&nd^bIz3Fpz@9 zvMPfT1S0>uHU(ZLprKz02?8gAMi$%tR*FqEloZ&7VTAKht43?Za&h8-2y>)xx488d^muKQZ zASl^Q>6SY{?R;Q(IF|CxotRl3435T63ydb~$hLy6$kS4{wOtVN{~-d1XM@rD&)?tw zQ5N=iSRdo;_Tvn)UCWvyIV`BCa3lYPI>*6>mGJ7!bD&{ASYw3*8Mk4|qnR-$5J?+ECN za^*M(lVZeFuvak)stgO^NeqCx(y`~bBx6zgjeyY$;Ss9x0~-3Fn0g+))m2Ve@>ng6 z00S&MY!T+~9vvJuMv8|IGxYv9Hcinq+nm7~EL+nA?xJPDWEA{#uW~-+1QD5q>D}rO z__w%97JvDu;9Leme=t_8{XokGH5@?SFEuNv{%<|rLNgBSrYBi8+m2GL3Sh-`$a2yi! zyjZCEYe>6z`bSVwK5&Hp<-x~>*Y^*P&=&_e>!3h9OgY#}B(qj&eH4lXN zdMgBA3(SM7+(KyTS05>5X?*Nz$YcM{e{QG%90K<~TipHt3(9RVPL7S41Cb_n&KOYDt3;iSiGmEw}@oJb8jx|MqVA z_m5A@KRY9qr)%vn(?hLIa8?PGN%vtqQQ)Sir)Vtl$_g?qGn0@DYl~ysKSLF*Gy*C) z0sxG^0yQ^0P`ON`ZVusz%UQU#qrfz$=omFnkQ#!D8vxW?2z%P}@P$*Gq^#*XGDV4tA}8 z@|7cS#UkZm0qLMOe3dGGX>Nv}LJ#LXw;B9FBR~HiN9m_0C0nrIbMg$G?@E*K+@}Y+ zJmm*HfouR+Yjkbe%Zui6awNauicN>x@t#e!?}bmb*(W^o1ok1hPe=0Q-&9l#9nqv> zl%|@b;>BY9^diyKVOY?|gSP|(DLh!Nx3O4K;H7$k*b%Hp%S{!giw0C&D=WvzqS5O4w|0E3~(z*E&Oi) zsSecE&V+uz44mH@^)&t^mf4i){WX4(#s4@>m+2Weiwd2N8lR+mY`Yx%($&Mxmpj}*9x3o6yRz8*Wm{OS3OJA za(`=XJ@J*LF0}7w2L0L;E1XvLD=Q1|It+6S^!PPX^da#Y0lAtO_`Jr8e1R}C9gy_6 zF!hSiYf4Tewjq{Zi25@RdjNfj5&7|4w|<7_alY{DKRyo%pJ9Qni;)9(ypgZz!`706 zqYGIH)Ml_~*&c|a5YMwfiv4R)IlDoUn)i|zb9(u^S|9~no>VTl8xBjovvL+$`Cn@| z>n}zMGHKGtC~KC0xw*N)^L8MHfX&~*L}GwFt?QE4fGU%|lMs4(w6lb8avILWMpByC z`dcjSzdpi3j7UzGg;s9>^#h=XpuYDoPlPC+IzJBT>tV%b4*Nz+ZB~jEmmUhEUyO+& z8hB>kA1ccLoYxJX{1?6OeO_(=*Gu>Fi#fWHCnN?zL6&(o7_Q^{_^lz#o#-hX;O1P; zJ;RcryO#$|kDG6SYeOna`i{Zha*Z5=eX9z2$WcIWD}o3y2d8@_1A!9)TGNG|pq zkEvWuV;R359B9=5Q*WXN)GkbX^x%1Oi;-0hVwuN;uK<7b zMdko_qFal-fJ)F*`yu0sGCGWyZFMhR-E?pZs(9CXG!h{C`c}3)I2@W7Ogx{|tQ6_M z@@%GVpbGKfe_bh51!CaGLmL*xa>0YA(+YMO3YBoxZfMP(-0xT6+U@QuPM& zm}m@`L344V{l_iKJcoqTPoX46&!8B5*&`XZ)vuqW2WZB}r3Ywx@IttgnJw3FO7M6z ztC^n{YM`JDuo3|=o(dKW7T%9}mW8*;xkBu)DM4MRG8_!Nz=O*msge8Frf*3DYy7g& z&YAuhqx;C6GCo_A#O&`_tETQavU)>c`T%3b-nUJUdn~a`W2oA3?6dGQpkv7Wfegc09AlnmCy-)Tn zzrirBzM_9r9OPXp(H=rQ(bW@M=qY|g8JR#U=M`4T={Cy3JAauaurS2R2kdiK4|wy= z=mSP2g;ERL7RLMPc*5MSa;h@l>T<=Wq$MPk<-=Jm^PV5HEK7)Cbc&+?yEup;XGwLg zC}GK%DF;40mQc9~W)jb1spI0KV|>@lfrC{Hsk$VsEbrV%oDT;O#^^{L{bH#oix#6= z3Udt-QtvY{!5*;RJy}v*?+rG=(+w$pp}P5g)Lj!HA7N{$_Jp@z`$iJ2P9u9!{uIIY z#;H+d%dfCmVE`+BA*rv$Q1g{bpkm4&BegfG?4e_QGENS4%@0wsFUt7DEFaZ0&}Bko zE!Cf}ZS*LC3zAF zL6MT``BK3-rx~3LupsUt9X<6EuCHNM2A?_8Eh<${Y+C@8L1v4c{PSnH0jt{6ssZRS zb5M`zamP9u0y^bZ?3}jDqDKl z)?Gi@JF`-u4*=RDtp8DNzoh&cB9rBqM9+RwxbsoSqVh%HM9Wg%8cWFt)K*Bl5IoIF zz?H9rF`uNk)RuVy;cQaiP)7mg5g&o1TZlMXdzQdvq1`36t?z&N!gB|zG<3<4AL)m% z!Y@T=pALH%K@WzS&*k#_oTT-PGxDAV3zjA)MQ zP0nw?2N`loI9(Ra(m&Va6OM|%dBC{R>Yzk5pZE^Dez5eCA@HFH$Ns~^21+U_zLu62 zV2Z$R>D@Iy8_NU1Yu=|n&4HNrn~Uh2U+E*P+7N(r0NHQMyva&;5OHkGs7V#R^ zw|!D{=09y!cGflRR(95nQ6s&TfSDojZsyBS8-90!`JpqHjtn zMuA;$B<_25qVc!}MU1Y$LP70M*u;l)$T2)s`56x;G>}#)V7kFsTlZeFlG7aP$>Z?| z1^fn(JMf<@S2e~`1eo*RrIYpBy2#O?2EG9&6&Z!`aAf3S-$Q~<(v`jm>`VW;GnyP$ zXRBA)#}9f2@ZQ)Y*1f+P8AX2zHLaGbA*&A1y^TJ-F9JfCz`|N;@?5G5uECgI_pez1 zXcodYgWJDhnw9m2>$}SX7_IGmP1CyI7~@AI=LEd$MSm1zWAgnc09Xr~zSA=qM$QI# zqNvC7MdGC;M4B3)#`kYBK%%KSDjBA{&mJc zW8T>III@0+m?w$xcEAspZnmD{9P68011q_~lR0?LjV{|;38pbmMwlmD|9PRWdP+12 zapd(Xld1!Rs5)tuA7eHEb2)x_Qe=5u`9|4ctNmF?@rYjOQxDZHvZRnDALL6;E#u8Vku{U z>p!3Um7GSA5%9Y1A=~Y!r(q2S9Ri<5TRc@2Z0ovfN*EuZ{!vr_QM(dy*?D^Ai}NA- zQv9 zbWKOKJ~j>AQf1Nw-d_UIlcggz1WDbam7Thy2zz!<>mV(luByoWvR&8u|Fl!W)F)@} zK6?9xw{B2np3%C%9O=Nmx~xU{ZwFm6-NTvG2Bd%IfnER=K7dMYRCFFYzkZ|pf4x{T zqVsw*Berg;Hr_6G;J@~4Gpqjz$Zj61@ zPpP5+7MZj|{7c1{g=^`*cYty{fg=z_2!JjYxEvm}8)tRon(m$L1L1VW#(IX?H3dv7 z6v`HwHw;pCG^kNbLpyfV|Dwzru?QCsFn^hR<=Rr7o*Yj%(8%~G82b#eM!-fvVVE}& zz^Iizrb|x(^I;!RDslxV{ht;?W{7m+sV84#pM~XS;Cm0J;9FvwV;_MMh!fnZ`EA+r zmZ4S(Kt_<~=+M6@Idr-&7I9{5SBoAEB;Dx)@I!l1Nk#M}%mGT>B;&Q>0kw3u5}DYJ}O8J`gMKHknZyE{u{3Zj34if&DB&*svgmWcIZ*D#9Wpp7*lmX&gswK zz&9J#vK#q~ee0?U0U#g;QGx=7lWJH4z>uh?Rra^EJ0ok}c_%c6nG*chDhI+>nUd0f zg~t!H*GiPsfhZxEoHeO*evM_`+G25Zwt?X5;^_y{M$FY=m@DuDLyHDHq82sC4U4=3 z>e5%R8BRYzh>n${>!Bx3D`^W)3i{ zBqAhC&CaHii&X?N^Tcr#YZT#Sz(*XOWB7-QCEy$_vJgAYkCCsueJ^N%x7(**WJ>wq zA76tJvkYXHi9YM+5Kfh1D$OkW??5^LUGhk`*6`qnjB^S$$Y(cG(|VBM8me=-wkyEo z;e8gkr9AMDGa9IlAR^bQd)U{^03XHn2vDyi(<_9FM#fdvrtl#_3XdEr-M=fw&2j*UU z;Q~t1U%Xai@4Ns$Rh7_Vn%1rOYN@e|30ta?tNhI;m_N&$cauNg6?pdPyzr(7VervD zx4fQNB^eDFOhebTm(NeOg#j3F%+ZR1q^LUHIuG!X6b$buGoYXNA?)or z!tG&VfT4$O7`jX8lA$C-x*McZx?|{+25AtGlt$?eX_QV82?6O2eQ)$R=l?tJxA`(V z?|tnn)>?bdLvNcG|9^KJFDEC54=5s(c6B{#2B&u@(I;tyW?ueaENtCA?6@*MTXCCw zd$u!~{c$~T`M&SjeW(vWPKNTUGaz+a1fXgR2lokT~O%IzTojQS&4Md=q%WEGsq-2sk!L(b?%T&6xhtLCS;= z&F_Yj=qJnpe)6)S22OwZZzHLXlk(qAKm5QpH`D_lugf_O1y@Y6?>Z{AXz0zPK@A)M z|LzvMm%4g3sRII3(gtoOrb}Ffho2tNN|_ILSCgZtt#oC71SKS#0C6-x&&=5YkHg-l z3>$Ckv?KEGNuD7EynRdR73Ej$+&rc2p!ittN8-ez5Slysg%z?9a6EG{12SEWaF zsqKJ{#|Hml8~F#j(AaJDY{;%m@h(9w6P?{gCs!!9vQx`Yx%sth=T2K7&)p%ZR;$)( zIG9azh$V-fBlGg;9RpqF>~F(=C%W{LrB{6GlR;KYP758m-ULuyHWAVz=u_bmXi0Vc z?FT_GLzzs5g<<`SI)6O?USGKLZf7<{vg$vZ0Br`bA-{VO_vDG~PNN#J{<^v&R zYiN9~?Uf9_v00|IIj$nF0MIy&Ecm#ScGOpM+aPK4D z^@B+l_0MhD)j|1JjBtSj)^X~=V#e4-f2~Tcs8<#sQ#g?X zvW%Od0-)#cVjhQl)0rV|1LEZfu$9(nmKCnWLMCK2j;#{wuVq$cN7wZFw}YI6spzR7 zPft&#WXX?|%DqsZ0*=P4Q|1sIs~1Q~O$eyya3?7idQJt^LHYSoIT@CHFCay@GZ?M| z){>|QuzChyb#v?0ofX`E3~?`#qEpaiYJIlP5|3M(B(y}i5ZQNoE?B6Uq^eE!*T@wJ z;P0lxD@4l__ZoNSia1yZNIhWH>M(xXX>WjryC_M5I z_Xh=h26r|Z&2$wvB#&IczPKBwA3qwKn~R#DTt(2RfLt#yRlQT-sDVI3dTMne9jiAa$aY@V5_vf6w}R^=4pHERez>Q4vv6sDhbB}B7AML|D?lcvOr{(aKH2)+%$0$0esjH+ipnw?7-8sqTG z=A~*r1Ek3nz1p4WYer|*nQ^S}Cm{;ilxdD}GFcNjW|qrnUe$axRGHkNuis3wSJ0!& z@>lHMT}AC#rPqh~VEhwHO9MbU90l23Up^Dm3#Acf=#_SXLx}ockdb&OQuU!cq zkvCoWP|yr$YjFVCegHSGYKfHMnO9Xo$R%I*{sWc;gTpU^^DgVZ=w2rXi$Tthfc?Pg z>Ye$6rt|a!Meu4z*ayg7M23^UCF4I_uBIZ=J5Ll@r2Sm%nY`{s{AoqCbY6Uc5$@2n zHa3FUc*M`kg@i}zRZar^cv6;Nk9SIf?e&!6e~WyQlk>>YMbWe;gIM}3>^6}Ip5)ZM4BeC%7j(I>4p5Ju55SMRie z<<$QjfEqv$2zdpH-iuEfcI~px3J6^bnxAK{EPIIiA5!+B$GkjP3$aiU{D1zbcYr2? zv`C-HkX`ykQ9SRmFnq8VrG&!DWR4eK&nq~--WdQbxrcdpzq{#)t36zD&882MLMw?|4<0)eb13a{T!*pirwofJhD^Hr1EI`DqR6%RGT`> zLnGZsFwko4Yy|72H-pe#V9#R)Hvvnr=xEet(lis|YpJS*&-Qlyw{3vaKLe8($ToUk3K7Z&aLGMQ?# z*OcnbHcIl*C$96kWf7Wner2F>dW}6jnPz$WrSkrny5MB870Tb^&!UNR=73>gvCF5H zS7n;aku12sllJWMv}y3M?O|TMb+Sry$}1?xIsdJGz?)b0{mkKd=|rVJsr8Goe6#Bv zCV7@ivr$`p3M?|F1~~C9By^(prGiKM`E8N(V_4*qn(jtCyz-3P*@CGNdHlruZ;oYKo( z>6D}Y(euKUOtq!Ize|PFh0Lb*SiOB)pso`1_WiSE60PeZt2g)RW!VtlPG6i>uGkSA zMb-0bwi-?)?WsRmRvro4X;Fia4VHRt)|tt(TWj&{~eH=0g^RS1B_YC)WJvbD?c*s7+pN=Y1k0)10$^yQM~|cbGAH1}HmFIcQSbpZQ|7sufyH zTeM1%>Nq{<^{lNKKPsaDL6=3wKQ*1i7Le5{834U1KK7642#`&OvF(@G3&e)(>BVc7 zNqbI>V@PC9zZj5HFQXu|7IVD=1U?c12)a$Em;M(|$nf{>+e+!K5(!yz&Tx_AG8UBj|S zj)LKD8)#h402>Z8q(vRB<{n+ZFDw=~dK>e5lJSZuctpkz-wNgH z0l~kE-xZ(K;~BIUrfEqS@k7oHm67Qe<{39$$6Kv+BPX&(pU#-9@?9bW^j#PDW^J9y zKU*fnnD`J3Vk{EOindt^wwmubG-nU?i>DV4Z4mVUK`5XGX!@W9Fvg7fOGOMpt=j*Jf?2ZH0lr1XGf7b_e);p1>%)Y*+7zEt5zv`R8-x*Zt>0FZ} zFOdOMQz>vIZyKK;`(*D_s(sBAyTmB{?C{TIV9Zp%e1tJdt-{XIC5z!@r^B%TuP*yn zkCvzEWZj~}VEbU`f|!ZZ*Ua}6?k~sfie<7o5?(z9l?8-08-*xQ5d)QexpFcKfTnFO zY*eBv0ose2Ao>o}scqPhX>}xSiFUD)%ByixeECJ8f5x!nE$Nbk&Y_EE_Ri?C@Woyv)f`Q z;q7y3pZ+T2j-|JbY1&AmQ)GNG=RPEljj!XwWY9mSesGTGp2EgeP+mjcdS^A3>haaM zHBXOKQ(+rG(1{4z8uE^98Y;*z7W?8fPi9SjB#h44Pf$LRpjg8HADE_AF&8sC zt@x&7(rCdJRux{Cr2~;kO?;tX!=SUY15_&g0X=05QKWvJ8n==m$H`s)rtyT-;k{1| z?b~aUb00o%J?f>sC*K6HR1?OIe~+YV#v>R<>n9eu>~GCvf$u32e~`59D!_E=9EOQ+ zrwC~yJVbQfQt6Cr9tSr6AEZ^B;lJX9WGO!Bb5QIa7Wu-knH<8y=?wL%@&EOU--xXZ*?z_>bX*2%w>2wkaufSi> zyBEa$`CpezD*+(_)+iOzG4;+P{kAe;j_Bvsh!EcYnWIbh#lJDkMW#n`Lkx7xttR%e|(#6c96fiLRi#Yk%H!n+HS_!p}6i+}C{fIf*eDle)due1>v_ z-3G<}+@DSCpM49(&EgI`iQNY1_5vo?y(BsF9dC~tBta}SpjLWBrs_n3N_-v(}S zu7WzB0c?ZqG#z6F4`zbXHm;%r%olv@E@$e`$5Kl~GeSVOqmpSpnq(Cq%|&@oA~dQV z(=-#b=jEBz2eK>-hUi28YhVFr?Dly@9Ar)^>;_}+}Y1*0{A?Z2o5+w zfC?lIB@e)#76h1s{J@q9K0=8G%AaL_mJkHk<+oqS$gLJ^@PLxIx!_R=~w{X1w$13ymkTBv~{= zwF@G25nG~T{k-!m0W?*+RD0!^Jn8lD;$dwno+hBQj3I|2V5?Ku)ZWBYn@TG55^2wx z#0WLZib@9J5hK#+RWE|`r*$EprH(NqT4rh-%XU3VF~a?$F5o@oHOetdF?Snr$jj(* z5E>9SdL0?>z_Ikf3*akM$*he`gv5K){53D%Km6qAi9g&VfSrD5R{hwcaIzCN`%rJ0JLS&nXQl;&qP9moWqG18w>WDeMW5Da(X+ZC}00Vhu0i5;Nk{|e_jI&(F_ zZQXPLmeLr1mm8(2iG=4Rna+%?@k*&3NG(nN3&#^h+-SOWQQJ4=i?6-2nf9LQP_>-x zl{#yI8rVKU*>xQRR7naM41fMC7?32!lo3z(z)c*5a1&#yEqLvnue0yA4(N@xar0D$ zoWSsRQ{hg{IvC_7A)#Gy?0aGhZ18r>Dxn3Bx>scZ{)QDor1iM;-eDXi8HGKnGZ{VJ~?7o&$HUnZM0YzB$ z=X{Y@l@^|=j}ut~bh+H}(2HIc?(5Hg{NQ%vf5NAB?l&~YD=UmsbG>zOSKCOpz{0*O zK%7`0d5H;sv~tp$XlQ7;CjLNgdQc?7uIqVjHcp$gRY{Nm00TTkS1~{__cQhHE9GfB zkT*@e{AE8^_4d8zPY4M5+MtUb4%%t7dWkqap;v7zSoZiSTgOJkQHf~D601G)@R#wtYu=mK03B9O zXNu~#NNjL|k)_kpS*k}9+R@o*z_y@0MB}_u(vmO@NKCEe*R#GbL>#LR5JfhFxr0HieXOj6ck;X@_QVT%qh)|Fqt--sg3&M8xa9H5~F_Uq+S$*^+AvN80|y&r5lCp!M z`nVARHUfaB&e$;$Ocy+RzfwP&S&WmviO@s>%NqRgk!85y5$ED#yk5cN{rhHT{NZZd z*{SQnv%&qRIzWj3X}E9JXOjK7FlZe@N6G~k84`If64^c(8?eeKVN1~;mKLV}mH^NV zqko$`-kgfRJC4MLT;ZzQQL`!@3^wHlsn(=OOnyyZ8@BfrM4*%ZnyJWvaq0x1aiomB z+bn=g{v3yKyZ6gW=|8_ByiDDn3X8e^7#@EKKQxzOECYnvtXsNTrE4$=y*5?!YWc9u z0g=L`Jc0!d%rbjbKl)h~H1x7T>ojr-Ta`*D)7>TIr|m1E2g~EA`@o9opNJIX2;7}T zg1_*U&cwp$vifViz^AEHNA2yGmzNQ%$eSaDY($Njs?BO8@0TKViO9wbKpr?Pg*plI zVjL8@uM}+b(H+i>wJ(DJIVHh{;Ofrfn(rdAHS_E>?dEy@rwZ29MfN)R1Gg{ctaWmZ z0~7YGTLe*o+q62pg=yt*@wJk}=EPNH1K|*>+T47L(Fh)}>ZvhB{|1syWn|JiaW5#6 zrC>%ctXTpdnM<===?rKScKH@eAF9<7ct!}jdTOYrm9}8l#dvgLPCO$}A3}xsD(%)Tr-%!k zuG=)9hl}~~%9>8{%AC0_>&}DF4M(Ni1cRZPGf0Vy-j2?W-cB2qAUPW=oGXC?xKeBBcJPb_#0`zH7BB{_k=qNq=am4L_t9N$U*8cW*_IL~tdsg~_z|vD^4a(RkA@v<>s;&v?27Jqhpj?w&>)fL!D>h}Rz$e6X zha38D=PEcvVVKbsmQ8pt;+gV>5PDA~sZCF?WX7L&?_YdEG zWKEEj(=0!WoRCh%x6Czp7^??bY^z7ua3z1=d#vRWgZ0LG!Q5 z2W8_@-!sf`0u*H+=DhgigEu#Q|Ht{rU#hcpB7i1iiyG)HGF-h$B5 zP+dC0Cp<&}dhU@KPNTbMf%ao>(&|#mvJ6~=+E-88j!X2a^AUaCI zJV~j72V$jZ|Cegk-o!FSw6_>)y81gltYulZU!urQ{l2BXe4_@{W$t=8P0Cd(2Cc^f zp~G`_d_G)}Z_#~Iqr}J8XFd-})bVzO;3$F{yPSqJ`SO)!^z@*RjYN%{hi&(?^=iT| z1*oB>x$MH8*1&+~9tT7Ln=)Rn4f?cZpB@`52oa7L=0707SN!?Mr*R=>+bvqeegv1H zar`;yi9{tguB?T_f1Q6lq8PWqop4*;@6c?CVhbVd-qJyf2#fg6Q$`?^VgAicufc*X zYm#=4gXsN44vdGWC-aU$AZ037tR$AG5bCo2l|A$D-vC_J(2ytG+V(r-TB7_w=Gr6C zeYG+&)Pu35Iofi$C63pdvtwMW;K3EabCe1tp4_6R()EL=LoSJpB)Zg)MKIj9nRJ>u zXUB8?E?hM6a$#PFWXjV_DugtqZ|uEtiCLoG4A~(K5~HehzT$NfG*j+v`CYL|LAhk2 zF-#Pb12@V6)Z=aj6I}{DTRHUYvNH=`J{>OdyIH(A#CAo*LkAg`}S2_ zRB}|Uol!$Y1y$bE!otO1pg)2C`a7VRI1?I=45t?Jc2U(WYm^@oU+YeLLR&}}`FYYC zakrOLC9N;rf)%}Mq6^URa004Z;ijK^dy!x~-`i5dbzf9Kmu^b_JPDn5ScdaIq@?`1AV zn;QDSG8pcLC{`Qne0~RLwXOoMVKD`~sYir45&m0DSCk$?^FQct|MelD{fxL{vqF^% zFlI?%#*qUCFzb$>z-qKG1Yo?u1P2DeX}YF_#t8KQxS+h-^ycY_`1MOkaj|yQ&x3)* z0X;%-Zio}#f?dx401|mC0AG;FkE9+2=0xmC{P?xHBKOpnb!*oB0rmI@me)?bmrIXJ z#KJ5|@}fR+P>k7b=?o3Vl?0oDRN)U8iAcK9h_V|%LtGy%M~Q)_x?25ARekS|Z?5xx zEq`o7M#CXIB3ERBaZ=nRU7~FAOrRVOe_wrzkJNw+b0QTWS)g>STmZv2{IEt#2gLB< zrpDC@be$@?yVI+iigNPd;a|E%-&_du%bw*ZDIiEq?RcYB5e27`@&FU8ePo??Tz`*6 z$*~2KrVrt)y8&;HT}_A{eFC^k+ZQa|i?YC2u;9R5vN&JDGL$%$S+gYne0}kX-bE>Sl>u~iKL;rma4>KD?T3%&HBdV|)SB=?t%<^p8 zcU)~D1ckEjmt@3Qn?2dp*>xfVXC;C!plBHp(I@*yx@MI*?>xZ3L8y3Hn<_bF=QKMd zZLJ}MDyE=YHif&j5RmT>_eY0lIZyrmCI^;C-NPr{-A1avbSk1A*;jhs{XzCe*UfR! z-Rzs8@Ni!UrMgU~9nEtxto=f7hs(HGf9A~&WUUgX?M^`g&`%=5Cam`i_)nSbm2al> z(0t60_-_$6i7R}lKLs7YA^+BWqu_SsY#kt1(mx+Um$9IW<4;48A<;OD7iM{1g*4c5~ z2vMi^XH)Z*IND?;OL1H@0q03~fJg_E&-xI#nEEL0D_xfOS!pT+7V3nnpz$pJ0hN2d z*-o~)xrXMF9NJ{4Jg{Y|HX%&~y=k#a=0pfcLQ_|d<8vuM$IT6p(v2|ueH;@wApUK2 z9;vq?^cqkD(K0l1nk6)iI{Nf_Gve;J4>z{2F5Ro$!CSv8uw%KwS_Lr_VM^q6{)eXY z3fCon@1j&@yQ*RN1IY1*!HkLW-Ke)zlRt3t^@TAVeefJ5h35Q1y86~P-Fic>4_Dh_*~hBcVx4R- zoWeFkrEh+IeZTs2QcQyqm2X>m76w}1x@%KhdB3m4O#P#epk(liV()Lr=4fJjA+20S zJcS_f5!o$IvzKabr2z_D8hY#oX+I;o=J02d@ROHd?US;tqPC0j`&p8)0t7|hfmmew zk)fELo_-ht6Cnde+w(TKAPBE^*RRqlgk`(I^%5T)j)yI@9 zm5BT9S*Q?B;nqq;{cc3#bIc$=fR)VsBdUiY@~Cg4eGdXP;_0a9!i&)-zWV8>wbgj@ zTQ>jQ5icrfY~g-Zc-RA5U!Uq`Y{WDpAHwyG$JR(%FFTbqm4`!~wIWm~BU#GL;mhD& z>(sqc23HG^JZ!<0xGvy9MMC9$hR38>1ARP8$dIb+TH`vd=a}!plkv2f%lm2FW3G%x z{qQ2L5M%_L*9<8oPHr$UF$ajYwP!;L!=AHKW&=<45Jy17GH7VZYYRF9jF}Ig{-_wS z?dy6sIekSMy8ip}<2y0Oa;Ad}@pc4`cG0zCp74{B(fcLfc@|N>O9w*IRMo(0HY#2@ zUUwF7J%amMWFT<7Qi3t(8h}J6iQ5sNS$POZ9ytNDs8#zU|_J?aNR${Hk)f+b$bUdGGpoJ1q=;b;bB21Y*Z|pZN4y1Muf4 z3MOzXu=O{;@XGz9l3#h~HodcZ$DHr~rQ`l|6a}mAY1XKfp+L7cF1I9mc#DqUTx@Kt zQ(pwO6TrAsGj-t@ey=G4M=3aS%wnY9QxuVGAsY;H+nI=#RU9AxED2mVF?y8mC9rl3 z?@BliC1&dse3H|}@vJ9uSgY>KDWw=YNCG-S9XG^{3d$z@zRW(|r9})1?HaIlSZXW} z9&4toV?{9BM{*ZC=_fcO>AIFRyXo{fE4>;2G=aJBVSPP&L^hAdQx18&{_C z)o{4n9W+5AWc{rjm?gEc0YfRPiVD3)1j_cWV4yQ8C`;X9ZE9Fv$#}B-ixDU(wM@V# zvux(x*5~CDp&_aZJkF37;!iG7G;M|2Tdm^9-N*wQxcuO@Fr4pR$8FaX_l{}IJc8F> zN8ZPvz}q~3u?1fMI{E``gn@sicn)TE((`q^i4StW+`arzLf`K7K2|Nt(Rgr=7E=29 zWsyxBHl)~00RrN;SFY>6|D^Crfq_X2!XXVcE#oBQ%Q)_3BR%&CHB)n^{6;&9?Q>X% zvNXEBJY+XdT#+XVvYXlY3WAy7BUA*a9!Yc2ZGsvKN| zyRtpT(MZ3ft39;`Dz~xVW$WQys2A<3^OzSMzi;QeS|2?%1k&_ZpLwyCN!n0r>U9`X=dw3)xL zn&dqnq5lgEzm%*!a9sQEYB1Basl2iAG0cuj#E%>>geCUk`0$N?!KQ9U@HD!@{`r(Z z*5V5quw-$;runUU96UAFt62o#^!=%EGNd~~*^HbFV3k0yZ0PP0Sp=y2PZqy@Oun|A zt73SRVkr{@w76|vl`hn0E2Fmc;YB_&*j1bt15S<>nzM5K<>b%}85Spa>JG^xo-52| z2PLq^P%qm(hcqI?m5(&OlIPn~e{i=$f+cc#STse*k4=?v{mOz1vwbB1?AJ7`)`9Z_ zhIC3+t@i5m7YtoqoCj8A%|Bcgg@bbN_S|x4Ew{TeuQu}h zMYrve@}K(D^|Vl7calq#!M>(L`-RI)77}ER zYGFs$)c6TUBL>na^Nj%2uwl(A&)hXLMW)XlCYZBt3VIkpjhMLZ|cat)bO=VbK_YI=rat{)jsbwPXrZi)AMXnF6ZycQn zU$=85-)m5x5BVb8n{5Ko?qk&J1Vq0mSe_TZbw{tNT94a-}e%#*ritx9iPc2kVybXWm}zGXdt|Ng#IS`UEh>NqE34y>dvE=Gj-wo{QK&F(KgV z0XO7`p(y-fhR&z`ehJ7RoCsyPRFO~xaJWbBEAoA~rbJHvLJ2Aye`CVIR*plN5&xY} z`j^i66$8>$4T((xkTniGaH=>ZfzuC#v08U)2Q3E*A~8z|0-*M*>wkWGc|F`-d{2bC z7-1{i=o0W_q0dfWI*9at*F#+X6ba;C+klHX04Hcc%xty4qX_rb_*(Q{TmmgW5*z18 zp+b_S5Z`-$j?)WRXe3lb=>>TNl)|eaKRM|)o>eE*Sx1ZR8;Mv8DCbB>h&|rFdEJ)Z0Df?!s+<^Ge%Q?tk+@&B1SJ3mI7Q_jpwf^h>(Br_2~`* z+~`$RlbE!Yv81=b>u1T--4c>fM?(SM0+-rD(3QMHRY=rMJw$fz4+GYC2L zTO>YK5S><_q=gtHeJ0*!NZjkjAXR2TrqbTiPl3ZQ@VWIzU;IVX8?v^$qu?b$8e{ja z+Y{fbNP3Frp-?V=90}Zfzds|kVkHg&^y%gpHL83Oz6dF6cDR=+vKt1ssm>8pG3;RZV+}E?8v;zZyBxzns*|i!<>`UW{_4~iIyHe5 zmD^fBAGHGfTV`G85DxHW#__k$ekuqcMvz4&v(0-w{OIXUub9C{e_t`Q)Uu_H$F@nv zJj?vBI@B}{*=V+~nWNopb1?n~G0h6@;XWX6e|WIikl$C39yKuoEkhC7;zz!*)E2xY zZ31bWA-!~zOjaMJ6!je5kmjOsy-i$>r0ik^Srij#Eq{bqo)_wgjX3JCrKKB?RXnF_8|_7dV4y!am5=(fu}L%dF(mK#;(Ot4~3wuzgqj z#J1$yM`v)ACB$Jlv$!K}CV(%dn*R%*a^WA$GLI9Vp{rmQoB@d{>N>|**GqrdB- z!Z^(eOMjpHgb2;_jtVsCSVUcEwoMeJ>&mh1r*9!G@WN{CI*W;=R*U<~@w9WyIeS=9 zEOuq<8k}?qqo>8}FSKlSL}h^CUsCdQ!Scm?)cM5t1{5l3@xNXyR>2Fj%agb)pQ{5# z*l+S%PZ)Cpmy9MRi1Ei6XO#g6=I7JsK_~r1N?KtCUsDx_Dw|oJJ0`xPuR=cVvO%{} zOBrZ5OIX#G`dlNsk(`d#h(xCnT4u{)&uT#P3SK&HVj9_rKc_ftsWu-Aoonvs<<09S?e^ zK|PI(p<}A^1h7%Ne%;QGGb~) zZpBtkw4_W@YbDI43UnZk;fBUGeu}{QLfNPh=baWG1eYY48w3qSNWUa-PGgoU450I8Mf#J%9 zhHm2?$pBnZ`$aa?1`Sj_YjAEX(4J2`*IidwMeYNa5If)T>)aLy+U&wo$F0UEtuGqM zu^$EEmqF@bBp}3q7xWekoMQ~;H3D8{Krd-^NI~&+R)Z8E*~UgLJ4%cLv=(;W5i7nc88J;fNzdE8g& zUQ$kYLFvj}P7Ia(u+8Ik&FyhcyvCNHra8SyoM$GYX4@i?3DB4k4i8C{qWF4>P_umM6LrY8CN!`9EB2|OBfv>I_IolH5pL3M^u|pEb%o85lS#{tL>At5H zNzyslIHmoR?AL2CTfP6dHABtO=Z7yPE0&A`?Bsdw!HMWTQt^e$2kgSXlJ>dZ(k|Bu3<&`}h zE;_3}lQfVeSlb7be(%BsMbj=|qr)7QwamaU(cyR;+PuBeO^R}HdWIY!1*Nlr6PU5v zO!AK#jtHx^L9Px=8abN9j}Or~erD`FL$!W|ebq5;^7_vTy-XtxDlHV5UyW3v?$5hj zv5rtzWzp|;z&kPn*8si8?GSkLT$$<0*xo2raf23o+D=Rb(pZO-oF14*MA`u!I#{q4 z1Yatl2O@L*?8j-_pny0pV`XkgY^O6JsDIWc1zXmCA3cwqJfxu0M+^0qJ7KD zY8?cDdif?;JT^Z8WVw&FUzx7H=Kr2~_!+LAnSKf!;OSRT?i!=1cQNM6J%8?~FXL0hE7qq{}bPaV}Ui%ffIPg##1?uzP( zPI^k+L-Vlv{IT?M=p1yHZD4Gi_p0*_b3N#6Tlwl_h^Fna5(Ie7O4y(sLm&pV0fVX; z#_fqR=M(Q|*~n;L2hB;UHn=|?#=q;jM^c{iL1a3UP)a7-bjlB{?!7OxKQQWd@K6Z` zhL60%C706s6-`;*008Xd0r*ocfSffOCGOVAbn7uy6i4rU9|||L^AEtgMak?03Q$g? z>73tfnK>8>H$51^Y#{|iWR9GGEBB*@u+dI8oddXu{@NI3>xaN2^*Y{MO_DAjN*MTxu+iZdP@C%756wEN zbS;8SNTUQ35hvV zCOO_kignCLD`mvjuj1K!ZPxw>)|vFlI$(dHryKsU!*pZMCDHT9Tq0TsqzW37 zd?t!`^_$26X9-$H6v!-YQ`Zi+2v!=UU};L6q8|>B3vz$ML zq;##DCpDjfZr*S3EP%q4RimVzK@skJ2)y0H2bwFfQdqn00F$k3O^Tp1du^IvV@Q2{ zY~^DYFWtZw8xB@$hSwhPh0tR>K&uLg46Tlw>0+WU7)^q`F_#YElVSur$ok5)87$Hm6AMsqmf6{62R zRDMDq<)dyhL780^lJ;J(~uBfW@71?+TE&ndj)PSmw}iqZO1yHO*)v)a?x#rDTh z<&$R2ovHDaF5j}L9b%ukCn#2ddZLVbXpMzFqiBy(*f@^yD`k%@_76PQMbW3;6m$aBa%k$0%s6EdP8=a)DhBe z-7|$$BPvzPO8Qg-GINZ9qqUc6Xxd~k0=N*`)VjIh==F0gmA*F+E3rxjnSskNT~Fp(n-^FR86kmFTp(bwfE<`($6IzJ>6=<`kOHQsEv%oCWVaMzr3AGpIlvByd?;Gv z-jEQIE3Q(P)nqZL#R~N(EE?95$=r*1f%98Sa@T%uW9)lJD4-<&TF_}lHCL2Z*4%sC zfR70kTptF4sdCPkf#Ymr`sE`bx+t(}e0(iTzT`VMqk@M*yh)Z^`X?x0{r{$Op|nfX zABgydz|?{T%a=&)r+-hgs#;mPR4o$;v?{c>-pd70rhUBiD|m!Tdbi-n(S2a^VWKux5xVTyYg8U~yz%BqMl-#U{Fj_%{ zPfi__xX%uAnS+*@{oJ$b=uy!<<}&F#NT7Lk2(a(dtK?rSm}L2QeX&?$!00_zU2HK| z=1hVPW50bkeY1loDH#lke5gaRGwU=>^N!=g@KgDDT1#8Pl5c4 z)*@bY%bri2_#kU+cwvS#K5<2r;DTx0G}3RNoMLnzhH?bFtLFqL7lade0=K9_On;cg zhw^?_@$Ia_IJemK`DP3PPzx;q=>0y)PslVW&jJxRN&3?kP(uVzJ=u}HBBcG^W-G-# z!F0T~F@ryV%jgcM#wPc+Dr4q`=|B=A6CdBeYy%2j-9~Mm)z|1?8C^6E-z{Z9*_u>O zM~R=j^Oxr1jDgQ0v@##(2NiPcl8=ZQ4C@hq`fpD49d23Ax4moY+Rm#8mI`~LkJQIT z%0ZD+A|=C$4`kX5P0-fi;l5R$#rxP8mPBOP(YAJE-%aK zfxnt}e#|~w`aUqDmN)h+_wQnU3HtCJ_!K3t--}9K15x);h?F-*S5xC|=S{6R567G5 zHZJKHc)&NJq~H?32%gxMEHN^bNDcU(9QX;rA7i4xrve z=5^qv>S%1>RLQbe6}_$a8x+HcGD2H_Q{&fOtl*hu$N<|ARD8RxPulGiLvaTi@9*|} zJ<6E6M#f97m9V4c~AdE^W znLam!FTxRdku3NY?^0!)ig>e%fKwd`jl#@pAU$-(t}!LRN(k>>z=U6V+b8%O9IKB1 z2pC1{Aw*ykL?#C8$CDC3+8nEB0y-jsP?qo z3i)+O@}Vg&W+1JU-=M}tB5To_KhO6#Q8}3ENH2ey4o?OoBooR4tYPw6Q_2-*WJC#) zY71E{SnPo0*N(#|$pO`8*Y(w@;h=}pXQ!wZ5ivN3eN2*+zG)~92;rTVw5DWJVlyma zR@k#^+}V=o>nWopC}AzJgElev+k|yb*&(U*F3LZN#%OJYn80>%J`R}g&xCNeuwVn(#zS71=9W5;KSnDASRyF8GoqPy75_@I} z34rrVXWEyQ%Dtq8qyOa-Xj$5n z9?>4eUZe3FQ4XD)m;hMujZf8U$BLsce^JUZ^)MK22$0r(k5HBgjZz-#>Lcz`0mBb6 zPL~Q0|G&zvJRYjH4G#u`F^;v78D^5QWQ~xqM+-`1NwzV03n`N9z05H7HQ|*Oin5!c zWH%;Mwu+K{5~FOBZ7|_G`rhyTz5jmqALpFE=6;@Mp5Hmwecjjn+$8+d%QNWcSU5Ik z(UYGPXbnTsmSrthO1VJr^vPN|Jx39?B3I+?N4uY7s@rqhPi3OXF&k4vaIhFo9NAfZP^3BG33ZD>f2zSr}q42A!le|Bo;5v z@jNX34RtIjP{jQ3$nyaKRw|=qdEyl_Jh-Q@urO@xTtd5=M~5cN`@oIUjS59`;(3bu zF}y&MZbhJ!48odOi~S|S;?%jPF()vd%5K@3Xv#$dt0zl2Ess9iR0el=h8|pEtW|Gf zc|ek!NZy4RPZJ7gv@NB{vV0JLS&`qDG^%AQja)eMz+fJfI$Q|mIcw;|RS^Ir$D=8t zN>hg{fd11nmU!DM%hKIo=zkE%d#mJliJLpkBo3eOLBxQ?3wmbSTYM+EcrWX}*estK zNzQ2@oNV;%;Z7yAOr-g}cYde_7cz_I>z6uaNP`$Fry~=KMLsM~{YwVm{Z&sluAP=L zi09+u0QyhudhEB%eQ}xNEjP42m|F|4)&&Yz(cabvYDxh! z#bv%d6p&w8ztTnQP~g1ohD3c-4Wt)9OoF?&Z)nP>;)8bx`oxGvv=amU?yHxLFZelj zR0Yrbaro|4gT(%^k#`a}2Qf~L?m5R}X>0z)$ud|46Fcl7ui&Joho5?#^bRVOf2 z_A|nY_eC*o%oZey9Dv2oU_i!?EL++}2=8M~qDuN*8iL<9ZmkW!K7)*7?pzzKyYraw zt|0V660su-q8r`nh@XbY2EVaaF1x%U!pTopxWd(@Fi}-O#^9nNThKumrrWkxJ}h}a zMP9~q|A8k?LB+b_Kj5jB$1xyFz#WA($1e5XCI(0asAh@O2Zu@lo7B3&LxA~LA0_$( z7&e^u(2M5yC4FoBvj&whv0Nusd(R1`0KRV-+Ci(^Yw4DidoSSn1a&}~u$74lqlhRJUJssoRup3ypXK-biD8!3hBtF?2U`2^8 z0g;lYXbHj$%(#4{AtznhrsJ*9ye1U_v0W%u+_5|?}o@IaNK4_3$_X7BTSnmaCx!S zOXY?2^heV0eA;=wSh^NOtloJY7p`I;GfrAugTyiIgSF_R$8=@@7|O$_Pwe%(^6ID; zw#G-%tsYS!AUmPa8oq^+3peWqTwfMnIxq6l~@ou$!q_#AC<|O>N+D z!$wtu@y`&}1MA>Fxse4ZQ*jj8K}jA_i(8=w{M=ZV4%c32<-#n8vKl;Sdp~MFb}Y5D zAJE5YyuMBeD6TQJh&PD+&5*i3;{v&JHExSDUFxX{Srcu!etuEndge{;GMJS~SDv;y zC1~@Jbqj9DlTM-XcM*vkB)f;>EXCA-0mt3c3@YQ2glsnW&0rXNo)~*r(y9zG?f+Iv zY-4(Jy~bw88vMO(?fP&IBfc|f)31sY4~dy51PBV04~JDBBb0^WUxAqVwsci-1F?9& za|cgrjtAfNgovJ-A54tw?id)j!OonxmQXcuK&z{`p*fuPBx!hv*@aFpYPTY2Ob|!!{p=!0m}&K1Os{jlo|@7ZTBDCuj#y_ z88Cp9I0~m~^(5P$Iyo^0@r-GlC%DV@%s|>NkLZ1_tlQM+i z0=`!%RMYYh?z>B@^1r81BNu6#yn0^%hKOoKAr4r1BHVq+Q`?|MZsE5A=-2XCW0-*5 zDFtK_T4E$imJsMHhbsl4mqpS{qMEbVqC%2}P9DDbQFfIS)Zrpn!Fph2uXAnEn(mbP2*-_bN24G)(NZKyPetx9~_HL_3BgbR&}lIEni1%@2= zh@+_;x-k?dR?0n1=wH8gDoqW94=IyYA*M;f_E|&3quM|ju~p@DdcZSHt|dQtlDKeI znB(2-?CiwSa?l^8(k9^!JkTm1-qDAGfh>&N5rEUWs(AxtqN?~&`--M^oAceM3Lz*+ zP*9xuaDRN{yk0sfY|$Nd%9uK5WUZH?y()M%K;#MXlHqaSP@DUMubsNlQulNNiX!z_ z^by|potH5uE=aPi6<+kzdwsV)KV^q5NH7Np3(I*qC}1CxjEJK4GyE>-_g&Aq^~LD( z>S!PT$?6|bxzD_gKXzR1Bl{>#z|)EZiHET2;I5J^nO?grIKH`CP%ih+kg-)g{a^IHl*Vx`Ob=4+sL)T&tnty8W1;Wn#~SNrN@HSTT6Ip@Dl$~+uC_s z6e~Z!z?L)GzBavAd@c4XWs#OikRiu$GL=KZN*At`?aN&Yf9ZWEnXj|jo<%ZgnAPcT zl^@_CPx-*)QyQs@s%tXCaVqC}i}#j5hyevRy(-<``mg!M zHv~wrO03^k#H8Dbqi3Y9_D|ib(pbA?$%b)R2}TD_Caxj@^*`qOau+|9KXajGPY$DVcO4N}P>41R*5!BsamI;GFCrmjM=$SuJ80;i zYPcQzb4#Qby;mHpu9vx4;nlfjCcA&LqG9ob^PniiE>(ZcQGKnMJ-V0yeE@2{#3OzV z`BX-^N6z`{cBG>OeAFko)W-+nTaJif!vN9r{f2^gFi3NGDwI z-xQ+M$TLO*dhfM5umcpC$@u{?)d26QGvYhe@C6hkU+y0gCNy1m{`RJzTS3jyZKosy z>LA9skq^$nWKM6E3do;w_MB;BeP#QfseK7-`|UuSBP*Z~GVlDZa&#eCdrbZlZ?l_V z!~*j#Dykh^SH#en>CNqe%Dzie0ns#eTyw`!ZXqcn(X^N?=|z*02;sdK{l{znj1T!f z?od`9*#c^c>OpN$U*9xO!t2O~#vf)Z)3lDLc)k0J+dKQjdX31XUjJ(>MChC4Cao%u z;+~W7h|KYL6L9jn=&?rom3Qel1NcSgy_sAQ{MXY29?^MSFYqQAJABSDF~-` zukH~G95y=pgUSd6=Ryzj7pgsIweB-q*^UcZws|YPN)$Fg24pH{(PMfV1-FK4LwU}|5$dG-52fV72gUjinL z_dsZkC*lzOk|tDCY(+i_pL0%;Fg`tBZljRdLqLi+9gtJZ*B>vx;91zHSZ&|I-NrOY z2@sV(<%V6MhyC2D6&krK@k^`xnrnJsR{;A`1{{BHwq8+Jg&qUrK~|O-g~HlvuZ=XX zpjH-@uzncWW;d`uIhp^WvX|9!^LZP-W;|NEmS&suoKY*pMMVN<58|wOqA3MjcH}g* zj(iLG<90dcya{fX3YAO6HW`_nhxxIU*Dn9nzV6+{LQTISuipRkBiP-s>4(wTN&fs^ zH`@gVaHoo1WN=1*Sd=vo@`=BrPL23_OKVzg+yM)$#6ksUW6Zo|?lLbpbSRt63U)*w z0dM1DUrLJ#kAA+XX5M-7vvo>|TCrG1Q}O-341ZaClN>O1ebA?&oY>GF{?eegri@i> z|Aa3g!y%=&J8PTWd251Q!b!~iB;eC;ph Date: Tue, 1 Sep 2026 11:46:45 +0200 Subject: [PATCH 081/157] Cred to Greek translators --- docs/index.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index b4283d1d5..9a34a7b71 100644 --- a/docs/index.md +++ b/docs/index.md @@ -173,13 +173,14 @@ Translators: * Finnish -- Sami Määttä (Accessibility Library Celia), and Essi Viippola (freelancer) * French -- Olivier Thiffault (Technologies Humanware) * German -- Nazli Andjic, Robert Graf and Paul Libbrecht (IU International University of Applied Sciences), and Moritz Groß (Math4VIP, Marburg University) +* Greek -- Theodora Antonakopoulou and Paraskevi Riga (National and Kapodistrian University of Athens) * Hungarian -- Attila Hammer (IT Foundation for the Visually Impaired) * Indonesian -- Dr. Pinta Deniyanti Sampoerno, M.Si; Dr. Meiliasari, S.Pd., M.Sc; and Ari Hendarno, S.Pd., M.Kom. -* Norwegian -- Marthe Gjelstad (National Library of Norway), Kvile +* Norwegian -- Marthe Gjelstad (National Library of Norway) and Kvile * Polish -- Michał Dziwisz (Fundacja Instytut Rozwoju Regionalnego) * Russian (both speech and braille) -- Danil Kostenkov * Spanish -- Noelia Ruiz Martínez (also helped with NVDA add-on development) and María Allo Roldán -* Swedish -- Tim Arborealis Lötberg (MTM), and Anders Eklund (SPSM) +* Swedish -- Tim Arborealis Lötberg (MTM) and Anders Eklund (SPSM) * Vietnamese -- Dang Hoai Phúc and Trang Pham * Others??? -- please volunteer so I can list you here... From 0932ffb8f4f0429518b28dd06071316d389a9b0b Mon Sep 17 00:00:00 2001 From: K4itsit Date: Wed, 2 Sep 2026 20:18:10 +0800 Subject: [PATCH 082/157] Fix outdated MathCAT project URLs (#732) Co-authored-by: k4its1t <306379390+k4its1t@users.noreply.github.com> --- Cargo.toml | 6 +++--- README.md | 2 +- Rules/Braille/ASCIIMath/ASCIIMath_Rules.yaml | 2 +- Rules/Braille/French/French_Rules.yaml | 2 +- Rules/Braille/LaTeX/LaTeX_Rules.yaml | 2 +- Rules/Braille/Nemeth/Nemeth_Rules.yaml | 4 ++-- Rules/Braille/Swedish/Swedish_Rules.yaml | 2 +- Rules/Braille/UEB/UEB_Rules.yaml | 2 +- Rules/Braille/Vietnam/Vietnam_Rules.yaml | 2 +- Rules/Intent/general.yaml | 2 +- docs/helpers_old.md | 2 +- docs/ru/helpers.md | 2 +- src/canonicalize.rs | 2 +- src/chemistry.rs | 2 +- src/navigate.rs | 2 +- src/speech.rs | 2 +- src/xpath_functions.rs | 2 +- tests/braille/Nemeth/other.rs | 14 +++++++------- tests/braille/Nemeth/rules.rs | 6 +++--- tests/braille/UEB/iceb.rs | 2 +- tests/braille/UEB/other.rs | 10 +++++----- 21 files changed, 36 insertions(+), 36 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 67522e0b3..fcf5428d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,9 +4,9 @@ version = "0.7.7-alpha.1" authors = ["Neil Soiffer "] license = "MIT" description = "MathCAT: Math Capable Assistive Technology ('Speech and braille from MathML')" -repository = "https://github.com/NSoiffer/MathCAT" -homepage = "https://nsoiffer.github.io/MathCAT/" -documentation = "https://nsoiffer.github.io/MathCAT/" +repository = "https://github.com/daisy/MathCAT" +homepage = "https://daisy.github.io/MathCAT/" +documentation = "https://daisy.github.io/MathCAT/" edition = "2024" exclude = ["src/main.rs", "docs", "BrailleDocs", "PythonScripts"] # should have "Rules/", but then one can't run build.rs to build the zip file diff --git a/README.md b/README.md index bf974dc3b..0ee92c6fa 100644 --- a/README.md +++ b/README.md @@ -16,4 +16,4 @@ There are four related projects that make use of MathCAT: MathCAT is used in many assistive technologies including NVDA and JAWS. -For more information, see the [full documentation](https://nsoiffer.github.io/MathCAT/). +For more information, see the [full documentation](https://daisy.github.io/MathCAT/). diff --git a/Rules/Braille/ASCIIMath/ASCIIMath_Rules.yaml b/Rules/Braille/ASCIIMath/ASCIIMath_Rules.yaml index d3cb9d090..edae6abab 100644 --- a/Rules/Braille/ASCIIMath/ASCIIMath_Rules.yaml +++ b/Rules/Braille/ASCIIMath/ASCIIMath_Rules.yaml @@ -223,7 +223,7 @@ # FIX: what should be output name: mhchem-hack # this captures the output for the mhchem's "<=>", "<<=>", and "<=>>" output (there are no Unicode arrows for them) - # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/NSoiffer/MathCAT/issues/60) + # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/daisy/MathCAT/issues/60) tag: mover match: - "*[1][substring(., 1, 1)='↽'] and" diff --git a/Rules/Braille/French/French_Rules.yaml b/Rules/Braille/French/French_Rules.yaml index 46c74a15c..f3514cebf 100644 --- a/Rules/Braille/French/French_Rules.yaml +++ b/Rules/Braille/French/French_Rules.yaml @@ -326,7 +326,7 @@ - name: mhchem-hack # this captures the output for the mhchem's "<=>", "<<=>", and "<=>>" output (there are no Unicode arrows for them) - # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/NSoiffer/MathCAT/issues/60) + # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/daisy/MathCAT/issues/60) tag: mover match: - "*[1][substring(., 1, 1)='↽'] and" diff --git a/Rules/Braille/LaTeX/LaTeX_Rules.yaml b/Rules/Braille/LaTeX/LaTeX_Rules.yaml index 315192dde..b9237dee0 100644 --- a/Rules/Braille/LaTeX/LaTeX_Rules.yaml +++ b/Rules/Braille/LaTeX/LaTeX_Rules.yaml @@ -235,7 +235,7 @@ # FIX: what should be output name: mhchem-hack # this captures the output for the mhchem's "<=>", "<<=>", and "<=>>" output (there are no Unicode arrows for them) - # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/NSoiffer/MathCAT/issues/60) + # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/daisy/MathCAT/issues/60) tag: mover match: - "*[1][substring(., 1, 1)='↽'] and" diff --git a/Rules/Braille/Nemeth/Nemeth_Rules.yaml b/Rules/Braille/Nemeth/Nemeth_Rules.yaml index 4fe821d0c..b5f74e562 100644 --- a/Rules/Braille/Nemeth/Nemeth_Rules.yaml +++ b/Rules/Braille/Nemeth/Nemeth_Rules.yaml @@ -164,7 +164,7 @@ replace: - test: if: "preceding-sibling::*" - then: [t: "W⣍"] # github.com/NSoiffer/MathCAT/issues/43#issuecomment-1297048039 + then: [t: "W⣍"] # github.com/daisy/MathCAT/issues/43#issuecomment-1297048039 - test: if: .[self::m:mlabeledtr] then: [x: "*[position()>1]"] @@ -900,7 +900,7 @@ - # this captures the output for the mhchem's "<=>", "<<=>", and "<=>>" output (there are no Unicode arrows for them) - # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/NSoiffer/MathCAT/issues/60) + # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/daisy/MathCAT/issues/60) name: chemistry-mhchem-equilibrium-arrow tag: mover match: diff --git a/Rules/Braille/Swedish/Swedish_Rules.yaml b/Rules/Braille/Swedish/Swedish_Rules.yaml index 7a8504574..94a40bdd6 100644 --- a/Rules/Braille/Swedish/Swedish_Rules.yaml +++ b/Rules/Braille/Swedish/Swedish_Rules.yaml @@ -329,7 +329,7 @@ - name: mhchem-hack # this captures the output for the mhchem's "<=>", "<<=>", and "<=>>" output (there are no Unicode arrows for them) - # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/NSoiffer/MathCAT/issues/60) + # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/daisy/MathCAT/issues/60) tag: mover match: - "*[1][substring(., 1, 1)='↽'] and" diff --git a/Rules/Braille/UEB/UEB_Rules.yaml b/Rules/Braille/UEB/UEB_Rules.yaml index 4d5b8ca1d..912e03d8a 100644 --- a/Rules/Braille/UEB/UEB_Rules.yaml +++ b/Rules/Braille/UEB/UEB_Rules.yaml @@ -300,7 +300,7 @@ - name: mhchem-hack # this captures the output for the mhchem's "<=>", "<<=>", and "<=>>" output (there are no Unicode arrows for them) - # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/NSoiffer/MathCAT/issues/60) + # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/daisy/MathCAT/issues/60) tag: mover match: - "*[1][substring(., 1, 1)='↽'] and" diff --git a/Rules/Braille/Vietnam/Vietnam_Rules.yaml b/Rules/Braille/Vietnam/Vietnam_Rules.yaml index 85146aeb7..60319160b 100644 --- a/Rules/Braille/Vietnam/Vietnam_Rules.yaml +++ b/Rules/Braille/Vietnam/Vietnam_Rules.yaml @@ -360,7 +360,7 @@ - # this captures the output for the mhchem's "<=>", "<<=>", and "<=>>" output (there are no Unicode arrows for them) - # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/NSoiffer/MathCAT/issues/60) + # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/daisy/MathCAT/issues/60) name: chemistry-mhchem-equilibrium-arrow tag: mover match: diff --git a/Rules/Intent/general.yaml b/Rules/Intent/general.yaml index d5ee239e9..15bd1dc7a 100644 --- a/Rules/Intent/general.yaml +++ b/Rules/Intent/general.yaml @@ -380,7 +380,7 @@ - # this captures the output for the mhchem's "<=>", "<<=>", and "<=>>" output (there are no Unicode arrows for them) - # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/NSoiffer/MathCAT/issues/60) + # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/daisy/MathCAT/issues/60) name: chemistry-mhchem-equilibrium-arrow tag: mover match: diff --git a/docs/helpers_old.md b/docs/helpers_old.md index 5266c8b3e..9292a2557 100644 --- a/docs/helpers_old.md +++ b/docs/helpers_old.md @@ -5,7 +5,7 @@ This page is a work-in-progress. ## Getting Started If you plan to work on MathCAT development, you need to make use of github: -1. Fork the MathCAT repo at `github.com/NSoiffer/MathCAT` +1. Fork the MathCAT repo at `github.com/daisy/MathCAT` 2. Clone the forked copy so you have a local copy to work on. 3. Checkout the branch I create for your work (typically the country code for your translation) and work in that branch. diff --git a/docs/ru/helpers.md b/docs/ru/helpers.md index ebcd6e8c4..fa70fc86f 100644 --- a/docs/ru/helpers.md +++ b/docs/ru/helpers.md @@ -11,7 +11,7 @@ title: Руководство переводчика и разработчика ## Начало работы Если вы планируете участвовать в разработке MathCAT, используйте GitHub: -1. Создайте форк репозитория MathCAT `github.com/NSoiffer/MathCAT`. +1. Создайте форк репозитория MathCAT `github.com/daisy/MathCAT`. 2. Клонируйте форк, чтобы получить локальную копию для работы. 3. Переключитесь на созданную для вашей работы ветку, обычно названную кодом языка перевода, и работайте в ней. diff --git a/src/canonicalize.rs b/src/canonicalize.rs index 47be3ad00..0e0a81447 100644 --- a/src/canonicalize.rs +++ b/src/canonicalize.rs @@ -2083,7 +2083,7 @@ impl CanonicalizeContext { fn merge_number_blocks(context: &CanonicalizeContext, parent_mrow: Element, children: &mut Vec) { // debug!("parent:\n{}", mml_to_string(parent_mrow)); // If we find a comma that is not part of a number, don't form a number - // (see https://github.com/NSoiffer/MathCAT/issues/271) + // (see https://github.com/daisy/MathCAT/issues/271) // Unfortunately, we can't do this in the loop below because we might discover the "not part of a number" after a number has been formed let do_not_merge_comma = is_comma_not_part_of_a_number(children); let mut i = 0; diff --git a/src/chemistry.rs b/src/chemistry.rs index 5bec42313..173c5cccb 100644 --- a/src/chemistry.rs +++ b/src/chemistry.rs @@ -1653,7 +1653,7 @@ fn likely_chem_equation_operator(mathml: Element) -> i32 { return -3; // there is still a chance /// Detects output of mhchem for some equilibrium arrows that currently (11/22) don't have Unicode points - /// See github.com/NSoiffer/MathCAT/issues/60 for the patterns being matched + /// See github.com/daisy/MathCAT/issues/60 for the patterns being matched fn is_hack_for_missing_arrows(mover: Element) -> bool { assert_eq!(name(mover), "mover"); let children = mover.children(); diff --git a/src/navigate.rs b/src/navigate.rs index f893b3838..a3365ef56 100644 --- a/src/navigate.rs +++ b/src/navigate.rs @@ -798,7 +798,7 @@ fn key_press_to_command_and_param( // key press mapping should probably be stored externally (registry) with an app that allows changes // for now, we build in the defaults - // this is a hack to map alt+ctl+arrow to ctl+arrow to change table mappings (github.com/NSoiffer/MathCAT/issues/105) + // this is a hack to map alt+ctl+arrow to ctl+arrow to change table mappings (github.com/daisy/MathCAT/issues/105) // if this change sticks, choose_command() needs to be changed and this hack should go away let mut alt_key = alt_key; if alt_key && control_key && [VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN].contains(&key) { diff --git a/src/speech.rs b/src/speech.rs index eaaeff282..100d5ff39 100644 --- a/src/speech.rs +++ b/src/speech.rs @@ -152,7 +152,7 @@ fn speak_rules(rules: &'static std::thread::LocalKey>, math // debug!("Speech string: {}", speech_string); // Note: [[...]] is added around a matching child, but if the "id" is on 'mathml', the whole string is used if !rules_with_context.nav_node_id.is_empty() { - // See https://github.com/NSoiffer/MathCAT/issues/174 for why we can just start the speech at the nav node + // See https://github.com/daisy/MathCAT/issues/174 for why we can just start the speech at the nav node let raw_intent_attr = mathml.attribute_value("data-intent-property"); let intent_attr = raw_intent_attr.as_deref().unwrap_or_default(); if let Some(start) = speech_string.find("[[") { diff --git a/src/xpath_functions.rs b/src/xpath_functions.rs index 19cf0b6cd..97e1db5ee 100644 --- a/src/xpath_functions.rs +++ b/src/xpath_functions.rs @@ -1945,7 +1945,7 @@ mod tests { test_is_not_simple("-x y z", "-x ⁢y⁢z")?; - test_is_not_simple("C(-2,1,4)", // github.com/NSoiffer/MathCAT/issues/199 + test_is_not_simple("C(-2,1,4)", // github.com/daisy/MathCAT/issues/199 "C(−2,1,4)")?; return Ok( () ); }); diff --git a/tests/braille/Nemeth/other.rs b/tests/braille/Nemeth/other.rs index 102c68096..5efae3d3d 100644 --- a/tests/braille/Nemeth/other.rs +++ b/tests/braille/Nemeth/other.rs @@ -5,7 +5,7 @@ use anyhow::Result; #[test] fn not_number_space_blocks() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/144 + // https://github.com/daisy/MathCAT/issues/144 let expr = "123 ⁣456"; test_braille("Nemeth", expr, "⠼⠂⠆⠒⠀⠼⠲⠢⠖")?; return Ok(()); @@ -14,7 +14,7 @@ fn not_number_space_blocks() -> Result<()> { #[test] fn space_between_digits() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/144 + // https://github.com/daisy/MathCAT/issues/144 let expr = "1 3 5"; test_braille("Nemeth", expr, "⠼⠂⠀⠼⠒⠀⠼⠢")?; return Ok(()); @@ -23,7 +23,7 @@ fn space_between_digits() -> Result<()> { #[test] fn space_hack_between_digits() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/144 + // https://github.com/daisy/MathCAT/issues/144 let expr = "1 ⁣3 ⁣5"; test_braille("Nemeth", expr, "⠼⠂⠀⠼⠒⠀⠼⠢")?; return Ok(()); @@ -32,7 +32,7 @@ fn space_hack_between_digits() -> Result<()> { #[test] fn tilde_prefix_bug_244() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/244 + // https://github.com/daisy/MathCAT/issues/244 let expr = " ~ p "; test_braille("Nemeth", expr, "⠈⠱⠏")?; return Ok(()); @@ -41,7 +41,7 @@ fn tilde_prefix_bug_244() -> Result<()> { #[test] fn double_struck_bug_334() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/334 -- double struck was problem (⠼ was missing); test all of the scripted numbers here + // https://github.com/daisy/MathCAT/issues/334 -- double struck was problem (⠼ was missing); test all of the scripted numbers here let expr = "𝟙,𝟐,𝟯,𝟺"; test_braille("Nemeth", expr, "⠠⠸⠼⠂⠠⠀⠸⠼⠆⠠⠀⠠⠨⠸⠼⠒⠠⠀⠼⠲")?; return Ok(()); @@ -50,7 +50,7 @@ fn double_struck_bug_334() -> Result<()> { #[test] fn extra_indicators_bug_343() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/343 -- extra indicators before baseline indicator due to -x^2, not there for x^2 + // https://github.com/daisy/MathCAT/issues/343 -- extra indicators before baseline indicator due to -x^2, not there for x^2 let expr = " @@ -78,7 +78,7 @@ fn extra_indicators_bug_343() -> Result<()> { #[test] fn find_baseline_indicator_bug_364() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/364 + // https://github.com/daisy/MathCAT/issues/364 let expr = r#" π diff --git a/tests/braille/Nemeth/rules.rs b/tests/braille/Nemeth/rules.rs index 18d31204f..d0cde7248 100644 --- a/tests/braille/Nemeth/rules.rs +++ b/tests/braille/Nemeth/rules.rs @@ -71,7 +71,7 @@ fn test_9_b_4() -> Result<()> { } #[test] fn test_9_c_1_linear() -> Result<()> { - // see https://github.com/NSoiffer/MathCAT/issues/43 for discussion on linear layout + // see https://github.com/daisy/MathCAT/issues/43 for discussion on linear layout let expr = "| 12 -3-4 @@ -1763,7 +1763,7 @@ fn racket_below_121_4() -> Result<()> { #[test] fn identity_matrix_126_linearize() -> Result<()> { - // see https://github.com/NSoiffer/MathCAT/issues/43 for discussion on linear layout + // see https://github.com/daisy/MathCAT/issues/43 for discussion on linear layout let expr = " ( 100 010 @@ -2203,7 +2203,7 @@ fn tensor_from_mathml_spec() -> Result<()> { l "; - // Note: the braille answer was verified to be correct (see https://github.com/NSoiffer/MathCAT/issues/55) + // Note: the braille answer was verified to be correct (see https://github.com/daisy/MathCAT/issues/55) test_braille("Nemeth", expr, "⠠⠗⠰⠊⠐⠘⠚⠐⠰⠅⠐⠰⠇")?; return Ok(()); } diff --git a/tests/braille/UEB/iceb.rs b/tests/braille/UEB/iceb.rs index b7f3a6560..3bd48b19b 100644 --- a/tests/braille/UEB/iceb.rs +++ b/tests/braille/UEB/iceb.rs @@ -522,7 +522,7 @@ fn ratio_3_2_6() -> Result<()> { #[test] fn standing_alone_1() -> Result<()> { - // Tests bug: github.com/NSoiffer/MathCAT/issues/142 + // Tests bug: github.com/daisy/MathCAT/issues/142 let expr = "(n=7)"; test_braille("UEB", expr, "⠐⠣⠰⠝⠀⠐⠶⠀⠼⠛⠐⠜")?; return Ok(()); diff --git a/tests/braille/UEB/other.rs b/tests/braille/UEB/other.rs index f1beb55cc..7dda38f6c 100644 --- a/tests/braille/UEB/other.rs +++ b/tests/braille/UEB/other.rs @@ -72,7 +72,7 @@ fn number_space_before_and_after() -> Result<()> { #[test] fn not_number_space_blocks() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/144 + // https://github.com/daisy/MathCAT/issues/144 let expr = "123 ⁣456"; test_braille("UEB", expr, "⠼⠁⠃⠉⠀⠼⠙⠑⠋")?; return Ok(()); @@ -81,7 +81,7 @@ fn not_number_space_blocks() -> Result<()> { #[test] fn dot_above_bug_204() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/204 + // https://github.com/daisy/MathCAT/issues/204 let expr = " 0. 6 · "; test_braille("UEB", expr, "⠼⠚⠲⠣⠼⠋⠜⠘⠲")?; return Ok(()); @@ -90,7 +90,7 @@ fn dot_above_bug_204() -> Result<()> { #[test] fn tilde_prefix_bug_244() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/244 + // https://github.com/daisy/MathCAT/issues/244 let expr = " ~ p "; test_braille("UEB", expr, "⠈⠔⠏")?; return Ok(()); @@ -109,7 +109,7 @@ fn double_tilde_prefix_bug_244() -> Result<()> { #[test] fn space_hack_between_digits() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/144 + // https://github.com/daisy/MathCAT/issues/144 let expr = "1 ⁣3 ⁣5"; test_braille("UEB", expr, "⠼⠁⠀⠼⠉⠀⠼⠑")?; return Ok(()); @@ -118,7 +118,7 @@ fn space_hack_between_digits() -> Result<()> { #[test] fn space_hack_around_operator() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/144 + // https://github.com/daisy/MathCAT/issues/144 let expr = "y ⁣= ⁣5"; test_braille("UEB", expr, "⠰⠽⠀⠐⠶⠀⠼⠑")?; return Ok(()); From 72e2b1ddf81950d2f12c6fd6cb2aadcdf4df8dac Mon Sep 17 00:00:00 2001 From: natalieac03 Date: Wed, 2 Sep 2026 10:04:44 -0300 Subject: [PATCH 083/157] Add Brazilian Portuguese (pt) translation- #729 (#736) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Create test * Traducao das regras pt-BR: unicode, definitions, SimpleSpeak, SharedRules e testes * Versão inicial em português do MathCAT * Corrige bugs da auditoria e traduz unicode-full.yaml (acentos, setas, operadores, formas) * Regras da rodada de testes: probability, ignore_period, unicode-full * Corrige unidades sec/arcsec, remove dot-over espúria, ACHADOS.md * pt: corrige 7 bugs de regra e reconcilia os testes (92/92) cargo test Languages::pt saía de 33 falhas em 91 testes. Agora passa 92/92, e a suíte inteira do repositório continua verde. Nada em src/ foi tocado. Bugs de regra: - SharedRules/general.yaml: a distinção Verbose/Medium tinha desabado na química. 14 pares de ramos diziam "subscrito"/"sobrescrito" nos dois níveis, onde o inglês tem subscript/sub. Um deles (ramo $Prescripts[4]) dizia "subscrito" onde o inglês diz superscript. - SharedRules/general.yaml: ligação dupla escrita "::" não era reconhecida. A regra testava .='::', mas o canonicalizador converte para ∷ (U+2237) antes de as regras rodarem, então H₂C::CH₂ saía "maiúsculo c, como maiúsculo c". - unicode.yaml: a regra de "|" era uma simplificação da inglesa e perdia três casos — P(A|B) ("dado"), a|b entre números ("divide") e o intent literal. Portada a estrutura inglesa inteira. - SharedRules/general.yaml: fora da química caía no default-text, que fala o nome da tag, e saía a palavra inglesa "none". Agora "nenhum". - SharedRules/general.yaml: faltava o Log maiúsculo (valor principal), que saía "Log de x". Marcado t: — a tradução precisa de conferência. - definitions.yaml: "segundo de arco" estava duplicado em PluralForms. O leitor de YAML do Rust aceita, mas audit-translations recusava o arquivo inteiro, ou seja, definitions.yaml não estava sendo auditado de verdade. - definitions.yaml: plurais das formas prefixadas de "segundo de arco", que a regra genérica produzia como "yoctossegundo de arcos". Testes desatualizados: pausas geradas pelo motor (ver ACHADOS.md seção 1), o artigo em "o log de x", "1 meio" em vez de "um meio", "l n x" no modo conciso, e a vírgula do grego (que o teste inglês também tem). Decisão: menos unário fica "menos", não "negativo". Os testes estavam divididos; a regra já dizia "menos" e os três discordantes foram alinhados. Resolve duas pendências do ACHADOS.md: a contradição aparente entre tensor_mmultiscripts e mhchem_so4_2mais (caminhos de código diferentes — só o da química estava quebrado) e a divergência de inverse_trig entre SimpleSpeak e ClearSpeak (as regras já estavam alinhadas; era o teste). ACHADOS.md ganha a seção 6. Corrigidas duas afirmações das seções anteriores: compute_auto_pause conta bytes, não letras; e as regras de química não eram idênticas às inglesas (só as diretivas de pausa eram). Registrado também que trocar bytes por caracteres foi testado e não resolve — piora de 15 para 36 falhas. Co-Authored-By: Claude Opus 5 * Terminologia: maiúscula, romanos por valor, expoente zero cardinal, testes * pt: pertinência sem verbo finito dentro de conjunto; ∉ com In deixa de colidir com ⊄ Duas correções de fala, com varredura e não caso a caso (ACHADOS 7.8/7.9): 1. Dentro de um conjunto ({x ∈ ℤ : x > 5}) a expressão modifica "todos os x" e não pode ter verbo finito nem singular: o verbo grudava em "conjunto" ("o conjunto de todos os x pertence a inteiros"). Seis dos oito ramos estavam errados, não só o Belongs. Agora: em / membros de / elementos de / pertencentes a, e as negações nominais. "fora de" foi rejeitado por trocar pertinência por localização; "não em" por ser truncado. O ramo SimpleSpeak usava uma string só para dentro e fora e passou a bifurcar. 2. ∉ com ClearSpeak_SetMemberSymbol=In fora de conjunto falava "não está contido em", exatamente a fala do ⊄. Passa a "não está em", espelhando o ∈. Também nesta rodada, já em varredura: termo único por família de estilo (fraktur, caligráfico) e adjetivo posposto nos dois arquivos; ∈ ∊ com Auto separado de Member como o ∉; ! volta a distinguir literal/fatorial; ≇ ≚ ≞ ⋕ com termo matemático em vez do nome Unicode; cópula dupla em ∦ ⊈ ⊉. Novo: tests/Languages/pt/ClearSpeak/sets.rs (pt vai de 102 para 142 testes, ∈ e ∊ travados iguais nas cinco preferências e nos dois estilos), PythonScripts/conferir_vocabulario.py (consistência de vocabulário entre unicode.yaml e unicode-full.yaml: 8 -> 4 grupos, restantes benignos) e Rules/Languages/pt/TERMINOLOGIA_PT_BR.md (registro único das leituras). Suíte inteira: 7307 passed, 0 failed. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_0134dJm6wzqbquvZrNhPD3Ea * pt: corrige o que o material real do ACESSÍLIA exige; recuo controlado; pacote de escuta Diagnóstico antes de escolher (ACHADOS 9): o MathML do ACESSÍLIA vem do latex2mathml nos dois caminhos (inclusive Docling) e nunca traz intent=, então os 186 IntentMappings ausentes não são prioridade. O que importa é o que o motor infere sozinho e o que sai cru para o sintetizador. Correções, pelo dano ao estudante: - caracteres crus no corpus real: negrito latino e grego (\mathbf, \boldsymbol), ⟨ ⟩, ¯ de \bar{x} (o motor canonicaliza U+0304/U+203E para U+00AF, então a entrada "com mácron" nunca era alcançada), setas longas, µ Ω ℧ Å soltos - "1 terceiro" -> "1 terço": listas fracionárias paravam em "meio" - "o integral" -> "a integral": artigo concorda com o operador grande - "magnitude de x" -> "a norma de x": intent inferido sem mapping pt - "cross product"/"dot product" literais -> "produto vetorial/escalar": o intent inferido vem sem filhos e nenhuma regra casava com count(*)=0 - recuo controlado só em regra (gerar_recuo_en.py): 2091 entradas do en para codepoints sem cobertura, estilo já definido traduzido, resto em t: minúsculo. Antes o caractere saía cru; agora sai em inglês, contado como pendente. Pacote da sessão de escuta (gerar_pacote_escuta.py -> SESSAO_ESCUTA.md): 30 expressões em 6 áreas, fala real nos dois estilos e três verbosidades, roteiro e tabela das decisões que dependem do ouvinte. cargo test: 7307 passed, 0 failed (pt: 142). conferir_vocabulario.py: 4 grupos, todos benignos, antes e depois. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_0134dJm6wzqbquvZrNhPD3Ea * pt: P(A ∣ B) fala "dado"; varredura de vazamento nas 593 expressões do en O latex2mathml emite \mid como U+2223, não "|": P(A ∣ B) saía "A divide B". A entrada "∣" ganha a mesma condição de contexto da regra do "|" (dentro de P( · ∣ · ) é "dado"; fora continua "divide"). Em conjunto por compreensão {x ∣ ...} o problema persiste e não é regra: o canonicalizador só trata "|" como cerca (registrado como item de src/ em ACHADOS 9.6). Varredura: as 593 expressões dos testes do inglês faladas em português, à procura de palavras inglesas. Fora dos em inglês dos próprios testes e das letras decoradas, nenhum vazamento em material real. As decorações (circulado, entre parênteses, com ponto, invertido) entraram no mapa de estilo do recuo controlado. cargo test: 7307 passed, 0 failed (pt: 142). conferir_vocabulario.py: 4. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_0134dJm6wzqbquvZrNhPD3Ea * pt: recuo marcado # RECUO-EN e separado da tradução pendente; regressão do recuo = 0 As entradas do recuo controlado usavam t: minúsculo, a mesma marca de "traduzido mas não conferido" — 2 mil delas contra 20 pendências reais, que sumiam no meio. Cada entrada do bloco leva agora # RECUO-EN na linha da chave e o conferir_vocabulario.py ganhou a seção 5, que reporta os dois números em separado: 2091 entradas de recuo (1980 strings em inglês) contra 20 strings pendentes de conferência (fraktur x10, caligráfico x10). Verificação de regressão: as 593 expressões dos testes do en faladas em pt sem e com o bloco. 526 iguais; 67 mudaram, todas com caractere cru antes. Nenhuma expressão 100% português mudou de fala. cargo test: 7307 passed, 0 failed (pt: 142). conferir_vocabulario.py: 4. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_0134dJm6wzqbquvZrNhPD3Ea * Delete auditar_pt.sh * Delete Rules/Languages/pt/ACHADOS.md * Delete Rules/Languages/pt/SESSAO_ESCUTA.md * Delete Rules/Languages/pt/TERMINOLOGIA_PT_BR.md * Terminologia: maiúscula, romanos por valor, expoente zero cardinal, testes * Restaura arquivos apagados por engano * Delete venv directory * Delete PythonScripts/venv directory * Delete PythonScripts/gerar_recuo_en.py * Delete PythonScripts/gerar_pacote_escuta.py * Delete PythonScripts/conferir_vocabulario.py * Remove translation correction comments from YAML Removed comments regarding translation corrections and pluralization issues. * Clean up comments in ClearSpeak_Rules.yaml Removed comments regarding corrections in Portuguese grammar and terminology for mathematical expressions. * Clean up comments in SimpleSpeak_Rules.yaml Removed comments regarding corrections related to gendered ordinal numbers and unnecessary English suffixes. * Clean up translation notes in definitions.yaml Removed translation notes and comments from definitions.yaml. * Fix tag for overview-default in overview.yaml Corrected the tag for 'overview-default' to include 'fraction' for better intent matching. * Clean up comments in escuta.rs Removed comments and documentation from escuta.rs. * Update expressions in escuta_expressoes.tsv * Clean up comments in intent.rs Removed cautionary comments regarding the Spanish equivalent tests and their historical inaccuracies. * Remove venv from version control * Restringe o PR a Rules/Languages/pt e tests/Languages/pt Reverte o .gitignore à versão do upstream; arquivos locais (venv, saídas de teste, scripts auxiliares e documentos .md) ficam fora do controle de versão via .git/info/exclude. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01VJN43HMwJHeagwCporXvF3 --------- Co-authored-by: Claude Opus 5 --- Rules/Languages/pt/ClearSpeak_Rules.yaml | 801 ++++ Rules/Languages/pt/SharedRules/calculus.yaml | 61 + Rules/Languages/pt/SharedRules/default.yaml | 734 ++++ Rules/Languages/pt/SharedRules/general.yaml | 1121 ++++++ Rules/Languages/pt/SharedRules/geometry.yaml | 80 + .../pt/SharedRules/linear-algebra.yaml | 35 + Rules/Languages/pt/SimpleSpeak_Rules.yaml | 338 ++ Rules/Languages/pt/definitions.yaml | 496 +++ Rules/Languages/pt/navigate.yaml | 1773 +++++++++ Rules/Languages/pt/overview.yaml | 119 + Rules/Languages/pt/unicode-full.yaml | 3431 +++++++++++++++++ Rules/Languages/pt/unicode.yaml | 571 +++ tests/Languages/pt.rs | 17 + tests/Languages/pt/ClearSpeak/sets.rs | 398 ++ tests/Languages/pt/SimpleSpeak/functions.rs | 422 ++ tests/Languages/pt/alphabets.rs | 438 +++ tests/Languages/pt/chemistry.rs | 721 ++++ tests/Languages/pt/escuta.rs | 33 + tests/Languages/pt/escuta_expressoes.tsv | 30 + tests/Languages/pt/intent.rs | 72 + tests/Languages/pt/shared.rs | 346 ++ tests/Languages/pt/unicode_full.rs | 159 + tests/Languages/pt/units.rs | 411 ++ tests/languages.rs | 1 + 24 files changed, 12608 insertions(+) create mode 100644 Rules/Languages/pt/ClearSpeak_Rules.yaml create mode 100644 Rules/Languages/pt/SharedRules/calculus.yaml create mode 100644 Rules/Languages/pt/SharedRules/default.yaml create mode 100644 Rules/Languages/pt/SharedRules/general.yaml create mode 100644 Rules/Languages/pt/SharedRules/geometry.yaml create mode 100644 Rules/Languages/pt/SharedRules/linear-algebra.yaml create mode 100644 Rules/Languages/pt/SimpleSpeak_Rules.yaml create mode 100644 Rules/Languages/pt/definitions.yaml create mode 100644 Rules/Languages/pt/navigate.yaml create mode 100644 Rules/Languages/pt/overview.yaml create mode 100644 Rules/Languages/pt/unicode-full.yaml create mode 100644 Rules/Languages/pt/unicode.yaml create mode 100644 tests/Languages/pt.rs create mode 100644 tests/Languages/pt/ClearSpeak/sets.rs create mode 100644 tests/Languages/pt/SimpleSpeak/functions.rs create mode 100644 tests/Languages/pt/alphabets.rs create mode 100644 tests/Languages/pt/chemistry.rs create mode 100644 tests/Languages/pt/escuta.rs create mode 100644 tests/Languages/pt/escuta_expressoes.tsv create mode 100644 tests/Languages/pt/intent.rs create mode 100644 tests/Languages/pt/shared.rs create mode 100644 tests/Languages/pt/unicode_full.rs create mode 100644 tests/Languages/pt/units.rs diff --git a/Rules/Languages/pt/ClearSpeak_Rules.yaml b/Rules/Languages/pt/ClearSpeak_Rules.yaml new file mode 100644 index 000000000..634aaf0ee --- /dev/null +++ b/Rules/Languages/pt/ClearSpeak_Rules.yaml @@ -0,0 +1,801 @@ +- name: pause + tag: "!*" + match: "not(self::m:math) and not($MatchingPause) and @data-intent-property[contains(., ':pause')]" + replace: + - with: + variables: [MatchingPause: "true()"] + replace: + - test: + - if: "contains(@data-intent-property, ':pause-long')" + then: [pause: long] + - else_if: "contains(@data-intent-property, ':pause-short')" + then: [pause: short] + else: [pause: medium] + - x: "." + +- name: intent-literal-silent + tag: [mi, mo, mn] + match: "contains(@data-intent-property, ':silent:')" + # say nothing + replace: [] + +# handling of negative numbers that come from 'intent' is hard -- we do something that is close to right here +- name: intent-literal-negative-number + tag: mn + match: "starts-with(text(), '-')" + replace: + - T: "menos" + - x: "translate(text(), '-_', '')" + +- name: default + tag: square-root + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "a"] # "a raiz" (feminino) + - T: "raiz quadrada" + # CORREÇÃO de ordem: o adjetivo vem depois do substantivo em português + # "a raiz quadrada negativa/positiva de x", não "a positiva raiz quadrada". + - test: + if: $ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd' + then: + - bookmark: "*[1]/@id" + - test: + if: parent::*[self::m:minus and count(*)=1] + then: [T: "negativa"] + else: [T: "positiva"] + - test: + if: "$Verbosity!='Terse'" + then: [T: "de"] + else: [pause: short] + - x: "*[1]" + - test: + - if: "$ClearSpeak_Roots = 'RootEnd' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" + then: + - pause: short + - T: "fim da raiz" + - pause: medium + - else_if: "IsNode(*[1], 'simple')" + then: [pause: short] + else: [pause: long] + +- name: default + # audit-ignore: divergência deliberada do en — adjetivo positiva/negativa pós-posto (ordem do português) + tag: root + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "a"] + - test: + if: "*[2][self::m:mn]" + then_test: + - if: "*[2][.='2']" + then: [T: "raiz quadrada"] + - else_if: "*[2][.='3']" + then: [T: "raiz cúbica"] + - else_if: "*[2][not(contains(., '.'))]" + then: [T: "raiz de índice", x: "*[2]"] + else: + - T: "raiz de índice" + - x: "*[2]" + # adjetivo depois do substantivo: "a raiz cúbica negativa de x" + - test: + if: $ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd' + then: + - test: + if: "parent::*[(self::m:minus or self::m:plus) and count(*)=1]" + then: [bookmark: "parent/@id"] + - test: + if: parent::m:minus + then: [T: "negativa"] + else: [T: "positiva"] + - test: + if: "$Verbosity!='Terse'" + then: [T: "de"] + - x: "*[1]" + - test: + if: $ClearSpeak_Roots = 'RootEnd' or $ClearSpeak_Roots = 'PosNegSqRootEnd' + then: + - pause: short + - T: "fim da raiz" + - pause: medium + else_test: + if: IsNode(*[1], 'simple') + then: [pause: short] + else: [pause: long] + +# The 'negative' rule interacts with the msqrt/mroot rules as those might pick off this case ("the negative square root of x") +- name: negative_and_positive + tag: [plus, minus] + match: "count(*)=1 and contains(@data-intent-property, ':prefix:')" + replace: + - test: + if: + - "*[1][self::m:square-root or self::m:root] and" + - "($ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd')" + then: [T: ""] + else: + - bookmark: "@id" + - test: + if: "self::m:minus" + then: [T: "menos"] + else: [T: "positivo"] + - x: "*[1]" + +# Fraction rules +# Mixed numbers mostly "just work" because the invisible char reads as "and" and other parts read properly on their own + +# Units (e.g., meters per second) +- name: per-fraction + tag: fraction + match: + - "$ClearSpeak_Fractions='Per' or" + - "(BaseNode(*[1])[contains(@data-intent-property, ':unit') or" + - " ( self::m:mrow and count(*)=3 and" # maybe a bit paranoid checking the structure... + - " *[1][self::m:mn] and *[2][.='\u2062'] and BaseNode(*[3])[contains(@data-intent-property, ':unit')] ) ] and" + - " BaseNode(*[2])[contains(@data-intent-property, ':unit')] )" + replace: + - x: "*[1]" + - T: "por" # "cinco metros por segundo" + - x: "*[2]" + +- name: common-fraction + tag: fraction + match: + - "($ClearSpeak_Fractions='Auto' or $ClearSpeak_Fractions='Ordinal' or $ClearSpeak_Fractions='EndFrac') and" + - "*[1][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and" + - "*[2][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or (2<= text() and text()<=10))]" + replace: [x: ToCommonFraction(.)] + +- name: common-fraction-mixed-number + tag: fraction + match: + - "preceding-sibling::*[1][self::m:mo][.='⁤'] and" # preceding element is invisible plus + - "($ClearSpeak_Fractions='Auto' or $ClearSpeak_Fractions='Ordinal' or $ClearSpeak_Fractions='EndFrac') and" + - "*[1][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and" + - "*[2][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or (2<= text() and text()<=10))]" + replace: [x: ToCommonFraction(.)] + +- name: fraction-over-simple + tag: fraction + match: + - "($ClearSpeak_Fractions='Over' or $ClearSpeak_Fractions='FracOver' or $ClearSpeak_Fractions='OverEndFrac') or" + - "( not($ClearSpeak_Fractions='General' or $ClearSpeak_Fractions='GeneralEndFrac') and" + - " (IsNode(*[1],'simple') and IsNode(*[2],'simple')) )" # simple fraction in ClearSpeak spec + replace: + - test: + if: "$ClearSpeak_Fractions='FracOver'" + then: + - test: + if: "$Verbosity!='Terse'" + then: [OT: "a"] + - T: "fração" + - x: "*[1]" + # léxico = fração simples é "a sobre b", não "a partido por b" + - T: "sobre" + - x: "*[2]" + - test: + + if: "$ClearSpeak_Fractions='OverEndFrac' or ($ClearSpeak_Fractions='EndFrac' and not( ($ClearSpeak_Fractions='Auto' or $ClearSpeak_Fractions='Ordinal' or $ClearSpeak_Fractions='EndFrac') and *[1][*[1][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and *[2][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or (2<= text() and text()<=10))] ] and *[2][*[1][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and *[2][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or (2<= text() and text()<=10))] ] ) )" + then: + - pause: short + - T: "fim da fração" + - pause: short + +- # fraction with text or numbers followed by text in both numerator and denominator + name: fraction-over-text + tag: fraction + match: + - "not($ClearSpeak_Fractions='General' or $ClearSpeak_Fractions='GeneralEndFrac') and" + - "( " + - " ((*[1][self::m:mi or self::m:mtext][string-length(.)>1]) or " # fractions with text + - " (*[1][self::m:mrow][count(*)=3][ " + - " *[1][self::m:mn] and " + - " *[2][self::m:mo][.='⁢'] and " # invisible times + - " *[3][self::m:mi or self::m:mtext][string-length(.)>1] ]) ) and" + - " ((*[2][self::m:mi or self::m:mtext][string-length(.)>1]) or " # fractions with text + - " (*[2][self::m:mrow][count(*)=3][ " + - " *[1][self::m:mn] and " + - " *[2][self::m:mo][.='⁢'] and " # invisible times + - " *[3][self::m:mi or self::m:mtext][string-length(.)>1] ]) )" + - ")" + replace: + - x: "*[1]" + - T: "sobre" + - x: "*[2]" + - test: + if: "$ClearSpeak_Fractions='EndFrac' or $ClearSpeak_Fractions='OverEndFrac'" + then: + - pause: short + - T: "fim da fração" + - pause: short + +- name: default + tag: fraction + match: "." + replace: + - OT: "a" + - T: "fração com numerador" + - test: + if: not(IsNode(*[1], 'simple')) + then: [pause: medium] + - x: "*[1]" + - pause: medium + - T: "e denominador" + - x: "*[2]" + - pause: long + - test: + if: "$ClearSpeak_Fractions='EndFrac' or $ClearSpeak_Fractions='GeneralEndFrac'" + then: + - pause: short + - T: "fim da fração" + - pause: short + +# rules for functions raised to a power +# these could have been written on 'mrow' but putting them on msup seems more specific +# to see if it is a function, we look right to see if the following sibling is apply-function +- name: ClearSpeak-function-inverse + tag: inverse-function + match: "." + replace: + - test: + if: $ClearSpeak_Trig = 'TrigInverse' + then: [x: "*[1]", bookmark: "*[2]/@id", T: "inverso"] + else_test: + if: $ClearSpeak_Trig = 'ArcTrig' + then: [bookmark: "*[2]/@id", T: "arco", x: "*[1]"] + else: [bookmark: "*[2]/@id", T: "inversa de", x: "*[1]"] # default/Auto + +- name: function-squared-or-cubed + # audit-ignore: divergência deliberada do en — ao quadrado/ao cubo com par verboso padronizado + tag: power + match: + - "*[2][self::m:mn][.='2' or .='3'] and" + - "following-sibling::*[1][self::m:mo][.='⁡']" #invisible function apply + replace: + - x: "*[1]" + - bookmark: "*[2]/@id" + - test: + if: "*[2][.='2']" + then_test: + if: "$Verbosity='Verbose'" + then: [T: "elevado ao quadrado"] + else: [T: "ao quadrado"] + else: [T: "ao cubo"] +- name: function-power + # audit-ignore: divergência deliberada do en — forma cardinal no lugar de ToOrdinal (sem ordinais femininos no motor) + tag: power + match: + - "following-sibling::*[1][self::m:mo][.='⁡']" #invisible function apply + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "a"] + - bookmark: "*[2]/@id" + - T: "potência" + - x: "*[2]" + - T: "de" + - pause: short + - x: "*[1]" + +- name: AfterPower-nested + tag: power + match: # directly a superscript or an mrow that contains a superscript + - "$ClearSpeak_Exponents = 'AfterPower' and" + - "*[2][self::m:power or self::m:power or self::m:mrow[m:power]]" + replace: + - x: "*[1]" + - T: "elevado ao expoente" + - pause: short + - x: "*[2]" + - pause: short + - T: "fim do expoente" + +- name: AfterPower-default + tag: power + match: "$ClearSpeak_Exponents = 'AfterPower'" + replace: + - x: "*[1]" + - T: "elevado à potência" + - x: "*[2]" + - pause: short + +- name: squared + tag: power + match: "*[2][self::m:mn][.='2'] and $ClearSpeak_Exponents = 'Auto'" + replace: + - x: "*[1]" + - bookmark: "*[2]/@id" + - T: "ao quadrado" + +- name: cubed + tag: power + match: "*[2][self::m:mn][.='3'] and $ClearSpeak_Exponents = 'Auto'" + replace: + - x: "*[1]" + - bookmark: "*[2]/@id" + - T: "ao cubo" + +- name: simple-integer + # audit-ignore: divergência deliberada do en — forma cardinal; preferência Ordinal degrada documentadamente + tag: power + match: "*[2][self::m:mn][not(contains(., '.'))]" + replace: + - x: "*[1]" + - T: "elevado a" + - x: "*[2]" + +- name: simple-negative-integer + # audit-ignore: divergência deliberada do en — forma cardinal + tag: power + match: + - "*[2][self::m:minus and count(*)=1 and" + - " *[1][self::m:mn][not(contains(., '.'))]" + - " ]" + replace: + - x: "*[1]" + - T: "elevado a" + - x: "*[2]" + +- name: simple-var + # audit-ignore: divergência deliberada do en — sem o sufixo fonético inglês -th + tag: power + match: "*[2][self::m:mi][string-length(.)=1]" + replace: + # CORREÇÃO: removido o bloco "pronounce" com o sufixo inglês "-th" (IPA θ), + # que produzia som estrangeiro. "x elevado a n" já está completo. + - x: "*[1]" + - T: "elevado a" + - x: "*[2]" + +# match nested exponent, where the nested exponent is has the power 2 or 3 (n below) +# [xxx]^n, - [xxx]^n, [xxx] var^n, -[xxx] var^n +# where xxx is a number or common fraction (or a var in the first two forms) +# short of creating a specialized built-in function, I don't see a way to eliminate a lot of repetition in the matches +# also really bad is that the test of a common fraction is replicated here (four times!) +# Note: the ClearSpeak doc doesn't say these only apply when the pref is "Auto", +# but the test cases all fall back to "raised to the exponent" when not "Auto" +# If these are allowed for non-Auto values, then you end up with "...power power...". +- # [xxx]^n + name: nested-squared-or-cubed + tag: power + match: + - "$ClearSpeak_Exponents = 'Auto' and" + - "*[2][self::m:power][" + - " *[2][self::m:mn][.='2' or .='3'] and " # exp is 2 or 3 + # base is mn, mi, common fraction ([xxx] case) + - " *[1][self::m:mn or self::m:mi or " + - " self::m:fraction[*[1][self::m:mn][not(contains(., '.')) and text()<20] and" + - " *[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]]" + - " ]" + - " ]" + replace: + - x: "*[1]" + - T: "elevado à potência" + - x: "*[2]" + +- # - [xxx]^n + name: nested-negative-squared-or-cubed + tag: power + match: + - "$ClearSpeak_Exponents = 'Auto' and" + - " *[2][self::m:minus and count(*)=1 and " + - " *[1]/*[1][self::m:power][" + - " *[2][self::m:mn][.='2' or .='3'] and " # exp is 2 or 3" + # base is mn, mi, common fraction ([xxx] case) + - " *[1][self::m:mn or self::m:mi or " + - " self::m:fraction[*[1][self::m:mn][not(contains(., '.')) and text()<20] and" + - " *[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]]" + - " ]" + - " ]" + - " ]" + replace: + - x: "*[1]" + - T: "elevado à potência" + - x: "*[2]" + +- # [xxx] var^n + name: nested-var-squared-or-cubed + tag: power + match: + - "$ClearSpeak_Exponents = 'Auto' and" + - " *[2][self::m:mrow][count(*)=3][ " + - " *[3][self::m:power][" + - " *[2][self::m:mn][.='2' or .='3'] and " # exp is 2 or 3 + - " *[1][self::m:mi]" + - " ] and " + - " *[2][self::m:mo][.='⁢'] and " # invisible times + # base is mn, or common fraction ([xxx] case) + - " *[1][self::m:mn or " + - " self::m:fraction[*[1][self::m:mn][not(contains(., '.')) and text()<20] and" + - " *[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]]" + - " ]" + - " ]" + replace: + - x: "*[1]" + - T: "elevado à potência" + - x: "*[2]" + +- # -[xxx] var^n + name: nested-negative-var-squared-or-cubed + tag: power + match: + - "$ClearSpeak_Exponents = 'Auto' and" + - " *[2][self::m:mrow][count(*)=3][ " + - " *[3][self::m:power][" + - " *[2][self::m:mn][.='2' or .='3'] and " # exp is 2 or 3 + - " *[1][self::m:mi]" + - " ] and " + - " *[2][self::m:mo][.='⁢'] and " # invisible times + - " *[1][self::m:minus and count(*)=1 and " + # base is mn, or common fraction ([xxx] case) + - " *[1][self::m:mn or " + - " self::m:fraction[*[1][self::m:mn][not(contains(., '.')) and text()<20] and" + - " *[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]]" + - " ]" + - " ]" + - " ]" + replace: + - x: "*[1]" + - T: "elevado à potência" + - x: "*[2]" + +- name: default-exponent-power + tag: power + match: # directly a superscript or an mrow that contains a superscript + - "*[2][self::m:power or self::m:power or self::m:mrow[m:power]]" + replace: + - x: "*[1]" + - T: "elevado ao expoente" + - pause: short + - x: "*[2]" + - pause: short + - T: "fim do expoente" + +- name: default + tag: power + match: "." + replace: + - x: "*[1]" + - T: "elevado à potência" + - x: "*[2]" + +# +# Some rules on mrows +# +- # the inference rules lump absolute value and cardinality together, so those rules are implemented here + name: ClearSpeak-absolute-value + # audit-ignore: divergência deliberada do en — três variáveis por causa do gênero (a cardinalidade / o valor absoluto) + tag: absolute-value + match: "." + variables: + - WordToSay: "IfThenElse($ClearSpeak_AbsoluteValue = 'Cardinality', 'cardinalidade', 'valor absoluto')" + - ArticleToSay: "IfThenElse($ClearSpeak_AbsoluteValue = 'Cardinality', 'a', 'o')" + - EndToSay: "IfThenElse($ClearSpeak_AbsoluteValue = 'Cardinality', 'fim da cardinalidade', 'fim do valor absoluto')" + replace: + - test: + if: "$Verbosity!='Terse'" + then: [x: "$ArticleToSay"] + - x: "$WordToSay" + - T: "de" + - x: "*[1]" + - test: + if: "$ClearSpeak_AbsoluteValue = 'AbsEnd'" + then: + - pause: short + - x: "$EndToSay" + - pause: short + +- name: set + # audit-ignore: divergência deliberada do en — conjunto de todos os x tal que (uso brasileiro) + tag: set + match: "." + replace: + - test: + - if: "count(*)=0" + then: [T: "o conjunto vazio"] + - else_if: "count(*)=2" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: "o"] + - T: "conjunto vazio" + - else_if: "count(*[1]/*)=3 and *[1]/*[2][self::m:mo][.=':' or .='|' or .='∣']" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: "o"] + # "conjunto de todos os x tal que" o inglês é + # "set of all"; a preferência woAll suprime só o "todos os". + - T: "conjunto de" + - test: + if: $ClearSpeak_Sets != 'woAll' + then: [T: "todos os"] + - x: "*[1]/*[1]" + - T: "tal que" + - x: "*[1]/*[3]" + else: + - test: + if: $ClearSpeak_Sets != 'SilentBracket' + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: "o"] + - T: "conjunto" + - x: "*[1]" + +- # intervals are controlled by a ClearSpeak Preference -- parens/brackets don't have to match, so we avoid IsBracketed + # alternatively, we could have four (or ten) rules, but there is a lot of duplication if we do that + # this one rule handles all ten cases listed as part $ClearSpeak_Paren = 'Interval' + # note that *[2] is an mrow with X, ",", Y, so getting X or Y is a double index + name: ClearSpeak-intervals # avoid overriding with default "intervals" name + variables: + - is_intervals_start_infinity: "*[1][self::m:minus and count(*)=1 and *[1][.='∞']]" + - is_intervals_end_infinity: "*[2][.='∞'or (self::m:plus and count(*)=1 and *[1][.='∞'])]" + tag: [open-interval, open-closed-interval, closed-interval, closed-open-interval] + match: "." + replace: + - T: "o intervalo de" + - x: "*[1]" + - T: "a" + - x: "*[2]" + - pause: short + - test: + if: "not($is_intervals_start_infinity)" + then: + - test: + if: "starts-with(name(.), 'open')" + # CORREÇÃO: "no" é espanhol; em português, "não" + then: [T: "não"] + - T: "incluindo" + - x: "*[1]" + # logic to deal with [not] arg #1 + - test: + if: "not($is_intervals_start_infinity or $is_intervals_end_infinity)" + then_test: + - if: "name(.)='open-interval'" + then: [T: "ou"] + - else_if: "name(.)='closed-interval'" + then: [T: "e"] + else: [T: "mas"] + # some ugly logic dealing with connectives: or, but, but, and (cleaner to be part of next clause?) + - test: + if: not($is_intervals_end_infinity) + then: + - test: + # there is some asymmetry to the test because of the and/or/but logic above + if: not( name(.)='open-interval' or name(.)='closed-interval' ) or $is_intervals_start_infinity + then: + - test: + if: "name(.) = 'open-interval' or name(.) = 'closed-open-interval'" + then: [T: "não"] + - T: "incluindo" + - x: "*[2]" + + # onto the [not] [including]... part +- name: binomial-frac-vector + tag: matrix + match: + - "$ClearSpeak_Matrix = 'Combinatorics' and " + - "count(*[1]/*)=1 and count(*)=2" + replace: + - x: "*[1]/*[1]/*" # mtable/mtr/mtd + - T: "escolhe" + - x: "*[2]/*[1]/*" + +- name: ClearSpeak-default + tag: [mtr, mlabeledtr] + match: "parent::m:matrix or parent::m:determinant" + replace: + - pause: medium + - T: "linha" + - x: "count(preceding-sibling::*)+1" + - test: + if: .[self::m:mlabeledtr] + then: + - T: "com rótulo" + - x: "*[1]/*" + - pause: short + - pause: medium + - test: + if: .[self::m:mlabeledtr] + then: [x: "*[position()>1]"] + else: [x: "*"] + +- name: matrix-default + tag: mtd + match: "parent::*[parent::m:matrix or parent::m:determinant]" + replace: + - test: + # ClearSpeak normally speaks "column 1" even though it says the row number, which is a waste... + # The following is commented out but the count(...)!=0 probably belongs in other rule sets + # if: not($IsColumnSilent) and ($ClearSpeak_Matrix = 'SpeakColNum' or count(preceding-sibling::*) != 0) + if: "not($IsColumnSilent)" + then: + - T: "coluna" + - x: "count(preceding-sibling::*)+1" + - pause: medium + - x: "*" + - test: + # short pause after each element; medium pause if last element in a row; long pause for last element in matrix + - if: count(following-sibling::*) > 0 + then: [pause: short] + - else_if: count(../following-sibling::*) > 0 + then: [pause: medium] + else: [pause: long] + +- # handle both log and ln + name: ClearSpeak-log + tag: mi + match: ".='log' or .='ln'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity!='Terse' and not(IsNode(following-sibling::*[2],'simple'))" + then: [T: "o"] + - test: + - if: ".='log'" + then: [T: "log"] + - else_if: "$ClearSpeak_Log = 'LnAsNaturalLog'" + then: [T: "logaritmo natural"] # phrase(the 'natural log' of x) + else: [spell: "'ln'"] + +- name: ClearSpeak-multi-line + # audit-ignore: divergência deliberada do en — plural por cadeias singular/plural, não por concatenação de s + tag: [piecewise, system-of-equations, lines] # these are ignored in favor of the ClearSpeak prefs + match: "." + variables: [IsColumnSilent: true()] + replace: + - x: "count(*)" + - test: + - if: $ClearSpeak_MultiLineOverview = 'Auto' + then: + - test: + if: "count(*) > 1" + then: + - test: + - if: "($ClearSpeak_MultiLineLabel = 'Auto' and self::m:piecewise) or $ClearSpeak_MultiLineLabel = 'Case'" + then: [T: "casos"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Auto' or $ClearSpeak_MultiLineLabel = 'Line'" + then: [T: "linhas"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" + then: [T: "restrições"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" + then: [T: "equações"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" + then: [T: "linhas"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" + then: [T: "passos"] + # else 'None' — não diz nada + else: + - test: + - if: "($ClearSpeak_MultiLineLabel = 'Auto' and self::m:piecewise) or $ClearSpeak_MultiLineLabel = 'Case'" + then: [T: "caso"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Auto' or $ClearSpeak_MultiLineLabel = 'Line'" + then: [T: "linha"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" + then: [T: "restrição"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" + then: [T: "equação"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" + then: [T: "linha"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" + then: [T: "passo"] + # else 'None' — não diz nada + - pause: short + - x: "*" + +- name: ClearSpeak-default-multiline + # audit-ignore: divergência deliberada do en — rótulos com plural correto + tag: [mtr, mlabeledtr] + match: "parent::m:piecewise or parent::m:system-of-equations or parent::m:lines" + replace: + - test: + - if: "($ClearSpeak_MultiLineLabel = 'Auto' and parent::m:piecewise) or $ClearSpeak_MultiLineLabel = 'Case'" + then: [T: "caso"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Auto' or $ClearSpeak_MultiLineLabel = 'Line'" + then: [T: "linha"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" + then: [T: "restrição"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" + then: [T: "equação"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" + then: [T: "linha"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" + then: [T: "passo"] + # else 'None' — não diz nada + - test: + if: "$ClearSpeak_MultiLineLabel != 'None'" + then: + - x: "count(preceding-sibling::*)+1" + - test: + if: .[self::m:mlabeledtr] + then: + - T: "com rótulo" + - x: "*[1]/*" + - pause: medium + - test: + if: .[self::m:mlabeledtr] + then: [x: "*[position()>1]"] + else: [x: "*"] + - test: + if: "$ClearSpeak_MultiLineLabel != 'None'" + then: [pause: long] + +- name: ClearSpeak_Functions_None + tag: mo + match: + - ".='⁡' and $ClearSpeak_Functions = 'None' and" + - "not(preceding-sibling::*[1][IsInDefinition(., 'TrigFunctionNames')])" # Functions=None does not apply to "trig" functions + replace: + test: + if: "$ClearSpeak_ImpliedTimes = 'None'" + then: [T: ""] + # léxico = "vezes" é a forma padrão; "multiplicado por" fica + # para o modo verboso + else_test: + if: "$Verbosity = 'Verbose'" + then: [T: "multiplicado por"] + else: [T: "vezes"] + +- name: no-times + tag: mo + match: + # Note: this rule is also part of the paren rule so that the parens speak + - ".='⁢' and $ClearSpeak_ImpliedTimes = 'None'" + replace: + - T: "" + +- name: ClearSpeak-times + # audit-ignore: divergência deliberada do en — vezes/multiplicado por conforme verbosidade (léxico ACESSÍLIA) + tag: mo + match: + # say "times" when invisible times is followed by parens or a superscript that has a base with parens or "|"s + # if we aren't sure if it is times or not, don't say anything + - ".='⁢' and (not(@data-function-guess) or $ClearSpeak_Functions = 'None') and (" + - " $ClearSpeak_ImpliedTimes = 'MoreImpliedTimes'" + - " or " + - " following-sibling::*[1][" + - " IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|') or " + - " self::m:matrix or self::m:determinant or self::m:binomial or" # followed by parens + - " ( (self::m:msup or self::m:msub or self::m:msubsup or self::m:power) and " # followed by msup, etc. + - " *[1][self::m:mrow[IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')] or " + - " self::m:matrix or self::m:determinant]" # base has parens + - " )" + - " ]" + # other possibility is the preceding element has parens (but not the following) + # this is not mentioned in the ClearSpeak rules or examples but seems like it should say "times". E.g, |x| y + - " or " + - " preceding-sibling::*[1][" + - " IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')]" # followed by parens + - " )" + replace: + - test: + if: "$Verbosity = 'Verbose'" + then: [T: "multiplicado por"] + else: [T: "vezes"] + +- name: no-say-parens + # audit-ignore: divergência deliberada do en — idem ClearSpeak-times + tag: mrow + match: + - "parent::*[not(self::m:msup) and not(self::m:msub) and not(self::m:msubsup) and not(self::m:power) and" + - " not(self::m:math) ] and " # rule out [x] standing alone + - "( IsBracketed(., '(', ')') or IsBracketed(., '[', ']') ) and " + - "not( $ClearSpeak_Functions = 'None' and " + - " (preceding-sibling::*[1][.='⁡'] or following-sibling::*[1][.='⁡']) ) and " + - "not( $ClearSpeak_ImpliedTimes = 'None' and " + - " (preceding-sibling::*[1][.='⁢'] or following-sibling::*[1][.='⁢']) ) and " + - "( IsNode(*[2], 'simple') )" + # missing clause: 'a positive fraction that is spoken as an ordinal + # (either by the Ordinal preference or by the default rules)' + replace: + - x: "*[2]" + +- include: "SharedRules/geometry.yaml" +- include: "SharedRules/linear-algebra.yaml" +- include: "SharedRules/calculus.yaml" +- include: "SharedRules/general.yaml" +- include: "SharedRules/default.yaml" diff --git a/Rules/Languages/pt/SharedRules/calculus.yaml b/Rules/Languages/pt/SharedRules/calculus.yaml new file mode 100644 index 000000000..03b99253a --- /dev/null +++ b/Rules/Languages/pt/SharedRules/calculus.yaml @@ -0,0 +1,61 @@ +--- + +- name: divergence + tag: divergence + match: "count(*) = 1" + replace: + # CORREÇÃO: a polaridade estava invertida — o modo padrão (Medium) ouvia a + # abreviação "div"; o nome completo só saía no Verbose. No inglês, só o + # Terse abrevia. E o "de" era incondicional, contrariando TerseFunctionNames + # (divergence/curl/gradient não dizem "de" no modo conciso). + - test: + if: "$Verbosity='Terse'" + then: [T: "div"] + else: [T: "divergente de"] + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [pause: short] + - x: "*[1]" + +- name: curl + tag: curl + match: "count(*) = 1" + replace: + - T: "rotacional" # phrase(the 'curl of' a field) + - test: + if: "$Verbosity!='Terse'" + then: [T: "de"] + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [pause: short] + - x: "*[1]" + +- name: gradient + tag: gradient + match: "count(*) = 1" + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "gradiente de"] # phrase('divergence' from the mean) + else: [T: "nabla"] # phrase('divergence' from the mean) + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [pause: short] + - x: "*[1]" + + +- name: laplacian + tag: laplacian + match: "count(*) <= 1" # can be on ∇^2 or on enclosing mrow + replace: + - T: "laplaciano" + - test: + if: "count(*) = 1" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: "de"] + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [pause: short] + - x: "*[1]" diff --git a/Rules/Languages/pt/SharedRules/default.yaml b/Rules/Languages/pt/SharedRules/default.yaml new file mode 100644 index 000000000..ff8ed2cf8 --- /dev/null +++ b/Rules/Languages/pt/SharedRules/default.yaml @@ -0,0 +1,734 @@ +--- +#default rules shared among several speech rules +- name: default + tag: math + match: "." + replace: + - with: + variables: + - ClearSpeak_Fractions: "IfThenElse($Verbosity='Verbose' and $ClearSpeak_Fractions='Auto', 'EndFrac', $ClearSpeak_Fractions)" + - ClearSpeak_AbsoluteValue: "IfThenElse($Verbosity='Verbose' and $ClearSpeak_AbsoluteValue='Auto', 'AbsEnd', $ClearSpeak_AbsoluteValue)" + - ClearSpeak_Roots: "IfThenElse($Verbosity='Verbose' and $ClearSpeak_Roots='Auto', 'RootEnd', $ClearSpeak_Roots)" + - ClearSpeak_Matrix: "IfThenElse($Verbosity='Verbose' and $ClearSpeak_Matrix='Auto', 'EndMatrix', $ClearSpeak_Matrix)" + # should be set at mtable level, but unknown intents make that impossible to know + - IsColumnSilent: false() + replace: + - test: + if: "$MathRate = 100" + then: [x: "*"] + else: + - rate: + value: "$MathRate" + replace: [x: "*"] + +- name: empty-mrow + tag: mrow + match: "not(*)" + replace: + - t: " " # say nothing -- placeholder + +- name: default + tag: mrow + match: "." + replace: + - insert: + nodes: "*" + replace: [pause: auto] + +- name: default + tag: mn + match: "." + replace: + - bookmark: "@id" + # ACRESCENTADO (en): numerais romanos são soletrados ("XIV" -> letra a + # letra), não lidos como palavra. + - test: + - if: "@data-roman-numeral" + then: [spell: "text()", pause: "short"] + else: [x: "translate(., $BlockSeparators, '')"] # remove digit block separators + +- name: default + tag: [mo, mtext] + match: "." + replace: + - bookmark: "@id" + - x: "text()" + +- name: default + tag: mi + match: "." + replace: + - bookmark: "@id" + - test: + - if: "string-length(.) = 1 and text() != '_'" # need unicode.tdl to kick in for single letter tokens + then: [x: "text()"] + # ACRESCENTADO (en): NavMode=Character precisa disto + - else_if: "@data-chem-element or @data-roman-numeral" + then: [spell: "text()", pause: "short"] + else: [x: "translate(., '-_\u00A0', ' ')"] # from intent literals + +- name: default + tag: ms + match: "." + replace: + - T: "a cadeia" + - pause: short + - x: "text()" + +- name: default + tag: mstyle + match: "." + replace: [x: "*"] + + +- name: literal-simple + # don't include nested fractions. E.g, fraction a plus b over c + 1 end fraction" is ambiguous + # by simplistic SimpleSpeak's rules "b over c" is a fraction, but if we say nested fractions + # are never simple, then any 'over' applies only to enclosing "fraction...end fraction" pair. + tag: mfrac + match: + - "(IsNode(*[1],'leaf') and IsNode(*[2],'leaf')) and" + - "not(ancestor::*[name() != 'mrow'][1]/self::m:fraction)" # FIX: can't test for mrow -- what should be used??? + replace: + - x: "*[1]" + - T: "sobre" + - x: "*[2]" + - pause: short + +- name: literal-default + tag: mfrac + match: "." + replace: + - T: "começar" + - pause: short + - x: "*[1]" + - test: + if: "not(IsNode(*[1],'leaf'))" + then: [pause: short] + - T: "sobre" + - test: + if: "not(IsNode(*[2],'leaf'))" + then: [pause: short] + - x: "*[2]" + - pause: short + # ALINHADO ao en: o marcador de fim é dito apenas para cegueira + - test: + if: "$Impairment = 'Blindness'" + then: [T: "fim da fração"] + - pause: medium + +# ACRESCENTADO: leitura literal de msqrt/mroot sem semântica inferida. +# O inglês evita dizer "quadrada" porque a forma literal não garante índice. +- name: literal-default + tag: msqrt + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [OT: "a"] + - T: "raiz" + - test: + if: "$Verbosity!='Terse'" + then: [T: "de"] + - x: "*[1]" + - pause: short + - test: + if: "not(IsNode(*[1],'leaf')) or $Impairment = 'Blindness'" + then: [T: "fim da raiz", pause: medium] + +- name: literal-default + # audit-ignore: divergência deliberada do en — ordem portuguesa: raiz de índice N de X — o teste final acompanha o último elemento falado + tag: mroot + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [OT: "a"] + - T: "raiz de índice" + - x: "*[2]" + - pause: short + - T: "de" + - x: "*[1]" + - pause: short + - test: + if: "not(IsNode(*[1],'leaf'))" + then: [T: "fim da raiz"] + +- name: simple-sub + tag: indexed-by + # invisible comma -- want "x 1 when subscript is an integer" + match: "count(*)=2 and $Verbosity='Terse' and *[2][self::m:mn and translate(., '.,', '')=.]" + replace: + - x: "*[1]" + - x: "*[2]" + - pause: short + +- name: no-end-sub + tag: indexed-by + # invisible comma -- want "x 1 when subscript is an integer" + match: "count(*)=2 and (IsNode(*[2], 'leaf') or *[2][self::m:mrow][*[2][.='⁣']])" + replace: + - x: "*[1]" + - test: + if: "$Verbosity!='Terse' or not(*[2][self::m:mn])" # just say "x 1" for terse vs "x sub 1" + then: [T: "subscrito"] + - x: "*[2]" + +- name: literal + tag: msub + match: "." + replace: + - x: "*[1]" + - T: "subscrito" + - x: "*[2]" + +- name: literal + tag: [msup, msubsup] + match: "." + replace: + - x: "*[1]" + - test: + if: "name(.)='msubsup'" + then: + - T: "subscrito" + - x: "*[2]" + - test: + if: "*[last()][translate(., '′″‴⁗†‡°*', '')='']" + then: [x: "*[last()]"] + else_test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" # FIX: is this test necessary? + then: + - T: "sobrescrito" + - x: "*[last()]" + - test: + if: "not(IsNode(*[last()], 'simple'))" + then: [T: "fim do sobrescrito"] + else: + - T: "elevado à" + - x: "*[last()]" + - T: "potência" + +- name: default + tag: munder + match: "." + replace: + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [T: "modificado"] + - x: "*[1]" + - T: "com" + - x: "*[2]" + - T: abaixo +# NOTA: aqui existia uma regra "dot-over" que eu havia acrescentado supondo +# ser uma porta do inglês. Ela NÃO existe em en/ — o inglês trata a notação +# de Newton pela regra "diacriticals" abaixo, que apenas fala o caractere. +# A regra inventada encobria a diacriticals e produzia "x com ponto acima" +# no lugar de "x ponto". Removida. + +- name: diacriticals + tag: [mover, modified-variable] + match: "*[1][self::m:mi] and *[2][translate(., '\u0306\u030c.\u00A8\u02D9\u20DB\u20DC`^ˇ~→¯_', '')='']" + replace: + - x: "*[1]" + - x: "*[2]" + - pause: short + +- name: default + tag: mover + match: "." + replace: + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [T: "modificado"] + - x: "*[1]" + - T: "com" + - x: "*[2]" + - T: "acima de" + +- name: default + tag: munderover + match: "." + replace: + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [T: "modificado"] + - x: "*[1]" + - T: "com" + - x: "*[2]" + - T: "e abaixo" + - x: "*[3]" + - T: "acima de" + +- name: default + # Here we support up to 2 prescripts and up to 4 postscripts -- that should cover all reasonable cases + # If there are more, we just dump them out without regard to sup/super :-( + # FIX: this could use more special cases + # There is (currently) no way in MathCAT to deal with n-ary arguments other than "all" ('*') or an individual entry ('*[1]'). + tag: mmultiscripts + match: "." + variables: + # computing the number of postscripts is messy because of being optionally present -- we use "mod" to get the count right + - Prescripts: "m:mprescripts/following-sibling::*" + - NumChildren: "count(*)" # need to stash this since the count is wrong inside '*[...]' below + - Postscripts: "*[position()>1 and position() < (last() + ($NumChildren mod 2) -count($Prescripts))]" + replace: + - x: "*[1]" + - test: + if: "$Prescripts" # more common case + then: + - with: + variables: + - PreSubscript: "IfThenElse($Verbosity='Verbose', 'pré-subscrito', 'pré-sub')" + - PreSuperscript: "IfThenElse($Verbosity='Verbose', 'pré-sobrescrito', 'pré-super')" + replace: + - test: # only bother announcing if there is more than one prescript + if: "count($Prescripts) > 2" + then: + - T: "com" + - x: "count($Prescripts) div 2" + - T: "pré-escritos" + - pause: short + - test: + if: "not($Prescripts[1][self::m:none])" + then: + - x: "$PreSubscript" + - x: "$Prescripts[1]" + - test: + if: "not($Prescripts[1][self::m:none] or $Prescripts[2][self::m:none])" + then: [T: "e"] + - test: + if: "not($Prescripts[2][self::m:none])" + then: + - x: "$PreSuperscript" + - x: "$Prescripts[2]" + - pause: short + - test: + if: "count($Prescripts) > 2" # more common case + then: + - test: + if: "not($Prescripts[3][self::m:none])" + then: + - x: "$PreSubscript" + - x: "$Prescripts[3]" + - test: + if: "not($Prescripts[3][self::m:none] or $Prescripts[4][self::m:none])" + then: [T: "e"] + - test: + if: "not($Prescripts[4][self::m:none])" + then: + - x: "$PreSuperscript" + - x: "$Prescripts[4]" + - test: + if: "count($Prescripts) > 4" # give up and just dump them out so at least the content is there + then: + - T: "e pré-escritos alternados" + - x: "$Prescripts[position() > 4]" + - T: "fim dos pré-escritos" + - test: + if: "$Postscripts" + then: + - with: + variables: + - PostSubscript: "IfThenElse($Verbosity='Verbose', 'subscrito', 'sub')" + - PostSuperscript: "IfThenElse($Verbosity='Verbose', 'sobrescrito', 'super')" + replace: + - test: # only bother announcing if there is more than one postscript + if: "count($Postscripts) > 2" + then: + - test: + if: "$Prescripts" + then: [T: "e"] + - T: "com" + - x: "count($Postscripts) div 2" + - T: "pós-escritos" + - pause: short + - test: + if: "not($Postscripts[1][self::m:none])" + then: + - x: "$PostSubscript" + - x: "$Postscripts[1]" + - test: + if: "not($Postscripts[1][self::m:none] or $Postscripts[2][self::m:none])" + then: [T: "e"] + - test: + if: "not($Postscripts[2][self::m:none])" + then: + - x: "$PostSuperscript" + - x: "$Postscripts[2]" + - test: + if: "count($Postscripts) > 2" + then: + - test: + if: "not($Postscripts[3][self::m:none])" + then: + - x: "$PostSubscript" + - x: "$Postscripts[3]" + - test: + if: "not($Postscripts[3][self::m:none] or $Postscripts[4][self::m:none])" + then: [T: "e"] + - test: + if: "not($Postscripts[4][self::m:none])" + then: + - x: "$PostSuperscript" + - x: "$Postscripts[4]" + - test: + if: "count($Postscripts) > 4" + then: + - test: + if: "not($Postscripts[5][self::m:none])" + then: + - x: "$PostSubscript" + - x: "$Postscripts[5]" + - test: + if: "not($Postscripts[5][self::m:none] or $Postscripts[6][self::m:none])" + then: [T: "e"] + - test: + if: "not($Postscripts[6][self::m:none])" + then: + - x: "$PostSuperscript" + - x: "$Postscripts[6]" + - test: + if: "count($Postscripts) > 6" + then: + - test: + if: "not($Postscripts[7][self::m:none])" + then: + - x: "$PostSubscript" + - x: "$Postscripts[7]" + - test: + if: "not($Postscripts[7][self::m:none] or $Postscripts[8][self::m:none])" + then: [T: "e"] + - test: + if: "not($Postscripts[8][self::m:none])" + then: + - x: "$PostSuperscript" + - x: "$Postscripts[8]" + - test: + if: "count($Postscripts) > 8" # give up and just dump them out so at least the content is there + then: + - T: "e índices alternados" + - x: "$Postscripts[position() > 8]" + - T: "fim dos índices" + + +- name: default + tag: [mtable, array] + variables: + - IsColumnSilent: "false()" + - NumColumns: "count(*[1]/*) - IfThenElse(*/self::m:mlabeledtr, 1, 0)" + match: "." + replace: + - T: "tabela com" + - x: count(*) + - test: + if: count(*)=1 + then: [T: "linha"] + else: [T: "linhas"] + - T: e + - x: "$NumColumns" + - test: + if: "$NumColumns" + then: [T: "coluna"] + else: [T: "colunas"] + - pause: long + - x: "*" + +- name: default + # ATUALIZADO para a geração atual do en: anuncia "linha N" e, no + # mlabeledtr, o rótulo — a versão herdada do es só falava os filhos, + # deixando tabelas genéricas sem anúncio de linha. + tag: [mtr, mlabeledtr] + match: "." + replace: + - pause: medium + - T: "linha" + - x: "count(preceding-sibling::*)+1" + - test: + if: "self::m:mlabeledtr" + then: + - T: "com rótulo" + - x: "*[1]/*" + - pause: short + - pause: medium + - test: + if: "self::m:mlabeledtr" + then: [x: "*[position()>1]"] + else: [x: "*"] + +- name: default + tag: mtd + match: "." + replace: + - T: "coluna" + - x: "count(preceding-sibling::*)+IfThenElse(parent::m:mlabeledtr, 0, 1)" + - pause: medium + - x: "*" # speak the entry + - pause: long + +- name: empty-box + # The ordering below is the order in which words come out when there is more than one value + # Note: @notation can contain more than one value + tag: menclose + match: "@notation='box' and *[self::m:mtext and .=' ']" + replace: + - T: "célula vazia" + +- name: default + # The ordering below is the order in which words come out when there is more than one value + # Note: @notation can contain more than one value + tag: menclose + match: "." + replace: + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' box ')]" + then: [T: "célula", pause: short] + - test: + if: ".[contains(@notation,'roundedbox')]" + then: [T: "célula redonda", pause: short] + - test: + if: ".[contains(@notation,'circle')]" + then: [T: "círculo", pause: short] + - test: + if: ".[ contains(concat(' ', normalize-space(@notation), ' '), ' left ') or contains(concat(' ', normalize-space(@notation), ' '), ' right ') or contains(@notation,'top') or contains(@notation,'bottom') ]" + then: + - T: linha acima + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' left ')]" + then: [T: "esquerda", pause: short] + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' right ')]" + then: [T: "direita", pause: short] + - test: + if: ".[contains(@notation,'top')]" + then: [T: "superior", pause: short] + - test: + if: ".[contains(@notation,'bottom')]" + then: [T: "inferior", pause: short] + - test: + if: ".[ contains(@notation,'updiagonalstrike') or contains(@notation,'downdiagonalstrike') or contains(@notation,'verticalstrike') or contains(@notation,'horizontalstrike') ]" + then: + - test: + if: ".[contains(@notation,'updiagonalstrike') and contains(@notation,'downdiagonalstrike')]" + then: [spell: "'x'", pause: short] # seems better to say 'x cross out' than 'up diagonal, down diagonal cross out' + else: + - test: + if: ".[contains(@notation,'updiagonalstrike')]" + then: [T: "diagonal superior", pause: short] + - test: + if: ".[contains(@notation,'downdiagonalstrike')]" + then: [T: "diagonal inferior", pause: short] + - test: + if: ".[contains(@notation,'verticalstrike')]" + then: [T: "vertical", pause: short] + - test: + if: ".[contains(@notation,'horizontalstrike')]" + then: [T: "horizontal", pause: short] + - T: riscado + - pause: short + - test: + if: ".[contains(@notation,'uparrow')]" + then: [T: "seta para cima", pause: short] + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' downarrow ')]" + then: [T: "seta para baixo", pause: short] + - test: + if: ".[contains(@notation,'leftarrow')]" + then: [T: "seta para a esquerda", pause: short] + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' rightarrow ')]" + then: [T: "seta para a direita", pause: short] + - test: + if: ".[contains(@notation,'northeastarrow')]" + then: [T: "seta para nordeste", pause: short] + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' southeastarrow ')]" + then: [T: "seta para sudeste", pause: short] + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' southwestarrow ')]" + then: [T: "seta para sudoeste", pause: short] + - test: + if: ".[contains(@notation,'northwestarrow')]" + then: [T: "seta para noroeste", pause: short] + - test: + if: ".[contains(@notation,'updownarrow')]" + then: [T: "seta vertical de duas pontas", pause: short] + - test: + if: ".[contains(@notation,'leftrightarrow')]" + then: [T: "seta horizontal de duas pontas", pause: short] + - test: + if: ".[contains(@notation,'northeastsouthwestarrow')]" + then: [T: "seta diagonal superior de duas pontas", pause: short] + - test: + if: ".[contains(@notation,'northwestsoutheastarrow')]" + then: [T: "seta diagonal inferior de duas pontas", pause: short] + - test: + if: ".[contains(@notation,'actuarial')]" + then: [T: "símbolo atuarial", pause: short] + - test: + if: ".[contains(@notation,'madrub')]" + then: [T: "símbolo fatorial arábico", pause: short] + - test: + if: ".[contains(@notation,'phasorangle')]" + then: [T: "ângulo fasorial", pause: short] + - test: + if: ".[contains(@notation,'longdiv') or not(@notation) or normalize-space(@notation) ='']" # default + then: [T: "símbolo de divisão longa", pause: short] + - test: + if: ".[contains(@notation,'radical')]" + then: [T: "raiz quadrada", pause: short] + - T: em torno de + - test: + if: "*[self::m:mtext and .=' ']" + then: [T: "espaço"] # otherwise there is complete silence + else: [x: "*"] + - test: + if: "$Impairment = 'Blindness' and ( $SpeechStyle != 'SimpleSpeak' or not(IsNode(*[1], 'leaf')) )" + then: [T: fim do destaque] + - pause: short + +- name: semantics + tag: "semantics" + match: "*[@encoding='MathML-Presentation']" + replace: + - x: "*[@encoding='MathML-Presentation']/*[1]" + +- name: semantics-default + tag: "semantics" + match: . + replace: + - x: "*[1]" + +- name: apply-function + tag: "apply-function" + match: . + replace: + - x: "*[1]" + - T: "de" + - pause: auto + - x: "*[position() > 1]" + +# Here are the intent hints that need to be handled: 'prefix' | 'infix' | 'postfix' | 'function' | 'silent' +- name: produto-vetorial-ou-escalar-sem-filhos + # O motor infere ⃗a × ⃗b e ⃗a ⋅ ⃗b como um elemento / + # SEM filhos (o próprio operador vira o elemento, data-from-mathml='mo'). + # Nenhuma regra de intent casa com count(*)=0, e a regra genérica falava o + # NOME do intent: "cross product", em inglês. Aqui passa pelo IntentMappings + # do pt. Ver ACHADOS 9.4. + tag: [cross-product, dot-product] + match: "count(*)=0" + replace: + - x: "SpeakIntentName(name(.), $Verbosity, 'infix')" + +- name: silent-intent + # uncaught intent -- the args have been inserted in the order of speech + tag: "*" + match: "count(*)>0 and (contains(@data-intent-property, ':silent:') or translate(name(.), '-_', '')='')" + replace: + - x: "*" + - test: + if: "IsNode(., '2D')" + then: [pause: short] + else: [pause: auto] + +# ACRESCENTADO: potência cujo expoente carrega um índice (x^(y_z)). +- name: power-indexed-by + tag: power-indexed-by + match: "." + replace: + - x: "*[1]" + - T: "sub" + - x: "*[2]" + - pause: short + +# ACRESCENTADO: intents com a propriedade :nofix: os argumentos já +# vêm na ordem de fala; basta falar o nome do intent. +- name: nofix-intent + tag: "*" + match: "contains(@data-intent-property, ':nofix:') " + replace: + - x: "SpeakIntentName(name(.), $Verbosity, 'nofix')" + +- name: prefix-intent + # uncaught intent -- the args have been inserted in the order of speech + tag: "*" + match: "count(*)>0 and contains(@data-intent-property, ':prefix:')" + replace: + - x: "SpeakIntentName(name(.), $Verbosity, 'prefix')" + - x: "*" + - test: + if: "not( IsBracketed(., '', '') or IsNode(*[last()], 'simple') )" + then: [x: "GetBracketingIntentName(name(.), $Verbosity, 'prefix', 'end')"] + - test: + if: "IsNode(., '2D')" + then: [pause: short] + else: [pause: auto] + +- name: postfix-intent + # uncaught intent -- the args have been inserted in the order of speech + tag: "*" + match: "count(*)>0 and contains(@data-intent-property, ':postfix:')" + replace: + - test: + if: "$Impairment = 'Blindness' and not( IsBracketed(., '', '') or IsNode(*[1], 'simple') )" + then: [x: "GetBracketingIntentName(name(.), $Verbosity, 'postfix', 'start')"] + - x: "*" + - x: "SpeakIntentName(name(.), $Verbosity, 'postfix')" + +- name: infix-intent + # uncaught intent -- the args have been inserted in the order of speech + tag: "*" + match: "count(*)>0 and contains(@data-intent-property, ':infix:')" + replace: + - test: + if: "$Impairment = 'Blindness' and not( IsBracketed(., '', '') or IsNode(*[1], 'simple') )" + then: [x: "GetBracketingIntentName(name(.), $Verbosity, 'infix', 'start')"] + - test: + if: "count(*) = 1" # in cases such as continued-row, plus/minus might have just one child + then: + - x: "SpeakIntentName(name(.), $Verbosity, 'infix')" + - pause: auto + - x: "*[1]" + else: + - insert: + nodes: "*" + replace: [x: "SpeakIntentName(name(.), $Verbosity, 'infix')", pause: auto] + - test: + if: "$Impairment = 'Blindness' and not( IsBracketed(., '', '') or IsNode(*[last()], 'simple') )" + then: [x: "GetBracketingIntentName(name(.), $Verbosity, 'infix', 'end')"] + - test: + if: "IsNode(., '2D')" # add (probably) a slightly longer pause if this came from a 2D node + then: [pause: short] + else: [pause: auto] + +- name: function-intent + # uncaught intent -- speak as foo of arg1 comma arg2 .... The MathML spec requires arguments to functions + tag: "*" + match: "count(*)>0" + replace: + - x: "SpeakIntentName(name(.), $Verbosity, 'function')" + - test: + if: "not(contains(@data-intent-property, ':literal:')) and + not(count(*)=2 and (IsInDefinition(*[1], 'TrigFunctionNames') or IsInDefinition(name(.), 'TerseFunctionNames')) and IsNode(*[2], 'simple'))" + then: [T: "de", pause: auto] # phrase(sine 'of' 5) + - insert: + nodes: "*" + replace: + - test: + if: "not(contains(@data-intent-property, ':literal:'))" + then: [x: "','"] + - pause: auto + - test: + if: "$Impairment = 'Blindness' and not(*[last()][IsBracketed(., '', '') or IsNode(., 'simple')] )" + then: [x: "GetBracketingIntentName(name(.), $Verbosity, 'function', 'end')"] + - test: + if: "IsNode(., '2D')" + then: [pause: short] + else: [pause: auto] + + +- name: default-text + # unknown leaf -- just speak the text -- could be a literal intent + tag: "*" + match: "." + replace: + - x: "translate(name(), '-_', ' ')" diff --git a/Rules/Languages/pt/SharedRules/general.yaml b/Rules/Languages/pt/SharedRules/general.yaml new file mode 100644 index 000000000..5b5a69634 --- /dev/null +++ b/Rules/Languages/pt/SharedRules/general.yaml @@ -0,0 +1,1121 @@ +--- + +# number-sets are a little messy in that the base was converted to a number-set, so we have to match that (simple) case last +- name: pos-neg-number-sets + tag: number-sets + match: "count(*)=2 and *[2][.='+' or .='-']" + replace: + - test: + if: "$Verbosity!='Terse'" + then: + - T: "a" + - bookmark: "*[2]/@id" + - test: + - if: "*[2][.='+']" + then: [T: "positivo"] + else: [T: "negativo"] + - bookmark: "*[1]/@id" + - test: + - if: "*[1][.='ℂ']" + then: [T: números complexos] + - else_if: "*[1][.='ℕ']" + then: [T: números naturais] + - else_if: "*[1][.='ℚ']" + then: [T: números racionais] + - else_if: "*[1][.='ℝ']" + then: [T: números reais] + - else_if: "*[1][.='ℤ']" + then: [T: inteiros] + else: [x: "*[1][text()]"] # shouldn't happen + +- name: dimension-number-sets + + # should be single digit integer at this point (e.g, R^3) + tag: number-sets + match: "count(*)=2" + replace: + - bookmark: "*[1]/@id" + - test: + - if: "*[1][.='ℂ']" + then: [T: "C"] + - else_if: "*[1][.='ℕ']" + then: [T: "N"] + - else_if: "*[1][.='ℚ']" + then: [T: "Q"] + - else_if: "*[1][.='ℝ']" + then: [T: "R"] + - else_if: "*[1][.='ℤ']" + then: [T: "Z"] + else: [x: "*[1][text()]"] # shouldn't happen + - bookmark: "*[2]/@id" + - x: "*[2]" + +- name: simple-number-sets + tag: number-sets + match: "count(*)=0" + replace: + - bookmark: "@id" + - test: + - if: ".='ℂ'" + then: [T: números complexos] + - else_if: ".='ℕ'" + then: [T: números naturais] + - else_if: ".='ℚ'" + then: [T: números racionais] + - else_if: ".='ℝ'" + then: [T: números reais] + - else_if: ".='ℤ'" + then: [T: inteiros] + else: [x: "text()"] # shouldn't happen + +- name: real-part + tag: real-part + match: "." + replace: + - bookmark: "@id" + - T: a parte real +- name: imaginary-part + tag: imaginary-part + match: "." + replace: + - bookmark: "@id" + - T: a parte imaginária# rules on scripted vertical bars ('evaluated at') +- name: evaluated-at-2 + tag: evaluate + match: "count(*)=2" + replace: + - x: "*[1]" + - pause: auto + - T: avaliado em + - pause: auto + - x: "*[2]" + +- name: evaluated-at-3 + tag: evaluate + match: "count(*)=3" + replace: + - x: "*[1]" + - pause: auto + - T: avaliado em + - pause: auto + - x: "*[3]" + - T: "avaliado na mesma expressão" + - x: "*[2]" + +- name: permutation + tag: pochhammer + match: "count(*)=2" + replace: + - x: "*[2]" + - T: permutações de + - x: "*[1]" + +- name: intervals + tag: [open-interval, open-closed-interval, closed-interval, closed-open-interval] + match: "count(*)=2" + replace: + - test: + if: "$Verbosity!='Terse'" + then: + - T: "o" + - test: + - if: "self::m:open-interval" + then: [T: "intervalo aberto"] + - else_if: "self::m:closed-interval" + then: [T: "intervalo fechado"] + - else_if: "self::m:open-closed-interval" + then: [T: "intervalo aberto fechado"] + else: [T: "intervalo fechado aberto"] + - test: + if: "$Verbosity!='Terse'" + then: + - T: "de" + - x: "*[1]" + - T: "a" + - x: "*[2]" + else: + - x: "*[1]" + - T: "vírgula" + - x: "*[2]" + +- name: default-point + tag: point + match: "count(*)=2" + replace: + - test: + if: "$Verbosity!='Terse'" + then: + - T: "o" + - T: "ponto" + - x: "*[1]" + - T: "vírgula" + - x: "*[2]" + +- name: bigop-both + tag: large-op + match: "count(*) = 3" + replace: + - test: + if: "$Verbosity!='Terse'" + then_test: + # "a integral", "o somatório": o artigo concorda com o operador. + if: "*[1][self::m:mo][contains('∫∬∭∮∯∰∱∲∳⨋⨌⨍⨎⨏⨐⨑⨒⨓⨔⨕⨖⨗⨘⨙⨚⨛⨜', .)]" + then: [T: a] + else: [T: o] + - x: "*[1]" + - T: de + - x: "*[2]" + - T: a + - x: "*[3]" + - test: + if: "following-sibling::*" + then: [T: de] + +- name: bigop-under + tag: large-op + match: "count(*)=2" + replace: + - test: + if: "$Verbosity!='Terse'" + then_test: + # "a integral", "o somatório": o artigo concorda com o operador. + if: "*[1][self::m:mo][contains('∫∬∭∮∯∰∱∲∳⨋⨌⨍⨎⨏⨐⨑⨒⨓⨔⨕⨖⨗⨘⨙⨚⨛⨜', .)]" + then: [T: a] + else: [T: o] + - x: "*[1]" + - T: sobre + - x: "*[2]" + - test: + if: "following-sibling::*" + then: [T: de] + +- name: largeop + tag: mrow + match: "count(*)=2 and IsInDefinition(*[1], 'LargeOperators')" + replace: + - test: + if: "$Verbosity!='Terse'" + then_test: + # "a integral", "o somatório": o artigo concorda com o operador. + if: "*[1][self::m:mo][contains('∫∬∭∮∯∰∱∲∳⨋⨌⨍⨎⨏⨐⨑⨒⨓⨔⨕⨖⨗⨘⨙⨚⨛⨜', .)]" + then: [T: a] + else: [T: o] + - x: "*[1]" + - T: de + - x: "*[2]" + +- name: msubsup-skip-super + # handles single, double, etc., prime + tag: [skip-super, say-super] + match: "count(*)=3" + replace: + - x: "*[1]" + # CORREÇÃO: a distinção Verbose/conciso do inglês ("subscript"/"sub") + # tinha colapsado, os dois ramos diziam a mesma coisa. Restaurada, + # coerente com as abreviações de default.yaml ('subscrito'/'sub'). + # Também restaurada a condição $Impairment='Blindness' do match interno, + # presente no inglês e perdida na tradução. + - test: + if: "$Verbosity='Verbose'" + then: [T: "subscrito"] + else: [T: "sub"] + - x: "*[2]" + - test: + if: "not(IsNode(*[2],'leaf') and $Impairment = 'Blindness')" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "fim do subscrito"] + else: [T: "fim do sub"] + - pause: short + else_test: + if: "*[2][self::m:mi]" # need a pause in "x sub k prime" so the prime is not associated with the 'k' + then: [pause: short] + - test: + if: "name(.)='say-super'" + then_test: + if: "$Verbosity='Verbose'" + then: [T: "sobrescrito"] + else: [T: "super"] + - x: "*[3]" + - pause: short + +# the order of matching is +# 1. does it match the base of an SI unit +# 2. does it match an English unit (if in an English language) +# 3. does it match an SI prefix followed by an SI that accepts SI prefixes +# Due to this order, some things like "ft" and "cd" mean "feet" vs "femto-tonnes" and "pints" vs "pico-tonnes" +# ACRESCENTADO (en): no modo conciso, unidade de uma letra é soletrada +# ("3 m" -> "3 m" soletrado), em vez de expandida para "metros". +- name: unit-terse + tag: unit + match: "$Verbosity = 'Terse' and string-length(.)=1" + replace: + - bookmark: "@id" + - spell: "text()" + +- name: unit + tag: unit + match: "." + variables: + # If the coefficient is singular, we don't add the plural ending. Finding the coefficient is tricky + # Normal case (A) "3m" (parents is mrow), but could also be (B) "3 m^2" (etc.). (parent is msup/mrow) + # But it might be in a fraction as (C) "3 m/s" (parent is mfrac/mrow) or (D) "3 m^2/s^2" (parent is msup/mfrac/mrow) + # or even (E) {3 m^2}/s (parent is msup/mrow) + # If in a fraction, only look in the numerator to find the coefficient + - MRowForCoefficient: "IfThenElse(parent::m:mrow, parent::m:mrow, + IfThenElse(parent::m:power, ancestor::*[2][self::m:mrow], + IfThenElse(parent::m:fraction and not(preceding-sibling::*), ancestor::*[2][self::m:mrow], + IfThenElse(parent::m:power[parent::m:fraction and not(preceding-sibling::*)], ancestor::*[3][self::m:mrow], false()) ) ) )" + - IsSingular: "(not($MRowForCoefficient) and parent::*[name(.)!='skip-super' or *[1][.=1]]) or + ($MRowForCoefficient and $MRowForCoefficient[(count(*) = 3 and *[1][self::m:mn and .=1] and *[2]='\u2062')])" + - Prefix: "''" + - Word: "''" + replace: + - bookmark: "@id" + - test: + # is the whole string match a SI Unit without a prefix? + - if: "DefinitionValue(., 'Speech', 'SIUnits') != ''" + then: + - set_variables: [Word: "DefinitionValue(., 'Speech', 'SIUnits')"] + - else_if: "DefinitionValue(., 'Speech', 'UnitsWithoutPrefixes') != ''" + then: + - set_variables: [Word: "DefinitionValue(., 'Speech', 'UnitsWithoutPrefixes')"] + - else_if: "DefinitionValue(., 'Speech', 'EnglishUnits') != ''" + then: + - set_variables: [Word: "DefinitionValue(., 'Speech', 'EnglishUnits')"] + + # do the first two chars match "da" and the remainder match an SIUnit + - else_if: "string-length(.) >= 3 and + substring(., 1, 2) = 'da' and + DefinitionValue(substring(., 3), 'Speech', 'SIUnits') != ''" + then: + - set_variables: + - Prefix: "DefinitionValue('da', 'Speech', 'SIPrefixes')" + - Word: "DefinitionValue(substring(., 3), 'Speech', 'SIUnits')" + + # does the first char match a prefix and the remainder match an SIUnit + - else_if: "string-length(.) >= 2 and + DefinitionValue(substring(., 1, 1), 'Speech', 'SIPrefixes') != '' and + DefinitionValue(substring(., 2), 'Speech', 'SIUnits') != ''" + then: + - set_variables: + - Prefix: "DefinitionValue(substring(., 1, 1), 'Speech', 'SIPrefixes')" + - Word: "DefinitionValue(substring(., 2), 'Speech', 'SIUnits')" + + # not a known unit -- just speak the text, possibly as a plural + - else: + - set_variables: + - Word: "text()" + + - with: + variables: + - Word: "IfThenElse(substring($Word, string-length($Word)-2, 3) = 'ián', concat(substring($Word, 1, string-length($Word)-2), ian), $Word)" + - LastChar: "substring($Word, string-length($Word), 1)" + - PluralEnding: "IfThenElse($LastChar = 'r' or $LastChar = 'l', 'es', + IfThenElse(substring($Word, string-length($Word)-2, 3) = 'ian', 'es', 's' )) " + replace: + # somewhat complicated logic to avoid spaces around "-" as in "centi-grams" vs "centi - grams" -- probably doesn't matter + - test: + if: "$Prefix = ''" + then: + - test: + - if: "$IsSingular" + # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets the prefix concatinated to the base + then: [x: "$Word"] + - else_if: "DefinitionValue($Word, 'Speech', 'PluralForms') != ''" + then: [x: "DefinitionValue($Word, 'Speech', 'PluralForms')"] + else: [x: "concat($Word, $PluralEnding)"] + else: + - x: "$Prefix" + - test: + - if: "$IsSingular" + # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets the prefix concatinated to the base + then: [x: "concat('\uF8FE', $Word)"] + - else_if: "DefinitionValue($Word, 'Speech', 'PluralForms') != ''" + then: [x: "concat('\uF8FE', DefinitionValue($Word, 'Speech', 'PluralForms'))"] + else: [x: "concat('\uF8FE', $Word, $PluralEnding)"] + + + +# ACRESCENTADO: valores monetários "R$ 100" -> "100 reais". +# Depende de CurrencySymbols e dos plurais em definitions.yaml. +- name: currency + tag: mrow + match: "count(*)=3 and DefinitionValue(*[1], 'Speech', 'CurrencySymbols') != ''" + variables: + # se o valor é 1, não pluraliza + - IsSingular: "*[3][self::m:mn and .=1] and *[2]='\u2062'" + - CurrencyWord: "DefinitionValue(*[1], 'Speech', 'CurrencySymbols')" + replace: + - bookmark: "*[3]/@id" + - x: "*[3]" + - test: + - if: "$IsSingular" + then: [x: "$CurrencyWord"] + - else_if: "DefinitionValue($CurrencyWord, 'Speech', 'PluralForms') != ''" + then: [x: "DefinitionValue($CurrencyWord, 'Speech', 'PluralForms')"] + else: [x: "DefinitionValue(*[1], 'Speech', 'CurrencySymbols')", ct: "s"] + +- name: sin + tag: mi + match: ".='sin' or .='sen'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: sen] + else: [T: seno] +- name: cos + tag: mi + match: ".='cos'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: cos] + else: [T: cosseno] +- name: tan + tag: mi + match: ".='tan' or .='tg'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: tan] + else: [T: tangente] +- name: sec + tag: mi + match: ".='sec'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: sec] + else: [T: secante] +- name: csc + tag: mi + match: ".='csc'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + # CORREÇÃO: dizia "sec", idêntico à regra sec; cossecante e secante + # ficavam indistinguíveis na fala concisa. + then: [T: cossec] + else: [T: cossecante] +- name: cot + tag: mi + match: ".='cot'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: cotan] + else: [T: cotangente] + +- name: sinh + tag: mi + match: ".='sinh'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: seno hiperbólico] + else: [T: seno hiperbólico] +- name: cosh + tag: mi + match: ".='cosh'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: cosseno hiperbólico] + else: [T: cosseno hiperbólico] +- name: tanh + tag: mi + match: ".='tanh'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: tangente hiperbólica] + else: [T: tangente hiperbólica] +- name: sech + tag: mi + match: ".='sech'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: secante hiperbólica] + else: [T: secante hiperbólica] +- name: csch + tag: mi + match: ".='csch'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: cossecante hiperbólica] + else: [T: cossecante hiperbólica] +- name: coth + tag: mi + match: ".='coth'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + + then: [T: cotangente hiperbólica] + else: [T: cotangente hiperbólica] + +- name: exponential + tag: mi + match: ".='exp'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: "exp"] + else: [T: "exponencial"] +- name: covariance + tag: mi + match: ".='Cov'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: "Cov"] + else: [T: "covariância"] + +- + # CORREÇÃO: faltava o 'Log' maiúsculo (valor principal), presente no inglês. + # Sem ele, "Log x" caía na regra genérica de mi e saía "Log de x", perdendo a + # distinção. A tradução de "principal value log" ainda não foi verificada por + # falante nativo -- daí o 't:' minúsculo. + name: log # handle log, principal Log, and ln (if in an mrow, 'intents' are used) + tag: mi + match: ".='log' or .='Log' or .='ln'" + replace: + - bookmark: "@id" + - test: + - if: "$Verbosity!='Terse'" + then: [T: "o"] # phrase('the' logarithm function is used in mathematics) + - test: + - if: ".= 'log'" + then: [T: "log"] # phrase(the 'log' function is used in mathematics) + - else_if: ".= 'Log'" + then: [t: "log do valor principal"] # (en: 'principal value log') + - else_if: "$Verbosity='Terse'" + then: [SPELL: "'ln'"] + else: [T: "logaritmo natural"] # phrase(the 'natural log' function is used in mathematics) + +- name: multi-line + # audit-ignore: divergência deliberada do en — plural por cadeias, não por concatenação de s + # that eliminates the need for the if: else_if: ... + # IDEA: set a variable with the word to say for the row (e.g., RowLabel = Row/Case/Line/...) + tag: [piecewise, system-of-equations, lines] + match: "." + variables: [IsColumnSilent: true()] + replace: + - x: "count(*)" + # CORREÇÃO: o plural era feito concatenando "s" (ct: "s"), o que produzia + # "equaçãos". Substituído por duas cadeias, singular e plural, escolhidas + # pela contagem — mesma correção já aplicada no ClearSpeak. + - test: + if: "count(*) > 1" + then: + - test: + - if: "self::m:piecewise" + then: [T: "casos"] + - else_if: "self::m:system-of-equations" + then: [T: "equações"] + else: [T: "linhas"] + else: + - test: + - if: "self::m:piecewise" + then: [T: "caso"] + - else_if: "self::m:system-of-equations" + then: [T: "equação"] + else: [T: "linha"] + - pause: short + - x: "*" + +- name: default-multiline + tag: [mtr, mlabeledtr] + match: "parent::m:piecewise or parent::m:system-of-equations or parent::m:lines" + replace: + - pause: medium + - test: + - if: "parent::m:piecewise" + then: [T: "caso"] + - else_if: "parent::m:system-of-equations" + then: [T: "equação"] + else: [T: "linha"] + - x: "count(preceding-sibling::*)+1" + - test: + if: .[self::m:mlabeledtr] + then: + - T: rotulada com + - x: "*[1]/*" + - pause: medium + - test: + if: .[self::m:mlabeledtr] + then: [x: "*[position()>1]"] + else: [x: "*"] + +- name: default-multiline + tag: mtd + match: "parent::*[parent::m:piecewise or parent::m:system-of-equations or parent::m:lines]" + variables: [LongPause: "$SpeechStyle = 'ClearSpeak' and $ClearSpeak_MultiLinePausesBetweenColumns = 'Long'"] + replace: + - x: "*" + - test: + # short pause after each element; medium pause if last element in a row; long pause for last element in matrix unless ClearSpeak override + - if: "count(following-sibling::*) > 0" + then_test: + if: "$LongPause" + then: [pause: medium] + else: [pause: short] + - else_if: "count(../following-sibling::*) > 0" + then_test: + if: "$LongPause" + then: [pause: long] + else: [pause: medium] + else: [pause: long] + +# Matrix/Determinant rules +# matrix and determinant are the same other than "matrix"/"determinant" based on the bracketing chars +# the pausing logic is pushed down to the +# the rules either speak the s (to get "row n") or the s. "column n" spoken if $IsColumnSilent is false +# ACRESCENTADO: regra presente em en/ e ausente em es/ (e portanto em pt). +# Sem ela, dízimas periódicas (0,333...) não eram anunciadas como periódicas. +- name: repeating-decimal + tag: repeating-decimal + match: "." + replace: + - x: "*[1]" + - T: "com dígitos periódicos" + - spell: "*[2]" + +# NOTA: o inglês funde matrix e determinant numa regra só. Em português os +# artigos diferem ("a matriz" / "o determinante"), então a separação é +# deliberada, não é lacuna de paridade. +- name: 1x1-matrix + # audit-ignore: divergência deliberada do en — separada de 1x1-determinant: artigos de gêneros diferentes + tag: matrix + variables: [IsColumnSilent: true()] + match: "count(*)=1 and *[self::m:mtr][count(*) = 1]" + replace: + - OT: "a" + - T: "matriz 1 por 1" + - T: "com o elemento" + - x: "*[1]/*" + +- name: 1x1-determinant + # audit-ignore: divergência deliberada do en — idem + tag: determinant + variables: [IsColumnSilent: true()] + match: "count(*)=1 and *[self::m:mtr][count(*) = 1]" + replace: + - OT: "o" + - T: "determinante 1 por 1" + - T: "com o elemento" + - x: "*[1]/*" + + +- name: zero-matrix + tag: matrix + match: "not( */*/*[not(self::m:mn and .= 0)] )" + replace: + - T: "a matriz nula" + - x: count(*) + - T: "por" + - x: count(*[self::m:mtr][1]/*) + - pause: long + +- name: identity-matrix + tag: matrix + match: + - "count(*) = count(*[1]/*) and " + - "not( */*[count(preceding-sibling::*) = count(../preceding-sibling::*)]/*[not(self::m:mn and .= 1)] ) and " + - "not( */*[count(preceding-sibling::*) != count(../preceding-sibling::*)]/*[not(self::m:mn and .= 0)] )" + replace: + - T: "a matriz identidade" + - x: count(*) + - T: "por" + - x: count(*[self::m:mtr][1]/*) + - pause: long + +- name: diagonal-matrix + tag: matrix + match: + - "count(*) = count(*[1]/*) and " + - "not( */*/*[not(self::m:mn and .= 0)]" + - " [count(../preceding-sibling::*)!=count(../../preceding-sibling::*)]" + - " )" + replace: + - T: "a matriz diagonal" + - x: count(*) + - T: "por" + - x: count(*[self::m:mtr][1]/*) + - pause: long + - insert: + nodes: "(*/*/*[not(self::m:mn and .= 0)]/..)" + replace: [pause: auto] + - pause: long + +# simpler reading methods for smaller matrices if the entries are simple +- name: 2-or-3x1-matrix + tag: matrix + variables: [IsColumnSilent: true()] + match: + - "$ClearSpeak_Matrix != 'SpeakColNum' and " # "simple" isn't used for this preference + - "*[self::m:mtr][count(*) = 1] and " # one column + - count(*)<=3 and # at least two rows + - IsNode(*/*/*,'simple') # IsNode() returns true if all the nodes are simple + replace: + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "o vetor coluna"] + else: [T: "a matriz coluna"] + - x: count(*) + - T: "por 1 coluna" + - pause: long + - x: "*/*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: "fim" + - test: + if: $ClearSpeak_Matrix = 'EndVector' + then: [T: vetor] + else: [T: matriz] + +- name: default-column-matrix + tag: matrix + variables: [IsColumnSilent: true()] + match: "*[self::m:mtr][count(*) = 1]" + replace: + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "o vetor"] + else: [T: "a matriz"] + - x: "count(*)" + - T: "por 1 coluna" + - pause: long + - x: "*" # select the rows (mtr) + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "fim da matriz"] + +- name: 1x2-or-3-matrix + tag: matrix + variables: [IsColumnSilent: "$SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix != 'SpeakColNum'"] + match: + - "$ClearSpeak_Matrix != 'SpeakColNum' and " # "simple" isn't used for this preference + - count(*)=1 and # one row + - count(*[1]/*)<=3 and # at least two cols + - IsNode(*/*/*,'simple') # IsNode() returns true if all the nodes are simple + replace: + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "o vetor"] + else: [T: "a matriz"] + - T: "1 por" + - x: count(*/*) + - T: "linha" + - pause: long + - x: "*/*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: "fim" + - test: + if: $ClearSpeak_Matrix = 'EndMatrix' + then: [T: matriz] + else: [T: vetor] + +- name: default-row-matrix + tag: matrix + variables: [IsColumnSilent: "$SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix = 'SilentColNum'"] + match: "count(*)=1" # one row + replace: + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "o vetor"] + else: [T: "a matriz"] + - T: "1 por" + - x: "count(*/*)" + - T: "linha" + - pause: long + - x: "*/*" # select the cols (mtd) + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: "fim" + - test: + if: $ClearSpeak_Matrix = 'EndMatrix' + then: [T: matriz] + else: [T: vetor] + +- name: simple-small-matrix + tag: [matrix, determinant] + match: + - "$ClearSpeak_Matrix != 'SpeakColNum' and " # "simple" isn't used for this preference + - (count(*)<=3 and count(*[1]/*)<=3) and # no bigger than a 3x3 matrix + - IsNode(*/*/*,'simple') # IsNode() returns true if all the nodes are simple + variables: [IsColumnSilent: "$SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix != 'SpeakColNum'"] + replace: + - test: + if: "self::m:determinant" + then: [T: "o determinante"] + else: [T: "a matriz"] + - x: count(*) + - T: por + - x: count(*[self::m:mtr][1]/*) + - pause: long + - x: "*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: fim + - test: + if: "self::m:determinant" + then: [T: "determinante"] + else: [T: "matriz"] + +- name: default-matrix + tag: [matrix, determinant] + variables: [IsColumnSilent: "$SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix = 'SilentColNum'"] + match: "not(@data-intent-property)" + replace: + - test: + if: "self::m:determinant" + then: [T: "o determinante"] + else: [T: "a matriz"] + - x: "count(*)" + - T: por + - x: "count(*[self::m:mtr][1]/*)" + - pause: long + - x: "*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: fim + - test: + if: "self::m:determinant" + then: [T: determinante] + else: [T: matriz] + +- name: chemistry-msub + + tag: [chemical-formula] + match: "*[1][.='msub']" + replace: + - x: "*[2]" + - test: + if: "$Verbosity='Verbose'" + then: [T: "subscrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] + - x: "*[3]" + +# ACRESCENTADO: dimensões de matriz anotadas como dimension-product +# ("3×5" com intent de dimensão) fala "3 por 5". +- name: dimension-by + tag: mrow + match: dimension-product + replace: + - insert: + nodes: "*" + replace: [T: "por", pause: auto] + +- name: chemistry-msup + tag: [chemical-formula] + match: "count(*)=3 and *[1][.='msup']" + replace: + - x: "*[2]" + - test: + if: "$Verbosity='Verbose'" + then: [T: "sobrescrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] + - x: "*[3]" + - test: + if: "following-sibling::*[1][.='+' or .='-']" # a little lazy -- assumes chemistry superscripts end with + or - + then: [pause: medium] + +- + # There currently is no way to do sub/super for n-ary number of args + # Instead, we just deal with up to two prescripts and up to four postscripts (repeating blocks of similar code [UGLY!]) + # This hopefully covers all reasonable cases... + name: chemistry-scripts + tag: [chemical-formula, chemical-nuclide] + variables: + # computing the number of postscripts is messy because of being optionally present -- we use "mod" to get the count right + - Prescripts: "m:mprescripts/following-sibling::*" + - NumChildren: "count(*)" # need to stash this since the count is wrong inside '*[...]' below + - Postscripts: "*[position()>1 and position() < (last() + ($NumChildren mod 2) -count($Prescripts))]" + match: . # should only be msubsup or mmultiscripts at this point + replace: + - test: + if: "$Prescripts" # we have at least one pre sub/super + then: + # nuclide: speak the superscript first + - test: + if: "not($Prescripts[2][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "sobrescrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] + - x: "$Prescripts[2]" + - pause: "short" + - test: + if: "not($Prescripts[1][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "subscrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] + - x: "$Prescripts[1]" + - pause: "short" + - test: + if: "count($Prescripts) > 2" # can this happen for chemistry??? we allow for one *extra* pre sub/super pair + then: + - test: + if: "not($Prescripts[4][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "sobrescrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] + - x: "$Prescripts[4]" + - pause: "short" + - test: + if: "not($Prescripts[3][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "subscrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] + - x: "$Prescripts[3]" + - pause: "short" + - x: "*[1]" # base + - test: + if: "$Postscripts" + then: + - test: + if: "not($Postscripts[1][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "subscrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] + - x: "$Postscripts[1]" + - pause: "short" + - test: + if: "not($Postscripts[2][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "sobrescrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] + - x: "$Postscripts[2]" + - pause: "short" + - test: + if: "count($Postscripts) > 2" + then: + - test: + if: "not($Postscripts[3][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "subscrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] + - x: "$Postscripts[3]" + - pause: "short" + - test: + if: "not($Postscripts[4][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "sobrescrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] + - x: "$Postscripts[4]" + - pause: "short" + - test: + if: "count($Postscripts) > 4" + then: + - test: + if: "not($Postscripts[5][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "subscrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] + - x: "$Postscripts[5]" + - pause: "short" + - test: + if: "not($Postscripts[6][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "sobrescrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] + - x: "$Postscripts[6]" + - pause: "short" + - test: + if: "count($Postscripts) > 6" + then: + - test: + if: "not($Postscripts[7][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "subscrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] + - x: "$Postscripts[7]" + - pause: "short" + - test: + if: "not($Postscripts[8][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "sobrescrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] + - x: "$Postscripts[8]" + - pause: "short" + - test: + if: "$Postscripts[last()][not(self::m:none)] and following-sibling::*[1][.='+' or .='-']" + then: [pause: medium] + +- name: chemistry + + + tag: chemical-equation + match: "." + replace: + - x: "*" + +- name: chemical-element + tag: chemical-element + match: "." + replace: + - bookmark: "@id" + - spell: text() + - pause: short + +- name: chemical-state + tag: chemical-state + match: "count(*)=1" + replace: + - bookmark: "*[1]/@id" + - test: + - if: ".='s'" + then: [T: "sólido"] + - else_if: ".='l'" + then: [T: "líquido"] + - else_if: ".='g'" + then: [T: "gasoso"] + else: [T: "aquoso"] # (aq) + - pause: short + +- name: chemical-formula-operator-bond + tag: chemical-formula-operator + match: "@data-chemical-bond" + replace: + # FIX: this might be better/more efficient if in unicode.yaml + - bookmark: "@id" + - test: + - if: ".='-' or .=':'" + then: [T: "ligação simples"] + - else_if: ".='=' or .='∷'" # U+2237: o canonicalizador converte '::' nesse caractere + then: [T: "ligação dupla"] + - else_if: ".='≡'" + then: [T: "ligação tripla"] + - else_if: ".='≣'" + then: [T: "ligação quádrupla"] + else: [x: "text()"] + +- name: chemical-formula-operator + tag: chemical-formula-operator + match: "." + replace: + x: "text()" + +- name: chemical-arrow-operator + tag: chemical-arrow-operator + match: "." + replace: + # FIX: this might be better/more efficient if in unicode.yaml + - bookmark: "@id" + - test: + - if: ".='→' or .='⟶'" + then_test: + if: "$Verbosity='Terse'" + then: [T: "forma"] + else: [T: "reage formando"] + - else_if: ".='⇌' or .='🣑'" # U+01F8D1 + then: [T: "está em equilíbrio com"] + - else_if: ".='🣓'" # U+1F8D3 + then: [T: "está em equilíbrio deslocado para a esquerda com"] + - else_if: ".='🣒'" # U+1F8D2 + then: [T: "está em equilíbrio deslocado para a direita com"] + else: [x: "*"] + +- name: chemical-equation-operator + tag: chemical-equation-operator + match: "." + replace: + - bookmark: "@id" + - x: "text()" + +- name: none + tag: none + match: "../../*[self::m:chemical-formula or self::m:chemical-nuclide]" + replace: + - t: "" # don't say anything + +# ACRESCENTADO: fora da química, cai na regra 'default-text', que fala o +# nome da tag -- em inglês isso dá "none", que é aceitável lá, mas em português +# saía a palavra inglesa. Aqui traduzimos. +- name: none-default + tag: none + match: "." + replace: + - T: "nenhum" + +- name: ignore-intent-wrapper + tag: intent-wrapper + match: "." + replace: + - x: "*" diff --git a/Rules/Languages/pt/SharedRules/geometry.yaml b/Rules/Languages/pt/SharedRules/geometry.yaml new file mode 100644 index 000000000..24227e81b --- /dev/null +++ b/Rules/Languages/pt/SharedRules/geometry.yaml @@ -0,0 +1,80 @@ + +--- + +- name: line-segment + tag: line-segment + match: "count(*)=2" + replace: + - test: + if: "$Verbosity='Verbose'" + then: + - T: "o segmento de reta de" + - x: "*[1]" + - T: "a" + - x: "*[2]" + else: + - T: "segmento de reta" + - x: "*[1]" + - x: "*[2]" + +- name: geometry-ray + tag: ray + match: "count(*)=2" + replace: + - test: + if: "$Verbosity='Verbose'" + then: + - T: "a semirreta de" + - x: "*[1]" + - T: "a" + - x: "*[2]" + else: + - T: "semirreta" + - x: "*[1]" + - x: "*[2]" + +- name: geometry-arc + tag: arc + match: "count(*)=2" + replace: + - test: + if: "$Verbosity='Verbose'" + then: [T: "o"] + - T: "arco" + - x: "*[1]" + - x: "*[2]" + +- name: measure-of-angle + tag: measure-of-angle + match: "count(*)=3" + replace: + - test: + if: "$Verbosity='Verbose'" + then: + - T: "a medida do ângulo" + else: + - T: "medida do ângulo" + - x: "*[1]" + - x: "*[2]" + - x: "*[3]" + +# ACRESCENTADO +- name: coordinate + tag: coordinate + match: "." + replace: + - test: + if: "$Verbosity='Verbose'" + then: [OT: "o"] + - T: "ponto" + - test: + if: "$Verbosity='Verbose'" + then: [T: "em"] + - pause: short + - insert: + nodes: "*" + replace: [T: "vírgula", pause: auto] + - pause: short + - test: + if: "($SpeechStyle='ClearSpeak' and $Verbosity='Verbose') or not(IsNode(*[last()],'leaf'))" + then: [T: "fim do ponto"] diff --git a/Rules/Languages/pt/SharedRules/linear-algebra.yaml b/Rules/Languages/pt/SharedRules/linear-algebra.yaml new file mode 100644 index 000000000..72acf26be --- /dev/null +++ b/Rules/Languages/pt/SharedRules/linear-algebra.yaml @@ -0,0 +1,35 @@ +--- + +- name: scalar-determinant + tag: determinant + match: "count(*)=1 and not(*[1][self::m:mtr])" + replace: + - test: + if: "$Verbosity='Verbose'" + then: + - T: "o" + - T: "determinante" + - test: + if: "$Verbosity!='Terse'" + then: + - T: "de" + - x: "*[1]" + - test: + if: "not(IsNode(*[1], 'simple'))" + then: [T: "fim do determinante"] + +- name: subscripted-norm + tag: subscripted-norm + match: "count(*)=2" + replace: + - test: + if: "$Verbosity='Verbose'" + then: + - T: "a" + - x: "*[2]" + - T: "norma" + - test: + if: "$Verbosity!='Terse'" + then: + - T: "de" + - x: "*[1]" diff --git a/Rules/Languages/pt/SimpleSpeak_Rules.yaml b/Rules/Languages/pt/SimpleSpeak_Rules.yaml new file mode 100644 index 000000000..7677751f0 --- /dev/null +++ b/Rules/Languages/pt/SimpleSpeak_Rules.yaml @@ -0,0 +1,338 @@ +--- + +- name: pause + tag: "!*" + match: "not(self::m:math) and not($MatchingPause) and @data-intent-property[contains(., ':pause')]" + replace: + - with: + variables: [MatchingPause: "true()"] + replace: + - test: + - if: "contains(@data-intent-property, ':pause-long')" + then: [pause: long] + - else_if: "contains(@data-intent-property, ':pause-short')" + then: [pause: short] + else: [pause: medium] + - x: "." + +- name: intent-literal-silent + tag: [mi, mo, mn] + match: "contains(@data-intent-property, ':silent:')" + # say nothing + replace: [] + +# handling of negative numbers that come from 'intent' is hard -- we do something that is close to right here +- name: intent-literal-negative-number + tag: mn + match: "starts-with(text(), '-')" + replace: + - T: "menos" # phrase(x 'minus' y) + - x: "translate(text(), '-_', '')" + +- name: default + tag: square-root + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "a"] # phrase('the' square root of x) — "a raiz" (feminino) + - T: "raiz quadrada" # phrase(the 'square root' of x) + - test: + if: "$Verbosity!='Terse'" + then: [T: "de"] # phrase(the square root 'of' x) + else: [pause: short] + - x: "*[1]" + - test: + if: IsNode(*[1], 'leaf') + then: [pause: short] + else: [T: "fim da raiz", pause: short] # phrase(the square root of x 'end root') + +- name: default + tag: root + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: a] + - test: + if: "*[2][self::m:mn]" + then_test: + - if: "*[2][.='2']" + then: [T: "raiz quadrada"] + - else_if: "*[2][.='3']" + then: [T: "raiz cúbica"] + - else_if: "*[2][not(contains(., '.'))]" + then: [T: "raiz de índice", x: "*[2]"] + else: + # CORREÇÃO: o arquivo em espanhol manteve o bloco "pronounce" com o + # sufixo inglês "-th" , herdado do inglês "n-th root". + # Em português a leitura natural é "raiz de índice n", sem sufixo... + - T: "raiz de índice" + - x: "*[2]" + - test: + if: "$Verbosity!='Terse'" + then: [T: "de"] + - x: "*[1]" + - test: + if: IsNode(*[1], 'leaf') + then: [pause: short] + else: [T: "fim da raiz", pause: short] + +# Fraction rules +# Mixed numbers mostly "just work" because the invisible char reads as "and" and other parts read properly on their own +- name: common-fraction + tag: fraction + match: + - "*[1][self::m:mn][not(contains(., '.')) and text()<20] and" + - "*[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]" + replace: [x: ToCommonFraction(.)] +- name: common-fraction-mixed-number + tag: fraction + match: + - "preceding-sibling::*[1][self::m:mo][.='⁤'] and" # preceding element is invisible plus + - "*[1][self::m:mn][not(contains(., '.'))] and" + - "*[2][self::m:mn][not(contains(., '.'))]" + replace: [x: ToCommonFraction(.)] + + +# Units (e.g., meters per second, m^2/s^2, (3m^2)/s) +- name: per-fraction + tag: fraction + match: + - "BaseNode(*[1])[contains(@data-intent-property, ':unit') or" + - " ( self::m:mrow and count(*)=3 and" # maybe a bit paranoid checking the structure... + - " *[1][self::m:mn] and *[2][.='\u2062'] and BaseNode(*[3])[contains(@data-intent-property, ':unit')] ) ] and" + - "BaseNode(*[2])[contains(@data-intent-property, ':unit')] " + replace: + - x: "*[1]" + - T: "por" # phrase('5 meters 'per' second) — "cinco metros por segundo" + - x: "*[2]" + +- name: simple + # don't include nested fractions. E.g, fraction a plus b over c + 1 end fraction" is ambiguous + # by simplistic SimpleSpeak's rules "b over c" is a fraction, but if we say nested fractions + # are never simple, then any 'over' applies only to enclosing "fraction...end fraction" pair. + tag: fraction + match: + - "(IsNode(*[1],'leaf') and IsNode(*[2],'leaf')) and" + - "not(ancestor::*[name() != 'mrow'][1]/self::m:fraction)" # FIX: can't test for mrow -- what should be used??? + replace: + - x: "*[1]" + - T: "sobre" + - x: "*[2]" + - pause: short + +- name: default + tag: fraction + match: "." + replace: + - T: fração + - pause: short + - x: "*[1]" + - test: + if: "not(IsNode(*[1],'leaf'))" + then: [pause: short] + - T: "sobre" + - test: + if: "not(IsNode(*[2],'leaf'))" + then: [pause: short] + - x: "*[2]" + - pause: short + - T: "fim da fração" + - pause: medium + +# rules for functions raised to a power +# these could have been written on 'mrow' but putting them on msup seems more specific +# to see if it is a function, we look right to see if the following sibling is apply-function +- name: inverse-function + tag: inverse-function + match: "." + replace: + - T: "inversa de" # phrase(the 'inverse' of f) + - x: "*[1]" + +- name: function-squared-or-cubed + tag: power + match: + - "*[2][self::m:mn][.='2' or .='3'] and" + - "following-sibling::*[1][self::m:mo][.='⁡']" #invisible function apply + replace: + - x: "*[1]" + - bookmark: "*[2]/@id" + - test: + if: "*[2][.=2]" + then_test: + if: "$Verbosity='Verbose'" + then: [T: "elevado ao quadrado"] + else: [T: "ao quadrado"] + # CORREÇÃO: o espanhol dizia "cúbica" (adjetivo feminino solto), + # incoerente com "al cuadrado" logo acima. O inglês é "cubed". + else: [T: "ao cubo"] +- name: function-power + tag: power + match: + - "following-sibling::*[1][self::m:mo][.='⁡']" #invisible function apply + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: a] + - bookmark: "*[2]/@id" + - T: "potência" + - x: "*[2]" + - T: "de" + - pause: short + - x: "*[1]" + +# non-function rules for power +- name: squared-or-cubed + tag: power + match: "*[2][self::m:mn][.='2' or .='3']" + replace: + - x: "*[1]" + - bookmark: "*[2]/@id" + - test: + if: "*[2][.=2]" + then_test: + if: "$Verbosity='Verbose'" + then: [T: "elevado ao quadrado"] + else: [T: "ao quadrado"] + else: [T: "ao cubo"] + +- name: simple-integer + tag: power + match: "*[2][self::m:mn][not(contains(., '.'))]" + replace: + - x: "*[1]" + - T: "elevado a" + - x: "*[2]" +- name: simple-negative-integer + tag: power + match: + - "*[2][self::m:minus and count(*)=1 and" + - " *[1][self::m:mn][not(contains(., '.'))]]" + replace: + - x: "*[1]" + - T: "elevado a" + - x: "*[2]" +- name: simple-var + tag: power + match: "*[2][self::m:mi][string-length(.)=1]" + replace: + - x: "*[1]" + - T: "elevado a" + - x: "*[2]" + +- name: simple + tag: power + match: "IsNode(*[2], 'leaf')" + replace: + - x: "*[1]" + - T: "elevado a" + - x: "*[2]" + +- name: nested + # it won't end in "power" if the exponent is simple enough + # FIX: not that important, but this misses the case where the nested exp is a negative integer (change test if this is fixed) + # ending nested exponents with "...power power" sounds bad + tag: power + match: + - "*[2][" + - " (self::m:power and not(IsNode(*[2], 'leaf'))) or" # non-simple nested superscript + - " self::m:mrow[*[last()][self::m:power[not(IsNode(*[2], 'leaf'))]]]" # same as above but at the end of an mrow # FIX: need to figure out linear replacement + - " ]" + replace: + - x: "*[1]" + - T: "elevado a" + - x: "*[2]" + - pause: short + # CORREÇÃO: o espanhol escreveu "fin de la exponente" — "exponente" é + # masculino, então já estava errado em espanhol ("fin del exponente"). + - T: "fim do expoente" +- name: default + tag: power + match: "." + replace: + - x: "*[1]" + # CORREÇÃO: a ordem herdada do inglês ("to the n plus 1 power") produzia + # "elevado à n mais 1 potência". Em português o núcleo vem antes do + # complemento: "elevado à potência n mais 1". + - T: "elevado à potência" + - x: "*[2]" + +# +# Some rules on mrows +# +- name: set + tag: set + match: "." + replace: + - test: + - if: "count(*)=0" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: o] + - T: "conjunto vazio" + - else_if: "count(*[1]/*)=3 and *[1]/*[2][self::m:mo][.=':' or .='|' or .='∣']" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: o] + - T: "conjunto de todos os" + - x: "*[1]/*[1]" + - T: "tal que" + - x: "*[1]/*[3]" + else: + - test: + if: "$Verbosity!='Terse'" + then: [T: o] + - T: "conjunto" + - x: "*[1]" + +- name: times + tag: mo + match: + # added: say times is the superscript is not simple + # if we aren't sure if it is times or not, don't say anything + - ".='⁢' and" + - "not(@data-function-guess) and (" + - "not(ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) and " + - " following-sibling::*[1][" + - " IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|') or " + - " self::m:matrix or self::m:determinant or self::m:binomial or" # followed by parens + - " ( (self::m:msub or self::m:msubsup or + ((self::m:msup or self::m:power) and not(IsNode(*[1], 'leaf') and *[2][self::m:mn and (.=2 or '.=3')]))) and " # followed by msup, etc. + - " (*[1][self::m:mrow[IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')] or " + - " self::m:matrix or self::m:determinant] or" # base has parens + - " not(IsNode(*[2], 'simple')) or " + - " (self::m:msubsup and not(IsNode(*[3], 'simple'))))" + - " )" + - " ]" + # other possibility is the preceding element has parens (but not the following) + - " or " + - " preceding-sibling::*[1][" + - " IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')]" # followed by parens + - " )" + replace: + - test: + if: "$Verbosity = 'Verbose'" + then: [T: "multiplicado por"] # (en: 'times') + else: [T: "vezes"] + +- name: no-say-parens + tag: mrow + match: + - "parent::*[not(self::m:msup) and not(self::m:msub) and not(self::m:msubsup) and not(self::m:power) and" + - " not(self::m:math) ] and " # rule out [x] standing alone + - "( IsBracketed(., '(', ')') or IsBracketed(., '[', ']') ) and " + - "( IsNode(*[2], 'simple') )" + # missing clause: 'a positive fraction that is spoken as an ordinal + # (either by the Ordinal preference or by the default rules_' + replace: + - x: "*[2]" + +- include: "SharedRules/geometry.yaml" +- include: "SharedRules/linear-algebra.yaml" +- include: "SharedRules/calculus.yaml" +- include: "SharedRules/general.yaml" +- include: "SharedRules/default.yaml" diff --git a/Rules/Languages/pt/definitions.yaml b/Rules/Languages/pt/definitions.yaml new file mode 100644 index 000000000..adf95240a --- /dev/null +++ b/Rules/Languages/pt/definitions.yaml @@ -0,0 +1,496 @@ +--- +- include: "../../definitions.yaml" +# Lines starting with "#" are a comment +# Each definition in this file is of the form +# - name: { "...", "..." "..." } +# For numbers, +# - name: [] "...", "..." "..." ] + + +# If an "intent" is used, the 'terse:medium:verbose' speech for the intent name is given here for a prefix||infix||postfix||function fixity +# If only one ":" is used, it the first part is used for 'terse' and the second part is used for 'medium' and 'verbose' +# If no ":"s are used, the same speech is used for all forms +# If bracketing words make sense, they are separated with ";"s +# Intent mappings must specify whether they are "prefix", "infix", "postfix", or "function" with an "=" sign +# If there are multiple fixities (e.g., see transpose), they are separated with "|| +# for readability, spaces can be used around any of the delimiter characters +# Note: if there are multiple fixities, the first one is used if the fixity is not given in the intent +- IntentMappings: { + "indexed-by": "infix= ; índice; fim do índice", + "modified-variable": "silent= ", + "say-super": "infix=sobrescrito", # used with 'mo' for superscripts (e.g, "<") + "skip-super": "silent=", # used with 'mo' for superscripts (e.g, "*") + + "absolute-value": "function= ; valor absoluto: o valor absoluto de: o valor absoluto de; fim do valor absoluto", + "binomial": "infix=binomial; escolhe; fim do binomial", + "limit": "prefix=limite quando", + "lim-sup": "prefix=lim sup quando: o limite superior quando: o limite superior quando", + "lim-inf": "prefix=lim inf quando: o limite inferior quando: o limite inferior quando", + "logarithm-with-base": "prefix=log na base: o log na base: o logaritmo na base", + "minus": "infix=menos || prefix=menos", + "plus": "infix=mais || prefix=positivo", + + "transpose": "postfix=transposta || function=transposta", + "norm": "function=; norma: norma: a norma; fim da norma", + # ‖x‖ é inferido pelo motor como 'magnitude' (não 'norm'); sem esta linha + # vazava "magnitude de x" em inglês. Mesma fala da norma. + "magnitude": "function=; norma: norma: a norma; fim da norma", + "trace": "function=; traço: traço de: o traço de; fim do traço", + "dimension": "function=; dimensão: dimensão de: a dimensão de; fim da dimensão", + "homomorphism": "function= ; homomorfismo: homomorfismo de: o homomorfismo de; fim do homomorfismo", + "kernel": "function= ; núcleo: núcleo de: o núcleo de; fim do núcleo", + "vector": "function= ; vetor || prefix=vetor", + # O motor infere ⃗a × ⃗b como um SEM filhos (o operador vira + # o próprio elemento); aí a fixidade infix não se aplica e ele falava o nome + # literal, "cross product". A fixidade nofix cobre esse caso. Idem dot-product. + "cross-product": "infix=vetorial: produto vetorial: produto vetorial || nofix=vetorial: produto vetorial: produto vetorial", + "dot-product": "infix=escalar: produto escalar: produto escalar || nofix=escalar: produto escalar: produto escalar", + + "divergence": "function= ; div: divergente: divergente; fim do divergente", + "curl": "function= ; rotacional; fim do rotacional", + "gradient": "function= ; grad: gradiente: gradiente; fim do gradiente", + "laplacian": "function=laplaciano", + + "chemistry-concentration": "function= ; concentração: concentração de: a concentração de; fim da concentração", + # CORREÇÃO: o en tem duas fixidades (nofix || function); só com a function + # a fala ganha o "de" ("probabilidade de x"). E o separador de palavras do + # conditional-probability é "|", como no en — ";" não é reconhecido aqui. + "probability": "nofix=P: probabilidade || function=probabilidade", + "conditional-probability": "function=probabilidade | dado", + "intersection": "infix=interseção", + "union": "infix=união", + } + + +# ACRESCENTADO: definição presente em en/ e ausente em es/ (e portanto em pt). +# ATENÇÃO: estes NÃO são textos falados — são nomes de intent (chaves internas +# do motor, sempre em inglês). A regra os consulta com IsInDefinition(name(.), ...). +# Traduzi-los quebraria o casamento. Copiados tal e qual do inglês. +- TerseFunctionNames: { + "divergence", "del:gradient", "curl" + } + +- KnownWords: { + "abs", "adj", "ano", "cel", "dez", "din", "elo", "fim", "lux", "nos" + } + +- NavigationParts: { + "large-op": "base; limite inferior; limite superior", + "mfrac": "numerador;denominador", + "fraction": "numerador;denominador", + "msqrt": "radicando", + "square-root": "radicando", + "mroot": "radicando;índice da raiz", + "root": "radicando;índice da raiz", + "msub": "base;subscrito", + "sub": "base;subscrito", + "msup": "base;sobrescrito", + "say-super": "base;sobrescrito", + "skip-super": "base;sobrescrito", + "power": "base;expoente", + "msubsup": "base;subscrito;sobrescrito", + "munder": "base;limite inferior", + "mover": "base;limite superior", + "munderover": "base;limite inferior;limite superior", + + # words for moving into and out of one of the parts (e.g., "move right 'out of' numerator, 'in' denominator") + # it's a hack to put them here, but at least they are grouped with the other navigation parts + "in": "em", + "out": "saindo de", + } + +- SIPrefixes: { + "Q": "quetta", "R": "ronna", "Y": "yotta", "Z": "zetta", "E": "exa", "P": "peta", "T": "tera", "G": "giga", "M": "mega", "k": "quilo", "h": "hecto", "da": "deca", + "d": "deci", "c": "centi", "m": "mili", "µ": "micro", "n": "nano", "p": "pico", "f": "femto", "a": "atto", "z": "zepto", "y": "yocto", "r": "ronto", "q": "quecto" + } + +# this is a list of all units that accept SIPrefixes +# from www.bipm.org/documents/20126/41483022/SIBrochure-9-EN.pdf +# Prefixes may be used with any of the 29 SI units with special names +# The SI prefixes can be used with several of accepted units, but not, for example, with the non-SI units of time. + +- SIUnits: { + # base units + "A": "ampère", + "cd": "candela", + "K": "kelvin", "K": "kelvin", + "g": "grama", + "m": "metro", + "mol": "mol", + "s": "segundo", "sec": "segundo", # "sec" not actually legal + + # derived units + "Bq": "becquerel", + "C": "coulomb", + "°C": "grau Celsius", "℃": "grau Celsius", # should only take negative powers + "F": "farad", + "Gy": "gray", + "H": "henry", + "Hz": "hertz", + "J": "joule", + "kat": "katal", + "lm": "lúmen", + "lx": "lux", + "N": "newton", + "Ω": "ohm", "Ω": "ohm", # Greek Cap letter, U+2126 OHM SIGN + "Pa": "pascal", + "S": "siemens", + "Sv": "sievert", + "T": "tesla", + "V": "volt", + "W": "watt", + "Wb": "weber", + + # accepted (plus a few variants) that take SI prefixes + "l": "litro", "L": "litro", "ℓ": "litro", # Should only take negative powers + "t": "tonelada", # should only take positive powers + "Da": "dalton", + "Np": "neper", # should only take negative powers + "u": "unidade de massa atômica", + "eV": "elétron-volt", + "rad": "radiano", # should only take negative powers + "sr": "esferorradiano", # should only take negative powers + + # others that take a prefix + "a": "ano", # should only take positive powers + "as": "segundo de arco", # see en.wikipedia.org/wiki/Minute_and_second_of_arc + + # technically wrong, but used in practice with SI Units (and only positive powers) + "b": "bit", # should only take positive powers + "B": "byte", # should only take positive powers + "Bd": "baud", # should only take positive powers + } + + +- UnitsWithoutPrefixes: { + # time + "″": "segundo", "\"": "segundo", + "′": "minuto", "'": "minuto","min": "minuto", + "h": "hora", "hr": "hora", "Hr": "hora", + "d": "dia", "dy": "dia", + "w": "semana", "wk": "semana", + "y": "ano", "yr": "ano", + + # angles + "°": "grau", "deg": "grau", # should only take negative powers + "arcmin": "minuto de arco", + "amin": "minuto de arco", + "am": "minuto de arco", + "MOA": "minuto de arco", + "arcsec": "segundo de arco", + "asec": "segundo de arco", + + # distance + "au": "unidade astronômica", "AU": "unidade astronômica", + "ltyr": "ano-luz", "ly": "ano-luz", + "pc": "parsec", + "Å": "angström", "Å": "angström", # U+00C5 and U+212B + "fm": "fermi", + + # others + "ha": "hectare", + # "B": "bel", # "B" more commonly means bytes + "dB": "decibel", # already logarithmic, so not used with SI prefixes + # radiano com prefixo dobra o r (nano+radiano = nanorradiano) + "mrad": "milirradiano", "µrad": "microrradiano", "nrad": "nanorradiano", "prad": "picorradiano", "krad": "quilorradiano", + + + # CORREÇÃO ORTOGRÁFICA pt: prefixo terminado em vogal seguido de + # palavra iniciada por "s" dobra o s ex: milissegundo, microssegundo, + # nanossegundo. É o mesmo caso já tratado para "radiano" acima + # (milirradiano). A regra genérica de composição do MathCAT concatena + # sem dobrar e produziria "milisegundo". + # "as" fica de fora: o símbolo já significa "segundo de arco". + "Qs": "quettassegundo", "Rs": "ronnassegundo", "Ys": "yottassegundo", "Zs": "zettassegundo", "Es": "exassegundo", + "Ps": "petassegundo", "Ts": "terassegundo", "Gs": "gigassegundo", "Ms": "megassegundo", "ks": "quilossegundo", + "hs": "hectossegundo", "das": "decassegundo", "ds": "decissegundo", "cs": "centissegundo", "ms": "milissegundo", + "µs": "microssegundo", "ns": "nanossegundo", "ps": "picossegundo", "fs": "femtossegundo", "zs": "zeptossegundo", + "ys": "yoctossegundo", "rs": "rontossegundo", "qs": "quectossegundo", + + "Qsec": "quettassegundo", "Rsec": "ronnassegundo", "Ysec": "yottassegundo", "Zsec": "zettassegundo", + "Esec": "exassegundo", "Psec": "petassegundo", "Tsec": "terassegundo", "Gsec": "gigassegundo", + "Msec": "megassegundo", "ksec": "quilossegundo", "hsec": "hectossegundo", "dasec": "decassegundo", + "dsec": "decissegundo", "csec": "centissegundo", "msec": "milissegundo", "µsec": "microssegundo", + "μsec": "microssegundo", "nsec": "nanossegundo", "psec": "picossegundo", "fsec": "femtossegundo", + "zsec": "zeptossegundo", "ysec": "yoctossegundo", "rsec": "rontossegundo", "qsec": "quectossegundo", + + + "μs": "microssegundo", + + + "cas": "centissegundo de arco", "mas": "milissegundo de arco", + "µas": "microssegundo de arco", "μas": "microssegundo de arco", "nas": "nanossegundo de arco", + "pas": "picossegundo de arco", "fas": "femtossegundo de arco", "zas": "zeptossegundo de arco", + "yas": "yoctossegundo de arco", "ras": "rontossegundo de arco", "qas": "quectossegundo de arco", + + "QS": "quettassiemens", "RS": "ronnassiemens", "YS": "yottassiemens", "ZS": "zettassiemens", "ES": "exassiemens", + "PS": "petassiemens", "TS": "terassiemens", "GS": "gigassiemens", "MS": "megassiemens", "kS": "quilossiemens", + "hS": "hectossiemens", "daS": "decassiemens", "dS": "decissiemens", "cS": "centissiemens", "mS": "milissiemens", + "µS": "microssiemens", "nS": "nanossiemens", "pS": "picossiemens", "fS": "femtossiemens", "aS": "attossiemens", + "zS": "zeptossiemens", "yS": "yoctossiemens", "rS": "rontossiemens", "qS": "quectossiemens", + + "QSv": "quettassievert", "RSv": "ronnassievert", "YSv": "yottassievert", "ZSv": "zettassievert", "ESv": "exassievert", + "PSv": "petassievert", "TSv": "terassievert", "GSv": "gigassievert", "MSv": "megassievert", "kSv": "quilossievert", + "hSv": "hectossievert", "daSv": "decassievert", "dSv": "decissievert", "cSv": "centissievert", "mSv": "milissievert", + "µSv": "microssievert", "nSv": "nanossievert", "pSv": "picossievert", "fSv": "femtossievert", "aSv": "attossievert", + "zSv": "zeptossievert", "ySv": "yoctossievert", "rSv": "rontossievert", "qSv": "quectossievert", + + "atm": "atmosfera", + "amu": "unidade de massa atômica", + "bar": "bar", + "cal": "caloria", + "Ci": "curie", + "grad": "grado", + "M": "molar", + "R": "roentgen", + "rpm": "rotação por minuto", + "℧": "mho", + "dyn": "dina", + "erg": "erg", + + # special case overrides because prefixes with the base "metro" all get accents + "Qm": "quetâmetro", "Rm": "ronâmetro", "Ym": "yotâmetro", "Zm": "zetâmetro", "Em": "exâmetro", "Pm": "petâmetro", + "Tm": "terâmetro", "Gm": "gigâmetro", "Mm": "megâmetro", "km": "quilômetro", "hm": "hectômetro", "dam": "decâmetro", + "dm": "decímetro", "cm": "centímetro", "mm": "milímetro", "µm": "micrômetro", "nm": "nanômetro", "pm": "picômetro", + # conflicts: "fm": "femtômetro", "am": "attômetro", + "zm": "zeptômetro", "ym": "yoctômetro", "rm": "rontômetro", "qm": "quectômetro", + + # powers of 2 used with bits and bytes + "Kib": "kibibit", "Mib": "mebibit", "Gib": "gibibit", "Tib": "tebibit", "Pib": "pebibit", "Eib": "exbibit", "Zib": "zebibit", "Yib": "yobibit", + "KiB": "kibibyte", "MiB": "mebibyte", "GiB": "gibibyte", "TiB": "tebibyte", "PiB": "pebibyte", "EiB": "exbibyte", "ZiB": "zebibyte", "YiB": "yobibyte", + } + + + # this will only be used if the language is English, so it can be empty for other countries + # Mantida em inglês de propósito: são unidades imperiais, sem uso no Brasil. +- EnglishUnits: { + # length + "in": "inch", + "ft": "foot", + "mi": "mile", + "rd": "rod", + "li": "link", + "ch": "chain", + + # area + "sq in": "square inch", "sq. in": "square inch", "sq. in.": "square inch", + "sq ft": "square foot", "sq. ft": "square foot", "sq. ft.": "square foot", + "sq yd": "square yard", "sq. yd": "square yard", "sq. yd.": "square yard", + "sq mi": "square mile", "sq. mi": "square mile", "sq. mi.": "square mile", + "ac": "acre", + "FBM": "board foot", + + # volume + "cu in": "cubic inch", "cu. in": "cubic inch", "cu. in.": "cubic inch", + "cu ft": "cubic foot", "cu. ft": "cubic foot", "cu. ft.": "cubic foot", + "cu yd": "cubic yard", "cu. yd": "cubic yard", "cu. yd.": "cubic yard", + "bbl": "barrel", "BBL": "barrel", + "pk": "peck", + "bu": "bushel", + "tsp": "teaspoon", + "tbl": "tablespoon", + + # liquid + "fl dr": "fluid drams", + "fl oz": "fluid ounce", + "gi": "gill", + "cp": "cup", "cup": "cup", + "pt": "pint", + "qt": "quart", + "gal": "gallon", + + # weight + "gr": "grain", + "dr": "dram", + "oz": "ounce", "℥": "ounce", + "lb": "pound", + "cwt": "hundredweight", + "dwt": "pennyweight", + "oz t": "troy ounce", + "lb t": "troy pound", + + # energy + "hp": "horsepower", + "BTU": "BTU", + "°F": "degree fahrenheit", "℉": "degree fahrenheit", + + # other + "mph": "mile per hour", + "mpg": "mile per gallon", + } + +# ACRESCENTADO símbolos monetários para a regra currency. +# O inglês não tem R$; acrescentado por ser o caso principal no Brasil. +- CurrencySymbols: { + "R$": "real", + "$": "dólar", "US$": "dólar", "¢": "centavo", "€": "euro", "£": "libra", + "₡": "colón", "₤": "lira", "₨": "rupia", "₩": "won", "₪": "shekel", + "₱": "peso", "₹": "rupia", "₺": "lira", "₿": "bitcoin", + } + +- PluralForms: { + "lúmen": "lúmens", + "kelvin": "kelvins", + "grau Celsius": "graus Celsius", + # O plural genérico acrescenta "s" no FIM da string, o que produziria + # "yoctossegundo de arcos". O "s" tem de ir no substantivo, não na frase. + # (a forma sem prefixo já está mais abaixo, junto de "minuto de arco".) + "centissegundo de arco": "centissegundos de arco", + "milissegundo de arco": "milissegundos de arco", + "microssegundo de arco": "microssegundos de arco", + "nanossegundo de arco": "nanossegundos de arco", + "picossegundo de arco": "picossegundos de arco", + "femtossegundo de arco": "femtossegundos de arco", + "zeptossegundo de arco": "zeptossegundos de arco", + "yoctossegundo de arco": "yoctossegundos de arco", + "rontossegundo de arco": "rontossegundos de arco", + "quectossegundo de arco": "quectossegundos de arco", + "grau Fahrenheit": "graus Fahrenheit", + "hertz": "hertz", + "siemens": "siemens", + "lux": "lux", + "mol": "mols", + # a regra genérica acrescenta "es" a palavras terminadas em l/r, o que + # gera "decibeles"/"molares". Em português o plural de -el é -éis. + "decibel": "decibéis", + "bel": "béis", + + # Unidades invariáveis no plural continuam invariáveis quando prefixadas. + # A regra genérica não consulta o nome composto e produziria + # "milissiemenses", "decahertzes", "attoluxes". + "quettassiemens": "quettassiemens", "ronnassiemens": "ronnassiemens", "yottassiemens": "yottassiemens", "zettassiemens": "zettassiemens", + "exassiemens": "exassiemens", "petassiemens": "petassiemens", "terassiemens": "terassiemens", "gigassiemens": "gigassiemens", + "megassiemens": "megassiemens", "quilossiemens": "quilossiemens", "hectossiemens": "hectossiemens", "decassiemens": "decassiemens", + "decissiemens": "decissiemens", "centissiemens": "centissiemens", "milissiemens": "milissiemens", "microssiemens": "microssiemens", + "nanossiemens": "nanossiemens", "picossiemens": "picossiemens", "femtossiemens": "femtossiemens", "attossiemens": "attossiemens", + "zeptossiemens": "zeptossiemens", "yoctossiemens": "yoctossiemens", "rontossiemens": "rontossiemens", "quectossiemens": "quectossiemens", + "quettahertz": "quettahertz", "ronnahertz": "ronnahertz", "yottahertz": "yottahertz", "zettahertz": "zettahertz", + "exahertz": "exahertz", "petahertz": "petahertz", "terahertz": "terahertz", "gigahertz": "gigahertz", + "megahertz": "megahertz", "quilohertz": "quilohertz", "hectohertz": "hectohertz", "decahertz": "decahertz", + "decihertz": "decihertz", "centihertz": "centihertz", "milihertz": "milihertz", "microhertz": "microhertz", + "nanohertz": "nanohertz", "picohertz": "picohertz", "femtohertz": "femtohertz", "attohertz": "attohertz", + "zeptohertz": "zeptohertz", "yoctohertz": "yoctohertz", "rontohertz": "rontohertz", "quectohertz": "quectohertz", + "quettalux": "quettalux", "ronnalux": "ronnalux", "yottalux": "yottalux", "zettalux": "zettalux", + "exalux": "exalux", "petalux": "petalux", "teralux": "teralux", "gigalux": "gigalux", + "megalux": "megalux", "quilolux": "quilolux", "hectolux": "hectolux", "decalux": "decalux", + "decilux": "decilux", "centilux": "centilux", "mililux": "mililux", "microlux": "microlux", + "nanolux": "nanolux", "picolux": "picolux", "femtolux": "femtolux", "attolux": "attolux", + "zeptolux": "zeptolux", "yoctolux": "yoctolux", "rontolux": "rontolux", "quectolux": "quectolux", + + "mho": "mhos", + "real": "reais", "dólar": "dólares", "colón": "colones", + "pascal": "pascals", + "weber": "webers", + "becquerel": "becquerels", + "katal": "katals", + "rotação por minuto": "rotações por minuto", + "unidade de massa atômica": "unidades de massa atômica", + "unidade astronômica": "unidades astronômicas", + "ano-luz": "anos-luz", + "minuto de arco": "minutos de arco", + "segundo de arco": "segundos de arco", + } + +# ---------------- Cardinal and Ordinal Numbers -------------------------- +# The following definitions are used to convert numbers to words +# The are mainly used for ordinals, of which there are two cases: +# 1. Regular ordinals: first, second, third, ... +# 2. Ordinals used in the denominator of fractions (e.g, one half, one third) +# When used in the denominator of fractions, a plural version might be +# used (e.g., two halves, two thirds) +# Although a lot of languages are regular after a few entries, for generality, +# the following lists should be filled out even though they are the same +# or easily derived from others in many languages (e.g, an 's' is added for plurals). +# The larger ordinal numbers (e.g, millionth) is used when there are only +# '0's after that decimal place (e.g., 23000000). +# +# NOTA DE TRADUÇÃO -> regra do português para denominador de fração: +# até 1/10 usa-se o ordinal ("um terço", "um décimo"); +# de 1/11 em diante usa-se "avos" ("um onze avos", "três vinte avos"). +# Isso difere do inglês e do espanhol, e está refletido nas listas plurais. + +# All definitions start 0, 10, 100, etc. + +# The definitions for the "ones" should extend until a regular pattern begins +# The minimum length is 10. + +- NumbersOnes: [ + "zero", "um", "dois", "três", "quatro", "cinco", "seis", "sete", "oito", "nove", + "dez", "onze", "doze", "treze", "catorze", "quinze", "dezesseis", + "dezessete", "dezoito", "dezenove" + ] + +- NumbersOrdinalOnes: [ + "zero", "primeiro", "segundo", "terceiro", "quarto", "quinto", "sexto", "sétimo", "oitavo", "nono", + "décimo", "décimo primeiro", "décimo segundo", "décimo terceiro", "décimo quarto", "décimo quinto", "décimo sexto", + "décimo sétimo", "décimo oitavo", "décimo nono" + ] + +- NumbersOrdinalPluralOnes: [ + "zeros", "primeiros", "meios", "terços", "quartos", "quintos", "sextos", "sétimos", "oitavos", "nonos", + "décimos", "onze avos", "doze avos", "treze avos", "catorze avos", "quinze avos", "dezesseis avos", + "dezessete avos", "dezoito avos", "dezenove avos" + ] + + # stop when regularity begins +# A lista parava em "meio": de 1/3 em diante o motor caía nos ordinais +# comuns e falava "1 terceiro". Até 1/10 a forma é a do denominador de +# fração ("um terço", "um décimo"); de 1/11 em diante entra "avos", que já +# está nas listas plurais acima. Ver ACHADOS 9. +- NumbersOrdinalFractionalOnes: [ + "zero", "primeiro", "meio", "terço", "quarto", "quinto", "sexto", "sétimo", "oitavo", "nono", + "décimo" + ] + + # stop when regularity begins +- NumbersOrdinalFractionalPluralOnes: [ + "zeros", "primeiros", "meios", "terços", "quartos", "quintos", "sextos", "sétimos", "oitavos", "nonos", + "décimos" + ] + + + # What to use for multiples of 10 +- NumbersTens: [ + "", "dez", "vinte", "trinta", "quarenta", "cinquenta", "sessenta", "setenta", "oitenta", "noventa" + ] + +- NumbersOrdinalTens: [ + "", "décimo", "vigésimo", "trigésimo", "quadragésimo", "quinquagésimo", "sexagésimo", "septuagésimo", "octogésimo", "nonagésimo" + ] + +- NumbersOrdinalPluralTens: [ + "", "décimos", "vinte avos", "trinta avos", "quarenta avos", "cinquenta avos", "sessenta avos", "setenta avos", "oitenta avos", "noventa avos" + ] + + +- NumbersHundreds: [ + "", "cem", "duzentos", "trezentos", "quatrocentos", "quinhentos", + "seiscentos", "setecentos", "oitocentos", "novecentos" + ] + +- NumbersOrdinalHundreds: [ + "", "centésimo", "ducentésimo", "tricentésimo", "quadringentésimo", "quingentésimo", + "sexcentésimo", "septingentésimo", "octingentésimo", "noningentésimo" + ] + +- NumbersOrdinalPluralHundreds: [ + "", "centésimos", "ducentésimos", "tricentésimos", "quadringentésimos", "quingentésimos", + "sexcentésimos", "septingentésimos", "octingentésimos", "noningentésimos" + ] + + + # At this point, hopefully the language is regular. If not, code needs to be written +- NumbersLarge: [ + "", "mil", "milhão", "bilhão", "trilhão", "quatrilhão", + "quintilhão", "sextilhão", "septilhão", "octilhão", "nonilhão" + ] + +- NumbersOrdinalLarge: [ + "", "milésimo", "milionésimo", "bilionésimo", "trilionésimo", "quatrilionésimo", + "quintilionésimo", "sextilionésimo", "septilionésimo", "octilionésimo", "nonilionésimo" + ] + +- NumbersOrdinalPluralLarge: [ + "", "milésimos", "milionésimos", "bilionésimos", "trilionésimos", "quatrilionésimos", + "quintilionésimos", "sextilionésimos", "septilionésimos", "octilionésimos", "nonilionésimos" + ] diff --git a/Rules/Languages/pt/navigate.yaml b/Rules/Languages/pt/navigate.yaml new file mode 100644 index 000000000..bc7c5fe26 --- /dev/null +++ b/Rules/Languages/pt/navigate.yaml @@ -0,0 +1,1773 @@ +--- +# Documentation: +# +# The general form for many rules is: +# 1. Say the command if this is first rule to fire (MatchCounter) and depending upon "NavVerbosity"s value +# 2. Say info about moving into/out of 2D structures +# 3. Set some variables and possibly recurse. +# If recursing, "MatchCounter" should be incremented. +# If stopping, "NavNode" should be set. +# +# The meaning of NavVerbosity: +# * Verbose -- always echo the command and end points (e.g., "can't move right") +# * Medium -- only echo the command for obscure commands like the placemarker commands; also say end points +# * Terse -- no echo of commands or end points +# +# For the second item, a common set of rules is used. These rules require the variable "Move2D" +# to be set along with "Child2D", where "Move2D" is either 'in' or 'out'. +# +# In addition, the navigation rules make use of two functions: +# +# int DistanceFromLeaf(node, leftSide, treat2DElementsAsTokens) +# Returns the distance (number of children) until a leaf is reached by traversing the leftmost/rightmost child +# If 'treat2DElementsAsTokens' is true, then 2D notations such as fractions are treated like leaves +# A leaf has distance == 0 +# +# EdgeNode(node, "left"/"right", stopNodeName) +# Returns the stopNode if at left/right edge of named ancestor node. 'stopNodeName' can also be "2D" +# If the stopNode isn't found, the original node is returned +# Note: if stopNodeName=="math", then punctuation is taken into account since it isn't really part of the math +# +# A few other variables are of importance to Navigation +# NavMode -- Enhanced, Simple, Character +# ReadZoomLevel -- -1 for Enhanced, otherwise the distance from leaf the rules should maintain +# PlaceMarkerIndex + + +# Rules for speaking what happens when moving into or out of a notation +- name: into-or-out-of + tag: mfrac + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "numerador"] + else: [T: "denominador"] + - pause: "medium" + +- name: into-or-out-of + tag: msqrt + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - T: "raiz quadrada" + - pause: "medium" + +- name: into-or-out-of + tag: mroot + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "radicando"] + else: [T: "índice da raiz"] + - pause: "medium" + +- name: into-or-out-of + tag: msub + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "base"] + else: [T: "subscrito"] + - pause: "medium" + +- name: into-or-out-of + tag: msup + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "base"] + else: [T: "sobrescrito"] # FIX: it would be better to use the word used when reading (power, exponent, ...) + - pause: "medium" + +- name: into-or-out-of + tag: msubsup + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + - if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "base"] + - else_if: "count($Child2D/preceding-sibling::*)=1" + then: [T: "subscrito"] + else: [T: "sobrescrito"] # FIX: it would be better to use the word used when reading (power, exponent, ...) + - pause: "medium" + +- name: into-or-out-of + tag: munder + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "base"] + else: [T: "limite inferior"] + - pause: "medium" + +- name: into-or-out-of + tag: mover + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "base"] + else: [T: "limite superior"] + - pause: "medium" + +- name: into-or-out-of + tag: munderover + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + - if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "base"] + - else_if: "count($Child2D/preceding-sibling::*)=1" + then: [T: "limite inferior"] + else: [T: "limite superior"] + - pause: "medium" + +- name: into-or-out-of + tag: mmultiscripts + match: "$Move2D != ''" + replace: + - test: + if: "name($Child2D)!='none'" + then: + - with: + variables: + - NumPrecedingSiblings: "count($Child2D/preceding-sibling::*)" + replace: + - x: "$Move2D" + - test: + - if: "$NumPrecedingSiblings=0" + then: [T: "base"] + - else_if: "$Child2D/preceding-sibling::*[self::m:mprescripts]" # are we before mprescripts and hence are postscripts + then: + - test: # in postscripts -- base shifts by one + if: "$NumPrecedingSiblings mod 2 = 0" + then: [T: "subscrito"] + else: [T: "sobrescrito"] + else: + - test: + if: "$NumPrecedingSiblings mod 2 = 0" + then: [T: "sobrescrito"] + else: [T: "subscrito"] + - pause: "medium" + +- name: into-or-out-of + tag: mtd + match: "$Move2D = 'em'" + replace: + - x: "$Move2D" + - T: "coluna" + - x: "count($Child2D/preceding-sibling::*)+1" + - pause: "medium" + +- name: into-or-out-of + tag: [mtr, mlabeledtr] + match: "$Move2D = 'em'" + replace: + - x: "$Move2D" + - x: "count($Child2D/preceding-sibling::*)+1" + - pause: "medium" + +- name: default-move + # nothing to do (not 2D) -- need to catch $Move2D though so rules based on NavCommand don't trigger + tag: "*" + match: "$Move2D != ''" + replace: [] + +# ********* Go back to last position *************** +# This is first since start/end position shouldn't matter +- name: move-last-location + + + tag: "*" + match: "$NavCommand = 'MoveLastLocation'" + replace: + - test: + if: "$NavVerbosity != 'Terse'" + then: + - test: + - if: "$PreviousNavCommand = 'ZoomIn'" + then: [T: "desfazer afastamento"] + - else_if: "$PreviousNavCommand = 'ZoomOut'" + then: [T: "desfazer aproximação"] + - else_if: "$PreviousNavCommand = 'ZoomInAll'" + then: [T: "desfazer afastamento máximo"] + - else_if: "$PreviousNavCommand = 'ZoomOutAll'" + then: [T: "desfazer aproximação máxima"] + - else_if: "$PreviousNavCommand = 'MovePrevious' or $PreviousNavCommand = 'MovePreviousZoom'" + then: [T: "desfazer movimento para a esquerda"] + - else_if: "$PreviousNavCommand = 'MoveNext' or $PreviousNavCommand = 'MoveNextZoom'" + then: [T: "desfazer movimento para a direita"] + - else_if: "$PreviousNavCommand = 'None'" + then: [T: "nenhum comando anterior"] + - pause: "long" + - set_variables: [NavNode: "@id"] + +# many times, for typographic reasons, people include punctuation at the end of a math expr +# these rules detect that and skip speaking it (should be similar regular rule) +- name: skip-punct-at-end-zoom-in + tag: mrow + match: + - "($NavCommand = 'ZoomIn' or $NavCommand = 'ZoomInAll' or $NavCommand = 'MoveNextZoom' or $NavCommand = 'MovePreviousZoom') and" + - " parent::m:math and count(*)=2 and" + - " *[2][translate(.,'.,;:?', '')='']" + replace: + - x: "*[1]" + +# ********* ZoomIn *************** +- name: zoom-in-leaf + + tag: "*" + match: "($NavCommand = 'ZoomIn' or $NavCommand = 'ZoomInAll') and IsNode(., 'leaf')" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse'" + then: [T: "aproximado ao máximo", pause: "long"] + - test: + if: "$ReadZoomLevel!=-1" + then: + - set_variables: [ReadZoomLevel: "0"] + - set_variables: [NavNode: "@id"] + +# special case of zooming into a matrix or determinant -- move to the first element +- name: zoom-in-matrix + + tag: mrow + match: + - "$NavCommand = 'ZoomIn' and count(*)=3 and " + - "*[2][self::m:mtable and (IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|'))]" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "aproximado", pause: "long"] + - set_variables: [NavNode: "*[2]/*[1]/@id"] + +# special case of zooming into a table -- move to the first element +- name: zoom-in-table + tag: mtable + match: "$NavCommand = 'ZoomIn'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "aproximado", pause: "long"] + - set_variables: [NavNode: "*[1]/@id"] + +- name: zoom-in-mrow-in-math + # Moving to first or last is meaningless the 'math' has only an 'mrow' inside -- dig inside and do it again + tag: math + match: "count(*)=1 and ($NavCommand = 'ZoomIn' or $NavCommand = 'MoveNextZoom' or $NavCommand = 'MovePreviousZoom')" + replace: + - test: + if: "$NavCommand = 'MovePreviousZoom'" + then: [x: "*[last()]"] + else: [x: "*[1]"] + +- # For msqrt and menclose, if the single child isn't an mrow, don't zoom in + name: zoom-in-again + # If there is only one child, this isn't an interesting move -- zoom in again + tag: "*" + match: + - "($NavCommand = 'ZoomIn' or " + - " ($NavCommand = 'MoveNextZoom' or $NavCommand = 'MovePreviousZoom') and $NavMode='Enhanced') and " + - "count(*)=1 and (*[1][self::m:mrow] and not(self::m:msqrt or self::m:menclose))" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "aproximado", pause: "long"] + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: + - test: + if: "$NavCommand = 'MovePreviousZoom'" + then: [x: "*[last()]"] + else: [x: "*[1]"] + +- name: zoom-in-enhanced + + tag: "*" + match: "$NavCommand = 'ZoomIn' and $NavMode='Enhanced'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "aproximado", pause: "long"] + - test: + - if: "self::m:mtr or self::m:mlabeledtr" + then: + - with: + variables: [Move2D: "'em'", Child2D: "*[1]/*[1]"] + replace: [x: "."] + - set_variables: [NavNode: "*[1]/*[1]/@id"] # skip mtd + - else_if: "*[1][self::m:mrow and IsBracketed(., '(', ')', false) or IsBracketed(., '[', ']', false)]" # auto zoom + then: + - with: + variables: [Move2D: "'em'", Child2D: "*[1]"] + replace: [x: "."] + - set_variables: [NavNode: "*[1]/*[2]/@id"] # skip parens/brackets + else: + - with: + variables: [Move2D: "'em'", Child2D: "*[1]"] + replace: [x: "."] + - set_variables: [NavNode: "*[1]/@id"] + +- name: zoom-in-2D-not-enhanced + tag: "*" + match: "$NavCommand = 'ZoomIn' and $NavMode!='Enhanced' and IsNode(., '2D')" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "aproximado", pause: "long"] + - with: + variables: [Move2D: "'em'", Child2D: "*[1]"] + replace: [x: "."] + - with: + variables: [MatchCounter: "$MatchCounter + 1", NavCommand: "'MoveNextZoom'"] + replace: [x: "*[1]"] + +- name: zoom-in-default + tag: "*" + match: "$NavCommand = 'ZoomIn'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "aproximado", pause: "long"] + - with: + variables: [Move2D: "'em'", Child2D: "*[1]"] + replace: [x: "."] + - test: + if: "$NavMode='Character'" + then: + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: "*[1]"] + else_test: + if: "self::m:mtd" + then: [x: "*[1]"] + else: + - test: + if: "$ReadZoomLevel!=-1" + then: + - set_variables: [ReadZoomLevel: "DistanceFromLeaf(*[1], true, $NavMode!='Character')"] + - set_variables: [NavNode: "*[1]/@id"] + +- name: zoom-in-all-default + tag: "*" + match: "$NavCommand = 'ZoomInAll'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "aproximado ao máximo", pause: "medium"] + - with: + variables: [Move2D: "'em'", Child2D: "*[1]"] + replace: [x: "."] + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: "*[1]"] + +- name: zoom-out + tag: math + match: "$NavCommand = 'ZoomOut' or $NavCommand = 'ZoomOutAll'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse'" + then: [T: "afastado ao máximo", pause: "long"] + - set_variables: [NavNode: "*[1]/@id"] # no-op for $NavCommand = 'ZoomOut' + +- name: zoom-out-top + tag: "*" + match: + - "($NavCommand = 'ZoomOut' or $NavCommand = 'ZoomOutAll') and" + - "parent::m:math " + replace: + - x: ".." # let math rule deal with it + +- name: skip-punct-at-end-zoom-out + tag: mrow + match: + - "($NavCommand = 'ZoomOut' or $NavCommand = 'ZoomOutAll') and" + - " parent::m:math and count(*)=2 and" + - " *[2][translate(.,'.,;:?', '')='']" + replace: + - x: ".." + +- name: zoom-out-all-default + tag: "*" + match: "$NavCommand = 'ZoomOutAll'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse'" + then: [T: "afastado ao máximo", pause: "medium"] + - with: + variables: [Move2D: "'fora de'", Child2D: "."] + replace: [x: ".."] + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: ".."] + +# deal with internal zooming: MoveNextZoom and MovePreviousZoom + +# start with Enhanced mode +- name: move-zoom-enhanced + tag: "*" + match: + - "($NavCommand = 'MoveNextZoom' or $NavCommand = 'MovePreviousZoom') and " + - "$NavMode = 'Enhanced'" + replace: + # don't bother with MatchCounter since we only get here if > 1 + - with: + variables: [Move2D: "'em'", Child2D: "*[1]"] + replace: [x: "."] + - test: + - if: "count(*)> 1 or IsNode(., 'leaf') or self::m:msqrt or self::m:menclose" + then: [set_variables: [NavNode: "@id"]] + else: [x: "*[1]"] + +- name: move-next-zoom-not-enhanced + # $ReadZoomLevel must be >= 0 + tag: "*" + match: "$NavCommand = 'MoveNextZoom'" + replace: + #don't bother with MatchCounter since we only get here if > 1 + - test: + if: "$ReadZoomLevel >= DistanceFromLeaf(., false, $NavMode!='Character')" + then: + # - with: + # variables: [Move2D: "'em'", Child2D: "following-sibling::*[1]"] + # replace: [x: ".."] + - set_variables: [NavNode: "@id"] + else: + - with: + variables: [Move2D: "'em'", Child2D: "*[1]"] + replace: [x: "."] + - x: "*[1]" + +- name: move-previous-zoom-not-enhanced + # $ReadZoomLevel must be >= 0 + tag: "*" + match: "$NavCommand = 'MovePreviousZoom'" + replace: + #don't bother with MatchCounter since we only get here if > 1 + - test: + if: "$ReadZoomLevel >= DistanceFromLeaf(., true, $NavMode!='Character')" + then: + # - with: + # variables: [Move2D: "'em'", Child2D: "preceding-sibling::*[1]"] + # replace: [x: ".."] + - set_variables: [NavNode: "@id"] + else: + - with: + variables: [Move2D: "'em'", Child2D: "*[last()]"] + replace: [x: "."] + - x: "*[last()]" + +# ********* ZoomOut *************** +- name: zoom-out-default + + + tag: mtd + match: "$Move2D = '' and ($NavCommand = 'ZoomOut')" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "afastar", pause: "medium"] + # we need to speak it here + - T: "linha" + # if we let the speech rules speak the row, it is given just the MathML for the row, so the row # will always be '1' + - x: "count(../preceding-sibling::*)+1" + - pause: medium + - set_variables: [NavNode: "../@id"] + +- name: zoom-out + # a row around a single element -- these might duplicate the position/offset, so we jump an extra level here + tag: "*" + match: "$NavCommand = 'ZoomOut'" + replace: + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: + - test: + if: "$MatchCounter = 1 and $NavVerbosity = 'Verbose'" + then: [T: "afastar", pause: "medium"] + - test: + if: "$NavMode='Enhanced' and parent::*[self::m:mrow and IsBracketed(., '(', ')', false) or IsBracketed(., '[', ']', false)]" + then: [x: ".."] # auto-zoom: move out a level and retry + else: + - with: + variables: [Move2D: "'fora de'", Child2D: "."] + replace: [x: ".."] + - test: + if: "parent::m:mtd" + then: [x: ".."] + else: + - test: + if: "$ReadZoomLevel!=-1" + then: [set_variables: [ReadZoomLevel: "DistanceFromLeaf(.., true, $NavMode!='Character')"]] + - set_variables: [NavNode: "../@id"] + +# ********* MoveStart/End *************** +- name: math-move-to-start-or-end + tag: math + match: "$NavCommand = 'MoveStart' or $NavCommand = 'MoveLineStart' or $NavCommand = 'MoveEnd' or $NavCommand = 'MoveLineEnd'" + replace: + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MoveStart'" + then: [T: "início da expressão"] + - else_if: "$NavCommand = 'MoveLineStart'" + then: [T: "mover para o início da linha"] + - else_if: "$NavCommand = 'MoveEnd'" + then: [T: "fim da expressão"] + else: [T: "mover para o fim da linha"] # "$NavCommand = 'MoveLineEnd'" + - pause: "medium" + - test: + if: "$NavCommand = 'MoveStart' or $NavCommand = 'MoveLineStart'" + then: + # move inside of the mrow inside of 'math' or inside the fraction, etc (hence two levels down) + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "*[1]/*[1]"] + else: + - with: + variables: [NavCommand: "'MovePreviousZoom'"] + replace: [x: "*[last()]/*[last()]"] + +# We stop when the parent is 2d (e.g., frac), but not if in leaf base of msub/msup/msubsup/mmultiscripts because that's really on the same line +- name: move-to-start-or-end-2d + tag: "*" + match: + - "($NavCommand = 'MoveLineStart' or $NavCommand = 'MoveLineEnd') and IsNode(.., '2D') and" + - "not( IsNode(., 'leaf') and (parent::m:msub or parent::m:msup or parent::m:msubsup or parent::m:mmultiscripts) )" + replace: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - test: + if: "$NavCommand = 'MoveLineStart'" + then: [T: "mover para o início da linha"] + else: [T: "mover para o fim da linha"] # "$NavCommand = 'MoveLineEnd'" + - pause: "medium" + - test: + if: "self::m:mrow" + then_test: + if: "$NavCommand = 'MoveLineStart'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "*[1]"] + else: + - with: + variables: [NavCommand: "'MovePreviousZoom'"] + replace: [x: "*[last()]"] + else: [set_variables: [NavNode: "@id"]] + +- name: move-to-start-or-end-default + tag: "*" + match: "$NavCommand = 'MoveStart' or $NavCommand = 'MoveLineStart' or $NavCommand = 'MoveEnd' or $NavCommand = 'MoveLineEnd'" + replace: + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: ".."] + +# Table-related movement +# Typically, we need to zoom out to the mtd level, then we move the appropriate direction +- name: not-in-table + + + tag: math + match: + - "$NavCommand='MoveCellPrevious' or $NavCommand='MoveCellNext' or" + - "$NavCommand='MoveCellUp' or $NavCommand='MoveCellDown' or" + - "$NavCommand='MoveColumnStart' or $NavCommand='MoveColumnEnd' or" + - "$NavCommand='ReadCellCurrent'" + replace: + - T: "fora da tabela" + - pause: long + - set_variables: [SpeakExpression: false()] + +- name: move-cell-previous + tag: mtd + match: "$NavCommand='MoveCellPrevious'" + replace: + - test: + if: "preceding-sibling::*" + then: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "mover para a esquerda" + - pause: short + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "coluna" + - x: "count(preceding-sibling::*)" + - pause: medium + - test: + if: "$NavMode='Character'" + then: + - with: + variables: [NavCommand: "'MovePreviousZoom'"] + replace: [x: "preceding-sibling::*[1]"] + else: + - set_variables: [NavNode: "preceding-sibling::*[1]/*[1]/@id"] + else: + - T: "não há coluna anterior" + - set_variables: [SpeakExpression: false()] + +- name: move-cell-next + tag: mtd + match: "$NavCommand='MoveCellNext'" + replace: + - test: + if: "following-sibling::*" + then: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "mover para a direita" + - pause: short + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "coluna" + - x: "count(preceding-sibling::*)+2" + - pause: medium + - test: + if: "$NavMode='Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "following-sibling::*[1]"] + else: + - set_variables: [NavNode: "following-sibling::*[1]/*[1]/@id"] + else: + - T: "não há próxima coluna" + - set_variables: [SpeakExpression: false()] + +- name: move-cell-up + tag: mtd + match: "$NavCommand='MoveCellUp'" + replace: + - test: + if: "../preceding-sibling::*" + then: + - with: + variables: [Column: "count(preceding-sibling::*)+1"] # store this because otherwise the value is used in the wrong context below + replace: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "mover para cima" + - pause: short + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "linha" + - x: "count(../preceding-sibling::*)" + - pause: short + - T: "coluna" + - x: "count(preceding-sibling::*)+1" + - pause: medium + - test: + if: "$NavMode='Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "../preceding-sibling::*[1]/*[$Column]"] + else: + - set_variables: [NavNode: "../preceding-sibling::*[1]/*[$Column]/*[1]/@id"] + else: + - T: "não há linha anterior" + - set_variables: [SpeakExpression: false()] + +- name: move-cell-down + tag: mtd + match: "$NavCommand='MoveCellDown'" + replace: + - test: + if: "../following-sibling::*" + then: + - with: + variables: [Column: "count(preceding-sibling::*)+1"] # store this because otherwise the value is used in the wrong context below + replace: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "descer" + - pause: short + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "linha" + - x: "count(../preceding-sibling::*)+2" + - pause: short + - T: "coluna" + - x: "count(preceding-sibling::*)+1" + - pause: medium + - test: + if: "$NavMode='Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "../following-sibling::*[1]/*[$Column]"] + else: + - set_variables: [NavNode: "../following-sibling::*[1]/*[$Column]/*[1]/@id"] + else: + - T: "não há próxima linha" + - set_variables: [SpeakExpression: false()] + +- name: move-cell-up + tag: [mtr, mlabeledtr] + match: "$NavCommand='MoveCellUp'" + replace: + - test: + if: "preceding-sibling::*" + then: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "subir" + - pause: medium + - T: "linha" + - x: "count(preceding-sibling::*)" + - pause: medium + - test: + if: "$NavMode='Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "preceding-sibling::*[1]"] + else: + - set_variables: [NavNode: "preceding-sibling::*[1]/@id"] + else: + - T: "não há linha anterior" + - set_variables: [SpeakExpression: false()] + +- name: move-cell-down + tag: [mtr, mlabeledtr] + match: "$NavCommand='MoveCellDown'" + replace: + - test: + if: "following-sibling::*" + then: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "descer" + - pause: medium + - T: "linha" + - x: "count(preceding-sibling::*)+2" + - pause: medium + - test: + if: "$NavMode='Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "following-sibling::*[1]"] + else: + - set_variables: [NavNode: "following-sibling::*[1]/@id"] + else: + - T: "não há próxima linha" + - set_variables: [SpeakExpression: false()] + +- name: default-read-cell + tag: "*" + match: "$NavCommand='ReadCellCurrent'" + replace: + - with: + variables: [MTD: "ancestor::m:mtd"] + replace: + - test: + if: "$MTD" + then: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "ler a entrada atual" + - pause: medium + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "linha" + - x: "count($MTD[1]/../preceding-sibling::*)+1" + - T: "coluna" + - x: "count($MTD[1]/preceding-sibling::*)+1" + - pause: short + - set_variables: [NavNode: "$MTD[1]/*[1]/@id"] + else: + - T: "fora da tabela" + - pause: long + - set_variables: [SpeakExpression: false()] + +# mtd ? ( $NavCommand='MoveColumnStart' ) +# => MoveColStart { +# ruleRef = name(^^match); +# column = index(match); +# ::StartPosition = ^^match[0][index(match)][0].dfs; +# ::EndPosition = ^^match[0][index(match)][0].offset; +# }; + +# mtd ? ( $NavCommand='MoveColumnEnd' ) +# => MoveColEnd { +# ruleRef = name(^^match); +# column = index(match); +# ::StartPosition = ^^match[count(^^match)-1][index(match)][0].dfs; +# ::EndPosition = ^^match[count(^^match)-1][index(match)][0].offset; +# }; + + + +# # Rules for columnar math (mstack and mlongdiv) -- each row is an msrow or mscarries except for the start of mlongdiv +# # FIX: not dealing with different number of digits on different lines +# # FIX: not dealing with + (etc) on same line if they are on the right side (Dutch, others) +# # FIX: not dealing with intervening msline (say it and move on??) +# # FIX: not dealing with carries well +# # FIX: not dealing with navigation of first three children of mlongdiv +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# ($NavCommand="MovePrevious" || $NavCommand='MoveCellPrevious') && has_previous(match) ) +# => MoveCell { +# ruleRef = name(^^match); +# wordRef = "previous"; +# ::StartPosition = previous(match).dfs; +# ::EndPosition = previous(match).offset; +# }; + +# # no previous child -- in first column -- don't move +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# ($NavCommand="MovePrevious" || $NavCommand='MoveCellPrevious' ) ) +# => MoveCell { +# ruleRef = name(^^match); +# wordRef = "previous"; +# childIndex = -1; # key to know what to say for each notation +# ::SpeakAfterMove = false; +# }; + +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# ($NavCommand="MoveNext" || $NavCommand='MoveCellNext') && has_next(match) ) +# => MoveCell { +# ruleRef = name(^^match); +# wordRef = "next"; +# ::StartPosition = next(match).dfs; +# ::EndPosition = next(match).offset; +# }; + +# # no next child -- in first column -- don't move +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# ($NavCommand="MoveNext" || $NavCommand='MoveCellNext' ) ) +# => MoveCell { +# ruleRef = name(^^match); +# wordRef = "next"; +# childIndex = -1; # key to know what to say for each notation +# ::SpeakAfterMove = false; +# }; + +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# $NavCommand='MoveCellUp' && has_previous(^^match) ) +# => MoveCell { +# ruleRef = name(^^match); +# wordRef = "up"; +# ::StartPosition = ^^^match[index(^^match)-1][-1][index(match)-count(^match)].dfs; +# ::EndPosition = ^^^match[index(^^match)-1][-1][index(match)-count(^match)].offset; +# }; + +# # no previous child -- in first column -- don't move +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# $NavCommand='MoveCellUp' ) +# => MoveCell { +# ruleRef = name(^^match); +# wordRef = "up"; +# childIndex = -1; # key to know what to say for each notation +# ::SpeakAfterMove = false; +# }; + +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# $NavCommand='MoveCellDown' && has_next(^^match) ) +# => MoveCell { +# ruleRef = name(^^match); +# wordRef = "down"; +# ::StartPosition = ^^^match[index(^^match)+1][-1][index(match)-count(^match)].dfs; +# ::EndPosition = ^^^match[index(^^match)+1][-1][index(match)-count(^match)].offset; +# }; + +# # no previous child -- in first column -- don't move +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# $NavCommand='MoveCellDown' ) +# => MoveCell { +# ruleRef = name(^^match); +# wordRef = "down"; +# childIndex = -1; # key to know what to say for each notation +# ::SpeakAfterMove = false; +# }; + +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# $NavCommand='MoveColumnStart' ) +# => MoveColStart { +# ruleRef = name(^^match); +# column = index(match); +# ::StartPosition = ^^^match[0][-1][index(match)-count(^match)].dfs; +# ::EndPosition = ^^^match[0][-1][index(match)-count(^match)].offset; +# }; + +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# $NavCommand='MoveColumnEnd' ) +# => MoveColEnd { +# ruleRef = name(^^match); +# column = index(match); +# ::StartPosition = ^^^match[count(^^^match)-1][-1][index(match)-count(^match)].dfs; +# ::EndPosition = ^^^match[count(^^^match)-1][-1][index(match)-count(^match)].offset; +# }; + +# any ? ( (name(match)=="mn" || name(match)=="none") && +# has_parent(match) && name(^match)=="mscarries" && +# ($NavCommand="MovePrevious" || $NavCommand='MoveCellPrevious') && has_previous(match) ) +# => MoveCell { +# ruleRef = name(^match); +# wordRef = "previous"; +# ::StartPosition = previous(match).dfs; +# ::EndPosition = previous(match).offset; +# }; + +# # no previous child -- in first column -- don't move +# any ? ( (name(match)=="mn" || name(match)=="none") && +# has_parent(match) && name(^match)=="mscarries" && +# ($NavCommand="MovePrevious" || $NavCommand='MoveCellPrevious') ) +# => MoveCell { +# ruleRef = name(^match); +# wordRef = "previous"; +# childIndex = -1; # key to know what to say for each notation +# ::SpeakAfterMove = false; +# }; + +# any ? ( (name(match)=="mn" || name(match)=="none") && +# has_parent(match) && name(^match)=="mscarries" && +# ($NavCommand="MoveNext" || $NavCommand='MoveCellNext') && has_next(match) ) +# => MoveCell { +# ruleRef = name(^match); +# wordRef = "next"; +# ::StartPosition = next(match).dfs; +# ::EndPosition = next(match).offset; +# }; + +# # no next child -- in last column -- don't move +# any ? ( (name(match)=="mn" || name(match)=="none") && +# has_parent(match) && name(^match)=="mscarries" && +# ($NavCommand="MoveNext" || $NavCommand='MoveCellNext') ) +# => MoveCell { +# ruleRef = name(^match); +# wordRef = "next"; +# childIndex = -1; # key to know what to say for each notation +# ::SpeakAfterMove = false; +# }; + +# any ? ( (name(match)=="mn" || name(match)=="none") && +# has_parent(match) && name(^match)=="mscarries" && +# $NavCommand='MoveCellUp' && has_previous(^match) ) +# => MoveCell { +# ruleRef = name(^match); +# wordRef = "up"; +# ::StartPosition = ^^match[index(^match)-1][index(match)-count(^match)].dfs; +# ::EndPosition = ^^match[index(^match)-1][index(match)-count(^match)].offset; +# }; + +# # no previous child -- in first row -- don't move +# any ? ( (name(match)=="mn" || name(match)=="none") && +# has_parent(match) && name(^match)=="mscarries" && +# $NavCommand='MoveCellUp' ) +# => MoveCell { +# ruleRef = name(^match); +# wordRef = "up"; +# childIndex = -1; # key to know what to say for each notation +# ::SpeakAfterMove = false; +# }; + +# any ? ( (name(match)=="mn" || name(match)=="none") && +# has_parent(match) && name(^match)=="mscarries" && +# $NavCommand='MoveCellDown' && has_next(^match) ) +# => MoveCell { +# ruleRef = name(^match); +# wordRef = "down"; +# ::StartPosition = ^^match[index(^match)+1][-1][index(match)-count(^match)].dfs; +# ::EndPosition = ^^match[index(^match)+1][-1][index(match)-count(^match)].offset; +# }; + +# # no next child -- in last row -- don't move +# any ? ( (name(match)=="mn" || name(match)=="none") && +# has_parent(match) && name(^match)=="mscarries" && +# $NavCommand='MoveCellDown' ) +# => MoveCell { +# ruleRef = name(^match); +# wordRef = "down"; +# childIndex = -1; # key to know what to say for each notation +# ::SpeakAfterMove = false; +# }; + +# mn ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# $NavCommand='MoveColumnStart' ) +# => MoveColStart { +# ruleRef = name(^^match); +# column = index(match); +# ::StartPosition = ^^^match[0][-1][index(match)-count(^match)].dfs; +# ::EndPosition = ^^^match[0][-1][index(match)-count(^match)].offset; +# }; + +# mn ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# $NavCommand='MoveColumnEnd' ) +# => MoveColEnd { +# ruleRef = name(^^match); +# column = index(match); +# ::StartPosition = ^^^match[count(^^^match)-1][-1][index(match)-count(^match)].dfs; +# ::EndPosition = ^^^match[count(^^^match)-1][-1][index(match)-count(^match)].offset; +# }; + + + +- name: default-cell-move + + tag: "*" + match: + - "$NavCommand='MoveCellPrevious' or $NavCommand='MoveCellNext' or" + - "$NavCommand='MoveCellUp' or $NavCommand='MoveCellDown' or" + - "$NavCommand='MoveColumnStart' or $NavCommand='MoveColumnEnd' or" + - "$NavCommand='ReadCellCurrent'" + replace: + - test: + if: "ancestor::m:mtd" + then: + - x: "ancestor::m:mtd[1]" # try again on an mtd node + else: + - T: "fora da tabela" + - pause: long + - set_variables: [SpeakExpression: false()] + +# ======== Move/Read/Describe Next rules ================= + +# skip 'none' +- name: move-next-none + tag: [none, mprescripts] + match: + - "($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext' or $NavCommand = 'DescribePrevious' or $NavCommand = 'MoveNextZoom') and" + - "parent::*[1][name(.)='mmultiscripts'] and following-sibling::*" + replace: + - with: + variables: [Following: "following-sibling::*[1]"] + replace: + # two 'none's in a row -- move over and try again; one 'none', zoom in on next + - test: + if: "$Following[name(.)='none']" + then: [x: "$Following"] + else: + - with: + variables: [Move2D: "'em'", Child2D: "$Following"] + replace: [x: ".."] + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "$Following"] + +# skip 'none' +- name: move-previous-none + tag: [none, mprescripts] + match: + - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious' or $NavCommand = 'MovePreviousZoom') and" + - "parent::*[1][name(.)='mmultiscripts'] and preceding-sibling::*" + replace: + - with: + variables: [Preceding: "preceding-sibling::*[1]"] + replace: + # two 'none's in a row -- move over and try again; one 'none', zoom in on preceding + - test: + if: "$Preceding[name(.)='none']" + then: [x: "$Preceding"] + else: + - with: + variables: [Move2D: "'em'", Child2D: "$Preceding"] + replace: [x: ".."] + - with: + variables: [NavCommand: "'MovePreviousZoom'"] + replace: [x: "$Preceding"] + + + +# skip invisible chars except for Enhanced mode when "times" should be read +- name: move-next-invisible + tag: "*" + match: + - "($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext') and" + - "following-sibling::*[1][name(.)='mo' and translate(., '\u2061\u2062\u2063\u2064', '')='']" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: "ir"] + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "direita" + - pause: short + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: + - test: + if: "following-sibling::*[1][.='\u2062' or .='\u2064'] and $NavMode='Enhanced'" # invisible times and plus + then: [set_variables: [NavNode: "following-sibling::*[1]/@id"]] + else: [x: "following-sibling::*[1]"] + +- name: move-next-no-auto-zoom-at-edge + # at edge of 2D and in a mode where moving right isn't an option + tag: "*" + variables: [EdgeNode: "EdgeNode(., 'right', '2D')"] + match: "$NavCommand = 'MoveNext' and $NavMode!='Character' and not($AutoZoomOut) and $EdgeNode/@id!=@id" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse' and $NavCommand = 'MoveNext'" + then: + - T: "não é possível mover para a direita" + - with: + variables: [Move2D: "'fim de'", Child2D: "$EdgeNode/*[last()]"] + replace: [x: "$EdgeNode"] + - pause: long + - set_variables: [SpeakExpression: false()] + +- name: move-next-no-auto-zoom-at-edge-math + # at edge of math -- no where to go (must be after we rule out being at the edge of 2D) because we want to speak that + tag: "*" + match: + - "($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext') and" + - "(self::m:math or name(EdgeNode(., 'right', 'math'))='math')" # at edge of math + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse'" + then: + - T: "não é possível" + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: "mover"] + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "direita, fim da expressão" + - pause: long + - set_variables: [SpeakExpression: false()] + +- name: move-next-auto-zoom-up-one-level + # Last child or in auto-zoom'd in-- move up a level and try again + # Note: we've already checked the for the case where we are at an edge and should not AutoZoomOut + tag: "*" + match: + - "($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext') and" + - "( not(following-sibling::*) or" + - " ( $NavMode='Enhanced' and " + - " count(following-sibling::*)=1 and (IsBracketed(.., '(', ')') or IsBracketed(.., '[', ']'))" + - " )" + - ")" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: "mover"] + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "direita" + - pause: short + - with: + variables: [MatchCounter: "$MatchCounter + 1", NavCommand: "'MoveNext'"] + replace: + - test: + if: "following-sibling::*" + then: + - with: + variables: [Move2D: "'em'", Child2D: "."] + replace: [x: ".."] + else: + - with: + variables: [Move2D: "'fora de'", Child2D: "."] + replace: [x: ".."] + - test: + if: "following-sibling::*" + then: + - x: ".." # move out of parens + else: + - x: ".." + +# At this point, if XXXNext, then we know there is must be a right sibling +- name: move-next-default + tag: mtd + match: "$Move2D = '' and ($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext')" + replace: + - test: + # can't get here with MatchCounter=0, so no need to echo command + if: "following-sibling::*" + then: + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "coluna" + - x: "count(preceding-sibling::*)+2" + - pause: short + - test: + if: "$NavMode = 'Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "following-sibling::*[1]"] + else: [set_variables: [NavNode: "following-sibling::*[1]/*[1]/@id"]] + else: + - x: ".." # try again at the row level + +- name: move-next-default + tag: [mtr, mlabeledtr] + match: "$Move2D = '' and ($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext')" + replace: + - test: + # can't get here with MatchCounter=0, so no need to echo command + if: "following-sibling::*" + then: + - T: "linha" + - x: "count(preceding-sibling::*)+2" + - T: "coluna 1" + - pause: medium + - test: + if: "$NavMode = 'Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "following-sibling::*[1]"] + else: + - set_variables: [NavNode: "following-sibling::*[1]/*[1]/*[1]/@id"] + else: [x: ".."] # try again for after + +- name: move-next-auto-zoom-parens + # auto-zoom into next child if next child is parenthesized expr + tag: "*" + match: + - "($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext') and" + - "$NavMode='Enhanced' and" + - "parent::m:mrow and following-sibling::* and" + - "following-sibling::*[1][self::m:mrow and count(*)=3 and " #exclude empty parens + - " (IsBracketed(., '(', ')') or IsBracketed(., '[', ']'))" + - " ]" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: mover] + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "direita" + - pause: short + - set_variables: [NavNode: "following-sibling::*[1]/*[2]/@id"] + +# normal cases for MoveNext +- name: move-next-locked-zoom-level + # locked zoom level + tag: "*" + match: + - "($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext') and" + - "$ReadZoomLevel>=0" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: mover] + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "direita" + - pause: short + - test: + # if in base (nothing before), we must be moving to a script, so "in" will be said + if: "preceding-sibling::* and following-sibling::*[1][name(.)='none']" + then: + - with: + variables: [Move2D: "'fora de'", Child2D: "."] + replace: [x: ".."] + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: "following-sibling::*[1]"] # skip over 'none' + else: + - with: + variables: [Move2D: "'em'", Child2D: "following-sibling::*[1]"] + replace: [x: ".."] + - with: + variables: [MatchCounter: "$MatchCounter + 1", NavCommand: "'MoveNextZoom'"] + replace: [x: "following-sibling::*[1]"] + +- name: move-next-default + tag: "*" + match: "$NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: mover] + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "direita" + - pause: short + - test: + if: "IsNode(.., '2D')" + then: + - with: + variables: [Move2D: "'em'", Child2D: "following-sibling::*[1]"] + replace: [x: ".."] + - set_variables: [NavNode: "following-sibling::*[1]/@id"] + +# ======== Move/Read/Describe Previous rules ================= + +# skip invisible chars except for Enhanced mode when "times" should be read +- name: move-previous-invisible + tag: "*" + match: + - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious') and" + - "preceding-sibling::*[1][name(.)='mo' and translate(., '\u2061\u2062\u2063\u2064', '')='']" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MovePrevious'" + then: [T: "mover"] + - else_if: "$NavCommand = 'ReadPrevious'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "esquerda" + - pause: short + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: + - test: + if: "preceding-sibling::*[1][.='\u2062' or .='\u2064'] and $NavMode='Enhanced'" # invisible times and plus + then: [set_variables: [NavNode: "preceding-sibling::*[1]/@id"]] + else: [x: "preceding-sibling::*[1]"] + +# two rules for when can't move right +- name: move-previous-no-auto-zoom-at-edge + # at edge of 2D and in a mode where moving right isn't an option + tag: "*" + variables: [EdgeNode: "EdgeNode(., 'left', '2D')"] + match: "$NavCommand = 'MovePrevious' and $NavMode!='Character' and not($AutoZoomOut) and $EdgeNode/@id!=@id" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse' and $NavCommand = 'MovePrevious'" + then: + - T: "não é possível mover para a esquerda" + - with: + variables: [Move2D: "'fim de'", Child2D: "$EdgeNode/*[1]"] + replace: [x: "$EdgeNode"] + - pause: long + +- name: move-previous-no-auto-zoom-at-edge-of-math + # at edge of math -- no where to go (must be after we rule out being at the edge of 2D) because we want to speak that + tag: "*" + match: + - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious') and" + - "(self::m:math or name(EdgeNode(., 'left', 'math'))='math')" + replace: + - T: "início da expressão" + - pause: long + - set_variables: [SpeakExpression: false()] + +- name: move-previous-at-end + + tag: "*" + match: + - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious') and" + - "EdgeNode(., 'left', 'math')/@id!=@id" # at edge of math + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse'" + then: + - T: "não é possível mover para a esquerda, início da expressão" + - pause: long + - set_variables: [SpeakExpression: false()] + +- name: move-previous-auto-zoom-up-one-level + # Last child or in auto-zoom'd in-- move up a level and try again + # Note: we've already checked the for the case where we are at an edge and should not AutoZoomOut + tag: "*" + match: + - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious') and" + - "( not(preceding-sibling::*) or" + - " ( $NavMode='Enhanced' and " + - " count(preceding-sibling::*)=1 and (IsBracketed(.., '(', ')') or IsBracketed(.., '[', ']'))" + - " )" + - ")" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MovePrevious'" + then: [T: "mover"] + - else_if: "$NavCommand = 'ReadPrevious'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "esquerda" + - pause: short + - with: + variables: [MatchCounter: "$MatchCounter + 1", NavCommand: "'MovePrevious'"] + replace: + - test: + if: "preceding-sibling::*" + then: + - with: + variables: [Move2D: "'em'", Child2D: "."] + replace: [x: ".."] + else: + - with: + variables: [Move2D: "'fora de'", Child2D: "."] + replace: [x: ".."] + - test: + if: "preceding-sibling::*" + then: + - x: .. # move out of parens + else: + - x: ".." + +- name: move-previous-auto-zoom-parens + # auto-zoom into next child if next child is parenthesized expr + # auto-zoom into previous child if previous child is parenthesized expr + # Note: there is an asymmetry here from MoveNext because the base of a scripted might have parens for grouping, but not true for the script + tag: "*" + match: + - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious') and" + - "$NavMode='Enhanced' and" + - "preceding-sibling::* and" + - "(parent::m:mrow or parent::m:msub or parent::m:msup or" + - " (count(preceding-sibling::*)=1 and (parent::m:msubsup or parent::m:mmultiscripts))" # make sure moving into base + - ") and" + - "preceding-sibling::*[1][self::m:mrow and count(*)=3 and " #exclude empty parens + - " (IsBracketed(., '(', ')') or IsBracketed(., '[', ']'))" + - " ]" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MovePrevious'" + then: [T: mover] + - else_if: "$NavCommand = 'ReadPrevious'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "esquerda" + - pause: short + - test: + if: "not(parent::m:mrow)" + then: + - with: + variables: [Move2D: "'em'", Child2D: "preceding-sibling::*[1]"] + replace: [x: ".."] + - set_variables: [NavNode: "preceding-sibling::*[1]/*[2]/@id"] + +# normal cases for MovePrevious + +- name: move-previous-default + tag: mtd + match: "$Move2D = '' and ($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious')" + replace: + - test: + # can't get here with MatchCounter=0, so no need to echo command + if: "preceding-sibling::*" + then: + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "coluna" + - x: "count(preceding-sibling::*)" + - pause: short + - test: + if: "$NavMode = 'Character'" + then: + - with: + variables: [NavCommand: "'MovePreviousZoom'"] + replace: [x: "preceding-sibling::*[1]"] + else: [set_variables: [NavNode: "preceding-sibling::*[1]/*[last()]/@id"]] + else: + - x: ".." # try again at the row level + +- name: move-previous-default + tag: [mtr, mlabeledtr] + match: "$Move2D = '' and ($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious')" + replace: + - test: + # can't get here with MatchCounter=0, so no need to echo command + if: "preceding-sibling::*" + then: + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "linha" + - x: "count(preceding-sibling::*)" + - T: "coluna" + - x: "count(*)" + - pause: medium + - test: + if: "$NavMode = 'Character'" + then: + - with: + variables: [NavCommand: "'MovePreviousZoom'"] + replace: [x: "preceding-sibling::*[1]"] + else: + - set_variables: [NavNode: "preceding-sibling::*[1]/*[last()]/*[last()]/@id"] + else: [x: ".."] # try again for after + +- name: move-previous-locked-zoom-level + # locked zoom level + tag: "*" + match: + - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious') and" + - "$ReadZoomLevel>=0" + replace: + - test: + # if moving into base (nothing before), we must be moving to the base, so "in" will be said + if: "count(preceding-sibling::*) > 2 and preceding-sibling::*[1][name(.)='none']" + then: + - with: + variables: [Move2D: "'fora de'", Child2D: "."] + replace: [x: ".."] + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: "preceding-sibling::*[1]"] # skip over 'none' + else: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MovePrevious'" + then: [T: mover] + - else_if: "$NavCommand = 'ReadPrevious'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "esquerda" + - pause: short + - with: + variables: [Move2D: "'em'", Child2D: "preceding-sibling::*[1]"] + replace: [x: ".."] + - with: + variables: [MatchCounter: "$MatchCounter + 1", NavCommand: "'MovePreviousZoom'"] + replace: [x: "preceding-sibling::*[1]"] + +- name: move-previous-default + tag: "*" + match: "$NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MovePrevious'" + then: [T: mover] + - else_if: "$NavCommand = 'ReadPrevious'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "esquerda" + - pause: short + - test: + if: "IsNode(.., '2D')" + then: + - with: + variables: [Move2D: "'em'", Child2D: "preceding-sibling::*[1]"] + replace: [x: ".."] + - set_variables: [NavNode: "preceding-sibling::*[1]/@id"] + +# ********* ReadZoomLevel toggle *************** +# These set ::NavMode + +- name: toggle-mode-up + + + tag: "*" + match: "$NavCommand = 'ToggleZoomLockUp'" + replace: + - test: + - if: "$NavMode = 'Enhanced'" + then: + - T: "caractere" + - set_variables: [NavMode: "'Character'", ReadZoomLevel: "1"] + - else_if: "$NavMode = 'Character'" + then: + - T: "simples" + - set_variables: [NavMode: "'Simple'", ReadZoomLevel: "1"] + - else: + - T: "avançado" + - set_variables: [NavMode: "'Enhanced'", ReadZoomLevel: "-1"] + - T: "modo" + - pause: long + - test: + - if: "$NavMode != 'Enhanced'" # potentially need to zoom to the sibling + then: + - with: + variables: [MatchCounter: "$MatchCounter + 1", NavCommand: "'MoveNextZoom'"] + replace: [x: "."] + +- name: toggle-mode-down + tag: "*" + match: "$NavCommand = 'ToggleZoomLockDown'" + replace: + - test: + - if: "$NavMode = 'Enhanced'" + then: + - T: "simples" + - set_variables: [NavMode: "'Simple'", ReadZoomLevel: "1"] + - else_if: "$NavMode = 'Character'" + then: + - T: "avançado" + - set_variables: [NavMode: "'Enhanced'", ReadZoomLevel: "-1"] + - else: + - T: "caractere" + - set_variables: [NavMode: "'Character'", ReadZoomLevel: "1"] + - T: "modo" + - pause: long + - test: + - if: "$NavMode != 'Enhanced'" # potentially need to zoom to the sibling + then: + - with: + variables: [MatchCounter: "$MatchCounter + 1", NavCommand: "'MoveNextZoom'"] + replace: [x: "."] + +- name: toggle-speech-describe + tag: "*" + match: "$NavCommand = 'ToggleSpeakMode'" + replace: + - test: + if: "$Overview = 'true'" + then: + - T: "falar a expressão após mover" + - set_variables: [Overview: "'false'"] + else: + - T: "resumo da expressão após mover" + - set_variables: [Overview: "'true'"] + - pause: long + +- name: current + tag: "*" + match: "$NavCommand = 'ReadCurrent' or $NavCommand = 'DescribeCurrent'" + replace: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'ReadCurrent'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "atual" + - set_variables: [NavNode: "@id"] + - pause: long + +# this needs to be near the end because we only test for 'Describe', "Read", etc., and we don't want to get 'DescribeNext', etc. +- name: placemarker + + tag: "*" + match: + - "starts-with($NavCommand, 'Read') or " + - "starts-with($NavCommand, 'Describe') or " + - "starts-with($NavCommand, 'MoveTo')" + replace: + - test: + if: "$NavVerbosity != 'Terse'" + then: + - test: + - if: "starts-with($NavCommand, 'Read')" + then: [T: "ler"] + - else_if: "starts-with($NavCommand, 'Describe')" + then: [T: "descrever"] + - else_if: "starts-with($NavCommand, 'MoveTo')" + then: [T: "mover para"] + else: [T: "definir"] + - T: "marcador de posição" + - x: "$PlaceMarkerIndex" + - pause: long + - set_variables: [NavNode: "$PlaceMarker"] + +- name: set-placemarker + tag: "*" + match: "starts-with($NavCommand, 'SetPlacemarker')" + replace: + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "inserir marcador de posição" + - x: "$PlaceMarkerIndex" + - pause: long + - set_variables: [NavNode: "@id"] + +# ********* WhereAmI *************** + +# FIX: WhereAmI needs support from the Rust code to loop around and do speech at each iteration. +# Alternatively, it could insert a special token that Rust code does a "replace" on with the speech (e.g. SPEECH_AT{id}) +# or a new command "speak" which takes a node id +- name: where-am-i-start + + + tag: "*" + match: "($NavCommand = 'WhereAmI' or $NavCommand = 'WhereAmIAll') and $MatchCounter = 0" + replace: + - translate: "@id" + - pause: long + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: ".."] + +- name: where-am-i-stop + tag: "*" + match: + - "($NavCommand = 'WhereAmI' or $NavCommand = 'WhereAmIAll') and $MatchCounter > 0 and" + # stopping conditions + - "(self::m:math or " + - " parent::*[self::m:math and (count(*)=1 or (count(*)=2 and *[2][.=',' or .='.' or .=';' or .='?']) ) ] " + - ")" + replace: + - test: + if: "$NavCommand = 'WhereAmI'" + then: + - T: "não há mais nada dentro" + - pause: long + - set_variables: [SpeakExpression: false()] + else: + - T: "interior" + - pause: medium + - set_variables: [NavNode: "@id"] + +- name: where-am-i-middle + tag: "*" + match: "$NavCommand = 'WhereAmI' or $NavCommand = 'WhereAmIAll'" + replace: + - T: "interior" + - pause: medium + - test: + - if: "$NavMode='Enhanced' and parent::*[self::m:mrow and IsBracketed(., '(', ')', false) or IsBracketed(., '[', ']', false)]" + then: [x: ".."] # auto-zoom up + - else_if: "$NavCommand = 'WhereAmI'" + then: [set_variables: [NavNode: "@id"]] + else: + - translate: "@id" + - pause: long + - x: '..' diff --git a/Rules/Languages/pt/overview.yaml b/Rules/Languages/pt/overview.yaml new file mode 100644 index 000000000..f28a44564 --- /dev/null +++ b/Rules/Languages/pt/overview.yaml @@ -0,0 +1,119 @@ +--- +# Provide an overview/outline/description of the math +# MathPlayer just tried to shorten things like "mfrac" by just saying "fraction" +# For mrow, it say up to 5 operands and just say "and n more things" for the rest +# This results in strings of varying length. Given human memory is about 7 words long, +# it would be better to aim for 7 words (maybe aim for a range of 6-10 words). +# Idea: +# Start by generating a terse form of the speech +# At every step when the strings are being joined +# a) if the #words <= 7, return the joined string +# b) otherwise, set verbosity to 'overview' and regenerate the expression and use that +# There is a balance that you want to maximize the info given, so 10 words is likely better then 3. +# That might mean that at the top level, we may want to allow the first few children to expand + + +- name: overview-default + tag: [fraction, mfrac] + match: "." + replace: + - test: + if: "IsNode(*[1], 'simple') and IsNode(*[2], 'simple')" + then: + - x: "*[1]" + - T: "sobre" + - x: "*[2]" + else: + - T: "fração" + +- name: overview-default + tag: [msqrt, "square-root"] # CORREÇÃO: idem + match: "." + replace: + - T: "raiz quadrada" + - test: + if: "IsNode(*[1], 'simple')" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: de] + - x: "*[1]" + +- name: overview-default + tag: [mroot, root] # CORREÇÃO: idem + match: "." + replace: + - test: + if: "*[2][self::m:mn]" + then_test: + - if: "*[2][.='2']" + then: [T: raiz quadrada] + - else_if: "*[2][.='3']" + then: [T: raiz cúbica] + - else_if: "*[2][not(contains(., '.'))]" + then: [T: raiz, T: de índice, x: "*[2]"] + else: + # índice simbólico (ex.: raiz de índice n) — em português a ordem natural + # é "raiz de índice n", diferente do inglês "n-th root". + - T: raiz + - T: de índice + - x: "*[2]" + - test: + if: "IsNode(*[1], 'simple')" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: de] + - x: "*[1]" + +- name: matrix-override + tag: mrow + match: + - "*[2][self::m:mtable] and" + - "(IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|'))" + replace: + # CORREÇÃO: a ordem herdada do inglês ("the 2 by 3 matrix") produzia + # "a 2 por 3 matriz". Em português o substantivo vem antes da dimensão. + - test: + if: "*[1][.='|']" # just need to check the first bracket since we know it must be (, [, or | + then: [T: determinante] + else: [T: matriz] + - x: count(*[2]/*) + - T: por + - x: count(*[2]/*[self::m:mtr][1]/*) + +- name: overview-default + tag: mtable + match: "." + replace: + # CORREÇÃO: mesma inversão de ordem do bloco acima. + - T: "tabela" + - x: count(*[2]/*) + - T: por + - x: count(*[2]/*[self::m:mtr][1]/*) + +- name: short-mrow + tag: mrow + match: "count(*)<6" + replace: + - insert: + nodes: "*" + replace: [pause: auto] + +- name: long-mrow + tag: mrow + match: "." + replace: + - x: "*[1]" + - pause: auto + - x: "*[2]" + - pause: auto + - x: "*[3]" + - pause: auto + - x: "*[4]" + - pause: auto + - x: "*[5]" + - pause: auto + - T: "etc." + +- include: "SimpleSpeak_Rules.yaml" diff --git a/Rules/Languages/pt/unicode-full.yaml b/Rules/Languages/pt/unicode-full.yaml new file mode 100644 index 000000000..21a1e0b71 --- /dev/null +++ b/Rules/Languages/pt/unicode-full.yaml @@ -0,0 +1,3431 @@ + + - "˘": [T: "breve"] # 0x2d8 + - "˚": [T: "anel acima"] # 0x2da + - "˛": [T: "ogonek"] # 0x2db + - "˜": [T: "til pequeno"] # 0x2dc + - "˝": [T: "acento agudo duplo"] # 0x2dd + - "↔": [T: "seta para a esquerda e para a direita"] # 0x2194 + - "↕": [T: "seta para cima e para baixo"] # 0x2195 + - "↖": [T: "seta para noroeste"] # 0x2196 + - "↙": [T: "seta para sudoeste"] # 0x2199 + - "↚": [T: "seta para a esquerda com traço"] # 0x219a + - "↛": [T: "seta para a direita com traço"] # 0x219b + - "↜": [T: "seta ondulada para a esquerda"] # 0x219c + - "↝": [T: "seta ondulada para a direita"] # 0x219d + - "↞": [T: "seta de duas pontas para a esquerda"] # 0x219e + - "↟": [T: "seta de duas pontas para cima"] # 0x219f + - "↠": [T: "seta de duas pontas para a direita"] # 0x21a0 + - "↡": [T: "seta de duas pontas para baixo"] # 0x21a1 + - "↢": [T: "seta para a esquerda com cauda"] # 0x21a2 + - "↣": [T: "seta para a direita com cauda"] # 0x21a3 + - "↤": [T: "seta para a esquerda a partir de barra"] # 0x21a4 + - "↥": [T: "seta para cima a partir de barra"] # 0x21a5 + - "↦": [T: "seta para a direita a partir de barra"] # 0x21a6 + - "↧": [T: "seta para baixo a partir de barra"] # 0x21a7 + - "↨": [T: "seta para cima e para baixo com base"] # 0x21a8 + - "↩": [T: "seta para a esquerda com gancho"] # 0x21a9 + - "↪": [T: "seta para a direita com gancho"] # 0x21aa + - "↫": [T: "seta para a esquerda com laço"] # 0x21ab + - "↬": [T: "seta para a direita com laço"] # 0x21ac + - "↭": [T: "seta ondulada para a esquerda e para a direita"] # 0x21ad + - "↮": [T: "seta para a esquerda e para a direita com traço"] # 0x21ae + - "↯": [T: "seta em zigue-zague para baixo"] # 0x21af + - "↰": [T: "seta para cima com ponta para a esquerda"] # 0x21b0 + - "↱": [T: "seta para cima com ponta para a direita"] # 0x21b1 + - "↲": [T: "seta para baixo com ponta para a esquerda"] # 0x21b2 + - "↳": [T: "seta para baixo com ponta para a direita"] # 0x21b3 + - "↴": [T: "seta para a direita com canto para baixo"] # 0x21b4 + - "↵": [T: "seta para baixo com canto para a esquerda"] # 0x21b5 + - "↶": [T: "seta semicircular superior no sentido anti-horário"] # 0x21b6 + - "↷": [T: "seta semicircular superior no sentido horário"] # 0x21b7 + - "↸": [T: "seta para noroeste até barra longa"] # 0x21b8 + - "↹": [T: "seta para a esquerda até barra sobre seta para a direita até barra"] # 0x21b9 + - "↺": [T: "seta circular aberta no sentido anti-horário"] # 0x21ba + - "↻": [T: "seta circular aberta no sentido horário"] # 0x21bb + - "↼": [T: "arpão para a esquerda com farpa para cima"] # 0x21bc + - "↽": [T: "arpão para a esquerda com farpa para baixo"] # 0x21bd + - "↾": [T: "arpão para cima com farpa para a direita"] # 0x21be + - "↿": [T: "arpão para cima com farpa para a esquerda"] # 0x21bf + - "⇀": [T: "arpão para a direita com farpa para cima"] # 0x21c0 + - "⇁": [T: "arpão para a direita com farpa para baixo"] # 0x21c1 + - "⇂": [T: "arpão para baixo com farpa para a direita"] # 0x21c2 + - "⇃": [T: "arpão para baixo com farpa para a esquerda"] # 0x21c3 + - "⇄": [T: "seta para a direita sobre seta para a esquerda"] # 0x21c4 + - "⇅": [T: "seta para cima à esquerda de seta para baixo"] # 0x21c5 + - "⇆": [T: "seta para a esquerda sobre seta para a direita"] # 0x21c6 + - "⇇": [T: "duas setas para a esquerda"] # 0x21c7 + - "⇈": [T: "duas setas para cima"] # 0x21c8 + - "⇉": [T: "duas setas para a direita"] # 0x21c9 + - "⇊": [T: "duas setas para baixo"] # 0x21ca + - "⇋": [T: "arpão para a esquerda sobre arpão para a direita"] # 0x21cb + - "⇌": [T: "arpão para a direita sobre arpão para a esquerda"] # 0x21cc + - "⇍": [T: "seta dupla para a esquerda com traço"] # 0x21cd + - "⇎": [T: "seta dupla para a esquerda e para a direita com traço"] # 0x21ce + - "⇏": [T: "seta dupla para a direita com traço"] # 0x21cf + - "⇐": [T: "seta dupla para a esquerda"] # 0x21d0 + - "⇑": [T: "seta dupla para cima"] # 0x21d1 + - "⇓": [T: "seta dupla para baixo"] # 0x21d3 + - "⇔": [T: "se e somente se"] # 0x21d4 + - "⇕": [T: "seta dupla para cima e para baixo"] # 0x21d5 + - "⇖": [T: "seta dupla para noroeste"] # 0x21d6 + - "⇗": [T: "seta dupla para nordeste"] # 0x21d7 + - "⇘": [T: "seta dupla para sudeste"] # 0x21d8 + - "⇙": [T: "seta dupla para sudoeste"] # 0x21d9 + - "⇚": [T: "seta tripla para a esquerda"] # 0x21da + - "⇛": [T: "seta tripla para a direita"] # 0x21db + - "⇜": [T: "seta serpenteante para a esquerda"] # 0x21dc + - "⇝": [T: "seta serpenteante para a direita"] # 0x21dd + - "⇞": [T: "seta para cima com traço duplo"] # 0x21de + - "⇟": [T: "seta para baixo com traço duplo"] # 0x21df + - "⇠": [T: "seta tracejada para a esquerda"] # 0x21e0 + - "⇡": [T: "seta tracejada para cima"] # 0x21e1 + - "⇢": [T: "seta tracejada para a direita"] # 0x21e2 + - "⇣": [T: "seta tracejada para baixo"] # 0x21e3 + - "⇤": [T: "seta para a esquerda até barra"] # 0x21e4 + - "⇥": [T: "seta para a direita até barra"] # 0x21e5 + - "⇦": [T: "seta vazada para a esquerda"] # 0x21e6 + - "⇧": [T: "seta vazada para cima"] # 0x21e7 + - "⇨": [T: "seta vazada para a direita"] # 0x21e8 + - "⇩": [T: "seta vazada para baixo"] # 0x21e9 + - "⇪": [T: "seta vazada para cima a partir de barra"] # 0x21ea + - "⇫": [T: "seta vazada para cima sobre pedestal"] # 0x21eb + - "⇬": [T: "seta vazada para cima sobre pedestal com barra horizontal"] # 0x21ec + - "⇭": [T: "seta vazada para cima sobre pedestal com barra vertical"] # 0x21ed + - "⇮": [T: "seta vazada dupla para cima"] # 0x21ee + - "⇯": [T: "seta vazada dupla para cima sobre pedestal"] # 0x21ef + - "⇰": [T: "seta vazada para a direita a partir de parede"] # 0x21f0 + - "⇱": [T: "seta para noroeste até o canto"] # 0x21f1 + - "⇲": [T: "seta para sudeste até o canto"] # 0x21f2 + - "⇳": [T: "seta vazada para cima e para baixo"] # 0x21f3 + - "⇴": [T: "seta para a direita com círculo pequeno"] # 0x21f4 + - "⇵": [T: "seta para baixo à esquerda de seta para cima"] # 0x21f5 + - "⇶": [T: "três setas para a direita"] # 0x21f6 + - "⇷": [T: "seta para a esquerda com traço vertical"] # 0x21f7 + - "⇸": [T: "seta para a direita com traço vertical"] # 0x21f8 + - "⇹": [T: "seta para a esquerda e para a direita com traço vertical"] # 0x21f9 + - "⇺": [T: "seta para a esquerda com traço vertical duplo"] # 0x21fa + - "⇻": [T: "seta para a direita com traço vertical duplo"] # 0x21fb + - "⇼": [T: "seta para a esquerda e para a direita com traço vertical duplo"] # 0x21fc + - "⇽": [T: "seta de ponta aberta para a esquerda"] # 0x21fd + - "⇾": [T: "seta de ponta aberta para a direita"] # 0x21fe + - "⇿": [T: "seta vazada para a esquerda e para a direita"] # 0x21ff + - "∀": [T: "para todo"] # 0x2200 + - "∁": # 0x2201 + - test: + if: "$Verbosity!='Terse'" + then: [OT: "o"] + - T: "complemento de" + - "∃": [T: "existe"] # 0x2203 + - "∄": [T: "não existe"] # 0x2204 + - "∅": [T: "conjunto vazio"] # 0x2205 + - "∇": [T: "nabla"] # 0x2207 + - "∋": [T: "contém o elemento"] # 0x220b + - "∌": [T: "não contém o elemento"] # 0x220c + - "∍": [T: "contém o elemento"] # 0x220d + - "∎": [T: "fim da demonstração"] # 0x220e + - "∏": [T: "produtório"] # 0x220f + - "∑": [T: "somatório"] # 0x2211 + - "−": [T: "menos"] # 0x2212 + - "∓": [T: "menos ou mais"] # 0x2213 + - "∔": [T: "mais com ponto"] # 0x2214 + - "∕": [T: "dividido por"] # 0x2215 + - "∖": [T: "diferença de conjuntos"] # 0x2216 + - "∗": [T: "vezes"] # 0x2217 + - "∙": # 0x2219 + - test: + if: "@data-chem-formula-op" + then: [T: "ponto"] + else: [T: "vezes"] + - "∛": # 0x221b + - test: + if: "$Verbosity!='Terse'" + then: [OT: "a"] + - T: "raiz cúbica de" + - "∜": # 0x221c + - test: + if: "$Verbosity!='Terse'" + then: [OT: "a"] + - T: "raiz quarta de" + - "∞": [T: "infinito"] # 0x221e + - "∟": [T: "ângulo reto"] # 0x221f + - "∠": [T: "ângulo"] # 0x2220 + - "∡": [T: "ângulo medido"] # 0x2221 + - "∢": [T: "ângulo esférico"] # 0x2222 + - "∧": [T: "e"] # 0x2227 + - "∨": [T: "ou"] # 0x2228 + - "∩": [T: "interseção"] # 0x2229 + - "∪": [T: "união"] # 0x222a + - "∫": [T: "integral"] # 0x222b + - "∬": [T: "integral dupla"] # 0x222c + - "∭": [T: "integral tripla"] # 0x222d + - "∮": [T: "integral de contorno"] # 0x222e + - "∯": [T: "integral de superfície"] # 0x222f + - "∰": [T: "integral de volume"] # 0x2230 + - "∱": [T: "integral no sentido horário"] # 0x2231 + - "∲": [T: "integral de contorno no sentido horário"] # 0x2232 + - "∳": [T: "integral de contorno no sentido anti-horário"] # 0x2233 + - "∴": [T: "portanto"] # 0x2234 + - "∵": [T: "porque"] # 0x2235 + - "∸": [T: "menos com ponto"] # 0x2238 + - "∹": [T: "tem excesso em relação a"] # 0x2239 + - "∺": # 0x223a + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "geometricamente proporcional a" + - "∻": # 0x223b + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "homotético a" + - "≀": [T: "produto coroa"] # 0x2240 + - "≁": [T: "não é semelhante a"] # 0x2241 + - "≂": [T: "menos til"] # 0x2242 + - "≃": # 0x2243 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "assintoticamente igual a" + - "≄": # 0x2244 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é assintoticamente igual a" + - "≅": # 0x2245 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "congruente a" + - "≆": # 0x2246 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "aproximadamente mas não realmente igual a" + - "≇": # 0x2247 + + - T: "não é congruente a" + - "≈": # 0x2248 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "aproximadamente igual a" + - "≉": # 0x2249 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é aproximadamente igual a" + - "≊": # 0x224a + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "aproximadamente igual ou igual a" + - "≋": [T: "til triplo"] # 0x224b + - "≌": [T: "são todos iguais a"] # 0x224c + - "≍": # 0x224d + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "equivalente a" + - "≎": # 0x224e + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "geometricamente equivalente a" + - "≏": # 0x224f + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "a diferença entre" + - "≐": [T: "aproxima-se do limite"] # 0x2250 + - "≑": # 0x2251 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "geometricamente igual a" + - "≒": # 0x2252 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "aproximadamente igual ou a imagem de" + - "≓": # 0x2253 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "a imagem de ou aproximadamente igual a" + - "≔": [T: "dois pontos igual"] # 0x2254 + - "≕": [T: "igual dois pontos"] # 0x2255 + - "≖": [T: "igual com anel"] # 0x2256 + - "≗": # 0x2257 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "igual por definição a" + - "≘": [T: "corresponde a"] # 0x2258 + - "≙": [T: "estima"] # 0x2259 + - "≚": # 0x225a + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "equiangular a" # era "igual e inclinado a" (descrição do glifo); en: 'is equiangular to' + - "≛": [T: "igual com estrela"] # 0x225b + - "≜": [T: "igual delta"] # 0x225c + - "≝": [T: "é definido como"] # 0x225d + - "≞": # 0x225e + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "medido por" # era "igual por medida a" (descrição); en: 'is measured by' + - "≟": [T: "tem relação desconhecida com"] # 0x225f + - "≢": # 0x2262 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é idêntico a" + - "≣": # 0x2263 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "estritamente equivalente a" + - "≨": # 0x2268 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "menor que mas não igual a" + - "≩": # 0x2269 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "maior que mas não igual a" + - "≬": # 0x226c + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "entre" + - "≭": # 0x226d + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é equivalente a" + - "≮": # 0x226e + # audit-ignore: em português a negação já é frase completa; o "é" do + # inglês (is not less than) não tem par que valha suprimir no Terse + - T: "não é menor que" + - "≯": # 0x226f + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é maior que" + - "≰": # 0x2270 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é menor nem igual a" + - "≱": # 0x2271 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é maior nem igual a" + - "≲": # 0x2272 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "menor ou equivalente a" + - "≳": # 0x2273 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "maior ou equivalente a" + - "≴": # 0x2274 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é menor nem equivalente a" + - "≵": # 0x2275 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é maior nem equivalente a" + - "≶": # 0x2276 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "menor ou maior que" + - "≷": # 0x2277 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "maior ou menor que" + - "≸": # 0x2278 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "nem menor nem maior que" + - "≹": # 0x2279 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "nem maior nem menor que" + - "≺": [T: "precede"] # 0x227a + - "≻": [T: "sucede"] # 0x227b + - "≼": [T: "precede ou é igual a"] # 0x227c + - "≽": [T: "sucede ou é igual a"] # 0x227d + - "≾": [T: "precede ou é equivalente a"] # 0x227e + - "≿": [T: "sucede ou é equivalente a"] # 0x227f + - "⊀": [T: "não precede"] # 0x2280 + - "⊁": [T: "não sucede"] # 0x2281 + - "⊈": # 0x2288 + # audit-ignore: negação já é frase completa; com o ramo "é" saía + # "é não está contido em nem é igual a". Igual a ≢, ≇ e ∦. + - T: "não está contido em nem é igual a" + - "⊉": # 0x2289 + # audit-ignore: idem ⊈ — saía "é não contém nem é igual a". + - T: "não contém nem é igual a" + - "⊊": [T: "está contido em mas não é igual a"] # 0x228a + - "⊋": [T: "contém mas não é igual a"] # 0x228b + - "⊌": [T: "multiconjunto"] # 0x228c + - "⊍": [T: "multiplicação de multiconjunto"] # 0x228d + - "⊎": [T: "união de multiconjunto"] # 0x228e + - "⊏": [T: "imagem quadrada de"] # 0x228f + - "⊐": [T: "original quadrado de"] # 0x2290 + - "⊑": [T: "imagem quadrada de ou igual a"] # 0x2291 + - "⊒": [T: "original quadrado de ou igual a"] # 0x2292 + - "⊓": [T: "interseção quadrada"] # 0x2293 + - "⊔": [T: "união quadrada"] # 0x2294 + - "⊕": [T: "mais circulado"] # 0x2295 + - "⊖": [T: "menos circulado"] # 0x2296 + - "⊗": [T: "vezes circulado"] # 0x2297 + - "⊘": [T: "barra circulada"] # 0x2298 + - "⊙": [T: "ponto circulado"] # 0x2299 + - "⊚": [T: "anel circulado"] # 0x229a + - "⊛": [T: "asterisco circulado"] # 0x229b + - "⊜": [T: "igual circulado"] # 0x229c + - "⊝": [T: "traço circulado"] # 0x229d + - "⊞": [T: "mais enquadrado"] # 0x229e + - "⊟": [T: "menos enquadrado"] # 0x229f + - "⊠": [T: "vezes enquadrado"] # 0x22a0 + - "⊡": [T: "ponto enquadrado"] # 0x22a1 + - "⊢": [T: "demonstra"] # 0x22a2 + - "⊣": [T: "não produz"] # 0x22a3 + - "⊤": [T: "topo"] # 0x22a4 + - "⊦": [T: "reduz a"] # 0x22a6 + - "⊧": [T: "modela"] # 0x22a7 + - "⊨": # 0x22a8 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "verdadeiro" + - "⊩": [T: "força"] # 0x22a9 + - "⊪": [T: "barra vertical tripla com catraca à direita"] # 0x22aa + - "⊫": [T: "barra vertical dupla com catraca dupla à direita"] # 0x22ab + - "⊬": [T: "não demonstra"] # 0x22ac + - "⊭": # 0x22ad + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é verdadeiro" + - "⊮": [T: "não força"] # 0x22ae + - "⊯": [T: "barra vertical dupla com catraca dupla à direita negada"] # 0x22af + - "⊰": [T: "precede sob relação"] # 0x22b0 + - "⊱": [T: "sucede sob relação"] # 0x22b1 + - "⊲": # 0x22b2 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "subgrupo normal de" + - "⊳": [T: "contém como subgrupo normal"] # 0x22b3 + - "⊴": # 0x22b4 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "subgrupo normal de ou igual a" + - "⊵": [T: "contém como subgrupo normal ou é igual a"] # 0x22b5 + - "⊶": # 0x22b6 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "imagem original" + - "⊷": # 0x22b7 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "imagem" + - "⊸": [T: "multimapa"] # 0x22b8 + - "⊹": [T: "matriz conjugada hermitiana"] # 0x22b9 + - "⊺": [T: "intercala"] # 0x22ba + - "⊻": [T: "ou exclusivo"] # 0x22bb + - "⊼": [T: "não-e"] # 0x22bc + - "⊽": [T: "não-ou"] # 0x22bd + - "⊾": [T: "ângulo reto com arco"] # 0x22be + - "⊿": [T: "triângulo retângulo"] # 0x22bf + - "⋀": [T: "e lógico"] # 0x22c0 + - "⋁": [T: "ou lógico"] # 0x22c1 + - "⋂": [T: "interseção"] # 0x22c2 + - "⋃": [T: "união"] # 0x22c3 + - "⋄": [T: "operador losango"] # 0x22c4 + - "⋅": # 0x22c5 + - test: + if: "@data-chem-formula-op" + then: [T: "ponto"] + else: [T: "vezes"] + - "⋆": [T: "vezes"] # 0x22c6 + - "⋇": [T: "divisão vezes"] # 0x22c7 + - "⋈": [T: "junção"] # 0x22c8 + - "⋉": # 0x22c9 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "produto semidireto à esquerda" + - "⋊": # 0x22ca + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "produto semidireto à direita" + - "⋋": # 0x22cb + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "junção semidireta à esquerda" + - "⋌": # 0x22cc + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "junção semidireta à direita" + - "⋍": [T: "til invertido igual"] # 0x22cd + - "⋎": [T: "ou lógico ondulado"] # 0x22ce + - "⋏": [T: "e lógico ondulado"] # 0x22cf + - "⋐": # 0x22d0 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "contido de forma fechada em" + - "⋑": # 0x22d1 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "contém de forma fechada" + - "⋒": # 0x22d2 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "interseção dupla" + - "⋓": # 0x22d3 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "união dupla" + - "⋔": # 0x22d4 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "transversal a" + - "⋕": # 0x22d5 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "igual e paralelo a" # era "paralelo forquilhado a" (descreve a forquilha); en: 'is equal to and parallel to' + - "⋖": [T: "menor que com ponto"] # 0x22d6 + - "⋗": [T: "maior que com ponto"] # 0x22d7 + - "⋘": # 0x22d8 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "muito menor que" + - "⋙": # 0x22d9 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "muito maior que" + - "⋚": # 0x22da + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "menor que, igual ou maior que" + - "⋛": # 0x22db + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "maior que, igual ou menor que" + - "⋜": # 0x22dc + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "igual ou menor que" + - "⋝": # 0x22dd + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "igual ou maior que" + - "⋞": # 0x22de + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "igual ou precede" + - "⋟": # 0x22df + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "igual ou sucede" + - "⋠": [T: "não precede nem é igual a"] # 0x22e0 + - "⋡": [T: "não sucede nem é igual a"] # 0x22e1 + - "⋢": [T: "não é imagem quadrada de nem igual a"] # 0x22e2 + - "⋣": [T: "não é original quadrado de nem igual a"] # 0x22e3 + - "⋤": [T: "imagem quadrada de ou não igual a"] # 0x22e4 + - "⋥": [T: "original quadrado de ou não igual a"] # 0x22e5 + - "⋦": # 0x22e6 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "menor mas não equivalente a" + - "⋧": # 0x22e7 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "maior mas não equivalente a" + - "⋨": [T: "precede mas não é equivalente a"] # 0x22e8 + - "⋩": [T: "sucede mas não é equivalente a"] # 0x22e9 + - "⋪": # 0x22ea + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é subgrupo normal de" + - "⋫": [T: "não contém como subgrupo normal"] # 0x22eb + - "⋬": # 0x22ec + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é subgrupo normal de nem igual a" + - "⋭": [T: "não contém como subgrupo normal nem é igual a"] # 0x22ed + - "⋮": [T: "reticências verticais"] # 0x22ee + - "⋯": [T: "reticências"] # 0x22ef + - "⋰": [T: "reticências diagonais para cima"] # 0x22f0 + - "⋱": [T: "reticências diagonais"] # 0x22f1 + - "⋲": [T: "pertence a com traço horizontal longo"] # 0x22f2 + - "⋳": [T: "pertence a com barra vertical no fim do traço"] # 0x22f3 + - "⋴": [T: "pertence a com barra vertical no fim do traço"] # 0x22f4 + - "⋵": [T: "pertence a com ponto acima"] # 0x22f5 + - "⋶": [T: "pertence a com barra acima"] # 0x22f6 + - "⋷": [T: "pertence a com barra acima"] # 0x22f7 + - "⋸": [T: "pertence a com barra abaixo"] # 0x22f8 + - "⋹": [T: "pertence a com dois traços horizontais"] # 0x22f9 + - "⋺": [T: "contém com traço horizontal longo"] # 0x22fa + - "⋻": [T: "contém com barra vertical no fim do traço"] # 0x22fb + - "⋼": [T: "contém com barra vertical no fim do traço"] # 0x22fc + - "⋽": [T: "contém com barra acima"] # 0x22fd + - "⋾": [T: "contém com barra acima"] # 0x22fe + - "⋿": [T: "pertinência de multiconjunto da notação z"] # 0x22ff + - "■": [T: "quadrado preto"] # 0x25a0 + - "□": [T: "quadrado branco"] # 0x25a1 + - "▢": [T: "quadrado branco de cantos arredondados"] # 0x25a2 + - "▣": [T: "quadrado branco contendo quadrado preto pequeno"] # 0x25a3 + - "▤": [T: "quadrado com preenchimento horizontal"] # 0x25a4 + - "▥": [T: "quadrado com preenchimento vertical"] # 0x25a5 + - "▦": [T: "quadrado com hachura ortogonal"] # 0x25a6 + - "▧": [T: "quadrado com preenchimento diagonal descendente"] # 0x25a7 + - "▨": [T: "quadrado com preenchimento diagonal ascendente"] # 0x25a8 + - "▩": [T: "quadrado com hachura diagonal"] # 0x25a9 + - "▪": [T: "quadrado preto pequeno"] # 0x25aa + - "▫": [T: "quadrado branco pequeno"] # 0x25ab + - "▬": [T: "retângulo preto"] # 0x25ac + - "▭": [T: "retângulo branco"] # 0x25ad + - "▮": [T: "retângulo preto vertical"] # 0x25ae + - "▯": [T: "retângulo branco vertical"] # 0x25af + - "▰": [T: "paralelogramo preto"] # 0x25b0 + - "▱": [T: "paralelogramo branco"] # 0x25b1 + - "▲": [T: "triângulo preto apontando para cima"] # 0x25b2 + - "△": [T: "triângulo"] # 0x25b3 + - "▴": [T: "triângulo preto pequeno apontando para cima"] # 0x25b4 + - "▵": [T: "triângulo branco pequeno apontando para cima"] # 0x25b5 + - "▶": [T: "triângulo preto apontando para a direita"] # 0x25b6 + - "▷": [T: "triângulo branco apontando para a direita"] # 0x25b7 + - "▸": [T: "triângulo preto pequeno apontando para a direita"] # 0x25b8 + - "▹": [T: "triângulo branco pequeno apontando para a direita"] # 0x25b9 + - "►": [T: "ponteiro preto para a direita"] # 0x25ba + - "▻": [T: "ponteiro branco para a direita"] # 0x25bb + - "▼": [T: "triângulo preto apontando para baixo"] # 0x25bc + - "▽": [T: "triângulo branco apontando para baixo"] # 0x25bd + - "▾": [T: "triângulo preto pequeno apontando para baixo"] # 0x25be + - "▿": [T: "triângulo branco pequeno apontando para baixo"] # 0x25bf + - "◀": [T: "triângulo preto apontando para a esquerda"] # 0x25c0 + - "◁": [T: "triângulo branco apontando para a esquerda"] # 0x25c1 + - "◂": [T: "triângulo preto pequeno apontando para a esquerda"] # 0x25c2 + - "◃": [T: "triângulo branco pequeno apontando para a esquerda"] # 0x25c3 + - "◄": [T: "ponteiro preto para a esquerda"] # 0x25c4 + - "◅": [T: "ponteiro branco para a esquerda"] # 0x25c5 + - "◆": [T: "losango preto"] # 0x25c6 + - "◇": [T: "losango branco"] # 0x25c7 + - "◈": [T: "losango branco contendo losango preto pequeno"] # 0x25c8 + - "◉": [T: "olho de peixe"] # 0x25c9 + - "◊": [T: "losango"] # 0x25ca + - "○": [T: "círculo branco"] # 0x25cb + - "◌": [T: "círculo pontilhado"] # 0x25cc + - "◍": [T: "círculo com preenchimento vertical"] # 0x25cd + - "◎": [T: "alvo"] # 0x25ce + - "●": [T: "círculo preto"] # 0x25cf + - "◐": [T: "círculo com metade esquerda preta"] # 0x25d0 + - "◑": [T: "círculo com metade direita preta"] # 0x25d1 + - "◒": [T: "círculo com metade inferior preta"] # 0x25d2 + - "◓": [T: "círculo com metade superior preta"] # 0x25d3 + - "◔": [T: "círculo com quadrante superior direito preto"] # 0x25d4 + - "◕": [T: "círculo preto exceto o quadrante superior esquerdo"] # 0x25d5 + - "◖": [T: "meio círculo preto esquerdo"] # 0x25d6 + - "◗": [T: "meio círculo preto direito"] # 0x25d7 + - "◘": [T: "marcador inverso"] # 0x25d8 + - "◙": [T: "círculo branco inverso"] # 0x25d9 + - "◚": [T: "metade superior de círculo branco inverso"] # 0x25da + - "◛": [T: "metade inferior de círculo branco inverso"] # 0x25db + - "◜": [T: "arco circular do quadrante superior esquerdo"] # 0x25dc + - "◝": [T: "arco circular do quadrante superior direito"] # 0x25dd + - "◞": [T: "arco circular do quadrante inferior direito"] # 0x25de + - "◟": [T: "arco circular do quadrante inferior esquerdo"] # 0x25df + - "◠": [T: "semicírculo superior"] # 0x25e0 + - "◡": [T: "semicírculo inferior"] # 0x25e1 + - "◢": [T: "triângulo preto inferior direito"] # 0x25e2 + - "◣": [T: "triângulo preto inferior esquerdo"] # 0x25e3 + - "◤": [T: "triângulo preto superior esquerdo"] # 0x25e4 + - "◥": [T: "triângulo preto superior direito"] # 0x25e5 + - "◦": [T: "composição"] # 0x25e6 + - "◧": [T: "quadrado com metade esquerda preta"] # 0x25e7 + - "◨": [T: "quadrado com metade direita preta"] # 0x25e8 + - "◩": [T: "quadrado com metade superior esquerda preta"] # 0x25e9 + - "◪": [T: "quadrado com metade inferior direita preta"] # 0x25ea + - "◫": [T: "quadrado branco com linha divisória"] # 0x25eb + - "◬": [T: "triângulo branco apontando para cima com ponto"] # 0x25ec + - "◭": [T: "triângulo apontando para cima com metade esquerda preta"] # 0x25ed + - "◮": [T: "triângulo apontando para cima com metade direita preta"] # 0x25ee + - "◯": [T: "círculo grande"] # 0x25ef + - "◰": [T: "quadrado branco com quadrante superior esquerdo"] # 0x25f0 + - "◱": [T: "quadrado branco com quadrante inferior esquerdo"] # 0x25f1 + - "◲": [T: "quadrado branco com quadrante inferior direito"] # 0x25f2 + - "◳": [T: "quadrado branco com quadrante superior direito"] # 0x25f3 + - "◴": [T: "círculo branco com quadrante superior esquerdo"] # 0x25f4 + - "◵": [T: "círculo branco com quadrante inferior esquerdo"] # 0x25f5 + - "◶": [T: "círculo branco com quadrante inferior direito"] # 0x25f6 + - "◷": [T: "círculo branco com quadrante superior direito"] # 0x25f7 + - "◸": [T: "triângulo superior esquerdo"] # 0x25f8 + - "◹": [T: "triângulo superior direito"] # 0x25f9 + - "◺": [T: "triângulo inferior esquerdo"] # 0x25fa + - "◻": [T: "quadrado branco médio"] # 0x25fb + - "◼": [T: "quadrado preto médio"] # 0x25fc + - "◽": [T: "quadrado branco pequeno médio"] # 0x25fd + - "◾": [T: "quadrado preto pequeno médio"] # 0x25fe + - "◿": [T: "triângulo inferior direito"] # 0x25ff + + +# Ordem das palavras: ao contrário do inglês, que antepõe o estilo +# ("fraktur cap a"), o português pospõe o adjetivo ("maiúscula a vazado"). +# Por isso o `spell:` vem ANTES da palavra de estilo nos blocos de alfabeto. +# Isso segue a expectativa já registrada em tests/Languages/pt/alphabets.rs +# ("maiúscula delta vazado"). + + +# ---- Frações vulgares (0x00bc-0x00be, 0x2150-0x215f) ---- + - "¼": [T: "um quarto"] # 0x00bc + - "½": [T: "um meio"] # 0x00bd + - "¾": [T: "três quartos"] # 0x00be + - "⅐": [T: "um sétimo"] # 0x2150 + - "⅑": [T: "um nono"] # 0x2151 + - "⅒": [T: "um décimo"] # 0x2152 + - "⅓": [T: "um terço"] # 0x2153 + - "⅔": [T: "dois terços"] # 0x2154 + - "⅕": [T: "um quinto"] # 0x2155 + - "⅖": [T: "dois quintos"] # 0x2156 + - "⅗": [T: "três quintos"] # 0x2157 + - "⅘": [T: "quatro quintos"] # 0x2158 + - "⅙": [T: "um sexto"] # 0x2159 + - "⅚": [T: "cinco sextos"] # 0x215a + - "⅛": [T: "um oitavo"] # 0x215b + - "⅜": [T: "três oitavos"] # 0x215c + - "⅝": [T: "cinco oitavos"] # 0x215d + - "⅞": [T: "sete oitavos"] # 0x215e + - "⅟": [T: "um sobre"] # 0x215f + +# ---- Sobrescritos e subscritos (0x2070-0x209f) ---- + - "⁰": [T: "elevado a zero"] # 0x2070 + - "ⁱ": [T: "elevado a i"] # 0x2071 + - "⁴": [T: "elevado à quarta potência"] # 0x2074 + - "⁵": [T: "elevado à quinta potência"] # 0x2075 + - "⁶": [T: "elevado à sexta potência"] # 0x2076 + - "⁷": [T: "elevado à sétima potência"] # 0x2077 + - "⁸": [T: "elevado à oitava potência"] # 0x2078 + - "⁹": [T: "elevado à nona potência"] # 0x2079 + - "⁺": [T: "sinal de mais sobrescrito"] # 0x207a + - "⁻": [T: "menos sobrescrito"] # 0x207b + - "⁼": [T: "sinal de igual sobrescrito"] # 0x207c + - "⁽": [T: "abre parênteses sobrescrito"] # 0x207d + - "⁾": [T: "fecha parênteses sobrescrito"] # 0x207e + - "ⁿ": [T: "elevado à enésima potência"] # 0x207f + - "₀": [T: "subscrito zero"] # 0x2080 + - "₁": [T: "subscrito um"] # 0x2081 + - "₂": [T: "subscrito dois"] # 0x2082 + - "₃": [T: "subscrito três"] # 0x2083 + - "₄": [T: "subscrito quatro"] # 0x2084 + - "₅": [T: "subscrito cinco"] # 0x2085 + - "₆": [T: "subscrito seis"] # 0x2086 + - "₇": [T: "subscrito sete"] # 0x2087 + - "₈": [T: "subscrito oito"] # 0x2088 + - "₉": [T: "subscrito nove"] # 0x2089 + - "₊": [T: "sinal de mais subscrito"] # 0x208a + - "₋": [T: "sinal de menos subscrito"] # 0x208b + - "₌": [T: "sinal de igual subscrito"] # 0x208c + - "₍": [T: "abre parênteses subscrito"] # 0x208d + - "₎": [T: "fecha parênteses subscrito"] # 0x208e + - "ₐ": [T: "subscrito A"] # 0x2090 + - "ₑ": [T: "subscrito E"] # 0x2091 + - "ₒ": [T: "subscrito O"] # 0x2092 + - "ₓ": [T: "subscrito X"] # 0x2093 + - "ₕ": [T: "subscrito H"] # 0x2095 + - "ₖ": [T: "subscrito K"] # 0x2096 + - "ₗ": [T: "subscrito L"] # 0x2097 + - "ₘ": [T: "subscrito M"] # 0x2098 + - "ₙ": [T: "subscrito N"] # 0x2099 + - "ₚ": [T: "subscrito P"] # 0x209a + - "ₛ": [T: "subscrito S"] # 0x209b + - "ₜ": [T: "subscrito T"] # 0x209c + +# ---- Numerais romanos (0x2160-0x217f) ---- + + - "Ⅰ": [T: "um"] # 0x2160 (valor 1) + - "Ⅱ": [T: "dois"] # 0x2161 (valor 2) + - "Ⅲ": [T: "três"] # 0x2162 (valor 3) + - "Ⅳ": [T: "quatro"] # 0x2163 (valor 4) + - "Ⅴ": [T: "cinco"] # 0x2164 (valor 5) + - "Ⅵ": [T: "seis"] # 0x2165 (valor 6) + - "Ⅶ": [T: "sete"] # 0x2166 (valor 7) + - "Ⅷ": [T: "oito"] # 0x2167 (valor 8) + - "Ⅸ": [T: "nove"] # 0x2168 (valor 9) + - "Ⅹ": [T: "dez"] # 0x2169 (valor 10) + - "Ⅺ": [T: "onze"] # 0x216a (valor 11) + - "Ⅻ": [T: "doze"] # 0x216b (valor 12) + - "Ⅼ": [T: "cinquenta"] # 0x216c (valor 50) + - "Ⅽ": [T: "cem"] # 0x216d (valor 100) + - "Ⅾ": [T: "quinhentos"] # 0x216e (valor 500) + - "Ⅿ": [T: "mil"] # 0x216f (valor 1000) + - "ⅰ": [T: "um"] # 0x2170 (valor 1) + - "ⅱ": [T: "dois"] # 0x2171 (valor 2) + - "ⅲ": [T: "três"] # 0x2172 (valor 3) + - "ⅳ": [T: "quatro"] # 0x2173 (valor 4) + - "ⅴ": [T: "cinco"] # 0x2174 (valor 5) + - "ⅵ": [T: "seis"] # 0x2175 (valor 6) + - "ⅶ": [T: "sete"] # 0x2176 (valor 7) + - "ⅷ": [T: "oito"] # 0x2177 (valor 8) + - "ⅸ": [T: "nove"] # 0x2178 (valor 9) + - "ⅹ": [T: "dez"] # 0x2179 (valor 10) + - "ⅺ": [T: "onze"] # 0x217a (valor 11) + - "ⅻ": [T: "doze"] # 0x217b (valor 12) + - "ⅼ": [T: "cinquenta"] # 0x217c (valor 50) + - "ⅽ": [T: "cem"] # 0x217d (valor 100) + - "ⅾ": [T: "quinhentos"] # 0x217e (valor 500) + - "ⅿ": [T: "mil"] # 0x217f (valor 1000) + +# ---- Alfabetos matemáticos: fraktur, vazado (double-struck) e caligráfico ---- +# Símbolos avulsos do bloco "letterlike" (0x2100-0x214f). + + - "ℊ": [T: "g caligráfico"] # 0x210a + - "ℯ": [T: "e caligráfico"] # 0x212f + - "ℴ": [T: "o caligráfico"] # 0x2134 + - "ℼ": [T: "pi vazado"] # 0x213c + - "ℽ": [T: "gama vazado"] # 0x213d + - "⅀": [T: "somatório n-ário vazado"] # 0x2140 + + - "ℌℑℨℭ": # 0x210c, 0x2111, 0x2128, 0x212d + - spell: "translate('.', 'ℌℑℨℭ', 'HIZC')" + - t: "fraktur" + + - "ℍℙℾℿ": # 0x210d, 0x2119, 0x213e, 0x213f + - spell: "translate('.', 'ℍℙℾℿ', 'HPΓΠ')" + - T: "vazado" + + - "ℐℒ℘ℬℰℱℳ": # 0x2110, 0x2112, 0x2118, 0x2130, 0x2131, 0x2133 + - spell: "translate('.', 'ℐℒ℘ℬℰℱℳ', 'ILPBEFM')" + - t: "caligráfico" + +# Blocos alfabéticos do plano 1 e as cópias na área de uso privado do +# MathType. Chaves e argumentos de translate() copiados byte a byte do en. + + - "𝔄-𝔜": # 0x1d504 - 0x1d51d ('z' version is reserved) + - spell: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" + - t: "fraktur" + + - "-": # 0xf000 - 0xf018 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" + - t: "fraktur" + + - "𝔞-𝔷": # 0x1d51e - 0x1d537 + - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" + - t: "fraktur" + + - "-": # 0xf01a - 0xf033 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - t: "fraktur" + + - "𝕬-𝖅": # 0x1D56C - 0x1D585 + - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - t: "fraktur" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + + - "-": # 0xf040 - 0xf059 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - t: "fraktur" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + + - "𝖆-𝖟": # 0x1d586 - 0x1d59f + - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" + - t: "fraktur" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + + - "-": # 0xf05a - 0xf073 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - t: "fraktur" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + + - "𝔸-𝕐": # 0x1d504 - 0x1d51d ('z' version is reserved) + - spell: "translate('.', '𝔸𝔹𝔺𝔻𝔼𝔽𝔾𝔿𝕀𝕁𝕂𝕃𝕄𝕅𝕆𝕇𝕈𝕉𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - T: "vazado" + + - "-": # 0xf080 - 0xf098 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - T: "vazado" + + - "𝕒-𝕫": # 0x1d552 - 0x1d56b + - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" + - T: "vazado" + + - "-": # 0xf09a - 0xf0b3 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - T: "vazado" + + - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 + - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" + - T: "vazado" + + - "-": # 0xf0c0 - 0xf0c9 + - spell: "translate('.', '', '0123456789')" + - T: "vazado" + + - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 + - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - t: "caligráfico" + + - "-": # 0xf100 - 0xf119 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - t: "caligráfico" + + - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf + - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" + - t: "caligráfico" + + - "-": # 0xf11a - 0xf133 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - t: "caligráfico" + + - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 + - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - t: "caligráfico" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + + - "-": # 0xf140 - 0xf159 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - t: "caligráfico" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + + - "𝓪-𝔃": # 0x1d4ea - 0x1d503 + - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" + - t: "caligráfico" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + + - "-": # 0xf15a - 0xf173 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - t: "caligráfico" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + + - "": [T: "nabla vazado"] # 0xf0ca + - "": [T: "constante de Euler vazada"] # 0xf0cb + +# ---- Rodada 9: caracteres que o corpus real (latex2mathml do ACESSÍLIA) mostrou +# saindo CRUS para o sintetizador. Prioridade pelo dano ao estudante, não pelo +# tamanho da lacuna. Ver ACHADOS 9 e TERMINOLOGIA_PT_BR.md. +# +# Letras negrito: \mathbf{x} (vetores em Álgebra Linear) e \boldsymbol{\alpha}. +# Ordem posposta (8.1): "x negrito". Grego negrito passa de novo pela tabela +# e sai com o nome da letra ("alfa negrito"). + - "𝐀-𝐙": # 0x1d400 - 0x1d419 \mathbf maiúsculas + - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - "𝐚-𝐳": # 0x1d41a - 0x1d433 \mathbf minúsculas + - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - "𝑨-𝒁": # 0x1d468 - 0x1d481 negrito itálico maiúsculas (o en também fala só "bold") + - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - "𝒂-𝒛": # 0x1d482 - 0x1d49b negrito itálico minúsculas + - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 grego negrito maiúsculas + - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da grego negrito minúsculas + - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - "𝜜-𝜴": # 0x1d71c - 0x1d734 grego negrito itálico maiúsculas (\boldsymbol) + - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - "𝜶-𝝎": # 0x1d736 - 0x1d74e grego negrito itálico minúsculas (\boldsymbol) + - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + +# Produto interno ⟨u, v⟩ e as setas longas (reações químicas, implicação). + - "⟨": [T: "abre colchete angular"] # 0x27e8 (en: 'left angle bracket') + - "⟩": [T: "fecha colchete angular"] # 0x27e9 + - "⟪": [T: "abre colchete angular duplo"] # 0x27ea + - "⟫": [T: "fecha colchete angular duplo"] # 0x27eb + - "⟵": [T: "seta longa para a esquerda"] # 0x27f5 + - "⟶": [T: "seta longa para a direita"] # 0x27f6 (em química a regra de reação fala "reage formando" antes de chegar aqui) + - "⟷": [T: "seta longa para a esquerda e para a direita"] # 0x27f7 + - "⟸": [T: "seta dupla longa para a esquerda"] # 0x27f8 + - "⟹": [T: "implica"] # 0x27f9 (en: 'implies') + - "⟺": [T: "se e somente se"] # 0x27fa (en: 'if and only if') + +# Barra sobre variável: \bar{x}, \overline{x}. O motor canonicaliza U+0304 e +# U+203E para U+00AF, então a entrada "̄" (com mácron) do unicode.yaml nunca +# era alcançada em . "x barra" é a leitura corrente (média amostral). + - "¯": # 0xaf + - test: + if: "ancestor::m:modified-variable and preceding-sibling::*[1][self::m:mi]" + then: [T: "barra"] # (en: 'bar') + else: [T: "linha superior"] # (en: 'line') + +# Sinais "letterlike" que aparecem soltos (fora de unidade, onde definitions.yaml +# já resolve): a leitura é a da letra, não a do prefixo. + - "µ": [T: "mi"] # 0xb5 MICRO SIGN — como letra; "micro" só dentro de unidade + - "Ω": [T: "ômega"] # 0x2126 OHM SIGN — espaço amostral, etc. + - "℧": [T: "mho"] # 0x2127 + - "Å": [T: "angstrom"] # 0xc5 + - "Å": [T: "angstrom"] # 0x212b + + + - "¤": [T: "símbolo de moeda"] + - "¥": [T: "iene"] + - "¦": [T: "barra quebrada"] + - "§": [T: "seção"] + - "©": [T: "direitos autorais"] + - "ª": [T: "feminino ordinal indicador"] + - "«": [T: "apontando para a esquerda duplo aspas angulares"] + - "²": [T: "dois"] + - "³": [T: "três"] + - "¹": [T: "um"] + - "º": [T: "masculino ordinal indicador"] + - "¡": [T: "ponto invertido de exclamação"] + - "¶": [T: "parágrafo marca"] + - "¿": [T: "ponto invertido de interrogação"] + - "ʰ": [T: "modificador pequeno agá"] + - "ʱ": [T: "modificador pequeno agá com gancho"] + - "ʲ": [T: "modificador pequeno jota"] + - "ʳ": [T: "modificador pequeno erre"] + - "ʴ": [T: "modificador pequeno invertido erre"] + - "ʵ": [T: "modificador pequeno invertido erre com gancho"] + - "ʶ": + - spell: "translate('R', 'R', 'R')" + - T: "modificador pequeno invertido" + - "ʷ": [T: "modificador pequeno w"] + - "ʸ": [T: "modificador pequeno y"] + - "ʹ": [T: "modificador linha"] + - "ʺ": [T: "modificador duplo linha"] + - "ʻ": [T: "modificador invertido vírgula"] + - "ʼ": [T: "modificador apóstrofo"] + - "ʽ": [T: "modificador invertido vírgula"] + - "ʾ": [T: "modificador direita metade anel"] + - "ʿ": [T: "modificador esquerda metade anel"] + - "ˀ": [T: "modificador oclusiva glotal"] + - "ˁ": [T: "modificador invertido oclusiva glotal"] + - "˂": [T: "modificador esquerda ponta de seta"] + - "˃": [T: "modificador direita ponta de seta"] + - "˄": [T: "modificador cima ponta de seta"] + - "˅": [T: "modificador baixo ponta de seta"] + - "ˆ": [T: "modificador circunflexo acento"] + - "ˇ": [T: "cáron"] + - "ˈ": [T: "modificador barra vertical"] + - "ˉ": [T: "modificador mácron"] + - "ˊ": [T: "modificador agudo acento"] + - "ˋ": [T: "modificador grave acento"] + - "ˌ": [T: "modificador baixo barra vertical"] + - "ˍ": [T: "modificador baixo mácron"] + - "ˎ": [T: "modificador baixo grave acento"] + - "ˏ": [T: "modificador baixo agudo acento"] + - "ː": [T: "modificador triangular dois pontos"] + - "ˑ": [T: "modificador metade triangular dois pontos"] + - "˒": [T: "modificador centralizado direita metade anel"] + - "˓": [T: "modificador centralizado esquerda metade anel"] + - "˔": [T: "modificador cima taco"] + - "˕": [T: "modificador baixo taco"] + - "˖": [T: "modificador sinal de mais"] + - "˗": [T: "modificador sinal de menos"] + - "˞": [T: "modificador rótico gancho"] + - "˟": [T: "cruzes modificador acento"] + - "ˠ": [T: "modificador pequeno gama"] + - "ˡ": [T: "modificador pequeno l"] + - "ˢ": [T: "modificador pequeno esse"] + - "ˣ": [T: "modificador pequeno xis"] + - "ˤ": [T: "modificador pequeno invertido oclusiva glotal"] + - "˥": [T: "modificador extra-alto tom barra"] + - "˦": [T: "modificador alto tom barra"] + - "˧": [T: "modificador médio tom barra"] + - "˨": [T: "modificador baixo tom barra"] + - "˩": [T: "modificador extra-baixo tom barra"] + - "˪": [T: "modificador yin partindo tom marca"] + - "˫": [T: "modificador yang partindo tom marca"] + - "ˬ": [T: "modificador sonorização"] + - "˭": [T: "modificador não aspirado"] + - "ˮ": [T: "modificador duplo apóstrofo"] + - "˯": [T: "modificador baixo baixo ponta de seta"] + - "˰": [T: "modificador baixo cima ponta de seta"] + - "˱": [T: "modificador baixo esquerda ponta de seta"] + - "˲": [T: "modificador baixo direita ponta de seta"] + - "˳": [T: "modificador baixo anel"] + - "˴": [T: "modificador do meio grave acento"] + - "˵": [T: "modificador do meio duplo grave acento"] + - "˶": [T: "modificador do meio duplo agudo acento"] + - "˷": [T: "modificador baixo til"] + - "˸": [T: "modificador elevado dois pontos"] + - "˹": [T: "modificador início alto tom"] + - "˺": [T: "modificador fim alto tom"] + - "˻": [T: "modificador início baixo tom"] + - "˼": [T: "modificador fim baixo tom"] + - "˽": [T: "modificador prateleira"] + - "˾": [T: "modificador aberto prateleira"] + - "˿": [T: "seta modificador baixo para a esquerda"] + - "̉": [T: "gancho acima de"] + - "̊": [T: "anel acima de"] + - "̋": [T: "duplo agudo acento"] + - "̍": [T: "barra vertical acima de"] + - "̎": [T: "barra dupla vertical acima de"] + - "̏": [T: "duplo grave acento"] + - "̐": [T: "candrabindu"] + - "̑": [T: "invertido breve"] + - "̒": [T: "invertido vírgula acima de"] + - "̓": [T: "vírgula acima de"] + - "̔": [T: "invertido vírgula acima de"] + - "̕": [T: "vírgula acima de direita"] + - "̖": [T: "grave acento abaixo de"] + - "̗": [T: "agudo acento abaixo de"] + - "̘": [T: "taco abaixo de à esquerda"] + - "̙": [T: "taco abaixo de à direita"] + - "̚": [T: "ângulo acima de à esquerda"] + - "̛": [T: "chifre"] + - "̜": [T: "esquerda metade anel abaixo de"] + - "̝": [T: "taco abaixo de para cima"] + - "̞": [T: "taco abaixo de para baixo"] + - "̟": [T: "sinal de mais abaixo de"] + - "̠": [T: "sinal de menos abaixo de"] + - "̡": [T: "palatalizado gancho abaixo de"] + - "̢": [T: "retroflexo gancho abaixo de"] + - "̣": [T: "ponto abaixo de"] + - "̤": [T: "trema abaixo de"] + - "̥": [T: "anel abaixo de"] + - "̦": [T: "vírgula abaixo de"] + - "̧": [T: "cedilha"] + - "̨": [T: "ogonek"] + - "̩": [T: "barra vertical abaixo de"] + - "̪": [T: "ponte abaixo de"] + - "̫": [T: "arco invertido duplo abaixo de"] + - "̬": [T: "cáron abaixo de"] + - "̭": [T: "circunflexo acento abaixo de"] + - "̮": [T: "breve abaixo de"] + - "̯": [T: "invertido breve abaixo de"] + - "̰": [T: "til abaixo de"] + - "̱": [T: "mácron abaixo de"] + - "̲": [T: "linha baixa"] + - "̳": [T: "linha dupla baixa"] + - "̴": [T: "til sobreposto"] + - "̵": [T: "traço curto sobreposto"] + - "̶": [T: "traço longo sobreposto"] + - "̷": [T: "barra curta sobreposto"] + - "̸": [T: "barra longa sobreposto"] + - "̹": [T: "direita metade anel abaixo de"] + - "̺": [T: "ponte invertida abaixo de"] + - "̻": [T: "quadrado abaixo de"] + - "̼": [T: "gaivota abaixo de"] + - "̽": [T: "xis acima de"] + - "̾": [T: "til vertical"] + - "̿": [T: "linha dupla superior"] + - "̀": [T: "grave tom marca"] + - "́": [T: "agudo tom marca"] + - "͆": [T: "ponte acima de"] + - "ΪΫϏ": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "maiúscula"] + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [spell: "translate('.', 'ΪΫϏ', 'ιυϗ')"] + - T: "com trema" + - "ϊ": [T: "iota com trema"] + - "ϋ": [T: "ípsilon com trema"] + - "ό": [T: "ômicron com tônico"] + - "ύ": [T: "ípsilon com tônico"] + - "ώ": [T: "ômega com tônico"] + - "ϐ": [T: "beta"] + - "ϑ": [T: "teta"] + - "ϒ": [T: "ípsilon com gancho"] + - "ϓ": [T: "ípsilon com agudo e gancho"] + - "ϔ": [T: "ípsilon com trema e gancho"] + - "ϗ": [T: "kai"] + - "Ϙ": [T: "maiúscula arcaico copa"] + - "ϙ": [T: "arcaico copa"] + - "А-Я": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "maiúscula"] + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [spell: "translate('.', 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ', 'абвгдежзийклмнопрстуфхцчшщъыьэюя')"] + - "а": [T: "a"] + - "б": [T: "ser"] + - "в": [T: "vê"] + - "г": [T: "guê"] + - "д": [T: "de"] + - "е": [T: "iê"] + - "ж": [T: "jê"] + - "з": [T: "zê"] + - "и": [T: "i"] + - "й": [T: "curto i"] + - "к": [T: "ka"] + - "л": [T: "ele"] + - "м": [T: "em"] + - "н": [T: "en"] + - "о": [T: "o"] + - "п": [T: "pê"] + - "р": [T: "erre"] + - "с": [T: "esse"] + - "т": [T: "tê"] + - "у": [T: "u"] + - "ф": [T: "efe"] + - "х": [T: "rrá"] + - "ц": [T: "tsê"] + - "ч": [T: "tchê"] + - "ш": [T: "chá"] + - "щ": [T: "chtchá"] + - "ъ": [T: "forte sinal"] + - "ы": [T: "ierí"] + - "ь": [T: "sinal suave"] + - "э": [T: "e"] + - "ю": [T: "iu"] + - "я": [T: "iá"] + - "؆": [T: "arábico-índico raiz cúbica"] + - "؇": [T: "arábico-índico raiz quarta"] + - "؈": [T: "arábico raio"] + - "‐": [T: "hífen"] + - "‑": [T: "hífen"] + - "‒": [T: "algarismo travessão"] + - "―": [T: "barra horizontal"] + - "†": [T: "adaga"] + - "‡": [T: "duplo adaga"] + - " - ": [t: " "] # RECUO-EN + - "•": + - test: + if: "@data-chem-formula-op" + then: [T: "ponto"] + else: [T: "marcador"] + - "‰": [T: "por mil"] + - "‱": [T: "por dez mil"] + - "‸": [T: "a o"] + - "‹": [T: "simples esquerda apontando aspas angulares"] + - "›": [T: "simples direita apontando aspas angulares"] + - "‼": + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [T: "ponto duplo de exclamação"] # 0x203c + else: [T: "duplo fatorial"] # 0x203c + - "⁄": + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [T: "barra grande"] # 0x203c + else: [T: "dividido por"] # 0x203c + - "⁅": [T: "quadrado esquerda colchete com pena"] + - "⁆": [T: "quadrado direita colchete com pena"] + - "※": [T: "marca de referência"] + - "‿": [T: "sob laço"] + - "⁀": [T: "laço"] + - "⁎": [T: "baixo asterisco"] + - "⁏": [T: "ponto invertido e vírgula"] + - "⁐": [T: "fechamento"] + - "⁑": [T: "dois vertical asteriscos"] + - "⁒": [T: "comercial sinal de menos"] + - "⁗": [T: "linha quádrupla"] + - "⁠": [T: ""] + - "₠": [T: "europeia moeda unidades"] + - "₡": [T: "dois pontos"] + - "₢": [T: "cruzeiro"] + - "₣": [T: "franco"] + - "₤": [T: "lira"] + - "₥": [T: "mills"] + - "₦": [T: "naira"] + - "₧": [T: "peseta"] + - "₨": [T: "rupias"] + - "₩": [T: "won"] + - "₪": [T: "novos shequels"] + - "₫": [T: "dong"] + - "€": [T: "euros"] + - "₭": [T: "kip"] + - "₮": [T: "tugrik"] + - "₯": [T: "dracma"] + - "₰": [T: "pfennigs"] + - "₱": [T: "pesos"] + - "₲": [T: "guaranis"] + - "₳": [T: "australes"] + - "₴": [T: "hryvnias"] + - "₵": [T: "cedis"] + - "₶": [T: "livre tournois"] + - "₷": [T: "spesmilos"] + - "₸": [T: "tenges"] + - "₹": [T: "indiano rupias"] + - "₺": [T: "liras turcas"] + - "⃐": [T: "arpão para a esquerda acima de"] + - "⃑": [T: "arpão para a direita acima de"] + - "⃒": [T: "barra longa vertical sobreposto"] + - "⃓": [T: "barra curta vertical sobreposto"] + - "⃔": [T: "seta no sentido anti-horário acima de"] + - "⃕": [T: "seta no sentido horário acima de"] + - "⃖": [T: "seta para a esquerda acima de"] + - "⃗": [T: "seta para a direita acima de"] + - "⃘": [T: "anel sobreposto"] + - "⃙": [T: "no sentido horário anel sobreposto"] + - "⃚": [T: "no sentido anti-horário anel sobreposto"] + - "⃝": [T: "círculo envolvente"] + - "⃞": [T: "quadrado envolvente"] + - "⃟": [T: "losango envolvente"] + - "⃠": [T: "círculo envolvente barra invertida"] + - "⃡": [T: "seta para a esquerda e para a direita acima de"] + - "⃢": [T: "envolvente tela"] + - "⃣": [T: "envolvente tecla"] + - "⃤": [T: "triângulo envolvente para cima apontando"] + - "⃥": [T: "barra invertida sobreposto"] + - "⃦": [T: "traço duplo vertical"] + - "⃧": [T: "anuidade símbolo"] + - "⃨": [T: "ponto triplo abaixo"] + - "⃩": [T: "ponte larga acima de"] + - "⃪": [T: "seta para a esquerda sobreposto"] + - "⃫": [T: "barra longa dupla sobreposto"] + - "⃬": [T: "arpão para a direita com farpa baixo"] + - "⃭": [T: "arpão para a esquerda com farpa baixo"] + - "⃮": [T: "seta para a esquerda abaixo de"] + - "⃯": [T: "seta para a direita abaixo de"] + - "⃰": [T: "asterisco acima de"] + - "℄": [T: "centro linha símbolo"] + - "℅": [T: "aos cuidados de"] + - "℆": [T: "cada uma"] + - "ℇ": [T: "euler'esse constante"] + - "℈": [T: "escrúpulos"] + - "ℏ": [T: "agá barra"] + - "℔": [T: "libras"] + - "№": [T: "número"] + - "℥": [T: "onças"] + - "℩": [T: "invertido iota"] + - "Ⅎ℺⅁⅂⅃⅄": + - test: + - if: "'.' = '℺'" + then: [T: "rotacionado"] + - else_if: "'.' = 'Ⅎ'" + then: [T: "invertido"] + - else_if: "'.' = '⅃'" + then: [T: "invertido sem serifa"] + else: [T: "invertido sem serifa"] + - spell: "translate('.', 'Ⅎ℺⅁⅂⅃⅄', 'FQGLLY')" + - "ℵ": [T: "primeiro transfinito cardinal"] + - "ℶ": [T: "segundo transfinito cardinal"] + - "ℷ": [T: "terceiro transfinito cardinal"] + - "ℸ": [T: "quarto transfinito cardinal"] + - "⅋": [T: "invertido e comercial"] + - "⅌": [T: "por"] + - "ⅎ": [T: "invertido efe"] + - "↉": [T: "zero terços"] + - "⌀": [T: "diâmetro"] + - "⌁": [T: "seta elétrico"] + - "⌂": [T: "casa"] + - "⌃": [T: "ponta de seta para cima"] + - "⌄": [T: "ponta de seta para baixo"] + - "⌅": [T: "projetivo"] + - "⌆": [T: "perspectiva"] + - "⌇": [T: "linha ondulada"] + - "⌈": [T: "abre teto"] + - "⌉": [T: "fecha teto"] + - "⌊": [T: "abre piso"] + - "⌋": [T: "fecha piso"] + - "⌌": [T: "inferior direita corte"] + - "⌍": [T: "inferior esquerda corte"] + - "⌎": [T: "superior direita corte"] + - "⌏": [T: "superior esquerda corte"] + - "⌐": [T: "invertido não sinal"] + - "⌑": [T: "quadrado losango"] + - "⌒": [T: "arco"] + - "⌓": [T: "segmento"] + - "⌔": [T: "setor"] + - "⌕": [T: "telefone gravador"] + - "⌖": [T: "posição indicador mira"] + - "⌗": [T: "quadrado viewdata"] + - "⌘": [T: "lugar de interesse sinal"] + - "⌙": [T: "invertido não sinal"] + - "⌚": [T: "relógio"] + - "⌛": [T: "ampulheta"] + - "⌜": [T: "superior esquerda canto"] + - "⌝": [T: "superior direita canto"] + - "⌞": [T: "inferior esquerda canto"] + - "⌟": [T: "inferior direita canto"] + - "⌠": [T: "superior metade integral"] + - "⌡": [T: "inferior metade integral"] + - "⌢": [T: "carranca"] + - "⌣": [T: "sorriso"] + - "⌤": [T: "ponta de seta entre dois barras horizontales para cima"] + - "⌥": [T: "tecla opção"] + - "⌦": [T: "apagar à direita"] + - "⌧": [T: "retângulo xis em a caixa"] + - "⌨": [T: "teclado"] + - "〈": [T: "abre colchete apontando ângulo"] + - "〉": [T: "fecha colchete apontando ângulo"] + - "⌫": [T: "apagar à esquerda"] + - "⌬": [T: "benzeno anel"] + - "⌭": [T: "cilindricidade"] + - "⌮": [T: "tudo ao redor perfil"] + - "⌯": [T: "simetria"] + - "⌰": [T: "total excentricidade"] + - "⌱": [T: "dimensão origem"] + - "⌲": [T: "cone de afunilamento"] + - "⌳": [T: "inclinação"] + - "⌴": [T: "rebaixo"] + - "⌵": [T: "escareado"] + - "⌶": [T: "viga i do apl"] + - "⌽": [T: "círculo apl montante"] + - "⌿": [T: "barra do apl com barra sobreposta"] + - "⍰": [T: "desconhecido caixa"] + - "⍼": [T: "seta ângulo com baixo em zigue-zague para a direita"] + - "⎔": [T: "hexágono"] + - "⎕": [T: "caixa"] + - "⎶": [T: "quadrado inferior colchete sobre superior quadrado colchete"] + - "⏜": [T: "parêntese superior"] + - "⏝": [T: "parêntese inferior"] + - "⏞": [T: "chave superior"] + - "⏟": [T: "chave inferior"] + - "⏠": [T: "concha superior de tartaruga colchete"] + - "⏡": [T: "concha inferior de tartaruga colchete"] + - "⏢": [T: "trapézio branco"] + - "⏣": [T: "círculo benzeno direita com"] + - "⏤": [T: "retilineidade"] + - "⏥": [T: "planicidade"] + - "⏦": + - spell: "ac" + - T: "corrente" + - "⏧": [T: "interseção elétrica"] + - "①-⑨": + - spell: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" + - T: "circulado" + - "⑩": [T: "dez circulado"] + - "⑪": [T: "onze circulado"] + - "⑫": [T: "doze circulado"] + - "⑬": [T: "treze circulado"] + - "⑭": [T: "quatorze circulado"] + - "⑮": [T: "quinze circulado"] + - "⑯": [T: "dezesseis circulado"] + - "⑰": [T: "dezessete circulado"] + - "⑱": [T: "dezoito circulado"] + - "⑳": [T: "vinte circulado"] + - "⑴-⑼": + - spell: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" + - T: "entre parênteses" + - "⑽": [T: "dez entre parênteses"] + - "⑾": [T: "onze entre parênteses"] + - "⑿": [T: "doze entre parênteses"] + - "⒀": [T: "treze entre parênteses"] + - "⒁": [T: "quatorze entre parênteses"] + - "⒂": [T: "quinze entre parênteses"] + - "⒃": [T: "dezesseis entre parênteses"] + - "⒄": [T: "dezessete entre parênteses"] + - "⒅": [T: "dezoito entre parênteses"] + - "⒆": [T: "dezenove entre parênteses"] + - "⒇": [T: "vinte entre parênteses"] + - "⒈-⒐": + - spell: "translate('.', '⒈⒉⒊⒋⒌⒍⒎⒏⒐', '123456789')" + - T: "com ponto" + - "⒑": [T: "dez com ponto final"] + - "⒒": [T: "onze com ponto final"] + - "⒓": [T: "doze com ponto final"] + - "⒔": [T: "treze com ponto final"] + - "⒕": [T: "quatorze com ponto final"] + - "⒖": [T: "quinze com ponto final"] + - "⒗": [T: "dezesseis com ponto final"] + - "⒘": [T: "dezessete com ponto final"] + - "⒙": [T: "dezoito com ponto final"] + - "⒚": [T: "dezenove com ponto final"] + - "⒛": [T: "vinte com ponto final"] + - "⒜-⒵": + - spell: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" + - T: "entre parênteses" + - "Ⓐ-ⓩ": + - spell: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - T: "circulado" + - "🅐-🅩": + - spell: "translate('.', '🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - T: "circulado preto" + - "ⓐ-ⓩ": + - spell: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" + - T: "circulado" + - "⓪": [T: "zero circulado"] + - "⓫": [T: "onze circulado preto"] + - "⓬": [T: "doze circulado preto"] + - "⓭": [T: "treze circulado preto"] + - "⓮": [T: "quatorze circulado preto"] + - "⓯": [T: "quinze circulado preto"] + - "⓰": [T: "dezesseis circulado preto"] + - "⓱": [T: "dezessete circulado preto"] + - "⓲": [T: "dezoito circulado preto"] + - "⓳": [T: "dezenove circulado preto"] + - "⓴": [T: "vinte circulado preto"] + - "⓵-⓽": + - spell: "translate('.', '⓵⓶⓷⓸⓹⓺⓻⓼⓽', '123456789')" + - T: "duplo circulado" + - "⓾": [T: "dez circulado duas vezes"] + - "⓿": [T: "zero circulado preto"] + - "★": [T: "estrela preta"] + - "☆": [T: "estrela branca"] + - "☉": [T: "sol"] + - "☌": [T: "conjunção"] + - "☒": [T: "cédula caixa com xis"] + - "☽": [T: "crescente lua"] + - "☾": [T: "minguante lua"] + - "☿": [T: "mercúrio"] + - "♀": [T: "feminino"] + - "♁": [T: "terra"] + - "♂": [T: "masculino"] + - "♃": [T: "júpiter"] + - "♄": [T: "saturno"] + - "♅": [T: "urano"] + - "♆": [T: "netuno"] + - "♇": [T: "plutão"] + - "♈": [T: "áries"] + - "♉": [T: "touro"] + - "♩": [T: "um quarto nota"] + - "♭": [T: "bemol"] + - "♮": [T: "natural"] + - "♯": [T: "sustenido"] + - "♠": [T: "preto naipe de espadas"] + - "♡": [T: "branco naipe de copas"] + - "♢": [T: "branco naipe de ouros"] + - "♣": [T: "preto naipe de paus"] + - "♤": [T: "branco naipe de espadas"] + - "♥": [T: "preto naipe de copas"] + - "♦": [T: "preto naipe de ouros"] + - "♧": [T: "branco naipe de paus"] + - "⚀": [T: "face de dado 1"] + - "⚁": [T: "face de dado 2"] + - "⚂": [T: "face de dado 3"] + - "⚃": [T: "face de dado 4"] + - "⚄": [T: "face de dado 5"] + - "⚅": [T: "face de dado 6"] + - "⚆": [T: "círculo branco com ponto direita"] + - "⚇": [T: "círculo branco com dois pontos"] + - "⚈": [T: "círculo preto com ponto direita"] + - "⚉": [T: "círculo preto com dois pontos"] + - "⚪": [T: "círculo médio branco"] + - "⚫": [T: "círculo médio preto"] + - "⚬": [T: "círculo médio pequeno branco"] + - "⚲": [T: "neutro"] + - "✓": [T: "verificação marca"] + - "✠": [T: "cruzes de malta"] + - "✪": [T: "branco estrela circulado"] + - "✶": [T: "estrela seis pontuda preta"] + - "❨": [T: "médio parênteses ornamento à esquerda"] + - "❩": [T: "médio parênteses ornamento à direita"] + - "❪": [T: "médio achatado parênteses ornamento à esquerda"] + - "❫": [T: "médio achatado parênteses ornamento à direita"] + - "❬": [T: "médio apontando para a colchete angular ornamento à esquerda"] + - "❭": [T: "médio apontando para a colchete angular ornamento à direita"] + - "❮": [T: "grosso apontando para a esquerda aspas angulares ornamento"] + - "❯": [T: "grosso apontando para a direita aspas angulares ornamento"] + - "❰": [T: "grosso apontando para a colchete angular ornamento à esquerda"] + - "❱": [T: "grosso apontando para a colchete angular ornamento à direita"] + - "❲": [T: "fino concha de tartaruga colchete ornamento à esquerda"] + - "❳": [T: "fino concha de tartaruga colchete ornamento à direita"] + - "❴": [T: "médio chave ornamento à esquerda"] + - "❵": [T: "médio chave ornamento à direita"] + - "❶": [T: "um circulado preto"] + - "❷": [T: "dois circulado preto"] + - "❸": [T: "três circulado preto"] + - "❹": [T: "quatro circulado preto"] + - "❺": [T: "cinco circulado preto"] + - "❻": [T: "seis circulado preto"] + - "❼": [T: "sete circulado preto"] + - "❽": [T: "oito circulado preto"] + - "❾": [T: "nove circulado preto"] + - "❿": [T: "dez circulado preto"] + - "➀": [T: "um circulado sem serifa"] + - "➁": [T: "dois circulado sem serifa"] + - "➂": [T: "três circulado sem serifa"] + - "➃": [T: "quatro circulado sem serifa"] + - "➄": [T: "cinco circulado sem serifa"] + - "➅": [T: "seis circulado sem serifa"] + - "➆": [T: "sete circulado sem serifa"] + - "➇": [T: "oito circulado sem serifa"] + - "➈": [T: "nove circulado sem serifa"] + - "➉": [T: "dez circulado sem serifa"] + - "➊": [T: "um circulado preto sem serifa"] + - "➋": [T: "dois circulado preto sem serifa"] + - "➌": [T: "três circulado preto sem serifa"] + - "➍": [T: "quatro circulado preto sem serifa"] + - "➎": [T: "cinco circulado preto sem serifa"] + - "➏": [T: "seis circulado preto sem serifa"] + - "➐": [T: "sete circulado preto sem serifa"] + - "➑": [T: "oito circulado preto sem serifa"] + - "➒": [T: "nove circulado preto sem serifa"] + - "➓": [T: "dez circulado preto sem serifa"] + - "➔": [T: "seta grossa de cabeça larga para a direita"] + - "➕": [T: "sinal grosso de mais"] + - "➖": [T: "sinal grosso de menos"] + - "➗": [T: "sinal grosso de divisão"] + - "➘": [T: "seta grossa para sudeste"] + - "➙": [T: "seta grossa para a direita"] + - "➚": [T: "seta grossa para nordeste"] + - "➛": [T: "seta desenho técnico ponto para a direita"] + - "➜": [T: "seta grossa de ponta arredondada para a direita"] + - "➝": [T: "seta de ponta triangular para a direita"] + - "➞": [T: "seta grossa de ponta triangular para a direita"] + - "➟": [T: "seta tracejada de ponta triangular para a direita"] + - "➠": [T: "seta grossa tracejada de ponta triangular para a direita"] + - "➡": [T: "seta preta para a direita"] + - "➢": [T: "seta três dê superior aceso para a direita"] + - "➣": [T: "seta três dê inferior aceso para a direita"] + - "➤": [T: "preto ponta de seta à direita"] + - "➥": [T: "seta grossa preta curva baixo e para a direita"] + - "➦": [T: "seta grossa preta curva cima e para a direita"] + - "➧": [T: "seta achatado preta para a direita"] + - "➨": [T: "seta grossa de ponta côncava preta para a direita"] + - "➩": [T: "seta sombreado à direita branca para a direita"] + - "➪": [T: "seta sombreado à esquerda branca para a direita"] + - "➫": [T: "seta inclinado para trás sombreada branca para a direita"] + - "➬": [T: "seta inclinado para a frente sombreada branca para a direita"] + - "➭": [T: "seta grossa inferior com sombra à direita branca para a direita"] + - "➮": [T: "seta grossa superior com sombra à direita branca para a direita"] + - "➯": [T: "seta entalhada inferior com sombra à direita branca para a direita"] + - "➱": [T: "seta entalhada superior com sombra à direita branca para a direita"] + - "➲": [T: "grosso branco direita seta circulado"] + - "➳": [T: "seta de pena branca para a direita"] + - "➴": [T: "seta de pena preta para sudeste"] + - "➵": [T: "seta de pena preta para a direita"] + - "➶": [T: "seta de pena preta para nordeste"] + - "➷": [T: "seta grossa de pena preta para sudeste"] + - "➸": [T: "seta grossa de pena preta para a direita"] + - "➹": [T: "seta grossa de pena preta para nordeste"] + - "➺": [T: "seta de farpa em gota para a direita"] + - "➻": [T: "seta grossa de haste em gota para a direita"] + - "➼": [T: "seta de cauda em cunha para a direita"] + - "➽": [T: "seta grossa de cauda em cunha para a direita"] + - "➾": [T: "seta de contorno aberto para a direita"] + - "⟀": [T: "três dimensional ângulo"] + - "⟁": [T: "triângulo branco contendo pequeno branco triângulo"] + - "⟃": + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "um aberto contido em" + - "⟄": + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "um aberto contém" + - "⟅": [T: "esquerda em forma de s saco delimitador"] + - "⟆": [T: "direita em forma de s saco delimitador"] + - "⟇": [T: "ou com ponto dentro de"] + - "⟈": [T: "barra invertida precedente contido"] + - "⟉": [T: "contendo precedente barra"] + - "⟊": [T: "barra vertical com traço horizontal"] + - "⟋": [T: "matemático subindo diagonal"] + - "⟌": [T: "divisão longa"] + - "⟍": [T: "matemático descendo diagonal"] + - "⟎": [T: "e lógico enquadrado"] + - "⟏": [T: "ou lógico enquadrado"] + - "⟐": [T: "losango branco com centralizado ponto"] + - "⟑": [T: "e com ponto"] + - "⟒": [T: "pertence a abrindo cima"] + - "⟓": [T: "inferior direita canto com ponto"] + - "⟔": [T: "superior esquerda canto com ponto"] + - "⟕": [T: "esquerda externo unir"] + - "⟖": [T: "direita externo unir"] + - "⟗": [T: "completo externo unir"] + - "⟘": [T: "grande taco para cima"] + - "⟙": [T: "grande taco para baixo"] + - "⟚": [T: "esquerda e direita catraca dupla"] + - "⟛": [T: "esquerda e taco à direita"] + - "⟜": [T: "esquerda multimapa"] + - "⟝": [T: "longo taco à direita"] + - "⟞": [T: "longo taco à esquerda"] + - "⟟": [T: "círculo cima taco com acima de"] + - "⟠": [T: "losango dividido por horizontal régua"] + - "⟡": [T: "losango branco côncavo lateral"] + - "⟢": [T: "losango branco côncavo lateral com esquerda marca"] + - "⟣": [T: "losango branco côncavo lateral com direita marca"] + - "⟤": [T: "quadrado branco com esquerda marca"] + - "⟥": [T: "quadrado branco com direita marca"] + - "⟦": [T: "abre colchete branco quadrado"] + - "⟧": [T: "fecha colchete branco quadrado"] + - "⟬": [T: "abre colchete branco concha de tartaruga"] + - "⟭": [T: "fecha colchete branco concha de tartaruga"] + - "⟮": [T: "abre parêntese achatado"] + - "⟯": [T: "fecha parêntese achatado"] + - "⟰": [T: "seta quádrupla para cima"] + - "⟱": [T: "seta quádrupla para baixo"] + - "⟲": [T: "seta no sentido anti-horário com falha círculo"] + - "⟳": [T: "seta no sentido horário com falha círculo"] + - "⟴": [T: "seta para a direita com circulado mais"] + - "⟻": [T: "seta longa para a esquerda a partir de barra"] + - "⟼": [T: "seta longa para a direita a partir de barra"] + - "⟽": [T: "seta longa dupla para a esquerda a partir de barra"] + - "⟾": [T: "seta longa dupla para a direita a partir de barra"] + - "⟿": [T: "seta longa serpenteante para a direita"] + - "⤀": [T: "seta de duas pontas para a direita com vertical traço"] + - "⤁": [T: "seta de duas pontas para a direita com duplo vertical traço"] + - "⤂": [T: "seta dupla para a esquerda com vertical traço"] + - "⤃": [T: "seta dupla para a direita com vertical traço"] + - "⤄": [T: "seta dupla para a esquerda e para a direita com vertical traço"] + - "⤅": [T: "seta de duas pontas para a direita a partir de barra"] + - "⤆": [T: "seta dupla para a esquerda a partir de barra"] + - "⤇": [T: "seta dupla para a direita a partir de barra"] + - "⤈": [T: "seta para baixo com horizontal traço"] + - "⤉": [T: "seta para cima com horizontal traço"] + - "⤊": [T: "seta tripla para cima"] + - "⤋": [T: "seta tripla para baixo"] + - "⤌": [T: "seta dupla travessão para a esquerda"] + - "⤍": [T: "seta dupla travessão para a direita"] + - "⤎": [T: "seta de três traços para a esquerda"] + - "⤏": [T: "seta de três traços para a direita"] + - "⤐": [T: "seta de duas pontas de três traços para a direita"] + - "⤑": [T: "seta para a direita com pontilhado haste"] + - "⤒": [T: "seta para cima a barra"] + - "⤓": [T: "seta para baixo a barra"] + - "⤔": [T: "seta para a direita com cauda e vertical traço"] + - "⤕": [T: "seta para a direita com cauda e duplo vertical traço"] + - "⤖": [T: "seta de duas pontas para a direita com cauda"] + - "⤗": [T: "seta de duas pontas para a direita com cauda com vertical traço"] + - "⤘": [T: "seta de duas pontas para a direita com cauda com duplo vertical traço"] + - "⤙": [T: "seta para a esquerda cauda"] + - "⤚": [T: "seta para a direita cauda"] + - "⤛": [T: "seta dupla para a esquerda cauda"] + - "⤜": [T: "seta dupla para a direita cauda"] + - "⤝": [T: "seta para a esquerda a preenchido losango"] + - "⤞": [T: "seta para a direita a preenchido losango"] + - "⤟": [T: "seta para a esquerda a partir de barra a preenchido losango"] + - "⤠": [T: "seta para a direita a partir de barra a preenchido losango"] + - "⤡": [T: "seta e sul leste para noroeste"] + - "⤢": [T: "seta e sul oeste para nordeste"] + - "⤣": [T: "seta para noroeste com gancho"] + - "⤤": [T: "seta para nordeste com gancho"] + - "⤥": [T: "seta para sudeste com gancho"] + - "⤦": [T: "seta para sudoeste com gancho"] + - "⤧": [T: "seta para noroeste e norte leste seta"] + - "⤨": [T: "seta para nordeste e sul leste seta"] + - "⤩": [T: "seta para sudeste e sul oeste seta"] + - "⤪": [T: "seta para sudoeste e norte oeste seta"] + - "⤫": [T: "subindo diagonal cruzando descendo diagonal"] + - "⤬": [T: "descendo diagonal cruzando subindo diagonal"] + - "⤭": [T: "seta para sudeste cruzando norte leste seta"] + - "⤮": [T: "seta para nordeste cruzando sul leste seta"] + - "⤯": [T: "seta descendo diagonal cruzando para nordeste"] + - "⤰": [T: "seta subindo diagonal cruzando para sudeste"] + - "⤱": [T: "seta para nordeste cruzando norte oeste seta"] + - "⤲": [T: "seta para noroeste cruzando norte leste seta"] + - "⤳": [T: "seta ondulada apontando diretamente direita"] + - "⤴": [T: "seta apontando direita depois curvando cima"] + - "⤵": [T: "seta apontando direita depois curvando baixo"] + - "⤶": [T: "seta apontando baixo depois curvando esquerda"] + - "⤷": [T: "seta apontando baixo depois curvando direita"] + - "⤸": [T: "seta lado arco no sentido horário para a direita"] + - "⤹": [T: "seta lado arco no sentido anti-horário para a esquerda"] + - "⤺": [T: "seta superior arco no sentido anti-horário"] + - "⤻": [T: "seta inferior arco no sentido anti-horário"] + - "⤼": [T: "seta superior arco no sentido horário com menos"] + - "⤽": [T: "seta superior arco no sentido anti-horário com mais"] + - "⤾": [T: "seta inferior semicircular no sentido horário para a direita"] + - "⤿": [T: "seta inferior semicircular no sentido anti-horário para a esquerda"] + - "⥀": [T: "seta no sentido anti-horário fechada círculo"] + - "⥁": [T: "seta no sentido horário fechada círculo"] + - "⥂": [T: "seta para a direita acima de curto esquerda seta"] + - "⥃": [T: "seta para a esquerda acima de curto direita seta"] + - "⥄": [T: "seta curta para a direita acima de esquerda seta"] + - "⥅": [T: "seta para a direita com mais abaixo de"] + - "⥆": [T: "seta para a esquerda com mais abaixo de"] + - "⥇": [T: "seta para a direita atravessado por xis"] + - "⥈": [T: "seta para a esquerda e para a direita atravessado por círculo"] + - "⥉": [T: "seta de duas pontas para cima a partir de círculo"] + - "⥊": [T: "arpão farpa cima direita farpa baixo para a esquerda"] + - "⥋": [T: "arpão farpa baixo direita farpa cima para a esquerda"] + - "⥌": [T: "arpão cima farpa direita baixo farpa para a esquerda"] + - "⥍": [T: "arpão cima farpa baixo farpa direita para a esquerda"] + - "⥎": [T: "arpão farpa cima direita farpa cima para a esquerda"] + - "⥏": [T: "arpão cima farpa baixo farpa direita para a direita"] + - "⥐": [T: "arpão farpa baixo direita farpa baixo para a esquerda"] + - "⥑": [T: "arpão cima farpa baixo farpa esquerda para a esquerda"] + - "⥒": [T: "arpão para a esquerda com farpa cima a barra"] + - "⥓": [T: "arpão para a direita com farpa cima a barra"] + - "⥔": [T: "arpão para cima com farpa direita a barra"] + - "⥕": [T: "arpão para baixo com farpa direita a barra"] + - "⥖": [T: "arpão para a esquerda com farpa baixo a barra"] + - "⥗": [T: "arpão para a direita com farpa baixo a barra"] + - "⥘": [T: "arpão para cima com farpa esquerda a barra"] + - "⥙": [T: "arpão para baixo com farpa esquerda a barra"] + - "⥚": [T: "arpão para a esquerda com farpa cima a partir de barra"] + - "⥛": [T: "arpão para a direita com farpa cima a partir de barra"] + - "⥜": [T: "arpão para cima com farpa direita a partir de barra"] + - "⥝": [T: "arpão para baixo com farpa direita a partir de barra"] + - "⥞": [T: "arpão para a esquerda com farpa baixo a partir de barra"] + - "⥟": [T: "arpão para a direita com farpa baixo a partir de barra"] + - "⥠": [T: "arpão para cima com farpa esquerda a partir de barra"] + - "⥡": [T: "arpão para baixo com farpa esquerda a partir de barra"] + - "⥢": [T: "arpão para a esquerda com farpa cima acima de esquerda arpão com farpa baixo"] + - "⥣": [T: "arpão para cima com farpa esquerda ao lado de cima arpão com farpa direita"] + - "⥤": [T: "arpão para a direita com farpa cima acima de direita arpão com farpa baixo"] + - "⥥": [T: "arpão para baixo com farpa esquerda ao lado de baixo arpão com farpa direita"] + - "⥦": [T: "arpão para a esquerda com farpa cima acima de direita arpão com farpa cima"] + - "⥧": [T: "arpão para a esquerda com farpa baixo acima de direita arpão com farpa baixo"] + - "⥨": [T: "arpão para a direita com farpa cima acima de esquerda arpão com farpa cima"] + - "⥩": [T: "arpão para a direita com farpa baixo acima de esquerda arpão com farpa baixo"] + - "⥪": [T: "arpão para a esquerda com farpa cima acima de longo travessão"] + - "⥫": [T: "arpão para a esquerda com farpa baixo abaixo de longo travessão"] + - "⥬": [T: "arpão para a direita com farpa cima acima de longo travessão"] + - "⥭": [T: "arpão para a direita com farpa baixo abaixo de longo travessão"] + - "⥮": [T: "arpão para cima com farpa esquerda ao lado de baixo arpão com farpa direita"] + - "⥯": [T: "arpão para baixo com farpa esquerda ao lado de cima arpão com farpa direita"] + - "⥰": [T: "seta dupla para a direita com ponta arredondada"] + - "⥱": [T: "seta igual acima de para a direita"] + - "⥲": [T: "seta til operador acima de para a direita"] + - "⥳": [T: "seta para a esquerda acima de operador til"] + - "⥴": [T: "seta para a direita acima de operador til"] + - "⥵": [T: "seta para a direita acima de quase igual a"] + - "⥶": [T: "seta menor que acima de para a esquerda"] + - "⥷": [T: "seta para a esquerda atravessado por menor que"] + - "⥸": [T: "seta maior que acima de para a direita"] + - "⥹": [T: "seta contido acima de para a direita"] + - "⥺": [T: "seta para a esquerda atravessado por contido"] + - "⥻": [T: "seta contendo acima de para a esquerda"] + - "⥼": [T: "esquerda peixe cauda"] + - "⥽": [T: "direita peixe cauda"] + - "⥾": [T: "cima peixe cauda"] + - "⥿": [T: "baixo peixe cauda"] + - "⦀": [T: "barra tripla vertical delimitador"] + - "⦁": [T: "da notação z ponto"] + - "⦂": [T: "da notação z tipo dois pontos"] + - "⦃": [T: "abre chave branca"] + - "⦄": [T: "fecha chave branca"] + - "⦅": [T: "abre parêntese branco"] + - "⦆": [T: "fecha parêntese branco"] + - "⦇": [T: "da notação z esquerda imagem colchete"] + - "⦈": [T: "da notação z direita imagem colchete"] + - "⦉": [T: "da notação z esquerda vinculação colchete"] + - "⦊": [T: "da notação z direita vinculação colchete"] + - "⦋": [T: "quadrado esquerda colchete com barra inferior"] + - "⦌": [T: "quadrado direita colchete com barra inferior"] + - "⦍": [T: "quadrado esquerda colchete com marca em superior canto"] + - "⦎": [T: "quadrado direita colchete com marca em inferior canto"] + - "⦏": [T: "quadrado esquerda colchete com marca em inferior canto"] + - "⦐": [T: "quadrado direita colchete com marca em superior canto"] + - "⦑": [T: "colchete angular com ponto à esquerda"] + - "⦒": [T: "colchete angular com ponto à direita"] + - "⦓": [T: "abre colchete arco menor que"] + - "⦔": [T: "fecha colchete arco maior que"] + - "⦕": [T: "arco duplo esquerda maior que colchete"] + - "⦖": [T: "arco duplo direita menor que colchete"] + - "⦗": [T: "abre colchete preto concha de tartaruga"] + - "⦘": [T: "fecha colchete preto concha de tartaruga"] + - "⦙": [T: "cerca pontilhada"] + - "⦚": [T: "linha vertical em zigue-zague"] + - "⦛": [T: "medido ângulo abrindo esquerda"] + - "⦜": [T: "quadrado direita ângulo variante com"] + - "⦝": [T: "medido ângulo com ponto à direita"] + - "⦞": [T: "ângulo com esse dentro de"] + - "⦟": [T: "agudo ângulo"] + - "⦠": [T: "ângulo esférico abrindo esquerda"] + - "⦡": [T: "ângulo esférico abrindo cima"] + - "⦢": [T: "ângulo invertido"] + - "⦣": [T: "ângulo invertido"] + - "⦤": [T: "ângulo com barra inferior"] + - "⦥": [T: "ângulo invertido com barra inferior"] + - "⦦": [T: "ângulo oblíquo abrindo cima"] + - "⦧": [T: "ângulo oblíquo abrindo baixo"] + - "⦨": [T: "seta medido ângulo com aberta braço terminando em apontando cima e à direita"] + - "⦩": [T: "seta medido ângulo com aberta braço terminando em apontando cima e à esquerda"] + - "⦪": [T: "seta medido ângulo com aberta braço terminando em apontando baixo e à direita"] + - "⦫": [T: "seta medido ângulo com aberta braço terminando em apontando baixo e à esquerda"] + - "⦬": [T: "seta medido ângulo com aberta braço terminando em apontando direita e cima"] + - "⦭": [T: "seta medido ângulo com aberta braço terminando em apontando esquerda e cima"] + - "⦮": [T: "seta medido ângulo com aberta braço terminando em apontando direita e baixo"] + - "⦯": [T: "seta medido ângulo com aberta braço terminando em apontando esquerda e baixo"] + - "⦰": [T: "conjunto invertido vazio"] + - "⦱": [T: "conjunto vazio com barra superior"] + - "⦲": [T: "círculo vazio conjunto com pequeno acima de"] + - "⦳": [T: "seta vazio conjunto com para a direita acima de"] + - "⦴": [T: "seta vazio conjunto com para a esquerda acima de"] + - "⦵": [T: "círculo com barra horizontal"] + - "⦶": [T: "barra vertical circulado"] + - "⦷": [T: "paralelo circulado"] + - "⦸": [T: "invertido barra circulado"] + - "⦹": [T: "perpendicular circulado"] + - "⦺": [T: "dividido por barra horizontal e superior metade dividido por barra vertical circulado"] + - "⦻": [T: "círculo com sobreposto xis"] + - "⦼": [T: "no sentido anti-horário rotacionado sinal de divisão circulado"] + - "⦽": [T: "seta para cima atravessado por círculo"] + - "⦾": [T: "branco marcador circulado"] + - "⦿": [T: "marcador circulado"] + - "⧀": [T: "menor que circulado"] + - "⧁": [T: "maior que circulado"] + - "⧂": [T: "círculo com pequeno círculo à direita"] + - "⧃": [T: "círculo com dois horizontal traços à direita"] + - "⧄": [T: "subindo diagonal barra enquadrado"] + - "⧅": [T: "descendo diagonal barra enquadrado"] + - "⧆": [T: "asterisco enquadrado"] + - "⧇": [T: "pequeno círculo enquadrado"] + - "⧈": [T: "quadrado enquadrado"] + - "⧉": [T: "quadrados dois unido"] + - "⧊": [T: "triângulo com ponto acima de"] + - "⧋": [T: "triângulo com barra inferior"] + - "⧌": [T: "triângulo esse em"] + - "⧍": [T: "triângulo com serifas em inferior"] + - "⧎": [T: "triângulo direita acima de esquerda triângulo"] + - "⧏": [T: "triângulo esquerda ao lado de barra vertical"] + - "⧐": [T: "triângulo vertical barra ao lado de direita"] + - "⧑": [T: "laço com esquerda metade preto"] + - "⧒": [T: "laço com direita metade preto"] + - "⧓": [T: "laço preto"] + - "⧔": [T: "vezes com esquerda metade preto"] + - "⧕": [T: "vezes com direita metade preto"] + - "⧖": [T: "ampulheta branco"] + - "⧗": [T: "ampulheta preto"] + - "⧘": [T: "abre cerca ondulada"] + - "⧙": [T: "fecha cerca ondulada"] + - "⧚": [T: "abre cerca dupla ondulada"] + - "⧛": [T: "fecha cerca dupla ondulada"] + - "⧜": [T: "incompleto infinito"] + - "⧝": [T: "laço sobre infinito"] + - "⧞": [T: "infinito negado com barra vertical"] + - "⧟": [T: "de duas pontas multimapa"] + - "⧠": [T: "quadrado com contornado contorno"] + - "⧡": [T: "aumenta como"] + - "⧢": [T: "embaralhamento produto"] + - "⧣": [T: "sinal de igual e inclinado paralelo"] + - "⧤": [T: "sinal de igual e inclinado paralelo com til acima de"] + - "⧥": [T: "idêntico a e inclinado paralelo"] + - "⧦": [T: "igualmente forte"] + - "⧧": [T: "termodinâmico"] + - "⧨": [T: "triângulo baixo apontando com esquerda metade preto"] + - "⧩": [T: "triângulo baixo apontando com direita metade preto"] + - "⧪": [T: "seta preta losango com para baixo"] + - "⧫": [T: "losango preto"] + - "⧬": [T: "seta branca círculo com para baixo"] + - "⧭": [T: "seta preta círculo com para baixo"] + - "⧮": [T: "quadrado com barra de erro branco"] + - "⧯": [T: "quadrado com barra de erro preto"] + - "⧰": [T: "losango com barra de erro branco"] + - "⧱": [T: "losango com barra de erro preto"] + - "⧲": [T: "círculo com barra de erro branco"] + - "⧳": [T: "círculo com barra de erro preto"] + - "⧴": [T: "regra atrasada"] + - "⧵": [T: "barra invertida operador"] + - "⧶": [T: "barra com barra superior"] + - "⧷": [T: "barra invertida com traço horizontal"] + - "⧸": [T: "barra grande"] + - "⧹": [T: "barra grande invertida"] + - "⧺": [T: "duplo mais"] + - "⧻": [T: "triplo mais"] + - "⧼": [T: "abre colchete apontando curvo ângulo"] + - "⧽": [T: "fecha colchete apontando curvo ângulo"] + - "⧾": [T: "minúsculo"] + - "⧿": [T: "miny"] + - "⨀": [T: "ponto circulado"] + - "⨁": [T: "mais operador circulado"] + - "⨂": [T: "vezes operador circulado"] + - "⨃": [T: "união operador com ponto"] + - "⨄": [T: "união operador com mais"] + - "⨅": [T: "quadrado interseção operador"] + - "⨆": [T: "quadrado união operador"] + - "⨇": [T: "dois e lógico operador"] + - "⨈": [T: "dois ou lógico operador"] + - "⨉": [T: "vezes operador"] + - "⨊": [T: "módulo dois soma"] + - "⨋": [T: "somatório com integral"] + - "⨌": [T: "integral quádrupla operador"] + - "⨍": [T: "integral de parte finita"] + - "⨎": [T: "integral com traço duplo"] + - "⨏": [T: "integral média com barra"] + - "⨐": [T: "circulação função"] + - "⨑": [T: "no sentido anti-horário integração"] + - "⨒": [T: "linha integração com retangular caminho ao redor polo"] + - "⨓": [T: "linha integração com semicircular caminho ao redor polo"] + - "⨔": [T: "linha integração não incluindo o polo"] + - "⨕": [T: "integral ao redor a ponto operador"] + - "⨖": [T: "quatérnio integral operador"] + - "⨗": [T: "seta integral com para a esquerda com gancho"] + - "⨘": [T: "integral com vezes sinal"] + - "⨙": [T: "integral com interseção"] + - "⨚": [T: "integral com união"] + - "⨛": [T: "integral com barra superior"] + - "⨜": [T: "integral com barra inferior"] + - "⨝": [T: "unir"] + - "⨞": [T: "triângulo grande esquerda operador"] + - "⨟": [T: "da notação z esquema composição"] + - "⨠": [T: "da notação z esquema encanamento"] + - "⨡": [T: "da notação z esquema projeção"] + - "⨢": [T: "círculo mais sinal com acima de"] + - "⨣": [T: "sinal de mais com circunflexo acento acima de"] + - "⨤": [T: "sinal de mais com til acima de"] + - "⨥": [T: "sinal de mais com ponto abaixo de"] + - "⨦": [T: "sinal de mais com til abaixo de"] + - "⨧": [T: "sinal de mais com subscrito dois"] + - "⨨": [T: "triângulo mais sinal com preto"] + - "⨩": [T: "sinal de menos com vírgula acima de"] + - "⨪": [T: "sinal de menos com ponto abaixo de"] + - "⨫": [T: "sinal de menos com descendo pontos"] + - "⨬": [T: "sinal de menos com subindo pontos"] + - "⨭": [T: "círculo mais sinal em esquerda metade"] + - "⨮": [T: "círculo mais sinal em direita metade"] + - "⨯": + - test: + if: "$Verbosity='Terse'" + then: [T: "cruzes"] + else: [T: "cruzes produto"] + - "⨰": [T: "sinal de multiplicação com ponto acima de"] + - "⨱": [T: "sinal de multiplicação com barra inferior"] + - "⨲": [T: "produto semidireto com inferior fechado"] + - "⨳": [T: "produto esmagado"] + - "⨴": [T: "círculo multiplicação sinal em esquerda metade"] + - "⨵": [T: "círculo multiplicação sinal em direita metade"] + - "⨶": [T: "sinal de multiplicação com circunflexo acento circulado"] + - "⨷": [T: "círculo multiplicação sinal em duplo"] + - "⨸": [T: "sinal de divisão circulado"] + - "⨹": [T: "triângulo mais sinal em"] + - "⨺": [T: "triângulo menos sinal em"] + - "⨻": [T: "triângulo multiplicação sinal em"] + - "⨼": [T: "interior produto"] + - "⨽": [T: "à direita interior produto"] + - "⨾": [T: "da notação z relacional composição"] + - "⨿": [T: "amálgama ou coproduto"] + - "⩀": [T: "interseção com ponto"] + - "⩁": [T: "união com sinal de menos"] + - "⩂": [T: "união com barra superior"] + - "⩃": [T: "interseção com barra superior"] + - "⩄": [T: "interseção com e lógico"] + - "⩅": [T: "união com ou lógico"] + - "⩆": [T: "união acima de interseção"] + - "⩇": [T: "interseção acima de união"] + - "⩈": [T: "união acima de barra acima de interseção"] + - "⩉": [T: "interseção acima de barra acima de união"] + - "⩊": [T: "união ao lado de e unido com união"] + - "⩋": [T: "interseção ao lado de e unido com interseção"] + - "⩌": [T: "união fechada com serifas"] + - "⩍": [T: "interseção fechada com serifas"] + - "⩎": [T: "quadrado duplo interseção"] + - "⩏": [T: "quadrado duplo união"] + - "⩐": [T: "união fechada com serifas e produto esmagado"] + - "⩑": [T: "e lógico com ponto acima de"] + - "⩒": [T: "ou lógico com ponto acima de"] + - "⩓": [T: "duplo e lógico"] + - "⩔": [T: "duplo ou lógico"] + - "⩕": [T: "dois cruzando e lógico"] + - "⩖": [T: "dois cruzando ou lógico"] + - "⩗": [T: "inclinado grande ou"] + - "⩘": [T: "inclinado grande e"] + - "⩙": [T: "ou lógico sobreposto e lógico"] + - "⩚": [T: "e lógico com do meio haste"] + - "⩛": [T: "ou lógico com do meio haste"] + - "⩜": [T: "e lógico com horizontal travessão"] + - "⩝": [T: "ou lógico com horizontal travessão"] + - "⩞": [T: "e lógico com barra dupla superior"] + - "⩟": [T: "e lógico com barra inferior"] + - "⩠": [T: "e lógico com barra dupla inferior"] + - "⩡": [T: "pequeno vê com barra inferior"] + - "⩢": [T: "ou lógico com barra dupla superior"] + - "⩣": [T: "ou lógico com barra dupla inferior"] + - "⩤": [T: "da notação z domínio antirrestrição"] + - "⩥": [T: "da notação z imagem antirrestrição"] + - "⩦": [T: "sinal de igual com ponto abaixo de"] + - "⩧": [T: "idêntico com ponto acima de"] + - "⩨": [T: "barra tripla horizontal com traço duplo vertical"] + - "⩩": [T: "barra tripla horizontal com traço triplo vertical"] + - "⩪": [T: "operador til com ponto acima de"] + - "⩫": [T: "operador til com subindo pontos"] + - "⩬": [T: "semelhante menos semelhante"] + - "⩭": [T: "congruente com ponto acima de"] + - "⩮": [T: "igual com asterisco"] + - "⩯": [T: "quase igual a com circunflexo acento"] + - "⩰": [T: "aproximadamente igual a ou igual a"] + - "⩱": [T: "sinal de igual acima de sinal de mais"] + - "⩲": [T: "sinal de mais acima de sinal de igual"] + - "⩳": [T: "sinal de igual acima de operador til"] + - "⩴": [T: "duplo dois pontos igual"] + - "⩵": [T: "dois consecutivo igual sinais"] + - "⩶": [T: "três consecutivo igual sinais"] + - "⩷": [T: "sinal de igual com dois pontos acima de e dois pontos abaixo de"] + - "⩸": [T: "equivalente com quatro pontos acima de"] + - "⩹": [T: "círculo menor que com dentro de"] + - "⩺": [T: "círculo maior que com dentro de"] + - "⩻": [T: "menor que com ponto de interrogação acima de"] + - "⩼": [T: "maior que com ponto de interrogação acima de"] + - "⩽": [T: "menor que ou inclinado igual a"] + - "⩾": [T: "maior que ou inclinado igual a"] + - "⩿": [T: "menor que ou inclinado igual a com ponto dentro de"] + - "⪀": [T: "maior que ou inclinado igual a com ponto dentro de"] + - "⪁": [T: "menor que ou inclinado igual a com ponto acima de"] + - "⪂": [T: "maior que ou inclinado igual a com ponto acima de"] + - "⪃": [T: "menor que ou inclinado igual a com ponto acima de direita"] + - "⪄": [T: "maior que ou inclinado igual a com ponto acima de esquerda"] + - "⪅": [T: "menor que ou aproximado"] + - "⪆": [T: "maior que ou aproximado"] + - "⪇": [T: "menor que e linha simples não igual a"] + - "⪈": [T: "maior que e linha simples não igual a"] + - "⪉": [T: "menor que e não aproximado"] + - "⪊": [T: "maior que e não aproximado"] + - "⪋": [T: "menor que acima de linha dupla igual acima de maior que"] + - "⪌": [T: "maior que acima de linha dupla igual acima de menor que"] + - "⪍": [T: "menor que acima de semelhante ou igual"] + - "⪎": [T: "maior que acima de semelhante ou igual"] + - "⪏": [T: "menor que acima de semelhante acima de maior que"] + - "⪐": [T: "maior que acima de semelhante acima de menor que"] + - "⪑": [T: "menor que acima de maior que acima de linha dupla igual"] + - "⪒": [T: "maior que acima de menor que acima de linha dupla igual"] + - "⪓": [T: "menor que acima de inclinado igual acima de maior que acima de inclinado igual"] + - "⪔": [T: "maior que acima de inclinado igual acima de menor que acima de inclinado igual"] + - "⪕": [T: "inclinado igual a ou menor que"] + - "⪖": [T: "inclinado igual a ou maior que"] + - "⪗": [T: "inclinado igual a ou menor que com ponto dentro de"] + - "⪘": [T: "inclinado igual a ou maior que com ponto dentro de"] + - "⪙": [T: "linha dupla igual a ou menor que"] + - "⪚": [T: "linha dupla igual a ou maior que"] + - "⪛": [T: "linha dupla inclinado igual a ou menor que"] + - "⪜": [T: "linha dupla inclinado igual a ou maior que"] + - "⪝": [T: "semelhante ou menor que"] + - "⪞": [T: "semelhante ou maior que"] + - "⪟": [T: "semelhante acima de menor que acima de sinal de igual"] + - "⪠": [T: "semelhante acima de maior que acima de sinal de igual"] + - "⪡": [T: "duplo aninhado menor que"] + - "⪢": [T: "duplo aninhado maior que"] + - "⪣": [T: "duplo aninhado menor que com barra inferior"] + - "⪤": [T: "maior que sobreposto menor que"] + - "⪥": [T: "maior que ao lado de menor que"] + - "⪦": [T: "menor que fechado por curva"] + - "⪧": [T: "maior que fechado por curva"] + - "⪨": [T: "menor que fechado por curva acima de inclinado igual"] + - "⪩": [T: "maior que fechado por curva acima de inclinado igual"] + - "⪪": [T: "menor que"] + - "⪫": [T: "maior que"] + - "⪬": [T: "menor que ou igual a"] + - "⪭": [T: "maior que ou igual a"] + - "⪮": [T: "sinal de igual com irregular acima de"] + - "⪯": [T: "precede acima de linha simples sinal de igual"] + - "⪰": [T: "sucede acima de linha simples sinal de igual"] + - "⪱": [T: "precede acima de linha simples não igual a"] + - "⪲": [T: "sucede acima de linha simples não igual a"] + - "⪳": [T: "precede acima de sinal de igual"] + - "⪴": [T: "sucede acima de sinal de igual"] + - "⪵": [T: "precede acima de não igual a"] + - "⪶": [T: "sucede acima de não igual a"] + - "⪷": [T: "precede acima de quase igual a"] + - "⪸": [T: "sucede acima de quase igual a"] + - "⪹": [T: "precede acima de não quase igual a"] + - "⪺": [T: "sucede acima de não quase igual a"] + - "⪻": [T: "duplo precede"] + - "⪼": [T: "duplo sucede"] + - "⪽": [T: "contido com ponto"] + - "⪾": [T: "contendo com ponto"] + - "⪿": [T: "contido com sinal de mais abaixo de"] + - "⫀": [T: "contendo com sinal de mais abaixo de"] + - "⫁": [T: "contido com sinal de multiplicação abaixo de"] + - "⫂": [T: "contendo com sinal de multiplicação abaixo de"] + - "⫃": [T: "contido em ou igual a com ponto acima de"] + - "⫄": [T: "contém ou igual a com ponto acima de"] + - "⫅": [T: "contido em acima de sinal de igual"] + - "⫆": [T: "contém acima de sinal de igual"] + - "⫇": [T: "contido em acima de operador til"] + - "⫈": [T: "contém acima de operador til"] + - "⫉": [T: "contido em acima de quase igual a"] + - "⫊": [T: "contém acima de quase igual a"] + - "⫋": [T: "contido acima de não igual a"] + - "⫌": [T: "contém acima de não igual a"] + - "⫍": [T: "quadrado esquerda aberto caixa operador"] + - "⫎": [T: "quadrado direita aberto caixa operador"] + - "⫏": [T: "fechado contido"] + - "⫐": [T: "fechado contendo"] + - "⫑": [T: "fechado contido ou igual a"] + - "⫒": [T: "fechado contendo ou igual a"] + - "⫓": [T: "contido acima de contendo"] + - "⫔": [T: "contendo acima de contido"] + - "⫕": [T: "contido acima de contido"] + - "⫖": [T: "contendo acima de contendo"] + - "⫗": [T: "contendo ao lado de contido"] + - "⫘": [T: "contendo ao lado de e unido por travessão com contido"] + - "⫙": [T: "pertence a abrindo baixo"] + - "⫚": [T: "forcado com t superior"] + - "⫛": [T: "interseção transversal"] + - "⫝̸": [T: "bifurcando"] + - "⫝": [T: "não bifurcante"] + - "⫞": [T: "curto taco à esquerda"] + - "⫟": [T: "curto taco para baixo"] + - "⫠": [T: "curto taco para cima"] + - "⫡": [T: "perpendicular com esse"] + - "⫢": [T: "barra vertical triplo catraca à direita"] + - "⫣": [T: "barra dupla vertical catraca à esquerda"] + - "⫤": [T: "barra vertical duplo catraca à esquerda"] + - "⫥": [T: "barra dupla vertical duplo catraca à esquerda"] + - "⫦": [T: "longo travessão a partir de esquerda membro de duplo vertical"] + - "⫧": [T: "curto taco com barra superior para baixo"] + - "⫨": [T: "curto taco com barra inferior para cima"] + - "⫩": [T: "curto taco acima de curto taco para baixo para cima"] + - "⫪": [T: "duplo taco para baixo"] + - "⫫": [T: "duplo taco para cima"] + - "⫬": [T: "traço duplo não sinal"] + - "⫭": [T: "traço invertido duplo não sinal"] + - "⫮": [T: "não divide com invertido negação barra"] + - "⫯": [T: "círculo vertical linha com acima de"] + - "⫰": [T: "círculo vertical linha com abaixo de"] + - "⫱": [T: "círculo baixo taco com abaixo de"] + - "⫲": [T: "paralelo com traço horizontal"] + - "⫳": [T: "paralelo com operador til"] + - "⫴": [T: "barra tripla vertical binário relação"] + - "⫵": [T: "barra tripla vertical com traço horizontal"] + - "⫶": [T: "triplo dois pontos operador"] + - "⫷": [T: "triplo aninhado menor que"] + - "⫸": [T: "triplo aninhado maior que"] + - "⫹": [T: "linha dupla inclinado menor ou igual a"] + - "⫺": [T: "linha dupla inclinado maior ou igual a"] + - "⫻": [T: "barra tripla binário relação"] + - "⫼": [T: "barra grande tripla operador vertical"] + - "⫽": [T: "barra dupla operador"] + - "⫾": [T: "barra branca vertical"] + - "⫿": [T: "barra branca vertical"] + - "⬀": [T: "seta branca para nordeste"] + - "⬁": [T: "seta branca para noroeste"] + - "⬂": [T: "seta branca para sudeste"] + - "⬃": [T: "seta branca para sudoeste"] + - "⬄": [T: "seta branca para a esquerda e para a direita"] + - "⬅": [T: "seta preta para a esquerda"] + - "⬆": [T: "seta preta para cima"] + - "⬇": [T: "seta preta para baixo"] + - "⬈": [T: "seta preta para nordeste"] + - "⬉": [T: "seta preta para noroeste"] + - "⬊": [T: "seta preta para sudeste"] + - "⬋": [T: "seta preta para sudoeste"] + - "⬌": [T: "seta preta para a esquerda e para a direita"] + - "⬍": [T: "seta preta para cima e para baixo"] + - "⬎": [T: "seta para a direita com ponta baixo"] + - "⬏": [T: "seta para a direita com ponta cima"] + - "⬐": [T: "seta para a esquerda com ponta baixo"] + - "⬑": [T: "seta para a esquerda com ponta cima"] + - "⬒": [T: "quadrado com superior metade preto"] + - "⬓": [T: "quadrado com inferior metade preto"] + - "⬔": [T: "quadrado com superior direita diagonal metade preto"] + - "⬕": [T: "quadrado com inferior esquerda diagonal metade preto"] + - "⬖": [T: "losango com esquerda metade preto"] + - "⬗": [T: "losango com direita metade preto"] + - "⬘": [T: "losango com superior metade preto"] + - "⬙": [T: "losango com inferior metade preto"] + - "⬚": [T: "caixa"] + - "⬛": [T: "quadrado preto grande"] + - "⬜": [T: "quadrado branco grande"] + - "⬝": [T: "quadrado preto muito pequeno"] + - "⬞": [T: "quadrado branco muito pequeno"] + - "⬟": [T: "pentágono preto"] + - "⬠": [T: "pentágono branco"] + - "⬡": [T: "hexágono branco"] + - "⬢": [T: "hexágono preto"] + - "⬣": [T: "hexágono horizontal preto"] + - "⬤": [T: "círculo preto grande"] + - "⬥": [T: "losango preto médio"] + - "⬦": [T: "losango branco médio"] + - "⬧": [T: "losango preto médio"] + - "⬨": [T: "losango branco médio"] + - "⬩": [T: "losango preto pequeno"] + - "⬪": [T: "losango preto pequeno"] + - "⬫": [T: "losango branco pequeno"] + - "⬬": [T: "elipse preta horizontal"] + - "⬭": [T: "elipse branca horizontal"] + - "⬮": [T: "elipse preta vertical"] + - "⬯": [T: "elipse branca vertical"] + - "⬰": [T: "seta para a esquerda com pequeno círculo"] + - "⬱": [T: "setas três para a esquerda"] + - "⬲": [T: "seta para a esquerda com circulado mais"] + - "⬳": [T: "seta longa serpenteante para a esquerda"] + - "⬴": [T: "seta de duas pontas para a esquerda com vertical traço"] + - "⬵": [T: "seta de duas pontas para a esquerda com duplo vertical traço"] + - "⬶": [T: "seta de duas pontas para a esquerda a partir de barra"] + - "⬷": [T: "seta de duas pontas de três traços para a esquerda"] + - "⬸": [T: "seta para a esquerda com pontilhado haste"] + - "⬹": [T: "seta para a esquerda com cauda com vertical traço"] + - "⬺": [T: "seta para a esquerda com cauda com duplo vertical traço"] + - "⬻": [T: "seta de duas pontas para a esquerda com cauda"] + - "⬼": [T: "seta de duas pontas para a esquerda com cauda com vertical traço"] + - "⬽": [T: "seta de duas pontas para a esquerda com cauda com duplo vertical traço"] + - "⬾": [T: "seta para a esquerda atravessado por xis"] + - "⬿": [T: "seta ondulada apontando diretamente esquerda"] + - "⭀": [T: "seta igual sinal acima de para a esquerda"] + - "⭁": [T: "seta invertida til operador acima de para a esquerda"] + - "⭂": [T: "seta para a esquerda acima de invertido quase igual a"] + - "⭃": [T: "seta para a direita atravessado por maior que"] + - "⭄": [T: "seta para a direita atravessado por contendo"] + - "⭅": [T: "seta quádrupla para a esquerda"] + - "⭆": [T: "seta quádrupla para a direita"] + - "⭇": [T: "seta invertida til operador acima de para a direita"] + - "⭈": [T: "seta para a direita acima de invertido quase igual a"] + - "⭉": [T: "seta til operador acima de para a esquerda"] + - "⭊": [T: "seta para a esquerda acima de quase igual a"] + - "⭋": [T: "seta para a esquerda acima de invertido operador til"] + - "⭌": [T: "seta para a direita acima de invertido operador til"] + - "⭐": [T: "estrela branca média"] + - "⭑": [T: "estrela preta pequena"] + - "⭒": [T: "estrela branca pequena"] + - "⭓": [T: "pentágono preto direita apontando"] + - "⭔": [T: "pentágono branco direita apontando"] + - "⭕": [T: "círculo grosso grande"] + - "⭖": [T: "grosso oval com oval dentro de"] + - "⭗": [T: "círculo grosso com círculo dentro de"] + - "⭘": [T: "círculo grosso"] + - "⭙": [T: "grosso circulado aspa"] + - "⸀": [T: "ângulo substituição marcador à direita"] + - "⸁": [T: "ângulo pontilhado substituição marcador à direita"] + - "⸂": [T: "abre colchete substituição"] + - "⸃": [T: "fecha colchete substituição"] + - "⸄": [T: "abre colchete pontilhado substituição"] + - "⸅": [T: "fecha colchete pontilhado substituição"] + - "⸆": [T: "elevado interpolação marcador"] + - "⸇": [T: "elevado pontilhado interpolação marcador"] + - "⸈": [T: "pontilhado transposição marcador marcador"] + - "⸉": [T: "abre colchete transposição"] + - "⸊": [T: "fecha colchete transposição"] + - "⸋": [T: "quadrado elevado"] + - "⸌": [T: "abre colchete elevado omissão"] + - "⸍": [T: "fecha colchete elevado omissão"] + - "⸎": [T: "editorial corônis"] + - "⸏": [T: "parágrafo"] + - "⸐": [T: "bifurcado parágrafo"] + - "⸑": [T: "invertido bifurcado parágrafo"] + - "⸒": [T: "hipodiástole"] + - "⸓": [T: "pontilhado óbelo"] + - "⸔": [T: "âncora para baixo"] + - "⸕": [T: "âncora para cima"] + - "⸖": [T: "pontilhado direita apontando ângulo"] + - "⸗": [T: "duplo oblíquo hífen"] + - "⸘": [T: "invertido interrobang"] + - "⸙": [T: "ramo de palmeira"] + - "⸚": [T: "hífen com trema"] + - "⸛": [T: "til com anel acima de"] + - "⸜": [T: "abre colchete baixo paráfrase"] + - "⸝": [T: "fecha colchete baixo paráfrase"] + - "⸞": [T: "til com ponto acima de"] + - "⸟": [T: "til com ponto abaixo de"] + - "⸠": [T: "barra vertical com pena à esquerda"] + - "⸡": [T: "barra vertical com pena à direita"] + - "⸢": [T: "superior esquerda metade colchete"] + - "⸣": [T: "superior direita metade colchete"] + - "⸤": [T: "inferior esquerda metade colchete"] + - "⸥": [T: "inferior direita metade colchete"] + - "⸦": [T: "abre colchete de lado u"] + - "⸧": [T: "fecha colchete de lado u"] + - "⸨": [T: "esquerda parênteses duplos"] + - "⸩": [T: "direita parênteses duplos"] + - "⸪": [T: "dois pontos sobre um ponto pontuação"] + - "⸫": [T: "um ponto sobre dois pontos pontuação"] + - "⸬": [T: "quatro ponto pontuação enquadrado"] + - "⸭": [T: "cinco ponto marca"] + - "⸮": [T: "ponto invertido de interrogação"] + - "ⸯ": [T: "til vertical"] + - "⸰": [T: "anel ponto"] + - "⸱": [T: "separador de palavras do meio ponto"] + - "⸲": [T: "invertido vírgula"] + - "⸳": [T: "elevado ponto"] + - "⸴": [T: "elevado vírgula"] + - "⸵": [T: "ponto invertido e vírgula"] + - "⸶": [T: "adaga com esquerda guarda"] + - "⸷": [T: "adaga com direita guarda"] + - "⸸": [T: "invertido adaga"] + - "⸹": [T: "superior metade seção sinal"] + - "⸺": [T: "dois em travessão"] + - "⸻": [T: "três em travessão"] + - "〃": [T: "idem marca"] + - "〈": [T: "abre colchete angular"] + - "〉": [T: "fecha colchete angular"] + - "《": [T: "abre colchete angular duplo"] + - "》": [T: "fecha colchete angular duplo"] + - "「": [T: "abre colchete canto"] + - "」": [T: "fecha colchete canto"] + - "『": [T: "abre colchete branco canto"] + - "』": [T: "fecha colchete branco canto"] + - "【": [T: "abre colchete preto lenticular"] + - "】": [T: "fecha colchete preto lenticular"] + - "〔": [T: "abre colchete concha de tartaruga"] + - "〕": [T: "fecha colchete concha de tartaruga"] + - "〖": [T: "abre colchete branco lenticular"] + - "〗": [T: "fecha colchete branco lenticular"] + - "〘": [T: "abre colchete branco concha de tartaruga"] + - "〙": [T: "fecha colchete branco concha de tartaruga"] + - "〚": [T: "abre colchete branco quadrado"] + - "〛": [T: "fecha colchete branco quadrado"] + - "〜": [T: "ondulado travessão"] + - "〰": [T: "ondulado travessão"] + - "㉈": [T: "dez sobre preto quadrado circulado"] + - "㉉": [T: "vinte sobre preto quadrado circulado"] + - "㉊": [T: "trinta sobre preto quadrado circulado"] + - "㉋": [T: "quarenta sobre pretos quadrado circulado"] + - "㉌": [T: "cinquenta sobre preto quadrado circulado"] + - "㉍": [T: "sessenta sobre preto quadrado circulado"] + - "㉎": [T: "setenta sobre preto quadrado circulado"] + - "㉏": [T: "oitenta sobre preto quadrado circulado"] + - "㉑": [T: "vinte um circulado"] + - "㉒": [T: "vinte dois circulado"] + - "㉓": [T: "vinte três circulado"] + - "㉔": [T: "vinte quatro circulado"] + - "㉕": [T: "vinte cinco circulado"] + - "㉖": [T: "vinte seis circulado"] + - "㉗": [T: "vinte sete circulado"] + - "㉘": [T: "vinte oito circulado"] + - "㉙": [T: "vinte nove circulado"] + - "㉚": [T: "trinta circulado"] + - "㉛": [T: "trinta um circulado"] + - "㉜": [T: "trinta dois circulado"] + - "㉝": [T: "trinta três circulado"] + - "㉞": [T: "trinta quatro circulado"] + - "㉟": [T: "trinta cinco circulado"] + - "㊱": [T: "trinta seis circulado"] + - "㊲": [T: "trinta sete circulado"] + - "㊳": [T: "trinta oito circulado"] + - "㊴": [T: "trinta nove circulado"] + - "㊵": [T: "quarenta circulado"] + - "㊶": [T: "quarenta um circulado"] + - "㊷": [T: "quarenta dois circulado"] + - "㊸": [T: "quarenta três circulado"] + - "㊹": [T: "quarenta quatro circulado"] + - "㊺": [T: "quarenta cinco circulado"] + - "㊻": [T: "quarenta seis circulado"] + - "㊼": [T: "quarenta sete circulado"] + - "㊽": [T: "quarenta oito circulado"] + - "㊾": [T: "quarenta nove circulado"] + - "㊿": [T: "cinquenta circulado"] + - "㋌": [T: "mercúrio"] + - "㋍": [T: "ergs"] + - "㋎": [T: "elétron volts"] + - "㋏": [T: "limitado responsabilidade sinal"] + - "㍱": [T: "hectopascals"] + - "㍲": [T: "daltons"] + - "㍳": [T: "unidades astronômicas"] + - "㍴": [T: "barras"] + - "㍵": [T: "o vê"] + - "㍶": [T: "parsecs"] + - "㍷": [T: "decimetros"] + - "㍸": [T: "decímetros ao quadrado"] + - "㍹": [T: "decímetros ao cubo"] + - "㍺": [T: "instrumental unidades"] + - "㎀": [T: "picoampères"] + - "㎁": [T: "nanoampères"] + - "㎂": [T: "microampères"] + - "㎃": [T: "miliampères"] + - "㎄": [T: "quiloampères"] + - "㎅": [T: "quilobytes"] + - "㎆": [T: "megabytes"] + - "㎇": [T: "gigabytes"] + - "㎈": [T: "calorias"] + - "㎉": [T: "quilocalorias"] + - "㎊": [T: "picofarads"] + - "㎋": [T: "nanofarads"] + - "㎌": [T: "microfarads"] + - "㎍": [T: "microgramas"] + - "㎎": [T: "miligramas"] + - "㎏": [T: "quilogramas"] + - "㎐": [T: "hertz"] + - "㎑": [T: "quilohertz"] + - "㎒": [T: "megahertz"] + - "㎓": [T: "gigahertz"] + - "㎔": [T: "terahertz"] + - "㎕": [T: "microlitros"] + - "㎖": [T: "mililitros"] + - "㎗": [T: "decilitros"] + - "㎘": [T: "quilolitros"] + - "㎙": [T: "femtometros"] + - "㎚": [T: "nanometros"] + - "㎛": [T: "micrometros"] + - "㎜": [T: "milimetros"] + - "㎝": [T: "centimetros"] + - "㎞": [T: "quilometros"] + - "㎟": [T: "milímetros ao quadrado"] + - "㎠": [T: "centímetros ao quadrado"] + - "㎡": [T: "metros ao quadrado"] + - "㎢": [T: "quilômetros ao quadrado"] + - "㎣": [T: "milímetros ao cubo"] + - "㎤": [T: "centímetros ao cubo"] + - "㎥": [T: "metros ao cubo"] + - "㎦": [T: "quilômetros ao cubo"] + - "㎧": [T: "metros por segundo"] + - "㎨": [T: "metros por segundo ao quadrado"] + - "㎩": [T: "pascals"] + - "㎪": [T: "quilopascals"] + - "㎫": [T: "megapascals"] + - "㎬": [T: "gigapascals"] + - "㎭": [T: "radianos"] + - "㎮": [T: "radianos por segundo"] + - "㎯": [T: "radianos por segundo ao quadrado"] + - "㎰": [T: "picosegundos"] + - "㎱": [T: "nanosegundos"] + - "㎲": [T: "microsegundos"] + - "㎳": [T: "milisegundos"] + - "㎴": [T: "picovolts"] + - "㎵": [T: "nanovolts"] + - "㎶": [T: "microvolts"] + - "㎷": [T: "milivolts"] + - "㎸": [T: "quilovolts"] + - "㎹": [T: "megavolts"] + - "㎺": [T: "picowatts"] + - "㎻": [T: "nanowatts"] + - "㎼": [T: "microwatts"] + - "㎽": [T: "miliwatts"] + - "㎾": [T: "quilowatts"] + - "㎿": [T: "megawatts"] + - "㏀": [T: "quiloohms"] + - "㏁": [T: "megaohms"] + - "㏂": [T: "atometros"] + - "㏃": [T: "becquereis"] + - "㏄": [T: "cúbico centímetros"] + - "㏅": [T: "candelas"] + - "㏆": [T: "coulombs por quilograma"] + - "㏇": [T: "maiúscula C, o, ponto final"] + - "㏈": [T: "decibéis"] + - "㏉": [T: "grays"] + - "㏊": [T: "hectares"] + - "㏋": [T: "cavalo-vapor"] + - "㏌": [T: "polegadas"] + - "㏍": [T: "quilokelvins"] + - "㏎": [T: "quilometros"] + - "㏏": [T: "nós"] + - "㏐": [T: "lúmens"] + - "㏑": [T: "logaritmo natural"] + - "㏒": [T: "logaritmo"] + - "㏓": [T: "lux"] + - "㏔": [T: "milibarns"] + - "㏕": [T: "mills"] + - "㏖": [T: "moles"] + - "㏗": [T: "pê agá"] + - "㏘": [T: "picometros"] + - "㏙": [T: "partes por milhão"] + - "㏚": [T: "petaroentgens"] + - "㏛": [T: "esferorradianos"] + - "㏜": [T: "sieverts"] + - "㏝": [T: "webers"] + - "㏞": [T: "volts por metro"] + - "㏟": [T: "ampères por metro"] + - "㏿": [T: "galões"] + - "": [T: "igual com chapéu abaixo de"] + - "": [T: "igual com mais acima de"] + - "": [T: "igual com mais abaixo de"] + - "": [T: "til com mais acima de"] + - "": [T: "til com mais abaixo de"] + - "": [T: "igual duplo sobre maior que"] + - "": [T: "igual duplo sobre menor que"] + - "": [T: "contém ou igual a"] + - "": [T: "contém ou igual a"] + - "": [T: "contido em ou igual a"] + - "": [T: "igual sobre menor que"] + - "": [T: "pertence a ou igual a"] + - "": [T: "igual a ou maior que"] + - "": [T: "aproximado contém"] + - "": [T: "aproximado contido em"] + - "": [T: "contém com ponto inclui como sub relação"] + - "": [T: "contido em com ponto é incluído em como sub relação"] + - "": [T: "igual com ponto abaixo de"] + - "": [T: "ponto sobre menos sobre ponto à direita à esquerda"] + - "": [T: "ponto sobre menos sobre ponto à esquerda à direita"] + - "": [T: "quase igual a menos"] + - "": [T: "quadrado duplo xícara"] + - "": [T: "quadrado duplo maiúscula"] + - "": [T: "menor que igual a ou maior que"] + - "": [T: "til com ponto"] + - "": [T: "til com dois pontos"] + - "": [T: "menor que maior ou igual a"] + - "": [T: "maior que menor ou igual a"] + - "": [T: "equivalente a ou menor que"] + - "": [T: "equivalente a ou maior que"] + - "": [T: "esquerda aberto caixa operador"] + - "": [T: "direita aberto caixa operador"] + - "": [T: "idêntico a com ponto"] + - "": [T: "maior que igual a ou menor que"] + - "": [T: "operador barra"] + - "": [T: "operador duplo barra"] + - "": [T: "operador triplo barra"] + - "": [T: "menor que ou aproximadamente igual a"] + - "": [T: "maior que ou aproximadamente igual a"] + - "": [T: "aninhado menor que"] + - "": [T: "aninhado maior que"] + - "": [T: "precede ou equivalente a"] + - "": [T: "sucede ou equivalente a"] + - "": [T: "precede sobre igual"] + - "": [T: "sucede sobre igual"] + - "": [T: "menor igual inclinado maior"] + - "": [T: "maior igual inclinado menor"] + - "": [T: "satisfeito por"] + - "": [T: "deitado esse"] + - "": [T: "não asserção"] + - "": [T: "duplo igual"] + - "": [T: "triplo igual"] + - "": [T: "régua atrasado"] + - "": [T: "alias delimitador"] + - "": [T: "subgrupo normal de com barra"] + - "": [T: "contém como subgrupo normal com barra"] + - "": [T: "implica arredondado"] + - "": [T: "sorriso barra inferior"] + - "": [T: "carranca barra superior"] + - "": [T: "contém ou quase igual a"] + - "": [T: "contido em ou quase igual a"] + - "": [T: "maior que quase igual a ou menor que"] + - "": [T: "menor que quase igual ou maior que"] + - "": [T: "duplo ou lógico"] + - "": [T: "duplo e lógico"] + - "": [T: "ou lógico com barra dupla abaixo de"] + - "": [T: "ou lógico com barra abaixo de"] + - "": [T: "quase igual sobre igual"] + - "": [T: "triângulo esquerda apontando com bissectando barra"] + - "": [T: "triângulo direita apontando com bissectando barra"] + - "": [T: "igual com linha pontilhada superior"] + - "": [T: "precede com dois pontos"] + - "": [T: "sucede com dois pontos"] + - "": [T: "menor que ou igual inclinado"] + - "": [T: "maior que ou igual inclinado"] + - "": [T: "aninhado muito muito menor que"] + - "": [T: "aninhado muito muito maior que"] + - "": [T: "diferença entre variante"] + - "": [T: "menor que maior que sobreposto"] + - "": [T: "ou lógico e lógico sobreposto"] + - "": [T: "contendo sobre contendo"] + - "": [T: "contido sobre contido"] + - "": [T: "contendo sobre contido"] + - "": [T: "contido sobre contendo"] + - "": [T: "barra tripla vertical"] + - "": [T: "pontos pareados quádruplos verticales"] + - "": [T: "perpendicular barra superior"] + - "": [T: "catraca barra dupla vertical à esquerda"] + - "": [T: "duplo catraca barra dupla vertical à esquerda"] + - "": [T: "perpendicular sobre invertido perpendicular"] + - "": [T: "duplo catraca barra vertical à esquerda"] + - "": [T: "ângulo esférico abrindo cima"] + - "": [T: "barra dupla"] + - "": [T: "ângulo com canto à direita"] + - "": [T: "barra vertical circulado"] + - "": [T: "sinal de divisão circulado"] + - "": [T: "barra tracejada"] + - "": [T: "barra tracejada invertida"] + - "": [T: "linha tracejada média"] + - "": [T: "barra tracejada vertical"] + - "": [T: "perpendicular com esse"] + - "": [T: "ângulo com esse"] + - "": [T: "ângulo esférico abrindo esquerda"] + - "": [T: "ângulo abrindo esquerda"] + - "": [T: "barra vertical com gancho duplo"] + - "": [T: "ponto médio operador radical livre"] + - "": [T: "triângulo branco cima apontando acima de barra"] + - "": [T: "idêntico e paralelo a"] + - "": [T: "produto esmagado"] + - "": [T: "operador triplo barra com barra horizontal"] + - "": [T: "idêntico a com barra dupla"] + - "": [T: "barras triplas cruzadas"] + - "": [T: "círculo vertical barra sobre"] + - "": [T: "vertical proporcional a"] + - "": [T: "preto último um quarto lua"] + - "": [T: "preto primeiro um quarto lua"] + - "": [T: "negativo seno ondulado"] + - "": [T: "ponto entre parênteses"] + - "": [T: "parênteses"] + - "": [T: "branco sorriso"] + - "": [T: "branco carranca"] + - "": [T: "hexágono"] + - "": [T: "equivalente a sobre mais"] + - "": [T: "mais sobre equivalente a"] + - "": [T: "interseção serifas"] + - "": [T: "união serifas"] + - "": [T: "quadrado interseção serifas"] + - "": [T: "quadrado união serifas"] + - "": [T: "precede equivalente a ou sucede"] + - "": [T: "sucede equivalente a ou precede"] + - "": [T: "precede quase igual a ou sucede"] + - "": [T: "sucede quase igual a ou precede"] + - "": [T: "menor que equivalente a ou maior que"] + - "": [T: "maior que equivalente a ou menor que"] + - "": [T: "não vertical muito menor que"] + - "": [T: "não vertical muito maior que"] + - "": [T: "não muito menor que variante"] + - "": [T: "não muito maior que variante"] + - "": [T: "menor vertical não duplo igual"] + - "": [T: "maior que vertical não duplo igual"] + - "": [T: "não menor ou igual a"] + - "": [T: "não maior ou igual a"] + - "": [T: "nem igual a nem menor que"] + - "": [T: "não contém ou igual a"] + - "": [T: "nem contém nem igual a"] + - "": [T: "nem contido em nem igual a"] + - "": [T: "barra invertida contido"] + - "": [T: "nem igual a nem maior que"] + - "": [T: "não menos operador til"] + - "": [T: "nem igual a nem menor que"] + - "": [T: "não operador til"] + - "": [T: "não pertence a ou igual a"] + - "": [T: "nem igual a nem maior que"] + - "": [T: "não quase igual"] + - "": [T: "não sucede semelhante"] + - "": [T: "menor que ou inclinado igual a com barra"] + - "": [T: "maior que ou inclinado igual a com barra"] + - "": [T: "contendo barra"] + - "": [T: "não contém"] + - "": [T: "não menor ou igual a"] + - "": [T: "não maior ou igual a"] + - "": [T: "não quase igual a menos"] + - "": [T: "negado conjunto pertinência ponto acima de"] + - "": [T: "não ângulo vertical"] + - "": [T: "não paralelo inclinado"] + - "": [T: "não operador barra"] + - "": [T: "não operador duplo barra"] + - "": [T: "não operador triplo barra"] + - "": [T: "menor que mas não aproximadamente igual a"] + - "": [T: "maior que mas não aproximadamente igual a"] + - "": [T: "menor que ou não igual a"] + - "": [T: "maior que ou não igual a"] + - "": [T: "não aninhado menor que"] + - "": [T: "não aninhado maior que"] + - "": [T: "não muito menor que"] + - "": [T: "não muito maior que"] + - "": [T: "precede mas não equivalente a"] + - "": [T: "sucede mas não equivalente a"] + - "": [T: "precede mas não igual a"] + - "": [T: "sucede mas não igual a"] + - "": [T: "não igual ou precede"] + - "": [T: "não igual ou sucede"] + - "": [T: "precede mas não igual a"] + - "": [T: "sucede mas não igual a"] + - "": [T: "não contido em nem igual a"] + - "": [T: "não contém nem igual a"] + - "": [T: "contido em ou não igual a"] + - "": [T: "contém ou não igual a"] + - "": [T: "não contido em nem igual a"] + - "": [T: "não contém nem igual a"] + - "": [T: "não triplo menor que"] + - "": [T: "não triplo maior que"] + - "": [T: "não precede igual"] + - "": [T: "não sucede igual"] + - "": [T: "não subgrupo normal de com barra"] + - "": [T: "não contém como subgrupo normal com barra"] + - "": [T: "não diferença entre"] + - "": [T: "não geometricamente equivalente a"] + - "": [T: "não vertical semelhante"] + - "": [T: "não igual ou semelhante"] + - "": [T: "não vertical aproximado"] + - "": [T: "não aproximadamente idêntico a"] + - "": [T: "não irregular igual"] + - "": [T: "não irregular simples igual"] + - "": [T: "não igual ponto"] + - "": [T: "invertido não equivalente"] + - "": [T: "quadrado não contido"] + - "": [T: "quadrado não contendo"] + - "": [T: "não quase igual sobre igual"] + - "": [T: "não estritamente equivalente a"] + - "": [T: "não congruente ponto"] + - "": [T: "invertido não igual"] + - "": [T: "triângulo não vertical esquerda igual"] + - "": [T: "triângulo não vertical direita igual"] + - "": [T: "não parcial"] + - "": [T: "seta extensor"] + - "": [T: "seta para a direita sobre seta esquerda"] + - "": [T: "seta para a direita sobre seta esquerda"] + - "": [T: "arpão para a direita sobre arpão esquerda"] + - "": [T: "arpão para a direita sobre arpão esquerda"] + - "": [T: "seta dupla para nordeste e para sudoeste"] + - "": [T: "seta dupla para noroeste e para sudeste"] + - "": [T: "arpão horizontal extensor"] + - "": [T: "seta no sentido anti-horário arco para a esquerda"] + - "": [T: "seta no sentido anti-horário arco para a direita"] + - "": [T: "seta grande para a direita acento"] + - "": [T: "seta grande para a esquerda acento"] + - "": [T: "ponta de seta à esquerda"] + - "": [T: "ponta de seta à direita"] + - "": [T: "seta grande para a esquerda e para a direita com traço"] + - "": [T: "seta horizontal dupla extensor"] + - "": [T: "seta grande dupla para a esquerda e para a direita com traço"] + - "": [T: "seta para baixo à esquerda de seta para cima"] + - "": [T: "seta para a esquerda com canto baixo"] + - "": [T: "seta para a direita com canto cima"] + - "": [T: "seta para a esquerda com canto cima"] + - "": [T: "seta semicircular superior no sentido anti-horário com mais"] + - "": [T: "seta semicircular superior no sentido horário com menos"] + - "": [T: "seta para a direita com cauda com traço"] + - "": [T: "arpão para a direita com farpa para baixo"] + - "": [T: "arpão para a esquerda com farpa para baixo"] + - "": [T: "arpão para a esquerda e para a direita baixo"] + - "": [T: "arpão para a esquerda e para a direita cima"] + - "": [T: "arpão para cima e para baixo esquerda"] + - "": [T: "arpão para cima e para baixo direita"] + - "": [T: "seta para cima à direita de baixo seta"] + - "": [T: "arpão para a esquerda a barra com farpa cima"] + - "": [T: "arpão para a direita a barra com farpa cima"] + - "": [T: "arpão para a esquerda a barra com farpa baixo"] + - "": [T: "arpão para a direita a barra com farpa baixo"] + - "": [T: "arpão para a esquerda a partir de barra com farpa cima"] + - "": [T: "arpão para a direita a partir de barra com farpa cima"] + - "": [T: "arpão para a esquerda a partir de barra com farpa baixo"] + - "": [T: "arpão para a direita a partir de barra com farpa baixo"] + - "": [T: "arpão para cima a barra com farpa esquerda"] + - "": [T: "arpão para baixo a barra com farpa esquerda"] + - "": [T: "arpão para cima a barra com farpa direita"] + - "": [T: "arpão para baixo a barra com farpa direita"] + - "": [T: "arpão para cima a partir de barra com farpa esquerda"] + - "": [T: "arpão para baixo a partir de barra com farpa esquerda"] + - "": [T: "arpão para cima a partir de barra com farpa direita"] + - "": [T: "arpão para baixo a partir de barra com farpa direita"] + - "": [T: "seta para cima a barra"] + - "": [T: "seta para baixo a barra"] + - "": [T: "arpão para cima à esquerda de baixo arpão"] + - "": [T: "arpão para cima à direita de baixo arpão"] + - "": [T: "ponta de seta para cima"] + - "": [T: "ponta de seta para baixo"] + - "": [T: "arpão duplo com esquerda farpa baixo direita farpa cima"] + - "": [T: "arpão duplo com esquerda farpa cima direita farpa baixo"] + - "": [T: "seta para a esquerda barra superior"] + - "": [T: "seta para a direita barra superior"] + - "": [T: "seta para a esquerda barra inferior"] + - "": [T: "seta para a direita barra inferior"] + - "": [T: "seta tripla para a esquerda e para a direita"] + - "": [T: "seta dupla para nordeste e para sudeste"] + - "": [T: "seta semicircular no sentido anti-horário para a esquerda"] + - "": [T: "seta semicircular no sentido horário para a esquerda"] + - "": [T: "seta esquerda aberta círculo para a esquerda e para a direita"] + - "": [T: "seta para a direita sobre til"] + - "": [T: "seta para a esquerda sobre til"] + - "": [T: "arpão para a esquerda barra superior"] + - "": [T: "arpão para a direita barra superior"] + - "": [T: "arpão para a esquerda barra inferior"] + - "": [T: "arpão para a direita barra inferior"] + - "": [T: "seta achatado preta para a esquerda"] + - "": [T: "seta semicircular no sentido horário para a direita"] + - "": [T: "seta semicircular no sentido anti-horário para a direita"] + - "": [T: "arpão esquerda aberto círculo para a esquerda e para a direita"] + - "": [T: "seta para cima esquerda de barra vertical"] + - "": [T: "seta para baixo esquerda de barra vertical"] + - "": [T: "seta para cima direita de barra vertical"] + - "": [T: "seta para baixo direita de barra vertical"] + - "": [T: "seta para a direita com estendido baixo gancho"] + - "": [T: "seta para a esquerda com estendido gancho"] + - "": [T: "seta para a esquerda com estendido baixo gancho"] + - "": [T: "seta para a direita com estendido gancho"] + - "": [T: "seta não para a direita ondulado"] + - "": [T: "seta não para a direita curvo"] + - "": [T: "arpão para cima esquerda de barra vertical"] + - "": [T: "arpão para baixo esquerda de barra vertical"] + - "": [T: "arpão para cima direita de barra vertical"] + - "": [T: "arpão para baixo direita de barra vertical"] + - "": [T: "seta vertical dupla extensor"] + - "": [T: "arpão vertical com farpa esquerda extensor"] + - "": [T: "arpão vertical com farpa direita extensor"] + - "": [T: "arpão para a direita sobre esquerda arpão direita"] + - "": [T: "arpão para a direita sobre esquerda arpão esquerda"] + - "": [T: "arpão para a esquerda sobre direita arpão direita"] + - "": [T: "arpão para a esquerda sobre direita arpão esquerda"] + - "": [T: "seta para a esquerda a partir de barra ponta de seta"] + - "": [T: "seta para a esquerda e para a direita a partir de barra extensor"] + - "": [T: "seta para a esquerda a partir de barra cauda"] + - "": [T: "seta para a direita a partir de barra cauda"] + - "": [T: "seta para a direita a partir de barra ponta de seta"] + - "": [T: "arpão para cima a partir de barra com farpa esquerda ponta de seta"] + - "": [T: "seta para a direita sobre esquerda seta direita"] + - "": [T: "seta para a direita sobre esquerda seta esquerda"] + - "": [T: "seta para a esquerda sobre direita seta direita"] + - "": [T: "seta para a esquerda sobre direita seta esquerda"] + - "": [T: "seta para cima a partir de barra ponta de seta"] + - "": [T: "seta para cima a partir de barra cauda"] + - "": [T: "seta para baixo a partir de barra cauda"] + - "": [T: "seta para baixo a partir de barra ponta de seta"] + - "": [T: "arpão para baixo a partir de barra com farpa direita ponta de seta"] + - "": [T: "arpão para cima à esquerda de baixo arpão inferior"] + - "": [T: "arpão para cima à esquerda de baixo arpão extensor"] + - "": [T: "arpão para baixo à esquerda de cima arpão superior"] + - "": [T: "arpão para cima à esquerda de baixo arpão superior"] + - "": [T: "arpão para baixo à esquerda de o cima arpão extensor"] + - "": [T: "arpão para baixo à esquerda de o cima arpão inferior"] + - "": [T: "seta para cima esquerda de baixo seta inferior"] + - "": [T: "seta para baixo esquerda de cima seta superior"] + - "": [T: "seta para cima esquerda de baixo seta superior"] + - "": [T: "seta para baixo esquerda de cima seta inferior"] + - "": [T: "setas para a esquerda e para a direita extensor"] + - "": [T: "seta para nordeste extensor"] + - "": [T: "seta para noroeste extensor"] + - "": [T: "baixo apontando chave esquerda"] + - "": [T: "baixo apontando chave médio"] + - "": [T: "baixo apontando chave direita"] + - "": [T: "chave horizontal extensor"] + - "": [T: "cima apontando chave esquerda"] + - "": [T: "cima apontando chave médio"] + - "": [T: "apontando para chave direita para cima"] + - "": [T: "barra vertical à esquerda"] + - "": [T: "barra vertical à direita"] + - "": [T: "esquerda barra dupla vertical"] + - "": [T: "direita barra dupla vertical"] + - "": [T: "colchete horizontal extensor"] + - "": [T: "quadrado sob colchete"] + - "⎵": [T: "quadrado sob colchete"] + - "": [T: "quadrado sobre colchete"] + - "⎴": [T: "quadrado sobre colchete"] + - "": [T: "sob colchete esquerda"] + - "": [T: "sob colchete direita"] + - "": [T: "sobre colchete esquerda"] + - "": [T: "sobre colchete direita"] + - "": [T: "abre parênteses 1"] + - "": [T: "abre parênteses 2"] + - "": [T: "abre parênteses 3"] + - "": [T: "abre parênteses 4"] + - "": [T: "fecha parênteses 1"] + - "": [T: "fecha parênteses 2"] + - "": [T: "fecha parênteses 3"] + - "": [T: "fecha parênteses 4"] + - "": [T: "radical 1"] + - "": [T: "radical 2"] + - "": [T: "radical 3"] + - "": [T: "radical 4"] + - "": [T: "radical 5"] + - "": [T: "radical inferior"] + - "": [T: "radical extensor vertical"] + - "": [T: "radical superior"] + - "": [T: "esquerda colchete branco superior"] + - "": [T: "esquerda colchete branco extensor"] + - "": [T: "esquerda colchete branco inferior"] + - "": [T: "direita colchete branco superior"] + - "": [T: "direita colchete branco extensor"] + - "": [T: "direita colchete branco inferior"] + - "": [T: "abre colchete branco encaracolado"] + - "": [T: "fecha colchete branco encaracolado"] + - "": [T: "sinal longo de divisão"] + - "": [T: "sinal longo de divisão extensor"] + - "": [T: "divisão curta"] + - "": [T: "duplo sudoeste a nordeste ligação em"] + - "": [T: "duplo noroeste a sudeste ligação em"] + - "": [T: "simples horizontal ligação em"] + - "": [T: "duplo horizontal ligação em"] + - "": [T: "triplo horizontal ligação em"] + - "": [T: "simples vertical ligação em"] + - "": [T: "duplo vertical ligação em"] + - "": [T: "triplo vertical ligação em"] + - "": [T: "menor que ligação em"] + - "": [T: "maior que ligação em"] + - "": [T: "simples horizontal ligação en"] + - "": [T: "duplo horizontal ligação en"] + - "": [T: "triplo horizontal ligação en"] + - "": [T: "retângulo superior esquerda"] + - "": [T: "retângulo inferior esquerda"] + - "": [T: "retângulo superior direita"] + - "": [T: "retângulo inferior direita"] + - "": [T: "divisão sintética canto"] + - "": [T: "divisão sintética extensor horizontal"] + - "": [T: "divisão sintética extensor vertical"] + - "": [T: "esquerda teto piso extensor"] + - "": [T: "direita teto piso extensor"] + - "": [T: "sobre colchete extensor"] + - "": [T: "barra extensor vertical"] + - "": [T: "esquerda barra dupla extensor vertical"] + - "": [T: "barra extensor horizontal"] + - "": [T: "sob colchete extensor"] + - "": [T: "baixo apontando parêntese direita"] + - "": [T: "baixo apontando parêntese extensor"] + - "": [T: "baixo apontando parêntese esquerda"] + - "": [T: "cima apontando chave extensor"] + - "": [T: "cima apontando parêntese esquerda"] + - "": [T: "cima apontando parêntese extensor"] + - "": [T: "cima apontando parêntese direita"] + - "": [T: "baixo apontando chave extensor"] + - "": [T: "planck constante sobre dois pi barra"] + - "": [T: "g espelhado"] + - "": [T: "sem ponto jota"] + - "": [T: "digama"] + - "ϝ": [T: "digama"] + - "": [T: "dê"] + - "": [T: "e"] + - "": [T: "i"] + - "": [T: "jota"] + - "ⅅ": + - spell: "translate('.', 'ⅅ', 'DD')" # 0xed16, 0x2145 + - "": [T: "no sentido anti-horário contorno integral laço"] + - "": [T: "no sentido horário contorno integral laço"] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: "junção status"] + - "": [T: "junção status esquerda"] + - "": [T: "junção status direita"] + - "": [T: "junção status extensor"] + - "": [T: "integral laço"] + - "": [T: "integral laço duplo"] + - "": [T: "integral laço triplo"] + - "": [T: "expandindo integral laço duplo"] + - "": [T: "expandindo integral laço triplo"] + - "": [T: "assintoticamente igual a acento"] + - "": [T: "sinal de igual acento"] + - "": [T: "linha quádrupla"] + - "": [T: "círculo barra acento com aberto esquerda"] + - "": [T: "círculo barra acento com fechado esquerda"] + - "": [T: "círculo barra acento com aberto direita"] + - "": [T: "barra acento com sobre ponto"] + - "": [T: "barra acento com sob ponto"] + - "": [T: "barra acento com duplo sobre ponto"] + - "": [T: "barra acento com duplo sob ponto"] + - "": [T: "barra acento com circunflexo"] + - "": [T: "barra espessa acento inferior"] + - "": [T: "círculo barra acento com fechado direita"] + - "": [T: "ponto grande acima de"] + - "": [T: "alinhamento marca"] + - "": [T: ""] + - "​": [T: ""] + - "": [T: ""] + - " ": [T: ""] + - "": [T: ""] + - " ": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - " ": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: "ausente termo"] + - "": [T: "seta no sentido horário contorno integral sobre esquerda"] + - "": [T: "quadrado integral com"] + - "": [T: "integral com barra"] + - "": [T: "integral invertida"] + - "": [T: "duplo zero sobre duplo zero"] + - "": [T: "zero com barra"] + - "-": + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "maiúscula"] + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "ligadura a e"] + - "": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "maiúscula"] + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "sustenido esse"] + - "": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "maiúscula"] + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "o com traço"] + - "": + - spell: "translate('.', '', 'ΔΨΛΠΣΘΓΩΥ')" + - T: "vazado" + - "-": + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - T: "vazado" + - "": [T: "vazado final sigma"] + - "": [T: "vazado rô"] + - "": [T: "vazado fi"] + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝐴-𝑍": + - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝑎-𝑧": + - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" + - "-": + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝖠-𝖹": + - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝖺-𝗓": + - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" + - "-": + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝗔-𝗭": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝗮-𝘇": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝘈-𝘡": + - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝘢-𝘻": + - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" + - "-": + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝘼-𝙕": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝙖-𝙯": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝙰-𝚉": + - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝚊-𝚣": + - spell: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" + - "-": + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "": [T: "sem ponto i"] + - "𝚤": [T: "sem ponto i"] + - "𝚥": [T: "sem ponto jota"] + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "": [T: "em negrito nábela"] + - "𝛁": [T: "em negrito nábela"] + - "𝛛𝛜𝛝𝛞𝛟𝛠𝛡": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" + - "": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', '∂εθκφρπ')" + - "𝛢-𝛺": + - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "-": + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "𝛼-𝜔": + - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓𝜔', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "-": + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "": [T: "itálico nábela"] + - "𝛻": [T: "itálico nábela"] + - "𝜕𝜖𝜗𝜘𝜙𝜚𝜛": + - spell: "translate('.', '𝜕𝜖𝜗𝜘𝜙𝜚𝜛', '∂εθκφρπ')" + - "": + - spell: "translate('.', '', '∂εθκφρπ')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εθκφρπ')" + - "": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', '∂εθκφρπ')" + - "𝜵": [T: "em negrito itálico nábela"] + - "": [T: "em negrito itálico nábela"] + - "𝝖-𝝮": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "𝝰-𝞈": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇𝞈', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "𝞉𝞊𝞋𝞌𝞍𝞎𝞏": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝞉𝞊𝞋𝞌𝞍𝞎𝞏', '∂εθκφρπ')" + - "": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', '∂εθκφρπ')" + - "": [T: "em negrito nábela"] + - "𝝯": [T: "em negrito nábela"] + - "𝞐-𝞨": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "𝞪-𝟂": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝟃𝟄𝟅𝟆𝟇𝟈𝟉', '∂εθκφρπ')" + - "": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', '∂εθκφρπ')" + - "": [T: "em negrito nábela"] + - "𝞩": [T: "em negrito nábela"] + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', '0123456789')" + - "𝟎-𝟗": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', '0123456789')" + - "𝟬-𝟵": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" + - "-": + - spell: "translate('.', '', '0123456789')" + - "𝟢-𝟫": + - spell: "translate('.', '𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫', '0123456789')" + - "𝟶-𝟿": + - spell: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" + - "": [T: "desconhecido caractere"] + - "": [T: "triângulos inferior direita e inferior esquerda"] + - "": [T: "horizontal reticências extensor"] + - "": [T: "linha média horizontal reticências extensor"] + - "": [T: "radical extensor"] + - "": [T: "seta vertical extensor"] + - "": [T: "seta horizontal extensor"] + - "": [T: "registrado sinal sem serifa"] + - "": [T: "direitos autorais sinal sem serifa"] + - "": [T: "marca registrada sinal sem serifa"] + - "": [T: "parêntese superior à esquerda"] + - "": [T: "parêntese extensor à esquerda"] + - "": [T: "parêntese inferior à esquerda"] + - "": [T: "colchete superior à esquerda"] + - "": [T: "colchete extensor à esquerda"] + - "": [T: "colchete inferior à esquerda"] + - "": [T: "chave superior à esquerda"] + - "": [T: "chave médio à esquerda"] + - "": [T: "chave inferior à esquerda"] + - "": [T: "chave extensor"] + - "": [T: "integral extensor"] + - "": [T: "parêntese superior à direita"] + - "": [T: "parêntese extensor à direita"] + - "": [T: "parêntese inferior à direita"] + - "": [T: "colchete superior à direita"] + - "": [T: "colchete extensor à direita"] + - "": [T: "colchete inferior à direita"] + - "": [T: "chave superior à direita"] + - "": [T: "chave médio à direita"] + - "": [T: "chave inferior à direita"] + - "": [T: "logo da apple"] + - "ff": [T: "ligadura ff"] + - "fi": [T: "ligadura fi"] + - "fl": [T: "ligadura fl"] + - "ffi": [T: "ligadura ffi"] + - "ffl": [T: "ligadura ffl"] + - "ſt": [T: "pés"] + - "st": [T: "st"] + - "﬩": [T: "letra hebraica alternativa mais"] + - "︠": [T: "ligadura esquerda metade"] + - "︡": [T: "ligadura direita metade"] + - "︢": [T: "til duplo esquerda metade"] + - "︣": [T: "til duplo direita metade"] + - "︤": [T: "mácron esquerda metade"] + - "︥": [T: "mácron direita metade"] + - "︦": [T: "conjugando mácron"] + - "︵": [T: "sobre parêntese"] + - "︶": [T: "sob parêntese"] + - "︷": [T: "sobre chave"] + - "︸": [T: "sob chave"] + - "︿": [T: "sobre colchete angular"] + - "﹀": [T: "sob colchete angular"] + - "﹡": [T: "pequeno asterisco"] + - "﹢": [T: "pequeno mais"] + - "﹣": [T: "pequeno menos"] + - "﹤": [T: "pequeno menor que"] + - "﹥": [T: "pequeno maior que"] + - "﹦": [T: "pequeno igual"] + - "+": [T: "de largura total sinal de mais"] + - "<": [T: "menor que"] + - "=": [T: "igual"] + - ">": [T: "maior que"] + - "\": [T: "barra invertida"] + - "^": [T: "chapéu"] + - "|": + - with: + variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) + replace: + - test: + - if: "$SpeechStyle != 'ClearSpeak'" + then_test: + if: "$DefaultToGiven" + then: [T: "dado"] + else: [T: "barra vertical"] + - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" + then: [T: "barra vertical"] + - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" + then: [T: "tal que"] + - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" + then: [T: "dado"] + - else: [T: "divide"] + - "~": [T: "til"] + - "¬": [T: "não"] + - "←": [T: "seta para a esquerda"] + - "↑": [T: "seta para cima"] + - "→": [T: "seta para a direita"] + - "↓": [T: "seta para baixo"] + - "": [T: "desconhecido ou ausente objeto"] + - "�": [T: "ausente caractere"] + - "🣑": [T: "é em equilíbrio com"] + - "🣒": [T: "está em equilíbrio deslocado para a direita com"] + - "🣓": [T: "está em equilíbrio deslocado para a esquerda com"] +# ==== FIM DO RECUO CONTROLADO ==== diff --git a/Rules/Languages/pt/unicode.yaml b/Rules/Languages/pt/unicode.yaml new file mode 100644 index 000000000..64b3fb518 --- /dev/null +++ b/Rules/Languages/pt/unicode.yaml @@ -0,0 +1,571 @@ +--- + # Note to translators: + # most languages don't have two ways to pronounce 'a' -- if not need, remove the rules and change "B-Z" to "A-Z" + # some languages say the word for "uppercase" after the letter. Make sure to change that where appropriate by moving some code around + - "a-z": + - test: + if: "$TTS='none'" + then: [T: "."] + else: [spell: "'.'"] + - "A-Z": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "maiúscula"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] + + - "0-9": [T: "."] # (en: '.') + + - " ": [t: " "] # 0x20 + + - "!": # 0x21 + # Restaura a ramificação do inglês: dentro de :literal: é pontuação, fora + # é o operador. Sem isto, um ponto de exclamação literal é lido "fatorial". + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then_test: + if: "$Verbosity = 'Terse'" + then: [T: "exclamação"] # (en: 'bang') + else: [T: "ponto de exclamação"] # (en: 'exclamation point') + else: [T: "fatorial"] # (en: 'factorial') + - "\"": [T: "aspas"] # 0x22 (en: 'quotation mark') + - "#": [T: "número"] # 0x23 (en: 'number', MathPlayer: 'signo de número', google: 'número') + - "$": [T: "dólares"] # 0x24 (en: 'dollars') + - "%": [T: "por cento"] # 0x25 (en: 'percent') + - "&": [T: "e comercial"] # 0x26 + - "'": [T: "apóstrofo"] # 0x27 (en: 'apostrophe', MathPlayer: 'apóstrofo', google: 'apóstrofe') + - "(": # 0x28 + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [T: "abre parênteses"] # (en: 'open', google translation) + else: [T: "abre parênteses"] # (en: 'open paren', MathPlayer: 'paréntesis', google: 'paréntesis abierto') + else: [T: "abre parênteses"] # (en: 'left paren', MathPlayer: 'paréntesis', google: 'paréntesis dejado') + - ")": # 0x29 + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [T: "fecha parênteses"] # (en: 'close', google translation) + else: [T: "fecha parênteses"] # (en: 'close paren', MathPlayer: 'cierra paréntesis', google: 'paréntesis cercana') + else: [T: "fecha parênteses"] # (en: 'right paren', MathPlayer: 'cierra paréntesis') + + - "*": # 0x2a + test: + if: "parent::*[name(.)='msup' or name(.)='msubsup']" + then: [T: "asterisco"] # (en: 'star', google translation) + else: [T: "vezes"] # (en: 'times') + - "+": [T: "mais"] # 0x2b (en: 'plus') + - ",": # 0x2c + # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent + # that this test is here and not with "…" is not ideal, but seems simplest + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak "comma" when not adjacent to '…' + - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " + # except if expression starts with '…' + - "../*[1][.='…'] " + then: + - T: "vírgula" # (en: 'comma', google translation) + - test: + if: "$Verbosity != Terse" + then: [pause: short] + # else silent + + - "-": [T: "menos"] # 0x2d (en: 'minus') + - ".": # 0x2e + - test: + if: "parent::*[1][self::m:mn]" + then: [T: "ponto"] # (en: 'point', google translation) + else: [T: "ponto"] # (en: 'dot') + - "/": [T: "barra"] # 0x2f (en: 'divided by') + - ":": [T: "dois pontos"] # 0x3a (en: 'colon') + - ";": [T: "ponto e vírgula"] # 0x3b (en: 'semicolon') + - "<": # 0x3c + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] # (en: 'is', google translation) + - T: "menor que" # (en: 'less than') + - "=": # 0x3d + - test: + if: "$Verbosity!='Terse'" + then: [T: "é igual a"] # (en: 'is equal to', google translation) + else: [T: "igual a"] # (en: 'equals', google: 'iguales') + + - ">": # 0x3e + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] # (en: 'is', google translation) + - T: "maior que" # (en: 'greater than') + - "?": [T: "ponto de interrogação"] # 0x3f (en: 'question mark', MathPlayer: 'cierra interrogación', google: 'signo de interrogación') + - "@": [T: "arroba"] # 0x40 (en: 'at sign') + - "[": # 0x5b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "abre colchetes"] # (en: 'open bracket', google translation) + else: [T: "abre colchetes"] # (en: 'left bracket', MathPlayer: 'abre corchetes', google: 'soporte izquierdo') + - "\\": [T: "barra invertida"] # 0x5c (en: 'back slash', MathPlayer: 'abre corchetes', google: 'back slash') + - "]": # 0x5d + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "fecha colchetes"] # (en: 'close bracket', google translation) + else: [T: "fecha colchetes"] # (en: 'right bracket', MathPlayer: 'cierra corchetes', google: 'soporte derecho') + # NOTA: o inglês distingue 'hat' (ornamento sobre variável) de 'caret' + # (o símbolo isolado). O português usa "circunflexo" nos dois casos, então + # o teste contextual seria redundante e foi omitido de propósito. + - "^": [T: "circunflexo"] # 0x5e (en: 'hat' / 'caret') + - "_": [T: "sublinhado"] # 0x5f (en: 'under bar') + - "`": [T: "acento grave"] # 0x60 (en: 'grave') + - "{": # 0x7b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "abre chaves"] # (en: 'open brace', google translation) + else: [T: "abre chaves"] # (en: 'left brace', MathPlayer: 'abre llaves', google: 'abrazadera izquierda') + - "|": # 0x7c + # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' + # CORREÇÃO: a versão anterior era uma simplificação da regra inglesa e perdia + # três casos: P(A|B) ("dado"), a|b entre números ("divide") e o intent literal. + # Fora do ClearSpeak tudo caía em "barra vertical". + - with: + variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) + replace: + - test: + - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [T: "barra vertical"] # (en: 'vertical line') + - else_if: "$SpeechStyle != 'ClearSpeak'" + then_test: + - if: "$DefaultToGiven" + then: [T: "dado"] # (en: 'given') + - else_if: "preceding-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))] and + following-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))]" + then: [T: "divide"] # (en: 'divides') + else: [T: "barra vertical"] # (en: 'vertical line') + - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" + then: [T: "barra vertical"] # (en: 'vertical line') + - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" + then: [T: "tal que"] # (en: 'such that') + - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" + then: [T: "dado"] # (en: 'given') + - else: [T: "divide"] # (en: 'divides') + + - "}": # 0x7d + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "fecha chaves"] # (en: 'close brace', google translation) + else: [T: "fecha chaves"] # (en: 'right brace', MathPlayer: 'cierra llaves', google: 'abrazadera derecha') + + - "~": [T: "til"] # 0x7e + - " ": # 0xa0 + - test: + if: "@data-empty-in-2D" + then: [T: "vazio"] # want to say something for fraction (etc) with empty child (en: 'empty', google translation) + else: [T: ""] + + - "¢": [T: "centavos"] # 0xa2 (en: 'cents') + - "£": [T: "libras"] # 0xa3 (en: 'pounds') + - "¬": [T: "não"] # 0xac (en: 'not') + - "°": [T: "graus"] # 0xb0 (en: 'degrees') + - "±": [T: "mais ou menos"] # 0xb1 (en: 'plus or minus') + - "´": [T: "acento agudo"] # 0xb4 (en: 'acute') + - "·": # 0xB7 + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolDot = 'Auto'" + then_test: + if: "$Verbosity = 'Verbose'" + then: [T: "multiplicado por"] # (en: 'times', google translation) + else: [T: "vezes"] + else: [T: "vezes"] # (en: 'dot') + - "×": # 0xd7 + - test: + if: "$Verbosity = 'Verbose'" + then: [T: "multiplicado por"] # (en: 'times', google translation) + else: [T: "vezes"] + - "÷": [T: "dividido por"] # 0xf7 (en: 'divided by') + - "̀": [T: "acento grave"] # 0x300 (en: 'grave accent embellishment', google: 'embellido de acento grave') + - "́": [T: "com acento agudo"] # 0x301 (en: 'acute accent embellishment', google: 'embellido de acento agudo') + - "̂": [T: "com acento circunflexo"] # 0x302 (en: 'circumflex accent embellishment', google: 'embellamiento del acento circunflejo') + - "̃": [T: "til"] # 0x303 (en: 'tilde embellishment', google: 'tilde adorno') + - "̄": [T: "com mácron"] # 0x304 (en: 'macron embellishment', google: 'embellido de macron') + - "̅": [T: "com barra acima"] # 0x305 (en: 'overbar embellishment', google: 'embellido de overbar') + - "̆": [T: "breve"] # 0x306 + - "̇": [T: "ponto acima"] # 0x307 (en: 'dot above embellishment', google: 'punto por encima del adorno') + + # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong + - "Α-Ω": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "maiúscula"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [spell: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] + + - "α": [T: "alfa"] # 0x3b1 (en: 'alpha') + - "β": [T: "beta"] # 0x3b2 + - "γ": [T: "gama"] # 0x3b3 (google: 'gama') + - "δ": [T: "delta"] # 0x3b4 + - "ε": [T: "épsilon"] # 0x3b5 (en: 'epsilon', google: 'epsilon') + - "ζ": [T: "zeta"] # 0x3b6 + - "η": [T: "eta"] # 0x3b7 + - "θ": [T: "teta"] # 0x3b8 + - "ι": [T: "iota"] # 0x3b9 + - "κ": [T: "capa"] # 0x3ba + - "λ": [T: "lambda"] # 0x3bb + - "μ": [T: "mi"] # 0x3bc (en: 'mu', google: 'mu') + - "ν": [T: "ni"] # 0x3bd (en: 'nu', google: 'nu') + - "ξ": [T: "csi"] # 0x3be (en: 'zai', google: 'zai') + - "ο": [T: "ômicron"] # 0x3bf (en: 'omicron', google: 'omicron') + - "π": [T: "pi"] # 0x3c0 + - "ρ": [T: "rô"] # 0x3c1 + - "ς": [T: "sigma final"] # 0x3c2 (en: 'final sigma', google: 'final sigma') + - "σ": [T: "sigma"] # 0x3c3 + - "τ": [T: "tau"] # 0x3c4 + - "υ": [T: "úpsilon"] # 0x3c5 (en: 'upsilon', google: 'upsilon') + - "φ": [T: "fi"] # 0x3c6 (google: 'fi') + - "χ": [T: "qui"] # 0x3c7 (en: 'chi', google: 'chi') + - "ψ": [T: "psi"] # 0x3c8 + - "ω": [T: "ômega"] # 0x3c9 + - "ϕ": [T: "fi reto"] # 0x3d5 (en: 'phi', google: 'fi') + - "ϖ": [T: "pi variante"] # 0x3d6 (en: 'pi', google: 'pi') + - "ϵ": [T: "épsilon variante"] # 0x3f5 (en: 'epsilon', google: 'epsilon') + - "϶": [T: "épsilon invertido"] # 0x3f6 (en: 'reversed epsilon') + + - "⁢": [T: ""] # 0x2062 + - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" + # Adjetivo de estilo POSPOSTO (decisão 8.1): o spell: vem primeiro. + - spell: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" + - T: "vazado" # (en: 'double-struck', google: 'doble golpe') + + - "℃": [T: "graus Celsius"] # 0x2103 (en: 'degrees celsius', google: 'grados celsius') + - "ℋℛℓ": # 0x210b + # 'caligráfico', não 'cursivo': termo único da família script, igual ao + # que o unicode-full.yaml usa (ℐ ℒ ℘ ℬ ℰ ℱ ℳ). t: minúsculo porque a + # escolha entre os dois ainda depende de escuta — ver ACHADOS 7.8. + - spell: "translate('.', 'ℋℛℓ', 'HRl')" + - t: "caligráfico" # (en: 'script', google: 'guion') + - "ℜ": # 0x211c + # 'fraktur', não 'gótico': termo único da família, igual ao + # unicode-full.yaml (ℑ ℌ ℨ ℭ e os blocos do plano 1). t: minúsculo. + - spell: "'R'" + - t: "fraktur" # (en: 'fraktur', google: 'fraktur') + + - "ⅆⅇⅈⅉ": # 0x2146-9 + - spell: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" + - T: "vazado itálico" # (en: 'double-struck italic') + + - "∥": # 0x2225 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] # (en: 'is', google translation) + - T: "paralela a" # (en: 'parallel to') + - "∦": # 0x2226 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês + # não tem par que valha suprimir no Terse. Com o ramo "é" a fala saía + # "é não é paralela a". Mesmo tratamento que ≢, ≇, ⊈ e ⊉. + - T: "não é paralela a" # (en: 'not parallel to') + - "≤": # 0x2264 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] # (en: 'is', google translation) + - T: "menor ou igual a" + - "≥": # 0x2265 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] # (en: 'is', google translation) + - T: "maior ou igual a" # (en: 'greater than or equal to') + + # --- restored complex short definitions (prefer over unicode-full) --- + - "…": # 0x2026 + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak '…' as 'and so on...' unless expr starts with '…' + - "../*[1][.='…']" + then: [T: "reticências"] # (en: 'dot dot dot', google translation) + else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' + if: "count(following-sibling::*) = 0" + then: [T: "etcétera"] # (en: 'and so on', google translation) + else: [T: "reticências"] # (en: 'and so on up to', MathPlayer: 'punto punteado punteado', google: 'y así sucesivamente') + - "⁡": # 0x2061 + - test: + # skip saying "of" when Terse and a trig function, when it is a shape (does this happen?), or we are in :literal mode + if: "not( + ( $Verbosity='Terse' or ($SpeechStyle = 'ClearSpeak' and IsNode(following-sibling::*[1],'simple')) and + preceding-sibling::*[1][IfThenElse($SpeechStyle='ClearSpeak', + IsInDefinition(., 'ClearSpeakTrigFunctionNames'), + IsInDefinition(., 'TrigFunctionNames') )] + ) or + preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')] or + (@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) + )" + then: [T: "de"] # (en: 'of', google translation) + - "→": # 0x2192 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "tende a"] # (en: 'approaches') + else: [T: "seta para a direita"] # (en: 'right arrow', MathPlayer: 'flecha', google: 'flecha correcta') + - "∂": # 0x2202 + - test: + if: "$Verbosity='Terse'" + then: [T: "parcial"] # (en: 'partial', google translation) + else: [T: "derivada parcial"] # (en: 'partial derivative') + - "∆": # 0x2206 + - test: + if: "$Verbosity!='Terse'" + then: [T: "o"] # (en: 'the', google translation) + - T: "incremento" # (en: 'laplacian of') + - "∈": # 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + # Também aqui o ramo dentro de um conjunto precisa do particípio: uma + # string só para os dois contextos daria "o conjunto de todos os x + # pertence a inteiros", com o verbo grudando em "conjunto". + then_test: + if: "../../self::m:set or ../../../self::m:set" + then: [T: "pertencentes a"] + else: [T: "pertence a"] # (en: 'an element of'; uso brasileiro corrente) + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + # DENTRO de um conjunto a expressão modifica "todos os x": nada de + # verbo finito (grudaria em "conjunto") e concordância no plural. + # É o que o inglês faz com 'in / member of / element of / belonging to'. + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "em"] # (en: 'in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "membros de"] # (en: 'member of'; plural concorda com "todos os x") + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "elementos de"] # (en: 'element of'; plural concorda com "todos os x") + - else: [T: "pertencentes a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + else_test: + # Auto separado de Member, como o ∉ já tinha: com as preferências + # padrão ($ClearSpeak_SetMemberSymbol = 'Auto') o brasileiro + # corrente é "pertence a". Ver ACHADOS 7.8. + - if: $ClearSpeak_SetMemberSymbol = 'Auto' + then: [T: "pertence a"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "é membro de"] # (en: 'is a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "é um elemento de"] # (en: 'is an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "está em"] # (en: 'is in', google translation) + - else: [T: "pertence a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - "∉": # 0x2209 + # rule is identical to 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then_test: + if: "../../self::m:set or ../../../self::m:set" + then: [T: "não pertencentes a"] + else: [T: "não pertence a"] # (en: 'is not an element of'; uso brasileiro) + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + # Idem ao 0x2208: sem verbo finito, concordando com "todos os x". + # "não em" é truncado ("não" não nega preposição nua) e "fora de" + # troca o conceito (afirma localização em vez de negar pertinência, + # ambíguo com complementar). Fica a forma nominal da negação, que + # coincide com o ramo Belongs — decisão registrada em + # TERMINOLOGIA_PT_BR.md e ACHADOS 7.9. + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "não pertencentes a"] # (en: 'not in') + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "não membros de"] # (en: 'not member of') + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "não elementos de"] # (en: 'not element of') + - else: [T: "não pertencentes a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' + then: [T: "não pertence a"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "não é membro de"] # (en: 'is not a member of') + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "não é um elemento de"] # (en: 'is not an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + # Era "não está contido em", que é exatamente a fala do ⊄ + # (ver 0x2284): duas relações distintas soavam iguais. Agora + # espelha o "está em" do ∈ e o que o próprio ∉ diz num conjunto. + then: [T: "não está em"] # (en: 'is not in', google translation) + - else: [T: "não pertence a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to') + - "∊": # 0x220a + # variante de forma do 0x2208: fala igual ao ∈ em todos os ramos. + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then_test: + if: "../../self::m:set or ../../../self::m:set" + then: [T: "pertencentes a"] + else: [T: "pertence a"] # alinhado ao ∈ (era "é um elemento de") + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + # DENTRO de um conjunto a expressão modifica "todos os x": nada de + # verbo finito (grudaria em "conjunto") e concordância no plural. + # É o que o inglês faz com 'in / member of / element of / belonging to'. + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "em"] # (en: 'in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "membros de"] # (en: 'member of'; plural concorda com "todos os x") + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "elementos de"] # (en: 'element of'; plural concorda com "todos os x") + - else: [T: "pertencentes a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + else_test: + # Auto separado de Member, igual ao ∈ e ao ∉. Ver ACHADOS 7.8. + - if: $ClearSpeak_SetMemberSymbol = 'Auto' + then: [T: "pertence a"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "é membro de"] # (en: 'is a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "é um elemento de"] # (en: 'is an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "está em"] # (en: 'is in', google translation) + - else: [T: "pertence a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - "√": # 0x221a + - test: + if: "$Verbosity!='Terse'" + then: [T: "a"] # (en: 'the', google translation) + - T: "raiz quadrada de" # (en: 'square root of') + - "∝": # 0x221d + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] # (en: 'is', google translation) + - T: "proporcional a" # (en: 'proportional to') + - "∶": # 0x2236 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] # (en: 'is', google translation) + - T: "a" # (en: 'to') + - "∾": # 0x223e + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] # (en: 'is', google translation) + - T: "mais positivo" # (en: 'most positive') + - "≠": # 0x2260 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # ("diferente de" já dispensa a cópula) + - T: "diferente de" # (en: 'not equal to'; MathPlayer sugeria 'distinto de' e o algoritmo escolheu a do Google) + - "≡": # 0x2261 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] # (en: 'is', google translation) + - T: "idêntico a" # (en: 'identical to') + - "⊂": # 0x2282 + - test: + if: "$Verbosity!='Terse'" + then: [T: "está"] # (en: 'is a'; "está contido em" é o uso brasileiro) + - T: "contido em" # (en: 'subset of') + - "⊃": # 0x2283 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is a'; "contém" já é verbo) + - T: "contém" # (en: 'superset of') + - "⊄": # 0x2284 + - test: + if: "$Verbosity!='Terse'" + then: [T: "não"] # (coerente com ⊂: "não está contido em") + - T: "está contido em" # (en: 'not a subset of') + - "⊅": # 0x2285 + - test: + if: "$Verbosity!='Terse'" + then: [T: "não"] # (coerente com ⊃) + - T: "contém" # (en: 'not a superset of') + - "⊆": # 0x2286 + - test: + if: "$Verbosity!='Terse'" + then: [T: "está"] # (coerente com ⊂) + - T: "contido em ou é igual a" # (en: 'subset of or equal to') + - "⊇": # 0x2287 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (coerente com ⊃) + - T: "contém ou é igual a" # (en: 'superset of or equal to') + + # --- restored short definitions that differ from unicode-full --- + - "–": [T: "meia-risca"] # 0x2013 (en: 'en dash') + - "—": [T: "travessão"] # 0x2014 (en: 'em dash') + - "‖": [T: "barra vertical dupla"] # 0x2016 (en: 'double vertical line') + - "″": [T: "duas linhas"] # 0x2033 (en: 'double prime', MathPlayer: 'segunda', google: 'doble primo') + - "‴": [T: "três linhas"] # 0x2034 (en: 'triple prime', MathPlayer: 'tercera', google: 'triple prime') + - "‵": [T: "linha invertida"] # 0x2035 (en: 'reversed prime') + - "‶": [T: "duas linhas invertidas"] # 0x2036 (en: 'reversed double prime') + - "‷": [T: "três linhas invertidas"] # 0x2037 (en: 'reversed triple prime', google: 'triple prime invertido') + - "℉": [T: "graus Fahrenheit"] # 0x2109 (en: 'degrees fahrenheit') + - "ℎ": [T: "constante de Planck"] # 0x210e (en: 'planck constant', MathPlayer: 'constante de Planck', google: 'planck constante') + - "K": [T: "kelvin"] # 0x212a (en: 'kelvin') + - "←": [T: "seta para a esquerda"] # 0x2190 (en: 'leftwards arrow') + - "↑": [T: "seta para cima"] # 0x2191 (en: 'upwards arrow') + - "↓": [T: "seta para baixo"] # 0x2193 (en: 'downwards arrow') + - "⇒": [T: "implica que"] # 0x21d2 (en: 'rightwards double arrow') + - "∘": [T: "composto com"] # 0x2218 (en: 'composed with') + - "∣": # 0x2223 (en: 'divides') + # O latex2mathml emite \mid como U+2223, não como "|". Em P(A ∣ B) é + # "dado" — mesma condição de contexto da regra do "|" (0x7c). Fora disso, + # continua "divide" (a ∣ b entre inteiros). Ver ACHADOS 9.6. + - test: + if: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']" + then: [T: "dado"] # (en: 'given') + else: [T: "divide"] + - "∤": [T: "não divide"] # 0x2224 (en: 'does not divide') + - "∷": [T: "como"] # 0x2237 (en: 'as') + - "∼": [T: "varia com"] # 0x223c (en: 'varies with') + - "∽": [T: "til invertido"] # 0x223d (en: 'reversed tilde') + - "∿": [T: "onda senoidal"] # 0x223f (en: 'sine wave') + - "≦": [T: "menor ou igual a"] # 0x2266 (en: 'less than over equal to') + - "≧": [T: "maior ou igual a"] # 0x2267 (en: 'greater than over equal to') + +# --- ACRÉSCIMOS pt (não existiam no es e caíam no unicode-full em inglês) --- + - "≪": [T: "é muito menor que"] # 0x226a (en: 'much less than') + - "≫": [T: "é muito maior que"] # 0x226b (en: 'much greater than') + - "⊥": [T: "é perpendicular a"] # 0x22a5 (en: 'perpendicular to') +# Ornamentos usados em variáveis modificadas (x com trema = 2a derivada): + - "̌": [T: "cáron"] # 0x030c (en: 'caron embellishment') + - "̈": [T: "dois pontos"] # 0x0308 (en: 'double dot above') + - "⃛": [T: "três pontos acima"] # 0x20db (en: 'triple dot above') + - "⃜": [T: "quatro pontos acima"] # 0x20dc (en: 'quadruple dot above') + - "⁤": [T: "e"] # 0x2064 (invisible plus — "dois e um meio"); FALTAVA em pt + - "∐": [T: "coproduto"] # 0x2210 (en: 'co-product'); FALTAVA em pt + - "⁣": [T: ""] # 0x2063 (invisible separator — silencioso) + - "′": [T: "linha"] # 0x2032 (en: 'prime') + - "↗": # 0x2197 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "tende por baixo a"] + else: [T: "seta para nordeste"] + - "↘": # 0x2198 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "tende por cima a"] + else: [T: "seta para sudeste"] + - "˙": [T: "ponto"] # 0x02d9 (dot above) + - "¨": [T: "dois pontos"] # 0x00a8 (diaeresis / 2a derivada) diff --git a/tests/Languages/pt.rs b/tests/Languages/pt.rs new file mode 100644 index 000000000..dac447ebd --- /dev/null +++ b/tests/Languages/pt.rs @@ -0,0 +1,17 @@ +#![allow(non_snake_case)] +// Módulo de testes do idioma pt (português). +// IMPORTANTE: acrescente `mod pt;` em tests/languages.rs para ativar. +mod ClearSpeak { + mod sets; +} +mod SimpleSpeak { + mod functions; +} +mod shared; +mod chemistry; +mod alphabets; +mod intent; +mod units; +mod unicode_full; +mod escuta; // gerador do pacote de escuta (#[ignore]) + diff --git a/tests/Languages/pt/ClearSpeak/sets.rs b/tests/Languages/pt/ClearSpeak/sets.rs new file mode 100644 index 000000000..ff2ee45cd --- /dev/null +++ b/tests/Languages/pt/ClearSpeak/sets.rs @@ -0,0 +1,398 @@ +/// Testes de conjuntos e pertinência — pt-BR, ClearSpeak e SimpleSpeak. +/// +/// POR QUE ESTE ARQUIVO EXISTE +/// O par ∈ / ∊ falou "é membro de" com as preferências padrão durante duas +/// rodadas inteiras sem ninguém notar, porque o pt não tinha NENHUM teste de +/// pertinência — nem ClearSpeak, nem SimpleSpeak. O ∉ foi corrigido sozinho +/// numa rodada e os outros dois ficaram para trás. Ver ACHADOS 7.8. +/// +/// A invariante que este arquivo trava: **∈ (0x2208) e ∊ (0x220a) são +/// variantes de forma do mesmo símbolo e devem falar igual em todos os ramos** +/// — nas cinco preferências de ClearSpeak_SetMemberSymbol, dentro e fora de +/// um conjunto, nos dois estilos de fala. +/// +/// COMO AS EXPECTATIVAS FORAM ESCRITAS +/// Todas saíram da saída real do motor, nunca de tradução do inglês. O método +/// é o do cabeçalho de tests/Languages/pt/shared.rs: rodar, comparar `left` +/// com `right`, e se o gerado estiver certo em português, copiá-lo; se estiver +/// errado, consertar a REGRA, nunca o teste. +/// +/// Cada teste de pertinência fixa ClearSpeak_SetMemberSymbol explicitamente, +/// inclusive no caso 'Auto'. Isso é de propósito: as preferências de +/// ClearSpeak não são reinicializadas entre testes na mesma thread, então um +/// teste que dependesse do padrão implícito poderia passar ou falhar conforme +/// a ordem de execução. + +use crate::common::*; +use anyhow::Result; + +// x ℝ — pertinência FORA de um conjunto (ramo else_test das regras) +fn sozinho(simbolo: &str) -> String { + format!("x{simbolo}ℝ") +} + +// { x ℤ : x > 5 } — pertinência DENTRO de um conjunto (ramo then_test) +fn no_conjunto(simbolo: &str) -> String { + format!(" + {{ + x {simbolo} ℤ + : x > 5 + }} + ") +} + +const PERTENCE: &str = "\u{2208}"; // ∈ +const NAO_PERTENCE: &str = "\u{2209}"; // ∉ +const PERTENCE_PEQ: &str = "\u{220A}"; // ∊ — variante de forma do 0x2208 + +/// ∈ e ∊ têm de falar igual. É o caso que sobreviveu duas rodadas. +fn ambas_variantes(pref: &str, expr: fn(&str) -> String, esperado: &str) -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", pref, &expr(PERTENCE), esperado)?; + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", pref, &expr(PERTENCE_PEQ), esperado)?; + return Ok(()); +} + +// --------------------------------------------------------------------------- +// Conjuntos numéricos +// --------------------------------------------------------------------------- + +#[test] +fn complexos() -> Result<()> { + test("pt", "ClearSpeak", "ℂ", "números complexos")?; + return Ok(()); +} + +#[test] +fn naturais() -> Result<()> { + test("pt", "ClearSpeak", "ℕ", "números naturais")?; + return Ok(()); +} + +#[test] +fn racionais() -> Result<()> { + test("pt", "ClearSpeak", "ℚ", "números racionais")?; + return Ok(()); +} + +#[test] +fn reais() -> Result<()> { + test("pt", "ClearSpeak", "ℝ", "números reais")?; + return Ok(()); +} + +// Sem "números", diferente dos quatro acima. O inglês tem a mesma assimetria +// ("the integers" contra "the complex numbers"), então isto acompanha o en. +#[test] +fn inteiros() -> Result<()> { + test("pt", "ClearSpeak", "ℤ", "inteiros")?; + return Ok(()); +} + +#[test] +fn conjuntos_numericos_iguais_em_simplespeak() -> Result<()> { + test("pt", "SimpleSpeak", "ℂ", "números complexos")?; + test("pt", "SimpleSpeak", "ℕ", "números naturais")?; + test("pt", "SimpleSpeak", "ℚ", "números racionais")?; + test("pt", "SimpleSpeak", "ℝ", "números reais")?; + test("pt", "SimpleSpeak", "ℤ", "inteiros")?; + return Ok(()); +} + +// --------------------------------------------------------------------------- +// Conjunto vazio, por extensão, por compreensão +// --------------------------------------------------------------------------- + +#[test] +fn conjunto_vazio_por_chaves() -> Result<()> { + test("pt", "ClearSpeak", "{ }", "o conjunto vazio")?; + test("pt", "SimpleSpeak", "{ }", "o conjunto vazio")?; + return Ok(()); +} + +// Sem artigo, ao contrário das chaves vazias acima. O en faz a mesma distinção +// ('empty set' para ∅, 'the empty set' para {}), então isto acompanha o en. +#[test] +fn conjunto_vazio_por_simbolo() -> Result<()> { + test("pt", "ClearSpeak", "∅", "conjunto vazio")?; + test("pt", "SimpleSpeak", "∅", "conjunto vazio")?; + return Ok(()); +} + +#[test] +fn extensao_um_elemento() -> Result<()> { + let expr = "{ 12 }"; + test("pt", "ClearSpeak", expr, "o conjunto 12")?; + test("pt", "SimpleSpeak", expr, "o conjunto 12")?; + return Ok(()); +} + +#[test] +fn extensao_varios_elementos() -> Result<()> { + let expr = " + { 5 , 10 , 15 } + "; + test("pt", "ClearSpeak", expr, "o conjunto 5 vírgula, 10 vírgula, 15")?; + test("pt", "SimpleSpeak", expr, "o conjunto 5 vírgula, 10 vírgula, 15")?; + return Ok(()); +} + +#[test] +fn compreensao_com_dois_pontos() -> Result<()> { + let expr = " + { x:x>2 } + "; + test("pt", "ClearSpeak", expr, "o conjunto de todos os x tal que x é maior que 2")?; + return Ok(()); +} + +// A barra vertical tem de falar igual aos dois pontos. +#[test] +fn compreensao_com_barra() -> Result<()> { + let expr = " + { x|x>2 } + "; + test("pt", "ClearSpeak", expr, "o conjunto de todos os x tal que x é maior que 2")?; + test("pt", "SimpleSpeak", expr, "o conjunto de todos os x tal que x é maior que 2")?; + return Ok(()); +} + +// --------------------------------------------------------------------------- +// União e interseção +// --------------------------------------------------------------------------- + +#[test] +fn uniao() -> Result<()> { + let expr = "A∪B"; + test("pt", "ClearSpeak", expr, "maiúscula a união maiúscula b")?; + test("pt", "SimpleSpeak", expr, "maiúscula a união maiúscula b")?; + return Ok(()); +} + +#[test] +fn intersecao() -> Result<()> { + let expr = "A∩B"; + test("pt", "ClearSpeak", expr, "maiúscula a interseção maiúscula b")?; + test("pt", "SimpleSpeak", expr, "maiúscula a interseção maiúscula b")?; + return Ok(()); +} + +// --------------------------------------------------------------------------- +// Pertinência FORA de um conjunto — as cinco preferências +// --------------------------------------------------------------------------- + +#[test] +fn pertinencia_auto() -> Result<()> { + ambas_variantes("Auto", sozinho, "x pertence a números reais") +} + +#[test] +fn pertinencia_member() -> Result<()> { + ambas_variantes("Member", sozinho, "x é membro de números reais") +} + +#[test] +fn pertinencia_element() -> Result<()> { + ambas_variantes("Element", sozinho, "x é um elemento de, números reais") +} + +#[test] +fn pertinencia_belongs() -> Result<()> { + ambas_variantes("Belongs", sozinho, "x pertence a números reais") +} + +#[test] +fn pertinencia_in() -> Result<()> { + ambas_variantes("In", sozinho, "x está em números reais") +} + +// --------------------------------------------------------------------------- +// Pertinência DENTRO de um conjunto — as cinco preferências +// --------------------------------------------------------------------------- + +#[test] +fn pertinencia_no_conjunto_auto() -> Result<()> { + ambas_variantes("Auto", no_conjunto, + "o conjunto de todos os x em inteiros tal que x é maior que 5") +} + +#[test] +fn pertinencia_no_conjunto_member() -> Result<()> { + ambas_variantes("Member", no_conjunto, + "o conjunto de todos os x membros de inteiros tal que x é maior que 5") +} + +#[test] +fn pertinencia_no_conjunto_element() -> Result<()> { + ambas_variantes("Element", no_conjunto, + "o conjunto de todos os x elementos de inteiros tal que x é maior que 5") +} + +// Auto e In coincidem dentro de um conjunto, como no inglês ('Auto or In'). +#[test] +fn pertinencia_no_conjunto_in() -> Result<()> { + ambas_variantes("In", no_conjunto, + "o conjunto de todos os x em inteiros tal que x é maior que 5") +} + +// --------------------------------------------------------------------------- +// Não-pertinência +// --------------------------------------------------------------------------- + +#[test] +fn nao_pertinencia_auto() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "Auto", + &sozinho(NAO_PERTENCE), "x não pertence a números reais")?; + return Ok(()); +} + +#[test] +fn nao_pertinencia_member() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "Member", + &sozinho(NAO_PERTENCE), "x não é membro de, números reais")?; + return Ok(()); +} + +#[test] +fn nao_pertinencia_element() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "Element", + &sozinho(NAO_PERTENCE), "x não é um elemento de, números reais")?; + return Ok(()); +} + +#[test] +fn nao_pertinencia_belongs() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "Belongs", + &sozinho(NAO_PERTENCE), "x não pertence a números reais")?; + return Ok(()); +} + +// Auto e In coincidem na negação também, como no positivo. E aqui coincidem +// também com Belongs: "não em" é truncado e "fora de" troca o conceito +// (localização, não pertinência), então a negação nominal é uma só. +// Ver TERMINOLOGIA_PT_BR.md. +#[test] +fn nao_pertinencia_no_conjunto_auto() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "Auto", &no_conjunto(NAO_PERTENCE), + "o conjunto de todos os x não pertencentes a inteiros tal que x é maior que 5")?; + return Ok(()); +} + +#[test] +fn nao_pertinencia_no_conjunto_member() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "Member", &no_conjunto(NAO_PERTENCE), + "o conjunto de todos os x não membros de inteiros tal que x é maior que 5")?; + return Ok(()); +} + +#[test] +fn nao_pertinencia_no_conjunto_element() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "Element", &no_conjunto(NAO_PERTENCE), + "o conjunto de todos os x não elementos de inteiros tal que x é maior que 5")?; + return Ok(()); +} + +#[test] +fn nao_pertinencia_no_conjunto_in() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "In", &no_conjunto(NAO_PERTENCE), + "o conjunto de todos os x não pertencentes a inteiros tal que x é maior que 5")?; + return Ok(()); +} + +// --------------------------------------------------------------------------- +// SimpleSpeak — a preferência de ClearSpeak não vale aqui +// --------------------------------------------------------------------------- + +#[test] +fn pertinencia_simplespeak() -> Result<()> { + test("pt", "SimpleSpeak", &sozinho(PERTENCE), "x pertence a números reais")?; + test("pt", "SimpleSpeak", &sozinho(PERTENCE_PEQ), "x pertence a números reais")?; + return Ok(()); +} + +#[test] +fn nao_pertinencia_simplespeak() -> Result<()> { + test("pt", "SimpleSpeak", &sozinho(NAO_PERTENCE), "x não pertence a números reais")?; + return Ok(()); +} + +// --------------------------------------------------------------------------- +// Pertinência sob um operador grande (não é "dentro de um conjunto") +// --------------------------------------------------------------------------- + +#[test] +fn pertinencia_sob_somatorio() -> Result<()> { + let expr = " + + ∑ + i ∈ ℤ + + + 1 + i 2 + + "; + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "Auto", expr, + "o somatório sobre i pertence a inteiros de; a fração com numerador 1; e denominador i ao quadrado")?; + return Ok(()); +} + +// --------------------------------------------------------------------------- +// Ramos que exigem forma não-finita (antes falavam com verbo finito) +// +// Dentro de um conjunto a expressão modifica "todos os x". Verbo finito ali +// gruda em "conjunto" ("o conjunto de todos os x PERTENCE A inteiros") e a +// concordância cai no lugar errado. O inglês usa 'belonging to' justamente +// para evitar isso. Ver ACHADOS 7.9. +// --------------------------------------------------------------------------- + +#[test] +fn pertinencia_no_conjunto_belongs() -> Result<()> { + ambas_variantes("Belongs", no_conjunto, + "o conjunto de todos os x pertencentes a inteiros tal que x é maior que 5") +} + +#[test] +fn nao_pertinencia_no_conjunto_belongs() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "Belongs", &no_conjunto(NAO_PERTENCE), + "o conjunto de todos os x não pertencentes a inteiros tal que x é maior que 5")?; + return Ok(()); +} + +// O SimpleSpeak usava UMA string só para dentro e fora do conjunto, então não +// conseguia distinguir os dois contextos. Agora bifurca como o ClearSpeak. +#[test] +fn pertinencia_no_conjunto_simplespeak() -> Result<()> { + test("pt", "SimpleSpeak", &no_conjunto(PERTENCE), + "o conjunto de todos os x pertencentes a inteiros tal que x é maior que 5")?; + test("pt", "SimpleSpeak", &no_conjunto(PERTENCE_PEQ), + "o conjunto de todos os x pertencentes a inteiros tal que x é maior que 5")?; + return Ok(()); +} + +#[test] +fn nao_pertinencia_no_conjunto_simplespeak() -> Result<()> { + test("pt", "SimpleSpeak", &no_conjunto(NAO_PERTENCE), + "o conjunto de todos os x não pertencentes a inteiros tal que x é maior que 5")?; + return Ok(()); +} + +/// Fora de um conjunto o verbo finito está certo (o sujeito é um termo só), mas +/// o ∉ com 'In' falava "não está contido em" — exatamente a fala do ⊄ +/// (unicode.yaml, 0x2284). Duas relações distintas soavam idênticas. Agora +/// espelha o "está em" do ∈, que é o que o próprio ∉ já dizia num conjunto. +#[test] +fn nao_pertinencia_in_nao_colide_com_subconjunto() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "In", + &sozinho(NAO_PERTENCE), "x não está em números reais")?; + return Ok(()); +} + +/// Guarda da distinção: ∉ e ⊄ não podem falar igual. +#[test] +fn nao_pertinencia_e_nao_subconjunto_falam_diferente() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "In", + "x\u{2209}ℝ", "x não está em números reais")?; + test("pt", "ClearSpeak", + "x\u{2284}ℝ", "x não está contido em, números reais")?; + return Ok(()); +} diff --git a/tests/Languages/pt/SimpleSpeak/functions.rs b/tests/Languages/pt/SimpleSpeak/functions.rs new file mode 100644 index 000000000..a656c2da0 --- /dev/null +++ b/tests/Languages/pt/SimpleSpeak/functions.rs @@ -0,0 +1,422 @@ +/// TESTES DO IDIOMA pt — como reconciliar com as regras +/// +/// As strings esperadas abaixo foram escritas para refletir a intenção +/// das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam +/// PAUSAS inseridas pelo motor e podem divergir levemente na primeira +/// execução. Método do guia oficial de tradutores: +/// 1. rode `cargo test Languages::pt` +/// 2. para cada falha, compare `left` (esperado) com `right` (gerado) +/// 3. se o GERADO estiver correto em português, copie-o para o teste; +/// se estiver errado, conserte a REGRA, nunca o teste. +/// +/// ATENÇÃO ao histórico: o arquivo espanhol equivalente continha testes +/// que não refletiam as regras (ex.: esperava "logaritmo natural" com a +/// regra dizendo "natural log") e dano de busca-e-troca (ex.: "eigh"→"8"). +/// Não herde strings esperadas de es/ sem conferir. + +use crate::common::*; +use anyhow::Result; + +#[test] +fn trig_names() -> Result<()> { + let expr = " + sinx+ + cosy+ + tanz+ + secα+ + cscϕ+ + cotφ + "; + test("pt", "SimpleSpeak", expr, "seno de x mais cosseno de y mais tangente de z mais secante de alfa, mais cossecante de fi reto, mais cotangente de fi")?; + return Ok(()); + +} + +#[test] +fn hyperbolic_trig_names() -> Result<()> { + let expr = " + sinhx+ + coshy+ + tanhz+ + sechα+ + cschϕ+ + cothφ + "; + test("pt", "SimpleSpeak", expr, "seno hiperbólico de x, mais \ + cosseno hiperbólico de y, mais \ + tangente hiperbólica de z, mais \ + secante hiperbólica de alfa, mais, \ + cossecante hiperbólica de fi reto, mais \ + cotangente hiperbólica de fi")?; + return Ok(()); + +} + + +#[test] +fn inverse_trig() -> Result<()> { + let expr = "sin-1x"; + test("pt", "SimpleSpeak", expr, "inversa de seno de x")?; + return Ok(()); + +} + +#[test] +fn trig_squared() -> Result<()> { + let expr = "sin2x"; + test("pt", "SimpleSpeak", expr, "seno ao quadrado de x")?; + return Ok(()); + +} + +#[test] +fn trig_cubed() -> Result<()> { + let expr = "tan3x"; + test("pt", "SimpleSpeak", expr, "tangente ao cubo de x")?; + return Ok(()); + +} + +#[test] +// Reconciliado com a regra function-power corrigida: ToOrdinal() gerava +// "quarto" (masculino) contra "potência" (feminino). +fn trig_fourth() -> Result<()> { + let expr = "sec4x"; + test("pt", "SimpleSpeak", expr, "a potência 4 de, secante de x")?; + return Ok(()); + +} + + +#[test] +fn trig_power_other() -> Result<()> { + let expr = "sinh>n-1x"; + test("pt", "SimpleSpeak", expr, "a potência n menos 1 de, seno hiperbólico de x")?; + return Ok(()); + +} + +#[test] +fn simple_log() -> Result<()> { + let expr = " logx "; + test("pt", "SimpleSpeak", expr, "o log de x")?; + return Ok(()); + +} + +#[test] +fn normal_log() -> Result<()> { + let expr = "log(x+y)"; + test("pt", "SimpleSpeak", expr, "o log de, abre parênteses, x mais y, fecha parênteses")?; + return Ok(()); + +} + +#[test] +fn simple_log_with_base() -> Result<()> { + let expr = " logbx "; + test("pt", "SimpleSpeak", expr, "o log na base b, de x")?; + return Ok(()); + +} + +#[test] +fn normal_log_with_base() -> Result<()> { + let expr = "logb(x+y)"; + test("pt", "SimpleSpeak", expr, "o log na base b, de, abre parênteses, x mais y, fecha parênteses")?; + return Ok(()); + +} + +/// 'Log' com maiúscula é o logaritmo de valor principal (variável complexa) e +/// tem leitura própria, diferente de 'log'. +#[test] +fn principal_value_log() -> Result<()> { + let expr = " Logx "; + test("pt", "SimpleSpeak", expr, "o log do valor principal de x")?; + return Ok(()); + +} + +#[test] +fn simple_ln() -> Result<()> { + let expr = " lnx "; + test("pt", "SimpleSpeak", expr, "o logaritmo natural de x")?; + return Ok(()); + +} + +#[test] +fn normal_ln() -> Result<()> { + let expr = "ln(x+y)"; + test("pt", "SimpleSpeak", expr, "o logaritmo natural de, abre parênteses, x mais y, fecha parênteses")?; + return Ok(()); + +} + +#[test] +fn normal_ln_terse() -> Result<()> { + let expr = "ln(x+y)"; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "l n, abre parênteses, x mais y, fecha parênteses")?; + return Ok(()); + +} + +#[test] +fn simple_ln_terse() -> Result<()> { + let expr = " lnx "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "l n x")?; + return Ok(()); + +} + +#[test] +fn explicit_function_call_with_parens() -> Result<()> { + let expr = "t⁡(x)"; + test("pt", "SimpleSpeak", expr, "t de x")?; + return Ok(()); + +} + + +#[test] +fn explicit_times_with_parens() -> Result<()> { + let expr = "t⁢(x)"; + test("pt", "SimpleSpeak", expr, "t vezes x")?; + return Ok(()); + +} + +#[test] +fn explicit_function_call() -> Result<()> { + let expr = "t⁡x"; + test("pt", "SimpleSpeak", expr, "t de x")?; + return Ok(()); + +} + +#[test] +fn explicit_times() -> Result<()> { + let expr = "t⁢x"; + test("pt", "SimpleSpeak", expr, "t x")?; + return Ok(()); + +} + + +/* + * Tests for times + */ +#[test] +fn no_times_binomial() -> Result<()> { + let expr = "x ⁢ y"; + test("pt", "SimpleSpeak", expr, "x y")?; + return Ok(()); + +} + +#[test] +fn times_following_paren() -> Result<()> { + let expr = " + 2 + ( 3 ) + "; + test("pt", "SimpleSpeak", expr, "2 vezes 3")?; + return Ok(()); + +} + +#[test] +fn times_preceding_paren() -> Result<()> { + let expr = " + ( 2 ) + 3 + "; + test("pt", "SimpleSpeak", expr, "2 vezes 3")?; + return Ok(()); + +} + +#[test] +fn no_times_sqrt() -> Result<()> { + let expr = " + a + b + = + ab + "; + test("pt", "SimpleSpeak", expr, + "a raiz quadrada de a; a raiz quadrada de b; é igual a, a raiz quadrada de a b fim da raiz")?; + return Ok(()); + +} + +/* + * Tests for parens + */ + #[test] + fn no_parens_number() -> Result<()> { + let expr = " + ( + 25 + ) + x + "; + test("pt", "SimpleSpeak", expr, "25 vezes x")?; + return Ok(()); + + } + + #[test] + fn no_parens_monomial() -> Result<()> { + let expr = " + b + ( + xy + ) + "; + test("pt", "SimpleSpeak", expr, "b x y")?; + return Ok(()); + + } + + #[test] + fn no_parens_negative_number() -> Result<()> { + let expr = " + 2+ + ( + −2 + ) + "; + test("pt", "SimpleSpeak", expr, "2 mais menos 2")?; + return Ok(()); + + } + + + #[test] + fn no_parens_negative_number_with_var() -> Result<()> { + let expr = " + ( + −2x + ) + +1 + "; + test("pt", "SimpleSpeak", expr, "menos 2 x, mais 1")?; + return Ok(()); + + } + + #[test] + fn parens_superscript() -> Result<()> { + let expr = " + + + + ( + 2x + ) + 2 + + + "; + test("pt", "SimpleSpeak", expr, "abre parênteses 2 x fecha parênteses ao quadrado")?; + return Ok(()); + + } + + #[test] + fn no_parens_fraction() -> Result<()> { + let expr = " + 2 + + + + ( + 12 + ) + "; + test("pt", "SimpleSpeak", expr, "2 mais 1 meio")?; + return Ok(()); + + } + + + // Tests for the four types of intervals in SimpleSpeak + #[test] + fn parens_interval_open_open() -> Result<()> { + let expr = " + ( + (c,d) + ) + "; + test("pt", "SimpleSpeak",expr, "o intervalo aberto de c a d")?; + return Ok(()); + +} + +#[test] + fn parens_interval_closed_open() -> Result<()> { + let expr = " + [ + [(]c,d) + ) + "; + test("pt", "SimpleSpeak",expr, "o intervalo fechado aberto de c a d")?; + return Ok(()); + +} + + +#[test] +fn parens_interval_open_closed() -> Result<()> { + let expr = " + ( + (c,d] + ] + "; + test("pt", "SimpleSpeak",expr,"o intervalo aberto fechado de c a d")?; + return Ok(()); + +} + + +#[test] +fn parens_interval_closed_closed() -> Result<()> { + let expr = " + [ + [(]c,d] + ] + "; + test("pt", "SimpleSpeak",expr, "o intervalo fechado de c a d")?; + return Ok(()); + +} + + #[test] + fn parens_interval_neg_infinity_open_open() -> Result<()> { + let expr = " + ( + - ∞,d) + ) + "; + test("pt", "SimpleSpeak",expr, + "o intervalo aberto de menos infinito a d")?; + return Ok(()); + +} + + #[test] + fn parens_interval_neg_infinity_open_closed() -> Result<()> { + let expr = " + ( + - ∞,d] + ] + "; + test("pt", "SimpleSpeak",expr, + "o intervalo aberto fechado de menos infinito a d")?; + return Ok(()); + +} + diff --git a/tests/Languages/pt/alphabets.rs b/tests/Languages/pt/alphabets.rs new file mode 100644 index 000000000..b648e59c4 --- /dev/null +++ b/tests/Languages/pt/alphabets.rs @@ -0,0 +1,438 @@ +/// TESTES DO IDIOMA pt — como reconciliar com as regras +/// Testes de alfabetos — versão pt. +/// * this has tests focused on the various alphabets +use crate::common::*; +use anyhow::Result; + + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn special_alphabet_chars() -> Result<()> { + let expr = " ℌ,ℭ"; + test("pt", "SimpleSpeak", expr, "fraktur cap h comma fraktur cap c")?; + let expr = " ℍ,ℿ"; + test("pt", "SimpleSpeak", expr, "double struck cap h comma double struck cap pi")?; + let expr = " ℐ,ℳ"; + test("pt", "SimpleSpeak", expr, "script cap i comma script cap m")?; + return Ok(()); + +} + +#[test] +fn greek() -> Result<()> { + let expr = " Α,Ω"; + // a segunda vírgula é a pausa automática do motor depois do operador; + // o inglês tem a mesma ("cap alpha comma, cap omega"). + test("pt", "SimpleSpeak", expr, "maiúscula alfa vírgula, maiúscula ômega")?; + let expr = " α,ω"; + test("pt", "SimpleSpeak", expr, "alfa vírgula, ômega")?; + return Ok(()); +} + +#[test] +#[ignore] // caracteres de área privada do MathType: dependem do unicode-full.yaml, removido de pt de propósito +fn greek_mathtype_private() -> Result<()> { + let expr = " \u{f8d3},\u{f8e0}"; + test("pt", "SimpleSpeak", expr, "maiúscula delta vazado, vírgula maiúscula úpsilon vazado")?; + return Ok(()); +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn cap_cyrillic() -> Result<()> { + let expr = " А,Я"; + test("pt", "SimpleSpeak", expr, "cap a comma cap ya")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn parenthesized() -> Result<()> { + let expr = " ⒜,⒵"; + test("pt", "SimpleSpeak", expr, "parenthesized eigh comma parenthesized z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn circled() -> Result<()> { + let expr = " Ⓐ,Ⓩ"; + test("pt", "SimpleSpeak", expr, "circled cap eigh comma circled cap z")?; + let expr = " ⓐ,ⓩ"; + test("pt", "SimpleSpeak", expr, "circled eigh comma circled z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn fraktur() -> Result<()> { + let expr = " 𝔄,𝔜"; + test("pt", "SimpleSpeak", expr, "fraktur cap eigh comma fraktur cap y")?; + let expr = " 𝔞,𝔷"; + test("pt", "SimpleSpeak", expr, "fraktur eigh comma fraktur z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "fraktur cap eigh comma fraktur cap y")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "fraktur eigh comma fraktur z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn bold_fraktur() -> Result<()> { + let expr = " 𝕬,𝖅"; + test("pt", "SimpleSpeak", expr, "fraktur bold cap eigh, comma fraktur bold cap z")?; + let expr = " 𝖆,𝖟"; + test("pt", "SimpleSpeak", expr, "fraktur bold eigh comma fraktur bold z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "fraktur bold cap eigh, comma fraktur bold cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "fraktur bold eigh comma fraktur bold z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn double_struck() -> Result<()> { + let expr = " 𝔸,𝕐"; + test("pt", "SimpleSpeak", expr, "double struck cap eigh, comma double struck cap y")?; + let expr = " 𝕒,𝕫"; + test("pt", "SimpleSpeak", expr, "double struck eigh comma double struck z")?; + let expr = " 𝟘,𝟡"; + test("pt", "SimpleSpeak", expr, "double struck 0 comma double struck 9")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "double struck cap eigh, comma double struck cap y")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "double struck eigh comma double struck z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "double struck 0 comma double struck 9")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn script() -> Result<()> { + let expr = " 𝒜,𝒵"; + test("pt", "SimpleSpeak", expr, "script cap eigh comma script cap z")?; + let expr = " 𝒶,𝓏"; + test("pt", "SimpleSpeak", expr, "script eigh comma script z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "script cap eigh comma script cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "script eigh comma script z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn bold_script() -> Result<()> { + let expr = " 𝓐,𝓩"; + test("pt", "SimpleSpeak", expr, "script bold cap eigh comma script bold cap z")?; + let expr = " 𝓪,𝔃"; + test("pt", "SimpleSpeak", expr, "script bold eigh comma script bold z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "script bold cap eigh comma script bold cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "script bold eigh comma script bold z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn bold() -> Result<()> { + let expr = " 𝐀,𝐙"; + test("pt", "SimpleSpeak", expr, "bold cap eigh comma bold cap z")?; + let expr = " 𝐚,𝐳"; + test("pt", "SimpleSpeak", expr, "bold eigh comma bold z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold cap eigh comma bold cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold eigh comma bold z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn italic() -> Result<()> { + let expr = " 𝐴,𝑍"; + test("pt", "SimpleSpeak", expr, "cap eigh comma cap z")?; + let expr = " 𝑎,𝑧"; + test("pt", "SimpleSpeak", expr, "eigh comma z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "cap eigh comma cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "eigh comma z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn sans_serif() -> Result<()> { + let expr = " 𝖠,𝖹"; + test("pt", "SimpleSpeak", expr, "cap eigh comma cap z")?; + let expr = " 𝖺,𝗓"; + test("pt", "SimpleSpeak", expr, "eigh comma z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "cap eigh comma cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "eigh comma z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn sans_serif_bold() -> Result<()> { + let expr = " 𝗔,𝗭"; + test("pt", "SimpleSpeak", expr, "bold cap eigh comma bold cap z")?; + let expr = " 𝗮,𝘇"; + test("pt", "SimpleSpeak", expr, "bold eigh comma bold z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold cap eigh comma bold cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold eigh comma bold z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn sans_serif_italic() -> Result<()> { + let expr = " 𝘈,𝘡"; + test("pt", "SimpleSpeak", expr, "cap eigh comma cap z")?; + let expr = " 𝘢,𝘻"; + test("pt", "SimpleSpeak", expr, "eigh comma z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "cap eigh comma cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "eigh comma z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn sans_serif_bold_italic() -> Result<()> { + let expr = " 𝘼,𝙕"; + test("pt", "SimpleSpeak", expr, "bold cap eigh comma bold cap z")?; + let expr = " 𝙖,𝙯"; + test("pt", "SimpleSpeak", expr, "bold eigh comma bold z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold cap eigh comma bold cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold eigh comma bold z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn monospace() -> Result<()> { + let expr = " 𝙰,𝚉"; + test("pt", "SimpleSpeak", expr, "cap eigh comma cap z")?; + let expr = " 𝚊,𝚣"; + test("pt", "SimpleSpeak", expr, "eigh comma z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "cap eigh comma cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "eigh comma z")?; + return Ok(()); + +} + + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn bold_greek() -> Result<()> { + let expr = " 𝚨,𝛀"; + test("pt", "SimpleSpeak", expr, "bold cap alpha comma bold cap omega")?; + let expr = " 𝛂,𝛚"; + test("pt", "SimpleSpeak", expr, "bold alpha comma bold omega")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold cap alpha comma bold cap omega")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold alpha comma bold omega")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn bold_greek_others() -> Result<()> { + let expr = " 𝛛,𝛡"; + test("pt", "SimpleSpeak", expr, "bold partial derivative, comma bold pi")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold partial derivative, comma bold pi")?; + return Ok(()); + +} + + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn italic_greek() -> Result<()> { + let expr = " 𝛢,𝛺"; + test("pt", "SimpleSpeak", expr, "maiúscula alfa vírgula maiúscula ômega")?; + let expr = " 𝛼,𝜔"; + test("pt", "SimpleSpeak", expr, "alfa vírgula ômega")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "maiúscula alfa vírgula maiúscula ômega")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "alfa vírgula ômega")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn italic_greek_others() -> Result<()> { + let expr = " 𝜕,𝜛"; + test("pt", "SimpleSpeak", expr, "partial derivative comma pi")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "partial derivative comma pi")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn bold_italic_greek() -> Result<()> { + let expr = " 𝜜,𝜴"; + test("pt", "SimpleSpeak", expr, "bold cap alpha comma bold cap omega")?; + let expr = " 𝜶,𝝎"; + test("pt", "SimpleSpeak", expr, "bold alpha comma bold omega")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold cap alpha comma bold cap omega")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold alpha comma bold omega")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn bold_italic_greek_others() -> Result<()> { + let expr = " 𝝏,𝝕"; + test("pt", "SimpleSpeak", expr, "bold partial derivative, comma bold pi")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold partial derivative, comma bold pi")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn sans_serif_bold_greek() -> Result<()> { + let expr = " 𝝖,𝝮"; + test("pt", "SimpleSpeak", expr, "bold cap alpha comma bold cap omega")?; + let expr = " 𝝰,𝞈"; + test("pt", "SimpleSpeak", expr, "bold alpha comma bold omega")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold cap alpha comma bold cap omega")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold alpha comma bold omega")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn sans_serif_bold_greek_others() -> Result<()> { + let expr = " 𝞉,𝞏"; + test("pt", "SimpleSpeak", expr, "bold partial derivative, comma bold pi")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold partial derivative, comma bold pi")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn sans_serif_bold_italic_greek() -> Result<()> { + let expr = " 𝞐,𝞨"; + test("pt", "SimpleSpeak", expr, "bold cap alpha comma bold cap omega")?; + let expr = " 𝞪,𝟂"; + test("pt", "SimpleSpeak", expr, "bold alpha comma bold omega")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold cap alpha comma bold cap omega")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold alpha comma bold omega")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn sans_serif_bold_italic_greek_others() -> Result<()> { + let expr = " 𝟃,𝟉"; + test("pt", "SimpleSpeak", expr, "bold partial derivative, comma bold pi")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold partial derivative, comma bold pi")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito +fn pua_regular() -> Result<()> { + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "cap eigh comma cap z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito +fn turned() -> Result<()> { + let expr = " Ⅎ,⅄"; + test("pt", "SimpleSpeak", expr, "turned cap f comma turned sans-serif cap y")?; + return Ok(()); + + } + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito +fn enclosed_numbers() -> Result<()> { + let expr = " ①,⑨"; + test("pt", "SimpleSpeak", expr, "circled 1 comma circled 9")?; + let expr = " ⑴,⑼"; + test("pt", "SimpleSpeak", expr, "parenthesized 1 comma parenthesized 9")?; + let expr = " ⒈,⒐"; + test("pt", "SimpleSpeak", expr, "1 with period comma 9 with period")?; + let expr = " ⓵,⓽"; + test("pt", "SimpleSpeak", expr, "double circled 1 comma double circled 9")?; + return Ok(()); + +} diff --git a/tests/Languages/pt/chemistry.rs b/tests/Languages/pt/chemistry.rs new file mode 100644 index 000000000..b8448add8 --- /dev/null +++ b/tests/Languages/pt/chemistry.rs @@ -0,0 +1,721 @@ +/// TESTES DO IDIOMA pt — como reconciliar com as regras +/// Tests for rules shared between various speech styles: +/// * modified var +use crate::common::*; +use anyhow::Result; + +#[test] +fn salt() -> Result<()> { + let expr = "NaCl"; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "maiúscula n a; maiúscula c l")?; + return Ok(()); + +} + +#[test] +fn water() -> Result<()> { + let expr = "H2O"; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "maiúscula h, 2, maiúscula o")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Medium")], expr, "maiúscula h, sub 2, maiúscula o")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, "maiúscula h, subscrito 2, maiúscula o")?; + return Ok(()); + +} + +#[test] +fn carbon() -> Result<()> { + let expr = "C"; // not enough to trigger recognition + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "maiúscula c")?; + return Ok(()); + +} + +#[test] +fn sulfate() -> Result<()> { + let expr = " + [SO4] + 2− + "; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Medium")], expr, "abre colchetes, maiúscula s, maiúscula o, sub 4; fecha colchetes super 2 menos")?; + return Ok(()); + +} + +#[test] +fn aluminum_sulfate() -> Result<()> { + let expr = "Al2 + (SO4)3"; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "maiúscula a l, 2; abre parênteses, maiúscula s, maiúscula o, 4; fecha parênteses 3")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Medium")], expr, "maiúscula a l, sub 2; abre parênteses, maiúscula s, maiúscula o, sub 4; fecha parênteses sub 3")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, "maiúscula a l, subscrito 2; abre parênteses, maiúscula s, maiúscula o, subscrito 4; fecha parênteses subscrito 3")?; + return Ok(()); + +} + +#[test] +fn ethanol_bonds() -> Result<()> { + let expr = " + + C + H 3 + − + C + H 2 + − + O + H + + "; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "maiúscula c, maiúscula h, 3, ligação simples, maiúscula c, maiúscula h, 2, ligação simples, maiúscula o, maiúscula h")?; + + return Ok(()); + +} + +#[test] +fn dichlorine_hexoxide() -> Result<()> { + let expr = " + + [ClO2] + + + + + [ClO4] + - + + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "abre colchetes, maiúscula c l; maiúscula o, 2; fecha colchetes mais; \ + abre colchetes, maiúscula c l; maiúscula o, 4; fecha colchetes menos")?; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Medium")], + expr, "abre colchetes, maiúscula c l; maiúscula o, sub 2; fecha colchetes super mais; \ + abre colchetes, maiúscula c l; maiúscula o, sub 4; fecha colchetes super menos")?; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Verbose")], + expr, "abre colchetes, maiúscula c l; maiúscula o, subscrito 2; fecha colchetes sobrescrito mais; \ + abre colchetes, maiúscula c l; maiúscula o, subscrito 4; fecha colchetes sobrescrito menos")?; + return Ok(()); + +} + + +#[test] +fn ethylene_with_bond() -> Result<()> { + let expr = " + H2C + = + CH2 + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "maiúscula h, 2, maiúscula c; ligação dupla, maiúscula c, maiúscula h, 2")?; + return Ok(()); + +} + +#[test] +fn ferric_chloride_aq() -> Result<()> { + let expr = " + Fe + Cl3 + (aq) + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "maiúscula f e; maiúscula c l, 3, aquoso")?; + return Ok(()); + + } + +#[test] +fn ethylene_with_colon_bond() -> Result<()> { + let expr = " + H2C + :: + CH2 + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "maiúscula h, 2, maiúscula c; ligação dupla, maiúscula c, maiúscula h, 2")?; + return Ok(()); + +} + +#[test] +fn beta_decay() -> Result<()> { + let expr = " + + C + + 6 + 14 + + → + + N + + 7 + 14 + + + + + e + + + − + 1 + + 0 + + "; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Terse")], expr, + "14, 6, maiúscula c; forma, 14, 7, maiúscula n; mais 0, menos 1, e")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Medium")], expr, + "super 14, sub 6, maiúscula c; reage formando; super 14, sub 7, maiúscula n; mais super 0, sub menos 1, e")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, + "sobrescrito 14, subscrito 6, maiúscula c; reage formando; sobrescrito 14, subscrito 7, maiúscula n; mais, sobrescrito 0, subscrito menos 1, e")?; + return Ok(()); + +} + +#[test] +fn mhchem_beta_decay() -> Result<()> { + let expr = " + + + + + + + A + + + + + + + + + 6 + + + + + + + + + 14 + + + + + + + + + + + + A + + + + + + + + + 2 + + + + + + + + 6 + + + + + + + + + + + + 2 + + + + + + + + 14 + + + + + + C + + + + ⟶ + + + + + + + + A + + + + + + + + + 7 + + + + + + + + + 14 + + + + + + + + + + + + A + + + + + + + + + 2 + + + + + + + + 7 + + + + + + + + + + + + 2 + + + + + + + + 14 + + + + + + N + + + + + + + + + + + A + + + + + + + + + − + 1 + + + + + + + + + 0 + + + + + + + + + + + + A + + + + + + + + + 2 + + + + + + + + − + 1 + + + + + + + + + + + + 2 + + + + + + + + 0 + + + + + + e + + + "; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Terse")], expr, + "14, 6, maiúscula c; forma, 14, 7, maiúscula n; mais 0, menos 1, e")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Medium")], expr, + "super 14, sub 6, maiúscula c; reage formando; super 14, sub 7, maiúscula n; mais super 0, sub menos 1, e")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, + "sobrescrito 14, subscrito 6, maiúscula c; reage formando; sobrescrito 14, subscrito 7, maiúscula n; mais, sobrescrito 0, subscrito menos 1, e")?; + return Ok(()); + +} + +#[test] +fn hcl_na_produz() -> Result<()> { + let expr = " + 2HCl+2Na + → + 2NaCl+ + H 2 + + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, + "2, maiúscula h, maiúscula c l; mais 2 maiúscula n a; reage formando; 2, maiúscula n a; maiúscula c l; mais maiúscula h, subscrito 2")?; + return Ok(()); + +} + +#[test] +fn mhchem_so4_2mais() -> Result<()> { + let expr = " + + + SO + + + + + + + A + + + + + + + + 4 + + + + + + + + + + A + + + + + + 2 + + + + + + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "maiúscula s; maiúscula o, 4, 2 mais")?; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Medium")], expr, "maiúscula s; maiúscula o, sub 4, super 2 mais")?; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "maiúscula s; maiúscula o, subscrito 4, sobrescrito 2 mais")?; + return Ok(()); + +} + + +#[test] +fn mhchem_hcl_aq_etc() -> Result<()> { + let expr = " + + 2 + + + + + HCl + + + ( + + aq + + ) + + + + + 2 + + + + + Na + + + ( + + s + + ) + + + ⟶ + + + 2 + + + + + NaCl + + + ( + + aq + + ) + + + + + + H + + + + + + + A + + + + + + + + 2 + + + + + + ( + + g + + ) + + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "2, maiúscula h, maiúscula c l; aquoso; mais, 2, maiúscula n a; sólido; forma; 2, maiúscula n a; maiúscula c l; aquoso; mais, maiúscula h, 2; gasoso")?; + + return Ok(()); + +} + + +#[test] +fn mhchem_barbed_equilibrium() -> Result<()> { + let expr = " + + + + H + 2 + + + ⁣ + + ( + g + ) + + + + + + + + I + 2 + + + ⁣ + + ( + g + ) + + + ⁢ + + + ↽ + - + + + - + ⇀ + + + ⁢ + 2 + ⁢ + + H + ⁣ + I + ⁣ + + ( + g + ) + + + + + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "maiúscula h, 2; gasoso; mais; maiúscula i, 2; gasoso; está em equilíbrio com, 2, maiúscula h, maiúscula i, gasoso")?; + return Ok(()); + +} + + + +#[test] +fn mhchem_roman_in_sobrescrito() -> Result<()> { + let expr = " + + + Fe + + II + + ⁣ + + Fe + + III + + ⁣ + + O + 4 + + + + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "maiúscula f e, 2; maiúscula f e, 3; maiúscula o, 4")?; + return Ok(()); + +} + + diff --git a/tests/Languages/pt/escuta.rs b/tests/Languages/pt/escuta.rs new file mode 100644 index 000000000..812be28be --- /dev/null +++ b/tests/Languages/pt/escuta.rs @@ -0,0 +1,33 @@ +use crate::common::*; + +fn falar(estilo: &str, verbosidade: &str, mathml: &str) -> String { + set_rules_dir(abs_rules_dir_path()).unwrap(); + set_preference("Language", "pt".to_string()).unwrap(); + set_preference("SpeechStyle", estilo.to_string()).unwrap(); + set_preference("Verbosity", verbosidade.to_string()).unwrap(); + set_preference("SpeechOverrides_CapitalLetters", "".to_string()).unwrap(); + set_preference("ClearSpeak_SetMemberSymbol", "Auto".to_string()).unwrap(); + match set_mathml(mathml.to_string()) { + Ok(_) => match get_spoken_text() { + Ok(fala) => regex::Regex::new(r" +").unwrap().replace_all(&fala, " ").to_string(), + Err(e) => format!("[ERRO ao falar: {}]", errors_to_string(&e)), + }, + Err(e) => format!("[ERRO no MathML: {}]", errors_to_string(&e)), + } +} + +#[test] +#[ignore = "gerador do pacote de escuta; rode com --ignored --nocapture"] +fn gerar_pacote_escuta() { + let tsv = include_str!("escuta_expressoes.tsv"); + for linha in tsv.lines().filter(|l| !l.starts_with('#') && !l.trim().is_empty()) { + let campos: Vec<&str> = linha.split('\t').collect(); + assert_eq!(campos.len(), 4, "linha malformada no tsv: {linha}"); + let (area, titulo, mathml) = (campos[0], campos[1], campos[3]); + for estilo in ["ClearSpeak", "SimpleSpeak"] { + for verb in ["Terse", "Medium", "Verbose"] { + println!("FALA\t{area}\t{titulo}\t{estilo}\t{verb}\t{}", falar(estilo, verb, mathml)); + } + } + } +} diff --git a/tests/Languages/pt/escuta_expressoes.tsv b/tests/Languages/pt/escuta_expressoes.tsv new file mode 100644 index 000000000..ce729ff9c --- /dev/null +++ b/tests/Languages/pt/escuta_expressoes.tsv @@ -0,0 +1,30 @@ +aritmetica Fração mista e decimal 3\frac{1}{2} + 0{,}75 = 4{,}25 312+0,75=4,25 +aritmetica Bhaskara x = \frac{-b \pm \sqrt{b^{2} - 4ac}}{2a} x=−b±b2−4ac2a +aritmetica Potência e raiz \sqrt[3]{27} = 3^{1} \quad \text{e} \quad 2^{10} = 1024 273=31e210=1024 +aritmetica Porcentagem 15\% \cdot 200 = 30 15%·200=30 +aritmetica Fração de fração \frac{\frac{1}{2}}{\frac{3}{4}} = \frac{2}{3} 1234=23 +conjuntos_logica Pertinência e compreensão \{ x \in \mathbb{Z} : x > 5 \} {x∈ℤ:x>5} +conjuntos_logica União e interseção (A \cup B) \cap C = (A \cap C) \cup (B \cap C) (A∪B)∩C=(A∩C)∪(B∩C) +conjuntos_logica Implicação p \Rightarrow q \equiv \neg p \lor q p⇒q≡¬p∨q +conjuntos_logica Quantificadores \forall \varepsilon > 0 \; \exists \delta > 0 ∀ε>0∃δ>0 +conjuntos_logica Continência \emptyset \subseteq A \subseteq \mathbb{N} ∅⊆A⊆ℕ +calculo Limite fundamental \lim_{x \to 0} \frac{\sin x}{x} = 1 limx→0sinxx=1 +calculo Derivada \frac{d}{dx}\left(x^{2} e^{x}\right) = 2x e^{x} + x^{2} e^{x} ddx(x2ex)=2xex+x2ex +calculo Integral definida \int_{0}^{1} x^{2}\,dx = \frac{1}{3} ∫01x2dx=13 +calculo Série \sum_{n=1}^{\infty} \frac{1}{n^{2}} = \frac{\pi^{2}}{6} ∑n=1∞1n2=π26 +calculo Derivada parcial \frac{\partial f}{\partial x} = 2xy ∂f∂x=2xy +algebra_linear Matriz e determinante A = \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix}, \quad \det(A) = -2 A=(1234),det(A)=−2 +algebra_linear Sistema A\mathbf{x} = \mathbf{b}, \quad \mathbf{x} \in \mathbb{R}^{n} A𝐱=𝐛,𝐱∈ℝn +algebra_linear Autovalor A v = \lambda v Av=λv +algebra_linear Produto interno e norma \langle u, v \rangle = \|u\| \|v\| \cos\theta ⟨u,v⟩=‖u‖‖v‖cosθ +algebra_linear Transposta e inversa (AB)^{T} = B^{T} A^{T}, \quad A^{-1}A = I (AB)T=BTAT,A−1A=I +quimica Água \mathrm{2H_2 + O_2 \longrightarrow 2H_2O} 2H2+O2⟶2H2O +quimica Ácido carbônico \mathrm{CO_2 + H_2O \rightleftharpoons H_2CO_3} CO2+H2O⇌H2CO3 +quimica Íon \mathrm{Na^{+} + Cl^{-} \longrightarrow NaCl} Na++Cl−⟶NaCl +quimica Concentração [\mathrm{H^{+}}] = 10^{-7}\ \mathrm{mol/L} [H+]=10−7 mol/L +quimica Isótopo {}^{14}_{6}\mathrm{C} 614C +estatistica Média amostral \bar{x} = \frac{1}{n} \sum_{i=1}^{n} x_{i} x¯=1n∑i=1nxi +estatistica Variância \sigma^{2} = \frac{\sum (x_{i} - \mu)^{2}}{N} σ2=∑(xi−μ)2N +estatistica Probabilidade condicional P(A \mid B) = \frac{P(A \cap B)}{P(B)} P(A∣B)=P(A∩B)P(B) +estatistica Binomial \binom{n}{k} p^{k} (1-p)^{n-k} (nk)pk(1−p)n−k +estatistica Normal X \sim N(\mu, \sigma^{2}) X~N(μ,σ2) diff --git a/tests/Languages/pt/intent.rs b/tests/Languages/pt/intent.rs new file mode 100644 index 000000000..df164bc1b --- /dev/null +++ b/tests/Languages/pt/intent.rs @@ -0,0 +1,72 @@ +/// TESTES DO IDIOMA pt — como reconciliar com as regras +/// +/// As strings esperadas abaixo foram escritas para refletir a intenção +/// das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam +/// PAUSAS inseridas pelo motor e podem divergir levemente na primeira +/// execução. Método do guia oficial de tradutores: +/// 1. rode `cargo test Languages::pt` +/// 2. para cada falha, compare `left` (esperado) com `right` (gerado) +/// 3. se o GERADO estiver correto em português, copie-o para o teste; +/// se estiver errado, conserte a REGRA, nunca o teste. +/// + +/// Tests for rules shared between various speech styles: +/// * this has tests focused on the various alphabets +use crate::common::*; +use anyhow::Result; + + +#[test] +fn silent_intent_mi() -> Result<()> { + let expr = " 2 x"; + test("pt", "SimpleSpeak", expr, "2")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test("pt", "ClearSpeak", expr, "2")?; + return Ok(()); + +} + +#[test] +fn silent_intent_msup() -> Result<()> { + let expr = " + + H + 2 + "; + test("pt", "SimpleSpeak", expr, "maiúscula h 2")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test("pt", "ClearSpeak", expr, "maiúscula h 2")?; + return Ok(()); + +} + +#[test] +fn silent_intent_underscore() -> Result<()> { + let expr = " + + H + 2 + "; + test("pt", "SimpleSpeak", expr, "maiúscula h 2")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test("pt", "ClearSpeak", expr, "maiúscula h 2")?; + return Ok(()); + +} + +#[test] +fn intent_prob_x() -> Result<()> { + let expr = " + + x + P + "; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test("pt", "ClearSpeak", expr, "probabilidade de x")?; + return Ok(()); + +} diff --git a/tests/Languages/pt/shared.rs b/tests/Languages/pt/shared.rs new file mode 100644 index 000000000..cf860236b --- /dev/null +++ b/tests/Languages/pt/shared.rs @@ -0,0 +1,346 @@ +/// TESTES DO IDIOMA pt — como reconciliar com as regras +/// +/// As strings esperadas abaixo foram escritas para refletir a intenção +/// das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam +/// PAUSAS inseridas pelo motor e podem divergir levemente na primeira +/// execução. Método do guia oficial de tradutores: +/// 1. rode `cargo test Languages::pt` +/// 2. para cada falha, compare `left` (esperado) com `right` (gerado) +/// 3. se o GERADO estiver correto em português, copie-o para o teste; +/// se estiver errado, conserte a REGRA, nunca o teste. +/// +/// ATENÇÃO ao histórico: o arquivo espanhol equivalente continha testes +/// que não refletiam as regras (ex.: esperava "logaritmo natural" com a +/// regra dizendo "natural log") e dano de busca-e-troca (ex.: "eigh"→"8"). +/// Não herde strings esperadas de es/ sem conferir. + +/// Tests for rules shared between various speech styles: +/// * modified var +use crate::common::*; +use anyhow::Result; + +#[test] +fn modified_vars() -> Result<()> { + let expr = " + a ` + b ~ + c ̆ + b ̌ + c ` + + x . + y ˙ + z ¨ + u ⃛ + v ⃜ + + x ^ + + t → + "; + test("pt", "SimpleSpeak", expr, + "a acento grave, b til, c breve, b cáron, c acento grave; mais; x ponto, y ponto, z dois pontos, u três pontos acima; v quatro pontos acima; mais x circunflexo, mais vetor t")?; + return Ok(()); + +} + +#[test] +fn limit() -> Result<()> { + let expr = " + + lim + x → 0 + + + + sin ⁡ x + x + + + "; + test("pt", "SimpleSpeak", expr, "limite quando x tende a 0, de, fração, seno de x, sobre x, fim da fração")?; + return Ok(()); + +} + +#[test] +fn limit_from_below() -> Result<()> { + let expr = " + + lim + x ↗ 0 + + + sin ⁡ x + + "; + test("pt", "SimpleSpeak", expr, "limite quando x tende por baixo a 0, de seno de x")?; + return Ok(()); + +} + + +#[test] +fn binomial_mmultiscripts() -> Result<()> { + let expr = "Cmn"; + test("pt", "SimpleSpeak", expr, "n escolhe m")?; + return Ok(()); + +} + + +#[test] +fn permutation_mmultiscripts() -> Result<()> { + let expr = "Pkn"; + test("pt", "SimpleSpeak", expr, "k permutações de n")?; + return Ok(()); + +} + +#[test] +fn permutation_mmultiscripts_sup() -> Result<()> { + let expr = "Pkn"; + test("pt", "SimpleSpeak", expr, "k permutações de n")?; + return Ok(()); + +} + +#[test] +fn permutation_msubsup() -> Result<()> { + let expr = "Pkn"; + test("pt", "SimpleSpeak", expr, "k permutações de n")?; + return Ok(()); + +} + +#[test] +fn tensor_mmultiscripts() -> Result<()> { + let expr = " + R i j k l + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, + "maiúscula r com 4 pós-escritos, subscrito i sobrescrito j subscrito k subscrito l")?; + // em Medium as regras usam a forma abreviada ('sub'/'super'), como no inglês; + // a forma longa fica reservada ao Verbose (SharedRules/default.yaml). + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Medium")], expr, + "maiúscula r com 4 pós-escritos, sub i super j sub k sub l")?; + return Ok(()); + +} + +#[test] +fn huge_num_mmultiscripts() -> Result<()> { + let expr = " + R i j k l m + I J K L + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, + "maiúscula r com 4 pré-escritos, pré-subscrito maiúscula i, pré-sobrescrito maiúscula j e pré-escritos alternados maiúscula k nenhum maiúscula l nenhum fim dos pré-escritos e com 5 pós-escritos, subscrito i sobrescrito j subscrito k subscrito l e índices alternados m nenhum fim dos índices")?; + return Ok(()); + +} + +#[test] +fn prime() -> Result<()> { + let expr = " x′ "; + test("pt", "SimpleSpeak", expr, "x linha")?; + return Ok(()); + +} + +#[test] +fn given() -> Result<()> { + let expr = "P(A|B)"; + // "dado": em P(A|B) a barra é probabilidade condicional nos dois estilos, + // como no inglês ("cap eigh given cap b"). + test("pt", "SimpleSpeak", expr, "maiúscula p; abre parênteses, maiúscula a dado maiúscula b; fecha parênteses")?; + test("pt", "ClearSpeak", expr, "maiúscula p; abre parênteses, maiúscula a dado maiúscula b; fecha parênteses")?; // not good, but follows the spec + return Ok(()); + +} + +#[test] +fn simple_msubsup() -> Result<()> { + let expr = " + + + x + + k + + + i + + + + "; + test("pt", "SimpleSpeak", expr, "x subscrito k elevado a i")?; + return Ok(()); + +} + +#[test] +fn presentation_mathml_in_semantics() -> Result<()> { + let expr = " + + {\\displaystyle x_k^i} + + + x + + k + + + i + + + + + "; + test("pt", "SimpleSpeak", expr, "x subscrito k elevado a i")?; + return Ok(()); + +} + +#[test] +fn ignore_period() -> Result<()> { + // from https://en.wikipedia.org/wiki/Probability + let expr = " + + {\\displaystyle x_k^i} + + + + P + ( + A + + +  e  + + + B + ) + = + P + ( + A + ∩ + B + ) + = + P + ( + A + ) + P + ( + B + ) + . + + + + + "; + test("pt", "SimpleSpeak", expr, "maiúscula p; abre parênteses, maiúscula a e maiúscula b; fecha parênteses; é igual a; maiúscula p; abre parênteses, maiúscula a interseção maiúscula b; fecha parênteses; é igual a; maiúscula p de maiúscula a; maiúscula p de maiúscula b")?; + return Ok(()); + +} + +#[test] +fn ignore_mtext_period() -> Result<()> { + let expr = "{2}."; + test("pt", "SimpleSpeak", expr, "o conjunto 2")?; + return Ok(()); + +} + +#[test] +fn ignore_comma() -> Result<()> { + // from https://en.wikipedia.org/wiki/Probability + let expr = " + + + ϕ + ( + x + ) + = + c + + e + + − + + h + + 2 + + + + x + + 2 + + + + + , + + +"; + test("pt", "SimpleSpeak", expr, "fi reto de x, é igual a; c vezes, e elevado à potência menos h ao quadrado, x ao quadrado")?; + return Ok(()); + +} + +#[test] +#[ignore] // issue #14 +fn ignore_period_and_space() -> Result<()> { + // from https://en.wikipedia.org/wiki/Probability + let expr = " + + + P + ( + A + ∣ + B + ) + = + + + + P + ( + A + ∩ + B + ) + + + P + ( + B + ) + + + + . + + + +"; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test("pt", "ClearSpeak", expr, "fi reto de x é igual a; c, e elevado a menos h ao quadrado x ao quadrado, fim do expoente")?; + return Ok(()); + +} + + +#[test] +fn mn_with_space() -> Result<()> { + let expr = "1 234 567"; + test("pt", "SimpleSpeak", expr, "1234567")?; + return Ok(()); + +} diff --git a/tests/Languages/pt/unicode_full.rs b/tests/Languages/pt/unicode_full.rs new file mode 100644 index 000000000..1d1d659d7 --- /dev/null +++ b/tests/Languages/pt/unicode_full.rs @@ -0,0 +1,159 @@ +/// TESTES DO IDIOMA pt — decisões de terminologia registradas em +/// Rules/Languages/pt/ACHADOS.md, seção 8. +/// +/// Este arquivo cobre duas decisões que antes não tinham teste nenhum: +/// * 8.2 — numerais romanos Unicode (0x2160-0x217F) falam o VALOR; +/// * 8.3 — os expoentes ⁰ e ⁱ usam a forma cardinal. +/// e fixa o comportamento ASCII que foi decidido PRESERVAR, para que uma +/// mudança futura no caminho de inferência de contexto não passe em silêncio. +/// +/// Todas as expectativas abaixo foram capturadas da saída real do motor, sob +/// as preferências do próprio harness — não foram escritas a partir do que se +/// esperava que saísse. +use crate::common::*; +use anyhow::Result; + +// --------------------------------------------------------------------------- +// 8.2 — Numerais romanos Unicode: falar o valor, não a grafia. +// Antes desta decisão a saída era a soletração ("I V", "X I I", "M"). +// --------------------------------------------------------------------------- + +#[test] +fn numerais_romanos_unicode_falam_o_valor() -> Result<()> { + // Representativos da faixa 0x2160-0x216F (maiúsculas). + let expr = "Ⅰ"; // 0x2160 + test("pt", "SimpleSpeak", expr, "um")?; + let expr = "Ⅳ"; // 0x2163 — o caso que motivou a decisão + test("pt", "SimpleSpeak", expr, "quatro")?; + let expr = "Ⅻ"; // 0x216b + test("pt", "SimpleSpeak", expr, "doze")?; + let expr = "Ⅼ"; // 0x216c + test("pt", "SimpleSpeak", expr, "cinquenta")?; + let expr = "Ⅽ"; // 0x216d + test("pt", "SimpleSpeak", expr, "cem")?; + let expr = "Ⅾ"; // 0x216e + test("pt", "SimpleSpeak", expr, "quinhentos")?; + let expr = "Ⅿ"; // 0x216f + test("pt", "SimpleSpeak", expr, "mil")?; + return Ok(()); +} + +#[test] +fn numerais_romanos_unicode_minusculos() -> Result<()> { + // A metade minúscula da faixa (0x2170-0x217F) tem os mesmos valores. + let expr = "ⅳ"; // 0x2173 + test("pt", "SimpleSpeak", expr, "quatro")?; + let expr = "ⅿ"; // 0x217f + test("pt", "SimpleSpeak", expr, "mil")?; + return Ok(()); +} + +#[test] +fn numerais_romanos_unicode_em_expressao() -> Result<()> { + // O valor também é falado quando o numeral aparece dentro de uma conta. + let expr = "Ⅳ+Ⅻ"; + test("pt", "SimpleSpeak", expr, "quatro mais doze")?; + // A decisão não depende do estilo de fala. + test("pt", "ClearSpeak", expr, "quatro mais doze")?; + return Ok(()); +} + +#[test] +fn numerais_romanos_unicode_em_mn() -> Result<()> { + // O caractere dedicado vale como numeral tanto em quanto em . + let expr = "Ⅳ"; + test("pt", "SimpleSpeak", expr, "quatro")?; + return Ok(()); +} + +// --------------------------------------------------------------------------- +// 8.3 — Expoentes ⁰ e ⁱ na forma cardinal. +// Antes: "elevado à potência zero" / "elevado à potência i". +// --------------------------------------------------------------------------- + +#[test] +fn expoente_zero_e_i_forma_cardinal() -> Result<()> { + let expr = "x⁰"; // 0x2070 + test("pt", "SimpleSpeak", expr, "x elevado a zero")?; + let expr = "xⁱ"; // 0x2071 + test("pt", "SimpleSpeak", expr, "x elevado a i")?; + // A decisão não depende do estilo de fala. + let expr = "x⁰"; + test("pt", "ClearSpeak", expr, "x elevado a zero")?; + return Ok(()); +} + +#[test] +fn expoente_zero_e_i_isolados() -> Result<()> { + let expr = "⁰"; + test("pt", "SimpleSpeak", expr, "elevado a zero")?; + let expr = "ⁱ"; + test("pt", "SimpleSpeak", expr, "elevado a i")?; + return Ok(()); +} + +#[test] +fn expoentes_ordinais_vizinhos_intactos() -> Result<()> { + // As entradas vizinhas continuam na forma ORDINAL: a decisão 8.3 valeu só + // para ⁰ e ⁱ, que não têm ordinal. Este teste existe para impedir que + // alguém "uniformize" o bloco inteiro por engano (ver ACHADOS 5.2). + let expr = "x⁴"; // 0x2074 + test("pt", "SimpleSpeak", expr, "x elevado à quarta potência")?; + let expr = "xⁿ"; // 0x207f + test("pt", "SimpleSpeak", expr, "x elevado à enésima potência")?; + return Ok(()); +} + +// --------------------------------------------------------------------------- +// GUARDA DE REGRESSÃO — o caminho ASCII foi decidido intocado (ACHADOS 8.2). +// +// Numerais romanos escritos com letras ASCII NÃO passam pelo unicode-full.yaml: +// são marcados por src/canonicalize.rs com `data-roman-numeral` e falados pelas +// regras `default` de / em SharedRules/default.yaml, que soletram. +// Esse é o mesmo ramo de regra que trata I e V como identificador ou variável. +// +// Se algum dia o valor passar a ser falado também no caminho ASCII, ESTES +// testes vão falhar — e é essa a intenção: a mudança tem que ser deliberada. +// --------------------------------------------------------------------------- + +#[test] +fn romanos_ascii_continuam_soletrados_nao_viram_valor() -> Result<()> { + // XIV NÃO deve virar "quatorze". + let expr = "XIV"; + test("pt", "SimpleSpeak", expr, "maiúscula x maiúscula i maiúscula v")?; + let expr = "XIV"; + test("pt", "SimpleSpeak", expr, "maiúscula x maiúscula i maiúscula v")?; + // Também não depende do estilo de fala. + let expr = "XIV"; + test("pt", "ClearSpeak", expr, "maiúscula x maiúscula i maiúscula v")?; + // MIX (1009 em romano) é o caso clássico de colisão com palavra. + let expr = "MIX"; + test("pt", "SimpleSpeak", expr, "maiúscula m maiúscula i maiúscula x")?; + // Minúsculas idem: "xiv" não vira "quatorze". + let expr = "xiv"; + test("pt", "SimpleSpeak", expr, "x i v")?; + return Ok(()); +} + +#[test] +fn letras_ascii_isoladas_continuam_identificadores() -> Result<()> { + // I e V sozinhos são identificadores/variáveis, não os romanos 1 e 5. + // Este é o caminho que a decisão 8.2 mandou explicitamente NÃO tocar. + let expr = "I"; + test("pt", "SimpleSpeak", expr, "maiúscula i")?; + let expr = "V"; + test("pt", "SimpleSpeak", expr, "maiúscula v")?; + // Separados, continuam três identificadores — não o numeral 14. + let expr = "XIV"; + test("pt", "SimpleSpeak", expr, "maiúscula x maiúscula i maiúscula v")?; + return Ok(()); +} + +#[test] +fn romano_ascii_em_estado_de_oxidacao_intacto() -> Result<()> { + // O caminho da química (estado de oxidação) usa romanos ASCII e tem o seu + // próprio tratamento em src/chemistry.rs. A decisão 8.2 não o alcança. + let expr = "IV"; + test("pt", "SimpleSpeak", expr, "maiúscula i maiúscula v")?; + return Ok(()); +} diff --git a/tests/Languages/pt/units.rs b/tests/Languages/pt/units.rs new file mode 100644 index 000000000..47bd73056 --- /dev/null +++ b/tests/Languages/pt/units.rs @@ -0,0 +1,411 @@ +/// TESTES DO IDIOMA pt — como reconciliar com as regras +/// +/// As strings esperadas abaixo foram escritas para refletir a intenção +/// das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam +/// PAUSAS inseridas pelo motor e podem divergir levemente na primeira +/// execução. Método do guia oficial de tradutores: +/// 1. rode `cargo test Languages::pt` +/// 2. para cada falha, compare `left` (esperado) com `right` (gerado) +/// 3. se o GERADO estiver correto em português, copie-o para o teste; +/// se estiver errado, conserte a REGRA, nunca o teste. +/// +/// ATENÇÃO ao histórico: o arquivo espanhol equivalente continha testes +/// que não refletiam as regras (ex.: esperava "logaritmo natural" com a +/// regra dizendo "natural log") e dano de busca-e-troca (ex.: "eigh"→"8"). +/// Não herde strings esperadas de es/ sem conferir. + +/// Tests for rules shared between various speech styles: +/// * modified var +use crate::common::*; +use anyhow::Result; + +// The basic layout of the tests is: +// 1. Sweep through all the SI prefixes +// 2. Sweep through each group of SI units +// a) with both singular and plural without prefixes +// b) with both singular and plural with one prefix +// 3. Sweep through each group of units that don't take SI prefixes +// These are broken into chunks so it is easier to see errors, when there are errors + +#[test] +fn prefix_sweep() -> Result<()> { + let expr = r#" + Qg, + Rg, + Yg, + Zg, + Eg, + Pg, + Tg, + Gg, + Mg, + kg, + hg, + dag, + dg, + cg, + mg, + µg, + ng, + pg, + fg, + ag, + zg, + yg, + rg, + qg + "#; + test("pt", "SimpleSpeak", expr, + "quettagramas vírgula, ronnagramas vírgula, yottagramas vírgula, zettagramas vírgula, exagramas vírgula, petagramas vírgula, teragramas vírgula, gigagramas vírgula, megagramas vírgula, quilogramas vírgula, hectogramas vírgula, decagramas vírgula, decigramas vírgula, centigramas vírgula, miligramas vírgula, microgramas vírgula, nanogramas vírgula, picogramas vírgula, femtogramas vírgula, attogramas vírgula, zeptogramas vírgula, yoctogramas vírgula, rontogramas vírgula, quectogramas")?; + return Ok(()); + +} + +#[test] +fn si_base() -> Result<()> { + let expr = r#" + 1A,2A, + 1cd,2cd, + 1K,2K, + 1K,2K, + 1g,2g, + 1m,2m, + 1mol,2mol, + 1s,2s, + 1″,2″, + 1",2", + 1sec,2sec + "#; + test("pt", "SimpleSpeak", expr, + "1 ampère, vírgula; 2 ampères, vírgula; 1 candela, vírgula; 2 candelas, vírgula; 1 kelvin, vírgula; 2 kelvins, vírgula; 1 kelvin, vírgula; 2 kelvins, vírgula, 1 grama, vírgula; 2 gramas, vírgula, 1 metro, vírgula; 2 metros, vírgula, 1 mol, vírgula, 2 mols, vírgula; 1 segundo, vírgula; 2 segundos, vírgula; 1 segundo, vírgula; 2 segundos, vírgula; 1 segundo, vírgula; 2 segundos, vírgula; 1 segundo, vírgula; 2 segundos")?; + return Ok(()); + +} + +#[test] +fn si_base_with_prefixes() -> Result<()> { + let expr = r#" + 1QA,2RA, + 1Ycd,2Zcd, + 1EK,2PK, + 1TK,2GK, + 1Mg,2kg, + 1hm,2dam, + 1dmol,2cmol, + 1ms,2µs, + 1nsec,2psec + "#; + test("pt", "SimpleSpeak", expr, + "1 quettaampère, vírgula; 2 ronnaampères, vírgula; 1 yottacandela, vírgula; 2 zettacandelas, vírgula; 1 exakelvin, vírgula; 2 petakelvins, vírgula; 1 terakelvin, vírgula; 2 gigakelvins, vírgula; 1 megagrama, vírgula; 2 quilogramas, vírgula; 1 hectômetro, vírgula; 2 decâmetros, vírgula; 1 decimol, vírgula; 2 centimols, vírgula; 1 milissegundo, vírgula; 2 microssegundos, vírgula; 1 nanossegundo, vírgula; 2 picossegundos")?; + return Ok(()); + +} + + +#[test] +fn si_derived_1() -> Result<()> { + let expr = r#" + 1Bq,2Bq, + 1C,2C, + 1°C,2°C, + 1℃,2℃, + 1F,2F, + 1Gy,2Gy, + 1H,2H, + 1Hz,2Hz, + 1J,2J, + 1kat,2kat, + 1lm,2lm, + 1lx,2lx + "#; + test("pt", "SimpleSpeak", expr, + "1 becquerel, vírgula; 2 becquerels, vírgula; 1 coulomb, vírgula; 2 coulombs, vírgula; 1 grau Celsius, vírgula; 2 graus Celsius, vírgula; 1 grau Celsius, vírgula; 2 graus Celsius, vírgula, 1 farad, vírgula; 2 farads, vírgula, 1 gray, vírgula, 2 grays, vírgula, 1 henry, vírgula; 2 henrys, vírgula, 1 hertz, vírgula, 2 hertz, vírgula, 1 joule, vírgula; 2 joules, vírgula, 1 katal, vírgula; 2 katals, vírgula; 1 lúmen, vírgula; 2 lúmens, vírgula, 1 lux, vírgula, 2 lux")?; + return Ok(()); + +} + +#[test] +fn si_derived_1_with_prefixes() -> Result<()> { + let expr = r#" + 1QBq,2RBq, + 1YC,2ZC, + 1EF,2PF, + 1TGy,2GGy, + 1MH,2kH, + 1daHz,2dHz, + 1cJ,2mJ, + 1µkat,2nkat, + 1plm,2flm, + 1alx,2zlx, + 1m°C,2µ°C, + 1p℃,2n℃ + "#; + test("pt", "SimpleSpeak", expr, + "1 quettabecquerel, vírgula; 2 ronnabecquerels, vírgula; 1 yottacoulomb, vírgula; 2 zettacoulombs, vírgula; 1 exafarad, vírgula; 2 petafarads, vírgula; 1 teragray, vírgula; 2 gigagrays, vírgula; 1 megahenry, vírgula; 2 quilohenrys, vírgula; 1 decahertz, vírgula; 2 decihertz, vírgula; 1 centijoule, vírgula; 2 milijoules, vírgula; 1 microkatal, vírgula; 2 nanokatals, vírgula; 1 picolúmen, vírgula; 2 femtolúmens, vírgula; 1 attolux, vírgula; 2 zeptolux, vírgula; 1 miligrau Celsius, vírgula; 2 micrograus Celsius, vírgula; 1 picograu Celsius, vírgula; 2 nanograus Celsius")?; + return Ok(()); + +} + +#[test] +fn si_derived_2() -> Result<()> { + let expr = r#" + 1N,2N, + 1Ω,2Ω, + 1Ω,2Ω, + 1Pa,2Pa, + 1S,2S, + 1Sv,2Sv, + 1T,2T, + 1V,2V, + 1W,2W, + 1Wb,2Wb + "#; + test("pt", "SimpleSpeak", expr, + "1 newton, vírgula; 2 newtons, vírgula, 1 ohm, vírgula, 2 ohms, vírgula, 1 ohm, vírgula, 2 ohms, vírgula; 1 pascal, vírgula; 2 pascals, vírgula; 1 siemens, vírgula; 2 siemens, vírgula; 1 sievert, vírgula; 2 sieverts, vírgula, 1 tesla, vírgula; 2 teslas, vírgula, 1 volt, vírgula, 2 volts, vírgula, 1 watt, vírgula, 2 watts, vírgula, 1 weber, vírgula; 2 webers")?; + return Ok(()); + +} + +#[test] +fn si_derived_2_with_prefixes() -> Result<()> { + let expr = r#" + 1qN,2rN, + 1yΩ,2zΩ, + 1aΩ,2fΩ, + 1pPa,2nPa, + 1µS,2mS, + 1cSv,2dSv, + 1daT,2hT, + 1kV,2MV, + 1GW,2TW, + 1PWb,2EWb + "#; + test("pt", "SimpleSpeak", expr, + "1 quectonewton, vírgula; 2 rontonewtons, vírgula; 1 yoctoohm, vírgula; 2 zeptoohms, vírgula; 1 attoohm, vírgula; 2 femtoohms, vírgula; 1 picopascal, vírgula; 2 nanopascals, vírgula; 1 microssiemens, vírgula; 2 milissiemens, vírgula; 1 centissievert, vírgula; 2 decissieverts, vírgula; 1 decatesla, vírgula; 2 hectoteslas, vírgula; 1 quilovolt, vírgula; 2 megavolts, vírgula; 1 gigawatt, vírgula; 2 terawatts, vírgula; 1 petaweber, vírgula; 2 exawebers")?; + return Ok(()); + +} + + +#[test] +fn si_accepted() -> Result<()> { + let expr = r#" + 1l,2l, + 1L,2L, + 1ℓ,2ℓ, + 1t,2t, + 1Da,2Da, + 1Np,2Np, + 1u,2u, + 1eV,2eV, + 1rad,2rad, + 1sr,2sr, + 1a,2a, + 1as,2as, + 1b,2b, + 1B,2B, + 1Bd,2Bd + "#; + test("pt", "SimpleSpeak", expr, + "1 litro, vírgula; 2 litros, vírgula, 1 litro, vírgula; 2 litros, vírgula, 1 litro, vírgula; 2 litros, vírgula; 1 tonelada, vírgula; 2 toneladas, vírgula; 1 dalton, vírgula; 2 daltons, vírgula, 1 neper, vírgula; 2 neperes, vírgula; 1 unidade de massa atômica, vírgula; 2 unidades de massa atômica; vírgula; 1 elétron-volt, vírgula; 2 elétron-volts, vírgula; 1 radiano, vírgula; 2 radianos, vírgula; 1 esferorradiano, vírgula; 2 esferorradianos, vírgula, 1 ano, vírgula, 2 anos, vírgula; 1 segundo de arco, vírgula; 2 segundos de arco, vírgula, 1 bit, vírgula, 2 bits, vírgula, 1 byte, vírgula, 2 bytes, vírgula, 1 baud, vírgula, 2 bauds")?; + return Ok(()); + +} + +#[test] +fn si_accepted_with_prefixes() -> Result<()> { + let expr = r#" + 1Ql,2Rl, + 1YL,2ZL, + 1Eℓ,2Pℓ, + 1Tt,2Gt, + 1MDa,2kDa, + 1dNp,2cNp, + 1hu,2dau, + 1meV,2µeV, + 1nrad,2prad, + 1fsr,2asr, + 1Ga,2Ma, + 1zas,2yas, + 1kb,2Mb, + 1GB,2TB, + 1TBd,2EBd + "#; + test("pt", "SimpleSpeak", expr, + "1 quettalitro, vírgula; 2 ronnalitros, vírgula; 1 yottalitro, vírgula; 2 zettalitros, vírgula; 1 exalitro, vírgula; 2 petalitros, vírgula; 1 teratonelada, vírgula; 2 gigatoneladas, vírgula; 1 megadalton, vírgula; 2 quilodaltons, vírgula; 1 decineper, vírgula; 2 centineperes, vírgula; 1 hectounidade de massa atômica; vírgula; 2 decaunidades de massa atômica; vírgula; 1 milielétron-volt, vírgula; 2 microelétron-volts, vírgula; 1 nanorradiano, vírgula; 2 picorradianos, vírgula; 1 femtoesferorradiano, vírgula; 2 attoesferorradianos, vírgula; 1 gigaano, vírgula; 2 megaanos, vírgula; 1 zeptossegundo de arco, vírgula; 2 yoctossegundos de arco, vírgula; 1 quilobit, vírgula; 2 megabits, vírgula; 1 gigabyte, vírgula; 2 terabytes, vírgula; 1 terabaud, vírgula; 2 exabauds")?; + return Ok(()); + +} + +#[test] +fn without_prefix_time() -> Result<()> { + let expr = r#" + 1″,2″, + 1",2", + 1′,2′, + 1',2', + 1min,2min, + 1h,2h, + 1hr,2hr, + 1Hr,2Hr, + 1d,2d, + 1dy,2dy, + 1w,2w, + 1wk,2wk, + 1y,2y, + 1yr,2yr + "#; + test("pt", "SimpleSpeak", expr, + "1 segundo, vírgula; 2 segundos, vírgula; 1 segundo, vírgula; 2 segundos, vírgula; 1 minuto, vírgula; 2 minutos, vírgula; 1 minuto, vírgula; 2 minutos, vírgula; 1 minuto, vírgula; 2 minutos, vírgula, 1 hora, vírgula, 2 horas, vírgula, 1 hora, vírgula, 2 horas, vírgula, 1 hora, vírgula, 2 horas, vírgula, 1 dia, vírgula, 2 dias, vírgula, 1 dia, vírgula, 2 dias, vírgula; 1 semana, vírgula; 2 semanas, vírgula; 1 semana, vírgula; 2 semanas, vírgula, 1 ano, vírgula, 2 anos, vírgula, 1 ano, vírgula, 2 anos")?; + return Ok(()); + +} + +#[test] +fn without_prefix_angles() -> Result<()> { + let expr = r#" + 1°,2°, + 1deg,2deg, + 1arcmin,2arcmin, + 1amin,2amin, + 1am,2am, + 1MOA,2MOA, + 1arcsec,2arcsec, + 1asec,2asec + "#; + test("pt", "SimpleSpeak", expr, + "1 grau, vírgula, 2 graus, vírgula, \ + 1 grau, vírgula, 2 graus, vírgula; \ + 1 minuto de arco, vírgula; 2 minutos de arco, vírgula; \ + 1 minuto de arco, vírgula; 2 minutos de arco, vírgula; \ + 1 minuto de arco, vírgula; 2 minutos de arco, vírgula; \ + 1 minuto de arco, vírgula; 2 minutos de arco, vírgula; \ + 1 segundo de arco, vírgula; 2 segundos de arco, vírgula; \ + 1 segundo de arco, vírgula; 2 segundos de arco")?; + return Ok(()); + +} + +#[test] +fn without_prefix_distance() -> Result<()> { + let expr = r#" + 1au,2au, + 1ltyr,2ltyr, + 1pc,2pc, + 1Å,2Å, + 1Å,2Å, + 1fm,2fm + "#; + test("pt", "SimpleSpeak", expr, + "1 unidade astronômica, vírgula; 2 unidades astronômicas, vírgula; 1 ano-luz, vírgula; 2 anos-luz, vírgula; 1 parsec, vírgula; 2 parsecs, vírgula; 1 angström, vírgula; 2 angströms, vírgula; 1 angström, vírgula; 2 angströms, vírgula, 1 fermi, vírgula; 2 fermis")?; + return Ok(()); + +} + +#[test] +fn without_prefix_other() -> Result<()> { + let expr = r#" + 1ha,2ha, + 1dB,2dB, + 1atm,2atm, + 1amu,2amu, + 1bar,2bar, + 1cal,2cal, + 1Ci,2Ci, + 1grad,2grad, + 1M,2M, + 1R,2R, + 1rpm,2rpm, + 1℧,2℧, + 1dyn,2dyn, + 1erg,2erg + "#; + test("pt", "SimpleSpeak", expr, + "1 hectare, vírgula; 2 hectares, vírgula; 1 decibel, vírgula; 2 decibéis, vírgula; 1 atmosfera, vírgula; 2 atmosferas, vírgula; 1 unidade de massa atômica, vírgula; 2 unidades de massa atômica; vírgula, 1 bar, vírgula, 2 bares, vírgula; 1 caloria, vírgula; 2 calorias, vírgula, 1 curie, vírgula; 2 curies, vírgula, 1 grado, vírgula; 2 grados, vírgula, 1 molar, vírgula; 2 molares, vírgula; 1 roentgen, vírgula; 2 roentgens, vírgula; 1 rotação por minuto, vírgula; 2 rotações por minuto, vírgula, 1 mho, vírgula, 2 mhos, vírgula, 1 dina, vírgula, 2 dinas, vírgula, 1 erg, vírgula, 2 ergs")?; + return Ok(()); + +} + +#[test] +fn metro() -> Result<()> { + // this is a special case in Spanish + let expr = r#" + 1m, + 2m, + 1Gm, + 2Gm, + 1Mm, + 2Mm, + 1km, + 2km, + 1hm, + 2hm, + 1dam, + 2dam, + 1mm, + 2mm + "#; + test("pt", "SimpleSpeak", expr, + "1 metro, vírgula; 2 metros, vírgula; 1 gigâmetro, vírgula; 2 gigâmetros, vírgula; 1 megâmetro, vírgula; 2 megâmetros, vírgula; 1 quilômetro, vírgula; 2 quilômetros, vírgula; 1 hectômetro, vírgula; 2 hectômetros, vírgula; 1 decâmetro, vírgula; 2 decâmetros, vírgula; 1 milímetro, vírgula; 2 milímetros")?; + return Ok(()); + +} + +#[test] +fn without_prefix_powers_of_2() -> Result<()> { + let expr = r#" + 1Kib,2Kib, + 1Mib,2Mib, + 1Gib,2Gib, + 1Tib,2Tib, + 1Pib,2Pib, + 1Eib,2Eib, + 1Zib,2Zib, + 1Yib,2Yib, + 1KiB,2KiB, + 1MiB,2MiB, + 1GiB,2GiB, + 1TiB,2TiB, + 1PiB,2PiB, + 1EiB,2EiB, + 1ZiB,2ZiB, + 1YiB,2YiB + "#; + test("pt", "SimpleSpeak", expr, + "1 kibibit, vírgula; 2 kibibits, vírgula; 1 mebibit, vírgula; 2 mebibits, vírgula; 1 gibibit, vírgula; 2 gibibits, vírgula; 1 tebibit, vírgula; 2 tebibits, vírgula; 1 pebibit, vírgula; 2 pebibits, vírgula; 1 exbibit, vírgula; 2 exbibits, vírgula; 1 zebibit, vírgula; 2 zebibits, vírgula; 1 yobibit, vírgula; 2 yobibits, vírgula; 1 kibibyte, vírgula; 2 kibibytes, vírgula; 1 mebibyte, vírgula; 2 mebibytes, vírgula; 1 gibibyte, vírgula; 2 gibibytes, vírgula; 1 tebibyte, vírgula; 2 tebibytes, vírgula; 1 pebibyte, vírgula; 2 pebibytes, vírgula; 1 exbibyte, vírgula; 2 exbibytes, vírgula; 1 zebibyte, vírgula; 2 zebibytes, vírgula; 1 yobibyte, vírgula; 2 yobibytes")?; + return Ok(()); + +} + + +#[test] +fn si_other_numbers() -> Result<()> { + let expr = r#"1.0l, + 2.0 m, + x ms, + yµs, + dag, + 1235daN, + 2.5µsec, + 32.34mol"#; + test("pt", "SimpleSpeak", expr, + "10 litro, vírgula; 20 metros, vírgula; x milissegundos, vírgula; y microssegundos, vírgula, decagramas vírgula; 1235 decanewtons, vírgula; 25 microssegundos, vírgula; 3234 mols")?; + return Ok(()); + +} + + +#[test] +fn test_mtext_inference() -> Result<()> { + let expr = r#"[ + 1t, + 2PA, + 3Pa, + 4.5mT + ]"#; + test("pt", "SimpleSpeak", expr, + "abre colchetes; 1 tonelada, vírgula; 2 petaampères, vírgula; 3 pascals, vírgula; 45 militeslas; fecha colchetes")?; + return Ok(()); + +} + diff --git a/tests/languages.rs b/tests/languages.rs index b0552b95b..287b53652 100644 --- a/tests/languages.rs +++ b/tests/languages.rs @@ -12,6 +12,7 @@ mod Languages { mod fi; mod pl; mod sv; + mod pt; mod nb; mod de; mod fr; From aaad7468e1fb0bc266a5855253bfcd7d6561ed18 Mon Sep 17 00:00:00 2001 From: NSoiffer Date: Wed, 2 Sep 2026 06:39:05 -0700 Subject: [PATCH 084/157] Release candidate (#743) * Add UEB G1 BANA/GTM mode preference and expand Grade-2 contractions. Adding the preference is a stall tactic while I wait for feedback from ICEB about whether BANA rules are obsolete. Introduce UEB_G1_BANA_Style (default true) to choose BANA 2019 vs ICEB GTM 1.7.3/1.7.5 grade-1 indicator placement in ueb_cleanup. Implement GTM 1.7 per-symbols-sequence counting with gtm_1_7_mode, and add matching ICEB tests. Extend handle_contractions for technical vocabulary: UEB 10.8 final-letter groupsigns, dot-5 through/part, dis/con prefixes, cc/ea exception words, and a ful-pattern fix. Add ueb_technical_word_contractions (311 words, goldens cross-checked with brailletranslators.com). Wire the preference through prefs, fuzz, and docs. * updated to new BANA and ICEB spec updates. Five tests fail. Still working on them * removed an option * fix contractions involving 'be, con, dis' which can only be at the start of a 'word' (where 'word' has a specific UEB meaning) * Updated to UEB to the latest guidance for grade 1 indicators. This adds new tests and changes a few tests. Also added more contractions. * update rc # * fix new clippy warnings * fix up Vietanmese tests * fix str compile issue with no-unsafe feature --- AGENTS.md | 3 +- Cargo.toml | 2 +- PythonScripts/audit_translations/README.md | 11 +- PythonScripts/audit_translations/auditor.py | 34 +- PythonScripts/audit_translations/cli.py | 14 +- .../tests/test_cli_end_to_end.py | 74 - Rules/Braille/Nemeth/unicode-full.yaml | 2728 ++++++++--------- Rules/Braille/UEB/UEB_Rules.yaml | 9 +- Rules/prefs.yaml | 1 + docs/users.md | 42 +- src/braille.rs | 980 +++++- tests/braille/UEB/iceb.rs | 1103 ++++++- tests/braille/UEB/other.rs | 21 +- 13 files changed, 3176 insertions(+), 1846 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index c6ca9e756..7093cf698 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,7 +13,7 @@ but add common mistakes of AI agents here instead. - `ClearSpeak_Rules.yaml`, `SimpleSpeak_Rules.yaml` - `SharedRules/`, `unicode.yaml`, `unicode-full.yaml`, `definitions.yaml`, `navigate.yaml` - `build.rs` can bundle rules into `rules.zip` when `include-zip` is enabled (always the minimized tree). Shared zipper: `src/rules_archive.rs`, invoked as `cargo run --bin package-rules -- Rules [--minimize]`. -- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (flow-style rewrite of all YAML: comments dropped). Each language/braille subdir is stored as `/.zip`; top-level and `Intent/` YAML stay loose. Inner language zips use BZIP2; the outer downloadable archive uses DEFLATE so `unzip` works. Both omit `Languages/zz`; the `test-rules-package` job restores `zz` from git after unzip so unit tests still run against release-like archives. +- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (comments stripped from `Languages/**/unicode.yaml` and `unicode-full.yaml` only). Each language/braille subdir is stored as `/.zip`; top-level and `Intent/` YAML stay loose. Inner language zips use BZIP2; the outer downloadable archive uses DEFLATE so `unzip` works. Both omit `Languages/zz`; the `test-rules-package` job restores `zz` from git after unzip so unit tests still run against release-like archives. ## Translation Conventions - `t:` means untranslated or unverified. @@ -33,6 +33,7 @@ but add common mistakes of AI agents here instead. - Do not mirror README content here; keep guidance agent-specific. - Avoid broad formatting sweeps; do not run `cargo fmt` in this repo. - Keep code/rule changes focused and validate with targeted tests first: `cargo test ` +- Do **not** change test goldens (expected braille/speech/nav strings) unless the user explicitly says to. Prefer fixing code/rules to match existing goldens; if a golden looks wrong vs the spec, ask before editing it. - do not do any git commands unless explicitly asked for - Rust coverage is in `target/coverage/`. - When working with GitHub, e.g. looking at PRs and issues, check if the GitHub CLI is installed (`gh --version`). diff --git a/Cargo.toml b/Cargo.toml index fcf5428d9..2e73cbf80 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mathcat" -version = "0.7.7-alpha.1" +version = "0.7.6-rc.4" authors = ["Neil Soiffer "] license = "MIT" description = "MathCAT: Math Capable Assistive Technology ('Speech and braille from MathML')" diff --git a/PythonScripts/audit_translations/README.md b/PythonScripts/audit_translations/README.md index fd399e412..8aedf1265 100644 --- a/PythonScripts/audit_translations/README.md +++ b/PythonScripts/audit_translations/README.md @@ -77,7 +77,6 @@ uv run --project PythonScripts audit-translations --list * Region variants are shown as `lang-region` (e.g., `zz-aa`) based on subdirectories under `Rules/Languages/`. * `--source`: Sets the source/reference language. Defaults to `en`. * `--file`: Audits a single specific file instead of the whole directory. -* `--exclude`: Exclude one or more files from the audit. * `--rules-dir`: Override the Rules/Languages directory path. * `--only`: Filter issue types (comma-separated): `missing`, `untranslated`, `extra`, `diffs`, `all`. * `--verbose`: Show detailed output including source/target snippets for rule differences. @@ -101,17 +100,9 @@ uv run audit-translations de # Compare Norwegian Bokmal against Swedish instead of English uv run audit-translations nb --source sv -# Audit only a specific file (note: --file is incompatible with --exclude) -uv run audit-translations es --file ClearSpeak_Rules.yaml +# Audit only a specific file uv run audit-translations es --file SharedRules/default.yaml -# Exclude a list of files from the audit, note that if you use this option before specifying the -# target language you'll need to use the option terminator (--). -# (note: --exclude is incompatible with --file) -uv run audit-translations es --exclude unicode-full.yaml -uv run audit-translations es --exclude unicode-full.yaml unicode.yaml -uv run audit-translations --exclude unicode-full.yaml -- es - # Audit a regional variant (merges Rules/Languages/de and Rules/Languages/de/CH) uv run audit-translations de-CH diff --git a/PythonScripts/audit_translations/auditor.py b/PythonScripts/audit_translations/auditor.py index 37ec44f13..b67cbf911 100644 --- a/PythonScripts/audit_translations/auditor.py +++ b/PythonScripts/audit_translations/auditor.py @@ -46,31 +46,24 @@ def is_definitions_file(file_path: str | Path) -> bool: return Path(file_path).name == "definitions.yaml" -def get_yaml_files(lang_dir: Path, region_dir: Path | None = None, excluded_files: list[str] | None = None) -> list[Path]: +def get_yaml_files(lang_dir: Path, region_dir: Path | None = None) -> list[Path]: """Get all YAML files to audit for a language, including region overrides.""" files: set[Path] = set() - def collect_from(directory: Path, root: Path, excluded: list[str] | None) -> None: + def collect_from(directory: Path, root: Path) -> None: if not directory.exists(): return - - excluded_paths = {Path(path) for path in excluded or []} - - candidates = {f for f in directory.glob("*.yaml") if f.name != "prefs.yaml"} - candidates.update((directory / "SharedRules").glob("*.yaml")) - - relative_candidates = {f.relative_to(directory): f for f in candidates} - - for path in excluded_paths - relative_candidates.keys(): - console.print(f"\n[yellow]⚠ Warning:[/] File to exclude {path} does not exist.") - - files.update( - f.relative_to(root) for relative_path, f in relative_candidates.items() if relative_path not in excluded_paths - ) - - collect_from(lang_dir, lang_dir, excluded_files) + for f in directory.glob("*.yaml"): + if f.name != "prefs.yaml": + files.add(f.relative_to(root)) + shared_dir = directory / "SharedRules" + if shared_dir.exists(): + for f in shared_dir.glob("*.yaml"): + files.add(f.relative_to(root)) + + collect_from(lang_dir, lang_dir) if region_dir: - collect_from(region_dir, region_dir, excluded_files) + collect_from(region_dir, region_dir) return sorted(files) @@ -222,7 +215,6 @@ def merge_definitions( def audit_language( language: str, specific_file: str | None = None, - excluded_files: list[str] | None = None, rules_dir: str | None = None, issue_filter: set[str] | None = None, verbose: bool = False, @@ -256,7 +248,7 @@ def audit_language( raise AuditError(f"Target region directory not found: {translated_region_dir}") # Get list of files to audit - files = [specific_file] if specific_file else get_yaml_files(source_dir, source_region_dir, excluded_files) + files = [specific_file] if specific_file else get_yaml_files(source_dir, source_region_dir) print_audit_header(language, len(files), source_language) diff --git a/PythonScripts/audit_translations/cli.py b/PythonScripts/audit_translations/cli.py index 5bdf30e6d..6916a636e 100644 --- a/PythonScripts/audit_translations/cli.py +++ b/PythonScripts/audit_translations/cli.py @@ -30,18 +30,7 @@ def main() -> None: parser.add_argument("language", nargs="?", help="Language code to audit (e.g., 'es', 'de', 'fi')") parser.add_argument("--source", default="en", help="Source/reference language code (default: 'en')") - file_group = parser.add_mutually_exclusive_group() - file_group.add_argument( - "--file", - dest="specific_file", - help="Audit only a specific file (e.g., 'SharedRules/default.yaml')", - ) - file_group.add_argument( - "--exclude", - nargs="+", - dest="excluded_files", - help="Exclude a list of files from the audit.", - ) + parser.add_argument("--file", dest="specific_file", help="Audit only a specific file (e.g., 'SharedRules/default.yaml')") parser.add_argument("--list", action="store_true", help="List available languages") parser.add_argument("--rules-dir", help="Override Rules/Languages directory path") parser.add_argument( @@ -78,7 +67,6 @@ def main() -> None: audit_language( args.language, args.specific_file, - args.excluded_files, args.rules_dir, issue_filter, args.verbose, diff --git a/PythonScripts/audit_translations/tests/test_cli_end_to_end.py b/PythonScripts/audit_translations/tests/test_cli_end_to_end.py index 40cf3f8b2..7876bc0de 100644 --- a/PythonScripts/audit_translations/tests/test_cli_end_to_end.py +++ b/PythonScripts/audit_translations/tests/test_cli_end_to_end.py @@ -127,80 +127,6 @@ def test_cli_main_rich_only_filters_issue_groups(capsys, monkeypatch) -> None: assert "Structure Differences" not in output -@pytest.mark.parametrize( - ("excluded_file", "expected_file", "expected_rule", "unexpected_rule"), - [ - ( - "default.yaml", - "SharedRules/default.yaml", - "shared-only", - "root-only", - ), - ( - "SharedRules/default.yaml", - "default.yaml", - "root-only", - "shared-only", - ), - ], - ids=["exclude-root", "exclude-shared-rules"], -) -def test_cli_main_exclude_uses_relative_paths( - tmp_path, - capsys, - monkeypatch, - excluded_file, - expected_file, - expected_rule, - unexpected_rule, -) -> None: - """Ensure --exclude distinguishes root files from SharedRules files.""" - rules_dir = tmp_path / "Rules" / "Languages" - source_dir = rules_dir / "en" - target_dir = rules_dir / "de" - - (source_dir / "SharedRules").mkdir(parents=True) - (target_dir / "SharedRules").mkdir(parents=True) - - (source_dir / "default.yaml").write_text( - '- name: root-only\n tag: mo\n match: ".//m:mi"\n replace:\n - t: "root"\n', - encoding="utf-8", - ) - (source_dir / "SharedRules" / "default.yaml").write_text( - '- name: shared-only\n tag: mo\n match: ".//m:mi"\n replace:\n - t: "shared"\n', - encoding="utf-8", - ) - - target_rule = '- name: target-only\n tag: mo\n match: ".//m:mi"\n replace:\n - t: "target"\n' - (target_dir / "default.yaml").write_text( - target_rule, - encoding="utf-8", - ) - (target_dir / "SharedRules" / "default.yaml").write_text( - target_rule, - encoding="utf-8", - ) - - args = [ - "de", - "--rules-dir", - str(rules_dir), - "--exclude", - excluded_file, - "--only", - "missing", - ] - monkeypatch.setattr(sys, "argv", ["audit_translations", *args]) - - audit_cli.main() - output = strip_ansi(capsys.readouterr().out) - - assert "Files to check: 1" in output - assert expected_file in output - assert expected_rule in output - assert unexpected_rule not in output - - def test_cli_main_accepts_source_language(capsys, monkeypatch) -> None: """ Ensure --source changes the reference language without changing target semantics. diff --git a/Rules/Braille/Nemeth/unicode-full.yaml b/Rules/Braille/Nemeth/unicode-full.yaml index bf4f842ea..30ffc561d 100644 --- a/Rules/Braille/Nemeth/unicode-full.yaml +++ b/Rules/Braille/Nemeth/unicode-full.yaml @@ -1,1364 +1,1364 @@ ---- -# To greatly simplify typeface/language generation, the chars have unique ASCII chars for them: -# Typeface: S: sans-serif, B: bold, T: script/blackboard, I: italic, R: Roman -# Language: E: English, D: German, G: Greek, V: Greek variants, H: Hebrew, U: Russian -# Indicators: C: capital, L: letter, N: number, P: punctuation, M: multipurpose -# Others: W -- whitespace that should be kept (e.g, in a numeral) -# SRE doesn't have H: Hebrew, so not encoded (yet) -# Some of the weird letters (e.g., circled letters) I didn't translate with the above because -# they don't interact with rules since they are enclosed in other chars. - - - "⨯": [t: "⠈⠡"] # U+2A2F(VECTOR OR CROSS PRODUCT) -- make the same as 0x00D7 (Multiplication sign) - - # --- Nemeth Default Alphabet bold chars. --- - - "𝐀-𝐙": # 0x1d400 - 0x1d419 - - tc: "BE" - - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - "𝐚-𝐳": # 0x1d41a - 0x1d433 - - tc: "BE" - - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 - - tc: "BG" - - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" - - - "𝛂-𝛒": # 0x1d6c2 - 0x1d6d2 - - tc: "BG" - - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒', 'αβγδεζηθικλμνξοπρ')" - - - "𝛔-𝛖": # 0x1d6d4 - 0x1d6d6 - - tc: "BG" - - spell: "translate('.', '𝛔𝛕𝛖', 'στυ')" - - - "𝛘-𝛚": # 0x1d6d8 - 0x1d6da - - tc: "BG" - - spell: "translate('.', '𝛘𝛙𝛚', 'χψω')" - - - "𝛁": [tc: "BGL⠫"] # 0x1d6c1 - - "𝛓": [tc: "BVL⠎"] # 0x1d6d3 - - "𝛗": [tc: "BVL⠋"] # 0x1d6d7 - - "𝛛": [tc: "⠸⠈⠙"] # 0x1d6db - - "𝛜": [tc: "BGL⠑"] # 0x1d6dc - - "𝛝": [tc: "BVL⠹"] # 0x1d6dd - - "𝛞": [tc: "BGL⠅"] # 0x1d6de - - "𝛟": [tc: "BGL⠋"] # 0x1d6df - - "𝛠": [tc: "BGL⠗"] # 0x1d6e0 - - "𝛡": [tc: "BGL⠏"] # 0x1d6e1 - - - "𝟎-𝟗": # 0x1d7ce - 0x1d7d7 - - tc: "B" - - spell: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" - - # --- Nemeth Default Alphabet bold-fraktur chars. --- - - - "𝕬-𝖅": # 0x1d56c - 0x1d585 - - tc: "BD" - - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝖆-𝖟": # 0x1d586 - 0x1d59f - - tc: "BD" - - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" - - # --- Nemeth Default Alphabet bold-italic chars. --- - - "𝑨-𝒁": # 0x1d468 - 0x1d481 - - tc: "BE" - - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝒂-𝒛": # 0x1d482 - 0x1d49b - - tc: "BE" - - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝜜-𝜴": # 0x1d71c - 0x1d734 - - tc: "BG" - - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" - - - "𝜵": [tc: "BGL⠫"] # 0x1d735 - - - "𝜶-𝝆": # 0x1d736 - 0x1d746 - - tc: "BG" - - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆', 'αβγδεζηθικλμνξοπρ')" - - - "𝝇": [tc: "BVL⠎"] # 0x1d747 - - - "𝝈-𝝊": # 0x1d748 - 0x1d74a - - tc: "BG" - - spell: "translate('.', '𝝈𝝉𝝊', 'στυ')" - - - "𝝋": [tc: "BVL⠋"] # 0x1d74b - - - "𝝌-𝝎": # 0x1d74c - 0x1d74e - - tc: "BG" - - spell: "translate('.', '𝝌𝝍𝝎', 'χψω')" - - - "𝝏": [tc: "BVL⠙"] # 0x1d74f - - "𝝐": [tc: "BGL⠑"] # 0x1d750 - - "𝝑": [tc: "BVL⠹"] # 0x1d751 - - - "𝝒-𝝕": # 0x1d752 - 0x1d755 - - tc: "BG" - - spell: "translate('.', '𝝒𝝓𝝔𝝕', 'κφρπ')" - - # --- Nemeth Default Alphabet bold-script chars. --- - - - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 - - tc: "BTE" - - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝓪-𝔃": # 0x1d4ea - 0x1d503 - - tc: "BTE" - - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝚤-𝚥": # 0x1d6a4 - 0x1d6a5 - - tc: "" - - spell: "translate('.', '𝚤𝚥', '⠊⠚')" - -# Russian Alphabet (from Nemeth book) -# NOTE: is this translation needed? - - "А-Я": # 0x410 - 0x42f - - tc: "U" - - spell: "translate('.', 'АБВГДЕЗИЙКЛМНОПРСТУФЭ', 'ABVGDEZIYKLMNOPRSTUFE')" - - - "а-я": # 0x430 - 0x44f - - tc: "U" - - spell: "translate('.', 'абвгдезийклмнопрстуфэ', 'abvgdeziylkmnoprstufye')" - - - "①-⑨": # 0x2460 - 0x2473 - - tc: "⠫⠉⠸⠫⠼" - - spell: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" - - tc: "⠻" - - - "⓪": [tc: "⠫⠉⠸⠫⠼⠴⠻"] # 0x24ea - - - "⑩": [tc: "⠫⠉⠸⠫⠼⠂⠴⠻"] # 0x2469 - - "⑪": [tc: "⠫⠉⠸⠫⠼⠂⠂⠻"] # 0x246a - - "⑫": [tc: "⠫⠉⠸⠫⠼⠂⠆⠻"] # 0x246b - - "⑬": [tc: "⠫⠉⠸⠫⠼⠂⠒⠻"] # 0x246c - - "⑭": [tc: "⠫⠉⠸⠫⠼⠂⠲⠻"] # 0x246d - - "⑮": [tc: "⠫⠉⠸⠫⠼⠂⠢⠻"] # 0x246e - - "⑯": [tc: "⠫⠉⠸⠫⠼⠂⠖⠻"] # 0x246f - - "⑰": [tc: "⠫⠉⠸⠫⠼⠂⠶⠻"] # 0x2470 - - "⑱": [tc: "⠫⠉⠸⠫⠼⠂⠦⠻"] # 0x2471 - - "⑲": [tc: "⠫⠉⠸⠫⠼⠂⠔⠻"] # 0x2472 - - "⑳": [tc: "⠫⠉⠸⠫⠼⠆⠴⠻"] # 0x2473 - - - "㉑": [tc: "⠫⠉⠸⠫⠼⠆⠂⠻"] # 0x3251 - - "㉒": [tc: "⠫⠉⠸⠫⠼⠆⠆⠻"] # 0x3252 - - "㉓": [tc: "⠫⠉⠸⠫⠼⠆⠒⠻"] # 0x3253 - - "㉔": [tc: "⠫⠉⠸⠫⠼⠆⠲⠻"] # 0x3254 - - "㉕": [tc: "⠫⠉⠸⠫⠼⠆⠢⠻"] # 0x3255 - - "㉖": [tc: "⠫⠉⠸⠫⠼⠆⠖⠻"] # 0x3256 - - "㉗": [tc: "⠫⠉⠸⠫⠼⠆⠶⠻"] # 0x3257 - - "㉘": [tc: "⠫⠉⠸⠫⠼⠆⠦⠻"] # 0x3258 - - "㉙": [tc: "⠫⠉⠸⠫⠼⠆⠔⠻"] # 0x3259 - - "㉚": [tc: "⠫⠉⠸⠫⠼⠒⠴⠻"] # 0x325a - - "㉛": [tc: "⠫⠉⠸⠫⠼⠒⠂⠻"] # 0x325b - - "㉜": [tc: "⠫⠉⠸⠫⠼⠒⠆⠻"] # 0x325c - - "㉝": [tc: "⠫⠉⠸⠫⠼⠒⠒⠻"] # 0x325d - - "㉞": [tc: "⠫⠉⠸⠫⠼⠒⠲⠻"] # 0x325e - - "㉟": [tc: "⠫⠉⠸⠫⠼⠒⠢⠻"] # 0x325f - - "㊱": [tc: "⠫⠉⠸⠫⠼⠒⠖⠻"] # 0x32b1 - - "㊲": [tc: "⠫⠉⠸⠫⠼⠒⠶⠻"] # 0x32b2 - - "㊳": [tc: "⠫⠉⠸⠫⠼⠒⠦⠻"] # 0x32b3 - - "㊴": [tc: "⠫⠉⠸⠫⠼⠒⠔⠻"] # 0x32b4 - - "㊵": [tc: "⠫⠉⠸⠫⠼⠲⠴⠻"] # 0x32b5 - - "㊶": [tc: "⠫⠉⠸⠫⠼⠲⠂⠻"] # 0x32b6 - - "㊷": [tc: "⠫⠉⠸⠫⠼⠲⠆⠻"] # 0x32b7 - - "㊸": [tc: "⠫⠉⠸⠫⠼⠲⠒⠻"] # 0x32b8 - - "㊹": [tc: "⠫⠉⠸⠫⠼⠲⠲⠻"] # 0x32b9 - - "㊺": [tc: "⠫⠉⠸⠫⠼⠲⠢⠻"] # 0x32ba - - "㊻": [tc: "⠫⠉⠸⠫⠼⠲⠖⠻"] # 0x32bb - - "㊼": [tc: "⠫⠉⠸⠫⠼⠲⠶⠻"] # 0x32bc - - "㊽": [tc: "⠫⠉⠸⠫⠼⠲⠦⠻"] # 0x32bd - - "㊾": [tc: "⠫⠉⠸⠫⠼⠲⠔⠻"] # 0x32be - - "㊿": [tc: "⠫⠉⠸⠫⠼⠢⠴⠻"] # 0x32bf - -#NOTE: uncertainty here - - "Ⓐ-Ⓩ": # 0x24b6 - 0x24cf - - tc: "⠫⠉⠸⠫⠠" - - spell: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - tc: "⠻" - - - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 - - tc: "⠫⠉⠸⠫" - - spell: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" - - tc: "⠻" - - # --- Nemeth Default Alphabet circled-sans-serif chars. --- - - - "➀-➈": # 0x1f10b, 0x2780 - 0x2788 - - tc: "⠫⠉⠸⠫⠠⠨⠼" - - spell: "translate('.', '➀➁➂➃➄➅➆➇➈', '123456789')" - - tc: "⠻" - - - "🄋": [tc: "⠫⠉⠸⠫⠠⠨⠼⠴⠻"] # 0x1f10b - - "➉": [tc: "⠫⠉⠸⠫⠠⠨⠼⠂⠴⠻"] # 0x2789 - - # --- Nemeth Default Alphabet comma chars. --- - - - "🄁-🄊": # 0x1f101 - 0x1f10a - - spell: "translate('.', '🄁🄂🄃🄄🄅🄆🄇🄈🄉🄊', '0123456789')" - - tc: "⠠" - - - # --- Nemeth Default Alphabet double-circled chars. --- - - - "⓵": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠂⠻⠻"] # 0x24f5 - - "⓶": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠆⠻⠻"] # 0x24f6 - - "⓷": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠒⠻⠻"] # 0x24f7 - - "⓸": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠲⠻⠻"] # 0x24f8 - - "⓹": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠢⠻⠻"] # 0x24f9 - - "⓺": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠖⠻⠻"] # 0x24fa - - "⓻": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠶⠻⠻"] # 0x24fb - - "⓼": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠦⠻⠻"] # 0x24fc - - "⓽": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠔⠻⠻"] # 0x24fd - - "⓾": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠂⠴⠻⠻"] # 0x24fe - - # --- Nemeth Default Alphabet double-struck chars. --- - - "𝔸-𝕐": # 0x1d538 - 0x1d550 (partial, excludes ℂ ℍ ℕ ℙ ℚ ℝ ℤ) - - tc: "𝔹E" - - spell: "translate('.', '𝔸𝔹𝔻𝔼𝔽𝔾𝕀𝕁𝕂𝕃𝕄𝕆𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABDEFGIJKLMOSTUVWXY')" - - - "ℂ": [tc: "𝔹ECL⠉"] # 0x2102 - - "ℍ": [tc: "𝔹ECL⠓"] # 0x210d - - "ℕ": [tc: "𝔹ECL⠝"] # 0x2115 - - "ℙ": [tc: "𝔹ECL⠏"] # 0x2119 - - "ℚ": [tc: "𝔹ECL⠟"] # 0x211a - - "ℝ": [tc: "𝔹ECL⠗"] # 0x211d - - "ℤ": [tc: "𝔹ECL⠵"] # 0x2124 - - "Ω": [t: "CGL⠺"] # 0x2126 (Ohm sign (capital Greek omega)) - - - "𝕒-𝕫": # 0x1d552 - 0x1d56b - - tc: "𝔹E" - - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 - - tc: "𝔹" - - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" - - - # --- Nemeth Default Alphabet fraktur chars. --- - - - "𝔄-𝔜": # 0x1d504 - 0x1d51c - - tc: "D" - - spell: "translate('.', '𝔄𝔅𝔇𝔈𝔉𝔊𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABDEFGJKLMNOPQSTUVWXY')" - - - "ℭ": [tc: "DCL⠉"] # 0x212d - - "ℌ": [tc: "DCL⠓"] # 0x210c - - "ℑ": [tc: "DCL⠊"] # 0x2111 - - "ℜ": [tc: "DCL⠗"] # 0x211c - - "ℨ": [tc: "DCL⠵"] # 0x2128 - - - "𝔞-𝔷": # 0x1d51e - 0x1d537 - - tc: "D" - - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" - - # --- Nemeth Default Alphabet fullwidth chars. --- - - - "A-Z": # 0xff21 - 0xff3a - - tc: "" - - spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "a-z": # 0xff41 - 0xff5a - - tc: "" - - spell: "translate('.', 'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz')" - - - "0-9": # 0xff10 - 0xff19 - - tc: "" - - spell: "translate('.', '0123456789', '0123456789')" - - # --- Nemeth Default Alphabet italic chars -- treat as non-italic. --- - - - "𝐴-𝑍": # 0x1d434 - 0x1d44d - - tc: "E" - - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝑎-𝑧": # 0x1d44e - 0x1d467 - - tc: "E" - - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔ℎ𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa - - tc: "G" - - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" - - - "𝛻": [tc: "GL⠫"] # 0x1d6fb - - - "𝛼-𝜌": # 0x1d6fc - 0x1d70c - - tc: "G" - - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌', 'αβγδεζηθικλμνξοπρ')" - - "𝜍": [tc: "VL⠎"] # 0x1d70d - - - "𝜎": [tc: "GL⠎"] # 0x1d70e - - "𝜏": [tc: "GL⠞"] # 0x1d70f - - "𝜐": [tc: "GL⠥"] # 0x1d710 - - - "𝜑": [tc: "VL⠋"] # 0x1d711 - - - "𝜒": [tc: "GL⠯"] # 0x1d712 - - "𝜓": [tc: "GL⠽"] # 0x1d713 - - "𝜔": [tc: "GL⠺"] # 0x1d714 - - - "𝜕": [tc: "VL⠙"] # 0x1d715 - - - "𝜖": [tc: "GL⠑"] # 0x1d716 - - - "𝜗": [tc: "VL⠹"] # 0x1d717 - - - "𝜘": [tc: "GL⠅"] # 0x1d718 - - "𝜙": [tc: "GL⠋"] # 0x1d719 - - "𝜚": [tc: "GL⠗"] # 0x1d71a - - "𝜛": [tc: "GL⠏"] # 0x1d71b - - # --- Nemeth Default Alphabet monospace chars. --- - - - "𝙰-𝚉": # 0x1d670 - 0x1d689 - - tc: "" - - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 - - tc: "" - - spell: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝟶-𝟿": # 0x1d7f6 - 0x1d7ff - - tc: "" - - spell: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" - - - # --- Nemeth Default Alphabet negative-circled chars. --- - - "⓿": [t: "⠫⠸⠉⠸⠫⠼⠴⠻"] # 0x24ff - - "❶": [t: "⠫⠸⠉⠸⠫⠼⠂⠻"] # 0x2776 - - "❷": [t: "⠫⠸⠉⠸⠫⠼⠆⠻"] # 0x2777 - - "❸": [t: "⠫⠸⠉⠸⠫⠼⠒⠻"] # 0x2778 - - "❹": [t: "⠫⠸⠉⠸⠫⠼⠲⠻"] # 0x2779 - - "❺": [t: "⠫⠸⠉⠸⠫⠼⠢⠻"] # 0x277a - - "❻": [t: "⠫⠸⠉⠸⠫⠼⠖⠻"] # 0x277b - - "❼": [t: "⠫⠸⠉⠸⠫⠼⠶⠻"] # 0x277c - - "❽": [t: "⠫⠸⠉⠸⠫⠼⠦⠻"] # 0x277d - - "❾": [t: "⠫⠸⠉⠸⠫⠼⠔⠻"] # 0x277e - - "❿": [t: "⠫⠸⠉⠸⠫⠼⠂⠴⠻"] # 0x277f - - "⓫": [t: "⠫⠸⠉⠸⠫⠼⠂⠂⠻"] # 0x24eb - - "⓬": [t: "⠫⠸⠉⠸⠫⠼⠂⠆⠻"] # 0x24ec - - "⓭": [t: "⠫⠸⠉⠸⠫⠼⠂⠒⠻"] # 0x24ed - - "⓮": [t: "⠫⠸⠉⠸⠫⠼⠂⠲⠻"] # 0x24ee - - "⓯": [t: "⠫⠸⠉⠸⠫⠼⠂⠢⠻"] # 0x24ef - - "⓰": [t: "⠫⠸⠉⠸⠫⠼⠂⠖⠻"] # 0x24f0 - - "⓱": [t: "⠫⠸⠉⠸⠫⠼⠂⠶⠻"] # 0x24f1 - - "⓲": [t: "⠫⠸⠉⠸⠫⠼⠂⠦⠻"] # 0x24f2 - - "⓳": [t: "⠫⠸⠉⠸⠫⠼⠂⠔⠻"] # 0x24f3 - - "⓴": [t: "⠫⠸⠉⠸⠫⠼⠆⠴⠻"] # 0x24f4 - - - "🅐": [t: "⠫⠸⠉⠸⠫⠠⠁⠻"] # 0x1f150 - - "🅑": [t: "⠫⠸⠉⠸⠫⠠⠃⠻"] # 0x1f151 - - "🅒": [t: "⠫⠸⠉⠸⠫⠠⠉⠻"] # 0x1f152 - - "🅓": [t: "⠫⠸⠉⠸⠫⠠⠙⠻"] # 0x1f153 - - "🅔": [t: "⠫⠸⠉⠸⠫⠠⠑⠻"] # 0x1f154 - - "🅕": [t: "⠫⠸⠉⠸⠫⠠⠋⠻"] # 0x1f155 - - "🅖": [t: "⠫⠸⠉⠸⠫⠠⠛⠻"] # 0x1f156 - - "🅗": [t: "⠫⠸⠉⠸⠫⠠⠓⠻"] # 0x1f157 - - "🅘": [t: "⠫⠸⠉⠸⠫⠠⠊⠻"] # 0x1f158 - - "🅙": [t: "⠫⠸⠉⠸⠫⠠⠚⠻"] # 0x1f159 - - "🅚": [t: "⠫⠸⠉⠸⠫⠠⠅⠻"] # 0x1f15a - - "🅛": [t: "⠫⠸⠉⠸⠫⠠⠇⠻"] # 0x1f15b - - "🅜": [t: "⠫⠸⠉⠸⠫⠠⠍⠻"] # 0x1f15c - - "🅝": [t: "⠫⠸⠉⠸⠫⠠⠝⠻"] # 0x1f15d - - "🅞": [t: "⠫⠸⠉⠸⠫⠠⠕⠻"] # 0x1f15e - - "🅟": [t: "⠫⠸⠉⠸⠫⠠⠏⠻"] # 0x1f15f - - "🅠": [t: "⠫⠸⠉⠸⠫⠠⠟⠻"] # 0x1f160 - - "🅡": [t: "⠫⠸⠉⠸⠫⠠⠗⠻"] # 0x1f161 - - "🅢": [t: "⠫⠸⠉⠸⠫⠠⠎⠻"] # 0x1f162 - - "🅣": [t: "⠫⠸⠉⠸⠫⠠⠞⠻"] # 0x1f163 - - "🅤": [t: "⠫⠸⠉⠸⠫⠠⠥⠻"] # 0x1f164 - - "🅥": [t: "⠫⠸⠉⠸⠫⠠⠧⠻"] # 0x1f165 - - "🅦": [t: "⠫⠸⠉⠸⠫⠠⠺⠻"] # 0x1f166 - - "🅧": [t: "⠫⠸⠉⠸⠫⠠⠭⠻"] # 0x1f167 - - "🅨": [t: "⠫⠸⠉⠸⠫⠠⠽⠻"] # 0x1f168 - - "🅩": [t: "⠫⠸⠉⠸⠫⠠⠵⠻"] # 0x1f169 - - # --- Nemeth Default Alphabet negative-circled-sans-serif chars. --- - - "🄌": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠴⠻"] # 0x1f10c - - "➊": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠂⠻"] # 0x278a - - "➋": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠆⠻"] # 0x278b - - "➌": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠒⠻"] # 0x278c - - "➍": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠲⠻"] # 0x278d - - "➎": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠢⠻"] # 0x278e - - "➏": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠖⠻"] # 0x278f - - "➐": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠶⠻"] # 0x2790 - - "➑": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠦⠻"] # 0x2791 - - "➒": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠔⠻"] # 0x2792 - - "➓": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠂⠴⠻"] # 0x2793 - - # --- Nemeth Default Alphabet negative-squared chars. --- - - "🅰-🆉": # 0x1f170 - 0x1f189 - - tc: "⠫⠸⠲⠸⠫⠠" - - spell: "translate('.', '🅰🅱🅲🅳🅴🅵🅶🅷🅸🅹🅺🅻🅼🅽🅾🅿🆀🆁🆂🆃🆄🆅🆆🆇🆈🆉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - tc: "⠻" - - # --- Nemeth Default Alphabet parenthesized chars. --- - - - "⑴-⑼": # 0x2474 - 0x247c - - tc: "⠷" - - spell: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" - - tc: "⠾" - - - "⑽": [t: "⠷⠂⠴⠾"] # 0x247d - - "⑾": [t: "⠷⠂⠂⠾"] # 0x247e - - "⑿": [t: "⠷⠂⠆⠾"] # 0x247f - - "⒀": [t: "⠷⠂⠒⠾"] # 0x2480 - - "⒁": [t: "⠷⠂⠲⠾"] # 0x2481 - - "⒂": [t: "⠷⠂⠢⠾"] # 0x2482 - - "⒃": [t: "⠷⠂⠖⠾"] # 0x2483 - - "⒄": [t: "⠷⠂⠶⠾"] # 0x2484 - - "⒅": [t: "⠷⠂⠦⠾"] # 0x2485 - - "⒆": [t: "⠷⠂⠔⠾"] # 0x2486 - - "⒇": [t: "⠷⠆⠴⠾"] # 0x2487 - - - "🄐-🄩": # 0x1f110 - 0x1f129 - - tc: "⠷⠠" - - spell: "translate('.', '🄐🄑🄒🄓🄔🄕🄖🄗🄘🄙🄚🄛🄜🄝🄞🄟🄠🄡🄢🄣🄤🄥🄦🄧🄨🄩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - tc: "⠾" - - - "⒜-⒵": # 0x249c - 0x24b5 - - tc: "⠷" - - spell: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" - - tc: "⠾" - - # --- Nemeth Default Alphabet period chars. --- - - "🄀": [t: "⠴⠸⠲"] # 0x1f100 - - "⒈": [t: "⠂⠸⠲"] # 0x2488 - - "⒉": [t: "⠆⠸⠲"] # 0x2489 - - "⒊": [t: "⠒⠸⠲"] # 0x248a - - "⒋": [t: "⠲⠸⠲"] # 0x248b - - "⒌": [t: "⠢⠸⠲"] # 0x248c - - "⒍": [t: "⠖⠸⠲"] # 0x248d - - "⒎": [t: "⠶⠸⠲"] # 0x248e - - "⒏": [t: "⠦⠸⠲"] # 0x248f - - "⒐": [t: "⠔⠸⠲"] # 0x2490 - - - "⒑": [t: "⠂⠴⠸⠲"] # 0x2491 - - "⒒": [t: "⠂⠂⠸⠲"] # 0x2492 - - "⒓": [t: "⠂⠆⠸⠲"] # 0x2493 - - "⒔": [t: "⠂⠒⠸⠲"] # 0x2494 - - "⒕": [t: "⠂⠲⠸⠲"] # 0x2495 - - "⒖": [t: "⠂⠢⠸⠲"] # 0x2496 - - "⒗": [t: "⠂⠖⠸⠲"] # 0x2497 - - "⒘": [t: "⠂⠶⠸⠲"] # 0x2498 - - "⒙": [t: "⠂⠦⠸⠲"] # 0x2499 - - "⒚": [t: "⠂⠔⠸⠲"] # 0x249a - - "⒛": [t: "⠆⠴⠸⠲"] # 0x249b - - # --- Nemeth Default Alphabet sans-serif chars. --- - - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 - - tc: "SE" - - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 - - tc: "SE" - - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝟢-𝟫": # 0x1d7e2 - 0x1d7eb - - tc: "S" - - spell: "translate('.', '𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫', '0123456789')" - - # --- Nemeth Default Alphabet sans-serif-bold chars. --- - - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed - - tc: "SBE" - - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝗮-𝘇": # 0x1d5ee - 0x1d607 - - tc: "SBE" - - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝝖-𝝮": # 0x1d756 - 0x1d76e - - tc: "SBG" - - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" - - - "𝝰-𝞀": # 0x1d770 - 0x1d780 - - tc: "SBG" - - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀', 'αβγδεζηθικλμνξοπρ')" - - - "𝝯": [tc: "SBGL⠫"] # 0x1d76f - - - "𝞁": [tc: "SBVL⠎"] # 0x1d781 - - - "𝞂-𝞄": # 0x1d782 - 0x1d784 - - tc: "SBG" - - spell: "translate('.', '𝞂𝞃𝞄', 'στυ')" - - - "𝞅": [tc: "SBVL⠋"] # 0x1d785 - - - "𝞆-𝞈": # 0x1d786 - 0x1d788 - - tc: "SBG" - - spell: "translate('.', '𝞆𝞇𝞈', 'χψω')" - - - "𝞉": [tc: "⠠⠨⠸⠈⠙"] # 0x1d789 - - "𝞊": [tc: "SBGL⠑"] # 0x1d78a - - "𝞋": [tc: "SBVL⠹"] # 0x1d78b - - - "𝞌-𝞏": # 0x1d78c - 0x1d78f - - tc: "SBG" - - spell: "translate('.', '𝞌𝞍𝞎𝞏', 'κφρπ')" - - - "𝟬-𝟵": # 0x1d7ec - 0x1d7f5 - - tc: "SB" - - spell: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" - - # --- Nemeth Default Alphabet sans-serif-bold-italic chars. --- - - - "𝘼-𝙕": # 0x1d63c - 0x1d655 - - tc: "SBE" - - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝙖-𝙯": # 0x1d656 - 0x1d66f - - tc: "SBE" - - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 - - tc: "SBG" - - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" - - - "𝞩": [t: "SBGL⠫"] # 0x1d7a9 - - - "𝞪-𝞺": # 0x1d7aa - 0x1d7ba - - tc: "SBG" - - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺', 'αβγδεζηθικλμνξοπρ')" - - - "𝞻": [t: "SBVL⠎"] # 0x1d7bb - - "𝞼": [t: "SBGL⠎"] # 0x1d7bc - - "𝞽": [t: "SBGL⠞"] # 0x1d7bd - - "𝞾": [t: "SBGL⠥"] # 0x1d7be - - "𝞿": [t: "SBVL⠋"] # 0x1d7bf - - - "𝟀": [t: "SBGL⠯"] # 0x1d7c0 - - "𝟁": [t: "SBGL⠽"] # 0x1d7c1 - - "𝟂": [t: "SBGL⠺"] # 0x1d7c2 - - "𝟃": [t: "SBVL⠙"] # 0x1d7c3 - - - "𝟄": [t: "SBGL⠑"] # 0x1d7c4 - - "𝟅": [t: "SBVL⠹"] # 0x1d7c5 - - - "𝟆": [t: "SBGL⠅"] # 0x1d7c6 - - "𝟇": [t: "SBGL⠋"] # 0x1d7c7 - - "𝟈": [t: "SBGL⠗"] # 0x1d7c8 - - "𝟉": [t: "SBGL⠏"] # 0x1d7c9 - - # --- Nemeth Default Alphabet sans-serif-italic chars. --- - - "𝘈-𝘡": # 0x1d608 - 0x1d621 - - tc: "SE" - - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝘢-𝘻": # 0x1d622 - 0x1d63b - - tc: "SE" - - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" - - # --- Nemeth Default Alphabet script chars. --- - - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 - - tc: "TE" - - spell: "translate('.', '𝒜𝒞𝒟𝒢𝒥𝒦𝒩𝒪𝒫𝒬𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ACDGJKNOPQSTUVWXYZ')" - - - "ℬ": [t: "TECL⠃"] # 0x212c - - "ℰ": [t: "TECL⠑"] # 0x2130 - - "ℱ": [t: "TECL⠋"] # 0x2131 - - "ℋ": [t: "TECL⠓"] # 0x210b - - "ℐ": [t: "TECL⠊"] # 0x2110 - - "ℒ": [t: "TECL⠇"] # 0x2112 - - "ℳ": [t: "TECL⠍"] # 0x2133 - - "ℛ": [t: "TECL⠗"] # 0x211b - - - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf - - tc: "TE" - - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒻𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdfhijklmnpqrstuvwxyz')" - - - "ℯ": [t: "TEL⠑"] # 0x212f - - "ℊ": [t: "TEL⠛"] # 0x210a - - "ℴ": [t: "TEL⠕"] # 0x2134 - - # --- Nemeth Default Alphabet squared chars. --- - - - "🄰": [t: "⠫⠲⠸⠫⠠⠁⠻"] # 0x1f130 - - "🄱": [t: "⠫⠲⠸⠫⠠⠃⠻"] # 0x1f131 - - "🄲": [t: "⠫⠲⠸⠫⠠⠉⠻"] # 0x1f132 - - "🄳": [t: "⠫⠲⠸⠫⠠⠙⠻"] # 0x1f133 - - "🄴": [t: "⠫⠲⠸⠫⠠⠑⠻"] # 0x1f134 - - "🄵": [t: "⠫⠲⠸⠫⠠⠋⠻"] # 0x1f135 - - "🄶": [t: "⠫⠲⠸⠫⠠⠛⠻"] # 0x1f136 - - "🄷": [t: "⠫⠲⠸⠫⠠⠓⠻"] # 0x1f137 - - "🄸": [t: "⠫⠲⠸⠫⠠⠊⠻"] # 0x1f138 - - "🄹": [t: "⠫⠲⠸⠫⠠⠚⠻"] # 0x1f139 - - "🄺": [t: "⠫⠲⠸⠫⠠⠅⠻"] # 0x1f13a - - "🄻": [t: "⠫⠲⠸⠫⠠⠇⠻"] # 0x1f13b - - "🄼": [t: "⠫⠲⠸⠫⠠⠍⠻"] # 0x1f13c - - "🄽": [t: "⠫⠲⠸⠫⠠⠝⠻"] # 0x1f13d - - "🄾": [t: "⠫⠲⠸⠫⠠⠕⠻"] # 0x1f13e - - "🄿": [t: "⠫⠲⠸⠫⠠⠏⠻"] # 0x1f13f - - "🅀": [t: "⠫⠲⠸⠫⠠⠟⠻"] # 0x1f140 - - "🅁": [t: "⠫⠲⠸⠫⠠⠗⠻"] # 0x1f141 - - "🅂": [t: "⠫⠲⠸⠫⠠⠎⠻"] # 0x1f142 - - "🅃": [t: "⠫⠲⠸⠫⠠⠞⠻"] # 0x1f143 - - "🅄": [t: "⠫⠲⠸⠫⠠⠥⠻"] # 0x1f144 - - "🅅": [t: "⠫⠲⠸⠫⠠⠧⠻"] # 0x1f145 - - "🅆": [t: "⠫⠲⠸⠫⠠⠺⠻"] # 0x1f146 - - "🅇": [t: "⠫⠲⠸⠫⠠⠭⠻"] # 0x1f147 - - "🅈": [t: "⠫⠲⠸⠫⠠⠽⠻"] # 0x1f148 - - "🅉": [t: "⠫⠲⠸⠫⠠⠵⠻"] # 0x1f149 - - # --- Nemeth Default Alphabet sub chars. --- - - - "₀": [t: "⠰⠴"] # 0x2080 - - "₁": [t: "⠰⠂"] # 0x2081 - - "₂": [t: "⠰⠆"] # 0x2082 - - "₃": [t: "⠰⠒"] # 0x2083 - - "₄": [t: "⠰⠲"] # 0x2084 - - "₅": [t: "⠰⠢"] # 0x2085 - - "₆": [t: "⠰⠖"] # 0x2086 - - "₇": [t: "⠰⠶"] # 0x2087 - - "₈": [t: "⠰⠦"] # 0x2088 - - "₉": [t: "⠰⠔"] # 0x2089 - - # --- Nemeth Default Alphabet super chars. --- - - - "⁰": [t: "⠘⠴"] # 0x2070 - - "¹": [t: "⠘⠂"] # 0xb9 - - "²": [t: "⠘⠆"] # 0xb2 - - "³": [t: "⠘⠒"] # 0xb3 - - "⁴": [t: "⠘⠲"] # 0x2074 - - "⁵": [t: "⠘⠢"] # 0x2075 - - "⁶": [t: "⠘⠖"] # 0x2076 - - "⁷": [t: "⠘⠶"] # 0x2077 - - "⁸": [t: "⠘⠦"] # 0x2078 - - "⁹": [t: "⠘⠔"] # 0x2079 - - # --- Nemeth Default Characters latin-lower-phonetic chars. --- - - - "ø": [t: "⠈⠕"] # 0xf8 - - # --- Nemeth Default Characters math_geometry chars. --- - - - "─": [t: "⠱"] # 0x2500 - - "│": [t: "⠳"] # 0x2502 - - "▰": [t: "⠫⠸⠛"] # 0x25b0 - - "▱": [t: "⠫⠛"] # 0x25b1 - - "▽": [t: "⠨⠫"] # 0x25bd - - "◆": [t: "⠫⠸⠙"] # 0x25c6 - - "◇": [t: "⠫⠙"] # 0x25c7 - - "◈": [t: "⠫⠸⠙"] # 0x25c8 - - "◉": [t: "⠫⠸⠉"] # 0x25c9 - - "◊": [t: "⠫⠙"] # 0x25ca - - "⬟": [t: "⠫⠸⠢"] # 0x2b1f - - "⬠": [t: "⠫⠢"] # 0x2b20 - - "⬡": [t: "⠫⠖"] # 0x2b21 - - "⬢": [t: "⠫⠸⠖"] # 0x2b22 - - "⬣": [t: "⠫⠸⠖"] # 0x2b23 - - "⬤": [t: "⠫⠸⠉"] # 0x2b24 - - "⬥": [t: "⠫⠸⠙"] # 0x2b25 - - # --- Nemeth Default Characters math_symbols chars. --- - - - "\"": [t: "⠄⠄"] # 0x22 - - "¡": [t: "⠖"] # 0xa1 - - "¢": [t: "⠈⠉"] # 0xa2 - - "£": [t: "⠈⠇"] # 0xa3 - - "¤": [t: "⠈⠫"] # 0xa4 - - "¥": [t: "⠈⠽"] # 0xa5 - - "§": [t: "⠈⠠⠎"] # 0xa7 - - "©": [t: "⠘⠉"] # 0xa9 (Copyright) - - "ª": [t: "⠸⠰⠁"] # 0xaa - - "«": [t: "⠐⠅⠈⠐⠅⠻"] # 0xab - - "®": [t: "⠘⠗"] # 0xae - - "´": [t: "⠈"] # 0xb4 - - "µ": [t: "⠨⠍"] # 0xb5 - - "¶": [t: "⠈⠠⠏"] # 0xb6 - - "¿": [t: "⠦"] # 0xbf - - "ʹ": [t: "⠄"] # 0x2b9 - - "ʺ": [t: "⠄⠄"] # 0x2ba - - "˙": [t: "⠡"] # 0x2d9 - - "˜": [t: "⠈⠱"] # 0x2dc - - "‐": [t: "⠤"] # 0x2010 - - "‑": [t: "⠤"] # 0x2011 - - "‒": [t: "⠤⠤"] # 0x2012 - - "–": [t: "⠤⠤"] # 0x2013 - - "‖": [t: "⠳⠳"] # 0x2016 - - "†": [t: "⠸⠻"] # 0x2020 - - "‡": [t: "⠸⠸⠻"] # 0x2021 - - "•": [t: "⠡"] # 0x2022 - - "․": [t: "⠄"] # 0x2024 - - "‥": [t: "⠄⠄"] # 0x2025 - - "′": [t: "⠄"] # 0x2032 - - "″": [t: "⠄⠄"] # 0x2033 - - "‴": [t: "⠄⠄."] # 0x2034 (Triple prime) - - "⁗": [t: "⠄⠄.."] # 0x2057 (Quadruple prime) - - "‼": [t: "⠖⠖"] # 0x203c - - "‾": [t: "⠱"] # 0x203e - - "⁇": [t: "⠹⠹"] # 0x2047 - - "⁈": [t: "⠹⠖"] # 0x2048 - - "⁉": [t: "⠖⠹"] # 0x2049 - - "∀": [t: "⠈⠯"] # 0x2200 - - "∃": [t: "⠈⠿"] # 0x2203 - - "∄": [t: "⠌⠈⠿"] # 0x2204 - - "∅": [t: "⠸⠴"] # 0x2205 - - "∈": [t: "⠈⠑"] # 0x2208 - - "∉": [t: "⠌⠈⠑"] # 0x2209 - - "∊": [t: "⠈⠑"] # 0x220a - - "∋": [t: "⠈⠢"] # 0x220b - - "∌": [t: "⠌⠈⠢"] # 0x220c - - "∍": [t: "⠈⠢"] # 0x220d - - "∎": [t: "⠸⠳"] # 0x220e - - "−": [t: "⠤"] # 0x2212 - - "∓": [t: "⠤⠬"] # 0x2213 - - "∕": [t: "⠸⠌"] # 0x2215 - - "∖": [t: "⠸⠡"] # 0x2216 - - "∗": [t: "⠈⠼"] # 0x2217 - - "∘": [t: "⠨⠡"] # 0x2218 - - "∝": [t: "⠸⠿"] # 0x221d - - "∞": [t: "⠠⠿"] # 0x221e - - "∟": [t: "⠫⠪⠨⠗⠻"] # 0x221f - - "∠": [t: "⠫⠪"] # 0x2220 - - "∢": [t: "⠫⠪⠸⠫⠫⠁⠻"] # 0x2222 - - "∣": [t: "⠳"] # 0x2223 - - "∤": [t: "⠌⠳"] # 0x2224 - - "∥": [t: "⠫⠇"] # 0x2225 - - "∦": [t: "⠌⠫⠇"] # 0x2226 - - "∧": [t: "⠈⠩"] # 0x2227 - - "∨": [t: "⠈⠬"] # 0x2228 - - "∩": [t: "⠨⠩"] # 0x2229 - - "∪": [t: "⠨⠬"] # 0x222a - - "∫": [t: "⠮"] # 0x222b - - "∬": [t: "⠮⠮"] # 0x222c - - "∭": [t: "⠮⠮⠮"] # 0x222d - - "∮": [t: "⠮⠈⠫⠉⠻"] # 0x222e - - "∲": [t: "⠮⠈⠫⠪⠢⠔⠻"] # 0x2232 - - "∳": [t: "⠮⠈⠫⠢⠔⠕⠻"] # 0x2233 - - "∴": [t: "⠠⠡"] # 0x2234 - - "∵": [t: "⠈⠌"] # 0x2235 - - "∶": [t: "⠐⠂"] # 0x2236 - - "∷": [t: "⠰⠆"] # 0x2237 - - "∸": [t: "⠨⠤"] # 0x2238 - - "∼": [t: "⠈⠱"] # 0x223c - - "≁": [t: "⠌⠈⠱"] # 0x2241 - - "≂": [t: "⠱⠈⠱"] # 0x2242 - - "≃": [t: "⠈⠱⠱"] # 0x2243 - - "≄": [t: "⠌⠈⠱⠱"] # 0x2244 - - "≅": [t: "⠈⠱⠨⠅"] # 0x2245 - - "≆": [t: "⠈⠱⠌⠨⠅"] # 0x2246 - - "≇": [t: "⠌⠈⠱⠨⠅"] # 0x2247 - - "≈": [t: "⠈⠱⠈⠱"] # 0x2248 - - "≉": [t: "⠌⠈⠱⠈⠱"] # 0x2249 - - "≊": [t: "⠈⠱⠈⠱⠱"] # 0x224a - - "≍": [t: "⠈⠣⠠⠣"] # 0x224d - - "≎": [t: "⠈⠣⠠⠣"] # 0x224e - - "≐": [t: "⠐⠨⠅⠣⠡⠻"] # 0x2250 - - "≑": [t: "⠐⠨⠅⠩⠡⠣⠡⠻"] # 0x2251 - - "≗": [t: "⠐⠨⠅⠣⠨⠡⠻"] # 0x2257 - - "≘": [t: "⠐⠨⠅⠣⠫⠁⠻"] # 0x2258 - - "≙": [t: "⠐⠨⠅⠣⠸⠣⠻"] # 0x2259 - - "≚": [t: "⠐⠨⠅⠣⠸⠩⠻"] # 0x225a - - "≛": [t: "⠐⠨⠅⠣⠫⠸⠎⠻"] # 0x225b - - "≜": [t: "⠐⠨⠅⠣⠫⠞⠻"] # 0x225c - - "≝": [t: "⠐⠨⠅⠣⠙⠑⠋⠻"] # 0x225d - - "≞": [t: "⠐⠨⠅⠣⠍⠻"] # 0x225e - - "≟": [t: "⠐⠨⠅⠣⠸⠦⠻"] # 0x225f - - "≠": [t: "⠌⠨⠅"] # 0x2260 - - "≢": [t: "⠌⠸⠇"] # 0x2262 - - "≤": [t: "⠐⠅⠱"] # 0x2264 - - "≥": [t: "⠨⠂⠱"] # 0x2265 - - "≦": [t: "⠐⠅⠨⠅"] # 0x2266 - - "≧": [t: "⠨⠂⠨⠅"] # 0x2267 - - "≨": [t: "⠐⠅⠌⠨⠅"] # 0x2268 - - "≩": [t: "⠨⠂⠌⠨⠅"] # 0x2269 - - "≪": [t: "⠐⠅⠈⠐⠅⠻"] # 0x226a - - "≫": [t: "⠨⠂⠈⠨⠂⠻"] # 0x226b - - "≭": [t: "⠌⠈⠣⠠⠣"] # 0x226d - - "≮": [t: "⠌⠐⠅"] # 0x226e - - "≯": [t: "⠌⠨⠂"] # 0x226f - - "≰": [t: "⠌⠐⠅⠱"] # 0x2270 - - "≱": [t: "⠌⠨⠂⠱"] # 0x2271 - - "≲": [t: "⠐⠅⠈⠱"] # 0x2272 - - "≳": [t: "⠨⠂⠈⠱"] # 0x2273 - - "≴": [t: "⠌⠐⠅⠈⠱"] # 0x2274 - - "≵": [t: "⠌⠨⠂⠈⠱"] # 0x2275 - - "≶": [t: "⠐⠅⠨⠂"] # 0x2276 - - "≷": [t: "⠨⠂⠐⠅"] # 0x2277 - - "≸": [t: "⠌⠐⠅⠨⠂"] # 0x2278 - - "≹": [t: "⠌⠨⠂⠐⠅"] # 0x2279 - - "≺": [t: "⠨⠐⠅"] # 0x227a - - "≻": [t: "⠨⠨⠂"] # 0x227b - - "≼": [t: "⠨⠐⠅⠱"] # 0x227c - - "≽": [t: "⠨⠨⠐⠱"] # 0x227d - - "≾": [t: "⠨⠐⠅⠈⠱"] # 0x227e - - "≿": [t: "⠨⠨⠂⠈⠱"] # 0x227f - - "⊀": [t: "⠌⠨⠐⠅"] # 0x2280 - - "⊁": [t: "⠌⠨⠐⠅"] # 0x2281 - - "⊂": [t: "⠸⠐⠅"] # 0x2282 - - "⊃": [t: "⠸⠨⠂"] # 0x2283 - - "⊄": [t: "⠌⠸⠐⠅"] # 0x2284 - - "⊅": [t: "⠌⠸⠨⠂"] # 0x2285 - - "⊆": [t: "⠸⠐⠅⠱"] # 0x2286 - - "⊇": [t: "⠸⠨⠂⠱"] # 0x2287 - - "⊈": [t: "⠌⠸⠐⠅⠱"] # 0x2288 - - "⊉": [t: "⠌⠸⠨⠂⠱"] # 0x2289 - - "⊊": [t: "⠸⠐⠅⠌⠨⠅"] # 0x228a - - "⊋": [t: "⠸⠨⠂⠌⠨⠅"] # 0x228b - - "⊥": [t: "⠫⠏"] # 0x22a5 - - "⋀": [t: "⠈⠩"] # 0x22c0 - - "⋁": [t: "⠈⠬"] # 0x22c1 - - "⋂": [t: "⠨⠩"] # 0x22c2 - - "⋃": [t: "⠨⠬"] # 0x22c3 - - "⋄": [t: "⠫⠙"] # 0x22c4 - - "⋜": [t: "⠱⠐⠅"] # 0x22dc - - "⋝": [t: "⠱⠨⠂"] # 0x22dd - - "⟂": [t: "⠫⠏"] # 0x27c2 - - "⦀": [t: "⠳⠳⠳"] # 0x2980 - - "⦶": [t: "⠫⠉⠸⠫⠳⠻"] # 0x29b6 - - "⦷": [t: "⠫⠉⠸⠫⠫⠇⠻"] # 0x29b7 - - "⦸": [t: "⠫⠉⠸⠫⠸⠡⠻"] # 0x29b8 - - "⦹": [t: "⠫⠉⠸⠫⠫⠏⠻"] # 0x29b9 - - "⦿": [t: "⠫⠉⠸⠫⠔⠔⠻"] # 0x29bf - - "⧀": [t: "⠫⠉⠸⠫⠐⠅⠻"] # 0x29c0 - - "⧁": [t: "⠫⠉⠸⠫⠨⠂⠻"] # 0x29c1 - - "⨀": [t: "⠫⠉⠸⠫⠡⠻"] # 0x2a00 - - "⨁": [t: "⠫⠉⠸⠫⠬⠻"] # 0x2a01 - - "⨂": [t: "⠫⠉⠸⠫⠈⠡⠻"] # 0x2a02 - - "⪯": [t: "⠨⠐⠅⠱"] # 0x2aaf - - "⪰": [t: "⠨⠨⠂⠱"] # 0x2ab0 - - "⪱": [t: "⠨⠐⠅⠌⠱"] # 0x2ab1 - - "⪲": [t: "⠨⠨⠂⠌⠱"] # 0x2ab2 - - "⪳": [t: "⠨⠐⠅⠨⠅"] # 0x2ab3 - - "⪴": [t: "⠨⠨⠂⠨⠅"] # 0x2ab4 - - "⪵": [t: "⠨⠐⠅⠌⠨⠅"] # 0x2ab5 - - "⪶": [t: "⠨⠨⠂⠌⠨⠅"] # 0x2ab6 - - "⪷": [t: "⠨⠐⠅⠈⠱⠈⠱"] # 0x2ab7 - - "⪸": [t: "⠨⠨⠂⠈⠱⠈⠱"] # 0x2ab8 - - "⪹": [t: "⠨⠐⠅⠌⠈⠱⠈⠱"] # 0x2ab9 - - "⪺": [t: "⠨⠨⠂⠌⠈⠱⠈⠱"] # 0x2aba - - "⪻": [t: "⠨⠐⠅⠈⠨⠐⠅⠻"] # 0x2abb - - "⪼": [t: "⠨⠨⠂⠈⠨⠨⠂⠻"] # 0x2abc - - "﹩": [t: "⠈⠎"] # 0xfe69 - - "$": [t: "⠈⠎"] # 0xff04 - - "_": [t: "⠱"] # 0xff3f - - "~": [t: "⠈⠱"] # 0xff5e - - "¢": [t: "⠈⠉"] # 0xffe0 - - "£": [t: "⠈⠇"] # 0xffe1 - - " ̄": [t: "⠱"] # 0xffe3 - - "¥": [t: "⠈⠽"] # 0xffe5 - - # --- Nemeth Default Characters rest chars. --- - - - "ℵ": [t: "⠠⠠⠁"] # 0x2135 - - "ℶ": [t: "⠠⠠⠃"] # 0x2136 - - "ℷ": [t: "⠠⠠⠉"] # 0x2137 - - "ℸ": [t: "⠠⠠⠙"] # 0x2138 - - "à": [t: "⠈⠁"] # 0xe0 - - "á": [t: "⠈⠁"] # 0xe1 - - "â": [t: "⠈⠁"] # 0xe2 - - "ã": [t: "⠈⠁"] # 0xe3 - - "ä": [t: "⠈⠁"] # 0xe4 - - "å": [t: "⠈⠁"] # 0xe5 - - "ç": [t: "⠈⠉"] # 0xe7 - - "è": [t: "⠈⠑"] # 0xe8 - - "é": [t: "⠈⠑"] # 0xe9 - - "ê": [t: "⠈⠑"] # 0xea - - "ë": [t: "⠈⠑"] # 0xeb - - "ì": [t: "⠈⠊"] # 0xec - - "í": [t: "⠈⠊"] # 0xed - - "î": [t: "⠈⠊"] # 0xee - - "ï": [t: "⠈⠊"] # 0xef - - "ñ": [t: "⠈⠝"] # 0xf1 - - "ò": [t: "⠈⠕"] # 0xf2 - - "ó": [t: "⠈⠕"] # 0xf3 - - "ô": [t: "⠈⠕"] # 0xf4 - - "õ": [t: "⠈⠕"] # 0xf5 - - "ö": [t: "⠈⠕"] # 0xf6 - - "ù": [t: "⠈⠥"] # 0xf9 - - "ú": [t: "⠈⠥"] # 0xfa - - "û": [t: "⠈⠥"] # 0xfb - - "ü": [t: "⠈⠥"] # 0xfc - - "ý": [t: "⠈⠽"] # 0xfd - - "ÿ": [t: "⠈⠽"] # 0xff - - - "À": [t: "⠠⠈⠁"] # 0xc0 - - "Á": [t: "⠠⠈⠁"] # 0xc1 - - "Â": [t: "⠠⠈⠁"] # 0xc2 - - "Ã": [t: "⠠⠈⠁"] # 0xc3 - - "Ä": [t: "⠠⠈⠁"] # 0xc4 - - "Å": [t: "⠠⠈⠁"] # 0xc5 - - "Ç": [t: "⠠⠈⠉"] # 0xc7 - - "È": [t: "⠠⠈⠑"] # 0xc8 - - "É": [t: "⠠⠈⠑"] # 0xc9 - - "Ê": [t: "⠠⠈⠑"] # 0xca - - "Ë": [t: "⠠⠈⠑"] # 0xcb - - "Ì": [t: "⠠⠈⠊"] # 0xcc - - "Í": [t: "⠠⠈⠊"] # 0xcd - - "Î": [t: "⠠⠈⠊"] # 0xce - - "Ï": [t: "⠠⠈⠊"] # 0xcf - - "Ñ": [t: "⠠⠈⠝"] # 0xd1 - - "Ò": [t: "⠠⠈⠕"] # 0xd2 - - "Ó": [t: "⠠⠈⠕"] # 0xd3 - - "Ô": [t: "⠠⠈⠕"] # 0xd4 - - "Ö": [t: "⠠⠈⠕"] # 0xd6 - - "Ù": [t: "⠠⠈⠥"] # 0xd9 - - "Ú": [t: "⠠⠈⠥"] # 0xda - - "Û": [t: "⠠⠈⠥"] # 0xdb - - "Ü": [t: "⠠⠈⠥"] # 0xdc - - "Ý": [t: "⠠⠈⠽"] # 0xdd - - "←": [t: "⠫⠪⠒⠒"] # 0x2190 - - - "↑": # 0x2191 - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠣"] - else: [t: "⠫⠣⠒⠒⠕"] - - - "↓": # 0x2193 - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠩"] - else: [t: "⠫⠩⠒⠒⠕"] - - - "↔": [t: "⠫⠪⠒⠒⠕"] # 0x2194 - - "↕": [t: "⠫⠣⠩⠪⠒⠒⠕"] # 0x2195 - - "↖": [t: "⠫⠘⠪⠒⠒"] # 0x2196 - - "↗": [t: "⠫⠘⠒⠒⠕"] # 0x2197 - - "↘": [t: "⠫⠰⠒⠒⠕"] # 0x2198 - - "↙": [t: "⠫⠰⠪⠒⠒"] # 0x2199 - - "↚": [t: "⠳⠈⠫⠪⠒⠒⠻"] # 0x219a - - "↛": [t: "⠳⠈⠫⠒⠒⠕⠻"] # 0x219b - - "↜": [t: "⠫⠪⠔⠒⠢"] # 0x219c - - "↝": [t: "⠫⠔⠒⠢⠕"] # 0x219d - - "↞": [t: "⠫⠪⠪⠒⠒"] # 0x219e - - "↟": [t: "⠫⠣⠒⠒⠕⠕"] # 0x219f - - "↠": [t: "⠫⠒⠒⠕⠕"] # 0x21a0 - - "↡": [t: "⠫⠩⠒⠒⠕⠕"] # 0x21a1 - - "↢": [t: "⠫⠪⠒⠒⠠⠽"] # 0x21a2 - - "↣": [t: "⠫⠠⠯⠒⠒⠕"] # 0x21a3 - - "↤": [t: "⠫⠪⠒⠒⠳"] # 0x21a4 - - "↥": [t: "⠫⠣⠳⠒⠒⠕"] # 0x21a5 - - "↦": [t: "⠫⠳⠒⠒⠕"] # 0x21a6 - - "↧": [t: "⠫⠩⠳⠒⠒⠕"] # 0x21a7 - - "↨": [t: "⠫⠪⠒⠳⠒⠕"] # 0x21a8 - - "↩": [t: "⠫⠪⠒⠒⠠⠕"] # 0x21a9 - - "↪": [t: "⠫⠠⠪⠒⠒⠕"] # 0x21aa - - "↫": [t: "⠫⠪⠒⠒⠨⠡"] # 0x21ab - - "↬": [t: "⠫⠨⠡⠒⠒⠕"] # 0x21ac - - "↭": [t: "⠫⠪⠔⠒⠢⠕"] # 0x21ad - - "↮": [t: "⠳⠈⠫⠪⠒⠒⠕"] # 0x21ae - - "↯": [t: "⠫⠩⠔⠢⠔"] # 0x21af - - "↴": [t: "⠫⠠⠳⠒⠒⠕"] # 0x21b4 - - "↵": [t: "⠫⠩⠠⠳⠒⠒⠕"] # 0x21b5 - - "↶": [t: "⠫⠢⠔⠕"] # 0x21b6 - - "↷": [t: "⠫⠪⠢⠔"] # 0x21b7 - - "↺": [t: "⠫⠢⠔⠕"] # 0x21ba - - "↻": [t: "⠫⠪⠢⠔"] # 0x21bb - - "⇄": [t: "⠫⠒⠒⠕⠫⠪⠒⠒"] # 0x21c4 - - "⇅": [t: "⠫⠣⠒⠒⠕⠐⠫⠩⠒⠒⠕"] # 0x21c5 - - "⇆": [t: "⠫⠪⠒⠒⠫⠒⠒⠕"] # 0x21c6 - - "⇇": [t: "⠫⠚⠒⠒⠫⠚⠒⠒"] # 0x21c7 - - "⇈": [t: "⠫⠣⠒⠒⠕⠐⠫⠣⠒⠒⠕"] # 0x21c8 - - "⇉": [t: "⠫⠒⠒⠕⠫⠒⠒⠕"] # 0x21c9 - - "⇊": [t: "⠫⠩⠒⠒⠕⠐⠫⠩⠒⠒⠕"] # 0x21ca - - "⇍": [t: "⠳⠈⠫⠪⠪⠒⠒"] # 0x21cd - - "⇎": [t: "⠳⠈⠫⠪⠪⠒⠒⠕⠕"] # 0x21ce - - "⇏": [t: "⠳⠈⠫⠒⠒⠕⠕"] # 0x21cf - - "⇐": [t: "⠫⠪⠶⠶"] # 0x21d0 - - "⇑": [t: "⠫⠣⠶⠶⠕"] # 0x21d1 - - "⇒": [t: "⠫⠶⠶⠕"] # 0x21d2 - - "⇓": [t: "⠫⠣⠶⠶⠕"] # 0x21d3 - - "⇔": [t: "⠫⠪⠶⠶⠕"] # 0x21d4 - - "⇕": [t: "⠫⠣⠪⠶⠶⠕"] # 0x21d5 - - "⇖": [t: "⠫⠘⠪⠶⠶"] # 0x21d6 - - "⇗": [t: "⠫⠘⠶⠶⠕"] # 0x21d7 - - "⇘": [t: "⠫⠰⠶⠶⠕"] # 0x21d8 - - "⇙": [t: "⠫⠰⠪⠪⠒⠒"] # 0x21d9 - - "⇚": [t: "⠫⠪⠪⠶⠶"] # 0x21da FIX: how to represent triple shafts? - - "⇛": [t: "⠫⠶⠶⠕⠕"] # 0x21db FIX: how to represent triple shafts? - - "⇜": [t: "⠫⠪⠢⠤⠔⠒⠢"] # 0x21dc - - "⇝": [t: "⠫⠢⠤⠔⠒⠢⠕"] # 0x21dd - - "⇞": [t: "⠳⠳⠈⠫⠣⠒⠒⠕⠻"] # 0x21de - - "⇟": [t: "⠳⠳⠈⠫⠩⠒⠒⠕⠻"] # 0x21df - - "⇠": [t: "⠫⠪⠒⠒"] # 0x21e0 - - "⇡": [t: "⠫⠣⠒⠒⠕"] # 0x21e1 - - "⇢": [t: "⠫⠒⠒⠕"] # 0x21e2 - - "⇣": [t: "⠫⠩⠒⠒⠕"] # 0x21e3 - - "⇤": [t: "⠫⠳⠪⠒⠒"] # 0x21e4 - - "⇥": [t: "⠫⠒⠒⠕⠳"] # 0x21e5 - - "⇦": [t: "⠫⠸⠪⠒⠒"] # 0x21e6 - - "⇧": [t: "⠫⠣⠸⠒⠒⠕"] # 0x21e7 - - "⇨": [t: "⠫⠸⠒⠒⠕"] # 0x21e8 - - "⇩": [t: "⠫⠩⠸⠒⠒⠕"] # 0x21e9 - - "⇳": [t: "⠫⠣⠸⠪⠒⠒⠕"] # 0x21f3 - - "⇴": [t: "⠫⠒⠒⠕⠨⠡"] # 0x21f4 - - "⇵": [t: "⠫⠩⠒⠒⠕⠐⠫⠣⠒⠒⠕"] # 0x21f5 - - "⇶": [t: "⠫⠒⠒⠕⠫⠒⠒⠕⠫⠒⠒⠕"] # 0x21f6 - - "⇷": [t: "⠳⠈⠫⠪⠒⠒⠻"] # 0x21f7 - - "⇸": [t: "⠳⠈⠫⠒⠒⠕⠻"] # 0x21f8 - - "⇹": [t: "⠳⠈⠫⠪⠒⠒⠕"] # 0x21f9 - - "⇺": [t: "⠳⠳⠈⠫⠪⠒⠒⠻"] # 0x21fa - - "⇻": [t: "⠳⠳⠈⠫⠒⠒⠕⠻"] # 0x21fb - - "⇼": [t: "⠳⠳⠈⠫⠪⠒⠒⠕"] # 0x21fc - - "⇽": [t: "⠫⠳⠒⠒"] # 0x21fd - - "⇾": [t: "⠫⠒⠒⠳"] # 0x21fe - - "⇿": [t: "⠫⠳⠒⠒⠳"] # 0x21ff - - - "ⅆ": [t: "⠙"] # 0x2146 - - "ⅇ": [t: "⠑"] # 0x2147 - - "ⅈ": [t: "⠊"] # 0x2148 - - "⌜": [t: "⠈⠘⠷"] # 0x231c - - "⌝": [t: "⠈⠘⠾"] # 0x231d - - "⌞": [t: "⠈⠰⠷"] # 0x231e - - "⌟": [t: "⠈⠰⠾"] # 0x231f - - "〈": [t: "⠨⠨⠷"] # 0x2329 - - "〉": [t: "⠨⠨⠾"] # 0x232a - - "⏞": [t: "⠨⠷"] # 0x23de - - "⏟": [t: "⠨⠾"] # 0x23df - - "⎴": [t: "⠈⠷"] # 0x23b4 - - "⎵": [t: "⠈⠾"] # 0x23b5 - - "⟪": [t: "⠨⠨⠨⠷"] # 0x27ea - - "⟫": [t: "⠨⠨⠨⠾"] # 0x27eb - - "〈": [t: "⠨⠨⠷"] # 0x3008 - - "〉": [t: "⠨⠨⠾"] # 0x3009 - - "《": [t: "⠨⠨⠨⠷"] # 0x300a - - "》": [t: "⠨⠨⠨⠾"] # 0x300b - - "「": [t: "⠈⠘⠷"] # 0x300c - - "」": [t: "⠈⠘⠾"] # 0x300d - - "↼": [t: "⠫⠈⠪⠒⠒"] # 0x21bc - - "↽": [t: "⠫⠠⠪⠒⠒"] # 0x21bd - - "↾": [t: "⠫⠣⠒⠒⠠⠕"] # 0x21be - - "↿": [t: "⠫⠣⠒⠒⠈⠕"] # 0x21bf - - "⇀": [t: "⠫⠒⠒⠈⠕"] # 0x21c0 - - "⇁": [t: "⠫⠒⠒⠠⠕"] # 0x21c1 - - "⇂": [t: "⠫⠪⠒⠒⠈⠕"] # 0x21c2 - - "⇃": [t: "⠫⠩⠒⠒⠠⠕"] # 0x21c3 - - "⇋": # 0x21cb - - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠪⠒⠫⠒⠕"] - else: [t: "⠫⠈⠪⠒⠒⠫⠒⠒⠈⠕"] - - "⇌": # 0x21cc - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠕⠫⠪⠒"] - else: [t: "⠫⠒⠒⠈⠕⠫⠈⠪⠒⠒"] - - - "℔": [t: "⠳"] # 0x2114 - - "™": [t: "⠘⠞"] # 0x2122 - - "Å": [t: "⠈⠠⠁"] # 0x212b - - "­": [t: "⠤"] # 0xad - - " -​": [t: "W"] # 0x2000 - 0x200b (various spaces / ZWSP) - - "
": [t: "W"] # 0x2028 - - "
": [t: "W"] # 0x2029 - - " ": [t: "W"] # 0x202f - - " ": [t: "W"] # 0x205f - - "₣": [t: "⠈⠋"] # 0x20A3 (French franc sign - - "₦": [t: "⠈⠝"] # 0x2046 (Naira sign) - - "₩": [t: "⠈⠺"] # 0x20A9 (Won sign) - - "€": [t: "⠈⠑"] # 0x20AC (Euro sign) - - "": [t: "W"] # 0xfeff - - "☆": [t: "⠫⠎"] # 0x2606 - - "✕": [t: "⠈⠡"] # 0x2715 - - "¼": [t: "⠹⠂⠌⠲⠼"] # 0xbc - - "½": [t: "⠹⠂⠌⠆⠼"] # 0xbd - - "¾": [t: "⠹⠒⠌⠲⠼"] # 0xbe - - "⅐": [t: "⠹⠂⠌⠶⠼"] # 0x2150 - - "⅑": [t: "⠹⠂⠌⠔⠼"] # 0x2151 - - "⅒": [t: "⠹⠂⠌⠂⠴⠼"] # 0x2152 - - "⅓": [t: "⠹⠂⠌⠒⠼"] # 0x2153 - - "⅔": [t: "⠹⠆⠌⠒⠼"] # 0x2154 - - "⅕": [t: "⠹⠂⠌⠢⠼"] # 0x2155 - - "⅖": [t: "⠹⠆⠌⠢⠼"] # 0x2156 - - "⅗": [t: "⠹⠒⠌⠢⠼"] # 0x2157 - - "⅘": [t: "⠹⠲⠌⠢⠼"] # 0x2158 - - "⅙": [t: "⠹⠂⠌⠖⠼"] # 0x2159 - - "⅚": [t: "⠹⠢⠌⠖⠼"] # 0x215a - - "⅛": [t: "⠹⠂⠌⠦⠼"] # 0x215b - - "⅜": [t: "⠹⠒⠌⠦⠼"] # 0x215c - - "⅝": [t: "⠹⠢⠌⠦⠼"] # 0x215d - - "⅞": [t: "⠹⠶⠌⠦⠼"] # 0x215e - - "⅟": [t: "⠹⠂⠌⠼"] # 0x215f - - "↉": [t: "⠹⠴⠌⠒⠼"] # 0x2189 - - "㉈": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠂⠴⠻⠻"] # 0x3248 - - "㉉": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠆⠴⠻⠻"] # 0x3249 - - "㉊": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠒⠴⠻⠻"] # 0x324a - - "㉋": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠲⠴⠻⠻"] # 0x324b - - "㉌": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠢⠴⠻⠻"] # 0x324c - - "㉍": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠖⠴⠻⠻"] # 0x324d - - "㉎": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠶⠴⠻⠻"] # 0x324e - - "㉏": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠦⠴⠻⠻"] # 0x324f - - - - "‘": [t: "P⠠⠦"] # 0x2018 (Left single quotation mark) - - "’": [t: "P⠠⠴"] # 0x2019 (Right single quotation mark) - - "“": [t: "P⠦"] # 0x201C (Left double quotation mark) - - "”": [t: "P⠴"] # 0x201D (Right double quotation mark) - - "‰": [t: "`00"] - - "ℏ": [t: "⠈⠓"] # 0x210F (Planck constant over two pi) - - "ℓ": [t: "TE⠇"] # 0x2113 (Script small l (differs from 1d4c1: 4-56-123)) - - "℘": [tc: "TCL⠏"] # 0x2118 (Script Capital P) -# - "ℝ": [t: ""] # 0x211D (Double-struck capital R (no nemeth double struck)) -# - "ⅆ": [t: ""] # 0x2146 (Double-struck italic small d) -# - "ⅇ": [t: ""] # 0x2147 (Double-struck italic small e) -# - "⇚": [t: "⠀⠫⠪⠸⠸⠀"] # 0x21DA (Leftwards triple arrow) -# - "⇛": [t: "⠀⠫⠸⠸⠕⠀"] # 0x21DB (Rightwards triple arrow) - - "∔": [t: "⠐⠬⠣⠡⠻"] # 0x2214 (Dot plus) - - "√": [t: "⠜"] # 0x221A (Square root) - - "∛": [t: "⠣⠒⠜"] # 0x221B (Cube root) - - "∜": [t: "⠣⠲⠜"] # 0x221C (Fourth root) - - "∡": [t: "⠫⠪⠸⠫⠫⠁⠻"] # 0x2221 (Measured angle) - - "∹": [t: "⠤⠐⠂"] # 0x2239 (Excess) - - "∺": [t: "⠐⠤⠩⠡⠡⠣⠡⠡⠻"] # 0x223A (Geometric proportion) - - "∻": [t: "⠐⠈⠱⠩⠡⠣⠡⠻"] # 0x223B (Homothetic) - - "∽": [t: "⠠⠱"] # 0x223D (Reversed tilde) - - "≋": [t: "⠈⠱⠈⠱⠈⠱"] # 0x224B (Triple tilde) - - "≌": [t: "⠠⠱⠨⠅"] # 0x224C (All equal to) - - "≏": [t: "⠈⠣⠱"] # 0x224F (Difference between) - - "≔": [t: "⠐⠂⠨⠅"] # 0x2254 (Colon equals) - - "≕": [t: "⠨⠅⠐⠂"] # 0x2255 (Equals colon) - - "≖": [t: "⠀⠨⠡⠈⠨⠅⠻⠀"] # 0x2256 (Ring in equal to) - - "⊌": [t: "⠨⠬⠈⠫⠪⠒⠻"] # 0x228C (Multiset) - - "⊍": [t: "⠡⠈⠨⠬⠻"] # 0x228D (Multiset multiplication) - - "⊎": [t: "⠬⠈⠨⠬⠻"] # 0x228E (Multiset union) - - "⊕": [t: "⠫⠉⠸⠫⠬⠻"] # 0x2295 (Circled plus) - - "⊖": [t: "⠫⠉⠸⠫⠤⠻"] # 0x2296 (Circled minus) - - "⊗": [t: "⠫⠉⠸⠫⠈⠡⠻"] # 0x2297 (Circled times) - - "⊘": [t: "⠫⠉⠸⠫⠸⠌⠻"] # 0x2298 (Circled division slash) - - "⊙": [t: "⠫⠉⠸⠫⠡⠻"] # 0x2299 (Circled dot operator) - - "⊚": [t: "⠫⠉⠸⠫⠘⠨⠡⠻"] # 0x229a (Circled ring operator) - - "⊛": [t: "⠫⠉⠸⠫⠈⠼⠻"] # 0x229B (Circled asterisk operator) - - "⊜": [t: "⠫⠉⠸⠫⠨⠅⠻"] # 0x229C (Circled equals) - - "⊝": [t: "⠫⠉⠸⠫⠤⠤⠻"] # 0x229D (Circled dash) - - "⊞": [t: "⠫⠲⠸⠫⠬⠻"] # 0x229E (Squared plus) - - "⊟": [t: "⠫⠲⠸⠫⠤⠻"] # 0x229F (Squared minus) - - "⊠": [t: "⠫⠲⠸⠫⠈⠡⠻"] # 0x22A0 (Squared times) - - "⊡": [t: "⠫⠲⠸⠫⠡⠻"] # 0x22A1 (Squared dot operator) - - "⊢": [t: "⠫⠳⠒"] # 0x22A2 (Right tack) - - "⊣": [t: "⠫⠒⠳"] # 0x22A3 (Left tack) - - "⊤": [t: "⠫⠩⠳⠒"] # 0x22A4 (Down tack) -# - "⊥": [t: "⠀⠫⠏⠀ or ⠀⠫⠣⠳⠒⠀"] # 0x22A5 (Up tack (See also 27C2)) -# - "⊦": [t: ""] # 0x22A6 (Assertion) -# - "⊨": [t: ""] # 0x22A8 (TRUE) -# - "⊲": [t: ""] # 0x22B2 (Normal subgroup of) -# - "⊳": [t: ""] # 0x22B3 (Contains as normal subgroup) -# - "⊴": [t: ""] # 0x22B4 (Normal subgroup of or equal to) -# - "⊵": [t: ""] # 0x22B5 (Contains as normal subgroup or equal to) - - "⊶": [t: "⠫⠨⠡⠒⠡"] # 0x22B6 (Original of) - - "⊷": [t: "⠫⠡⠒⠨⠡"] # 0x22B7 (Image of) - - "⊸": [t: "⠫⠒⠨⠡"] # 0x22B8 (Multimap) -# - "⊾": [t: ""] # 0x22BE (Right angle w arc) - - "⊿": [t: "⠫⠞⠨⠗⠻"] # 0x22BF (Right triangle) - - "⋅": [t: "⠡"] # 0x22C5 (Dot operator) - - "∙": [t: "⠡"] # 0x2219 -- similar looking to 0x22c5, so using the same braille - - "⋆": [t: "⠫⠎"] # 0x22C6 (Star operator) - - "⋍": [t: "⠠⠱⠱"] # 0x22CD (Reversed tilde equals) - - "⋖": [t: "⠡⠈⠐⠅⠻"] # 0x22D6 (Less-than w dot) - - "⋗": [t: "⠡⠈⠨⠂⠻"] # 0x22D7 (Greater-than w dot) - - "⋘": [t: "⠐⠅⠈⠐⠅⠈⠐⠅⠻"] # 0x22D8 (Much less-than) - - "⋙": [t: "⠨⠂⠈⠨⠂⠈⠨⠂⠻"] # 0x22D9 (Much greater-than) - - "⋲": [t: "⠱⠈⠈⠑⠻"] # 0x22F2 (Element of w long horizontal stroke) - - "⋵": [t: "⠐⠈⠑⠣⠡⠻"] # 0x22F5 (Element of w dot above) - - "⋶": [t: "⠱⠈⠑"] # 0x22F6 (Element of w overbar) - - "⋺": [t: "⠱⠈⠈⠢⠻"] # 0x22FA (Contains w long horizontal stroke) - - "⋽": [t: "⠱⠈⠢"] # 0x22FD (Contains w overbar) - - "⌈": [t: "⠈⠘⠷"] # 0x2308 (Left ceiling) - - "⌉": [t: "⠈⠘⠾"] # 0x2309 (Right ceiling) - - "⌊": [t: "⠈⠰⠷"] # 0x230A (Left floor) - - "⌋": [t: "⠈⠰⠾"] # 0x230B (Right floor) - - "⌢": [t: "⠫⠁"] # 0x2322 (Frown) - - "⌣": [t: "⠫⠄"] # 0x2323 (Smile) - - "■": [t: "⠫⠸⠲"] # 0x25A0 (Filled square) - - "▫": [t: "⠫⠲"] # 0x25AB (Small white Square) - - "□": [t: "⠫⠲"] # 0x25A1 (Square) - - "◻": [t: "⠫⠲"] # 0x25FB (Square) - - "▬": [t: "⠫⠸⠗"] # 0x25AC (Filled rectangle) - - "▭": [t: "⠫⠗"] # 0x25AD (Rectangle) - - "▲": [t: "⠫⠸⠞"] # 0x25B2 (Black up-pointing triangle) - - "△": [t: "⠫⠞"] # 0x25B3 (White up-pointing triangle) - - "▼": [t: "⠸⠨⠫"] # 0x25BC (Black down-pointing triangle) - - "○": [t: "⠫⠉"] # 0x25CB (White circle) - - "●": [t: "⠫⠸⠉"] # 0x25CF (Black circle) - - "◫": [t: "⠫⠲⠸⠫⠳⠻"] # 0x25EB (White square w vertical bisecting line) -# - "⊥": [t: "⠫⠏"] # 0x27C2 (Perpendicular) - - "⟃": [t: "⠨⠡⠈⠸⠐⠅⠻"] # 0x27C3 (Open subset) - - "⟄": [t: "⠨⠡⠈⠸⠨⠂⠻"] # 0x27C4 (Open superset) - - "⟜": [t: "⠫⠨⠡⠒⠒"] # 0x27DC (Left multimap) - - "⟝": [t: "⠫⠳⠒⠒"] # 0x27DD (Long right tack) - - "⟞": [t: "⠫⠒⠒⠳"] # 0x27DE (Long left tack) - - "⟟": [t: "⠫⠣⠳⠒⠒⠨⠡"] # 0x27DF (Up tack w circle above) - - "⟦": [t: "⠈⠸⠷"] # 0x27E6 (Mathematical left white square bracket) - - "⟧": [t: "⠈⠸⠾"] # 0x27E7 (Mathematical right white square bracket) - - "⟨": [t: "⠨⠨⠷"] # 0x27E8 (Mathematical left angle bracket) - - "⟩": [t: "⠨⠨⠾"] # 0x27E9 (Mathematical right angle bracket) - - "⟵": [t: "⠀⠫⠪⠒⠒⠒⠀"] # 0x27F5 (Long leftwards arrow ) - - "⟶": [t: "⠀⠫⠒⠒⠒⠕⠀"] # 0x27F6 (Long rightwards arrow) - - "⟷": [t: "⠀⠫⠪⠒⠒⠒⠕⠀"] # 0x27F7 (Long left right arrow) - - "⟸": [t: "⠀⠫⠪⠶⠶⠶⠀"] # 0x27F8 (Long leftwards arrow ) - - "⟹": [t: "⠀⠫⠶⠶⠶⠕⠀"] # 0x27F9 (Long rightwards arrow) - - "⟺": [t: "⠀⠫⠪⠶⠶⠶⠕⠀"] # 0x27FA (Long left right arrow) - - "⟻": [t: "⠀⠫⠪⠒⠒⠒⠳⠀"] # 0x27FB (Long leftwards arrow from bar) - - "⟼": [t: "⠀⠫⠳⠒⠒⠒⠕⠀"] # 0x27FC (Long rightwards arrow from bar) - - "⟽": [t: "⠀⠫⠪⠶⠶⠶⠳⠀"] # 0x27FD (Long leftwards double arrow from bar) - - "⟾": [t: "⠀⠫⠳⠶⠶⠶⠕⠀"] # 0x27FE (Long rightwards double arrow from bar) - - "⟿": [t: "⠀⠫⠢⠤⠔⠒⠢⠤⠔⠒⠢⠕⠀"] # 0x27FF (Long rightwards squiggle arrow) - - "⤡": [t: "⠀⠫⠘⠪⠒⠒⠕⠀"] # 0x2921 (North west and south east arrow) - - "⤢": [t: "⠀⠫⠰⠪⠒⠒⠕⠀"] # 0x2922 (North east and south west arrow) - - "🣐": # 0x1f8d0 (Long rightwards arrow over leftwards arrow (equilibrium)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠕⠫⠪⠒"] - else: [t: "⠫⠒⠒⠈⠕⠫⠠⠪⠒⠒"] - - "🣑": # 0x1f8d1 (Long rightwards harpoon over leftwards harpoon (equilibrium)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠕⠫⠪⠒"] - else: [t: "⠫⠒⠒⠈⠕⠫⠠⠪⠒⠒"] - - "🣒": # 0x1f8d2 (Long rightwards harpoon over short leftwards harpoon (equilibrium)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠒⠕⠫⠪⠒"] - else: [t: "⠫⠒⠒⠈⠕⠫⠈⠪⠒⠒"] - - "🣓": # 0x1f8d3 (Short rightwards harpoon over long leftwards harpoon (equilibrium, trend to the right)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠕⠫⠪⠒⠒"] - else: [t: "⠫⠒⠈⠕⠫⠠⠪⠒⠒"] - - "🣔": # 0x1f8d4 (Long leftwards harpoon over short rightwards harpoon (equilibrium, trend to the left)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠪⠒⠒⠫⠒⠕"] - else: [t: "⠫⠈⠪⠒⠒⠫⠒⠠⠕"] - - "🣕": # 0x1f8d5 (Short leftwards harpoon over long rightwards harpoon (equilibrium, trend to the left)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠪⠒⠫⠒⠒⠕"] - else: [t: "⠫⠈⠪⠒⠫⠒⠒⠠⠕"] - - "⥂": # 0x2942 (Long rightwards harpoon over short leftwards harpoon (equilibrium)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠒⠕⠫⠪⠒"] - else: [t: "⠫⠒⠒⠈⠕⠫⠈⠪⠒⠒"] - - "⥄": # 0x2944 (Short rightwards harpoon over long leftwards harpoon (equilibrium, trend to the right)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠕⠫⠪⠒⠒"] - else: [t: "⠫⠒⠈⠕⠫⠠⠪⠒⠒"] - - "⥃": # 0x2943 (Long leftwards harpoon over short rightwards harpoon (equilibrium, trend to the left)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠪⠒⠒⠫⠒⠕"] - else: [t: "⠫⠈⠪⠒⠒⠫⠒⠠⠕"] - - "🣖": [t: "⠌⠫⠒⠒⠕"] # 0x1f8d6 (long rightwards arrow with through X) - - "🣗": [t: "⠌⠫⠒⠒⠕"] # 0x1f8d7 (long rightwards arrow with double slash) chem code says it is same as 0x1f8d6 - - - - "⦃": [t: "⠨⠸⠷"] # 0x2983 (Left white curly bracket) - - "⦄": [t: "⠨⠸⠾"] # 0x2984 (Right white curly bracket) - - "⦑": [t: "⠡⠈⠨⠨⠷⠻"] # 0x2991 (Left angle bracket w dot) - - "⦒": [t: "⠡⠈⠨⠨⠾⠻"] # 0x2992 (Right angle bracket w dot) - - "⧄": [t: "⠫⠲⠸⠫⠔⠻"] # 0x29C4 (Square rising diagonal slash) - - "⧅": [t: "⠫⠲⠸⠫⠢⠻"] # 0x29C5 (Square falling diagonal slash) - - "⧆": [t: "⠫⠲⠸⠫⠈⠼⠻"] # 0x29C6 (Squared asterisk) - - "⧊": [t: "⠐⠫⠞⠣⠡⠻"] # 0x29CA (Triangle w dot above) - - "⧋": [t: "⠫⠞⠱"] # 0x29CB (Triangle w underbar) - - "⧌": [t: "⠫⠞⠎"] # 0x29CC (s in triangle §114) - - "⧦": [t: "⠫⠳⠶⠶⠳"] # 0x29E6 (Gleich stark) - - "⨌": [t: "⠮⠮⠮⠮"] # 0x2A0C (Quadruple integral operator) - - "⨍": [t: "⠮⠈⠱⠻"] # 0x2A0D (Finite part integral) - - "⨎": [t: "⠮⠈⠱⠱⠻"] # 0x2A0E (Integral w double stroke) - - "⨖": [t: "⠮⠈⠫⠲⠻"] # 0x2A16 (Quaternion integral operator) - - "⨘": [t: "⠮⠈⠈⠡⠻"] # 0x2A18 (Integral w times sign) - - "⨙": [t: "⠮⠈⠨⠩⠻"] # 0x2A19 (Integral w intersection) - - "⨚": [t: "⠮⠈⠨⠬⠻"] # 0x2A1A (Integral w union) - - "⨛": [t: "⠣⠮"] # 0x2A1B (Integral w overbar (upper)) - - "⨜": [t: "⠩⠮"] # 0x2A1C (Integral w underbar (lower)) - - "⨢": [t: "⠐⠬⠣⠨⠡⠻"] # 0x2A22 (Plus sign w small circle above) - - "⨣": [t: "⠐⠬⠣⠸⠣⠻"] # 0x2A23 (Plus sign w circumflex accent above) - - "⨤": [t: "⠐⠬⠣⠈⠱⠻"] # 0x2A24 (Plus sign w tilde above) - - "⨥": [t: "⠐⠬⠩⠡⠻"] # 0x2A25 (Plus sign w dot below) - - "⨪": [t: "⠐⠱⠩⠡⠻"] # 0x2A2A (Minus sign w dot below) - - "⨰": [t: "⠐⠈⠡⠣⠡⠻"] # 0x2A30 (Multiplication sign w dot above) - - "⨱": [t: "⠈⠡⠱"] # 0x2A31 (Multiplication sign w underbar) - - "⨸": [t: "⠫⠉⠸⠫⠨⠌⠻"] # 0x2A38 (Circled division sign) - - "⨹": [t: "⠫⠞⠸⠫⠬⠻"] # 0x2A39 (Plus sign in triangle) - - "⨺": [t: "⠫⠞⠸⠫⠤⠻"] # 0x2A3A (Minus sign in triangle) - - "⨻": [t: "⠫⠞⠸⠫⠈⠡⠻"] # 0x2A3B (Multiplication sign in triangle) - - "⩀": [t: "⠡⠈⠨⠩⠻"] # 0x2A40 (Intersection w dot) - - "⩁": [t: "⠤⠈⠨⠬⠻"] # 0x2A41 (Union w minus sign) - - "⩂": [t: "⠱⠨⠬"] # 0x2A42 (Union w overbar) - - "⩃": [t: "⠱⠨⠩"] # 0x2A43 (Intersection w overbar) - - "⩑": [t: "⠐⠈⠩⠣⠡⠻"] # 0x2A51 (Logical AND w dot above) - - "⩒": [t: "⠐⠈⠬⠣⠡⠻"] # 0x2A52 (Logical OR w dot above) - - "⩜": [t: "⠱⠈⠈⠩⠻"] # 0x2A5C (Logical AND with horizontal dash) - - "⩝": [t: "⠱⠈⠈⠬⠻"] # 0x2A5D (Logical OR with horizontal dash) - - "⩞": [t: "⠱⠱⠈⠩"] # 0x2A5E (Logical AND w double overbar) - - "⩟": [t: "⠈⠩⠱"] # 0x2A5F (Logical AND w underbar) - - "⩠": [t: "⠈⠩⠱⠱"] # 0x2A60 (Logical AND w double underbar) - - "⩢": [t: "⠱⠱⠈⠬"] # 0x2A62 (Logical OR w double overbar) - - "⩣": [t: "⠈⠬⠱⠱"] # 0x2A63 (Logical OR w double underbar) - - "⩦": [t: "⠐⠨⠅⠩⠡⠻"] # 0x2A66 (Equals sign w dot below) - - "⩧": [t: "⠐⠸⠇⠣⠡⠻"] # 0x2A67 (Identical w dot above) - - "⩪": [t: "⠐⠈⠱⠣⠡⠻"] # 0x2A6A (Tilde operator w dot above) - - "⩬": [t: "⠈⠱⠱⠈⠱"] # 0x2A6C (Similar minus similar) - - "⩭": [t: "⠐⠈⠱⠨⠅⠣⠡⠻"] # 0x2A6D (Congruent w dot above) - - "⩮": [t: "⠐⠨⠅⠣⠈⠼⠻"] # 0x2A6E (Equals w asterisk) - - "⩯": [t: "⠐⠈⠱⠈⠱⠣⠸⠣⠻"] # 0x2A6F (Almost equal to w circumflex) - - "⩰": [t: "⠈⠱⠈⠱⠨⠅"] # 0x2A70 (Approximately equal or equal to) - - "⩱": [t: "⠨⠅⠬"] # 0x2A71 (Equals sign above plus sign) - - "⩲": [t: "⠬⠨⠅"] # 0x2A72 (Plus sign above equals sign) - - "⩳": [t: "⠨⠅⠈⠱"] # 0x2A73 (Equals sign above tilde operator) - - "⩴": [t: "⠐⠂⠐⠂⠨⠅"] # 0x2A74 (Double colon equal) - - "⩵": [t: "⠨⠅⠨⠅"] # 0x2A75 (Two consecutive equals signs) - - "⩶": [t: "⠨⠅⠨⠅⠨⠅"] # 0x2A76 (Three consecutive equals signs) - - "⩷": [t: "⠐⠨⠅⠩⠡⠡⠣⠡⠡⠻"] # 0x2A77 (Equals sign w two dots above and two dots below) - - "⩸": [t: "⠐⠸⠇⠣⠡⠡⠡⠡⠻"] # 0x2A78 (Equivalent w four dots above) - - "⩹": [t: "⠐⠅⠈⠨⠡⠻"] # 0x2A79 (Less than w circle inside) - - "⩺": [t: "⠨⠂⠈⠨⠡⠻"] # 0x2A7A (Greater than w circle inside) - - "⩻": [t: "⠐⠐⠅⠣⠸⠦⠻"] # 0x2A7B (Less-than w question mark above) - - "⩼": [t: "⠐⠨⠂⠣⠸⠦⠻"] # 0x2A7C (Greater-than w question mark above) - - "⪅": [t: "⠐⠅⠈⠱⠈⠱"] # 0x2A85 (Less-than or approximate) - - "⪆": [t: "⠨⠂⠈⠱⠈⠱"] # 0x2A86 (Greater-than or approximate) - - "⪋": [t: "⠐⠅⠨⠅⠨⠂"] # 0x2A8B (Less-than above double-line equal above greater-than) - - "⪌": [t: "⠨⠂⠨⠅⠐⠅"] # 0x2A8C (Greater-than above double-line equal above less-than) - - "⪍": [t: "⠐⠅⠈⠱⠱"] # 0x2A8D (Less-than above similar or equal to) - - "⪎": [t: "⠨⠂⠈⠱⠱"] # 0x2A8E (Greater-than above similar or equal to) - - "⪏": [t: "⠐⠅⠈⠱⠨⠂"] # 0x2A8F (Less-than above similar above greater-than) - - "⪐": [t: "⠨⠂⠈⠱⠐⠅"] # 0x2A90 (Greater-than above similar above less-than) - - "⪑": [t: "⠐⠅⠨⠂⠨⠅"] # 0x2A91 (Less-than above greater-than above double-line equal) - - "⪒": [t: "⠨⠂⠐⠅⠨⠅"] # 0x2A92 (Greater-than above less-than above double-line equal) - - "⪙": [t: "⠨⠅⠐⠅"] # 0x2A99 (Double-line equal to or less-than) - - "⪚": [t: "⠨⠅⠨⠂"] # 0x2A9A (Double-line equal to or greater-than) - - "⪝": [t: "⠈⠱⠐⠅"] # 0x2A9D (Similar or less-than) - - "⪞": [t: "⠈⠱⠨⠂"] # 0x2A9E (Similar or greater-than) - - "⪟": [t: "⠈⠱⠐⠅⠨⠅"] # 0x2A9F (Similar above less-than above equals sign) - - "⪠": [t: "⠈⠱⠨⠂⠨⠅"] # 0x2AA0 (Similar above greater-than above equals sign) - - "⪮": [t: "⠈⠣⠨⠅"] # 0x2AAE (Equals sign with bumpy above) - - "⪽": [t: "⠡⠈⠸⠐⠅⠻"] # 0x2ABD (Subset w dot) - - "⪾": [t: "⠡⠈⠸⠨⠂⠻"] # 0x2ABE (Superset w dot) - - "⪿": [t: "⠐⠸⠐⠅⠩⠬⠻"] # 0x2ABF (Subset with plus sign below) - - "⫀": [t: "⠐⠸⠨⠂⠩⠬⠻"] # 0x2AC0 (Superset with plus sign below) - - "⫁": [t: "⠐⠸⠐⠅⠩⠈⠡⠻"] # 0x2AC1 (Subset with multiplication sign below) - - "⫂": [t: "⠐⠸⠨⠂⠩⠈⠡⠻"] # 0x2AC2 (Superset with multiplication sign below) - - "⫅": [t: "⠸⠐⠅⠨⠅"] # 0x2AC5 (Subset of above equals sign) - - "⫆": [t: "⠸⠨⠂⠨⠅"] # 0x2AC6 (Superset of above equals sign) - - "⫇": [t: "⠸⠐⠅⠈⠱"] # 0x2AC7 (Subset of above tilde operator) - - "⫈": [t: "⠸⠨⠂⠈⠱"] # 0x2AC8 (Superset of above tilde operator) - - "⫉": [t: "⠸⠐⠅⠈⠱⠈⠱"] # 0x2AC9 (Subset of above almost equal to) - - "⫊": [t: "⠸⠨⠂⠈⠱⠈⠱"] # 0x2ACA (Superset of above almost equal to) - - "⫋": [t: "⠸⠐⠅⠌⠨⠅"] # 0x2ACB (Subset of above not equals sign) - - "⫌": [t: "⠸⠨⠂⠌⠨⠅"] # 0x2ACC (Superset of above not equals sign) - - "⫓": [t: "⠸⠐⠅⠸⠨⠂"] # 0x2AD3 (Subset above superset) - - "⫔": [t: "⠸⠨⠂⠸⠐⠅"] # 0x2AD4 (Superset above subset) - - "⫕": [t: "⠸⠐⠅⠸⠐⠅"] # 0x2AD5 (Subset above subset) - - "⫖": [t: "⠸⠨⠂⠸⠨⠂"] # 0x2AD6 (Superset above superset) - - "⫗": [t: "⠸⠨⠂⠐⠸⠐⠅"] # 0x2AD7 (Superset beside subset) - - "⫯": [t: "⠫⠩⠨⠡⠒⠒"] # 0x2AEF (Vertical line w circle above) - - "⫰": [t: "⠫⠣⠨⠡⠒⠒"] # 0x2AF0 (Vertical line w circle below) - - "⫱": [t: "⠫⠣⠨⠡⠒⠒⠳"] # 0x2AF1 (Down tack w circle below) - - "⫲": [t: "⠱⠈⠫⠇⠻"] # 0x2AF2 (Parallel w horizontal stroke) - - "⫳": [t: "⠈⠱⠈⠫⠇⠻"] # 0x2AF3 (Parallel w tilde operator) - - "⫴": [t: "⠳⠳⠳"] # 0x2AF4 (Triple vertical bar binary relation) - - "⬬": [t: "⠫⠸⠑"] # 0x2B2C (Black ellipse) - - "⬭": [t: "⠫⠑"] # 0x2B2D (White ellipse) - - "⬰": [t: "⠨⠡⠈⠫⠪⠒⠒⠻"] # 0x2B30 (Left arrow w small circle) - - "⬱": [t: "⠫⠪⠒⠒⠫⠪⠒⠒⠫⠪⠒⠒"] # 0x2B31 (Three leftwards arrows) - - "⬲": [t: "⠫⠪⠒⠒⠈⠫⠉⠸⠫⠬⠻"] # 0x2B32 (Left arrow w circled plus) - - "⮖": [t: "⠨⠡"] # 0x2B96 (Standard State Symbol) - - "⯃": [t: "⠫⠸⠦"] # 0x2BC3 (Horizontal black octagon) - - # SRE lists this as a custom transcription - - "⋊": [t: "⠈⠡⠳"] # 0x22ca (RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT) +--- +# To greatly simplify typeface/language generation, the chars have unique ASCII chars for them: +# Typeface: S: sans-serif, B: bold, T: script/blackboard, I: italic, R: Roman +# Language: E: English, D: German, G: Greek, V: Greek variants, H: Hebrew, U: Russian +# Indicators: C: capital, L: letter, N: number, P: punctuation, M: multipurpose +# Others: W -- whitespace that should be kept (e.g, in a numeral) +# SRE doesn't have H: Hebrew, so not encoded (yet) +# Some of the weird letters (e.g., circled letters) I didn't translate with the above because +# they don't interact with rules since they are enclosed in other chars. + + - "⨯": [t: "⠈⠡"] # U+2A2F(VECTOR OR CROSS PRODUCT) -- make the same as 0x00D7 (Multiplication sign) + + # --- Nemeth Default Alphabet bold chars. --- + - "𝐀-𝐙": # 0x1d400 - 0x1d419 + - tc: "BE" + - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝐚-𝐳": # 0x1d41a - 0x1d433 + - tc: "BE" + - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 + - tc: "BG" + - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" + + - "𝛂-𝛒": # 0x1d6c2 - 0x1d6d2 + - tc: "BG" + - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒', 'αβγδεζηθικλμνξοπρ')" + + - "𝛔-𝛖": # 0x1d6d4 - 0x1d6d6 + - tc: "BG" + - spell: "translate('.', '𝛔𝛕𝛖', 'στυ')" + + - "𝛘-𝛚": # 0x1d6d8 - 0x1d6da + - tc: "BG" + - spell: "translate('.', '𝛘𝛙𝛚', 'χψω')" + + - "𝛁": [tc: "BGL⠫"] # 0x1d6c1 + - "𝛓": [tc: "BVL⠎"] # 0x1d6d3 + - "𝛗": [tc: "BVL⠋"] # 0x1d6d7 + - "𝛛": [tc: "⠸⠈⠙"] # 0x1d6db + - "𝛜": [tc: "BGL⠑"] # 0x1d6dc + - "𝛝": [tc: "BVL⠹"] # 0x1d6dd + - "𝛞": [tc: "BGL⠅"] # 0x1d6de + - "𝛟": [tc: "BGL⠋"] # 0x1d6df + - "𝛠": [tc: "BGL⠗"] # 0x1d6e0 + - "𝛡": [tc: "BGL⠏"] # 0x1d6e1 + + - "𝟎-𝟗": # 0x1d7ce - 0x1d7d7 + - tc: "B" + - spell: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" + + # --- Nemeth Default Alphabet bold-fraktur chars. --- + + - "𝕬-𝖅": # 0x1d56c - 0x1d585 + - tc: "BD" + - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝖆-𝖟": # 0x1d586 - 0x1d59f + - tc: "BD" + - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" + + # --- Nemeth Default Alphabet bold-italic chars. --- + - "𝑨-𝒁": # 0x1d468 - 0x1d481 + - tc: "BE" + - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝒂-𝒛": # 0x1d482 - 0x1d49b + - tc: "BE" + - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝜜-𝜴": # 0x1d71c - 0x1d734 + - tc: "BG" + - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" + + - "𝜵": [tc: "BGL⠫"] # 0x1d735 + + - "𝜶-𝝆": # 0x1d736 - 0x1d746 + - tc: "BG" + - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆', 'αβγδεζηθικλμνξοπρ')" + + - "𝝇": [tc: "BVL⠎"] # 0x1d747 + + - "𝝈-𝝊": # 0x1d748 - 0x1d74a + - tc: "BG" + - spell: "translate('.', '𝝈𝝉𝝊', 'στυ')" + + - "𝝋": [tc: "BVL⠋"] # 0x1d74b + + - "𝝌-𝝎": # 0x1d74c - 0x1d74e + - tc: "BG" + - spell: "translate('.', '𝝌𝝍𝝎', 'χψω')" + + - "𝝏": [tc: "BVL⠙"] # 0x1d74f + - "𝝐": [tc: "BGL⠑"] # 0x1d750 + - "𝝑": [tc: "BVL⠹"] # 0x1d751 + + - "𝝒-𝝕": # 0x1d752 - 0x1d755 + - tc: "BG" + - spell: "translate('.', '𝝒𝝓𝝔𝝕', 'κφρπ')" + + # --- Nemeth Default Alphabet bold-script chars. --- + + - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 + - tc: "BTE" + - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝓪-𝔃": # 0x1d4ea - 0x1d503 + - tc: "BTE" + - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝚤-𝚥": # 0x1d6a4 - 0x1d6a5 + - tc: "" + - spell: "translate('.', '𝚤𝚥', '⠊⠚')" + +# Russian Alphabet (from Nemeth book) +# NOTE: is this translation needed? + - "А-Я": # 0x410 - 0x42f + - tc: "U" + - spell: "translate('.', 'АБВГДЕЗИЙКЛМНОПРСТУФЭ', 'ABVGDEZIYKLMNOPRSTUFE')" + + - "а-я": # 0x430 - 0x44f + - tc: "U" + - spell: "translate('.', 'абвгдезийклмнопрстуфэ', 'abvgdeziylkmnoprstufye')" + + - "①-⑨": # 0x2460 - 0x2473 + - tc: "⠫⠉⠸⠫⠼" + - spell: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" + - tc: "⠻" + + - "⓪": [tc: "⠫⠉⠸⠫⠼⠴⠻"] # 0x24ea + + - "⑩": [tc: "⠫⠉⠸⠫⠼⠂⠴⠻"] # 0x2469 + - "⑪": [tc: "⠫⠉⠸⠫⠼⠂⠂⠻"] # 0x246a + - "⑫": [tc: "⠫⠉⠸⠫⠼⠂⠆⠻"] # 0x246b + - "⑬": [tc: "⠫⠉⠸⠫⠼⠂⠒⠻"] # 0x246c + - "⑭": [tc: "⠫⠉⠸⠫⠼⠂⠲⠻"] # 0x246d + - "⑮": [tc: "⠫⠉⠸⠫⠼⠂⠢⠻"] # 0x246e + - "⑯": [tc: "⠫⠉⠸⠫⠼⠂⠖⠻"] # 0x246f + - "⑰": [tc: "⠫⠉⠸⠫⠼⠂⠶⠻"] # 0x2470 + - "⑱": [tc: "⠫⠉⠸⠫⠼⠂⠦⠻"] # 0x2471 + - "⑲": [tc: "⠫⠉⠸⠫⠼⠂⠔⠻"] # 0x2472 + - "⑳": [tc: "⠫⠉⠸⠫⠼⠆⠴⠻"] # 0x2473 + + - "㉑": [tc: "⠫⠉⠸⠫⠼⠆⠂⠻"] # 0x3251 + - "㉒": [tc: "⠫⠉⠸⠫⠼⠆⠆⠻"] # 0x3252 + - "㉓": [tc: "⠫⠉⠸⠫⠼⠆⠒⠻"] # 0x3253 + - "㉔": [tc: "⠫⠉⠸⠫⠼⠆⠲⠻"] # 0x3254 + - "㉕": [tc: "⠫⠉⠸⠫⠼⠆⠢⠻"] # 0x3255 + - "㉖": [tc: "⠫⠉⠸⠫⠼⠆⠖⠻"] # 0x3256 + - "㉗": [tc: "⠫⠉⠸⠫⠼⠆⠶⠻"] # 0x3257 + - "㉘": [tc: "⠫⠉⠸⠫⠼⠆⠦⠻"] # 0x3258 + - "㉙": [tc: "⠫⠉⠸⠫⠼⠆⠔⠻"] # 0x3259 + - "㉚": [tc: "⠫⠉⠸⠫⠼⠒⠴⠻"] # 0x325a + - "㉛": [tc: "⠫⠉⠸⠫⠼⠒⠂⠻"] # 0x325b + - "㉜": [tc: "⠫⠉⠸⠫⠼⠒⠆⠻"] # 0x325c + - "㉝": [tc: "⠫⠉⠸⠫⠼⠒⠒⠻"] # 0x325d + - "㉞": [tc: "⠫⠉⠸⠫⠼⠒⠲⠻"] # 0x325e + - "㉟": [tc: "⠫⠉⠸⠫⠼⠒⠢⠻"] # 0x325f + - "㊱": [tc: "⠫⠉⠸⠫⠼⠒⠖⠻"] # 0x32b1 + - "㊲": [tc: "⠫⠉⠸⠫⠼⠒⠶⠻"] # 0x32b2 + - "㊳": [tc: "⠫⠉⠸⠫⠼⠒⠦⠻"] # 0x32b3 + - "㊴": [tc: "⠫⠉⠸⠫⠼⠒⠔⠻"] # 0x32b4 + - "㊵": [tc: "⠫⠉⠸⠫⠼⠲⠴⠻"] # 0x32b5 + - "㊶": [tc: "⠫⠉⠸⠫⠼⠲⠂⠻"] # 0x32b6 + - "㊷": [tc: "⠫⠉⠸⠫⠼⠲⠆⠻"] # 0x32b7 + - "㊸": [tc: "⠫⠉⠸⠫⠼⠲⠒⠻"] # 0x32b8 + - "㊹": [tc: "⠫⠉⠸⠫⠼⠲⠲⠻"] # 0x32b9 + - "㊺": [tc: "⠫⠉⠸⠫⠼⠲⠢⠻"] # 0x32ba + - "㊻": [tc: "⠫⠉⠸⠫⠼⠲⠖⠻"] # 0x32bb + - "㊼": [tc: "⠫⠉⠸⠫⠼⠲⠶⠻"] # 0x32bc + - "㊽": [tc: "⠫⠉⠸⠫⠼⠲⠦⠻"] # 0x32bd + - "㊾": [tc: "⠫⠉⠸⠫⠼⠲⠔⠻"] # 0x32be + - "㊿": [tc: "⠫⠉⠸⠫⠼⠢⠴⠻"] # 0x32bf + +#NOTE: uncertainty here + - "Ⓐ-Ⓩ": # 0x24b6 - 0x24cf + - tc: "⠫⠉⠸⠫⠠" + - spell: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - tc: "⠻" + + - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 + - tc: "⠫⠉⠸⠫" + - spell: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" + - tc: "⠻" + + # --- Nemeth Default Alphabet circled-sans-serif chars. --- + + - "➀-➈": # 0x1f10b, 0x2780 - 0x2788 + - tc: "⠫⠉⠸⠫⠠⠨⠼" + - spell: "translate('.', '➀➁➂➃➄➅➆➇➈', '123456789')" + - tc: "⠻" + + - "🄋": [tc: "⠫⠉⠸⠫⠠⠨⠼⠴⠻"] # 0x1f10b + - "➉": [tc: "⠫⠉⠸⠫⠠⠨⠼⠂⠴⠻"] # 0x2789 + + # --- Nemeth Default Alphabet comma chars. --- + + - "🄁-🄊": # 0x1f101 - 0x1f10a + - spell: "translate('.', '🄁🄂🄃🄄🄅🄆🄇🄈🄉🄊', '0123456789')" + - tc: "⠠" + + + # --- Nemeth Default Alphabet double-circled chars. --- + + - "⓵": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠂⠻⠻"] # 0x24f5 + - "⓶": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠆⠻⠻"] # 0x24f6 + - "⓷": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠒⠻⠻"] # 0x24f7 + - "⓸": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠲⠻⠻"] # 0x24f8 + - "⓹": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠢⠻⠻"] # 0x24f9 + - "⓺": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠖⠻⠻"] # 0x24fa + - "⓻": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠶⠻⠻"] # 0x24fb + - "⓼": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠦⠻⠻"] # 0x24fc + - "⓽": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠔⠻⠻"] # 0x24fd + - "⓾": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠂⠴⠻⠻"] # 0x24fe + + # --- Nemeth Default Alphabet double-struck chars. --- + - "𝔸-𝕐": # 0x1d538 - 0x1d550 (partial, excludes ℂ ℍ ℕ ℙ ℚ ℝ ℤ) + - tc: "𝔹E" + - spell: "translate('.', '𝔸𝔹𝔻𝔼𝔽𝔾𝕀𝕁𝕂𝕃𝕄𝕆𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABDEFGIJKLMOSTUVWXY')" + + - "ℂ": [tc: "𝔹ECL⠉"] # 0x2102 + - "ℍ": [tc: "𝔹ECL⠓"] # 0x210d + - "ℕ": [tc: "𝔹ECL⠝"] # 0x2115 + - "ℙ": [tc: "𝔹ECL⠏"] # 0x2119 + - "ℚ": [tc: "𝔹ECL⠟"] # 0x211a + - "ℝ": [tc: "𝔹ECL⠗"] # 0x211d + - "ℤ": [tc: "𝔹ECL⠵"] # 0x2124 + - "Ω": [t: "CGL⠺"] # 0x2126 (Ohm sign (capital Greek omega)) + + - "𝕒-𝕫": # 0x1d552 - 0x1d56b + - tc: "𝔹E" + - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 + - tc: "𝔹" + - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" + + + # --- Nemeth Default Alphabet fraktur chars. --- + + - "𝔄-𝔜": # 0x1d504 - 0x1d51c + - tc: "D" + - spell: "translate('.', '𝔄𝔅𝔇𝔈𝔉𝔊𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABDEFGJKLMNOPQSTUVWXY')" + + - "ℭ": [tc: "DCL⠉"] # 0x212d + - "ℌ": [tc: "DCL⠓"] # 0x210c + - "ℑ": [tc: "DCL⠊"] # 0x2111 + - "ℜ": [tc: "DCL⠗"] # 0x211c + - "ℨ": [tc: "DCL⠵"] # 0x2128 + + - "𝔞-𝔷": # 0x1d51e - 0x1d537 + - tc: "D" + - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" + + # --- Nemeth Default Alphabet fullwidth chars. --- + + - "A-Z": # 0xff21 - 0xff3a + - tc: "" + - spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "a-z": # 0xff41 - 0xff5a + - tc: "" + - spell: "translate('.', 'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz')" + + - "0-9": # 0xff10 - 0xff19 + - tc: "" + - spell: "translate('.', '0123456789', '0123456789')" + + # --- Nemeth Default Alphabet italic chars -- treat as non-italic. --- + + - "𝐴-𝑍": # 0x1d434 - 0x1d44d + - tc: "E" + - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝑎-𝑧": # 0x1d44e - 0x1d467 + - tc: "E" + - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔ℎ𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa + - tc: "G" + - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" + + - "𝛻": [tc: "GL⠫"] # 0x1d6fb + + - "𝛼-𝜌": # 0x1d6fc - 0x1d70c + - tc: "G" + - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌', 'αβγδεζηθικλμνξοπρ')" + - "𝜍": [tc: "VL⠎"] # 0x1d70d + + - "𝜎": [tc: "GL⠎"] # 0x1d70e + - "𝜏": [tc: "GL⠞"] # 0x1d70f + - "𝜐": [tc: "GL⠥"] # 0x1d710 + + - "𝜑": [tc: "VL⠋"] # 0x1d711 + + - "𝜒": [tc: "GL⠯"] # 0x1d712 + - "𝜓": [tc: "GL⠽"] # 0x1d713 + - "𝜔": [tc: "GL⠺"] # 0x1d714 + + - "𝜕": [tc: "VL⠙"] # 0x1d715 + + - "𝜖": [tc: "GL⠑"] # 0x1d716 + + - "𝜗": [tc: "VL⠹"] # 0x1d717 + + - "𝜘": [tc: "GL⠅"] # 0x1d718 + - "𝜙": [tc: "GL⠋"] # 0x1d719 + - "𝜚": [tc: "GL⠗"] # 0x1d71a + - "𝜛": [tc: "GL⠏"] # 0x1d71b + + # --- Nemeth Default Alphabet monospace chars. --- + + - "𝙰-𝚉": # 0x1d670 - 0x1d689 + - tc: "" + - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 + - tc: "" + - spell: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝟶-𝟿": # 0x1d7f6 - 0x1d7ff + - tc: "" + - spell: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" + + + # --- Nemeth Default Alphabet negative-circled chars. --- + - "⓿": [t: "⠫⠸⠉⠸⠫⠼⠴⠻"] # 0x24ff + - "❶": [t: "⠫⠸⠉⠸⠫⠼⠂⠻"] # 0x2776 + - "❷": [t: "⠫⠸⠉⠸⠫⠼⠆⠻"] # 0x2777 + - "❸": [t: "⠫⠸⠉⠸⠫⠼⠒⠻"] # 0x2778 + - "❹": [t: "⠫⠸⠉⠸⠫⠼⠲⠻"] # 0x2779 + - "❺": [t: "⠫⠸⠉⠸⠫⠼⠢⠻"] # 0x277a + - "❻": [t: "⠫⠸⠉⠸⠫⠼⠖⠻"] # 0x277b + - "❼": [t: "⠫⠸⠉⠸⠫⠼⠶⠻"] # 0x277c + - "❽": [t: "⠫⠸⠉⠸⠫⠼⠦⠻"] # 0x277d + - "❾": [t: "⠫⠸⠉⠸⠫⠼⠔⠻"] # 0x277e + - "❿": [t: "⠫⠸⠉⠸⠫⠼⠂⠴⠻"] # 0x277f + - "⓫": [t: "⠫⠸⠉⠸⠫⠼⠂⠂⠻"] # 0x24eb + - "⓬": [t: "⠫⠸⠉⠸⠫⠼⠂⠆⠻"] # 0x24ec + - "⓭": [t: "⠫⠸⠉⠸⠫⠼⠂⠒⠻"] # 0x24ed + - "⓮": [t: "⠫⠸⠉⠸⠫⠼⠂⠲⠻"] # 0x24ee + - "⓯": [t: "⠫⠸⠉⠸⠫⠼⠂⠢⠻"] # 0x24ef + - "⓰": [t: "⠫⠸⠉⠸⠫⠼⠂⠖⠻"] # 0x24f0 + - "⓱": [t: "⠫⠸⠉⠸⠫⠼⠂⠶⠻"] # 0x24f1 + - "⓲": [t: "⠫⠸⠉⠸⠫⠼⠂⠦⠻"] # 0x24f2 + - "⓳": [t: "⠫⠸⠉⠸⠫⠼⠂⠔⠻"] # 0x24f3 + - "⓴": [t: "⠫⠸⠉⠸⠫⠼⠆⠴⠻"] # 0x24f4 + + - "🅐": [t: "⠫⠸⠉⠸⠫⠠⠁⠻"] # 0x1f150 + - "🅑": [t: "⠫⠸⠉⠸⠫⠠⠃⠻"] # 0x1f151 + - "🅒": [t: "⠫⠸⠉⠸⠫⠠⠉⠻"] # 0x1f152 + - "🅓": [t: "⠫⠸⠉⠸⠫⠠⠙⠻"] # 0x1f153 + - "🅔": [t: "⠫⠸⠉⠸⠫⠠⠑⠻"] # 0x1f154 + - "🅕": [t: "⠫⠸⠉⠸⠫⠠⠋⠻"] # 0x1f155 + - "🅖": [t: "⠫⠸⠉⠸⠫⠠⠛⠻"] # 0x1f156 + - "🅗": [t: "⠫⠸⠉⠸⠫⠠⠓⠻"] # 0x1f157 + - "🅘": [t: "⠫⠸⠉⠸⠫⠠⠊⠻"] # 0x1f158 + - "🅙": [t: "⠫⠸⠉⠸⠫⠠⠚⠻"] # 0x1f159 + - "🅚": [t: "⠫⠸⠉⠸⠫⠠⠅⠻"] # 0x1f15a + - "🅛": [t: "⠫⠸⠉⠸⠫⠠⠇⠻"] # 0x1f15b + - "🅜": [t: "⠫⠸⠉⠸⠫⠠⠍⠻"] # 0x1f15c + - "🅝": [t: "⠫⠸⠉⠸⠫⠠⠝⠻"] # 0x1f15d + - "🅞": [t: "⠫⠸⠉⠸⠫⠠⠕⠻"] # 0x1f15e + - "🅟": [t: "⠫⠸⠉⠸⠫⠠⠏⠻"] # 0x1f15f + - "🅠": [t: "⠫⠸⠉⠸⠫⠠⠟⠻"] # 0x1f160 + - "🅡": [t: "⠫⠸⠉⠸⠫⠠⠗⠻"] # 0x1f161 + - "🅢": [t: "⠫⠸⠉⠸⠫⠠⠎⠻"] # 0x1f162 + - "🅣": [t: "⠫⠸⠉⠸⠫⠠⠞⠻"] # 0x1f163 + - "🅤": [t: "⠫⠸⠉⠸⠫⠠⠥⠻"] # 0x1f164 + - "🅥": [t: "⠫⠸⠉⠸⠫⠠⠧⠻"] # 0x1f165 + - "🅦": [t: "⠫⠸⠉⠸⠫⠠⠺⠻"] # 0x1f166 + - "🅧": [t: "⠫⠸⠉⠸⠫⠠⠭⠻"] # 0x1f167 + - "🅨": [t: "⠫⠸⠉⠸⠫⠠⠽⠻"] # 0x1f168 + - "🅩": [t: "⠫⠸⠉⠸⠫⠠⠵⠻"] # 0x1f169 + + # --- Nemeth Default Alphabet negative-circled-sans-serif chars. --- + - "🄌": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠴⠻"] # 0x1f10c + - "➊": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠂⠻"] # 0x278a + - "➋": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠆⠻"] # 0x278b + - "➌": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠒⠻"] # 0x278c + - "➍": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠲⠻"] # 0x278d + - "➎": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠢⠻"] # 0x278e + - "➏": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠖⠻"] # 0x278f + - "➐": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠶⠻"] # 0x2790 + - "➑": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠦⠻"] # 0x2791 + - "➒": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠔⠻"] # 0x2792 + - "➓": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠂⠴⠻"] # 0x2793 + + # --- Nemeth Default Alphabet negative-squared chars. --- + - "🅰-🆉": # 0x1f170 - 0x1f189 + - tc: "⠫⠸⠲⠸⠫⠠" + - spell: "translate('.', '🅰🅱🅲🅳🅴🅵🅶🅷🅸🅹🅺🅻🅼🅽🅾🅿🆀🆁🆂🆃🆄🆅🆆🆇🆈🆉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - tc: "⠻" + + # --- Nemeth Default Alphabet parenthesized chars. --- + + - "⑴-⑼": # 0x2474 - 0x247c + - tc: "⠷" + - spell: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" + - tc: "⠾" + + - "⑽": [t: "⠷⠂⠴⠾"] # 0x247d + - "⑾": [t: "⠷⠂⠂⠾"] # 0x247e + - "⑿": [t: "⠷⠂⠆⠾"] # 0x247f + - "⒀": [t: "⠷⠂⠒⠾"] # 0x2480 + - "⒁": [t: "⠷⠂⠲⠾"] # 0x2481 + - "⒂": [t: "⠷⠂⠢⠾"] # 0x2482 + - "⒃": [t: "⠷⠂⠖⠾"] # 0x2483 + - "⒄": [t: "⠷⠂⠶⠾"] # 0x2484 + - "⒅": [t: "⠷⠂⠦⠾"] # 0x2485 + - "⒆": [t: "⠷⠂⠔⠾"] # 0x2486 + - "⒇": [t: "⠷⠆⠴⠾"] # 0x2487 + + - "🄐-🄩": # 0x1f110 - 0x1f129 + - tc: "⠷⠠" + - spell: "translate('.', '🄐🄑🄒🄓🄔🄕🄖🄗🄘🄙🄚🄛🄜🄝🄞🄟🄠🄡🄢🄣🄤🄥🄦🄧🄨🄩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - tc: "⠾" + + - "⒜-⒵": # 0x249c - 0x24b5 + - tc: "⠷" + - spell: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" + - tc: "⠾" + + # --- Nemeth Default Alphabet period chars. --- + - "🄀": [t: "⠴⠸⠲"] # 0x1f100 + - "⒈": [t: "⠂⠸⠲"] # 0x2488 + - "⒉": [t: "⠆⠸⠲"] # 0x2489 + - "⒊": [t: "⠒⠸⠲"] # 0x248a + - "⒋": [t: "⠲⠸⠲"] # 0x248b + - "⒌": [t: "⠢⠸⠲"] # 0x248c + - "⒍": [t: "⠖⠸⠲"] # 0x248d + - "⒎": [t: "⠶⠸⠲"] # 0x248e + - "⒏": [t: "⠦⠸⠲"] # 0x248f + - "⒐": [t: "⠔⠸⠲"] # 0x2490 + + - "⒑": [t: "⠂⠴⠸⠲"] # 0x2491 + - "⒒": [t: "⠂⠂⠸⠲"] # 0x2492 + - "⒓": [t: "⠂⠆⠸⠲"] # 0x2493 + - "⒔": [t: "⠂⠒⠸⠲"] # 0x2494 + - "⒕": [t: "⠂⠲⠸⠲"] # 0x2495 + - "⒖": [t: "⠂⠢⠸⠲"] # 0x2496 + - "⒗": [t: "⠂⠖⠸⠲"] # 0x2497 + - "⒘": [t: "⠂⠶⠸⠲"] # 0x2498 + - "⒙": [t: "⠂⠦⠸⠲"] # 0x2499 + - "⒚": [t: "⠂⠔⠸⠲"] # 0x249a + - "⒛": [t: "⠆⠴⠸⠲"] # 0x249b + + # --- Nemeth Default Alphabet sans-serif chars. --- + - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 + - tc: "SE" + - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 + - tc: "SE" + - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝟢-𝟫": # 0x1d7e2 - 0x1d7eb + - tc: "S" + - spell: "translate('.', '𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫', '0123456789')" + + # --- Nemeth Default Alphabet sans-serif-bold chars. --- + - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed + - tc: "SBE" + - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝗮-𝘇": # 0x1d5ee - 0x1d607 + - tc: "SBE" + - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝝖-𝝮": # 0x1d756 - 0x1d76e + - tc: "SBG" + - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" + + - "𝝰-𝞀": # 0x1d770 - 0x1d780 + - tc: "SBG" + - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀', 'αβγδεζηθικλμνξοπρ')" + + - "𝝯": [tc: "SBGL⠫"] # 0x1d76f + + - "𝞁": [tc: "SBVL⠎"] # 0x1d781 + + - "𝞂-𝞄": # 0x1d782 - 0x1d784 + - tc: "SBG" + - spell: "translate('.', '𝞂𝞃𝞄', 'στυ')" + + - "𝞅": [tc: "SBVL⠋"] # 0x1d785 + + - "𝞆-𝞈": # 0x1d786 - 0x1d788 + - tc: "SBG" + - spell: "translate('.', '𝞆𝞇𝞈', 'χψω')" + + - "𝞉": [tc: "⠠⠨⠸⠈⠙"] # 0x1d789 + - "𝞊": [tc: "SBGL⠑"] # 0x1d78a + - "𝞋": [tc: "SBVL⠹"] # 0x1d78b + + - "𝞌-𝞏": # 0x1d78c - 0x1d78f + - tc: "SBG" + - spell: "translate('.', '𝞌𝞍𝞎𝞏', 'κφρπ')" + + - "𝟬-𝟵": # 0x1d7ec - 0x1d7f5 + - tc: "SB" + - spell: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" + + # --- Nemeth Default Alphabet sans-serif-bold-italic chars. --- + + - "𝘼-𝙕": # 0x1d63c - 0x1d655 + - tc: "SBE" + - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝙖-𝙯": # 0x1d656 - 0x1d66f + - tc: "SBE" + - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 + - tc: "SBG" + - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" + + - "𝞩": [t: "SBGL⠫"] # 0x1d7a9 + + - "𝞪-𝞺": # 0x1d7aa - 0x1d7ba + - tc: "SBG" + - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺', 'αβγδεζηθικλμνξοπρ')" + + - "𝞻": [t: "SBVL⠎"] # 0x1d7bb + - "𝞼": [t: "SBGL⠎"] # 0x1d7bc + - "𝞽": [t: "SBGL⠞"] # 0x1d7bd + - "𝞾": [t: "SBGL⠥"] # 0x1d7be + - "𝞿": [t: "SBVL⠋"] # 0x1d7bf + + - "𝟀": [t: "SBGL⠯"] # 0x1d7c0 + - "𝟁": [t: "SBGL⠽"] # 0x1d7c1 + - "𝟂": [t: "SBGL⠺"] # 0x1d7c2 + - "𝟃": [t: "SBVL⠙"] # 0x1d7c3 + + - "𝟄": [t: "SBGL⠑"] # 0x1d7c4 + - "𝟅": [t: "SBVL⠹"] # 0x1d7c5 + + - "𝟆": [t: "SBGL⠅"] # 0x1d7c6 + - "𝟇": [t: "SBGL⠋"] # 0x1d7c7 + - "𝟈": [t: "SBGL⠗"] # 0x1d7c8 + - "𝟉": [t: "SBGL⠏"] # 0x1d7c9 + + # --- Nemeth Default Alphabet sans-serif-italic chars. --- + - "𝘈-𝘡": # 0x1d608 - 0x1d621 + - tc: "SE" + - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝘢-𝘻": # 0x1d622 - 0x1d63b + - tc: "SE" + - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" + + # --- Nemeth Default Alphabet script chars. --- + - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 + - tc: "TE" + - spell: "translate('.', '𝒜𝒞𝒟𝒢𝒥𝒦𝒩𝒪𝒫𝒬𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ACDGJKNOPQSTUVWXYZ')" + + - "ℬ": [t: "TECL⠃"] # 0x212c + - "ℰ": [t: "TECL⠑"] # 0x2130 + - "ℱ": [t: "TECL⠋"] # 0x2131 + - "ℋ": [t: "TECL⠓"] # 0x210b + - "ℐ": [t: "TECL⠊"] # 0x2110 + - "ℒ": [t: "TECL⠇"] # 0x2112 + - "ℳ": [t: "TECL⠍"] # 0x2133 + - "ℛ": [t: "TECL⠗"] # 0x211b + + - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf + - tc: "TE" + - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒻𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdfhijklmnpqrstuvwxyz')" + + - "ℯ": [t: "TEL⠑"] # 0x212f + - "ℊ": [t: "TEL⠛"] # 0x210a + - "ℴ": [t: "TEL⠕"] # 0x2134 + + # --- Nemeth Default Alphabet squared chars. --- + + - "🄰": [t: "⠫⠲⠸⠫⠠⠁⠻"] # 0x1f130 + - "🄱": [t: "⠫⠲⠸⠫⠠⠃⠻"] # 0x1f131 + - "🄲": [t: "⠫⠲⠸⠫⠠⠉⠻"] # 0x1f132 + - "🄳": [t: "⠫⠲⠸⠫⠠⠙⠻"] # 0x1f133 + - "🄴": [t: "⠫⠲⠸⠫⠠⠑⠻"] # 0x1f134 + - "🄵": [t: "⠫⠲⠸⠫⠠⠋⠻"] # 0x1f135 + - "🄶": [t: "⠫⠲⠸⠫⠠⠛⠻"] # 0x1f136 + - "🄷": [t: "⠫⠲⠸⠫⠠⠓⠻"] # 0x1f137 + - "🄸": [t: "⠫⠲⠸⠫⠠⠊⠻"] # 0x1f138 + - "🄹": [t: "⠫⠲⠸⠫⠠⠚⠻"] # 0x1f139 + - "🄺": [t: "⠫⠲⠸⠫⠠⠅⠻"] # 0x1f13a + - "🄻": [t: "⠫⠲⠸⠫⠠⠇⠻"] # 0x1f13b + - "🄼": [t: "⠫⠲⠸⠫⠠⠍⠻"] # 0x1f13c + - "🄽": [t: "⠫⠲⠸⠫⠠⠝⠻"] # 0x1f13d + - "🄾": [t: "⠫⠲⠸⠫⠠⠕⠻"] # 0x1f13e + - "🄿": [t: "⠫⠲⠸⠫⠠⠏⠻"] # 0x1f13f + - "🅀": [t: "⠫⠲⠸⠫⠠⠟⠻"] # 0x1f140 + - "🅁": [t: "⠫⠲⠸⠫⠠⠗⠻"] # 0x1f141 + - "🅂": [t: "⠫⠲⠸⠫⠠⠎⠻"] # 0x1f142 + - "🅃": [t: "⠫⠲⠸⠫⠠⠞⠻"] # 0x1f143 + - "🅄": [t: "⠫⠲⠸⠫⠠⠥⠻"] # 0x1f144 + - "🅅": [t: "⠫⠲⠸⠫⠠⠧⠻"] # 0x1f145 + - "🅆": [t: "⠫⠲⠸⠫⠠⠺⠻"] # 0x1f146 + - "🅇": [t: "⠫⠲⠸⠫⠠⠭⠻"] # 0x1f147 + - "🅈": [t: "⠫⠲⠸⠫⠠⠽⠻"] # 0x1f148 + - "🅉": [t: "⠫⠲⠸⠫⠠⠵⠻"] # 0x1f149 + + # --- Nemeth Default Alphabet sub chars. --- + + - "₀": [t: "⠰⠴"] # 0x2080 + - "₁": [t: "⠰⠂"] # 0x2081 + - "₂": [t: "⠰⠆"] # 0x2082 + - "₃": [t: "⠰⠒"] # 0x2083 + - "₄": [t: "⠰⠲"] # 0x2084 + - "₅": [t: "⠰⠢"] # 0x2085 + - "₆": [t: "⠰⠖"] # 0x2086 + - "₇": [t: "⠰⠶"] # 0x2087 + - "₈": [t: "⠰⠦"] # 0x2088 + - "₉": [t: "⠰⠔"] # 0x2089 + + # --- Nemeth Default Alphabet super chars. --- + + - "⁰": [t: "⠘⠴"] # 0x2070 + - "¹": [t: "⠘⠂"] # 0xb9 + - "²": [t: "⠘⠆"] # 0xb2 + - "³": [t: "⠘⠒"] # 0xb3 + - "⁴": [t: "⠘⠲"] # 0x2074 + - "⁵": [t: "⠘⠢"] # 0x2075 + - "⁶": [t: "⠘⠖"] # 0x2076 + - "⁷": [t: "⠘⠶"] # 0x2077 + - "⁸": [t: "⠘⠦"] # 0x2078 + - "⁹": [t: "⠘⠔"] # 0x2079 + + # --- Nemeth Default Characters latin-lower-phonetic chars. --- + + - "ø": [t: "⠈⠕"] # 0xf8 + + # --- Nemeth Default Characters math_geometry chars. --- + + - "─": [t: "⠱"] # 0x2500 + - "│": [t: "⠳"] # 0x2502 + - "▰": [t: "⠫⠸⠛"] # 0x25b0 + - "▱": [t: "⠫⠛"] # 0x25b1 + - "▽": [t: "⠨⠫"] # 0x25bd + - "◆": [t: "⠫⠸⠙"] # 0x25c6 + - "◇": [t: "⠫⠙"] # 0x25c7 + - "◈": [t: "⠫⠸⠙"] # 0x25c8 + - "◉": [t: "⠫⠸⠉"] # 0x25c9 + - "◊": [t: "⠫⠙"] # 0x25ca + - "⬟": [t: "⠫⠸⠢"] # 0x2b1f + - "⬠": [t: "⠫⠢"] # 0x2b20 + - "⬡": [t: "⠫⠖"] # 0x2b21 + - "⬢": [t: "⠫⠸⠖"] # 0x2b22 + - "⬣": [t: "⠫⠸⠖"] # 0x2b23 + - "⬤": [t: "⠫⠸⠉"] # 0x2b24 + - "⬥": [t: "⠫⠸⠙"] # 0x2b25 + + # --- Nemeth Default Characters math_symbols chars. --- + + - "\"": [t: "⠄⠄"] # 0x22 + - "¡": [t: "⠖"] # 0xa1 + - "¢": [t: "⠈⠉"] # 0xa2 + - "£": [t: "⠈⠇"] # 0xa3 + - "¤": [t: "⠈⠫"] # 0xa4 + - "¥": [t: "⠈⠽"] # 0xa5 + - "§": [t: "⠈⠠⠎"] # 0xa7 + - "©": [t: "⠘⠉"] # 0xa9 (Copyright) + - "ª": [t: "⠸⠰⠁"] # 0xaa + - "«": [t: "⠐⠅⠈⠐⠅⠻"] # 0xab + - "®": [t: "⠘⠗"] # 0xae + - "´": [t: "⠈"] # 0xb4 + - "µ": [t: "⠨⠍"] # 0xb5 + - "¶": [t: "⠈⠠⠏"] # 0xb6 + - "¿": [t: "⠦"] # 0xbf + - "ʹ": [t: "⠄"] # 0x2b9 + - "ʺ": [t: "⠄⠄"] # 0x2ba + - "˙": [t: "⠡"] # 0x2d9 + - "˜": [t: "⠈⠱"] # 0x2dc + - "‐": [t: "⠤"] # 0x2010 + - "‑": [t: "⠤"] # 0x2011 + - "‒": [t: "⠤⠤"] # 0x2012 + - "–": [t: "⠤⠤"] # 0x2013 + - "‖": [t: "⠳⠳"] # 0x2016 + - "†": [t: "⠸⠻"] # 0x2020 + - "‡": [t: "⠸⠸⠻"] # 0x2021 + - "•": [t: "⠡"] # 0x2022 + - "․": [t: "⠄"] # 0x2024 + - "‥": [t: "⠄⠄"] # 0x2025 + - "′": [t: "⠄"] # 0x2032 + - "″": [t: "⠄⠄"] # 0x2033 + - "‴": [t: "⠄⠄."] # 0x2034 (Triple prime) + - "⁗": [t: "⠄⠄.."] # 0x2057 (Quadruple prime) + - "‼": [t: "⠖⠖"] # 0x203c + - "‾": [t: "⠱"] # 0x203e + - "⁇": [t: "⠹⠹"] # 0x2047 + - "⁈": [t: "⠹⠖"] # 0x2048 + - "⁉": [t: "⠖⠹"] # 0x2049 + - "∀": [t: "⠈⠯"] # 0x2200 + - "∃": [t: "⠈⠿"] # 0x2203 + - "∄": [t: "⠌⠈⠿"] # 0x2204 + - "∅": [t: "⠸⠴"] # 0x2205 + - "∈": [t: "⠈⠑"] # 0x2208 + - "∉": [t: "⠌⠈⠑"] # 0x2209 + - "∊": [t: "⠈⠑"] # 0x220a + - "∋": [t: "⠈⠢"] # 0x220b + - "∌": [t: "⠌⠈⠢"] # 0x220c + - "∍": [t: "⠈⠢"] # 0x220d + - "∎": [t: "⠸⠳"] # 0x220e + - "−": [t: "⠤"] # 0x2212 + - "∓": [t: "⠤⠬"] # 0x2213 + - "∕": [t: "⠸⠌"] # 0x2215 + - "∖": [t: "⠸⠡"] # 0x2216 + - "∗": [t: "⠈⠼"] # 0x2217 + - "∘": [t: "⠨⠡"] # 0x2218 + - "∝": [t: "⠸⠿"] # 0x221d + - "∞": [t: "⠠⠿"] # 0x221e + - "∟": [t: "⠫⠪⠨⠗⠻"] # 0x221f + - "∠": [t: "⠫⠪"] # 0x2220 + - "∢": [t: "⠫⠪⠸⠫⠫⠁⠻"] # 0x2222 + - "∣": [t: "⠳"] # 0x2223 + - "∤": [t: "⠌⠳"] # 0x2224 + - "∥": [t: "⠫⠇"] # 0x2225 + - "∦": [t: "⠌⠫⠇"] # 0x2226 + - "∧": [t: "⠈⠩"] # 0x2227 + - "∨": [t: "⠈⠬"] # 0x2228 + - "∩": [t: "⠨⠩"] # 0x2229 + - "∪": [t: "⠨⠬"] # 0x222a + - "∫": [t: "⠮"] # 0x222b + - "∬": [t: "⠮⠮"] # 0x222c + - "∭": [t: "⠮⠮⠮"] # 0x222d + - "∮": [t: "⠮⠈⠫⠉⠻"] # 0x222e + - "∲": [t: "⠮⠈⠫⠪⠢⠔⠻"] # 0x2232 + - "∳": [t: "⠮⠈⠫⠢⠔⠕⠻"] # 0x2233 + - "∴": [t: "⠠⠡"] # 0x2234 + - "∵": [t: "⠈⠌"] # 0x2235 + - "∶": [t: "⠐⠂"] # 0x2236 + - "∷": [t: "⠰⠆"] # 0x2237 + - "∸": [t: "⠨⠤"] # 0x2238 + - "∼": [t: "⠈⠱"] # 0x223c + - "≁": [t: "⠌⠈⠱"] # 0x2241 + - "≂": [t: "⠱⠈⠱"] # 0x2242 + - "≃": [t: "⠈⠱⠱"] # 0x2243 + - "≄": [t: "⠌⠈⠱⠱"] # 0x2244 + - "≅": [t: "⠈⠱⠨⠅"] # 0x2245 + - "≆": [t: "⠈⠱⠌⠨⠅"] # 0x2246 + - "≇": [t: "⠌⠈⠱⠨⠅"] # 0x2247 + - "≈": [t: "⠈⠱⠈⠱"] # 0x2248 + - "≉": [t: "⠌⠈⠱⠈⠱"] # 0x2249 + - "≊": [t: "⠈⠱⠈⠱⠱"] # 0x224a + - "≍": [t: "⠈⠣⠠⠣"] # 0x224d + - "≎": [t: "⠈⠣⠠⠣"] # 0x224e + - "≐": [t: "⠐⠨⠅⠣⠡⠻"] # 0x2250 + - "≑": [t: "⠐⠨⠅⠩⠡⠣⠡⠻"] # 0x2251 + - "≗": [t: "⠐⠨⠅⠣⠨⠡⠻"] # 0x2257 + - "≘": [t: "⠐⠨⠅⠣⠫⠁⠻"] # 0x2258 + - "≙": [t: "⠐⠨⠅⠣⠸⠣⠻"] # 0x2259 + - "≚": [t: "⠐⠨⠅⠣⠸⠩⠻"] # 0x225a + - "≛": [t: "⠐⠨⠅⠣⠫⠸⠎⠻"] # 0x225b + - "≜": [t: "⠐⠨⠅⠣⠫⠞⠻"] # 0x225c + - "≝": [t: "⠐⠨⠅⠣⠙⠑⠋⠻"] # 0x225d + - "≞": [t: "⠐⠨⠅⠣⠍⠻"] # 0x225e + - "≟": [t: "⠐⠨⠅⠣⠸⠦⠻"] # 0x225f + - "≠": [t: "⠌⠨⠅"] # 0x2260 + - "≢": [t: "⠌⠸⠇"] # 0x2262 + - "≤": [t: "⠐⠅⠱"] # 0x2264 + - "≥": [t: "⠨⠂⠱"] # 0x2265 + - "≦": [t: "⠐⠅⠨⠅"] # 0x2266 + - "≧": [t: "⠨⠂⠨⠅"] # 0x2267 + - "≨": [t: "⠐⠅⠌⠨⠅"] # 0x2268 + - "≩": [t: "⠨⠂⠌⠨⠅"] # 0x2269 + - "≪": [t: "⠐⠅⠈⠐⠅⠻"] # 0x226a + - "≫": [t: "⠨⠂⠈⠨⠂⠻"] # 0x226b + - "≭": [t: "⠌⠈⠣⠠⠣"] # 0x226d + - "≮": [t: "⠌⠐⠅"] # 0x226e + - "≯": [t: "⠌⠨⠂"] # 0x226f + - "≰": [t: "⠌⠐⠅⠱"] # 0x2270 + - "≱": [t: "⠌⠨⠂⠱"] # 0x2271 + - "≲": [t: "⠐⠅⠈⠱"] # 0x2272 + - "≳": [t: "⠨⠂⠈⠱"] # 0x2273 + - "≴": [t: "⠌⠐⠅⠈⠱"] # 0x2274 + - "≵": [t: "⠌⠨⠂⠈⠱"] # 0x2275 + - "≶": [t: "⠐⠅⠨⠂"] # 0x2276 + - "≷": [t: "⠨⠂⠐⠅"] # 0x2277 + - "≸": [t: "⠌⠐⠅⠨⠂"] # 0x2278 + - "≹": [t: "⠌⠨⠂⠐⠅"] # 0x2279 + - "≺": [t: "⠨⠐⠅"] # 0x227a + - "≻": [t: "⠨⠨⠂"] # 0x227b + - "≼": [t: "⠨⠐⠅⠱"] # 0x227c + - "≽": [t: "⠨⠨⠐⠱"] # 0x227d + - "≾": [t: "⠨⠐⠅⠈⠱"] # 0x227e + - "≿": [t: "⠨⠨⠂⠈⠱"] # 0x227f + - "⊀": [t: "⠌⠨⠐⠅"] # 0x2280 + - "⊁": [t: "⠌⠨⠐⠅"] # 0x2281 + - "⊂": [t: "⠸⠐⠅"] # 0x2282 + - "⊃": [t: "⠸⠨⠂"] # 0x2283 + - "⊄": [t: "⠌⠸⠐⠅"] # 0x2284 + - "⊅": [t: "⠌⠸⠨⠂"] # 0x2285 + - "⊆": [t: "⠸⠐⠅⠱"] # 0x2286 + - "⊇": [t: "⠸⠨⠂⠱"] # 0x2287 + - "⊈": [t: "⠌⠸⠐⠅⠱"] # 0x2288 + - "⊉": [t: "⠌⠸⠨⠂⠱"] # 0x2289 + - "⊊": [t: "⠸⠐⠅⠌⠨⠅"] # 0x228a + - "⊋": [t: "⠸⠨⠂⠌⠨⠅"] # 0x228b + - "⊥": [t: "⠫⠏"] # 0x22a5 + - "⋀": [t: "⠈⠩"] # 0x22c0 + - "⋁": [t: "⠈⠬"] # 0x22c1 + - "⋂": [t: "⠨⠩"] # 0x22c2 + - "⋃": [t: "⠨⠬"] # 0x22c3 + - "⋄": [t: "⠫⠙"] # 0x22c4 + - "⋜": [t: "⠱⠐⠅"] # 0x22dc + - "⋝": [t: "⠱⠨⠂"] # 0x22dd + - "⟂": [t: "⠫⠏"] # 0x27c2 + - "⦀": [t: "⠳⠳⠳"] # 0x2980 + - "⦶": [t: "⠫⠉⠸⠫⠳⠻"] # 0x29b6 + - "⦷": [t: "⠫⠉⠸⠫⠫⠇⠻"] # 0x29b7 + - "⦸": [t: "⠫⠉⠸⠫⠸⠡⠻"] # 0x29b8 + - "⦹": [t: "⠫⠉⠸⠫⠫⠏⠻"] # 0x29b9 + - "⦿": [t: "⠫⠉⠸⠫⠔⠔⠻"] # 0x29bf + - "⧀": [t: "⠫⠉⠸⠫⠐⠅⠻"] # 0x29c0 + - "⧁": [t: "⠫⠉⠸⠫⠨⠂⠻"] # 0x29c1 + - "⨀": [t: "⠫⠉⠸⠫⠡⠻"] # 0x2a00 + - "⨁": [t: "⠫⠉⠸⠫⠬⠻"] # 0x2a01 + - "⨂": [t: "⠫⠉⠸⠫⠈⠡⠻"] # 0x2a02 + - "⪯": [t: "⠨⠐⠅⠱"] # 0x2aaf + - "⪰": [t: "⠨⠨⠂⠱"] # 0x2ab0 + - "⪱": [t: "⠨⠐⠅⠌⠱"] # 0x2ab1 + - "⪲": [t: "⠨⠨⠂⠌⠱"] # 0x2ab2 + - "⪳": [t: "⠨⠐⠅⠨⠅"] # 0x2ab3 + - "⪴": [t: "⠨⠨⠂⠨⠅"] # 0x2ab4 + - "⪵": [t: "⠨⠐⠅⠌⠨⠅"] # 0x2ab5 + - "⪶": [t: "⠨⠨⠂⠌⠨⠅"] # 0x2ab6 + - "⪷": [t: "⠨⠐⠅⠈⠱⠈⠱"] # 0x2ab7 + - "⪸": [t: "⠨⠨⠂⠈⠱⠈⠱"] # 0x2ab8 + - "⪹": [t: "⠨⠐⠅⠌⠈⠱⠈⠱"] # 0x2ab9 + - "⪺": [t: "⠨⠨⠂⠌⠈⠱⠈⠱"] # 0x2aba + - "⪻": [t: "⠨⠐⠅⠈⠨⠐⠅⠻"] # 0x2abb + - "⪼": [t: "⠨⠨⠂⠈⠨⠨⠂⠻"] # 0x2abc + - "﹩": [t: "⠈⠎"] # 0xfe69 + - "$": [t: "⠈⠎"] # 0xff04 + - "_": [t: "⠱"] # 0xff3f + - "~": [t: "⠈⠱"] # 0xff5e + - "¢": [t: "⠈⠉"] # 0xffe0 + - "£": [t: "⠈⠇"] # 0xffe1 + - " ̄": [t: "⠱"] # 0xffe3 + - "¥": [t: "⠈⠽"] # 0xffe5 + + # --- Nemeth Default Characters rest chars. --- + + - "ℵ": [t: "⠠⠠⠁"] # 0x2135 + - "ℶ": [t: "⠠⠠⠃"] # 0x2136 + - "ℷ": [t: "⠠⠠⠉"] # 0x2137 + - "ℸ": [t: "⠠⠠⠙"] # 0x2138 + - "à": [t: "⠈⠁"] # 0xe0 + - "á": [t: "⠈⠁"] # 0xe1 + - "â": [t: "⠈⠁"] # 0xe2 + - "ã": [t: "⠈⠁"] # 0xe3 + - "ä": [t: "⠈⠁"] # 0xe4 + - "å": [t: "⠈⠁"] # 0xe5 + - "ç": [t: "⠈⠉"] # 0xe7 + - "è": [t: "⠈⠑"] # 0xe8 + - "é": [t: "⠈⠑"] # 0xe9 + - "ê": [t: "⠈⠑"] # 0xea + - "ë": [t: "⠈⠑"] # 0xeb + - "ì": [t: "⠈⠊"] # 0xec + - "í": [t: "⠈⠊"] # 0xed + - "î": [t: "⠈⠊"] # 0xee + - "ï": [t: "⠈⠊"] # 0xef + - "ñ": [t: "⠈⠝"] # 0xf1 + - "ò": [t: "⠈⠕"] # 0xf2 + - "ó": [t: "⠈⠕"] # 0xf3 + - "ô": [t: "⠈⠕"] # 0xf4 + - "õ": [t: "⠈⠕"] # 0xf5 + - "ö": [t: "⠈⠕"] # 0xf6 + - "ù": [t: "⠈⠥"] # 0xf9 + - "ú": [t: "⠈⠥"] # 0xfa + - "û": [t: "⠈⠥"] # 0xfb + - "ü": [t: "⠈⠥"] # 0xfc + - "ý": [t: "⠈⠽"] # 0xfd + - "ÿ": [t: "⠈⠽"] # 0xff + + - "À": [t: "⠠⠈⠁"] # 0xc0 + - "Á": [t: "⠠⠈⠁"] # 0xc1 + - "Â": [t: "⠠⠈⠁"] # 0xc2 + - "Ã": [t: "⠠⠈⠁"] # 0xc3 + - "Ä": [t: "⠠⠈⠁"] # 0xc4 + - "Å": [t: "⠠⠈⠁"] # 0xc5 + - "Ç": [t: "⠠⠈⠉"] # 0xc7 + - "È": [t: "⠠⠈⠑"] # 0xc8 + - "É": [t: "⠠⠈⠑"] # 0xc9 + - "Ê": [t: "⠠⠈⠑"] # 0xca + - "Ë": [t: "⠠⠈⠑"] # 0xcb + - "Ì": [t: "⠠⠈⠊"] # 0xcc + - "Í": [t: "⠠⠈⠊"] # 0xcd + - "Î": [t: "⠠⠈⠊"] # 0xce + - "Ï": [t: "⠠⠈⠊"] # 0xcf + - "Ñ": [t: "⠠⠈⠝"] # 0xd1 + - "Ò": [t: "⠠⠈⠕"] # 0xd2 + - "Ó": [t: "⠠⠈⠕"] # 0xd3 + - "Ô": [t: "⠠⠈⠕"] # 0xd4 + - "Ö": [t: "⠠⠈⠕"] # 0xd6 + - "Ù": [t: "⠠⠈⠥"] # 0xd9 + - "Ú": [t: "⠠⠈⠥"] # 0xda + - "Û": [t: "⠠⠈⠥"] # 0xdb + - "Ü": [t: "⠠⠈⠥"] # 0xdc + - "Ý": [t: "⠠⠈⠽"] # 0xdd + - "←": [t: "⠫⠪⠒⠒"] # 0x2190 + + - "↑": # 0x2191 + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠣"] + else: [t: "⠫⠣⠒⠒⠕"] + + - "↓": # 0x2193 + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠩"] + else: [t: "⠫⠩⠒⠒⠕"] + + - "↔": [t: "⠫⠪⠒⠒⠕"] # 0x2194 + - "↕": [t: "⠫⠣⠩⠪⠒⠒⠕"] # 0x2195 + - "↖": [t: "⠫⠘⠪⠒⠒"] # 0x2196 + - "↗": [t: "⠫⠘⠒⠒⠕"] # 0x2197 + - "↘": [t: "⠫⠰⠒⠒⠕"] # 0x2198 + - "↙": [t: "⠫⠰⠪⠒⠒"] # 0x2199 + - "↚": [t: "⠳⠈⠫⠪⠒⠒⠻"] # 0x219a + - "↛": [t: "⠳⠈⠫⠒⠒⠕⠻"] # 0x219b + - "↜": [t: "⠫⠪⠔⠒⠢"] # 0x219c + - "↝": [t: "⠫⠔⠒⠢⠕"] # 0x219d + - "↞": [t: "⠫⠪⠪⠒⠒"] # 0x219e + - "↟": [t: "⠫⠣⠒⠒⠕⠕"] # 0x219f + - "↠": [t: "⠫⠒⠒⠕⠕"] # 0x21a0 + - "↡": [t: "⠫⠩⠒⠒⠕⠕"] # 0x21a1 + - "↢": [t: "⠫⠪⠒⠒⠠⠽"] # 0x21a2 + - "↣": [t: "⠫⠠⠯⠒⠒⠕"] # 0x21a3 + - "↤": [t: "⠫⠪⠒⠒⠳"] # 0x21a4 + - "↥": [t: "⠫⠣⠳⠒⠒⠕"] # 0x21a5 + - "↦": [t: "⠫⠳⠒⠒⠕"] # 0x21a6 + - "↧": [t: "⠫⠩⠳⠒⠒⠕"] # 0x21a7 + - "↨": [t: "⠫⠪⠒⠳⠒⠕"] # 0x21a8 + - "↩": [t: "⠫⠪⠒⠒⠠⠕"] # 0x21a9 + - "↪": [t: "⠫⠠⠪⠒⠒⠕"] # 0x21aa + - "↫": [t: "⠫⠪⠒⠒⠨⠡"] # 0x21ab + - "↬": [t: "⠫⠨⠡⠒⠒⠕"] # 0x21ac + - "↭": [t: "⠫⠪⠔⠒⠢⠕"] # 0x21ad + - "↮": [t: "⠳⠈⠫⠪⠒⠒⠕"] # 0x21ae + - "↯": [t: "⠫⠩⠔⠢⠔"] # 0x21af + - "↴": [t: "⠫⠠⠳⠒⠒⠕"] # 0x21b4 + - "↵": [t: "⠫⠩⠠⠳⠒⠒⠕"] # 0x21b5 + - "↶": [t: "⠫⠢⠔⠕"] # 0x21b6 + - "↷": [t: "⠫⠪⠢⠔"] # 0x21b7 + - "↺": [t: "⠫⠢⠔⠕"] # 0x21ba + - "↻": [t: "⠫⠪⠢⠔"] # 0x21bb + - "⇄": [t: "⠫⠒⠒⠕⠫⠪⠒⠒"] # 0x21c4 + - "⇅": [t: "⠫⠣⠒⠒⠕⠐⠫⠩⠒⠒⠕"] # 0x21c5 + - "⇆": [t: "⠫⠪⠒⠒⠫⠒⠒⠕"] # 0x21c6 + - "⇇": [t: "⠫⠚⠒⠒⠫⠚⠒⠒"] # 0x21c7 + - "⇈": [t: "⠫⠣⠒⠒⠕⠐⠫⠣⠒⠒⠕"] # 0x21c8 + - "⇉": [t: "⠫⠒⠒⠕⠫⠒⠒⠕"] # 0x21c9 + - "⇊": [t: "⠫⠩⠒⠒⠕⠐⠫⠩⠒⠒⠕"] # 0x21ca + - "⇍": [t: "⠳⠈⠫⠪⠪⠒⠒"] # 0x21cd + - "⇎": [t: "⠳⠈⠫⠪⠪⠒⠒⠕⠕"] # 0x21ce + - "⇏": [t: "⠳⠈⠫⠒⠒⠕⠕"] # 0x21cf + - "⇐": [t: "⠫⠪⠶⠶"] # 0x21d0 + - "⇑": [t: "⠫⠣⠶⠶⠕"] # 0x21d1 + - "⇒": [t: "⠫⠶⠶⠕"] # 0x21d2 + - "⇓": [t: "⠫⠣⠶⠶⠕"] # 0x21d3 + - "⇔": [t: "⠫⠪⠶⠶⠕"] # 0x21d4 + - "⇕": [t: "⠫⠣⠪⠶⠶⠕"] # 0x21d5 + - "⇖": [t: "⠫⠘⠪⠶⠶"] # 0x21d6 + - "⇗": [t: "⠫⠘⠶⠶⠕"] # 0x21d7 + - "⇘": [t: "⠫⠰⠶⠶⠕"] # 0x21d8 + - "⇙": [t: "⠫⠰⠪⠪⠒⠒"] # 0x21d9 + - "⇚": [t: "⠫⠪⠪⠶⠶"] # 0x21da FIX: how to represent triple shafts? + - "⇛": [t: "⠫⠶⠶⠕⠕"] # 0x21db FIX: how to represent triple shafts? + - "⇜": [t: "⠫⠪⠢⠤⠔⠒⠢"] # 0x21dc + - "⇝": [t: "⠫⠢⠤⠔⠒⠢⠕"] # 0x21dd + - "⇞": [t: "⠳⠳⠈⠫⠣⠒⠒⠕⠻"] # 0x21de + - "⇟": [t: "⠳⠳⠈⠫⠩⠒⠒⠕⠻"] # 0x21df + - "⇠": [t: "⠫⠪⠒⠒"] # 0x21e0 + - "⇡": [t: "⠫⠣⠒⠒⠕"] # 0x21e1 + - "⇢": [t: "⠫⠒⠒⠕"] # 0x21e2 + - "⇣": [t: "⠫⠩⠒⠒⠕"] # 0x21e3 + - "⇤": [t: "⠫⠳⠪⠒⠒"] # 0x21e4 + - "⇥": [t: "⠫⠒⠒⠕⠳"] # 0x21e5 + - "⇦": [t: "⠫⠸⠪⠒⠒"] # 0x21e6 + - "⇧": [t: "⠫⠣⠸⠒⠒⠕"] # 0x21e7 + - "⇨": [t: "⠫⠸⠒⠒⠕"] # 0x21e8 + - "⇩": [t: "⠫⠩⠸⠒⠒⠕"] # 0x21e9 + - "⇳": [t: "⠫⠣⠸⠪⠒⠒⠕"] # 0x21f3 + - "⇴": [t: "⠫⠒⠒⠕⠨⠡"] # 0x21f4 + - "⇵": [t: "⠫⠩⠒⠒⠕⠐⠫⠣⠒⠒⠕"] # 0x21f5 + - "⇶": [t: "⠫⠒⠒⠕⠫⠒⠒⠕⠫⠒⠒⠕"] # 0x21f6 + - "⇷": [t: "⠳⠈⠫⠪⠒⠒⠻"] # 0x21f7 + - "⇸": [t: "⠳⠈⠫⠒⠒⠕⠻"] # 0x21f8 + - "⇹": [t: "⠳⠈⠫⠪⠒⠒⠕"] # 0x21f9 + - "⇺": [t: "⠳⠳⠈⠫⠪⠒⠒⠻"] # 0x21fa + - "⇻": [t: "⠳⠳⠈⠫⠒⠒⠕⠻"] # 0x21fb + - "⇼": [t: "⠳⠳⠈⠫⠪⠒⠒⠕"] # 0x21fc + - "⇽": [t: "⠫⠳⠒⠒"] # 0x21fd + - "⇾": [t: "⠫⠒⠒⠳"] # 0x21fe + - "⇿": [t: "⠫⠳⠒⠒⠳"] # 0x21ff + + - "ⅆ": [t: "⠙"] # 0x2146 + - "ⅇ": [t: "⠑"] # 0x2147 + - "ⅈ": [t: "⠊"] # 0x2148 + - "⌜": [t: "⠈⠘⠷"] # 0x231c + - "⌝": [t: "⠈⠘⠾"] # 0x231d + - "⌞": [t: "⠈⠰⠷"] # 0x231e + - "⌟": [t: "⠈⠰⠾"] # 0x231f + - "〈": [t: "⠨⠨⠷"] # 0x2329 + - "〉": [t: "⠨⠨⠾"] # 0x232a + - "⏞": [t: "⠨⠷"] # 0x23de + - "⏟": [t: "⠨⠾"] # 0x23df + - "⎴": [t: "⠈⠷"] # 0x23b4 + - "⎵": [t: "⠈⠾"] # 0x23b5 + - "⟪": [t: "⠨⠨⠨⠷"] # 0x27ea + - "⟫": [t: "⠨⠨⠨⠾"] # 0x27eb + - "〈": [t: "⠨⠨⠷"] # 0x3008 + - "〉": [t: "⠨⠨⠾"] # 0x3009 + - "《": [t: "⠨⠨⠨⠷"] # 0x300a + - "》": [t: "⠨⠨⠨⠾"] # 0x300b + - "「": [t: "⠈⠘⠷"] # 0x300c + - "」": [t: "⠈⠘⠾"] # 0x300d + - "↼": [t: "⠫⠈⠪⠒⠒"] # 0x21bc + - "↽": [t: "⠫⠠⠪⠒⠒"] # 0x21bd + - "↾": [t: "⠫⠣⠒⠒⠠⠕"] # 0x21be + - "↿": [t: "⠫⠣⠒⠒⠈⠕"] # 0x21bf + - "⇀": [t: "⠫⠒⠒⠈⠕"] # 0x21c0 + - "⇁": [t: "⠫⠒⠒⠠⠕"] # 0x21c1 + - "⇂": [t: "⠫⠪⠒⠒⠈⠕"] # 0x21c2 + - "⇃": [t: "⠫⠩⠒⠒⠠⠕"] # 0x21c3 + - "⇋": # 0x21cb + + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠪⠒⠫⠒⠕"] + else: [t: "⠫⠈⠪⠒⠒⠫⠒⠒⠈⠕"] + - "⇌": # 0x21cc + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠕⠫⠪⠒"] + else: [t: "⠫⠒⠒⠈⠕⠫⠈⠪⠒⠒"] + + - "℔": [t: "⠳"] # 0x2114 + - "™": [t: "⠘⠞"] # 0x2122 + - "Å": [t: "⠈⠠⠁"] # 0x212b + - "­": [t: "⠤"] # 0xad + - " -​": [t: "W"] # 0x2000 - 0x200b (various spaces / ZWSP) + - "
": [t: "W"] # 0x2028 + - "
": [t: "W"] # 0x2029 + - " ": [t: "W"] # 0x202f + - " ": [t: "W"] # 0x205f + - "₣": [t: "⠈⠋"] # 0x20A3 (French franc sign + - "₦": [t: "⠈⠝"] # 0x2046 (Naira sign) + - "₩": [t: "⠈⠺"] # 0x20A9 (Won sign) + - "€": [t: "⠈⠑"] # 0x20AC (Euro sign) + - "": [t: "W"] # 0xfeff + - "☆": [t: "⠫⠎"] # 0x2606 + - "✕": [t: "⠈⠡"] # 0x2715 + - "¼": [t: "⠹⠂⠌⠲⠼"] # 0xbc + - "½": [t: "⠹⠂⠌⠆⠼"] # 0xbd + - "¾": [t: "⠹⠒⠌⠲⠼"] # 0xbe + - "⅐": [t: "⠹⠂⠌⠶⠼"] # 0x2150 + - "⅑": [t: "⠹⠂⠌⠔⠼"] # 0x2151 + - "⅒": [t: "⠹⠂⠌⠂⠴⠼"] # 0x2152 + - "⅓": [t: "⠹⠂⠌⠒⠼"] # 0x2153 + - "⅔": [t: "⠹⠆⠌⠒⠼"] # 0x2154 + - "⅕": [t: "⠹⠂⠌⠢⠼"] # 0x2155 + - "⅖": [t: "⠹⠆⠌⠢⠼"] # 0x2156 + - "⅗": [t: "⠹⠒⠌⠢⠼"] # 0x2157 + - "⅘": [t: "⠹⠲⠌⠢⠼"] # 0x2158 + - "⅙": [t: "⠹⠂⠌⠖⠼"] # 0x2159 + - "⅚": [t: "⠹⠢⠌⠖⠼"] # 0x215a + - "⅛": [t: "⠹⠂⠌⠦⠼"] # 0x215b + - "⅜": [t: "⠹⠒⠌⠦⠼"] # 0x215c + - "⅝": [t: "⠹⠢⠌⠦⠼"] # 0x215d + - "⅞": [t: "⠹⠶⠌⠦⠼"] # 0x215e + - "⅟": [t: "⠹⠂⠌⠼"] # 0x215f + - "↉": [t: "⠹⠴⠌⠒⠼"] # 0x2189 + - "㉈": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠂⠴⠻⠻"] # 0x3248 + - "㉉": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠆⠴⠻⠻"] # 0x3249 + - "㉊": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠒⠴⠻⠻"] # 0x324a + - "㉋": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠲⠴⠻⠻"] # 0x324b + - "㉌": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠢⠴⠻⠻"] # 0x324c + - "㉍": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠖⠴⠻⠻"] # 0x324d + - "㉎": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠶⠴⠻⠻"] # 0x324e + - "㉏": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠦⠴⠻⠻"] # 0x324f + + + - "‘": [t: "P⠠⠦"] # 0x2018 (Left single quotation mark) + - "’": [t: "P⠠⠴"] # 0x2019 (Right single quotation mark) + - "“": [t: "P⠦"] # 0x201C (Left double quotation mark) + - "”": [t: "P⠴"] # 0x201D (Right double quotation mark) + - "‰": [t: "`00"] + - "ℏ": [t: "⠈⠓"] # 0x210F (Planck constant over two pi) + - "ℓ": [t: "TE⠇"] # 0x2113 (Script small l (differs from 1d4c1: 4-56-123)) + - "℘": [tc: "TCL⠏"] # 0x2118 (Script Capital P) +# - "ℝ": [t: ""] # 0x211D (Double-struck capital R (no nemeth double struck)) +# - "ⅆ": [t: ""] # 0x2146 (Double-struck italic small d) +# - "ⅇ": [t: ""] # 0x2147 (Double-struck italic small e) +# - "⇚": [t: "⠀⠫⠪⠸⠸⠀"] # 0x21DA (Leftwards triple arrow) +# - "⇛": [t: "⠀⠫⠸⠸⠕⠀"] # 0x21DB (Rightwards triple arrow) + - "∔": [t: "⠐⠬⠣⠡⠻"] # 0x2214 (Dot plus) + - "√": [t: "⠜"] # 0x221A (Square root) + - "∛": [t: "⠣⠒⠜"] # 0x221B (Cube root) + - "∜": [t: "⠣⠲⠜"] # 0x221C (Fourth root) + - "∡": [t: "⠫⠪⠸⠫⠫⠁⠻"] # 0x2221 (Measured angle) + - "∹": [t: "⠤⠐⠂"] # 0x2239 (Excess) + - "∺": [t: "⠐⠤⠩⠡⠡⠣⠡⠡⠻"] # 0x223A (Geometric proportion) + - "∻": [t: "⠐⠈⠱⠩⠡⠣⠡⠻"] # 0x223B (Homothetic) + - "∽": [t: "⠠⠱"] # 0x223D (Reversed tilde) + - "≋": [t: "⠈⠱⠈⠱⠈⠱"] # 0x224B (Triple tilde) + - "≌": [t: "⠠⠱⠨⠅"] # 0x224C (All equal to) + - "≏": [t: "⠈⠣⠱"] # 0x224F (Difference between) + - "≔": [t: "⠐⠂⠨⠅"] # 0x2254 (Colon equals) + - "≕": [t: "⠨⠅⠐⠂"] # 0x2255 (Equals colon) + - "≖": [t: "⠀⠨⠡⠈⠨⠅⠻⠀"] # 0x2256 (Ring in equal to) + - "⊌": [t: "⠨⠬⠈⠫⠪⠒⠻"] # 0x228C (Multiset) + - "⊍": [t: "⠡⠈⠨⠬⠻"] # 0x228D (Multiset multiplication) + - "⊎": [t: "⠬⠈⠨⠬⠻"] # 0x228E (Multiset union) + - "⊕": [t: "⠫⠉⠸⠫⠬⠻"] # 0x2295 (Circled plus) + - "⊖": [t: "⠫⠉⠸⠫⠤⠻"] # 0x2296 (Circled minus) + - "⊗": [t: "⠫⠉⠸⠫⠈⠡⠻"] # 0x2297 (Circled times) + - "⊘": [t: "⠫⠉⠸⠫⠸⠌⠻"] # 0x2298 (Circled division slash) + - "⊙": [t: "⠫⠉⠸⠫⠡⠻"] # 0x2299 (Circled dot operator) + - "⊚": [t: "⠫⠉⠸⠫⠘⠨⠡⠻"] # 0x229a (Circled ring operator) + - "⊛": [t: "⠫⠉⠸⠫⠈⠼⠻"] # 0x229B (Circled asterisk operator) + - "⊜": [t: "⠫⠉⠸⠫⠨⠅⠻"] # 0x229C (Circled equals) + - "⊝": [t: "⠫⠉⠸⠫⠤⠤⠻"] # 0x229D (Circled dash) + - "⊞": [t: "⠫⠲⠸⠫⠬⠻"] # 0x229E (Squared plus) + - "⊟": [t: "⠫⠲⠸⠫⠤⠻"] # 0x229F (Squared minus) + - "⊠": [t: "⠫⠲⠸⠫⠈⠡⠻"] # 0x22A0 (Squared times) + - "⊡": [t: "⠫⠲⠸⠫⠡⠻"] # 0x22A1 (Squared dot operator) + - "⊢": [t: "⠫⠳⠒"] # 0x22A2 (Right tack) + - "⊣": [t: "⠫⠒⠳"] # 0x22A3 (Left tack) + - "⊤": [t: "⠫⠩⠳⠒"] # 0x22A4 (Down tack) +# - "⊥": [t: "⠀⠫⠏⠀ or ⠀⠫⠣⠳⠒⠀"] # 0x22A5 (Up tack (See also 27C2)) +# - "⊦": [t: ""] # 0x22A6 (Assertion) +# - "⊨": [t: ""] # 0x22A8 (TRUE) +# - "⊲": [t: ""] # 0x22B2 (Normal subgroup of) +# - "⊳": [t: ""] # 0x22B3 (Contains as normal subgroup) +# - "⊴": [t: ""] # 0x22B4 (Normal subgroup of or equal to) +# - "⊵": [t: ""] # 0x22B5 (Contains as normal subgroup or equal to) + - "⊶": [t: "⠫⠨⠡⠒⠡"] # 0x22B6 (Original of) + - "⊷": [t: "⠫⠡⠒⠨⠡"] # 0x22B7 (Image of) + - "⊸": [t: "⠫⠒⠨⠡"] # 0x22B8 (Multimap) +# - "⊾": [t: ""] # 0x22BE (Right angle w arc) + - "⊿": [t: "⠫⠞⠨⠗⠻"] # 0x22BF (Right triangle) + - "⋅": [t: "⠡"] # 0x22C5 (Dot operator) + - "∙": [t: "⠡"] # 0x2219 -- similar looking to 0x22c5, so using the same braille + - "⋆": [t: "⠫⠎"] # 0x22C6 (Star operator) + - "⋍": [t: "⠠⠱⠱"] # 0x22CD (Reversed tilde equals) + - "⋖": [t: "⠡⠈⠐⠅⠻"] # 0x22D6 (Less-than w dot) + - "⋗": [t: "⠡⠈⠨⠂⠻"] # 0x22D7 (Greater-than w dot) + - "⋘": [t: "⠐⠅⠈⠐⠅⠈⠐⠅⠻"] # 0x22D8 (Much less-than) + - "⋙": [t: "⠨⠂⠈⠨⠂⠈⠨⠂⠻"] # 0x22D9 (Much greater-than) + - "⋲": [t: "⠱⠈⠈⠑⠻"] # 0x22F2 (Element of w long horizontal stroke) + - "⋵": [t: "⠐⠈⠑⠣⠡⠻"] # 0x22F5 (Element of w dot above) + - "⋶": [t: "⠱⠈⠑"] # 0x22F6 (Element of w overbar) + - "⋺": [t: "⠱⠈⠈⠢⠻"] # 0x22FA (Contains w long horizontal stroke) + - "⋽": [t: "⠱⠈⠢"] # 0x22FD (Contains w overbar) + - "⌈": [t: "⠈⠘⠷"] # 0x2308 (Left ceiling) + - "⌉": [t: "⠈⠘⠾"] # 0x2309 (Right ceiling) + - "⌊": [t: "⠈⠰⠷"] # 0x230A (Left floor) + - "⌋": [t: "⠈⠰⠾"] # 0x230B (Right floor) + - "⌢": [t: "⠫⠁"] # 0x2322 (Frown) + - "⌣": [t: "⠫⠄"] # 0x2323 (Smile) + - "■": [t: "⠫⠸⠲"] # 0x25A0 (Filled square) + - "▫": [t: "⠫⠲"] # 0x25AB (Small white Square) + - "□": [t: "⠫⠲"] # 0x25A1 (Square) + - "◻": [t: "⠫⠲"] # 0x25FB (Square) + - "▬": [t: "⠫⠸⠗"] # 0x25AC (Filled rectangle) + - "▭": [t: "⠫⠗"] # 0x25AD (Rectangle) + - "▲": [t: "⠫⠸⠞"] # 0x25B2 (Black up-pointing triangle) + - "△": [t: "⠫⠞"] # 0x25B3 (White up-pointing triangle) + - "▼": [t: "⠸⠨⠫"] # 0x25BC (Black down-pointing triangle) + - "○": [t: "⠫⠉"] # 0x25CB (White circle) + - "●": [t: "⠫⠸⠉"] # 0x25CF (Black circle) + - "◫": [t: "⠫⠲⠸⠫⠳⠻"] # 0x25EB (White square w vertical bisecting line) +# - "⊥": [t: "⠫⠏"] # 0x27C2 (Perpendicular) + - "⟃": [t: "⠨⠡⠈⠸⠐⠅⠻"] # 0x27C3 (Open subset) + - "⟄": [t: "⠨⠡⠈⠸⠨⠂⠻"] # 0x27C4 (Open superset) + - "⟜": [t: "⠫⠨⠡⠒⠒"] # 0x27DC (Left multimap) + - "⟝": [t: "⠫⠳⠒⠒"] # 0x27DD (Long right tack) + - "⟞": [t: "⠫⠒⠒⠳"] # 0x27DE (Long left tack) + - "⟟": [t: "⠫⠣⠳⠒⠒⠨⠡"] # 0x27DF (Up tack w circle above) + - "⟦": [t: "⠈⠸⠷"] # 0x27E6 (Mathematical left white square bracket) + - "⟧": [t: "⠈⠸⠾"] # 0x27E7 (Mathematical right white square bracket) + - "⟨": [t: "⠨⠨⠷"] # 0x27E8 (Mathematical left angle bracket) + - "⟩": [t: "⠨⠨⠾"] # 0x27E9 (Mathematical right angle bracket) + - "⟵": [t: "⠀⠫⠪⠒⠒⠒⠀"] # 0x27F5 (Long leftwards arrow ) + - "⟶": [t: "⠀⠫⠒⠒⠒⠕⠀"] # 0x27F6 (Long rightwards arrow) + - "⟷": [t: "⠀⠫⠪⠒⠒⠒⠕⠀"] # 0x27F7 (Long left right arrow) + - "⟸": [t: "⠀⠫⠪⠶⠶⠶⠀"] # 0x27F8 (Long leftwards arrow ) + - "⟹": [t: "⠀⠫⠶⠶⠶⠕⠀"] # 0x27F9 (Long rightwards arrow) + - "⟺": [t: "⠀⠫⠪⠶⠶⠶⠕⠀"] # 0x27FA (Long left right arrow) + - "⟻": [t: "⠀⠫⠪⠒⠒⠒⠳⠀"] # 0x27FB (Long leftwards arrow from bar) + - "⟼": [t: "⠀⠫⠳⠒⠒⠒⠕⠀"] # 0x27FC (Long rightwards arrow from bar) + - "⟽": [t: "⠀⠫⠪⠶⠶⠶⠳⠀"] # 0x27FD (Long leftwards double arrow from bar) + - "⟾": [t: "⠀⠫⠳⠶⠶⠶⠕⠀"] # 0x27FE (Long rightwards double arrow from bar) + - "⟿": [t: "⠀⠫⠢⠤⠔⠒⠢⠤⠔⠒⠢⠕⠀"] # 0x27FF (Long rightwards squiggle arrow) + - "⤡": [t: "⠀⠫⠘⠪⠒⠒⠕⠀"] # 0x2921 (North west and south east arrow) + - "⤢": [t: "⠀⠫⠰⠪⠒⠒⠕⠀"] # 0x2922 (North east and south west arrow) + - "🣐": # 0x1f8d0 (Long rightwards arrow over leftwards arrow (equilibrium)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠕⠫⠪⠒"] + else: [t: "⠫⠒⠒⠈⠕⠫⠠⠪⠒⠒"] + - "🣑": # 0x1f8d1 (Long rightwards harpoon over leftwards harpoon (equilibrium)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠕⠫⠪⠒"] + else: [t: "⠫⠒⠒⠈⠕⠫⠠⠪⠒⠒"] + - "🣒": # 0x1f8d2 (Long rightwards harpoon over short leftwards harpoon (equilibrium)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠒⠕⠫⠪⠒"] + else: [t: "⠫⠒⠒⠈⠕⠫⠈⠪⠒⠒"] + - "🣓": # 0x1f8d3 (Short rightwards harpoon over long leftwards harpoon (equilibrium, trend to the right)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠕⠫⠪⠒⠒"] + else: [t: "⠫⠒⠈⠕⠫⠠⠪⠒⠒"] + - "🣔": # 0x1f8d4 (Long leftwards harpoon over short rightwards harpoon (equilibrium, trend to the left)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠪⠒⠒⠫⠒⠕"] + else: [t: "⠫⠈⠪⠒⠒⠫⠒⠠⠕"] + - "🣕": # 0x1f8d5 (Short leftwards harpoon over long rightwards harpoon (equilibrium, trend to the left)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠪⠒⠫⠒⠒⠕"] + else: [t: "⠫⠈⠪⠒⠫⠒⠒⠠⠕"] + - "⥂": # 0x2942 (Long rightwards harpoon over short leftwards harpoon (equilibrium)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠒⠕⠫⠪⠒"] + else: [t: "⠫⠒⠒⠈⠕⠫⠈⠪⠒⠒"] + - "⥄": # 0x2944 (Short rightwards harpoon over long leftwards harpoon (equilibrium, trend to the right)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠕⠫⠪⠒⠒"] + else: [t: "⠫⠒⠈⠕⠫⠠⠪⠒⠒"] + - "⥃": # 0x2943 (Long leftwards harpoon over short rightwards harpoon (equilibrium, trend to the left)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠪⠒⠒⠫⠒⠕"] + else: [t: "⠫⠈⠪⠒⠒⠫⠒⠠⠕"] + - "🣖": [t: "⠌⠫⠒⠒⠕"] # 0x1f8d6 (long rightwards arrow with through X) + - "🣗": [t: "⠌⠫⠒⠒⠕"] # 0x1f8d7 (long rightwards arrow with double slash) chem code says it is same as 0x1f8d6 + + + - "⦃": [t: "⠨⠸⠷"] # 0x2983 (Left white curly bracket) + - "⦄": [t: "⠨⠸⠾"] # 0x2984 (Right white curly bracket) + - "⦑": [t: "⠡⠈⠨⠨⠷⠻"] # 0x2991 (Left angle bracket w dot) + - "⦒": [t: "⠡⠈⠨⠨⠾⠻"] # 0x2992 (Right angle bracket w dot) + - "⧄": [t: "⠫⠲⠸⠫⠔⠻"] # 0x29C4 (Square rising diagonal slash) + - "⧅": [t: "⠫⠲⠸⠫⠢⠻"] # 0x29C5 (Square falling diagonal slash) + - "⧆": [t: "⠫⠲⠸⠫⠈⠼⠻"] # 0x29C6 (Squared asterisk) + - "⧊": [t: "⠐⠫⠞⠣⠡⠻"] # 0x29CA (Triangle w dot above) + - "⧋": [t: "⠫⠞⠱"] # 0x29CB (Triangle w underbar) + - "⧌": [t: "⠫⠞⠎"] # 0x29CC (s in triangle §114) + - "⧦": [t: "⠫⠳⠶⠶⠳"] # 0x29E6 (Gleich stark) + - "⨌": [t: "⠮⠮⠮⠮"] # 0x2A0C (Quadruple integral operator) + - "⨍": [t: "⠮⠈⠱⠻"] # 0x2A0D (Finite part integral) + - "⨎": [t: "⠮⠈⠱⠱⠻"] # 0x2A0E (Integral w double stroke) + - "⨖": [t: "⠮⠈⠫⠲⠻"] # 0x2A16 (Quaternion integral operator) + - "⨘": [t: "⠮⠈⠈⠡⠻"] # 0x2A18 (Integral w times sign) + - "⨙": [t: "⠮⠈⠨⠩⠻"] # 0x2A19 (Integral w intersection) + - "⨚": [t: "⠮⠈⠨⠬⠻"] # 0x2A1A (Integral w union) + - "⨛": [t: "⠣⠮"] # 0x2A1B (Integral w overbar (upper)) + - "⨜": [t: "⠩⠮"] # 0x2A1C (Integral w underbar (lower)) + - "⨢": [t: "⠐⠬⠣⠨⠡⠻"] # 0x2A22 (Plus sign w small circle above) + - "⨣": [t: "⠐⠬⠣⠸⠣⠻"] # 0x2A23 (Plus sign w circumflex accent above) + - "⨤": [t: "⠐⠬⠣⠈⠱⠻"] # 0x2A24 (Plus sign w tilde above) + - "⨥": [t: "⠐⠬⠩⠡⠻"] # 0x2A25 (Plus sign w dot below) + - "⨪": [t: "⠐⠱⠩⠡⠻"] # 0x2A2A (Minus sign w dot below) + - "⨰": [t: "⠐⠈⠡⠣⠡⠻"] # 0x2A30 (Multiplication sign w dot above) + - "⨱": [t: "⠈⠡⠱"] # 0x2A31 (Multiplication sign w underbar) + - "⨸": [t: "⠫⠉⠸⠫⠨⠌⠻"] # 0x2A38 (Circled division sign) + - "⨹": [t: "⠫⠞⠸⠫⠬⠻"] # 0x2A39 (Plus sign in triangle) + - "⨺": [t: "⠫⠞⠸⠫⠤⠻"] # 0x2A3A (Minus sign in triangle) + - "⨻": [t: "⠫⠞⠸⠫⠈⠡⠻"] # 0x2A3B (Multiplication sign in triangle) + - "⩀": [t: "⠡⠈⠨⠩⠻"] # 0x2A40 (Intersection w dot) + - "⩁": [t: "⠤⠈⠨⠬⠻"] # 0x2A41 (Union w minus sign) + - "⩂": [t: "⠱⠨⠬"] # 0x2A42 (Union w overbar) + - "⩃": [t: "⠱⠨⠩"] # 0x2A43 (Intersection w overbar) + - "⩑": [t: "⠐⠈⠩⠣⠡⠻"] # 0x2A51 (Logical AND w dot above) + - "⩒": [t: "⠐⠈⠬⠣⠡⠻"] # 0x2A52 (Logical OR w dot above) + - "⩜": [t: "⠱⠈⠈⠩⠻"] # 0x2A5C (Logical AND with horizontal dash) + - "⩝": [t: "⠱⠈⠈⠬⠻"] # 0x2A5D (Logical OR with horizontal dash) + - "⩞": [t: "⠱⠱⠈⠩"] # 0x2A5E (Logical AND w double overbar) + - "⩟": [t: "⠈⠩⠱"] # 0x2A5F (Logical AND w underbar) + - "⩠": [t: "⠈⠩⠱⠱"] # 0x2A60 (Logical AND w double underbar) + - "⩢": [t: "⠱⠱⠈⠬"] # 0x2A62 (Logical OR w double overbar) + - "⩣": [t: "⠈⠬⠱⠱"] # 0x2A63 (Logical OR w double underbar) + - "⩦": [t: "⠐⠨⠅⠩⠡⠻"] # 0x2A66 (Equals sign w dot below) + - "⩧": [t: "⠐⠸⠇⠣⠡⠻"] # 0x2A67 (Identical w dot above) + - "⩪": [t: "⠐⠈⠱⠣⠡⠻"] # 0x2A6A (Tilde operator w dot above) + - "⩬": [t: "⠈⠱⠱⠈⠱"] # 0x2A6C (Similar minus similar) + - "⩭": [t: "⠐⠈⠱⠨⠅⠣⠡⠻"] # 0x2A6D (Congruent w dot above) + - "⩮": [t: "⠐⠨⠅⠣⠈⠼⠻"] # 0x2A6E (Equals w asterisk) + - "⩯": [t: "⠐⠈⠱⠈⠱⠣⠸⠣⠻"] # 0x2A6F (Almost equal to w circumflex) + - "⩰": [t: "⠈⠱⠈⠱⠨⠅"] # 0x2A70 (Approximately equal or equal to) + - "⩱": [t: "⠨⠅⠬"] # 0x2A71 (Equals sign above plus sign) + - "⩲": [t: "⠬⠨⠅"] # 0x2A72 (Plus sign above equals sign) + - "⩳": [t: "⠨⠅⠈⠱"] # 0x2A73 (Equals sign above tilde operator) + - "⩴": [t: "⠐⠂⠐⠂⠨⠅"] # 0x2A74 (Double colon equal) + - "⩵": [t: "⠨⠅⠨⠅"] # 0x2A75 (Two consecutive equals signs) + - "⩶": [t: "⠨⠅⠨⠅⠨⠅"] # 0x2A76 (Three consecutive equals signs) + - "⩷": [t: "⠐⠨⠅⠩⠡⠡⠣⠡⠡⠻"] # 0x2A77 (Equals sign w two dots above and two dots below) + - "⩸": [t: "⠐⠸⠇⠣⠡⠡⠡⠡⠻"] # 0x2A78 (Equivalent w four dots above) + - "⩹": [t: "⠐⠅⠈⠨⠡⠻"] # 0x2A79 (Less than w circle inside) + - "⩺": [t: "⠨⠂⠈⠨⠡⠻"] # 0x2A7A (Greater than w circle inside) + - "⩻": [t: "⠐⠐⠅⠣⠸⠦⠻"] # 0x2A7B (Less-than w question mark above) + - "⩼": [t: "⠐⠨⠂⠣⠸⠦⠻"] # 0x2A7C (Greater-than w question mark above) + - "⪅": [t: "⠐⠅⠈⠱⠈⠱"] # 0x2A85 (Less-than or approximate) + - "⪆": [t: "⠨⠂⠈⠱⠈⠱"] # 0x2A86 (Greater-than or approximate) + - "⪋": [t: "⠐⠅⠨⠅⠨⠂"] # 0x2A8B (Less-than above double-line equal above greater-than) + - "⪌": [t: "⠨⠂⠨⠅⠐⠅"] # 0x2A8C (Greater-than above double-line equal above less-than) + - "⪍": [t: "⠐⠅⠈⠱⠱"] # 0x2A8D (Less-than above similar or equal to) + - "⪎": [t: "⠨⠂⠈⠱⠱"] # 0x2A8E (Greater-than above similar or equal to) + - "⪏": [t: "⠐⠅⠈⠱⠨⠂"] # 0x2A8F (Less-than above similar above greater-than) + - "⪐": [t: "⠨⠂⠈⠱⠐⠅"] # 0x2A90 (Greater-than above similar above less-than) + - "⪑": [t: "⠐⠅⠨⠂⠨⠅"] # 0x2A91 (Less-than above greater-than above double-line equal) + - "⪒": [t: "⠨⠂⠐⠅⠨⠅"] # 0x2A92 (Greater-than above less-than above double-line equal) + - "⪙": [t: "⠨⠅⠐⠅"] # 0x2A99 (Double-line equal to or less-than) + - "⪚": [t: "⠨⠅⠨⠂"] # 0x2A9A (Double-line equal to or greater-than) + - "⪝": [t: "⠈⠱⠐⠅"] # 0x2A9D (Similar or less-than) + - "⪞": [t: "⠈⠱⠨⠂"] # 0x2A9E (Similar or greater-than) + - "⪟": [t: "⠈⠱⠐⠅⠨⠅"] # 0x2A9F (Similar above less-than above equals sign) + - "⪠": [t: "⠈⠱⠨⠂⠨⠅"] # 0x2AA0 (Similar above greater-than above equals sign) + - "⪮": [t: "⠈⠣⠨⠅"] # 0x2AAE (Equals sign with bumpy above) + - "⪽": [t: "⠡⠈⠸⠐⠅⠻"] # 0x2ABD (Subset w dot) + - "⪾": [t: "⠡⠈⠸⠨⠂⠻"] # 0x2ABE (Superset w dot) + - "⪿": [t: "⠐⠸⠐⠅⠩⠬⠻"] # 0x2ABF (Subset with plus sign below) + - "⫀": [t: "⠐⠸⠨⠂⠩⠬⠻"] # 0x2AC0 (Superset with plus sign below) + - "⫁": [t: "⠐⠸⠐⠅⠩⠈⠡⠻"] # 0x2AC1 (Subset with multiplication sign below) + - "⫂": [t: "⠐⠸⠨⠂⠩⠈⠡⠻"] # 0x2AC2 (Superset with multiplication sign below) + - "⫅": [t: "⠸⠐⠅⠨⠅"] # 0x2AC5 (Subset of above equals sign) + - "⫆": [t: "⠸⠨⠂⠨⠅"] # 0x2AC6 (Superset of above equals sign) + - "⫇": [t: "⠸⠐⠅⠈⠱"] # 0x2AC7 (Subset of above tilde operator) + - "⫈": [t: "⠸⠨⠂⠈⠱"] # 0x2AC8 (Superset of above tilde operator) + - "⫉": [t: "⠸⠐⠅⠈⠱⠈⠱"] # 0x2AC9 (Subset of above almost equal to) + - "⫊": [t: "⠸⠨⠂⠈⠱⠈⠱"] # 0x2ACA (Superset of above almost equal to) + - "⫋": [t: "⠸⠐⠅⠌⠨⠅"] # 0x2ACB (Subset of above not equals sign) + - "⫌": [t: "⠸⠨⠂⠌⠨⠅"] # 0x2ACC (Superset of above not equals sign) + - "⫓": [t: "⠸⠐⠅⠸⠨⠂"] # 0x2AD3 (Subset above superset) + - "⫔": [t: "⠸⠨⠂⠸⠐⠅"] # 0x2AD4 (Superset above subset) + - "⫕": [t: "⠸⠐⠅⠸⠐⠅"] # 0x2AD5 (Subset above subset) + - "⫖": [t: "⠸⠨⠂⠸⠨⠂"] # 0x2AD6 (Superset above superset) + - "⫗": [t: "⠸⠨⠂⠐⠸⠐⠅"] # 0x2AD7 (Superset beside subset) + - "⫯": [t: "⠫⠩⠨⠡⠒⠒"] # 0x2AEF (Vertical line w circle above) + - "⫰": [t: "⠫⠣⠨⠡⠒⠒"] # 0x2AF0 (Vertical line w circle below) + - "⫱": [t: "⠫⠣⠨⠡⠒⠒⠳"] # 0x2AF1 (Down tack w circle below) + - "⫲": [t: "⠱⠈⠫⠇⠻"] # 0x2AF2 (Parallel w horizontal stroke) + - "⫳": [t: "⠈⠱⠈⠫⠇⠻"] # 0x2AF3 (Parallel w tilde operator) + - "⫴": [t: "⠳⠳⠳"] # 0x2AF4 (Triple vertical bar binary relation) + - "⬬": [t: "⠫⠸⠑"] # 0x2B2C (Black ellipse) + - "⬭": [t: "⠫⠑"] # 0x2B2D (White ellipse) + - "⬰": [t: "⠨⠡⠈⠫⠪⠒⠒⠻"] # 0x2B30 (Left arrow w small circle) + - "⬱": [t: "⠫⠪⠒⠒⠫⠪⠒⠒⠫⠪⠒⠒"] # 0x2B31 (Three leftwards arrows) + - "⬲": [t: "⠫⠪⠒⠒⠈⠫⠉⠸⠫⠬⠻"] # 0x2B32 (Left arrow w circled plus) + - "⮖": [t: "⠨⠡"] # 0x2B96 (Standard State Symbol) + - "⯃": [t: "⠫⠸⠦"] # 0x2BC3 (Horizontal black octagon) + + # SRE lists this as a custom transcription + - "⋊": [t: "⠈⠡⠳"] # 0x22ca (RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT) diff --git a/Rules/Braille/UEB/UEB_Rules.yaml b/Rules/Braille/UEB/UEB_Rules.yaml index 912e03d8a..c161530dd 100644 --- a/Rules/Braille/UEB/UEB_Rules.yaml +++ b/Rules/Braille/UEB/UEB_Rules.yaml @@ -8,7 +8,7 @@ variables: [MatchingWhitespace: "true()"] replace: - test: - - if: "(@class='MathML-unit' or BaseNode(.)[@class='MathML-unit']) and @data-previous-space-width >= 0.25" # BANA 5.3(a) + - if: "(@class='MathML-unit' or contains(@data-intent-property, ':unit:') or BaseNode(.)[@class='MathML-unit' or contains(@data-intent-property, ':unit:')]) and @data-previous-space-width >= 0.25" # treat spaced units as separate exprs for G1 placement then: [t: "𝐖"] - else_if: "@data-previous-space-width > 1.1" then: [t: "⠬"] @@ -16,7 +16,7 @@ then: [t: "W"] - x: "." - test: - - if: "(@class='MathML-unit' or BaseNode(.)[@class='MathML-unit']) and @data-following-space-width >= 0.25" # BANA 5.3(a) + - if: "(@class='MathML-unit' or contains(@data-intent-property, ':unit:') or BaseNode(.)[@class='MathML-unit' or contains(@data-intent-property, ':unit:')]) and @data-following-space-width >= 0.25" # treat spaced units as separate exprs for G1 placement then: [t: "𝐖"] - else_if: "@data-following-space-width > 1.1" then: [t: "⠬"] @@ -107,7 +107,7 @@ replace: - t: "1⠷" - x: "*[1]" - - t: "1⠨⠌" + - t: "⠨⠌" - x: "*[2]" - t: "1⠾" @@ -256,9 +256,10 @@ tag: mo # add spaces around comparison operators unless they are in a script position, variables: # ratio not spaced in UEB; also make sure it is an infix operator (e.g., "~" can be prefix) + # ∴ / ∵ / ∎ are spaced like comparison signs (GTM 1.7.9 "∴ force = …"; GTM 11) - AddSpaces: "$UseSpacesAroundAllOperators or ( parent::*[self::m:mrow] and $NewScriptContext='' and - .!='∶' and IsInDefinition(., 'Braille', 'NemethComparisonOperators') )" + .!='∶' and (IsInDefinition(., 'Braille', 'NemethComparisonOperators') or .='∴' or .='∵' or .='∎') )" match: "." replace: - test: diff --git a/Rules/prefs.yaml b/Rules/prefs.yaml index 8a324721e..6c36c4020 100644 --- a/Rules/prefs.yaml +++ b/Rules/prefs.yaml @@ -61,6 +61,7 @@ UEB: StartMode: "Grade2" # Grade1/Grade2 -- assumed starting mode UEB braille (Grade1 assumes we are in G1 passage mode) + # Grade 1 indicators follow ICEB GTM 1.7 (also BANA 2026 math/science guidance) # UEB Guide to Technical Material (https://iceb.org/Guidelines_for_Technical_Material_2008-10.pdf) # says to normally treat Fraktur and DoubleStruck as Script diff --git a/docs/users.md b/docs/users.md index 6328e522f..a5ab487d3 100644 --- a/docs/users.md +++ b/docs/users.md @@ -10,8 +10,6 @@ MathCAT is a tool used together with a screen reader. Through MathCAT, you can h In screen readers NVDA and JAWS, MathCAT comes built-in. This means you don’t have to install it as an addon. -MathCAT is still available as an addon to NVDA. You can use it if you want access to the very latest features between NVDA releases. [How to use MathCAT as an addon is described here](#how-to-install-mathcat-as-an-addon-in-nvda). - ## Get started with MathCAT Use your screen reader on a web page or in an e-book as usual. When you get to a mathematical expression, the screen reader will read it out automatically. If you want to investigate the expression more closely you can activate the navigation mode by pressing Space. In NVDA, the NVDA-key+Alt+M can also be used. If you want to leave the navigation mode, press Escape. @@ -139,42 +137,4 @@ Note: tabular math means mathematical content in a table structure such as a mat ## Do you have feedback on MathCAT? -MathCAT is under active development, and we want your feedback. Do you have a feature request, or have you found any bugs? Please create an issue on [MathCAT's GitHub page](https://github.com/daisy/MathCAT/issues). You are also welcome to get in touch by signing up to [the mailing list of the DAISY MathCAT working group](https://www.surveymonkey.com/r/HXTLXGN). - -## How to install MathCAT as an addon in NVDA - -To use MathCAT as an add-on, do the following: - -1. Open the NVDA menu. -2. Choose Tools and then Add-on store. -3. In the add-on store, choose Available add-ons. - - The channel settings have the following options: - - Stable: Will only search for stable add-ons - - All: Will search for all add-ons - - Beta: Will search for add-ons that are in beta - - Dev: Will search for add-ons in development - - Choose option "All". - -4. Search for MathCAT and install. - -5. In the settings menu, you can control how add-ons are updated: - - - Open the NVDA menu - - Choose settings and Add-on Store - - For Automatic updates, you can choose between: - - Notify - - Update Automatically - - Deactivated - - For Default update channel, you have the following options: - - - Same: If automatic updates is set to “Update Automatically” and your add-on is a beta, it will update to the first available beta. - - Any: It will update to any version of the add-on. - - Do not update - - Stable: It will only update to stable versions. - - Beta or dev: It will update to beta or dev versions. - - Beta: It will update to beta versions. - - Dev: It will update to dev versions. \ No newline at end of file +MathCAT is under active development, and we want your feedback. Do you have a feature request, or have you found any bugs? Please create an issue on [MathCAT's GitHub page](https://github.com/daisy/MathCAT/issues). You are also welcome to get in touch by signing up to [the mailing list of the DAISY MathCAT working group](https://www.surveymonkey.com/r/HXTLXGN). \ No newline at end of file diff --git a/src/braille.rs b/src/braille.rs index 1966f09c0..4f0ac0ec7 100644 --- a/src/braille.rs +++ b/src/braille.rs @@ -15,6 +15,7 @@ use crate::canonicalize::get_parent; use std::borrow::Cow; use std::ops::Range; use std::sync::LazyLock; +#[allow(unused_imports)] use log::{debug, error}; fn is_ueb_prefix(ch: char) -> bool { @@ -1047,11 +1048,9 @@ fn ueb_cleanup(pref_manager: Ref, raw_braille: String) -> Str let use_only_grade1 = pref_manager.pref_to_string("UEB_START_MODE").as_str() == "Grade1"; - // '𝐖' is a hard break -- basically, it separates exprs - let mut result = result.split('𝐖') - .map(|str| pick_start_mode(str, use_only_grade1) + "W") - .collect::(); - result.pop(); // we added a 'W' at the end that needs to be removed. + // 𝐖 is a unit hard-break. For GTM 1.7 it is still a symbols-sequence boundary (same as W), + // so G1 passage decisions (1.7.3(b) / 1.7.5(c)) see the whole expression. + let result = pick_start_mode(&result, use_only_grade1); let result = result.replace("tW", "W"); @@ -1067,42 +1066,42 @@ fn ueb_cleanup(pref_manager: Ref, raw_braille: String) -> Str return result.to_string(); fn pick_start_mode(raw_braille: &str, use_only_grade1: bool) -> String { - // Need to decide what the start mode should be - // From http://www.brailleauthority.org/ueb/ueb_math_guidance/final_for_posting_ueb_math_guidance_may_2019_102419.pdf - // Unless a math expression can be correctly represented with only a grade 1 symbol indicator in the first three cells - // or before a single letter standing alone anywhere in the expression, - // begin the expression with a grade 1 word indicator (or a passage indicator if the expression includes spaces) - // Apparently "only a grade 1 symbol..." means at most one grade 1 symbol based on some examples (GTM 6.4, example 4) + // Decide grade 1 indicator placement per ICEB GTM 1.7 (2025). + // BANA's 2026 guidance adopts the same GTM §1.7 rules: + // https://www.brailleauthority.org/sites/default/files/2026-07/Guidance%20on%20Transcribing%20Math%20and%20Science%20in%20UEB%202026.pdf + // GTM 1.7.3 decides indicators per *symbols-sequence* (RUEB 2.1 -- text separated by spaces): + // (a) allow one grade 1 symbol per symbols-sequence, or a grade 1 word indicator if a sequence needs more than one; + // (b) use a grade 1 passage only if three or more symbols-sequences each need a grade 1 symbol or word indicator. + // Grade 1 symbol indicators forced by 'a-j' following a digit are not counted (GTM 1.7.3 note). // debug!("before determining mode: '{}'", raw_braille); - // a bit ugly because we need to store the string if we have cap passage mode - let raw_braille_string = if is_cap_passage_mode_good(raw_braille) {convert_to_cap_passage_mode(raw_braille)} else {String::default()}; - let raw_braille = if raw_braille_string.is_empty() {raw_braille} else {&raw_braille_string}; - if use_only_grade1 { - return remove_unneeded_mode_changes(raw_braille, UEB_Mode::Grade1, UEB_Duration::Passage); - } - let grade2 = remove_unneeded_mode_changes(raw_braille, UEB_Mode::Grade2, UEB_Duration::Symbol); - debug!("Symbol mode: '{}'", grade2); - - if is_grade2_string_ok(&grade2) { - return grade2; + // Capital passage (RUEB §8.5): like word mode's extra 'C' (CC…), passage uses CCC…Ce. + // Count G1 on the original (with capital markers) so standing-alone letters still force + // passage when needed (BANA Ex 5-15), but apply mode changes after stripping C/𝐶 so + // Grade 2 contractions are not blocked by cap_word_mode (chem "ch" → ⠡). + let had_unit_break = raw_braille.contains('𝐖'); + let raw_braille = raw_braille.replace('𝐖', "W"); + let use_cap_passage = is_cap_passage_mode_good(&raw_braille); + let stripped_caps = raw_braille.replace(['C', '𝐶'], ""); + let apply_to = if use_cap_passage { stripped_caps.as_str() } else { raw_braille.as_str() }; + let result = if use_only_grade1 { + remove_unneeded_mode_changes(apply_to, UEB_Mode::Grade1, UEB_Duration::Passage) } else { - // BANA says use g1 word mode if spaces are present, but that's not what their examples do - // A conversation with Ms. DeAndrea from BANA said that they mean use passage mode if ≥3 "segments" (≥2 blanks) - // The G1 Word mode might not be at the start (iceb.rs:omission_3_6_7) - let grade1_word = try_grade1_word_mode(raw_braille); - debug!("Word mode: '{}'", grade1_word); - if !grade1_word.is_empty() { - return grade1_word; - } else { - let grade1_passage = remove_unneeded_mode_changes(raw_braille, UEB_Mode::Grade1, UEB_Duration::Passage); - return "⠰⠰⠰".to_string() + &grade1_passage + "⠰⠄"; - } + gtm_1_7_mode(&raw_braille, apply_to, had_unit_break) + }; + if use_cap_passage { + return convert_to_cap_passage_mode(&result); } + return result; - /// Return true if at least five (= # of cap passage indicators) cap indicators and no lower case letters + /// Return true if capital passage mode should be used (RUEB §8.5 / BANA Ex 5-15). + /// Requires no lowercase letters, and either ≥5 capital indicators (chem / dense caps) + /// or ≥3 letter-bearing symbols-sequences that are fully capitalized. + /// Grade 1 / numeric / other non-letter markers are transparent (do not abort the scan). fn is_cap_passage_mode_good(braille: &str) -> bool { let mut n_caps = 0; + let mut n_letter_seqs = 0; + let mut seq_has_letter = false; let mut is_cap_mode = false; let mut cap_mode = UEB_Duration::Symbol; // real value set when is_cap_mode is set to true let mut chars = braille.chars(); @@ -1115,6 +1114,7 @@ fn ueb_cleanup(pref_manager: Ref, raw_braille: String) -> Str if !is_cap_mode { return false; } + seq_has_letter = true; chars.next(); // skip letter if cap_mode == UEB_Duration::Symbol { is_cap_mode = false; @@ -1130,76 +1130,33 @@ fn ueb_cleanup(pref_manager: Ref, raw_braille: String) -> Str } n_caps += 1; } else if ch == 'W' || ch == '𝐖' { - if is_cap_mode { - assert!(cap_mode == UEB_Duration::Word); + if seq_has_letter { + n_letter_seqs += 1; + seq_has_letter = false; } is_cap_mode = false; - } else if ch == '1' && is_cap_mode { - break; } + // else: '1', '𝟙', 'N', operators, typeforms, etc. — transparent } - return n_caps > 4; + if seq_has_letter { + n_letter_seqs += 1; + } + return n_caps >= 5 || n_letter_seqs >= 3; } + /// After G1 placement: strip any leftover capital markers and wrap with intermediate + /// `CCC`…`Ce` (same map as word mode: C→⠠, e→⠄ → ⠠⠠⠠…⠠⠄). Applied after + /// remove_unneeded_mode_changes so parsers never treat passage opener as CL letters. + /// If G1 passage is present (⠰⠰⠰…⠰⠄), capital passage goes inside (BANA Ex 5-15). fn convert_to_cap_passage_mode(braille: &str) -> String { - return "⠠⠠⠠".to_string() + &braille.replace(['C', '𝐶'], "") + "⠠⠄"; - } - - /// Return true if the BANA or ICEB guidelines say it is ok to start with grade 2 - fn is_grade2_string_ok(grade2_braille: &str) -> bool { - // BANA says use grade 2 if there is not more than one grade one symbol or single letter standing alone. - // The exact quote from their guidance: - // Unless a math expression can be correctly represented with only a grade 1 symbol indicator in the first three cells - // or before a single letter standing alone anywhere in the expression, - // begin the expression with a grade 1 word indicator - // Note: I modified this slightly to exclude the cap indicator in the count. That allows three more ICEB rule to pass and seems - // like it is a reasonable thing to do. - // Another modification is allow a single G1 indicator to occur after whitespace later on - // because ICEB examples show it and it seems better than going to passage mode if it is the only G1 indicator - - // Because of the 'L's which go away, we have to put a little more work into finding the first three chars - let chars = grade2_braille.chars().collect::>(); - let mut n_real_chars = 0; // actually number of chars - let mut found_g1 = false; - let mut i = 0; - while i < chars.len() { - let ch = chars[i]; - if ch == '1' && !is_forced_grade1(&chars, i) { - if found_g1 { - return false; - } - found_g1 = true; - } else if !"𝐶CLobc".contains(ch) { - if n_real_chars == 2 { - i += 1; - break; // this is the third real char - }; - n_real_chars += 1; - } - i += 1 - } - - // if we find *another* g1 that isn't forced and isn't standing alone, we are done - // I've added a 'follows whitespace' clause for test iceb.rs:omission_3_6_2 to the standing alone rule - // we only allow one standing alone example -- not sure if BANA guidance has this limit, but GTM 11_5_5_3 seems better with it - // Same for GTM 1_7_3_1 (passage mode is mentioned also) - let mut is_standing_alone_already_encountered = false; - let mut is_after_whitespace = false; - while i < chars.len() { - let ch = chars[i]; - if ch == 'W' { - is_after_whitespace = true; - } else if ch == '1' && !is_forced_grade1(&chars, i) { - if is_standing_alone_already_encountered || - ((found_g1 || !is_after_whitespace) && !is_single_letter_on_right(&chars, i)) { - return false; - } - found_g1 = true; - is_standing_alone_already_encountered = true; + let body = braille.replace(['C', '𝐶'], ""); + const G1_START: &str = "⠰⠰⠰"; + const G1_END: &str = "⠰⠄"; + if let Some(rest) = body.strip_prefix(G1_START) + && let Some(mid) = rest.strip_suffix(G1_END) { + return format!("{G1_START}CCC{mid}Ce{G1_END}"); } - i += 1; - } - return true; + return format!("CCC{body}Ce"); } /// Return true if the sequence of chars forces a '1' at the `i`th position @@ -1221,56 +1178,139 @@ fn ueb_cleanup(pref_manager: Ref, raw_braille: String) -> Str return false; } - fn is_single_letter_on_right(chars: &[char], i: usize) -> bool { - fn is_skip_char(ch: char) -> bool { - matches!(ch, 'B' | 'I' | '𝔹' | 'S' | 'T' | 'D' | 'C' | '𝐶' | 's' | 'w') - } + /// Count the number of non-forced grade 1 indicators needed for a single symbols-sequence. + /// (Forced indicators -- 'a-j' following a digit -- are excluded per the GTM 1.7.3 note.) + fn grade1_count(raw_word: &str) -> usize { + let grade2 = remove_unneeded_mode_changes(raw_word, UEB_Mode::Grade2, UEB_Duration::Symbol); + let chars = grade2.chars().collect::>(); + return chars.iter().enumerate() + .filter(|&(i, &ch)| ch == '1' && !is_forced_grade1(&chars, i)) + .count(); + } - // find the first char (if any) - let mut count = 0; // how many letters - let mut i = i+1; + /// True if this symbols-sequence contains a literary English word (4+ letters). + /// GTM 1.7.5: short math names (sin, cos, lim, min, …) and single-letter variables + /// are not treated as words. + fn sequence_contains_word(raw_word: &str) -> bool { + let chars: Vec = raw_word.chars().collect(); + let mut run = 0usize; + let mut i = 0usize; while i < chars.len() { let ch = chars[i]; - if !is_skip_char(ch) { - if ch == 'L' { - if count == 1 { - return false; // found a second letter in the sequence - } - count += 1; - } else { - return count==1; + if ch == 'L' { + run += 1; + i += 1; + if i < chars.len() { + i += 1; // skip the braille cell after 'L' + } + if run >= 4 { + return true; } - i += 2; // eat 'L' and actual letter + } else if ch == 'A' { + run += 1; + i += 1; + if run >= 4 { + return true; + } + } else if is_math_alphabet_typeform(ch) { + // Double-struck/script/fraktur/sans-serif letters are not part of an English word. + let end = math_typeform_item_end(&chars, i); + i = if end > i { end } else { i + 1 }; + run = 0; + } else if matches!(ch, 'C' | '𝐶' | 'G' | 'V' | 'B' | 'I' | 's' | 'w' | 'e') { + i += 1; // letter prefixes / literary typeform — do not break the run } else { + run = 0; i += 1; } } - return true; + false + } + + /// G2 form of a general-fraction sequence when two symbol indicators keep words + /// contracted (GTM 1.7.5(a)). `None` if more than two G1 symbols would remain. + fn g2_two_symbol_form(raw_word: &str) -> Option { + // Only the GTM 1.7.5(a) case: a general fraction whose numerator/denominator + // contain literary words. Superscripts, radicals, etc. keep 1.7.3 word indicators. + if !(raw_word.contains('⠷') && raw_word.contains("⠨⠌")) { + return None; + } + let g2 = remove_unneeded_mode_changes(raw_word, UEB_Mode::Grade2, UEB_Duration::Symbol); + let chars: Vec = g2.chars().collect(); + let n_g1 = chars.iter().enumerate() + .filter(|&(i, &ch)| ch == '1' && !is_forced_grade1(&chars, i)) + .count(); + if n_g1 <= 2 { + Some(g2) + } else { + None + } } - fn try_grade1_word_mode(raw_braille: &str) -> String { - // this isn't quite right, but pretty close -- try splitting at 'W' (words) - // only one of the parts can be in word mode and none of the others can have '1' unless forced - let mut g1_words = Vec::default(); - let mut found_word_mode = false; - for raw_word in raw_braille.split('W') { - let word = remove_unneeded_mode_changes(raw_word, UEB_Mode::Grade2, UEB_Duration::Symbol); - // debug!("try_grade1_word_mode: word='{}'", word); - let word_chars = word.chars().collect::>(); - let needs_word_mode = word_chars.iter().enumerate() - .any(|(i, &ch) | ch == '1' && !is_forced_grade1(&word_chars, i)); - if needs_word_mode { - if found_word_mode { - return "".to_string(); + /// ICEB GTM 1.7 grade 1 indicator placement (per symbols-sequence). + /// GTM 1.7.3: one grade 1 symbol per sequence, or a word indicator if more than one. + /// GTM 1.7.5(a): for a sequence containing word(s), allow two grade 1 symbol + /// indicators when that keeps the words in their usual contracted form + /// (e.g. ⠷…⠾ around work/distance). More than two still uses a word indicator. + /// `count_src` decides passage vs word vs symbol; changes are applied to `apply_to` + /// (may differ when capital markers were stripped for capital-passage mode). + fn gtm_1_7_mode(count_src: &str, apply_to: &str, had_unit_break: bool) -> String { + let count_words: Vec<&str> = count_src.split('W').collect(); + let apply_words: Vec<&str> = apply_to.split('W').collect(); + assert_eq!(count_words.len(), apply_words.len(), + "gtm_1_7_mode: count_src and apply_to must have the same number of symbols-sequences"); + + // Count how many symbols-sequences (whitespace-separated) need a non-forced grade 1 indicator. + let n_seq_needing = count_words.iter().filter(|raw_word| grade1_count(raw_word) >= 1).count(); + + // GTM 1.7.3(b) / 1.7.5(c): use a grade 1 passage if three or more sequences + // each need grade 1. 1.7.5(c) starts the passage at the first such sequence so + // preceding words (e.g. "speed") stay contracted. That delayed start is used when + // spaced units (𝐖) joined the expression; otherwise a passage wraps the whole + // expression (chem, roots, labelled equations). + if n_seq_needing >= 3 { + let first = count_words.iter().position(|w| grade1_count(w) >= 1) + .expect("n_seq_needing >= 3 implies a sequence that needs grade 1"); + let delay_start = had_unit_break && first > 0; + if delay_start { + let prefix: Vec = apply_words[..first].iter() + .map(|w| remove_unneeded_mode_changes(w, UEB_Mode::Grade2, UEB_Duration::Symbol)) + .collect(); + let rest = apply_words[first..].join("W"); + let passage = remove_unneeded_mode_changes(&rest, UEB_Mode::Grade1, UEB_Duration::Passage); + let mut out = prefix.join("W"); + if !out.is_empty() { + out.push('W'); } - found_word_mode = true; - g1_words.push("⠰⠰".to_string() + &remove_unneeded_mode_changes(raw_word, UEB_Mode::Grade1, UEB_Duration::Word) - ); - } else { - g1_words.push(word); + out.push_str("⠰⠰⠰"); + out.push_str(&passage); + out.push_str("⠰⠄"); + return out; } + let grade1_passage = remove_unneeded_mode_changes(apply_to, UEB_Mode::Grade1, UEB_Duration::Passage); + return "⠰⠰⠰".to_string() + &grade1_passage + "⠰⠄"; } - return if found_word_mode {g1_words.join("W")} else {"".to_string()}; + + // GTM 1.7.3(a): per sequence, allow one grade 1 symbol indicator, or a grade 1 word + // indicator if the sequence needs more than one. + let words = count_words.iter().zip(apply_words.iter()) + .map(|(&count_word, &apply_word)| { + let n_g1 = grade1_count(count_word); + if n_g1 >= 2 { + // GTM 1.7.5(a): two symbol indicators if that preserves contractions + if sequence_contains_word(count_word) + && let Some(g2) = g2_two_symbol_form(apply_word) { + g2 + } else { + "⠰⠰".to_string() + &remove_unneeded_mode_changes(apply_word, UEB_Mode::Grade1, UEB_Duration::Word) + } + } else { + // 0 or 1 grade 1 indicators: the grade 2 form leaves a single symbol indicator inline + remove_unneeded_mode_changes(apply_word, UEB_Mode::Grade2, UEB_Duration::Symbol) + } + }) + .collect::>(); + return words.join("W"); } } } @@ -1510,6 +1550,93 @@ fn is_left_intervening_char(ch: char) -> bool { matches!(ch, 'B' | 'I' | '𝔹' | 'S' | 'T' | 'D' | 'C' | '𝐶' | 's' | 'w') } +/// Double-struck / script / fraktur / sans-serif: math alphabets, not literary emphasis. +fn is_math_alphabet_typeform(ch: char) -> bool { + matches!(ch, '𝔹' | 'T' | 'D' | 'S') +} + +/// Advance past one letter with optional capital, Greek, and accent prefixes (`C? G|V? A…? L cell`). +fn skip_one_prefixed_letter(chars: &[char], mut i: usize) -> usize { + if i >= chars.len() { + return i; + } + if matches!(chars[i], 'C' | '𝐶') { + i += 1; + } + if i < chars.len() && matches!(chars[i], 'G' | 'V') { + i += 1; + } + if i < chars.len() && chars[i] == 'A' { + match index_after_accent_to_l(chars, i + 1) { + Some(i_l) => i = i_l, + None => return i, + } + } + if i < chars.len() && chars[i] == 'L' { + i += 1; + if i < chars.len() { + i += 1; // braille cell + } + } + i +} + +/// End index of a math-alphabet typeform item starting at `i` (`𝔹`/`T`/`D`/`S`). +/// `s` covers one letter; `w` covers the typeform word until its terminator. +fn math_typeform_item_end(chars: &[char], i: usize) -> usize { + if i >= chars.len() || !is_math_alphabet_typeform(chars[i]) { + return i; + } + let typeform = chars[i]; + let mut j = i + 1; + let word_mode = j < chars.len() && chars[j] == 'w'; + if j < chars.len() && matches!(chars[j], 's' | 'w') { + j += 1; + } + if word_mode { + loop { + let next = skip_one_prefixed_letter(chars, j); + if next == j { + break; + } + j = next; + } + if j + 1 < chars.len() && chars[j] == typeform && chars[j + 1] == 'e' { + j += 2; + } else if j < chars.len() && chars[j] == 'e' { + j += 1; + } + return j; + } + return skip_one_prefixed_letter(chars, j); +} + +/// RUEB 10.6.2: lower groupsigns "be", "con", "dis" only at the beginning of a word. +/// Beginning of a word = letters-sequence after space, hyphen or dash, optionally with +/// intervening punctuation/indicators from RUEB 2.6.2 (opening brackets/quotes, typeform, +/// capitals). Math operators and fraction indicators are not word boundaries. +/// `word_start` is the index of the first char of a grade-2 letter run ('L', 'C', or 'A'). +fn allows_lower_word_sign_at(chars: &[char], word_start: usize) -> bool { + if word_start >= chars.len() { + return false; + } + if word_start == 0 { + return true; + } + let mut j = word_start; + while j > 0 { + j -= 1; + let ch = chars[j]; + // 2.6.2 intervening symbols (opening punctuation flags, typeform, capitals, etc.) + if is_left_intervening_char(ch) || matches!(ch, 'e' | 'c' | 's' | 'w' | 'o' | 'b' | 'G' | 'V') { + continue; + } + // Must be space, hyphen or dash (RUEB 10.6.2 Note) + return "W𝐖-—―".contains(ch); + } + true +} + /// Return value for use_g1_word_mode() #[derive(Debug, PartialEq)] enum Grade1WordIndicator { @@ -1677,6 +1804,34 @@ fn remove_unneeded_mode_changes(raw_braille: &str, start_mode: UEB_Mode, start_d } // debug!("Grade 2: ch={}, duration: {:?}", ch, duration); match ch { + '𝔹' | 'T' | 'D' | 'S' => { + // Math-alphabet typeform: this letter is not part of an English word + // (GTM 11.6). Close any current contraction run, emit the typeform + // item on its own, then let following letters start a new word. + if let Some(start) = start_g2_letter { + if !cap_word_mode { + result = handle_contractions(&chars, start, i, result); + } + cap_word_mode = false; + start_g2_letter = None; + } + let unit_end = math_typeform_item_end(&chars, i); + // Typeform prefix (`𝔹s`) must precede the grade 1 indicator: ⠈⠆⠰⠠⠗, not ⠰⠈⠆⠠⠗. + let mut letter_start = i + 1; + if letter_start < unit_end && matches!(chars[letter_start], 's' | 'w') { + letter_start += 1; + } + result.extend(chars[i..letter_start].iter().copied()); + if let Some(letter_idx) = chars[i..unit_end].iter().position(|&c| c == 'L') { + let (is_alone, _, n_letters) = stands_alone(&chars, i + letter_idx); + if is_alone && n_letters == 1 { + result.push('1'); + mode = UEB_Mode::Grade1; + } + } + result.extend(chars[letter_start..unit_end].iter().copied()); + i = unit_end; + }, 'L' => { if start_g2_letter.is_none() { start_g2_letter = Some(i); @@ -1758,6 +1913,16 @@ fn remove_unneeded_mode_changes(raw_braille: &str, start_mode: UEB_Mode, start_d } }, '1' => { + // Contract the preceding letter run before consuming '1'. The '1' arm used + // to increment first, so handle_contractions saw "work1" and the whole-word + // patterns `^work$` / `^time$` failed (GTM 1.7.9 work/distance, 1.7.5(a) time). + if let Some(start) = start_g2_letter { + if !cap_word_mode { + result = handle_contractions(&chars, start, i, result); + } + cap_word_mode = false; + start_g2_letter = None; + } result.push(ch); i += 1; mode = UEB_Mode::Grade1; @@ -1778,7 +1943,7 @@ fn remove_unneeded_mode_changes(raw_braille: &str, start_mode: UEB_Mode, start_d _ => { if let Some(start) = start_g2_letter { if !cap_word_mode { - result = handle_contractions(&chars[start..i], result); + result = handle_contractions(&chars, start, i, result); } cap_word_mode = false; start_g2_letter = None; // not start of char sequence @@ -1794,7 +1959,7 @@ fn remove_unneeded_mode_changes(raw_braille: &str, start_mode: UEB_Mode, start_d } if mode != UEB_Mode::Grade2 && !cap_word_mode && let Some(start) = start_g2_letter { - result = handle_contractions(&chars[start..i], result); + result = handle_contractions(&chars, start, i, result); start_g2_letter = None; // not start of char sequence } }, @@ -1814,7 +1979,7 @@ fn remove_unneeded_mode_changes(raw_braille: &str, start_mode: UEB_Mode, start_d } if mode == UEB_Mode::Grade2 && let Some(start) = start_g2_letter { - result = handle_contractions(&chars[start..i], result); + result = handle_contractions(&chars, start, i, result); } return result; @@ -1946,10 +2111,12 @@ fn stands_alone(chars: &[char], i: usize) -> (bool, &[char], usize) { /// Return a modified result if chars can be contracted. /// Otherwise, the original string is returned -fn handle_contractions(chars: &[char], mut result: String) -> String { +fn handle_contractions(full_chars: &[char], start: usize, end: usize, mut result: String) -> String { struct Replacement { pattern: String, - replacement: &'static str + replacement: &'static str, + skip_if_word_in: Option<&'static phf::Set<&'static str>>, + word_start_only: bool, } const ASCII_TO_UNICODE: &[char] = &[ @@ -1968,47 +2135,95 @@ fn handle_contractions(chars: &[char], mut result: String) -> String { return unicode; } + // Whole words where the lower groupsign 'cc' must not apply (10.11.1 compound/function names). + static CC_EXCEPTION_WORDS: phf::Set<&str> = phf_set! { + "L⠁L⠗L⠉L⠉L⠕L⠎", // arccos + "L⠁L⠗L⠉L⠉L⠕L⠎L⠊L⠝L⠑", // arccosine + "L⠁L⠗L⠉L⠉L⠕L⠎L⠓", // arccosh + "L⠁L⠗L⠉L⠉L⠕L⠎L⠑L⠉", // arccosec + "L⠁L⠗L⠉L⠉L⠕L⠎L⠑L⠉L⠁L⠝L⠞", // arccosecant + "L⠁L⠗L⠉L⠉L⠕L⠞", // arccot + "L⠁L⠗L⠉L⠉L⠕L⠞L⠁L⠝L⠛L⠑L⠝L⠞", // arccotangent + "L⠁L⠗L⠉L⠉L⠎L⠉", // arccsc + }; + + // Words where the 'ea' lower groupsign must not apply (re- prefix morpheme boundary). + static EA_EXCEPTION_WORDS: phf::Set<&str> = phf_set! { + "L⠗L⠑L⠁L⠉L⠞L⠁L⠝L⠉L⠑", // reactance + "L⠗L⠑L⠁L⠉L⠞L⠊L⠕L⠝", // reaction + "L⠗L⠑L⠁L⠉L⠞L⠊L⠧L⠊L⠞L⠽", // reactivity + }; + + // Words where "be" is not the first syllable (RUEB 10.6.1 "But:" cases and similar). + static BE_EXCEPTION_WORDS: phf::Set<&str> = phf_set! { + "L⠃L⠑L⠁L⠗L⠊L⠝L⠛", // bearing + "L⠃L⠑L⠝L⠉L⠓L⠍L⠁L⠗L⠅", // benchmark + }; + // It would be much better from an extensibility point of view to read the table in from a file static CONTRACTIONS: LazyLock> = LazyLock::new(|| { vec![ + // 10.9: initial-letter (dot-5) wordsigns -- whole word only + Replacement{ pattern: format!("^{}$", to_unicode_braille("time")), replacement: "⠐⠞", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: format!("^{}$", to_unicode_braille("work")), replacement: "⠐⠺", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: format!("^{}$", to_unicode_braille("leverage")), replacement: "⠇⠐⠑⠁⠛⠑", skip_if_word_in: None, word_start_only: false }, + + // 10.7.1: dot-5 initial-letter contractions (as wordsigns / groupsigns) + Replacement{ pattern: format!("^{}", to_unicode_braille("through")), replacement: "⠐⠹", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: format!("(?PL.){}(?PL.)", to_unicode_braille("part")), replacement: "${s}⠐⠏${e}", skip_if_word_in: None, word_start_only: false }, + // 10.3: Strong contractions - Replacement{ pattern: to_unicode_braille("and"), replacement: "L⠯"}, - Replacement{ pattern: to_unicode_braille("for"), replacement: "L⠿"}, - Replacement{ pattern: to_unicode_braille("of"), replacement: "L⠷"}, - Replacement{ pattern: to_unicode_braille("the"), replacement: "L⠮"}, - Replacement{ pattern: to_unicode_braille("with"), replacement: "L⠾"}, + Replacement{ pattern: to_unicode_braille("and"), replacement: "L⠯", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("for"), replacement: "L⠿", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("of"), replacement: "L⠷", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("the"), replacement: "L⠮", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("with"), replacement: "L⠾", skip_if_word_in: None, word_start_only: false }, + + // 10.6.1-10.6.4 / 10.10.4: lower groupsigns be/con/dis -- only at word start, + // and preferred over other groupsigns (e.g. "distance" is ⠲⠞⠨⠑, not di+st+ance). + Replacement{ pattern: format!("^{}", to_unicode_braille("be")), replacement: "⠆", skip_if_word_in: Some(&BE_EXCEPTION_WORDS), word_start_only: true }, + Replacement{ pattern: format!("^{}", to_unicode_braille("con")), replacement: "⠒", skip_if_word_in: None, word_start_only: true }, + Replacement{ pattern: format!("^{}", to_unicode_braille("dis")), replacement: "⠲", skip_if_word_in: None, word_start_only: true }, - // 10.8: final-letter group signs (this need to precede 'en' and any other shorter contraction) - Replacement{ pattern: "(?PL.)L⠍L⠑L⠝L⠞".to_string(), replacement: "${s}L⠰L⠞" }, // ment - Replacement{ pattern: "(?PL.)L⠞L⠊L⠕L⠝".to_string(), replacement: "${s}L⠰L⠝" } ,// tion + // 10.8: final-letter group signs (these need to precede 'en' and any other shorter contraction) + Replacement{ pattern: "(?PL.)L⠍L⠑L⠝L⠞".to_string(), replacement: "${s}L⠰L⠞", skip_if_word_in: None, word_start_only: false }, // ment + Replacement{ pattern: "(?PL.)L⠞L⠊L⠕L⠝".to_string(), replacement: "${s}L⠰L⠝", skip_if_word_in: None, word_start_only: false }, // tion + Replacement{ pattern: "(?PL.)L⠊L⠞L⠽".to_string(), replacement: "${s}L⠰L⠽", skip_if_word_in: None, word_start_only: false }, // ity + Replacement{ pattern: "(?PL.)L⠁L⠝L⠉L⠑".to_string(), replacement: "${s}L⠨L⠑", skip_if_word_in: None, word_start_only: false }, // ance + Replacement{ pattern: "(?PL.)L⠎L⠊L⠕L⠝".to_string(), replacement: "${s}L⠨L⠝", skip_if_word_in: None, word_start_only: false }, // sion + Replacement{ pattern: "(?PL.)L⠑L⠝L⠉L⠑".to_string(), replacement: "${s}L⠰L⠑", skip_if_word_in: None, word_start_only: false }, // ence + Replacement{ pattern: "(?PL.)L⠝L⠑L⠎L⠎".to_string(), replacement: "${s}L⠰L⠎", skip_if_word_in: None, word_start_only: false }, // ness + Replacement{ pattern: "(?PL.)L⠕L⠥L⠝L⠙".to_string(), replacement: "${s}L⠨L⠙", skip_if_word_in: None, word_start_only: false }, // ound + Replacement{ pattern: "(?PL.)L⠕L⠥L⠝L⠞".to_string(), replacement: "${s}L⠨L⠞", skip_if_word_in: None, word_start_only: false }, // ount + Replacement{ pattern: "(?PL.)L⠇L⠑L⠎L⠎".to_string(), replacement: "${s}L⠨L⠎", skip_if_word_in: None, word_start_only: false }, // less + Replacement{ pattern: "(?PL.)L⠕L⠝L⠛".to_string(), replacement: "${s}L⠰L⠛", skip_if_word_in: None, word_start_only: false }, // ong + Replacement{ pattern: "(?PL.)L⠋L⠥L⠇".to_string(), replacement: "${s}L⠰L⠇", skip_if_word_in: None, word_start_only: false }, // ful // 10.4: Strong group signs - Replacement{ pattern: to_unicode_braille("ch"), replacement: "L⠡"}, - Replacement{ pattern: to_unicode_braille("gh"), replacement: "L⠣"}, - Replacement{ pattern: to_unicode_braille("sh"), replacement: "L⠩"}, - Replacement{ pattern: to_unicode_braille("th"), replacement: "L⠹"}, - Replacement{ pattern: to_unicode_braille("wh"), replacement: "L⠱"}, - Replacement{ pattern: to_unicode_braille("ed"), replacement: "L⠫"}, - Replacement{ pattern: to_unicode_braille("er"), replacement: "L⠻"}, - Replacement{ pattern: to_unicode_braille("ou"), replacement: "L⠳"}, - Replacement{ pattern: to_unicode_braille("ow"), replacement: "L⠪"}, - Replacement{ pattern: to_unicode_braille("st"), replacement: "L⠌"}, - Replacement{ pattern: "(?PL.)L⠊L⠝L⠛".to_string(), replacement: "${s}L⠬" }, // 'ing', not at start - Replacement{ pattern: to_unicode_braille("ar"), replacement: "L⠜"}, + Replacement{ pattern: to_unicode_braille("ch"), replacement: "L⠡", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("gh"), replacement: "L⠣", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("sh"), replacement: "L⠩", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("th"), replacement: "L⠹", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("wh"), replacement: "L⠱", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("ed"), replacement: "L⠫", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("er"), replacement: "L⠻", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("ou"), replacement: "L⠳", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("ow"), replacement: "L⠪", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("st"), replacement: "L⠌", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: "(?PL.)L⠊L⠝L⠛".to_string(), replacement: "${s}L⠬", skip_if_word_in: None, word_start_only: false }, // 'ing', not at start + Replacement{ pattern: to_unicode_braille("ar"), replacement: "L⠜", skip_if_word_in: None, word_start_only: false }, // 10.6.5: Lower group signs preceded and followed by letters // FIX: don't match if after/before a cap letter -- can't use negative pattern (?!...) in regex package - // Note: removed cc because "arccos" shouldn't be contracted (10.11.1), but there is no way to know about compound words - // Add it back after implementing a lookup dictionary of exceptions - Replacement{ pattern: "(?PL.)L⠑L⠁(?PL.)".to_string(), replacement: "${s}L⠂${e}" }, // ea - Replacement{ pattern: "(?PL.)L⠃L⠃(?PL.)".to_string(), replacement: "${s}L⠆${e}" }, // bb - // Replacement{ pattern: "(?PL.)L⠉L⠉(?PL.)".to_string(), replacement: "${s}L⠒${e}" }, // cc - Replacement{ pattern: "(?PL.)L⠋L⠋(?PL.)".to_string(), replacement: "${s}L⠖${e}" }, // ff - Replacement{ pattern: "(?PL.)L⠛L⠛(?PL.)".to_string(), replacement: "${s}L⠶${e}" }, // gg - - // 10.6.8: Lower group signs ("in" also 10.5.4 lower word signs) + Replacement{ pattern: "(?PL.)L⠑L⠁(?PL.)".to_string(), replacement: "${s}L⠂${e}", skip_if_word_in: Some(&EA_EXCEPTION_WORDS), word_start_only: false }, // ea + Replacement{ pattern: "(?PL.)L⠃L⠃(?PL.)".to_string(), replacement: "${s}L⠆${e}", skip_if_word_in: None, word_start_only: false }, // bb + Replacement{ pattern: "(?PL.)L⠉L⠉(?PL.)".to_string(), replacement: "${s}L⠒${e}", skip_if_word_in: Some(&CC_EXCEPTION_WORDS), word_start_only: false }, // cc + Replacement{ pattern: "(?PL.)L⠋L⠋(?PL.)".to_string(), replacement: "${s}L⠖${e}", skip_if_word_in: None, word_start_only: false }, // ff + Replacement{ pattern: "(?PL.)L⠛L⠛(?PL.)".to_string(), replacement: "${s}L⠶${e}", skip_if_word_in: None, word_start_only: false }, // gg + + // 10.6.8: lower group signs; also 10.6.2 word signs when at word start ("sin", etc.) // FIX: these need restrictions about only applying when upper dots are present - Replacement{ pattern: to_unicode_braille("en"), replacement: "⠢"}, - Replacement{ pattern: to_unicode_braille("in"), replacement: "⠔"}, + Replacement{ pattern: to_unicode_braille("en"), replacement: "⠢", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("in"), replacement: "⠔", skip_if_word_in: None, word_start_only: false }, ] }); @@ -2016,11 +2231,28 @@ fn handle_contractions(chars: &[char], mut result: String) -> String { static CONTRACTION_PATTERNS: LazyLock = LazyLock::new(|| init_patterns(&CONTRACTIONS)); static CONTRACTION_REGEX: LazyLock> = LazyLock::new(|| init_regex(&CONTRACTIONS)); + let word_start_ok = allows_lower_word_sign_at(full_chars, start); + let chars = &full_chars[start..end]; + // A non-English letter glued to an English word (GTM 1.7.9 Δtime, or a + // double-struck/script/fraktur letter) is not part of the English + // letters-sequence; contract the following word on its own (time → ⠐⠞). + let skip = leading_non_word_letter_len(chars); + if skip > 0 && skip < chars.len() { + return handle_contractions(full_chars, start + skip, end, result); + } let mut chars_as_str = chars.iter().collect::(); + let original_chars_as_str = chars_as_str.clone(); // debug!(" handle_contractions: examine '{}'", &chars_as_str); let matches = CONTRACTION_PATTERNS.matches(&chars_as_str); for i in matches.iter() { let element = &CONTRACTIONS[i]; + if let Some(exceptions) = element.skip_if_word_in + && exceptions.contains(&original_chars_as_str) { + continue; + } + if element.word_start_only && !word_start_ok { + continue; + } // debug!(" replacing '{}' with '{}' in '{}'", element.pattern, element.replacement, &chars_as_str); result.truncate(result.len() - chars_as_str.len()); chars_as_str = CONTRACTION_REGEX[i].replace_all(&chars_as_str, element.replacement).to_string(); @@ -2031,6 +2263,31 @@ fn handle_contractions(chars: &[char], mut result: String) -> String { + fn leading_non_word_letter_len(chars: &[char]) -> usize { + if chars.is_empty() { + return 0; + } + if is_math_alphabet_typeform(chars[0]) { + let end = math_typeform_item_end(chars, 0); + return if end < chars.len() { end } else { 0 }; + } + let mut i = 0; + if i < chars.len() && matches!(chars[i], 'C' | '𝐶') { + i += 1; + } + if i < chars.len() && matches!(chars[i], 'G' | 'V') { + i += 1; + if i < chars.len() && chars[i] == 'L' { + i += 1; + if i < chars.len() { + i += 1; // braille cell + } + return i; + } + } + 0 + } + fn init_patterns(contractions: &[Replacement]) -> RegexSet { let mut vec: Vec<&str> = Vec::with_capacity(contractions.len()); for contraction in contractions { @@ -3808,6 +4065,26 @@ mod tests { }); } + #[test] + fn ueb_lower_word_sign_contractions() -> Result<()> { + return braille_test(|| { + init_braille_mathml("distance")?; + set_preference("BrailleCode", "UEB")?; + let distance = get_braille("")?; + // RUEB 10.6.1 / 10.10.4: distance at word start uses dis lower groupsign + assert_eq!(distance, "⠲⠞⠨⠑", "dis lower groupsign at word start: got '{distance}'"); + // After fraction open (not a RUEB 10.6.2 word start), dis must not apply; st+ance may. + init_braille_mathml("distancetime")?; + let frac = get_braille("")?; + assert!(!frac.contains("⠲"), "dis wrongly used after fraction open: got '{frac}'"); + assert!(frac.contains("⠙⠊⠌⠨⠑") || frac.contains("⠙⠊⠎⠞⠁⠝⠉⠑"), + "expected st+ance or uncontracted distance after fraction open: got '{frac}'"); + init_braille_mathml("include")?; + assert!(get_braille("")?.starts_with("⠔"), "in lower groupsign at word start"); + return Ok(()); + }); + } + #[test] // This test probably should be repeated for each braille code and be taken out of here fn find_mathml_from_braille() -> Result<()> { @@ -3868,7 +4145,7 @@ mod tests { set_preference("BrailleCode", "UEB")?; let _braille = get_braille("")?; - let answers= &[0, 0, 0, 2, 3, 3, 3, 3, 4, 7, 7, 8, 9, 9, 10, 13, 12, 14, 14, 15, 15, 17, 17, 19, 19, 21, 10, 4, 4, 23, 23, 25, 25, 4, 0, 0]; + let answers= &[2, 2, 3, 3, 3, 3, 4, 4, 4, 7, 7, 8, 9, 9, 10, 13, 12, 14, 14, 15, 15, 17, 17, 19, 19, 21, 10, 4, 4, 23, 23, 25, 25, 4]; let answers = answers.map(|num| format!("id-{}", num)); debug!("\n\n*** Testing UEB ***"); for (i, answer) in answers.iter().enumerate() { @@ -3927,4 +4204,367 @@ mod tests { "oL⠈N⠹⠜L⠁cL⠈N⠩⠜L⠃" ); } + + /// Letter-to-Unicode-braille mapping (matches handle_contractions). + const TEST_ASCII_TO_UNICODE: &[char] = &[ + '⠀', '⠮', '⠐', '⠼', '⠫', '⠩', '⠯', '⠄', '⠷', '⠾', '⠡', '⠬', '⠠', '⠤', '⠨', '⠌', + '⠴', '⠂', '⠆', '⠒', '⠲', '⠢', '⠖', '⠶', '⠦', '⠔', '⠱', '⠰', '⠣', '⠿', '⠜', '⠹', + '⠈', '⠁', '⠃', '⠉', '⠙', '⠑', '⠋', '⠛', '⠓', '⠊', '⠚', '⠅', '⠇', '⠍', '⠝', '⠕', + '⠏', '⠟', '⠗', '⠎', '⠞', '⠥', '⠧', '⠺', '⠭', '⠽', '⠵', '⠪', '⠳', '⠻', '⠘', '⠸', + ]; + + fn ascii_to_uncontracted_braille(word: &str) -> String { + word.bytes() + .map(|b| TEST_ASCII_TO_UNICODE[(b.to_ascii_uppercase() - 32) as usize]) + .collect() + } + + /// Run handle_contractions on a lowercase ASCII word (L-cell input) and return Unicode braille. + fn contract_word(word: &str) -> String { + let l_chars: Vec = word.bytes() + .flat_map(|b| { + let ch = TEST_ASCII_TO_UNICODE[(b.to_ascii_uppercase() - 32) as usize]; + ['L', ch] + }) + .collect(); + let input: String = l_chars.iter().collect(); + let output = handle_contractions(&l_chars, 0, l_chars.len(), input); + output.chars().filter(|&c| c != 'L').collect() + } + + /// Grade-2 contraction coverage for technical vocabulary (311 words). + /// Cross-check goldens at https://brailletranslators.com/ (Grade 2 / UEB). + /// Should contract (225): force, work, time, speed, distance, area, height, weight, power, energy, density, gravity, acceleration, length, width, depth, cost, profit, interest, revenue, clearance, conductance, capacitance, resistance, impedance, reactance, variance, tolerance, luminosity, reliability, velocity, viscosity, precision, tension, efficiency, frequency, valence, stiffness, thickness, displacement, concentration, consumption, duration, elevation, fraction, friction, inflation, iteration, population, position, potential, production, resolution, rotation, charge, chord, pitch, growth, head, heat, reach, shear, margin, salary, offset, income, input, inventory, current, error, leverage, temperature, turnover, accuracy, breadth, strength, spread, discount, count, version, inductance, intensity, interval, perimeter, probability, utility, validity, parity, permeability, proportion, uncertainty, circumference, capacity, deceleration, dilution, enthalpy, entropy, equity, expense, gradient, headroom, inertia, latency, longitude, permittivity, period, principal, sensitivity, stress, throughput, thrust, wavelength, absorption, activation, activity, admittance, affinity, albedo, aperture, attenuation, average, bandwidth, baseline, bearing, benchmark, boiling, boundary, cohesion, compliance, compression, conductivity, coverage, damping, deflection, departure, depreciation, deviation, diffusion, dispersion, dissipation, distortion, divergence, downforce, elasticity, emissivity, emission, erosion, evaporation, expansion, expectation, extent, feedback, fidelity, filament, hardness, humidity, hysteresis, illuminance, incidence, index, inflow, influx, inhibition, injection, irradiance, kinetic, leakage, luminance, maturity, mean, median, melting, minimum, mobility, molarity, moisture, opacity, oscillation, outflow, overlap, parallax, parameter, peak, percentile, percentage, polarization, propagation, purity, quality, quantity, quenching, quotient, radiance, radiation, reaction, reactivity, redshift, reflectance, reflection, refraction, reluctance, remanence, resistivity, resonance, restitution, retardation, rigidity, salinity, saturation, scalar, scattering, separation, shrinkage, similarity, battery, diameter, epoch, gain, jitter, joule, momentum, shift, step, stride, zenith + /// Should not contract (86): mass, volume, base, rate, drag, drift, gap, lag, loss, pace, radius, range, ratio, risk, run, scale, size, slope, tax, torque, capital, impulse, latitude, magnitude, premium, pressure, response, return, trajectory, voltage, aspect, backlog, curvature, dosage, dose, equilibrium, excess, exposure, fatigue, hydraulic, lifetime, likelihood, maximum, metric, orbit, osmosis, pulse, quanta, quantum, regret, residual, ripple, root, rotor, sag, secant, signal, altitude, amplitude, angle, bias, bitrate, budget, bulk, decay, deficit, degree, delay, duty, lift, limit, load, modulus, payload, phase, price, sample, skew, slack, span, supply, total, value, vector, wage, yield + /// Note: arccos (cc exception, partial ar groupsign) is covered in tests/braille/UEB/other.rs contractions_1. + #[test] + fn ueb_technical_word_contractions() { + const SHOULD_CONTRACT: &[(&str, &str)] = &[ + ("force", "⠿⠉⠑"), + ("work", "⠐⠺"), + ("time", "⠐⠞"), + ("speed", "⠎⠏⠑⠫"), + ("distance", "⠲⠞⠨⠑"), + ("area", "⠜⠑⠁"), + ("height", "⠓⠑⠊⠣⠞"), + ("weight", "⠺⠑⠊⠣⠞"), + ("power", "⠏⠪⠻"), + ("energy", "⠢⠻⠛⠽"), + ("density", "⠙⠢⠎⠰⠽"), + ("gravity", "⠛⠗⠁⠧⠰⠽"), + ("acceleration", "⠁⠒⠑⠇⠻⠁⠰⠝"), + ("length", "⠇⠢⠛⠹"), + ("width", "⠺⠊⠙⠹"), + ("depth", "⠙⠑⠏⠹"), + ("cost", "⠉⠕⠌"), + ("profit", "⠏⠗⠷⠊⠞"), + ("interest", "⠔⠞⠻⠑⠌"), + ("revenue", "⠗⠑⠧⠢⠥⠑"), + ("clearance", "⠉⠇⠑⠜⠨⠑"), + ("conductance", "⠒⠙⠥⠉⠞⠨⠑"), + ("capacitance", "⠉⠁⠏⠁⠉⠊⠞⠨⠑"), + ("resistance", "⠗⠑⠎⠊⠌⠨⠑"), + ("impedance", "⠊⠍⠏⠫⠨⠑"), + ("reactance", "⠗⠑⠁⠉⠞⠨⠑"), + ("variance", "⠧⠜⠊⠨⠑"), + ("tolerance", "⠞⠕⠇⠻⠨⠑"), + ("luminosity", "⠇⠥⠍⠔⠕⠎⠰⠽"), + ("reliability", "⠗⠑⠇⠊⠁⠃⠊⠇⠰⠽"), + ("velocity", "⠧⠑⠇⠕⠉⠰⠽"), + ("viscosity", "⠧⠊⠎⠉⠕⠎⠰⠽"), + ("precision", "⠏⠗⠑⠉⠊⠨⠝"), + ("tension", "⠞⠢⠨⠝"), + ("efficiency", "⠑⠖⠊⠉⠊⠢⠉⠽"), + ("frequency", "⠋⠗⠑⠟⠥⠢⠉⠽"), + ("valence", "⠧⠁⠇⠰⠑"), + ("stiffness", "⠌⠊⠖⠰⠎"), + ("thickness", "⠹⠊⠉⠅⠰⠎"), + ("displacement", "⠲⠏⠇⠁⠉⠑⠰⠞"), + ("concentration", "⠒⠉⠢⠞⠗⠁⠰⠝"), + ("consumption", "⠒⠎⠥⠍⠏⠰⠝"), + ("duration", "⠙⠥⠗⠁⠰⠝"), + ("elevation", "⠑⠇⠑⠧⠁⠰⠝"), + ("fraction", "⠋⠗⠁⠉⠰⠝"), + ("friction", "⠋⠗⠊⠉⠰⠝"), + ("inflation", "⠔⠋⠇⠁⠰⠝"), + ("iteration", "⠊⠞⠻⠁⠰⠝"), + ("population", "⠏⠕⠏⠥⠇⠁⠰⠝"), + ("position", "⠏⠕⠎⠊⠰⠝"), + ("potential", "⠏⠕⠞⠢⠞⠊⠁⠇"), + ("production", "⠏⠗⠕⠙⠥⠉⠰⠝"), + ("resolution", "⠗⠑⠎⠕⠇⠥⠰⠝"), + ("rotation", "⠗⠕⠞⠁⠰⠝"), + ("charge", "⠡⠜⠛⠑"), + ("chord", "⠡⠕⠗⠙"), + ("pitch", "⠏⠊⠞⠡"), + ("growth", "⠛⠗⠪⠹"), + ("head", "⠓⠂⠙"), + ("heat", "⠓⠂⠞"), + ("reach", "⠗⠂⠡"), + ("shear", "⠩⠑⠜"), + ("margin", "⠍⠜⠛⠔"), + ("salary", "⠎⠁⠇⠜⠽"), + ("offset", "⠷⠋⠎⠑⠞"), + ("income", "⠔⠉⠕⠍⠑"), + ("input", "⠔⠏⠥⠞"), + ("inventory", "⠔⠧⠢⠞⠕⠗⠽"), + ("current", "⠉⠥⠗⠗⠢⠞"), + ("error", "⠻⠗⠕⠗"), + ("leverage", "⠇⠐⠑⠁⠛⠑"), + ("temperature", "⠞⠑⠍⠏⠻⠁⠞⠥⠗⠑"), + ("turnover", "⠞⠥⠗⠝⠕⠧⠻"), + ("accuracy", "⠁⠒⠥⠗⠁⠉⠽"), + ("breadth", "⠃⠗⠂⠙⠹"), + ("strength", "⠌⠗⠢⠛⠹"), + ("spread", "⠎⠏⠗⠂⠙"), + ("discount", "⠲⠉⠨⠞"), + ("count", "⠉⠨⠞"), + ("version", "⠧⠻⠨⠝"), + ("inductance", "⠔⠙⠥⠉⠞⠨⠑"), + ("intensity", "⠔⠞⠢⠎⠰⠽"), + ("interval", "⠔⠞⠻⠧⠁⠇"), + ("perimeter", "⠏⠻⠊⠍⠑⠞⠻"), + ("probability", "⠏⠗⠕⠃⠁⠃⠊⠇⠰⠽"), + ("utility", "⠥⠞⠊⠇⠰⠽"), + ("validity", "⠧⠁⠇⠊⠙⠰⠽"), + ("parity", "⠏⠜⠰⠽"), + ("permeability", "⠏⠻⠍⠂⠃⠊⠇⠰⠽"), + ("proportion", "⠏⠗⠕⠏⠕⠗⠰⠝"), + ("uncertainty", "⠥⠝⠉⠻⠞⠁⠔⠞⠽"), + ("circumference", "⠉⠊⠗⠉⠥⠍⠋⠻⠰⠑"), + ("capacity", "⠉⠁⠏⠁⠉⠰⠽"), + ("deceleration", "⠙⠑⠉⠑⠇⠻⠁⠰⠝"), + ("dilution", "⠙⠊⠇⠥⠰⠝"), + ("enthalpy", "⠢⠹⠁⠇⠏⠽"), + ("entropy", "⠢⠞⠗⠕⠏⠽"), + ("equity", "⠑⠟⠥⠰⠽"), + ("expense", "⠑⠭⠏⠢⠎⠑"), + ("gradient", "⠛⠗⠁⠙⠊⠢⠞"), + ("headroom", "⠓⠂⠙⠗⠕⠕⠍"), + ("inertia", "⠔⠻⠞⠊⠁"), + ("latency", "⠇⠁⠞⠢⠉⠽"), + ("longitude", "⠇⠰⠛⠊⠞⠥⠙⠑"), + ("permittivity", "⠏⠻⠍⠊⠞⠞⠊⠧⠰⠽"), + ("period", "⠏⠻⠊⠕⠙"), + ("principal", "⠏⠗⠔⠉⠊⠏⠁⠇"), + ("sensitivity", "⠎⠢⠎⠊⠞⠊⠧⠰⠽"), + ("stress", "⠌⠗⠑⠎⠎"), + ("throughput", "⠐⠹⠏⠥⠞"), + ("thrust", "⠹⠗⠥⠌"), + ("wavelength", "⠺⠁⠧⠑⠇⠢⠛⠹"), + ("absorption", "⠁⠃⠎⠕⠗⠏⠰⠝"), + ("activation", "⠁⠉⠞⠊⠧⠁⠰⠝"), + ("activity", "⠁⠉⠞⠊⠧⠰⠽"), + ("admittance", "⠁⠙⠍⠊⠞⠞⠨⠑"), + ("affinity", "⠁⠖⠔⠰⠽"), + ("albedo", "⠁⠇⠃⠫⠕"), + ("aperture", "⠁⠏⠻⠞⠥⠗⠑"), + ("attenuation", "⠁⠞⠞⠢⠥⠁⠰⠝"), + ("average", "⠁⠧⠻⠁⠛⠑"), + ("bandwidth", "⠃⠯⠺⠊⠙⠹"), + ("baseline", "⠃⠁⠎⠑⠇⠔⠑"), + ("bearing", "⠃⠑⠜⠬"), + ("benchmark", "⠃⠢⠡⠍⠜⠅"), + ("boiling", "⠃⠕⠊⠇⠬"), + ("boundary", "⠃⠨⠙⠜⠽"), + ("cohesion", "⠉⠕⠓⠑⠨⠝"), + ("compliance", "⠉⠕⠍⠏⠇⠊⠨⠑"), + ("compression", "⠉⠕⠍⠏⠗⠑⠎⠨⠝"), + ("conductivity", "⠒⠙⠥⠉⠞⠊⠧⠰⠽"), + ("coverage", "⠉⠕⠧⠻⠁⠛⠑"), + ("damping", "⠙⠁⠍⠏⠬"), + ("deflection", "⠙⠑⠋⠇⠑⠉⠰⠝"), + ("departure", "⠙⠑⠐⠏⠥⠗⠑"), + ("depreciation", "⠙⠑⠏⠗⠑⠉⠊⠁⠰⠝"), + ("deviation", "⠙⠑⠧⠊⠁⠰⠝"), + ("diffusion", "⠙⠊⠖⠥⠨⠝"), + ("dispersion", "⠲⠏⠻⠨⠝"), + ("dissipation", "⠲⠎⠊⠏⠁⠰⠝"), + ("distortion", "⠲⠞⠕⠗⠰⠝"), + ("divergence", "⠙⠊⠧⠻⠛⠰⠑"), + ("downforce", "⠙⠪⠝⠿⠉⠑"), + ("elasticity", "⠑⠇⠁⠌⠊⠉⠰⠽"), + ("emissivity", "⠑⠍⠊⠎⠎⠊⠧⠰⠽"), + ("emission", "⠑⠍⠊⠎⠨⠝"), + ("erosion", "⠻⠕⠨⠝"), + ("evaporation", "⠑⠧⠁⠏⠕⠗⠁⠰⠝"), + ("expansion", "⠑⠭⠏⠁⠝⠨⠝"), + ("expectation", "⠑⠭⠏⠑⠉⠞⠁⠰⠝"), + ("extent", "⠑⠭⠞⠢⠞"), + ("feedback", "⠋⠑⠫⠃⠁⠉⠅"), + ("fidelity", "⠋⠊⠙⠑⠇⠰⠽"), + ("filament", "⠋⠊⠇⠁⠰⠞"), + ("hardness", "⠓⠜⠙⠰⠎"), + ("humidity", "⠓⠥⠍⠊⠙⠰⠽"), + ("hysteresis", "⠓⠽⠌⠻⠑⠎⠊⠎"), + ("illuminance", "⠊⠇⠇⠥⠍⠔⠨⠑"), + ("incidence", "⠔⠉⠊⠙⠰⠑"), + ("index", "⠔⠙⠑⠭"), + ("inflow", "⠔⠋⠇⠪"), + ("influx", "⠔⠋⠇⠥⠭"), + ("inhibition", "⠔⠓⠊⠃⠊⠰⠝"), + ("injection", "⠔⠚⠑⠉⠰⠝"), + ("irradiance", "⠊⠗⠗⠁⠙⠊⠨⠑"), + ("kinetic", "⠅⠔⠑⠞⠊⠉"), + ("leakage", "⠇⠂⠅⠁⠛⠑"), + ("luminance", "⠇⠥⠍⠔⠨⠑"), + ("maturity", "⠍⠁⠞⠥⠗⠰⠽"), + ("mean", "⠍⠂⠝"), + ("median", "⠍⠫⠊⠁⠝"), + ("melting", "⠍⠑⠇⠞⠬"), + ("minimum", "⠍⠔⠊⠍⠥⠍"), + ("mobility", "⠍⠕⠃⠊⠇⠰⠽"), + ("molarity", "⠍⠕⠇⠜⠰⠽"), + ("moisture", "⠍⠕⠊⠌⠥⠗⠑"), + ("opacity", "⠕⠏⠁⠉⠰⠽"), + ("oscillation", "⠕⠎⠉⠊⠇⠇⠁⠰⠝"), + ("outflow", "⠳⠞⠋⠇⠪"), + ("overlap", "⠕⠧⠻⠇⠁⠏"), + ("parallax", "⠏⠜⠁⠇⠇⠁⠭"), + ("parameter", "⠏⠜⠁⠍⠑⠞⠻"), + ("peak", "⠏⠂⠅"), + ("percentile", "⠏⠻⠉⠢⠞⠊⠇⠑"), + ("percentage", "⠏⠻⠉⠢⠞⠁⠛⠑"), + ("polarization", "⠏⠕⠇⠜⠊⠵⠁⠰⠝"), + ("propagation", "⠏⠗⠕⠏⠁⠛⠁⠰⠝"), + ("purity", "⠏⠥⠗⠰⠽"), + ("quality", "⠟⠥⠁⠇⠰⠽"), + ("quantity", "⠟⠥⠁⠝⠞⠰⠽"), + ("quenching", "⠟⠥⠢⠡⠬"), + ("quotient", "⠟⠥⠕⠞⠊⠢⠞"), + ("radiance", "⠗⠁⠙⠊⠨⠑"), + ("radiation", "⠗⠁⠙⠊⠁⠰⠝"), + ("reaction", "⠗⠑⠁⠉⠰⠝"), + ("reactivity", "⠗⠑⠁⠉⠞⠊⠧⠰⠽"), + ("redshift", "⠗⠫⠩⠊⠋⠞"), + ("reflectance", "⠗⠑⠋⠇⠑⠉⠞⠨⠑"), + ("reflection", "⠗⠑⠋⠇⠑⠉⠰⠝"), + ("refraction", "⠗⠑⠋⠗⠁⠉⠰⠝"), + ("reluctance", "⠗⠑⠇⠥⠉⠞⠨⠑"), + ("remanence", "⠗⠑⠍⠁⠝⠰⠑"), + ("resistivity", "⠗⠑⠎⠊⠌⠊⠧⠰⠽"), + ("resonance", "⠗⠑⠎⠕⠝⠨⠑"), + ("restitution", "⠗⠑⠌⠊⠞⠥⠰⠝"), + ("retardation", "⠗⠑⠞⠜⠙⠁⠰⠝"), + ("rigidity", "⠗⠊⠛⠊⠙⠰⠽"), + ("salinity", "⠎⠁⠇⠔⠰⠽"), + ("saturation", "⠎⠁⠞⠥⠗⠁⠰⠝"), + ("scalar", "⠎⠉⠁⠇⠜"), + ("scattering", "⠎⠉⠁⠞⠞⠻⠬"), + ("separation", "⠎⠑⠏⠜⠁⠰⠝"), + ("shrinkage", "⠩⠗⠔⠅⠁⠛⠑"), + ("similarity", "⠎⠊⠍⠊⠇⠜⠰⠽"), + ("battery", "⠃⠁⠞⠞⠻⠽"), + ("diameter", "⠙⠊⠁⠍⠑⠞⠻"), + ("epoch", "⠑⠏⠕⠡"), + ("gain", "⠛⠁⠔"), + ("jitter", "⠚⠊⠞⠞⠻"), + ("joule", "⠚⠳⠇⠑"), + ("momentum", "⠍⠕⠰⠞⠥⠍"), + ("shift", "⠩⠊⠋⠞"), + ("step", "⠌⠑⠏"), + ("stride", "⠌⠗⠊⠙⠑"), + ("zenith", "⠵⠢⠊⠹"), + ]; + const SHOULD_NOT_CONTRACT: &[&str] = &[ + "mass", "volume", "base", "rate", "drag", "drift", "gap", "lag", "loss", "pace", + "radius", "range", "ratio", "risk", "run", "scale", "size", "slope", "tax", "torque", + "capital", "impulse", "latitude", "magnitude", "premium", "pressure", "response", "return", + "trajectory", "voltage", "aspect", "backlog", "curvature", "dosage", "dose", "equilibrium", + "excess", "exposure", "fatigue", "hydraulic", "lifetime", "likelihood", "maximum", "metric", + "orbit", "osmosis", "pulse", "quanta", "quantum", "regret", "residual", "ripple", "root", + "rotor", "sag", "secant", "signal", "altitude", "amplitude", "angle", "bias", "bitrate", + "budget", "bulk", "decay", "deficit", "degree", "delay", "duty", "lift", "limit", "load", + "modulus", "payload", "phase", "price", "sample", "skew", "slack", "span", "supply", + "total", "value", "vector", "wage", "yield", + ]; + + for &(word, expected) in SHOULD_CONTRACT { + let got = contract_word(word); + assert_eq!(expected, got, "word '{word}'"); + assert_ne!(ascii_to_uncontracted_braille(word), got, "word '{word}' should contract"); + } + for &word in SHOULD_NOT_CONTRACT { + let got = contract_word(word); + let uncontracted = ascii_to_uncontracted_braille(word); + assert_eq!(uncontracted, got, "word '{word}' should not contract"); + } + } + + #[test] + #[ignore] + fn ueb_technical_word_contractions_probe_batch2() { + let try_contract = [ + "circumference", "capacity", "deceleration", "dilution", "enthalpy", "entropy", "equity", "expense", + "gradient", "headroom", "inertia", "latency", "longitude", "permittivity", "period", "principal", + "sensitivity", "stress", "throughput", "thrust", "wavelength", "absorption", "activation", "activity", + "admittance", "affinity", "albedo", "aperture", "attenuation", "average", "bandwidth", "baseline", + "bearing", "benchmark", "boiling", "boundary", "cohesion", "compliance", "compression", "conductivity", + "coverage", "damping", "deflection", "departure", "depreciation", "deviation", "diffusion", "dispersion", + "dissipation", "distortion", "divergence", "downforce", "elasticity", "emissivity", "emission", "erosion", + "evaporation", "expansion", "expectation", "extent", "feedback", "fidelity", "filament", "hardness", + "humidity", "hysteresis", "illuminance", "incidence", "index", "inflow", "influx", "inhibition", + "injection", "irradiance", "kinetic", "leakage", "luminance", "maturity", "mean", "median", "melting", + "minimum", "mobility", "molarity", "moisture", "opacity", "oscillation", "outflow", "overlap", "parallax", + "parameter", "peak", "percentile", "percentage", "polarization", "propagation", "purity", "quality", + "quantity", "quenching", "quotient", "radiance", "radiation", "reaction", "reactivity", "redshift", + "reflectance", "reflection", "refraction", "reluctance", "remanence", "resistivity", "resonance", + "restitution", "retardation", "rigidity", "salinity", "saturation", "scalar", "scattering", "separation", + "shrinkage", "similarity", "battery", "diameter", "epoch", "gain", "jitter", "joule", "momentum", "shift", + "step", "stride", "zenith", + ]; + let try_not = [ + "capital", "impulse", "latitude", "magnitude", "premium", "pressure", "response", "return", "trajectory", + "voltage", "aspect", "backlog", "curvature", "dosage", "dose", "equilibrium", "excess", "exposure", + "fatigue", "hydraulic", "lifetime", "likelihood", "maximum", "metric", "orbit", "osmosis", "pulse", + "quanta", "quantum", "regret", "residual", "ripple", "root", "rotor", "sag", "secant", "signal", + "altitude", "amplitude", "angle", "bias", "bitrate", "budget", "bulk", "decay", "deficit", "degree", + "delay", "duty", "lift", "limit", "load", "modulus", "payload", "phase", "price", "sample", "skew", + "slack", "span", "supply", "total", "value", "vector", "wage", "yield", + ]; + let mut out = String::new(); + for w in try_contract { + let c = contract_word(w); + out.push_str(&format!("(\"{w}\", \"{c}\"),\n")); + } + for w in try_not { + out.push_str(&format!("// no: {w}\n")); + } + let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("notes/_batch2_goldens.txt"); + std::fs::write(path, out).unwrap(); + } + + #[test] + #[ignore] + fn ueb_technical_word_contractions_probe() { + let should_contract = [ + "force", "work", "time", "speed", "distance", "area", "height", "weight", "power", "energy", + "density", "gravity", "acceleration", "length", "width", "depth", "cost", "profit", "interest", "revenue", + "clearance", "conductance", "capacitance", "resistance", "impedance", "reactance", "variance", "tolerance", + "luminosity", "reliability", "velocity", "viscosity", "precision", "tension", "efficiency", "frequency", + "valence", "stiffness", "thickness", "displacement", "concentration", "consumption", "duration", "elevation", + "fraction", "friction", "inflation", "iteration", "population", "position", "potential", "production", + "resolution", "rotation", "charge", "chord", "pitch", "growth", "head", "heat", "reach", "shear", "margin", + "salary", "offset", "income", "input", "inventory", "current", "error", "leverage", "temperature", + "turnover", "accuracy", "breadth", "strength", "spread", "discount", "count", "version", "inductance", + "intensity", "interval", "perimeter", "probability", "utility", "validity", "parity", "permeability", + "proportion", "uncertainty", + ]; + let should_not = [ + "mass", "volume", "base", "rate", "drag", "drift", "gap", "lag", "loss", "pace", + "radius", "range", "ratio", "risk", "run", "scale", "size", "slope", "tax", "torque", + ]; + eprintln!("=== SHOULD CONTRACT ==="); + for w in should_contract { + let c = contract_word(w); + let u = ascii_to_uncontracted_braille(w); + eprintln!("(\"{w}\", \"{c}\"), // uncontracted={u} changed={}", c != u); + } + eprintln!("=== SHOULD NOT CONTRACT ==="); + for w in should_not { + let c = contract_word(w); + let u = ascii_to_uncontracted_braille(w); + eprintln!("{w}: contracted={c} uncontracted={u} ok={}", c == u); + } + } } diff --git a/tests/braille/UEB/iceb.rs b/tests/braille/UEB/iceb.rs index 3bd48b19b..70eb878f8 100644 --- a/tests/braille/UEB/iceb.rs +++ b/tests/braille/UEB/iceb.rs @@ -1,7 +1,8 @@ // UEB tests for the basic mathml tags -// Initial tests are from BANA guidelines, mostly about initial chars for code switching -// http://www.brailleauthority.org/ueb/ueb_math_guidance/final_for_posting_ueb_math_guidance_may_2019_102419.pdf -// These tests start with "bana_" +// BANA guidance (2026; replaces 2019 provisional): +// https://www.brailleauthority.org/sites/default/files/2026-07/Guidance%20on%20Transcribing%20Math%20and%20Science%20in%20UEB%202026.pdf +// Older `bana_*` names map from 2019 section numbers where still valid; `bana2026_*` are new 2026 examples. +// Grade 1 indicators follow ICEB GTM §1.7 (adopted by BANA 2026). // // Many come from (refer to) https://iceb.org/guidelines_for_technical_material_2014.pdf // For example, "fraction_6_1_1" is a fraction example from section 6.1, and is the first example there. @@ -10,7 +11,8 @@ use anyhow::Result; #[test] fn bana_2_1() -> Result<()> { - let expr = "6=1×2×3 + // BANA 2026 Ex 2-1 (spacing of signs) + let expr = "6=1×2×3 =1+2+3"; test_braille("UEB", expr, "⠼⠋⠀⠐⠶⠀⠼⠁⠐⠦⠼⠃⠐⠦⠼⠉⠀⠐⠶⠀⠼⠁⠐⠖⠼⠃⠐⠖⠼⠉")?; return Ok(()); @@ -19,6 +21,7 @@ fn bana_2_1() -> Result<()> { #[test] fn bana_5_1() -> Result<()> { + // BANA 2026 Ex 5-1 let expr = "x+y=6"; test_braille("UEB", expr, "⠭⠐⠖⠽⠀⠐⠶⠀⠼⠋")?; return Ok(()); @@ -27,6 +30,7 @@ fn bana_5_1() -> Result<()> { #[test] fn bana_5_2() -> Result<()> { + // BANA 2026 Ex 5-7 let expr = "x2+y2=C"; test_braille("UEB", expr, "⠭⠰⠔⠼⠃⠐⠖⠽⠔⠼⠃⠀⠐⠶⠀⠰⠠⠉")?; return Ok(()); @@ -35,6 +39,7 @@ fn bana_5_2() -> Result<()> { #[test] fn bana_5_3() -> Result<()> { + // BANA 2026 Ex 5-10 let expr = "ab+cd"; test_braille("UEB", expr, "⠰⠰⠷⠁⠨⠌⠃⠾⠐⠖⠷⠉⠨⠌⠙⠾")?; return Ok(()); @@ -43,26 +48,27 @@ fn bana_5_3() -> Result<()> { #[test] fn bana_5_4() -> Result<()> { - let expr = "an×am= + // BANA 2026 Ex 5-14 (GTM 1.7: word indicator per sequence, not passage) + let expr = "an×am= an+m"; - test_braille("UEB", expr, "⠰⠰⠰⠁⠔⠝⠐⠦⠁⠔⠍⠀⠐⠶⠀⠁⠔⠣⠝⠐⠖⠍⠜⠰⠄")?; + test_braille("UEB", expr, "⠰⠰⠁⠔⠝⠐⠦⠁⠔⠍⠀⠐⠶⠀⠰⠰⠁⠔⠣⠝⠐⠖⠍⠜")?; return Ok(()); } #[test] fn bana_5_5() -> Result<()> { - let expr = "logxy"; - // BANA example contradicts GTM 9.2 that says don't use a space after a function name if there is an intervening indicator. - // Corrected: removed the space and the G1 indicator needed if a space were inserted - test_braille("UEB", expr, "⠰⠰⠇⠕⠛⠢⠭⠽")?; + // BANA 2026 Ex 5-8 (replaces 2019 log_x y example) + let expr = "log2x+logx"; + test_braille("UEB", expr, "⠇⠕⠛⠰⠢⠼⠃⠭⠐⠖⠇⠕⠛⠀⠰⠭")?; return Ok(()); } #[test] fn bana_5a_1() -> Result<()> { - let expr = "100°F"; + // Former 2019 §5(a) units example (dropped from BANA 2026); kept as unit-spacing practice + let expr = "100°F"; test_braille("UEB", expr, "⠼⠁⠚⠚⠘⠚⠠⠋")?; return Ok(()); @@ -70,7 +76,17 @@ fn bana_5a_1() -> Result<()> { #[test] fn bana_5a_1_baseline() -> Result<()> { - let expr = "100°F"; + // Former 2019 §5(a) units example (dropped from BANA 2026); kept as unit-spacing practice + let expr = "100°F"; + test_braille("UEB", expr, "⠼⠁⠚⠚⠘⠚⠠⠋")?; + return Ok(()); + +} + +#[test] +fn bana_5a_1_baseline_unit() -> Result<()> { + // Same as bana_5a_1_baseline; unit marked via data-intent-property + let expr = "100°F"; test_braille("UEB", expr, "⠼⠁⠚⠚⠘⠚⠠⠋")?; return Ok(()); @@ -78,22 +94,43 @@ fn bana_5a_1_baseline() -> Result<()> { #[test] fn bana_5a_2() -> Result<()> { + // Former 2019 §5(a) units example (dropped from BANA 2026); kept as unit-spacing practice let expr = "25 km2"; test_braille("UEB", expr, "⠼⠃⠑⠀⠅⠍⠰⠔⠼⠃")?; return Ok(()); } +#[test] +fn bana_5a_2_unit() -> Result<()> { + // Same as bana_5a_2; unit marked via data-intent-property + let expr = "25 km2"; + test_braille("UEB", expr, "⠼⠃⠑⠀⠅⠍⠰⠔⠼⠃")?; + return Ok(()); + +} + #[test] fn bana_5a_2_mtext() -> Result<()> { + // Former 2019 §5(a) units example (dropped from BANA 2026); kept as unit-spacing practice let expr = "25 km2"; test_braille("UEB", expr, "⠼⠃⠑⠀⠅⠍⠰⠔⠼⠃")?; return Ok(()); } +#[test] +fn bana_5a_2_mtext_unit() -> Result<()> { + // Same as bana_5a_2_mtext; unit marked via data-intent-property + let expr = "25 km2"; + test_braille("UEB", expr, "⠼⠃⠑⠀⠅⠍⠰⠔⠼⠃")?; + return Ok(()); + +} + #[test] fn bana_5a_3() -> Result<()> { + // Former 2019 §5(a) units example (dropped from BANA 2026); kept as unit-spacing practice let expr = "6 m  s-1"; test_braille("UEB", expr, "⠼⠋⠀⠰⠍⠀⠰⠰⠎⠔⠣⠐⠤⠼⠁⠜")?; @@ -101,11 +138,183 @@ fn bana_5a_3() -> Result<()> { } +#[test] +fn bana_5a_3_unit() -> Result<()> { + // Same as bana_5a_3; unit marked via data-intent-property + let expr = "6 m  + s-1"; + test_braille("UEB", expr, "⠼⠋⠀⠰⠍⠀⠰⠰⠎⠔⠣⠐⠤⠼⠁⠜")?; + return Ok(()); + +} + #[test] fn bana_6_1() -> Result<()> { + // Punctuation before G1 terminator (BANA 2026 §5.4 / GTM 1.7.3b note) let expr = "x+y=z =t2."; - test_braille("UEB", expr, "⠰⠰⠰⠭⠐⠖⠽⠀⠐⠶⠀⠵⠀⠐⠶⠀⠞⠔⠼⠃⠲⠰⠄")?; + test_braille("UEB", expr, "⠭⠐⠖⠽⠀⠐⠶⠀⠰⠵⠀⠐⠶⠀⠞⠰⠔⠼⠃⠲")?; + return Ok(()); + +} + +// --- BANA 2026 examples not covered by older bana_* tests --- + +#[test] +fn bana2026_2_2() -> Result<()> { + // BANA 2026 Ex 2-2: spaced operation signs for beginning readers + let expr = "6-3=_"; + test_braille_prefs("UEB", vec![("UseSpacesAroundAllOperators", "true")], expr, "⠼⠋⠀⠐⠤⠀⠼⠉⠀⠐⠶⠀⠨⠤")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_2() -> Result<()> { + // BANA 2026 Ex 5-2: words with contractions in a technical expression + let expr = "Surface area=2lh+2lw+2wh"; + test_braille("UEB", expr, "⠠⠎⠥⠗⠋⠁⠉⠑⠀⠜⠑⠁⠀⠐⠶⠀⠼⠃⠇⠓⠐⠖⠼⠃⠇⠺⠐⠖⠼⠃⠺⠓")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_3() -> Result<()> { + // BANA 2026 Ex 5-3 + let expr = "NaCl+H2O"; + test_braille("UEB", expr, "⠠⠝⠁⠠⠉⠇⠐⠖⠠⠓⠰⠢⠼⠃⠠⠕")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_4() -> Result<()> { + // BANA 2026 Ex 5-4 + let expr = "5x2y3z"; + test_braille("UEB", expr, "⠰⠷⠼⠑⠭⠔⠼⠃⠨⠌⠽⠔⠼⠉⠵⠾")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_5() -> Result<()> { + // BANA 2026 Ex 5-5: 1×3 matrix and column (linearized like other matrix_* tests) + let expr = r#" + (abc) + ( + -1 + 2 + -3 + ) + "#; + test_braille("UEB", expr, "⠠⠐⠣⠁⠀⠰⠃⠀⠉⠠⠐⠜⠠⠐⠣⠐⠤⠼⠁⠠⠐⠜⠸⠀⠠⠐⠣⠼⠃⠠⠐⠜⠸⠀⠠⠐⠣⠐⠤⠼⠉⠠⠐⠜")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_6() -> Result<()> { + // BANA 2026 Ex 5-6 + let expr = r#" + (ab) + (-x2y) + "#; + test_braille("UEB", expr, "⠠⠐⠣⠁⠀⠃⠠⠐⠜⠠⠐⠣⠐⠤⠭⠠⠐⠜⠸⠀⠠⠐⠣⠼⠃⠽⠠⠐⠜")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_9_slope() -> Result<()> { + // BANA 2026 Ex 5-9 (math fragments): slope 3/5 and parallel lines l₁ ∥ l₂ + let expr = "l1∥l2"; + test_braille("UEB", expr, "⠇⠰⠢⠼⠁⠀⠼⠇⠀⠇⠰⠢⠼⠃")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_11() -> Result<()> { + // BANA 2026 Ex 5-11 + let expr = "ab"; + test_braille("UEB", expr, "⠰⠰⠷⠁⠨⠌⠃⠾")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_12() -> Result<()> { + // BANA 2026 Ex 5-12: vector AB with arrow + let expr = "AB→"; + test_braille("UEB", expr, "⠰⠰⠣⠠⠠⠁⠃⠜⠘⠱")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_13() -> Result<()> { + // BANA 2026 Ex 5-13 + let expr = "x-1=1x"; + test_braille("UEB", expr, "⠰⠰⠭⠔⠣⠐⠤⠼⠁⠜⠀⠐⠶⠀⠰⠷⠼⠁⠨⠌⠭⠾")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_15() -> Result<()> { + // BANA 2026 Ex 5-15: all-caps print uses capital passage (⠠⠠⠠ … ⠠⠄) inside G1 passage + let expr = "P=VI=I2R=V2R"; + test_braille("UEB", expr, "⠰⠰⠰⠠⠠⠠⠏⠀⠐⠶⠀⠧⠊⠀⠐⠶⠀⠊⠔⠼⠃⠗⠀⠐⠶⠀⠷⠧⠔⠼⠃⠨⠌⠗⠾⠠⠄⠰⠄")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_16() -> Result<()> { + // BANA 2026 Ex 5-16: CaCO₃ ⇄ CaO + CO₂ + let expr = "CaCO3 + ⇄ + CaO+ + CO2"; + test_braille("UEB", expr, "⠰⠰⠰⠠⠉⠁⠠⠉⠠⠕⠢⠼⠉⠀⠳⠕⠻⠳⠪⠀⠠⠉⠁⠠⠕⠐⠖⠠⠉⠠⠕⠢⠼⠃⠰⠄")?; + return Ok(()); + +} + +#[test] +fn bana2026_7_1() -> Result<()> { + // BANA 2026 Ex 7-1: V = lim Δx→0 Σ f(xᵢ)Δx (single-line) + let expr = r#"V= + limΔx→0 + ∑i + f(xi)Δx + "#; + test_braille("UEB", expr, "⠰⠠⠧⠀⠐⠶⠀⠰⠰⠇⠊⠍⠨⠢⠣⠠⠨⠙⠭⠳⠕⠼⠚⠜⠠⠨⠎⠨⠢⠊⠋⠐⠣⠭⠢⠊⠐⠜⠠⠨⠙⠭")?; + return Ok(()); + +} + +#[test] +fn bana2026_7_2() -> Result<()> { + // BANA 2026 Ex 7-2: first step of radical simplification chain + let expr = r#"x= + 36-4(9)+3(12)18 + "#; + test_braille("UEB", expr, "⠰⠭⠀⠐⠶⠀⠰⠰⠷⠩⠼⠉⠋⠐⠤⠼⠙⠐⠣⠼⠊⠐⠜⠐⠖⠼⠉⠐⠣⠼⠁⠃⠐⠜⠬⠨⠌⠼⠁⠓⠾")?; + return Ok(()); + +} + +#[test] +fn bana2026_7_3() -> Result<()> { + // BANA 2026 Ex 7-3 + let expr = r#"x= + + 54+7-111×2+8000+1000 + -42 + + "#; + test_braille("UEB", expr, "⠰⠭⠀⠐⠶⠀⠰⠷⠼⠑⠙⠐⠖⠼⠛⠐⠤⠼⠁⠁⠁⠐⠦⠼⠃⠐⠖⠼⠓⠚⠚⠚⠐⠖⠼⠁⠚⠚⠚⠨⠌⠐⠤⠼⠙⠃⠾")?; return Ok(()); } @@ -167,7 +376,7 @@ fn grade1_1_7_2() -> Result<()> { #[test] fn grade1_1_7_3_1() -> Result<()> { let expr = " - 3x−4y+ + 3x−4y+ y2 = x2 @@ -193,13 +402,614 @@ fn grade1_1_7_3_2() -> Result<()> { #[test] fn grade1_1_7_4() -> Result<()> { let expr = " - (y−x2) + (y−x2) "; test_braille("UEB", expr, "⠰⠰⠩⠐⠣⠽⠐⠤⠭⠔⠼⠃⠐⠜⠬")?; return Ok(()); } +// Additional examples from GTM 1.7 (July 2025): +// https://iceb.org/wp-content/uploads/2026/02/GTM-1.7-Grade-1-Indicators-Approved.pdf +// Ordinary surrounding text is omitted; braille is the preferred math from the spec. + +#[test] +fn grade1_1_7_3_a_1() -> Result<()> { + let expr = "x2"; + test_braille("UEB", expr, "⠭⠰⠔⠼⠃")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_3_a_2() -> Result<()> { + let expr = "x→∞"; + test_braille("UEB", expr, "⠰⠭⠀⠰⠳⠕⠀⠼⠿")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_3_a_3() -> Result<()> { + let expr = "xy"; + test_braille("UEB", expr, "⠰⠰⠷⠭⠨⠌⠽⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_3_b_1() -> Result<()> { + let expr = "xa=xb + =xc"; + test_braille("UEB", expr, "⠰⠰⠰⠭⠢⠁⠀⠐⠶⠀⠭⠢⠃⠀⠐⠶⠀⠭⠢⠉⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_3_b_2() -> Result<()> { + let expr = "y=x2-4; +  y=x2-2x; +  y=x-x2."; + test_braille("UEB", expr, "⠰⠰⠰⠽⠀⠐⠶⠀⠭⠔⠼⠃⠐⠤⠼⠙⠆⠀⠽⠀⠐⠶⠀⠭⠔⠼⠃⠐⠤⠼⠃⠭⠆⠀⠽⠀⠐⠶⠀⠭⠐⠤⠭⠔⠼⠃⠲⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_4_1() -> Result<()> { + let expr = "x2-x-2 + =0"; + test_braille("UEB", expr, "⠭⠰⠔⠼⠃⠐⠤⠭⠐⠤⠼⠃⠀⠐⠶⠀⠼⠚")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_4_2() -> Result<()> { + let expr = "x2-4x-3 + =0"; + test_braille("UEB", expr, "⠭⠰⠔⠼⠃⠐⠤⠼⠙⠭⠐⠤⠼⠉⠀⠐⠶⠀⠼⠚")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_4_3() -> Result<()> { + let expr = "x2-1=0"; + test_braille("UEB", expr, "⠭⠰⠔⠼⠃⠐⠤⠼⠁⠀⠐⠶⠀⠼⠚")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_5_a() -> Result<()> { + let expr = "speed= + distancetime"; + // GTM 1.7.5(a) (2025): two grade 1 symbol indicators so the words stay contracted. + // After the fraction open, "dis" is not a word start (RUEB 10.6.2), so st+ance: ⠙⠊⠌⠨⠑. + test_braille("UEB", expr, "⠎⠏⠑⠫⠀⠐⠶⠀⠰⠷⠙⠊⠌⠨⠑⠨⠌⠐⠞⠰⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_5_b() -> Result<()> { + let expr = "luminositysun"; + test_braille("UEB", expr, "⠰⠰⠇⠥⠍⠊⠝⠕⠎⠊⠞⠽⠢⠣⠎⠥⠝⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_5_c() -> Result<()> { + let expr = "speed= + distancetime= + 30,000 m + 60 s= + 500 m/s"; + test_braille("UEB", expr, "⠎⠏⠑⠫⠀⠐⠶⠀⠰⠰⠰⠷⠙⠊⠎⠞⠁⠝⠉⠑⠨⠌⠞⠊⠍⠑⠾⠀⠐⠶⠀⠷⠼⠉⠚⠂⠚⠚⠚⠀⠍⠨⠌⠼⠋⠚⠀⠎⠾⠀⠐⠶⠀⠼⠑⠚⠚⠀⠍⠸⠌⠎⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_5_c_unit() -> Result<()> { + // Same as grade1_1_7_5_c; unit marked via data-intent-property + let expr = "speed= + distancetime= + 30,000 m + 60 s= + 500 m/s"; + test_braille("UEB", expr, "⠎⠏⠑⠫⠀⠐⠶⠀⠰⠰⠰⠷⠙⠊⠎⠞⠁⠝⠉⠑⠨⠌⠞⠊⠍⠑⠾⠀⠐⠶⠀⠷⠼⠉⠚⠂⠚⠚⠚⠀⠍⠨⠌⠼⠋⠚⠀⠎⠾⠀⠐⠶⠀⠼⠑⠚⠚⠀⠍⠸⠌⠎⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_1() -> Result<()> { + let expr = "y=x"; + test_braille("UEB", expr, "⠰⠽⠀⠐⠶⠀⠰⠭")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_2() -> Result<()> { + let expr = "25=5"; + test_braille("UEB", expr, "⠰⠩⠼⠃⠑⠬⠀⠐⠶⠀⠼⠑")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_3() -> Result<()> { + let expr = "x=7"; + test_braille("UEB", expr, "⠰⠰⠩⠭⠬⠀⠐⠶⠀⠼⠛")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_4() -> Result<()> { + let expr = "ms + -1"; + test_braille("UEB", expr, "⠰⠰⠍⠎⠔⠣⠐⠤⠼⠁⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_4_unit() -> Result<()> { + // Same as grade1_1_7_9_4; unit marked via data-intent-property + let expr = "ms + -1"; + test_braille("UEB", expr, "⠰⠰⠍⠎⠔⠣⠐⠤⠼⠁⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_5() -> Result<()> { + let expr = "y=x2"; + // GTM 1.7.9 (July 2025): one symbol indicator; numeric mode covers the closer. + test_braille("UEB", expr, "⠰⠽⠀⠐⠶⠀⠰⠷⠭⠨⠌⠼⠃⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_6() -> Result<()> { + let expr = "y=x22"; + test_braille("UEB", expr, "⠰⠽⠀⠐⠶⠀⠰⠰⠷⠭⠔⠼⠃⠨⠌⠼⠃⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_7() -> Result<()> { + let expr = "xy=cd"; + test_braille("UEB", expr, "⠰⠰⠷⠭⠨⠌⠽⠾⠀⠐⠶⠀⠰⠰⠷⠉⠨⠌⠙⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_8() -> Result<()> { + let expr = "(x,y)"; + test_braille("UEB", expr, "⠐⠣⠰⠭⠂⠀⠰⠽⠐⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_9() -> Result<()> { + let expr = "(xi,yi)"; + test_braille("UEB", expr, "⠐⠣⠭⠰⠢⠊⠂⠀⠽⠰⠢⠊⠐⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_10() -> Result<()> { + let expr = "(xi2, + yi2)"; + test_braille("UEB", expr, "⠰⠰⠐⠣⠭⠢⠊⠔⠼⠃⠂⠀⠰⠰⠽⠢⠊⠔⠼⠃⠐⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_11() -> Result<()> { + let expr = "B¯"; + test_braille("UEB", expr, "⠠⠃⠰⠱")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_12() -> Result<()> { + let expr = "M↔"; + test_braille("UEB", expr, "⠠⠍⠨⠔⠰⠳⠺⠗⠕")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_13() -> Result<()> { + let expr = "AZ + ↔"; + test_braille("UEB", expr, "⠰⠰⠣⠠⠠⠁⠵⠜⠨⠔⠳⠺⠗⠕")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_14() -> Result<()> { + let expr = "1327Al"; + test_braille("UEB", expr, "⠰⠢⠼⠁⠉⠔⠼⠃⠛⠠⠁⠇")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_15() -> Result<()> { + let expr = "O2-"; + test_braille("UEB", expr, "⠰⠰⠠⠕⠔⠣⠼⠃⠐⠤⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_16() -> Result<()> { + let expr = "2H2 + (g)+ + O2 + (g)→ + 2H2 + O(l)"; + test_braille("UEB", expr, "⠼⠃⠠⠓⠢⠼⠃⠐⠣⠛⠐⠜⠐⠖⠠⠕⠢⠼⠃⠐⠣⠛⠐⠜⠀⠰⠳⠕⠀⠼⠃⠠⠓⠢⠼⠃⠠⠕⠐⠣⠇⠐⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_17() -> Result<()> { + let expr = "y=mx+c"; + test_braille("UEB", expr, "⠰⠽⠀⠐⠶⠀⠍⠭⠐⠖⠉")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_18() -> Result<()> { + let expr = "A=πr2"; + test_braille("UEB", expr, "⠠⠁⠀⠐⠶⠀⠨⠏⠗⠰⠔⠼⠃")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_19() -> Result<()> { + let expr = "E=mc2"; + test_braille("UEB", expr, "⠰⠠⠑⠀⠐⠶⠀⠍⠉⠰⠔⠼⠃")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_20() -> Result<()> { + let expr = "x2-2x+1 + =(x-1)2"; + test_braille("UEB", expr, "⠭⠰⠔⠼⠃⠐⠤⠼⠃⠭⠐⠖⠼⠁⠀⠐⠶⠀⠐⠣⠭⠐⠤⠼⠁⠐⠜⠔⠼⠃")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_21() -> Result<()> { + let expr = "xn=1+ + -1nn"; + test_braille("UEB", expr, "⠭⠰⠢⠝⠀⠐⠶⠀⠼⠁⠐⠖⠷⠐⠤⠼⠁⠔⠝⠨⠌⠝⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_22() -> Result<()> { + let expr = "xn= + 2nn2"; + test_braille("UEB", expr, "⠭⠰⠢⠝⠀⠐⠶⠀⠰⠷⠼⠃⠔⠝⠨⠌⠝⠔⠼⠃⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_23() -> Result<()> { + let expr = "x= + + −b± + b2−4ac + + 2a + + "; + test_braille("UEB", expr, "⠰⠭⠀⠐⠶⠀⠰⠰⠷⠐⠤⠃⠸⠖⠩⠃⠔⠼⠃⠐⠤⠼⠙⠰⠁⠉⠬⠨⠌⠼⠃⠰⠁⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_24() -> Result<()> { + let expr = "xsinθ"; + test_braille("UEB", expr, "⠰⠰⠭⠩⠎⠊⠝⠨⠹⠬")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_25() -> Result<()> { + let expr = "Version1b"; + test_braille("UEB", expr, "⠰⠰⠠⠧⠑⠗⠎⠊⠕⠝⠔⠣⠼⠁⠰⠃⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_26() -> Result<()> { + let expr = "W=Fs"; + test_braille("UEB", expr, "⠰⠠⠺⠀⠐⠶⠀⠠⠋⠎")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_27() -> Result<()> { + let expr = "work=force×distance"; + test_braille("UEB", expr, "⠐⠺⠀⠐⠶⠀⠿⠉⠑⠐⠦⠙⠊⠌⠨⠑")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_28() -> Result<()> { + let expr = "∴force= + workdistance"; + test_braille("UEB", expr, "⠰⠠⠡⠀⠿⠉⠑⠀⠐⠶⠀⠰⠷⠐⠺⠨⠌⠙⠊⠌⠨⠑⠰⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_29() -> Result<()> { + let expr = "acceleration= + Δspeed + Δtime"; + test_braille("UEB", expr, "⠁⠒⠑⠇⠻⠁⠰⠝⠀⠐⠶⠀⠰⠷⠠⠨⠙⠎⠏⠑⠫⠨⠌⠠⠨⠙⠐⠞⠰⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_30() -> Result<()> { + let expr = "frequency=1time"; + test_braille("UEB", expr, "⠋⠗⠑⠟⠥⠢⠉⠽⠀⠐⠶⠀⠰⠷⠼⠁⠨⠌⠞⠊⠍⠑⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_31() -> Result<()> { + let expr = "frequency=1/time"; + test_braille("UEB", expr, "⠋⠗⠑⠟⠥⠢⠉⠽⠀⠐⠶⠀⠼⠁⠸⠌⠞⠊⠍⠑")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_32() -> Result<()> { + let expr = "Vcone= + 13π + r2h"; + test_braille("UEB", expr, "⠰⠰⠠⠧⠢⠣⠉⠕⠝⠑⠜⠀⠐⠶⠀⠼⠁⠌⠉⠨⠏⠗⠔⠼⠃⠰⠓")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_33() -> Result<()> { + let expr = "V=∫π + y2dx"; + test_braille("UEB", expr, "⠰⠠⠧⠀⠐⠶⠀⠰⠰⠮⠨⠏⠽⠔⠼⠃⠰⠙⠭")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_34() -> Result<()> { + let expr = "period=2π + + lcosα + g + "; + test_braille("UEB", expr, "⠏⠻⠊⠕⠙⠀⠐⠶⠀⠼⠃⠨⠏⠩⠷⠇⠀⠰⠰⠉⠕⠎⠨⠁⠨⠌⠛⠾⠬")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_35() -> Result<()> { + let expr = "Assume g=9.81  + ms + -2"; + test_braille("UEB", expr, "⠠⠁⠎⠎⠥⠍⠑⠀⠰⠛⠀⠐⠶⠀⠼⠊⠲⠓⠁⠀⠰⠰⠍⠎⠔⠣⠐⠤⠼⠃⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_35_unit() -> Result<()> { + // Same as grade1_1_7_9_35; unit marked via data-intent-property + let expr = "Assume g=9.81  + ms + -2"; + test_braille("UEB", expr, "⠠⠁⠎⠎⠥⠍⠑⠀⠰⠛⠀⠐⠶⠀⠼⠊⠲⠓⠁⠀⠰⠰⠍⠎⠔⠣⠐⠤⠼⠃⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_36() -> Result<()> { + let expr = "v1=x  + ms + -1"; + test_braille("UEB", expr, "⠰⠰⠰⠧⠢⠼⠁⠀⠐⠶⠀⠭⠀⠍⠎⠔⠣⠐⠤⠼⠁⠜⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_36_unit() -> Result<()> { + // Same as grade1_1_7_9_36; unit marked via data-intent-property + let expr = "v1=x  + ms + -1"; + test_braille("UEB", expr, "⠰⠰⠰⠧⠢⠼⠁⠀⠐⠶⠀⠭⠀⠍⠎⠔⠣⠐⠤⠼⠁⠜⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_37() -> Result<()> { + let expr = "P= + t,u,v"; + test_braille("UEB", expr, "⠰⠰⠰⠠⠏⠀⠐⠶⠀⠸⠣⠞⠂⠀⠥⠂⠀⠧⠸⠜⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_38() -> Result<()> { + let expr = "xa=xb + =xc=xd"; + test_braille("UEB", expr, "⠰⠰⠰⠭⠢⠁⠀⠐⠶⠀⠭⠢⠃⠀⠐⠶⠀⠭⠢⠉⠀⠐⠶⠀⠭⠢⠙⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_39() -> Result<()> { + let expr = "x2×x3 + =x2+3 + =x5"; + test_braille("UEB", expr, "⠰⠰⠰⠭⠔⠼⠃⠐⠦⠭⠔⠼⠉⠀⠐⠶⠀⠭⠔⠣⠼⠃⠐⠖⠼⠉⠜⠀⠐⠶⠀⠭⠔⠼⠑⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_40() -> Result<()> { + let expr = "am×an + =am+n"; + test_braille("UEB", expr, "⠰⠰⠁⠔⠍⠐⠦⠁⠔⠝⠀⠐⠶⠀⠰⠰⠁⠔⠣⠍⠐⠖⠝⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_41() -> Result<()> { + let expr = "(am)n + =amn"; + test_braille("UEB", expr, "⠰⠰⠐⠣⠁⠔⠍⠐⠜⠔⠝⠀⠐⠶⠀⠰⠰⠁⠔⠣⠍⠝⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_42() -> Result<()> { + let expr = "aman + =am-n"; + test_braille("UEB", expr, "⠰⠰⠷⠁⠔⠍⠨⠌⠁⠔⠝⠾⠀⠐⠶⠀⠰⠰⠁⠔⠣⠍⠐⠤⠝⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_43() -> Result<()> { + let expr = "a-m + =1am"; + test_braille("UEB", expr, "⠰⠰⠁⠔⠣⠐⠤⠍⠜⠀⠐⠶⠀⠰⠷⠼⠁⠨⠌⠁⠔⠍⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_44() -> Result<()> { + let expr = "a0=1"; + test_braille("UEB", expr, "⠁⠰⠔⠼⠚⠀⠐⠶⠀⠼⠁")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_45() -> Result<()> { + let expr = "a1n + =an"; + test_braille("UEB", expr, "⠰⠰⠁⠔⠷⠼⠁⠨⠌⠝⠾⠀⠐⠶⠀⠰⠰⠩⠔⠝⠁⠬")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_46() -> Result<()> { + let expr = "B→C"; + test_braille("UEB", expr, "⠰⠰⠰⠠⠃⠀⠳⠕⠀⠠⠉⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_47() -> Result<()> { + let expr = "x+y=5"; + test_braille("UEB", expr, "⠭⠐⠖⠽⠀⠐⠶⠀⠼⠑")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_48() -> Result<()> { + let expr = "CH4 + +4Cl2 + → + CCl4 + +4HCl"; + test_braille("UEB", expr, "⠰⠰⠰⠠⠉⠠⠓⠢⠼⠙⠐⠖⠼⠙⠠⠉⠇⠢⠼⠃⠀⠳⠕⠀⠠⠉⠠⠉⠇⠢⠼⠙⠐⠖⠼⠙⠠⠓⠠⠉⠇⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_49() -> Result<()> { + let expr = "614C + → + 714N + + + -10β"; + test_braille("UEB", expr, "⠰⠰⠰⠢⠼⠋⠔⠼⠁⠙⠠⠉⠀⠳⠕⠀⠢⠼⠛⠔⠼⠁⠙⠠⠝⠐⠖⠢⠣⠐⠤⠼⠁⠜⠔⠼⠚⠨⠃⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_50() -> Result<()> { + let expr = "reliability= + number of faultstotal number of items + =p"; + test_braille("UEB", expr, "⠰⠰⠰⠗⠑⠇⠊⠁⠃⠊⠇⠊⠞⠽⠀⠐⠶⠀⠷⠝⠥⠍⠃⠑⠗⠀⠕⠋⠀⠋⠁⠥⠇⠞⠎⠨⠌⠞⠕⠞⠁⠇⠀⠝⠥⠍⠃⠑⠗⠀⠕⠋⠀⠊⠞⠑⠍⠎⠾⠀⠐⠶⠀⠏⠰⠄")?; + return Ok(()); + +} + #[test] fn number_2_1_2() -> Result<()> { let expr = "3,000"; @@ -313,7 +1123,7 @@ fn bold_2_7_3() -> Result<()> { fn signs_2_10_2() -> Result<()> { let expr = "$0.30,  30c  - or 30¢"; + or 30¢"; test_braille("UEB", expr, "⠈⠎⠼⠚⠲⠉⠚⠂⠀⠼⠉⠚⠰⠉⠀⠕⠗⠀⠼⠉⠚⠈⠉")?; return Ok(()); @@ -323,7 +1133,7 @@ fn signs_2_10_2() -> Result<()> { fn signs_2_10_5() -> Result<()> { let expr = "1 ft 6 in  or  - 1′ 6′′"; + 1′ 6′′"; test_braille("UEB", expr, "⠼⠁⠀⠋⠞⠀⠼⠋⠀⠔⠀⠕⠗⠀⠼⠁⠶⠀⠼⠋⠶⠶")?; return Ok(()); @@ -331,8 +1141,8 @@ fn signs_2_10_5() -> Result<()> { #[test] fn signs_2_10_8() -> Result<()> { - let expr = "0°C or -  32°F"; + let expr = "0°C or +  32°F"; test_braille("UEB", expr, "⠼⠚⠘⠚⠠⠉⠀⠕⠗⠀⠼⠉⠃⠘⠚⠠⠋")?; return Ok(()); @@ -340,9 +1150,9 @@ fn signs_2_10_8() -> Result<()> { #[test] fn signs_2_10_16() -> Result<()> { - let expr = "1 Å= + let expr = "1 Å= 110,000  - μ"; + μ"; test_braille("UEB", expr, "⠼⠁⠀⠠⠘⠫⠁⠀⠐⠶⠀⠼⠁⠌⠁⠚⠂⠚⠚⠚⠀⠨⠍")?; return Ok(()); @@ -384,7 +1194,7 @@ fn expr_3_1_2() -> Result<()> { #[test] fn expr_3_1_3() -> Result<()> { - let expr = "3×5=5×3=15"; + let expr = "3×5=5×3=15"; test_braille("UEB", expr, "⠼⠉⠐⠦⠼⠑⠀⠐⠶⠀⠼⠑⠐⠦⠼⠉⠀⠐⠶⠀⠼⠁⠑")?; return Ok(()); @@ -393,7 +1203,7 @@ fn expr_3_1_3() -> Result<()> { #[test] fn expr_3_1_6() -> Result<()> { // example includes spaces, so does the MathML (from WIRIS) - let expr = "5.72 m÷10= + let expr = "5.72 m÷10= 57.2 cm"; test_braille("UEB", expr, "⠼⠑⠲⠛⠃⠀⠍⠐⠌⠼⠁⠚⠀⠐⠶⠀⠼⠑⠛⠲⠃⠀⠉⠍")?; return Ok(()); @@ -402,7 +1212,7 @@ fn expr_3_1_6() -> Result<()> { #[test] fn expr_3_1_7() -> Result<()> { - let expr = "15±0.5"; + let expr = "15±0.5"; test_braille("UEB", expr, "⠼⠁⠑⠸⠖⠼⠚⠲⠑")?; return Ok(()); @@ -411,7 +1221,7 @@ fn expr_3_1_7() -> Result<()> { #[test] fn expr_3_1_8() -> Result<()> { let expr = "Area=bh= - 5·3=15"; + 5·3=15"; test_braille("UEB", expr, "⠠⠜⠑⠁⠀⠐⠶⠀⠃⠓⠀⠐⠶⠀⠼⠑⠐⠲⠼⠉⠀⠐⠶⠀⠼⠁⠑")?; return Ok(()); @@ -419,7 +1229,7 @@ fn expr_3_1_8() -> Result<()> { #[test] fn expr_3_1_9_wiris() -> Result<()> { - let expr = "3.9×4.1≃16"; + let expr = "3.9×4.1≃16"; test_braille("UEB", expr, "⠼⠉⠲⠊⠐⠦⠼⠙⠲⠁⠀⠸⠔⠀⠼⠁⠋")?; return Ok(()); @@ -427,7 +1237,7 @@ fn expr_3_1_9_wiris() -> Result<()> { #[test] fn expr_3_1_9() -> Result<()> { - let expr = "3.9×4.1≃16"; + let expr = "3.9×4.1≃16"; test_braille("UEB", expr, "⠼⠉⠲⠊⠐⠦⠼⠙⠲⠁⠀⠸⠔⠀⠼⠁⠋")?; return Ok(()); @@ -435,7 +1245,7 @@ fn expr_3_1_9() -> Result<()> { #[test] fn expr_3_1_10() -> Result<()> { - let expr = "5-3≠3-5"; + let expr = "5-3≠3-5"; test_braille("UEB", expr, "⠼⠑⠐⠤⠼⠉⠀⠐⠶⠈⠱⠀⠼⠉⠐⠤⠼⠑")?; return Ok(()); @@ -459,7 +1269,7 @@ fn ratio_3_1_12() -> Result<()> { #[test] fn alg_3_2_1_1() -> Result<()> { - let expr = "y∝x"; + let expr = "y∝x"; test_braille("UEB", expr, "⠰⠽⠀⠸⠐⠶⠀⠰⠭")?; return Ok(()); @@ -475,8 +1285,8 @@ fn alg_3_2_1_2() -> Result<()> { #[test] fn alg_3_2_2() -> Result<()> { - let expr = "0≤θ - ≤2π"; + let expr = "0≤θ + ≤2π"; test_braille("UEB", expr, "⠼⠚⠀⠸⠈⠣⠀⠨⠹⠀⠸⠈⠣⠀⠼⠃⠨⠏")?; return Ok(()); @@ -502,10 +1312,7 @@ fn alg_3_2_4() -> Result<()> { #[test] fn alg_3_2_5() -> Result<()> { let expr = "d+ab=ac"; - // BANA says use a word indicator if G1 not in first 3 cells (it is after the '='); use passage if >=2 whitespace - // This seems like a poor choice in this case since there is only one G1 indicator, but that's the BANA guidance so... - // "⠰⠰⠰⠙⠐⠖⠁⠃⠀⠐⠶⠀⠁⠉⠰⠄" - // GTM says to use the following and it is more sensisble, so I'm going with it + // GTM 1.7 / BANA 2026: one G1 symbol for standing-alone 'a' after '=' test_braille("UEB", expr, "⠙⠐⠖⠁⠃⠀⠐⠶⠀⠰⠁⠉")?; return Ok(()); @@ -541,10 +1348,10 @@ fn example_3_4_1() -> Result<()> { fn example_3_4_2() -> Result<()> { // removed some cruft from TeX output of {}^{-}2+{}^{+}3, but the basics are preserved let expr = " - − + − 2 + - − + − 3 "; test_braille("UEB", expr, "⠰⠔⠐⠤⠼⠃⠐⠖⠔⠐⠤⠼⠉")?; @@ -578,7 +1385,7 @@ fn omission_3_6_3() -> Result<()> { #[test] fn omission_3_6_4() -> Result<()> { - let expr = "3□7=10"; + let expr = "3□7=10"; test_braille("UEB", expr, "⠼⠉⠫⠼⠙⠱⠼⠛⠀⠐⠶⠀⠼⠁⠚")?; return Ok(()); @@ -637,9 +1444,21 @@ fn fraction_6_2_1() -> Result<()> { #[test] fn fraction_6_2_2() -> Result<()> { let expr = "1750 -  cm= +  cm= + 134 +  m"; + test_braille("UEB", expr, "⠼⠁⠛⠑⠚⠀⠉⠍⠀⠐⠶⠀⠼⠁⠼⠉⠌⠙⠀⠰⠍")?; + return Ok(()); + +} + +#[test] +fn fraction_6_2_2_unit() -> Result<()> { + // Same as fraction_6_2_2; unit marked via data-intent-property + let expr = "1750 +  cm= 134 -  m"; +  m"; test_braille("UEB", expr, "⠼⠁⠛⠑⠚⠀⠉⠍⠀⠐⠶⠀⠼⠁⠼⠉⠌⠙⠀⠰⠍")?; return Ok(()); @@ -648,26 +1467,30 @@ fn fraction_6_2_2() -> Result<()> { #[test] fn fraction_6_2_2_unicode_frac() -> Result<()> { let expr = "1750 -  cm= - 1¾ -  m"; +  cm= + 1¾ +  m"; test_braille("UEB", expr, "⠼⠁⠛⠑⠚⠀⠉⠍⠀⠐⠶⠀⠼⠁⠼⠉⠌⠙⠀⠰⠍")?; return Ok(()); } #[test] -fn fraction_6_3_1() -> Result<()> { - let expr = "3/8"; - test_braille("UEB", expr, "⠼⠉⠸⠌⠼⠓")?; +fn fraction_6_2_2_unicode_frac_unit() -> Result<()> { + // Same as fraction_6_2_2_unicode_frac; unit marked via data-intent-property + let expr = "1750 +  cm= + 1¾ +  m"; + test_braille("UEB", expr, "⠼⠁⠛⠑⠚⠀⠉⠍⠀⠐⠶⠀⠼⠁⠼⠉⠌⠙⠀⠰⠍")?; return Ok(()); } #[test] -fn fraction_6_4_1() -> Result<()> { - let expr = "y=x2"; - test_braille("UEB", expr, "⠰⠰⠰⠽⠀⠐⠶⠀⠷⠭⠨⠌⠼⠃⠾⠰⠄")?; +fn fraction_6_3_1() -> Result<()> { + let expr = "3/8"; + test_braille("UEB", expr, "⠼⠉⠸⠌⠼⠓")?; return Ok(()); } @@ -716,8 +1539,9 @@ fn fraction_6_4_5() -> Result<()> { #[test] fn fraction_6_4_6() -> Result<()> { let expr = "speed=distancetime"; - // GTM lists two options: "⠎⠏⠑⠫⠀⠐⠶⠀⠰⠰⠷⠙⠊⠎⠞⠁⠝⠉⠑⠨⠌⠞⠊⠍⠑⠾" and "⠰⠰⠰⠎⠏⠑⠑⠙⠀⠐⠶⠀⠷⠙⠊⠎⠞⠁⠝⠉⠑⠨⠌⠞⠊⠍⠑⠾⠰⠄" - test_braille("UEB", expr, "⠎⠏⠑⠫⠀⠐⠶⠀⠰⠰⠷⠙⠊⠎⠞⠁⠝⠉⠑⠨⠌⠞⠊⠍⠑⠾")?; + // GTM 2014 §6.4 listed word-indicator and passage alternatives (uncontracted words). + // GTM 1.7.5(a) (2025) prefers two grade 1 symbol indicators with contracted words. + test_braille("UEB", expr, "⠎⠏⠑⠫⠀⠐⠶⠀⠰⠷⠙⠊⠌⠨⠑⠨⠌⠐⠞⠰⠾")?; return Ok(()); } @@ -766,7 +1590,7 @@ fn msup_7_3_7() -> Result<()> { #[test] fn msup_7_3_11() -> Result<()> { let expr = "xaby=x"; - test_braille("UEB", expr, "⠰⠰⠰⠭⠔⠷⠁⠨⠌⠃⠾⠽⠀⠐⠶⠀⠭⠰⠄")?; + test_braille("UEB", expr, "⠰⠰⠭⠔⠷⠁⠨⠌⠃⠾⠽⠀⠐⠶⠀⠰⠭")?; return Ok(()); } @@ -798,7 +1622,7 @@ fn msub_7_4_3() -> Result<()> { #[test] fn msup_7_5_1() -> Result<()> { let expr = "0.0045= - 4.5×10-3 + 4.5×10-3 "; test_braille("UEB", expr, "⠼⠚⠲⠚⠚⠙⠑⠀⠐⠶⠀⠼⠙⠲⠑⠐⠦⠼⠁⠚⠔⠣⠐⠤⠼⠉⠜")?; return Ok(()); @@ -824,7 +1648,7 @@ fn msup_7_6_2() -> Result<()> { #[test] fn msubsup_7_7_1() -> Result<()> { let expr = "x12=y23"; - test_braille("UEB", expr, "⠰⠰⠰⠭⠢⠼⠁⠔⠼⠃⠀⠐⠶⠀⠽⠢⠼⠃⠔⠼⠉⠰⠄")?; + test_braille("UEB", expr, "⠭⠰⠢⠼⠁⠔⠼⠃⠀⠐⠶⠀⠽⠰⠢⠼⠃⠔⠼⠉")?; return Ok(()); } @@ -852,7 +1676,7 @@ fn pre_sup_7_8_2() -> Result<()> { +3- =5- "; - test_braille("UEB", expr, "⠰⠰⠰⠔⠐⠤⠼⠃⠐⠖⠔⠐⠤⠼⠉⠀⠐⠶⠀⠔⠐⠤⠼⠑⠰⠄")?; + test_braille("UEB", expr, "⠰⠔⠐⠤⠼⠃⠐⠖⠔⠐⠤⠼⠉⠀⠐⠶⠀⠰⠔⠐⠤⠼⠑")?; return Ok(()); } @@ -860,9 +1684,9 @@ fn pre_sup_7_8_2() -> Result<()> { #[test] fn sum_7_9_1() -> Result<()> { - let expr = "∑x=1n + let expr = "∑x=1n xi2"; - test_braille("UEB", expr, "⠰⠰⠠⠨⠎⠨⠢⠣⠭⠐⠶⠼⠁⠜⠨⠔⠝⠭⠢⠊⠔⠼⠃")?; + test_braille("UEB", expr, "⠠⠨⠎⠨⠢⠰⠣⠭⠐⠶⠼⠁⠜⠨⠔⠝⠭⠢⠊⠔⠼⠃")?; return Ok(()); } @@ -870,7 +1694,7 @@ fn sum_7_9_1() -> Result<()> { #[test] fn lim_7_9_2() -> Result<()> { // Note: modified because passage indicator is not needed (same expr when word indicator is used) - let expr = "limx→a + let expr = "limx→a f(x)=1"; test_braille("UEB", expr, "⠰⠰⠇⠊⠍⠨⠢⠣⠭⠳⠕⠁⠜⠋⠐⠣⠭⠐⠜⠀⠐⠶⠀⠼⠁")?; return Ok(()); @@ -889,7 +1713,7 @@ fn sqrt_8_1_1() -> Result<()> { fn sqrt_8_1_2() -> Result<()> { let expr = "r= x2+y2"; - test_braille("UEB", expr, "⠰⠰⠰⠗⠀⠐⠶⠀⠩⠭⠔⠼⠃⠐⠖⠽⠔⠼⠃⠬⠰⠄")?; + test_braille("UEB", expr, "⠰⠗⠀⠐⠶⠀⠰⠰⠩⠭⠔⠼⠃⠐⠖⠽⠔⠼⠃⠬")?; return Ok(()); } @@ -899,7 +1723,7 @@ fn sqrt_8_1_3() -> Result<()> { let expr = " - 783.2×6.547 + 783.2×6.547 0.4628 @@ -915,17 +1739,17 @@ fn sqrt_8_1_4() -> Result<()> { x = - −b± + −b± b 2 - −4ac + −4ac 2a "; - test_braille("UEB", expr, "⠰⠰⠰⠭⠀⠐⠶⠀⠷⠐⠤⠃⠸⠖⠩⠃⠔⠼⠃⠐⠤⠼⠙⠰⠁⠉⠬⠨⠌⠼⠃⠰⠁⠾⠰⠄")?; + test_braille("UEB", expr, "⠰⠭⠀⠐⠶⠀⠰⠰⠷⠐⠤⠃⠸⠖⠩⠃⠔⠼⠃⠐⠤⠼⠙⠰⠁⠉⠬⠨⠌⠼⠃⠰⠁⠾")?; return Ok(()); } @@ -946,7 +1770,7 @@ fn root_8_2_2() -> Result<()> { y3+ z3 3"; - test_braille("UEB", expr, "⠰⠰⠰⠟⠀⠐⠶⠀⠩⠔⠼⠉⠭⠔⠼⠉⠐⠖⠽⠔⠼⠉⠐⠖⠵⠔⠼⠉⠬⠰⠄")?; + test_braille("UEB", expr, "⠰⠟⠀⠐⠶⠀⠰⠰⠩⠔⠼⠉⠭⠔⠼⠉⠐⠖⠽⠔⠼⠉⠐⠖⠵⠔⠼⠉⠬")?; return Ok(()); } @@ -992,7 +1816,7 @@ fn spacing_9_3_1_1() -> Result<()> { #[test] fn spacing_9_3_1_2() -> Result<()> { - let expr = "3tan45°"; + let expr = "3tan45°"; test_braille("UEB", expr, "⠼⠉⠞⠁⠝⠼⠙⠑⠘⠚")?; return Ok(()); @@ -1016,7 +1840,7 @@ fn spacing_9_3_2_1() -> Result<()> { #[test] fn spacing_9_3_2_2() -> Result<()> { - let expr = "sinθ"; + let expr = "sinθ"; test_braille("UEB", expr, "⠎⠔⠨⠹")?; return Ok(()); @@ -1041,7 +1865,9 @@ fn spacing_9_3_2_4() -> Result<()> { #[test] fn spacing_9_3_2_5() -> Result<()> { let expr = "Limx2"; - test_braille("UEB", expr, "⠰⠰⠠⠇⠊⠍⠷⠭⠨⠌⠼⠃⠾")?; + // GTM 2014 9.3.2 used a word indicator (;;,lim(x./#b)). GTM 1.7.3(a): one + // symbol indicator on the fraction open; numeric mode covers the closer. + test_braille("UEB", expr, "⠠⠇⠊⠍⠰⠷⠭⠨⠌⠼⠃⠾")?; return Ok(()); } @@ -1091,8 +1917,8 @@ fn spacing_9_3_3_5() -> Result<()> { #[test] fn spacing_9_3_3_6() -> Result<()> { - let expr = "sin2β= - 2sinβcosβ"; + let expr = "sin2β= + 2sinβcosβ"; test_braille("UEB", expr, "⠎⠔⠼⠃⠨⠃⠀⠐⠶⠀⠼⠃⠎⠊⠝⠨⠃⠉⠕⠎⠨⠃")?; return Ok(()); @@ -1121,9 +1947,9 @@ fn text_9_7_1() -> Result<()> { fn stat_9_7_2() -> Result<()> { let expr = "Exp(R)= n2+1"; - // GTM uses "⠰⠰⠰⠠⠑⠭⠏⠐⠣⠠⠗⠐⠜⠀⠐⠶⠀⠷⠝⠨⠌⠼⠃⠾⠐⠖⠼⠁⠰⠄", - // but "⠠⠑⠭⠏⠐⠣⠠⠗⠐⠜⠀⠐⠶⠀⠰⠰⠷⠝⠨⠌⠼⠃⠾⠐⠖⠼⠁" is shorter and is consistent with omission_3_6_7 and fraction_6_4_6 - test_braille("UEB", expr, "⠠⠑⠭⠏⠐⠣⠠⠗⠐⠜⠀⠐⠶⠀⠰⠰⠷⠝⠨⠌⠼⠃⠾⠐⠖⠼⠁")?; + // GTM 2014 9.7 used a passage around the whole equation. GTM 1.7.3(a): one + // symbol indicator on n/2 (same as grade1_1_7_9_5). + test_braille("UEB", expr, "⠠⠑⠭⠏⠐⠣⠠⠗⠐⠜⠀⠐⠶⠀⠰⠷⠝⠨⠌⠼⠃⠾⠐⠖⠼⠁")?; return Ok(()); } @@ -1141,7 +1967,7 @@ fn set_10_1() -> Result<()> { #[test] fn set_10_3() -> Result<()> { - let expr = "3∈A∩B"; + let expr = "3∈A∩B"; test_braille("UEB", expr, "⠼⠉⠀⠘⠑⠀⠠⠁⠨⠦⠠⠃")?; return Ok(()); @@ -1149,7 +1975,7 @@ fn set_10_3() -> Result<()> { #[test] fn set_10_4() -> Result<()> { - let expr = "A∩B⊂A∪B"; + let expr = "A∩B⊂A∪B"; test_braille("UEB", expr, "⠠⠁⠨⠦⠠⠃⠀⠘⠣⠀⠠⠁⠨⠖⠠⠃")?; return Ok(()); @@ -1158,7 +1984,7 @@ fn set_10_4() -> Result<()> { fn set_10_5() -> Result<()> { let expr = "A'∪B'= (A∩B)'"; - test_braille("UEB", expr, "⠰⠰⠰⠠⠁⠶⠨⠖⠠⠃⠶⠀⠐⠶⠀⠐⠣⠠⠁⠨⠦⠠⠃⠐⠜⠶⠰⠄")?; + test_braille("UEB", expr, "⠰⠰⠠⠁⠶⠨⠖⠠⠃⠶⠀⠐⠶⠀⠐⠣⠠⠁⠨⠦⠠⠃⠐⠜⠰⠶")?; return Ok(()); } @@ -1166,11 +1992,9 @@ fn set_10_5() -> Result<()> { #[test] fn set_10_6() -> Result<()> { // Note: example uses the wrong char "├" in the display -- should be "⊢" - let expr = "[(p∨q)∧¬p] + let expr = "[(p∨q)∧¬p] ⊢q"; - // Acceptable: GTM does uses a G1 passage indicator: "⠰⠰⠰⠨⠣⠐⠣⠏⠈⠖⠟⠐⠜⠈⠦⠈⠹⠏⠨⠜⠀⠸⠒⠀⠟⠰⠄" - // However, the BANA G1 standing alone rule ("...before a single letter standing alone") applies, so start in G2 mode. - // Corrected to remove the passage indicator + // GTM / BANA 2026: grade 1 passage test_braille("UEB", expr, "⠨⠣⠐⠣⠏⠈⠖⠟⠐⠜⠈⠦⠈⠹⠏⠨⠜⠀⠸⠒⠀⠰⠟")?; return Ok(()); @@ -1187,9 +2011,7 @@ fn example_11_5_1_2() -> Result<()> { #[test] fn example_11_5_1_3() -> Result<()> { let expr = "f'(x)"; - // Acceptable: GTM uses a G1 start indicator: "⠰⠰⠋⠶⠐⠣⠭⠐⠜" - // However, BANA says don't use a word indicator if G1 is in first 3 cells (the ':' needs it) - // Corrected to avoid word indicator + // GTM / BANA 2026: grade 1 word indicator test_braille("UEB", expr, "⠋⠰⠶⠐⠣⠭⠐⠜")?; return Ok(()); @@ -1197,7 +2019,7 @@ fn example_11_5_1_3() -> Result<()> { #[test] fn example_11_5_1_4() -> Result<()> { - let expr = "∂y∂x"; + let expr = "∂y∂x"; test_braille("UEB", expr, "⠰⠰⠷⠈⠙⠽⠨⠌⠈⠙⠭⠾")?; return Ok(()); @@ -1205,11 +2027,11 @@ fn example_11_5_1_4() -> Result<()> { #[test] fn example_11_5_2() -> Result<()> { - let expr = "∫23(2x+1)dx + let expr = "∫23(2x+1)dx =x2+x23 =(32+3)-(22+2) =12-6=6"; - test_braille("UEB", expr, "⠰⠰⠰⠮⠢⠼⠃⠔⠼⠉⠐⠣⠼⠃⠭⠐⠖⠼⠁⠐⠜⠙⠭⠀⠐⠶⠀⠨⠣⠭⠔⠼⠃⠐⠖⠭⠨⠜⠢⠼⠃⠔⠼⠉⠀⠐⠶⠀⠐⠣⠼⠉⠔⠼⠃⠐⠖⠼⠉⠐⠜⠐⠤⠐⠣⠼⠃⠔⠼⠃⠐⠖⠼⠃⠐⠜⠀⠐⠶⠀⠼⠁⠃⠐⠤⠼⠋⠀⠐⠶⠀⠼⠋⠰⠄")?; + test_braille("UEB", expr, "⠰⠰⠮⠢⠼⠃⠔⠼⠉⠐⠣⠼⠃⠭⠐⠖⠼⠁⠐⠜⠙⠭⠀⠐⠶⠀⠨⠣⠭⠰⠔⠼⠃⠐⠖⠭⠨⠜⠢⠼⠃⠔⠼⠉⠀⠐⠶⠀⠐⠣⠼⠉⠔⠼⠃⠐⠖⠼⠉⠐⠜⠐⠤⠐⠣⠼⠃⠔⠼⠃⠐⠖⠼⠃⠐⠜⠀⠐⠶⠀⠼⠁⠃⠐⠤⠼⠋⠀⠐⠶⠀⠼⠋")?; return Ok(()); } @@ -1229,19 +2051,19 @@ fn example_11_5_3() -> Result<()> { = n! - r!(n−r)! + r!(n−r)! "; // modified to use "shape" as recommended in a comment on this example - test_braille("UEB", expr, "⠰⠰⠰⠔⠝⠠⠉⠢⠗⠀⠐⠶⠀⠐⠣⠝⠰⠻⠗⠐⠜⠀⠐⠶⠀⠷⠝⠖⠨⠌⠗⠖⠐⠣⠝⠐⠤⠗⠐⠜⠖⠾⠰⠄")?; + test_braille("UEB", expr, "⠰⠰⠔⠝⠠⠉⠢⠗⠀⠐⠶⠀⠐⠣⠝⠰⠻⠗⠐⠜⠀⠐⠶⠀⠰⠰⠷⠝⠖⠨⠌⠗⠖⠐⠣⠝⠐⠤⠗⠐⠜⠖⠾")?; return Ok(()); } #[test] fn example_11_5_4() -> Result<()> { - let expr = "a∗(b◦c) - =(a∗b)◦(a∗c)"; + let expr = "a∗(b◦c) + =(a∗b)◦(a∗c)"; test_braille("UEB", expr, "⠁⠐⠔⠐⠣⠃⠐⠴⠉⠐⠜⠀⠐⠶⠀⠐⠣⠁⠐⠔⠃⠐⠜⠐⠴⠐⠣⠁⠐⠔⠉⠐⠜")?; return Ok(()); @@ -1252,11 +2074,11 @@ fn example_11_5_5_2() -> Result<()> { let expr = " f - − 1 + − 1 : Y - → + → X "; test_braille("UEB", expr, "⠰⠰⠰⠋⠔⠣⠐⠤⠼⠁⠜⠒⠀⠠⠽⠀⠳⠕⠀⠠⠭⠰⠄")?; @@ -1268,17 +2090,17 @@ fn example_11_5_5_2() -> Result<()> { fn example_11_5_5_3() -> Result<()> { // this comes from MathJax let expr = " - ∀ + ∀ y - ∈ + ∈ Y - ∃ + ∃ x - ∈ + ∈ X "; - test_braille("UEB", expr, "⠰⠰⠰⠘⠁⠽⠀⠘⠑⠀⠠⠽⠀⠘⠢⠭⠀⠘⠑⠀⠠⠭⠰⠄")?; + test_braille("UEB", expr, "⠘⠁⠽⠀⠘⠑⠀⠰⠠⠽⠀⠘⠢⠭⠀⠘⠑⠀⠰⠠⠭")?; return Ok(()); } @@ -1291,7 +2113,7 @@ fn example_11_5_6() -> Result<()> { x + y = 6 return Ok(()); } "; - test_braille("UEB", expr, "⠰⠰⠰⠸⠣⠐⠣⠭⠂⠀⠽⠐⠜⠀⠸⠳⠀⠭⠐⠖⠽⠀⠐⠶⠀⠼⠋⠸⠜⠰⠄")?; + test_braille("UEB", expr, "⠸⠣⠐⠣⠰⠭⠂⠀⠰⠽⠐⠜⠀⠸⠳⠀⠭⠐⠖⠽⠀⠐⠶⠀⠼⠋⠸⠜")?; return Ok(()); } @@ -1315,7 +2137,7 @@ fn example_11_6() -> Result<()> { fn bar_over_12_1_1() -> Result<()> { let expr = "x_= 10+11+123"; - test_braille("UEB", expr, "⠰⠰⠰⠭⠱⠀⠐⠶⠀⠷⠼⠁⠚⠐⠖⠼⠁⠁⠐⠖⠼⠁⠃⠨⠌⠼⠉⠾⠰⠄")?; + test_braille("UEB", expr, "⠭⠰⠱⠀⠐⠶⠀⠰⠷⠼⠁⠚⠐⠖⠼⠁⠁⠐⠖⠼⠁⠃⠨⠌⠼⠉⠾")?; return Ok(()); } @@ -1346,8 +2168,8 @@ fn dot_12_1_4() -> Result<()> { #[test] fn dot_12_1_5() -> Result<()> { - let expr = "0.561˙ - 23˙"; + let expr = "0.561˙ + 23˙"; test_braille("UEB", expr, "⠼⠚⠲⠑⠋⠣⠼⠁⠜⠘⠲⠼⠃⠣⠼⠉⠜⠘⠲")?; return Ok(()); @@ -1355,7 +2177,7 @@ fn dot_12_1_5() -> Result<()> { #[test] fn dot_12_1_6_single() -> Result<()> { - let expr = "x˙"; + let expr = "x˙"; test_braille("UEB", expr, "⠭⠘⠲")?; return Ok(()); @@ -1363,7 +2185,7 @@ fn dot_12_1_6_single() -> Result<()> { #[test] fn dot_12_1_6_double() -> Result<()> { - let expr = "x¨"; + let expr = "x¨"; test_braille("UEB", expr, "⠰⠰⠭⠨⠔⠣⠲⠲⠜")?; return Ok(()); @@ -1372,9 +2194,7 @@ fn dot_12_1_6_double() -> Result<()> { #[test] fn hat_12_1_7() -> Result<()> { let expr = "AB^C"; - // Acceptable: GTM uses a G1 start indicator: "⠰⠰⠠⠁⠠⠃⠐⠱⠠⠉" - // BANA says use a word indicator if G1 not in first 3 cells (modified it to not count cap indicators since that helps with GTM compatibility) - // Corrected to skip the G1 indicator at the start (it's debatable as to which is better) + // GTM / BANA 2026: grade 1 word indicator test_braille("UEB", expr, "⠠⠁⠠⠃⠰⠐⠱⠠⠉")?; return Ok(()); @@ -1400,7 +2220,7 @@ fn arrow_under_12() -> Result<()> { #[test] fn bar_12_2_1() -> Result<()> { - let expr = "xy¯"; + let expr = "xy¯"; test_braille("UEB", expr, "⠰⠰⠭⠔⠣⠽⠱⠜")?; return Ok(()); @@ -1408,7 +2228,7 @@ fn bar_12_2_1() -> Result<()> { #[test] fn bar_12_2_2() -> Result<()> { - let expr = "xy¯"; + let expr = "xy¯"; test_braille("UEB", expr, "⠰⠰⠣⠭⠔⠽⠜⠱")?; return Ok(()); @@ -1416,7 +2236,7 @@ fn bar_12_2_2() -> Result<()> { #[test] fn shape_14_1_1_1() -> Result<()> { - let expr = "△ ABC"; + let expr = "△ ABC"; test_braille("UEB", expr, "⠰⠫⠼⠉⠀⠠⠠⠁⠃⠉")?; return Ok(()); @@ -1424,7 +2244,7 @@ fn shape_14_1_1_1() -> Result<()> { #[test] fn shape_14_1_2_1() -> Result<()> { - let expr = "△ABC"; + let expr = "△ABC"; test_braille("UEB", expr, "⠰⠫⠼⠉⠱⠠⠠⠁⠃⠉")?; return Ok(()); @@ -1433,11 +2253,11 @@ fn shape_14_1_2_1() -> Result<()> { #[test] fn shape_14_1_2_2() -> Result<()> { // the for the shapes are wrong -- but it isn't clear what they should be (from WIRIS editor) - let expr = "{□, -  ◍, -  ▲, + let expr = "{□, +  ◍, +  ▲, return Ok(()); -  ▧ …}"; +  ▧ …}"; test_braille("UEB", expr, "⠸⠣⠰⠫⠼⠙⠱⠂⠀⠨⠫⠿⠱⠂⠀⠸⠫⠼⠉⠱⠂⠀⠨⠫⠼⠙⠀⠲⠲⠲⠸⠜")?; return Ok(()); } @@ -1584,11 +2404,8 @@ fn omission_15_4_1() -> Result<()> { #[test] fn chem_16_2_8() -> Result<()> { let expr = "Ca(OH)2"; - // Acceptable: GTM does not use a G1 start indicator: "⠠⠉⠁⠐⠣⠠⠕⠠⠓⠐⠜⠰⠢⠼⠃" - // However, BANA says use a word indicator if G1 not in first 3 cells (it is before the subscript near the end); use passage if >=2 whitespace - // This seems like a debateable choice in this case since there is only one G1 indicator, but that's the BANA guidance so... - // Corrected to use word indicator - test_braille("UEB", expr, "⠰⠰⠠⠉⠁⠐⠣⠠⠕⠠⠓⠐⠜⠢⠼⠃")?; + // GTM / BANA 2026: single G1 symbol for subscript (no word indicator) + test_braille("UEB", expr, "⠠⠉⠁⠐⠣⠠⠕⠠⠓⠐⠜⠰⠢⠼⠃")?; return Ok(()); } @@ -1623,7 +2440,7 @@ fn chem_16_2_9() -> Result<()> { - ⋅ + ⋅ @@ -1658,11 +2475,8 @@ fn chem_16_2_9() -> Result<()> { "; - // Acceptable: GTM does not use a G1 start indicator: "⠠⠉⠥⠠⠎⠠⠕⠰⠢⠼⠙⠐⠲⠼⠑⠠⠓⠢⠼⠃⠠⠕" - // However, BANA says use a word indicator if G1 not in first 3 cells (it is before the subscript); use passage if >=2 whitespace - // This seems like a debatable choice in this case since there is only one G1 indicator, but that's the BANA guidance so... - // Corrected to use word indicator - test_braille("UEB", expr, "⠰⠰⠠⠉⠥⠠⠎⠠⠕⠢⠼⠙⠐⠲⠼⠑⠠⠓⠢⠼⠃⠠⠕")?; + // GTM / BANA 2026: single G1 symbol for first subscript (no word indicator) + test_braille("UEB", expr, "⠠⠉⠥⠠⠎⠠⠕⠰⠢⠼⠙⠐⠲⠼⠑⠠⠓⠢⠼⠃⠠⠕")?; return Ok(()); } @@ -1693,14 +2507,14 @@ fn chem_16_2_12() -> Result<()> { R - ⋅ + ⋅ CH ( OH ) - ⋅ + ⋅ CH @@ -1708,7 +2522,7 @@ fn chem_16_2_12() -> Result<()> { 2 - ⋅ + ⋅ CH @@ -1716,7 +2530,7 @@ fn chem_16_2_12() -> Result<()> { 2 - ⋅ + ⋅ CO @@ -1726,9 +2540,8 @@ fn chem_16_2_12() -> Result<()> { H "; - // GTM uses G2 mode and has two G1 indicators (in middle and near end). That definitely violates BANA guidelines and maybe there guidelines. - // I have switched it to G1 word mode, which seems better (same length, but no switching) - test_braille("UEB", expr, "⠰⠰⠠⠠⠠⠗⠐⠲⠉⠓⠐⠣⠕⠓⠐⠜⠐⠲⠉⠓⠢⠼⠃⠐⠲⠉⠓⠢⠼⠃⠐⠲⠉⠕⠢⠼⠃⠰⠓⠠⠄")?; + // GTM / BANA 2026: G2 with inline G1 symbols (not forced word mode) + test_braille("UEB", expr, "⠠⠠⠠⠗⠐⠲⠡⠐⠣⠕⠓⠐⠜⠐⠲⠡⠰⠢⠼⠃⠐⠲⠉⠓⠢⠼⠃⠐⠲⠉⠕⠢⠼⠃⠰⠓⠠⠄")?; return Ok(()); } @@ -1815,7 +2628,7 @@ fn chem_16_5_1() -> Result<()> { - → + → Na @@ -1861,7 +2674,7 @@ fn chem_16_5_1() -> Result<()> { "#; - test_braille("UEB", expr, "⠰⠰⠰⠼⠃⠠⠝⠁⠠⠕⠠⠓⠐⠖⠠⠓⠢⠼⠃⠠⠎⠠⠕⠢⠼⠙⠀⠳⠕⠀⠠⠝⠁⠢⠼⠃⠠⠎⠠⠕⠢⠼⠙⠐⠖⠼⠃⠠⠓⠢⠼⠃⠠⠕⠰⠄")?; + test_braille("UEB", expr, "⠼⠃⠠⠝⠁⠠⠕⠠⠓⠐⠖⠠⠓⠢⠼⠃⠠⠎⠠⠕⠢⠼⠙⠀⠰⠳⠕⠀⠠⠝⠁⠰⠢⠼⠃⠠⠎⠠⠕⠢⠼⠙⠐⠖⠼⠃⠠⠓⠢⠼⠃⠠⠕")?; return Ok(()); } @@ -1872,7 +2685,7 @@ fn chem_16_5_2() -> Result<()> { let expr = r#" N2 - →Haber processH2 + →Haber processH2 N H3 @@ -1952,7 +2765,7 @@ fn chem_16_5_4() -> Result<()> { - → + → @@ -1983,7 +2796,7 @@ fn chem_16_5_4() -> Result<()> { - ⋅ + ⋅ @@ -1995,7 +2808,7 @@ fn chem_16_5_4() -> Result<()> { - ⋅ + ⋅ @@ -2005,7 +2818,7 @@ fn chem_16_5_4() -> Result<()> { - → + → @@ -2040,7 +2853,7 @@ fn chem_16_5_4() -> Result<()> { - ⋅ + ⋅ @@ -2052,7 +2865,7 @@ fn chem_16_5_4() -> Result<()> { - ⋅ + ⋅ @@ -2111,16 +2924,16 @@ fn chem_16_5_5() -> Result<()> { - ↽ + ↽ - − + − - − + − - ⇀ + ⇀ @@ -2128,7 +2941,7 @@ fn chem_16_5_5() -> Result<()> { "#; - test_braille("UEB", expr, "⠰⠰⠰⠠⠏⠃⠔⠣⠐⠖⠐⠖⠜⠐⠖⠼⠃⠰⠑⠀⠘⠸⠶⠀⠠⠏⠃⠰⠄")?; + test_braille("UEB", expr, "⠰⠰⠠⠏⠃⠔⠣⠐⠖⠐⠖⠜⠐⠖⠼⠃⠰⠑⠀⠰⠘⠸⠶⠀⠠⠏⠃")?; return Ok(()); } diff --git a/tests/braille/UEB/other.rs b/tests/braille/UEB/other.rs index 7dda38f6c..9b8a1ab29 100644 --- a/tests/braille/UEB/other.rs +++ b/tests/braille/UEB/other.rs @@ -12,7 +12,7 @@ use anyhow::Result; #[test] fn overscript_grouping_aph_5_4_8() -> Result<()> { // this test was added because #220 (failed to add grouping around overscript) - let expr = " MN ↔ "; + let expr = " MN ↔ "; test_braille("UEB", expr, "⠰⠰⠣⠠⠠⠍⠝⠜⠨⠔⠳⠺⠗⠕")?; return Ok(()); @@ -39,7 +39,7 @@ fn blank_aph_7_1_ex5() -> Result<()> { #[test] fn word_symbol_aph_10_3_11() -> Result<()> { // this test was added because ⊻ (U+22bb) uses a 'G1 Word mode' char, so is different than others - let expr = " p ⊻ q "; + let expr = " p ⊻ q "; test_braille("UEB", expr, "⠰⠰⠏⠈⠖⠠⠱⠟")?; return Ok(()); @@ -247,6 +247,23 @@ fn ueb_no_italic_typeform_for_math_letters() -> Result<()> { return Ok(()); } +#[test] +fn ueb_space_because_and_qed() -> Result<()> { + // ∵ and ∎ are spaced like ∴ (GTM 11 miscellaneous; same mo AddSpaces path as 1.7.9). + test_braille("UEB", "∵x=1", "⠈⠌⠀⠰⠭⠀⠐⠶⠀⠼⠁")?; + test_braille("UEB", "x=1∎", "⠰⠭⠀⠐⠶⠀⠼⠁⠀⠸⠫⠼⠙⠱")?; + return Ok(()); +} + +#[test] +fn ueb_math_typeform_not_part_of_word() -> Result<()> { + // Double-struck/script/fraktur letters are math alphabets, not part of an English + // letters-sequence, so a following whole word still takes its contraction (time → ⠐⠞). + test_braille("UEB", "Rtime", "⠈⠆⠠⠗⠐⠞")?; + test_braille("UEB", "R", "⠈⠆⠰⠠⠗")?; + return Ok(()); +} + #[test] fn ueb_italic_typeform_for_digits() -> Result<()> { // UEB uses italic typeform for digits (GTM 2.7 emphasis of numeric material). From 9ea98c23e8c44eb19975f3da4a0284b5eaf0c056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dziwisz?= Date: Wed, 2 Sep 2026 15:42:45 +0200 Subject: [PATCH 085/157] pl: fix five speech/navigation defects and catch up with recent en changes (#738) * pl: speak up tack (U+22A5) as perpendicular, matching en Follow-up to 45aefb2d for Polish. Editors commonly emit U+22A5 where perpendicularity is meant, so both U+27C2 and U+22A5 now say "jest prostopadle do". LiteralSpeak keeps reading U+22A5 literally as "dol". Previously Polish said "dol" for U+22A5, so the same formula was read differently in Polish than in English. Adds up_tack_330 to tests/Languages/pl/alphabets.rs, mirroring the English test. * pl: adopt the `|` argument-glue syntax from definitions.yaml Follow-up to 4347d884 for Polish. That commit added the `|` syntax and updated the Polish tests, but not the Polish rule files, so several intents lost their function name in speech. Fixed, with the spoken output before -> after: quotient "podzielone przez z x przecinek, y" -> "czesc calkowita z x podzielone przez y" remainder "podzielone przez z x przecinek, y" -> "reszta z x podzielone przez y" set-difference "i z wielka a przecinek, wielka b" -> "roznica zbiorow z wielka a i wielka b" polar-coordinate "przecinek z x przecinek, y" -> "wspolrzedna biegunowa z x przecinek, y" The `|` syntax needs the function-intent rule to call IntentFunctionUseArityPath / IntentFunctionGlueBefore. Only en and hu had it, so it is now ported to pl (with "of" -> "z"). Also here: * SharedRules/geometry.yaml: the `coordinate` rule matched "." instead of "not(*[@arg])", so it swallowed coordinate($x,...) intents that should fall through to IntentMappings. Its name was also mistranslated as "przecinek" (comma) rather than "punkt" (point). * transpose: fixity order now matches en (postfix first). The function form is tested explicitly via intent='transpose:function($x)', as en does. * empty-set: added, it was missing. NOT adopted: arity templates ("| po | od,do") for sum/product. intent_function_glue_before in src/infer_intent.rs hardcodes the English word "of" for the last argument, which yields "suma po i of x" in Polish. This affects every non-English language; hu avoids it the same way. The binary separator form works correctly and is what this commit uses. * pl: fix navigation direction words, unreachable for any translation Follow-up to ec36e057 and 080ca162 for Polish, but it also fixes a long-standing Polish bug rather than only porting the new code. navigate.yaml compared the suffix of $NavCommand (always English, e.g. "ZoomIn") against a substring offset by the length of the SPOKEN $Prefix. For English those are the same; for any translation they are not. With "przybliz" (8 chars) vs "Zoom" (4), "ZoomIn" was cut to "" instead of "In", so ALL 16 branches were dead: ZoomIn -> "" (want "In") ZoomOutAll -> "ll" (want "OutAll") MoveNext -> "t" (want "Next") DescribeNext -> "ibeNext" (want "Next") Users heard "przejdz; do mianownika" with no direction, never "przejdz w prawo". Using $CommandOffset, as ec36e057 introduced, fixes all of them. Two more things here: * Polish needs two verbs where English reuses "zoom": "przybliz na zewnatrz" (zoom in outwards) is self-contradictory, so ZoomOut* now says "oddal". The direction word for plain In/Out is dropped, as the verb already carries it: "przybliz" / "oddal", and "przybliz maksymalnie" / "oddal maksymalnie". * Ports into-or-out-of-prefix-or-silent-without-parts (080ca162) and the SpeakIntentName fallbacks in into-or-out-of-default, keeping our own Polish preposition logic (including "ze stopnia" euphony). Adds zoom_speech_pl and move_char_speech_pl. Both fail on the old formula, showing the missing direction word, so they do discriminate. * pl: announce table column and row separators Follow-up to fbc49bb7 (#679) for Polish. The HasVisibleColumnLine / HasVisibleRowLine rules were missing from pl/SharedRules/default.yaml, so visible lines in a matrix were silent for Polish users, e.g. an augmented matrix was read exactly like a plain one. before: "2 na 3 macierz rozszerzona; wiersz 1; 3, 1, 4; ..." after: "2 na 3 macierz rozszerzona; wiersz 1; 3, 1, separator, 4; ..." Two existing tests (augmented_matrix_2x3, augmented_matrix_3x4_end_matrix) were pinning the pre-#679 output; their English counterparts already expect "separator", so they are updated rather than worked around. Adds dashed_augmented_matrix_separator and matrix_row_separator, ported from tests/Languages/en/mtable.rs. Removing either rule fails all four tests, so they discriminate. * pl: clear the remaining untranslated unicode entries The audit tool reported 81 unicode entries whose text equals the English source. Reviewing them one by one, only two were actually untranslated: U+2127 "mhos" -> "mho" (unit, as nb and sv have it) U+2644 "Saturn" (Polish spelling is the same; key raised) The other 75 are correct as-is and only needed the verified key: * 30 Roman numerals (U+2160..U+217F) spelled out letter by letter * 29 space, PUA and zero-width entries with no speech at all * 6 typographic ligatures (ff, fl, ffi, ffl, ft, st) * 10 proper names and symbols (spesmilos, paragraphos, hypodiastole, digamma, differential d, imaginary j, oV, pH) Four more in unicode.yaml (digit separator, space, U+2062, U+2063) likewise carry no translatable speech. Raising the key on an entry whose text legitimately matches English is what the convention is for; it is not the same as marking English text as verified. Only the wording of "mhos" changed - the diff is otherwise key case only, checked line by line. Audit's "untranslated" for unicode files: 81 -> 0. --- Rules/Languages/pl/SharedRules/default.yaml | 47 ++++- Rules/Languages/pl/SharedRules/geometry.yaml | 10 +- Rules/Languages/pl/definitions.yaml | 35 ++-- Rules/Languages/pl/navigate.yaml | 80 ++++++--- Rules/Languages/pl/unicode-full.yaml | 173 +++++++++---------- Rules/Languages/pl/unicode.yaml | 8 +- src/navigate.rs | 53 ++++++ tests/Languages/pl/alphabets.rs | 15 ++ tests/Languages/pl/definitions.rs | 40 ++++- tests/Languages/pl/mtable.rs | 47 ++++- 10 files changed, 356 insertions(+), 152 deletions(-) diff --git a/Rules/Languages/pl/SharedRules/default.yaml b/Rules/Languages/pl/SharedRules/default.yaml index ae139ebd6..531f57a5d 100644 --- a/Rules/Languages/pl/SharedRules/default.yaml +++ b/Rules/Languages/pl/SharedRules/default.yaml @@ -513,6 +513,18 @@ - x: "count(preceding-sibling::*)+IfThenElse(parent::m:mlabeledtr, 0, 1)" - pause: medium - x: "*" + - test: + if: "HasVisibleColumnLine(../.., count(preceding-sibling::*) + 1)" + then: + - pause: short + - T: "separator" + - test: + # Separator wiersza zapowiadamy tylko po ostatniej komórce wiersza, żeby + # wybrzmiał raz na każdą granicę poziomą. + if: "count(following-sibling::*) = 0 and HasVisibleRowLine(../.., count(../preceding-sibling::*) + 1)" + then: + - pause: short + - T: "separator wiersza" - test: # short pause after each element; medium pause if last element in a row; long pause for last element in matrix - if: count(following-sibling::*) > 0 @@ -737,21 +749,38 @@ - name: function-intent # uncaught intent -- speak as foo of arg1 comma arg2 .... The MathML spec requires arguments to functions + # IntentMappings mogą dodać po nazwie opcje spoiwa "| ...": + # * jedna opcja bez przecinka: separator dwuargumentowy po "z" + # (np. "| podzielone przez" daje "część całkowita z x podzielone przez y") + # * wiele opcji albo opcja z przecinkami: szablony arności; k słów spoiwa + # opisuje k+1 argumentów (np. "| po | od,do") + # * gdy arność nie pasuje, argumenty rozdziela przecinek tag: "*" match: "count(*)>0" replace: - x: "SpeakIntentName(name(.), $Verbosity, 'function')" - test: - if: "$Verbosity != 'Terse' and not(contains(@data-intent-property, ':literal:')) and - not(count(*)=2 and (IsInDefinition(*[1], 'TrigFunctionNames') or IsInDefinition(name(.), 'TerseFunctionNames')) and IsNode(*[2], 'simple'))" - then: [T: "z", pause: auto] # phrase(sine 'of' 5) - - insert: - nodes: "*" - replace: - - test: - if: "not(contains(@data-intent-property, ':literal:'))" - then: [x: "','"] + - if: "IntentFunctionUseArityPath(name(.), 'function', count(*))" + then: + - x: "IntentFunctionGlueBefore(name(.), 'function', 1, count(*))" - pause: auto + - insert: + nodes: "*" + replace: + - x: "IntentFunctionGlueBefore(name(.), 'function', $InsertIndex, count(*))" + - pause: auto + else: + - test: + if: "$Verbosity != 'Terse' and not(contains(@data-intent-property, ':literal:')) and + not(count(*)=2 and (IsInDefinition(*[1], 'TrigFunctionNames') or IsInDefinition(name(.), 'TerseFunctionNames')) and IsNode(*[2], 'simple'))" + then: [T: "z", pause: auto] # phrase(sine 'of' 5) + - insert: + nodes: "*" + replace: + - test: + if: "not(contains(@data-intent-property, ':literal:'))" + then: [x: "IntentFunctionArgSeparator(name(.), 'function', count(*))"] + - pause: auto - test: # speak "end ..." if not bracketed or last child is not simple and not last node if: "$Impairment = 'Blindness' and not(*[last()][IsBracketed(., '', '') or IsNode(., 'simple')] )" diff --git a/Rules/Languages/pl/SharedRules/geometry.yaml b/Rules/Languages/pl/SharedRules/geometry.yaml index 37155f79c..f110a71ed 100644 --- a/Rules/Languages/pl/SharedRules/geometry.yaml +++ b/Rules/Languages/pl/SharedRules/geometry.yaml @@ -57,12 +57,16 @@ - name: coordinate tag: coordinate - match: "." + # Intencje postaci coordinate($x,...) mają @arg i spadają do function-intent / IntentMappings + match: "not(*[@arg])" replace: - - T: "przecinek" # phrase(the 'point' at 1, 2) - test: if: "$Verbosity='Verbose'" - then: [t: "w"] # phrase('the' point at 1, 2) + then: [OT: "ten"] # phrase('the' point at 1, 2) + - T: "punkt" # phrase(the 'point' at 1, 2) + - test: + if: "$Verbosity='Verbose'" + then: [T: "w"] # phrase('the' point at 1, 2) - pause: short - insert: nodes: "*" diff --git a/Rules/Languages/pl/definitions.yaml b/Rules/Languages/pl/definitions.yaml index 6dda0ebe0..9c4c6e69c 100644 --- a/Rules/Languages/pl/definitions.yaml +++ b/Rules/Languages/pl/definitions.yaml @@ -13,9 +13,9 @@ "image":"function=obraz", "mixed-fraction":"infix=i", - "quotient":"function=część całkowita; podzielone przez", + "quotient":"function=część całkowita | podzielone przez", "evaluated-at":"infix=obliczone w", - "remainder":"function=reszta; podzielone przez", + "remainder":"function=reszta | podzielone przez", "max":"function=maksimum", "min":"function=minimum", @@ -32,10 +32,10 @@ "real-part": "function=część rzeczywista", "imaginary-part": "function=część urojona: część urojona: część urojona", - "polar-coordinate":"function=współrzędna biegunowa; przecinek", - "spherical-coordinate":"function=współrzędna sferyczna; przecinek; przecinek", - "cartesian-coordinate":"function=współrzędna kartezjańska; przecinek", - "coordinate":"function=współrzędna; przecinek", + "polar-coordinate":"function=współrzędna biegunowa", + "spherical-coordinate":"function=współrzędna sferyczna", + "cartesian-coordinate":"function=współrzędna kartezjańska", + "coordinate":"function=współrzędna", "floor":"function=podłoga", "ceiling":"function=sufit", "round":"function=zaokrąglenie", @@ -51,16 +51,23 @@ ### Sets "set": "function=; zbiór: zbiór", - "set-difference":"function=różnica zbiorów; i || infix=minus", # NOTE: not tested + "set-difference":"function=różnica zbiorów | i || infix=minus", "complement":"function=dopełnienie", + "empty-set":"nofix=zbiór pusty", "cardinality":"function=moc zbioru", "list":"function=lista", "tuple": "function=; krotka: krotka", ### Sequence and Series - "sum":"function=; suma po: suma; ", - "product":"function=iloczyn || function=iloczyn po || function=iloczyn od; do", + # UWAGA: NIE używamy tu szablonów arności ("| po | od,do"), choć angielski je ma. + # Powód (zmierzone 31.08.2026): intent_function_glue_before w src/infer_intent.rs + # zwraca dla ostatniego argumentu ZASZYTE W KODZIE angielskie "of", więc polskie + # wyjście brzmiałoby "suma po i of x". To defekt rdzenia dotyczący każdego języka + # poza angielskim; węgierski uniknął go tak samo, zostawiając prostą postać. + # Separator binarny (jedna opcja "| słowo") działa poprawnie i jest używany niżej. + "sum":"function=suma", + "product":"function=iloczyn", ### Elementary classical functions @@ -104,7 +111,7 @@ "median":"function=mediana", "mode":"function=dominanta", - "conditional-probability":"function=prawdopodobieństwo; pod warunkiem", # NOTE: Check test + "conditional-probability":"function=prawdopodobieństwo | pod warunkiem", ### Linear Algebra @@ -120,7 +127,7 @@ "unit-vector":"prefix=wektor jednostkowy", "identity-matrix":"nofix=macierz jednostkowa", # NOTE: no function specified - "transpose":"function=transpozycja || postfix=transponowane", + "transpose":"postfix=transponowane || function=transpozycja", "dimensional-product":"infix=na", # INFIX @@ -150,13 +157,13 @@ ### General Concepts "fenced-group":"function=grupa w nawiasach", - "ordered-pair": "function=; para; i", + "ordered-pair": "function=para | i", "indexed-by": "infix=; indeks dolny; koniec indeksu dolnego", "highlight":"postfix=podświetlone", "least-common-denominator":"function=najmniejszy wspólny mianownik", "rate":"infix=na", - "translation":"function=przesunięcie o; przecinek", + "translation":"function=przesunięcie o", "constraint":"infix=; przy warunku; ", "binomial-coefficient":"infix=po", @@ -264,7 +271,7 @@ ## Default fixity nofix "diameter":"nofix=d: średnica", "distance":"nofix=d; D: odległość", - "probability":"nofix=P: prawdopodobieństwo", + "probability":"nofix=P: prawdopodobieństwo || function=prawdopodobieństwo", "radius":"nofix=r: promień", "volume":"nofix=V: objętość || function=objętość", "exponential-e":"nofix=e", diff --git a/Rules/Languages/pl/navigate.yaml b/Rules/Languages/pl/navigate.yaml index cfdecbcb4..c99b60490 100644 --- a/Rules/Languages/pl/navigate.yaml +++ b/Rules/Languages/pl/navigate.yaml @@ -53,39 +53,46 @@ then: [t: "maksymalnie oddalono", pause: "medium"] else: - test: - - if: "starts-with($NavCommand, 'Zoom')" - then: [set_variables: [Prefix: "'przybliż'"]] # phrase('zoom' in to see more details) + # CommandOffset to 1 + długość ANGIELSKIEGO rdzenia $NavCommand + # (Zoom/Move/Read/Describe), a NIE długość wymawianego $Prefix - + # dzięki temu tłumaczenie może mieć słowo Prefix innej długości. + # Angielskie "zoom" obsługuje oba kierunki, polski ma dwa różne + # czasowniki - "przybliż na zewnątrz" byłoby sprzeczne. + - if: "starts-with($NavCommand, 'ZoomOut')" + then: [set_variables: [Prefix: "'oddal'", CommandOffset: "5"]] # phrase('zoom' out to see less detail) + - else_if: "starts-with($NavCommand, 'Zoom')" + then: [set_variables: [Prefix: "'przybliż'", CommandOffset: "5"]] # phrase('zoom' in to see more details) - else_if: "starts-with($NavCommand, 'Move')" - then: [set_variables: [Prefix: "'przejdź'"]] # phrase('move' to next entry in table) + then: [set_variables: [Prefix: "'przejdź'", CommandOffset: "5"]] # phrase('move' to next entry in table) - else_if: "starts-with($NavCommand, 'Read')" - then: [set_variables: [Prefix: "'odczytaj'"]] # phrase('read' to next entry in table) + then: [set_variables: [Prefix: "'odczytaj'", CommandOffset: "5"]] # phrase('read' to next entry in table) - else_if: "starts-with($NavCommand, 'Describe')" - then: [set_variables: [Prefix: "'opisz'"]] # phrase('describe' to next entry in table) + then: [set_variables: [Prefix: "'opisz'", CommandOffset: "9"]] # phrase('describe' to next entry in table) - test: if: "$Prefix != ''" then: - x: "$Prefix" - test: - - if: "substring($NavCommand, string-length($Prefix)+1) = 'In'" - then: [T: "do"] # phrase(zoom 'in' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'InAll'" + - if: "substring($NavCommand, $CommandOffset) = 'In'" + then: [] # sam czasownik "przybliż" wystarcza + - else_if: "substring($NavCommand, $CommandOffset) = 'InAll'" # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets "ed" concatenated to "zoom" - then: [t: "maksymalnie do środka"] # phrase(zoom 'out all the way' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Out'" - then: [t: "na zewnątrz"] # phrase(zoom 'out' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'OutAll'" + then: [T: "maksymalnie"] # phrase(zoom 'in all of the way' to see more details) + - else_if: "substring($NavCommand, $CommandOffset) = 'Out'" + then: [] # sam czasownik "oddal" wystarcza + - else_if: "substring($NavCommand, $CommandOffset) = 'OutAll'" # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets "ed" concatenated to "zoom" - then: [t: "maksymalnie na zewnątrz"] # phrase(zoom 'out all the way' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Next'" - then: [t: "w prawo"] # phrase(move to the 'right') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Previous'" - then: [t: "w lewo"] # phrase(move to the 'left') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Current'" - then: [t: "bieżący"] # phrase(who is the 'current' president) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'LineStart'" - then: [t: "do początku linii"] # phrase(move 'to start of line') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'LineEnd'" - then: [t: "do końca linii"] # phrase(move 'to end of line') + then: [T: "maksymalnie"] # phrase(zoom 'out all of the way' to see more details) + - else_if: "substring($NavCommand, $CommandOffset) = 'Next'" + then: [T: "w prawo"] # phrase(move to the 'right') + - else_if: "substring($NavCommand, $CommandOffset) = 'Previous'" + then: [T: "w lewo"] # phrase(move to the 'left') + - else_if: "substring($NavCommand, $CommandOffset) = 'Current'" + then: [T: "bieżący"] # phrase(who is the 'current' president) + - else_if: "substring($NavCommand, $CommandOffset) = 'LineStart'" + then: [T: "do początku linii"] # phrase(move 'to start of line') + - else_if: "substring($NavCommand, $CommandOffset) = 'LineEnd'" + then: [T: "do końca linii"] # phrase(move 'to end of line') - pause: "medium" - set_variables: [MatchCounter: "$MatchCounter + 1"] @@ -96,6 +103,15 @@ (name(.)='mrow' or name(.) = 'mtr' or name(.) = 'mlabeledtr' or @data-from-mathml = 'mtable')" replace: [] +- name: into-or-out-of-prefix-or-silent-without-parts + tag: "*" + # Intencje prefiksowe i ciche bez wpisu w NavigationParts (np. minus unarny, + # x z daszkiem) NIE powinny zapowiadać "do"/"na zewnątrz". + match: "$Move2D != '' and + (contains(@data-intent-property, ':prefix:') or contains(@data-intent-property, ':silent:')) and + GetNavigationPartName(name(.), count($Child2D/preceding-sibling::*)) = ''" + replace: [] + - name: into-or-out-of-mtr tag: [mtr, mlabeledtr] match: "$Move2D = 'in'" @@ -168,6 +184,24 @@ - test: - if: "$PartName != ''" then: [x: "$PartName"] + - else_if: "count(*) = 1" + then_test: + if: "$NavVerbosity = 'Verbose'" + then: # IntentMappings przez SpeakIntentName; w razie braku - nazwa intentu ze spacjami + - test: + - if: "contains(@data-intent-property, ':prefix:')" + then: [x: "SpeakIntentName(name(.), $Verbosity, 'prefix')"] + - else_if: "contains(@data-intent-property, ':postfix:')" + then: [x: "SpeakIntentName(name(.), $Verbosity, 'postfix')"] + - else_if: "contains(@data-intent-property, ':infix:')" + then: [x: "SpeakIntentName(name(.), $Verbosity, 'infix')"] + - else_if: "contains(@data-intent-property, ':function:')" + then: [x: "SpeakIntentName(name(.), $Verbosity, 'function')"] + - else_if: "contains(@data-intent-property, ':nofix:')" + then: [x: "SpeakIntentName(name(.), $Verbosity, 'nofix')"] + - else_if: "contains(@data-intent-property, ':silent:')" + then: [x: "SpeakIntentName(name(.), $Verbosity, 'silent')"] + - else: [x: "SpeakIntentName(name(.), $Verbosity, 'other')"] else: - t: "części" # phrase(the 'part' of the expression) - x: "count($Child2D/preceding-sibling::*) + 1" diff --git a/Rules/Languages/pl/unicode-full.yaml b/Rules/Languages/pl/unicode-full.yaml index 0fbeda954..8246f4650 100644 --- a/Rules/Languages/pl/unicode-full.yaml +++ b/Rules/Languages/pl/unicode-full.yaml @@ -291,7 +291,7 @@ - "†": [t: "obelisk"] # 0x2020 - "‡": [t: "podwójny obelisk"] # 0x2021 - - " - ": [t: " "] # 0x2000 - 0x2007 + - " - ": [T: " "] # 0x2000 - 0x2007 - "•": # 0x2022 - test: @@ -344,7 +344,7 @@ - "⁑": [t: "dwie pionowe gwiazdki"] # 0x2051 - "⁒": [t: "handlowy znak minus"] # 0x2052 - "⁗": [t: "poczwórny prim"] # 0x2057 - - "⁠": [t: ""] # 0x2060 + - "⁠": [T: ""] # 0x2060 - "⁰": [t: "do zerowej potęgi"] # 0x2070 - "ⁱ": [t: "do potęgi i"] # 0x2071 - "⁴": [t: "do czwartej potęgi"] # 0x2074 @@ -409,7 +409,7 @@ - "₴": [t: "hrywny"] # 0x20b4 - "₵": [t: "cedi"] # 0x20b5 - "₶": [t: "liwr turoński"] # 0x20b6 - - "₷": [t: "spesmilos"] # 0x20b7 + - "₷": [T: "spesmilos"] # 0x20b7 - "₸": [t: "tenge"] # 0x20b8 - "₹": [t: "rupie indyjskie"] # 0x20b9 - "₺": [t: "liry tureckie"] # 0x20ba @@ -473,7 +473,7 @@ - "№": [t: "numer"] # 0x2116 - "℥": [t: "uncje"] # 0x2125 - "Ω": [t: "omy"] # 0x2126 - - "℧": [t: "mhos"] # 0x2127 + - "℧": [T: "mho"] # 0x2127 - "℩": [t: "odwrócony jota"] # 0x2129 - "K": [t: "kelwin"] # 0x212a - "Å": [t: "angstremy"] # 0x212b @@ -522,37 +522,37 @@ - "⅞": [t: "siedem ósmych"] # 0x215e - "⅟": [t: "jeden przez"] # 0x215f - "Ⅰ": [t: "I"] # 0x2160 - - "Ⅱ": [t: "I I"] # 0x2161 - - "Ⅲ": [t: "I I I"] # 0x2162 - - "Ⅳ": [t: "I V"] # 0x2163 - - "Ⅴ": [t: "V"] # 0x2164 - - "Ⅵ": [t: "V I"] # 0x2165 - - "Ⅶ": [t: "V I I"] # 0x2166 - - "Ⅷ": [t: "V I I I"] # 0x2167 - - "Ⅸ": [t: "I X"] # 0x2168 - - "Ⅹ": [t: "X"] # 0x2169 - - "Ⅺ": [t: "X I"] # 0x216a - - "Ⅻ": [t: "X I I"] # 0x216b - - "Ⅼ": [t: "L"] # 0x216c - - "Ⅽ": [t: "C"] # 0x216d - - "Ⅾ": [t: "D"] # 0x216e - - "Ⅿ": [t: "M"] # 0x216f + - "Ⅱ": [T: "I I"] # 0x2161 + - "Ⅲ": [T: "I I I"] # 0x2162 + - "Ⅳ": [T: "I V"] # 0x2163 + - "Ⅴ": [T: "V"] # 0x2164 + - "Ⅵ": [T: "V I"] # 0x2165 + - "Ⅶ": [T: "V I I"] # 0x2166 + - "Ⅷ": [T: "V I I I"] # 0x2167 + - "Ⅸ": [T: "I X"] # 0x2168 + - "Ⅹ": [T: "X"] # 0x2169 + - "Ⅺ": [T: "X I"] # 0x216a + - "Ⅻ": [T: "X I I"] # 0x216b + - "Ⅼ": [T: "L"] # 0x216c + - "Ⅽ": [T: "C"] # 0x216d + - "Ⅾ": [T: "D"] # 0x216e + - "Ⅿ": [T: "M"] # 0x216f - "ⅰ": [t: "I"] # 0x2170 - - "ⅱ": [t: "I I"] # 0x2171 - - "ⅲ": [t: "I I I"] # 0x2172 - - "ⅳ": [t: "I V"] # 0x2173 - - "ⅴ": [t: "V"] # 0x2174 - - "ⅵ": [t: "V I"] # 0x2175 - - "ⅶ": [t: "V I I"] # 0x2176 - - "ⅷ": [t: "V I I I"] # 0x2177 - - "ⅸ": [t: "I X"] # 0x2178 - - "ⅹ": [t: "X"] # 0x2179 - - "ⅺ": [t: "X I"] # 0x217a - - "ⅻ": [t: "X I I"] # 0x217b - - "ⅼ": [t: "L"] # 0x217c - - "ⅽ": [t: "C"] # 0x217d - - "ⅾ": [t: "D"] # 0x217e - - "ⅿ": [t: "M"] # 0x217f + - "ⅱ": [T: "I I"] # 0x2171 + - "ⅲ": [T: "I I I"] # 0x2172 + - "ⅳ": [T: "I V"] # 0x2173 + - "ⅴ": [T: "V"] # 0x2174 + - "ⅵ": [T: "V I"] # 0x2175 + - "ⅶ": [T: "V I I"] # 0x2176 + - "ⅷ": [T: "V I I I"] # 0x2177 + - "ⅸ": [T: "I X"] # 0x2178 + - "ⅹ": [T: "X"] # 0x2179 + - "ⅺ": [T: "X I"] # 0x217a + - "ⅻ": [T: "X I I"] # 0x217b + - "ⅼ": [T: "L"] # 0x217c + - "ⅽ": [T: "C"] # 0x217d + - "ⅾ": [T: "D"] # 0x217e + - "ⅿ": [T: "M"] # 0x217f - "↉": [t: "zero trzecich"] # 0x2189 - "↔": [t: "lewy strzałka w prawo"] # 0x2194 - "↕": [t: "górny strzałka w dół"] # 0x2195 @@ -1081,11 +1081,6 @@ - "⊢": [t: "dowodzi"] # 0x22a2 - "⊣": [t: "jest dowodzone przez"] # 0x22a3 - "⊤": [t: "góra"] # 0x22a4 - - "⊥": # 0x22a5 - - test: - if: "$Verbosity!='Terse'" - then: [T: "jest"] - - t: "dół" - "⊦": [t: "redukuje się do"] # 0x22a6 - "⊧": [t: "modeluje"] # 0x22a7 - "⊨": # 0x22a8 @@ -1538,7 +1533,7 @@ - "♁": [t: "Ziemia"] # 0x2641 - "♂": [t: "męskie"] # 0x2642 - "♃": [t: "Jowisz"] # 0x2643 - - "♄": [t: "Saturn"] # 0x2644 + - "♄": [T: "Saturn"] # 0x2644 - "♅": [t: "Uran"] # 0x2645 - "♆": [t: "Neptun"] # 0x2646 - "♇": [t: "Pluton"] # 0x2647 @@ -1662,11 +1657,15 @@ - "➾": [t: "otwarta konturowa strzałka w prawo"] # 0x27be - "⟀": [t: "trójwymiarowy kąt"] # 0x27c0 - "⟁": [t: "biały trójkąt zawierający mały biały trójkąt"] # 0x27c1 - - "⟂": # 0x27c2 - - test: - if: "$Verbosity!='Terse'" - then: [T: "jest"] - - t: "prostopadłe do" + - "⟂⊥": # 0x27c2, 22A5 (22A5 wrongly used for perpendicular by most editors) + - test: + - if: "$SpeechStyle = 'LiteralSpeak' and text()='⊥'" # 22A5 (up tack/bottom) + then: [T: "dół"] + - else: + - test: + if: "$Verbosity!='Terse'" + then: [T: "jest"] + - T: "prostopadłe do" - "⟃": # 0x27c3 - test: if: "$Verbosity!='Terse'" @@ -2354,10 +2353,10 @@ - "⸌": [t: "lewy podniesiony pominięcia nawias kwadratowy"] # 0x2e0c - "⸍": [t: "prawy podniesiony pominięcia nawias kwadratowy"] # 0x2e0d - "⸎": [t: "redakcyjny koronis"] # 0x2e0e - - "⸏": [t: "paragraphos"] # 0x2e0f + - "⸏": [T: "paragraphos"] # 0x2e0f - "⸐": [t: "rozwidlony paragrafos"] # 0x2e10 - "⸑": [t: "odwrócony rozwidlony paragrafos"] # 0x2e11 - - "⸒": [t: "hypodiastole"] # 0x2e12 + - "⸒": [T: "hypodiastole"] # 0x2e12 - "⸓": [t: "kropkowany obelos"] # 0x2e13 - "⸔": [t: "dolny ancora"] # 0x2e14 - "⸕": [t: "górny ancora"] # 0x2e15 @@ -2466,7 +2465,7 @@ - "㍲": [t: "daltony"] # 0x3372 - "㍳": [t: "jednostki astronomiczne"] # 0x3373 - "㍴": [t: "bary"] # 0x3374 - - "㍵": [t: "o V"] # 0x3375 + - "㍵": [T: "o V"] # 0x3375 - "㍶": [t: "parseki"] # 0x3376 - "㍷": [t: "decymetry"] # 0x3377 - "㍸": [t: "decymetry do kwadratu"] # 0x3378 @@ -2559,7 +2558,7 @@ - "㏔": [t: "milibarny"] # 0x33d4 - "㏕": [t: "mile"] # 0x33d5 - "㏖": [t: "mole"] # 0x33d6 - - "㏗": [t: "p h"] # 0x33d7 + - "㏗": [T: "p h"] # 0x33d7 - "㏘": [t: "pikometry"] # 0x33d8 - "㏙": [t: "części na milion"] # 0x33d9 - "㏚": [t: "petarentgeny"] # 0x33da @@ -2992,30 +2991,30 @@ - "": [t: "stała Plancka przez dwa pi kreska"] # 0xed00 - "": [t: "lustrzane g"] # 0xed01 - "": [t: "j bez kropki"] # 0xed02 - - "": [t: "digamma"] # 0xed03 - - "ϝ": [t: "digamma"] # 0x3dd - - "": [t: "d"] # 0xed10 - - "ⅆ": [t: "d"] # 0x2146 + - "": [T: "digamma"] # 0xed03 + - "ϝ": [T: "digamma"] # 0x3dd + - "": [T: "d"] # 0xed10 + - "ⅆ": [T: "d"] # 0x2146 - "": [t: "e"] # 0xed11 - "ⅇ": [t: "e"] # 0x2147 - "": [t: "i"] # 0xed12 - "ⅈ": [t: "i"] # 0x2148 - - "": [t: "j"] # 0xed13 + - "": [T: "j"] # 0xed13 - "ⅅ": - spell: "translate('.', 'ⅅ', 'DD')" # 0xed16, 0x2145 # The private use chars are from MathType - "": [t: "całka krzywoliniowa z pętlą przeciwnie do ruchu wskazówek zegara"] # 0xee00 - "": [t: "całka krzywoliniowa z pętlą zgodnie z ruchem wskazówek zegara"] # 0xee01 - - "": [t: ""] # 0xee04 - - "": [t: ""] # 0xee05 - - "": [t: ""] # 0xee06 - - "": [t: ""] # 0xee07 - - "": [t: ""] # 0xee08 - - "": [t: ""] # 0xee09 - - "": [t: ""] # 0xee0a - - "": [t: ""] # 0xee0b - - "": [t: ""] # 0xee0c + - "": [T: ""] # 0xee04 + - "": [T: ""] # 0xee05 + - "": [T: ""] # 0xee06 + - "": [T: ""] # 0xee07 + - "": [T: ""] # 0xee08 + - "": [T: ""] # 0xee09 + - "": [T: ""] # 0xee0a + - "": [T: ""] # 0xee0b + - "": [T: ""] # 0xee0c - "": [t: "ozdobnik statusu połączenia"] # 0xee0d - "": [t: "lewy ozdobnik statusu połączenia"] # 0xee0e - "": [t: "prawy ozdobnik statusu połączenia"] # 0xee0f @@ -3040,24 +3039,24 @@ - "": [t: "kreska akcent z zamkniętym okręgiem po prawej"] # 0xee23 - "": [t: "duży kropka nad"] # 0xee24 - "": [t: "znak wyrównania"] # 0xef00 - - "": [t: ""] # 0xef01 - - "​": [t: ""] # 0x200b - - "": [t: ""] # 0xef02 - - " ": [t: ""] # 0x2009 - - "": [t: ""] # 0xef03 - - " ": [t: ""] # 0x205f - - "": [t: ""] # 0xef04 - - "": [t: ""] # 0xef05 - - "": [t: ""] # 0xef06 - - "": [t: ""] # 0xef07 - - "": [t: ""] # 0xef08 - - "": [t: ""] # 0xef09 - - "": [t: ""] # 0xef0a - - " ": [t: ""] # 0x200a - - "": [t: ""] # 0xef22 - - "": [t: ""] # 0xef23 - - "": [t: ""] # 0xef24 - - "": [t: ""] # 0xef29 + - "": [T: ""] # 0xef01 + - "​": [T: ""] # 0x200b + - "": [T: ""] # 0xef02 + - " ": [T: ""] # 0x2009 + - "": [T: ""] # 0xef03 + - " ": [T: ""] # 0x205f + - "": [T: ""] # 0xef04 + - "": [T: ""] # 0xef05 + - "": [T: ""] # 0xef06 + - "": [T: ""] # 0xef07 + - "": [T: ""] # 0xef08 + - "": [T: ""] # 0xef09 + - "": [T: ""] # 0xef0a + - " ": [T: ""] # 0x200a + - "": [T: ""] # 0xef22 + - "": [T: ""] # 0xef23 + - "": [T: ""] # 0xef24 + - "": [T: ""] # 0xef29 - "": [t: "brakujący składnik"] # 0xef41 - "": [t: "całka krzywoliniowa zgodna z ruchem wskazówek zegara ze strzałką po lewej"] # 0xef80 - "": [t: "całka z kwadrat"] # 0xef81 @@ -3564,13 +3563,13 @@ - "": [t: "prawy nawias klamrowy środkowy"] # 0xf8fd - "": [t: "prawy nawias klamrowy dolny"] # 0xf8fe - "": [t: "logo jabłka"] # 0xf8ff - - "ff": [t: "ff"] # 0xfb00 + - "ff": [T: "ff"] # 0xfb00 - "fi": [t: "fi"] # 0xfb01 - - "fl": [t: "fl"] # 0xfb02 - - "ffi": [t: "ffi"] # 0xfb03 - - "ffl": [t: "ffl"] # 0xfb04 - - "ſt": [t: "ft"] # 0xfb05 - - "st": [t: "st"] # 0xfb06 + - "fl": [T: "fl"] # 0xfb02 + - "ffi": [T: "ffi"] # 0xfb03 + - "ffl": [T: "ffl"] # 0xfb04 + - "ſt": [T: "ft"] # 0xfb05 + - "st": [T: "st"] # 0xfb06 - "﬩": [t: "hebrajska litera alternatywny znak plus"] # 0xfb29 - "︠": [t: "lewa połowa ligatury, ozdobnik"] # 0xfe20 - "︡": [t: "prawa połowa ligatury, ozdobnik"] # 0xfe21 diff --git a/Rules/Languages/pl/unicode.yaml b/Rules/Languages/pl/unicode.yaml index 6d90fdcd3..bd3ee353a 100644 --- a/Rules/Languages/pl/unicode.yaml +++ b/Rules/Languages/pl/unicode.yaml @@ -60,9 +60,9 @@ # note: processing of ranges converts '.' into the character, so it needs to be in quotes below replace: [spell: "translate('.', 'BCDEFGHIJKLMNOPQRSTUVWXYZ', 'bcdefghijklmnopqrstuvwxyz')"] - - "0-9": [t: "."] + - "0-9": [T: "."] - - " ": [t: " "] # 0x20 + - " ": [T: " "] # 0x20 - "!": # 0x21 - test: @@ -337,8 +337,8 @@ (@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) )" then: [T: "z"] - - "⁢": [t: ""] # 0x2062 - - "⁣": [t: ""] # 0x2063 + - "⁢": [T: ""] # 0x2062 + - "⁣": [T: ""] # 0x2063 - "⁤": [T: "i"] # 0x2064 - "′": [t: "prim"] # 0x2032 - "″": [t: "podwójny prim"] # 0x2033 diff --git a/src/navigate.rs b/src/navigate.rs index a3365ef56..1fac4e766 100644 --- a/src/navigate.rs +++ b/src/navigate.rs @@ -1765,6 +1765,59 @@ mod tests { }); } + #[test] + fn zoom_speech_pl() -> Result<()> { + let mathml_str = " + b2 + d + "; + init_prefs(mathml_str, "Enhanced", "pl")?; + return MATHML_INSTANCE.with(|package_instance| { + let package_instance = package_instance.borrow(); + let mathml = get_element(&package_instance); + let speech = test_command("ZoomIn", mathml, "msup")?; + assert_eq!("przybliż; do licznika; b do kwadratu", speech); + let speech = test_command("ZoomIn", mathml, "base")?; + assert_eq!("przybliż; do podstawy; b", speech); + let speech = test_command("ZoomOut", mathml, "msup")?; + assert_eq!("oddal; z podstawy; b do kwadratu", speech); + let speech = test_command("ZoomInAll", mathml, "base")?; + assert_eq!("przybliż maksymalnie; do podstawy; b", speech); + let speech = test_command("ZoomOutAll", mathml, "mfrac")?; + assert_eq!("oddal maksymalnie; z podstawy; z licznika; ułamek, b do kwadratu, przez d, koniec ułamka", speech); + return Ok( () ); + }); + } + + #[test] + fn move_char_speech_pl() -> Result<()> { + let mathml_str = " + + + x + y + + ⁢ + z + + "; + init_prefs(mathml_str, "Character", "pl")?; + return MATHML_INSTANCE.with(|package_instance| { + let package_instance = package_instance.borrow(); + let mathml = get_element(&package_instance); + test_command("ZoomInAll", mathml, "id-3")?; + let speech = test_command("MoveNext", mathml, "id-4")?; + assert_eq!("przejdź w prawo; do mianownika; y", speech); + let speech = test_command("MoveNext", mathml, "id-7")?; + assert_eq!("przejdź w prawo; z mianownika; do pierwiastka; z", speech); + let speech = test_command("MovePrevious", mathml, "id-4")?; + assert_eq!("przejdź w lewo; z pierwiastka; do mianownika; y", speech); + let speech = test_command("MovePrevious", mathml, "id-3")?; + assert_eq!("przejdź w lewo; do licznika; x", speech); + return Ok( () ); + }); + } + #[test] fn move_char_speech_ru() -> Result<()> { let mathml_str = " diff --git a/tests/Languages/pl/alphabets.rs b/tests/Languages/pl/alphabets.rs index 5c2aef97b..eda0a1ae4 100644 --- a/tests/Languages/pl/alphabets.rs +++ b/tests/Languages/pl/alphabets.rs @@ -391,6 +391,21 @@ fn turned() -> Result<()> { } +#[test] +fn up_tack_330() -> Result<()> { + // Znak prostopadłości i znak "dół" wyglądają identycznie, a edytory + // wstawiają U+22A5 tam, gdzie chodzi o prostopadłość. Dlatego oba znaki + // mówią "prostopadłe do", a osobna reguła LiteralSpeak zachowuje dosłowne + // czytanie U+22A5 jako "dół". + let perp = "a⟂b"; // 0x27c2 + test("pl", "SimpleSpeak", perp, "a jest prostopadłe do b")?; + test("pl", "LiteralSpeak", perp, "a jest prostopadłe do b")?; + let up_tack = "a⊥b"; // 0x22a5 + test("pl", "ClearSpeak", up_tack, "a jest prostopadłe do b")?; + test("pl", "LiteralSpeak", up_tack, "a dół b")?; + return Ok(()); + } + #[test] fn unicode_typo_regressions() -> Result<()> { test("pl", "SimpleSpeak", "ⁱ", "do potęgi i")?; diff --git a/tests/Languages/pl/definitions.rs b/tests/Languages/pl/definitions.rs index 312075f80..338f7ff95 100644 --- a/tests/Languages/pl/definitions.rs +++ b/tests/Languages/pl/definitions.rs @@ -91,7 +91,14 @@ fn set_difference_basic() -> Result<()> { "#; - test("pl", "ClearSpeak", expr, "i z wielka a przecinek, wielka b")?; + // Separator dwuargumentowy: nazwa funkcji + "z" + argumenty spięte słowem "i". + // Wcześniej nazwa przepadała i zostawało samo spoiwo ("i z wielka a..."). + test( + "pl", + "ClearSpeak", + expr, + "różnica zbiorów z wielka a i wielka b", + )?; Ok(()) } @@ -107,7 +114,9 @@ fn postfix_test() -> Result<()> { T "#, - "transpozycja z x", + // Test postfiksowy: bez jawnej fixity silnik bierze PIERWSZĄ z listy + // w IntentMappings, a tam (jak w EN) postfix jest pierwszy. + "x transponowane", ), ( "highlight", @@ -205,9 +214,11 @@ fn functions_and_inverses_tests() -> Result<()> { //("fraction", "fraction x over y end fraction"), ("mixed-fraction", "x i y"), - ("quotient", "podzielone przez z x przecinek, y"), + // Separator dwuargumentowy z IntentMappings ("| podzielone przez"): + // nazwa funkcji wraca na swoje miejsce, a spoiwo łączy oba argumenty. + ("quotient", "część całkowita z x podzielone przez y"), ("evaluated-at", "x obliczone w y"), - ("remainder", "podzielone przez z x przecinek, y"), + ("remainder", "reszta z x podzielone przez y"), ("max", "maksimum z x przecinek, y przecinek, z"), ("min", "minimum z x przecinek, y przecinek, z"), @@ -228,10 +239,18 @@ fn functions_and_inverses_tests() -> Result<()> { ("real-part", "część rzeczywista"), ("imaginary-part", "część urojona"), - ("polar-coordinate", "przecinek z x przecinek, y"), - ("spherical-coordinate", "przecinek z x przecinek, y przecinek, z"), - ("cartesian-coordinate", "przecinek z x przecinek, y przecinek, z"), - ("coordinate", "przecinek, x przecinek y przecinek z"), + // Współrzędne: po usunięciu zbędnego "; przecinek" z IntentMappings + // nazwa wraca na swoje miejsce (wcześniej wyjście brzmiało "przecinek z x..."). + ("polar-coordinate", "współrzędna biegunowa z x przecinek, y"), + ( + "spherical-coordinate", + "współrzędna sferyczna z x przecinek, y przecinek, z", + ), + ( + "cartesian-coordinate", + "współrzędna kartezjańska z x przecinek, y przecinek, z", + ), + ("coordinate", "współrzędna z x przecinek, y przecinek, z"), ("floor", "podłoga z x"), ("ceiling", "sufit z x"), @@ -598,6 +617,11 @@ fn linear_algebra_tests() -> Result<()> { " .to_string() } + "transpose" => " + + x + + ".to_string(), _ => format!( " diff --git a/tests/Languages/pl/mtable.rs b/tests/Languages/pl/mtable.rs index 8403eeae2..093cb1084 100644 --- a/tests/Languages/pl/mtable.rs +++ b/tests/Languages/pl/mtable.rs @@ -265,8 +265,8 @@ fn augmented_matrix_2x3() -> Result<()> { ] "; - test("pl", "ClearSpeak", expr, "2 na 3 macierz rozszerzona; wiersz 1; 3, 1, 4; wiersz 2; 0, 2, 6")?; - test("pl", "SimpleSpeak", expr, "2 na 3 macierz rozszerzona; wiersz 1; 3, 1, 4; wiersz 2; 0, 2, 6")?; + test("pl", "ClearSpeak", expr, "2 na 3 macierz rozszerzona; wiersz 1; 3, 1, separator, 4; wiersz 2; 0, 2, separator, 6")?; + test("pl", "SimpleSpeak", expr, "2 na 3 macierz rozszerzona; wiersz 1; 3, 1, separator, 4; wiersz 2; 0, 2, separator, 6")?; Ok(()) } @@ -897,9 +897,9 @@ let expr = " "; test_ClearSpeak("pl", "ClearSpeak_Matrix", "EndMatrix", - expr, "3 na 4 macierz rozszerzona; wiersz 1; kolumna 1; 1, kolumna 2; 2, kolumna 3; minus 1, kolumna 4; 3; wiersz 2; kolumna 1; minus 3, kolumna 2; 3, kolumna 3; minus 1, kolumna 4; 2; wiersz 3; kolumna 1; 2, kolumna 2; 3, kolumna 3; 2, kolumna 4; minus 1; koniec macierzy")?; + expr, "3 na 4 macierz rozszerzona; wiersz 1; kolumna 1; 1, kolumna 2; 2, kolumna 3; minus 1, separator, kolumna 4; 3; wiersz 2; kolumna 1; minus 3, kolumna 2; 3, kolumna 3; minus 1, separator, kolumna 4; 2; wiersz 3; kolumna 1; 2, kolumna 2; 3, kolumna 3; 2, separator, kolumna 4; minus 1; koniec macierzy")?; test("pl", "SimpleSpeak", - expr, "3 na 4 macierz rozszerzona; wiersz 1; kolumna 1; 1, kolumna 2; 2, kolumna 3; minus 1, kolumna 4; 3; wiersz 2; kolumna 1; minus 3, kolumna 2; 3, kolumna 3; minus 1, kolumna 4; 2; wiersz 3; kolumna 1; 2, kolumna 2; 3, kolumna 3; 2, kolumna 4; minus 1; koniec macierzy")?; + expr, "3 na 4 macierz rozszerzona; wiersz 1; kolumna 1; 1, kolumna 2; 2, kolumna 3; minus 1, separator, kolumna 4; 3; wiersz 2; kolumna 1; minus 3, kolumna 2; 3, kolumna 3; minus 1, separator, kolumna 4; 2; wiersz 3; kolumna 1; 2, kolumna 2; 3, kolumna 3; 2, separator, kolumna 4; minus 1; koniec macierzy")?; Ok(()) } @@ -1294,3 +1294,42 @@ fn single_line_with_label() -> Result<()> { expr, "1 równanie, z etykietą 2; b równa się 2")?; return Ok(()); } + +/// Linia pionowa w tabeli jest zapowiadana jako separator (upstream #679). +#[test] +fn dashed_augmented_matrix_separator() -> Result<()> { + let expr = " + + [ + + 123 + + ] + "; + test("pl", "ClearSpeak", expr, "jeden na 3 wiersz macierz; 1, separator, 2, separator, 3")?; + test("pl", "SimpleSpeak", expr, "jeden na 3 wiersz macierz; 1, separator, 2, separator, 3")?; + Ok(()) +} + +/// Linia pozioma wybrzmiewa RAZ, po wierszu, ktory oddziela od nastepnego. +#[test] +fn matrix_row_separator() -> Result<()> { + let expr = " + + [ + + + 1 + 2 + + + 3 + 4 + + + ] + "; + test("pl", "ClearSpeak", expr, "2 na 2 macierz; wiersz 1; 1, 2, separator wiersza; wiersz 2; 3, 4")?; + test("pl", "SimpleSpeak", expr, "2 na 2 macierz; wiersz 1; 1, 2, separator wiersza; wiersz 2; 3, 4")?; + Ok(()) +} From df565e27cdf776249c7f97d37f126c38e6fcfeed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dziwisz?= Date: Thu, 3 Sep 2026 12:59:09 +0200 Subject: [PATCH 086/157] pl: inflect unit names according to the numeral, not with an English "s" (#744) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * pl: mark the unicode translations as verified (t -> T) Mechanical change: 2435 text keys raised from t/ot/ct to T/OT/CT in the two unicode files. No text is touched. The Polish rules were written before the lowercase/uppercase convention was in use, so entries that have been translated all along still carried the "needs review" key. The audit tool therefore reported them as untranslated, which made the real gaps impossible to see: audit-translations pl, untranslated text: 3162 -> 727 The remaining 727 are in the rule files, where the entries need reading rather than a mechanical pass, so they are deliberately left alone. Every raised entry was checked to differ from the English source, i.e. it really is translated. Entries whose text legitimately equals English (Roman numerals, ligatures, proper names, whitespace) were handled separately in the previous PR; entries still holding English text are NOT raised, since that would assert a translation that does not exist. Verification: cargo test --test languages Languages::pl 609 passed, 0 failed diff: 2436 insertions, 2436 deletions, zero changes outside key case The last point is checked by normalising the key case in the diff and confirming no unpaired lines remain (without normalising, 4710 remain, so the check does discriminate). * pl: also mark the multi-line unicode entries as verified The previous commit raised the key on entries written on a single line (`- "±": [t: "..."]`), but not on entries whose body is a block: - "°": - test: if: "parent::*[name(.)='msup' ...]" then: [t: "stopni"] else: [t: "stopień"] Those are exactly the entries carrying inflection or a TTS condition, so 312 of the most deliberate translations in the file were left looking unreviewed. This raises them: 64 in unicode.yaml, 247 in unicode-full.yaml and one single-line entry (U+23E6) missed earlier. One entry is deliberately left with a lower-case key: `t: ""` for U+00A0, the else-branch of the `@data-empty-in-2D` test. That is silence rather than text, and an upper-case key means "a translator checked this wording" - there is no wording to check. English keeps a lower-case key there too. No content changes; only key case. `cargo test --test languages Languages::pl` gives 609 passed, 0 failed, which is the same result as before this commit, as expected for a change the engine treats as equivalent (src/speech.rs matches "t"|"T" in one match arm). * pl: raise the remaining rule-file keys and test the number-set rules Two loose ends in the Polish localization. **Rule-file keys.** 248 entries in the rule files still used a lower-case key while carrying translated Polish text. Content is untouched - every one of the 248 changed lines differs from its predecessor only in the case of the key name, verified line by line after normalizing the key. 17 entries are deliberately left lower-case: five are the letters C, N, Q, R, Z in `dimension-number-sets` (the letter itself is the wording, as in English); `ct: "s"`/`ct: "-"` in the unit rule are the plural suffix and prefix separator; `navigate.yaml:176` is a Polish euphony variant ("ze" before "st-"); the remaining seven are XPath expressions rather than speech. **Tests for the number-set rules.** These rules had no Polish test at all, in a file where two silent defects were already found. New `tests/Languages/pl/number_sets.rs` covers the bare symbols, the dimension form, both sign variants, and ClearSpeak agreeing with SimpleSpeak. The `number_set_with_variable_exponent` case is the negative control: `dimension-number-sets` fires on `count(*)=2`, so a non-numeric exponent must fall through to the full phrase ("liczby całkowite do potęgi n") rather than being read as a dimension. Without it, a rule that swallowed every superscript would still pass. Polish keeps the letter with a dimension ("R 3"), matching en, de, fr, nb, sv, fi and es; Hungarian is the only language that translates in that position too. Measured with the SAPI voice NVDA actually uses: "R 3" is byte-identical to a phonetic "er 3" and "N 4" to "en 4", so the letters are pronounced as their Polish names. cargo test --test languages Languages::pl 614 passed, 0 failed * pl: inflect unit names according to the numeral, not with an English "s" The `unit` rule appended `ct: "s"` whenever a unit had no entry in `PluralForms`, and the Polish `PluralForms` contained no SI base unit at all. Measured output of the engine before this change: 1 metr, 2 metrs, 5 metrs, 21 metrs, 2 grams, 2 sekundas, 2 ampers, 2 mols, 2 kilo-metrs So a Polish NVDA user heard an English plural ending on essentially every quantity. Hungarian avoids this with `CT: ""` (it appends nothing); French and German legitimately use "s"; Russian, whose plurals work like Polish, does not rely on a suffix at all and fills in `PluralForms` instead. Polish was in the wrong group. Polish does not have one plural form. The noun follows the numeral: 1 metr | 2, 3, 4 metry (nominative plural) | 5 metrów (genitive plural) and the teens are the exception that breaks the naive rule: 12, 13, 14 metrów, likewise 112-114, while 22 and 102 take the nominative again. One extra plural column is therefore not enough, so this adds a second definition section, `PluralGenitive`, next to `PluralForms` (now the nominative plural). No Rust change is needed: `build_values` accepts any definition name as a hashmap. The `unit` rule (both the bare and the prefixed branch) and the `currency` rule now read the value of the numeral and pick the section accordingly. When the numeral cannot be determined - a variable coefficient, as in "x ms" - `$Coefficient` is 0 and the genitive is used, which is also what Polish uses for unknown quantities ("x mili-sekund"). Where no inflected form is known the singular is spoken rather than a guessed ending: a wrong ending is worse for a screen reader user than a missing one. Both sections cover all 131 unit and currency names that the Polish `SIUnits`, `UnitsWithoutPrefixes`, `EnglishUnits` and `CurrencySymbols` can produce. The forms are written out because Polish inflection cannot be derived from the ending: metr/metry but litr/litry, om/omy, dzień/dni, tydzień/tygodnie, rok/lata. Multi-word units inflect the head noun and keep the dependent word's case ("5 lat świetlnych", "5 minut łuku"). They were checked against hunspell pl_PL; the only words it does not know are the binary-prefix neologisms (kibibajt, gibibit, ...) whose singular forms already existed in the file. Three base forms were themselves wrong - plurals used as singulars, so the engine said "1 herce" and "1 konie mechaniczne": Hz herce -> herc hp konie mechaniczne -> koń mechaniczny ℧ M h o -> mho Every other language has a singular here (en hertz, ru герц, fi hertsi, es hercio; hp: ru "лошадиная сила", hu "lóerő", nb "hestekraft"; ℧: de/fr "mho"). Why this survived: the existing Polish expectations in tests/Languages/pl/units.rs recorded the broken output, so 609 tests passed while the speech was wrong ("2 dzieńs", "2 tydzieńs", "kwetta-grams"). Expectations harvested from real engine output are a good regression net but prove nothing about correctness unless they are read as a user would hear them. 21 test expectations are updated here, each difference reviewed word by word. Verification: cargo test --test languages Languages::pl 615 passed, 0 failed reverting general.yaml alone -> 6 of 6 new tests fail The new tests in tests/Languages/pl/unit_plurals.rs cover one class of phenomenon each: the three numeral classes including the teens exception, SI base units, the prefixed branch of the rule, irregular nouns, the corrected base forms, and multi-word units. --- Rules/Languages/pl/ClearSpeak_Rules.yaml | 50 +- Rules/Languages/pl/SharedRules/calculus.yaml | 12 +- Rules/Languages/pl/SharedRules/default.yaml | 80 +- Rules/Languages/pl/SharedRules/general.yaml | 189 +- Rules/Languages/pl/SharedRules/geometry.yaml | 14 +- .../pl/SharedRules/linear-algebra.yaml | 2 +- Rules/Languages/pl/definitions.yaml | 286 +- Rules/Languages/pl/navigate.yaml | 152 +- Rules/Languages/pl/overview.yaml | 30 +- Rules/Languages/pl/unicode-full.yaml | 5238 ++++++++--------- Rules/Languages/pl/unicode.yaml | 262 +- tests/Languages/pl.rs | 2 + tests/Languages/pl/ClearSpeak/mfrac.rs | 2 +- tests/Languages/pl/SimpleSpeak/mfrac.rs | 6 +- tests/Languages/pl/number_sets.rs | 69 + tests/Languages/pl/unit_plurals.rs | 86 + tests/Languages/pl/units.rs | 38 +- 17 files changed, 3474 insertions(+), 3044 deletions(-) create mode 100644 tests/Languages/pl/number_sets.rs create mode 100644 tests/Languages/pl/unit_plurals.rs diff --git a/Rules/Languages/pl/ClearSpeak_Rules.yaml b/Rules/Languages/pl/ClearSpeak_Rules.yaml index 5e6cca14c..c7bb0fc7f 100644 --- a/Rules/Languages/pl/ClearSpeak_Rules.yaml +++ b/Rules/Languages/pl/ClearSpeak_Rules.yaml @@ -228,13 +228,13 @@ tag: fraction match: "." replace: - - t: "ułamek z licznikiem" # phrase(the 'fraction with numerator' 6) + - T: "ułamek z licznikiem" # phrase(the 'fraction with numerator' 6) - test: if: "not(IsNode(*[1], 'simple'))" then: [pause: medium] - x: "*[1]" - pause: medium - - t: "i mianownikiem" # phrase(the fraction with numerator 5 'and denominator' 8) + - T: "i mianownikiem" # phrase(the fraction with numerator 5 'and denominator' 8) - x: "*[2]" - pause: long - test: @@ -525,7 +525,7 @@ replace: - test: - if: "count(*)=0" - then: [t: "zbiór pusty"] # phrase('the empty set') + then: [T: "zbiór pusty"] # phrase('the empty set') - else_if: "count(*)=2" then: - test: @@ -537,10 +537,10 @@ - test: if: "$Verbosity!='Terse'" then: [T: ""] # phrase('the' set of all integers) - - t: "zbiór" # phrase(this is a 'set of' numbers) + - T: "zbiór" # phrase(this is a 'set of' numbers) - test: if: "$ClearSpeak_Sets != 'woAll'" - then: [t: "wszystkie"] # phrase(the set of 'all' integers) + then: [T: "wszystkie"] # phrase(the set of 'all' integers) - x: "*[1]/*[1]" - T: "takich że" # phrase(the set S 'such that' x is less than y) - x: "*[1]/*[3]" @@ -645,31 +645,31 @@ - if: "$IsCase" then_test: - if: "$LineCount = 1" - then: [t: "przypadek"] # phrase(this is the first 'case' of three cases) + then: [T: "przypadek"] # phrase(this is the first 'case' of three cases) - else_if: "$Paucal" - then: [t: "przypadki"] # phrase(there are 'two cases' to consider) - else: [t: "przypadków"] # phrase(there are 'five cases' to consider) + then: [T: "przypadki"] # phrase(there are 'two cases' to consider) + else: [T: "przypadków"] # phrase(there are 'five cases' to consider) - else_if: "$IsLine" then_test: - if: "$LineCount = 1" - then: [t: "linia"] # phrase(this is the first 'line' of three lines) + then: [T: "linia"] # phrase(this is the first 'line' of three lines) - else_if: "$Paucal" - then: [t: "linie"] # phrase(there are 'two lines' shown) - else: [t: "linii"] # phrase(there are 'five lines' shown) + then: [T: "linie"] # phrase(there are 'two lines' shown) + else: [T: "linii"] # phrase(there are 'five lines' shown) - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" then_test: - if: "$LineCount = 1" - then: [t: "warunek"] # phrase(this is the first 'constraint' of three constraints) + then: [T: "warunek"] # phrase(this is the first 'constraint' of three constraints) - else_if: "$Paucal" - then: [t: "warunki"] # phrase(there are 'two constraints' to satisfy) - else: [t: "warunków"] # phrase(there are 'five constraints' to satisfy) + then: [T: "warunki"] # phrase(there are 'two constraints' to satisfy) + else: [T: "warunków"] # phrase(there are 'five constraints' to satisfy) - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" then_test: - if: "$LineCount = 1" - then: [t: "równanie"] # phrase(this is the first 'equation' of three equations) + then: [T: "równanie"] # phrase(this is the first 'equation' of three equations) - else_if: "$Paucal" - then: [t: "równania"] # phrase(there are 'two equations' to solve) - else: [t: "równań"] # phrase(there are 'five equations' to solve) + then: [T: "równania"] # phrase(there are 'two equations' to solve) + else: [T: "równań"] # phrase(there are 'five equations' to solve) - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" then_test: - if: "$LineCount = 1" @@ -680,10 +680,10 @@ - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" then_test: - if: "$LineCount = 1" - then: [t: "krok"] # phrase(this is the first 'step' of three steps) + then: [T: "krok"] # phrase(this is the first 'step' of three steps) - else_if: "$Paucal" - then: [t: "kroki"] # phrase(there are 'two steps' to follow) - else: [t: "kroków"] # phrase(there are 'five steps' to follow) + then: [T: "kroki"] # phrase(there are 'two steps' to follow) + else: [T: "kroków"] # phrase(there are 'five steps' to follow) # else 'None -- don't say anything' - pause: short - x: "*" @@ -700,17 +700,17 @@ - pause: medium - test: - if: "($ClearSpeak_MultiLineLabel = 'Auto' and parent::m:piecewise) or $ClearSpeak_MultiLineLabel = 'Case'" - then: [t: "przypadek"] # phrase(in this 'case' x is not equal to y) + then: [T: "przypadek"] # phrase(in this 'case' x is not equal to y) - else_if: "$ClearSpeak_MultiLineLabel = 'Auto' or $ClearSpeak_MultiLineLabel = 'Line'" # already dealt with Auto/Case - then: [t: "linia"] # phrase(the straight 'line' between x and y) + then: [T: "linia"] # phrase(the straight 'line' between x and y) - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" - then: [t: "warunek"] # phrase(there is a 'constraint' on possible values) + then: [T: "warunek"] # phrase(there is a 'constraint' on possible values) - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" - then: [t: "równanie"] # phrase(the 'equation' pi r squared gives the area of a circle) + then: [T: "równanie"] # phrase(the 'equation' pi r squared gives the area of a circle) - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" then: [T: "wiersz"] # phrase(the values on the top 'row' are relevant) - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" - then: [t: "krok"] # phrase(this is a 'step' by step process) + then: [T: "krok"] # phrase(this is a 'step' by step process) # else 'None -- don't say anything' - x: "count(preceding-sibling::*[not(contains(@data-intent-property, ':continued-row:'))]) + 1" - test: diff --git a/Rules/Languages/pl/SharedRules/calculus.yaml b/Rules/Languages/pl/SharedRules/calculus.yaml index 777ca4171..4d499f9a8 100644 --- a/Rules/Languages/pl/SharedRules/calculus.yaml +++ b/Rules/Languages/pl/SharedRules/calculus.yaml @@ -4,7 +4,7 @@ tag: laplacian match: "count(*) <= 1" # can be on ∇^2 or on enclosing mrow replace: - - t: "laplasjan" # phrase('laplacian' of x) -- "LahPlahsian" sounds better with speech engines tested + - T: "laplasjan" # phrase('laplacian' of x) -- "LahPlahsian" sounds better with speech engines tested - test: if: "count(*) = 1" then: @@ -22,8 +22,8 @@ replace: - test: if: "$Verbosity='Terse'" - then: [t: "dywergencja"] # phrase('div' is short for divergence) -- note OneCore voices spell out "div" - else: [t: "dywergencja z"] # phrase('divergence of' this function from the mean) + then: [T: "dywergencja"] # phrase('div' is short for divergence) -- note OneCore voices spell out "div" + else: [T: "dywergencja z"] # phrase('divergence of' this function from the mean) - test: if: "not(IsNode(*[1], 'leaf'))" then: [pause: short] @@ -33,7 +33,7 @@ tag: curl match: "count(*) = 1" replace: - - t: "rotacja" # phrase(the 'curl of' a field) + - T: "rotacja" # phrase(the 'curl of' a field) - test: if: "$Verbosity!='Terse'" then: [T: "z"] # phrase(function 'of' one variable) -- note OneCore voices spell out "div" @@ -48,8 +48,8 @@ replace: - test: if: "$Verbosity!='Terse'" - then: [t: "gradient z"] # phrase(the hill has a 'gradient of' five percent) - else: [t: "gradient"] # phrase(the delete key is labeled 'del') + then: [T: "gradient z"] # phrase(the hill has a 'gradient of' five percent) + else: [T: "gradient"] # phrase(the delete key is labeled 'del') - test: if: "not(IsNode(*[1], 'leaf'))" then: [pause: short] diff --git a/Rules/Languages/pl/SharedRules/default.yaml b/Rules/Languages/pl/SharedRules/default.yaml index 531f57a5d..8397efb7b 100644 --- a/Rules/Languages/pl/SharedRules/default.yaml +++ b/Rules/Languages/pl/SharedRules/default.yaml @@ -100,7 +100,7 @@ tag: ms match: "." replace: - - t: "string" # phrase('the string' is long) + - T: "string" # phrase('the string' is long) - pause: short - x: "text()" @@ -142,7 +142,7 @@ - pause: short - test: if: "$Impairment = 'Blindness'" - then: [t: "koniec ułamka"] # phrase("start of fraction x over y 'end over'") + then: [T: "koniec ułamka"] # phrase("start of fraction x over y 'end over'") - pause: medium @@ -332,7 +332,7 @@ then: - T: "z" # phrase(substitute x 'with' y) - x: "count($Prescripts) div 2" - - t: "lewe indeksy" # phrase(in this equation certain 'prescripts' apply) + - T: "lewe indeksy" # phrase(in this equation certain 'prescripts' apply) - pause: short - test: if: "not($Prescripts[1][self::m:none])" @@ -367,9 +367,9 @@ - test: if: "count($Prescripts) > 4" # give up and just dump them out so at least the content is there then: - - t: "i kolejne lewe indeksy" # phrase(in this case there are values 'and alternating prescripts') + - T: "i kolejne lewe indeksy" # phrase(in this case there are values 'and alternating prescripts') - x: "$Prescripts[position() > 4]" - - t: "koniec lewych indeksów" # phrase(This is where 'end prescripts' occurs) + - T: "koniec lewych indeksów" # phrase(This is where 'end prescripts' occurs) - test: if: "$Postscripts" then: @@ -386,7 +386,7 @@ then: [T: "i"] # phrase(10 is greater than 8 'and' less than 15) - T: "z" # phrase(substitute x 'with' y) - x: "count($Postscripts) div 2" - - t: "prawe indeksy" # phrase(this material includes several 'postscripts') + - T: "prawe indeksy" # phrase(this material includes several 'postscripts') - pause: short - test: if: "not($Postscripts[1][self::m:none])" @@ -452,9 +452,9 @@ - test: if: "count($Postscripts) > 8" # give up and just dump them out so at least the content is there then: - - t: "i kolejne indeksy" # phrase(this situation involves complexities 'and alternating scripts') + - T: "i kolejne indeksy" # phrase(this situation involves complexities 'and alternating scripts') - x: "$Postscripts[position() > 8]" - - t: "koniec indeksów" # phrase(At this point 'end scripts' occurs) + - T: "koniec indeksów" # phrase(At this point 'end scripts' occurs) - name: default tag: mtable @@ -540,7 +540,7 @@ tag: menclose match: "@notation='box' and *[self::m:mtext and .=' ']" replace: - - t: "pusta ramka" # phrase(the 'empty box' contains no values) + - T: "pusta ramka" # phrase(the 'empty box' contains no values) - name: default # The ordering below is the order in which words come out when there is more than one value @@ -550,29 +550,29 @@ replace: - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' box ')]" - then: [t: "ramka", pause: short] # phrase(the 'box' around the expression) + then: [T: "ramka", pause: short] # phrase(the 'box' around the expression) - test: if: ".[contains(@notation,'roundedbox')]" - then: [t: "zaokrąglona ramka", pause: short] # phrase(the 'round box' around the expression) + then: [T: "zaokrąglona ramka", pause: short] # phrase(the 'round box' around the expression) - test: if: ".[contains(@notation,'circle')]" - then: [t: "okrąg", pause: short] # phrase(the 'circle' around the expression) + then: [T: "okrąg", pause: short] # phrase(the 'circle' around the expression) - test: if: ".[ contains(concat(' ', normalize-space(@notation), ' '), ' left ') or contains(concat(' ', normalize-space(@notation), ' '), ' right ') or contains(@notation,'top') or contains(@notation,'bottom') ]" then: - - t: "linia na" # phrase(draw a straight 'line' on the page) + - T: "linia na" # phrase(draw a straight 'line' on the page) - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' left ')]" - then: [t: "lewo", pause: short] # phrase(line on 'left' of the expression) + then: [T: "lewo", pause: short] # phrase(line on 'left' of the expression) - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' right ')]" - then: [t: "prawo", pause: short] # phrase(line on 'right' of the expression) + then: [T: "prawo", pause: short] # phrase(line on 'right' of the expression) - test: if: ".[contains(@notation,'top')]" - then: [t: "góra", pause: short] # phrase(line on 'top' of the expression) + then: [T: "góra", pause: short] # phrase(line on 'top' of the expression) - test: if: ".[contains(@notation,'bottom')]" - then: [t: "dół", pause: short] # phrase(line on the 'bottom' of the expression) + then: [T: "dół", pause: short] # phrase(line on the 'bottom' of the expression) - test: if: ".[ contains(@notation,'updiagonalstrike') or contains(@notation,'downdiagonalstrike') or contains(@notation,'verticalstrike') or contains(@notation,'horizontalstrike') ]" then: @@ -582,77 +582,77 @@ else: - test: if: ".[contains(@notation,'updiagonalstrike')]" - then: [t: "ukośnie w górę", pause: short] # phrase(the line runs 'up diagonal') + then: [T: "ukośnie w górę", pause: short] # phrase(the line runs 'up diagonal') - test: if: ".[contains(@notation,'downdiagonalstrike')]" - then: [t: "ukośnie w dół", pause: short] # phrase(the line runs 'down diagonal') + then: [T: "ukośnie w dół", pause: short] # phrase(the line runs 'down diagonal') - test: if: ".[contains(@notation,'verticalstrike')]" - then: [t: "pionowy", pause: short] # phrase(the line is 'vertical') + then: [T: "pionowy", pause: short] # phrase(the line is 'vertical') - test: if: ".[contains(@notation,'horizontalstrike')]" - then: [t: "poziomy", pause: short] # phrase(the line is 'horizontal') - - t: "krzyż na zewnątrz" # phrase(please 'cross out' the incorrect answer) + then: [T: "poziomy", pause: short] # phrase(the line is 'horizontal') + - T: "krzyż na zewnątrz" # phrase(please 'cross out' the incorrect answer) - pause: short - test: if: ".[contains(@notation,'uparrow')]" - then: [t: "strzałka w górę", pause: short] # phrase(direction is shown by the 'up arrow') + then: [T: "strzałka w górę", pause: short] # phrase(direction is shown by the 'up arrow') - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' downarrow ')]" - then: [t: "strzałka w dół", pause: short] # phrase(the trend is shown by the 'down arrow') + then: [T: "strzałka w dół", pause: short] # phrase(the trend is shown by the 'down arrow') - test: if: ".[contains(@notation,'leftarrow')]" - then: [t: "strzałka w lewo", pause: short] # phrase(the 'left arrow' indicates going back) + then: [T: "strzałka w lewo", pause: short] # phrase(the 'left arrow' indicates going back) - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' rightarrow ')]" - then: [t: "strzałka w prawo", pause: short] # phrase(the 'right arrow' indicates moving forward) + then: [T: "strzałka w prawo", pause: short] # phrase(the 'right arrow' indicates moving forward) - test: if: ".[contains(@notation,'northeastarrow')]" - then: [t: "strzałka na północny wschód", pause: short] # phrase(direction is indicated by the 'northeast arrow') + then: [T: "strzałka na północny wschód", pause: short] # phrase(direction is indicated by the 'northeast arrow') - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' southeastarrow ')]" - then: [t: "strzałka na południowy wschód", pause: short] # phrase(direction is shown by the 'southeast arrow') + then: [T: "strzałka na południowy wschód", pause: short] # phrase(direction is shown by the 'southeast arrow') - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' southwestarrow ')]" - then: [t: "strzałka na południowy zachód", pause: short] # phrase(direction is shown by the 'southwest arrow') + then: [T: "strzałka na południowy zachód", pause: short] # phrase(direction is shown by the 'southwest arrow') - test: if: ".[contains(@notation,'northwestarrow')]" - then: [t: "strzałka na północny zachód", pause: short] # phrase(direction is shown by the 'northwest arrow') + then: [T: "strzałka na północny zachód", pause: short] # phrase(direction is shown by the 'northwest arrow') - test: if: ".[contains(@notation,'updownarrow')]" - then: [t: "strzałka dwukierunkowa pionowa", pause: short] # phrase(upward movement is indicated by the 'double ended vertical arrow') + then: [T: "strzałka dwukierunkowa pionowa", pause: short] # phrase(upward movement is indicated by the 'double ended vertical arrow') - test: if: ".[contains(@notation,'leftrightarrow')]" - then: [t: "strzałka dwukierunkowa pozioma", pause: short] # phrase(progress is indicated by the 'double ended horizontal arrow') + then: [T: "strzałka dwukierunkowa pozioma", pause: short] # phrase(progress is indicated by the 'double ended horizontal arrow') - test: if: ".[contains(@notation,'northeastsouthwestarrow')]" - then: [t: "strzałka dwukierunkowa ukośna w górę", pause: short] # phrase(trend is indicated by the 'double ended up diagonal arrow') + then: [T: "strzałka dwukierunkowa ukośna w górę", pause: short] # phrase(trend is indicated by the 'double ended up diagonal arrow') - test: if: ".[contains(@notation,'northwestsoutheastarrow')]" - then: [t: "strzałka dwukierunkowa ukośna w dół", pause: short] # phrase(trend is indicated by the 'double ended down diagonal arrow') + then: [T: "strzałka dwukierunkowa ukośna w dół", pause: short] # phrase(trend is indicated by the 'double ended down diagonal arrow') - test: if: ".[contains(@notation,'actuarial')]" - then: [t: "symbol aktuarialny", pause: short] # phrase(the 'actuarial symbol' represents a specific quantity) + then: [T: "symbol aktuarialny", pause: short] # phrase(the 'actuarial symbol' represents a specific quantity) - test: if: ".[contains(@notation,'madrub')]" - then: [t: "arabski symbol silni", pause: short] # phrase(the 'arabic factorial symbol' represents a factorial operation) + then: [T: "arabski symbol silni", pause: short] # phrase(the 'arabic factorial symbol' represents a factorial operation) - test: if: ".[contains(@notation,'phasorangle')]" - then: [t: "kąt fazowy", pause: short] # phrase(the 'phasor angle' is used to measure electrical current) + then: [T: "kąt fazowy", pause: short] # phrase(the 'phasor angle' is used to measure electrical current) - test: if: ".[contains(@notation,'longdiv') or not(@notation) or normalize-space(@notation) ='']" # default - then: [t: "znak dzielenia pisemnego", pause: short] # phrase(the 'long division symbol' indicates a long division calculation) + then: [T: "znak dzielenia pisemnego", pause: short] # phrase(the 'long division symbol' indicates a long division calculation) - test: if: ".[contains(@notation,'radical')]" then: [T: "pierwiastek kwadratowy", pause: short] # phrase(5 is the 'square root' of 25) - - t: "obejmujący" # phrase(parentheses are 'enclosing' part of the equation) + - T: "obejmujący" # phrase(parentheses are 'enclosing' part of the equation) - test: if: "*[self::m:mtext and .=' ']" then: [T: "spacja"] # otherwise there is complete silence # phrase(there is a 'space' between the words) else: [x: "*"] - test: if: "$Impairment = 'Blindness' and ( $SpeechStyle != 'SimpleSpeak' or not(IsNode(*[1], 'leaf')) )" - then: [t: "koniec obramowania"] # phrase(reached the 'end enclosure' point) + then: [T: "koniec obramowania"] # phrase(reached the 'end enclosure' point) - pause: short - name: semantics diff --git a/Rules/Languages/pl/SharedRules/general.yaml b/Rules/Languages/pl/SharedRules/general.yaml index 40e996f49..f3d026f2b 100644 --- a/Rules/Languages/pl/SharedRules/general.yaml +++ b/Rules/Languages/pl/SharedRules/general.yaml @@ -17,15 +17,15 @@ - bookmark: "*[1]/@id" - test: - if: "*[1][.='ℂ']" - then: [t: "liczby zespolone"] # phrase('complex numbers' consist of two parts) + then: [T: "liczby zespolone"] # phrase('complex numbers' consist of two parts) - else_if: "*[1][.='ℕ']" - then: [t: "liczby naturalne"] # phrase('natural numbers' are numbers from 1 to infinity) + then: [T: "liczby naturalne"] # phrase('natural numbers' are numbers from 1 to infinity) - else_if: "*[1][.='ℚ']" - then: [t: "liczby wymierne"] # phrase('rational numbers' are the fraction of 2 integers) + then: [T: "liczby wymierne"] # phrase('rational numbers' are the fraction of 2 integers) - else_if: "*[1][.='ℝ']" - then: [t: "liczby rzeczywiste"] # phrase('real numbers' can be both positive and negative) + then: [T: "liczby rzeczywiste"] # phrase('real numbers' can be both positive and negative) - else_if: "*[1][.='ℤ']" - then: [t: "liczby całkowite"] # phrase(positive 'integers' are natural numbers above 0) + then: [T: "liczby całkowite"] # phrase(positive 'integers' are natural numbers above 0) else: [x: "*[1][text()]"] # shouldn't happen - name: dimension-number-sets @@ -57,15 +57,15 @@ - bookmark: "@id" - test: - if: ".='ℂ'" - then: [t: "liczby zespolone"] # phrase('the complex numbers' include 2 parts) + then: [T: "liczby zespolone"] # phrase('the complex numbers' include 2 parts) - else_if: ".='ℕ'" - then: [t: "liczby naturalne"] # phrase('the natural numbers' begin at 1) + then: [T: "liczby naturalne"] # phrase('the natural numbers' begin at 1) - else_if: ".='ℚ'" - then: [t: "liczby wymierne"] # phrase('the rational numbers' are the fraction of 2 integers) + then: [T: "liczby wymierne"] # phrase('the rational numbers' are the fraction of 2 integers) - else_if: ".='ℝ'" - then: [t: "liczby rzeczywiste"] # phrase('the real numbers' can be both positive and negative) + then: [T: "liczby rzeczywiste"] # phrase('the real numbers' can be both positive and negative) - else_if: ".='ℤ'" - then: [t: "liczby całkowite"] # phrase('the integers' are natural numbers above 0) + then: [T: "liczby całkowite"] # phrase('the integers' are natural numbers above 0) else: [x: "text()"] # shouldn't happen - name: word-degree-celsius-fahrenheit-unit @@ -101,14 +101,14 @@ match: "." replace: - bookmark: "@id" - - t: "część rzeczywista" # phrase('the real part' of a complex number does not include the imaginary part) + - T: "część rzeczywista" # phrase('the real part' of a complex number does not include the imaginary part) - name: imaginary-part tag: imaginary-part match: "." replace: - bookmark: "@id" - - t: "część urojona" # phrase('the imaginary part' is part of a complex number) + - T: "część urojona" # phrase('the imaginary part' is part of a complex number) # rules on scripted vertical bars ('evaluated at') - name: evaluated-at-2 @@ -117,7 +117,7 @@ replace: - x: "*[1]" - pause: auto - - t: "obliczone w" # phrase(results were 'evaluated at' a given point) + - T: "obliczone w" # phrase(results were 'evaluated at' a given point) - pause: auto - x: "*[2]" @@ -127,10 +127,10 @@ replace: - x: "*[1]" - pause: auto - - t: "obliczone w" # phrase(results were 'evaluated at' this point) + - T: "obliczone w" # phrase(results were 'evaluated at' this point) - pause: auto - x: "*[3]" - - t: "minus to samo wyrażenie obliczone w" # phrase(this result is 'minus the same expression evaluated at' an earlier point) + - T: "minus to samo wyrażenie obliczone w" # phrase(this result is 'minus the same expression evaluated at' an earlier point) - x: "*[2]" - name: permutation @@ -139,7 +139,7 @@ match: "count(*)=2 and contains(@data-intent-property, ':infix:')" replace: - x: "*[2]" - - t: "permutacji z" # phrase(the solution involves several 'permutations of' values) + - T: "permutacji z" # phrase(the solution involves several 'permutations of' values) - x: "*[1]" - name: intervals @@ -221,7 +221,7 @@ match: "." replace: - x: "*[1]" - - t: "z okresem" # phrase('with repeating digits') + - T: "z okresem" # phrase('with repeating digits') - spell: "*[2]" - name: msubsup-skip-super @@ -286,6 +286,15 @@ IfThenElse(parent::m:power[parent::m:fraction and not(preceding-sibling::*)], ancestor::*[3][self::m:mrow], false()) ) ) )" - IsSingular: "(not($MRowForCoefficient) and parent::*[name(.)!='skip-super' or *[1][.=1]]) or ($MRowForCoefficient and $MRowForCoefficient[(count(*) = 3 and *[1][self::m:mn and .=1] and *[2]='\u2062')])" + # Polish plural depends on the numeral, not only on "is it one": + # 1 metr | 2, 3, 4 metry (nominative plural) | 5 metrów (genitive plural) + # and the teens break the naive rule: 12, 13, 14 metrów (genitive, despite + # ending in 2, 3, 4), likewise 112-114. $Coefficient is 0 when the numeral + # cannot be determined, which falls through to the genitive - the form + # Polish uses with unknown or large quantities. + - Coefficient: "IfThenElse($MRowForCoefficient, number($MRowForCoefficient/*[1][self::m:mn]), 0)" + - IsNominativePlural: "$Coefficient mod 10 >= 2 and $Coefficient mod 10 <= 4 and + not($Coefficient mod 100 >= 12 and $Coefficient mod 100 <= 14)" - Prefix: "''" - Word: "''" replace: @@ -333,9 +342,13 @@ - if: "$IsSingular" # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets the prefix concatenated to the base then: [x: "$Word"] - - else_if: "DefinitionValue($Word, 'Speech', 'PluralForms') != ''" + - else_if: "$IsNominativePlural and DefinitionValue($Word, 'Speech', 'PluralForms') != ''" then: [x: "DefinitionValue($Word, 'Speech', 'PluralForms')"] - else: [x: "$Word", ct: "s"] + - else_if: "DefinitionValue($Word, 'Speech', 'PluralGenitive') != ''" + then: [x: "DefinitionValue($Word, 'Speech', 'PluralGenitive')"] + # No inflected form is known: speak the singular, because a wrong + # ending is worse for a screen reader user than a missing one. + else: [x: "$Word"] else: - x: "$Prefix" - ct: "-" @@ -343,9 +356,11 @@ - if: "$IsSingular" # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets the prefix concatenated to the base then: [x: "concat('\uF8FE', $Word)"] - - else_if: "DefinitionValue($Word, 'Speech', 'PluralForms') != ''" + - else_if: "$IsNominativePlural and DefinitionValue($Word, 'Speech', 'PluralForms') != ''" then: [x: "concat('\uF8FE', DefinitionValue($Word, 'Speech', 'PluralForms'))"] - else: [x: "concat('\uF8FE', $Word)", ct: "s"] + - else_if: "DefinitionValue($Word, 'Speech', 'PluralGenitive') != ''" + then: [x: "concat('\uF8FE', DefinitionValue($Word, 'Speech', 'PluralGenitive'))"] + else: [x: "concat('\uF8FE', $Word)"] # need to reverse the order of speech: $ 3 -> 3 dollars - name: currency @@ -355,15 +370,21 @@ # If the amount is singular, we don't add the plural ending. - IsSingular: "*[3][self::m:mn and .=1] and *[2]='\u2062'" - CurrencyWord: "DefinitionValue(*[1], 'Speech', 'CurrencySymbols')" + # Same numeral-dependent choice as in the 'unit' rule above. + - Coefficient: "IfThenElse(*[3][self::m:mn], number(*[3]), 0)" + - IsNominativePlural: "$Coefficient mod 10 >= 2 and $Coefficient mod 10 <= 4 and + not($Coefficient mod 100 >= 12 and $Coefficient mod 100 <= 14)" replace: - bookmark: "*[3]/@id" - x: "*[3]" - test: - if: "$IsSingular" then: [x: "$CurrencyWord"] - - else_if: "DefinitionValue($CurrencyWord, 'Speech', 'PluralForms') != ''" + - else_if: "$IsNominativePlural and DefinitionValue($CurrencyWord, 'Speech', 'PluralForms') != ''" then: [x: "DefinitionValue($CurrencyWord, 'Speech', 'PluralForms')"] - else: [x: "DefinitionValue(*[1], 'Speech', 'CurrencySymbols')", ct: "s"] + - else_if: "DefinitionValue($CurrencyWord, 'Speech', 'PluralGenitive') != ''" + then: [x: "DefinitionValue($CurrencyWord, 'Speech', 'PluralGenitive')"] + else: [x: "$CurrencyWord"] - name: sin tag: mi @@ -378,7 +399,7 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "cosinus"] # phrase('cos' is the abbreviation for cosine) + then: [T: "cosinus"] # phrase('cos' is the abbreviation for cosine) else: [T: "cosinus"] # phrase(find the 'cosine' in a right-angle triangle) - name: tan tag: mi @@ -387,7 +408,7 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "tangens"] # phrase(the 'tan' is the ratio of the opposite to the adjacent side of a right-angled triangle) + then: [T: "tangens"] # phrase(the 'tan' is the ratio of the opposite to the adjacent side of a right-angled triangle) else: [T: "tangens"] # phrase(a 'tangent' is a straight line that touches a curve) - name: sec tag: mi @@ -396,8 +417,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "sekans"] # phrase(to 'seek' a solution) - else: [t: "sekans"] # phrase(a 'secant' intersects a curve at two or more points) + then: [T: "sekans"] # phrase(to 'seek' a solution) + else: [T: "sekans"] # phrase(a 'secant' intersects a curve at two or more points) - name: csc tag: mi match: ".='csc'" @@ -405,8 +426,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "kosekans"] # phrase(we will 'cosecant' a solution) - else: [t: "kosekans"] # phrase(the 'cosecant' is the reciprocal of the secant) + then: [T: "kosekans"] # phrase(we will 'cosecant' a solution) + else: [T: "kosekans"] # phrase(the 'cosecant' is the reciprocal of the secant) - name: cot tag: mi match: ".='cot'" @@ -414,8 +435,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "cotangens"] # phrase(find the 'cotangent' in a right-angle triangle) - else: [t: "cotangens"] # phrase(the 'cotangent' is the reciprocal of the tangent) + then: [T: "cotangens"] # phrase(find the 'cotangent' in a right-angle triangle) + else: [T: "cotangens"] # phrase(the 'cotangent' is the reciprocal of the tangent) - name: sinh tag: mi @@ -424,8 +445,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "sinus hiperboliczny"] # phrase(the word 'sinch' is an abbreviation for hyperbolic sine) - else: [t: "sinus hiperboliczny"] # phrase(the 'hyperbolic sine' is used in mathematics) + then: [T: "sinus hiperboliczny"] # phrase(the word 'sinch' is an abbreviation for hyperbolic sine) + else: [T: "sinus hiperboliczny"] # phrase(the 'hyperbolic sine' is used in mathematics) - name: cosh tag: mi match: ".='cosh'" @@ -433,8 +454,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "cosinus hiperboliczny"] # phrase('cosh' is an abbreviation of hyperbolic cosine) - else: [t: "cosinus hiperboliczny"] # phrase(the 'hyperbolic cosine' is a mathematical function) + then: [T: "cosinus hiperboliczny"] # phrase('cosh' is an abbreviation of hyperbolic cosine) + else: [T: "cosinus hiperboliczny"] # phrase(the 'hyperbolic cosine' is a mathematical function) - name: tanh tag: mi match: ".='tanh'" @@ -442,8 +463,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "tangens hiperboliczny"] # phrase('tanch' is shorthand for hyperbolic tangent) - else: [t: "tangens hiperboliczny"] # phrase('hyperbolic tangent' is a mathematical function) + then: [T: "tangens hiperboliczny"] # phrase('tanch' is shorthand for hyperbolic tangent) + else: [T: "tangens hiperboliczny"] # phrase('hyperbolic tangent' is a mathematical function) - name: sech tag: mi match: ".='sech'" @@ -451,8 +472,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "sekans hiperboliczny"] # phrase('sheck' is shorthand for hyperbolic secant) - else: [t: "sekans hiperboliczny"] # phrase('hyperbolic secant' is a mathematical function) + then: [T: "sekans hiperboliczny"] # phrase('sheck' is shorthand for hyperbolic secant) + else: [T: "sekans hiperboliczny"] # phrase('hyperbolic secant' is a mathematical function) - name: csch tag: mi match: ".='csch'" @@ -460,8 +481,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "kosekans hiperboliczny"] # phrase('cosheck' is shorthand for hyperbolic cosecant) - else: [t: "kosekans hiperboliczny"] # phrase('hyperbolic cosecant' is a mathematical function) + then: [T: "kosekans hiperboliczny"] # phrase('cosheck' is shorthand for hyperbolic cosecant) + else: [T: "kosekans hiperboliczny"] # phrase('hyperbolic cosecant' is a mathematical function) - name: coth tag: mi match: ".='coth'" @@ -469,8 +490,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "cotangens hiperboliczny"] # phrase('cotanch' is shorthand for hyperbolic cotangent) - else: [t: "cotangens hiperboliczny"] # phrase(the 'hyperbolic cotangent' is a mathematical function) + then: [T: "cotangens hiperboliczny"] # phrase('cotanch' is shorthand for hyperbolic cotangent) + else: [T: "cotangens hiperboliczny"] # phrase(the 'hyperbolic cotangent' is a mathematical function) - name: exponential tag: mi match: ".='exp'" @@ -478,8 +499,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "eksponenta"] # phrase('exp' means exponential function) - else: [t: "funkcja wykładnicza"] # phrase('exponential' function) + then: [T: "eksponenta"] # phrase('exp' means exponential function) + else: [T: "funkcja wykładnicza"] # phrase('exponential' function) - name: covariance tag: mi match: ".='Cov'" @@ -487,8 +508,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "kowariancja"] # phrase('Cov' is shorthand for the covariance function) - else: [t: "kowariancja"] # phrase('covariance' function) + then: [T: "kowariancja"] # phrase('Cov' is shorthand for the covariance function) + else: [T: "kowariancja"] # phrase('covariance' function) - name: maximum tag: mi @@ -551,25 +572,25 @@ then: - test: - if: "self::m:piecewise" - then: [t: "przypadek"] # phrase(this is the first 'case' of three cases) + then: [T: "przypadek"] # phrase(this is the first 'case' of three cases) - else_if: "self::m:system-of-equations" - then: [t: "równanie"] # phrase(this is the first 'equation' of three equations) - else: [t: "linia"] # phrase(this is the first 'line' of three lines) + then: [T: "równanie"] # phrase(this is the first 'equation' of three equations) + else: [T: "linia"] # phrase(this is the first 'line' of three lines) - else_if: "($LineCount mod 10 = 2 or $LineCount mod 10 = 3 or $LineCount mod 10 = 4) and not($LineCount mod 100 = 12 or $LineCount mod 100 = 13 or $LineCount mod 100 = 14)" then: - test: - if: "self::m:piecewise" - then: [t: "przypadki"] # phrase(there are 'two cases' to consider) + then: [T: "przypadki"] # phrase(there are 'two cases' to consider) - else_if: "self::m:system-of-equations" - then: [t: "równania"] # phrase(there are 'two equations' to solve) - else: [t: "linie"] # phrase(there are 'two lines' shown) + then: [T: "równania"] # phrase(there are 'two equations' to solve) + else: [T: "linie"] # phrase(there are 'two lines' shown) - else: - test: - if: "self::m:piecewise" - then: [t: "przypadków"] # phrase(there are 'five cases' to consider) + then: [T: "przypadków"] # phrase(there are 'five cases' to consider) - else_if: "self::m:system-of-equations" - then: [t: "równań"] # phrase(there are 'five equations' to solve) - else: [t: "linii"] # phrase(there are 'five lines' shown) + then: [T: "równań"] # phrase(there are 'five equations' to solve) + else: [T: "linii"] # phrase(there are 'five lines' shown) - pause: short - x: "*" - pause: long @@ -586,10 +607,10 @@ - pause: medium - test: - if: "parent::m:piecewise" - then: [t: "przypadek"] # phrase('case' 1 of 10 cases) + then: [T: "przypadek"] # phrase('case' 1 of 10 cases) - else_if: "parent::m:system-of-equations" - then: [t: "równanie"] # phrase('equation' 1 of 10 equations) - else: [t: "linia"] # phrase('line 1 of 10 lines) + then: [T: "równanie"] # phrase('equation' 1 of 10 equations) + else: [T: "linia"] # phrase('line 1 of 10 lines) - x: "count(preceding-sibling::*[not(contains(@data-intent-property, ':continued-row:'))]) + 1" - test: if: "self::m:mlabeledtr" @@ -638,13 +659,13 @@ variables: [IsColumnSilent: true()] match: "count(*)=1 and *[self::m:mtr][count(*) = 1]" replace: - - t: "jeden na jeden" # phrase(the '1 by 1' matrix) + - T: "jeden na jeden" # phrase(the '1 by 1' matrix) - test: if: "self::m:determinant" # just need to check the first bracket since we know it must be (, [, or | then: [T: "wyznacznik"] # phrase(the 2 by 2 'determinant')) else: [T: "macierz"] # phrase(the 2 by 2 'matrix') - - t: "z elementem" # phrase(the 2 by 2 matrix 'with entry' x) + - T: "z elementem" # phrase(the 2 by 2 matrix 'with entry' x) - x: "*[1]/*" # simpler reading methods for special case matrices @@ -657,7 +678,7 @@ - x: count(*) - T: "na" # phrase(the 1 'by' 2 matrix) - x: count(*[self::m:mtr][1]/*) - - t: "macierz zerowa" # phrase(the 2 by 2 'zero matrix') + - T: "macierz zerowa" # phrase(the 2 by 2 'zero matrix') - pause: long - name: identity-matrix @@ -672,7 +693,7 @@ - x: count(*) - T: "na" # phrase(the 1 'by' 2 matrix) - x: count(*[self::m:mtr][1]/*) - - t: "macierz jednostkowa" # phrase(the 2 by 2 'identity matrix') + - T: "macierz jednostkowa" # phrase(the 2 by 2 'identity matrix') - pause: long - name: diagonal-matrix @@ -689,7 +710,7 @@ - x: count(*) - T: "na" # phrase(the 1 'by' 2 matrix) - x: count(*[self::m:mtr][1]/*) - - t: "macierz diagonalna" # phrase(the 2 by 2 'diagonal matrix') + - T: "macierz diagonalna" # phrase(the 2 by 2 'diagonal matrix') - pause: long - insert: # this lists the diagonal 'mtd's to be read, and they say "column nnn" before reading the contents @@ -711,7 +732,7 @@ replace: - T: "" # phrase('the' 2 by 2 matrix M) - x: count(*) - - t: "na jedną kolumnę" # phrase(the 2 'by 1 column' matrix) + - T: "na jedną kolumnę" # phrase(the 2 'by 1 column' matrix) - test: if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" then: [T: "wektor"] # phrase(the 2 by 2 'vector') @@ -733,7 +754,7 @@ replace: - T: "" # phrase('the' 2 by 2 matrix M) - x: "count(*)" - - t: "na jedną kolumnę" # phrase(the 2 'by 1 column' matrix) + - T: "na jedną kolumnę" # phrase(the 2 'by 1 column' matrix) - test: if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" then: [T: "wektor"] # phrase(the 2 column 'vector') @@ -742,7 +763,7 @@ - x: "*" # select the rows (mtr) - test: if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" - then: [t: "koniec macierzy"] # phrase(the 'end of matrix' has been reached) + then: [T: "koniec macierzy"] # phrase(the 'end of matrix' has been reached) - name: 1x2-or-3-matrix tag: matrix @@ -753,7 +774,7 @@ - count(*[1]/*)<=3 and # at least two cols - IsNode(*/*/*,'simple') # IsNode() returns true if all the nodes are simple replace: - - t: "jeden na" # phrase('the 1 by' 2 matrix) + - T: "jeden na" # phrase('the 1 by' 2 matrix) - x: count(*/*) - T: "wiersz" # phrase(the 1 by 4 'row' matrix) - test: @@ -775,7 +796,7 @@ variables: [IsColumnSilent: "$SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix = 'SilentColNum'"] match: "count(*)=1" # one row replace: - - t: "jeden na" # phrase('the 1 by' 2 matrix) + - T: "jeden na" # phrase('the 1 by' 2 matrix) - x: "count(*/*)" - T: "wiersz" # phrase(the 1 by 2 'row' matrix) - test: @@ -811,7 +832,7 @@ else: - test: if: "@columnlines and (contains(normalize-space(@columnlines), 'solid') or contains(normalize-space(@columnlines), 'dashed'))" - then: [t: "macierz rozszerzona"] # phrase(the 2 by 2 'augmented matrix') + then: [T: "macierz rozszerzona"] # phrase(the 2 by 2 'augmented matrix') else: [T: "macierz"] # phrase(the 2 by 2 'matrix') - pause: long - x: "*" @@ -838,7 +859,7 @@ else: - test: if: "@columnlines and (contains(normalize-space(@columnlines), 'solid') or contains(normalize-space(@columnlines), 'dashed'))" - then: [t: "macierz rozszerzona"] # phrase(the 2 by 2 'augmented matrix') + then: [T: "macierz rozszerzona"] # phrase(the 2 by 2 'augmented matrix') else: [T: "macierz"] # phrase(the 2 by 2 'matrix') - pause: long - x: "*" @@ -1077,12 +1098,12 @@ - bookmark: "*[1]/@id" - test: - if: ".='s'" - then: [t: "ciało stałe"] # phrase(Boron is a 'solid' in its natural state) + then: [T: "ciało stałe"] # phrase(Boron is a 'solid' in its natural state) - else_if: ".='l'" - then: [t: "ciecz"] # phrase(water is a 'liquid') + then: [T: "ciecz"] # phrase(water is a 'liquid') - else_if: ".='g'" - then: [t: "gaz"] # phrase(hydrogen is a 'gas' ) - else: [t: "wodny"] # phrase(an 'aqueous' solution is contained in water) + then: [T: "gaz"] # phrase(hydrogen is a 'gas' ) + else: [T: "wodny"] # phrase(an 'aqueous' solution is contained in water) - pause: short - name: chemical-formula-operator-bond @@ -1093,13 +1114,13 @@ - bookmark: "@id" - test: - if: ".='-' or .=':'" - then: [t: "wiązanie pojedyncze"] # phrase(a 'single bond' is formed when two atoms share one pair of electrons) + then: [T: "wiązanie pojedyncze"] # phrase(a 'single bond' is formed when two atoms share one pair of electrons) - else_if: ".='=' or .='∷'" - then: [t: "wiązanie podwójne"] # phrase(a 'double bond' may occur when two atoms share two pairs of electrons) + then: [T: "wiązanie podwójne"] # phrase(a 'double bond' may occur when two atoms share two pairs of electrons) - else_if: ".='≡'" - then: [t: "wiązanie potrójne"] # phrase(a 'triple bond' occurs when two atoms share three pairs of electrons) + then: [T: "wiązanie potrójne"] # phrase(a 'triple bond' occurs when two atoms share three pairs of electrons) - else_if: ".='≣'" - then: [t: "wiązanie poczwórne"] # phrase(a 'quadruple bond' occurs when two atoms share four pairs of electrons) + then: [T: "wiązanie poczwórne"] # phrase(a 'quadruple bond' occurs when two atoms share four pairs of electrons) else: [x: "text()"] - name: chemical-formula-operator @@ -1118,14 +1139,14 @@ - if: ".='→' or .='⟶'" then_test: if: "$Verbosity='Terse'" - then: [t: "tworzy"] # phrase(hydrogen and oxygen 'forms' water ) - else: [t: "reaguje tworząc"] # phrase(hydrogen and oxygen 'reacts to form' water) + then: [T: "tworzy"] # phrase(hydrogen and oxygen 'forms' water ) + else: [T: "reaguje tworząc"] # phrase(hydrogen and oxygen 'reacts to form' water) - else_if: ".='⇌' or .='🣑'" # U+01F8D1 - then: [t: "jest w równowadze z"] # phrase(a reactant 'is in equilibrium with' a product) + then: [T: "jest w równowadze z"] # phrase(a reactant 'is in equilibrium with' a product) - else_if: ".='🣓'" # U+1F8D3 - then: [t: "jest w równowadze przesuniętej w lewo z"] # phrase(the reactant 'is in equilibrium biased to the left with' the product) + then: [T: "jest w równowadze przesuniętej w lewo z"] # phrase(the reactant 'is in equilibrium biased to the left with' the product) - else_if: ".='🣒'" # U+1F8D2 - then: [t: "jest w równowadze przesuniętej w prawo z"] # phrase(the reactant 'is in equilibrium biased to the right with' the product) + then: [T: "jest w równowadze przesuniętej w prawo z"] # phrase(the reactant 'is in equilibrium biased to the right with' the product) else: [x: "*"] - name: chemical-equation-operator diff --git a/Rules/Languages/pl/SharedRules/geometry.yaml b/Rules/Languages/pl/SharedRules/geometry.yaml index f110a71ed..3fa9c9ccc 100644 --- a/Rules/Languages/pl/SharedRules/geometry.yaml +++ b/Rules/Languages/pl/SharedRules/geometry.yaml @@ -7,12 +7,12 @@ - test: if: "$Verbosity='Verbose'" then: - - t: "odcinek od" # phrase('the line segment from' A to B) + - T: "odcinek od" # phrase('the line segment from' A to B) - x: "*[1]" - T: "do" # phrase(the line segment from A 'to' B) - x: "*[2]" else: - - t: "odcinek" # phrase(the 'line segment' A B) + - T: "odcinek" # phrase(the 'line segment' A B) - x: "*[1]" - x: "*[2]" @@ -23,12 +23,12 @@ - test: if: "$Verbosity='Verbose'" then: - - t: "półprosta od" # phrase('the ray from' A to B) + - T: "półprosta od" # phrase('the ray from' A to B) - x: "*[1]" - T: "do" # phrase(the ray from A 'to' B) - x: "*[2]" else: - - t: "półprosta" # phrase(the 'ray'A B) + - T: "półprosta" # phrase(the 'ray'A B) - x: "*[1]" - x: "*[2]" @@ -47,9 +47,9 @@ - test: if: "$Verbosity='Verbose'" then: - - t: "miara kąta" # phrase('the measure of the angle' ABC) + - T: "miara kąta" # phrase('the measure of the angle' ABC) else: - - t: "miara kąta" # phrase('measure of angle' ABC) + - T: "miara kąta" # phrase('measure of angle' ABC) - x: "*[1]" - x: "*[2]" - x: "*[3]" @@ -74,4 +74,4 @@ - pause: short - test: if: "($SpeechStyle='ClearSpeak' and $Verbosity='Verbose') or not(IsNode(*[last()],'leaf'))" - then: [t: "punkt końcowy"] # phrase(start point, 'end point') + then: [T: "punkt końcowy"] # phrase(start point, 'end point') diff --git a/Rules/Languages/pl/SharedRules/linear-algebra.yaml b/Rules/Languages/pl/SharedRules/linear-algebra.yaml index 1ebcf9f95..69752bd48 100644 --- a/Rules/Languages/pl/SharedRules/linear-algebra.yaml +++ b/Rules/Languages/pl/SharedRules/linear-algebra.yaml @@ -36,7 +36,7 @@ - x: "*[1]" - test: if: "not(IsNode(*[1], 'simple')) and $Impairment = 'Blindness'" - then: [t: "koniec wyznacznika"] # phrase('end determinant' of a matrix) + then: [T: "koniec wyznacznika"] # phrase('end determinant' of a matrix) - name: subscripted-norm diff --git a/Rules/Languages/pl/definitions.yaml b/Rules/Languages/pl/definitions.yaml index 9c4c6e69c..18785562b 100644 --- a/Rules/Languages/pl/definitions.yaml +++ b/Rules/Languages/pl/definitions.yaml @@ -363,7 +363,7 @@ "F": "farad", "Gy": "grej", "H": "henr", - "Hz": "herce", + "Hz": "herc", "J": "dżul", "kat": "katal", "lm": "lumen", @@ -438,7 +438,7 @@ "M": "molowy", "R": "rentgen", "rpm": "obrót na minutę", - "℧": "M h o", + "℧": "mho", "dyn": "dyna", "erg": "erg", @@ -495,7 +495,7 @@ "lb t": "funt trojański", # energy - "hp": "konie mechaniczne", + "hp": "koń mechaniczny", "BTU": "btu", "°F": "stopień Fahrenheita", "℉": "stopień Fahrenheita", @@ -511,25 +511,277 @@ } - PluralForms: { - # FIX: this needs to be flushed out - "cal": "cale", "cal kwadratowy": "cale kwadratowe", "cal sześcienny": "cale sześcienne", - "stopa": "stopy", "stopa kwadratowa": "stopy kwadratowe", "stopa sześcienna": "stopy sześcienne", + # Nominative plural - after the numerals 2, 3, 4 (but not 12-14 or 112-114). + # The genitive plural (5 and above) lives in PluralGenitive below. + "akr": "akry", + "amper": "ampery", + "angstrem": "angstremy", + "atmosfera": "atmosfery", + "bajt": "bajty", + "bar": "bary", + "baryłka": "baryłki", + "bekerel": "bekerele", + "bel": "bele", + "bit": "bity", + "bitcoin": "bitcoiny", + "bod": "body", + "btu": "btu", + "buszel": "buszle", + "cal": "cale", + "cal kwadratowy": "cale kwadratowe", + "cal sześcienny": "cale sześcienne", + "cent": "centy", + "cetnar": "cetnary", + "colon": "colony", + "dalton": "daltony", + "decybel": "decybele", + "dolar": "dolary", + "drachma": "drachmy", + "drachma płynu": "drachmy płynu", + "dyna": "dyny", + "dzień": "dni", + "dżul": "dżule", + "eksbibajt": "eksbibajty", + "eksbibit": "eksbibity", + "elektronowolt": "elektronowolty", + "erg": "ergi", + "euro": "euro", + "farad": "farady", + "fermi": "fermi", + "funt": "funty", + "funt trojański": "funty trojańskie", + "galon": "galony", + "gibibajt": "gibibajty", + "gibibit": "gibibity", + "gill": "gille", + "godzina": "godziny", + "grad": "grady", + "gram": "gramy", + "gran": "grany", + "grej": "greje", + "hektar": "hektary", + "henr": "henry", + "herc": "herce", + "jard kwadratowy": "jardy kwadratowe", + "jard sześcienny": "jardy sześcienne", + "jednostka astronomiczna": "jednostki astronomiczne", + "jednostka masy atomowej": "jednostki masy atomowej", + "jobibajt": "jobibajty", + "jobibit": "jobibity", + "kaloria": "kalorie", + "kandela": "kandele", + "katal": "katale", + "kelwin": "kelwiny", + "kibibajt": "kibibajty", + "kibibit": "kibibity", + "kiur": "kiury", + "koń mechaniczny": "konie mechaniczne", + "kubek": "kubki", + "kulomb": "kulomby", + "kwarta": "kwarty", + "lir": "liry", + "litr": "litry", + "luks": "luksy", + "lumen": "lumeny", + "mebibajt": "mebibajty", + "mebibit": "mebibity", + "metr": "metry", + "mho": "mho", + "mila": "mile", + "mila kwadratowa": "mile kwadratowe", + "mila na galon": "mile na galon", + "mila na godzinę": "mile na godzinę", + "minuta": "minuty", + "minuta łuku": "minuty łuku", + "mol": "mole", + "molowy": "molowe", + "neper": "nepery", + "niuton": "niutony", + "obrót na minutę": "obroty na minutę", + "ogniwo": "ogniwa", + "om": "omy", + "parsek": "parseki", + "paskal": "paskale", + "pebibajt": "pebibajty", + "pebibit": "pebibity", + "pek": "peki", + "pennyweight": "pennyweight", + "peso": "peso", + "pinta": "pinty", + "pręt": "pręty", + "radian": "radiany", + "rentgen": "rentgeny", + "rok": "lata", + "rok świetlny": "lata świetlne", + "rupia": "rupie", + "sekunda": "sekundy", + "sekunda łuku": "sekundy łuku", + "siemens": "siemensy", + "siwert": "siwerty", + "steradian": "steradiany", + "stopa": "stopy", "stopa deskowa": "stopy deskowe", + "stopa kwadratowa": "stopy kwadratowe", + "stopa sześcienna": "stopy sześcienne", "stopień": "stopnie", "stopień Celsjusza": "stopnie Celsjusza", "stopień Fahrenheita": "stopnie Fahrenheita", - "degree celsius": "stopnie Celsjusza", - "degree fahrenheit": "stopnie Fahrenheita", - "henr": "henry", - "wolt": "wolty", + "szekel": "szekle", + "tebibajt": "tebibajty", + "tebibit": "tebibity", + "tesla": "tesle", + "tona": "tony", + "tydzień": "tygodnie", + "uncja": "uncje", + "uncja płynu": "uncje płynu", + "uncja trojańska": "uncje trojańskie", "wat": "waty", - "hertz": "herce", - "luks": "luksy", - "siemens": "siemens", - "obrót na minutę": "obroty na minutę", - "mila na godzinę": "mile na godzinę", - "mila na galon": "mile na galon", - "colon": "colony", "lir": "liry", "won": "wony", "bitcoin": "bitcoiny" + "weber": "webery", + "wolt": "wolty", + "won": "wony", + "zebibajt": "zebibajty", + "zebibit": "zebibity", + "łańcuch": "łańcuchy", + "łyżeczka": "łyżeczki", + "łyżka stołowa": "łyżki stołowe" + } + +- PluralGenitive: { + # Genitive plural - after 5 and above, and after 12-14, 112-114. + # Polish inflects the noun according to the numeral, so a single plural + # form is not enough: 2 metry but 5 metrów. The 'unit' and 'currency' + # rules pick the section based on the value of the numeral. + "akr": "akrów", + "amper": "amperów", + "angstrem": "angstremów", + "atmosfera": "atmosfer", + "bajt": "bajtów", + "bar": "barów", + "baryłka": "baryłek", + "bekerel": "bekereli", + "bel": "beli", + "bit": "bitów", + "bitcoin": "bitcoinów", + "bod": "bodów", + "btu": "btu", + "buszel": "buszli", + "cal": "cali", + "cal kwadratowy": "cali kwadratowych", + "cal sześcienny": "cali sześciennych", + "cent": "centów", + "cetnar": "cetnarów", + "colon": "colonów", + "dalton": "daltonów", + "decybel": "decybeli", + "dolar": "dolarów", + "drachma": "drachm", + "drachma płynu": "drachm płynu", + "dyna": "dyn", + "dzień": "dni", + "dżul": "dżuli", + "eksbibajt": "eksbibajtów", + "eksbibit": "eksbibitów", + "elektronowolt": "elektronowoltów", + "erg": "ergów", + "euro": "euro", + "farad": "faradów", + "fermi": "fermi", + "funt": "funtów", + "funt trojański": "funtów trojańskich", + "galon": "galonów", + "gibibajt": "gibibajtów", + "gibibit": "gibibitów", + "gill": "gilli", + "godzina": "godzin", + "grad": "gradów", + "gram": "gramów", + "gran": "granów", + "grej": "grejów", + "hektar": "hektarów", + "henr": "henrów", + "herc": "herców", + "jard kwadratowy": "jardów kwadratowych", + "jard sześcienny": "jardów sześciennych", + "jednostka astronomiczna": "jednostek astronomicznych", + "jednostka masy atomowej": "jednostek masy atomowej", + "jobibajt": "jobibajtów", + "jobibit": "jobibitów", + "kaloria": "kalorii", + "kandela": "kandeli", + "katal": "katali", + "kelwin": "kelwinów", + "kibibajt": "kibibajtów", + "kibibit": "kibibitów", + "kiur": "kiurów", + "koń mechaniczny": "koni mechanicznych", + "kubek": "kubków", + "kulomb": "kulombów", + "kwarta": "kwart", + "lir": "lirów", + "litr": "litrów", + "luks": "luksów", + "lumen": "lumenów", + "mebibajt": "mebibajtów", + "mebibit": "mebibitów", + "metr": "metrów", + "mho": "mho", + "mila": "mil", + "mila kwadratowa": "mil kwadratowych", + "mila na galon": "mil na galon", + "mila na godzinę": "mil na godzinę", + "minuta": "minut", + "minuta łuku": "minut łuku", + "mol": "moli", + "molowy": "molowych", + "neper": "neperów", + "niuton": "niutonów", + "obrót na minutę": "obrotów na minutę", + "ogniwo": "ogniw", + "om": "omów", + "parsek": "parseków", + "paskal": "paskali", + "pebibajt": "pebibajtów", + "pebibit": "pebibitów", + "pek": "peków", + "pennyweight": "pennyweight", + "peso": "peso", + "pinta": "pint", + "pręt": "prętów", + "radian": "radianów", + "rentgen": "rentgenów", + "rok": "lat", + "rok świetlny": "lat świetlnych", + "rupia": "rupii", + "sekunda": "sekund", + "sekunda łuku": "sekund łuku", + "siemens": "siemensów", + "siwert": "siwertów", + "steradian": "steradianów", + "stopa": "stóp", + "stopa deskowa": "stóp deskowych", + "stopa kwadratowa": "stóp kwadratowych", + "stopa sześcienna": "stóp sześciennych", + "stopień": "stopni", + "stopień Celsjusza": "stopni Celsjusza", + "stopień Fahrenheita": "stopni Fahrenheita", + "szekel": "szekli", + "tebibajt": "tebibajtów", + "tebibit": "tebibitów", + "tesla": "tesli", + "tona": "ton", + "tydzień": "tygodni", + "uncja": "uncji", + "uncja płynu": "uncji płynu", + "uncja trojańska": "uncji trojańskich", + "wat": "watów", + "weber": "weberów", + "wolt": "woltów", + "won": "wonów", + "zebibajt": "zebibajtów", + "zebibit": "zebibitów", + "łańcuch": "łańcuchów", + "łyżeczka": "łyżeczek", + "łyżka stołowa": "łyżek stołowych" } # Lines starting with "#" are a comment diff --git a/Rules/Languages/pl/navigate.yaml b/Rules/Languages/pl/navigate.yaml index c99b60490..bb89c8a9a 100644 --- a/Rules/Languages/pl/navigate.yaml +++ b/Rules/Languages/pl/navigate.yaml @@ -48,9 +48,9 @@ - if: "$MatchCounter = 0 and $SayCommand = 'true'" then_test: - if: "self::m:math and starts-with($NavCommand, 'ZoomOut')" - then: [t: "maksymalnie oddalono", pause: "medium"] + then: [T: "maksymalnie oddalono", pause: "medium"] - else_if: "IsNode(., 'leaf') and starts-with($NavCommand, 'ZoomIn')" - then: [t: "maksymalnie oddalono", pause: "medium"] + then: [T: "maksymalnie oddalono", pause: "medium"] else: - test: # CommandOffset to 1 + długość ANGIELSKIEGO rdzenia $NavCommand @@ -133,13 +133,13 @@ replace: - test: - if: "$Move2D = 'in'" - then: [t: "do"] # phrase(move 'in' to a part) + then: [T: "do"] # phrase(move 'in' to a part) - else_if: "$Move2D = 'out of'" - then: [t: "z"] # phrase(move 'out of' a part) + then: [T: "z"] # phrase(move 'out of' a part) - else_if: "$Move2D = 'end of'" - then: [t: "na koniec"] # phrase(move to the 'end of' a part) + then: [T: "na koniec"] # phrase(move to the 'end of' a part) - else_if: "$Move2D = 'start of'" - then: [t: "na początek"] # phrase(move to the 'start of' a part) + then: [T: "na początek"] # phrase(move to the 'start of' a part) else: [x: "$Move2D"] - test: - if: "$NumPrecedingSiblings=0" @@ -148,8 +148,8 @@ then: - test: # in postscripts -- base shifts by one if: "$NumPrecedingSiblings mod 2 = 0" - then: [t: "lewego indeksu dolnego"] # phrase(x with 'subscript' 2) - else: [t: "lewego indeksu górnego"] # phrase(x with 'superscript' 2) + then: [T: "lewego indeksu dolnego"] # phrase(x with 'subscript' 2) + else: [T: "lewego indeksu górnego"] # phrase(x with 'superscript' 2) else: - test: if: "$NumPrecedingSiblings mod 2 = 0" @@ -171,15 +171,15 @@ replace: - test: - if: "$Move2D = 'in'" - then: [t: "do"] # phrase(move 'in' to a part) + then: [T: "do"] # phrase(move 'in' to a part) - else_if: "$Move2D = 'out of' and starts-with($PartName, 'st')" then: [t: "ze"] # "ze stopnia" (eufonia przed 'st') - else_if: "$Move2D = 'out of'" - then: [t: "z"] # phrase(move 'out of' a part) + then: [T: "z"] # phrase(move 'out of' a part) - else_if: "$Move2D = 'end of'" - then: [t: "na koniec"] # phrase(move to the 'end of' a part) + then: [T: "na koniec"] # phrase(move to the 'end of' a part) - else_if: "$Move2D = 'start of'" - then: [t: "na początek"] # phrase(move to the 'start of' a part) + then: [T: "na początek"] # phrase(move to the 'start of' a part) else: [x: "$Move2D"] - test: - if: "$PartName != ''" @@ -203,7 +203,7 @@ then: [x: "SpeakIntentName(name(.), $Verbosity, 'silent')"] - else: [x: "SpeakIntentName(name(.), $Verbosity, 'other')"] else: - - t: "części" # phrase(the 'part' of the expression) + - T: "części" # phrase(the 'part' of the expression) - x: "count($Child2D/preceding-sibling::*) + 1" - pause: "medium" @@ -226,19 +226,19 @@ then: - test: - if: "$PreviousNavCommand = 'ZoomIn'" - then: [t: "cofnij przybliżenie"] # phrase('undo zoom in') + then: [T: "cofnij przybliżenie"] # phrase('undo zoom in') - else_if: "$PreviousNavCommand = 'ZoomOut'" - then: [t: "cofnij oddalenie"] # phrase('undo zoom out') + then: [T: "cofnij oddalenie"] # phrase('undo zoom out') - else_if: "$PreviousNavCommand = 'ZoomInAll'" - then: [t: "cofnij maksymalne przybliżenie"] # phrase('undo zooming in all the way') + then: [T: "cofnij maksymalne przybliżenie"] # phrase('undo zooming in all the way') - else_if: "$PreviousNavCommand = 'ZoomOutAll'" - then: [t: "cofnij maksymalne oddalenie"] # phrase('undo zooming out all the way') + then: [T: "cofnij maksymalne oddalenie"] # phrase('undo zooming out all the way') - else_if: "$PreviousNavCommand = 'MovePrevious' or $PreviousNavCommand = 'MovePreviousZoom'" - then: [t: "cofnij ruch w lewo"] # phrase('undo move left') + then: [T: "cofnij ruch w lewo"] # phrase('undo move left') - else_if: "$PreviousNavCommand = 'MoveNext' or $PreviousNavCommand = 'MoveNextZoom'" - then: [t: "cofnij ruch w prawo"] # phrase('undo move right') + then: [T: "cofnij ruch w prawo"] # phrase('undo move right') - else_if: "$PreviousNavCommand = 'None'" - then: [t: "brak poprzedniego polecenia"] # phrase('no previous command') + then: [T: "brak poprzedniego polecenia"] # phrase('no previous command') - pause: "medium" - set_variables: [NavNode: "@id"] @@ -261,7 +261,7 @@ replace: - test: if: "$MatchCounter = 0 and $NavVerbosity != 'Terse'" - then: [t: "maksymalnie przybliżono", pause: "long"] # phrase('zoomed in all of the way') + then: [T: "maksymalnie przybliżono", pause: "long"] # phrase('zoomed in all of the way') - test: if: "$ReadZoomLevel!=-1" then: @@ -552,12 +552,12 @@ then: - test: - if: "$NavCommand = 'MoveStart'" - then: [t: "przejdź na początek wyrażenia matematycznego"] # phrase('move to start of math') + then: [T: "przejdź na początek wyrażenia matematycznego"] # phrase('move to start of math') - else_if: "$NavCommand = 'MoveLineStart'" - then: [t: "przejdź na początek linii"] # phrase('move to start of line') + then: [T: "przejdź na początek linii"] # phrase('move to start of line') - else_if: "$NavCommand = 'MoveEnd'" - then: [t: "przejdź na koniec wyrażenia matematycznego"] # phrase('move to end of math') - else: [t: "przejdź na koniec linii"] # "$NavCommand = 'MoveLineEnd'" # phrase('move to end of line') + then: [T: "przejdź na koniec wyrażenia matematycznego"] # phrase('move to end of math') + else: [T: "przejdź na koniec linii"] # "$NavCommand = 'MoveLineEnd'" # phrase('move to end of line') - pause: "medium" - test: if: "$NavCommand = 'MoveStart' or $NavCommand = 'MoveLineStart'" @@ -597,8 +597,8 @@ then: - test: if: "$NavCommand = 'MoveLineStart'" - then: [t: "przejdź na początek linii"] # phrase('move to start of line') - else: [t: "przejdź na koniec linii"] # "$NavCommand = 'MoveLineEnd'" # phrase('move to end of line') + then: [T: "przejdź na początek linii"] # phrase('move to start of line') + else: [T: "przejdź na koniec linii"] # "$NavCommand = 'MoveLineEnd'" # phrase('move to end of line') - pause: "medium" - test: if: "self::m:mrow or @data-from-mathml = 'mrow'" @@ -634,7 +634,7 @@ - "$NavCommand='MoveColumnStart' or $NavCommand='MoveColumnEnd' or" - "$NavCommand='ReadCellCurrent'" replace: - - t: "poza tabelą" # phrase('not in table') + - T: "poza tabelą" # phrase('not in table') - pause: long - set_variables: [SpeakExpression: "'false'"] @@ -648,7 +648,7 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - t: "przejdź w lewo" # phrase('move left') + - T: "przejdź w lewo" # phrase('move left') - pause: short - test: if: "$NavVerbosity != 'Terse'" @@ -665,7 +665,7 @@ else: - set_variables: [NavNode: "preceding-sibling::*[1]/*[1]/@id"] else: - - t: "brak poprzedniej kolumny" # phrase('no previous column' in the table) + - T: "brak poprzedniej kolumny" # phrase('no previous column' in the table) - set_variables: [SpeakExpression: "'false'"] - name: move-cell-next @@ -678,7 +678,7 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - t: "przejdź w prawo" # phrase('move right') + - T: "przejdź w prawo" # phrase('move right') - pause: short - test: if: "$NavVerbosity != 'Terse'" @@ -695,7 +695,7 @@ else: - set_variables: [NavNode: "following-sibling::*[1]/*[1]/@id"] else: - - t: "brak następnej kolumny" # phrase('no next column' in the table) + - T: "brak następnej kolumny" # phrase('no next column' in the table) - set_variables: [SpeakExpression: "'false'"] - name: move-cell-up @@ -711,7 +711,7 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - t: "przejdź w górę" # phrase('move up' to previous row in the table) + - T: "przejdź w górę" # phrase('move up' to previous row in the table) - pause: short - test: if: "$NavVerbosity != 'Terse'" @@ -731,7 +731,7 @@ else: - set_variables: [NavNode: "../preceding-sibling::*[1]/*[$Column]/*[1]/@id"] else: - - t: "brak poprzedniego wiersza" # phrase('no previous row' in the table) + - T: "brak poprzedniego wiersza" # phrase('no previous row' in the table) - set_variables: [SpeakExpression: "'false'"] - name: move-cell-down @@ -747,7 +747,7 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - t: "przejdź w dół" # phrase('move down to the next row in the table) + - T: "przejdź w dół" # phrase('move down to the next row in the table) - pause: short - test: if: "$NavVerbosity != 'Terse'" @@ -767,7 +767,7 @@ else: - set_variables: [NavNode: "../following-sibling::*[1]/*[$Column]/*[1]/@id"] else: - - t: "brak następnego wiersza" # phrase('no next row' in the table) + - T: "brak następnego wiersza" # phrase('no next row' in the table) - set_variables: [SpeakExpression: "'false'"] - name: move-cell-up @@ -777,7 +777,7 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - t: "przejdź do poprzedniego wiersza" # phrase('move to previous row' to the previous row in the table) + - T: "przejdź do poprzedniego wiersza" # phrase('move to previous row' to the previous row in the table) - pause: medium - test: if: "preceding-sibling::*" @@ -791,7 +791,7 @@ else: - set_variables: [NavNode: "preceding-sibling::*[1]/@id"] else: - - t: "brak poprzedniego wiersza" # phrase('no previous row' in the table) + - T: "brak poprzedniego wiersza" # phrase('no previous row' in the table) - set_variables: [SpeakExpression: "'false'"] - name: move-cell-down @@ -801,7 +801,7 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - t: "przejdź do następnego wiersza" # phrase('move to next row' to the next row in the table) + - T: "przejdź do następnego wiersza" # phrase('move to next row' to the next row in the table) - pause: medium - test: if: "following-sibling::*" @@ -815,7 +815,7 @@ else: - set_variables: [NavNode: "following-sibling::*[1]/@id"] else: - - t: "brak następnego wiersza" # phrase('no next row' in the table) + - T: "brak następnego wiersza" # phrase('no next row' in the table) - set_variables: [SpeakExpression: "'false'"] - name: move-cell-previous @@ -826,9 +826,9 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - t: "przejdź do poprzedniej kolumny" # phrase('move to previous column' to the previous row in the table) + - T: "przejdź do poprzedniej kolumny" # phrase('move to previous column' to the previous row in the table) - pause: medium - - t: "brak poprzedniej kolumny" # phrase('no previous column' in the table) + - T: "brak poprzedniej kolumny" # phrase('no previous column' in the table) - set_variables: [SpeakExpression: "'false'"] - name: move-cell-next @@ -839,9 +839,9 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - t: "przejdź do następnej kolumny" # phrase('move up' to the previous row in the table) + - T: "przejdź do następnej kolumny" # phrase('move up' to the previous row in the table) - pause: medium - - t: "brak następnej kolumny" # phrase('no next row' in the table) + - T: "brak następnej kolumny" # phrase('no next row' in the table) - set_variables: [SpeakExpression: "'false'"] - name: default-read-cell @@ -857,7 +857,7 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - t: "czytaj bieżący element" # phrase('read current entry' in the table) + - T: "czytaj bieżący element" # phrase('read current entry' in the table) - pause: medium - test: if: "$NavVerbosity != 'Terse'" @@ -870,7 +870,7 @@ - pause: short - set_variables: [NavNode: "$MTD[1]/*[1]/@id"] else: - - t: "poza tabelą" # phrase('not in table' or matrix) + - T: "poza tabelą" # phrase('not in table' or matrix) - pause: long - set_variables: [SpeakExpression: "'false'"] @@ -1110,7 +1110,7 @@ then: - x: "ancestor::m:mtd[1]" # try again on an mtd node else: - - t: "poza tabelą" # phrase('not in table' or matrix) + - T: "poza tabelą" # phrase('not in table' or matrix) - pause: long - set_variables: [SpeakExpression: "'false'"] @@ -1187,7 +1187,7 @@ - test: if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" then: - - t: "nie można przejść w prawo" # phrase('cannot move right') + - T: "nie można przejść w prawo" # phrase('cannot move right') - pause: medium - with: variables: @@ -1208,14 +1208,14 @@ - test: if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" then: - - t: "nie można" # phrase('cannot' move right in expression) + - T: "nie można" # phrase('cannot' move right in expression) - test: - if: "$NavCommand = 'MoveNext'" - then: [t: "przejść"] # phrase('move' to next entry in table) + then: [T: "przejść"] # phrase('move' to next entry in table) - else_if: "$NavCommand = 'ReadNext'" - then: [t: "odczytać"] # phrase('read' next entry in table) - else: [t: "opisać"] # phrase('describe' next entry in table) - - t: "w prawo" # phrase(move 'right') + then: [T: "odczytać"] # phrase('read' next entry in table) + else: [T: "opisać"] # phrase('describe' next entry in table) + - T: "w prawo" # phrase(move 'right') - pause: short - T: "koniec matematyki" # phrase(move 'end of math') - pause: long @@ -1382,7 +1382,7 @@ - test: if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose' and $NavCommand = 'MovePrevious'" then: - - t: "nie można przejść w lewo" # phrase('cannot move left' in expression) + - T: "nie można przejść w lewo" # phrase('cannot move left' in expression) - pause: medium - with: variables: @@ -1399,7 +1399,7 @@ - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious') and" - "(self::m:math or name(EdgeNode(., 'left', 'math'))='math')" replace: - - t: "początek wyrażenia matematycznego" # phrase('start of math') + - T: "początek wyrażenia matematycznego" # phrase('start of math') - pause: long - set_variables: [SpeakExpression: "'false'"] @@ -1412,7 +1412,7 @@ - test: if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" then: - - t: "nie można przejść w lewo" # phrase('cannot move left') + - T: "nie można przejść w lewo" # phrase('cannot move left') - pause: short - with: variables: [Move2D: "'start of'", Child2D: "."] @@ -1573,16 +1573,16 @@ - test: - if: "$NavMode = 'Enhanced'" then: - - t: "znak" # phrase(a mathematical 'character') + - T: "znak" # phrase(a mathematical 'character') - set_variables: [NavMode: "'Character'", ReadZoomLevel: "1"] - else_if: "$NavMode = 'Character'" then: - - t: "prosty" # phrase(a 'simple' way to do something) + - T: "prosty" # phrase(a 'simple' way to do something) - set_variables: [NavMode: "'Simple'", ReadZoomLevel: "1"] - else: - - t: "rozszerzony" # phrase(an 'enhanced' way to do something) + - T: "rozszerzony" # phrase(an 'enhanced' way to do something) - set_variables: [NavMode: "'Enhanced'", ReadZoomLevel: "-1"] - - t: "tryb" # phrase(a simple 'mode' of use) + - T: "tryb" # phrase(a simple 'mode' of use) - pause: long - test: - if: "$NavMode != 'Enhanced'" # potentially need to zoom to the sibling @@ -1598,16 +1598,16 @@ - test: - if: "$NavMode = 'Enhanced'" then: - - t: "prosty" # phrase(an 'simple' way to do something) + - T: "prosty" # phrase(an 'simple' way to do something) - set_variables: [NavMode: "'Simple'", ReadZoomLevel: "1"] - else_if: "$NavMode = 'Character'" then: - - t: "rozszerzony" # phrase(an 'enhanced' way to do something) + - T: "rozszerzony" # phrase(an 'enhanced' way to do something) - set_variables: [NavMode: "'Enhanced'", ReadZoomLevel: "-1"] - else: - - t: "znak" # phrase(a mathematical 'character') + - T: "znak" # phrase(a mathematical 'character') - set_variables: [NavMode: "'Character'", ReadZoomLevel: "1"] - - t: "tryb" # phrase(a simple 'mode' of use) + - T: "tryb" # phrase(a simple 'mode' of use) - pause: long - test: - if: "$NavMode != 'Enhanced'" # potentially need to zoom to the sibling @@ -1623,7 +1623,7 @@ - test: if: "$Overview = 'true'" then: - - t: "czytaj wyrażenie po ruchu" # phrase('speak expression after move') + - T: "czytaj wyrażenie po ruchu" # phrase('speak expression after move') - pause: long - set_variables: [Overview: "'false'"] else: @@ -1640,9 +1640,9 @@ then: - test: - if: "$NavCommand = 'ReadCurrent'" - then: [t: "czytaj"] # phrase('read' next entry in table) - else: [t: "opisz"] # phrase('describe' next entry in table) - - t: "bieżący" # phrase('current' entry in table) + then: [T: "czytaj"] # phrase('read' next entry in table) + else: [T: "opisz"] # phrase('describe' next entry in table) + - T: "bieżący" # phrase('current' entry in table) - pause: long - set_variables: [NavNode: "@id"] @@ -1660,13 +1660,13 @@ then: - test: - if: "starts-with($NavCommand, 'Read')" - then: [t: "czytaj"] # phrase('read' next entry in table) + then: [T: "czytaj"] # phrase('read' next entry in table) - else_if: "starts-with($NavCommand, 'Describe')" - then: [t: "opisz"] # phrase('describe' next entry in table) + then: [T: "opisz"] # phrase('describe' next entry in table) - else_if: "starts-with($NavCommand, 'MoveTo')" - then: [t: "przejdź do"] # phrase('move to' the next entry in table) + then: [T: "przejdź do"] # phrase('move to' the next entry in table) else: [T: "zbiór"] # phrase('set' the value of the next entry in table) - - t: "symbol zastępczy" # phrase('placeholder' for the value) + - T: "symbol zastępczy" # phrase('placeholder' for the value) - x: "$PlaceMarkerIndex" - pause: long - set_variables: [NavNode: "$PlaceMarker"] @@ -1678,7 +1678,7 @@ - test: if: "$NavVerbosity != 'Terse'" then: - - t: "ustaw symbol zastępczy" # phrase('set placeholder' to the value) + - T: "ustaw symbol zastępczy" # phrase('set placeholder' to the value) - x: "$PlaceMarkerIndex" - pause: long - set_variables: [NavNode: "@id"] @@ -1710,11 +1710,11 @@ - test: if: "$NavCommand = 'WhereAmI'" then: - - t: "wewnątrz niczego więcej" # phrase('inside of nothing more') + - T: "wewnątrz niczego więcej" # phrase('inside of nothing more') - pause: long - set_variables: [SpeakExpression: "'false'"] else: - - t: "wewnątrz" # phrase('inside' a big expression) + - T: "wewnątrz" # phrase('inside' a big expression) - pause: medium - set_variables: [NavNode: "@id"] @@ -1722,7 +1722,7 @@ tag: "*" match: "$NavCommand = 'WhereAmI' or $NavCommand = 'WhereAmIAll'" replace: - - t: "wewnątrz" # phrase('inside' a big expression) + - T: "wewnątrz" # phrase('inside' a big expression) - pause: medium - test: - if: "$NavMode='Enhanced' and parent::*[self::m:mrow and (IsBracketed(., '(', ')', false) or IsBracketed(., '[', ']', false))]" diff --git a/Rules/Languages/pl/overview.yaml b/Rules/Languages/pl/overview.yaml index a65395889..a51169bb3 100644 --- a/Rules/Languages/pl/overview.yaml +++ b/Rules/Languages/pl/overview.yaml @@ -21,22 +21,22 @@ if: "IsNode(*[1], 'simple') and IsNode(*[2], 'simple')" then: - x: "*[1]" - - t: "przez" + - T: "przez" - x: "*[2]" else: - - t: "ułamek" + - T: "ułamek" - name: overview-default tag: [msqrt, "square-root"] match: "." replace: - - t: "pierwiastek kwadratowy" + - T: "pierwiastek kwadratowy" - test: if: "IsNode(*[1], 'simple')" then: - test: if: "$Verbosity!='Terse'" - then: [t: "z"] + then: [T: "z"] - x: "*[1]" - name: overview-default @@ -47,24 +47,24 @@ if: "*[2][self::m:mn]" then_test: - if: "*[2][.='2']" - then: [t: "pierwiastek kwadratowy"] + then: [T: "pierwiastek kwadratowy"] - else_if: "*[2][.='3']" - then: [t: "pierwiastek sześcienny"] + then: [T: "pierwiastek sześcienny"] - else_if: "*[2][not(contains(., '.'))]" - then: [x: "ToOrdinal(*[2])", t: "pierwiastek"] + then: [x: "ToOrdinal(*[2])", T: "pierwiastek"] else: - test: if: "*[2][self::m:mi][string-length(.)=1]" then: - x: "*[2]" else: {x: "*[2]"} - - t: "pierwiastek" + - T: "pierwiastek" - test: if: "IsNode(*[1], 'simple')" then: - test: if: "$Verbosity!='Terse'" - then: [t: "z"] + then: [T: "z"] - x: "*[1]" - name: matrix-override @@ -75,12 +75,12 @@ replace: - t: "" - x: count(*[2]/*) - - t: "na" + - T: "na" - x: count(*[2]/*[self::m:mtr][1]/*) - test: if: "*[1][.='|']" # just need to check the first bracket since we know it must be (, [, or | - then: [t: "wyznacznik"] - else: [t: "macierz"] + then: [T: "wyznacznik"] + else: [T: "macierz"] - name: overview-default tag: mtable @@ -88,9 +88,9 @@ replace: - t: "" - x: count(*[2]/*) - - t: "na" + - T: "na" - x: count(*[2]/*[self::m:mtr][1]/*) - - t: "tabela" + - T: "tabela" - name: short-mrow tag: mrow @@ -114,6 +114,6 @@ - pause: auto - x: "*[5]" - pause: auto - - t: "i tak dalej" + - T: "i tak dalej" - include: "SimpleSpeak_Rules.yaml" diff --git a/Rules/Languages/pl/unicode-full.yaml b/Rules/Languages/pl/unicode-full.yaml index 8246f4650..3c378bc8c 100644 --- a/Rules/Languages/pl/unicode-full.yaml +++ b/Rules/Languages/pl/unicode-full.yaml @@ -1,28 +1,28 @@ --- - - "¢": [t: "centy"] # 0xa2 - - "£": [t: "funty"] # 0xa3 - - "¤": [t: "znak waluty"] # 0xa4 - - "¥": [t: "jen"] # 0xa5 - - "¦": [t: "przerwana kreska"] # 0xa6 - - "§": [t: "paragraf"] # 0xa7 - - "¨": [t: "diereza"] # 0xa8 - - "©": [t: "znak praw autorskich"] # 0xa9 - - "ª": [t: "żeński wskaźnik liczebnika porządkowego"] # 0xaa + - "¢": [T: "centy"] # 0xa2 + - "£": [T: "funty"] # 0xa3 + - "¤": [T: "znak waluty"] # 0xa4 + - "¥": [T: "jen"] # 0xa5 + - "¦": [T: "przerwana kreska"] # 0xa6 + - "§": [T: "paragraf"] # 0xa7 + - "¨": [T: "diereza"] # 0xa8 + - "©": [T: "znak praw autorskich"] # 0xa9 + - "ª": [T: "żeński wskaźnik liczebnika porządkowego"] # 0xaa - "¬": [T: "nie"] # 0xac - - "«": [t: "lewy podwójny cudzysłów ostrokątny"] # 0xab + - "«": [T: "lewy podwójny cudzysłów ostrokątny"] # 0xab - "¯": # 0xaf - test: if: "ancestor::m:modified-variable and preceding-sibling::*[1][self::m:mi]" - then: [t: "kreska"] - else: [t: "linia"] - - "²": [t: "dwa"] # 0xb2 - - "³": [t: "trzy"] # 0xb3 - - "´": [t: "akut"] # 0xb4 - - "µ": [t: "mikro"] # 0xb5 - - "¹": [t: "jeden"] # 0xb9 - - "º": [t: "męski wskaźnik liczebnika porządkowego"] # 0xb9 + then: [T: "kreska"] + else: [T: "linia"] + - "²": [T: "dwa"] # 0xb2 + - "³": [T: "trzy"] # 0xb3 + - "´": [T: "akut"] # 0xb4 + - "µ": [T: "mikro"] # 0xb5 + - "¹": [T: "jeden"] # 0xb9 + - "º": [T: "męski wskaźnik liczebnika porządkowego"] # 0xb9 - "·": - test: if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolDot = 'Auto'" @@ -35,162 +35,162 @@ else_test: if: $ClearSpeak_MultSymbolX = 'By' then: [T: "na"] - else: [t: "krzyż"] + else: [T: "krzyż"] - "÷": [T: "podzielone przez"] # 0xf7 - - "¡": [t: "odwrócony wykrzyknik"] # 0xa1 - - "¶": [t: "znak akapitu"] # 0xb6 - - "¿": [t: "odwrócony znak zapytania"] # 0xbf - - - "ʰ": [t: "modyfikator mały h"] # 0x2b0 - - "ʱ": [t: "modyfikator mały h z haczykiem"] # 0x2b1 - - "ʲ": [t: "modyfikator mały j"] # 0x2b2 - - "ʳ": [t: "modyfikator mały R"] # 0x2b3 - - "ʴ": [t: "modyfikator mały odwrócony R"] # 0x2b4 - - "ʵ": [t: "modyfikator mały odwrócony R z haczykiem"] # 0x2b5 + - "¡": [T: "odwrócony wykrzyknik"] # 0xa1 + - "¶": [T: "znak akapitu"] # 0xb6 + - "¿": [T: "odwrócony znak zapytania"] # 0xbf + + - "ʰ": [T: "modyfikator mały h"] # 0x2b0 + - "ʱ": [T: "modyfikator mały h z haczykiem"] # 0x2b1 + - "ʲ": [T: "modyfikator mały j"] # 0x2b2 + - "ʳ": [T: "modyfikator mały R"] # 0x2b3 + - "ʴ": [T: "modyfikator mały odwrócony R"] # 0x2b4 + - "ʵ": [T: "modyfikator mały odwrócony R z haczykiem"] # 0x2b5 - "ʶ": # 0x2b6 - - t: "modyfikator mały odwrócony" + - T: "modyfikator mały odwrócony" - spell: "translate('R', 'R', 'R')" - - "ʷ": [t: "modyfikator mały w"] # 0x2b7 - - "ʸ": [t: "modyfikator mały y"] # 0x2b8 - - "ʹ": [t: "modyfikator prim"] # 0x2b9 - - "ʺ": [t: "modyfikator podwójny prim"] # 0x2ba - - "ʻ": [t: "modyfikator odwrócony przecinek"] # 0x2bb - - "ʼ": [t: "modyfikator apostrof"] # 0x2bc - - "ʽ": [t: "modyfikator odwrócony przecinek"] # 0x2bd - - "ʾ": [t: "modyfikator prawa połowa pierścień"] # 0x2be - - "ʿ": [t: "modyfikator lewa połowa pierścień"] # 0x2bf - - "ˀ": [t: "modyfikator zwarcie krtaniowe"] # 0x2c0 - - "ˁ": [t: "modyfikator odwrócone zwarcie krtaniowe"] # 0x2c1 - - "˂": [t: "modyfikator lewy grot strzałki"] # 0x2c2 - - "˃": [t: "modyfikator prawy grot strzałki"] # 0x2c3 - - "˄": [t: "modyfikator górny grot strzałki"] # 0x2c4 - - "˅": [t: "modyfikator dolny grot strzałki"] # 0x2c5 - - "ˆ": [t: "modyfikator akcent daszkowy"] # 0x2c6 - - "ˇ": [t: "haczek"] # 0x2c7 - - "ˈ": [t: "modyfikator pionowej kreski"] # 0x2c8 - - "ˉ": [t: "modyfikator makron"] # 0x2c9 - - "ˊ": [t: "modyfikator akut akcent"] # 0x2ca - - "ˋ": [t: "modyfikator grawis akcent"] # 0x2cb - - "ˌ": [t: "modyfikator dolnej pionowej kreski"] # 0x2cc - - "ˍ": [t: "modyfikator dolny makron"] # 0x2cd - - "ˎ": [t: "modyfikator dolny akcent grawis"] # 0x2ce - - "ˏ": [t: "modyfikator dolny akcent akut"] # 0x2cf - - "ː": [t: "modyfikator trójkątny dwukropek"] # 0x2d0 - - "ˑ": [t: "modyfikator połowa trójkątny dwukropek"] # 0x2d1 - - "˒": [t: "modyfikator wyśrodkowany prawa połowa pierścień"] # 0x2d2 - - "˓": [t: "modyfikator wyśrodkowany lewa połowa pierścień"] # 0x2d3 - - "˔": [t: "modyfikator górnej pinezki"] # 0x2d4 - - "˕": [t: "modyfikator dolnej pinezki"] # 0x2d5 - - "˖": [t: "modyfikator znaku plus"] # 0x2d6 - - "˗": [t: "modyfikator znaku minus"] # 0x2d7 - - "˘": [t: "znak krótkości"] # 0x2d8 + - "ʷ": [T: "modyfikator mały w"] # 0x2b7 + - "ʸ": [T: "modyfikator mały y"] # 0x2b8 + - "ʹ": [T: "modyfikator prim"] # 0x2b9 + - "ʺ": [T: "modyfikator podwójny prim"] # 0x2ba + - "ʻ": [T: "modyfikator odwrócony przecinek"] # 0x2bb + - "ʼ": [T: "modyfikator apostrof"] # 0x2bc + - "ʽ": [T: "modyfikator odwrócony przecinek"] # 0x2bd + - "ʾ": [T: "modyfikator prawa połowa pierścień"] # 0x2be + - "ʿ": [T: "modyfikator lewa połowa pierścień"] # 0x2bf + - "ˀ": [T: "modyfikator zwarcie krtaniowe"] # 0x2c0 + - "ˁ": [T: "modyfikator odwrócone zwarcie krtaniowe"] # 0x2c1 + - "˂": [T: "modyfikator lewy grot strzałki"] # 0x2c2 + - "˃": [T: "modyfikator prawy grot strzałki"] # 0x2c3 + - "˄": [T: "modyfikator górny grot strzałki"] # 0x2c4 + - "˅": [T: "modyfikator dolny grot strzałki"] # 0x2c5 + - "ˆ": [T: "modyfikator akcent daszkowy"] # 0x2c6 + - "ˇ": [T: "haczek"] # 0x2c7 + - "ˈ": [T: "modyfikator pionowej kreski"] # 0x2c8 + - "ˉ": [T: "modyfikator makron"] # 0x2c9 + - "ˊ": [T: "modyfikator akut akcent"] # 0x2ca + - "ˋ": [T: "modyfikator grawis akcent"] # 0x2cb + - "ˌ": [T: "modyfikator dolnej pionowej kreski"] # 0x2cc + - "ˍ": [T: "modyfikator dolny makron"] # 0x2cd + - "ˎ": [T: "modyfikator dolny akcent grawis"] # 0x2ce + - "ˏ": [T: "modyfikator dolny akcent akut"] # 0x2cf + - "ː": [T: "modyfikator trójkątny dwukropek"] # 0x2d0 + - "ˑ": [T: "modyfikator połowa trójkątny dwukropek"] # 0x2d1 + - "˒": [T: "modyfikator wyśrodkowany prawa połowa pierścień"] # 0x2d2 + - "˓": [T: "modyfikator wyśrodkowany lewa połowa pierścień"] # 0x2d3 + - "˔": [T: "modyfikator górnej pinezki"] # 0x2d4 + - "˕": [T: "modyfikator dolnej pinezki"] # 0x2d5 + - "˖": [T: "modyfikator znaku plus"] # 0x2d6 + - "˗": [T: "modyfikator znaku minus"] # 0x2d7 + - "˘": [T: "znak krótkości"] # 0x2d8 - "˙": [T: "kropka"] # 0x2d9 - - "˚": [t: "pierścień nad"] # 0x2da + - "˚": [T: "pierścień nad"] # 0x2da - "˛": [t: "ogonek"] # 0x2db - - "˜": [t: "mały tylda"] # 0x2dc - - "˝": [t: "podwójny akut akcent"] # 0x2dd - - "˞": [t: "modyfikator rotycznego haczyka"] # 0x2de - - "˟": [t: "modyfikator krzyż akcent"] # 0x2df - - "ˠ": [t: "modyfikator mały gamma"] # 0x2e0 - - "ˡ": [t: "modyfikator mały L"] # 0x2e1 - - "ˢ": [t: "modyfikator mały s"] # 0x2e2 - - "ˣ": [t: "modyfikator mały X"] # 0x2e3 - - "ˤ": [t: "modyfikator mały odwrócone zwarcie krtaniowe"] # 0x2e4 - - "˥": [t: "modyfikator kreski bardzo wysokiego tonu"] # 0x2e5 - - "˦": [t: "modyfikator kreski wysokiego tonu"] # 0x2e6 - - "˧": [t: "modyfikator środkowy tonowy kreska"] # 0x2e7 - - "˨": [t: "modyfikator kreski niskiego tonu"] # 0x2e8 - - "˩": [t: "modyfikator kreski bardzo niskiego tonu"] # 0x2e9 - - "˪": [t: "modyfikator znak tonu yin odchodzącego"] # 0x2ea - - "˫": [t: "modyfikator znak tonu yang odchodzącego"] # 0x2eb - - "ˬ": [t: "modyfikator dźwięczność"] # 0x2ec - - "˭": [t: "modyfikator nieaspirowany"] # 0x2ed - - "ˮ": [t: "modyfikator podwójny apostrof"] # 0x2ee - - "˯": [t: "modyfikator dolny grot strzałki"] # 0x2ef - - "˰": [t: "modyfikator dolny górny grot strzałki"] # 0x2f0 - - "˱": [t: "modyfikator dolny lewy grot strzałki"] # 0x2f1 - - "˲": [t: "modyfikator dolny prawy grot strzałki"] # 0x2f2 - - "˳": [t: "modyfikator dolny pierścień"] # 0x2f3 - - "˴": [t: "modyfikator środkowy grawis akcent"] # 0x2f4 - - "˵": [t: "modyfikator środkowy podwójny grawis akcent"] # 0x2f5 - - "˶": [t: "modyfikator środkowy podwójny akut akcent"] # 0x2f6 - - "˷": [t: "modyfikator dolna tylda"] # 0x2f7 - - "˸": [t: "modyfikator podniesiony dwukropek"] # 0x2f8 - - "˹": [t: "modyfikator początek wysoki ton"] # 0x2f9 - - "˺": [t: "modyfikator koniec wysoki ton"] # 0x2fa - - "˻": [t: "modyfikator początek niski ton"] # 0x2fb - - "˼": [t: "modyfikator koniec niski ton"] # 0x2fc - - "˽": [t: "modyfikator półka"] # 0x2fd - - "˾": [t: "modyfikator otwórz półka"] # 0x2fe - - "˿": [t: "modyfikator dolny strzałka w lewo"] # 0x2ff - - "̀": [t: "ozdobnik akcentu grawis"] # 0x300 - - "́": [t: "ozdobnik akcentu ostrego"] # 0x301 - - "̂": [t: "ozdobnik daszka"] # 0x302 - - "̃": [t: "ozdobnik tyldy"] # 0x303 - - "̄": [t: "ozdobnik makronu"] # 0x304 - - "̅": [t: "ozdobnik kreski górnej"] # 0x305 - - "̆": [t: "ozdobnik znaku krótkości"] # 0x306 - - "̇": [t: "ozdobnik kropki nad"] # 0x307 - - "̈": [t: "ozdobnik diaerezy"] # 0x308 - - "̉": [t: "hak nad ozdobnik"] # 0x309 - - "̊": [t: "pierścień nad ozdobnik"] # 0x30a - - "̋": [t: "ozdobnik podwójnego akutu"] # 0x30b - - "̌": [t: "haczek"] # 0x30c - - "̍": [t: "ozdobnik pionowej kreski nad"] # 0x30d - - "̎": [t: "ozdobnik podwójnej pionowej kreski nad"] # 0x30e - - "̏": [t: "ozdobnik podwójnego grawisu"] # 0x30f - - "̐": [t: "ozdobnik ćandrabindu"] # 0x310 - - "̑": [t: "odwrócony ozdobnik znaku krótkości"] # 0x311 - - "̒": [t: "odwrócony przecinek nad ozdobnik"] # 0x312 - - "̓": [t: "przecinek nad ozdobnik"] # 0x313 - - "̔": [t: "odwrócony przecinek nad ozdobnik"] # 0x314 - - "̕": [t: "przecinek nad prawy ozdobnik"] # 0x315 - - "̖": [t: "ozdobnik akcentu grawis pod"] # 0x316 - - "̗": [t: "ozdobnik akcentu ostrego pod"] # 0x317 - - "̘": [t: "ozdobnik lewej pinezki pod spodem"] # 0x318 - - "̙": [t: "ozdobnik prawej pinezki pod spodem"] # 0x319 - - "̚": [t: "lewy kąt nad ozdobnik"] # 0x31a - - "̛": [t: "ozdobnik rożka"] # 0x31b - - "̜": [t: "lewa połowa pierścień pod ozdobnik"] # 0x31c - - "̝": [t: "ozdobnik górnej pinezki pod spodem"] # 0x31d - - "̞": [t: "ozdobnik dolnej pinezki pod spodem"] # 0x31e - - "̟": [t: "ozdobnik znaku plus pod spodem"] # 0x31f - - "̠": [t: "ozdobnik znaku minus pod spodem"] # 0x320 - - "̡": [t: "palatalizowany haczyk pod spodem"] # 0x321 - - "̢": [t: "retrofleksyjny haczyk pod spodem"] # 0x322 - - "̣": [t: "ozdobnik kropki pod"] # 0x323 - - "̤": [t: "ozdobnik dierezy pod spodem"] # 0x324 - - "̥": [t: "pierścień pod ozdobnik"] # 0x325 - - "̦": [t: "przecinek pod ozdobnik"] # 0x326 - - "̧": [t: "ozdobnik cedilli"] # 0x327 - - "̨": [t: "ogonek ozdobnik"] # 0x328 - - "̩": [t: "ozdobnik pionowej kreski pod spodem"] # 0x329 - - "̪": [t: "mostek pod ozdobnik"] # 0x32a - - "̫": [t: "odwrócony podwójny łuk pod spodem"] # 0x32b - - "̬": [t: "haczek pod ozdobnik"] # 0x32c - - "̭": [t: "ozdobnik daszka pod"] # 0x32d - - "̮": [t: "ozdobnik znaku krótkości pod spodem"] # 0x32e - - "̯": [t: "odwrócony ozdobnik znaku krótkości pod spodem"] # 0x32f - - "̰": [t: "tylda pod ozdobnik"] # 0x330 - - "̱": [t: "ozdobnik makronu pod"] # 0x331 - - "̲": [t: "dolny linia ozdobnik"] # 0x332 - - "̳": [t: "podwójny dolny linia ozdobnik"] # 0x333 - - "̴": [t: "tylda nakładka ozdobnik"] # 0x334 - - "̵": [t: "krótkie przekreślenie nakładane jako ozdobnik"] # 0x335 - - "̶": [t: "długie przekreślenie nakładane jako ozdobnik"] # 0x336 - - "̷": [t: "krótki ukośnik nakładka ozdobnik"] # 0x337 - - "̸": [t: "długi ukośnik nakładka ozdobnik"] # 0x338 - - "̹": [t: "prawa połowa pierścień pod ozdobnik"] # 0x339 - - "̺": [t: "odwrócony mostek pod ozdobnik"] # 0x33a - - "̻": [t: "kwadrat pod ozdobnik"] # 0x33b - - "̼": [t: "ozdobnik mewy pod spodem"] # 0x33c - - "̽": [t: "X nad ozdobnik"] # 0x33d - - "̾": [t: "pionowy ozdobnik tyldy"] # 0x33e - - "̿": [t: "ozdobnik podwójnej kreski górnej"] # 0x33f - - "̀": [t: "grawis tonowy znak ozdobnik"] # 0x340 - - "́": [t: "akut tonowy znak ozdobnik"] # 0x341 - - "͆": [t: "mostek nad"] # 0x346 + - "˜": [T: "mały tylda"] # 0x2dc + - "˝": [T: "podwójny akut akcent"] # 0x2dd + - "˞": [T: "modyfikator rotycznego haczyka"] # 0x2de + - "˟": [T: "modyfikator krzyż akcent"] # 0x2df + - "ˠ": [T: "modyfikator mały gamma"] # 0x2e0 + - "ˡ": [T: "modyfikator mały L"] # 0x2e1 + - "ˢ": [T: "modyfikator mały s"] # 0x2e2 + - "ˣ": [T: "modyfikator mały X"] # 0x2e3 + - "ˤ": [T: "modyfikator mały odwrócone zwarcie krtaniowe"] # 0x2e4 + - "˥": [T: "modyfikator kreski bardzo wysokiego tonu"] # 0x2e5 + - "˦": [T: "modyfikator kreski wysokiego tonu"] # 0x2e6 + - "˧": [T: "modyfikator środkowy tonowy kreska"] # 0x2e7 + - "˨": [T: "modyfikator kreski niskiego tonu"] # 0x2e8 + - "˩": [T: "modyfikator kreski bardzo niskiego tonu"] # 0x2e9 + - "˪": [T: "modyfikator znak tonu yin odchodzącego"] # 0x2ea + - "˫": [T: "modyfikator znak tonu yang odchodzącego"] # 0x2eb + - "ˬ": [T: "modyfikator dźwięczność"] # 0x2ec + - "˭": [T: "modyfikator nieaspirowany"] # 0x2ed + - "ˮ": [T: "modyfikator podwójny apostrof"] # 0x2ee + - "˯": [T: "modyfikator dolny grot strzałki"] # 0x2ef + - "˰": [T: "modyfikator dolny górny grot strzałki"] # 0x2f0 + - "˱": [T: "modyfikator dolny lewy grot strzałki"] # 0x2f1 + - "˲": [T: "modyfikator dolny prawy grot strzałki"] # 0x2f2 + - "˳": [T: "modyfikator dolny pierścień"] # 0x2f3 + - "˴": [T: "modyfikator środkowy grawis akcent"] # 0x2f4 + - "˵": [T: "modyfikator środkowy podwójny grawis akcent"] # 0x2f5 + - "˶": [T: "modyfikator środkowy podwójny akut akcent"] # 0x2f6 + - "˷": [T: "modyfikator dolna tylda"] # 0x2f7 + - "˸": [T: "modyfikator podniesiony dwukropek"] # 0x2f8 + - "˹": [T: "modyfikator początek wysoki ton"] # 0x2f9 + - "˺": [T: "modyfikator koniec wysoki ton"] # 0x2fa + - "˻": [T: "modyfikator początek niski ton"] # 0x2fb + - "˼": [T: "modyfikator koniec niski ton"] # 0x2fc + - "˽": [T: "modyfikator półka"] # 0x2fd + - "˾": [T: "modyfikator otwórz półka"] # 0x2fe + - "˿": [T: "modyfikator dolny strzałka w lewo"] # 0x2ff + - "̀": [T: "ozdobnik akcentu grawis"] # 0x300 + - "́": [T: "ozdobnik akcentu ostrego"] # 0x301 + - "̂": [T: "ozdobnik daszka"] # 0x302 + - "̃": [T: "ozdobnik tyldy"] # 0x303 + - "̄": [T: "ozdobnik makronu"] # 0x304 + - "̅": [T: "ozdobnik kreski górnej"] # 0x305 + - "̆": [T: "ozdobnik znaku krótkości"] # 0x306 + - "̇": [T: "ozdobnik kropki nad"] # 0x307 + - "̈": [T: "ozdobnik diaerezy"] # 0x308 + - "̉": [T: "hak nad ozdobnik"] # 0x309 + - "̊": [T: "pierścień nad ozdobnik"] # 0x30a + - "̋": [T: "ozdobnik podwójnego akutu"] # 0x30b + - "̌": [T: "haczek"] # 0x30c + - "̍": [T: "ozdobnik pionowej kreski nad"] # 0x30d + - "̎": [T: "ozdobnik podwójnej pionowej kreski nad"] # 0x30e + - "̏": [T: "ozdobnik podwójnego grawisu"] # 0x30f + - "̐": [T: "ozdobnik ćandrabindu"] # 0x310 + - "̑": [T: "odwrócony ozdobnik znaku krótkości"] # 0x311 + - "̒": [T: "odwrócony przecinek nad ozdobnik"] # 0x312 + - "̓": [T: "przecinek nad ozdobnik"] # 0x313 + - "̔": [T: "odwrócony przecinek nad ozdobnik"] # 0x314 + - "̕": [T: "przecinek nad prawy ozdobnik"] # 0x315 + - "̖": [T: "ozdobnik akcentu grawis pod"] # 0x316 + - "̗": [T: "ozdobnik akcentu ostrego pod"] # 0x317 + - "̘": [T: "ozdobnik lewej pinezki pod spodem"] # 0x318 + - "̙": [T: "ozdobnik prawej pinezki pod spodem"] # 0x319 + - "̚": [T: "lewy kąt nad ozdobnik"] # 0x31a + - "̛": [T: "ozdobnik rożka"] # 0x31b + - "̜": [T: "lewa połowa pierścień pod ozdobnik"] # 0x31c + - "̝": [T: "ozdobnik górnej pinezki pod spodem"] # 0x31d + - "̞": [T: "ozdobnik dolnej pinezki pod spodem"] # 0x31e + - "̟": [T: "ozdobnik znaku plus pod spodem"] # 0x31f + - "̠": [T: "ozdobnik znaku minus pod spodem"] # 0x320 + - "̡": [T: "palatalizowany haczyk pod spodem"] # 0x321 + - "̢": [T: "retrofleksyjny haczyk pod spodem"] # 0x322 + - "̣": [T: "ozdobnik kropki pod"] # 0x323 + - "̤": [T: "ozdobnik dierezy pod spodem"] # 0x324 + - "̥": [T: "pierścień pod ozdobnik"] # 0x325 + - "̦": [T: "przecinek pod ozdobnik"] # 0x326 + - "̧": [T: "ozdobnik cedilli"] # 0x327 + - "̨": [T: "ogonek ozdobnik"] # 0x328 + - "̩": [T: "ozdobnik pionowej kreski pod spodem"] # 0x329 + - "̪": [T: "mostek pod ozdobnik"] # 0x32a + - "̫": [T: "odwrócony podwójny łuk pod spodem"] # 0x32b + - "̬": [T: "haczek pod ozdobnik"] # 0x32c + - "̭": [T: "ozdobnik daszka pod"] # 0x32d + - "̮": [T: "ozdobnik znaku krótkości pod spodem"] # 0x32e + - "̯": [T: "odwrócony ozdobnik znaku krótkości pod spodem"] # 0x32f + - "̰": [T: "tylda pod ozdobnik"] # 0x330 + - "̱": [T: "ozdobnik makronu pod"] # 0x331 + - "̲": [T: "dolny linia ozdobnik"] # 0x332 + - "̳": [T: "podwójny dolny linia ozdobnik"] # 0x333 + - "̴": [T: "tylda nakładka ozdobnik"] # 0x334 + - "̵": [T: "krótkie przekreślenie nakładane jako ozdobnik"] # 0x335 + - "̶": [T: "długie przekreślenie nakładane jako ozdobnik"] # 0x336 + - "̷": [T: "krótki ukośnik nakładka ozdobnik"] # 0x337 + - "̸": [T: "długi ukośnik nakładka ozdobnik"] # 0x338 + - "̹": [T: "prawa połowa pierścień pod ozdobnik"] # 0x339 + - "̺": [T: "odwrócony mostek pod ozdobnik"] # 0x33a + - "̻": [T: "kwadrat pod ozdobnik"] # 0x33b + - "̼": [T: "ozdobnik mewy pod spodem"] # 0x33c + - "̽": [T: "X nad ozdobnik"] # 0x33d + - "̾": [T: "pionowy ozdobnik tyldy"] # 0x33e + - "̿": [T: "ozdobnik podwójnej kreski górnej"] # 0x33f + - "̀": [T: "grawis tonowy znak ozdobnik"] # 0x340 + - "́": [T: "akut tonowy znak ozdobnik"] # 0x341 + - "͆": [T: "mostek nad"] # 0x346 - "ΪΫϏ": # 0x3aa, 0x3ab, 0x3cf - test: @@ -205,29 +205,29 @@ if: "$SpeechOverrides_CapitalLetters = ''" then_test: if: "$Impairment = 'Blindness'" - then: [t: "wielka"] + then: [T: "wielka"] else: [x: "$SpeechOverrides_CapitalLetters"] - pitch: value: "$CapitalLetters_Pitch" replace: [spell: "translate('.', 'ΪΫϏ', 'ιυϗ')"] - - t: "z dialityką" - - "ϊ": [t: "jota z dialityką"] # 0x3ca - - "ϋ": [t: "ypsilon z dialityką"] # 0x3cb - - "ό": [t: "omikron z tonosem"] # 0x3cc - - "ύ": [t: "ypsilon z tonosem"] # 0x3cd - - "ώ": [t: "omega z tonosem"] # 0x3ce + - T: "z dialityką" + - "ϊ": [T: "jota z dialityką"] # 0x3ca + - "ϋ": [T: "ypsilon z dialityką"] # 0x3cb + - "ό": [T: "omikron z tonosem"] # 0x3cc + - "ύ": [T: "ypsilon z tonosem"] # 0x3cd + - "ώ": [T: "omega z tonosem"] # 0x3ce - "ϐ": [t: "beta"] # 0x3d0 - "ϑ": [t: "theta"] # 0x3d1 - - "ϒ": [t: "ypsilon z haczykiem"] # 0x3d2 - - "ϓ": [t: "ypsilon z akutem i haczykiem"] # 0x3d3 - - "ϔ": [t: "ypsilon z dierezą i haczykiem"] # 0x3d4 - - "ϕ": [t: "fi"] # 0x3d5 + - "ϒ": [T: "ypsilon z haczykiem"] # 0x3d2 + - "ϓ": [T: "ypsilon z akutem i haczykiem"] # 0x3d3 + - "ϔ": [T: "ypsilon z dierezą i haczykiem"] # 0x3d4 + - "ϕ": [T: "fi"] # 0x3d5 - "ϖ": [t: "pi"] # 0x3d6 - "ϗ": [t: "kai"] # 0x3d7 - - "Ϙ": [t: "wielka archaiczna koppa"] # 0x3d8 - - "ϙ": [t: "archaiczna koppa"] # 0x3d9 + - "Ϙ": [T: "wielka archaiczna koppa"] # 0x3d8 + - "ϙ": [T: "archaiczna koppa"] # 0x3d9 - "ϵ": [t: "epsilon"] # 0x3f5 - - "϶": [t: "odwrócony epsilon"] # 0x3f6 + - "϶": [T: "odwrócony epsilon"] # 0x3f6 - "А-Я": # 0x410 - 0x42f - test: if: "$CapitalLetters_Beep" @@ -241,23 +241,23 @@ if: "$SpeechOverrides_CapitalLetters = ''" then_test: if: "$Impairment = 'Blindness'" - then: [t: "wielka"] + then: [T: "wielka"] else: [x: "$SpeechOverrides_CapitalLetters"] - pitch: value: "$CapitalLetters_Pitch" replace: [spell: "translate('.', 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ', 'абвгдежзийклмнопрстуфхцчшщъыьэюя')"] - "а": [T: "a"] # 0x430 - "б": [t: "be"] # 0x431 - - "в": [t: "we"] # 0x432 - - "г": [t: "ge"] # 0x433 + - "в": [T: "we"] # 0x432 + - "г": [T: "ge"] # 0x433 - "д": [t: "de"] # 0x434 - - "е": [t: "je"] # 0x435 - - "ж": [t: "że"] # 0x436 + - "е": [T: "je"] # 0x435 + - "ж": [T: "że"] # 0x436 - "з": [t: "ze"] # 0x437 - "и": [t: "i"] # 0x438 - - "й": [t: "krótkie i"] # 0x439 + - "й": [T: "krótkie i"] # 0x439 - "к": [t: "ka"] # 0x43a - - "л": [t: "eł"] # 0x43b + - "л": [T: "eł"] # 0x43b - "м": [t: "em"] # 0x43c - "н": [t: "en"] # 0x43d - "о": [t: "o"] # 0x43e @@ -267,29 +267,29 @@ - "т": [t: "te"] # 0x442 - "у": [t: "u"] # 0x443 - "ф": [t: "ef"] # 0x444 - - "х": [t: "cha"] # 0x445 - - "ц": [t: "ce"] # 0x446 - - "ч": [t: "cze"] # 0x447 - - "ш": [t: "sza"] # 0x448 - - "щ": [t: "szcza"] # 0x449 - - "ъ": [t: "twardy znak"] # 0x44a - - "ы": [t: "jery"] # 0x44b - - "ь": [t: "miękki znak"] # 0x44c + - "х": [T: "cha"] # 0x445 + - "ц": [T: "ce"] # 0x446 + - "ч": [T: "cze"] # 0x447 + - "ш": [T: "sza"] # 0x448 + - "щ": [T: "szcza"] # 0x449 + - "ъ": [T: "twardy znak"] # 0x44a + - "ы": [T: "jery"] # 0x44b + - "ь": [T: "miękki znak"] # 0x44c - "э": [t: "e"] # 0x44d - - "ю": [t: "ju"] # 0x44e - - "я": [t: "ja"] # 0x44f - - "؆": [t: "arabsko-indyjski pierwiastek sześcienny"] # 0x606 - - "؇": [t: "arabsko-indyjski czwarty pierwiastek"] # 0x607 - - "؈": [t: "arabski półprosta"] # 0x608 - - "‐": [t: "łącznik"] # 0x2010 - - "‑": [t: "łącznik"] # 0x2011 - - "‒": [t: "pauza cyfrowa"] # 0x2012 - - "–": [t: "półpauza"] # 0x2013 - - "—": [t: "pauza"] # 0x2014 - - "―": [t: "kreska pozioma"] # 0x2015 - - "‖": [t: "podwójna pionowa kreska"] # 0x2016 - - "†": [t: "obelisk"] # 0x2020 - - "‡": [t: "podwójny obelisk"] # 0x2021 + - "ю": [T: "ju"] # 0x44e + - "я": [T: "ja"] # 0x44f + - "؆": [T: "arabsko-indyjski pierwiastek sześcienny"] # 0x606 + - "؇": [T: "arabsko-indyjski czwarty pierwiastek"] # 0x607 + - "؈": [T: "arabski półprosta"] # 0x608 + - "‐": [T: "łącznik"] # 0x2010 + - "‑": [T: "łącznik"] # 0x2011 + - "‒": [T: "pauza cyfrowa"] # 0x2012 + - "–": [T: "półpauza"] # 0x2013 + - "—": [T: "pauza"] # 0x2014 + - "―": [T: "kreska pozioma"] # 0x2015 + - "‖": [T: "podwójna pionowa kreska"] # 0x2016 + - "†": [T: "obelisk"] # 0x2020 + - "‡": [T: "podwójny obelisk"] # 0x2021 - " - ": [T: " "] # 0x2000 - 0x2007 @@ -297,7 +297,7 @@ - test: if: "@data-chem-formula-op" then: [T: "kropka"] - else: [t: "punkt"] + else: [T: "punkt"] - "…": # 0x2026 test: @@ -306,221 +306,221 @@ # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' # speak '…' as 'and so on...' unless expr starts with '…' - "../*[1][.='…']" - then: [t: "trzy kropki"] + then: [T: "trzy kropki"] else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' if: "count(following-sibling::*) = 0" - then: [t: "i tak dalej"] - else: [t: "i tak dalej aż do"] - - - "‰": [t: "promil"] # 0x2030 - - "‱": [t: "na dziesięć tysięcy"] # 0x2031 - - "′": [t: "prim"] # 0x2032 - - "″": [t: "podwójny prim"] # 0x2033 - - "‴": [t: "potrójny prim"] # 0x2034 - - "‵": [t: "odwrócony prim"] # 0x2035 - - "‶": [t: "odwrócony podwójny prim"] # 0x2036 - - "‷": [t: "odwrócony potrójny prim"] # 0x2037 + then: [T: "i tak dalej"] + else: [T: "i tak dalej aż do"] + + - "‰": [T: "promil"] # 0x2030 + - "‱": [T: "na dziesięć tysięcy"] # 0x2031 + - "′": [T: "prim"] # 0x2032 + - "″": [T: "podwójny prim"] # 0x2033 + - "‴": [T: "potrójny prim"] # 0x2034 + - "‵": [T: "odwrócony prim"] # 0x2035 + - "‶": [T: "odwrócony podwójny prim"] # 0x2036 + - "‷": [T: "odwrócony potrójny prim"] # 0x2037 - "‸": [T: "do potęgi"] # 0x2038 - - "‹": [t: "pojedynczy lewy cudzysłów ostrokątny"] # 0x2039 - - "›": [t: "pojedynczy prawy cudzysłów ostrokątny"] # 0x203a + - "‹": [T: "pojedynczy lewy cudzysłów ostrokątny"] # 0x2039 + - "›": [T: "pojedynczy prawy cudzysłów ostrokątny"] # 0x203a - "‼": # 0x203c - test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [t: "podwójny wykrzyknik punkt"] # 0x203c - else: [t: "podwójny silnia"] # 0x203c + then: [T: "podwójny wykrzyknik punkt"] # 0x203c + else: [T: "podwójny silnia"] # 0x203c - "⁄": # 0x2044 - test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [t: "duży ukośnik"] # 0x203c + then: [T: "duży ukośnik"] # 0x203c else: [T: "podzielone przez"] # 0x203c - - "⁅": [t: "lewy kwadratowy nawias z piórem"] # 0x2045 - - "⁆": [t: "prawy kwadratowy nawias z piórem"] # 0x2046 - - "※": [t: "znak odsyłacza"] # 0x203b - - "‿": [t: "łuk dolny"] # 0x203F - - "⁀": [t: "łuk górny"] # 0x2040 - - "⁎": [t: "dolna gwiazdka"] # 0x204e - - "⁏": [t: "odwrócony średnik"] # 0x204f - - "⁐": [t: "zamknij górny"] # 0x2050 - - "⁑": [t: "dwie pionowe gwiazdki"] # 0x2051 - - "⁒": [t: "handlowy znak minus"] # 0x2052 - - "⁗": [t: "poczwórny prim"] # 0x2057 + - "⁅": [T: "lewy kwadratowy nawias z piórem"] # 0x2045 + - "⁆": [T: "prawy kwadratowy nawias z piórem"] # 0x2046 + - "※": [T: "znak odsyłacza"] # 0x203b + - "‿": [T: "łuk dolny"] # 0x203F + - "⁀": [T: "łuk górny"] # 0x2040 + - "⁎": [T: "dolna gwiazdka"] # 0x204e + - "⁏": [T: "odwrócony średnik"] # 0x204f + - "⁐": [T: "zamknij górny"] # 0x2050 + - "⁑": [T: "dwie pionowe gwiazdki"] # 0x2051 + - "⁒": [T: "handlowy znak minus"] # 0x2052 + - "⁗": [T: "poczwórny prim"] # 0x2057 - "⁠": [T: ""] # 0x2060 - - "⁰": [t: "do zerowej potęgi"] # 0x2070 - - "ⁱ": [t: "do potęgi i"] # 0x2071 - - "⁴": [t: "do czwartej potęgi"] # 0x2074 - - "⁵": [t: "do piątej potęgi"] # 0x2075 - - "⁶": [t: "do szóstej potęgi"] # 0x2076 - - "⁷": [t: "do siódmej potęgi"] # 0x2077 - - "⁸": [t: "do ósmej potęgi"] # 0x2078 - - "⁹": [t: "do dziewiątej potęgi"] # 0x2079 - - "⁺": [t: "znak plus w indeksie górnym"] # 0x207a - - "⁻": [t: "znak minus w indeksie górnym"] # 0x207b - - "⁼": [t: "znak równości w indeksie górnym"] # 0x207c - - "⁽": [t: "lewy nawias w indeksie górnym"] # 0x207d - - "⁾": [t: "prawy nawias w indeksie górnym"] # 0x207e - - "ⁿ": [t: "do potęgi n"] # 0x207f - - "₀": [t: "indeks dolny zero"] # 0x2080 - - "₁": [t: "indeks dolny jeden"] # 0x2081 - - "₂": [t: "indeks dolny dwa"] # 0x2082 - - "₃": [t: "indeks dolny trzy"] # 0x2083 - - "₄": [t: "indeks dolny cztery"] # 0x2084 - - "₅": [t: "indeks dolny pięć"] # 0x2085 - - "₆": [t: "indeks dolny sześć"] # 0x2086 - - "₇": [t: "indeks dolny siedem"] # 0x2087 - - "₈": [t: "indeks dolny osiem"] # 0x2088 - - "₉": [t: "indeks dolny dziewięć"] # 0x2089 - - "₊": [t: "znak plus w indeksie dolnym"] # 0x208a - - "₋": [t: "znak minus w indeksie dolnym"] # 0x208b - - "₌": [t: "znak równości w indeksie dolnym"] # 0x208c - - "₍": [t: "lewy nawias w indeksie dolnym"] # 0x208d - - "₎": [t: "prawy nawias w indeksie dolnym"] # 0x208e - - "ₐ": [t: "indeks dolny a"] # 0x2090 - - "ₑ": [t: "indeks dolny e"] # 0x2091 - - "ₒ": [t: "indeks dolny o"] # 0x2092 - - "ₓ": [t: "indeks dolny X"] # 0x2093 - - "ₕ": [t: "indeks dolny h"] # 0x2095 - - "ₖ": [t: "indeks dolny k"] # 0x2096 - - "ₗ": [t: "indeks dolny L"] # 0x2097 - - "ₘ": [t: "indeks dolny M"] # 0x2098 - - "ₙ": [t: "indeks dolny N"] # 0x2099 - - "ₚ": [t: "indeks dolny p"] # 0x209a - - "ₛ": [t: "indeks dolny s"] # 0x209b - - "ₜ": [t: "indeks dolny t"] # 0x209c - - "₠": [t: "europejska jednostka walutowa"] # 0x20a0 - - "₡": [t: "kolon"] # 0x20a1 - - "₢": [t: "znak cruzeiro"] # 0x20a2 - - "₣": [t: "frank"] # 0x20a3 + - "⁰": [T: "do zerowej potęgi"] # 0x2070 + - "ⁱ": [T: "do potęgi i"] # 0x2071 + - "⁴": [T: "do czwartej potęgi"] # 0x2074 + - "⁵": [T: "do piątej potęgi"] # 0x2075 + - "⁶": [T: "do szóstej potęgi"] # 0x2076 + - "⁷": [T: "do siódmej potęgi"] # 0x2077 + - "⁸": [T: "do ósmej potęgi"] # 0x2078 + - "⁹": [T: "do dziewiątej potęgi"] # 0x2079 + - "⁺": [T: "znak plus w indeksie górnym"] # 0x207a + - "⁻": [T: "znak minus w indeksie górnym"] # 0x207b + - "⁼": [T: "znak równości w indeksie górnym"] # 0x207c + - "⁽": [T: "lewy nawias w indeksie górnym"] # 0x207d + - "⁾": [T: "prawy nawias w indeksie górnym"] # 0x207e + - "ⁿ": [T: "do potęgi n"] # 0x207f + - "₀": [T: "indeks dolny zero"] # 0x2080 + - "₁": [T: "indeks dolny jeden"] # 0x2081 + - "₂": [T: "indeks dolny dwa"] # 0x2082 + - "₃": [T: "indeks dolny trzy"] # 0x2083 + - "₄": [T: "indeks dolny cztery"] # 0x2084 + - "₅": [T: "indeks dolny pięć"] # 0x2085 + - "₆": [T: "indeks dolny sześć"] # 0x2086 + - "₇": [T: "indeks dolny siedem"] # 0x2087 + - "₈": [T: "indeks dolny osiem"] # 0x2088 + - "₉": [T: "indeks dolny dziewięć"] # 0x2089 + - "₊": [T: "znak plus w indeksie dolnym"] # 0x208a + - "₋": [T: "znak minus w indeksie dolnym"] # 0x208b + - "₌": [T: "znak równości w indeksie dolnym"] # 0x208c + - "₍": [T: "lewy nawias w indeksie dolnym"] # 0x208d + - "₎": [T: "prawy nawias w indeksie dolnym"] # 0x208e + - "ₐ": [T: "indeks dolny a"] # 0x2090 + - "ₑ": [T: "indeks dolny e"] # 0x2091 + - "ₒ": [T: "indeks dolny o"] # 0x2092 + - "ₓ": [T: "indeks dolny X"] # 0x2093 + - "ₕ": [T: "indeks dolny h"] # 0x2095 + - "ₖ": [T: "indeks dolny k"] # 0x2096 + - "ₗ": [T: "indeks dolny L"] # 0x2097 + - "ₘ": [T: "indeks dolny M"] # 0x2098 + - "ₙ": [T: "indeks dolny N"] # 0x2099 + - "ₚ": [T: "indeks dolny p"] # 0x209a + - "ₛ": [T: "indeks dolny s"] # 0x209b + - "ₜ": [T: "indeks dolny t"] # 0x209c + - "₠": [T: "europejska jednostka walutowa"] # 0x20a0 + - "₡": [T: "kolon"] # 0x20a1 + - "₢": [T: "znak cruzeiro"] # 0x20a2 + - "₣": [T: "frank"] # 0x20a3 - "₤": [t: "lira"] # 0x20a4 - - "₥": [t: "mille"] # 0x20a5 + - "₥": [T: "mille"] # 0x20a5 - "₦": [t: "naira"] # 0x20a6 - "₧": [t: "peseta"] # 0x20a7 - - "₨": [t: "rupie"] # 0x20a8 + - "₨": [T: "rupie"] # 0x20a8 - "₩": [t: "won"] # 0x20a9 - - "₪": [t: "nowe szekle"] # 0x20aa + - "₪": [T: "nowe szekle"] # 0x20aa - "₫": [t: "dong"] # 0x20ab - - "€": [t: "euro"] # 0x20ac + - "€": [T: "euro"] # 0x20ac - "₭": [t: "kip"] # 0x20ad - "₮": [t: "tugrik"] # 0x20ae - "₯": [t: "drachma"] # 0x20af - - "₰": [t: "niemieckie fenigi"] # 0x20b0 - - "₱": [t: "peso"] # 0x20b1 - - "₲": [t: "guarani"] # 0x20b2 - - "₳": [t: "australe"] # 0x20b3 - - "₴": [t: "hrywny"] # 0x20b4 - - "₵": [t: "cedi"] # 0x20b5 - - "₶": [t: "liwr turoński"] # 0x20b6 + - "₰": [T: "niemieckie fenigi"] # 0x20b0 + - "₱": [T: "peso"] # 0x20b1 + - "₲": [T: "guarani"] # 0x20b2 + - "₳": [T: "australe"] # 0x20b3 + - "₴": [T: "hrywny"] # 0x20b4 + - "₵": [T: "cedi"] # 0x20b5 + - "₶": [T: "liwr turoński"] # 0x20b6 - "₷": [T: "spesmilos"] # 0x20b7 - - "₸": [t: "tenge"] # 0x20b8 - - "₹": [t: "rupie indyjskie"] # 0x20b9 - - "₺": [t: "liry tureckie"] # 0x20ba - - "⃐": [t: "lewy harpun nad ozdobnik"] # 0x20d0 - - "⃑": [t: "prawy harpun nad ozdobnik"] # 0x20d1 - - "⃒": [t: "ozdobnik długiej pionowej kreski nakładanej"] # 0x20d2 - - "⃓": [t: "ozdobnik krótkiej pionowej kreski nakładanej"] # 0x20d3 - - "⃔": [t: "strzałka nad przeciwnie do ruchu wskazówek zegara, ozdobnik"] # 0x20d4 - - "⃕": [t: "strzałka nad zgodnie z ruchem wskazówek zegara, ozdobnik"] # 0x20d5 - - "⃖": [t: "strzałka w lewo nad ozdobnik"] # 0x20d6 - - "⃗": [t: "strzałka w prawo nad ozdobnik"] # 0x20d7 - - "⃘": [t: "pierścień nakładka ozdobnik"] # 0x20d8 - - "⃙": [t: "pierścień zgodnie z ruchem wskazówek zegara, ozdobnik nakładany"] # 0x20d9 - - "⃚": [t: "pierścień przeciwnie do ruchu wskazówek zegara, ozdobnik nakładany"] # 0x20da - - "⃛": [t: "potrójny kropka"] # 0x20db - - "⃜": [t: "poczwórny kropka"] # 0x20dc - - "⃝": [t: "obejmujący okrąg ozdobnik"] # 0x20dd - - "⃞": [t: "obejmujący kwadrat ozdobnik"] # 0x20de - - "⃟": [t: "obejmujący romb ozdobnik"] # 0x20df - - "⃠": [t: "obejmujący okrąg ukośnik odwrotny ozdobnik"] # 0x20e0 - - "⃡": [t: "lewy strzałka w prawo nad ozdobnik"] # 0x20e1 - - "⃢": [t: "obejmujący ekran, ozdobnik"] # 0x20e2 - - "⃣": [t: "obejmujący nasadkę klawisza, ozdobnik"] # 0x20e3 - - "⃤": [t: "obejmujący w górę skierowany trójkąt ozdobnik"] # 0x20e4 - - "⃥": [t: "odwrotny ukośnik nakładka ozdobnik"] # 0x20e5 - - "⃦": [t: "ozdobnik podwójnej pionowej kreski"] # 0x20e6 - - "⃧": [t: "symbol renty, ozdobnik"] # 0x20e7 - - "⃨": [t: "potrójna kropka pod spodem"] # 0x20e8 - - "⃩": [t: "szeroki mostek nad, ozdobnik"] # 0x20e9 - - "⃪": [t: "strzałka w lewo nakładka ozdobnik"] # 0x20ea - - "⃫": [t: "długi podwójny ukośnik nakładka ozdobnik"] # 0x20eb - - "⃬": [t: "prawy harpun z grotem dolnym ozdobnik"] # 0x20ec - - "⃭": [t: "lewy harpun z grotem dolnym ozdobnik"] # 0x20ed - - "⃮": [t: "strzałka w lewo pod ozdobnik"] # 0x20ee - - "⃯": [t: "strzałka w prawo pod ozdobnik"] # 0x20ef - - "⃰": [t: "gwiazdka nad ozdobnik"] # 0x20f0 - - "℄": [t: "symbol linii środkowej"] # 0x2104 - - "℅": [t: "do rąk"] # 0x2105 - - "℆": [t: "każda"] # 0x2106 - - "ℇ": [t: "stała Eulera"] # 0x2107 - - "℈": [t: "skrupule"] # 0x2108 - - "℉": [t: "stopnie Fahrenheita"] # 0x2109 - - "ℊ": [t: "pisane g"] # 0x210a + - "₸": [T: "tenge"] # 0x20b8 + - "₹": [T: "rupie indyjskie"] # 0x20b9 + - "₺": [T: "liry tureckie"] # 0x20ba + - "⃐": [T: "lewy harpun nad ozdobnik"] # 0x20d0 + - "⃑": [T: "prawy harpun nad ozdobnik"] # 0x20d1 + - "⃒": [T: "ozdobnik długiej pionowej kreski nakładanej"] # 0x20d2 + - "⃓": [T: "ozdobnik krótkiej pionowej kreski nakładanej"] # 0x20d3 + - "⃔": [T: "strzałka nad przeciwnie do ruchu wskazówek zegara, ozdobnik"] # 0x20d4 + - "⃕": [T: "strzałka nad zgodnie z ruchem wskazówek zegara, ozdobnik"] # 0x20d5 + - "⃖": [T: "strzałka w lewo nad ozdobnik"] # 0x20d6 + - "⃗": [T: "strzałka w prawo nad ozdobnik"] # 0x20d7 + - "⃘": [T: "pierścień nakładka ozdobnik"] # 0x20d8 + - "⃙": [T: "pierścień zgodnie z ruchem wskazówek zegara, ozdobnik nakładany"] # 0x20d9 + - "⃚": [T: "pierścień przeciwnie do ruchu wskazówek zegara, ozdobnik nakładany"] # 0x20da + - "⃛": [T: "potrójny kropka"] # 0x20db + - "⃜": [T: "poczwórny kropka"] # 0x20dc + - "⃝": [T: "obejmujący okrąg ozdobnik"] # 0x20dd + - "⃞": [T: "obejmujący kwadrat ozdobnik"] # 0x20de + - "⃟": [T: "obejmujący romb ozdobnik"] # 0x20df + - "⃠": [T: "obejmujący okrąg ukośnik odwrotny ozdobnik"] # 0x20e0 + - "⃡": [T: "lewy strzałka w prawo nad ozdobnik"] # 0x20e1 + - "⃢": [T: "obejmujący ekran, ozdobnik"] # 0x20e2 + - "⃣": [T: "obejmujący nasadkę klawisza, ozdobnik"] # 0x20e3 + - "⃤": [T: "obejmujący w górę skierowany trójkąt ozdobnik"] # 0x20e4 + - "⃥": [T: "odwrotny ukośnik nakładka ozdobnik"] # 0x20e5 + - "⃦": [T: "ozdobnik podwójnej pionowej kreski"] # 0x20e6 + - "⃧": [T: "symbol renty, ozdobnik"] # 0x20e7 + - "⃨": [T: "potrójna kropka pod spodem"] # 0x20e8 + - "⃩": [T: "szeroki mostek nad, ozdobnik"] # 0x20e9 + - "⃪": [T: "strzałka w lewo nakładka ozdobnik"] # 0x20ea + - "⃫": [T: "długi podwójny ukośnik nakładka ozdobnik"] # 0x20eb + - "⃬": [T: "prawy harpun z grotem dolnym ozdobnik"] # 0x20ec + - "⃭": [T: "lewy harpun z grotem dolnym ozdobnik"] # 0x20ed + - "⃮": [T: "strzałka w lewo pod ozdobnik"] # 0x20ee + - "⃯": [T: "strzałka w prawo pod ozdobnik"] # 0x20ef + - "⃰": [T: "gwiazdka nad ozdobnik"] # 0x20f0 + - "℄": [T: "symbol linii środkowej"] # 0x2104 + - "℅": [T: "do rąk"] # 0x2105 + - "℆": [T: "każda"] # 0x2106 + - "ℇ": [T: "stała Eulera"] # 0x2107 + - "℈": [T: "skrupule"] # 0x2108 + - "℉": [T: "stopnie Fahrenheita"] # 0x2109 + - "ℊ": [T: "pisane g"] # 0x210a - "ℌℑℨℭ": # 0x210c, 0x2111, 0x2128, 0x212d - - t: "fraktura" + - T: "fraktura" - spell: "translate('.', 'ℌℑℨℭ', 'HIZC')" - "ℍℙℾℿ": # 0x210d, 0x2119, 0x213e, 0x213f - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', 'ℍℙℾℿ', 'HPΓΠ')" - - "ℎ": [t: "stała Plancka"] # 0x210e - - "ℏ": [t: "h kreślone"] # 0x210f + - "ℎ": [T: "stała Plancka"] # 0x210e + - "ℏ": [T: "h kreślone"] # 0x210f - "ℐℒ℘ℬℰℱℳ": # 0x2110, 0x2112, 0x2118, 0x2130, 0x2131, 0x2133 - - t: "pisane" + - T: "pisane" - spell: "translate('.', 'ℐℒ℘ℬℰℱℳ', 'ILPBEFM')" - - "ℓ": [t: "pisane L"] # 0x2113 - - "℔": [t: "funty"] # 0x2114 - - "№": [t: "numer"] # 0x2116 - - "℥": [t: "uncje"] # 0x2125 - - "Ω": [t: "omy"] # 0x2126 + - "ℓ": [T: "pisane L"] # 0x2113 + - "℔": [T: "funty"] # 0x2114 + - "№": [T: "numer"] # 0x2116 + - "℥": [T: "uncje"] # 0x2125 + - "Ω": [T: "omy"] # 0x2126 - "℧": [T: "mho"] # 0x2127 - - "℩": [t: "odwrócony jota"] # 0x2129 - - "K": [t: "kelwin"] # 0x212a - - "Å": [t: "angstremy"] # 0x212b - - "ℯ": [t: "pisane e"] # 0x212f + - "℩": [T: "odwrócony jota"] # 0x2129 + - "K": [T: "kelwin"] # 0x212a + - "Å": [T: "angstremy"] # 0x212b + - "ℯ": [T: "pisane e"] # 0x212f # coalesced some chars that use cap letters - "Ⅎ℺⅁⅂⅃⅄": # 0x2132, 0x213a, 0x2141, 0x2142, 0x2143, 0x2144 - test: - if: "'.' = '℺'" - then: [t: "obrócone"] + then: [T: "obrócone"] - else_if: "'.' = 'Ⅎ'" - then: [t: "odwrócone"] + then: [T: "odwrócone"] - else_if: "'.' = '⅃'" - then: [t: "odwrócone bezszeryfowe"] - else: [t: "odwrócony bezszeryfowe"] + then: [T: "odwrócone bezszeryfowe"] + else: [T: "odwrócony bezszeryfowe"] - spell: "translate('.', 'Ⅎ℺⅁⅂⅃⅄', 'FQGLLY')" - - "ℴ": [t: "pisane o"] # 0x2134 - - "ℵ": [t: "pierwsza pozaskończona liczba kardynalna"] # 0x2135 - - "ℶ": [t: "druga pozaskończona liczba kardynalna"] # 0x2136 - - "ℷ": [t: "trzecia pozaskończona liczba kardynalna"] # 0x2137 - - "ℸ": [t: "czwarta pozaskończona liczba kardynalna"] # 0x2138 - - "ℼ": [t: "dwukreskowe pi"] # 0x213c - - "ℽ": [t: "dwukreskowe gamma"] # 0x213d - - "⅀": [t: "dwukreskowa suma N-arna"] # 0x2140 - - "⅋": [t: "odwrócony znak et"] # 0x214b + - "ℴ": [T: "pisane o"] # 0x2134 + - "ℵ": [T: "pierwsza pozaskończona liczba kardynalna"] # 0x2135 + - "ℶ": [T: "druga pozaskończona liczba kardynalna"] # 0x2136 + - "ℷ": [T: "trzecia pozaskończona liczba kardynalna"] # 0x2137 + - "ℸ": [T: "czwarta pozaskończona liczba kardynalna"] # 0x2138 + - "ℼ": [T: "dwukreskowe pi"] # 0x213c + - "ℽ": [T: "dwukreskowe gamma"] # 0x213d + - "⅀": [T: "dwukreskowa suma N-arna"] # 0x2140 + - "⅋": [T: "odwrócony znak et"] # 0x214b - "⅌": [T: "na"] # 0x214c - - "ⅎ": [t: "odwrócony f"] # 0x214e - - "¼": [t: "jedna czwarta"] # 0x00bc - - "½": [t: "jedna druga"] # 0x00bd - - "¾": [t: "trzy czwarte"] # 0x00be - - "⅐": [t: "jeden siódmy"] # 0x2150 - - "⅑": [t: "jeden dziewiąty"] # 0x2151 - - "⅒": [t: "jedna dziesiąta"] # 0x2152 - - "⅓": [t: "jeden trzeci"] # 0x2153 - - "⅔": [t: "dwie trzecie"] # 0x2154 - - "⅕": [t: "jeden piąty"] # 0x2155 - - "⅖": [t: "dwie piąte"] # 0x2156 - - "⅗": [t: "trzy piąte"] # 0x2157 - - "⅘": [t: "cztery piąte"] # 0x2158 - - "⅙": [t: "jeden szósty"] # 0x2159 - - "⅚": [t: "pięć szóstych"] # 0x215a - - "⅛": [t: "jeden ósmy"] # 0x215b - - "⅜": [t: "trzy ósme"] # 0x215c - - "⅝": [t: "pięć ósmych"] # 0x215d - - "⅞": [t: "siedem ósmych"] # 0x215e - - "⅟": [t: "jeden przez"] # 0x215f + - "ⅎ": [T: "odwrócony f"] # 0x214e + - "¼": [T: "jedna czwarta"] # 0x00bc + - "½": [T: "jedna druga"] # 0x00bd + - "¾": [T: "trzy czwarte"] # 0x00be + - "⅐": [T: "jeden siódmy"] # 0x2150 + - "⅑": [T: "jeden dziewiąty"] # 0x2151 + - "⅒": [T: "jedna dziesiąta"] # 0x2152 + - "⅓": [T: "jeden trzeci"] # 0x2153 + - "⅔": [T: "dwie trzecie"] # 0x2154 + - "⅕": [T: "jeden piąty"] # 0x2155 + - "⅖": [T: "dwie piąte"] # 0x2156 + - "⅗": [T: "trzy piąte"] # 0x2157 + - "⅘": [T: "cztery piąte"] # 0x2158 + - "⅙": [T: "jeden szósty"] # 0x2159 + - "⅚": [T: "pięć szóstych"] # 0x215a + - "⅛": [T: "jeden ósmy"] # 0x215b + - "⅜": [T: "trzy ósme"] # 0x215c + - "⅝": [T: "pięć ósmych"] # 0x215d + - "⅞": [T: "siedem ósmych"] # 0x215e + - "⅟": [T: "jeden przez"] # 0x215f - "Ⅰ": [t: "I"] # 0x2160 - "Ⅱ": [T: "I I"] # 0x2161 - "Ⅲ": [T: "I I I"] # 0x2162 @@ -553,170 +553,170 @@ - "ⅽ": [T: "C"] # 0x217d - "ⅾ": [T: "D"] # 0x217e - "ⅿ": [T: "M"] # 0x217f - - "↉": [t: "zero trzecich"] # 0x2189 - - "↔": [t: "lewy strzałka w prawo"] # 0x2194 - - "↕": [t: "górny strzałka w dół"] # 0x2195 - - "↖": [t: "północ zachód strzałka"] # 0x2196 + - "↉": [T: "zero trzecich"] # 0x2189 + - "↔": [T: "lewy strzałka w prawo"] # 0x2194 + - "↕": [T: "górny strzałka w dół"] # 0x2195 + - "↖": [T: "północ zachód strzałka"] # 0x2196 - "↗": # 0x2197 - test: if: "ancestor::*[2][self::m:limit]" - then: [t: "dąży od dołu"] - else: [t: "północ wschód strzałka"] + then: [T: "dąży od dołu"] + else: [T: "północ wschód strzałka"] - "↘": # 0x2198 - test: if: "ancestor::*[2][self::m:limit]" - then: [t: "dąży od góry"] - else: [t: "południe wschód strzałka"] - - - "↙": [t: "południe zachód strzałka"] # 0x2199 - - "↚": [t: "przekreślona strzałka w lewo"] # 0x219a - - "↛": [t: "przekreślona strzałka w prawo"] # 0x219b - - "↜": [t: "falista strzałka w lewo"] # 0x219c - - "↝": [t: "falista strzałka w prawo"] # 0x219d - - "↞": [t: "strzałka w lewo z dwoma grotami"] # 0x219e - - "↟": [t: "strzałka w górę z dwoma grotami"] # 0x219f - - "↠": [t: "strzałka w prawo z dwoma grotami"] # 0x21a0 - - "↡": [t: "strzałka w dół z dwoma grotami"] # 0x21a1 - - "↢": [t: "strzałka w lewo z ogon"] # 0x21a2 - - "↣": [t: "strzałka w prawo z ogon"] # 0x21a3 - - "↤": [t: "strzałka w lewo od kreski"] # 0x21a4 - - "↥": [t: "strzałka w górę od kreski"] # 0x21a5 - - "↦": [t: "strzałka w prawo od kreski"] # 0x21a6 - - "↧": [t: "strzałka w dół od kreski"] # 0x21a7 - - "↨": [t: "górny strzałka w dół z podstawa"] # 0x21a8 - - "↩": [t: "strzałka w lewo z hak"] # 0x21a9 - - "↪": [t: "strzałka w prawo z hak"] # 0x21aa - - "↫": [t: "strzałka w lewo z pętlą"] # 0x21ab - - "↬": [t: "strzałka w prawo z pętlą"] # 0x21ac - - "↭": [t: "falista strzałka w lewo i w prawo"] # 0x21ad - - "↮": [t: "przekreślona strzałka w lewo i w prawo"] # 0x21ae - - "↯": [t: "strzałka zygzakowata w dół"] # 0x21af - - "↰": [t: "strzałka w górę z tip lewy"] # 0x21b0 - - "↱": [t: "strzałka w górę z tip prawy"] # 0x21b1 - - "↲": [t: "strzałka w dół z tip lewy"] # 0x21b2 - - "↳": [t: "strzałka w dół z tip prawy"] # 0x21b3 - - "↴": [t: "strzałka w prawo z narożnikiem w dół"] # 0x21b4 - - "↵": [t: "strzałka w dół z narożnikiem w lewo"] # 0x21b5 - - "↶": [t: "strzałka po górnym półokręgu przeciwnie do ruchu wskazówek zegara"] # 0x21b6 - - "↷": [t: "strzałka po górnym półokręgu zgodnie z ruchem wskazówek zegara"] # 0x21b7 - - "↸": [t: "strzałka północno-zachodnia do długiej kreski"] # 0x21b8 - - "↹": [t: "strzałka w lewo do kreski nad strzałką w prawo do kreski"] # 0x21b9 - - "↺": [t: "strzałka po otwartym okręgu przeciwnie do ruchu wskazówek zegara"] # 0x21ba - - "↻": [t: "strzałka po otwartym okręgu zgodnie z ruchem wskazówek zegara"] # 0x21bb - - "↼": [t: "lewy harpun górny"] # 0x21bc - - "↽": [t: "lewy harpun dolny"] # 0x21bd - - "↾": [t: "górny harpun prawy"] # 0x21be - - "↿": [t: "górny harpun lewy"] # 0x21bf - - "⇀": [t: "prawy harpun górny"] # 0x21c0 - - "⇁": [t: "prawy harpun dolny"] # 0x21c1 - - "⇂": [t: "dolny harpun prawy"] # 0x21c2 - - "⇃": [t: "dolny harpun lewy"] # 0x21c3 - - "⇄": [t: "strzałka w prawo nad strzałką w lewo"] # 0x21c4 - - "⇅": [t: "strzałka w górę po lewej i strzałka w dół"] # 0x21c5 - - "⇆": [t: "strzałka w lewo nad strzałką w prawo"] # 0x21c6 - - "⇇": [t: "podwójne strzałki w lewo"] # 0x21c7 - - "⇈": [t: "podwójne strzałki w górę"] # 0x21c8 - - "⇉": [t: "podwójne strzałki w prawo"] # 0x21c9 - - "⇊": [t: "podwójne strzałki w dół"] # 0x21ca - - "⇋": [t: "lewy harpun przez prawy harpun"] # 0x21cb - - "⇌": [t: "prawy harpun przez lewy harpun"] # 0x21cc + then: [T: "dąży od góry"] + else: [T: "południe wschód strzałka"] + + - "↙": [T: "południe zachód strzałka"] # 0x2199 + - "↚": [T: "przekreślona strzałka w lewo"] # 0x219a + - "↛": [T: "przekreślona strzałka w prawo"] # 0x219b + - "↜": [T: "falista strzałka w lewo"] # 0x219c + - "↝": [T: "falista strzałka w prawo"] # 0x219d + - "↞": [T: "strzałka w lewo z dwoma grotami"] # 0x219e + - "↟": [T: "strzałka w górę z dwoma grotami"] # 0x219f + - "↠": [T: "strzałka w prawo z dwoma grotami"] # 0x21a0 + - "↡": [T: "strzałka w dół z dwoma grotami"] # 0x21a1 + - "↢": [T: "strzałka w lewo z ogon"] # 0x21a2 + - "↣": [T: "strzałka w prawo z ogon"] # 0x21a3 + - "↤": [T: "strzałka w lewo od kreski"] # 0x21a4 + - "↥": [T: "strzałka w górę od kreski"] # 0x21a5 + - "↦": [T: "strzałka w prawo od kreski"] # 0x21a6 + - "↧": [T: "strzałka w dół od kreski"] # 0x21a7 + - "↨": [T: "górny strzałka w dół z podstawa"] # 0x21a8 + - "↩": [T: "strzałka w lewo z hak"] # 0x21a9 + - "↪": [T: "strzałka w prawo z hak"] # 0x21aa + - "↫": [T: "strzałka w lewo z pętlą"] # 0x21ab + - "↬": [T: "strzałka w prawo z pętlą"] # 0x21ac + - "↭": [T: "falista strzałka w lewo i w prawo"] # 0x21ad + - "↮": [T: "przekreślona strzałka w lewo i w prawo"] # 0x21ae + - "↯": [T: "strzałka zygzakowata w dół"] # 0x21af + - "↰": [T: "strzałka w górę z tip lewy"] # 0x21b0 + - "↱": [T: "strzałka w górę z tip prawy"] # 0x21b1 + - "↲": [T: "strzałka w dół z tip lewy"] # 0x21b2 + - "↳": [T: "strzałka w dół z tip prawy"] # 0x21b3 + - "↴": [T: "strzałka w prawo z narożnikiem w dół"] # 0x21b4 + - "↵": [T: "strzałka w dół z narożnikiem w lewo"] # 0x21b5 + - "↶": [T: "strzałka po górnym półokręgu przeciwnie do ruchu wskazówek zegara"] # 0x21b6 + - "↷": [T: "strzałka po górnym półokręgu zgodnie z ruchem wskazówek zegara"] # 0x21b7 + - "↸": [T: "strzałka północno-zachodnia do długiej kreski"] # 0x21b8 + - "↹": [T: "strzałka w lewo do kreski nad strzałką w prawo do kreski"] # 0x21b9 + - "↺": [T: "strzałka po otwartym okręgu przeciwnie do ruchu wskazówek zegara"] # 0x21ba + - "↻": [T: "strzałka po otwartym okręgu zgodnie z ruchem wskazówek zegara"] # 0x21bb + - "↼": [T: "lewy harpun górny"] # 0x21bc + - "↽": [T: "lewy harpun dolny"] # 0x21bd + - "↾": [T: "górny harpun prawy"] # 0x21be + - "↿": [T: "górny harpun lewy"] # 0x21bf + - "⇀": [T: "prawy harpun górny"] # 0x21c0 + - "⇁": [T: "prawy harpun dolny"] # 0x21c1 + - "⇂": [T: "dolny harpun prawy"] # 0x21c2 + - "⇃": [T: "dolny harpun lewy"] # 0x21c3 + - "⇄": [T: "strzałka w prawo nad strzałką w lewo"] # 0x21c4 + - "⇅": [T: "strzałka w górę po lewej i strzałka w dół"] # 0x21c5 + - "⇆": [T: "strzałka w lewo nad strzałką w prawo"] # 0x21c6 + - "⇇": [T: "podwójne strzałki w lewo"] # 0x21c7 + - "⇈": [T: "podwójne strzałki w górę"] # 0x21c8 + - "⇉": [T: "podwójne strzałki w prawo"] # 0x21c9 + - "⇊": [T: "podwójne strzałki w dół"] # 0x21ca + - "⇋": [T: "lewy harpun przez prawy harpun"] # 0x21cb + - "⇌": [T: "prawy harpun przez lewy harpun"] # 0x21cc - "⇍": [T: "nie wynika z"] # 0x21cd - "⇎": [T: "nie jest równoważne"] # 0x21ce - "⇏": [T: "nie implikuje"] # 0x21cf - "⇐": [T: "wynika z"] # 0x21d0 - - "⇑": [t: "podwójna strzałka w górę"] # 0x21d1 - - "⇒": [t: "implikuje"] # 0x21d2 - - "⇓": [t: "podwójna strzałka w dół"] # 0x21d3 - - "⇔": [t: "wtedy i tylko wtedy"] # 0x21d4 - - "⇕": [t: "podwójna strzałka w górę i w dół"] # 0x21d5 - - "⇖": [t: "podwójna strzałka na północny zachód"] # 0x21d6 - - "⇗": [t: "podwójna strzałka na północny wschód"] # 0x21d7 - - "⇘": [t: "podwójna strzałka na południowy wschód"] # 0x21d8 - - "⇙": [t: "podwójna strzałka na południowy zachód"] # 0x21d9 - - "⇚": [t: "lewy potrójny strzałka"] # 0x21da - - "⇛": [t: "prawy potrójny strzałka"] # 0x21db - - "⇜": [t: "falista strzałka w lewo"] # 0x21dc - - "⇝": [t: "falista strzałka w prawo"] # 0x21dd - - "⇞": [t: "strzałka w górę z podwójną kreską"] # 0x21de - - "⇟": [t: "strzałka w dół z podwójną kreską"] # 0x21df - - "⇠": [t: "przerywana strzałka w lewo"] # 0x21e0 - - "⇡": [t: "przerywana strzałka w górę"] # 0x21e1 - - "⇢": [t: "przerywana strzałka w prawo"] # 0x21e2 - - "⇣": [t: "przerywana strzałka w dół"] # 0x21e3 - - "⇤": [t: "strzałka w lewo do kreski"] # 0x21e4 - - "⇥": [t: "strzałka w prawo do kreski"] # 0x21e5 - - "⇦": [t: "biała strzałka w lewo"] # 0x21e6 - - "⇧": [t: "biała strzałka w górę"] # 0x21e7 - - "⇨": [t: "biała strzałka w prawo"] # 0x21e8 - - "⇩": [t: "biała strzałka w dół"] # 0x21e9 - - "⇪": [t: "biała strzałka w górę od kreski"] # 0x21ea - - "⇫": [t: "górna biała strzałka na podstawie"] # 0x21eb - - "⇬": [t: "górna biała strzałka na podstawie z kreską poziomą"] # 0x21ec - - "⇭": [t: "górna biała strzałka na podstawie z kreską pionową"] # 0x21ed - - "⇮": [t: "górny biały podwójna strzałka"] # 0x21ee - - "⇯": [t: "górna biała podwójna strzałka na podstawie"] # 0x21ef - - "⇰": [t: "biała strzałka w prawo od ściany"] # 0x21f0 - - "⇱": [t: "strzałka północno-zachodnia do narożnika"] # 0x21f1 - - "⇲": [t: "strzałka południowo-wschodnia do narożnika"] # 0x21f2 - - "⇳": [t: "biała strzałka w górę i w dół"] # 0x21f3 - - "⇴": [t: "strzałka w prawo z małym okręgiem"] # 0x21f4 - - "⇵": [t: "strzałka w dół po lewej od strzałki w górę"] # 0x21f5 - - "⇶": [t: "trzy strzałki w prawo"] # 0x21f6 - - "⇷": [t: "strzałka w lewo z pionową kreską"] # 0x21f7 - - "⇸": [t: "strzałka w prawo z pionową kreską"] # 0x21f8 - - "⇹": [t: "strzałki w lewo i w prawo z pionową kreską"] # 0x21f9 - - "⇺": [t: "strzałka w lewo z podwójną pionową kreską"] # 0x21fa - - "⇻": [t: "strzałka w prawo z podwójną pionową kreską"] # 0x21fb - - "⇼": [t: "strzałki w lewo i w prawo z podwójną pionową kreską"] # 0x21fc - - "⇽": [t: "strzałka w lewo z otwartym grotem"] # 0x21fd - - "⇾": [t: "strzałka w prawo z otwartym grotem"] # 0x21fe - - "⇿": [t: "strzałka w lewo i w prawo z otwartymi grotami"] # 0x21ff - - "∀": [t: "dla każdego"] # 0x2200 + - "⇑": [T: "podwójna strzałka w górę"] # 0x21d1 + - "⇒": [T: "implikuje"] # 0x21d2 + - "⇓": [T: "podwójna strzałka w dół"] # 0x21d3 + - "⇔": [T: "wtedy i tylko wtedy"] # 0x21d4 + - "⇕": [T: "podwójna strzałka w górę i w dół"] # 0x21d5 + - "⇖": [T: "podwójna strzałka na północny zachód"] # 0x21d6 + - "⇗": [T: "podwójna strzałka na północny wschód"] # 0x21d7 + - "⇘": [T: "podwójna strzałka na południowy wschód"] # 0x21d8 + - "⇙": [T: "podwójna strzałka na południowy zachód"] # 0x21d9 + - "⇚": [T: "lewy potrójny strzałka"] # 0x21da + - "⇛": [T: "prawy potrójny strzałka"] # 0x21db + - "⇜": [T: "falista strzałka w lewo"] # 0x21dc + - "⇝": [T: "falista strzałka w prawo"] # 0x21dd + - "⇞": [T: "strzałka w górę z podwójną kreską"] # 0x21de + - "⇟": [T: "strzałka w dół z podwójną kreską"] # 0x21df + - "⇠": [T: "przerywana strzałka w lewo"] # 0x21e0 + - "⇡": [T: "przerywana strzałka w górę"] # 0x21e1 + - "⇢": [T: "przerywana strzałka w prawo"] # 0x21e2 + - "⇣": [T: "przerywana strzałka w dół"] # 0x21e3 + - "⇤": [T: "strzałka w lewo do kreski"] # 0x21e4 + - "⇥": [T: "strzałka w prawo do kreski"] # 0x21e5 + - "⇦": [T: "biała strzałka w lewo"] # 0x21e6 + - "⇧": [T: "biała strzałka w górę"] # 0x21e7 + - "⇨": [T: "biała strzałka w prawo"] # 0x21e8 + - "⇩": [T: "biała strzałka w dół"] # 0x21e9 + - "⇪": [T: "biała strzałka w górę od kreski"] # 0x21ea + - "⇫": [T: "górna biała strzałka na podstawie"] # 0x21eb + - "⇬": [T: "górna biała strzałka na podstawie z kreską poziomą"] # 0x21ec + - "⇭": [T: "górna biała strzałka na podstawie z kreską pionową"] # 0x21ed + - "⇮": [T: "górny biały podwójna strzałka"] # 0x21ee + - "⇯": [T: "górna biała podwójna strzałka na podstawie"] # 0x21ef + - "⇰": [T: "biała strzałka w prawo od ściany"] # 0x21f0 + - "⇱": [T: "strzałka północno-zachodnia do narożnika"] # 0x21f1 + - "⇲": [T: "strzałka południowo-wschodnia do narożnika"] # 0x21f2 + - "⇳": [T: "biała strzałka w górę i w dół"] # 0x21f3 + - "⇴": [T: "strzałka w prawo z małym okręgiem"] # 0x21f4 + - "⇵": [T: "strzałka w dół po lewej od strzałki w górę"] # 0x21f5 + - "⇶": [T: "trzy strzałki w prawo"] # 0x21f6 + - "⇷": [T: "strzałka w lewo z pionową kreską"] # 0x21f7 + - "⇸": [T: "strzałka w prawo z pionową kreską"] # 0x21f8 + - "⇹": [T: "strzałki w lewo i w prawo z pionową kreską"] # 0x21f9 + - "⇺": [T: "strzałka w lewo z podwójną pionową kreską"] # 0x21fa + - "⇻": [T: "strzałka w prawo z podwójną pionową kreską"] # 0x21fb + - "⇼": [T: "strzałki w lewo i w prawo z podwójną pionową kreską"] # 0x21fc + - "⇽": [T: "strzałka w lewo z otwartym grotem"] # 0x21fd + - "⇾": [T: "strzałka w prawo z otwartym grotem"] # 0x21fe + - "⇿": [T: "strzałka w lewo i w prawo z otwartymi grotami"] # 0x21ff + - "∀": [T: "dla każdego"] # 0x2200 - "∁": # 0x2201 - - t: "dopełnienie" + - T: "dopełnienie" - "∂": # 0x2202 - test: if: "$Verbosity='Terse'" - then: [t: "cząstkowe"] - else: [t: "pochodna cząstkowa"] - - "∃": [t: "istnieje"] # 0x2203 - - "∄": [t: "nie istnieje"] # 0x2204 + then: [T: "cząstkowe"] + else: [T: "pochodna cząstkowa"] + - "∃": [T: "istnieje"] # 0x2203 + - "∄": [T: "nie istnieje"] # 0x2204 - "∅": [T: "zbiór pusty"] # 0x2205 - "∆": # 0x2206 - test: if: "following-sibling::*" then_test: if: "$Verbosity!='Terse'" - then: [t: "laplasjan"] # "LahPlahsian" sounds better than "laplacian" in speech engines tested - else: [t: "laplasjan"] - else: [t: "laplasjan"] + then: [T: "laplasjan"] # "LahPlahsian" sounds better than "laplacian" in speech engines tested + else: [T: "laplasjan"] + else: [T: "laplasjan"] - - "∇": [t: "nabla"] # 0x2207 + - "∇": [T: "nabla"] # 0x2207 - "∉": # 0x2209 # rule is identical to 0x2208 - test: if: "$SpeechStyle != 'ClearSpeak'" - then: [t: "nie jest elementem zbioru"] + then: [T: "nie jest elementem zbioru"] # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option else_test: if: "../../self::m:set or ../../../self::m:set" # inside a set then_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "nie należy do"] + then: [T: "nie należy do"] - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "nie jest elementem zbioru"] + then: [T: "nie jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "nie jest elementem zbioru"] - - else: [t: "nienależące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + then: [T: "nie jest elementem zbioru"] + - else: [T: "nienależące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' else_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "nie jest elementem zbioru"] + then: [T: "nie jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "nie jest elementem zbioru"] + then: [T: "nie jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "nie należy do"] - - else: [t: "nie należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + then: [T: "nie należy do"] + - else: [T: "nie należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' - "∊": # 0x220a - test: if: "$SpeechStyle != 'ClearSpeak'" @@ -724,7 +724,7 @@ - test: if: "$Verbosity!='Terse' and not(parent::m:set)" # "the set x is an element of ..." sounds bad then: [T: "jest"] - - t: "element zbioru" + - T: "element zbioru" # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option else_test: if: "../../self::m:set or ../../../self::m:set" # inside a set @@ -732,32 +732,32 @@ - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' then: [T: "do"] - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "element zbioru"] + then: [T: "element zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "należy do"] - - else: [t: "należące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + then: [T: "należy do"] + - else: [T: "należące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' else_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "jest elementem zbioru"] + then: [T: "jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "jest elementem zbioru"] + then: [T: "jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "należy do"] - - else: [t: "należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' - - "∋": [t: "zawiera element"] # 0x220b - - "∌": [t: "nie zawiera elementu"] # 0x220c - - "∍": [t: "zawiera element"] # 0x220d - - "∎": [t: "koniec dowodu"] # 0x220e + then: [T: "należy do"] + - else: [T: "należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + - "∋": [T: "zawiera element"] # 0x220b + - "∌": [T: "nie zawiera elementu"] # 0x220c + - "∍": [T: "zawiera element"] # 0x220d + - "∎": [T: "koniec dowodu"] # 0x220e - "∏": [T: "iloczyn"] # 0x220f - - "∐": [t: "koprodukt"] # 0x2210 + - "∐": [T: "koprodukt"] # 0x2210 - "∑": [T: "suma"] # 0x2211 - "−": [T: "minus"] # 0x2212 - "∓": [T: "minus plus"] # 0x2213 - - "∔": [t: "kropka plus"] # 0x2214 + - "∔": [T: "kropka plus"] # 0x2214 - "∕": [T: "podzielone przez"] # 0x2215 - - "∖": [t: "zbiór minus"] # 0x2216 + - "∖": [T: "zbiór minus"] # 0x2216 - "∗": [T: "razy"] # 0x2217 - - "∘": [t: "złożone z"] # 0x2218 + - "∘": [T: "złożone z"] # 0x2218 - "∙": # 0x2219 - test: if: "@data-chem-formula-op" @@ -765,71 +765,71 @@ else: [T: "razy"] - "√": # 0x221a - - t: "pierwiastek kwadratowy z" + - T: "pierwiastek kwadratowy z" - "∛": # 0x221b - - t: "pierwiastek sześcienny z" + - T: "pierwiastek sześcienny z" - "∜": # 0x221c - - t: "czwarty pierwiastek z" + - T: "czwarty pierwiastek z" - "∝": # 0x221d - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "proporcjonalne do" + - T: "proporcjonalne do" - "∞": - test: if: "ancestor::*[self::m:limit or self::m:limit-sup or self::m:limit-inf or self::m:large-op]" then: [T: "nieskończoności"] else: [T: "nieskończoność"] # 0x221e - - "∟": [t: "kąt prosty"] # 0x221f - - "∠": [t: "kąt"] # 0x2220 - - "∡": [t: "kąt mierzony"] # 0x2221 - - "∢": [t: "kąt sferyczny"] # 0x2222 + - "∟": [T: "kąt prosty"] # 0x221f + - "∠": [T: "kąt"] # 0x2220 + - "∡": [T: "kąt mierzony"] # 0x2221 + - "∢": [T: "kąt sferyczny"] # 0x2222 - "∣": [T: "dzieli"] # 0x2223 - - "∤": [t: "nie dzieli"] # 0x2224 + - "∤": [T: "nie dzieli"] # 0x2224 - "∧": [T: "i"] # 0x2227 - "∨": [T: "lub"] # 0x2228 - "∩": [T: "przecięcie"] # 0x2229 - "∪": [T: "suma zbiorów"] # 0x222a - "∫": [T: "całka"] # 0x222b - - "∬": [t: "całka podwójna"] # 0x222c - - "∭": [t: "całka potrójna"] # 0x222d - - "∮": [t: "całka krzywoliniowa"] # 0x222e - - "∯": [t: "całka powierzchniowa"] # 0x222f - - "∰": [t: "całka objętościowa"] # 0x2230 - - "∱": [t: "całka zgodnie z ruchem wskazówek zegara"] # 0x2231 - - "∲": [t: "całka krzywoliniowa zgodnie z ruchem wskazówek zegara"] # 0x2232 - - "∳": [t: "całka krzywoliniowa przeciwnie do ruchu wskazówek zegara"] # 0x2233 - - "∴": [t: "zatem"] # 0x2234 - - "∵": [t: "ponieważ"] # 0x2235 + - "∬": [T: "całka podwójna"] # 0x222c + - "∭": [T: "całka potrójna"] # 0x222d + - "∮": [T: "całka krzywoliniowa"] # 0x222e + - "∯": [T: "całka powierzchniowa"] # 0x222f + - "∰": [T: "całka objętościowa"] # 0x2230 + - "∱": [T: "całka zgodnie z ruchem wskazówek zegara"] # 0x2231 + - "∲": [T: "całka krzywoliniowa zgodnie z ruchem wskazówek zegara"] # 0x2232 + - "∳": [T: "całka krzywoliniowa przeciwnie do ruchu wskazówek zegara"] # 0x2233 + - "∴": [T: "zatem"] # 0x2234 + - "∵": [T: "ponieważ"] # 0x2235 - "∶": # 0x2236 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - T: "do" - - "∷": [t: "jako"] # 0x2237 - - "∸": [t: "kropka minus"] # 0x2238 - - "∹": [t: "ma nadmiar względem"] # 0x2239 + - "∷": [T: "jako"] # 0x2237 + - "∸": [T: "kropka minus"] # 0x2238 + - "∹": [T: "ma nadmiar względem"] # 0x2239 - "∺": # 0x223a - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "geometrycznie proporcjonalne do" + - T: "geometrycznie proporcjonalne do" - "∻": # 0x223b - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "homotetyczne do" - - "∼": [t: "tylda"] # 0x223c - - "∽": [t: "odwrócona tylda"] # 0x223d + - T: "homotetyczne do" + - "∼": [T: "tylda"] # 0x223c + - "∽": [T: "odwrócona tylda"] # 0x223d - "∾": # 0x223e - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "most dodatnie" - - "∿": [t: "fala sinusoidalna"] # 0x223f - - "≀": [t: "iloczyn wieńcowy"] # 0x2240 - - "≁": [t: "nie jest podobne"] # 0x2241 - - "≂": [t: "minus tylda"] # 0x2242 + - T: "most dodatnie" + - "∿": [T: "fala sinusoidalna"] # 0x223f + - "≀": [T: "iloczyn wieńcowy"] # 0x2240 + - "≁": [T: "nie jest podobne"] # 0x2241 + - "≂": [T: "minus tylda"] # 0x2242 - "≃": # 0x2243 - test: if: "$Verbosity!='Terse'" @@ -844,7 +844,7 @@ - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "przystające do" + - T: "przystające do" - "≆": # 0x2246 - test: if: "$Verbosity!='Terse'" @@ -854,7 +854,7 @@ - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "nie przystające do" + - T: "nie przystające do" - "≈": # 0x2248 - test: if: "$Verbosity!='Terse'" @@ -870,21 +870,21 @@ if: "$Verbosity!='Terse'" then: [T: "jest"] - T: "w przybliżeniu równe lub równe" - - "≋": [t: "potrójny tylda"] # 0x224b + - "≋": [T: "potrójny tylda"] # 0x224b - "≌": [T: "wszystkie równe"] # 0x224c - "≍": # 0x224d - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "Równoważne" + - T: "Równoważne" - "≎": # 0x224e - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - T: "geometrycznie równoważne" - "≏": # 0x224f - - t: "różnica między" - - "≐": [t: "dąży do granicy"] # 0x2250 + - T: "różnica między" + - "≐": [T: "dąży do granicy"] # 0x2250 - "≑": # 0x2251 - test: if: "$Verbosity!='Terse'" @@ -898,32 +898,32 @@ - "≓": # 0x2253 - test: if: "$Verbosity!='Terse'" - then: [t: "jest"] + then: [T: "jest"] - T: "obrazem lub w przybliżeniu równe" - - "≔": [t: "dwukropek równa się"] # 0x2254 - - "≕": [t: "równa się dwukropek"] # 0x2255 - - "≖": [t: "pierścień w znaku równości"] # 0x2256 + - "≔": [T: "dwukropek równa się"] # 0x2254 + - "≕": [T: "równa się dwukropek"] # 0x2255 + - "≖": [T: "pierścień w znaku równości"] # 0x2256 - "≗": # 0x2257 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - T: "w przybliżeniu równe" - - "≘": [t: "odpowiada"] # 0x2258 - - "≙": [t: "estymuje"] # 0x2259 + - "≘": [T: "odpowiada"] # 0x2258 + - "≙": [T: "estymuje"] # 0x2259 - "≚": # 0x225a - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "równokątne do" - - "≛": [t: "gwiazda równa się"] # 0x225b - - "≜": [t: "delta równa się"] # 0x225c - - "≝": [t: "jest z definicji równe"] # 0x225d + - T: "równokątne do" + - "≛": [T: "gwiazda równa się"] # 0x225b + - "≜": [T: "delta równa się"] # 0x225c + - "≝": [T: "jest z definicji równe"] # 0x225d - "≞": # 0x225e - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "mierzone na" - - "≟": [t: "ma nieznaną relację z"] # 0x225f + - T: "mierzone na" + - "≟": [T: "ma nieznaną relację z"] # 0x225f - "≠": # 0x2260 - test: if: "$Verbosity!='Terse'" @@ -933,209 +933,209 @@ - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "identyczne z" + - T: "identyczne z" - "≢": # 0x2262 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "nie identyczne z" + - T: "nie identyczne z" - "≣": # 0x2263 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "ściśle równoważne" - - "≦": [t: "mniejsze nad równe"] # 0x2266 - - "≧": [t: "większe nad równe"] # 0x2267 + - T: "ściśle równoważne" + - "≦": [T: "mniejsze nad równe"] # 0x2266 + - "≧": [T: "większe nad równe"] # 0x2267 - "≨": # 0x2268 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "mniejsze niż ale nie równa się" + - T: "mniejsze niż ale nie równa się" - "≩": # 0x2269 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "większe niż ale nie równa się" + - T: "większe niż ale nie równa się" - "≪": # 0x226a - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "znacznie mniejsze niż" + - T: "znacznie mniejsze niż" - "≫": # 0x226b - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "znacznie większe niż" + - T: "znacznie większe niż" - "≬": # 0x226c - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "między" + - T: "między" - "≭": # 0x226d - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "nie równoważne" + - T: "nie równoważne" - "≮": # 0x226e - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "nie mniejsze niż" + - T: "nie mniejsze niż" - "≯": # 0x226f - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "nie większe niż" + - T: "nie większe niż" - "≰": # 0x2270 - - t: "nie jest mniejsze ani równe" + - T: "nie jest mniejsze ani równe" - "≱": # 0x2271 - - t: "nie jest większe ani równe" + - T: "nie jest większe ani równe" - "≲": # 0x2272 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "mniejsze niż lub równoważne" + - T: "mniejsze niż lub równoważne" - "≳": # 0x2273 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "większe niż lub równoważne" + - T: "większe niż lub równoważne" - "≴": # 0x2274 - - t: "nie jest mniejsze ani równoważne" + - T: "nie jest mniejsze ani równoważne" - "≵": # 0x2275 - - t: "nie jest większe ani równoważne" + - T: "nie jest większe ani równoważne" - "≶": # 0x2276 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "mniejsze lub większe niż" + - T: "mniejsze lub większe niż" - "≷": # 0x2277 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "większe lub mniejsze niż" + - T: "większe lub mniejsze niż" - "≸": # 0x2278 - - t: "nie jest mniejsze ani większe niż" + - T: "nie jest mniejsze ani większe niż" - "≹": # 0x2279 - - t: "nie jest większe ani mniejsze niż" - - "≺": [t: "poprzedza"] # 0x227a - - "≻": [t: "następuje po"] # 0x227b + - T: "nie jest większe ani mniejsze niż" + - "≺": [T: "poprzedza"] # 0x227a + - "≻": [T: "następuje po"] # 0x227b - "≼": [T: "poprzedza lub jest równe"] # 0x227c - "≽": [T: "następuje po lub jest równe"] # 0x227d - - "≾": [t: "poprzedza lub jest równoważne"] # 0x227e - - "≿": [t: "następuje po lub jest równoważne"] # 0x227f + - "≾": [T: "poprzedza lub jest równoważne"] # 0x227e + - "≿": [T: "następuje po lub jest równoważne"] # 0x227f - "⊀": [T: "nie poprzedza"] # 0x2280 - "⊁": [T: "nie następuje po"] # 0x2281 - "⊂": # 0x2282 - test: if: "$Verbosity!='Terse'" - then: [t: "jest"] - - t: "podzbiór" + then: [T: "jest"] + - T: "podzbiór" - "⊃": # 0x2283 - test: if: "$Verbosity!='Terse'" - then: [t: "jest"] - - t: "nadzbiór" + then: [T: "jest"] + - T: "nadzbiór" - "⊄": # 0x2284 - - t: "nie jest podzbiorem" + - T: "nie jest podzbiorem" - "⊅": # 0x2285 - - t: "nie jest nadzbiorem" + - T: "nie jest nadzbiorem" - "⊆": # 0x2286 - test: if: "$Verbosity!='Terse'" - then: [t: "jest"] - - t: "podzbiór lub równy" + then: [T: "jest"] + - T: "podzbiór lub równy" - "⊇": # 0x2287 - test: if: "$Verbosity!='Terse'" - then: [t: "jest"] - - t: "nadzbiór lub równy" + then: [T: "jest"] + - T: "nadzbiór lub równy" - "⊈": # 0x2288 - - t: "nie jest podzbiorem ani nie jest równe" + - T: "nie jest podzbiorem ani nie jest równe" - "⊉": # 0x2289 - - t: "nie jest nadzbiorem ani nie jest równe" - - "⊊": [t: "podzbiór z nie równa się"] # 0x228a - - "⊋": [t: "nadzbiór z nie równa się"] # 0x228b - - "⊌": [t: "wielozbiór"] # 0x228c - - "⊍": [t: "mnożenie wielozbiorów"] # 0x228d - - "⊎": [t: "suma wielozbiorów"] # 0x228e + - T: "nie jest nadzbiorem ani nie jest równe" + - "⊊": [T: "podzbiór z nie równa się"] # 0x228a + - "⊋": [T: "nadzbiór z nie równa się"] # 0x228b + - "⊌": [T: "wielozbiór"] # 0x228c + - "⊍": [T: "mnożenie wielozbiorów"] # 0x228d + - "⊎": [T: "suma wielozbiorów"] # 0x228e - "⊏": [T: "kwadratowo poprzedza"] # 0x228f - "⊐": [T: "kwadratowo następuje po"] # 0x2290 - "⊑": [T: "kwadratowo poprzedza lub jest równe"] # 0x2291 - "⊒": [T: "kwadratowo następuje po lub jest równe"] # 0x2292 - - "⊓": [t: "kwadratowa część wspólna"] # 0x2293 - - "⊔": [t: "kwadratowa suma zbiorów"] # 0x2294 - - "⊕": [t: "w kółku plus"] # 0x2295 - - "⊖": [t: "w kółku minus"] # 0x2296 - - "⊗": [t: "w kółku razy"] # 0x2297 - - "⊘": [t: "w kółku ukośnik"] # 0x2298 - - "⊙": [t: "kropka w kółku"] # 0x2299 - - "⊚": [t: "pierścień w kółku"] # 0x229a - - "⊛": [t: "gwiazdka w kółku"] # 0x229b - - "⊜": [t: "równa się w kółku"] # 0x229c - - "⊝": [t: "kreska w kółku"] # 0x229d - - "⊞": [t: "plus w kwadracie"] # 0x229e - - "⊟": [t: "minus w kwadracie"] # 0x229f - - "⊠": [t: "razy w kwadracie"] # 0x22a0 - - "⊡": [t: "kropka w kwadracie"] # 0x22a1 - - "⊢": [t: "dowodzi"] # 0x22a2 - - "⊣": [t: "jest dowodzone przez"] # 0x22a3 - - "⊤": [t: "góra"] # 0x22a4 - - "⊦": [t: "redukuje się do"] # 0x22a6 - - "⊧": [t: "modeluje"] # 0x22a7 + - "⊓": [T: "kwadratowa część wspólna"] # 0x2293 + - "⊔": [T: "kwadratowa suma zbiorów"] # 0x2294 + - "⊕": [T: "w kółku plus"] # 0x2295 + - "⊖": [T: "w kółku minus"] # 0x2296 + - "⊗": [T: "w kółku razy"] # 0x2297 + - "⊘": [T: "w kółku ukośnik"] # 0x2298 + - "⊙": [T: "kropka w kółku"] # 0x2299 + - "⊚": [T: "pierścień w kółku"] # 0x229a + - "⊛": [T: "gwiazdka w kółku"] # 0x229b + - "⊜": [T: "równa się w kółku"] # 0x229c + - "⊝": [T: "kreska w kółku"] # 0x229d + - "⊞": [T: "plus w kwadracie"] # 0x229e + - "⊟": [T: "minus w kwadracie"] # 0x229f + - "⊠": [T: "razy w kwadracie"] # 0x22a0 + - "⊡": [T: "kropka w kwadracie"] # 0x22a1 + - "⊢": [T: "dowodzi"] # 0x22a2 + - "⊣": [T: "jest dowodzone przez"] # 0x22a3 + - "⊤": [T: "góra"] # 0x22a4 + - "⊦": [T: "redukuje się do"] # 0x22a6 + - "⊧": [T: "modeluje"] # 0x22a7 - "⊨": # 0x22a8 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "prawdziwe" - - "⊩": [t: "wymusza"] # 0x22a9 - - "⊪": [t: "potrójna pionowa kreska z prawym znacznikiem dedukcji"] # 0x22aa - - "⊫": [t: "podwójna pionowa kreska z podwójnym prawym znacznikiem dedukcji"] # 0x22ab - - "⊬": [t: "nie dowodzi"] # 0x22ac + - T: "prawdziwe" + - "⊩": [T: "wymusza"] # 0x22a9 + - "⊪": [T: "potrójna pionowa kreska z prawym znacznikiem dedukcji"] # 0x22aa + - "⊫": [T: "podwójna pionowa kreska z podwójnym prawym znacznikiem dedukcji"] # 0x22ab + - "⊬": [T: "nie dowodzi"] # 0x22ac - "⊭": # 0x22ad - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "nie jest prawdziwe" - - "⊮": [t: "nie wymusza"] # 0x22ae - - "⊯": [t: "zanegowana podwójna pionowa kreska z podwójnym prawym znacznikiem dedukcji"] # 0x22af - - "⊰": [t: "poprzedza pod relacją"] # 0x22b0 - - "⊱": [t: "następuje po pod relacją"] # 0x22b1 + - T: "nie jest prawdziwe" + - "⊮": [T: "nie wymusza"] # 0x22ae + - "⊯": [T: "zanegowana podwójna pionowa kreska z podwójnym prawym znacznikiem dedukcji"] # 0x22af + - "⊰": [T: "poprzedza pod relacją"] # 0x22b0 + - "⊱": [T: "następuje po pod relacją"] # 0x22b1 - "⊲": # 0x22b2 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "normalną podgrupą" - - "⊳": [t: "zawiera jako normalną podgrupę"] # 0x22b3 + - T: "normalną podgrupą" + - "⊳": [T: "zawiera jako normalną podgrupę"] # 0x22b3 - "⊴": # 0x22b4 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "normalną podgrupą lub równe" - - "⊵": [t: "zawiera jako normalną podgrupę lub jest równe"] # 0x22b5 + - T: "normalną podgrupą lub równe" + - "⊵": [T: "zawiera jako normalną podgrupę lub jest równe"] # 0x22b5 - "⊶": # 0x22b6 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "oryginałem" + - T: "oryginałem" - "⊷": # 0x22b7 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "obrazem" - - "⊸": [t: "multimapa"] # 0x22b8 - - "⊹": [t: "macierz sprzężona hermitowsko"] # 0x22b9 - - "⊺": [t: "interkalacja"] # 0x22ba - - "⊻": [t: "alternatywa wykluczająca"] # 0x22bb - - "⊼": [t: "negacja koniunkcji"] # 0x22bc - - "⊽": [t: "negacja alternatywy"] # 0x22bd - - "⊾": [t: "kąt prosty z łukiem"] # 0x22be - - "⊿": [t: "prawy trójkąt"] # 0x22bf - - "⋀": [t: "logiczne I"] # 0x22c0 - - "⋁": [t: "logiczne lub"] # 0x22c1 + - T: "obrazem" + - "⊸": [T: "multimapa"] # 0x22b8 + - "⊹": [T: "macierz sprzężona hermitowsko"] # 0x22b9 + - "⊺": [T: "interkalacja"] # 0x22ba + - "⊻": [T: "alternatywa wykluczająca"] # 0x22bb + - "⊼": [T: "negacja koniunkcji"] # 0x22bc + - "⊽": [T: "negacja alternatywy"] # 0x22bd + - "⊾": [T: "kąt prosty z łukiem"] # 0x22be + - "⊿": [T: "prawy trójkąt"] # 0x22bf + - "⋀": [T: "logiczne I"] # 0x22c0 + - "⋁": [T: "logiczne lub"] # 0x22c1 - "⋂": [T: "przecięcie"] # 0x22c2 - "⋃": [T: "suma zbiorów"] # 0x22c3 - - "⋄": [t: "operator rombu"] # 0x22c4 + - "⋄": [T: "operator rombu"] # 0x22c4 - "⋅": # 0x22c5 - test: if: "@data-chem-formula-op" @@ -1143,520 +1143,520 @@ else: [T: "razy"] - "⋆": [T: "razy"] # 0x22c6 - - "⋇": [t: "znak dzielenia razy"] # 0x22c7 - - "⋈": [t: "muszka"] # 0x22c8 + - "⋇": [T: "znak dzielenia razy"] # 0x22c7 + - "⋈": [T: "muszka"] # 0x22c8 - "⋉": # 0x22c9 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "lewym iloczynem półprostym z czynnikiem normalnym" + - T: "lewym iloczynem półprostym z czynnikiem normalnym" - "⋊": # 0x22ca - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "prawym iloczynem półprostym z czynnikiem normalnym" + - T: "prawym iloczynem półprostym z czynnikiem normalnym" - "⋋": # 0x22cb - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "lewym iloczynem półprostym" + - T: "lewym iloczynem półprostym" - "⋌": # 0x22cc - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "prawym iloczynem półprostym" - - "⋍": [t: "odwrócona tylda równa się"] # 0x22cd - - "⋎": [t: "zakręcone logiczne lub"] # 0x22ce - - "⋏": [t: "zakręcone logiczne i"] # 0x22cf + - T: "prawym iloczynem półprostym" + - "⋍": [T: "odwrócona tylda równa się"] # 0x22cd + - "⋎": [T: "zakręcone logiczne lub"] # 0x22ce + - "⋏": [T: "zakręcone logiczne i"] # 0x22cf - "⋐": # 0x22d0 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "podwójnym podzbiorem" + - T: "podwójnym podzbiorem" - "⋑": # 0x22d1 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "podwójnym nadzbiorem" + - T: "podwójnym nadzbiorem" - "⋒": # 0x22d2 - - t: "podwójna część wspólna" + - T: "podwójna część wspólna" - "⋓": # 0x22d3 - - t: "podwójna suma zbiorów" + - T: "podwójna suma zbiorów" - "⋔": # 0x22d4 - - t: "właściwa część wspólna" + - T: "właściwa część wspólna" - "⋕": # 0x22d5 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "równe i równoległe do" - - "⋖": [t: "mniejsze niż z kropką"] # 0x22d6 - - "⋗": [t: "większe niż z kropką"] # 0x22d7 + - T: "równe i równoległe do" + - "⋖": [T: "mniejsze niż z kropką"] # 0x22d6 + - "⋗": [T: "większe niż z kropką"] # 0x22d7 - "⋘": # 0x22d8 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "bardzo znacznie mniejsze niż" + - T: "bardzo znacznie mniejsze niż" - "⋙": # 0x22d9 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "bardzo znacznie większe niż" + - T: "bardzo znacznie większe niż" - "⋚": # 0x22da - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "mniejsze niż, równe lub większe niż" + - T: "mniejsze niż, równe lub większe niż" - "⋛": # 0x22db - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "większe niż, równe lub mniejsze niż" + - T: "większe niż, równe lub mniejsze niż" - "⋜": # 0x22dc - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "równe lub mniejsze niż" + - T: "równe lub mniejsze niż" - "⋝": # 0x22dd - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "równe lub większe niż" + - T: "równe lub większe niż" - "⋞": # 0x22de - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "równe lub poprzedza" + - T: "równe lub poprzedza" - "⋟": # 0x22df - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "równe lub następuje po" - - "⋠": [t: "nie poprzedza ani nie jest równe"] # 0x22e0 - - "⋡": [t: "nie następuje po ani nie jest równe"] # 0x22e1 - - "⋢": [t: "nie poprzedza kwadratowo ani nie jest równe"] # 0x22e2 - - "⋣": [t: "nie następuje kwadratowo po ani nie jest równe"] # 0x22e3 - - "⋤": [t: "poprzedza kwadratowo, ale nie jest równe"] # 0x22e4 - - "⋥": [t: "następuje kwadratowo po, ale nie jest równe"] # 0x22e5 + - T: "równe lub następuje po" + - "⋠": [T: "nie poprzedza ani nie jest równe"] # 0x22e0 + - "⋡": [T: "nie następuje po ani nie jest równe"] # 0x22e1 + - "⋢": [T: "nie poprzedza kwadratowo ani nie jest równe"] # 0x22e2 + - "⋣": [T: "nie następuje kwadratowo po ani nie jest równe"] # 0x22e3 + - "⋤": [T: "poprzedza kwadratowo, ale nie jest równe"] # 0x22e4 + - "⋥": [T: "następuje kwadratowo po, ale nie jest równe"] # 0x22e5 - "⋦": # 0x22e6 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "mniejsze niż, ale nie równoważne" + - T: "mniejsze niż, ale nie równoważne" - "⋧": # 0x22e7 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "większe niż, ale nie równoważne" - - "⋨": [t: "poprzedza, ale nie jest równoważne"] # 0x22e8 - - "⋩": [t: "następuje po, ale nie jest równoważne"] # 0x22e9 + - T: "większe niż, ale nie równoważne" + - "⋨": [T: "poprzedza, ale nie jest równoważne"] # 0x22e8 + - "⋩": [T: "następuje po, ale nie jest równoważne"] # 0x22e9 - "⋪": # 0x22ea - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "nie jest normalną podgrupą" - - "⋫": [t: "nie zawiera jako normalnej podgrupy"] # 0x22eb + - T: "nie jest normalną podgrupą" + - "⋫": [T: "nie zawiera jako normalnej podgrupy"] # 0x22eb - "⋬": # 0x22ec - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "nie jest normalną podgrupą ani równe" - - "⋭": [t: "nie zawiera jako normalnej podgrupy ani równe"] # 0x22ed - - "⋮": [t: "pionowy wielokropek"] # 0x22ee - - "⋯": [t: "trzy kropki"] # 0x22ef - - "⋰": [t: "ukośny wielokropek w górę"] # 0x22f0 - - "⋱": [t: "ukośny wielokropek w dół"] # 0x22f1 - - "⋲": [t: "należy do z długą poziomą kreską"] # 0x22f2 - - "⋳": [t: "należy do z pionową kreską na końcu i poziomą kreską"] # 0x22f3 - - "⋴": [t: "należy do z pionową kreską na końcu i poziomą kreską"] # 0x22f4 - - "⋵": [t: "należy do z kropką nad"] # 0x22f5 - - "⋶": [t: "należy do z kreską nad"] # 0x22f6 - - "⋷": [t: "należy do z kreską nad"] # 0x22f7 - - "⋸": [t: "należy do z podkreśleniem"] # 0x22f8 - - "⋹": [t: "należy do z dwiema poziomymi kreskami"] # 0x22f9 - - "⋺": [t: "zawiera z długą poziomą kreską"] # 0x22fa - - "⋻": [t: "zawiera z pionową kreską na końcu i poziomą kreską"] # 0x22fb - - "⋼": [t: "zawiera z pionową kreską na końcu i poziomą kreską"] # 0x22fc - - "⋽": [t: "zawiera z kreską nad"] # 0x22fd - - "⋾": [t: "zawiera z kreską nad"] # 0x22fe - - "⋿": [t: "przynależność do wielozbioru w notacji Z"] # 0x22ff - - "⌀": [t: "znak średnicy"] # 0x2300 - - "⌁": [t: "strzałka elektryczna"] # 0x2301 - - "⌂": [t: "dom"] # 0x2302 - - "⌃": [t: "górny grot strzałki"] # 0x2303 - - "⌄": [t: "dolny grot strzałki"] # 0x2304 - - "⌅": [t: "rzutowy"] # 0x2305 - - "⌆": [t: "perspektywiczny"] # 0x2306 - - "⌇": [t: "linia falista"] # 0x2307 - - "⌈": [t: "lewy sufit"] # 0x2308 - - "⌉": [t: "prawy sufit"] # 0x2309 - - "⌊": [t: "lewa podłoga"] # 0x230a - - "⌋": [t: "prawa podłoga"] # 0x230b - - "⌌": [t: "dolny prawy znacznik kadrowania"] # 0x230c - - "⌍": [t: "dolny lewy znacznik kadrowania"] # 0x230d - - "⌎": [t: "górny prawy znacznik kadrowania"] # 0x230e - - "⌏": [t: "górny lewy znacznik kadrowania"] # 0x230f - - "⌐": [t: "odwrócony nie znak"] # 0x2310 - - "⌑": [t: "kwadrat romb"] # 0x2311 + - T: "nie jest normalną podgrupą ani równe" + - "⋭": [T: "nie zawiera jako normalnej podgrupy ani równe"] # 0x22ed + - "⋮": [T: "pionowy wielokropek"] # 0x22ee + - "⋯": [T: "trzy kropki"] # 0x22ef + - "⋰": [T: "ukośny wielokropek w górę"] # 0x22f0 + - "⋱": [T: "ukośny wielokropek w dół"] # 0x22f1 + - "⋲": [T: "należy do z długą poziomą kreską"] # 0x22f2 + - "⋳": [T: "należy do z pionową kreską na końcu i poziomą kreską"] # 0x22f3 + - "⋴": [T: "należy do z pionową kreską na końcu i poziomą kreską"] # 0x22f4 + - "⋵": [T: "należy do z kropką nad"] # 0x22f5 + - "⋶": [T: "należy do z kreską nad"] # 0x22f6 + - "⋷": [T: "należy do z kreską nad"] # 0x22f7 + - "⋸": [T: "należy do z podkreśleniem"] # 0x22f8 + - "⋹": [T: "należy do z dwiema poziomymi kreskami"] # 0x22f9 + - "⋺": [T: "zawiera z długą poziomą kreską"] # 0x22fa + - "⋻": [T: "zawiera z pionową kreską na końcu i poziomą kreską"] # 0x22fb + - "⋼": [T: "zawiera z pionową kreską na końcu i poziomą kreską"] # 0x22fc + - "⋽": [T: "zawiera z kreską nad"] # 0x22fd + - "⋾": [T: "zawiera z kreską nad"] # 0x22fe + - "⋿": [T: "przynależność do wielozbioru w notacji Z"] # 0x22ff + - "⌀": [T: "znak średnicy"] # 0x2300 + - "⌁": [T: "strzałka elektryczna"] # 0x2301 + - "⌂": [T: "dom"] # 0x2302 + - "⌃": [T: "górny grot strzałki"] # 0x2303 + - "⌄": [T: "dolny grot strzałki"] # 0x2304 + - "⌅": [T: "rzutowy"] # 0x2305 + - "⌆": [T: "perspektywiczny"] # 0x2306 + - "⌇": [T: "linia falista"] # 0x2307 + - "⌈": [T: "lewy sufit"] # 0x2308 + - "⌉": [T: "prawy sufit"] # 0x2309 + - "⌊": [T: "lewa podłoga"] # 0x230a + - "⌋": [T: "prawa podłoga"] # 0x230b + - "⌌": [T: "dolny prawy znacznik kadrowania"] # 0x230c + - "⌍": [T: "dolny lewy znacznik kadrowania"] # 0x230d + - "⌎": [T: "górny prawy znacznik kadrowania"] # 0x230e + - "⌏": [T: "górny lewy znacznik kadrowania"] # 0x230f + - "⌐": [T: "odwrócony nie znak"] # 0x2310 + - "⌑": [T: "kwadrat romb"] # 0x2311 - "⌒": [T: "łuk"] # 0x2312 - - "⌓": [t: "odcinek"] # 0x2313 - - "⌔": [t: "sektor"] # 0x2314 - - "⌕": [t: "rejestrator telefoniczny"] # 0x2315 - - "⌖": [t: "celownik wskaźnika pozycji"] # 0x2316 - - "⌗": [t: "kwadrat danych ekranowych"] # 0x2317 - - "⌘": [t: "znak miejsca zainteresowania"] # 0x2318 - - "⌙": [t: "odwrócony nie znak"] # 0x2319 - - "⌚": [t: "zegarek"] # 0x231a - - "⌛": [t: "klepsydra"] # 0x231b - - "⌜": [t: "górny lewy narożnik"] # 0x231c - - "⌝": [t: "górny prawy narożnik"] # 0x231d - - "⌞": [t: "dolny lewy narożnik"] # 0x231e - - "⌟": [t: "dolny prawy narożnik"] # 0x231f - - "⌠": [t: "górna połowa całki"] # 0x2320 - - "⌡": [t: "dolna połowa całki"] # 0x2321 - - "⌢": [t: "łuk w dół"] # 0x2322 - - "⌣": [t: "łuk w górę"] # 0x2323 - - "⌤": [t: "górny grot strzałki między dwiema poziomymi kreskami"] # 0x2324 - - "⌥": [t: "klawisz opcji"] # 0x2325 - - "⌦": [t: "wymaż w prawo"] # 0x2326 - - "⌧": [t: "X w prostokątnej ramce"] # 0x2327 - - "⌨": [t: "klawiatura"] # 0x2328 - - "〈": [t: "kąt skierowany w lewo nawias kwadratowy"] # 0x2329 - - "〉": [t: "kąt skierowany w prawo nawias kwadratowy"] # 0x232a - - "⌫": [t: "wymaż w lewo"] # 0x232b - - "⌬": [t: "pierścień benzenowy"] # 0x232c - - "⌭": [t: "walcowość"] # 0x232d - - "⌮": [t: "profil dookoła"] # 0x232e - - "⌯": [t: "symetria"] # 0x232f - - "⌰": [t: "bicie całkowite"] # 0x2330 - - "⌱": [t: "początek wymiarowania"] # 0x2331 - - "⌲": [t: "stożkowatość"] # 0x2332 - - "⌳": [t: "nachylenie"] # 0x2333 - - "⌴": [t: "pogłębienie walcowe"] # 0x2334 - - "⌵": [t: "pogłębienie stożkowe"] # 0x2335 - - "⌶": [t: "belka i APL"] # 0x2336 - - "⌽": [t: "okrąg z kreską pionową APL"] # 0x233d - - "⌿": [t: "apl ukośnik kreska"] # 0x233f - - "⍰": [t: "nieznana ramka"] # 0x2370 - - "⍼": [t: "kąt prosty z dolną strzałką zygzakowatą"] # 0x237c - - "⎔": [t: "sześciokąt"] # 0x2394 - - "⎕": [t: "ramka"] # 0x2395 - - "⎶": [t: "dolny nawias kwadratowy nad górnym nawiasem kwadratowym"] # 0x23b6 - - "⏜": [t: "górny nawias"] # 0x23dc - - "⏝": [t: "dolny nawias"] # 0x23dd - - "⏞": [t: "górny nawias klamrowy"] # 0x23de - - "⏟": [t: "dolny nawias klamrowy"] # 0x23df - - "⏠": [t: "górny nawias skorupowy"] # 0x23e0 - - "⏡": [t: "dolny nawias skorupowy"] # 0x23e1 - - "⏢": [t: "biały trapez"] # 0x23e2 - - "⏣": [t: "benzenowy pierścień z okręgiem po prawej"] # 0x23e3 - - "⏤": [t: "prostoliniowość"] # 0x23e4 - - "⏥": [t: "płaskość"] # 0x23e5 - - "⏦": [t: "prąd przemienny"] # 0x23e6 - - "⏧": [t: "symbol elektrycznego przecięcia"] # 0x23e7 + - "⌓": [T: "odcinek"] # 0x2313 + - "⌔": [T: "sektor"] # 0x2314 + - "⌕": [T: "rejestrator telefoniczny"] # 0x2315 + - "⌖": [T: "celownik wskaźnika pozycji"] # 0x2316 + - "⌗": [T: "kwadrat danych ekranowych"] # 0x2317 + - "⌘": [T: "znak miejsca zainteresowania"] # 0x2318 + - "⌙": [T: "odwrócony nie znak"] # 0x2319 + - "⌚": [T: "zegarek"] # 0x231a + - "⌛": [T: "klepsydra"] # 0x231b + - "⌜": [T: "górny lewy narożnik"] # 0x231c + - "⌝": [T: "górny prawy narożnik"] # 0x231d + - "⌞": [T: "dolny lewy narożnik"] # 0x231e + - "⌟": [T: "dolny prawy narożnik"] # 0x231f + - "⌠": [T: "górna połowa całki"] # 0x2320 + - "⌡": [T: "dolna połowa całki"] # 0x2321 + - "⌢": [T: "łuk w dół"] # 0x2322 + - "⌣": [T: "łuk w górę"] # 0x2323 + - "⌤": [T: "górny grot strzałki między dwiema poziomymi kreskami"] # 0x2324 + - "⌥": [T: "klawisz opcji"] # 0x2325 + - "⌦": [T: "wymaż w prawo"] # 0x2326 + - "⌧": [T: "X w prostokątnej ramce"] # 0x2327 + - "⌨": [T: "klawiatura"] # 0x2328 + - "〈": [T: "kąt skierowany w lewo nawias kwadratowy"] # 0x2329 + - "〉": [T: "kąt skierowany w prawo nawias kwadratowy"] # 0x232a + - "⌫": [T: "wymaż w lewo"] # 0x232b + - "⌬": [T: "pierścień benzenowy"] # 0x232c + - "⌭": [T: "walcowość"] # 0x232d + - "⌮": [T: "profil dookoła"] # 0x232e + - "⌯": [T: "symetria"] # 0x232f + - "⌰": [T: "bicie całkowite"] # 0x2330 + - "⌱": [T: "początek wymiarowania"] # 0x2331 + - "⌲": [T: "stożkowatość"] # 0x2332 + - "⌳": [T: "nachylenie"] # 0x2333 + - "⌴": [T: "pogłębienie walcowe"] # 0x2334 + - "⌵": [T: "pogłębienie stożkowe"] # 0x2335 + - "⌶": [T: "belka i APL"] # 0x2336 + - "⌽": [T: "okrąg z kreską pionową APL"] # 0x233d + - "⌿": [T: "apl ukośnik kreska"] # 0x233f + - "⍰": [T: "nieznana ramka"] # 0x2370 + - "⍼": [T: "kąt prosty z dolną strzałką zygzakowatą"] # 0x237c + - "⎔": [T: "sześciokąt"] # 0x2394 + - "⎕": [T: "ramka"] # 0x2395 + - "⎶": [T: "dolny nawias kwadratowy nad górnym nawiasem kwadratowym"] # 0x23b6 + - "⏜": [T: "górny nawias"] # 0x23dc + - "⏝": [T: "dolny nawias"] # 0x23dd + - "⏞": [T: "górny nawias klamrowy"] # 0x23de + - "⏟": [T: "dolny nawias klamrowy"] # 0x23df + - "⏠": [T: "górny nawias skorupowy"] # 0x23e0 + - "⏡": [T: "dolny nawias skorupowy"] # 0x23e1 + - "⏢": [T: "biały trapez"] # 0x23e2 + - "⏣": [T: "benzenowy pierścień z okręgiem po prawej"] # 0x23e3 + - "⏤": [T: "prostoliniowość"] # 0x23e4 + - "⏥": [T: "płaskość"] # 0x23e5 + - "⏦": [T: "prąd przemienny"] # 0x23e6 + - "⏧": [T: "symbol elektrycznego przecięcia"] # 0x23e7 - "①-⑨": # 0x2460 - 0x2469 - - t: "w kółku" + - T: "w kółku" - spell: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" - - "⑩": [t: "w kółku dziesięć"] # 0x2469 - - "⑪": [t: "w kółku jedenaście"] # 0x246a - - "⑫": [t: "w kółku dwanaście"] # 0x246b - - "⑬": [t: "w kółku trzynaście"] # 0x246c - - "⑭": [t: "w kółku czternaście"] # 0x246d - - "⑮": [t: "w kółku piętnaście"] # 0x246e - - "⑯": [t: "w kółku szesnaście"] # 0x246f - - "⑰": [t: "w kółku siedemnaście"] # 0x2470 - - "⑱": [t: "w kółku osiemnaście"] # 0x2471 - - "⑳": [t: "w kółku dwadzieścia"] # 0x2473 + - "⑩": [T: "w kółku dziesięć"] # 0x2469 + - "⑪": [T: "w kółku jedenaście"] # 0x246a + - "⑫": [T: "w kółku dwanaście"] # 0x246b + - "⑬": [T: "w kółku trzynaście"] # 0x246c + - "⑭": [T: "w kółku czternaście"] # 0x246d + - "⑮": [T: "w kółku piętnaście"] # 0x246e + - "⑯": [T: "w kółku szesnaście"] # 0x246f + - "⑰": [T: "w kółku siedemnaście"] # 0x2470 + - "⑱": [T: "w kółku osiemnaście"] # 0x2471 + - "⑳": [T: "w kółku dwadzieścia"] # 0x2473 - "⑴-⑼": # 0x2474 - 0x247d - - t: "w nawiasie" + - T: "w nawiasie" - spell: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" - - "⑽": [t: "w nawiasie dziesięć"] # 0x247d - - "⑾": [t: "w nawiasie jedenaście"] # 0x247e - - "⑿": [t: "w nawiasie dwanaście"] # 0x247f - - "⒀": [t: "w nawiasie trzynaście"] # 0x2480 - - "⒁": [t: "w nawiasie czternaście"] # 0x2481 - - "⒂": [t: "w nawiasie piętnaście"] # 0x2482 - - "⒃": [t: "w nawiasie szesnaście"] # 0x2483 - - "⒄": [t: "w nawiasie siedemnaście"] # 0x2484 - - "⒅": [t: "w nawiasie osiemnaście"] # 0x2485 - - "⒆": [t: "w nawiasie dziewiętnaście"] # 0x2486 - - "⒇": [t: "w nawiasie dwadzieścia"] # 0x2487 + - "⑽": [T: "w nawiasie dziesięć"] # 0x247d + - "⑾": [T: "w nawiasie jedenaście"] # 0x247e + - "⑿": [T: "w nawiasie dwanaście"] # 0x247f + - "⒀": [T: "w nawiasie trzynaście"] # 0x2480 + - "⒁": [T: "w nawiasie czternaście"] # 0x2481 + - "⒂": [T: "w nawiasie piętnaście"] # 0x2482 + - "⒃": [T: "w nawiasie szesnaście"] # 0x2483 + - "⒄": [T: "w nawiasie siedemnaście"] # 0x2484 + - "⒅": [T: "w nawiasie osiemnaście"] # 0x2485 + - "⒆": [T: "w nawiasie dziewiętnaście"] # 0x2486 + - "⒇": [T: "w nawiasie dwadzieścia"] # 0x2487 - "⒈-⒐": # 0x2488 - 0x2491 - spell: "translate('.', '⒈⒉⒊⒋⒌⒍⒎⒏⒐', '123456789')" - - t: "z kropką" - - "⒑": [t: "dziesięć z kropką"] # 0x2491 - - "⒒": [t: "jedenaście z kropką"] # 0x2492 - - "⒓": [t: "dwanaście z kropką"] # 0x2493 - - "⒔": [t: "trzynaście z kropką"] # 0x2494 - - "⒕": [t: "czternaście z kropką"] # 0x2495 - - "⒖": [t: "piętnaście z kropką"] # 0x2496 - - "⒗": [t: "szesnaście z kropką"] # 0x2497 - - "⒘": [t: "siedemnaście z kropką"] # 0x2498 - - "⒙": [t: "osiemnaście z kropką"] # 0x2499 - - "⒚": [t: "dziewiętnaście z kropką"] # 0x249a - - "⒛": [t: "dwadzieścia z kropką"] # 0x249b + - T: "z kropką" + - "⒑": [T: "dziesięć z kropką"] # 0x2491 + - "⒒": [T: "jedenaście z kropką"] # 0x2492 + - "⒓": [T: "dwanaście z kropką"] # 0x2493 + - "⒔": [T: "trzynaście z kropką"] # 0x2494 + - "⒕": [T: "czternaście z kropką"] # 0x2495 + - "⒖": [T: "piętnaście z kropką"] # 0x2496 + - "⒗": [T: "szesnaście z kropką"] # 0x2497 + - "⒘": [T: "siedemnaście z kropką"] # 0x2498 + - "⒙": [T: "osiemnaście z kropką"] # 0x2499 + - "⒚": [T: "dziewiętnaście z kropką"] # 0x249a + - "⒛": [T: "dwadzieścia z kropką"] # 0x249b - "⒜-⒵": # 0x249c - 0x24b5 - - t: "w nawiasie" + - T: "w nawiasie" - spell: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" - "Ⓐ-ⓩ": # 0x24b6 - 0x24cf - - t: "w kółku" + - T: "w kółku" - spell: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "🅐-🅩": # 0x1f150 - 0x1f169 - - t: "czarny w kółku" + - T: "czarny w kółku" - spell: "translate('.', '🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 - - t: "w kółku" + - T: "w kółku" - spell: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" - - "⓪": [t: "w kółku zero"] # 0x24ea - - "⓫": [t: "czarny w kółku jedenaście"] # 0x24eb - - "⓬": [t: "czarny w kółku dwanaście"] # 0x24ec - - "⓭": [t: "czarny w kółku trzynaście"] # 0x24ed - - "⓮": [t: "czarny w kółku czternaście"] # 0x24ee - - "⓯": [t: "czarny w kółku piętnaście"] # 0x24ef - - "⓰": [t: "czarny w kółku szesnaście"] # 0x24f0 - - "⓱": [t: "czarny w kółku siedemnaście"] # 0x24f1 - - "⓲": [t: "czarny w kółku osiemnaście"] # 0x24f2 - - "⓳": [t: "czarny w kółku dziewiętnaście"] # 0x24f3 - - "⓴": [t: "czarny w kółku dwadzieścia"] # 0x24f4 + - "⓪": [T: "w kółku zero"] # 0x24ea + - "⓫": [T: "czarny w kółku jedenaście"] # 0x24eb + - "⓬": [T: "czarny w kółku dwanaście"] # 0x24ec + - "⓭": [T: "czarny w kółku trzynaście"] # 0x24ed + - "⓮": [T: "czarny w kółku czternaście"] # 0x24ee + - "⓯": [T: "czarny w kółku piętnaście"] # 0x24ef + - "⓰": [T: "czarny w kółku szesnaście"] # 0x24f0 + - "⓱": [T: "czarny w kółku siedemnaście"] # 0x24f1 + - "⓲": [T: "czarny w kółku osiemnaście"] # 0x24f2 + - "⓳": [T: "czarny w kółku dziewiętnaście"] # 0x24f3 + - "⓴": [T: "czarny w kółku dwadzieścia"] # 0x24f4 - "⓵-⓽": # 0x24f5 - 0x24fe - - t: "podwójny w kółku" + - T: "podwójny w kółku" - spell: "translate('.', '⓵⓶⓷⓸⓹⓺⓻⓼⓽', '123456789')" - - "⓾": [t: "podwójny w kółku dziesięć"] # 0x24fe - - "⓿": [t: "czarny w kółku zero"] # 0x24ff - - "■": [t: "czarny kwadrat"] # 0x25a0 - - "□": [t: "biały kwadrat"] # 0x25a1 - - "▢": [t: "biały kwadrat z zaokrąglonymi narożnikami"] # 0x25a2 - - "▣": [t: "biały kwadrat zawierający mały czarny kwadrat"] # 0x25a3 - - "▤": [t: "kwadrat z poziomym wypełnieniem"] # 0x25a4 - - "▥": [t: "kwadrat z pionowym wypełnieniem"] # 0x25a5 - - "▦": [t: "kwadrat z ortogonalnym kreskowanym wypełnieniem"] # 0x25a6 - - "▧": [t: "kwadrat z wypełnieniem od góry po lewej do dołu po prawej"] # 0x25a7 - - "▨": [t: "kwadrat z wypełnieniem od góry po prawej do dołu po lewej"] # 0x25a8 - - "▩": [t: "kwadrat z ukośnym kreskowanym wypełnieniem"] # 0x25a9 - - "▪": [t: "czarny mały kwadrat"] # 0x25aa - - "▫": [t: "biały mały kwadrat"] # 0x25ab - - "▬": [t: "czarny prostokąt"] # 0x25ac - - "▭": [t: "biały prostokąt"] # 0x25ad - - "▮": [t: "czarny pionowy prostokąt"] # 0x25ae - - "▯": [t: "biały pionowy prostokąt"] # 0x25af - - "▰": [t: "czarny Równoległobok"] # 0x25b0 - - "▱": [t: "biały Równoległobok"] # 0x25b1 - - "▲": [t: "czarny trójkąt skierowany w górę"] # 0x25b2 - - "△": [t: "trójkąt"] # 0x25b3 - - "▴": [t: "czarny mały trójkąt skierowany w górę"] # 0x25b4 - - "▵": [t: "biały mały trójkąt skierowany w górę"] # 0x25b5 - - "▶": [t: "czarny trójkąt skierowany w prawo"] # 0x25b6 - - "▷": [t: "biały trójkąt skierowany w prawo"] # 0x25b7 - - "▸": [t: "czarny mały trójkąt skierowany w prawo"] # 0x25b8 - - "▹": [t: "biały mały trójkąt skierowany w prawo"] # 0x25b9 - - "►": [t: "czarny wskaźnik skierowany w prawo"] # 0x25ba - - "▻": [t: "biały wskaźnik skierowany w prawo"] # 0x25bb - - "▼": [t: "czarny trójkąt skierowany w dół"] # 0x25bc - - "▽": [t: "biały trójkąt skierowany w dół"] # 0x25bd - - "▾": [t: "czarny mały trójkąt skierowany w dół"] # 0x25be - - "▿": [t: "biały mały trójkąt skierowany w dół"] # 0x25bf - - "◀": [t: "czarny trójkąt skierowany w lewo"] # 0x25c0 - - "◁": [t: "biały trójkąt skierowany w lewo"] # 0x25c1 - - "◂": [t: "czarny mały trójkąt skierowany w lewo"] # 0x25c2 - - "◃": [t: "biały mały trójkąt skierowany w lewo"] # 0x25c3 - - "◄": [t: "czarny wskaźnik skierowany w lewo"] # 0x25c4 - - "◅": [t: "biały wskaźnik skierowany w lewo"] # 0x25c5 - - "◆": [t: "czarny romb"] # 0x25c6 - - "◇": [t: "biały romb"] # 0x25c7 - - "◈": [t: "biały romb zawierający czarny mały romb"] # 0x25c8 - - "◉": [t: "rybie oko"] # 0x25c9 - - "◊": [t: "romb"] # 0x25ca - - "○": [t: "białe koło"] # 0x25cb - - "◌": [t: "kropkowany okrąg"] # 0x25cc - - "◍": [t: "okrąg z pionowe wypełnienie"] # 0x25cd - - "◎": [t: "tarcza"] # 0x25ce - - "●": [t: "czarne koło"] # 0x25cf - - "◐": [t: "okrąg z czarną lewą połową"] # 0x25d0 - - "◑": [t: "okrąg z czarną prawą połową"] # 0x25d1 - - "◒": [t: "okrąg z czarną dolną połową"] # 0x25d2 - - "◓": [t: "okrąg z czarną górną połową"] # 0x25d3 - - "◔": [t: "okrąg z czarną górną prawą ćwiartką"] # 0x25d4 - - "◕": [t: "okrąg czarny poza górną lewą ćwiartką"] # 0x25d5 - - "◖": [t: "czarne koło z lewą połową"] # 0x25d6 - - "◗": [t: "czarne koło z prawą połową"] # 0x25d7 - - "◘": [t: "odwrotność punkt"] # 0x25d8 - - "◙": [t: "odwrotność białe koło"] # 0x25d9 - - "◚": [t: "górna połowa odwrotność białe koło"] # 0x25da - - "◛": [t: "dolna połowa odwrotność białe koło"] # 0x25db - - "◜": [t: "górny lewy ćwiartka łuk kołowy"] # 0x25dc - - "◝": [t: "górny prawy ćwiartka łuk kołowy"] # 0x25dd - - "◞": [t: "dolny prawy ćwiartka łuk kołowy"] # 0x25de - - "◟": [t: "dolny lewy ćwiartka łuk kołowy"] # 0x25df - - "◠": [t: "górna połowa okrąg"] # 0x25e0 - - "◡": [t: "dolna połowa okrąg"] # 0x25e1 - - "◢": [t: "czarny dolny prawy trójkąt"] # 0x25e2 - - "◣": [t: "czarny dolny lewy trójkąt"] # 0x25e3 - - "◤": [t: "czarny górny lewy trójkąt"] # 0x25e4 - - "◥": [t: "czarny górny prawy trójkąt"] # 0x25e5 - - "◦": [t: "złożenie"] # 0x25e6 - - "◧": [t: "kwadrat z czarną lewą połową"] # 0x25e7 - - "◨": [t: "kwadrat z czarną prawą połową"] # 0x25e8 - - "◩": [t: "kwadrat z czarną górną lewą połową"] # 0x25e9 - - "◪": [t: "kwadrat z czarną dolną prawą połową"] # 0x25ea - - "◫": [t: "biały kwadrat z linią dzielącą na pół"] # 0x25eb - - "◬": [t: "biały trójkąt skierowany w górę z kropką"] # 0x25ec - - "◭": [t: "trójkąt skierowany w górę z czarną lewą połową"] # 0x25ed - - "◮": [t: "trójkąt skierowany w górę z czarną prawą połową"] # 0x25ee - - "◯": [t: "duży okrąg"] # 0x25ef - - "◰": [t: "biały kwadrat z górną lewą ćwiartką"] # 0x25f0 - - "◱": [t: "biały kwadrat z dolną lewą ćwiartką"] # 0x25f1 - - "◲": [t: "biały kwadrat z dolną prawą ćwiartką"] # 0x25f2 - - "◳": [t: "biały kwadrat z górną prawą ćwiartką"] # 0x25f3 - - "◴": [t: "białe koło z górną lewą ćwiartką"] # 0x25f4 - - "◵": [t: "białe koło z dolną lewą ćwiartką"] # 0x25f5 - - "◶": [t: "białe koło z dolną prawą ćwiartką"] # 0x25f6 - - "◷": [t: "białe koło z górną prawą ćwiartką"] # 0x25f7 - - "◸": [t: "górny lewy trójkąt"] # 0x25f8 - - "◹": [t: "górny prawy trójkąt"] # 0x25f9 - - "◺": [t: "dolny lewy trójkąt"] # 0x25fa - - "◻": [t: "biały średni kwadrat"] # 0x25fb - - "◼": [t: "czarny średni kwadrat"] # 0x25fc - - "◽": [t: "biały średni mały kwadrat"] # 0x25fd - - "◾": [t: "czarny średni mały kwadrat"] # 0x25fe - - "◿": [t: "dolny prawy trójkąt"] # 0x25ff - - "★": [t: "czarna gwiazda"] # 0x2605 - - "☆": [t: "biały gwiazda"] # 0x2606 - - "☉": [t: "słońce"] # 0x2609 - - "☌": [t: "koniunkcja"] # 0x260c - - "☒": [t: "ramka wyboru z iksem"] # 0x2612 - - "☽": [t: "przybywający księżyc"] # 0x263d - - "☾": [t: "ubywający księżyc"] # 0x263e - - "☿": [t: "Merkury"] # 0x263f - - "♀": [t: "żeńskie"] # 0x2640 - - "♁": [t: "Ziemia"] # 0x2641 - - "♂": [t: "męskie"] # 0x2642 - - "♃": [t: "Jowisz"] # 0x2643 + - "⓾": [T: "podwójny w kółku dziesięć"] # 0x24fe + - "⓿": [T: "czarny w kółku zero"] # 0x24ff + - "■": [T: "czarny kwadrat"] # 0x25a0 + - "□": [T: "biały kwadrat"] # 0x25a1 + - "▢": [T: "biały kwadrat z zaokrąglonymi narożnikami"] # 0x25a2 + - "▣": [T: "biały kwadrat zawierający mały czarny kwadrat"] # 0x25a3 + - "▤": [T: "kwadrat z poziomym wypełnieniem"] # 0x25a4 + - "▥": [T: "kwadrat z pionowym wypełnieniem"] # 0x25a5 + - "▦": [T: "kwadrat z ortogonalnym kreskowanym wypełnieniem"] # 0x25a6 + - "▧": [T: "kwadrat z wypełnieniem od góry po lewej do dołu po prawej"] # 0x25a7 + - "▨": [T: "kwadrat z wypełnieniem od góry po prawej do dołu po lewej"] # 0x25a8 + - "▩": [T: "kwadrat z ukośnym kreskowanym wypełnieniem"] # 0x25a9 + - "▪": [T: "czarny mały kwadrat"] # 0x25aa + - "▫": [T: "biały mały kwadrat"] # 0x25ab + - "▬": [T: "czarny prostokąt"] # 0x25ac + - "▭": [T: "biały prostokąt"] # 0x25ad + - "▮": [T: "czarny pionowy prostokąt"] # 0x25ae + - "▯": [T: "biały pionowy prostokąt"] # 0x25af + - "▰": [T: "czarny Równoległobok"] # 0x25b0 + - "▱": [T: "biały Równoległobok"] # 0x25b1 + - "▲": [T: "czarny trójkąt skierowany w górę"] # 0x25b2 + - "△": [T: "trójkąt"] # 0x25b3 + - "▴": [T: "czarny mały trójkąt skierowany w górę"] # 0x25b4 + - "▵": [T: "biały mały trójkąt skierowany w górę"] # 0x25b5 + - "▶": [T: "czarny trójkąt skierowany w prawo"] # 0x25b6 + - "▷": [T: "biały trójkąt skierowany w prawo"] # 0x25b7 + - "▸": [T: "czarny mały trójkąt skierowany w prawo"] # 0x25b8 + - "▹": [T: "biały mały trójkąt skierowany w prawo"] # 0x25b9 + - "►": [T: "czarny wskaźnik skierowany w prawo"] # 0x25ba + - "▻": [T: "biały wskaźnik skierowany w prawo"] # 0x25bb + - "▼": [T: "czarny trójkąt skierowany w dół"] # 0x25bc + - "▽": [T: "biały trójkąt skierowany w dół"] # 0x25bd + - "▾": [T: "czarny mały trójkąt skierowany w dół"] # 0x25be + - "▿": [T: "biały mały trójkąt skierowany w dół"] # 0x25bf + - "◀": [T: "czarny trójkąt skierowany w lewo"] # 0x25c0 + - "◁": [T: "biały trójkąt skierowany w lewo"] # 0x25c1 + - "◂": [T: "czarny mały trójkąt skierowany w lewo"] # 0x25c2 + - "◃": [T: "biały mały trójkąt skierowany w lewo"] # 0x25c3 + - "◄": [T: "czarny wskaźnik skierowany w lewo"] # 0x25c4 + - "◅": [T: "biały wskaźnik skierowany w lewo"] # 0x25c5 + - "◆": [T: "czarny romb"] # 0x25c6 + - "◇": [T: "biały romb"] # 0x25c7 + - "◈": [T: "biały romb zawierający czarny mały romb"] # 0x25c8 + - "◉": [T: "rybie oko"] # 0x25c9 + - "◊": [T: "romb"] # 0x25ca + - "○": [T: "białe koło"] # 0x25cb + - "◌": [T: "kropkowany okrąg"] # 0x25cc + - "◍": [T: "okrąg z pionowe wypełnienie"] # 0x25cd + - "◎": [T: "tarcza"] # 0x25ce + - "●": [T: "czarne koło"] # 0x25cf + - "◐": [T: "okrąg z czarną lewą połową"] # 0x25d0 + - "◑": [T: "okrąg z czarną prawą połową"] # 0x25d1 + - "◒": [T: "okrąg z czarną dolną połową"] # 0x25d2 + - "◓": [T: "okrąg z czarną górną połową"] # 0x25d3 + - "◔": [T: "okrąg z czarną górną prawą ćwiartką"] # 0x25d4 + - "◕": [T: "okrąg czarny poza górną lewą ćwiartką"] # 0x25d5 + - "◖": [T: "czarne koło z lewą połową"] # 0x25d6 + - "◗": [T: "czarne koło z prawą połową"] # 0x25d7 + - "◘": [T: "odwrotność punkt"] # 0x25d8 + - "◙": [T: "odwrotność białe koło"] # 0x25d9 + - "◚": [T: "górna połowa odwrotność białe koło"] # 0x25da + - "◛": [T: "dolna połowa odwrotność białe koło"] # 0x25db + - "◜": [T: "górny lewy ćwiartka łuk kołowy"] # 0x25dc + - "◝": [T: "górny prawy ćwiartka łuk kołowy"] # 0x25dd + - "◞": [T: "dolny prawy ćwiartka łuk kołowy"] # 0x25de + - "◟": [T: "dolny lewy ćwiartka łuk kołowy"] # 0x25df + - "◠": [T: "górna połowa okrąg"] # 0x25e0 + - "◡": [T: "dolna połowa okrąg"] # 0x25e1 + - "◢": [T: "czarny dolny prawy trójkąt"] # 0x25e2 + - "◣": [T: "czarny dolny lewy trójkąt"] # 0x25e3 + - "◤": [T: "czarny górny lewy trójkąt"] # 0x25e4 + - "◥": [T: "czarny górny prawy trójkąt"] # 0x25e5 + - "◦": [T: "złożenie"] # 0x25e6 + - "◧": [T: "kwadrat z czarną lewą połową"] # 0x25e7 + - "◨": [T: "kwadrat z czarną prawą połową"] # 0x25e8 + - "◩": [T: "kwadrat z czarną górną lewą połową"] # 0x25e9 + - "◪": [T: "kwadrat z czarną dolną prawą połową"] # 0x25ea + - "◫": [T: "biały kwadrat z linią dzielącą na pół"] # 0x25eb + - "◬": [T: "biały trójkąt skierowany w górę z kropką"] # 0x25ec + - "◭": [T: "trójkąt skierowany w górę z czarną lewą połową"] # 0x25ed + - "◮": [T: "trójkąt skierowany w górę z czarną prawą połową"] # 0x25ee + - "◯": [T: "duży okrąg"] # 0x25ef + - "◰": [T: "biały kwadrat z górną lewą ćwiartką"] # 0x25f0 + - "◱": [T: "biały kwadrat z dolną lewą ćwiartką"] # 0x25f1 + - "◲": [T: "biały kwadrat z dolną prawą ćwiartką"] # 0x25f2 + - "◳": [T: "biały kwadrat z górną prawą ćwiartką"] # 0x25f3 + - "◴": [T: "białe koło z górną lewą ćwiartką"] # 0x25f4 + - "◵": [T: "białe koło z dolną lewą ćwiartką"] # 0x25f5 + - "◶": [T: "białe koło z dolną prawą ćwiartką"] # 0x25f6 + - "◷": [T: "białe koło z górną prawą ćwiartką"] # 0x25f7 + - "◸": [T: "górny lewy trójkąt"] # 0x25f8 + - "◹": [T: "górny prawy trójkąt"] # 0x25f9 + - "◺": [T: "dolny lewy trójkąt"] # 0x25fa + - "◻": [T: "biały średni kwadrat"] # 0x25fb + - "◼": [T: "czarny średni kwadrat"] # 0x25fc + - "◽": [T: "biały średni mały kwadrat"] # 0x25fd + - "◾": [T: "czarny średni mały kwadrat"] # 0x25fe + - "◿": [T: "dolny prawy trójkąt"] # 0x25ff + - "★": [T: "czarna gwiazda"] # 0x2605 + - "☆": [T: "biały gwiazda"] # 0x2606 + - "☉": [T: "słońce"] # 0x2609 + - "☌": [T: "koniunkcja"] # 0x260c + - "☒": [T: "ramka wyboru z iksem"] # 0x2612 + - "☽": [T: "przybywający księżyc"] # 0x263d + - "☾": [T: "ubywający księżyc"] # 0x263e + - "☿": [T: "Merkury"] # 0x263f + - "♀": [T: "żeńskie"] # 0x2640 + - "♁": [T: "Ziemia"] # 0x2641 + - "♂": [T: "męskie"] # 0x2642 + - "♃": [T: "Jowisz"] # 0x2643 - "♄": [T: "Saturn"] # 0x2644 - - "♅": [t: "Uran"] # 0x2645 - - "♆": [t: "Neptun"] # 0x2646 - - "♇": [t: "Pluton"] # 0x2647 - - "♈": [t: "Baran"] # 0x2648 - - "♉": [t: "Byk"] # 0x2649 - - "♩": [t: "ćwierćnuta"] # 0x2669 - - "♭": [t: "bemol"] # 0x266d - - "♮": [t: "kasownik"] # 0x266e - - "♯": [t: "krzyżyk"] # 0x266f - - "♠": [t: "czarny pik"] # 0x2660 - - "♡": [t: "biały kier"] # 0x2661 - - "♢": [t: "biały karo"] # 0x2662 - - "♣": [t: "czarny trefl"] # 0x2663 - - "♤": [t: "biały pik"] # 0x2664 - - "♥": [t: "czarny kier"] # 0x2665 - - "♦": [t: "czarny karo"] # 0x2666 - - "♧": [t: "biały trefl"] # 0x2667 - - "⚀": [t: "ścianka kostki 1"] # 0x2680 - - "⚁": [t: "ścianka kostki 2"] # 0x2681 - - "⚂": [t: "ścianka kostki 3"] # 0x2682 - - "⚃": [t: "ścianka kostki 4"] # 0x2683 - - "⚄": [t: "ścianka kostki 5"] # 0x2684 - - "⚅": [t: "ścianka kostki 6"] # 0x2685 - - "⚆": [t: "białe koło z kropką prawy"] # 0x2686 - - "⚇": [t: "białe koło z dwiema kropkami"] # 0x2687 - - "⚈": [t: "czarne koło z kropką prawy"] # 0x2688 - - "⚉": [t: "czarne koło z dwiema kropkami"] # 0x2689 - - "⚪": [t: "średni białe koło"] # 0x26aa - - "⚫": [t: "średni czarne koło"] # 0x26ab - - "⚬": [t: "średni mały białe koło"] # 0x26ac - - "⚲": [t: "neutralny"] # 0x26b2 - - "✓": [t: "haczek znak"] # 0x2713 - - "✠": [t: "krzyż maltański"] # 0x2720 - - "✪": [t: "w kółku biały gwiazda"] # 0x272a - - "✶": [t: "czarna sześcioramienna gwiazda"] # 0x2736 - - "❨": [t: "średni lewy ornament nawiasu okrągłego"] # 0x2768 - - "❩": [t: "średni prawy ornament nawiasu okrągłego"] # 0x2769 - - "❪": [t: "średni spłaszczony lewy ornament nawiasu okrągłego"] # 0x276a - - "❫": [t: "średni spłaszczony prawy ornament nawiasu okrągłego"] # 0x276b - - "❬": [t: "średni kąt skierowany w lewo nawias kwadratowy ornament"] # 0x276c - - "❭": [t: "średni kąt skierowany w prawo nawias kwadratowy ornament"] # 0x276d - - "❮": [t: "gruby kąt skierowany w lewo cudzysłów ornament"] # 0x276e - - "❯": [t: "gruby kąt skierowany w prawo cudzysłów ornament"] # 0x276f - - "❰": [t: "gruby kąt skierowany w lewo nawias kwadratowy ornament"] # 0x2770 - - "❱": [t: "gruby kąt skierowany w prawo nawias kwadratowy ornament"] # 0x2771 - - "❲": [t: "lekki lewy nawias skorupowy ornament"] # 0x2772 - - "❳": [t: "lekki prawy nawias skorupowy ornament"] # 0x2773 - - "❴": [t: "średni lewy nawias klamrowy ornament"] # 0x2774 - - "❵": [t: "średni prawy nawias klamrowy ornament"] # 0x2775 - - "❶": [t: "czarny w kółku jeden"] # 0x2776 - - "❷": [t: "czarny w kółku dwa"] # 0x2777 - - "❸": [t: "czarny w kółku trzy"] # 0x2778 - - "❹": [t: "czarny w kółku cztery"] # 0x2779 - - "❺": [t: "czarny w kółku pięć"] # 0x277a - - "❻": [t: "czarny w kółku sześć"] # 0x277b - - "❼": [t: "czarny w kółku siedem"] # 0x277c - - "❽": [t: "czarny w kółku osiem"] # 0x277d - - "❾": [t: "czarny w kółku dziewięć"] # 0x277e - - "❿": [t: "czarny w kółku dziesięć"] # 0x277f - - "➀": [t: "w kółku bezszeryfowe jeden"] # 0x2780 - - "➁": [t: "w kółku bezszeryfowe dwa"] # 0x2781 - - "➂": [t: "w kółku bezszeryfowe trzy"] # 0x2782 - - "➃": [t: "w kółku bezszeryfowe cztery"] # 0x2783 - - "➄": [t: "w kółku bezszeryfowe pięć"] # 0x2784 - - "➅": [t: "w kółku bezszeryfowe sześć"] # 0x2785 - - "➆": [t: "w kółku bezszeryfowe siedem"] # 0x2786 - - "➇": [t: "w kółku bezszeryfowe osiem"] # 0x2787 - - "➈": [t: "w kółku bezszeryfowe dziewięć"] # 0x2788 - - "➉": [t: "w kółku bezszeryfowe dziesięć"] # 0x2789 - - "➊": [t: "czarny w kółku bezszeryfowe jeden"] # 0x278a - - "➋": [t: "czarny w kółku bezszeryfowe dwa"] # 0x278b - - "➌": [t: "czarny w kółku bezszeryfowe trzy"] # 0x278c - - "➍": [t: "czarny w kółku bezszeryfowe cztery"] # 0x278d - - "➎": [t: "czarny w kółku bezszeryfowe pięć"] # 0x278e - - "➏": [t: "czarny w kółku bezszeryfowe sześć"] # 0x278f - - "➐": [t: "czarny w kółku bezszeryfowe siedem"] # 0x2790 - - "➑": [t: "czarny w kółku bezszeryfowe osiem"] # 0x2791 - - "➒": [t: "czarny w kółku bezszeryfowe dziewięć"] # 0x2792 - - "➓": [t: "czarny w kółku bezszeryfowe dziesięć"] # 0x2793 - - "➔": [t: "gruba strzałka w prawo z szerokim grotem"] # 0x2794 - - "➕": [t: "gruby znak plus"] # 0x2795 - - "➖": [t: "gruby znak minus"] # 0x2796 - - "➗": [t: "gruby znak dzielenia"] # 0x2797 - - "➘": [t: "gruba strzałka na południowy wschód"] # 0x2798 - - "➙": [t: "gruby strzałka w prawo"] # 0x2799 - - "➚": [t: "gruba strzałka na północny wschód"] # 0x279a - - "➛": [t: "strzałka w prawo z grotem kreślarskim"] # 0x279b - - "➜": [t: "gruba strzałka w prawo z okrągłym grotem"] # 0x279c - - "➝": [t: "strzałka w prawo z trójkątnym grotem"] # 0x279d - - "➞": [t: "gruba strzałka w prawo z trójkątnym grotem"] # 0x279e - - "➟": [t: "kreskowana strzałka w prawo z trójkątnym grotem"] # 0x279f - - "➠": [t: "gruba kreskowana strzałka w prawo z trójkątnym grotem"] # 0x27a0 - - "➡": [t: "czarny strzałka w prawo"] # 0x27a1 - - "➢": [t: "trójwymiarowa strzałka w prawo podświetlona od góry"] # 0x27a2 - - "➣": [t: "trójwymiarowa strzałka w prawo podświetlona od dołu"] # 0x27a3 - - "➤": [t: "czarny prawy grot strzałki"] # 0x27a4 - - "➥": [t: "gruba czarna zakrzywiona dolna strzałka w prawo"] # 0x27a5 - - "➦": [t: "gruba czarna zakrzywiona górna strzałka w prawo"] # 0x27a6 - - "➧": [t: "krótki czarny strzałka w prawo"] # 0x27a7 - - "➨": [t: "gruba czarna wklęsła ostro zakończona strzałka w prawo"] # 0x27a8 - - "➩": [t: "prawostronnie cieniowana biała strzałka w prawo"] # 0x27a9 - - "➪": [t: "lewostronnie cieniowana biała strzałka w prawo"] # 0x27aa - - "➫": [t: "biała strzałka w prawo pochylona do tyłu z cieniem"] # 0x27ab - - "➬": [t: "biała strzałka w prawo pochylona do przodu z cieniem"] # 0x27ac - - "➭": [t: "gruba biała strzałka w prawo z cieniem w dolnym prawym rogu"] # 0x27ad - - "➮": [t: "gruba biała strzałka w prawo z cieniem w górnym prawym rogu"] # 0x27ae - - "➯": [t: "biała strzałka w prawo z dolnym prawym wcięciem i cieniem"] # 0x27af - - "➱": [t: "biała strzałka w prawo z górnym prawym wcięciem i cieniem"] # 0x27b1 - - "➲": [t: "gruba biała strzałka w prawo w kółku"] # 0x27b2 - - "➳": [t: "biała pierzasta strzałka w prawo"] # 0x27b3 - - "➴": [t: "czarna pierzasta strzałka południowo-wschodnia"] # 0x27b4 - - "➵": [t: "czarna pierzasta strzałka w prawo"] # 0x27b5 - - "➶": [t: "czarny pierzasty północ wschód strzałka"] # 0x27b6 - - "➷": [t: "gruby czarna pierzasta strzałka południowo-wschodnia"] # 0x27b7 - - "➸": [t: "gruby czarna pierzasta strzałka w prawo"] # 0x27b8 - - "➹": [t: "gruby czarny pierzasty północ wschód strzałka"] # 0x27b9 - - "➺": [t: "strzałka w prawo z łezkowatym grotem z zadziorami"] # 0x27ba - - "➻": [t: "gruba strzałka w prawo z łezkowatym grotem i trzonkiem"] # 0x27bb - - "➼": [t: "strzałka w prawo z klinowym ogonem"] # 0x27bc - - "➽": [t: "gruby strzałka w prawo z klinowym ogonem"] # 0x27bd - - "➾": [t: "otwarta konturowa strzałka w prawo"] # 0x27be - - "⟀": [t: "trójwymiarowy kąt"] # 0x27c0 - - "⟁": [t: "biały trójkąt zawierający mały biały trójkąt"] # 0x27c1 + - "♅": [T: "Uran"] # 0x2645 + - "♆": [T: "Neptun"] # 0x2646 + - "♇": [T: "Pluton"] # 0x2647 + - "♈": [T: "Baran"] # 0x2648 + - "♉": [T: "Byk"] # 0x2649 + - "♩": [T: "ćwierćnuta"] # 0x2669 + - "♭": [T: "bemol"] # 0x266d + - "♮": [T: "kasownik"] # 0x266e + - "♯": [T: "krzyżyk"] # 0x266f + - "♠": [T: "czarny pik"] # 0x2660 + - "♡": [T: "biały kier"] # 0x2661 + - "♢": [T: "biały karo"] # 0x2662 + - "♣": [T: "czarny trefl"] # 0x2663 + - "♤": [T: "biały pik"] # 0x2664 + - "♥": [T: "czarny kier"] # 0x2665 + - "♦": [T: "czarny karo"] # 0x2666 + - "♧": [T: "biały trefl"] # 0x2667 + - "⚀": [T: "ścianka kostki 1"] # 0x2680 + - "⚁": [T: "ścianka kostki 2"] # 0x2681 + - "⚂": [T: "ścianka kostki 3"] # 0x2682 + - "⚃": [T: "ścianka kostki 4"] # 0x2683 + - "⚄": [T: "ścianka kostki 5"] # 0x2684 + - "⚅": [T: "ścianka kostki 6"] # 0x2685 + - "⚆": [T: "białe koło z kropką prawy"] # 0x2686 + - "⚇": [T: "białe koło z dwiema kropkami"] # 0x2687 + - "⚈": [T: "czarne koło z kropką prawy"] # 0x2688 + - "⚉": [T: "czarne koło z dwiema kropkami"] # 0x2689 + - "⚪": [T: "średni białe koło"] # 0x26aa + - "⚫": [T: "średni czarne koło"] # 0x26ab + - "⚬": [T: "średni mały białe koło"] # 0x26ac + - "⚲": [T: "neutralny"] # 0x26b2 + - "✓": [T: "haczek znak"] # 0x2713 + - "✠": [T: "krzyż maltański"] # 0x2720 + - "✪": [T: "w kółku biały gwiazda"] # 0x272a + - "✶": [T: "czarna sześcioramienna gwiazda"] # 0x2736 + - "❨": [T: "średni lewy ornament nawiasu okrągłego"] # 0x2768 + - "❩": [T: "średni prawy ornament nawiasu okrągłego"] # 0x2769 + - "❪": [T: "średni spłaszczony lewy ornament nawiasu okrągłego"] # 0x276a + - "❫": [T: "średni spłaszczony prawy ornament nawiasu okrągłego"] # 0x276b + - "❬": [T: "średni kąt skierowany w lewo nawias kwadratowy ornament"] # 0x276c + - "❭": [T: "średni kąt skierowany w prawo nawias kwadratowy ornament"] # 0x276d + - "❮": [T: "gruby kąt skierowany w lewo cudzysłów ornament"] # 0x276e + - "❯": [T: "gruby kąt skierowany w prawo cudzysłów ornament"] # 0x276f + - "❰": [T: "gruby kąt skierowany w lewo nawias kwadratowy ornament"] # 0x2770 + - "❱": [T: "gruby kąt skierowany w prawo nawias kwadratowy ornament"] # 0x2771 + - "❲": [T: "lekki lewy nawias skorupowy ornament"] # 0x2772 + - "❳": [T: "lekki prawy nawias skorupowy ornament"] # 0x2773 + - "❴": [T: "średni lewy nawias klamrowy ornament"] # 0x2774 + - "❵": [T: "średni prawy nawias klamrowy ornament"] # 0x2775 + - "❶": [T: "czarny w kółku jeden"] # 0x2776 + - "❷": [T: "czarny w kółku dwa"] # 0x2777 + - "❸": [T: "czarny w kółku trzy"] # 0x2778 + - "❹": [T: "czarny w kółku cztery"] # 0x2779 + - "❺": [T: "czarny w kółku pięć"] # 0x277a + - "❻": [T: "czarny w kółku sześć"] # 0x277b + - "❼": [T: "czarny w kółku siedem"] # 0x277c + - "❽": [T: "czarny w kółku osiem"] # 0x277d + - "❾": [T: "czarny w kółku dziewięć"] # 0x277e + - "❿": [T: "czarny w kółku dziesięć"] # 0x277f + - "➀": [T: "w kółku bezszeryfowe jeden"] # 0x2780 + - "➁": [T: "w kółku bezszeryfowe dwa"] # 0x2781 + - "➂": [T: "w kółku bezszeryfowe trzy"] # 0x2782 + - "➃": [T: "w kółku bezszeryfowe cztery"] # 0x2783 + - "➄": [T: "w kółku bezszeryfowe pięć"] # 0x2784 + - "➅": [T: "w kółku bezszeryfowe sześć"] # 0x2785 + - "➆": [T: "w kółku bezszeryfowe siedem"] # 0x2786 + - "➇": [T: "w kółku bezszeryfowe osiem"] # 0x2787 + - "➈": [T: "w kółku bezszeryfowe dziewięć"] # 0x2788 + - "➉": [T: "w kółku bezszeryfowe dziesięć"] # 0x2789 + - "➊": [T: "czarny w kółku bezszeryfowe jeden"] # 0x278a + - "➋": [T: "czarny w kółku bezszeryfowe dwa"] # 0x278b + - "➌": [T: "czarny w kółku bezszeryfowe trzy"] # 0x278c + - "➍": [T: "czarny w kółku bezszeryfowe cztery"] # 0x278d + - "➎": [T: "czarny w kółku bezszeryfowe pięć"] # 0x278e + - "➏": [T: "czarny w kółku bezszeryfowe sześć"] # 0x278f + - "➐": [T: "czarny w kółku bezszeryfowe siedem"] # 0x2790 + - "➑": [T: "czarny w kółku bezszeryfowe osiem"] # 0x2791 + - "➒": [T: "czarny w kółku bezszeryfowe dziewięć"] # 0x2792 + - "➓": [T: "czarny w kółku bezszeryfowe dziesięć"] # 0x2793 + - "➔": [T: "gruba strzałka w prawo z szerokim grotem"] # 0x2794 + - "➕": [T: "gruby znak plus"] # 0x2795 + - "➖": [T: "gruby znak minus"] # 0x2796 + - "➗": [T: "gruby znak dzielenia"] # 0x2797 + - "➘": [T: "gruba strzałka na południowy wschód"] # 0x2798 + - "➙": [T: "gruby strzałka w prawo"] # 0x2799 + - "➚": [T: "gruba strzałka na północny wschód"] # 0x279a + - "➛": [T: "strzałka w prawo z grotem kreślarskim"] # 0x279b + - "➜": [T: "gruba strzałka w prawo z okrągłym grotem"] # 0x279c + - "➝": [T: "strzałka w prawo z trójkątnym grotem"] # 0x279d + - "➞": [T: "gruba strzałka w prawo z trójkątnym grotem"] # 0x279e + - "➟": [T: "kreskowana strzałka w prawo z trójkątnym grotem"] # 0x279f + - "➠": [T: "gruba kreskowana strzałka w prawo z trójkątnym grotem"] # 0x27a0 + - "➡": [T: "czarny strzałka w prawo"] # 0x27a1 + - "➢": [T: "trójwymiarowa strzałka w prawo podświetlona od góry"] # 0x27a2 + - "➣": [T: "trójwymiarowa strzałka w prawo podświetlona od dołu"] # 0x27a3 + - "➤": [T: "czarny prawy grot strzałki"] # 0x27a4 + - "➥": [T: "gruba czarna zakrzywiona dolna strzałka w prawo"] # 0x27a5 + - "➦": [T: "gruba czarna zakrzywiona górna strzałka w prawo"] # 0x27a6 + - "➧": [T: "krótki czarny strzałka w prawo"] # 0x27a7 + - "➨": [T: "gruba czarna wklęsła ostro zakończona strzałka w prawo"] # 0x27a8 + - "➩": [T: "prawostronnie cieniowana biała strzałka w prawo"] # 0x27a9 + - "➪": [T: "lewostronnie cieniowana biała strzałka w prawo"] # 0x27aa + - "➫": [T: "biała strzałka w prawo pochylona do tyłu z cieniem"] # 0x27ab + - "➬": [T: "biała strzałka w prawo pochylona do przodu z cieniem"] # 0x27ac + - "➭": [T: "gruba biała strzałka w prawo z cieniem w dolnym prawym rogu"] # 0x27ad + - "➮": [T: "gruba biała strzałka w prawo z cieniem w górnym prawym rogu"] # 0x27ae + - "➯": [T: "biała strzałka w prawo z dolnym prawym wcięciem i cieniem"] # 0x27af + - "➱": [T: "biała strzałka w prawo z górnym prawym wcięciem i cieniem"] # 0x27b1 + - "➲": [T: "gruba biała strzałka w prawo w kółku"] # 0x27b2 + - "➳": [T: "biała pierzasta strzałka w prawo"] # 0x27b3 + - "➴": [T: "czarna pierzasta strzałka południowo-wschodnia"] # 0x27b4 + - "➵": [T: "czarna pierzasta strzałka w prawo"] # 0x27b5 + - "➶": [T: "czarny pierzasty północ wschód strzałka"] # 0x27b6 + - "➷": [T: "gruby czarna pierzasta strzałka południowo-wschodnia"] # 0x27b7 + - "➸": [T: "gruby czarna pierzasta strzałka w prawo"] # 0x27b8 + - "➹": [T: "gruby czarny pierzasty północ wschód strzałka"] # 0x27b9 + - "➺": [T: "strzałka w prawo z łezkowatym grotem z zadziorami"] # 0x27ba + - "➻": [T: "gruba strzałka w prawo z łezkowatym grotem i trzonkiem"] # 0x27bb + - "➼": [T: "strzałka w prawo z klinowym ogonem"] # 0x27bc + - "➽": [T: "gruby strzałka w prawo z klinowym ogonem"] # 0x27bd + - "➾": [T: "otwarta konturowa strzałka w prawo"] # 0x27be + - "⟀": [T: "trójwymiarowy kąt"] # 0x27c0 + - "⟁": [T: "biały trójkąt zawierający mały biały trójkąt"] # 0x27c1 - "⟂⊥": # 0x27c2, 22A5 (22A5 wrongly used for perpendicular by most editors) - test: - if: "$SpeechStyle = 'LiteralSpeak' and text()='⊥'" # 22A5 (up tack/bottom) @@ -1670,1327 +1670,1327 @@ - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "otwórz podzbiór" + - T: "otwórz podzbiór" - "⟄": # 0x27c4 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "otwórz nadzbiór" - - "⟅": [t: "lewy ogranicznik workowy w kształcie S"] # 0x27c5 - - "⟆": [t: "prawy ogranicznik workowy w kształcie S"] # 0x27c6 - - "⟇": [t: "lub z kropką wewnątrz"] # 0x27c7 - - "⟈": [t: "odwrotny ukośnik poprzedzający podzbiór"] # 0x27c8 - - "⟉": [t: "nadzbiór poprzedzający ukośnik"] # 0x27c9 - - "⟊": [t: "pionowa kreska z poziomą kreską"] # 0x27ca - - "⟋": [t: "matematyczny ukośnik wznoszący"] # 0x27cb - - "⟌": [t: "dzielenie pisemne"] # 0x27cc - - "⟍": [t: "matematyczny ukośnik opadający"] # 0x27cd - - "⟎": [t: "kwadratowa koniunkcja logiczna"] # 0x27ce - - "⟏": [t: "do kwadratu logiczne lub"] # 0x27cf - - "⟐": [t: "biały romb z wyśrodkowaną kropką"] # 0x27d0 - - "⟑": [t: "i z kropką"] # 0x27d1 - - "⟒": [t: "należy do z otwarciem u góry"] # 0x27d2 - - "⟓": [t: "prawy dolny narożnik z kropką"] # 0x27d3 - - "⟔": [t: "górny lewy narożnik z kropką"] # 0x27d4 - - "⟕": [t: "lewe złączenie zewnętrzne"] # 0x27d5 - - "⟖": [t: "prawe złączenie zewnętrzne"] # 0x27d6 - - "⟗": [t: "pełne złączenie zewnętrzne"] # 0x27d7 - - "⟘": [t: "duży górny znacznik"] # 0x27d8 - - "⟙": [t: "duży dolny znacznik"] # 0x27d9 - - "⟚": [t: "lewy i prawy podwójny znacznik dedukcji"] # 0x27da - - "⟛": [t: "lewy i prawy znacznik"] # 0x27db - - "⟜": [t: "lewa multimapa"] # 0x27dc - - "⟝": [t: "długi prawy znacznik"] # 0x27dd - - "⟞": [t: "długi lewy znacznik"] # 0x27de - - "⟟": [t: "górny znacznik z okręgiem nad"] # 0x27df - - "⟠": [t: "romb podzielony poziomą kreską"] # 0x27e0 - - "⟡": [t: "biały romb o wklęsłych bokach"] # 0x27e1 - - "⟢": [t: "biały romb o wklęsłych bokach z lewym haczykiem"] # 0x27e2 - - "⟣": [t: "biały romb o wklęsłych bokach z prawym haczykiem"] # 0x27e3 - - "⟤": [t: "biały kwadrat z lewym haczykiem"] # 0x27e4 - - "⟥": [t: "biały kwadrat z prawym haczykiem"] # 0x27e5 - - "⟦": [t: "lewy biały nawias kwadratowy"] # 0x27e6 - - "⟧": [t: "prawy biały nawias kwadratowy"] # 0x27e7 - - "⟨": [t: "lewy nawias kątowy"] # 0x27e8 - - "⟩": [t: "prawy nawias kątowy"] # 0x27e9 - - "⟪": [t: "lewy podwójny nawias kątowy"] # 0x27ea - - "⟫": [t: "prawy podwójny nawias kątowy"] # 0x27eb - - "⟬": [t: "lewy biały nawias skorupowy"] # 0x27ec - - "⟭": [t: "prawy biały nawias skorupowy"] # 0x27ed - - "⟮": [t: "lewy spłaszczony nawias"] # 0x27ee - - "⟯": [t: "prawy spłaszczony nawias"] # 0x27ef - - "⟰": [t: "poczwórna strzałka w górę"] # 0x27f0 - - "⟱": [t: "poczwórna strzałka w dół"] # 0x27f1 - - "⟲": [t: "okrężna strzałka z przerwą przeciwnie do ruchu wskazówek zegara"] # 0x27f2 - - "⟳": [t: "okrężna strzałka z przerwą zgodnie z ruchem wskazówek zegara"] # 0x27f3 - - "⟴": [t: "strzałka w prawo z plusem w kółku"] # 0x27f4 - - "⟵": [t: "długa strzałka w lewo"] # 0x27f5 - - "⟶": [t: "długa strzałka w prawo"] # 0x27f6 - - "⟷": [t: "długa strzałka w lewo i w prawo"] # 0x27f7 - - "⟸": [t: "długa podwójna strzałka w lewo"] # 0x27f8 - - "⟹": [t: "implikuje"] # 0x27f9 - - "⟺": [t: "wtedy i tylko wtedy"] # 0x27fa - - "⟻": [t: "długa strzałka w lewo od kreski"] # 0x27fb - - "⟼": [t: "długa strzałka w prawo od kreski"] # 0x27fc - - "⟽": [t: "długa podwójna strzałka w lewo od kreski"] # 0x27fd - - "⟾": [t: "długa podwójna strzałka w prawo od kreski"] # 0x27fe - - "⟿": [t: "długa falista strzałka w prawo"] # 0x27ff - - "⤀": [t: "strzałka w prawo z dwoma grotami i pionowym przekreśleniem"] # 0x2900 - - "⤁": [t: "strzałka w prawo z dwoma grotami i podwójnym pionowym przekreśleniem"] # 0x2901 - - "⤂": [t: "podwójna strzałka w lewo z pionową kreską"] # 0x2902 - - "⤃": [t: "podwójna strzałka w prawo z pionową kreską"] # 0x2903 - - "⤄": [t: "podwójna strzałka w lewo i w prawo z pionową kreską"] # 0x2904 - - "⤅": [t: "strzałka w prawo z dwoma grotami od kreski"] # 0x2905 - - "⤆": [t: "podwójna strzałka w lewo od kreski"] # 0x2906 - - "⤇": [t: "podwójna strzałka w prawo od kreski"] # 0x2907 - - "⤈": [t: "strzałka w dół z poziomą kreską"] # 0x2908 - - "⤉": [t: "strzałka w górę z poziomą kreską"] # 0x2909 - - "⤊": [t: "górny potrójny strzałka"] # 0x290a - - "⤋": [t: "dolny potrójny strzałka"] # 0x290b - - "⤌": [t: "lewy podwójny kreska strzałka"] # 0x290c - - "⤍": [t: "prawy podwójny kreska strzałka"] # 0x290d - - "⤎": [t: "lewy potrójny kreska strzałka"] # 0x290e - - "⤏": [t: "prawy potrójny kreska strzałka"] # 0x290f - - "⤐": [t: "strzałka w prawo z dwoma grotami i potrójną kreską"] # 0x2910 - - "⤑": [t: "strzałka w prawo z kropkowanym trzonem"] # 0x2911 - - "⤒": [t: "strzałka w górę do kreski"] # 0x2912 - - "⤓": [t: "strzałka w dół do kreski"] # 0x2913 - - "⤔": [t: "strzałka w prawo z ogonem i pionową kreską"] # 0x2914 - - "⤕": [t: "strzałka w prawo z ogonem i podwójną pionową kreską"] # 0x2915 - - "⤖": [t: "strzałka w prawo z dwoma grotami i ogonem"] # 0x2916 - - "⤗": [t: "strzałka w prawo z dwoma grotami, ogonem i pionowym przekreśleniem"] # 0x2917 - - "⤘": [t: "strzałka w prawo z dwoma grotami, ogonem i podwójnym pionowym przekreśleniem"] # 0x2918 - - "⤙": [t: "strzałka w lewo ogon"] # 0x2919 - - "⤚": [t: "strzałka w prawo ogon"] # 0x291a - - "⤛": [t: "lewy podwójna strzałka ogon"] # 0x291b - - "⤜": [t: "prawy podwójna strzałka ogon"] # 0x291c - - "⤝": [t: "strzałka w lewo do wypełnionego rombu"] # 0x291d - - "⤞": [t: "strzałka w prawo do wypełnionego rombu"] # 0x291e - - "⤟": [t: "strzałka w lewo od kreski do wypełnionego rombu"] # 0x291f - - "⤠": [t: "strzałka w prawo od kreski do wypełnionego rombu"] # 0x2920 - - "⤡": [t: "strzałka północno-zachodnia i południowo-wschodnia"] # 0x2921 - - "⤢": [t: "strzałka północno-wschodnia i południowo-zachodnia"] # 0x2922 - - "⤣": [t: "strzałka północno-zachodnia z hakiem"] # 0x2923 - - "⤤": [t: "strzałka północno-wschodnia z hakiem"] # 0x2924 - - "⤥": [t: "strzałka południowo-wschodnia z hakiem"] # 0x2925 - - "⤦": [t: "strzałka południowo-zachodnia z hakiem"] # 0x2926 - - "⤧": [t: "strzałka północno-zachodnia i strzałka północno-wschodnia"] # 0x2927 - - "⤨": [t: "strzałka północno-wschodnia i strzałka południowo-wschodnia"] # 0x2928 - - "⤩": [t: "strzałka południowo-wschodnia i strzałka południowo-zachodnia"] # 0x2929 - - "⤪": [t: "strzałka południowo-zachodnia i strzałka północno-zachodnia"] # 0x292a - - "⤫": [t: "ukośna wznosząca przecinająca ukośną opadającą"] # 0x292b - - "⤬": [t: "ukośna opadająca przecinająca ukośną wznoszącą"] # 0x292c - - "⤭": [t: "strzałka południowo-wschodnia przecinająca strzałkę północno-wschodnią"] # 0x292d - - "⤮": [t: "strzałka północno-wschodnia przecinająca strzałkę południowo-wschodnią"] # 0x292e - - "⤯": [t: "ukośna opadająca przecinająca strzałkę północno-wschodnią"] # 0x292f - - "⤰": [t: "ukośna wznosząca przecinająca strzałkę południowo-wschodnią"] # 0x2930 - - "⤱": [t: "strzałka północno-wschodnia przecinająca strzałkę północno-zachodnią"] # 0x2931 - - "⤲": [t: "strzałka północno-zachodnia przecinająca strzałkę północno-wschodnią"] # 0x2932 - - "⤳": [t: "falista strzałka skierowana bezpośrednio w prawo"] # 0x2933 - - "⤴": [t: "strzałka skierowana w prawo, potem zakrzywiona w górę"] # 0x2934 - - "⤵": [t: "strzałka skierowana w prawo, potem zakrzywiona w dół"] # 0x2935 - - "⤶": [t: "strzałka skierowana w dół, potem zakrzywiona w lewo"] # 0x2936 - - "⤷": [t: "strzałka skierowana w dół, potem zakrzywiona w prawo"] # 0x2937 - - "⤸": [t: "prawostronna strzałka łukowa zgodna z ruchem wskazówek zegara"] # 0x2938 - - "⤹": [t: "lewostronna strzałka łukowa przeciwna do ruchu wskazówek zegara"] # 0x2939 - - "⤺": [t: "górna strzałka łukowa przeciwna do ruchu wskazówek zegara"] # 0x293a - - "⤻": [t: "dolna strzałka łukowa przeciwna do ruchu wskazówek zegara"] # 0x293b - - "⤼": [t: "górna strzałka łukowa zgodna z ruchem wskazówek zegara z minusem"] # 0x293c - - "⤽": [t: "górna strzałka łukowa przeciwna do ruchu wskazówek zegara z plusem"] # 0x293d - - "⤾": [t: "dolna prawa strzałka półokrągła zgodna z ruchem wskazówek zegara"] # 0x293e - - "⤿": [t: "dolna lewa strzałka półokrągła przeciwna do ruchu wskazówek zegara"] # 0x293f - - "⥀": [t: "zamknięta strzałka okrężna przeciwna do ruchu wskazówek zegara"] # 0x2940 - - "⥁": [t: "zamknięta strzałka okrężna zgodna z ruchem wskazówek zegara"] # 0x2941 - - "⥂": [t: "strzałka w prawo nad krótką strzałką w lewo"] # 0x2942 - - "⥃": [t: "strzałka w lewo nad krótką strzałką w prawo"] # 0x2943 - - "⥄": [t: "krótka strzałka w prawo nad strzałką w lewo"] # 0x2944 - - "⥅": [t: "strzałka w prawo z plusem pod spodem"] # 0x2945 - - "⥆": [t: "strzałka w lewo z plusem pod spodem"] # 0x2946 - - "⥇": [t: "strzałka w prawo przez X"] # 0x2947 - - "⥈": [t: "strzałka w lewo i w prawo przez okrąg"] # 0x2948 - - "⥉": [t: "strzałka w górę z dwoma grotami od okręgu"] # 0x2949 - - "⥊": [t: "lewy grot górny prawy grot dolny harpun"] # 0x294a - - "⥋": [t: "lewy grot dolny prawy grot górny harpun"] # 0x294b - - "⥌": [t: "górny grot prawy dolny grot lewy harpun"] # 0x294c - - "⥍": [t: "górny grot lewy dolny grot prawy harpun"] # 0x294d - - "⥎": [t: "lewy grot górny prawy grot górny harpun"] # 0x294e - - "⥏": [t: "górny grot prawy dolny grot prawy harpun"] # 0x294f - - "⥐": [t: "lewy grot dolny prawy grot dolny harpun"] # 0x2950 - - "⥑": [t: "górny grot lewy dolny grot lewy harpun"] # 0x2951 - - "⥒": [t: "lewy harpun z grotem górnym do kreski"] # 0x2952 - - "⥓": [t: "prawy harpun z grotem górnym do kreski"] # 0x2953 - - "⥔": [t: "górny harpun z grotem prawym do kreski"] # 0x2954 - - "⥕": [t: "dolny harpun z grotem prawym do kreski"] # 0x2955 - - "⥖": [t: "lewy harpun z grotem dolnym do kreski"] # 0x2956 - - "⥗": [t: "prawy harpun z grotem dolnym do kreski"] # 0x2957 - - "⥘": [t: "górny harpun z grotem lewym do kreski"] # 0x2958 - - "⥙": [t: "dolny harpun z grotem lewym do kreski"] # 0x2959 - - "⥚": [t: "lewy harpun z grotem górnym od kreski"] # 0x295a - - "⥛": [t: "prawy harpun z grotem górnym od kreski"] # 0x295b - - "⥜": [t: "górny harpun z grotem prawym od kreski"] # 0x295c - - "⥝": [t: "dolny harpun z grotem prawym od kreski"] # 0x295d - - "⥞": [t: "lewy harpun z grotem dolnym od kreski"] # 0x295e - - "⥟": [t: "prawy harpun z grotem dolnym od kreski"] # 0x295f - - "⥠": [t: "górny harpun z grotem lewym od kreski"] # 0x2960 - - "⥡": [t: "dolny harpun z grotem lewym od kreski"] # 0x2961 - - "⥢": [t: "lewy harpun z grotem górnym nad lewy harpun z grotem dolnym"] # 0x2962 - - "⥣": [t: "górny harpun z grotem w lewo obok górnego harpuna z grotem w prawo"] # 0x2963 - - "⥤": [t: "prawy harpun z grotem górnym nad prawy harpun z grotem dolnym"] # 0x2964 - - "⥥": [t: "dolny harpun z grotem w lewo obok dolnego harpuna z grotem w prawo"] # 0x2965 - - "⥦": [t: "lewy harpun z grotem górnym nad prawy harpun z grotem górnym"] # 0x2966 - - "⥧": [t: "lewy harpun z grotem dolnym nad prawy harpun z grotem dolnym"] # 0x2967 - - "⥨": [t: "prawy harpun z grotem górnym nad lewy harpun z grotem górnym"] # 0x2968 - - "⥩": [t: "prawy harpun z grotem dolnym nad lewy harpun z grotem dolnym"] # 0x2969 - - "⥪": [t: "lewy harpun z grotem górnym nad długą kreską"] # 0x296a - - "⥫": [t: "lewy harpun z grotem dolnym pod długą kreską"] # 0x296b - - "⥬": [t: "prawy harpun z grotem górnym nad długą kreską"] # 0x296c - - "⥭": [t: "prawy harpun z grotem dolnym pod długą kreską"] # 0x296d - - "⥮": [t: "górny harpun z grotem w lewo obok dolnego harpuna z grotem w prawo"] # 0x296e - - "⥯": [t: "dolny harpun z grotem w lewo obok górnego harpuna z grotem w prawo"] # 0x296f - - "⥰": [t: "podwójna strzałka w prawo z zaokrąglonym grotem"] # 0x2970 - - "⥱": [t: "równa się nad strzałka w prawo"] # 0x2971 - - "⥲": [t: "operator tyldy nad strzałką w prawo"] # 0x2972 - - "⥳": [t: "strzałka w lewo nad operatorem tyldy"] # 0x2973 - - "⥴": [t: "strzałka w prawo nad operatorem tyldy"] # 0x2974 - - "⥵": [t: "strzałka w prawo nad znakiem przybliżonej równości"] # 0x2975 - - "⥶": [t: "mniejsze niż nad strzałka w lewo"] # 0x2976 - - "⥷": [t: "strzałka w lewo przez znak mniejsze niż"] # 0x2977 - - "⥸": [t: "większe niż nad strzałka w prawo"] # 0x2978 - - "⥹": [t: "podzbiór nad strzałka w prawo"] # 0x2979 - - "⥺": [t: "strzałka w lewo przez znak podzbioru"] # 0x297a - - "⥻": [t: "nadzbiór nad strzałka w lewo"] # 0x297b - - "⥼": [t: "lewy rybi ogon"] # 0x297c - - "⥽": [t: "prawy rybi ogon"] # 0x297d - - "⥾": [t: "górny rybi ogon"] # 0x297e - - "⥿": [t: "dolny rybi ogon"] # 0x297f - - "⦀": [t: "potrójna pionowa kreska jako ogranicznik"] # 0x2980 - - "⦁": [t: "punkt w notacji Z"] # 0x2981 - - "⦂": [t: "dwukropek typu w notacji Z"] # 0x2982 - - "⦃": [t: "lewy biały nawias klamrowy"] # 0x2983 - - "⦄": [t: "prawy biały nawias klamrowy"] # 0x2984 - - "⦅": [t: "lewy biały nawias"] # 0x2985 - - "⦆": [t: "prawy biały nawias"] # 0x2986 - - "⦇": [t: "lewy nawias kwadratowy obrazu w notacji Z"] # 0x2987 - - "⦈": [t: "prawy nawias kwadratowy obrazu w notacji Z"] # 0x2988 - - "⦉": [t: "lewy nawias kwadratowy wiązania w notacji Z"] # 0x2989 - - "⦊": [t: "prawy nawias kwadratowy wiązania w notacji Z"] # 0x298a - - "⦋": [t: "lewy nawias kwadratowy z podkreśleniem"] # 0x298b - - "⦌": [t: "prawy nawias kwadratowy z podkreśleniem"] # 0x298c - - "⦍": [t: "lewy nawias kwadratowy z haczykiem w górnym rogu"] # 0x298d - - "⦎": [t: "prawy nawias kwadratowy z haczykiem w dolnym rogu"] # 0x298e - - "⦏": [t: "lewy nawias kwadratowy z haczykiem w dolnym rogu"] # 0x298f - - "⦐": [t: "prawy nawias kwadratowy z haczykiem w górnym rogu"] # 0x2990 - - "⦑": [t: "lewy kąt nawias kwadratowy z kropką"] # 0x2991 - - "⦒": [t: "prawy nawias kątowy z kropką"] # 0x2992 - - "⦓": [t: "lewy łuk mniejsze niż nawias kwadratowy"] # 0x2993 - - "⦔": [t: "prawy łuk większe niż nawias kwadratowy"] # 0x2994 - - "⦕": [t: "podwójny lewy łuk większe niż nawias kwadratowy"] # 0x2995 - - "⦖": [t: "podwójny prawy łuk mniejsze niż nawias kwadratowy"] # 0x2996 - - "⦗": [t: "lewy czarny nawias skorupowy"] # 0x2997 - - "⦘": [t: "prawy czarny nawias skorupowy"] # 0x2998 - - "⦙": [t: "kropkowany ogranicznik"] # 0x2999 - - "⦚": [t: "pionowa linia zygzakowata"] # 0x299a - - "⦛": [t: "kąt mierzony otwarty w lewo"] # 0x299b - - "⦜": [t: "wariant kąta prostego z kwadratem"] # 0x299c - - "⦝": [t: "mierzony kąt prosty z kropką"] # 0x299d - - "⦞": [t: "kąt z s wewnątrz"] # 0x299e - - "⦟": [t: "akut kąt"] # 0x299f - - "⦠": [t: "kąt sferyczny otwarty w lewo"] # 0x29a0 - - "⦡": [t: "kąt sferyczny otwarty w górę"] # 0x29a1 - - "⦢": [t: "odwrócony kąt"] # 0x29a2 - - "⦣": [t: "kąt odwrócony"] # 0x29a3 - - "⦤": [t: "kąt z podkreśleniem"] # 0x29a4 - - "⦥": [t: "kąt odwrócony z podkreśleniem"] # 0x29a5 - - "⦦": [t: "kąt ukośny otwarty w górę"] # 0x29a6 - - "⦧": [t: "kąt ukośny otwarty w dół"] # 0x29a7 - - "⦨": [t: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w górę i w prawo"] # 0x29a8 - - "⦩": [t: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w górę i w lewo"] # 0x29a9 - - "⦪": [t: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w dół i w prawo"] # 0x29aa - - "⦫": [t: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w dół i w lewo"] # 0x29ab - - "⦬": [t: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w prawo i w górę"] # 0x29ac - - "⦭": [t: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w lewo i w górę"] # 0x29ad - - "⦮": [t: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w prawo i w dół"] # 0x29ae - - "⦯": [t: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w lewo i w dół"] # 0x29af - - "⦰": [t: "odwrócony zbiór pusty"] # 0x29b0 - - "⦱": [t: "zbiór pusty z kreską nad"] # 0x29b1 - - "⦲": [t: "zbiór pusty z małym okręgiem nad"] # 0x29b2 - - "⦳": [t: "zbiór pusty ze strzałką w prawo nad"] # 0x29b3 - - "⦴": [t: "zbiór pusty ze strzałką w lewo nad"] # 0x29b4 - - "⦵": [t: "okrąg z kreską poziomą"] # 0x29b5 - - "⦶": [t: "pionowa kreska w kółku"] # 0x29b6 - - "⦷": [t: "w kółku równoległe"] # 0x29b7 - - "⦸": [t: "ukośnik odwrotny w kółku"] # 0x29b8 - - "⦹": [t: "w kółku prostopadłe"] # 0x29b9 - - "⦺": [t: "okrąg podzielony kreską poziomą, z górną połową podzieloną kreską pionową"] # 0x29ba - - "⦻": [t: "okrąg z nałożonym X"] # 0x29bb - - "⦼": [t: "znak dzielenia w kółku obrócony przeciwnie do ruchu wskazówek zegara"] # 0x29bc - - "⦽": [t: "strzałka w górę przez okrąg"] # 0x29bd - - "⦾": [t: "w kółku biały punkt"] # 0x29be - - "⦿": [t: "w kółku punkt"] # 0x29bf - - "⧀": [t: "w kółku mniejsze niż"] # 0x29c0 - - "⧁": [t: "w kółku większe niż"] # 0x29c1 - - "⧂": [t: "okrąg z małym okręgiem po prawej"] # 0x29c2 - - "⧃": [t: "okrąg z dwiema poziomymi kreskami po prawej"] # 0x29c3 - - "⧄": [t: "kwadrat z ukośnikiem wznoszącym"] # 0x29c4 - - "⧅": [t: "kwadrat z ukośnikiem opadającym"] # 0x29c5 - - "⧆": [t: "do kwadratu gwiazdka"] # 0x29c6 - - "⧇": [t: "do kwadratu mały okrąg"] # 0x29c7 - - "⧈": [t: "do kwadratu kwadrat"] # 0x29c8 - - "⧉": [t: "dwa połączone kwadraty"] # 0x29c9 - - "⧊": [t: "trójkąt z kropką nad"] # 0x29ca - - "⧋": [t: "trójkąt z podkreśleniem"] # 0x29cb - - "⧌": [t: "s w trójkąt"] # 0x29cc - - "⧍": [t: "trójkąt z szeryfami u dołu"] # 0x29cd - - "⧎": [t: "prawy trójkąt nad lewy trójkąt"] # 0x29ce - - "⧏": [t: "lewy trójkąt obok pionowej kreski"] # 0x29cf - - "⧐": [t: "pionowa kreska obok prawego trójkąta"] # 0x29d0 - - "⧑": [t: "kokarda z lewą połową czarną"] # 0x29d1 - - "⧒": [t: "kokarda z prawą połową czarną"] # 0x29d2 - - "⧓": [t: "czarna kokarda"] # 0x29d3 - - "⧔": [t: "znak mnożenia z lewą połową czarną"] # 0x29d4 - - "⧕": [t: "znak mnożenia z prawą połową czarną"] # 0x29d5 - - "⧖": [t: "biały klepsydra"] # 0x29d6 - - "⧗": [t: "czarny klepsydra"] # 0x29d7 - - "⧘": [t: "lewy falisty ogranicznik"] # 0x29d8 - - "⧙": [t: "prawy falisty ogranicznik"] # 0x29d9 - - "⧚": [t: "lewy podwójny falisty ogranicznik"] # 0x29da - - "⧛": [t: "prawy podwójny falisty ogranicznik"] # 0x29db - - "⧜": [t: "niepełna nieskończoność"] # 0x29dc - - "⧝": [t: "wiązanie nad nieskończonością"] # 0x29dd - - "⧞": [t: "zanegowana nieskończoność z kreską pionową"] # 0x29de - - "⧟": [t: "podwójnie zakończona strzałka mapująca"] # 0x29df - - "⧠": [t: "kwadrat z konturowym obrysem"] # 0x29e0 - - "⧡": [t: "wzrasta jak"] # 0x29e1 - - "⧢": [t: "iloczyn przetasowania"] # 0x29e2 - - "⧣": [t: "znak równości i ukośne równoległe"] # 0x29e3 - - "⧤": [t: "znak równości i ukośne równoległe z tyldą nad"] # 0x29e4 - - "⧥": [t: "identyczne i ukośne równoległe"] # 0x29e5 - - "⧦": [t: "równoliczne"] # 0x29e6 - - "⧧": [t: "termodynamiczny"] # 0x29e7 - - "⧨": [t: "trójkąt skierowany w dół z lewą połową czarną"] # 0x29e8 - - "⧩": [t: "trójkąt skierowany w dół z prawą połową czarną"] # 0x29e9 - - "⧪": [t: "czarny romb ze strzałką w dół"] # 0x29ea - - "⧫": [t: "czarny romb"] # 0x29eb - - "⧬": [t: "białe koło ze strzałką w dół"] # 0x29ec - - "⧭": [t: "czarne koło ze strzałką w dół"] # 0x29ed - - "⧮": [t: "biały kwadrat z przekreśleniem błędu"] # 0x29ee - - "⧯": [t: "czarny kwadrat z przekreśleniem błędu"] # 0x29ef - - "⧰": [t: "biały romb z przekreśleniem błędu"] # 0x29f0 - - "⧱": [t: "czarny romb z przekreśleniem błędu"] # 0x29f1 - - "⧲": [t: "białe koło z przekreśleniem błędu"] # 0x29f2 - - "⧳": [t: "czarne koło z przekreśleniem błędu"] # 0x29f3 - - "⧴": [t: "opóźniona reguła"] # 0x29f4 - - "⧵": [t: "operator ukośnika odwrotnego"] # 0x29f5 - - "⧶": [t: "ukośnik z kreską nad"] # 0x29f6 - - "⧷": [t: "ukośnik odwrotny z poziomą kreską"] # 0x29f7 - - "⧸": [t: "duży ukośnik"] # 0x29f8 - - "⧹": [t: "duży ukośnik odwrotny"] # 0x29f9 - - "⧺": [t: "podwójny plus"] # 0x29fa - - "⧻": [t: "potrójny plus"] # 0x29fb - - "⧼": [t: "lewy zakrzywiony nawias kątowy"] # 0x29fc - - "⧽": [t: "prawy zakrzywiony nawias kątowy"] # 0x29fd - - "⧾": [t: "maleńki"] # 0x29fe - - "⧿": [t: "mini"] # 0x29ff - - "⨀": [t: "operator kropka w kółku"] # 0x2a00 - - "⨁": [t: "operator plus w kółku"] # 0x2a01 - - "⨂": [t: "operator razy w kółku"] # 0x2a02 - - "⨃": [t: "operator sumy zbiorów z kropką"] # 0x2a03 - - "⨄": [t: "operator sumy zbiorów z plusem"] # 0x2a04 - - "⨅": [t: "operator kwadratowej części wspólnej"] # 0x2a05 - - "⨆": [t: "operator kwadratowej sumy zbiorów"] # 0x2a06 - - "⨇": [t: "operator podwójnej koniunkcji logicznej"] # 0x2a07 - - "⨈": [t: "dwa logiczne lub operator"] # 0x2a08 - - "⨉": [t: "razy operator"] # 0x2a09 - - "⨊": [t: "suma modulo dwa"] # 0x2a0a - - "⨋": [t: "suma z całką"] # 0x2a0b - - "⨌": [t: "operator poczwórnej całki"] # 0x2a0c - - "⨍": [t: "całka części skończonej"] # 0x2a0d - - "⨎": [t: "całka z podwójnym przekreśleniem"] # 0x2a0e - - "⨏": [t: "całka uśredniona z ukośnikiem"] # 0x2a0f - - "⨐": [t: "funkcja cyrkulacji"] # 0x2a10 - - "⨑": [t: "całka przeciwna do ruchu wskazówek zegara"] # 0x2a11 - - "⨒": [t: "całka liniowa po prostokątnej ścieżce wokół bieguna"] # 0x2a12 - - "⨓": [t: "całka liniowa po półokrągłej ścieżce wokół bieguna"] # 0x2a13 - - "⨔": [t: "całka liniowa bez pola"] # 0x2a14 - - "⨕": [t: "operator całki wokół punktu"] # 0x2a15 - - "⨖": [t: "operator całki kwaternionowej"] # 0x2a16 - - "⨗": [t: "całka ze strzałką w lewo z haczykiem"] # 0x2a17 - - "⨘": [t: "całka ze znakiem razy"] # 0x2a18 - - "⨙": [t: "całka z częścią wspólną"] # 0x2a19 - - "⨚": [t: "całka z sumą zbiorów"] # 0x2a1a - - "⨛": [t: "całka z kreską nad"] # 0x2a1b - - "⨜": [t: "całka z podkreśleniem"] # 0x2a1c - - "⨝": [t: "złączenie"] # 0x2a1d - - "⨞": [t: "duży lewy trójkąt operator"] # 0x2a1e - - "⨟": [t: "składanie schematów w notacji Z"] # 0x2a1f - - "⨠": [t: "potok schematów w notacji Z"] # 0x2a20 - - "⨡": [t: "rzutowanie schematów w notacji Z"] # 0x2a21 - - "⨢": [t: "znak plus z okręgiem nad"] # 0x2a22 - - "⨣": [t: "znak plus z daszkiem nad"] # 0x2a23 - - "⨤": [t: "znak plus z tyldą nad"] # 0x2a24 - - "⨥": [t: "znak plus z kropką pod"] # 0x2a25 - - "⨦": [t: "znak plus z tyldą pod"] # 0x2a26 - - "⨧": [t: "znak plus z indeksem dolnym dwa"] # 0x2a27 - - "⨨": [t: "znak plus z czarnym trójkątem"] # 0x2a28 - - "⨩": [t: "znak minus z przecinkiem nad"] # 0x2a29 - - "⨪": [t: "znak minus z kropką pod"] # 0x2a2a - - "⨫": [t: "znak minus z kropkami opadającymi"] # 0x2a2b - - "⨬": [t: "znak minus z kropkami wznoszącymi"] # 0x2a2c - - "⨭": [t: "znak plus w lewej połówce okręgu"] # 0x2a2d - - "⨮": [t: "znak plus w prawej połówce okręgu"] # 0x2a2e + - T: "otwórz nadzbiór" + - "⟅": [T: "lewy ogranicznik workowy w kształcie S"] # 0x27c5 + - "⟆": [T: "prawy ogranicznik workowy w kształcie S"] # 0x27c6 + - "⟇": [T: "lub z kropką wewnątrz"] # 0x27c7 + - "⟈": [T: "odwrotny ukośnik poprzedzający podzbiór"] # 0x27c8 + - "⟉": [T: "nadzbiór poprzedzający ukośnik"] # 0x27c9 + - "⟊": [T: "pionowa kreska z poziomą kreską"] # 0x27ca + - "⟋": [T: "matematyczny ukośnik wznoszący"] # 0x27cb + - "⟌": [T: "dzielenie pisemne"] # 0x27cc + - "⟍": [T: "matematyczny ukośnik opadający"] # 0x27cd + - "⟎": [T: "kwadratowa koniunkcja logiczna"] # 0x27ce + - "⟏": [T: "do kwadratu logiczne lub"] # 0x27cf + - "⟐": [T: "biały romb z wyśrodkowaną kropką"] # 0x27d0 + - "⟑": [T: "i z kropką"] # 0x27d1 + - "⟒": [T: "należy do z otwarciem u góry"] # 0x27d2 + - "⟓": [T: "prawy dolny narożnik z kropką"] # 0x27d3 + - "⟔": [T: "górny lewy narożnik z kropką"] # 0x27d4 + - "⟕": [T: "lewe złączenie zewnętrzne"] # 0x27d5 + - "⟖": [T: "prawe złączenie zewnętrzne"] # 0x27d6 + - "⟗": [T: "pełne złączenie zewnętrzne"] # 0x27d7 + - "⟘": [T: "duży górny znacznik"] # 0x27d8 + - "⟙": [T: "duży dolny znacznik"] # 0x27d9 + - "⟚": [T: "lewy i prawy podwójny znacznik dedukcji"] # 0x27da + - "⟛": [T: "lewy i prawy znacznik"] # 0x27db + - "⟜": [T: "lewa multimapa"] # 0x27dc + - "⟝": [T: "długi prawy znacznik"] # 0x27dd + - "⟞": [T: "długi lewy znacznik"] # 0x27de + - "⟟": [T: "górny znacznik z okręgiem nad"] # 0x27df + - "⟠": [T: "romb podzielony poziomą kreską"] # 0x27e0 + - "⟡": [T: "biały romb o wklęsłych bokach"] # 0x27e1 + - "⟢": [T: "biały romb o wklęsłych bokach z lewym haczykiem"] # 0x27e2 + - "⟣": [T: "biały romb o wklęsłych bokach z prawym haczykiem"] # 0x27e3 + - "⟤": [T: "biały kwadrat z lewym haczykiem"] # 0x27e4 + - "⟥": [T: "biały kwadrat z prawym haczykiem"] # 0x27e5 + - "⟦": [T: "lewy biały nawias kwadratowy"] # 0x27e6 + - "⟧": [T: "prawy biały nawias kwadratowy"] # 0x27e7 + - "⟨": [T: "lewy nawias kątowy"] # 0x27e8 + - "⟩": [T: "prawy nawias kątowy"] # 0x27e9 + - "⟪": [T: "lewy podwójny nawias kątowy"] # 0x27ea + - "⟫": [T: "prawy podwójny nawias kątowy"] # 0x27eb + - "⟬": [T: "lewy biały nawias skorupowy"] # 0x27ec + - "⟭": [T: "prawy biały nawias skorupowy"] # 0x27ed + - "⟮": [T: "lewy spłaszczony nawias"] # 0x27ee + - "⟯": [T: "prawy spłaszczony nawias"] # 0x27ef + - "⟰": [T: "poczwórna strzałka w górę"] # 0x27f0 + - "⟱": [T: "poczwórna strzałka w dół"] # 0x27f1 + - "⟲": [T: "okrężna strzałka z przerwą przeciwnie do ruchu wskazówek zegara"] # 0x27f2 + - "⟳": [T: "okrężna strzałka z przerwą zgodnie z ruchem wskazówek zegara"] # 0x27f3 + - "⟴": [T: "strzałka w prawo z plusem w kółku"] # 0x27f4 + - "⟵": [T: "długa strzałka w lewo"] # 0x27f5 + - "⟶": [T: "długa strzałka w prawo"] # 0x27f6 + - "⟷": [T: "długa strzałka w lewo i w prawo"] # 0x27f7 + - "⟸": [T: "długa podwójna strzałka w lewo"] # 0x27f8 + - "⟹": [T: "implikuje"] # 0x27f9 + - "⟺": [T: "wtedy i tylko wtedy"] # 0x27fa + - "⟻": [T: "długa strzałka w lewo od kreski"] # 0x27fb + - "⟼": [T: "długa strzałka w prawo od kreski"] # 0x27fc + - "⟽": [T: "długa podwójna strzałka w lewo od kreski"] # 0x27fd + - "⟾": [T: "długa podwójna strzałka w prawo od kreski"] # 0x27fe + - "⟿": [T: "długa falista strzałka w prawo"] # 0x27ff + - "⤀": [T: "strzałka w prawo z dwoma grotami i pionowym przekreśleniem"] # 0x2900 + - "⤁": [T: "strzałka w prawo z dwoma grotami i podwójnym pionowym przekreśleniem"] # 0x2901 + - "⤂": [T: "podwójna strzałka w lewo z pionową kreską"] # 0x2902 + - "⤃": [T: "podwójna strzałka w prawo z pionową kreską"] # 0x2903 + - "⤄": [T: "podwójna strzałka w lewo i w prawo z pionową kreską"] # 0x2904 + - "⤅": [T: "strzałka w prawo z dwoma grotami od kreski"] # 0x2905 + - "⤆": [T: "podwójna strzałka w lewo od kreski"] # 0x2906 + - "⤇": [T: "podwójna strzałka w prawo od kreski"] # 0x2907 + - "⤈": [T: "strzałka w dół z poziomą kreską"] # 0x2908 + - "⤉": [T: "strzałka w górę z poziomą kreską"] # 0x2909 + - "⤊": [T: "górny potrójny strzałka"] # 0x290a + - "⤋": [T: "dolny potrójny strzałka"] # 0x290b + - "⤌": [T: "lewy podwójny kreska strzałka"] # 0x290c + - "⤍": [T: "prawy podwójny kreska strzałka"] # 0x290d + - "⤎": [T: "lewy potrójny kreska strzałka"] # 0x290e + - "⤏": [T: "prawy potrójny kreska strzałka"] # 0x290f + - "⤐": [T: "strzałka w prawo z dwoma grotami i potrójną kreską"] # 0x2910 + - "⤑": [T: "strzałka w prawo z kropkowanym trzonem"] # 0x2911 + - "⤒": [T: "strzałka w górę do kreski"] # 0x2912 + - "⤓": [T: "strzałka w dół do kreski"] # 0x2913 + - "⤔": [T: "strzałka w prawo z ogonem i pionową kreską"] # 0x2914 + - "⤕": [T: "strzałka w prawo z ogonem i podwójną pionową kreską"] # 0x2915 + - "⤖": [T: "strzałka w prawo z dwoma grotami i ogonem"] # 0x2916 + - "⤗": [T: "strzałka w prawo z dwoma grotami, ogonem i pionowym przekreśleniem"] # 0x2917 + - "⤘": [T: "strzałka w prawo z dwoma grotami, ogonem i podwójnym pionowym przekreśleniem"] # 0x2918 + - "⤙": [T: "strzałka w lewo ogon"] # 0x2919 + - "⤚": [T: "strzałka w prawo ogon"] # 0x291a + - "⤛": [T: "lewy podwójna strzałka ogon"] # 0x291b + - "⤜": [T: "prawy podwójna strzałka ogon"] # 0x291c + - "⤝": [T: "strzałka w lewo do wypełnionego rombu"] # 0x291d + - "⤞": [T: "strzałka w prawo do wypełnionego rombu"] # 0x291e + - "⤟": [T: "strzałka w lewo od kreski do wypełnionego rombu"] # 0x291f + - "⤠": [T: "strzałka w prawo od kreski do wypełnionego rombu"] # 0x2920 + - "⤡": [T: "strzałka północno-zachodnia i południowo-wschodnia"] # 0x2921 + - "⤢": [T: "strzałka północno-wschodnia i południowo-zachodnia"] # 0x2922 + - "⤣": [T: "strzałka północno-zachodnia z hakiem"] # 0x2923 + - "⤤": [T: "strzałka północno-wschodnia z hakiem"] # 0x2924 + - "⤥": [T: "strzałka południowo-wschodnia z hakiem"] # 0x2925 + - "⤦": [T: "strzałka południowo-zachodnia z hakiem"] # 0x2926 + - "⤧": [T: "strzałka północno-zachodnia i strzałka północno-wschodnia"] # 0x2927 + - "⤨": [T: "strzałka północno-wschodnia i strzałka południowo-wschodnia"] # 0x2928 + - "⤩": [T: "strzałka południowo-wschodnia i strzałka południowo-zachodnia"] # 0x2929 + - "⤪": [T: "strzałka południowo-zachodnia i strzałka północno-zachodnia"] # 0x292a + - "⤫": [T: "ukośna wznosząca przecinająca ukośną opadającą"] # 0x292b + - "⤬": [T: "ukośna opadająca przecinająca ukośną wznoszącą"] # 0x292c + - "⤭": [T: "strzałka południowo-wschodnia przecinająca strzałkę północno-wschodnią"] # 0x292d + - "⤮": [T: "strzałka północno-wschodnia przecinająca strzałkę południowo-wschodnią"] # 0x292e + - "⤯": [T: "ukośna opadająca przecinająca strzałkę północno-wschodnią"] # 0x292f + - "⤰": [T: "ukośna wznosząca przecinająca strzałkę południowo-wschodnią"] # 0x2930 + - "⤱": [T: "strzałka północno-wschodnia przecinająca strzałkę północno-zachodnią"] # 0x2931 + - "⤲": [T: "strzałka północno-zachodnia przecinająca strzałkę północno-wschodnią"] # 0x2932 + - "⤳": [T: "falista strzałka skierowana bezpośrednio w prawo"] # 0x2933 + - "⤴": [T: "strzałka skierowana w prawo, potem zakrzywiona w górę"] # 0x2934 + - "⤵": [T: "strzałka skierowana w prawo, potem zakrzywiona w dół"] # 0x2935 + - "⤶": [T: "strzałka skierowana w dół, potem zakrzywiona w lewo"] # 0x2936 + - "⤷": [T: "strzałka skierowana w dół, potem zakrzywiona w prawo"] # 0x2937 + - "⤸": [T: "prawostronna strzałka łukowa zgodna z ruchem wskazówek zegara"] # 0x2938 + - "⤹": [T: "lewostronna strzałka łukowa przeciwna do ruchu wskazówek zegara"] # 0x2939 + - "⤺": [T: "górna strzałka łukowa przeciwna do ruchu wskazówek zegara"] # 0x293a + - "⤻": [T: "dolna strzałka łukowa przeciwna do ruchu wskazówek zegara"] # 0x293b + - "⤼": [T: "górna strzałka łukowa zgodna z ruchem wskazówek zegara z minusem"] # 0x293c + - "⤽": [T: "górna strzałka łukowa przeciwna do ruchu wskazówek zegara z plusem"] # 0x293d + - "⤾": [T: "dolna prawa strzałka półokrągła zgodna z ruchem wskazówek zegara"] # 0x293e + - "⤿": [T: "dolna lewa strzałka półokrągła przeciwna do ruchu wskazówek zegara"] # 0x293f + - "⥀": [T: "zamknięta strzałka okrężna przeciwna do ruchu wskazówek zegara"] # 0x2940 + - "⥁": [T: "zamknięta strzałka okrężna zgodna z ruchem wskazówek zegara"] # 0x2941 + - "⥂": [T: "strzałka w prawo nad krótką strzałką w lewo"] # 0x2942 + - "⥃": [T: "strzałka w lewo nad krótką strzałką w prawo"] # 0x2943 + - "⥄": [T: "krótka strzałka w prawo nad strzałką w lewo"] # 0x2944 + - "⥅": [T: "strzałka w prawo z plusem pod spodem"] # 0x2945 + - "⥆": [T: "strzałka w lewo z plusem pod spodem"] # 0x2946 + - "⥇": [T: "strzałka w prawo przez X"] # 0x2947 + - "⥈": [T: "strzałka w lewo i w prawo przez okrąg"] # 0x2948 + - "⥉": [T: "strzałka w górę z dwoma grotami od okręgu"] # 0x2949 + - "⥊": [T: "lewy grot górny prawy grot dolny harpun"] # 0x294a + - "⥋": [T: "lewy grot dolny prawy grot górny harpun"] # 0x294b + - "⥌": [T: "górny grot prawy dolny grot lewy harpun"] # 0x294c + - "⥍": [T: "górny grot lewy dolny grot prawy harpun"] # 0x294d + - "⥎": [T: "lewy grot górny prawy grot górny harpun"] # 0x294e + - "⥏": [T: "górny grot prawy dolny grot prawy harpun"] # 0x294f + - "⥐": [T: "lewy grot dolny prawy grot dolny harpun"] # 0x2950 + - "⥑": [T: "górny grot lewy dolny grot lewy harpun"] # 0x2951 + - "⥒": [T: "lewy harpun z grotem górnym do kreski"] # 0x2952 + - "⥓": [T: "prawy harpun z grotem górnym do kreski"] # 0x2953 + - "⥔": [T: "górny harpun z grotem prawym do kreski"] # 0x2954 + - "⥕": [T: "dolny harpun z grotem prawym do kreski"] # 0x2955 + - "⥖": [T: "lewy harpun z grotem dolnym do kreski"] # 0x2956 + - "⥗": [T: "prawy harpun z grotem dolnym do kreski"] # 0x2957 + - "⥘": [T: "górny harpun z grotem lewym do kreski"] # 0x2958 + - "⥙": [T: "dolny harpun z grotem lewym do kreski"] # 0x2959 + - "⥚": [T: "lewy harpun z grotem górnym od kreski"] # 0x295a + - "⥛": [T: "prawy harpun z grotem górnym od kreski"] # 0x295b + - "⥜": [T: "górny harpun z grotem prawym od kreski"] # 0x295c + - "⥝": [T: "dolny harpun z grotem prawym od kreski"] # 0x295d + - "⥞": [T: "lewy harpun z grotem dolnym od kreski"] # 0x295e + - "⥟": [T: "prawy harpun z grotem dolnym od kreski"] # 0x295f + - "⥠": [T: "górny harpun z grotem lewym od kreski"] # 0x2960 + - "⥡": [T: "dolny harpun z grotem lewym od kreski"] # 0x2961 + - "⥢": [T: "lewy harpun z grotem górnym nad lewy harpun z grotem dolnym"] # 0x2962 + - "⥣": [T: "górny harpun z grotem w lewo obok górnego harpuna z grotem w prawo"] # 0x2963 + - "⥤": [T: "prawy harpun z grotem górnym nad prawy harpun z grotem dolnym"] # 0x2964 + - "⥥": [T: "dolny harpun z grotem w lewo obok dolnego harpuna z grotem w prawo"] # 0x2965 + - "⥦": [T: "lewy harpun z grotem górnym nad prawy harpun z grotem górnym"] # 0x2966 + - "⥧": [T: "lewy harpun z grotem dolnym nad prawy harpun z grotem dolnym"] # 0x2967 + - "⥨": [T: "prawy harpun z grotem górnym nad lewy harpun z grotem górnym"] # 0x2968 + - "⥩": [T: "prawy harpun z grotem dolnym nad lewy harpun z grotem dolnym"] # 0x2969 + - "⥪": [T: "lewy harpun z grotem górnym nad długą kreską"] # 0x296a + - "⥫": [T: "lewy harpun z grotem dolnym pod długą kreską"] # 0x296b + - "⥬": [T: "prawy harpun z grotem górnym nad długą kreską"] # 0x296c + - "⥭": [T: "prawy harpun z grotem dolnym pod długą kreską"] # 0x296d + - "⥮": [T: "górny harpun z grotem w lewo obok dolnego harpuna z grotem w prawo"] # 0x296e + - "⥯": [T: "dolny harpun z grotem w lewo obok górnego harpuna z grotem w prawo"] # 0x296f + - "⥰": [T: "podwójna strzałka w prawo z zaokrąglonym grotem"] # 0x2970 + - "⥱": [T: "równa się nad strzałka w prawo"] # 0x2971 + - "⥲": [T: "operator tyldy nad strzałką w prawo"] # 0x2972 + - "⥳": [T: "strzałka w lewo nad operatorem tyldy"] # 0x2973 + - "⥴": [T: "strzałka w prawo nad operatorem tyldy"] # 0x2974 + - "⥵": [T: "strzałka w prawo nad znakiem przybliżonej równości"] # 0x2975 + - "⥶": [T: "mniejsze niż nad strzałka w lewo"] # 0x2976 + - "⥷": [T: "strzałka w lewo przez znak mniejsze niż"] # 0x2977 + - "⥸": [T: "większe niż nad strzałka w prawo"] # 0x2978 + - "⥹": [T: "podzbiór nad strzałka w prawo"] # 0x2979 + - "⥺": [T: "strzałka w lewo przez znak podzbioru"] # 0x297a + - "⥻": [T: "nadzbiór nad strzałka w lewo"] # 0x297b + - "⥼": [T: "lewy rybi ogon"] # 0x297c + - "⥽": [T: "prawy rybi ogon"] # 0x297d + - "⥾": [T: "górny rybi ogon"] # 0x297e + - "⥿": [T: "dolny rybi ogon"] # 0x297f + - "⦀": [T: "potrójna pionowa kreska jako ogranicznik"] # 0x2980 + - "⦁": [T: "punkt w notacji Z"] # 0x2981 + - "⦂": [T: "dwukropek typu w notacji Z"] # 0x2982 + - "⦃": [T: "lewy biały nawias klamrowy"] # 0x2983 + - "⦄": [T: "prawy biały nawias klamrowy"] # 0x2984 + - "⦅": [T: "lewy biały nawias"] # 0x2985 + - "⦆": [T: "prawy biały nawias"] # 0x2986 + - "⦇": [T: "lewy nawias kwadratowy obrazu w notacji Z"] # 0x2987 + - "⦈": [T: "prawy nawias kwadratowy obrazu w notacji Z"] # 0x2988 + - "⦉": [T: "lewy nawias kwadratowy wiązania w notacji Z"] # 0x2989 + - "⦊": [T: "prawy nawias kwadratowy wiązania w notacji Z"] # 0x298a + - "⦋": [T: "lewy nawias kwadratowy z podkreśleniem"] # 0x298b + - "⦌": [T: "prawy nawias kwadratowy z podkreśleniem"] # 0x298c + - "⦍": [T: "lewy nawias kwadratowy z haczykiem w górnym rogu"] # 0x298d + - "⦎": [T: "prawy nawias kwadratowy z haczykiem w dolnym rogu"] # 0x298e + - "⦏": [T: "lewy nawias kwadratowy z haczykiem w dolnym rogu"] # 0x298f + - "⦐": [T: "prawy nawias kwadratowy z haczykiem w górnym rogu"] # 0x2990 + - "⦑": [T: "lewy kąt nawias kwadratowy z kropką"] # 0x2991 + - "⦒": [T: "prawy nawias kątowy z kropką"] # 0x2992 + - "⦓": [T: "lewy łuk mniejsze niż nawias kwadratowy"] # 0x2993 + - "⦔": [T: "prawy łuk większe niż nawias kwadratowy"] # 0x2994 + - "⦕": [T: "podwójny lewy łuk większe niż nawias kwadratowy"] # 0x2995 + - "⦖": [T: "podwójny prawy łuk mniejsze niż nawias kwadratowy"] # 0x2996 + - "⦗": [T: "lewy czarny nawias skorupowy"] # 0x2997 + - "⦘": [T: "prawy czarny nawias skorupowy"] # 0x2998 + - "⦙": [T: "kropkowany ogranicznik"] # 0x2999 + - "⦚": [T: "pionowa linia zygzakowata"] # 0x299a + - "⦛": [T: "kąt mierzony otwarty w lewo"] # 0x299b + - "⦜": [T: "wariant kąta prostego z kwadratem"] # 0x299c + - "⦝": [T: "mierzony kąt prosty z kropką"] # 0x299d + - "⦞": [T: "kąt z s wewnątrz"] # 0x299e + - "⦟": [T: "akut kąt"] # 0x299f + - "⦠": [T: "kąt sferyczny otwarty w lewo"] # 0x29a0 + - "⦡": [T: "kąt sferyczny otwarty w górę"] # 0x29a1 + - "⦢": [T: "odwrócony kąt"] # 0x29a2 + - "⦣": [T: "kąt odwrócony"] # 0x29a3 + - "⦤": [T: "kąt z podkreśleniem"] # 0x29a4 + - "⦥": [T: "kąt odwrócony z podkreśleniem"] # 0x29a5 + - "⦦": [T: "kąt ukośny otwarty w górę"] # 0x29a6 + - "⦧": [T: "kąt ukośny otwarty w dół"] # 0x29a7 + - "⦨": [T: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w górę i w prawo"] # 0x29a8 + - "⦩": [T: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w górę i w lewo"] # 0x29a9 + - "⦪": [T: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w dół i w prawo"] # 0x29aa + - "⦫": [T: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w dół i w lewo"] # 0x29ab + - "⦬": [T: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w prawo i w górę"] # 0x29ac + - "⦭": [T: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w lewo i w górę"] # 0x29ad + - "⦮": [T: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w prawo i w dół"] # 0x29ae + - "⦯": [T: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w lewo i w dół"] # 0x29af + - "⦰": [T: "odwrócony zbiór pusty"] # 0x29b0 + - "⦱": [T: "zbiór pusty z kreską nad"] # 0x29b1 + - "⦲": [T: "zbiór pusty z małym okręgiem nad"] # 0x29b2 + - "⦳": [T: "zbiór pusty ze strzałką w prawo nad"] # 0x29b3 + - "⦴": [T: "zbiór pusty ze strzałką w lewo nad"] # 0x29b4 + - "⦵": [T: "okrąg z kreską poziomą"] # 0x29b5 + - "⦶": [T: "pionowa kreska w kółku"] # 0x29b6 + - "⦷": [T: "w kółku równoległe"] # 0x29b7 + - "⦸": [T: "ukośnik odwrotny w kółku"] # 0x29b8 + - "⦹": [T: "w kółku prostopadłe"] # 0x29b9 + - "⦺": [T: "okrąg podzielony kreską poziomą, z górną połową podzieloną kreską pionową"] # 0x29ba + - "⦻": [T: "okrąg z nałożonym X"] # 0x29bb + - "⦼": [T: "znak dzielenia w kółku obrócony przeciwnie do ruchu wskazówek zegara"] # 0x29bc + - "⦽": [T: "strzałka w górę przez okrąg"] # 0x29bd + - "⦾": [T: "w kółku biały punkt"] # 0x29be + - "⦿": [T: "w kółku punkt"] # 0x29bf + - "⧀": [T: "w kółku mniejsze niż"] # 0x29c0 + - "⧁": [T: "w kółku większe niż"] # 0x29c1 + - "⧂": [T: "okrąg z małym okręgiem po prawej"] # 0x29c2 + - "⧃": [T: "okrąg z dwiema poziomymi kreskami po prawej"] # 0x29c3 + - "⧄": [T: "kwadrat z ukośnikiem wznoszącym"] # 0x29c4 + - "⧅": [T: "kwadrat z ukośnikiem opadającym"] # 0x29c5 + - "⧆": [T: "do kwadratu gwiazdka"] # 0x29c6 + - "⧇": [T: "do kwadratu mały okrąg"] # 0x29c7 + - "⧈": [T: "do kwadratu kwadrat"] # 0x29c8 + - "⧉": [T: "dwa połączone kwadraty"] # 0x29c9 + - "⧊": [T: "trójkąt z kropką nad"] # 0x29ca + - "⧋": [T: "trójkąt z podkreśleniem"] # 0x29cb + - "⧌": [T: "s w trójkąt"] # 0x29cc + - "⧍": [T: "trójkąt z szeryfami u dołu"] # 0x29cd + - "⧎": [T: "prawy trójkąt nad lewy trójkąt"] # 0x29ce + - "⧏": [T: "lewy trójkąt obok pionowej kreski"] # 0x29cf + - "⧐": [T: "pionowa kreska obok prawego trójkąta"] # 0x29d0 + - "⧑": [T: "kokarda z lewą połową czarną"] # 0x29d1 + - "⧒": [T: "kokarda z prawą połową czarną"] # 0x29d2 + - "⧓": [T: "czarna kokarda"] # 0x29d3 + - "⧔": [T: "znak mnożenia z lewą połową czarną"] # 0x29d4 + - "⧕": [T: "znak mnożenia z prawą połową czarną"] # 0x29d5 + - "⧖": [T: "biały klepsydra"] # 0x29d6 + - "⧗": [T: "czarny klepsydra"] # 0x29d7 + - "⧘": [T: "lewy falisty ogranicznik"] # 0x29d8 + - "⧙": [T: "prawy falisty ogranicznik"] # 0x29d9 + - "⧚": [T: "lewy podwójny falisty ogranicznik"] # 0x29da + - "⧛": [T: "prawy podwójny falisty ogranicznik"] # 0x29db + - "⧜": [T: "niepełna nieskończoność"] # 0x29dc + - "⧝": [T: "wiązanie nad nieskończonością"] # 0x29dd + - "⧞": [T: "zanegowana nieskończoność z kreską pionową"] # 0x29de + - "⧟": [T: "podwójnie zakończona strzałka mapująca"] # 0x29df + - "⧠": [T: "kwadrat z konturowym obrysem"] # 0x29e0 + - "⧡": [T: "wzrasta jak"] # 0x29e1 + - "⧢": [T: "iloczyn przetasowania"] # 0x29e2 + - "⧣": [T: "znak równości i ukośne równoległe"] # 0x29e3 + - "⧤": [T: "znak równości i ukośne równoległe z tyldą nad"] # 0x29e4 + - "⧥": [T: "identyczne i ukośne równoległe"] # 0x29e5 + - "⧦": [T: "równoliczne"] # 0x29e6 + - "⧧": [T: "termodynamiczny"] # 0x29e7 + - "⧨": [T: "trójkąt skierowany w dół z lewą połową czarną"] # 0x29e8 + - "⧩": [T: "trójkąt skierowany w dół z prawą połową czarną"] # 0x29e9 + - "⧪": [T: "czarny romb ze strzałką w dół"] # 0x29ea + - "⧫": [T: "czarny romb"] # 0x29eb + - "⧬": [T: "białe koło ze strzałką w dół"] # 0x29ec + - "⧭": [T: "czarne koło ze strzałką w dół"] # 0x29ed + - "⧮": [T: "biały kwadrat z przekreśleniem błędu"] # 0x29ee + - "⧯": [T: "czarny kwadrat z przekreśleniem błędu"] # 0x29ef + - "⧰": [T: "biały romb z przekreśleniem błędu"] # 0x29f0 + - "⧱": [T: "czarny romb z przekreśleniem błędu"] # 0x29f1 + - "⧲": [T: "białe koło z przekreśleniem błędu"] # 0x29f2 + - "⧳": [T: "czarne koło z przekreśleniem błędu"] # 0x29f3 + - "⧴": [T: "opóźniona reguła"] # 0x29f4 + - "⧵": [T: "operator ukośnika odwrotnego"] # 0x29f5 + - "⧶": [T: "ukośnik z kreską nad"] # 0x29f6 + - "⧷": [T: "ukośnik odwrotny z poziomą kreską"] # 0x29f7 + - "⧸": [T: "duży ukośnik"] # 0x29f8 + - "⧹": [T: "duży ukośnik odwrotny"] # 0x29f9 + - "⧺": [T: "podwójny plus"] # 0x29fa + - "⧻": [T: "potrójny plus"] # 0x29fb + - "⧼": [T: "lewy zakrzywiony nawias kątowy"] # 0x29fc + - "⧽": [T: "prawy zakrzywiony nawias kątowy"] # 0x29fd + - "⧾": [T: "maleńki"] # 0x29fe + - "⧿": [T: "mini"] # 0x29ff + - "⨀": [T: "operator kropka w kółku"] # 0x2a00 + - "⨁": [T: "operator plus w kółku"] # 0x2a01 + - "⨂": [T: "operator razy w kółku"] # 0x2a02 + - "⨃": [T: "operator sumy zbiorów z kropką"] # 0x2a03 + - "⨄": [T: "operator sumy zbiorów z plusem"] # 0x2a04 + - "⨅": [T: "operator kwadratowej części wspólnej"] # 0x2a05 + - "⨆": [T: "operator kwadratowej sumy zbiorów"] # 0x2a06 + - "⨇": [T: "operator podwójnej koniunkcji logicznej"] # 0x2a07 + - "⨈": [T: "dwa logiczne lub operator"] # 0x2a08 + - "⨉": [T: "razy operator"] # 0x2a09 + - "⨊": [T: "suma modulo dwa"] # 0x2a0a + - "⨋": [T: "suma z całką"] # 0x2a0b + - "⨌": [T: "operator poczwórnej całki"] # 0x2a0c + - "⨍": [T: "całka części skończonej"] # 0x2a0d + - "⨎": [T: "całka z podwójnym przekreśleniem"] # 0x2a0e + - "⨏": [T: "całka uśredniona z ukośnikiem"] # 0x2a0f + - "⨐": [T: "funkcja cyrkulacji"] # 0x2a10 + - "⨑": [T: "całka przeciwna do ruchu wskazówek zegara"] # 0x2a11 + - "⨒": [T: "całka liniowa po prostokątnej ścieżce wokół bieguna"] # 0x2a12 + - "⨓": [T: "całka liniowa po półokrągłej ścieżce wokół bieguna"] # 0x2a13 + - "⨔": [T: "całka liniowa bez pola"] # 0x2a14 + - "⨕": [T: "operator całki wokół punktu"] # 0x2a15 + - "⨖": [T: "operator całki kwaternionowej"] # 0x2a16 + - "⨗": [T: "całka ze strzałką w lewo z haczykiem"] # 0x2a17 + - "⨘": [T: "całka ze znakiem razy"] # 0x2a18 + - "⨙": [T: "całka z częścią wspólną"] # 0x2a19 + - "⨚": [T: "całka z sumą zbiorów"] # 0x2a1a + - "⨛": [T: "całka z kreską nad"] # 0x2a1b + - "⨜": [T: "całka z podkreśleniem"] # 0x2a1c + - "⨝": [T: "złączenie"] # 0x2a1d + - "⨞": [T: "duży lewy trójkąt operator"] # 0x2a1e + - "⨟": [T: "składanie schematów w notacji Z"] # 0x2a1f + - "⨠": [T: "potok schematów w notacji Z"] # 0x2a20 + - "⨡": [T: "rzutowanie schematów w notacji Z"] # 0x2a21 + - "⨢": [T: "znak plus z okręgiem nad"] # 0x2a22 + - "⨣": [T: "znak plus z daszkiem nad"] # 0x2a23 + - "⨤": [T: "znak plus z tyldą nad"] # 0x2a24 + - "⨥": [T: "znak plus z kropką pod"] # 0x2a25 + - "⨦": [T: "znak plus z tyldą pod"] # 0x2a26 + - "⨧": [T: "znak plus z indeksem dolnym dwa"] # 0x2a27 + - "⨨": [T: "znak plus z czarnym trójkątem"] # 0x2a28 + - "⨩": [T: "znak minus z przecinkiem nad"] # 0x2a29 + - "⨪": [T: "znak minus z kropką pod"] # 0x2a2a + - "⨫": [T: "znak minus z kropkami opadającymi"] # 0x2a2b + - "⨬": [T: "znak minus z kropkami wznoszącymi"] # 0x2a2c + - "⨭": [T: "znak plus w lewej połówce okręgu"] # 0x2a2d + - "⨮": [T: "znak plus w prawej połówce okręgu"] # 0x2a2e - "⨯": # 0x2a2f - test: if: "$Verbosity='Terse'" - then: [t: "krzyż"] - else: [t: "krzyż iloczyn"] - - "⨰": [t: "znak mnożenia z kropką nad"] # 0x2a30 - - "⨱": [t: "znak mnożenia z podkreśleniem"] # 0x2a31 - - "⨲": [t: "iloczyn półprosty domknięty od dołu"] # 0x2a32 - - "⨳": [t: "iloczyn spłaszczony"] # 0x2a33 - - "⨴": [t: "znak mnożenia w lewej połówce okręgu"] # 0x2a34 - - "⨵": [t: "znak mnożenia w prawej połówce okręgu"] # 0x2a35 - - "⨶": [t: "znak mnożenia w kółku z daszkiem"] # 0x2a36 - - "⨷": [t: "znak mnożenia w podwójnym okręgu"] # 0x2a37 - - "⨸": [t: "znak dzielenia w kółku"] # 0x2a38 - - "⨹": [t: "znak plus w trójkącie"] # 0x2a39 - - "⨺": [t: "znak minus w trójkącie"] # 0x2a3a - - "⨻": [t: "znak mnożenia w trójkącie"] # 0x2a3b - - "⨼": [t: "iloczyn wewnętrzny"] # 0x2a3c - - "⨽": [t: "prawostronny iloczyn wewnętrzny"] # 0x2a3d - - "⨾": [t: "składanie relacji w notacji Z"] # 0x2a3e - - "⨿": [t: "amalgamacja lub koprodukt"] # 0x2a3f - - "⩀": [t: "część wspólna z kropką"] # 0x2a40 - - "⩁": [t: "suma zbiorów ze znakiem minus"] # 0x2a41 - - "⩂": [t: "suma zbiorów z kreską nad"] # 0x2a42 - - "⩃": [t: "część wspólna z kreską nad"] # 0x2a43 - - "⩄": [t: "część wspólna z koniunkcją logiczną"] # 0x2a44 - - "⩅": [t: "suma zbiorów z alternatywą logiczną"] # 0x2a45 - - "⩆": [t: "suma zbiorów nad część wspólna"] # 0x2a46 - - "⩇": [t: "część wspólna nad suma zbiorów"] # 0x2a47 - - "⩈": [t: "suma zbiorów nad kreska nad część wspólna"] # 0x2a48 - - "⩉": [t: "część wspólna nad kreska nad suma zbiorów"] # 0x2a49 - - "⩊": [t: "suma zbiorów obok sumy zbiorów połączona kreską"] # 0x2a4a - - "⩋": [t: "część wspólna obok części wspólnej połączona kreską"] # 0x2a4b - - "⩌": [t: "zamknięta suma zbiorów z szeryfami"] # 0x2a4c - - "⩍": [t: "zamknięta część wspólna z szeryfami"] # 0x2a4d - - "⩎": [t: "podwójny kwadrat część wspólna"] # 0x2a4e - - "⩏": [t: "podwójny kwadrat suma zbiorów"] # 0x2a4f - - "⩐": [t: "zamknięta suma zbiorów z szeryfami i iloczynem spłaszczonym"] # 0x2a50 - - "⩑": [t: "koniunkcja logiczna z kropką nad"] # 0x2a51 - - "⩒": [t: "logiczne lub z kropką nad"] # 0x2a52 - - "⩓": [t: "podwójna koniunkcja logiczna"] # 0x2a53 - - "⩔": [t: "podwójny logiczne lub"] # 0x2a54 - - "⩕": [t: "dwa przecinające się logiczne i"] # 0x2a55 - - "⩖": [t: "dwa przecinające się logiczne lub"] # 0x2a56 - - "⩗": [t: "skośne duże lub"] # 0x2a57 - - "⩘": [t: "skośne duże i"] # 0x2a58 - - "⩙": [t: "logiczne lub nakładające się na logiczne i"] # 0x2a59 - - "⩚": [t: "logiczne i ze środkowym trzonem"] # 0x2a5a - - "⩛": [t: "logiczne lub ze środkowym trzonem"] # 0x2a5b - - "⩜": [t: "koniunkcja logiczna z poziomą kreską"] # 0x2a5c - - "⩝": [t: "alternatywa logiczna z poziomą kreską"] # 0x2a5d - - "⩞": [t: "logiczne i z podwójną kreską nad"] # 0x2a5e - - "⩟": [t: "koniunkcja logiczna z podkreśleniem"] # 0x2a5f - - "⩠": [t: "logiczne i z podwójną kreską pod"] # 0x2a60 - - "⩡": [t: "małe logiczne lub z podkreśleniem"] # 0x2a61 - - "⩢": [t: "logiczne lub z podwójną kreską nad"] # 0x2a62 - - "⩣": [t: "logiczne lub z podwójną kreską pod"] # 0x2a63 - - "⩤": [t: "antyograniczenie dziedziny w notacji Z"] # 0x2a64 - - "⩥": [t: "antyograniczenie przeciwdziedziny w notacji Z"] # 0x2a65 - - "⩦": [t: "znak równości z kropką pod spodem"] # 0x2a66 - - "⩧": [t: "identyczne z kropką nad"] # 0x2a67 - - "⩨": [t: "potrójna kreska pozioma z podwójną pionową kreską"] # 0x2a68 - - "⩩": [t: "potrójna kreska pozioma z potrójną pionową kreską"] # 0x2a69 - - "⩪": [t: "operator tyldy z kropką nad"] # 0x2a6a - - "⩫": [t: "operator tyldy ze wznoszącymi kropkami"] # 0x2a6b - - "⩬": [t: "podobne minus podobne"] # 0x2a6c - - "⩭": [t: "przystające z kropką nad"] # 0x2a6d - - "⩮": [t: "równa się z gwiazdką"] # 0x2a6e - - "⩯": [t: "w przybliżeniu równe z daszkiem"] # 0x2a6f - - "⩰": [t: "w przybliżeniu równe lub równe"] # 0x2a70 - - "⩱": [t: "znak równości nad znakiem plus"] # 0x2a71 - - "⩲": [t: "znak plus nad znakiem równości"] # 0x2a72 - - "⩳": [t: "znak równości nad operatorem tyldy"] # 0x2a73 - - "⩴": [t: "podwójny dwukropek równe"] # 0x2a74 - - "⩵": [t: "dwa kolejne znaki równości"] # 0x2a75 - - "⩶": [t: "trzy kolejne znaki równości"] # 0x2a76 - - "⩷": [t: "znak równości z dwiema kropkami nad i dwiema kropkami pod"] # 0x2a77 - - "⩸": [t: "równoważne z czterema kropkami nad"] # 0x2a78 - - "⩹": [t: "mniejsze niż z okrąg wewnątrz"] # 0x2a79 - - "⩺": [t: "większe niż z okrąg wewnątrz"] # 0x2a7a - - "⩻": [t: "mniejsze niż ze znakiem zapytania nad"] # 0x2a7b - - "⩼": [t: "większe niż ze znakiem zapytania nad"] # 0x2a7c - - "⩽": [t: "mniejsze niż lub ukośnie równe"] # 0x2a7d - - "⩾": [t: "większe niż lub ukośnie równe"] # 0x2a7e - - "⩿": [t: "mniejsze niż lub ukośnie równe z kropką wewnątrz"] # 0x2a7f - - "⪀": [t: "większe niż lub ukośnie równe z kropką wewnątrz"] # 0x2a80 - - "⪁": [t: "mniejsze niż lub ukośnie równe z kropką nad"] # 0x2a81 - - "⪂": [t: "większe niż lub ukośnie równe z kropką nad"] # 0x2a82 - - "⪃": [t: "mniejsze niż lub ukośnie równe z kropką nad prawą stroną"] # 0x2a83 - - "⪄": [t: "większe niż lub ukośnie równe z kropką nad lewą stroną"] # 0x2a84 - - "⪅": [t: "mniejsze niż lub przybliżone"] # 0x2a85 - - "⪆": [t: "większe niż lub przybliżone"] # 0x2a86 - - "⪇": [t: "mniejsze niż z pojedynczą linią nierówności"] # 0x2a87 - - "⪈": [t: "większe niż z pojedynczą linią nierówności"] # 0x2a88 - - "⪉": [t: "mniejsze niż i nie przybliżone"] # 0x2a89 - - "⪊": [t: "większe niż i nie przybliżone"] # 0x2a8a - - "⪋": [t: "mniejsze niż nad podwójną linią równości nad większe niż"] # 0x2a8b - - "⪌": [t: "większe niż nad podwójną linią równości nad mniejsze niż"] # 0x2a8c - - "⪍": [t: "mniejsze niż nad podobne lub równe"] # 0x2a8d - - "⪎": [t: "większe niż nad podobne lub równe"] # 0x2a8e - - "⪏": [t: "mniejsze niż nad podobne nad większe niż"] # 0x2a8f - - "⪐": [t: "większe niż nad podobne nad mniejsze niż"] # 0x2a90 - - "⪑": [t: "mniejsze niż nad większe niż nad podwójną linią równości"] # 0x2a91 - - "⪒": [t: "większe niż nad mniejsze niż nad podwójną linią równości"] # 0x2a92 - - "⪓": [t: "mniejsze niż nad ukośnie równe nad większe niż nad ukośnie równe"] # 0x2a93 - - "⪔": [t: "większe niż nad ukośnie równe nad mniejsze niż nad ukośnie równe"] # 0x2a94 - - "⪕": [t: "ukośnie równe lub mniejsze niż"] # 0x2a95 - - "⪖": [t: "ukośnie równe lub większe niż"] # 0x2a96 - - "⪗": [t: "ukośnie równe lub mniejsze niż z kropką wewnątrz"] # 0x2a97 - - "⪘": [t: "ukośnie równe lub większe niż z kropką wewnątrz"] # 0x2a98 - - "⪙": [t: "podwójna linia równa lub mniejsze niż"] # 0x2a99 - - "⪚": [t: "podwójna linia równa lub większe niż"] # 0x2a9a - - "⪛": [t: "podwójna linia ukośnie równa lub mniejsze niż"] # 0x2a9b - - "⪜": [t: "podwójna linia ukośnie równa lub większe niż"] # 0x2a9c - - "⪝": [t: "podobne lub mniejsze niż"] # 0x2a9d - - "⪞": [t: "podobne lub większe niż"] # 0x2a9e - - "⪟": [t: "podobne nad mniejsze niż nad znakiem równości"] # 0x2a9f - - "⪠": [t: "podobne nad większe niż nad znakiem równości"] # 0x2aa0 - - "⪡": [t: "podwójnie zagnieżdżone mniejsze niż"] # 0x2aa1 - - "⪢": [t: "podwójnie zagnieżdżone większe niż"] # 0x2aa2 - - "⪣": [t: "podwójnie zagnieżdżone mniejsze niż z podkreśleniem"] # 0x2aa3 - - "⪤": [t: "większe niż nakładające się na mniejsze niż"] # 0x2aa4 - - "⪥": [t: "większe niż obok mniejsze niż"] # 0x2aa5 - - "⪦": [t: "mniejsze niż zamknięte krzywą"] # 0x2aa6 - - "⪧": [t: "większe niż zamknięte krzywą"] # 0x2aa7 - - "⪨": [t: "mniejsze niż zamknięte krzywą nad ukośnie równe"] # 0x2aa8 - - "⪩": [t: "większe niż zamknięte krzywą nad ukośnie równe"] # 0x2aa9 - - "⪪": [t: "mniejsze niż"] # 0x2aaa - - "⪫": [t: "większe niż"] # 0x2aab - - "⪬": [t: "mniejsze niż lub równe"] # 0x2aac - - "⪭": [t: "większe niż lub równe"] # 0x2aad - - "⪮": [t: "znak równości z garbem nad"] # 0x2aae - - "⪯": [t: "poprzedza nad pojedynczą linią równości"] # 0x2aaf - - "⪰": [t: "następuje po nad pojedynczą linią równości"] # 0x2ab0 - - "⪱": [t: "poprzedza nad pojedynczą linią nierówności"] # 0x2ab1 - - "⪲": [t: "następuje po nad pojedynczy linia nie równa się"] # 0x2ab2 - - "⪳": [t: "poprzedza nad znakiem równości"] # 0x2ab3 - - "⪴": [t: "następuje po nad znakiem równości"] # 0x2ab4 - - "⪵": [t: "poprzedza nad nie równa się"] # 0x2ab5 - - "⪶": [t: "następuje po nad nie równa się"] # 0x2ab6 - - "⪷": [t: "poprzedza nad znakiem przybliżonej równości"] # 0x2ab7 - - "⪸": [t: "następuje po nad znakiem przybliżonej równości"] # 0x2ab8 - - "⪹": [t: "poprzedza nad znakiem nie w przybliżeniu równe"] # 0x2ab9 - - "⪺": [t: "następuje po nad znakiem nie w przybliżeniu równe"] # 0x2aba - - "⪻": [t: "podwójny poprzedza"] # 0x2abb - - "⪼": [t: "podwójny następuje po"] # 0x2abc - - "⪽": [t: "podzbiór z kropką"] # 0x2abd - - "⪾": [t: "nadzbiór z kropką"] # 0x2abe - - "⪿": [t: "podzbiór ze znakiem plus pod spodem"] # 0x2abf - - "⫀": [t: "nadzbiór ze znakiem plus pod spodem"] # 0x2ac0 - - "⫁": [t: "podzbiór ze znakiem mnożenia pod"] # 0x2ac1 - - "⫂": [t: "nadzbiór ze znakiem mnożenia pod"] # 0x2ac2 - - "⫃": [t: "podzbiór lub równy z kropką nad"] # 0x2ac3 - - "⫄": [t: "nadzbiór lub równy z kropką nad"] # 0x2ac4 - - "⫅": [t: "podzbiór nad znakiem równości"] # 0x2ac5 - - "⫆": [t: "nadzbiór nad znakiem równości"] # 0x2ac6 - - "⫇": [t: "podzbiór nad operatorem tyldy"] # 0x2ac7 - - "⫈": [t: "nadzbiór nad operatorem tyldy"] # 0x2ac8 - - "⫉": [t: "podzbiór nad znakiem przybliżonej równości"] # 0x2ac9 - - "⫊": [t: "nadzbiór nad znakiem przybliżonej równości"] # 0x2aca - - "⫋": [t: "podzbiór nad nie równa się"] # 0x2acb - - "⫌": [t: "nadzbiór nad nie równa się"] # 0x2acc - - "⫍": [t: "kwadrat lewy otwórz ramka operator"] # 0x2acd - - "⫎": [t: "kwadrat prawy otwórz ramka operator"] # 0x2ace - - "⫏": [t: "zamknięty podzbiór"] # 0x2acf - - "⫐": [t: "zamknięty nadzbiór"] # 0x2ad0 - - "⫑": [t: "zamknięty podzbiór lub równe"] # 0x2ad1 - - "⫒": [t: "zamknięty nadzbiór lub równe"] # 0x2ad2 - - "⫓": [t: "podzbiór nad nadzbiór"] # 0x2ad3 - - "⫔": [t: "nadzbiór nad podzbiór"] # 0x2ad4 - - "⫕": [t: "podzbiór nad podzbiór"] # 0x2ad5 - - "⫖": [t: "nadzbiór nad nadzbiór"] # 0x2ad6 - - "⫗": [t: "nadzbiór obok podzbioru"] # 0x2ad7 - - "⫘": [t: "nadzbiór obok podzbioru połączony kreską"] # 0x2ad8 - - "⫙": [t: "należy do otwarte od dołu"] # 0x2ad9 - - "⫚": [t: "widły z górną poprzeczką"] # 0x2ada - - "⫛": [t: "poprzeczna część wspólna"] # 0x2adb - - "⫝̸": [t: "rozwidlanie"] # 0x2adc - - "⫝": [t: "nierozwidlanie"] # 0x2add - - "⫞": [t: "krótki lewy znacznik"] # 0x2ade - - "⫟": [t: "krótki dolny znacznik"] # 0x2adf - - "⫠": [t: "krótki górny znacznik"] # 0x2ae0 - - "⫡": [t: "prostopadłe z literą s"] # 0x2ae1 - - "⫢": [t: "pionowa kreska z potrójnym prawym znacznikiem dedukcji"] # 0x2ae2 - - "⫣": [t: "podwójna pionowa kreska z lewym znacznikiem dedukcji"] # 0x2ae3 - - "⫤": [t: "pionowa kreska z podwójnym lewym znacznikiem dedukcji"] # 0x2ae4 - - "⫥": [t: "podwójna pionowa kreska z podwójnym lewym znacznikiem dedukcji"] # 0x2ae5 - - "⫦": [t: "długa kreska od lewego elementu z podwójną pionową kreską"] # 0x2ae6 - - "⫧": [t: "krótki dolny znacznik z kreską nad"] # 0x2ae7 - - "⫨": [t: "krótki górny znacznik z podkreśleniem"] # 0x2ae8 - - "⫩": [t: "krótki górny znacznik nad krótkim dolnym znacznikiem"] # 0x2ae9 - - "⫪": [t: "podwójny dolny znacznik"] # 0x2aea - - "⫫": [t: "podwójny górny znacznik"] # 0x2aeb - - "⫬": [t: "znak negacji z podwójnym przekreśleniem"] # 0x2aec - - "⫭": [t: "odwrócony znak negacji z podwójnym przekreśleniem"] # 0x2aed - - "⫮": [t: "nie dzieli z odwróconym ukośnikiem negacji"] # 0x2aee - - "⫯": [t: "pionowa linia z okręgiem nad"] # 0x2aef - - "⫰": [t: "pionowa linia z okręgiem pod"] # 0x2af0 - - "⫱": [t: "dolny znacznik z okręgiem pod"] # 0x2af1 - - "⫲": [t: "równoległe z poziomą kreską"] # 0x2af2 - - "⫳": [t: "równoległe z operatorem tyldy"] # 0x2af3 - - "⫴": [t: "potrójna pionowa kreska jako relacja binarna"] # 0x2af4 - - "⫵": [t: "potrójna pionowa kreska z poziomą kreską"] # 0x2af5 - - "⫶": [t: "potrójny dwukropek operator"] # 0x2af6 - - "⫷": [t: "potrójnie zagnieżdżone mniejsze niż"] # 0x2af7 - - "⫸": [t: "potrójnie zagnieżdżone większe niż"] # 0x2af8 - - "⫹": [t: "podwójna linia ukośnie mniejsze lub równe"] # 0x2af9 - - "⫺": [t: "podwójna linia ukośnie większe lub równe"] # 0x2afa - - "⫻": [t: "potrójny ukośnik jako relacja binarna"] # 0x2afb - - "⫼": [t: "operator dużej potrójnej pionowej kreski"] # 0x2afc - - "⫽": [t: "podwójny ukośnik operator"] # 0x2afd - - "⫾": [t: "biała pionowa kreska"] # 0x2afe - - "⫿": [t: "biała pionowa kreska"] # 0x2aff - - "⬀": [t: "biała strzałka na północny wschód"] # 0x2b00 - - "⬁": [t: "biała strzałka na północny zachód"] # 0x2b01 - - "⬂": [t: "biała strzałka na południowy wschód"] # 0x2b02 - - "⬃": [t: "biała strzałka na południowy zachód"] # 0x2b03 - - "⬄": [t: "biała strzałka w lewo i w prawo"] # 0x2b04 - - "⬅": [t: "lewy czarny strzałka"] # 0x2b05 - - "⬆": [t: "górny czarny strzałka"] # 0x2b06 - - "⬇": [t: "dolny czarny strzałka"] # 0x2b07 - - "⬈": [t: "północ wschód czarny strzałka"] # 0x2b08 - - "⬉": [t: "północ zachód czarny strzałka"] # 0x2b09 - - "⬊": [t: "południe wschód czarny strzałka"] # 0x2b0a - - "⬋": [t: "południe zachód czarny strzałka"] # 0x2b0b - - "⬌": [t: "lewy prawy czarny strzałka"] # 0x2b0c - - "⬍": [t: "górny dolny czarny strzałka"] # 0x2b0d - - "⬎": [t: "strzałka w prawo z dolnym czubkiem"] # 0x2b0e - - "⬏": [t: "strzałka w prawo z górnym czubkiem"] # 0x2b0f - - "⬐": [t: "strzałka w lewo z dolnym czubkiem"] # 0x2b10 - - "⬑": [t: "strzałka w lewo z górnym czubkiem"] # 0x2b11 - - "⬒": [t: "kwadrat z górną połową czarną"] # 0x2b12 - - "⬓": [t: "kwadrat z dolną połową czarną"] # 0x2b13 - - "⬔": [t: "kwadrat z górną prawą ukośną połową czarną"] # 0x2b14 - - "⬕": [t: "kwadrat z dolną lewą ukośną połową czarną"] # 0x2b15 - - "⬖": [t: "romb z lewą połową czarną"] # 0x2b16 - - "⬗": [t: "romb z prawą połową czarną"] # 0x2b17 - - "⬘": [t: "romb z górną połową czarną"] # 0x2b18 - - "⬙": [t: "romb z dolną połową czarną"] # 0x2b19 - - "⬚": [t: "ramka"] # 0x2b1a - - "⬛": [t: "czarny duży kwadrat"] # 0x2b1b - - "⬜": [t: "biały duży kwadrat"] # 0x2b1c - - "⬝": [t: "czarny bardzo mały kwadrat"] # 0x2b1d - - "⬞": [t: "biały bardzo mały kwadrat"] # 0x2b1e - - "⬟": [t: "czarny pięciokąt"] # 0x2b1f - - "⬠": [t: "biały pięciokąt"] # 0x2b20 - - "⬡": [t: "biały sześciokąt"] # 0x2b21 - - "⬢": [t: "czarny sześciokąt"] # 0x2b22 - - "⬣": [t: "poziomy czarny sześciokąt"] # 0x2b23 - - "⬤": [t: "czarny duży okrąg"] # 0x2b24 - - "⬥": [t: "czarny średni romb"] # 0x2b25 - - "⬦": [t: "biały średni romb"] # 0x2b26 - - "⬧": [t: "czarny średni romb"] # 0x2b27 - - "⬨": [t: "biały średni romb"] # 0x2b28 - - "⬩": [t: "czarny mały romb"] # 0x2b29 - - "⬪": [t: "czarny mały romb"] # 0x2b2a - - "⬫": [t: "biały mały romb"] # 0x2b2b - - "⬬": [t: "czarna pozioma elipsa"] # 0x2b2c - - "⬭": [t: "biała pozioma elipsa"] # 0x2b2d - - "⬮": [t: "czarna pionowa elipsa"] # 0x2b2e - - "⬯": [t: "biała pionowa elipsa"] # 0x2b2f - - "⬰": [t: "strzałka w lewo z małym okręgiem"] # 0x2b30 - - "⬱": [t: "trzy strzałki w lewo"] # 0x2b31 - - "⬲": [t: "strzałka w lewo z plusem w kółku"] # 0x2b32 - - "⬳": [t: "długa falista strzałka w lewo"] # 0x2b33 - - "⬴": [t: "strzałka w lewo z dwoma grotami i pionowym przekreśleniem"] # 0x2b34 - - "⬵": [t: "strzałka w lewo z dwoma grotami i podwójnym pionowym przekreśleniem"] # 0x2b35 - - "⬶": [t: "strzałka w lewo z dwoma grotami od kreski"] # 0x2b36 - - "⬷": [t: "strzałka w lewo z dwoma grotami i potrójną kreską"] # 0x2b37 - - "⬸": [t: "strzałka w lewo z kropkowanym trzonem"] # 0x2b38 - - "⬹": [t: "strzałka w lewo z ogonem i pionową kreską"] # 0x2b39 - - "⬺": [t: "strzałka w lewo z ogonem i podwójną pionową kreską"] # 0x2b3a - - "⬻": [t: "strzałka w lewo z dwoma grotami i ogonem"] # 0x2b3b - - "⬼": [t: "strzałka w lewo z dwoma grotami, ogonem i pionowym przekreśleniem"] # 0x2b3c - - "⬽": [t: "strzałka w lewo z dwoma grotami, ogonem i podwójnym pionowym przekreśleniem"] # 0x2b3d - - "⬾": [t: "strzałka w lewo przez X"] # 0x2b3e - - "⬿": [t: "falista strzałka skierowana bezpośrednio w lewo"] # 0x2b3f - - "⭀": [t: "znak równości nad strzałką w lewo"] # 0x2b40 - - "⭁": [t: "operator odwrotnej tyldy nad strzałką w lewo"] # 0x2b41 - - "⭂": [t: "strzałka w lewo nad odwróconym znakiem przybliżonej równości"] # 0x2b42 - - "⭃": [t: "strzałka w prawo przez znak większe niż"] # 0x2b43 - - "⭄": [t: "strzałka w prawo przez znak nadzbioru"] # 0x2b44 - - "⭅": [t: "lewy poczwórny strzałka"] # 0x2b45 - - "⭆": [t: "prawy poczwórny strzałka"] # 0x2b46 - - "⭇": [t: "operator odwrotnej tyldy nad strzałką w prawo"] # 0x2b47 - - "⭈": [t: "strzałka w prawo nad odwróconym znakiem przybliżonej równości"] # 0x2b48 - - "⭉": [t: "operator tyldy nad strzałką w lewo"] # 0x2b49 - - "⭊": [t: "strzałka w lewo nad znakiem przybliżonej równości"] # 0x2b4a - - "⭋": [t: "strzałka w lewo nad operatorem odwrotnej tyldy"] # 0x2b4b - - "⭌": [t: "strzałka w prawo nad operatorem odwrotnej tyldy"] # 0x2b4c - - "⭐": [t: "biały średni gwiazda"] # 0x2b50 - - "⭑": [t: "czarny mały gwiazda"] # 0x2b51 - - "⭒": [t: "biały mały gwiazda"] # 0x2b52 - - "⭓": [t: "czarny prawy skierowany pięciokąt"] # 0x2b53 - - "⭔": [t: "biały prawy skierowany pięciokąt"] # 0x2b54 - - "⭕": [t: "gruby duży okrąg"] # 0x2b55 - - "⭖": [t: "gruby owal z owalem wewnątrz"] # 0x2b56 - - "⭗": [t: "gruby okrąg z okręgiem wewnątrz"] # 0x2b57 - - "⭘": [t: "gruby okrąg"] # 0x2b58 - - "⭙": [t: "gruby ukośny krzyż w kółku"] # 0x2b59 - - "⸀": [t: "kąt prosty znacznik podstawienia"] # 0x2e00 - - "⸁": [t: "kąt prosty kropkowany znacznik podstawienia"] # 0x2e01 - - "⸂": [t: "lewy nawias kwadratowy podstawienia"] # 0x2e02 - - "⸃": [t: "prawy nawias kwadratowy podstawienia"] # 0x2e03 - - "⸄": [t: "lewy kropkowany nawias kwadratowy podstawienia"] # 0x2e04 - - "⸅": [t: "prawy kropkowany nawias kwadratowy podstawienia"] # 0x2e05 - - "⸆": [t: "podniesiony znacznik interpolacji"] # 0x2e06 - - "⸇": [t: "podniesiony kropkowany znacznik interpolacji"] # 0x2e07 - - "⸈": [t: "kropkowany znacznik transpozycji"] # 0x2e08 - - "⸉": [t: "lewy nawias kwadratowy transpozycji"] # 0x2e09 - - "⸊": [t: "prawy nawias kwadratowy transpozycji"] # 0x2e0a - - "⸋": [t: "podniesiony kwadrat"] # 0x2e0b - - "⸌": [t: "lewy podniesiony pominięcia nawias kwadratowy"] # 0x2e0c - - "⸍": [t: "prawy podniesiony pominięcia nawias kwadratowy"] # 0x2e0d - - "⸎": [t: "redakcyjny koronis"] # 0x2e0e + then: [T: "krzyż"] + else: [T: "krzyż iloczyn"] + - "⨰": [T: "znak mnożenia z kropką nad"] # 0x2a30 + - "⨱": [T: "znak mnożenia z podkreśleniem"] # 0x2a31 + - "⨲": [T: "iloczyn półprosty domknięty od dołu"] # 0x2a32 + - "⨳": [T: "iloczyn spłaszczony"] # 0x2a33 + - "⨴": [T: "znak mnożenia w lewej połówce okręgu"] # 0x2a34 + - "⨵": [T: "znak mnożenia w prawej połówce okręgu"] # 0x2a35 + - "⨶": [T: "znak mnożenia w kółku z daszkiem"] # 0x2a36 + - "⨷": [T: "znak mnożenia w podwójnym okręgu"] # 0x2a37 + - "⨸": [T: "znak dzielenia w kółku"] # 0x2a38 + - "⨹": [T: "znak plus w trójkącie"] # 0x2a39 + - "⨺": [T: "znak minus w trójkącie"] # 0x2a3a + - "⨻": [T: "znak mnożenia w trójkącie"] # 0x2a3b + - "⨼": [T: "iloczyn wewnętrzny"] # 0x2a3c + - "⨽": [T: "prawostronny iloczyn wewnętrzny"] # 0x2a3d + - "⨾": [T: "składanie relacji w notacji Z"] # 0x2a3e + - "⨿": [T: "amalgamacja lub koprodukt"] # 0x2a3f + - "⩀": [T: "część wspólna z kropką"] # 0x2a40 + - "⩁": [T: "suma zbiorów ze znakiem minus"] # 0x2a41 + - "⩂": [T: "suma zbiorów z kreską nad"] # 0x2a42 + - "⩃": [T: "część wspólna z kreską nad"] # 0x2a43 + - "⩄": [T: "część wspólna z koniunkcją logiczną"] # 0x2a44 + - "⩅": [T: "suma zbiorów z alternatywą logiczną"] # 0x2a45 + - "⩆": [T: "suma zbiorów nad część wspólna"] # 0x2a46 + - "⩇": [T: "część wspólna nad suma zbiorów"] # 0x2a47 + - "⩈": [T: "suma zbiorów nad kreska nad część wspólna"] # 0x2a48 + - "⩉": [T: "część wspólna nad kreska nad suma zbiorów"] # 0x2a49 + - "⩊": [T: "suma zbiorów obok sumy zbiorów połączona kreską"] # 0x2a4a + - "⩋": [T: "część wspólna obok części wspólnej połączona kreską"] # 0x2a4b + - "⩌": [T: "zamknięta suma zbiorów z szeryfami"] # 0x2a4c + - "⩍": [T: "zamknięta część wspólna z szeryfami"] # 0x2a4d + - "⩎": [T: "podwójny kwadrat część wspólna"] # 0x2a4e + - "⩏": [T: "podwójny kwadrat suma zbiorów"] # 0x2a4f + - "⩐": [T: "zamknięta suma zbiorów z szeryfami i iloczynem spłaszczonym"] # 0x2a50 + - "⩑": [T: "koniunkcja logiczna z kropką nad"] # 0x2a51 + - "⩒": [T: "logiczne lub z kropką nad"] # 0x2a52 + - "⩓": [T: "podwójna koniunkcja logiczna"] # 0x2a53 + - "⩔": [T: "podwójny logiczne lub"] # 0x2a54 + - "⩕": [T: "dwa przecinające się logiczne i"] # 0x2a55 + - "⩖": [T: "dwa przecinające się logiczne lub"] # 0x2a56 + - "⩗": [T: "skośne duże lub"] # 0x2a57 + - "⩘": [T: "skośne duże i"] # 0x2a58 + - "⩙": [T: "logiczne lub nakładające się na logiczne i"] # 0x2a59 + - "⩚": [T: "logiczne i ze środkowym trzonem"] # 0x2a5a + - "⩛": [T: "logiczne lub ze środkowym trzonem"] # 0x2a5b + - "⩜": [T: "koniunkcja logiczna z poziomą kreską"] # 0x2a5c + - "⩝": [T: "alternatywa logiczna z poziomą kreską"] # 0x2a5d + - "⩞": [T: "logiczne i z podwójną kreską nad"] # 0x2a5e + - "⩟": [T: "koniunkcja logiczna z podkreśleniem"] # 0x2a5f + - "⩠": [T: "logiczne i z podwójną kreską pod"] # 0x2a60 + - "⩡": [T: "małe logiczne lub z podkreśleniem"] # 0x2a61 + - "⩢": [T: "logiczne lub z podwójną kreską nad"] # 0x2a62 + - "⩣": [T: "logiczne lub z podwójną kreską pod"] # 0x2a63 + - "⩤": [T: "antyograniczenie dziedziny w notacji Z"] # 0x2a64 + - "⩥": [T: "antyograniczenie przeciwdziedziny w notacji Z"] # 0x2a65 + - "⩦": [T: "znak równości z kropką pod spodem"] # 0x2a66 + - "⩧": [T: "identyczne z kropką nad"] # 0x2a67 + - "⩨": [T: "potrójna kreska pozioma z podwójną pionową kreską"] # 0x2a68 + - "⩩": [T: "potrójna kreska pozioma z potrójną pionową kreską"] # 0x2a69 + - "⩪": [T: "operator tyldy z kropką nad"] # 0x2a6a + - "⩫": [T: "operator tyldy ze wznoszącymi kropkami"] # 0x2a6b + - "⩬": [T: "podobne minus podobne"] # 0x2a6c + - "⩭": [T: "przystające z kropką nad"] # 0x2a6d + - "⩮": [T: "równa się z gwiazdką"] # 0x2a6e + - "⩯": [T: "w przybliżeniu równe z daszkiem"] # 0x2a6f + - "⩰": [T: "w przybliżeniu równe lub równe"] # 0x2a70 + - "⩱": [T: "znak równości nad znakiem plus"] # 0x2a71 + - "⩲": [T: "znak plus nad znakiem równości"] # 0x2a72 + - "⩳": [T: "znak równości nad operatorem tyldy"] # 0x2a73 + - "⩴": [T: "podwójny dwukropek równe"] # 0x2a74 + - "⩵": [T: "dwa kolejne znaki równości"] # 0x2a75 + - "⩶": [T: "trzy kolejne znaki równości"] # 0x2a76 + - "⩷": [T: "znak równości z dwiema kropkami nad i dwiema kropkami pod"] # 0x2a77 + - "⩸": [T: "równoważne z czterema kropkami nad"] # 0x2a78 + - "⩹": [T: "mniejsze niż z okrąg wewnątrz"] # 0x2a79 + - "⩺": [T: "większe niż z okrąg wewnątrz"] # 0x2a7a + - "⩻": [T: "mniejsze niż ze znakiem zapytania nad"] # 0x2a7b + - "⩼": [T: "większe niż ze znakiem zapytania nad"] # 0x2a7c + - "⩽": [T: "mniejsze niż lub ukośnie równe"] # 0x2a7d + - "⩾": [T: "większe niż lub ukośnie równe"] # 0x2a7e + - "⩿": [T: "mniejsze niż lub ukośnie równe z kropką wewnątrz"] # 0x2a7f + - "⪀": [T: "większe niż lub ukośnie równe z kropką wewnątrz"] # 0x2a80 + - "⪁": [T: "mniejsze niż lub ukośnie równe z kropką nad"] # 0x2a81 + - "⪂": [T: "większe niż lub ukośnie równe z kropką nad"] # 0x2a82 + - "⪃": [T: "mniejsze niż lub ukośnie równe z kropką nad prawą stroną"] # 0x2a83 + - "⪄": [T: "większe niż lub ukośnie równe z kropką nad lewą stroną"] # 0x2a84 + - "⪅": [T: "mniejsze niż lub przybliżone"] # 0x2a85 + - "⪆": [T: "większe niż lub przybliżone"] # 0x2a86 + - "⪇": [T: "mniejsze niż z pojedynczą linią nierówności"] # 0x2a87 + - "⪈": [T: "większe niż z pojedynczą linią nierówności"] # 0x2a88 + - "⪉": [T: "mniejsze niż i nie przybliżone"] # 0x2a89 + - "⪊": [T: "większe niż i nie przybliżone"] # 0x2a8a + - "⪋": [T: "mniejsze niż nad podwójną linią równości nad większe niż"] # 0x2a8b + - "⪌": [T: "większe niż nad podwójną linią równości nad mniejsze niż"] # 0x2a8c + - "⪍": [T: "mniejsze niż nad podobne lub równe"] # 0x2a8d + - "⪎": [T: "większe niż nad podobne lub równe"] # 0x2a8e + - "⪏": [T: "mniejsze niż nad podobne nad większe niż"] # 0x2a8f + - "⪐": [T: "większe niż nad podobne nad mniejsze niż"] # 0x2a90 + - "⪑": [T: "mniejsze niż nad większe niż nad podwójną linią równości"] # 0x2a91 + - "⪒": [T: "większe niż nad mniejsze niż nad podwójną linią równości"] # 0x2a92 + - "⪓": [T: "mniejsze niż nad ukośnie równe nad większe niż nad ukośnie równe"] # 0x2a93 + - "⪔": [T: "większe niż nad ukośnie równe nad mniejsze niż nad ukośnie równe"] # 0x2a94 + - "⪕": [T: "ukośnie równe lub mniejsze niż"] # 0x2a95 + - "⪖": [T: "ukośnie równe lub większe niż"] # 0x2a96 + - "⪗": [T: "ukośnie równe lub mniejsze niż z kropką wewnątrz"] # 0x2a97 + - "⪘": [T: "ukośnie równe lub większe niż z kropką wewnątrz"] # 0x2a98 + - "⪙": [T: "podwójna linia równa lub mniejsze niż"] # 0x2a99 + - "⪚": [T: "podwójna linia równa lub większe niż"] # 0x2a9a + - "⪛": [T: "podwójna linia ukośnie równa lub mniejsze niż"] # 0x2a9b + - "⪜": [T: "podwójna linia ukośnie równa lub większe niż"] # 0x2a9c + - "⪝": [T: "podobne lub mniejsze niż"] # 0x2a9d + - "⪞": [T: "podobne lub większe niż"] # 0x2a9e + - "⪟": [T: "podobne nad mniejsze niż nad znakiem równości"] # 0x2a9f + - "⪠": [T: "podobne nad większe niż nad znakiem równości"] # 0x2aa0 + - "⪡": [T: "podwójnie zagnieżdżone mniejsze niż"] # 0x2aa1 + - "⪢": [T: "podwójnie zagnieżdżone większe niż"] # 0x2aa2 + - "⪣": [T: "podwójnie zagnieżdżone mniejsze niż z podkreśleniem"] # 0x2aa3 + - "⪤": [T: "większe niż nakładające się na mniejsze niż"] # 0x2aa4 + - "⪥": [T: "większe niż obok mniejsze niż"] # 0x2aa5 + - "⪦": [T: "mniejsze niż zamknięte krzywą"] # 0x2aa6 + - "⪧": [T: "większe niż zamknięte krzywą"] # 0x2aa7 + - "⪨": [T: "mniejsze niż zamknięte krzywą nad ukośnie równe"] # 0x2aa8 + - "⪩": [T: "większe niż zamknięte krzywą nad ukośnie równe"] # 0x2aa9 + - "⪪": [T: "mniejsze niż"] # 0x2aaa + - "⪫": [T: "większe niż"] # 0x2aab + - "⪬": [T: "mniejsze niż lub równe"] # 0x2aac + - "⪭": [T: "większe niż lub równe"] # 0x2aad + - "⪮": [T: "znak równości z garbem nad"] # 0x2aae + - "⪯": [T: "poprzedza nad pojedynczą linią równości"] # 0x2aaf + - "⪰": [T: "następuje po nad pojedynczą linią równości"] # 0x2ab0 + - "⪱": [T: "poprzedza nad pojedynczą linią nierówności"] # 0x2ab1 + - "⪲": [T: "następuje po nad pojedynczy linia nie równa się"] # 0x2ab2 + - "⪳": [T: "poprzedza nad znakiem równości"] # 0x2ab3 + - "⪴": [T: "następuje po nad znakiem równości"] # 0x2ab4 + - "⪵": [T: "poprzedza nad nie równa się"] # 0x2ab5 + - "⪶": [T: "następuje po nad nie równa się"] # 0x2ab6 + - "⪷": [T: "poprzedza nad znakiem przybliżonej równości"] # 0x2ab7 + - "⪸": [T: "następuje po nad znakiem przybliżonej równości"] # 0x2ab8 + - "⪹": [T: "poprzedza nad znakiem nie w przybliżeniu równe"] # 0x2ab9 + - "⪺": [T: "następuje po nad znakiem nie w przybliżeniu równe"] # 0x2aba + - "⪻": [T: "podwójny poprzedza"] # 0x2abb + - "⪼": [T: "podwójny następuje po"] # 0x2abc + - "⪽": [T: "podzbiór z kropką"] # 0x2abd + - "⪾": [T: "nadzbiór z kropką"] # 0x2abe + - "⪿": [T: "podzbiór ze znakiem plus pod spodem"] # 0x2abf + - "⫀": [T: "nadzbiór ze znakiem plus pod spodem"] # 0x2ac0 + - "⫁": [T: "podzbiór ze znakiem mnożenia pod"] # 0x2ac1 + - "⫂": [T: "nadzbiór ze znakiem mnożenia pod"] # 0x2ac2 + - "⫃": [T: "podzbiór lub równy z kropką nad"] # 0x2ac3 + - "⫄": [T: "nadzbiór lub równy z kropką nad"] # 0x2ac4 + - "⫅": [T: "podzbiór nad znakiem równości"] # 0x2ac5 + - "⫆": [T: "nadzbiór nad znakiem równości"] # 0x2ac6 + - "⫇": [T: "podzbiór nad operatorem tyldy"] # 0x2ac7 + - "⫈": [T: "nadzbiór nad operatorem tyldy"] # 0x2ac8 + - "⫉": [T: "podzbiór nad znakiem przybliżonej równości"] # 0x2ac9 + - "⫊": [T: "nadzbiór nad znakiem przybliżonej równości"] # 0x2aca + - "⫋": [T: "podzbiór nad nie równa się"] # 0x2acb + - "⫌": [T: "nadzbiór nad nie równa się"] # 0x2acc + - "⫍": [T: "kwadrat lewy otwórz ramka operator"] # 0x2acd + - "⫎": [T: "kwadrat prawy otwórz ramka operator"] # 0x2ace + - "⫏": [T: "zamknięty podzbiór"] # 0x2acf + - "⫐": [T: "zamknięty nadzbiór"] # 0x2ad0 + - "⫑": [T: "zamknięty podzbiór lub równe"] # 0x2ad1 + - "⫒": [T: "zamknięty nadzbiór lub równe"] # 0x2ad2 + - "⫓": [T: "podzbiór nad nadzbiór"] # 0x2ad3 + - "⫔": [T: "nadzbiór nad podzbiór"] # 0x2ad4 + - "⫕": [T: "podzbiór nad podzbiór"] # 0x2ad5 + - "⫖": [T: "nadzbiór nad nadzbiór"] # 0x2ad6 + - "⫗": [T: "nadzbiór obok podzbioru"] # 0x2ad7 + - "⫘": [T: "nadzbiór obok podzbioru połączony kreską"] # 0x2ad8 + - "⫙": [T: "należy do otwarte od dołu"] # 0x2ad9 + - "⫚": [T: "widły z górną poprzeczką"] # 0x2ada + - "⫛": [T: "poprzeczna część wspólna"] # 0x2adb + - "⫝̸": [T: "rozwidlanie"] # 0x2adc + - "⫝": [T: "nierozwidlanie"] # 0x2add + - "⫞": [T: "krótki lewy znacznik"] # 0x2ade + - "⫟": [T: "krótki dolny znacznik"] # 0x2adf + - "⫠": [T: "krótki górny znacznik"] # 0x2ae0 + - "⫡": [T: "prostopadłe z literą s"] # 0x2ae1 + - "⫢": [T: "pionowa kreska z potrójnym prawym znacznikiem dedukcji"] # 0x2ae2 + - "⫣": [T: "podwójna pionowa kreska z lewym znacznikiem dedukcji"] # 0x2ae3 + - "⫤": [T: "pionowa kreska z podwójnym lewym znacznikiem dedukcji"] # 0x2ae4 + - "⫥": [T: "podwójna pionowa kreska z podwójnym lewym znacznikiem dedukcji"] # 0x2ae5 + - "⫦": [T: "długa kreska od lewego elementu z podwójną pionową kreską"] # 0x2ae6 + - "⫧": [T: "krótki dolny znacznik z kreską nad"] # 0x2ae7 + - "⫨": [T: "krótki górny znacznik z podkreśleniem"] # 0x2ae8 + - "⫩": [T: "krótki górny znacznik nad krótkim dolnym znacznikiem"] # 0x2ae9 + - "⫪": [T: "podwójny dolny znacznik"] # 0x2aea + - "⫫": [T: "podwójny górny znacznik"] # 0x2aeb + - "⫬": [T: "znak negacji z podwójnym przekreśleniem"] # 0x2aec + - "⫭": [T: "odwrócony znak negacji z podwójnym przekreśleniem"] # 0x2aed + - "⫮": [T: "nie dzieli z odwróconym ukośnikiem negacji"] # 0x2aee + - "⫯": [T: "pionowa linia z okręgiem nad"] # 0x2aef + - "⫰": [T: "pionowa linia z okręgiem pod"] # 0x2af0 + - "⫱": [T: "dolny znacznik z okręgiem pod"] # 0x2af1 + - "⫲": [T: "równoległe z poziomą kreską"] # 0x2af2 + - "⫳": [T: "równoległe z operatorem tyldy"] # 0x2af3 + - "⫴": [T: "potrójna pionowa kreska jako relacja binarna"] # 0x2af4 + - "⫵": [T: "potrójna pionowa kreska z poziomą kreską"] # 0x2af5 + - "⫶": [T: "potrójny dwukropek operator"] # 0x2af6 + - "⫷": [T: "potrójnie zagnieżdżone mniejsze niż"] # 0x2af7 + - "⫸": [T: "potrójnie zagnieżdżone większe niż"] # 0x2af8 + - "⫹": [T: "podwójna linia ukośnie mniejsze lub równe"] # 0x2af9 + - "⫺": [T: "podwójna linia ukośnie większe lub równe"] # 0x2afa + - "⫻": [T: "potrójny ukośnik jako relacja binarna"] # 0x2afb + - "⫼": [T: "operator dużej potrójnej pionowej kreski"] # 0x2afc + - "⫽": [T: "podwójny ukośnik operator"] # 0x2afd + - "⫾": [T: "biała pionowa kreska"] # 0x2afe + - "⫿": [T: "biała pionowa kreska"] # 0x2aff + - "⬀": [T: "biała strzałka na północny wschód"] # 0x2b00 + - "⬁": [T: "biała strzałka na północny zachód"] # 0x2b01 + - "⬂": [T: "biała strzałka na południowy wschód"] # 0x2b02 + - "⬃": [T: "biała strzałka na południowy zachód"] # 0x2b03 + - "⬄": [T: "biała strzałka w lewo i w prawo"] # 0x2b04 + - "⬅": [T: "lewy czarny strzałka"] # 0x2b05 + - "⬆": [T: "górny czarny strzałka"] # 0x2b06 + - "⬇": [T: "dolny czarny strzałka"] # 0x2b07 + - "⬈": [T: "północ wschód czarny strzałka"] # 0x2b08 + - "⬉": [T: "północ zachód czarny strzałka"] # 0x2b09 + - "⬊": [T: "południe wschód czarny strzałka"] # 0x2b0a + - "⬋": [T: "południe zachód czarny strzałka"] # 0x2b0b + - "⬌": [T: "lewy prawy czarny strzałka"] # 0x2b0c + - "⬍": [T: "górny dolny czarny strzałka"] # 0x2b0d + - "⬎": [T: "strzałka w prawo z dolnym czubkiem"] # 0x2b0e + - "⬏": [T: "strzałka w prawo z górnym czubkiem"] # 0x2b0f + - "⬐": [T: "strzałka w lewo z dolnym czubkiem"] # 0x2b10 + - "⬑": [T: "strzałka w lewo z górnym czubkiem"] # 0x2b11 + - "⬒": [T: "kwadrat z górną połową czarną"] # 0x2b12 + - "⬓": [T: "kwadrat z dolną połową czarną"] # 0x2b13 + - "⬔": [T: "kwadrat z górną prawą ukośną połową czarną"] # 0x2b14 + - "⬕": [T: "kwadrat z dolną lewą ukośną połową czarną"] # 0x2b15 + - "⬖": [T: "romb z lewą połową czarną"] # 0x2b16 + - "⬗": [T: "romb z prawą połową czarną"] # 0x2b17 + - "⬘": [T: "romb z górną połową czarną"] # 0x2b18 + - "⬙": [T: "romb z dolną połową czarną"] # 0x2b19 + - "⬚": [T: "ramka"] # 0x2b1a + - "⬛": [T: "czarny duży kwadrat"] # 0x2b1b + - "⬜": [T: "biały duży kwadrat"] # 0x2b1c + - "⬝": [T: "czarny bardzo mały kwadrat"] # 0x2b1d + - "⬞": [T: "biały bardzo mały kwadrat"] # 0x2b1e + - "⬟": [T: "czarny pięciokąt"] # 0x2b1f + - "⬠": [T: "biały pięciokąt"] # 0x2b20 + - "⬡": [T: "biały sześciokąt"] # 0x2b21 + - "⬢": [T: "czarny sześciokąt"] # 0x2b22 + - "⬣": [T: "poziomy czarny sześciokąt"] # 0x2b23 + - "⬤": [T: "czarny duży okrąg"] # 0x2b24 + - "⬥": [T: "czarny średni romb"] # 0x2b25 + - "⬦": [T: "biały średni romb"] # 0x2b26 + - "⬧": [T: "czarny średni romb"] # 0x2b27 + - "⬨": [T: "biały średni romb"] # 0x2b28 + - "⬩": [T: "czarny mały romb"] # 0x2b29 + - "⬪": [T: "czarny mały romb"] # 0x2b2a + - "⬫": [T: "biały mały romb"] # 0x2b2b + - "⬬": [T: "czarna pozioma elipsa"] # 0x2b2c + - "⬭": [T: "biała pozioma elipsa"] # 0x2b2d + - "⬮": [T: "czarna pionowa elipsa"] # 0x2b2e + - "⬯": [T: "biała pionowa elipsa"] # 0x2b2f + - "⬰": [T: "strzałka w lewo z małym okręgiem"] # 0x2b30 + - "⬱": [T: "trzy strzałki w lewo"] # 0x2b31 + - "⬲": [T: "strzałka w lewo z plusem w kółku"] # 0x2b32 + - "⬳": [T: "długa falista strzałka w lewo"] # 0x2b33 + - "⬴": [T: "strzałka w lewo z dwoma grotami i pionowym przekreśleniem"] # 0x2b34 + - "⬵": [T: "strzałka w lewo z dwoma grotami i podwójnym pionowym przekreśleniem"] # 0x2b35 + - "⬶": [T: "strzałka w lewo z dwoma grotami od kreski"] # 0x2b36 + - "⬷": [T: "strzałka w lewo z dwoma grotami i potrójną kreską"] # 0x2b37 + - "⬸": [T: "strzałka w lewo z kropkowanym trzonem"] # 0x2b38 + - "⬹": [T: "strzałka w lewo z ogonem i pionową kreską"] # 0x2b39 + - "⬺": [T: "strzałka w lewo z ogonem i podwójną pionową kreską"] # 0x2b3a + - "⬻": [T: "strzałka w lewo z dwoma grotami i ogonem"] # 0x2b3b + - "⬼": [T: "strzałka w lewo z dwoma grotami, ogonem i pionowym przekreśleniem"] # 0x2b3c + - "⬽": [T: "strzałka w lewo z dwoma grotami, ogonem i podwójnym pionowym przekreśleniem"] # 0x2b3d + - "⬾": [T: "strzałka w lewo przez X"] # 0x2b3e + - "⬿": [T: "falista strzałka skierowana bezpośrednio w lewo"] # 0x2b3f + - "⭀": [T: "znak równości nad strzałką w lewo"] # 0x2b40 + - "⭁": [T: "operator odwrotnej tyldy nad strzałką w lewo"] # 0x2b41 + - "⭂": [T: "strzałka w lewo nad odwróconym znakiem przybliżonej równości"] # 0x2b42 + - "⭃": [T: "strzałka w prawo przez znak większe niż"] # 0x2b43 + - "⭄": [T: "strzałka w prawo przez znak nadzbioru"] # 0x2b44 + - "⭅": [T: "lewy poczwórny strzałka"] # 0x2b45 + - "⭆": [T: "prawy poczwórny strzałka"] # 0x2b46 + - "⭇": [T: "operator odwrotnej tyldy nad strzałką w prawo"] # 0x2b47 + - "⭈": [T: "strzałka w prawo nad odwróconym znakiem przybliżonej równości"] # 0x2b48 + - "⭉": [T: "operator tyldy nad strzałką w lewo"] # 0x2b49 + - "⭊": [T: "strzałka w lewo nad znakiem przybliżonej równości"] # 0x2b4a + - "⭋": [T: "strzałka w lewo nad operatorem odwrotnej tyldy"] # 0x2b4b + - "⭌": [T: "strzałka w prawo nad operatorem odwrotnej tyldy"] # 0x2b4c + - "⭐": [T: "biały średni gwiazda"] # 0x2b50 + - "⭑": [T: "czarny mały gwiazda"] # 0x2b51 + - "⭒": [T: "biały mały gwiazda"] # 0x2b52 + - "⭓": [T: "czarny prawy skierowany pięciokąt"] # 0x2b53 + - "⭔": [T: "biały prawy skierowany pięciokąt"] # 0x2b54 + - "⭕": [T: "gruby duży okrąg"] # 0x2b55 + - "⭖": [T: "gruby owal z owalem wewnątrz"] # 0x2b56 + - "⭗": [T: "gruby okrąg z okręgiem wewnątrz"] # 0x2b57 + - "⭘": [T: "gruby okrąg"] # 0x2b58 + - "⭙": [T: "gruby ukośny krzyż w kółku"] # 0x2b59 + - "⸀": [T: "kąt prosty znacznik podstawienia"] # 0x2e00 + - "⸁": [T: "kąt prosty kropkowany znacznik podstawienia"] # 0x2e01 + - "⸂": [T: "lewy nawias kwadratowy podstawienia"] # 0x2e02 + - "⸃": [T: "prawy nawias kwadratowy podstawienia"] # 0x2e03 + - "⸄": [T: "lewy kropkowany nawias kwadratowy podstawienia"] # 0x2e04 + - "⸅": [T: "prawy kropkowany nawias kwadratowy podstawienia"] # 0x2e05 + - "⸆": [T: "podniesiony znacznik interpolacji"] # 0x2e06 + - "⸇": [T: "podniesiony kropkowany znacznik interpolacji"] # 0x2e07 + - "⸈": [T: "kropkowany znacznik transpozycji"] # 0x2e08 + - "⸉": [T: "lewy nawias kwadratowy transpozycji"] # 0x2e09 + - "⸊": [T: "prawy nawias kwadratowy transpozycji"] # 0x2e0a + - "⸋": [T: "podniesiony kwadrat"] # 0x2e0b + - "⸌": [T: "lewy podniesiony pominięcia nawias kwadratowy"] # 0x2e0c + - "⸍": [T: "prawy podniesiony pominięcia nawias kwadratowy"] # 0x2e0d + - "⸎": [T: "redakcyjny koronis"] # 0x2e0e - "⸏": [T: "paragraphos"] # 0x2e0f - - "⸐": [t: "rozwidlony paragrafos"] # 0x2e10 - - "⸑": [t: "odwrócony rozwidlony paragrafos"] # 0x2e11 + - "⸐": [T: "rozwidlony paragrafos"] # 0x2e10 + - "⸑": [T: "odwrócony rozwidlony paragrafos"] # 0x2e11 - "⸒": [T: "hypodiastole"] # 0x2e12 - - "⸓": [t: "kropkowany obelos"] # 0x2e13 - - "⸔": [t: "dolny ancora"] # 0x2e14 - - "⸕": [t: "górny ancora"] # 0x2e15 - - "⸖": [t: "kropkowany kąt skierowany w prawo"] # 0x2e16 - - "⸗": [t: "podwójny ukośny łącznik"] # 0x2e17 - - "⸘": [t: "odwrócony interrobang"] # 0x2e18 - - "⸙": [t: "gałązka palmowa"] # 0x2e19 - - "⸚": [t: "łącznik z dierezą"] # 0x2e1a - - "⸛": [t: "tylda z pierścieniem nad"] # 0x2e1b - - "⸜": [t: "lewy dolny nawias kwadratowy parafrazy"] # 0x2e1c - - "⸝": [t: "prawy dolny nawias kwadratowy parafrazy"] # 0x2e1d - - "⸞": [t: "tylda z kropką nad"] # 0x2e1e - - "⸟": [t: "tylda z kropką pod"] # 0x2e1f - - "⸠": [t: "lewa pionowa kreska z piórem"] # 0x2e20 - - "⸡": [t: "prawa pionowa kreska z piórem"] # 0x2e21 - - "⸢": [t: "górny lewa połowa nawias kwadratowy"] # 0x2e22 - - "⸣": [t: "górny prawa połowa nawias kwadratowy"] # 0x2e23 - - "⸤": [t: "dolny lewa połowa nawias kwadratowy"] # 0x2e24 - - "⸥": [t: "dolny prawa połowa nawias kwadratowy"] # 0x2e25 - - "⸦": [t: "lewy obrócony nawias kwadratowy u"] # 0x2e26 - - "⸧": [t: "prawy obrócony nawias kwadratowy u"] # 0x2e27 - - "⸨": [t: "lewy podwójny nawias okrągły"] # 0x2e28 - - "⸩": [t: "prawy podwójny nawias okrągły"] # 0x2e29 - - "⸪": [t: "dwie kropki nad jedną kropką interpunkcyjną"] # 0x2e2a - - "⸫": [t: "jedna kropka nad dwiema kropkami interpunkcyjnymi"] # 0x2e2b - - "⸬": [t: "do kwadratu cztery kropka interpunkcyjny"] # 0x2e2c - - "⸭": [t: "pięć kropka znak"] # 0x2e2d - - "⸮": [t: "odwrócony zapytania znak"] # 0x2e2e - - "ⸯ": [t: "pionowy tylda"] # 0x2e2f - - "⸰": [t: "pierścień punkt"] # 0x2e30 - - "⸱": [t: "separator wyrazów środkowa kropka"] # 0x2e31 - - "⸲": [t: "odwrócony przecinek"] # 0x2e32 - - "⸳": [t: "podniesiony kropka"] # 0x2e33 - - "⸴": [t: "podniesiony przecinek"] # 0x2e34 - - "⸵": [t: "odwrócony średnik"] # 0x2e35 - - "⸶": [t: "obelisk z lewą osłoną"] # 0x2e36 - - "⸷": [t: "obelisk z prawą osłoną"] # 0x2e37 - - "⸸": [t: "odwrócony obelisk"] # 0x2e38 - - "⸹": [t: "górna połowa paragraf znak"] # 0x2e39 - - "⸺": [t: "dwa pauza"] # 0x2e3a - - "⸻": [t: "trzy pauza"] # 0x2e3b - - "〃": [t: "znak powtórzenia"] # 0x3003 - - "〈": [t: "lewy nawias kątowy"] # 0x3008 - - "〉": [t: "prawy nawias kątowy"] # 0x3009 - - "《": [t: "lewy podwójny nawias kątowy"] # 0x300a - - "》": [t: "prawy podwójny nawias kątowy"] # 0x300b - - "「": [t: "lewy nawias narożny"] # 0x300c - - "」": [t: "prawy nawias narożny"] # 0x300d - - "『": [t: "lewy biały nawias narożny"] # 0x300e - - "』": [t: "prawy biały nawias narożny"] # 0x300f - - "【": [t: "lewy czarny nawias soczewkowy"] # 0x3010 - - "】": [t: "prawy czarny nawias soczewkowy"] # 0x3011 - - "〔": [t: "lewy nawias skorupowy"] # 0x3014 - - "〕": [t: "prawy nawias skorupowy"] # 0x3015 - - "〖": [t: "lewy biały nawias soczewkowy"] # 0x3016 - - "〗": [t: "prawy biały nawias soczewkowy"] # 0x3017 - - "〘": [t: "lewy biały nawias skorupowy"] # 0x3018 - - "〙": [t: "prawy biały nawias skorupowy"] # 0x3019 - - "〚": [t: "lewy biały nawias kwadratowy"] # 0x301a - - "〛": [t: "prawy biały nawias kwadratowy"] # 0x301b - - "〜": [t: "falista kreska"] # 0x301c - - "〰": [t: "falista kreska"] # 0x3030 - - "㉈": [t: "liczba dziesięć w kółku na czarnym kwadracie"] # 0x3248 - - "㉉": [t: "liczba dwadzieścia w kółku na czarnym kwadracie"] # 0x3249 - - "㉊": [t: "liczba trzydzieści w kółku na czarnym kwadracie"] # 0x324a - - "㉋": [t: "liczba czterdzieści w kółku na czarnym kwadracie"] # 0x324b - - "㉌": [t: "liczba pięćdziesiąt w kółku na czarnym kwadracie"] # 0x324c - - "㉍": [t: "liczba sześćdziesiąt w kółku na czarnym kwadracie"] # 0x324d - - "㉎": [t: "liczba siedemdziesiąt w kółku na czarnym kwadracie"] # 0x324e - - "㉏": [t: "liczba osiemdziesiąt w kółku na czarnym kwadracie"] # 0x324f - - "㉑": [t: "w kółku numer dwadzieścia jeden"] # 0x3251 - - "㉒": [t: "w kółku numer dwadzieścia dwa"] # 0x3252 - - "㉓": [t: "w kółku numer dwadzieścia trzy"] # 0x3253 - - "㉔": [t: "w kółku numer dwadzieścia cztery"] # 0x3254 - - "㉕": [t: "w kółku numer dwadzieścia pięć"] # 0x3255 - - "㉖": [t: "w kółku numer dwadzieścia sześć"] # 0x3256 - - "㉗": [t: "w kółku numer dwadzieścia siedem"] # 0x3257 - - "㉘": [t: "w kółku numer dwadzieścia osiem"] # 0x3258 - - "㉙": [t: "w kółku numer dwadzieścia dziewięć"] # 0x3259 - - "㉚": [t: "w kółku numer trzydzieści"] # 0x325a - - "㉛": [t: "w kółku numer trzydzieści jeden"] # 0x325b - - "㉜": [t: "w kółku numer trzydzieści dwa"] # 0x325c - - "㉝": [t: "w kółku numer trzydzieści trzy"] # 0x325d - - "㉞": [t: "w kółku numer trzydzieści cztery"] # 0x325e - - "㉟": [t: "w kółku numer trzydzieści pięć"] # 0x325f - - "㊱": [t: "w kółku numer trzydzieści sześć"] # 0x32b1 - - "㊲": [t: "w kółku numer trzydzieści siedem"] # 0x32b2 (GPT-5.4 translation) - - "㊳": [t: "w kółku numer trzydzieści osiem"] # 0x32b3 (GPT-5.4 translation) - - "㊴": [t: "w kółku numer trzydzieści dziewięć"] # 0x32b4 (GPT-5.4 translation) - - "㊵": [t: "w kółku numer czterdzieści"] # 0x32b5 (GPT-5.4 translation) - - "㊶": [t: "w kółku numer czterdzieści jeden"] # 0x32b6 (GPT-5.4 translation) - - "㊷": [t: "w kółku numer czterdzieści dwa"] # 0x32b7 (GPT-5.4 translation) - - "㊸": [t: "w kółku numer czterdzieści trzy"] # 0x32b8 (GPT-5.4 translation) - - "㊹": [t: "w kółku numer czterdzieści cztery"] # 0x32b9 (GPT-5.4 translation) - - "㊺": [t: "w kółku numer czterdzieści pięć"] # 0x32ba (GPT-5.4 translation) - - "㊻": [t: "w kółku numer czterdzieści sześć"] # 0x32bb (GPT-5.4 translation) - - "㊼": [t: "w kółku numer czterdzieści siedem"] # 0x32bc (GPT-5.4 translation) - - "㊽": [t: "w kółku numer czterdzieści osiem"] # 0x32bd (GPT-5.4 translation) - - "㊾": [t: "w kółku numer czterdzieści dziewięć"] # 0x32be (GPT-5.4 translation) - - "㊿": [t: "w kółku numer pięćdziesiąt"] # 0x32bf (GPT-5.4 translation) - - "㋌": [t: "Merkury"] # 0x32cc - - "㋍": [t: "ergi"] # 0x32cd - - "㋎": [t: "elektron wolty"] # 0x32ce - - "㋏": [t: "znak ograniczonej odpowiedzialności"] # 0x32cf - - "㍱": [t: "hektopaskale"] # 0x3371 - - "㍲": [t: "daltony"] # 0x3372 - - "㍳": [t: "jednostki astronomiczne"] # 0x3373 - - "㍴": [t: "bary"] # 0x3374 + - "⸓": [T: "kropkowany obelos"] # 0x2e13 + - "⸔": [T: "dolny ancora"] # 0x2e14 + - "⸕": [T: "górny ancora"] # 0x2e15 + - "⸖": [T: "kropkowany kąt skierowany w prawo"] # 0x2e16 + - "⸗": [T: "podwójny ukośny łącznik"] # 0x2e17 + - "⸘": [T: "odwrócony interrobang"] # 0x2e18 + - "⸙": [T: "gałązka palmowa"] # 0x2e19 + - "⸚": [T: "łącznik z dierezą"] # 0x2e1a + - "⸛": [T: "tylda z pierścieniem nad"] # 0x2e1b + - "⸜": [T: "lewy dolny nawias kwadratowy parafrazy"] # 0x2e1c + - "⸝": [T: "prawy dolny nawias kwadratowy parafrazy"] # 0x2e1d + - "⸞": [T: "tylda z kropką nad"] # 0x2e1e + - "⸟": [T: "tylda z kropką pod"] # 0x2e1f + - "⸠": [T: "lewa pionowa kreska z piórem"] # 0x2e20 + - "⸡": [T: "prawa pionowa kreska z piórem"] # 0x2e21 + - "⸢": [T: "górny lewa połowa nawias kwadratowy"] # 0x2e22 + - "⸣": [T: "górny prawa połowa nawias kwadratowy"] # 0x2e23 + - "⸤": [T: "dolny lewa połowa nawias kwadratowy"] # 0x2e24 + - "⸥": [T: "dolny prawa połowa nawias kwadratowy"] # 0x2e25 + - "⸦": [T: "lewy obrócony nawias kwadratowy u"] # 0x2e26 + - "⸧": [T: "prawy obrócony nawias kwadratowy u"] # 0x2e27 + - "⸨": [T: "lewy podwójny nawias okrągły"] # 0x2e28 + - "⸩": [T: "prawy podwójny nawias okrągły"] # 0x2e29 + - "⸪": [T: "dwie kropki nad jedną kropką interpunkcyjną"] # 0x2e2a + - "⸫": [T: "jedna kropka nad dwiema kropkami interpunkcyjnymi"] # 0x2e2b + - "⸬": [T: "do kwadratu cztery kropka interpunkcyjny"] # 0x2e2c + - "⸭": [T: "pięć kropka znak"] # 0x2e2d + - "⸮": [T: "odwrócony zapytania znak"] # 0x2e2e + - "ⸯ": [T: "pionowy tylda"] # 0x2e2f + - "⸰": [T: "pierścień punkt"] # 0x2e30 + - "⸱": [T: "separator wyrazów środkowa kropka"] # 0x2e31 + - "⸲": [T: "odwrócony przecinek"] # 0x2e32 + - "⸳": [T: "podniesiony kropka"] # 0x2e33 + - "⸴": [T: "podniesiony przecinek"] # 0x2e34 + - "⸵": [T: "odwrócony średnik"] # 0x2e35 + - "⸶": [T: "obelisk z lewą osłoną"] # 0x2e36 + - "⸷": [T: "obelisk z prawą osłoną"] # 0x2e37 + - "⸸": [T: "odwrócony obelisk"] # 0x2e38 + - "⸹": [T: "górna połowa paragraf znak"] # 0x2e39 + - "⸺": [T: "dwa pauza"] # 0x2e3a + - "⸻": [T: "trzy pauza"] # 0x2e3b + - "〃": [T: "znak powtórzenia"] # 0x3003 + - "〈": [T: "lewy nawias kątowy"] # 0x3008 + - "〉": [T: "prawy nawias kątowy"] # 0x3009 + - "《": [T: "lewy podwójny nawias kątowy"] # 0x300a + - "》": [T: "prawy podwójny nawias kątowy"] # 0x300b + - "「": [T: "lewy nawias narożny"] # 0x300c + - "」": [T: "prawy nawias narożny"] # 0x300d + - "『": [T: "lewy biały nawias narożny"] # 0x300e + - "』": [T: "prawy biały nawias narożny"] # 0x300f + - "【": [T: "lewy czarny nawias soczewkowy"] # 0x3010 + - "】": [T: "prawy czarny nawias soczewkowy"] # 0x3011 + - "〔": [T: "lewy nawias skorupowy"] # 0x3014 + - "〕": [T: "prawy nawias skorupowy"] # 0x3015 + - "〖": [T: "lewy biały nawias soczewkowy"] # 0x3016 + - "〗": [T: "prawy biały nawias soczewkowy"] # 0x3017 + - "〘": [T: "lewy biały nawias skorupowy"] # 0x3018 + - "〙": [T: "prawy biały nawias skorupowy"] # 0x3019 + - "〚": [T: "lewy biały nawias kwadratowy"] # 0x301a + - "〛": [T: "prawy biały nawias kwadratowy"] # 0x301b + - "〜": [T: "falista kreska"] # 0x301c + - "〰": [T: "falista kreska"] # 0x3030 + - "㉈": [T: "liczba dziesięć w kółku na czarnym kwadracie"] # 0x3248 + - "㉉": [T: "liczba dwadzieścia w kółku na czarnym kwadracie"] # 0x3249 + - "㉊": [T: "liczba trzydzieści w kółku na czarnym kwadracie"] # 0x324a + - "㉋": [T: "liczba czterdzieści w kółku na czarnym kwadracie"] # 0x324b + - "㉌": [T: "liczba pięćdziesiąt w kółku na czarnym kwadracie"] # 0x324c + - "㉍": [T: "liczba sześćdziesiąt w kółku na czarnym kwadracie"] # 0x324d + - "㉎": [T: "liczba siedemdziesiąt w kółku na czarnym kwadracie"] # 0x324e + - "㉏": [T: "liczba osiemdziesiąt w kółku na czarnym kwadracie"] # 0x324f + - "㉑": [T: "w kółku numer dwadzieścia jeden"] # 0x3251 + - "㉒": [T: "w kółku numer dwadzieścia dwa"] # 0x3252 + - "㉓": [T: "w kółku numer dwadzieścia trzy"] # 0x3253 + - "㉔": [T: "w kółku numer dwadzieścia cztery"] # 0x3254 + - "㉕": [T: "w kółku numer dwadzieścia pięć"] # 0x3255 + - "㉖": [T: "w kółku numer dwadzieścia sześć"] # 0x3256 + - "㉗": [T: "w kółku numer dwadzieścia siedem"] # 0x3257 + - "㉘": [T: "w kółku numer dwadzieścia osiem"] # 0x3258 + - "㉙": [T: "w kółku numer dwadzieścia dziewięć"] # 0x3259 + - "㉚": [T: "w kółku numer trzydzieści"] # 0x325a + - "㉛": [T: "w kółku numer trzydzieści jeden"] # 0x325b + - "㉜": [T: "w kółku numer trzydzieści dwa"] # 0x325c + - "㉝": [T: "w kółku numer trzydzieści trzy"] # 0x325d + - "㉞": [T: "w kółku numer trzydzieści cztery"] # 0x325e + - "㉟": [T: "w kółku numer trzydzieści pięć"] # 0x325f + - "㊱": [T: "w kółku numer trzydzieści sześć"] # 0x32b1 + - "㊲": [T: "w kółku numer trzydzieści siedem"] # 0x32b2 (GPT-5.4 translation) + - "㊳": [T: "w kółku numer trzydzieści osiem"] # 0x32b3 (GPT-5.4 translation) + - "㊴": [T: "w kółku numer trzydzieści dziewięć"] # 0x32b4 (GPT-5.4 translation) + - "㊵": [T: "w kółku numer czterdzieści"] # 0x32b5 (GPT-5.4 translation) + - "㊶": [T: "w kółku numer czterdzieści jeden"] # 0x32b6 (GPT-5.4 translation) + - "㊷": [T: "w kółku numer czterdzieści dwa"] # 0x32b7 (GPT-5.4 translation) + - "㊸": [T: "w kółku numer czterdzieści trzy"] # 0x32b8 (GPT-5.4 translation) + - "㊹": [T: "w kółku numer czterdzieści cztery"] # 0x32b9 (GPT-5.4 translation) + - "㊺": [T: "w kółku numer czterdzieści pięć"] # 0x32ba (GPT-5.4 translation) + - "㊻": [T: "w kółku numer czterdzieści sześć"] # 0x32bb (GPT-5.4 translation) + - "㊼": [T: "w kółku numer czterdzieści siedem"] # 0x32bc (GPT-5.4 translation) + - "㊽": [T: "w kółku numer czterdzieści osiem"] # 0x32bd (GPT-5.4 translation) + - "㊾": [T: "w kółku numer czterdzieści dziewięć"] # 0x32be (GPT-5.4 translation) + - "㊿": [T: "w kółku numer pięćdziesiąt"] # 0x32bf (GPT-5.4 translation) + - "㋌": [T: "Merkury"] # 0x32cc + - "㋍": [T: "ergi"] # 0x32cd + - "㋎": [T: "elektron wolty"] # 0x32ce + - "㋏": [T: "znak ograniczonej odpowiedzialności"] # 0x32cf + - "㍱": [T: "hektopaskale"] # 0x3371 + - "㍲": [T: "daltony"] # 0x3372 + - "㍳": [T: "jednostki astronomiczne"] # 0x3373 + - "㍴": [T: "bary"] # 0x3374 - "㍵": [T: "o V"] # 0x3375 - - "㍶": [t: "parseki"] # 0x3376 - - "㍷": [t: "decymetry"] # 0x3377 - - "㍸": [t: "decymetry do kwadratu"] # 0x3378 - - "㍹": [t: "decymetry do sześcianu"] # 0x3379 - - "㍺": [t: "jednostki międzynarodowe"] # 0x337a - - "㎀": [t: "pikoampery"] # 0x3380 - - "㎁": [t: "nanoampery"] # 0x3381 - - "㎂": [t: "mikroampery"] # 0x3382 - - "㎃": [t: "miliampery"] # 0x3383 - - "㎄": [t: "kiloampery"] # 0x3384 - - "㎅": [t: "kilobajty"] # 0x3385 - - "㎆": [t: "megabajty"] # 0x3386 - - "㎇": [t: "gigabajty"] # 0x3387 - - "㎈": [t: "kalorie"] # 0x3388 - - "㎉": [t: "kilokalorie"] # 0x3389 - - "㎊": [t: "pikofarady"] # 0x338a - - "㎋": [t: "nanofarady"] # 0x338b - - "㎌": [t: "mikrofarady"] # 0x338c - - "㎍": [t: "mikrogramy"] # 0x338d - - "㎎": [t: "miligramy"] # 0x338e - - "㎏": [t: "kilogramy"] # 0x338f - - "㎐": [t: "herce"] # 0x3390 - - "㎑": [t: "kiloherce"] # 0x3391 - - "㎒": [t: "megaherce"] # 0x3392 - - "㎓": [t: "gigaherce"] # 0x3393 - - "㎔": [t: "teraherce"] # 0x3394 - - "㎕": [t: "mikrolitry"] # 0x3395 - - "㎖": [t: "mililitry"] # 0x3396 - - "㎗": [t: "decylitry"] # 0x3397 - - "㎘": [t: "kilolitry"] # 0x3398 - - "㎙": [t: "femtometry"] # 0x3399 - - "㎚": [t: "nanometry"] # 0x339a - - "㎛": [t: "mikrometry"] # 0x339b - - "㎜": [t: "milimetry"] # 0x339c - - "㎝": [t: "centymetry"] # 0x339d - - "㎞": [t: "kilometry"] # 0x339e - - "㎟": [t: "milimetry do kwadratu"] # 0x339f - - "㎠": [t: "centymetry do kwadratu"] # 0x33a0 - - "㎡": [t: "metry do kwadratu"] # 0x33a1 - - "㎢": [t: "kilometry do kwadratu"] # 0x33a2 - - "㎣": [t: "milimetry do sześcianu"] # 0x33a3 - - "㎤": [t: "centymetry do sześcianu"] # 0x33a4 - - "㎥": [t: "metry do sześcianu"] # 0x33a5 - - "㎦": [t: "kilometry do sześcianu"] # 0x33a6 - - "㎧": [t: "metry na drugi"] # 0x33a7 - - "㎨": [t: "metry na drugi do kwadratu"] # 0x33a8 - - "㎩": [t: "paskale"] # 0x33a9 - - "㎪": [t: "kilopaskale"] # 0x33aa - - "㎫": [t: "megapaskale"] # 0x33ab - - "㎬": [t: "gigapaskale"] # 0x33ac - - "㎭": [t: "radiany"] # 0x33ad - - "㎮": [t: "radiany na sekundę"] # 0x33ae - - "㎯": [t: "radiany na sekundę do kwadratu"] # 0x33af - - "㎰": [t: "pikosekundy"] # 0x33b0 - - "㎱": [t: "nanosekundy"] # 0x33b1 - - "㎲": [t: "mikrosekundy"] # 0x33b2 - - "㎳": [t: "milisekundy"] # 0x33b3 - - "㎴": [t: "pikowolty"] # 0x33b4 - - "㎵": [t: "nanowolty"] # 0x33b5 - - "㎶": [t: "mikrowolty"] # 0x33b6 - - "㎷": [t: "miliwolty"] # 0x33b7 - - "㎸": [t: "kilowolty"] # 0x33b8 - - "㎹": [t: "megawolty"] # 0x33b9 - - "㎺": [t: "pikowaty"] # 0x33ba - - "㎻": [t: "nanowaty"] # 0x33bb - - "㎼": [t: "mikrowaty"] # 0x33bc - - "㎽": [t: "miliwaty"] # 0x33bd - - "㎾": [t: "kilowaty"] # 0x33be - - "㎿": [t: "megawaty"] # 0x33bf - - "㏀": [t: "kilo omy"] # 0x33c0 - - "㏁": [t: "megaomy"] # 0x33c1 - - "㏂": [t: "A M"] # 0x33c2 - - "㏃": [t: "bekerele"] # 0x33c3 - - "㏄": [t: "centymetry sześcienne"] # 0x33c4 - - "㏅": [t: "kandele"] # 0x33c5 - - "㏆": [t: "kulomby na kilogram"] # 0x33c6 - - "㏇": [t: "wielkie C, o, kropka"] # 0x33c7 (I have no idea what this is) - - "㏈": [t: "decybele"] # 0x33c8 - - "㏉": [t: "greje"] # 0x33c9 - - "㏊": [t: "hektary"] # 0x33ca - - "㏋": [t: "konie mechaniczne"] # 0x33cb - - "㏌": [t: "cale"] # 0x33cc - - "㏍": [t: "kilokelwiny"] # 0x33cd - - "㏎": [t: "kilometry"] # 0x33ce - - "㏏": [t: "węzły"] # 0x33cf - - "㏐": [t: "lumeny"] # 0x33d0 + - "㍶": [T: "parseki"] # 0x3376 + - "㍷": [T: "decymetry"] # 0x3377 + - "㍸": [T: "decymetry do kwadratu"] # 0x3378 + - "㍹": [T: "decymetry do sześcianu"] # 0x3379 + - "㍺": [T: "jednostki międzynarodowe"] # 0x337a + - "㎀": [T: "pikoampery"] # 0x3380 + - "㎁": [T: "nanoampery"] # 0x3381 + - "㎂": [T: "mikroampery"] # 0x3382 + - "㎃": [T: "miliampery"] # 0x3383 + - "㎄": [T: "kiloampery"] # 0x3384 + - "㎅": [T: "kilobajty"] # 0x3385 + - "㎆": [T: "megabajty"] # 0x3386 + - "㎇": [T: "gigabajty"] # 0x3387 + - "㎈": [T: "kalorie"] # 0x3388 + - "㎉": [T: "kilokalorie"] # 0x3389 + - "㎊": [T: "pikofarady"] # 0x338a + - "㎋": [T: "nanofarady"] # 0x338b + - "㎌": [T: "mikrofarady"] # 0x338c + - "㎍": [T: "mikrogramy"] # 0x338d + - "㎎": [T: "miligramy"] # 0x338e + - "㎏": [T: "kilogramy"] # 0x338f + - "㎐": [T: "herce"] # 0x3390 + - "㎑": [T: "kiloherce"] # 0x3391 + - "㎒": [T: "megaherce"] # 0x3392 + - "㎓": [T: "gigaherce"] # 0x3393 + - "㎔": [T: "teraherce"] # 0x3394 + - "㎕": [T: "mikrolitry"] # 0x3395 + - "㎖": [T: "mililitry"] # 0x3396 + - "㎗": [T: "decylitry"] # 0x3397 + - "㎘": [T: "kilolitry"] # 0x3398 + - "㎙": [T: "femtometry"] # 0x3399 + - "㎚": [T: "nanometry"] # 0x339a + - "㎛": [T: "mikrometry"] # 0x339b + - "㎜": [T: "milimetry"] # 0x339c + - "㎝": [T: "centymetry"] # 0x339d + - "㎞": [T: "kilometry"] # 0x339e + - "㎟": [T: "milimetry do kwadratu"] # 0x339f + - "㎠": [T: "centymetry do kwadratu"] # 0x33a0 + - "㎡": [T: "metry do kwadratu"] # 0x33a1 + - "㎢": [T: "kilometry do kwadratu"] # 0x33a2 + - "㎣": [T: "milimetry do sześcianu"] # 0x33a3 + - "㎤": [T: "centymetry do sześcianu"] # 0x33a4 + - "㎥": [T: "metry do sześcianu"] # 0x33a5 + - "㎦": [T: "kilometry do sześcianu"] # 0x33a6 + - "㎧": [T: "metry na drugi"] # 0x33a7 + - "㎨": [T: "metry na drugi do kwadratu"] # 0x33a8 + - "㎩": [T: "paskale"] # 0x33a9 + - "㎪": [T: "kilopaskale"] # 0x33aa + - "㎫": [T: "megapaskale"] # 0x33ab + - "㎬": [T: "gigapaskale"] # 0x33ac + - "㎭": [T: "radiany"] # 0x33ad + - "㎮": [T: "radiany na sekundę"] # 0x33ae + - "㎯": [T: "radiany na sekundę do kwadratu"] # 0x33af + - "㎰": [T: "pikosekundy"] # 0x33b0 + - "㎱": [T: "nanosekundy"] # 0x33b1 + - "㎲": [T: "mikrosekundy"] # 0x33b2 + - "㎳": [T: "milisekundy"] # 0x33b3 + - "㎴": [T: "pikowolty"] # 0x33b4 + - "㎵": [T: "nanowolty"] # 0x33b5 + - "㎶": [T: "mikrowolty"] # 0x33b6 + - "㎷": [T: "miliwolty"] # 0x33b7 + - "㎸": [T: "kilowolty"] # 0x33b8 + - "㎹": [T: "megawolty"] # 0x33b9 + - "㎺": [T: "pikowaty"] # 0x33ba + - "㎻": [T: "nanowaty"] # 0x33bb + - "㎼": [T: "mikrowaty"] # 0x33bc + - "㎽": [T: "miliwaty"] # 0x33bd + - "㎾": [T: "kilowaty"] # 0x33be + - "㎿": [T: "megawaty"] # 0x33bf + - "㏀": [T: "kilo omy"] # 0x33c0 + - "㏁": [T: "megaomy"] # 0x33c1 + - "㏂": [T: "A M"] # 0x33c2 + - "㏃": [T: "bekerele"] # 0x33c3 + - "㏄": [T: "centymetry sześcienne"] # 0x33c4 + - "㏅": [T: "kandele"] # 0x33c5 + - "㏆": [T: "kulomby na kilogram"] # 0x33c6 + - "㏇": [T: "wielkie C, o, kropka"] # 0x33c7 (I have no idea what this is) + - "㏈": [T: "decybele"] # 0x33c8 + - "㏉": [T: "greje"] # 0x33c9 + - "㏊": [T: "hektary"] # 0x33ca + - "㏋": [T: "konie mechaniczne"] # 0x33cb + - "㏌": [T: "cale"] # 0x33cc + - "㏍": [T: "kilokelwiny"] # 0x33cd + - "㏎": [T: "kilometry"] # 0x33ce + - "㏏": [T: "węzły"] # 0x33cf + - "㏐": [T: "lumeny"] # 0x33d0 - "㏑": [T: "logarytm naturalny"] # 0x33d1 - - "㏒": [t: "logarytm"] # 0x33d2 - - "㏓": [t: "luksy"] # 0x33d3 - - "㏔": [t: "milibarny"] # 0x33d4 - - "㏕": [t: "mile"] # 0x33d5 - - "㏖": [t: "mole"] # 0x33d6 + - "㏒": [T: "logarytm"] # 0x33d2 + - "㏓": [T: "luksy"] # 0x33d3 + - "㏔": [T: "milibarny"] # 0x33d4 + - "㏕": [T: "mile"] # 0x33d5 + - "㏖": [T: "mole"] # 0x33d6 - "㏗": [T: "p h"] # 0x33d7 - - "㏘": [t: "pikometry"] # 0x33d8 - - "㏙": [t: "części na milion"] # 0x33d9 - - "㏚": [t: "petarentgeny"] # 0x33da - - "㏛": [t: "steradiany"] # 0x33db - - "㏜": [t: "siwerty"] # 0x33dc - - "㏝": [t: "webery"] # 0x33dd - - "㏞": [t: "wolty na metr"] # 0x33de - - "㏟": [t: "ampery na metr"] # 0x33df - - "㏿": [t: "galony"] # 0x33ff - - "": [t: "równa się z daszkiem pod"] # 0xe900 - - "": [t: "równa się z plusem nad"] # 0xe901 - - "": [t: "równa się z plusem pod"] # 0xe902 - - "": [t: "tylda z plusem nad"] # 0xe903 - - "": [t: "tylda z plusem pod"] # 0xe904 - - "": [t: "równe podwójny przez większe niż"] # 0xe908 - - "": [t: "równe podwójny przez mniejsze niż"] # 0xe909 - - "": [t: "zawiera lub równe"] # 0xe90a - - "": [t: "nadzbiór lub równy"] # 0xe90b - - "": [t: "podzbiór lub równy"] # 0xe90c - - "": [t: "równe przez mniejsze niż"] # 0xe90d - - "": [t: "należy do lub równe"] # 0xe912 - - "": [t: "równe lub większe niż"] # 0xe913 - - "": [t: "przybliżone nadzbiór"] # 0xe914 - - "": [t: "przybliżone podzbiór"] # 0xe915 - - "": [t: "nadzbiór z kropką zawiera jako relację indeksu dolnego"] # 0xe916 - - "": [t: "podzbiór z kropką jest zawarty jako relacja indeksu dolnego"] # 0xe917 - - "": [t: "równe z kropką pod"] # 0xe918 - - "": [t: "lewy kropka nad minus przez prawy kropka"] # 0xe919 - - "": [t: "prawy kropka nad minus przez lewy kropka"] # 0xe91a - - "": [t: "w przybliżeniu równe minus"] # 0xe91f - - "": [t: "podwójna kwadratowa suma zbiorów"] # 0xe920 - - "": [t: "podwójny kwadrat wielka"] # 0xe921 - - "": [t: "mniejsze niż równe lub większe niż"] # 0xe922 - - "": [t: "tylda z kropką"] # 0xe924 - - "": [t: "tylda z dwiema kropkami"] # 0xe925 - - "": [t: "mniejsze niż większe lub równe"] # 0xe926 - - "": [t: "większe niż mniejsze lub równe"] # 0xe927 - - "": [t: "Równoważne lub mniejsze niż"] # 0xe928 - - "": [t: "Równoważne lub większe niż"] # 0xe929 - - "": [t: "lewy otwórz ramka operator"] # 0xe92a - - "": [t: "prawy otwórz ramka operator"] # 0xe92b - - "": [t: "identyczne z kropką"] # 0xe92c - - "": [t: "większe niż równe lub mniejsze niż"] # 0xe92d - - "": [t: "kreska operator"] # 0xe92e - - "": [t: "podwójny kreska operator"] # 0xe92f - - "": [t: "potrójny kreska operator"] # 0xe930 - - "": [t: "mniejsze niż lub w przybliżeniu równe"] # 0xe932 - - "": [t: "większe niż lub w przybliżeniu równe"] # 0xe933 - - "": [t: "zagnieżdżone mniejsze niż"] # 0xe936 - - "": [t: "zagnieżdżone większe niż"] # 0xe937 - - "": [t: "poprzedza lub Równoważne"] # 0xe93a - - "": [t: "następuje po lub Równoważne"] # 0xe93b - - "": [t: "poprzedza nad równe"] # 0xe940 - - "": [t: "następuje po nad równe"] # 0xe941 - - "": [t: "mniejsze niż nad ukośnie równe nad większe niż"] # 0xe942 - - "": [t: "większe niż nad ukośnie równe nad mniejsze niż"] # 0xe943 - - "": [t: "spełnione przez"] # 0xe948 - - "": [t: "leniwe s"] # 0xe949 - - "": [t: "nie asercja"] # 0xe94a - - "": [t: "podwójny równe"] # 0xe94b - - "": [t: "potrójny równe"] # 0xe94c - - "": [t: "reguła opóźniona"] # 0xe94d - - "": [t: "alias ogranicznika"] # 0xe94e - - "": [t: "normalna podgrupa z kreską"] # 0xe950 - - "": [t: "zawiera jako normalny podgrupa z kreską"] # 0xe951 - - "": [t: "zaokrąglone implikuje"] # 0xe954 - - "": [t: "uśmiech pod kreską"] # 0xe955 - - "": [t: "smutek przez kreskę"] # 0xe956 - - "": [t: "nadzbiór lub w przybliżeniu równe"] # 0xe957 - - "": [t: "podzbiór lub w przybliżeniu równe"] # 0xe958 - - "": [t: "większe niż w przybliżeniu równe lub mniejsze niż"] # 0xe959 - - "": [t: "mniejsze niż w przybliżeniu równe lub większe niż"] # 0xe95a - - "": [t: "podwójny logiczne lub"] # 0xe95c - - "": [t: "podwójna koniunkcja logiczna"] # 0xe95d - - "": [t: "alternatywa logiczna z podwójną kreską pod"] # 0xe95e - - "": [t: "logiczne lub z kreską pod"] # 0xe95f - - "": [t: "w przybliżeniu równe nad równe"] # 0xe962 - - "": [t: "trójkąt skierowany w lewo z kreską dzielącą"] # 0xe964 - - "": [t: "trójkąt skierowany w prawo z kreską dzielącą"] # 0xe965 - - "": [t: "równa się z kropkowaną górną linią"] # 0xe966 - - "": [t: "poprzedza z dwukropkiem"] # 0xe967 - - "": [t: "następuje po z dwukropkiem"] # 0xe968 - - "": [t: "mniejsze niż lub ukośnie równe"] # 0xe969 - - "": [t: "większe niż lub ukośnie równe"] # 0xe96a - - "": [t: "zagnieżdżone bardzo znacznie mniejsze niż"] # 0xe96b - - "": [t: "zagnieżdżone bardzo znacznie większe niż"] # 0xe96c - - "": [t: "wariant różnicy między"] # 0xe96d - - "": [t: "mniejsze niż większe niż nakładka"] # 0xe96e - - "": [t: "alternatywa logiczna z nałożoną koniunkcją logiczną"] # 0xe96f - - "": [t: "nadzbiór przez nadzbiór"] # 0xe970 - - "": [t: "podzbiór przez podzbiór"] # 0xe971 - - "": [t: "nadzbiór przez podzbiór"] # 0xe972 - - "": [t: "podzbiór przez nadzbiór"] # 0xe973 - - "": [t: "potrójna pionowa kreska"] # 0xe979 - - "": [t: "sparowane poczwórne pionowe kropki"] # 0xe97a - - "": [t: "prostopadłe przez kreskę"] # 0xe97b - - "": [t: "lewy znak dedukcji z podwójną pionową kreską"] # 0xe97c - - "": [t: "podwójny lewy znak dedukcji z podwójną pionową kreską"] # 0xe97d - - "": [t: "prostopadłe przez odwrócony prostopadłe"] # 0xe97e - - "": [t: "podwójny lewy znak dedukcji z pionową kreską"] # 0xe97f - - "": [t: "kąt sferyczny otwarty w górę"] # 0xe980 - - "": [t: "podwójny ukośnik"] # 0xe981 - - "": [t: "kąt prosty z narożnikiem"] # 0xe982 - - "": [t: "pionowa kreska w kółku"] # 0xe984 - - "": [t: "znak dzielenia w kółku"] # 0xe985 - - "": [t: "kreskowany ukośnik"] # 0xe986 - - "": [t: "kreskowany ukośnik odwrotny"] # 0xe987 - - "": [t: "kreskowana linia środkowa"] # 0xe988 - - "": [t: "kreskowana pionowa kreska"] # 0xe989 - - "": [t: "prostopadłe z s"] # 0xe98a - - "": [t: "kąt z s"] # 0xe98b - - "": [t: "kąt sferyczny otwarty w lewo"] # 0xe98c - - "": [t: "kąt otwarty w lewo"] # 0xe98d - - "": [t: "pionowa kreska z podwójnym haczykiem"] # 0xe98e - - "": [t: "operator średniej kropki wolnego rodnika"] # 0xe98f - - "": [t: "biały trójkąt skierowany w górę nad kreską"] # 0xe990 - - "": [t: "identyczne i równoległe do"] # 0xe991 - - "": [t: "iloczyn spłaszczony"] # 0xe992 - - "": [t: "potrójny operator kreski z kreską poziomą"] # 0xe993 - - "": [t: "identyczne z podwójnym ukośnikiem"] # 0xe994 - - "": [t: "potrójne skrzyżowane kreski"] # 0xe995 - - "": [t: "pionowa kreska przez okrąg"] # 0xe996 - - "": [t: "pionowy proporcjonalne do"] # 0xe997 - - "": [t: "czarna ostatnia kwadra księżyca"] # 0xe998 - - "": [t: "czarna pierwsza kwadra księżyca"] # 0xe999 - - "": [t: "ujemna fala sinusoidalna"] # 0xe9a0 - - "": [t: "kropka w nawiasach"] # 0xe9a1 - - "": [t: "nawiasy"] # 0xe9a2 - - "": [t: "biały uśmiech"] # 0xe9a3 - - "": [t: "biały smutek"] # 0xe9a4 - - "": [t: "sześciokąt"] # 0xe9a5 - - "": [t: "Równoważne nad plus"] # 0xe9a6 - - "": [t: "plus przez Równoważne"] # 0xe9a7 - - "": [t: "część wspólna z szeryfami"] # 0xe9b0 - - "": [t: "suma zbiorów z szeryfami"] # 0xe9b1 - - "": [t: "kwadratowa część wspólna z szeryfami"] # 0xe9b2 - - "": [t: "kwadratowa suma zbiorów z szeryfami"] # 0xe9b3 - - "": [t: "poprzedza Równoważne lub następuje po"] # 0xe9e0 - - "": [t: "następuje po Równoważne lub poprzedza"] # 0xe9e1 - - "": [t: "poprzedza w przybliżeniu równe lub następuje po"] # 0xe9e2 - - "": [t: "następuje po w przybliżeniu równe lub poprzedza"] # 0xe9e3 - - "": [t: "mniejsze niż Równoważne lub większe niż"] # 0xe9f0 - - "": [t: "większe niż Równoważne lub mniejsze niż"] # 0xe9f1 - - "": [t: "pionowo przekreślone znacznie mniejsze niż"] # 0xea00 - - "": [t: "pionowo przekreślone znacznie większe niż"] # 0xea01 - - "": [t: "nie jest znacznie mniejsze niż, wariant"] # 0xea02 - - "": [t: "nie jest znacznie większe niż, wariant"] # 0xea03 - - "": [t: "mniejsze niż z pionową kreską i nie podwójne równe"] # 0xea04 - - "": [t: "większe niż z pionową kreską i nie podwójne równe"] # 0xea05 - - "": [t: "nie mniejsze lub równe"] # 0xea06 - - "": [t: "nie większe lub równe"] # 0xea07 - - "": [t: "ani równe, ani mniejsze niż"] # 0xea09 - - "": [t: "nie zawiera lub równe"] # 0xea0a - - "": [t: "ani nadzbiór, ani równe"] # 0xea0b - - "": [t: "ani podzbiór, ani równe"] # 0xea0c - - "": [t: "ukośnik odwrotny z podzbiorem"] # 0xea0d - - "": [t: "ani równe, ani większe niż"] # 0xea0e - - "": [t: "nie minus operator tyldy"] # 0xea0f - - "": [t: "ani równe, ani mniejsze niż"] # 0xea10 - - "": [t: "nie operator tyldy"] # 0xea11 - - "": [t: "nie jest elementem zbioru lub równe"] # 0xea12 - - "": [t: "ani równe, ani większe niż"] # 0xea13 - - "": [t: "nie w przybliżeniu równe"] # 0xea14 - - "": [t: "nie następuje po podobne"] # 0xea15 - - "": [t: "mniejsze niż lub ukośnie równe z ukośnikiem"] # 0xea16 - - "": [t: "większe niż lub ukośnie równe z ukośnikiem"] # 0xea17 - - "": [t: "nadzbiór ukośnik"] # 0xea1a - - "": [t: "nie zawiera"] # 0xea1b - - "": [t: "nie mniejsze lub równe"] # 0xea1d - - "": [t: "nie większe lub równe"] # 0xea1e - - "": [t: "nie w przybliżeniu równe minus"] # 0xea1f - - "": [t: "zanegowana przynależność do zbioru z kropką nad"] # 0xea22 - - "": [t: "nie kąt pionowy"] # 0xea2c - - "": [t: "nie ukośnie równoległe"] # 0xea2d - - "": [t: "nie kreska operator"] # 0xea2e - - "": [t: "nie podwójny kreska operator"] # 0xea2f - - "": [t: "nie potrójny kreska operator"] # 0xea30 - - "": [t: "mniejsze niż ale nie w przybliżeniu równe"] # 0xea32 - - "": [t: "większe niż ale nie w przybliżeniu równe"] # 0xea33 - - "": [t: "mniejsze niż lub nie równa się"] # 0xea34 - - "": [t: "większe niż lub nie równa się"] # 0xea35 - - "": [t: "nie zagnieżdżone mniejsze niż"] # 0xea36 - - "": [t: "nie zagnieżdżone większe niż"] # 0xea37 - - "": [t: "nie jest znacznie mniejsze niż"] # 0xea38 - - "": [t: "nie jest znacznie większe niż"] # 0xea39 - - "": [t: "poprzedza ale nie Równoważne"] # 0xea3a - - "": [t: "następuje po ale nie Równoważne"] # 0xea3b - - "": [t: "poprzedza ale nie równa się"] # 0xea3c - - "": [t: "następuje po ale nie równa się"] # 0xea3d - - "": [t: "nie równa się ani nie poprzedza"] # 0xea3e - - "": [t: "nie równa się ani nie następuje po"] # 0xea3f - - "": [t: "poprzedza ale nie równa się"] # 0xea40 - - "": [t: "następuje po ale nie równa się"] # 0xea41 - - "": [t: "ani podzbiór, ani równe"] # 0xea42 - - "": [t: "ani nadzbiór, ani równe"] # 0xea43 - - "": [t: "podzbiór lub nie równa się"] # 0xea44 - - "": [t: "nadzbiór lub nie równa się"] # 0xea45 - - "": [t: "ani podzbiór, ani równe"] # 0xea46 - - "": [t: "ani nadzbiór, ani równe"] # 0xea47 - - "": [t: "nie potrójny mniejsze niż"] # 0xea48 - - "": [t: "nie potrójny większe niż"] # 0xea49 - - "": [t: "nie poprzedza równa się"] # 0xea4c - - "": [t: "nie następuje po równa się"] # 0xea4d - - "": [t: "nie normalna podgrupa z kreską"] # 0xea50 - - "": [t: "nie zawiera jako normalnej podgrupy z kreską"] # 0xea51 - - "": [t: "nie różnica między"] # 0xea52 - - "": [t: "nie geometrycznie równoważne"] # 0xea53 - - "": [t: "nie pionowo podobne"] # 0xea54 - - "": [t: "nie równe lub podobne"] # 0xea55 - - "": [t: "nie pionowo przybliżone"] # 0xea56 - - "": [t: "nie w przybliżeniu identyczne z"] # 0xea57 - - "": [t: "nie wyboiście równe"] # 0xea58 - - "": [t: "nie wyboiście pojedynczo równe"] # 0xea59 - - "": [t: "nie równe kropka"] # 0xea5a - - "": [t: "odwrotne nie równoważne"] # 0xea5b - - "": [t: "nie kwadrat podzbiór"] # 0xea60 - - "": [t: "nie kwadrat nadzbiór"] # 0xea61 - - "": [t: "nie w przybliżeniu równe nad znakiem równości"] # 0xea62 - - "": [t: "nie ściśle równoważne"] # 0xea63 - - "": [t: "nie przystające z kropką"] # 0xea64 - - "": [t: "odwrotnie nie równe"] # 0xea65 - - "": [t: "nie pionowy lewy trójkąt równa się"] # 0xea70 - - "": [t: "nie pionowy prawy trójkąt równa się"] # 0xea71 - - "": [t: "nie cząstkowe"] # 0xea80 - - "": [t: "ozdobnik przedłużenia strzałki"] # 0xeb00 - - "": [t: "strzałka prawy przeze strzałką lewy"] # 0xeb01 - - "": [t: "strzałka prawy przeze strzałką lewy"] # 0xeb02 - - "": [t: "harpun prawy przez harpun lewy"] # 0xeb03 - - "": [t: "harpun prawy przez harpun lewy"] # 0xeb04 - - "": [t: "podwójna strzałka północny wschód południowy zachód"] # 0xeb05 - - "": [t: "podwójna strzałka północny zachód południowy wschód"] # 0xeb06 - - "": [t: "poziome przedłużenie harpuna"] # 0xeb07 - - "": [t: "łuk ze strzałką w lewo przeciwnie do ruchu wskazówek zegara"] # 0xeb08 - - "": [t: "łuk ze strzałką w prawo przeciwnie do ruchu wskazówek zegara"] # 0xeb09 - - "": [t: "duży strzałka w prawo akcent"] # 0xeb0b - - "": [t: "duży strzałka w lewo akcent"] # 0xeb0c - - "": [t: "lewy grot strzałki"] # 0xeb0d - - "": [t: "prawy grot strzałki"] # 0xeb0e - - "": [t: "duża strzałka w prawo z lewym przekreśleniem"] # 0xeb0f - - "": [t: "poziome przedłużenie podwójnej strzałki"] # 0xeb10 - - "": [t: "duża podwójna strzałka w lewo i prawo z przekreśleniem"] # 0xeb11 - - "": [t: "strzałka w dół po lewej i strzałka w górę"] # 0xeb12 - - "": [t: "strzałka w lewo z dolnym narożnikiem"] # 0xeb13 - - "": [t: "strzałka w prawo z górnym narożnikiem"] # 0xeb14 - - "": [t: "strzałka w lewo z górnym narożnikiem"] # 0xeb15 - - "": [t: "strzałka po górnym półokręgu przeciwnie do ruchu wskazówek zegara z plusem"] # 0xeb16 - - "": [t: "strzałka po górnym półokręgu zgodnie z ruchem wskazówek zegara z minusem"] # 0xeb17 - - "": [t: "strzałka w prawo z ogonem i przekreśleniem"] # 0xeb18 - - "": [t: "prawy harpun dolny"] # 0xeb19 - - "": [t: "lewy harpun dolny"] # 0xeb1a - - "": [t: "lewy prawy harpun dolny"] # 0xeb1b - - "": [t: "lewy prawy harpun górny"] # 0xeb1c - - "": [t: "górny dolny harpun lewy"] # 0xeb1d - - "": [t: "górny dolny harpun prawy"] # 0xeb1e - - "": [t: "strzałka w górę w prawo ze strzałką w dół"] # 0xeb1f - - "": [t: "lewy harpun do kreski z grotem górnym"] # 0xeb20 - - "": [t: "prawy harpun do kreski z grotem górnym"] # 0xeb21 - - "": [t: "lewy harpun do kreski z grotem dolnym"] # 0xeb22 - - "": [t: "prawy harpun do kreski z grotem dolnym"] # 0xeb23 - - "": [t: "lewy harpun od kreski z grotem górnym"] # 0xeb24 - - "": [t: "prawy harpun od kreski z grotem górnym"] # 0xeb25 - - "": [t: "lewy harpun od kreski z grotem dolnym"] # 0xeb26 - - "": [t: "prawy harpun od kreski z grotem dolnym"] # 0xeb27 - - "": [t: "górny harpun do kreski z grotem lewym"] # 0xeb28 - - "": [t: "dolny harpun do kreski z grotem lewym"] # 0xeb29 - - "": [t: "górny harpun do kreski z grotem prawym"] # 0xeb2a - - "": [t: "dolny harpun do kreski z grotem prawym"] # 0xeb2b - - "": [t: "górny harpun od kreski z grotem lewym"] # 0xeb2c - - "": [t: "dolny harpun od kreski z grotem lewym"] # 0xeb2d - - "": [t: "górny harpun od kreski z grotem prawym"] # 0xeb2e - - "": [t: "dolny harpun od kreski z grotem prawym"] # 0xeb2f - - "": [t: "strzałka w górę do kreski"] # 0xeb30 - - "": [t: "strzałka w dół do kreski"] # 0xeb31 - - "": [t: "górny harpun w lewo z dolnym harpunem"] # 0xeb32 - - "": [t: "górny harpun w prawo z dolnym harpunem"] # 0xeb33 - - "": [t: "górny grot strzałki"] # 0xeb34 - - "": [t: "dolny grot strzałki"] # 0xeb35 - - "": [t: "podwójny harpun z lewym grotem dolnym i prawym grotem górnym"] # 0xeb36 - - "": [t: "podwójny harpun z lewym grotem górnym i prawym grotem dolnym"] # 0xeb37 - - "": [t: "strzałka w lewo przez kreskę"] # 0xeb38 - - "": [t: "strzałka w prawo przez kreskę"] # 0xeb39 - - "": [t: "strzałka w lewo pod kreski"] # 0xeb3a - - "": [t: "strzałka w prawo pod kreski"] # 0xeb3b - - "": [t: "lewy prawy potrójny strzałka"] # 0xeb3c - - "": [t: "podwójna strzałka północny wschód południowy wschód"] # 0xeb3f - - "": [t: "strzałka po lewym półokręgu przeciwnie do ruchu wskazówek zegara"] # 0xeb40 - - "": [t: "strzałka po lewym półokręgu zgodnie z ruchem wskazówek zegara"] # 0xeb41 - - "": [t: "lewy otwarty okrąg lewy strzałka w prawo"] # 0xeb42 - - "": [t: "strzałka w prawo przez tylda"] # 0xeb44 - - "": [t: "strzałka w lewo przez tylda"] # 0xeb45 - - "": [t: "lewy harpun przez kreskę"] # 0xeb48 - - "": [t: "prawy harpun przez kreskę"] # 0xeb49 - - "": [t: "lewy harpun pod kreski"] # 0xeb4a - - "": [t: "prawy harpun pod kreski"] # 0xeb4b - - "": [t: "krótka czarna strzałka w lewo"] # 0xeb4c - - "": [t: "strzałka po prawym półokręgu zgodnie z ruchem wskazówek zegara"] # 0xeb50 - - "": [t: "strzałka po prawym półokręgu przeciwnie do ruchu wskazówek zegara"] # 0xeb51 - - "": [t: "lewy otwarty okrąg lewy prawy harpun"] # 0xeb52 - - "": [t: "strzałka w górę lewy z pionową kreską"] # 0xeb58 - - "": [t: "strzałka w dół lewy z pionową kreską"] # 0xeb59 - - "": [t: "strzałka w górę prawy z pionową kreską"] # 0xeb5a - - "": [t: "strzałka w dół prawy z pionową kreską"] # 0xeb5b - - "": [t: "strzałka w prawo z wydłużonym dolnym hakiem"] # 0xeb5c - - "": [t: "strzałka w lewo z wydłużonym hakiem"] # 0xeb5d - - "": [t: "strzałka w lewo z wydłużonym dolnym hakiem"] # 0xeb5e - - "": [t: "strzałka w prawo z wydłużonym hakiem"] # 0xeb5f - - "": [t: "nie strzałka w prawo falista"] # 0xeb60 - - "": [t: "nie strzałka w prawo zakrzywiony"] # 0xeb61 - - "": [t: "górny harpun lewy z pionową kreską"] # 0xeb68 - - "": [t: "dolny harpun lewy z pionową kreską"] # 0xeb69 - - "": [t: "górny harpun prawy z pionową kreską"] # 0xeb6a - - "": [t: "dolny harpun prawy z pionową kreską"] # 0xeb6b - - "": [t: "pionowe przedłużenie podwójnej strzałki"] # 0xeb6c - - "": [t: "pionowe przedłużenie harpuna z grotem w lewo"] # 0xeb6d - - "": [t: "pionowe przedłużenie harpuna z grotem w prawo"] # 0xeb6e - - "": [t: "prawy harpun przez lewy harpun prawy"] # 0xeb6f - - "": [t: "prawy harpun przez lewy harpun lewy"] # 0xeb70 - - "": [t: "lewy harpun przez prawy harpun prawy"] # 0xeb71 - - "": [t: "lewy harpun przez prawy harpun lewy"] # 0xeb72 - - "": [t: "strzałka w lewo od kreski z grotem strzałki"] # 0xeb73 - - "": [t: "przedłużenie strzałki w prawo od lewej kreski"] # 0xeb74 - - "": [t: "strzałka w lewo od kreski ogon"] # 0xeb75 - - "": [t: "strzałka w prawo od kreski ogon"] # 0xeb76 - - "": [t: "strzałka w prawo od kreski z grotem strzałki"] # 0xeb77 - - "": [t: "górny harpun od kreski z lewym grotem strzałki"] # 0xeb78 - - "": [t: "strzałka w prawo nad strzałką w lewo prawy"] # 0xeb79 - - "": [t: "strzałka w prawo nad strzałką w lewo lewy"] # 0xeb7a - - "": [t: "strzałka w lewo nad strzałką w prawo prawy"] # 0xeb7b - - "": [t: "strzałka w lewo nad strzałką w prawo lewy"] # 0xeb7c - - "": [t: "strzałka w górę od kreski z grotem strzałki"] # 0xeb7d - - "": [t: "strzałka w górę od kreski ogon"] # 0xeb7e - - "": [t: "strzałka w dół od kreski ogon"] # 0xeb7f - - "": [t: "strzałka w dół od kreski z grotem strzałki"] # 0xeb80 - - "": [t: "dolny harpun od kreski z prawym grotem strzałki"] # 0xeb81 - - "": [t: "górny harpun w lewo z dolnym harpunem dolny"] # 0xeb82 - - "": [t: "przedłużenie górnego harpuna w lewo i dolnego harpuna"] # 0xeb83 - - "": [t: "dolny harpun w lewo z górnym harpunem górny"] # 0xeb84 - - "": [t: "górny harpun w lewo z dolnym harpunem górny"] # 0xeb85 - - "": [t: "przedłużenie dolnego harpuna w lewo i górnego harpuna"] # 0xeb86 - - "": [t: "dolny harpun w lewo z górnym harpunem dolny"] # 0xeb87 - - "": [t: "strzałka w górę po lewej i strzałka w dół dolny"] # 0xeb88 - - "": [t: "strzałka w dół po lewej i strzałka w górę górny"] # 0xeb89 - - "": [t: "strzałka w górę po lewej i strzałka w dół górny"] # 0xeb8a - - "": [t: "strzałka w dół po lewej i strzałka w górę dolny"] # 0xeb8b - - "": [t: "przedłużenie strzałki w lewo i w prawo"] # 0xeb8c - - "": [t: "przedłużenie strzałki północno-wschodniej"] # 0xeb8d - - "": [t: "przedłużenie strzałki północno-zachodniej"] # 0xeb8e - - "": [t: "lewa część dolnego nawiasu klamrowego"] # 0xec00 - - "": [t: "środkowa część dolnego nawiasu klamrowego"] # 0xec01 - - "": [t: "prawa część dolnego nawiasu klamrowego"] # 0xec02 - - "": [t: "poziome przedłużenie nawiasu klamrowego"] # 0xec03 - - "": [t: "lewa część górnego nawiasu klamrowego"] # 0xec04 - - "": [t: "środkowa część górnego nawiasu klamrowego"] # 0xec05 - - "": [t: "prawa część górnego nawiasu klamrowego"] # 0xec06 - - "": [t: "lewa pionowa kreska"] # 0xec07 - - "": [t: "prawa pionowa kreska"] # 0xec08 - - "": [t: "lewa podwójna pionowa kreska"] # 0xec09 - - "": [t: "prawa podwójna pionowa kreska"] # 0xec0a - - "": [t: "poziome przedłużenie nawiasu kwadratowego"] # 0xec0b - - "": [t: "dolny nawias kwadratowy"] # 0xec0c - - "⎵": [t: "dolny nawias kwadratowy"] # 0x23b5 - - "": [t: "górny nawias kwadratowy"] # 0xec0d - - "⎴": [t: "górny nawias kwadratowy"] # 0x23b4 - - "": [t: "pod nawias kwadratowy lewy"] # 0xec0e - - "": [t: "pod nawias kwadratowy prawy"] # 0xec0f - - "": [t: "przez nawias kwadratowy lewy"] # 0xec10 - - "": [t: "przez nawias kwadratowy prawy"] # 0xec11 - - "": [t: "lewy nawias okrągły 1"] # 0xec12 - - "": [t: "lewy nawias okrągły 2"] # 0xec13 - - "": [t: "lewy nawias okrągły 3"] # 0xec14 - - "": [t: "lewy nawias okrągły 4"] # 0xec15 - - "": [t: "prawy nawias okrągły 1"] # 0xec16 - - "": [t: "prawy nawias okrągły 2"] # 0xec17 - - "": [t: "prawy nawias okrągły 3"] # 0xec18 - - "": [t: "prawy nawias okrągły 4"] # 0xec19 - - "": [t: "znak pierwiastka 1"] # 0xec1a - - "": [t: "znak pierwiastka 2"] # 0xec1b - - "": [t: "znak pierwiastka 3"] # 0xec1c - - "": [t: "znak pierwiastka 4"] # 0xec1d - - "": [t: "znak pierwiastka 5"] # 0xec1e - - "": [t: "dolna część znaku pierwiastka"] # 0xec1f - - "": [t: "pionowe przedłużenie znaku pierwiastka"] # 0xec20 - - "": [t: "górna część znaku pierwiastka"] # 0xec21 - - "": [t: "lewy biały nawias kwadratowy górny"] # 0xec22 - - "": [t: "przedłużenie lewego białego nawiasu kwadratowego"] # 0xec23 - - "": [t: "lewy biały nawias kwadratowy dolny"] # 0xec24 - - "": [t: "prawy biały nawias kwadratowy górny"] # 0xec25 - - "": [t: "przedłużenie prawego białego nawiasu kwadratowego"] # 0xec26 - - "": [t: "prawy biały nawias kwadratowy dolny"] # 0xec27 - - "": [t: "lewy biały zakrzywiony nawias kwadratowy"] # 0xec30 - - "": [t: "prawy biały zakrzywiony nawias kwadratowy"] # 0xec31 - - "": [t: "znak dzielenia pisemnego"] # 0xec32 - - "": [t: "przedłużenie znaku dzielenia pisemnego"] # 0xec33 - - "": [t: "krótkie dzielenie"] # 0xec34 - - "": [t: "podwójne wiązanie em od południowego zachodu do północnego wschodu"] # 0xec40 - - "": [t: "podwójne wiązanie em od północnego zachodu do południowego wschodu"] # 0xec41 - - "": [t: "pojedyncze poziome wiązanie em"] # 0xec42 - - "": [t: "podwójne poziome wiązanie em"] # 0xec43 - - "": [t: "potrójne poziome wiązanie em"] # 0xec44 - - "": [t: "pojedyncze pionowe wiązanie em"] # 0xec45 - - "": [t: "podwójne pionowe wiązanie em"] # 0xec46 - - "": [t: "potrójne pionowe wiązanie em"] # 0xec47 - - "": [t: "wiązanie em mniejsze niż"] # 0xec48 - - "": [t: "wiązanie em większe niż"] # 0xec49 - - "": [t: "pojedyncze poziome wiązanie en"] # 0xec4a - - "": [t: "podwójne poziome wiązanie en"] # 0xec4b - - "": [t: "potrójne poziome wiązanie en"] # 0xec4c - - "": [t: "górny lewy prostokąt"] # 0xec80 - - "": [t: "dolny lewy prostokąt"] # 0xec81 - - "": [t: "górny prawy prostokąt"] # 0xec90 - - "": [t: "dolny prawy prostokąt"] # 0xec91 - - "": [t: "narożnik dzielenia syntetycznego"] # 0xec92 - - "": [t: "poziome przedłużenie dzielenia syntetycznego"] # 0xec93 - - "": [t: "pionowe przedłużenie dzielenia syntetycznego"] # 0xec94 - - "": [t: "lewy przedłużacz sufitu i podłogi"] # 0xec95 - - "": [t: "prawy przedłużacz sufitu i podłogi"] # 0xec96 - - "": [t: "przedłużenie przez nawias kwadratowy"] # 0xec97 - - "": [t: "pionowe przedłużenie kreski"] # 0xec98 - - "": [t: "lewy podwójny pionowe przedłużenie kreski"] # 0xec99 - - "": [t: "poziome przedłużenie kreski"] # 0xec9a - - "": [t: "przedłużenie pod nawiasem kwadratowym"] # 0xec9c - - "": [t: "prawa część dolnego nawiasu"] # 0xec9d - - "": [t: "przedłużenie dolnego nawiasu"] # 0xec9e - - "": [t: "lewa część dolnego nawiasu"] # 0xec9f - - "": [t: "przedłużenie górnego nawiasu klamrowego"] # 0xeca0 - - "": [t: "lewa część górnego nawiasu"] # 0xeca1 - - "": [t: "przedłużenie górnego nawiasu"] # 0xeca2 - - "": [t: "prawa część górnego nawiasu"] # 0xeca3 - - "": [t: "przedłużenie dolnego nawiasu klamrowego"] # 0xeca4 - - "": [t: "stała Plancka przez dwa pi kreska"] # 0xed00 - - "": [t: "lustrzane g"] # 0xed01 - - "": [t: "j bez kropki"] # 0xed02 + - "㏘": [T: "pikometry"] # 0x33d8 + - "㏙": [T: "części na milion"] # 0x33d9 + - "㏚": [T: "petarentgeny"] # 0x33da + - "㏛": [T: "steradiany"] # 0x33db + - "㏜": [T: "siwerty"] # 0x33dc + - "㏝": [T: "webery"] # 0x33dd + - "㏞": [T: "wolty na metr"] # 0x33de + - "㏟": [T: "ampery na metr"] # 0x33df + - "㏿": [T: "galony"] # 0x33ff + - "": [T: "równa się z daszkiem pod"] # 0xe900 + - "": [T: "równa się z plusem nad"] # 0xe901 + - "": [T: "równa się z plusem pod"] # 0xe902 + - "": [T: "tylda z plusem nad"] # 0xe903 + - "": [T: "tylda z plusem pod"] # 0xe904 + - "": [T: "równe podwójny przez większe niż"] # 0xe908 + - "": [T: "równe podwójny przez mniejsze niż"] # 0xe909 + - "": [T: "zawiera lub równe"] # 0xe90a + - "": [T: "nadzbiór lub równy"] # 0xe90b + - "": [T: "podzbiór lub równy"] # 0xe90c + - "": [T: "równe przez mniejsze niż"] # 0xe90d + - "": [T: "należy do lub równe"] # 0xe912 + - "": [T: "równe lub większe niż"] # 0xe913 + - "": [T: "przybliżone nadzbiór"] # 0xe914 + - "": [T: "przybliżone podzbiór"] # 0xe915 + - "": [T: "nadzbiór z kropką zawiera jako relację indeksu dolnego"] # 0xe916 + - "": [T: "podzbiór z kropką jest zawarty jako relacja indeksu dolnego"] # 0xe917 + - "": [T: "równe z kropką pod"] # 0xe918 + - "": [T: "lewy kropka nad minus przez prawy kropka"] # 0xe919 + - "": [T: "prawy kropka nad minus przez lewy kropka"] # 0xe91a + - "": [T: "w przybliżeniu równe minus"] # 0xe91f + - "": [T: "podwójna kwadratowa suma zbiorów"] # 0xe920 + - "": [T: "podwójny kwadrat wielka"] # 0xe921 + - "": [T: "mniejsze niż równe lub większe niż"] # 0xe922 + - "": [T: "tylda z kropką"] # 0xe924 + - "": [T: "tylda z dwiema kropkami"] # 0xe925 + - "": [T: "mniejsze niż większe lub równe"] # 0xe926 + - "": [T: "większe niż mniejsze lub równe"] # 0xe927 + - "": [T: "Równoważne lub mniejsze niż"] # 0xe928 + - "": [T: "Równoważne lub większe niż"] # 0xe929 + - "": [T: "lewy otwórz ramka operator"] # 0xe92a + - "": [T: "prawy otwórz ramka operator"] # 0xe92b + - "": [T: "identyczne z kropką"] # 0xe92c + - "": [T: "większe niż równe lub mniejsze niż"] # 0xe92d + - "": [T: "kreska operator"] # 0xe92e + - "": [T: "podwójny kreska operator"] # 0xe92f + - "": [T: "potrójny kreska operator"] # 0xe930 + - "": [T: "mniejsze niż lub w przybliżeniu równe"] # 0xe932 + - "": [T: "większe niż lub w przybliżeniu równe"] # 0xe933 + - "": [T: "zagnieżdżone mniejsze niż"] # 0xe936 + - "": [T: "zagnieżdżone większe niż"] # 0xe937 + - "": [T: "poprzedza lub Równoważne"] # 0xe93a + - "": [T: "następuje po lub Równoważne"] # 0xe93b + - "": [T: "poprzedza nad równe"] # 0xe940 + - "": [T: "następuje po nad równe"] # 0xe941 + - "": [T: "mniejsze niż nad ukośnie równe nad większe niż"] # 0xe942 + - "": [T: "większe niż nad ukośnie równe nad mniejsze niż"] # 0xe943 + - "": [T: "spełnione przez"] # 0xe948 + - "": [T: "leniwe s"] # 0xe949 + - "": [T: "nie asercja"] # 0xe94a + - "": [T: "podwójny równe"] # 0xe94b + - "": [T: "potrójny równe"] # 0xe94c + - "": [T: "reguła opóźniona"] # 0xe94d + - "": [T: "alias ogranicznika"] # 0xe94e + - "": [T: "normalna podgrupa z kreską"] # 0xe950 + - "": [T: "zawiera jako normalny podgrupa z kreską"] # 0xe951 + - "": [T: "zaokrąglone implikuje"] # 0xe954 + - "": [T: "uśmiech pod kreską"] # 0xe955 + - "": [T: "smutek przez kreskę"] # 0xe956 + - "": [T: "nadzbiór lub w przybliżeniu równe"] # 0xe957 + - "": [T: "podzbiór lub w przybliżeniu równe"] # 0xe958 + - "": [T: "większe niż w przybliżeniu równe lub mniejsze niż"] # 0xe959 + - "": [T: "mniejsze niż w przybliżeniu równe lub większe niż"] # 0xe95a + - "": [T: "podwójny logiczne lub"] # 0xe95c + - "": [T: "podwójna koniunkcja logiczna"] # 0xe95d + - "": [T: "alternatywa logiczna z podwójną kreską pod"] # 0xe95e + - "": [T: "logiczne lub z kreską pod"] # 0xe95f + - "": [T: "w przybliżeniu równe nad równe"] # 0xe962 + - "": [T: "trójkąt skierowany w lewo z kreską dzielącą"] # 0xe964 + - "": [T: "trójkąt skierowany w prawo z kreską dzielącą"] # 0xe965 + - "": [T: "równa się z kropkowaną górną linią"] # 0xe966 + - "": [T: "poprzedza z dwukropkiem"] # 0xe967 + - "": [T: "następuje po z dwukropkiem"] # 0xe968 + - "": [T: "mniejsze niż lub ukośnie równe"] # 0xe969 + - "": [T: "większe niż lub ukośnie równe"] # 0xe96a + - "": [T: "zagnieżdżone bardzo znacznie mniejsze niż"] # 0xe96b + - "": [T: "zagnieżdżone bardzo znacznie większe niż"] # 0xe96c + - "": [T: "wariant różnicy między"] # 0xe96d + - "": [T: "mniejsze niż większe niż nakładka"] # 0xe96e + - "": [T: "alternatywa logiczna z nałożoną koniunkcją logiczną"] # 0xe96f + - "": [T: "nadzbiór przez nadzbiór"] # 0xe970 + - "": [T: "podzbiór przez podzbiór"] # 0xe971 + - "": [T: "nadzbiór przez podzbiór"] # 0xe972 + - "": [T: "podzbiór przez nadzbiór"] # 0xe973 + - "": [T: "potrójna pionowa kreska"] # 0xe979 + - "": [T: "sparowane poczwórne pionowe kropki"] # 0xe97a + - "": [T: "prostopadłe przez kreskę"] # 0xe97b + - "": [T: "lewy znak dedukcji z podwójną pionową kreską"] # 0xe97c + - "": [T: "podwójny lewy znak dedukcji z podwójną pionową kreską"] # 0xe97d + - "": [T: "prostopadłe przez odwrócony prostopadłe"] # 0xe97e + - "": [T: "podwójny lewy znak dedukcji z pionową kreską"] # 0xe97f + - "": [T: "kąt sferyczny otwarty w górę"] # 0xe980 + - "": [T: "podwójny ukośnik"] # 0xe981 + - "": [T: "kąt prosty z narożnikiem"] # 0xe982 + - "": [T: "pionowa kreska w kółku"] # 0xe984 + - "": [T: "znak dzielenia w kółku"] # 0xe985 + - "": [T: "kreskowany ukośnik"] # 0xe986 + - "": [T: "kreskowany ukośnik odwrotny"] # 0xe987 + - "": [T: "kreskowana linia środkowa"] # 0xe988 + - "": [T: "kreskowana pionowa kreska"] # 0xe989 + - "": [T: "prostopadłe z s"] # 0xe98a + - "": [T: "kąt z s"] # 0xe98b + - "": [T: "kąt sferyczny otwarty w lewo"] # 0xe98c + - "": [T: "kąt otwarty w lewo"] # 0xe98d + - "": [T: "pionowa kreska z podwójnym haczykiem"] # 0xe98e + - "": [T: "operator średniej kropki wolnego rodnika"] # 0xe98f + - "": [T: "biały trójkąt skierowany w górę nad kreską"] # 0xe990 + - "": [T: "identyczne i równoległe do"] # 0xe991 + - "": [T: "iloczyn spłaszczony"] # 0xe992 + - "": [T: "potrójny operator kreski z kreską poziomą"] # 0xe993 + - "": [T: "identyczne z podwójnym ukośnikiem"] # 0xe994 + - "": [T: "potrójne skrzyżowane kreski"] # 0xe995 + - "": [T: "pionowa kreska przez okrąg"] # 0xe996 + - "": [T: "pionowy proporcjonalne do"] # 0xe997 + - "": [T: "czarna ostatnia kwadra księżyca"] # 0xe998 + - "": [T: "czarna pierwsza kwadra księżyca"] # 0xe999 + - "": [T: "ujemna fala sinusoidalna"] # 0xe9a0 + - "": [T: "kropka w nawiasach"] # 0xe9a1 + - "": [T: "nawiasy"] # 0xe9a2 + - "": [T: "biały uśmiech"] # 0xe9a3 + - "": [T: "biały smutek"] # 0xe9a4 + - "": [T: "sześciokąt"] # 0xe9a5 + - "": [T: "Równoważne nad plus"] # 0xe9a6 + - "": [T: "plus przez Równoważne"] # 0xe9a7 + - "": [T: "część wspólna z szeryfami"] # 0xe9b0 + - "": [T: "suma zbiorów z szeryfami"] # 0xe9b1 + - "": [T: "kwadratowa część wspólna z szeryfami"] # 0xe9b2 + - "": [T: "kwadratowa suma zbiorów z szeryfami"] # 0xe9b3 + - "": [T: "poprzedza Równoważne lub następuje po"] # 0xe9e0 + - "": [T: "następuje po Równoważne lub poprzedza"] # 0xe9e1 + - "": [T: "poprzedza w przybliżeniu równe lub następuje po"] # 0xe9e2 + - "": [T: "następuje po w przybliżeniu równe lub poprzedza"] # 0xe9e3 + - "": [T: "mniejsze niż Równoważne lub większe niż"] # 0xe9f0 + - "": [T: "większe niż Równoważne lub mniejsze niż"] # 0xe9f1 + - "": [T: "pionowo przekreślone znacznie mniejsze niż"] # 0xea00 + - "": [T: "pionowo przekreślone znacznie większe niż"] # 0xea01 + - "": [T: "nie jest znacznie mniejsze niż, wariant"] # 0xea02 + - "": [T: "nie jest znacznie większe niż, wariant"] # 0xea03 + - "": [T: "mniejsze niż z pionową kreską i nie podwójne równe"] # 0xea04 + - "": [T: "większe niż z pionową kreską i nie podwójne równe"] # 0xea05 + - "": [T: "nie mniejsze lub równe"] # 0xea06 + - "": [T: "nie większe lub równe"] # 0xea07 + - "": [T: "ani równe, ani mniejsze niż"] # 0xea09 + - "": [T: "nie zawiera lub równe"] # 0xea0a + - "": [T: "ani nadzbiór, ani równe"] # 0xea0b + - "": [T: "ani podzbiór, ani równe"] # 0xea0c + - "": [T: "ukośnik odwrotny z podzbiorem"] # 0xea0d + - "": [T: "ani równe, ani większe niż"] # 0xea0e + - "": [T: "nie minus operator tyldy"] # 0xea0f + - "": [T: "ani równe, ani mniejsze niż"] # 0xea10 + - "": [T: "nie operator tyldy"] # 0xea11 + - "": [T: "nie jest elementem zbioru lub równe"] # 0xea12 + - "": [T: "ani równe, ani większe niż"] # 0xea13 + - "": [T: "nie w przybliżeniu równe"] # 0xea14 + - "": [T: "nie następuje po podobne"] # 0xea15 + - "": [T: "mniejsze niż lub ukośnie równe z ukośnikiem"] # 0xea16 + - "": [T: "większe niż lub ukośnie równe z ukośnikiem"] # 0xea17 + - "": [T: "nadzbiór ukośnik"] # 0xea1a + - "": [T: "nie zawiera"] # 0xea1b + - "": [T: "nie mniejsze lub równe"] # 0xea1d + - "": [T: "nie większe lub równe"] # 0xea1e + - "": [T: "nie w przybliżeniu równe minus"] # 0xea1f + - "": [T: "zanegowana przynależność do zbioru z kropką nad"] # 0xea22 + - "": [T: "nie kąt pionowy"] # 0xea2c + - "": [T: "nie ukośnie równoległe"] # 0xea2d + - "": [T: "nie kreska operator"] # 0xea2e + - "": [T: "nie podwójny kreska operator"] # 0xea2f + - "": [T: "nie potrójny kreska operator"] # 0xea30 + - "": [T: "mniejsze niż ale nie w przybliżeniu równe"] # 0xea32 + - "": [T: "większe niż ale nie w przybliżeniu równe"] # 0xea33 + - "": [T: "mniejsze niż lub nie równa się"] # 0xea34 + - "": [T: "większe niż lub nie równa się"] # 0xea35 + - "": [T: "nie zagnieżdżone mniejsze niż"] # 0xea36 + - "": [T: "nie zagnieżdżone większe niż"] # 0xea37 + - "": [T: "nie jest znacznie mniejsze niż"] # 0xea38 + - "": [T: "nie jest znacznie większe niż"] # 0xea39 + - "": [T: "poprzedza ale nie Równoważne"] # 0xea3a + - "": [T: "następuje po ale nie Równoważne"] # 0xea3b + - "": [T: "poprzedza ale nie równa się"] # 0xea3c + - "": [T: "następuje po ale nie równa się"] # 0xea3d + - "": [T: "nie równa się ani nie poprzedza"] # 0xea3e + - "": [T: "nie równa się ani nie następuje po"] # 0xea3f + - "": [T: "poprzedza ale nie równa się"] # 0xea40 + - "": [T: "następuje po ale nie równa się"] # 0xea41 + - "": [T: "ani podzbiór, ani równe"] # 0xea42 + - "": [T: "ani nadzbiór, ani równe"] # 0xea43 + - "": [T: "podzbiór lub nie równa się"] # 0xea44 + - "": [T: "nadzbiór lub nie równa się"] # 0xea45 + - "": [T: "ani podzbiór, ani równe"] # 0xea46 + - "": [T: "ani nadzbiór, ani równe"] # 0xea47 + - "": [T: "nie potrójny mniejsze niż"] # 0xea48 + - "": [T: "nie potrójny większe niż"] # 0xea49 + - "": [T: "nie poprzedza równa się"] # 0xea4c + - "": [T: "nie następuje po równa się"] # 0xea4d + - "": [T: "nie normalna podgrupa z kreską"] # 0xea50 + - "": [T: "nie zawiera jako normalnej podgrupy z kreską"] # 0xea51 + - "": [T: "nie różnica między"] # 0xea52 + - "": [T: "nie geometrycznie równoważne"] # 0xea53 + - "": [T: "nie pionowo podobne"] # 0xea54 + - "": [T: "nie równe lub podobne"] # 0xea55 + - "": [T: "nie pionowo przybliżone"] # 0xea56 + - "": [T: "nie w przybliżeniu identyczne z"] # 0xea57 + - "": [T: "nie wyboiście równe"] # 0xea58 + - "": [T: "nie wyboiście pojedynczo równe"] # 0xea59 + - "": [T: "nie równe kropka"] # 0xea5a + - "": [T: "odwrotne nie równoważne"] # 0xea5b + - "": [T: "nie kwadrat podzbiór"] # 0xea60 + - "": [T: "nie kwadrat nadzbiór"] # 0xea61 + - "": [T: "nie w przybliżeniu równe nad znakiem równości"] # 0xea62 + - "": [T: "nie ściśle równoważne"] # 0xea63 + - "": [T: "nie przystające z kropką"] # 0xea64 + - "": [T: "odwrotnie nie równe"] # 0xea65 + - "": [T: "nie pionowy lewy trójkąt równa się"] # 0xea70 + - "": [T: "nie pionowy prawy trójkąt równa się"] # 0xea71 + - "": [T: "nie cząstkowe"] # 0xea80 + - "": [T: "ozdobnik przedłużenia strzałki"] # 0xeb00 + - "": [T: "strzałka prawy przeze strzałką lewy"] # 0xeb01 + - "": [T: "strzałka prawy przeze strzałką lewy"] # 0xeb02 + - "": [T: "harpun prawy przez harpun lewy"] # 0xeb03 + - "": [T: "harpun prawy przez harpun lewy"] # 0xeb04 + - "": [T: "podwójna strzałka północny wschód południowy zachód"] # 0xeb05 + - "": [T: "podwójna strzałka północny zachód południowy wschód"] # 0xeb06 + - "": [T: "poziome przedłużenie harpuna"] # 0xeb07 + - "": [T: "łuk ze strzałką w lewo przeciwnie do ruchu wskazówek zegara"] # 0xeb08 + - "": [T: "łuk ze strzałką w prawo przeciwnie do ruchu wskazówek zegara"] # 0xeb09 + - "": [T: "duży strzałka w prawo akcent"] # 0xeb0b + - "": [T: "duży strzałka w lewo akcent"] # 0xeb0c + - "": [T: "lewy grot strzałki"] # 0xeb0d + - "": [T: "prawy grot strzałki"] # 0xeb0e + - "": [T: "duża strzałka w prawo z lewym przekreśleniem"] # 0xeb0f + - "": [T: "poziome przedłużenie podwójnej strzałki"] # 0xeb10 + - "": [T: "duża podwójna strzałka w lewo i prawo z przekreśleniem"] # 0xeb11 + - "": [T: "strzałka w dół po lewej i strzałka w górę"] # 0xeb12 + - "": [T: "strzałka w lewo z dolnym narożnikiem"] # 0xeb13 + - "": [T: "strzałka w prawo z górnym narożnikiem"] # 0xeb14 + - "": [T: "strzałka w lewo z górnym narożnikiem"] # 0xeb15 + - "": [T: "strzałka po górnym półokręgu przeciwnie do ruchu wskazówek zegara z plusem"] # 0xeb16 + - "": [T: "strzałka po górnym półokręgu zgodnie z ruchem wskazówek zegara z minusem"] # 0xeb17 + - "": [T: "strzałka w prawo z ogonem i przekreśleniem"] # 0xeb18 + - "": [T: "prawy harpun dolny"] # 0xeb19 + - "": [T: "lewy harpun dolny"] # 0xeb1a + - "": [T: "lewy prawy harpun dolny"] # 0xeb1b + - "": [T: "lewy prawy harpun górny"] # 0xeb1c + - "": [T: "górny dolny harpun lewy"] # 0xeb1d + - "": [T: "górny dolny harpun prawy"] # 0xeb1e + - "": [T: "strzałka w górę w prawo ze strzałką w dół"] # 0xeb1f + - "": [T: "lewy harpun do kreski z grotem górnym"] # 0xeb20 + - "": [T: "prawy harpun do kreski z grotem górnym"] # 0xeb21 + - "": [T: "lewy harpun do kreski z grotem dolnym"] # 0xeb22 + - "": [T: "prawy harpun do kreski z grotem dolnym"] # 0xeb23 + - "": [T: "lewy harpun od kreski z grotem górnym"] # 0xeb24 + - "": [T: "prawy harpun od kreski z grotem górnym"] # 0xeb25 + - "": [T: "lewy harpun od kreski z grotem dolnym"] # 0xeb26 + - "": [T: "prawy harpun od kreski z grotem dolnym"] # 0xeb27 + - "": [T: "górny harpun do kreski z grotem lewym"] # 0xeb28 + - "": [T: "dolny harpun do kreski z grotem lewym"] # 0xeb29 + - "": [T: "górny harpun do kreski z grotem prawym"] # 0xeb2a + - "": [T: "dolny harpun do kreski z grotem prawym"] # 0xeb2b + - "": [T: "górny harpun od kreski z grotem lewym"] # 0xeb2c + - "": [T: "dolny harpun od kreski z grotem lewym"] # 0xeb2d + - "": [T: "górny harpun od kreski z grotem prawym"] # 0xeb2e + - "": [T: "dolny harpun od kreski z grotem prawym"] # 0xeb2f + - "": [T: "strzałka w górę do kreski"] # 0xeb30 + - "": [T: "strzałka w dół do kreski"] # 0xeb31 + - "": [T: "górny harpun w lewo z dolnym harpunem"] # 0xeb32 + - "": [T: "górny harpun w prawo z dolnym harpunem"] # 0xeb33 + - "": [T: "górny grot strzałki"] # 0xeb34 + - "": [T: "dolny grot strzałki"] # 0xeb35 + - "": [T: "podwójny harpun z lewym grotem dolnym i prawym grotem górnym"] # 0xeb36 + - "": [T: "podwójny harpun z lewym grotem górnym i prawym grotem dolnym"] # 0xeb37 + - "": [T: "strzałka w lewo przez kreskę"] # 0xeb38 + - "": [T: "strzałka w prawo przez kreskę"] # 0xeb39 + - "": [T: "strzałka w lewo pod kreski"] # 0xeb3a + - "": [T: "strzałka w prawo pod kreski"] # 0xeb3b + - "": [T: "lewy prawy potrójny strzałka"] # 0xeb3c + - "": [T: "podwójna strzałka północny wschód południowy wschód"] # 0xeb3f + - "": [T: "strzałka po lewym półokręgu przeciwnie do ruchu wskazówek zegara"] # 0xeb40 + - "": [T: "strzałka po lewym półokręgu zgodnie z ruchem wskazówek zegara"] # 0xeb41 + - "": [T: "lewy otwarty okrąg lewy strzałka w prawo"] # 0xeb42 + - "": [T: "strzałka w prawo przez tylda"] # 0xeb44 + - "": [T: "strzałka w lewo przez tylda"] # 0xeb45 + - "": [T: "lewy harpun przez kreskę"] # 0xeb48 + - "": [T: "prawy harpun przez kreskę"] # 0xeb49 + - "": [T: "lewy harpun pod kreski"] # 0xeb4a + - "": [T: "prawy harpun pod kreski"] # 0xeb4b + - "": [T: "krótka czarna strzałka w lewo"] # 0xeb4c + - "": [T: "strzałka po prawym półokręgu zgodnie z ruchem wskazówek zegara"] # 0xeb50 + - "": [T: "strzałka po prawym półokręgu przeciwnie do ruchu wskazówek zegara"] # 0xeb51 + - "": [T: "lewy otwarty okrąg lewy prawy harpun"] # 0xeb52 + - "": [T: "strzałka w górę lewy z pionową kreską"] # 0xeb58 + - "": [T: "strzałka w dół lewy z pionową kreską"] # 0xeb59 + - "": [T: "strzałka w górę prawy z pionową kreską"] # 0xeb5a + - "": [T: "strzałka w dół prawy z pionową kreską"] # 0xeb5b + - "": [T: "strzałka w prawo z wydłużonym dolnym hakiem"] # 0xeb5c + - "": [T: "strzałka w lewo z wydłużonym hakiem"] # 0xeb5d + - "": [T: "strzałka w lewo z wydłużonym dolnym hakiem"] # 0xeb5e + - "": [T: "strzałka w prawo z wydłużonym hakiem"] # 0xeb5f + - "": [T: "nie strzałka w prawo falista"] # 0xeb60 + - "": [T: "nie strzałka w prawo zakrzywiony"] # 0xeb61 + - "": [T: "górny harpun lewy z pionową kreską"] # 0xeb68 + - "": [T: "dolny harpun lewy z pionową kreską"] # 0xeb69 + - "": [T: "górny harpun prawy z pionową kreską"] # 0xeb6a + - "": [T: "dolny harpun prawy z pionową kreską"] # 0xeb6b + - "": [T: "pionowe przedłużenie podwójnej strzałki"] # 0xeb6c + - "": [T: "pionowe przedłużenie harpuna z grotem w lewo"] # 0xeb6d + - "": [T: "pionowe przedłużenie harpuna z grotem w prawo"] # 0xeb6e + - "": [T: "prawy harpun przez lewy harpun prawy"] # 0xeb6f + - "": [T: "prawy harpun przez lewy harpun lewy"] # 0xeb70 + - "": [T: "lewy harpun przez prawy harpun prawy"] # 0xeb71 + - "": [T: "lewy harpun przez prawy harpun lewy"] # 0xeb72 + - "": [T: "strzałka w lewo od kreski z grotem strzałki"] # 0xeb73 + - "": [T: "przedłużenie strzałki w prawo od lewej kreski"] # 0xeb74 + - "": [T: "strzałka w lewo od kreski ogon"] # 0xeb75 + - "": [T: "strzałka w prawo od kreski ogon"] # 0xeb76 + - "": [T: "strzałka w prawo od kreski z grotem strzałki"] # 0xeb77 + - "": [T: "górny harpun od kreski z lewym grotem strzałki"] # 0xeb78 + - "": [T: "strzałka w prawo nad strzałką w lewo prawy"] # 0xeb79 + - "": [T: "strzałka w prawo nad strzałką w lewo lewy"] # 0xeb7a + - "": [T: "strzałka w lewo nad strzałką w prawo prawy"] # 0xeb7b + - "": [T: "strzałka w lewo nad strzałką w prawo lewy"] # 0xeb7c + - "": [T: "strzałka w górę od kreski z grotem strzałki"] # 0xeb7d + - "": [T: "strzałka w górę od kreski ogon"] # 0xeb7e + - "": [T: "strzałka w dół od kreski ogon"] # 0xeb7f + - "": [T: "strzałka w dół od kreski z grotem strzałki"] # 0xeb80 + - "": [T: "dolny harpun od kreski z prawym grotem strzałki"] # 0xeb81 + - "": [T: "górny harpun w lewo z dolnym harpunem dolny"] # 0xeb82 + - "": [T: "przedłużenie górnego harpuna w lewo i dolnego harpuna"] # 0xeb83 + - "": [T: "dolny harpun w lewo z górnym harpunem górny"] # 0xeb84 + - "": [T: "górny harpun w lewo z dolnym harpunem górny"] # 0xeb85 + - "": [T: "przedłużenie dolnego harpuna w lewo i górnego harpuna"] # 0xeb86 + - "": [T: "dolny harpun w lewo z górnym harpunem dolny"] # 0xeb87 + - "": [T: "strzałka w górę po lewej i strzałka w dół dolny"] # 0xeb88 + - "": [T: "strzałka w dół po lewej i strzałka w górę górny"] # 0xeb89 + - "": [T: "strzałka w górę po lewej i strzałka w dół górny"] # 0xeb8a + - "": [T: "strzałka w dół po lewej i strzałka w górę dolny"] # 0xeb8b + - "": [T: "przedłużenie strzałki w lewo i w prawo"] # 0xeb8c + - "": [T: "przedłużenie strzałki północno-wschodniej"] # 0xeb8d + - "": [T: "przedłużenie strzałki północno-zachodniej"] # 0xeb8e + - "": [T: "lewa część dolnego nawiasu klamrowego"] # 0xec00 + - "": [T: "środkowa część dolnego nawiasu klamrowego"] # 0xec01 + - "": [T: "prawa część dolnego nawiasu klamrowego"] # 0xec02 + - "": [T: "poziome przedłużenie nawiasu klamrowego"] # 0xec03 + - "": [T: "lewa część górnego nawiasu klamrowego"] # 0xec04 + - "": [T: "środkowa część górnego nawiasu klamrowego"] # 0xec05 + - "": [T: "prawa część górnego nawiasu klamrowego"] # 0xec06 + - "": [T: "lewa pionowa kreska"] # 0xec07 + - "": [T: "prawa pionowa kreska"] # 0xec08 + - "": [T: "lewa podwójna pionowa kreska"] # 0xec09 + - "": [T: "prawa podwójna pionowa kreska"] # 0xec0a + - "": [T: "poziome przedłużenie nawiasu kwadratowego"] # 0xec0b + - "": [T: "dolny nawias kwadratowy"] # 0xec0c + - "⎵": [T: "dolny nawias kwadratowy"] # 0x23b5 + - "": [T: "górny nawias kwadratowy"] # 0xec0d + - "⎴": [T: "górny nawias kwadratowy"] # 0x23b4 + - "": [T: "pod nawias kwadratowy lewy"] # 0xec0e + - "": [T: "pod nawias kwadratowy prawy"] # 0xec0f + - "": [T: "przez nawias kwadratowy lewy"] # 0xec10 + - "": [T: "przez nawias kwadratowy prawy"] # 0xec11 + - "": [T: "lewy nawias okrągły 1"] # 0xec12 + - "": [T: "lewy nawias okrągły 2"] # 0xec13 + - "": [T: "lewy nawias okrągły 3"] # 0xec14 + - "": [T: "lewy nawias okrągły 4"] # 0xec15 + - "": [T: "prawy nawias okrągły 1"] # 0xec16 + - "": [T: "prawy nawias okrągły 2"] # 0xec17 + - "": [T: "prawy nawias okrągły 3"] # 0xec18 + - "": [T: "prawy nawias okrągły 4"] # 0xec19 + - "": [T: "znak pierwiastka 1"] # 0xec1a + - "": [T: "znak pierwiastka 2"] # 0xec1b + - "": [T: "znak pierwiastka 3"] # 0xec1c + - "": [T: "znak pierwiastka 4"] # 0xec1d + - "": [T: "znak pierwiastka 5"] # 0xec1e + - "": [T: "dolna część znaku pierwiastka"] # 0xec1f + - "": [T: "pionowe przedłużenie znaku pierwiastka"] # 0xec20 + - "": [T: "górna część znaku pierwiastka"] # 0xec21 + - "": [T: "lewy biały nawias kwadratowy górny"] # 0xec22 + - "": [T: "przedłużenie lewego białego nawiasu kwadratowego"] # 0xec23 + - "": [T: "lewy biały nawias kwadratowy dolny"] # 0xec24 + - "": [T: "prawy biały nawias kwadratowy górny"] # 0xec25 + - "": [T: "przedłużenie prawego białego nawiasu kwadratowego"] # 0xec26 + - "": [T: "prawy biały nawias kwadratowy dolny"] # 0xec27 + - "": [T: "lewy biały zakrzywiony nawias kwadratowy"] # 0xec30 + - "": [T: "prawy biały zakrzywiony nawias kwadratowy"] # 0xec31 + - "": [T: "znak dzielenia pisemnego"] # 0xec32 + - "": [T: "przedłużenie znaku dzielenia pisemnego"] # 0xec33 + - "": [T: "krótkie dzielenie"] # 0xec34 + - "": [T: "podwójne wiązanie em od południowego zachodu do północnego wschodu"] # 0xec40 + - "": [T: "podwójne wiązanie em od północnego zachodu do południowego wschodu"] # 0xec41 + - "": [T: "pojedyncze poziome wiązanie em"] # 0xec42 + - "": [T: "podwójne poziome wiązanie em"] # 0xec43 + - "": [T: "potrójne poziome wiązanie em"] # 0xec44 + - "": [T: "pojedyncze pionowe wiązanie em"] # 0xec45 + - "": [T: "podwójne pionowe wiązanie em"] # 0xec46 + - "": [T: "potrójne pionowe wiązanie em"] # 0xec47 + - "": [T: "wiązanie em mniejsze niż"] # 0xec48 + - "": [T: "wiązanie em większe niż"] # 0xec49 + - "": [T: "pojedyncze poziome wiązanie en"] # 0xec4a + - "": [T: "podwójne poziome wiązanie en"] # 0xec4b + - "": [T: "potrójne poziome wiązanie en"] # 0xec4c + - "": [T: "górny lewy prostokąt"] # 0xec80 + - "": [T: "dolny lewy prostokąt"] # 0xec81 + - "": [T: "górny prawy prostokąt"] # 0xec90 + - "": [T: "dolny prawy prostokąt"] # 0xec91 + - "": [T: "narożnik dzielenia syntetycznego"] # 0xec92 + - "": [T: "poziome przedłużenie dzielenia syntetycznego"] # 0xec93 + - "": [T: "pionowe przedłużenie dzielenia syntetycznego"] # 0xec94 + - "": [T: "lewy przedłużacz sufitu i podłogi"] # 0xec95 + - "": [T: "prawy przedłużacz sufitu i podłogi"] # 0xec96 + - "": [T: "przedłużenie przez nawias kwadratowy"] # 0xec97 + - "": [T: "pionowe przedłużenie kreski"] # 0xec98 + - "": [T: "lewy podwójny pionowe przedłużenie kreski"] # 0xec99 + - "": [T: "poziome przedłużenie kreski"] # 0xec9a + - "": [T: "przedłużenie pod nawiasem kwadratowym"] # 0xec9c + - "": [T: "prawa część dolnego nawiasu"] # 0xec9d + - "": [T: "przedłużenie dolnego nawiasu"] # 0xec9e + - "": [T: "lewa część dolnego nawiasu"] # 0xec9f + - "": [T: "przedłużenie górnego nawiasu klamrowego"] # 0xeca0 + - "": [T: "lewa część górnego nawiasu"] # 0xeca1 + - "": [T: "przedłużenie górnego nawiasu"] # 0xeca2 + - "": [T: "prawa część górnego nawiasu"] # 0xeca3 + - "": [T: "przedłużenie dolnego nawiasu klamrowego"] # 0xeca4 + - "": [T: "stała Plancka przez dwa pi kreska"] # 0xed00 + - "": [T: "lustrzane g"] # 0xed01 + - "": [T: "j bez kropki"] # 0xed02 - "": [T: "digamma"] # 0xed03 - "ϝ": [T: "digamma"] # 0x3dd - "": [T: "d"] # 0xed10 @@ -3004,8 +3004,8 @@ - spell: "translate('.', 'ⅅ', 'DD')" # 0xed16, 0x2145 # The private use chars are from MathType - - "": [t: "całka krzywoliniowa z pętlą przeciwnie do ruchu wskazówek zegara"] # 0xee00 - - "": [t: "całka krzywoliniowa z pętlą zgodnie z ruchem wskazówek zegara"] # 0xee01 + - "": [T: "całka krzywoliniowa z pętlą przeciwnie do ruchu wskazówek zegara"] # 0xee00 + - "": [T: "całka krzywoliniowa z pętlą zgodnie z ruchem wskazówek zegara"] # 0xee01 - "": [T: ""] # 0xee04 - "": [T: ""] # 0xee05 - "": [T: ""] # 0xee06 @@ -3015,30 +3015,30 @@ - "": [T: ""] # 0xee0a - "": [T: ""] # 0xee0b - "": [T: ""] # 0xee0c - - "": [t: "ozdobnik statusu połączenia"] # 0xee0d - - "": [t: "lewy ozdobnik statusu połączenia"] # 0xee0e - - "": [t: "prawy ozdobnik statusu połączenia"] # 0xee0f - - "": [t: "przedłużenie ozdobnika statusu połączenia"] # 0xee10 - - "": [t: "całka z pętlą"] # 0xee11 - - "": [t: "podwójna całka z pętlą"] # 0xee12 - - "": [t: "potrójna całka z pętlą"] # 0xee13 - - "": [t: "rozszerzająca się podwójna całka z pętlą"] # 0xee15 - - "": [t: "rozszerzająca się potrójna całka z pętlą"] # 0xee16 + - "": [T: "ozdobnik statusu połączenia"] # 0xee0d + - "": [T: "lewy ozdobnik statusu połączenia"] # 0xee0e + - "": [T: "prawy ozdobnik statusu połączenia"] # 0xee0f + - "": [T: "przedłużenie ozdobnika statusu połączenia"] # 0xee10 + - "": [T: "całka z pętlą"] # 0xee11 + - "": [T: "podwójna całka z pętlą"] # 0xee12 + - "": [T: "potrójna całka z pętlą"] # 0xee13 + - "": [T: "rozszerzająca się podwójna całka z pętlą"] # 0xee15 + - "": [T: "rozszerzająca się potrójna całka z pętlą"] # 0xee16 - "": [T: "akcent asymptotycznie równy"] # 0xee17 - - "": [t: "akcent znaku równości"] # 0xee18 - - "": [t: "poczwórny prim"] # 0xee19 - - "": [t: "kreska akcent z otwartym okręgiem po lewej"] # 0xee1a - - "": [t: "kreska akcent z zamkniętym okręgiem po lewej"] # 0xee1b - - "": [t: "kreska akcent z otwartym okręgiem po prawej"] # 0xee1c - - "": [t: "kreska akcent z przekreśloną kropką"] # 0xee1d - - "": [t: "kreska akcent z kropką pod spodem"] # 0xee1e - - "": [t: "kreska akcent z podwójnie przekreśloną kropką"] # 0xee1f - - "": [t: "kreska akcent z podwójną kropką pod spodem"] # 0xee20 - - "": [t: "kreska akcent z daszkiem"] # 0xee21 - - "": [t: "gruby akcent kreski dolnej"] # 0xee22 - - "": [t: "kreska akcent z zamkniętym okręgiem po prawej"] # 0xee23 - - "": [t: "duży kropka nad"] # 0xee24 - - "": [t: "znak wyrównania"] # 0xef00 + - "": [T: "akcent znaku równości"] # 0xee18 + - "": [T: "poczwórny prim"] # 0xee19 + - "": [T: "kreska akcent z otwartym okręgiem po lewej"] # 0xee1a + - "": [T: "kreska akcent z zamkniętym okręgiem po lewej"] # 0xee1b + - "": [T: "kreska akcent z otwartym okręgiem po prawej"] # 0xee1c + - "": [T: "kreska akcent z przekreśloną kropką"] # 0xee1d + - "": [T: "kreska akcent z kropką pod spodem"] # 0xee1e + - "": [T: "kreska akcent z podwójnie przekreśloną kropką"] # 0xee1f + - "": [T: "kreska akcent z podwójną kropką pod spodem"] # 0xee20 + - "": [T: "kreska akcent z daszkiem"] # 0xee21 + - "": [T: "gruby akcent kreski dolnej"] # 0xee22 + - "": [T: "kreska akcent z zamkniętym okręgiem po prawej"] # 0xee23 + - "": [T: "duży kropka nad"] # 0xee24 + - "": [T: "znak wyrównania"] # 0xef00 - "": [T: ""] # 0xef01 - "​": [T: ""] # 0x200b - "": [T: ""] # 0xef02 @@ -3057,110 +3057,110 @@ - "": [T: ""] # 0xef23 - "": [T: ""] # 0xef24 - "": [T: ""] # 0xef29 - - "": [t: "brakujący składnik"] # 0xef41 - - "": [t: "całka krzywoliniowa zgodna z ruchem wskazówek zegara ze strzałką po lewej"] # 0xef80 - - "": [t: "całka z kwadrat"] # 0xef81 - - "": [t: "całka z ukośnikiem"] # 0xef82 - - "": [t: "odwrócony całka"] # 0xef83 - - "": [t: "podwójny zero przez podwójny zero"] # 0xef90 - - "": [t: "zero z ukośnikiem"] # 0xef91 + - "": [T: "brakujący składnik"] # 0xef41 + - "": [T: "całka krzywoliniowa zgodna z ruchem wskazówek zegara ze strzałką po lewej"] # 0xef80 + - "": [T: "całka z kwadrat"] # 0xef81 + - "": [T: "całka z ukośnikiem"] # 0xef82 + - "": [T: "odwrócony całka"] # 0xef83 + - "": [T: "podwójny zero przez podwójny zero"] # 0xef90 + - "": [T: "zero z ukośnikiem"] # 0xef91 # fraktur chars in math alphabetic block and also MathType private use area # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display - "𝔄-𝔜": # 0x1d504 - 0x1d51d ('z' version is reserved) - - t: "fraktura" + - T: "fraktura" - spell: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" - "-": # 0xf000 - 0xf018 - - t: "fraktura" + - T: "fraktura" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" - "𝔞-𝔷": # 0x1d51e - 0x1d537 - - t: "fraktura" + - T: "fraktura" - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf01a - 0xf033 - - t: "fraktura" + - T: "fraktura" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝕬-𝖅": # 0x1D56C - 0x1D585 - - t: "fraktura" - - t: "pogrubione" + - T: "fraktura" + - T: "pogrubione" - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf040 - 0xf059 - - t: "fraktura" - - t: "pogrubione" + - T: "fraktura" + - T: "pogrubione" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝖆-𝖟": # 0x1d586 - 0x1d59f - - t: "fraktura" - - t: "pogrubione" + - T: "fraktura" + - T: "pogrubione" - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf05a - 0xf073 - - t: "fraktura" - - t: "pogrubione" + - T: "fraktura" + - T: "pogrubione" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" # double struck (blackboard bold) chars in math alphabetic block and also MathType private use area # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display - "𝔸-𝕐": # 0x1d504 - 0x1d51d ('z' version is reserved) - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', '𝔸𝔹𝔺𝔻𝔼𝔽𝔾𝔿𝕀𝕁𝕂𝕃𝕄𝕅𝕆𝕇𝕈𝕉𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf080 - 0xf098 - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝕒-𝕫": # 0x1d552 - 0x1d56b - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf09a - 0xf0b3 - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" - "-": # 0xf0c0 - 0xf0c9 - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', '', '0123456789')" - - "": [t: "dwukreskowe nabla"] # 0xf0ca - - "": [t: "dwukreskowa stała Eulera"] # 0xf0cb + - "": [T: "dwukreskowe nabla"] # 0xf0ca + - "": [T: "dwukreskowa stała Eulera"] # 0xf0cb # script chars in math alphabetic block and also MathType private use area - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 - - t: "pisane" + - T: "pisane" - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf100 - 0xf119 - - t: "pisane" + - T: "pisane" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf - - t: "pisane" + - T: "pisane" - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf11a - 0xf133 - - t: "pisane" + - T: "pisane" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" # bold script chars in math alphabetic block and also MathType private use area - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 - - t: "pisane" - - t: "pogrubione" + - T: "pisane" + - T: "pogrubione" - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf140 - 0xf159 - - t: "pisane" - - t: "pogrubione" + - T: "pisane" + - T: "pogrubione" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝓪-𝔃": # 0x1d4ea - 0x1d503 - - t: "pisane" - - t: "pogrubione" + - T: "pisane" + - T: "pogrubione" - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf15a - 0xf173 - - t: "pisane" - - t: "pogrubione" + - T: "pisane" + - T: "pogrubione" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf180 - 0xf199 @@ -3179,11 +3179,11 @@ if: "$SpeechOverrides_CapitalLetters = ''" then_test: if: "$Impairment = 'Blindness'" - then: [t: "wielka"] + then: [T: "wielka"] else: [x: "$SpeechOverrides_CapitalLetters"] - pitch: value: "$CapitalLetters_Pitch" - replace: [t: "ligatura ae"] + replace: [T: "ligatura ae"] - "": # 0xf19b - test: if: "$CapitalLetters_Beep" @@ -3197,11 +3197,11 @@ if: "$SpeechOverrides_CapitalLetters = ''" then_test: if: "$Impairment = 'Blindness'" - then: [t: "wielka"] + then: [T: "wielka"] else: [x: "$SpeechOverrides_CapitalLetters"] - pitch: value: "$CapitalLetters_Pitch" - replace: [t: "eszett"] + replace: [T: "eszett"] - "": # 0xf19c - test: if: "$CapitalLetters_Beep" @@ -3215,38 +3215,38 @@ if: "$SpeechOverrides_CapitalLetters = ''" then_test: if: "$Impairment = 'Blindness'" - then: [t: "wielka"] + then: [T: "wielka"] else: [x: "$SpeechOverrides_CapitalLetters"] - pitch: value: "$CapitalLetters_Pitch" - replace: [t: "o z kreską"] + replace: [T: "o z kreską"] # MathType only has a few of the cap Greek letters in PUA - "": # 0xf201 - 0xf209 - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', '', 'ΔΨΛΠΣΘΓΩΥ')" - "-": # 0xf220 - 0xf236 - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - "": [t: "dwukreskowe sigma końcowa"] # 0xf237 - - "": [t: "dwukreskowe ro"] # 0xf250 - - "": [t: "dwukreskowe fi"] # 0xf251 + - "": [T: "dwukreskowe sigma końcowa"] # 0xf237 + - "": [T: "dwukreskowe ro"] # 0xf250 + - "": [T: "dwukreskowe fi"] # 0xf251 - "𝐀-𝐙": # 0x1d400 - 0x1d419 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf260 - 0xf279 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝐚-𝐳": # 0x1d41a - 0x1d433 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf27a - 0xf293 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝐴-𝑍": # 0x1d434 - 0x1d44d @@ -3262,23 +3262,23 @@ - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝑨-𝒁": # 0x1d468 - 0x1d481 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf2c8 - 0xf2e1 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝒂-𝒛": # 0x1d482 - 0x1d49b - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf2e2 - 0xf2fb - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 @@ -3294,53 +3294,53 @@ - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf334 - 0xf34d - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝗮-𝘇": # 0x1d5ee - 0x1d607 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf34e - 0xf367 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝘈-𝘡": # 0x1d608 - 0x1d621 - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf368 - 0xf381 - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝘢-𝘻": # 0x1d622 - 0x1d63b - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf382 - 0xf39b - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝘼-𝙕": # 0x1d63c - 0x1d655 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf39c - 0xf3b5 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝙖-𝙯": # 0x1d656 - 0x1d66f - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf3b6 - 0xf3cf - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝙰-𝚉": # 0x1d670 - 0x1d689 @@ -3355,170 +3355,170 @@ - "-": # 0xf3ea - 0xf403 - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - "": [t: "bez kropki I"] # 0xf404 - - "𝚤": [t: "bez kropki I"] # 0x1d6a4 - - "𝚥": [t: "j bez kropki"] # 0x1d6a5 + - "": [T: "bez kropki I"] # 0xf404 + - "𝚤": [T: "bez kropki I"] # 0x1d6a4 + - "𝚥": [T: "j bez kropki"] # 0x1d6a5 - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "-": # 0xf408 - 0xf420 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "-": # 0xf422 - 0xf43a - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - "": [t: "pogrubiona nabla"] # 0xf421 - - "𝛁": [t: "pogrubiona nabla"] # 0x1d6c1 + - "": [T: "pogrubiona nabla"] # 0xf421 + - "𝛁": [T: "pogrubiona nabla"] # 0x1d6c1 - "𝛛𝛜𝛝𝛞𝛟𝛠𝛡": # 0x1D6DB - 0x1D6E1 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" - "": # 0xF43C - 0xF441 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', '∂εθκφρπ')" - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "-": # 0xf442 - 0xf45a - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "𝛼-𝜔": # 0x1d6fc - 0x1d714 - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓𝜔', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "-": # 0xf45c - 0xf474 - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - "": [t: "kursywa nabla"] # 0xf45b - - "𝛻": [t: "kursywa nabla"] # 0x1d6fb + - "": [T: "kursywa nabla"] # 0xf45b + - "𝛻": [T: "kursywa nabla"] # 0x1d6fb - "𝜕𝜖𝜗𝜘𝜙𝜚𝜛": # 0x1d715 - 0x1d71b - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '𝜕𝜖𝜗𝜘𝜙𝜚𝜛', '∂εθκφρπ')" - "": # 0xf475 - 0xf47b - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '', '∂εθκφρπ')" - "𝜜-𝜴": # 0x1d71c - 0x1d734 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "-": # 0xf47c - 0xf494 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "𝜶-𝝎": # 0x1d736 - 0x1d74e - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "-": # 0xf496 - 0xf4ae - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": # 0x1d74f - 0x1d755 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εθκφρπ')" - "": # 0xf422 - 0xf43a - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', '∂εθκφρπ')" - - "𝜵": [t: "pogrubiona pochylona nabla"] # 0x1d735 - - "": [t: "pogrubiona pochylona nabla"] # 0xf495 + - "𝜵": [T: "pogrubiona pochylona nabla"] # 0x1d735 + - "": [T: "pogrubiona pochylona nabla"] # 0xf495 - "𝝖-𝝮": # 0x1d756 - 0x1d76e - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "-": # 0xf4b6 - 0xf4ce - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "𝝰-𝞈": # 0x1d770 - 0x1d788 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇𝞈', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "-": # 0xf4d0 - 0xf4e8 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝞉𝞊𝞋𝞌𝞍𝞎𝞏": # 0x1d789 - 0x1d78f - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝞉𝞊𝞋𝞌𝞍𝞎𝞏', '∂εθκφρπ')" - "": # 0xf4e9 - 0xf4ef - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', '∂εθκφρπ')" - - "": [t: "pogrubiona nabla"] # 0xf4cf - - "𝝯": [t: "pogrubiona nabla"] # 0x1d76f + - "": [T: "pogrubiona nabla"] # 0xf4cf + - "𝝯": [T: "pogrubiona nabla"] # 0x1d76f - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "-": # 0xf4f0 - 0xf508 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "𝞪-𝟂": # 0x1d7aa - 0x1d7c2 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "-": # 0xf50a - 0xf522 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": # 0x1d7c3 - 0x1d7c9 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝟃𝟄𝟅𝟆𝟇𝟈𝟉', '∂εθκφρπ')" - "": # 0xf523 - 0xf529 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', '∂εθκφρπ')" - - "": [t: "pogrubiona nabla"] # 0xf509 - - "𝞩": [t: "pogrubiona nabla"] # 0x1d7a9 + - "": [T: "pogrubiona nabla"] # 0xf509 + - "𝞩": [T: "pogrubiona nabla"] # 0x1d7a9 - "-": # 0xf52e - 0xf537 (old MathType) - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', '0123456789')" - "𝟎-𝟗": # 0x1d7ce - 0x1d7d7 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" - "-": # 0xf52e - 0xf537 (old MathType) - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', '0123456789')" - "𝟬-𝟵": # 0x1D7EC - 0x1D7F5 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" - "-": # 0xf556 - 0xf55f (old MathType) @@ -3532,37 +3532,37 @@ - spell: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" - - "": [t: "nieznany znak"] # 0xf700 - - "": [t: "dolny prawy i dolny lewy trójkąt"] # 0xf726 - - "": [t: "poziome przedłużenie wielokropka"] # 0xf72d - - "": [t: "poziome przedłużenie wielokropka w linii środkowej"] # 0xf72e - - "": [t: "przedłużenie znaku pierwiastka"] # 0xf8e5 - - "": [t: "pionowy strzałka przedłużenie"] # 0xf8e6 - - "": [t: "poziomy strzałka przedłużenie"] # 0xf8e7 - - "": [t: "bezszeryfowy znak zastrzeżony"] # 0xf8e8 - - "": [t: "znak praw autorskich znak bezszeryfowe"] # 0xf8e9 - - "": [t: "bezszeryfowy znak towarowy"] # 0xf8ea - - "": [t: "lewy nawias górny"] # 0xf8eb - - "": [t: "lewy nawias przedłużenie"] # 0xf8ec - - "": [t: "lewy nawias dolny"] # 0xf8ed - - "": [t: "lewy nawias kwadratowy górny"] # 0xf8ee - - "": [t: "lewy nawias kwadratowy przedłużenie"] # 0xf8ef - - "": [t: "lewy nawias kwadratowy dolny"] # 0xf8f0 - - "": [t: "lewy nawias klamrowy górny"] # 0xf8f1 - - "": [t: "lewy nawias klamrowy środkowy"] # 0xf8f2 - - "": [t: "lewy nawias klamrowy dolny"] # 0xf8f3 - - "": [t: "nawias klamrowy przedłużenie"] # 0xf8f4 - - "": [t: "całka przedłużenie"] # 0xf8f5 - - "": [t: "prawy nawias górny"] # 0xf8f6 - - "": [t: "prawy nawias przedłużenie"] # 0xf8f7 - - "": [t: "prawy nawias dolny"] # 0xf8f8 - - "": [t: "prawy nawias kwadratowy górny"] # 0xf8f9 - - "": [t: "prawy nawias kwadratowy przedłużenie"] # 0xf8fa - - "": [t: "prawy nawias kwadratowy dolny"] # 0xf8fb - - "": [t: "prawy nawias klamrowy górny"] # 0xf8fc - - "": [t: "prawy nawias klamrowy środkowy"] # 0xf8fd - - "": [t: "prawy nawias klamrowy dolny"] # 0xf8fe - - "": [t: "logo jabłka"] # 0xf8ff + - "": [T: "nieznany znak"] # 0xf700 + - "": [T: "dolny prawy i dolny lewy trójkąt"] # 0xf726 + - "": [T: "poziome przedłużenie wielokropka"] # 0xf72d + - "": [T: "poziome przedłużenie wielokropka w linii środkowej"] # 0xf72e + - "": [T: "przedłużenie znaku pierwiastka"] # 0xf8e5 + - "": [T: "pionowy strzałka przedłużenie"] # 0xf8e6 + - "": [T: "poziomy strzałka przedłużenie"] # 0xf8e7 + - "": [T: "bezszeryfowy znak zastrzeżony"] # 0xf8e8 + - "": [T: "znak praw autorskich znak bezszeryfowe"] # 0xf8e9 + - "": [T: "bezszeryfowy znak towarowy"] # 0xf8ea + - "": [T: "lewy nawias górny"] # 0xf8eb + - "": [T: "lewy nawias przedłużenie"] # 0xf8ec + - "": [T: "lewy nawias dolny"] # 0xf8ed + - "": [T: "lewy nawias kwadratowy górny"] # 0xf8ee + - "": [T: "lewy nawias kwadratowy przedłużenie"] # 0xf8ef + - "": [T: "lewy nawias kwadratowy dolny"] # 0xf8f0 + - "": [T: "lewy nawias klamrowy górny"] # 0xf8f1 + - "": [T: "lewy nawias klamrowy środkowy"] # 0xf8f2 + - "": [T: "lewy nawias klamrowy dolny"] # 0xf8f3 + - "": [T: "nawias klamrowy przedłużenie"] # 0xf8f4 + - "": [T: "całka przedłużenie"] # 0xf8f5 + - "": [T: "prawy nawias górny"] # 0xf8f6 + - "": [T: "prawy nawias przedłużenie"] # 0xf8f7 + - "": [T: "prawy nawias dolny"] # 0xf8f8 + - "": [T: "prawy nawias kwadratowy górny"] # 0xf8f9 + - "": [T: "prawy nawias kwadratowy przedłużenie"] # 0xf8fa + - "": [T: "prawy nawias kwadratowy dolny"] # 0xf8fb + - "": [T: "prawy nawias klamrowy górny"] # 0xf8fc + - "": [T: "prawy nawias klamrowy środkowy"] # 0xf8fd + - "": [T: "prawy nawias klamrowy dolny"] # 0xf8fe + - "": [T: "logo jabłka"] # 0xf8ff - "ff": [T: "ff"] # 0xfb00 - "fi": [t: "fi"] # 0xfb01 - "fl": [T: "fl"] # 0xfb02 @@ -3570,31 +3570,31 @@ - "ffl": [T: "ffl"] # 0xfb04 - "ſt": [T: "ft"] # 0xfb05 - "st": [T: "st"] # 0xfb06 - - "﬩": [t: "hebrajska litera alternatywny znak plus"] # 0xfb29 - - "︠": [t: "lewa połowa ligatury, ozdobnik"] # 0xfe20 - - "︡": [t: "prawa połowa ligatury, ozdobnik"] # 0xfe21 - - "︢": [t: "podwójny tylda lewa połowa ozdobnik"] # 0xfe22 - - "︣": [t: "podwójny tylda prawa połowa ozdobnik"] # 0xfe23 - - "︤": [t: "makron lewa połowa ozdobnik"] # 0xfe24 - - "︥": [t: "makron prawa połowa ozdobnik"] # 0xfe25 - - "︦": [t: "łączący ozdobnik makronu"] # 0xfe26 - - "︵": [t: "przez nawias"] # 0xfe35 - - "︶": [t: "pod nawias"] # 0xfe36 - - "︷": [t: "przez nawias klamrowy"] # 0xfe37 - - "︸": [t: "pod nawias klamrowy"] # 0xfe38 - - "︿": [t: "przez kąt nawias kwadratowy"] # 0xfe3f - - "﹀": [t: "pod kąt nawias kwadratowy"] # 0xfe40 - - "﹡": [t: "mały gwiazdka"] # 0xfe61 - - "﹢": [t: "mały plus"] # 0xfe62 - - "﹣": [t: "mały minus"] # 0xfe63 - - "﹤": [t: "mały mniejsze niż"] # 0xfe64 - - "﹥": [t: "mały większe niż"] # 0xfe65 - - "﹦": [t: "mały równa się"] # 0xfe66 - - "+": [t: "pełnoszeroki znak plus"] # 0xff0b + - "﬩": [T: "hebrajska litera alternatywny znak plus"] # 0xfb29 + - "︠": [T: "lewa połowa ligatury, ozdobnik"] # 0xfe20 + - "︡": [T: "prawa połowa ligatury, ozdobnik"] # 0xfe21 + - "︢": [T: "podwójny tylda lewa połowa ozdobnik"] # 0xfe22 + - "︣": [T: "podwójny tylda prawa połowa ozdobnik"] # 0xfe23 + - "︤": [T: "makron lewa połowa ozdobnik"] # 0xfe24 + - "︥": [T: "makron prawa połowa ozdobnik"] # 0xfe25 + - "︦": [T: "łączący ozdobnik makronu"] # 0xfe26 + - "︵": [T: "przez nawias"] # 0xfe35 + - "︶": [T: "pod nawias"] # 0xfe36 + - "︷": [T: "przez nawias klamrowy"] # 0xfe37 + - "︸": [T: "pod nawias klamrowy"] # 0xfe38 + - "︿": [T: "przez kąt nawias kwadratowy"] # 0xfe3f + - "﹀": [T: "pod kąt nawias kwadratowy"] # 0xfe40 + - "﹡": [T: "mały gwiazdka"] # 0xfe61 + - "﹢": [T: "mały plus"] # 0xfe62 + - "﹣": [T: "mały minus"] # 0xfe63 + - "﹤": [T: "mały mniejsze niż"] # 0xfe64 + - "﹥": [T: "mały większe niż"] # 0xfe65 + - "﹦": [T: "mały równa się"] # 0xfe66 + - "+": [T: "pełnoszeroki znak plus"] # 0xff0b - "<": [T: "mniejsze niż"] # 0xff1c - "=": [T: "równa się"] # 0xff1d - ">": [T: "większe niż"] # 0xff1e - - "\": [t: "ukośnik odwrotny"] # 0xff3c + - "\": [T: "ukośnik odwrotny"] # 0xff3c - "^": [T: "daszek"] # 0xff3e - "|": # 0xff5c # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' @@ -3616,21 +3616,21 @@ - else: [T: "dzieli"] - "~": [T: "tylda"] # 0xff5e - "¬": [T: "nie"] # 0xffe2 - - "←": [t: "strzałka w lewo"] # 0xffe9 - - "↑": [t: "strzałka w górę"] # 0xffea - - "→": [t: "strzałka w prawo"] # 0xffeb - - "↓": [t: "strzałka w dół"] # 0xffec - - "": [t: "nieznany lub brakujący obiekt"] # 0xfffc - - "�": [t: "nieznany lub brakujący znak"] # 0xfffd + - "←": [T: "strzałka w lewo"] # 0xffe9 + - "↑": [T: "strzałka w górę"] # 0xffea + - "→": [T: "strzałka w prawo"] # 0xffeb + - "↓": [T: "strzałka w dół"] # 0xffec + - "": [T: "nieznany lub brakujący obiekt"] # 0xfffc + - "�": [T: "nieznany lub brakujący znak"] # 0xfffd - - "🣑": [t: "jest w równowadze z"] # 0x1F8D1 - - "🣒": [t: "jest w równowadze przesuniętej w prawo z"] # 0x1F8D2 - - "🣓": [t: "jest w równowadze przesuniętej w lewo z"] # 0x1F8D3 + - "🣑": [T: "jest w równowadze z"] # 0x1F8D1 + - "🣒": [T: "jest w równowadze przesuniętej w prawo z"] # 0x1F8D2 + - "🣓": [T: "jest w równowadze przesuniętej w lewo z"] # 0x1F8D3 # MathJax v4 has adopted these PUA values for some partial chem bonds that aren't in Unicode - - "\uE410": [t: "wiązanie cząstkowe"] # 0xe410 - - "\uE411": [t: "podwójne wiązanie cząstkowe"] # 0xe411 - - "\uE412": [t: "potrójne wiązanie cząstkowe"] # 0xe412 + - "\uE410": [T: "wiązanie cząstkowe"] # 0xe410 + - "\uE411": [T: "podwójne wiązanie cząstkowe"] # 0xe411 + - "\uE412": [T: "potrójne wiązanie cząstkowe"] # 0xe412 # MathJax v4 also adopted these PUA values for some arrows thar are in Unicode # Hopefully these will be exported properly in future versions of MathJax diff --git a/Rules/Languages/pl/unicode.yaml b/Rules/Languages/pl/unicode.yaml index bd3ee353a..c67b5cc8a 100644 --- a/Rules/Languages/pl/unicode.yaml +++ b/Rules/Languages/pl/unicode.yaml @@ -5,12 +5,12 @@ - "a": - test: if: "$TTS='none'" - then: [t: "a"] # long "a" sound in all speech engines I tested (espeak, MS SAPI, eloquence, + then: [T: "a"] # long "a" sound in all speech engines I tested (espeak, MS SAPI, eloquence, else: [spell: "'a'"] # AWS Polly, ReadSpeaker, NaturalReader, google cloud, nuance, ibm watson) - "b-z": - test: if: "$TTS='none'" - then: [t: "."] + then: [T: "."] else: [spell: "'.'"] # Capital letters are a little tricky: users can pick their favorite word (something that was requested) and @@ -30,14 +30,14 @@ if: "$SpeechOverrides_CapitalLetters = ''" then_test: if: "$Impairment = 'Blindness'" - then: [t: "wielka"] + then: [T: "wielka"] else: [x: "$SpeechOverrides_CapitalLetters"] - pitch: value: "$CapitalLetters_Pitch" replace: - test: if: "$TTS='none'" - then: [t: "a"] + then: [T: "a"] else: [spell: "'a'"] - "B-Z": @@ -53,7 +53,7 @@ if: "$SpeechOverrides_CapitalLetters = ''" then_test: if: "$Impairment = 'Blindness'" - then: [t: "wielka"] + then: [T: "wielka"] else: [x: "$SpeechOverrides_CapitalLetters"] - pitch: value: "$CapitalLetters_Pitch" @@ -73,12 +73,12 @@ else: [T: "wykrzyknik"] # 0x21 else: [T: "silnia"] # 0x21 - - "\"": [t: "cudzysłów"] # 0x22 - - "#": [t: "numer"] # 0x23 - - "$": [t: "dolary"] # 0x24 + - "\"": [T: "cudzysłów"] # 0x22 + - "#": [T: "numer"] # 0x23 + - "$": [T: "dolary"] # 0x24 - "%": [T: "procent"] # 0x25 - - "&": [t: "znak et"] # 0x26 - - "'": [t: "apostrof"] # 0x27 + - "&": [T: "znak et"] # 0x26 + - "'": [T: "apostrof"] # 0x27 - "(": # 0x28 - test: if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' @@ -105,7 +105,7 @@ then: [T: "gwiazdkowa"] # 0x2a (norma 'gwiazdkowa' - * jako indeks normy) else_test: if: "parent::*[name(.)='msup' or name(.)='msubsup' or name(.)='skip-super']" - then: [t: "gwiazda"] # 0x2a + then: [T: "gwiazda"] # 0x2a else: [T: "razy"] # 0x2a - "+": [T: "plus"] # 0x2b - ",": # 0x2c @@ -157,7 +157,7 @@ then: [T: "jest"] - T: "większe niż" - "?": [T: "znak zapytania"] # 0x3f - - "@": [t: "małpa"] # 0x40 + - "@": [T: "małpa"] # 0x40 - "[": # 0x5b - test: if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' @@ -173,9 +173,9 @@ - test: if: "parent::m:modified-variable or parent::m:mover" then: [T: "daszek"] - else: [t: "daszek"] - - "_": [t: "pod kreska"] # 0x5f - - "`": [t: "grawis"] # 0x60 + else: [T: "daszek"] + - "_": [T: "pod kreska"] # 0x5f + - "`": [T: "grawis"] # 0x60 - "{": # 0x7b - test: if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' @@ -226,7 +226,7 @@ then: [T: "stopni"] else: [T: "stopień"] - "±": [T: "plus minus"] # 0xb1 - - "´": [t: "akut"] # 0xb4 + - "´": [T: "akut"] # 0xb4 - "·": # 0xB7 - test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')] or not($SpeechStyle = 'ClearSpeak' and $ClearSpeak_MultSymbolDot = 'Auto')" @@ -240,21 +240,21 @@ then: [T: "razy"] - else_if: "$ClearSpeak_MultSymbolX = 'By'" then: [T: "na"] - else: [t: "krzyż"] + else: [T: "krzyż"] else_test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [t: "krzyż"] + then: [T: "krzyż"] else: [T: "razy"] - "÷": [T: "podzielone przez"] # 0xf7 - - "̀": [t: "ozdobnik akcentu grawis"] # 0x300 - - "́": [t: "ozdobnik akcentu ostrego"] # 0x301 - - "̂": [t: "ozdobnik daszka"] # 0x302 - - "̃": [t: "ozdobnik tyldy"] # 0x303 - - "̄": [t: "ozdobnik makronu"] # 0x304 - - "̅": [t: "ozdobnik kreski górnej"] # 0x305 - - "̆": [t: "znak krótkości"] # 0x306 - - "̇": [t: "ozdobnik kropki nad"] # 0x307 + - "̀": [T: "ozdobnik akcentu grawis"] # 0x300 + - "́": [T: "ozdobnik akcentu ostrego"] # 0x301 + - "̂": [T: "ozdobnik daszka"] # 0x302 + - "̃": [T: "ozdobnik tyldy"] # 0x303 + - "̄": [T: "ozdobnik makronu"] # 0x304 + - "̅": [T: "ozdobnik kreski górnej"] # 0x305 + - "̆": [T: "znak krótkości"] # 0x306 + - "̇": [T: "ozdobnik kropki nad"] # 0x307 # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong - "Α-Ω": @@ -270,47 +270,47 @@ if: "$SpeechOverrides_CapitalLetters = ''" then_test: if: "$Impairment = 'Blindness'" - then: [t: "wielka"] + then: [T: "wielka"] else: [x: "$SpeechOverrides_CapitalLetters"] - pitch: value: "$CapitalLetters_Pitch" # note: processing of ranges converts '.' into the character, so it needs to be in quotes below replace: [spell: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] - - "α": [t: "alfa"] # 0x3b1 + - "α": [T: "alfa"] # 0x3b1 - "β": [t: "beta"] # 0x3b2 - "γ": [t: "gamma"] # 0x3b3 - "δ": [t: "delta"] # 0x3b4 - "ε": [t: "epsilon"] # 0x3b5 - - "ζ": [t: "dzeta"] # 0x3b6 + - "ζ": [T: "dzeta"] # 0x3b6 - "η": [t: "eta"] # 0x3b7 - "θ": [t: "theta"] # 0x3b8 - - "ι": [t: "jota"] # 0x3b9 + - "ι": [T: "jota"] # 0x3b9 - "κ": [t: "kappa"] # 0x3ba - "λ": [t: "lambda"] # 0x3bb - - "μ": [t: "mi"] # 0x3bc - - "ν": [t: "ni"] # 0x3bd - - "ξ": [t: "ksi"] # 0x3be - - "ο": [t: "omikron"] # 0x3bf + - "μ": [T: "mi"] # 0x3bc + - "ν": [T: "ni"] # 0x3bd + - "ξ": [T: "ksi"] # 0x3be + - "ο": [T: "omikron"] # 0x3bf - "π": [t: "pi"] # 0x3c0 - - "ρ": [t: "ro"] # 0x3c1 - - "ς": [t: "sigma końcowa"] # 0x3c2 + - "ρ": [T: "ro"] # 0x3c1 + - "ς": [T: "sigma końcowa"] # 0x3c2 - "σ": [t: "sigma"] # 0x3c3 - "τ": [t: "tau"] # 0x3c4 - - "υ": [t: "ypsilon"] # 0x3c5 - - "φ": [t: "fi"] # 0x3c6 + - "υ": [T: "ypsilon"] # 0x3c5 + - "φ": [T: "fi"] # 0x3c6 - "χ": [t: "chi"] # 0x3c7 - "ψ": [t: "psi"] # 0x3c8 - "ω": [t: "omega"] # 0x3c9 - - "ϕ": [t: "fi"] # 0x3d5 + - "ϕ": [T: "fi"] # 0x3d5 - "ϖ": [t: "pi"] # 0x3d6 - "ϵ": [t: "epsilon"] # 0x3f5 - - "϶": [t: "odwrócony epsilon"] # 0x3f6 + - "϶": [T: "odwrócony epsilon"] # 0x3f6 - - "–": [t: "półpauza"] # 0x2013 - - "—": [t: "pauza"] # 0x2014 - - "―": [t: "kreska pozioma"] # 0x2015 - - "‖": [t: "podwójna pionowa kreska"] # 0x2016 + - "–": [T: "półpauza"] # 0x2013 + - "—": [T: "pauza"] # 0x2014 + - "―": [T: "kreska pozioma"] # 0x2015 + - "‖": [T: "podwójna pionowa kreska"] # 0x2016 - "…": # 0x2026 test: if: @@ -318,11 +318,11 @@ # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' # speak '…' as 'and so on...' unless expr starts with '…' - "../*[1][.='…']" - then: [t: "trzy kropki"] + then: [T: "trzy kropki"] else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' if: "count(following-sibling::*) = 0" - then: [t: "i tak dalej"] - else: [t: "i tak dalej aż do"] + then: [T: "i tak dalej"] + else: [T: "i tak dalej aż do"] - "⁡": # 0x2061 - test: @@ -340,55 +340,55 @@ - "⁢": [T: ""] # 0x2062 - "⁣": [T: ""] # 0x2063 - "⁤": [T: "i"] # 0x2064 - - "′": [t: "prim"] # 0x2032 - - "″": [t: "podwójny prim"] # 0x2033 - - "‴": [t: "potrójny prim"] # 0x2034 + - "′": [T: "prim"] # 0x2032 + - "″": [T: "podwójny prim"] # 0x2033 + - "‴": [T: "potrójny prim"] # 0x2034 - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" - - "℃": [t: "stopnie Celsjusza"] # 0x2103 - - "℉": [t: "stopnie Fahrenheita"] # 0x2109 + - "℃": [T: "stopnie Celsjusza"] # 0x2103 + - "℉": [T: "stopnie Fahrenheita"] # 0x2109 - "ℋℛℓ": # 0x210b - - t: "pisane" + - T: "pisane" - spell: "translate('.', 'ℋℛℓ', 'HRl')" - - "ℎ": [t: "stała Plancka"] # 0x210e + - "ℎ": [T: "stała Plancka"] # 0x210e - "ℜ": # 0x211c - - t: "fraktura" + - T: "fraktura" - spell: "'R'" - - "Ω": [t: "omy"] # 0x2126 - - "K": [t: "kelwin"] # 0x212a - - "Å": [t: "angstremy"] # 0x212b + - "Ω": [T: "omy"] # 0x2126 + - "K": [T: "kelwin"] # 0x212a + - "Å": [T: "angstremy"] # 0x212b - "ⅆⅇⅈⅉ": # 0x2146-9 - - t: "dwukreskowa kursywa" + - T: "dwukreskowa kursywa" - spell: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" - - "←": [t: "strzałka w lewo"] # 0x2190 - - "↑": [t: "strzałka w górę"] # 0x2191 + - "←": [T: "strzałka w lewo"] # 0x2190 + - "↑": [T: "strzałka w górę"] # 0x2191 - "→": # 0x2192 - test: if: "ancestor::*[2][self::m:limit or self::m:limit-sup or self::m:limit-inf]" - then: [t: "dąży do"] + then: [T: "dąży do"] else_test: if: "parent::*[self::m:mrow]/parent::*[self::m:subscripted-norm]" - then: [t: "do"] # indeks normy operatorowej ‖·‖_{p→q}: → czyta sie "do" - else: [t: "strzałka w prawo"] + then: [T: "do"] # indeks normy operatorowej ‖·‖_{p→q}: → czyta sie "do" + else: [T: "strzałka w prawo"] - - "↓": [t: "strzałka w dół"] # 0x2193 + - "↓": [T: "strzałka w dół"] # 0x2193 - "⇒": [T: "implikuje"] # 0x21d2 - - "∀": [t: "dla każdego"] # 0x2200 + - "∀": [T: "dla każdego"] # 0x2200 - "∂": # 0x2202 - test: if: "$Verbosity='Terse'" - then: [t: "cząstkowe"] - else: [t: "pochodna cząstkowa"] - - "∃": [t: "istnieje"] # 0x2203 - - "∄": [t: "nie istnieje"] # 0x2204 + then: [T: "cząstkowe"] + else: [T: "pochodna cząstkowa"] + - "∃": [T: "istnieje"] # 0x2203 + - "∄": [T: "nie istnieje"] # 0x2204 - "∅": [T: "zbiór pusty"] # 0x2205 - "∆": # 0x2206 - - t: "laplasjan" + - T: "laplasjan" - "∈": # 0x2208 - test: if: "$SpeechStyle != 'ClearSpeak'" @@ -396,7 +396,7 @@ - test: if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" then: [T: "jest"] - - t: "elementem zbioru" + - T: "elementem zbioru" # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option else_test: if: "../../self::m:set or ../../../self::m:set" # inside a set @@ -404,43 +404,43 @@ - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' then: [T: "do"] - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "element zbioru"] + then: [T: "element zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "należy do"] - - else: [t: "należące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + then: [T: "należy do"] + - else: [T: "należące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' else_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "jest elementem zbioru"] + then: [T: "jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "jest elementem zbioru"] + then: [T: "jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "należy do"] - - else: [t: "należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + then: [T: "należy do"] + - else: [T: "należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' - "∉": # 0x2209 # rule is identical to 0x2208 - test: if: "$SpeechStyle != 'ClearSpeak'" then: - - t: "nie jest elementem zbioru" + - T: "nie jest elementem zbioru" # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option else_test: if: "../../self::m:set or ../../../self::m:set" # inside a set then_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "nie należy do"] + then: [T: "nie należy do"] - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "nie jest elementem zbioru"] + then: [T: "nie jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "nie jest elementem zbioru"] - - else: [t: "nienależące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + then: [T: "nie jest elementem zbioru"] + - else: [T: "nienależące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' else_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "nie jest elementem zbioru"] + then: [T: "nie jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "nie jest elementem zbioru"] + then: [T: "nie jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "nie należy do"] - - else: [t: "nie należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + then: [T: "nie należy do"] + - else: [T: "nie należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' - "∊": # 0x220a - test: if: "$SpeechStyle != 'ClearSpeak'" @@ -448,7 +448,7 @@ - test: if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" then: [T: "jest"] - - t: "element zbioru" + - T: "element zbioru" # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option else_test: if: "../../self::m:set or ../../../self::m:set" # inside a set @@ -456,20 +456,20 @@ - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' then: [T: "do"] - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "element zbioru"] + then: [T: "element zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "należy do"] - - else: [t: "należące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + then: [T: "należy do"] + - else: [T: "należące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' else_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "jest elementem zbioru"] + then: [T: "jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "jest elementem zbioru"] + then: [T: "jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "należy do"] - - else: [t: "należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + then: [T: "należy do"] + - else: [T: "należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' - "∏": [T: "iloczyn"] # 0x220f - - "∐": [t: "koprodukt"] # 0x2210 + - "∐": [T: "koprodukt"] # 0x2210 - "∑": [T: "suma"] # 0x2211 - "−": [T: "minus"] # 0x2212 - "∓": [T: "minus plus"] # 0x2213 @@ -481,60 +481,60 @@ - "parent::*[name(.)='msubsup' and *[1][self::m:mo and .='∥']] and count(preceding-sibling::*)=1" then: [T: "gwiazdkowa"] # norma ‖·‖_* -> "norma gwiazdkowa" else: [T: "razy"] # 0x2217 - - "∘": [t: "złożone z"] # 0x2218 + - "∘": [T: "złożone z"] # 0x2218 - "√": # 0x221a - - t: "pierwiastek kwadratowy z" + - T: "pierwiastek kwadratowy z" - "∝": # 0x221d - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "proporcjonalne do" + - T: "proporcjonalne do" - "∞": - test: if: "ancestor::*[self::m:limit or self::m:limit-sup or self::m:limit-inf or self::m:large-op] or parent::*[self::m:subscripted-norm] or parent::*[self::m:mrow]/parent::*[self::m:subscripted-norm]" then: [T: "nieskończoności"] else: [T: "nieskończoność"] # 0x221e - - "∟": [t: "kąt prosty"] # 0x221f - - "∠": [t: "kąt"] # 0x2220 - - "∡": [t: "kąt mierzony"] # 0x2221 + - "∟": [T: "kąt prosty"] # 0x221f + - "∠": [T: "kąt"] # 0x2220 + - "∡": [T: "kąt mierzony"] # 0x2221 - "∣": [T: "dzieli"] # 0x2223 - - "∤": [t: "nie dzieli"] # 0x2224 + - "∤": [T: "nie dzieli"] # 0x2224 - "∥": # 0x2225 - test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [t: "podwójna pionowa kreska"] + then: [T: "podwójna pionowa kreska"] else: - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "równoległe do" + - T: "równoległe do" - "∦": # 0x2226 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "nierównoległe do" + - T: "nierównoległe do" - "∧": [T: "i"] # 0x2227 - "∨": [T: "lub"] # 0x2228 - "∩": [T: "przecięcie"] # 0x2229 - "∪": [T: "suma zbiorów"] # 0x222a - "∫": [T: "całka"] # 0x222b - - "∬": [t: "całka podwójna"] # 0x222c - - "∭": [t: "całka potrójna"] # 0x222d - - "∮": [t: "całka krzywoliniowa"] # 0x222e + - "∬": [T: "całka podwójna"] # 0x222c + - "∭": [T: "całka potrójna"] # 0x222d + - "∮": [T: "całka krzywoliniowa"] # 0x222e - "∶": # 0x2236 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - T: "do" - - "∷": [t: "jako"] # 0x2237 - - "∼": [t: "tylda"] # 0x223c - - "∽": [t: "odwrócona tylda"] # 0x223d + - "∷": [T: "jako"] # 0x2237 + - "∼": [T: "tylda"] # 0x223c + - "∽": [T: "odwrócona tylda"] # 0x223d - "∾": # 0x223e - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "most dodatnie" - - "∿": [t: "fala sinusoidalna"] # 0x223f + - T: "most dodatnie" + - "∿": [T: "fala sinusoidalna"] # 0x223f - "≠": # 0x2260 - test: if: "$Verbosity!='Terse'" @@ -544,7 +544,7 @@ - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "identyczne z" + - T: "identyczne z" - "≤": # 0x2264 - test: if: "$Verbosity!='Terse'" @@ -555,31 +555,31 @@ if: "$Verbosity!='Terse'" then: [T: "jest"] - T: "większe lub równe" - - "≦": [t: "mniejsze nad równe"] # 0x2266 - - "≧": [t: "większe nad równe"] # 0x2267 - - "≺": [t: "poprzedza"] # 0x227a - - "≻": [t: "następuje po"] # 0x227b + - "≦": [T: "mniejsze nad równe"] # 0x2266 + - "≧": [T: "większe nad równe"] # 0x2267 + - "≺": [T: "poprzedza"] # 0x227a + - "≻": [T: "następuje po"] # 0x227b - "⊂": # 0x2282 - test: if: "$Verbosity!='Terse'" - then: [t: "jest"] - - t: "podzbiorem" + then: [T: "jest"] + - T: "podzbiorem" - "⊃": # 0x2283 - test: if: "$Verbosity!='Terse'" - then: [t: "jest"] - - t: "nadzbiorem" + then: [T: "jest"] + - T: "nadzbiorem" - "⊄": # 0x2284 - - t: "nie jest podzbiorem" + - T: "nie jest podzbiorem" - "⊅": # 0x2285 - - t: "nie jest nadzbiorem" + - T: "nie jest nadzbiorem" - "⊆": # 0x2286 - test: if: "$Verbosity!='Terse'" - then: [t: "jest"] - - t: "podzbiorem lub równym" + then: [T: "jest"] + - T: "podzbiorem lub równym" - "⊇": # 0x2287 - test: if: "$Verbosity!='Terse'" - then: [t: "jest"] - - t: "nadzbiorem lub równym" + then: [T: "jest"] + - T: "nadzbiorem lub równym" diff --git a/tests/Languages/pl.rs b/tests/Languages/pl.rs index 44016ff5b..c9423ea9f 100644 --- a/tests/Languages/pl.rs +++ b/tests/Languages/pl.rs @@ -2,6 +2,8 @@ // Existing hand-written Polish tests (norms, degrees, relations, etc.) mod pl; +mod number_sets; +mod unit_plurals; // Tests mirrored from the English suite, with expected speech localized to Polish. mod ClearSpeak { diff --git a/tests/Languages/pl/ClearSpeak/mfrac.rs b/tests/Languages/pl/ClearSpeak/mfrac.rs index f7197bcb2..a53bba559 100644 --- a/tests/Languages/pl/ClearSpeak/mfrac.rs +++ b/tests/Languages/pl/ClearSpeak/mfrac.rs @@ -86,7 +86,7 @@ fn frac_with_units() -> Result<()> { "; - test("pl", "ClearSpeak", expr, "62 milas na godzina")?; + test("pl", "ClearSpeak", expr, "62 mile na godzina")?; return Ok(()); } diff --git a/tests/Languages/pl/SimpleSpeak/mfrac.rs b/tests/Languages/pl/SimpleSpeak/mfrac.rs index 2e84dc987..a07f0592b 100644 --- a/tests/Languages/pl/SimpleSpeak/mfrac.rs +++ b/tests/Languages/pl/SimpleSpeak/mfrac.rs @@ -164,7 +164,7 @@ fn frac_with_units() -> Result<()> { "; - test("pl", "SimpleSpeak", expr, "62 milas na godzina")?; + test("pl", "SimpleSpeak", expr, "62 mile na godzina")?; return Ok(()); } @@ -198,7 +198,7 @@ fn number_in_numerator_with_units() -> Result<()> { mi "; - test("pl", "SimpleSpeak", expr, "3 galons na mila")?; + test("pl", "SimpleSpeak", expr, "3 galony na mila")?; return Ok(()); } @@ -212,7 +212,7 @@ fn units_with_powers() -> Result<()> { s2 "; - test("pl", "SimpleSpeak", expr, "3 metrs na sekunda do kwadratu")?; + test("pl", "SimpleSpeak", expr, "3 metry na sekunda do kwadratu")?; return Ok(()); } diff --git a/tests/Languages/pl/number_sets.rs b/tests/Languages/pl/number_sets.rs new file mode 100644 index 000000000..6d672447b --- /dev/null +++ b/tests/Languages/pl/number_sets.rs @@ -0,0 +1,69 @@ +/// Number sets: ℂ ℕ ℚ ℝ ℤ, on their own and with a dimension (ℝ³). +/// +/// These rules had no Polish test at all, which is how the earlier defects in +/// this file were able to sit unnoticed: a rule with no test in a given +/// language is not "known good", it is "never looked at". +use crate::common::*; +use anyhow::Result; + +/// A bare number set is spoken as a full Polish phrase. +#[test] +fn simple_number_sets() -> Result<()> { + let expr = r#" + ℂ, + ℕ, + ℚ, + ℝ, + ℤ + "#; + test("pl", "SimpleSpeak", expr, "liczby zespolone przecinek, liczby naturalne przecinek, liczby wymierne przecinek, liczby rzeczywiste, przecinek, liczby całkowite")?; + Ok(()) +} + +/// With a dimension the letter itself is spoken, as in every language except +/// Hungarian: "R 3", not "liczby rzeczywiste 3". +#[test] +fn dimension_number_sets() -> Result<()> { + let expr = r#" + ℝ3, + ℂ2, + ℕ4 + "#; + test("pl", "SimpleSpeak", expr, "R 3 przecinek, C 2 przecinek, N 4")?; + Ok(()) +} + +/// A non-numeric exponent is not a dimension, so the full phrase comes back. +/// This is the negative control for the rule above: it fires on `count(*)=2` +/// with a digit, and must not swallow every superscript. +#[test] +fn number_set_with_variable_exponent() -> Result<()> { + let expr = r#" + ℤn + "#; + test("pl", "SimpleSpeak", expr, "liczby całkowite do potęgi n")?; + Ok(()) +} + +/// Positive and negative variants (ℝ⁺, ℤ⁻) are a separate rule again. +#[test] +fn pos_neg_number_sets() -> Result<()> { + let expr = r#" + ℝ+, + ℤ- + "#; + test("pl", "SimpleSpeak", expr, "plus liczby rzeczywiste, przecinek; minus liczby całkowite")?; + Ok(()) +} + +/// ClearSpeak must agree with SimpleSpeak here - the rules live in +/// SharedRules, so a divergence would mean one of them stopped matching. +#[test] +fn number_sets_clearspeak_matches() -> Result<()> { + let expr = r#" + ℝ, + ℝ3 + "#; + test("pl", "ClearSpeak", expr, "liczby rzeczywiste, przecinek, R 3")?; + Ok(()) +} diff --git a/tests/Languages/pl/unit_plurals.rs b/tests/Languages/pl/unit_plurals.rs new file mode 100644 index 000000000..a3a6ec5b8 --- /dev/null +++ b/tests/Languages/pl/unit_plurals.rs @@ -0,0 +1,86 @@ +/// Polish unit plurals: the noun form follows the numeral, not just "is it one". +/// 1 metr | 2, 3, 4 metry (nominative plural) | 5+ metrów (genitive plural) +/// The teens are the exception that breaks the naive rule: 12, 13, 14 metrów. +use crate::common::*; +use anyhow::Result; + +/// The three numeral classes on a single unit, including the teens exception. +#[test] +fn unit_plural_numeral_classes() -> Result<()> { + let expr = r#" + 1m,2m, + 3m,4m, + 5m,11m, + 12m,13m, + 14m,22m, + 101m,102m, + 112m + "#; + test("pl", "SimpleSpeak", expr, "1 metr, przecinek; 2 metry, przecinek; 3 metry, przecinek; 4 metry, przecinek; 5 metrów, przecinek; 11 metrów, przecinek; 12 metrów, przecinek; 13 metrów, przecinek; 14 metrów, przecinek; 22 metry, przecinek; 101 metrów, przecinek; 102 metry, przecinek; 112 metrów")?; + Ok(()) +} + +/// SI base units: previously all of these took the English "s". +#[test] +fn unit_plural_si_base() -> Result<()> { + let expr = r#" + 2g,5g, + 2s,5s, + 2A,5A, + 2K,5K, + 2mol,5mol, + 2cd,5cd + "#; + test("pl", "SimpleSpeak", expr, "2 gramy, przecinek; 5 gramów, przecinek; 2 sekundy, przecinek; 5 sekund, przecinek; 2 ampery, przecinek; 5 amperów, przecinek; 2 kelwiny, przecinek; 5 kelwinów, przecinek; 2 mole, przecinek; 5 moli, przecinek; 2 kandele, przecinek; 5 kandeli")?; + Ok(()) +} + +/// With an SI prefix the unit goes through a different branch of the rule. +#[test] +fn unit_plural_with_prefix() -> Result<()> { + let expr = r#" + 2km,5km, + 2mg,5mg, + 2daA,5daA + "#; + test("pl", "SimpleSpeak", expr, "2 kilo-metry, przecinek; 5 kilo-metrów, przecinek; 2 mili-gramy, przecinek; 5 mili-gramów, przecinek; 2 deka-ampery, przecinek; 5 deka-amperów")?; + Ok(()) +} + +/// Irregular nouns: the plural cannot be derived from the ending. +#[test] +fn unit_plural_irregular() -> Result<()> { + let expr = r#" + 2d,5d, + 2w,5w, + 2yr,5yr, + 2ft,5ft + "#; + test("pl", "SimpleSpeak", expr, "2 dni, przecinek, 5 dni, przecinek; 2 tygodnie, przecinek; 5 tygodni, przecinek; 2 lata, przecinek, 5 lat, przecinek; 2 stopy, przecinek; 5 stóp")?; + Ok(()) +} + +/// Units whose base form was itself wrong (plural used as singular). +#[test] +fn unit_singular_forms_fixed() -> Result<()> { + let expr = r#" + 1Hz,2Hz, + 5Hz, + 1hp,2hp, + 1℧ + "#; + test("pl", "SimpleSpeak", expr, "1 herc, przecinek; 2 herce, przecinek; 5 herców, przecinek; 1 koń mechaniczny, przecinek; 2 konie mechaniczne, przecinek, 1 mho")?; + Ok(()) +} + +/// Multi-word units inflect the head noun and keep the dependent word's case. +#[test] +fn unit_plural_multiword() -> Result<()> { + let expr = r#" + 2ly,5ly, + 2au,5au, + 2arcmin,5arcmin + "#; + test("pl", "SimpleSpeak", expr, "2 lata świetlne, przecinek; 5 lat świetlnych, przecinek; 2 jednostki astronomiczne, przecinek; 5 jednostek astronomicznych; przecinek; 2 minuty łuku, przecinek; 5 minut łuku")?; + Ok(()) +} diff --git a/tests/Languages/pl/units.rs b/tests/Languages/pl/units.rs index 1676cf8ae..591e2eaff 100644 --- a/tests/Languages/pl/units.rs +++ b/tests/Languages/pl/units.rs @@ -40,7 +40,7 @@ fn prefix_sweep() -> Result<()> { qg "#; test("pl", "SimpleSpeak", expr, - "kwetta-grams, przecinek; ronna-grams, przecinek; jotta-grams, przecinek; zetta-grams, przecinek; eksa-grams, przecinek; peta-grams, przecinek; tera-grams, przecinek; giga-grams, przecinek; mega-grams, przecinek; kilo-grams, przecinek; hekto-grams, przecinek; deka-grams, przecinek; decy-grams, przecinek; centy-grams, przecinek; mili-grams, przecinek; mikro-grams, przecinek; nano-grams, przecinek; piko-grams, przecinek; femto-grams, przecinek; atto-grams, przecinek; zepto-grams, przecinek; jokto-grams, przecinek; ronto-grams, przecinek; kwekto-grams")?; + "kwetta-gramów, przecinek; ronna-gramów, przecinek; jotta-gramów, przecinek; zetta-gramów, przecinek; eksa-gramów, przecinek; peta-gramów, przecinek; tera-gramów, przecinek; giga-gramów, przecinek; mega-gramów, przecinek; kilo-gramów, przecinek; hekto-gramów, przecinek; deka-gramów, przecinek; decy-gramów, przecinek; centy-gramów, przecinek; mili-gramów, przecinek; mikro-gramów, przecinek; nano-gramów, przecinek; piko-gramów, przecinek; femto-gramów, przecinek; atto-gramów, przecinek; zepto-gramów, przecinek; jokto-gramów, przecinek; ronto-gramów, przecinek; kwekto-gramów")?; return Ok(()); } @@ -61,7 +61,7 @@ fn si_base() -> Result<()> { 1sec,2sec "#; test("pl", "SimpleSpeak", expr, - "1 amper, przecinek; 2 ampers, przecinek; 1 kandela, przecinek; 2 kandelas, przecinek; 1 kelwin, przecinek; 2 kelwins, przecinek; 1 kelwin, przecinek; 2 kelwins, przecinek; 1 gram, przecinek; 2 grams, przecinek; 1 metr, przecinek; 2 metrs, przecinek, 1 mol, przecinek; 2 mols, przecinek; 1 sekunda, przecinek; 2 sekundas, przecinek; 1 sekunda, przecinek; 2 sekundas, przecinek; 1 sekunda, przecinek; 2 sekundas, przecinek; 1 sekunda, przecinek; 2 sekundas")?; + "1 amper, przecinek; 2 ampery, przecinek; 1 kandela, przecinek; 2 kandele, przecinek; 1 kelwin, przecinek; 2 kelwiny, przecinek; 1 kelwin, przecinek; 2 kelwiny, przecinek; 1 gram, przecinek; 2 gramy, przecinek; 1 metr, przecinek; 2 metry, przecinek, 1 mol, przecinek; 2 mole, przecinek; 1 sekunda, przecinek; 2 sekundy, przecinek; 1 sekunda, przecinek; 2 sekundy, przecinek; 1 sekunda, przecinek; 2 sekundy, przecinek; 1 sekunda, przecinek; 2 sekundy")?; return Ok(()); } @@ -80,7 +80,7 @@ fn si_base_with_prefixes() -> Result<()> { 1nsec,2psec "#; test("pl", "SimpleSpeak", expr, - "1 kwetta-amper, przecinek; 2 ronna-ampers, przecinek; 1 jotta-kandela, przecinek; 2 zetta-kandelas; przecinek; 1 eksa-kelwin, przecinek; 2 peta-kelwins, przecinek; 1 tera-kelwin, przecinek; 2 giga-kelwins, przecinek; 1 mega-gram, przecinek; 2 kilo-grams, przecinek; 1 hekto-metr, przecinek; 2 deka-metrs, przecinek; 1 decy-mol, przecinek; 2 centy-mols, przecinek; 1 mili-sekunda, przecinek; 2 mikro-sekundas; przecinek; 1 nano-sekunda, przecinek; 2 piko-sekundas")?; + "1 kwetta-amper, przecinek; 2 ronna-ampery, przecinek; 1 jotta-kandela, przecinek; 2 zetta-kandele, przecinek; 1 eksa-kelwin, przecinek; 2 peta-kelwiny, przecinek; 1 tera-kelwin, przecinek; 2 giga-kelwiny, przecinek; 1 mega-gram, przecinek; 2 kilo-gramy, przecinek; 1 hekto-metr, przecinek; 2 deka-metry, przecinek; 1 decy-mol, przecinek; 2 centy-mole, przecinek; 1 mili-sekunda, przecinek; 2 mikro-sekundy, przecinek; 1 nano-sekunda, przecinek; 2 piko-sekundy")?; return Ok(()); } @@ -103,7 +103,7 @@ fn si_derived_1() -> Result<()> { 1lx,2lx "#; test("pl", "SimpleSpeak", expr, - "1 bekerel, przecinek; 2 bekerels, przecinek; 1 kulomb, przecinek; 2 kulombs, przecinek; 1 stopień Celsjusza, przecinek; 2 stopnie Celsjusza, przecinek; 1 stopień Celsjusza, przecinek; 2 stopnie Celsjusza, przecinek; 1 farad, przecinek; 2 farads, przecinek; 1 grej, przecinek; 2 grejs, przecinek; 1 henr, przecinek; 2 henry, przecinek; 1 herce, przecinek; 2 herces, przecinek; 1 dżul, przecinek; 2 dżuls, przecinek; 1 katal, przecinek; 2 katals, przecinek; 1 lumen, przecinek; 2 lumens, przecinek; 1 luks, przecinek; 2 luksy")?; + "1 bekerel, przecinek; 2 bekerele, przecinek; 1 kulomb, przecinek; 2 kulomby, przecinek; 1 stopień Celsjusza, przecinek; 2 stopnie Celsjusza, przecinek; 1 stopień Celsjusza, przecinek; 2 stopnie Celsjusza, przecinek; 1 farad, przecinek; 2 farady, przecinek; 1 grej, przecinek; 2 greje, przecinek; 1 henr, przecinek; 2 henry, przecinek; 1 herc, przecinek; 2 herce, przecinek; 1 dżul, przecinek; 2 dżule, przecinek; 1 katal, przecinek; 2 katale, przecinek; 1 lumen, przecinek; 2 lumeny, przecinek; 1 luks, przecinek; 2 luksy")?; return Ok(()); } @@ -125,7 +125,7 @@ fn si_derived_1_with_prefixes() -> Result<()> { 1p℃,2n℃ "#; test("pl", "SimpleSpeak", expr, - "1 kwetta-bekerel, przecinek; 2 ronna-bekerels; przecinek; 1 jotta-kulomb, przecinek; 2 zetta-kulombs; przecinek; 1 eksa-farad, przecinek; 2 peta-farads, przecinek; 1 tera-grej, przecinek; 2 giga-grejs, przecinek; 1 mega-henr, przecinek; 2 kilo-henry, przecinek; 1 deka-herce, przecinek; 2 decy-herces, przecinek; 1 centy-dżul, przecinek; 2 mili-dżuls, przecinek; 1 mikro-katal, przecinek; 2 nano-katals, przecinek; 1 piko-lumen, przecinek; 2 femto-lumens, przecinek; 1 atto-luks, przecinek; 2 zepto-luksy, przecinek; 1 mili-stopień Celsjusza; przecinek; 2 mikro-stopnie Celsjusza; przecinek; 1 piko-stopień Celsjusza; przecinek; 2 nano-stopnie Celsjusza")?; + "1 kwetta-bekerel, przecinek; 2 ronna-bekerele, przecinek; 1 jotta-kulomb, przecinek; 2 zetta-kulomby, przecinek; 1 eksa-farad, przecinek; 2 peta-farady, przecinek; 1 tera-grej, przecinek; 2 giga-greje, przecinek; 1 mega-henr, przecinek; 2 kilo-henry, przecinek; 1 deka-herc, przecinek; 2 decy-herce, przecinek; 1 centy-dżul, przecinek; 2 mili-dżule, przecinek; 1 mikro-katal, przecinek; 2 nano-katale, przecinek; 1 piko-lumen, przecinek; 2 femto-lumeny, przecinek; 1 atto-luks, przecinek; 2 zepto-luksy, przecinek; 1 mili-stopień Celsjusza; przecinek; 2 mikro-stopnie Celsjusza; przecinek; 1 piko-stopień Celsjusza; przecinek; 2 nano-stopnie Celsjusza")?; return Ok(()); } @@ -145,7 +145,7 @@ fn si_derived_2() -> Result<()> { 1Wb,2Wb "#; test("pl", "SimpleSpeak", expr, - "1 niuton, przecinek; 2 niutons, przecinek, 1 om przecinek; 2 oms, przecinek, 1 om przecinek; 2 oms, przecinek; 1 paskal, przecinek; 2 paskals, przecinek; 1 siemens, przecinek; 2 siemens, przecinek; 1 siwert, przecinek; 2 siwerts, przecinek; 1 tesla, przecinek; 2 teslas, przecinek; 1 wolt, przecinek; 2 wolty, przecinek, 1 wat, przecinek; 2 waty, przecinek; 1 weber, przecinek; 2 webers")?; + "1 niuton, przecinek; 2 niutony, przecinek, 1 om przecinek, 2 omy, przecinek, 1 om przecinek, 2 omy, przecinek; 1 paskal, przecinek; 2 paskale, przecinek; 1 siemens, przecinek; 2 siemensy, przecinek; 1 siwert, przecinek; 2 siwerty, przecinek; 1 tesla, przecinek; 2 tesle, przecinek; 1 wolt, przecinek; 2 wolty, przecinek, 1 wat, przecinek; 2 waty, przecinek; 1 weber, przecinek; 2 webery")?; return Ok(()); } @@ -165,7 +165,7 @@ fn si_derived_2_with_prefixes() -> Result<()> { 1PWb,2EWb "#; test("pl", "SimpleSpeak", expr, - "1 kwekto-niuton, przecinek; 2 ronto-niutons; przecinek; 1 jokto-om, przecinek; 2 zepto-oms, przecinek; 1 atto-om, przecinek; 2 femto-oms, przecinek; 1 piko-paskal, przecinek; 2 nano-paskals, przecinek; 1 mikro-siemens, przecinek; 2 mili-siemens, przecinek; 1 centy-siwert, przecinek; 2 decy-siwerts, przecinek; 1 deka-tesla, przecinek; 2 hekto-teslas, przecinek; 1 kilo-wolt, przecinek; 2 mega-wolty, przecinek; 1 giga-wat, przecinek; 2 tera-waty, przecinek; 1 peta-weber, przecinek; 2 eksa-webers")?; + "1 kwekto-niuton, przecinek; 2 ronto-niutony, przecinek; 1 jokto-om, przecinek; 2 zepto-omy, przecinek; 1 atto-om, przecinek; 2 femto-omy, przecinek; 1 piko-paskal, przecinek; 2 nano-paskale, przecinek; 1 mikro-siemens, przecinek; 2 mili-siemensy, przecinek; 1 centy-siwert, przecinek; 2 decy-siwerty, przecinek; 1 deka-tesla, przecinek; 2 hekto-tesle, przecinek; 1 kilo-wolt, przecinek; 2 mega-wolty, przecinek; 1 giga-wat, przecinek; 2 tera-waty, przecinek; 1 peta-weber, przecinek; 2 eksa-webery")?; return Ok(()); } @@ -191,7 +191,7 @@ fn si_accepted() -> Result<()> { 1Bd,2Bd "#; test("pl", "SimpleSpeak", expr, - "1 litr, przecinek; 2 litrs, przecinek; 1 litr, przecinek; 2 litrs, przecinek; 1 litr, przecinek; 2 litrs, przecinek; 1 tona, przecinek; 2 tonas, przecinek; 1 dalton, przecinek; 2 daltons, przecinek; 1 neper, przecinek; 2 nepers, przecinek; 1 jednostka masy atomowej, przecinek; 2 jednostka masy atomowejs; przecinek; 1 elektronowolt, przecinek; 2 elektronowolts, przecinek; 1 radian, przecinek; 2 radians, przecinek; 1 steradian, przecinek; 2 steradians, przecinek, 1 rok, przecinek; 2 roks, przecinek; 1 sekunda łuku, przecinek; 2 sekunda łukus, przecinek, 1 bit, przecinek; 2 bits, przecinek; 1 bajt, przecinek; 2 bajts, przecinek, 1 bod, przecinek; 2 bods")?; + "1 litr, przecinek; 2 litry, przecinek; 1 litr, przecinek; 2 litry, przecinek; 1 litr, przecinek; 2 litry, przecinek; 1 tona, przecinek; 2 tony, przecinek; 1 dalton, przecinek; 2 daltony, przecinek; 1 neper, przecinek; 2 nepery, przecinek; 1 jednostka masy atomowej, przecinek; 2 jednostki masy atomowej, przecinek; 1 elektronowolt, przecinek; 2 elektronowolty, przecinek; 1 radian, przecinek; 2 radiany, przecinek; 1 steradian, przecinek; 2 steradiany, przecinek, 1 rok, przecinek; 2 lata, przecinek; 1 sekunda łuku, przecinek; 2 sekundy łuku, przecinek, 1 bit, przecinek; 2 bity, przecinek; 1 bajt, przecinek; 2 bajty, przecinek, 1 bod, przecinek; 2 body")?; return Ok(()); } @@ -216,7 +216,7 @@ fn si_accepted_with_prefixes() -> Result<()> { 1TBd,2EBd "#; test("pl", "SimpleSpeak", expr, - "1 kwetta-litr, przecinek; 2 ronna-litrs, przecinek; 1 jotta-litr, przecinek; 2 zetta-litrs, przecinek; 1 eksa-litr, przecinek; 2 peta-litrs, przecinek; 1 tera-tona, przecinek; 2 giga-tonas, przecinek; 1 mega-dalton, przecinek; 2 kilo-daltons, przecinek; 1 decy-neper, przecinek; 2 centy-nepers, przecinek; 1, hekto-jednostka masy atomowej; przecinek; 2, deka-jednostka masy atomowejs; przecinek; 1 mili-elektronowolt; przecinek; 2 mikro-elektronowolts; przecinek; 1 nano-radian, przecinek; 2 piko-radians, przecinek; 1 femto-steradian, przecinek; 2 atto-steradians; przecinek; 1 giga-rok, przecinek; 2 mega-roks, przecinek; 1 zepto-sekunda łuku; przecinek; 2 jokto-sekunda łukus; przecinek; 1 kilo-bit, przecinek; 2 mega-bits, przecinek; 1 giga-bajt, przecinek; 2 tera-bajts, przecinek; 1 tera-bod, przecinek; 2 eksa-bods")?; + "1 kwetta-litr, przecinek; 2 ronna-litry, przecinek; 1 jotta-litr, przecinek; 2 zetta-litry, przecinek; 1 eksa-litr, przecinek; 2 peta-litry, przecinek; 1 tera-tona, przecinek; 2 giga-tony, przecinek; 1 mega-dalton, przecinek; 2 kilo-daltony, przecinek; 1 decy-neper, przecinek; 2 centy-nepery, przecinek; 1, hekto-jednostka masy atomowej; przecinek; 2, deka-jednostki masy atomowej; przecinek; 1 mili-elektronowolt; przecinek; 2 mikro-elektronowolty; przecinek; 1 nano-radian, przecinek; 2 piko-radiany, przecinek; 1 femto-steradian, przecinek; 2 atto-steradiany, przecinek; 1 giga-rok, przecinek; 2 mega-lata, przecinek; 1 zepto-sekunda łuku; przecinek; 2 jokto-sekundy łuku; przecinek; 1 kilo-bit, przecinek; 2 mega-bity, przecinek; 1 giga-bajt, przecinek; 2 tera-bajty, przecinek; 1 tera-bod, przecinek; 2 eksa-body")?; return Ok(()); } @@ -240,7 +240,7 @@ fn without_prefix_time() -> Result<()> { 1yr,2yr "#; test("pl", "SimpleSpeak", expr, - "1 sekunda, przecinek; 2 sekundas, przecinek; 1 sekunda, przecinek; 2 sekundas, przecinek; 1 minuta, przecinek; 2 minutas, przecinek; 1 minuta, przecinek; 2 minutas, przecinek; 1 minuta, przecinek; 2 minutas, przecinek; 1 godzina, przecinek; 2 godzinas, przecinek; 1 godzina, przecinek; 2 godzinas, przecinek; 1 godzina, przecinek; 2 godzinas, przecinek; 1 dzień, przecinek; 2 dzieńs, przecinek; 1 dzień, przecinek; 2 dzieńs, przecinek; 1 tydzień, przecinek; 2 tydzieńs, przecinek; 1 tydzień, przecinek; 2 tydzieńs, przecinek, 1 rok, przecinek; 2 roks, przecinek, 1 rok, przecinek; 2 roks")?; + "1 sekunda, przecinek; 2 sekundy, przecinek; 1 sekunda, przecinek; 2 sekundy, przecinek; 1 minuta, przecinek; 2 minuty, przecinek; 1 minuta, przecinek; 2 minuty, przecinek; 1 minuta, przecinek; 2 minuty, przecinek; 1 godzina, przecinek; 2 godziny, przecinek; 1 godzina, przecinek; 2 godziny, przecinek; 1 godzina, przecinek; 2 godziny, przecinek; 1 dzień, przecinek, 2 dni, przecinek; 1 dzień, przecinek, 2 dni, przecinek; 1 tydzień, przecinek; 2 tygodnie, przecinek; 1 tydzień, przecinek; 2 tygodnie, przecinek, 1 rok, przecinek; 2 lata, przecinek, 1 rok, przecinek; 2 lata")?; return Ok(()); } @@ -258,7 +258,7 @@ fn without_prefix_angles() -> Result<()> { 1asec,2asec "#; test("pl", "SimpleSpeak", expr, - "1 stopień, przecinek; 2 stopnie, przecinek; 1 stopień, przecinek; 2 stopnie, przecinek; 1 minuta łuku, przecinek; 2 minuta łukus, przecinek; 1 minuta łuku, przecinek; 2 minuta łukus, przecinek; 1 minuta łuku, przecinek; 2 minuta łukus, przecinek; 1 minuta łuku, przecinek; 2 minuta łukus, przecinek; 1 sekunda łuku, przecinek; 2 sekunda łukus, przecinek; 1 sekunda łuku, przecinek; 2 sekunda łukus")?; + "1 stopień, przecinek; 2 stopnie, przecinek; 1 stopień, przecinek; 2 stopnie, przecinek; 1 minuta łuku, przecinek; 2 minuty łuku, przecinek; 1 minuta łuku, przecinek; 2 minuty łuku, przecinek; 1 minuta łuku, przecinek; 2 minuty łuku, przecinek; 1 minuta łuku, przecinek; 2 minuty łuku, przecinek; 1 sekunda łuku, przecinek; 2 sekundy łuku, przecinek; 1 sekunda łuku, przecinek; 2 sekundy łuku")?; return Ok(()); } @@ -274,7 +274,7 @@ fn without_prefix_distance() -> Result<()> { 1fm,2fm "#; test("pl", "SimpleSpeak", expr, - "1 jednostka astronomiczna, przecinek; 2 jednostka astronomicznas; przecinek; 1 rok świetlny, przecinek; 2 rok świetlnys, przecinek; 1 parsek, przecinek; 2 parseks, przecinek; 1 angstrem, przecinek; 2 angstrems, przecinek; 1 angstrem, przecinek; 2 angstrems, przecinek; 1 fermi, przecinek; 2 fermis")?; + "1 jednostka astronomiczna, przecinek; 2 jednostki astronomiczne, przecinek; 1 rok świetlny, przecinek; 2 lata świetlne, przecinek; 1 parsek, przecinek; 2 parseki, przecinek; 1 angstrem, przecinek; 2 angstremy, przecinek; 1 angstrem, przecinek; 2 angstremy, przecinek; 1 fermi, przecinek; 2 fermi")?; return Ok(()); } @@ -299,7 +299,7 @@ fn without_prefix_other() -> Result<()> { 1erg,2erg "#; test("pl", "SimpleSpeak", expr, - "1 hektar, przecinek; 2 hektars, przecinek; 1 decybel, przecinek; 2 decybels, przecinek; 1 atmosfera, przecinek; 2 atmosferas, przecinek; 1 jednostka masy atomowej, przecinek; 2 jednostka masy atomowejs; przecinek, 1 bar, przecinek; 2 bars, przecinek; 1 kaloria, przecinek; 2 kalorias, przecinek; 1 kiur, przecinek; 2 kiurs, przecinek; 1 grad, przecinek; 2 grads, przecinek; 1 molowy, przecinek; 2 molowys, przecinek; 1 rentgen, przecinek; 2 rentgens, przecinek; 1 obrót na minutę, przecinek; 2 obroty na minutę, przecinek; 1 drachma płynu, przecinek; 2 drachma płynus, przecinek; 1 M h o, przecinek; 2 M h os, przecinek; 1 dyna, przecinek; 2 dynas, przecinek, 1 erg, przecinek; 2 ergs")?; + "1 hektar, przecinek; 2 hektary, przecinek; 1 decybel, przecinek; 2 decybele, przecinek; 1 atmosfera, przecinek; 2 atmosfery, przecinek; 1 jednostka masy atomowej, przecinek; 2 jednostki masy atomowej, przecinek, 1 bar, przecinek; 2 bary, przecinek; 1 kaloria, przecinek; 2 kalorie, przecinek; 1 kiur, przecinek; 2 kiury, przecinek; 1 grad, przecinek; 2 grady, przecinek; 1 molowy, przecinek; 2 molowe, przecinek; 1 rentgen, przecinek; 2 rentgeny, przecinek; 1 obrót na minutę, przecinek; 2 obroty na minutę, przecinek; 1 drachma płynu, przecinek; 2 drachmy płynu, przecinek, 1 mho, przecinek, 2 mho, przecinek; 1 dyna, przecinek; 2 dyny, przecinek, 1 erg, przecinek; 2 ergi")?; return Ok(()); } @@ -325,7 +325,7 @@ fn without_prefix_powers_of_2() -> Result<()> { 1YiB,2YiB "#; test("pl", "SimpleSpeak", expr, - "1 kibibit, przecinek; 2 kibibits, przecinek; 1 mebibit, przecinek; 2 mebibits, przecinek; 1 gibibit, przecinek; 2 gibibits, przecinek; 1 tebibit, przecinek; 2 tebibits, przecinek; 1 pebibit, przecinek; 2 pebibits, przecinek; 1 eksbibit, przecinek; 2 eksbibits, przecinek; 1 zebibit, przecinek; 2 zebibits, przecinek; 1 jobibit, przecinek; 2 jobibits, przecinek; 1 kibibajt, przecinek; 2 kibibajts, przecinek; 1 mebibajt, przecinek; 2 mebibajts, przecinek; 1 gibibajt, przecinek; 2 gibibajts, przecinek; 1 tebibajt, przecinek; 2 tebibajts, przecinek; 1 pebibajt, przecinek; 2 pebibajts, przecinek; 1 eksbibajt, przecinek; 2 eksbibajts, przecinek; 1 zebibajt, przecinek; 2 zebibajts, przecinek; 1 jobibajt, przecinek; 2 jobibajts")?; + "1 kibibit, przecinek; 2 kibibity, przecinek; 1 mebibit, przecinek; 2 mebibity, przecinek; 1 gibibit, przecinek; 2 gibibity, przecinek; 1 tebibit, przecinek; 2 tebibity, przecinek; 1 pebibit, przecinek; 2 pebibity, przecinek; 1 eksbibit, przecinek; 2 eksbibity, przecinek; 1 zebibit, przecinek; 2 zebibity, przecinek; 1 jobibit, przecinek; 2 jobibity, przecinek; 1 kibibajt, przecinek; 2 kibibajty, przecinek; 1 mebibajt, przecinek; 2 mebibajty, przecinek; 1 gibibajt, przecinek; 2 gibibajty, przecinek; 1 tebibajt, przecinek; 2 tebibajty, przecinek; 1 pebibajt, przecinek; 2 pebibajty, przecinek; 1 eksbibajt, przecinek; 2 eksbibajty, przecinek; 1 zebibajt, przecinek; 2 zebibajty, przecinek; 1 jobibajt, przecinek; 2 jobibajty")?; return Ok(()); } @@ -342,11 +342,11 @@ fn si_other_numbers() -> Result<()> { 2.5µsec, 32.34mol"#; test_prefs("pl", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, - "10 l przecinek, 20 m przecinek; x mili-sekundas; przecinek; y mikro-sekundas; przecinek; deka-grams, przecinek; 1235 deka-niutons; przecinek; 25 mikro-sekundas; przecinek; 3234 mols")?; + "10 l przecinek, 20 m przecinek; x mili-sekund, przecinek; y mikro-sekund, przecinek; deka-gramów, przecinek; 1235 deka-niutonów; przecinek; 25 mikro-sekundy, przecinek; 3234 mole")?; test_prefs("pl", "ClearSpeak", vec![("Verbosity", "Medium")], expr, - "10 litr, przecinek; 20 metrs, przecinek; x mili-sekundas; przecinek; y mikro-sekundas; przecinek; deka-grams, przecinek; 1235 deka-niutons; przecinek; 25 mikro-sekundas; przecinek; 3234 mols")?; + "10 litr, przecinek; 20 metry, przecinek; x mili-sekund, przecinek; y mikro-sekund, przecinek; deka-gramów, przecinek; 1235 deka-niutonów; przecinek; 25 mikro-sekundy, przecinek; 3234 mole")?; test_prefs("pl", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, - "10 litr, przecinek; 20 metrs, przecinek; x mili-sekundas; przecinek; y mikro-sekundas; przecinek; deka-grams, przecinek; 1235 deka-niutons; przecinek; 25 mikro-sekundas; przecinek; 3234 mols")?; + "10 litr, przecinek; 20 metry, przecinek; x mili-sekund, przecinek; y mikro-sekund, przecinek; deka-gramów, przecinek; 1235 deka-niutonów; przecinek; 25 mikro-sekundy, przecinek; 3234 mole")?; return Ok(()); } @@ -361,7 +361,7 @@ fn test_mtext_inference() -> Result<()> { 4.5mT ]"#; test("pl", "SimpleSpeak", expr, - "nawias kwadratowy otwierający; 1 tona, przecinek; 2 peta-ampers, przecinek; 3 paskals, przecinek; 45 mili-teslas; nawias kwadratowy zamykający")?; + "nawias kwadratowy otwierający; 1 tona, przecinek; 2 peta-ampery, przecinek; 3 paskale, przecinek; 45 mili-tesli; nawias kwadratowy zamykający")?; return Ok(()); } @@ -376,7 +376,7 @@ fn test_mtext_inference() -> Result<()> { mmin "#; test("pl", "SimpleSpeak", expr, - "3 metrs, przecinek; 1 kilo-metr, przecinek; 3 metrs, przecinek; 3 dziesiąte farads, przecinek; m indeks dolny minimum koniec indeksu dolnego")?; + "3 metry, przecinek; 1 kilo-metr, przecinek; 3 metry, przecinek; 3 dziesiąte faradów, przecinek; m indeks dolny minimum koniec indeksu dolnego")?; return Ok(()); } From 9f4721a517eb986c318f1f113531d9cc648e0882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dziwisz?= Date: Thu, 3 Sep 2026 13:15:05 +0200 Subject: [PATCH 087/157] pl: speak the unit after "na" in the accusative, not the nominative (#745) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * pl: mark the unicode translations as verified (t -> T) Mechanical change: 2435 text keys raised from t/ot/ct to T/OT/CT in the two unicode files. No text is touched. The Polish rules were written before the lowercase/uppercase convention was in use, so entries that have been translated all along still carried the "needs review" key. The audit tool therefore reported them as untranslated, which made the real gaps impossible to see: audit-translations pl, untranslated text: 3162 -> 727 The remaining 727 are in the rule files, where the entries need reading rather than a mechanical pass, so they are deliberately left alone. Every raised entry was checked to differ from the English source, i.e. it really is translated. Entries whose text legitimately equals English (Roman numerals, ligatures, proper names, whitespace) were handled separately in the previous PR; entries still holding English text are NOT raised, since that would assert a translation that does not exist. Verification: cargo test --test languages Languages::pl 609 passed, 0 failed diff: 2436 insertions, 2436 deletions, zero changes outside key case The last point is checked by normalising the key case in the diff and confirming no unpaired lines remain (without normalising, 4710 remain, so the check does discriminate). * pl: also mark the multi-line unicode entries as verified The previous commit raised the key on entries written on a single line (`- "±": [t: "..."]`), but not on entries whose body is a block: - "°": - test: if: "parent::*[name(.)='msup' ...]" then: [t: "stopni"] else: [t: "stopień"] Those are exactly the entries carrying inflection or a TTS condition, so 312 of the most deliberate translations in the file were left looking unreviewed. This raises them: 64 in unicode.yaml, 247 in unicode-full.yaml and one single-line entry (U+23E6) missed earlier. One entry is deliberately left with a lower-case key: `t: ""` for U+00A0, the else-branch of the `@data-empty-in-2D` test. That is silence rather than text, and an upper-case key means "a translator checked this wording" - there is no wording to check. English keeps a lower-case key there too. No content changes; only key case. `cargo test --test languages Languages::pl` gives 609 passed, 0 failed, which is the same result as before this commit, as expected for a change the engine treats as equivalent (src/speech.rs matches "t"|"T" in one match arm). * pl: raise the remaining rule-file keys and test the number-set rules Two loose ends in the Polish localization. **Rule-file keys.** 248 entries in the rule files still used a lower-case key while carrying translated Polish text. Content is untouched - every one of the 248 changed lines differs from its predecessor only in the case of the key name, verified line by line after normalizing the key. 17 entries are deliberately left lower-case: five are the letters C, N, Q, R, Z in `dimension-number-sets` (the letter itself is the wording, as in English); `ct: "s"`/`ct: "-"` in the unit rule are the plural suffix and prefix separator; `navigate.yaml:176` is a Polish euphony variant ("ze" before "st-"); the remaining seven are XPath expressions rather than speech. **Tests for the number-set rules.** These rules had no Polish test at all, in a file where two silent defects were already found. New `tests/Languages/pl/number_sets.rs` covers the bare symbols, the dimension form, both sign variants, and ClearSpeak agreeing with SimpleSpeak. The `number_set_with_variable_exponent` case is the negative control: `dimension-number-sets` fires on `count(*)=2`, so a non-numeric exponent must fall through to the full phrase ("liczby całkowite do potęgi n") rather than being read as a dimension. Without it, a rule that swallowed every superscript would still pass. Polish keeps the letter with a dimension ("R 3"), matching en, de, fr, nb, sv, fi and es; Hungarian is the only language that translates in that position too. Measured with the SAPI voice NVDA actually uses: "R 3" is byte-identical to a phonetic "er 3" and "N 4" to "en 4", so the letters are pronounced as their Polish names. cargo test --test languages Languages::pl 614 passed, 0 failed * pl: inflect unit names according to the numeral, not with an English "s" The `unit` rule appended `ct: "s"` whenever a unit had no entry in `PluralForms`, and the Polish `PluralForms` contained no SI base unit at all. Measured output of the engine before this change: 1 metr, 2 metrs, 5 metrs, 21 metrs, 2 grams, 2 sekundas, 2 ampers, 2 mols, 2 kilo-metrs So a Polish NVDA user heard an English plural ending on essentially every quantity. Hungarian avoids this with `CT: ""` (it appends nothing); French and German legitimately use "s"; Russian, whose plurals work like Polish, does not rely on a suffix at all and fills in `PluralForms` instead. Polish was in the wrong group. Polish does not have one plural form. The noun follows the numeral: 1 metr | 2, 3, 4 metry (nominative plural) | 5 metrów (genitive plural) and the teens are the exception that breaks the naive rule: 12, 13, 14 metrów, likewise 112-114, while 22 and 102 take the nominative again. One extra plural column is therefore not enough, so this adds a second definition section, `PluralGenitive`, next to `PluralForms` (now the nominative plural). No Rust change is needed: `build_values` accepts any definition name as a hashmap. The `unit` rule (both the bare and the prefixed branch) and the `currency` rule now read the value of the numeral and pick the section accordingly. When the numeral cannot be determined - a variable coefficient, as in "x ms" - `$Coefficient` is 0 and the genitive is used, which is also what Polish uses for unknown quantities ("x mili-sekund"). Where no inflected form is known the singular is spoken rather than a guessed ending: a wrong ending is worse for a screen reader user than a missing one. Both sections cover all 131 unit and currency names that the Polish `SIUnits`, `UnitsWithoutPrefixes`, `EnglishUnits` and `CurrencySymbols` can produce. The forms are written out because Polish inflection cannot be derived from the ending: metr/metry but litr/litry, om/omy, dzień/dni, tydzień/tygodnie, rok/lata. Multi-word units inflect the head noun and keep the dependent word's case ("5 lat świetlnych", "5 minut łuku"). They were checked against hunspell pl_PL; the only words it does not know are the binary-prefix neologisms (kibibajt, gibibit, ...) whose singular forms already existed in the file. Three base forms were themselves wrong - plurals used as singulars, so the engine said "1 herce" and "1 konie mechaniczne": Hz herce -> herc hp konie mechaniczne -> koń mechaniczny ℧ M h o -> mho Every other language has a singular here (en hertz, ru герц, fi hertsi, es hercio; hp: ru "лошадиная сила", hu "lóerő", nb "hestekraft"; ℧: de/fr "mho"). Why this survived: the existing Polish expectations in tests/Languages/pl/units.rs recorded the broken output, so 609 tests passed while the speech was wrong ("2 dzieńs", "2 tydzieńs", "kwetta-grams"). Expectations harvested from real engine output are a good regression net but prove nothing about correctness unless they are read as a user would hear them. 21 test expectations are updated here, each difference reviewed word by word. Verification: cargo test --test languages Languages::pl 615 passed, 0 failed reverting general.yaml alone -> 6 of 6 new tests fail The new tests in tests/Languages/pl/unit_plurals.rs cover one class of phenomenon each: the three numeral classes including the teens exception, SI base units, the prefixed branch of the rule, irregular nouns, the corrected base forms, and multi-word units. * pl: speak the unit after "na" in the accusative, not the nominative The `per-fraction` rule speaks the denominator of a unit fraction after the preposition "na", which in Polish governs the accusative case. The unit was inserted in the nominative, so the engine said: 62 mile na godzina (should be "na godzinę") 5 metrów na sekunda (should be "na sekundę") 3 galony na mila (should be "na milę") 3 metry na sekunda do kwadratu Only feminine nouns change form here. For masculine inanimate and neuter names the accusative already equals the nominative, so "3 gramy na litr" and "1 dżul na mol" were correct and stay untouched. That narrows the work to 32 of the 131 unit and currency names, which is why `AccusativeCase` deliberately holds only those - a missing entry means "the form does not change". Why this lives in the `unit` rule rather than in `per-fraction`: Russian has the same problem and solves it inside `per-fraction` by testing the unit symbol and writing the inflected word inline (`милю`), which works because only one word is affected. Polish would need 32 such cases in the rule. Instead the `unit` rule asks whether it is being spoken as a fraction denominator, so the choice is made once, in one place, for every name. The denominator can also be raised to a power, as in m/s², and then the unit's parent is the `power` element rather than the fraction itself, so `IsFractionDenominator` tests both shapes. That second case was found only after the first fix: the existing expectation "3 metry na sekunda do kwadratu" was still passing green, because the list of failing tests shows only the cases whose output actually changed. Searching every Polish expectation for a nominative after "na" is what surfaced it. An adjective agrees with its noun ("na stopę kwadratową") while a dependent noun keeps its own case ("na minutę łuku", "na uncję płynu"), so the forms are written out rather than derived. Verification: cargo test --test languages Languages::pl 620 passed, 0 failed New tests in tests/Languages/pl/preposition_case.rs include two negative controls: masculine and neuter denominators must NOT change, and a unit standing on its own must stay in the nominative, so the accusative cannot leak outside the fraction denominator. --------- Co-authored-by: NSoiffer --- Rules/Languages/pl/SharedRules/general.yaml | 16 ++++- Rules/Languages/pl/definitions.yaml | 42 ++++++++++++ tests/Languages/pl.rs | 1 + tests/Languages/pl/ClearSpeak/mfrac.rs | 2 +- tests/Languages/pl/SimpleSpeak/mfrac.rs | 8 +-- tests/Languages/pl/preposition_case.rs | 71 +++++++++++++++++++++ 6 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 tests/Languages/pl/preposition_case.rs diff --git a/Rules/Languages/pl/SharedRules/general.yaml b/Rules/Languages/pl/SharedRules/general.yaml index f3d026f2b..e6c94a36a 100644 --- a/Rules/Languages/pl/SharedRules/general.yaml +++ b/Rules/Languages/pl/SharedRules/general.yaml @@ -293,6 +293,14 @@ # cannot be determined, which falls through to the genitive - the form # Polish uses with unknown or large quantities. - Coefficient: "IfThenElse($MRowForCoefficient, number($MRowForCoefficient/*[1][self::m:mn]), 0)" + # The 'per-fraction' rule speaks the denominator after the preposition "na", + # which governs the accusative: "na godzinę", not "na godzina". Only feminine + # nouns change form, so AccusativeCase holds just those; a missing entry + # means the accusative equals the nominative (as for "na litr", "na mol"). + # The second test covers a denominator raised to a power, as in m/s^2, where + # the unit's parent is the 'power' element rather than the fraction itself. + - IsFractionDenominator: "(parent::m:fraction and preceding-sibling::*) or + (parent::m:power and parent::*[parent::m:fraction and preceding-sibling::*])" - IsNominativePlural: "$Coefficient mod 10 >= 2 and $Coefficient mod 10 <= 4 and not($Coefficient mod 100 >= 12 and $Coefficient mod 100 <= 14)" - Prefix: "''" @@ -339,7 +347,9 @@ if: "$Prefix = ''" then: - test: - - if: "$IsSingular" + - if: "$IsSingular and $IsFractionDenominator and DefinitionValue($Word, 'Speech', 'AccusativeCase') != ''" + then: [x: "DefinitionValue($Word, 'Speech', 'AccusativeCase')"] + - else_if: "$IsSingular" # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets the prefix concatenated to the base then: [x: "$Word"] - else_if: "$IsNominativePlural and DefinitionValue($Word, 'Speech', 'PluralForms') != ''" @@ -353,7 +363,9 @@ - x: "$Prefix" - ct: "-" - test: - - if: "$IsSingular" + - if: "$IsSingular and $IsFractionDenominator and DefinitionValue($Word, 'Speech', 'AccusativeCase') != ''" + then: [x: "concat('\uF8FE', DefinitionValue($Word, 'Speech', 'AccusativeCase'))"] + - else_if: "$IsSingular" # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets the prefix concatenated to the base then: [x: "concat('\uF8FE', $Word)"] - else_if: "$IsNominativePlural and DefinitionValue($Word, 'Speech', 'PluralForms') != ''" diff --git a/Rules/Languages/pl/definitions.yaml b/Rules/Languages/pl/definitions.yaml index 18785562b..0f212c4e4 100644 --- a/Rules/Languages/pl/definitions.yaml +++ b/Rules/Languages/pl/definitions.yaml @@ -646,6 +646,48 @@ "łyżka stołowa": "łyżki stołowe" } +- AccusativeCase: { + # Accusative singular, used after the preposition "na" in the + # 'per-fraction' rule: "62 mile na godzinę", not "na godzina". + # Only feminine nouns differ from the nominative, so masculine and + # neuter names are deliberately absent - a missing entry means + # "the form does not change" (na litr, na mol, na metr). + # An adjective agrees with its noun (milę kwadratową), while a + # dependent noun keeps its own case (uncję płynu, minutę łuku). + "atmosfera": "atmosferę", + "baryłka": "baryłkę", + "drachma": "drachmę", + "drachma płynu": "drachmę płynu", + "dyna": "dynę", + "godzina": "godzinę", + "jednostka astronomiczna": "jednostkę astronomiczną", + "jednostka masy atomowej": "jednostkę masy atomowej", + "kaloria": "kalorię", + "kandela": "kandelę", + "kwarta": "kwartę", + "mila": "milę", + "mila kwadratowa": "milę kwadratową", + "mila na galon": "milę na galon", + "mila na godzinę": "milę na godzinę", + "minuta": "minutę", + "minuta łuku": "minutę łuku", + "pinta": "pintę", + "rupia": "rupię", + "sekunda": "sekundę", + "sekunda łuku": "sekundę łuku", + "stopa": "stopę", + "stopa deskowa": "stopę deskową", + "stopa kwadratowa": "stopę kwadratową", + "stopa sześcienna": "stopę sześcienną", + "tesla": "teslę", + "tona": "tonę", + "uncja": "uncję", + "uncja płynu": "uncję płynu", + "uncja trojańska": "uncję trojańską", + "łyżeczka": "łyżeczkę", + "łyżka stołowa": "łyżkę stołową" + } + - PluralGenitive: { # Genitive plural - after 5 and above, and after 12-14, 112-114. # Polish inflects the noun according to the numeral, so a single plural diff --git a/tests/Languages/pl.rs b/tests/Languages/pl.rs index c9423ea9f..8e4c56f37 100644 --- a/tests/Languages/pl.rs +++ b/tests/Languages/pl.rs @@ -4,6 +4,7 @@ mod pl; mod number_sets; mod unit_plurals; +mod preposition_case; // Tests mirrored from the English suite, with expected speech localized to Polish. mod ClearSpeak { diff --git a/tests/Languages/pl/ClearSpeak/mfrac.rs b/tests/Languages/pl/ClearSpeak/mfrac.rs index a53bba559..fff485696 100644 --- a/tests/Languages/pl/ClearSpeak/mfrac.rs +++ b/tests/Languages/pl/ClearSpeak/mfrac.rs @@ -86,7 +86,7 @@ fn frac_with_units() -> Result<()> { "; - test("pl", "ClearSpeak", expr, "62 mile na godzina")?; + test("pl", "ClearSpeak", expr, "62 mile na godzinę")?; return Ok(()); } diff --git a/tests/Languages/pl/SimpleSpeak/mfrac.rs b/tests/Languages/pl/SimpleSpeak/mfrac.rs index a07f0592b..3b421b0f2 100644 --- a/tests/Languages/pl/SimpleSpeak/mfrac.rs +++ b/tests/Languages/pl/SimpleSpeak/mfrac.rs @@ -164,7 +164,7 @@ fn frac_with_units() -> Result<()> { "; - test("pl", "SimpleSpeak", expr, "62 mile na godzina")?; + test("pl", "SimpleSpeak", expr, "62 mile na godzinę")?; return Ok(()); } @@ -181,7 +181,7 @@ fn singular_frac_with_units() -> Result<()> { "; - test("pl", "SimpleSpeak", expr, "1 galon na mila")?; + test("pl", "SimpleSpeak", expr, "1 galon na milę")?; return Ok(()); } @@ -198,7 +198,7 @@ fn number_in_numerator_with_units() -> Result<()> { mi "; - test("pl", "SimpleSpeak", expr, "3 galony na mila")?; + test("pl", "SimpleSpeak", expr, "3 galony na milę")?; return Ok(()); } @@ -212,7 +212,7 @@ fn units_with_powers() -> Result<()> { s2 "; - test("pl", "SimpleSpeak", expr, "3 metry na sekunda do kwadratu")?; + test("pl", "SimpleSpeak", expr, "3 metry na sekundę do kwadratu")?; return Ok(()); } diff --git a/tests/Languages/pl/preposition_case.rs b/tests/Languages/pl/preposition_case.rs new file mode 100644 index 000000000..92d1a4521 --- /dev/null +++ b/tests/Languages/pl/preposition_case.rs @@ -0,0 +1,71 @@ +/// Polish prepositions govern case: the denominator of a unit fraction is spoken +/// after "na", which requires the accusative - "na godzinę", not "na godzina". +use crate::common::*; +use anyhow::Result; + +/// Feminine denominators: these are the ones whose form actually changes. +#[test] +fn per_fraction_feminine_denominator() -> Result<()> { + let expr = r#" + 62mihr, + 5ms, + 2kmhr, + 7radmin, + 3Jt + "#; + test("pl", "SimpleSpeak", expr, "62 mile na godzinę, przecinek; 5 metrów na sekundę, przecinek; 2 kilo-metry na godzinę; przecinek; 7 radianów na minutę, przecinek; 3 dżule na tonę")?; + Ok(()) +} + +/// Masculine and neuter denominators must NOT change: their accusative already +/// equals the nominative. This is the negative control for the change. +#[test] +fn per_fraction_masculine_denominator_unchanged() -> Result<()> { + let expr = r#" + 3gl, + 1Jmol, + 5Nm, + 2VA + "#; + test("pl", "SimpleSpeak", expr, "3 gramy na litr, przecinek; 1 dżul na mol, przecinek; 5 niutonów na metr, przecinek; 2 wolty na amper")?; + Ok(()) +} + +/// A unit standing on its own keeps the nominative - the accusative must not +/// leak outside the fraction denominator. +#[test] +fn standalone_unit_stays_nominative() -> Result<()> { + let expr = r#" + 1hr, + 1s, + 1t, + 1min + "#; + test("pl", "SimpleSpeak", expr, "1 godzina, przecinek; 1 sekunda, przecinek; 1 tona, przecinek; 1 minuta")?; + Ok(()) +} + +/// Multi-word feminine units: the adjective agrees, a dependent noun does not. +#[test] +fn per_fraction_multiword_denominator() -> Result<()> { + let expr = r#" + 3gsq ft, + 2marcmin + "#; + test("pl", "SimpleSpeak", expr, "3 gramy na stopę kwadratową; przecinek; 2 metry na minutę łuku")?; + Ok(()) +} + +/// A denominator raised to a power, as in m/s^2: the unit's parent is the +/// 'power' element, not the fraction, so this needs its own test. +#[test] +fn per_fraction_denominator_with_power() -> Result<()> { + let expr = r#" + + 3m + s2 + + "#; + test("pl", "SimpleSpeak", expr, "3 metry na sekundę do kwadratu")?; + Ok(()) +} From 6a5170a57526ea1c873f4cb67f92a0b892c6087f Mon Sep 17 00:00:00 2001 From: mgros Date: Fri, 4 Sep 2026 01:59:00 +0200 Subject: [PATCH 088/157] Update: Add `Cargo.lock` file to track dependencies --- .gitignore | 1 - Cargo.lock | 2075 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2075 insertions(+), 1 deletion(-) create mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index fef5d915c..b2784f7e8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ target build.rs.orig Python/libmathcat.pyd -Cargo.lock src-pest.7z src.7z mp2.7z diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000..50bccf29f --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2075 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "alsa" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed7572b7ba83a31e20d1b48970ee402d2e3e0537dcfe0a3ff4d6eb7508617d43" +dependencies = [ + "alsa-sys", + "bitflags 2.11.0", + "cfg-if", + "libc", +] + +[[package]] +name = "alsa-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db8fee663d06c4e303404ef5f40488a53e062f89ba8bfed81f42325aafad1527" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "android_log-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84521a3cf562bc62942e294181d9eef17eb38ceb8c68677bc49f144e4c3d4f8d" + +[[package]] +name = "android_logger" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb4e440d04be07da1f1bf44fb4495ebd58669372fe0cffa6e48595ac5bd88a3" +dependencies = [ + "android_log-sys", + "env_filter 0.1.4", + "log", +] + +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse 0.2.7", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +dependencies = [ + "anstyle", + "anstyle-parse 1.0.0", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-parse" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + +[[package]] +name = "anyhow" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "backtrace" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-link", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" + +[[package]] +name = "bumpalo" +version = "3.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" + +[[package]] +name = "bytemuck" +version = "1.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" + +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "bzip2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a53fac24f34a81bc9954b5d6cfce0c21e18ec6959f44f56e8e90e4bb7c346c" +dependencies = [ + "libbz2-rs-sys", +] + +[[package]] +name = "cc" +version = "1.2.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "clap" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +dependencies = [ + "anstream 1.0.0", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" +dependencies = [ + "heck", + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "clap_lex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "coreaudio-rs" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aae284fbaf7d27aa0e292f7677dfbe26503b0d555026f702940805a630eac17" +dependencies = [ + "bitflags 1.3.2", + "libc", + "objc2-audio-toolbox", + "objc2-core-audio", + "objc2-core-audio-types", + "objc2-core-foundation", +] + +[[package]] +name = "cpal" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbd307f43cc2a697e2d1f8bc7a1d824b5269e052209e28883e5bc04d095aaa3f" +dependencies = [ + "alsa", + "coreaudio-rs", + "dasp_sample", + "jni", + "js-sys", + "libc", + "mach2", + "ndk", + "ndk-context", + "num-derive", + "num-traits", + "objc2-audio-toolbox", + "objc2-core-audio", + "objc2-core-audio-types", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2 1.0.106", + "quote 1.0.45", + "strsim", + "syn 2.0.117", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "dasp_sample" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" + +[[package]] +name = "derive_builder" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" +dependencies = [ + "darling", + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" +dependencies = [ + "derive_builder_core", + "syn 2.0.117", +] + +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.61.2", +] + +[[package]] +name = "dispatch2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" +dependencies = [ + "bitflags 2.11.0", + "objc2", +] + +[[package]] +name = "doc-comment" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "780955b8b195a21ab8e4ac6b60dd1dbdcec1dc6c51c0617964b08c81785e12c9" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "env_filter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_filter" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a1c3cc8e57274ec99de65301228b537f1e4eedc1b8e0f9411c6caac8ae7308f" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2daee4ea451f429a58296525ddf28b45a3b64f1acf6587e2067437bb11e218d" +dependencies = [ + "anstream 0.6.21", + "anstyle", + "env_filter 1.0.0", + "jiff", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "extended" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af9673d8203fcb076b19dfd17e38b3d4ae9f44959416ea532ce72415a6020365" + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "miniz_oxide", + "zlib-rs", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi", +] + +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hound" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f" + +[[package]] +name = "html-escape" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" +dependencies = [ + "utf8-width", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "jiff" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c867c356cc096b33f4981825ab281ecba3db0acefe60329f044c1789d94c6543" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", +] + +[[package]] +name = "jiff-static" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7946b4325269738f270bb55b3c19ab5c5040525f83fd625259422a9d25d9be5" +dependencies = [ + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys 0.3.1", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "js-sys" +version = "0.3.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libbz2-rs-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4a545a15244c7d945065b5d392b2d2d7f21526fba56ce51467b06ed445e8f7" + +[[package]] +name = "libc" +version = "0.2.182" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" + +[[package]] +name = "libredox" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +dependencies = [ + "bitflags 2.11.0", + "libc", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "mach2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" +dependencies = [ + "libc", +] + +[[package]] +name = "mathcat" +version = "0.7.6-rc.4" +dependencies = [ + "android_logger", + "anyhow", + "bitflags 2.11.0", + "cfg-if", + "clap", + "dirs", + "env_logger", + "fastrand", + "html-escape", + "log", + "natural-tts", + "phf", + "radix_fmt", + "regex", + "roman-numerals-rs", + "strum", + "sxd-document-no-unsafe", + "sxd-xpath-no-unsafe", + "tempfile", + "unicode-script", + "yaml-rust", + "zip", +] + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "minreq" +version = "2.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05015102dad0f7d61691ca347e9d9d9006685a64aefb3d79eecf62665de2153d" +dependencies = [ + "rustls", + "rustls-webpki", + "webpki-roots", +] + +[[package]] +name = "natural-tts" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06ae31375ea7364dfadc29bbae70683fce13617e602c458898ebd2630fb1a89" +dependencies = [ + "derive_builder", + "hound", + "minreq", + "percent-encoding", + "rodio", + "serde", + "thiserror 2.0.18", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.11.0", + "jni-sys 0.3.1", + "log", + "ndk-sys", + "num_enum", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys 0.3.1", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro-crate", + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "objc2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-audio-toolbox" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6948501a91121d6399b79abaa33a8aa4ea7857fe019f341b8c23ad6e81b79b08" +dependencies = [ + "bitflags 2.11.0", + "libc", + "objc2", + "objc2-core-audio", + "objc2-core-audio-types", + "objc2-core-foundation", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-audio" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1eebcea8b0dbff5f7c8504f3107c68fc061a3eb44932051c8cf8a68d969c3b2" +dependencies = [ + "dispatch2", + "objc2", + "objc2-core-audio-types", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-core-audio-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a89f2ec274a0cf4a32642b2991e8b351a404d290da87bb6a9a9d8632490bd1c" +dependencies = [ + "bitflags 2.11.0", + "objc2", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags 2.11.0", + "dispatch2", + "objc2", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "objc2", +] + +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "peresil" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f658886ed52e196e850cfbbfddab9eaa7f6d90dd0929e264c31e5cec07e09e57" + +[[package]] +name = "phf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +dependencies = [ + "phf_macros", + "phf_shared", + "serde", +] + +[[package]] +name = "phf_generator" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +dependencies = [ + "fastrand", + "phf_shared", +] + +[[package]] +name = "phf_macros" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "phf_shared" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "portable-atomic-util" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +dependencies = [ + "proc-macro2 0.4.30", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2 1.0.106", +] + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "radix_fmt" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce082a9940a7ace2ad4a8b7d0b1eac6aa378895f18be598230c5f2284ac05426" + +[[package]] +name = "redox_users" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror 2.0.18", +] + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rodio" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e40ecf59e742e03336be6a3d53755e789fd05a059fa22dfa0ed624722319e183" +dependencies = [ + "cpal", + "dasp_sample", + "num-rational", + "symphonia", +] + +[[package]] +name = "roman-numerals-rs" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8408ef3512d2c5d6876de3cf8f24751e19c5f2566e37e1d31ced56a1892f1e92" + +[[package]] +name = "rustc-demangle" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b74b56ffa8bb2830709a538c2cbcae9aa062db0d2a42563bfb09bdaae44020eb" + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags 2.11.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] +name = "siphasher" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "snafu" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d0bf93d08d6a44363b47d737f1f5bebbf5e6a1eaaa3d4c128ceeaca6b718292" +dependencies = [ + "backtrace", + "doc-comment", + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624e94bd38e471f67883b467711e7a7ad7dbe284f5fb7e661dc8a671fc5b26a0" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" +dependencies = [ + "heck", + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "sxd-document-no-unsafe" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c08c6a37e27fb1559e036ae8f45672faf06623f13c74c8de9719d50536981f5" +dependencies = [ + "peresil", + "typed-arena", +] + +[[package]] +name = "sxd-xpath-no-unsafe" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff5bfe9c78786014d5a76d9328ea6508b0b74b7dc4a7c4d9b881ace23ce50d" +dependencies = [ + "peresil", + "snafu", + "sxd-document-no-unsafe", +] + +[[package]] +name = "symphonia" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5773a4c030a19d9bfaa090f49746ff35c75dfddfa700df7a5939d5e076a57039" +dependencies = [ + "lazy_static", + "symphonia-bundle-flac", + "symphonia-bundle-mp3", + "symphonia-codec-aac", + "symphonia-codec-pcm", + "symphonia-codec-vorbis", + "symphonia-core", + "symphonia-format-isomp4", + "symphonia-format-ogg", + "symphonia-format-riff", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-bundle-flac" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c91565e180aea25d9b80a910c546802526ffd0072d0b8974e3ebe59b686c9976" +dependencies = [ + "log", + "symphonia-core", + "symphonia-metadata", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-bundle-mp3" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4872dd6bb56bf5eac799e3e957aa1981086c3e613b27e0ac23b176054f7c57ed" +dependencies = [ + "lazy_static", + "log", + "symphonia-core", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-codec-aac" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c263845aa86881416849c1729a54c7f55164f8b96111dba59de46849e73a790" +dependencies = [ + "lazy_static", + "log", + "symphonia-core", +] + +[[package]] +name = "symphonia-codec-pcm" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e89d716c01541ad3ebe7c91ce4c8d38a7cf266a3f7b2f090b108fb0cb031d95" +dependencies = [ + "log", + "symphonia-core", +] + +[[package]] +name = "symphonia-codec-vorbis" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f025837c309cd69ffef572750b4a2257b59552c5399a5e49707cc5b1b85d1c73" +dependencies = [ + "log", + "symphonia-core", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-core" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea00cc4f79b7f6bb7ff87eddc065a1066f3a43fe1875979056672c9ef948c2af" +dependencies = [ + "arrayvec", + "bitflags 1.3.2", + "bytemuck", + "lazy_static", + "log", +] + +[[package]] +name = "symphonia-format-isomp4" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243739585d11f81daf8dac8d9f3d18cc7898f6c09a259675fc364b382c30e0a5" +dependencies = [ + "encoding_rs", + "log", + "symphonia-core", + "symphonia-metadata", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-format-ogg" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b4955c67c1ed3aa8ae8428d04ca8397fbef6a19b2b051e73b5da8b1435639cb" +dependencies = [ + "log", + "symphonia-core", + "symphonia-metadata", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-format-riff" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2d7c3df0e7d94efb68401d81906eae73c02b40d5ec1a141962c592d0f11a96f" +dependencies = [ + "extended", + "log", + "symphonia-core", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-metadata" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36306ff42b9ffe6e5afc99d49e121e0bd62fe79b9db7b9681d48e29fa19e6b16" +dependencies = [ + "encoding_rs", + "lazy_static", + "log", + "symphonia-core", +] + +[[package]] +name = "symphonia-utils-xiph" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27c85ab799a338446b68eec77abf42e1a6f1bb490656e121c6e27bfbab9f16" +dependencies = [ + "symphonia-core", + "symphonia-metadata", +] + +[[package]] +name = "syn" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2 1.0.106", + "quote 1.0.45", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom 0.4.3", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.25.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow", +] + +[[package]] +name = "typed-arena" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" + +[[package]] +name = "typed-path" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e28f89b80c87b8fb0cf04ab448d5dd0dd0ade2f8891bae878de66a75a28600e" + +[[package]] +name = "unicode-ident" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" + +[[package]] +name = "unicode-script" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "383ad40bb927465ec0ce7720e033cb4ca06912855fc35db31b5755d0de75b1ee" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "utf8-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1292c0d970b54115d14f2492fe0170adf21d68a1de108eebc51c1df4f346a091" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" +dependencies = [ + "quote 1.0.45", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" +dependencies = [ + "bumpalo", + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "windows" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" +dependencies = [ + "windows-core", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +dependencies = [ + "memchr", +] + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "zip" +version = "8.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d04a6b5381502aa6087c94c669499eb1602eb9c5e8198e534de571f7154809b" +dependencies = [ + "bzip2", + "crc32fast", + "flate2", + "indexmap", + "memchr", + "typed-path", + "zopfli", +] + +[[package]] +name = "zlib-rs" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7948af682ccbc3342b6e9420e8c51c1fe5d7bf7756002b4a3c6cabfe96a7e3c" + +[[package]] +name = "zopfli" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249" +dependencies = [ + "bumpalo", + "crc32fast", + "log", + "simd-adler32", +] From a6b6af1592cf35c46a8d2309abdfd514c71e0115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Arborealis=20L=C3=B6tberg?= <143188129+TimArborealis@users.noreply.github.com> Date: Mon, 7 Sep 2026 13:34:39 +0200 Subject: [PATCH 089/157] Minor chemistry fix in Swedish Changed chemical arrow operator to read "reagerar och bildar" instead of "reaktion bildar", to make grammatical sense. --- Rules/Languages/sv/SharedRules/general.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rules/Languages/sv/SharedRules/general.yaml b/Rules/Languages/sv/SharedRules/general.yaml index 192c11204..48676832d 100644 --- a/Rules/Languages/sv/SharedRules/general.yaml +++ b/Rules/Languages/sv/SharedRules/general.yaml @@ -1161,7 +1161,7 @@ then_test: if: "$Verbosity='Terse'" then: [{T: "bildar"}] # phrase(hydrogen and oxygen 'forms' water ) - else: [{T: "reaktion bildar"}] # phrase(hydrogen and oxygen 'reacts to form' water) + else: [{T: "reagerar och bildar"}] # phrase(hydrogen and oxygen 'reacts to form' water) - else_if: ".='⇌' or .='\u1f8d2'" then: [{T: "är i jämvikt med"}] # phrase(a reactant 'is in equilibrium with' a product) - else_if: ".='\u1f8d4'" From bd03fcd02cc69344b574e1d417ded032e40ed290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dziwisz?= Date: Tue, 8 Sep 2026 00:57:22 +0200 Subject: [PATCH 090/157] pl: mark the unicode translations as verified (t -> T) (#741) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * pl: mark the unicode translations as verified (t -> T) Mechanical change: 2435 text keys raised from t/ot/ct to T/OT/CT in the two unicode files. No text is touched. The Polish rules were written before the lowercase/uppercase convention was in use, so entries that have been translated all along still carried the "needs review" key. The audit tool therefore reported them as untranslated, which made the real gaps impossible to see: audit-translations pl, untranslated text: 3162 -> 727 The remaining 727 are in the rule files, where the entries need reading rather than a mechanical pass, so they are deliberately left alone. Every raised entry was checked to differ from the English source, i.e. it really is translated. Entries whose text legitimately equals English (Roman numerals, ligatures, proper names, whitespace) were handled separately in the previous PR; entries still holding English text are NOT raised, since that would assert a translation that does not exist. Verification: cargo test --test languages Languages::pl 609 passed, 0 failed diff: 2436 insertions, 2436 deletions, zero changes outside key case The last point is checked by normalising the key case in the diff and confirming no unpaired lines remain (without normalising, 4710 remain, so the check does discriminate). * pl: also mark the multi-line unicode entries as verified The previous commit raised the key on entries written on a single line (`- "±": [t: "..."]`), but not on entries whose body is a block: - "°": - test: if: "parent::*[name(.)='msup' ...]" then: [t: "stopni"] else: [t: "stopień"] Those are exactly the entries carrying inflection or a TTS condition, so 312 of the most deliberate translations in the file were left looking unreviewed. This raises them: 64 in unicode.yaml, 247 in unicode-full.yaml and one single-line entry (U+23E6) missed earlier. One entry is deliberately left with a lower-case key: `t: ""` for U+00A0, the else-branch of the `@data-empty-in-2D` test. That is silence rather than text, and an upper-case key means "a translator checked this wording" - there is no wording to check. English keeps a lower-case key there too. No content changes; only key case. `cargo test --test languages Languages::pl` gives 609 passed, 0 failed, which is the same result as before this commit, as expected for a change the engine treats as equivalent (src/speech.rs matches "t"|"T" in one match arm). * pl: raise the remaining rule-file keys and test the number-set rules Two loose ends in the Polish localization. **Rule-file keys.** 248 entries in the rule files still used a lower-case key while carrying translated Polish text. Content is untouched - every one of the 248 changed lines differs from its predecessor only in the case of the key name, verified line by line after normalizing the key. 17 entries are deliberately left lower-case: five are the letters C, N, Q, R, Z in `dimension-number-sets` (the letter itself is the wording, as in English); `ct: "s"`/`ct: "-"` in the unit rule are the plural suffix and prefix separator; `navigate.yaml:176` is a Polish euphony variant ("ze" before "st-"); the remaining seven are XPath expressions rather than speech. **Tests for the number-set rules.** These rules had no Polish test at all, in a file where two silent defects were already found. New `tests/Languages/pl/number_sets.rs` covers the bare symbols, the dimension form, both sign variants, and ClearSpeak agreeing with SimpleSpeak. The `number_set_with_variable_exponent` case is the negative control: `dimension-number-sets` fires on `count(*)=2`, so a non-numeric exponent must fall through to the full phrase ("liczby całkowite do potęgi n") rather than being read as a dimension. Without it, a rule that swallowed every superscript would still pass. Polish keeps the letter with a dimension ("R 3"), matching en, de, fr, nb, sv, fi and es; Hungarian is the only language that translates in that position too. Measured with the SAPI voice NVDA actually uses: "R 3" is byte-identical to a phonetic "er 3" and "N 4" to "en 4", so the letters are pronounced as their Polish names. cargo test --test languages Languages::pl 614 passed, 0 failed --------- Co-authored-by: NSoiffer From e1990813b058ff4c27671c244c0960983e78acae Mon Sep 17 00:00:00 2001 From: "U-rainshowers\\neils" Date: Tue, 8 Sep 2026 12:26:42 +1000 Subject: [PATCH 091/157] add PauseFactor to test initialization so that local changes don't affect the outcome. Also consolodate nav preference testing. --- src/interface.rs | 22 ++++++++++++++++++++++ src/navigate.rs | 8 +------- tests/Languages/en/navigate.rs | 15 +-------------- tests/Languages/nb/navigate.rs | 15 +-------------- tests/Languages/ru/navigate.rs | 15 +-------------- tests/common/mod.rs | 11 +++++++++++ 6 files changed, 37 insertions(+), 49 deletions(-) diff --git a/src/interface.rs b/src/interface.rs index 3177c22c8..157a895f1 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -540,6 +540,28 @@ pub fn do_navigate_command(command: impl AsRef) -> Result { return report_any_panic(result); } +/// Preferences shared by navigation unit and integration tests. +/// +/// Sets `PauseFactor` to 100 so local user prefs (e.g. AppData) cannot change +/// TTS:None pause punctuation (`,` vs `;`) in goldens. +/// `auto_zoom_out` is true for most `src/navigate.rs` tests and false for +/// `tests/Languages/*/navigate.rs`. +pub fn set_navigation_test_preferences( + language: impl AsRef, + nav_mode: impl AsRef, + auto_zoom_out: bool, +) -> Result<()> { + set_preference("NavMode", nav_mode)?; + set_preference("NavVerbosity", "Verbose")?; + set_preference("AutoZoomOut", if auto_zoom_out { "True" } else { "False" })?; + set_preference("Language", language)?; + set_preference("SpeechStyle", "SimpleSpeak")?; + set_preference("Verbosity", "Medium")?; + set_preference("PauseFactor", "100")?; + set_preference("Overview", "False")?; + return Ok(()); +} + /// Given an 'id' and an offset (for tokens), set the navigation node to that id. /// An error is returned if the 'id' doesn't exist pub fn set_navigation_node(id: impl AsRef, offset: usize) -> Result<()> { diff --git a/src/navigate.rs b/src/navigate.rs index 1fac4e766..d1444a86c 100644 --- a/src/navigate.rs +++ b/src/navigate.rs @@ -1030,13 +1030,7 @@ mod tests { init_panic_handler(); let result = catch_unwind(AssertUnwindSafe(|| { set_rules_dir(super::super::abs_rules_dir_path())?; - set_preference("NavMode", nav_mode_default)?; - set_preference("NavVerbosity", "Verbose")?; - set_preference("AutoZoomOut", "True")?; - set_preference("Language", language)?; - set_preference("SpeechStyle", "SimpleSpeak")?; - set_preference("Verbosity", "Medium")?; - set_preference("Overview", "False")?; + set_navigation_test_preferences(language, nav_mode_default, true)?; set_mathml(mathml)?; return Ok( () ); })); diff --git a/tests/Languages/en/navigate.rs b/tests/Languages/en/navigate.rs index abb317f18..6752f9773 100644 --- a/tests/Languages/en/navigate.rs +++ b/tests/Languages/en/navigate.rs @@ -8,23 +8,10 @@ use crate::common::*; use anyhow::Result; use std::panic::{catch_unwind, AssertUnwindSafe}; -fn init_nav(mathml: &str) -> Result<()> { - set_rules_dir(abs_rules_dir_path())?; - set_preference("Language", "en")?; - set_preference("SpeechStyle", "SimpleSpeak")?; - set_preference("Verbosity", "Medium")?; - set_preference("NavMode", "Enhanced")?; - set_preference("NavVerbosity", "Verbose")?; - set_preference("AutoZoomOut", "False")?; - set_preference("Overview", "False")?; - set_mathml(mathml)?; - Ok(()) -} - fn assert_zoom_in(command: &str, mathml: &str, expected: &str) -> Result<()> { init_panic_handler(); let result = catch_unwind(AssertUnwindSafe(|| { - init_nav(mathml)?; + init_nav("en", mathml)?; let speech = do_navigate_command(command)?; let trimmed_speech = speech.trim_end_matches([' ', ',', ';']).to_string(); assert_eq!(expected, trimmed_speech); diff --git a/tests/Languages/nb/navigate.rs b/tests/Languages/nb/navigate.rs index 4f1b8dbf2..fd254c6b3 100644 --- a/tests/Languages/nb/navigate.rs +++ b/tests/Languages/nb/navigate.rs @@ -8,23 +8,10 @@ use crate::common::*; use anyhow::Result; use std::panic::{catch_unwind, AssertUnwindSafe}; -fn init_nav(mathml: &str) -> Result<()> { - set_rules_dir(abs_rules_dir_path())?; - set_preference("Language", "nb")?; - set_preference("SpeechStyle", "SimpleSpeak")?; - set_preference("Verbosity", "Medium")?; - set_preference("NavMode", "Enhanced")?; - set_preference("NavVerbosity", "Verbose")?; - set_preference("AutoZoomOut", "False")?; - set_preference("Overview", "False")?; - set_mathml(mathml)?; - Ok(()) -} - fn assert_zoom_in(command: &str, mathml: &str, expected: &str) -> Result<()> { init_panic_handler(); let result = catch_unwind(AssertUnwindSafe(|| { - init_nav(mathml)?; + init_nav("nb", mathml)?; let speech = do_navigate_command(command)?; let trimmed_speech = speech.trim_end_matches([' ', ',', ';']).to_string(); assert_eq!(expected, trimmed_speech); diff --git a/tests/Languages/ru/navigate.rs b/tests/Languages/ru/navigate.rs index 690df9eff..0195f5bde 100644 --- a/tests/Languages/ru/navigate.rs +++ b/tests/Languages/ru/navigate.rs @@ -4,23 +4,10 @@ use crate::common::*; use anyhow::Result; use std::panic::{catch_unwind, AssertUnwindSafe}; -fn init_nav(mathml: &str) -> Result<()> { - set_rules_dir(abs_rules_dir_path())?; - set_preference("Language", "ru")?; - set_preference("SpeechStyle", "SimpleSpeak")?; - set_preference("Verbosity", "Medium")?; - set_preference("NavMode", "Enhanced")?; - set_preference("NavVerbosity", "Verbose")?; - set_preference("AutoZoomOut", "False")?; - set_preference("Overview", "False")?; - set_mathml(mathml)?; - Ok(()) -} - fn assert_zoom_in(mathml: &str, expected: &str) -> Result<()> { init_panic_handler(); let result = catch_unwind(AssertUnwindSafe(|| { - init_nav(mathml)?; + init_nav("ru", mathml)?; let speech = do_navigate_command("ZoomIn")?; let trimmed_speech = speech.trim_end_matches([' ', ',', ';']).to_string(); assert_eq!(expected, trimmed_speech); diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 6b42a25b8..837fca05b 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -75,6 +75,17 @@ fn set_default_speech_prefs() { prefs.set_user_prefs("Impairment", "Blindness").unwrap(); }); } + +/// Initialize navigation prefs + MathML for `tests/Languages/*/navigate.rs`. +/// Uses the same prefs as `src/navigate.rs` tests via [`set_navigation_test_preferences`], +/// except `AutoZoomOut` is false (language ZoomIn speech tests need that). +#[allow(dead_code)] // used in testing +pub fn init_nav(language: &str, mathml: &str) -> Result<()> { + set_rules_dir(abs_rules_dir_path())?; + set_navigation_test_preferences(language, "Enhanced", false)?; + set_mathml(mathml)?; + Ok(()) +} // Compare the result of speaking the mathml input to the output 'speech' // This uses default preferences #[allow(dead_code)] // used in testing From d3b7970e38fa073e1f187afb6537e37d6b9ab859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Tue, 8 Sep 2026 05:59:07 +0200 Subject: [PATCH 092/157] Fix pica unit parsing in spacing width conversion (#755) --- src/xpath_functions.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/xpath_functions.rs b/src/xpath_functions.rs index 97e1db5ee..17b6d360b 100644 --- a/src/xpath_functions.rs +++ b/src/xpath_functions.rs @@ -1408,9 +1408,10 @@ pub struct FontSizeGuess; /// "" // returns original node match isn't found impl FontSizeGuess { + /// Returns an estimated width in em units, using an assumed 12-point font for conversions. pub fn em_from_value(value_with_unit: &str) -> f64 { // match one or more digits followed by a unit -- there are many more units, but they tend to be large and rarer(?) - static FONT_VALUE: LazyLock = LazyLock::new(|| { Regex::new(r"(-?[0-9]*\.?[0-9]*)(px|cm|mm|Q|in|ppc|pt|ex|em|rem)").unwrap() }); + static FONT_VALUE: LazyLock = LazyLock::new(|| { Regex::new(r"(-?[0-9]*\.?[0-9]*)(px|cm|mm|Q|in|pc|pt|ex|em|rem)").unwrap() }); let cap = FONT_VALUE.captures(value_with_unit); if let Some(cap) = cap { if cap.len() == 3 { @@ -1784,6 +1785,16 @@ mod tests { return Ok( () ); } + // Pica widths must use the existing 12pt font estimate: 1pc, 12pt, and 1em are equivalent. + #[test] + fn font_size_guess_pica_widths() { + assert_eq!(FontSizeGuess::em_from_value("1pc"), 1.0); + assert_eq!(FontSizeGuess::em_from_value("0.5pc"), 0.5); + assert_eq!(FontSizeGuess::em_from_value("-1pc"), -1.0); + assert_eq!(FontSizeGuess::em_from_value("12pt"), 1.0); + assert_eq!(FontSizeGuess::em_from_value("1em"), 1.0); + } + #[test] fn ordinal_one_digit() -> Result<()> { return xpath_test(|| { From 07149291fde5258e24148f18139082d49ebf2016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Arborealis=20L=C3=B6tberg?= <143188129+TimArborealis@users.noreply.github.com> Date: Tue, 8 Sep 2026 09:34:46 +0200 Subject: [PATCH 093/157] Update chemistry.rs --- tests/Languages/sv/chemistry.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/Languages/sv/chemistry.rs b/tests/Languages/sv/chemistry.rs index 6332997fc..09612bd26 100644 --- a/tests/Languages/sv/chemistry.rs +++ b/tests/Languages/sv/chemistry.rs @@ -160,9 +160,9 @@ fn beta_decay() -> Result<()> { test_prefs("sv", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "14, 6, versal c; bildar, 14, 7, versal n; plus 0, minus 1, e")?; test_prefs("sv", "ClearSpeak", vec![("Verbosity", "Medium")], expr, - "upphöjt 14, nedsänkt 6, versal c; reaktion bildar; upphöjt 14, nedsänkt 7, versal n; plus, upphöjt 0, nedsänkt minus 1, e")?; + "upphöjt 14, nedsänkt 6, versal c; reagerar och bildar; upphöjt 14, nedsänkt 7, versal n; plus, upphöjt 0, nedsänkt minus 1, e")?; test_prefs("sv", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, - "övre index 14, nedre index 6, versal c; reaktion bildar; övre index 14, nedre index 7, versal n; plus, övre index 0, nedre index minus 1, e")?; + "övre index 14, nedre index 6, versal c; reagerar och bildar; övre index 14, nedre index 7, versal n; plus, övre index 0, nedre index minus 1, e")?; return Ok(()); } @@ -426,9 +426,9 @@ fn mhchem_beta_decay() -> Result<()> { test_prefs("sv", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "14, 6, versal c; bildar, 14, 7, versal n; plus 0, minus 1, e")?; test_prefs("sv", "ClearSpeak", vec![("Verbosity", "Medium")], expr, - "upphöjt 14, nedsänkt 6, versal c; reaktion bildar; upphöjt 14, nedsänkt 7, versal n; plus, upphöjt 0, nedsänkt minus 1, e")?; + "upphöjt 14, nedsänkt 6, versal c; reagerar och bildar; upphöjt 14, nedsänkt 7, versal n; plus, upphöjt 0, nedsänkt minus 1, e")?; test_prefs("sv", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, - "övre index 14, nedre index 6, versal c; reaktion bildar; övre index 14, nedre index 7, versal n; plus, övre index 0, nedre index minus 1, e")?; + "övre index 14, nedre index 6, versal c; reagerar och bildar; övre index 14, nedre index 7, versal n; plus, övre index 0, nedre index minus 1, e")?; return Ok(()); } @@ -443,7 +443,7 @@ fn hcl_na_yields() -> Result<()> { "; test_prefs("sv", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, - "2, versal h, versal c l; plus 2 versal n a; reaktion bildar; 2, versal n a, versal c l; plus versal h, nedre index 2")?; + "2, versal h, versal c l; plus 2 versal n a; reagerar och bildar; 2, versal n a, versal c l; plus versal h, nedre index 2")?; return Ok(()); } From d5d1933c07396b84642e6839eb8d3569340d499d Mon Sep 17 00:00:00 2001 From: Jeff Witt <1848307+wittjeff@users.noreply.github.com> Date: Sun, 13 Sep 2026 07:37:39 -0400 Subject: [PATCH 094/157] Fix "TEMP NAME of" when a parenthesized matrix is raised to a power (#762) (#763) * fix(speech): flatten nested TEMP_NAME wrappers so a matrix raised to a power is not read as "TEMP NAME of" The mrow 'matrix' intent rule replaces with a bare `x: "*[2]"`, so its result is wrapped in the internal TEMP_NAME transport element; the parent `power` rule's `x: "*[1]"` wraps it again and lift_children only stripped one level. The leftover wrapper reached the generic function-intent speech rule, which spoke its name: "TEMP NAME of the 2 by 2 matrix; ...; squared" (#762). lift_children now flattens nested wrappers recursively. A leaf wrapper holding text is still only unwrapped as a direct child, matching the previous behavior. Two regression tests added to tests/Languages/en/mtable.rs; no goldens changed. Fixes #762 Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01U86v5m1m8oaLSy5UsNbBpc * Simplify condition in push_lifted function Fixes clippy warning * Fix indent and delete extra "}" I should have deleted on the last change --------- Co-authored-by: Claude Fable 5.1 Co-authored-by: NSoiffer --- src/speech.rs | 32 ++++++++++++++++++-------- tests/Languages/en/mtable.rs | 44 ++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/src/speech.rs b/src/speech.rs index 100d5ff39..544ce35c7 100644 --- a/src/speech.rs +++ b/src/speech.rs @@ -709,24 +709,36 @@ impl Intent { /// "lift" up the children any "TEMP_NAME" child -- could short circuit when only one child + /// + /// TEMP_NAME is only ever a transport wrapper created by `replace_nodes_tree`, so wrappers can nest: + /// a rule whose replacement is a bare `x:` (e.g., the mrow 'matrix' rule returns `x: "*[2]"`) yields + /// TEMP_NAME(matrix), and the parent intent's `x: "*[1]"` wraps that again. Lifting only one level left + /// `power(TEMP_NAME(matrix), 2)`, spoken as "TEMP NAME of the 2 by 2 matrix ... squared" (issue #762). + /// Nested wrappers whose children are all elements are flattened; a leaf wrapper (text from a Text or + /// Attribute node) is only unwrapped when it is a direct child, matching the previous behavior. fn lift_children(result: Element) -> Element { // debug!("lift_children:\n{}", mml_to_string(result)); // most likely there will be the same number of new children as result has, but there could be more let mut new_children = Vec::with_capacity(2*result.children().len()); for child_of_element in result.children() { - match child_of_element { - ChildOfElement::Element(child) => { - if name(child) == "TEMP_NAME" { - new_children.append(&mut child.children()); // almost always just one - } else { - new_children.push(child_of_element); - } - }, - _ => new_children.push(child_of_element), // text() - } + push_lifted(child_of_element, &mut new_children, true); } result.replace_children(new_children); return result; + + fn push_lifted<'a>(child_of_element: ChildOfElement<'a>, new_children: &mut Vec>, is_direct_child: bool) { + if let ChildOfElement::Element(child) = child_of_element && name(child) == "TEMP_NAME" { + let grandchildren = child.children(); + let is_leaf_wrapper = grandchildren.iter().any(|gc| matches!(gc, ChildOfElement::Text(_))); + if is_direct_child || !is_leaf_wrapper { + for grandchild in grandchildren { + push_lifted(grandchild, new_children, false); + } + return; + } + } + new_children.push(child_of_element); + } } } } diff --git a/tests/Languages/en/mtable.rs b/tests/Languages/en/mtable.rs index 8a670988e..e2d063689 100644 --- a/tests/Languages/en/mtable.rs +++ b/tests/Languages/en/mtable.rs @@ -1390,3 +1390,47 @@ fn single_line_with_label() -> Result<()> { expr, "1 equation, with label 2; b equals 2")?; return Ok(()); } + +#[test] +fn matrix_raised_to_power() -> Result<()> { + // A parenthesized matrix as the base of msup must speak as "the matrix ... squared". + // Regression for #762: the mrow 'matrix' intent rule returns a bare `x:`, so the intent tree + // carried a nested TEMP_NAME wrapper into `power` and NVDA read "TEMP NAME of the 2 by 2 matrix ...". + let expr = " + ( + + 12 + 34 + + ) + 2 + "; + test("en", "ClearSpeak", expr, "the 2 by 2 matrix; row 1; 1, 2; row 2; 3, 4; squared") +} + +#[test] +fn matrix_raised_to_power_lualatex_spacing() -> Result<()> { + // The exact MathML from #762 (LuaLaTeX pmatrix output): negative-width mspace around the + // table and fence attributes on the parens. Canonicalization must fold the spacing away so + // the matrix is still recognized as the base of the power. + let expr = " + + + ( + + + + + 12 + 34 + + + + + ) + + 2 + + "; + test("en", "ClearSpeak", expr, "the 2 by 2 matrix; row 1; 1, 2; row 2; 3, 4; squared") +} From 8ef6ee1b134262b7f6db24851ca2da2588052b82 Mon Sep 17 00:00:00 2001 From: "U-rainshowers\\neils" Date: Tue, 15 Sep 2026 10:59:32 +1000 Subject: [PATCH 095/157] Fix typo in fallback --- src/speech.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/speech.rs b/src/speech.rs index 544ce35c7..6d5b252a7 100644 --- a/src/speech.rs +++ b/src/speech.rs @@ -293,7 +293,7 @@ pub fn process_include(current_file: &Path, new_file_name: &str, mut read_new // get the subdir ...Rules/Braille/en/... // could have ...Rules/Braille/definitions.yaml, so 'next()' doesn't exist in this case, but the file wasn't zipped up if let Some(subdir) = new_file.strip_prefix(unzip_dir).unwrap().iter().next() { - let default_lang = if unzip_dir.ends_with("Languages") {"en"} else {"UEB;"}; + let default_lang = if unzip_dir.ends_with("Languages") {"en"} else {"UEB"}; PreferenceManager::unzip_files(unzip_dir, subdir.to_str().unwrap(), Some(default_lang)).unwrap_or_default(); } } @@ -2868,8 +2868,6 @@ pub fn braille_replace_chars(str: &str, mathml: Element) -> Result { ), Err(e) => Err(e), } - - }) } From 87f4c590a497acaa5daeb2b9864493760e3b0f15 Mon Sep 17 00:00:00 2001 From: "U-rainshowers\\neils" Date: Tue, 15 Sep 2026 11:01:03 +1000 Subject: [PATCH 096/157] The word "of" was hard-coded into intents. This moves its value to definitions.yaml. This also cleans up some really old code that tried to figure out if what was read was a vector or hashmap/hashset. Fixes #739. --- Rules/Languages/en/definitions.yaml | 7 +++ src/definitions.rs | 69 +++++++++++++++++------------ src/infer_intent.rs | 17 ++++--- 3 files changed, 60 insertions(+), 33 deletions(-) diff --git a/Rules/Languages/en/definitions.yaml b/Rules/Languages/en/definitions.yaml index c71e10b89..9a720e7f4 100644 --- a/Rules/Languages/en/definitions.yaml +++ b/Rules/Languages/en/definitions.yaml @@ -363,6 +363,13 @@ "chemistry-concentration": "function= ; concentration: concentration of: the concentration of; end concentration", } + # The connector word to say for functional 'IntentMappings' (in English, "of") + # This is likely the word used for U+2061 in unicode.yaml, but for technical reasons needs to be defined here + # vector of length=1 because scalars not supported +- FunctionApplicationWord: [ + "of", "foo" + ] + # Names of functions that in terse mode don't say "of" (or it's equivalent in other languages) - TerseFunctionNames: { "divergence", "del:gradient", "curl" diff --git a/src/definitions.rs b/src/definitions.rs index 489c25b61..b7c45fca9 100644 --- a/src/definitions.rs +++ b/src/definitions.rs @@ -141,9 +141,20 @@ pub fn read_definitions_file(use_speech_defs: bool) -> Result> { let file_path = pref_manager.get_definitions_file(use_speech_defs); let definitions = if use_speech_defs {&SPEECH_DEFINITIONS} else {&BRAILLE_DEFINITIONS}; definitions.with( |defs| defs.borrow_mut().name_to_var_mapping.clear() ); - let mut new_files = vec![file_path.to_path_buf()]; - let mut files_read = read_one_definitions_file(use_speech_defs, file_path).with_context(|| format!("in file '{}", file_path.to_string_lossy()))?; - new_files.append(&mut files_read); + let mut files_read = read_one_definitions_file(use_speech_defs, file_path) + .with_context(|| format!("in file '{}'", file_path.to_string_lossy()))?; + let mut seen: HashSet = HashSet::with_capacity(files_read.len()); + let mut new_files: Vec = Vec::with_capacity(files_read.len()); + for p in files_read.drain(..) { + let canon = match crate::shim_filesystem::canonicalize_shim(&p) { + Ok(c) => c, + Err(_) => p, + }; + let key = canon.to_string_lossy().to_string(); + if seen.insert(key) { + new_files.push(canon); + } + } // merge the contents of `TrigFunctions` into a set that contains all the function names (from `AdditionalFunctionNames`). return definitions.with(|defs| { @@ -228,39 +239,21 @@ fn build_values(definition: &Yaml, use_speech_defs: bool, path: &Path) -> Result return Ok( Some(crate::speech::process_include(path, include_file_name, do_include_fn)?) ); } - let result; - if def_name.starts_with("Numbers") || def_name.ends_with("_vec") { - result = Contains::Vec( Rc::new( RefCell::new( get_vec_values(value.as_vec().unwrap())? ) ) ); + let result = if let Some(vec) = value.as_vec() { + Contains::Vec( Rc::new( RefCell::new( get_vec_values(vec)? ) ) ) } else { - // match value.as_vec() { - // Some(vec) => { - // result = Contains::Set( Rc::new( RefCell::new( get_set_values(vec)? ) ) ); }, - // None => { - // let dict = value.as_hash().ok_or_else(|| anyhow!("definition list value '{}' is not an array or dictionary", yaml_to_type(value)))?; - // result = Contains::Map( Rc::new( RefCell::new( get_map_values(dict) - // .chain_err(||format!("while reading value '{}'", def_name))? ) ) ); - - // }, - // } let dict = value.as_hash().ok_or_else(|| anyhow!("definition list value '{}' is not an array or dictionary", yaml_to_type(value)))?; if dict.is_empty() { - result = Contains::Set( Rc::new( RefCell::new( HashSet::with_capacity(0) ) ) ); + Contains::Set( Rc::new( RefCell::new( HashSet::with_capacity(0) ) ) ) } else { // peak and see if this is a set or a map let (_, entry_value) = dict.iter().next().unwrap(); if entry_value.is_null() { - result = Contains::Set( Rc::new( RefCell::new( get_set_values(dict) - .with_context(||format!("while reading value '{def_name}'"))? ) ) ); + Contains::Set( Rc::new( RefCell::new( get_set_values(dict) + .with_context(||format!("while reading value '{def_name}'"))? ) ) ) } else { - // peak and see if this is a set or a map - let (_, entry_value) = dict.iter().next().unwrap(); - if entry_value.is_null() { - result = Contains::Set( Rc::new( RefCell::new( get_set_values(dict) - .with_context(||format!("while reading value '{def_name}'"))? ) ) ); - } else { - result = Contains::Map( Rc::new( RefCell::new( get_map_values(dict) - .with_context(||format!("while reading value '{def_name}'"))? ) ) ); - } + Contains::Map( Rc::new( RefCell::new( get_map_values(dict) + .with_context(||format!("while reading value '{def_name}'"))? ) ) ) } } }; @@ -369,6 +362,26 @@ mod tests { }); } + #[test] + fn test_vec_not_numbers() { + let function_application_word = r#"[FunctionApplicationWord: ["of"]]"#; + let defs_build_fn = |variable_def_list: &Yaml| { + for variable_def in variable_def_list.as_vec().unwrap() { + if let Err(e) = build_values(variable_def, true, Path::new("")) { + bail!("{}", crate::interface::errors_to_string(&e.context(format!("in file {:?}", function_application_word)))); + } + } + return Ok(vec![]); + }; + compile_rule(function_application_word, defs_build_fn).unwrap(); + SPEECH_DEFINITIONS.with(|defs| { + let defs = defs.borrow(); + let word = defs.get_vec("FunctionApplicationWord"); + assert!(word.is_some()); + assert_eq!(word.unwrap().as_slice(), ["of"]); + }); + } + #[test] fn test_hashmap() { let units = r#"[Units: {"A": "amp", "g": "gram", "m": "meter", "sec": "second"}]"#; diff --git a/src/infer_intent.rs b/src/infer_intent.rs index 4dc0b3d2e..81cbb9933 100644 --- a/src/infer_intent.rs +++ b/src/infer_intent.rs @@ -314,19 +314,26 @@ pub fn intent_function_has_arity_match(intent_name: &str, fixity: &str, arg_coun /// Spoken glue immediately before argument `arg_index` (1-based) when using an arity template. /// Empty when not in a matching arity template (caller uses separator/`of` path instead). pub fn intent_function_glue_before(intent_name: &str, fixity: &str, arg_index: usize, arg_count: usize) -> String { - let Some(after_eq) = intent_mapping_for_fixity(intent_name, fixity) else { return String::new(); }; if !intent_function_is_arity_mode(intent_name, fixity) { return String::new(); } - let Some(words) = intent_function_arity_glue(&after_eq, arg_count) else { return String::new(); }; - // words has arg_count-1 entries for args 1..arg_count-1; last arg is preceded by "of" if arg_index == arg_count { - return "of".to_string(); + return crate::definitions::SPEECH_DEFINITIONS.with(|definitions| { + let definitions = definitions.borrow(); + let word_ref = definitions.get_vec("FunctionApplicationWord"); + if let Some(word) = word_ref && !word.is_empty() { + return word[0].clone(); + } + return String::new(); + }) } + let Some(after_eq) = intent_mapping_for_fixity(intent_name, fixity) else { return String::new(); }; + let Some(words) = intent_function_arity_glue(&after_eq, arg_count) else { return String::new(); }; + // words has arg_count-1 entries for args 1..arg_count-1; last arg is preceded by "of" if arg_index >= 1 && arg_index < arg_count { return words[arg_index - 1].to_string(); } - String::new() + return String::new(); } /// Separator between args when not using an arity template. From a74a6e2d45f1f0ca454091d75d56b4335c9a8e88 Mon Sep 17 00:00:00 2001 From: "U-rainshowers\\neils" Date: Tue, 15 Sep 2026 11:16:18 +1000 Subject: [PATCH 097/157] remove value used in debugging --- Rules/Languages/en/definitions.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Rules/Languages/en/definitions.yaml b/Rules/Languages/en/definitions.yaml index 9a720e7f4..bd3931549 100644 --- a/Rules/Languages/en/definitions.yaml +++ b/Rules/Languages/en/definitions.yaml @@ -366,9 +366,7 @@ # The connector word to say for functional 'IntentMappings' (in English, "of") # This is likely the word used for U+2061 in unicode.yaml, but for technical reasons needs to be defined here # vector of length=1 because scalars not supported -- FunctionApplicationWord: [ - "of", "foo" - ] +- FunctionApplicationWord: ["of"] # Names of functions that in terse mode don't say "of" (or it's equivalent in other languages) - TerseFunctionNames: { From 2622ee5b2ef2bc3294ee50b1a520e2d65e2f3f1f Mon Sep 17 00:00:00 2001 From: Danil <81031453+Kostenkov-2021@users.noreply.github.com> Date: Sat, 19 Sep 2026 11:19:58 +0300 Subject: [PATCH 098/157] Fix audit-ignore rule scoping Adjust the audit-translations parser so `# audit-ignore` markers immediately above a rule apply to that rule, while still supporting existing inline markers inside a rule block. This also clarifies the documented behavior and adds regression tests for leading, inline, and first-item ignore cases. --- PythonScripts/audit_translations/README.md | 3 +- PythonScripts/audit_translations/parsers.py | 17 +++++-- .../audit_translations/tests/test_parsers.py | 47 +++++++++++++++++++ 3 files changed, 61 insertions(+), 6 deletions(-) diff --git a/PythonScripts/audit_translations/README.md b/PythonScripts/audit_translations/README.md index 8aedf1265..fe391d49b 100644 --- a/PythonScripts/audit_translations/README.md +++ b/PythonScripts/audit_translations/README.md @@ -12,7 +12,8 @@ The tool analyzes rule files to detect the following issues: * **Rule Differences:** Structural changes (match expressions, conditions, variables, or test/replace layout) between the source and target translation. * **Definition Coverage:** Compares literal `definitions.yaml` entries by name and collection kind (`vector`, `set`, or `map`). -Add `# audit-ignore` to a rule block to suppress auditing that rule. +Add `# audit-ignore` on the line immediately before a rule to suppress auditing +that rule. Existing markers inside a rule block are also supported. --- diff --git a/PythonScripts/audit_translations/parsers.py b/PythonScripts/audit_translations/parsers.py index 11dfc5292..a96de8bef 100644 --- a/PythonScripts/audit_translations/parsers.py +++ b/PythonScripts/audit_translations/parsers.py @@ -149,13 +149,20 @@ def format_tag(tag_value: Any) -> str | None: def build_raw_blocks(lines: list[str], starts: list[int]) -> list[str]: - blocks = [] if not starts: - return blocks + return [] + + block_starts = starts.copy() for idx, start in enumerate(starts): - end = starts[idx + 1] if idx + 1 < len(starts) else len(lines) - blocks.append("\n".join(lines[start:end])) - return blocks + lower_bound = starts[idx - 1] + 1 if idx else 0 + while start > lower_bound and (not lines[start - 1].strip() or lines[start - 1].lstrip().startswith("#")): + start -= 1 + block_starts[idx] = start + + return [ + "\n".join(lines[start : block_starts[idx + 1] if idx + 1 < len(block_starts) else len(lines)]) + for idx, start in enumerate(block_starts) + ] def _extract_item_fields(item: Any, is_unicode: bool) -> tuple[str, str | None, str | None, Any] | None: diff --git a/PythonScripts/audit_translations/tests/test_parsers.py b/PythonScripts/audit_translations/tests/test_parsers.py index db7f31e1f..a8d1c36db 100644 --- a/PythonScripts/audit_translations/tests/test_parsers.py +++ b/PythonScripts/audit_translations/tests/test_parsers.py @@ -174,6 +174,53 @@ def test_detects_audit_ignore(self): rules = parse_rules_file(content, data) assert rules[0].audit_ignore + def test_assigns_leading_audit_ignore_to_following_rule(self): + """A marker directly above a rule suppresses that rule, not its neighbour.""" + content = """- name: first + tag: mo + match: "." + +# audit-ignore: the following placeholder intentionally differs +# from the source-language rule. +- name: second + tag: mi + match: "false()" +""" + yaml = YAML() + data = yaml.load(content) + rules = parse_rules_file(content, data) + assert not rules[0].audit_ignore + assert rules[1].audit_ignore + + def test_keeps_audit_ignore_inside_rule(self): + """Existing markers within a rule block remain supported.""" + content = """- name: first + tag: mo + # audit-ignore + match: "." + +- name: second + tag: mi + match: "x" +""" + yaml = YAML() + data = yaml.load(content) + rules = parse_rules_file(content, data) + assert rules[0].audit_ignore + assert not rules[1].audit_ignore + + def test_assigns_file_header_to_first_rule(self): + """A leading marker before the first item is included in its raw block.""" + content = """# audit-ignore +- name: first + tag: mo + match: "." +""" + yaml = YAML() + data = yaml.load(content) + rules = parse_rules_file(content, data) + assert rules[0].audit_ignore + def test_handles_array_tag(self): """Ensure handles array tag.""" content = """- name: multi-tag From a6e65c80560ff302a82b6e821cd8758ce0aace03 Mon Sep 17 00:00:00 2001 From: dtsengchromium Date: Sat, 19 Sep 2026 04:39:38 -0700 Subject: [PATCH 099/157] Add in-memory virtual filesystem support to shim_filesystem (#760) * Add in-memory virtual filesystem support to shim_filesystem * Fix clippy warnings across codebase and tests --- src/prefs.rs | 14 +-- src/shim_filesystem.rs | 105 ++++++++++++++++---- tests/Languages/pt/ClearSpeak/sets.rs | 48 ++++----- tests/Languages/pt/SimpleSpeak/functions.rs | 30 +++--- tests/Languages/pt/escuta.rs | 12 +-- tests/Languages/pt/intent.rs | 25 +++-- tests/Languages/pt/shared.rs | 36 +++---- tests/Languages/pt/units.rs | 36 +++---- 8 files changed, 180 insertions(+), 126 deletions(-) diff --git a/src/prefs.rs b/src/prefs.rs index 4dc51c4bc..89748119f 100644 --- a/src/prefs.rs +++ b/src/prefs.rs @@ -261,17 +261,9 @@ impl PreferenceManager { // Note: if current_dir() also fails, unwrap_or_default yields an empty PathBuf, // and the result may remain relative. #[cfg(not(feature = "include-zip"))] - let rules_dir = match rules_dir.canonicalize() { - Err(_e) => { - if rules_dir.is_absolute() { - rules_dir - } else { - std::env::current_dir() - .unwrap_or_default() - .join(&rules_dir) - } - }, - Ok(rules_dir) => rules_dir, + let rules_dir = match canonicalize_shim(&rules_dir) { + Err(e) => bail!("set_rules_dir: could not canonicalize path {}: {}", rules_dir.display(), e), + Ok(rules_dir) => rules_dir, }; self.set_rules_dir(&rules_dir)?; diff --git a/src/shim_filesystem.rs b/src/shim_filesystem.rs index 14c5b26fb..d539a6300 100644 --- a/src/shim_filesystem.rs +++ b/src/shim_filesystem.rs @@ -281,15 +281,81 @@ cfg_if! { crate::interface::set_rules_dir("Rules").unwrap(); // force reinitialization after the change } } else { + use std::collections::{HashMap, HashSet}; + use std::sync::RwLock; + + static IN_MEMORY_FILES: RwLock>> = RwLock::new(None); + static IN_MEMORY_DIRS: RwLock>> = RwLock::new(None); + + pub fn add_in_memory_file(path: &str, content: &str) { + { + let mut files = IN_MEMORY_FILES.write().unwrap(); + files.get_or_insert_with(HashMap::new).insert(path.to_string(), content.to_string()); + } + + let path_obj = Path::new(path); + { + let mut dirs = IN_MEMORY_DIRS.write().unwrap(); + let dirs = dirs.get_or_insert_with(HashSet::new); + for parent in path_obj.ancestors().skip(1) { + let parent_str = parent.to_str().unwrap_or_default(); + if !parent_str.is_empty() { + dirs.insert(parent_str.to_string()); + } + } + } + } + + pub fn canonicalize_shim(path: &Path) -> std::io::Result { + use std::ffi::OsStr; + let dot = OsStr::new("."); + let dot_dot = OsStr::new(".."); + let mut result = PathBuf::new(); + for part in path.iter() { + if dot == part { + continue; + } else if dot_dot == part { + result.pop(); + } else { + result.push(part); + } + } + return Ok(result); + } + + fn get_in_memory_key(path: &Path) -> String { + canonicalize_shim(path).unwrap_or_else(|_| path.to_path_buf()).to_str().unwrap_or_default().to_string() + } + pub fn is_file_shim(path: &Path) -> bool { + if IN_MEMORY_FILES.read().unwrap().as_ref().is_some_and(|f| f.contains_key(&get_in_memory_key(path))) { + return true; + } return path.is_file(); } pub fn is_dir_shim(path: &Path) -> bool { + if IN_MEMORY_DIRS.read().unwrap().as_ref().is_some_and(|d| d.contains(&get_in_memory_key(path))) { + return true; + } return path.is_dir(); } pub fn find_files_in_dir_that_ends_with_shim(dir: &Path, ending: &str) -> Vec { + let dir_name = get_in_memory_key(dir); + let mut answer = Vec::new(); + if let Some(files) = IN_MEMORY_FILES.read().unwrap().as_ref() { + for file_name in files.keys() { + if file_name.starts_with(&dir_name) && file_name.ends_with(ending) { + let name = Path::new(file_name).file_name().unwrap_or_default().to_str().unwrap_or_default(); + answer.push(name.to_string()); + } + } + } + if !answer.is_empty() { + return answer; + } + match dir.read_dir() { Err(_) => return vec![], // empty Ok(read_dir) => { @@ -340,27 +406,6 @@ cfg_if! { } } - /// Resolves the path to an absolute, canonical form using the OS. - /// If `canonicalize()` fails (e.g., ACCESS_DENIED in containers), falls back to: - /// - returning the path as-is if it is already absolute, - /// - prepending the current working directory if it is relative. - /// Note: the fallback does not resolve symlinks or normalize `..`/`.` segments. - pub fn canonicalize_shim(path: &Path) -> std::io::Result { - match path.canonicalize() { - Ok(p) => Ok(p), - Err(_) => { - if path.is_absolute() { - Ok(path.to_path_buf()) - } else { - // Prepend cwd to make the relative path absolute. - // unwrap_or_default yields an empty PathBuf if cwd is unavailable, - // in which case the returned path will still be relative. - Ok(std::env::current_dir().unwrap_or_default().join(path)) - } - } - } - } - // Tests extract language/braille zips in parallel. During extraction, individual YAML // files can briefly exist in a partially-written state (created/truncated before the // full contents are flushed). Guard both extraction and YAML reads with the same lock @@ -379,6 +424,10 @@ cfg_if! { } pub fn read_to_string_shim(path: &Path) -> Result { + if let Some(content) = IN_MEMORY_FILES.read().unwrap().as_ref().and_then(|f| f.get(&get_in_memory_key(path)).cloned()) { + return Ok(content); + } + let path = match path.canonicalize() { Ok(path) => path, Err(_) => path.to_path_buf(), @@ -490,4 +539,18 @@ mod tests { assert_eq!("test-value", read_to_string_shim(&existing_file).unwrap()); assert!(read_to_string_shim(&test_dir.path().join("does-not-exist.yaml")).is_err()); } + + #[test] + fn in_memory_filesystem_shim() { + add_in_memory_file("virtual/rules/Languages/en/test_Rules.yaml", "key: value"); + let file_path = Path::new("virtual/rules/Languages/en/test_Rules.yaml"); + let dir_path = Path::new("virtual/rules/Languages/en"); + + assert!(is_file_shim(file_path)); + assert!(is_dir_shim(dir_path)); + assert_eq!(read_to_string_shim(file_path).unwrap(), "key: value"); + + let found = find_files_in_dir_that_ends_with_shim(dir_path, "_Rules.yaml"); + assert_eq!(found, vec!["test_Rules.yaml".to_string()]); + } } diff --git a/tests/Languages/pt/ClearSpeak/sets.rs b/tests/Languages/pt/ClearSpeak/sets.rs index ff2ee45cd..87923aeac 100644 --- a/tests/Languages/pt/ClearSpeak/sets.rs +++ b/tests/Languages/pt/ClearSpeak/sets.rs @@ -1,27 +1,27 @@ -/// Testes de conjuntos e pertinência — pt-BR, ClearSpeak e SimpleSpeak. -/// -/// POR QUE ESTE ARQUIVO EXISTE -/// O par ∈ / ∊ falou "é membro de" com as preferências padrão durante duas -/// rodadas inteiras sem ninguém notar, porque o pt não tinha NENHUM teste de -/// pertinência — nem ClearSpeak, nem SimpleSpeak. O ∉ foi corrigido sozinho -/// numa rodada e os outros dois ficaram para trás. Ver ACHADOS 7.8. -/// -/// A invariante que este arquivo trava: **∈ (0x2208) e ∊ (0x220a) são -/// variantes de forma do mesmo símbolo e devem falar igual em todos os ramos** -/// — nas cinco preferências de ClearSpeak_SetMemberSymbol, dentro e fora de -/// um conjunto, nos dois estilos de fala. -/// -/// COMO AS EXPECTATIVAS FORAM ESCRITAS -/// Todas saíram da saída real do motor, nunca de tradução do inglês. O método -/// é o do cabeçalho de tests/Languages/pt/shared.rs: rodar, comparar `left` -/// com `right`, e se o gerado estiver certo em português, copiá-lo; se estiver -/// errado, consertar a REGRA, nunca o teste. -/// -/// Cada teste de pertinência fixa ClearSpeak_SetMemberSymbol explicitamente, -/// inclusive no caso 'Auto'. Isso é de propósito: as preferências de -/// ClearSpeak não são reinicializadas entre testes na mesma thread, então um -/// teste que dependesse do padrão implícito poderia passar ou falhar conforme -/// a ordem de execução. +//! Testes de conjuntos e pertinência — pt-BR, ClearSpeak e SimpleSpeak. +//! +//! POR QUE ESTE ARQUIVO EXISTE +//! O par ∈ / ∊ falou "é membro de" com as preferências padrão durante duas +//! rodadas inteiras sem ninguém notar, porque o pt não tinha NENHUM teste de +//! pertinência — nem ClearSpeak, nem SimpleSpeak. O ∉ foi corrigido sozinho +//! numa rodada e os outros dois ficaram para trás. Ver ACHADOS 7.8. +//! +//! A invariante que este arquivo trava: **∈ (0x2208) e ∊ (0x220a) são +//! variantes de forma do mesmo símbolo e devem falar igual em todos os ramos** +//! — nas cinco preferências de ClearSpeak_SetMemberSymbol, dentro e fora de +//! um conjunto, nos dois estilos de fala. +//! +//! COMO AS EXPECTATIVAS FORAM ESCRITAS +//! Todas saíram da saída real do motor, nunca de tradução do inglês. O método +//! é o do cabeçalho de tests/Languages/pt/shared.rs: rodar, comparar `left` +//! com `right`, e se o gerado estiver certo em português, copiá-lo; se estiver +//! errado, consertar a REGRA, nunca o teste. +//! +//! Cada teste de pertinência fixa ClearSpeak_SetMemberSymbol explicitamente, +//! inclusive no caso 'Auto'. Isso é de propósito: as preferências de +//! ClearSpeak não são reinicializadas entre testes na mesma thread, então um +//! teste que dependesse do padrão implícito poderia passar ou falhar conforme +//! a ordem de execução. use crate::common::*; use anyhow::Result; diff --git a/tests/Languages/pt/SimpleSpeak/functions.rs b/tests/Languages/pt/SimpleSpeak/functions.rs index a656c2da0..1429d1447 100644 --- a/tests/Languages/pt/SimpleSpeak/functions.rs +++ b/tests/Languages/pt/SimpleSpeak/functions.rs @@ -1,18 +1,18 @@ -/// TESTES DO IDIOMA pt — como reconciliar com as regras -/// -/// As strings esperadas abaixo foram escritas para refletir a intenção -/// das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam -/// PAUSAS inseridas pelo motor e podem divergir levemente na primeira -/// execução. Método do guia oficial de tradutores: -/// 1. rode `cargo test Languages::pt` -/// 2. para cada falha, compare `left` (esperado) com `right` (gerado) -/// 3. se o GERADO estiver correto em português, copie-o para o teste; -/// se estiver errado, conserte a REGRA, nunca o teste. -/// -/// ATENÇÃO ao histórico: o arquivo espanhol equivalente continha testes -/// que não refletiam as regras (ex.: esperava "logaritmo natural" com a -/// regra dizendo "natural log") e dano de busca-e-troca (ex.: "eigh"→"8"). -/// Não herde strings esperadas de es/ sem conferir. +//! TESTES DO IDIOMA pt — como reconciliar com as regras +//! +//! As strings esperadas abaixo foram escritas para refletir a intenção +//! das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam +//! PAUSAS inseridas pelo motor e podem divergir levemente na primeira +//! execução. Método do guia oficial de tradutores: +//! 1. rode `cargo test Languages::pt` +//! 2. para cada falha, compare `left` (esperado) com `right` (gerado) +//! 3. se o GERADO estiver correto em português, copie-o para o teste; +//! se estiver errado, conserte a REGRA, nunca o teste. +//! +//! ATENÇÃO ao histórico: o arquivo espanhol equivalente continha testes +//! que não refletiam as regras (ex.: esperava "logaritmo natural" com a +//! regra dizendo "natural log") e dano de busca-e-troca (ex.: "eigh"→"8"). +//! Não herde strings esperadas de es/ sem conferir. use crate::common::*; use anyhow::Result; diff --git a/tests/Languages/pt/escuta.rs b/tests/Languages/pt/escuta.rs index 812be28be..661cf4c85 100644 --- a/tests/Languages/pt/escuta.rs +++ b/tests/Languages/pt/escuta.rs @@ -2,12 +2,12 @@ use crate::common::*; fn falar(estilo: &str, verbosidade: &str, mathml: &str) -> String { set_rules_dir(abs_rules_dir_path()).unwrap(); - set_preference("Language", "pt".to_string()).unwrap(); - set_preference("SpeechStyle", estilo.to_string()).unwrap(); - set_preference("Verbosity", verbosidade.to_string()).unwrap(); - set_preference("SpeechOverrides_CapitalLetters", "".to_string()).unwrap(); - set_preference("ClearSpeak_SetMemberSymbol", "Auto".to_string()).unwrap(); - match set_mathml(mathml.to_string()) { + set_preference("Language", "pt").unwrap(); + set_preference("SpeechStyle", estilo).unwrap(); + set_preference("Verbosity", verbosidade).unwrap(); + set_preference("SpeechOverrides_CapitalLetters", "").unwrap(); + set_preference("ClearSpeak_SetMemberSymbol", "Auto").unwrap(); + match set_mathml(mathml) { Ok(_) => match get_spoken_text() { Ok(fala) => regex::Regex::new(r" +").unwrap().replace_all(&fala, " ").to_string(), Err(e) => format!("[ERRO ao falar: {}]", errors_to_string(&e)), diff --git a/tests/Languages/pt/intent.rs b/tests/Languages/pt/intent.rs index df164bc1b..cd43e0251 100644 --- a/tests/Languages/pt/intent.rs +++ b/tests/Languages/pt/intent.rs @@ -1,17 +1,16 @@ -/// TESTES DO IDIOMA pt — como reconciliar com as regras -/// -/// As strings esperadas abaixo foram escritas para refletir a intenção -/// das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam -/// PAUSAS inseridas pelo motor e podem divergir levemente na primeira -/// execução. Método do guia oficial de tradutores: -/// 1. rode `cargo test Languages::pt` -/// 2. para cada falha, compare `left` (esperado) com `right` (gerado) -/// 3. se o GERADO estiver correto em português, copie-o para o teste; -/// se estiver errado, conserte a REGRA, nunca o teste. -/// +//! TESTES DO IDIOMA pt — como reconciliar com as regras +//! +//! As strings esperadas abaixo foram escritas para refletir a intenção +//! das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam +//! PAUSAS inseridas pelo motor e podem divergir levemente na primeira +//! execução. Método do guia oficial de tradutores: +//! 1. rode `cargo test Languages::pt` +//! 2. para cada falha, compare `left` (esperado) com `right` (gerado) +//! 3. se o GERADO estiver correto em português, copie-o para o teste; +//! se estiver errado, conserte a REGRA, nunca o teste. -/// Tests for rules shared between various speech styles: -/// * this has tests focused on the various alphabets +// Tests for rules shared between various speech styles: +// * this has tests focused on the various alphabets use crate::common::*; use anyhow::Result; diff --git a/tests/Languages/pt/shared.rs b/tests/Languages/pt/shared.rs index cf860236b..50a28d49a 100644 --- a/tests/Languages/pt/shared.rs +++ b/tests/Languages/pt/shared.rs @@ -1,21 +1,21 @@ -/// TESTES DO IDIOMA pt — como reconciliar com as regras -/// -/// As strings esperadas abaixo foram escritas para refletir a intenção -/// das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam -/// PAUSAS inseridas pelo motor e podem divergir levemente na primeira -/// execução. Método do guia oficial de tradutores: -/// 1. rode `cargo test Languages::pt` -/// 2. para cada falha, compare `left` (esperado) com `right` (gerado) -/// 3. se o GERADO estiver correto em português, copie-o para o teste; -/// se estiver errado, conserte a REGRA, nunca o teste. -/// -/// ATENÇÃO ao histórico: o arquivo espanhol equivalente continha testes -/// que não refletiam as regras (ex.: esperava "logaritmo natural" com a -/// regra dizendo "natural log") e dano de busca-e-troca (ex.: "eigh"→"8"). -/// Não herde strings esperadas de es/ sem conferir. - -/// Tests for rules shared between various speech styles: -/// * modified var +//! TESTES DO IDIOMA pt — como reconciliar com as regras +//! +//! As strings esperadas abaixo foram escritas para refletir a intenção +//! das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam +//! PAUSAS inseridas pelo motor e podem divergir levemente na primeira +//! execução. Método do guia oficial de tradutores: +//! 1. rode `cargo test Languages::pt` +//! 2. para cada falha, compare `left` (esperado) com `right` (gerado) +//! 3. se o GERADO estiver correto em português, copie-o para o teste; +//! se estiver errado, conserte a REGRA, nunca o teste. +//! +//! ATENÇÃO ao histórico: o arquivo espanhol equivalente continha testes +//! que não refletiam as regras (ex.: esperava "logaritmo natural" com a +//! regra dizendo "natural log") e dano de busca-e-troca (ex.: "eigh"→"8"). +//! Não herde strings esperadas de es/ sem conferir. + +// Tests for rules shared between various speech styles: +// * modified var use crate::common::*; use anyhow::Result; diff --git a/tests/Languages/pt/units.rs b/tests/Languages/pt/units.rs index 47bd73056..cf0048f0d 100644 --- a/tests/Languages/pt/units.rs +++ b/tests/Languages/pt/units.rs @@ -1,21 +1,21 @@ -/// TESTES DO IDIOMA pt — como reconciliar com as regras -/// -/// As strings esperadas abaixo foram escritas para refletir a intenção -/// das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam -/// PAUSAS inseridas pelo motor e podem divergir levemente na primeira -/// execução. Método do guia oficial de tradutores: -/// 1. rode `cargo test Languages::pt` -/// 2. para cada falha, compare `left` (esperado) com `right` (gerado) -/// 3. se o GERADO estiver correto em português, copie-o para o teste; -/// se estiver errado, conserte a REGRA, nunca o teste. -/// -/// ATENÇÃO ao histórico: o arquivo espanhol equivalente continha testes -/// que não refletiam as regras (ex.: esperava "logaritmo natural" com a -/// regra dizendo "natural log") e dano de busca-e-troca (ex.: "eigh"→"8"). -/// Não herde strings esperadas de es/ sem conferir. - -/// Tests for rules shared between various speech styles: -/// * modified var +//! TESTES DO IDIOMA pt — como reconciliar com as regras +//! +//! As strings esperadas abaixo foram escritas para refletir a intenção +//! das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam +//! PAUSAS inseridas pelo motor e podem divergir levemente na primeira +//! execução. Método do guia oficial de tradutores: +//! 1. rode `cargo test Languages::pt` +//! 2. para cada falha, compare `left` (esperado) com `right` (gerado) +//! 3. se o GERADO estiver correto em português, copie-o para o teste; +//! se estiver errado, conserte a REGRA, nunca o teste. +//! +//! ATENÇÃO ao histórico: o arquivo espanhol equivalente continha testes +//! que não refletiam as regras (ex.: esperava "logaritmo natural" com a +//! regra dizendo "natural log") e dano de busca-e-troca (ex.: "eigh"→"8"). +//! Não herde strings esperadas de es/ sem conferir. + +// Tests for rules shared between various speech styles: +// * modified var use crate::common::*; use anyhow::Result; From 49de6d67c802f0f516cef11eef8f2528339f2a5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Sat, 19 Sep 2026 13:45:17 +0200 Subject: [PATCH 100/157] Refactor: Simplify match return logic and improve string interpolation readability (#774) --- src/bin/package_rules.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bin/package_rules.rs b/src/bin/package_rules.rs index 900af235f..971e95175 100644 --- a/src/bin/package_rules.rs +++ b/src/bin/package_rules.rs @@ -37,7 +37,7 @@ fn main() -> ExitCode { return ExitCode::from(1); } - match package_rules( + return match package_rules( &cli.source, &cli.output, cli.minimize, @@ -45,15 +45,15 @@ fn main() -> ExitCode { ) { Ok(minimized) => { let label = if cli.minimize { "minimized" } else { "standard" }; - println!("Created {} archive: {}", label, cli.output.display()); + println!("Created {label} archive: {}", cli.output.display()); if cli.minimize { - println!(" minimized YAML files: {}", minimized); + println!(" minimized YAML files: {minimized}"); } - return ExitCode::SUCCESS; + ExitCode::SUCCESS } Err(e) => { - eprintln!("error: {}", e); - return ExitCode::from(1); + eprintln!("error: {e}"); + ExitCode::from(1) } } } From 5c8117e99041f74aeb4f322593ec11d1e3766d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dziwisz?= Date: Sun, 20 Sep 2026 09:21:16 +0200 Subject: [PATCH 101/157] de, el: use $CommandOffset instead of string-length($Prefix) in navigate.yaml (#766) Ports ec36e057 to the two remaining languages that still cut the direction word out of $NavCommand with the length of the SPOKEN prefix. $NavCommand is always English (ZoomIn, MoveNext), while $Prefix is the translated word, so string-length($Prefix)+1 only lands on the right offset while the prefix happens to match the English stem. In de and el the prefixes are still the untranslated zoom/move/read/describe, so all 18 branches work today by coincidence; localizing those strings -- the obvious thing for a translator to do -- silently kills every direction word. This is a no-op right now, which is exactly why it is a good time to do it: substring($NavCommand, $CommandOffset) returns the same value as before for every one of the 15 navigation commands with the current prefixes. Verified on the engine, not only on paper: Languages::de is 209/209 both with and without this change. Greek has no tests at all (tests/Languages/el exists but is not declared in tests/languages.rs), so el rests on the structural check: offsets and the list of 9 branches are now identical to en. Refs #740. --- Rules/Languages/de/navigate.yaml | 26 +++++++++++++------------- Rules/Languages/el/navigate.yaml | 26 +++++++++++++------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/Rules/Languages/de/navigate.yaml b/Rules/Languages/de/navigate.yaml index 4ff42e67a..0b5ea83e8 100644 --- a/Rules/Languages/de/navigate.yaml +++ b/Rules/Languages/de/navigate.yaml @@ -54,37 +54,37 @@ else: - test: - if: "starts-with($NavCommand, 'Zoom')" - then: [set_variables: [Prefix: "'zoom'"]] # phrase('zoom' in to see more details) + then: [set_variables: [Prefix: "'zoom'", CommandOffset: "5"]] # phrase('zoom' in to see more details) - else_if: "starts-with($NavCommand, 'Move')" - then: [set_variables: [Prefix: "'move'"]] # phrase('move' to next entry in table) + then: [set_variables: [Prefix: "'move'", CommandOffset: "5"]] # phrase('move' to next entry in table) - else_if: "starts-with($NavCommand, 'Read')" - then: [set_variables: [Prefix: "'read'"]] # phrase('read' to next entry in table) + then: [set_variables: [Prefix: "'read'", CommandOffset: "5"]] # phrase('read' to next entry in table) - else_if: "starts-with($NavCommand, 'Describe')" - then: [set_variables: [Prefix: "'describe'"]] # phrase('describe' to next entry in table) + then: [set_variables: [Prefix: "'describe'", CommandOffset: "9"]] # phrase('describe' to next entry in table) - test: if: "$Prefix != ''" then: - x: "$Prefix" - test: - - if: "substring($NavCommand, string-length($Prefix)+1) = 'In'" + - if: "substring($NavCommand, $CommandOffset) = 'In'" then: [T: "in"] # phrase(zoom 'in' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'InAll'" + - else_if: "substring($NavCommand, $CommandOffset) = 'InAll'" # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets "ed" concatenated to "zoom" then: [T: "den ganzen weg"] # phrase(zoom 'out all the way' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Out'" + - else_if: "substring($NavCommand, $CommandOffset) = 'Out'" then: [T: "raus"] # phrase(zoom 'out' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'OutAll'" + - else_if: "substring($NavCommand, $CommandOffset) = 'OutAll'" # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets "ed" concatenated to "zoom" then: [T: "den ganzen weg"] # phrase(zoom 'out all the way' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Next'" + - else_if: "substring($NavCommand, $CommandOffset) = 'Next'" then: [T: "rechten"] # phrase(move to the 'right') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Previous'" + - else_if: "substring($NavCommand, $CommandOffset) = 'Previous'" then: [T: "linken"] # phrase(move to the 'left') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Current'" + - else_if: "substring($NavCommand, $CommandOffset) = 'Current'" then: [T: "aktuelle"] # phrase(who is the 'current' president) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'LineStart'" + - else_if: "substring($NavCommand, $CommandOffset) = 'LineStart'" then: [T: "start der linie"] # phrase(move 'to start of line') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'LineEnd'" + - else_if: "substring($NavCommand, $CommandOffset) = 'LineEnd'" then: [T: "bis zum ende der linie"] # phrase(move 'to end of line') - pause: "medium" - set_variables: [MatchCounter: "1"] diff --git a/Rules/Languages/el/navigate.yaml b/Rules/Languages/el/navigate.yaml index 2466efd8c..1cbfcc6f5 100644 --- a/Rules/Languages/el/navigate.yaml +++ b/Rules/Languages/el/navigate.yaml @@ -54,37 +54,37 @@ else: - test: - if: "starts-with($NavCommand, 'Zoom')" - then: [set_variables: [Prefix: "'zoom'"]] # phrase('zoom' in to see more details) + then: [set_variables: [Prefix: "'zoom'", CommandOffset: "5"]] # phrase('zoom' in to see more details) - else_if: "starts-with($NavCommand, 'Move')" - then: [set_variables: [Prefix: "'move'"]] # phrase('move' to next entry in table) + then: [set_variables: [Prefix: "'move'", CommandOffset: "5"]] # phrase('move' to next entry in table) - else_if: "starts-with($NavCommand, 'Read')" - then: [set_variables: [Prefix: "'read'"]] # phrase('read' to next entry in table) + then: [set_variables: [Prefix: "'read'", CommandOffset: "5"]] # phrase('read' to next entry in table) - else_if: "starts-with($NavCommand, 'Describe')" - then: [set_variables: [Prefix: "'describe'"]] # phrase('describe' to next entry in table) + then: [set_variables: [Prefix: "'describe'", CommandOffset: "9"]] # phrase('describe' to next entry in table) - test: if: "$Prefix != ''" then: - x: "$Prefix" - test: - - if: "substring($NavCommand, string-length($Prefix)+1) = 'In'" + - if: "substring($NavCommand, $CommandOffset) = 'In'" then: [t: "εντός"] # phrase(zoom 'in' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'InAll'" + - else_if: "substring($NavCommand, $CommandOffset) = 'InAll'" # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets "ed" concatenated to "zoom" then: [t: "\uF8FEed πλήρως"] #theodora. check # phrase(zoom 'out all the way' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Out'" + - else_if: "substring($NavCommand, $CommandOffset) = 'Out'" then: [t: "εκτός"] # phrase(zoom 'out' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'OutAll'" + - else_if: "substring($NavCommand, $CommandOffset) = 'OutAll'" # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets "ed" concatenated to "zoom" then: [t: "\uF8FEed πλήρως"] #theodora. check # phrase(zoom 'out all the way' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Next'" + - else_if: "substring($NavCommand, $CommandOffset) = 'Next'" then: [t: "δεξιά"] # phrase(move to the 'right') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Previous'" + - else_if: "substring($NavCommand, $CommandOffset) = 'Previous'" then: [t: "αριστερά"] # phrase(move to the 'left') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Current'" + - else_if: "substring($NavCommand, $CommandOffset) = 'Current'" then: [t: "τρέχον"] # phrase(who is the 'current' president) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'LineStart'" + - else_if: "substring($NavCommand, $CommandOffset) = 'LineStart'" then: [t: "στην αρχή της γραμμής"] # phrase(move 'to start of line') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'LineEnd'" + - else_if: "substring($NavCommand, $CommandOffset) = 'LineEnd'" then: [t: "στο τέλος της γραμμής"] # phrase(move 'to end of line') - pause: "medium" - set_variables: [MatchCounter: "$MatchCounter + 1"] From 600180b4291f0f5a5797d443e84dfb41337d29d5 Mon Sep 17 00:00:00 2001 From: Danil <81031453+Kostenkov-2021@users.noreply.github.com> Date: Sun, 20 Sep 2026 10:41:20 +0300 Subject: [PATCH 102/157] Fix audit-ignore parsing around comments This change fixes how audit_translations YAML blocks are split when comments or blank lines appear around list items. It keeps introductory comments with the correct rule, preserves explicit audit-ignore markers inside a rule, and avoids incorrectly attaching comment-only lines to neighboring items. --- PythonScripts/audit_translations/README.md | 4 +- PythonScripts/audit_translations/parsers.py | 35 ++++++++++++--- .../audit_translations/tests/test_parsers.py | 44 +++++++++++++++++-- 3 files changed, 71 insertions(+), 12 deletions(-) diff --git a/PythonScripts/audit_translations/README.md b/PythonScripts/audit_translations/README.md index fe391d49b..241a500d2 100644 --- a/PythonScripts/audit_translations/README.md +++ b/PythonScripts/audit_translations/README.md @@ -12,8 +12,8 @@ The tool analyzes rule files to detect the following issues: * **Rule Differences:** Structural changes (match expressions, conditions, variables, or test/replace layout) between the source and target translation. * **Definition Coverage:** Compares literal `definitions.yaml` entries by name and collection kind (`vector`, `set`, or `map`). -Add `# audit-ignore` on the line immediately before a rule to suppress auditing -that rule. Existing markers inside a rule block are also supported. +After a blank line, add `# audit-ignore` immediately before a rule to suppress +auditing that rule. Existing markers inside a rule block are also supported. --- diff --git a/PythonScripts/audit_translations/parsers.py b/PythonScripts/audit_translations/parsers.py index a96de8bef..bcbdd0027 100644 --- a/PythonScripts/audit_translations/parsers.py +++ b/PythonScripts/audit_translations/parsers.py @@ -154,15 +154,36 @@ def build_raw_blocks(lines: list[str], starts: list[int]) -> list[str]: block_starts = starts.copy() for idx, start in enumerate(starts): - lower_bound = starts[idx - 1] + 1 if idx else 0 - while start > lower_bound and (not lines[start - 1].strip() or lines[start - 1].lstrip().startswith("#")): + if idx == 0: + while start > 0 and (not lines[start - 1].strip() or lines[start - 1].lstrip().startswith("#")): + start -= 1 + block_starts[idx] = start + continue + + lower_bound = starts[idx - 1] + 1 + dash_line = re.fullmatch(r"\s*-\s*(?:#.*)?", lines[start - 1]) if start > lower_bound else None + if dash_line: start -= 1 - block_starts[idx] = start + block_starts[idx] = start + continue - return [ - "\n".join(lines[start : block_starts[idx + 1] if idx + 1 < len(block_starts) else len(lines)]) - for idx, start in enumerate(block_starts) - ] + comment_start = start + while comment_start > lower_bound and lines[comment_start - 1].lstrip().startswith("#"): + comment_start -= 1 + + # A separating blank makes the comment run introductory text for this + # item. Without one, leave the run with the preceding rule. + if comment_start > lower_bound and not lines[comment_start - 1].strip(): + start = comment_start - 1 + while start > lower_bound and not lines[start - 1].strip(): + start -= 1 + block_starts[idx] = start + + blocks = [] + for idx, start in enumerate(block_starts): + end = block_starts[idx + 1] if idx + 1 < len(block_starts) else len(lines) + blocks.append("\n".join(lines[start:end])) + return blocks def _extract_item_fields(item: Any, is_unicode: bool) -> tuple[str, str | None, str | None, Any] | None: diff --git a/PythonScripts/audit_translations/tests/test_parsers.py b/PythonScripts/audit_translations/tests/test_parsers.py index a8d1c36db..6714f3581 100644 --- a/PythonScripts/audit_translations/tests/test_parsers.py +++ b/PythonScripts/audit_translations/tests/test_parsers.py @@ -176,7 +176,8 @@ def test_detects_audit_ignore(self): def test_assigns_leading_audit_ignore_to_following_rule(self): """A marker directly above a rule suppresses that rule, not its neighbour.""" - content = """- name: first + content = """ +- name: first tag: mo match: "." @@ -194,7 +195,8 @@ def test_assigns_leading_audit_ignore_to_following_rule(self): def test_keeps_audit_ignore_inside_rule(self): """Existing markers within a rule block remain supported.""" - content = """- name: first + content = """ +- name: first tag: mo # audit-ignore match: "." @@ -209,9 +211,45 @@ def test_keeps_audit_ignore_inside_rule(self): assert rules[0].audit_ignore assert not rules[1].audit_ignore + def test_keeps_touching_comment_with_preceding_rule(self): + """A comment without a separating blank remains part of the preceding rule.""" + content = """ +- name: first + tag: mo + match: "." +# audit-ignore: this comment documents the first rule +- name: second + tag: mi + match: "x" +""" + yaml = YAML() + data = yaml.load(content) + rules = parse_rules_file(content, data) + assert rules[0].audit_ignore + assert not rules[1].audit_ignore + + def test_includes_comment_on_item_dash_line(self): + """A comment attached to an item's dash belongs to that item.""" + content = """ +- name: first + tag: mo + match: "." + +- # second rule introduction + name: second + tag: mi + match: "x" +""" + yaml = YAML() + data = yaml.load(content) + rules = parse_rules_file(content, data) + assert "second rule introduction" not in rules[0].raw_content + assert "second rule introduction" in rules[1].raw_content + def test_assigns_file_header_to_first_rule(self): """A leading marker before the first item is included in its raw block.""" - content = """# audit-ignore + content = """ +# audit-ignore - name: first tag: mo match: "." From 7f3e79dc19a6a8d3fca0732f60ff878174fe3a37 Mon Sep 17 00:00:00 2001 From: mgros Date: Tue, 22 Sep 2026 01:23:11 +0200 Subject: [PATCH 103/157] add tests for intervals in German --- tests/Languages/de.rs | 1 + tests/Languages/de/ClearSpeak/intervals.rs | 149 +++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 tests/Languages/de/ClearSpeak/intervals.rs diff --git a/tests/Languages/de.rs b/tests/Languages/de.rs index 4d2be48ab..b2c36e61e 100644 --- a/tests/Languages/de.rs +++ b/tests/Languages/de.rs @@ -2,6 +2,7 @@ mod ClearSpeak { mod functions; + mod intervals; mod large_ops; mod menclose; mod mfrac; diff --git a/tests/Languages/de/ClearSpeak/intervals.rs b/tests/Languages/de/ClearSpeak/intervals.rs new file mode 100644 index 000000000..3bf359a55 --- /dev/null +++ b/tests/Languages/de/ClearSpeak/intervals.rs @@ -0,0 +1,149 @@ +//! Regression tests for German ClearSpeak interval endpoint wording. +//! Each endpoint combination should use one German connector and no untranslated words. + +use crate::common::*; +use anyhow::Result; + +#[test] +fn interval_open_open() -> Result<()> { + let expr = " + ( + c,d + ) + "; + test_ClearSpeak( + "de", + "ClearSpeak_Paren", + "Interval", + expr, + "das Intervall c bis d, nicht einschließlich c und nicht einschließlich d", + ) +} + +#[test] +fn interval_open_closed() -> Result<()> { + let expr = " + ( + c,d + ] + "; + test_ClearSpeak( + "de", + "ClearSpeak_Paren", + "Interval", + expr, + "das Intervall c bis d, nicht einschließlich c aber einschließlich d", + ) +} + +#[test] +fn interval_closed_open() -> Result<()> { + let expr = " + [ + c,d + ) + "; + test_ClearSpeak( + "de", + "ClearSpeak_Paren", + "Interval", + expr, + "das Intervall c bis d, einschließlich c aber nicht einschließlich d", + ) +} + +#[test] +fn interval_closed_closed() -> Result<()> { + let expr = " + [ + c,d + ] + "; + test_ClearSpeak( + "de", + "ClearSpeak_Paren", + "Interval", + expr, + "das Intervall c bis d, einschließlich c und d", + ) +} + +#[test] +fn interval_negative_infinity_to_open_endpoint() -> Result<()> { + let expr = " + ( + -∞,d + ) + "; + test_ClearSpeak( + "de", + "ClearSpeak_Paren", + "Interval", + expr, + "das Intervall negative unendlich bis d, nicht einschließlich d", + ) +} + +#[test] +fn interval_negative_infinity_to_closed_endpoint() -> Result<()> { + let expr = " + ( + -∞,d + ] + "; + test_ClearSpeak( + "de", + "ClearSpeak_Paren", + "Interval", + expr, + "das Intervall negative unendlich bis d, einschließlich d", + ) +} + +#[test] +fn interval_open_endpoint_to_infinity() -> Result<()> { + let expr = " + ( + c,∞ + ) + "; + test_ClearSpeak( + "de", + "ClearSpeak_Paren", + "Interval", + expr, + "das Intervall c bis unendlich, nicht einschließlich c", + ) +} + +#[test] +fn interval_closed_endpoint_to_infinity() -> Result<()> { + let expr = " + [ + c,∞ + ) + "; + test_ClearSpeak( + "de", + "ClearSpeak_Paren", + "Interval", + expr, + "das Intervall c bis unendlich, einschließlich c", + ) +} + +#[test] +fn interval_between_infinities_has_no_endpoint_qualifier() -> Result<()> { + let expr = " + ( + -∞,∞ + ) + "; + test_ClearSpeak( + "de", + "ClearSpeak_Paren", + "Interval", + expr, + "das Intervall negative unendlich bis unendlich", + ) +} From f1895d960dcd692cc3c748564aaddc12025cd067 Mon Sep 17 00:00:00 2001 From: mgros Date: Tue, 22 Sep 2026 01:41:01 +0200 Subject: [PATCH 104/157] Refine German interval descriptions and update translation rules --- Rules/Languages/de/ClearSpeak_Rules.yaml | 57 ++++++++++++++---------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/Rules/Languages/de/ClearSpeak_Rules.yaml b/Rules/Languages/de/ClearSpeak_Rules.yaml index 4c8f1d277..8d23c3502 100644 --- a/Rules/Languages/de/ClearSpeak_Rules.yaml +++ b/Rules/Languages/de/ClearSpeak_Rules.yaml @@ -532,37 +532,46 @@ - x: "*[2]" - pause: short - test: - if: "not($is_intervals_start_infinity)" + if: "not($is_intervals_start_infinity) and starts-with(name(.), 'open')" + then: + - T: "nicht einschließlich" + - x: "*[1]" + - test: + if: "not($is_intervals_start_infinity) and not(starts-with(name(.), 'open'))" then: - - test: - if: "starts-with(name(.), 'open')" - then: [T: "no"] - T: "einschließlich" - x: "*[1]" - # logic to deal with [not] arg #1 - test: - if: "not($is_intervals_start_infinity or $is_intervals_end_infinity)" - then_test: - - if: "name(.)='open-interval'" - then: [T: "ohne"] - - else_if: "name(.)='closed-interval'" - then: [T: "mit"] - else: [T: "ohne"] - # some ugly logic dealing with connectives: or, but, but, and (cleaner to be part of next clause?) - - test: - if: not($is_intervals_end_infinity) + if: "not($is_intervals_start_infinity or $is_intervals_end_infinity) and name(.)='open-interval'" then: - - test: - # there is some asymmetry to the test because of the and/or/but logic above - if: not( name(.)='open-interval' or name(.)='closed-interval' ) or $is_intervals_start_infinity - then: - - test: - if: "name(.) = 'open-interval' or name(.) = 'closed-open-interval'" - then: [T: "ohne"] - - T: "einschließlich" + - T: "und nicht einschließlich" + - x: "*[2]" + - test: + if: "not($is_intervals_start_infinity or $is_intervals_end_infinity) and name(.)='open-closed-interval'" + then: + - T: "aber einschließlich" + - x: "*[2]" + - test: + if: "not($is_intervals_start_infinity or $is_intervals_end_infinity) and name(.)='closed-open-interval'" + then: + - T: "aber nicht einschließlich" + - x: "*[2]" + - test: + if: "not($is_intervals_start_infinity or $is_intervals_end_infinity) and name(.)='closed-interval'" + then: + - T: "und" + - x: "*[2]" + - test: + if: "$is_intervals_start_infinity and not($is_intervals_end_infinity) and (name(.)='open-interval' or name(.)='closed-open-interval')" + then: + - T: "nicht einschließlich" + - x: "*[2]" + - test: + if: "$is_intervals_start_infinity and not($is_intervals_end_infinity) and (name(.)='open-closed-interval' or name(.)='closed-interval')" + then: + - T: "einschließlich" - x: "*[2]" - # onto the [not] [including]... part - name: binomial-frac-vector tag: matrix match: From ee539f2855b4e90a4fea5cb607f0c38f3480f790 Mon Sep 17 00:00:00 2001 From: mgros Date: Tue, 22 Sep 2026 01:56:01 +0200 Subject: [PATCH 105/157] Add German ClearSpeak rule and tests for pause intent --- Rules/Languages/de/ClearSpeak_Rules.yaml | 15 +++++++++++++++ tests/Languages/de/intent.rs | 21 +++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/Rules/Languages/de/ClearSpeak_Rules.yaml b/Rules/Languages/de/ClearSpeak_Rules.yaml index 8d23c3502..d2551ffef 100644 --- a/Rules/Languages/de/ClearSpeak_Rules.yaml +++ b/Rules/Languages/de/ClearSpeak_Rules.yaml @@ -1,4 +1,19 @@ --- +- name: pause + tag: "!*" + match: "not(self::m:math) and not($MatchingPause) and @data-intent-property[contains(., ':pause')]" + replace: + - with: + variables: [MatchingPause: "true()"] + replace: + - test: + - if: "contains(@data-intent-property, ':pause-long')" + then: [pause: long] + - else_if: "contains(@data-intent-property, ':pause-short')" + then: [pause: short] + else: [pause: medium] + - x: "." + - name: intent-literal-silent tag: [mi, mo, mn] match: "contains(@data-intent-property, ':silent:')" diff --git a/tests/Languages/de/intent.rs b/tests/Languages/de/intent.rs index a93e49d2d..62e711db6 100644 --- a/tests/Languages/de/intent.rs +++ b/tests/Languages/de/intent.rs @@ -3,6 +3,27 @@ use crate::common::*; use anyhow::Result; +#[test] +fn clear_speak_short_pause_intent() -> Result<()> { + // A short pause intent should survive intent inference and render as a comma. + let expr = "xy"; + test("de", "ClearSpeak", expr, "x, y") +} + +#[test] +fn clear_speak_medium_pause_intent() -> Result<()> { + // An unsuffixed pause intent requests the default medium pause. + let expr = "xy"; + test("de", "ClearSpeak", expr, "x; y") +} + +#[test] +fn clear_speak_long_pause_intent() -> Result<()> { + // A long pause intent should be preserved in ClearSpeak text output. + let expr = "xy"; + test("de", "ClearSpeak", expr, "x; y") +} + #[test] fn silent_intent() -> Result<()> { From 21fd1ebf5358a03a00d5fafeb3e4d6f6b82f2248 Mon Sep 17 00:00:00 2001 From: mgros Date: Tue, 22 Sep 2026 02:03:52 +0200 Subject: [PATCH 106/157] Add German localization for currency symbol placement and corresponding tests --- Rules/Languages/de/SharedRules/general.yaml | 18 +++++++++++++++++- tests/Languages/de/units.rs | 9 +++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Rules/Languages/de/SharedRules/general.yaml b/Rules/Languages/de/SharedRules/general.yaml index a5792c745..4c0f252fb 100644 --- a/Rules/Languages/de/SharedRules/general.yaml +++ b/Rules/Languages/de/SharedRules/general.yaml @@ -317,7 +317,23 @@ then: [x: "concat('\uF8FE', DefinitionValue($Word, 'Speech', 'PluralForms'))", ct: " "] else: [x: "concat('\uF8FE', $Word)", ct: "s"] - +# Currency symbols precede amounts in MathML but are spoken after them in German: $ 3 -> 3 dollar. +- name: currency + tag: mrow + match: "count(*)=3 and DefinitionValue(*[1], 'Speech', 'CurrencySymbols') != ''" + variables: + - IsSingular: "*[3][self::m:mn and .=1] and *[2]='\u2062'" + - CurrencyWord: "DefinitionValue(*[1], 'Speech', 'CurrencySymbols')" + replace: + - bookmark: "*[3]/@id" + - x: "*[3]" + - test: + - if: "$IsSingular" + then: [x: "$CurrencyWord"] + - else_if: "DefinitionValue($CurrencyWord, 'Speech', 'PluralForms') != ''" + then: [x: "DefinitionValue($CurrencyWord, 'Speech', 'PluralForms')"] + else: [x: "$CurrencyWord"] + - name: sin tag: mi match: ".='sin'" diff --git a/tests/Languages/de/units.rs b/tests/Languages/de/units.rs index fffd6ac5a..81467b92f 100644 --- a/tests/Languages/de/units.rs +++ b/tests/Languages/de/units.rs @@ -103,6 +103,15 @@ fn non_si_unit_plural_regression() -> Result<()> { Ok(()) } +#[test] +fn currency_symbol_precedes_amount() -> Result<()> { + // German speaks a prefixed currency symbol after its amount. + let expr = r#"$3"#; + test("de", "ClearSpeak", expr, "3 dollar")?; + test("de", "SimpleSpeak", expr, "3 dollar")?; + Ok(()) +} + /* #[test] fn si_base_with_prefixes() -> Result<()> { From 327d988b3dfc7d0e7f4b6f51601b5a0d940e723e Mon Sep 17 00:00:00 2001 From: mgros Date: Tue, 22 Sep 2026 02:05:57 +0200 Subject: [PATCH 107/157] add another test for euro --- tests/Languages/de/units.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/Languages/de/units.rs b/tests/Languages/de/units.rs index 81467b92f..1c932ae1c 100644 --- a/tests/Languages/de/units.rs +++ b/tests/Languages/de/units.rs @@ -109,6 +109,10 @@ fn currency_symbol_precedes_amount() -> Result<()> { let expr = r#"$3"#; test("de", "ClearSpeak", expr, "3 dollar")?; test("de", "SimpleSpeak", expr, "3 dollar")?; + + let expr = r#"€1"#; + test("de", "ClearSpeak", expr, "1 euro")?; + test("de", "SimpleSpeak", expr, "1 euro")?; Ok(()) } From a4083cef4adf0dd8c73b1b04c3f46a4c5517458e Mon Sep 17 00:00:00 2001 From: mgros Date: Tue, 22 Sep 2026 02:07:32 +0200 Subject: [PATCH 108/157] add another test for pound/pfund --- tests/Languages/de/units.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/Languages/de/units.rs b/tests/Languages/de/units.rs index 1c932ae1c..605ac2ed1 100644 --- a/tests/Languages/de/units.rs +++ b/tests/Languages/de/units.rs @@ -113,6 +113,10 @@ fn currency_symbol_precedes_amount() -> Result<()> { let expr = r#"€1"#; test("de", "ClearSpeak", expr, "1 euro")?; test("de", "SimpleSpeak", expr, "1 euro")?; + + let expr = r#"£4,7"#; + test("de", "ClearSpeak", expr, "4,7 pfund")?; + test("de", "SimpleSpeak", expr, "4,7 pfund")?; Ok(()) } From 692343a4b3c97ae07682c300b6198e8ac48e06be Mon Sep 17 00:00:00 2001 From: mgros Date: Tue, 22 Sep 2026 02:21:32 +0200 Subject: [PATCH 109/157] Update German ClearSpeak rules: Add support for principal logarithm (Log) and corresponding tests --- Rules/Languages/de/SharedRules/general.yaml | 6 ++++-- tests/Languages/de/ClearSpeak/functions.rs | 9 +++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Rules/Languages/de/SharedRules/general.yaml b/Rules/Languages/de/SharedRules/general.yaml index 4c0f252fb..3098d76ac 100644 --- a/Rules/Languages/de/SharedRules/general.yaml +++ b/Rules/Languages/de/SharedRules/general.yaml @@ -460,9 +460,9 @@ else: [T: "kovarianz"] # phrase('covariance' function) - - name: log # handle both log and ln (if in an mrow, 'intents' are used) + name: log # handle log, principal Log, and ln (if in an mrow, 'intents' are used) tag: mi - match: ".='log' or .='ln'" + match: ".='log' or .='Log' or .='ln'" replace: - bookmark: "@id" - test: @@ -472,6 +472,8 @@ - test: - if: ".= 'log'" then: [T: "log"] # phrase(the 'log' function is used in mathematics) + - else_if: ".= 'Log'" + then: [T: "hauptwert des logarithmus"] - else_if: "$Verbosity='Terse'" then: [spell: "'ln'"] else: [T: "natürliche logarithmus"] # phrase(the 'natural log' function is used in mathematics) diff --git a/tests/Languages/de/ClearSpeak/functions.rs b/tests/Languages/de/ClearSpeak/functions.rs index 6cb30e259..90217658e 100644 --- a/tests/Languages/de/ClearSpeak/functions.rs +++ b/tests/Languages/de/ClearSpeak/functions.rs @@ -106,6 +106,15 @@ fn simple_log() -> Result<()> { } +#[test] +fn principal_value_log() -> Result<()> { + // Uppercase Log denotes the principal-value logarithm. + let expr = "Logx"; + test("de", "ClearSpeak", expr, "der hauptwert des logarithmus, von x")?; + test("de", "SimpleSpeak", expr, "der hauptwert des logarithmus, von x")?; + Ok(()) +} + #[test] fn normal_log() -> Result<()> { let expr = "log(x+y)"; From 25059ddcd19d85abd4f7ac35eaba805cf504cbd5 Mon Sep 17 00:00:00 2001 From: mgros Date: Tue, 22 Sep 2026 02:29:39 +0200 Subject: [PATCH 110/157] Refine German ClearSpeak fraction translations and update ordinal fraction definitions --- Rules/Languages/de/definitions.yaml | 4 +++- tests/Languages/de/ClearSpeak/mfrac.rs | 16 ++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Rules/Languages/de/definitions.yaml b/Rules/Languages/de/definitions.yaml index 94ac82330..de78c7530 100644 --- a/Rules/Languages/de/definitions.yaml +++ b/Rules/Languages/de/definitions.yaml @@ -253,7 +253,9 @@ # stop when regularity begins - NumbersOrdinalFractionalPluralOnes: [ - "nulle", "erste", "hälften" + "nulle", "erste", "hälften", "Drittel", "Viertel", "Fünftel", "Sechstel", "Siebtel", "Achtel", "Neuntel", "Zehntel", + "Elftel", "Zwölftel", "Dreizehntel", "Vierzehntel", "Fünfzehntel", "Sechzehntel", + "Siebzehntel", "Achtzehntel", "Neunzehntel" ] # What to use for multiples of 10 diff --git a/tests/Languages/de/ClearSpeak/mfrac.rs b/tests/Languages/de/ClearSpeak/mfrac.rs index 0081e0197..c5744d8aa 100644 --- a/tests/Languages/de/ClearSpeak/mfrac.rs +++ b/tests/Languages/de/ClearSpeak/mfrac.rs @@ -19,7 +19,7 @@ fn common_fraction_thirds() -> Result<()> { let expr = " 2 3 "; - test("de", "ClearSpeak", expr, "2 dritte")?; + test("de", "ClearSpeak", expr, "2 Drittel")?; return Ok(()); } @@ -29,8 +29,8 @@ fn common_fraction_tenths() -> Result<()> { let expr = " 17 10 "; - test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr, "17 zehnte")?; - test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Ordinal")], expr, "17 zehnte")?; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr, "17 Zehntel")?; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Ordinal")], expr, "17 Zehntel")?; return Ok(()); } @@ -42,7 +42,7 @@ fn not_ClearSpeak_common_fraction_tenths() -> Result<()> { 89 10 "; test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr, "89 durch 10")?; - test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Ordinal")], expr, "89 zehnte")?; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Ordinal")], expr, "89 Zehntel")?; return Ok(()); } @@ -172,14 +172,14 @@ fn nested_simple_fractions() -> Result<()> { "; - test_prefs("de", "ClearSpeak", vec![("ClearSpeak_Fractions", "Auto")], expr, "1 hälfte durch 2 dritte")?; - test_prefs("de", "ClearSpeak", vec![("ClearSpeak_Fractions", "Ordinal")], expr, "1 hälfte durch 2 dritte")?; + test_prefs("de", "ClearSpeak", vec![("ClearSpeak_Fractions", "Auto")], expr, "1 hälfte durch 2 Drittel")?; + test_prefs("de", "ClearSpeak", vec![("ClearSpeak_Fractions", "Ordinal")], expr, "1 hälfte durch 2 Drittel")?; test_prefs("de", "ClearSpeak", vec![("ClearSpeak_Fractions", "Over")], expr, "1 durch 2 durch 2 durch 3")?; test_prefs("de", "ClearSpeak", vec![("ClearSpeak_Fractions", "FracOver")], expr, "der bruch der bruch 1 durch 2 durch der bruch 2 durch 3")?; test_prefs("de", "ClearSpeak", vec![("ClearSpeak_Fractions", "General")], expr, "der bruch mit zähler der bruch mit zähler 1; und nenner 2; und nenner der bruch mit zähler 2; und nenner 3")?; - test_prefs("de", "ClearSpeak", vec![("ClearSpeak_Fractions", "EndFrac")], expr, "1 hälfte durch 2 dritte")?; + test_prefs("de", "ClearSpeak", vec![("ClearSpeak_Fractions", "EndFrac")], expr, "1 hälfte durch 2 Drittel")?; test_prefs("de", "ClearSpeak", vec![("ClearSpeak_Fractions", "GeneralEndFrac")], expr, "der bruch mit zähler der bruch mit zähler 1; und nenner 2; ende des bruchs; und nenner der bruch mit zähler 2; und nenner 3; ende des bruchs; ende des bruchs")?; test_prefs("de", "ClearSpeak", vec![("ClearSpeak_Fractions", "OverEndFrac")], expr, @@ -205,7 +205,7 @@ fn semi_nested_fraction() -> Result<()> { "; - test("de", "ClearSpeak", expr, "2 dritte x durch 6")?; + test("de", "ClearSpeak", expr, "2 Drittel x durch 6")?; return Ok(()); } From 5df8e8123eca59dd945f5779afb29e55518f2ee0 Mon Sep 17 00:00:00 2001 From: mgros Date: Tue, 22 Sep 2026 03:18:00 +0200 Subject: [PATCH 111/157] German ClearSpeak: subset & superset --- Rules/Languages/de/unicode-full.yaml | 8 ++++---- Rules/Languages/de/unicode.yaml | 4 ++-- tests/Languages/de/ClearSpeak/sets.rs | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/Rules/Languages/de/unicode-full.yaml b/Rules/Languages/de/unicode-full.yaml index 8a98107f8..871e4e434 100644 --- a/Rules/Languages/de/unicode-full.yaml +++ b/Rules/Languages/de/unicode-full.yaml @@ -1102,13 +1102,13 @@ - "⊆": # 0x2286 - test: if: "$Verbosity!='Terse'" - then: [T: "ist ein"] # (en: 'is a', google translation) - - T: "Teilmenge oder gleich" # (en: 'subset of or equal to', MathPlayer: 'Teilmenge von odre gleich', google: 'teilmenge von oder gleich') + then: [T: "ist eine"] # (en: 'is a', google translation) + - T: "Teilmenge von oder gleich" # (en: 'subset of or equal to', MathPlayer: 'Teilmenge von odre gleich', google: 'teilmenge von oder gleich') - "⊇": # 0x2287 - test: if: "$Verbosity!='Terse'" - then: [T: "ist ein"] # (en: 'is a', google translation) - - T: "Obermenge oder gleich" # (en: 'superset of or equal to', MathPlayer: 'Obermenge von oder gleich', google: 'superset von oder gleich') + then: [T: "ist eine"] # (en: 'is a', google translation) + - T: "Obermenge von oder gleich" # (en: 'superset of or equal to', MathPlayer: 'Obermenge von oder gleich', google: 'superset von oder gleich') - "⊈": # 0x2288 - test: if: "$Verbosity!='Terse'" diff --git a/Rules/Languages/de/unicode.yaml b/Rules/Languages/de/unicode.yaml index bdd89fc76..bee3b6e7b 100644 --- a/Rules/Languages/de/unicode.yaml +++ b/Rules/Languages/de/unicode.yaml @@ -431,12 +431,12 @@ - test: if: "$Verbosity!='Terse'" then: [T: "ist eine"] # (en: 'is a', google translation) - - T: "teilmenge oder gleich" # (en: 'subset of or equal to', MathPlayer: 'Teilmenge von odre gleich', google: 'teilmenge von oder gleich') + - T: "teilmenge von oder gleich" # (en: 'subset of or equal to', MathPlayer: 'Teilmenge von odre gleich', google: 'teilmenge von oder gleich') - "⊇": # 0x2287 - test: if: "$Verbosity!='Terse'" then: [T: "ist eine"] # (en: 'is a', google translation) - - T: "obermenge oder gleich" # (en: 'superset of or equal to', MathPlayer: 'Obermenge von oder gleich', google: 'superset von oder gleich') + - T: "obermenge von oder gleich" # (en: 'superset of or equal to', MathPlayer: 'Obermenge von oder gleich', google: 'superset von oder gleich') # --- restored short definitions that differ from unicode-full --- - "–": [T: "halbgeviertstrich"] # 0x2013 (SRE: 'En Dash') diff --git a/tests/Languages/de/ClearSpeak/sets.rs b/tests/Languages/de/ClearSpeak/sets.rs index e8911f33f..e9f70e3cc 100644 --- a/tests/Languages/de/ClearSpeak/sets.rs +++ b/tests/Languages/de/ClearSpeak/sets.rs @@ -230,6 +230,24 @@ fn element_alone() -> Result<()> { } +#[test] +fn subset_and_superset_or_equal_include_von() -> Result<()> { + // Both inclusive set relations should form complete German relational phrases. + test( + "de", + "ClearSpeak", + "A⊆B", + "groß a, ist eine teilmenge von oder gleich, groß b", + )?; + test( + "de", + "ClearSpeak", + "A⊇B", + "groß a, ist eine obermenge von oder gleich, groß b", + )?; + Ok(()) +} + #[test] fn element_under_sum() -> Result<()> { let expr = " From 88404bfa21276daf86a4883f45d79483571ea225 Mon Sep 17 00:00:00 2001 From: mgros Date: Tue, 22 Sep 2026 03:28:13 +0200 Subject: [PATCH 112/157] de: fix chemical state names --- Rules/Languages/de/SharedRules/general.yaml | 8 ++--- tests/Languages/de/chemistry.rs | 34 +++++++++++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/Rules/Languages/de/SharedRules/general.yaml b/Rules/Languages/de/SharedRules/general.yaml index 3098d76ac..9f4807946 100644 --- a/Rules/Languages/de/SharedRules/general.yaml +++ b/Rules/Languages/de/SharedRules/general.yaml @@ -1005,12 +1005,12 @@ - bookmark: "*[1]/@id" - test: - if: ".='s'" - then: [T: "solide"] # phrase(Boron is a 'solid' in its natural state) + then: [T: "fest"] # phrase(Boron is a 'solid' in its natural state) - else_if: ".='l'" - then: [T: "flüssigkeit"] # phrase(water is a 'liquid') + then: [T: "flüssig"] # phrase(water is a 'liquid') - else_if: ".='g'" - then: [T: "gas"] # phrase(hydrogen is a 'gas' ) - else: [T: "wässrige"] # phrase(an 'aqueous' solution is contained in water) + then: [T: "gasförmig"] # phrase(hydrogen is a 'gas' ) + else: [T: "wässrig"] # phrase(an 'aqueous' solution is contained in water) - pause: short - name: chemical-formula-operator-bond diff --git a/tests/Languages/de/chemistry.rs b/tests/Languages/de/chemistry.rs index 14bb1bfd1..63c46302d 100644 --- a/tests/Languages/de/chemistry.rs +++ b/tests/Languages/de/chemistry.rs @@ -40,6 +40,40 @@ fn sulfate() -> Result<()> { } +#[test] +fn chemical_state_names_are_german_adjectives() -> Result<()> { + // Chemical state suffixes should use the standard German adjectival names. + test_prefs( + "de", + "ClearSpeak", + vec![("Verbosity", "Terse")], + "Na(s)", + "groß n a, fest", + )?; + test_prefs( + "de", + "ClearSpeak", + vec![("Verbosity", "Terse")], + "H2O(l)", + "groß h, 2 groß o, flüssig", + )?; + test_prefs( + "de", + "ClearSpeak", + vec![("Verbosity", "Terse")], + "HCl(g)", + "groß h, groß c l, gasförmig", + )?; + test_prefs( + "de", + "ClearSpeak", + vec![("Verbosity", "Terse")], + "HCl(aq)", + "groß h, groß c l, wässrig", + )?; + Ok(()) +} + /* // ignored below #[test] From c17671cb3b7fca7609f54603015ed7fef036b155 Mon Sep 17 00:00:00 2001 From: mgros Date: Tue, 22 Sep 2026 03:50:13 +0200 Subject: [PATCH 113/157] de: fix chemical reaction arrow --- Rules/Languages/de/SharedRules/general.yaml | 5 +--- tests/Languages/de/chemistry.rs | 26 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/Rules/Languages/de/SharedRules/general.yaml b/Rules/Languages/de/SharedRules/general.yaml index 9f4807946..b600b517f 100644 --- a/Rules/Languages/de/SharedRules/general.yaml +++ b/Rules/Languages/de/SharedRules/general.yaml @@ -1044,10 +1044,7 @@ - bookmark: "@id" - test: - if: ".='→' or .='⟶'" - then_test: - if: "$Verbosity='Terse'" - then: [T: "formen"] # phrase(hydrogen and oxygen 'forms' water ) - else: [T: "reagiert auf die form"] # phrase(hydrogen and oxygen 'reacts to form' water) + then: [T: "ergibt"] # phrase(hydrogen and oxygen 'forms/reacts to form' water) - else_if: ".='⇌' or .='🣑'" # U+01F8D1 then: [T: "ist im gleichgewicht mit"] # phrase(a reactant 'is in equilibrium with' a product) - else_if: ".='🣓'" # U+1F8D3 diff --git a/tests/Languages/de/chemistry.rs b/tests/Languages/de/chemistry.rs index 63c46302d..25b888ec2 100644 --- a/tests/Languages/de/chemistry.rs +++ b/tests/Languages/de/chemistry.rs @@ -74,6 +74,32 @@ fn chemical_state_names_are_german_adjectives() -> Result<()> { Ok(()) } +#[test] +fn reaction_arrow_uses_idiomatic_german() -> Result<()> { + // A reaction arrow should describe the resulting products idiomatically in German. + let expr = " + 2HCl+2Na + → + 2NaCl+ + H2 + "; + test_prefs( + "de", + "SimpleSpeak", + vec![("Verbosity", "Terse")], + expr, + "2, groß h, groß c l; plus 2 groß n a; ergibt; 2, groß n a, groß c l; plus groß h, 2", + )?; + test_prefs( + "de", + "SimpleSpeak", + vec![("Verbosity", "Verbose")], + expr, + "2, groß h, groß c l; plus 2 groß n a; ergibt; 2, groß n a, groß c l; plus groß h, index 2", + )?; + Ok(()) +} + /* // ignored below #[test] From 771dc68e4e836404e0c52b964969e6c078d0d7dc Mon Sep 17 00:00:00 2001 From: mgros Date: Tue, 22 Sep 2026 04:09:31 +0200 Subject: [PATCH 114/157] de: fix integer exponentiation --- Rules/Languages/de/ClearSpeak_Rules.yaml | 8 +------- Rules/Languages/de/SimpleSpeak_Rules.yaml | 7 ++----- tests/Languages/de/shared.rs | 13 +++++++++++++ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/Rules/Languages/de/ClearSpeak_Rules.yaml b/Rules/Languages/de/ClearSpeak_Rules.yaml index d2551ffef..01f8c9eba 100644 --- a/Rules/Languages/de/ClearSpeak_Rules.yaml +++ b/Rules/Languages/de/ClearSpeak_Rules.yaml @@ -326,13 +326,7 @@ replace: - x: "*[1]" - T: "hoch" - - test: - if: "*[2][.>0]" - then: [x: "ToOrdinal(*[2])"] - else: [x: "*[2]"] - - test: - if: "$ClearSpeak_Exponents != 'Ordinal'" - then: [T: "hoch"] + - x: "*[2]" - name: simple-negative-integer tag: power diff --git a/Rules/Languages/de/SimpleSpeak_Rules.yaml b/Rules/Languages/de/SimpleSpeak_Rules.yaml index e04749887..d23a47d7c 100644 --- a/Rules/Languages/de/SimpleSpeak_Rules.yaml +++ b/Rules/Languages/de/SimpleSpeak_Rules.yaml @@ -208,11 +208,8 @@ match: "*[2][self::m:mn][not(contains(., '.'))]" replace: - x: "*[1]" - - T: "zu dem" # phrase(15 raised 'to the' second power equals 225) - - test: - if: "*[2][.>0]" - then: [x: "ToOrdinal(*[2])"] - else: [x: "*[2]"] + - T: "hoch" # phrase(15 raised 'to the' fourth power equals 50625) + - x: "*[2]" - name: simple-negative-integer tag: power match: diff --git a/tests/Languages/de/shared.rs b/tests/Languages/de/shared.rs index 34518d9e0..53d1468db 100644 --- a/tests/Languages/de/shared.rs +++ b/tests/Languages/de/shared.rs @@ -3,6 +3,19 @@ use crate::common::*; use anyhow::Result; +#[test] +fn ordinary_integer_powers() -> Result<()> { + // Ordinary integer exponents use the idiomatic German "hoch" construction. + let fourth_power = "x4"; + test("de", "ClearSpeak", fourth_power, "x hoch 4")?; + test("de", "SimpleSpeak", fourth_power, "x hoch 4")?; + + let zeroth_power = "x0"; + test("de", "ClearSpeak", zeroth_power, "x hoch 0")?; + test("de", "SimpleSpeak", zeroth_power, "x hoch 0")?; + Ok(()) +} + #[test] fn modified_vars() -> Result<()> { let expr = " From c6a33fad46c8a3cc83c91c771160113c381023ee Mon Sep 17 00:00:00 2001 From: mgros Date: Tue, 22 Sep 2026 04:27:02 +0200 Subject: [PATCH 115/157] de: fix exponentiation by arbitrary exponents --- Rules/Languages/de/ClearSpeak_Rules.yaml | 4 ---- Rules/Languages/de/SimpleSpeak_Rules.yaml | 1 - tests/Languages/de/shared.rs | 9 +++++++++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Rules/Languages/de/ClearSpeak_Rules.yaml b/Rules/Languages/de/ClearSpeak_Rules.yaml index 01f8c9eba..c1dd81eb5 100644 --- a/Rules/Languages/de/ClearSpeak_Rules.yaml +++ b/Rules/Languages/de/ClearSpeak_Rules.yaml @@ -349,10 +349,6 @@ - x: "*[1]" - T: "hoch" - x: "*[2]" - - pronounce: [text: "-th", ipa: "θ", sapi5: "th", eloquence: "T"] - - test: - if: "$ClearSpeak_Exponents != 'Ordinal'" - then: [T: "hoch"] # match nested exponent, where the nested exponent is has the power 2 or 3 (n below) # [xxx]^n, - [xxx]^n, [xxx] var^n, -[xxx] var^n diff --git a/Rules/Languages/de/SimpleSpeak_Rules.yaml b/Rules/Languages/de/SimpleSpeak_Rules.yaml index d23a47d7c..4d48fd27e 100644 --- a/Rules/Languages/de/SimpleSpeak_Rules.yaml +++ b/Rules/Languages/de/SimpleSpeak_Rules.yaml @@ -226,7 +226,6 @@ - x: "*[1]" - T: "hoch" # phrase(15 raised 'to the' second power equals 225) - x: "*[2]" - - pronounce: [text: "-th", ipa: "θ", sapi5: "th", eloquence: "T"] - name: simple tag: power diff --git a/tests/Languages/de/shared.rs b/tests/Languages/de/shared.rs index 53d1468db..d69acf25a 100644 --- a/tests/Languages/de/shared.rs +++ b/tests/Languages/de/shared.rs @@ -16,6 +16,15 @@ fn ordinary_integer_powers() -> Result<()> { Ok(()) } +#[test] +fn variable_powers() -> Result<()> { + // Variable exponents should not acquire an English ordinal suffix or a second "hoch". + let expr = "2x"; + test("de", "ClearSpeak", expr, "2 hoch x")?; + test("de", "SimpleSpeak", expr, "2 hoch x")?; + Ok(()) +} + #[test] fn modified_vars() -> Result<()> { let expr = " From 6f24b27a37cb986e1434c5dc76aeb65adc45f66d Mon Sep 17 00:00:00 2001 From: mgros Date: Tue, 22 Sep 2026 04:37:54 +0200 Subject: [PATCH 116/157] de: add vector norm --- Rules/Languages/de/definitions.yaml | 1 + tests/Languages/de/intent.rs | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/Rules/Languages/de/definitions.yaml b/Rules/Languages/de/definitions.yaml index de78c7530..163c3f86d 100644 --- a/Rules/Languages/de/definitions.yaml +++ b/Rules/Languages/de/definitions.yaml @@ -29,6 +29,7 @@ "plus": "infix=plus || prefix=positiv", "real-part": "function=der reale teil", "transpose": "postfix=transponieren || function=transponieren", + "magnitude": "function=; Norm: Norm: Norm; Ende Norm", "norm": "function=; norm: norm: norm; ende norm", "trace": "function=; spur : spur: die spur; ende spur", "dimension": "function=; dimension : dimension: die dimension; ende dimension", diff --git a/tests/Languages/de/intent.rs b/tests/Languages/de/intent.rs index 62e711db6..d31af9d9b 100644 --- a/tests/Languages/de/intent.rs +++ b/tests/Languages/de/intent.rs @@ -3,6 +3,15 @@ use crate::common::*; use anyhow::Result; +#[test] +fn magnitude_is_localized_as_norm() -> Result<()> { + // Double bars infer the magnitude intent, which should use the German term "Norm". + let expr = "‖x‖"; + test("de", "ClearSpeak", expr, "Norm von x")?; + test("de", "SimpleSpeak", expr, "Norm von x")?; + Ok(()) +} + #[test] fn clear_speak_short_pause_intent() -> Result<()> { // A short pause intent should survive intent inference and render as a comma. From 11736b5bb3638ae30ab955a1a8cdfee8e196333d Mon Sep 17 00:00:00 2001 From: mgros Date: Tue, 22 Sep 2026 04:42:03 +0200 Subject: [PATCH 117/157] de: fix "transpose" --- Rules/Languages/de/definitions.yaml | 2 +- tests/Languages/de/shared.rs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Rules/Languages/de/definitions.yaml b/Rules/Languages/de/definitions.yaml index 163c3f86d..427eec726 100644 --- a/Rules/Languages/de/definitions.yaml +++ b/Rules/Languages/de/definitions.yaml @@ -28,7 +28,7 @@ "minus": "infix=minus || prefix=negativ", "plus": "infix=plus || prefix=positiv", "real-part": "function=der reale teil", - "transpose": "postfix=transponieren || function=transponieren", + "transpose": "postfix=transponiert || function=die Transponierte", "magnitude": "function=; Norm: Norm: Norm; Ende Norm", "norm": "function=; norm: norm: norm; ende norm", "trace": "function=; spur : spur: die spur; ende spur", diff --git a/tests/Languages/de/shared.rs b/tests/Languages/de/shared.rs index d69acf25a..93d570108 100644 --- a/tests/Languages/de/shared.rs +++ b/tests/Languages/de/shared.rs @@ -3,6 +3,18 @@ use crate::common::*; use anyhow::Result; +#[test] +fn transpose_uses_grammatical_german_forms() -> Result<()> { + // A superscript T uses the participle, while a function intent names the transpose. + let postfix = "AT"; + test("de", "ClearSpeak", postfix, "groß a transponiert")?; + test("de", "SimpleSpeak", postfix, "groß a transponiert")?; + + let function = "A"; + test("de", "ClearSpeak", function, "die Transponierte von groß a")?; + Ok(()) +} + #[test] fn ordinary_integer_powers() -> Result<()> { // Ordinary integer exponents use the idiomatic German "hoch" construction. From bb775c5a7b8d5a9d50b65629106023bdefbed1df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Tue, 22 Sep 2026 08:28:44 +0200 Subject: [PATCH 118/157] replace lamda with lambda (#789) * replace lamda with lambda * fix line endings --- Rules/Languages/de/unicode.yaml | 2 +- Rules/Languages/id/unicode-full.yaml | 4 ++-- Rules/Languages/id/unicode.yaml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Rules/Languages/de/unicode.yaml b/Rules/Languages/de/unicode.yaml index bee3b6e7b..f8b0ec641 100644 --- a/Rules/Languages/de/unicode.yaml +++ b/Rules/Languages/de/unicode.yaml @@ -214,7 +214,7 @@ - "θ": [T: "theta"] # 0x3b8 - "ι": [T: "iota"] # 0x3b9 (google: 'jota') - "κ": [T: "kappa"] # 0x3ba - - "λ": [T: "lamda"] # 0x3bb (en: 'lambda', google: 'lambda') + - "λ": [T: "lambda"] # 0x3bb (en: 'lambda', google: 'lambda') - "μ": [T: "mü"] # 0x3bc - "ν": [T: "nü"] # 0x3bd - "ξ": [T: "xi"] # 0x3be (en: 'zai', google: 'zai') diff --git a/Rules/Languages/id/unicode-full.yaml b/Rules/Languages/id/unicode-full.yaml index 5591060fd..65af01886 100644 --- a/Rules/Languages/id/unicode-full.yaml +++ b/Rules/Languages/id/unicode-full.yaml @@ -314,7 +314,7 @@ - test: if: "($Blind or $Verbosity!='Terse')" then: [T: huruf besar] - - T: lamda + - T: lambda - "Μ": # 0x39c - test: if: "($Blind or $Verbosity!='Terse')" @@ -400,7 +400,7 @@ - "θ": [T: theta] # 0x3b8 - "ι": [T: iota] # 0x3b9 - "κ": [T: kappa] # 0x3ba - - "λ": [T: lamda] # 0x3bb + - "λ": [T: lambda] # 0x3bb - "μ": [T: mu] # 0x3bc - "ν": [T: nu] # 0x3bd - "ξ": [T: zai] # 0x3be diff --git a/Rules/Languages/id/unicode.yaml b/Rules/Languages/id/unicode.yaml index 11f586349..ebc0a1909 100644 --- a/Rules/Languages/id/unicode.yaml +++ b/Rules/Languages/id/unicode.yaml @@ -243,7 +243,7 @@ - "θ": [T: theta] # 0x3b8 - "ι": [T: iota] # 0x3b9 - "κ": [T: kappa] # 0x3ba -- "λ": [T: lamda] # 0x3bb +- "λ": [T: lambda] # 0x3bb - "μ": [T: mu] # 0x3bc - "ν": [T: nu] # 0x3bd - "ξ": [T: zai] # 0x3be From 24eaee398ca4b5c6bc308efcfa66c73dbfd888d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dziwisz?= Date: Tue, 22 Sep 2026 08:31:10 +0200 Subject: [PATCH 119/157] =?UTF-8?q?fix(pl):=20przywr=C3=B3=C4=87=20szablon?= =?UTF-8?q?y=20sum=20i=20iloczyn=C3=B3w=20po=20naprawie=20s=C5=82owa=20?= =?UTF-8?q?=C5=82=C4=85cz=C4=85cego=20(#783)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Rules/Languages/pl/definitions.yaml | 19 +++++++++++-------- tests/Languages/pl/definitions.rs | 8 ++++---- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Rules/Languages/pl/definitions.yaml b/Rules/Languages/pl/definitions.yaml index 0f212c4e4..e3a8bc1db 100644 --- a/Rules/Languages/pl/definitions.yaml +++ b/Rules/Languages/pl/definitions.yaml @@ -60,14 +60,12 @@ ### Sequence and Series - # UWAGA: NIE używamy tu szablonów arności ("| po | od,do"), choć angielski je ma. - # Powód (zmierzone 31.08.2026): intent_function_glue_before w src/infer_intent.rs - # zwraca dla ostatniego argumentu ZASZYTE W KODZIE angielskie "of", więc polskie - # wyjście brzmiałoby "suma po i of x". To defekt rdzenia dotyczący każdego języka - # poza angielskim; węgierski uniknął go tak samo, zostawiając prostą postać. - # Separator binarny (jedna opcja "| słowo") działa poprawnie i jest używany niżej. - "sum":"function=suma", - "product":"function=iloczyn", + # Szablony arności działają od czasu, gdy słowo łączące przestało być zaszyte + # w kodzie (issue #739): ostatni argument poprzedza teraz FunctionApplicationWord + # z tego pliku, czyli polskie "z". Słowa "przez" i "od,do" dobrane tak, jak mówią + # o tym istniejące reguły dużych operatorów ("suma przez wielka s z i"). + "sum":"function=suma | przez | od,do", + "product":"function=iloczyn | przez | od,do", ### Elementary classical functions @@ -298,6 +296,11 @@ "chemistry-concentration": "function=; stężenie: stężenie: stężenie; koniec stężenia", } + # The connector word to say for functional 'IntentMappings' (in English, "of") + # This is likely the word used for U+2061 in unicode.yaml, but for technical reasons needs to be defined here + # vector of length=1 because scalars not supported +- FunctionApplicationWord: ["z"] + # Names of functions that in terse mode don't say "of" (or it's equivalent in other languages) - TerseFunctionNames: { "divergence", "gradient", "curl" diff --git a/tests/Languages/pl/definitions.rs b/tests/Languages/pl/definitions.rs index 338f7ff95..d009d9120 100644 --- a/tests/Languages/pl/definitions.rs +++ b/tests/Languages/pl/definitions.rs @@ -422,7 +422,7 @@ fn sequence_and_series_intents() -> Result<()> { x "#, - "suma z i przecinek, x", + "suma przez i z x", ), ( "sum-3", @@ -434,7 +434,7 @@ fn sequence_and_series_intents() -> Result<()> { x "#, - "suma z i przecinek, n przecinek, x", + "suma od i do n z x", ), ( "product-1", @@ -455,7 +455,7 @@ fn sequence_and_series_intents() -> Result<()> { x "#, - "iloczyn z i przecinek, x", + "iloczyn przez i z x", ), ( "product-3", @@ -467,7 +467,7 @@ fn sequence_and_series_intents() -> Result<()> { x "#, - "iloczyn z i przecinek, n przecinek, x", + "iloczyn od i do n z x", ), ]; From e46e7dbcc89f11d304de660ca1444fdf8322acb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Tue, 22 Sep 2026 08:42:49 +0200 Subject: [PATCH 120/157] Refactor/simplify prefs rs (#780) * remove pointless cloning * simplify logic flow of is_user_pref * simplify path joins * Add comment to clarify update condition Added a comment to prevent unnecessary updates if the value hasn't changed. --------- Co-authored-by: NSoiffer --- src/prefs.rs | 68 ++++++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/src/prefs.rs b/src/prefs.rs index 89748119f..f515ca483 100644 --- a/src/prefs.rs +++ b/src/prefs.rs @@ -133,12 +133,11 @@ impl Preferences{ verify_keys(doc, "Other", file_name)?; } - let prefs = &mut base_prefs.prefs; - add_prefs(prefs, &doc["Speech"], "", file_name); - add_prefs(prefs, &doc["Navigation"], "", file_name); - add_prefs(prefs, &doc["Braille"], "", file_name); - add_prefs(prefs, &doc["Other"], "", file_name); - return Ok( Preferences{ prefs: prefs.to_owned() } ); + add_prefs(&mut base_prefs.prefs, &doc["Speech"], "", file_name); + add_prefs(&mut base_prefs.prefs, &doc["Navigation"], "", file_name); + add_prefs(&mut base_prefs.prefs, &doc["Braille"], "", file_name); + add_prefs(&mut base_prefs.prefs, &doc["Other"], "", file_name); + return Ok(base_prefs); @@ -317,8 +316,7 @@ impl PreferenceManager { let mut prefs = Preferences::default(); - let mut system_prefs_file = self.rules_dir.to_path_buf(); - system_prefs_file.push("prefs.yaml"); + let system_prefs_file: PathBuf = self.rules_dir.join("prefs.yaml"); if is_file_shim(&system_prefs_file) { let defaults = DEFAULT_USER_PREFERENCES.with(|defaults| defaults.clone()); prefs = Preferences::read_prefs_file(&system_prefs_file, defaults)?; @@ -363,11 +361,11 @@ impl PreferenceManager { let language = self.pref_to_string("Language"); let language = if language.as_str() == "Auto" {"en"} else {language.as_str()}; // avoid 'temp value dropped while borrowed' error - let language_dir = rules_dir.to_path_buf().join("Languages"); + let language_dir = rules_dir.join("Languages"); self.set_speech_files(&language_dir, language, None)?; // also sets style file let braille_code = self.pref_to_string("BrailleCode"); - let braille_dir = rules_dir.to_path_buf().join("Braille"); + let braille_dir = rules_dir.join("Braille"); self.set_braille_files(&braille_dir, &braille_code)?; return Ok(()); } @@ -426,12 +424,12 @@ impl PreferenceManager { let new_language = new_prefs.prefs.get("Language").unwrap(); debug!("set_files_based_on_changes: old_language={old_language:?}, new_language={new_language:?}"); if old_language != new_language { - let language_dir = self.rules_dir.to_path_buf().join("Languages"); + let language_dir = self.rules_dir.join("Languages"); self.set_speech_files(&language_dir, new_language.as_str().unwrap(), None)?; // also sets style file } else { let old_speech_style = self.user_prefs.prefs.get("SpeechStyle").unwrap(); let new_speech_style = new_prefs.prefs.get("SpeechStyle").unwrap(); - let language_dir = self.rules_dir.to_path_buf().join("Languages"); + let language_dir = self.rules_dir.join("Languages"); if old_speech_style != new_speech_style { self.set_speech_files(&language_dir, new_language.as_str().unwrap(), new_speech_style.as_str())?; } @@ -440,7 +438,7 @@ impl PreferenceManager { let old_braille_code = self.user_prefs.prefs.get("BrailleCode").unwrap(); let new_braille_code = new_prefs.prefs.get("BrailleCode").unwrap(); if old_braille_code != new_braille_code { - let braille_code_dir = self.rules_dir.to_path_buf().join("Braille"); + let braille_code_dir = self.rules_dir.join("Braille"); self.set_braille_files(&braille_code_dir, new_braille_code.as_str().unwrap())?; // also sets style file } @@ -566,7 +564,7 @@ impl PreferenceManager { let mut alternative_style_file = None; // back up in case we don't find the target style in lang_dir let looking_for_style_file = file_name.ends_with("_Rules.yaml"); for os_path in lang_dir.ancestors() { // ancestor returns self and ancestors - let path = PathBuf::from(os_path).join(file_name); + let path = os_path.join(file_name); // debug!("find_file: checking file: {}", path.to_string_lossy()); if is_file_shim(&path) { // we make an exception for definitions.yaml -- there a language specific checks for Hundreds, etc @@ -634,8 +632,7 @@ impl PreferenceManager { fn get_language_dir(rules_dir: &Path, lang: &str, default_lang: Option<&str>) -> Result { // return 'Rules/Language/fr', 'Rules/Language/en/gb', etc, if they exist. // fall back to main language, and then to default_dir if language dir doesn't exist - let mut full_path = rules_dir.to_path_buf(); - full_path.push(lang.replace('-', std::path::MAIN_SEPARATOR_STR)); + let full_path = rules_dir.join(lang.replace('-', std::path::MAIN_SEPARATOR_STR)); for parent in full_path.ancestors() { if parent == rules_dir { break; @@ -710,21 +707,17 @@ impl PreferenceManager { !value.chars().all(|c| matches!(c, 'a'..='z' | 'A'..='Z' | '_' | '-')) { bail!("{} is an invalid value! Must contains only ascii letters, '_', or'-'", key); } - + // don't do an update if the value hasn't changed - let mut is_user_pref = true; - if let Some(pref_value) = self.api_prefs.prefs.get(key) { - if pref_value.as_str().unwrap() != value { - is_user_pref = false; - self.reset_files_from_preference_change(key, value)?; - } - } else if let Some(pref_value) = self.user_prefs.prefs.get(key) { - if pref_value.as_str().unwrap() != value { - self.reset_files_from_preference_change(key, value)?; - } - } else { - bail!("{} is an unknown MathCAT preference!", key); + let api_pref: Option<&Yaml> = self.api_prefs.prefs.get(key); + let Some(pref_value) = api_pref.or_else(|| self.user_prefs.prefs.get(key)) else { + bail!("{key} is an unknown MathCAT preference!"); + }; + if pref_value.as_str().unwrap() == value { + return Ok( () ); } + let is_user_pref: bool = api_pref.is_none(); + self.reset_files_from_preference_change(key, value)?; // debug!("Setting ({}) {} to '{}'", if is_user_pref {"user"} else {"sys"}, key, value); if is_user_pref { @@ -755,7 +748,7 @@ impl PreferenceManager { } let changed_pref = if changed_pref == "LanguageAuto" {"Language"} else {changed_pref}; - let language_dir = self.rules_dir.to_path_buf().join("Languages"); + let language_dir = self.rules_dir.join("Languages"); match changed_pref { "Language" => { self.set_speech_files(&language_dir, changed_value, None)?; @@ -768,7 +761,7 @@ impl PreferenceManager { crate::speech::invalidate_speech_style_caches(); }, "BrailleCode" => { - let braille_dir = self.rules_dir.to_path_buf().join("Braille"); + let braille_dir = self.rules_dir.join("Braille"); self.set_braille_files(&braille_dir, changed_value)?; crate::speech::invalidate_braille_caches(); }, @@ -1170,6 +1163,19 @@ cfg_if::cfg_if! {if #[cfg(not(feature = "include-zip"))] { }); } + /// Setting `TTS` to its existing value should not copy it from API preferences into user preferences. + #[test] + fn unchanged_api_string_pref_is_noop() { + let mut pref_manager = PreferenceManager { + api_prefs: Preferences::api_defaults(), + ..PreferenceManager::default() + }; + + pref_manager.set_string_pref("TTS", "none").unwrap(); + + assert!(!pref_manager.user_prefs.prefs.contains_key("TTS")); + } + /// #262: MathCAT must notice when a rule file on disk changes and reload it. /// This copies the rule files it needs (`en`, `zz`, and `Nemeth`) into a uniquely-named /// temp dir, so the test can freely modify files and run in parallel without touching the From 8ef55c415e68400fe24a7bacaa703ea8b3720096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Rand=C3=A9n?= Date: Tue, 8 Sep 2026 10:39:34 +0200 Subject: [PATCH 121/157] ci: add scheduled workflow to alert translators of English rule changes --- .github/translator-alert.config | 7 + .github/workflows/translator-alert.yml | 268 +++++++++++++++++++++++++ 2 files changed, 275 insertions(+) create mode 100644 .github/translator-alert.config create mode 100644 .github/workflows/translator-alert.yml diff --git a/.github/translator-alert.config b/.github/translator-alert.config new file mode 100644 index 000000000..1ed950460 --- /dev/null +++ b/.github/translator-alert.config @@ -0,0 +1,7 @@ +# Add your GitHub username (including '@') to the 'notify' list to receive alerts when English rules change. +# Append to the existing list on the same line, separated by a single space (e.g. notify=@user1 @user2). +# You do not have to add your Github username if you are already in the mathcat-translators group. + +paths=Rules/Languages/en/ +exclude=Rules/Languages/en/gb/ +notify=@johannes-spsm @daisy/mathcat-translators \ No newline at end of file diff --git a/.github/workflows/translator-alert.yml b/.github/workflows/translator-alert.yml new file mode 100644 index 000000000..c8c54c397 --- /dev/null +++ b/.github/workflows/translator-alert.yml @@ -0,0 +1,268 @@ +name: Alert Translators on English File Changes + +permissions: + contents: read + discussions: write + +on: + schedule: + - cron: '3 14 1,15 * *' + +jobs: + alert: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v7 + with: + fetch-depth: 0 + + - name: Load alert config + id: config + run: | + CONFIG_FILE=".github/translator-alert.config" + + PATHS=$(grep '^paths=' "$CONFIG_FILE" | cut -d '=' -f2-) + EXCLUDE=$(grep '^exclude=' "$CONFIG_FILE" | cut -d '=' -f2-) + NOTIFY=$(grep '^notify=' "$CONFIG_FILE" | cut -d '=' -f2-) + + echo "paths=$PATHS" >> $GITHUB_OUTPUT + echo "exclude=$EXCLUDE" >> $GITHUB_OUTPUT + echo "notify=$NOTIFY" >> $GITHUB_OUTPUT + + - name: Determine changed files + id: changes + run: | + LAST_WORKFLOW_RUN_DATE=$([ "$(date "+%d")" -eq 1 ] && echo "$(date --date "-1 month" "+%Y-%m")-15 14:03:00 +0000" || echo "$(date "+%Y-%m")-01 14:03:00 +0000") + LOG=$(git log --since="$LAST_WORKFLOW_RUN_DATE" --name-only --pretty=format:'COMMIT:%H') + + FILES=$(printf "%s\n" "$LOG" | awk '/^COMMIT:/{next} NF' | sort -u) + + { + echo "log<> "$GITHUB_OUTPUT" + + { + echo "files<> "$GITHUB_OUTPUT" + + - name: Check if monitored paths has changes + id: check + env: + FILES: ${{ steps.changes.outputs.files }} + INCLUDES: ${{ steps.config.outputs.paths }} + EXCLUDES: ${{ steps.config.outputs.exclude }} + run: | + + ALERT=false + MATCHED_FILES="" + + while IFS= read -r f; do + [ -z "$f" ] && continue + + INCLUDED=false + for p in $INCLUDES; do + case "$f" in + $p*) INCLUDED=true; break ;; + esac + done + [ "$INCLUDED" = false ] && continue + + EXCLUDED=false + for x in $EXCLUDES; do + [ -z "$x" ] && continue + case "$f" in + $x*) EXCLUDED=true; break ;; + esac + done + [ "$EXCLUDED" = true ] && continue + + ALERT=true + MATCHED_FILES="${MATCHED_FILES}${f}\n" + done <<< "${FILES}" + + echo "alert=$ALERT" >> "$GITHUB_OUTPUT" + + echo "matched<> "$GITHUB_OUTPUT" + printf "%b" "$MATCHED_FILES" >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + + - name: Craft alert message + id: message + if: steps.check.outputs.alert == 'true' + uses: actions/github-script@v9 + env: + NOTIFY: ${{ steps.config.outputs.notify }} + PATHS: ${{ steps.config.outputs.paths }} + EXCLUDES: ${{ steps.config.outputs.exclude }} + MATCHED: ${{ steps.check.outputs.matched }} + LOG: ${{ steps.changes.outputs.log }} + with: + script: | + const notify = process.env.NOTIFY; + const paths = process.env.PATHS; + const excludes = process.env.EXCLUDES; + + const matchedList = process.env.MATCHED + .split("\n") + .map(s => s.trim()) + .filter(Boolean); + + const rawLog = process.env.LOG; + const lines = rawLog.split("\n"); + + const shaSet = new Set(); + let currentSha = null; + + for (const line of lines) { + if (line.startsWith("COMMIT:")) { + currentSha = line.substring("COMMIT:".length).trim(); + } else { + const file = line.trim(); + if (!file || !currentSha) continue; + + if (matchedList.includes(file)) { + shaSet.add(currentSha); + } + } + } + + const commitUrls = shaSet.size + ? Array.from(shaSet).map(sha => `- https://github.com/${context.repo.owner}/${context.repo.repo}/commit/${sha}`).join("\n") + : "(No commits specifically touched monitored files)"; + + const body = ` + Changes detected in english files. + + Changed files: + ${JSON.stringify(matchedList, null, 2)} + + See changes in the commits affecting monitored files: + ${commitUrls} + + Notifying: ${notify} + `; + + core.setOutput('body', body); + + - name: Resolve discussion category + id: discussion_meta + if: steps.check.outputs.alert == 'true' + uses: actions/github-script@v9 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const QUERY = `query ($owner: String!, $name: String!) { + repository(owner: $owner, name: $name) { + id + discussionCategories(first: 50) { + nodes { id slug } + } + } + }`; + + const data = await github.graphql(QUERY, { + owner: context.repo.owner, + name: context.repo.repo + }); + + const category = data.repository.discussionCategories.nodes + .find(c => c.slug === "announcements"); + + if (!category) { + core.setFailed("Discussion category not found."); + return; + } + + core.setOutput("repository_id", data.repository.id); + core.setOutput("category_id", category.id); + + - name: Determine release title + id: release + if: steps.check.outputs.alert == 'true' + run: | + RELEASE_TAG=$(git describe --tags --abbrev=0) + RELEASE_TITLE="Translation alerts for release ${RELEASE_TAG}" + echo "title=$RELEASE_TITLE" >> $GITHUB_OUTPUT + + - name: Find or create release discussion + id: discussion + if: steps.check.outputs.alert == 'true' + uses: actions/github-script@v9 + env: + REPOSITORY_ID: ${{ steps.discussion_meta.outputs.repository_id }} + CATEGORY_ID: ${{ steps.discussion_meta.outputs.category_id }} + TITLE: ${{ steps.release.outputs.title }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const repoId = process.env.REPOSITORY_ID; + const categoryId = process.env.CATEGORY_ID; + const title = process.env.TITLE; + + const FIND = `query ($owner: String!, $name: String!) { + repository(owner: $owner, name: $name) { + discussions(first: 50) { + nodes { id title category { id } } + } + } + }`; + + const result = await github.graphql(FIND, { + owner: context.repo.owner, + name: context.repo.repo + }); + + let discussion = result.repository.discussions.nodes + .find(d => d.title === title && d.category?.id === categoryId); + + if (!discussion) { + const CREATE = `mutation ($input: CreateDiscussionInput!) { + createDiscussion(input: $input) { + discussion { id } + } + }`; + + const created = await github.graphql(CREATE, { + input: { + repositoryId: repoId, + categoryId, + title, + body: "Translation updates for this release." + } + }); + + discussion = created.createDiscussion.discussion; + } + + core.setOutput("discussion_id", discussion.id); + + - name: Post alert comment + if: steps.check.outputs.alert == 'true' + uses: actions/github-script@v9 + env: + DISCUSSION_ID: ${{ steps.discussion.outputs.discussion_id }} + BODY: ${{ steps.message.outputs.body }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const discussionId = process.env.DISCUSSION_ID; + const body = process.env.BODY; + + const ADD = `mutation ($input: AddDiscussionCommentInput!) { + addDiscussionComment(input: $input) { + comment { id } + } + }`; + + await github.graphql(ADD, { + input: { + discussionId: discussionId, + body: body + } + }); \ No newline at end of file From 1af0b432f867bfcb3e0803eb191931a0dc0a01b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Wed, 9 Sep 2026 19:25:46 +0200 Subject: [PATCH 122/157] Add comment to cron schedule in translator-alert.yml --- .github/workflows/translator-alert.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/translator-alert.yml b/.github/workflows/translator-alert.yml index c8c54c397..0ceacbae1 100644 --- a/.github/workflows/translator-alert.yml +++ b/.github/workflows/translator-alert.yml @@ -6,7 +6,7 @@ permissions: on: schedule: - - cron: '3 14 1,15 * *' + - cron: '3 14 1,15 * *' # 14:03 UTC on day 1 and 15 of the month jobs: alert: @@ -265,4 +265,4 @@ jobs: discussionId: discussionId, body: body } - }); \ No newline at end of file + }); From 6172909b5eb6194aa0f807bb0afa37e859102a84 Mon Sep 17 00:00:00 2001 From: mgros Date: Tue, 22 Sep 2026 14:55:53 +0200 Subject: [PATCH 123/157] de: fix "k-th root" --- Rules/Languages/de/ClearSpeak_Rules.yaml | 2 +- Rules/Languages/de/SimpleSpeak_Rules.yaml | 2 +- tests/Languages/de/ClearSpeak/mroot.rs | 14 +++++++++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Rules/Languages/de/ClearSpeak_Rules.yaml b/Rules/Languages/de/ClearSpeak_Rules.yaml index c1dd81eb5..0436516f5 100644 --- a/Rules/Languages/de/ClearSpeak_Rules.yaml +++ b/Rules/Languages/de/ClearSpeak_Rules.yaml @@ -90,7 +90,7 @@ if: "*[2][self::m:mi][string-length(.)=1]" then: - x: "*[2]" - - pronounce: [text: "-th", ipa: "θ", sapi5: "th", eloquence: "T"] + - pronounce: [text: "-te", ipa: "te", sapi5: "te", eloquence: "T"] else: [x: "*[2]"] - T: "wurzel" - test: diff --git a/Rules/Languages/de/SimpleSpeak_Rules.yaml b/Rules/Languages/de/SimpleSpeak_Rules.yaml index 4d48fd27e..f5afa4120 100644 --- a/Rules/Languages/de/SimpleSpeak_Rules.yaml +++ b/Rules/Languages/de/SimpleSpeak_Rules.yaml @@ -66,7 +66,7 @@ if: "*[2][self::m:mi][string-length(.)=1]" then: - x: "*[2]" - - pronounce: [text: "-th", ipa: "θ", sapi5: "th", eloquence: "T"] + - pronounce: [text: "-te", ipa: "te", sapi5: "te", eloquence: "T"] else: [x: "*[2]"] - T: "wurzel" # phrase(the square 'root' of) - test: diff --git a/tests/Languages/de/ClearSpeak/mroot.rs b/tests/Languages/de/ClearSpeak/mroot.rs index 5acba4ebb..577c6751a 100644 --- a/tests/Languages/de/ClearSpeak/mroot.rs +++ b/tests/Languages/de/ClearSpeak/mroot.rs @@ -119,17 +119,25 @@ fn ordinal_root() -> Result<()> { } -/* // should have n-te wurze #[test] -fn simple_mi_root() -> Result<()> { +fn variable_root_index_uses_german_ordinal_suffix() -> Result<()> { + // A variable root index uses the German ordinal suffix in both speech styles. let expr = " x n "; - test("de", "ClearSpeak", expr, "die n-th wurzel von x")?; + test("de", "ClearSpeak", expr, "die n-te wurzel von x")?; + test("de", "SimpleSpeak", expr, "die n-te wurzel von x")?; + + let expr = " + x k + "; + test("de", "ClearSpeak", expr, "die k-te wurzel von x")?; + test("de", "SimpleSpeak", expr, "die k-te wurzel von x")?; return Ok(()); } +/* #[test] fn mroot_simple_pos_end_root() -> Result<()> { let expr = " From 71f2f8ac4ac317c3a3242cf788899ad8fe9797c5 Mon Sep 17 00:00:00 2001 From: mgros Date: Tue, 22 Sep 2026 15:03:40 +0200 Subject: [PATCH 124/157] de: fix "negativ positiv" --- Rules/Languages/de/ClearSpeak_Rules.yaml | 6 +++--- Rules/Languages/de/definitions.yaml | 4 ++-- tests/Languages/de/ClearSpeak/intervals.rs | 6 +++--- tests/Languages/de/ClearSpeak/mroot.rs | 2 +- .../de/ClearSpeak/symbols_and_adornments.rs | 8 ++++---- tests/Languages/de/mtable.rs | 2 +- tests/Languages/de/shared.rs | 13 +++++++++++++ 7 files changed, 27 insertions(+), 14 deletions(-) diff --git a/Rules/Languages/de/ClearSpeak_Rules.yaml b/Rules/Languages/de/ClearSpeak_Rules.yaml index 0436516f5..eed98a687 100644 --- a/Rules/Languages/de/ClearSpeak_Rules.yaml +++ b/Rules/Languages/de/ClearSpeak_Rules.yaml @@ -108,7 +108,7 @@ then: [pause: short] else: [pause: long] -# The 'negative' rule interacts with the msqrt/mroot rules as those might pick off this case ("the negative square root of x") +# Prefix signs interact with the msqrt/mroot rules as those might pick off this case. - name: negative_and_positive tag: [plus, minus] match: "count(*)=1 and contains(@data-intent-property, ':prefix:')" @@ -122,8 +122,8 @@ - bookmark: "@id" - test: if: "self::m:minus" - then: [T: "negative"] - else: [T: "positive"] + then: [T: "minus"] + else: [T: "plus"] - x: "*[1]" # Fraction rules diff --git a/Rules/Languages/de/definitions.yaml b/Rules/Languages/de/definitions.yaml index 427eec726..bb54a3c82 100644 --- a/Rules/Languages/de/definitions.yaml +++ b/Rules/Languages/de/definitions.yaml @@ -25,8 +25,8 @@ "lim-inf": "prefix=lim inf bei: der untere grenzwert bei : der untere grenzwert bei", "logarithm-with-base": "prefix=logarithmus basis: der logarithmus basis: der logarithmus basis", "natural-logarithm": "function=ln: natürlicher logarithmus: natürlicher logarithmus", - "minus": "infix=minus || prefix=negativ", - "plus": "infix=plus || prefix=positiv", + "minus": "infix=minus || prefix=minus", + "plus": "infix=plus || prefix=plus", "real-part": "function=der reale teil", "transpose": "postfix=transponiert || function=die Transponierte", "magnitude": "function=; Norm: Norm: Norm; Ende Norm", diff --git a/tests/Languages/de/ClearSpeak/intervals.rs b/tests/Languages/de/ClearSpeak/intervals.rs index 3bf359a55..e3a5a8ff1 100644 --- a/tests/Languages/de/ClearSpeak/intervals.rs +++ b/tests/Languages/de/ClearSpeak/intervals.rs @@ -80,7 +80,7 @@ fn interval_negative_infinity_to_open_endpoint() -> Result<()> { "ClearSpeak_Paren", "Interval", expr, - "das Intervall negative unendlich bis d, nicht einschließlich d", + "das Intervall minus unendlich bis d, nicht einschließlich d", ) } @@ -96,7 +96,7 @@ fn interval_negative_infinity_to_closed_endpoint() -> Result<()> { "ClearSpeak_Paren", "Interval", expr, - "das Intervall negative unendlich bis d, einschließlich d", + "das Intervall minus unendlich bis d, einschließlich d", ) } @@ -144,6 +144,6 @@ fn interval_between_infinities_has_no_endpoint_qualifier() -> Result<()> { "ClearSpeak_Paren", "Interval", expr, - "das Intervall negative unendlich bis unendlich", + "das Intervall minus unendlich bis unendlich", ) } diff --git a/tests/Languages/de/ClearSpeak/mroot.rs b/tests/Languages/de/ClearSpeak/mroot.rs index 577c6751a..e237552dc 100644 --- a/tests/Languages/de/ClearSpeak/mroot.rs +++ b/tests/Languages/de/ClearSpeak/mroot.rs @@ -71,7 +71,7 @@ fn neg_without_root() -> Result<()> { let expr = " - x - y "; - test("de", "ClearSpeak", expr, "negative x minus y")?; + test("de", "ClearSpeak", expr, "minus x minus y")?; return Ok(()); } diff --git a/tests/Languages/de/ClearSpeak/symbols_and_adornments.rs b/tests/Languages/de/ClearSpeak/symbols_and_adornments.rs index f0c5cb6b3..535de28ed 100644 --- a/tests/Languages/de/ClearSpeak/symbols_and_adornments.rs +++ b/tests/Languages/de/ClearSpeak/symbols_and_adornments.rs @@ -85,7 +85,7 @@ fn ellipses_auto_start() -> Result<()> { …, -2,-1,0 "; - test("de", "ClearSpeak", expr, "punkt punkt punkt komma negative 2 komma negative 1 komma 0")?; + test("de", "ClearSpeak", expr, "punkt punkt punkt komma minus 2 komma minus 1 komma 0")?; return Ok(()); } @@ -135,7 +135,7 @@ fn ellipses_auto_both() -> Result<()> { ,… "; test_ClearSpeak("de", "ClearSpeak_Ellipses", "Auto", expr, - "punkt punkt punkt komma negative 2 komma negative 1 komma 0 komma 1 komma 2 komma punkt punkt punkt")?; + "punkt punkt punkt komma minus 2 komma minus 1 komma 0 komma 1 komma 2 komma punkt punkt punkt")?; return Ok(()); } @@ -146,7 +146,7 @@ fn ellipses_and_so_on_start() -> Result<()> { …, -2,-1,0 "; - test_ClearSpeak("de", "ClearSpeak_Ellipses", "AndSoOn", expr, "punkt punkt punkt komma negative 2 komma negative 1 komma 0")?; + test_ClearSpeak("de", "ClearSpeak_Ellipses", "AndSoOn", expr, "punkt punkt punkt komma minus 2 komma minus 1 komma 0")?; return Ok(()); } @@ -196,7 +196,7 @@ fn ellipses_and_so_on_both() -> Result<()> { ,… "; test_ClearSpeak("de", "ClearSpeak_Ellipses", "AndSoOn", expr, - "punkt punkt punkt komma negative 2 komma negative 1 komma 0 komma 1 komma 2 komma punkt punkt punkt")?; + "punkt punkt punkt komma minus 2 komma minus 1 komma 0 komma 1 komma 2 komma punkt punkt punkt")?; return Ok(()); } diff --git a/tests/Languages/de/mtable.rs b/tests/Languages/de/mtable.rs index d8ad1aa28..e00273738 100644 --- a/tests/Languages/de/mtable.rs +++ b/tests/Languages/de/mtable.rs @@ -1196,7 +1196,7 @@ fn identity_matrix_false_positive_negative_one() -> Result<()> { ] "; test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], - expr, "die 2 mal 2 diagonalmatrix; spalte 1; 1; spalte 2; negativ 1")?; + expr, "die 2 mal 2 diagonalmatrix; spalte 1; 1; spalte 2; minus 1")?; Ok(()) } diff --git a/tests/Languages/de/shared.rs b/tests/Languages/de/shared.rs index 93d570108..3b86d7d89 100644 --- a/tests/Languages/de/shared.rs +++ b/tests/Languages/de/shared.rs @@ -37,6 +37,19 @@ fn variable_powers() -> Result<()> { Ok(()) } +#[test] +fn unary_signs_use_plus_and_minus() -> Result<()> { + // Unary signs use their mathematical names rather than adjectival forms. + let signed_numbers = "−5,+5"; + test("de", "ClearSpeak", signed_numbers, "minus 5 komma plus 5")?; + test("de", "SimpleSpeak", signed_numbers, "minus 5 komma plus 5")?; + + let negative_root = "−x"; + test("de", "ClearSpeak", negative_root, "minus die quadratwurzel von x")?; + test("de", "SimpleSpeak", negative_root, "minus die quadratwurzel von x")?; + Ok(()) +} + #[test] fn modified_vars() -> Result<()> { let expr = " From 8ebda89cceeb59bee377e60b4696e18718c28609 Mon Sep 17 00:00:00 2001 From: mgros Date: Tue, 22 Sep 2026 15:45:07 +0200 Subject: [PATCH 125/157] de: fix RPM singular/plural --- Rules/Languages/de/definitions.yaml | 4 ++-- tests/Languages/de/units.rs | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Rules/Languages/de/definitions.yaml b/Rules/Languages/de/definitions.yaml index bb54a3c82..73dfcf7f7 100644 --- a/Rules/Languages/de/definitions.yaml +++ b/Rules/Languages/de/definitions.yaml @@ -96,7 +96,7 @@ "pc": "parsec", "Å": "ångström", "Å": "ångström", "fm": "fermi", "ha": "hektar", "dB": "dezibel", "amu": "atommasse-einheit", "atm": "atmosphäre", "bar": "bar", "cal": "kalorie", "Ci": "curie", "grad": "gon", "M": "mol/liter", - "R": "röntgen", "rpm": "umdrehungen pro minute", "℧": "mho", "dyn": "dyn", "erg": "erg", + "R": "röntgen", "rpm": "Umdrehung pro Minute", "℧": "mho", "dyn": "dyn", "erg": "erg", "Kib": "kibi-bit", "Mib": "mebi-bit", "Gib": "gibi-bit", "Tib": "tebi-bit", "Pib": "pebi-bit", "Eib": "exbi-bit", "Zib": "zebi-bit", "Yib": "yobi-bit", "KiB": "kibi-byte", "MiB": "mebi-byte", "GiB": "gibi-byte", "TiB": "tebi-byte", "PiB": "pebi-byte", "EiB": "exbi-byte", @@ -204,7 +204,7 @@ "kibi-byte": "kibi-byte", "mebi-byte": "mebi-byte", "gibi-byte": "gibi-byte", "tebi-byte": "tebi-byte", "pebi-byte": "pebi-byte", "exbi-byte": "exbi-byte", "zebi-byte": "zebi-byte", "yobi-byte": "yobi-byte", - "umdrehungen pro minute": "umdrehungen pro minute" + "Umdrehung pro Minute": "Umdrehungen pro Minute" } diff --git a/tests/Languages/de/units.rs b/tests/Languages/de/units.rs index 605ac2ed1..06de867e2 100644 --- a/tests/Languages/de/units.rs +++ b/tests/Languages/de/units.rs @@ -120,6 +120,24 @@ fn currency_symbol_precedes_amount() -> Result<()> { Ok(()) } +#[test] +fn rpm_uses_singular_and_plural_forms() -> Result<()> { + // The unit name is singular only for a coefficient of exactly one. + test( + "de", + "SimpleSpeak", + r#"1rpm"#, + "1 Umdrehung pro Minute", + )?; + test( + "de", + "SimpleSpeak", + r#"2rpm"#, + "2 Umdrehungen pro Minute", + )?; + Ok(()) +} + /* #[test] fn si_base_with_prefixes() -> Result<()> { From 32d7a9c6872e4e19b9bcdfee72faec28a1725149 Mon Sep 17 00:00:00 2001 From: mgros Date: Wed, 23 Sep 2026 00:36:24 +0200 Subject: [PATCH 126/157] Set CRLF line endings for .rs and .yaml files --- .editorconfig | 7 + .gitattributes | 2 + Rules/Languages/de/unicode.yaml | 930 ++++++++++++++++---------------- 3 files changed, 474 insertions(+), 465 deletions(-) create mode 100644 .editorconfig create mode 100644 .gitattributes diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..f8b039633 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +root = true + +[*.rs] +end_of_line = crlf + +[*.yaml] +end_of_line = crlf diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..40c212418 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +*.rs text eol=crlf +*.yaml text eol=crlf diff --git a/Rules/Languages/de/unicode.yaml b/Rules/Languages/de/unicode.yaml index f8b0ec641..2a093e90b 100644 --- a/Rules/Languages/de/unicode.yaml +++ b/Rules/Languages/de/unicode.yaml @@ -1,476 +1,476 @@ ---- - # Note to translators: - # most languages don't have two ways to pronounce 'a' -- if not need, remove the rules and change "B-Z" to "A-Z" - # some languages say the word for "uppercase" after the letter. Make sure to change that where appropriate by moving some code around - - "a-z": - - test: - if: "$TTS='none'" - then: [ T: "." ] # (en: '.', google translation) - else: [ spell: "'.'" ] - -# Capital letters are a little tricky: users can pick their favorite word (something that was requested) and - # screen readers have options to use pitch changes or beeps instead of or in addition to say "cap" - # Also, if a user can see the screen, they probably don't need to hear "cap", but if they specified an override, they must want to hear the override. - - - "A-Z": - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "groß"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] - - - "0-9": [T: "."] # (en: '.', google: 'A') - - - "!": # 0x21 - - test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':structure:')]" - then_test: - if: "$Verbosity = ' '" - then: [T: "knall"] # 0x21 (en: 'bang', google translation) - else: [T: "ausrufezeichen"] # 0x21 (en: 'exclamation point') - else: [T: "fakultät"] # 0x21 (en: 'factorial') - - - "\"": [T: "anführungszeichen"] # 0x22 (en: 'quotation mark') - - "#": [T: "nummernzeichen"] # 0x23 (en: 'number') - - "$": [T: "dollar"] # 0x24 (en: 'dollars') - - "%": [T: "prozent"] # 0x25 (en: 'percent') - - "&": [T: "kaufmännisches und"] # 0x26 (en: 'ampersand') - - "'": [T: "hochkomma"] # 0x27 (en: 'apostrophe', MathPlayer: 'Hochkomma', google: 'apostroph') - - "(": # 0x28 - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then_test: - if: "$Verbosity='Terse'" - then: [T: "klammer auf"] # 0x28 (en: 'open', google translation) #unklar - else: [T: "klammer auf"] # 0x28 (en: 'open paren') - else: [T: "klammer auf"] # 0x28 (en: 'left paren') - - ")": # 0x29 - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then_test: - if: "$Verbosity='Terse'" - then: [T: "klammer zu"] # 0x29 (en: 'close', google translation) #unklar - else: [T: "klammer zu"] # 0x29 (en: 'close paren') - else: [T: "klammer zu"] # 0x29 (en: 'right paren') - - - "*": # 0x2a - test: - if: "parent::*[name(.)='msup' or name(.)='msubsup' or name(.)='skip-super']" - then: [T: "stern"] # 0x2a (en: 'star', google translation) - else: [T: "mal"] # 0x2a - - "+": [T: "plus"] # 0x2b - - ",": # 0x2c - # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent - # that this test is here and not with "…" is not ideal, but seems simplest - test: - if: - - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " - # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' - # speak "comma" when not adjacent to '…' - - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " - # except if expression starts with '…' - - "../*[1][text()='…'] " - then: [T: "komma"] # (en: 'comma', google translation) - # else silent - - - "-": [T: "minus"] # 0x2d - - ".": # 0x2e - - test: - if: "parent::*[1][self::m:mn]" - then: [T: "punkt"] # (en: 'point', google translation) - else: [T: "punkt"] # (en: 'dot', google: 'punkt') - - "/": [T: "schrägstrich"] # 0x2f (en: 'divided by') - - ":": [T: "doppelpunkt"] # 0x3a (en: 'colon') - - ";": [T: "strichpunkt"] # 0x3b (en: 'semicolon') - - "<": # 0x3c - - test: - if: "$Verbosity!='Terse'" - then: [T: "ist"] # (en: 'is', google translation) - - T: "kleiner als" # (en: 'less than') - - "=": # 0x3d - - test: - if: "$Verbosity!='Terse'" - then: [T: "ist gleich"] # (en: 'is equal to', google translation) - else: [T: "ist gleich"] # (en: 'equals') - - - ">": # 0x3e - - test: - if: "$Verbosity!='Terse'" - then: [T: "ist"] # (en: 'is', google translation) - - T: "größer als" # (en: 'greater than') - - "?": [T: "fragezeichen"] # 0x3f (en: 'question mark', MathPlayer: 'Frgezeichen', google: 'fragezeichen') - - "@": [T: "ät-zeichen"] # 0x40 (en: 'at sign') - - "[": # 0x5b - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "offene eckige klammer"] # (en: 'open bracket', google translation) #unklar - else: [T: "eckige klammer auf"] # (en: 'left bracket', MathPlayer: 'eckig Klammer auf', google: 'linke klammer') - - "\\": [T: "eckige klammer auf"] # 0x5c (en: 'back slash', MathPlayer: 'eckig Klammer auf', google: 'rückenstrich') - - "]": # 0x5d - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "schließende eckige klammer"] # (en: 'close bracket', google translation) #unklar - else: [T: "eckige klammer zu"] # (en: 'right bracket') - - "^": [T: "zirkumflex"] # 0x5e (en: 'hat') - - "_": [T: "unterstrich"] # 0x5f (en: 'under bar', MathPlayer: 'under bar', google: 'unter bar') - - "`": [T: "gravis akzent"] # 0x60 (en: 'grave', MathPlayer: 'grave accent', google: 'grab') - - "{": # 0x7b - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "offene geschweifte klammer"] # (en: 'open brace', google translation) - else: [T: "geschweifte klammer auf"] # (en: 'left brace') - - "|": # 0x7c - # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' - - test: - - if: "$SpeechStyle != 'ClearSpeak' or not(preceding-sibling::*) or not(following-sibling::*)" - then: [T: "senkrechter strich"] # (en: 'vertical line', google translation) - - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" - then: [T: "so dass"] # (en: 'such that', google translation) - - else_if: "$ClearSpeak_VerticalLine = 'Given'" - then: [T: "gegeben"] # (en: 'given', google translation) - - else: [T: "teilt"] # (en: 'divides') - - - "}": # 0x7d - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "schließende geschweifte klammer"] # (en: 'close brace', google translation) - else: [T: "geschweifte klammer zu"] # (en: 'right brace') - - - "~": [T: "tilde"] # 0x7e - - " ": # 0xa0 - - test: - if: "@data-empty-in-2D and ../../../../*[name(.)!='equations']" - then: [T: "leer"] # want to say something for fraction (etc) with empty child (en: 'empty', google translation) - else: [T: ""] - - - "¬": [T: "nicht"] # 0xac (en: 'not') - - "°": [T: "grad"] # 0xb0 (en: 'degrees') - - "±": [T: "plus minus"] # 0xb1 (en: 'plus or minus') - - "´": [T: "akut akzent"] # 0xb4 (en: 'acute', MathPlayer: 'acute accent', google: 'akut') - - "·": # 0xB7 - - test: - if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolDot = 'Auto'" - then: [T: "mal"] # (en: 'times', google translation) - else: [T: "mal"] # (en: 'dot', MathPlayer: 'Punkt mittig', google: 'punkt') - - "×": # 0xd7 - - test: - if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolX = 'Auto'" - then: [T: "mal"] # (en: 'times', google translation) - else_test: - if: $ClearSpeak_MultSymbolX = 'By' - then: [T: "von"] # (en: 'by', google translation) - else: [T: "mal"] # (en: 'cross', MathPlayer: 'times', google: 'kreuzen') #unklar - - "÷": [T: "geteilt durch"] # 0xf7 (en: 'divided by', MathPlayer: 'divides') - - "̀": [T: "accent grave"] # 0x300 (en: 'grave accent embellishment', google: 'grabakzentverzierung') - - "́": [T: "accent aigu"] # 0x301 (en: 'acute accent embellishment', google: 'akute akzentverzierung') - - "̂": [T: "zirkumflex"] # 0x302 (en: 'circumflex accent embellishment', google: 'zirma akzentverzierung') - - "̃": [T: "tilde"] # 0x303 (google: 'tilde verzierung') - - "̄": [T: "makron"] # 0x304 (en: 'macron embellishment', google: 'makron -verzierung') - - "̅": [T: "überstrich"] # 0x305 (google: 'überbärerverzierung') - - "̆": [T: "brevis"] # 0x306 (en: 'breve', google: 'breve') - - "̇": [T: "punkt darüber"] # 0x307 (google: 'punkt über verzierung') - - # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong - - "Α-Ω": - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "großbuchstabe"] # (en: 'cap', google translation) #großbuchstaben? - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [spell: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] - - - "α": [T: "alpha"] # 0x3b1 - - "β": [T: "beta"] # 0x3b2 - - "γ": [T: "gamma"] # 0x3b3 - - "δ": [T: "delta"] # 0x3b4 - - "ε": [T: "epsilon"] # 0x3b5 - - "ζ": [T: "zeta"] # 0x3b6 - - "η": [T: "eta"] # 0x3b7 - - "θ": [T: "theta"] # 0x3b8 - - "ι": [T: "iota"] # 0x3b9 (google: 'jota') - - "κ": [T: "kappa"] # 0x3ba - - "λ": [T: "lambda"] # 0x3bb (en: 'lambda', google: 'lambda') - - "μ": [T: "mü"] # 0x3bc - - "ν": [T: "nü"] # 0x3bd - - "ξ": [T: "xi"] # 0x3be (en: 'zai', google: 'zai') - - "ο": [T: "omicron"] # 0x3bf - - "π": [T: "pi"] # 0x3c0 - - "ρ": [T: "rho"] # 0x3c1 - - "ς": [T: "sigma am wortende"] # 0x3c2 - - "σ": [T: "sigma"] # 0x3c3 - - "τ": [T: "tau"] # 0x3c4 - - "υ": [T: "üpsilon"] # 0x3c5 #ypsilon - - "φ": [T: "phi"] # 0x3c6 - - "χ": [T: "chi"] # 0x3c7 - - "ψ": [T: "psi"] # 0x3c8 - - "ω": [T: "omega"] # 0x3c9 - - "ϕ": [T: "phi"] # 0x3d5 (en: 'phi', google: 'phi') - - "ϖ": [T: "pi"] # 0x3d6 (en: 'pi', google: 'pi') - - "ϵ": [T: "epsilon"] # 0x3f5 - - "϶": [T: "umgekehrtes epsilon"] # 0x3f6 (en: 'reversed epsilon', MathPlayer: 'reversed epsilon', google: 'umgekehrter epsilon') - - - "⁡": # 0x2061 - - test: - if: "$Verbosity!='Terse' and not(preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')]) and - not(@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':structure:')])" - then: [T: "von"] # (en: 'of', google translation) - - "⁢": [T: ""] # 0x2062 - - "⁣": [T: ""] # 0x2063 - - "⁤": [T: "und"] # 0x2064 (en: 'and', google: 'und') - - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" - - T: "drei Strich" # (en: 'double-struck', MathPlayer: 'drei-strich', google: 'doppelter takt') - - spell: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" - - - "℃": [T: "grad celsius"] # 0x2103 (google: 'grad celsius') - - "ℋℛℓ": # 0x210b #klären - - T: "schreibschrift" # (en: 'script', google: 'skript') - - spell: "translate('.', 'ℋℛℓ', 'HRl')" - - "ℜ": # 0x211c - - T: "frakturschrift groß r" # (en: 'fraktur', google: 'fraktur') - - spell: "'R'" - - - "ⅆⅇⅈⅉ": # 0x2146-9 - - T: "doppelstrich kursiv" # (en: 'double-struck italic', MathPlayer: 'angstroms', google: 'doppelt übertroffene kursivschrift') - - spell: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" - - - "∥": # 0x2225 - - test: - if: "$Verbosity!='Terse'" - then: [T: "ist"] # (en: 'is', google translation) - - T: "parallel zu" # (en: 'parallel to') - - "∦": # 0x2226 - - test: - if: "$Verbosity!='Terse'" - then: [T: "ist"] # (en: 'is', google translation) - - T: "nicht parallel zu" # (en: 'not parallel to') - - "≤": # 0x2264 - - test: - if: "$Verbosity!='Terse'" - then: [T: "ist"] # (en: 'is', google translation) - - T: "kleiner gleich" - - "≥": # 0x2265 - - test: - if: "$Verbosity!='Terse'" - then: [T: "ist"] # (en: 'is', google translation) - - T: "größer gleich" # (en: 'greater than or equal to') - - # --- restored complex short definitions (prefer over unicode-full) --- - - "…": # 0x2026 - test: - if: - - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" - # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' - # speak '…' as 'and so on...' unless expr starts with '…' - - "../*[1][text()='…']" - then: [T: "punkt punkt punkt"] # (en: 'dot dot dot', google translation) - else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' - if: "count(following-sibling::*) = 0" - then: [T: "und so weiter"] # (en: 'and so on', google translation) - else: [T: "punkt punkt punkt"] # (en: 'and so on up to', MathPlayer: 'dot dot dot', google: 'und so weiter bis') #horizontale Ellipsis - - "→": # 0x2192 - - test: - if: "ancestor::*[2][self::m:limit]" - then: [T: "gegen"] # (en: 'approaches', google translation) - else: [T: "pfeil nach rechts"] # (en: 'right arrow', MathPlayer: 'rightwards arrow', google: 'rechter pfeil') - - "∂": # 0x2202 - - test: - if: "$Verbosity='Terse'" - then: [T: "teilweise"] # (en: 'partial', google translation) - else: [T: "partielle ableitung"] # (en: 'partial derivative', google: 'partielle ableitung') - - "∆": # 0x2206 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'the', google translation) - - T: "delta" # (en: 'laplacian of', MathPlayer: 'increment', google: 'laplace von') #unklar, sehr kontextabhängig - - "∇": # 0x2207 - - test: - if: "$Verbosity!='Terse'" - then: [T: "der"] # (en: 'the', google translation) - - T: "nabla-operator" # (en: 'gradient of', google: 'gradient von') #gradient nur einer der drei möglichen differentialoperatoren - - "∈": # 0x2208 - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: [T: "ein element von"] # (en: 'an element of', google translation) - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: +--- + # Note to translators: + # most languages don't have two ways to pronounce 'a' -- if not need, remove the rules and change "B-Z" to "A-Z" + # some languages say the word for "uppercase" after the letter. Make sure to change that where appropriate by moving some code around + - "a-z": + - test: + if: "$TTS='none'" + then: [ T: "." ] # (en: '.', google translation) + else: [ spell: "'.'" ] + +# Capital letters are a little tricky: users can pick their favorite word (something that was requested) and + # screen readers have options to use pitch changes or beeps instead of or in addition to say "cap" + # Also, if a user can see the screen, they probably don't need to hear "cap", but if they specified an override, they must want to hear the override. + + - "A-Z": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "groß"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] + + - "0-9": [T: "."] # (en: '.', google: 'A') + + - "!": # 0x21 + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':structure:')]" + then_test: + if: "$Verbosity = ' '" + then: [T: "knall"] # 0x21 (en: 'bang', google translation) + else: [T: "ausrufezeichen"] # 0x21 (en: 'exclamation point') + else: [T: "fakultät"] # 0x21 (en: 'factorial') + + - "\"": [T: "anführungszeichen"] # 0x22 (en: 'quotation mark') + - "#": [T: "nummernzeichen"] # 0x23 (en: 'number') + - "$": [T: "dollar"] # 0x24 (en: 'dollars') + - "%": [T: "prozent"] # 0x25 (en: 'percent') + - "&": [T: "kaufmännisches und"] # 0x26 (en: 'ampersand') + - "'": [T: "hochkomma"] # 0x27 (en: 'apostrophe', MathPlayer: 'Hochkomma', google: 'apostroph') + - "(": # 0x28 + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [T: "klammer auf"] # 0x28 (en: 'open', google translation) #unklar + else: [T: "klammer auf"] # 0x28 (en: 'open paren') + else: [T: "klammer auf"] # 0x28 (en: 'left paren') + - ")": # 0x29 + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [T: "klammer zu"] # 0x29 (en: 'close', google translation) #unklar + else: [T: "klammer zu"] # 0x29 (en: 'close paren') + else: [T: "klammer zu"] # 0x29 (en: 'right paren') + + - "*": # 0x2a + test: + if: "parent::*[name(.)='msup' or name(.)='msubsup' or name(.)='skip-super']" + then: [T: "stern"] # 0x2a (en: 'star', google translation) + else: [T: "mal"] # 0x2a + - "+": [T: "plus"] # 0x2b + - ",": # 0x2c + # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent + # that this test is here and not with "…" is not ideal, but seems simplest + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak "comma" when not adjacent to '…' + - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " + # except if expression starts with '…' + - "../*[1][text()='…'] " + then: [T: "komma"] # (en: 'comma', google translation) + # else silent + + - "-": [T: "minus"] # 0x2d + - ".": # 0x2e + - test: + if: "parent::*[1][self::m:mn]" + then: [T: "punkt"] # (en: 'point', google translation) + else: [T: "punkt"] # (en: 'dot', google: 'punkt') + - "/": [T: "schrägstrich"] # 0x2f (en: 'divided by') + - ":": [T: "doppelpunkt"] # 0x3a (en: 'colon') + - ";": [T: "strichpunkt"] # 0x3b (en: 'semicolon') + - "<": # 0x3c + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "kleiner als" # (en: 'less than') + - "=": # 0x3d + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist gleich"] # (en: 'is equal to', google translation) + else: [T: "ist gleich"] # (en: 'equals') + + - ">": # 0x3e + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "größer als" # (en: 'greater than') + - "?": [T: "fragezeichen"] # 0x3f (en: 'question mark', MathPlayer: 'Frgezeichen', google: 'fragezeichen') + - "@": [T: "ät-zeichen"] # 0x40 (en: 'at sign') + - "[": # 0x5b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "offene eckige klammer"] # (en: 'open bracket', google translation) #unklar + else: [T: "eckige klammer auf"] # (en: 'left bracket', MathPlayer: 'eckig Klammer auf', google: 'linke klammer') + - "\\": [T: "eckige klammer auf"] # 0x5c (en: 'back slash', MathPlayer: 'eckig Klammer auf', google: 'rückenstrich') + - "]": # 0x5d + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "schließende eckige klammer"] # (en: 'close bracket', google translation) #unklar + else: [T: "eckige klammer zu"] # (en: 'right bracket') + - "^": [T: "zirkumflex"] # 0x5e (en: 'hat') + - "_": [T: "unterstrich"] # 0x5f (en: 'under bar', MathPlayer: 'under bar', google: 'unter bar') + - "`": [T: "gravis akzent"] # 0x60 (en: 'grave', MathPlayer: 'grave accent', google: 'grab') + - "{": # 0x7b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "offene geschweifte klammer"] # (en: 'open brace', google translation) + else: [T: "geschweifte klammer auf"] # (en: 'left brace') + - "|": # 0x7c + # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' + - test: + - if: "$SpeechStyle != 'ClearSpeak' or not(preceding-sibling::*) or not(following-sibling::*)" + then: [T: "senkrechter strich"] # (en: 'vertical line', google translation) + - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" + then: [T: "so dass"] # (en: 'such that', google translation) + - else_if: "$ClearSpeak_VerticalLine = 'Given'" + then: [T: "gegeben"] # (en: 'given', google translation) + - else: [T: "teilt"] # (en: 'divides') + + - "}": # 0x7d + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "schließende geschweifte klammer"] # (en: 'close brace', google translation) + else: [T: "geschweifte klammer zu"] # (en: 'right brace') + + - "~": [T: "tilde"] # 0x7e + - " ": # 0xa0 + - test: + if: "@data-empty-in-2D and ../../../../*[name(.)!='equations']" + then: [T: "leer"] # want to say something for fraction (etc) with empty child (en: 'empty', google translation) + else: [T: ""] + + - "¬": [T: "nicht"] # 0xac (en: 'not') + - "°": [T: "grad"] # 0xb0 (en: 'degrees') + - "±": [T: "plus minus"] # 0xb1 (en: 'plus or minus') + - "´": [T: "akut akzent"] # 0xb4 (en: 'acute', MathPlayer: 'acute accent', google: 'akut') + - "·": # 0xB7 + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolDot = 'Auto'" + then: [T: "mal"] # (en: 'times', google translation) + else: [T: "mal"] # (en: 'dot', MathPlayer: 'Punkt mittig', google: 'punkt') + - "×": # 0xd7 + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolX = 'Auto'" + then: [T: "mal"] # (en: 'times', google translation) + else_test: + if: $ClearSpeak_MultSymbolX = 'By' + then: [T: "von"] # (en: 'by', google translation) + else: [T: "mal"] # (en: 'cross', MathPlayer: 'times', google: 'kreuzen') #unklar + - "÷": [T: "geteilt durch"] # 0xf7 (en: 'divided by', MathPlayer: 'divides') + - "̀": [T: "accent grave"] # 0x300 (en: 'grave accent embellishment', google: 'grabakzentverzierung') + - "́": [T: "accent aigu"] # 0x301 (en: 'acute accent embellishment', google: 'akute akzentverzierung') + - "̂": [T: "zirkumflex"] # 0x302 (en: 'circumflex accent embellishment', google: 'zirma akzentverzierung') + - "̃": [T: "tilde"] # 0x303 (google: 'tilde verzierung') + - "̄": [T: "makron"] # 0x304 (en: 'macron embellishment', google: 'makron -verzierung') + - "̅": [T: "überstrich"] # 0x305 (google: 'überbärerverzierung') + - "̆": [T: "brevis"] # 0x306 (en: 'breve', google: 'breve') + - "̇": [T: "punkt darüber"] # 0x307 (google: 'punkt über verzierung') + + # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong + - "Α-Ω": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "großbuchstabe"] # (en: 'cap', google translation) #großbuchstaben? + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [spell: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] + + - "α": [T: "alpha"] # 0x3b1 + - "β": [T: "beta"] # 0x3b2 + - "γ": [T: "gamma"] # 0x3b3 + - "δ": [T: "delta"] # 0x3b4 + - "ε": [T: "epsilon"] # 0x3b5 + - "ζ": [T: "zeta"] # 0x3b6 + - "η": [T: "eta"] # 0x3b7 + - "θ": [T: "theta"] # 0x3b8 + - "ι": [T: "iota"] # 0x3b9 (google: 'jota') + - "κ": [T: "kappa"] # 0x3ba + - "λ": [T: "lambda"] # 0x3bb (en: 'lambda', google: 'lambda') + - "μ": [T: "mü"] # 0x3bc + - "ν": [T: "nü"] # 0x3bd + - "ξ": [T: "xi"] # 0x3be (en: 'zai', google: 'zai') + - "ο": [T: "omicron"] # 0x3bf + - "π": [T: "pi"] # 0x3c0 + - "ρ": [T: "rho"] # 0x3c1 + - "ς": [T: "sigma am wortende"] # 0x3c2 + - "σ": [T: "sigma"] # 0x3c3 + - "τ": [T: "tau"] # 0x3c4 + - "υ": [T: "üpsilon"] # 0x3c5 #ypsilon + - "φ": [T: "phi"] # 0x3c6 + - "χ": [T: "chi"] # 0x3c7 + - "ψ": [T: "psi"] # 0x3c8 + - "ω": [T: "omega"] # 0x3c9 + - "ϕ": [T: "phi"] # 0x3d5 (en: 'phi', google: 'phi') + - "ϖ": [T: "pi"] # 0x3d6 (en: 'pi', google: 'pi') + - "ϵ": [T: "epsilon"] # 0x3f5 + - "϶": [T: "umgekehrtes epsilon"] # 0x3f6 (en: 'reversed epsilon', MathPlayer: 'reversed epsilon', google: 'umgekehrter epsilon') + + - "⁡": # 0x2061 + - test: + if: "$Verbosity!='Terse' and not(preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')]) and + not(@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':structure:')])" + then: [T: "von"] # (en: 'of', google translation) + - "⁢": [T: ""] # 0x2062 + - "⁣": [T: ""] # 0x2063 + - "⁤": [T: "und"] # 0x2064 (en: 'and', google: 'und') + - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" + - T: "drei Strich" # (en: 'double-struck', MathPlayer: 'drei-strich', google: 'doppelter takt') + - spell: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" + + - "℃": [T: "grad celsius"] # 0x2103 (google: 'grad celsius') + - "ℋℛℓ": # 0x210b #klären + - T: "schreibschrift" # (en: 'script', google: 'skript') + - spell: "translate('.', 'ℋℛℓ', 'HRl')" + - "ℜ": # 0x211c + - T: "frakturschrift groß r" # (en: 'fraktur', google: 'fraktur') + - spell: "'R'" + + - "ⅆⅇⅈⅉ": # 0x2146-9 + - T: "doppelstrich kursiv" # (en: 'double-struck italic', MathPlayer: 'angstroms', google: 'doppelt übertroffene kursivschrift') + - spell: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" + + - "∥": # 0x2225 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "parallel zu" # (en: 'parallel to') + - "∦": # 0x2226 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "nicht parallel zu" # (en: 'not parallel to') + - "≤": # 0x2264 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "kleiner gleich" + - "≥": # 0x2265 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "größer gleich" # (en: 'greater than or equal to') + + # --- restored complex short definitions (prefer over unicode-full) --- + - "…": # 0x2026 + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak '…' as 'and so on...' unless expr starts with '…' + - "../*[1][text()='…']" + then: [T: "punkt punkt punkt"] # (en: 'dot dot dot', google translation) + else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' + if: "count(following-sibling::*) = 0" + then: [T: "und so weiter"] # (en: 'and so on', google translation) + else: [T: "punkt punkt punkt"] # (en: 'and so on up to', MathPlayer: 'dot dot dot', google: 'und so weiter bis') #horizontale Ellipsis + - "→": # 0x2192 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "gegen"] # (en: 'approaches', google translation) + else: [T: "pfeil nach rechts"] # (en: 'right arrow', MathPlayer: 'rightwards arrow', google: 'rechter pfeil') + - "∂": # 0x2202 + - test: + if: "$Verbosity='Terse'" + then: [T: "teilweise"] # (en: 'partial', google translation) + else: [T: "partielle ableitung"] # (en: 'partial derivative', google: 'partielle ableitung') + - "∆": # 0x2206 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'the', google translation) + - T: "delta" # (en: 'laplacian of', MathPlayer: 'increment', google: 'laplace von') #unklar, sehr kontextabhängig + - "∇": # 0x2207 + - test: + if: "$Verbosity!='Terse'" + then: [T: "der"] # (en: 'the', google translation) + - T: "nabla-operator" # (en: 'gradient of', google: 'gradient von') #gradient nur einer der drei möglichen differentialoperatoren + - "∈": # 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: [T: "ein element von"] # (en: 'an element of', google translation) + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' then: [T: "in"] - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "element von"] # (en: 'member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "element von"] # (en: 'element of', google translation) - - else: [T: "element von"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "ist ein element von"] # (en: 'is a member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "ist ein element von"] # (en: 'is an element of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "ist in"] # (en: 'is in', google translation) - - else: [T: "element von"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') - - "∉": # 0x2209 - # rule is identical to 0x2208 - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: [T: "ist kein element von"] # (en: 'is not an element of', google translation) - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: + then: [T: "element von"] # (en: 'member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "element von"] # (en: 'element of', google translation) + - else: [T: "element von"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "ist ein element von"] # (en: 'is a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "ist ein element von"] # (en: 'is an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "ist in"] # (en: 'is in', google translation) + - else: [T: "element von"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - "∉": # 0x2209 + # rule is identical to 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: [T: "ist kein element von"] # (en: 'is not an element of', google translation) + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' then: [T: "nicht in"] - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "nicht element von"] # (en: 'not member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "nicht element von"] # (en: 'not element of', google translation) - - else: [T: "nicht element von"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to') - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "ist kein element von"] # (en: 'is not a member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "ist kein element von"] # (en: 'is not an element of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "ist nicht in"] # (en: 'is not in', google translation) - - else: [T: "nicht element von"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to') - - "∊": # 0x220a - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: [T: "ist ein element von"] # (en: 'is an element of', google translation) - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: + then: [T: "nicht element von"] # (en: 'not member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "nicht element von"] # (en: 'not element of', google translation) + - else: [T: "nicht element von"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "ist kein element von"] # (en: 'is not a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "ist kein element von"] # (en: 'is not an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "ist nicht in"] # (en: 'is not in', google translation) + - else: [T: "nicht element von"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to') + - "∊": # 0x220a + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: [T: "ist ein element von"] # (en: 'is an element of', google translation) + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' then: [T: "in"] - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "element von"] # (en: 'member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "element von"] # (en: 'element of', google translation) - - else: [T: "element von"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "ist ein element von"] # (en: 'is a member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "ist ein element von"] # (en: 'is an element of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "ist in"] # (en: 'is in', google translation) - - else: [T: "element von"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') - - "∝": # 0x221d - - test: - if: "$Verbosity!='Terse'" - then: [T: "ist"] # (en: 'is', google translation) - - T: "proportional zu" # (en: 'proportional to') - - "∶": # 0x2236 - - test: - if: "$Verbosity!='Terse'" - then: [T: "ist"] # (en: 'is', google translation) #unklar - - T: "zu" # (en: 'to') - - "∾": # 0x223e - - test: - if: "$Verbosity!='Terse'" - then: [T: "ist"] # (en: 'is', google translation) - - T: "umgekehrtes stummes s" # (en: 'most positive', MathPlayer: 'inverted lazy s', google: 'am positivsten') - - "≠": # 0x2260 - - test: - if: "$Verbosity!='Terse'" - then: [T: "ist"] # (en: 'is', google translation) - - T: "ungleich" # (en: 'not equal to') - - "≡": # 0x2261 - - test: - if: "$Verbosity!='Terse'" - then: [T: "ist"] # (en: 'is', google translation) - - T: "identisch mit" # (en: 'identical to', SRE: 'kongruent mit') - - "⊂": # 0x2282 - - test: - if: "$Verbosity!='Terse'" - then: [T: "ist eine"] # (en: 'is a', google translation) - - T: "teilmenge von" # (en: 'subset of', MathPlayer: 'Teilmenge von', google: 'untergruppe von') - - "⊃": # 0x2283 - - test: - if: "$Verbosity!='Terse'" - then: [T: "ist eine"] # (en: 'is a', google translation) - - T: "obermenge von" # (en: 'superset of', MathPlayer: 'Obermenge von', google: 'superset von') - - "⊄": # 0x2284 - - test: - if: "$Verbosity!='Terse'" - then: [T: "ist"] # (en: 'is', google translation) - - T: "keine teilmenge von" # (en: 'not a subset of', MathPlayer: 'nicht Teilmenge von', google: 'keine teilmenge von') - - "⊅": # 0x2285 - - test: - if: "$Verbosity!='Terse'" - then: [T: "ist"] # (en: 'is', google translation) - - T: "keine obermenge von" # (en: 'not a superset of', MathPlayer: 'nicht Obermenge von', google: 'kein superset von') - - "⊆": # 0x2286 - - test: - if: "$Verbosity!='Terse'" - then: [T: "ist eine"] # (en: 'is a', google translation) + then: [T: "element von"] # (en: 'member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "element von"] # (en: 'element of', google translation) + - else: [T: "element von"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "ist ein element von"] # (en: 'is a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "ist ein element von"] # (en: 'is an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "ist in"] # (en: 'is in', google translation) + - else: [T: "element von"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - "∝": # 0x221d + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "proportional zu" # (en: 'proportional to') + - "∶": # 0x2236 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) #unklar + - T: "zu" # (en: 'to') + - "∾": # 0x223e + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "umgekehrtes stummes s" # (en: 'most positive', MathPlayer: 'inverted lazy s', google: 'am positivsten') + - "≠": # 0x2260 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "ungleich" # (en: 'not equal to') + - "≡": # 0x2261 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "identisch mit" # (en: 'identical to', SRE: 'kongruent mit') + - "⊂": # 0x2282 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist eine"] # (en: 'is a', google translation) + - T: "teilmenge von" # (en: 'subset of', MathPlayer: 'Teilmenge von', google: 'untergruppe von') + - "⊃": # 0x2283 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist eine"] # (en: 'is a', google translation) + - T: "obermenge von" # (en: 'superset of', MathPlayer: 'Obermenge von', google: 'superset von') + - "⊄": # 0x2284 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "keine teilmenge von" # (en: 'not a subset of', MathPlayer: 'nicht Teilmenge von', google: 'keine teilmenge von') + - "⊅": # 0x2285 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "keine obermenge von" # (en: 'not a superset of', MathPlayer: 'nicht Obermenge von', google: 'kein superset von') + - "⊆": # 0x2286 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist eine"] # (en: 'is a', google translation) - T: "teilmenge von oder gleich" # (en: 'subset of or equal to', MathPlayer: 'Teilmenge von odre gleich', google: 'teilmenge von oder gleich') - - "⊇": # 0x2287 - - test: - if: "$Verbosity!='Terse'" - then: [T: "ist eine"] # (en: 'is a', google translation) + - "⊇": # 0x2287 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist eine"] # (en: 'is a', google translation) - T: "obermenge von oder gleich" # (en: 'superset of or equal to', MathPlayer: 'Obermenge von oder gleich', google: 'superset von oder gleich') - - # --- restored short definitions that differ from unicode-full --- - - "–": [T: "halbgeviertstrich"] # 0x2013 (SRE: 'En Dash') - - "—": [T: "geviertstrich"] # 0x2014 (SRE: 'EM Dash') - - "―": [T: "horizontale linie"] # 0x2015 (en: 'horizontal bar', MathPlayer: 'horizontal bar', google: 'horizontale linie') - - "‖": [T: "doppelte senkrechte linie"] # 0x2016 (en: 'double vertical line', MathPlayer: 'double vertical bar', google: 'doppelte vertikale linie') - - "′": [T: "strich"] # 0x2032 (en: 'prime', MathPlayer: 'strich', google: 'prime') - - "″": [T: "zwei strich"] # 0x2033 (en: 'double prime', MathPlayer: 'zwei-strich', google: 'double prime') - - "‴": [T: "drei strich"] # 0x2034 (en: 'triple prime', MathPlayer: 'drei-strich', google: 'triple prime') - - "℉": [T: "grad fahrenheit"] # 0x2109 (google: 'grad fahrenheit') - - "ℎ": [T: "planck-konstante"] # 0x210e (en: 'planck constant', MathPlayer: 'planck constant', google: 'planck konstant') - - "Ω": [T: "ohm"] # 0x2126 (en: 'ohms', MathPlayer: 'ohm sign', google: 'ohm') - - "K": [T: "kelvin"] # 0x212a (en: 'kelvin', MathPlayer: 'degrees kelvin', google: 'kelvin') - - "Å": [T: "angström"] # 0x212b (en: 'angstroms', MathPlayer: 'angstroms', google: 'angstrome') - - "←": [T: "pfeil nach links"] # 0x2190 (en: 'leftwards arrow', MathPlayer: 'leftwards arrow', google: 'pfeil nach links') - - "↑": [T: "pfeil nach oben"] # 0x2191 (en: 'upwards arrow', MathPlayer: 'upwards arrow', google: 'nach oben pfeil') - - "↓": [T: "pfeil nach unten"] # 0x2193 (en: 'downwards arrow', MathPlayer: 'downwards arrow', google: 'nach unten pfeil') - - "⇒": [T: "doppelpfeil nach rechts"] # 0x21d2 (en: 'rightwards double arrow', MathPlayer: 'rightwards double arrow', google: 'richtiger doppelpfeil') - - "∏": [T: "produkt"] # 0x220f (en: 'product', MathPlayer: 'Product', google: 'produkt') - - "∐": [T: "koprodukt"] # 0x2210 (en: 'co-product', MathPlayer: 'coproduct', google: 'ko-produkt') - - "∑": [T: "summe"] # 0x2211 (en: 'sum') - - "∗": [T: "mal"] # 0x2217 (en: 'times', MathPlayer: 'asterisk operator', google: 'mal') - - "√": # 0x221a - - T: "quadratwurzel" # (en: 'square root of', MathPlayer: 'radical', google: 'quadratwurzel von') - - "∟": [T: "rechter winkel"] # 0x221f (en: 'right angle') - - "∠": [T: "winkel"] # 0x2220 (en: 'angle') - - "∡": [T: "gerichteter winkel"] # 0x2221 (en: 'measured angle', MathPlayer: 'measured angle', google: 'gemessener winkel') - - "∩": [T: "schnitt mit"] # 0x2229 (en: 'intersection') #Problem: Schnittmenge wenn alleinstehend vor Bezeichnung, schnitt wenn zwischen 2 Mengen - - "∪": [T: "vereinigt mit"] # 0x222a (en: 'union') #Problem: vereinigungsmenge wenn alleinstehend vor Bezeichnung, vereinigt mit wenn zwischen 2 Mengen - - "∫": [T: "integral"] # 0x222b (en: 'integral') - - "∬": [T: "doppelintegral"] # 0x222c (en: 'double integral') - - "∭": [T: "dreifachintegral"] # 0x222d (en: 'triple integral', MathPlayer: 'Dreifaches Integral', google: 'dreifachintegral') - - "∮": [T: "randintegral"] # 0x222e (en: 'contour integral', MathPlayer: 'Kontur-Integral', google: 'konturintegral') - - "∷": [T: "proportional"] # 0x2237 (en: 'as') - - "∼": [T: "tilde"] # 0x223c (en: 'varies with', MathPlayer: 'tilde operator', google: 'variiert mit') - - "∽": [T: "umgekehrte tilde"] # 0x223d (en: 'reversed tilde', MathPlayer: 'reversed tilde', google: 'umgekehrte tilde') - - "∿": [T: "sinuswelle"] # 0x223f (en: 'sine wave', MathPlayer: 'sine wave', google: 'sinus') + + # --- restored short definitions that differ from unicode-full --- + - "–": [T: "halbgeviertstrich"] # 0x2013 (SRE: 'En Dash') + - "—": [T: "geviertstrich"] # 0x2014 (SRE: 'EM Dash') + - "―": [T: "horizontale linie"] # 0x2015 (en: 'horizontal bar', MathPlayer: 'horizontal bar', google: 'horizontale linie') + - "‖": [T: "doppelte senkrechte linie"] # 0x2016 (en: 'double vertical line', MathPlayer: 'double vertical bar', google: 'doppelte vertikale linie') + - "′": [T: "strich"] # 0x2032 (en: 'prime', MathPlayer: 'strich', google: 'prime') + - "″": [T: "zwei strich"] # 0x2033 (en: 'double prime', MathPlayer: 'zwei-strich', google: 'double prime') + - "‴": [T: "drei strich"] # 0x2034 (en: 'triple prime', MathPlayer: 'drei-strich', google: 'triple prime') + - "℉": [T: "grad fahrenheit"] # 0x2109 (google: 'grad fahrenheit') + - "ℎ": [T: "planck-konstante"] # 0x210e (en: 'planck constant', MathPlayer: 'planck constant', google: 'planck konstant') + - "Ω": [T: "ohm"] # 0x2126 (en: 'ohms', MathPlayer: 'ohm sign', google: 'ohm') + - "K": [T: "kelvin"] # 0x212a (en: 'kelvin', MathPlayer: 'degrees kelvin', google: 'kelvin') + - "Å": [T: "angström"] # 0x212b (en: 'angstroms', MathPlayer: 'angstroms', google: 'angstrome') + - "←": [T: "pfeil nach links"] # 0x2190 (en: 'leftwards arrow', MathPlayer: 'leftwards arrow', google: 'pfeil nach links') + - "↑": [T: "pfeil nach oben"] # 0x2191 (en: 'upwards arrow', MathPlayer: 'upwards arrow', google: 'nach oben pfeil') + - "↓": [T: "pfeil nach unten"] # 0x2193 (en: 'downwards arrow', MathPlayer: 'downwards arrow', google: 'nach unten pfeil') + - "⇒": [T: "doppelpfeil nach rechts"] # 0x21d2 (en: 'rightwards double arrow', MathPlayer: 'rightwards double arrow', google: 'richtiger doppelpfeil') + - "∏": [T: "produkt"] # 0x220f (en: 'product', MathPlayer: 'Product', google: 'produkt') + - "∐": [T: "koprodukt"] # 0x2210 (en: 'co-product', MathPlayer: 'coproduct', google: 'ko-produkt') + - "∑": [T: "summe"] # 0x2211 (en: 'sum') + - "∗": [T: "mal"] # 0x2217 (en: 'times', MathPlayer: 'asterisk operator', google: 'mal') + - "√": # 0x221a + - T: "quadratwurzel" # (en: 'square root of', MathPlayer: 'radical', google: 'quadratwurzel von') + - "∟": [T: "rechter winkel"] # 0x221f (en: 'right angle') + - "∠": [T: "winkel"] # 0x2220 (en: 'angle') + - "∡": [T: "gerichteter winkel"] # 0x2221 (en: 'measured angle', MathPlayer: 'measured angle', google: 'gemessener winkel') + - "∩": [T: "schnitt mit"] # 0x2229 (en: 'intersection') #Problem: Schnittmenge wenn alleinstehend vor Bezeichnung, schnitt wenn zwischen 2 Mengen + - "∪": [T: "vereinigt mit"] # 0x222a (en: 'union') #Problem: vereinigungsmenge wenn alleinstehend vor Bezeichnung, vereinigt mit wenn zwischen 2 Mengen + - "∫": [T: "integral"] # 0x222b (en: 'integral') + - "∬": [T: "doppelintegral"] # 0x222c (en: 'double integral') + - "∭": [T: "dreifachintegral"] # 0x222d (en: 'triple integral', MathPlayer: 'Dreifaches Integral', google: 'dreifachintegral') + - "∮": [T: "randintegral"] # 0x222e (en: 'contour integral', MathPlayer: 'Kontur-Integral', google: 'konturintegral') + - "∷": [T: "proportional"] # 0x2237 (en: 'as') + - "∼": [T: "tilde"] # 0x223c (en: 'varies with', MathPlayer: 'tilde operator', google: 'variiert mit') + - "∽": [T: "umgekehrte tilde"] # 0x223d (en: 'reversed tilde', MathPlayer: 'reversed tilde', google: 'umgekehrte tilde') + - "∿": [T: "sinuswelle"] # 0x223f (en: 'sine wave', MathPlayer: 'sine wave', google: 'sinus') From 7c7f9b57564763345bd77afe1161b9978c2c0eac Mon Sep 17 00:00:00 2001 From: mgros Date: Wed, 23 Sep 2026 01:04:33 +0200 Subject: [PATCH 127/157] Add support for stdin, inline MathML, and default fallback --- src/bin/mathml2text.rs | 56 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/src/bin/mathml2text.rs b/src/bin/mathml2text.rs index ff05b5219..f0116ec32 100644 --- a/src/bin/mathml2text.rs +++ b/src/bin/mathml2text.rs @@ -7,6 +7,11 @@ use log::*; use std::path::PathBuf; use clap::{Parser, ValueEnum}; +// The quadratic formula used as the MathCAT demo's starting example. +const DEFAULT_MATHML: &str = r#" + x=−b±b2−4ac2a + "#; + // Maybe also have this speak to test the TTS generation. // There is a rust winapi crate that mirrors the WinPAI and has "Speak(...)" in it @@ -32,8 +37,19 @@ struct Options { #[arg(short, long)] rules_dir: Option, + #[arg( + value_name = "INPUT_FILE", + help = "MathML file to read, or '-' to read from stdin")] input_file: Option, + #[arg( + long, + conflicts_with = "input_file", + value_name = "MATHML", + help = "Use MathML text directly as input", + )] + mathml: Option, + #[arg(short, long, default_value="en")] language: String, @@ -52,22 +68,42 @@ fn main() -> Result<()> { let cli = Options::parse(); - let expr = if let Some(f) = cli.input_file { - std::fs::read_to_string(&f).with_context(|| format!("unable to open {}", f.to_str().unwrap_or_default()))? - } else { - r#" - (1) - "#.to_string() + let expr = match (cli.input_file, cli.mathml) { + + // Match "-" as stdin + (Some(f), None) if f.as_os_str() == std::ffi::OsStr::new("-") => { + let mut mathml = String::new(); + std::io::Read::read_to_string(&mut std::io::stdin(), &mut mathml) + .with_context(|| "unable to read MathML from stdin")?; + mathml + } + + // regular file + (Some(f), None) => { + std::fs::read_to_string(&f) + .with_context(|| format!("unable to open {}", f.to_str().unwrap_or_default()))? + } + + (None, Some(mathml)) => mathml, + + (None, None) => DEFAULT_MATHML.to_string(), + + (Some(_), Some(_)) => unreachable!("clap rejects conflicting input sources"), }; - if let Err(e) = set_rules_dir(get_rules_dir()) { - panic!("Error: exiting -- {}", errors_to_string(&e)); - } + let rules_dir = if let Some(path) = cli.rules_dir { + path.to_str() + .context("Rules directory path must be valid UTF-8")? + .to_string() + } else { + get_rules_dir() + }; + set_rules_dir(&rules_dir).with_context(|| format!("unable to use Rules dir {}", rules_dir))?; debug!("Languages: {}", libmathcat::interface::get_supported_languages()?.join(", ")); #[cfg(feature = "include-zip")] info!("***********include-zip is present**********"); - info!("Version = '{}' using Rules dir {}", get_version(), get_rules_dir()); + info!("Version = '{}' using Rules dir {}", get_version(), rules_dir); set_preference("Language", cli.language)?; set_preference("DecimalSeparator", "Auto").unwrap(); From a8f2e3c1e129d9e6dca160cb36599379bfd96ca6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Arborealis=20L=C3=B6tberg?= <143188129+TimArborealis@users.noreply.github.com> Date: Wed, 23 Sep 2026 17:43:51 +0200 Subject: [PATCH 128/157] Re-add addon info to user guide Added back the info on how to use MathCAT as an addon to NVDA, which was accidentally removed. --- docs/users.md | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/docs/users.md b/docs/users.md index a5ab487d3..7e7c59c12 100644 --- a/docs/users.md +++ b/docs/users.md @@ -10,6 +10,8 @@ MathCAT is a tool used together with a screen reader. Through MathCAT, you can h In screen readers NVDA and JAWS, MathCAT comes built-in. This means you don’t have to install it as an addon. +MathCAT is still available as an addon to NVDA. You can use it if you want access to the very latest features between NVDA releases. [How to use MathCAT as an addon is described here](#how-to-install-mathcat-as-an-addon-in-nvda). + ## Get started with MathCAT Use your screen reader on a web page or in an e-book as usual. When you get to a mathematical expression, the screen reader will read it out automatically. If you want to investigate the expression more closely you can activate the navigation mode by pressing Space. In NVDA, the NVDA-key+Alt+M can also be used. If you want to leave the navigation mode, press Escape. @@ -49,6 +51,7 @@ You can choose between the following settings for speech. Below each setting you - Indonesian (id) - Norwegian bokmål (nb) - Polish (pl) + - Brazilian Portugese (pt) - Russian (ru) - Swedish (sv) - Vietnamese (vi) @@ -137,4 +140,42 @@ Note: tabular math means mathematical content in a table structure such as a mat ## Do you have feedback on MathCAT? -MathCAT is under active development, and we want your feedback. Do you have a feature request, or have you found any bugs? Please create an issue on [MathCAT's GitHub page](https://github.com/daisy/MathCAT/issues). You are also welcome to get in touch by signing up to [the mailing list of the DAISY MathCAT working group](https://www.surveymonkey.com/r/HXTLXGN). \ No newline at end of file +MathCAT is under active development, and we want your feedback. Do you have a feature request, or have you found any bugs? Please create an issue on [MathCAT's GitHub page](https://github.com/daisy/MathCAT/issues). You are also welcome to get in touch by signing up to [the mailing list of the DAISY MathCAT working group](https://www.surveymonkey.com/r/HXTLXGN). + +## How to install MathCAT as an addon in NVDA + +To use MathCAT as an add-on, do the following: + +1. Open the NVDA menu. +2. Choose Tools and then Add-on store. +3. In the add-on store, choose Available add-ons. + + The channel settings have the following options: + - Stable: Will only search for stable add-ons + - All: Will search for all add-ons + - Beta: Will search for add-ons that are in beta + - Dev: Will search for add-ons in development + + Choose option "All". + +4. Search for MathCAT and install. + +5. In the settings menu, you can control how add-ons are updated: + + - Open the NVDA menu + - Choose settings and Add-on Store + + For Automatic updates, you can choose between: + - Notify + - Update Automatically + - Deactivated + + For Default update channel, you have the following options: + + - Same: If automatic updates is set to “Update Automatically” and your add-on is a beta, it will update to the first available beta. + - Any: It will update to any version of the add-on. + - Do not update + - Stable: It will only update to stable versions. + - Beta or dev: It will update to beta or dev versions. + - Beta: It will update to beta versions. + - Dev: It will update to dev versions. From 709b7164af73c8717d1307491f292405bee8f79c Mon Sep 17 00:00:00 2001 From: mgros Date: Thu, 24 Sep 2026 01:35:54 +0200 Subject: [PATCH 129/157] Add rule order checks and reporting for shared rule mismatches --- PythonScripts/audit_translations/README.md | 1 + PythonScripts/audit_translations/auditor.py | 20 +++ .../audit_translations/models/rules.py | 1 + PythonScripts/audit_translations/renderer.py | 9 ++ .../audit_translations/tests/test_auditor.py | 127 ++++++++++++++++++ .../audit_translations/tests/test_parsers.py | 2 +- 6 files changed, 159 insertions(+), 1 deletion(-) diff --git a/PythonScripts/audit_translations/README.md b/PythonScripts/audit_translations/README.md index 241a500d2..5ebf83203 100644 --- a/PythonScripts/audit_translations/README.md +++ b/PythonScripts/audit_translations/README.md @@ -10,6 +10,7 @@ The tool analyzes rule files to detect the following issues: * **Extra Rules:** Rules present in the target translation but absent in the source (flagged as potentially intentional language-specific additions). * **Untranslated Text:** Detects text keys that still use **lowercase** formatting, indicating they haven't been verified or translated yet. * **Rule Differences:** Structural changes (match expressions, conditions, variables, or test/replace layout) between the source and target translation. +* **Rule Order:** After the summary, reports the first differing position of shared named rules in each affected file. Missing, extra, and `# audit-ignore` rules do not shift the comparison. Include entries are not checked. * **Definition Coverage:** Compares literal `definitions.yaml` entries by name and collection kind (`vector`, `set`, or `map`). After a blank line, add `# audit-ignore` immediately before a rule to suppress diff --git a/PythonScripts/audit_translations/auditor.py b/PythonScripts/audit_translations/auditor.py index b67cbf911..6cf718ea1 100644 --- a/PythonScripts/audit_translations/auditor.py +++ b/PythonScripts/audit_translations/auditor.py @@ -19,6 +19,7 @@ print_audit_summary, print_definition_findings, print_language_list, + print_order_findings, print_warnings, ) @@ -109,6 +110,19 @@ def merge_rules(base_rules: list[RuleInfo], region_rules: list[RuleInfo]) -> lis include_untranslated = include_all or "untranslated" in issue_filter include_extra = include_all or "extra" in issue_filter include_diffs = include_all or "diffs" in issue_filter + include_order = include_all + + first_order_mismatch_position = None + if include_order: + source_keys = {rule.key for rule in english_rules if rule.name is not None and not rule.audit_ignore} + target_keys = {rule.key for rule in translated_rules if rule.name is not None and not rule.audit_ignore} + shared_keys = source_keys & target_keys + source_order = [rule for rule in english_rules if rule.key in shared_keys and not rule.audit_ignore] + target_order = [rule for rule in translated_rules if rule.key in shared_keys and not rule.audit_ignore] + for position, (source_rule, target_rule) in enumerate(zip(source_order, target_order), start=1): + if source_rule.key != target_rule.key: + first_order_mismatch_position = position + break # Find missing rules (in source but not in translation) missing_rules = [] @@ -146,6 +160,7 @@ def merge_rules(base_rules: list[RuleInfo], region_rules: list[RuleInfo]) -> lis extra_rules=extra_rules, untranslated_text=untranslated_text, rule_differences=rule_differences, + first_order_mismatch_position=first_order_mismatch_position, english_rule_count=len(english_rules), translated_rule_count=len(translated_rules), ) @@ -262,6 +277,7 @@ def audit_language( total_definition_type_mismatches = 0 files_with_issues = 0 files_ok = 0 + order_findings: list[tuple[str, int]] = [] # One item per file, eg [("calculus.yaml", 2), ...] for file_name in files: english_path = source_dir / file_name @@ -308,6 +324,8 @@ def audit_language( existing_translated_region_path, existing_english_region_path, ) + if result.first_order_mismatch_position is not None: + order_findings.append((file_name, result.first_order_mismatch_position)) if result.has_issues: issues = print_warnings(result, file_name, verbose, language, source_language) @@ -338,6 +356,8 @@ def audit_language( ) ) + print_order_findings(order_findings) + return total_issues diff --git a/PythonScripts/audit_translations/models/rules.py b/PythonScripts/audit_translations/models/rules.py index 39069d9db..fd0044521 100644 --- a/PythonScripts/audit_translations/models/rules.py +++ b/PythonScripts/audit_translations/models/rules.py @@ -107,6 +107,7 @@ class ComparisonResult: english_rule_count: int translated_rule_count: int rule_differences: list[RuleDifference] = field(default_factory=list) + first_order_mismatch_position: int | None = None @property def has_issues(self) -> bool: diff --git a/PythonScripts/audit_translations/renderer.py b/PythonScripts/audit_translations/renderer.py index d79449e80..1ba2db693 100644 --- a/PythonScripts/audit_translations/renderer.py +++ b/PythonScripts/audit_translations/renderer.py @@ -260,6 +260,15 @@ def print_audit_summary(summary: AuditSummary) -> None: console.print(Panel(table, style="cyan")) +def print_order_findings(findings: list[tuple[str, int]]) -> None: + """Print the first shared-rule order difference for each affected file.""" + for file_name, position in findings: + console.print( + f"[yellow]Rule order differs[/] in {escape(str(file_name))}: " + f"first difference at shared rule position {position}" + ) + + def print_language_list(languages: list[tuple[str, int]]) -> None: """Print the available languages table. diff --git a/PythonScripts/audit_translations/tests/test_auditor.py b/PythonScripts/audit_translations/tests/test_auditor.py index 38b63694f..ff7f32a0f 100644 --- a/PythonScripts/audit_translations/tests/test_auditor.py +++ b/PythonScripts/audit_translations/tests/test_auditor.py @@ -46,6 +46,133 @@ def fixture_rules_dir() -> Path: return Path(__file__).resolve().parent / "fixtures" / "Rules" / "Languages" +def test_rule_order_reports_first_shared_difference(tmp_path) -> None: + """A swapped pair records the first shared rule position without adding an issue.""" + source = tmp_path / "source.yaml" + target = tmp_path / "target.yaml" + source.write_text("""- name: a + tag: mi +- name: b + tag: mi +- name: c + tag: mi +""", encoding="utf-8") + target.write_text("""- name: a + tag: mi +- name: c + tag: mi +- name: b + tag: mi +""", encoding="utf-8") + + result = compare_files(source, target) + assert result.first_order_mismatch_position == 2 + assert not result.has_issues + + +def test_missing_and_ignored_rules_do_not_shift_order(tmp_path) -> None: + """Only shared rules without audit-ignore markers participate in ordering.""" + source = tmp_path / "source.yaml" + target = tmp_path / "target.yaml" + source.write_text("""- name: a + tag: mi +- name: missing + tag: mi +- name: b + tag: mi +""", encoding="utf-8") + target.write_text("""- name: a + tag: mi +- name: extra + tag: mi +- name: b + tag: mi +""", encoding="utf-8") + assert compare_files(source, target).first_order_mismatch_position is None + + source.write_text("""- name: a + tag: mi +- name: b + tag: mi +# audit-ignore +- name: c + tag: mi +""", encoding="utf-8") + target.write_text("""# audit-ignore +- name: c + tag: mi +- name: a + tag: mi +- name: b + tag: mi +""", encoding="utf-8") + assert compare_files(source, target).first_order_mismatch_position is None + + +def test_include_placement_is_not_checked(tmp_path) -> None: + """An include moving around a named rule has no effect on named rule order.""" + source = tmp_path / "source.yaml" + target = tmp_path / "target.yaml" + source.write_text("""- include: shared.yaml +- name: a + tag: mi +""", encoding="utf-8") + target.write_text("""- name: a + tag: mi +- include: shared.yaml +""", encoding="utf-8") + result = compare_files(source, target) + assert result.first_order_mismatch_position is None + assert result.english_rule_count == result.translated_rule_count == 1 + assert not result.missing_rules and not result.extra_rules + assert compare_files(source, target, {"missing"}).first_order_mismatch_position is None + + +def test_unicode_entries_are_not_checked_for_order(tmp_path) -> None: + """The order check only covers named rules, not Unicode character entries.""" + source = tmp_path / "unicode.yaml" + target = tmp_path / "target" / "unicode.yaml" + target.parent.mkdir() + source.write_text("""- "←": [t: left] +- "∥": [t: parallel] +""", encoding="utf-8") + target.write_text("""- "∥": [T: parallel] +- "←": [T: left] +""", encoding="utf-8") + + assert compare_files(source, target).first_order_mismatch_position is None + + +def test_order_findings_appear_after_summary_without_affecting_totals(tmp_path, capsys) -> None: + """Each affected file gets one final line while the audit issue count stays zero.""" + rules_dir = tmp_path / "Rules" / "Languages" + source_dir = rules_dir / "en" + target_dir = rules_dir / "de" + source_dir.mkdir(parents=True) + target_dir.mkdir(parents=True) + source = """- name: a + tag: mi +- name: b + tag: mi +""" + target = """- name: b + tag: mi +- name: a + tag: mi +""" + for filename in ("first.yaml", "second.yaml"): + (source_dir / filename).write_text(source, encoding="utf-8") + (target_dir / filename).write_text(target, encoding="utf-8") + + assert audit_language("de", rules_dir=str(rules_dir)) == 0 + output = strip_ansi(capsys.readouterr().out) + assert "Files with issues 0" in output + assert "Rule order differences" not in output + assert output.count("first difference at shared rule position 1") == 2 + assert output.index("SUMMARY") < output.index("Rule order differs in first.yaml") + assert output.index("Rule order differs in first.yaml") < output.index("Rule order differs in second.yaml") + + def aggregate_issue_counts( language: str, issue_filter: set[str] | None = None, diff --git a/PythonScripts/audit_translations/tests/test_parsers.py b/PythonScripts/audit_translations/tests/test_parsers.py index 6714f3581..92ea56ab0 100644 --- a/PythonScripts/audit_translations/tests/test_parsers.py +++ b/PythonScripts/audit_translations/tests/test_parsers.py @@ -303,7 +303,7 @@ def test_skips_items_without_name(self): assert rules[0].name == "real-rule" def test_mixed_valid_and_skipped_items(self): - """Valid rules interspersed with non-rule items keep correct line numbers.""" + """Named rules retain their line numbers around skipped includes.""" content = """- name: first tag: mo match: "." From e42aec2f9cd87f8402b02ec862033878797da48a Mon Sep 17 00:00:00 2001 From: mgros Date: Thu, 24 Sep 2026 01:49:10 +0200 Subject: [PATCH 130/157] fix ruff --- PythonScripts/audit_translations/auditor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PythonScripts/audit_translations/auditor.py b/PythonScripts/audit_translations/auditor.py index 6cf718ea1..a3ce4a3c8 100644 --- a/PythonScripts/audit_translations/auditor.py +++ b/PythonScripts/audit_translations/auditor.py @@ -119,7 +119,7 @@ def merge_rules(base_rules: list[RuleInfo], region_rules: list[RuleInfo]) -> lis shared_keys = source_keys & target_keys source_order = [rule for rule in english_rules if rule.key in shared_keys and not rule.audit_ignore] target_order = [rule for rule in translated_rules if rule.key in shared_keys and not rule.audit_ignore] - for position, (source_rule, target_rule) in enumerate(zip(source_order, target_order), start=1): + for position, (source_rule, target_rule) in enumerate(zip(source_order, target_order, strict=True), start=1): if source_rule.key != target_rule.key: first_order_mismatch_position = position break From 16a830d59ccfdf7f14a5d1a6727ec94189b8076c Mon Sep 17 00:00:00 2001 From: mgros Date: Thu, 24 Sep 2026 01:51:04 +0200 Subject: [PATCH 131/157] uv run ruff format audit_translations/ --- PythonScripts/audit_translations/auditor.py | 2 +- PythonScripts/audit_translations/renderer.py | 3 +- .../audit_translations/tests/test_auditor.py | 70 +++++++++++++------ 3 files changed, 52 insertions(+), 23 deletions(-) diff --git a/PythonScripts/audit_translations/auditor.py b/PythonScripts/audit_translations/auditor.py index a3ce4a3c8..5df06b6fe 100644 --- a/PythonScripts/audit_translations/auditor.py +++ b/PythonScripts/audit_translations/auditor.py @@ -277,7 +277,7 @@ def audit_language( total_definition_type_mismatches = 0 files_with_issues = 0 files_ok = 0 - order_findings: list[tuple[str, int]] = [] # One item per file, eg [("calculus.yaml", 2), ...] + order_findings: list[tuple[str, int]] = [] # One item per file, eg [("calculus.yaml", 2), ...] for file_name in files: english_path = source_dir / file_name diff --git a/PythonScripts/audit_translations/renderer.py b/PythonScripts/audit_translations/renderer.py index 1ba2db693..198aefc54 100644 --- a/PythonScripts/audit_translations/renderer.py +++ b/PythonScripts/audit_translations/renderer.py @@ -264,8 +264,7 @@ def print_order_findings(findings: list[tuple[str, int]]) -> None: """Print the first shared-rule order difference for each affected file.""" for file_name, position in findings: console.print( - f"[yellow]Rule order differs[/] in {escape(str(file_name))}: " - f"first difference at shared rule position {position}" + f"[yellow]Rule order differs[/] in {escape(str(file_name))}: first difference at shared rule position {position}" ) diff --git a/PythonScripts/audit_translations/tests/test_auditor.py b/PythonScripts/audit_translations/tests/test_auditor.py index ff7f32a0f..e8e7ec266 100644 --- a/PythonScripts/audit_translations/tests/test_auditor.py +++ b/PythonScripts/audit_translations/tests/test_auditor.py @@ -50,20 +50,26 @@ def test_rule_order_reports_first_shared_difference(tmp_path) -> None: """A swapped pair records the first shared rule position without adding an issue.""" source = tmp_path / "source.yaml" target = tmp_path / "target.yaml" - source.write_text("""- name: a + source.write_text( + """- name: a tag: mi - name: b tag: mi - name: c tag: mi -""", encoding="utf-8") - target.write_text("""- name: a +""", + encoding="utf-8", + ) + target.write_text( + """- name: a tag: mi - name: c tag: mi - name: b tag: mi -""", encoding="utf-8") +""", + encoding="utf-8", + ) result = compare_files(source, target) assert result.first_order_mismatch_position == 2 @@ -74,38 +80,50 @@ def test_missing_and_ignored_rules_do_not_shift_order(tmp_path) -> None: """Only shared rules without audit-ignore markers participate in ordering.""" source = tmp_path / "source.yaml" target = tmp_path / "target.yaml" - source.write_text("""- name: a + source.write_text( + """- name: a tag: mi - name: missing tag: mi - name: b tag: mi -""", encoding="utf-8") - target.write_text("""- name: a +""", + encoding="utf-8", + ) + target.write_text( + """- name: a tag: mi - name: extra tag: mi - name: b tag: mi -""", encoding="utf-8") +""", + encoding="utf-8", + ) assert compare_files(source, target).first_order_mismatch_position is None - source.write_text("""- name: a + source.write_text( + """- name: a tag: mi - name: b tag: mi # audit-ignore - name: c tag: mi -""", encoding="utf-8") - target.write_text("""# audit-ignore +""", + encoding="utf-8", + ) + target.write_text( + """# audit-ignore - name: c tag: mi - name: a tag: mi - name: b tag: mi -""", encoding="utf-8") +""", + encoding="utf-8", + ) assert compare_files(source, target).first_order_mismatch_position is None @@ -113,14 +131,20 @@ def test_include_placement_is_not_checked(tmp_path) -> None: """An include moving around a named rule has no effect on named rule order.""" source = tmp_path / "source.yaml" target = tmp_path / "target.yaml" - source.write_text("""- include: shared.yaml + source.write_text( + """- include: shared.yaml - name: a tag: mi -""", encoding="utf-8") - target.write_text("""- name: a +""", + encoding="utf-8", + ) + target.write_text( + """- name: a tag: mi - include: shared.yaml -""", encoding="utf-8") +""", + encoding="utf-8", + ) result = compare_files(source, target) assert result.first_order_mismatch_position is None assert result.english_rule_count == result.translated_rule_count == 1 @@ -133,12 +157,18 @@ def test_unicode_entries_are_not_checked_for_order(tmp_path) -> None: source = tmp_path / "unicode.yaml" target = tmp_path / "target" / "unicode.yaml" target.parent.mkdir() - source.write_text("""- "←": [t: left] + source.write_text( + """- "←": [t: left] - "∥": [t: parallel] -""", encoding="utf-8") - target.write_text("""- "∥": [T: parallel] +""", + encoding="utf-8", + ) + target.write_text( + """- "∥": [T: parallel] - "←": [T: left] -""", encoding="utf-8") +""", + encoding="utf-8", + ) assert compare_files(source, target).first_order_mismatch_position is None From fc7d939705581685065f033f6ca20d52e2f8c71f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Thu, 24 Sep 2026 21:08:34 +0200 Subject: [PATCH 132/157] Refactor: Replace custom path utilities with `Path` API and update zip methods accordingly (#775) --- src/rules_archive.rs | 50 ++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/src/rules_archive.rs b/src/rules_archive.rs index 70d8d81fe..938937683 100644 --- a/src/rules_archive.rs +++ b/src/rules_archive.rs @@ -64,17 +64,6 @@ fn is_zip_file(path: &Path) -> bool { return path.extension().map(|ext| ext.eq_ignore_ascii_case("zip")).unwrap_or(false); } -fn posix_path(parts: &[&str]) -> String { - return parts.join("/"); -} - -fn posix_join(prefix: &str, name: &str) -> String { - if prefix.is_empty() { - return name.to_string(); - } - return format!("{}/{}", prefix, name); -} - fn file_name_str(path: &Path) -> io::Result { let name = path .file_name() @@ -305,10 +294,10 @@ fn copy_dir(src: &Path, dst: &Path, minify: bool, parent_is_languages: bool) -> fn add_file_to_zip( zip: &mut ZipWriter, in_path: &Path, - zip_name: &str, + zip_path: &Path, options: SimpleFileOptions, ) -> io::Result<()> { - zip.start_file(zip_name, options) + zip.start_file_from_path(zip_path, options) .map_err(io::Error::other)?; let mut file = File::open(in_path)?; let mut buffer = Vec::new(); @@ -319,11 +308,11 @@ fn add_file_to_zip( fn add_bytes_to_zip( zip: &mut ZipWriter, - zip_name: &str, + zip_path: &Path, bytes: &[u8], options: SimpleFileOptions, ) -> io::Result<()> { - zip.start_file(zip_name, options) + zip.start_file_from_path(zip_path, options) .map_err(io::Error::other)?; zip.write_all(bytes)?; return Ok(()); @@ -332,7 +321,7 @@ fn add_bytes_to_zip( fn zip_entry( zip: &mut ZipWriter, full_path: &Path, - relative_path: &str, + relative_path: &Path, options: SimpleFileOptions, ) -> io::Result { let mut n_files_in_zip = 0; @@ -343,7 +332,7 @@ fn zip_entry( continue; } let entry_name = file_name_str(&entry_path)?; - let child_rel = posix_join(relative_path, &entry_name); + let child_rel = relative_path.join(entry_name); n_files_in_zip += zip_entry(zip, &entry_path, &child_rel, options)?; } } else if is_yaml_file(full_path) { @@ -356,7 +345,7 @@ fn zip_entry( fn write_inner_zip(source_dir: &Path, inner: SimpleFileOptions) -> io::Result>> { let cursor = Cursor::new(Vec::new()); let mut zip = ZipWriter::new(cursor); - let n_files = zip_entry(&mut zip, source_dir, "", inner)?; + let n_files = zip_entry(&mut zip, source_dir, Path::new(""), inner)?; let cursor = zip.finish().map_err(io::Error::other)?; if n_files == 0 { return Ok(None); @@ -370,7 +359,7 @@ fn zip_dir( archive_zip: &mut ZipWriter, inner: SimpleFileOptions, outer: SimpleFileOptions, - archive_prefix: &str, + archive_prefix: &Path, ) -> io::Result<()> { if !rules_section.is_dir() { return Ok(()); @@ -386,14 +375,14 @@ fn zip_dir( continue; } if let Some(bytes) = write_inner_zip(&entry_path, inner)? { - let zip_name = posix_path(&[archive_prefix, &dir_name, &format!("{}.zip", dir_name)]); - add_bytes_to_zip(archive_zip, &zip_name, &bytes, outer)?; + let zip_path = archive_prefix.join(&dir_name).join(format!("{dir_name}.zip")); + add_bytes_to_zip(archive_zip, &zip_path, &bytes, outer)?; } } else if is_yaml_file(&entry_path) { // e.g. Rules/Braille/definitions.yaml let name = file_name_str(&entry_path)?; - let zip_name = posix_path(&[archive_prefix, &name]); - add_file_to_zip(archive_zip, &entry_path, &zip_name, outer)?; + let zip_path = archive_prefix.join(name); + add_file_to_zip(archive_zip, &entry_path, &zip_path, outer)?; } } return Ok(()); @@ -404,7 +393,7 @@ fn zip_other_files( rules_dir: &Path, archive_zip: &mut ZipWriter, outer: SimpleFileOptions, - archive_prefix: &str, + archive_prefix: &Path, ) -> io::Result<()> { for entry in read_dir(rules_dir)? { let entry_path = entry?.path(); @@ -415,12 +404,12 @@ fn zip_other_files( &rules_dir.join("Intent"), archive_zip, outer, - &posix_join(archive_prefix, "Intent"), + &archive_prefix.join("Intent"), )?; } } else if is_yaml_file(&entry_path) { - let zip_name = posix_join(archive_prefix, &entry_name); - add_file_to_zip(archive_zip, &entry_path, &zip_name, outer)?; + let zip_path = archive_prefix.join(entry_name); + add_file_to_zip(archive_zip, &entry_path, &zip_path, outer)?; } } return Ok(()); @@ -441,21 +430,22 @@ pub fn write_rules_archive( let outer = zip_options(compression.outer); let archive_zip_file = File::create(output)?; let mut archive_zip = ZipWriter::new(archive_zip_file); + let archive_root = Path::new(ARCHIVE_ROOT); - zip_other_files(rules_dir, &mut archive_zip, outer, ARCHIVE_ROOT)?; + zip_other_files(rules_dir, &mut archive_zip, outer, archive_root)?; zip_dir( &rules_dir.join("Languages"), &mut archive_zip, inner, outer, - &posix_join(ARCHIVE_ROOT, "Languages"), + &archive_root.join("Languages"), )?; zip_dir( &rules_dir.join("Braille"), &mut archive_zip, inner, outer, - &posix_join(ARCHIVE_ROOT, "Braille"), + &archive_root.join("Braille"), )?; archive_zip.finish().map_err(io::Error::other)?; From e79dda767673b9349d15d6d71b4bd3ed1501890c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Thu, 24 Sep 2026 21:15:47 +0200 Subject: [PATCH 133/157] Refactor navigation state management: unify position and command stacks into a single history vector (#776) * Refactor navigation state management: unify position and command stacks into a single history vector * fix cargo clippy no-unsafe --- src/navigate.rs | 79 ++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 44 deletions(-) diff --git a/src/navigate.rs b/src/navigate.rs index d1444a86c..b398f3c75 100644 --- a/src/navigate.rs +++ b/src/navigate.rs @@ -52,6 +52,12 @@ struct NavigationPosition { current_node_offset: usize, // for leaves, char offset in leaf (default = 0), otherwise id for artificial intent node } +#[derive(Clone, Debug)] +struct NavigationHistoryEntry { + position: NavigationPosition, + command: &'static str, +} + impl fmt::Display for NavigationPosition { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { return write!(f, "{}[+{}]", self.current_node, self.current_node_offset); @@ -71,10 +77,7 @@ impl Default for NavigationPosition { #[derive(Debug, Clone)] pub struct NavigationState { - // it might be better to use a linked for the stacks, with the first node being the top - // these two stacks should be kept in sync. - position_stack: Vec, // all positions, so we can go back to them - command_stack: Vec<&'static str>, // all commands, so we can undo them + history: Vec, // positions and commands, so we can undo them place_markers: [NavigationPosition; MAX_PLACE_MARKERS], where_am_i: NavigationPosition, // current 'where am i' location @@ -90,13 +93,13 @@ impl fmt::Display for NavigationState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { writeln!(f, "NavigationState{{")?; write!(f, " Position Stack: ")?; - for (i, nav_state) in self.position_stack.iter().enumerate() { - write!(f, "{}{}", if i==0 {""} else {", "}, nav_state)?; + for (i, entry) in self.history.iter().enumerate() { + write!(f, "{}{}", if i==0 {""} else {", "}, entry.position)?; } writeln!(f)?; write!(f, " Command Stack: ")?; - for (i, nav_state) in self.command_stack.iter().enumerate() { - write!(f, "{}{}", if i==0 {""} else {", "}, *nav_state)?; + for (i, entry) in self.history.iter().enumerate() { + write!(f, "{}{}", if i==0 {""} else {", "}, entry.command)?; } writeln!(f)?; writeln!(f, " where_am_i: {}, start_time: {:?}", self.where_am_i, self.where_am_i_start_time)?; @@ -109,8 +112,7 @@ impl fmt::Display for NavigationState { impl NavigationState { fn new() -> NavigationState { return NavigationState { - position_stack: Vec::with_capacity(1024), - command_stack: Vec::with_capacity(1024), + history: Vec::with_capacity(1024), place_markers: Default::default(), where_am_i: NavigationPosition::default(), // FIX: figure this out for the web @@ -124,8 +126,7 @@ impl NavigationState { } pub fn reset(&mut self) { - self.position_stack.clear(); - self.command_stack.clear(); + self.history.clear(); self.where_am_i = NavigationPosition::default(); self.reset_start_time() } @@ -146,32 +147,22 @@ impl NavigationState { fn push(&mut self, position: NavigationPosition, command: &'static str) { - self.position_stack.push(position); - self.command_stack.push(command); + self.history.push(NavigationHistoryEntry { position, command }); } - fn pop(&mut self) -> Option<(NavigationPosition, &'static str)> { - assert_eq!(self.position_stack.len(), self.command_stack.len()); - if self.position_stack.is_empty() { - return None; - } else { - return Some( (self.position_stack.pop().unwrap(), self.command_stack.pop().unwrap()) ); - } + fn pop(&mut self) -> Option { + return self.history.pop(); } - fn top(&self) -> Option<(&NavigationPosition, &'static str)> { - if self.position_stack.is_empty() { - return None; - } - let last = self.position_stack.len()-1; - return Some( (&self.position_stack[last], self.command_stack[last]) ); + fn top(&self) -> Option<&NavigationHistoryEntry> { + return self.history.last(); } pub fn get_navigation_mathml<'a>(&self, mathml: Element<'a>) -> Result<(Element<'a>, usize)> { - if self.position_stack.is_empty() { + if self.history.is_empty() { return Ok( (mathml, 0) ); } else { - let (position, _) = self.top().unwrap(); + let position = &self.top().unwrap().position; return match get_node_by_id(mathml, position) { None => bail!("internal error: id '{}' was not found in mathml:\n{}", position.current_node, mml_to_string(mathml)), @@ -181,23 +172,23 @@ impl NavigationState { } pub fn get_navigation_mathml_id(&self, mathml: Element) -> (String, usize) { - if self.position_stack.is_empty() { + if self.history.is_empty() { return (mathml.attribute_value("id").unwrap().to_string(), 0); } else { - let (position, _) = self.top().unwrap(); + let position = &self.top().unwrap().position; return (position.current_node.clone(), position.current_node_offset); } } fn init_navigation_context(&self, context: &mut sxd_xpath_no_unsafe::Context, command: &'static str, - nav_state_top: Option<(&NavigationPosition, &'static str)>) { + nav_state_top: Option<&NavigationHistoryEntry>) { context.set_variable("NavCommand", command); if command == "WhereAmI" && self.where_am_i == NavigationPosition::default() { context.set_variable("NavNode", self.where_am_i.current_node.as_str()); context.set_variable("NavNodeOffset", self.where_am_i.current_node_offset as f64); } else { - let position = &self.position_stack[self.position_stack.len()-1]; + let position = &self.history.last().unwrap().position; context.set_variable("NavNode", position.current_node.as_str()); context.set_variable("NavNodeOffset", position.current_node_offset as f64); } @@ -218,7 +209,7 @@ impl NavigationState { if command == "MoveLastLocation" { let previous_command = match nav_state_top { None => "None", - Some( (_, previous_command) ) => previous_command, + Some(entry) => entry.command, }; context.set_variable("PreviousNavCommand", previous_command); } @@ -372,7 +363,7 @@ pub fn do_navigate_command_string(mathml: Element, nav_command: &'static str) -> return NAVIGATION_STATE.with(|nav_state| { let mut nav_state = nav_state.borrow_mut(); // debug!("MathML: {}", mml_to_string(mathml)); - if nav_state.position_stack.is_empty() { + if nav_state.history.is_empty() { // initialize to root node nav_state.push(NavigationPosition{ current_node: mathml.attribute_value("id").unwrap().to_string(), @@ -440,7 +431,7 @@ pub fn do_navigate_command_string(mathml: Element, nav_command: &'static str) -> } bail!("Internal error: Navigation exceeded limit of number of times no speech generated when attempting to {} in {} mode start at id={} in this MathML:\n{}.", - nav_command, nav_state.mode, nav_state.top().unwrap().0.current_node, mml_to_string(mathml)); + nav_command, nav_state.mode, nav_state.top().unwrap().position.current_node, mml_to_string(mathml)); }); }); @@ -450,14 +441,14 @@ pub fn do_navigate_command_string(mathml: Element, nav_command: &'static str) -> let nav_position = NavigationPosition { current_node: mathml.attribute_value("id").unwrap().to_string(), current_node_offset: 0 }; get_node_by_id(mathml, &nav_position) }, - Some( (position, _) ) => get_node_by_id(mathml, position), + Some(entry) => get_node_by_id(mathml, &entry.position), }; return match element { Some(node) => Ok(node), None => { bail!("Internal Error: didn't find id/offset '{:?}' while attempting to start navigation. MathML is\n{}", - nav_state.top().map(|t| t.0), mml_to_string(mathml)); + nav_state.top().map(|entry| &entry.position), mml_to_string(mathml)); } }; } @@ -518,7 +509,7 @@ pub fn do_navigate_command_string(mathml: Element, nav_command: &'static str) -> // debug!("intent=\n{}", mml_to_string(intent)); // debug!("nav intent=\n{}", mml_to_string(nav_intent)); - // debug!("start_node id={}\n{}", nav_state.top().unwrap().0.current_node.as_str(), mml_to_string(start_node)); + // debug!("start_node id={}\n{}", nav_state.top().unwrap().position.current_node.as_str(), mml_to_string(start_node)); // if name(start_node) != "math" { // let mut parent= get_parent(start_node); // if name(parent) != "math" { @@ -528,7 +519,7 @@ pub fn do_navigate_command_string(mathml: Element, nav_command: &'static str) -> // } let offset = context_get_int_variable(rules_with_context.get_context(), "NavNodeOffset", intent)?; rules_with_context.set_nav_node_offset(offset); - debug!("starting nav_position: {}, start node ={}", nav_state.top().unwrap().0, name(start_node)); + debug!("starting nav_position: {}, start node ={}", nav_state.top().unwrap().position, name(start_node)); let raw_speech_string = rules_with_context.match_pattern::(start_node) .context("Pattern match/replacement failure during math navigation!")?; @@ -569,7 +560,7 @@ pub fn do_navigate_command_string(mathml: Element, nav_command: &'static str) -> debug!("after match nav_position: {}", nav_position); // push the new location on the stack - if nav_position != NavigationPosition::default() && &nav_position != nav_state.top().unwrap().0 { + if nav_position != NavigationPosition::default() && nav_position != nav_state.top().unwrap().position { nav_state.push(nav_position.clone(), nav_command); } @@ -634,12 +625,12 @@ pub fn do_navigate_command_string(mathml: Element, nav_command: &'static str) -> let push_command_on_stack = (nav_command.starts_with("Move") && nav_command != "MoveLastLocation") || nav_command.starts_with("Zoom"); // debug!("pop_stack: nav_command={}, count={}, push? {} stack=\n{}", nav_command, count, push_command_on_stack, nav_state); if count == 0 { - if !push_command_on_stack && nav_command == nav_state.top().unwrap().1 { + if !push_command_on_stack && nav_command == nav_state.top().unwrap().command { nav_state.pop(); // remove ReadXXX, SetPlacemarker, etc. commands that don't change the state } return; } - let (top_position, top_command) = nav_state.pop().unwrap(); + let top_entry = nav_state.pop().unwrap(); let mut count = count - 1; loop { // debug!(" ... loop count={}", count); @@ -650,7 +641,7 @@ pub fn do_navigate_command_string(mathml: Element, nav_command: &'static str) -> count -= 1; }; if push_command_on_stack { - nav_state.push(top_position, top_command); + nav_state.push(top_entry.position, top_entry.command); } // debug!("END pop_stack: stack=\n{}", nav_state); } From c1130286b6dcce18d5dc8f0e4d841d45bc646f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Thu, 24 Sep 2026 21:24:26 +0200 Subject: [PATCH 134/157] simplify `read_prefs_file` (#808) * Refactor `read_prefs_file` to simplify error handling and optimize section processing * use with_context(..) from anyhow-crate for error-handling --- src/prefs.rs | 41 +++++++++++++---------------------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/src/prefs.rs b/src/prefs.rs index f515ca483..162574c5b 100644 --- a/src/prefs.rs +++ b/src/prefs.rs @@ -106,37 +106,24 @@ impl Preferences{ fn read_prefs_file(file: &Path, mut base_prefs: Preferences) -> Result { let file_name = file.to_str().unwrap(); - let docs; - match read_to_string_shim(file) { - Err(e) => { - bail!("Couldn't read file {}\n{}", file_name, e); - }, - Ok( file_contents) => { - match YamlLoader::load_from_str(&file_contents) { - Err(e) => { - bail!("Yaml parse error ('{}') in preference file {}.", e, file_name); - }, - Ok(d) => docs = d, - } - - } - } + let file_contents = read_to_string_shim(file) + .with_context(|| format!("Couldn't read file {file_name}"))?; + let docs = YamlLoader::load_from_str(&file_contents) + .with_context(|| format!("Yaml parse error in preference file {file_name}."))?; if docs.len() != 1 { bail!("MathCAT: error in prefs file '{}'.\nFound {} 'documents' -- should only be 1.", file_name, docs.len()); } let doc = &docs[0]; + const SECTIONS: [&str; 4] = ["Speech", "Navigation", "Braille", "Other"]; if cfg!(debug_assertions) { - verify_keys(doc, "Speech", file_name)?; - verify_keys(doc, "Navigation", file_name)?; - verify_keys(doc, "Braille", file_name)?; - verify_keys(doc, "Other", file_name)?; + for section in SECTIONS { + verify_keys(doc, section, file_name)?; + } + } + for section in SECTIONS { + add_prefs(&mut base_prefs.prefs, &doc[section], "", file_name); } - - add_prefs(&mut base_prefs.prefs, &doc["Speech"], "", file_name); - add_prefs(&mut base_prefs.prefs, &doc["Navigation"], "", file_name); - add_prefs(&mut base_prefs.prefs, &doc["Braille"], "", file_name); - add_prefs(&mut base_prefs.prefs, &doc["Other"], "", file_name); return Ok(base_prefs); @@ -260,10 +247,8 @@ impl PreferenceManager { // Note: if current_dir() also fails, unwrap_or_default yields an empty PathBuf, // and the result may remain relative. #[cfg(not(feature = "include-zip"))] - let rules_dir = match canonicalize_shim(&rules_dir) { - Err(e) => bail!("set_rules_dir: could not canonicalize path {}: {}", rules_dir.display(), e), - Ok(rules_dir) => rules_dir, - }; + let rules_dir = canonicalize_shim(&rules_dir) + .with_context(|| format!("set_rules_dir: could not canonicalize path {}", rules_dir.display()))?; self.set_rules_dir(&rules_dir)?; self.set_preference_files()?; From 7764ea64c13f86300206871547f5e244ad4fb175 Mon Sep 17 00:00:00 2001 From: mgros Date: Wed, 23 Sep 2026 22:15:41 +0200 Subject: [PATCH 135/157] Replace `unwrap()` with `let Some(...) else` constructs for safer option handling --- src/interface.rs | 5 ++--- src/speech.rs | 43 +++++++++++++++--------------------------- src/xpath_functions.rs | 10 ++++------ 3 files changed, 21 insertions(+), 37 deletions(-) diff --git a/src/interface.rs b/src/interface.rs index 157a895f1..20389959f 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -526,11 +526,10 @@ pub fn do_navigate_command(command: impl AsRef) -> Result { enable_logs(); let command = command.as_ref().to_string(); let result = catch_unwind(AssertUnwindSafe(|| { - let cmd = NAV_COMMANDS.get_key(&command); // gets a &'static version of the command - if cmd.is_none() { + let Some(cmd) = NAV_COMMANDS.get_key(&command) else { // gets a &'static version of the command. bail!("Unknown command in call to DoNavigateCommand()"); }; - let cmd = *cmd.unwrap(); + let cmd = *cmd; MATHML_INSTANCE.with(|package_instance| { let package_instance = package_instance.borrow(); let mathml = get_element(&package_instance); diff --git a/src/speech.rs b/src/speech.rs index 6d5b252a7..4b6691bec 100644 --- a/src/speech.rs +++ b/src/speech.rs @@ -431,11 +431,9 @@ impl fmt::Display for Replacement { impl Replacement { fn build(replacement: &Yaml) -> Result { // Replacement -- single key/value (see below for allowed values) - let dictionary = replacement.as_hash(); - if dictionary.is_none() { + let Some(dictionary) = replacement.as_hash() else { bail!(" expected a key/value pair. Found {}.", yaml_to_string(replacement, 0)); }; - let dictionary = dictionary.unwrap(); if dictionary.is_empty() { bail!("No key/value pairs found for key 'replace'.\n\ Suggestion: are the following lines indented properly?"); @@ -898,8 +896,7 @@ impl ReplacementArray { /// Any errors are passed back out. pub fn build(replacements: &Yaml) -> Result { // replacements is either a single replacement or an array of replacements - let result= if replacements.is_array() { - let replacements = replacements.as_vec().unwrap(); + let result= if let Some(replacements) = replacements.as_vec() { replacements .iter() .enumerate() // useful for errors @@ -1173,12 +1170,9 @@ impl MyXPath { /// Convert DEBUG(...) input to the internal function which is DEBUG(arg, arg_as_string) fn add_debug_string_arg(xpath: &str) -> Result { // do a quick check to see if "DEBUG" is in the string -- this is the common case - let debug_start = xpath.find("DEBUG("); - if debug_start.is_none() { + let Some(debug_start) = xpath.find("DEBUG(") else { return Ok( xpath.to_string() ); - } - - let debug_start = debug_start.unwrap(); + }; let mut before_paren = xpath[..debug_start+5].to_string(); // includes "DEBUG" let chars = xpath[debug_start+5..].chars().collect::>(); // begins at '(' before_paren.push_str(&chars_add_debug_string_arg(&chars).with_context(|| format!("In xpath='{xpath}'"))?); @@ -1469,9 +1463,9 @@ impl TestArray { // 'if:' should only be the first entry in the array; 'else_if' should never be the first entry. Otherwise, they are the same let mut test_array = vec![]; for test in tests { - if test.as_hash().is_none() { + let Some(test_hash) = test.as_hash() else { bail!("Value for array entry in 'test:' must be a dictionary/contain keys"); - } + }; let if_part = &test[if test_array.is_empty() {"if"} else {"else_if"}]; if !if_part.is_badvalue() { // first case: if:, then:, optional else: @@ -1479,7 +1473,7 @@ impl TestArray { let then_part = TestOrReplacements::build(test, "then", "then_test", true)?; let else_part = TestOrReplacements::build(test, "else", "else_test", false)?; let n_keys = if else_part.is_none() {2} else {3}; - if test.as_hash().unwrap().len() > n_keys { + if test_hash.len() > n_keys { bail!("A key other than 'if', 'else_if', 'then', 'then_test', 'else', or 'else_test' was found in the 'then' clause of 'test'"); }; test_array.push( @@ -1488,7 +1482,7 @@ impl TestArray { } else { // second case: should be else/else_test let else_part = TestOrReplacements::build(test, "else", "else_test", true)?; - if test.as_hash().unwrap().len() > 1 { + if test_hash.len() > 1 { bail!("A key other than 'if', 'else_if', 'then', 'then_test', 'else', or 'else_test' was found the 'else' clause of 'test'"); }; test_array.push( @@ -1715,8 +1709,7 @@ impl VariableDefinitions { if defs.is_badvalue() { return Ok( VariableDefinitions::new(0) ); }; - if defs.is_array() { - let defs = defs.as_vec().unwrap(); + if let Some(defs) = defs.as_vec() { let mut definitions = VariableDefinitions::new(defs.len()); for def in defs { let variable_def = VariableDefinition::build(def) @@ -1874,12 +1867,9 @@ impl UnicodeDef { return Ok( Some(process_include(file_name, include_file_name, do_include_fn)?) ); } // key: char, value is replacement or array of replacements - let dictionary = unicode_def.as_hash(); - if dictionary.is_none() { + let Some(dictionary) = unicode_def.as_hash() else { bail!("Expected a unicode definition (e.g, '+':[t: \"plus\"]'), found {}", yaml_to_string(unicode_def, 0)); - } - - let dictionary = dictionary.unwrap(); + }; if dictionary.len() != 1 { bail!("Expected a unicode definition (e.g, '+':[t: \"plus\"]'), found {}", yaml_to_string(unicode_def, 0)); } @@ -2334,11 +2324,9 @@ impl SpeechRules { fn build_speech_patterns(&mut self, patterns: &Yaml, file_name: &Path) -> Result> { // Rule::SpeechPatternList - let patterns_vec = patterns.as_vec(); - if patterns_vec.is_none() { + let Some(patterns_vec) = patterns.as_vec() else { bail!(yaml_type_err(patterns, "array")); - } - let patterns_vec = patterns.as_vec().unwrap(); + }; let mut files_read = vec![file_name.to_path_buf()]; for entry in patterns_vec.iter() { if let Some(mut added_files) = SpeechPattern::build(entry, file_name, self)? { @@ -2368,12 +2356,11 @@ impl SpeechRules { // info!("Reading unicode file {}", path.to_str().unwrap()); let unicode_file_contents = read_to_string_shim(&path)?; let unicode_build_fn = |unicode_def_list: &Yaml| { - let unicode_defs = unicode_def_list.as_vec(); - if unicode_defs.is_none() { + let Some(unicode_defs) = unicode_def_list.as_vec() else { bail!("File '{}' does not begin with an array", yaml_to_type(unicode_def_list)); }; let mut files_read = vec![path.to_path_buf()]; - for unicode_def in unicode_defs.unwrap() { + for unicode_def in unicode_defs { if let Some(mut added_files) = UnicodeDef::build(unicode_def, &path, self, use_short) .with_context(|| {format!("In file {:?}", path.to_str())})? { files_read.append(&mut added_files); diff --git a/src/xpath_functions.rs b/src/xpath_functions.rs index 17b6d360b..ec2f7c4ec 100644 --- a/src/xpath_functions.rs +++ b/src/xpath_functions.rs @@ -266,14 +266,12 @@ impl IsNode { return false; } - let num = children[0].element(); - let denom = children[1].element(); - if num.is_none() || denom.is_none() { + let Some(num) = children[0].element() else { + return false; + }; + let Some(denom) = children[1].element() else { return false; }; - - let num = num.unwrap(); - let denom = denom.unwrap(); if !is_tag(num, "mn") || !is_tag(denom, "mn") { return false }; From 2b801136fee44a27ba36d32fd8a8d77b1a04c92f Mon Sep 17 00:00:00 2001 From: mgros Date: Thu, 24 Sep 2026 22:46:36 +0200 Subject: [PATCH 136/157] simplify destructuring syntax using tuples --- src/xpath_functions.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/xpath_functions.rs b/src/xpath_functions.rs index ec2f7c4ec..a713fad88 100644 --- a/src/xpath_functions.rs +++ b/src/xpath_functions.rs @@ -266,10 +266,7 @@ impl IsNode { return false; } - let Some(num) = children[0].element() else { - return false; - }; - let Some(denom) = children[1].element() else { + let (Some(num), Some(denom)) = (children[0].element(), children[1].element()) else { return false; }; if !is_tag(num, "mn") || !is_tag(denom, "mn") { From 824cdda5d940ebcf2e6431202312b354198e699c Mon Sep 17 00:00:00 2001 From: mgros Date: Sun, 20 Sep 2026 02:58:37 +0200 Subject: [PATCH 137/157] use elements.rs as chemistry database --- Cargo.lock | 12 +++++ Cargo.toml | 1 + src/chemistry.rs | 120 ++++++++++++++++++++++++++++------------------- 3 files changed, 84 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 50bccf29f..529029471 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -447,6 +447,17 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "780955b8b195a21ab8e4ac6b60dd1dbdcec1dc6c51c0617964b08c81785e12c9" +[[package]] +name = "elements_rs" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5834efe826a9a66b548e0887d9fc744fc8bb57065dcc6e5495359b25ab98319" +dependencies = [ + "strum", + "strum_macros", + "thiserror 2.0.18", +] + [[package]] name = "encoding_rs" version = "0.8.35" @@ -784,6 +795,7 @@ dependencies = [ "cfg-if", "clap", "dirs", + "elements_rs", "env_logger", "fastrand", "html-escape", diff --git a/Cargo.toml b/Cargo.toml index 2e73cbf80..e07193031 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ cfg-if = "1.0.1" fastrand = { version = "2.3.0" } clap = { version = "4.5.60", features = ["derive"] } html-escape = "0.2.13" +elements_rs = { version = "0.2.8", default-features = false } # Runtime extracts inner language/braille zips (BZIP2). The package-rules binary also # writes DEFLATE outer archives for Windows/unzip-compatible Rules.zip downloads. diff --git a/src/chemistry.rs b/src/chemistry.rs index 173c5cccb..f54e018dd 100644 --- a/src/chemistry.rs +++ b/src/chemistry.rs @@ -52,6 +52,10 @@ use std::collections::HashSet; use std::cmp::Ordering; use crate::errors::*; use std::sync::LazyLock; +use elements_rs::{ + AtomicNumber, Electronegativity, Element as PeriodicElement, ElementCategory, + ElementClassification, +}; pub static NOT_CHEMISTRY: i32 = -10000; // should overwhelm any positive signal @@ -411,7 +415,7 @@ pub fn convert_leaves_to_chem_elements(mathml: Element) -> Option> } match str::from_utf8(&bytes_str[..n]) { Ok(chem_element) => { - if CHEMICAL_ELEMENT_ELECTRONEGATIVITY.contains_key(chem_element) { + if is_known_chemical_symbol(chem_element) { return Some(new_chemical_element(doc, chem_element)); } return None; @@ -1254,7 +1258,7 @@ fn likely_chem_formula(mathml: Element) -> i32 { fn is_order_ok(mrow: Element) -> bool { assert_eq!(name(mrow), "mrow"); if let Some(elements) = collect_elements(mrow) { - if elements.iter().any(|e| !CHEMICAL_ELEMENT_ELECTRONEGATIVITY.contains_key(as_str!(*e))) { + if elements.iter().any(|e| !is_known_chemical_symbol(as_str!(e))) { return false; } let n_elements = elements.len(); @@ -1278,10 +1282,10 @@ fn is_order_ok(mrow: Element) -> bool { fn has_noble_element(elements: &[NameStr<'_>]) -> bool { - static NOBLE_ELEMENTS: phf::Set<&str> = phf_set! { - "He", "Ne", "Ar", "Kr", "Xe", "Rn", "Og" // Og might be reactive, but it is unstable - }; - return elements.iter().any(|e| NOBLE_ELEMENTS.contains(as_str!(*e))); + return elements.iter().any(|symbol| { + periodic_element(as_str!(symbol)) + .is_some_and(|e| e.classification() == ElementCategory::NobleGas) + }); } #[allow(clippy::manual_contains)] @@ -1343,7 +1347,9 @@ fn is_ordered_by_electronegativity(elements: &[NameStr<'_>]) -> bool { // HPO_4^2 (Mono-hydrogen phosphate) doesn't fit this pattern, nor does HCO_3^- (Hydrogen carbonate) and some others // FIX: drop "H" from the ordering?? assert!(elements.len() > 1); // already handled - return elements.windows(2).all(|pair| CHEMICAL_ELEMENT_ELECTRONEGATIVITY.get(as_str!(pair[0])).unwrap() < CHEMICAL_ELEMENT_ELECTRONEGATIVITY.get(as_str!(pair[1])).unwrap()); + return elements.windows(2).all(|pair| { + chemical_electronegativity(as_str!(pair[0])).unwrap() < chemical_electronegativity(as_str!(pair[1])).unwrap() + }); } fn is_generalized_salt(elements: &[NameStr<'_>]) -> bool { @@ -1429,8 +1435,8 @@ pub fn likely_adorned_chem_formula(mathml: Element) -> i32 { let base = as_element(children[0]); let base_name = name(base); let atomic_number = if matches!(as_str!(base_name), "mi" | "mtext") && - let Some(atomic_number) = CHEMICAL_ELEMENT_ATOMIC_NUMBER.get(as_str!(as_text(base))) { - *atomic_number + let Some(atomic_number) = chemical_element_atomic_number(as_str!(as_text(base))) { + atomic_number } else { return NOT_CHEMISTRY; }; @@ -1835,46 +1841,34 @@ fn convert_to_short_form(mathml: Element) -> Result { } } -/// A map of chemical elements and their relative IUPAC electronegativity (https://i.stack.imgur.com/VCSzW.png) -/// That list uses a horizontal line for the Lanthanide and Actinide Series. -/// Because I had already ordered the elements before realizing that, I opened a gap and started the higher ones again with a '1' in front. -/// The list is missing recent (unstable) elements -- I added them with the same value as the element above them in the periodic table. -static CHEMICAL_ELEMENT_ELECTRONEGATIVITY: phf::Map<&str, u32> = phf_map! { - "Ac" => 40, "Ag" => 155, "Al" => 163, "Am" => 29, "Ar" => 4, "As" => 172, "At" => 181, "Au" => 154, - "B" => 164, "Ba" => 14, "Be" => 18, "Bh" => 137, "Bi" => 170, "Bk" => 27, "Br" => 183, - "C" => 169, "Ca" => 16, "Cd" => 158, "Ce" => 56, "Cf" => 26, "Cl" => 184, "Cm" => 28, "Cn" => 157, "Co" => 148, "Cr" => 136, "Cs" => 8, "Cu" => 156, - "Db" => 129, "Ds" => 149, "Dy" => 48, - "Er" => 46, "Es" => 25, "Eu" => 51, "F" => 185, "Fe" => 144, "Fl" => 165, "Fm" => 24, "Fr" => 7, "Ga" => 162, "Gd" => 50, "Ge" => 167, - "H" => 175, "He" => 6, "Hf" => 126, "Hg" => 157, "Ho" => 47, "Hs" => 141, "I" => 182, "In" => 161, "Ir" => 146, "K" => 10, "Kr" => 3, - "La" => 62, "Li" => 12, "Lr" => 19, "Lu" => 41, "Lv" => 176, "Mc" => 170, "Md" => 23, "Mg" => 17, "Mn" => 140, "Mo" => 135, "Mt" => 145, - "N" => 174, "Na" => 11, "Nb" => 131, "Nd" => 54, "Ne" => 5, "Nh" => 160, "Ni" => 152, "No" => 22, "Np" => 31, "O" => 180, "Og" => 1, "Os" => 142, - "P" => 173, "Pa" => 33, "Pb" => 165, "Pd" => 151, "Pm" => 53, "Po" => 176, "Pr" => 55, "Pt" => 150, "Pu" => 30, - "Ra" => 13, "Rb" => 9, "Re" => 138, "Rf" => 125, "Rg" => 153, "Rh" => 147, "Rn" => 1, "Ru" => 143, - "S" => 179, "Sb" => 171, "Sc" => 124, "Se" => 178, "Sg" => 133, "Si" => 168, "Sm" => 52, "Sn" => 166, "Sr" => 15, - "Ta" => 130, "Tb" => 49, "Tc" => 139, "Te" => 177, "Th" => 34, "Ti" => 128, "Tl" => 160, "Tm" => 45, "Ts" => 181, - "U" => 32, "V" => 132, "W" => 134, "Xe" => 2, "Y" => 123, "Yb" => 44, "Zn" => 159, "Zr" => 127, - // The following come from E.A. Moore who said to treat them like chemicals - // These stand for methyl, ethyl, alkyl, acetyl and phenyl and apparently are quite commonly used ("Ac" is already a chemical) - // A full(er?) list is at en.wikipedia.org/wiki/Skeletal_formula#Alkyl_groups and in following sections - "Me" => 0, "Et" => 0, "R" => 0, /* "Ac" => 0, */ "Ph" => 0, - "X" => 0, /* treated as an unknown */ +// These MathCAT-specific abbreviations are commonly used in chemical formulae, but are not +// elements. Ac is deliberately absent: it is the real element actinium, even when authors use +// the same spelling for acetyl. X represents an unknown element in MathCAT's chemistry heuristic. +static CHEMICAL_ABBREVIATIONS: phf::Set<&str> = phf_set! { + "Me", "Et", "R", "Ph", "X" }; -// A map of the chemical elements and their atomic numbers -static CHEMICAL_ELEMENT_ATOMIC_NUMBER: phf::Map<&str, u32> = phf_map! { - "H" => 1, "He" => 2, "Li" => 3, "Be" => 4, "B" => 5, "C" => 6, "N" => 7, "O" => 8, "F" => 9, "Ne" => 10, - "Na" => 11, "Mg" => 12, "Al" => 13, "Si" => 14, "P" => 15, "S" => 16, "Cl" => 17, "Ar" => 18, "K" => 19, "Ca" => 20, - "Sc" => 21, "Ti" => 22, "V" => 23, "Cr" => 24, "Mn" => 25, "Fe" => 26, "Co" => 27, "Ni" => 28, "Cu" => 29, "Zn" => 30, - "Ga" => 31, "Ge" => 32, "As" => 33, "Se" => 34, "Br" => 35, "Kr" => 36, "Rb" => 37, "Sr" => 38, "Y" => 39, "Zr" => 40, - "Nb" => 41, "Mo" => 42, "Tc" => 43, "Ru" => 44, "Rh" => 45, "Pd" => 46, "Ag" => 47, "Cd" => 48, "In" => 49, "Sn" => 50, - "Sb" => 51, "Te" => 52, "I" => 53, "Xe" => 54, "Cs" => 55, "Ba" => 56, "La" => 57, "Ce" => 58, "Pr" => 59, "Nd" => 60, - "Pm" => 61, "Sm" => 62, "Eu" => 63, "Gd" => 64, "Tb" => 65, "Dy" => 66, "Ho" => 67, "Er" => 68, "Tm" => 69, "Yb" => 70, - "Lu" => 71, "Hf" => 72, "Ta" => 73, "W" => 74, "Re" => 75, "Os" => 76, "Ir" => 77, "Pt" => 78, "Au" => 79, "Hg" => 80, - "Tl" => 81, "Pb" => 82, "Bi" => 83, "Po" => 84, "At" => 85, "Rn" => 86, "Fr" => 87, "Ra" => 88, "Ac" => 89, "Th" => 90, - "Pa" => 91, "U" => 92, "Np" => 93, "Pu" => 94, "Am" => 95, "Cm" => 96, "Bk" => 97, "Cf" => 98, "Es" => 99, "Fm" => 100, - "Md" => 101, "No" => 102, "Lr" => 103, "Rf" => 104, "Db" => 105, "Sg" => 106, "Bh" => 107, "Hs" => 108, "Mt" => 109, "Ds" => 110, - "Rg" => 111, "Cn" => 112, "Nh" => 113, "Fl" => 114, "Mc" => 115, "Lv" => 116, "Ts" => 117, "Og" => 118, -}; +fn periodic_element(symbol: &str) -> Option { + symbol.parse().ok() +} + +fn is_known_chemical_symbol(symbol: &str) -> bool { + periodic_element(symbol).is_some() || CHEMICAL_ABBREVIATIONS.contains(symbol) +} + +fn chemical_element_atomic_number(symbol: &str) -> Option { + periodic_element(symbol).map(|e| u32::from(e.atomic_number())) +} + +fn chemical_electronegativity(symbol: &str) -> Option { + if CHEMICAL_ABBREVIATIONS.contains(symbol) { + return Some(0.0); + } + + // MathCAT historically assigned a value to every real element. Keep that coverage for + // elements whose Pauling electronegativity has not been measured by sorting them at zero. + periodic_element(symbol).map(|e| e.pauling_electronegativity().unwrap_or(0.0)) +} pub fn is_chemical_element(node: Element) -> bool { // FIX: allow name to be in an mrow (e.g., Na @@ -1884,7 +1878,7 @@ pub fn is_chemical_element(node: Element) -> bool { } let text = as_text(node); - return CHEMICAL_ELEMENT_ELECTRONEGATIVITY.contains_key(as_str!(text)) || + return is_known_chemical_symbol(as_str!(text)) || has_chem_intent(node, "chemical-element") || has_inherited_property(node, "chemical-formula"); } @@ -1973,6 +1967,34 @@ mod chem_tests { return Ok( () ); } + #[test] + fn test_periodic_element_lookups() { + // Representative symbols retain their old validity and atomic-number results. + assert_eq!(chemical_element_atomic_number("H"), Some(1)); + assert_eq!(chemical_element_atomic_number("Fe"), Some(26)); + assert_eq!(chemical_element_atomic_number("Og"), Some(118)); + assert!(is_known_chemical_symbol("H")); + assert!(is_known_chemical_symbol("Fe")); + assert!(is_known_chemical_symbol("Og")); + assert!(!is_known_chemical_symbol("fe")); + assert!(!is_known_chemical_symbol("Zz")); + } + + #[test] + fn test_chemical_abbreviations_are_not_periodic_elements() { + // MathCAT abbreviations remain valid chemistry tokens without acquiring element data. + for abbreviation in ["Me", "Et", "Ph", "R", "X"] { + assert!(is_known_chemical_symbol(abbreviation)); + assert!(periodic_element(abbreviation).is_none()); + assert_eq!(chemical_element_atomic_number(abbreviation), None); + assert_eq!(chemical_electronegativity(abbreviation), Some(0.0)); + } + + // Ac remains actinium; its alternate use as acetyl does not shadow the real element. + assert!(!CHEMICAL_ABBREVIATIONS.contains("Ac")); + assert_eq!(chemical_element_atomic_number("Ac"), Some(89)); + } + #[test] fn test_noble_element() -> Result<()> { return chem_test(|| { @@ -2054,7 +2076,7 @@ mod chem_tests { N⁣ H3 "#; - assert_chem_elements(test, true, is_ordered_by_electronegativity)?; + assert_chem_elements(test, false, is_ordered_by_electronegativity)?; let test = r#" O⁣ F2 From d22ed4d7644692c0c1efe5b392c6b734d2d2d4de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Fri, 25 Sep 2026 06:58:23 +0200 Subject: [PATCH 138/157] fix redundant call of pref_to_string (#815) --- src/interface.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/interface.rs b/src/interface.rs index 20389959f..823d89430 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -287,10 +287,7 @@ pub fn get_preference(name: impl AsRef) -> Result { crate::speech::SPEECH_RULES.with(|rules| { let rules = rules.borrow(); let pref_manager = rules.pref_manager.borrow(); - let mut value = pref_manager.pref_to_string(&name); - if value == NO_PREFERENCE { - value = pref_manager.pref_to_string(&name); - } + let value = pref_manager.pref_to_string(&name); if value == NO_PREFERENCE { bail!("No preference named '{}'", name); } else { From ad0e716e515fe850e3e1a193f4500e7fdb235e29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Fri, 25 Sep 2026 07:03:28 +0200 Subject: [PATCH 139/157] clean up unused types in definitions and remove outdated docstring (#818) --- src/definitions.rs | 53 ++++++++++------------------------------------ 1 file changed, 11 insertions(+), 42 deletions(-) diff --git a/src/definitions.rs b/src/definitions.rs index b7c45fca9..33b833912 100644 --- a/src/definitions.rs +++ b/src/definitions.rs @@ -33,44 +33,13 @@ use std::path::{Path, PathBuf}; use std::collections::{HashMap, HashSet}; use crate::shim_filesystem::read_to_string_shim; -/// An enum to paper over the different types of data access needed. -/// -/// Having a Rc> seems a bit complicated in terms of types but... -/// 1. The rust book seems to endorse the Rc>> approach when there are multiple owners of mutable date. -/// See towards the end -/// 2. When a file is read, we need to clear and add data to the structure being read (reassigning could work for clearing). -/// When we use the data, we either want to index into it or test if an item is there. -/// The structures we use are either a Vec or a HashMap, so we need to abstract that away in `FromFileVariable`. -/// Unfortunately, traits don't quite work as an option here: -/// * Vec implements extends (`add`), but there is no test/contains -/// * Hashmap implements `index`, but panics if the item isn't there -/// -/// Because of the above limitations, we introduce the enum [`Contains`] which dispatches appropriately to Vec/Hashmap #[derive(Debug, Clone)] -pub enum Contains { +pub enum DefinitionCollection { Vec(Rc>>), Set(Rc>>), Map(Rc>>), } -impl Contains { - // fn add(&mut self, item: String) { - // match self { - // Contains::Vec(v) => { v.borrow_mut().push(item); }, - // Contains::Set(s) => { s.borrow_mut().insert(item); } - // } - // } - - // fn clear(&mut self) { - // match self { - // Contains::Vec(v) => { v.borrow_mut().clear(); }, - // Contains::Set(s) => { s.borrow_mut().clear(); } - // } - // } -} -pub type CollectionFromFile = Contains; -type VariableDefHashMap = HashMap; - /// Global structure containing all of the definitions. /// Each field in the structure corresponds to a named value read in from the `definitions.yaml` files. /// @@ -80,7 +49,7 @@ type VariableDefHashMap = HashMap; /// There should only be one instance of this structure ([`DEFINITIONS`]) // FIX: this probably can done with a macro to remove all the repetition pub struct Definitions { - pub name_to_var_mapping: VariableDefHashMap, + pub name_to_var_mapping: HashMap, } impl Default for Definitions { @@ -100,7 +69,7 @@ impl Definitions { pub fn get_hashset(&self, name: &str) -> Option>> { let names = self.name_to_var_mapping.get(name); - if let Some(Contains::Set(set)) = names { + if let Some(DefinitionCollection::Set(set)) = names { return Some(set.borrow()); } return None; @@ -108,7 +77,7 @@ impl Definitions { pub fn get_hashmap(&self, name: &str) -> Option>> { let names = self.name_to_var_mapping.get(name); - if let Some(Contains::Map(map)) = names { + if let Some(DefinitionCollection::Map(map)) = names { return Some(map.borrow()); } return None; @@ -116,7 +85,7 @@ impl Definitions { pub fn get_vec(&self, name: &str) -> Option>> { let names = self.name_to_var_mapping.get(name); - if let Some(Contains::Vec(vec)) = names { + if let Some(DefinitionCollection::Vec(vec)) = names { return Some(vec.borrow()); } return None; @@ -172,12 +141,12 @@ pub fn read_definitions_file(use_speech_defs: bool) -> Result> { // let name_to_mapping = defs.name_to_var_mapping.borrow_mut(); for set_name in used_set_names { if defs.get_hashset(set_name).is_none() { - defs.name_to_var_mapping.insert(set_name.to_string(), Contains::Set( Rc::new( RefCell::new( HashSet::with_capacity(0) ) ) )); + defs.name_to_var_mapping.insert(set_name.to_string(), DefinitionCollection::Set( Rc::new( RefCell::new( HashSet::with_capacity(0) ) ) )); } } if defs.get_hashset("FunctionNames").is_none() { let all_functions = build_all_functions_set(defs); - defs.name_to_var_mapping.insert("FunctionNames".to_string(), Contains::Set( Rc::new( RefCell::new( all_functions ) ) )); + defs.name_to_var_mapping.insert("FunctionNames".to_string(), DefinitionCollection::Set( Rc::new( RefCell::new( all_functions ) ) )); } } @@ -240,19 +209,19 @@ fn build_values(definition: &Yaml, use_speech_defs: bool, path: &Path) -> Result } let result = if let Some(vec) = value.as_vec() { - Contains::Vec( Rc::new( RefCell::new( get_vec_values(vec)? ) ) ) + DefinitionCollection::Vec( Rc::new( RefCell::new( get_vec_values(vec)? ) ) ) } else { let dict = value.as_hash().ok_or_else(|| anyhow!("definition list value '{}' is not an array or dictionary", yaml_to_type(value)))?; if dict.is_empty() { - Contains::Set( Rc::new( RefCell::new( HashSet::with_capacity(0) ) ) ) + DefinitionCollection::Set( Rc::new( RefCell::new( HashSet::with_capacity(0) ) ) ) } else { // peak and see if this is a set or a map let (_, entry_value) = dict.iter().next().unwrap(); if entry_value.is_null() { - Contains::Set( Rc::new( RefCell::new( get_set_values(dict) + DefinitionCollection::Set( Rc::new( RefCell::new( get_set_values(dict) .with_context(||format!("while reading value '{def_name}'"))? ) ) ) } else { - Contains::Map( Rc::new( RefCell::new( get_map_values(dict) + DefinitionCollection::Map( Rc::new( RefCell::new( get_map_values(dict) .with_context(||format!("while reading value '{def_name}'"))? ) ) ) } } From 414a7dfa927fa6a2db1a52c74e68b4b0ebbe5d00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Fri, 25 Sep 2026 07:06:49 +0200 Subject: [PATCH 140/157] remove dead functions set_string_value and set_bool_value (#819) --- src/prefs.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/prefs.rs b/src/prefs.rs index 162574c5b..406a9d314 100644 --- a/src/prefs.rs +++ b/src/prefs.rs @@ -170,16 +170,6 @@ impl Preferences{ } } } - - #[allow(dead_code)] // used in testing - fn set_string_value(&mut self, name: &str, value: &str) { - self.prefs.insert(name.to_string(), Yaml::String(value.trim().to_string())); - } - - #[allow(dead_code)] // used in testing - fn set_bool_value(&mut self, name: &str, value: bool) { - self.prefs.insert(name.to_string(), Yaml::Boolean(value)); - } } From 307109fac7da71c6950dc1b1214138a443ee4018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Fri, 25 Sep 2026 07:34:13 +0200 Subject: [PATCH 141/157] replace custom constructor with struct literals for TTSCommandRule (#821) --- src/tts.rs | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/src/tts.rs b/src/tts.rs index c2f951b39..134c96251 100644 --- a/src/tts.rs +++ b/src/tts.rs @@ -243,16 +243,6 @@ impl fmt::Display for TTSCommandRule { } -impl TTSCommandRule { - pub fn new(command: TTSCommand, value: TTSCommandValue, replacements: ReplacementArray) -> TTSCommandRule { - return TTSCommandRule{ - command, - value, - replacements - } - } -} - /// Supported TTS engines /// These types should do something for all the TTSCommands #[allow(clippy::upper_case_acronyms)] @@ -348,7 +338,11 @@ impl TTS { TTSCommandValue::String(tts_str_value.to_string()) }, }; - return Ok( Box::new( TTSCommandRule::new(tts_enum, tts_command_value, replacements) ) ); + return Ok(Box::new(TTSCommandRule { + command: tts_enum, + value: tts_command_value, + replacements, + })); } /// The rule called to execute the TTSCommand `command` @@ -691,11 +685,11 @@ impl TTS { } let pause = std::cmp::min(3000, ((2 * before_len + after_len)/48) * 128); // create a TTSCommandRule so we reuse code - let command = TTSCommandRule::new( - TTSCommand::Pause, - TTSCommandValue::Number(pause as f64), - ReplacementArray::build_empty(), - ); + let command = TTSCommandRule { + command: TTSCommand::Pause, + value: TTSCommandValue::Number(pause as f64), + replacements: ReplacementArray::build_empty(), + }; return match self { TTS::None => self.get_string_none(&command, prefs, true), TTS::SSML => self.get_string_ssml(&command, prefs, true), From 5c5286becf68e379eb1753dd3a416a67381bf3ad Mon Sep 17 00:00:00 2001 From: Danil <81031453+Kostenkov-2021@users.noreply.github.com> Date: Fri, 25 Sep 2026 11:35:30 +0300 Subject: [PATCH 142/157] =?UTF-8?q?ru:=20use=20explicit=20"=D0=BC=D0=BD?= =?UTF-8?q?=D0=BE=D0=B6=D0=B5=D1=81=D1=82=D0=B2=D0=BE"=20for=20standard=20?= =?UTF-8?q?number=20sets?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clarify Russian wording for membership of standard number sets (ℕ, ℤ, ℚ, ℝ). Add a dedicated set-member-number-set rule and update ClearSpeak/SimpleSpeak shared rules to speak e.g. "принадлежащих множеству целых чисел" instead of ambiguous/calque forms. Fix related translations in unicode-full (remove English OT markers, replace «член» → «элемент»), simplify interval terminology in general rules, add FunctionApplicationWord connector, and refine several UI phrases (table/diacritical labels). Update and add unit tests in tests/Languages/ru to assert the new phrasing. --- Rules/Languages/ru/ClearSpeak_Rules.yaml | 43 ++++++-- Rules/Languages/ru/SharedRules/default.yaml | 104 ++++++++++++++------ Rules/Languages/ru/SharedRules/general.yaml | 8 +- Rules/Languages/ru/definitions.yaml | 3 + Rules/Languages/ru/unicode-full.yaml | 20 ++-- tests/Languages/ru/ClearSpeak/sets.rs | 69 ++++++++++--- tests/Languages/ru/SimpleSpeak/functions.rs | 12 +-- tests/Languages/ru/SimpleSpeak/sets.rs | 4 +- 8 files changed, 190 insertions(+), 73 deletions(-) diff --git a/Rules/Languages/ru/ClearSpeak_Rules.yaml b/Rules/Languages/ru/ClearSpeak_Rules.yaml index 87bb9cdfd..e4cbb6328 100644 --- a/Rules/Languages/ru/ClearSpeak_Rules.yaml +++ b/Rules/Languages/ru/ClearSpeak_Rules.yaml @@ -541,26 +541,53 @@ - if: "$ClearSpeak_SetMemberSymbol='Belongs'" then: - pause: short - - T: "входящих в" - test: - - if: "*[3][.='ℤ']" - then: [T: "целые числа"] + if: "*[3][.='ℕ' or .='ℤ' or .='ℚ' or .='ℝ']" + then: [T: "входящих в множество"] + else: [T: "входящих в"] + - test: + - if: "*[3][.='ℕ']" + then: [T: "натуральных чисел"] + - else_if: "*[3][.='ℤ']" + then: [T: "целых чисел"] + - else_if: "*[3][.='ℚ']" + then: [T: "рациональных чисел"] + - else_if: "*[3][.='ℝ']" + then: [T: "действительных чисел"] - else: [x: "*[3]"] - else_if: "$ClearSpeak_SetMemberSymbol='Element'" then: - pause: short - - T: "являющихся элементами" - test: - - if: "*[3][.='ℤ']" + if: "*[3][.='ℕ' or .='ℤ' or .='ℚ' or .='ℝ']" + then: [T: "являющихся элементами множества"] + else: [T: "являющихся элементами"] + - test: + - if: "*[3][.='ℕ']" + then: [T: "натуральных чисел"] + - else_if: "*[3][.='ℤ']" then: [T: "целых чисел"] + - else_if: "*[3][.='ℚ']" + then: [T: "рациональных чисел"] + - else_if: "*[3][.='ℝ']" + then: [T: "действительных чисел"] - else: [x: "*[3]"] - else_if: "$ClearSpeak_SetMemberSymbol='Auto' or $ClearSpeak_SetMemberSymbol='Member'" then: - pause: short - - T: "принадлежащих" - test: - - if: "*[3][.='ℤ']" - then: [T: "целым числам"] + if: "*[3][.='ℕ' or .='ℤ' or .='ℚ' or .='ℝ']" + then: [T: "принадлежащих множеству"] + else: [T: "принадлежащих"] + - test: + - if: "*[3][.='ℕ']" + then: [T: "натуральных чисел"] + - else_if: "*[3][.='ℤ']" + then: [T: "целых чисел"] + - else_if: "*[3][.='ℚ']" + then: [T: "рациональных чисел"] + - else_if: "*[3][.='ℝ']" + then: [T: "действительных чисел"] - else: [x: "*[3]"] - else: - T: "из" diff --git a/Rules/Languages/ru/SharedRules/default.yaml b/Rules/Languages/ru/SharedRules/default.yaml index 250f5fa8c..fab6ad11c 100644 --- a/Rules/Languages/ru/SharedRules/default.yaml +++ b/Rules/Languages/ru/SharedRules/default.yaml @@ -185,6 +185,26 @@ - pause: short - x: "*[3]" +- name: set-member-number-set + tag: mrow + match: "count(*)=3 and *[2][.='∈'] and *[3][.='ℕ' or .='ℤ' or .='ℚ' or .='ℝ'] and not(ancestor::*[self::m:set or self::m:large-op])" + replace: + - x: "*[1]" + - test: + - if: "$SpeechStyle='ClearSpeak' and $ClearSpeak_SetMemberSymbol='Element'" + then: [T: "является элементом множества"] + - else_if: "$SpeechStyle='ClearSpeak' and $ClearSpeak_SetMemberSymbol='In'" + then: [T: "находится в множестве"] + - else: [T: "принадлежит множеству"] + - test: + - if: "*[3][.='ℕ']" + then: [T: "натуральных чисел"] + - else_if: "*[3][.='ℤ']" + then: [T: "целых чисел"] + - else_if: "*[3][.='ℚ']" + then: [T: "рациональных чисел"] + - else: [T: "действительных чисел"] + - name: set-membership-in-builder tag: mrow match: "count(*)=3 and *[2][.='∈'] and ancestor::*[self::m:set]" @@ -194,26 +214,30 @@ - if: "$SpeechStyle='ClearSpeak' and $ClearSpeak_SetMemberSymbol='Belongs'" then: - pause: short - - T: "входящих в" + - test: + if: "*[3][.='ℕ' or .='ℤ' or .='ℚ' or .='ℝ']" + then: [T: "входящих в множество"] + else: [T: "входящих в"] - else_if: "$SpeechStyle='ClearSpeak' and $ClearSpeak_SetMemberSymbol='Element'" then: - pause: short - - T: "являющихся элементами" + - test: + if: "*[3][.='ℕ' or .='ℤ' or .='ℚ' or .='ℝ']" + then: [T: "являющихся элементами множества"] + else: [T: "являющихся элементами"] - else_if: "$SpeechStyle='ClearSpeak' and ($ClearSpeak_SetMemberSymbol='Member')" then: - pause: short - - T: "принадлежащих" + - test: + if: "*[3][.='ℕ' or .='ℤ' or .='ℚ' or .='ℝ']" + then: [T: "принадлежащих множеству"] + else: [T: "принадлежащих"] - else: [T: "из"] - test: - if: "*[3][.='ℕ']" then: [T: "натуральных чисел"] - else_if: "*[3][.='ℤ']" - then_test: - - if: "$SpeechStyle='ClearSpeak' and $ClearSpeak_SetMemberSymbol='Belongs'" - then: [T: "целые числа"] - - else_if: "$SpeechStyle='ClearSpeak' and $ClearSpeak_SetMemberSymbol='Member'" - then: [T: "целым числам"] - - else: [T: "целых чисел"] + then: [T: "целых чисел"] - else_if: "*[3][.='ℚ']" then: [T: "рациональных чисел"] - else_if: "*[3][.='ℝ']" @@ -236,24 +260,28 @@ - if: "$SpeechStyle='ClearSpeak' and $ClearSpeak_SetMemberSymbol='Belongs'" then: - pause: short - - T: "входящему в" + - test: + if: "*[3][.='ℕ' or .='ℤ' or .='ℚ' or .='ℝ']" + then: [T: "входящему в множество"] + else: [T: "входящему в"] - else_if: "$SpeechStyle='ClearSpeak' and $ClearSpeak_SetMemberSymbol='In'" then: [T: "из"] - else_if: "$SpeechStyle='ClearSpeak' and ($ClearSpeak_SetMemberSymbol='Auto' or $ClearSpeak_SetMemberSymbol='Member')" then: - pause: short - - T: "принадлежащему" + - test: + if: "*[3][.='ℕ' or .='ℤ' or .='ℚ' or .='ℝ']" + then: [T: "принадлежащему множеству"] + else: [T: "принадлежащему"] - else: - pause: short - - T: "являющемуся элементом" + - test: + if: "*[3][.='ℕ' or .='ℤ' or .='ℚ' or .='ℝ']" + then: [T: "являющемуся элементом множества"] + else: [T: "являющемуся элементом"] - test: - if: "*[3][.='ℤ']" - then_test: - - if: "$SpeechStyle='ClearSpeak' and $ClearSpeak_SetMemberSymbol='Belongs'" - then: [T: "целые числа"] - - else_if: "$SpeechStyle='ClearSpeak' and ($ClearSpeak_SetMemberSymbol='Auto' or $ClearSpeak_SetMemberSymbol='Member')" - then: [T: "целым числам"] - - else: [T: "целых чисел"] + then: [T: "целых чисел"] - else_if: "*[3][.='ℚ']" then: [T: "рациональных чисел"] - else: [x: "*[3]"] @@ -267,17 +295,35 @@ - pause: short - test: - if: "$SpeechStyle='ClearSpeak' and $ClearSpeak_SetMemberSymbol='Belongs'" - then: [T: "не входит в"] + then: + - test: + if: "*[3][.='ℕ' or .='ℤ' or .='ℚ' or .='ℝ']" + then: [T: "не входит в множество"] + else: [T: "не входит в"] - else_if: "$SpeechStyle='ClearSpeak' and $ClearSpeak_SetMemberSymbol='Element'" - then: [T: "не является элементом"] + then: + - test: + if: "*[3][.='ℕ' or .='ℤ' or .='ℚ' or .='ℝ']" + then: [T: "не является элементом множества"] + else: [T: "не является элементом"] - else_if: "$SpeechStyle='ClearSpeak'" - then: [T: "не принадлежит"] - - else: [T: "не является элементом"] + then: + - test: + if: "*[3][.='ℕ' or .='ℤ' or .='ℚ' or .='ℝ']" + then: [T: "не принадлежит множеству"] + else: [T: "не принадлежит"] + - else: + - test: + if: "*[3][.='ℕ' or .='ℤ' or .='ℚ' or .='ℝ']" + then: [T: "не является элементом множества"] + else: [T: "не является элементом"] - test: - - if: "*[3][.='ℝ'] and $SpeechStyle='ClearSpeak' and $ClearSpeak_SetMemberSymbol='Belongs'" - then: [T: "действительные числа"] - - else_if: "*[3][.='ℝ'] and $SpeechStyle='ClearSpeak' and $ClearSpeak_SetMemberSymbol!='Element'" - then: [T: "действительным числам"] + - if: "*[3][.='ℕ']" + then: [T: "натуральных чисел"] + - else_if: "*[3][.='ℤ']" + then: [T: "целых чисел"] + - else_if: "*[3][.='ℚ']" + then: [T: "рациональных чисел"] - else_if: "*[3][.='ℝ']" then: [T: "действительных чисел"] - else: [x: "*[3]"] @@ -761,7 +807,7 @@ - x: "*[1]" - T: "с" # phrase(x 'with' z below it) - x: "*[2]" - - T: "ниже" # phrase(x with z 'below' it) + - T: "нижний придел" # phrase(x with z 'below' it) - name: diacriticals tag: mover @@ -794,7 +840,7 @@ - x: "*[2]" - T: "ниже и" # phrase(x modified with y 'below and' y above it) - x: "*[3]" - - T: "выше" # phrase(x modified with y 'above' it) + - T: "верхний придел" # phrase(x modified with y 'above' it) - name: default # Here we support up to 2 prescripts and up to 4 postscripts -- that should cover all reasonable cases @@ -987,7 +1033,7 @@ variables: [IsColumnSilent: false()] match: "." replace: - - T: "стол с" # phrase(the 'table with' 3 rows) + - T: "таблица с" # phrase(the 'table with' 3 rows) - x: count(*) - test: if: count(*)=1 diff --git a/Rules/Languages/ru/SharedRules/general.yaml b/Rules/Languages/ru/SharedRules/general.yaml index 497d372aa..fba36a536 100644 --- a/Rules/Languages/ru/SharedRules/general.yaml +++ b/Rules/Languages/ru/SharedRules/general.yaml @@ -215,12 +215,10 @@ replace: - test: - if: "name(.)='open-interval'" - then: [T: "открытый интервал"] + then: [T: "интервал"] - else_if: "name(.)='closed-interval'" - then: [T: "закрытый интервал"] - - else_if: "name(.)='open-closed-interval'" - then: [T: "открыто-закрытый интервал"] - else: [T: "закрыто-открытый интервал"] + then: [T: "отрезок"] + else: [T: "полуинтервал"] - T: "от" - test: if: "*[1][self::m:minus and count(*)=1 and *[1][.='∞']]" diff --git a/Rules/Languages/ru/definitions.yaml b/Rules/Languages/ru/definitions.yaml index c17e4f1ac..73874fa6e 100644 --- a/Rules/Languages/ru/definitions.yaml +++ b/Rules/Languages/ru/definitions.yaml @@ -308,6 +308,9 @@ "19": "девятнадцать", "89": "восемьдесят девять" } +# Connector used by functional intent mappings, for example "синус от икс". +- FunctionApplicationWord: ["от"] + - CurrencySymbols: { "$": "доллар", "¢": "цент", "€": "евро", "£": "фунт", "₡": "колон", "₤": "лира", "₨": "рупия", "₩": "вона", "₪": "шекель", "₱": "песо", "₹": "рупия", "₺": "лира", "₿": "биткоин" diff --git a/Rules/Languages/ru/unicode-full.yaml b/Rules/Languages/ru/unicode-full.yaml index ec9f296ee..346506821 100644 --- a/Rules/Languages/ru/unicode-full.yaml +++ b/Rules/Languages/ru/unicode-full.yaml @@ -680,7 +680,7 @@ - "∁": # 0x2201 - test: if: "$Verbosity!='Terse'" - then: [OT: "the"] + then: [T: ""] - T: "дополнение" - "∂": # 0x2202 - test: @@ -751,9 +751,9 @@ - else_if: $ClearSpeak_SetMemberSymbol = 'In' then: [T: "находится в"] - else: [T: "принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' - - "∋": [T: "содержит член"] # 0x220b - - "∌": [T: "не содержит член"] # 0x220c - - "∍": [T: "содержит член"] # 0x220d + - "∋": [T: "содержит элемент"] # 0x220b + - "∌": [T: "не содержит элемента"] # 0x220c + - "∍": [T: "содержит элемент"] # 0x220d - "∎": [T: "конец доказательства"] # 0x220e - "∏": [T: "произведение"] # 0x220f - "∐": [T: "копроизведение"] # 0x2210 @@ -774,17 +774,17 @@ - "√": # 0x221a - test: if: "$Verbosity!='Terse'" - then: [OT: "the"] + then: [T: ""] - T: "квадратный корень из" - "∛": # 0x221b - test: if: "$Verbosity!='Terse'" - then: [OT: "the"] + then: [T: ""] - T: "кубический корень из" - "∜": # 0x221c - test: if: "$Verbosity!='Terse'" - then: [OT: "the"] + then: [T: ""] - T: "корень четвёртой степени из" - "∝": # 0x221d - test: @@ -901,7 +901,7 @@ - "≏": # 0x224f - test: if: "$Verbosity!='Terse'" - then: [OT: "the"] + then: [T: ""] - T: "разность" - "≐": [T: "равно с точкой сверху"] # 0x2250 - "≑": # 0x2251 @@ -1198,12 +1198,12 @@ - "⋒": # 0x22d2 - test: if: "$Verbosity!='Terse'" - then: [OT: "the"] + then: [T: ""] - T: "двойное пересечение" - "⋓": # 0x22d3 - test: if: "$Verbosity!='Terse'" - then: [OT: "the"] + then: [T: ""] - T: "двойное объединение" - "⋔": # 0x22d4 - test: diff --git a/tests/Languages/ru/ClearSpeak/sets.rs b/tests/Languages/ru/ClearSpeak/sets.rs index 13b2160ee..d7085f373 100644 --- a/tests/Languages/ru/ClearSpeak/sets.rs +++ b/tests/Languages/ru/ClearSpeak/sets.rs @@ -235,7 +235,7 @@ fn element_alone() -> Result<()> { let expr = " 3+2i∉ℝ "; - test("ru", "ClearSpeak", expr, "3 плюс 2 и, не принадлежит действительным числам")?; + test("ru", "ClearSpeak", expr, "3 плюс 2 и, не принадлежит множеству действительных чисел")?; return Ok(()); } @@ -252,7 +252,7 @@ fn element_under_sum() -> Result<()> { "; test("ru", "ClearSpeak", expr, - "сумма по и, принадлежащему целым числам, от; дробь, числитель: 1; знаменатель: и в квадрате")?; + "сумма по и, принадлежащему множеству целых чисел, от; дробь, числитель: 1; знаменатель: и в квадрате")?; return Ok(()); } @@ -303,7 +303,7 @@ fn set_with_bar_member() -> Result<()> { } "; test_ClearSpeak("ru", "ClearSpeak_SetMemberSymbol", "Member", - expr, "множество всех икс, принадлежащих целым числам, таких что икс больше 5")?; + expr, "множество всех икс, принадлежащих множеству целых чисел, таких что икс больше 5")?; return Ok(()); } @@ -313,7 +313,7 @@ fn element_alone_member() -> Result<()> { 3+2i∉ℝ "; test_ClearSpeak("ru", "ClearSpeak_SetMemberSymbol", "Member", - expr, "3 плюс 2 и, не принадлежит действительным числам")?; + expr, "3 плюс 2 и, не принадлежит множеству действительных чисел")?; return Ok(()); } @@ -330,7 +330,7 @@ fn element_under_sum_member() -> Result<()> { "; test_ClearSpeak("ru", "ClearSpeak_SetMemberSymbol", "Member", - expr, "сумма по и, принадлежащему целым числам, от; дробь, числитель: 1; знаменатель: и в квадрате")?; + expr, "сумма по и, принадлежащему множеству целых чисел, от; дробь, числитель: 1; знаменатель: и в квадрате")?; return Ok(()); } @@ -348,7 +348,7 @@ fn set_with_bar_element() -> Result<()> { } "; test_ClearSpeak("ru", "ClearSpeak_SetMemberSymbol", "Element", - expr, "множество всех икс, являющихся элементами целых чисел, таких что икс больше 5")?; + expr, "множество всех икс, являющихся элементами множества целых чисел, таких что икс больше 5")?; return Ok(()); } @@ -358,7 +358,7 @@ fn element_alone_element() -> Result<()> { 3+2i∉ℝ "; test_ClearSpeak("ru", "ClearSpeak_SetMemberSymbol", "Element", - expr, "3 плюс 2 и, не является элементом действительных чисел")?; + expr, "3 плюс 2 и, не является элементом множества действительных чисел")?; return Ok(()); } @@ -375,7 +375,7 @@ fn element_under_sum_element() -> Result<()> { "; test_ClearSpeak("ru", "ClearSpeak_SetMemberSymbol", "Element", - expr, "сумма по и, являющемуся элементом целых чисел, от; дробь, числитель: 1; знаменатель: и в квадрате")?; + expr, "сумма по и, являющемуся элементом множества целых чисел, от; дробь, числитель: 1; знаменатель: и в квадрате")?; return Ok(()); } @@ -403,7 +403,7 @@ fn element_alone_in() -> Result<()> { 3+2i∉ℝ "; test_ClearSpeak("ru", "ClearSpeak_SetMemberSymbol", "In", - expr, "3 плюс 2 и, не принадлежит действительным числам")?; + expr, "3 плюс 2 и, не принадлежит множеству действительных чисел")?; return Ok(()); } @@ -438,7 +438,7 @@ fn set_with_bar_belongs() -> Result<()> { } "; test_ClearSpeak("ru", "ClearSpeak_SetMemberSymbol", "Belongs", - expr, "множество всех икс, входящих в целые числа, таких что икс больше 5")?; + expr, "множество всех икс, входящих в множество целых чисел, таких что икс больше 5")?; return Ok(()); } @@ -448,7 +448,7 @@ fn element_alone_belongs() -> Result<()> { 3+2i∉ℝ "; test_ClearSpeak("ru", "ClearSpeak_SetMemberSymbol", "Belongs", - expr, "3 плюс 2 и, не входит в действительные числа")?; + expr, "3 плюс 2 и, не входит в множество действительных чисел")?; return Ok(()); } @@ -465,7 +465,7 @@ fn element_under_sum_belongs() -> Result<()> { "; test_ClearSpeak("ru", "ClearSpeak_SetMemberSymbol", "Belongs", - expr, "сумма по и, входящему в целые числа, от; дробь, числитель: 1; знаменатель: и в квадрате")?; + expr, "сумма по и, входящему в множество целых чисел, от; дробь, числитель: 1; знаменатель: и в квадрате")?; return Ok(()); } @@ -483,10 +483,53 @@ fn set_member_woall() -> Result<()> { } "; test_ClearSpeak_prefs("ru", vec![("ClearSpeak_SetMemberSymbol", "Member"), ("ClearSpeak_Sets", "woAll")], - expr, "множество икс, принадлежащих целым числам, таких что икс больше 5")?; + expr, "множество икс, принадлежащих множеству целых чисел, таких что икс больше 5")?; return Ok(()); } +#[test] +fn standard_number_sets_use_explicit_set_terminology() -> Result<()> { + // A number belongs to a set of numbers; the preference must not make it an + // element "of numbers" or say that it enters the numbers themselves. + let natural = "{x∈ℕ:x>0}"; + test_ClearSpeak("ru", "ClearSpeak_SetMemberSymbol", "Member", natural, + "множество всех икс, принадлежащих множеству натуральных чисел, таких что икс больше 0")?; + + let rational = "{x∈ℚ:x>0}"; + test_ClearSpeak("ru", "ClearSpeak_SetMemberSymbol", "Element", rational, + "множество всех икс, являющихся элементами множества рациональных чисел, таких что икс больше 0")?; + + let real = "{x∈ℝ:x>0}"; + test_ClearSpeak("ru", "ClearSpeak_SetMemberSymbol", "Belongs", real, + "множество всех икс, входящих в множество действительных чисел, таких что икс больше 0")?; + return Ok(()); +} + +#[test] +fn standalone_membership_uses_explicit_set_terminology() -> Result<()> { + // The spoken predicate must govern "множество", with the number-set name in the genitive. + let expr = "x∈ℝ"; + test("ru", "SimpleSpeak", expr, + "икс принадлежит множеству действительных чисел")?; + test_ClearSpeak("ru", "ClearSpeak_SetMemberSymbol", "Member", expr, + "икс принадлежит множеству действительных чисел")?; + test_ClearSpeak("ru", "ClearSpeak_SetMemberSymbol", "Element", expr, + "икс является элементом множества действительных чисел")?; + test_ClearSpeak("ru", "ClearSpeak_SetMemberSymbol", "In", expr, + "икс находится в множестве действительных чисел")?; + return Ok(()); +} + +#[test] +fn reverse_membership_uses_element_terminology() -> Result<()> { + // The reverse membership signs describe an element, not the nonstandard calque "член". + test("ru", "ClearSpeak", "A∋x", + "заглавная а содержит элемент икс")?; + test("ru", "SimpleSpeak", "A∌x", + "заглавная а не содержит элемента икс")?; + return Ok(()); +} + #[test] fn multiple_element_set_woall() -> Result<()> { let expr = " diff --git a/tests/Languages/ru/SimpleSpeak/functions.rs b/tests/Languages/ru/SimpleSpeak/functions.rs index d190328dd..0cb5385ee 100644 --- a/tests/Languages/ru/SimpleSpeak/functions.rs +++ b/tests/Languages/ru/SimpleSpeak/functions.rs @@ -305,7 +305,7 @@ fn parens_interval_open_open() -> Result<()> { (c,d) ) "; - test("ru", "SimpleSpeak", expr, "открытый интервал от цэ до дэ")?; + test("ru", "SimpleSpeak", expr, "интервал от цэ до дэ")?; return Ok(()); } @@ -316,7 +316,7 @@ fn parens_interval_closed_open() -> Result<()> { [(]c,d) ) "; - test("ru", "SimpleSpeak", expr, "закрыто-открытый интервал от цэ до дэ")?; + test("ru", "SimpleSpeak", expr, "полуинтервал от цэ до дэ")?; return Ok(()); } @@ -327,7 +327,7 @@ fn parens_interval_open_closed() -> Result<()> { (c,d] ] "; - test("ru", "SimpleSpeak", expr, "открыто-закрытый интервал от цэ до дэ")?; + test("ru", "SimpleSpeak", expr, "полуинтервал от цэ до дэ")?; return Ok(()); } @@ -338,7 +338,7 @@ fn parens_interval_closed_closed() -> Result<()> { [(]c,d] ] "; - test("ru", "SimpleSpeak", expr, "закрытый интервал от цэ до дэ")?; + test("ru", "SimpleSpeak", expr, "отрезок от цэ до дэ")?; return Ok(()); } @@ -350,7 +350,7 @@ fn parens_interval_neg_infinity_open_open() -> Result<()> { ) "; test("ru", "SimpleSpeak", expr, - "открытый интервал от минус бесконечности до дэ")?; + "интервал от минус бесконечности до дэ")?; return Ok(()); } @@ -362,7 +362,7 @@ fn parens_interval_neg_infinity_open_closed() -> Result<()> { ] "; test("ru", "SimpleSpeak", expr, - "открыто-закрытый интервал от минус бесконечности до дэ")?; + "полуинтервал от минус бесконечности до дэ")?; return Ok(()); } diff --git a/tests/Languages/ru/SimpleSpeak/sets.rs b/tests/Languages/ru/SimpleSpeak/sets.rs index 3bbb31a29..20cc99601 100644 --- a/tests/Languages/ru/SimpleSpeak/sets.rs +++ b/tests/Languages/ru/SimpleSpeak/sets.rs @@ -205,7 +205,7 @@ fn element_alone() -> Result<()> { let expr = " 3+2i∉ℝ "; - test("ru", "SimpleSpeak", expr, "3 плюс 2 и, не является элементом действительных чисел")?; + test("ru", "SimpleSpeak", expr, "3 плюс 2 и, не является элементом множества действительных чисел")?; return Ok(()); } @@ -222,7 +222,7 @@ fn element_under_sum() -> Result<()> { "; test("ru", "SimpleSpeak", expr, - "сумма по и, являющемуся элементом целых чисел, от; дробь, числитель: 1, знаменатель: и в квадрате, конец дроби")?; + "сумма по и, являющемуся элементом множества целых чисел, от; дробь, числитель: 1, знаменатель: и в квадрате, конец дроби")?; return Ok(()); } From a1b1c8ceb0a61887bcab7301a08ee0b911274729 Mon Sep 17 00:00:00 2001 From: Danil <81031453+Kostenkov-2021@users.noreply.github.com> Date: Fri, 25 Sep 2026 11:49:24 +0300 Subject: [PATCH 143/157] Refine Russian math terminology This update improves Russian mathematical speech and navigation by fixing set-membership wording, compact Unicode operator and relation names, and table navigation boundary phrasing. It also adds targeted regression tests covering the corrected column navigation message and compact Unicode output. --- Rules/Languages/ru/SharedRules/default.yaml | 2 +- Rules/Languages/ru/navigate.yaml | 4 +-- Rules/Languages/ru/unicode-full.yaml | 2 +- Rules/Languages/ru/unicode.yaml | 30 ++++++++++----------- tests/Languages/ru/navigate.rs | 13 +++++++++ tests/Languages/ru/shared.rs | 14 ++++++++++ 6 files changed, 46 insertions(+), 19 deletions(-) diff --git a/Rules/Languages/ru/SharedRules/default.yaml b/Rules/Languages/ru/SharedRules/default.yaml index fab6ad11c..ac0b4ddc0 100644 --- a/Rules/Languages/ru/SharedRules/default.yaml +++ b/Rules/Languages/ru/SharedRules/default.yaml @@ -524,7 +524,7 @@ tag: mi match: - "string-length(.)=1 and" - - "(parent::*[self::m:trace or self::m:dimension or self::m:homomorphism or self::m:kernel or self::m:norm or self::m:determinant or self::m:real-part or self::m:imaginary-part or self::m:laplacian or self::m:divergence or self::m:curl or self::m:gradient or self::m:subscripted-norm or self::m:limit or self::m:line-segment or self::m:ray or self::m:open-interval or self::m:closed-interval or self::m:open-closed-interval or self::m:closed-open-interval or self::m:binomial or self::m:pochhammer or self::m:square-root or self::m:root or self::m:absolute-value] or parent::m:large-op or parent::m:logarithm-with-base or (parent::m:power and preceding-sibling::*) or (parent::m:fraction and preceding-sibling::* and IsNode(../*[1], 'simple') and IsNode(., 'simple')) or (parent::m:apply-function and preceding-sibling::*) or (parent::m:evaluate and preceding-sibling::*) or preceding-sibling::*[1][.='⁡'] or parent::m:mrow[IsBracketed(., '(', ')') and count(*)=3 and parent::*[self::m:kernel or self::m:homomorphism]])" + - "(parent::*[self::m:trace or self::m:dimension or self::m:homomorphism or self::m:kernel or self::m:norm or self::m:determinant or self::m:real-part or self::m:imaginary-part or self::m:laplacian or self::m:divergence or self::m:curl or self::m:gradient or self::m:subscripted-norm or self::m:limit or self::m:line-segment or self::m:ray or self::m:open-interval or self::m:closed-interval or self::m:open-closed-interval or self::m:closed-open-interval or self::m:binomial or self::m:pochhammer or self::m:square-root or self::m:root or self::m:absolute-value] or parent::m:large-op or parent::m:logarithm-with-base or (parent::m:power and preceding-sibling::*) or (parent::m:fraction and preceding-sibling::* and IsNode(../*[1], 'simple') and IsNode(., 'simple')) or (parent::m:apply-function and preceding-sibling::*) or (parent::m:evaluate and preceding-sibling::*) or preceding-sibling::*[1][.='⁡' or .='∈' or .='∉' or .='∊'] or parent::m:mrow[IsBracketed(., '(', ')') and count(*)=3 and parent::*[self::m:kernel or self::m:homomorphism]])" replace: - bookmark: "@id" - with: diff --git a/Rules/Languages/ru/navigate.yaml b/Rules/Languages/ru/navigate.yaml index f056e742b..709d4ff3d 100644 --- a/Rules/Languages/ru/navigate.yaml +++ b/Rules/Languages/ru/navigate.yaml @@ -1048,9 +1048,9 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - T: "перемещение вверх" # phrase('move up' to the previous row in the table) + - T: "перейти к следующему столбцу" - pause: medium - - T: "нет следующей строки" # phrase('no next row' in the table) + - T: "нет следующего столбца" - set_variables: [SpeakExpression: "'false'"] - name: default-read-cell diff --git a/Rules/Languages/ru/unicode-full.yaml b/Rules/Languages/ru/unicode-full.yaml index 346506821..1963465d5 100644 --- a/Rules/Languages/ru/unicode-full.yaml +++ b/Rules/Languages/ru/unicode-full.yaml @@ -1208,7 +1208,7 @@ - "⋔": # 0x22d4 - test: if: "$Verbosity!='Terse'" - then: [OT: "the"] + then: [T: ""] - T: "собственное пересечение" - "⋕": # 0x22d5 - test: diff --git a/Rules/Languages/ru/unicode.yaml b/Rules/Languages/ru/unicode.yaml index f7b8731db..09838fff7 100644 --- a/Rules/Languages/ru/unicode.yaml +++ b/Rules/Languages/ru/unicode.yaml @@ -347,15 +347,15 @@ - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' then: [T: "в"] # (en: 'in', google translation) - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "член"] # (en: 'member of', google translation) + then: [T: "принадлежит"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' then: [T: "элемент"] # (en: 'element of', google translation) - else: [T: "принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') else_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "член"] # (en: 'is a member of', google translation) + then: [T: "принадлежит"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "элемент"] # (en: 'is an element of', google translation) + then: [T: "является элементом"] - else_if: $ClearSpeak_SetMemberSymbol = 'In' then: [T: "находится в"] # (en: 'is in', google translation) - else: [T: "принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') @@ -425,9 +425,9 @@ - else: [T: "не принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to') else_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "не член"] # (en: 'is not a member of', google translation) + then: [T: "не принадлежит"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "не элемент"] # (en: 'is not an element of', google translation) + then: [T: "не является элементом"] - else_if: $ClearSpeak_SetMemberSymbol = 'In' then: [T: "не в"] # (en: 'is not in', google translation) - else: [T: "не принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to') @@ -438,7 +438,7 @@ - test: if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" then: [T: ""] # (en: 'is', google translation) - - T: "малое принадлежит" # (en: 'an element of') + - T: "принадлежит" # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option else_test: if: "../../self::m:set or ../../../self::m:set" # inside a set @@ -446,18 +446,18 @@ - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' then: [T: "в"] # (en: 'in', google translation) - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "член"] # (en: 'member of', google translation) + then: [T: "принадлежит"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' then: [T: "элемент"] # (en: 'element of', google translation) - - else: [T: "малое принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + - else: [T: "принадлежит"] else_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "член"] # (en: 'is a member of', google translation) + then: [T: "принадлежит"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "элемент"] # (en: 'is an element of', google translation) + then: [T: "является элементом"] - else_if: $ClearSpeak_SetMemberSymbol = 'In' then: [T: "находится в"] # (en: 'is in', google translation) - - else: [T: "малое принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - else: [T: "принадлежит"] - "√": # 0x221a - test: if: "$Verbosity!='Terse'" @@ -500,8 +500,8 @@ - "℉": [T: "градусы фаренгейта"] # 0x2109 (en: 'degrees fahrenheit', google translation) - "Ω": [T: "ом"] # 0x2126 (en: 'ohms', google translation) - "Å": [T: "ангстрем"] # 0x212b (en: 'angstroms', google translation) - - "⇒": [T: "двойная стрелка вправо"] # 0x21d2 (en: 'rightwards double arrow', google translation) - - "∐": [T: "эн-арный сомножитель"] # 0x2210 (en: 'co-product') + - "⇒": [T: "следует"] + - "∐": [T: "копроизведение"] - "∓": [T: "минус плюс"] # 0x2213 (en: 'minus or plus') - "∗": [T: "звёздочка"] # 0x2217 (en: 'times') - "∘": [T: "композиция"] # 0x2218 (en: 'composed with') @@ -511,6 +511,6 @@ - "∷": [T: "пропорция"] # 0x2237 (en: 'as') - "∼": [T: "тильда"] # 0x223c (en: 'varies with') - "∿": [T: "синусоидальная волна"] # 0x223f (en: 'sine wave') - - "≦": [T: "меньше над равно"] # 0x2266 (en: 'less than over equal to') - - "≧": [T: "больше над равно"] # 0x2267 (en: 'greater than over equal to') + - "≦": [T: "меньше или равно"] + - "≧": [T: "больше или равно"] - "≻": [T: "следует за"] # 0x227b (en: 'succeeds') diff --git a/tests/Languages/ru/navigate.rs b/tests/Languages/ru/navigate.rs index 73008f825..1d83e6dc7 100644 --- a/tests/Languages/ru/navigate.rs +++ b/tests/Languages/ru/navigate.rs @@ -132,3 +132,16 @@ fn no_parts_silent_modified_variable_suppresses_base_announcement() -> Result<() "#; assert_zoom_in(expr, "переход внутрь; икс") } + +#[test] +fn move_cell_next_from_row_reports_column_boundary() -> Result<()> { + // MoveCellNext acts on columns; the boundary message must not mention rows or moving up. + let expr = "12"; + init_nav("ru", expr)?; + set_preference("NavVerbosity", "Verbose")?; + do_navigate_command("ZoomIn")?; + let speech = do_navigate_command("MoveCellNext")?; + assert_eq!(speech.trim_end_matches([' ', ',', ';']), + "перейти к следующему столбцу; нет следующего столбца"); + Ok(()) +} diff --git a/tests/Languages/ru/shared.rs b/tests/Languages/ru/shared.rs index ed699f731..b04221b2c 100644 --- a/tests/Languages/ru/shared.rs +++ b/tests/Languages/ru/shared.rs @@ -142,6 +142,20 @@ fn given() -> Result<()> { return Ok(()); } +#[test] +fn compact_unicode_uses_mathematical_terminology() -> Result<()> { + // The compact Unicode table takes precedence over unicode-full, so its + // common relation and operator names must retain their mathematical meaning. + test("ru", "SimpleSpeak", "a⇒b", + "а следует бэ")?; + test("ru", "SimpleSpeak", "∐", "копроизведение")?; + test("ru", "SimpleSpeak", "a≦b≧c", + "а меньше или равно бэ больше или равно цэ")?; + test("ru", "SimpleSpeak", "x∊A", + "икс принадлежит заглавной а")?; + return Ok(()); +} + #[test] fn simple_msubsup() -> Result<()> { let expr = " From fc200d04a8615bf3af554c6928fb2d5cc5f525d4 Mon Sep 17 00:00:00 2001 From: Danil <81031453+Kostenkov-2021@users.noreply.github.com> Date: Fri, 25 Sep 2026 13:35:17 +0300 Subject: [PATCH 144/157] Fix Russian overline terminology MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update Russian Unicode names in `Rules/Languages/ru/unicode-full.yaml` to use the orthographically correct `ё` variants for overline and underline descriptions. This keeps the terminology consistent across related symbols and aligns the translations with the language's spelling conventions. --- Rules/Languages/ru/unicode-full.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Rules/Languages/ru/unicode-full.yaml b/Rules/Languages/ru/unicode-full.yaml index 1963465d5..09172881e 100644 --- a/Rules/Languages/ru/unicode-full.yaml +++ b/Rules/Languages/ru/unicode-full.yaml @@ -128,7 +128,7 @@ - "̂": [T: "циркумфлекс"] # 0x302 - "̃": [T: "тильда"] # 0x303 - "̄": [T: "макрон"] # 0x304 - - "̅": [T: "надчеркивание"] # 0x305 + - "̅": [T: "надчёркивание"] # 0x305 - "̆": [T: "брэвэ"] # 0x306 - "̇": [T: "точка сверху"] # 0x307 - "̈": [T: "две точки"] # 0x308 @@ -1295,15 +1295,15 @@ - "⋳": [T: "элемент с вертикальной чертой в конце горизонтального штриха"] # 0x22f3 - "⋴": [T: "элемент с вертикальной чертой в конце горизонтального штриха"] # 0x22f4 - "⋵": [T: "элемент с точкой сверху"] # 0x22f5 - - "⋶": [T: "элемент с надчеркиванием"] # 0x22f6 - - "⋷": [T: "элемент с надчеркиванием"] # 0x22f7 - - "⋸": [T: "элемент с подчеркиванием"] # 0x22f8 + - "⋶": [T: "элемент с надчёркиванием"] # 0x22f6 + - "⋷": [T: "элемент с надчёркиванием"] # 0x22f7 + - "⋸": [T: "элемент с подчёркиванием"] # 0x22f8 - "⋹": [T: "элемент с двумя горизонтальными штрихами"] # 0x22f9 - "⋺": [T: "содержит с длинным горизонтальным штрихом"] # 0x22fa - "⋻": [T: "содержит с вертикальной чертой в конце горизонтального штриха"] # 0x22fb - "⋼": [T: "содержит с вертикальной чертой в конце горизонтального штриха"] # 0x22fc - - "⋽": [T: "содержит с надчеркиванием"] # 0x22fd - - "⋾": [T: "содержит с надчеркиванием"] # 0x22fe + - "⋽": [T: "содержит с надчёркиванием"] # 0x22fd + - "⋾": [T: "содержит с надчёркиванием"] # 0x22fe - "⋿": [T: "Z-нотация принадлежность мультимножеству"] # 0x22ff - "⌀": [T: "диаметр"] # 0x2300 - "⌁": [T: "электрическая стрелка"] # 0x2301 From 614664562560dc883fe1b4e10717ed40e1245350 Mon Sep 17 00:00:00 2001 From: mgros Date: Sat, 26 Sep 2026 20:15:29 +0200 Subject: [PATCH 145/157] Add GitHub Actions workflows to measure and report library size changes --- .github/workflows/library-size-comment.yml | 102 +++++++++++++++++++++ .github/workflows/library-size.yml | 83 +++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 .github/workflows/library-size-comment.yml create mode 100644 .github/workflows/library-size.yml diff --git a/.github/workflows/library-size-comment.yml b/.github/workflows/library-size-comment.yml new file mode 100644 index 000000000..2eca78919 --- /dev/null +++ b/.github/workflows/library-size-comment.yml @@ -0,0 +1,102 @@ +name: Library Size Comment + +on: + workflow_run: + workflows: [Library Size] + types: [completed] + +permissions: + actions: read + pull-requests: write + +concurrency: + group: library-size-comment-${{ github.event.workflow_run.head_repository.id }}-${{ github.event.workflow_run.head_branch }} + cancel-in-progress: false + +jobs: + comment: + name: Update PR comment + if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' + runs-on: ubuntu-24.04 + steps: + - name: Download measurements + uses: actions/download-artifact@v8 + with: + name: library-size-report + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + path: ${{ runner.temp }}/mathcat-size-report + + # This job never checks out or executes PR code. Treat the downloaded report as untrusted. + - name: Update size comment + uses: actions/github-script@v9 + env: + REPORT_PATH: ${{ runner.temp }}/mathcat-size-report/report.json + with: + script: | + const fs = require('fs'); + const report = JSON.parse(fs.readFileSync(process.env.REPORT_PATH, 'utf8')); + const run = context.payload.workflow_run; + const shaPattern = /^[0-9a-f]{40}$/i; + if (!Number.isSafeInteger(report.prNumber) || report.prNumber <= 0 || + !shaPattern.test(report.baseSha) || !shaPattern.test(report.headSha) || + !Number.isSafeInteger(report.baseBytes) || report.baseBytes <= 0 || + !Number.isSafeInteger(report.headBytes) || report.headBytes <= 0) { + core.setFailed('Invalid library size report'); + return; + } + + const {owner, repo} = context.repo; + const {data: pull} = await github.rest.pulls.get({ + owner, repo, pull_number: report.prNumber, + }); + if (pull.state !== 'open' || pull.base.sha !== report.baseSha || + pull.head.sha !== report.headSha) { + core.notice('PR revisions changed or PR closed; ignoring stale measurements'); + return; + } + if (run.head_repository?.id !== pull.head.repo?.id || + run.head_branch !== pull.head.ref) { + core.setFailed('Report does not match the triggering branch'); + return; + } + if (run.pull_requests?.length > 0 && + !run.pull_requests.some(pr => pr.number === report.prNumber)) { + core.setFailed('Report does not belong to the triggering PR'); + return; + } + + const marker = ''; + const formatSize = bytes => `${(bytes / 1048576).toFixed(2)} MiB (${bytes.toLocaleString('en-US')} bytes)`; + const delta = report.headBytes - report.baseBytes; + const deltaPercent = 100 * delta / report.baseBytes; + const signed = value => value > 0 ? `+${value}` : String(value); + const body = [ + marker, + '### Linux library size', + '', + '| Revision | Release `liblibmathcat.so` |', + '| --- | ---: |', + `| Base (${report.baseSha.slice(0, 7)}) | ${formatSize(report.baseBytes)} |`, + `| PR (${report.headSha.slice(0, 7)}) | ${formatSize(report.headBytes)} |`, + `| Change | ${delta > 0 ? '+' : ''}${delta.toLocaleString('en-US')} bytes (${signed(deltaPercent.toFixed(2))}%) |`, + '', + `Built with default features, Rust 1.96.0, and Ubuntu 24.04. [Workflow run](${run.html_url}).`, + ].join('\n'); + + const comments = await github.paginate(github.rest.issues.listComments, { + owner, repo, issue_number: report.prNumber, per_page: 100, + }); + const previous = comments.find(comment => + comment.user?.login === 'github-actions[bot]' && comment.body?.includes(marker)); + if (previous) { + if (previous.body !== body) { + await github.rest.issues.updateComment({ + owner, repo, comment_id: previous.id, body, + }); + } + } else { + await github.rest.issues.createComment({ + owner, repo, issue_number: report.prNumber, body, + }); + } diff --git a/.github/workflows/library-size.yml b/.github/workflows/library-size.yml new file mode 100644 index 000000000..c94cf9e87 --- /dev/null +++ b/.github/workflows/library-size.yml @@ -0,0 +1,83 @@ +name: Library Size + +on: pull_request + +permissions: + contents: read + +concurrency: + group: library-size-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + measure: + name: Measure Linux shared library + runs-on: ubuntu-24.04 + steps: + - name: Check out base revision + uses: actions/checkout@v5 + with: + ref: ${{ github.event.pull_request.base.sha }} + path: base + persist-credentials: false + + - name: Check out PR revision + uses: actions/checkout@v5 + with: + repository: ${{ github.event.pull_request.head.repo.full_name }} + ref: ${{ github.event.pull_request.head.sha }} + path: head + persist-credentials: false + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@1.96.0 + + - name: Build base library + id: base + working-directory: base + env: + CARGO_TARGET_DIR: ${{ runner.temp }}/mathcat-size-base-target + run: | + cargo build --release --lib --locked + bytes=$(stat -c%s "$CARGO_TARGET_DIR/release/liblibmathcat.so") + echo "bytes=$bytes" >> "$GITHUB_OUTPUT" + + - name: Build PR library + id: head + working-directory: head + env: + CARGO_TARGET_DIR: ${{ runner.temp }}/mathcat-size-head-target + run: | + cargo build --release --lib --locked + bytes=$(stat -c%s "$CARGO_TARGET_DIR/release/liblibmathcat.so") + echo "bytes=$bytes" >> "$GITHUB_OUTPUT" + + - name: Save measurements + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + BASE_SHA: ${{ github.event.pull_request.base.sha }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + BASE_BYTES: ${{ steps.base.outputs.bytes }} + HEAD_BYTES: ${{ steps.head.outputs.bytes }} + REPORT_DIR: ${{ runner.temp }}/mathcat-size-report + run: | + mkdir -p "$REPORT_DIR" + node - <<'NODE' + const fs = require('fs'); + const path = require('path'); + const report = { + prNumber: Number(process.env.PR_NUMBER), + baseSha: process.env.BASE_SHA, + headSha: process.env.HEAD_SHA, + baseBytes: Number(process.env.BASE_BYTES), + headBytes: Number(process.env.HEAD_BYTES), + }; + fs.writeFileSync(path.join(process.env.REPORT_DIR, 'report.json'), JSON.stringify(report)); + NODE + + - name: Upload measurements + uses: actions/upload-artifact@v7 + with: + name: library-size-report + path: ${{ runner.temp }}/mathcat-size-report/report.json + retention-days: 1 From 89d018b071796c89b0092c47d2beb983f3128073 Mon Sep 17 00:00:00 2001 From: mgros Date: Sat, 26 Sep 2026 21:17:03 +0200 Subject: [PATCH 146/157] Refactor library size comment script to improve readability and error handling --- .github/workflows/library-size-comment.yml | 129 ++++++++++++--------- 1 file changed, 73 insertions(+), 56 deletions(-) diff --git a/.github/workflows/library-size-comment.yml b/.github/workflows/library-size-comment.yml index 2eca78919..3fbb3b3cf 100644 --- a/.github/workflows/library-size-comment.yml +++ b/.github/workflows/library-size-comment.yml @@ -35,68 +35,85 @@ jobs: with: script: | const fs = require('fs'); - const report = JSON.parse(fs.readFileSync(process.env.REPORT_PATH, 'utf8')); const run = context.payload.workflow_run; - const shaPattern = /^[0-9a-f]{40}$/i; - if (!Number.isSafeInteger(report.prNumber) || report.prNumber <= 0 || - !shaPattern.test(report.baseSha) || !shaPattern.test(report.headSha) || - !Number.isSafeInteger(report.baseBytes) || report.baseBytes <= 0 || - !Number.isSafeInteger(report.headBytes) || report.headBytes <= 0) { - core.setFailed('Invalid library size report'); - return; - } - const {owner, repo} = context.repo; - const {data: pull} = await github.rest.pulls.get({ - owner, repo, pull_number: report.prNumber, - }); - if (pull.state !== 'open' || pull.base.sha !== report.baseSha || - pull.head.sha !== report.headSha) { - core.notice('PR revisions changed or PR closed; ignoring stale measurements'); - return; - } - if (run.head_repository?.id !== pull.head.repo?.id || - run.head_branch !== pull.head.ref) { - core.setFailed('Report does not match the triggering branch'); - return; + const marker = ''; + + // Read and validate the artifact from the untrusted PR build. + function readReport() { + const report = JSON.parse(fs.readFileSync(process.env.REPORT_PATH, 'utf8')); + const shaPattern = /^[0-9a-f]{40}$/i; + if (!Number.isSafeInteger(report.prNumber) || report.prNumber <= 0 || + !shaPattern.test(report.baseSha) || !shaPattern.test(report.headSha) || + !Number.isSafeInteger(report.baseBytes) || report.baseBytes <= 0 || + !Number.isSafeInteger(report.headBytes) || report.headBytes <= 0) { + throw new Error('Invalid library size report'); + } + return report; } - if (run.pull_requests?.length > 0 && - !run.pull_requests.some(pr => pr.number === report.prNumber)) { - core.setFailed('Report does not belong to the triggering PR'); - return; + + // Only report measurements for the current PR and source branch. + async function matchesCurrentPull(report) { + const {data: pull} = await github.rest.pulls.get({ + owner, repo, pull_number: report.prNumber, + }); + if (pull.state !== 'open' || pull.base.sha !== report.baseSha || + pull.head.sha !== report.headSha) { + core.notice('PR revisions changed or PR closed; ignoring stale measurements'); + return false; + } + if (run.head_repository?.id !== pull.head.repo?.id || + run.head_branch !== pull.head.ref || + (run.pull_requests?.length > 0 && + !run.pull_requests.some(pr => pr.number === report.prNumber))) { + throw new Error('Report does not belong to the triggering PR branch'); + } + return true; } - const marker = ''; - const formatSize = bytes => `${(bytes / 1048576).toFixed(2)} MiB (${bytes.toLocaleString('en-US')} bytes)`; - const delta = report.headBytes - report.baseBytes; - const deltaPercent = 100 * delta / report.baseBytes; - const signed = value => value > 0 ? `+${value}` : String(value); - const body = [ - marker, - '### Linux library size', - '', - '| Revision | Release `liblibmathcat.so` |', - '| --- | ---: |', - `| Base (${report.baseSha.slice(0, 7)}) | ${formatSize(report.baseBytes)} |`, - `| PR (${report.headSha.slice(0, 7)}) | ${formatSize(report.headBytes)} |`, - `| Change | ${delta > 0 ? '+' : ''}${delta.toLocaleString('en-US')} bytes (${signed(deltaPercent.toFixed(2))}%) |`, - '', - `Built with default features, Rust 1.96.0, and Ubuntu 24.04. [Workflow run](${run.html_url}).`, - ].join('\n'); + // The summary is the entire collapsed view; the table is shown on expansion. + function renderComment(report) { + const mib = bytes => `${(bytes / 1048576).toFixed(2)} MiB`; + const size = bytes => `${mib(bytes)} (${bytes.toLocaleString('en-US')} bytes)`; + const delta = report.headBytes - report.baseBytes; + const percent = `${delta > 0 ? '+' : ''}${(100 * delta / report.baseBytes).toFixed(2)}%`; + return [ + marker, + '
', + `Linux library size: ${mib(report.headBytes)} (${percent})`, + '', + '| Revision | Release `liblibmathcat.so` |', + '| --- | ---: |', + `| Base (${report.baseSha.slice(0, 7)}) | ${size(report.baseBytes)} |`, + `| PR (${report.headSha.slice(0, 7)}) | ${size(report.headBytes)} |`, + `| Change | ${delta > 0 ? '+' : ''}${delta.toLocaleString('en-US')} bytes (${percent}) |`, + '', + `Built with default features, Rust 1.96.0, and Ubuntu 24.04. [Workflow run](${run.html_url}).`, + '
', + ].join('\n'); + } - const comments = await github.paginate(github.rest.issues.listComments, { - owner, repo, issue_number: report.prNumber, per_page: 100, - }); - const previous = comments.find(comment => - comment.user?.login === 'github-actions[bot]' && comment.body?.includes(marker)); - if (previous) { - if (previous.body !== body) { - await github.rest.issues.updateComment({ - owner, repo, comment_id: previous.id, body, + // Reuse the bot's marked comment instead of posting on every run. + async function upsertComment(prNumber, body) { + const comments = await github.paginate(github.rest.issues.listComments, { + owner, repo, issue_number: prNumber, per_page: 100, + }); + const previous = comments.find(comment => + comment.user?.login === 'github-actions[bot]' && comment.body?.includes(marker)); + if (previous) { + if (previous.body !== body) { + await github.rest.issues.updateComment({ + owner, repo, comment_id: previous.id, body, + }); + } + } else { + await github.rest.issues.createComment({ + owner, repo, issue_number: prNumber, body, }); } - } else { - await github.rest.issues.createComment({ - owner, repo, issue_number: report.prNumber, body, - }); + } + + const report = readReport(); + if (await matchesCurrentPull(report)) { + await upsertComment(report.prNumber, renderComment(report)); } From aab967cf7fb8a2cd28d7916f2fa7c767ac6b6b8b Mon Sep 17 00:00:00 2001 From: mgros Date: Wed, 23 Sep 2026 23:15:11 +0200 Subject: [PATCH 147/157] Update README with supported and in-progress speech languages list --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 0ee92c6fa..e72c60c1b 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,17 @@ * Navigation of math (in multiple ways including overviews) +
+Supported speech languages + +**Supported:** Chinese (Traditional), English, Finnish, French, German, Greek, Hungarian, Indonesian, Norwegian, Polish, Portuguese, Russian, Spanish, Swedish, and Vietnamese. + +**In progress:** Catalan, Icelandic, Italian, Japanese, and Urdu. + +Source: [DAISY MathCAT Initiative](https://daisy.org/activities/projects/mathcat-initiative/). + +
+ There are four related projects that make use of MathCAT: - [MathCATDemo](https://nsoiffer.github.io/MathCATDemo/) -- an online demonstration of some of what can be done with MathCAT - [A python interface for MathCAT](https://github.com/NSoiffer/MathCATForPython) -- used by a [MathCAT NVDA add-on](https://addons.nvda-project.org/addons/MathCAT.en.html). From 3bbbd4426725b1b20e6f501d2312e7d92f2ed6bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Sun, 27 Sep 2026 22:48:03 +0200 Subject: [PATCH 148/157] replace buggy Display implementation for Pronounce with Debug trait (#820) * replace buggy Display implementation for Pronounce with Debug trait * remove unused `eloquence` field and related code from `Pronounce` struct * fix outdated syntax --- src/tts.rs | 63 ++++++++++++++++++++++++------------------------------ 1 file changed, 28 insertions(+), 35 deletions(-) diff --git a/src/tts.rs b/src/tts.rs index 134c96251..0c26e52c7 100644 --- a/src/tts.rs +++ b/src/tts.rs @@ -114,36 +114,10 @@ pub struct Pronounce { text: String, // plain text ipa: String, // ipa sapi5: String, - eloquence: String, + // eloquence: String, } -impl fmt::Display for Pronounce { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut comma = ""; // comma separator so it looks right - write!(f, "pronounce: [")?; - if !self.text.is_empty() { - write!(f, "text: '{}'", self.text)?; - comma = ","; - } - write!(f, "pronounce: [")?; - if !self.ipa.is_empty() { - write!(f, "{}ipa: '{}'", comma, self.ipa)?; - comma = ","; - } - write!(f, "pronounce: [")?; - if !self.sapi5.is_empty() { - write!(f, "{}sapi5: '{}'", comma, self.sapi5)?; - comma = ","; - } - write!(f, "pronounce: [")?; - if !self.eloquence.is_empty() { - write!(f, "{}eloquence: '{}'", comma, self.eloquence)?; - } - return writeln!(f, "]"); - } -} - impl Pronounce { fn build(values: &Yaml) -> Result { use crate::speech::{as_str_checked, yaml_to_type}; @@ -152,7 +126,6 @@ impl Pronounce { let mut text = ""; let mut ipa = ""; let mut sapi5 = ""; - let mut eloquence = ""; // values should be an array with potential values for Pronounce let values = values.as_vec().ok_or_else(|| anyhow!("'pronounce' value '{}' is not an array", yaml_to_type(values)))?; @@ -168,7 +141,7 @@ impl Pronounce { "text" => text = as_str_checked(value)?, "ipa" => ipa = as_str_checked(value)?, "sapi5" => sapi5 = as_str_checked(value)?, - "eloquence" => eloquence = as_str_checked(value)?, + "eloquence" => { as_str_checked(value)?; }, _ => bail!("unknown pronounce type: {} with value {}", yaml_to_string(key, 0), yaml_to_string(value, 0)), } } @@ -180,7 +153,7 @@ impl Pronounce { text: text.to_string(), ipa: ipa.to_string(), sapi5: sapi5.to_string(), - eloquence: eloquence.to_string() + // eloquence: eloquence.to_string() } ); @@ -232,7 +205,7 @@ impl fmt::Display for TTSCommandRule { TTSCommandValue::String(s) => s.to_string(), TTSCommandValue::Number(f) => f.to_string(), TTSCommandValue::XPath(p) => p.to_string(), - TTSCommandValue::Pronounce(p) => p.to_string(), + TTSCommandValue::Pronounce(p) => format!("{p:?}"), }; if self.command == TTSCommand::Pause { return write!(f, "pause: {value}"); @@ -783,10 +756,30 @@ mod tests { let rule = TTS::build("pronounce", values).unwrap(); let rendered = format!("{rule}"); - assert!(rendered.contains("text: 'alpha'")); - assert!(rendered.contains("ipa: 'a'")); - assert!(rendered.contains("sapi5: 'b'")); - assert!(rendered.contains("eloquence: 'c'")); + assert!(rendered.contains("text: \"alpha\"")); + assert!(rendered.contains("ipa: \"a\"")); + assert!(rendered.contains("sapi5: \"b\"")); + assert!(!rendered.contains("eloquence")); + } + + /// Shows the derived pronunciation details when displaying a TTS rule. + #[test] + fn pronounce_rule_display_uses_debug_fields() { + let pronounce = Pronounce { + text: "bli bla blub".to_string(), + ipa: "a".to_string(), + sapi5: "b".to_string(), + }; + let rule = TTSCommandRule { + command: TTSCommand::Pronounce, + value: TTSCommandValue::Pronounce(Box::new(pronounce)), + replacements: ReplacementArray::build_empty(), + }; + + assert_eq!( + rule.to_string(), + "pronounce: Pronounce { text: \"bli bla blub\", ipa: \"a\", sapi5: \"b\" }\n" + ); } #[test] From 429cf07446dc0589aea85298c5135a8ff09e3e3b Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Mon, 28 Sep 2026 16:43:13 -0700 Subject: [PATCH 149/157] define ratio (U+2236) --- Rules/Braille/ASCIIMath/unicode.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Rules/Braille/ASCIIMath/unicode.yaml b/Rules/Braille/ASCIIMath/unicode.yaml index 94c9bf260..0adf91c66 100644 --- a/Rules/Braille/ASCIIMath/unicode.yaml +++ b/Rules/Braille/ASCIIMath/unicode.yaml @@ -184,6 +184,7 @@ - "∪": [t: "𝐖uu𝐖"] # 0x222a - "∫": [t: "𝐖int𝐖"] # 0x222b - "∮": [t: "𝐖oint𝐖"] # 0x222e + - "∶": [t: ":"] # 0x2236 - "∼": [t: "~"] # 0x223c - "≅": [t: "~="] # 0x2245 - "≈": [t: "~~"] # 0x2248 From f2f3ebce96c50560a1cc958f9b00574a47833f41 Mon Sep 17 00:00:00 2001 From: Danil <81031453+Kostenkov-2021@users.noreply.github.com> Date: Tue, 29 Sep 2026 18:22:19 +0300 Subject: [PATCH 150/157] ru: improve norms, overlines, multiline & operators MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Russian rules to recognize norms (double bars and magnitude) and nested double overline; treat paired absolute-value as "норма" and ordinary as "модуль". Fix multiline handling to skip duplicated '=' and final '.' in gathered/continued lines and announce visual lines. Add translations for named operators (max/min/sup/lim) including munder lower-limit phrasing and context-sensitive wording for overline and infinity in unicode. Adjust munder/mover default wording. Update and add unit tests (mtable, shared, linear_algebra) to cover these cases. --- Rules/Languages/ru/ClearSpeak_Rules.yaml | 39 ++++++++-- Rules/Languages/ru/SharedRules/default.yaml | 72 ++++++++++++++++--- .../ru/SharedRules/linear-algebra.yaml | 7 ++ Rules/Languages/ru/SimpleSpeak_Rules.yaml | 24 +++++++ Rules/Languages/ru/unicode-full.yaml | 14 ++-- .../ru/SimpleSpeak/linear_algebra.rs | 22 ++++++ tests/Languages/ru/mtable.rs | 29 ++++++-- tests/Languages/ru/shared.rs | 47 ++++++++++++ 8 files changed, 229 insertions(+), 25 deletions(-) diff --git a/Rules/Languages/ru/ClearSpeak_Rules.yaml b/Rules/Languages/ru/ClearSpeak_Rules.yaml index e4cbb6328..77e5e3a05 100644 --- a/Rules/Languages/ru/ClearSpeak_Rules.yaml +++ b/Rules/Languages/ru/ClearSpeak_Rules.yaml @@ -483,6 +483,14 @@ then: [x: "*[2]/text()"] else: [x: "*[2]"] +- name: ClearSpeak-double-absolute-value-as-norm + tag: absolute-value + match: "count(*)=1 and *[1][self::m:absolute-value]" + replace: + - T: "норма" + - x: "*[1]/*[1]" + - pause: short + - name: ClearSpeak-absolute-value tag: absolute-value match: "." @@ -501,7 +509,6 @@ if: "$ClearSpeak_AbsoluteValue = 'Cardinality'" then: [T: "мощность множества"] else: [T: "модуль"] - - T: "из" - x: "*[1]" - test: if: "$ClearSpeak_AbsoluteValue = 'AbsEnd'" @@ -946,6 +953,16 @@ then: [T: "скобка закрывается"] else: [T: "скобка закрывается"] +- name: skip-equality-before-continued-gathered-line + tag: mo + match: ".='=' and not(following-sibling::*) and ancestor::m:lines and ancestor::m:mtr/following-sibling::*[1]//*[.='=']" + replace: [T: ""] + +- name: skip-final-period-in-multiline + tag: mo + match: ".='.' and not(following-sibling::*) and ancestor::m:mtr[not(following-sibling::*)] and ancestor::m:lines" + replace: [T: ""] + - name: ClearSpeak-multi-line tag: [piecewise, system-of-equations, lines] match: "." @@ -990,7 +1007,16 @@ then: [T: "шаг"] else: [T: "шага"] - pause: short - - x: "*" + - test: + # Announce the first visual line here: intent processing may flatten that + # row while retaining later mtr nodes. + if: "self::m:lines and count(*) > 1" + then: + - T: "строка" + - x: "1" + - pause: medium + - x: "*" + else: [x: "*"] - pause: long - name: ClearSpeak-default-multiline @@ -999,7 +1025,10 @@ variables: [NextLineIsContinuedRow: "following-sibling::*[1][contains(@data-intent-property, ':continued-row:')]"] replace: - test: - if: "not($LineCount=1 or $ClearSpeak_MultiLineLabel='None' or contains(@data-intent-property, ':continued-row:'))" + if: "not($ClearSpeak_MultiLineLabel='None') and + ((parent::m:lines and preceding-sibling::*) or + (not(parent::m:lines) and + not($LineCount=1 or contains(@data-intent-property, ':continued-row:'))))" then: - pause: medium - test: @@ -1015,7 +1044,9 @@ then: [T: "строка"] - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" then: [T: "шаг"] - - x: "count(preceding-sibling::*[not(contains(@data-intent-property, ':continued-row:'))]) + 1" + - x: "IfThenElse(parent::m:lines, + count(preceding-sibling::*) + 1, + count(preceding-sibling::*[not(contains(@data-intent-property, ':continued-row:'))]) + 1)" - test: if: "self::m:mlabeledtr" then: diff --git a/Rules/Languages/ru/SharedRules/default.yaml b/Rules/Languages/ru/SharedRules/default.yaml index ac0b4ddc0..247eb84b8 100644 --- a/Rules/Languages/ru/SharedRules/default.yaml +++ b/Rules/Languages/ru/SharedRules/default.yaml @@ -537,6 +537,20 @@ - SpeechOverrides_CapitalLetters: "IfThenElse($RuInflectCapital and $SpeechOverrides_CapitalLetters='' and $Impairment='Blindness', $RuCapitalWord, $SpeechOverrides_CapitalLetters)" replace: [x: "text()"] +- name: named-math-operator + tag: mi + match: "@class='qopname' and (text()='max' or text()='min' or text()='sup' or text()='lim')" + replace: + - bookmark: "@id" + - test: + - if: "text()='max'" + then: [T: "максимум"] + - else_if: "text()='min'" + then: [T: "минимум"] + - else_if: "text()='sup'" + then: [T: "супремум"] + - else: [T: "предел"] + - name: default tag: mi match: "." @@ -797,17 +811,55 @@ then: [T: "конец верхнего индекса"] else: [T: "конец степени"] +- name: named-operator-with-lower-limit + tag: munder + variables: [OperatorName: "translate(*[1], ' \u00A0\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2061', '')"] + match: "$OperatorName='max' or $OperatorName='min' or $OperatorName='sup' or $OperatorName='lim'" + replace: + - test: + - if: "$OperatorName='max'" + then: [T: "максимум"] + - else_if: "$OperatorName='min'" + then: [T: "минимум"] + - else_if: "$OperatorName='sup'" + then: [T: "супремум"] + - else: [T: "предел"] + - test: + - if: "$OperatorName='lim'" + then: [T: "при"] + - else: [T: "по"] + - test: + - if: "$OperatorName='lim' and *[2][self::m:mrow and count(*)=3 and *[2][.='→' or .='↗']]" + then: + - x: "*[2]/*[1]" + - T: "стремящемся к" + - test: + if: "*[2]/*[3][.='∞']" + then: [T: "бесконечности"] + else: [x: "*[2]/*[3]"] + - test: + if: "*[2]/*[2][.='↗']" + then: [T: "снизу"] + - else: [x: "*[2]"] + - name: default tag: munder match: "." replace: - test: if: "not(IsNode(*[1], 'leaf'))" - then: [T: "количество"] # phrase(phrase(x 'quantity' with y above it) + then: [T: "выражение"] - x: "*[1]" - - T: "с" # phrase(x 'with' z below it) + - T: "с" - x: "*[2]" - - T: "нижний придел" # phrase(x with z 'below' it) + - T: "снизу" + +- name: double-overline + tag: mover + match: "*[1][self::m:mover or self::m:modified-variable][*[2][.='¯']] and *[2][.='¯']" + replace: + - x: "*[1]/*[1]" + - T: "с двойным надчёркиванием" - name: diacriticals tag: mover @@ -822,11 +874,11 @@ replace: - test: if: "not(IsNode(*[1], 'leaf'))" - then: [T: "количество"] # phrase(phrase(the 'quantity' x plus 1 with y above it) + then: [T: "выражение"] - x: "*[1]" - - T: "с" # phrase(x modified 'with' y above it) + - T: "с" - x: "*[2]" - - T: "с" # phrase(x modified 'with' y above it) + - T: "сверху" - name: default tag: munderover @@ -834,13 +886,13 @@ replace: - test: if: "not(IsNode(*[1], 'leaf'))" - then: [T: "количество"] # phrase(the 'quantity' x plus 1 with y above it) + then: [T: "выражение"] - x: "*[1]" - - T: "с" # phrase(x modified 'with' y above it) + - T: "с" - x: "*[2]" - - T: "ниже и" # phrase(x modified with y 'below and' y above it) + - T: "снизу и" - x: "*[3]" - - T: "верхний придел" # phrase(x modified with y 'above' it) + - T: "сверху" - name: default # Here we support up to 2 prescripts and up to 4 postscripts -- that should cover all reasonable cases diff --git a/Rules/Languages/ru/SharedRules/linear-algebra.yaml b/Rules/Languages/ru/SharedRules/linear-algebra.yaml index 8b8d61e4a..13345ccea 100644 --- a/Rules/Languages/ru/SharedRules/linear-algebra.yaml +++ b/Rules/Languages/ru/SharedRules/linear-algebra.yaml @@ -20,6 +20,13 @@ - T: "с индексом" - x: "*[2]" +- name: magnitude-as-norm + tag: magnitude + match: "count(*)=1" + replace: + - T: "норма" + - x: "*[1]" + - name: transpose tag: transpose match: "count(*)=1" diff --git a/Rules/Languages/ru/SimpleSpeak_Rules.yaml b/Rules/Languages/ru/SimpleSpeak_Rules.yaml index 69324ede3..bcfb11aca 100644 --- a/Rules/Languages/ru/SimpleSpeak_Rules.yaml +++ b/Rules/Languages/ru/SimpleSpeak_Rules.yaml @@ -374,6 +374,30 @@ - pause: short - x: "*[3]" +- name: skip-equality-before-continued-gathered-line + tag: mo + match: ".='=' and not(following-sibling::*) and ancestor::m:lines and ancestor::m:mtr/following-sibling::*[1]//*[.='=']" + replace: [T: ""] + +- name: skip-final-period-in-multiline + tag: mo + match: ".='.' and not(following-sibling::*) and ancestor::m:mtr[not(following-sibling::*)] and ancestor::m:lines" + replace: [T: ""] + +- name: SimpleSpeak-double-absolute-value-as-norm + tag: absolute-value + match: "count(*)=1 and *[1][self::m:absolute-value]" + replace: + - T: "норма" + - x: "*[1]/*[1]" + +- name: SimpleSpeak-absolute-value + tag: absolute-value + match: "." + replace: + - T: "модуль" + - x: "*[1]" + - name: SimpleSpeak-log tag: mrow match: diff --git a/Rules/Languages/ru/unicode-full.yaml b/Rules/Languages/ru/unicode-full.yaml index 09172881e..bf7f02d9c 100644 --- a/Rules/Languages/ru/unicode-full.yaml +++ b/Rules/Languages/ru/unicode-full.yaml @@ -14,9 +14,11 @@ - "«": [T: "левая двойная угловая кавычка"] # 0xab - "¯": # 0xaf - test: - if: "ancestor::m:modified-variable and preceding-sibling::*[1][self::m:mi]" - then: [T: "черта"] - else: [T: "линия"] + - if: "(parent::m:mover or parent::m:modified-variable) and preceding-sibling::*[1][self::m:mi]" + then: [T: "с чертой"] + - else_if: "parent::m:mover or parent::m:modified-variable" + then: [T: "чертой"] + - else: [T: "линия"] - "²": [T: "два"] # 0xb2 - "³": [T: "три"] # 0xb3 - "´": [T: "акут"] # 0xb4 @@ -791,7 +793,11 @@ if: "$Verbosity!='Terse'" then: [T: "является"] - T: "пропорционально" - - "∞": [T: "бесконечность"] # 0x221e + - "∞": # 0x221e + - test: + if: "ancestor::*[self::m:limit or self::m:limit-sup or self::m:limit-inf]" + then: [T: "бесконечности"] + else: [T: "бесконечность"] - "∟": [T: "прямой угол"] # 0x221f - "∠": [T: "угол"] # 0x2220 - "∡": [T: "измеренный угол"] # 0x2221 diff --git a/tests/Languages/ru/SimpleSpeak/linear_algebra.rs b/tests/Languages/ru/SimpleSpeak/linear_algebra.rs index dbb29089c..314a58207 100644 --- a/tests/Languages/ru/SimpleSpeak/linear_algebra.rs +++ b/tests/Languages/ru/SimpleSpeak/linear_algebra.rs @@ -97,6 +97,28 @@ fn norm_subscripted() -> Result<()> { return Ok(()); } +#[test] +fn norm_with_subscript_on_closing_bar() -> Result<()> { + // Recognize the TeX4ht form in which only the closing norm bar carries the index. + let expr = "∥A∥p"; + test("ru", "SimpleSpeak", expr, "норма заглавной а с индексом пэ")?; + test("ru", "ClearSpeak", expr, "норма заглавной а с индексом пэ")?; + + let doubled_bars = "||x||∞"; + test("ru", "SimpleSpeak", doubled_bars, "норма икс с индексом бесконечность")?; + test("ru", "ClearSpeak", doubled_bars, "норма икс с индексом бесконечность")?; + return Ok(()); +} + +#[test] +fn norm_with_doubled_ordinary_bars() -> Result<()> { + // TeX4ht sometimes emits a norm as two adjacent ordinary bars on each side. + let expr = "||x+y||"; + test("ru", "SimpleSpeak", expr, "норма икс плюс игрек")?; + test("ru", "ClearSpeak", expr, "норма икс плюс игрек")?; + return Ok(()); +} + #[test] fn not_gradient() -> Result<()> { // the nabla is at the end, so it can't be gradient because it doesn't operate on anything diff --git a/tests/Languages/ru/mtable.rs b/tests/Languages/ru/mtable.rs index 13b7e5b77..b44af3283 100644 --- a/tests/Languages/ru/mtable.rs +++ b/tests/Languages/ru/mtable.rs @@ -558,11 +558,11 @@ fn simple_absolute_value() -> Result<()> { let expr = " | x | "; - test("ru", "SimpleSpeak", expr, "модуль от икс")?; - test("ru", "ClearSpeak", expr, "модуль из икс")?; - test_prefs("ru", "ClearSpeak", vec![("Verbosity", "Terse"), ("ClearSpeak_AbsoluteValue", "Auto")], expr, "модуль из икс")?; + test("ru", "SimpleSpeak", expr, "модуль икс")?; + test("ru", "ClearSpeak", expr, "модуль икс")?; + test_prefs("ru", "ClearSpeak", vec![("Verbosity", "Terse"), ("ClearSpeak_AbsoluteValue", "Auto")], expr, "модуль икс")?; test_prefs("ru", "ClearSpeak", vec![("Verbosity", "Verbose"), ("ClearSpeak_AbsoluteValue", "AbsEnd")], - expr, "модуль из икс, конец модуля")?; + expr, "модуль икс, конец модуля")?; return Ok(()); } @@ -573,9 +573,9 @@ let expr = " x+1 | "; - test("ru", "ClearSpeak", expr, "модуль из икс плюс 1")?; + test("ru", "ClearSpeak", expr, "модуль икс плюс 1")?; test_prefs("ru", "ClearSpeak", vec![("Verbosity", "Terse"), ("ClearSpeak_AbsoluteValue", "AbsEnd")], - expr, "модуль из икс плюс 1, конец модуля")?; + expr, "модуль икс плюс 1, конец модуля")?; return Ok(()); } @@ -585,7 +585,7 @@ fn simple_cardinality_value() -> Result<()> { | S |
"; test_prefs("ru", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_AbsoluteValue", "Cardinality")], expr, - "мощность множества из заглавной эс")?; + "мощность множества заглавной эс")?; return Ok(()); } @@ -1081,6 +1081,21 @@ fn unknown_mtable_property() -> Result<()> { return Ok(()); } +#[test] +fn gathered_continued_equation() -> Result<()> { + // A gathered display is one derivation split across lines; do not duplicate + // the equality at the wrap or announce its final sentence punctuation. + let expr = " + a= + =b. + "; + test("ru", "ClearSpeak", expr, "2 строки, строка 1; а; строка 2; равно бэ")?; + test("ru", "SimpleSpeak", expr, "2 строки; строка 1; а; строка 2; равно бэ")?; + test("ru", "LiteralSpeak", expr, + "таблица с 2 строками и 1 столбцом; строка 1; столбец 1; а равно; строка 2; столбец 1; равно бэ точка")?; + Ok(()) +} + #[test] fn zero_matrix() -> Result<()> { diff --git a/tests/Languages/ru/shared.rs b/tests/Languages/ru/shared.rs index b04221b2c..3230e5000 100644 --- a/tests/Languages/ru/shared.rs +++ b/tests/Languages/ru/shared.rs @@ -27,6 +27,41 @@ fn modified_vars() -> Result<()> { return Ok(()); } +#[test] +fn double_overline() -> Result<()> { + // A nested overline should be announced as one standard Russian mathematical term. + let expr = " + + z¯ + ¯ + + "; + let expected = "зэт с двойным надчёркиванием"; + test("ru", "LiteralSpeak", expr, expected)?; + test("ru", "ClearSpeak", expr, expected)?; + test("ru", "SimpleSpeak", expr, expected)?; + Ok(()) +} + +#[test] +fn complex_number_modulus_identity() -> Result<()> { + // An overlined variable and an absolute value should use natural Russian terminology. + let expr = " + z⁢z¯ + = + x2+y2 + = + |z|2 + "; + test("ru", "ClearSpeak", expr, + "зэт зэт с чертой равно икс в квадрате плюс игрек в квадрате равно модуль зэт, в квадрате")?; + test("ru", "SimpleSpeak", expr, + "зэт зэт с чертой равно икс в квадрате плюс игрек в квадрате равно модуль зэт в квадрате")?; + test("ru", "LiteralSpeak", expr, + "зэт зэт с чертой равно икс верхний индекс 2 конец верхнего индекса плюс игрек верхний индекс 2 конец верхнего индекса равно вертикальная черта зэт вертикальная черта верхний индекс 2 конец верхнего индекса")?; + Ok(()) +} + #[test] fn limit() -> Result<()> { let expr = " @@ -375,6 +410,18 @@ fn mn_with_block_and_decimal_separators() -> Result<()> { return Ok(()); } +#[test] +fn named_operators_with_lower_limits() -> Result<()> { + // TeX4ht wraps named operators and the invisible apply character in the munder base. + let max_expr = "max⁡i"; + let lim_expr = "lim⁡x→∞"; + test("ru", "SimpleSpeak", max_expr, "максимум по и")?; + test("ru", "ClearSpeak", max_expr, "максимум по и")?; + test("ru", "SimpleSpeak", lim_expr, "предел при икс стремящемся к бесконечности")?; + test("ru", "ClearSpeak", lim_expr, "предел при икс стремящемся к бесконечности")?; + return Ok(()); +} + #[test] fn divergence() -> Result<()> { let expr = "∇·F"; From 71f208c62c6450c5120df7490112c39f4e609c04 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Tue, 29 Sep 2026 12:45:23 -0700 Subject: [PATCH 151/157] added/modified comments for functions that deal with function names and parts --- src/xpath_functions.rs | 92 ++++++++++++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 31 deletions(-) diff --git a/src/xpath_functions.rs b/src/xpath_functions.rs index a713fad88..29215c65f 100644 --- a/src/xpath_functions.rs +++ b/src/xpath_functions.rs @@ -1198,14 +1198,16 @@ impl Function for EdgeNode { } pub struct SpeakIntentName; -/// SpeakIntentName(intent, verbosity, fixity) -/// Real-life example: -/// If a MathML element has intent="factorial($x)", in the rules you might see: -/// - x: "SpeakIntentName(name(.), $Verbosity, 'postfix')" -/// For English, MathCAT will resolve: -/// SpeakIntentName("factorial", "Verbose", "postfix") → "factorial" -/// This is used to generate speech like "x factorial" for expressions like "x!". -/// Returns a string corresponding to the intent name with the indicated verbosity +/// SpeakIntentName(intentName, verbosity, fixity) +/// Returns the spoken name for an intent, using the selected verbosity and fixity. +/// Calling arguments (as used by the rule layer): +/// 1. intentName: the intent name, e.g. "factorial" or "ratio" +/// 2. verbosity: "Terse", "Medium", or "Verbose" +/// 3. fixity: the function fixity, e.g. "prefix", "infix", "postfix" +/// Example: +/// SpeakIntentName("factorial", "Verbose", "postfix") -> "factorial" +/// SpeakIntentName("ratio", "Medium", "infix") -> "ratio" +/// This is used to generate speech such as "x factorial" for expressions like "x!". impl Function for SpeakIntentName { fn evaluate<'d>(&self, _context: &context::Evaluation<'_, 'd>, @@ -1222,12 +1224,16 @@ impl Function for SpeakIntentName { } pub struct IntentFunctionUseArityPath; -/// IntentFunctionUseArityPath(name, fixity, argCount) -/// True when IntentMappings `|` arity templates match this argument count. -/// For example, in en/definitions.yaml for intent "choose": -/// "function=choose|from|to" -/// means for three arguments, templates like "choose n from k to l" apply. -/// This returns true if the `choose` function is used with three arguments. +/// IntentFunctionUseArityPath(intentName, fixity, argCount) +/// Returns true when the intent uses an arity-based template instead of a binary separator form. +/// Calling arguments (as used by the rule layer): +/// 1. intentName: the intent name, e.g. "choose" or "ratio" +/// 2. fixity: the function fixity, e.g. "function" or "postfix" +/// 3. argCount: the number of arguments supplied to the function +/// Example: +/// IntentFunctionUseArityPath("choose", "function", 3) -> true +/// IntentFunctionUseArityPath("ratio", "function", 2) -> false +/// This is used for patterns such as "choose n from k to l", where the template depends on arity. impl Function for IntentFunctionUseArityPath { fn evaluate<'d>(&self, _context: &context::Evaluation<'_, 'd>, @@ -1246,8 +1252,17 @@ impl Function for IntentFunctionUseArityPath { } pub struct IntentFunctionGlueBefore; -/// IntentFunctionGlueBefore(name, fixity, argIndex, argCount) -/// Glue spoken immediately before the given 1-based argument when using an arity template. +/// IntentFunctionGlueBefore(intentName, fixity, argIndex, argCount) +/// Returns the leading glue text to speak before a specific argument in an arity-based template. +/// Calling arguments (as used by the rule layer): +/// 1. intentName: the intent name, e.g. "choose" or "binomial" +/// 2. fixity: the function fixity, e.g. "function" +/// 3. argIndex: the 1-based argument position to inspect +/// 4. argCount: the total number of arguments in the call +/// Example: +/// IntentFunctionGlueBefore("choose", "function", 2, 3) -> "from" +/// IntentFunctionGlueBefore("choose", "function", 3, 3) -> "to" +/// This controls text such as "choose n from k to l". impl Function for IntentFunctionGlueBefore { fn evaluate<'d>(&self, _context: &context::Evaluation<'_, 'd>, @@ -1267,13 +1282,16 @@ impl Function for IntentFunctionGlueBefore { } pub struct IntentFunctionArgSeparator; -/// IntentFunctionArgSeparator(name, fixity, argCount) -/// Glue spoken immediately before the given 1-based argument when using an arity template. -/// For example, in en/definitions.yaml, for the intent name "choose", the mapping is: -/// "function=choose|from|to". -/// When called as IntentFunctionGlueBefore("choose", "function", 2, 3), this returns "from", -/// which is spoken before the second argument when reading an expression like "choose n from k". -/// Likewise, for arg_index = 3, it would return "to". +/// IntentFunctionArgSeparator(intentName, fixity, argCount) +/// Returns the separator text placed between arguments when the intent uses a binary separator form. +/// Calling arguments (as used by the rule layer): +/// 1. intentName: the intent name, e.g. "ratio" or "gcd" +/// 2. fixity: the function fixity, e.g. "function" +/// 3. argCount: the number of arguments supplied to the function +/// Example: +/// IntentFunctionArgSeparator("ratio", "function", 2) -> "to" +/// IntentFunctionArgSeparator("gcd", "function", 2) -> "and" +/// This is the text spoken between the first and second arguments, as in "ratio of 6 to 3". impl Function for IntentFunctionArgSeparator { fn evaluate<'d>(&self, _context: &context::Evaluation<'_, 'd>, @@ -1292,9 +1310,17 @@ impl Function for IntentFunctionArgSeparator { } pub struct GetBracketingIntentName; -/// GetBracketingIntentName(name, verbosity, at_start_or_end) -/// Returns a potentially empty string to use to bracket an intent expression (start foo... end foo) -/// +/// GetBracketingIntentName(intentName, fixity, verbosity, startOrEnd) +/// Returns the optional bracket wording for an intent expression, such as the leading/trailing phrase +/// around a start/end bracketed form. +/// Calling arguments (as used by the rule layer): +/// 1. intentName: the intent name, e.g. "floor" or "ceil" +/// 2. fixity: the fixity, e.g. "prefix" or "postfix" +/// 3. verbosity: "Terse", "Medium", or "Verbose" +/// 4. startOrEnd: either "start" or "end" +/// Example: +/// GetBracketingIntentName("floor", "prefix", "Medium", "start") -> "the floor of" +/// This is used to wrap expressions like "the floor of x" rather than just speaking the bare function name. impl GetBracketingIntentName { fn bracketing_words(intent_name: &str, verbosity: &str, fixity: &str, at_start: bool) -> String { crate::definitions::SPEECH_DEFINITIONS.with(|definitions| { @@ -1360,11 +1386,15 @@ impl Function for GetBracketingIntentName { } pub struct GetNavigationPartName; -/// GetNavigationPartName(name, index) -/// Returns the name to use to speak the part of a navigation expression (e.g., 'numerator', 'denominator', 'base', 'exponent', ...). -/// If there is no match, an empty string is returned. -/// 'index' is 0-based -/// +/// GetNavigationPartName(intentName, index) +/// Returns the navigation label for one part of a structured expression. +/// Calling arguments (as used by the rule layer): +/// 1. intentName: the intent name, e.g. "fraction" or "power" +/// 2. index: the 0-based position of the part to speak +/// Example: +/// GetNavigationPartName("fraction", 0) -> "numerator" +/// GetNavigationPartName("fraction", 1) -> "denominator" +/// If no matching part exists, this returns an empty string. impl GetNavigationPartName { fn navigation_part_name(intent_name: &str, index: usize) -> String { crate::definitions::SPEECH_DEFINITIONS.with(|definitions| { From 5ad398739270ed10fcd32c6dcab78d871b8ba131 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Wed, 30 Sep 2026 00:11:05 -0700 Subject: [PATCH 152/157] Swap IntentMappings so ":" is argument glue and "|" is verbosity -- this looks much better. All language `definitions.yaml` are updated. Fix parsing of `IntentMappings`. Parsing now lives in one place, so ratio-style "name : glue" pairs, arity templates, and bracketing speech stay consistent across languages. This all started as a fix to #709, but then I discovered that the format used in `IntentMappings` was parsed incorrectly in some cases (such as "ratio"). --- Rules/Intent/general.yaml | 14 ++ Rules/Languages/de/definitions.yaml | 127 +++++++--- Rules/Languages/el/definitions.yaml | 123 ++++++++-- Rules/Languages/en/definitions.yaml | 176 ++++++------- Rules/Languages/es/definitions.yaml | 113 +++++++-- Rules/Languages/fi/definitions.yaml | 101 ++++++-- Rules/Languages/fr/definitions.yaml | 130 +++++++--- Rules/Languages/hu/definitions.yaml | 168 +++++++------ Rules/Languages/id/definitions.yaml | 111 +++++++-- Rules/Languages/nb/definitions.yaml | 101 ++++++-- Rules/Languages/pl/definitions.yaml | 167 +++++++++---- Rules/Languages/pt/definitions.yaml | 119 +++++++-- Rules/Languages/ru/definitions.yaml | 125 +++++++--- Rules/Languages/sv/definitions.yaml | 113 +++++++-- Rules/Languages/vi/definitions.yaml | 105 ++++++-- Rules/Languages/zh/tw/definitions.yaml | 157 ++++++++---- Rules/Languages/zz/definitions.yaml | 95 ++++++- src/infer_intent.rs | 328 ++++++++++++++++--------- src/xpath_functions.rs | 45 +--- tests/Languages/en/definitions.rs | 20 +- 20 files changed, 1766 insertions(+), 672 deletions(-) diff --git a/Rules/Intent/general.yaml b/Rules/Intent/general.yaml index 15bd1dc7a..54303de79 100644 --- a/Rules/Intent/general.yaml +++ b/Rules/Intent/general.yaml @@ -81,6 +81,20 @@ children: [x: "*[2]"] + +- + # We want to say "ratio of x to y" instead of "x ratio y" (which is ambiguous) + name: ratio + tag: mrow + match: "count(*)=3 and *[2][self::m:mo][.='∶']" + replace: + - intent: + name: "ratio" + attrs: "data-intent-property='concat(data-intent-property, \":function:\")'" + children: + - x: "*[1]" + - x: "*[3]" + - # (a,b) has many interpretations; (a, b] (etc) have fewer interpretations. # as an interval, it represents a set and hence a clue that it is an interval is that a set operator comes diff --git a/Rules/Languages/de/definitions.yaml b/Rules/Languages/de/definitions.yaml index 73dfcf7f7..4e1cce7f7 100644 --- a/Rules/Languages/de/definitions.yaml +++ b/Rules/Languages/de/definitions.yaml @@ -1,48 +1,117 @@ --- - include: "../../definitions.yaml" -# If an "intent" is used, the 'terse:medium:verbose' speech for the intent name is given here for a prefix||infix||postfix||function fixity -# If only one ":" is used, it the first part is used for 'terse' and the second part is used for 'medium' and 'verbose' -# If no ":"s are used, the same speech is used for all forms -# If bracketing words make sense, they are separated with ";"s -# Intent mappings must specify whether they are "prefix", "infix", "postfix", or "function" with an "=" sign -# If there are multiple fixities (e.g., see transpose), they are separated with "|| -# for readability, spaces can be used around any of the delimiter characters -# Note: if there are multiple fixities, the first one is used if the fixity is not given in the intent +# IntentMappings Syntax: +# +# This section defines how each "intent" is spoken for various grammatical forms (fixities such as "prefix", "infix", "postfix", and "function"), +# along with supporting different verbosity levels. +# The syntax is a little bit complicated, but allows a declarative syntax so you don't have to write as many rules. +# +# For each intent, you specify spoken forms for one or more fixities using the syntax below. +# +# - Each mapping has the form: +# "": "= || = || ...", +# Every alternative must name a fixity and use "="; the fixity requested when speaking selects one. +# +# - Separate multiple fixities with "||". Spaces are allowed around any delimiter for readability. +# - Within a speech string, "|" selects the verbosity form: +# - one "|" (two forms): the first is 'terse', the second is used for 'medium' and 'verbose' +# - two "|" (three forms): 'terse', 'medium', 'verbose', in that order +# - no "|": the same spoken form is used for all verbosity levels +# +# - Use semicolons ";" to divide opening; main; closing bracketing words within the name part, +# where such words make sense (a name with no ";" is just the main phrase). +# - If an intent has multiple fixities but a definition does not specify one, the first fixity listed is chosen by default. +# +# Functions and argument glue (the part after the name): +# - ":" separates the name/bracketing phrase from the argument-glue options that follow it. +# - Arity template (two or more ":" options, or one option with ','-separated glue words): the +# number of glue words implies the arity, and the final argument is preceded by "of". +# Example: "sum: over: from,to" +# - 1 arg: "sum of x" +# - 2 args: "sum over i of x" +# - 3 args: "sum from i to n of x" +# If no option matches the argument count, the arguments are separated with "comma". +# - Binary separator (exactly one ":" option, no commas in it): after "of", that word joins the two args. +# Example: "quotient": "function=integer part: divided by" → "integer part of x divided by y" +# If there are not exactly two args, the arguments fall back to "comma". +# - Paired "ratio-style" (" : | : | ..."): used when every "|"-separated +# piece is a single "name : glue" pair. Verbosity selects one pair, whose glue is the binary +# separator described above. Example: "ratio": "function=ratio : to | the ratio : to | the ratio : to" +# +# Conceptual grammar (with precedence): +# +# IntentMappingsEntry ::= ":" # ":" is the YAML key/value separator +# +# ::= ( "||" )* +# +# ::= "=" +# +# ::= "prefix" | "infix" | "postfix" | "function" | "nofix" | "silent" +# +# ::= | +# +# # Standard form: a name/bracketing part, then ":"-separated argument-glue options. +# ::= ( ":" )* +# +# ::= [ ";" ";" ] # 1 part: name; 3 parts: opening; main; closing +# +# ::= [ "|" [ "|" ] ] # terse | medium | verbose +# +# ::= # a single glue word, or ","-separated arity words +# +# # Paired "ratio-style" form: recognized only when every "|" piece is a single "name : glue" pair. +# ::= ( "|" )+ +# +# ::= ":" # the glue contains no ":" +# +# ::= text +# +# Precedence depends on the form: +# - Standard: split on ":" first (name vs. argument-glue options), then split each piece on "|" +# for terse|medium|verbose, and split only the name part on ";" for opening; main; closing. +# - Paired: split on "|" first into "name : glue" pairs, then verbosity selects one pair. +# +# Example: +# "absolute-value": "function= ; absolute value| the absolute value| the absolute value; end absolute value" +# "sum": "function=sum: over: from,to" +# "quotient": "function=integer part: divided by" +# "ratio": "function=ratio : to | the ratio : to | the ratio : to" # verbosity of name:glue pairs +# - IntentMappings: { - "indexed-by": "infix= ; sub; ende sub: ende sub: ende subskript", + "indexed-by": "infix= ; sub; ende sub| ende sub| ende subskript", "modified-variable": "silent= ", - "say-super": "infix=super: hochstellung: hochstellung", + "say-super": "infix=super| hochstellung| hochstellung", "skip-super": "silent=", - "absolute-value": "function= ; absoluter wert: der absolute wert: der absolute wert; ende absoluter wert", + "absolute-value": "function= ; absoluter wert| der absolute wert| der absolute wert; ende absoluter wert", "binomial": "infix=binomial; wählen; ende binomial", "dimension-product": "infix=mal", - "greatest-common-divisor": "function=gcd: der gcd: der größte gemeinsame teiler", + "greatest-common-divisor": "function=gcd| der gcd| der größte gemeinsame teiler", "imaginary-part": "function=imaginärer teil, der imaginäre teil, der imaginäre teil", - "least-common-multiple": "function=lcm:der lcm:das kleinste gemeinsame vielfache", - "limit": "prefix=grenzwert bei: der grenzwert bei: der grenzwert bei", - "lim-sup": "prefix=lim sup bei: der obere grenzwert bei: der obere grenzwert bei", - "lim-inf": "prefix=lim inf bei: der untere grenzwert bei : der untere grenzwert bei", - "logarithm-with-base": "prefix=logarithmus basis: der logarithmus basis: der logarithmus basis", - "natural-logarithm": "function=ln: natürlicher logarithmus: natürlicher logarithmus", + "least-common-multiple": "function=lcm|der lcm|das kleinste gemeinsame vielfache", + "limit": "prefix=grenzwert bei| der grenzwert bei| der grenzwert bei", + "lim-sup": "prefix=lim sup bei| der obere grenzwert bei| der obere grenzwert bei", + "lim-inf": "prefix=lim inf bei| der untere grenzwert bei | der untere grenzwert bei", + "logarithm-with-base": "prefix=logarithmus basis| der logarithmus basis| der logarithmus basis", + "natural-logarithm": "function=ln| natürlicher logarithmus| natürlicher logarithmus", "minus": "infix=minus || prefix=minus", "plus": "infix=plus || prefix=plus", "real-part": "function=der reale teil", "transpose": "postfix=transponiert || function=die Transponierte", - "magnitude": "function=; Norm: Norm: Norm; Ende Norm", - "norm": "function=; norm: norm: norm; ende norm", - "trace": "function=; spur : spur: die spur; ende spur", - "dimension": "function=; dimension : dimension: die dimension; ende dimension", - "homomorphism": "function= ; homomorphismus : homomorphismus: der homomorphismus; ende homomorphismus", - "kernel": "function= ; kern : kern: der kern; ende kern", + "magnitude": "function=; Norm| Norm| Norm; Ende Norm", + "norm": "function=; norm| norm| norm; ende norm", + "trace": "function=; spur | spur| die spur; ende spur", + "dimension": "function=; dimension | dimension| die dimension; ende dimension", + "homomorphism": "function= ; homomorphismus | homomorphismus| der homomorphismus; ende homomorphismus", + "kernel": "function= ; kern | kern| der kern; ende kern", "vector": "function= ; vektor || prefix=vektor", - "cross-product": "infix=kreuz: kreuzprodukt: kreuzprodukt", - "dot-product": "infix=punkt: punktprodukt: punkt:punktprodukt", - "divergence": "function= ; div: divergenz: divergenz; ende divergenz", + "cross-product": "infix=kreuz| kreuzprodukt| kreuzprodukt", + "dot-product": "infix=punkt| punktprodukt| punkt|punktprodukt", + "divergence": "function= ; div| divergenz| divergenz; ende divergenz", "curl": "function= ; rotation; ende rotation", - "gradient": "function= ; grad: gradient: gradient; ende gradient", + "gradient": "function= ; grad| gradient| gradient; ende gradient", "laplacian": "function=laplace", - "chemistry-concentration": "function= ; konzentration: konzentration von: die konzentration von; ende konzentration" + "chemistry-concentration": "function= ; konzentration| konzentration von| die konzentration von; ende konzentration" } - NavigationParts: { diff --git a/Rules/Languages/el/definitions.yaml b/Rules/Languages/el/definitions.yaml index d507f0719..d00479d31 100644 --- a/Rules/Languages/el/definitions.yaml +++ b/Rules/Languages/el/definitions.yaml @@ -2,33 +2,102 @@ --- - include: "../../definitions.yaml" -# If an "intent" is used, the 'terse:medium:verbose' speech for the intent name is given here for a prefix||infix||postfix||function fixity -# If only one ":" is used, the first part is used for 'terse' and the second part is used for 'medium' and 'verbose' -# If no ":"s are used, the same speech is used for all forms -# If bracketing words make sense, they are separated with ";"s -# Intent mappings must specify whether they are "prefix", "infix", "postfix", or "function" with an "=" sign -# If there are multiple fixities (e.g., see transpose), they are separated with "||" -# for readability, spaces can be used around any of the delimiter characters -# Note: if there are multiple fixities, the first one is used if the fixity is not given in the intent +# IntentMappings Syntax: +# +# This section defines how each "intent" is spoken for various grammatical forms (fixities such as "prefix", "infix", "postfix", and "function"), +# along with supporting different verbosity levels. +# The syntax is a little bit complicated, but allows a declarative syntax so you don't have to write as many rules. +# +# For each intent, you specify spoken forms for one or more fixities using the syntax below. +# +# - Each mapping has the form: +# "": "= || = || ...", +# Every alternative must name a fixity and use "="; the fixity requested when speaking selects one. +# +# - Separate multiple fixities with "||". Spaces are allowed around any delimiter for readability. +# - Within a speech string, "|" selects the verbosity form: +# - one "|" (two forms): the first is 'terse', the second is used for 'medium' and 'verbose' +# - two "|" (three forms): 'terse', 'medium', 'verbose', in that order +# - no "|": the same spoken form is used for all verbosity levels +# +# - Use semicolons ";" to divide opening; main; closing bracketing words within the name part, +# where such words make sense (a name with no ";" is just the main phrase). +# - If an intent has multiple fixities but a definition does not specify one, the first fixity listed is chosen by default. +# +# Functions and argument glue (the part after the name): +# - ":" separates the name/bracketing phrase from the argument-glue options that follow it. +# - Arity template (two or more ":" options, or one option with ','-separated glue words): the +# number of glue words implies the arity, and the final argument is preceded by "of". +# Example: "sum: over: from,to" +# - 1 arg: "sum of x" +# - 2 args: "sum over i of x" +# - 3 args: "sum from i to n of x" +# If no option matches the argument count, the arguments are separated with "comma". +# - Binary separator (exactly one ":" option, no commas in it): after "of", that word joins the two args. +# Example: "quotient": "function=integer part: divided by" → "integer part of x divided by y" +# If there are not exactly two args, the arguments fall back to "comma". +# - Paired "ratio-style" (" : | : | ..."): used when every "|"-separated +# piece is a single "name : glue" pair. Verbosity selects one pair, whose glue is the binary +# separator described above. Example: "ratio": "function=ratio : to | the ratio : to | the ratio : to" +# +# Conceptual grammar (with precedence): +# +# IntentMappingsEntry ::= ":" # ":" is the YAML key/value separator +# +# ::= ( "||" )* +# +# ::= "=" +# +# ::= "prefix" | "infix" | "postfix" | "function" | "nofix" | "silent" +# +# ::= | +# +# # Standard form: a name/bracketing part, then ":"-separated argument-glue options. +# ::= ( ":" )* +# +# ::= [ ";" ";" ] # 1 part: name; 3 parts: opening; main; closing +# +# ::= [ "|" [ "|" ] ] # terse | medium | verbose +# +# ::= # a single glue word, or ","-separated arity words +# +# # Paired "ratio-style" form: recognized only when every "|" piece is a single "name : glue" pair. +# ::= ( "|" )+ +# +# ::= ":" # the glue contains no ":" +# +# ::= text +# +# Precedence depends on the form: +# - Standard: split on ":" first (name vs. argument-glue options), then split each piece on "|" +# for terse|medium|verbose, and split only the name part on ";" for opening; main; closing. +# - Paired: split on "|" first into "name : glue" pairs, then verbosity selects one pair. +# +# Example: +# "absolute-value": "function= ; absolute value| the absolute value| the absolute value; end absolute value" +# "sum": "function=sum: over: from,to" +# "quotient": "function=integer part: divided by" +# "ratio": "function=ratio : to | the ratio : to | the ratio : to" # verbosity of name:glue pairs +# - IntentMappings: { - "indexed-by": "infix= ; δείκτης; τέλος δείκτη: τέλος δείκτη: τέλος δείκτη", + "indexed-by": "infix= ; δείκτης; τέλος δείκτη| τέλος δείκτη| τέλος δείκτη", "modified-variable": "silent= ", - "say-super": "infix= εις την: εκθέτης: εκθέτης", # used with 'mo' for superscripts (e.g, "<") + "say-super": "infix= εις την| εκθέτης| εκθέτης", # used with 'mo' for superscripts (e.g, "<") "skip-super": "silent=", # used with 'mo' for superscripts (e.g, "*") - "absolute-value": "function= ; απόλυτη τιμή: η απόλυτη τιμή: η απόλυτη τιμή; τέλος απόλυτης τιμής", + "absolute-value": "function= ; απόλυτη τιμή| η απόλυτη τιμή| η απόλυτη τιμή; τέλος απόλυτης τιμής", "binomial": "infix=διωνυμικό; ανά; τέλος διωνυμικού", #theodora. ανἀ = chooce in english. check "dimension-product": "infix=επί", # "closed-interval": "other=closed-interval; from,to; end closed-interval", - "greatest-common-divisor": "function=μκδ: ο μκδ: ο μέγιστος κοινός διαιρέτης", # theodora. check how μκδ and εκπ sounds + "greatest-common-divisor": "function=μκδ| ο μκδ| ο μέγιστος κοινός διαιρέτης", # theodora. check how μκδ and εκπ sounds "imaginary-part": "function=φανταστικό μέρος, το φανταστικό μέρος, το φανταστικό μέρος", - "least-common-multiple": "function=εκπ:το εκπ:το ελάχιστο κοινό πολλαπλάσιο", + "least-common-multiple": "function=εκπ|το εκπ|το ελάχιστο κοινό πολλαπλάσιο", # "large-op": "infix=over || other=from,to", - "limit": "prefix=όριο όταν: το όριο όταν: το όριο όταν", - "lim-sup": "prefix=ανώτατο όριο όταν: το ανώτατο όριο όταν: το ανώτατο όριο όταν", #theodora. check "όταν " english: as - "lim-inf": "prefix=κατώτατο όριο όταν: το κατώτατο όριο όταν : το κατώτατο όριο όταν", - "logarithm-with-base": "prefix=ο λογάριθμος με βάση: ο λογάριθμος με βάση: ο λογάριθμος με βάση", - "natural-logarithm": "function=l n: φυσικός λογάριθμος: φυσικός λογάριθμος", + "limit": "prefix=όριο όταν| το όριο όταν| το όριο όταν", + "lim-sup": "prefix=ανώτατο όριο όταν| το ανώτατο όριο όταν| το ανώτατο όριο όταν", #theodora. check "όταν " english: as + "lim-inf": "prefix=κατώτατο όριο όταν| το κατώτατο όριο όταν | το κατώτατο όριο όταν", + "logarithm-with-base": "prefix=ο λογάριθμος με βάση| ο λογάριθμος με βάση| ο λογάριθμος με βάση", + "natural-logarithm": "function=l n| φυσικός λογάριθμος| φυσικός λογάριθμος", "minus": "infix=μείον || prefix=μείον", "plus": "infix=συν || prefix=συν", # check. prefix = negative prefix = positive in english. not always appropriate/unatural for greek @@ -37,21 +106,21 @@ "transpose": "postfix=ανάστροφος || function=ανάστροφος", "magnitude": "postfix=νόρμα || function=νόρμα", #theodora. added the magnitude, was read in english otherwise. Check if "διπλή κάθετος" is more appropriate - "norm": "function=; νόρμα: νόρμα: νόρμα; τέλος νόρμας", - "trace": "function=;ίχνος : ίχνος: το ίχνος; τέλος ίχνους", - "dimension": "function=; διάσταση : διάσταση: η διάσταση; τέλος διάστασης", - "homomorphism": "function= ; ομομορφισμός : ομομορφισμός: ο ομομορφισμός; τέλος ομομορφισμού", - "kernel": "function= ; πυρήνας : πυρήνας: ο πυρήνας; τέλος πυρήνα", + "norm": "function=; νόρμα| νόρμα| νόρμα; τέλος νόρμας", + "trace": "function=;ίχνος | ίχνος| το ίχνος; τέλος ίχνους", + "dimension": "function=; διάσταση | διάσταση| η διάσταση; τέλος διάστασης", + "homomorphism": "function= ; ομομορφισμός | ομομορφισμός| ο ομομορφισμός; τέλος ομομορφισμού", + "kernel": "function= ; πυρήνας | πυρήνας| ο πυρήνας; τέλος πυρήνα", "vector": "function= ; διάνυσμα || prefix=διάνυσμα", "cross-product": "infix=διανυσματικό γινόμενο", # theodora. check το είχε έτσι "infix=cross: διανυσματικό γινόμενο: διανυσματικό γινόμενο", - "dot-product": "infix=τελεία: εσωτερικό γινόμενο: τελεία: εσωτερικό γινόμενο", #theodora. check. είναι ολα εσωτερικό γινόμενο ή πιάνει κι άλλα οπότε θέλει πιο γενικό όρο; + "dot-product": "infix=τελεία| εσωτερικό γινόμενο| τελεία| εσωτερικό γινόμενο", #theodora. check. είναι ολα εσωτερικό γινόμενο ή πιάνει κι άλλα οπότε θέλει πιο γενικό όρο; - "divergence": "function= ; απόκλιση: απόκλιση: απόκλιση; τέλος απόκλισης", + "divergence": "function= ; απόκλιση| απόκλιση| απόκλιση; τέλος απόκλισης", "curl": "function= ; στροβιλισμός; τέλος στροβιλισμού", - "gradient": "function= ; ανάδελτα: ανάδελτα: ανάδελτα; τέλος ανάδελτα", + "gradient": "function= ; ανάδελτα| ανάδελτα| ανάδελτα; τέλος ανάδελτα", "laplacian": "function=λαπλασιανή", # speech engines don't do a good job with "laplacian" - "chemistry-concentration": "function= ; συγκέντρωση: η συγκέντρωση του: η συγκέντρωση του; τέλος συγκέντρωσης", + "chemistry-concentration": "function= ; συγκέντρωση| η συγκέντρωση του| η συγκέντρωση του; τέλος συγκέντρωσης", } # Names of functions that in terse mode don't say "of" (or it's equivalent in other languages) diff --git a/Rules/Languages/en/definitions.yaml b/Rules/Languages/en/definitions.yaml index bd3931549..677d7c78c 100644 --- a/Rules/Languages/en/definitions.yaml +++ b/Rules/Languages/en/definitions.yaml @@ -11,60 +11,72 @@ # # - Each mapping has the form: # "": "= || = || ...", -# or just -# "": "", -# where is used for all forms if fixity and '=' are omitted. +# Every alternative must name a fixity and use "="; the fixity requested when speaking selects one. # -# - If an intent has multiple fixities, separate them with "||". Spaces are allowed around delimiters for readability. -# - If only one ":" is present in **, it provides the 'terse' form, and the following string is used for both 'medium' and 'verbose'. -# - If more than one ":" is present, the string is split into 'terse', 'medium', and 'verbose' forms, in that order (each separated by ":"). -# - If no ":" is present, the same spoken form is used for all styles. +# - Separate multiple fixities with "||". Spaces are allowed around any delimiter for readability. +# - Within a speech string, "|" selects the verbosity form: +# - one "|" (two forms): the first is 'terse', the second is used for 'medium' and 'verbose' +# - two "|" (three forms): 'terse', 'medium', 'verbose', in that order +# - no "|": the same spoken form is used for all verbosity levels # -# - Use semicolons ";" to divide opening, main, and closing bracketing words within a speech string, where such words make sense. +# - Use semicolons ";" to divide opening; main; closing bracketing words within the name part, +# where such words make sense (a name with no ";" is just the main phrase). # - If an intent has multiple fixities but a definition does not specify one, the first fixity listed is chosen by default. # -# Functions and argument glue: -# - The "|" character delimits options describing how to glue arguments together when speaking function arguments. -# - Arity templates (multiple "|" options, or one option with ','-separated glue words): glue-word count -# implies arity; the final argument is preceded by "of". Example: "sum | over | from,to" +# Functions and argument glue (the part after the name): +# - ":" separates the name/bracketing phrase from the argument-glue options that follow it. +# - Arity template (two or more ":" options, or one option with ','-separated glue words): the +# number of glue words implies the arity, and the final argument is preceded by "of". +# Example: "sum: over: from,to" # - 1 arg: "sum of x" # - 2 args: "sum over i of x" # - 3 args: "sum from i to n of x" -# If no option matches the argument count, separators fall back to "comma". -# - Binary separator (exactly one "|" option, no commas in it): after "of", that word joins the two args. -# Example: "quotient": "function=integer part | divided by" → "integer part of x divided by y" -# If there are not exactly two args, separators fall back to "comma" (no real n-ary use of these words). +# If no option matches the argument count, the arguments are separated with "comma". +# - Binary separator (exactly one ":" option, no commas in it): after "of", that word joins the two args. +# Example: "quotient": "function=integer part: divided by" → "integer part of x divided by y" +# If there are not exactly two args, the arguments fall back to "comma". +# - Paired "ratio-style" (" : | : | ..."): used when every "|"-separated +# piece is a single "name : glue" pair. Verbosity selects one pair, whose glue is the binary +# separator described above. Example: "ratio": "function=ratio : to | the ratio : to | the ratio : to" # -# BNF-like description: +# Conceptual grammar (with precedence): # -# IntentMappingsEntry ::= ":" +# IntentMappingsEntry ::= ":" # ":" is the YAML key/value separator # # ::= ( "||" )* -# | # -# ::= "=" +# ::= "=" # # ::= "prefix" | "infix" | "postfix" | "function" | "nofix" | "silent" # -# ::= -# | "|" ( "|" )* +# ::= | # -# ::= text -# # May use ":" to separate terse:medium:verbose forms. -# # May use ";" for bracketing (opening; main; closing). +# # Standard form: a name/bracketing part, then ":"-separated argument-glue options. +# ::= ( ":" )* # -# ::= text -# # One option, no commas: binary separator after "of" (e.g. "divided by"). -# # One option with "," or several "|" options: arity templates -# # (glue-word count = arg_count - 1; last arg preceded by "of"). -# # Unmatched arity (or binary glue with ≠2 args): fall back to "comma". +# ::= [ ";" ";" ] # 1 part: name; 3 parts: opening; main; closing # -# ::= (applies to all fixities) +# ::= [ "|" [ "|" ] ] # terse | medium | verbose +# +# ::= # a single glue word, or ","-separated arity words +# +# # Paired "ratio-style" form: recognized only when every "|" piece is a single "name : glue" pair. +# ::= ( "|" )+ +# +# ::= ":" # the glue contains no ":" +# +# ::= text +# +# Precedence depends on the form: +# - Standard: split on ":" first (name vs. argument-glue options), then split each piece on "|" +# for terse|medium|verbose, and split only the name part on ";" for opening; main; closing. +# - Paired: split on "|" first into "name : glue" pairs, then verbosity selects one pair. # # Example: -# "absolute-value": "function= ; absolute value: the absolute value: the absolute value; end absolute value" -# "sum": "function=sum | over | from,to" -# "quotient": "function=integer part | divided by" +# "absolute-value": "function= ; absolute value| the absolute value| the absolute value; end absolute value" +# "sum": "function=sum: over: from,to" +# "quotient": "function=integer part: divided by" +# "ratio": "function=ratio : to | the ratio : to | the ratio : to" # verbosity of name:glue pairs # - IntentMappings: { "binomial": "infix=binomial; choose; end binomial", @@ -79,9 +91,9 @@ "image":"function=image", #"fraction":"function=fraction; over; end fraction", # NOTE: Fails "mixed-fraction":"infix=and", # NOTE: in website says function, but follow infix speech pattern. - "quotient":"function=integer part | divided by", + "quotient":"function=integer part: divided by", "evaluated-at":"infix=evaluated at", - "remainder":"function=the remainder | divided by", + "remainder":"function=the remainder: divided by", "max":"function=max", "min":"function=min", @@ -89,14 +101,14 @@ "power":"infix=to the power", "root":"function=root", - "greatest-common-divisor": "function=gcd: the gcd: the greatest common divisor", - "least-common-multiple":"function=lcm: the lcm: the least common multiple", # In webpage typo "lest common" + "greatest-common-divisor": "function=gcd| the gcd| the greatest common divisor", + "least-common-multiple":"function=lcm| the lcm| the least common multiple", # In webpage typo "lest common" - "absolute-value": "function= ; absolute value: the absolute value: the absolute value; end absolute value", + "absolute-value": "function= ; absolute value| the absolute value| the absolute value; end absolute value", "complex-conjugate":"function=complex conjugate", "complex-arg":"function=arg", "real-part": "function=the real part", - "imaginary-part": "function=imaginary part: the imaginary part: the imaginary part", + "imaginary-part": "function=imaginary part| the imaginary part| the imaginary part", "polar-coordinate":"function=polar coordinate", "spherical-coordinate":"function=spherical coordinate", @@ -113,34 +125,34 @@ # "derivative":"function=the derivative; with respect to", # Property ??? # "partial-derivative":"function=partial", ## Note, included with infix, but separately under calculus tab has ??? for functionality - "limit": "prefix=limit as:the limit as", + "limit": "prefix=limit as|the limit as", "tends-to":"infix=tends to", "tends-to-from-above":"infix=tends to from above", "tends-to-from-below":"infix=tends to from below", ### Sets - "set": "function= ; set: the set", - "set-difference":"function=set difference | and || infix=minus", + "set": "function= ; set| the set", + "set-difference":"function=set difference: and || infix=minus", "complement":"function=complement", "empty-set":"nofix=empty set", "cardinality":"function=cardinality", # NOTE: does not have a defined speech template in website "list":"function=list", - "tuple": "function= ; tuple: the tuple", + "tuple": "function= ; tuple| the tuple", ### Sequence and Series - "sum": "function=sum | over | from,to", - "product": "function=product | over | from,to", + "sum": "function=sum: over: from,to", + "product": "function=product: over: from,to", ### Elementary classical functions - "sine":"function=sin: sine", - "cosine":"function=cos: cosine", - "tangent":"function=tan: tangent", - "secant":"function=seech: secant", - "cosecant":"function=co-seech: cosecant", - "cotangent":"function=co-tan: cotangent", + "sine":"function=sin | sine", + "cosine":"function=cos | cosine", + "tangent":"function=tan | tangent", + "secant":"function=seech | secant", + "cosecant":"function=co-seech | cosecant", + "cotangent":"function=co-tan | cotangent", "arcsine":"function=arcsine", "arccosine":"function=arccosine", @@ -164,7 +176,7 @@ "arc-hyperbolic-cotangent":"function=arc coth", "exponential":"function=exponential", - "natural-logarithm": "function=l n: natural log: natural log", + "natural-logarithm": "function=l n| natural log| natural log", "logarithm":"function=log", ##Check arity 2 @@ -175,7 +187,7 @@ "median":"function=median", "mode":"function=mode", - "conditional-probability":"function=probability | given", + "conditional-probability":"function=probability: given", ### Linear Algebra @@ -184,7 +196,7 @@ "determinant":"function=determinant", "adjugate":"function=adjugate", "magnitude":"function=magnitude", - "norm": "function=; norm: norm: norm; end norm", + "norm": "function=; norm| norm| norm; end norm", "span":"function=span", "unit-vector":"prefix=unit vector", @@ -195,12 +207,12 @@ ### Constants and Sets - "set-of-integers":"nofix=ℤ: set of all integers", - "set-of-reals":"nofix=ℝ: set of all real numbers", - "set-of-rationals":"nofix=ℚ: set of all rational numbers", - "set-of-natural-numbers":"nofix=ℕ: set of all natural numbers", - "set-of-complex-numbers":"nofix=ℂ: set of all complex numbers", - "set-of-primes":"nofix=ℙ: set of all prime numbers", + "set-of-integers":"nofix=ℤ| set of all integers", + "set-of-reals":"nofix=ℝ| set of all real numbers", + "set-of-rationals":"nofix=ℚ| set of all rational numbers", + "set-of-natural-numbers":"nofix=ℕ| set of all natural numbers", + "set-of-complex-numbers":"nofix=ℂ| set of all complex numbers", + "set-of-primes":"nofix=ℙ| set of all prime numbers", ### Geometry @@ -221,9 +233,9 @@ ### General Concepts "fenced-group":"function=fenced-group", # appears both under general concepts and grouping # NOTE: in site mentions "the pair x and y", due to being defined as function, needs the "of" keyword - "ordered-pair": "function=the pair | and", # Needs to be tested + "ordered-pair": "function=the pair: and", # Needs to be tested # Simple last arg: "x sub k". Complex: "… end sub" (terse/medium) / "end subscript" (verbose) via infix-intent. - "indexed-by": "infix= ; sub; end sub: end sub: end subscript", + "indexed-by": "infix= ; sub; end sub| end sub| end subscript", "highlight":"postfix=highlighted", "least-common-denominator":"function=least common denominator", @@ -245,8 +257,8 @@ ### Other ## Default fixity function "curl": "function=curl", - "divergence": "function=div:divergence", - "gradient": "function=del:gradient", + "divergence": "function=div|divergence", + "gradient": "function=del|gradient", "laplacian": "function=laplacian", ## Default fixity prefix @@ -271,7 +283,7 @@ "congruent": "infix=congruent to", "cartesian-product": "infix=cartesian product", "composed-with": "infix=composed with", - "cross-product": "infix=cross: cross product: cross product", + "cross-product": "infix=cross| cross product| cross product", "defined-as": "infix=defined as", "divided-by": "infix=divided by", "divides": "infix=divides", @@ -315,7 +327,7 @@ "precedes": "infix=precedes", "proportional": "infix=proportional to", "range-separator": "infix=through", - "ratio": "infix=ratio", + "ratio": "function=ratio : to | the ratio : to | the ratio : to", "similar": "infix=similar to", "subset": "infix=subset of", "subset-or-equal": "infix=subset or equal to", @@ -335,11 +347,11 @@ "percent": "postfix=percent", ## Default fixity nofix - "diameter":"nofix=d: diameter", - "distance":"nofix=d; D: distance", - "probability":"nofix=P: probability || function=probability", - "radius":"nofix=r: radius", - "volume":"nofix=V: volume || function=volume", + "diameter":"nofix=d| diameter", + "distance":"nofix=d; D| distance", + "probability":"nofix=P| probability || function=probability", + "radius":"nofix=r| radius", + "volume":"nofix=V| volume || function=volume", "exponential-e":"nofix=e", "imaginary-i":"nofix=i", "differential-d":"nofix=d", @@ -348,19 +360,19 @@ ## Other : Not tested, don't appear in https://w3c.github.io/mathml-docs/intent-core-concepts/ "modified-variable": "silent= ", - "say-super": "infix=super: superscript: superscript", # used with 'mo' for superscripts (e.g, "<") + "say-super": "infix=super| superscript| superscript", # used with 'mo' for superscripts (e.g, "<") "skip-super": "silent=", # used with 'mo' for superscripts (e.g, "*") # "large-op": "infix=over || other=from,to", - "lim-sup": "prefix=lim sup as: the limit superior as: the limit superior as", - "lim-inf": "prefix=lim inf as: the limit inferior as : the limit inferior as", - "logarithm-with-base": "prefix=log base: the log base: the log base", + "lim-sup": "prefix=lim sup as| the limit superior as| the limit superior as", + "lim-inf": "prefix=lim inf as| the limit inferior as| the limit inferior as", + "logarithm-with-base": "prefix=log base| the log base| the log base", # "pochhammer": "infix=permutations of", # arguments are in reverse order, so can't work here - "trace": "function= ; trace : trace: the trace; end trace", - "dimension": "function=; dimension : dimension: the dimension; end dimension", - "homomorphism": "function= ; homomorphism : homomorphism: the homomorphism; end homomorphism", - "kernel": "function= ; kernel : kernel: the kernel; end kernel", + "trace": "function= ; trace| trace| the trace; end trace", + "dimension": "function=; dimension| dimension| the dimension; end dimension", + "homomorphism": "function= ; homomorphism| homomorphism| the homomorphism; end homomorphism", + "kernel": "function= ; kernel| kernel| the kernel; end kernel", - "chemistry-concentration": "function= ; concentration: concentration of: the concentration of; end concentration", + "chemistry-concentration": "function= ; concentration| concentration of| the concentration of; end concentration", } # The connector word to say for functional 'IntentMappings' (in English, "of") @@ -370,7 +382,7 @@ # Names of functions that in terse mode don't say "of" (or it's equivalent in other languages) - TerseFunctionNames: { - "divergence", "del:gradient", "curl" + "divergence", "del|gradient", "curl" } - NavigationParts: { diff --git a/Rules/Languages/es/definitions.yaml b/Rules/Languages/es/definitions.yaml index 47267348e..795892f5c 100644 --- a/Rules/Languages/es/definitions.yaml +++ b/Rules/Languages/es/definitions.yaml @@ -7,45 +7,114 @@ # - name: [] "...", "..." "..." ] -# If an "intent" is used, the 'terse:medium:verbose' speech for the intent name is given here for a prefix||infix||postfix||function fixity -# If only one ":" is used, it the first part is used for 'terse' and the second part is used for 'medium' and 'verbose' -# If no ":"s are used, the same speech is used for all forms -# If bracketing words make sense, they are separated with ";"s -# Intent mappings must specify whether they are "prefix", "infix", "postfix", or "function" with an "=" sign -# If there are multiple fixities (e.g., see transpose), they are separated with "|| -# for readability, spaces can be used around any of the delimiter characters -# Note: if there are multiple fixities, the first one is used if the fixity is not given in the intent +# IntentMappings Syntax: +# +# This section defines how each "intent" is spoken for various grammatical forms (fixities such as "prefix", "infix", "postfix", and "function"), +# along with supporting different verbosity levels. +# The syntax is a little bit complicated, but allows a declarative syntax so you don't have to write as many rules. +# +# For each intent, you specify spoken forms for one or more fixities using the syntax below. +# +# - Each mapping has the form: +# "": "= || = || ...", +# Every alternative must name a fixity and use "="; the fixity requested when speaking selects one. +# +# - Separate multiple fixities with "||". Spaces are allowed around any delimiter for readability. +# - Within a speech string, "|" selects the verbosity form: +# - one "|" (two forms): the first is 'terse', the second is used for 'medium' and 'verbose' +# - two "|" (three forms): 'terse', 'medium', 'verbose', in that order +# - no "|": the same spoken form is used for all verbosity levels +# +# - Use semicolons ";" to divide opening; main; closing bracketing words within the name part, +# where such words make sense (a name with no ";" is just the main phrase). +# - If an intent has multiple fixities but a definition does not specify one, the first fixity listed is chosen by default. +# +# Functions and argument glue (the part after the name): +# - ":" separates the name/bracketing phrase from the argument-glue options that follow it. +# - Arity template (two or more ":" options, or one option with ','-separated glue words): the +# number of glue words implies the arity, and the final argument is preceded by "of". +# Example: "sum: over: from,to" +# - 1 arg: "sum of x" +# - 2 args: "sum over i of x" +# - 3 args: "sum from i to n of x" +# If no option matches the argument count, the arguments are separated with "comma". +# - Binary separator (exactly one ":" option, no commas in it): after "of", that word joins the two args. +# Example: "quotient": "function=integer part: divided by" → "integer part of x divided by y" +# If there are not exactly two args, the arguments fall back to "comma". +# - Paired "ratio-style" (" : | : | ..."): used when every "|"-separated +# piece is a single "name : glue" pair. Verbosity selects one pair, whose glue is the binary +# separator described above. Example: "ratio": "function=ratio : to | the ratio : to | the ratio : to" +# +# Conceptual grammar (with precedence): +# +# IntentMappingsEntry ::= ":" # ":" is the YAML key/value separator +# +# ::= ( "||" )* +# +# ::= "=" +# +# ::= "prefix" | "infix" | "postfix" | "function" | "nofix" | "silent" +# +# ::= | +# +# # Standard form: a name/bracketing part, then ":"-separated argument-glue options. +# ::= ( ":" )* +# +# ::= [ ";" ";" ] # 1 part: name; 3 parts: opening; main; closing +# +# ::= [ "|" [ "|" ] ] # terse | medium | verbose +# +# ::= # a single glue word, or ","-separated arity words +# +# # Paired "ratio-style" form: recognized only when every "|" piece is a single "name : glue" pair. +# ::= ( "|" )+ +# +# ::= ":" # the glue contains no ":" +# +# ::= text +# +# Precedence depends on the form: +# - Standard: split on ":" first (name vs. argument-glue options), then split each piece on "|" +# for terse|medium|verbose, and split only the name part on ";" for opening; main; closing. +# - Paired: split on "|" first into "name : glue" pairs, then verbosity selects one pair. +# +# Example: +# "absolute-value": "function= ; absolute value| the absolute value| the absolute value; end absolute value" +# "sum": "function=sum: over: from,to" +# "quotient": "function=integer part: divided by" +# "ratio": "function=ratio : to | the ratio : to | the ratio : to" # verbosity of name:glue pairs +# - IntentMappings: { "indexed-by": "infix= ; subíndice; final del subíndice", "modified-variable": "silent= ", "say-super": "infix=superíndice", # used with 'mo' for superscripts (e.g, "<") "skip-super": "silent=", # used with 'mo' for superscripts (e.g, "*") - "absolute-value": "function= ; valor absoluto: el valor absoluto de: el valor absoluto de; final del valor absoluto", + "absolute-value": "function= ; valor absoluto| el valor absoluto de| el valor absoluto de; final del valor absoluto", "binomial": "infix=binomial; elegir; end binomial", "limit": "prefix=límite cuando", - "lim-sup": "prefix=lim sup as: the limit superior as: the limit superior as", - "lim-inf": "prefix=lim inf as: the limit inferior as : the limit inferior as", - "logarithm-with-base": "prefix=log base: el log base: el log base", + "lim-sup": "prefix=lim sup as| the limit superior as| the limit superior as", + "lim-inf": "prefix=lim inf as| the limit inferior as | the limit inferior as", + "logarithm-with-base": "prefix=log base| el log base| el log base", "minus": "infix=menos || prefix=negativo", "plus": "infix=más || prefix=positivo", "transpose": "postfix=intercambiar || function=intercambiar", - "norm": "function=; regla: regla: la regla; fin de la regla", - "trace": "function=;traza : traza de: la traza de; fin de la traza", - "dimension": "function=; dimensión : dimensión de: la dimensión de; fin de la dimensión", - "homomorphism": "function= ; homomorfismo : homomorfismo de: el homomorfismo de; find de el homomorfismo", - "kernel": "function= ; núcleo : núcleo de: el núcleo de; fin de el núcleo", + "norm": "function=; regla| regla| la regla; fin de la regla", + "trace": "function=;traza | traza de| la traza de; fin de la traza", + "dimension": "function=; dimensión | dimensión de| la dimensión de; fin de la dimensión", + "homomorphism": "function= ; homomorfismo | homomorfismo de| el homomorfismo de; find de el homomorfismo", + "kernel": "function= ; núcleo | núcleo de| el núcleo de; fin de el núcleo", "vector": "function= ; vector || prefix=vector", - "cross-product": "infix=cross: cross product: cross product", - "dot-product": "infix=dot: dot product: dot:dot product", + "cross-product": "infix=cross| cross product| cross product", + "dot-product": "infix=dot| dot product| dot|dot product", - "divergence": "function= ; div: divergence: divergence; end divergence", + "divergence": "function= ; div| divergence| divergence; end divergence", "curl": "function= ; curl; end curl", - "gradient": "function= ; grad: gradient: gradient; end gradient", + "gradient": "function= ; grad| gradient| gradient; end gradient", "laplacian": "function=lahplahsian", # speech engines don't do a good job with "laplacian" - "chemistry-concentration": "function= ; concentración: concentración de: la concentración de; fin de la concentración", + "chemistry-concentration": "function= ; concentración| concentración de| la concentración de; fin de la concentración", } - NavigationParts: { diff --git a/Rules/Languages/fi/definitions.yaml b/Rules/Languages/fi/definitions.yaml index d68062a01..67abe6f23 100644 --- a/Rules/Languages/fi/definitions.yaml +++ b/Rules/Languages/fi/definitions.yaml @@ -6,25 +6,94 @@ # name: [ "...", "..." "..." ], -# If an "intent" is used, the 'terse:medium:verbose' speech for the intent name is given here for a prefix||infix||postfix||function fixity -# If only one ":" is used, it the first part is used for 'terse' and the second part is used for 'medium' and 'verbose' -# If no ":"s are used, the same speech is used for all forms -# If bracketing words make sense, they are separated with ";"s -# Intent mappings must specify whether they are "prefix", "infix", "postfix", or "function" with an "=" sign -# If there are multiple fixities (e.g., see transpose), they are separated with "|| -# for readability, spaces can be used around any of the delimiter characters -# Note: if there are multiple fixities, the first one is used if the fixity is not given in the intent +# IntentMappings Syntax: +# +# This section defines how each "intent" is spoken for various grammatical forms (fixities such as "prefix", "infix", "postfix", and "function"), +# along with supporting different verbosity levels. +# The syntax is a little bit complicated, but allows a declarative syntax so you don't have to write as many rules. +# +# For each intent, you specify spoken forms for one or more fixities using the syntax below. +# +# - Each mapping has the form: +# "": "= || = || ...", +# Every alternative must name a fixity and use "="; the fixity requested when speaking selects one. +# +# - Separate multiple fixities with "||". Spaces are allowed around any delimiter for readability. +# - Within a speech string, "|" selects the verbosity form: +# - one "|" (two forms): the first is 'terse', the second is used for 'medium' and 'verbose' +# - two "|" (three forms): 'terse', 'medium', 'verbose', in that order +# - no "|": the same spoken form is used for all verbosity levels +# +# - Use semicolons ";" to divide opening; main; closing bracketing words within the name part, +# where such words make sense (a name with no ";" is just the main phrase). +# - If an intent has multiple fixities but a definition does not specify one, the first fixity listed is chosen by default. +# +# Functions and argument glue (the part after the name): +# - ":" separates the name/bracketing phrase from the argument-glue options that follow it. +# - Arity template (two or more ":" options, or one option with ','-separated glue words): the +# number of glue words implies the arity, and the final argument is preceded by "of". +# Example: "sum: over: from,to" +# - 1 arg: "sum of x" +# - 2 args: "sum over i of x" +# - 3 args: "sum from i to n of x" +# If no option matches the argument count, the arguments are separated with "comma". +# - Binary separator (exactly one ":" option, no commas in it): after "of", that word joins the two args. +# Example: "quotient": "function=integer part: divided by" → "integer part of x divided by y" +# If there are not exactly two args, the arguments fall back to "comma". +# - Paired "ratio-style" (" : | : | ..."): used when every "|"-separated +# piece is a single "name : glue" pair. Verbosity selects one pair, whose glue is the binary +# separator described above. Example: "ratio": "function=ratio : to | the ratio : to | the ratio : to" +# +# Conceptual grammar (with precedence): +# +# IntentMappingsEntry ::= ":" # ":" is the YAML key/value separator +# +# ::= ( "||" )* +# +# ::= "=" +# +# ::= "prefix" | "infix" | "postfix" | "function" | "nofix" | "silent" +# +# ::= | +# +# # Standard form: a name/bracketing part, then ":"-separated argument-glue options. +# ::= ( ":" )* +# +# ::= [ ";" ";" ] # 1 part: name; 3 parts: opening; main; closing +# +# ::= [ "|" [ "|" ] ] # terse | medium | verbose +# +# ::= # a single glue word, or ","-separated arity words +# +# # Paired "ratio-style" form: recognized only when every "|" piece is a single "name : glue" pair. +# ::= ( "|" )+ +# +# ::= ":" # the glue contains no ":" +# +# ::= text +# +# Precedence depends on the form: +# - Standard: split on ":" first (name vs. argument-glue options), then split each piece on "|" +# for terse|medium|verbose, and split only the name part on ";" for opening; main; closing. +# - Paired: split on "|" first into "name : glue" pairs, then verbosity selects one pair. +# +# Example: +# "absolute-value": "function= ; absolute value| the absolute value| the absolute value; end absolute value" +# "sum": "function=sum: over: from,to" +# "quotient": "function=integer part: divided by" +# "ratio": "function=ratio : to | the ratio : to | the ratio : to" # verbosity of name:glue pairs +# - IntentMappings: { "indexed-by": "infix= ; ala; loppu ala", "modified-variable": "silent= ", - "say-super": "infix=ylä: yläindeksi: yläindeksi", # used with 'mo' for superscripts (e.g, "<") + "say-super": "infix=ylä| yläindeksi| yläindeksi", # used with 'mo' for superscripts (e.g, "<") "skip-super": "silent=", # used with 'mo' for superscripts (e.g, "*") "absolute-value": "function= ; itseisarvo; loppu itseisarvo", "binomial": "infix=binomi; yli; loppu binomi", - "limit": "prefix=raja-arvo: raja-arvo kun: raja-arvo kun", - "lim-sup": "prefix=supremum: supremum: supremum", - "lim-inf": "prefix=infimum: infimum : infimum", + "limit": "prefix=raja-arvo| raja-arvo kun| raja-arvo kun", + "lim-sup": "prefix=supremum| supremum| supremum", + "lim-inf": "prefix=infimum| infimum | infimum", "logarithm-with-base": "prefix=log kanta", "minus": "infix=miinus || prefix=negatiivinen", "plus": "infix=plus || prefix=positiivinen", @@ -36,12 +105,12 @@ "homomorphism": "function= ; homomorfismi; loppu homomorfismi", "kernel": "function= ; ydin; loppu ydin", "vector": "function= ; vektori || prefix=vektori", - "cross-product": "infix=risti: ristitulo: ristitulo", - "dot-product": "infix=piste: pistetulo: piste:pistetulo", + "cross-product": "infix=risti| ristitulo| ristitulo", + "dot-product": "infix=piste| pistetulo| piste|pistetulo", - "divergence": "function= ; div: divergenssi: divergenssi; loppu divergenssi", + "divergence": "function= ; div| divergenssi| divergenssi; loppu divergenssi", "curl": "function= ; roottori; loppu roottori", - "gradient": "function= ; grad: gradientti: gradientti; loppu gradientti", + "gradient": "function= ; grad| gradientti| gradientti; loppu gradientti", "laplacian": "function=laplasen", # speech engines don't do a good job with "laplacian" } diff --git a/Rules/Languages/fr/definitions.yaml b/Rules/Languages/fr/definitions.yaml index c2e822d5b..9e49cc01f 100644 --- a/Rules/Languages/fr/definitions.yaml +++ b/Rules/Languages/fr/definitions.yaml @@ -4,52 +4,120 @@ # French overrides for language-dependent speech definitions. Anything omitted # here continues to fall back to the shared English defaults. -# If an "intent" is used, the 'terse:medium:verbose' speech for the intent name is given here for a prefix||infix||postfix||function fixity -# If only one ":" is used, the first part is used for 'terse' and the second part is used for 'medium' and 'verbose' -# If no ":"s are used, the same speech is used for all forms -# If bracketing words make sense, they are separated with ";"s -# Intent mappings must specify whether they are "prefix", "infix", "postfix", or "function" with an "=" sign -# If there are multiple fixities (e.g., see transpose), they are separated with "||" -# for readability, spaces can be used around any of the delimiter characters -# Note: if there are multiple fixities, the first one is used if the fixity is not given in the intent - +# IntentMappings Syntax: +# +# This section defines how each "intent" is spoken for various grammatical forms (fixities such as "prefix", "infix", "postfix", and "function"), +# along with supporting different verbosity levels. +# The syntax is a little bit complicated, but allows a declarative syntax so you don't have to write as many rules. +# +# For each intent, you specify spoken forms for one or more fixities using the syntax below. +# +# - Each mapping has the form: +# "": "= || = || ...", +# Every alternative must name a fixity and use "="; the fixity requested when speaking selects one. +# +# - Separate multiple fixities with "||". Spaces are allowed around any delimiter for readability. +# - Within a speech string, "|" selects the verbosity form: +# - one "|" (two forms): the first is 'terse', the second is used for 'medium' and 'verbose' +# - two "|" (three forms): 'terse', 'medium', 'verbose', in that order +# - no "|": the same spoken form is used for all verbosity levels +# +# - Use semicolons ";" to divide opening; main; closing bracketing words within the name part, +# where such words make sense (a name with no ";" is just the main phrase). +# - If an intent has multiple fixities but a definition does not specify one, the first fixity listed is chosen by default. +# +# Functions and argument glue (the part after the name): +# - ":" separates the name/bracketing phrase from the argument-glue options that follow it. +# - Arity template (two or more ":" options, or one option with ','-separated glue words): the +# number of glue words implies the arity, and the final argument is preceded by "of". +# Example: "sum: over: from,to" +# - 1 arg: "sum of x" +# - 2 args: "sum over i of x" +# - 3 args: "sum from i to n of x" +# If no option matches the argument count, the arguments are separated with "comma". +# - Binary separator (exactly one ":" option, no commas in it): after "of", that word joins the two args. +# Example: "quotient": "function=integer part: divided by" → "integer part of x divided by y" +# If there are not exactly two args, the arguments fall back to "comma". +# - Paired "ratio-style" (" : | : | ..."): used when every "|"-separated +# piece is a single "name : glue" pair. Verbosity selects one pair, whose glue is the binary +# separator described above. Example: "ratio": "function=ratio : to | the ratio : to | the ratio : to" +# +# Conceptual grammar (with precedence): +# +# IntentMappingsEntry ::= ":" # ":" is the YAML key/value separator +# +# ::= ( "||" )* +# +# ::= "=" +# +# ::= "prefix" | "infix" | "postfix" | "function" | "nofix" | "silent" +# +# ::= | +# +# # Standard form: a name/bracketing part, then ":"-separated argument-glue options. +# ::= ( ":" )* +# +# ::= [ ";" ";" ] # 1 part: name; 3 parts: opening; main; closing +# +# ::= [ "|" [ "|" ] ] # terse | medium | verbose +# +# ::= # a single glue word, or ","-separated arity words +# +# # Paired "ratio-style" form: recognized only when every "|" piece is a single "name : glue" pair. +# ::= ( "|" )+ +# +# ::= ":" # the glue contains no ":" +# +# ::= text +# +# Precedence depends on the form: +# - Standard: split on ":" first (name vs. argument-glue options), then split each piece on "|" +# for terse|medium|verbose, and split only the name part on ";" for opening; main; closing. +# - Paired: split on "|" first into "name : glue" pairs, then verbosity selects one pair. +# +# Example: +# "absolute-value": "function= ; absolute value| the absolute value| the absolute value; end absolute value" +# "sum": "function=sum: over: from,to" +# "quotient": "function=integer part: divided by" +# "ratio": "function=ratio : to | the ratio : to | the ratio : to" # verbosity of name:glue pairs +# - IntentMappings: { - "indexed-by": "infix= ; indice; fin d'indice: fin d'indice: fin d'indice", + "indexed-by": "infix= ; indice; fin d'indice| fin d'indice| fin d'indice", "modified-variable": "silent= ", - "say-super": "infix=super: exposant: exposant", + "say-super": "infix=super| exposant| exposant", "skip-super": "silent=", - "absolute-value": "function= ; valeur absolue: la valeur absolue: la valeur absolue; fin de valeur absolue", + "absolute-value": "function= ; valeur absolue| la valeur absolue| la valeur absolue; fin de valeur absolue", "binomial": "infix=binôme; parmi; fin du binôme", "dimension-product": "infix=par", - "greatest-common-divisor": "function=pgcd: le pgcd: le plus grand commun diviseur", - "imaginary-part": "function=partie imaginaire: la partie imaginaire: la partie imaginaire", - "least-common-multiple": "function=ppcm: le ppcm: le plus petit commun multiple", - "limit": "prefix=limite quand: la limite quand: la limite quand", - "lim-sup": "prefix=lim sup quand: la limite supérieure quand: la limite supérieure quand", - "lim-inf": "prefix=lim inf quand: la limite inférieure quand: la limite inférieure quand", - "logarithm-with-base": "prefix=log en base: le log en base: le log en base", - "natural-logarithm": "function=l n: logarithme naturel: logarithme naturel", + "greatest-common-divisor": "function=pgcd| le pgcd| le plus grand commun diviseur", + "imaginary-part": "function=partie imaginaire| la partie imaginaire| la partie imaginaire", + "least-common-multiple": "function=ppcm| le ppcm| le plus petit commun multiple", + "limit": "prefix=limite quand| la limite quand| la limite quand", + "lim-sup": "prefix=lim sup quand| la limite supérieure quand| la limite supérieure quand", + "lim-inf": "prefix=lim inf quand| la limite inférieure quand| la limite inférieure quand", + "logarithm-with-base": "prefix=log en base| le log en base| le log en base", + "natural-logarithm": "function=l n| logarithme naturel| logarithme naturel", "minus": "infix=moins || prefix=moins", "plus": "infix=plus || prefix=positif", "real-part": "function=la partie réelle", "transpose": "postfix=transposée || function=transposée", - "norm": "function= ; norme: norme: la norme de; fin de norme", - "trace": "function= ; trace : trace: la trace de; fin de trace", - "dimension": "function= ; dimension : dimension: la dimension de; fin de dimension", - "homomorphism": "function= ; homomorphisme : homomorphisme: l'homomorphisme de; fin de l'homomorphisme", - "kernel": "function= ; noyau : noyau: le noyau de; fin du noyau", + "norm": "function= ; norme| norme| la norme de; fin de norme", + "trace": "function= ; trace | trace| la trace de; fin de trace", + "dimension": "function= ; dimension | dimension| la dimension de; fin de dimension", + "homomorphism": "function= ; homomorphisme | homomorphisme| l'homomorphisme de; fin de l'homomorphisme", + "kernel": "function= ; noyau | noyau| le noyau de; fin du noyau", "vector": "function= ; vecteur || prefix=vecteur", - "cross-product": "infix=croix: produit vectoriel: produit vectoriel", - "dot-product": "infix=point: produit scalaire: point: produit scalaire", + "cross-product": "infix=croix| produit vectoriel| produit vectoriel", + "dot-product": "infix=point| produit scalaire| point| produit scalaire", - "divergence": "function= ; div: divergence: divergence; fin de divergence", - "curl": "function= ; rotationnel: rotationnel: rotationnel; fin du rotationnel", - "gradient": "function= ; grad: gradient: gradient; fin de gradient", + "divergence": "function= ; div| divergence| divergence; fin de divergence", + "curl": "function= ; rotationnel| rotationnel| rotationnel; fin du rotationnel", + "gradient": "function= ; grad| gradient| gradient; fin de gradient", "laplacian": "function=laplacien", - "chemistry-concentration": "function= ; concentration: concentration de: la concentration de; fin de concentration", + "chemistry-concentration": "function= ; concentration| concentration de| la concentration de; fin de concentration", } # Names of functions that in terse mode don't say "of" (or it's equivalent in other languages) diff --git a/Rules/Languages/hu/definitions.yaml b/Rules/Languages/hu/definitions.yaml index d66738ec4..f070f72fc 100644 --- a/Rules/Languages/hu/definitions.yaml +++ b/Rules/Languages/hu/definitions.yaml @@ -11,67 +11,79 @@ # # - Each mapping has the form: # "": "= || = || ...", -# or just -# "": "", -# where is used for all forms if fixity and '=' are omitted. +# Every alternative must name a fixity and use "="; the fixity requested when speaking selects one. # -# - If an intent has multiple fixities, separate them with "||". Spaces are allowed around delimiters for readability. -# - If only one ":" is present in **, it provides the 'terse' form, and the following string is used for both 'medium' and 'verbose'. -# - If more than one ":" is present, the string is split into 'terse', 'medium', and 'verbose' forms, in that order (each separated by ":"). -# - If no ":" is present, the same spoken form is used for all styles. +# - Separate multiple fixities with "||". Spaces are allowed around any delimiter for readability. +# - Within a speech string, "|" selects the verbosity form: +# - one "|" (two forms): the first is 'terse', the second is used for 'medium' and 'verbose' +# - two "|" (three forms): 'terse', 'medium', 'verbose', in that order +# - no "|": the same spoken form is used for all verbosity levels # -# - Use semicolons ";" to divide opening, main, and closing bracketing words within a speech string, where such words make sense. +# - Use semicolons ";" to divide opening; main; closing bracketing words within the name part, +# where such words make sense (a name with no ";" is just the main phrase). # - If an intent has multiple fixities but a definition does not specify one, the first fixity listed is chosen by default. # -# Functions and argument glue: -# - The "|" character delimits options describing how to glue arguments together when speaking function arguments. -# - Arity templates (multiple "|" options, or one option with ','-separated glue words): glue-word count -# implies arity; the final argument is preceded by "of". Example: "sum | over | from,to" +# Functions and argument glue (the part after the name): +# - ":" separates the name/bracketing phrase from the argument-glue options that follow it. +# - Arity template (two or more ":" options, or one option with ','-separated glue words): the +# number of glue words implies the arity, and the final argument is preceded by "of". +# Example: "sum: over: from,to" # - 1 arg: "sum of x" # - 2 args: "sum over i of x" # - 3 args: "sum from i to n of x" -# If no option matches the argument count, separators fall back to "comma". -# - Binary separator (exactly one "|" option, no commas in it): after "of", that word joins the two args. -# Example: "quotient": "function=integer part | divided by" → "integer part of x divided by y" -# If there are not exactly two args, separators fall back to "comma" (no real n-ary use of these words). +# If no option matches the argument count, the arguments are separated with "comma". +# - Binary separator (exactly one ":" option, no commas in it): after "of", that word joins the two args. +# Example: "quotient": "function=integer part: divided by" → "integer part of x divided by y" +# If there are not exactly two args, the arguments fall back to "comma". +# - Paired "ratio-style" (" : | : | ..."): used when every "|"-separated +# piece is a single "name : glue" pair. Verbosity selects one pair, whose glue is the binary +# separator described above. Example: "ratio": "function=ratio : to | the ratio : to | the ratio : to" # -# BNF-like description: +# Conceptual grammar (with precedence): # -# IntentMappingsEntry ::= ":" +# IntentMappingsEntry ::= ":" # ":" is the YAML key/value separator # # ::= ( "||" )* -# | # -# ::= "=" +# ::= "=" # # ::= "prefix" | "infix" | "postfix" | "function" | "nofix" | "silent" # -# ::= -# | "|" ( "|" )* +# ::= | # -# ::= text -# # May use ":" to separate terse:medium:verbose forms. -# # May use ";" for bracketing (opening; main; closing). +# # Standard form: a name/bracketing part, then ":"-separated argument-glue options. +# ::= ( ":" )* # -# ::= text -# # One option, no commas: binary separator after "of" (e.g. "divided by"). -# # One option with "," or several "|" options: arity templates -# # (glue-word count = arg_count - 1; last arg preceded by "of"). -# # Unmatched arity (or binary glue with ≠2 args): fall back to "comma". +# ::= [ ";" ";" ] # 1 part: name; 3 parts: opening; main; closing # -# ::= (applies to all fixities) +# ::= [ "|" [ "|" ] ] # terse | medium | verbose +# +# ::= # a single glue word, or ","-separated arity words +# +# # Paired "ratio-style" form: recognized only when every "|" piece is a single "name : glue" pair. +# ::= ( "|" )+ +# +# ::= ":" # the glue contains no ":" +# +# ::= text +# +# Precedence depends on the form: +# - Standard: split on ":" first (name vs. argument-glue options), then split each piece on "|" +# for terse|medium|verbose, and split only the name part on ";" for opening; main; closing. +# - Paired: split on "|" first into "name : glue" pairs, then verbosity selects one pair. # # Example: -# "absolute-value": "function= ; absolute value: the absolute value: the absolute value; end absolute value" -# "sum": "function=sum | over | from,to" -# "quotient": "function=integer part | divided by" +# "absolute-value": "function= ; absolute value| the absolute value| the absolute value; end absolute value" +# "sum": "function=sum: over: from,to" +# "quotient": "function=integer part: divided by" +# "ratio": "function=ratio : to | the ratio : to | the ratio : to" # verbosity of name:glue pairs # - IntentMappings: { - "indexed-by": "infix= alsó index kezdete; alsó index; alsó index vége: alsó index vége: alsó index vége", - "say-super": "infix=felső index: felső index: felső index", # used with 'mo' for superscripts (e.g, "<") + "indexed-by": "infix= alsó index kezdete; alsó index; alsó index vége| alsó index vége| alsó index vége", + "say-super": "infix=felső index| felső index| felső index", # used with 'mo' for superscripts (e.g, "<") "skip-super": "silent=", # used with 'mo' for superscripts (e.g, "*") - "absolute-value": "function= ; abszolút érték: az abszolút érték: az abszolút érték; abszolút érték vége", + "absolute-value": "function= ; abszolút érték| az abszolút érték| az abszolút érték; abszolút érték vége", "binomial": "infix=binomiális kezdete; a; binomiális vége", "dimension-product": "infix=by", ### Functions and Inverses @@ -87,15 +99,15 @@ #"fraction":"function=fraction; over; end fraction", # NOTE: Fails "mixed-fraction":"infix=és", # NOTE: in website says function, but follow infix speech pattern. "greatest-common-divisor": "function=a legnagyobb közös osztó", - "quotient":"function=egész rész | osztva", # NOTE: Logic somewhere here failing, becomes "divided by of x comma, y" instead of "integer part of x divided by y" + "quotient":"function=egész rész : osztva", # NOTE: Logic somewhere here failing, becomes "divided by of x comma, y" instead of "integer part of x divided by y" "evaluated-at":"infix=értékelve || postfix=értékként", - "remainder":"function=a maradék | osztva", + "remainder":"function=a maradék : osztva", "max":"function=max", "min":"function=min", "power":"infix=a hatványra", "root":"function=root", - "imaginary-part": "function=a képzeletbeli rész: a képzeletbeli rész: a képzeletbeli rész", - "least-common-multiple": "function=lcm: a legkisebb közös többszörös: a legkisebb közös többszörös", + "imaginary-part": "function=a képzeletbeli rész| a képzeletbeli rész| a képzeletbeli rész", + "least-common-multiple": "function=lcm| a legkisebb közös többszörös| a legkisebb közös többszörös", "complex-conjugate":"function=Komplex konjugált", "complex-arg":"function=argumentum", "polar-coordinate":"function=poláris koordináta", @@ -107,47 +119,47 @@ "round":"function=kerekített érték", "fractional-part":"function=tört rész", # "large-op": "infix=over || other=from,to", - "limit": "prefix=határérték: határérték: határérték", - "lim-sup": "prefix=lim-sup: a határérték, amely nagyobb, mint: a határérték, amely nagyobb, mint", - "lim-inf": "prefix=lim inf mint: az alsó határérték, mint: a határérték alsó határértéke, mint", - "logarithm-with-base": "prefix=alap logaritmus: alap logaritmus: alap logaritmus", + "limit": "prefix=határérték| határérték| határérték", + "lim-sup": "prefix=lim-sup| a határérték, amely nagyobb, mint| a határérték, amely nagyobb, mint", + "lim-inf": "prefix=lim inf mint| az alsó határérték, mint| a határérték alsó határértéke, mint", + "logarithm-with-base": "prefix=alap logaritmus| alap logaritmus| alap logaritmus", # "pochhammer": "infix=permutations of", # arguments are in reverse order, so can't work here "real-part": "function=az igazi rész", - "trace": "function= ; nyom : nyom: a nyom; nyom vége", - "dimension": "function=; dimenzió : dimenzió: a dimenzió; dimenzió vége", - "homomorphism": "function= ; homomorfizmus : homomorfizmus: a homomorfizmus; homomorfizmus vége", - "kernel": "function= ; kernel : kernel: a kernel; kernel vége", + "trace": "function= ; nyom | nyom| a nyom; nyom vége", + "dimension": "function=; dimenzió | dimenzió| a dimenzió; dimenzió vége", + "homomorphism": "function= ; homomorfizmus | homomorfizmus| a homomorfizmus; homomorfizmus vége", + "kernel": "function= ; kernel | kernel| a kernel; kernel vége", "dot-product": "infix=skaláris szorzat", #"divergence": "function= ; dihv: divergencia: divergencia; divergencia vége", #"laplacian": "function=laplaciáns", # speech engines don't do a good job with "laplacian" - "chemistry-concentration": "function= ; koncentráció: koncentrációja ennek: a koncentrációja; koncentráció vége", + "chemistry-concentration": "function= ; koncentráció| koncentrációja ennek| a koncentrációja; koncentráció vége", ### Calculus - "definite-integral":"function=integrál felett || function=integrál innen:; ide:", # Property ??? - "derivative":"function=a deriváltja; mely erre vonatkozik:", # Property ??? + "definite-integral":"function=integrál felett || function=integrál innen|; ide|", # Property ??? + "derivative":"function=a deriváltja; mely erre vonatkozik|", # Property ??? "tends-to":"infix=ehhez tart", "tends-to-from-above":"infix=általában alulról indul", "tends-to-from-below":"infix=alulról indul", ### Sets - "set": "function= ; halmaz: a halmaz", - "set-difference":"function=különbséghalmaz | és || infix=mínusz", + "set": "function= ; halmaz| a halmaz", + "set-difference":"function=különbséghalmaz : és || infix=mínusz", "complement":"function=komplemens", "empty-set":"nofix=üres halmaz", "cardinality":"function=számosság", # NOTE: does not have a defined speech template in website "list":"function=lista", - "tuple": "function= ; tuple: a tuple", + "tuple": "function= ; tuple| a tuple", ### Sequence and Series "sum": "function=összeg", "product":"function=szorzat", ### Elementary classical functions - "sine":"function=szinusz: szinusz", - "cosine":"function=koszinusz: koszinusz", - "tangent":"function=tangens: tangens", - "secant":"function=szekáns: szekáns", - "cosecant":"function=koszekáns: koszekáns", - "cotangent":"function=kotangens: kotangens", + "sine":"function=szinusz| szinusz", + "cosine":"function=koszinusz| koszinusz", + "tangent":"function=tangens| tangens", + "secant":"function=szekáns| szekáns", + "cosecant":"function=koszekáns| koszekáns", + "cotangent":"function=kotangens| kotangens", "arcsine":"function=arkusz szinusz", "arccosine":"function=arkusz koszinusz", "arctangent":"function=arkusz tangens", @@ -167,7 +179,7 @@ "arc-hyperbolic-cosecant":"function=arkusz hiperbolikus koszekáns", "arc-hyperbolic-cotangent":"function=arkusz hiperbolikus kotangens", "exponential":"function=exponenciális", - "natural-logarithm": "function=l n: természetes alapú logaritmus: természetes alapú logaritmus", + "natural-logarithm": "function=l n| természetes alapú logaritmus| természetes alapú logaritmus", "logarithm":"function=logaritmus", ##Check arity 2 ### Statistics and Probability "mean":"function=jelentése", @@ -184,7 +196,7 @@ "determinant":"function=determináns", "adjugate":"function=adjugált", "magnitude":"function=nagyságrend", - "norm": "function=; normalizálás: normalizálás: normalizálás; normalizálás vége", + "norm": "function=; normalizálás| normalizálás| normalizálás; normalizálás vége", "span":"function=fesztávolság", "unit-vector":"prefix=egységvektor", @@ -195,12 +207,12 @@ ### Constants and Sets - "set-of-integers":"nofix=ℤ: az összes egész szám halmaza", - "set-of-reals":"nofix=valós számok halmaza: az összes valós szám halmaza", - "set-of-rationals":"nofix=ℚ: az összes racionális szám halmaza", - "set-of-natural-numbers":"nofix=ℕ: az összes természetes szám halmaza", - "set-of-complex-numbers":"nofix=ℂ: az összes komplex szám halmaza", - "set-of-primes":"nofix=ℙ: az összes prímszám halmaza", + "set-of-integers":"nofix=ℤ| az összes egész szám halmaza", + "set-of-reals":"nofix=valós számok halmaza| az összes valós szám halmaza", + "set-of-rationals":"nofix=ℚ| az összes racionális szám halmaza", + "set-of-natural-numbers":"nofix=ℕ| az összes természetes szám halmaza", + "set-of-complex-numbers":"nofix=ℂ| az összes komplex szám halmaza", + "set-of-primes":"nofix=ℙ| az összes prímszám halmaza", ### Geometry @@ -221,7 +233,7 @@ ### General Concepts "fenced-group":"function=bekerített csoport", # appears both under general concepts and grouping # NOTE: in site mentions "the pair x and y", due to being defined as function, needs the "of" keyword - "ordered-pair": "function=a pár | és", # Needs to be tested, test converts "and" to "comma," + "ordered-pair": "function=a pár : és", # Needs to be tested, test converts "and" to "comma," "highlight":"postfix=kiemelt", "least-common-denominator":"function=legkisebb közös nevező", "rate":"infix=per", @@ -236,8 +248,8 @@ ### Other ## Default fixity function "curl": "function=rotáció", - "divergence": "function=eltérés:eltérés", - "gradient": "function=gradiens:gradiens", + "divergence": "function=eltérés|eltérés", + "gradient": "function=gradiens|gradiens", "laplacian": "function=laplaciánus", ## Default fixity prefix @@ -262,7 +274,7 @@ "congruent": "infix=egybeesik", "cartesian-product": "infix=derékszögű szorzat", "composed-with": "infix=komponálva", - "cross-product": "infix=kereszt szorzata: kereszt szorzata: kereszt szorzata", + "cross-product": "infix=kereszt szorzata| kereszt szorzata| kereszt szorzata", "defined-as": "infix=definiálva", "divided-by": "infix=osztva", "divides": "infix=osztja", @@ -325,11 +337,11 @@ "percent": "postfix=százalék", ## Default fixity nofix - "diameter":"nofix=átmérő: átmérő", - "distance":"nofix=távolság; távolság: távolság", - "probability":"nofix=P: valószínűség || function=valószínűség", - "radius":"nofix=r: sugár", - "volume":"nofix=hangerő: hangerő || function=hangerő", + "diameter":"nofix=átmérő| átmérő", + "distance":"nofix=távolság; távolság| távolság", + "probability":"nofix=P| valószínűség || function=valószínűség", + "radius":"nofix=r| sugár", + "volume":"nofix=hangerő| hangerő || function=hangerő", "exponential-e":"nofix=e", "imaginary-i":"nofix=képzeletbeli én", "differential-d":"nofix=d", diff --git a/Rules/Languages/id/definitions.yaml b/Rules/Languages/id/definitions.yaml index 6f063cfd8..2051a5488 100644 --- a/Rules/Languages/id/definitions.yaml +++ b/Rules/Languages/id/definitions.yaml @@ -2,39 +2,108 @@ - include: "../../definitions.yaml" -# If an "intent" is used, the 'terse:medium:verbose' speech for the intent name is given here for a prefix||infix||postfix||function fixity -# If only one ":" is used, it the first part is used for 'terse' and the second part is used for 'medium' and 'verbose' -# If no ":"s are used, the same speech is used for all forms -# If bracketing words make sense, they are separated with ";"s -# Intent mappings must specify whether they are "prefix", "infix", "postfix", or "function" with an "=" sign -# If there are multiple fixities (e.g., see transpose), they are separated with "|| -# for readability, spaces can be used around any of the delimiter characters -# Note: if there are multiple fixities, the first one is used if the fixity is not given in the intent +# IntentMappings Syntax: +# +# This section defines how each "intent" is spoken for various grammatical forms (fixities such as "prefix", "infix", "postfix", and "function"), +# along with supporting different verbosity levels. +# The syntax is a little bit complicated, but allows a declarative syntax so you don't have to write as many rules. +# +# For each intent, you specify spoken forms for one or more fixities using the syntax below. +# +# - Each mapping has the form: +# "": "= || = || ...", +# Every alternative must name a fixity and use "="; the fixity requested when speaking selects one. +# +# - Separate multiple fixities with "||". Spaces are allowed around any delimiter for readability. +# - Within a speech string, "|" selects the verbosity form: +# - one "|" (two forms): the first is 'terse', the second is used for 'medium' and 'verbose' +# - two "|" (three forms): 'terse', 'medium', 'verbose', in that order +# - no "|": the same spoken form is used for all verbosity levels +# +# - Use semicolons ";" to divide opening; main; closing bracketing words within the name part, +# where such words make sense (a name with no ";" is just the main phrase). +# - If an intent has multiple fixities but a definition does not specify one, the first fixity listed is chosen by default. +# +# Functions and argument glue (the part after the name): +# - ":" separates the name/bracketing phrase from the argument-glue options that follow it. +# - Arity template (two or more ":" options, or one option with ','-separated glue words): the +# number of glue words implies the arity, and the final argument is preceded by "of". +# Example: "sum: over: from,to" +# - 1 arg: "sum of x" +# - 2 args: "sum over i of x" +# - 3 args: "sum from i to n of x" +# If no option matches the argument count, the arguments are separated with "comma". +# - Binary separator (exactly one ":" option, no commas in it): after "of", that word joins the two args. +# Example: "quotient": "function=integer part: divided by" → "integer part of x divided by y" +# If there are not exactly two args, the arguments fall back to "comma". +# - Paired "ratio-style" (" : | : | ..."): used when every "|"-separated +# piece is a single "name : glue" pair. Verbosity selects one pair, whose glue is the binary +# separator described above. Example: "ratio": "function=ratio : to | the ratio : to | the ratio : to" +# +# Conceptual grammar (with precedence): +# +# IntentMappingsEntry ::= ":" # ":" is the YAML key/value separator +# +# ::= ( "||" )* +# +# ::= "=" +# +# ::= "prefix" | "infix" | "postfix" | "function" | "nofix" | "silent" +# +# ::= | +# +# # Standard form: a name/bracketing part, then ":"-separated argument-glue options. +# ::= ( ":" )* +# +# ::= [ ";" ";" ] # 1 part: name; 3 parts: opening; main; closing +# +# ::= [ "|" [ "|" ] ] # terse | medium | verbose +# +# ::= # a single glue word, or ","-separated arity words +# +# # Paired "ratio-style" form: recognized only when every "|" piece is a single "name : glue" pair. +# ::= ( "|" )+ +# +# ::= ":" # the glue contains no ":" +# +# ::= text +# +# Precedence depends on the form: +# - Standard: split on ":" first (name vs. argument-glue options), then split each piece on "|" +# for terse|medium|verbose, and split only the name part on ";" for opening; main; closing. +# - Paired: split on "|" first into "name : glue" pairs, then verbosity selects one pair. +# +# Example: +# "absolute-value": "function= ; absolute value| the absolute value| the absolute value; end absolute value" +# "sum": "function=sum: over: from,to" +# "quotient": "function=integer part: divided by" +# "ratio": "function=ratio : to | the ratio : to | the ratio : to" # verbosity of name:glue pairs +# - IntentMappings: { "indexed-by": "infix= ; indeks; akhir indeks", - "absolute-value": "function= ; nilai mutlak: nilai mutlak dari: nilai mutlak dari; akhir nilai mutlak", + "absolute-value": "function= ; nilai mutlak| nilai mutlak dari| nilai mutlak dari; akhir nilai mutlak", "binomial": "infix=binomial; memilih; end binomial", "dimension-product": "infix=kali", - "limit": "prefix=raja-arvo: raja-arvo kun: raja-arvo kun", - "lim-sup": "prefix=lim sup as: the limit superior as: the limit superior as", - "lim-inf": "prefix=lim inf as: the limit inferior as : the limit inferior as", + "limit": "prefix=raja-arvo| raja-arvo kun| raja-arvo kun", + "lim-sup": "prefix=lim sup as| the limit superior as| the limit superior as", + "lim-inf": "prefix=lim inf as| the limit inferior as | the limit inferior as", "minus": "infix=kurang || prefix=negatif", "plus": "infix=tambah || prefix=positif", "transpose": "postfix=transpose || function=transpose", - "norm": "function=; norma: norma: norma dari; end norm", - "trace": "function=;jejak : jejak: jejak dari; end trace", - "dimension": "function=; dimensi : dimensi: dimensi dari; end dimension", - "homomorphism": "function= ; homomorfisme : homomorfisme: homomorfisme dari; end homomorphism", - "kernel": "function= ; kernel : kernel: kernel dari; end kernel", + "norm": "function=; norma| norma| norma dari; end norm", + "trace": "function=;jejak | jejak| jejak dari; end trace", + "dimension": "function=; dimensi | dimensi| dimensi dari; end dimension", + "homomorphism": "function= ; homomorfisme | homomorfisme| homomorfisme dari; end homomorphism", + "kernel": "function= ; kernel | kernel| kernel dari; end kernel", "vector": "function= ; vector || prefix=vector", - "cross-product": "infix=cross: cross product: cross product", - "dot-product": "infix=dot: dot product: dot:dot product", + "cross-product": "infix=cross| cross product| cross product", + "dot-product": "infix=dot| dot product| dot|dot product", - "divergence": "function= ; div: divergence: divergence; end divergence", + "divergence": "function= ; div| divergence| divergence; end divergence", "curl": "function= ; curl; end curl", - "gradient": "function= ; grad: gradient: gradient; end gradient", + "gradient": "function= ; grad| gradient| gradient; end gradient", "laplacian": "function=lahplahsian", # speech engines don't do a good job with "laplacian" } diff --git a/Rules/Languages/nb/definitions.yaml b/Rules/Languages/nb/definitions.yaml index 08a5520f4..e0bc7dda4 100644 --- a/Rules/Languages/nb/definitions.yaml +++ b/Rules/Languages/nb/definitions.yaml @@ -4,18 +4,87 @@ # Each definition in this file is of the form # name: [ "...", "..." "..." ], -# If an "intent" is used, the 'terse:medium:verbose' speech for the intent name is given here for a prefix||infix||postfix||function fixity -# If only one ":" is used, the first part is used for 'terse' and the second part is used for 'medium' and 'verbose' -# If no ":"s are used, the same speech is used for all forms -# If bracketing words make sense, they are separated with ";"s -# Intent mappings must specify whether they are "prefix", "infix", "postfix", or "function" with an "=" sign -# If there are multiple fixities (e.g., see transpose), they are separated with "||" -# for readability, spaces can be used around any of the delimiter characters -# Note: if there are multiple fixities, the first one is used if the fixity is not given in the intent +# IntentMappings Syntax: +# +# This section defines how each "intent" is spoken for various grammatical forms (fixities such as "prefix", "infix", "postfix", and "function"), +# along with supporting different verbosity levels. +# The syntax is a little bit complicated, but allows a declarative syntax so you don't have to write as many rules. +# +# For each intent, you specify spoken forms for one or more fixities using the syntax below. +# +# - Each mapping has the form: +# "": "= || = || ...", +# Every alternative must name a fixity and use "="; the fixity requested when speaking selects one. +# +# - Separate multiple fixities with "||". Spaces are allowed around any delimiter for readability. +# - Within a speech string, "|" selects the verbosity form: +# - one "|" (two forms): the first is 'terse', the second is used for 'medium' and 'verbose' +# - two "|" (three forms): 'terse', 'medium', 'verbose', in that order +# - no "|": the same spoken form is used for all verbosity levels +# +# - Use semicolons ";" to divide opening; main; closing bracketing words within the name part, +# where such words make sense (a name with no ";" is just the main phrase). +# - If an intent has multiple fixities but a definition does not specify one, the first fixity listed is chosen by default. +# +# Functions and argument glue (the part after the name): +# - ":" separates the name/bracketing phrase from the argument-glue options that follow it. +# - Arity template (two or more ":" options, or one option with ','-separated glue words): the +# number of glue words implies the arity, and the final argument is preceded by "of". +# Example: "sum: over: from,to" +# - 1 arg: "sum of x" +# - 2 args: "sum over i of x" +# - 3 args: "sum from i to n of x" +# If no option matches the argument count, the arguments are separated with "comma". +# - Binary separator (exactly one ":" option, no commas in it): after "of", that word joins the two args. +# Example: "quotient": "function=integer part: divided by" → "integer part of x divided by y" +# If there are not exactly two args, the arguments fall back to "comma". +# - Paired "ratio-style" (" : | : | ..."): used when every "|"-separated +# piece is a single "name : glue" pair. Verbosity selects one pair, whose glue is the binary +# separator described above. Example: "ratio": "function=ratio : to | the ratio : to | the ratio : to" +# +# Conceptual grammar (with precedence): +# +# IntentMappingsEntry ::= ":" # ":" is the YAML key/value separator +# +# ::= ( "||" )* +# +# ::= "=" +# +# ::= "prefix" | "infix" | "postfix" | "function" | "nofix" | "silent" +# +# ::= | +# +# # Standard form: a name/bracketing part, then ":"-separated argument-glue options. +# ::= ( ":" )* +# +# ::= [ ";" ";" ] # 1 part: name; 3 parts: opening; main; closing +# +# ::= [ "|" [ "|" ] ] # terse | medium | verbose +# +# ::= # a single glue word, or ","-separated arity words +# +# # Paired "ratio-style" form: recognized only when every "|" piece is a single "name : glue" pair. +# ::= ( "|" )+ +# +# ::= ":" # the glue contains no ":" +# +# ::= text +# +# Precedence depends on the form: +# - Standard: split on ":" first (name vs. argument-glue options), then split each piece on "|" +# for terse|medium|verbose, and split only the name part on ";" for opening; main; closing. +# - Paired: split on "|" first into "name : glue" pairs, then verbosity selects one pair. +# +# Example: +# "absolute-value": "function= ; absolute value| the absolute value| the absolute value; end absolute value" +# "sum": "function=sum: over: from,to" +# "quotient": "function=integer part: divided by" +# "ratio": "function=ratio : to | the ratio : to | the ratio : to" # verbosity of name:glue pairs +# - IntentMappings: { - "indexed-by": "infix= ; senket: senket: nedre indeks; slutt senket: slutt senket: slutt nedre indeks", + "indexed-by": "infix= ; senket| senket| nedre indeks; slutt senket| slutt senket| slutt nedre indeks", "modified-variable": "silent= ", - "say-super": "infix=opphøyd: øvre indeks: øvre indeks", # used with 'mo' for superscripts (e.g, "<") + "say-super": "infix=opphøyd| øvre indeks| øvre indeks", # used with 'mo' for superscripts (e.g, "<") "skip-super": "silent=", # used with 'mo' for superscripts (e.g, "*") "absolute-value": "function= ; absoluttverdien; slutt absoluttverdi", @@ -27,8 +96,8 @@ "limit": "prefix=grenseverdien når", "lim-sup": "prefix=den øvre grenseverdien når", "lim-inf": "prefix=den nedre grenseverdien når", - "logarithm-with-base": "prefix=log med grunntall: logaritmen med grunntall: logaritmen med grunntall", - "natural-logarithm": "function=l n: den naturlige logaritmen: den naturlige logaritmen", + "logarithm-with-base": "prefix=log med grunntall| logaritmen med grunntall| logaritmen med grunntall", + "natural-logarithm": "function=l n| den naturlige logaritmen| den naturlige logaritmen", "minus": "infix=minus || prefix=minus", "plus": "infix=pluss || prefix=pluss", "real-part": "function=den reelle delen", @@ -40,16 +109,16 @@ #"dimension": "function=; dimensjonen; slutt dimensjon", # NORWEGIAN: We say "dimensjonen til" (the dimension to), so this rule is in linear-algebra # "homomorphism": "function= ; homomorfi; slutt homomorfi", # doesn't fit function pattern # "kernel": "function= ; nullrommet ; slutt nullrommet # NORWEGIAN: We say "nullrommet til" (the kernel to), so this rule is in linear-algebra - "vector": "function= ; vektor: vektoren: vektoren || prefix=vektor: vektoren: vektoren", - "cross-product": "infix=kryss: kryssprodukt: kryssprodukt", - "dot-product": "infix=prikk: skalarprodukt: skalarprodukt", + "vector": "function= ; vektor| vektoren| vektoren || prefix=vektor| vektoren| vektoren", + "cross-product": "infix=kryss| kryssprodukt| kryssprodukt", + "dot-product": "infix=prikk| skalarprodukt| skalarprodukt", #"divergence": "function= ; div: divergens: divergens; slutt divergens", #NORWEGIAN: We say "divergensen til" (the divergence to), so this rule is in calculus. #"curl": "function= ; curl; slutt curl", #NORWEGIAN: We say "curlen til" (the curl to), so this rule is in calculus #"gradient": "function= ; grad: gradient: gradient; slutt gradient", #NORWEGIAN: We say "gradienten til" (the gradient to), so this rule is in calculus "laplacian": "function=laplace", # speech engines don't do a good job with "laplacian" (swedish ones might) - "chemistry-concentration": "function= ; konsentrasjon: konsentrasjonen av: konsentrasjonen av; slutt konsentrasjon", + "chemistry-concentration": "function= ; konsentrasjon| konsentrasjonen av| konsentrasjonen av; slutt konsentrasjon", } - NavigationParts: { diff --git a/Rules/Languages/pl/definitions.yaml b/Rules/Languages/pl/definitions.yaml index e3a8bc1db..6a37d3999 100644 --- a/Rules/Languages/pl/definitions.yaml +++ b/Rules/Languages/pl/definitions.yaml @@ -1,8 +1,83 @@ --- - include: "../../definitions.yaml" -# If an "intent" is used, the 'terse:medium:verbose' speech for the intent name is given here. -# Polish entries below are source-level speech strings used by MathCAT. +# IntentMappings Syntax: +# +# This section defines how each "intent" is spoken for various grammatical forms (fixities such as "prefix", "infix", "postfix", and "function"), +# along with supporting different verbosity levels. +# The syntax is a little bit complicated, but allows a declarative syntax so you don't have to write as many rules. +# +# For each intent, you specify spoken forms for one or more fixities using the syntax below. +# +# - Each mapping has the form: +# "": "= || = || ...", +# Every alternative must name a fixity and use "="; the fixity requested when speaking selects one. +# +# - Separate multiple fixities with "||". Spaces are allowed around any delimiter for readability. +# - Within a speech string, "|" selects the verbosity form: +# - one "|" (two forms): the first is 'terse', the second is used for 'medium' and 'verbose' +# - two "|" (three forms): 'terse', 'medium', 'verbose', in that order +# - no "|": the same spoken form is used for all verbosity levels +# +# - Use semicolons ";" to divide opening; main; closing bracketing words within the name part, +# where such words make sense (a name with no ";" is just the main phrase). +# - If an intent has multiple fixities but a definition does not specify one, the first fixity listed is chosen by default. +# +# Functions and argument glue (the part after the name): +# - ":" separates the name/bracketing phrase from the argument-glue options that follow it. +# - Arity template (two or more ":" options, or one option with ','-separated glue words): the +# number of glue words implies the arity, and the final argument is preceded by "of". +# Example: "sum: over: from,to" +# - 1 arg: "sum of x" +# - 2 args: "sum over i of x" +# - 3 args: "sum from i to n of x" +# If no option matches the argument count, the arguments are separated with "comma". +# - Binary separator (exactly one ":" option, no commas in it): after "of", that word joins the two args. +# Example: "quotient": "function=integer part: divided by" → "integer part of x divided by y" +# If there are not exactly two args, the arguments fall back to "comma". +# - Paired "ratio-style" (" : | : | ..."): used when every "|"-separated +# piece is a single "name : glue" pair. Verbosity selects one pair, whose glue is the binary +# separator described above. Example: "ratio": "function=ratio : to | the ratio : to | the ratio : to" +# +# Conceptual grammar (with precedence): +# +# IntentMappingsEntry ::= ":" # ":" is the YAML key/value separator +# +# ::= ( "||" )* +# +# ::= "=" +# +# ::= "prefix" | "infix" | "postfix" | "function" | "nofix" | "silent" +# +# ::= | +# +# # Standard form: a name/bracketing part, then ":"-separated argument-glue options. +# ::= ( ":" )* +# +# ::= [ ";" ";" ] # 1 part: name; 3 parts: opening; main; closing +# +# ::= [ "|" [ "|" ] ] # terse | medium | verbose +# +# ::= # a single glue word, or ","-separated arity words +# +# # Paired "ratio-style" form: recognized only when every "|" piece is a single "name : glue" pair. +# ::= ( "|" )+ +# +# ::= ":" # the glue contains no ":" +# +# ::= text +# +# Precedence depends on the form: +# - Standard: split on ":" first (name vs. argument-glue options), then split each piece on "|" +# for terse|medium|verbose, and split only the name part on ";" for opening; main; closing. +# - Paired: split on "|" first into "name : glue" pairs, then verbosity selects one pair. +# +# Example: +# "absolute-value": "function= ; absolute value| the absolute value| the absolute value; end absolute value" +# "sum": "function=sum: over: from,to" +# "quotient": "function=integer part: divided by" +# "ratio": "function=ratio : to | the ratio : to | the ratio : to" # verbosity of name:glue pairs +# - IntentMappings: { "binomial": "infix=symbol newtona; po; koniec symbolu newtona", @@ -13,9 +88,9 @@ "image":"function=obraz", "mixed-fraction":"infix=i", - "quotient":"function=część całkowita | podzielone przez", + "quotient":"function=część całkowita : podzielone przez", "evaluated-at":"infix=obliczone w", - "remainder":"function=reszta | podzielone przez", + "remainder":"function=reszta : podzielone przez", "max":"function=maksimum", "min":"function=minimum", @@ -23,14 +98,14 @@ "power":"infix=do potęgi", "root":"function=pierwiastek", - "greatest-common-divisor": "function=nwd: największy wspólny dzielnik: największy wspólny dzielnik", - "least-common-multiple":"function=nww: najmniejsza wspólna wielokrotność: najmniejsza wspólna wielokrotność", + "greatest-common-divisor": "function=nwd| największy wspólny dzielnik| największy wspólny dzielnik", + "least-common-multiple":"function=nww| najmniejsza wspólna wielokrotność| najmniejsza wspólna wielokrotność", - "absolute-value": "function=; wartość bezwzględna: wartość bezwzględna: wartość bezwzględna; koniec wartości bezwzględnej", + "absolute-value": "function=; wartość bezwzględna| wartość bezwzględna| wartość bezwzględna; koniec wartości bezwzględnej", "complex-conjugate":"function=sprzężenie zespolone", "complex-arg":"function=arg", "real-part": "function=część rzeczywista", - "imaginary-part": "function=część urojona: część urojona: część urojona", + "imaginary-part": "function=część urojona| część urojona| część urojona", "polar-coordinate":"function=współrzędna biegunowa", "spherical-coordinate":"function=współrzędna sferyczna", @@ -50,13 +125,13 @@ ### Sets - "set": "function=; zbiór: zbiór", - "set-difference":"function=różnica zbiorów | i || infix=minus", + "set": "function=; zbiór| zbiór", + "set-difference":"function=różnica zbiorów : i || infix=minus", "complement":"function=dopełnienie", "empty-set":"nofix=zbiór pusty", "cardinality":"function=moc zbioru", "list":"function=lista", - "tuple": "function=; krotka: krotka", + "tuple": "function=; krotka| krotka", ### Sequence and Series @@ -64,17 +139,17 @@ # w kodzie (issue #739): ostatni argument poprzedza teraz FunctionApplicationWord # z tego pliku, czyli polskie "z". Słowa "przez" i "od,do" dobrane tak, jak mówią # o tym istniejące reguły dużych operatorów ("suma przez wielka s z i"). - "sum":"function=suma | przez | od,do", - "product":"function=iloczyn | przez | od,do", + "sum":"function=suma : przez : od,do", + "product":"function=iloczyn : przez : od,do", ### Elementary classical functions - "sine":"function=sin: sinus", - "cosine":"function=cos: cosinus", - "tangent":"function=tan: tangens", - "secant":"function=sec: sekans", - "cosecant":"function=cosec: kosekans", - "cotangent":"function=cot: cotangens", + "sine":"function=sin| sinus", + "cosine":"function=cos| cosinus", + "tangent":"function=tan| tangens", + "secant":"function=sec| sekans", + "cosecant":"function=cosec| kosekans", + "cotangent":"function=cot| cotangens", "arcsine":"function=arcus sinus", "arccosine":"function=arcus cosinus", @@ -98,7 +173,7 @@ "arc-hyperbolic-cotangent":"function=arcus cotangens hiperboliczny", "exponential":"function=funkcja wykładnicza", - "natural-logarithm": "function=L N: logarytm naturalny: logarytm naturalny", + "natural-logarithm": "function=L N| logarytm naturalny| logarytm naturalny", "logarithm":"function=logarytm", ##Check arity 2 @@ -109,7 +184,7 @@ "median":"function=mediana", "mode":"function=dominanta", - "conditional-probability":"function=prawdopodobieństwo | pod warunkiem", + "conditional-probability":"function=prawdopodobieństwo : pod warunkiem", ### Linear Algebra @@ -119,7 +194,7 @@ "determinant":"function=wyznacznik", "adjugate":"function=macierz dopełnień algebraicznych", "magnitude":"function=długość", - "norm": "function=; norma: norma: norma; koniec normy", + "norm": "function=; norma| norma| norma; koniec normy", "span":"function=powłoka liniowa", "unit-vector":"prefix=wektor jednostkowy", @@ -130,12 +205,12 @@ ### Constants and Sets - "set-of-integers":"nofix=ℤ: zbiór liczb całkowitych", - "set-of-reals":"nofix=ℝ: zbiór liczb rzeczywistych", - "set-of-rationals":"nofix=ℚ: zbiór liczb wymiernych", - "set-of-natural-numbers":"nofix=ℕ: zbiór liczb naturalnych", - "set-of-complex-numbers":"nofix=ℂ: zbiór liczb zespolonych", - "set-of-primes":"nofix=ℙ: zbiór liczb pierwszych", + "set-of-integers":"nofix=ℤ| zbiór liczb całkowitych", + "set-of-reals":"nofix=ℝ| zbiór liczb rzeczywistych", + "set-of-rationals":"nofix=ℚ| zbiór liczb wymiernych", + "set-of-natural-numbers":"nofix=ℕ| zbiór liczb naturalnych", + "set-of-complex-numbers":"nofix=ℂ| zbiór liczb zespolonych", + "set-of-primes":"nofix=ℙ| zbiór liczb pierwszych", ### Geometry @@ -155,7 +230,7 @@ ### General Concepts "fenced-group":"function=grupa w nawiasach", - "ordered-pair": "function=para | i", + "ordered-pair": "function=para : i", "indexed-by": "infix=; indeks dolny; koniec indeksu dolnego", "highlight":"postfix=podświetlone", @@ -203,7 +278,7 @@ "congruent": "infix=przystające do", "cartesian-product": "infix=iloczyn kartezjański", "composed-with": "infix=złożone z", - "cross-product": "infix=krzyż: iloczyn wektorowy: iloczyn wektorowy", + "cross-product": "infix=krzyż| iloczyn wektorowy| iloczyn wektorowy", "defined-as": "infix=zdefiniowane jako", "divided-by": "infix=podzielone przez", "divides": "infix=dzieli", @@ -267,11 +342,11 @@ "percent": "postfix=procent", ## Default fixity nofix - "diameter":"nofix=d: średnica", - "distance":"nofix=d; D: odległość", - "probability":"nofix=P: prawdopodobieństwo || function=prawdopodobieństwo", - "radius":"nofix=r: promień", - "volume":"nofix=V: objętość || function=objętość", + "diameter":"nofix=d| średnica", + "distance":"nofix=d; D| odległość", + "probability":"nofix=P| prawdopodobieństwo || function=prawdopodobieństwo", + "radius":"nofix=r| promień", + "volume":"nofix=V| objętość || function=objętość", "exponential-e":"nofix=e", "imaginary-i":"nofix=i", "differential-d":"nofix=d", @@ -280,20 +355,20 @@ ## Other : Not tested, don't appear in https://w3c.github.io/mathml-docs/intent-core-concepts/ "modified-variable": "silent=", - "say-super": "infix=indeks górny: indeks górny: indeks górny", # used with 'mo' for superscripts (e.g, "<") + "say-super": "infix=indeks górny| indeks górny| indeks górny", # used with 'mo' for superscripts (e.g, "<") "skip-super": "silent=", # used with 'mo' for superscripts (e.g, "*") # "large-op": "infix=przez|| other=od,do", - "lim-sup": "prefix=lim sup gdy: granica górna gdy: granica górna gdy", - "lim-inf": "prefix=lim inf gdy: granica dolna gdy: granica dolna gdy", - "limit-sup": "prefix=lim sup gdy: granica górna gdy: granica górna gdy", - "limit-inf": "prefix=lim inf gdy: granica dolna gdy: granica dolna gdy", - "logarithm-with-base": "prefix=log podstawa: logarytm o podstawie: logarytm o podstawie", - "trace": "function=; ślad: ślad: ślad; koniec śladu", - "dimension": "function=; wymiar: wymiar: wymiar; koniec wymiaru", - "homomorphism": "function=; homomorfizm: homomorfizm: homomorfizm; koniec homomorfizmu", - "kernel": "function=; jądro: jądro: jądro; koniec jądra", + "lim-sup": "prefix=lim sup gdy| granica górna gdy| granica górna gdy", + "lim-inf": "prefix=lim inf gdy| granica dolna gdy| granica dolna gdy", + "limit-sup": "prefix=lim sup gdy| granica górna gdy| granica górna gdy", + "limit-inf": "prefix=lim inf gdy| granica dolna gdy| granica dolna gdy", + "logarithm-with-base": "prefix=log podstawa| logarytm o podstawie| logarytm o podstawie", + "trace": "function=; ślad| ślad| ślad; koniec śladu", + "dimension": "function=; wymiar| wymiar| wymiar; koniec wymiaru", + "homomorphism": "function=; homomorfizm| homomorfizm| homomorfizm; koniec homomorfizmu", + "kernel": "function=; jądro| jądro| jądro; koniec jądra", - "chemistry-concentration": "function=; stężenie: stężenie: stężenie; koniec stężenia", + "chemistry-concentration": "function=; stężenie| stężenie| stężenie; koniec stężenia", } # The connector word to say for functional 'IntentMappings' (in English, "of") diff --git a/Rules/Languages/pt/definitions.yaml b/Rules/Languages/pt/definitions.yaml index adf95240a..fd0beffcf 100644 --- a/Rules/Languages/pt/definitions.yaml +++ b/Rules/Languages/pt/definitions.yaml @@ -7,56 +7,125 @@ # - name: [] "...", "..." "..." ] -# If an "intent" is used, the 'terse:medium:verbose' speech for the intent name is given here for a prefix||infix||postfix||function fixity -# If only one ":" is used, it the first part is used for 'terse' and the second part is used for 'medium' and 'verbose' -# If no ":"s are used, the same speech is used for all forms -# If bracketing words make sense, they are separated with ";"s -# Intent mappings must specify whether they are "prefix", "infix", "postfix", or "function" with an "=" sign -# If there are multiple fixities (e.g., see transpose), they are separated with "|| -# for readability, spaces can be used around any of the delimiter characters -# Note: if there are multiple fixities, the first one is used if the fixity is not given in the intent +# IntentMappings Syntax: +# +# This section defines how each "intent" is spoken for various grammatical forms (fixities such as "prefix", "infix", "postfix", and "function"), +# along with supporting different verbosity levels. +# The syntax is a little bit complicated, but allows a declarative syntax so you don't have to write as many rules. +# +# For each intent, you specify spoken forms for one or more fixities using the syntax below. +# +# - Each mapping has the form: +# "": "= || = || ...", +# Every alternative must name a fixity and use "="; the fixity requested when speaking selects one. +# +# - Separate multiple fixities with "||". Spaces are allowed around any delimiter for readability. +# - Within a speech string, "|" selects the verbosity form: +# - one "|" (two forms): the first is 'terse', the second is used for 'medium' and 'verbose' +# - two "|" (three forms): 'terse', 'medium', 'verbose', in that order +# - no "|": the same spoken form is used for all verbosity levels +# +# - Use semicolons ";" to divide opening; main; closing bracketing words within the name part, +# where such words make sense (a name with no ";" is just the main phrase). +# - If an intent has multiple fixities but a definition does not specify one, the first fixity listed is chosen by default. +# +# Functions and argument glue (the part after the name): +# - ":" separates the name/bracketing phrase from the argument-glue options that follow it. +# - Arity template (two or more ":" options, or one option with ','-separated glue words): the +# number of glue words implies the arity, and the final argument is preceded by "of". +# Example: "sum: over: from,to" +# - 1 arg: "sum of x" +# - 2 args: "sum over i of x" +# - 3 args: "sum from i to n of x" +# If no option matches the argument count, the arguments are separated with "comma". +# - Binary separator (exactly one ":" option, no commas in it): after "of", that word joins the two args. +# Example: "quotient": "function=integer part: divided by" → "integer part of x divided by y" +# If there are not exactly two args, the arguments fall back to "comma". +# - Paired "ratio-style" (" : | : | ..."): used when every "|"-separated +# piece is a single "name : glue" pair. Verbosity selects one pair, whose glue is the binary +# separator described above. Example: "ratio": "function=ratio : to | the ratio : to | the ratio : to" +# +# Conceptual grammar (with precedence): +# +# IntentMappingsEntry ::= ":" # ":" is the YAML key/value separator +# +# ::= ( "||" )* +# +# ::= "=" +# +# ::= "prefix" | "infix" | "postfix" | "function" | "nofix" | "silent" +# +# ::= | +# +# # Standard form: a name/bracketing part, then ":"-separated argument-glue options. +# ::= ( ":" )* +# +# ::= [ ";" ";" ] # 1 part: name; 3 parts: opening; main; closing +# +# ::= [ "|" [ "|" ] ] # terse | medium | verbose +# +# ::= # a single glue word, or ","-separated arity words +# +# # Paired "ratio-style" form: recognized only when every "|" piece is a single "name : glue" pair. +# ::= ( "|" )+ +# +# ::= ":" # the glue contains no ":" +# +# ::= text +# +# Precedence depends on the form: +# - Standard: split on ":" first (name vs. argument-glue options), then split each piece on "|" +# for terse|medium|verbose, and split only the name part on ";" for opening; main; closing. +# - Paired: split on "|" first into "name : glue" pairs, then verbosity selects one pair. +# +# Example: +# "absolute-value": "function= ; absolute value| the absolute value| the absolute value; end absolute value" +# "sum": "function=sum: over: from,to" +# "quotient": "function=integer part: divided by" +# "ratio": "function=ratio : to | the ratio : to | the ratio : to" # verbosity of name:glue pairs +# - IntentMappings: { "indexed-by": "infix= ; índice; fim do índice", "modified-variable": "silent= ", "say-super": "infix=sobrescrito", # used with 'mo' for superscripts (e.g, "<") "skip-super": "silent=", # used with 'mo' for superscripts (e.g, "*") - "absolute-value": "function= ; valor absoluto: o valor absoluto de: o valor absoluto de; fim do valor absoluto", + "absolute-value": "function= ; valor absoluto| o valor absoluto de| o valor absoluto de; fim do valor absoluto", "binomial": "infix=binomial; escolhe; fim do binomial", "limit": "prefix=limite quando", - "lim-sup": "prefix=lim sup quando: o limite superior quando: o limite superior quando", - "lim-inf": "prefix=lim inf quando: o limite inferior quando: o limite inferior quando", - "logarithm-with-base": "prefix=log na base: o log na base: o logaritmo na base", + "lim-sup": "prefix=lim sup quando| o limite superior quando| o limite superior quando", + "lim-inf": "prefix=lim inf quando| o limite inferior quando| o limite inferior quando", + "logarithm-with-base": "prefix=log na base| o log na base| o logaritmo na base", "minus": "infix=menos || prefix=menos", "plus": "infix=mais || prefix=positivo", "transpose": "postfix=transposta || function=transposta", - "norm": "function=; norma: norma: a norma; fim da norma", + "norm": "function=; norma| norma| a norma; fim da norma", # ‖x‖ é inferido pelo motor como 'magnitude' (não 'norm'); sem esta linha # vazava "magnitude de x" em inglês. Mesma fala da norma. - "magnitude": "function=; norma: norma: a norma; fim da norma", - "trace": "function=; traço: traço de: o traço de; fim do traço", - "dimension": "function=; dimensão: dimensão de: a dimensão de; fim da dimensão", - "homomorphism": "function= ; homomorfismo: homomorfismo de: o homomorfismo de; fim do homomorfismo", - "kernel": "function= ; núcleo: núcleo de: o núcleo de; fim do núcleo", + "magnitude": "function=; norma| norma| a norma; fim da norma", + "trace": "function=; traço| traço de| o traço de; fim do traço", + "dimension": "function=; dimensão| dimensão de| a dimensão de; fim da dimensão", + "homomorphism": "function= ; homomorfismo| homomorfismo de| o homomorfismo de; fim do homomorfismo", + "kernel": "function= ; núcleo| núcleo de| o núcleo de; fim do núcleo", "vector": "function= ; vetor || prefix=vetor", # O motor infere ⃗a × ⃗b como um SEM filhos (o operador vira # o próprio elemento); aí a fixidade infix não se aplica e ele falava o nome # literal, "cross product". A fixidade nofix cobre esse caso. Idem dot-product. - "cross-product": "infix=vetorial: produto vetorial: produto vetorial || nofix=vetorial: produto vetorial: produto vetorial", - "dot-product": "infix=escalar: produto escalar: produto escalar || nofix=escalar: produto escalar: produto escalar", + "cross-product": "infix=vetorial| produto vetorial| produto vetorial || nofix=vetorial| produto vetorial| produto vetorial", + "dot-product": "infix=escalar| produto escalar| produto escalar || nofix=escalar| produto escalar| produto escalar", - "divergence": "function= ; div: divergente: divergente; fim do divergente", + "divergence": "function= ; div| divergente| divergente; fim do divergente", "curl": "function= ; rotacional; fim do rotacional", - "gradient": "function= ; grad: gradiente: gradiente; fim do gradiente", + "gradient": "function= ; grad| gradiente| gradiente; fim do gradiente", "laplacian": "function=laplaciano", - "chemistry-concentration": "function= ; concentração: concentração de: a concentração de; fim da concentração", + "chemistry-concentration": "function= ; concentração| concentração de| a concentração de; fim da concentração", # CORREÇÃO: o en tem duas fixidades (nofix || function); só com a function # a fala ganha o "de" ("probabilidade de x"). E o separador de palavras do # conditional-probability é "|", como no en — ";" não é reconhecido aqui. - "probability": "nofix=P: probabilidade || function=probabilidade", - "conditional-probability": "function=probabilidade | dado", + "probability": "nofix=P| probabilidade || function=probabilidade", + "conditional-probability": "function=probabilidade : dado", "intersection": "infix=interseção", "union": "infix=união", } diff --git a/Rules/Languages/ru/definitions.yaml b/Rules/Languages/ru/definitions.yaml index c89178abc..2426a2c53 100644 --- a/Rules/Languages/ru/definitions.yaml +++ b/Rules/Languages/ru/definitions.yaml @@ -1,57 +1,126 @@ --- - include: "../../definitions.yaml" -# If an "intent" is used, the 'terse:medium:verbose' speech for the intent name is given here for a prefix||infix||postfix||function fixity -# If only one ":" is used, it the first part is used for 'terse' and the second part is used for 'medium' and 'verbose' -# If no ":"s are used, the same speech is used for all forms -# If bracketing words make sense, they are separated with ";"s -# Intent mappings must specify whether they are "prefix", "infix", "postfix", or "function" with an "=" sign -# If there are multiple fixities (e.g., see transpose), they are separated with "|| -# for readability, spaces can be used around any of the delimiter characters -# Note: if there are multiple fixities, the first one is used if the fixity is not given in the intent +# IntentMappings Syntax: +# +# This section defines how each "intent" is spoken for various grammatical forms (fixities such as "prefix", "infix", "postfix", and "function"), +# along with supporting different verbosity levels. +# The syntax is a little bit complicated, but allows a declarative syntax so you don't have to write as many rules. +# +# For each intent, you specify spoken forms for one or more fixities using the syntax below. +# +# - Each mapping has the form: +# "": "= || = || ...", +# Every alternative must name a fixity and use "="; the fixity requested when speaking selects one. +# +# - Separate multiple fixities with "||". Spaces are allowed around any delimiter for readability. +# - Within a speech string, "|" selects the verbosity form: +# - one "|" (two forms): the first is 'terse', the second is used for 'medium' and 'verbose' +# - two "|" (three forms): 'terse', 'medium', 'verbose', in that order +# - no "|": the same spoken form is used for all verbosity levels +# +# - Use semicolons ";" to divide opening; main; closing bracketing words within the name part, +# where such words make sense (a name with no ";" is just the main phrase). +# - If an intent has multiple fixities but a definition does not specify one, the first fixity listed is chosen by default. +# +# Functions and argument glue (the part after the name): +# - ":" separates the name/bracketing phrase from the argument-glue options that follow it. +# - Arity template (two or more ":" options, or one option with ','-separated glue words): the +# number of glue words implies the arity, and the final argument is preceded by "of". +# Example: "sum: over: from,to" +# - 1 arg: "sum of x" +# - 2 args: "sum over i of x" +# - 3 args: "sum from i to n of x" +# If no option matches the argument count, the arguments are separated with "comma". +# - Binary separator (exactly one ":" option, no commas in it): after "of", that word joins the two args. +# Example: "quotient": "function=integer part: divided by" → "integer part of x divided by y" +# If there are not exactly two args, the arguments fall back to "comma". +# - Paired "ratio-style" (" : | : | ..."): used when every "|"-separated +# piece is a single "name : glue" pair. Verbosity selects one pair, whose glue is the binary +# separator described above. Example: "ratio": "function=ratio : to | the ratio : to | the ratio : to" +# +# Conceptual grammar (with precedence): +# +# IntentMappingsEntry ::= ":" # ":" is the YAML key/value separator +# +# ::= ( "||" )* +# +# ::= "=" +# +# ::= "prefix" | "infix" | "postfix" | "function" | "nofix" | "silent" +# +# ::= | +# +# # Standard form: a name/bracketing part, then ":"-separated argument-glue options. +# ::= ( ":" )* +# +# ::= [ ";" ";" ] # 1 part: name; 3 parts: opening; main; closing +# +# ::= [ "|" [ "|" ] ] # terse | medium | verbose +# +# ::= # a single glue word, or ","-separated arity words +# +# # Paired "ratio-style" form: recognized only when every "|" piece is a single "name : glue" pair. +# ::= ( "|" )+ +# +# ::= ":" # the glue contains no ":" +# +# ::= text +# +# Precedence depends on the form: +# - Standard: split on ":" first (name vs. argument-glue options), then split each piece on "|" +# for terse|medium|verbose, and split only the name part on ";" for opening; main; closing. +# - Paired: split on "|" first into "name : glue" pairs, then verbosity selects one pair. +# +# Example: +# "absolute-value": "function= ; absolute value| the absolute value| the absolute value; end absolute value" +# "sum": "function=sum: over: from,to" +# "quotient": "function=integer part: divided by" +# "ratio": "function=ratio : to | the ratio : to | the ratio : to" # verbosity of name:glue pairs +# - IntentMappings: { - "indexed-by": "infix= ; с индексом; конец индекса: с индексом: с индексом", + "indexed-by": "infix= ; с индексом; конец индекса| с индексом| с индексом", "modified-variable": "silent= ", - "say-super": "infix=верхний индекс: верхний индекс: верхний индекс", # used with 'mo' for superscripts (e.g, "<") + "say-super": "infix=верхний индекс| верхний индекс| верхний индекс", # used with 'mo' for superscripts (e.g, "<") "skip-super": "silent=", # used with 'mo' for superscripts (e.g, "*") - "absolute-value": "function= ; модуль: модуль: модуль; конец модуля", + "absolute-value": "function= ; модуль| модуль| модуль; конец модуля", "binomial": "infix=число сочетаний из; по; конец числа сочетаний", # "closed-interval": "other=closed-interval; от,до; end closed-interval", - "greatest-common-divisor": "function=нод: нод: наибольший общий делитель", + "greatest-common-divisor": "function=нод| нод| наибольший общий делитель", "imaginary-part": "function=мнимая часть, мнимая часть, мнимая часть", - "least-common-multiple": "function=нок:нок:наименьшее общее кратное", + "least-common-multiple": "function=нок|нок|наименьшее общее кратное", # "large-op": "infix=над || other=от,до", - "limit": "prefix=предел при: предел при: предел при", - "lim-sup": "prefix=верхний предел при: верхний предел при: верхний предел при", - "lim-inf": "prefix=нижний предел при: нижний предел при: нижний предел при", - "logarithm-with-base": "prefix=логарифм по основанию: логарифм по основанию: логарифм по основанию", - "natural-logarithm": "function=эл эн: натуральный логарифм: натуральный логарифм", + "limit": "prefix=предел при| предел при| предел при", + "lim-sup": "prefix=верхний предел при| верхний предел при| верхний предел при", + "lim-inf": "prefix=нижний предел при| нижний предел при| нижний предел при", + "logarithm-with-base": "prefix=логарифм по основанию| логарифм по основанию| логарифм по основанию", + "natural-logarithm": "function=эл эн| натуральный логарифм| натуральный логарифм", "minus": "infix=минус || prefix=минус", "plus": "infix=плюс || prefix=плюс", # "pochhammer": "infix=permutations of", # arguments are in reverse order, so can't work here "real-part": "function=действительная часть", "transpose": "postfix=транспонирование || function=транспонированная", - "norm": "function=; норма: норма: норма; конец нормы", - "trace": "function=;след : след: след; конец следа", - "dimension": "function=; размерность : размерность: размерность; конец размерности", - "homomorphism": "function= ; гомоморфизм : гомоморфизм: гомоморфизм; конец гомоморфизма", - "kernel": "function= ; ядро : ядро: ядро; конец ядра", + "norm": "function=; норма| норма| норма; конец нормы", + "trace": "function=;след | след| след; конец следа", + "dimension": "function=; размерность | размерность| размерность; конец размерности", + "homomorphism": "function= ; гомоморфизм | гомоморфизм| гомоморфизм; конец гомоморфизма", + "kernel": "function= ; ядро | ядро| ядро; конец ядра", "vector": "function= ; вектор || prefix=вектор", - "cross-product": "infix=векторное произведение: векторное произведение: векторное произведение", - "dot-product": "infix=скалярное произведение: скалярное произведение: скалярное произведение", + "cross-product": "infix=векторное произведение| векторное произведение| векторное произведение", + "dot-product": "infix=скалярное произведение| скалярное произведение| скалярное произведение", "perpendicular-to": "infix=перпендикулярно", "perpendicular to": "infix=перпендикулярно", "perpendicular_to": "infix=перпендикулярно", "forced": "prefix=форсид", - "divergence": "function= ; дивергенция: дивергенция: дивергенция; конец дивергенции", + "divergence": "function= ; дивергенция| дивергенция| дивергенция; конец дивергенции", "curl": "function= ; ротор; конец ротора", - "gradient": "function= ; градиент: градиент: градиент; конец градиента", + "gradient": "function= ; градиент| градиент| градиент; конец градиента", "laplacian": "function=лапласиан", # speech engines don't do a good job with "laplacian" - "chemistry-concentration": "function= ; концентрация: концентрация: концентрация; конец концентрации", + "chemistry-concentration": "function= ; концентрация| концентрация| концентрация; конец концентрации", } # Names of functions that in terse mode don't say "of" (or it's equivalent in other languages) diff --git a/Rules/Languages/sv/definitions.yaml b/Rules/Languages/sv/definitions.yaml index 643f50377..b0c7cffbd 100644 --- a/Rules/Languages/sv/definitions.yaml +++ b/Rules/Languages/sv/definitions.yaml @@ -5,32 +5,101 @@ # name: [ "...", "..." "..." ], -# If an "intent" is used, the 'terse:medium:verbose' speech for the intent name is given here for a prefix||infix||postfix||function fixity -# If only one ":" is used, it the first part is used for 'terse' and the second part is used for 'medium' and 'verbose' -# If no ":"s are used, the same speech is used for all forms -# If bracketing words make sense, they are separated with ";"s -# Intent mappings must specify whether they are "prefix", "infix", "postfix", or "function" with an "=" sign -# If there are multiple fixities (e.g., see transpose), they are separated with "|| -# for readability, spaces can be used around any of the delimiter characters -# Note: if there are multiple fixities, the first one is used if the fixity is not given in the intent +# IntentMappings Syntax: +# +# This section defines how each "intent" is spoken for various grammatical forms (fixities such as "prefix", "infix", "postfix", and "function"), +# along with supporting different verbosity levels. +# The syntax is a little bit complicated, but allows a declarative syntax so you don't have to write as many rules. +# +# For each intent, you specify spoken forms for one or more fixities using the syntax below. +# +# - Each mapping has the form: +# "": "= || = || ...", +# Every alternative must name a fixity and use "="; the fixity requested when speaking selects one. +# +# - Separate multiple fixities with "||". Spaces are allowed around any delimiter for readability. +# - Within a speech string, "|" selects the verbosity form: +# - one "|" (two forms): the first is 'terse', the second is used for 'medium' and 'verbose' +# - two "|" (three forms): 'terse', 'medium', 'verbose', in that order +# - no "|": the same spoken form is used for all verbosity levels +# +# - Use semicolons ";" to divide opening; main; closing bracketing words within the name part, +# where such words make sense (a name with no ";" is just the main phrase). +# - If an intent has multiple fixities but a definition does not specify one, the first fixity listed is chosen by default. +# +# Functions and argument glue (the part after the name): +# - ":" separates the name/bracketing phrase from the argument-glue options that follow it. +# - Arity template (two or more ":" options, or one option with ','-separated glue words): the +# number of glue words implies the arity, and the final argument is preceded by "of". +# Example: "sum: over: from,to" +# - 1 arg: "sum of x" +# - 2 args: "sum over i of x" +# - 3 args: "sum from i to n of x" +# If no option matches the argument count, the arguments are separated with "comma". +# - Binary separator (exactly one ":" option, no commas in it): after "of", that word joins the two args. +# Example: "quotient": "function=integer part: divided by" → "integer part of x divided by y" +# If there are not exactly two args, the arguments fall back to "comma". +# - Paired "ratio-style" (" : | : | ..."): used when every "|"-separated +# piece is a single "name : glue" pair. Verbosity selects one pair, whose glue is the binary +# separator described above. Example: "ratio": "function=ratio : to | the ratio : to | the ratio : to" +# +# Conceptual grammar (with precedence): +# +# IntentMappingsEntry ::= ":" # ":" is the YAML key/value separator +# +# ::= ( "||" )* +# +# ::= "=" +# +# ::= "prefix" | "infix" | "postfix" | "function" | "nofix" | "silent" +# +# ::= | +# +# # Standard form: a name/bracketing part, then ":"-separated argument-glue options. +# ::= ( ":" )* +# +# ::= [ ";" ";" ] # 1 part: name; 3 parts: opening; main; closing +# +# ::= [ "|" [ "|" ] ] # terse | medium | verbose +# +# ::= # a single glue word, or ","-separated arity words +# +# # Paired "ratio-style" form: recognized only when every "|" piece is a single "name : glue" pair. +# ::= ( "|" )+ +# +# ::= ":" # the glue contains no ":" +# +# ::= text +# +# Precedence depends on the form: +# - Standard: split on ":" first (name vs. argument-glue options), then split each piece on "|" +# for terse|medium|verbose, and split only the name part on ";" for opening; main; closing. +# - Paired: split on "|" first into "name : glue" pairs, then verbosity selects one pair. +# +# Example: +# "absolute-value": "function= ; absolute value| the absolute value| the absolute value; end absolute value" +# "sum": "function=sum: over: from,to" +# "quotient": "function=integer part: divided by" +# "ratio": "function=ratio : to | the ratio : to | the ratio : to" # verbosity of name:glue pairs +# - IntentMappings: { - "indexed-by": "infix= ; nedsänkt: nedsänkt: nedre index; slut nedsänkt: slut nedsänkt: slut nedre index", + "indexed-by": "infix= ; nedsänkt| nedsänkt| nedre index; slut nedsänkt| slut nedsänkt| slut nedre index", "modified-variable": "silent= ", - "say-super": "infix=upphöjt: övre index: övre index", # used with 'mo' for superscripts (e.g, "<") + "say-super": "infix=upphöjt| övre index| övre index", # used with 'mo' for superscripts (e.g, "<") "skip-super": "silent=", # used with 'mo' for superscripts (e.g, "*") "absolute-value": "function= ; absolutbeloppet; slut absolutbelopp", "binomial": "infix=binomial; över; slut binomial", "dimension-product": "infix=gånger", # "closed-interval": "other=closed-interval; from,to; end closed-interval", - "greatest-common-divisor": "function=sgd: sgd: största gemensamma delaren", - "imaginary-part": "function=imaginär del: den imaginära delen: den imaginära delen", - "least-common-multiple": "function=mgm: mgm: den minsta gemensamma multipeln", + "greatest-common-divisor": "function=sgd| sgd| största gemensamma delaren", + "imaginary-part": "function=imaginär del| den imaginära delen| den imaginära delen", + "least-common-multiple": "function=mgm| mgm| den minsta gemensamma multipeln", # "large-op": "infix=over || other=from,to", "limit": "prefix=gränsvärdet då", - "lim-sup": "prefix=lim sup då: övre gränsvärdet då: det övre gränsvärdet då", - "lim-inf": "prefix=lim inf då: undre gränsvärdet då : det undre gränsvärdet då", - "logarithm-with-base": "prefix=logg bas: logaritmen med bas: logaritmen med bas", + "lim-sup": "prefix=lim sup då| övre gränsvärdet då| det övre gränsvärdet då", + "lim-inf": "prefix=lim inf då| undre gränsvärdet då | det undre gränsvärdet då", + "logarithm-with-base": "prefix=logg bas| logaritmen med bas| logaritmen med bas", "minus": "infix=minus || prefix=minus", "plus": "infix=plus || prefix=positivt", # "pochhammer": "infix=permutations of", # arguments are in reverse order, so can't work here @@ -42,16 +111,16 @@ "dimension": "function=; dimensionen; slut dimension", # "homomorphism": "function= ; homomorfism; slut homomorfism", # SWEDISH: doesn't fit function pattern # "kernel": "function= ; noll-rummet : noll-rummet till: noll-rummet till; slut noll-rummet", # SWEDISH: doesn't fit function pattern - "vector": "function= ; vektor: vektorn: vektorn || prefix=vektor: vektorn: vektorn", - "cross-product": "infix=kryss: kryssprodukt: kryssprodukt", - "dot-product": "infix=skalärt: skalärprodukt: skalärprodukt", + "vector": "function= ; vektor| vektorn| vektorn || prefix=vektor| vektorn| vektorn", + "cross-product": "infix=kryss| kryssprodukt| kryssprodukt", + "dot-product": "infix=skalärt| skalärprodukt| skalärprodukt", - "divergence": "function= ; div: divergens: divergens; slut divergens", + "divergence": "function= ; div| divergens| divergens; slut divergens", "curl": "function= ; rotation; slut rotation", - "gradient": "function= ; grad: gradient: gradient; slut gradient", + "gradient": "function= ; grad| gradient| gradient; slut gradient", "laplacian": "function=laplacianen", # speech engines don't do a good job with "laplacian" (swedish ones might) - "chemistry-concentration": "function= ; koncentration: koncentrationen av: koncentrationen av; slut koncentration", + "chemistry-concentration": "function= ; koncentration| koncentrationen av| koncentrationen av; slut koncentration", } - NavigationParts: { diff --git a/Rules/Languages/vi/definitions.yaml b/Rules/Languages/vi/definitions.yaml index aba2adf36..ba0617a73 100644 --- a/Rules/Languages/vi/definitions.yaml +++ b/Rules/Languages/vi/definitions.yaml @@ -8,21 +8,90 @@ # - name: [] "...", "..." "..." ] -# If an "intent" is used, the 'terse:medium:verbose' speech for the intent name is given here for a prefix||infix||postfix||function fixity -# If only one ":" is used, it the first part is used for 'terse' and the second part is used for 'medium' and 'verbose' -# If no ":"s are used, the same speech is used for all forms -# If bracketing words make sense, they are separated with ";"s -# Intent mappings must specify whether they are "prefix", "infix", "postfix", or "function" with an "=" sign -# If there are multiple fixities (e.g., see transpose), they are separated with "|| -# for readability, spaces can be used around any of the delimiter characters -# Note: if there are multiple fixities, the first one is used if the fixity is not given in the intent +# IntentMappings Syntax: +# +# This section defines how each "intent" is spoken for various grammatical forms (fixities such as "prefix", "infix", "postfix", and "function"), +# along with supporting different verbosity levels. +# The syntax is a little bit complicated, but allows a declarative syntax so you don't have to write as many rules. +# +# For each intent, you specify spoken forms for one or more fixities using the syntax below. +# +# - Each mapping has the form: +# "": "= || = || ...", +# Every alternative must name a fixity and use "="; the fixity requested when speaking selects one. +# +# - Separate multiple fixities with "||". Spaces are allowed around any delimiter for readability. +# - Within a speech string, "|" selects the verbosity form: +# - one "|" (two forms): the first is 'terse', the second is used for 'medium' and 'verbose' +# - two "|" (three forms): 'terse', 'medium', 'verbose', in that order +# - no "|": the same spoken form is used for all verbosity levels +# +# - Use semicolons ";" to divide opening; main; closing bracketing words within the name part, +# where such words make sense (a name with no ";" is just the main phrase). +# - If an intent has multiple fixities but a definition does not specify one, the first fixity listed is chosen by default. +# +# Functions and argument glue (the part after the name): +# - ":" separates the name/bracketing phrase from the argument-glue options that follow it. +# - Arity template (two or more ":" options, or one option with ','-separated glue words): the +# number of glue words implies the arity, and the final argument is preceded by "of". +# Example: "sum: over: from,to" +# - 1 arg: "sum of x" +# - 2 args: "sum over i of x" +# - 3 args: "sum from i to n of x" +# If no option matches the argument count, the arguments are separated with "comma". +# - Binary separator (exactly one ":" option, no commas in it): after "of", that word joins the two args. +# Example: "quotient": "function=integer part: divided by" → "integer part of x divided by y" +# If there are not exactly two args, the arguments fall back to "comma". +# - Paired "ratio-style" (" : | : | ..."): used when every "|"-separated +# piece is a single "name : glue" pair. Verbosity selects one pair, whose glue is the binary +# separator described above. Example: "ratio": "function=ratio : to | the ratio : to | the ratio : to" +# +# Conceptual grammar (with precedence): +# +# IntentMappingsEntry ::= ":" # ":" is the YAML key/value separator +# +# ::= ( "||" )* +# +# ::= "=" +# +# ::= "prefix" | "infix" | "postfix" | "function" | "nofix" | "silent" +# +# ::= | +# +# # Standard form: a name/bracketing part, then ":"-separated argument-glue options. +# ::= ( ":" )* +# +# ::= [ ";" ";" ] # 1 part: name; 3 parts: opening; main; closing +# +# ::= [ "|" [ "|" ] ] # terse | medium | verbose +# +# ::= # a single glue word, or ","-separated arity words +# +# # Paired "ratio-style" form: recognized only when every "|" piece is a single "name : glue" pair. +# ::= ( "|" )+ +# +# ::= ":" # the glue contains no ":" +# +# ::= text +# +# Precedence depends on the form: +# - Standard: split on ":" first (name vs. argument-glue options), then split each piece on "|" +# for terse|medium|verbose, and split only the name part on ";" for opening; main; closing. +# - Paired: split on "|" first into "name : glue" pairs, then verbosity selects one pair. +# +# Example: +# "absolute-value": "function= ; absolute value| the absolute value| the absolute value; end absolute value" +# "sum": "function=sum: over: from,to" +# "quotient": "function=integer part: divided by" +# "ratio": "function=ratio : to | the ratio : to | the ratio : to" # verbosity of name:glue pairs +# - IntentMappings: { "indexed-by": "infix= ; chỉ số dưới là; hết chỉ số dưới", "modified-variable": "silent= ", "say-super": "infix=chỉ số trên", # used with 'mo' for superscripts (e.g, "<") "skip-super": "silent=", # used with 'mo' for superscripts (e.g, "*") - "absolute-value": "function= ; trị tuyệt đối: trị tuyệt đối của: trị tuyệt đối của; hết trị tuyệt đối", + "absolute-value": "function= ; trị tuyệt đối| trị tuyệt đối của| trị tuyệt đối của; hết trị tuyệt đối", "binomial": "infix=nhị thức; chọn; hết nhị thức", "limit": "prefix=giới hạn", "lim-sup": "prefix=giới hạn trên khi", @@ -32,18 +101,18 @@ "plus": "infix=cộng || prefix=dương", "transpose": "postfix=ma trận chuyển vị || function=ma trận chuyển vị", - "norm": "function=; định mức: định mức: định mức của; end norm", - "trace": "function=;vết : vết: vết của; hết vết", - "dimension": "function=; kích thước : kích thước: kích thước của; hết kích thước", - "homomorphism": "function= ; đồng cấu : đồng cấu: đồng cấu của; hết đồng cấu", - "kernel": "function= ; hạch tâm : hạch tâm: hạch tâm của; hết hạch tâm", + "norm": "function=; định mức| định mức| định mức của; end norm", + "trace": "function=;vết | vết| vết của; hết vết", + "dimension": "function=; kích thước | kích thước| kích thước của; hết kích thước", + "homomorphism": "function= ; đồng cấu | đồng cấu| đồng cấu của; hết đồng cấu", + "kernel": "function= ; hạch tâm | hạch tâm| hạch tâm của; hết hạch tâm", "vector": "function=véc tơ || prefix=véc tơ", - "cross-product": "infix=hướng: tích có hướng: tích có hướng", - "dot-product": "infix=chấm: tích vô hướng: dot:tích vô hướng", + "cross-product": "infix=hướng| tích có hướng| tích có hướng", + "dot-product": "infix=chấm| tích vô hướng| dot|tích vô hướng", - "divergence": "function= ; phân kì: độ phân kì: độ phân kì; hết độ phân kì", + "divergence": "function= ; phân kì| độ phân kì| độ phân kì; hết độ phân kì", "curl": "function= ; vòng xoáy; hết vòng xoáy", - "gradient": "function= ; đạo hàm: đạo hàm: đạo hàm; hết đạo hàm", + "gradient": "function= ; đạo hàm| đạo hàm| đạo hàm; hết đạo hàm", "laplacian": "function=láp-la-xe", # speech engines don't do a good job with "laplacian" } diff --git a/Rules/Languages/zh/tw/definitions.yaml b/Rules/Languages/zh/tw/definitions.yaml index d5857679f..e79991b91 100644 --- a/Rules/Languages/zh/tw/definitions.yaml +++ b/Rules/Languages/zh/tw/definitions.yaml @@ -1,14 +1,83 @@ --- - include: "../../../definitions.yaml" -# If an "intent" is used, the 'terse:medium:verbose' speech for the intent name is given here for a prefix||infix||postfix||function||nofix||silent fixity -# If only one ":" is used, the first part is used for 'terse' and the second part is used for 'medium' and 'verbose' -# If no ":"s are used, the same speech is used for all forms -# If bracketing words make sense, they are separated with ";"s -# Intent mappings must specify whether they are "prefix", "infix", "postfix", or "function" with an "=" sign -# If there are multiple fixities (e.g., see transpose), they are separated with "|| -# for readability, spaces can be used around any of the delimiter characters -# Note: if there are multiple fixities, the first one is used if the fixity is not given in the intent +# IntentMappings Syntax: +# +# This section defines how each "intent" is spoken for various grammatical forms (fixities such as "prefix", "infix", "postfix", and "function"), +# along with supporting different verbosity levels. +# The syntax is a little bit complicated, but allows a declarative syntax so you don't have to write as many rules. +# +# For each intent, you specify spoken forms for one or more fixities using the syntax below. +# +# - Each mapping has the form: +# "": "= || = || ...", +# Every alternative must name a fixity and use "="; the fixity requested when speaking selects one. +# +# - Separate multiple fixities with "||". Spaces are allowed around any delimiter for readability. +# - Within a speech string, "|" selects the verbosity form: +# - one "|" (two forms): the first is 'terse', the second is used for 'medium' and 'verbose' +# - two "|" (three forms): 'terse', 'medium', 'verbose', in that order +# - no "|": the same spoken form is used for all verbosity levels +# +# - Use semicolons ";" to divide opening; main; closing bracketing words within the name part, +# where such words make sense (a name with no ";" is just the main phrase). +# - If an intent has multiple fixities but a definition does not specify one, the first fixity listed is chosen by default. +# +# Functions and argument glue (the part after the name): +# - ":" separates the name/bracketing phrase from the argument-glue options that follow it. +# - Arity template (two or more ":" options, or one option with ','-separated glue words): the +# number of glue words implies the arity, and the final argument is preceded by "of". +# Example: "sum: over: from,to" +# - 1 arg: "sum of x" +# - 2 args: "sum over i of x" +# - 3 args: "sum from i to n of x" +# If no option matches the argument count, the arguments are separated with "comma". +# - Binary separator (exactly one ":" option, no commas in it): after "of", that word joins the two args. +# Example: "quotient": "function=integer part: divided by" → "integer part of x divided by y" +# If there are not exactly two args, the arguments fall back to "comma". +# - Paired "ratio-style" (" : | : | ..."): used when every "|"-separated +# piece is a single "name : glue" pair. Verbosity selects one pair, whose glue is the binary +# separator described above. Example: "ratio": "function=ratio : to | the ratio : to | the ratio : to" +# +# Conceptual grammar (with precedence): +# +# IntentMappingsEntry ::= ":" # ":" is the YAML key/value separator +# +# ::= ( "||" )* +# +# ::= "=" +# +# ::= "prefix" | "infix" | "postfix" | "function" | "nofix" | "silent" +# +# ::= | +# +# # Standard form: a name/bracketing part, then ":"-separated argument-glue options. +# ::= ( ":" )* +# +# ::= [ ";" ";" ] # 1 part: name; 3 parts: opening; main; closing +# +# ::= [ "|" [ "|" ] ] # terse | medium | verbose +# +# ::= # a single glue word, or ","-separated arity words +# +# # Paired "ratio-style" form: recognized only when every "|" piece is a single "name : glue" pair. +# ::= ( "|" )+ +# +# ::= ":" # the glue contains no ":" +# +# ::= text +# +# Precedence depends on the form: +# - Standard: split on ":" first (name vs. argument-glue options), then split each piece on "|" +# for terse|medium|verbose, and split only the name part on ";" for opening; main; closing. +# - Paired: split on "|" first into "name : glue" pairs, then verbosity selects one pair. +# +# Example: +# "absolute-value": "function= ; absolute value| the absolute value| the absolute value; end absolute value" +# "sum": "function=sum: over: from,to" +# "quotient": "function=integer part: divided by" +# "ratio": "function=ratio : to | the ratio : to | the ratio : to" # verbosity of name:glue pairs +# - IntentMappings: { "binomial": "infix=; 選; ", @@ -36,14 +105,14 @@ "power":"infix=to the power", "root":"function=root", - "greatest-common-divisor": "function=gcd: the gcd: the greatest common divisor", - "least-common-multiple":"function=lcm: the lcm: the least common multiple", # In webpage typo "lest common" + "greatest-common-divisor": "function=gcd| the gcd| the greatest common divisor", + "least-common-multiple":"function=lcm| the lcm| the least common multiple", # In webpage typo "lest common" - "absolute-value": "function= ; absolute value: the absolute value: the absolute value; end absolute value", + "absolute-value": "function= ; absolute value| the absolute value| the absolute value; end absolute value", "complex-conjugate":"function=complex conjugate", "complex-arg":"function=arg", "real-part": "function=the real part", - "imaginary-part": "function=imaginary part: the imaginary part: the imaginary part", + "imaginary-part": "function=imaginary part| the imaginary part| the imaginary part", "polar-coordinate":"function=polar coordinate; comma", "spherical-coordinate":"function=spherical coordinate; comma; comma", @@ -67,27 +136,27 @@ ### Sets - "set": "function= ; set: the set", + "set": "function= ; set| the set", "set-difference":"function=set difference; and || infix=minus", # NOTE: not tested "complement":"function=complement", #"empty-set":"nofix=empty set", "cardinality":"function=cardinality", # NOTE: does not have a defined speech template in website "list":"function=list", - "tuple": "function= ; tuple: the tuple", + "tuple": "function= ; tuple| the tuple", ### Sequence and Series - "sum":"function= ; sum over : sum ; ", #: sum over : sum from; to", + "sum":"function= ; sum over | sum ; ", #: sum over : sum from; to", "product":"function=product || function=product over || function=product from; to", ### Elementary classical functions - "sine":"function=sin: sine", - "cosine":"function=cos: cosine", - "tangent":"function=tan: tangent", - "secant":"function=seech: secant", - "cosecant":"function=co-seech: cosecant", - "cotangent":"function=co-tan: cotangent", + "sine":"function=sin| sine", + "cosine":"function=cos| cosine", + "tangent":"function=tan| tangent", + "secant":"function=seech| secant", + "cosecant":"function=co-seech| cosecant", + "cotangent":"function=co-tan| cotangent", "arcsine":"function=arcsine", "arccosine":"function=arccosine", @@ -111,7 +180,7 @@ "arc-hyperbolic-cotangent":"function=arc coth", "exponential":"function=exponential", - "natural-logarithm": "function=l n: natural log: natural log", + "natural-logarithm": "function=l n| natural log| natural log", "logarithm":"function=log", ##Check arity 2 @@ -131,7 +200,7 @@ "determinant":"function=determinant", "adjugate":"function=adjugate", "magnitude":"function=magnitude", - "norm": "function=; norm: norm: norm; 結束 norm", + "norm": "function=; norm| norm| norm; 結束 norm", "span":"function=span", "unit-vector":"prefix=unit vector", @@ -142,12 +211,12 @@ ### Constants and Sets - "set-of-integers":"nofix=ℤ: set of all integers", - "set-of-reals":"nofix=ℝ: set of all real numbers", - "set-of-rationals":"nofix=ℚ: set of all rational numbers", - "set-of-natural-numbers":"nofix=ℕ: set of all natural numbers", - "set-of-complex-numbers":"nofix=ℂ: set of all complex numbers", - "set-of-primes":"nofix=ℙ: set of all prime numbers", + "set-of-integers":"nofix=ℤ| set of all integers", + "set-of-reals":"nofix=ℝ| set of all real numbers", + "set-of-rationals":"nofix=ℚ| set of all rational numbers", + "set-of-natural-numbers":"nofix=ℕ| set of all natural numbers", + "set-of-complex-numbers":"nofix=ℂ| set of all complex numbers", + "set-of-primes":"nofix=ℙ| set of all prime numbers", ### Geometry @@ -192,8 +261,8 @@ ### Other ## Default fixity function "curl": "function=curl", - "divergence": "function=div:divergence", - "gradient": "function=del:gradient", + "divergence": "function=div|divergence", + "gradient": "function=del|gradient", "laplacian": "function=laplacian", ## Default fixity prefix @@ -218,7 +287,7 @@ "congruent": "infix=congruent to", "cartesian-product": "infix=cartesian product", "composed-with": "infix=composed with", - "cross-product": "infix=cross: cross product: cross product", + "cross-product": "infix=cross| cross product| cross product", "defined-as": "infix=defined as", "divided-by": "infix=divided by", "divides": "infix=divides", @@ -282,11 +351,11 @@ "percent": "postfix=percent", ## Default fixity nofix - "diameter":"nofix=d: diameter", - "distance":"nofix=d; D: distance", - "probability":"nofix=P: probability", - "radius":"nofix=r: radius", - "volume":"nofix=V: volume || function=volume", + "diameter":"nofix=d| diameter", + "distance":"nofix=d; D| distance", + "probability":"nofix=P| probability", + "radius":"nofix=r| radius", + "volume":"nofix=V| volume || function=volume", "exponential-e":"nofix=e", "imaginary-i":"nofix=i", "differential-d":"nofix=d", @@ -298,16 +367,16 @@ "say-super": "infix=上標", # used with 'mo' for superscripts (e.g, "<") "skip-super": "silent=", # used with 'mo' for superscripts (e.g, "*") # "large-op": "infix=over || other=from,to", - "lim-sup": "prefix=lim sup as: the limit superior as: the limit superior as", - "lim-inf": "prefix=lim inf as: the limit inferior as : the limit inferior as", + "lim-sup": "prefix=lim sup as| the limit superior as| the limit superior as", + "lim-inf": "prefix=lim inf as| the limit inferior as | the limit inferior as", "logarithm-with-base": "prefix=log 底數", #"prefix=log base: the log base: the log base", # "pochhammer": "infix=permutations of", # arguments are in reverse order, so can't work here - "trace": "function= ; trace : trace: trace; 結束 trace", - "dimension": "function=; dimension : dimension: dimension; 結束 dimension", - "homomorphism": "function= ; homomorphism : homomorphism: homomorphism; 結束 homomorphism", - "kernel": "function= ; kernel : kernel: kernel; 結束 kernel", + "trace": "function= ; trace | trace| trace; 結束 trace", + "dimension": "function=; dimension | dimension| dimension; 結束 dimension", + "homomorphism": "function= ; homomorphism | homomorphism| homomorphism; 結束 homomorphism", + "kernel": "function= ; kernel | kernel| kernel; 結束 kernel", - "chemistry-concentration": "function= ; concentration: concentration of: the concentration of; end concentration", + "chemistry-concentration": "function= ; concentration| concentration of| the concentration of; end concentration", } # Names of functions that in terse mode don't say "of" (or it's equivalent in other languages) diff --git a/Rules/Languages/zz/definitions.yaml b/Rules/Languages/zz/definitions.yaml index 592871ab4..27966dc68 100644 --- a/Rules/Languages/zz/definitions.yaml +++ b/Rules/Languages/zz/definitions.yaml @@ -7,30 +7,99 @@ # - name: [] "...", "..." "..." ] -# If an "intent" is used, the 'terse:medium:verbose' speech for the intent name is given here for a prefix||infix||postfix||function fixity -# If only one ":" is used, it the first part is used for 'terse' and the second part is used for 'medium' and 'verbose' -# If no ":"s are used, the same speech is used for all forms -# If bracketing words make sense, they are separated with ";"s -# Intent mappings must specify whether they are "prefix", "infix", "postfix", or "function" with an "=" sign -# If there are multiple fixities (e.g., see transpose), they are separated with "|| -# for readability, spaces can be used around any of the delimiter characters -# Note: if there are multiple fixities, the first one is used if the fixity is not given in the intent +# IntentMappings Syntax: +# +# This section defines how each "intent" is spoken for various grammatical forms (fixities such as "prefix", "infix", "postfix", and "function"), +# along with supporting different verbosity levels. +# The syntax is a little bit complicated, but allows a declarative syntax so you don't have to write as many rules. +# +# For each intent, you specify spoken forms for one or more fixities using the syntax below. +# +# - Each mapping has the form: +# "": "= || = || ...", +# Every alternative must name a fixity and use "="; the fixity requested when speaking selects one. +# +# - Separate multiple fixities with "||". Spaces are allowed around any delimiter for readability. +# - Within a speech string, "|" selects the verbosity form: +# - one "|" (two forms): the first is 'terse', the second is used for 'medium' and 'verbose' +# - two "|" (three forms): 'terse', 'medium', 'verbose', in that order +# - no "|": the same spoken form is used for all verbosity levels +# +# - Use semicolons ";" to divide opening; main; closing bracketing words within the name part, +# where such words make sense (a name with no ";" is just the main phrase). +# - If an intent has multiple fixities but a definition does not specify one, the first fixity listed is chosen by default. +# +# Functions and argument glue (the part after the name): +# - ":" separates the name/bracketing phrase from the argument-glue options that follow it. +# - Arity template (two or more ":" options, or one option with ','-separated glue words): the +# number of glue words implies the arity, and the final argument is preceded by "of". +# Example: "sum: over: from,to" +# - 1 arg: "sum of x" +# - 2 args: "sum over i of x" +# - 3 args: "sum from i to n of x" +# If no option matches the argument count, the arguments are separated with "comma". +# - Binary separator (exactly one ":" option, no commas in it): after "of", that word joins the two args. +# Example: "quotient": "function=integer part: divided by" → "integer part of x divided by y" +# If there are not exactly two args, the arguments fall back to "comma". +# - Paired "ratio-style" (" : | : | ..."): used when every "|"-separated +# piece is a single "name : glue" pair. Verbosity selects one pair, whose glue is the binary +# separator described above. Example: "ratio": "function=ratio : to | the ratio : to | the ratio : to" +# +# Conceptual grammar (with precedence): +# +# IntentMappingsEntry ::= ":" # ":" is the YAML key/value separator +# +# ::= ( "||" )* +# +# ::= "=" +# +# ::= "prefix" | "infix" | "postfix" | "function" | "nofix" | "silent" +# +# ::= | +# +# # Standard form: a name/bracketing part, then ":"-separated argument-glue options. +# ::= ( ":" )* +# +# ::= [ ";" ";" ] # 1 part: name; 3 parts: opening; main; closing +# +# ::= [ "|" [ "|" ] ] # terse | medium | verbose +# +# ::= # a single glue word, or ","-separated arity words +# +# # Paired "ratio-style" form: recognized only when every "|" piece is a single "name : glue" pair. +# ::= ( "|" )+ +# +# ::= ":" # the glue contains no ":" +# +# ::= text +# +# Precedence depends on the form: +# - Standard: split on ":" first (name vs. argument-glue options), then split each piece on "|" +# for terse|medium|verbose, and split only the name part on ";" for opening; main; closing. +# - Paired: split on "|" first into "name : glue" pairs, then verbosity selects one pair. +# +# Example: +# "absolute-value": "function= ; absolute value| the absolute value| the absolute value; end absolute value" +# "sum": "function=sum: over: from,to" +# "quotient": "function=integer part: divided by" +# "ratio": "function=ratio : to | the ratio : to | the ratio : to" # verbosity of name:glue pairs +# - IntentMappings: { "absolute-value": "function=absolute value", "binomial": "infix=binomial; choose; end binomial", "closed-interval": "other=closed-interval;from,to;end closed-interval", - "dot-product": "infix=dot:dot product:dot product", - "greatest-common-divisor": "function=gcd: the gcd: the greatest common divisor", + "dot-product": "infix=dot|dot product|dot product", + "greatest-common-divisor": "function=gcd| the gcd| the greatest common divisor", "imaginary-part": "function=imaginary part, the imaginary part, the imaginary part", - "least-common-multiple": "function=lcm:the lcm:the least common multiple", + "least-common-multiple": "function=lcm|the lcm|the least common multiple", "large-op:2": "infix=over", "large-op:3": "other=from,to", "real-part": "function=the real part", "transpose": "postfix=transpose || function=transpose", - "divergence": "function= ; div: divergence: divergence; end divergence", + "divergence": "function= ; div| divergence| divergence; end divergence", "curl": "function= ; curl; end curl", - "gradient": "function= ; grad: gradient: gradient; end gradient", + "gradient": "function= ; grad| gradient| gradient; end gradient", "laplacian": "function=lahplahsian", # speech engines don't do a good job with "laplacian" } diff --git a/src/infer_intent.rs b/src/infer_intent.rs index 81cbb9933..251be6674 100644 --- a/src/infer_intent.rs +++ b/src/infer_intent.rs @@ -215,158 +215,224 @@ pub fn add_fixity_children(intent: Element) -> Element { } } -pub fn intent_speech_for_name(intent_name: &str, verbosity: &str, fixity: &str) -> String { - crate::definitions::SPEECH_DEFINITIONS.with(|definitions| { - let definitions = definitions.borrow(); - if let Some(intent_name_pattern) = definitions.get_hashmap("IntentMappings").unwrap().get(intent_name) { - // Split the pattern is: - // fixity-def [|| fixity-def]* - // fixity-def := fixity=[open;] verbosity[; close] [| arity-or-sep]* - // verbosity := terse | medium | verbose - // After '|': arity templates (glue words, ','-separated) or a single repeating separator - if let Some(matched_intent) = intent_name_pattern.split("||").find(|&entry| entry.trim().starts_with(fixity)) { - let (_, matched_intent) = matched_intent.split_once("=").unwrap_or_default(); - let name_part = intent_mapping_name_part(matched_intent); - let parts = name_part.split(";").collect::>(); - let mut operator_names = (if parts.len() > 1 {parts[1]} else {parts[0]}).split(":").collect::>(); - match operator_names.len() { - 1 => return operator_names[0].trim().to_string(), - 2 | 3 => { - if operator_names.len() == 2 { - warn!("Intent '{intent_name}' has only two operator names, but should have three"); - operator_names.push(operator_names[1]); - } - let intent_word = match verbosity { - "Terse" => operator_names[0], - "Medium" => operator_names[1], - _ => operator_names[2], - }; - return intent_word.trim().to_string(); - }, - _ => { - error!("Intent '{}' has too many ({}) operator names, should only have 2", intent_name, operator_names.len()); - return intent_name.to_string(); - }, - } - } - }; - return intent_name.replace(['_', '-'], " ").trim().to_string(); - }) +// ------------------------------------------------------------------------------------------------- +// IntentMappings parsing +// +// A mapping value is `fixity= [|| fixity2= ...]`. Each `` is parsed by +// `parse_fixity_mapping` into a `FixityMapping` (resolved for the current verbosity). Two forms +// are supported: +// * Standard: `[open;] name [;close] [: glue]*` +// `|` inside any piece selects terse|medium|verbose. The `:`-separated glue +// options describe how arguments are joined (arity templates or a binary word). +// * Ratio-style: `name : glue | name2 : glue2 | ...` +// each `|`-alternative is a whole `name : glue` pair and verbosity picks one. +// All the query functions below operate on the parsed `FixityMapping`, so the delimiter rules +// live in exactly one place. +// ------------------------------------------------------------------------------------------------- + +/// A fixity mapping (`fixity=...` text) parsed and resolved for one verbosity level. +struct FixityMapping { + /// Bracketing phrase spoken before the arguments (only present for an `open; name; close` form). + open: String, + /// The main spoken name/phrase. + name: String, + /// Bracketing phrase spoken after the arguments. + close: String, + /// Argument-glue options (the `:`-separated parts after the name). An arity template has one + /// entry per supported arity (comma-separated glue words); a binary separator is a single entry + /// with no comma; a plain function has none. + glue: Vec, } -/// Portion of a fixity mapping before `|` arity/separator options. -pub fn intent_mapping_name_part(matched_after_equals: &str) -> &str { - matched_after_equals.split('|').next().unwrap_or(matched_after_equals).trim() +pub fn intent_speech_for_name(intent_name: &str, verbosity: &str, fixity: &str) -> String { + match fixity_mapping(intent_name, fixity, verbosity) { + Some(mapping) => mapping.name, + None => intent_name.replace(['_', '-'], " ").trim().to_string(), + } } -/// `|` options after the spoken-name portion of a fixity mapping. -fn intent_mapping_pipe_options(matched_after_equals: &str) -> Vec<&str> { - let mut parts = matched_after_equals.split('|'); - parts.next(); // name / bracketing portion - parts.map(str::trim).filter(|s| !s.is_empty()).collect() +/// Bracketing phrase for an intent's `open; name; close` speech form. `at_start` selects the +/// opening phrase, otherwise the closing one. Empty when the mapping has no bracketing or the +/// fixity is not found. +pub fn intent_bracketing_word(intent_name: &str, fixity: &str, verbosity: &str, at_start: bool) -> String { + match fixity_mapping(intent_name, fixity, verbosity) { + Some(mapping) => if at_start { mapping.open } else { mapping.close }, + None => String::new(), + } } -fn intent_mapping_for_fixity(intent_name: &str, fixity: &str) -> Option { +/// Look up `intent_name`'s body for `fixity` and parse it, resolving `|` variants for `verbosity`. +fn fixity_mapping(intent_name: &str, fixity: &str, verbosity: &str) -> Option { crate::definitions::SPEECH_DEFINITIONS.with(|definitions| { let definitions = definitions.borrow(); let mappings = definitions.get_hashmap("IntentMappings").unwrap(); - let intent_name_pattern = mappings.get(intent_name)?; - let matched = intent_name_pattern.split("||").find(|&entry| entry.trim().starts_with(fixity))?; - let (_, after_eq) = matched.split_once("=")?; - Some(after_eq.trim().to_string()) + let pattern = mappings.get(intent_name)?; + let body = pattern.split("||").find(|entry| entry.trim().starts_with(fixity))?; + let (_, after_eq) = body.split_once('=')?; + Some(parse_fixity_mapping(after_eq.trim(), verbosity)) }) } -/// True when `|` options are arity templates (more than one option, or an option listing multiple glue words). -pub fn intent_function_is_arity_mode(intent_name: &str, fixity: &str) -> bool { - let Some(after_eq) = intent_mapping_for_fixity(intent_name, fixity) else { return false; }; - let options = intent_mapping_pipe_options(&after_eq); - options.len() > 1 || options.iter().any(|opt| opt.contains(',')) +fn parse_fixity_mapping(after_eq: &str, verbosity: &str) -> FixityMapping { + // Ratio-style: `name : glue | name2 : glue2 | ...` — verbosity picks one (name, glue) pair. + if let Some((name, glue)) = ratio_style_pair(after_eq, verbosity) { + return FixityMapping { open: String::new(), name, close: String::new(), glue: vec![glue] }; + } + + // Standard: the name/bracketing part (before the first `:`), then argument-glue options. + let mut sections = after_eq.split(':'); + let (open, name, close) = split_bracketing(sections.next().unwrap_or_default()); + let glue = sections + .map(str::trim) + .filter(|s| !s.is_empty()) + .map(|option| pick_verbosity(option, verbosity)) + .collect(); + FixityMapping { + open: pick_verbosity(open, verbosity), + name: pick_verbosity(name, verbosity), + close: pick_verbosity(close, verbosity), + glue, + } } -/// Glue words for an exact arity match: `arg_count - 1` words, else `None`. -fn intent_function_arity_glue(after_eq: &str, arg_count: usize) -> Option> { - if arg_count == 0 { +/// Split the name portion into `(open, name, close)` on `;`. Bracketing words are only present +/// when there are exactly three parts; otherwise the second part (if any) is the name. +fn split_bracketing(speech_part: &str) -> (&str, &str, &str) { + let parts: Vec<&str> = speech_part.split(';').collect(); + match parts.len() { + 1 => ("", parts[0], ""), + 3 => (parts[0], parts[1], parts[2]), + _ => ("", parts.get(1).copied().unwrap_or_default(), ""), + } +} + +/// The index into a `|`-separated option (or ratio-style pair list) for `verbosity`, clamped to +/// the number of available forms: terse=0, medium=1, verbose=2. +fn verbosity_index(verbosity: &str, len: usize) -> usize { + match verbosity { + _ if len <= 1 => 0, + "Terse" => 0, + "Medium" => 1.min(len - 1), + _ => 2.min(len - 1), + } +} + +/// Selects the form for `verbosity` from a `|`-separated option, e.g. `sin | sine` or `to | to`. +fn pick_verbosity(option: &str, verbosity: &str) -> String { + let forms: Vec<&str> = option.split('|').map(str::trim).filter(|s| !s.is_empty()).collect(); + match forms.as_slice() { + [] => String::new(), + _ => forms[verbosity_index(verbosity, forms.len())].to_string(), + } +} + +/// Ratio-style mapping: `name : glue | name2 : glue2 | ...`. Returns the (name, glue) pair for +/// `verbosity`, or `None` if the text is not a set of `name : glue` alternatives. +fn ratio_style_pair(after_eq: &str, verbosity: &str) -> Option<(String, String)> { + let alternatives: Vec<&str> = after_eq.split('|').map(str::trim).filter(|s| !s.is_empty()).collect(); + if alternatives.len() < 2 { return None; } - let want = arg_count - 1; - for opt in intent_mapping_pipe_options(after_eq) { - let words: Vec<&str> = if opt.is_empty() { - Vec::new() - } else { - opt.split(',').map(str::trim).filter(|s| !s.is_empty()).collect() - }; - if words.len() == want { - return Some(words); - } + let pairs: Vec<(&str, &str)> = alternatives.iter() + .map(|alternative| { + let (name, glue) = alternative.split_once(':')?; + let glue = glue.trim(); + (!glue.is_empty() && !glue.contains(':')).then_some((name.trim(), glue)) + }) + .collect::>()?; + let (name, glue) = pairs[verbosity_index(verbosity, pairs.len())]; + Some((name.to_string(), glue.to_string())) +} + +fn get_verbosity_pref() -> String { + PreferenceManager::get().borrow().pref_to_string("Verbosity") +} + +/// A binary separator is a single glue option with no comma (e.g. `integer part: divided by`). +fn binary_separator(mapping: &FixityMapping) -> Option<&str> { + match mapping.glue.as_slice() { + [only] if !only.contains(',') => Some(only), + _ => None, } - None } -pub fn intent_function_has_arity_match(intent_name: &str, fixity: &str, arg_count: usize) -> bool { - let Some(after_eq) = intent_mapping_for_fixity(intent_name, fixity) else { return false; }; - if !intent_function_is_arity_mode(intent_name, fixity) { - return false; +/// True when the glue is an arity template (multiple options, or one option with comma-separated +/// glue words) rather than a binary separator or a plain function. +fn is_arity_mode(mapping: &FixityMapping) -> bool { + binary_separator(mapping).is_none() + && (mapping.glue.len() > 1 || mapping.glue.iter().any(|option| option.contains(','))) +} + +/// The glue words for an exact arity match: the option with `arg_count - 1` comma-separated words. +fn arity_glue(mapping: &FixityMapping, arg_count: usize) -> Option> { + if arg_count == 0 || binary_separator(mapping).is_some() { + return None; } - intent_function_arity_glue(&after_eq, arg_count).is_some() + let want = arg_count - 1; + mapping.glue.iter().find_map(|option| { + let words: Vec<&str> = option.split(',').map(str::trim).filter(|s| !s.is_empty()).collect(); + (words.len() == want).then_some(words) + }) } -/// Spoken glue immediately before argument `arg_index` (1-based) when using an arity template. -/// Empty when not in a matching arity template (caller uses separator/`of` path instead). + +/// Whether the function intent matches an arity-template pattern for the current argument count. +pub fn intent_function_has_arity_match(intent_name: &str, fixity: &str, arg_count: usize) -> bool { + let verbosity = get_verbosity_pref(); + let Some(mapping) = fixity_mapping(intent_name, fixity, &verbosity) else { return false; }; + is_arity_mode(&mapping) && arity_glue(&mapping, arg_count).is_some() +} + +/// Returns the glue word immediately before a specific argument when using an arity template. pub fn intent_function_glue_before(intent_name: &str, fixity: &str, arg_index: usize, arg_count: usize) -> String { - if !intent_function_is_arity_mode(intent_name, fixity) { + let verbosity = get_verbosity_pref(); + let Some(mapping) = fixity_mapping(intent_name, fixity, &verbosity) else { return String::new(); }; + if !is_arity_mode(&mapping) { return String::new(); } if arg_index == arg_count { - return crate::definitions::SPEECH_DEFINITIONS.with(|definitions| { - let definitions = definitions.borrow(); - let word_ref = definitions.get_vec("FunctionApplicationWord"); - if let Some(word) = word_ref && !word.is_empty() { - return word[0].clone(); - } - return String::new(); - }) + return function_application_word(); // last argument is preceded by "of" } - let Some(after_eq) = intent_mapping_for_fixity(intent_name, fixity) else { return String::new(); }; - let Some(words) = intent_function_arity_glue(&after_eq, arg_count) else { return String::new(); }; - // words has arg_count-1 entries for args 1..arg_count-1; last arg is preceded by "of" - if arg_index >= 1 && arg_index < arg_count { - return words[arg_index - 1].to_string(); + match arity_glue(&mapping, arg_count) { + Some(words) if (1..arg_count).contains(&arg_index) => words[arg_index - 1].to_string(), + _ => String::new(), } - return String::new(); } -/// Separator between args when not using an arity template. -/// A single `|` option is a binary separator after "of" (e.g. `| divided by`); otherwise comma. -/// Non-comma glue is only used when there are exactly two args — there is no real n-ary case for it. +/// Returns the separator used between arguments when not using an arity-template path. pub fn intent_function_arg_separator(intent_name: &str, fixity: &str, arg_count: usize) -> String { - let Some(after_eq) = intent_mapping_for_fixity(intent_name, fixity) else { - return ",".to_string(); - }; - let options = intent_mapping_pipe_options(&after_eq); - if intent_function_is_arity_mode(intent_name, fixity) { - // Extra/unknown arity: always commas (including when multiple arity options exist) - if intent_function_arity_glue(&after_eq, arg_count).is_some() { - return String::new(); // unused on arity-match path - } - return ",".to_string(); - } - if options.len() == 1 && arg_count == 2 { - let sep = options[0]; - // IntentMappings write the word "comma"; speech uses the ',' character so unicode → "comma" - if sep.eq_ignore_ascii_case("comma") { - return ",".to_string(); + let verbosity = get_verbosity_pref(); + let Some(mapping) = fixity_mapping(intent_name, fixity, &verbosity) else { return ",".to_string(); }; + if is_arity_mode(&mapping) { + // On an exact arity match the glue words are inserted individually (no separator). + return if arity_glue(&mapping, arg_count).is_some() { String::new() } else { ",".to_string() }; + } + if arg_count == 2 { + if let Some(separator) = binary_separator(&mapping) { + if !separator.eq_ignore_ascii_case("comma") { + return separator.to_string(); + } } - return sep.to_string(); } ",".to_string() } -/// Whether function-intent should use the arity-template word order (no trailing name-level "of"). +/// Returns true when the function-intent should use the arity-template word order instead of +/// a generic `of`/separator pattern. pub fn intent_function_use_arity_path(intent_name: &str, fixity: &str, arg_count: usize) -> bool { intent_function_has_arity_match(intent_name, fixity, arg_count) } +/// The word inserted before a function's final argument (e.g. English "of"), from definitions. +fn function_application_word() -> String { + crate::definitions::SPEECH_DEFINITIONS.with(|definitions| { + let definitions = definitions.borrow(); + definitions.get_vec("FunctionApplicationWord") + .and_then(|words| words.first().cloned()) + .unwrap_or_default() + }) +} + // intent := self-property-list | expression @@ -883,6 +949,44 @@ mod tests { return Ok(()); } + #[test] + fn parse_intent_mapping_forms() -> Result<()> { + use super::{parse_fixity_mapping, ratio_style_pair, pick_verbosity, binary_separator, is_arity_mode, arity_glue}; + + // Ratio-style: verbosity selects a whole `name : glue` pair; glue acts as a binary separator. + let ratio = "ratio : to | the ratio : to | the ratio : to"; + assert_eq!(ratio_style_pair(ratio, "Terse"), Some(("ratio".to_string(), "to".to_string()))); + assert_eq!(ratio_style_pair(ratio, "Medium"), Some(("the ratio".to_string(), "to".to_string()))); + let ratio_terse = parse_fixity_mapping(ratio, "Terse"); + assert_eq!(ratio_terse.name, "ratio"); + assert_eq!(binary_separator(&ratio_terse), Some("to")); + assert!(!is_arity_mode(&ratio_terse)); + assert_eq!(arity_glue(&ratio_terse, 2), None); + + // `|` selects terse/medium/verbose within one piece. + assert_eq!(pick_verbosity("sin | sine", "Terse"), "sin"); + assert_eq!(pick_verbosity("sin | sine", "Medium"), "sine"); + + // Arity template: `:`-separated glue options, `,`-separated glue words imply arity. + let sum = parse_fixity_mapping("sum: over: from,to", "Medium"); + assert_eq!(sum.name, "sum"); + assert_eq!(sum.glue, vec!["over".to_string(), "from,to".to_string()]); + assert!(is_arity_mode(&sum)); + assert_eq!(arity_glue(&sum, 3), Some(vec!["from", "to"])); + assert_eq!(arity_glue(&sum, 1), None); // no zero-word option -> falls back to "of" + + // Binary separator: a single non-comma glue option. + let quotient = parse_fixity_mapping("integer part: divided by", "Medium"); + assert_eq!(quotient.name, "integer part"); + assert_eq!(binary_separator("ient), Some("divided by")); + assert!(!is_arity_mode("ient)); + + // Bracketing: `open; name; close`, with `|` verbosity inside the name. + let norm = parse_fixity_mapping("; norm| norm| norm; end norm", "Verbose"); + assert_eq!((norm.open.as_str(), norm.name.as_str(), norm.close.as_str()), ("", "norm", "end norm")); + Ok(()) + } + #[test] fn silent_underscore() -> Result<()> { let mathml = "silent+e"; diff --git a/src/xpath_functions.rs b/src/xpath_functions.rs index 29215c65f..b917e68ea 100644 --- a/src/xpath_functions.rs +++ b/src/xpath_functions.rs @@ -24,7 +24,7 @@ use crate::definitions::{Definitions, SPEECH_DEFINITIONS, BRAILLE_DEFINITIONS}; use regex::Regex; use crate::pretty_print::mml_to_string; use std::{cell::{Ref, RefCell}, collections::HashMap}; -use log::{debug, error, warn}; +use log::debug; use std::sync::LazyLock; use std::thread::LocalKey; use phf::phf_set; @@ -1323,46 +1323,9 @@ pub struct GetBracketingIntentName; /// This is used to wrap expressions like "the floor of x" rather than just speaking the bare function name. impl GetBracketingIntentName { fn bracketing_words(intent_name: &str, verbosity: &str, fixity: &str, at_start: bool) -> String { - crate::definitions::SPEECH_DEFINITIONS.with(|definitions| { - let definitions = definitions.borrow(); - if let Some(intent_name_pattern) = definitions.get_hashmap("IntentMappings").unwrap().get(intent_name) { - // Split the pattern is: fixity-def [|| fixity-def]* - // fixity-def := fixity=open; verbosity; close - // verbosity := terse | medium | verbose - if let Some(matched_intent) = intent_name_pattern.split("||").find(|&entry| entry.trim().starts_with(fixity)) { - let (_, matched_intent) = matched_intent.split_once("=").unwrap_or_default(); - let name_part = crate::infer_intent::intent_mapping_name_part(matched_intent); - let parts = name_part.split(";").collect::>(); - if parts.len() == 1 { - return "".to_string(); - } - if parts.len() != 3 { - error!("Intent '{}' has {} ';' separated parts, should have 3", intent_name, parts.len()); - return "".to_string(); - } - let mut speech = (if at_start {parts[0]} else {parts[2]}).split(":").collect::>(); - match speech.len() { - 1 => return speech[0].to_string(), - 2 | 3 => { - if speech.len() == 2 { - warn!("Intent '{intent_name}' has only two ':' separated parts, but should have three"); - speech.push(speech[1]); - } - let bracketing_words = match verbosity { - "Terse" => speech[0], - "Medium" => speech[1], - _ => speech[2], - }; - return bracketing_words.to_string(); - }, - _ => { - error!("Intent '{}' has too many ({}) operator names, should only have 2", intent_name, speech.len()); - }, - } - } - }; - return "".to_string(); - }) + // Bracketing words come from the `open; name; close` form of a fixity mapping; the + // parsing lives in infer_intent so all IntentMappings delimiter rules stay in one place. + crate::infer_intent::intent_bracketing_word(intent_name, fixity, verbosity, at_start) } } diff --git a/tests/Languages/en/definitions.rs b/tests/Languages/en/definitions.rs index adbae499c..8f7577c4d 100644 --- a/tests/Languages/en/definitions.rs +++ b/tests/Languages/en/definitions.rs @@ -79,6 +79,24 @@ fn floor_basic() -> Result<()> { Ok(()) } +#[test] +fn ratio_function_basic() -> Result<()> { + let expr = r#" + + + 6 + 3 + + + "#; + + test_prefs("en", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "ratio 6 to 3")?; + test_prefs("en", "ClearSpeak", vec![("Verbosity", "Medium")], expr, "the ratio of 6 to 3")?; + test_prefs("en", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, "the ratio of 6 to 3")?; + test("en", "ClearSpeak", expr, "the ratio of 6 to 3")?; + Ok(()) +} + #[test] fn set_difference_basic() -> Result<()> { let expr = r#" @@ -944,7 +962,7 @@ fn infix_default_fixity_tests() -> Result<()> { ("precedes", "x precedes y"), ("proportional", "x proportional to y"), ("range-separator", "x through y"), - ("ratio", "x ratio y"), + ("ratio", "the ratio of x to y"), ("similar", "x similar to y"), ("subset", "x subset of y"), ("subset-or-equal", "x subset or equal to y"), From 762d492901c6b97cf58f77f5bd1bc1720230113c Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Wed, 30 Sep 2026 00:15:35 -0700 Subject: [PATCH 153/157] shorten 'ratio' def after debugging --- Rules/Languages/en/definitions.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rules/Languages/en/definitions.yaml b/Rules/Languages/en/definitions.yaml index 677d7c78c..fc18be07f 100644 --- a/Rules/Languages/en/definitions.yaml +++ b/Rules/Languages/en/definitions.yaml @@ -327,7 +327,7 @@ "precedes": "infix=precedes", "proportional": "infix=proportional to", "range-separator": "infix=through", - "ratio": "function=ratio : to | the ratio : to | the ratio : to", + "ratio": "function=ratio : to | the ratio : to", "similar": "infix=similar to", "subset": "infix=subset of", "subset-or-equal": "infix=subset or equal to", From a3de867933ecfb05ec90c406b008d15f7baf6c91 Mon Sep 17 00:00:00 2001 From: nsoiffer Date: Wed, 30 Sep 2026 00:32:24 -0700 Subject: [PATCH 154/157] fix clippy warnings (about comments) --- src/infer_intent.rs | 11 +++++------ src/xpath_functions.rs | 6 ++++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/infer_intent.rs b/src/infer_intent.rs index 251be6674..79f813d84 100644 --- a/src/infer_intent.rs +++ b/src/infer_intent.rs @@ -407,12 +407,11 @@ pub fn intent_function_arg_separator(intent_name: &str, fixity: &str, arg_count: // On an exact arity match the glue words are inserted individually (no separator). return if arity_glue(&mapping, arg_count).is_some() { String::new() } else { ",".to_string() }; } - if arg_count == 2 { - if let Some(separator) = binary_separator(&mapping) { - if !separator.eq_ignore_ascii_case("comma") { - return separator.to_string(); - } - } + if arg_count == 2 + && let Some(separator) = binary_separator(&mapping) + && !separator.eq_ignore_ascii_case("comma") + { + return separator.to_string(); } ",".to_string() } diff --git a/src/xpath_functions.rs b/src/xpath_functions.rs index b917e68ea..d4b174adf 100644 --- a/src/xpath_functions.rs +++ b/src/xpath_functions.rs @@ -1204,6 +1204,7 @@ pub struct SpeakIntentName; /// 1. intentName: the intent name, e.g. "factorial" or "ratio" /// 2. verbosity: "Terse", "Medium", or "Verbose" /// 3. fixity: the function fixity, e.g. "prefix", "infix", "postfix" +/// /// Example: /// SpeakIntentName("factorial", "Verbose", "postfix") -> "factorial" /// SpeakIntentName("ratio", "Medium", "infix") -> "ratio" @@ -1230,6 +1231,7 @@ pub struct IntentFunctionUseArityPath; /// 1. intentName: the intent name, e.g. "choose" or "ratio" /// 2. fixity: the function fixity, e.g. "function" or "postfix" /// 3. argCount: the number of arguments supplied to the function +/// /// Example: /// IntentFunctionUseArityPath("choose", "function", 3) -> true /// IntentFunctionUseArityPath("ratio", "function", 2) -> false @@ -1259,6 +1261,7 @@ pub struct IntentFunctionGlueBefore; /// 2. fixity: the function fixity, e.g. "function" /// 3. argIndex: the 1-based argument position to inspect /// 4. argCount: the total number of arguments in the call +/// /// Example: /// IntentFunctionGlueBefore("choose", "function", 2, 3) -> "from" /// IntentFunctionGlueBefore("choose", "function", 3, 3) -> "to" @@ -1288,6 +1291,7 @@ pub struct IntentFunctionArgSeparator; /// 1. intentName: the intent name, e.g. "ratio" or "gcd" /// 2. fixity: the function fixity, e.g. "function" /// 3. argCount: the number of arguments supplied to the function +/// /// Example: /// IntentFunctionArgSeparator("ratio", "function", 2) -> "to" /// IntentFunctionArgSeparator("gcd", "function", 2) -> "and" @@ -1318,6 +1322,7 @@ pub struct GetBracketingIntentName; /// 2. fixity: the fixity, e.g. "prefix" or "postfix" /// 3. verbosity: "Terse", "Medium", or "Verbose" /// 4. startOrEnd: either "start" or "end" +/// /// Example: /// GetBracketingIntentName("floor", "prefix", "Medium", "start") -> "the floor of" /// This is used to wrap expressions like "the floor of x" rather than just speaking the bare function name. @@ -1354,6 +1359,7 @@ pub struct GetNavigationPartName; /// Calling arguments (as used by the rule layer): /// 1. intentName: the intent name, e.g. "fraction" or "power" /// 2. index: the 0-based position of the part to speak +/// /// Example: /// GetNavigationPartName("fraction", 0) -> "numerator" /// GetNavigationPartName("fraction", 1) -> "denominator" From e1692f01841ab6fcfeb0f8d879507d0f294fc6b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Thu, 1 Oct 2026 01:52:38 +0200 Subject: [PATCH 155/157] Normalize tracked files to match .gitattributes (#843) --- Rules/Braille/CMU/unicode-full.yaml | 470 +- Rules/Braille/CMU/unicode.yaml | 1396 ++-- Rules/Braille/Nemeth/unicode.yaml | 704 +-- Rules/Braille/UEB/unicode.yaml | 902 +-- Rules/Braille/Vietnam/unicode.yaml | 1176 ++-- Rules/Languages/en/unicode.yaml | 1068 ++-- Rules/Languages/es/unicode-full.yaml | 6802 ++++++++++---------- Rules/Languages/es/unicode.yaml | 932 +-- Rules/Languages/fi/unicode-full.yaml | 6870 ++++++++++---------- Rules/Languages/fi/unicode.yaml | 964 +-- Rules/Languages/hu/ClearSpeak_Rules.yaml | 1680 ++--- Rules/Languages/hu/unicode.yaml | 1016 +-- Rules/Languages/nb/unicode-full.yaml | 7342 +++++++++++----------- Rules/Languages/nb/unicode.yaml | 972 +-- Rules/Languages/ru/unicode.yaml | 1096 ++-- Rules/Languages/vi/unicode-full.yaml | 6764 ++++++++++---------- Rules/Languages/vi/unicode.yaml | 1036 +-- 17 files changed, 20595 insertions(+), 20595 deletions(-) diff --git a/Rules/Braille/CMU/unicode-full.yaml b/Rules/Braille/CMU/unicode-full.yaml index 558972fcf..5c24c0c8f 100644 --- a/Rules/Braille/CMU/unicode-full.yaml +++ b/Rules/Braille/CMU/unicode-full.yaml @@ -1,235 +1,235 @@ ---- - - "ⅆ": [t: "⠙"] # 0x2146 - - "ⅇ": [t: "⠑"] # 0x2147 - - "ⅈ": [t: "⠊"] # 0x2148 - - "ℭ": [t: "⠸⠕"] # 0x212D (números de Cailey (octoniones)) - - - "𝐚-𝐳": # 0x1d41a - 0x1d433 - - tc: "B" - - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝐀-𝐙": # 0x1d400 - 0x1d419 - - tc: "BC" - - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'abcdefghijklmnopqrstuvwxyz')" - -# don't mark these as italic - - "𝑎-𝑧": # 0x1d44e - 0x1d467 - - tc: "" - - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝐴-𝑍": # 0x1d434 - 0x1d44d - - tc: "C" - - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝒂-𝒛": # 0x1d482 - 0x1d49b - - tc: "B" - - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝑨-𝒁": # 0x1d468 - 0x1d481 - - tc: "BC" - - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf - - tc: "Ts" - - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 - - tc: "TsC" - - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'abcdefghijklmnopqrstuvwxyz')" - - - "ℊ": [t: "TL⠛⠁"] # 0x210a (Script Small G) - - "ℋ": [t: "TCL⠓⠁"] # 0x210b (Script Capital H) - - "ℒ": [t: "TCL⠇"] # 0x2113 (Script Capital L) - - "ℓ": [t: "TL⠇"] # 0x2113 (Script Small L) - - "℘": [t: "TCL⠏"] # 0x2118 (Script Capital P) - - "ℛ": [t: "TCL⠗"] # 0x211B (Script Capital R) - - "ℯ": [t: "TL⠑"] # 0x212F (Script Small E) - - "ℰ": [t: "TCL⠑"] # 0x2130 (Script Capital E) - - "ℱ": [t: "TCL⠋"] # 0x2131 (Script Capital F) - - "ℳ": [t: "TCL⠍"] # 0x2133 (Script Capital M) - - "ℴ": [t: "TL⠕"] # 0x21334 (Script Small O) - - "𝓪-𝔃": # 0x1d4ea - 0x1d503 - - tc: "BTs" - - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 - - tc: "BTsC" - - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝔞-𝔷": # 0x1d51e - 0x1d537 - - tc: "D" - - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝔄-𝔝": # 0x1d504 - 0x1d51d - - tc: "DC" - - spell: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'abcdefgjklmnopqstuvwxy')" - - - "ℌ": [t: "DCL⠓"] # 0x210C (Fraktur Capital H) - - "ℑ": [t: "DCL⠊"] # 0x2111 (Fraktur Capital I) - - "ℜ": [t: "DCL⠗"] # 0x211C (Fraktur Capital R) - - "ℨ": [t: "DCL⠵"] # 0x2128 (Fraktur Capital Z) - - "𝕒-𝕫": # 0x1d552 - 0x1d56b - - tc: "𝔹" - - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝔸-𝕐": # 0x1d538 - 0x1d550 (blackboard bold capitals, excluding special number sets) - - tc: "𝔹C" - - spell: "translate('.', '𝔸𝔹𝔻𝔼𝔽𝔾𝕀𝕁𝕂𝕃𝕄𝕆𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'abcdefghijklmnopqrst')" - - - "ℂ": [t: "⠸⠉"] # 0x2102 (números complejos) - - "ℍ": [t: "⠸⠓"] # 0x210D (cuaterniones) - - "ℕ": [t: "⠸⠝"] # 0x2115 (números naturales) - - "ℙ": [t: "⠸⠏"] # 0x2119 (números primos) - - "ℚ": [t: "⠸⠟"] # 0x211A (números racionales) - - "ℝ": [t: "⠸⠗"] # 0x211D (números reales) - - "ℤ": [t: "⠸⠵"] # 0x2124 (números enteros) - - - "𝖆-𝖟": # 0x1d586 - 0x1d59f - - tc: "BD" - - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝕬-𝖅": # 0x1d56c - 0x1d585 - - tc: "BDC" - - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 - - tc: "S" - - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 - - tc: "SC" - - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝗮-𝘇": # 0x1d5ee - 0x1d607 - - tc: "BS" - - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed - - tc: "BSC" - - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝘢-𝘻": # 0x1d622 - 0x1d63b - - tc: "S" - - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝘈-𝘡": # 0x1d608 - 0x1d621 - - tc: "SC" - - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝙖-𝙯": # 0x1d656 - 0x1d66f - - tc: "BS" - - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝘼-𝙕": # 0x1d63c - 0x1d655 - - tc: "BSC" - - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 - - tc: "" - - spell: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝙰-𝚉": # 0x1d670 - 0x1d689 - - tc: "C" - - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝚤": [t: "L⠊"] # 0x1d6a4 (dotless i) - - "𝚥": [t: "L⠚"] # 0x1d6a5 (dotless j) - - "𝛂-𝛙": # 0x1d6c2 - 0x1d6d9 - - tc: "BGL" - - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙')" - - - "𝚨-𝚿": # 0x1d6a8 - 0x1d6bf - - tc: "BCGL" - - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿')" - - - "𝛼-𝜓": # 0x1d6fc - 0x1d713 - - tc: "GL" - - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓')" - - - "𝛢-𝛹": # 0x1d6e2 - 0x1d6f9 - - tc: "CGL" - - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹')" - - - "𝜶-𝝍": # 0x1d736 - 0x1d74d - - tc: "BGL" - - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍')" - - - "𝜜-𝜳": # 0x1d71c - 0x1d733 - - tc: "BCGL" - - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳')" - - - "𝝰-𝞇": # 0x1d770 - 0x1d787 - - tc: "BSGL" - - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇')" - - - "𝝖-𝝭": # 0x1d756 - 0x1d76d - - tc: "BSCGL" - - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭')" - - - "𝞪-𝟁": # 0x1d7aa - 0x1d7c1 - - tc: "BSGL" - - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁')" - - - "𝞐-𝞧": # 0x1d790 - 0x1d7a7 - - tc: "BSCGL" - - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧')" - - - "𝟎-𝟗": # 0x1d7ce - 0x1d7d7 - - tc: "BN" - - spell: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" - - - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 - - tc: "SBN" - - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" - - - "𝟢-𝟫": # 0x1d7e2 - 0x1d7eb - - tc: "SN" - - spell: "translate('.', '𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫', '0123456789')" - - - "𝟬-𝟵": # 0x1d7ec - 0x1d7f5 - - tc: "BSN" - - spell: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" - - - "𝟶-𝟿": # 0x1d7f6 - 0x1d7ff - - tc: "N" - - spell: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" - - - "¼": [t: "#N⠁N⠲"] # 0x00BC (Vulgar Fraction One Quarter) - - "½": [t: "#N⠁N⠆"] # 0x00BD (Vulgar Fraction One Half) - - "¾": [t: "#N⠒N⠲"] # 0x00BE (Vulgar Fraction Three Quarters) - - "⅐": [t: "#N⠁N⠶"] # 0x2150 (Vulgar Fraction One Seventh) - - "⅑": [t: "#N⠁N⠔"] # 0x2151 (Vulgar Fraction One Ninth) - - "⅒": [t: "#N⠁N⠂N⠴"] # 0x2152 (Vulgar Fraction One Tenth) - - "⅓": [t: "#N⠁N⠒"] # 0x2153 (Vulgar Fraction One Third) - - "⅔": [t: "#N⠃N⠒"] # 0x2154 (Vulgar Fraction Two Thirds) - - "⅕": [t: "#N⠁N⠢"] # 0x2155 (Vulgar Fraction One Fifth) - - "⅖": [t: "#N⠃N⠢"] # 0x2156 (Vulgar Fraction Two Fifths) - - "⅗": [t: "#N⠒N⠢"] # 0x2157 (Vulgar Fraction Three Fifths) - - "⅘": [t: "#N⠙N⠢"] # 0x2158 (Vulgar Fraction Four Fifths) - - "⅙": [t: "#N⠁N⠖"] # 0x2159 (Vulgar Fraction One Sixth) - - "⅚": [t: "#N⠢N⠖"] # 0x215A (Vulgar Fraction Five Sixths) - - "⅛": [t: "#N⠁N⠦"] # 0x215B (Vulgar Fraction One Eighth) - - "⅜": [t: "#N⠒N⠦"] # 0x215C (Vulgar Fraction Three Eighths) - - "⅝": [t: "#N⠢N⠦"] # 0x215D (Vulgar Fraction Five Eighths) - - "⅞": [t: "#N⠛N⠦"] # 0x215E (Vulgar Fraction Seven Eighths) - - "↉": [t: "#N⠚N⠒"] # 0x2189 (Vulgar Fraction Zero Thirds) - - - "̊": [t: "⠈⠴"] # 0x030A (Ring) - - "ˇ": [t: "⠰⠒"] # 0x02C7 (Caron) - - "⌢": [T: "⠈⠒"] # 0x2322 - - "⌣": [T: "⠠⠒"] # 0x2323 - - "⏜": [T: "⠈⠒"] # 0x232DC - - "⏝": [T: "⠠⠒"] # 0x23DD - - - "∟": [t: "⠸⠤"] # 0x221F (ángulo recto) - - "⦜": [t: "⠸⠤"] # 0x299C (ángulo recto) - - "⦝": [t: "⠸⠤"] # 0x299D (ángulo recto) - - "⦨": [t: "⠨⠱"] # 0x29A8 (ángulo orientado positivo) - - "⦩": [t: "⠨⠜"] # 0x29A9 (ángulo orientado negativo) - - "ᴗ": [t: "⠢⠜"] # 0x1D17 (arco correspondiente al ángulo abc) - - "⤻": [t: "⠠⠱"] # 0x293B (vector axial positivo) - - "↷": [t: "⠈⠜"] # 0x21B7 (vector axial negativo) - - - "∾": [t: "⠰⠢⠆"] # 0x223E (homólogo a/semejante a) - - "⌅": [t: "⠸⠫"] # 0x2305 (proyectividad) - - "⌆": [t: "⠸⠻"] # 0x2306 (perspectividad) +--- + - "ⅆ": [t: "⠙"] # 0x2146 + - "ⅇ": [t: "⠑"] # 0x2147 + - "ⅈ": [t: "⠊"] # 0x2148 + - "ℭ": [t: "⠸⠕"] # 0x212D (números de Cailey (octoniones)) + + - "𝐚-𝐳": # 0x1d41a - 0x1d433 + - tc: "B" + - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝐀-𝐙": # 0x1d400 - 0x1d419 + - tc: "BC" + - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'abcdefghijklmnopqrstuvwxyz')" + +# don't mark these as italic + - "𝑎-𝑧": # 0x1d44e - 0x1d467 + - tc: "" + - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝐴-𝑍": # 0x1d434 - 0x1d44d + - tc: "C" + - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝒂-𝒛": # 0x1d482 - 0x1d49b + - tc: "B" + - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝑨-𝒁": # 0x1d468 - 0x1d481 + - tc: "BC" + - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf + - tc: "Ts" + - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 + - tc: "TsC" + - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'abcdefghijklmnopqrstuvwxyz')" + + - "ℊ": [t: "TL⠛⠁"] # 0x210a (Script Small G) + - "ℋ": [t: "TCL⠓⠁"] # 0x210b (Script Capital H) + - "ℒ": [t: "TCL⠇"] # 0x2113 (Script Capital L) + - "ℓ": [t: "TL⠇"] # 0x2113 (Script Small L) + - "℘": [t: "TCL⠏"] # 0x2118 (Script Capital P) + - "ℛ": [t: "TCL⠗"] # 0x211B (Script Capital R) + - "ℯ": [t: "TL⠑"] # 0x212F (Script Small E) + - "ℰ": [t: "TCL⠑"] # 0x2130 (Script Capital E) + - "ℱ": [t: "TCL⠋"] # 0x2131 (Script Capital F) + - "ℳ": [t: "TCL⠍"] # 0x2133 (Script Capital M) + - "ℴ": [t: "TL⠕"] # 0x21334 (Script Small O) + - "𝓪-𝔃": # 0x1d4ea - 0x1d503 + - tc: "BTs" + - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 + - tc: "BTsC" + - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝔞-𝔷": # 0x1d51e - 0x1d537 + - tc: "D" + - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝔄-𝔝": # 0x1d504 - 0x1d51d + - tc: "DC" + - spell: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'abcdefgjklmnopqstuvwxy')" + + - "ℌ": [t: "DCL⠓"] # 0x210C (Fraktur Capital H) + - "ℑ": [t: "DCL⠊"] # 0x2111 (Fraktur Capital I) + - "ℜ": [t: "DCL⠗"] # 0x211C (Fraktur Capital R) + - "ℨ": [t: "DCL⠵"] # 0x2128 (Fraktur Capital Z) + - "𝕒-𝕫": # 0x1d552 - 0x1d56b + - tc: "𝔹" + - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝔸-𝕐": # 0x1d538 - 0x1d550 (blackboard bold capitals, excluding special number sets) + - tc: "𝔹C" + - spell: "translate('.', '𝔸𝔹𝔻𝔼𝔽𝔾𝕀𝕁𝕂𝕃𝕄𝕆𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'abcdefghijklmnopqrst')" + + - "ℂ": [t: "⠸⠉"] # 0x2102 (números complejos) + - "ℍ": [t: "⠸⠓"] # 0x210D (cuaterniones) + - "ℕ": [t: "⠸⠝"] # 0x2115 (números naturales) + - "ℙ": [t: "⠸⠏"] # 0x2119 (números primos) + - "ℚ": [t: "⠸⠟"] # 0x211A (números racionales) + - "ℝ": [t: "⠸⠗"] # 0x211D (números reales) + - "ℤ": [t: "⠸⠵"] # 0x2124 (números enteros) + + - "𝖆-𝖟": # 0x1d586 - 0x1d59f + - tc: "BD" + - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝕬-𝖅": # 0x1d56c - 0x1d585 + - tc: "BDC" + - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 + - tc: "S" + - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 + - tc: "SC" + - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝗮-𝘇": # 0x1d5ee - 0x1d607 + - tc: "BS" + - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed + - tc: "BSC" + - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝘢-𝘻": # 0x1d622 - 0x1d63b + - tc: "S" + - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝘈-𝘡": # 0x1d608 - 0x1d621 + - tc: "SC" + - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝙖-𝙯": # 0x1d656 - 0x1d66f + - tc: "BS" + - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝘼-𝙕": # 0x1d63c - 0x1d655 + - tc: "BSC" + - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 + - tc: "" + - spell: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝙰-𝚉": # 0x1d670 - 0x1d689 + - tc: "C" + - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝚤": [t: "L⠊"] # 0x1d6a4 (dotless i) + - "𝚥": [t: "L⠚"] # 0x1d6a5 (dotless j) + - "𝛂-𝛙": # 0x1d6c2 - 0x1d6d9 + - tc: "BGL" + - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙')" + + - "𝚨-𝚿": # 0x1d6a8 - 0x1d6bf + - tc: "BCGL" + - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿')" + + - "𝛼-𝜓": # 0x1d6fc - 0x1d713 + - tc: "GL" + - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓')" + + - "𝛢-𝛹": # 0x1d6e2 - 0x1d6f9 + - tc: "CGL" + - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹')" + + - "𝜶-𝝍": # 0x1d736 - 0x1d74d + - tc: "BGL" + - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍')" + + - "𝜜-𝜳": # 0x1d71c - 0x1d733 + - tc: "BCGL" + - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳')" + + - "𝝰-𝞇": # 0x1d770 - 0x1d787 + - tc: "BSGL" + - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇')" + + - "𝝖-𝝭": # 0x1d756 - 0x1d76d + - tc: "BSCGL" + - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭')" + + - "𝞪-𝟁": # 0x1d7aa - 0x1d7c1 + - tc: "BSGL" + - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁')" + + - "𝞐-𝞧": # 0x1d790 - 0x1d7a7 + - tc: "BSCGL" + - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧')" + + - "𝟎-𝟗": # 0x1d7ce - 0x1d7d7 + - tc: "BN" + - spell: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" + + - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 + - tc: "SBN" + - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" + + - "𝟢-𝟫": # 0x1d7e2 - 0x1d7eb + - tc: "SN" + - spell: "translate('.', '𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫', '0123456789')" + + - "𝟬-𝟵": # 0x1d7ec - 0x1d7f5 + - tc: "BSN" + - spell: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" + + - "𝟶-𝟿": # 0x1d7f6 - 0x1d7ff + - tc: "N" + - spell: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" + + - "¼": [t: "#N⠁N⠲"] # 0x00BC (Vulgar Fraction One Quarter) + - "½": [t: "#N⠁N⠆"] # 0x00BD (Vulgar Fraction One Half) + - "¾": [t: "#N⠒N⠲"] # 0x00BE (Vulgar Fraction Three Quarters) + - "⅐": [t: "#N⠁N⠶"] # 0x2150 (Vulgar Fraction One Seventh) + - "⅑": [t: "#N⠁N⠔"] # 0x2151 (Vulgar Fraction One Ninth) + - "⅒": [t: "#N⠁N⠂N⠴"] # 0x2152 (Vulgar Fraction One Tenth) + - "⅓": [t: "#N⠁N⠒"] # 0x2153 (Vulgar Fraction One Third) + - "⅔": [t: "#N⠃N⠒"] # 0x2154 (Vulgar Fraction Two Thirds) + - "⅕": [t: "#N⠁N⠢"] # 0x2155 (Vulgar Fraction One Fifth) + - "⅖": [t: "#N⠃N⠢"] # 0x2156 (Vulgar Fraction Two Fifths) + - "⅗": [t: "#N⠒N⠢"] # 0x2157 (Vulgar Fraction Three Fifths) + - "⅘": [t: "#N⠙N⠢"] # 0x2158 (Vulgar Fraction Four Fifths) + - "⅙": [t: "#N⠁N⠖"] # 0x2159 (Vulgar Fraction One Sixth) + - "⅚": [t: "#N⠢N⠖"] # 0x215A (Vulgar Fraction Five Sixths) + - "⅛": [t: "#N⠁N⠦"] # 0x215B (Vulgar Fraction One Eighth) + - "⅜": [t: "#N⠒N⠦"] # 0x215C (Vulgar Fraction Three Eighths) + - "⅝": [t: "#N⠢N⠦"] # 0x215D (Vulgar Fraction Five Eighths) + - "⅞": [t: "#N⠛N⠦"] # 0x215E (Vulgar Fraction Seven Eighths) + - "↉": [t: "#N⠚N⠒"] # 0x2189 (Vulgar Fraction Zero Thirds) + + - "̊": [t: "⠈⠴"] # 0x030A (Ring) + - "ˇ": [t: "⠰⠒"] # 0x02C7 (Caron) + - "⌢": [T: "⠈⠒"] # 0x2322 + - "⌣": [T: "⠠⠒"] # 0x2323 + - "⏜": [T: "⠈⠒"] # 0x232DC + - "⏝": [T: "⠠⠒"] # 0x23DD + + - "∟": [t: "⠸⠤"] # 0x221F (ángulo recto) + - "⦜": [t: "⠸⠤"] # 0x299C (ángulo recto) + - "⦝": [t: "⠸⠤"] # 0x299D (ángulo recto) + - "⦨": [t: "⠨⠱"] # 0x29A8 (ángulo orientado positivo) + - "⦩": [t: "⠨⠜"] # 0x29A9 (ángulo orientado negativo) + - "ᴗ": [t: "⠢⠜"] # 0x1D17 (arco correspondiente al ángulo abc) + - "⤻": [t: "⠠⠱"] # 0x293B (vector axial positivo) + - "↷": [t: "⠈⠜"] # 0x21B7 (vector axial negativo) + + - "∾": [t: "⠰⠢⠆"] # 0x223E (homólogo a/semejante a) + - "⌅": [t: "⠸⠫"] # 0x2305 (proyectividad) + - "⌆": [t: "⠸⠻"] # 0x2306 (perspectividad) diff --git a/Rules/Braille/CMU/unicode.yaml b/Rules/Braille/CMU/unicode.yaml index fa027b0b6..b37edce03 100644 --- a/Rules/Braille/CMU/unicode.yaml +++ b/Rules/Braille/CMU/unicode.yaml @@ -1,698 +1,698 @@ ---- -# UEB characters -# -# Some chars that originally came from an Excel spreadsheet, converted to csv, and the greatly expanded -# -# The UEB translation makes use of some non-braille chars as flags -# L -- what follows is a letter -# N -- what follows is a digit -# C -- precedes L for capital letters -# G -- precedes L for Greek Letters (after C for capitals) -# Typeface Indicators ("typeforms") -# B bold, I Italic, S Sans-serif, T script, D, Fraktur, 𝔹 blackboard-bold -# the type face indicators can be combined with B (first) and I (second) -# Standing alone chars: -# Any character which acts as a standing alone character (e.g, "{") needs each braille symbol to be labeled -# o -- opening/left side, c -- closing/right side, b -- both open and close (e.g, '"') - - - "0": [t: "N⠚"] # 0x30 - - "1": [t: "N⠁"] # 0x31 - - "2": [t: "N⠃"] # 0x32 - - "3": [t: "N⠉"] # 0x33 - - "4": [t: "N⠙"] # 0x34 - - "5": [t: "N⠑"] # 0x35 - - "6": [t: "N⠋"] # 0x36 - - "7": [t: "N⠛"] # 0x37 - - "8": [t: "N⠓"] # 0x38 - - "9": [t: "N⠊"] # 0x39 - -# we stick the drop numbers into the private use area for consistency - - "\ue000": [t: "N⠴"] # 0 - - "\ue001": [t: "N⠂"] # 1 - - "\ue002": [t: "N⠆"] # 2 - - "\ue003": [t: "N⠒"] # 3 - - "\ue004": [t: "N⠲"] # 4 - - "\ue005": [t: "N⠢"] # 5 - - "\ue006": [t: "N⠖"] # 6 - - "\ue007": [t: "N⠶"] # 7 - - "\ue008": [t: "N⠦"] # 8 - - "\ue009": [t: "N⠔"] # 9 - -# we stick hex digits into the private use area for consistency -# these are used when we don't want to add a numeric indicator for subsequent digits (3.3) - - "\ue00A": [t: "N⠐N⠁"] # A - - "\ue00B": [t: "N⠐N⠃"] # B - - "\ue00C": [t: "N⠐N⠉"] # C - - "\ue00D": [t: "N⠐N⠙"] # D - - "\ue00E": [t: "N⠐N⠑"] # E - - "\ue00F": [t: "N⠐N⠋"] # F - -# leave room for the rest of the alphabet - - "\ue01A": [t: "N⠨N⠁"] # A - - "\ue01B": [t: "N⠨N⠃"] # B - - "\ue01C": [t: "N⠨N⠉"] # C - - "\ue01D": [t: "N⠨N⠙"] # D - - "\ue01E": [t: "N⠨N⠑"] # E - - "\ue01F": [t: "N⠨N⠋"] # F - -# Omission char -- there isn't a specific code point, so we use a private use area - - "\ue020": [t: "⠰"] # omission (three dot 5s with letter indicator) - - - - "a": [t: "L⠁"] # 0x61 - - "b": [t: "L⠃"] # 0x62 - - "c": [t: "L⠉"] # 0x63 - - "d": [t: "L⠙"] # 0x64 - - "e": [t: "L⠑"] # 0x65 - - "f": [t: "L⠋"] # 0x66 - - "g": [t: "L⠛"] # 0x67 - - "h": [t: "L⠓"] # 0x68 - - "i": [t: "L⠊"] # 0x69 - - "j": [t: "L⠚"] # 0x6a - - "k": [t: "L⠅"] # 0x6b - - "l": [t: "L⠇"] # 0x6c - - "m": [t: "L⠍"] # 0x6d - - "n": [t: "L⠝"] # 0x6e - - "o": # 0x6f - - test: # special case because these have the same dot pattern - if: "preceding-sibling::*[1][self::m:mo and (.='>' or .='≫')]" - then: [t: "⠐"] - - t: "L⠕" - - "p": [t: "L⠏"] # 0x70 - - "q": [t: "L⠟"] # 0x71 - - "r": [t: "L⠗"] # 0x72 - - "s": [t: "L⠎"] # 0x73 - - "t": [t: "L⠞"] # 0x74 - - "u": [t: "L⠥"] # 0x75 - - "v": [t: "L⠧"] # 0x76 - - "w": [t: "L⠺"] # 0x77 - - "x": [t: "L⠭"] # 0x78 - - "y": [t: "L⠽"] # 0x79 - - "z": [t: "L⠵"] # 0x7a - - - - "á": [t: "L⠷"] # 0xE1 - - "é": [t: "L⠮"] # 0xE9 - - "í": [t: "L⠌"] # 0xED - - "ñ": [t: "L⠻"] # 0xF1 - - "ó": [t: "L⠬"] # 0xF3 - - "ú": [t: "L⠾"] # 0xFA - - "ü": [t: "L⠳"] # 0xFC - - - "Á": [t: "CL⠷"] # 0xC0 - - "É": [t: "CL⠮"] # 0xC9 - - "Í": [t: "CL⠌"] # 0xCD - - "Ñ": [t: "CL⠻"] # 0xD1 - - "Ó": [t: "CL⠬"] # 0xD3 - - "Û": [t: "CL⠾"] # 0xDA - - "Ü": [t: "CL⠳"] # 0xDC - - # Latin capitals: chem-element letters use 𝐶 (no word indicator); others use C. - # Cells come from lowercase a-z via spell/translate. - - "BCHIKNOPSUVWY": # chemistry-capable capitals - - test: - if: "@data-chem-element" - then: [tc: "𝐶"] - else: [tc: "C"] - - spell: "translate('.', 'BCHIKNOPSUVWY', 'bchiknopsuvwy')" - - "ADEFGJLMQRTXZ": # remaining capitals - - tc: "C" - - spell: "translate('.', 'ADEFGJLMQRTXZ', 'adefgjlmqrtxz')" - - - "α": [t: "GL⠁"] # 0x3b1 - - "β": [t: "GL⠃"] # 0x3b2 - - "γ": [t: "GL⠛"] # 0x3b3 - - "δ": [t: "GL⠙"] # 0x3b4 - - "ε": [t: "GL⠑"] # 0x3b5 - - "ζ": [t: "GL⠵"] # 0x3b6 - - "η": [t: "GL⠱"] # 0x3b7 - - "θ": [t: "GL⠹"] # 0x3b8 - - "ι": [t: "GL⠊"] # 0x3b9 - - "κ": [t: "GL⠅"] # 0x3ba - - "λ": [t: "GL⠇"] # 0x3bb - - "μ": [t: "GL⠍"] # 0x3bc - - "ν": [t: "GL⠝"] # 0x3bd - - "ξ": [t: "GL⠭"] # 0x3be - - "ο": [t: "GL⠕"] # 0x3bf - - "π": [t: "GL⠏"] # 0x3c0 - - "ρ": [t: "GL⠗"] # 0x3c1 - - "ς": [t: "VL⠎"] # 0x3c2 - - "σ": [t: "GL⠎"] # 0x3c3 - - "τ": [t: "GL⠞"] # 0x3c4 - - "υ": [t: "GL⠥"] # 0x3c5 - - "φ": [t: "GL⠋"] # 0x3c6 - - "χ": [t: "GL⠯"] # 0x3c7 - - "ψ": [t: "GL⠽"] # 0x3c8 - - "ω": [t: "GL⠺"] # 0x3c9 - - - "Α": [t: "CGL⠁"] # 0x391 - - "Β": [t: "CGL⠃"] # 0x392 - - "Γ": [t: "CGL⠛"] # 0x393 - - "Δ": [t: "CGL⠙"] # 0x394 - - "Ε": [t: "CGL⠑"] # 0x395 - - "Ζ": [t: "CGL⠵"] # 0x396 - - "Η": [t: "CGL⠱ "] # 0x397 - - "Θ": [t: "CGL⠹"] # 0x398 - - "Ι": [t: "CGL⠊"] # 0x399 - - "Κ": [t: "CGL⠅"] # 0x39a - - "Λ": [t: "CGL⠇"] # 0x39b - - "Μ": [t: "CGL⠍"] # 0x39c - - "Ν": [t: "CGL⠝"] # 0x39d - - "Ξ": [t: "CGL⠭"] # 0x39e - - "Ο": [t: "CGL⠕"] # 0x39f - - "Π": [t: "CGL⠏"] # 0x3a0 - - "Ρ": [t: "CGL⠗"] # 0x3a1 - - "΢": [t: "CGL⠎"] # 0x3a2 - - "Σ": [t: "CGL⠎"] # 0x3a3 - - "Τ": [t: "CGL⠞"] # 0x3a4 - - "Υ": [t: "CGL⠥"] # 0x3a5 - - "Φ": [t: "CGL⠋"] # 0x3a6 - - "Χ": [t: "CGL⠯"] # 0x3a7 - - "Ψ": [t: "CGL⠽"] # 0x3a8 - - "Ω": [t: "CGL⠺"] # 0x3a9 - - - "ϑ": [t: "VL⠹"] # 0x3d1 - - "ϵ": [t: "VL⠑"] # 0x3f5 - - "ϰ": [t: "VL⠅"] # 0x3f0 - - "ϕ": [t: "VL⠋"] # 0x3d5 - - "ϱ": [t: "VL⠗"] # 0x3f1 - - "ϖ": [t: "VL⠏"] # 0x3d6 - - "Ϝ": [t: "VL⠧"] # 0x3d7 - - - "µ": [t: "GL⠍"] # 0x00B5 (Micro (Greek mu)) - - "Ω": [t: "CGL⠺"] # 0x2126 (Ohm sign (capital Greek omega)) - - "∆": [t: "⠸⠦"] # 0x2206 (Increment) - - "∏": # 0x220F (Product (capital Greek pi)) - - t: "CGL⠏" - - test: - if: "not(IsNode(.., 'modified'))" - then: [t: "⠱"] - - "∐": # 0x2210 (CoProduct (capital Greek pi)) - - t: "⠘⠻" - - test: - if: "not(IsNode(.., 'modified'))" - then: [t: "⠱"] - - "∑": # 0x2211 (Sum (capital Greek sigma)) - - t: "CGL⠎" - - test: - if: "not(IsNode(.., 'modified'))" - then: [t: "⠱"] - - - "<": [t: "⠪"] # 0x003C (Less than) - - "≨": [t: "⠪"] # 0x2268 (Less-Than But Not Equal To) - - "⋦": [t: "⠪"] # 0x22E6 (Less-Than But Not Equivalent To) - - ">": [t: "⠕"] # 0x003E (Greater than) - - "≩": [t: "⠕"] # 0x2269 (Greater-Than But Not Equal To) - - "⋧": [t: "⠕"] # 0x22E7 (Greater-Than But Not Equivalent To) -# - "≮": [t: "⠈⠣⠈⠱"] # 0x226E (Not less than) -# - "≯": [t: "⠈⠜⠈⠱"] # 0x226F (Not greater than) -# - "≰": [t: "⠸⠈⠣⠈⠱"] # 0x2270 (Neither less than nor equal to) -# - "≱": [t: "⠸⠈⠜⠈⠱"] # 0x2271 (Neither greater than nor equal to) -# - "∝": [t: "⠸⠐⠶"] # 0x221D (Proportional to) -# - "≃": [t: "⠸⠔"] # 0x2243 (Approximately equal to (tilde over horizontal line)) -# - "≅": [t: "⠐⠸⠔"] # 0x2245 (Approximately equal to (tilde over equals sign)) -# - "≏": [t: "⠘⠐⠶"] # 0x224F (Equals with bump in top bar (difference between)) -# - "≢": [t: "⠸⠿⠈⠱"] # 0x2262 (Not identical to) -# - "∈": [t: "⠘⠑"] # 0x2208 (Element of (member of)) -# - "∉": [t: "⠘⠑⠈⠱"] # 0x2209 (Not Element of) - - "+": [t: "⠖"] # 0x002B (Plus sign) -# - "∋": [t: "⠈⠘⠑"] # 0x220B (Contains) -# - "⊂": [t: "⠘⠣"] # 0x2282 (Subset of) -# - "⊃": [t: "⠘⠜"] # 0x2283 (Superset of) -# - "⊆": [t: "⠸⠘⠣"] # 0x2286 (Subset of or equal) -# - "⊇": [t: "⠸⠘⠜"] # 0x2287 (Superset of or equal) -# - "⊊": [t: "⠨⠘⠣"] # 0x228A (Subset of with not equal) -# - "⊋": [t: "⠨⠘⠜"] # 0x228B (Superset of with not equal) -# - "⊲": [t: "⠈⠸⠣"] # 0x22B2 (Normal subgroup of) -# - "⊳": [t: "⠈⠸⠜"] # 0x22B3 (Contains as normal subgroup) -# - "⊴": [t: "⠸⠸⠣"] # 0x22B4 (Normal subgroup of or equal) -# - "⊵": [t: "⠸⠸⠜"] # 0x22B5 (Contains as normal subgroup or equal) -# - "⋬": [t: "⠨⠸⠣"] # 0x22EC (not normal subgroup) -- this isn't the same as what is in GTM 10, but that similar has no Unicode equiv -# - "⋭": [t: "⠨⠸⠣"] # 0x22ED (does not contain as normal subgroup) -- this isn't the same as what is in GTM 10, but that similar has no Unicode equiv -# - "⊢": [t: "⠸⠒"] # 0x22a2 (Right tack) -# - "⊣": [t: "⠈⠸⠒"] # 0x22a3 (Left tack) - - "−": [t: "⠐⠤"] # 0x2212 (Minus sign) - - "·": [t: "⠠𝘄"] # 0x00B7 (Multiplication dot (times)) -# - "∗": [t: "⠐⠔"] # 0x2217 (Asterisk operator) - - "∘": [t: "⠠⠆"] # 0x2218 (Ring operator) value based on last row in 5.1 (probably what they should have used) - - "◦": [t: "⠠⠆"] # 0x25E6 (White bullet) (value based on 2218) - - "⋅": [t: "⠰⠄"] # 0x22C5 (Dot operator)(value based on 2218) -# - "∖": [t: "⠸⠡"] # 0x2216 (Set minus) - - "(": [t: "⠣"] # 0x0028 (Left parenthesis) - - ")": [t: "⠜"] # 0x0029 (Right parenthesis) - - "[": [t: "⠷"] # 0x005B (Left square bracket) - - "]": [t: "⠾"] # 0x005D (Right square bracket) - - "!": # 0x21 (Exclamation (factorial)) - - test: # CMU seems to use a different char for factorial (7.5) -- this weak guess for factorial - if: "self::m:mo and preceding-sibling::*" - then: [t: "⠘⠄"] - else: [t: "⠖"] - - "&": [t: "⠠⠯"] # 0x26 (Ampersand) - - "*": [t: "⠲"] # 0x002A (Asterisk) - - "?": [t: "⠢"] # 0x003F (Question mark) - - "¿": [t: "⠢"] # 0x00BF (Question mark) - - "@": [t: "⠐"] # 0x0040 (Commercial at sign) - - "^": # 0x005E (Caret (hat, up arrow)) 4.3.2 uses one form as a circumflex, and 11.1 as a geometric angle - - test: # it is not clear how to distinguish one form from another -- the following passes the tests, but is almost certainly wrong - - if: "..[self::m:mover][ *[1][self::m:mi and string-length(.)=1 and translate(., 'abcdefghijklmnopqrstuvwxyz', '') = ''] ]" - then: [t: "⠰⠒"] # circumflex - else: [t: "⠘⠒"] # angle and everything else - - "_": [t: "⠤"] # 0x005F (Low line (underscore)) - - "¯": [t: "⠈⠉"] # 0x00AF (macron) - - "═": [t: "⠈⠉⠈⠉"] # 0x2550 (BOX DRAWINGS DOUBLE HORIZONTAL) - - "~": # 0x007E (Tilde (swung dash)) - - test: # unclear what really should happen see 4.3.2, 4.3.3, 6.1, and 8.2 -- all use different codes - - if: "..[self::m:mover]" - then: [t: "⠐⠢"] - - else_if: "..[self::m:munder]" - then: [t: "⠠⠢"] - - else_if: "not(preceding-sibling::*)" - then: [t: "⠠⠄"] # (8.2 -- prefix?) - else: [t: "⠐⠢⠠"] # (6.1 -- infix?) - - ∼: # 223c (Tilde operator) - - test: # unclear what really should happen see 4.3.2, 4.3.3, 6.1, and 8.2 -- all use different codes - - if: "..[self::m:mover]" - then: [t: "⠐⠢"] - - else_if: "..[self::m:munder]" - then: [t: "⠠⠢"] - - else_if: "not(preceding-sibling::*)" - then: [t: "⠠⠄"] # (8.2 -- prefix?) - else: [t: "⠐⠢⠠"] # (6.1 -- infix?) - - "—": [t: "⠤⠤"] # 0x2014 (Em dash) - - "‖": [t: "⠸⠇"] # 0x2016 -# - "¦": [t: "⠨⠳"] # 0x00A6 (Broken bar) -# - "¬": [t: "⠈⠹"] # 0x00AC (Not sign) - - "°": [t: "⠴"] # 0x00B0 (Degree sign) - - "²": [t: "⠡⠼⠃⠉"] # 0x00B2 (superscripted 2) - - "³": [t: "⠡⠼⠉"] # 0x00B3 (superscripted 3) -# - "†": [t: "⠈⠠⠹"] # 0x2020 (Dagger) -# - "‡": [t: "⠈⠠⠻"] # 0x2021 (Double dagger) -# - "‰": [t: "⠸⠴⠴"] # 0x2030 (Per mille) - - "′": [t: "⠳"] # 0x2032 (Prime sign) - - "″": [t: "⠳⠳"] # 0x2033 (Double prime sign) - - "‴": [t: "⠳⠳⠳"] # 0x2034 (Triple prime sign) -# - "Å": [t: "⠠⠘⠫⠁"] # 0x212B (Angstrom symbol) -# - "Å": [t: "⠠⠘⠫⠁"] # 0x00C5 (WIRIS uses this for Angstrom) -# - "∀": [t: "⠘⠁"] # 0x2200 (For all) - - "∂": [t: "⠸⠙"] # 0x2202 (Partial differential) -# - "∃": [t: "⠘⠢"] # 0x2203 (There exists) -# - "∄": [t: "⠘⠢⠈⠱"] # 0x2204 (There does not exist) -# - "∅": [t: "⠈⠚"] # 0x2205 (Empty set) -# - "∎": [t: "⠸⠫⠼⠙t"] # 0x220E (End of proof) -# - "√": [t: "⠐⠩"] # 0x221A (Square root (radical) without vinculum) -# - "∠": [t: "⠸⠪"] # 0x2220 (Angle) -# - "∡": [t: "⠨⠸⠪"] # 0x2221 (Measured angle) -# - "⊾": [t: "⠼⠸⠪"] # 0x22BE (Right angle with arc) - - "∫": # 0x222B (Integral) - - t: "⠯" - - test: - if: "not(IsNode(.., 'modified'))" - then: [t: "⠱"] - - "∬": # 0x222c (Double integral) - - t: "⠯⠯" - - test: - if: "not(IsNode(.., 'modified'))" - then: [t: "⠱"] - - "∭": # 0x222d (Triple integral) - - t: "⠯⠯⠯" - - test: - if: "not(IsNode(.., 'modified'))" - then: [t: "⠱"] - - "∮": # 0x222E (Contour integral (closed line integral)) - - t: "⠯⠴" - - test: - if: "not(IsNode(.., 'modified'))" - then: [t: "⠱"] -# - "∷": [t: "⠒⠒"] # 0x2237 (Proportion) -# - "∣": [t: "⠸⠳"] # 0x2223 (Divides) -# - "∤": [t: "⠸⠳⠈⠱"] # 0x2224 (Does not divide) - - "←": # 0x2190 (Leftwards arrow) - - test: # this is a guess as to when to use each - if: # mi on either side or if parent is mover, mi on either side of the parent (e.g., A⟶B or labeled arrow) - - "(..[self::m:mrow] and preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]) or " - - "(..[self::m:mover][ ..[self::m:mrow][preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]] ])" - then: [t: "⠐⠒⠒"] # 9.1 - else: [t: "⠐⠒"] # 9.2 - - "⟵": # 0x27F5 (Long leftwards arrow) - - test: # this is a guess as to when to use each - if: # mi on either side or if parent is mover, mi on either side of the parent (e.g., A⟶B or labeled arrow) - - "(..[self::m:mrow] and preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]) or " - - "(..[self::m:mover][ ..[self::m:mrow][preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]] ])" - then: [t: "⠐⠒⠒"] # 9.1 - else: [t: "⠐⠒"] # 9.2 - - "→": # 0x2192 (Rightwards arrow) - - test: # this is a guess as to when to use each - if: # mi on either side or if parent is mover, mi on either side of the parent (e.g., A⟶B or labeled arrow), but rule out limit - - "(" - - " (..[self::m:mrow] and preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]) or " - - " (..[self::m:mover][ ..[self::m:mrow][preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]] ])" - - ") and" - - "not(../..[self::m:munder or self::m:msub][*[1][self::m:mi and starts-with(., 'lim')]])" - then: [t: "⠒⠒⠂"] # 9.1 - else: [t: "⠒⠂"] # 9.2 - - "⟶": # 0x27F6 (Long rightwards arrow) - - test: # this is a guess as to when to use each - if: # mi on either side or if parent is mover, mi on either side of the parent (e.g., A⟶B or labeled arrow), but rule out limit - - "(" - - " (..[self::m:mrow] and preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]) or " - - " (..[self::m:mover][ ..[self::m:mrow][preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]] ])" - - ") and" - - "not(../..[self::m:munder or self::m:msub][*[1][self::m:mi and starts-with(., 'lim')]])" - then: [t: "⠒⠒⠂"] # 9.1 - else: [t: "⠒⠂"] # 9.2 - - "⇀": # 0x21C0 (RIGHTWARDS HARPOON WITH BARB UPWARDS) [not mentioned in spec] - - test: # this is a guess as to when to use each - if: # mi on either side or if parent is mover, mi on either side of the parent (e.g., A⟶B or labeled arrow), but rule out limit - - "(" - - " (..[self::m:mrow] and preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]) or " - - " (..[self::m:mover][ ..[self::m:mrow][preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]] ])" - - ") and" - - "not(../..[self::m:munder or self::m:msub][*[1][self::m:mi and starts-with(., 'lim')]])" - then: [t: "⠒⠒⠂"] # 9.1 - else: [t: "⠒⠂"] # 9.2 - - "↔": # 0x2194 (Left right arrow) - - test: # this is a guess as to when to use each - if: # mi on either side or if parent is mover, mi on either side of the parent (e.g., A⟶B or labeled arrow) - - "(..[self::m:mrow] and preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]) or " - - "(..[self::m:mover][ ..[self::m:mrow][preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]] ])" - then: [t: "⠐⠒⠒⠂"] # 9.1 - else: [t: "⠐⠒⠂"] # 9.2 - - "⟷": # 0x27F7 (Long Left right arrow) - - test: # this is a guess as to when to use each - if: # mi on either side or if parent is mover, mi on either side of the parent (e.g., A⟶B or labeled arrow) - - "(..[self::m:mrow] and preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]) or " - - "(..[self::m:mover][ ..[self::m:mrow][preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]] ])" - then: [t: "⠐⠒⠒⠂"] # 9.1 - else: [t: "⠐⠒⠂"] # 9.2 -# - "↚": [t: "1⠳⠪⠈⠱"] # 0x219A (Leftwards arrow with stroke) -# - "↛": [t: "1⠳⠕⠈⠱"] # 0x219B (Rightwards arrow with stroke) -# - "↜": [t: "1⠳⠔⠢⠪"] # 0x219C (Leftwards wave arrow) -# - "↝": [t: "1⠳⠢⠔⠕"] # 0x219D (Rightwards wave arrow) -# - "↞": [t: "1⠳⠒⠗⠗⠪"] # 0x219E (Leftwards two headed arrow) -# - "↟": [t: "1⠳⠒⠗⠗⠬"] # 0x219F (Upwards two headed arrow) -# - "↠": [t: "1⠳⠒⠗⠗⠕"] # 0x21A0 (Rightwards two headed arrow) -# - "↡": [t: "1⠳⠒⠗⠗⠩"] # 0x21A1 (Downwards two headed arrow) -# - "↢": [t: "1⠳⠗⠗⠪"] # 0x21A2 (Leftwards arrow with tail) -# - "↣": [t: "1⠳⠗⠗⠕"] # 0x21A3 (Rightwards arrow with tail) -# - "↤": [t: "1⠳⠳⠗⠪"] # 0x21A4 (Leftwards arrow from bar) -# - "↥": [t: "1⠳⠳⠗⠬"] # 0x21A5 (Upwards arrow from bar) -# - "↦": [t: "1⠳⠳⠗⠕"] # 0x21A6 (Rightwards arrow from bar) -# - "↧": [t: "1⠳⠳⠗⠩"] # 0x21A7 (Downwards arrow from bar) -# - "↭": [t: "1⠳⠺⠔⠢⠗⠕"] # 0x21AD (Left right wave arrow) -# - "↮": [t: "1⠳⠺⠗⠕⠈⠱"] # 0x21AE (Left right arrow with stroke) -# - "↰": [t: "1⠳⠴⠬"] # 0x21B0 (Upwards arrow with tip left) -# - "↱": [t: "1⠳⠲⠬"] # 0x21B1 (Upwards arrow with tip right) -# - "↲": [t: "1⠳⠲⠩"] # 0x21B2 (Downwards arrow with tip left) -# - "↳": [t: "1⠳⠴⠩"] # 0x21B3 (Downwards arrow with tip right) -# - "↶": [t: "1⠳⠔⠔⠪"] # 0x21B6 (Anticlockwise top semicircle arrow) -# - "↷": [t: "1⠳⠢⠢⠕"] # 0x21B7 (Clockwise top semicircle arrow) -# - "↼": [t: "1⠳⠈⠗⠪"] # 0x21BC (Leftwards harpoon with barb upwards) -# - "↽": [t: "1⠳⠠⠗⠪"] # 0x21BD (Leftwards harpoon with barb downwards) -# - "↾": [t: "1⠳⠠⠗⠬"] # 0x21BE (Upwards harpoon with barb rightwards) -# - "↿": [t: "1⠳⠈⠗⠬"] # 0x21BF (Upwards harpoon with barb leftwards) -# - "⇀": [t: "1⠳⠈⠗⠕"] # 0x21C0 (Rightwards harpoon with barb upwards) -# - "⇁": [t: "1⠳⠠⠗⠕"] # 0x21C1 (Rightwards harpoon with barb downwards) -# - "⇂": [t: "1⠳⠈⠗⠩"] # 0x21C2 (Downwards harpoon with barb rightwards) -# - "⇃": [t: "1⠳⠠⠗⠩"] # 0x21C3 (Downwards harpoon with barb leftwards) -# - "⇄": [t: "1⠳⠕⠻⠳⠪"] # 0x21C4 (Rightwards arrow over leftwards arrow) -# - "⇅": [t: "1⠳⠬⠿⠳⠩"] # 0x21C5 (Upwards arrow left of Downwards arrow) -# - "⇌": [t: "⠘⠸⠶"] # 0x21CC (Rightwards harpoon over leftwards harpoon (equilibrium)) -# - "⇑": [t: "1⠳⠶⠬"] # 0x21D1 (Upwards double arrow) -# - "⇓": [t: "1⠳⠶⠩"] # 0x21D3 (Downwards double arrow) -# - "⇕": [t: "1⠳⠺⠶⠗⠬"] # 0x21D5 (Up down double arrow) -# - "⇠": [t: "1⠳⠂⠪"] # 0x21E0 (Leftwards dashed arrow) -# - "⇡": [t: "1⠳⠂⠬"] # 0x21E1 (Upwards dashed arrow) -# - "⇢": [t: "1⠳⠂⠕"] # 0x21E2 (Rightwards dashed arrow) -# - "⇣": [t: "1⠳⠂⠩"] # 0x21E3 (Downwards dashed arrow) -# - "⥂": [t: "⠸⠶"] # 0x2942 (Rightwards arrow above short leftwards arrow (equilibrium, trend to the right)) -# - "⥄": [t: "⠈⠸⠶"] # 0x2944 (Short rightwards arrow above leftwards arrow (equilibrium, trend to the left)) -# - "▤": [t: "⠨⠫⠼⠙t"] # 0x25A4 (Square with horizontal fill) -# - "▥": [t: "⠨⠫⠼⠙t"] # 0x25A5 (Square with vertical fill) -# - "▦": [t: "⠨⠫⠼⠙t"] # 0x25A6 (Square with orthogonal crosshatch fill) -# - "▧": [t: "⠨⠫⠼⠙t"] # 0x25A7 (Square with upper left to lower right fill) -# - "▨": [t: "⠨⠫⠼⠙t"] # 0x25A8 (Square with upper right to lower left fill) -# - "▩": [t: "⠨⠫⠼⠙t"] # 0x25A9 (Square with diagonal crosshatch fill) -# - "◍": [t: "⠨⠫⠿t"] # 0x25CD (Circle with vertical fill) -# - "▱": [t: "1⠫⠈⠼⠙t"] # 0x25B1 (Parallelogram) -# - "▲": [t: "⠸⠫⠼⠉t"] # 0x25B2 (Filled triangle) -# - "■": [t: "⠸⠫⠼⠙t"] # 0x25A0 (Filled square) -# - "≜": [t: "⠠⠨⠙⠻⠐⠶"] # 0x225C (Delta equal to) -# - "≝": [t: "1⠣⠙⠑⠋⠜⠻⠐⠶"] # 0x225D (Equal to by definition) -# - "⊕": [t: "1⠫⠿⠪⠐⠖t"] # 0x2295 (Circled plus) -# - "⊖": [t: "1⠫⠿⠪⠐⠤t"] # 0x2296 (Circled minus) -# - "⊗": [t: "1⠫⠿⠪⠐⠦t"] # 0x2297 (Circled times) -# - "⊛": [t: "1⠫⠿⠪⠐⠔t"] # 0x229B (Circled asterisk operator) -# - "⊞": [t: "1⠫⠼⠙⠪⠐⠖t"] # 0x229E (Squared plus) -# - "⊟": [t: "1⠫⠼⠙⠪⠐⠤t"] # 0x229F (Squared minus) -# - "⊠": [t: "1⠫⠼⠙⠪⠐⠦t"] # 0x22A0 (Squared times) -# - "⋇": [t: "1⠌⠯⠦"] # 0x22C7 (Division times) -# - "⊩": [t: "⠸⠳⠿⠸⠒"] # 0x22A9 (Forces) - - "˙": [t: "⠈"] # 0x02D9 ( Dot Above) - - "¨": [t: "⠈⠈"] # 0x00A8 ( Diaeresis/Double Dot Above ) - - "⃛": [t: "⠈⠈⠈"] # 0x20db (combining triple dot) - - "©": [t: "⠣⠨⠉⠜"] # 0xa9 (Copyright) - - "®": [t: "⠣⠨⠗⠜"] # 0xa9 (Registered sign) - - - "…": [t: "⠄⠄⠄"] # 0x2026 (Ellipsis) - - "⋯": [t: "⠄⠄⠄"] # 0x22EF (mid-line Ellipsis) -- seems to be same based on Example 10.1.3 - - -# All the quotes are the same - - "\"": [t: "⠦"] - - "'": [t: "⠄"] - - "“": [t: "⠦"] # 0x201C - - "”": [t: "⠦"] # 0x201C - - "‘": [t: "⠦"] - - "’": # 0x2019 (2.3_3) - - test: - if: "self::m:mn" - then: [t: "N⠂"] # same as '.' block separator - else: [t: "⠦"] - - "«": [t: "⠦"] - - "»": [t: "⠦"] - - - " ": # 0x20 (Space) - - test: - - if: "self::m:mn" - then: [t: "N⠄"] - - else_if: "@data-added='missing-content' or @data-empty-in-2D or @width > 1.1" - then: [t: "⠰⠤⠆"] # omission - - else_if: "@width < 0.25" - then: [t: ""] # tweaking space -- ignore - else: [t: "W"] # space in text or wide enough space - - " ": # 0xa0 (Non-breaking Space) - - test: - - if: "self::m:mn" - then: [t: "N⠄"] - else: [t: "W"] - - ",": # 0x2c (Comma) - - test: - if: "self::m:mn" - then: [t: "N⠂"] - else: [t: "W⠂"] - - ".": # 0x2e (Period) -- 2.3 says that if this is acting like a decimal separator, it should be brailled like "," - - test: - if: "self::m:mn" - then: - # presunme this is likely uses "," for a decimal separator, so just do a few checks - # 1. if there are < 3 chars after the first ".", then not a block separator - # 2. if there is a '.' or other likely block separator after the first '.', then not decimal separator - # likely other (complicated?) other tests that could be used - - with: - variables: [StringAfter: "substring-after(., '.')"] - replace: - - test: - if: "string-length($StringAfter) >= 3 and string-length($StringAfter)=string-length( translate($StringAfter, $BlockSeparators, '') )" - then: [t: "N⠄"] # really is a block separator - else: [t: "N⠂"] # treat as decimal separator - else: [t: "W⠄"] - - ":": [t: "⠐⠂"] # 0x003A (Colon) - - "-": [t: "⠤"] # 0x2d (Minus sign or hyphen) - - "⁡": [t: ""] # 0x2061⁡ (invisible function apply) - - "⁢": [t: ""] # 0x2062 (invisible times) - - "⁣": [t: ""] # 0x2063⁡ (invisible separator) - - "⁤": [t: ""] # 0x2064 (invisible plus) - - - "`": [t: "⠢"] # 0x0060 (GRAVE ACCEN) - - - "א": [t: "⠠⠳"] # 0x05D0 (aleph) - - "○": [t: "⠪⠕"] # 0x25CB (círculo) - - "∞": [t: "⠼⠳"] # 0x221E (infinito) - - "⎔": [t: "⠯⠕"] # 0x2394 (polígono) - - "‰": [t: "⠸⠴⠴"] # 0x2030 (tanto por mil) - - "¬": [t: "⠠⠄"] # 0x00AC (negación lógica) - - "↕": [t: "⠸⠅"] # 0x2195 (flecha arriba-abajo) - - "↖": [t: "⠐⠡"] # 0x2196 (flecha oblicua arriba-izquierda) - - "↙": [t: "⠐⠌"] # 0x2199 (flecha abajo-izquierda) - - "↓": [t: "⠸⠄"] # 0x2193 (flecha hacia abajo) - - "↘": [t: "⠡⠂"] # 0x2198 (flecha oblicua abajo-derecha) - - "↗": [t: "⠌⠂"] # 0x2197 (flecha arriba-derecha) - - "↑": [t: "⠸⠁"] # 0x2191 (flecha hacia arriba) - - "△": [t: "⠠⠾"] # 0x25B3 (Triangle) - - "▭": [t: "⠯⠽"] # 0x25AD (rectángulo) - - "□": [t: "⠸⠽"] # 0x25A1 (cuadrado) - - "⟺": [t: "⠪⠒⠕"] # 0x27FA (doble implicación «si y solo si») - - "⟸": [t: "⠪⠒"] # 0x27F8 (implicación recíproca; porque) - - "⟹": [t: "⠒⠕"] # 0x27F9 (implicación directa; implica) - - "⇔": [t: "⠪⠒⠕"] # 0x21D4 (LEFT RIGHT DOUBLE ARROW) - - "⇐": [t: "⠪⠒"] # 0x21D0 (LEFTWARDS DOUBLE ARROW) - - "⇒": [t: "⠒⠕"] # 0x21D2 (RIGHTWARDS DOUBLE ARROW) - - "⤡": [t: "⠐⠡⠂"] # 0x2921 (flecha abajo-derecha y arriba izquierda) - - "⤢": [t: "⠐⠌⠂"] # 0x2922 (flecha abajo-izquierda y arriba derecha) - - "⌋": [t: "⠠⠾"] # 0x230B (cerrar suelo) - - "⌊": [t: "⠷⠄"] # 0x230A (abrir suelo) - - "⌉": [t: "⠐⠾"] # 0x2309 (cerrar techo) - - "⌈": [t: "⠷⠂"] # 0x2308 (abrir techo) - - "⋩": [t: "⠕⠂"] # 0x22E9 (posterior a MULTI) - - "⋨": [t: "⠐⠪"] # 0x22E8 (anterior a MULTI) - - "⋟": [t: "⠕⠂⠶"] # 0x22DF (posterior o igual a) - - "⋞": [t: "⠐⠪⠶"] # 0x22DE (anterior o igual a) - - "⋝": [t: "⠕⠶"] # 0x22DD (mayor o igual que MULTI) - - "⋜": [t: "⠪⠶"] # 0x22DC (menor o igual que MULTI) - - "⋏": [t: "⠸⠣"] # 0x22CF (proposición falsa) - - "⋎": [t: "⠸⠎"] # 0x22CE (proposición verdadera) - - "⨂": [t: "⠪⠦"] # 0x2A02 (producto tensorial) - - "⨁": [t: "⠪⠖"] # 0x2A01 (suma directa) - - "⋃": # 0x22C3 (unión de una familia de conjuntos) - - t: "⠿⠜" - - test: - if: "not(IsNode(.., 'modified'))" - then: [t: "⠱"] - - "⋂": # 0x22C2 (intersección de una familia de conjuntos) - - t: "⠿⠱" - - test: - if: "not(IsNode(.., 'modified'))" - then: [t: "⠱"] - - "⋁": # 0x22C1 (disyunción de una familia de proposiciones) - - t: "⠿⠊" - - test: - if: "not(IsNode(.., 'modified'))" - then: [t: "⠱"] - - "⋀": # 0x22C0 (conjunción de una familia de proposiciones) - - t: "⠿⠢" - - test: - if: "not(IsNode(.., 'modified'))" - then: [t: "⠱"] - - "⊿": [t: "⠸⠦"] # 0x22BF (triángulo rectángulo) - - "⊩": [t: "⠸⠶"] # 0x22A9 (tautología) - - "⊮": [t: "⠘⠸⠶"] # 0x22AE (no tautología) - - "⊇": [t: "⠰⠜"] # 0x2287 (incluye o es igual a) - - "⊉": [t: "⠘⠰⠜"] # 0x2289 (no incluye ni es igual a) - - "⊆": [t: "⠣⠆"] # 0x2286 (incluido o es igual a) - - "⊈": [t: "⠘⠣⠆"] # 0x2288 (no incluido ni es igual a) - - "⊃": [t: "⠠⠜"] # 0x2283 (Incluye; tiene como subconjunto) - - "⊅": [t: "⠘⠠⠜"] # 0x2285 (no incluye a) - - "⊂": [t: "⠣⠄"] # 0x2282 (Incluido; subconjunto) - - "⊄": [t: "⠘⠣⠄"] # 0x2284 (no incluido en) - - "⋡": [t: "⠘⠕⠂⠶"] # 0x22E1 (no es posterior ni igual a) - - "≽": [t: "⠕⠂⠶"] # 0x227D (sigue o igual a) - - "⋠": [t: "⠘⠐⠪⠶"] # 0x22E0 (no es anterior ni igual a) - - "≼": [t: "⠐⠪⠶"] # 0x227C (precede o igual a) - - "≹": [t: "⠘⠕⠪"] # 0x2279 (ni mayor ni menor que) - - "≸": [t: "⠘⠕⠪"] # 0x2278 (ni mayor ni menor que) - - "≧": [t: "⠕⠶"] # 0x2267 (mayor o igual que MULTI) - - "≦": [t: "⠪⠶"] # 0x2266 (menor o igual que MULTI) - - "≱": [t: "⠘⠕⠶"] # 0x2271 (no es mayor ni igual que) - - "≥": [t: "⠕⠶"] # 0x2265 (mayor o igual que MULTI) - - "≤": [t: "⠪⠶"] # 0x2264 (menor o igual que MULTI) - - "≰": [t: "⠘⠪⠶"] # 0x2270 (no es menor ni igual que) - - "⩽": [t: "⠪⠶"] # 0x227D - - "⩾": [t: "⠕⠶"] # 0x2A7E (greater-than-or-slanted-equals) - # FIX: ≈" p99 has "⠐⠶" - - "≈": [t: "⠐⠶⠄"] # 0x2248 (casi igual a; asintóticamente igual a) - - "≄": [t: "⠘⠐⠶⠄"] # 0x2244 (no es asintóticamente igual a) - - "≁": [t: "⠘⠐⠢⠄"] # 0x2241 (tilde sube-baja tachada) - - "∺": [t: "⠨⠒⠅"] # 0x223A (progresión geométrica) - - "∷": [t: "⠰⠆"] # 0x2237 (proporción; igualdad de razones) - - "∶": [t: "⠐⠂"] # 0x2236 (ratio) - - "∵": [t: "⠀⠈⠌⠀"] # 0x2235 (puesto que) - - "∴": [t: "⠀⠠⠡⠀"] # 0x2234 (por lo tanto) - - "∪": [t: "⠸⠜"] # 0x222A (unión) - - "⩊": [t: "⠢⠔"] # 0x2A4A (curva geométrica) - - "∩": [t: "⠸⠱"] # 0x2229 (intersección) - - "⊻": [t: "⠸⠮"] # 0x2228 (disyunción excluyente) - - "∨": [t: "⠸⠊"] # 0x2228 (disyunción (o)) - - "∧": [t: "⠸⠢"] # 0x2227 (conjunción (y)) - - "∤": [t: "⠘⠸⠀"] # 0x2224 (no es divisor de) - - "∝": [t: "⠸⠲"] # 0x221D (proporcional a) - - "∖": [t: "⠐⠄"] # 0x2216 (diferencia de conjuntos) - - "∌": [t: "⠘⠐⠜"] # 0x220C (no comprende; no tiene como elemento) - - "∋": [t: "⠐⠜"] # 0x220B (comprende; tiene como elemento) - - "∈": [t: "⠣⠂"] # 0x2208 (es elemento de; pertenece a) - - "∉": [t: "⠘⠣⠂"] # 0x2209 (no es un elemento de; no pertenece a) - - "∅": [t: "⠸⠚"] # 0x2205 (conjunto vacío) - - "∃": [t: "⠨⠢"] # 0x2203 (cuantificador existencial: existe por lo menos un elemento) - - "∄": [t: "⠘⠨⠢"] # 0x2204 (no existe) - - "∀": [t: "⠨⠄"] # 0x2200 (cuantificador universal: para todo) - - "ǁ": [t: "⠸⠇"] # 0x01C1 (doble barra) - - "÷": [t: "⠲"] # 0x00F7 (dividido por) - - "×": # 0x00D7 (multiplicar (aspas)) - # FIX: this is a hacky attempt to figure out whether this is vector multiplication or regular multiplication - # Look for an arrow above or a bold on each side - - test: - if: - - "preceding-sibling::*[1][@math-variant='bold' or self::m:mover[*[2][.='→' or .='⟶' or .='⇀']]] and" - - "following-sibling::*[1][@math-variant='bold' or self::m:mover[*[2][.='→' or .='⟶' or .='⇀']]]" - then: [t: "⠈⠦"] - else: [t: "⠦"] - - "≫": [t: "⠕⠕"] # 0x226B (mucho mayor que) - - "≪": [t: "⠪⠪"] # 0x226A (mucho menor que) - - "±": [t: "⠖⠒⠤"] # 0x00B1 (más o menos) - - "⊁": [t: "⠘⠕⠂"] # 0x2281 (no es posterior a) - - "≻": [t: "⠕⠂"] # 0x227B (sigue a; posterior a) - - "≯": [t: "⠘⠕"] # 0x226F (no mayor que) - - "=": [t: "⠶"] # 0x003D (igual a) - - "≠": [t: "⠘⠶"] # 0x2260 (distinto de) - - "⊀": [t: "⠘⠐⠪"] # 0x2280 (no es anterior a) - - "⪼": [t: "⠕⠕⠂"] # 0x2ABC (muy posterior a) - - "⪻": [t: "⠐⠪⠪"] # 0x2ABB (muy anterior a) - - "≺": [t: "⠐⠪"] # 0x227A (precede a; anterior a) - - "≮": [t: "⠘⠪"] # 0x226E (no menor que) - - "∓": [t: "⠤⠒⠖"] # 0x2213 (menos o más) - - "∕": [t: "⠠⠂"] # 0x2215 (conjunto cociente) - - "〛": [t: "⠾⠂"] # 0x301B (cerrar corchetes de clase) - - "〚": [t: "⠐⠷"] # 0x301A (abrir corchetes de clase) - - "₡": [t: "⠸⠉"] # 0x20A1 (colón) - - "€": [t: "⠸⠑"] # 0x20AC (euro) - - "¥": [t: "⠸⠽"] # 0x00A5 (yen) - - "£": [t: "⠐⠮"] # 0x00A3 (libra) - - "¢": [t: "⠘⠉"] # 0x00A2 (centavo) - - "〉": [t: "⠨⠂"] # 0x232A (cerrar paréntesis angulares) - - "〈": [t: "⠐⠅"] # 0x2329 (abrir paréntesis angulares) - - "⟨": [t: "⠐⠅"] # 0x27E8 (Mathematical left angle bracket) - - "⟩": [t: "⠨⠂"] # 0x27E9 (Mathematical right angle bracket) - - "}": [t: "⠸⠂"] # 0x007D (cerrar llaves) - - "|": [t: "⠸𝘄"] # 0x007C (barra vertical) - - "{": [t: "⠐⠇"] # 0x007B (abrir llaves) - - "\\": [t: "⠐⠄"] # 0x005C (barra inversa) - - ";": [t: "⠀⠆"] # 0x003B (punto y coma de separación) - - "/": [t: "⠲"] # 0x002F (barra oblicua) - - "%": [t: "⠸⠴"] # 0x0025 (tanto por ciento) - - "$": - - test: - if: "following-sibling::*[self::m:mn]" - then: [t: "⠸⠏"] # 0x0024 (peso) - else: [t: "⠸⠎"] # 0x0024 (dólar) - - "#": [t: "⠼⠅"] # 0x0023 (cardinal de un conjunto) - - "₿": [t: "⠸⠃"] # 0x20BF (bitcoin) - - "⟧": [t: "⠾⠂"] # 0x27E7 (cerrar corchete de clase) - - "⟦": [t: "⠐⠷"] # 0x27E6 (abrir corchete de clase) - - "∇": [t: "⠈⠻"] # 0x2207 (Nabla (del, inverted capital delta)) - - - "≐": [t: "⠈⠶"] # 0x2250 (aproximadamente igual a) - - "≟": [t: "⠶⠢⠀"] # 0x225F (cuestionado que sea igual a) - - "≔": [t: "⠰⠶"] # 0x2254 (igual por definición) - - "≙": [t: "⠰⠒⠶"] # 0x2259 (corresponde a) - - "≡": [t: "⠶⠶"] # 0x2261 (idéntico a; congruente con) - - - "∥": [t: "⠸⠇"] # 0x2225 (es paralela a) - - "∦": [t: "⠘⠸⠇"] # 0x2226 (no paralela) - - "≅": [t: "⠐⠢⠶"] # 0x2245 (congruente con) - - "⊥": [t: "⠼⠄"] # 0x22A5 (perpendicular a/ortogonal a) [symbol used in spec] - - "⟂": [t: "⠼⠤"] # 0x27C2 (Perpendicular) - - - "⊙": [t: "⠰⠄"] # 0x2299 (operador genérico (suele utilizarse para representar una operación entre elementos de un conjunto) - - "⊚": [t: "⠰⠄"] # 0x229A (operador genérico (suele utilizarse para representar una operación entre elementos de un conjunto) - - "⋆": [t: "⠰⠄"] # 0x22C6 (operador genérico (suele utilizarse para representar una operación entre elementos de un conjunto) - - "†": [t: "⠰⠄"] # 0x2020 (operador genérico (suele utilizarse para representar una operación entre elementos de un conjunto) - - "∗": [t: "⠰⠄"] # 0x2217 (operador genérico (suele utilizarse para representar una operación entre elementos de un conjunto) +--- +# UEB characters +# +# Some chars that originally came from an Excel spreadsheet, converted to csv, and the greatly expanded +# +# The UEB translation makes use of some non-braille chars as flags +# L -- what follows is a letter +# N -- what follows is a digit +# C -- precedes L for capital letters +# G -- precedes L for Greek Letters (after C for capitals) +# Typeface Indicators ("typeforms") +# B bold, I Italic, S Sans-serif, T script, D, Fraktur, 𝔹 blackboard-bold +# the type face indicators can be combined with B (first) and I (second) +# Standing alone chars: +# Any character which acts as a standing alone character (e.g, "{") needs each braille symbol to be labeled +# o -- opening/left side, c -- closing/right side, b -- both open and close (e.g, '"') + + - "0": [t: "N⠚"] # 0x30 + - "1": [t: "N⠁"] # 0x31 + - "2": [t: "N⠃"] # 0x32 + - "3": [t: "N⠉"] # 0x33 + - "4": [t: "N⠙"] # 0x34 + - "5": [t: "N⠑"] # 0x35 + - "6": [t: "N⠋"] # 0x36 + - "7": [t: "N⠛"] # 0x37 + - "8": [t: "N⠓"] # 0x38 + - "9": [t: "N⠊"] # 0x39 + +# we stick the drop numbers into the private use area for consistency + - "\ue000": [t: "N⠴"] # 0 + - "\ue001": [t: "N⠂"] # 1 + - "\ue002": [t: "N⠆"] # 2 + - "\ue003": [t: "N⠒"] # 3 + - "\ue004": [t: "N⠲"] # 4 + - "\ue005": [t: "N⠢"] # 5 + - "\ue006": [t: "N⠖"] # 6 + - "\ue007": [t: "N⠶"] # 7 + - "\ue008": [t: "N⠦"] # 8 + - "\ue009": [t: "N⠔"] # 9 + +# we stick hex digits into the private use area for consistency +# these are used when we don't want to add a numeric indicator for subsequent digits (3.3) + - "\ue00A": [t: "N⠐N⠁"] # A + - "\ue00B": [t: "N⠐N⠃"] # B + - "\ue00C": [t: "N⠐N⠉"] # C + - "\ue00D": [t: "N⠐N⠙"] # D + - "\ue00E": [t: "N⠐N⠑"] # E + - "\ue00F": [t: "N⠐N⠋"] # F + +# leave room for the rest of the alphabet + - "\ue01A": [t: "N⠨N⠁"] # A + - "\ue01B": [t: "N⠨N⠃"] # B + - "\ue01C": [t: "N⠨N⠉"] # C + - "\ue01D": [t: "N⠨N⠙"] # D + - "\ue01E": [t: "N⠨N⠑"] # E + - "\ue01F": [t: "N⠨N⠋"] # F + +# Omission char -- there isn't a specific code point, so we use a private use area + - "\ue020": [t: "⠰"] # omission (three dot 5s with letter indicator) + + + - "a": [t: "L⠁"] # 0x61 + - "b": [t: "L⠃"] # 0x62 + - "c": [t: "L⠉"] # 0x63 + - "d": [t: "L⠙"] # 0x64 + - "e": [t: "L⠑"] # 0x65 + - "f": [t: "L⠋"] # 0x66 + - "g": [t: "L⠛"] # 0x67 + - "h": [t: "L⠓"] # 0x68 + - "i": [t: "L⠊"] # 0x69 + - "j": [t: "L⠚"] # 0x6a + - "k": [t: "L⠅"] # 0x6b + - "l": [t: "L⠇"] # 0x6c + - "m": [t: "L⠍"] # 0x6d + - "n": [t: "L⠝"] # 0x6e + - "o": # 0x6f + - test: # special case because these have the same dot pattern + if: "preceding-sibling::*[1][self::m:mo and (.='>' or .='≫')]" + then: [t: "⠐"] + - t: "L⠕" + - "p": [t: "L⠏"] # 0x70 + - "q": [t: "L⠟"] # 0x71 + - "r": [t: "L⠗"] # 0x72 + - "s": [t: "L⠎"] # 0x73 + - "t": [t: "L⠞"] # 0x74 + - "u": [t: "L⠥"] # 0x75 + - "v": [t: "L⠧"] # 0x76 + - "w": [t: "L⠺"] # 0x77 + - "x": [t: "L⠭"] # 0x78 + - "y": [t: "L⠽"] # 0x79 + - "z": [t: "L⠵"] # 0x7a + + + - "á": [t: "L⠷"] # 0xE1 + - "é": [t: "L⠮"] # 0xE9 + - "í": [t: "L⠌"] # 0xED + - "ñ": [t: "L⠻"] # 0xF1 + - "ó": [t: "L⠬"] # 0xF3 + - "ú": [t: "L⠾"] # 0xFA + - "ü": [t: "L⠳"] # 0xFC + + - "Á": [t: "CL⠷"] # 0xC0 + - "É": [t: "CL⠮"] # 0xC9 + - "Í": [t: "CL⠌"] # 0xCD + - "Ñ": [t: "CL⠻"] # 0xD1 + - "Ó": [t: "CL⠬"] # 0xD3 + - "Û": [t: "CL⠾"] # 0xDA + - "Ü": [t: "CL⠳"] # 0xDC + + # Latin capitals: chem-element letters use 𝐶 (no word indicator); others use C. + # Cells come from lowercase a-z via spell/translate. + - "BCHIKNOPSUVWY": # chemistry-capable capitals + - test: + if: "@data-chem-element" + then: [tc: "𝐶"] + else: [tc: "C"] + - spell: "translate('.', 'BCHIKNOPSUVWY', 'bchiknopsuvwy')" + - "ADEFGJLMQRTXZ": # remaining capitals + - tc: "C" + - spell: "translate('.', 'ADEFGJLMQRTXZ', 'adefgjlmqrtxz')" + + - "α": [t: "GL⠁"] # 0x3b1 + - "β": [t: "GL⠃"] # 0x3b2 + - "γ": [t: "GL⠛"] # 0x3b3 + - "δ": [t: "GL⠙"] # 0x3b4 + - "ε": [t: "GL⠑"] # 0x3b5 + - "ζ": [t: "GL⠵"] # 0x3b6 + - "η": [t: "GL⠱"] # 0x3b7 + - "θ": [t: "GL⠹"] # 0x3b8 + - "ι": [t: "GL⠊"] # 0x3b9 + - "κ": [t: "GL⠅"] # 0x3ba + - "λ": [t: "GL⠇"] # 0x3bb + - "μ": [t: "GL⠍"] # 0x3bc + - "ν": [t: "GL⠝"] # 0x3bd + - "ξ": [t: "GL⠭"] # 0x3be + - "ο": [t: "GL⠕"] # 0x3bf + - "π": [t: "GL⠏"] # 0x3c0 + - "ρ": [t: "GL⠗"] # 0x3c1 + - "ς": [t: "VL⠎"] # 0x3c2 + - "σ": [t: "GL⠎"] # 0x3c3 + - "τ": [t: "GL⠞"] # 0x3c4 + - "υ": [t: "GL⠥"] # 0x3c5 + - "φ": [t: "GL⠋"] # 0x3c6 + - "χ": [t: "GL⠯"] # 0x3c7 + - "ψ": [t: "GL⠽"] # 0x3c8 + - "ω": [t: "GL⠺"] # 0x3c9 + + - "Α": [t: "CGL⠁"] # 0x391 + - "Β": [t: "CGL⠃"] # 0x392 + - "Γ": [t: "CGL⠛"] # 0x393 + - "Δ": [t: "CGL⠙"] # 0x394 + - "Ε": [t: "CGL⠑"] # 0x395 + - "Ζ": [t: "CGL⠵"] # 0x396 + - "Η": [t: "CGL⠱ "] # 0x397 + - "Θ": [t: "CGL⠹"] # 0x398 + - "Ι": [t: "CGL⠊"] # 0x399 + - "Κ": [t: "CGL⠅"] # 0x39a + - "Λ": [t: "CGL⠇"] # 0x39b + - "Μ": [t: "CGL⠍"] # 0x39c + - "Ν": [t: "CGL⠝"] # 0x39d + - "Ξ": [t: "CGL⠭"] # 0x39e + - "Ο": [t: "CGL⠕"] # 0x39f + - "Π": [t: "CGL⠏"] # 0x3a0 + - "Ρ": [t: "CGL⠗"] # 0x3a1 + - "΢": [t: "CGL⠎"] # 0x3a2 + - "Σ": [t: "CGL⠎"] # 0x3a3 + - "Τ": [t: "CGL⠞"] # 0x3a4 + - "Υ": [t: "CGL⠥"] # 0x3a5 + - "Φ": [t: "CGL⠋"] # 0x3a6 + - "Χ": [t: "CGL⠯"] # 0x3a7 + - "Ψ": [t: "CGL⠽"] # 0x3a8 + - "Ω": [t: "CGL⠺"] # 0x3a9 + + - "ϑ": [t: "VL⠹"] # 0x3d1 + - "ϵ": [t: "VL⠑"] # 0x3f5 + - "ϰ": [t: "VL⠅"] # 0x3f0 + - "ϕ": [t: "VL⠋"] # 0x3d5 + - "ϱ": [t: "VL⠗"] # 0x3f1 + - "ϖ": [t: "VL⠏"] # 0x3d6 + - "Ϝ": [t: "VL⠧"] # 0x3d7 + + - "µ": [t: "GL⠍"] # 0x00B5 (Micro (Greek mu)) + - "Ω": [t: "CGL⠺"] # 0x2126 (Ohm sign (capital Greek omega)) + - "∆": [t: "⠸⠦"] # 0x2206 (Increment) + - "∏": # 0x220F (Product (capital Greek pi)) + - t: "CGL⠏" + - test: + if: "not(IsNode(.., 'modified'))" + then: [t: "⠱"] + - "∐": # 0x2210 (CoProduct (capital Greek pi)) + - t: "⠘⠻" + - test: + if: "not(IsNode(.., 'modified'))" + then: [t: "⠱"] + - "∑": # 0x2211 (Sum (capital Greek sigma)) + - t: "CGL⠎" + - test: + if: "not(IsNode(.., 'modified'))" + then: [t: "⠱"] + + - "<": [t: "⠪"] # 0x003C (Less than) + - "≨": [t: "⠪"] # 0x2268 (Less-Than But Not Equal To) + - "⋦": [t: "⠪"] # 0x22E6 (Less-Than But Not Equivalent To) + - ">": [t: "⠕"] # 0x003E (Greater than) + - "≩": [t: "⠕"] # 0x2269 (Greater-Than But Not Equal To) + - "⋧": [t: "⠕"] # 0x22E7 (Greater-Than But Not Equivalent To) +# - "≮": [t: "⠈⠣⠈⠱"] # 0x226E (Not less than) +# - "≯": [t: "⠈⠜⠈⠱"] # 0x226F (Not greater than) +# - "≰": [t: "⠸⠈⠣⠈⠱"] # 0x2270 (Neither less than nor equal to) +# - "≱": [t: "⠸⠈⠜⠈⠱"] # 0x2271 (Neither greater than nor equal to) +# - "∝": [t: "⠸⠐⠶"] # 0x221D (Proportional to) +# - "≃": [t: "⠸⠔"] # 0x2243 (Approximately equal to (tilde over horizontal line)) +# - "≅": [t: "⠐⠸⠔"] # 0x2245 (Approximately equal to (tilde over equals sign)) +# - "≏": [t: "⠘⠐⠶"] # 0x224F (Equals with bump in top bar (difference between)) +# - "≢": [t: "⠸⠿⠈⠱"] # 0x2262 (Not identical to) +# - "∈": [t: "⠘⠑"] # 0x2208 (Element of (member of)) +# - "∉": [t: "⠘⠑⠈⠱"] # 0x2209 (Not Element of) + - "+": [t: "⠖"] # 0x002B (Plus sign) +# - "∋": [t: "⠈⠘⠑"] # 0x220B (Contains) +# - "⊂": [t: "⠘⠣"] # 0x2282 (Subset of) +# - "⊃": [t: "⠘⠜"] # 0x2283 (Superset of) +# - "⊆": [t: "⠸⠘⠣"] # 0x2286 (Subset of or equal) +# - "⊇": [t: "⠸⠘⠜"] # 0x2287 (Superset of or equal) +# - "⊊": [t: "⠨⠘⠣"] # 0x228A (Subset of with not equal) +# - "⊋": [t: "⠨⠘⠜"] # 0x228B (Superset of with not equal) +# - "⊲": [t: "⠈⠸⠣"] # 0x22B2 (Normal subgroup of) +# - "⊳": [t: "⠈⠸⠜"] # 0x22B3 (Contains as normal subgroup) +# - "⊴": [t: "⠸⠸⠣"] # 0x22B4 (Normal subgroup of or equal) +# - "⊵": [t: "⠸⠸⠜"] # 0x22B5 (Contains as normal subgroup or equal) +# - "⋬": [t: "⠨⠸⠣"] # 0x22EC (not normal subgroup) -- this isn't the same as what is in GTM 10, but that similar has no Unicode equiv +# - "⋭": [t: "⠨⠸⠣"] # 0x22ED (does not contain as normal subgroup) -- this isn't the same as what is in GTM 10, but that similar has no Unicode equiv +# - "⊢": [t: "⠸⠒"] # 0x22a2 (Right tack) +# - "⊣": [t: "⠈⠸⠒"] # 0x22a3 (Left tack) + - "−": [t: "⠐⠤"] # 0x2212 (Minus sign) + - "·": [t: "⠠𝘄"] # 0x00B7 (Multiplication dot (times)) +# - "∗": [t: "⠐⠔"] # 0x2217 (Asterisk operator) + - "∘": [t: "⠠⠆"] # 0x2218 (Ring operator) value based on last row in 5.1 (probably what they should have used) + - "◦": [t: "⠠⠆"] # 0x25E6 (White bullet) (value based on 2218) + - "⋅": [t: "⠰⠄"] # 0x22C5 (Dot operator)(value based on 2218) +# - "∖": [t: "⠸⠡"] # 0x2216 (Set minus) + - "(": [t: "⠣"] # 0x0028 (Left parenthesis) + - ")": [t: "⠜"] # 0x0029 (Right parenthesis) + - "[": [t: "⠷"] # 0x005B (Left square bracket) + - "]": [t: "⠾"] # 0x005D (Right square bracket) + - "!": # 0x21 (Exclamation (factorial)) + - test: # CMU seems to use a different char for factorial (7.5) -- this weak guess for factorial + if: "self::m:mo and preceding-sibling::*" + then: [t: "⠘⠄"] + else: [t: "⠖"] + - "&": [t: "⠠⠯"] # 0x26 (Ampersand) + - "*": [t: "⠲"] # 0x002A (Asterisk) + - "?": [t: "⠢"] # 0x003F (Question mark) + - "¿": [t: "⠢"] # 0x00BF (Question mark) + - "@": [t: "⠐"] # 0x0040 (Commercial at sign) + - "^": # 0x005E (Caret (hat, up arrow)) 4.3.2 uses one form as a circumflex, and 11.1 as a geometric angle + - test: # it is not clear how to distinguish one form from another -- the following passes the tests, but is almost certainly wrong + - if: "..[self::m:mover][ *[1][self::m:mi and string-length(.)=1 and translate(., 'abcdefghijklmnopqrstuvwxyz', '') = ''] ]" + then: [t: "⠰⠒"] # circumflex + else: [t: "⠘⠒"] # angle and everything else + - "_": [t: "⠤"] # 0x005F (Low line (underscore)) + - "¯": [t: "⠈⠉"] # 0x00AF (macron) + - "═": [t: "⠈⠉⠈⠉"] # 0x2550 (BOX DRAWINGS DOUBLE HORIZONTAL) + - "~": # 0x007E (Tilde (swung dash)) + - test: # unclear what really should happen see 4.3.2, 4.3.3, 6.1, and 8.2 -- all use different codes + - if: "..[self::m:mover]" + then: [t: "⠐⠢"] + - else_if: "..[self::m:munder]" + then: [t: "⠠⠢"] + - else_if: "not(preceding-sibling::*)" + then: [t: "⠠⠄"] # (8.2 -- prefix?) + else: [t: "⠐⠢⠠"] # (6.1 -- infix?) + - ∼: # 223c (Tilde operator) + - test: # unclear what really should happen see 4.3.2, 4.3.3, 6.1, and 8.2 -- all use different codes + - if: "..[self::m:mover]" + then: [t: "⠐⠢"] + - else_if: "..[self::m:munder]" + then: [t: "⠠⠢"] + - else_if: "not(preceding-sibling::*)" + then: [t: "⠠⠄"] # (8.2 -- prefix?) + else: [t: "⠐⠢⠠"] # (6.1 -- infix?) + - "—": [t: "⠤⠤"] # 0x2014 (Em dash) + - "‖": [t: "⠸⠇"] # 0x2016 +# - "¦": [t: "⠨⠳"] # 0x00A6 (Broken bar) +# - "¬": [t: "⠈⠹"] # 0x00AC (Not sign) + - "°": [t: "⠴"] # 0x00B0 (Degree sign) + - "²": [t: "⠡⠼⠃⠉"] # 0x00B2 (superscripted 2) + - "³": [t: "⠡⠼⠉"] # 0x00B3 (superscripted 3) +# - "†": [t: "⠈⠠⠹"] # 0x2020 (Dagger) +# - "‡": [t: "⠈⠠⠻"] # 0x2021 (Double dagger) +# - "‰": [t: "⠸⠴⠴"] # 0x2030 (Per mille) + - "′": [t: "⠳"] # 0x2032 (Prime sign) + - "″": [t: "⠳⠳"] # 0x2033 (Double prime sign) + - "‴": [t: "⠳⠳⠳"] # 0x2034 (Triple prime sign) +# - "Å": [t: "⠠⠘⠫⠁"] # 0x212B (Angstrom symbol) +# - "Å": [t: "⠠⠘⠫⠁"] # 0x00C5 (WIRIS uses this for Angstrom) +# - "∀": [t: "⠘⠁"] # 0x2200 (For all) + - "∂": [t: "⠸⠙"] # 0x2202 (Partial differential) +# - "∃": [t: "⠘⠢"] # 0x2203 (There exists) +# - "∄": [t: "⠘⠢⠈⠱"] # 0x2204 (There does not exist) +# - "∅": [t: "⠈⠚"] # 0x2205 (Empty set) +# - "∎": [t: "⠸⠫⠼⠙t"] # 0x220E (End of proof) +# - "√": [t: "⠐⠩"] # 0x221A (Square root (radical) without vinculum) +# - "∠": [t: "⠸⠪"] # 0x2220 (Angle) +# - "∡": [t: "⠨⠸⠪"] # 0x2221 (Measured angle) +# - "⊾": [t: "⠼⠸⠪"] # 0x22BE (Right angle with arc) + - "∫": # 0x222B (Integral) + - t: "⠯" + - test: + if: "not(IsNode(.., 'modified'))" + then: [t: "⠱"] + - "∬": # 0x222c (Double integral) + - t: "⠯⠯" + - test: + if: "not(IsNode(.., 'modified'))" + then: [t: "⠱"] + - "∭": # 0x222d (Triple integral) + - t: "⠯⠯⠯" + - test: + if: "not(IsNode(.., 'modified'))" + then: [t: "⠱"] + - "∮": # 0x222E (Contour integral (closed line integral)) + - t: "⠯⠴" + - test: + if: "not(IsNode(.., 'modified'))" + then: [t: "⠱"] +# - "∷": [t: "⠒⠒"] # 0x2237 (Proportion) +# - "∣": [t: "⠸⠳"] # 0x2223 (Divides) +# - "∤": [t: "⠸⠳⠈⠱"] # 0x2224 (Does not divide) + - "←": # 0x2190 (Leftwards arrow) + - test: # this is a guess as to when to use each + if: # mi on either side or if parent is mover, mi on either side of the parent (e.g., A⟶B or labeled arrow) + - "(..[self::m:mrow] and preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]) or " + - "(..[self::m:mover][ ..[self::m:mrow][preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]] ])" + then: [t: "⠐⠒⠒"] # 9.1 + else: [t: "⠐⠒"] # 9.2 + - "⟵": # 0x27F5 (Long leftwards arrow) + - test: # this is a guess as to when to use each + if: # mi on either side or if parent is mover, mi on either side of the parent (e.g., A⟶B or labeled arrow) + - "(..[self::m:mrow] and preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]) or " + - "(..[self::m:mover][ ..[self::m:mrow][preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]] ])" + then: [t: "⠐⠒⠒"] # 9.1 + else: [t: "⠐⠒"] # 9.2 + - "→": # 0x2192 (Rightwards arrow) + - test: # this is a guess as to when to use each + if: # mi on either side or if parent is mover, mi on either side of the parent (e.g., A⟶B or labeled arrow), but rule out limit + - "(" + - " (..[self::m:mrow] and preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]) or " + - " (..[self::m:mover][ ..[self::m:mrow][preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]] ])" + - ") and" + - "not(../..[self::m:munder or self::m:msub][*[1][self::m:mi and starts-with(., 'lim')]])" + then: [t: "⠒⠒⠂"] # 9.1 + else: [t: "⠒⠂"] # 9.2 + - "⟶": # 0x27F6 (Long rightwards arrow) + - test: # this is a guess as to when to use each + if: # mi on either side or if parent is mover, mi on either side of the parent (e.g., A⟶B or labeled arrow), but rule out limit + - "(" + - " (..[self::m:mrow] and preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]) or " + - " (..[self::m:mover][ ..[self::m:mrow][preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]] ])" + - ") and" + - "not(../..[self::m:munder or self::m:msub][*[1][self::m:mi and starts-with(., 'lim')]])" + then: [t: "⠒⠒⠂"] # 9.1 + else: [t: "⠒⠂"] # 9.2 + - "⇀": # 0x21C0 (RIGHTWARDS HARPOON WITH BARB UPWARDS) [not mentioned in spec] + - test: # this is a guess as to when to use each + if: # mi on either side or if parent is mover, mi on either side of the parent (e.g., A⟶B or labeled arrow), but rule out limit + - "(" + - " (..[self::m:mrow] and preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]) or " + - " (..[self::m:mover][ ..[self::m:mrow][preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]] ])" + - ") and" + - "not(../..[self::m:munder or self::m:msub][*[1][self::m:mi and starts-with(., 'lim')]])" + then: [t: "⠒⠒⠂"] # 9.1 + else: [t: "⠒⠂"] # 9.2 + - "↔": # 0x2194 (Left right arrow) + - test: # this is a guess as to when to use each + if: # mi on either side or if parent is mover, mi on either side of the parent (e.g., A⟶B or labeled arrow) + - "(..[self::m:mrow] and preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]) or " + - "(..[self::m:mover][ ..[self::m:mrow][preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]] ])" + then: [t: "⠐⠒⠒⠂"] # 9.1 + else: [t: "⠐⠒⠂"] # 9.2 + - "⟷": # 0x27F7 (Long Left right arrow) + - test: # this is a guess as to when to use each + if: # mi on either side or if parent is mover, mi on either side of the parent (e.g., A⟶B or labeled arrow) + - "(..[self::m:mrow] and preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]) or " + - "(..[self::m:mover][ ..[self::m:mrow][preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]] ])" + then: [t: "⠐⠒⠒⠂"] # 9.1 + else: [t: "⠐⠒⠂"] # 9.2 +# - "↚": [t: "1⠳⠪⠈⠱"] # 0x219A (Leftwards arrow with stroke) +# - "↛": [t: "1⠳⠕⠈⠱"] # 0x219B (Rightwards arrow with stroke) +# - "↜": [t: "1⠳⠔⠢⠪"] # 0x219C (Leftwards wave arrow) +# - "↝": [t: "1⠳⠢⠔⠕"] # 0x219D (Rightwards wave arrow) +# - "↞": [t: "1⠳⠒⠗⠗⠪"] # 0x219E (Leftwards two headed arrow) +# - "↟": [t: "1⠳⠒⠗⠗⠬"] # 0x219F (Upwards two headed arrow) +# - "↠": [t: "1⠳⠒⠗⠗⠕"] # 0x21A0 (Rightwards two headed arrow) +# - "↡": [t: "1⠳⠒⠗⠗⠩"] # 0x21A1 (Downwards two headed arrow) +# - "↢": [t: "1⠳⠗⠗⠪"] # 0x21A2 (Leftwards arrow with tail) +# - "↣": [t: "1⠳⠗⠗⠕"] # 0x21A3 (Rightwards arrow with tail) +# - "↤": [t: "1⠳⠳⠗⠪"] # 0x21A4 (Leftwards arrow from bar) +# - "↥": [t: "1⠳⠳⠗⠬"] # 0x21A5 (Upwards arrow from bar) +# - "↦": [t: "1⠳⠳⠗⠕"] # 0x21A6 (Rightwards arrow from bar) +# - "↧": [t: "1⠳⠳⠗⠩"] # 0x21A7 (Downwards arrow from bar) +# - "↭": [t: "1⠳⠺⠔⠢⠗⠕"] # 0x21AD (Left right wave arrow) +# - "↮": [t: "1⠳⠺⠗⠕⠈⠱"] # 0x21AE (Left right arrow with stroke) +# - "↰": [t: "1⠳⠴⠬"] # 0x21B0 (Upwards arrow with tip left) +# - "↱": [t: "1⠳⠲⠬"] # 0x21B1 (Upwards arrow with tip right) +# - "↲": [t: "1⠳⠲⠩"] # 0x21B2 (Downwards arrow with tip left) +# - "↳": [t: "1⠳⠴⠩"] # 0x21B3 (Downwards arrow with tip right) +# - "↶": [t: "1⠳⠔⠔⠪"] # 0x21B6 (Anticlockwise top semicircle arrow) +# - "↷": [t: "1⠳⠢⠢⠕"] # 0x21B7 (Clockwise top semicircle arrow) +# - "↼": [t: "1⠳⠈⠗⠪"] # 0x21BC (Leftwards harpoon with barb upwards) +# - "↽": [t: "1⠳⠠⠗⠪"] # 0x21BD (Leftwards harpoon with barb downwards) +# - "↾": [t: "1⠳⠠⠗⠬"] # 0x21BE (Upwards harpoon with barb rightwards) +# - "↿": [t: "1⠳⠈⠗⠬"] # 0x21BF (Upwards harpoon with barb leftwards) +# - "⇀": [t: "1⠳⠈⠗⠕"] # 0x21C0 (Rightwards harpoon with barb upwards) +# - "⇁": [t: "1⠳⠠⠗⠕"] # 0x21C1 (Rightwards harpoon with barb downwards) +# - "⇂": [t: "1⠳⠈⠗⠩"] # 0x21C2 (Downwards harpoon with barb rightwards) +# - "⇃": [t: "1⠳⠠⠗⠩"] # 0x21C3 (Downwards harpoon with barb leftwards) +# - "⇄": [t: "1⠳⠕⠻⠳⠪"] # 0x21C4 (Rightwards arrow over leftwards arrow) +# - "⇅": [t: "1⠳⠬⠿⠳⠩"] # 0x21C5 (Upwards arrow left of Downwards arrow) +# - "⇌": [t: "⠘⠸⠶"] # 0x21CC (Rightwards harpoon over leftwards harpoon (equilibrium)) +# - "⇑": [t: "1⠳⠶⠬"] # 0x21D1 (Upwards double arrow) +# - "⇓": [t: "1⠳⠶⠩"] # 0x21D3 (Downwards double arrow) +# - "⇕": [t: "1⠳⠺⠶⠗⠬"] # 0x21D5 (Up down double arrow) +# - "⇠": [t: "1⠳⠂⠪"] # 0x21E0 (Leftwards dashed arrow) +# - "⇡": [t: "1⠳⠂⠬"] # 0x21E1 (Upwards dashed arrow) +# - "⇢": [t: "1⠳⠂⠕"] # 0x21E2 (Rightwards dashed arrow) +# - "⇣": [t: "1⠳⠂⠩"] # 0x21E3 (Downwards dashed arrow) +# - "⥂": [t: "⠸⠶"] # 0x2942 (Rightwards arrow above short leftwards arrow (equilibrium, trend to the right)) +# - "⥄": [t: "⠈⠸⠶"] # 0x2944 (Short rightwards arrow above leftwards arrow (equilibrium, trend to the left)) +# - "▤": [t: "⠨⠫⠼⠙t"] # 0x25A4 (Square with horizontal fill) +# - "▥": [t: "⠨⠫⠼⠙t"] # 0x25A5 (Square with vertical fill) +# - "▦": [t: "⠨⠫⠼⠙t"] # 0x25A6 (Square with orthogonal crosshatch fill) +# - "▧": [t: "⠨⠫⠼⠙t"] # 0x25A7 (Square with upper left to lower right fill) +# - "▨": [t: "⠨⠫⠼⠙t"] # 0x25A8 (Square with upper right to lower left fill) +# - "▩": [t: "⠨⠫⠼⠙t"] # 0x25A9 (Square with diagonal crosshatch fill) +# - "◍": [t: "⠨⠫⠿t"] # 0x25CD (Circle with vertical fill) +# - "▱": [t: "1⠫⠈⠼⠙t"] # 0x25B1 (Parallelogram) +# - "▲": [t: "⠸⠫⠼⠉t"] # 0x25B2 (Filled triangle) +# - "■": [t: "⠸⠫⠼⠙t"] # 0x25A0 (Filled square) +# - "≜": [t: "⠠⠨⠙⠻⠐⠶"] # 0x225C (Delta equal to) +# - "≝": [t: "1⠣⠙⠑⠋⠜⠻⠐⠶"] # 0x225D (Equal to by definition) +# - "⊕": [t: "1⠫⠿⠪⠐⠖t"] # 0x2295 (Circled plus) +# - "⊖": [t: "1⠫⠿⠪⠐⠤t"] # 0x2296 (Circled minus) +# - "⊗": [t: "1⠫⠿⠪⠐⠦t"] # 0x2297 (Circled times) +# - "⊛": [t: "1⠫⠿⠪⠐⠔t"] # 0x229B (Circled asterisk operator) +# - "⊞": [t: "1⠫⠼⠙⠪⠐⠖t"] # 0x229E (Squared plus) +# - "⊟": [t: "1⠫⠼⠙⠪⠐⠤t"] # 0x229F (Squared minus) +# - "⊠": [t: "1⠫⠼⠙⠪⠐⠦t"] # 0x22A0 (Squared times) +# - "⋇": [t: "1⠌⠯⠦"] # 0x22C7 (Division times) +# - "⊩": [t: "⠸⠳⠿⠸⠒"] # 0x22A9 (Forces) + - "˙": [t: "⠈"] # 0x02D9 ( Dot Above) + - "¨": [t: "⠈⠈"] # 0x00A8 ( Diaeresis/Double Dot Above ) + - "⃛": [t: "⠈⠈⠈"] # 0x20db (combining triple dot) + - "©": [t: "⠣⠨⠉⠜"] # 0xa9 (Copyright) + - "®": [t: "⠣⠨⠗⠜"] # 0xa9 (Registered sign) + + - "…": [t: "⠄⠄⠄"] # 0x2026 (Ellipsis) + - "⋯": [t: "⠄⠄⠄"] # 0x22EF (mid-line Ellipsis) -- seems to be same based on Example 10.1.3 + + +# All the quotes are the same + - "\"": [t: "⠦"] + - "'": [t: "⠄"] + - "“": [t: "⠦"] # 0x201C + - "”": [t: "⠦"] # 0x201C + - "‘": [t: "⠦"] + - "’": # 0x2019 (2.3_3) + - test: + if: "self::m:mn" + then: [t: "N⠂"] # same as '.' block separator + else: [t: "⠦"] + - "«": [t: "⠦"] + - "»": [t: "⠦"] + + - " ": # 0x20 (Space) + - test: + - if: "self::m:mn" + then: [t: "N⠄"] + - else_if: "@data-added='missing-content' or @data-empty-in-2D or @width > 1.1" + then: [t: "⠰⠤⠆"] # omission + - else_if: "@width < 0.25" + then: [t: ""] # tweaking space -- ignore + else: [t: "W"] # space in text or wide enough space + - " ": # 0xa0 (Non-breaking Space) + - test: + - if: "self::m:mn" + then: [t: "N⠄"] + else: [t: "W"] + - ",": # 0x2c (Comma) + - test: + if: "self::m:mn" + then: [t: "N⠂"] + else: [t: "W⠂"] + - ".": # 0x2e (Period) -- 2.3 says that if this is acting like a decimal separator, it should be brailled like "," + - test: + if: "self::m:mn" + then: + # presunme this is likely uses "," for a decimal separator, so just do a few checks + # 1. if there are < 3 chars after the first ".", then not a block separator + # 2. if there is a '.' or other likely block separator after the first '.', then not decimal separator + # likely other (complicated?) other tests that could be used + - with: + variables: [StringAfter: "substring-after(., '.')"] + replace: + - test: + if: "string-length($StringAfter) >= 3 and string-length($StringAfter)=string-length( translate($StringAfter, $BlockSeparators, '') )" + then: [t: "N⠄"] # really is a block separator + else: [t: "N⠂"] # treat as decimal separator + else: [t: "W⠄"] + - ":": [t: "⠐⠂"] # 0x003A (Colon) + - "-": [t: "⠤"] # 0x2d (Minus sign or hyphen) + - "⁡": [t: ""] # 0x2061⁡ (invisible function apply) + - "⁢": [t: ""] # 0x2062 (invisible times) + - "⁣": [t: ""] # 0x2063⁡ (invisible separator) + - "⁤": [t: ""] # 0x2064 (invisible plus) + + - "`": [t: "⠢"] # 0x0060 (GRAVE ACCEN) + + - "א": [t: "⠠⠳"] # 0x05D0 (aleph) + - "○": [t: "⠪⠕"] # 0x25CB (círculo) + - "∞": [t: "⠼⠳"] # 0x221E (infinito) + - "⎔": [t: "⠯⠕"] # 0x2394 (polígono) + - "‰": [t: "⠸⠴⠴"] # 0x2030 (tanto por mil) + - "¬": [t: "⠠⠄"] # 0x00AC (negación lógica) + - "↕": [t: "⠸⠅"] # 0x2195 (flecha arriba-abajo) + - "↖": [t: "⠐⠡"] # 0x2196 (flecha oblicua arriba-izquierda) + - "↙": [t: "⠐⠌"] # 0x2199 (flecha abajo-izquierda) + - "↓": [t: "⠸⠄"] # 0x2193 (flecha hacia abajo) + - "↘": [t: "⠡⠂"] # 0x2198 (flecha oblicua abajo-derecha) + - "↗": [t: "⠌⠂"] # 0x2197 (flecha arriba-derecha) + - "↑": [t: "⠸⠁"] # 0x2191 (flecha hacia arriba) + - "△": [t: "⠠⠾"] # 0x25B3 (Triangle) + - "▭": [t: "⠯⠽"] # 0x25AD (rectángulo) + - "□": [t: "⠸⠽"] # 0x25A1 (cuadrado) + - "⟺": [t: "⠪⠒⠕"] # 0x27FA (doble implicación «si y solo si») + - "⟸": [t: "⠪⠒"] # 0x27F8 (implicación recíproca; porque) + - "⟹": [t: "⠒⠕"] # 0x27F9 (implicación directa; implica) + - "⇔": [t: "⠪⠒⠕"] # 0x21D4 (LEFT RIGHT DOUBLE ARROW) + - "⇐": [t: "⠪⠒"] # 0x21D0 (LEFTWARDS DOUBLE ARROW) + - "⇒": [t: "⠒⠕"] # 0x21D2 (RIGHTWARDS DOUBLE ARROW) + - "⤡": [t: "⠐⠡⠂"] # 0x2921 (flecha abajo-derecha y arriba izquierda) + - "⤢": [t: "⠐⠌⠂"] # 0x2922 (flecha abajo-izquierda y arriba derecha) + - "⌋": [t: "⠠⠾"] # 0x230B (cerrar suelo) + - "⌊": [t: "⠷⠄"] # 0x230A (abrir suelo) + - "⌉": [t: "⠐⠾"] # 0x2309 (cerrar techo) + - "⌈": [t: "⠷⠂"] # 0x2308 (abrir techo) + - "⋩": [t: "⠕⠂"] # 0x22E9 (posterior a MULTI) + - "⋨": [t: "⠐⠪"] # 0x22E8 (anterior a MULTI) + - "⋟": [t: "⠕⠂⠶"] # 0x22DF (posterior o igual a) + - "⋞": [t: "⠐⠪⠶"] # 0x22DE (anterior o igual a) + - "⋝": [t: "⠕⠶"] # 0x22DD (mayor o igual que MULTI) + - "⋜": [t: "⠪⠶"] # 0x22DC (menor o igual que MULTI) + - "⋏": [t: "⠸⠣"] # 0x22CF (proposición falsa) + - "⋎": [t: "⠸⠎"] # 0x22CE (proposición verdadera) + - "⨂": [t: "⠪⠦"] # 0x2A02 (producto tensorial) + - "⨁": [t: "⠪⠖"] # 0x2A01 (suma directa) + - "⋃": # 0x22C3 (unión de una familia de conjuntos) + - t: "⠿⠜" + - test: + if: "not(IsNode(.., 'modified'))" + then: [t: "⠱"] + - "⋂": # 0x22C2 (intersección de una familia de conjuntos) + - t: "⠿⠱" + - test: + if: "not(IsNode(.., 'modified'))" + then: [t: "⠱"] + - "⋁": # 0x22C1 (disyunción de una familia de proposiciones) + - t: "⠿⠊" + - test: + if: "not(IsNode(.., 'modified'))" + then: [t: "⠱"] + - "⋀": # 0x22C0 (conjunción de una familia de proposiciones) + - t: "⠿⠢" + - test: + if: "not(IsNode(.., 'modified'))" + then: [t: "⠱"] + - "⊿": [t: "⠸⠦"] # 0x22BF (triángulo rectángulo) + - "⊩": [t: "⠸⠶"] # 0x22A9 (tautología) + - "⊮": [t: "⠘⠸⠶"] # 0x22AE (no tautología) + - "⊇": [t: "⠰⠜"] # 0x2287 (incluye o es igual a) + - "⊉": [t: "⠘⠰⠜"] # 0x2289 (no incluye ni es igual a) + - "⊆": [t: "⠣⠆"] # 0x2286 (incluido o es igual a) + - "⊈": [t: "⠘⠣⠆"] # 0x2288 (no incluido ni es igual a) + - "⊃": [t: "⠠⠜"] # 0x2283 (Incluye; tiene como subconjunto) + - "⊅": [t: "⠘⠠⠜"] # 0x2285 (no incluye a) + - "⊂": [t: "⠣⠄"] # 0x2282 (Incluido; subconjunto) + - "⊄": [t: "⠘⠣⠄"] # 0x2284 (no incluido en) + - "⋡": [t: "⠘⠕⠂⠶"] # 0x22E1 (no es posterior ni igual a) + - "≽": [t: "⠕⠂⠶"] # 0x227D (sigue o igual a) + - "⋠": [t: "⠘⠐⠪⠶"] # 0x22E0 (no es anterior ni igual a) + - "≼": [t: "⠐⠪⠶"] # 0x227C (precede o igual a) + - "≹": [t: "⠘⠕⠪"] # 0x2279 (ni mayor ni menor que) + - "≸": [t: "⠘⠕⠪"] # 0x2278 (ni mayor ni menor que) + - "≧": [t: "⠕⠶"] # 0x2267 (mayor o igual que MULTI) + - "≦": [t: "⠪⠶"] # 0x2266 (menor o igual que MULTI) + - "≱": [t: "⠘⠕⠶"] # 0x2271 (no es mayor ni igual que) + - "≥": [t: "⠕⠶"] # 0x2265 (mayor o igual que MULTI) + - "≤": [t: "⠪⠶"] # 0x2264 (menor o igual que MULTI) + - "≰": [t: "⠘⠪⠶"] # 0x2270 (no es menor ni igual que) + - "⩽": [t: "⠪⠶"] # 0x227D + - "⩾": [t: "⠕⠶"] # 0x2A7E (greater-than-or-slanted-equals) + # FIX: ≈" p99 has "⠐⠶" + - "≈": [t: "⠐⠶⠄"] # 0x2248 (casi igual a; asintóticamente igual a) + - "≄": [t: "⠘⠐⠶⠄"] # 0x2244 (no es asintóticamente igual a) + - "≁": [t: "⠘⠐⠢⠄"] # 0x2241 (tilde sube-baja tachada) + - "∺": [t: "⠨⠒⠅"] # 0x223A (progresión geométrica) + - "∷": [t: "⠰⠆"] # 0x2237 (proporción; igualdad de razones) + - "∶": [t: "⠐⠂"] # 0x2236 (ratio) + - "∵": [t: "⠀⠈⠌⠀"] # 0x2235 (puesto que) + - "∴": [t: "⠀⠠⠡⠀"] # 0x2234 (por lo tanto) + - "∪": [t: "⠸⠜"] # 0x222A (unión) + - "⩊": [t: "⠢⠔"] # 0x2A4A (curva geométrica) + - "∩": [t: "⠸⠱"] # 0x2229 (intersección) + - "⊻": [t: "⠸⠮"] # 0x2228 (disyunción excluyente) + - "∨": [t: "⠸⠊"] # 0x2228 (disyunción (o)) + - "∧": [t: "⠸⠢"] # 0x2227 (conjunción (y)) + - "∤": [t: "⠘⠸⠀"] # 0x2224 (no es divisor de) + - "∝": [t: "⠸⠲"] # 0x221D (proporcional a) + - "∖": [t: "⠐⠄"] # 0x2216 (diferencia de conjuntos) + - "∌": [t: "⠘⠐⠜"] # 0x220C (no comprende; no tiene como elemento) + - "∋": [t: "⠐⠜"] # 0x220B (comprende; tiene como elemento) + - "∈": [t: "⠣⠂"] # 0x2208 (es elemento de; pertenece a) + - "∉": [t: "⠘⠣⠂"] # 0x2209 (no es un elemento de; no pertenece a) + - "∅": [t: "⠸⠚"] # 0x2205 (conjunto vacío) + - "∃": [t: "⠨⠢"] # 0x2203 (cuantificador existencial: existe por lo menos un elemento) + - "∄": [t: "⠘⠨⠢"] # 0x2204 (no existe) + - "∀": [t: "⠨⠄"] # 0x2200 (cuantificador universal: para todo) + - "ǁ": [t: "⠸⠇"] # 0x01C1 (doble barra) + - "÷": [t: "⠲"] # 0x00F7 (dividido por) + - "×": # 0x00D7 (multiplicar (aspas)) + # FIX: this is a hacky attempt to figure out whether this is vector multiplication or regular multiplication + # Look for an arrow above or a bold on each side + - test: + if: + - "preceding-sibling::*[1][@math-variant='bold' or self::m:mover[*[2][.='→' or .='⟶' or .='⇀']]] and" + - "following-sibling::*[1][@math-variant='bold' or self::m:mover[*[2][.='→' or .='⟶' or .='⇀']]]" + then: [t: "⠈⠦"] + else: [t: "⠦"] + - "≫": [t: "⠕⠕"] # 0x226B (mucho mayor que) + - "≪": [t: "⠪⠪"] # 0x226A (mucho menor que) + - "±": [t: "⠖⠒⠤"] # 0x00B1 (más o menos) + - "⊁": [t: "⠘⠕⠂"] # 0x2281 (no es posterior a) + - "≻": [t: "⠕⠂"] # 0x227B (sigue a; posterior a) + - "≯": [t: "⠘⠕"] # 0x226F (no mayor que) + - "=": [t: "⠶"] # 0x003D (igual a) + - "≠": [t: "⠘⠶"] # 0x2260 (distinto de) + - "⊀": [t: "⠘⠐⠪"] # 0x2280 (no es anterior a) + - "⪼": [t: "⠕⠕⠂"] # 0x2ABC (muy posterior a) + - "⪻": [t: "⠐⠪⠪"] # 0x2ABB (muy anterior a) + - "≺": [t: "⠐⠪"] # 0x227A (precede a; anterior a) + - "≮": [t: "⠘⠪"] # 0x226E (no menor que) + - "∓": [t: "⠤⠒⠖"] # 0x2213 (menos o más) + - "∕": [t: "⠠⠂"] # 0x2215 (conjunto cociente) + - "〛": [t: "⠾⠂"] # 0x301B (cerrar corchetes de clase) + - "〚": [t: "⠐⠷"] # 0x301A (abrir corchetes de clase) + - "₡": [t: "⠸⠉"] # 0x20A1 (colón) + - "€": [t: "⠸⠑"] # 0x20AC (euro) + - "¥": [t: "⠸⠽"] # 0x00A5 (yen) + - "£": [t: "⠐⠮"] # 0x00A3 (libra) + - "¢": [t: "⠘⠉"] # 0x00A2 (centavo) + - "〉": [t: "⠨⠂"] # 0x232A (cerrar paréntesis angulares) + - "〈": [t: "⠐⠅"] # 0x2329 (abrir paréntesis angulares) + - "⟨": [t: "⠐⠅"] # 0x27E8 (Mathematical left angle bracket) + - "⟩": [t: "⠨⠂"] # 0x27E9 (Mathematical right angle bracket) + - "}": [t: "⠸⠂"] # 0x007D (cerrar llaves) + - "|": [t: "⠸𝘄"] # 0x007C (barra vertical) + - "{": [t: "⠐⠇"] # 0x007B (abrir llaves) + - "\\": [t: "⠐⠄"] # 0x005C (barra inversa) + - ";": [t: "⠀⠆"] # 0x003B (punto y coma de separación) + - "/": [t: "⠲"] # 0x002F (barra oblicua) + - "%": [t: "⠸⠴"] # 0x0025 (tanto por ciento) + - "$": + - test: + if: "following-sibling::*[self::m:mn]" + then: [t: "⠸⠏"] # 0x0024 (peso) + else: [t: "⠸⠎"] # 0x0024 (dólar) + - "#": [t: "⠼⠅"] # 0x0023 (cardinal de un conjunto) + - "₿": [t: "⠸⠃"] # 0x20BF (bitcoin) + - "⟧": [t: "⠾⠂"] # 0x27E7 (cerrar corchete de clase) + - "⟦": [t: "⠐⠷"] # 0x27E6 (abrir corchete de clase) + - "∇": [t: "⠈⠻"] # 0x2207 (Nabla (del, inverted capital delta)) + + - "≐": [t: "⠈⠶"] # 0x2250 (aproximadamente igual a) + - "≟": [t: "⠶⠢⠀"] # 0x225F (cuestionado que sea igual a) + - "≔": [t: "⠰⠶"] # 0x2254 (igual por definición) + - "≙": [t: "⠰⠒⠶"] # 0x2259 (corresponde a) + - "≡": [t: "⠶⠶"] # 0x2261 (idéntico a; congruente con) + + - "∥": [t: "⠸⠇"] # 0x2225 (es paralela a) + - "∦": [t: "⠘⠸⠇"] # 0x2226 (no paralela) + - "≅": [t: "⠐⠢⠶"] # 0x2245 (congruente con) + - "⊥": [t: "⠼⠄"] # 0x22A5 (perpendicular a/ortogonal a) [symbol used in spec] + - "⟂": [t: "⠼⠤"] # 0x27C2 (Perpendicular) + + - "⊙": [t: "⠰⠄"] # 0x2299 (operador genérico (suele utilizarse para representar una operación entre elementos de un conjunto) + - "⊚": [t: "⠰⠄"] # 0x229A (operador genérico (suele utilizarse para representar una operación entre elementos de un conjunto) + - "⋆": [t: "⠰⠄"] # 0x22C6 (operador genérico (suele utilizarse para representar una operación entre elementos de un conjunto) + - "†": [t: "⠰⠄"] # 0x2020 (operador genérico (suele utilizarse para representar una operación entre elementos de un conjunto) + - "∗": [t: "⠰⠄"] # 0x2217 (operador genérico (suele utilizarse para representar una operación entre elementos de un conjunto) diff --git a/Rules/Braille/Nemeth/unicode.yaml b/Rules/Braille/Nemeth/unicode.yaml index 5b9c973f9..6ac9c74d8 100644 --- a/Rules/Braille/Nemeth/unicode.yaml +++ b/Rules/Braille/Nemeth/unicode.yaml @@ -1,352 +1,352 @@ ---- -# To greatly simplify typeface/language generation, the chars have unique ASCII chars for them: -# Typeface: S: sans-serif, B: bold, T: script/blackboard, I: italic, R: Roman -# Language: E: English, D: German, G: Greek, V: Greek variants, H: Hebrew, U: Russian -# Indicators: C: capital, L: letter, N: number, P: punctuation, M: multipurpose -# Others: W -- whitespace that should be kept (e.g, in a numeral) -# SRE doesn't have H: Hebrew or U: Russian, so not encoded (yet) -# Some of the weird letters (e.g., circled letters) I didn't translate with the above because -# they don't interact with rules since they are enclosed in other chars. - - - # --- Nemeth Default Alphabet normal chars. --- - - "0": [t: "N⠴"] # 0x30 - - "1": [t: "N⠂"] # 0x31 - - "2": [t: "N⠆"] # 0x32 - - "3": [t: "N⠒"] # 0x33 - - "4": [t: "N⠲"] # 0x34 - - "5": [t: "N⠢"] # 0x35 - - "6": [t: "N⠖"] # 0x36 - - "7": [t: "N⠶"] # 0x37 - - "8": [t: "N⠦"] # 0x38 - - "9": [t: "N⠔"] # 0x39 - # Latin capitals: C + cells from lowercase a-z via spell/translate. - - "A-Z": # 0x41 - 0x5a - - tc: "C" - - spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" - - "a": [t: "L⠁"] # 0x61 - - "b": [t: "L⠃"] # 0x62 - - "c": [t: "L⠉"] # 0x63 - - "d": [t: "L⠙"] # 0x64 - - "e": [t: "L⠑"] # 0x65 - - "f": [t: "L⠋"] # 0x66 - - "g": [t: "L⠛"] # 0x67 - - "h": [t: "L⠓"] # 0x68 - - "i": [t: "L⠊"] # 0x69 - - "j": [t: "L⠚"] # 0x6a - - "k": [t: "L⠅"] # 0x6b - - "l": [t: "L⠇"] # 0x6c - - "m": [t: "L⠍"] # 0x6d - - "n": [t: "L⠝"] # 0x6e - - "o": [t: "L⠕"] # 0x6f - - "p": [t: "L⠏"] # 0x70 - - "q": [t: "L⠟"] # 0x71 - - "r": [t: "L⠗"] # 0x72 - - "s": [t: "L⠎"] # 0x73 - - "t": [t: "L⠞"] # 0x74 - - "u": [t: "L⠥"] # 0x75 - - "v": [t: "L⠧"] # 0x76 - - "w": [t: "L⠺"] # 0x77 - - "x": [t: "L⠭"] # 0x78 - - "y": [t: "L⠽"] # 0x79 - - "z": [t: "L⠵"] # 0x7a - - "Α": [t: "GCL⠁"] # 0x391 - - "Β": [t: "GCL⠃"] # 0x392 - - "Γ": [t: "GCL⠛"] # 0x393 - - "Δ": [t: "GCL⠙"] # 0x394 - - "Ε": [t: "GCL⠑"] # 0x395 - - "Ζ": [t: "GCL⠵"] # 0x396 - - "Η": [t: "GCL⠱"] # 0x397 - - "Θ": [t: "GCL⠹"] # 0x398 - - "Ι": [t: "GCL⠊"] # 0x399 - - "Κ": [t: "GCL⠅"] # 0x39a - - "Λ": [t: "GCL⠇"] # 0x39b - - "Μ": [t: "GCL⠍"] # 0x39c - - "Ν": [t: "GCL⠝"] # 0x39d - - "Ξ": [t: "GCL⠭"] # 0x39e - - "Ο": [t: "GCL⠕"] # 0x39f - - "Π": [t: "GCL⠏"] # 0x3a0 - - "Ρ": [t: "GCL⠗"] # 0x3a1 - - "ϴ": [t: "GCL⠹"] # 0x3f4 - - "Σ": [t: "GCL⠎"] # 0x3a3 - - "Τ": [t: "GCL⠞"] # 0x3a4 - - "Υ": [t: "GCL⠥"] # 0x3a5 - - "Φ": [t: "GCL⠋"] # 0x3a6 - - "Χ": [t: "GCL⠯"] # 0x3a7 - - "Ψ": [t: "GCL⠽"] # 0x3a8 - - "Ω": [t: "GCL⠺"] # 0x3a9 - - "∇": [t: "GL⠫"] # 0x2207 - - "α": [t: "GL⠁"] # 0x3b1 - - "β": [t: "GL⠃"] # 0x3b2 - - "γ": [t: "GL⠛"] # 0x3b3 - - "δ": [t: "GL⠙"] # 0x3b4 - - "ε": [t: "GL⠑"] # 0x3b5 - - "ζ": [t: "GL⠵"] # 0x3b6 - - "η": [t: "GL⠱"] # 0x3b7 - - "θ": [t: "GL⠹"] # 0x3b8 - - "ι": [t: "GL⠊"] # 0x3b9 - - "κ": [t: "GL⠅"] # 0x3ba - - "λ": [t: "GL⠇"] # 0x3bb - - "μ": [t: "GL⠍"] # 0x3bc - - "ν": [t: "GL⠝"] # 0x3bd - - "ξ": [t: "GL⠭"] # 0x3be - - "ο": [t: "GL⠕"] # 0x3bf - - "π": [t: "GL⠏"] # 0x3c0 - - "ρ": [t: "GL⠗"] # 0x3c1 - - "ς": [t: "VL⠎"] # 0x3c2 - - "σ": [t: "GL⠎"] # 0x3c3 - - "τ": [t: "GL⠞"] # 0x3c4 - - "υ": [t: "GL⠥"] # 0x3c5 - - "φ": [t: "VL⠋"] # 0x3c6 - - "χ": [t: "GL⠯"] # 0x3c7 - - "ψ": [t: "GL⠽"] # 0x3c8 - - "ω": [t: "GL⠺"] # 0x3c9 - - "ϵ": [t: "GL⠑"] # 0x3f5 - - "ϑ": [t: "VL⠹"] # 0x3d1 - - "ϰ": [t: "GL⠅"] # 0x3f0 - - "ϕ": [t: "GL⠋"] # 0x3d5 - - "ϱ": [t: "GL⠗"] # 0x3f1 - - "ϖ": [t: "GL⠏"] # 0x3d6 - - - # --- Nemeth Default Characters math_symbols chars. --- - - "`": [t: "⠈"] # 0x60 - - "⋮": # 0x22ee - - test: # if we have a triple bond represented by "⋮⋮", the we output the triple bond for the first but not the second - if: "@data-chemical-bond and (preceding-sibling::*[1] = '⋮' or following-sibling::*[1] = '⋮')" - then_test: - if: "following-sibling::*[1] = '⋮'" - then: [t: "⠨⠹"] # output only the first of the two chars - else: [t: "⠩⠄⠄"] - - "⋯": [t: "⠄⠄⠄"] # 0x22ef - - "⋰": [t: "⠘⠄⠄"] # 0x22f0 - - "⋱": [t: "⠰⠄⠄"] # 0x22f1 - - "≡": # 0x2261 - - test: - if: "@data-chemical-bond" - then: [t: "⠸⠿⠻"] - else: [t: "⠸⠇"] - - # --- Nemeth Default Characters rest chars. --- - - " ": # 0x20 (space) - - test: - if: "self::m:mn" - then: [t: "⠀"] - else: [t: "W"] - - - " ": # 0xA0 (non-breaking space) - - test: - - if: "self::m:mn" - then: [t: "⠀"] - # # part of longer string or part of preceeding or following text - - else_if: "@data-added='missing-content' or @data-empty-in-2D or @width > 1.1" - then: [t: "⠿"] # omission - - else_if: "(string-length(.) > 1 or preceding-sibling::*[1][self::m:mtext and .!=','] or following-sibling::*[1][self::m:mtext])" - then: [t: "W"] - # treat mo like 0x2061 (function apply) - - else_if: "self::m:mo and - (preceding-sibling::*[1][IsInDefinition(., 'Braille', 'GeometryShapes')] or - @data-function-likelihood and - IsInDefinition(BaseNode(.), 'Braille', 'FunctionNames') and - not(following-sibling::*[1][IsBracketed(., '', '')]) - )" - then: [t: "w"] # follows a function name, so lowercase - - - "!": # 0x21 (Factorial) - - test: - if: "self::m:mo" - then: [t: "⠯"] - else: [t: "P⠖"] - -# - "\"": [t: ""] # 0x22 (Quotation mark) - - "#": [t: "⠨⠼"] # 0x23 (Number sign) - - "$": [t: "⠈⠎"] # 0x24 (Dollar sign) - - "%": [t: "⠈⠴"] # 0x25 (Percent sign) - - "&": [t: "⠸⠯"] # 0x26 (Ampersand) - - "'": [t: "P⠄"] # 0x27 (Apostrophe) - - "(": [t: "⠷"] # 0x28 (Left parenthesis) - - ")": [t: "⠾"] # 0x29 (Right parenthesis) - - "*": [t: "⠈⠼"] # 0x002A (Asterisk) - - "+": # 0x002B (Plus sign) - - test: - # Add multipurpose indicator before prefix '+' to avoid being the same as '∓' - if: "not(preceding-sibling::*) and parent::*[1][name(.)='mrow' and preceding-sibling::*[1][name(.)='mo' and .='-']]" - then: [t: "m⠬"] - else: [t: "⠬"] - - - ",": # 0x002C (Comma) - - test: - # test if first ancestor that isn't an mrow is a script tag (rule 78) - - if: "self::m:mn" - then: [t: "⠠"] - - else_if: "ancestor-or-self::*[not(parent::m:mrow)][1][parent::m:msub or parent::m:msup or parent::m:msubsup or parent::m:mmultiscripts][preceding-sibling::*]" - then: [t: "⠪"] # Rule 78 - else: [t: ","] # ',' used for matching purposes, converted to "⠠⠀" - - "-": # 0x002D (Hyphen) (0x2212 normalized to here) -- 38vi says don't use the punctuation indicator - - test: - # Add multipurpose indicator before prefix '+' to avoid being the same as '±' or a dash - if: "@data-chemical-bond" - then: [t: "⠸⠒⠻"] - else_test: - if: "not(preceding-sibling::*) and parent::*[1][name(.)='mrow' and preceding-sibling::*[1][name(.)='mo' and (.='+' or .='-')]]" - then: [t: "m⠤"] - else: [t: "⠤"] - - - ".": # 0x002E (Full stop or decimal pt) - # '.' is particularly tricky because we need to know if it is really numeric or not. - # if it is numeric, it might be a on it's own or part of a number. - # normally, it is merged with the digits if part of a number, but if the adjacent digit(s) are modified - # by something (e.g., a bar over the digit to signify that it repeats), then it is really part of the number - # If it is the last part of the expr, then it is punctuation (for typographic reasons, punctuation is often included in the math) - - test: - if: "self::m:mn or (self::m:mo and following-sibling::*)" - then_test: - if: "string-length(text()) = 1 and not( - following-sibling::*[1][BaseNode(.)[self::m:mn]] or - following-sibling::*[1][self::m:menclose and @notation='top' and *[1][self::m:mn]] - )" - then: [t: "𝑁⠨"] # example 8c(4) -- lone "." is not considered numeric, but not a period - else: [t: "N⠨"] - else_test: - - if: "parent::m:mover and preceding-sibling::*" - then: [t: "⠡"] - - else_if: "preceding-sibling::*[1][@data-roman-numeral or - (name(.)='mrow' and *[last()][@data-roman-numeral])]" - then: [t: "𝐏⠲"] - else: [t: "P⠲"] - - "/": [t: "⠸⠌"] # 0x002F (Solidus) - - ":": # 0x003A (Colon) - # sometimes a colon is meant to be a ratio - # we start to see if this is marked as 'ratio' and not marked as something else (but ignoring a literal) - # this test is based on what SRE does -- if the "roles" are the same, it guesses "ratio" - # MathCAT doesn't have roles, so we do a hack that looks checks mrows if not atomic. - # If an mrow, guess it is infix and checks the operator. This is pretty weak! - # Need to rule out field extensions "[K:F]" and trilinear coordinates "a:b:c" as they use the punctuation form - # When using the punctuation form, there may or may not be a trailing spacing depending on the "print" - # NFB Lesson 5.7 says "Follow print for spacing after the colon." - # We can't normally tell spacing, but it *should* have a space in function mapping and set builder notation if the author used appropriate notation - # The canonicalization code makes this guess and adds "data-space-after" - - test: - - if: "@intent='ratio' or - ( (@intent and starts-with(@intent, '_')) and - ../self::m:mrow and - not(ancestor::*[2][IsBracketed(., '[', ']')]) and - not( preceding-sibling::*[2][.=':'] or following-sibling::*[2][.=':']) and - name(preceding-sibling::*[1]) = name(following-sibling::*[1]) and - ( name(preceding-sibling::*[1]) != 'mrow' or - (preceding-sibling::*[1]/*[2][text()] = following-sibling::*[1]/*[2][text()]) ) - )" - then: [t: "W⠐⠂W"] - - else_if: "@data-chem-formula-op" # lewis dots - then: - - t: "⠹" - else: - - t: "P⠒" - - test: - if: "@data-space-after or ancestor::*[2][IsBracketed(., '{', '}')] or following-sibling::*[1]/*[2][IsInDefinition(., 'Braille', 'Arrows')]" # "Arrows" is a bit broad... - then: [t: "W"] - - ";": [t: "P⠆"] # 0x003B (Semicolon) - - "<": [t: "⠐⠅"] # 0x003C (Less-than sign) - - "=": # 0x003D (Equals sign) - - test: - if: "@data-chemical-bond" - then: [t: "⠸⠶⠻"] - else: [t: "⠨⠅"] - - - ">": [t: "⠨⠂"] # 0x003E (Greater-than sign) - - "?": [t: "P⠦"] # 0x003F (Question mark) - - "@": [t: "⠈⠁"] # 0x40 (Commercial at) - - "[": [t: "⠈⠷"] # 0x005B (Left square bracket) - - "\\": [t: "⠸⠡"] # 0x005C (Reverse solidus) - - "]": [t: "⠈⠾"] # 0x005D (Right square bracket) - - "^": [t: "⠸⠣"] # 0x005E (Circumflex accent) - - "_": [t: ""] # 0x005F (Low line) - - "{": [t: "⠨⠷"] # 0x007B (Left curly bracket) - - "|": # 0x007C (Vertical line) - - test: - if: "preceding-sibling::* and following-sibling::*" - then: [t: "w⠳w"] # comparison (e.g., such that -- rule 145) - else: [t: "⠳"] # absolute value, others??? - - "}": [t: "⠨⠾"] # 0x007D (Right curly bracket) - - "~": [t: "⠈⠱"] # 0x007E (Tilde) - - "¬": [t: ""] # 0x00AC (Not sign) - - "¯": [t: "⠱"] # 0x00AF (bar) - - "°": [t: "⠨⠡"] # 0x00B0 (Degree sign) - - "±": [t: "⠬⠤"] # 0x00B1 (Plus-minus sign) - - "·": [t: "⠡"] # 0x00B7 (Middle dot) - - "×": [t: "⠈⠡"] # 0x00D7 (Multiplication sign) - - "÷": [t: "⠨⠌"] # 0x00F7 (Division sign) - - "—": [t: "P⠤⠤"] # 0x2014 (Em dash) - # rule 43b about spaces (references rule 42) - # dashes are 'mo's so no inserted invisible times between it and currency symbols - - "―": # 0x2015 (Horizontal bar) - - test: - if: - - "not(" - - " (not(preceding-sibling::*) and parent::*[1][name(.)='mrow' and preceding-sibling::*[1][IsInDefinition(., 'Braille', 'NemethPunctAndOpenBeforeSymbols')]]) or" - - " (preceding-sibling::*[1][IsInDefinition(., 'Braille', 'NemethCurrencyBeforeSymbols')])" - - ")" - then: [t: "W"] - - t: "⠤⠤⠤⠤" - - test: - if: - - "not(" - - " name(parent::*[1])='mrow' and (" - - " (following-sibling::*[1][IsInDefinition(., 'Braille', 'NemethPunctAndOpenAfterSymbols')]) or " - - " (not(following-sibling::*) and parent::*[1][name(.)='mrow' and following-sibling::*[1][IsInDefinition(., 'Braille', 'NemethPunctAndOpenAfterSymbols')]]) or " - - " (following-sibling::*[1][.='\u2062'] and following-sibling::*[2][IsInDefinition(., 'Braille', 'NemethCurrencyAfterSymbols')])" - - " )" - - ")" - then: [t: "W"] - - - "…": # 0x2026 (Ellipsis) - # rule 43b about spaces (references rule 42); partly superseded by lesson 2.13 - # tests are ugly because an invisible times might have been inserted and we need to skip that - - test: - if: - - "not(" - - " (not(preceding-sibling::*) and parent::*[1][name(.)='mrow' and preceding-sibling::*[1][IsInDefinition(., 'Braille', 'NemethPunctAndOpenBeforeSymbols')]]) or" - - " (preceding-sibling::*[1][.='\u2062'] and preceding-sibling::*[2][IsInDefinition(., 'Braille', 'NemethCurrencyBeforeSymbols')])" - - ")" - then: [t: "W"] - - t: "⠄⠄⠄" - - test: - if: - - "not(" - - " name(parent::*[1])='mrow' and (" - - " (following-sibling::*[1][IsInDefinition(., 'Braille', 'NemethPunctAndOpenAfterSymbols')]) or " - - " (not(following-sibling::*) and parent::*[1][name(.)='mrow' and following-sibling::*[1][IsInDefinition(., 'Braille', 'NemethPunctAndOpenAfterSymbols')]]) or " - - " (following-sibling::*[1][.='\u2062'] and following-sibling::*[2][IsInDefinition(., 'Braille', 'NemethCurrencyAfterSymbols')])" - - " )" - - ")" - then: [t: "W"] - - "⁡": # 0x2061⁡ (invisible function apply) - # add a space if name doesn't have brackets after it or is in FunctionNames list - - test: - if: "not(following-sibling::*[1][IsBracketed(., '', '')]) or preceding-sibling::*[1][IsInDefinition(BaseNode(.), 'Braille', 'FunctionNames')]" - then: [t: "w"] # follows a function name, so lowercase - - "⁢": [t: ""] # 0x2062 - - "⁣": # 0x2063 (Invisible Comma -- treat like a normal comma when in a subscript[issue #40]) else ignore - - test: - # test if first ancestor that isn't an mrow is a script tag (rule 78) - - if: "self::m:mn" - then: [t: ""] - - else_if: "ancestor-or-self::*[not(parent::m:mrow)][1][parent::m:msub or parent::m:msup or parent::m:msubsup or parent::m:mmultiscripts][preceding-sibling::*]" - then: [t: "⠪"] # Rule 78 - else: [t: ""] - - "⁤": [t: ""] # 0x2064 - - - "→": # 0x2192 (Rightwards arrow) - - test: # Rule 96 -- uncontracted form if base of under/over - if: "not(preceding-sibling::*) and parent::*[self::m:mover or self::m:munder or self::m:munderover]" - then: [t: "⠫⠒⠒⠕"] # uncontracted version - else: [t: "⠫⠕"] # contracted version - - "∂": [t: "⠈⠙"] # 0x2202 (Partial differential) - - "∆": [t: "GCL⠙"] # 2206 - - - "℃": [t: "⠘⠨⠡⠀⠰⠠⠉"] # 0x2103 (Degrees Celsius) - - "℉": [t: "⠘⠨⠡⠀⠰⠠⠋"] # 0x2109 (Degrees Fahrenheit) - - # --- restored short definitions that differ from unicode-full --- - - "∏": [t: "GCL⠏"] # 0x220F (N-ary product) - - "∑": [t: "GCL⠎"] # 0x2211 (N-ary summation) +--- +# To greatly simplify typeface/language generation, the chars have unique ASCII chars for them: +# Typeface: S: sans-serif, B: bold, T: script/blackboard, I: italic, R: Roman +# Language: E: English, D: German, G: Greek, V: Greek variants, H: Hebrew, U: Russian +# Indicators: C: capital, L: letter, N: number, P: punctuation, M: multipurpose +# Others: W -- whitespace that should be kept (e.g, in a numeral) +# SRE doesn't have H: Hebrew or U: Russian, so not encoded (yet) +# Some of the weird letters (e.g., circled letters) I didn't translate with the above because +# they don't interact with rules since they are enclosed in other chars. + + + # --- Nemeth Default Alphabet normal chars. --- + - "0": [t: "N⠴"] # 0x30 + - "1": [t: "N⠂"] # 0x31 + - "2": [t: "N⠆"] # 0x32 + - "3": [t: "N⠒"] # 0x33 + - "4": [t: "N⠲"] # 0x34 + - "5": [t: "N⠢"] # 0x35 + - "6": [t: "N⠖"] # 0x36 + - "7": [t: "N⠶"] # 0x37 + - "8": [t: "N⠦"] # 0x38 + - "9": [t: "N⠔"] # 0x39 + # Latin capitals: C + cells from lowercase a-z via spell/translate. + - "A-Z": # 0x41 - 0x5a + - tc: "C" + - spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" + - "a": [t: "L⠁"] # 0x61 + - "b": [t: "L⠃"] # 0x62 + - "c": [t: "L⠉"] # 0x63 + - "d": [t: "L⠙"] # 0x64 + - "e": [t: "L⠑"] # 0x65 + - "f": [t: "L⠋"] # 0x66 + - "g": [t: "L⠛"] # 0x67 + - "h": [t: "L⠓"] # 0x68 + - "i": [t: "L⠊"] # 0x69 + - "j": [t: "L⠚"] # 0x6a + - "k": [t: "L⠅"] # 0x6b + - "l": [t: "L⠇"] # 0x6c + - "m": [t: "L⠍"] # 0x6d + - "n": [t: "L⠝"] # 0x6e + - "o": [t: "L⠕"] # 0x6f + - "p": [t: "L⠏"] # 0x70 + - "q": [t: "L⠟"] # 0x71 + - "r": [t: "L⠗"] # 0x72 + - "s": [t: "L⠎"] # 0x73 + - "t": [t: "L⠞"] # 0x74 + - "u": [t: "L⠥"] # 0x75 + - "v": [t: "L⠧"] # 0x76 + - "w": [t: "L⠺"] # 0x77 + - "x": [t: "L⠭"] # 0x78 + - "y": [t: "L⠽"] # 0x79 + - "z": [t: "L⠵"] # 0x7a + - "Α": [t: "GCL⠁"] # 0x391 + - "Β": [t: "GCL⠃"] # 0x392 + - "Γ": [t: "GCL⠛"] # 0x393 + - "Δ": [t: "GCL⠙"] # 0x394 + - "Ε": [t: "GCL⠑"] # 0x395 + - "Ζ": [t: "GCL⠵"] # 0x396 + - "Η": [t: "GCL⠱"] # 0x397 + - "Θ": [t: "GCL⠹"] # 0x398 + - "Ι": [t: "GCL⠊"] # 0x399 + - "Κ": [t: "GCL⠅"] # 0x39a + - "Λ": [t: "GCL⠇"] # 0x39b + - "Μ": [t: "GCL⠍"] # 0x39c + - "Ν": [t: "GCL⠝"] # 0x39d + - "Ξ": [t: "GCL⠭"] # 0x39e + - "Ο": [t: "GCL⠕"] # 0x39f + - "Π": [t: "GCL⠏"] # 0x3a0 + - "Ρ": [t: "GCL⠗"] # 0x3a1 + - "ϴ": [t: "GCL⠹"] # 0x3f4 + - "Σ": [t: "GCL⠎"] # 0x3a3 + - "Τ": [t: "GCL⠞"] # 0x3a4 + - "Υ": [t: "GCL⠥"] # 0x3a5 + - "Φ": [t: "GCL⠋"] # 0x3a6 + - "Χ": [t: "GCL⠯"] # 0x3a7 + - "Ψ": [t: "GCL⠽"] # 0x3a8 + - "Ω": [t: "GCL⠺"] # 0x3a9 + - "∇": [t: "GL⠫"] # 0x2207 + - "α": [t: "GL⠁"] # 0x3b1 + - "β": [t: "GL⠃"] # 0x3b2 + - "γ": [t: "GL⠛"] # 0x3b3 + - "δ": [t: "GL⠙"] # 0x3b4 + - "ε": [t: "GL⠑"] # 0x3b5 + - "ζ": [t: "GL⠵"] # 0x3b6 + - "η": [t: "GL⠱"] # 0x3b7 + - "θ": [t: "GL⠹"] # 0x3b8 + - "ι": [t: "GL⠊"] # 0x3b9 + - "κ": [t: "GL⠅"] # 0x3ba + - "λ": [t: "GL⠇"] # 0x3bb + - "μ": [t: "GL⠍"] # 0x3bc + - "ν": [t: "GL⠝"] # 0x3bd + - "ξ": [t: "GL⠭"] # 0x3be + - "ο": [t: "GL⠕"] # 0x3bf + - "π": [t: "GL⠏"] # 0x3c0 + - "ρ": [t: "GL⠗"] # 0x3c1 + - "ς": [t: "VL⠎"] # 0x3c2 + - "σ": [t: "GL⠎"] # 0x3c3 + - "τ": [t: "GL⠞"] # 0x3c4 + - "υ": [t: "GL⠥"] # 0x3c5 + - "φ": [t: "VL⠋"] # 0x3c6 + - "χ": [t: "GL⠯"] # 0x3c7 + - "ψ": [t: "GL⠽"] # 0x3c8 + - "ω": [t: "GL⠺"] # 0x3c9 + - "ϵ": [t: "GL⠑"] # 0x3f5 + - "ϑ": [t: "VL⠹"] # 0x3d1 + - "ϰ": [t: "GL⠅"] # 0x3f0 + - "ϕ": [t: "GL⠋"] # 0x3d5 + - "ϱ": [t: "GL⠗"] # 0x3f1 + - "ϖ": [t: "GL⠏"] # 0x3d6 + + + # --- Nemeth Default Characters math_symbols chars. --- + - "`": [t: "⠈"] # 0x60 + - "⋮": # 0x22ee + - test: # if we have a triple bond represented by "⋮⋮", the we output the triple bond for the first but not the second + if: "@data-chemical-bond and (preceding-sibling::*[1] = '⋮' or following-sibling::*[1] = '⋮')" + then_test: + if: "following-sibling::*[1] = '⋮'" + then: [t: "⠨⠹"] # output only the first of the two chars + else: [t: "⠩⠄⠄"] + - "⋯": [t: "⠄⠄⠄"] # 0x22ef + - "⋰": [t: "⠘⠄⠄"] # 0x22f0 + - "⋱": [t: "⠰⠄⠄"] # 0x22f1 + - "≡": # 0x2261 + - test: + if: "@data-chemical-bond" + then: [t: "⠸⠿⠻"] + else: [t: "⠸⠇"] + + # --- Nemeth Default Characters rest chars. --- + - " ": # 0x20 (space) + - test: + if: "self::m:mn" + then: [t: "⠀"] + else: [t: "W"] + + - " ": # 0xA0 (non-breaking space) + - test: + - if: "self::m:mn" + then: [t: "⠀"] + # # part of longer string or part of preceeding or following text + - else_if: "@data-added='missing-content' or @data-empty-in-2D or @width > 1.1" + then: [t: "⠿"] # omission + - else_if: "(string-length(.) > 1 or preceding-sibling::*[1][self::m:mtext and .!=','] or following-sibling::*[1][self::m:mtext])" + then: [t: "W"] + # treat mo like 0x2061 (function apply) + - else_if: "self::m:mo and + (preceding-sibling::*[1][IsInDefinition(., 'Braille', 'GeometryShapes')] or + @data-function-likelihood and + IsInDefinition(BaseNode(.), 'Braille', 'FunctionNames') and + not(following-sibling::*[1][IsBracketed(., '', '')]) + )" + then: [t: "w"] # follows a function name, so lowercase + + - "!": # 0x21 (Factorial) + - test: + if: "self::m:mo" + then: [t: "⠯"] + else: [t: "P⠖"] + +# - "\"": [t: ""] # 0x22 (Quotation mark) + - "#": [t: "⠨⠼"] # 0x23 (Number sign) + - "$": [t: "⠈⠎"] # 0x24 (Dollar sign) + - "%": [t: "⠈⠴"] # 0x25 (Percent sign) + - "&": [t: "⠸⠯"] # 0x26 (Ampersand) + - "'": [t: "P⠄"] # 0x27 (Apostrophe) + - "(": [t: "⠷"] # 0x28 (Left parenthesis) + - ")": [t: "⠾"] # 0x29 (Right parenthesis) + - "*": [t: "⠈⠼"] # 0x002A (Asterisk) + - "+": # 0x002B (Plus sign) + - test: + # Add multipurpose indicator before prefix '+' to avoid being the same as '∓' + if: "not(preceding-sibling::*) and parent::*[1][name(.)='mrow' and preceding-sibling::*[1][name(.)='mo' and .='-']]" + then: [t: "m⠬"] + else: [t: "⠬"] + + - ",": # 0x002C (Comma) + - test: + # test if first ancestor that isn't an mrow is a script tag (rule 78) + - if: "self::m:mn" + then: [t: "⠠"] + - else_if: "ancestor-or-self::*[not(parent::m:mrow)][1][parent::m:msub or parent::m:msup or parent::m:msubsup or parent::m:mmultiscripts][preceding-sibling::*]" + then: [t: "⠪"] # Rule 78 + else: [t: ","] # ',' used for matching purposes, converted to "⠠⠀" + - "-": # 0x002D (Hyphen) (0x2212 normalized to here) -- 38vi says don't use the punctuation indicator + - test: + # Add multipurpose indicator before prefix '+' to avoid being the same as '±' or a dash + if: "@data-chemical-bond" + then: [t: "⠸⠒⠻"] + else_test: + if: "not(preceding-sibling::*) and parent::*[1][name(.)='mrow' and preceding-sibling::*[1][name(.)='mo' and (.='+' or .='-')]]" + then: [t: "m⠤"] + else: [t: "⠤"] + + - ".": # 0x002E (Full stop or decimal pt) + # '.' is particularly tricky because we need to know if it is really numeric or not. + # if it is numeric, it might be a on it's own or part of a number. + # normally, it is merged with the digits if part of a number, but if the adjacent digit(s) are modified + # by something (e.g., a bar over the digit to signify that it repeats), then it is really part of the number + # If it is the last part of the expr, then it is punctuation (for typographic reasons, punctuation is often included in the math) + - test: + if: "self::m:mn or (self::m:mo and following-sibling::*)" + then_test: + if: "string-length(text()) = 1 and not( + following-sibling::*[1][BaseNode(.)[self::m:mn]] or + following-sibling::*[1][self::m:menclose and @notation='top' and *[1][self::m:mn]] + )" + then: [t: "𝑁⠨"] # example 8c(4) -- lone "." is not considered numeric, but not a period + else: [t: "N⠨"] + else_test: + - if: "parent::m:mover and preceding-sibling::*" + then: [t: "⠡"] + - else_if: "preceding-sibling::*[1][@data-roman-numeral or + (name(.)='mrow' and *[last()][@data-roman-numeral])]" + then: [t: "𝐏⠲"] + else: [t: "P⠲"] + - "/": [t: "⠸⠌"] # 0x002F (Solidus) + - ":": # 0x003A (Colon) + # sometimes a colon is meant to be a ratio + # we start to see if this is marked as 'ratio' and not marked as something else (but ignoring a literal) + # this test is based on what SRE does -- if the "roles" are the same, it guesses "ratio" + # MathCAT doesn't have roles, so we do a hack that looks checks mrows if not atomic. + # If an mrow, guess it is infix and checks the operator. This is pretty weak! + # Need to rule out field extensions "[K:F]" and trilinear coordinates "a:b:c" as they use the punctuation form + # When using the punctuation form, there may or may not be a trailing spacing depending on the "print" + # NFB Lesson 5.7 says "Follow print for spacing after the colon." + # We can't normally tell spacing, but it *should* have a space in function mapping and set builder notation if the author used appropriate notation + # The canonicalization code makes this guess and adds "data-space-after" + - test: + - if: "@intent='ratio' or + ( (@intent and starts-with(@intent, '_')) and + ../self::m:mrow and + not(ancestor::*[2][IsBracketed(., '[', ']')]) and + not( preceding-sibling::*[2][.=':'] or following-sibling::*[2][.=':']) and + name(preceding-sibling::*[1]) = name(following-sibling::*[1]) and + ( name(preceding-sibling::*[1]) != 'mrow' or + (preceding-sibling::*[1]/*[2][text()] = following-sibling::*[1]/*[2][text()]) ) + )" + then: [t: "W⠐⠂W"] + - else_if: "@data-chem-formula-op" # lewis dots + then: + - t: "⠹" + else: + - t: "P⠒" + - test: + if: "@data-space-after or ancestor::*[2][IsBracketed(., '{', '}')] or following-sibling::*[1]/*[2][IsInDefinition(., 'Braille', 'Arrows')]" # "Arrows" is a bit broad... + then: [t: "W"] + - ";": [t: "P⠆"] # 0x003B (Semicolon) + - "<": [t: "⠐⠅"] # 0x003C (Less-than sign) + - "=": # 0x003D (Equals sign) + - test: + if: "@data-chemical-bond" + then: [t: "⠸⠶⠻"] + else: [t: "⠨⠅"] + + - ">": [t: "⠨⠂"] # 0x003E (Greater-than sign) + - "?": [t: "P⠦"] # 0x003F (Question mark) + - "@": [t: "⠈⠁"] # 0x40 (Commercial at) + - "[": [t: "⠈⠷"] # 0x005B (Left square bracket) + - "\\": [t: "⠸⠡"] # 0x005C (Reverse solidus) + - "]": [t: "⠈⠾"] # 0x005D (Right square bracket) + - "^": [t: "⠸⠣"] # 0x005E (Circumflex accent) + - "_": [t: ""] # 0x005F (Low line) + - "{": [t: "⠨⠷"] # 0x007B (Left curly bracket) + - "|": # 0x007C (Vertical line) + - test: + if: "preceding-sibling::* and following-sibling::*" + then: [t: "w⠳w"] # comparison (e.g., such that -- rule 145) + else: [t: "⠳"] # absolute value, others??? + - "}": [t: "⠨⠾"] # 0x007D (Right curly bracket) + - "~": [t: "⠈⠱"] # 0x007E (Tilde) + - "¬": [t: ""] # 0x00AC (Not sign) + - "¯": [t: "⠱"] # 0x00AF (bar) + - "°": [t: "⠨⠡"] # 0x00B0 (Degree sign) + - "±": [t: "⠬⠤"] # 0x00B1 (Plus-minus sign) + - "·": [t: "⠡"] # 0x00B7 (Middle dot) + - "×": [t: "⠈⠡"] # 0x00D7 (Multiplication sign) + - "÷": [t: "⠨⠌"] # 0x00F7 (Division sign) + - "—": [t: "P⠤⠤"] # 0x2014 (Em dash) + # rule 43b about spaces (references rule 42) + # dashes are 'mo's so no inserted invisible times between it and currency symbols + - "―": # 0x2015 (Horizontal bar) + - test: + if: + - "not(" + - " (not(preceding-sibling::*) and parent::*[1][name(.)='mrow' and preceding-sibling::*[1][IsInDefinition(., 'Braille', 'NemethPunctAndOpenBeforeSymbols')]]) or" + - " (preceding-sibling::*[1][IsInDefinition(., 'Braille', 'NemethCurrencyBeforeSymbols')])" + - ")" + then: [t: "W"] + - t: "⠤⠤⠤⠤" + - test: + if: + - "not(" + - " name(parent::*[1])='mrow' and (" + - " (following-sibling::*[1][IsInDefinition(., 'Braille', 'NemethPunctAndOpenAfterSymbols')]) or " + - " (not(following-sibling::*) and parent::*[1][name(.)='mrow' and following-sibling::*[1][IsInDefinition(., 'Braille', 'NemethPunctAndOpenAfterSymbols')]]) or " + - " (following-sibling::*[1][.='\u2062'] and following-sibling::*[2][IsInDefinition(., 'Braille', 'NemethCurrencyAfterSymbols')])" + - " )" + - ")" + then: [t: "W"] + + - "…": # 0x2026 (Ellipsis) + # rule 43b about spaces (references rule 42); partly superseded by lesson 2.13 + # tests are ugly because an invisible times might have been inserted and we need to skip that + - test: + if: + - "not(" + - " (not(preceding-sibling::*) and parent::*[1][name(.)='mrow' and preceding-sibling::*[1][IsInDefinition(., 'Braille', 'NemethPunctAndOpenBeforeSymbols')]]) or" + - " (preceding-sibling::*[1][.='\u2062'] and preceding-sibling::*[2][IsInDefinition(., 'Braille', 'NemethCurrencyBeforeSymbols')])" + - ")" + then: [t: "W"] + - t: "⠄⠄⠄" + - test: + if: + - "not(" + - " name(parent::*[1])='mrow' and (" + - " (following-sibling::*[1][IsInDefinition(., 'Braille', 'NemethPunctAndOpenAfterSymbols')]) or " + - " (not(following-sibling::*) and parent::*[1][name(.)='mrow' and following-sibling::*[1][IsInDefinition(., 'Braille', 'NemethPunctAndOpenAfterSymbols')]]) or " + - " (following-sibling::*[1][.='\u2062'] and following-sibling::*[2][IsInDefinition(., 'Braille', 'NemethCurrencyAfterSymbols')])" + - " )" + - ")" + then: [t: "W"] + - "⁡": # 0x2061⁡ (invisible function apply) + # add a space if name doesn't have brackets after it or is in FunctionNames list + - test: + if: "not(following-sibling::*[1][IsBracketed(., '', '')]) or preceding-sibling::*[1][IsInDefinition(BaseNode(.), 'Braille', 'FunctionNames')]" + then: [t: "w"] # follows a function name, so lowercase + - "⁢": [t: ""] # 0x2062 + - "⁣": # 0x2063 (Invisible Comma -- treat like a normal comma when in a subscript[issue #40]) else ignore + - test: + # test if first ancestor that isn't an mrow is a script tag (rule 78) + - if: "self::m:mn" + then: [t: ""] + - else_if: "ancestor-or-self::*[not(parent::m:mrow)][1][parent::m:msub or parent::m:msup or parent::m:msubsup or parent::m:mmultiscripts][preceding-sibling::*]" + then: [t: "⠪"] # Rule 78 + else: [t: ""] + - "⁤": [t: ""] # 0x2064 + + - "→": # 0x2192 (Rightwards arrow) + - test: # Rule 96 -- uncontracted form if base of under/over + if: "not(preceding-sibling::*) and parent::*[self::m:mover or self::m:munder or self::m:munderover]" + then: [t: "⠫⠒⠒⠕"] # uncontracted version + else: [t: "⠫⠕"] # contracted version + - "∂": [t: "⠈⠙"] # 0x2202 (Partial differential) + - "∆": [t: "GCL⠙"] # 2206 + + - "℃": [t: "⠘⠨⠡⠀⠰⠠⠉"] # 0x2103 (Degrees Celsius) + - "℉": [t: "⠘⠨⠡⠀⠰⠠⠋"] # 0x2109 (Degrees Fahrenheit) + + # --- restored short definitions that differ from unicode-full --- + - "∏": [t: "GCL⠏"] # 0x220F (N-ary product) + - "∑": [t: "GCL⠎"] # 0x2211 (N-ary summation) diff --git a/Rules/Braille/UEB/unicode.yaml b/Rules/Braille/UEB/unicode.yaml index 477946d70..0700fa24f 100644 --- a/Rules/Braille/UEB/unicode.yaml +++ b/Rules/Braille/UEB/unicode.yaml @@ -1,451 +1,451 @@ ---- -# UEB characters -# -# Some chars that originally came from an Excel spreadsheet, converted to csv, and the greatly expanded -# -# The UEB translation makes use of some non-braille chars as flags -# L -- what follows is a letter -# N -- what follows is a digit -# C -- precedes L for capital letters -# G -- precedes L for Greek Letters (after C for capitals) -# Typeface Indicators ("typeforms") -# B bold, I Italic, S Sans-serif, T script, D, Fraktur, 𝔹 blackboard-bold -# the type face indicators can be combined with B (first) and I (second) -# Standing alone chars: -# Any character which acts as a standing alone character (e.g, "{") needs each braille symbol to be labeled -# o -- opening/left side, c -- closing/right side, b -- both open and close (e.g, '"') - - - - "=": [t: "⠐⠶"] # 0x003D (Equals) - - "≠": [t: "⠐⠶⠈⠱"] # 0x2260 (Not equal) - - "<": [t: "⠈⠣"] # 0x003C (Less than) - - "≤": [t: "⠸⠈⠣"] # 0x2264 (Less than or equal to) - - ">": [t: "⠈⠜"] # 0x003E (Greater than) - - "≣": [t: "⠈⠸⠠⠤"] # 0x2263 - - "≥": [t: "⠸⠈⠜"] # 0x2265 (Greater than or equal to) - - "≪": [t: "⠨⠈⠣"] # 0x226A (Much less than) - - "≫": [t: "⠨⠈⠜"] # 0x226B (Much greater than) - - "≮": [t: "⠈⠣⠈⠱"] # 0x226E (Not less than) - - "≯": [t: "⠈⠜⠈⠱"] # 0x226F (Not greater than) - - "≰": [t: "⠸⠈⠣⠈⠱"] # 0x2270 (Neither less than nor equal to) - - "≱": [t: "⠸⠈⠜⠈⠱"] # 0x2271 (Neither greater than nor equal to) - - "∝": [t: "⠸⠐⠶"] # 0x221D (Proportional to) - - "≃": [t: "⠸⠔"] # 0x2243 (Approximately equal to (tilde over horizontal line)) - - "≅": [t: "⠐⠸⠔"] # 0x2245 (Approximately equal to (tilde over equals sign)) - - "≈": [t: "⠘⠔"] # 0x2248 (Approximately equal (tilde over tilde)) - - "≏": [t: "⠘⠐⠶"] # 0x224F (Equals with bump in top bar (difference between)) - - "≑": [t: "⠨⠐⠶"] # 0x2251 (Geometrically equal to (equals dotted above and below)) - - "≟": [t: "𝟙⠦⠻⠐⠶"] # 0x225F (Questioned equal to) - - "≡": [t: "⠸⠿"] # 0x2261 (Equivalent to (three horizontal lines)) - - "≢": [t: "⠸⠿⠈⠱"] # 0x2262 (Not identical to) - - "∈": [t: "⠘⠑"] # 0x2208 (Element of (member of)) - - "∉": [t: "⠘⠑⠈⠱"] # 0x2209 (Not Element of) - - "+": [t: "⠐⠖"] # 0x002B (Plus sign) - - "∋": [t: "⠈⠘⠑"] # 0x220B (Contains) - - "⊂": [t: "⠘⠣"] # 0x2282 (Subset of) - - "⊃": [t: "⠘⠜"] # 0x2283 (Superset of) - - "⊆": [t: "⠸⠘⠣"] # 0x2286 (Subset of or equal) - - "⊇": [t: "⠸⠘⠜"] # 0x2287 (Superset of or equal) - - "⊊": [t: "⠨⠘⠣"] # 0x228A (Subset of with not equal) - - "⊋": [t: "⠨⠘⠜"] # 0x228B (Superset of with not equal) - - "⊲": [t: "⠈⠸⠣"] # 0x22B2 (Normal subgroup of) - - "⊳": [t: "⠈⠸⠜"] # 0x22B3 (Contains as normal subgroup) - - "⊴": [t: "⠸⠸⠣"] # 0x22B4 (Normal subgroup of or equal) - - "⊵": [t: "⠸⠸⠜"] # 0x22B5 (Contains as normal subgroup or equal) - - "⊻": [t: "𝟙⠈⠖⠠⠱"] # 0x22bb (Xor) - - "⋬": [t: "⠨⠸⠣"] # 0x22EC (not normal subgroup) -- this isn't the same as what is in GTM 10, but that similar has no Unicode equiv - - "⋭": [t: "⠨⠸⠣"] # 0x22ED (does not contain as normal subgroup) -- this isn't the same as what is in GTM 10, but that similar has no Unicode equiv - - "⊢": [t: "⠸⠒"] # 0x22a2 (Right tack) - - "⊣": [t: "⠈⠸⠒"] # 0x22a3 (Left tack) - - "−": [t: "⠐⠤"] # 0x2212 (Minus sign) - - "·": [t: "⠐⠲"] # 0x00B7 (Multiplication dot (times)) - - "×": [t: "⠐⠦"] # 0x00D7 (Multiplication sign (times)) - - "÷": [t: "⠐⠌"] # 0x00F7 (Division sign (divided by)) - - "±": [t: "⠸⠖"] # 0x00B1 (Plus or minus) - - "∓": [t: "⠸⠤"] # 0x2213 (Minus or plus) - - "∗": [t: "⠐⠔"] # 0x2217 (Asterisk operator) - - "∘": [t: "⠐⠴"] # 0x2218 (Ring operator) - - "◦": [t: "⠐⠴"] # 0x25E6 (White bullet) - - "∼": [t: "⠈⠔"] # 0x223C (Tilde operator) - - "⋅": [t: "⠐⠲"] # 0x22C5 (Dot operator) - - "∧": [t: "⠈⠦"] # 0x2227 (Logical and) - - "∨": [t: "⠈⠖"] # 0x2228 (Logical or) - - "∩": [t: "⠨⠦"] # 0x2229 (Intersection) - - "∪": [t: "⠨⠖"] # 0x222A (Union) - - "∖": [t: "⠸⠡"] # 0x2216 (Set minus) - - "(": [t: "o⠐o⠣"] # 0x0028 (Left parenthesis) - - ")": [t: "c⠐c⠜"] # 0x0029 (Right parenthesis) - - "[": [t: "o⠨o⠣"] # 0x005B (Left square bracket) - - "]": [t: "c⠨c⠜"] # 0x005D (Right square bracket) - - "{": [t: "o⠸o⠣"] # 0x007B (Left curly bracket) - - "}": [t: "c⠸c⠜"] # 0x007D (Right curly bracket) - - "〈": [t: "o⠈⠣"] # 0x2329 (Left angle bracket) - - "〉": [t: "c⠈⠜"] # 0x232A (Right angle bracket) - - "⟨": [t: "o⠈⠣"] # 0x27E8 (Left angle bracket) - - "⟩": [t: "c⠈⠜"] # 0x27E9 (Right angle bracket) - - "|": # 0x007C (Vertical line) - - test: - if: "preceding-sibling::* and following-sibling::*" - then: [t: "W⠸⠳W"] # comparison (e.g., such that -- rule 145) - else: [t: "⠸⠳"] # absolute value, others??? - - "!": [t: "c⠖"] # 0x21 (Exclamation (factorial)) - - "#": [t: "⠸⠹"] # 0x23 (Number sign (hash)) - - "%": [t: "⠨⠴"] # 0x25 (Percent sign) - - "&": [t: "⠈⠯"] # 0x26 (Ampersand) - - "*": [t: "⠐⠔"] # 0x002A (Asterisk) - - "/": [t: "⠸⠌"] # 0x002F (Solidus (slash)) - - ";": [t: "1c⠆"] # 0x003B (Semicolon) - - "?": [t: "1c⠦"] # 0x003F (Question mark) - - "@": [t: "⠈⠁"] # 0x0040 (Commercial at sign) - - "\\": [t: "⠸⠡"] # 0x005C (Backslash) - - "^": [t: "⠈⠢"] # 0x005E (Caret (hat, up arrow)) - - "_": [t: "⠨⠤"] # 0x005F (Low line (underscore)) - - "~": [t: "⠈⠔"] # 0x007E (Tilde (swung dash)) - - "¢": [t: "⠈⠉"] # 0x00A2 (Cents sign) - - "‐": [t: "⠤"] # 0x2010 (Hyphen) - - "–": [t: "P⠠⠤"] # 0x2013 (En Dash) - - "―": [t: "⠐⠠⠤"] # 0x2015 (Horizontal Bar) - - "‖": [t: "⠸⠳"] # 0x2016 - - "€": [t: "⠈⠑"] # 0x20AC (Euro sign) - - "₣": [t: "⠈⠋"] # 0x20A3 (French franc sign) - - "£": [t: "⠈⠇"] # 0x00A3 (Pound sign) - - "₦": [t: "⠈⠝"] # 0x20A6 (Naira sign) - - "$": [t: "⠈⠎"] # 0x0024 (Dollar sign) - - "¥": [t: "⠈⠽"] # 0x00A5 (Yen sign) - - "¦": [t: "⠨⠳"] # 0x00A6 (Broken bar) - - "¬": [t: "⠈⠹"] # 0x00AC (Not sign) - - "°": [t: "⠘⠚"] # 0x00B0 (Degree sign) - - "†": [t: "⠈⠠⠹"] # 0x2020 (Dagger) - - "‡": [t: "⠈⠠⠻"] # 0x2021 (Double dagger) - - "…": [t: "c⠲c⠲c⠲"] # 0x2026 (Ellipsis) - - "⋯": [t: "⠄⠄⠄"] # 0x22EF (midline horizontal ellipsis; GTM 15.4 matrix omission) - - "′": [t: "1⠶"] # 0x2032 (Prime sign) - - "″": [t: "1⠶⠶"] # 0x2033 (Double prime sign) - - "‴": [t: "1⠶⠶⠶"] # 0x2034 (Triple prime sign) - - "℃": [t: "⠘⠚⠠⠉"] # 0x2103 (Degrees Celsius) - - "℉": [t: "⠘⠚⠠⠋"] # 0x2109 (Degrees Fahrenheit) - - "Å": [t: "CA⠘⠫L⠁"] # 0x212B (Angstrom symbol) - - "Å": [t: "CA⠘⠫L⠁"] # 0x00C5 (WIRIS uses this for Angstrom) - - "∀": [t: "⠘⠁"] # 0x2200 (For all) - - "∂": [t: "⠈⠙"] # 0x2202 (Partial differential) - - "∃": [t: "⠘⠢"] # 0x2203 (There exists) - - "∄": [t: "⠘⠢⠈⠱"] # 0x2204 (There does not exist) - - "∅": [t: "⠈⠚"] # 0x2205 (Empty set) - - "∇": [t: "⠘⠙"] # 0x2207 (Nabla (del, inverted capital delta)) - - "∎": [t: "⠸⠫⠼⠙t"] # 0x220E (End of proof) - - "√": [t: "⠐⠩"] # 0x221A (Square root (radical) without vinculum) - - "∞": [t: "⠼⠿"] # 0x221E (Infinity) - - "∠": [t: "⠸⠪"] # 0x2220 (Angle) - - "∡": [t: "⠨⠸⠪"] # 0x2221 (Measured angle) - - "⊾": [t: "⠼⠸⠪"] # 0x22BE (Right angle with arc) - - "∫": [t: "1⠮"] # 0x222B (Integral) - - "∮": [t: "⠈⠮"] # 0x222E (Contour integral (closed line integral)) - - "∴": [t: "1⠠⠡"] # 0x2234 (Therefore) - - "∵": [t: "⠈⠌"] # 0x2235 (Because (since)) - - "∶": [t: "⠒"] # 0x2236 (Ratio) - - "∷": [t: "⠒⠒"] # 0x2237 (Proportion) - - "∣": [t: "⠸⠳"] # 0x2223 (Divides) - - "∤": [t: "⠸⠳⠈⠱"] # 0x2224 (Does not divide) - - "∥": [t: "⠼⠇"] # 0x2225 (Parallel) - - "∦": [t: "⠼⠇⠈⠱"] # 0x2226 (Not parallel) - - "⟂": [t: "⠼⠤"] # 0x27C2 (Perpendicular) - - "⊥": [t: "⠼⠤"] # 0x22A5 (Up tack (perpendicular)) - - "⊦": [t: "⠸⠒"] # 0x22A6 (Assertion (is a theorem)) - - "⊨": [t: "⠘⠸⠒"] # 0x22A8 (TRUE (is valid)) - - "⊬": [t: "⠸⠒⠈⠱"] # 0x22AC (Does not prove) - - "⊭": [t: "⠘⠸⠒⠈⠱"] # 0x22AD (Not TRUE) - - "⫅": [t: "⠘⠣⠰⠻⠐⠶"] # 0x2AC5 (Subset above equals) - - "⫆": [t: "⠘⠜⠰⠻⠐⠶"] # 0x2AC6 (Superset above equals) - - "⫤": [t: "⠨⠸⠒"] # 0x2AE4 (Vertical bar double left turnstile) - - "⬠": [t: "1⠫⠼⠑t"] # 0x2B20 (White Pentagon) - - "⬡": [t: "1⠫⠼⠋t"] # 0x2B21 (White Hexagon) - - "✓": [t: "⠈⠩"] # 0x2713 (Check mark (tick)) - - "⦵": [t: "⠨⠚"] # 0x29B5 (Plimsoll sign) - - "⮖": [t: "1⠐⠠⠤⠯⠫⠿"] # 0x2B96 (MEDIUM SMALL WHITE CIRCLE WITH HORIZONTAL BAR (standard state)) - - "←": [t: "1⠳⠪"] # 0x2190 (Leftwards arrow) - - "↑": [t: "1⠳⠬"] # 0x2191 (Upwards arrow) - - "→": [t: "1⠳⠕"] # 0x2192 (Rightwards arrow) - - "↓": [t: "1⠳⠩"] # 0x2193 (Downwards arrow) - - "↔": [t: "1⠳⠺⠗⠕"] # 0x2194 (Left right arrow) - - "↕": [t: "1⠳⠺⠗⠬"] # 0x2195 (Up down arrow) - - "↖": [t: "1⠳⠱"] # 0x2196 (Northwest arrow) - - "↗": [t: "1⠳⠎"] # 0x2197 (Northeast arrow) - - "↘": [t: "1⠳⠣"] # 0x2198 (Southeast arrow) - - "↙": [t: "1⠳⠜"] # 0x2199 (Southwest arrow) - - "↚": [t: "1⠳⠪⠈⠱"] # 0x219A (Leftwards arrow with stroke) - - "↛": [t: "1⠳⠕⠈⠱"] # 0x219B (Rightwards arrow with stroke) - - "↜": [t: "1⠳⠔⠢⠪"] # 0x219C (Leftwards wave arrow) - - "↝": [t: "1⠳⠢⠔⠕"] # 0x219D (Rightwards wave arrow) - - "↞": [t: "1⠳⠒⠗⠗⠪"] # 0x219E (Leftwards two headed arrow) - - "↟": [t: "1⠳⠒⠗⠗⠬"] # 0x219F (Upwards two headed arrow) - - "↠": [t: "1⠳⠒⠗⠗⠕"] # 0x21A0 (Rightwards two headed arrow) - - "↡": [t: "1⠳⠒⠗⠗⠩"] # 0x21A1 (Downwards two headed arrow) - - "↢": [t: "1⠳⠗⠗⠪"] # 0x21A2 (Leftwards arrow with tail) - - "↣": [t: "1⠳⠗⠗⠕"] # 0x21A3 (Rightwards arrow with tail) - - "↤": [t: "1⠳⠳⠗⠪"] # 0x21A4 (Leftwards arrow from bar) - - "↥": [t: "1⠳⠳⠗⠬"] # 0x21A5 (Upwards arrow from bar) - - "↦": [t: "1⠳⠳⠗⠕"] # 0x21A6 (Rightwards arrow from bar) - - "↧": [t: "1⠳⠳⠗⠩"] # 0x21A7 (Downwards arrow from bar) - - "↭": [t: "1⠳⠺⠔⠢⠗⠕"] # 0x21AD (Left right wave arrow) - - "↮": [t: "1⠳⠺⠗⠕⠈⠱"] # 0x21AE (Left right arrow with stroke) - - "↰": [t: "1⠳⠴⠬"] # 0x21B0 (Upwards arrow with tip left) - - "↱": [t: "1⠳⠲⠬"] # 0x21B1 (Upwards arrow with tip right) - - "↲": [t: "1⠳⠲⠩"] # 0x21B2 (Downwards arrow with tip left) - - "↳": [t: "1⠳⠴⠩"] # 0x21B3 (Downwards arrow with tip right) - - "↶": [t: "1⠳⠔⠔⠪"] # 0x21B6 (Anticlockwise top semicircle arrow) - - "↷": [t: "1⠳⠢⠢⠕"] # 0x21B7 (Clockwise top semicircle arrow) - - "↼": [t: "1⠳⠈⠗⠪"] # 0x21BC (Leftwards harpoon with barb upwards) - - "↽": [t: "1⠳⠠⠗⠪"] # 0x21BD (Leftwards harpoon with barb downwards) - - "↾": [t: "1⠳⠠⠗⠬"] # 0x21BE (Upwards harpoon with barb rightwards) - - "↿": [t: "1⠳⠈⠗⠬"] # 0x21BF (Upwards harpoon with barb leftwards) - - "⇀": [t: "1⠳⠈⠗⠕"] # 0x21C0 (Rightwards harpoon with barb upwards) - - "⇁": [t: "1⠳⠠⠗⠕"] # 0x21C1 (Rightwards harpoon with barb downwards) - - "⇂": [t: "1⠳⠈⠗⠩"] # 0x21C2 (Downwards harpoon with barb rightwards) - - "⇃": [t: "1⠳⠠⠗⠩"] # 0x21C3 (Downwards harpoon with barb leftwards) - - "⇄": [t: "1⠳⠕⠻⠳⠪"] # 0x21C4 (Rightwards arrow over leftwards arrow) - - "⇅": [t: "1⠳⠬⠿⠳⠩"] # 0x21C5 (Upwards arrow left of Downwards arrow) - - "⇌": [t: "1⠘⠸⠶"] # 0x21CC (Rightwards harpoon over leftwards harpoon (equilibrium)) - - "⇐": [t: "1⠳⠶⠪"] # 0x21D0 (Leftwards double arrow) - - "⇑": [t: "1⠳⠶⠬"] # 0x21D1 (Upwards double arrow) - - "⇒": [t: "1⠳⠶⠕"] # 0x21D2 (Rightwards double arrow) - - "⇓": [t: "1⠳⠶⠩"] # 0x21D3 (Downwards double arrow) - - "⇔": [t: "1⠳⠺⠶⠗⠕"] # 0x21D4 (Left right double arrow) - - "⇕": [t: "1⠳⠺⠶⠗⠬"] # 0x21D5 (Up down double arrow) - - "⇠": [t: "1⠳⠂⠪"] # 0x21E0 (Leftwards dashed arrow) - - "⇡": [t: "1⠳⠂⠬"] # 0x21E1 (Upwards dashed arrow) - - "⇢": [t: "1⠳⠂⠕"] # 0x21E2 (Rightwards dashed arrow) - - "⇣": [t: "1⠳⠂⠩"] # 0x21E3 (Downwards dashed arrow) - - "⟵": [t: "1⠳⠒⠒⠒⠪"] # 0x27F5 (Long leftwards arrow) - - "⟶": [t: "1⠳⠒⠒⠒⠕"] # 0x27F6 (Long rightwards arrow) - - "⥂": [t: "1⠸⠶"] # 0x2942 (Rightwards arrow above short leftwards arrow (equilibrium, trend to the right)) - - "⥄": [t: "1⠈⠸⠶"] # 0x2944 (Short rightwards arrow above leftwards arrow (equilibrium, trend to the left)) - -# Mappings for some new Unicode chemistry arrows/symbols -# These repeat the short arrow version because that is what is in the spec (GTM 16), but the spec should really use the long version - - "🣑": [t: "1⠘⠸⠶"] # 0x1F8D1 LONG RIGHTWARDS HARPOON OVER LONG LEFTWARDS HARPOON (equilibrium) - - "🣒": [t: "1⠐⠸⠶"] # 0x1f8d2 LONG RIGHTWARDS HARPOON ABOVE SHORT LEFTWARDS HARPOON(equilibrium, trend to the right) - - "🣓": [t: "1⠈⠸⠶"] # 0x1f8d3 SHORT RIGHTWARDS HARPOON ABOVE LONG LEFTWARDS HARPOON (equilibrium, trend to the left)) - -# These need to be verified -- 0x1f8d1, 0x1f8d2, and 0x1f8d3 conflict with GTM 16 (uses short arrow when really should be long) - - "🣐": [t: "1⠳⠒⠒⠒⠕⠻⠳⠒⠒⠒⠪"] # 0x1F8D0 LONG RIGHTWARDS ARROW OVER LONG LEFTWARDS ARROW - - "🣕": [t: "1⠳⠒⠈⠗⠪⠻⠳⠒⠒⠒⠠⠗⠕"] # 0x1F8D5 SHORT LEFTWARDS HARPOON ABOVELONG RIGHTWARDS HARPOON - - "🣖": [t: "1⠳⠒⠒⠒⠕⠯⠠⠭"] # 0x1F8D6 LONG RIGHTWARDS ARROW WITH THROUGH X - - "🣗": [t: "1⠳⠒⠒⠒⠕⠯⠣⠸⠌⠸⠌⠜"] # 0x1F8D7 LONG RIGHTWARDS ARROW WITH DOUBLE SLASH -# - "": [t: ""] # 0x1F8D8 LONG LEFT RIGHT ARROW WITH DEPENDENT LOBE (no clue what to do) - - - "△": [t: "1⠫⠼⠉t"] # 0x25B3 (Triangle) - - "▫": [t: "1⠫⠼⠙t"] # 0x25AB (Small white Square) - - "□": [t: "1⠫⠼⠙t"] # 0x25A1 (Square) - - "◻": [t: "1⠫⠼⠙t"] # 0x25FB (Square) - - "▤": [t: "⠨⠫⠼⠙t"] # 0x25A4 (Square with horizontal fill) - - "▥": [t: "⠨⠫⠼⠙t"] # 0x25A5 (Square with vertical fill) - - "▦": [t: "⠨⠫⠼⠙t"] # 0x25A6 (Square with orthogonal crosshatch fill) - - "▧": [t: "⠨⠫⠼⠙t"] # 0x25A7 (Square with upper left to lower right fill) - - "▨": [t: "⠨⠫⠼⠙t"] # 0x25A8 (Square with upper right to lower left fill) - - "▩": [t: "⠨⠫⠼⠙t"] # 0x25A9 (Square with diagonal crosshatch fill) - - "○": [t: "1⠫⠿t"] # 0x25CB (Circle) - - "◍": [t: "⠨⠫⠿t"] # 0x25CD (Circle with vertical fill) - - "▱": [t: "1⠫⠈⠼⠙t"] # 0x25B1 (Parallelogram) - - "▲": [t: "⠸⠫⠼⠉t"] # 0x25B2 (Filled triangle) - - "■": [t: "⠸⠫⠼⠙t"] # 0x25A0 (Filled square) - - "≜": [t: "⠠⠨⠙⠻⠐⠶"] # 0x225C (Delta equal to) - - "≝": [t: "1⠣⠙⠑⠋⠜⠻⠐⠶"] # 0x225D (Equal to by definition) - - "⊕": [t: "1⠫⠿⠪⠐⠖t"] # 0x2295 (Circled plus) - - "⊖": [t: "1⠫⠿⠪⠐⠤t"] # 0x2296 (Circled minus) - - "⊗": [t: "1⠫⠿⠪⠐⠦t"] # 0x2297 (Circled times) - - "⊛": [t: "1⠫⠿⠪⠐⠔t"] # 0x229B (Circled asterisk operator) - - "⊞": [t: "1⠫⠼⠙⠪⠐⠖t"] # 0x229E (Squared plus) - - "⊟": [t: "1⠫⠼⠙⠪⠐⠤t"] # 0x229F (Squared minus) - - "⊠": [t: "1⠫⠼⠙⠪⠐⠦t"] # 0x22A0 (Squared times) - - "˙": [t: "1⠲"] # 0x02D9 ( Dot Above) - - "¨": [t: "1⠲⠲"] # 0x00A8 ( Diaeresis/Double Dot Above ) - - "©": [t: "⠘⠉"] # 0xa9 (Copyright) - - - - "\"": [t: "b⠠b⠶"] - - "'": [t: "b⠄"] - - "“": [t: "o⠘o⠦"] - - "”": [t: "c⠘c⠴"] - - "‘": [t: "o⠠o⠦"] - - "’": [t: "c⠠c⠴"] - - "«": [t: "o⠸o⠦"] - - "»": [t: "c⠸c⠴"] - - - " ": # 0x20 (Space) - - test: - if: "self::m:mn" - then: [t: "N⠐"] - else: [t: "W"] - - " ": # 0xa0 (Non-breaking Space) - - test: - - if: "self::m:mn" - then: [t: "N⠐"] - - else_if: "@data-added='missing-content' or @data-empty-in-2D or @width > 1.1" - then: [t: "⠬"] # omission - - else_if: "@width < 0.25" - then: [t: ""] # tweaking space -- ignore - else: [t: "W"] # space in text or wide enough space - - ",": # 0x2c (Comma) - - test: - if: "self::m:mn" - then: [t: "N⠂"] - else: [t: "c,W"] - - ".": # 0x2e (Period) - - test: - if: "self::m:mn" - then: [t: "N⠲"] - else: [t: "c."] - - ":": # 0x003A (Colon) - # We can't normally tell spacing, but it *should* have a space in function mapping and set builder notation if the author used appropriate notation - # The canonicalization code makes this guess and adds "data-space-after" - - test: - if: "@data-space-after or (../self::m:mrow and ancestor::*[2][IsBracketed(., '{', '}')]) or following-sibling::*[1]/*[2][IsInDefinition(., 'Braille', 'Arrows')]" # "Arrows" is a bit broad... - then: [t: "1⠒W"] - else: [t: "1c⠒"] - - - "-": # 0x2d (Minus sign or hyphen) - - test: - if: "self::m:mo" - then: [t: "⠐⠤"] - else: [t: "⠤"] - - - "⁡": # 0x2061⁡ (invisible function apply) - - test: - if: - - "preceding-sibling::*[1][self::m:mi and substring(., string-length(.), 1)!=' '] and " # avoid scripted function names and one that end with spaces - - "following-sibling::*[1][self::m:mi and translate(., 'abcdefghijklmnopqrstuvwxyz', '') = '']" # GTM 9.3.2 - then: [t: "W"] - else: [t: ""] - - - "⁢": # 0x2062 (invisible times) - - test: - if: # GTM 9.3.3 (not very clear in rule, but the function name has to start with a lower case latin char ['no indicators']) - - "parent::m:mrow and " - - "preceding-sibling::*[1][" - - " (self::m:mi and translate(., 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', '') = '') or " - - " (self::m:mrow and translate(*[last()], 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', '') = '')] and" - - " following::*[1][self::m:mrow and count(*)=3 and " # look for function apply - - " *[2][.='⁡'] and *[1][self::m:mi and translate(., 'abcdefghijklmnopqrstuvwxyz', '') = '']]" - then: [t: "W"] - else: [t: ""] - - "⁣": [t: ""] # 0x2063⁡ (invisible separator) - - "⁤": [t: ""] # 0x2064 (invisible plus) - - "0": [t: "N⠚"] # 0x30 - - "1": [t: "N⠁"] # 0x31 - - "2": [t: "N⠃"] # 0x32 - - "3": [t: "N⠉"] # 0x33 - - "4": [t: "N⠙"] # 0x34 - - "5": [t: "N⠑"] # 0x35 - - "6": [t: "N⠋"] # 0x36 - - "7": [t: "N⠛"] # 0x37 - - "8": [t: "N⠓"] # 0x38 - - "9": [t: "N⠊"] # 0x39 - - - "a": [t: "L⠁"] # 0x61 - - "b": [t: "L⠃"] # 0x62 - - "c": [t: "L⠉"] # 0x63 - - "d": [t: "L⠙"] # 0x64 - - "e": [t: "L⠑"] # 0x65 - - "f": [t: "L⠋"] # 0x66 - - "g": [t: "L⠛"] # 0x67 - - "h": [t: "L⠓"] # 0x68 - - "i": [t: "L⠊"] # 0x69 - - "j": [t: "L⠚"] # 0x6a - - "k": [t: "L⠅"] # 0x6b - - "l": [t: "L⠇"] # 0x6c - - "m": [t: "L⠍"] # 0x6d - - "n": [t: "L⠝"] # 0x6e - - "o": [t: "L⠕"] # 0x6f - - "p": [t: "L⠏"] # 0x70 - - "q": [t: "L⠟"] # 0x71 - - "r": [t: "L⠗"] # 0x72 - - "s": [t: "L⠎"] # 0x73 - - "t": [t: "L⠞"] # 0x74 - - "u": [t: "L⠥"] # 0x75 - - "v": [t: "L⠧"] # 0x76 - - "w": [t: "L⠺"] # 0x77 - - "x": [t: "L⠭"] # 0x78 - - "y": [t: "L⠽"] # 0x79 - - "z": [t: "L⠵"] # 0x7a - - # Latin capitals: chem-element letters use 𝐶 (no word indicator); others use C. - # Cells come from lowercase a-z via spell/translate. - - "BCHIKNOPSUVWY": # chemistry-capable capitals - - test: - if: "@data-chem-element" - then: [tc: "𝐶"] - else: [tc: "C"] - - spell: "translate('.', 'BCHIKNOPSUVWY', 'bchiknopsuvwy')" - - "ADEFGJLMQRTXZ": # remaining capitals - - tc: "C" - - spell: "translate('.', 'ADEFGJLMQRTXZ', 'adefgjlmqrtxz')" - - - "α": [t: "GL⠁"] # 0x3b1 - - "β": [t: "GL⠃"] # 0x3b2 - - "γ": [t: "GL⠛"] # 0x3b3 - - "δ": [t: "GL⠙"] # 0x3b4 - - "ε": [t: "GL⠑"] # 0x3b5 - - "ζ": [t: "GL⠵"] # 0x3b6 - - "η": [t: "GL⠱"] # 0x3b7 - - "θ": [t: "GL⠹"] # 0x3b8 - - "ι": [t: "GL⠊"] # 0x3b9 - - "κ": [t: "GL⠅"] # 0x3ba - - "λ": [t: "GL⠇"] # 0x3bb - - "μ": [t: "GL⠍"] # 0x3bc - - "ν": [t: "GL⠝"] # 0x3bd - - "ξ": [t: "GL⠭"] # 0x3be - - "ο": [t: "GL⠕"] # 0x3bf - - "π": [t: "GL⠏"] # 0x3c0 - - "ρ": [t: "GL⠗"] # 0x3c1 - - "ς": [t: "GL⠎"] # 0x3c2 - - "σ": [t: "GL⠎"] # 0x3c3 - - "τ": [t: "GL⠞"] # 0x3c4 - - "υ": [t: "GL⠥"] # 0x3c5 - - "φ": [t: "GL⠋"] # 0x3c6 - - "χ": [t: "GL⠯"] # 0x3c7 - - "ψ": [t: "GL⠽"] # 0x3c8 - - "ω": [t: "GL⠺"] # 0x3c9 - - - "ϑ": [t: "GL⠹"] # 0x3d1 - - "ϵ": [t: "GL⠑"] # 0x3f5 \varepsilon - - "ϰ": [t: "GL⠅"] # 0x3f0 - - "ϕ": [t: "GL⠋"] # 0x3d5 - - "ϱ": [t: "GL⠗"] # 0x3f1 - - "ϖ": [t: "GL⠏"] # 0x3d6 - - "Ϝ": [t: "GL⠧"] # 0x3d7 - - - "Α": [t: "CGL⠁"] # 0x391 - - "Β": [t: "CGL⠃"] # 0x392 - - "Γ": [t: "CGL⠛"] # 0x393 - - "Δ": [t: "CGL⠙"] # 0x394 - - "Ε": [t: "CGL⠑"] # 0x395 - - "Ζ": [t: "CGL⠵"] # 0x396 - - "Η": [t: "CGL⠱"] # 0x397 - - "Θ": [t: "CGL⠹"] # 0x398 - - "Ι": [t: "CGL⠊"] # 0x399 - - "Κ": [t: "CGL⠅"] # 0x39a - - "Λ": [t: "CGL⠇"] # 0x39b - - "Μ": [t: "CGL⠍"] # 0x39c - - "Ν": [t: "CGL⠝"] # 0x39d - - "Ξ": [t: "CGL⠭"] # 0x39e - - "Ο": [t: "CGL⠕"] # 0x39f - - "Π": [t: "CGL⠏"] # 0x3a0 - - "Ρ": [t: "CGL⠗"] # 0x3a1 - - "΢": [t: "CGL⠎"] # 0x3a2 - - "Σ": [t: "CGL⠎"] # 0x3a3 - - "Τ": [t: "CGL⠞"] # 0x3a4 - - "Υ": [t: "CGL⠥"] # 0x3a5 - - "Φ": [t: "CGL⠋"] # 0x3a6 - - "Χ": [t: "CGL⠯"] # 0x3a7 - - "Ψ": [t: "CGL⠽"] # 0x3a8 - - "Ω": [t: "CGL⠺"] # 0x3a9 - - - "µ": [t: "GL⠍"] # 0x00B5 (Micro (Greek mu)) - - "Ω": [t: "CGL⠺"] # 0x2126 (Ohm sign (capital Greek omega)) - - "∆": [t: "CGL⠙"] # 0x2206 (Increment (capital Greek delta)) - - "∏": [t: "CGL⠏"] # 0x220F (Product (capital Greek pi)) - - "∑": [t: "CGL⠎"] # 0x2211 (Sum (capital Greek sigma)) - - # --- restored short definitions that differ from unicode-full --- - - "⋇": [t: "1⠌⠯⠦"] # 0x22C7 (Division times) - - "⊩": [t: "⠸⠳⠿⠸⠒"] # 0x22A9 (Forces) +--- +# UEB characters +# +# Some chars that originally came from an Excel spreadsheet, converted to csv, and the greatly expanded +# +# The UEB translation makes use of some non-braille chars as flags +# L -- what follows is a letter +# N -- what follows is a digit +# C -- precedes L for capital letters +# G -- precedes L for Greek Letters (after C for capitals) +# Typeface Indicators ("typeforms") +# B bold, I Italic, S Sans-serif, T script, D, Fraktur, 𝔹 blackboard-bold +# the type face indicators can be combined with B (first) and I (second) +# Standing alone chars: +# Any character which acts as a standing alone character (e.g, "{") needs each braille symbol to be labeled +# o -- opening/left side, c -- closing/right side, b -- both open and close (e.g, '"') + + + - "=": [t: "⠐⠶"] # 0x003D (Equals) + - "≠": [t: "⠐⠶⠈⠱"] # 0x2260 (Not equal) + - "<": [t: "⠈⠣"] # 0x003C (Less than) + - "≤": [t: "⠸⠈⠣"] # 0x2264 (Less than or equal to) + - ">": [t: "⠈⠜"] # 0x003E (Greater than) + - "≣": [t: "⠈⠸⠠⠤"] # 0x2263 + - "≥": [t: "⠸⠈⠜"] # 0x2265 (Greater than or equal to) + - "≪": [t: "⠨⠈⠣"] # 0x226A (Much less than) + - "≫": [t: "⠨⠈⠜"] # 0x226B (Much greater than) + - "≮": [t: "⠈⠣⠈⠱"] # 0x226E (Not less than) + - "≯": [t: "⠈⠜⠈⠱"] # 0x226F (Not greater than) + - "≰": [t: "⠸⠈⠣⠈⠱"] # 0x2270 (Neither less than nor equal to) + - "≱": [t: "⠸⠈⠜⠈⠱"] # 0x2271 (Neither greater than nor equal to) + - "∝": [t: "⠸⠐⠶"] # 0x221D (Proportional to) + - "≃": [t: "⠸⠔"] # 0x2243 (Approximately equal to (tilde over horizontal line)) + - "≅": [t: "⠐⠸⠔"] # 0x2245 (Approximately equal to (tilde over equals sign)) + - "≈": [t: "⠘⠔"] # 0x2248 (Approximately equal (tilde over tilde)) + - "≏": [t: "⠘⠐⠶"] # 0x224F (Equals with bump in top bar (difference between)) + - "≑": [t: "⠨⠐⠶"] # 0x2251 (Geometrically equal to (equals dotted above and below)) + - "≟": [t: "𝟙⠦⠻⠐⠶"] # 0x225F (Questioned equal to) + - "≡": [t: "⠸⠿"] # 0x2261 (Equivalent to (three horizontal lines)) + - "≢": [t: "⠸⠿⠈⠱"] # 0x2262 (Not identical to) + - "∈": [t: "⠘⠑"] # 0x2208 (Element of (member of)) + - "∉": [t: "⠘⠑⠈⠱"] # 0x2209 (Not Element of) + - "+": [t: "⠐⠖"] # 0x002B (Plus sign) + - "∋": [t: "⠈⠘⠑"] # 0x220B (Contains) + - "⊂": [t: "⠘⠣"] # 0x2282 (Subset of) + - "⊃": [t: "⠘⠜"] # 0x2283 (Superset of) + - "⊆": [t: "⠸⠘⠣"] # 0x2286 (Subset of or equal) + - "⊇": [t: "⠸⠘⠜"] # 0x2287 (Superset of or equal) + - "⊊": [t: "⠨⠘⠣"] # 0x228A (Subset of with not equal) + - "⊋": [t: "⠨⠘⠜"] # 0x228B (Superset of with not equal) + - "⊲": [t: "⠈⠸⠣"] # 0x22B2 (Normal subgroup of) + - "⊳": [t: "⠈⠸⠜"] # 0x22B3 (Contains as normal subgroup) + - "⊴": [t: "⠸⠸⠣"] # 0x22B4 (Normal subgroup of or equal) + - "⊵": [t: "⠸⠸⠜"] # 0x22B5 (Contains as normal subgroup or equal) + - "⊻": [t: "𝟙⠈⠖⠠⠱"] # 0x22bb (Xor) + - "⋬": [t: "⠨⠸⠣"] # 0x22EC (not normal subgroup) -- this isn't the same as what is in GTM 10, but that similar has no Unicode equiv + - "⋭": [t: "⠨⠸⠣"] # 0x22ED (does not contain as normal subgroup) -- this isn't the same as what is in GTM 10, but that similar has no Unicode equiv + - "⊢": [t: "⠸⠒"] # 0x22a2 (Right tack) + - "⊣": [t: "⠈⠸⠒"] # 0x22a3 (Left tack) + - "−": [t: "⠐⠤"] # 0x2212 (Minus sign) + - "·": [t: "⠐⠲"] # 0x00B7 (Multiplication dot (times)) + - "×": [t: "⠐⠦"] # 0x00D7 (Multiplication sign (times)) + - "÷": [t: "⠐⠌"] # 0x00F7 (Division sign (divided by)) + - "±": [t: "⠸⠖"] # 0x00B1 (Plus or minus) + - "∓": [t: "⠸⠤"] # 0x2213 (Minus or plus) + - "∗": [t: "⠐⠔"] # 0x2217 (Asterisk operator) + - "∘": [t: "⠐⠴"] # 0x2218 (Ring operator) + - "◦": [t: "⠐⠴"] # 0x25E6 (White bullet) + - "∼": [t: "⠈⠔"] # 0x223C (Tilde operator) + - "⋅": [t: "⠐⠲"] # 0x22C5 (Dot operator) + - "∧": [t: "⠈⠦"] # 0x2227 (Logical and) + - "∨": [t: "⠈⠖"] # 0x2228 (Logical or) + - "∩": [t: "⠨⠦"] # 0x2229 (Intersection) + - "∪": [t: "⠨⠖"] # 0x222A (Union) + - "∖": [t: "⠸⠡"] # 0x2216 (Set minus) + - "(": [t: "o⠐o⠣"] # 0x0028 (Left parenthesis) + - ")": [t: "c⠐c⠜"] # 0x0029 (Right parenthesis) + - "[": [t: "o⠨o⠣"] # 0x005B (Left square bracket) + - "]": [t: "c⠨c⠜"] # 0x005D (Right square bracket) + - "{": [t: "o⠸o⠣"] # 0x007B (Left curly bracket) + - "}": [t: "c⠸c⠜"] # 0x007D (Right curly bracket) + - "〈": [t: "o⠈⠣"] # 0x2329 (Left angle bracket) + - "〉": [t: "c⠈⠜"] # 0x232A (Right angle bracket) + - "⟨": [t: "o⠈⠣"] # 0x27E8 (Left angle bracket) + - "⟩": [t: "c⠈⠜"] # 0x27E9 (Right angle bracket) + - "|": # 0x007C (Vertical line) + - test: + if: "preceding-sibling::* and following-sibling::*" + then: [t: "W⠸⠳W"] # comparison (e.g., such that -- rule 145) + else: [t: "⠸⠳"] # absolute value, others??? + - "!": [t: "c⠖"] # 0x21 (Exclamation (factorial)) + - "#": [t: "⠸⠹"] # 0x23 (Number sign (hash)) + - "%": [t: "⠨⠴"] # 0x25 (Percent sign) + - "&": [t: "⠈⠯"] # 0x26 (Ampersand) + - "*": [t: "⠐⠔"] # 0x002A (Asterisk) + - "/": [t: "⠸⠌"] # 0x002F (Solidus (slash)) + - ";": [t: "1c⠆"] # 0x003B (Semicolon) + - "?": [t: "1c⠦"] # 0x003F (Question mark) + - "@": [t: "⠈⠁"] # 0x0040 (Commercial at sign) + - "\\": [t: "⠸⠡"] # 0x005C (Backslash) + - "^": [t: "⠈⠢"] # 0x005E (Caret (hat, up arrow)) + - "_": [t: "⠨⠤"] # 0x005F (Low line (underscore)) + - "~": [t: "⠈⠔"] # 0x007E (Tilde (swung dash)) + - "¢": [t: "⠈⠉"] # 0x00A2 (Cents sign) + - "‐": [t: "⠤"] # 0x2010 (Hyphen) + - "–": [t: "P⠠⠤"] # 0x2013 (En Dash) + - "―": [t: "⠐⠠⠤"] # 0x2015 (Horizontal Bar) + - "‖": [t: "⠸⠳"] # 0x2016 + - "€": [t: "⠈⠑"] # 0x20AC (Euro sign) + - "₣": [t: "⠈⠋"] # 0x20A3 (French franc sign) + - "£": [t: "⠈⠇"] # 0x00A3 (Pound sign) + - "₦": [t: "⠈⠝"] # 0x20A6 (Naira sign) + - "$": [t: "⠈⠎"] # 0x0024 (Dollar sign) + - "¥": [t: "⠈⠽"] # 0x00A5 (Yen sign) + - "¦": [t: "⠨⠳"] # 0x00A6 (Broken bar) + - "¬": [t: "⠈⠹"] # 0x00AC (Not sign) + - "°": [t: "⠘⠚"] # 0x00B0 (Degree sign) + - "†": [t: "⠈⠠⠹"] # 0x2020 (Dagger) + - "‡": [t: "⠈⠠⠻"] # 0x2021 (Double dagger) + - "…": [t: "c⠲c⠲c⠲"] # 0x2026 (Ellipsis) + - "⋯": [t: "⠄⠄⠄"] # 0x22EF (midline horizontal ellipsis; GTM 15.4 matrix omission) + - "′": [t: "1⠶"] # 0x2032 (Prime sign) + - "″": [t: "1⠶⠶"] # 0x2033 (Double prime sign) + - "‴": [t: "1⠶⠶⠶"] # 0x2034 (Triple prime sign) + - "℃": [t: "⠘⠚⠠⠉"] # 0x2103 (Degrees Celsius) + - "℉": [t: "⠘⠚⠠⠋"] # 0x2109 (Degrees Fahrenheit) + - "Å": [t: "CA⠘⠫L⠁"] # 0x212B (Angstrom symbol) + - "Å": [t: "CA⠘⠫L⠁"] # 0x00C5 (WIRIS uses this for Angstrom) + - "∀": [t: "⠘⠁"] # 0x2200 (For all) + - "∂": [t: "⠈⠙"] # 0x2202 (Partial differential) + - "∃": [t: "⠘⠢"] # 0x2203 (There exists) + - "∄": [t: "⠘⠢⠈⠱"] # 0x2204 (There does not exist) + - "∅": [t: "⠈⠚"] # 0x2205 (Empty set) + - "∇": [t: "⠘⠙"] # 0x2207 (Nabla (del, inverted capital delta)) + - "∎": [t: "⠸⠫⠼⠙t"] # 0x220E (End of proof) + - "√": [t: "⠐⠩"] # 0x221A (Square root (radical) without vinculum) + - "∞": [t: "⠼⠿"] # 0x221E (Infinity) + - "∠": [t: "⠸⠪"] # 0x2220 (Angle) + - "∡": [t: "⠨⠸⠪"] # 0x2221 (Measured angle) + - "⊾": [t: "⠼⠸⠪"] # 0x22BE (Right angle with arc) + - "∫": [t: "1⠮"] # 0x222B (Integral) + - "∮": [t: "⠈⠮"] # 0x222E (Contour integral (closed line integral)) + - "∴": [t: "1⠠⠡"] # 0x2234 (Therefore) + - "∵": [t: "⠈⠌"] # 0x2235 (Because (since)) + - "∶": [t: "⠒"] # 0x2236 (Ratio) + - "∷": [t: "⠒⠒"] # 0x2237 (Proportion) + - "∣": [t: "⠸⠳"] # 0x2223 (Divides) + - "∤": [t: "⠸⠳⠈⠱"] # 0x2224 (Does not divide) + - "∥": [t: "⠼⠇"] # 0x2225 (Parallel) + - "∦": [t: "⠼⠇⠈⠱"] # 0x2226 (Not parallel) + - "⟂": [t: "⠼⠤"] # 0x27C2 (Perpendicular) + - "⊥": [t: "⠼⠤"] # 0x22A5 (Up tack (perpendicular)) + - "⊦": [t: "⠸⠒"] # 0x22A6 (Assertion (is a theorem)) + - "⊨": [t: "⠘⠸⠒"] # 0x22A8 (TRUE (is valid)) + - "⊬": [t: "⠸⠒⠈⠱"] # 0x22AC (Does not prove) + - "⊭": [t: "⠘⠸⠒⠈⠱"] # 0x22AD (Not TRUE) + - "⫅": [t: "⠘⠣⠰⠻⠐⠶"] # 0x2AC5 (Subset above equals) + - "⫆": [t: "⠘⠜⠰⠻⠐⠶"] # 0x2AC6 (Superset above equals) + - "⫤": [t: "⠨⠸⠒"] # 0x2AE4 (Vertical bar double left turnstile) + - "⬠": [t: "1⠫⠼⠑t"] # 0x2B20 (White Pentagon) + - "⬡": [t: "1⠫⠼⠋t"] # 0x2B21 (White Hexagon) + - "✓": [t: "⠈⠩"] # 0x2713 (Check mark (tick)) + - "⦵": [t: "⠨⠚"] # 0x29B5 (Plimsoll sign) + - "⮖": [t: "1⠐⠠⠤⠯⠫⠿"] # 0x2B96 (MEDIUM SMALL WHITE CIRCLE WITH HORIZONTAL BAR (standard state)) + - "←": [t: "1⠳⠪"] # 0x2190 (Leftwards arrow) + - "↑": [t: "1⠳⠬"] # 0x2191 (Upwards arrow) + - "→": [t: "1⠳⠕"] # 0x2192 (Rightwards arrow) + - "↓": [t: "1⠳⠩"] # 0x2193 (Downwards arrow) + - "↔": [t: "1⠳⠺⠗⠕"] # 0x2194 (Left right arrow) + - "↕": [t: "1⠳⠺⠗⠬"] # 0x2195 (Up down arrow) + - "↖": [t: "1⠳⠱"] # 0x2196 (Northwest arrow) + - "↗": [t: "1⠳⠎"] # 0x2197 (Northeast arrow) + - "↘": [t: "1⠳⠣"] # 0x2198 (Southeast arrow) + - "↙": [t: "1⠳⠜"] # 0x2199 (Southwest arrow) + - "↚": [t: "1⠳⠪⠈⠱"] # 0x219A (Leftwards arrow with stroke) + - "↛": [t: "1⠳⠕⠈⠱"] # 0x219B (Rightwards arrow with stroke) + - "↜": [t: "1⠳⠔⠢⠪"] # 0x219C (Leftwards wave arrow) + - "↝": [t: "1⠳⠢⠔⠕"] # 0x219D (Rightwards wave arrow) + - "↞": [t: "1⠳⠒⠗⠗⠪"] # 0x219E (Leftwards two headed arrow) + - "↟": [t: "1⠳⠒⠗⠗⠬"] # 0x219F (Upwards two headed arrow) + - "↠": [t: "1⠳⠒⠗⠗⠕"] # 0x21A0 (Rightwards two headed arrow) + - "↡": [t: "1⠳⠒⠗⠗⠩"] # 0x21A1 (Downwards two headed arrow) + - "↢": [t: "1⠳⠗⠗⠪"] # 0x21A2 (Leftwards arrow with tail) + - "↣": [t: "1⠳⠗⠗⠕"] # 0x21A3 (Rightwards arrow with tail) + - "↤": [t: "1⠳⠳⠗⠪"] # 0x21A4 (Leftwards arrow from bar) + - "↥": [t: "1⠳⠳⠗⠬"] # 0x21A5 (Upwards arrow from bar) + - "↦": [t: "1⠳⠳⠗⠕"] # 0x21A6 (Rightwards arrow from bar) + - "↧": [t: "1⠳⠳⠗⠩"] # 0x21A7 (Downwards arrow from bar) + - "↭": [t: "1⠳⠺⠔⠢⠗⠕"] # 0x21AD (Left right wave arrow) + - "↮": [t: "1⠳⠺⠗⠕⠈⠱"] # 0x21AE (Left right arrow with stroke) + - "↰": [t: "1⠳⠴⠬"] # 0x21B0 (Upwards arrow with tip left) + - "↱": [t: "1⠳⠲⠬"] # 0x21B1 (Upwards arrow with tip right) + - "↲": [t: "1⠳⠲⠩"] # 0x21B2 (Downwards arrow with tip left) + - "↳": [t: "1⠳⠴⠩"] # 0x21B3 (Downwards arrow with tip right) + - "↶": [t: "1⠳⠔⠔⠪"] # 0x21B6 (Anticlockwise top semicircle arrow) + - "↷": [t: "1⠳⠢⠢⠕"] # 0x21B7 (Clockwise top semicircle arrow) + - "↼": [t: "1⠳⠈⠗⠪"] # 0x21BC (Leftwards harpoon with barb upwards) + - "↽": [t: "1⠳⠠⠗⠪"] # 0x21BD (Leftwards harpoon with barb downwards) + - "↾": [t: "1⠳⠠⠗⠬"] # 0x21BE (Upwards harpoon with barb rightwards) + - "↿": [t: "1⠳⠈⠗⠬"] # 0x21BF (Upwards harpoon with barb leftwards) + - "⇀": [t: "1⠳⠈⠗⠕"] # 0x21C0 (Rightwards harpoon with barb upwards) + - "⇁": [t: "1⠳⠠⠗⠕"] # 0x21C1 (Rightwards harpoon with barb downwards) + - "⇂": [t: "1⠳⠈⠗⠩"] # 0x21C2 (Downwards harpoon with barb rightwards) + - "⇃": [t: "1⠳⠠⠗⠩"] # 0x21C3 (Downwards harpoon with barb leftwards) + - "⇄": [t: "1⠳⠕⠻⠳⠪"] # 0x21C4 (Rightwards arrow over leftwards arrow) + - "⇅": [t: "1⠳⠬⠿⠳⠩"] # 0x21C5 (Upwards arrow left of Downwards arrow) + - "⇌": [t: "1⠘⠸⠶"] # 0x21CC (Rightwards harpoon over leftwards harpoon (equilibrium)) + - "⇐": [t: "1⠳⠶⠪"] # 0x21D0 (Leftwards double arrow) + - "⇑": [t: "1⠳⠶⠬"] # 0x21D1 (Upwards double arrow) + - "⇒": [t: "1⠳⠶⠕"] # 0x21D2 (Rightwards double arrow) + - "⇓": [t: "1⠳⠶⠩"] # 0x21D3 (Downwards double arrow) + - "⇔": [t: "1⠳⠺⠶⠗⠕"] # 0x21D4 (Left right double arrow) + - "⇕": [t: "1⠳⠺⠶⠗⠬"] # 0x21D5 (Up down double arrow) + - "⇠": [t: "1⠳⠂⠪"] # 0x21E0 (Leftwards dashed arrow) + - "⇡": [t: "1⠳⠂⠬"] # 0x21E1 (Upwards dashed arrow) + - "⇢": [t: "1⠳⠂⠕"] # 0x21E2 (Rightwards dashed arrow) + - "⇣": [t: "1⠳⠂⠩"] # 0x21E3 (Downwards dashed arrow) + - "⟵": [t: "1⠳⠒⠒⠒⠪"] # 0x27F5 (Long leftwards arrow) + - "⟶": [t: "1⠳⠒⠒⠒⠕"] # 0x27F6 (Long rightwards arrow) + - "⥂": [t: "1⠸⠶"] # 0x2942 (Rightwards arrow above short leftwards arrow (equilibrium, trend to the right)) + - "⥄": [t: "1⠈⠸⠶"] # 0x2944 (Short rightwards arrow above leftwards arrow (equilibrium, trend to the left)) + +# Mappings for some new Unicode chemistry arrows/symbols +# These repeat the short arrow version because that is what is in the spec (GTM 16), but the spec should really use the long version + - "🣑": [t: "1⠘⠸⠶"] # 0x1F8D1 LONG RIGHTWARDS HARPOON OVER LONG LEFTWARDS HARPOON (equilibrium) + - "🣒": [t: "1⠐⠸⠶"] # 0x1f8d2 LONG RIGHTWARDS HARPOON ABOVE SHORT LEFTWARDS HARPOON(equilibrium, trend to the right) + - "🣓": [t: "1⠈⠸⠶"] # 0x1f8d3 SHORT RIGHTWARDS HARPOON ABOVE LONG LEFTWARDS HARPOON (equilibrium, trend to the left)) + +# These need to be verified -- 0x1f8d1, 0x1f8d2, and 0x1f8d3 conflict with GTM 16 (uses short arrow when really should be long) + - "🣐": [t: "1⠳⠒⠒⠒⠕⠻⠳⠒⠒⠒⠪"] # 0x1F8D0 LONG RIGHTWARDS ARROW OVER LONG LEFTWARDS ARROW + - "🣕": [t: "1⠳⠒⠈⠗⠪⠻⠳⠒⠒⠒⠠⠗⠕"] # 0x1F8D5 SHORT LEFTWARDS HARPOON ABOVELONG RIGHTWARDS HARPOON + - "🣖": [t: "1⠳⠒⠒⠒⠕⠯⠠⠭"] # 0x1F8D6 LONG RIGHTWARDS ARROW WITH THROUGH X + - "🣗": [t: "1⠳⠒⠒⠒⠕⠯⠣⠸⠌⠸⠌⠜"] # 0x1F8D7 LONG RIGHTWARDS ARROW WITH DOUBLE SLASH +# - "": [t: ""] # 0x1F8D8 LONG LEFT RIGHT ARROW WITH DEPENDENT LOBE (no clue what to do) + + - "△": [t: "1⠫⠼⠉t"] # 0x25B3 (Triangle) + - "▫": [t: "1⠫⠼⠙t"] # 0x25AB (Small white Square) + - "□": [t: "1⠫⠼⠙t"] # 0x25A1 (Square) + - "◻": [t: "1⠫⠼⠙t"] # 0x25FB (Square) + - "▤": [t: "⠨⠫⠼⠙t"] # 0x25A4 (Square with horizontal fill) + - "▥": [t: "⠨⠫⠼⠙t"] # 0x25A5 (Square with vertical fill) + - "▦": [t: "⠨⠫⠼⠙t"] # 0x25A6 (Square with orthogonal crosshatch fill) + - "▧": [t: "⠨⠫⠼⠙t"] # 0x25A7 (Square with upper left to lower right fill) + - "▨": [t: "⠨⠫⠼⠙t"] # 0x25A8 (Square with upper right to lower left fill) + - "▩": [t: "⠨⠫⠼⠙t"] # 0x25A9 (Square with diagonal crosshatch fill) + - "○": [t: "1⠫⠿t"] # 0x25CB (Circle) + - "◍": [t: "⠨⠫⠿t"] # 0x25CD (Circle with vertical fill) + - "▱": [t: "1⠫⠈⠼⠙t"] # 0x25B1 (Parallelogram) + - "▲": [t: "⠸⠫⠼⠉t"] # 0x25B2 (Filled triangle) + - "■": [t: "⠸⠫⠼⠙t"] # 0x25A0 (Filled square) + - "≜": [t: "⠠⠨⠙⠻⠐⠶"] # 0x225C (Delta equal to) + - "≝": [t: "1⠣⠙⠑⠋⠜⠻⠐⠶"] # 0x225D (Equal to by definition) + - "⊕": [t: "1⠫⠿⠪⠐⠖t"] # 0x2295 (Circled plus) + - "⊖": [t: "1⠫⠿⠪⠐⠤t"] # 0x2296 (Circled minus) + - "⊗": [t: "1⠫⠿⠪⠐⠦t"] # 0x2297 (Circled times) + - "⊛": [t: "1⠫⠿⠪⠐⠔t"] # 0x229B (Circled asterisk operator) + - "⊞": [t: "1⠫⠼⠙⠪⠐⠖t"] # 0x229E (Squared plus) + - "⊟": [t: "1⠫⠼⠙⠪⠐⠤t"] # 0x229F (Squared minus) + - "⊠": [t: "1⠫⠼⠙⠪⠐⠦t"] # 0x22A0 (Squared times) + - "˙": [t: "1⠲"] # 0x02D9 ( Dot Above) + - "¨": [t: "1⠲⠲"] # 0x00A8 ( Diaeresis/Double Dot Above ) + - "©": [t: "⠘⠉"] # 0xa9 (Copyright) + + + - "\"": [t: "b⠠b⠶"] + - "'": [t: "b⠄"] + - "“": [t: "o⠘o⠦"] + - "”": [t: "c⠘c⠴"] + - "‘": [t: "o⠠o⠦"] + - "’": [t: "c⠠c⠴"] + - "«": [t: "o⠸o⠦"] + - "»": [t: "c⠸c⠴"] + + - " ": # 0x20 (Space) + - test: + if: "self::m:mn" + then: [t: "N⠐"] + else: [t: "W"] + - " ": # 0xa0 (Non-breaking Space) + - test: + - if: "self::m:mn" + then: [t: "N⠐"] + - else_if: "@data-added='missing-content' or @data-empty-in-2D or @width > 1.1" + then: [t: "⠬"] # omission + - else_if: "@width < 0.25" + then: [t: ""] # tweaking space -- ignore + else: [t: "W"] # space in text or wide enough space + - ",": # 0x2c (Comma) + - test: + if: "self::m:mn" + then: [t: "N⠂"] + else: [t: "c,W"] + - ".": # 0x2e (Period) + - test: + if: "self::m:mn" + then: [t: "N⠲"] + else: [t: "c."] + - ":": # 0x003A (Colon) + # We can't normally tell spacing, but it *should* have a space in function mapping and set builder notation if the author used appropriate notation + # The canonicalization code makes this guess and adds "data-space-after" + - test: + if: "@data-space-after or (../self::m:mrow and ancestor::*[2][IsBracketed(., '{', '}')]) or following-sibling::*[1]/*[2][IsInDefinition(., 'Braille', 'Arrows')]" # "Arrows" is a bit broad... + then: [t: "1⠒W"] + else: [t: "1c⠒"] + + - "-": # 0x2d (Minus sign or hyphen) + - test: + if: "self::m:mo" + then: [t: "⠐⠤"] + else: [t: "⠤"] + + - "⁡": # 0x2061⁡ (invisible function apply) + - test: + if: + - "preceding-sibling::*[1][self::m:mi and substring(., string-length(.), 1)!=' '] and " # avoid scripted function names and one that end with spaces + - "following-sibling::*[1][self::m:mi and translate(., 'abcdefghijklmnopqrstuvwxyz', '') = '']" # GTM 9.3.2 + then: [t: "W"] + else: [t: ""] + + - "⁢": # 0x2062 (invisible times) + - test: + if: # GTM 9.3.3 (not very clear in rule, but the function name has to start with a lower case latin char ['no indicators']) + - "parent::m:mrow and " + - "preceding-sibling::*[1][" + - " (self::m:mi and translate(., 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', '') = '') or " + - " (self::m:mrow and translate(*[last()], 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', '') = '')] and" + - " following::*[1][self::m:mrow and count(*)=3 and " # look for function apply + - " *[2][.='⁡'] and *[1][self::m:mi and translate(., 'abcdefghijklmnopqrstuvwxyz', '') = '']]" + then: [t: "W"] + else: [t: ""] + - "⁣": [t: ""] # 0x2063⁡ (invisible separator) + - "⁤": [t: ""] # 0x2064 (invisible plus) + - "0": [t: "N⠚"] # 0x30 + - "1": [t: "N⠁"] # 0x31 + - "2": [t: "N⠃"] # 0x32 + - "3": [t: "N⠉"] # 0x33 + - "4": [t: "N⠙"] # 0x34 + - "5": [t: "N⠑"] # 0x35 + - "6": [t: "N⠋"] # 0x36 + - "7": [t: "N⠛"] # 0x37 + - "8": [t: "N⠓"] # 0x38 + - "9": [t: "N⠊"] # 0x39 + + - "a": [t: "L⠁"] # 0x61 + - "b": [t: "L⠃"] # 0x62 + - "c": [t: "L⠉"] # 0x63 + - "d": [t: "L⠙"] # 0x64 + - "e": [t: "L⠑"] # 0x65 + - "f": [t: "L⠋"] # 0x66 + - "g": [t: "L⠛"] # 0x67 + - "h": [t: "L⠓"] # 0x68 + - "i": [t: "L⠊"] # 0x69 + - "j": [t: "L⠚"] # 0x6a + - "k": [t: "L⠅"] # 0x6b + - "l": [t: "L⠇"] # 0x6c + - "m": [t: "L⠍"] # 0x6d + - "n": [t: "L⠝"] # 0x6e + - "o": [t: "L⠕"] # 0x6f + - "p": [t: "L⠏"] # 0x70 + - "q": [t: "L⠟"] # 0x71 + - "r": [t: "L⠗"] # 0x72 + - "s": [t: "L⠎"] # 0x73 + - "t": [t: "L⠞"] # 0x74 + - "u": [t: "L⠥"] # 0x75 + - "v": [t: "L⠧"] # 0x76 + - "w": [t: "L⠺"] # 0x77 + - "x": [t: "L⠭"] # 0x78 + - "y": [t: "L⠽"] # 0x79 + - "z": [t: "L⠵"] # 0x7a + + # Latin capitals: chem-element letters use 𝐶 (no word indicator); others use C. + # Cells come from lowercase a-z via spell/translate. + - "BCHIKNOPSUVWY": # chemistry-capable capitals + - test: + if: "@data-chem-element" + then: [tc: "𝐶"] + else: [tc: "C"] + - spell: "translate('.', 'BCHIKNOPSUVWY', 'bchiknopsuvwy')" + - "ADEFGJLMQRTXZ": # remaining capitals + - tc: "C" + - spell: "translate('.', 'ADEFGJLMQRTXZ', 'adefgjlmqrtxz')" + + - "α": [t: "GL⠁"] # 0x3b1 + - "β": [t: "GL⠃"] # 0x3b2 + - "γ": [t: "GL⠛"] # 0x3b3 + - "δ": [t: "GL⠙"] # 0x3b4 + - "ε": [t: "GL⠑"] # 0x3b5 + - "ζ": [t: "GL⠵"] # 0x3b6 + - "η": [t: "GL⠱"] # 0x3b7 + - "θ": [t: "GL⠹"] # 0x3b8 + - "ι": [t: "GL⠊"] # 0x3b9 + - "κ": [t: "GL⠅"] # 0x3ba + - "λ": [t: "GL⠇"] # 0x3bb + - "μ": [t: "GL⠍"] # 0x3bc + - "ν": [t: "GL⠝"] # 0x3bd + - "ξ": [t: "GL⠭"] # 0x3be + - "ο": [t: "GL⠕"] # 0x3bf + - "π": [t: "GL⠏"] # 0x3c0 + - "ρ": [t: "GL⠗"] # 0x3c1 + - "ς": [t: "GL⠎"] # 0x3c2 + - "σ": [t: "GL⠎"] # 0x3c3 + - "τ": [t: "GL⠞"] # 0x3c4 + - "υ": [t: "GL⠥"] # 0x3c5 + - "φ": [t: "GL⠋"] # 0x3c6 + - "χ": [t: "GL⠯"] # 0x3c7 + - "ψ": [t: "GL⠽"] # 0x3c8 + - "ω": [t: "GL⠺"] # 0x3c9 + + - "ϑ": [t: "GL⠹"] # 0x3d1 + - "ϵ": [t: "GL⠑"] # 0x3f5 \varepsilon + - "ϰ": [t: "GL⠅"] # 0x3f0 + - "ϕ": [t: "GL⠋"] # 0x3d5 + - "ϱ": [t: "GL⠗"] # 0x3f1 + - "ϖ": [t: "GL⠏"] # 0x3d6 + - "Ϝ": [t: "GL⠧"] # 0x3d7 + + - "Α": [t: "CGL⠁"] # 0x391 + - "Β": [t: "CGL⠃"] # 0x392 + - "Γ": [t: "CGL⠛"] # 0x393 + - "Δ": [t: "CGL⠙"] # 0x394 + - "Ε": [t: "CGL⠑"] # 0x395 + - "Ζ": [t: "CGL⠵"] # 0x396 + - "Η": [t: "CGL⠱"] # 0x397 + - "Θ": [t: "CGL⠹"] # 0x398 + - "Ι": [t: "CGL⠊"] # 0x399 + - "Κ": [t: "CGL⠅"] # 0x39a + - "Λ": [t: "CGL⠇"] # 0x39b + - "Μ": [t: "CGL⠍"] # 0x39c + - "Ν": [t: "CGL⠝"] # 0x39d + - "Ξ": [t: "CGL⠭"] # 0x39e + - "Ο": [t: "CGL⠕"] # 0x39f + - "Π": [t: "CGL⠏"] # 0x3a0 + - "Ρ": [t: "CGL⠗"] # 0x3a1 + - "΢": [t: "CGL⠎"] # 0x3a2 + - "Σ": [t: "CGL⠎"] # 0x3a3 + - "Τ": [t: "CGL⠞"] # 0x3a4 + - "Υ": [t: "CGL⠥"] # 0x3a5 + - "Φ": [t: "CGL⠋"] # 0x3a6 + - "Χ": [t: "CGL⠯"] # 0x3a7 + - "Ψ": [t: "CGL⠽"] # 0x3a8 + - "Ω": [t: "CGL⠺"] # 0x3a9 + + - "µ": [t: "GL⠍"] # 0x00B5 (Micro (Greek mu)) + - "Ω": [t: "CGL⠺"] # 0x2126 (Ohm sign (capital Greek omega)) + - "∆": [t: "CGL⠙"] # 0x2206 (Increment (capital Greek delta)) + - "∏": [t: "CGL⠏"] # 0x220F (Product (capital Greek pi)) + - "∑": [t: "CGL⠎"] # 0x2211 (Sum (capital Greek sigma)) + + # --- restored short definitions that differ from unicode-full --- + - "⋇": [t: "1⠌⠯⠦"] # 0x22C7 (Division times) + - "⊩": [t: "⠸⠳⠿⠸⠒"] # 0x22A9 (Forces) diff --git a/Rules/Braille/Vietnam/unicode.yaml b/Rules/Braille/Vietnam/unicode.yaml index 78a9adaa6..c86e95055 100644 --- a/Rules/Braille/Vietnam/unicode.yaml +++ b/Rules/Braille/Vietnam/unicode.yaml @@ -1,588 +1,588 @@ ---- -# Definitions for Vietnamese Math Braille. But most of theym are same as UEB. -# UEB characters -# -# Some chars that originally came from an Excel spreadsheet, converted to csv, and the greatly expanded -# -# The UEB translation makes use of some non-braille chars as flags -# L -- what follows is a letter -# N -- what follows is a digit -# C -- precedes L for capital letters -# G -- precedes L for Greek Letters (after C for capitals) -# Typeface Indicators ("typeforms") -# B bold, I Italic, S Sans-serif, T script, D, Fraktur, 𝔹 blackboard-bold -# the type face indicators can be combined with B (first) and I (second) -# Standing alone chars: -# Any character which acts as a standing alone character (e.g, "{") needs each braille symbol to be labeled -# o -- opening/left side, c -- closing/right side, b -- both open and close (e.g, '"') - - - - "=": [T: "⠐⠶"] # 0x003D (Equals) - - "≠": [T: "⠐⠾"] # 0x2260 (Not equal) - - "<": [T: "⠐⠪"] # 0x003C (Less than) - - "≤": [T: "⠐⠪⠶"] # 0x2264 (Less than or equal to) - - ">": [T: "⠐⠕"] # 0x003E (Greater than) - - "≥": [T: "⠐⠕⠶"] # 0x2265 (Greater than or equal to) - - "≪": [T: "⠐⠪⠪"] # 0x226A (Much less than) - - "≫": [T: "⠐⠕⠕"] # 0x226B (Much greater than) - - "≮": [T: "⠐⠪⠈"] # 0x226E (Not less than) - - "≯": [T: "⠐⠕⠈"] # 0x226F (Not greater than) - - "≰": [T: "⠸⠐⠪⠈⠐⠾"] # 0x2270 (Neither less than nor equal to) - - "≱": [T: "⠸⠐⠕⠈⠐⠾"] # 0x2271 (Neither greater than nor equal to) - - "∝": [t: "⠸⠐⠶"] # 0x221D (Proportional to) - - "≃": [T: "⠐⠢⠢"] # 0x2243 (Approximately equal to (tilde over horizontal line)) - - "≅": [T: "⠐⠢⠢"] # 0x2245 (Approximately equal to (tilde over equals sign)) - - "≈": [T: "⠐⠢⠢"] # 0x2248 (Approximately equal (tilde over tilde)) - - "≏": [t: "⠘⠐⠶"] # 0x224F (Equals with bump in top bar (difference between)) - - "≑": [t: "⠨⠐⠶"] # 0x2251 (Geometrically equal to (equals dotted above and below)) - - "≡": [T: "⠐⠿"] # 0x2261 (Equivalent to (three horizontal lines)) vi: trùng - - "≢": [T: "⠐⠿⠈"] # 0x2262 (Not identical to) - - "∈": [T: "⠈⠑"] # 0x2208 (Element of (member of)) - - "∉": [T: "⠈⠑⠈"] # 0x2209 (Element of (not member of)) - - "+": [T: "⠐⠖"] # 0x002B (Plus sign) - - "∋": [t: "⠈⠘⠑"] # 0x220B (Contains) - - "⊂": [T: "⠘⠣"] # 0x2282 (Subset of) - - "⊃": [T: "⠘⠜"] # 0x2283 (Superset of) - - "⊆": [T: "⠘⠣⠐⠶"] # 0x2286 (Subset of or equal) - - "⊇": [T: "⠘⠜⠐⠶"] # 0x2287 (Superset of or equal) - - "⊊": [t: "⠨⠘⠣"] # 0x228A (Subset of with not equal) - - "⊋": [t: "⠨⠘⠜"] # 0x228B (Superset of with not equal) - - "⊲": [t: "⠈⠸⠣"] # 0x22B2 (Normal subgroup of) - - "⊳": [t: "⠈⠸⠜"] # 0x22B3 (Contains as normal subgroup) - - "⊴": [t: "⠸⠸⠣"] # 0x22B4 (Normal subgroup of or equal) - - "⊵": [t: "⠸⠸⠜"] # 0x22B5 (Contains as normal subgroup or equal) - - "⋬": [t: "⠨⠸⠣"] # 0x22EC (not normal subgroup) -- this isn't the same as what is in GTM 10, but that similar has no Unicode equiv - - "⋭": [t: "⠨⠸⠣"] # 0x22ED (does not contain as normal subgroup) -- this isn't the same as what is in GTM 10, but that similar has no Unicode equiv - - "−": [t: "⠐⠤"] # 0x2212 (Minus sign) - - "·": [T: "⠐⠦"] # 0x00D7 (Multiplication dot (times)) - - "×": [T: "⠐⠦"] # 0x00D7 (Multiplication sign (times)) - - "÷": [T: "⠐⠲"] # 0x00F7 (Division sign (divided by)) - - "±": [T: "⠐⠖⠤"] # 0x00B1 (Plus or minus) - - "∓": [T: "⠐⠤⠖"] # 0x2213 (Minus or plus) - - "∗": [t: "⠐⠦"] # 0x2217 (Asterisk operator) - - "∘": [t: "⠐⠴"] # 0x2218 (Ring operator) - - "◦": [t: "⠐⠴"] # 0x25E6 (White bullet) - - "∼": [t: "⠈⠔"] # 0x223C (Tilde operator) - - "⋅": [t: "⠐⠦"] # 0x22C5 (Dot operator) - - "∧": [t: "⠈⠦"] # 0x2227 (Logical and) - - "∨": [t: "⠈⠖"] # 0x2228 (Logical or) - - "∩": [T: "⠨⠦"] # 0x2229 (Intersection) - - "∪": [T: "⠨⠖"] # 0x222A (Union) - - "∖": [T: "⠸⠡"] # 0x2216 (Set minus) - - "(": [T: "o⠈o⠣"] # 0x0028 (Left parenthesis) - - ")": [T: "c⠈c⠜"] # 0x0029 (Right parenthesis) - - "[": [T: "o⠨o⠣"] # 0x005B (Left square bracket) - - "]": [T: "c⠨c⠜"] # 0x005D (Right square bracket) - - "{": [T: "o⠸o⠣"] # 0x007B (Left curly bracket) - - "}": [T: "c⠸c⠜"] # 0x007D (Right curly bracket) - - "〈": [T: "o⠸⠣⠤"] # 0x2329 (Left angle bracket) - - "〉": [T: "c⠤⠸⠜"] # 0x232A (Right angle bracket) - - "|": [T: "⠸⠳"] # 0x007C (Vertical line) - # - test: - # if: "preceding-sibling::* and following-sibling::*" - # then: [T: "W⠸⠳W"] # comparison (e.g., such that -- rule 145) - # else: [T: "⠸⠳"] # absolute value, others??? - - "!": [T: "c⠖"] # 0x21 (Exclamation (factorial)) - - "#": [T: "⠼"] # 0x23 (Number sign (hash)) - - "%": [T: "⠼⠚⠴"] # 0x25 (Percent sign) No dots 46 before as in UEB - - "&": [t: "⠈⠯"] # 0x26 (Ampersand) - - "*": [T: "⠐⠦"] # 0x002A (Asterisk) - - "/": [T: "⠐⠲"] # 0x002F (Solidus (slash)) - - ";": [t: "c⠆"] # 0x003B (Semicolon) - - "?": [T: "c⠢"] # 0x003F (Question mark) - - "@": [T: "⠈⠁"] # 0x0040 (Commercial at sign) - - "\\": [t: "⠸⠡"] # 0x005C (Backslash) - - "^": [t: "⠈⠢"] # 0x005E (Caret (hat, up arrow)) - - "_": [t: "⠨⠤"] # 0x005F (Low line (underscore)) - - "~": [t: "⠈⠔"] # 0x007E (Tilde (swung dash)) - - "¢": [t: "⠈⠉"] # 0x00A2 (Cents sign) - - "€": [t: "⠈⠑"] # 0x20AC (Euro sign) - - "₣": [t: "⠈⠋"] # 0x20A3 (French franc sign) - - "£": [t: "⠈⠇"] # 0x00A3 (Pound sign) - - "₦": [t: "⠈⠝"] # 0x20A6 (Naira sign) - - "$": [t: "⠈⠎"] # 0x0024 (Dollar sign) - - "¥": [t: "⠈⠽"] # 0x00A5 (Yen sign) - - "¦": [t: "⠨⠳"] # 0x00A6 (Broken bar) - - "¬": [t: "⠈⠹"] # 0x00AC (Not sign) - - "°": [T: "⠔⠚"] # 0x00B0 (Degree sign) - - "†": [t: "⠈⠠⠹"] # 0x2020 (Dagger) - - "‡": [t: "⠈⠠⠻"] # 0x2021 (Double dagger) - - "…": [T: "c⠄c⠄c⠄"] # 0x2026 (Ellipsis) - - "′": [T: "⠄"] # 0x2032 (Prime sign) - - "″": [T: "⠄⠄"] # 0x2033 (Double prime sign) - - "‴": [T: "⠄⠄⠄"] # 0x2034 (Triple prime sign) - - "Å": [t: "⠠⠘⠫⠁"] # 0x212B (Angstrom symbol) - - "Å": [t: "⠠⠘⠫⠁"] # 0x00C5 (WIRIS uses this for Angstrom) - - "∀": [t: "⠘⠁"] # 0x2200 (For all) - - "∂": [t: "⠈⠙"] # 0x2202 (Partial differential) - - "∃": [T: "⠘⠑"] # 0x2203 (There exists) - - "∄": [T: "⠘⠑⠈"] # 0x2204 (There does not exist) - - "∅": [T: "⠈⠚"] # 0x2205 (Empty set) - - "∇": [t: "⠘⠙"] # 0x2207 (Nabla (del, inverted capital delta)) - - "∎": [t: "⠸⠫⠼⠙t"] # 0x220E (End of proof) - - "√": [T: "⠩"] # 0x221A (Square root (radical) without vinculum) - - "∞": [T: "⠼⠕"] # 0x221E (Infinity) - - "∠": [T: "⠫⠛"] # 0x2220 (Angle) - - "∡": [T: "⠨⠫⠛"] # 0x2221 (Measured angle) - - "⊾": [T: "⠼⠫⠛"] # 0x22BE (Right angle with arc) - - "∟": [T: "⠫⠧"] - - "∫": [T: "⠾"] # 0x222B (Integral) - - "∮": [T: "⠐⠾"] # 0x222E (Contour integral (closed line integral)) - - "∴": [t: "⠠⠡"] # 0x2234 (Therefore) - - "∵": [t: "⠈⠌"] # 0x2235 (Because (since)) - - "∶": [t: "⠒"] # 0x2236 (Ratio) - - "∷": [T: "⠒⠒"] # 0x2237 (Proportion) - - "∣": [T: "⠣⠴⠜"] # 0x2223 (Divides) ueb: ⠸⠳ - - "∤": [T: "⠣⠼⠜"] # 0x2224 (Does not divide) ueb: ⠸⠳⠈⠱ - - "∥": [T: "⠫⠶"] # 0x2225 (Parallel) VI: AB parallel to CD, should be: ⠫AB⠶CD - - "∦": [T: "⠫⠾"] # 0x2226 (Not parallel) Vi: AB not parallel to CD, should be: ⠫AB⠐⠾CD - - "⟂": [T: "⠫⠧"] # 0x27C2 (Perpendicular) - - "⊢": [t: "⠸⠒"] # 0x22a2 (Right tack) - - "⊣": [t: "⠈⠸⠒"] # 0x22a3 (Left tack) - - "⊥": [T: "⠫⠧"] # 0x22A5 (Up tack (perpendicular)) - - "⊦": [t: "⠸⠒"] # 0x22A6 (Assertion (is a theorem)) - - "⊨": [t: "⠘⠸⠒"] # 0x22A8 (TRUE (is valid)) - - "⊬": [t: "⠸⠒⠈⠱"] # 0x22AC (Does not prove) - - "⊭": [t: "⠘⠸⠒⠈⠱"] # 0x22AD (Not TRUE) - - "⫤": [t: "⠨⠸⠒"] # 0x2AE4 (Vertical bar double left turnstile) - - "✓": [t: "⠈⠩"] # 0x2713 (Check mark (tick)) - - "⦵": [t: "⠨⠚"] # 0x29B5 (Plimsoll sign (standard state)) - - "⮖": [t: "1⠐⠠⠤⠯⠫⠿"] # 0x2B96 (MEDIUM SMALL WHITE CIRCLE WITH HORIZONTAL BAR (standard state)) - - "←": [t: "⠳⠪"] # 0x2190 (Leftwards arrow) - - "↑": [t: "⠳⠬"] # 0x2191 (Upwards arrow) - - "→": [t: "⠳⠕"] # 0x2192 (Rightwards arrow) - - "↓": [t: "⠳⠩"] # 0x2193 (Downwards arrow) - - "↔": [T: "⠳⠪⠶⠕"] # 0x2194 (Left right arrow) - - "↕": [t: "⠳⠺⠗⠬"] # 0x2195 (Up down arrow) - - "↖": [t: "⠳⠱"] # 0x2196 (Northwest arrow) - - "↗": [t: "⠳⠎"] # 0x2197 (Northeast arrow) - - "↘": [t: "⠳⠣"] # 0x2198 (Southeast arrow) - - "↙": [t: "⠳⠜"] # 0x2199 (Southwest arrow) - - "↚": [t: "⠳⠪⠈⠱"] # 0x219A (Leftwards arrow with stroke) - - "↛": [t: "⠳⠕⠈⠱"] # 0x219B (Rightwards arrow with stroke) - - "↜": [t: "⠳⠔⠢⠪"] # 0x219C (Leftwards wave arrow) - - "↝": [t: "⠳⠢⠔⠕"] # 0x219D (Rightwards wave arrow) - - "↞": [t: "⠳⠒⠗⠗⠪"] # 0x219E (Leftwards two headed arrow) - - "↟": [t: "⠳⠒⠗⠗⠬"] # 0x219F (Upwards two headed arrow) - - "↠": [t: "⠳⠒⠗⠗⠕"] # 0x21A0 (Rightwards two headed arrow) - - "↡": [t: "⠳⠒⠗⠗⠩"] # 0x21A1 (Downwards two headed arrow) - - "↢": [t: "⠳⠗⠗⠪"] # 0x21A2 (Leftwards arrow with tail) - - "↣": [t: "⠳⠗⠗⠕"] # 0x21A3 (Rightwards arrow with tail) - - "↤": [t: "⠳⠳⠗⠪"] # 0x21A4 (Leftwards arrow from bar) - - "↥": [t: "⠳⠳⠗⠬"] # 0x21A5 (Upwards arrow from bar) - - "↦": [t: "⠳⠳⠗⠕"] # 0x21A6 (Rightwards arrow from bar) - - "↧": [t: "⠳⠳⠗⠩"] # 0x21A7 (Downwards arrow from bar) - - "↭": [t: "⠳⠺⠔⠢⠗⠕"] # 0x21AD (Left right wave arrow) - - "↮": [t: "⠳⠺⠗⠕⠈⠱"] # 0x21AE (Left right arrow with stroke) - - "↰": [t: "⠳⠴⠬"] # 0x21B0 (Upwards arrow with tip left) - - "↱": [t: "⠳⠲⠬"] # 0x21B1 (Upwards arrow with tip right) - - "↲": [t: "⠳⠲⠩"] # 0x21B2 (Downwards arrow with tip left) - - "↳": [t: "⠳⠴⠩"] # 0x21B3 (Downwards arrow with tip right) - - "↶": [t: "⠳⠔⠔⠪"] # 0x21B6 (Anticlockwise top semicircle arrow) - - "↷": [t: "⠳⠢⠢⠕"] # 0x21B7 (Clockwise top semicircle arrow) - - "↼": [t: "⠳⠈⠗⠪"] # 0x21BC (Leftwards harpoon with barb upwards) - - "↽": [t: "⠳⠠⠗⠪"] # 0x21BD (Leftwards harpoon with barb downwards) - - "↾": [t: "⠳⠠⠗⠬"] # 0x21BE (Upwards harpoon with barb rightwards) - - "↿": [t: "⠳⠈⠗⠬"] # 0x21BF (Upwards harpoon with barb leftwards) - - "⇀": [t: "⠳⠈⠗⠕"] # 0x21C0 (Rightwards harpoon with barb upwards) - - "⇁": [t: "⠳⠠⠗⠕"] # 0x21C1 (Rightwards harpoon with barb downwards) - - "⇂": [t: "⠳⠈⠗⠩"] # 0x21C2 (Downwards harpoon with barb rightwards) - - "⇃": [t: "⠳⠠⠗⠩"] # 0x21C3 (Downwards harpoon with barb leftwards) - - "⇄": [t: "⠳⠕⠻⠳⠪"] # 0x21C4 (Rightwards arrow over leftwards arrow) - - "⇅": [t: "⠳⠬⠿⠳⠩"] # 0x21C5 (Upwards arrow left of Downwards arrow) - - "⇌": [T: "⠳⠪⠕"] # 0x21CC (Rightwards harpoon over leftwards harpoon (equilibrium)) - - "⇐": [t: "⠳⠶⠪"] # 0x21D0 (Leftwards double arrow) - - "⇑": [t: "⠳⠶⠬"] # 0x21D1 (Upwards double arrow) - - "⇒": [t: "⠳⠶⠕"] # 0x21D2 (Rightwards double arrow) - - "⇓": [t: "⠳⠶⠩"] # 0x21D3 (Downwards double arrow) - - "⇔": [T: "⠳⠪⠶⠕"] # 0x21D4 (Left right double arrow) - - "⇕": [t: "⠳⠺⠶⠗⠬"] # 0x21D5 (Up down double arrow) - - "⇠": [t: "⠳⠂⠪"] # 0x21E0 (Leftwards dashed arrow) - - "⇡": [t: "⠳⠂⠬"] # 0x21E1 (Upwards dashed arrow) - - "⇢": [t: "⠳⠂⠕"] # 0x21E2 (Rightwards dashed arrow) - - "⇣": [t: "⠳⠂⠩"] # 0x21E3 (Downwards dashed arrow) - - "⟵": [t: "⠳⠪"] # 0x27F5 (Long leftwards arrow) - - "⟶": [t: "⠳⠕"] # 0x27F6 (Long rightwards arrow) - - "⥂": [t: "⠸⠶"] # 0x2942 (Rightwards arrow above short leftwards arrow (equilibrium, trend to the right)) - - "⥄": [t: "⠈⠸⠶"] # 0x2944 (Short rightwards arrow above leftwards arrow (equilibrium, trend to the left)) - -# Mappings for some new Unicode chemistry arrows/symbols -# These need to be verified -- 0x1f8d1, 0x1f8d2, and 0x1f8d3 conflict with GTM 16 (uses short arrow when really should be long) - - "🣐": [t: "⠳⠒⠒⠒⠕⠻⠳⠒⠒⠒⠪"] # 0x1F8D0 LONG RIGHTWARDS ARROW OVER LONG LEFTWARDS ARROW - - "🣑": [t: "⠳⠪⠕"] # 0x1f8d1 (Long rightwards harpoon over leftwards harpoon (equilibrium)) - - "🣒": [t: "⠸⠶"] # 0x1f8d2 (Long rightwards harpoon over leftwards harpoon (equilibrium, trend to the right)) - - "🣓": [t: "⠈⠸⠶"] # 0x1f8d3 (Long rightwards harpoon over leftwards harpoon (equilibrium, trend to the left)) -# - "🣑": [t: "⠳⠒⠒⠒⠈⠗⠕⠻⠳⠒⠒⠒⠠⠗⠪"] # 0x1F8D1 LONG RIGHTWARDS HARPOON OVER LONG LEFTWARDS HARPOON -# - "🣒": [t: "⠳⠒⠒⠒⠈⠗⠕⠻⠳⠒⠠⠗⠪"] # 0x1F8D2 LONG RIGHTWARDS HARPOON ABOVESHORT LEFTWARDS HARPOON -# - "🣓": [t: "⠳⠒⠈⠗⠕⠻⠳⠒⠒⠒⠠⠗⠪"] # 0x1F8D3 SHORT RIGHTWARDS HARPOON ABOVELONG LEFTWARDS HARPOON - - "🣔": [t: "⠳⠒⠒⠒⠈⠗⠪⠻⠳⠒⠠⠗⠕"] # 0x1F8D4 LONG LEFTWARDS HARPOON ABOVESHORT RIGHTWARDS HARPOON - - "🣕": [t: "⠳⠒⠈⠗⠪⠻⠳⠒⠒⠒⠠⠗⠕"] # 0x1F8D5 SHORT LEFTWARDS HARPOON ABOVELONG RIGHTWARDS HARPOON - - "🣖": [t: "⠳⠒⠒⠒⠕⠯⠠⠭"] # 0x1F8D6 LONG RIGHTWARDS ARROW WITH THROUGH X - - "🣗": [t: "⠐⠠⠤⠯⠫⠿"] # 0x1F8D7 LONG RIGHTWARDS ARROW WITH DOUBLE SLASH - - - "△": [T: "⠫⠼⠉"] # 0x25B3 (Triangle) - - "□": [T: "⠫⠼⠙"] # 0x25A1 (Square) - - "▤": [T: "⠨⠫⠼⠙"] # 0x25A4 (Square with horizontal fill) - - "▥": [T: "⠨⠫⠼⠙"] # 0x25A5 (Square with vertical fill) - - "▦": [T: "⠨⠫⠼⠙"] # 0x25A6 (Square with orthogonal crosshatch fill) - - "▧": [T: "⠨⠫⠼⠙"] # 0x25A7 (Square with upper left to lower right fill) - - "▨": [T: "⠨⠫⠼⠙"] # 0x25A8 (Square with upper right to lower left fill) - - "▩": [T: "⠨⠫⠼⠙"] # 0x25A9 (Square with diagonal crosshatch fill) - - "○": [t: "⠫⠿"] # 0x25CB (Circle) - - "◍": [T: "⠨⠫⠿"] # 0x25CD (Circle with vertical fill) - - "▱": [T: "⠫⠈⠼⠙"] # 0x25B1 (Parallelogram) - - "▲": [T: "⠸⠫⠼⠉"] # 0x25B2 (Filled triangle) - - "■": [T: "⠸⠫⠼⠙"] # 0x25A0 (Filled square) - - "≜": [T: "⠸⠙⠐⠶"] # 0x225C (Delta equal to) - - "≝": [t: "⠣⠙⠑⠋⠜⠻⠐⠶"] # 0x225D (Equal to by definition) - - "⊕": [t: "⠫⠿⠪⠐⠖t"] # 0x2295 (Circled plus) - - "⊖": [t: "⠫⠿⠪⠐⠤t"] # 0x2296 (Circled minus) - - "⊗": [t: "⠐⠦t"] # 0x2297 (Circled times) - - "⊛": [t: "⠐⠦t"] # 0x229B (Circled asterisk operator) - - "⊞": [t: "⠫⠼⠙⠪⠐⠖t"] # 0x229E (Squared plus) - - "⊟": [t: "⠫⠼⠙⠪⠐⠤t"] # 0x229F (Squared minus) - - "⊠": [t: "⠫⠼⠙⠪⠐⠦t"] # 0x22A0 (Squared times) - - "˙": [t: "⠲"] # 0x02D9 ( Dot Above) - - "¨": [t: "⠲⠲"] # 0x00A8 ( Diaeresis/Double Dot Above) - - "©": [t: "⠘⠉"] # 0xa9 (Copyright) - - - - "\"": [t: "b⠠b⠶"] - - "'": [t: "b⠄"] - - "“": [t: "o⠘o⠦"] - - "”": [t: "c⠘c⠴"] - - "‘": [t: "o⠠o⠦"] - - "’": [t: "c⠠c⠴"] - - "«": [t: "o⠸o⠦"] - - "»": [t: "c⠸c⠴"] - - - " ": # 0x20 (Space) - - test: - if: "self::m:mn" - then: [t: "N⠐"] - else: [t: "W"] - - " ": # 0xa0 (Non-breaking Space) - - test: - - if: "self::m:mn" - then: [t: "N⠐"] - - else_if: "following-sibling::*[1][@class='MathML-unit' or BaseNode(.)[@class='MathML-unit']]" - then: [t: "𝐖"] - else: [t: "W"] - - ",": # 0x2c (Comma) - - test: - if: "self::m:mn" - then: [t: "N⠂"] - else: [t: ",W"] - - ".": # 0x2e (Period) - - test: - if: "self::m:mn" - then: [T: "N⠄"] - else: [t: "."] - - ":": # 0x003A (Colon) - # Sometimes a colon is meant to be a ratio/mathord and sometimes a map/punct. - # The latter has a space after it. - # If in an mrow, guess it is infix and checks the operator. This is pretty weak! - # Field extensions "[K:F]" and trilinear coordinates "a:b:c" don't want extra space - # Time doesn't want an extra space -- the am/pm get wrapped in an mrow with the minutes after the colon - - test: - if: - - "ancestor::*[2][IsBracketed(., '{', '}')] or " # field extension - - "preceding-sibling::*[2][.=':'] or following-sibling::*[2][.=':'] or" # trilinear form - # ratios tend to have similar left and right sides - - "name(preceding-sibling::*[1]) = name(following-sibling::*[1]) or" - # am/pm test - - "(name(preceding-sibling::*[1]) = 'mn' and " - - " following-sibling::*[1][self::m:mrow and count(*)=3 and *[1][self::m:mn] and " - - " *[3][translate(., 'APM\u00A0', 'apm') = 'am' or translate(., 'APM\u00A0', 'apm') = 'pm']" - - " ])" - then: [t: "⠒"] - else: [t: "⠒W"] - - - "-": # 0x2d (Minus sign or hyphen) - - test: - if: "self::m:mo" - then: [t: "⠐⠤"] - else: [t: "⠤"] - - - "⁡": [t: ""] # 0x2061⁡ (invisible function apply) - #- test: - #if: - #- "preceding-sibling::*[1][self::m:mi and substring(., string-length(.), 1)!=' '] and " # avoid scripted function names and one that end with spaces - #- "following-sibling::*[1][self::m:mi and translate(., 'abcdefghijklmnopqrstuvwxyz', '') = '']" # GTM 9.3.2 - #then: [t: "W"] - #else: [t: ""] - - - "⁢": [t: ""] # 0x2062 (invisible times) - #- test: - #if: # GTM 9.3.3 (not very clear in rule, but the function name has to start with a lower case latin char ['no indicators']) - #- "parent::m:mrow and " - #- "preceding-sibling::*[1][" - #- " (self::m:mi and translate(., 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', '') = '') or " - #- " (self::m:mrow and translate(*[last()], 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', '') = '')] and" - #- " following::*[1][self::m:mrow and count(*)=3 and " # look for function apply - #- " *[2][.='⁡'] and *[1][self::m:mi and translate(., 'abcdefghijklmnopqrstuvwxyz', '') = '']]" - #then: [t: "W"] - #else: [t: ""] - - "⁣": [t: ""] # 0x2063⁡ (invisible separator) - - "⁤": [t: ""] # 0x2064 (invisible plus) - - "0": [t: "N⠚"] # 0x30 - - "1": [t: "N⠁"] # 0x31 - - "2": [t: "N⠃"] # 0x32 - - "3": [t: "N⠉"] # 0x33 - - "4": [t: "N⠙"] # 0x34 - - "5": [t: "N⠑"] # 0x35 - - "6": [t: "N⠋"] # 0x36 - - "7": [t: "N⠛"] # 0x37 - - "8": [t: "N⠓"] # 0x38 - - "9": [t: "N⠊"] # 0x39 - - # we stick the drop numbers into the private use area for consistency - - "\ue000": [t: "N⠴"] # 0 - - "\ue001": [t: "N⠂"] # 1 - - "\ue002": [t: "N⠆"] # 2 - - "\ue003": [t: "N⠒"] # 3 - - "\ue004": [t: "N⠲"] # 4 - - "\ue005": [t: "N⠢"] # 5 - - "\ue006": [t: "N⠖"] # 6 - - "\ue007": [t: "N⠶"] # 7 - - "\ue008": [t: "N⠦"] # 8 - - "\ue009": [t: "N⠔"] # 9 - - - "a": [t: "L⠁"] # 0x61 - - "b": [t: "L⠃"] # 0x62 - - "c": [t: "L⠉"] # 0x63 - - "d": [t: "L⠙"] # 0x64 - - "e": [t: "L⠑"] # 0x65 - - "f": [t: "L⠋"] # 0x66 - - "g": [t: "L⠛"] # 0x67 - - "h": [t: "L⠓"] # 0x68 - - "i": [t: "L⠊"] # 0x69 - - "j": [t: "L⠚"] # 0x6a - - "k": [t: "L⠅"] # 0x6b - - "l": [t: "L⠇"] # 0x6c - - "m": [t: "L⠍"] # 0x6d - - "n": [t: "L⠝"] # 0x6e - - "o": [t: "L⠕"] # 0x6f - - "p": [t: "L⠏"] # 0x70 - - "q": [t: "L⠟"] # 0x71 - - "r": [t: "L⠗"] # 0x72 - - "s": [t: "L⠎"] # 0x73 - - "t": [t: "L⠞"] # 0x74 - - "u": [t: "L⠥"] # 0x75 - - "v": [t: "L⠧"] # 0x76 - - "w": [t: "L⠺"] # 0x77 - - "x": [t: "L⠭"] # 0x78 - - "y": [t: "L⠽"] # 0x79 - - "z": [t: "L⠵"] # 0x7a - - - "đ": [t: "L⠮"] - - "á": [t: "L⠔L⠁"] - - "à": [t: "L⠰L⠁"] - - "ả": [t: "L⠢L⠁"] - - "ã": [t: "L⠤L⠁"] - - "ạ": [t: "L⠠L⠁"] - - "â": [t: "L⠡"] - - "ấ": [t: "L⠔L⠡"] - - "ầ": [t: "L⠰L⠡"] - - "ẩ": [t: "L⠢L⠡"] - - "ẫ": [t: "L⠤L⠡"] - - "ậ": [t: "L⠠L⠡"] - - "ă": [t: "L⠜"] - - "ắ": [t: "L⠔L⠜"] - - "ằ": [t: "L⠰L⠜"] - - "ẳ": [t: "L⠢L⠜"] - - "ẵ": [t: "L⠤L⠜"] - - "ặ": [t: "L⠠L⠜"] - - "é": [t: "L⠔L⠑"] - - "è": [t: "L⠰L⠑"] - - "ẻ": [t: "L⠢L⠑"] - - "ẽ": [t: "L⠤L⠑"] - - "ẹ": [t: "L⠠L⠑"] - - "ê": [t: "L⠣"] - - "ế": [t: "L⠔L⠣"] - - "ề": [t: "L⠰L⠣"] - - "ể": [t: "L⠢L⠣"] - - "ễ": [t: "L⠤L⠣"] - - "ệ": [t: "L⠠L⠣"] - - "í": [t: "L⠔L⠊"] - - "ì": [t: "L⠰L⠊"] - - "ỉ": [t: "L⠢L⠊"] - - "ĩ": [t: "L⠤L⠊"] - - "ị": [t: "L⠠L⠊"] - - "ó": [t: "L⠔L⠕"] - - "ò": [t: "L⠰L⠕"] - - "ỏ": [t: "L⠢L⠕"] - - "õ": [t: "L⠤L⠕"] - - "ọ": [t: "L⠠L⠕"] - - "ô": [t: "L⠹"] - - "ố": [t: "L⠔L⠹"] - - "ồ": [t: "L⠰L⠹"] - - "ổ": [t: "L⠢L⠹"] - - "ỗ": [t: "L⠤L⠹"] - - "ộ": [t: "L⠠L⠹"] - - "ơ": [t: "L⠪"] - - "ớ": [t: "L⠔L⠪"] - - "ờ": [t: "L⠰L⠪"] - - "ở": [t: "L⠢L⠪"] - - "ỡ": [t: "L⠤L⠪"] - - "ợ": [t: "L⠠L⠪"] - - "ú": [t: "L⠔L⠥"] - - "ù": [t: "L⠰L⠥"] - - "ủ": [t: "L⠢L⠥"] - - "ũ": [t: "L⠤L⠥"] - - "ụ": [t: "L⠠L⠥"] - - "ư": [t: "L⠳"] - - "ứ": [t: "L⠔L⠳"] - - "ừ": [t: "L⠰L⠳"] - - "ử": [t: "L⠢L⠳"] - - "ữ": [t: "L⠤L⠳"] - - "ự": [t: "L⠠L⠳"] - - "ý": [t: "L⠔L⠽"] - - "ỳ": [t: "L⠰L⠽"] - - "ỷ": [t: "L⠢L⠽"] - - "ỹ": [t: "L⠤L⠽"] - - "ỵ": [t: "L⠠L⠽"] - - - "Đ": [t: "CL⠮"] - - "Á": [t: "CL⠔𝑐L⠁"] - - "À": [t: "CL⠰𝑐L⠁"] - - "Ả": [t: "CL⠢𝑐L⠁"] - - "Ã": [t: "CL⠤𝑐L⠁"] - - "Ạ": [t: "CL⠠𝑐L⠁"] - - "Â": [t: "CL⠡"] - - "Ấ": [t: "CL⠔𝑐L⠡"] - - "Ầ": [t: "CL⠰𝑐L⠡"] - - "Ẩ": [t: "CL⠢𝑐L⠡"] - - "Ẫ": [t: "CL⠤𝑐L⠡"] - - "Ậ": [t: "CL⠠𝑐L⠡"] - - "Ă": [t: "CL⠜"] - - "Ắ": [t: "CL⠔𝑐L⠜"] - - "Ằ": [t: "CL⠰𝑐L⠜"] - - "Ẳ": [t: "CL⠢𝑐L⠜"] - - "Ẵ": [t: "CL⠤𝑐L⠜"] - - "Ặ": [t: "CL⠠𝑐L⠜"] - - "É": [t: "CL⠔𝑐L⠑"] - - "È": [t: "CL⠰𝑐L⠑"] - - "Ẻ": [t: "CL⠢𝑐L⠑"] - - "Ẽ": [t: "CL⠤𝑐L⠑"] - - "Ẹ": [t: "CL⠠𝑐L⠑"] - - "Ê": [t: "CL⠣"] - - "Ế": [t: "CL⠔𝑐L⠣"] - - "Ề": [t: "CL⠰𝑐L⠣"] - - "Ể": [t: "CL⠢𝑐L⠣"] - - "Ễ": [t: "CL⠤𝑐L⠣"] - - "Ệ": [t: "CL⠠𝑐L⠣"] - - "Í": [t: "CL⠔𝑐L⠊"] - - "Ì": [t: "CL⠰𝑐L⠊"] - - "Ỉ": [t: "CL⠢𝑐L⠊"] - - "Ĩ": [t: "CL⠤𝑐L⠊"] - - "Ị": [t: "CL⠠𝑐L⠊"] - - "Ó": [t: "CL⠔𝑐L⠕"] - - "Ò": [t: "CL⠰𝑐L⠕"] - - "Ỏ": [t: "CL⠢𝑐L⠕"] - - "Õ": [t: "CL⠤𝑐L⠕"] - - "Ọ": [t: "CL⠠𝑐L⠕"] - - "Ô": [t: "CL⠹"] - - "Ố": [t: "CL⠔𝑐L⠹"] - - "Ồ": [t: "CL⠰𝑐L⠹"] - - "Ổ": [t: "CL⠢𝑐L⠹"] - - "Ỗ": [t: "CL⠤𝑐L⠹"] - - "Ộ": [t: "CL⠠𝑐L⠹"] - - "Ơ": [t: "CL⠪"] - - "Ớ": [t: "CL⠔𝑐L⠪"] - - "Ờ": [t: "CL⠰𝑐L⠪"] - - "Ở": [t: "CL⠢𝑐L⠪"] - - "Ỡ": [t: "CL⠤𝑐L⠪"] - - "Ợ": [t: "CL⠠𝑐L⠪"] - - "Ú": [t: "CL⠔𝑐L⠥"] - - "Ù": [t: "CL⠰𝑐L⠥"] - - "Ủ": [t: "CL⠢𝑐L⠥"] - - "Ũ": [t: "CL⠤𝑐L⠥"] - - "Ụ": [t: "CL⠠𝑐L⠥"] - - "Ư": [t: "CL⠳"] - - "Ứ": [t: "CL⠔𝑐L⠳"] - - "Ừ": [t: "CL⠰𝑐L⠳"] - - "Ử": [t: "CL⠢𝑐L⠳"] - - "Ữ": [t: "CL⠤𝑐L⠳"] - - "Ự": [t: "CL⠠𝑐L⠳"] - - "Ý": [t: "CL⠔𝑐L⠽"] - - "Ỳ": [t: "CL⠰𝑐L⠽"] - - "Ỷ": [t: "CL⠢𝑐L⠽"] - - "Ỹ": [t: "CL⠤𝑐L⠽"] - - "Ỵ": [t: "CL⠠𝑐L⠽"] - - # Latin capitals: C + cells from lowercase a-z via spell/translate. - - "A-Z": # 0x41 - 0x5a - - tc: "C" - - spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" - - - "α": [t: "GL⠁"] # 0x3b1 - - "β": [t: "GL⠃"] # 0x3b2 - - "γ": [t: "GL⠛"] # 0x3b3 - - "δ": [t: "GL⠙"] # 0x3b4 - - "ε": [t: "GL⠑"] # 0x3b5 - - "ζ": [t: "GL⠵"] # 0x3b6 - - "η": [t: "GL⠱"] # 0x3b7 - - "θ": [t: "GL⠹"] # 0x3b8 - - "ι": [t: "GL⠊"] # 0x3b9 - - "κ": [t: "GL⠅"] # 0x3ba - - "λ": [t: "GL⠇"] # 0x3bb - - "μ": [t: "GL⠍"] # 0x3bc - - "ν": [t: "GL⠝"] # 0x3bd - - "ξ": [t: "GL⠭"] # 0x3be - - "ο": [t: "GL⠕"] # 0x3bf - - "π": [t: "GL⠏"] # 0x3c0 - - "ρ": [t: "GL⠗"] # 0x3c1 - - "ς": [t: "GL⠎"] # 0x3c2 - - "σ": [t: "GL⠎"] # 0x3c3 - - "τ": [t: "GL⠞"] # 0x3c4 - - "υ": [t: "GL⠥"] # 0x3c5 - - "φ": [T: "GL⠋"] # 0x3c6 - - "ϕ": [T: "GL⠋"] # 0x3c6 - - "χ": [T: "GL⠯"] # 0x3c7 - - "ψ": [t: "GL⠽"] # 0x3c8 - - "ω": [t: "GL⠺"] # 0x3c9 - - - "Α": [t: "CGL⠁"] # 0x391 - - "Β": [t: "CGL⠃"] # 0x392 - - "Γ": [t: "CGL⠛"] # 0x393 - - "Δ": [t: "CGL⠙"] # 0x394 - - "Ε": [t: "CGL⠑"] # 0x395 - - "Ζ": [t: "CGL⠵"] # 0x396 - - "Η": [t: "CGL⠱ "] # 0x397 - - "Θ": [t: "CGL⠹"] # 0x398 - - "Ι": [t: "CGL⠊"] # 0x399 - - "Κ": [t: "CGL⠅"] # 0x39a - - "Λ": [t: "CGL⠇"] # 0x39b - - "Μ": [t: "CGL⠍"] # 0x39c - - "Ν": [t: "CGL⠝"] # 0x39d - - "Ξ": [t: "CGL⠭"] # 0x39e - - "Ο": [t: "CGL⠕"] # 0x39f - - "Π": [t: "CGL⠏"] # 0x3a0 - - "Ρ": [t: "CGL⠗"] # 0x3a1 - - "΢": [t: "CGL⠎"] # 0x3a2 - - "Σ": [t: "CGL⠎"] # 0x3a3 - - "Τ": [t: "CGL⠞"] # 0x3a4 - - "Υ": [t: "CGL⠥"] # 0x3a5 - - "Φ": [t: "CGL⠋"] # 0x3a6 - - "Χ": [t: "CGL⠯"] # 0x3a7 - - "Ψ": [t: "CGL⠽"] # 0x3a8 - - "Ω": [T: "CGL⠺"] # 0x3a9 - - - "µ": [t: "GL⠍"] # 0x00B5 (Micro (Greek mu)) - - "Ω": [t: "CGL⠺"] # 0x2126 (Ohm sign (capital Greek omega)) - - "∆": [t: "CGL⠙"] # 0x2206 (Increment (capital Greek delta)) - - "∏": [t: "CGL⠏"] # 0x220F (Product (capital Greek pi)) - - "∑": [t: "CGL⠎"] # 0x2211 (Sum (capital Greek sigma)) - - -# Not yet defined symbols - - "‰": [T: "⠼⠚⠴⠴"] - - "≊": [T: "⠐⠢⠢⠶"] - - "⋮": [T: "⠣⠴⠜"] # 0x22ee (vertical ellipsis used to indicate dividable) - - "⧵": [T: "⠸⠡"] - - "∕": [T: "⠐⠲"] - - "⊘": [T: "⠐⠲"] - - "⁄": [T: "⠐⠲"] - - "℃": [T: "⠔⠚⠀⠨⠉"] - - "℉": [T: "⠔⠚⠀⠨⠋"] +--- +# Definitions for Vietnamese Math Braille. But most of theym are same as UEB. +# UEB characters +# +# Some chars that originally came from an Excel spreadsheet, converted to csv, and the greatly expanded +# +# The UEB translation makes use of some non-braille chars as flags +# L -- what follows is a letter +# N -- what follows is a digit +# C -- precedes L for capital letters +# G -- precedes L for Greek Letters (after C for capitals) +# Typeface Indicators ("typeforms") +# B bold, I Italic, S Sans-serif, T script, D, Fraktur, 𝔹 blackboard-bold +# the type face indicators can be combined with B (first) and I (second) +# Standing alone chars: +# Any character which acts as a standing alone character (e.g, "{") needs each braille symbol to be labeled +# o -- opening/left side, c -- closing/right side, b -- both open and close (e.g, '"') + + + - "=": [T: "⠐⠶"] # 0x003D (Equals) + - "≠": [T: "⠐⠾"] # 0x2260 (Not equal) + - "<": [T: "⠐⠪"] # 0x003C (Less than) + - "≤": [T: "⠐⠪⠶"] # 0x2264 (Less than or equal to) + - ">": [T: "⠐⠕"] # 0x003E (Greater than) + - "≥": [T: "⠐⠕⠶"] # 0x2265 (Greater than or equal to) + - "≪": [T: "⠐⠪⠪"] # 0x226A (Much less than) + - "≫": [T: "⠐⠕⠕"] # 0x226B (Much greater than) + - "≮": [T: "⠐⠪⠈"] # 0x226E (Not less than) + - "≯": [T: "⠐⠕⠈"] # 0x226F (Not greater than) + - "≰": [T: "⠸⠐⠪⠈⠐⠾"] # 0x2270 (Neither less than nor equal to) + - "≱": [T: "⠸⠐⠕⠈⠐⠾"] # 0x2271 (Neither greater than nor equal to) + - "∝": [t: "⠸⠐⠶"] # 0x221D (Proportional to) + - "≃": [T: "⠐⠢⠢"] # 0x2243 (Approximately equal to (tilde over horizontal line)) + - "≅": [T: "⠐⠢⠢"] # 0x2245 (Approximately equal to (tilde over equals sign)) + - "≈": [T: "⠐⠢⠢"] # 0x2248 (Approximately equal (tilde over tilde)) + - "≏": [t: "⠘⠐⠶"] # 0x224F (Equals with bump in top bar (difference between)) + - "≑": [t: "⠨⠐⠶"] # 0x2251 (Geometrically equal to (equals dotted above and below)) + - "≡": [T: "⠐⠿"] # 0x2261 (Equivalent to (three horizontal lines)) vi: trùng + - "≢": [T: "⠐⠿⠈"] # 0x2262 (Not identical to) + - "∈": [T: "⠈⠑"] # 0x2208 (Element of (member of)) + - "∉": [T: "⠈⠑⠈"] # 0x2209 (Element of (not member of)) + - "+": [T: "⠐⠖"] # 0x002B (Plus sign) + - "∋": [t: "⠈⠘⠑"] # 0x220B (Contains) + - "⊂": [T: "⠘⠣"] # 0x2282 (Subset of) + - "⊃": [T: "⠘⠜"] # 0x2283 (Superset of) + - "⊆": [T: "⠘⠣⠐⠶"] # 0x2286 (Subset of or equal) + - "⊇": [T: "⠘⠜⠐⠶"] # 0x2287 (Superset of or equal) + - "⊊": [t: "⠨⠘⠣"] # 0x228A (Subset of with not equal) + - "⊋": [t: "⠨⠘⠜"] # 0x228B (Superset of with not equal) + - "⊲": [t: "⠈⠸⠣"] # 0x22B2 (Normal subgroup of) + - "⊳": [t: "⠈⠸⠜"] # 0x22B3 (Contains as normal subgroup) + - "⊴": [t: "⠸⠸⠣"] # 0x22B4 (Normal subgroup of or equal) + - "⊵": [t: "⠸⠸⠜"] # 0x22B5 (Contains as normal subgroup or equal) + - "⋬": [t: "⠨⠸⠣"] # 0x22EC (not normal subgroup) -- this isn't the same as what is in GTM 10, but that similar has no Unicode equiv + - "⋭": [t: "⠨⠸⠣"] # 0x22ED (does not contain as normal subgroup) -- this isn't the same as what is in GTM 10, but that similar has no Unicode equiv + - "−": [t: "⠐⠤"] # 0x2212 (Minus sign) + - "·": [T: "⠐⠦"] # 0x00D7 (Multiplication dot (times)) + - "×": [T: "⠐⠦"] # 0x00D7 (Multiplication sign (times)) + - "÷": [T: "⠐⠲"] # 0x00F7 (Division sign (divided by)) + - "±": [T: "⠐⠖⠤"] # 0x00B1 (Plus or minus) + - "∓": [T: "⠐⠤⠖"] # 0x2213 (Minus or plus) + - "∗": [t: "⠐⠦"] # 0x2217 (Asterisk operator) + - "∘": [t: "⠐⠴"] # 0x2218 (Ring operator) + - "◦": [t: "⠐⠴"] # 0x25E6 (White bullet) + - "∼": [t: "⠈⠔"] # 0x223C (Tilde operator) + - "⋅": [t: "⠐⠦"] # 0x22C5 (Dot operator) + - "∧": [t: "⠈⠦"] # 0x2227 (Logical and) + - "∨": [t: "⠈⠖"] # 0x2228 (Logical or) + - "∩": [T: "⠨⠦"] # 0x2229 (Intersection) + - "∪": [T: "⠨⠖"] # 0x222A (Union) + - "∖": [T: "⠸⠡"] # 0x2216 (Set minus) + - "(": [T: "o⠈o⠣"] # 0x0028 (Left parenthesis) + - ")": [T: "c⠈c⠜"] # 0x0029 (Right parenthesis) + - "[": [T: "o⠨o⠣"] # 0x005B (Left square bracket) + - "]": [T: "c⠨c⠜"] # 0x005D (Right square bracket) + - "{": [T: "o⠸o⠣"] # 0x007B (Left curly bracket) + - "}": [T: "c⠸c⠜"] # 0x007D (Right curly bracket) + - "〈": [T: "o⠸⠣⠤"] # 0x2329 (Left angle bracket) + - "〉": [T: "c⠤⠸⠜"] # 0x232A (Right angle bracket) + - "|": [T: "⠸⠳"] # 0x007C (Vertical line) + # - test: + # if: "preceding-sibling::* and following-sibling::*" + # then: [T: "W⠸⠳W"] # comparison (e.g., such that -- rule 145) + # else: [T: "⠸⠳"] # absolute value, others??? + - "!": [T: "c⠖"] # 0x21 (Exclamation (factorial)) + - "#": [T: "⠼"] # 0x23 (Number sign (hash)) + - "%": [T: "⠼⠚⠴"] # 0x25 (Percent sign) No dots 46 before as in UEB + - "&": [t: "⠈⠯"] # 0x26 (Ampersand) + - "*": [T: "⠐⠦"] # 0x002A (Asterisk) + - "/": [T: "⠐⠲"] # 0x002F (Solidus (slash)) + - ";": [t: "c⠆"] # 0x003B (Semicolon) + - "?": [T: "c⠢"] # 0x003F (Question mark) + - "@": [T: "⠈⠁"] # 0x0040 (Commercial at sign) + - "\\": [t: "⠸⠡"] # 0x005C (Backslash) + - "^": [t: "⠈⠢"] # 0x005E (Caret (hat, up arrow)) + - "_": [t: "⠨⠤"] # 0x005F (Low line (underscore)) + - "~": [t: "⠈⠔"] # 0x007E (Tilde (swung dash)) + - "¢": [t: "⠈⠉"] # 0x00A2 (Cents sign) + - "€": [t: "⠈⠑"] # 0x20AC (Euro sign) + - "₣": [t: "⠈⠋"] # 0x20A3 (French franc sign) + - "£": [t: "⠈⠇"] # 0x00A3 (Pound sign) + - "₦": [t: "⠈⠝"] # 0x20A6 (Naira sign) + - "$": [t: "⠈⠎"] # 0x0024 (Dollar sign) + - "¥": [t: "⠈⠽"] # 0x00A5 (Yen sign) + - "¦": [t: "⠨⠳"] # 0x00A6 (Broken bar) + - "¬": [t: "⠈⠹"] # 0x00AC (Not sign) + - "°": [T: "⠔⠚"] # 0x00B0 (Degree sign) + - "†": [t: "⠈⠠⠹"] # 0x2020 (Dagger) + - "‡": [t: "⠈⠠⠻"] # 0x2021 (Double dagger) + - "…": [T: "c⠄c⠄c⠄"] # 0x2026 (Ellipsis) + - "′": [T: "⠄"] # 0x2032 (Prime sign) + - "″": [T: "⠄⠄"] # 0x2033 (Double prime sign) + - "‴": [T: "⠄⠄⠄"] # 0x2034 (Triple prime sign) + - "Å": [t: "⠠⠘⠫⠁"] # 0x212B (Angstrom symbol) + - "Å": [t: "⠠⠘⠫⠁"] # 0x00C5 (WIRIS uses this for Angstrom) + - "∀": [t: "⠘⠁"] # 0x2200 (For all) + - "∂": [t: "⠈⠙"] # 0x2202 (Partial differential) + - "∃": [T: "⠘⠑"] # 0x2203 (There exists) + - "∄": [T: "⠘⠑⠈"] # 0x2204 (There does not exist) + - "∅": [T: "⠈⠚"] # 0x2205 (Empty set) + - "∇": [t: "⠘⠙"] # 0x2207 (Nabla (del, inverted capital delta)) + - "∎": [t: "⠸⠫⠼⠙t"] # 0x220E (End of proof) + - "√": [T: "⠩"] # 0x221A (Square root (radical) without vinculum) + - "∞": [T: "⠼⠕"] # 0x221E (Infinity) + - "∠": [T: "⠫⠛"] # 0x2220 (Angle) + - "∡": [T: "⠨⠫⠛"] # 0x2221 (Measured angle) + - "⊾": [T: "⠼⠫⠛"] # 0x22BE (Right angle with arc) + - "∟": [T: "⠫⠧"] + - "∫": [T: "⠾"] # 0x222B (Integral) + - "∮": [T: "⠐⠾"] # 0x222E (Contour integral (closed line integral)) + - "∴": [t: "⠠⠡"] # 0x2234 (Therefore) + - "∵": [t: "⠈⠌"] # 0x2235 (Because (since)) + - "∶": [t: "⠒"] # 0x2236 (Ratio) + - "∷": [T: "⠒⠒"] # 0x2237 (Proportion) + - "∣": [T: "⠣⠴⠜"] # 0x2223 (Divides) ueb: ⠸⠳ + - "∤": [T: "⠣⠼⠜"] # 0x2224 (Does not divide) ueb: ⠸⠳⠈⠱ + - "∥": [T: "⠫⠶"] # 0x2225 (Parallel) VI: AB parallel to CD, should be: ⠫AB⠶CD + - "∦": [T: "⠫⠾"] # 0x2226 (Not parallel) Vi: AB not parallel to CD, should be: ⠫AB⠐⠾CD + - "⟂": [T: "⠫⠧"] # 0x27C2 (Perpendicular) + - "⊢": [t: "⠸⠒"] # 0x22a2 (Right tack) + - "⊣": [t: "⠈⠸⠒"] # 0x22a3 (Left tack) + - "⊥": [T: "⠫⠧"] # 0x22A5 (Up tack (perpendicular)) + - "⊦": [t: "⠸⠒"] # 0x22A6 (Assertion (is a theorem)) + - "⊨": [t: "⠘⠸⠒"] # 0x22A8 (TRUE (is valid)) + - "⊬": [t: "⠸⠒⠈⠱"] # 0x22AC (Does not prove) + - "⊭": [t: "⠘⠸⠒⠈⠱"] # 0x22AD (Not TRUE) + - "⫤": [t: "⠨⠸⠒"] # 0x2AE4 (Vertical bar double left turnstile) + - "✓": [t: "⠈⠩"] # 0x2713 (Check mark (tick)) + - "⦵": [t: "⠨⠚"] # 0x29B5 (Plimsoll sign (standard state)) + - "⮖": [t: "1⠐⠠⠤⠯⠫⠿"] # 0x2B96 (MEDIUM SMALL WHITE CIRCLE WITH HORIZONTAL BAR (standard state)) + - "←": [t: "⠳⠪"] # 0x2190 (Leftwards arrow) + - "↑": [t: "⠳⠬"] # 0x2191 (Upwards arrow) + - "→": [t: "⠳⠕"] # 0x2192 (Rightwards arrow) + - "↓": [t: "⠳⠩"] # 0x2193 (Downwards arrow) + - "↔": [T: "⠳⠪⠶⠕"] # 0x2194 (Left right arrow) + - "↕": [t: "⠳⠺⠗⠬"] # 0x2195 (Up down arrow) + - "↖": [t: "⠳⠱"] # 0x2196 (Northwest arrow) + - "↗": [t: "⠳⠎"] # 0x2197 (Northeast arrow) + - "↘": [t: "⠳⠣"] # 0x2198 (Southeast arrow) + - "↙": [t: "⠳⠜"] # 0x2199 (Southwest arrow) + - "↚": [t: "⠳⠪⠈⠱"] # 0x219A (Leftwards arrow with stroke) + - "↛": [t: "⠳⠕⠈⠱"] # 0x219B (Rightwards arrow with stroke) + - "↜": [t: "⠳⠔⠢⠪"] # 0x219C (Leftwards wave arrow) + - "↝": [t: "⠳⠢⠔⠕"] # 0x219D (Rightwards wave arrow) + - "↞": [t: "⠳⠒⠗⠗⠪"] # 0x219E (Leftwards two headed arrow) + - "↟": [t: "⠳⠒⠗⠗⠬"] # 0x219F (Upwards two headed arrow) + - "↠": [t: "⠳⠒⠗⠗⠕"] # 0x21A0 (Rightwards two headed arrow) + - "↡": [t: "⠳⠒⠗⠗⠩"] # 0x21A1 (Downwards two headed arrow) + - "↢": [t: "⠳⠗⠗⠪"] # 0x21A2 (Leftwards arrow with tail) + - "↣": [t: "⠳⠗⠗⠕"] # 0x21A3 (Rightwards arrow with tail) + - "↤": [t: "⠳⠳⠗⠪"] # 0x21A4 (Leftwards arrow from bar) + - "↥": [t: "⠳⠳⠗⠬"] # 0x21A5 (Upwards arrow from bar) + - "↦": [t: "⠳⠳⠗⠕"] # 0x21A6 (Rightwards arrow from bar) + - "↧": [t: "⠳⠳⠗⠩"] # 0x21A7 (Downwards arrow from bar) + - "↭": [t: "⠳⠺⠔⠢⠗⠕"] # 0x21AD (Left right wave arrow) + - "↮": [t: "⠳⠺⠗⠕⠈⠱"] # 0x21AE (Left right arrow with stroke) + - "↰": [t: "⠳⠴⠬"] # 0x21B0 (Upwards arrow with tip left) + - "↱": [t: "⠳⠲⠬"] # 0x21B1 (Upwards arrow with tip right) + - "↲": [t: "⠳⠲⠩"] # 0x21B2 (Downwards arrow with tip left) + - "↳": [t: "⠳⠴⠩"] # 0x21B3 (Downwards arrow with tip right) + - "↶": [t: "⠳⠔⠔⠪"] # 0x21B6 (Anticlockwise top semicircle arrow) + - "↷": [t: "⠳⠢⠢⠕"] # 0x21B7 (Clockwise top semicircle arrow) + - "↼": [t: "⠳⠈⠗⠪"] # 0x21BC (Leftwards harpoon with barb upwards) + - "↽": [t: "⠳⠠⠗⠪"] # 0x21BD (Leftwards harpoon with barb downwards) + - "↾": [t: "⠳⠠⠗⠬"] # 0x21BE (Upwards harpoon with barb rightwards) + - "↿": [t: "⠳⠈⠗⠬"] # 0x21BF (Upwards harpoon with barb leftwards) + - "⇀": [t: "⠳⠈⠗⠕"] # 0x21C0 (Rightwards harpoon with barb upwards) + - "⇁": [t: "⠳⠠⠗⠕"] # 0x21C1 (Rightwards harpoon with barb downwards) + - "⇂": [t: "⠳⠈⠗⠩"] # 0x21C2 (Downwards harpoon with barb rightwards) + - "⇃": [t: "⠳⠠⠗⠩"] # 0x21C3 (Downwards harpoon with barb leftwards) + - "⇄": [t: "⠳⠕⠻⠳⠪"] # 0x21C4 (Rightwards arrow over leftwards arrow) + - "⇅": [t: "⠳⠬⠿⠳⠩"] # 0x21C5 (Upwards arrow left of Downwards arrow) + - "⇌": [T: "⠳⠪⠕"] # 0x21CC (Rightwards harpoon over leftwards harpoon (equilibrium)) + - "⇐": [t: "⠳⠶⠪"] # 0x21D0 (Leftwards double arrow) + - "⇑": [t: "⠳⠶⠬"] # 0x21D1 (Upwards double arrow) + - "⇒": [t: "⠳⠶⠕"] # 0x21D2 (Rightwards double arrow) + - "⇓": [t: "⠳⠶⠩"] # 0x21D3 (Downwards double arrow) + - "⇔": [T: "⠳⠪⠶⠕"] # 0x21D4 (Left right double arrow) + - "⇕": [t: "⠳⠺⠶⠗⠬"] # 0x21D5 (Up down double arrow) + - "⇠": [t: "⠳⠂⠪"] # 0x21E0 (Leftwards dashed arrow) + - "⇡": [t: "⠳⠂⠬"] # 0x21E1 (Upwards dashed arrow) + - "⇢": [t: "⠳⠂⠕"] # 0x21E2 (Rightwards dashed arrow) + - "⇣": [t: "⠳⠂⠩"] # 0x21E3 (Downwards dashed arrow) + - "⟵": [t: "⠳⠪"] # 0x27F5 (Long leftwards arrow) + - "⟶": [t: "⠳⠕"] # 0x27F6 (Long rightwards arrow) + - "⥂": [t: "⠸⠶"] # 0x2942 (Rightwards arrow above short leftwards arrow (equilibrium, trend to the right)) + - "⥄": [t: "⠈⠸⠶"] # 0x2944 (Short rightwards arrow above leftwards arrow (equilibrium, trend to the left)) + +# Mappings for some new Unicode chemistry arrows/symbols +# These need to be verified -- 0x1f8d1, 0x1f8d2, and 0x1f8d3 conflict with GTM 16 (uses short arrow when really should be long) + - "🣐": [t: "⠳⠒⠒⠒⠕⠻⠳⠒⠒⠒⠪"] # 0x1F8D0 LONG RIGHTWARDS ARROW OVER LONG LEFTWARDS ARROW + - "🣑": [t: "⠳⠪⠕"] # 0x1f8d1 (Long rightwards harpoon over leftwards harpoon (equilibrium)) + - "🣒": [t: "⠸⠶"] # 0x1f8d2 (Long rightwards harpoon over leftwards harpoon (equilibrium, trend to the right)) + - "🣓": [t: "⠈⠸⠶"] # 0x1f8d3 (Long rightwards harpoon over leftwards harpoon (equilibrium, trend to the left)) +# - "🣑": [t: "⠳⠒⠒⠒⠈⠗⠕⠻⠳⠒⠒⠒⠠⠗⠪"] # 0x1F8D1 LONG RIGHTWARDS HARPOON OVER LONG LEFTWARDS HARPOON +# - "🣒": [t: "⠳⠒⠒⠒⠈⠗⠕⠻⠳⠒⠠⠗⠪"] # 0x1F8D2 LONG RIGHTWARDS HARPOON ABOVESHORT LEFTWARDS HARPOON +# - "🣓": [t: "⠳⠒⠈⠗⠕⠻⠳⠒⠒⠒⠠⠗⠪"] # 0x1F8D3 SHORT RIGHTWARDS HARPOON ABOVELONG LEFTWARDS HARPOON + - "🣔": [t: "⠳⠒⠒⠒⠈⠗⠪⠻⠳⠒⠠⠗⠕"] # 0x1F8D4 LONG LEFTWARDS HARPOON ABOVESHORT RIGHTWARDS HARPOON + - "🣕": [t: "⠳⠒⠈⠗⠪⠻⠳⠒⠒⠒⠠⠗⠕"] # 0x1F8D5 SHORT LEFTWARDS HARPOON ABOVELONG RIGHTWARDS HARPOON + - "🣖": [t: "⠳⠒⠒⠒⠕⠯⠠⠭"] # 0x1F8D6 LONG RIGHTWARDS ARROW WITH THROUGH X + - "🣗": [t: "⠐⠠⠤⠯⠫⠿"] # 0x1F8D7 LONG RIGHTWARDS ARROW WITH DOUBLE SLASH + + - "△": [T: "⠫⠼⠉"] # 0x25B3 (Triangle) + - "□": [T: "⠫⠼⠙"] # 0x25A1 (Square) + - "▤": [T: "⠨⠫⠼⠙"] # 0x25A4 (Square with horizontal fill) + - "▥": [T: "⠨⠫⠼⠙"] # 0x25A5 (Square with vertical fill) + - "▦": [T: "⠨⠫⠼⠙"] # 0x25A6 (Square with orthogonal crosshatch fill) + - "▧": [T: "⠨⠫⠼⠙"] # 0x25A7 (Square with upper left to lower right fill) + - "▨": [T: "⠨⠫⠼⠙"] # 0x25A8 (Square with upper right to lower left fill) + - "▩": [T: "⠨⠫⠼⠙"] # 0x25A9 (Square with diagonal crosshatch fill) + - "○": [t: "⠫⠿"] # 0x25CB (Circle) + - "◍": [T: "⠨⠫⠿"] # 0x25CD (Circle with vertical fill) + - "▱": [T: "⠫⠈⠼⠙"] # 0x25B1 (Parallelogram) + - "▲": [T: "⠸⠫⠼⠉"] # 0x25B2 (Filled triangle) + - "■": [T: "⠸⠫⠼⠙"] # 0x25A0 (Filled square) + - "≜": [T: "⠸⠙⠐⠶"] # 0x225C (Delta equal to) + - "≝": [t: "⠣⠙⠑⠋⠜⠻⠐⠶"] # 0x225D (Equal to by definition) + - "⊕": [t: "⠫⠿⠪⠐⠖t"] # 0x2295 (Circled plus) + - "⊖": [t: "⠫⠿⠪⠐⠤t"] # 0x2296 (Circled minus) + - "⊗": [t: "⠐⠦t"] # 0x2297 (Circled times) + - "⊛": [t: "⠐⠦t"] # 0x229B (Circled asterisk operator) + - "⊞": [t: "⠫⠼⠙⠪⠐⠖t"] # 0x229E (Squared plus) + - "⊟": [t: "⠫⠼⠙⠪⠐⠤t"] # 0x229F (Squared minus) + - "⊠": [t: "⠫⠼⠙⠪⠐⠦t"] # 0x22A0 (Squared times) + - "˙": [t: "⠲"] # 0x02D9 ( Dot Above) + - "¨": [t: "⠲⠲"] # 0x00A8 ( Diaeresis/Double Dot Above) + - "©": [t: "⠘⠉"] # 0xa9 (Copyright) + + + - "\"": [t: "b⠠b⠶"] + - "'": [t: "b⠄"] + - "“": [t: "o⠘o⠦"] + - "”": [t: "c⠘c⠴"] + - "‘": [t: "o⠠o⠦"] + - "’": [t: "c⠠c⠴"] + - "«": [t: "o⠸o⠦"] + - "»": [t: "c⠸c⠴"] + + - " ": # 0x20 (Space) + - test: + if: "self::m:mn" + then: [t: "N⠐"] + else: [t: "W"] + - " ": # 0xa0 (Non-breaking Space) + - test: + - if: "self::m:mn" + then: [t: "N⠐"] + - else_if: "following-sibling::*[1][@class='MathML-unit' or BaseNode(.)[@class='MathML-unit']]" + then: [t: "𝐖"] + else: [t: "W"] + - ",": # 0x2c (Comma) + - test: + if: "self::m:mn" + then: [t: "N⠂"] + else: [t: ",W"] + - ".": # 0x2e (Period) + - test: + if: "self::m:mn" + then: [T: "N⠄"] + else: [t: "."] + - ":": # 0x003A (Colon) + # Sometimes a colon is meant to be a ratio/mathord and sometimes a map/punct. + # The latter has a space after it. + # If in an mrow, guess it is infix and checks the operator. This is pretty weak! + # Field extensions "[K:F]" and trilinear coordinates "a:b:c" don't want extra space + # Time doesn't want an extra space -- the am/pm get wrapped in an mrow with the minutes after the colon + - test: + if: + - "ancestor::*[2][IsBracketed(., '{', '}')] or " # field extension + - "preceding-sibling::*[2][.=':'] or following-sibling::*[2][.=':'] or" # trilinear form + # ratios tend to have similar left and right sides + - "name(preceding-sibling::*[1]) = name(following-sibling::*[1]) or" + # am/pm test + - "(name(preceding-sibling::*[1]) = 'mn' and " + - " following-sibling::*[1][self::m:mrow and count(*)=3 and *[1][self::m:mn] and " + - " *[3][translate(., 'APM\u00A0', 'apm') = 'am' or translate(., 'APM\u00A0', 'apm') = 'pm']" + - " ])" + then: [t: "⠒"] + else: [t: "⠒W"] + + - "-": # 0x2d (Minus sign or hyphen) + - test: + if: "self::m:mo" + then: [t: "⠐⠤"] + else: [t: "⠤"] + + - "⁡": [t: ""] # 0x2061⁡ (invisible function apply) + #- test: + #if: + #- "preceding-sibling::*[1][self::m:mi and substring(., string-length(.), 1)!=' '] and " # avoid scripted function names and one that end with spaces + #- "following-sibling::*[1][self::m:mi and translate(., 'abcdefghijklmnopqrstuvwxyz', '') = '']" # GTM 9.3.2 + #then: [t: "W"] + #else: [t: ""] + + - "⁢": [t: ""] # 0x2062 (invisible times) + #- test: + #if: # GTM 9.3.3 (not very clear in rule, but the function name has to start with a lower case latin char ['no indicators']) + #- "parent::m:mrow and " + #- "preceding-sibling::*[1][" + #- " (self::m:mi and translate(., 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', '') = '') or " + #- " (self::m:mrow and translate(*[last()], 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', '') = '')] and" + #- " following::*[1][self::m:mrow and count(*)=3 and " # look for function apply + #- " *[2][.='⁡'] and *[1][self::m:mi and translate(., 'abcdefghijklmnopqrstuvwxyz', '') = '']]" + #then: [t: "W"] + #else: [t: ""] + - "⁣": [t: ""] # 0x2063⁡ (invisible separator) + - "⁤": [t: ""] # 0x2064 (invisible plus) + - "0": [t: "N⠚"] # 0x30 + - "1": [t: "N⠁"] # 0x31 + - "2": [t: "N⠃"] # 0x32 + - "3": [t: "N⠉"] # 0x33 + - "4": [t: "N⠙"] # 0x34 + - "5": [t: "N⠑"] # 0x35 + - "6": [t: "N⠋"] # 0x36 + - "7": [t: "N⠛"] # 0x37 + - "8": [t: "N⠓"] # 0x38 + - "9": [t: "N⠊"] # 0x39 + + # we stick the drop numbers into the private use area for consistency + - "\ue000": [t: "N⠴"] # 0 + - "\ue001": [t: "N⠂"] # 1 + - "\ue002": [t: "N⠆"] # 2 + - "\ue003": [t: "N⠒"] # 3 + - "\ue004": [t: "N⠲"] # 4 + - "\ue005": [t: "N⠢"] # 5 + - "\ue006": [t: "N⠖"] # 6 + - "\ue007": [t: "N⠶"] # 7 + - "\ue008": [t: "N⠦"] # 8 + - "\ue009": [t: "N⠔"] # 9 + + - "a": [t: "L⠁"] # 0x61 + - "b": [t: "L⠃"] # 0x62 + - "c": [t: "L⠉"] # 0x63 + - "d": [t: "L⠙"] # 0x64 + - "e": [t: "L⠑"] # 0x65 + - "f": [t: "L⠋"] # 0x66 + - "g": [t: "L⠛"] # 0x67 + - "h": [t: "L⠓"] # 0x68 + - "i": [t: "L⠊"] # 0x69 + - "j": [t: "L⠚"] # 0x6a + - "k": [t: "L⠅"] # 0x6b + - "l": [t: "L⠇"] # 0x6c + - "m": [t: "L⠍"] # 0x6d + - "n": [t: "L⠝"] # 0x6e + - "o": [t: "L⠕"] # 0x6f + - "p": [t: "L⠏"] # 0x70 + - "q": [t: "L⠟"] # 0x71 + - "r": [t: "L⠗"] # 0x72 + - "s": [t: "L⠎"] # 0x73 + - "t": [t: "L⠞"] # 0x74 + - "u": [t: "L⠥"] # 0x75 + - "v": [t: "L⠧"] # 0x76 + - "w": [t: "L⠺"] # 0x77 + - "x": [t: "L⠭"] # 0x78 + - "y": [t: "L⠽"] # 0x79 + - "z": [t: "L⠵"] # 0x7a + + - "đ": [t: "L⠮"] + - "á": [t: "L⠔L⠁"] + - "à": [t: "L⠰L⠁"] + - "ả": [t: "L⠢L⠁"] + - "ã": [t: "L⠤L⠁"] + - "ạ": [t: "L⠠L⠁"] + - "â": [t: "L⠡"] + - "ấ": [t: "L⠔L⠡"] + - "ầ": [t: "L⠰L⠡"] + - "ẩ": [t: "L⠢L⠡"] + - "ẫ": [t: "L⠤L⠡"] + - "ậ": [t: "L⠠L⠡"] + - "ă": [t: "L⠜"] + - "ắ": [t: "L⠔L⠜"] + - "ằ": [t: "L⠰L⠜"] + - "ẳ": [t: "L⠢L⠜"] + - "ẵ": [t: "L⠤L⠜"] + - "ặ": [t: "L⠠L⠜"] + - "é": [t: "L⠔L⠑"] + - "è": [t: "L⠰L⠑"] + - "ẻ": [t: "L⠢L⠑"] + - "ẽ": [t: "L⠤L⠑"] + - "ẹ": [t: "L⠠L⠑"] + - "ê": [t: "L⠣"] + - "ế": [t: "L⠔L⠣"] + - "ề": [t: "L⠰L⠣"] + - "ể": [t: "L⠢L⠣"] + - "ễ": [t: "L⠤L⠣"] + - "ệ": [t: "L⠠L⠣"] + - "í": [t: "L⠔L⠊"] + - "ì": [t: "L⠰L⠊"] + - "ỉ": [t: "L⠢L⠊"] + - "ĩ": [t: "L⠤L⠊"] + - "ị": [t: "L⠠L⠊"] + - "ó": [t: "L⠔L⠕"] + - "ò": [t: "L⠰L⠕"] + - "ỏ": [t: "L⠢L⠕"] + - "õ": [t: "L⠤L⠕"] + - "ọ": [t: "L⠠L⠕"] + - "ô": [t: "L⠹"] + - "ố": [t: "L⠔L⠹"] + - "ồ": [t: "L⠰L⠹"] + - "ổ": [t: "L⠢L⠹"] + - "ỗ": [t: "L⠤L⠹"] + - "ộ": [t: "L⠠L⠹"] + - "ơ": [t: "L⠪"] + - "ớ": [t: "L⠔L⠪"] + - "ờ": [t: "L⠰L⠪"] + - "ở": [t: "L⠢L⠪"] + - "ỡ": [t: "L⠤L⠪"] + - "ợ": [t: "L⠠L⠪"] + - "ú": [t: "L⠔L⠥"] + - "ù": [t: "L⠰L⠥"] + - "ủ": [t: "L⠢L⠥"] + - "ũ": [t: "L⠤L⠥"] + - "ụ": [t: "L⠠L⠥"] + - "ư": [t: "L⠳"] + - "ứ": [t: "L⠔L⠳"] + - "ừ": [t: "L⠰L⠳"] + - "ử": [t: "L⠢L⠳"] + - "ữ": [t: "L⠤L⠳"] + - "ự": [t: "L⠠L⠳"] + - "ý": [t: "L⠔L⠽"] + - "ỳ": [t: "L⠰L⠽"] + - "ỷ": [t: "L⠢L⠽"] + - "ỹ": [t: "L⠤L⠽"] + - "ỵ": [t: "L⠠L⠽"] + + - "Đ": [t: "CL⠮"] + - "Á": [t: "CL⠔𝑐L⠁"] + - "À": [t: "CL⠰𝑐L⠁"] + - "Ả": [t: "CL⠢𝑐L⠁"] + - "Ã": [t: "CL⠤𝑐L⠁"] + - "Ạ": [t: "CL⠠𝑐L⠁"] + - "Â": [t: "CL⠡"] + - "Ấ": [t: "CL⠔𝑐L⠡"] + - "Ầ": [t: "CL⠰𝑐L⠡"] + - "Ẩ": [t: "CL⠢𝑐L⠡"] + - "Ẫ": [t: "CL⠤𝑐L⠡"] + - "Ậ": [t: "CL⠠𝑐L⠡"] + - "Ă": [t: "CL⠜"] + - "Ắ": [t: "CL⠔𝑐L⠜"] + - "Ằ": [t: "CL⠰𝑐L⠜"] + - "Ẳ": [t: "CL⠢𝑐L⠜"] + - "Ẵ": [t: "CL⠤𝑐L⠜"] + - "Ặ": [t: "CL⠠𝑐L⠜"] + - "É": [t: "CL⠔𝑐L⠑"] + - "È": [t: "CL⠰𝑐L⠑"] + - "Ẻ": [t: "CL⠢𝑐L⠑"] + - "Ẽ": [t: "CL⠤𝑐L⠑"] + - "Ẹ": [t: "CL⠠𝑐L⠑"] + - "Ê": [t: "CL⠣"] + - "Ế": [t: "CL⠔𝑐L⠣"] + - "Ề": [t: "CL⠰𝑐L⠣"] + - "Ể": [t: "CL⠢𝑐L⠣"] + - "Ễ": [t: "CL⠤𝑐L⠣"] + - "Ệ": [t: "CL⠠𝑐L⠣"] + - "Í": [t: "CL⠔𝑐L⠊"] + - "Ì": [t: "CL⠰𝑐L⠊"] + - "Ỉ": [t: "CL⠢𝑐L⠊"] + - "Ĩ": [t: "CL⠤𝑐L⠊"] + - "Ị": [t: "CL⠠𝑐L⠊"] + - "Ó": [t: "CL⠔𝑐L⠕"] + - "Ò": [t: "CL⠰𝑐L⠕"] + - "Ỏ": [t: "CL⠢𝑐L⠕"] + - "Õ": [t: "CL⠤𝑐L⠕"] + - "Ọ": [t: "CL⠠𝑐L⠕"] + - "Ô": [t: "CL⠹"] + - "Ố": [t: "CL⠔𝑐L⠹"] + - "Ồ": [t: "CL⠰𝑐L⠹"] + - "Ổ": [t: "CL⠢𝑐L⠹"] + - "Ỗ": [t: "CL⠤𝑐L⠹"] + - "Ộ": [t: "CL⠠𝑐L⠹"] + - "Ơ": [t: "CL⠪"] + - "Ớ": [t: "CL⠔𝑐L⠪"] + - "Ờ": [t: "CL⠰𝑐L⠪"] + - "Ở": [t: "CL⠢𝑐L⠪"] + - "Ỡ": [t: "CL⠤𝑐L⠪"] + - "Ợ": [t: "CL⠠𝑐L⠪"] + - "Ú": [t: "CL⠔𝑐L⠥"] + - "Ù": [t: "CL⠰𝑐L⠥"] + - "Ủ": [t: "CL⠢𝑐L⠥"] + - "Ũ": [t: "CL⠤𝑐L⠥"] + - "Ụ": [t: "CL⠠𝑐L⠥"] + - "Ư": [t: "CL⠳"] + - "Ứ": [t: "CL⠔𝑐L⠳"] + - "Ừ": [t: "CL⠰𝑐L⠳"] + - "Ử": [t: "CL⠢𝑐L⠳"] + - "Ữ": [t: "CL⠤𝑐L⠳"] + - "Ự": [t: "CL⠠𝑐L⠳"] + - "Ý": [t: "CL⠔𝑐L⠽"] + - "Ỳ": [t: "CL⠰𝑐L⠽"] + - "Ỷ": [t: "CL⠢𝑐L⠽"] + - "Ỹ": [t: "CL⠤𝑐L⠽"] + - "Ỵ": [t: "CL⠠𝑐L⠽"] + + # Latin capitals: C + cells from lowercase a-z via spell/translate. + - "A-Z": # 0x41 - 0x5a + - tc: "C" + - spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" + + - "α": [t: "GL⠁"] # 0x3b1 + - "β": [t: "GL⠃"] # 0x3b2 + - "γ": [t: "GL⠛"] # 0x3b3 + - "δ": [t: "GL⠙"] # 0x3b4 + - "ε": [t: "GL⠑"] # 0x3b5 + - "ζ": [t: "GL⠵"] # 0x3b6 + - "η": [t: "GL⠱"] # 0x3b7 + - "θ": [t: "GL⠹"] # 0x3b8 + - "ι": [t: "GL⠊"] # 0x3b9 + - "κ": [t: "GL⠅"] # 0x3ba + - "λ": [t: "GL⠇"] # 0x3bb + - "μ": [t: "GL⠍"] # 0x3bc + - "ν": [t: "GL⠝"] # 0x3bd + - "ξ": [t: "GL⠭"] # 0x3be + - "ο": [t: "GL⠕"] # 0x3bf + - "π": [t: "GL⠏"] # 0x3c0 + - "ρ": [t: "GL⠗"] # 0x3c1 + - "ς": [t: "GL⠎"] # 0x3c2 + - "σ": [t: "GL⠎"] # 0x3c3 + - "τ": [t: "GL⠞"] # 0x3c4 + - "υ": [t: "GL⠥"] # 0x3c5 + - "φ": [T: "GL⠋"] # 0x3c6 + - "ϕ": [T: "GL⠋"] # 0x3c6 + - "χ": [T: "GL⠯"] # 0x3c7 + - "ψ": [t: "GL⠽"] # 0x3c8 + - "ω": [t: "GL⠺"] # 0x3c9 + + - "Α": [t: "CGL⠁"] # 0x391 + - "Β": [t: "CGL⠃"] # 0x392 + - "Γ": [t: "CGL⠛"] # 0x393 + - "Δ": [t: "CGL⠙"] # 0x394 + - "Ε": [t: "CGL⠑"] # 0x395 + - "Ζ": [t: "CGL⠵"] # 0x396 + - "Η": [t: "CGL⠱ "] # 0x397 + - "Θ": [t: "CGL⠹"] # 0x398 + - "Ι": [t: "CGL⠊"] # 0x399 + - "Κ": [t: "CGL⠅"] # 0x39a + - "Λ": [t: "CGL⠇"] # 0x39b + - "Μ": [t: "CGL⠍"] # 0x39c + - "Ν": [t: "CGL⠝"] # 0x39d + - "Ξ": [t: "CGL⠭"] # 0x39e + - "Ο": [t: "CGL⠕"] # 0x39f + - "Π": [t: "CGL⠏"] # 0x3a0 + - "Ρ": [t: "CGL⠗"] # 0x3a1 + - "΢": [t: "CGL⠎"] # 0x3a2 + - "Σ": [t: "CGL⠎"] # 0x3a3 + - "Τ": [t: "CGL⠞"] # 0x3a4 + - "Υ": [t: "CGL⠥"] # 0x3a5 + - "Φ": [t: "CGL⠋"] # 0x3a6 + - "Χ": [t: "CGL⠯"] # 0x3a7 + - "Ψ": [t: "CGL⠽"] # 0x3a8 + - "Ω": [T: "CGL⠺"] # 0x3a9 + + - "µ": [t: "GL⠍"] # 0x00B5 (Micro (Greek mu)) + - "Ω": [t: "CGL⠺"] # 0x2126 (Ohm sign (capital Greek omega)) + - "∆": [t: "CGL⠙"] # 0x2206 (Increment (capital Greek delta)) + - "∏": [t: "CGL⠏"] # 0x220F (Product (capital Greek pi)) + - "∑": [t: "CGL⠎"] # 0x2211 (Sum (capital Greek sigma)) + + +# Not yet defined symbols + - "‰": [T: "⠼⠚⠴⠴"] + - "≊": [T: "⠐⠢⠢⠶"] + - "⋮": [T: "⠣⠴⠜"] # 0x22ee (vertical ellipsis used to indicate dividable) + - "⧵": [T: "⠸⠡"] + - "∕": [T: "⠐⠲"] + - "⊘": [T: "⠐⠲"] + - "⁄": [T: "⠐⠲"] + - "℃": [T: "⠔⠚⠀⠨⠉"] + - "℉": [T: "⠔⠚⠀⠨⠋"] diff --git a/Rules/Languages/en/unicode.yaml b/Rules/Languages/en/unicode.yaml index 0a6b6b3b8..f9b39fb2e 100644 --- a/Rules/Languages/en/unicode.yaml +++ b/Rules/Languages/en/unicode.yaml @@ -1,534 +1,534 @@ ---- - # Note to translators: - # most languages don't have two ways to pronounce 'a' -- if not need, remove the rules and change "B-Z" to "A-Z" - # some languages say the word for "uppercase" after the letter. Make sure to change that where appropriate by moving some code around - - "a": - - test: - if: "$TTS='none'" - then: [t: "eigh"] # long "a" sound in all speech engines I tested (espeak, MS SAPI, eloquence, - else: [spell: "'a'"] # AWS Polly, ReadSpeaker, NaturalReader, google cloud, nuance, ibm watson) - - "b-z": - - test: - if: "$TTS='none'" - then: [t: "."] - else: [spell: "'.'"] - - # Capital letters are a little tricky: users can pick their favorite word (something that was requested) and - # screen readers have options to use pitch changes or beeps instead of or in addition to say "cap" - # Also, if a user can see the screen, they probably don't need to hear "cap", but if they specified an override, they must want to hear the override. - - - "A": - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [t: "cap"] - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: - - test: - if: "$TTS='none'" - then: [t: "eigh"] - else: [spell: "'a'"] - - - "B-Z": - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [t: "cap"] - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [spell: "translate('.', 'BCDEFGHIJKLMNOPQRSTUVWXYZ', 'bcdefghijklmnopqrstuvwxyz')"] - - - "0-9": [t: "."] - - - " ": [t: " "] # 0x20 - - - "!": # 0x21 - - test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then_test: - if: "$Verbosity = 'Terse'" - then: [t: "bang"] # 0x21 - else: [t: "exclamation point"] # 0x21 - else: [t: "factorial"] # 0x21 - - - "\"": [t: "quotation mark"] # 0x22 - - "#": [t: "number"] # 0x23 - - "$": [t: "dollars"] # 0x24 - - "%": [t: "percent"] # 0x25 - - "&": [t: "ampersand"] # 0x26 - - "'": [t: "apostrophe"] # 0x27 - - "(": # 0x28 - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then_test: - if: "$Verbosity='Terse'" - then: [t: "open"] # 0x28 - else: [t: "open paren"] # 0x28 - else: [t: "left paren"] # 0x28 - - ")": # 0x29 - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then_test: - if: "$Verbosity='Terse'" - then: [t: "close"] # 0x29 - else: [t: "close paren"] # 0x29 - else: [t: "right paren"] # 0x29 - - - "*": # 0x2a - test: - if: "parent::*[name(.)='msup' or name(.)='msubsup' or name(.)='skip-super']" - then: [t: "star"] # 0x2a - else: [t: "times"] # 0x2a - - "+": [t: "plus"] # 0x2b - - ",": # 0x2c - # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent - # that this test is here and not with "…" is not ideal, but seems simplest - test: - if: - - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " - # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' - # speak "comma" when not adjacent to '…' - - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " - # except if expression starts with '…' - - "../*[1][.='…'] " - then: - - T: "comma" # (en: 'comma', google translation) - - test: - if: "$Verbosity != Terse" - then: [pause: short] - # else silent - - - "-": [t: "minus"] # 0x2d - - ".": # 0x2e - - test: - if: "parent::*[1][self::m:mn]" - then: [t: "point"] - else: [t: "dot"] - - "/": # 0x2f - - test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [t: "slash"] # 0x2f - else: [t: "divided by"] # 0x2f - - - ":": [t: "colon"] # 0x3a - - ";": [t: "semicolon"] # 0x3b - - "<": # 0x3c - - test: - if: "$Verbosity!='Terse'" - then: [t: "is"] - - t: "less than" - - "=": # 0x3d - - test: - if: "$Verbosity!='Terse'" - then: [t: "is equal to"] - else: [t: "equals"] - - - ">": # 0x3e - - test: - if: "$Verbosity!='Terse'" - then: [t: "is"] - - t: "greater than" - - "?": [t: "question mark"] # 0x3f - - "@": [t: "at sign"] # 0x40 - - "[": # 0x5b - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [t: "open bracket"] - else: [t: "left bracket"] - - "\\": [t: "back slash"] # 0x5c - - "]": # 0x5d - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [t: "close bracket"] - else: [t: "right bracket"] - - "^": # 0x5e - - test: - if: "parent::m:modified-variable or parent::m:mover" - then: [t: "hat"] - else: [t: "caret"] - - "_": [t: "under bar"] # 0x5f - - "`": [t: "grave"] # 0x60 - - "{": # 0x7b - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [t: "open brace"] - else: [t: "left brace"] - - "|": # 0x7c - # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' - - with: - variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) - replace: - - test: - - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [t: "vertical line"] - - else_if: "$SpeechStyle != 'ClearSpeak'" - then_test: - - if: "$DefaultToGiven" - then: [t: "given"] - - else_if: "preceding-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))] and - following-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))]" - then: [t: "divides"] - else: [t: "vertical line"] - - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" - then: [t: "vertical line"] - - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" - then: [t: "such that"] - - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" - then: [t: "given"] - - else: [t: "divides"] - - - "}": # 0x7d - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [t: "close brace"] - else: [t: "right brace"] - - - "~": [t: "tilde"] # 0x7e - - " ": # 0xa0 - - test: - # could be mtext in mtd or mtext in an mrow that is a concatenation of mtd's. Is there a better solution? - if: "@data-empty-in-2D and not(ancestor::*[self::m:piecewise or self::m:system-of-equations or self::m:lines])" - then: [t: "empty"] # want to say something for fraction (etc) with empty child - else: [t: ""] - - - "¬": [t: "not"] # 0xac - - "°": [t: "degrees"] # 0xb0 - - "±": [t: "plus or minus"] # 0xb1 - - "´": [t: "acute"] # 0xb4 - - "·": # 0xB7 - - test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')] or not($SpeechStyle = 'ClearSpeak' and $ClearSpeak_MultSymbolDot = 'Auto')" - then: [t: "dot"] - else: [t: "times"] - - "×": # 0xd7 - - test: - if: "$SpeechStyle = 'ClearSpeak'" - then_test: - - if: "$ClearSpeak_MultSymbolX = 'Auto'" - then: [t: "times"] - - else_if: "$ClearSpeak_MultSymbolX = 'By'" - then: [t: "by"] - else: [t: "cross"] - else_test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [t: "cross"] - else: [t: "times"] - - - "÷": [t: "divided by"] # 0xf7 - - "̀": [t: "grave accent embellishment"] # 0x300 - - "́": [t: "acute accent embellishment"] # 0x301 - - "̂": [t: "circumflex accent embellishment"] # 0x302 - - "̃": [t: "tilde embellishment"] # 0x303 - - "̄": [t: "macron embellishment"] # 0x304 - - "̅": [t: "overbar embellishment"] # 0x305 - - "̆": [t: "breve"] # 0x306 - - "̇": [t: "dot above embellishment"] # 0x307 - - # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong - - "Α-Ω": - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [t: "cap"] - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [spell: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] - - - "α": [t: "alpha"] # 0x3b1 - - "β": [t: "beta"] # 0x3b2 - - "γ": [t: "gamma"] # 0x3b3 - - "δ": [t: "delta"] # 0x3b4 - - "ε": [t: "epsilon"] # 0x3b5 - - "ζ": [t: "zeta"] # 0x3b6 - - "η": [t: "eta"] # 0x3b7 - - "θ": [t: "theta"] # 0x3b8 - - "ι": [t: "iota"] # 0x3b9 - - "κ": [t: "kappa"] # 0x3ba - - "λ": [t: "lambda"] # 0x3bb - - "μ": [t: "mu"] # 0x3bc - - "ν": [t: "nu"] # 0x3bd - - "ξ": [t: "zai"] # 0x3be - - "ο": [t: "omicron"] # 0x3bf - - "π": [t: "pi"] # 0x3c0 - - "ρ": [t: "rho"] # 0x3c1 - - "ς": [t: "final sigma"] # 0x3c2 - - "σ": [t: "sigma"] # 0x3c3 - - "τ": [t: "tau"] # 0x3c4 - - "υ": [t: "upsilon"] # 0x3c5 - - "φ": [t: "phi"] # 0x3c6 - - "χ": [t: "chi"] # 0x3c7 - - "ψ": [t: "psi"] # 0x3c8 - - "ω": [t: "omega"] # 0x3c9 - - "ϕ": [t: "phi"] # 0x3d5 - - "ϖ": [t: "pi"] # 0x3d6 - - "ϵ": [t: "epsilon"] # 0x3f5 - - "϶": [t: "reversed epsilon"] # 0x3f6 - - - "⁡": # 0x2061 - - test: - # skip saying "of" when Terse and a trig function, when it is a shape (does this happen?), or we are in :literal mode - if: "not( - ( $Verbosity='Terse' or ($SpeechStyle = 'ClearSpeak' and IsNode(following-sibling::*[1],'simple')) and - preceding-sibling::*[1][IfThenElse($SpeechStyle='ClearSpeak', - IsInDefinition(., 'ClearSpeakTrigFunctionNames'), - IsInDefinition(., 'TrigFunctionNames') )] - ) or - preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')] or - (@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) - )" - then: [t: "of"] - - "⁢": [t: ""] # 0x2062 - - "⁣": [t: ""] # 0x2063 - - "⁤": [t: "and"] # 0x2064 - - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" - - t: "double-struck" - - spell: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" - - - "℃": [t: "degrees celsius"] # 0x2103 - - "ℋℛℓ": # 0x210b - - t: "script" - - spell: "translate('.', 'ℋℛℓ', 'HRl')" - - "ℜ": # 0x211c - - t: "fraktur" - - spell: "'R'" - - - "ⅆⅇⅈⅉ": # 0x2146-9 - - t: "double-struck italic" - - spell: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" - - - "←": [t: "left arrow"] # 0x2190 - - "↑": [t: "up arrow"] # 0x2191 - - "→": # 0x2192 - - test: - if: "ancestor::*[2][self::m:limit]" - then: [t: "approaches"] - else: [t: "right arrow"] - - - "↓": [t: "down arrow"] # 0x2193 - - "∈": # 0x2208 - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: - - test: - if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" - then: [t: "is"] - - t: "an element of" - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "in"] - - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "member of"] - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "element of"] - - else: [t: "belonging to"] # $ClearSpeak_SetMemberSymbol = 'Belongs' - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "is a member of"] - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "is an element of"] - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "is in"] - - else: [t: "belongs to"] # $ClearSpeak_SetMemberSymbol = 'Belongs' - - "∥": # 0x2225 - - test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [t: "double vertical line"] - else: - - test: - if: "$Verbosity!='Terse'" - then: [t: "is"] - - t: "parallel to" - - "∦": # 0x2226 - - test: - if: "$Verbosity!='Terse'" - then: [t: "is"] - - t: "not parallel to" - - "≤": # 0x2264 - - test: - if: "$Verbosity!='Terse'" - then: [t: "is"] - - t: "less than or equal to" - - "≥": # 0x2265 - - test: - if: "$Verbosity!='Terse'" - then: [t: "is"] - - t: "greater than or equal to" - - # --- restored complex short definitions (prefer over unicode-full) --- - - "…": # 0x2026 - test: - if: - - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" - # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' - # speak '…' as 'and so on...' unless expr starts with '…' - - "../*[1][.='…']" - then: [t: "dot dot dot"] - else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' - if: "count(following-sibling::*) = 0" - then: [t: "and so on"] - else: [t: "and so on up to"] - - "∂": # 0x2202 - - test: - if: "$Verbosity='Terse'" - then: [t: "partial"] - else: [t: "partial derivative"] - - "∆": # 0x2206 - - test: - if: "$Verbosity!='Terse'" - then: [ot: "the"] - - t: "laplacian of" - - "∉": # 0x2209 - # rule is identical to 0x2208 - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: - - test: - if: "$Verbosity!='Terse'" - then: [t: "is"] - - t: "not an element of" - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "not in"] - - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "not member of"] - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "not element of"] - - else: [t: "not belonging to"] # $ClearSpeak_SetMemberSymbol = 'Belongs' - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "is not a member of"] - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "is not an element of"] - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "is not in"] - - else: [t: "does not belong to"] # $ClearSpeak_SetMemberSymbol = 'Belongs' - - "∊": # 0x220a - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: - - test: - if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" - then: [t: "is"] - - t: "an element of" - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "in"] - - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "member of"] - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "element of"] - - else: [t: "belonging to"] # $ClearSpeak_SetMemberSymbol = 'Belongs' - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "is a member of"] - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "is an element of"] - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "is in"] - - else: [t: "belongs to"] # $ClearSpeak_SetMemberSymbol = 'Belongs' - - "√": # 0x221a - - test: - if: "$Verbosity!='Terse'" - then: [ot: "the"] - - t: "square root of" - - "∝": # 0x221d - - test: - if: "$Verbosity!='Terse'" - then: [t: "is"] - - t: "proportional to" - - "∶": # 0x2236 - - test: - if: "$Verbosity!='Terse'" - then: [t: "is"] - - t: "to" - - "∾": # 0x223e - - test: - if: "$Verbosity!='Terse'" - then: [t: "is"] - - t: "most positive" - - "≠": # 0x2260 - - test: - if: "$Verbosity!='Terse'" - then: [t: "is"] - - t: "not equal to" - - "≡": # 0x2261 - - test: - if: "$Verbosity!='Terse'" - then: [t: "is"] - - t: "identical to" - - "⊂": # 0x2282 - - test: - if: "$Verbosity!='Terse'" - then: [t: "is a"] - - t: "subset of" - - "⊃": # 0x2283 - - test: - if: "$Verbosity!='Terse'" - then: [t: "is a"] - - t: "superset of" - - "⊄": # 0x2284 - - test: - if: "$Verbosity!='Terse'" - then: [t: "is"] - - t: "not a subset of" - - "⊅": # 0x2285 - - test: - if: "$Verbosity!='Terse'" - then: [t: "is"] - - t: "not a superset of" - - "⊆": # 0x2286 - - test: - if: "$Verbosity!='Terse'" - then: [t: "is a"] - - t: "subset of or equal to" - - "⊇": # 0x2287 - - test: - if: "$Verbosity!='Terse'" - then: [t: "is a"] - - t: "superset of or equal to" - - # --- restored short definitions that differ from unicode-full --- - - "⇒": [t: "right double arrow"] # 0x21d2 - - "∐": [t: "co-product"] # 0x2210 +--- + # Note to translators: + # most languages don't have two ways to pronounce 'a' -- if not need, remove the rules and change "B-Z" to "A-Z" + # some languages say the word for "uppercase" after the letter. Make sure to change that where appropriate by moving some code around + - "a": + - test: + if: "$TTS='none'" + then: [t: "eigh"] # long "a" sound in all speech engines I tested (espeak, MS SAPI, eloquence, + else: [spell: "'a'"] # AWS Polly, ReadSpeaker, NaturalReader, google cloud, nuance, ibm watson) + - "b-z": + - test: + if: "$TTS='none'" + then: [t: "."] + else: [spell: "'.'"] + + # Capital letters are a little tricky: users can pick their favorite word (something that was requested) and + # screen readers have options to use pitch changes or beeps instead of or in addition to say "cap" + # Also, if a user can see the screen, they probably don't need to hear "cap", but if they specified an override, they must want to hear the override. + + - "A": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [t: "cap"] + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: + - test: + if: "$TTS='none'" + then: [t: "eigh"] + else: [spell: "'a'"] + + - "B-Z": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [t: "cap"] + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [spell: "translate('.', 'BCDEFGHIJKLMNOPQRSTUVWXYZ', 'bcdefghijklmnopqrstuvwxyz')"] + + - "0-9": [t: "."] + + - " ": [t: " "] # 0x20 + + - "!": # 0x21 + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then_test: + if: "$Verbosity = 'Terse'" + then: [t: "bang"] # 0x21 + else: [t: "exclamation point"] # 0x21 + else: [t: "factorial"] # 0x21 + + - "\"": [t: "quotation mark"] # 0x22 + - "#": [t: "number"] # 0x23 + - "$": [t: "dollars"] # 0x24 + - "%": [t: "percent"] # 0x25 + - "&": [t: "ampersand"] # 0x26 + - "'": [t: "apostrophe"] # 0x27 + - "(": # 0x28 + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [t: "open"] # 0x28 + else: [t: "open paren"] # 0x28 + else: [t: "left paren"] # 0x28 + - ")": # 0x29 + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [t: "close"] # 0x29 + else: [t: "close paren"] # 0x29 + else: [t: "right paren"] # 0x29 + + - "*": # 0x2a + test: + if: "parent::*[name(.)='msup' or name(.)='msubsup' or name(.)='skip-super']" + then: [t: "star"] # 0x2a + else: [t: "times"] # 0x2a + - "+": [t: "plus"] # 0x2b + - ",": # 0x2c + # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent + # that this test is here and not with "…" is not ideal, but seems simplest + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak "comma" when not adjacent to '…' + - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " + # except if expression starts with '…' + - "../*[1][.='…'] " + then: + - T: "comma" # (en: 'comma', google translation) + - test: + if: "$Verbosity != Terse" + then: [pause: short] + # else silent + + - "-": [t: "minus"] # 0x2d + - ".": # 0x2e + - test: + if: "parent::*[1][self::m:mn]" + then: [t: "point"] + else: [t: "dot"] + - "/": # 0x2f + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [t: "slash"] # 0x2f + else: [t: "divided by"] # 0x2f + + - ":": [t: "colon"] # 0x3a + - ";": [t: "semicolon"] # 0x3b + - "<": # 0x3c + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "less than" + - "=": # 0x3d + - test: + if: "$Verbosity!='Terse'" + then: [t: "is equal to"] + else: [t: "equals"] + + - ">": # 0x3e + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "greater than" + - "?": [t: "question mark"] # 0x3f + - "@": [t: "at sign"] # 0x40 + - "[": # 0x5b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [t: "open bracket"] + else: [t: "left bracket"] + - "\\": [t: "back slash"] # 0x5c + - "]": # 0x5d + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [t: "close bracket"] + else: [t: "right bracket"] + - "^": # 0x5e + - test: + if: "parent::m:modified-variable or parent::m:mover" + then: [t: "hat"] + else: [t: "caret"] + - "_": [t: "under bar"] # 0x5f + - "`": [t: "grave"] # 0x60 + - "{": # 0x7b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [t: "open brace"] + else: [t: "left brace"] + - "|": # 0x7c + # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' + - with: + variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) + replace: + - test: + - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [t: "vertical line"] + - else_if: "$SpeechStyle != 'ClearSpeak'" + then_test: + - if: "$DefaultToGiven" + then: [t: "given"] + - else_if: "preceding-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))] and + following-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))]" + then: [t: "divides"] + else: [t: "vertical line"] + - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" + then: [t: "vertical line"] + - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" + then: [t: "such that"] + - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" + then: [t: "given"] + - else: [t: "divides"] + + - "}": # 0x7d + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [t: "close brace"] + else: [t: "right brace"] + + - "~": [t: "tilde"] # 0x7e + - " ": # 0xa0 + - test: + # could be mtext in mtd or mtext in an mrow that is a concatenation of mtd's. Is there a better solution? + if: "@data-empty-in-2D and not(ancestor::*[self::m:piecewise or self::m:system-of-equations or self::m:lines])" + then: [t: "empty"] # want to say something for fraction (etc) with empty child + else: [t: ""] + + - "¬": [t: "not"] # 0xac + - "°": [t: "degrees"] # 0xb0 + - "±": [t: "plus or minus"] # 0xb1 + - "´": [t: "acute"] # 0xb4 + - "·": # 0xB7 + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')] or not($SpeechStyle = 'ClearSpeak' and $ClearSpeak_MultSymbolDot = 'Auto')" + then: [t: "dot"] + else: [t: "times"] + - "×": # 0xd7 + - test: + if: "$SpeechStyle = 'ClearSpeak'" + then_test: + - if: "$ClearSpeak_MultSymbolX = 'Auto'" + then: [t: "times"] + - else_if: "$ClearSpeak_MultSymbolX = 'By'" + then: [t: "by"] + else: [t: "cross"] + else_test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [t: "cross"] + else: [t: "times"] + + - "÷": [t: "divided by"] # 0xf7 + - "̀": [t: "grave accent embellishment"] # 0x300 + - "́": [t: "acute accent embellishment"] # 0x301 + - "̂": [t: "circumflex accent embellishment"] # 0x302 + - "̃": [t: "tilde embellishment"] # 0x303 + - "̄": [t: "macron embellishment"] # 0x304 + - "̅": [t: "overbar embellishment"] # 0x305 + - "̆": [t: "breve"] # 0x306 + - "̇": [t: "dot above embellishment"] # 0x307 + + # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong + - "Α-Ω": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [t: "cap"] + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [spell: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] + + - "α": [t: "alpha"] # 0x3b1 + - "β": [t: "beta"] # 0x3b2 + - "γ": [t: "gamma"] # 0x3b3 + - "δ": [t: "delta"] # 0x3b4 + - "ε": [t: "epsilon"] # 0x3b5 + - "ζ": [t: "zeta"] # 0x3b6 + - "η": [t: "eta"] # 0x3b7 + - "θ": [t: "theta"] # 0x3b8 + - "ι": [t: "iota"] # 0x3b9 + - "κ": [t: "kappa"] # 0x3ba + - "λ": [t: "lambda"] # 0x3bb + - "μ": [t: "mu"] # 0x3bc + - "ν": [t: "nu"] # 0x3bd + - "ξ": [t: "zai"] # 0x3be + - "ο": [t: "omicron"] # 0x3bf + - "π": [t: "pi"] # 0x3c0 + - "ρ": [t: "rho"] # 0x3c1 + - "ς": [t: "final sigma"] # 0x3c2 + - "σ": [t: "sigma"] # 0x3c3 + - "τ": [t: "tau"] # 0x3c4 + - "υ": [t: "upsilon"] # 0x3c5 + - "φ": [t: "phi"] # 0x3c6 + - "χ": [t: "chi"] # 0x3c7 + - "ψ": [t: "psi"] # 0x3c8 + - "ω": [t: "omega"] # 0x3c9 + - "ϕ": [t: "phi"] # 0x3d5 + - "ϖ": [t: "pi"] # 0x3d6 + - "ϵ": [t: "epsilon"] # 0x3f5 + - "϶": [t: "reversed epsilon"] # 0x3f6 + + - "⁡": # 0x2061 + - test: + # skip saying "of" when Terse and a trig function, when it is a shape (does this happen?), or we are in :literal mode + if: "not( + ( $Verbosity='Terse' or ($SpeechStyle = 'ClearSpeak' and IsNode(following-sibling::*[1],'simple')) and + preceding-sibling::*[1][IfThenElse($SpeechStyle='ClearSpeak', + IsInDefinition(., 'ClearSpeakTrigFunctionNames'), + IsInDefinition(., 'TrigFunctionNames') )] + ) or + preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')] or + (@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) + )" + then: [t: "of"] + - "⁢": [t: ""] # 0x2062 + - "⁣": [t: ""] # 0x2063 + - "⁤": [t: "and"] # 0x2064 + - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" + - t: "double-struck" + - spell: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" + + - "℃": [t: "degrees celsius"] # 0x2103 + - "ℋℛℓ": # 0x210b + - t: "script" + - spell: "translate('.', 'ℋℛℓ', 'HRl')" + - "ℜ": # 0x211c + - t: "fraktur" + - spell: "'R'" + + - "ⅆⅇⅈⅉ": # 0x2146-9 + - t: "double-struck italic" + - spell: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" + + - "←": [t: "left arrow"] # 0x2190 + - "↑": [t: "up arrow"] # 0x2191 + - "→": # 0x2192 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [t: "approaches"] + else: [t: "right arrow"] + + - "↓": [t: "down arrow"] # 0x2193 + - "∈": # 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - test: + if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" + then: [t: "is"] + - t: "an element of" + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [t: "in"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [t: "member of"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [t: "element of"] + - else: [t: "belonging to"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [t: "is a member of"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [t: "is an element of"] + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [t: "is in"] + - else: [t: "belongs to"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + - "∥": # 0x2225 + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [t: "double vertical line"] + else: + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "parallel to" + - "∦": # 0x2226 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "not parallel to" + - "≤": # 0x2264 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "less than or equal to" + - "≥": # 0x2265 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "greater than or equal to" + + # --- restored complex short definitions (prefer over unicode-full) --- + - "…": # 0x2026 + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak '…' as 'and so on...' unless expr starts with '…' + - "../*[1][.='…']" + then: [t: "dot dot dot"] + else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' + if: "count(following-sibling::*) = 0" + then: [t: "and so on"] + else: [t: "and so on up to"] + - "∂": # 0x2202 + - test: + if: "$Verbosity='Terse'" + then: [t: "partial"] + else: [t: "partial derivative"] + - "∆": # 0x2206 + - test: + if: "$Verbosity!='Terse'" + then: [ot: "the"] + - t: "laplacian of" + - "∉": # 0x2209 + # rule is identical to 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "not an element of" + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [t: "not in"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [t: "not member of"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [t: "not element of"] + - else: [t: "not belonging to"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [t: "is not a member of"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [t: "is not an element of"] + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [t: "is not in"] + - else: [t: "does not belong to"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + - "∊": # 0x220a + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - test: + if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" + then: [t: "is"] + - t: "an element of" + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [t: "in"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [t: "member of"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [t: "element of"] + - else: [t: "belonging to"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [t: "is a member of"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [t: "is an element of"] + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [t: "is in"] + - else: [t: "belongs to"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + - "√": # 0x221a + - test: + if: "$Verbosity!='Terse'" + then: [ot: "the"] + - t: "square root of" + - "∝": # 0x221d + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "proportional to" + - "∶": # 0x2236 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "to" + - "∾": # 0x223e + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "most positive" + - "≠": # 0x2260 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "not equal to" + - "≡": # 0x2261 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "identical to" + - "⊂": # 0x2282 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is a"] + - t: "subset of" + - "⊃": # 0x2283 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is a"] + - t: "superset of" + - "⊄": # 0x2284 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "not a subset of" + - "⊅": # 0x2285 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is"] + - t: "not a superset of" + - "⊆": # 0x2286 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is a"] + - t: "subset of or equal to" + - "⊇": # 0x2287 + - test: + if: "$Verbosity!='Terse'" + then: [t: "is a"] + - t: "superset of or equal to" + + # --- restored short definitions that differ from unicode-full --- + - "⇒": [t: "right double arrow"] # 0x21d2 + - "∐": [t: "co-product"] # 0x2210 diff --git a/Rules/Languages/es/unicode-full.yaml b/Rules/Languages/es/unicode-full.yaml index 603fc3a85..23d453e29 100644 --- a/Rules/Languages/es/unicode-full.yaml +++ b/Rules/Languages/es/unicode-full.yaml @@ -1,3401 +1,3401 @@ ---- - - - "¤": [T: "moneda"] # 0xa4 (en: 'currency sign') - - "¥": [T: "yen"] # 0xa5 - - "¦": [T: "barra vertical partida"] # 0xa6 (en: 'broken bar') - - "§": [T: "sección"] # 0xa7 (en: 'section') - - "¨": [T: "diéresis"] # 0xa8 (en: 'double dot') - - "©": [T: "copyright"] # 0xa9 - - "ª": [T: "ordinal femenino"] # 0xaa (en: 'feminine ordinal indicator') - - "«": [T: "abrir comillas angulare"] # 0xab (en: 'left-pointing double angle quote mark', MathPlayer: 'abre comillas angulares', google: 'marca de cotización de doble ángulo de punta izquierda') - - "¯": # 0xaf - - test: - if: "ancestor::m:modified-variable and preceding-sibling::*[1][self::m:mi]" - then: [T: "barra"] # (google translation) - else: [T: "barra"] # (en: 'line') - - "²": [T: "al cuadrado"] # 0xb2 (en: 'two', MathPlayer: 'super 2', google: 'dos') - - "³": [T: "al cubo"] # 0xb3 (en: 'three', MathPlayer: 'super 3', google: 'tres') - - "µ": [T: "micro"] # 0xb5 - - "¹": [T: "super 1"] # 0xb9 (en: 'one', google: 'uno') - - "º": [T: "ordinal masculino"] # 0xb9 (en: 'masculine ordinal indicator') - - "ʰ": [T: "modificador pequeño h"] # 0x2b0 (en: 'modifier small h', google translation) - - "ʱ": [T: "modificador pequeño h con gancho"] # 0x2b1 (en: 'modifier small h with hook', google translation) - - "ʲ": [T: "modificador pequeño j"] # 0x2b2 (en: 'modifier small j', google translation) - - "ʳ": [T: "modificador pequeño r"] # 0x2b3 (en: 'modifier small r', google translation) - - "ʴ": [T: "modificador pequeño girado r"] # 0x2b4 (en: 'modifier small turned r', google translation) - - "ʵ": [T: "modificador pequeño girado r con gancho"] # 0x2b5 (en: 'modifier small turned r with hook', google translation) - - "ʶ": # 0x2b6 - - T: "modificador pequeño invertido" # (en: 'modifier small inverted', google translation) - - spell: "translate('R', 'R', 'R')" - - - "ʷ": [T: "modificador pequeño w"] # 0x2b7 (en: 'modifier small w', google translation) - - "ʸ": [T: "modificador pequeño y"] # 0x2b8 (en: 'modifier small y', google translation) - - "ʹ": [T: "prima"] # 0x2b9 (en: 'modifier prime', google: 'modificador prime') - - "ʺ": [T: "dos prima"] # 0x2ba (en: 'modifier double prime', google: 'modificador doble prime') - - "ʻ": [T: "modificador girado por coma"] # 0x2bb (en: 'modifier turned comma', google translation) - - "ʼ": [T: "apóstrofo modificador"] # 0x2bc (en: 'modifier apostrophe', google translation) - - "ʽ": [T: "modificador de coma invertida"] # 0x2bd (en: 'modifier reversed comma', google translation) - - "ʾ": [T: "semianillo a la derecha"] # 0x2be (en: 'modifier right half ring', google: 'modificador de medio anillo derecho') - - "ʿ": [T: "semianillo a la izquierda"] # 0x2bf (en: 'modifier left half ring', google: 'modificador de medio anillo izquierdo') - - "ˀ": [T: "modificador de parada glótica"] # 0x2c0 (en: 'modifier glottal stop', google translation) - - "ˁ": [T: "modificador invertido de parada glótica"] # 0x2c1 (en: 'modifier reversed glottal stop', google translation) - - "˂": [T: "modificador de punta de flecha izquierda"] # 0x2c2 (en: 'modifier left arrowhead', google translation) - - "˃": [T: "modificador de punta de flecha derecha"] # 0x2c3 (en: 'modifier right arrowhead', google translation) - - "˄": [T: "modificador de punta de flecha hacia arriba"] # 0x2c4 (en: 'modifier up arrowhead', google translation) - - "˅": [T: "modificador de punta de flecha hacia abajo"] # 0x2c5 (en: 'modifier down arrowhead', google translation) - - "ˆ": [T: "circunflejo"] # 0x2c6 (en: 'modifier circumflex accent', google: 'acento circunflejo modificador') - - "ˇ": [T: "carón"] # 0x2c7 (en: 'caron', google: 'caron') - - "ˈ": [T: "línea vertical modificador"] # 0x2c8 (en: 'modifier vertical line', google translation) - - "ˉ": [T: "modificador macron"] # 0x2c9 (en: 'modifier macron', google translation) - - "ˊ": [T: "modificador acento agudo"] # 0x2ca (en: 'modifier acute accent', google translation) - - "ˋ": [T: "modificador acento grave"] # 0x2cb (en: 'modifier grave accent', google translation) - - "ˌ": [T: "modificador línea baja vertical"] # 0x2cc (en: 'modifier low vertical line', google translation) - - "ˍ": [T: "modificador bajo macron"] # 0x2cd (en: 'modifier low macron', google translation) - - "ˎ": [T: "modificador acento acento grave bajo"] # 0x2ce (en: 'modifier low grave accent', google translation) - - "ˏ": [T: "modificador acento bajo agudo"] # 0x2cf (en: 'modifier low acute accent', google translation) - - "ː": [T: "modificador de colon triangular"] # 0x2d0 (en: 'modifier triangular colon', google translation) - - "ˑ": [T: "modificador de medio colon triangular"] # 0x2d1 (en: 'modifier half triangular colon', google translation) - - "˒": [T: "modificador centrado en la mitad del anillo rerecho"] # 0x2d2 (en: 'modifier centered right half ring', google translation) - - "˓": [T: "modificador centrado en la mitad del anillo izquierdo"] # 0x2d3 (en: 'modifier centered left half ring', google translation) - - "˔": [T: "modificador de tadck superior"] # 0x2d4 (en: 'modifier up tadck', google translation) - - "˕": [T: "modificador hacia abajo"] # 0x2d5 (en: 'modifier down tack', google translation) - - "˖": [T: "modificador más signo"] # 0x2d6 (en: 'modifier plus sign', google translation) - - "˗": [T: "medio anillo derecho por debajo de la ornamentación"] # 0x339 (en: 'right half ring below embellishment', google translation) - - "̺": [T: "puente invertido debajo de la ornamentación"] # 0x33a (en: 'inverted bridge below embellishment', google translation) - - "̻": [T: "cuadrado por debajo de la ornamentación"] # 0x33b (en: 'square below embellishment', google translation) - - "̼": [T: "gaviota por debajo del adorno"] # 0x33c (en: 'seagull below embellishment', google translation) - - "̽": [T: "x por encima del adorno"] # 0x33d (en: 'x above embellishment', google translation) - - "̾": [T: "ornamentación de tilde vertical"] # 0x33e (en: 'vertical tilde embellishment', google translation) - - "̿": [T: "ornamentación de doble superposición"] # 0x33f (en: 'double overline embellishment', google translation) - - "̀": [T: "ornamentación de la señal de tono grave"] # 0x340 (en: 'grave tone mark embellishment', google translation) - - "́": [T: "ornamentación de la señal de tono agudo"] # 0x341 (en: 'acute tone mark embellishment', google translation) - - - "ΪΫϏ": # 0x3aa, 0x3ab, 0x3cf - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "mayúscula"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [spell: "translate('.', 'ΪΫϏ', 'ιυϗ')"] - - T: "con dialytika" # (en: 'with dialytika', google translation) - - "ϊ": [T: "iota con dialytika"] # 0x3ca (en: 'iota with dialytika', google translation) - - "ϋ": [T: "épsilon con dialytika"] # 0x3cb (en: 'upsilon with dialytika', google translation) - - "ό": [T: "ómicron con tonos"] # 0x3cc (en: 'omicron with tonos', google translation) - - "ύ": [T: "épsilon con tonos"] # 0x3cd (en: 'upsilon with tonos', google translation) - - "ώ": [T: "omega con tonos"] # 0x3ce (en: 'omega with tonos', google translation) - - "ϐ": [T: "símbolo beta"] # 0x3d0 (en: 'beta') - - "ϑ": [T: "variante de theta"] # 0x3d1 (en: 'theta', google: 'theta') - - "ϒ": [T: "ípsilon con gancho"] # 0x3d2 (en: 'upsilon with hook', google: 'upsilon con gancho') - - "ϓ": [T: "épsilon con diéresis y gancho"] # 0x3d4 (en: 'upsilon with diaeresis and hook', google translation) - - "ϗ": [T: "símbolo kai griego"] # 0x3d7 (en: 'kai') - - "А-Я": # 0x410 - 0x42f - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "mayúscula"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [spell: "translate('.', 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ', 'абвгдежзийклмнопрстуфхцчшщъыьэюя')"] - - "а": [T: "a"] # 0x430 (google: 'а') - - "б": [T: "be"] # 0x431 (google: 'ser') - - "в": [T: "ve"] # 0x432 (google: 'veinte') - - "г": [T: "ghe"] # 0x433 - - "д": [T: "de"] # 0x434 (google: 'delaware') - - "е": [T: "ie"] # 0x435 (google: 'es decir') - - "ж": [T: "zhe"] # 0x436 - - "з": [T: "i"] # 0x438 (google: 'и') - - "й": [T: "i corta"] # 0x439 (en: 'short i', google: 'corto i') - - "к": [T: "ka"] # 0x43a - - "л": [T: "em"] # 0x43c - - "н": [T: "o"] # 0x43e (google: 'о') - - "п": [T: "pe"] # 0x43f (google: 'educación física') - - "р": [T: "er"] # 0x440 - - "с": [T: "es"] # 0x441 - - "т": [T: "te"] # 0x442 - - "у": [T: "u"] # 0x443 (google: 'у') - - "ф": [T: "ef"] # 0x444 - - "х": [T: "ha"] # 0x445 (google: 'ja') - - "ц": [T: "tse"] # 0x446 - - "ч": [T: "che"] # 0x447 - - "ш": [T: "sha"] # 0x448 - - "щ": [T: "shcha"] # 0x449 - - "ъ": [T: "signo duro"] # 0x44a (en: 'hard sign') - - "ы": [T: "yeru"] # 0x44b - - "ь": [T: "signo suave"] # 0x44c (en: 'soft sign') - - "э": [T: "e"] # 0x44d (google: 'э') - - "ю": [T: "yu"] # 0x44e - - "я": [T: "ya"] # 0x44f - - "‐": [T: "menos"] # 0x2010 (en: 'hyphen') - - "‑": [T: "guión indivisible"] # 0x2011 (en: 'hyphen', google: 'guión') - - "‒": [T: "figura Dash"] # 0x2012 (en: 'figure dash', google: 'figura dash') - - "―": [T: "barra horizontal"] # 0x2015 (en: 'horizontal bar') - - "•": # 0x2022 - - test: - if: "@data-chem-formula-op" - then: [T: "punto"] # (en: 'dot', google translation) - else: [T: "bala"] # (en: 'bullet') - - - "‰": [T: "tanto por millar"] # 0x2030 (en: 'per mille') - - "‱": [T: "tanto por diez mil"] # 0x2031 (en: 'per ten thousand') - - "′": [T: "prima"] # 0x2032 (en: 'prime') - - "‸": [T: "signo de intercalación"] # 0x2038 (en: 'to the', google: 'hacia') - - "‹": [T: "comillas izquierda"] # 0x2039 (en: 'single left pointing angle quote mark', MathPlayer: 'abre comillas', google: 'marque de cotización de ángulo de punta individual izquierdo') - - "›": [T: "comillas derecha"] # 0x203a (en: 'single right pointing angle quote mark', MathPlayer: 'cierra comillas', google: 'marque de cita de ángulo de punta de la derecha única') - - "‼": [T: "doble signo de exclamación"] # 0x203c (en: 'double factorial', google: 'doble factorial') - - "⁄": [T: "barra de fracción"] # 0x2044 (en: 'divided by') - - "⁅": [T: "corchete izquierdo"] # 0x2045 (en: 'left square bracket with quill') - - "⁆": [T: "corchete derecho"] # 0x2046 (en: 'right square bracket with quill') - - "⁗": [T: "cuatro prima"] # 0x2057 (en: 'quadruple prime', MathPlayer: 'cuarta', google: 'prime cuádruple') - - "⁠": [T: ""] # 0x2060 - - "⁣": [T: ""] # 0x2063 - - "⁤": [T: "más"] # 0x2064 (en: 'and', google: 'y') - - "⁰": [T: "a la potencia de cero"] # 0x2070 (en: 'to the zeroth power', google translation) - - "ⁱ": [T: "superíndice i"] # 0x2071 (en: 'to the eihth power', google: 'al poder eihth') - - "⁴": [T: "a la cuarta potencia"] # 0x2074 (en: 'to the fourth power', google translation) - - "⁵": [T: "a la quinta potencia"] # 0x2075 (en: 'to the fifth power', google translation) - - "⁶": [T: "a la sexta potencia"] # 0x2076 (en: 'to the sixth power', google translation) - - "⁷": [T: "a la séptima potencia"] # 0x2077 (en: 'to the seventh power', google translation) - - "⁸": [T: "a la octava potencia"] # 0x2078 (en: 'to the eighth power', google translation) - - "⁹": [T: "a la novena potencia"] # 0x2079 (en: 'to the ninth power', google translation) - - "⁺": [T: "superíndice signo más"] # 0x207a (en: 'superscript plus sign', google: 'superscript plus sign') - - "⁻": [T: "superíndice menos"] # 0x207b (en: 'superscript minus', google: 'superscript menos') - - "⁼": [T: "superíndice signo igual"] # 0x207c (en: 'superscript equals sign', google: 'superscript es igual a signo') - - "⁽": [T: "paréntesis izquierdo superíndice"] # 0x207d (en: 'superscript left parenthesis', google: 'superscript dejó paréntesis') - - "⁾": [T: "paréntesis derecho superíndice"] # 0x207e (en: 'superscript right parenthesis', google: 'superscript dirección de entrega de paréntesis') - - "ⁿ": [T: "superíndice n"] # 0x207f (en: 'to the ennth power', google: 'al poder de enth') - - "₀": [T: "bajo cero"] # 0x2080 (en: 'sub zero', google translation) - - "₁": [T: "sub uno"] # 0x2081 (en: 'sub one', google translation) - - "₂": [T: "sub dos"] # 0x2082 (en: 'sub two', google translation) - - "₃": [T: "sub tres"] # 0x2083 (en: 'sub three', google translation) - - "₄": [T: "sub cuatro"] # 0x2084 (en: 'sub four', google translation) - - "₅": [T: "sub cinco"] # 0x2085 (en: 'sub five', google translation) - - "₆": [T: "sub seis"] # 0x2086 (en: 'sub six', google translation) - - "₇": [T: "sub siete"] # 0x2087 (en: 'sub seven', google translation) - - "₈": [T: "sub ocho"] # 0x2088 (en: 'sub eight', google translation) - - "₉": [T: "sub nueve"] # 0x2089 (en: 'sub nine', google translation) - - "₊": [T: "subíndice signo más"] # 0x208a (en: 'subscript plus sign', google: 'subscript plus sign') - - "₋": [T: "subíndice menos"] # 0x208b (en: 'subscript minus sign', google: 'subíndico menos signo') - - "₌": [T: "subíndice signo igual"] # 0x208c (en: 'subscript equals sign', google: 'el subíndice es igual al signo') - - "₍": [T: "subíndice paréntesis derecho"] # 0x208e (en: 'subscript right parenthesis', google: 'subíndice de paréntesis derecha') - - "ₐ": [T: "subíndice a"] # 0x2090 (en: 'sub A', google: 'sub a') - - "ₑ": [T: "subíndice e"] # 0x2091 (en: 'sub E', google: 'sub e') - - "ₒ": [T: "subíndice o"] # 0x2092 (en: 'sub O', google: 'sub o') - - "ₓ": [T: "subíndice x"] # 0x2093 (en: 'sub X', google: 'sub x') - - "ₕ": [T: "subíndice h"] # 0x2095 (en: 'sub H', google: 'sub h') - - "ₖ": [T: "subíndice k"] # 0x2096 (en: 'sub K', google: 'sub k') - - "ₗ": [T: "subíndice l"] # 0x2097 (en: 'sub L', google: 'sub l') - - "ₘ": [T: "subíndice m"] # 0x2098 (en: 'sub M', google: 'sub m') - - "ₙ": [T: "subíndice n"] # 0x2099 (en: 'sub N', google: 'sub n') - - "ₚ": [T: "subíndice p"] # 0x209a (en: 'sub P', google: 'sub p') - - "ₛ": [T: "subíndice s"] # 0x209b (en: 'sub S', google: 'sub s') - - "ₜ": [T: "subíndice t"] # 0x209c (en: 'sub T', google: 'sub t') - - "₠": [T: "unidades de corriente europeas"] # 0x20a0 (en: 'european currenty units', google translation) - - "₡": [T: "dos puntos"] # 0x20a1 (en: 'colons', google: 'colons') - - "₢": [T: "cruzeiro"] # 0x20a2 (en: 'cruzeiro', google: 'cruzeiro') - - "₣": [T: "franco"] # 0x20a3 (en: 'franc') - - "₤": [T: "lira"] # 0x20a4 - - "₥": [T: "molinos"] # 0x20a5 (en: 'mills') - - "₦": [T: "naira"] # 0x20a6 - - "₧": [T: "peseta"] # 0x20a7 - - "₨": [T: "rupia"] # 0x20a8 (en: 'rupees', google: 'rupias') - - "₩": [T: "won"] # 0x20a9 (google: 'ganado') - - "₪": [T: "nuevo sheqel"] # 0x20aa (en: 'new sheqels', google: 'nuevo sheqels') - - "₫": [T: "dong"] # 0x20ab (google: 'polla') - - "€": [T: "euro"] # 0x20ac (en: 'euros', google: 'euros') - - "₭": [T: "kip"] # 0x20ad (google: 'dormir') - - "₮": [T: "tugrik"] # 0x20ae - - "₯": [T: "dracma"] # 0x20af (en: 'drachma') - - "₰": [T: "penique alemán"] # 0x20b0 (en: 'german pennies', google: 'centavos alemanes') - - "₱": [T: "peso"] # 0x20b1 (en: 'pesos', google: 'pesos') - - "₲": [T: "guaraníes"] # 0x20b2 (en: 'guaranis', google translation) - - "₳": [T: "australs"] # 0x20b3 (google translation) - - "₴": [T: "hryvnias"] # 0x20b4 (google translation) - - "₵": [T: "cedis"] # 0x20b5 (google translation) - - "₶": [T: "livre tournois"] # 0x20b6 (google translation) - - "₷": [T: "spesmilos"] # 0x20b7 (google translation) - - "₸": [T: "tenges"] # 0x20b8 (google translation) - - "₹": [T: "rupias indias"] # 0x20b9 (en: 'indian rupees', google translation) - - "₺": [T: "liras turcas"] # 0x20ba (en: 'turkish liras', google translation) - - "⃐": [T: "arpón izquierdo por encima de la ornamentación"] # 0x20d0 (en: 'left harpoon above embellishment', google: 'arpón de izquierda por encima del adorno') - - "⃑": [T: "arpón derecho por encima de la ornamentación"] # 0x20d1 (en: 'right harpoon above embellishment', google: 'arpón derecho por encima del adorno') - - "⃒": [T: "línea vertical larga con ornamentación superpuesta"] # 0x20d2 (en: 'long vertical line overlay embellishment', google translation) - - "⃓": [T: "línea vertical corta con ornamentación superpuesta"] # 0x20d3 (en: 'short vertical line overlay embellishment', google translation) - - "⃔": [T: "flecha en sentido contrario a las agujas del reloj por encima de la ornamentación"] # 0x20d4 (en: 'anticlockwise arrow above embellishment', google translation) - - "⃕": [T: "flecha en el sentido de las agujas del reloj por encima de la ornamentación"] # 0x20d5 (en: 'clockwise arrow above embellishment', google translation) - - "⃖": [T: "flecha izquierda por encima de la ornamentación"] # 0x20d6 (en: 'left arrow above embellishment', google: 'flecha izquierda por encima del adorno') - - "⃗": [T: "flecha derecha por encima de la ornamentación"] # 0x20d7 (en: 'right arrow above embellishment', google: 'flecha derecha por encima del adorno') - - "⃘": [T: "ornamentación superpuesta al anillo"] # 0x20d8 (en: 'ring overlay embellishment', google translation) - - "⃙": [T: "anillo en el sentido de las agujas del reloj con ornamentación superpuesta"] # 0x20d9 (en: 'clockwise ring overlay embellishment', google translation) - - "⃚": [T: "anilo en sentido contrario a las agujas del reloj con ornamentación superpuesta"] # 0x20da (en: 'anticlockwise ring overlay embellishment', google translation) - - "⃛": [T: "tres puntos"] # 0x20db (en: 'triple dot', google: 'triple punto') - - "⃜": [T: "cuatro puntos "] # 0x20dc (en: 'quadruple dot', google: 'punto cuádruple') - - "⃝": [T: "ornamentación de círculo envolvente"] # 0x20dd (en: 'enclosing circle embellishment', google translation) - - "⃞": [T: "ornamentación de cuadrado envolvente"] # 0x20de (en: 'enclosing square embellishment', google translation) - - "⃟": [T: "ornamentación de rombo envolvente"] # 0x20df (en: 'enclosing diamond embellishment', google translation) - - "⃠": [T: "ornamentación con bara inversa de círculo envolvente"] # 0x20e0 (en: 'enclosing circle backslash embellishment', google translation) - - "⃡": [T: "doble flecha por encima de la ornamentación"] # 0x20e1 (en: 'left right arrow above embellishment', google: 'flecha derecha izquierda por encima del adorno') - - "⃢": [T: "ornamentación de pantalla envolvente"] # 0x20e2 (en: 'enclosing screen embellishment', google translation) - - "⃣": [T: "ornamentación de clave envolvente"] # 0x20e3 (en: 'enclosing keycap embellishment', google translation) - - "⃤": [T: "ornamentación de triángulo envolvente apuntando hacia arriba"] # 0x20e4 (en: 'enclosing upward pointing triangle embellishment', google translation) - - "⃥": [T: "solidus invertido con ornamentación superpuesta"] # 0x20e5 (en: 'reverse solidus overlay embellishment', google translation) - - "⃦": [T: "doble vértice con ornamentación de trazo"] # 0x20e6 (en: 'double verticle stroke embellishment', google translation) - - "⃧": [T: "símbolo de anualidad con ornamentación"] # 0x20e7 (en: 'annuity symbol embellishment', google translation) - - "⃨": [T: "triple punto bajo"] # 0x20e8 (en: 'triple underdot', google translation) - - "⃩": [T: "amplio puente por encima de la ornamentación"] # 0x20e9 (en: 'wide bridge above embellishment', google translation) - - "⃪": [T: "flecha izquierda con ornamentación superpuesta"] # 0x20ea (en: 'leftwards arrow overlay embellishment', google translation) - - "⃫": [T: "largo y doble solidus con ornamentación superpuesta"] # 0x20eb (en: 'long double solidus overlay embellishment', google translation) - - "⃬": [T: "arpón hacia la derecha con ornamentación apuntando hacia abajo"] # 0x20ec (en: 'rightwards harpoon with barb downwards embellishment', google translation) - - "⃭": [T: "arpón hacia la izquierda con ornamentación apuntando hacia abajo"] # 0x20ed (en: 'leftwards harpoon with barb downwards embellishment', google translation) - - "⃮": [T: "flecha izquierda por debajo de la ornamentación"] # 0x20ee (en: 'left arrow below embellishment', google translation) - - "⃯": [T: "flecha derecha por debajo de la ornamentación"] # 0x20ef (en: 'right arrow below embellishment', google translation) - - "⃰": [T: "asterisco por encima de la ornamentación"] # 0x20f0 (en: 'asterisk above embellishment', google translation) - - "℄": [T: "símbolo de línea central"] # 0x2104 (en: 'center line symbol', google translation) - - "℅": [T: "para"] # 0x2105 (en: 'care of', google: 'cuidado de') - - "℆": [T: "cada una"] # 0x2106 (google: 'cadada una') - - "ℇ": [T: "constante de euler"] # 0x2107 (en: 'euler's constant', google: 'la constante de euler') - - "℈": [T: "escrúpulo"] # 0x2108 (en: 'scruples', google translation) - - "ℊ": [T: "g cursiva"] # 0x210a (en: 'script g', google: 'guión g') - - "ℌℑℨℭ": # 0x210c, 0x2111, 0x2128, 0x212d - - T: "g cursiva" # (en: 'fraktur', google: 'fraktur') - - spell: "translate('.', 'ℌℑℨℭ', 'HIZC')" - - - "ℍℙℾℿ": # 0x210d, 0x2119, 0x213e, 0x213f - - test: - if: "$Verbosity!='Terse'" - then: [T: "doble tachadura"] # (en: 'double struck', google translation) - - spell: "translate('.', 'ℍℙℾℿ', 'HPΓΠ')" - - - "ℏ": # 0x210f - - test: - if: "($Verbosity='Terse')" - then: [T: "h bar"] # (google translation) - else: [T: "h barra"] # (en: 'reduced planck constant') - - - "ℐℒ℘ℬℰℱℳ": # 0x2110, 0x2112, 0x2118, 0x2130, 0x2131, 0x2133 - - T: "h barra" # (en: 'script') - - spell: "translate('.', 'ℐℒ℘ℬℰℱℳ', 'ILPBEFM')" - - - "℔": [T: "L B símbolo de barra"] # 0x2114 (en: 'pounds', google: 'libras') - - "№": [T: "signo de número"] # 0x2116 (en: 'number') - - "℥": [T: "onza"] # 0x2125 (en: 'ounces') - - "Ω": [T: "ohmio"] # 0x2126 (en: 'ohms') - - "℧": [T: "iota invertida"] # 0x2129 (en: 'turned iota', google: 'convertido en iota') - - "Å": [T: "angstrom"] # 0x212b (en: 'angstroms') - - "ℯ": [T: "e cursiva"] # 0x212f (en: 'script e', google: 'guión e') - - # coalesced some chars that use cap letters - - "Ⅎ℺⅁⅂⅃⅄": # 0x2132, 0x213a, 0x2141, 0x2142, 0x2143, 0x2144 - - test: - - if: "'.' = '℺'" - then: [T: "rotado"] # (en: 'rotated', google translation) - - else_if: "'.' = 'Ⅎ'" - then: [T: "transformado"] # (en: 'turned', google translation) - - else_if: "'.' = '⅃'" - then: [T: "invertido sans-serif"] # (en: 'reversed sans-serif', google translation) - else: [T: "e cursiva"] # (en: 'turned sans-serif', google: 'convertido en sans-serif') - - spell: "translate('.', 'Ⅎ℺⅁⅂⅃⅄', 'FQGLLY')" - - - "ℴ": [T: "o cursiva"] # 0x2134 (en: 'script o', google: 'guión o') - - "ℵ": [T: "alef"] # 0x2135 (en: 'first transfinite cardinal') - - "ℶ": [T: "bet"] # 0x2136 (en: 'second transfinite cardinal') - - "ℷ": [T: "guímel"] # 0x2137 (en: 'third transfinite cardinal') - - "ℸ": [T: "dálet"] # 0x2138 (en: 'fourth transfinite cardinal') - - "ℼ": [T: "pi en negrita de pizarra"] # 0x213c (en: 'double struck pi', google: 'double golpeado pi') - - "ℽ": [T: "gamma en negrita de pizarra"] # 0x213d (en: 'double struck gamma', google: 'double golpeó a gamma') - - "⅀": [T: "suma de n-ary en negrita"] # 0x2140 (en: 'double struck n-ary summation', google: 'suma de doble apolón n-ary') - - "⅋": [T: "ampersand invertido"] # 0x214b (en: 'turned ampersand', google: 'convertido en ampersand') - - "⅌": [T: "por"] # 0x214c (en: 'per', google: 'por') - - "ⅎ": [T: "f invertida"] # 0x214e (en: 'turned F', google: 'girado f') - - "⅐": [T: "un séptimo"] # 0x2150 (en: 'one seventh', google: 'un septimo') - - "⅑": [T: "un noveno"] # 0x2151 (en: 'one ninth', google: 'un noveno') - - "⅒": [T: "un dadoécimo"] # 0x2152 (en: 'one tenth', google: 'una décima parte') - - "⅓": [T: "un tercio"] # 0x2153 (en: 'one third', SRE: 'Vulgar Fracción Un Tercero') - - "⅔": [T: "dos tercios"] # 0x2154 (en: 'two thirds', SRE: 'Fracción vulgar dos tercios') - - "⅕": [T: "un quinto"] # 0x2155 (en: 'one fifth', SRE: 'Vulgar Fraction One Fifth') - - "⅖": [T: " franción comúndos quintos"] # 0x2156 (en: 'two fifths', MathPlayer: 'dos quintos', google: 'dos quintas partes') - - "⅗": [T: " fracción común tres quintos"] # 0x2157 (en: 'three fifths', SRE: 'Fracción vulgar tres quintos') - - "⅘": [T: " fracción común cuatro quintos"] # 0x2158 (en: 'four fifths', SRE: 'Fracción vulgar cuatro quintos') - - "⅙": [T: "un sexto"] # 0x2159 (en: 'one sixth', SRE: 'Vulgar Fracción Un Sexto') - - "⅚": [T: "cinco sextos"] # 0x215a (en: 'five sixths', SRE: 'Vulgar fracción cinco sextos') - - "⅛": [T: "fracción común un octavo"] # 0x215b (en: 'one eighth', MathPlayer: 'un octavo', google: 'un ath') - - "⅜": [T: "fracción común tres octavos"] # 0x215c (en: 'three eighths', MathPlayer: 'tres octavos', google: 'tres ats') - - "⅝": [T: "fracción común cinco octavos"] # 0x215d (en: 'five eighths', MathPlayer: 'cinco octavos', google: 'cinco ats') - - "⅞": [T: "fracción común siete octavos"] # 0x215e (en: 'seven eighths', MathPlayer: 'siete octavos', google: 'siete ats') - - "⅟": [T: "Numerador de fracción uno"] # 0x215f (en: 'one over', google: 'uno sobre') - - "Ⅰ": [T: "Ⅰ"] # 0x2160 (en: 'I', google translation) - - "Ⅱ": [T: "T"] # 0x2161 (en: 'I I', google translation) - - "Ⅲ": [T: "III"] # 0x2162 (en: 'I I I', google translation) - - "Ⅳ": [T: "IV"] # 0x2163 (en: 'I V', google translation) - - "Ⅴ": [T: "V"] # 0x2164 (en: 'V', google translation) - - "Ⅵ": [T: "VI"] # 0x2165 (en: 'V I', google translation) - - "Ⅶ": [T: "VII"] # 0x2166 (en: 'V I I', google translation) - - "Ⅷ": [T: "VIII"] # 0x2167 (en: 'V I I I', google translation) - - "Ⅸ": [T: "IX"] # 0x2168 (en: 'I X', google translation) - - "Ⅹ": [T: "XI"] # 0x216a (en: 'X I', google translation) - - "Ⅻ": [T: "XII"] # 0x216b (en: 'X I I', google translation) - - "Ⅼ": [T: "Ⅼ"] # 0x216c (en: 'L', google translation) - - "Ⅽ": [T: "Ⅽ"] # 0x216d (en: 'C', google translation) - - "Ⅾ": [T: "Ⅾ"] # 0x216e (en: 'D', google translation) - - "Ⅿ": [T: "Ⅿ"] # 0x216f (en: 'M', google translation) - - "ⅰ": [T: "ⅰ"] # 0x2170 (en: 'I', google translation) - - "ⅱ": [T: "I"] # 0x2171 (en: 'I I', google translation) - - "ⅲ": [T: "III"] # 0x2172 (en: 'I I I', google translation) - - "ⅳ": [T: "IV"] # 0x2173 (en: 'I V', google translation) - - "ⅴ": [T: "ⅴ"] # 0x2174 (en: 'V', google translation) - - "ⅵ": [T: "VI"] # 0x2175 (en: 'V I', google translation) - - "ⅶ": [T: "VII"] # 0x2176 (en: 'V I I', google translation) - - "ⅷ": [T: "VIII"] # 0x2177 (en: 'V I I I', google translation) - - "ⅸ": [T: "IX"] # 0x2178 (en: 'I X', google translation) - - "ⅹ": [T: "ⅹ"] # 0x2179 (en: 'X', google translation) - - "ⅺ": [T: "XI"] # 0x217a (en: 'X I', google translation) - - "ⅻ": [T: "XII"] # 0x217b (en: 'X I I', google translation) - - "ⅼ": [T: "ⅼ"] # 0x217c (en: 'L', google translation) - - "ⅽ": [T: "ⅽ"] # 0x217d (en: 'C', google translation) - - "ⅾ": [T: "ⅾ"] # 0x217e (en: 'D', google translation) - - "ⅿ": [T: "ⅿ"] # 0x217f (en: 'M', google translation) - - "↉": [T: "fracción común cero tercios"] # 0x2189 (en: 'zero thirds', google: 'cero tercios') - - "↔": [T: "flecha hacia izquierda y derecha"] # 0x2194 (en: 'left right arrow') - - "↕": [T: "flecha hacia arriba y abajo"] # 0x2195 (en: 'up down arrow') - - "↖": [T: "flecha hacia el noroeste"] # 0x2196 (en: 'north west arrow') - - "↗": # 0x2197 - - test: - if: "ancestor::*[2][self::m:limit]" - then: [T: "enfoque desde abajo"] # (en: 'approaches from below', google translation) - else: [T: "flecha hacia el nordeste"] # (en: 'north east arrow') - - - "↘": # 0x2198 - - test: - if: "ancestor::*[2][self::m:limit]" - then: [T: "enfoque desde arriba"] # (en: 'approaches from above', google translation) - else: [T: "flecha hacia el sudeste"] # (en: 'south east arrow') - - - "↙": [T: "flecha hacia el sudoeste"] # 0x2199 (en: 'south west arrow') - - "↚": [T: "flecha con trazo hacia la izquierda"] # 0x219a (en: 'leftwards arrow with stroke') - - "↛": [T: "flecha con trazo hacia la derecha"] # 0x219b (en: 'rightwards arrow with stroke') - - "↜": [T: "flecha izquierda ondulada"] # 0x219c (en: 'leftwards wave arrow') - - "↝": [T: "flecha derecha ondulada"] # 0x219d (en: 'rightwards wave arrow') - - "↞": [T: "flecha hacia la izquierda con doble punta"] # 0x219e (en: 'leftwards two headed arrow') - - "↟": [T: "flecha hacia arriba con doble punta"] # 0x219f (en: 'upwards two headed arrow') - - "↠": [T: "flecha hacia la derecha con doble punta"] # 0x21a0 (en: 'rightwards two headed arrow') - - "↡": [T: "flecha hacia abajo con doble punta"] # 0x21a1 (en: 'downwards two headed arrow') - - "↢": [T: "flecha hacia la izquierda con cola"] # 0x21a2 (en: 'leftwards arrow with tail') - - "↣": [T: "flecha hacia la derecha con cola"] # 0x21a3 (en: 'rightwards arrow with tail') - - "↤": [T: "flecha hacia la izquierda con barra"] # 0x21a4 (en: 'leftwards arrow from bar') - - "↥": [T: "flecha hacia arriba con barra"] # 0x21a5 (en: 'upwards arrow from bar') - - "↦": [T: "flecha derecha hacia arriba con barra"] # 0x21a6 (en: 'rightwards arrow from bar') - - "↧": [T: "flecha hacia abajo con barra"] # 0x21a7 (en: 'downwards arrow from bar') - - "↨": [T: "flecha hacia arriba y hacia abajo con base"] # 0x21a8 (en: 'up down arrow with base') - - "↩": [T: "flecha hacia la izquierda con gancho"] # 0x21a9 (en: 'leftwards arrow with hook') - - "↪": [T: "fflecha hacia la derecha con gancho"] # 0x21aa (en: 'rightwards arrow with hook') - - "↫": [T: "flecha hacia la izquierda con bucle"] # 0x21ab (en: 'leftwards arrow with loop') - - "↬": [T: "flecha hacia la derecha con bucle"] # 0x21ac (en: 'rightwards arrow with loop') - - "↭": [T: "flecha ondulada hacia la izquierda y la derecha"] # 0x21ad (en: 'left right wave arrow') - - "↮": [T: "flecha hacia la izquierda y derecha con trazo"] # 0x21ae (en: 'left right arrow with stroke') - - "↯": [T: "flecha hacia abajo en zigzag"] # 0x21af (en: 'downwards zigzag arrow') - - "↰": [T: "flecha hacia arriba con punta hacia la izquierda"] # 0x21b0 (en: 'upwards arrow with tip leftwards') - - "↱": [T: "flecha hacia arriba con punta hacia la derecha"] # 0x21b1 (en: 'upwards arrow with tip rightwards') - - "↲": [T: "flecha hacia abajo con punta hacia la izquierda"] # 0x21b2 (en: 'downwards arrow with tip leftwards') - - "↳": [T: "flecha hacia abajo con punta hacia la derecha"] # 0x21b3 (en: 'downwards arrow with tip rightwards') - - "↴": [T: "flecha hacia la derecha con intersección hacia abajo"] # 0x21b4 (en: 'rightwards arrow with corner downwards') - - "↵": [T: "flecha hacia abajo con intersección hacia la izquierda"] # 0x21b5 (en: 'downwards arrow with corner leftwards') - - "↶": [T: "flecha semicircular superior en sentido contrario a las agujas del reloj"] # 0x21b6 (en: 'anticlockwise top semicircle arrow') - - "↷": [T: "flecha semicircular superior en sentido de las agujas del reloj"] # 0x21b7 (en: 'clockwise top semicircle arrow') - - "↸": [T: "flecha noroeste hacia barra larga"] # 0x21b8 (en: 'north west arrow to long bar') - - "↹": [T: "flecha izquierda hacia barra por encima de flecha derecha hacia barra"] # 0x21b9 (en: 'leftwards arrow to bar over rightwards arrow to bar') - - "↺": [T: "flecha circular abierta en sentido contrario a las agujas del reloj"] # 0x21ba (en: 'anticlockwise open circle arrow') - - "↻": [T: "flecha circular abierta en sentido de las agujas del reloj"] # 0x21bb (en: 'clockwise open circle arrow') - - "↼": [T: "flecha izquierda con arpón en la parte superior"] # 0x21bc (en: 'left harpoon up') - - "↽": [T: "flecha izquierda con arpón en la parte inferior"] # 0x21bd (en: 'left harpoon down') - - "↾": [T: "arpón derecho hacia arriba"] # 0x21be (en: 'up harpoon right') - - "↿": [T: "arpón izquierdo hacia arriba"] # 0x21bf (en: 'up harpoon left') - - "⇀": [T: "arpón derecho hacia arriba"] # 0x21c0 (en: 'right harpoon up') - - "⇁": [T: "arpón derecho hacia abajo"] # 0x21c1 (en: 'right harpoon down') - - "⇂": [T: "arpón derecho hacia abajo"] # 0x21c2 (en: 'down harpoon right') - - "⇃": [T: "arpón izquierdo hacia abajo"] # 0x21c3 (en: 'down harpoon left') - - "⇄": [T: "flecha hacia la derecha por encima de flecha hacia la izquierda"] # 0x21c4 (en: 'rightwards arrow over leftwards arrow') - - "⇅": [T: "flecha hacia arriba a la izquierda de flecha hacia abajo"] # 0x21c5 (en: 'upwards arrow leftwards of downwards arrow') - - "⇆": [T: "flecha hacia la izquierda por encima de flecha hacia la derecha"] # 0x21c6 (en: 'leftwards arrow over rightwards arrow') - - "⇇": [T: "dos flechas hacia la izquierda"] # 0x21c7 (en: 'leftwards paired arrows') - - "⇈": [T: "dos flechas hacia arriba"] # 0x21c8 (en: 'upwards paired arrows') - - "⇉": [T: "dos flechas hacia la derecha"] # 0x21c9 (en: 'rightwards paired arrows') - - "⇊": [T: "dos flechas hacia abajo"] # 0x21ca (en: 'downwards paired arrows') - - "⇋": [T: "arpón izquierdo por encima de arpón derecho"] # 0x21cb (en: 'left harpoon over right harpoon') - - "⇌": [T: "arpón derecho por encima de arpón izquierdo"] # 0x21cc (en: 'right harpoon over left harpoon') - - "⇍": [T: "flecha doble izquierda con trazo"] # 0x21cd (en: 'leftwards double arrow with stroke') - - "⇎": [T: "flecha doble izquierda y derecha con trazo"] # 0x21ce (en: 'left right double arrow with stroke') - - "⇏": [T: "flecha doble hacia la derecha con trazo"] # 0x21cf (en: 'rightwards double arrow with stroke') - - "⇐": [T: "flecha doble hacia la izquierda"] # 0x21d0 (en: 'leftwards double arrow') - - "⇑": [T: "flecha doble hacia arriba"] # 0x21d1 (en: 'upwards double arrow') - - "⇓": [T: "flecha doble hacia abajo"] # 0x21d3 (en: 'downwards double arrow') - - "⇔": [T: "flecha doble vertical"] # 0x21d5 (en: 'up down double arrow') - - "⇖": [T: "flecha doble hacia noroeste"] # 0x21d6 (en: 'north west double arrow') - - "⇗": [T: "flecha doble hacia nordeste"] # 0x21d7 (en: 'north east double arrow') - - "⇘": [T: "flecha doble hacia sudeste"] # 0x21d8 (en: 'south east double arrow') - - "⇙": [T: "flecha doble hacia sudoeste"] # 0x21d9 (en: 'south west double arrow') - - "⇚": [T: "flecha triple hacia la izquierda"] # 0x21da (en: 'leftwards triple arrow') - - "⇛": [T: "flecha triple hacia la derecha"] # 0x21db (en: 'rightwards triple arrow') - - "⇜": [T: "flecha ondulada izquierda"] # 0x21dc (en: 'leftwards squiggle arrow') - - "⇝": [T: "flecha ondulada hacia la derecha"] # 0x21dd (en: 'rightwards squiggle arrow') - - "⇞": [T: "flecha hacia arriba con doble trazo"] # 0x21de (en: 'upwards arrow with double stroke') - - "⇟": [T: "flecha hacia abajo con doble trazo"] # 0x21df (en: 'downwards arrow with double stroke') - - "⇠": [T: "flecha de puntos hacia la izquierda"] # 0x21e0 (en: 'leftwards dashed arrow') - - "⇡": [T: "flecha de puntos hacia arriba"] # 0x21e1 (en: 'upwards dashed arrow') - - "⇢": [T: "flecha de puntos hacia la derecha"] # 0x21e2 (en: 'rightwards dashed arrow') - - "⇣": [T: "flecha de puntos hacia abajo"] # 0x21e3 (en: 'downwards dashed arrow') - - "⇤": [T: "flecha hacia la izquierda con barra"] # 0x21e4 (en: 'leftwards arrow to bar') - - "⇥": [T: "flecha hacia la derecha con barra"] # 0x21e5 (en: 'rightwards arrow to bar') - - "⇦": [T: "flecha blanca hacia la izquierda"] # 0x21e6 (en: 'leftwards white arrow') - - "⇧": [T: "flecha blanca hacia arriba"] # 0x21e7 (en: 'upwards white arrow') - - "⇨": [T: "flecha blanca hacia la derecha"] # 0x21e8 (en: 'rightwards white arrow') - - "⇩": [T: "flecha blanca hacia abajo"] # 0x21e9 (en: 'downwards white arrow') - - "⇪": [T: "flecha blanca hacia arriba partiendo de barra"] # 0x21ea (en: 'upwards white arrow from bar') - - "⇫": [T: "flecha blanca hacia arriba sobre un pedestal con barra horizontal"] # 0x21eb - - "⇬": [T: "flecha blanca hacia arriba sobre pedestal con barra horizontal"] # 0x21ec (en: 'upwards white arrow on pedestal with horizontal bar', google: 'arrow blanca hacia arriba en el pedestal con barra horizontal') - - "⇭": [T: "flecha blanca hacia arriba sobre un pedestal con barra vertical"] # 0x21ed (en: 'upwards white arrow on pedestal with vertical bar', google: 'arrow blanca hacia arriba en el pedestal con barra vertical') - - "⇮": [T: "flecha doble blanca hacia arriba"] # 0x21ee (en: 'upwards white double arrow', google: 'hacia arriba flecha doble blanca') - - "⇯": [T: "flecha doble blanca hacia arriba sobre un pedestal"] # 0x21ef (en: 'upwards white double arrow on pedestal', google: 'arrow doble blanca hacia arriba en el pedestal') - - "⇰": [T: "flecha blanca hacia la derecha partiendo de un muro"] # 0x21f0 (en: 'rightwards white arrow from wall', google: 'arrow blanca hacia la derecha desde la pared') - - "⇱": [T: "flecha noroeste hacia la intersección"] # 0x21f1 (en: 'north west arrow to corner', google: 'north west arrow a la esquina') - - "⇲": [T: "flecha sudeste hacia la intersección"] # 0x21f2 (en: 'south east arrow to corner', google: 'south east arrow a la esquina') - - "⇳": [T: "flecha blanca vertical"] # 0x21f3 (en: 'up down white arrow', google: 'arrow white arrow') - - "⇴": [T: "flecha derecha con círculo pequeño"] # 0x21f4 (en: 'right arrow with small circle') - - "⇵": [T: "flecha superior hacia la derecha de flecha inferior"] # 0x21f5 (en: 'downwards arrow leftwards of upwards arrow') - - "⇶": [T: "tres flechashacia la derecha"] # 0x21f6 - - ⇷": [T: "flecha hacia la izquierda con trazo vertical"] # 0x21f7 (en: 'leftwards arrow with vertical stroke') - - "⇸": [T: "flecha hacia la derecha con trazo vertical"] # 0x21f8 (en: 'rightwards arrow with vertical stroke') - - "⇹": [T: "flecha izquierda derecha con trazo vertical"] # 0x21f9 (en: 'left right arrow with vertical stroke', google: 'flecha derecha izquierda con carrera vertical') - - "⇺": [T: "flecha hacia la izquierda con doble trazo vertical"] # 0x21fa (en: 'leftwards arrow with double vertical stroke', google: 'flecha hacia la izquierda con trazo vertical doble') - - "⇻": [T: "flecha hacia la derecha con doble trazo vertical"] # 0x21fb (en: 'rightwards arrow with double vertical stroke', google: 'flecha hacia la derecha con trazo vertical doble') - - "⇼": [T: "flecha izquierda derecha con doble trazo vertical"] # 0x21fc (en: 'left right arrow with double vertical stroke', google: 'flecha derecha izquierda con doble carrera vertical') - - "⇽": [T: "flecha hacia la izquierda con punta abierta"] # 0x21fd (en: 'leftwards open headed arrow') - - "⇾": [T: "flecha hacia la derecha con punta abierta"] # 0x21fe (en: 'rightwards open headed arrow') - - "⇿": [T: "flecha izquierda derecha con punta abierta"] # 0x21ff (en: 'left right open headed arrow') - - "∀": [T: "para todo"] # 0x2200 (en: 'for all') - - "∁": # 0x2201 - - test: - if: "$Verbosity!='Terse'" - then: [T: "el"] # (en: 'the', google translation) - - T: "complemento de" # (en: 'complement of') - - "∃": [T: "existe"] # 0x2203 (en: 'there exists') - - "∄": [T: "no existe"] # 0x2204 (en: 'there does not exist') - - "∅": [T: "conjunto vacío"] # 0x2205 (en: 'empty set') - - "∇": # 0x2207 - - test: - if: "$Verbosity!='Terse'" - then: [T: "el"] # (en: 'the', google translation) - - T: "gradiente" # (en: 'gradient of', google: 'gradiente de') - - "∋": [T: "comprende "] # 0x220b (en: 'contains the member') - - "∌": [T: "no comprende"] # 0x220c (en: 'does not contain the member') - - "∍": [T: "comprende "] # 0x220d (en: 'contains the member') - - "∎": [T: "fin de demostración"] # 0x220e (en: 'end of proof') - - "∏": [T: "producto"] # 0x220f (en: 'product') - - "∐": [T: "coproducto"] # 0x2210 (en: 'coproduct') - - "∑": [T: "suma"] # 0x2211 (en: 'sum', SRE: 'sumatorio') - - "−": [T: "menos"] # 0x2212 (en: 'minus') - - "∓": [T: "menos más"] # 0x2213 (en: 'minus or plus') - - "∔": [T: "punto más"] # 0x2214 (en: 'dot plus') - - "∕": [T: "dividido por"] # 0x2215 (en: 'divided by') - - "∖": [T: "menos"] # 0x2216 (en: 'set minus') - - "∗": [T: "asterisco"] # 0x2217 (en: 'times') - - "∙": # 0x2219 - - test: - if: "@data-chem-formula-op" - then: [T: "punto"] # (en: 'dot', google translation) - else: [T: "bala"] # (en: 'times') - - - "∛": # 0x221b - - test: - if: "$Verbosity!='Terse'" - then: [T: "raíz cúbica de"] # (en: 'cube root of') - - "∜": # 0x221c - - test: - if: "$Verbosity!='Terse'" - then: [T: "el"] # (en: 'the', google translation) - - T: "raíz cuarta de" # (en: 'fourth root of') - - "∞": [T: "infinito"] # 0x221e (en: 'infinity') - - "∟": [T: "ángulo recto"] # 0x221f (en: 'right angle') - - "∠": [T: "ángulo"] # 0x2220 (en: 'angle') - - "∡": [T: "ángulo medido"] # 0x2221 (en: 'measured angle') - - "∢": [T: "ángulo esférico"] # 0x2222 (en: 'spherical angle') - - "∧": [T: "y"] # 0x2227 (en: 'and') - - "∨": [T: "o"] # 0x2228 (en: 'or') - - "∩": [T: "intersección"] # 0x2229 (en: 'intersection') - - "∪": [T: "unión"] # 0x222a (en: 'union') - - "∫": [T: "integral"] # 0x222b - - "∬": [T: "integral doble"] # 0x222c (en: 'double integral') - - "∭": [T: "integral triple"] # 0x222d (en: 'triple integral') - - "∮": [T: "integral de contorno"] # 0x222e (en: 'contour integral') - - "∯": [T: "integral de superficie"] # 0x222f (en: 'surface integral') - - "∰": [T: "integral de volumen"] # 0x2230 (en: 'volume integral') - - "∱": [T: "integral de contorno en sentido de las agujas del reloj"] # 0x2231 (en: 'clockwise integral') - - "∲": [T: "integral de contorno en sentido de las agujas del reloj"] # 0x2232 (en: 'clockwise contour integral') - - "∳": [T: "integral de contorno en sentido contrario a las agujas del reloj"] # 0x2233 (en: 'anticlockwise contour integral') - - "∴": [T: "por lo tanto"] # 0x2234 (en: 'therefore') - - "∵": [T: "porque"] # 0x2235 (en: 'because') - - "∸": [T: "punto menos"] # 0x2238 (en: 'dot minus') - - "∹": [T: "exceso"] # 0x2239 (en: 'has excess compared to') - - "∺": # 0x223a - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "geométricamente proporcional a" # (en: 'geometrically proportional to') - - "∻": # 0x223b - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "homotético a" # (en: 'homothetic to') - - "≀": [T: "producto de guirnalda"] # 0x2240 (en: 'wreath product') - - "≁": [T: "no tilde"] # 0x2241 (en: 'not tilde') - - "≂": [T: "menos tilde"] # 0x2242 (en: 'minus tilde') - - "≃": # 0x2243 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "asintóticamente igual a" # (en: 'asymptotically equal to') - - "≄": # 0x2244 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no asintóticamente igual a" # (en: 'not asymptotically equal to') - - "≅": # 0x2245 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "aproximadamente igual a" # (en: 'approximately equal to') - - "≆": # 0x2246 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "aproximado pero no igual a" # (en: 'approximately but not actually equal to') - - "≇": # 0x2247 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "ni proximadamente ni realmente igual a" # (en: 'neither approximately nor actually equal to') - - "≈": # 0x2248 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "casi igual a" # (en: 'almost equal to', SRE: 'aproximado') - - "≉": # 0x2249 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no es casi igual a" # (en: 'not almost equal to') - - "≊": # 0x224a - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "igual o casi igual a" # (en: 'almost equal or equal to') - - "≋": [T: "triple tilde"] # 0x224b - - "≌": [T: "todo igual a"] # 0x224c (en: 'are all equal to') - - "≍": # 0x224d - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "equivalente a" # (en: 'equivalent to') - - "≎": # 0x224e - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "geométricamente equivalente a" # (en: 'geometrically equivalent to') - - "≏": # 0x224f - - test: - if: "$Verbosity!='Terse'" - then: [T: "la"] # (en: 'the', google translation) - - T: "diferencia entre" # (en: 'difference between') - - "≐": [T: "se acerca al límite"] # 0x2250 (en: 'approaches the limit') - - "≑": # 0x2251 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "geométricamente igual a" # (en: 'geometrically equal to') - - "≒": # 0x2252 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "aproximadamente igual a o imagen de" # (en: 'approximately equal to or the image of') - - "≓": # 0x2253 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es la"] # (en: 'is the', google translation) - - T: "imagen de o aproximadamente igual a" # (en: 'image of or approximately equal to') - - "≔": [T: "dos puntos igual"] # 0x2254 (en: 'colon equals') - - "≕": [T: "igual dos puntos"] # 0x2255 (en: 'equals colon') - - "≖": [T: "igual incluyendo anillo"] # 0x2256 (en: 'ring in equal to') - - "≗": # 0x2257 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "aproximadamente igual a" # (en: 'approximately equal to') - - "≘": [T: "corresponde a"] # 0x2258 (en: 'corresponds to') - - "≙": [T: "estimación"] # 0x2259 (en: 'estimates') - - "≚": # 0x225a - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "equiángulo con" # (en: 'equiangular to') - - "≛": [T: "igual con estrella"] # 0x225b (en: 'star equals') - - "≜": [T: "delta igual a"] # 0x225c (en: 'delta equals') - - "≝": [T: "igual por definición a"] # 0x225d (en: 'is defined to be') - - "≞": # 0x225e - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "medido por" # (en: 'measured by') - - "≟": [T: "igual con interrogante"] # 0x225f (en: 'has an unknown relationship with') - - "≢": # 0x2262 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no es idéntico a" # (en: 'not identical to') - - "≣": # 0x2263 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "estrictamente equivalente a" # (en: 'strictly equivalent to') - - "≨": # 0x2268 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "menor que pero no igual a" # (en: 'less than but not equal to') - - "≩": # 0x2269 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "mayor que pero no igual a" # (en: 'greater than but not equal to') - - "≪": # 0x226a - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "mucho menor que" # (en: 'much less than') - - "≫": # 0x226b - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "mucho mayor que" # (en: 'much greater than') - - "≬": # 0x226c - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "entre" # (en: 'between') - - "≭": # 0x226d - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no equivalente a" # (en: 'not equivalent to') - - "≮": # 0x226e - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no menor que" # (en: 'not less than') - - "≯": # 0x226f - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no mayor que" # (en: 'not greater than') - - "≰": # 0x2270 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no menor ni igual a" # (en: 'neither less than nor equal to') - - "≱": # 0x2271 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no mayor ni igual a" # (en: 'neither greater than nor equal to') - - "≲": # 0x2272 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "menor o equivalente a" # (en: 'less than or equivalent to') - - "≳": # 0x2273 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "mayor o equivalente a" # (en: 'greater than or equivalent to') - - "≴": # 0x2274 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no menor ni equivalente a" # (en: 'neither less than nor equivalent to') - - "≵": # 0x2275 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no mayor ni equivalente a" # (en: 'neither greater than nor equivalent to') - - "≶": # 0x2276 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "menor o mayor que" # (en: 'less than or greater than') - - "≷": # 0x2277 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "mayor o menor que" # (en: 'greater than or less than') - - "≸": # 0x2278 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no menor ni mayor que" # (en: 'neither less than nor greater than') - - "≹": # 0x2279 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no mayor ni menor que" # (en: 'neither greater than nor less than') - - "≺": [T: "precede a"] # 0x227a (en: 'precedes') - - "≻": [T: "sigue a"] # 0x227b (en: 'succeeds') - - "≼": [T: "precede o es igual a"] # 0x227c (en: 'precedes or is equal to') - - "≽": [T: "sigue o es igual a"] # 0x227d (en: 'succeeds or is equal to') - - "≾": [T: "precede o es equivalente a"] # 0x227e (en: 'precedes or is equivalent to') - - "≿": [T: "sigue o es equivalente a"] # 0x227f (en: 'succeeds or is equivalent to') - - "⊀": [T: "no precede a"] # 0x2280 (en: 'does not precede') - - "⊁": [T: "no sigue a"] # 0x2281 (en: 'does not succeed') - - "⊈": # 0x2288 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no incluido ni igual a" # (en: 'neither a subset of nor equal to') - - "⊉": # 0x2289 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no contiene ni es igual a" # (en: 'neither a superset of nor equal to') - - "⊊": [T: "incluido estrictamente en"] # 0x228a (en: 'subset of with not equal to') - - "⊋": [T: "contiene estrictamente a"] # 0x228b (en: 'superset of with not equal to') - - "⊌": [T: "multiconjunto"] # 0x228c (en: 'multiset') - - "⊍": [T: "multiplicación de multiconjuntos"] # 0x228d (en: 'multiset multiplication') - - "⊎": [T: "unión de multiconjuntos"] # 0x228e (en: 'multiset union') - - "⊏": [T: "imagen cuadrada de"] # 0x228f (en: 'square image of') - - "⊐": [T: "original cuadrado de"] # 0x2290 (en: 'square original of') - - "⊑": [T: "imagen cuadrada de o igual a"] # 0x2291 (en: 'square image of or equal to') - - "⊒": [T: "original cuadrado de o igual a"] # 0x2292 (en: 'square original of or equal to') - - "⊓": [T: "intersección cuadrada"] # 0x2293 (en: 'square cap') - - "⊔": [T: "unión cuadrada"] # 0x2294 (en: 'square cup') - - "⊕": [T: "signo más en forma de círculo"] # 0x2295 (en: 'circled plus') - - "⊖": [T: "signo menos en forma de círculo"] # 0x2296 (en: 'circled minus') - - "⊗": [T: "signo por en forma de círculo"] # 0x2297 (en: 'circled times') - - "⊘": [T: "barra en forma de círculo"] # 0x2298 (en: 'circled slash') - - "⊙": [T: "punto en forma de círculo"] # 0x2299 (en: 'circled dot operator') - - "⊚": [T: "anillo en círculo"] # 0x229a (en: 'circled ring') - - "⊛": [T: "asterisco en círculo"] # 0x229b (en: 'circled asterisk') - - "⊜": [T: "signo igual en círculo"] # 0x229c (en: 'circled equals') - - "⊝": [T: "signo menos en círculo"] # 0x229d (en: 'circled dash') - - "⊞": [T: "signo más en forma de cuadrado"] # 0x229e (en: 'squared plus') - - "⊟": [T: "menos en forma de cuadrado"] # 0x229f (en: 'squared minus') - - "⊠": [T: "signo por en forma de cuadrado"] # 0x22a0 (en: 'squared times') - - "⊡": [T: "punto en forma de cuadrado"] # 0x22a1 (en: 'squared dot operator') - - "⊢": [T: "t horizontal hacia la izquierda"] # 0x22a2 (en: 'proves') - - "⊣": [T: "t horizontal hacia la derecha"] # 0x22a3 (en: 'does not yield') - - "⊤": [T: "perpendicular"] # 0x22a4 (en: 'top') - - "⊥": # 0x22a5 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "perpendicular invertida" # (en: 'bottom') - - "⊦": [T: "afirmación"] # 0x22a6 (en: 'reduces to') - - "⊧": [T: "modela"] # 0x22a7 (en: 'models') - - "⊨": # 0x22a8 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "verdadero" # (en: 'true') - - "⊩": [T: "obliga"] # 0x22a9 (en: 'forces') - - "⊪": [T: "triple barra vertical torniquete a la derecha"] # 0x22aa (en: 'triple vertical bar right turnstile') - - "⊫": [T: "doble barra vertical con doble torniquete a la derecha"] # 0x22ab (en: 'double vertical bar double right turnstile') - - "⊬": [T: "no demuestra"] # 0x22ac (en: 'does not prove') - - "⊭": # 0x22ad - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "falso" # (en: 'not true') - - "⊮": [T: "no obliga"] # 0x22ae (en: 'does not force') - - "⊯": [T: "doble barra vertical negada con doble torniquete a la derecha"] # 0x22af (en: 'negated double vertical bar double right turnstile') - - "⊰": [T: "precede con respecto a"] # 0x22b0 (en: 'precedes under relation') - - "⊱": [T: "sigue con respecto a"] # 0x22b1 (en: 'succeeds under relation') - - "⊲": # 0x22b2 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "subgrupo normal de" # (en: 'a normal subgroup of') - - "⊳": [T: "contiene como subgrupo normal a"] # 0x22b3 (en: 'contains as a normal subgroup') - - "⊴": # 0x22b4 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "subgrupo normal o es igual a" # (en: 'a normal subgroup of or equal to') - - "⊵": [T: "contiene como subgrupo normal o es igual a"] # 0x22b5 (en: 'contains as a normal subgroup or equal to') - - "⊶": # 0x22b6 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "el original de" # (en: 'the original of') - - "⊷": # 0x22b7 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "imagen de" # (en: 'an image of') - - "⊸": [T: "multifunción"] # 0x22b8 (en: 'multimap') - - "⊹": [T: "matriz hermitiana conjugada"] # 0x22b9 (en: 'hermitian conjugate matrix') - - "⊺": [T: "intercalada"] # 0x22ba (en: 'intercalate') - - "⊻": [T: "o excluyente"] # 0x22bb (en: 'xor') - - "⊼": [T: "no y"] # 0x22bc (en: 'nand') - - "⊽": [T: "no o"] # 0x22bd (en: 'nor') - - "⊾": [T: "ángulo recto con arco"] # 0x22be (en: 'right angle with arc') - - "⊿": [T: "triángulo rectángulo"] # 0x22bf (en: 'right triangle') - - "⋀": [T: "y"] # 0x22c0 (en: 'logical and') - - "⋁": [T: "o"] # 0x22c1 (en: 'logical or') - - "⋂": [T: "intersección"] # 0x22c2 (en: 'intersection') - - "⋃": [T: "unión"] # 0x22c3 (en: 'union') - - "⋄": [T: "operador diamante"] # 0x22c4 (en: 'diamond operator') - - "⋅": # 0x22c5 - - test: - if: "@data-chem-formula-op" - then: [T: "punto"] # (en: 'dot', google translation) - else: [T: "punto"] # (en: 'times') - - - "⋆": [T: "operador estrella"] # 0x22c6 (en: 'times') - - "⋇": [T: "dividido por"] # 0x22c7 (en: 'division times') - - "⋈": [T: "moño"] # 0x22c8 (en: 'bowtie') - - "⋉": # 0x22c9 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "factor normal izquierdo producto semidirecto" # (en: 'the left normal factor semidirect product of') - - "⋊": # 0x22ca - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "factor normal derecho producto semidirecto" # (en: 'the right normal factor semidirect product of') - - "⋋": # 0x22cb - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "producto semidirecto izquierdo" # (en: 'the left semidirect product of') - - "⋌": # 0x22cc - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "producto semidirecto derecho" # (en: 'the right semidirect product of') - - "⋍": [T: "tilde invertida igual a"] # 0x22cd (en: 'reversed tilde equals') - - "⋎": [T: "o rotacional"] # 0x22ce (en: 'curly logical or') - - "⋏": [T: "y rotacional"] # 0x22cf (en: 'curly logical and') - - "⋐": # 0x22d0 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "subconjunto doble de" # (en: 'a double subset of') - - "⋑": # 0x22d1 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "superconjunto doble de" # (en: 'a double superset of') - - "⋒": # 0x22d2 - - test: - if: "$Verbosity!='Terse'" - then: [T: "la"] # (en: 'the', google translation) - - T: "doble intersección" # (en: 'double intersection of') - - "⋓": # 0x22d3 - - test: - if: "$Verbosity!='Terse'" - then: [T: "la"] # (en: 'the', google translation) - - T: "doble unión" # (en: 'double union of') - - "⋔": # 0x22d4 - - test: - if: "$Verbosity!='Terse'" - then: [T: "el"] # (en: 'the', google translation) - - T: "intersección propia de" # (en: 'proper intersection of') - - "⋕": # 0x22d5 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "paralela o igual a" # (en: 'equal to and parallel to') - - "⋖": [T: "menor que con punto"] # 0x22d6 (en: 'less than with dot') - - "⋗": [T: "mayor que con punto"] # 0x22d7 (en: 'greater than with dot') - - "⋘": # 0x22d8 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "mucho menor que" # (en: 'very much less than') - - "⋙": # 0x22d9 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "mucho mayor que" # (en: 'very much greater than') - - "⋚": # 0x22da - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "menor que igual a o mayor que" # (en: 'less than equal to or greater than') - - "⋛": # 0x22db - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "mayor que igual a o menor que" # (en: 'greater than equal to or less than') - - "⋜": # 0x22dc - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "menor o igual que" # (en: 'equal to or less than') - - "⋝": # 0x22dd - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "mayor o igual que" # (en: 'equal to or greater than') - - "⋞": # 0x22de - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "precede o es igual a" # (en: 'equal to or precedes') - - "⋟": # 0x22df - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "sigue o es igual a" # (en: 'equal to or succeeds') - - "⋠": [T: "no precede ni es igual a"] # 0x22e0 (en: 'does not precede nor is equal to') - - "⋡": [T: "no sigue ni es igual a"] # 0x22e1 (en: 'does not succeed nor is equal to') - - "⋢": [T: "no es imagen cuadrada ni igual a"] # 0x22e2 (en: 'not square image of or equal to') - - "⋣": [T: "no es original cuadrada ni igual a"] # 0x22e3 (en: 'not square original of or equal to') - - "⋤": [T: "imagen cuadrada precisa"] # 0x22e4 (en: 'square image of or not equal to') - - "⋥": [T: "cuadrada original precisa"] # 0x22e5 (en: 'square original of or not equal to') - - "⋦": # 0x22e6 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "menor que no equivalente a" # (en: 'less than but not equivalent to') - - "⋧": # 0x22e7 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "mayor que no equivalente a" # (en: 'greater than but not equivalent to') - - "⋨": [T: "precede pero no es equivalente a"] # 0x22e8 (en: 'precedes but is not equivalent to') - - "⋩": [T: "sigue pero no es equivalente a"] # 0x22e9 (en: 'succeeds but is not equivalent to') - - "⋪": # 0x22ea - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no subgrupo normal de" # (en: 'not a normal subgroup of') - - "⋫": [T: "no contiene como subgrupo normal a"] # 0x22eb (en: 'does not contain as a normal subgroup') - - "⋬": # 0x22ec - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no es subgrupo normal ni igual a" # (en: 'not a normal subgroup of nor is equal to') - - "⋭": [T: "no contiene como subgrupo normal ni es igual a"] # 0x22ed (en: 'does not contain as a normal subgroup nor is equal to') - - "⋮": [T: "puntos suspensivos verticales"] # 0x22ee (en: 'vertical ellipsis') - - "⋯": [T: "puntos suspensivos altos"] # 0x22ef (en: 'dot dot dot') - - "⋰": [T: "puntos suspensivos diagonales hacia arriba"] # 0x22f0 (en: 'upwards diagonal ellipsis') - - "⋱": [T: "puntos suspensivos diagonales hacia abajo"] # 0x22f1 (en: 'diagonal ellipsis') - - "⋲": [T: "pertenece a con trazo horizontal"] # 0x22f2 (en: 'element of with long horizontal stroke') - - "⋳": [T: "pertenece a con barra vertical al final del trazo horizontal"] # 0x22f3 (en: 'element of with vertical bar at end of horizontal stroke') - - "⋴": [T: "pertenece a con barra vertical al final del trazo horizontal"] # 0x22f4 (en: 'element of with vertical bar at end of horizontal stroke') - - "⋵": [T: "pertenece a con punto arriba"] # 0x22f5 (en: 'element of with dot above') - - "⋶": [T: "pertenece a con barra arriba"] # 0x22f6 (en: 'element of with overbar') - - "⋷": [T: "perteneciente subrayado"] # 0x22f7 (en: 'element of with overbar') - - "⋸": [T: "perteneciente subrayado"] # 0x22f8 (en: 'element of with underbar') - - "⋹": [T: "pertenece con dos trazos horizontales"] # 0x22f9 (en: 'element of with two horizontal strokes') - - "⋺": [T: "contiene o es igual a"] # 0x22fa (en: 'contains with long horizontal stroke') - - "⋻": [T: "contiene barra vertical al final de trazo horizontal"] # 0x22fb (en: 'contains with vertical bar at end of horizontal stroke') - - "⋼": [T: "contiene barra vertical al final de trazo horizontal"] # 0x22fc (en: 'contains with vertical bar at end of horizontal stroke') - - "⋽": [T: "contiene barra superior"] # 0x22fd (en: 'contains with overbar') - - "⋾": [T: "incluye barra superior"] # 0x22fe (en: 'contains with overbar') - - "⋿": [T: "z anotación pertenencia a bolsa"] # 0x22ff (en: 'z notation bag membership') - - "⌀": [T: "diámetro"] # 0x2300 (en: 'diameter') - - "⌁": [T: "flecha eléctrica"] # 0x2301 (en: 'electric arrow', google: 'flecha eléctrica') - - "⌂": [T: "casa"] # 0x2302 (en: 'house') - - "⌃": [T: "flecha arriba"] # 0x2303 (en: 'up arrowhead', google: 'arrowhead de flecha') - - "⌄": [T: "flecha con punta hacia abajo"] # 0x2304 (en: 'down arrowhead', google: 'abajo de arrowhead') - - "⌅": [T: "proyectiva"] # 0x2305 (en: 'projective') - - "⌆": [T: "perspectiva"] # 0x2306 (en: 'perspective') - - "⌇": [T: "línea ondulada"] # 0x2307 (en: 'wavy line') - - "⌈": [T: "límite superior izquierdo"] # 0x2308 (en: 'left ceiling') - - "⌉": [T: "límite superior derecho"] # 0x2309 (en: 'right ceiling') - - "⌊": [T: "límite inferior izquierdo"] # 0x230a (en: 'left floor') - - "⌋": [T: "límite inferior derecho"] # 0x230b (en: 'right floor') - - "⌌": [T: "corte inferior derecho"] # 0x230c (en: 'bottom right crop') - - "⌍": [T: "corte inferior izquierdo"] # 0x230d (en: 'bottom left crop') - - "⌎": [T: "corte superior derecho "] # 0x230e (en: 'top right crop', MathPlayer: 'corte superior derecho', google: 'cropa de arriba a la derecha') - - "⌏": [T: "corte superior izquierdo"] # 0x230f (en: 'top left crop') - - "⌐": [T: "no invertido"] # 0x2310 (en: 'reversed not sign') - - "⌑": [T: "rombo cuadrado"] # 0x2311 (en: 'square lozenge', google: 'pombra cuadrada') - - "⌒": [T: "arco"] # 0x2312 (en: 'arc') - - "⌓": [T: "segmento"] # 0x2313 (en: 'segment') - - "⌔": [T: "sector"] # 0x2314 - - "⌕": [T: "grabadora telefónica"] # 0x2315 (en: 'telephone recorder', google: 'recordadora telefónica') - - "⌖": [T: "indicador de posición"] # 0x2316 (en: 'position indicator crosshairs', google: 'posición indicador de mira') - - "⌗": [T: "viewdata square"] # 0x2317 (google translation) - - "⌘": [T: "lugar del signo de interés"] # 0x2318 (en: 'place of interest sign', google: 'señal de lugar de interés') - - "⌙": [T: "signo no invertido"] # 0x2319 (en: 'turned not sign', google translation) - - "⌚": [T: "reloj"] # 0x231a (en: 'watch', google: 'mirar') - - "⌛": [T: "reloj de arena"] # 0x231b (en: 'hourglass', google translation) - - "⌜": [T: "ángulo superior izquierdo"] # 0x231c (en: 'top left corner') - - "⌝": [T: "ángulo superior derecho"] # 0x231d (en: 'top right corner') - - "⌞": [T: "ángulo inferior izquierdo"] # 0x231e (en: 'bottom left corner') - - "⌟": [T: "ángulo inferior derecho"] # 0x231f (en: 'bottom right corner') - - "⌠": [T: "mitad superior de integral"] # 0x2320 (en: 'top half integral') - - "⌡": [T: "mitad inferior de integral"] # 0x2321 (en: 'bottom half integral') - - "⌢": [T: "ceño fruncido"] # 0x2322 (en: 'frown', google: 'fruncir el ceño') - - "⌣": [T: "sonrisa"] # 0x2323 (en: 'smile') - - "⌤": [T: "flecha arriba entre dos barras horizontales"] # 0x2324 (en: 'up arrowhead between two horizontal bars', google: 'arrowehead de flecha entre dos barras horizontales') - - "⌥": [T: "clave de opción"] # 0x2325 (en: 'option key', google translation) - - "⌦": [T: "borrar hacia la derecha"] # 0x2326 (en: 'erase to the right', google translation) - - "⌧": [T: "x en un rectángulo"] # 0x2327 (en: 'x in a rectangle box', google translation) - - "⌨": [T: "teclado"] # 0x2328 (en: 'keyboard', google translation) - - "〈": [T: "paréntesis angular izquierdo"] # 0x2329 (en: 'left pointing angle bracket') - - "〉": [T: "paréntesis angular derecho"] # 0x232a (en: 'right pointing angle bracket') - - "⌫": [T: "borrar hacia la izquierda"] # 0x232b (en: 'erase to the left', google translation) - - "⌬": [T: "anillo de benceno"] # 0x232c (en: 'benzene ring', google translation) - - "⌭": [T: "cilindro"] # 0x232d (en: 'cylindricity') - - "⌮": [T: "perfil"] # 0x232e (en: 'all around profile', google: 'alrededor de perfil') - - "⌯": [T: "simetría"] # 0x232f (en: 'symmetry', google translation) - - "⌰": [T: "desviación total"] # 0x2330 (en: 'total runout', google translation) - - "⌱": [T: "origen de dimensión"] # 0x2331 (en: 'dimension origin', google translation) - - "⌲": [T: "cónico cónico"] # 0x2332 (en: 'conical taper', google translation) - - "⌳": [T: "pendiente"] # 0x2333 (en: 'slope', google translation) - - "⌴": [T: "contrataladro"] # 0x2334 (en: 'counterbore', google translation) - - "⌵": [T: "avellanador"] # 0x2335 (en: 'countersink', google translation) - - "⍰": [T: "interrogación en caja"] # 0x2370 (en: 'unknown box', google: 'caja desconocida') - - "⎕": [T: "caja"] # 0x2395 (en: 'box', google translation) - - "⏞": [T: "corchete rotacional superior"] # 0x23DE (en: 'top brace') - - "⏟": [T: "corchete rotacional inferior"] # 0x23DF (en: 'bottom brace') - - "①-⑨": # 0x2460 - 0x2469 - - T: "corchete rotacional inferior" # (en: 'circled') - - spell: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" - - "⑩": [T: "diez en un círculo"] # 0x2469 (en: 'circled ten', google translation) - - "⑪": [T: "once en un círculo"] # 0x246a (en: 'circled eleven', google translation) - - "⑫": [T: "doce en un círculo"] # 0x246b (en: 'circled twelve', google translation) - - "⑬": [T: "trece en un círculo"] # 0x246c (en: 'circled thirteen', google translation) - - "⑭": [T: "catorce en un círculo"] # 0x246d (en: 'circled fourteen', google translation) - - "⑮": [T: "quince en un círculo"] # 0x246e (en: 'circled fifteen', google translation) - - "⑯": [T: "dieciséis en un círculo"] # 0x246f (en: 'circled sixteen', google translation) - - "⑰": [T: "diecisiete en un círculo"] # 0x2470 (en: 'circled seventeen', google translation) - - "⑱": [T: "dieciocho en un círculo"] # 0x2471 (en: 'circled eighteen', google translation) - - "⑱": [T: "diecinueve en un círculo"] # 0x2471 (en: 'circled nineteen', google translation) - - "⑳": [T: "veinte en un círculo"] # 0x2473 (en: 'circled twenty', google translation) - - "⑴-⑼": # 0x2474 - 0x247d - - T: "entre paréntesis" # (en: 'parenthesized', google translation) - - spell: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" - - "⑽": [T: "diez entre paréntesis"] # 0x247d (en: 'parenthesized ten', google translation) - - "⑾": [T: "once entre paréntesis"] # 0x247e (en: 'parenthesized eleven', google translation) - - "⑿": [T: "doce entre paréntesis"] # 0x247f (en: 'parenthesized twelve', google translation) - - "⒀": [T: "trece entre paréntesis"] # 0x2480 (en: 'parenthesized thirteen', google translation) - - "⒁": [T: "catorce entre paréntesis"] # 0x2481 (en: 'parenthesized fourteen', google translation) - - "⒂": [T: "quince entre paréntesis"] # 0x2482 (en: 'parenthesized fifteen', google translation) - - "⒃": [T: "dieciséis entre paréntesis"] # 0x2483 (en: 'parenthesized sixteen', google translation) - - "⒄": [T: "diecisiete entre paréntesis"] # 0x2484 (en: 'parenthesized seventeen', google translation) - - "⒅": [T: "dieciocho entre paréntesis"] # 0x2485 (en: 'parenthesized eighteen', google translation) - - "⒆": [T: "diecinueve entre paréntesis"] # 0x2486 (en: 'parenthesized nineteen', google translation) - - "⒇": [T: "veinte entre paréntesis"] # 0x2487 (en: 'parenthesized twenty', google translation) - - "⒈-⒐": # 0x2488 - 0x2491 - - spell: "translate('.', '⒈⒉⒊⒋⒌⒍⒎⒏⒐', '123456789')" - - T: "con periodo" # (en: 'with period', google translation) - - "⒑": [T: "diez con signo de periodo"] # 0x2491 (en: 'ten with period', google translation) - - "⒒": [T: "once con signo de periodo"] # 0x2492 (en: 'eleven with period', google translation) - - "⒓": [T: "doce con signo de periodo"] # 0x2493 (en: 'twelve with period', google translation) - - "⒔": [T: "trece con signo de periodo"] # 0x2494 (en: 'thirteen with period', google translation) - - "⒕": [T: "catorce con signo de periodo"] # 0x2495 (en: 'fourteen with period', google translation) - - "⒖": [T: "quince con signo de periodo"] # 0x2496 (en: 'fifteen with period', google translation) - - "⒗": [T: "dieciséis con signo de periodo"] # 0x2497 (en: 'sixteen with period', google translation) - - "⒘": [T: "diecisiete con signo de periodo"] # 0x2498 (en: 'seventeen with period', google translation) - - "⒙": [T: "dieciocho con signo de periodo"] # 0x2499 (en: 'eighteen with period', google translation) - - "⒚": [T: "diecinueve con signo de periodo"] # 0x249a (en: 'nineteen with period', google translation) - - "⒛": [T: "veinte con signo de periodo"] # 0x249b (en: 'twenty with period', google translation) - - "⒜-⒵": # 0x249c - 0x24b5 - - T: "entre paréntesis" # (en: 'parenthesized', google translation) - - spell: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" - - - "Ⓐ-Ⓩ": - - T: "dentro de uncírculo" # (en: 'circled', google translation) - - spell: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "🅐-🅩": # 0x1f150 - 0x1f169 - - T: "dentro de un círculo negro" # (en: 'black circled', google translation) - - spell: "translate('.', '🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 - - T: "dentro de un círculo" # (en: 'circled', google translation) - - spell: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" - - "⓪": [T: "cero en un círculo"] # 0x24ea (en: 'circled zero', google translation) - - "⓫": [T: "once en un círculo negro"] # 0x24eb (google translation) - - "⓬": [T: "doce en un círculo negro"] # 0x24ec (en: 'black circled twelve', google translation) - - "⓭": [T: "trece en un círculo negro"] # 0x24ed (en: 'black circled thirteen', google translation) - - "⓮": [T: "catorce en un círculo negro"] # 0x24ee (en: 'black circled fourteen', google translation) - - "⓯": [T: "quince en un círculo negro"] # 0x24ef (en: 'black circled fifteen', google translation) - - "⓰": [T: "dieciséis en un círculo negro"] # 0x24f0 (en: 'black circled sixteen', google translation) - - "⓱": [T: "diecisiete en un círculo negro"] # 0x24f1 (en: 'black circled seventeen', google translation) - - "⓲": [T: "dieciocho en un círculo negro"] # 0x24f2 (en: 'black circled eighteen', google translation) - - "⓳": [T: "diecinueve en un círculo negro"] # 0x24f3 (en: 'black circled nineteen', google translation) - - "⓴": [T: "veinte en un círculo negro"] # 0x24f4 (en: 'black circled twenty', google translation) - - "⓵-⓽": # 0x24f5 - 0x24fe - - T: "doble círculo" # (en: 'double circled', google translation) - - spell: "translate('.', '⓵⓶⓷⓸⓹⓺⓻⓼⓽', '123456789')" - - "⓾": [T: "diez en un doble círculo"] # 0x24fe (en: 'double circled ten', google translation) - - "⓿": [T: "cero en círculo negro"] # 0x24ff (en: 'black circled zero', google translation) - - "■": [T: "cuadrado negro"] # 0x25a0 (en: 'black square') - - "□": [T: "cuadrado blanco"] # 0x25a1 (en: 'white square') - - "▢": [T: "cuadrado blanco con esquinas redondeadas"] # 0x25a2 (en: 'white square with rounded corners') - - "▣": [T: "cuadrado blanco que contiene cuadrado pequeño negro"] # 0x25a3 (en: 'white square containing small black square', google: 'cuadrado blanco que contiene un pequeño cuadrado negro') - - "▤": [T: "cuadrado con relleno horizontal"] # 0x25a4 (en: 'square with horizontal fill') - - "▥": [T: "cuadrado con relleno vertical"] # 0x25a5 (en: 'square with vertical fill') - - "▦": [T: "cuadrado con relleno octogonal de rayas"] # 0x25a6 (en: 'square with orthogonal crosshatch fill', google: 'cuadrado con relleno ortogonal de muñeca') - - "▧": [T: "cuadrado con la esquina superior izquierda hacia la parte derecha inferior del relleno"] # 0x25a7 (en: 'square with upper left to lower right fill', google: 'cuadrado con la parte superior izquierda a la parte inferior del relleno derecho') - - "▨": [T: "cuadrado con la parte superior derecha hacia la parte inferior izquierda del relleno"] # 0x25a8 (en: 'square with upper right to lower left fill', google: 'cuadrado con la parte superior derecha a la parte inferior izquierda del relleno') - - "▩": [T: "cuadrado con relleno diagonal rayado"] # 0x25a9 (en: 'square with diagonal crosshatch fill', google: 'cuadrado con relleno de shatch diagonal') - - "▪": [T: "cuadrado pequeño negro"] # 0x25aa (en: 'black small square') - - "▫": [T: "cuadrado pequeño blanco"] # 0x25ab (en: 'white small square') - - "▬": [T: "rectángulo negro"] # 0x25ac (en: 'black rectangle') - - "▭": [T: "rectángulo blanco"] # 0x25ad (en: 'white rectangle') - - "▮": [T: "rectángulo relleno vertical"] # 0x25ae (en: 'black vertical rectangle') - - "▯": [T: "rectángulo vertical blanco"] # 0x25af (en: 'white vertical rectangle') - - "▰": [T: "paralelogramo negro"] # 0x25b0 (en: 'black parallelogram', google: 'paralelograma negro') - - "▱": [T: "paralelogramo blanco"] # 0x25b1 (en: 'white parallelogram') - - "▲": [T: "triángulo negro apuntando hacia arriba"] # 0x25b2 (en: 'black up pointing triangle') - - "△": [T: "triángulo blanco apuntando hacia arriba"] # 0x25b3 (en: 'white up pointing triangle') - - "▴": [T: "triángulo negro pequeño apuntando hacia arriba"] # 0x25b4 (en: 'black up pointing small triangle') - - "▵": [T: "triángulo blanco pequeño apuntando hacia arriba"] # 0x25b5 (en: 'white up pointing small triangle') - - "▶": [T: "triángulo negro apuntando hacia la derecha"] # 0x25b6 (en: 'black right pointing triangle') - - "▷": [T: "triángulo blanco apuntando hacia la derecha"] # 0x25b7 (en: 'white right pointing triangle') - - "▸": [T: "triángulonegro pequeño apuntando hacia la derecha"] # 0x25b8 (en: 'black right pointing small triangle') - - "▹": [T: "triángulo blanco pequeño apuntando hacia la derecha"] # 0x25b9 (en: 'white right pointing small triangle') - - "►": [T: "indicador negro apuntando a la derecha"] # 0x25ba (en: 'black right pointing pointer', google: 'puntero de punta derecha negra') - - "▻": [T: "indicador blanco apuntando hacia la derecha"] # 0x25bb (en: 'white right pointing pointer', google: 'puntero de punta derecha blanca') - - "▼": [T: "triángulo negro apuntando hacia abajo"] # 0x25bc (en: 'black down pointing triangle') - - "▽": [T: "triángulo blanco apuntando hacia abajo"] # 0x25bd (en: 'white down pointing triangle') - - "▾": [T: "pequeño triángulo negro apuntando hacia abajo"] # 0x25be (en: 'black down pointing small triangle') - - "▿": [T: "triángulo pequeño blanco apuntando hacia abajo"] # 0x25bf (en: 'white down pointing small triangle') - - "◀": [T: "triángulo negro apuntando hacia la izquierda"] # 0x25c0 (en: 'black left pointing triangle') - - "◁": [T: "triángulo blanco apuntando hacia la izquierda"] # 0x25c1 (en: 'white left pointing triangle') - - "◂": [T: "pequeño triángulo negro apuntando hacia la izquierda izquierda"] # 0x25c2 (en: 'black left pointing small triangle') - - "◃": [T: "pequeño triángulo blanco apuntando hacia la izquierda"] # 0x25c3 (en: 'white left pointing small triangle') - - "◄": [T: "puntero negro apuntando hacia la izquierda"] # 0x25c4 (en: 'black left pointing pointer') - - "◅": [T: "puntero blanco apuntando hacia la izquierda"] # 0x25c5 (en: 'white left pointing pointer') - - "◆": [T: "rombo negro"] # 0x25c6 (en: 'black diamond') - - "◇": [T: "rombo blanco"] # 0x25c7 (en: 'white diamond') - - "◈": [T: "rombo blanco contiene rombo pequeño negro"] # 0x25c8 (en: 'white diamond containing black small diamond') - - "◉": [T: "ojo de pez"] # 0x25c9 (en: 'fisheye') - - "◊": [T: "rombo"] # 0x25ca (en: 'lozenge') - - "○": [T: "círculo blanco"] # 0x25cb (en: 'white circle') - - "◌": [T: "círculo punteado"] # 0x25cc (en: 'dotted circle') - - "◍": [T: "círculo con relleno vertical"] # 0x25cd (en: 'circle with vertical fill') - - "◎": [T: "diana"] # 0x25ce (en: 'bullseye') - - "●": [T: "círculo negro"] # 0x25cf (en: 'black circle') - - "◐": [T: "círculo con mitad izquierda negra"] # 0x25d0 (en: 'circle with left half black') - - "◑": [T: "círculo con mitad derecha negra"] # 0x25d1 (en: 'circle with right half black') - - "◒": [T: "círculo con mitad inferior negra"] # 0x25d2 (en: 'circle with lower half black') - - "◓": [T: "círculo con mitad superior negra"] # 0x25d3 - - "◔": [T: "círculo con cuadrante superior derecho relleno"] # 0x25d4 (en: 'circle with upper right quadrant black') - - "◕": [T: "círculo con cuadrante superior izquierdo negro"] # 0x25d5 (en: 'circle with all but upper left quadrant black') - - "◖": [T: "semicírculo izquierdo negro"] # 0x25d6 (en: 'left half black circle') - - "◗": [T: "semicírculo derecho negro"] # 0x25d7 (en: 'right half black circle') - - "◘": [T: "viñeta inversa"] # 0x25d8 (en: 'inverse bullet') - - "◙": [T: "círculo blanco inverso"] # 0x25d9 (en: 'inverse white circle') - - "◚": [T: "semicírculo superior blanco inverso"] # 0x25da (en: 'upper half inverse white circle') - - "◛": [T: "semicírculo inferior blanco inverso"] # 0x25db (en: 'lower half inverse white circle') - - "◜": [T: "cuadrante superior izquierdo arco circular"] # 0x25dc (en: 'upper left quadrant circular arc') - - "◝": [T: "cuadrante superior derecho arco circular"] # 0x25dd (en: 'upper right quadrant circular arc') - - "◞": [T: "cuadrante inferior derecho arco circular"] # 0x25de (en: 'lower right quadrant circular arc') - - "◟": [T: "cuadrante inferior izquierdo arco circular"] # 0x25df (en: 'lower left quadrant circular arc') - - "◠": [T: "semicírculo superior"] # 0x25e0 (en: 'upper half circle') - - "◡": [T: "semicírculo inferior"] # 0x25e1 (en: 'lower half circle') - - "◢": [T: "triángulo inferior derecha relleno"] # 0x25e2 (en: 'black lower right triangle') - - "◣": [T: "triángulo negro inferior izquierdo"] # 0x25e3 (en: 'black lower left triangle') - - "◤": [T: "triángulo negro superior izquierdo"] # 0x25e4 (en: 'black upper left triangle') - - "◥": [T: "triángulo negro superior derecho"] # 0x25e5 (en: 'black upper right triangle') - - "◦": [T: "composición"] # 0x25e6 (en: 'composition') - - "◧": [T: "cuadrado con mitad izquierda negra"] # 0x25e7 (en: 'square with left half black') - - "◨": [T: "cuadrado con mitad derecha negra"] # 0x25e8 (en: 'square with right half black') - - "◩": [T: "cuadrado con mitad superior izquierda negra"] # 0x25e9 (en: 'square with upper left half black') - - "◪": [T: "cuadrado con mitad inferior derecha negra"] # 0x25ea (en: 'square with lower right half black') - - "◫": [T: "cuadrado blanco con bisectriz"] # 0x25eb (en: 'white square with bisecting line') - - "◬": [T: "triángulo blanco apuntando hacia arriba con punto"] # 0x25ec (en: 'white up pointing triangle with dot') - - "◭": [T: "triángulo apuntando hacia arriba con mitad izquierda negra"] # 0x25ed (en: 'up pointing triangle with left half black') - - "◮": [T: "triángulo apuntando hacia arriba con mitad derecha negra"] # 0x25ee (en: 'up pointing triangle with right half black') - - "◯": [T: "círculo grande"] # 0x25ef (en: 'large circle') - - "◰": [T: "cuadrado blanco con cuadrante superior izquierdo"] # 0x25f0 (en: 'white square with upper left quadrant') - - "◱": [T: "cuadrado blanco con cuadrante inferior izquierdo"] # 0x25f1 (en: 'white square with lower left quadrant') - - "◲": [T: "cuadrado blanco con cuadrante inferior derecho"] # 0x25f2 (en: 'white square with lower right quadrant') - - "◳": [T: "cuadrado blanco con cuadrante superior derecho"] # 0x25f3 (en: 'white square with upper right quadrant') - - "◴": [T: "círculo blanco con cuadrante superior izquierdo"] # 0x25f4 (en: 'white circle with upper left quadrant') - - "◵": [T: "círculo blanco con cuadrante inferior izquierdo"] # 0x25f5 (en: 'white circle with lower left quadrant') - - "◶": [T: "círculo blanco con cuadrante inferior derecho"] # 0x25f6 (en: 'white circle with lower right quadrant') - - "◷": [T: "círculo blanco con cuadrante superior derecho"] # 0x25f7 (en: 'white circle with upper right quadrant', google: 'círculo blanco con cuadrante superior derecha') - - "◸": [T: "triángulo superior izquierdo"] # 0x25f8 (en: 'upper left triangle') - - "◹": [T: "triángulo superior derecho"] # 0x25f9 (en: 'upper right triangle') - - "◺": [T: "triángulo inferior izquierda"] # 0x25fa (en: 'lower left triangle') - - "◻": [T: "cuadrado blanco mediano"] # 0x25fb (en: 'white medium square') - - "◼": [T: "cuadrado negro mediano"] # 0x25fc (en: 'black medium square') - - "◽": [T: "cuadrado pequeño medianamente vacío"] # 0x25fd (en: 'white medium small square') - - "◾": [T: "cuadrado pequeño medianamente lleno"] # 0x25fe (en: 'black medium small square') - - "◿": [T: "triángulo inferior derecho"] # 0x25ff (en: 'lower right triangle') - - "♠": [T: "picas"] # 0x2660 (google: 'traje de pala negro') - - "♡": [T: "corazones"] # 0x2661 (google: 'traje de corazón blanco') - - "♢": [T: "diamantes"] # 0x2662 (google: 'traje de diamante blanco') - - "♣": [T: "trébol"] # 0x2663 (google: 'traje de club negro') - - "♤": [T: "picas"] # 0x2664 (google: 'traje de pala blanca') - - "♥": [T: "corazones"] # 0x2665 (google: 'traje de corazón negro') - - "♦": [T: "diamantes"] # 0x2666 (google: 'traje de diamante negro') - - "♧": [T: "trébol"] # 0x2667 (google: 'traje de club blanco') - - "❨": [T: "ornamento en paréntesis mediano izquierdo"] # 0x2768 (en: 'medium left parentheses ornament', google: 'medio de la paréntesis de la izquierda adorno') - - "❩": [T: "ornamento en paréntesis mediano derecho"] # 0x2769 (en: 'medium right parentheses ornament', google: 'medio derecho a la derecha del adorno') - - "❪": [T: "ornamento en paréntesis izquierdo medio aplanado"] # 0x276a (en: 'medium flattened left parentheses ornament', google: 'medio aplanado a la izquierda paréntesis de adornos') - - "❫": [T: "ornamento en paréntesis derecho medio aplanado"] # 0x276b (en: 'medium flattened right parentheses ornament', google: 'medio aplanado a la derecha paréntesis de adornos') - - "❬": [T: "ornamento en soporte de ángulo medio apuntando hacia la izquierda"] # 0x276c (en: 'medium left-pointing angle bracket ornament', google: 'ornamento de soporte de ángulo de punta izquierda mediana') - - "❭": [T: "ornamento en soporte de ángulo medio apuntando hacia la derecha"] # 0x276d (en: 'medium right-pointing angle bracket ornament', google: 'ornamento de soporte de ángulo de punta derecha mediana') - - "❮": [T: "ornamento en comillas en el ángulo que apunta hacia la izquierda"] # 0x276e (en: 'heavy left-pointing angle quotation mark ornament', google: 'ornamento de cita de ángulo de punta izquierda pesada') - - "❯": [T: "ornamento en comillas en el ángulo recto que apunta hacia la derecha"] # 0x276f (en: 'heavy right-pointing angle quotation mark ornament', google: 'ornamento de cita de cita de ángulo derecho pesado') - - "❰": [T: "ornamento en soporte del ángulo que apunta a la izquierda"] # 0x2770 (en: 'heavy left-pointing angle bracket ornament', google: 'adorno de soporte de ángulo izquierdo pesado') - - "❱": [T: "ornamento en soporte del ángulo que apunta hacia la derecha"] # 0x2771 (en: 'heavy right-pointing angle bracket ornament', google: 'ornamento de soporte de ángulo de punta derecha pesada') - - "❲": [T: "ornamento en soporte de concha de tortuga a la izquierda"] # 0x2772 (en: 'light left tortoise shell bracket ornament', google: 'ornamento de soporte de concha de tortuga de luz') - - "❳": [T: "ornamento en corchete derecho de concha de tortuga hacia la derecha"] # 0x2773 (en: 'light right tortoise shell bracket ornament', google: 'ornamento de soporte de carcasa de tortuga ligera') - - "❴": [T: "ornamento en soporte izquierdo mediano"] # 0x2774 (en: 'medium left brace ornament', google: 'ornamento de brace izquierdo mediano') - - "❵": [T: "ornamento en soporte derechomediano"] # 0x2775 (en: 'medium right brace ornament', google: 'ornamento de aparato ortopédico medio derecho') - - "❶": [T: "círculo negro rodeando uno"] # 0x2776 (en: 'black circled one', google translation) - - "❷": [T: "c´riculo negro rodeando dos"] # 0x2777 (en: 'black circled two', google translation) - - "❸": [T: "círculo negro rodeando tres"] # 0x2778 (en: 'black circled three', google translation) - - "❹": [T: "círculo negro rodeando cuatro"] # 0x2779 (en: 'black circled four', google translation) - - "❺": [T: "círculo negro rodeando cinco"] # 0x277a (en: 'black circled five', google translation) - - "❻": [T: "círculo negro rodeando seis"] # 0x277b (en: 'black circled six', google translation) - - "❼": [T: "círculo negro rodeando siete"] # 0x277c (en: 'black circled seven', google translation) - - "❽": [T: "círculo negro rodeando ocho"] # 0x277d (en: 'black circled eight', google translation) - - "❾": [T: "círculo negro rodeando nueve"] # 0x277e (en: 'black circled nine', google translation) - - "❿": [T: "círculo negro rodeando diez"] # 0x277f (en: 'black circled ten', google translation) - - "➀": [T: "círculo rodeando sans serif uno"] # 0x2780 (en: 'circled sans serif one', google translation) - - "➁": [T: "círculo rodeando sans serif dos"] # 0x2781 (en: 'circled sans serif two', google translation) - - "➂": [T: "círculo rodeando sans serif tres"] # 0x2782 (en: 'circled sans serif three', google translation) - - "➃": [T: "círculo rodeando sans serif cuatro"] # 0x2783 (en: 'circled sans serif four', google translation) - - "➄": [T: "círculo rodeando sans serif cinco"] # 0x2784 (en: 'circled sans serif five', google translation) - - "➅": [T: "círculo rodeando sans serif seis"] # 0x2785 (en: 'circled sans serif six', google translation) - - "➆": [T: "círculo rodeando sans serif siete"] # 0x2786 (en: 'circled sans serif seven', google translation) - - "➇": [T: "círculo rodeando sans serif ocho"] # 0x2787 (en: 'circled sans serif eight', google translation) - - "➈": [T: "círculo rodeando sans serif nueve"] # 0x2788 (en: 'circled sans serif nine', google translation) - - "➉": [T: "círculo rodeando sans serif diez"] # 0x2789 (en: 'circled sans serif ten', google translation) - - "➊": [T: "círculo negro rodeando sans serif uno"] # 0x278a (google translation) - - "➋": [T: "círculo negro rodeando sans serif dos"] # 0x278b (en: 'black circled sans serif two', google translation) - - "➌": [T: "círculo negro rodeando sans serif tres"] # 0x278c (en: 'black circled sans serif three', google translation) - - "➍": [T: "círculo negro rodeando sans serif cuatro"] # 0x278d (google translation) - - "➎": [T: "círculo negro rodeando sans serif cinco"] # 0x278e (google translation) - - "➏": [T: "círculo negro rodeando sans serif seis"] # 0x278f (google translation) - - "➐": [T: "círculo negro rodeando sans serif siete"] # 0x2790 (google translation) - - "➑": [T: "círculo negro rodeando sans serif ocho"] # 0x2791 (en: 'black circled sans serif eight', google translation) - - "➒": [T: "círculo negro rodeando sans serif nueve"] # 0x2792 (google translation) - - "➓": [T: "círculo negro rodeando sans serif diez"] # 0x2793 (google translation) - - "➔": [T: "flecha hacia la derecha con cabeza ancha"] # 0x2794 (en: 'heavy wide-headed rightwards arrow', google: 'a la cabeza ancha de cabeza ancha') - - "➕": [T: "signo más"] # 0x2795 (en: 'heavy plus sign', google: 'señal de plus plus') - - "➖": [T: "signo menos"] # 0x2796 (en: 'heavy minus sign', google: 'fuerte señal menos') - - "➗": [T: "signo de dividir"] # 0x2797 (en: 'heavy division sign', google: 'señal de división pesada') - - "➘": [T: "flecha gruesa hacia el sudeste"] # 0x2798 (en: 'heavy south east arrow', google: 'heavy south east arrow') - - "➙": [T: "flecha gruesa hacia la derecha"] # 0x2799 (en: 'heavy rightwards arrow', google: 'flecha pesada hacia la derecha') - - "➚": [T: "flecha gruesa hacia el nordeste"] # 0x279a (en: 'heavy north east arrow', google: 'heavy north east arrow') - - "➛": [T: "flecha hacia la derecha con punto centrado"] # 0x279b (en: 'drafting point rightwards arrow', google: 'punto de redacción arrow hacia la derecha') - - "➜": [T: "flecha hacia la derecha con punta gruesa y redonda"] # 0x279c (en: 'heavy round-tipped rightwards arrow', google: 'arrow de la derecha pesada con punta redonda') - - "➝": [T: "flecha hacia la derecha con cabeza triangular"] # 0x279d (en: 'triangle-headed rightwards arrow', google: 'arrow de cabeza de triángulo') - - "➞": [T: "flecha hacia la derecha con cabeza gruesa triangular"] # 0x279e (en: 'heavy triangle-headed rightwards arrow', google: 'arrow de cabeza de triángulo pesado hacia el triángulo') - - "➟": [T: "flecha discontinua hacia la derecha de cabeza triangular"] # 0x279f (en: 'dashed triangle-headed rightwards arrow', google: 'arrow de cabeza de triángulo discontinua') - - "➠": [T: "flecha gruesa derecha discontinua con cabeza triangular"] # 0x27a0 (en: 'heavy dashed triangle-headed rightwards arrow', google: 'arrow de cabeza de triángulo pesado con cabeza de triángulo') - - "➡": [T: "flecha negra hacia la derecha"] # 0x27a1 (en: 'black rightwards arrow', google: 'negra flecha derecha hacia la derecha') - - "➢": [T: "flecha hacia la derecha tres d en parte superior"] # 0x27a2 (en: 'three d top lighted rightwards arrow', google: 'tres d top iluminados con flecha hacia la derecha') - - "➣": [T: "flecha hacia la derecha tres d en parte inferior en tres dimensiones"] # 0x27a3 (en: 'three d bottom lighted rightwards arrow', google: 'tres d de fondo iluminado hacia la derecha') - - "➤": [T: "punta de flecha negra hacia la derecha"] # 0x27a4 (en: 'black rightwards arrowhead', google: 'black rightwards arrowhead') - - "➥": [T: "flecha gruesa y negra curvada hacia la derecha y hacia abajo"] # 0x27a5 (en: 'heavy black curved downwards and rightwards arrow', google: 'negro pesado curvado hacia abajo y flecha derecha') - - "➦": [T: "flecha gruesa y negra curvada hacia la derecha y hacia arriba"] # 0x27a6 (en: 'heavy black curved upwards and rightwards arrow', google: 'negro pesado curvado hacia arriba y flecha hacia la derecha') - - "➧": [T: "flecha negra corta hacia la derecha"] # 0x27a7 (en: 'squat black rightwards arrow', google: 'corta la flecha negra a la derecha') - - "➨": [T: "flecha negra hacia la derecha con punta cóncava"] # 0x27a8 (en: 'heavy concave-pointed black rightwards arrow', google: 'flecha negra cóncava pesada pesada hacia la derecha') - - "➩": [T: "flecha hacia la derecha sombreada en la parte derecha"] # 0x27a9 (en: 'right-shaded white rightwards arrow', google: 'flecha blanca a la derecha de sombreado derecho') - - "➪": [T: "flecha blanca hacia la derecha sombreada en la parte izquierda"] # 0x27aa (en: 'left-shaded white rightwards arrow', google: 'flecha blanca a la derecha de sombreado izquierdo') - - "➫": [T: "flecha blanca hacia la derecha con sonbra inclinada hacia la parte posterior"] # 0x27ab (en: 'bck-tilted shadowed white rightwards arrow', google: 'flecha blanca a la derecha en la espalda') - - "➬": [T: "flecha blanca hacia la derecha con sombra inclinada hacia la parte anterior"] # 0x27ac (en: 'front-tilted shadowed white rightwards arrow', google: 'flecha blanca a la derecha sombreada en la sombra frontal') - - "➭": [T: "flecha gruesa inferior hacia la derecha sombreada en la parte derecha"] # 0x27ad (en: 'heavy lower right-shadowed white rightwards arrow', google: 'flecha blanca hacia la derecha inferior derecha pesada') - - "➮": [T: "flecha gruesa superior hacia la derecha sombreada en la parte derecha"] # 0x27ae (en: 'heavy upper right-shadowed white rightwards arrow', google: 'flecha blanca hacia la derecha de la parte superior derecha pesada') - - "➯": [T: "flecha escopleada inferior hacia la derecha sombreada en la parte derecha"] # 0x27af (en: 'notched lower right-shadowed white rightwards arrow', google: 'muesca con muescas de la flecha blanca a la derecha de la derecha inferior') - - "➱": [T: "flecha escopleada superior hacia la derecha sombreada en la parte derecha"] # 0x27b1 (en: 'notched upper right-shadowed white rightwards arrow', google: 'arrow blanca de sombra superior derecha con muescas de la parte superior') - - "➲": [T: "flecha blanca hacia la derecha rodeada por un círculo grueso"] # 0x27b2 (en: 'circled heavy white rightwards arrow', google: 'flecha de color blanco pesado con rodajas') - - "➳": [T: "flecha hacia la derecha con pluma blanca"] # 0x27b3 (en: 'white-feathered rightwards arrow', google: 'flecha derecha de plumas blancas') - - "➴": [T: "flecha sudeste con pluma negra"] # 0x27b4 (en: 'black-feathered south east arrow', google: 'flecha del sureste de plumas negras') - - "➵": [T: "flecha hacia la derecha con pluma negra"] # 0x27b5 (en: 'black-feathered rightwards arrow', google: 'flecha derecha de plumas negras') - - "➶": [T: "flecha nordeste con pluma negra"] # 0x27b6 (en: 'black-feathered north east arrow', google: 'flecha del noreste de plumas negras') - - "➷": [T: "flecha sudeste con pluma negra y gruesa"] # 0x27b7 (en: 'heavy black-feathered south east arrow', google: 'pesada flecha del sureste de plumas negras') - - "➸": [T: "flecha hacia la derecha con pluma gruesa y negra"] # 0x27b8 (en: 'heavy black-feathered rightwards arrow', google: 'flecha pesada de plumas negras hacia la derecha') - - "➹": [T: "flecha nordeste con pluma negra y gruesa"] # 0x27b9 (en: 'heavy black-feathered north east arrow', google: 'pesada flecha del noreste de plumas negras') - - "➺": [T: "flecha hacia la derecha con punta en forma de lágrima"] # 0x27ba (en: 'teradrop-barbed rightwards arrow', google: 'teradrop-barbed rightwards arrow') - - "➻": [T: "flecha hacia la derecha con punta en forma de lágrima"] # 0x27bb (en: 'heavy teardrop-shanked rightwards arrow', google: 'arrow a la derecha de la lágrima pesada hacia la lágrima') - - "➼": [T: "flecha hacia la derecha con cola de cuña"] # 0x27bc (en: 'wedge-tailed rightwards arrow', google: 'arrow de cola de cola de cuña') - - "➽": [T: "flecha hacia la derecha con cola de cuña gruesa"] # 0x27bd (en: 'heavy wedge-tailed rightwards arrow', google: 'flecha de cola de cuña pesada') - - "➾": [T: "flecha abierta delineada hacia fuera"] # 0x27be (en: 'open-outlined rightwards arrow', google: 'abra por la flecha de la derecha abierta') - - "⟀": [T: "ángulo tridimensional"] # 0x27c0 (en: 'three dimensional angle') - - "⟁": [T: "triángulo blanco conteniendo triángulo pequeño y blanco"] # 0x27c1 (en: 'white triangle containing small white triangle') - - "⟂": # 0x27c2 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "perpendicular a" # (en: 'perpendicular to') - - "⟃": # 0x27c3 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "un subconjunto de" # (en: 'an open subset of') - - "⟄": # 0x27c4 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "un subconjunto de" # (en: 'an open superset of') - - "⟅": [T: "símbolo delimitador con forma de s inversa"] # 0x27c5 (en: 'left s-shaped bag delimiter') - - "⟆": [T: "símbolo delimitador con forma de s"] # 0x27c6 (en: 'right s-shaped bag delimiter') - - "⟇": [T: "o con punto en el interior"] # 0x27c7 (en: 'or with dot inside') - - "⟈": [T: "solidus inverso precediendo subconjunto"] # 0x27c8 (en: 'reverse solidus preceding subset') - - "⟉": [T: "superconjunto precediendo solidus"] # 0x27c9 (en: 'superset preceding solidus') - - "⟊": [T: "barra vertical con trazo horizontal"] # 0x27ca (en: 'vertical bar with horizontal stroke') - - "⟋": [T: "diagonal ascendiente"] # 0x27cb (en: 'mathematical rising diagonal', google: 'diagonal matemática en ascenso') - - "⟌": [T: "división larga"] # 0x27cc (en: 'long division') - - "⟍": [T: "diagonal descendente"] # 0x27cd (en: 'mathematical falling diagonal', google: 'diagonal de caída matemática') - - "⟎": [T: "cuadrado Lógico Y"] # 0x27ce (en: 'squared logical and', google: 'cuadrado lógico y') - - "⟏": [T: "cuadrado Lógico O"] # 0x27cf (en: 'squared logical or', google: 'cuadrado lógico o') - - "⟐": [T: "diamante blanco con punto centrado"] # 0x27d0 (en: 'white diamond with centered dot') - - "⟑": [T: "y con punto interior"] # 0x27d1 (en: 'and with dot') - - "⟒": [T: "elemento de apertura hacia arriba"] # 0x27d2 (en: 'element of opening upwards') - - "⟓": [T: "esquina inferior derecha con punto"] # 0x27d3 (en: 'lower right corner with dot') - - "⟔": [T: "esquina superior izquierda con punto"] # 0x27d4 (en: 'upper left corner with dot') - - "⟕": [T: "unión exterior izquierda"] # 0x27d5 (en: 'left outer join') - - "⟖": [T: "unión exterior derecha"] # 0x27d6 (en: 'right outer join') - - "⟗": [T: "unión exterior llena de"] # 0x27d7 (en: 'full outer join') - - "⟘": [T: "perpendicular inversa"] # 0x27d8 (en: 'large up tack') - - "⟙": [T: "perpendicular"] # 0x27d9 (en: 'large down tack') - - "⟚": [T: "izquierdo y derecho doble torniquete"] # 0x27da (en: 'left and right double turnstile') - - "⟛": [T: "doble T horizontal"] # 0x27db (en: 'left and right tack') - - "⟜": [T: "multifunción por la izquierda"] # 0x27dc (en: 'left multimap') - - "⟝": [T: "t horizontal derecha"] # 0x27dd (en: 'long right tack', MathPlayer: 'T horizontal derecha larga', google: 'tachuela a la derecha larga') - - "⟞": [T: "t horizontal izquierda"] # 0x27de (en: 'long left tack', MathPlayer: 'T horizontal izquierda larga', google: 'táctica izquierda larga') - - "⟟": [T: "perpendicular inversa con círculo arriba"] # 0x27df (en: 'up tack with circle above') - - "⟠": [T: "rombo dividido por regla horizontal"] # 0x27e0 (en: 'lozenge divided by horizontal rule') - - "⟡": [T: "rombo blanco cóncavo"] # 0x27e1 (en: 'white concave sided diamond') - - "⟢": [T: "rombo blanco cóncavo con marca hacia la izquierda"] # 0x27e2 (en: 'white concave sided diamond with leftwards tick') - - "⟣": [T: "rombo cóncavo con marca hacia la derecha"] # 0x27e3 (en: 'white concave sided diamond with rightwards tick') - - "⟤": [T: "cuadrado blanco con marca hacia la izquierda"] # 0x27e4 (en: 'white square with leftwards tick') - - "⟥": [T: "cuadrado blanco con marca hacia la derecha"] # 0x27e5 (en: 'white square with rightwards tick') - - "⟦": [T: "abrir corchete"] # 0x27e6 (en: 'left white square bracket') - - "⟧": [T: "cerrar corchete"] # 0x27e7 (en: 'right white square bracket') - - "⟨": [T: "soporte angular izquierdo"] # 0x27e8 (en: 'left angle bracket') - - "⟩": [T: "soporte angular derecho"] # 0x27e9 (en: 'right angle bracket') - - "⟪": [T: "doble corchetehacia la izquierda"] # 0x27ea (en: 'left double angle bracket') - - "⟫": [T: "doble corchete hacia la derecha"] # 0x27eb (en: 'right double angle bracket') - - "⟬": [T: "corchete blanco hacia la izquierda con concha de tortuga"] # 0x27ec (en: 'left white tortoise shell bracket') - - "⟭": [T: "corchete blanco hacia la derecha con concha de tortuga"] # 0x27ed (en: 'right white tortoise shell bracket', MathPlayer: 'corchete de tortuga vacío derecho', google: 'soporte de carcasa de tortuga blanca derecha') - - "⟮": [T: "paréntesis plano izquierdo"] # 0x27ee (en: 'left flattened parenthesis') - - "⟯": [T: "paréntesis plano derecho"] # 0x27ef (en: 'right flattened parenthesis') - - "⟰": [T: "flecha cuádruple hacia arriba"] # 0x27f0 (en: 'upwards quadruple arrow') - - "⟱": [T: "flecha cuádruple hacia abajo"] # 0x27f1 (en: 'downwards quadruple arrow') - - "⟲": [T: "flecha circular vacía en sentido contrario a las agujas del reloj"] # 0x27f2 (en: 'anticlockwise gapped circle arrow') - - "⟳": [T: "flecha circular vacía en sentido a las agujas del reloj"] # 0x27f3 (en: 'clockwise gapped circle arrow') - - "⟴": [T: "flecha hacia la derecha con signo más rodeado por un círculo"] # 0x27f4 (en: 'right arrow with circled plus') - - "⟵": [T: "flecha larga hacia la izquierda"] # 0x27f5 (en: 'long leftwards arrow') - - "⟶": [T: "flecha larga hacia la derecha"] # 0x27f6 (en: 'long rightwards arrow') - - "⟷": [T: "flecha larga hacia izquierda y derecha"] # 0x27f7 (en: 'long left right arrow') - - "⟸": [T: "doble flecha larga hacia la izquierda"] # 0x27f8 (en: 'long leftwards double arrow') - - "⟹": [T: "doble flecha larga hacia la derecha"] # 0x27f9 (en: 'long rightwards double arrow') - - "⟺": [T: "doble flecha larga hacia izquierda y derecha"] # 0x27fa (en: 'long left right double arrow') - - "⟻": [T: "flecha larga hacia la izquierda partiendo de una barra"] # 0x27fb (en: 'long leftwards arrow from bar') - - "⟼": [T: "flecha larga hacia la derecha partiendo de una barra"] # 0x27fc (en: 'long rightwards arrow from bar') - - "⟽": [T: "doble flecha larga hacia la izquierda partiendo de una barra"] # 0x27fd (en: 'long leftwards double arrow from bar') - - "⟾": [T: "doble flecha larga hacia la derecha partiendo de una barra"] # 0x27fe (en: 'long rightwards double arrow from bar') - - "⟿": [T: "flecha ondulada hacia la derecha"] # 0x27ff (en: 'long rightwards squiggle arrow') - - "⤀": [T: "flecha de dos cabezas hacia la derecha con trazo vertical"] # 0x2900 (en: 'rightwards two headed arrow with vertical stroke', google: 'derecho de dos flechas con trazo vertical') - - "⤁": [T: "flecha de dos cabezas hacia la derecha con doble trazo vertical"] # 0x2901 (en: 'rightwards two headed arrow with double vertical stroke', google: 'derecho de dos flechas con cabeza de carrera vertical doble') - - "⤂": [T: "doble flecha hacia la izquierda con trazo vertical"] # 0x2902 (en: 'leftwards double arrow with vertical stroke', google: 'flecha doble hacia la izquierda con carrera vertical') - - "⤃": [T: "doble flecha hacia la derecha con trazo vertical"] # 0x2903 (en: 'rightwards double arrow with vertical stroke', google: 'arrow doble hacia la derecha con trazo vertical') - - "⤄": [T: "doble flecha hacia izquierda y derecha con trazo vertical"] # 0x2904 (en: 'left right double arrow with vertical stroke', google: 'flecha doble derecha izquierda con carrera vertical') - - "⤅": [T: "flecha de dos cabezas hacia la derecha partiendo de una barra"] # 0x2905 - - "⤆": [T: "doble flecha hacia la izquierda partiendo de una barra"] # 0x2906 (en: 'leftwards double arrow from bar', google: 'flecha doble a la izquierda desde el bar') - - "⤇": [T: "flecha doble hacia la derecha partiendo de una barra"] # 0x2907 (en: 'rightwards double arrow from bar', google: 'arrow doble hacia la derecha desde el bar') - - "⤈": [T: "flecha hacia abajo con trazo horizontal"] # 0x2908 (en: 'downwards arrow with horizontal stroke') - - "⤉": [T: "flecha hacia arriba con trazo horizontal"] # 0x2909 (en: 'upwards arrow with horizontal stroke', google: 'arrow hacia arriba con trazo horizontal') - - "⤊": [T: "triple flecha hacia arriba"] # 0x290a (en: 'upwards triple arrow', google: 'arriba de arriba arriba') - - "⤋": [T: "triple flecha hacia abajo"] # 0x290b (en: 'downwards triple arrow', google: 'aleja hacia abajo') - - "⤌": [T: "flecha doble discontinua hacia la izquierda"] # 0x290c - - "⤍": [T: "doble flecha discontinua hacia la derecha"] # 0x290d - - "⤎": [T: "triple flecha discontinua hacia la izquierda"] # 0x290e - - "⤏": [T: "triple flecha discontinua hacia la derecha"] # 0x290f - - "⤐": [T: "triple flecha discontinua con dos cabezas hacia la derecha"] # 0x2910 - - "⤑": [T: "flecha hacia la derecha con trazo punteado"] # 0x2911 - - "⤒": [T: "flecha hacia arriba partiendo de una barra"] # 0x2912 - - "⤓": [T: "flecha hacia abajo partiendo de una barra"] # 0x2913 - - "⤔": [T: "flecha hacia la derecha con cola y trazo vertical"] # 0x2914 (en: 'rightwards arrow with tail and vertical stroke', google: 'flecha hacia la derecha con cola y trazo vertical') - - "⤕": [T: "flecha hacia la derecha con cola y doble trazo vertical"] # 0x2915 (en: 'rightwards arrow with tail and double vertical stroke', google: 'flecha hacia la derecha con cola y trazo vertical doble') - - "⤖": [T: "flecha hacia la derecha con cola y dos cabezas"] # 0x2916 - - "⤗": [T: "flecha de dos cabezas hacia la derecha con cola con trazo vertical"] # 0x2917 (en: 'rightwards two headed arrow with tail with vertical stroke', google: 'derecho de dos flecha con la cola con trazo vertical') - - "⤘": [T: "flecha de dos cabezas hacia la derecha con cola con doble trazo vertical"] # 0x2918 (en: 'rightwards two headed arrow with tail with double vertical stroke', google: 'derecho de dos flecha con la cola con trazo vertical doble') - - "⤙": [T: "cola de doble flecha hacia la izquierda"] # 0x2919 (en: 'leftwards arrow tail') - - "⤚": [T: "cola de flecha hacia la derecha"] # 0x291a (en: 'rightwards arrow tail', google: 'tail de flecha hacia la derecha') - - "⤛": [T: "doble flecha hacia la izquierda con cola"] # 0x291b (en: 'leftwards double arrow tail') - - "⤜": [T: "cola de doble flecha hacia la derecha"] # 0x291c (en: 'rightwards double arrow tail') - - "⤝": [T: "flecha izquierda hacia rombo lleno"] # 0x291d (en: 'leftwards arrow to filled diamond') - - "⤞": [T: "flecha derecha hacia rombo lleno"] # 0x291e (en: 'rightwards arrow to filled diamond') - - "⤟": [T: "flecha izquierda desde barra hacia rombo lleno"] # 0x291f (en: 'leftwards arrow from bar to filled diamond') - - "⤠": [T: "flecha derecha desde barra hacia rombo lleno"] # 0x2920 (en: 'rightwards arrow from bar to filled diamond') - - "⤡": [T: "flecha del noroeste y del sudeste"] # 0x2921 (en: 'north west and south east arrow', google: 'noroeste y arrow south east') - - "⤢": [T: "flecha nordeste y sudoeste"] # 0x2922 (en: 'north east and south west arrow', google: 'north east y south west arrow') - - "⤣": [T: "flecha hacia el noroeste con garfio"] # 0x2923 (en: 'north west arrow with hook') - - "⤤": [T: "flecha hacia el nordeste con garfio"] # 0x2924 (en: 'north east arrow with hook') - - "⤥": [T: "flecha hacia el sudeste con garfio"] # 0x2925 (en: 'south east arrow with hook') - - "⤦": [T: "flecha hacia el suroeste con garfio"] # 0x2926 (en: 'south west arrow with hook') - - "⤧": [T: "flechas hacia el noroeste y hacia el nordeste"] # 0x2927 (en: 'north west arrow and north east arrow') - - "⤨": [T: "flechas hacia el nordeste y hacia el sudeste"] # 0x2928 (en: 'north east arrow and south east arrow') - - "⤩": [T: "flechas hacia el sudeste y hacia el sudoeste"] # 0x2929 (en: 'south east arrow and south west arrow') - - "⤪": [T: "flechas hacia el sudoeste y hacia el noroeste"] # 0x292a (en: 'south west arrow and north west arrow') - - "⤫": [T: "cruce de diagonal ascendente con diagonal descendente"] # 0x292b (en: 'rising diagonal crossing falling diagonal', google: 'cruce diagonal en ascenso caída diagonal') - - "⤬": [T: "cruce de diagonal descendente con diagonal ascendente"] # 0x292c (en: 'falling diagonal crossing rising diagonal', google: 'cambio de cruce diagonal diagonal') - - "⤭": [T: "flecha Sureste Cruzando Flecha Noreste"] # 0x292d (en: 'south east arrow crossing north east arrow', google: 'south east arrow crossing north east arrow') - - "⤮": [T: "flecha nordeste atravesando flecha sudeste"] # 0x292e (en: 'north east arrow crossing south east arrow', google: 'north east arrow crossing south east arrow') - - "⤯": [T: "diagonal descendente atravesando flecha nordeste"] # 0x292f (en: 'falling diagonal crossing north east arrow', google: 'caída diagonal atravesando la flecha del noreste') - - "⤰": [T: "diagonal ascendente atravesando flecha sudeste"] # 0x2930 (en: 'rising diagonal crossing south east arrow', google: 'cruce diagonal ascendente crossing south east arrow') - - "⤱": [T: "flecha nordeste atravesando flecha noroeste"] # 0x2931 (en: 'north east arrow crossing north west arrow', google: 'north east arrow crossing north west arrow') - - "⤲": [T: "flecha noroeste atravesando flecha nordeste"] # 0x2932 (en: 'north west arrow crossing north east arrow', google: 'north west arrow crossing north east arrow') - - "⤳": [T: "flecha ondulada apuntando hacia la derecha"] # 0x2933 (en: 'wave arrow pointing directly right') - - "⤴": [T: "flecha hacia la derecha curvada hacia arriba"] # 0x2934 (en: 'arrow pointing rightwards then curving upwards', google: 'arrow apuntando hacia la derecha y luego curvando hacia arriba') - - "⤵": [T: "flecha hacia la derecha curvada hacia abajo"] # 0x2935 (en: 'arrow pointing rightwards then curving downwards') - - "⤶": [T: "flecha hacia abajo curvada hacia la izquierda"] # 0x2936 (en: 'arrow pointing downwards then curving leftwards') - - "⤷": [T: "flecha hacia abajo curvada hacia la derecha"] # 0x2937 (en: 'arrow pointing downwards then curving rightwards') - - "⤸": [T: "flecha semicircular hacia la derecha en sentido de las agujas del reloj"] # 0x2938 (en: 'right side arc clockwise arrow') - - "⤹": [T: "flecha semicircular hacia la izquierda en sentido contrario a las agujas del reloj"] # 0x2939 (en: 'left side arc anticlockwise arrow') - - "⤺": [T: "arco superior en flecha en sentido contrario a las agujas del reloj"] # 0x293a (en: 'top arc anticlockwise arrow', google: 'arro de arco superior en sentido antihorario') - - "⤻": [T: "arco inferior en flecha hen sentido contrario a las agujas del reloj"] # 0x293b (en: 'bottom arc anticlockwise arrow', google: 'arco inferior de la flecha en sentido antihorario') - - "⤼": [T: "flecha en sentido a las agujas del reloj, con arco superior y signo menos"] # 0x293c (en: 'top arc clockwise arrow with minus') - - "⤽": [T: "flecha en sentido contrario a las agujas del reloj, con arco superior y signo más"] # 0x293d (en: 'top arc anticlockwise arrow with plus') - - "⤾": [T: "flecha semicircular inferior en sentido a las agujas del reloj"] # 0x293e (en: 'lower right semicircular clockwise arrow', google: 'flecha semicircular inferior derecha en el sentido de las agujas del reloj') - - "⤿": [T: "flecha semicircular inferior en sentido contrario a las agujas del reloj"] # 0x293f (en: 'lower left semicircular anticlockwise arrow', google: 'flecha semicircular inferior izquierda en sentido antihorario') - - "⥀": [T: "círculo cerrado en sentido contrario a las agujas del reloj"] # 0x2940 (en: 'anticlockwise closed circle arrow', google: 'flecha de círculo cerrado en sentido antihorario') - - "⥁": [T: "círculo cerrado en sentido de las agujas del reloj"] # 0x2941 (en: 'clockwise closed circle arrow', google: 'flecha del círculo cerrado en el sentido de las agujas del reloj') - - "⥂": [T: "flecha hacia la derecha sobre flecha corta hacia la izquierda"] # 0x2942 (en: 'rightwards arrow above short leftwards arrow') - - "⥃": [T: "flecha hacia la izquierda sobre flecha corta hacia la derecha"] # 0x2943 (en: 'leftwards arrow above short rightwards arrow', google: 'flecha hacia la izquierda sobre la flecha corta derecha hacia la derecha') - - "⥄": [T: "flecha corta hacia la derecha sobre flecha hacia la izquierda"] # 0x2944 (en: 'short rightwards arrow above leftwards arrow', google: 'flecha corta hacia la derecha sobre la flecha hacia la izquierda') - - "⥅": [T: "flecha hacia la derecha con signo más inferior"] # 0x2945 (en: 'rightwards arrow with plus below') - - "⥆": [T: "flecha hacia la izquierda con signo más inferior"] # 0x2946 (en: 'leftwards arrow with plus below', google: 'flecha hacia la izquierda con más a continuación') - - "⥇": [T: "flecha hacia la derecha a través de X"] # 0x2947 (en: 'rightwards arrow through x', google: 'flecha hacia la derecha a través de x') - - "⥈": [T: "flecha hacia la izquierda a través de círculo"] # 0x2948 (en: 'left right arrow through circle') - - "⥉": [T: "flecha con dos cabezas haciarriba partiendo de un círculo"] # 0x2949 (en: 'upwards two headed arrow from circle') - - "⥊": [T: "arpón con punta izquierda hacia arriba y punta derecha hacia abajo"] # 0x294a (en: 'left barb up right barb down harpoon', MathPlayer: 'left barb up right barb down harpoon', google: 'barb de la izquierda hacia arriba barb barb por harpoon') - - "⥋": [T: "arpón con punta izquierda hacia abajo y punta derecha hacia arriba"] # 0x294b (en: 'left barb down right barb up harpoon', MathPlayer: 'left barb down right barb up harpoon', google: 'barb de la izquierda hacia abajo barb en la barbilla hacia arriba') - - "⥌": [T: "arpón conpunta derecha hacia arriba y punta izquierda hacia abajo"] # 0x294c (google: 'barb a la derecha por barb harpoon izquierda') - - "⥍": [T: "arpón con punta izquierda hacia arriba y punta derecha hacia abajo"] # 0x294d (en: 'up barb left down barb right harpoon', google: 'barb a la barb izquierda por barb right harpoon') - - "⥎": [T: "arpón con puntas derecha e izquierda hacia arriba"] # 0x294e (en: 'left barb up right barb up harpoon', MathPlayer: 'arpón superior derecha-izquierda', google: 'barb izquierda arriba barb arriba de barca') - - "⥏": [T: "arpón con puntas superior e inferior hacia la derecha"] # 0x294f (en: 'up barb right down barb right harpoon') - - "⥐": [T: "arpón con puntas derecha e izquierda hacia abajo"] # 0x2950 (en: 'left barb down right barb down harpoon', MathPlayer: 'arpón inferior derecha-izquierda', google: 'barb de la izquierda hacia abajo barb barb por harpoon') - - "⥑": [T: "arpón izquierdo con puntas hacia arriba y hacia abajo"] # 0x2951 (en: 'up barb left down barb left harpoon') - - "⥒": [T: "arpón hacia la izquierda con punta hasta la barra"] # 0x2952 (en: 'leftwards harpoon with barb up to bar', MathPlayer: 'leftwards harpoon to bar with barb upwards', google: 'arpón de la izquierda con barb hasta bar') - - "⥓": [T: "arpón hacia la derecha con punta hasta la barra"] # 0x2953 (en: 'rightwards harpoon with barb up to bar', MathPlayer: 'rightwards harpoon to bar with barb upwards', google: 'arpoon a la derecha con barb hasta bar') - - "⥔": [T: "arpón ascendente con punta derecha hacia la barra"] # 0x2954 (en: 'upwards harpoon with barb right to bar', MathPlayer: 'upwards harpoon to bar with barb rightwards', google: 'hacia arriba hacia arriba con barb directamente a bar') - - "⥕": [T: "arpón hacia abajo con punta derecha hacia la barra"] # 0x2955 (en: 'downwards harpoon with barb right to bar', MathPlayer: 'downwards harpoon to bar with barb rightwards', google: 'harpoon hacia abajo con barb directamente a bar') - - "⥖": [T: "arpón hacia la izquierda con punta descendente hacia la barra"] # 0x2956 (en: 'leftwards harpoon with barb down to bar', MathPlayer: 'leftwards harpoon to bar with barb downwards', google: 'arpón de la izquierda con barb hasta el bar') - - "⥗": [T: "arpón hacia la derecha con punta inferior hacia la barra"] # 0x2957 (en: 'rightwards harpoon with barb down to bar', MathPlayer: 'rightwards harpoon to bar with barb downwards', google: 'arpoon a la derecha con barb hasta bar') - - "⥘": [T: "arpón ascendente con punta izquierda hacia la barra"] # 0x2958 (en: 'upwards harpoon with barb left to bar', MathPlayer: 'upwards harpoon to bar with barb leftwards', google: 'hace arriba de barb con barb se fue a bar') - - "⥙": [T: "arpón hacia abajo con punta izquierda hacia la barra"] # 0x2959 (en: 'downwards harpoon with barb left to bar', MathPlayer: 'downwards harpoon to bar with barb leftwards', google: 'arpón hacia abajo con barb se fue a bar') - - "⥚": [T: "arpón hacia la izquierda con punta por encima de la barra"] # 0x295a (en: 'leftwards harpoon with barb up from bar', MathPlayer: 'leftwards harpoon from bar with barb upwards', google: 'arpón de la izquierda con barb arriba desde el bar') - - "⥛": [T: "arpón hacia la derecha con punta por encima de la barra"] # 0x295b (en: 'rightwards harpoon with barb up from bar', MathPlayer: 'rightwards harpoon from bar with barb upwards', google: 'arpoon a la derecha con barb up from bar') - - "⥜": [T: "arpón ascendente con punta partiendo de la barra"] # 0x295c (en: 'upwards harpoon with barb right from bar', MathPlayer: 'upwards harpoon from bar with barb rightwards', google: 'hacia arriba hacia arriba con barb directamente desde el bar') - - "⥝": [T: "arpón descendente con punta partiendo de la barra"] # 0x295d (en: 'downwards harpoon with barb right from bar', MathPlayer: 'downwards harpoon from bar with barb rightwards', google: 'arpón hacia abajo con barb directamente desde el bar') - - "⥞": [T: "arpón hacia la izquierda con punta por debajo de la barra"] # 0x295e (en: 'leftwards harpoon with barb down from bar', MathPlayer: 'leftwards harpoon from bar with barb downwards', google: 'arpón hacia la izquierda con barb down desde bar') - - "⥟": [T: "arpón hacia la derecha con punta por debajo de barra"] # 0x295f (en: 'rightwards harpoon with barb down from bar', MathPlayer: 'rightwards harpoon from bar with barb downwards', google: 'arpoon a la derecha con barb down desde bar') - - "⥠": [T: "arpón ascendente con punta a la izquierda de la barra"] # 0x2960 (en: 'upwards harpoon with barb left from bar', MathPlayer: 'upwards harpoon from bar with barb leftwards', google: 'hacia arriba de la arpón con barb se queda desde el bar') - - "⥡": [T: "arpón descendente con punta a la izquierda de la barra"] # 0x2961 (en: 'downwards harpoon with barb left from bar', MathPlayer: 'downwards harpoon from bar with barb leftwards', google: 'arpón hacia abajo con barb se queda desde el bar') - - "⥢": [T: "arpón hacia la izquierda con punta por encima de arpon hacia la izquierda con punta hacia abajo"] # 0x2962 (en: 'leftwards harpoon with barb up above leftwards harpoon with barb down', MathPlayer: 'leftwards harpoon with barb up above leftwards harpoon with barb down', google: 'arpón de la izquierda con barb arriba sobre la arpón hacia la izquierda con barb down') - - "⥣": [T: "arpón ascendente con punta hacia la izquierda al lado de arpón ascendente con punta hacia la derecha"] # 0x2963 (en: 'upwards harpoon with barb left beside upwards harpoon with barb right', MathPlayer: 'upwards harpoon with barb left beside upwards harpoon with barb right', google: 'hacia arriba de la arpón con barb izquierda junto a la arpón hacia arriba con barb a la derecha') - - "⥤": [T: "arpón hacia la derecha con punta por encima de arpón hacia la derecha con punta hacia abajo"] # 0x2964 (en: 'rightwards harpoon with barb up above rightwards harpoon with barb down', MathPlayer: 'rightwards harpoon with barb up above rightwards harpoon with barb down', google: 'arpoon a la derecha con barb arriba sobre la arpón de la derecha con barb down') - - "⥥": [T: "arpón hacia abajo con lengüeta a la izquierda al lado arpón hacia abajo con lengüeta a la derecha"] # 0x2965 (en: 'downwards harpoon with barb left beside downwards harpoon with barb right', MathPlayer: 'downwards harpoon with barb left beside downwards harpoon with barb right', google: 'arpón hacia abajo con barb izquierda junto a la arpón hacia abajo con barb a la derecha') - - "⥦": [T: "arpón a la izquierda con punta por encima de arpón a la derecha con punta hacia arriba"] # 0x2966 (en: 'leftwards harpoon with barb up above rightwards harpoon with barb up', MathPlayer: 'leftwards harpoon with barb up above rightwards harpoon with barb up', google: 'arpón hacia la izquierda con barb arriba sobre la arpón hacia la derecha con barb') - - "⥧": [T: "arpón a la izquierda con punta hacia abajo por encima de arpón a la derecha con punta hacia abajo"] # 0x2967 (en: 'leftwards harpoon with barb down above rightwards harpoon with barb down', MathPlayer: 'leftwards harpoon with barb down above rightwards harpoon with barb down', google: 'arpón de la izquierda con barb hacia abajo sobre la arpón hacia la derecha con barb down') - - "⥨": [T: "arpón a la derecha con punta hacia arriba por encima de arpón hacia la izquierda con punta hacia arriba"] # 0x2968 (en: 'rightwards harpoon with barb up above leftwards harpoon with barb up', MathPlayer: 'rightwards harpoon with barb up above leftwards harpoon with barb up', google: 'arpoon a la derecha con barb arriba sobre la arpón de la izquierda con barb hacia arriba') - - "⥩": [T: "arpón a la derecha con punta hacia abajo por encima de arpón a la izquierda con punta hacia abajo"] # 0x2969 (en: 'rightwards harpoon with barb down above leftwards harpoon with barb down', MathPlayer: 'rightwards harpoon with barb down above leftwards harpoon with barb down', google: 'arpón a la derecha con barb hacia abajo sobre la arpón hacia la izquierda con barb down') - - "⥪": [T: "arpón hacia la izquierda con punta hacia arriba por encima de raya larga discontinua"] # 0x296a (en: 'leftwards harpoon with barb up above long dash') - - "⥫": [T: "arpón hacia la izquierda con punta hacia abajo por debajo de raya larga discontinua"] # 0x296b (en: 'leftwards harpoon with barb down below long dash') - - "⥬": [T: "arpón hacia la derecha con punta por encima de raya larga discontinua"] # 0x296c (en: 'rightwards harpoon with barb up above long dash') - - "⥭": [T: "arpón hacia la derecha con punta hacia abajo por debajo de raya larga discontinua"] # 0x296d (en: 'rightwards harpoon with barb down below long dash') - - "⥮": [T: "arpón ascendente con punta a la izquierda al lado arpón descendente con punta a la derecha"] # 0x296e (en: 'upwards harpoon with barb left beside downwards harpoon with barb right', MathPlayer: 'upwards harpoon to the left of downwards harpoon', google: 'hacia arriba de la arpón con barb izquierda junto al arpón hacia abajo con barb a la derecha') - - "⥯": [T: "arpón hacia abajo con lengüeta a la izquierda al lado arpón hacia arriba con lengüeta a la derecha"] # 0x296f (en: 'downwards harpoon with barb left beside upwards harpoon with barb right', MathPlayer: 'upwards harpoon to the right of downwards harpoon', google: 'arpón hacia abajo con barb izquierda junto a la arpón hacia arriba con barb a la derecha') - - "⥰": [T: "flecha doble hacia la derecha con cabeza redondeada"] # 0x2970 (en: 'right double arrow with rounded head') - - "⥱": [T: "flecha hacia la derecha con signo igual por encima"] # 0x2971 (en: 'equals above rightwards arrow') - - "⥲": [T: "flecha con tilde"] # 0x2972 (en: 'tilde operator above rightwards arrow') - - "⥳": [T: "tilde con flecha"] # 0x2974 (en: 'rightwards arrow above tilde operator') - - "⥵": [T: "flecha hacia la derecha por encima de signo casi igual a"] # 0x2975 (en: 'rightwards arrow above almost equal to') - - "⥶": [T: "signo menor que por encima de flecha hacia la izquierda"] # 0x2976 (en: 'less than above leftwards arrow') - - "⥷": [T: "flecha hacia la izquierda atravesando signo menor que"] # 0x2977 (en: 'leftwards arrow through less than') - - "⥸": [T: "signo mayor que por encima de flecha hacia la derecha"] # 0x2978 (en: 'greater than above rightwards arrow') - - "⥹": [T: "subconjunto por encima de flecha hacia la derecha"] # 0x2979 (en: 'subset above rightwards arrow') - - "⥺": [T: "flecha hacia la izquierda a través de subconjunto"] # 0x297a (en: 'leftwards arrow through subset') - - "⥻": [T: "superconjunto por encima de flecha hacia la izquierda"] # 0x297b (en: 'superset above leftwards arrow') - - "⥼": [T: "cola de pez izquierda"] # 0x297c (en: 'left fish tail', MathPlayer: 'left fish tail', google: 'cola de pescado izquierdo') - - "⥽": [T: "cola de pez derecha"] # 0x297d (en: 'right fish tail', MathPlayer: 'right fish tail', google: 'cola de pescado derecho') - - "⥾": [T: "cola de pez hacia arriba"] # 0x297e (en: 'up fish tail') - - "⥿": [T: "cola de pez haciaabajo"] # 0x297f (en: 'down fish tail', MathPlayer: 'down fish tail', google: 'abajo de la cola de pescado') - - "⦀": [T: "delimitador triple barra vertical"] # 0x2980 (en: 'triple vertical bar delimiter', google: 'delimitador de triple barra vertical') - - "⦁": [T: "punto de notación Z"] # 0x2981 (en: 'z notation spot', google: 'z spot de notación') - - "⦂": [T: "tipo de notación Z Colon"] # 0x2982 (en: 'z notation type colon', google: 'z tipo de notación colon') - - "⦃": [T: "soporte rotacional blanco izquierdo"] # 0x2983 (en: 'left white brace', google: 'brace blanco izquierdo') - - "⦄": [T: "soporte rotacional blanco derecho"] # 0x2984 (en: 'right white brace', google: 'brace blanco derecho') - - "⦅": [T: "paréntesis izquierdo"] # 0x2985 (en: 'left white parenthesis') - - "⦆": [T: "paréntesis derecho"] # 0x2986 (en: 'right white parenthesis') - - "⦇": [T: "notación Z izquierda soporte de imagen"] # 0x2987 (en: 'z notation left image bracket', google: 'z notación del soporte de la imagen izquierda') - - "⦈": [T: "notación Z derecha soporte de imagen"] # 0x2988 (en: 'z notation right image bracket', google: 'z notación de la imagen correcta soporte de imagen') - - "⦉": [T: "notación Z izquierda unida a soporte"] # 0x2989 - - "⦊": [T: "notación Z derecha unida a soporte"] # 0x298a - - "⦋": [T: "corchete izquierdo con barra ijnferior"] # 0x298b (en: 'left square bracket with underbar') - - "⦌": [T: "corchete derecho con barra inferior"] # 0x298c (en: 'right square bracket with underbar') - - "⦍": [T: "corchete izquierdo con trazo en esquina superior"] # 0x298d (en: 'left square bracket with tick in top corner') - - "⦎": [T: "corchete derecho con trazo en esquina inferior"] # 0x298e (en: 'right square bracket with tick in bottom corner') - - "⦏": [T: "corchete izquierdo con trazo en esquina inferior"] # 0x298f (en: 'left square bracket with tick in bottom corner') - - "⦐": [T: "corchete derecho con trazo en esquina superior"] # 0x2990 (en: 'right square bracket with tick in top corner') - - "⦑": [T: "ángulo izquierdo de corchete con punto"] # 0x2991 - - "⦒": [T: "ángulo derecho de corchete con punto"] # 0x2992 - - "⦓": [T: "arco izquierdo menor que soporte"] # 0x2993 - - "⦔": [T: "arco derecho mayor que soporte"] # 0x2994 - - "⦕": [T: "doble arco izquierdo mayor que soporte"] # 0x2995 - - "⦖": [T: "doble arco derecho menor que soporte"] # 0x2996 - - "⦗": [T: "soporte de concha de tortuga negra izquierda"] # 0x2997 (en: 'left black tortoise shell bracket') - - "⦘": [T: "soporte con concha de tortuga a la derecha"] # 0x2998 (en: 'right black tortoise shell bracket', google: 'soporte de carcasa de tortuga negra derecha') - - "⦙": [T: "valla punteada"] # 0x2999 (en: 'dotted fence') - - "⦚": [T: "línea vertical en zigzag"] # 0x299a (en: 'vertical zigzag line') - - "⦛": [T: "Ángulo medido de apertura a la izquierda"] # 0x299b (en: 'measured angle opening left', google: 'apertura de ángulo medido a la izquierda') - - "⦜": [T: "Variante de ángulo recto con cuadrado"] # 0x299c (en: 'right angle variant with square', google: 'variante de ángulo recto con cuadrado') - - "⦝": [T: "ángulo recto medido con punto"] # 0x299d (en: 'measured right angle with dot') - - "⦞": [T: "Ángulo con S dentro"] # 0x299e (en: 'angle with s inside', google: 'ángulo con s adentro') - - "⦟": [T: "Ángulo agudo"] # 0x299f (en: 'acute angle', google: 'ángulo agudo') - - "⦠": [T: "Ángulo esférico de apertura a la izquierda"] # 0x29a0 (en: 'spherical angle opening left', google: 'abertura del ángulo esférico izquierda') - - "⦡": [T: "ángulo esférico con apertura hacia arriaba"] # 0x29a1 (en: 'spherical angle opening up', google: 'abertura del ángulo esférico') - - "⦢": [T: "ángulo girado"] # 0x29a2 (en: 'turned angle', google: 'ángulo girado') - - "⦣": [T: "Ángulo invertido"] # 0x29a3 (en: 'reversed angle', google: 'ángulo invertido') - - "⦤": [T: "ángulo con barra inferior"] # 0x29a4 (en: 'angle with underbar') - - "⦥": [T: "ángulo invertido con barra inferior"] # 0x29a5 (en: 'reversed angle with underbar') - - "⦦": [T: "ángulo oblicuo abierto hacia arriba"] # 0x29a6 (en: 'oblique angle opening up') - - "⦧": [T: "ángulo oblicuo abierto hacia abajo"] # 0x29a7 (en: 'oblique angle opening down') - - "⦨": [T: "ángulo medio con brazo extendido terminando en flecha hacia arriba y hacia la derecha"] # 0x29a8 - - "⦩": [T: "ángulo medio con brazo extendido terminando en flecha hacia arriba y hacia la izquierda"] # 0x29a9 - - "⦪": [T: "ángulo medio con brazo extendido terminando en flecha hacia abajo y hacia la derecha"] # 0x29aa - - "⦫": [T: "ángulo medio con brazo extendido terminando en flecha hacia abajo y hacia la izquierda"] # 0x29ab - - "⦬": [T: "ángulo medio con brazo extendido terminando en flecha hacia la derecha y hacia arriba"] # 0x29ac - - "⦭": [T: "ángulo medio con brazo extendido terminando en flecha apuntando hacia la izquierda y hacia arriba"] # 0x29ad - - "⦮": [T: "ángulo medio con brazo extendido terminando en flecha hacia la derecha y hacia abajo"] # 0x29ae - - "⦯": [T: "ángulo medio con brazo extendido terminando en flecha hacia la izquierda y hacia abajo"] # 0x29af - - "⦰": [T: "conjunto vacío invertido"] # 0x29b0 (en: 'reversed empty set') - - "⦱": [T: "conjunto vacío con barra superior"] # 0x29b1 (en: 'empty set with overbar') - - "⦲": [T: "conjunto vacío con círculo pequeño encima"] # 0x29b2 (en: 'empty set with small circle above') - - "⦳": [T: "conjunto vacío con flecha derecha encima"] # 0x29b3 (en: 'empty set with right arrow above') - - "⦴": [T: "conjunto vacío con flecha izquierda encima"] # 0x29b4 (en: 'empty set with left arrow above') - - "⦵": [T: "círculo con barra horizontal"] # 0x29b5 (en: 'circle with horizontal bar') - - "⦶": [T: "barra vertical rodeada por un círculo"] # 0x29b6 (en: 'circled vertical bar') - - "⦷": [T: "paralelas rodeadas por un círculo"] # 0x29b7 (en: 'circled parallel') - - "⦸": [T: "solidus en círculo inverso"] # 0x29b8 (en: 'circled reverse solidus', google: 'solidus reverso en circulación') - - "⦹": [T: "perpendicular rodeada por un círculo"] # 0x29b9 (en: 'circled perpendicular') - - "⦺": [T: "círculo dividido por barra horizontal y mitad superior dividido por barra vertical"] # 0x29ba (en: 'circled divided by horizontal bar and top half divided by vertical bar', google: 'círculo dividido por la barra horizontal y la mitad superior dividida por la barra vertical') - - "⦻": [T: "círculo con x superpuesta"] # 0x29bb (en: 'circle with superimposed x') - - "⦼": [T: "círculo en sentido contrario a las agujas del reloj virando a signo de división"] # 0x29bc (en: 'circled anticlockwise rotated division sign') - - "⦽": [T: "flecha hacia arriba a través de círculo"] # 0x29bd (en: 'up arrow through circle', google: 'arrow a través del círculo') - - "⦾": [T: "viñeta vacía en un círculo"] # 0x29be (en: 'circled white bullet') - - "⦿": [T: "viñeta en un círculo"] # 0x29bf (en: 'circled bullet') - - "⧀": [T: "signo menor que en un círculo"] # 0x29c0 (en: 'circled less than') - - "⧁": [T: "signo mayor que en un círculo"] # 0x29c1 (en: 'circled greater than') - - "⧂": [T: "círculo con círculo pequeño a la derecha"] # 0x29c2 (en: 'circle with small circle to the right') - - "⧃": [T: "círculo con dos trazos horizontales a la derecha"] # 0x29c3 - - "⧄": [T: "cuadrado con diagonal ascendente"] # 0x29c4 (en: 'squared rising diagonal slash') - - "⧅": [T: "cuadrado con diagonal descendente"] # 0x29c5 (en: 'squared falling diagonal slash') - - "⧆": [T: "asterisco cuadrado"] # 0x29c6 (en: 'squared asterisk') - - "⧇": [T: "pequeño círculo cuadrado"] # 0x29c7 (en: 'squared small circle', google: 'círculo pequeño cuadrado') - - "⧈": [T: "cuadrado cuadrado"] # 0x29c8 (en: 'squared square') - - "⧉": [T: "dos cuadrados unidos"] # 0x29c9 (en: 'two joined squares') - - "⧊": [T: "triángulo con punto arriba"] # 0x29ca (en: 'triangle with dot above') - - "⧋": [T: "triángulo con barra inferior"] # 0x29cb (en: 'triangle with underbar', google: 'triángulo con debajo de la barra') - - "⧌": [T: "s dentro de un triangulo"] # 0x29cc (en: 's in triangle', google: 's en triángulo') - - "⧍": [T: "triángulo con serifs en la parte inferior"] # 0x29cd - - "⧎": [T: "triángulo hacia la derecha sobre triángulo hacia la izquierda"] # 0x29ce (en: 'right triangle above left triangle') - - "⧏": [T: "triángulo izquierdo al lado de barra vertical"] # 0x29cf (en: 'left triangle beside vertical bar') - - "⧐": [T: "barra vertical al lado de triángulo derecho"] # 0x29d0 (en: 'vertical bar beside right triangle') - - "⧑": [T: "pajarita Con Mitad Izquierda Negra"] # 0x29d1 (en: 'bowtie with left half black', google: 'bowtie con la mitad de la izquierda') - - "⧒": [T: "pajarita Con Mitad Derecha Negra"] # 0x29d2 (en: 'bowtie with right half black', google: 'bowtie con la mitad derecha negra') - - "⧓": [T: "pajarita Negra"] # 0x29d3 (en: 'black bowtie', google: 'bowtie negro') - - "⧔": [T: "multiplicado por con mitad izquierda negra"] # 0x29d4 (en: 'times with left half black', google: 'veces con la mitad de la izquierda') - - "⧕": [T: "multiplicado por con mitad derecha negra"] # 0x29d5 (en: 'times with right half black', google: 'veces con la mitad derecha negra') - - "⧖": [T: "reloj de arena blanco"] # 0x29d6 (en: 'white hourglass', google: 'hourglass blancos') - - "⧗": [T: "reloj de arena negro"] # 0x29d7 (en: 'black hourglass', google: 'hourglass negros') - - "⧘": [T: "valla izquierda ondulada"] # 0x29d8 (en: 'left wiggly fence', google: 'left fence wiggly') - - "⧙": [T: "valla derecha ondulada"] # 0x29d9 (en: 'right wiggly fence', google: 'derecha cerca ondulada') - - "⧚": [T: "valla doble izquierda ondulada"] # 0x29da - - "⧛": [T: "valla doble derecha ondulada"] # 0x29db - - "⧜": [T: "infinito incompleto"] # 0x29dc (en: 'incomplete infinity') - - "⧝": [T: "infinito"] # 0x29dd (en: 'tie over infinity', google: 'ate el infinito') - - "⧞": [T: "no infinito"] # 0x29de (en: 'infinity negated with vertical bar') - - "⧟": [T: "multimapa de doble extremo"] # 0x29df (en: 'double-ended multimap') - - "⧠": [T: "cuadrado con contorno delineado"] # 0x29e0 (en: 'square with contoured outline') - - "⧡": [T: "aumenta a medida que"] # 0x29e1 (en: 'increases as') - - "⧢": [T: "producto aleatorio"] # 0x29e2 (en: 'shuffle product', google: 'producto de baraja') - - "⧣": [T: "signo igual y paralela inclinada"] # 0x29e3 (en: 'equals sign and slanted parallel', MathPlayer: 'igual tachado doble', google: 'es igual a la señal y se inclinó paralelo') - - "⧤": [T: "signo igual y paralela inclinada con tilde por encima"] # 0x29e4 (en: 'equals sign and slanted parallel with tilde above') - - "⧥": [T: "idéntico a una paralela inclinada"] # 0x29e5 (en: 'identical to and slanted parallel') - - "⧦": [T: "gleich Stark"] # 0x29e6 (en: 'gleich stark', google: 'gleich stark') - - "⧧": [T: "termodinámica"] # 0x29e7 (en: 'thermodynamic', google: 'termodinámico') - - "⧨": [T: "triángulo apuntando hacia abajo con la mitad izquierda negra"] # 0x29e8 (en: 'down pointing triangle with left half black', google: 'down pointing triangle con la mitad izquierda') - - "⧩": [T: "triángulo apuntando hacia abajo con la mitad derecha negra"] # 0x29e9 (en: 'down pointing triangle with right half black', google: 'down apuntando al triángulo con la mitad derecha negra') - - "⧪": [T: "rombo negro con flecha hacia abajo"] # 0x29ea (en: 'black diamond with down arrow') - - "⧫": [T: "rombo relleno"] # 0x29eb (en: 'black lozenge') - - "⧬": [T: "círculo blanco con flecha hacia abajo"] # 0x29ec (en: 'white circle with down arrow') - - "⧭": [T: "círculo negro con flecha hacia abajo"] # 0x29ed (en: 'black circle with down arrow') - - "⧮": [T: "cuadrado blanco con error barrado"] # 0x29ee (en: 'error-barred white square', google: 'cuadrado blanco con barra de error') - - "⧯": [T: "cuadrado negro con error barrado"] # 0x29ef (en: 'error-barred black square', google: 'cuadrado negro con barra de error') - - "⧰": [T: "rombo blanco con error barrado"] # 0x29f0 (en: 'error-barred white diamond', google: 'diamante blanco con accesorios de error') - - "⧱": [T: "rombo negro con error barrado"] # 0x29f1 (en: 'error-barred black diamond', google: 'diamante negro con accesorios de error') - - "⧲": [T: "círculo blanco con error barrado"] # 0x29f2 (en: 'error-barred white circle', google: 'círculo blanco con barra de error') - - "⧳": [T: "círculo negro con error barrado"] # 0x29f3 (en: 'error-barred black circle', google: 'círculo negro con barra de error') - - "⧴": [T: "regla retardada"] # 0x29f4 (en: 'rule-delayed') - - "⧵": [T: "operador de Solidus Inverso"] # 0x29f5 (en: 'reverse solidus operator', google: 'operador reverso de solidus') - - "⧶": [T: "solidus con barra superior"] # 0x29f6 - - "⧷": [T: "solidus inverso con trazo horizontal"] # 0x29f7 (en: 'reverse solidus with horizontal stroke', google: 'reverse solidus con carrera horizontal') - - "⧸": [T: "sólido grande"] # 0x29f8 (en: 'big solidus', google: 'big solidus') - - "⧹": [T: "solidus inverso grande"] # 0x29f9 (en: 'big reverse solidus', google: 'big reverso solidus') - - "⧺": [T: "doble signo más"] # 0x29fa (en: 'double plus', google: 'doble más') - - "⧻": [T: "triple signo más"] # 0x29fb (en: 'triple plus', google: 'triple plus') - - "⧼": [T: "paréntesis con ángulo curvado hacia la izquierda"] # 0x29fc (en: 'left pointing curved angle bracket', google: 'soporte de ángulo curvo de apuntamiento izquierdo') - - "⧽": [T: "paréntesis con ángulo curvado hacia la derecha"] # 0x29fd (en: 'right pointing curved angle bracket', google: 'soporte de ángulo curvo apuntando a la derecha') - - "⧾": [T: "minúsculo"] # 0x29fe (en: 'tiny', google: 'diminuto') - - "⧿": [T: "miny"] # 0x29ff - - "⨀": [T: "operador de puntos circulares N-Ary"] # 0x2a00 (en: 'circled dot operator', google: 'operador de puntos en circulación') - - "⨁": [T: "operador N-Ary con signo más en un círculo"] # 0x2a01 (en: 'circled plus operator', google: 'operador circlado plus') - - "⨂": [T: "operador N-Ary con signo multiplicado por dentro de un círculo"] # 0x2a02 (en: 'circled times operator', google: 'operador de times en circulación') - - "⨃": [T: "operador de la unión N-Ary con punto"] # 0x2a03 (en: 'union operator with dot', google: 'operador sindical con dot') - - "⨄": [T: "n-Ary Union Operator con signo más"] # 0x2a04 (en: 'union operator with plus', google: 'operador sindical con más') - - "⨅": [T: "operador de intersecciones cuadradas N-Ary"] # 0x2a05 (en: 'square intersection operator', google: 'operador de intersección cuadrada') - - "⨆": [T: "n-Ary Square Union Operator"] # 0x2a06 (en: 'square union operator', google: 'operador de la unión square') - - "⨇": [T: "dos lógico y operador"] # 0x2a07 (en: 'two logical and operator', google: 'dos lógicos y operadores') - - "⨈": [T: "dos lógico u operador"] # 0x2a08 (en: 'two logical or operator', google: 'dos lógicos u operadores') - - "⨉": [T: "operador multiplicado por N-Ary Times"] # 0x2a09 (en: 'times operator', google: 'operador de tiempos') - - "⨊": [T: "módulo dos sumas"] # 0x2a0a (en: 'modulo two sum', google: 'módulo dos suma') - - "⨋": [T: "suma con Integral"] # 0x2a0b (en: 'summation with integral', google: 'suma con integral') - - "⨌": [T: "operador integral cuádruple"] # 0x2a0c (en: 'quadruple integral operator') - - "⨍": [T: "parte integral finita"] # 0x2a0d - - "⨎": [T: "integral con Doble Trazo"] # 0x2a0e (en: 'integral with double stroke', google: 'integral con doble trazo') - - "⨏": [T: "promedio Integral con barra discontinua"] # 0x2a0f (en: 'integral average with slash', google: 'promedio integral con corte') - - "⨐": [T: "circulation function"] # 0x2a10 - - "⨑": [T: "integral en sentido contrario a las agujas del reloj"] # 0x2a11 (en: 'anticlockwise integration') - - "⨒": [T: "integral lineal para rectángulo en polo"] # 0x2a12 (en: 'line integration with rectangular path around pole') - - "⨓": [T: "integral lineal para semicírculo en polo"] # 0x2a13 (en: 'line integration with semicircular path around pole') - - "⨔": [T: "integral lineal excluyendo el polo"] # 0x2a14 (en: 'line integration not including the pole') - - "⨕": [T: "integral en torno a un punto operador"] # 0x2a15 (en: 'integral around a point operator') - - "⨖": [T: "operador integral para cuaterniones"] # 0x2a16 (en: 'quaternion integral operator') - - "⨗": [T: "integral con flecha hacia la izquierda con garfio"] # 0x2a17 (en: 'integral with leftwards arrow with hook') - - "⨘": [T: "integral con signo multiplicado por"] # 0x2a18 (en: 'integral with times sign', google: 'integral con el signo de tiempos') - - "⨙": [T: "integral con Intersección"] # 0x2a19 (en: 'integral with intersection', google: 'integral con la intersección') - - "⨚": [T: "integral con unión"] # 0x2a1a (en: 'integral with union', google: 'integral con la unión') - - "⨛": [T: "integral con barra superior"] # 0x2a1b (en: 'integral with overbar', google: 'integral con overbar') - - "⨜": [T: "integral con barra inferior"] # 0x2a1c (en: 'integral with underbar', google: 'integral con underbar') - - "⨝": [T: "unir"] # 0x2a1d (en: 'join') - - "⨞": [T: "operador de triángulo izquierdo grande"] # 0x2a1e (en: 'large left triangle operator', google: 'gran operador del triángulo izquierdo') - - "⨟": [T: "composición de esquemas de notación Z"] # 0x2a1f (en: 'z notation schema composition', google: 'z composición de esquema de notación') - - "⨠": [T: "esquema de notación Z"] # 0x2a20 (en: 'z notation schema piping', google: 'z tubería de esquema de notación') - - "⨡": [T: "proyección del esquema de notación Z"] # 0x2a21 (en: 'z notation schema projection', google: 'z proyección de esquema de notación') - - "⨢": [T: "signo más con círculo encima"] # 0x2a22 (en: 'plus sign with circle above') - - "⨣": [T: "signo más con signo circunflejo encima"] # 0x2a23 (en: 'plus sign with circumflex accent above') - - "⨤": [T: "signo más con tilde encima"] # 0x2a24 (en: 'plus sign with tilde above') - - "⨥": [T: "signo más con punto inferior"] # 0x2a25 (en: 'plus sign with dot below') - - "⨦": [T: "signo más con tilde inferior"] # 0x2a26 (en: 'plus sign with tilde below') - - "⨧": [T: "signo más con 2 subíndice"] # 0x2a27 (en: 'plus sign with subscript two') - - "⨨": [T: "signo más con triángulo negro"] # 0x2a28 (en: 'plus sign with black triangle', google: 'más letrero con triángulo negro') - - "⨩": [T: "signo menos con coma encima"] # 0x2a29 (en: 'minus sign with comma above') - - "⨪": [T: "signo menos con punto inferior"] # 0x2a2a (en: 'minus sign with dot below') - - "⨫": [T: "signo menos con puntos descendentes"] # 0x2a2b (en: 'minus sign with falling dots', google: 'señal menos con puntos de caída') - - "⨬": [T: "signo menos con puntos ascendentes"] # 0x2a2c (en: 'minus sign with rising dots', google: 'minus firma con puntos ascendentes') - - "⨭": [T: "signo más en semicírculo izquierdo"] # 0x2a2d (en: 'plus sign in left half circle') - - "⨮": [T: "signo más en semicírculo derecho"] # 0x2a2e (en: 'plus sign in right half circle') - - "⨯": [T: "producto vectorial"] # 0x2a2f (en: 'cross product') - - "⨰": [T: "signo de multiplicación con punto encima"] # 0x2a30 (en: 'multiplication sign with dot above') - - "⨱": [T: "signo de multiplicación con barra inferior"] # 0x2a31 (en: 'multiplication sign with underbar') - - "⨲": [T: "producto semidirecto con fondo cerrado"] # 0x2a32 (en: 'semidirect product with bottom closed') - - "⨳": [T: "smash product"] # 0x2a33 - - "⨴": [T: "signo de multiplicación dentro de semicírculo izquierdo"] # 0x2a34 (en: 'multiplication sign in left half circle') - - "⨵": [T: "signo de multiplicación dentro de semicírculo derecho"] # 0x2a35 (en: 'multiplication sign in right half circle') - - "⨶": [T: "signo de multiplicación dentro de círculo con circunflejo"] # 0x2a36 (en: 'circled multiplication sign with circumflex accent') - - "⨷": [T: "signo de multiplicación en doble círculo"] # 0x2a37 (en: 'multiplication sign in double circle') - - "⨸": [T: "signo de división dentro de un círdulo"] # 0x2a38 (en: 'circled division sign') - - "⨹": [T: "signo más dentro de un triángulo"] # 0x2a39 (en: 'plus sign in triangle') - - "⨺": [T: "signo menos dentro de un triángulo"] # 0x2a3a (en: 'minus sign in triangle') - - "⨻": [T: "signo de multiplicación dentro de un triángulo"] # 0x2a3b (en: 'multiplication sign in triangle') - - "⨼": [T: "producto interior"] # 0x2a3c (en: 'interior product') - - "⨽": [T: "producto interior derecho"] # 0x2a3d (en: 'righthand interior product') - - "⨮": [T: "signo más en semicírculo derecho"] # 0x2a2e (en: 'z notation relational composition') - - "⨿": [T: "coproducto"] # 0x2a3f (en: 'amalgamation or coproduct') - - "⩀": [T: "intersección con punto"] # 0x2a40 (en: 'intersection with dot') - - "⩁": [T: "unión con signo menos"] # 0x2a41 (en: 'union with minus sign', google: 'unión con menos signo') - - "⩂": [T: "unión con barrasuperior"] # 0x2a42 (en: 'union with overbar') - - "⩃": [T: "intersección con barrasuperior"] # 0x2a43 (en: 'intersection with overbar') - - "⩄": [T: "intersección con and lógico"] # 0x2a44 (en: 'intersection with logical and') - - "⩅": [T: "unión con or lógico"] # 0x2a45 (en: 'union with logical or') - - "⩆": [T: "unión sobre intersección"] # 0x2a46 (en: 'union above intersection') - - "⩇": [T: "intersección sobre unión"] # 0x2a47 (en: 'intersection above union') - - "⩈": [T: "unión sobre barra sobre intersección"] # 0x2a48 (en: 'union above bar above intersection') - - "⩉": [T: "intersección sobre barra sobre unión"] # 0x2a49 (en: 'intersection above bar above union', MathPlayer: 'intersección sobre barra, sobre unión', google: 'intersección por encima de la barra por encima de la unión') - - "⩊": [T: "unión y unión"] # 0x2a4a (en: 'union beside and joined with union') - - "⩋": [T: "intersección e intersección"] # 0x2a4b (en: 'intersection beside and joined with intersection') - - "⩌": [T: "unión cerrada con serifs"] # 0x2a4c (en: 'closed union with serifs') - - "⩍": [T: "intersección cerrada con serifs"] # 0x2a4d (en: 'closed intersection with serifs') - - "⩎": [T: "intersección cuadrada doble"] # 0x2a4e (en: 'double square intersection', google: 'intersección doble cuadrado') - - "⩏": [T: "unión cuadrada doble"] # 0x2a4f (en: 'double square union', google: 'unión doble cuadrado') - - "⩐": [T: "unión cerrada con serifs y signo de multiplicación"] # 0x2a50 (en: 'closed union with serifs and smash product') - - "⩑": [T: "lógico y con punto arriba."] # 0x2a51 (en: 'logical and with dot above', google: 'lógico y con punto arriba') - - "⩒": [T: "lógico o con punto arriba"] # 0x2a52 (en: 'logical or with dot above') - - "⩓": [T: "Y"] # 0x2a53 (en: 'double logical and') - - "⩔": [T: "O"] # 0x2a54 (en: 'double logical or') - - "⩕": [T: "doble Y lógica intersecada"] # 0x2a55 - - "⩖": [T: "doble O lógica intersecada"] # 0x2a56 - - "⩗": [T: "O grande inclinada"] # 0x2a57 - - "⩘": [T: "Y grande inclinada"] # 0x2a58 - - "⩙": [T: "lógica O superpuesta a lógica Y"] # 0x2a59 (en: 'logical or overlapping logical and', google: 'lógico o superpuesto lógico y') - - "⩚": [T: "Y lógica con trazo en medio"] # 0x2a5a - - "⩛": [T: "O lógica con trazo en medio"] # 0x2a5b - - "⩜": [T: "Y lógica con barra horizontal discontinua"] # 0x2a5c - - "⩝": [T: "O lógica con barra horizontal discontinua"] # 0x2a5d - - "⩞": [T: "Y lógica con doble barra superior"] # 0x2a5e (en: 'logical and with double overbar', google: 'lógico y con doble overbar') - - "⩟": [T: "Y lógica con barra inferior"] # 0x2a5f - - "⩠": [T: "Y lógica con doble barra inferior."] # 0x2a60 (en: 'logical and with double underbar', google: 'lógico y con doble debajo de la barra') - - "⩡": [T: "pequeño Vee con barra inferior"] # 0x2a61 (en: 'small vee with underbar', google: 'pequeño vee con debajo de la barra') - - "⩢": [T: "O lógica con doble barra."] # 0x2a62 (en: 'logical or with double overbar', google: 'lógico o con doble overbar') - - "⩣": [T: "O lógica con doble barra inferior"] # 0x2a63 (en: 'logical or with double underbar', google: 'lógico o con doble bajo') - - "⩤": [T: "notación Z Dominio Antirestricción"] # 0x2a64 (en: 'z notation domain antirestriction', google: 'z dominio de notación antirestricción') - - "⩥": [T: "notación Z, rango antirrestrición"] # 0x2a65 (en: 'z notation range antirestriction', google: 'z rango de notación antirestricción') - - "⩦": [T: "signo igual con punto abajo"] # 0x2a66 (en: 'equals sign with dot below') - - "⩧": [T: "idéntico a con punto arriba"] # 0x2a67 (en: 'identical with dot above', google: 'idéntico al punto arriba') - - "⩨": [T: "triple barra horizontal con doble trazo vertical"] # 0x2a68 (en: 'triple horizontal bar with double vertical stroke', google: 'barra horizontal triple con doble carrera vertical') - - "⩩": [T: "triple barra horizontal con triple trazo vertical"] # 0x2a69 (en: 'triple horizontal bar with triple vertical stroke', google: 'barra horizontal triple con trazo vertical triple') - - "⩪": [T: "tilde con punto encima"] # 0x2a6a (en: 'tilde operator with dot above') - - "⩫": [T: "tilde con puntos ascendentes"] # 0x2a6b (en: 'tilde operator with rising dots', google: 'operador de tilde con puntos ascendentes') - - "⩬": [T: "similar menos similar"] # 0x2a6c (en: 'similar minus similar', google: 'similar menos similar') - - "⩭": [T: "congruente con punto encima"] # 0x2a6d (en: 'congruent with dot above') - - "⩮": [T: "igual a con Asterisco"] # 0x2a6e (en: 'equals with asterisk', google: 'igualmente con asterisco') - - "⩯": [T: "casi igual con acento circunflejo"] # 0x2a6f (en: 'almost equal to with circumflex accent') - - "⩰": [T: "aproximadamente igual o igual a"] # 0x2a70 (en: 'approximately equal to or equal to') - - "⩱": [T: "signo igual por encima de signo más"] # 0x2a71 (en: 'equals sign above plus sign') - - "⩲": [T: "signo más por encima de signo igual"] # 0x2a72 (en: 'plus sign above equals sign') - - "⩳": [T: "signo igual por encima de tilde"] # 0x2a73 (en: 'equals sign above tilde operator') - - "⩴": [T: "signo igual con dos puntos"] # 0x2a74 (en: 'double colon equal') - - "⩵": [T: "doble signo igual"] # 0x2a75 (en: 'two consecutive equals signs') - - "⩶": [T: "triple signo igual"] # 0x2a76 (en: 'three consecutive equals signs', google: 'tres signos consecutivos iguales') - - "⩷": [T: "signo igual entre dos puntos arriba y dos puntos abajo"] # 0x2a77 (en: 'equals sign with two dots above and two dots below') - - "⩸": [T: "equivalente a con cuatro puntos en la parte superior"] # 0x2a78 (en: 'equivalent with four dots above') - - "⩹": [T: "menor que con círculo dentro"] # 0x2a79 (en: 'less than with circle inside') - - "⩺": [T: "mayor que con círculo dentro"] # 0x2a7a (en: 'greater than with circle inside') - - "⩻": [T: "menor que con signo de interrogación en la parte superior"] # 0x2a7b (en: 'less than with question mark above') - - "⩼": [T: "mayor que con signo de interrogación en la parte superior"] # 0x2a7c (en: 'greater than with question mark above') - - "⩽": [T: "menor que o signo igual inclinado"] # 0x2a7d (en: 'less than or slanted equal to') - - "⩾": [T: "mayor que o signo igual inclinado"] # 0x2a7e (en: 'greater than or slanted equal to') - - "⩿": [T: "menor que o signo igual inclinado con punto en el interior"] # 0x2a7f (en: 'less than or slanted equal to with dot inside') - - "⪀": [T: "mayor que o signo igual inclinado con punto en el interior"] # 0x2a80 (en: 'greater than or slanted equal to with dot inside') - - "⪁": [T: "menor que o signo igual inclinado con punto en la parte superior"] # 0x2a81 (en: 'less than or slanted equal to with dot above') - - "⪂": [T: "mayor que o signo igual con punto en la parte superior"] # 0x2a82 (en: 'greater than or slanted equal to with dot above') - - "⪃": [T: "menor que o signo igual inclinado con punto superior a la derecha"] # 0x2a83 (en: 'less than or slanted equal to with dot above right') - - "⪄": [ T: "mayor que con signo igual inclinado con punto superior hacia la izquierda"] # 0x2a84 (en: 'greater than or slanted equal to with dot above left') - - "⪅": [T: "menor que o aproximado"] # 0x2a85 (en: 'less than or approximate', google: 'menos o aproximado') - - "⪆": [T: "mayor que o aproximado"] # 0x2a86 (en: 'greater than or approximate', google: 'mayor o aproximado') - - "⪇": [T: "menor que y una línea no es igual a"] # 0x2a87 (en: 'less than and single line not equal to', google: 'menos que y una sola línea no es igual a') - - "⪈": [T: "mayor que y una línea no es igual a"] # 0x2a88 (en: 'greater than and single line not equal to', google: 'mayor que y una sola línea no es igual a') - - "⪉": [T: "menor que y no aproximado a"] # 0x2a89 (en: 'less than and not approximate') - - "⪊": [T: "mayor que y no aproximado a"] # 0x2a8a (en: 'greater than and not approximate') - - "⪋": [T: "menor que por encima de línea doble, signo iguaal por encima de mayor que"] # 0x2a8b (en: 'less than above double line equal above greater than', google: 'menos que por encima de la doble línea igual por encima de más que') - - "⪌": [T: "mayor que por encima de doble línea, signo igual por encima de menor que"] # 0x2a8c (en: 'greater than above double line equal above less than', google: 'mayor que por encima de la doble línea igual por encima de menos que') - - "⪍": [T: "menor que por encima de similar o igual a"] # 0x2a8d (en: 'less than above similar or equal') - - "⪎": [T: "mayor que por encima de similar o igual a"] # 0x2a8e (en: 'greater than above similar or equal') - - "⪏": [T: "menor que por encima de similar por encima de mayor que"] # 0x2a8f (en: 'less than above similar above greater than') - - "⪐": [T: "mayor que por encima de similar por encima de menor que"] # 0x2a90 (en: 'greater than above similar above less than') - - "⪑": [T: "menor que por encima de mayor que por encima de doble línea igual"] # 0x2a91 (en: 'less than above greater than above double line equal') - - "⪒": [T: "mayor que por encima de menor que por encima de doble línea igual"] # 0x2a92 (en: 'greater than above less than above double line equal') - - "⪓": [T: "menor que por encima de signo igual inclinado por encima de mayor que por encima de signo igual inclinado"] # 0x2a93 (en: 'less than above slanted equal above greater than above slanted equal') - - "⪔": [T: "mayor que por encima de signo igual inclinado por encima de menor que por encima de signo igual inclinado"] # 0x2a94 (en: 'greater than above slanted equal above less than above slanted equal') - - "⪕": [T: "igual o menor que"] # 0x2a95 (en: 'slanted equal to or less than', google: 'inclinado igual o menos de') - - "⪖": [T: "igual o mayor que"] # 0x2a96 (en: 'slanted equal to or greater than') - - "⪗": [T: "igual o menor que con punto en el interior"] # 0x2a97 (en: 'slanted equal to or less than with dot inside') - - "⪘": [T: "igual o mayor que con punto en el interior"] # 0x2a98 (en: 'slanted equal to or greater than with dot inside') - - "⪙": [T: "doble línea igual a o menor que"] # 0x2a99 (en: 'double line equal to or less than') - - "⪚": [T: "doble línea igual a o mayor que"] # 0x2a9a (en: 'double line equal to or greater than') - - "⪛": [T: "doble línea inclinada igual a o menor que"] # 0x2a9b (en: 'double line slanted equal to or less than', google: 'doble línea inclinada igual o menos de') - - "⪜": [T: "doble línea inclinada igual a o mayor que"] # 0x2a9c (en: 'double line slanted equal to or greater than', google: 'línea doble inclinada igual o mayor que') - - "⪝": [T: "similar a o menor que"] # 0x2a9d (en: 'similar or less than') - - "⪞": [T: "similar a o mayor que"] # 0x2a9e (en: 'similar or greater than') - - "⪟": [T: "similar a por encima de menor que por encima de signo igual"] # 0x2a9f (en: 'similar above less than above equals sign') - - "⪠": [T: "similar a por encima de mayor que por encima de signo egual"] # 0x2aa0 (en: 'similar above greater than above equals sign') - - "⪡": [T: "mucho menor que"] # 0x2aa1 (en: 'double nested less than') - - "⪢": [T: "mucho mayor que"] # 0x2aa2 (en: 'double nested greater than') - - "⪣": [T: "signo menor que doblemente anidado con barra inferior"] # 0x2aa3 (en: 'double nested less than with underbar', google: 'doble anidado menos que con debajo de la barra') - - "⪤": [T: "signo mayor que superpuesto a signo menor que"] # 0x2aa4 (en: 'greater than overlapping less than') - - "⪥": [T: "signo mayor que al lado de signo enor que"] # 0x2aa5 (en: 'greater than beside less than') - - "⪦": [T: "menor que cerrado con curva"] # 0x2aa6 (en: 'less than closed by curve') - - "⪧": [T: "mayor que cerrado con curva"] # 0x2aa7 (en: 'greater than closed by curve') - - "⪨": [T: "signo menor que cerrado con curva por encima de signo igual inclinadoa"] # 0x2aa8 (en: 'less than closed by curve above slanted equal') - - "⪩": [T: "signo mayor que cerrado con curva por encima de signo igual inclinado"] # 0x2aa9 (en: 'greater than closed by curve above slanted equal') - - "⪪": [T: "más pequeño que"] # 0x2aaa (en: 'smaller than') - - "⪫": [T: "más grande que"] # 0x2aab (en: 'larger than') - - "⪬": [T: "más pequeño que o igual a"] # 0x2aac (en: 'smaller than or equal to') - - "⪭": [T: "más grande que o igual a"] # 0x2aad (en: 'larger than or equal to') - - "⪮": [T: "signo igual abultado en la parte superior"] # 0x2aae (en: 'equals sign with bumpy above') - - "⪯": [T: "precede o es igual a"] # 0x2aaf (en: 'precedes above single line equals sign') - - "⪰": [T: "sucede o es igual a"] # 0x2ab0 (en: 'succeeds above single line equals sign', google: 'tiene éxito por encima de la línea única es igual al signo') - - "⪱": [T: "precede no es igual a"] # 0x2ab1 (en: 'precedes above single line not equal to', google: 'precede por encima de una sola línea no es igual a') - - "⪲": [T: "sucede no es igual a"] # 0x2ab2 (en: 'succeeds above single line not equal to', google: 'tiene éxito por encima de una sola línea no es igual a') - - "⪳": [T: "precede por encima del signo igual"] # 0x2ab3 (en: 'precedes above equals sign', google: 'precede arriba es igual al signo') - - "⪴": [T: "sucede por encima del signo igual"] # 0x2ab4 (en: 'succeeds above equals sign', google: 'tiene éxito arriba es igual al signo') - - "⪵": [T: "precede por encima de no es igual a"] # 0x2ab5 (en: 'precedes above not equal to') - - "⪶": [T: "sucede por encima de no es igual a"] # 0x2ab6 (en: 'succeeds above not equal to') - - "⪷": [T: "precede por encima de casi igual a"] # 0x2ab7 (en: 'precedes above almost equal to') - - "⪸": [T: "sucede por encima de casi igual a"] # 0x2ab8 (en: 'succeeds above almost equal to') - - "⪹": [T: "precede por encima de no es casi igual a"] # 0x2ab9 (en: 'precedes above not almost equal to', google: 'precede arriba no casi igual a') - - "⪺": [T: "sucede por encima de casi igual a"] # 0x2aba (en: 'succeeds above not almost equal to', google: 'tiene éxito arriba no casi igual a') - - "⪻": [T: "es muy anterior a"] # 0x2abb (en: 'double precedes') - - "⪼": [T: "sigue mucho después"] # 0x2abc (en: 'double succeeds') - - "⪽": [T: "subconjunto con punto"] # 0x2abd (en: 'subset with dot') - - "⪾": [T: "superconjunto con punto"] # 0x2abe (en: 'superset with dot') - - "⪿": [T: "subconjunto con signo más debajo de"] # 0x2abf (en: 'subset with plus sign below') - - "⫁": [T: "subconjunto con signo de multiplicación debajo de"] # 0x2ac1 (en: 'subset with multiplication sign below') - - "⫀": [T: "superconjunto con signo más debajo de"] # 0x2ac0 (en: 'superset with plus sign below') - - "⫂": [T: "superconjunto con signo de multiplicación debajo de"] # 0x2ac2 (en: 'superset with multiplication sign below') - - "⫃": [T: "incluido con punto o es igual a"] # 0x2ac3 (en: 'subset of or equal to with dot above') - - "⫄": [T: "superconjunto de o igual a con punto encima"] # 0x2ac4 (en: 'superset of or equal to with dot above') - - "⫅": [T: "subconjunto de signo igual encima de"] # 0x2ac5 (en: 'subset of above equals sign', google: 'el subconjunto de arriba es igual al signo') - - "⫆": [T: "superconjunto de signo igual encima de"] # 0x2ac6 (en: 'superset of above equals sign', google: 'el superconjunto de arriba es igual al signo') - - "⫇": [T: "subconjunto por encima de tilde"] # 0x2ac7 (en: 'subset of above tilde operator') - - "⫈": [T: "superconjunto por encima de"] # 0x2ac8 (en: 'superset of above tilde operator') - - "⫉": [T: "subconjunto por encima de signo casi igual a"] # 0x2ac9 (en: 'subset of above almost equal to', google: 'subconjunto de arriba casi igual a') - - "⫊": [T: "superconjunto por encima de casi igual a"] # 0x2aca (en: 'superset of above almost equal to', google: 'superset de arriba casi igual a') - - "⫋": [T: "subconjunto por encima de signo no es igual a"] # 0x2acb (en: 'subset above not equal to', google: 'subconjunto arriba no igual a') - - "⫌": [T: "superconjunto por encima de signo no es igual a "] # 0x2acc (en: 'superset of above not equal to', google: 'superset de arriba no es igual a') - - "⫍": [T: "operador de caja abierta cuadrada a la izquierda"] # 0x2acd (en: 'square left open box operator', google: 'operador de caja abierta cuadrada izquierda') - - "⫎": [T: "operador de caja abierta cuadrada a la derecha"] # 0x2ace (en: 'square right open box operator', google: 'operador de caja abierta cuadrada derecha') - - "⫏": [T: "subconjunto cerrado"] # 0x2acf (en: 'closed subset') - - "⫐": [T: "superconjunto cerrado"] # 0x2ad0 (en: 'closed superset') - - "⫑": [T: "subconjunto cerrado o es igual a"] # 0x2ad1 (en: 'closed subset or equal to') - - "⫒": [T: "superconjunto cerrado o es igual a"] # 0x2ad2 (en: 'closed superset or equal to') - - "⫓": [T: "subconjunto por encima de superconjunto"] # 0x2ad3 (en: 'subset above superset') - - "⫔": [T: "superconjunto por encima de subconjunto"] # 0x2ad4 (en: 'superset above subset') - - "⫕": [T: "subconjunto por encima de subconjunto"] # 0x2ad5 (en: 'subset above subset') - - "⫖": [T: "superconjunto por encima de superconjunto"] # 0x2ad6 (en: 'superset above superset') - - "⫗": [T: "superconjunto al lado de subconjunto"] # 0x2ad7 (en: 'superset beside subset') - - "⫘": [T: "superconjunto al lado de y unido por barra discontinua a subconjunto"] # 0x2ad8 (en: 'superset beside and joined by dash with subset') - - "⫙": [T: "grupo de apertura hacia arriba y hacia abajo"] # 0x2ad9 (en: 'element of opening downwards') - - "⫚": [T: "bifurcación"] # 0x2ada - - "⫛": [T: "intersección transversal"] # 0x2adb - - "⫝̸": [T: "bifurcación"] # 0x2adc (en: 'forking') - - "⫝": [T: "sin bifurcación"] # 0x2add (google: 'no efectivo') - - "⫞": [T: "tack corto a la izquierda"] # 0x2ade (en: 'short left tack', google: 'tachuela a la izquierda corta') - - "⫟": [T: "tack corto hacia abajo"] # 0x2adf (en: 'short down tack', google: 'tachuela corta') - - "⫠": [T: "tack corto hacia arriba"] # 0x2ae0 (en: 'short up tack', google: 'tachuela corta') - - "⫡": [T: "perpendicular a s"] # 0x2ae1 (en: 'perpendicular with s') - - "⫢": [T: "barra vertical con triple torniquete a la derecha"] # 0x2ae2 (en: 'vertical bar triple right turnstile', google: 'barra vertical triple turnstile a la derecha') - - "⫣": [T: "doble barra vertical con torniquete a la izquierda"] # 0x2ae3 (en: 'double vertical bar left turnstile', google: 'doble barra vertical a la izquierda el torniquete') - - "⫤": [T: "barra vertical con doble torniquete a la izquierda"] # 0x2ae4 (en: 'vertical bar double left turnstile') - - "⫥": [T: "doble barra vertical doble torniquete a la izquierda"] # 0x2ae5 (en: 'double vertical bar double left turnstile', google: 'doble barra vertical de doble tornillo a la izquierda') - - "⫦": [T: "larga barra discontinua partiendo de doble barra vertical izquierda"] # 0x2ae6 - - "⫧": [T: "tack corto con barra superior"] # 0x2ae7 - - "⫨": [T: "tack corto arriba con barra inferior"] # 0x2ae8 (en: 'short up tack with underbar') - - "⫩": [T: "tack corto arriba sobre tack corto abajo"] # 0x2ae9 - - "⫪": [T: "doble tack hacia abajo"] # 0x2aea (en: 'double down tack', google: 'duplicar la tachuela') - - "⫫": [T: "doble tack hacia arriba"] # 0x2aeb - - "⫬": [T: "doble trazo sin signo"] # 0x2aec - - "⫭": [T: "doble trazo invertido sin signo"] # 0x2aed - - "⫮": [T: "no divide con barra invertida discontinua de negación"] # 0x2aee - - "⫯": [T: "línea vertical con círculo encima"] # 0x2aef (en: 'vertical line with circle above') - - "⫰": [T: "línea vertical con círculo abajo"] # 0x2af0 (en: 'vertical line with circle below') - - "⫱": [T: "tack hacia abajo con círculo abajo"] # 0x2af1 - - "⫲": [T: "paralela con trazo horizontal"] # 0x2af2 (en: 'parallel with horizontal stroke') - - "⫳": [T: "paralela con tilde"] # 0x2af3 (en: 'parallel with tilde operator') - - "⫴": [T: "relación binaria de barra vertical triple"] # 0x2af4 (en: 'triple vertical bar binary relation', google: 'relación binaria de la barra vertical triple') - - "⫵": [T: "barra vertical triple con trazo horizontal"] # 0x2af5 (en: 'triple vertical bar with horizontal stroke', google: 'barra vertical triple con carrera horizontal') - - "⫶": [T: "operador TripleC olon"] # 0x2af6 (en: 'triple colon operator', google: 'operador de triple colon') - - "⫷": [T: "signo menor que triplemente anidado"] # 0x2af7 (en: 'triple nested less than', google: 'triple anidado menos que') - - "⫸": [T: "signo mayor que triplemente anidado"] # 0x2af8 (en: 'triple nested greater than', google: 'triple anidado más grande que') - - "⫹": [T: "doble línea inclinada menor o igual a"] # 0x2af9 (en: 'double line slanted less than or equal to', google: 'doble línea inclinada menos o igual a') - - "⫺": [T: "doble línea inclinada mayor o igual a"] # 0x2afa (en: 'double line slanted greater than or equal to', google: 'línea doble inclinada mayor o igual a') - - "⫻": [T: "relación Binaria Triple Sólida"] # 0x2afb (en: 'triple solidus binary relation', google: 'triple relación binaria de solidus') - - "⫼": [T: "operador de barra vertical triple y grande"] # 0x2afc (en: 'large triple vertical bar operator', google: 'gran operador de barra vertical triple') - - "⫽": [T: "operador Doble Sólido"] # 0x2afd (en: 'double solidus operator', google: 'operador doble solidus') - - "⫾": [T: "barra vertical blanca"] # 0x2afe (en: 'white vertical bar') - - "⫿": [T: "barra vertical blanca N-Ary"] # 0x2aff (en: 'white vertical bar', google: 'barra vertical blanca') - - "⬀": [T: "flecha blanca apuntando al nordeste"] # 0x2b00 (en: 'north east white arrow', google: 'noreste de la flecha blanca') - - "⬁": [T: "flecha blanca apuntando a noroeste"] # 0x2b01 (en: 'north west white arrow', google: 'noroeste de flecha blanca') - - "⬂": [T: "flecha blanca apuntando al sudeste"] # 0x2b02 (en: 'south east white arrow', google: 'south east white arrow') - - "⬃": [T: "flecha blanca apuntando al sudoeste"] # 0x2b03 (en: 'south west white arrow', google: 'south west white arrow') - - "⬄": [T: "flecha blanca hacia izquierda y derecha"] # 0x2b04 (en: 'left right white arrow', google: 'flecha blanca derecha izquierda') - - "⬅": [T: "flecha negra hacia la izquierda"] # 0x2b05 (en: 'leftwards black arrow') - - "⬆": [T: "flecha negra hacia arriba"] # 0x2b06 (en: 'upwards black arrow', google: 'arrow negro hacia arriba') - - "⬇": [T: "flecha negra hacia abajo"] # 0x2b07 (en: 'downwards black arrow', google: 'arrow negra hacia abajo') - - "⬈": [T: "flecha negra apuntando al nordeste"] # 0x2b08 (en: 'north east black arrow', google: 'north east black arrow') - - "⬉": [T: "flecha negra apuntando al noroeste"] # 0x2b09 (en: 'north west black arrow', google: 'noroeste de flecha negra') - - "⬊": [T: "flecha negra apuntando al sudeste"] # 0x2b0a (en: 'south east black arrow', google: 'south east black arrow') - - "⬋": [T: "flecha negra apuntando al sudoeste"] # 0x2b0b (en: 'south west black arrow', google: 'south west arrow negro') - - "⬌": [T: "flecha negra hacia izquierda y derecha"] # 0x2b0c (en: 'left right black arrow', google: 'flecha negra derecha izquierda') - - "⬍": [T: "flecha negra hacia arriba y hacia abajo"] # 0x2b0d (en: 'up down black arrow', google: 'arrow black arrow') - - "⬎": [T: "flecha hacia la derecha con la punta hacia abajo"] # 0x2b0e (en: 'rightwards arrow with tip downwards') - - "⬏": [T: "flecha hacia la derecha con la punta hacia arriba"] # 0x2b0f (en: 'rightwards arrow with tip upwards') - - "⬐": [T: "flecha hacia la izquierda con la punta hacia abajo"] # 0x2b10 (en: 'leftwards arrow with tip downwards', google: 'flecha hacia la izquierda con punta hacia abajo') - - "⬑": [T: "flecha hacia la izquierda con la punta hacia arriba"] # 0x2b11 (en: 'leftwards arrow with tip upwards', google: 'flecha hacia la izquierda con punta hacia arriba') - - "⬒": [T: "cuadrado con mitad superior negra"] # 0x2b12 (en: 'square with top half black', google: 'cuadrado con la mitad superior negra') - - "⬓": [T: "cuadrado con mitad inferior negra"] # 0x2b13 (en: 'square with bottom half black', google: 'cuadrado con la mitad inferior negra') - - "⬔": [T: "cuadrado con mitad derecha superior diagonal negra"] # 0x2b14 (en: 'square with upper right diagonal half black', google: 'cuadrado con diagonal superior derecha de la parte superior negra') - - "⬕": [T: "cuadrado con mitad izquierda inferior diagonal negra"] # 0x2b15 (en: 'square with lower left diagonal half black', google: 'cuadrado con diagonal inferior izquierda mitad negra') - - "⬖": [T: "rombo con Mitad Izquierda Negro"] # 0x2b16 (en: 'diamond with left half black', google: 'diamante con la mitad de la izquierda') - - "⬗": [T: "rombo con mitad derecha negra"] # 0x2b17 (en: 'diamond with right half black', google: 'diamante con la mitad derecha negra') - - "⬘": [T: "rombo con mitad superior negra"] # 0x2b18 (en: 'diamond with top half black', google: 'diamante con mitad superior negro') - - "⬙": [T: "rojmbo con mitad inferior negra"] # 0x2b19 (en: 'diamond with bottom half black', google: 'diamante con la mitad de negro') - - "⬚": [T: "cuadrado punteado"] # 0x2b1a (en: 'box', google: 'caja') - - "⬛": [T: "cuadrado grande negro"] # 0x2b1b (en: 'black large square') - - "⬜": [T: "cuadrado grande blanco"] # 0x2b1c (en: 'white large square', google: 'cuadrado grande blanco') - - "⬝": [T: "cuadrado muy pequeño negro"] # 0x2b1d (en: 'black very small square', google: 'negro muy pequeño cuadrado') - - "⬞": [T: "cuadrado muy pequeño blanco"] # 0x2b1e (en: 'white very small square', google: 'blanco muy pequeño cuadrado') - - "⬟": [T: "pentágono blanco"] # 0x2b20 (en: 'white pentagon') - - "⬡": [T: "hexágono blanco"] # 0x2b21 (en: 'white hexagon') - - "⬢": [T: "hexágono negro"] # 0x2b22 (en: 'black hexagon') - - "⬣": [T: "hexágono hegro horizontal"] # 0x2b23 (en: 'horizontal black hexagon', google: 'hexagon negro horizontal') - - "⬤": [T: "circulo grande negro"] # 0x2b24 (en: 'black large circle', google: 'círculo negro negro') - - "⬥": [T: "rombo Mediano Negro"] # 0x2b25 (en: 'black medium diamond', google: 'diamante medio negro') - - "⬦": [T: "rombo mediano blanco"] # 0x2b26 (en: 'white medium diamond', google: 'diamante medio blanco') - - "⬧": [T: "rombo Mediano Negro"] # 0x2b27 (en: 'black medium lozenge', google: 'rombina media negra') - - "⬨": [T: "rombo mediano blanco"] # 0x2b28 (en: 'white medium lozenge', google: 'rombita media blanca') - - "⬩": [T: "rombo pequeño negro"] # 0x2b29 (en: 'black small diamond', google: 'diamante pequeño negro') - - "⬪": [T: "rombo pequeño negro"] # 0x2b2a (en: 'black small lozenge', google: 'pequeña barra negra') - - "⬫": [T: "rombo pequeño blanco"] # 0x2b2b (en: 'white small lozenge', google: 'pequeña barra blanca') - - "⬬": [T: "elipse horizontal negra"] # 0x2b2c (en: 'black horizontal ellipse') - - "⬭": [T: "elipse horizontal blanca"] # 0x2b2d (en: 'white horizontal ellipse') - - "⬮": [T: "elipse Vertical Negra"] # 0x2b2e (en: 'black vertical ellipse', google: 'elipse vertical negro') - - "⬯": [T: "elipse Vertical Blanca"] # 0x2b2f (en: 'white vertical ellipse', google: 'elipse vertical blanco') - - "⬰": [T: "flecha izquierda con círculo pequeño"] # 0x2b30 (en: 'left arrow with small circle') - - "⬱": [T: "tres flechas a la izquierda"] # 0x2b31 (en: 'three leftwards arrows', google: 'tres flechas de izquierda') - - "⬲": [T: "flecha izquierda con signo más en el interior de uncírculo"] # 0x2b32 (en: 'left arrow with circled plus', google: 'flecha izquierda con círculos plus') - - "⬳": [T: "flecha serpenteante larga hacia la izquierda"] # 0x2b33 (en: 'long leftwards squiggle arrow', google: 'larga flecha de tirantes de la izquierda') - - "⬴": [T: "flecha de dos cabezas hacia la izquierda con trazo vertical"] # 0x2b34 (en: 'leftwards two headed arrow with vertical stroke', google: 'a la izquierda, dos flechas con carrera vertical') - - "⬵": [T: "flecha de dos cabezas hacia la izquierda con doble trazo vertical"] # 0x2b35 (en: 'leftwards two headed arrow with double vertical stroke', google: 'a la izquierda, dos flechas con cabeza de carrera vertical doble') - - "⬶": [T: "flecha de dos cabezas hacia la izquierda partiendo de barra"] # 0x2b36 (en: 'leftwards two headed arrow from bar', google: 'a la izquierda, dos flechas de la cabeza del bar') - - "⬷": [T: "flecha de dos cabezas hacia la izquierda con triple barra discontinua"] # 0x2b37 (en: 'leftwards two headed triple dash arrow', google: 'a la izquierda, dos flechas del triple tablero') - - "⬸": [T: "flecha hacia la izquierda con trazo punteado"] # 0x2b38 (en: 'leftwards arrow with dotted stem') - - "⬹": [T: "flecha hacia la izquierda con cola con trazo vertical"] # 0x2b39 (en: 'leftwards arrow with tail with vertical stroke') - - "⬺": [T: "flecha hacia la izquierda con cola con doble trazo vertical"] # 0x2b3a (en: 'leftwards arrow with tail with double vertical stroke', google: 'flecha hacia la izquierda con cola con doble carrera vertical') - - "⬻": [T: "flecha de dos cabezas hacia la izquierda con cola"] # 0x2b3b (en: 'leftwards two headed arrow with tail', google: 'a la izquierda, dos flechas con la cola') - - "⬼": [T: "flecha de dos cabezas hacia la izquierda con cola con trazo vertical"] # 0x2b3c (en: 'leftwards two headed arrow with tail with vertical stroke', google: 'a la izquierda, dos flechas con cola con trazo vertical') - - "⬽": [T: "flecha de dos cabezas hacia la izquierda con cola con doble trazo vertical"] # 0x2b3d (en: 'leftwards two headed arrow with tail with double vertical stroke', google: 'a la izquierda, dos flechas con cola con trazo vertical doble') - - "⬾": [T: "flecha hacia la izquierda a través de X"] # 0x2b3e (en: 'leftwards arrow through x', google: 'flecha hacia la izquierda a través de x') - - "⬿": [T: "flecha ondulada apuntando directamente a la izquierda"] # 0x2b3f (en: 'wave arrow pointing directly left', google: 'flecha de onda apuntando directamente a la izquierda') - - "⭀": [T: "signo igual por encima de flecha hacia la izquierda"] # 0x2b40 (en: 'equals sign above leftwards arrow', google: 'igual de la señal de la flecha hacia la izquierda') - - "⭁": [T: "operador de tilde inverso sobre la flecha hacia la izquierda"] # 0x2b41 (en: 'reverse tilde operator above leftwards arrow', google: 'reverse del operador de tilde sobre la flecha de la izquierda') - - "⭂": [T: "flecha hacia la izquierda sobre el reverso de signo casi igual a"] # 0x2b42 (en: 'leftwards arrow above reverse almost equal to') - - "⭃": [T: "flecha hacia la derecha a través de signomayor que"] # 0x2b43 (en: 'rightwards arrow through greater than', google: 'flecha hacia la derecha a través de mayor que') - - "⭄": [T: "flecha hacia la derecha a través de superconjunto"] # 0x2b44 (en: 'rightwards arrow through superset', google: 'arrow hacia la derecha a través del superconjunto') - - "⭅": [T: "flecha cuádruple hacia la izquierda"] # 0x2b45 (en: 'leftwards quadruple arrow', google: 'flecha quadruple hacia la izquierda') - - "⭆": [T: "flecha cuádruple hacia la derecha"] # 0x2b46 (en: 'rightwards quadruple arrow', google: 'arrow cuádruple hacia la derecha') - - "⭇": [T: "operador de tilde inverso sobre flecha hacia la derecha"] # 0x2b47 (en: 'reverse tilde operator above rightwards arrow', google: 'reverse el operador de tilde sobre la flecha derecha hacia la derecha') - - "⭈": [T: "flecha hacia la derecha sobre el reverso de signo casi igual a"] # 0x2b48 (en: 'rightwards arrow above reverse almost equal to') - - "⭉": [T: "operador de tilde sobre flecha hacia la izquierda"] # 0x2b49 (en: 'tilde operator above leftwards arrow', google: 'operador de tilde sobre la flecha de la izquierda') - - "⭊": [T: "flecha hacia la izquierda por encima de signo casi igual a"] # 0x2b4a (en: 'leftwards arrow above almost equal to', google: 'flecha hacia la izquierda arriba casi igual a') - - "⭋": [T: "flecha hacia la izquierda sobre operador de tilde inverso"] # 0x2b4b (en: 'leftwards arrow above reverse tilde operator') - - "⭌": [T: "flecha hacia la derecha sobre operador de tilde inverso"] # 0x2b4c (en: 'rightwards arrow above reverse tilde operator') - - "⭐": [T: "estrella media vacía"] # 0x2b50 (en: 'white medium star') - - "⭑": [T: "estrella pequeña llena"] # 0x2b51 (en: 'black small star') - - "⭒": [T: "estrella pequeña vacía"] # 0x2b52 (en: 'white small star') - - "⭓": [T: "pentágono negro apuntando hacia la derecha"] # 0x2b53 (en: 'black right pointing pentagon', google: 'black derecha apuntando al pentágono') - - "⭔": [T: "pentágono blanco apuntando hacia la derecha"] # 0x2b54 (en: 'white right pointing pentagon', google: 'pentágono apuntando a la derecha blanca') - - "⭕": [T: "círculo grueso grande"] # 0x2b55 (en: 'heavy large circle', google: 'círculo grande y pesado') - - "⭖": [T: "óvalo grueso con óvalo en el interior"] # 0x2b56 (en: 'heavy oval with oval inside', google: 'ovalo pesado con óvalo en el interior') - - "⭗": [T: "círculo grueso con círculo en el interior"] # 0x2b57 (en: 'heavy circle with circle inside', google: 'círculo pesado con círculo interior') - - "⭘": [T: "círculo grueso"] # 0x2b58 (en: 'heavy circle') - - "⭙": [T: "saltire en círculo grueso"] # 0x2b59 (en: 'heavy circled saltire', google: 'saltire con círculo pesado') - - "⸀": [T: "marcador de sustitución en ángulo recto"] # 0x2e00 (en: 'right angle substitution marker', google translation) - - "⸁": [T: "marcador de sustitución punteado en ángulo recto"] # 0x2e01 (en: 'right angle dotted substitution marker', google translation) - - "⸂": [T: "soporte de sustitución izquierdo"] # 0x2e02 (en: 'left substitution bracket', google translation) - - "⸃": [T: "soporte de sustitución derecho"] # 0x2e03 (en: 'right substitution bracket', google translation) - - "⸄": [T: "soporte de sustitución punteado izquierdo"] # 0x2e04 (en: 'left dotted substitution bracket', google translation) - - "⸅": [T: "soporte de sustitución punteado derecho"] # 0x2e05 (en: 'right dotted substitution bracket', google translation) - - "⸆": [T: "marcador de interpolación elevado"] # 0x2e06 (en: 'raised interpolation marker', google translation) - - "⸇": [T: "marcador de interpolación punteado elevado"] # 0x2e07 (en: 'raised dotted interpolation marker', google translation) - - "⸈": [T: "marcador de marcador de transposición punteado"] # 0x2e08 (en: 'dotted transposition marker marker', google translation) - - "⸉": [T: "soporte de transposición izquierdo"] # 0x2e09 (en: 'left transposition bracket', google translation) - - "⸊": [T: "soporte de transposición derecho"] # 0x2e0a (en: 'right transposition bracket', google translation) - - "⸋": [T: "cuadrado elevado"] # 0x2e0b (en: 'raised square', google translation) - - "⸌": [T: "soporte de omisión izquierdo elevado"] # 0x2e0c (en: 'left raised omission bracket', google translation) - - "⸍": [T: "soporte de omisión derecho elevado"] # 0x2e0d (en: 'right raised omission bracket', google translation) - - "⸎": [T: "editorial coronis"] # 0x2e0e (google translation) - - "⸏": [T: "párrafos"] # 0x2e0f (en: 'paragraphos', google translation) - - "⸐": [T: "párrafos bifurcados"] # 0x2e10 (en: 'forked paragraphos', google translation) - - "⸑": [T: "párrafos invertidos bifurcados"] # 0x2e11 (en: 'reversed forked paragraphos', google translation) - - "⸒": [T: "hipodiastole"] # 0x2e12 (en: 'hypodiastole', google translation) - - "⸓": [T: "óbelos punteados"] # 0x2e13 (en: 'dotted obelos', google translation) - - "⸔": [T: "áncora hacia abajo"] # 0x2e14 (en: 'downwards ancora', google translation) - - "⸕": [T: "áncora hacia arriba"] # 0x2e15 (en: 'upwards ancora', google translation) - - "⸖": [T: "ángulo punteado apuntando hacia la derecha"] # 0x2e16 (en: 'dotted right pointing angle', google translation) - - "⸗": [T: "doble guión oblicuo"] # 0x2e17 (en: 'double oblique hyphen', google translation) - - "⸘": [T: "interrobang invertido"] # 0x2e18 (en: 'inverted interrobang', google translation) - - "⸙": [T: "rama de palma"] # 0x2e19 (en: 'palm branch', google translation) - - "⸚": [T: "guión con diéresis"] # 0x2e1a (en: 'hyphen with diaeresis', google translation) - - "⸛": [T: "tilde con anillo arriba"] # 0x2e1b (en: 'tilde with ring above', google translation) - - "⸜": [T: "soporte de paráfrasis bajo izquierdo"] # 0x2e1c (en: 'left low paraphrase bracket', google translation) - - "⸝": [T: "soporte de paráfrasis bajo derecho"] # 0x2e1d (en: 'right low paraphrase bracket', google translation) - - "⸞": [T: "tilde con punto arriba"] # 0x2e1e (en: 'tilde with dot above', google translation) - - "⸟": [T: "tilde con punto abajo"] # 0x2e1f (en: 'tilde with dot below', google translation) - - "⸠": [T: "barra vertical izquierda con pluma"] # 0x2e20 (en: 'left vertical bar with quill', google translation) - - "⸡": [T: "barra vertical derecha con pluma"] # 0x2e21 (en: 'right vertical bar with quill', google translation) - - "⸢": [T: "medio soporte superior izquierdo"] # 0x2e22 (en: 'top left half bracket', google: 'medio soporte superior izquierdo') - - "⸣": [T: "medio soporte superior derecho"] # 0x2e23 (en: 'top right half bracket', google: 'arroja superior derecha') - - "⸤": [T: "abrazadera inferior izquierda"] # 0x2e24 (en: 'bottom left half bracket', google: 'medio soporte inferior izquierdo') - - "⸥": [T: "medio soporte inferior derecho"] # 0x2e25 (en: 'bottom right half bracket') - - "⸦": [T: "soporte U lateral izquierdo"] # 0x2e26 (en: 'left sideways u bracket', google: 'izquierda lateral u soporte') - - "⸧": [T: "soporte U lateral derecho"] # 0x2e27 (en: 'right sideways u bracket', google: 'right sideways u soporte') - - "⸨": [T: "doble paréntesis izquierdo"] # 0x2e28 (en: 'left double parentheses', google: 'dejó doble paréntesis de tesas') - - "⸩": [T: "doble paréntesis derecho"] # 0x2e29 (en: 'right double parentheses', google: 'doble paréntesis derecha') - - "⸪": [T: "dos puntos sobre un punto de puntuación"] # 0x2e2a (en: 'two dots over one dot punctuation', google translation) - - "⸫": [T: "un punto sobre dos puntos de puntuación"] # 0x2e2b (en: 'one dot over two dots punctuation', google translation) - - "⸬": [T: "cuatro puntos de puntuación al cuadrado"] # 0x2e2c (en: 'squared four dot punctuation', google translation) - - "⸭": [T: "marca de cinco puntos"] # 0x2e2d (en: 'five dot mark', google translation) - - "⸮": [T: "signo de interrogación invertido"] # 0x2e2e (en: 'reversed question mark', google translation) - - "ⸯ": [T: "tilde vertical"] # 0x2e2f (en: 'vertical tilde', google translation) - - "⸰": [T: "punta del anillo"] # 0x2e30 (en: 'ring point', google translation) - - "⸱": [T: "punto medio separador de palabras"] # 0x2e31 (en: 'word separator middle dot', google translation) - - "⸲": [T: "convertido en coma"] # 0x2e32 (en: 'turned comma', google translation) - - "⸳": [T: "punto elevado"] # 0x2e33 (en: 'raised dot', google translation) - - "⸴": [T: "coma elevada"] # 0x2e34 (en: 'raised comma', google translation) - - "⸵": [T: "convertido en punto y coma"] # 0x2e35 (en: 'turned semicolon', google translation) - - "⸶": [T: "obelisco con portaestandarte izquierdo"] # 0x2e36 (en: 'dagger with left guard', google translation) - - "⸷": [T: "obelisco con portaestandarte derecho"] # 0x2e37 (en: 'dagger with right guard', google translation) - - "⸸": [T: "obelisco girado"] # 0x2e38 (en: 'turned dagger', google translation) - - "⸹": [T: "señal de la mitad superior de la sección"] # 0x2e39 (en: 'top half section sign', google translation) - - "⸺": [T: "dos em línea discontinua"] # 0x2e3a (en: 'two em dash', google translation) - - "⸻": [T: "tres em línea discontinua"] # 0x2e3b (en: 'three em dash', google translation) - - "〃": [T: "ídem mark"] # 0x3003 (en: 'ditto mark', google translation) - - "〈": [T: "soporte de ángulo izquierdo"] # 0x3008 (en: 'left angle bracket') - - "〉": [T: "soporte de ángulo derecho"] # 0x3009 (en: 'right angle bracket') - - "《": [T: "doble paréntesis angular izquierdo"] # 0x300a (en: 'left double angle bracket') - - "》": [T: "doble paréntesis angular derecho"] # 0x300b (en: 'right double angle bracket', MathPlayer: 'cierra paréntesis angular doble', google: 'soporte de doble ángulo derecho') - - "「": [T: "soporte de esquina izquierda"] # 0x300c (en: 'left corner bracket', google: 'soporte de esquina izquierda') - - "」": [T: "soporte de esquina derecha"] # 0x300d (en: 'right corner bracket') - - "『": [T: "soporte de esquina blanca izquierda"] # 0x300e (en: 'left white corner bracket', google: 'soporte de esquina blanca izquierda') - - "』": [T: "soporte de esquina blanca derecha"] # 0x300f (en: 'right white corner bracket', google: 'soporte de esquina blanca derecha') - - "【": [T: "soporte Lenticular negro izquierdo"] # 0x3010 (en: 'left black lenticular bracket', google: 'soporte lenticular negro izquierdo') - - "】": [T: "soporte Lenticular Negro Derecho"] # 0x3011 (en: 'right black lenticular bracket', google: 'soporte lenticular negro derecho') - - "〔": [T: "soporte de caparazón de tortuga izquierdo"] # 0x3014 - - "〕": [T: "soporte de caparazón de tortuga derecho"] # 0x3015 - - "〖": [T: "soporte lenticular blanco izquierdo"] # 0x3016 (en: 'left white lenticular bracket') - - "〗": [T: "soporte lenticular blanco derecho"] # 0x3017 (en: 'right white lenticular bracket') - - "〘": [T: "soporte de caparazón de tortuga blanco izquierdo"] # 0x3018 (en: 'left white tortoise shell bracket', google: 'soporte de carcasa de tortuga blanca izquierda') - - "〙": [T: "soporte de caparazón de tortuga blanco derecho"] # 0x3019 (en: 'right white tortoise shell bracket', google: 'soporte de carcasa de tortuga blanca derecha') - - "〚": [T: "corchete vacío izquierdo"] # 0x301a (en: 'left white square bracket') - - "〛": [T: "corchete vacío derecho"] # 0x301b (en: 'right white square bracket', MathPlayer: 'cierra corchete vacío', google: 'soporte cuadrado blanco derecho') - - "〜": [T: "línea discontinua ondulada"] # 0x301c (en: 'wave dash', google: 'ola de ola') - - "〰": [T: "línea discontinua en zigzag"] # 0x3030 (en: 'wavy dash', google: 'dash ondulado') - - "㉈": [T: "número diez rodeado por un círculo en un cuadrado negro"] # 0x3248 (en: 'circled number ten on black square', google: 'circlado número diez en black square') - - "㉉": [T: "número veinte rodeado por un círculo en un cuadrado negro"] # 0x3249 (en: 'circled number twenty on black square', google: 'número de círculo veinte en black square') - - "㉊": [T: "número treinta rodeado por un círculo en un cuadrado negro"] # 0x324a (en: 'circled number thirty on black square', google: 'número de círculo treinta en black square') - - "㉋": [T: "número cuarenta rodeado por un círculo en un cuadrado negro"] # 0x324b (en: 'circled number forty on blacks square', google: 'número de círculo cuarenta en blacks square') - - "㉌": [T: "número cincuenta rodeado por un círculo en un cuadrado negro"] # 0x324c (en: 'circled number fifty on black square', google: 'número de círculo cincuenta en black square') - - "㉍": [T: "número sesenta rodeado por un círculo en un cuadrado negro"] # 0x324d (en: 'circled number sixty on black square', google: 'número de círculos sesenta en black square') - - "㉎": [T: "número setenta rodeado por un círculo en un cuadrado negro"] # 0x324e (en: 'circled number seventy on black square', google: 'número de círculo setenta en black square') - - "㉏": [T: "número ochenta rodeado por un círculo en un cuadrado negro"] # 0x324f (en: 'circled number eighty on black square', google: 'número de círculo aty en black square') - - "㉑": [T: "número veintiuno rodeado por un círculo"] # 0x3251 (en: 'circled number twenty one', google translation) - - "㉒": [T: "número veintidós rodeado por un círculo"] # 0x3252 (en: 'circled number twenty two', google translation) - - "㉓": [T: "número veintitrés rodeado por un círculo"] # 0x3253 (en: 'circled number twenty three', google translation) - - "㉔": [T: "número veinticuatro rodeado por un círculo"] # 0x3254 (en: 'circled number twenty four', google translation) - - "㉕": [T: "número veinticinco rodeado por un círculo"] # 0x3255 (en: 'circled number twenty five', google translation) - - "㉖": [T: "número veintiséis rodeado por un círculo"] # 0x3256 (en: 'circled number twenty six', GPT-5.4 fixed translation) - - "㉗": [T: "número veintisiete rodeado por un círculo"] # 0x3257 (en: 'circled number twenty seven', google translation) - - "㉘": [T: "número veintiocho rodeado por un círculo"] # 0x3258 (en: 'circled number twenty eight', google translation) - - "㉙": [T: "número veintinueve rodeado por un círculo"] # 0x3259 (en: 'circled number twenty nine', GPT-5.4 fixed translation) - - "㉚": [T: "número treinta rodeado por un círculo"] # 0x325a (en: 'circled number thirty', google translation) - - "㉛": [T: "número treinta y uno rodeado por un círculo"] # 0x325b (en: 'circled number thirty one', GPT-5.4 fixed translation) - - "㉜": [T: "número treinta y dos rodeado por un círculo"] # 0x325c (en: 'circled number thirty two', google translation) - - "㉝": [T: "número treinta y tres rodeado por un círculo"] # 0x325d (en: 'circled number thirty three', google translation) - - "㉞": [T: "número treinta y cuatro rodeado por un círculo"] # 0x325e (en: 'circled number thirty four', google translation) - - "㉟": [T: "número treinta y cinco rodeado por un círculo"] # 0x325f (en: 'circled number thirty five', google translation) - - "㊱": [T: "número treinta y seis rodeado por un círculo"] # 0x32b1 (en: 'circled number thirty six', google translation) - - "㊲": [T: "número treinta y siete rodeado por un círculo"] # 0x32b2 (en: 'circled number thirty seven', GPT-5.4 translation) - - "㊳": [T: "número treinta y ocho rodeado por un círculo"] # 0x32b3 (en: 'circled number thirty eight', GPT-5.4 translation) - - "㊴": [T: "número treinta y nueve rodeado por un círculo"] # 0x32b4 (en: 'circled number thirty nine', GPT-5.4 translation) - - "㊵": [T: "número cuarenta rodeado por un círculo"] # 0x32b5 (en: 'circled number forty', GPT-5.4 translation) - - "㊶": [T: "número cuarenta y uno rodeado por un círculo"] # 0x32b6 (en: 'circled number forty one', GPT-5.4 translation) - - "㊷": [T: "número cuarenta y dos rodeado por un círculo"] # 0x32b7 (en: 'circled number forty two', GPT-5.4 translation) - - "㊸": [T: "número cuarenta y tres rodeado por un círculo"] # 0x32b8 (en: 'circled number forty three', GPT-5.4 translation) - - "㊹": [T: "número cuarenta y cuatro rodeado por un círculo"] # 0x32b9 (en: 'circled number forty four', GPT-5.4 translation) - - "㊺": [T: "número cuarenta y cinco rodeado por un círculo"] # 0x32ba (en: 'circled number forty five', GPT-5.4 translation) - - "㊻": [T: "número cuarenta y seis rodeado por un círculo"] # 0x32bb (en: 'circled number forty six', GPT-5.4 translation) - - "㊼": [T: "número cuarenta y siete rodeado por un círculo"] # 0x32bc (en: 'circled number forty seven', GPT-5.4 translation) - - "㊽": [T: "número cuarenta y ocho rodeado por un círculo"] # 0x32bd (en: 'circled number forty eight', GPT-5.4 translation) - - "㊾": [T: "número cuarenta y nueve rodeado por un círculo"] # 0x32be (en: 'circled number forty nine', GPT-5.4 translation) - - "㊿": [T: "número cincuenta rodeado por un círculo"] # 0x32bf (en: 'circled number fifty', GPT-5.4 translation) - - "㋌": [T: "mercurio"] # 0x32cc (en: 'mercury', google translation) - - "㋍": [T: "ergs"] # 0x32cd (google translation) - - "㋎": [T: "electronvoltios"] # 0x32ce (en: 'electron volts', google translation) - - "㋏": [T: "señal de responsabilidad limitada"] # 0x32cf (en: 'limited liability sign', google translation) - - "㍱": [T: "hectopascales"] # 0x3371 (en: 'hectopascals', google translation) - - "㍲": [T: "daltons"] # 0x3372 (google translation) - - "㍳": [T: "unidades astronómicas"] # 0x3373 (en: 'astronomical units', google translation) - - "㍴": [T: "barras"] # 0x3374 (en: 'bars', google translation) - - "㍵": [T: "o v"] # 0x3375 (google translation) - - "㍶": [T: "parsecs"] # 0x3376 (google translation) - - "㍷": [T: "decímetros"] # 0x3377 (en: 'decimeters', google translation) - - "㍸": [T: "decímetros al cuadrado"] # 0x3378 (en: 'decimeters squared', google translation) - - "㍹": [T: "decímetros al cubo"] # 0x3379 (en: 'decimeters cubed', google translation) - - "㍺": [T: "unidades instrumentales"] # 0x337a (en: 'instrumental units', google translation) - - "㎀": [T: "picoamperios"] # 0x3380 (google translation) - - "㎁": [T: "nanoamperios"] # 0x3381 (google translation) - - "㎂": [T: "microamperios"] # 0x3382 (google translation) - - "㎃": [T: "miliamperios"] # 0x3383 (en: 'milliamps', google translation) - - "㎄": [T: "kiloamperios"] # 0x3384 (google translation) - - "㎅": [T: "kilobytes"] # 0x3385 (google translation) - - "㎆": [T: "megabytes"] # 0x3386 (google translation) - - "㎇": [T: "gigabytes"] # 0x3387 (google translation) - - "㎈": [T: "calorías"] # 0x3388 (en: 'calories', google translation) - - "㎉": [T: "kilocalorías"] # 0x3389 (en: 'kilocalories', google translation) - - "㎊": [T: "picofaradios"] # 0x338a (google translation) - - "㎋": [T: "nanofaradios"] # 0x338b (google translation) - - "㎌": [T: "microfaradios"] # 0x338c (google translation) - - "㎍": [T: "microgramos"] # 0x338d (en: 'micrograms', google translation) - - "㎎": [T: "miligramos"] # 0x338e (en: 'milligrams', google translation) - - "㎏": [T: "kilogramos"] # 0x338f (en: 'kilograms', google translation) - - "㎐": [T: "hercios"] # 0x3390 (google translation) - - "㎑": [T: "kilohercios"] # 0x3391 (en: 'kilohertz', google translation) - - "㎒": [T: "megahercios"] # 0x3392 (en: 'megahertz', google translation) - - "㎓": [T: "gigahercios"] # 0x3393 (google translation) - - "㎔": [T: "terahercios"] # 0x3394 (google translation) - - "㎕": [T: "microlitros"] # 0x3395 (en: 'microliters', google translation) - - "㎖": [T: "mililitros"] # 0x3396 (google translation) - - "㎗": [T: "decilitros"] # 0x3397 (en: 'deciliters', google translation) - - "㎘": [T: "kilolitros"] # 0x3398 (en: 'kiloliters', google translation) - - "㎙": [T: "femtómetros"] # 0x3399 (en: 'femtometers', google translation) - - "㎚": [T: "micrómetros"] # 0x339b (en: 'micrometers', google translation) - - "㎜": [T: "milímetros"] # 0x339c (en: 'millimeters', google translation) - - "㎝": [T: "centímetros"] # 0x339d (en: 'centimeters', google translation) - - "㎞": [T: "kilómetros"] # 0x339e (en: 'kilometers', google translation) - - "㎟": [T: "milímetros cuadrados"] # 0x339f (en: 'millimeters squared', google translation) - - "㎠": [T: "centímetros cuadrados"] # 0x33a0 (en: 'centimeters squared', google translation) - - "㎡": [T: "metros cuadrados"] # 0x33a1 (en: 'meters squared', google translation) - - "㎢": [T: "kilómetros cuadrados"] # 0x33a2 (en: 'kilometers squared', google translation) - - "㎣": [T: "milímetros cúbicos"] # 0x33a3 (en: 'millimeters cubed', google translation) - - "㎤": [T: "centímetros cúbicos"] # 0x33a4 (en: 'centimeters cubed', google translation) - - "㎥": [T: "metros cúbicos"] # 0x33a5 (en: 'meters cubed', google translation) - - "㎦": [T: "kilómetros cúbicos"] # 0x33a6 (en: 'kilometers cubed', google translation) - - "㎧": [T: "metros por segundo"] # 0x33a7 (en: 'meters per second', google translation) - - "㎨": [T: "metros por segundo al cuadrado"] # 0x33a8 (en: 'meters per second squared', google translation) - - "㎩": [T: "pascales"] # 0x33a9 (en: 'pascals', google translation) - - "㎪": [T: "kilopascales"] # 0x33aa (en: 'kilopascals', google translation) - - "㎫": [T: "megapascales"] # 0x33ab (en: 'megapascals', google translation) - - "㎬": [T: "gigapascales"] # 0x33ac (en: 'gigapascals', google translation) - - "㎭": [T: "radián"] # 0x33ad (google translation) - - "㎮": [T: "radián por segundo"] # 0x33ae (en: 'rads per second', google translation) - - "㎯": [T: "radián por segundo al cuadrado"] # 0x33af (en: 'rads per second squared', google translation) - - "㎰": [T: "picosegundos"] # 0x33b0 (en: 'picoseconds', google translation) - - "㎱": [T: "nanosegundos"] # 0x33b1 (en: 'nanoseconds', google translation) - - "㎲": [T: "microsegundos"] # 0x33b2 (en: 'microseconds', google translation) - - "㎳": [T: "milisegundos"] # 0x33b3 (en: 'milliseconds', google translation) - - "㎴": [T: "picovoltios"] # 0x33b4 (google translation) - - "㎵": [T: "nanovoltios"] # 0x33b5 (en: 'nanovolts', google translation) - - "㎶": [T: "microvoltios"] # 0x33b6 (en: 'microvolts', google translation) - - "㎷": [T: "milivoltios"] # 0x33b7 (en: 'millivolts', google translation) - - "㎸": [T: "kilovoltios"] # 0x33b8 (en: 'kilovolts', google translation) - - "㎹": [T: "megavoltios"] # 0x33b9 (google translation) - - "㎺": [T: "picovatios"] # 0x33ba (google translation) - - "㎻": [T: "nanovatios"] # 0x33bb (google translation) - - "㎼": [T: "microvatios"] # 0x33bc (google translation) - - "㎽": [T: "milivatios"] # 0x33bd (google translation) - - "㎾": [T: "kilovatios"] # 0x33be (en: 'kilowatts', google translation) - - "㎿": [T: "megavatios"] # 0x33bf (google translation) - - "㏀": [T: "kiloohmios"] # 0x33c0 (google translation) - - "㏁": [T: "megaohmios"] # 0x33c1 (google translation) - - "㏂": [T: "attómetros"] # 0x33c2 (en: 'attometers', google translation) - - "㏃": [T: "becquerels"] # 0x33c3 (google translation) - - "㏄": [T: "centímetros cubicos"] # 0x33c4 (en: 'cubic centimeters', google translation) - - "㏅": [T: "candelas"] # 0x33c5 (google translation) - - "㏆": [T: "culombios por kilogramos"] # 0x33c6 (en: 'coulombs per kilogram', google translation) - - "㏇": [T: "volumen minuto"] # 0x33c7 (en: 'cardiac output', google translation) - - "㏈": [T: "decibelios"] # 0x33c8 (en: 'decibels', google translation) - - "㏉": [T: "grises"] # 0x33c9 (en: 'grays', google translation) - - "㏊": [T: "hectáreas"] # 0x33ca (en: 'hectares', google translation) - - "㏋": [T: "caballo de fuerza"] # 0x33cb (en: 'horsepower', google translation) - - "㏌": [T: "pulgadas"] # 0x33cc (en: 'inches', google translation) - - "㏍": [T: "kilokelvins"] # 0x33cd (google translation) - - "㏎": [T: "kilómetros"] # 0x33ce (en: 'kilometers', google translation) - - "㏏": [T: "nudos"] # 0x33cf (en: 'knots', google translation) - - "㏐": [T: "lúmenes"] # 0x33d0 (en: 'lumens', google translation) - - "㏑": [T: "logaritmo natural"] # 0x33d1 (en: 'natural log', google translation) - - "㏒": [T: "logaritmo"] # 0x33d2 (en: 'logarithm', google translation) - - "㏓": [T: "lux"] # 0x33d3 (google translation) - - "㏔": [T: "milibares"] # 0x33d4 (google translation) - - "㏕": [T: "mills"] # 0x33d5 (en: 'mills', google translation) - - "㏖": [T: "moles"] # 0x33d6 (google translation) - - "㏗": [T: "p h"] # 0x33d7 (google translation) - - "㏘": [T: "picómetros"] # 0x33d8 (en: 'picometers', google translation) - - "㏙": [T: "partes por millón"] # 0x33d9 (en: 'parts per million', google translation) - - "㏚": [T: "roentgens"] # 0x33da (en: 'petaroentgens', google translation) - - "㏛": [T: "estererradián"] # 0x33db (en: 'steradians', google translation) - - "㏜": [T: "sieverts"] # 0x33dc (google translation) - - "㏝": [T: "webers"] # 0x33dd (google translation) - - "㏞": [T: "voltios por metro"] # 0x33de (en: 'volts per meter', google translation) - - "㏟": [T: "amperios por metro"] # 0x33df (en: 'amps per meter', google translation) - - "㏿": [T: "galones"] # 0x33ff (en: 'gallons', google translation) - - "": [T: "sino igual a con sombrero debajo"] # 0xe900 (en: 'equals with hat below', google translation) - - "": [T: "es igual a con signo más encima"] # 0xe901 (en: 'equals with plus above', google translation) - - "⩲": [T: "es igual a con signo más encima"] # 0x2a72 (en: 'equals with plus above') - - "": [T: "es igual a con signo más debajo"] # 0xe902 (en: 'equals with plus below', google translation) - - "⩱": [T: "es igual a con signo más debajo"] # 0x2a71 (en: 'equals with plus below') - - "": [T: "tilde con más encima"] # 0xe903 (en: 'tilde with plus above', google translation) - - "⨦": [T: "tilde con signo más encima"] # 0x2a26 (en: 'tilde with plus above') - - "": [T: "tilde signo más debajo"] # 0xe904 (en: 'tilde with plus below', google translation) - - "⨤": [T: "tilde con signo más debajo"] # 0x2a24 (en: 'tilde with plus below') - - "": [T: "doble signo igual sobre mayor que"] # 0xe908 (en: 'equal double over greater than', google translation) - - "": [T: "doble signo igual sobre menor que"] # 0xe909 (en: 'equal double over less than', google translation) - - "⪙": [T: "doble signo igual sobre menor que"] # 0x2a99 (en: 'equal double over less than') - - "": [T: "contiene o igual a"] # 0xe90a (en: 'contains or equal to', google translation) - - "⋽": [T: "contiene o igual a"] # 0x22fd (en: 'contains or equal to') - - "": [T: "superconjunto de o igual a"] # 0xe90b (en: 'superset of or equal to', google translation) - - "": [T: "subconjunto de o igual a"] # 0xe90c (en: 'subset of or equal to', google translation) - - "": [T: "signo igual sobre signo menor que"] # 0xe90d (en: 'equal over less than', google translation) - - "": [T: "elemento de o igual a"] # 0xe912 (en: 'element of or equal to', google translation) - - "⋷": [T: "elemento de o igual a"] # 0x22f7 (en: 'element of or equal to') - - "": [T: "igual a o mayor que"] # 0xe913 (en: 'equal to or greater than', google translation) - - "⪚": [T: "mayor que o igual a"] # 0x2a9a (en: 'equal to or greater than') - - "": [T: "superconjunto aproximado de"] # 0xe914 (en: 'approximate superset of', google translation) - - "⫈": [T: "contiene aproximadamente a"] # 0x2ac8 (en: 'approximate superset of') - - "": [T: "subconjunto aproximado de"] # 0xe915 (en: 'approximate subset of', google translation) - - "⫇": [T: "incluido aproximadamente en"] # 0x2ac7 (en: 'approximate subset of') - - "": [T: "superconjunto de con punto incluido como sub-relación"] # 0xe916 (en: 'superset of with dot includes as sub relation', google translation) - - "⪾": [T: "contiene como sub-relación a"] # 0x2abe (en: 'superset of with dot includes as sub relation') - - "": [T: "el subconjunto de con dot se incluye en una subselección"] # 0xe917 (en: 'subset of with dot is included in as sub relation', google translation) - - "⪽": [T: "sub-relación de"] # 0x2abd (en: 'subset of with dot is included in as sub relation') - - "": [T: "signo igual a con punto debajo"] # 0xe918 (en: 'equal with dot below', google translation) - - "⩦": [T: "signo igual a con punto debajo"] # 0x2a66 (en: 'equal with dot below') - - "": [T: "punto izquierdo sobre signo menos sobre punto derecho"] # 0xe919 (en: 'left dot over minus over right dot', google translation) - - "": [T: "punto derecho sobre signo menos sobre punto izquierdo"] # 0xe91a (en: 'right dot over minus over left dot', google translation) - - "": [T: "casi igual a menos"] # 0xe91f (en: 'almost equal to minus', google translation) - - "": [T: "taza doble cuadrada"] # 0xe920 (en: 'double square cup', google translation) - - "": [T: "doble cuadrado en mayúsculas"] # 0xe921 (en: 'double square cap', google translation) - - "": [T: "menor que igual o mayor que"] # 0xe922 (en: 'less than equal to or greater than', google translation) - - "": [T: "tilde con punto"] # 0xe924 (en: 'tilde with dot', google translation) - - "⩪": [T: "tilde con punto"] # 0x2a6a (en: 'tilde with dot') - - "": [T: "tilde con dos puntos"] # 0xe925 (en: 'tilde with two dots', google translation) - - "": [T: "menor que mayor o igual a"] # 0xe926 (en: 'less than greater than or equal to', google translation) - - "⪑": [T: "menor que mayor que o igual a"] # 0x2a91 (en: 'less than greater than or equal to') - - "": [T: "mayor que menor que o igual a"] # 0xe927 (en: 'greater than less than or equal to', google translation) - - "⪒": [T: "mayor que menor que o igual a"] # 0x2a92 (en: 'greater than less than or equal to') - - "": [T: "equivalente a o menor que"] # 0xe928 (en: 'equivalent to or less than', google translation) - - "⪝": [T: "equivalente a o menor que"] # 0x2a9d (en: 'equivalent to or less than') - - "": [T: "equivalente a o mayor que"] # 0xe929 (en: 'equivalent to or greater than', google translation) - - "": [T: "operador de caja abierta izquierda"] # 0xe92a (en: 'left open box operator', google translation) - - "": [T: "operador de caja abierta derecha"] # 0xe92b (en: 'right open box operator', google translation) - - "": [T: "idéntico a con punto"] # 0xe92c (en: 'identical to with dot', google translation) - - "": [T: "mayor que igual a o menor que"] # 0xe92d (en: 'greater than equal to or less than', google translation) - - "": [T: "operador de barra"] # 0xe92e (en: 'bar operator', google translation) - - "": [T: "operador de doble barra"] # 0xe92f (en: 'double bar operator', google translation) - - "": [T: "operador de triple barra"] # 0xe930 (en: 'triple bar operator', google translation) - - "": [T: "menor que o aproximadamente igual a"] # 0xe932 (en: 'less than or approximately equal to', google translation) - - "": [T: "mayor que o aproximadamente igual a"] # 0xe933 (en: 'greater than or approximately equal to', google translation) - - "": [T: "menor que anidado"] # 0xe936 (en: 'nested less than', google translation) - - "⪡": [T: "mucho menor que"] # 0x2aa1 (en: 'nested less than') - - "": [T: "mayor que anidado"] # 0xe937 (en: 'nested greater than', google translation) - - "⪢": [T: "mucho mayor que"] # 0x2aa2 (en: 'nested greater than') - - "": [T: "precede o equivalente a"] # 0xe93a (en: 'precedes or equivalent to', google translation) - - "": [T: "sucede o equivalente a"] # 0xe93b (en: 'succeeds or equivalent to', google translation) - - "": [T: "precede sobre signo igual"] # 0xe940 (en: 'precedes over equal', google translation) - - "": [T: "sucede sobre signo igual"] # 0xe941 (en: 'succeeds over equal', google translation) - - "": [T: "menor igual inclinado mayor"] # 0xe942 (en: 'less equal slanted greater', google translation) - - "": [T: "mayor igual inclinado menor"] # 0xe943 (en: 'greater equal slanted less', google translation) - - "": [T: "satisfecho por"] # 0xe948 (en: 'satisfied by', google translation) - - "": [T: "lazy s"] # 0xe949 (en: 'lazy s', google translation) - - "": [T: "no afirmación"] # 0xe94a (en: 'not assertion', google translation) - - "": [T: "doble igual"] # 0xe94b (en: 'double equal', google translation) - - "⩵": [T: "doble igual"] # 0x2a75 (en: 'double equal') - - "": [T: "triple igual"] # 0xe94c (en: 'triple equal', google translation) - - "": [T: "regla retardada"] # 0xe94d (en: 'rule delayed', google translation) - - "⧴": [T: "regla retardada"] # 0x29f4 - - "": [T: "delimitador de alias"] # 0xe94e (en: 'alias delimiter', google translation) - - "": [T: "subgrupo normal de con barra"] # 0xe950 (en: 'normal subgroup of with bar', google translation) - - "⧏": [T: "subgrupo normal o igual a"] # 0x29cf (en: 'normal subgroup of with bar') - - "": [T: "contiene como subgrupo normal con barra"] # 0xe951 (en: 'contains as normal subgroup with bar', google translation) - - "⧐": [T: "contiene como subgrupo normal o es igual a"] # 0x29d0 (en: 'contains as normal subgroup with bar') - - "": [T: "implica circular"] # 0xe954 (en: 'round implies', google translation) - - "⥰": [T: "implica circular"] # 0x2970 - - "": [T: "emoticono de sonrisa debajo de una barra"] # 0xe955 (en: 'smile under bar', google translation) - - "": [T: "emoticono de ceño fruncido sobe barra"] # 0xe956 (en: 'frown over bar', google translation) - - "": [T: "superconjunto de o casi igual a"] # 0xe957 (en: 'superset of or almost equal to', google translation) - - "": [T: "subconjunto de o casi igual a"] # 0xe958 (en: 'subset of or almost equal to', google translation) - - "": [T: "mayor que casi igual a o menor que"] # 0xe959 (en: 'greater than almost equal to or less than', google translation) - - "": [T: "menor que casi igual a o mayor que"] # 0xe95a (en: 'less than almost equal or greater than', google translation) - - "": [T: "doble o lógica"] # 0xe95c (en: 'double logical or', google translation) - - "⩔": [T: "o"] # 0x2a54 (en: 'double logical or') - - "": [T: "doble y lógica"] # 0xe95d (en: 'double logical and', google translation) - - "⩓": [T: "y"] # 0x2a53 (en: 'double logical and') - - "": [T: "o lógica con doble barra debajo"] # 0xe95e (en: 'logical or with double bar below', google translation) - - "": [T: "o lógica con barra debajo"] # 0xe95f (en: 'logical or with bar below', google translation) - - "": [T: "casi igual sobre igual"] # 0xe962 (en: 'almost equal over equal', google translation) - - "": [T: "triángulo apuntando a la izquierda con barra bisectriz"] # 0xe964 - - "": [T: "triángulo apuntando a la derecha con barra bisectriz"] # 0xe965 (en: 'right pointing triangle with bisecting bar', google translation) - - "": [T: "es igual a la línea punteada superior"] # 0xe966 (en: 'equals with dotted top line', google translation) - - "": [T: "precede con dos puntos"] # 0xe967 (en: 'precedes with colon', google translation) - - "": [T: "sucede con dos puntos"] # 0xe968 (en: 'succeeds with colon', google translation) - - "": [T: "más pequeño o igual inclinado"] # 0xe969 (en: 'smaller than or equal slanted', google translation) - - "": [T: "más grande o igual inclinado"] # 0xe96a (en: 'larger than or equal slanted', google translation) - - "": [T: "mucho menor que anidado"] # 0xe96b (en: 'nested very much less than', google translation) - - "": [T: "mucho mayor que anidado"] # 0xe96c (en: 'nested very much greater than', google translation) - - "": [T: "diferencia entre variantes"] # 0xe96d (en: 'difference between variant', google translation) - - "⪮": [T: "diferencia entre"] # 0x2aae (en: 'difference between variant') - - "": [T: "superposición de menor que mayor que"] # 0xe96e (en: 'less than greater than overlay', google translation) - - "⪤": [T: "superposición de menor que mayor que"] # 0x2aa4 (en: 'less than greater than overlay') - - "": [T: "o lógica y lógica superpuestas"] # 0xe96f (en: 'logical or logical and overlay', google translation) - - "": [T: "superconjunto sobre superconjunto"] # 0xe970 (en: 'superset over superset', google translation) - - "⫖": [T: "superconjunto sobre superconjunto"] # 0x2ad6 (en: 'superset over superset') - - "": [T: "subconjunto sobre subconjunto"] # 0xe971 (en: 'subset over subset', google translation) - - "⫕": [T: "subconjunto por encima de subconjunto"] # 0x2ad5 (en: 'subset over subset') - - "": [T: "superconjunto sobre subconjunto"] # 0xe972 (en: 'superset over subset', google translation) - - "⫔": [T: "contiene o está incluido en"] # 0x2ad4 (en: 'superset over subset') - - "": [T: "subconjunto sobre superconjunto"] # 0xe973 (en: 'subset over superset', google translation) - - "⫓": [T: "está incluido o contiene a"] # 0x2ad3 (en: 'subset over superset') - - "": [T: "triple barra vertical"] # 0xe979 (en: 'triple vertical bar', google translation) - - "": [T: "puntos verticales cuádruples emparejados"] # 0xe97a (en: 'paired quadruple vertical dots', google translation) - - "": [T: "perpendicular sobre barra"] # 0xe97b (en: 'perpendicular over bar', google translation) - - "⫨": [T: "perpendicular sobre barra"] # 0x2ae8 (en: 'perpendicular over bar') - - "": [T: "doble barra vertical con torniquete a la izquierda"] # 0xe97c (en: 'left turnstile double vertical bar', google translation) - - "": [T: "doble barra vertical con doble torniquete a la izquierda"] # 0xe97d (en: 'double left turnstile double vertical bar', google translation) - - "": [T: "perpendicular sobre perpendicular invertida"] # 0xe97e (en: 'perpendicular over inverted perpendicular', google translation) - - "": [T: "barra vertical con doble torniquete a la izquierda"] # 0xe97f (en: 'double left turnstile vertical bar', google translation) - - "⫤": [T: "barra vertical con doble torniquete a la izquierda"] # 0x2ae4 - - "": [T: "apertura de ángulo esférico"] # 0xe980 (en: 'spherical angle opening up', google translation) - - "": [T: "doble barra"] # 0xe981 (en: 'double slash', google translation) - - "": [T: "ángulo recto con esquina"] # 0xe982 (en: 'right angle with corner', google translation) - - "": [T: "barra vertical rodeada por un círculo"] # 0xe984 (en: 'circled vertical bar', google translation) - - "⦶": [T: "barra vertical rodeada por un círculo"] # 0x29b6 (en: 'circled vertical bar') - - "": [T: "signo de división rodeado por un círculo"] # 0xe985 (en: 'circled division sign', google translation) - - "⨸": [T: "signo de división rodeado por un círculo"] # 0x2a38 (en: 'circled division sign') - - "": [T: "solidus discontinuo"] # 0xe986 (en: 'dashed solidus', google translation) - - "": [T: "barra inversa discontinua"] # 0xe987 (en: 'dashed backslash', google translation) - - "": [T: "línea media discontinua"] # 0xe988 (en: 'dashed mid line', google translation) - - "": [T: "barra vertical discontinua"] # 0xe989 (en: 'dashed vertical bar', google translation) - - "": [T: "perpendicular con s"] # 0xe98a (en: 'perpendicular with s', google translation) - - "": [T: "ángulo con s"] # 0xe98b (en: 'angle with s', google translation) - - "": [T: "apertura izquierda en ángulo esférico"] # 0xe98c (en: 'spherical angle opening left', google translation) - - "": [T: "apertura angular izquierda"] # 0xe98d (en: 'angle opening left', google translation) - - "": [T: "barra vertical con doble garfio"] # 0xe98e (en: 'vertical bar with double hook', google translation) - - "⥾": [T: "barra vertical con doble garfio"] # 0x297e (en: 'vertical bar with double hook') - - "": [T: "operador de punto medio radical libre"] # 0xe98f (en: 'medium dot operator free radical', google translation) - - "": [T: "blanco apuntando al triángulo sobre la barra"] # 0xe990 (en: 'white up pointing triangle above bar', google translation) - - "": [T: "idéntico y paralelo a"] # 0xe991 (en: 'identical and parallel to', google translation) - - "": [T: "smash product"] # 0xe992 (en: 'smash product', google translation) - - "⨳": [T: "smash product"] # 0x2a33 - - "": [T: "operador de triple barra con barra horizontal"] # 0xe993 (en: 'triple bar operator with horizontal bar', google translation) - - "": [T: "idéntico a con doble barra cortada"] # 0xe994 (en: 'identical to with double slash', google translation) - - "⧥": [T: "idéntico a con doble barra cortada"] # 0x29e5 (en: 'identical to with double slash') - - "": [T: "barras triples cruzadas"] # 0xe995 (en: 'triple crossed bars', google translation) - - "": [T: "barra vertical sobre círculo"] # 0xe996 (en: 'vertical bar over circle', google translation) - - "": [T: "vertical proporcional a"] # 0xe997 (en: 'vertical proportional to', google translation) - - "": [T: "luna en cuarto menguante"] # 0xe998 (google translation) - - "": [T: "cuarto creciente"] # 0xe999 (google translation) - - "": [T: "onda sinusoidal negativa"] # 0xe9a0 (en: 'negative sine wave', google translation) - - "": [T: "punto entre paréntesis"] # 0xe9a1 (en: 'parenthesized dot', google translation) - - "": [T: "paréntesis"] # 0xe9a2 (en: 'parens', google translation) - - "": [T: "emoticono de sonrisa blanca"] # 0xe9a3 (en: 'white smile', google translation) - - "": [T: "emoticono de ceño fruncido"] # 0xe9a4 (en: 'white frown', google translation) - - "": [T: "hexágono"] # 0xe9a5 (en: 'hexagon', google translation) - - "": [T: "equivalente a sobre signo más"] # 0xe9a6 (en: 'equivalent to over plus', google translation) - - "": [T: "signo más sobre equivalente a"] # 0xe9a7 (en: 'plus over equivalent to', google translation) - - "": [T: "intersección serifs"] # 0xe9b0 (en: 'intersection serifs', google translation) - - "": [T: "union serifs"] # 0xe9b1 (google translation) - - "": [T: "intersección cuadrada serifs"] # 0xe9b2 (en: 'square intersection serifs', google translation) - - "": [T: "unión cuadrada serifs"] # 0xe9b3 (google translation) - - "": [T: "precede equivalente a o sucede a"] # 0xe9e0 (en: 'precedes equivalent to or succeeds', google translation) - - "": [T: "sucede equivalente a o precede"] # 0xe9e1 (en: 'succeeds equivalent to or precedes', google translation) - - "": [T: "precede casi igual a o sucede a"] # 0xe9e2 (en: 'precedes almost equal to or succeeds', google translation) - - "": [T: "sucede casi igual o precede"] # 0xe9e3 (en: 'succeeds almost equal to or precedes', google translation) - - "": [T: "menor que equivalente a o mayor que"] # 0xe9f0 (en: 'less than equivalent to or greater than', google translation) - - "": [T: "mayor que equivalente a o menor que"] # 0xe9f1 (en: 'greater than equivalent to or less than', google translation) - - "": [T: "no vert mucho menor que"] # 0xea00 (en: 'not vert much less than', google translation) - - "": [T: "no vert mucho mayor que"] # 0xea01 (en: 'not vert much greater than', google translation) - - "": [T: "variante no mucho menor que"] # 0xea02 (en: 'not much less than variant', google translation) - - "": [T: "variante no mucho mayor que"] # 0xea03 (en: 'not much greater than variant', google translation) - - "": [T: "menor que vert no signos igual doble"] # 0xea04 (en: 'less vert not double equals', google translation) - - "": [T: "gt vert no doble signo igual"] # 0xea05 (en: 'gt vert not double equals', google translation) - - "": [T: "no menor que o igual a"] # 0xea06 (en: 'not less than or equal to', google translation) - - "": [T: "no mayor que o igual a"] # 0xea07 (en: 'not greater than or equal to', google translation) - - "": [T: "ni igual a ni menor que"] # 0xea09 (en: 'neither equal to nor less than', google translation) - - "": [T: "no contiene ni igual a"] # 0xea0a (en: 'does not contain or equal to', google translation) - - "": [T: "ni superconjunto ni igual a"] # 0xea0b (en: 'neither superset of nor equal to', google translation) - - "": [T: "ni subconjunto ni igual a"] # 0xea0c (en: 'neither subset of nor equal to', google translation) - - "": [T: "subconjunto con solidus invertido"] # 0xea0d (en: 'reverse solidus subset', google translation) - - "": [T: "ni igual a ni mayor que"] # 0xea0e (en: 'neither equal to nor greater than', google translation) - - "": [T: "no menos operador tilde"] # 0xea0f (en: 'not minus tilde operator', google translation) - - "": [T: "ni igual a ni menor que"] # 0xea10 (en: 'neither equal to nor less than', google translation) - - "": [T: "no operador tilde"] # 0xea11 (en: 'not tilde operator', google translation) - - "": [T: "ni elemento de ni igual a"] # 0xea12 (en: 'not element of or equal to', google translation) - - "": [T: "ni igual ni mayor que"] # 0xea13 (en: 'neither equal to nor greater than', google translation) - - "": [T: "no casi igual"] # 0xea14 (en: 'not almost equal', google translation) - - "": [T: "no sucede similar"] # 0xea15 (en: 'not succeeds similar', google translation) - - "": [T: "menor que o igual a inclinado con barra cortada"] # 0xea16 (en: 'less than or slanted equal to with slash', google translation) - - "": [T: "mayor que o igual a inclinado con barra cortada"] # 0xea17 (en: 'greater than or slanted equal to with slash', google translation) - - "": [T: "superconjunto solidus"] # 0xea1a (google translation) - - "": [T: "no contiene"] # 0xea1b (en: 'does not contain', google translation) - - "": [T: "no menor que o igual a"] # 0xea1d (en: 'not less than or equal to', google translation) - - "": [T: "no mayor que o igual a"] # 0xea1e (en: 'not greater than or equal to', google translation) - - "": [T: "no casi igual a menos"] # 0xea1f (en: 'not almost equal to minus', google translation) - - "": [T: "conjunto negado de afiliación con punto encima"] # 0xea22 (en: 'negated set membership dot above', google translation) - - "": [T: "no ángulo de vert"] # 0xea2c (en: 'not vert angle', google translation) - - "": [T: "no paralelo inclinado"] # 0xea2d (en: 'not parallel slanted', google translation) - - "": [T: "no operador de barra"] # 0xea2e (en: 'not bar operator', google translation) - - "": [T: "no operador de barra doble"] # 0xea2f (en: 'not double bar operator', google translation) - - "": [T: "no operador de triple barra"] # 0xea30 (en: 'not triple bar operator', google translation) - - "": [T: "menor que pero no aproximadamente igual a"] # 0xea32 (en: 'less than but not approximately equal to', google translation) - - "⪉": [T: "menor que pero no aproximadamente igual a"] # 0x2a89 (en: 'less than but not approximately equal to') - - "": [T: "mayor que pero no aproximadamente igual a"] # 0xea33 (en: 'greater than but not approximately equal to', google translation) - - "⪊": [T: "mayor que pero no aproximadamente igual a"] # 0x2a8a (en: 'greater than but not approximately equal to') - - "": [T: "menor que o no igual a"] # 0xea34 (en: 'less than or not equal to', google translation) - - "": [T: "mayor que o no igual a"] # 0xea35 (en: 'greater than or not equal to', google translation) - - "": [T: "menor que no anidado"] # 0xea36 (en: 'not nested less than', google translation) - - "": [T: "mayor que no anidado"] # 0xea37 (en: 'not nested greater than', google translation) - - "": [T: "no mucho menor que"] # 0xea38 (en: 'not much less than', google translation) - - "": [T: "no mucho mayor que"] # 0xea39 (en: 'not much greater than', google translation) - - "": [T: "precede pero no equivalente a"] # 0xea3a (en: 'precedes but not equivalent to', google translation) - - "": [T: "sucede pero no equivalente a"] # 0xea3b (en: 'succeeds but not equivalent to', google translation) - - "": [T: "precede pero no es igual a"] # 0xea3c (en: 'precedes but not equal to', google translation) - - "": [T: "sucede pero no es igual a"] # 0xea3d (en: 'succeeds but not equal to', google translation) - - "": [T: "ni es igual a ni precede"] # 0xea3e (en: 'does not equal or precede', google translation) - - "": [T: "ni es igual a ni sucede"] # 0xea3f (en: 'does not equal or succeed', google translation) - - "": [T: "precede pero no es igual a"] # 0xea40 (en: 'precedes but not equal to', google translation) - - "⪵": [T: "precede pero no es igual a"] # 0x2ab5 (en: 'precedes but not equal to') - - "": [T: "sucede pero no es igual a"] # 0xea41 (en: 'succeeds but not equal to', google translation) - - "⪶": [T: "sucede pero no es igual a"] # 0x2ab6 (en: 'succeeds but not equal to') - - "": [T: "ni subconjunto de ni igual a"] # 0xea42 (en: 'not subset of nor equal to', google translation) - - "": [T: "ni superconjunto de ni igual a"] # 0xea43 (en: 'not superset of nor equal to', google translation) - - "": [T: "subconjunto de o no igual a"] # 0xea44 (en: 'subset of or not equal to', google translation) - - "": [T: "superconjunto de o no igual a"] # 0xea45 (en: 'superset of or not equal to', google translation) - - "": [T: "ni subconjunto de ni igual a"] # 0xea46 (en: 'not subset of nor equal to', google translation) - - "": [T: "ni superconjunto de ni igual a"] # 0xea47 (en: 'not superset of nor equal to', google translation) - - "": [T: "no triple menor que"] # 0xea48 (en: 'not triple less than', google translation) - - "": [T: "no triple mayor que"] # 0xea49 (en: 'not triple greater than', google translation) - - "": [T: "no precede a igual"] - - "": [T: "no sucede a igual"] # 0xea4d (en: 'not succeeds equals', google translation) - - "": [T: "no subgrupo normal de con barra"] # 0xea50 (en: 'not normal subgroup of with bar', google translation) - - "": [T: "no contiene como subgrupo normal con barra"] # 0xea51 (en: 'does not contain as normal subgroup with bar', google translation) - - "": [T: "no diferencia entre"] # 0xea52 (en: 'not difference between', google translation) - - "": [T: "no geométricamente equivalente a"] # 0xea53 (en: 'not geometrically equivalent to', google translation) - - "": [T: "no vert similar"] # 0xea54 (en: 'not vert similar', google translation) - - "": [T: "no igual o similar"] # 0xea55 (en: 'not equal or similar', google translation) - - "": [T: "no vert aproximado"] # 0xea56 (en: 'not vert approximate', google translation) - - "": [T: "no aproximadamente idéntico a"] # 0xea57 (en: 'not approximately identical to', google translation) - - "": [T: "no bump igual"] # 0xea58 (en: 'not bumpy equals', google translation) - - "": [T: "ni un solo bumpy igual a"] # 0xea59 (en: 'not bumpy single equals', google translation) - - "": [T: "no punto igual"] # 0xea5a (en: 'not equal dot', google translation) - - "": [T: "inverso no equivalente"] # 0xea5b (en: 'reverse not equivalent', google translation) - - "": [T: "no subconjunto cuadrado"] # 0xea60 (en: 'not square subset', google translation) - - "": [T: "no superconjunto cuadrado"] # 0xea61 (en: 'not square superset', google translation) - - "": [T: "no casi igual sobre igual"] # 0xea62 (en: 'not almost equal over equal', google translation) - - "": [T: "no estrictamente equivalente a"] # 0xea63 (en: 'not strictly equivalent to', google translation) - - "": [T: "no congruente punto"] # 0xea64 (en: 'not congruent dot', google translation) - - "": [T: "reverso no es igual"] # 0xea65 (en: 'reverse not equal', google translation) - - "": [T: "no vert triángulo izquierdo es igual a"] # 0xea70 (en: 'not vert left triangle equals', google translation) - - "": [T: "no vert triángulo recto es igual a"] # 0xea71 (en: 'not vert right triangle equals', google translation) - - "": [T: "no parcial"] # 0xea80 (en: 'not partial', google translation) - - "": [T: "extensor de adornos de flecha"] # 0xeb00 (en: 'arrow embellishment extender', google translation) - - "": [T: "flecha hacia la derecha sobre flecha hacia la izquierda"] # 0xeb01 (en: 'arrow rightwards over arrow leftwards', google translation) - - "": [T: "flecha hacia la derecha sobre flecha hacia la izquierda"] # 0xeb02 (en: 'arrow rightwards over arrow leftwards', google translation) - - "": [T: "arpón a la derecha sobre arpón a la izquierda"] # 0xeb03 (en: 'harpoon right over harpoon left', google translation) - - "": [T: "arpón a la derecha sobre arpón a la izquierda"] # 0xeb04 (en: 'harpoon right over harpoon left', google translation) - - "": [T: "doble flecha al nordeste desde el sudoeste"] # 0xeb05 (en: 'double arrow northeast southwest', google translation) - - "": [T: "doble flecha al noroeste desde el sudeste"] # 0xeb06 (en: 'double arrow northwest southeast', google translation) - - "": [T: "extensor de arpón horizontal"] # 0xeb07 (en: 'horizontal harpoon extender', google translation) - - "": [T: "arco en sentido contrario a las agujas del reloj a la izquierda de flecha"] # 0xeb08 (en: 'anticlockwise arc leftwards arrow', google translation) - - "": [T: "arco en sentido contrario a las agujas del reloj a la derecha de flecha"] # 0xeb09 (en: 'anticlockwise arc rightwards arrow', google translation) - - "": [T: "acento con flecha grande hacia la derecha"] # 0xeb0b (en: 'large rightwards arrow accent', google translation) - - "": [T: "acento con flecha grande hacia la izquierda"] # 0xeb0c (en: 'large leftwards arrow accent', google translation) - - "": [T: "punta de flecha hacia la izquierda"] # 0xeb0d (en: 'leftwards arrowhead', google translation) - - "": [T: "punta de flecha hacia la derecha"] # 0xeb0e (en: 'rightwards arrowhead', google translation) - - "": [T: "gran flecha derecha izquierda con trazo"] # 0xeb0f (en: 'large left right arrow with stroke', google translation) - - "": [T: "extensor de flecha doble horizontal"] # 0xeb10 (en: 'horizontal double arrow extender', google translation) - - "": [T: "gran flecha doble izquierda derecha con trazo"] # 0xeb11 (en: 'large left right double arrow with stroke', google translation) - - "": [T: "flecha hacia abajo y hacia la izquierda de flecha hacia arriba"] # 0xeb12 (en: 'downwards arrow leftwards of upwards arrow', google translation) - - "⇵": [T: "flecha hacia arriba y a la derecha de flecha hacia abajo"] # 0x21f5 (en: 'downwards arrow leftwards of upwards arrow') - - "": [T: "flecha hacia la izquierda con la esquina hacia abajo"] # 0xeb13 (en: 'leftwards arrow with corner downwards', google translation) - - "": [T: "flecha hacia la derecha con la esquina hacia arriba"] # 0xeb14 (en: 'rightwards arrow with corner upwards', google translation) - - "": [T: "flecha hacia la izquierda con la esquina hacia arriba"] # 0xeb15 (en: 'leftwards arrow with corner upwards', google translation) - - "": [T: "flecha superior semicircular en sentido contrario a las agujas del reloj con signo más"] # 0xeb16 (en: 'anticlockwise top semicircle arrow with plus', google translation) - - "⤽": [T: "flecha superior semicircular en sentido contrario a las agujas del reloj con signo más"] # 0x293d (en: 'anticlockwise top semicircle arrow with plus') - - "": [T: "flecha superior semicircular en sentido a las agujas del reloj con signo menos"] # 0xeb17 (en: 'clockwise top semicircle arrow with minus', google translation) - - "⤼": [T: "flecha superior semicircular en sentido a las agujas del reloj con signo menos"] # 0x293c (en: 'clockwise top semicircle arrow with minus') - - "": [T: "flecha hacia la derecha con cola con trazo"] # 0xeb18 (en: 'rightwards arrow with tail with stroke', google translation) - - "": [T: "arpón derecho hacia abajo"] # 0xeb19 (en: 'right harpoon down', google translation) - - "": [T: "arpón izquierdo hacia abajo"] # 0xeb1a (en: 'left harpoon down', google translation) - - "": [T: "arpón derecho izquierdo hacia abajo"] # 0xeb1b (en: 'left right harpoon down', google translation) - - "⥐": [T: "arpón derecho izquierdo hacia abajo"] # 0x2950 (en: 'left right harpoon down', MathPlayer: 'arpón inferior derecha-izquierda', google: 'arpón derecho izquierdo hacia abajo') - - "": [T: "arpón derecho izquierdo hacia arriba"] # 0xeb1c (en: 'left right harpoon up', google translation) - - "⥎": [T: "arpón izquierdo derecho hacia arriba"] # 0x294e (en: 'left right harpoon up', MathPlayer: 'arpón superior derecha-izquierda', google: 'arpón derecho izquierdo hacia arriba') - - "": [T: "arpón izquierdo arriba y abajo"] # 0xeb1d (en: 'up down harpoon left', google translation) - - "⥑": [T: "arpón izquierdo arriba y abajo"] # 0x2951 (en: 'up down harpoon left') - - "": [T: "arpón derecho arriba y abajo"] # 0xeb1e (en: 'up down harpoon right', google translation) - - "⥏": [T: "arpón derecho arriba y abajo"] # 0x294f (en: 'up down harpoon right') - - "": [T: "flecha hacia arriba a la derecha de flecha hacia abajo"] # 0xeb1f (en: 'upwards arrow to the right of downwards arrow', google translation) - - "⇵": [T: "flecha hacia arriba a la derecha de flecha hacia abajo"] # 0x21f5 - - "": [T: "arpón hacia la izquierda a barra con punta hacia arriba"] # 0xeb20 (en: 'leftwards harpoon to bar with barb upwards', google translation) - - "⥒": [T: "arpón hacia la izquierda a barra con punta hacia arriba"] # 0x2952 (en: 'leftwards harpoon to bar with barb upwards', MathPlayer: 'leftwards harpoon to bar with barb upwards', google: 'arpón de la izquierda para bar con barb hacia arriba') - - "": [T: "arpón hacia la derecha a barra con punta hacia arriba"] # 0xeb21 (en: 'rightwards harpoon to bar with barb upwards', google translation) - - "⥓": [T: "arpón hacia la derechaa a barra con punta hacia arriba"] # 0x2953 (en: 'rightwards harpoon to bar with barb upwards', MathPlayer: 'rightwards harpoon to bar with barb upwards', google: 'arpoon a la derecha para bar con barb hacia arriba') - - "": [T: "arpón hacia la izquierda a barra con punta hacia abajo"] # 0xeb22 (en: 'leftwards harpoon to bar with barb downwards', google translation) - - "⥖": [T: "arpón hacia la izquierda a barra con punta hacia abajo"] # 0x2956 (en: 'leftwards harpoon to bar with barb downwards', MathPlayer: 'leftwards harpoon to bar with barb downwards', google: 'arpoon hacia la izquierda para bar con barb hacia abajo') - - "": [T: "arpón hacia la derecha a barra con punta hacia abajo"] # 0xeb23 (en: 'rightwards harpoon to bar with barb downwards', google translation) - - "⥗": [T: "arpón hacia la derecha a barra con punta hacia abajo"] # 0x2957 (en: 'rightwards harpoon to bar with barb downwards', MathPlayer: 'rightwards harpoon to bar with barb downwards', google: 'arpoon a la derecha para bar con barb hacia abajo') - - "": [T: "arpón hacia la izquierda partiendo de barra con punta hacia arriba"] # 0xeb24 (en: 'leftwards harpoon from bar with barb upwards', google translation) - - "⥚": [T: "arpón hacia la izquierda partiendo d barra con punta hacia arriba"] # 0x295a (en: 'leftwards harpoon from bar with barb upwards', MathPlayer: 'leftwards harpoon from bar with barb upwards', google: 'arpón de la izquierda desde el bar con barb al alza') - - "": [T: "arpón hacia la derecha partiendo de barra con punta hacia arriba"] # 0xeb25 (en: 'rightwards harpoon from bar with barb upwards', google translation) - - "⥛": [T: "arpón hacia la derecha partiendo de barra con punta hacia arriba"] # 0x295b (en: 'rightwards harpoon from bar with barb upwards', MathPlayer: 'rightwards harpoon from bar with barb upwards', google: 'arpoon a la derecha desde el bar con barb al alza') - - "": [T: "arpón hacia la izquierda partiendo de barra con punta hacia abajo"] # 0xeb26 (en: 'leftwards harpoon from bar with barb downwards', google translation) - - "⥞": [T: "arpón hacia la izquierda partiendo de barra con punta hacia abajo"] # 0x295e (en: 'leftwards harpoon from bar with barb downwards', MathPlayer: 'leftwards harpoon from bar with barb downwards', google: 'arpón de la izquierda desde el bar con barb hacia abajo') - - "": [T: "arpón hacia la derecha partiendo de barra con punta hacia abajo"] # 0xeb27 (en: 'rightwards harpoon from bar with barb downwards', google translation) - - "⥟": [T: "arpón hacia la derecha partiendo de barra con punta hacia abajo"] # 0x295f (en: 'rightwards harpoon from bar with barb downwards', MathPlayer: 'rightwards harpoon from bar with barb downwards', google: 'arpoon a la derecha desde el bar con barb hacia abajo') - - "": [T: "arpón hacia arriba a barra con punta a la izquierda"] # 0xeb28 (en: 'upwards harpoon to bar with barb leftwards', google translation) - - "⥘": [T: "arpón hacia arriba a barra con púa a la izquierda"] # 0x2958 (en: 'upwards harpoon to bar with barb leftwards', MathPlayer: 'upwards harpoon to bar with barb leftwards', google: 'hace arriba hacia arriba para bar con barb a la izquierda') - - "": [T: "arpón hacia abajo a barra con punta hacia la izquierda"] # 0xeb29 (en: 'downwards harpoon to bar with barb leftwards', google translation) - - "⥙": [T: "arpón hacia abajo a barra con punta hacia la izquierda"] # 0x2959 (en: 'downwards harpoon to bar with barb leftwards', MathPlayer: 'downwards harpoon to bar with barb leftwards', google: 'harpoon hacia abajo para bar con barb a la izquierda') - - "": [T: "arpón hacia arriba a barra con punta hacia la derecha"] # 0xeb2a (en: 'upwards harpoon to bar with barb rightwards', google translation) - - "⥔": [T: "arpón hacia arriba a barra con punta hacia la derecha"] # 0x2954 (en: 'upwards harpoon to bar with barb rightwards', MathPlayer: 'upwards harpoon to bar with barb rightwards', google: 'hace arriba hacia arriba para bar con barb a la derecha') - - "": [T: "arpón hacia abajo a barra con punta hacia la derecha"] # 0xeb2b (en: 'downwards harpoon to bar with barb rightwards', google translation) - - "⥕": [T: "arpón hacia abajo a barra con punta hacia la derecha"] # 0x2955 (en: 'downwards harpoon to bar with barb rightwards', MathPlayer: 'downwards harpoon to bar with barb rightwards', google: 'harpoon hacia abajo para bar con barb a la derecha') - - "": [T: "arpón hacia harriba partiendo de barra con punta hacia la izquierda"] # 0xeb2c (en: 'upwards harpoon from bar with barb leftwards', google translation) - - "⥠": [T: "arpón hacia arriba partiendo de barra con punta hacia la izquierda"] # 0x2960 (en: 'upwards harpoon from bar with barb leftwards', MathPlayer: 'upwards harpoon from bar with barb leftwards', google: 'hacia arriba hacia arriba desde el bar con barb a la izquierda') - - "": [T: "arpón hacia abajo partiendo de barra con punta hacia la izquierda"] # 0xeb2d (en: 'downwards harpoon from bar with barb leftwards', google translation) - - "⥡": [T: "arpón hacia abajo partiendo de barra con punta hacia la izquierda"] # 0x2961 (en: 'downwards harpoon from bar with barb leftwards', MathPlayer: 'downwards harpoon from bar with barb leftwards', google: 'hosto hacia abajo de bar con barb a la izquierda') - - "": [T: "arpón hacia arriba partiendo de barra con punta hacia la derecha"] # 0xeb2e (en: 'upwards harpoon from bar with barb rightwards', google translation) - - "⥜": [T: "arpón hacia arriba partiendo de barra con punta hacia la derecha"] # 0x295c (en: 'upwards harpoon from bar with barb rightwards', MathPlayer: 'upwards harpoon from bar with barb rightwards', google: 'hace arriba hacia arriba desde el bar con barb a la derecha') - - "": [T: "arpón hacia abajo partiendo de barra con punta hacia la derecha"] # 0xeb2f (en: 'downwards harpoon from bar with barb rightwards', google translation) - - "⥝": [T: "arpón hacia abajo partiendo de barra con punta hacia la derecha"] # 0x295d (en: 'downwards harpoon from bar with barb rightwards', MathPlayer: 'downwards harpoon from bar with barb rightwards', google: 'hosto hacia abajo desde el bar con barb a la derecha') - - "": [T: "flecha hacia arriba a barra"] # 0xeb30 (en: 'upwards arrow to bar', google translation) - - "⤒": [T: "flecha hacia arriba a barra"] # 0x2912 - - "": [T: "flecha hacia abajo a barra"] # 0xeb31 (en: 'downwards arrow to bar', google translation) - - "⤓": [T: "flecha hacia abajo a barra"] # 0x2913 - - "": [T: "arpón hacia arriba a la izquierda de arpón hacia abajo"] # 0xeb32 (en: 'upwards harpoon to the left of downwards harpoon', google translation) - - "⥮": [T: "arpón hacia arriba a la izquierda de arpón hacia abajo"] # 0x296e (en: 'upwards harpoon to the left of downwards harpoon', MathPlayer: 'upwards harpoon to the left of downwards harpoon', google: 'hacia arriba harpoon a la izquierda de la arpón hacia abajo') - - "": [T: "arpón hacia arriba a la derecha de arpón hacia abajo"] # 0xeb33 (en: 'upwards harpoon to the right of downwards harpoon', google translation) - - "⥯": [T: "arpón hacia arriba a la derecha de arpón hacia abajo"] # 0x296f (en: 'upwards harpoon to the right of downwards harpoon', MathPlayer: 'upwards harpoon to the right of downwards harpoon', google: 'hacia arriba hacia arriba a la derecha de la arpón hacia abajo') - - "": [T: "punta de flecha hacia arriba"] # 0xeb34 (en: 'upwards arrowhead', google translation) - - "": [T: "punta de flecha hacia abajo"] # 0xeb35 (en: 'downwards arrowhead', google translation) - - "": [T: "doble arpón con punta hacia abajo a la izquierda y punta hacia arriba a la derecha"] # 0xeb36 (en: 'double harpoon with leftwards barb down rightwards barb up', google translation) - - "": [T: "doble arpón con punta hacia arriba a la izquierda y con punta hacia abajo a la derecha"] # 0xeb37 (en: 'double harpoon with leftwards barb up rightwards barb down', google translation) - - "": [T: "flecha hacia la izquierda sobre barra"] # 0xeb38 (en: 'leftwards arrow over bar', google translation) - - "": [T: "flecha hacia la derecha sobre barra"] # 0xeb39 (en: 'rightwards arrow over bar', google translation) - - "": [T: "flecha hacia la izquierda debajo de barra"] # 0xeb3a (en: 'leftwards arrow under bar', google translation) - - "": [T: "flecha hacia la derecha debajo de barra"] # 0xeb3b (en: 'rightwards arrow under bar', google translation) - - "": [T: "triple flecha derecha e izquierda"] # 0xeb3c (en: 'left right triple arrow', google translation) - - "": [T: "doble flecha nordeste sudeste"] # 0xeb3f (en: 'double arrow northeast southeast', google translation) - - "": [T: "flecha semicircular izquierda en sentido contrario a las agujas del reloj"] # 0xeb40 (en: 'anticlockwise left semicircle arrow', google translation) - - "⤹": [T: "flecha semicircular izquierda en sentido contrario a las agujas del reloj"] # 0x2939 (en: 'anticlockwise left semicircle arrow') - - "": [T: "flecha semicircular izquierda en sentido a las agujas del reloj"] # 0xeb41 (en: 'clockwise left semicircle arrow', google translation) - - "": [T: "círculo abierto izquierdo flecha derecha izquierda"] # 0xeb42 (en: 'left open circle left right arrow', google translation) - - "": [T: "flecha hacia la derecha sobre tilde"] # 0xeb44 (en: 'rightwards arrow over tilde', google translation) - - "⥴": [T: "flecha hacia la derecha sobre tilde"] # 0x2974 (en: 'rightwards arrow over tilde') - - "": [T: "flecha hacia la izquierda sobre tilde"] # 0xeb45 (en: 'leftwards arrow over tilde', google translation) - - "⥳": [T: "flecha hacia la derecha sobre tilde"] # 0x2973 (en: 'leftwards arrow over tilde') - - "": [T: "arpón hacia la izquierda sobre barra"] # 0xeb48 (en: 'leftwards harpoon over bar', google translation) - - "⥪": [T: "arpón hacia la izquierda sobre barra"] # 0x296a (en: 'leftwards harpoon over bar') - - "": [T: "arpón hacia la derecha sobre barra"] # 0xeb49 (en: 'rightwards harpoon over bar', google translation) - - "⥬": [T: "arpón hacia la derecha sobre barra"] # 0x296c (en: 'rightwards harpoon over bar') - - "": [T: "arpón hacia la izquierda debajo de barra"] # 0xeb4a (en: 'leftwards harpoon under bar', google translation) - - "⥫": [T: "arpón hacia la izquierda debajo de barra"] # 0x296b (en: 'leftwards harpoon under bar') - - "": [T: "arpón hacia la derecha debajo de barra"] # 0xeb4b (en: 'rightwards harpoon under bar', google translation) - - "⥭": [T: "arpón hacia la derecha debajo de barra"] # 0x296d (en: 'rightwards harpoon under bar') - - "": [T: "flecha corta negra hacia la izquierda"] # 0xeb4c (en: 'squat black leftwards arrow', google translation) - - "": [T: "flecha semicircular derecha en sentido a las agujas del reloj"] # 0xeb50 (en: 'clockwise right semicircle arrow', google translation) - - "⤸": [T: "flecha semicircular derecha en sentido a las agujas del relojt"] # 0x2938 (en: 'clockwise right semicircle arrow') - - "": [T: "flecha semicircular derecha en sentido contrario a las agujas del reloj"] # 0xeb51 (en: 'anticlockwise right semicircle arrow', google translation) - - "": [T: "círculo abierto izquierdo arpón izquierdo derecho"] # 0xeb52 (en: 'left open circle left right harpoon', google translation) - - "": [T: "flecha hacia arriba y hacia la izquierda de barra vertical"] # 0xeb58 (en: 'upwards arrow leftwards of vertical bar', google translation) - - "": [T: "flecha hacia abajo hacia la izquierda de barra vertical"] # 0xeb59 (en: 'downwards arrow leftwards of vertical bar', google translation) - - "": [T: "flecha hacia arriba hacia la derecha de barra vertical"] # 0xeb5a (en: 'upwards arrow rightwards of vertical bar', google translation) - - "": [T: "flecha hacia abajo hacia la derecha de barra vertical"] # 0xeb5b (en: 'downwards arrow rightwards of vertical bar', google translation) - - "": [T: "flecha hacia la derecha con garfio hacia abajo extendido"] # 0xeb5c (en: 'rightwards arrow with extended downwards hook', google translation) - - "": [T: "flecha hacia la izquierda con gancho extendido"] # 0xeb5d (en: 'leftwards arrow with extended hook', google translation) - - "": [T: "flecha hacia la izquierda con gancho hacia abajo extendido"] # 0xeb5e (en: 'leftwards arrow with extended downwards hook', google translation) - - "": [T: "flecha hacia la derecha con garfio extendido"] # 0xeb5f (en: 'rightwards arrow with extended hook', google translation) - - "": [T: "no flecha derecha ondulada"] # 0xeb60 (en: 'not right arrow wavy', google translation) - - "": [T: "no flecha derecha curva"] # 0xeb61 (en: 'not right arrow curved', google translation) - - "": [T: "arpón hacia arriba hacia la izquierda de barra vertical"] # 0xeb68 (en: 'upwards harpoon leftwards of vertical bar', google translation) - - "": [T: "arpoon hacia abajo hacia la izquierda de barra vertical"] # 0xeb69 (en: 'downwards harpoon leftwards of vertical bar', google translation) - - "": [T: "arpón hacia arriba hacia la derecha de barra vertical"] # 0xeb6a (en: 'upwards harpoon rightwards of vertical bar', google translation) - - "": [T: "arpón hacia abajo hacia la derecha de barra vertical"] # 0xeb6b (en: 'downwards harpoon rightwards of vertical bar', google translation) - - "": [T: "extensor de flecha doble vertical"] # 0xeb6c (en: 'vertical double arrow extender', google translation) - - "": [T: "arpón vertical con extensor de punta izquierda"] # 0xeb6d (en: 'vertical harpoon with barb left extender', google translation) - - "": [T: "arpón vertical con extensor de punta derecha"] # 0xeb6e (en: 'vertical harpoon with barb right extender', google translation) - - "": [T: "arpón derecho sobre arpón izquierdo a la derecha"] # 0xeb6f (en: 'right harpoon over left harpoon right', google translation) - - "": [T: "arpón derecho sobre arpón izquierdo a la izquierda"] # 0xeb70 (en: 'right harpoon over left harpoon left', google translation) - - "": [T: "arpón izquierdo sobre arpón derecho a la derecha"] # 0xeb71 (en: 'left harpoon over right harpoon right', google translation) - - "": [T: "arpón izquierdo sobre arpón derecho a la izquierda"] # 0xeb72 (en: 'left harpoon over right harpoon left', google translation) - - "": [T: "flecha hacia la izquierda partiendo de punta de flecha de barra"] # 0xeb73 (en: 'leftwards arrow from bar arrowhead', google translation) - - "": [T: "flecha hacia la izquierda y derecha partiendo de extensor de barra"] # 0xeb74 (en: 'leftwards rightwards arrow from bar extender', google translation) - - "": [T: "flecha hacia la izquierda partiendo de cola de barra"] # 0xeb75 (en: 'leftwards arrow from bar tail', google translation) - - "": [T: "flecha hacia la derecha partiendo de cola de barra"] # 0xeb76 (en: 'rightwards arrow from bar tail', google translation) - - "": [T: "flecha hacia la derecha partiendo de punta de flecha de barra"] # 0xeb77 (en: 'rightwards arrow from bar arrowhead', google translation) - - "": [T: "arpón hacia arriba partiendo de barra punzante con punta de flecha hacia la izquierda"] # 0xeb78 (en: 'upwards harpoon from bar with barb leftwards arrowhead', google translation) - - "": [T: "flecha hacia la derecha sobre flecha derecha hacia la izquierda"] # 0xeb79 (en: 'rightwards arrow over leftwards arrow right', google translation) - - "": [T: "flecha derecha sobre flecha izquierda hacia la izquierda"] # 0xeb7a (en: 'rightwards arrow over leftwards arrow left', google translation) - - "": [T: "flecha hacia la izquierda sobre flecha derecha hacia la derecha"] # 0xeb7b (en: 'leftwards arrow over rightwards arrow right', google translation) - - "": [T: "flecha hacia la izquierda sobre flecha derecha hacia la izquierda"] # 0xeb7c (en: 'leftwards arrow over rightwards arrow left', google translation) - - "": [T: "flecha hacia arriba partiendo de punta de flecha de barra"] # 0xeb7d (en: 'upwards arrow from bar arrowhead', google translation) - - "": [T: "flecha hacia arriba partiendo de la cola de la barra"] # 0xeb7e (en: 'upwards arrow from bar tail', google translation) - - "": [T: "flecha hacia abajo partiendo de la cola de la barra"] # 0xeb7f (en: 'downwards arrow from bar tail', google translation) - - "": [T: "flecha hacia abajo partiendo de la punta de flecha de la barra"] # 0xeb80 (en: 'downwards arrow from bar arrowhead', google translation) - - "": [T: "arpón hacia abajo partiendo de punta de flecha derecha de barra punzante"] # 0xeb81 (en: 'downwards harpoon from bar with barb rightwards arrowhead', google translation) - - "": [T: "arpón hacia arriba a la izquierda del fondo del arpón hacia abajo"] # 0xeb82 (en: 'upwards harpoon to the left of downwards harpoon bottom', google translation) - - "": [T: "arpón hacia arriba a la izquierda de extensor de arpón hacia abajo"] # 0xeb83 (en: 'upwards harpoon to the left of downwards harpoon extender', google translation) - - "": [T: "arpón hacia abajo a la izquierda de parte superior de arpón hacia arriba"] # 0xeb84 (en: 'downwards harpoon to the left of upwards harpoon top', google translation) - - "": [T: "arpón hacia arriba a la izquierda de parte superior de arpón hacia abajo"] # 0xeb85 (en: 'upwards harpoon to the left of downwards harpoon top', google translation) - - "": [T: "arpón hacia abajo a la izquierda de extensor de arpón hacia arriba"] # 0xeb86 (en: 'downwards harpoon to the left of the upwards harpoon extender', google translation) - - "": [T: "arpón hacia arriba a la izquierda de parte inferior d arpón hacia abajo"] # 0xeb87 (en: 'downwards harpoon to the left of the upwards harpoon bottom', google translation) - - "": [T: "flecha hacia arriba hacia la izquierda del fondo de flecha hacia abajo"] # 0xeb88 (en: 'upwards arrow leftwards of downwards arrow bottom', google translation) - - "": [T: "flecha hacia abajo hacia la izquierda de la parte superiorde flecha hacia arriba"] # 0xeb89 (en: 'downwards arrow leftwards of upwards arrow top', google translation) - - "": [T: "flecha hacia arriba hacia la izquierda de la parte superior de flecha hacia abajo"] # 0xeb8a (en: 'upwards arrow leftwards of downwards arrow top', google translation) - - "": [T: "flecha hacia abajo hacia la izquierda de la parte inferior de flecha hacia arriba"] # 0xeb8b (en: 'downwards arrow leftwards of upwards arrow bottom', google translation) - - "": [T: "extensor de flechas hacia izquierda y derecha"] # 0xeb8c (en: 'leftwards rightwards arrows extender', google translation) - - "": [T: "extensor de flecha nordeste"] # 0xeb8d (google translation) - - "": [T: "extensor de flecha noroeste"] # 0xeb8e (google translation) - - "": [T: "paréntesis izquierdo apuntando hacia abajo"] # 0xec00 (en: 'down pointing brace left', google translation) - - "": [T: "paréntesis medio apuntando hacia abajo"] # 0xec01 (google translation) - - "": [T: "paréntesis derecho apuntando hacia abajo"] # 0xec02 (en: 'down pointing brace right', google translation) - - "": [T: "extensor de paréntesis horizontal"] # 0xec03 (en: 'horizontal brace extender', google translation) - - "": [T: "paréntesis izquierdo apuntando hacia arriba"] # 0xec04 (en: 'up pointing brace left', google translation) - - "": [T: "paréntesis medio apuntando hacia arriba"] # 0xec05 (en: 'up pointing brace mid', google translation) - - "": [T: "paréntesis derecho apuntando hacia arriba"] # 0xec06 (en: 'up-pointing brace right', google translation) - - "": [T: "barra vertical izquierda"] # 0xec07 (en: 'left vertical bar', google translation) - - "": [T: "barra vertical derecha"] # 0xec08 (en: 'right vertical bar', google translation) - - "": [T: "doble barra vertical izquierda"] # 0xec09 (en: 'left double vertical bar', google translation) - - "": [T: "doble barra vertical derecha"] # 0xec0a (en: 'right double vertical bar', google translation) - - "": [T: "extensor de soporte horizontal"] # 0xec0b (en: 'horizontal bracket extender', google translation) - - "": [T: "debajo de corchete"] # 0xec0c (en: 'under square bracket', google translation) - - "⎵": [T: "debajo de corchete"] # 0x23b5 (en: 'under square bracket') - - "": [T: "encima de corchete"] # 0xec0d (en: 'over square bracket', google translation) - - "⎴": [T: "encima de corchete"] # 0x23b4 (en: 'over square bracket') - - "": [T: "debajo de paréntesis izquierdo"] # 0xec0e (en: 'under bracket left', google translation) - - "": [T: "debajo de paréntesis derecho"] # 0xec0f (en: 'under bracket right', google translation) - - "": [T: "sobre paréntesis izquierdo"] # 0xec10 (en: 'over bracket left', google translation) - - "": [T: "encima de paréntesis derecho"] # 0xec11 (en: 'over bracket right', google translation) - - "": [T: "abrir paréntesis 1"] # 0xec12 (en: 'left parens 1', google translation) - - "": [T: "abrir paréntesis 2"] # 0xec13 (en: 'left parens 2', google translation) - - "": [T: "abrir paréntesis 3"] # 0xec14 (en: 'left parens 3', google translation) - - "": [T: "abrir paréntesis 4"] # 0xec15 (en: 'left parens 4', google translation) - - "": [T: "cerrar paréntesis 1"] # 0xec16 (en: 'right parens 1', google translation) - - "": [T: "cerrar paréntesis 2"] # 0xec17 (en: 'right parens 2', google translation) - - "": [T: "cerrar paréntesis 3"] # 0xec18 (en: 'right parens 3', google translation) - - "": [T: "cerrar paréntesis 4"] # 0xec19 (en: 'right parens 4', google translation) - - "": [T: "radical 1"] # 0xec1a (google translation) - - "": [T: "radical 2"] # 0xec1b (google translation) - - "": [T: "radical 3"] # 0xec1c (google translation) - - "": [T: "radical 4"] # 0xec1d (google translation) - - "": [T: "radical 5"] # 0xec1e (google translation) - - "": [T: "radical inferior"] # 0xec1f (en: 'radical bottom', google translation) - - "": [T: "extensor de radical vertical"] # 0xec20 (en: 'radical vertical extender', google translation) - - "": [T: "radical superior"] # 0xec21 (en: 'radical top', google translation) - - "": [T: "soporte blanco izquierdo superior"] # 0xec22 (en: 'left white bracket top', google translation) - - "": [T: "extensor de soporte blanco izquierdo"] # 0xec23 (en: 'left white bracket extender', google translation) - - "": [T: "soporte blanco izquierdo inferior"] # 0xec24 (en: 'left white bracket bottom', google translation) - - "": [T: "soporte blanco derecho superior"] # 0xec25 (en: 'right white bracket top', google translation) - - "": [T: "extensor de soporte blanco derecho"] # 0xec26 (en: 'right white bracket extender', google translation) - - "": [T: "soporte blanco derecho inferior"] # 0xec27 (en: 'right white bracket bottom', google translation) - - "": [T: "soporte blanco izquierdo rotacional"] # 0xec30 (en: 'left white curly bracket', google translation) - - "": [T: "soporte blanco derecho rotacional"] # 0xec31 (en: 'right white curly bracket', google translation) - - "": [T: "signo de división largo"] # 0xec32 (google translation) - - "": [T: "extensor de signo de división largo"] # 0xec33 (en: 'long division sign extender', google translation) - - "": [T: "división corta"] # 0xec34 (en: 'short division', google translation) - - "": [T: "doble sudoeste al nordeste unión em"] # 0xec40 (en: 'double southwest to northeast em bond', google translation) - - "": [T: "doble noroeste al sudeste unión em"] # 0xec41 (en: 'double northwest to southeast em bond', google translation) - - "": [T: "enlace em horizontal único"] # 0xec42 (en: 'single horizontal em bond', google translation) - - "": [T: "doble enlace em horizontal"] # 0xec43 (en: 'double horizontal em bond', google translation) - - "": [T: "triple enlace em horizontal"] # 0xec44 (en: 'triple horizontal em bond', google translation) - - "": [T: "enlace em único vertical"] # 0xec45 (en: 'single vertical em bond', google translation) - - "": [T: "doble enlace em vertical"] # 0xec46 (en: 'double vertical em bond', google translation) - - "": [T: "triple enlace em vertical"] # 0xec47 (en: 'triple vertical em bond', google translation) - - "": [T: "menr que enlace em"] # 0xec48 (en: 'less than em bond', google translation) - - "": [T: "mayor que enlace em"] # 0xec49 (en: 'greater than em bond', google translation) - - "": [T: "enlace único horizontal"] # 0xec4a (en: 'single horizontal en bond', google translation) - - "": [T: "doble enlace horizontal en"] # 0xec4b (en: 'double horizontal en bond', google translation) - - "": [T: "triple enlace horizontal en"] # 0xec4c (en: 'triple horizontal en bond', google translation) - - "": [T: "rectángulo superior izquierdo"] # 0xec80 (en: 'top left rectangle', google translation) - - "": [T: "rectángulo inferior izquierdo"] # 0xec81 (en: 'bottom left rectangle', google translation) - - "": [T: "rectángulo superior derecho"] # 0xec90 (en: 'top right rectangle', google translation) - - "": [T: "rectángulo inferior derecho"] # 0xec91 (en: 'bottom right rectangle', google translation) - - "": [T: "intersección de división sintética"] # 0xec92 (en: 'synthetic division corner', google translation) - - "": [T: "extensor horizontal de división sintética"] # 0xec93 (en: 'synthetic division horizontal extender', google translation) - - "": [T: "extensor vertical de división sintética"] # 0xec94 (en: 'synthetic division vertical extender', google translation) - - "": [T: "extensor de límite izquierdo del fondo"] # 0xec95 (en: 'left ceiling floor extender', google translation) - - "": [T: "extensor de límite derecho del fondo"] # 0xec96 (en: 'right ceiling floor extender', google translation) - - "": [T: "por encima de extensor de soporte"] # 0xec97 (en: 'over bracket extender', google translation) - - "": [T: "extensor de barra vertical"] # 0xec98 (en: 'vertical bar extender', google translation) - - "": [T: "extensor de barra vertical doble izquierda"] # 0xec99 (en: 'left double vertical bar extender', google translation) - - "": [T: "extensor de barra horizontal"] # 0xec9a (en: 'horizontal bar extender', google translation) - - "": [T: "debajo de extensor de soporte"] # 0xec9c (en: 'under bracket extender', google translation) - - "": [T: "apuntando hacia abajo de paréntesis derecho"] # 0xec9d (en: 'down pointing paren right', google translation) - - "": [T: "apuntando hacia abajo de extensor de paréntesis"] # 0xec9e (en: 'down pointing paren extender', google translation) - - "": [T: "apuntando hacia abajo de paréntesis izquierdo"] # 0xec9f (en: 'down pointing paren left', google translation) - - "": [T: "apuntando hacia arriba de extensor de paréntesis"] # 0xeca0 (en: 'up pointing brace extender', google translation) - - "": [T: "apuntando hacia arriba de paréntesis de izquierda"] # 0xeca1 (en: 'up pointing paren left', google translation) - - "": [T: "apuntando hacia arriba de extensor de paréntesis"] # 0xeca2 (en: 'up pointing paren extender', google translation) - - "": [T: "apuntando hacia arriba de paréntesis derecho"] # 0xeca3 (en: 'up pointing paren right', google translation) - - "": [T: "apuntando hacia abajo de extensor de paréntesis"] # 0xeca4 (google translation) - - "": [T: "constante de Planck sobre dos barras pi"] # 0xed00 (en: 'planck constant over two pi bar', google translation) - - "": [T: "espejo g"] # 0xed01 (en: 'mirror g', google translation) - - "": [T: "j sin puntos"] # 0xed02 (google translation) - - "": [T: "digamma"] # 0xed03 (google translation) - - "ϝ": [T: "digamma"] # 0x3dd - - "": [T: "d"] # 0xed10 (en: 'd', google translation) - - "": [T: "e"] # 0xed11 (en: 'e', google translation) - - "": [T: "i"] # 0xed12 (en: 'i', google translation) - - "": [T: "j"] # 0xed13 (en: 'j', google translation) - - "ⅅ": - - spell: "translate('.', 'ⅅ', 'DD')" # 0xed16, 0x2145 - -# The private use chars are efrom MathType - - "": [T: "bucle integral de contorno en sentido contrario a las agujas del reloj"] # 0xee00 (en: 'anticlockwise contour integral loop', google translation) - - "": [T: "bucle integral de contorno en sentido de las agujas del reloj"] # 0xee01 (en: 'clockwise contour integral loop', google translation) - - "": [t: ""] # 0xee04 - - "": [t: ""] # 0xee05 - - "": [t: ""] # 0xee06 - - "": [t: ""] # 0xee07 - - "": [t: ""] # 0xee08 - - "": [t: ""] # 0xee09 - - "": [t: ""] # 0xee0a - - "": [t: ""] # 0xee0b - - "": [t: ""] # 0xee0c - - "": [T: "ornamentación de estatus conjunto"] # 0xee0d (en: 'joint status embellishment', google translation) - - "": [T: "ornamentación de estatus conjunto"] # 0xee0e (en: 'joint status embellishment left', google translation) - - "": [T: "ornamentación derecha de estatus conjunto"] # 0xee0f (en: 'joint status embellishment right', google translation) - - "": [T: "extensión de ornamentos de estatus conjunto"] # 0xee10 (en: 'joint status embellishment extender', google translation) - - "": [T: "bucle integral"] # 0xee11 (en: 'integral loop', google translation) - - "": [T: "doble bucle integral"] # 0xee12 (en: 'integral loop double', google translation) - - "": [T: "triple bucle integral"] # 0xee13 (en: 'integral loop triple', google translation) - - "": [T: "doble expansión de bucle integral"] # 0xee15 (en: 'expanding integral loop double', google translation) - - "": [T: "triple expansión de bucle integral"] # 0xee16 (en: 'expanding integral loop triple', google translation) - - "": [T: "asintóticamente igual al acento"] # 0xee17 (en: 'asymptotically equal to accent', google translation) - - "": [T: "signo igual a acetno"] # 0xee18 (en: 'equal sign accent', google translation) - - "": [T: "prima cuádruple"] # 0xee19 (en: 'quadruple prime', google translation) - - "⁗": [T: "prima cuádruple"] # 0x2057 (en: 'quadruple prime', MathPlayer: 'cuarta', google: 'prime cuádruple') - - "": [T: "acento de barra con círculo abierto izquierdo"] # 0xee1a (en: 'bar accent with open circle left', google translation) - - "": [T: "acento de barra con círculo cerrado izquierdo"] # 0xee1b (en: 'bar accent with closed circle left', google translation) - - "": [T: "acento de barra con círculo abierto derecho"] # 0xee1c (en: 'bar accent with open circle right', google translation) - - "": [T: "acento de barra con punto encima"] # 0xee1d (en: 'bar accent with over dot', google translation) - - "": [T: "acento de barra con punto debajo"] # 0xee1e (en: 'bar accent with under dot', google translation) - - "": [T: "acento de barra con doble punto encima"] # 0xee1f (en: 'bar accent with double over dot', google translation) - - "": [T: "acento de barra con doble punto debajo"] # 0xee20 (en: 'bar accent with double under dot', google translation) - - "": [T: "acento de barra con signo de intercalación"] # 0xee21 (en: 'bar accent with caret', google translation) - - "": [T: "marcado debajo de acento de barra"] # 0xee22 (en: 'thick under bar accent', google translation) - - "": [T: "acento de barra con círculo cerrado a la derecha"] # 0xee23 (en: 'bar accent with closed circle right', google translation) - - "": [T: "gran punto arriba"] # 0xee24 (en: 'large dot above', google translation) - - "": [T: "marca de alineación"] # 0xef00 (en: 'alignment mark', google translation) - - "": [t: ""] # 0xef01 - - "​": [t: ""] # 0x200b - - "": [t: ""] # 0xef02 - - " ": [t: ""] # 0x2009 - - "": [t: ""] # 0xef03 - - " ": [t: ""] # 0x205f - - "": [t: ""] # 0xef04 - - "": [t: ""] # 0xef05 - - " ": [t: ""] # 0x2003 - - "": [t: ""] # 0xef06 - - "": [t: ""] # 0xef07 - - "": [t: ""] # 0xef08 - - "": [t: ""] # 0xef09 - - "": [t: ""] # 0xef0a - - " ": [t: ""] # 0x200a - - "": [t: ""] # 0xef22 - - "": [t: ""] # 0xef23 - - "": [t: ""] # 0xef24 - - "": [t: ""] # 0xef29 - - "": [T: "término ausente"] # 0xef41 (en: 'missing term', google translation) - - "": [T: "flecha integral de contorno en sentido de las agujas del reloj a la izquierda"] # 0xef80 (en: 'clockwise contour integral arrow on left', google translation) - - "": [T: "integral con cuadrado"] # 0xef81 (en: 'integral with square', google translation) - - "": [T: "integral con barra cortada"] # 0xef82 (en: 'integral with slash', google translation) - - "": [T: "integral invertida"] # 0xef83 (en: 'reversed integral', google translation) - - "": [T: "doble cero sobre doble cero"] # 0xef90 (en: 'double zero over double zero', google translation) - - "": [T: "cero con barra cortada"] # 0xef91 (en: 'zero with slash', google translation) - - # fraktur chars in math alphabetic block and also MathType private use area - # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display - - "𝔄-𝔜": # 0x1d504 - 0x1d51d ('z' version is reserved) - - T: "fraktur" # (google translation) - - spell: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" - - - "-": # 0xf000 - 0xf018 - - T: "fraktur" # (google translation) - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" - - - "𝔞-𝔷": # 0x1d51e - 0x1d537 - - T: "fraktur" # (google translation) - - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" - - "-": # 0xf01a - 0xf033 - - T: "fraktur" # (google translation) - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝕬-𝖅": # 0x1D56C - 0x1D585 - - T: "fraktur bold" # (google translation) - - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf040 - 0xf059 - - T: "fraktur bold" # (google translation) - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝖆-𝖟": # 0x1d586 - 0x1d59f - - T: "fraktur bold" # (google translation) - - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" - - "-": # 0xf05a - 0xf073 - - T: "fraktur bold" # (google translation) - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - # double struck (blackboard bold) chars in math alphabetic block and also MathType private use area - # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display - - "𝔸-𝕐": # 0x1d504 - 0x1d51d ('z' version is reserved) - - test: - if: "$Verbosity!='Terse'" - then: [T: "doble tachadura"] # (en: 'double struck', google translation) - - spell: "translate('.', '𝔸𝔹𝔺𝔻𝔼𝔽𝔾𝔿𝕀𝕁𝕂𝕃𝕄𝕅𝕆𝕇𝕈𝕉𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf080 - 0xf098 - - test: - if: "$Verbosity!='Terse'" - then: [T: "doble tachadura"] # (en: 'double struck', google translation) - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝕒-𝕫": # 0x1d552 - 0x1d56b - - test: - if: "$Verbosity!='Terse'" - then: [T: "doble tachadura"] # (en: 'double struck', google translation) - - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" - - "-": # 0xf09a - 0xf0b3 - - test: - if: "$Verbosity!='Terse'" - then: [T: "doble tachadura"] # (en: 'double struck', google translation) - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 - - test: - if: "$Verbosity!='Terse'" - then: [T: "doble tachadura"] # (en: 'double struck', google translation) - - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" - - "-": # 0xf0c0 - 0xf0c9 - - test: - if: "$Verbosity!='Terse'" - then: [T: "doble tachadura"] # (en: 'double struck', google translation) - - spell: "translate('.', '', '0123456789')" - - - "": [T: "doble nabla tachada"] # 0xf0ca (en: 'double struck nabla', google translation) - - "": [T: "doble constante de Euler tachada"] # 0xf0cb (en: 'double struck euler constant', google translation) - - # script chars in math alphabetic block and also MathType private use area - - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 - - T: "guión" # (en: 'script', google translation) - - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf100 - 0xf119 - - T: "guión" # (en: 'script', google translation) - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf - - T: "guión" # (en: 'script', google translation) - - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" - - "-": # 0xf11a - 0xf133 - - T: "guión" # (en: 'script', google translation) - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - # bold script chars in math alphabetic block and also MathType private use area - - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 - - T: "guión en negrita" # (en: 'script bold', google translation) - - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf140 - 0xf159 - - T: "guión en negrita" # (en: 'script bold', google translation) - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝓪-𝔃": # 0x1d4ea - 0x1d503 - - T: "guión en negrita" # (en: 'script bold', google translation) - - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" - - "-": # 0xf15a - 0xf173 - - T: "guión en negrita" # (en: 'script bold', google translation) - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf180 - 0xf199 - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "": # 0xf19a - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "mayúscula"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [T: "ligadura ae"] # (en: 'ligature ae', google translation) - - "": # 0xf19b - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "mayúscula"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [T: "s puntiaguda"] # (en: 'sharp s', google translation) - - "": # 0xf19c - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "mayúscula"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [T: "o con trazo"] # (en: 'o with stroke', google translation) - - # MathType only has a few of the cap Greek letters in PUA - - "": # 0xf201 - 0xf209 - - test: - if: "$Verbosity!='Terse'" - then: [T: "doble tachadura"] # (en: 'double struck', google translation) - - spell: "translate('.', '', 'ΔΨΛΠΣΘΓΩΥ')" - - - "-": # 0xf220 - 0xf236 - - test: - if: "$Verbosity!='Terse'" - then: [T: "doble tachadura"] # (en: 'double struck', google translation) - - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "": [T: "doble tachadura en sigma final"] # 0xf237 (en: 'double struck final sigma', google translation) - - "": [T: "doble tachadura en rho"] # 0xf250 (en: 'double struck rho', google translation) - - "": [T: "doble tachadura en phi"] # 0xf251 (en: 'double struck phi', google translation) - - "𝐀-𝐙": # 0x1d400 - 0x1d419 - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf260 - 0xf279 - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝐚-𝐳": # 0x1d41a - 0x1d433 - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf27a - 0xf293 - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝐴-𝑍": # 0x1d434 - 0x1d44d - - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf294 - 0xf2ad - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝑎-𝑧": # 0x1d44e - 0x1d467 - - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf2ae - 0xf2c7 - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝑨-𝒁": # 0x1d468 - 0x1d481 - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf2c8 - 0xf2e1 - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝒂-𝒛": # 0x1d482 - 0x1d49b - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf2e2 - 0xf2fb - # - T: "negrita cursiva" # (en: 'bold', google translation) - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 - - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf300 - 0xf319 - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 - - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf31a - 0xf333 - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf334 - 0xf34d - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝗮-𝘇": # 0x1d5ee - 0x1d607 - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf34e - 0xf367 - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - "𝘈-𝘡": # 0x1d608 - 0x1d621 - # - T: "cursiva" - - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - "-": # 0xf368 - 0xf381 - # - T: "cursiva" - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝘢-𝘻": # 0x1d622 - 0x1d63b - # - T: "cursiva" - - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf382 - 0xf39b - # - T: "cursiva" - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝘼-𝙕": # 0x1d63c - 0x1d655 - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf39c - 0xf3b5 - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝙖-𝙯": # 0x1d656 - 0x1d66f - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf3b6 - 0xf3cf - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝙰-𝚉": # 0x1d670 - 0x1d689 - - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf3d0 - 0xf3e9 - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 - - spell: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf3ea - 0xf403 - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "": [T: "i sin punto"] # 0xf404 (google translation) - - "𝚤": [T: "ci cursiva sin punto"] # 0x1d6a4 (en: 'dotless i', google: 'dotless i') - - "𝚥": [T: "j cursiva sin punto"] # 0x1d6a5 (en: 'dotless j', google: 'dotless j') - - - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 - - T: "j cursiva sin punto" # (en: 'bold', google: 'atrevido') - - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "-": # 0xf408 - 0xf420 - - T: "j cursiva sin punto" # (en: 'bold', google: 'atrevido') - - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da - - T: "j cursiva sin punto" # (en: 'bold', google: 'atrevido') - - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf422 - 0xf43a - - T: "j cursiva sin punto" # (en: 'bold', google: 'atrevido') - - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "": [T: "nabla en negrita"] # 0xf421 (google translation) - - "𝛁": [T: "nabla en negrita"] # 0x1d6c1 (google translation) - - - "𝛛𝛜𝛝𝛞𝛟𝛠𝛡": # 0x1D6DB - 0x1D6E1 - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" - - - "": # 0xF43C - 0xF441 - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '', '∂εθκφρπ')" - - - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa - # - T: "cursiva" - - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "-": # 0xf442 - 0xf45a - # - T: "cursiva" - - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝛼-𝜔": # 0x1d6fc - 0x1d714 - # - T: "cursiva" - - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓𝜔', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf45c - 0xf474 - # - T: "cursiva" - - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "": [T: "nabla en cursiva"] # 0xf45b (en: 'italic nabla', google translation) - - "𝛻": [T: "nabla en cursiva"] # 0x1d6fb (en: 'italic nabla', google translation) - - - "𝜕𝜖𝜗𝜘𝜙𝜚𝜛": # 0x1d715 - 0x1d71b - # - T: "cursiva" - - spell: "translate('.', '𝜕𝜖𝜗𝜘𝜙𝜚𝜛', '∂εθκφρπ')" - - - "": # 0xf475 - 0xf47b - # - T: "cursiva" - - spell: "translate('.', '', '∂εθκφρπ')" - - - "𝜜-𝜴": # 0x1d71c - 0x1d734 - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "-": # 0xf47c - 0xf494 - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝜶-𝝎": # 0x1d736 - 0x1d74e - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf496 - 0xf4ae - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": # 0x1d74f - 0x1d755 - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εθκφρπ')" - - - "": # 0xf422 - 0xf43a - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '', '∂εθκφρπ')" - - - "𝜵": [T: "nabla en cursiva y negrita"] # 0x1d735 (en: 'bold italic nabla', google translation) - - "": [T: "nabla en cursiva y negrita"] # 0xf495 (en: 'bold italic nabla', google translation) - - - "𝝖-𝝮": # 0x1d756 - 0x1d76e - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - "-": # 0xf4b6 - 0xf4ce - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝝰-𝞈": # 0x1d770 - 0x1d788 - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇𝞈', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf4d0 - 0xf4e8 - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "𝞉𝞊𝞋𝞌𝞍𝞎𝞏": # 0x1d789 - 0x1d78f - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '𝞉𝞊𝞋𝞌𝞍𝞎𝞏', '∂εθκφρπ')" - - - "": # 0xf4e9 - 0xf4ef - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '', '∂εθκφρπ')" - - - "": [T: "nabla en negrita"] # 0xf4cf (google translation) - - "𝝯": [T: "nabla en negrita"] # 0x1d76f (google translation) - - - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "-": # 0xf4f0 - 0xf508 - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝞪-𝟂": # 0x1d7aa - 0x1d7c2 - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf50a - 0xf522 - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": # 0x1d7c3 - 0x1d7c9 - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '𝟃𝟄𝟅𝟆𝟇𝟈𝟉', '∂εθκφρπ')" - - - "": # 0xf523 - 0xf529 - # - T: "negrita cursiva" - - T: "negrita" # (en: 'bold', google translation) - - spell: "translate('.', '', '∂εθκφρπ')" - - - "": [T: "nabla en negrita"] # 0xf509 (google translation) - - "𝞩": [T: "nabla en negrita"] # 0x1d7a9 (google translation) - - - "": [T: "cero en negrita"] # 0xf52e (en: 'bold zero', google translation) - - "𝟎": [T: "cero en negrita"] # 0x1d7ce (en: 'bold zero', google translation) - - "": [T: "uno en negrita"] # 0xf52f (en: 'bold one', google translation) - - "𝟏": [T: "negrita"] # 0x1d7cf (en: 'bold one', google translation) - - "": [T: "dos en negrita"] # 0xf530 (en: 'bold two', google translation) - - "𝟐": [T: "dos en negrita"] # 0x1d7d0 (en: 'bold two', google translation) - - "": [T: "tres en negrita"] # 0xf531 (en: 'bold three', google translation) - - "𝟑": [T: "tres en negrita"] # 0x1d7d1 (en: 'bold three', google translation) - - "": [T: "cuatro en negrita"] # 0xf532 (en: 'bold four', google translation) - - "𝟒": [T: "bold en negrita"] # 0x1d7d2 (en: 'bold four', google translation) - - "": [T: "cinco en negrita"] # 0xf533 (en: 'bold five', google translation) - - "𝟓": [T: "cinco en negrita"] # 0x1d7d3 (en: 'bold five', google translation) - - "": [T: "seis en negrita"] # 0xf534 (en: 'bold six', google translation) - - "𝟔": [T: "seis en negrita"] # 0x1d7d4 (en: 'bold six', google translation) - - "": [T: "siete en negrita"] # 0xf535 (en: 'bold seven', google translation) - - "𝟕": [T: "siete en negrita"] # 0x1d7d5 (en: 'bold seven', google translation) - - "": [T: "ocho en negrita"] # 0xf536 (en: 'bold eight', google translation) - - "𝟖": [T: "ocho en negrita"] # 0x1d7d6 (en: 'bold eight', google translation) - - "": [T: "nueve en negrita"] # 0xf537 (en: 'bold nine', google translation) - - "𝟗": [T: "nueve en negrita"] # 0x1d7d7 (en: 'bold nine', google translation) - - "": [T: "cero"] # 0xf542 (en: 'zero', google translation) - - "𝟢": [T: "cero"] # 0x1d7e2 (en: 'zero', google translation) - - "": [T: "uno"] # 0x1d7e3 (en: 'one', google translation) - - "": [T: "dos"] # 0xf544 (en: 'two', google translation) - - "𝟤": [T: "dos"] # 0x1d7e4 (en: 'two', google translation) - - "": [T: "tres"] # 0xf545 (en: 'three', google translation) - - "𝟥": [T: "tres"] # 0x1d7e5 (en: 'three', google translation) - - "": [T: "cuatro"] # 0xf546 (en: 'four', google translation) - - "𝟦": [T: "cuatro"] # 0x1d7e6 (en: 'four', google translation) - - "": [T: "cinco"] # 0xf547 (en: 'five', google translation) - - "𝟧": [T: "cinco"] # 0x1d7e7 (en: 'five', google translation) - - "": [T: "seis"] # 0xf548 (en: 'six', google translation) - - "𝟨": [T: "seis"] # 0x1d7e8 (en: 'six', google translation) - - "": [T: "siete"] # 0xf549 (en: 'seven', google translation) - - "𝟩": [T: "siete"] # 0x1d7e9 (en: 'seven', google translation) - - "": [T: "ocho"] # 0xf54a (en: 'eight', google translation) - - "𝟪": [T: "ocho"] # 0x1d7ea (en: 'eight', google translation) - - "": [T: "nueve"] # 0xf54b (en: 'nine', google translation) - - "𝟫": [T: "nueve"] # 0x1d7eb (en: 'nine', google translation) - - "": [T: "cero en negrita"] # 0xf54c (en: 'bold zero', google translation) - - "𝟬": [T: "cero en negrita"] # 0x1d7ec (en: 'bold zero', google translation) - - "": [T: "uno en negrita"] # 0xf54d (en: 'bold one', google translation) - - "𝟭": [T: "uno en negrita"] # 0x1d7ed (en: 'bold one', google translation) - - "": [T: "dos en negrita"] # 0xf54e (en: 'bold two', google translation) - - "𝟮": [T: "dos en negrita"] # 0x1d7ee (en: 'bold two', google translation) - - "": [T: "tres en negrita"] # 0xf54f (en: 'bold three', google translation) - - "𝟯": [T: "tres en negrita"] # 0x1d7ef (en: 'bold three', google translation) - - "": [T: "cuatro en negrita"] # 0xf550 (en: 'bold four', google translation) - - "𝟰": [T: "bold en negrita"] # 0x1d7f0 (en: 'bold four', google translation) - - "": [T: "cinco en negrita"] # 0xf551 (en: 'bold five', google translation) - - "𝟱": [T: "bcinco en negrita"] # 0x1d7f1 (en: 'bold five', google translation) - - "": [T: "seis negrita"] # 0xf552 (en: 'bold six', google translation) - - "𝟲": [T: "seis negrita"] # 0x1d7f2 (en: 'bold six', google translation) - - "": [T: "siete negrita"] # 0xf553 (en: 'bold seven', google translation) - - "𝟳": [T: "siete en negrita"] # 0x1d7f3 (en: 'bold seven', google translation) - - "": [T: "ocho en negrita"] # 0xf554 (en: 'bold eight', google translation) - - "𝟴": [T: "ocho en negrita"] # 0x1d7f4 (en: 'bold eight', google translation) - - "": [T: "nueve en negrita"] # 0xf555 (en: 'bold nine', google translation) - - "𝟵": [T: "nueve en negrita"] # 0x1d7f5 (en: 'bold nine', google translation) - - "": [T: "cero"] # 0xf556 (en: 'zero', google translation) - - "𝟶": [T: "cero"] # 0x1d7f6 (en: 'zero', google translation) - - "": [T: "uno"] # 0xf557 (en: 'one', google translation) - - "𝟷": [T: "uno"] # 0x1d7f7 (en: 'one', google translation) - - "": [T: "dos"] # 0xf558 (en: 'two', google translation) - - "𝟸": [T: "dos"] # 0x1d7f8 (en: 'two', google translation) - - "": [T: "tres"] # 0xf559 (en: 'three', google translation) - - "𝟹": [T: "tres"] # 0x1d7f9 (en: 'three', google translation) - - "": [T: "cuatro"] # 0xf55a (en: 'four', google translation) - - "𝟺": [T: "cuatro"] # 0x1d7fa (en: 'four', google translation) - - "": [T: "cinco"] # 0xf55b (en: 'five', google translation) - - "𝟻": [T: "cinco"] # 0x1d7fb (en: 'five', google translation) - - "": [T: "seis"] # 0xf55c (en: 'six', google translation) - - "𝟼": [T: "seis"] # 0x1d7fc (en: 'six', google translation) - - "": [T: "siete"] # 0xf55d (en: 'seven', google translation) - - "𝟽": [T: "siete"] # 0x1d7fd (en: 'seven', google translation) - - "": [T: "ocho"] # 0xf55e (en: 'eight', google translation) - - "𝟾": [T: "ocho"] # 0x1d7fe (en: 'eight', google translation) - - "": [T: "nueve"] # 0xf55f (en: 'nine', google translation) - - "𝟿": [T: "nueve"] # 0x1d7ff (en: 'nine', google translation) - - "": [T: "carácter desconocido"] # 0xf700 (en: 'unknown character', google translation) - - "": [T: "triángulos inferior derecho e inferior izquierdo"] # 0xf726 (en: 'lower right and lower left triangles', google translation) - - "": [T: "extensor de puntos suspensivos horizontales"] # 0xf72d (en: 'horizontal ellipsis extender', google translation) - - "": [T: "extensor de puntos suspensivos de línea media horizontal"] # 0xf72e (en: 'midline horizontal ellipsis extender', google translation) - - "": [T: "extensor radical"] # 0xf8e5 (en: 'radical extender', google translation) - - "": [T: "extensor de flecha vertical"] # 0xf8e6 (en: 'vertical arrow extender', google translation) - - "": [T: "extensor de flecha horizontal"] # 0xf8e7 (en: 'horizontal arrow extender', google translation) - - "": [T: "señal registrada sans serif"] # 0xf8e8 (en: 'registered sign sans serif', google translation) - - "": [T: "copyright sign sans serif"] # 0xf8e9 (google translation) - - "": [T: "signo de marca comercial sans serif"] # 0xf8ea (en: 'trade mark sign sans serif', google translation) - - "": [T: "paréntesis superior izquierdo"] # 0xf8eb (en: 'left paren top', google translation) - - "": [T: "extensor de paréntesis izquierdo"] # 0xf8ec (en: 'left paren extender', google translation) - - "": [T: "paréntesis izquierdo inferior"] # 0xf8ed (en: 'left paren bottom', google translation) - - "": [T: "soporte izquierdo superior"] # 0xf8ee (en: 'left bracket top', google translation) - - "": [T: "extensor de soporte izquierdo"] # 0xf8ef (en: 'left bracket extender', google translation) - - "": [T: "soporte izquierdo inferior"] # 0xf8f0 (en: 'left bracket bottom', google translation) - - "": [T: "soporte izquierdo superior"] # 0xf8f1 (en: 'left brace top', google translation) - - "": [T: "soporte izquierdo medio"] # 0xf8f2 (en: 'left brace mid', google translation) - - "": [T: "soporte izquierdo inferior"] # 0xf8f3 (en: 'left brace bottom', google translation) - - "": [T: "extensor de soporte"] # 0xf8f4 (en: 'brace extender', google translation) - - "": [T: "extensor integral"] # 0xf8f5 (en: 'integral extender', google translation) - - "": [T: "paréntesis superior derecho"] # 0xf8f6 (en: 'right paren top', google translation) - - "": [T: "extensor de paréntesis derecho"] # 0xf8f7 (en: 'right paren extender', google translation) - - "": [T: "paréntesis inferior derecho"] # 0xf8f8 (en: 'right paren bottom', google translation) - - "": [T: "soporte derecho superior"] # 0xf8f9 (en: 'right bracket top', google translation) - - "": [T: "extensor de soporte derecho"] # 0xf8fa (en: 'right bracket extender', google translation) - - "": [T: "soporte derecho inferior"] # 0xf8fc (en: 'right brace top', google translation) - - "": [T: "soporte derecho medio"] # 0xf8fd (en: 'right brace mid', google translation) - - "": [T: "soporte derecho inferior"] # 0xf8fe (en: 'right brace bottom', google translation) - - "": [T: "logotipo de apple"] # 0xf8ff (en: 'apple logo', google translation) - - "ff": [T: "ff ligadas"] # 0xfb00 (en: 'ff', google: 'ff') - - "fi": [T: "fi ligadas"] # 0xfb01 (en: 'fi', google: 'f') - - "fl": [T: "fl ligadas"] # 0xfb02 (en: 'fl', google: 'florida') - - "ffi": [T: "ffl ligadas"] # 0xfb04 (en: 'ffl', google: 'ffl') - - "ſt": [T: "pie"] # 0xfb05 (en: 'ft', google translation) - - "st": [T: "calle"] # 0xfb06 (en: 'st', google translation) - - "︠": [T: "mitad de ornamentación izquierda en ligadura"] # 0xfe20 (en: 'ligature left half embellishment', google translation) - - "︡": [T: "mitad de ornamentación derecha en ligadura"] # 0xfe21 (en: 'ligature right half embellishment', google translation) - - "︢": [T: "doble tilde con media ornamentación izquierda"] # 0xfe22 (en: 'double tilde left half embellishment', google translation) - - "︣": [T: "doble tilde medio adorno"] # 0xfe23 (en: 'double tilde right half embellishment', google translation) - - "︤": [T: "macron dejó medio adorno"] # 0xfe24 (en: 'macron left half embellishment', google translation) - - "︥": [T: "macron medio adorno"] # 0xfe25 (en: 'macron right half embellishment', google translation) - - "︦": [T: "unir el adorno de macron"] # 0xfe26 (en: 'conjoining macron embellishment', google translation) - - "︵": [T: "paréntesis superior"] # 0xfe35 (en: 'over paren') - - "︶": [T: "paréntesis inferior"] # 0xfe36 (en: 'under paren') - - "︷": [T: "llave superior"] # 0xfe37 (en: 'over brace') - - "︸": [T: "llave inferior"] # 0xfe38 (en: 'under brace') - - "︿": [T: "paréntesis angular superior"] # 0xfe3f (en: 'over angle bracket') - - "﹀": [T: "paréntesis angular inferior"] # 0xfe40 (en: 'under angle bracket') - - "﹨": [T: "división entera"] # 0xfe68 (en: 'integer divide') - - "": [T: "objeto desconocido o faltante"] # 0xfffc (en: 'unknown or missing object', google translation) - - "�": [T: "caracter desconocido o faltante"] # 0xfffd (en: 'unknown or missing character', google: 'personaje desconocido o faltante') - +--- + + - "¤": [T: "moneda"] # 0xa4 (en: 'currency sign') + - "¥": [T: "yen"] # 0xa5 + - "¦": [T: "barra vertical partida"] # 0xa6 (en: 'broken bar') + - "§": [T: "sección"] # 0xa7 (en: 'section') + - "¨": [T: "diéresis"] # 0xa8 (en: 'double dot') + - "©": [T: "copyright"] # 0xa9 + - "ª": [T: "ordinal femenino"] # 0xaa (en: 'feminine ordinal indicator') + - "«": [T: "abrir comillas angulare"] # 0xab (en: 'left-pointing double angle quote mark', MathPlayer: 'abre comillas angulares', google: 'marca de cotización de doble ángulo de punta izquierda') + - "¯": # 0xaf + - test: + if: "ancestor::m:modified-variable and preceding-sibling::*[1][self::m:mi]" + then: [T: "barra"] # (google translation) + else: [T: "barra"] # (en: 'line') + - "²": [T: "al cuadrado"] # 0xb2 (en: 'two', MathPlayer: 'super 2', google: 'dos') + - "³": [T: "al cubo"] # 0xb3 (en: 'three', MathPlayer: 'super 3', google: 'tres') + - "µ": [T: "micro"] # 0xb5 + - "¹": [T: "super 1"] # 0xb9 (en: 'one', google: 'uno') + - "º": [T: "ordinal masculino"] # 0xb9 (en: 'masculine ordinal indicator') + - "ʰ": [T: "modificador pequeño h"] # 0x2b0 (en: 'modifier small h', google translation) + - "ʱ": [T: "modificador pequeño h con gancho"] # 0x2b1 (en: 'modifier small h with hook', google translation) + - "ʲ": [T: "modificador pequeño j"] # 0x2b2 (en: 'modifier small j', google translation) + - "ʳ": [T: "modificador pequeño r"] # 0x2b3 (en: 'modifier small r', google translation) + - "ʴ": [T: "modificador pequeño girado r"] # 0x2b4 (en: 'modifier small turned r', google translation) + - "ʵ": [T: "modificador pequeño girado r con gancho"] # 0x2b5 (en: 'modifier small turned r with hook', google translation) + - "ʶ": # 0x2b6 + - T: "modificador pequeño invertido" # (en: 'modifier small inverted', google translation) + - spell: "translate('R', 'R', 'R')" + + - "ʷ": [T: "modificador pequeño w"] # 0x2b7 (en: 'modifier small w', google translation) + - "ʸ": [T: "modificador pequeño y"] # 0x2b8 (en: 'modifier small y', google translation) + - "ʹ": [T: "prima"] # 0x2b9 (en: 'modifier prime', google: 'modificador prime') + - "ʺ": [T: "dos prima"] # 0x2ba (en: 'modifier double prime', google: 'modificador doble prime') + - "ʻ": [T: "modificador girado por coma"] # 0x2bb (en: 'modifier turned comma', google translation) + - "ʼ": [T: "apóstrofo modificador"] # 0x2bc (en: 'modifier apostrophe', google translation) + - "ʽ": [T: "modificador de coma invertida"] # 0x2bd (en: 'modifier reversed comma', google translation) + - "ʾ": [T: "semianillo a la derecha"] # 0x2be (en: 'modifier right half ring', google: 'modificador de medio anillo derecho') + - "ʿ": [T: "semianillo a la izquierda"] # 0x2bf (en: 'modifier left half ring', google: 'modificador de medio anillo izquierdo') + - "ˀ": [T: "modificador de parada glótica"] # 0x2c0 (en: 'modifier glottal stop', google translation) + - "ˁ": [T: "modificador invertido de parada glótica"] # 0x2c1 (en: 'modifier reversed glottal stop', google translation) + - "˂": [T: "modificador de punta de flecha izquierda"] # 0x2c2 (en: 'modifier left arrowhead', google translation) + - "˃": [T: "modificador de punta de flecha derecha"] # 0x2c3 (en: 'modifier right arrowhead', google translation) + - "˄": [T: "modificador de punta de flecha hacia arriba"] # 0x2c4 (en: 'modifier up arrowhead', google translation) + - "˅": [T: "modificador de punta de flecha hacia abajo"] # 0x2c5 (en: 'modifier down arrowhead', google translation) + - "ˆ": [T: "circunflejo"] # 0x2c6 (en: 'modifier circumflex accent', google: 'acento circunflejo modificador') + - "ˇ": [T: "carón"] # 0x2c7 (en: 'caron', google: 'caron') + - "ˈ": [T: "línea vertical modificador"] # 0x2c8 (en: 'modifier vertical line', google translation) + - "ˉ": [T: "modificador macron"] # 0x2c9 (en: 'modifier macron', google translation) + - "ˊ": [T: "modificador acento agudo"] # 0x2ca (en: 'modifier acute accent', google translation) + - "ˋ": [T: "modificador acento grave"] # 0x2cb (en: 'modifier grave accent', google translation) + - "ˌ": [T: "modificador línea baja vertical"] # 0x2cc (en: 'modifier low vertical line', google translation) + - "ˍ": [T: "modificador bajo macron"] # 0x2cd (en: 'modifier low macron', google translation) + - "ˎ": [T: "modificador acento acento grave bajo"] # 0x2ce (en: 'modifier low grave accent', google translation) + - "ˏ": [T: "modificador acento bajo agudo"] # 0x2cf (en: 'modifier low acute accent', google translation) + - "ː": [T: "modificador de colon triangular"] # 0x2d0 (en: 'modifier triangular colon', google translation) + - "ˑ": [T: "modificador de medio colon triangular"] # 0x2d1 (en: 'modifier half triangular colon', google translation) + - "˒": [T: "modificador centrado en la mitad del anillo rerecho"] # 0x2d2 (en: 'modifier centered right half ring', google translation) + - "˓": [T: "modificador centrado en la mitad del anillo izquierdo"] # 0x2d3 (en: 'modifier centered left half ring', google translation) + - "˔": [T: "modificador de tadck superior"] # 0x2d4 (en: 'modifier up tadck', google translation) + - "˕": [T: "modificador hacia abajo"] # 0x2d5 (en: 'modifier down tack', google translation) + - "˖": [T: "modificador más signo"] # 0x2d6 (en: 'modifier plus sign', google translation) + - "˗": [T: "medio anillo derecho por debajo de la ornamentación"] # 0x339 (en: 'right half ring below embellishment', google translation) + - "̺": [T: "puente invertido debajo de la ornamentación"] # 0x33a (en: 'inverted bridge below embellishment', google translation) + - "̻": [T: "cuadrado por debajo de la ornamentación"] # 0x33b (en: 'square below embellishment', google translation) + - "̼": [T: "gaviota por debajo del adorno"] # 0x33c (en: 'seagull below embellishment', google translation) + - "̽": [T: "x por encima del adorno"] # 0x33d (en: 'x above embellishment', google translation) + - "̾": [T: "ornamentación de tilde vertical"] # 0x33e (en: 'vertical tilde embellishment', google translation) + - "̿": [T: "ornamentación de doble superposición"] # 0x33f (en: 'double overline embellishment', google translation) + - "̀": [T: "ornamentación de la señal de tono grave"] # 0x340 (en: 'grave tone mark embellishment', google translation) + - "́": [T: "ornamentación de la señal de tono agudo"] # 0x341 (en: 'acute tone mark embellishment', google translation) + + - "ΪΫϏ": # 0x3aa, 0x3ab, 0x3cf + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "mayúscula"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [spell: "translate('.', 'ΪΫϏ', 'ιυϗ')"] + - T: "con dialytika" # (en: 'with dialytika', google translation) + - "ϊ": [T: "iota con dialytika"] # 0x3ca (en: 'iota with dialytika', google translation) + - "ϋ": [T: "épsilon con dialytika"] # 0x3cb (en: 'upsilon with dialytika', google translation) + - "ό": [T: "ómicron con tonos"] # 0x3cc (en: 'omicron with tonos', google translation) + - "ύ": [T: "épsilon con tonos"] # 0x3cd (en: 'upsilon with tonos', google translation) + - "ώ": [T: "omega con tonos"] # 0x3ce (en: 'omega with tonos', google translation) + - "ϐ": [T: "símbolo beta"] # 0x3d0 (en: 'beta') + - "ϑ": [T: "variante de theta"] # 0x3d1 (en: 'theta', google: 'theta') + - "ϒ": [T: "ípsilon con gancho"] # 0x3d2 (en: 'upsilon with hook', google: 'upsilon con gancho') + - "ϓ": [T: "épsilon con diéresis y gancho"] # 0x3d4 (en: 'upsilon with diaeresis and hook', google translation) + - "ϗ": [T: "símbolo kai griego"] # 0x3d7 (en: 'kai') + - "А-Я": # 0x410 - 0x42f + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "mayúscula"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [spell: "translate('.', 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ', 'абвгдежзийклмнопрстуфхцчшщъыьэюя')"] + - "а": [T: "a"] # 0x430 (google: 'а') + - "б": [T: "be"] # 0x431 (google: 'ser') + - "в": [T: "ve"] # 0x432 (google: 'veinte') + - "г": [T: "ghe"] # 0x433 + - "д": [T: "de"] # 0x434 (google: 'delaware') + - "е": [T: "ie"] # 0x435 (google: 'es decir') + - "ж": [T: "zhe"] # 0x436 + - "з": [T: "i"] # 0x438 (google: 'и') + - "й": [T: "i corta"] # 0x439 (en: 'short i', google: 'corto i') + - "к": [T: "ka"] # 0x43a + - "л": [T: "em"] # 0x43c + - "н": [T: "o"] # 0x43e (google: 'о') + - "п": [T: "pe"] # 0x43f (google: 'educación física') + - "р": [T: "er"] # 0x440 + - "с": [T: "es"] # 0x441 + - "т": [T: "te"] # 0x442 + - "у": [T: "u"] # 0x443 (google: 'у') + - "ф": [T: "ef"] # 0x444 + - "х": [T: "ha"] # 0x445 (google: 'ja') + - "ц": [T: "tse"] # 0x446 + - "ч": [T: "che"] # 0x447 + - "ш": [T: "sha"] # 0x448 + - "щ": [T: "shcha"] # 0x449 + - "ъ": [T: "signo duro"] # 0x44a (en: 'hard sign') + - "ы": [T: "yeru"] # 0x44b + - "ь": [T: "signo suave"] # 0x44c (en: 'soft sign') + - "э": [T: "e"] # 0x44d (google: 'э') + - "ю": [T: "yu"] # 0x44e + - "я": [T: "ya"] # 0x44f + - "‐": [T: "menos"] # 0x2010 (en: 'hyphen') + - "‑": [T: "guión indivisible"] # 0x2011 (en: 'hyphen', google: 'guión') + - "‒": [T: "figura Dash"] # 0x2012 (en: 'figure dash', google: 'figura dash') + - "―": [T: "barra horizontal"] # 0x2015 (en: 'horizontal bar') + - "•": # 0x2022 + - test: + if: "@data-chem-formula-op" + then: [T: "punto"] # (en: 'dot', google translation) + else: [T: "bala"] # (en: 'bullet') + + - "‰": [T: "tanto por millar"] # 0x2030 (en: 'per mille') + - "‱": [T: "tanto por diez mil"] # 0x2031 (en: 'per ten thousand') + - "′": [T: "prima"] # 0x2032 (en: 'prime') + - "‸": [T: "signo de intercalación"] # 0x2038 (en: 'to the', google: 'hacia') + - "‹": [T: "comillas izquierda"] # 0x2039 (en: 'single left pointing angle quote mark', MathPlayer: 'abre comillas', google: 'marque de cotización de ángulo de punta individual izquierdo') + - "›": [T: "comillas derecha"] # 0x203a (en: 'single right pointing angle quote mark', MathPlayer: 'cierra comillas', google: 'marque de cita de ángulo de punta de la derecha única') + - "‼": [T: "doble signo de exclamación"] # 0x203c (en: 'double factorial', google: 'doble factorial') + - "⁄": [T: "barra de fracción"] # 0x2044 (en: 'divided by') + - "⁅": [T: "corchete izquierdo"] # 0x2045 (en: 'left square bracket with quill') + - "⁆": [T: "corchete derecho"] # 0x2046 (en: 'right square bracket with quill') + - "⁗": [T: "cuatro prima"] # 0x2057 (en: 'quadruple prime', MathPlayer: 'cuarta', google: 'prime cuádruple') + - "⁠": [T: ""] # 0x2060 + - "⁣": [T: ""] # 0x2063 + - "⁤": [T: "más"] # 0x2064 (en: 'and', google: 'y') + - "⁰": [T: "a la potencia de cero"] # 0x2070 (en: 'to the zeroth power', google translation) + - "ⁱ": [T: "superíndice i"] # 0x2071 (en: 'to the eihth power', google: 'al poder eihth') + - "⁴": [T: "a la cuarta potencia"] # 0x2074 (en: 'to the fourth power', google translation) + - "⁵": [T: "a la quinta potencia"] # 0x2075 (en: 'to the fifth power', google translation) + - "⁶": [T: "a la sexta potencia"] # 0x2076 (en: 'to the sixth power', google translation) + - "⁷": [T: "a la séptima potencia"] # 0x2077 (en: 'to the seventh power', google translation) + - "⁸": [T: "a la octava potencia"] # 0x2078 (en: 'to the eighth power', google translation) + - "⁹": [T: "a la novena potencia"] # 0x2079 (en: 'to the ninth power', google translation) + - "⁺": [T: "superíndice signo más"] # 0x207a (en: 'superscript plus sign', google: 'superscript plus sign') + - "⁻": [T: "superíndice menos"] # 0x207b (en: 'superscript minus', google: 'superscript menos') + - "⁼": [T: "superíndice signo igual"] # 0x207c (en: 'superscript equals sign', google: 'superscript es igual a signo') + - "⁽": [T: "paréntesis izquierdo superíndice"] # 0x207d (en: 'superscript left parenthesis', google: 'superscript dejó paréntesis') + - "⁾": [T: "paréntesis derecho superíndice"] # 0x207e (en: 'superscript right parenthesis', google: 'superscript dirección de entrega de paréntesis') + - "ⁿ": [T: "superíndice n"] # 0x207f (en: 'to the ennth power', google: 'al poder de enth') + - "₀": [T: "bajo cero"] # 0x2080 (en: 'sub zero', google translation) + - "₁": [T: "sub uno"] # 0x2081 (en: 'sub one', google translation) + - "₂": [T: "sub dos"] # 0x2082 (en: 'sub two', google translation) + - "₃": [T: "sub tres"] # 0x2083 (en: 'sub three', google translation) + - "₄": [T: "sub cuatro"] # 0x2084 (en: 'sub four', google translation) + - "₅": [T: "sub cinco"] # 0x2085 (en: 'sub five', google translation) + - "₆": [T: "sub seis"] # 0x2086 (en: 'sub six', google translation) + - "₇": [T: "sub siete"] # 0x2087 (en: 'sub seven', google translation) + - "₈": [T: "sub ocho"] # 0x2088 (en: 'sub eight', google translation) + - "₉": [T: "sub nueve"] # 0x2089 (en: 'sub nine', google translation) + - "₊": [T: "subíndice signo más"] # 0x208a (en: 'subscript plus sign', google: 'subscript plus sign') + - "₋": [T: "subíndice menos"] # 0x208b (en: 'subscript minus sign', google: 'subíndico menos signo') + - "₌": [T: "subíndice signo igual"] # 0x208c (en: 'subscript equals sign', google: 'el subíndice es igual al signo') + - "₍": [T: "subíndice paréntesis derecho"] # 0x208e (en: 'subscript right parenthesis', google: 'subíndice de paréntesis derecha') + - "ₐ": [T: "subíndice a"] # 0x2090 (en: 'sub A', google: 'sub a') + - "ₑ": [T: "subíndice e"] # 0x2091 (en: 'sub E', google: 'sub e') + - "ₒ": [T: "subíndice o"] # 0x2092 (en: 'sub O', google: 'sub o') + - "ₓ": [T: "subíndice x"] # 0x2093 (en: 'sub X', google: 'sub x') + - "ₕ": [T: "subíndice h"] # 0x2095 (en: 'sub H', google: 'sub h') + - "ₖ": [T: "subíndice k"] # 0x2096 (en: 'sub K', google: 'sub k') + - "ₗ": [T: "subíndice l"] # 0x2097 (en: 'sub L', google: 'sub l') + - "ₘ": [T: "subíndice m"] # 0x2098 (en: 'sub M', google: 'sub m') + - "ₙ": [T: "subíndice n"] # 0x2099 (en: 'sub N', google: 'sub n') + - "ₚ": [T: "subíndice p"] # 0x209a (en: 'sub P', google: 'sub p') + - "ₛ": [T: "subíndice s"] # 0x209b (en: 'sub S', google: 'sub s') + - "ₜ": [T: "subíndice t"] # 0x209c (en: 'sub T', google: 'sub t') + - "₠": [T: "unidades de corriente europeas"] # 0x20a0 (en: 'european currenty units', google translation) + - "₡": [T: "dos puntos"] # 0x20a1 (en: 'colons', google: 'colons') + - "₢": [T: "cruzeiro"] # 0x20a2 (en: 'cruzeiro', google: 'cruzeiro') + - "₣": [T: "franco"] # 0x20a3 (en: 'franc') + - "₤": [T: "lira"] # 0x20a4 + - "₥": [T: "molinos"] # 0x20a5 (en: 'mills') + - "₦": [T: "naira"] # 0x20a6 + - "₧": [T: "peseta"] # 0x20a7 + - "₨": [T: "rupia"] # 0x20a8 (en: 'rupees', google: 'rupias') + - "₩": [T: "won"] # 0x20a9 (google: 'ganado') + - "₪": [T: "nuevo sheqel"] # 0x20aa (en: 'new sheqels', google: 'nuevo sheqels') + - "₫": [T: "dong"] # 0x20ab (google: 'polla') + - "€": [T: "euro"] # 0x20ac (en: 'euros', google: 'euros') + - "₭": [T: "kip"] # 0x20ad (google: 'dormir') + - "₮": [T: "tugrik"] # 0x20ae + - "₯": [T: "dracma"] # 0x20af (en: 'drachma') + - "₰": [T: "penique alemán"] # 0x20b0 (en: 'german pennies', google: 'centavos alemanes') + - "₱": [T: "peso"] # 0x20b1 (en: 'pesos', google: 'pesos') + - "₲": [T: "guaraníes"] # 0x20b2 (en: 'guaranis', google translation) + - "₳": [T: "australs"] # 0x20b3 (google translation) + - "₴": [T: "hryvnias"] # 0x20b4 (google translation) + - "₵": [T: "cedis"] # 0x20b5 (google translation) + - "₶": [T: "livre tournois"] # 0x20b6 (google translation) + - "₷": [T: "spesmilos"] # 0x20b7 (google translation) + - "₸": [T: "tenges"] # 0x20b8 (google translation) + - "₹": [T: "rupias indias"] # 0x20b9 (en: 'indian rupees', google translation) + - "₺": [T: "liras turcas"] # 0x20ba (en: 'turkish liras', google translation) + - "⃐": [T: "arpón izquierdo por encima de la ornamentación"] # 0x20d0 (en: 'left harpoon above embellishment', google: 'arpón de izquierda por encima del adorno') + - "⃑": [T: "arpón derecho por encima de la ornamentación"] # 0x20d1 (en: 'right harpoon above embellishment', google: 'arpón derecho por encima del adorno') + - "⃒": [T: "línea vertical larga con ornamentación superpuesta"] # 0x20d2 (en: 'long vertical line overlay embellishment', google translation) + - "⃓": [T: "línea vertical corta con ornamentación superpuesta"] # 0x20d3 (en: 'short vertical line overlay embellishment', google translation) + - "⃔": [T: "flecha en sentido contrario a las agujas del reloj por encima de la ornamentación"] # 0x20d4 (en: 'anticlockwise arrow above embellishment', google translation) + - "⃕": [T: "flecha en el sentido de las agujas del reloj por encima de la ornamentación"] # 0x20d5 (en: 'clockwise arrow above embellishment', google translation) + - "⃖": [T: "flecha izquierda por encima de la ornamentación"] # 0x20d6 (en: 'left arrow above embellishment', google: 'flecha izquierda por encima del adorno') + - "⃗": [T: "flecha derecha por encima de la ornamentación"] # 0x20d7 (en: 'right arrow above embellishment', google: 'flecha derecha por encima del adorno') + - "⃘": [T: "ornamentación superpuesta al anillo"] # 0x20d8 (en: 'ring overlay embellishment', google translation) + - "⃙": [T: "anillo en el sentido de las agujas del reloj con ornamentación superpuesta"] # 0x20d9 (en: 'clockwise ring overlay embellishment', google translation) + - "⃚": [T: "anilo en sentido contrario a las agujas del reloj con ornamentación superpuesta"] # 0x20da (en: 'anticlockwise ring overlay embellishment', google translation) + - "⃛": [T: "tres puntos"] # 0x20db (en: 'triple dot', google: 'triple punto') + - "⃜": [T: "cuatro puntos "] # 0x20dc (en: 'quadruple dot', google: 'punto cuádruple') + - "⃝": [T: "ornamentación de círculo envolvente"] # 0x20dd (en: 'enclosing circle embellishment', google translation) + - "⃞": [T: "ornamentación de cuadrado envolvente"] # 0x20de (en: 'enclosing square embellishment', google translation) + - "⃟": [T: "ornamentación de rombo envolvente"] # 0x20df (en: 'enclosing diamond embellishment', google translation) + - "⃠": [T: "ornamentación con bara inversa de círculo envolvente"] # 0x20e0 (en: 'enclosing circle backslash embellishment', google translation) + - "⃡": [T: "doble flecha por encima de la ornamentación"] # 0x20e1 (en: 'left right arrow above embellishment', google: 'flecha derecha izquierda por encima del adorno') + - "⃢": [T: "ornamentación de pantalla envolvente"] # 0x20e2 (en: 'enclosing screen embellishment', google translation) + - "⃣": [T: "ornamentación de clave envolvente"] # 0x20e3 (en: 'enclosing keycap embellishment', google translation) + - "⃤": [T: "ornamentación de triángulo envolvente apuntando hacia arriba"] # 0x20e4 (en: 'enclosing upward pointing triangle embellishment', google translation) + - "⃥": [T: "solidus invertido con ornamentación superpuesta"] # 0x20e5 (en: 'reverse solidus overlay embellishment', google translation) + - "⃦": [T: "doble vértice con ornamentación de trazo"] # 0x20e6 (en: 'double verticle stroke embellishment', google translation) + - "⃧": [T: "símbolo de anualidad con ornamentación"] # 0x20e7 (en: 'annuity symbol embellishment', google translation) + - "⃨": [T: "triple punto bajo"] # 0x20e8 (en: 'triple underdot', google translation) + - "⃩": [T: "amplio puente por encima de la ornamentación"] # 0x20e9 (en: 'wide bridge above embellishment', google translation) + - "⃪": [T: "flecha izquierda con ornamentación superpuesta"] # 0x20ea (en: 'leftwards arrow overlay embellishment', google translation) + - "⃫": [T: "largo y doble solidus con ornamentación superpuesta"] # 0x20eb (en: 'long double solidus overlay embellishment', google translation) + - "⃬": [T: "arpón hacia la derecha con ornamentación apuntando hacia abajo"] # 0x20ec (en: 'rightwards harpoon with barb downwards embellishment', google translation) + - "⃭": [T: "arpón hacia la izquierda con ornamentación apuntando hacia abajo"] # 0x20ed (en: 'leftwards harpoon with barb downwards embellishment', google translation) + - "⃮": [T: "flecha izquierda por debajo de la ornamentación"] # 0x20ee (en: 'left arrow below embellishment', google translation) + - "⃯": [T: "flecha derecha por debajo de la ornamentación"] # 0x20ef (en: 'right arrow below embellishment', google translation) + - "⃰": [T: "asterisco por encima de la ornamentación"] # 0x20f0 (en: 'asterisk above embellishment', google translation) + - "℄": [T: "símbolo de línea central"] # 0x2104 (en: 'center line symbol', google translation) + - "℅": [T: "para"] # 0x2105 (en: 'care of', google: 'cuidado de') + - "℆": [T: "cada una"] # 0x2106 (google: 'cadada una') + - "ℇ": [T: "constante de euler"] # 0x2107 (en: 'euler's constant', google: 'la constante de euler') + - "℈": [T: "escrúpulo"] # 0x2108 (en: 'scruples', google translation) + - "ℊ": [T: "g cursiva"] # 0x210a (en: 'script g', google: 'guión g') + - "ℌℑℨℭ": # 0x210c, 0x2111, 0x2128, 0x212d + - T: "g cursiva" # (en: 'fraktur', google: 'fraktur') + - spell: "translate('.', 'ℌℑℨℭ', 'HIZC')" + + - "ℍℙℾℿ": # 0x210d, 0x2119, 0x213e, 0x213f + - test: + if: "$Verbosity!='Terse'" + then: [T: "doble tachadura"] # (en: 'double struck', google translation) + - spell: "translate('.', 'ℍℙℾℿ', 'HPΓΠ')" + + - "ℏ": # 0x210f + - test: + if: "($Verbosity='Terse')" + then: [T: "h bar"] # (google translation) + else: [T: "h barra"] # (en: 'reduced planck constant') + + - "ℐℒ℘ℬℰℱℳ": # 0x2110, 0x2112, 0x2118, 0x2130, 0x2131, 0x2133 + - T: "h barra" # (en: 'script') + - spell: "translate('.', 'ℐℒ℘ℬℰℱℳ', 'ILPBEFM')" + + - "℔": [T: "L B símbolo de barra"] # 0x2114 (en: 'pounds', google: 'libras') + - "№": [T: "signo de número"] # 0x2116 (en: 'number') + - "℥": [T: "onza"] # 0x2125 (en: 'ounces') + - "Ω": [T: "ohmio"] # 0x2126 (en: 'ohms') + - "℧": [T: "iota invertida"] # 0x2129 (en: 'turned iota', google: 'convertido en iota') + - "Å": [T: "angstrom"] # 0x212b (en: 'angstroms') + - "ℯ": [T: "e cursiva"] # 0x212f (en: 'script e', google: 'guión e') + + # coalesced some chars that use cap letters + - "Ⅎ℺⅁⅂⅃⅄": # 0x2132, 0x213a, 0x2141, 0x2142, 0x2143, 0x2144 + - test: + - if: "'.' = '℺'" + then: [T: "rotado"] # (en: 'rotated', google translation) + - else_if: "'.' = 'Ⅎ'" + then: [T: "transformado"] # (en: 'turned', google translation) + - else_if: "'.' = '⅃'" + then: [T: "invertido sans-serif"] # (en: 'reversed sans-serif', google translation) + else: [T: "e cursiva"] # (en: 'turned sans-serif', google: 'convertido en sans-serif') + - spell: "translate('.', 'Ⅎ℺⅁⅂⅃⅄', 'FQGLLY')" + + - "ℴ": [T: "o cursiva"] # 0x2134 (en: 'script o', google: 'guión o') + - "ℵ": [T: "alef"] # 0x2135 (en: 'first transfinite cardinal') + - "ℶ": [T: "bet"] # 0x2136 (en: 'second transfinite cardinal') + - "ℷ": [T: "guímel"] # 0x2137 (en: 'third transfinite cardinal') + - "ℸ": [T: "dálet"] # 0x2138 (en: 'fourth transfinite cardinal') + - "ℼ": [T: "pi en negrita de pizarra"] # 0x213c (en: 'double struck pi', google: 'double golpeado pi') + - "ℽ": [T: "gamma en negrita de pizarra"] # 0x213d (en: 'double struck gamma', google: 'double golpeó a gamma') + - "⅀": [T: "suma de n-ary en negrita"] # 0x2140 (en: 'double struck n-ary summation', google: 'suma de doble apolón n-ary') + - "⅋": [T: "ampersand invertido"] # 0x214b (en: 'turned ampersand', google: 'convertido en ampersand') + - "⅌": [T: "por"] # 0x214c (en: 'per', google: 'por') + - "ⅎ": [T: "f invertida"] # 0x214e (en: 'turned F', google: 'girado f') + - "⅐": [T: "un séptimo"] # 0x2150 (en: 'one seventh', google: 'un septimo') + - "⅑": [T: "un noveno"] # 0x2151 (en: 'one ninth', google: 'un noveno') + - "⅒": [T: "un dadoécimo"] # 0x2152 (en: 'one tenth', google: 'una décima parte') + - "⅓": [T: "un tercio"] # 0x2153 (en: 'one third', SRE: 'Vulgar Fracción Un Tercero') + - "⅔": [T: "dos tercios"] # 0x2154 (en: 'two thirds', SRE: 'Fracción vulgar dos tercios') + - "⅕": [T: "un quinto"] # 0x2155 (en: 'one fifth', SRE: 'Vulgar Fraction One Fifth') + - "⅖": [T: " franción comúndos quintos"] # 0x2156 (en: 'two fifths', MathPlayer: 'dos quintos', google: 'dos quintas partes') + - "⅗": [T: " fracción común tres quintos"] # 0x2157 (en: 'three fifths', SRE: 'Fracción vulgar tres quintos') + - "⅘": [T: " fracción común cuatro quintos"] # 0x2158 (en: 'four fifths', SRE: 'Fracción vulgar cuatro quintos') + - "⅙": [T: "un sexto"] # 0x2159 (en: 'one sixth', SRE: 'Vulgar Fracción Un Sexto') + - "⅚": [T: "cinco sextos"] # 0x215a (en: 'five sixths', SRE: 'Vulgar fracción cinco sextos') + - "⅛": [T: "fracción común un octavo"] # 0x215b (en: 'one eighth', MathPlayer: 'un octavo', google: 'un ath') + - "⅜": [T: "fracción común tres octavos"] # 0x215c (en: 'three eighths', MathPlayer: 'tres octavos', google: 'tres ats') + - "⅝": [T: "fracción común cinco octavos"] # 0x215d (en: 'five eighths', MathPlayer: 'cinco octavos', google: 'cinco ats') + - "⅞": [T: "fracción común siete octavos"] # 0x215e (en: 'seven eighths', MathPlayer: 'siete octavos', google: 'siete ats') + - "⅟": [T: "Numerador de fracción uno"] # 0x215f (en: 'one over', google: 'uno sobre') + - "Ⅰ": [T: "Ⅰ"] # 0x2160 (en: 'I', google translation) + - "Ⅱ": [T: "T"] # 0x2161 (en: 'I I', google translation) + - "Ⅲ": [T: "III"] # 0x2162 (en: 'I I I', google translation) + - "Ⅳ": [T: "IV"] # 0x2163 (en: 'I V', google translation) + - "Ⅴ": [T: "V"] # 0x2164 (en: 'V', google translation) + - "Ⅵ": [T: "VI"] # 0x2165 (en: 'V I', google translation) + - "Ⅶ": [T: "VII"] # 0x2166 (en: 'V I I', google translation) + - "Ⅷ": [T: "VIII"] # 0x2167 (en: 'V I I I', google translation) + - "Ⅸ": [T: "IX"] # 0x2168 (en: 'I X', google translation) + - "Ⅹ": [T: "XI"] # 0x216a (en: 'X I', google translation) + - "Ⅻ": [T: "XII"] # 0x216b (en: 'X I I', google translation) + - "Ⅼ": [T: "Ⅼ"] # 0x216c (en: 'L', google translation) + - "Ⅽ": [T: "Ⅽ"] # 0x216d (en: 'C', google translation) + - "Ⅾ": [T: "Ⅾ"] # 0x216e (en: 'D', google translation) + - "Ⅿ": [T: "Ⅿ"] # 0x216f (en: 'M', google translation) + - "ⅰ": [T: "ⅰ"] # 0x2170 (en: 'I', google translation) + - "ⅱ": [T: "I"] # 0x2171 (en: 'I I', google translation) + - "ⅲ": [T: "III"] # 0x2172 (en: 'I I I', google translation) + - "ⅳ": [T: "IV"] # 0x2173 (en: 'I V', google translation) + - "ⅴ": [T: "ⅴ"] # 0x2174 (en: 'V', google translation) + - "ⅵ": [T: "VI"] # 0x2175 (en: 'V I', google translation) + - "ⅶ": [T: "VII"] # 0x2176 (en: 'V I I', google translation) + - "ⅷ": [T: "VIII"] # 0x2177 (en: 'V I I I', google translation) + - "ⅸ": [T: "IX"] # 0x2178 (en: 'I X', google translation) + - "ⅹ": [T: "ⅹ"] # 0x2179 (en: 'X', google translation) + - "ⅺ": [T: "XI"] # 0x217a (en: 'X I', google translation) + - "ⅻ": [T: "XII"] # 0x217b (en: 'X I I', google translation) + - "ⅼ": [T: "ⅼ"] # 0x217c (en: 'L', google translation) + - "ⅽ": [T: "ⅽ"] # 0x217d (en: 'C', google translation) + - "ⅾ": [T: "ⅾ"] # 0x217e (en: 'D', google translation) + - "ⅿ": [T: "ⅿ"] # 0x217f (en: 'M', google translation) + - "↉": [T: "fracción común cero tercios"] # 0x2189 (en: 'zero thirds', google: 'cero tercios') + - "↔": [T: "flecha hacia izquierda y derecha"] # 0x2194 (en: 'left right arrow') + - "↕": [T: "flecha hacia arriba y abajo"] # 0x2195 (en: 'up down arrow') + - "↖": [T: "flecha hacia el noroeste"] # 0x2196 (en: 'north west arrow') + - "↗": # 0x2197 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "enfoque desde abajo"] # (en: 'approaches from below', google translation) + else: [T: "flecha hacia el nordeste"] # (en: 'north east arrow') + + - "↘": # 0x2198 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "enfoque desde arriba"] # (en: 'approaches from above', google translation) + else: [T: "flecha hacia el sudeste"] # (en: 'south east arrow') + + - "↙": [T: "flecha hacia el sudoeste"] # 0x2199 (en: 'south west arrow') + - "↚": [T: "flecha con trazo hacia la izquierda"] # 0x219a (en: 'leftwards arrow with stroke') + - "↛": [T: "flecha con trazo hacia la derecha"] # 0x219b (en: 'rightwards arrow with stroke') + - "↜": [T: "flecha izquierda ondulada"] # 0x219c (en: 'leftwards wave arrow') + - "↝": [T: "flecha derecha ondulada"] # 0x219d (en: 'rightwards wave arrow') + - "↞": [T: "flecha hacia la izquierda con doble punta"] # 0x219e (en: 'leftwards two headed arrow') + - "↟": [T: "flecha hacia arriba con doble punta"] # 0x219f (en: 'upwards two headed arrow') + - "↠": [T: "flecha hacia la derecha con doble punta"] # 0x21a0 (en: 'rightwards two headed arrow') + - "↡": [T: "flecha hacia abajo con doble punta"] # 0x21a1 (en: 'downwards two headed arrow') + - "↢": [T: "flecha hacia la izquierda con cola"] # 0x21a2 (en: 'leftwards arrow with tail') + - "↣": [T: "flecha hacia la derecha con cola"] # 0x21a3 (en: 'rightwards arrow with tail') + - "↤": [T: "flecha hacia la izquierda con barra"] # 0x21a4 (en: 'leftwards arrow from bar') + - "↥": [T: "flecha hacia arriba con barra"] # 0x21a5 (en: 'upwards arrow from bar') + - "↦": [T: "flecha derecha hacia arriba con barra"] # 0x21a6 (en: 'rightwards arrow from bar') + - "↧": [T: "flecha hacia abajo con barra"] # 0x21a7 (en: 'downwards arrow from bar') + - "↨": [T: "flecha hacia arriba y hacia abajo con base"] # 0x21a8 (en: 'up down arrow with base') + - "↩": [T: "flecha hacia la izquierda con gancho"] # 0x21a9 (en: 'leftwards arrow with hook') + - "↪": [T: "fflecha hacia la derecha con gancho"] # 0x21aa (en: 'rightwards arrow with hook') + - "↫": [T: "flecha hacia la izquierda con bucle"] # 0x21ab (en: 'leftwards arrow with loop') + - "↬": [T: "flecha hacia la derecha con bucle"] # 0x21ac (en: 'rightwards arrow with loop') + - "↭": [T: "flecha ondulada hacia la izquierda y la derecha"] # 0x21ad (en: 'left right wave arrow') + - "↮": [T: "flecha hacia la izquierda y derecha con trazo"] # 0x21ae (en: 'left right arrow with stroke') + - "↯": [T: "flecha hacia abajo en zigzag"] # 0x21af (en: 'downwards zigzag arrow') + - "↰": [T: "flecha hacia arriba con punta hacia la izquierda"] # 0x21b0 (en: 'upwards arrow with tip leftwards') + - "↱": [T: "flecha hacia arriba con punta hacia la derecha"] # 0x21b1 (en: 'upwards arrow with tip rightwards') + - "↲": [T: "flecha hacia abajo con punta hacia la izquierda"] # 0x21b2 (en: 'downwards arrow with tip leftwards') + - "↳": [T: "flecha hacia abajo con punta hacia la derecha"] # 0x21b3 (en: 'downwards arrow with tip rightwards') + - "↴": [T: "flecha hacia la derecha con intersección hacia abajo"] # 0x21b4 (en: 'rightwards arrow with corner downwards') + - "↵": [T: "flecha hacia abajo con intersección hacia la izquierda"] # 0x21b5 (en: 'downwards arrow with corner leftwards') + - "↶": [T: "flecha semicircular superior en sentido contrario a las agujas del reloj"] # 0x21b6 (en: 'anticlockwise top semicircle arrow') + - "↷": [T: "flecha semicircular superior en sentido de las agujas del reloj"] # 0x21b7 (en: 'clockwise top semicircle arrow') + - "↸": [T: "flecha noroeste hacia barra larga"] # 0x21b8 (en: 'north west arrow to long bar') + - "↹": [T: "flecha izquierda hacia barra por encima de flecha derecha hacia barra"] # 0x21b9 (en: 'leftwards arrow to bar over rightwards arrow to bar') + - "↺": [T: "flecha circular abierta en sentido contrario a las agujas del reloj"] # 0x21ba (en: 'anticlockwise open circle arrow') + - "↻": [T: "flecha circular abierta en sentido de las agujas del reloj"] # 0x21bb (en: 'clockwise open circle arrow') + - "↼": [T: "flecha izquierda con arpón en la parte superior"] # 0x21bc (en: 'left harpoon up') + - "↽": [T: "flecha izquierda con arpón en la parte inferior"] # 0x21bd (en: 'left harpoon down') + - "↾": [T: "arpón derecho hacia arriba"] # 0x21be (en: 'up harpoon right') + - "↿": [T: "arpón izquierdo hacia arriba"] # 0x21bf (en: 'up harpoon left') + - "⇀": [T: "arpón derecho hacia arriba"] # 0x21c0 (en: 'right harpoon up') + - "⇁": [T: "arpón derecho hacia abajo"] # 0x21c1 (en: 'right harpoon down') + - "⇂": [T: "arpón derecho hacia abajo"] # 0x21c2 (en: 'down harpoon right') + - "⇃": [T: "arpón izquierdo hacia abajo"] # 0x21c3 (en: 'down harpoon left') + - "⇄": [T: "flecha hacia la derecha por encima de flecha hacia la izquierda"] # 0x21c4 (en: 'rightwards arrow over leftwards arrow') + - "⇅": [T: "flecha hacia arriba a la izquierda de flecha hacia abajo"] # 0x21c5 (en: 'upwards arrow leftwards of downwards arrow') + - "⇆": [T: "flecha hacia la izquierda por encima de flecha hacia la derecha"] # 0x21c6 (en: 'leftwards arrow over rightwards arrow') + - "⇇": [T: "dos flechas hacia la izquierda"] # 0x21c7 (en: 'leftwards paired arrows') + - "⇈": [T: "dos flechas hacia arriba"] # 0x21c8 (en: 'upwards paired arrows') + - "⇉": [T: "dos flechas hacia la derecha"] # 0x21c9 (en: 'rightwards paired arrows') + - "⇊": [T: "dos flechas hacia abajo"] # 0x21ca (en: 'downwards paired arrows') + - "⇋": [T: "arpón izquierdo por encima de arpón derecho"] # 0x21cb (en: 'left harpoon over right harpoon') + - "⇌": [T: "arpón derecho por encima de arpón izquierdo"] # 0x21cc (en: 'right harpoon over left harpoon') + - "⇍": [T: "flecha doble izquierda con trazo"] # 0x21cd (en: 'leftwards double arrow with stroke') + - "⇎": [T: "flecha doble izquierda y derecha con trazo"] # 0x21ce (en: 'left right double arrow with stroke') + - "⇏": [T: "flecha doble hacia la derecha con trazo"] # 0x21cf (en: 'rightwards double arrow with stroke') + - "⇐": [T: "flecha doble hacia la izquierda"] # 0x21d0 (en: 'leftwards double arrow') + - "⇑": [T: "flecha doble hacia arriba"] # 0x21d1 (en: 'upwards double arrow') + - "⇓": [T: "flecha doble hacia abajo"] # 0x21d3 (en: 'downwards double arrow') + - "⇔": [T: "flecha doble vertical"] # 0x21d5 (en: 'up down double arrow') + - "⇖": [T: "flecha doble hacia noroeste"] # 0x21d6 (en: 'north west double arrow') + - "⇗": [T: "flecha doble hacia nordeste"] # 0x21d7 (en: 'north east double arrow') + - "⇘": [T: "flecha doble hacia sudeste"] # 0x21d8 (en: 'south east double arrow') + - "⇙": [T: "flecha doble hacia sudoeste"] # 0x21d9 (en: 'south west double arrow') + - "⇚": [T: "flecha triple hacia la izquierda"] # 0x21da (en: 'leftwards triple arrow') + - "⇛": [T: "flecha triple hacia la derecha"] # 0x21db (en: 'rightwards triple arrow') + - "⇜": [T: "flecha ondulada izquierda"] # 0x21dc (en: 'leftwards squiggle arrow') + - "⇝": [T: "flecha ondulada hacia la derecha"] # 0x21dd (en: 'rightwards squiggle arrow') + - "⇞": [T: "flecha hacia arriba con doble trazo"] # 0x21de (en: 'upwards arrow with double stroke') + - "⇟": [T: "flecha hacia abajo con doble trazo"] # 0x21df (en: 'downwards arrow with double stroke') + - "⇠": [T: "flecha de puntos hacia la izquierda"] # 0x21e0 (en: 'leftwards dashed arrow') + - "⇡": [T: "flecha de puntos hacia arriba"] # 0x21e1 (en: 'upwards dashed arrow') + - "⇢": [T: "flecha de puntos hacia la derecha"] # 0x21e2 (en: 'rightwards dashed arrow') + - "⇣": [T: "flecha de puntos hacia abajo"] # 0x21e3 (en: 'downwards dashed arrow') + - "⇤": [T: "flecha hacia la izquierda con barra"] # 0x21e4 (en: 'leftwards arrow to bar') + - "⇥": [T: "flecha hacia la derecha con barra"] # 0x21e5 (en: 'rightwards arrow to bar') + - "⇦": [T: "flecha blanca hacia la izquierda"] # 0x21e6 (en: 'leftwards white arrow') + - "⇧": [T: "flecha blanca hacia arriba"] # 0x21e7 (en: 'upwards white arrow') + - "⇨": [T: "flecha blanca hacia la derecha"] # 0x21e8 (en: 'rightwards white arrow') + - "⇩": [T: "flecha blanca hacia abajo"] # 0x21e9 (en: 'downwards white arrow') + - "⇪": [T: "flecha blanca hacia arriba partiendo de barra"] # 0x21ea (en: 'upwards white arrow from bar') + - "⇫": [T: "flecha blanca hacia arriba sobre un pedestal con barra horizontal"] # 0x21eb + - "⇬": [T: "flecha blanca hacia arriba sobre pedestal con barra horizontal"] # 0x21ec (en: 'upwards white arrow on pedestal with horizontal bar', google: 'arrow blanca hacia arriba en el pedestal con barra horizontal') + - "⇭": [T: "flecha blanca hacia arriba sobre un pedestal con barra vertical"] # 0x21ed (en: 'upwards white arrow on pedestal with vertical bar', google: 'arrow blanca hacia arriba en el pedestal con barra vertical') + - "⇮": [T: "flecha doble blanca hacia arriba"] # 0x21ee (en: 'upwards white double arrow', google: 'hacia arriba flecha doble blanca') + - "⇯": [T: "flecha doble blanca hacia arriba sobre un pedestal"] # 0x21ef (en: 'upwards white double arrow on pedestal', google: 'arrow doble blanca hacia arriba en el pedestal') + - "⇰": [T: "flecha blanca hacia la derecha partiendo de un muro"] # 0x21f0 (en: 'rightwards white arrow from wall', google: 'arrow blanca hacia la derecha desde la pared') + - "⇱": [T: "flecha noroeste hacia la intersección"] # 0x21f1 (en: 'north west arrow to corner', google: 'north west arrow a la esquina') + - "⇲": [T: "flecha sudeste hacia la intersección"] # 0x21f2 (en: 'south east arrow to corner', google: 'south east arrow a la esquina') + - "⇳": [T: "flecha blanca vertical"] # 0x21f3 (en: 'up down white arrow', google: 'arrow white arrow') + - "⇴": [T: "flecha derecha con círculo pequeño"] # 0x21f4 (en: 'right arrow with small circle') + - "⇵": [T: "flecha superior hacia la derecha de flecha inferior"] # 0x21f5 (en: 'downwards arrow leftwards of upwards arrow') + - "⇶": [T: "tres flechashacia la derecha"] # 0x21f6 + - ⇷": [T: "flecha hacia la izquierda con trazo vertical"] # 0x21f7 (en: 'leftwards arrow with vertical stroke') + - "⇸": [T: "flecha hacia la derecha con trazo vertical"] # 0x21f8 (en: 'rightwards arrow with vertical stroke') + - "⇹": [T: "flecha izquierda derecha con trazo vertical"] # 0x21f9 (en: 'left right arrow with vertical stroke', google: 'flecha derecha izquierda con carrera vertical') + - "⇺": [T: "flecha hacia la izquierda con doble trazo vertical"] # 0x21fa (en: 'leftwards arrow with double vertical stroke', google: 'flecha hacia la izquierda con trazo vertical doble') + - "⇻": [T: "flecha hacia la derecha con doble trazo vertical"] # 0x21fb (en: 'rightwards arrow with double vertical stroke', google: 'flecha hacia la derecha con trazo vertical doble') + - "⇼": [T: "flecha izquierda derecha con doble trazo vertical"] # 0x21fc (en: 'left right arrow with double vertical stroke', google: 'flecha derecha izquierda con doble carrera vertical') + - "⇽": [T: "flecha hacia la izquierda con punta abierta"] # 0x21fd (en: 'leftwards open headed arrow') + - "⇾": [T: "flecha hacia la derecha con punta abierta"] # 0x21fe (en: 'rightwards open headed arrow') + - "⇿": [T: "flecha izquierda derecha con punta abierta"] # 0x21ff (en: 'left right open headed arrow') + - "∀": [T: "para todo"] # 0x2200 (en: 'for all') + - "∁": # 0x2201 + - test: + if: "$Verbosity!='Terse'" + then: [T: "el"] # (en: 'the', google translation) + - T: "complemento de" # (en: 'complement of') + - "∃": [T: "existe"] # 0x2203 (en: 'there exists') + - "∄": [T: "no existe"] # 0x2204 (en: 'there does not exist') + - "∅": [T: "conjunto vacío"] # 0x2205 (en: 'empty set') + - "∇": # 0x2207 + - test: + if: "$Verbosity!='Terse'" + then: [T: "el"] # (en: 'the', google translation) + - T: "gradiente" # (en: 'gradient of', google: 'gradiente de') + - "∋": [T: "comprende "] # 0x220b (en: 'contains the member') + - "∌": [T: "no comprende"] # 0x220c (en: 'does not contain the member') + - "∍": [T: "comprende "] # 0x220d (en: 'contains the member') + - "∎": [T: "fin de demostración"] # 0x220e (en: 'end of proof') + - "∏": [T: "producto"] # 0x220f (en: 'product') + - "∐": [T: "coproducto"] # 0x2210 (en: 'coproduct') + - "∑": [T: "suma"] # 0x2211 (en: 'sum', SRE: 'sumatorio') + - "−": [T: "menos"] # 0x2212 (en: 'minus') + - "∓": [T: "menos más"] # 0x2213 (en: 'minus or plus') + - "∔": [T: "punto más"] # 0x2214 (en: 'dot plus') + - "∕": [T: "dividido por"] # 0x2215 (en: 'divided by') + - "∖": [T: "menos"] # 0x2216 (en: 'set minus') + - "∗": [T: "asterisco"] # 0x2217 (en: 'times') + - "∙": # 0x2219 + - test: + if: "@data-chem-formula-op" + then: [T: "punto"] # (en: 'dot', google translation) + else: [T: "bala"] # (en: 'times') + + - "∛": # 0x221b + - test: + if: "$Verbosity!='Terse'" + then: [T: "raíz cúbica de"] # (en: 'cube root of') + - "∜": # 0x221c + - test: + if: "$Verbosity!='Terse'" + then: [T: "el"] # (en: 'the', google translation) + - T: "raíz cuarta de" # (en: 'fourth root of') + - "∞": [T: "infinito"] # 0x221e (en: 'infinity') + - "∟": [T: "ángulo recto"] # 0x221f (en: 'right angle') + - "∠": [T: "ángulo"] # 0x2220 (en: 'angle') + - "∡": [T: "ángulo medido"] # 0x2221 (en: 'measured angle') + - "∢": [T: "ángulo esférico"] # 0x2222 (en: 'spherical angle') + - "∧": [T: "y"] # 0x2227 (en: 'and') + - "∨": [T: "o"] # 0x2228 (en: 'or') + - "∩": [T: "intersección"] # 0x2229 (en: 'intersection') + - "∪": [T: "unión"] # 0x222a (en: 'union') + - "∫": [T: "integral"] # 0x222b + - "∬": [T: "integral doble"] # 0x222c (en: 'double integral') + - "∭": [T: "integral triple"] # 0x222d (en: 'triple integral') + - "∮": [T: "integral de contorno"] # 0x222e (en: 'contour integral') + - "∯": [T: "integral de superficie"] # 0x222f (en: 'surface integral') + - "∰": [T: "integral de volumen"] # 0x2230 (en: 'volume integral') + - "∱": [T: "integral de contorno en sentido de las agujas del reloj"] # 0x2231 (en: 'clockwise integral') + - "∲": [T: "integral de contorno en sentido de las agujas del reloj"] # 0x2232 (en: 'clockwise contour integral') + - "∳": [T: "integral de contorno en sentido contrario a las agujas del reloj"] # 0x2233 (en: 'anticlockwise contour integral') + - "∴": [T: "por lo tanto"] # 0x2234 (en: 'therefore') + - "∵": [T: "porque"] # 0x2235 (en: 'because') + - "∸": [T: "punto menos"] # 0x2238 (en: 'dot minus') + - "∹": [T: "exceso"] # 0x2239 (en: 'has excess compared to') + - "∺": # 0x223a + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "geométricamente proporcional a" # (en: 'geometrically proportional to') + - "∻": # 0x223b + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "homotético a" # (en: 'homothetic to') + - "≀": [T: "producto de guirnalda"] # 0x2240 (en: 'wreath product') + - "≁": [T: "no tilde"] # 0x2241 (en: 'not tilde') + - "≂": [T: "menos tilde"] # 0x2242 (en: 'minus tilde') + - "≃": # 0x2243 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "asintóticamente igual a" # (en: 'asymptotically equal to') + - "≄": # 0x2244 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no asintóticamente igual a" # (en: 'not asymptotically equal to') + - "≅": # 0x2245 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "aproximadamente igual a" # (en: 'approximately equal to') + - "≆": # 0x2246 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "aproximado pero no igual a" # (en: 'approximately but not actually equal to') + - "≇": # 0x2247 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "ni proximadamente ni realmente igual a" # (en: 'neither approximately nor actually equal to') + - "≈": # 0x2248 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "casi igual a" # (en: 'almost equal to', SRE: 'aproximado') + - "≉": # 0x2249 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no es casi igual a" # (en: 'not almost equal to') + - "≊": # 0x224a + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "igual o casi igual a" # (en: 'almost equal or equal to') + - "≋": [T: "triple tilde"] # 0x224b + - "≌": [T: "todo igual a"] # 0x224c (en: 'are all equal to') + - "≍": # 0x224d + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "equivalente a" # (en: 'equivalent to') + - "≎": # 0x224e + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "geométricamente equivalente a" # (en: 'geometrically equivalent to') + - "≏": # 0x224f + - test: + if: "$Verbosity!='Terse'" + then: [T: "la"] # (en: 'the', google translation) + - T: "diferencia entre" # (en: 'difference between') + - "≐": [T: "se acerca al límite"] # 0x2250 (en: 'approaches the limit') + - "≑": # 0x2251 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "geométricamente igual a" # (en: 'geometrically equal to') + - "≒": # 0x2252 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "aproximadamente igual a o imagen de" # (en: 'approximately equal to or the image of') + - "≓": # 0x2253 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es la"] # (en: 'is the', google translation) + - T: "imagen de o aproximadamente igual a" # (en: 'image of or approximately equal to') + - "≔": [T: "dos puntos igual"] # 0x2254 (en: 'colon equals') + - "≕": [T: "igual dos puntos"] # 0x2255 (en: 'equals colon') + - "≖": [T: "igual incluyendo anillo"] # 0x2256 (en: 'ring in equal to') + - "≗": # 0x2257 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "aproximadamente igual a" # (en: 'approximately equal to') + - "≘": [T: "corresponde a"] # 0x2258 (en: 'corresponds to') + - "≙": [T: "estimación"] # 0x2259 (en: 'estimates') + - "≚": # 0x225a + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "equiángulo con" # (en: 'equiangular to') + - "≛": [T: "igual con estrella"] # 0x225b (en: 'star equals') + - "≜": [T: "delta igual a"] # 0x225c (en: 'delta equals') + - "≝": [T: "igual por definición a"] # 0x225d (en: 'is defined to be') + - "≞": # 0x225e + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "medido por" # (en: 'measured by') + - "≟": [T: "igual con interrogante"] # 0x225f (en: 'has an unknown relationship with') + - "≢": # 0x2262 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no es idéntico a" # (en: 'not identical to') + - "≣": # 0x2263 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "estrictamente equivalente a" # (en: 'strictly equivalent to') + - "≨": # 0x2268 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "menor que pero no igual a" # (en: 'less than but not equal to') + - "≩": # 0x2269 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "mayor que pero no igual a" # (en: 'greater than but not equal to') + - "≪": # 0x226a + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "mucho menor que" # (en: 'much less than') + - "≫": # 0x226b + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "mucho mayor que" # (en: 'much greater than') + - "≬": # 0x226c + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "entre" # (en: 'between') + - "≭": # 0x226d + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no equivalente a" # (en: 'not equivalent to') + - "≮": # 0x226e + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no menor que" # (en: 'not less than') + - "≯": # 0x226f + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no mayor que" # (en: 'not greater than') + - "≰": # 0x2270 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no menor ni igual a" # (en: 'neither less than nor equal to') + - "≱": # 0x2271 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no mayor ni igual a" # (en: 'neither greater than nor equal to') + - "≲": # 0x2272 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "menor o equivalente a" # (en: 'less than or equivalent to') + - "≳": # 0x2273 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "mayor o equivalente a" # (en: 'greater than or equivalent to') + - "≴": # 0x2274 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no menor ni equivalente a" # (en: 'neither less than nor equivalent to') + - "≵": # 0x2275 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no mayor ni equivalente a" # (en: 'neither greater than nor equivalent to') + - "≶": # 0x2276 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "menor o mayor que" # (en: 'less than or greater than') + - "≷": # 0x2277 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "mayor o menor que" # (en: 'greater than or less than') + - "≸": # 0x2278 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no menor ni mayor que" # (en: 'neither less than nor greater than') + - "≹": # 0x2279 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no mayor ni menor que" # (en: 'neither greater than nor less than') + - "≺": [T: "precede a"] # 0x227a (en: 'precedes') + - "≻": [T: "sigue a"] # 0x227b (en: 'succeeds') + - "≼": [T: "precede o es igual a"] # 0x227c (en: 'precedes or is equal to') + - "≽": [T: "sigue o es igual a"] # 0x227d (en: 'succeeds or is equal to') + - "≾": [T: "precede o es equivalente a"] # 0x227e (en: 'precedes or is equivalent to') + - "≿": [T: "sigue o es equivalente a"] # 0x227f (en: 'succeeds or is equivalent to') + - "⊀": [T: "no precede a"] # 0x2280 (en: 'does not precede') + - "⊁": [T: "no sigue a"] # 0x2281 (en: 'does not succeed') + - "⊈": # 0x2288 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no incluido ni igual a" # (en: 'neither a subset of nor equal to') + - "⊉": # 0x2289 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no contiene ni es igual a" # (en: 'neither a superset of nor equal to') + - "⊊": [T: "incluido estrictamente en"] # 0x228a (en: 'subset of with not equal to') + - "⊋": [T: "contiene estrictamente a"] # 0x228b (en: 'superset of with not equal to') + - "⊌": [T: "multiconjunto"] # 0x228c (en: 'multiset') + - "⊍": [T: "multiplicación de multiconjuntos"] # 0x228d (en: 'multiset multiplication') + - "⊎": [T: "unión de multiconjuntos"] # 0x228e (en: 'multiset union') + - "⊏": [T: "imagen cuadrada de"] # 0x228f (en: 'square image of') + - "⊐": [T: "original cuadrado de"] # 0x2290 (en: 'square original of') + - "⊑": [T: "imagen cuadrada de o igual a"] # 0x2291 (en: 'square image of or equal to') + - "⊒": [T: "original cuadrado de o igual a"] # 0x2292 (en: 'square original of or equal to') + - "⊓": [T: "intersección cuadrada"] # 0x2293 (en: 'square cap') + - "⊔": [T: "unión cuadrada"] # 0x2294 (en: 'square cup') + - "⊕": [T: "signo más en forma de círculo"] # 0x2295 (en: 'circled plus') + - "⊖": [T: "signo menos en forma de círculo"] # 0x2296 (en: 'circled minus') + - "⊗": [T: "signo por en forma de círculo"] # 0x2297 (en: 'circled times') + - "⊘": [T: "barra en forma de círculo"] # 0x2298 (en: 'circled slash') + - "⊙": [T: "punto en forma de círculo"] # 0x2299 (en: 'circled dot operator') + - "⊚": [T: "anillo en círculo"] # 0x229a (en: 'circled ring') + - "⊛": [T: "asterisco en círculo"] # 0x229b (en: 'circled asterisk') + - "⊜": [T: "signo igual en círculo"] # 0x229c (en: 'circled equals') + - "⊝": [T: "signo menos en círculo"] # 0x229d (en: 'circled dash') + - "⊞": [T: "signo más en forma de cuadrado"] # 0x229e (en: 'squared plus') + - "⊟": [T: "menos en forma de cuadrado"] # 0x229f (en: 'squared minus') + - "⊠": [T: "signo por en forma de cuadrado"] # 0x22a0 (en: 'squared times') + - "⊡": [T: "punto en forma de cuadrado"] # 0x22a1 (en: 'squared dot operator') + - "⊢": [T: "t horizontal hacia la izquierda"] # 0x22a2 (en: 'proves') + - "⊣": [T: "t horizontal hacia la derecha"] # 0x22a3 (en: 'does not yield') + - "⊤": [T: "perpendicular"] # 0x22a4 (en: 'top') + - "⊥": # 0x22a5 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "perpendicular invertida" # (en: 'bottom') + - "⊦": [T: "afirmación"] # 0x22a6 (en: 'reduces to') + - "⊧": [T: "modela"] # 0x22a7 (en: 'models') + - "⊨": # 0x22a8 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "verdadero" # (en: 'true') + - "⊩": [T: "obliga"] # 0x22a9 (en: 'forces') + - "⊪": [T: "triple barra vertical torniquete a la derecha"] # 0x22aa (en: 'triple vertical bar right turnstile') + - "⊫": [T: "doble barra vertical con doble torniquete a la derecha"] # 0x22ab (en: 'double vertical bar double right turnstile') + - "⊬": [T: "no demuestra"] # 0x22ac (en: 'does not prove') + - "⊭": # 0x22ad + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "falso" # (en: 'not true') + - "⊮": [T: "no obliga"] # 0x22ae (en: 'does not force') + - "⊯": [T: "doble barra vertical negada con doble torniquete a la derecha"] # 0x22af (en: 'negated double vertical bar double right turnstile') + - "⊰": [T: "precede con respecto a"] # 0x22b0 (en: 'precedes under relation') + - "⊱": [T: "sigue con respecto a"] # 0x22b1 (en: 'succeeds under relation') + - "⊲": # 0x22b2 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "subgrupo normal de" # (en: 'a normal subgroup of') + - "⊳": [T: "contiene como subgrupo normal a"] # 0x22b3 (en: 'contains as a normal subgroup') + - "⊴": # 0x22b4 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "subgrupo normal o es igual a" # (en: 'a normal subgroup of or equal to') + - "⊵": [T: "contiene como subgrupo normal o es igual a"] # 0x22b5 (en: 'contains as a normal subgroup or equal to') + - "⊶": # 0x22b6 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "el original de" # (en: 'the original of') + - "⊷": # 0x22b7 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "imagen de" # (en: 'an image of') + - "⊸": [T: "multifunción"] # 0x22b8 (en: 'multimap') + - "⊹": [T: "matriz hermitiana conjugada"] # 0x22b9 (en: 'hermitian conjugate matrix') + - "⊺": [T: "intercalada"] # 0x22ba (en: 'intercalate') + - "⊻": [T: "o excluyente"] # 0x22bb (en: 'xor') + - "⊼": [T: "no y"] # 0x22bc (en: 'nand') + - "⊽": [T: "no o"] # 0x22bd (en: 'nor') + - "⊾": [T: "ángulo recto con arco"] # 0x22be (en: 'right angle with arc') + - "⊿": [T: "triángulo rectángulo"] # 0x22bf (en: 'right triangle') + - "⋀": [T: "y"] # 0x22c0 (en: 'logical and') + - "⋁": [T: "o"] # 0x22c1 (en: 'logical or') + - "⋂": [T: "intersección"] # 0x22c2 (en: 'intersection') + - "⋃": [T: "unión"] # 0x22c3 (en: 'union') + - "⋄": [T: "operador diamante"] # 0x22c4 (en: 'diamond operator') + - "⋅": # 0x22c5 + - test: + if: "@data-chem-formula-op" + then: [T: "punto"] # (en: 'dot', google translation) + else: [T: "punto"] # (en: 'times') + + - "⋆": [T: "operador estrella"] # 0x22c6 (en: 'times') + - "⋇": [T: "dividido por"] # 0x22c7 (en: 'division times') + - "⋈": [T: "moño"] # 0x22c8 (en: 'bowtie') + - "⋉": # 0x22c9 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "factor normal izquierdo producto semidirecto" # (en: 'the left normal factor semidirect product of') + - "⋊": # 0x22ca + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "factor normal derecho producto semidirecto" # (en: 'the right normal factor semidirect product of') + - "⋋": # 0x22cb + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "producto semidirecto izquierdo" # (en: 'the left semidirect product of') + - "⋌": # 0x22cc + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "producto semidirecto derecho" # (en: 'the right semidirect product of') + - "⋍": [T: "tilde invertida igual a"] # 0x22cd (en: 'reversed tilde equals') + - "⋎": [T: "o rotacional"] # 0x22ce (en: 'curly logical or') + - "⋏": [T: "y rotacional"] # 0x22cf (en: 'curly logical and') + - "⋐": # 0x22d0 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "subconjunto doble de" # (en: 'a double subset of') + - "⋑": # 0x22d1 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "superconjunto doble de" # (en: 'a double superset of') + - "⋒": # 0x22d2 + - test: + if: "$Verbosity!='Terse'" + then: [T: "la"] # (en: 'the', google translation) + - T: "doble intersección" # (en: 'double intersection of') + - "⋓": # 0x22d3 + - test: + if: "$Verbosity!='Terse'" + then: [T: "la"] # (en: 'the', google translation) + - T: "doble unión" # (en: 'double union of') + - "⋔": # 0x22d4 + - test: + if: "$Verbosity!='Terse'" + then: [T: "el"] # (en: 'the', google translation) + - T: "intersección propia de" # (en: 'proper intersection of') + - "⋕": # 0x22d5 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "paralela o igual a" # (en: 'equal to and parallel to') + - "⋖": [T: "menor que con punto"] # 0x22d6 (en: 'less than with dot') + - "⋗": [T: "mayor que con punto"] # 0x22d7 (en: 'greater than with dot') + - "⋘": # 0x22d8 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "mucho menor que" # (en: 'very much less than') + - "⋙": # 0x22d9 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "mucho mayor que" # (en: 'very much greater than') + - "⋚": # 0x22da + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "menor que igual a o mayor que" # (en: 'less than equal to or greater than') + - "⋛": # 0x22db + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "mayor que igual a o menor que" # (en: 'greater than equal to or less than') + - "⋜": # 0x22dc + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "menor o igual que" # (en: 'equal to or less than') + - "⋝": # 0x22dd + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "mayor o igual que" # (en: 'equal to or greater than') + - "⋞": # 0x22de + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "precede o es igual a" # (en: 'equal to or precedes') + - "⋟": # 0x22df + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "sigue o es igual a" # (en: 'equal to or succeeds') + - "⋠": [T: "no precede ni es igual a"] # 0x22e0 (en: 'does not precede nor is equal to') + - "⋡": [T: "no sigue ni es igual a"] # 0x22e1 (en: 'does not succeed nor is equal to') + - "⋢": [T: "no es imagen cuadrada ni igual a"] # 0x22e2 (en: 'not square image of or equal to') + - "⋣": [T: "no es original cuadrada ni igual a"] # 0x22e3 (en: 'not square original of or equal to') + - "⋤": [T: "imagen cuadrada precisa"] # 0x22e4 (en: 'square image of or not equal to') + - "⋥": [T: "cuadrada original precisa"] # 0x22e5 (en: 'square original of or not equal to') + - "⋦": # 0x22e6 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "menor que no equivalente a" # (en: 'less than but not equivalent to') + - "⋧": # 0x22e7 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "mayor que no equivalente a" # (en: 'greater than but not equivalent to') + - "⋨": [T: "precede pero no es equivalente a"] # 0x22e8 (en: 'precedes but is not equivalent to') + - "⋩": [T: "sigue pero no es equivalente a"] # 0x22e9 (en: 'succeeds but is not equivalent to') + - "⋪": # 0x22ea + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no subgrupo normal de" # (en: 'not a normal subgroup of') + - "⋫": [T: "no contiene como subgrupo normal a"] # 0x22eb (en: 'does not contain as a normal subgroup') + - "⋬": # 0x22ec + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no es subgrupo normal ni igual a" # (en: 'not a normal subgroup of nor is equal to') + - "⋭": [T: "no contiene como subgrupo normal ni es igual a"] # 0x22ed (en: 'does not contain as a normal subgroup nor is equal to') + - "⋮": [T: "puntos suspensivos verticales"] # 0x22ee (en: 'vertical ellipsis') + - "⋯": [T: "puntos suspensivos altos"] # 0x22ef (en: 'dot dot dot') + - "⋰": [T: "puntos suspensivos diagonales hacia arriba"] # 0x22f0 (en: 'upwards diagonal ellipsis') + - "⋱": [T: "puntos suspensivos diagonales hacia abajo"] # 0x22f1 (en: 'diagonal ellipsis') + - "⋲": [T: "pertenece a con trazo horizontal"] # 0x22f2 (en: 'element of with long horizontal stroke') + - "⋳": [T: "pertenece a con barra vertical al final del trazo horizontal"] # 0x22f3 (en: 'element of with vertical bar at end of horizontal stroke') + - "⋴": [T: "pertenece a con barra vertical al final del trazo horizontal"] # 0x22f4 (en: 'element of with vertical bar at end of horizontal stroke') + - "⋵": [T: "pertenece a con punto arriba"] # 0x22f5 (en: 'element of with dot above') + - "⋶": [T: "pertenece a con barra arriba"] # 0x22f6 (en: 'element of with overbar') + - "⋷": [T: "perteneciente subrayado"] # 0x22f7 (en: 'element of with overbar') + - "⋸": [T: "perteneciente subrayado"] # 0x22f8 (en: 'element of with underbar') + - "⋹": [T: "pertenece con dos trazos horizontales"] # 0x22f9 (en: 'element of with two horizontal strokes') + - "⋺": [T: "contiene o es igual a"] # 0x22fa (en: 'contains with long horizontal stroke') + - "⋻": [T: "contiene barra vertical al final de trazo horizontal"] # 0x22fb (en: 'contains with vertical bar at end of horizontal stroke') + - "⋼": [T: "contiene barra vertical al final de trazo horizontal"] # 0x22fc (en: 'contains with vertical bar at end of horizontal stroke') + - "⋽": [T: "contiene barra superior"] # 0x22fd (en: 'contains with overbar') + - "⋾": [T: "incluye barra superior"] # 0x22fe (en: 'contains with overbar') + - "⋿": [T: "z anotación pertenencia a bolsa"] # 0x22ff (en: 'z notation bag membership') + - "⌀": [T: "diámetro"] # 0x2300 (en: 'diameter') + - "⌁": [T: "flecha eléctrica"] # 0x2301 (en: 'electric arrow', google: 'flecha eléctrica') + - "⌂": [T: "casa"] # 0x2302 (en: 'house') + - "⌃": [T: "flecha arriba"] # 0x2303 (en: 'up arrowhead', google: 'arrowhead de flecha') + - "⌄": [T: "flecha con punta hacia abajo"] # 0x2304 (en: 'down arrowhead', google: 'abajo de arrowhead') + - "⌅": [T: "proyectiva"] # 0x2305 (en: 'projective') + - "⌆": [T: "perspectiva"] # 0x2306 (en: 'perspective') + - "⌇": [T: "línea ondulada"] # 0x2307 (en: 'wavy line') + - "⌈": [T: "límite superior izquierdo"] # 0x2308 (en: 'left ceiling') + - "⌉": [T: "límite superior derecho"] # 0x2309 (en: 'right ceiling') + - "⌊": [T: "límite inferior izquierdo"] # 0x230a (en: 'left floor') + - "⌋": [T: "límite inferior derecho"] # 0x230b (en: 'right floor') + - "⌌": [T: "corte inferior derecho"] # 0x230c (en: 'bottom right crop') + - "⌍": [T: "corte inferior izquierdo"] # 0x230d (en: 'bottom left crop') + - "⌎": [T: "corte superior derecho "] # 0x230e (en: 'top right crop', MathPlayer: 'corte superior derecho', google: 'cropa de arriba a la derecha') + - "⌏": [T: "corte superior izquierdo"] # 0x230f (en: 'top left crop') + - "⌐": [T: "no invertido"] # 0x2310 (en: 'reversed not sign') + - "⌑": [T: "rombo cuadrado"] # 0x2311 (en: 'square lozenge', google: 'pombra cuadrada') + - "⌒": [T: "arco"] # 0x2312 (en: 'arc') + - "⌓": [T: "segmento"] # 0x2313 (en: 'segment') + - "⌔": [T: "sector"] # 0x2314 + - "⌕": [T: "grabadora telefónica"] # 0x2315 (en: 'telephone recorder', google: 'recordadora telefónica') + - "⌖": [T: "indicador de posición"] # 0x2316 (en: 'position indicator crosshairs', google: 'posición indicador de mira') + - "⌗": [T: "viewdata square"] # 0x2317 (google translation) + - "⌘": [T: "lugar del signo de interés"] # 0x2318 (en: 'place of interest sign', google: 'señal de lugar de interés') + - "⌙": [T: "signo no invertido"] # 0x2319 (en: 'turned not sign', google translation) + - "⌚": [T: "reloj"] # 0x231a (en: 'watch', google: 'mirar') + - "⌛": [T: "reloj de arena"] # 0x231b (en: 'hourglass', google translation) + - "⌜": [T: "ángulo superior izquierdo"] # 0x231c (en: 'top left corner') + - "⌝": [T: "ángulo superior derecho"] # 0x231d (en: 'top right corner') + - "⌞": [T: "ángulo inferior izquierdo"] # 0x231e (en: 'bottom left corner') + - "⌟": [T: "ángulo inferior derecho"] # 0x231f (en: 'bottom right corner') + - "⌠": [T: "mitad superior de integral"] # 0x2320 (en: 'top half integral') + - "⌡": [T: "mitad inferior de integral"] # 0x2321 (en: 'bottom half integral') + - "⌢": [T: "ceño fruncido"] # 0x2322 (en: 'frown', google: 'fruncir el ceño') + - "⌣": [T: "sonrisa"] # 0x2323 (en: 'smile') + - "⌤": [T: "flecha arriba entre dos barras horizontales"] # 0x2324 (en: 'up arrowhead between two horizontal bars', google: 'arrowehead de flecha entre dos barras horizontales') + - "⌥": [T: "clave de opción"] # 0x2325 (en: 'option key', google translation) + - "⌦": [T: "borrar hacia la derecha"] # 0x2326 (en: 'erase to the right', google translation) + - "⌧": [T: "x en un rectángulo"] # 0x2327 (en: 'x in a rectangle box', google translation) + - "⌨": [T: "teclado"] # 0x2328 (en: 'keyboard', google translation) + - "〈": [T: "paréntesis angular izquierdo"] # 0x2329 (en: 'left pointing angle bracket') + - "〉": [T: "paréntesis angular derecho"] # 0x232a (en: 'right pointing angle bracket') + - "⌫": [T: "borrar hacia la izquierda"] # 0x232b (en: 'erase to the left', google translation) + - "⌬": [T: "anillo de benceno"] # 0x232c (en: 'benzene ring', google translation) + - "⌭": [T: "cilindro"] # 0x232d (en: 'cylindricity') + - "⌮": [T: "perfil"] # 0x232e (en: 'all around profile', google: 'alrededor de perfil') + - "⌯": [T: "simetría"] # 0x232f (en: 'symmetry', google translation) + - "⌰": [T: "desviación total"] # 0x2330 (en: 'total runout', google translation) + - "⌱": [T: "origen de dimensión"] # 0x2331 (en: 'dimension origin', google translation) + - "⌲": [T: "cónico cónico"] # 0x2332 (en: 'conical taper', google translation) + - "⌳": [T: "pendiente"] # 0x2333 (en: 'slope', google translation) + - "⌴": [T: "contrataladro"] # 0x2334 (en: 'counterbore', google translation) + - "⌵": [T: "avellanador"] # 0x2335 (en: 'countersink', google translation) + - "⍰": [T: "interrogación en caja"] # 0x2370 (en: 'unknown box', google: 'caja desconocida') + - "⎕": [T: "caja"] # 0x2395 (en: 'box', google translation) + - "⏞": [T: "corchete rotacional superior"] # 0x23DE (en: 'top brace') + - "⏟": [T: "corchete rotacional inferior"] # 0x23DF (en: 'bottom brace') + - "①-⑨": # 0x2460 - 0x2469 + - T: "corchete rotacional inferior" # (en: 'circled') + - spell: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" + - "⑩": [T: "diez en un círculo"] # 0x2469 (en: 'circled ten', google translation) + - "⑪": [T: "once en un círculo"] # 0x246a (en: 'circled eleven', google translation) + - "⑫": [T: "doce en un círculo"] # 0x246b (en: 'circled twelve', google translation) + - "⑬": [T: "trece en un círculo"] # 0x246c (en: 'circled thirteen', google translation) + - "⑭": [T: "catorce en un círculo"] # 0x246d (en: 'circled fourteen', google translation) + - "⑮": [T: "quince en un círculo"] # 0x246e (en: 'circled fifteen', google translation) + - "⑯": [T: "dieciséis en un círculo"] # 0x246f (en: 'circled sixteen', google translation) + - "⑰": [T: "diecisiete en un círculo"] # 0x2470 (en: 'circled seventeen', google translation) + - "⑱": [T: "dieciocho en un círculo"] # 0x2471 (en: 'circled eighteen', google translation) + - "⑱": [T: "diecinueve en un círculo"] # 0x2471 (en: 'circled nineteen', google translation) + - "⑳": [T: "veinte en un círculo"] # 0x2473 (en: 'circled twenty', google translation) + - "⑴-⑼": # 0x2474 - 0x247d + - T: "entre paréntesis" # (en: 'parenthesized', google translation) + - spell: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" + - "⑽": [T: "diez entre paréntesis"] # 0x247d (en: 'parenthesized ten', google translation) + - "⑾": [T: "once entre paréntesis"] # 0x247e (en: 'parenthesized eleven', google translation) + - "⑿": [T: "doce entre paréntesis"] # 0x247f (en: 'parenthesized twelve', google translation) + - "⒀": [T: "trece entre paréntesis"] # 0x2480 (en: 'parenthesized thirteen', google translation) + - "⒁": [T: "catorce entre paréntesis"] # 0x2481 (en: 'parenthesized fourteen', google translation) + - "⒂": [T: "quince entre paréntesis"] # 0x2482 (en: 'parenthesized fifteen', google translation) + - "⒃": [T: "dieciséis entre paréntesis"] # 0x2483 (en: 'parenthesized sixteen', google translation) + - "⒄": [T: "diecisiete entre paréntesis"] # 0x2484 (en: 'parenthesized seventeen', google translation) + - "⒅": [T: "dieciocho entre paréntesis"] # 0x2485 (en: 'parenthesized eighteen', google translation) + - "⒆": [T: "diecinueve entre paréntesis"] # 0x2486 (en: 'parenthesized nineteen', google translation) + - "⒇": [T: "veinte entre paréntesis"] # 0x2487 (en: 'parenthesized twenty', google translation) + - "⒈-⒐": # 0x2488 - 0x2491 + - spell: "translate('.', '⒈⒉⒊⒋⒌⒍⒎⒏⒐', '123456789')" + - T: "con periodo" # (en: 'with period', google translation) + - "⒑": [T: "diez con signo de periodo"] # 0x2491 (en: 'ten with period', google translation) + - "⒒": [T: "once con signo de periodo"] # 0x2492 (en: 'eleven with period', google translation) + - "⒓": [T: "doce con signo de periodo"] # 0x2493 (en: 'twelve with period', google translation) + - "⒔": [T: "trece con signo de periodo"] # 0x2494 (en: 'thirteen with period', google translation) + - "⒕": [T: "catorce con signo de periodo"] # 0x2495 (en: 'fourteen with period', google translation) + - "⒖": [T: "quince con signo de periodo"] # 0x2496 (en: 'fifteen with period', google translation) + - "⒗": [T: "dieciséis con signo de periodo"] # 0x2497 (en: 'sixteen with period', google translation) + - "⒘": [T: "diecisiete con signo de periodo"] # 0x2498 (en: 'seventeen with period', google translation) + - "⒙": [T: "dieciocho con signo de periodo"] # 0x2499 (en: 'eighteen with period', google translation) + - "⒚": [T: "diecinueve con signo de periodo"] # 0x249a (en: 'nineteen with period', google translation) + - "⒛": [T: "veinte con signo de periodo"] # 0x249b (en: 'twenty with period', google translation) + - "⒜-⒵": # 0x249c - 0x24b5 + - T: "entre paréntesis" # (en: 'parenthesized', google translation) + - spell: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" + + - "Ⓐ-Ⓩ": + - T: "dentro de uncírculo" # (en: 'circled', google translation) + - spell: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "🅐-🅩": # 0x1f150 - 0x1f169 + - T: "dentro de un círculo negro" # (en: 'black circled', google translation) + - spell: "translate('.', '🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 + - T: "dentro de un círculo" # (en: 'circled', google translation) + - spell: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" + - "⓪": [T: "cero en un círculo"] # 0x24ea (en: 'circled zero', google translation) + - "⓫": [T: "once en un círculo negro"] # 0x24eb (google translation) + - "⓬": [T: "doce en un círculo negro"] # 0x24ec (en: 'black circled twelve', google translation) + - "⓭": [T: "trece en un círculo negro"] # 0x24ed (en: 'black circled thirteen', google translation) + - "⓮": [T: "catorce en un círculo negro"] # 0x24ee (en: 'black circled fourteen', google translation) + - "⓯": [T: "quince en un círculo negro"] # 0x24ef (en: 'black circled fifteen', google translation) + - "⓰": [T: "dieciséis en un círculo negro"] # 0x24f0 (en: 'black circled sixteen', google translation) + - "⓱": [T: "diecisiete en un círculo negro"] # 0x24f1 (en: 'black circled seventeen', google translation) + - "⓲": [T: "dieciocho en un círculo negro"] # 0x24f2 (en: 'black circled eighteen', google translation) + - "⓳": [T: "diecinueve en un círculo negro"] # 0x24f3 (en: 'black circled nineteen', google translation) + - "⓴": [T: "veinte en un círculo negro"] # 0x24f4 (en: 'black circled twenty', google translation) + - "⓵-⓽": # 0x24f5 - 0x24fe + - T: "doble círculo" # (en: 'double circled', google translation) + - spell: "translate('.', '⓵⓶⓷⓸⓹⓺⓻⓼⓽', '123456789')" + - "⓾": [T: "diez en un doble círculo"] # 0x24fe (en: 'double circled ten', google translation) + - "⓿": [T: "cero en círculo negro"] # 0x24ff (en: 'black circled zero', google translation) + - "■": [T: "cuadrado negro"] # 0x25a0 (en: 'black square') + - "□": [T: "cuadrado blanco"] # 0x25a1 (en: 'white square') + - "▢": [T: "cuadrado blanco con esquinas redondeadas"] # 0x25a2 (en: 'white square with rounded corners') + - "▣": [T: "cuadrado blanco que contiene cuadrado pequeño negro"] # 0x25a3 (en: 'white square containing small black square', google: 'cuadrado blanco que contiene un pequeño cuadrado negro') + - "▤": [T: "cuadrado con relleno horizontal"] # 0x25a4 (en: 'square with horizontal fill') + - "▥": [T: "cuadrado con relleno vertical"] # 0x25a5 (en: 'square with vertical fill') + - "▦": [T: "cuadrado con relleno octogonal de rayas"] # 0x25a6 (en: 'square with orthogonal crosshatch fill', google: 'cuadrado con relleno ortogonal de muñeca') + - "▧": [T: "cuadrado con la esquina superior izquierda hacia la parte derecha inferior del relleno"] # 0x25a7 (en: 'square with upper left to lower right fill', google: 'cuadrado con la parte superior izquierda a la parte inferior del relleno derecho') + - "▨": [T: "cuadrado con la parte superior derecha hacia la parte inferior izquierda del relleno"] # 0x25a8 (en: 'square with upper right to lower left fill', google: 'cuadrado con la parte superior derecha a la parte inferior izquierda del relleno') + - "▩": [T: "cuadrado con relleno diagonal rayado"] # 0x25a9 (en: 'square with diagonal crosshatch fill', google: 'cuadrado con relleno de shatch diagonal') + - "▪": [T: "cuadrado pequeño negro"] # 0x25aa (en: 'black small square') + - "▫": [T: "cuadrado pequeño blanco"] # 0x25ab (en: 'white small square') + - "▬": [T: "rectángulo negro"] # 0x25ac (en: 'black rectangle') + - "▭": [T: "rectángulo blanco"] # 0x25ad (en: 'white rectangle') + - "▮": [T: "rectángulo relleno vertical"] # 0x25ae (en: 'black vertical rectangle') + - "▯": [T: "rectángulo vertical blanco"] # 0x25af (en: 'white vertical rectangle') + - "▰": [T: "paralelogramo negro"] # 0x25b0 (en: 'black parallelogram', google: 'paralelograma negro') + - "▱": [T: "paralelogramo blanco"] # 0x25b1 (en: 'white parallelogram') + - "▲": [T: "triángulo negro apuntando hacia arriba"] # 0x25b2 (en: 'black up pointing triangle') + - "△": [T: "triángulo blanco apuntando hacia arriba"] # 0x25b3 (en: 'white up pointing triangle') + - "▴": [T: "triángulo negro pequeño apuntando hacia arriba"] # 0x25b4 (en: 'black up pointing small triangle') + - "▵": [T: "triángulo blanco pequeño apuntando hacia arriba"] # 0x25b5 (en: 'white up pointing small triangle') + - "▶": [T: "triángulo negro apuntando hacia la derecha"] # 0x25b6 (en: 'black right pointing triangle') + - "▷": [T: "triángulo blanco apuntando hacia la derecha"] # 0x25b7 (en: 'white right pointing triangle') + - "▸": [T: "triángulonegro pequeño apuntando hacia la derecha"] # 0x25b8 (en: 'black right pointing small triangle') + - "▹": [T: "triángulo blanco pequeño apuntando hacia la derecha"] # 0x25b9 (en: 'white right pointing small triangle') + - "►": [T: "indicador negro apuntando a la derecha"] # 0x25ba (en: 'black right pointing pointer', google: 'puntero de punta derecha negra') + - "▻": [T: "indicador blanco apuntando hacia la derecha"] # 0x25bb (en: 'white right pointing pointer', google: 'puntero de punta derecha blanca') + - "▼": [T: "triángulo negro apuntando hacia abajo"] # 0x25bc (en: 'black down pointing triangle') + - "▽": [T: "triángulo blanco apuntando hacia abajo"] # 0x25bd (en: 'white down pointing triangle') + - "▾": [T: "pequeño triángulo negro apuntando hacia abajo"] # 0x25be (en: 'black down pointing small triangle') + - "▿": [T: "triángulo pequeño blanco apuntando hacia abajo"] # 0x25bf (en: 'white down pointing small triangle') + - "◀": [T: "triángulo negro apuntando hacia la izquierda"] # 0x25c0 (en: 'black left pointing triangle') + - "◁": [T: "triángulo blanco apuntando hacia la izquierda"] # 0x25c1 (en: 'white left pointing triangle') + - "◂": [T: "pequeño triángulo negro apuntando hacia la izquierda izquierda"] # 0x25c2 (en: 'black left pointing small triangle') + - "◃": [T: "pequeño triángulo blanco apuntando hacia la izquierda"] # 0x25c3 (en: 'white left pointing small triangle') + - "◄": [T: "puntero negro apuntando hacia la izquierda"] # 0x25c4 (en: 'black left pointing pointer') + - "◅": [T: "puntero blanco apuntando hacia la izquierda"] # 0x25c5 (en: 'white left pointing pointer') + - "◆": [T: "rombo negro"] # 0x25c6 (en: 'black diamond') + - "◇": [T: "rombo blanco"] # 0x25c7 (en: 'white diamond') + - "◈": [T: "rombo blanco contiene rombo pequeño negro"] # 0x25c8 (en: 'white diamond containing black small diamond') + - "◉": [T: "ojo de pez"] # 0x25c9 (en: 'fisheye') + - "◊": [T: "rombo"] # 0x25ca (en: 'lozenge') + - "○": [T: "círculo blanco"] # 0x25cb (en: 'white circle') + - "◌": [T: "círculo punteado"] # 0x25cc (en: 'dotted circle') + - "◍": [T: "círculo con relleno vertical"] # 0x25cd (en: 'circle with vertical fill') + - "◎": [T: "diana"] # 0x25ce (en: 'bullseye') + - "●": [T: "círculo negro"] # 0x25cf (en: 'black circle') + - "◐": [T: "círculo con mitad izquierda negra"] # 0x25d0 (en: 'circle with left half black') + - "◑": [T: "círculo con mitad derecha negra"] # 0x25d1 (en: 'circle with right half black') + - "◒": [T: "círculo con mitad inferior negra"] # 0x25d2 (en: 'circle with lower half black') + - "◓": [T: "círculo con mitad superior negra"] # 0x25d3 + - "◔": [T: "círculo con cuadrante superior derecho relleno"] # 0x25d4 (en: 'circle with upper right quadrant black') + - "◕": [T: "círculo con cuadrante superior izquierdo negro"] # 0x25d5 (en: 'circle with all but upper left quadrant black') + - "◖": [T: "semicírculo izquierdo negro"] # 0x25d6 (en: 'left half black circle') + - "◗": [T: "semicírculo derecho negro"] # 0x25d7 (en: 'right half black circle') + - "◘": [T: "viñeta inversa"] # 0x25d8 (en: 'inverse bullet') + - "◙": [T: "círculo blanco inverso"] # 0x25d9 (en: 'inverse white circle') + - "◚": [T: "semicírculo superior blanco inverso"] # 0x25da (en: 'upper half inverse white circle') + - "◛": [T: "semicírculo inferior blanco inverso"] # 0x25db (en: 'lower half inverse white circle') + - "◜": [T: "cuadrante superior izquierdo arco circular"] # 0x25dc (en: 'upper left quadrant circular arc') + - "◝": [T: "cuadrante superior derecho arco circular"] # 0x25dd (en: 'upper right quadrant circular arc') + - "◞": [T: "cuadrante inferior derecho arco circular"] # 0x25de (en: 'lower right quadrant circular arc') + - "◟": [T: "cuadrante inferior izquierdo arco circular"] # 0x25df (en: 'lower left quadrant circular arc') + - "◠": [T: "semicírculo superior"] # 0x25e0 (en: 'upper half circle') + - "◡": [T: "semicírculo inferior"] # 0x25e1 (en: 'lower half circle') + - "◢": [T: "triángulo inferior derecha relleno"] # 0x25e2 (en: 'black lower right triangle') + - "◣": [T: "triángulo negro inferior izquierdo"] # 0x25e3 (en: 'black lower left triangle') + - "◤": [T: "triángulo negro superior izquierdo"] # 0x25e4 (en: 'black upper left triangle') + - "◥": [T: "triángulo negro superior derecho"] # 0x25e5 (en: 'black upper right triangle') + - "◦": [T: "composición"] # 0x25e6 (en: 'composition') + - "◧": [T: "cuadrado con mitad izquierda negra"] # 0x25e7 (en: 'square with left half black') + - "◨": [T: "cuadrado con mitad derecha negra"] # 0x25e8 (en: 'square with right half black') + - "◩": [T: "cuadrado con mitad superior izquierda negra"] # 0x25e9 (en: 'square with upper left half black') + - "◪": [T: "cuadrado con mitad inferior derecha negra"] # 0x25ea (en: 'square with lower right half black') + - "◫": [T: "cuadrado blanco con bisectriz"] # 0x25eb (en: 'white square with bisecting line') + - "◬": [T: "triángulo blanco apuntando hacia arriba con punto"] # 0x25ec (en: 'white up pointing triangle with dot') + - "◭": [T: "triángulo apuntando hacia arriba con mitad izquierda negra"] # 0x25ed (en: 'up pointing triangle with left half black') + - "◮": [T: "triángulo apuntando hacia arriba con mitad derecha negra"] # 0x25ee (en: 'up pointing triangle with right half black') + - "◯": [T: "círculo grande"] # 0x25ef (en: 'large circle') + - "◰": [T: "cuadrado blanco con cuadrante superior izquierdo"] # 0x25f0 (en: 'white square with upper left quadrant') + - "◱": [T: "cuadrado blanco con cuadrante inferior izquierdo"] # 0x25f1 (en: 'white square with lower left quadrant') + - "◲": [T: "cuadrado blanco con cuadrante inferior derecho"] # 0x25f2 (en: 'white square with lower right quadrant') + - "◳": [T: "cuadrado blanco con cuadrante superior derecho"] # 0x25f3 (en: 'white square with upper right quadrant') + - "◴": [T: "círculo blanco con cuadrante superior izquierdo"] # 0x25f4 (en: 'white circle with upper left quadrant') + - "◵": [T: "círculo blanco con cuadrante inferior izquierdo"] # 0x25f5 (en: 'white circle with lower left quadrant') + - "◶": [T: "círculo blanco con cuadrante inferior derecho"] # 0x25f6 (en: 'white circle with lower right quadrant') + - "◷": [T: "círculo blanco con cuadrante superior derecho"] # 0x25f7 (en: 'white circle with upper right quadrant', google: 'círculo blanco con cuadrante superior derecha') + - "◸": [T: "triángulo superior izquierdo"] # 0x25f8 (en: 'upper left triangle') + - "◹": [T: "triángulo superior derecho"] # 0x25f9 (en: 'upper right triangle') + - "◺": [T: "triángulo inferior izquierda"] # 0x25fa (en: 'lower left triangle') + - "◻": [T: "cuadrado blanco mediano"] # 0x25fb (en: 'white medium square') + - "◼": [T: "cuadrado negro mediano"] # 0x25fc (en: 'black medium square') + - "◽": [T: "cuadrado pequeño medianamente vacío"] # 0x25fd (en: 'white medium small square') + - "◾": [T: "cuadrado pequeño medianamente lleno"] # 0x25fe (en: 'black medium small square') + - "◿": [T: "triángulo inferior derecho"] # 0x25ff (en: 'lower right triangle') + - "♠": [T: "picas"] # 0x2660 (google: 'traje de pala negro') + - "♡": [T: "corazones"] # 0x2661 (google: 'traje de corazón blanco') + - "♢": [T: "diamantes"] # 0x2662 (google: 'traje de diamante blanco') + - "♣": [T: "trébol"] # 0x2663 (google: 'traje de club negro') + - "♤": [T: "picas"] # 0x2664 (google: 'traje de pala blanca') + - "♥": [T: "corazones"] # 0x2665 (google: 'traje de corazón negro') + - "♦": [T: "diamantes"] # 0x2666 (google: 'traje de diamante negro') + - "♧": [T: "trébol"] # 0x2667 (google: 'traje de club blanco') + - "❨": [T: "ornamento en paréntesis mediano izquierdo"] # 0x2768 (en: 'medium left parentheses ornament', google: 'medio de la paréntesis de la izquierda adorno') + - "❩": [T: "ornamento en paréntesis mediano derecho"] # 0x2769 (en: 'medium right parentheses ornament', google: 'medio derecho a la derecha del adorno') + - "❪": [T: "ornamento en paréntesis izquierdo medio aplanado"] # 0x276a (en: 'medium flattened left parentheses ornament', google: 'medio aplanado a la izquierda paréntesis de adornos') + - "❫": [T: "ornamento en paréntesis derecho medio aplanado"] # 0x276b (en: 'medium flattened right parentheses ornament', google: 'medio aplanado a la derecha paréntesis de adornos') + - "❬": [T: "ornamento en soporte de ángulo medio apuntando hacia la izquierda"] # 0x276c (en: 'medium left-pointing angle bracket ornament', google: 'ornamento de soporte de ángulo de punta izquierda mediana') + - "❭": [T: "ornamento en soporte de ángulo medio apuntando hacia la derecha"] # 0x276d (en: 'medium right-pointing angle bracket ornament', google: 'ornamento de soporte de ángulo de punta derecha mediana') + - "❮": [T: "ornamento en comillas en el ángulo que apunta hacia la izquierda"] # 0x276e (en: 'heavy left-pointing angle quotation mark ornament', google: 'ornamento de cita de ángulo de punta izquierda pesada') + - "❯": [T: "ornamento en comillas en el ángulo recto que apunta hacia la derecha"] # 0x276f (en: 'heavy right-pointing angle quotation mark ornament', google: 'ornamento de cita de cita de ángulo derecho pesado') + - "❰": [T: "ornamento en soporte del ángulo que apunta a la izquierda"] # 0x2770 (en: 'heavy left-pointing angle bracket ornament', google: 'adorno de soporte de ángulo izquierdo pesado') + - "❱": [T: "ornamento en soporte del ángulo que apunta hacia la derecha"] # 0x2771 (en: 'heavy right-pointing angle bracket ornament', google: 'ornamento de soporte de ángulo de punta derecha pesada') + - "❲": [T: "ornamento en soporte de concha de tortuga a la izquierda"] # 0x2772 (en: 'light left tortoise shell bracket ornament', google: 'ornamento de soporte de concha de tortuga de luz') + - "❳": [T: "ornamento en corchete derecho de concha de tortuga hacia la derecha"] # 0x2773 (en: 'light right tortoise shell bracket ornament', google: 'ornamento de soporte de carcasa de tortuga ligera') + - "❴": [T: "ornamento en soporte izquierdo mediano"] # 0x2774 (en: 'medium left brace ornament', google: 'ornamento de brace izquierdo mediano') + - "❵": [T: "ornamento en soporte derechomediano"] # 0x2775 (en: 'medium right brace ornament', google: 'ornamento de aparato ortopédico medio derecho') + - "❶": [T: "círculo negro rodeando uno"] # 0x2776 (en: 'black circled one', google translation) + - "❷": [T: "c´riculo negro rodeando dos"] # 0x2777 (en: 'black circled two', google translation) + - "❸": [T: "círculo negro rodeando tres"] # 0x2778 (en: 'black circled three', google translation) + - "❹": [T: "círculo negro rodeando cuatro"] # 0x2779 (en: 'black circled four', google translation) + - "❺": [T: "círculo negro rodeando cinco"] # 0x277a (en: 'black circled five', google translation) + - "❻": [T: "círculo negro rodeando seis"] # 0x277b (en: 'black circled six', google translation) + - "❼": [T: "círculo negro rodeando siete"] # 0x277c (en: 'black circled seven', google translation) + - "❽": [T: "círculo negro rodeando ocho"] # 0x277d (en: 'black circled eight', google translation) + - "❾": [T: "círculo negro rodeando nueve"] # 0x277e (en: 'black circled nine', google translation) + - "❿": [T: "círculo negro rodeando diez"] # 0x277f (en: 'black circled ten', google translation) + - "➀": [T: "círculo rodeando sans serif uno"] # 0x2780 (en: 'circled sans serif one', google translation) + - "➁": [T: "círculo rodeando sans serif dos"] # 0x2781 (en: 'circled sans serif two', google translation) + - "➂": [T: "círculo rodeando sans serif tres"] # 0x2782 (en: 'circled sans serif three', google translation) + - "➃": [T: "círculo rodeando sans serif cuatro"] # 0x2783 (en: 'circled sans serif four', google translation) + - "➄": [T: "círculo rodeando sans serif cinco"] # 0x2784 (en: 'circled sans serif five', google translation) + - "➅": [T: "círculo rodeando sans serif seis"] # 0x2785 (en: 'circled sans serif six', google translation) + - "➆": [T: "círculo rodeando sans serif siete"] # 0x2786 (en: 'circled sans serif seven', google translation) + - "➇": [T: "círculo rodeando sans serif ocho"] # 0x2787 (en: 'circled sans serif eight', google translation) + - "➈": [T: "círculo rodeando sans serif nueve"] # 0x2788 (en: 'circled sans serif nine', google translation) + - "➉": [T: "círculo rodeando sans serif diez"] # 0x2789 (en: 'circled sans serif ten', google translation) + - "➊": [T: "círculo negro rodeando sans serif uno"] # 0x278a (google translation) + - "➋": [T: "círculo negro rodeando sans serif dos"] # 0x278b (en: 'black circled sans serif two', google translation) + - "➌": [T: "círculo negro rodeando sans serif tres"] # 0x278c (en: 'black circled sans serif three', google translation) + - "➍": [T: "círculo negro rodeando sans serif cuatro"] # 0x278d (google translation) + - "➎": [T: "círculo negro rodeando sans serif cinco"] # 0x278e (google translation) + - "➏": [T: "círculo negro rodeando sans serif seis"] # 0x278f (google translation) + - "➐": [T: "círculo negro rodeando sans serif siete"] # 0x2790 (google translation) + - "➑": [T: "círculo negro rodeando sans serif ocho"] # 0x2791 (en: 'black circled sans serif eight', google translation) + - "➒": [T: "círculo negro rodeando sans serif nueve"] # 0x2792 (google translation) + - "➓": [T: "círculo negro rodeando sans serif diez"] # 0x2793 (google translation) + - "➔": [T: "flecha hacia la derecha con cabeza ancha"] # 0x2794 (en: 'heavy wide-headed rightwards arrow', google: 'a la cabeza ancha de cabeza ancha') + - "➕": [T: "signo más"] # 0x2795 (en: 'heavy plus sign', google: 'señal de plus plus') + - "➖": [T: "signo menos"] # 0x2796 (en: 'heavy minus sign', google: 'fuerte señal menos') + - "➗": [T: "signo de dividir"] # 0x2797 (en: 'heavy division sign', google: 'señal de división pesada') + - "➘": [T: "flecha gruesa hacia el sudeste"] # 0x2798 (en: 'heavy south east arrow', google: 'heavy south east arrow') + - "➙": [T: "flecha gruesa hacia la derecha"] # 0x2799 (en: 'heavy rightwards arrow', google: 'flecha pesada hacia la derecha') + - "➚": [T: "flecha gruesa hacia el nordeste"] # 0x279a (en: 'heavy north east arrow', google: 'heavy north east arrow') + - "➛": [T: "flecha hacia la derecha con punto centrado"] # 0x279b (en: 'drafting point rightwards arrow', google: 'punto de redacción arrow hacia la derecha') + - "➜": [T: "flecha hacia la derecha con punta gruesa y redonda"] # 0x279c (en: 'heavy round-tipped rightwards arrow', google: 'arrow de la derecha pesada con punta redonda') + - "➝": [T: "flecha hacia la derecha con cabeza triangular"] # 0x279d (en: 'triangle-headed rightwards arrow', google: 'arrow de cabeza de triángulo') + - "➞": [T: "flecha hacia la derecha con cabeza gruesa triangular"] # 0x279e (en: 'heavy triangle-headed rightwards arrow', google: 'arrow de cabeza de triángulo pesado hacia el triángulo') + - "➟": [T: "flecha discontinua hacia la derecha de cabeza triangular"] # 0x279f (en: 'dashed triangle-headed rightwards arrow', google: 'arrow de cabeza de triángulo discontinua') + - "➠": [T: "flecha gruesa derecha discontinua con cabeza triangular"] # 0x27a0 (en: 'heavy dashed triangle-headed rightwards arrow', google: 'arrow de cabeza de triángulo pesado con cabeza de triángulo') + - "➡": [T: "flecha negra hacia la derecha"] # 0x27a1 (en: 'black rightwards arrow', google: 'negra flecha derecha hacia la derecha') + - "➢": [T: "flecha hacia la derecha tres d en parte superior"] # 0x27a2 (en: 'three d top lighted rightwards arrow', google: 'tres d top iluminados con flecha hacia la derecha') + - "➣": [T: "flecha hacia la derecha tres d en parte inferior en tres dimensiones"] # 0x27a3 (en: 'three d bottom lighted rightwards arrow', google: 'tres d de fondo iluminado hacia la derecha') + - "➤": [T: "punta de flecha negra hacia la derecha"] # 0x27a4 (en: 'black rightwards arrowhead', google: 'black rightwards arrowhead') + - "➥": [T: "flecha gruesa y negra curvada hacia la derecha y hacia abajo"] # 0x27a5 (en: 'heavy black curved downwards and rightwards arrow', google: 'negro pesado curvado hacia abajo y flecha derecha') + - "➦": [T: "flecha gruesa y negra curvada hacia la derecha y hacia arriba"] # 0x27a6 (en: 'heavy black curved upwards and rightwards arrow', google: 'negro pesado curvado hacia arriba y flecha hacia la derecha') + - "➧": [T: "flecha negra corta hacia la derecha"] # 0x27a7 (en: 'squat black rightwards arrow', google: 'corta la flecha negra a la derecha') + - "➨": [T: "flecha negra hacia la derecha con punta cóncava"] # 0x27a8 (en: 'heavy concave-pointed black rightwards arrow', google: 'flecha negra cóncava pesada pesada hacia la derecha') + - "➩": [T: "flecha hacia la derecha sombreada en la parte derecha"] # 0x27a9 (en: 'right-shaded white rightwards arrow', google: 'flecha blanca a la derecha de sombreado derecho') + - "➪": [T: "flecha blanca hacia la derecha sombreada en la parte izquierda"] # 0x27aa (en: 'left-shaded white rightwards arrow', google: 'flecha blanca a la derecha de sombreado izquierdo') + - "➫": [T: "flecha blanca hacia la derecha con sonbra inclinada hacia la parte posterior"] # 0x27ab (en: 'bck-tilted shadowed white rightwards arrow', google: 'flecha blanca a la derecha en la espalda') + - "➬": [T: "flecha blanca hacia la derecha con sombra inclinada hacia la parte anterior"] # 0x27ac (en: 'front-tilted shadowed white rightwards arrow', google: 'flecha blanca a la derecha sombreada en la sombra frontal') + - "➭": [T: "flecha gruesa inferior hacia la derecha sombreada en la parte derecha"] # 0x27ad (en: 'heavy lower right-shadowed white rightwards arrow', google: 'flecha blanca hacia la derecha inferior derecha pesada') + - "➮": [T: "flecha gruesa superior hacia la derecha sombreada en la parte derecha"] # 0x27ae (en: 'heavy upper right-shadowed white rightwards arrow', google: 'flecha blanca hacia la derecha de la parte superior derecha pesada') + - "➯": [T: "flecha escopleada inferior hacia la derecha sombreada en la parte derecha"] # 0x27af (en: 'notched lower right-shadowed white rightwards arrow', google: 'muesca con muescas de la flecha blanca a la derecha de la derecha inferior') + - "➱": [T: "flecha escopleada superior hacia la derecha sombreada en la parte derecha"] # 0x27b1 (en: 'notched upper right-shadowed white rightwards arrow', google: 'arrow blanca de sombra superior derecha con muescas de la parte superior') + - "➲": [T: "flecha blanca hacia la derecha rodeada por un círculo grueso"] # 0x27b2 (en: 'circled heavy white rightwards arrow', google: 'flecha de color blanco pesado con rodajas') + - "➳": [T: "flecha hacia la derecha con pluma blanca"] # 0x27b3 (en: 'white-feathered rightwards arrow', google: 'flecha derecha de plumas blancas') + - "➴": [T: "flecha sudeste con pluma negra"] # 0x27b4 (en: 'black-feathered south east arrow', google: 'flecha del sureste de plumas negras') + - "➵": [T: "flecha hacia la derecha con pluma negra"] # 0x27b5 (en: 'black-feathered rightwards arrow', google: 'flecha derecha de plumas negras') + - "➶": [T: "flecha nordeste con pluma negra"] # 0x27b6 (en: 'black-feathered north east arrow', google: 'flecha del noreste de plumas negras') + - "➷": [T: "flecha sudeste con pluma negra y gruesa"] # 0x27b7 (en: 'heavy black-feathered south east arrow', google: 'pesada flecha del sureste de plumas negras') + - "➸": [T: "flecha hacia la derecha con pluma gruesa y negra"] # 0x27b8 (en: 'heavy black-feathered rightwards arrow', google: 'flecha pesada de plumas negras hacia la derecha') + - "➹": [T: "flecha nordeste con pluma negra y gruesa"] # 0x27b9 (en: 'heavy black-feathered north east arrow', google: 'pesada flecha del noreste de plumas negras') + - "➺": [T: "flecha hacia la derecha con punta en forma de lágrima"] # 0x27ba (en: 'teradrop-barbed rightwards arrow', google: 'teradrop-barbed rightwards arrow') + - "➻": [T: "flecha hacia la derecha con punta en forma de lágrima"] # 0x27bb (en: 'heavy teardrop-shanked rightwards arrow', google: 'arrow a la derecha de la lágrima pesada hacia la lágrima') + - "➼": [T: "flecha hacia la derecha con cola de cuña"] # 0x27bc (en: 'wedge-tailed rightwards arrow', google: 'arrow de cola de cola de cuña') + - "➽": [T: "flecha hacia la derecha con cola de cuña gruesa"] # 0x27bd (en: 'heavy wedge-tailed rightwards arrow', google: 'flecha de cola de cuña pesada') + - "➾": [T: "flecha abierta delineada hacia fuera"] # 0x27be (en: 'open-outlined rightwards arrow', google: 'abra por la flecha de la derecha abierta') + - "⟀": [T: "ángulo tridimensional"] # 0x27c0 (en: 'three dimensional angle') + - "⟁": [T: "triángulo blanco conteniendo triángulo pequeño y blanco"] # 0x27c1 (en: 'white triangle containing small white triangle') + - "⟂": # 0x27c2 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "perpendicular a" # (en: 'perpendicular to') + - "⟃": # 0x27c3 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "un subconjunto de" # (en: 'an open subset of') + - "⟄": # 0x27c4 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "un subconjunto de" # (en: 'an open superset of') + - "⟅": [T: "símbolo delimitador con forma de s inversa"] # 0x27c5 (en: 'left s-shaped bag delimiter') + - "⟆": [T: "símbolo delimitador con forma de s"] # 0x27c6 (en: 'right s-shaped bag delimiter') + - "⟇": [T: "o con punto en el interior"] # 0x27c7 (en: 'or with dot inside') + - "⟈": [T: "solidus inverso precediendo subconjunto"] # 0x27c8 (en: 'reverse solidus preceding subset') + - "⟉": [T: "superconjunto precediendo solidus"] # 0x27c9 (en: 'superset preceding solidus') + - "⟊": [T: "barra vertical con trazo horizontal"] # 0x27ca (en: 'vertical bar with horizontal stroke') + - "⟋": [T: "diagonal ascendiente"] # 0x27cb (en: 'mathematical rising diagonal', google: 'diagonal matemática en ascenso') + - "⟌": [T: "división larga"] # 0x27cc (en: 'long division') + - "⟍": [T: "diagonal descendente"] # 0x27cd (en: 'mathematical falling diagonal', google: 'diagonal de caída matemática') + - "⟎": [T: "cuadrado Lógico Y"] # 0x27ce (en: 'squared logical and', google: 'cuadrado lógico y') + - "⟏": [T: "cuadrado Lógico O"] # 0x27cf (en: 'squared logical or', google: 'cuadrado lógico o') + - "⟐": [T: "diamante blanco con punto centrado"] # 0x27d0 (en: 'white diamond with centered dot') + - "⟑": [T: "y con punto interior"] # 0x27d1 (en: 'and with dot') + - "⟒": [T: "elemento de apertura hacia arriba"] # 0x27d2 (en: 'element of opening upwards') + - "⟓": [T: "esquina inferior derecha con punto"] # 0x27d3 (en: 'lower right corner with dot') + - "⟔": [T: "esquina superior izquierda con punto"] # 0x27d4 (en: 'upper left corner with dot') + - "⟕": [T: "unión exterior izquierda"] # 0x27d5 (en: 'left outer join') + - "⟖": [T: "unión exterior derecha"] # 0x27d6 (en: 'right outer join') + - "⟗": [T: "unión exterior llena de"] # 0x27d7 (en: 'full outer join') + - "⟘": [T: "perpendicular inversa"] # 0x27d8 (en: 'large up tack') + - "⟙": [T: "perpendicular"] # 0x27d9 (en: 'large down tack') + - "⟚": [T: "izquierdo y derecho doble torniquete"] # 0x27da (en: 'left and right double turnstile') + - "⟛": [T: "doble T horizontal"] # 0x27db (en: 'left and right tack') + - "⟜": [T: "multifunción por la izquierda"] # 0x27dc (en: 'left multimap') + - "⟝": [T: "t horizontal derecha"] # 0x27dd (en: 'long right tack', MathPlayer: 'T horizontal derecha larga', google: 'tachuela a la derecha larga') + - "⟞": [T: "t horizontal izquierda"] # 0x27de (en: 'long left tack', MathPlayer: 'T horizontal izquierda larga', google: 'táctica izquierda larga') + - "⟟": [T: "perpendicular inversa con círculo arriba"] # 0x27df (en: 'up tack with circle above') + - "⟠": [T: "rombo dividido por regla horizontal"] # 0x27e0 (en: 'lozenge divided by horizontal rule') + - "⟡": [T: "rombo blanco cóncavo"] # 0x27e1 (en: 'white concave sided diamond') + - "⟢": [T: "rombo blanco cóncavo con marca hacia la izquierda"] # 0x27e2 (en: 'white concave sided diamond with leftwards tick') + - "⟣": [T: "rombo cóncavo con marca hacia la derecha"] # 0x27e3 (en: 'white concave sided diamond with rightwards tick') + - "⟤": [T: "cuadrado blanco con marca hacia la izquierda"] # 0x27e4 (en: 'white square with leftwards tick') + - "⟥": [T: "cuadrado blanco con marca hacia la derecha"] # 0x27e5 (en: 'white square with rightwards tick') + - "⟦": [T: "abrir corchete"] # 0x27e6 (en: 'left white square bracket') + - "⟧": [T: "cerrar corchete"] # 0x27e7 (en: 'right white square bracket') + - "⟨": [T: "soporte angular izquierdo"] # 0x27e8 (en: 'left angle bracket') + - "⟩": [T: "soporte angular derecho"] # 0x27e9 (en: 'right angle bracket') + - "⟪": [T: "doble corchetehacia la izquierda"] # 0x27ea (en: 'left double angle bracket') + - "⟫": [T: "doble corchete hacia la derecha"] # 0x27eb (en: 'right double angle bracket') + - "⟬": [T: "corchete blanco hacia la izquierda con concha de tortuga"] # 0x27ec (en: 'left white tortoise shell bracket') + - "⟭": [T: "corchete blanco hacia la derecha con concha de tortuga"] # 0x27ed (en: 'right white tortoise shell bracket', MathPlayer: 'corchete de tortuga vacío derecho', google: 'soporte de carcasa de tortuga blanca derecha') + - "⟮": [T: "paréntesis plano izquierdo"] # 0x27ee (en: 'left flattened parenthesis') + - "⟯": [T: "paréntesis plano derecho"] # 0x27ef (en: 'right flattened parenthesis') + - "⟰": [T: "flecha cuádruple hacia arriba"] # 0x27f0 (en: 'upwards quadruple arrow') + - "⟱": [T: "flecha cuádruple hacia abajo"] # 0x27f1 (en: 'downwards quadruple arrow') + - "⟲": [T: "flecha circular vacía en sentido contrario a las agujas del reloj"] # 0x27f2 (en: 'anticlockwise gapped circle arrow') + - "⟳": [T: "flecha circular vacía en sentido a las agujas del reloj"] # 0x27f3 (en: 'clockwise gapped circle arrow') + - "⟴": [T: "flecha hacia la derecha con signo más rodeado por un círculo"] # 0x27f4 (en: 'right arrow with circled plus') + - "⟵": [T: "flecha larga hacia la izquierda"] # 0x27f5 (en: 'long leftwards arrow') + - "⟶": [T: "flecha larga hacia la derecha"] # 0x27f6 (en: 'long rightwards arrow') + - "⟷": [T: "flecha larga hacia izquierda y derecha"] # 0x27f7 (en: 'long left right arrow') + - "⟸": [T: "doble flecha larga hacia la izquierda"] # 0x27f8 (en: 'long leftwards double arrow') + - "⟹": [T: "doble flecha larga hacia la derecha"] # 0x27f9 (en: 'long rightwards double arrow') + - "⟺": [T: "doble flecha larga hacia izquierda y derecha"] # 0x27fa (en: 'long left right double arrow') + - "⟻": [T: "flecha larga hacia la izquierda partiendo de una barra"] # 0x27fb (en: 'long leftwards arrow from bar') + - "⟼": [T: "flecha larga hacia la derecha partiendo de una barra"] # 0x27fc (en: 'long rightwards arrow from bar') + - "⟽": [T: "doble flecha larga hacia la izquierda partiendo de una barra"] # 0x27fd (en: 'long leftwards double arrow from bar') + - "⟾": [T: "doble flecha larga hacia la derecha partiendo de una barra"] # 0x27fe (en: 'long rightwards double arrow from bar') + - "⟿": [T: "flecha ondulada hacia la derecha"] # 0x27ff (en: 'long rightwards squiggle arrow') + - "⤀": [T: "flecha de dos cabezas hacia la derecha con trazo vertical"] # 0x2900 (en: 'rightwards two headed arrow with vertical stroke', google: 'derecho de dos flechas con trazo vertical') + - "⤁": [T: "flecha de dos cabezas hacia la derecha con doble trazo vertical"] # 0x2901 (en: 'rightwards two headed arrow with double vertical stroke', google: 'derecho de dos flechas con cabeza de carrera vertical doble') + - "⤂": [T: "doble flecha hacia la izquierda con trazo vertical"] # 0x2902 (en: 'leftwards double arrow with vertical stroke', google: 'flecha doble hacia la izquierda con carrera vertical') + - "⤃": [T: "doble flecha hacia la derecha con trazo vertical"] # 0x2903 (en: 'rightwards double arrow with vertical stroke', google: 'arrow doble hacia la derecha con trazo vertical') + - "⤄": [T: "doble flecha hacia izquierda y derecha con trazo vertical"] # 0x2904 (en: 'left right double arrow with vertical stroke', google: 'flecha doble derecha izquierda con carrera vertical') + - "⤅": [T: "flecha de dos cabezas hacia la derecha partiendo de una barra"] # 0x2905 + - "⤆": [T: "doble flecha hacia la izquierda partiendo de una barra"] # 0x2906 (en: 'leftwards double arrow from bar', google: 'flecha doble a la izquierda desde el bar') + - "⤇": [T: "flecha doble hacia la derecha partiendo de una barra"] # 0x2907 (en: 'rightwards double arrow from bar', google: 'arrow doble hacia la derecha desde el bar') + - "⤈": [T: "flecha hacia abajo con trazo horizontal"] # 0x2908 (en: 'downwards arrow with horizontal stroke') + - "⤉": [T: "flecha hacia arriba con trazo horizontal"] # 0x2909 (en: 'upwards arrow with horizontal stroke', google: 'arrow hacia arriba con trazo horizontal') + - "⤊": [T: "triple flecha hacia arriba"] # 0x290a (en: 'upwards triple arrow', google: 'arriba de arriba arriba') + - "⤋": [T: "triple flecha hacia abajo"] # 0x290b (en: 'downwards triple arrow', google: 'aleja hacia abajo') + - "⤌": [T: "flecha doble discontinua hacia la izquierda"] # 0x290c + - "⤍": [T: "doble flecha discontinua hacia la derecha"] # 0x290d + - "⤎": [T: "triple flecha discontinua hacia la izquierda"] # 0x290e + - "⤏": [T: "triple flecha discontinua hacia la derecha"] # 0x290f + - "⤐": [T: "triple flecha discontinua con dos cabezas hacia la derecha"] # 0x2910 + - "⤑": [T: "flecha hacia la derecha con trazo punteado"] # 0x2911 + - "⤒": [T: "flecha hacia arriba partiendo de una barra"] # 0x2912 + - "⤓": [T: "flecha hacia abajo partiendo de una barra"] # 0x2913 + - "⤔": [T: "flecha hacia la derecha con cola y trazo vertical"] # 0x2914 (en: 'rightwards arrow with tail and vertical stroke', google: 'flecha hacia la derecha con cola y trazo vertical') + - "⤕": [T: "flecha hacia la derecha con cola y doble trazo vertical"] # 0x2915 (en: 'rightwards arrow with tail and double vertical stroke', google: 'flecha hacia la derecha con cola y trazo vertical doble') + - "⤖": [T: "flecha hacia la derecha con cola y dos cabezas"] # 0x2916 + - "⤗": [T: "flecha de dos cabezas hacia la derecha con cola con trazo vertical"] # 0x2917 (en: 'rightwards two headed arrow with tail with vertical stroke', google: 'derecho de dos flecha con la cola con trazo vertical') + - "⤘": [T: "flecha de dos cabezas hacia la derecha con cola con doble trazo vertical"] # 0x2918 (en: 'rightwards two headed arrow with tail with double vertical stroke', google: 'derecho de dos flecha con la cola con trazo vertical doble') + - "⤙": [T: "cola de doble flecha hacia la izquierda"] # 0x2919 (en: 'leftwards arrow tail') + - "⤚": [T: "cola de flecha hacia la derecha"] # 0x291a (en: 'rightwards arrow tail', google: 'tail de flecha hacia la derecha') + - "⤛": [T: "doble flecha hacia la izquierda con cola"] # 0x291b (en: 'leftwards double arrow tail') + - "⤜": [T: "cola de doble flecha hacia la derecha"] # 0x291c (en: 'rightwards double arrow tail') + - "⤝": [T: "flecha izquierda hacia rombo lleno"] # 0x291d (en: 'leftwards arrow to filled diamond') + - "⤞": [T: "flecha derecha hacia rombo lleno"] # 0x291e (en: 'rightwards arrow to filled diamond') + - "⤟": [T: "flecha izquierda desde barra hacia rombo lleno"] # 0x291f (en: 'leftwards arrow from bar to filled diamond') + - "⤠": [T: "flecha derecha desde barra hacia rombo lleno"] # 0x2920 (en: 'rightwards arrow from bar to filled diamond') + - "⤡": [T: "flecha del noroeste y del sudeste"] # 0x2921 (en: 'north west and south east arrow', google: 'noroeste y arrow south east') + - "⤢": [T: "flecha nordeste y sudoeste"] # 0x2922 (en: 'north east and south west arrow', google: 'north east y south west arrow') + - "⤣": [T: "flecha hacia el noroeste con garfio"] # 0x2923 (en: 'north west arrow with hook') + - "⤤": [T: "flecha hacia el nordeste con garfio"] # 0x2924 (en: 'north east arrow with hook') + - "⤥": [T: "flecha hacia el sudeste con garfio"] # 0x2925 (en: 'south east arrow with hook') + - "⤦": [T: "flecha hacia el suroeste con garfio"] # 0x2926 (en: 'south west arrow with hook') + - "⤧": [T: "flechas hacia el noroeste y hacia el nordeste"] # 0x2927 (en: 'north west arrow and north east arrow') + - "⤨": [T: "flechas hacia el nordeste y hacia el sudeste"] # 0x2928 (en: 'north east arrow and south east arrow') + - "⤩": [T: "flechas hacia el sudeste y hacia el sudoeste"] # 0x2929 (en: 'south east arrow and south west arrow') + - "⤪": [T: "flechas hacia el sudoeste y hacia el noroeste"] # 0x292a (en: 'south west arrow and north west arrow') + - "⤫": [T: "cruce de diagonal ascendente con diagonal descendente"] # 0x292b (en: 'rising diagonal crossing falling diagonal', google: 'cruce diagonal en ascenso caída diagonal') + - "⤬": [T: "cruce de diagonal descendente con diagonal ascendente"] # 0x292c (en: 'falling diagonal crossing rising diagonal', google: 'cambio de cruce diagonal diagonal') + - "⤭": [T: "flecha Sureste Cruzando Flecha Noreste"] # 0x292d (en: 'south east arrow crossing north east arrow', google: 'south east arrow crossing north east arrow') + - "⤮": [T: "flecha nordeste atravesando flecha sudeste"] # 0x292e (en: 'north east arrow crossing south east arrow', google: 'north east arrow crossing south east arrow') + - "⤯": [T: "diagonal descendente atravesando flecha nordeste"] # 0x292f (en: 'falling diagonal crossing north east arrow', google: 'caída diagonal atravesando la flecha del noreste') + - "⤰": [T: "diagonal ascendente atravesando flecha sudeste"] # 0x2930 (en: 'rising diagonal crossing south east arrow', google: 'cruce diagonal ascendente crossing south east arrow') + - "⤱": [T: "flecha nordeste atravesando flecha noroeste"] # 0x2931 (en: 'north east arrow crossing north west arrow', google: 'north east arrow crossing north west arrow') + - "⤲": [T: "flecha noroeste atravesando flecha nordeste"] # 0x2932 (en: 'north west arrow crossing north east arrow', google: 'north west arrow crossing north east arrow') + - "⤳": [T: "flecha ondulada apuntando hacia la derecha"] # 0x2933 (en: 'wave arrow pointing directly right') + - "⤴": [T: "flecha hacia la derecha curvada hacia arriba"] # 0x2934 (en: 'arrow pointing rightwards then curving upwards', google: 'arrow apuntando hacia la derecha y luego curvando hacia arriba') + - "⤵": [T: "flecha hacia la derecha curvada hacia abajo"] # 0x2935 (en: 'arrow pointing rightwards then curving downwards') + - "⤶": [T: "flecha hacia abajo curvada hacia la izquierda"] # 0x2936 (en: 'arrow pointing downwards then curving leftwards') + - "⤷": [T: "flecha hacia abajo curvada hacia la derecha"] # 0x2937 (en: 'arrow pointing downwards then curving rightwards') + - "⤸": [T: "flecha semicircular hacia la derecha en sentido de las agujas del reloj"] # 0x2938 (en: 'right side arc clockwise arrow') + - "⤹": [T: "flecha semicircular hacia la izquierda en sentido contrario a las agujas del reloj"] # 0x2939 (en: 'left side arc anticlockwise arrow') + - "⤺": [T: "arco superior en flecha en sentido contrario a las agujas del reloj"] # 0x293a (en: 'top arc anticlockwise arrow', google: 'arro de arco superior en sentido antihorario') + - "⤻": [T: "arco inferior en flecha hen sentido contrario a las agujas del reloj"] # 0x293b (en: 'bottom arc anticlockwise arrow', google: 'arco inferior de la flecha en sentido antihorario') + - "⤼": [T: "flecha en sentido a las agujas del reloj, con arco superior y signo menos"] # 0x293c (en: 'top arc clockwise arrow with minus') + - "⤽": [T: "flecha en sentido contrario a las agujas del reloj, con arco superior y signo más"] # 0x293d (en: 'top arc anticlockwise arrow with plus') + - "⤾": [T: "flecha semicircular inferior en sentido a las agujas del reloj"] # 0x293e (en: 'lower right semicircular clockwise arrow', google: 'flecha semicircular inferior derecha en el sentido de las agujas del reloj') + - "⤿": [T: "flecha semicircular inferior en sentido contrario a las agujas del reloj"] # 0x293f (en: 'lower left semicircular anticlockwise arrow', google: 'flecha semicircular inferior izquierda en sentido antihorario') + - "⥀": [T: "círculo cerrado en sentido contrario a las agujas del reloj"] # 0x2940 (en: 'anticlockwise closed circle arrow', google: 'flecha de círculo cerrado en sentido antihorario') + - "⥁": [T: "círculo cerrado en sentido de las agujas del reloj"] # 0x2941 (en: 'clockwise closed circle arrow', google: 'flecha del círculo cerrado en el sentido de las agujas del reloj') + - "⥂": [T: "flecha hacia la derecha sobre flecha corta hacia la izquierda"] # 0x2942 (en: 'rightwards arrow above short leftwards arrow') + - "⥃": [T: "flecha hacia la izquierda sobre flecha corta hacia la derecha"] # 0x2943 (en: 'leftwards arrow above short rightwards arrow', google: 'flecha hacia la izquierda sobre la flecha corta derecha hacia la derecha') + - "⥄": [T: "flecha corta hacia la derecha sobre flecha hacia la izquierda"] # 0x2944 (en: 'short rightwards arrow above leftwards arrow', google: 'flecha corta hacia la derecha sobre la flecha hacia la izquierda') + - "⥅": [T: "flecha hacia la derecha con signo más inferior"] # 0x2945 (en: 'rightwards arrow with plus below') + - "⥆": [T: "flecha hacia la izquierda con signo más inferior"] # 0x2946 (en: 'leftwards arrow with plus below', google: 'flecha hacia la izquierda con más a continuación') + - "⥇": [T: "flecha hacia la derecha a través de X"] # 0x2947 (en: 'rightwards arrow through x', google: 'flecha hacia la derecha a través de x') + - "⥈": [T: "flecha hacia la izquierda a través de círculo"] # 0x2948 (en: 'left right arrow through circle') + - "⥉": [T: "flecha con dos cabezas haciarriba partiendo de un círculo"] # 0x2949 (en: 'upwards two headed arrow from circle') + - "⥊": [T: "arpón con punta izquierda hacia arriba y punta derecha hacia abajo"] # 0x294a (en: 'left barb up right barb down harpoon', MathPlayer: 'left barb up right barb down harpoon', google: 'barb de la izquierda hacia arriba barb barb por harpoon') + - "⥋": [T: "arpón con punta izquierda hacia abajo y punta derecha hacia arriba"] # 0x294b (en: 'left barb down right barb up harpoon', MathPlayer: 'left barb down right barb up harpoon', google: 'barb de la izquierda hacia abajo barb en la barbilla hacia arriba') + - "⥌": [T: "arpón conpunta derecha hacia arriba y punta izquierda hacia abajo"] # 0x294c (google: 'barb a la derecha por barb harpoon izquierda') + - "⥍": [T: "arpón con punta izquierda hacia arriba y punta derecha hacia abajo"] # 0x294d (en: 'up barb left down barb right harpoon', google: 'barb a la barb izquierda por barb right harpoon') + - "⥎": [T: "arpón con puntas derecha e izquierda hacia arriba"] # 0x294e (en: 'left barb up right barb up harpoon', MathPlayer: 'arpón superior derecha-izquierda', google: 'barb izquierda arriba barb arriba de barca') + - "⥏": [T: "arpón con puntas superior e inferior hacia la derecha"] # 0x294f (en: 'up barb right down barb right harpoon') + - "⥐": [T: "arpón con puntas derecha e izquierda hacia abajo"] # 0x2950 (en: 'left barb down right barb down harpoon', MathPlayer: 'arpón inferior derecha-izquierda', google: 'barb de la izquierda hacia abajo barb barb por harpoon') + - "⥑": [T: "arpón izquierdo con puntas hacia arriba y hacia abajo"] # 0x2951 (en: 'up barb left down barb left harpoon') + - "⥒": [T: "arpón hacia la izquierda con punta hasta la barra"] # 0x2952 (en: 'leftwards harpoon with barb up to bar', MathPlayer: 'leftwards harpoon to bar with barb upwards', google: 'arpón de la izquierda con barb hasta bar') + - "⥓": [T: "arpón hacia la derecha con punta hasta la barra"] # 0x2953 (en: 'rightwards harpoon with barb up to bar', MathPlayer: 'rightwards harpoon to bar with barb upwards', google: 'arpoon a la derecha con barb hasta bar') + - "⥔": [T: "arpón ascendente con punta derecha hacia la barra"] # 0x2954 (en: 'upwards harpoon with barb right to bar', MathPlayer: 'upwards harpoon to bar with barb rightwards', google: 'hacia arriba hacia arriba con barb directamente a bar') + - "⥕": [T: "arpón hacia abajo con punta derecha hacia la barra"] # 0x2955 (en: 'downwards harpoon with barb right to bar', MathPlayer: 'downwards harpoon to bar with barb rightwards', google: 'harpoon hacia abajo con barb directamente a bar') + - "⥖": [T: "arpón hacia la izquierda con punta descendente hacia la barra"] # 0x2956 (en: 'leftwards harpoon with barb down to bar', MathPlayer: 'leftwards harpoon to bar with barb downwards', google: 'arpón de la izquierda con barb hasta el bar') + - "⥗": [T: "arpón hacia la derecha con punta inferior hacia la barra"] # 0x2957 (en: 'rightwards harpoon with barb down to bar', MathPlayer: 'rightwards harpoon to bar with barb downwards', google: 'arpoon a la derecha con barb hasta bar') + - "⥘": [T: "arpón ascendente con punta izquierda hacia la barra"] # 0x2958 (en: 'upwards harpoon with barb left to bar', MathPlayer: 'upwards harpoon to bar with barb leftwards', google: 'hace arriba de barb con barb se fue a bar') + - "⥙": [T: "arpón hacia abajo con punta izquierda hacia la barra"] # 0x2959 (en: 'downwards harpoon with barb left to bar', MathPlayer: 'downwards harpoon to bar with barb leftwards', google: 'arpón hacia abajo con barb se fue a bar') + - "⥚": [T: "arpón hacia la izquierda con punta por encima de la barra"] # 0x295a (en: 'leftwards harpoon with barb up from bar', MathPlayer: 'leftwards harpoon from bar with barb upwards', google: 'arpón de la izquierda con barb arriba desde el bar') + - "⥛": [T: "arpón hacia la derecha con punta por encima de la barra"] # 0x295b (en: 'rightwards harpoon with barb up from bar', MathPlayer: 'rightwards harpoon from bar with barb upwards', google: 'arpoon a la derecha con barb up from bar') + - "⥜": [T: "arpón ascendente con punta partiendo de la barra"] # 0x295c (en: 'upwards harpoon with barb right from bar', MathPlayer: 'upwards harpoon from bar with barb rightwards', google: 'hacia arriba hacia arriba con barb directamente desde el bar') + - "⥝": [T: "arpón descendente con punta partiendo de la barra"] # 0x295d (en: 'downwards harpoon with barb right from bar', MathPlayer: 'downwards harpoon from bar with barb rightwards', google: 'arpón hacia abajo con barb directamente desde el bar') + - "⥞": [T: "arpón hacia la izquierda con punta por debajo de la barra"] # 0x295e (en: 'leftwards harpoon with barb down from bar', MathPlayer: 'leftwards harpoon from bar with barb downwards', google: 'arpón hacia la izquierda con barb down desde bar') + - "⥟": [T: "arpón hacia la derecha con punta por debajo de barra"] # 0x295f (en: 'rightwards harpoon with barb down from bar', MathPlayer: 'rightwards harpoon from bar with barb downwards', google: 'arpoon a la derecha con barb down desde bar') + - "⥠": [T: "arpón ascendente con punta a la izquierda de la barra"] # 0x2960 (en: 'upwards harpoon with barb left from bar', MathPlayer: 'upwards harpoon from bar with barb leftwards', google: 'hacia arriba de la arpón con barb se queda desde el bar') + - "⥡": [T: "arpón descendente con punta a la izquierda de la barra"] # 0x2961 (en: 'downwards harpoon with barb left from bar', MathPlayer: 'downwards harpoon from bar with barb leftwards', google: 'arpón hacia abajo con barb se queda desde el bar') + - "⥢": [T: "arpón hacia la izquierda con punta por encima de arpon hacia la izquierda con punta hacia abajo"] # 0x2962 (en: 'leftwards harpoon with barb up above leftwards harpoon with barb down', MathPlayer: 'leftwards harpoon with barb up above leftwards harpoon with barb down', google: 'arpón de la izquierda con barb arriba sobre la arpón hacia la izquierda con barb down') + - "⥣": [T: "arpón ascendente con punta hacia la izquierda al lado de arpón ascendente con punta hacia la derecha"] # 0x2963 (en: 'upwards harpoon with barb left beside upwards harpoon with barb right', MathPlayer: 'upwards harpoon with barb left beside upwards harpoon with barb right', google: 'hacia arriba de la arpón con barb izquierda junto a la arpón hacia arriba con barb a la derecha') + - "⥤": [T: "arpón hacia la derecha con punta por encima de arpón hacia la derecha con punta hacia abajo"] # 0x2964 (en: 'rightwards harpoon with barb up above rightwards harpoon with barb down', MathPlayer: 'rightwards harpoon with barb up above rightwards harpoon with barb down', google: 'arpoon a la derecha con barb arriba sobre la arpón de la derecha con barb down') + - "⥥": [T: "arpón hacia abajo con lengüeta a la izquierda al lado arpón hacia abajo con lengüeta a la derecha"] # 0x2965 (en: 'downwards harpoon with barb left beside downwards harpoon with barb right', MathPlayer: 'downwards harpoon with barb left beside downwards harpoon with barb right', google: 'arpón hacia abajo con barb izquierda junto a la arpón hacia abajo con barb a la derecha') + - "⥦": [T: "arpón a la izquierda con punta por encima de arpón a la derecha con punta hacia arriba"] # 0x2966 (en: 'leftwards harpoon with barb up above rightwards harpoon with barb up', MathPlayer: 'leftwards harpoon with barb up above rightwards harpoon with barb up', google: 'arpón hacia la izquierda con barb arriba sobre la arpón hacia la derecha con barb') + - "⥧": [T: "arpón a la izquierda con punta hacia abajo por encima de arpón a la derecha con punta hacia abajo"] # 0x2967 (en: 'leftwards harpoon with barb down above rightwards harpoon with barb down', MathPlayer: 'leftwards harpoon with barb down above rightwards harpoon with barb down', google: 'arpón de la izquierda con barb hacia abajo sobre la arpón hacia la derecha con barb down') + - "⥨": [T: "arpón a la derecha con punta hacia arriba por encima de arpón hacia la izquierda con punta hacia arriba"] # 0x2968 (en: 'rightwards harpoon with barb up above leftwards harpoon with barb up', MathPlayer: 'rightwards harpoon with barb up above leftwards harpoon with barb up', google: 'arpoon a la derecha con barb arriba sobre la arpón de la izquierda con barb hacia arriba') + - "⥩": [T: "arpón a la derecha con punta hacia abajo por encima de arpón a la izquierda con punta hacia abajo"] # 0x2969 (en: 'rightwards harpoon with barb down above leftwards harpoon with barb down', MathPlayer: 'rightwards harpoon with barb down above leftwards harpoon with barb down', google: 'arpón a la derecha con barb hacia abajo sobre la arpón hacia la izquierda con barb down') + - "⥪": [T: "arpón hacia la izquierda con punta hacia arriba por encima de raya larga discontinua"] # 0x296a (en: 'leftwards harpoon with barb up above long dash') + - "⥫": [T: "arpón hacia la izquierda con punta hacia abajo por debajo de raya larga discontinua"] # 0x296b (en: 'leftwards harpoon with barb down below long dash') + - "⥬": [T: "arpón hacia la derecha con punta por encima de raya larga discontinua"] # 0x296c (en: 'rightwards harpoon with barb up above long dash') + - "⥭": [T: "arpón hacia la derecha con punta hacia abajo por debajo de raya larga discontinua"] # 0x296d (en: 'rightwards harpoon with barb down below long dash') + - "⥮": [T: "arpón ascendente con punta a la izquierda al lado arpón descendente con punta a la derecha"] # 0x296e (en: 'upwards harpoon with barb left beside downwards harpoon with barb right', MathPlayer: 'upwards harpoon to the left of downwards harpoon', google: 'hacia arriba de la arpón con barb izquierda junto al arpón hacia abajo con barb a la derecha') + - "⥯": [T: "arpón hacia abajo con lengüeta a la izquierda al lado arpón hacia arriba con lengüeta a la derecha"] # 0x296f (en: 'downwards harpoon with barb left beside upwards harpoon with barb right', MathPlayer: 'upwards harpoon to the right of downwards harpoon', google: 'arpón hacia abajo con barb izquierda junto a la arpón hacia arriba con barb a la derecha') + - "⥰": [T: "flecha doble hacia la derecha con cabeza redondeada"] # 0x2970 (en: 'right double arrow with rounded head') + - "⥱": [T: "flecha hacia la derecha con signo igual por encima"] # 0x2971 (en: 'equals above rightwards arrow') + - "⥲": [T: "flecha con tilde"] # 0x2972 (en: 'tilde operator above rightwards arrow') + - "⥳": [T: "tilde con flecha"] # 0x2974 (en: 'rightwards arrow above tilde operator') + - "⥵": [T: "flecha hacia la derecha por encima de signo casi igual a"] # 0x2975 (en: 'rightwards arrow above almost equal to') + - "⥶": [T: "signo menor que por encima de flecha hacia la izquierda"] # 0x2976 (en: 'less than above leftwards arrow') + - "⥷": [T: "flecha hacia la izquierda atravesando signo menor que"] # 0x2977 (en: 'leftwards arrow through less than') + - "⥸": [T: "signo mayor que por encima de flecha hacia la derecha"] # 0x2978 (en: 'greater than above rightwards arrow') + - "⥹": [T: "subconjunto por encima de flecha hacia la derecha"] # 0x2979 (en: 'subset above rightwards arrow') + - "⥺": [T: "flecha hacia la izquierda a través de subconjunto"] # 0x297a (en: 'leftwards arrow through subset') + - "⥻": [T: "superconjunto por encima de flecha hacia la izquierda"] # 0x297b (en: 'superset above leftwards arrow') + - "⥼": [T: "cola de pez izquierda"] # 0x297c (en: 'left fish tail', MathPlayer: 'left fish tail', google: 'cola de pescado izquierdo') + - "⥽": [T: "cola de pez derecha"] # 0x297d (en: 'right fish tail', MathPlayer: 'right fish tail', google: 'cola de pescado derecho') + - "⥾": [T: "cola de pez hacia arriba"] # 0x297e (en: 'up fish tail') + - "⥿": [T: "cola de pez haciaabajo"] # 0x297f (en: 'down fish tail', MathPlayer: 'down fish tail', google: 'abajo de la cola de pescado') + - "⦀": [T: "delimitador triple barra vertical"] # 0x2980 (en: 'triple vertical bar delimiter', google: 'delimitador de triple barra vertical') + - "⦁": [T: "punto de notación Z"] # 0x2981 (en: 'z notation spot', google: 'z spot de notación') + - "⦂": [T: "tipo de notación Z Colon"] # 0x2982 (en: 'z notation type colon', google: 'z tipo de notación colon') + - "⦃": [T: "soporte rotacional blanco izquierdo"] # 0x2983 (en: 'left white brace', google: 'brace blanco izquierdo') + - "⦄": [T: "soporte rotacional blanco derecho"] # 0x2984 (en: 'right white brace', google: 'brace blanco derecho') + - "⦅": [T: "paréntesis izquierdo"] # 0x2985 (en: 'left white parenthesis') + - "⦆": [T: "paréntesis derecho"] # 0x2986 (en: 'right white parenthesis') + - "⦇": [T: "notación Z izquierda soporte de imagen"] # 0x2987 (en: 'z notation left image bracket', google: 'z notación del soporte de la imagen izquierda') + - "⦈": [T: "notación Z derecha soporte de imagen"] # 0x2988 (en: 'z notation right image bracket', google: 'z notación de la imagen correcta soporte de imagen') + - "⦉": [T: "notación Z izquierda unida a soporte"] # 0x2989 + - "⦊": [T: "notación Z derecha unida a soporte"] # 0x298a + - "⦋": [T: "corchete izquierdo con barra ijnferior"] # 0x298b (en: 'left square bracket with underbar') + - "⦌": [T: "corchete derecho con barra inferior"] # 0x298c (en: 'right square bracket with underbar') + - "⦍": [T: "corchete izquierdo con trazo en esquina superior"] # 0x298d (en: 'left square bracket with tick in top corner') + - "⦎": [T: "corchete derecho con trazo en esquina inferior"] # 0x298e (en: 'right square bracket with tick in bottom corner') + - "⦏": [T: "corchete izquierdo con trazo en esquina inferior"] # 0x298f (en: 'left square bracket with tick in bottom corner') + - "⦐": [T: "corchete derecho con trazo en esquina superior"] # 0x2990 (en: 'right square bracket with tick in top corner') + - "⦑": [T: "ángulo izquierdo de corchete con punto"] # 0x2991 + - "⦒": [T: "ángulo derecho de corchete con punto"] # 0x2992 + - "⦓": [T: "arco izquierdo menor que soporte"] # 0x2993 + - "⦔": [T: "arco derecho mayor que soporte"] # 0x2994 + - "⦕": [T: "doble arco izquierdo mayor que soporte"] # 0x2995 + - "⦖": [T: "doble arco derecho menor que soporte"] # 0x2996 + - "⦗": [T: "soporte de concha de tortuga negra izquierda"] # 0x2997 (en: 'left black tortoise shell bracket') + - "⦘": [T: "soporte con concha de tortuga a la derecha"] # 0x2998 (en: 'right black tortoise shell bracket', google: 'soporte de carcasa de tortuga negra derecha') + - "⦙": [T: "valla punteada"] # 0x2999 (en: 'dotted fence') + - "⦚": [T: "línea vertical en zigzag"] # 0x299a (en: 'vertical zigzag line') + - "⦛": [T: "Ángulo medido de apertura a la izquierda"] # 0x299b (en: 'measured angle opening left', google: 'apertura de ángulo medido a la izquierda') + - "⦜": [T: "Variante de ángulo recto con cuadrado"] # 0x299c (en: 'right angle variant with square', google: 'variante de ángulo recto con cuadrado') + - "⦝": [T: "ángulo recto medido con punto"] # 0x299d (en: 'measured right angle with dot') + - "⦞": [T: "Ángulo con S dentro"] # 0x299e (en: 'angle with s inside', google: 'ángulo con s adentro') + - "⦟": [T: "Ángulo agudo"] # 0x299f (en: 'acute angle', google: 'ángulo agudo') + - "⦠": [T: "Ángulo esférico de apertura a la izquierda"] # 0x29a0 (en: 'spherical angle opening left', google: 'abertura del ángulo esférico izquierda') + - "⦡": [T: "ángulo esférico con apertura hacia arriaba"] # 0x29a1 (en: 'spherical angle opening up', google: 'abertura del ángulo esférico') + - "⦢": [T: "ángulo girado"] # 0x29a2 (en: 'turned angle', google: 'ángulo girado') + - "⦣": [T: "Ángulo invertido"] # 0x29a3 (en: 'reversed angle', google: 'ángulo invertido') + - "⦤": [T: "ángulo con barra inferior"] # 0x29a4 (en: 'angle with underbar') + - "⦥": [T: "ángulo invertido con barra inferior"] # 0x29a5 (en: 'reversed angle with underbar') + - "⦦": [T: "ángulo oblicuo abierto hacia arriba"] # 0x29a6 (en: 'oblique angle opening up') + - "⦧": [T: "ángulo oblicuo abierto hacia abajo"] # 0x29a7 (en: 'oblique angle opening down') + - "⦨": [T: "ángulo medio con brazo extendido terminando en flecha hacia arriba y hacia la derecha"] # 0x29a8 + - "⦩": [T: "ángulo medio con brazo extendido terminando en flecha hacia arriba y hacia la izquierda"] # 0x29a9 + - "⦪": [T: "ángulo medio con brazo extendido terminando en flecha hacia abajo y hacia la derecha"] # 0x29aa + - "⦫": [T: "ángulo medio con brazo extendido terminando en flecha hacia abajo y hacia la izquierda"] # 0x29ab + - "⦬": [T: "ángulo medio con brazo extendido terminando en flecha hacia la derecha y hacia arriba"] # 0x29ac + - "⦭": [T: "ángulo medio con brazo extendido terminando en flecha apuntando hacia la izquierda y hacia arriba"] # 0x29ad + - "⦮": [T: "ángulo medio con brazo extendido terminando en flecha hacia la derecha y hacia abajo"] # 0x29ae + - "⦯": [T: "ángulo medio con brazo extendido terminando en flecha hacia la izquierda y hacia abajo"] # 0x29af + - "⦰": [T: "conjunto vacío invertido"] # 0x29b0 (en: 'reversed empty set') + - "⦱": [T: "conjunto vacío con barra superior"] # 0x29b1 (en: 'empty set with overbar') + - "⦲": [T: "conjunto vacío con círculo pequeño encima"] # 0x29b2 (en: 'empty set with small circle above') + - "⦳": [T: "conjunto vacío con flecha derecha encima"] # 0x29b3 (en: 'empty set with right arrow above') + - "⦴": [T: "conjunto vacío con flecha izquierda encima"] # 0x29b4 (en: 'empty set with left arrow above') + - "⦵": [T: "círculo con barra horizontal"] # 0x29b5 (en: 'circle with horizontal bar') + - "⦶": [T: "barra vertical rodeada por un círculo"] # 0x29b6 (en: 'circled vertical bar') + - "⦷": [T: "paralelas rodeadas por un círculo"] # 0x29b7 (en: 'circled parallel') + - "⦸": [T: "solidus en círculo inverso"] # 0x29b8 (en: 'circled reverse solidus', google: 'solidus reverso en circulación') + - "⦹": [T: "perpendicular rodeada por un círculo"] # 0x29b9 (en: 'circled perpendicular') + - "⦺": [T: "círculo dividido por barra horizontal y mitad superior dividido por barra vertical"] # 0x29ba (en: 'circled divided by horizontal bar and top half divided by vertical bar', google: 'círculo dividido por la barra horizontal y la mitad superior dividida por la barra vertical') + - "⦻": [T: "círculo con x superpuesta"] # 0x29bb (en: 'circle with superimposed x') + - "⦼": [T: "círculo en sentido contrario a las agujas del reloj virando a signo de división"] # 0x29bc (en: 'circled anticlockwise rotated division sign') + - "⦽": [T: "flecha hacia arriba a través de círculo"] # 0x29bd (en: 'up arrow through circle', google: 'arrow a través del círculo') + - "⦾": [T: "viñeta vacía en un círculo"] # 0x29be (en: 'circled white bullet') + - "⦿": [T: "viñeta en un círculo"] # 0x29bf (en: 'circled bullet') + - "⧀": [T: "signo menor que en un círculo"] # 0x29c0 (en: 'circled less than') + - "⧁": [T: "signo mayor que en un círculo"] # 0x29c1 (en: 'circled greater than') + - "⧂": [T: "círculo con círculo pequeño a la derecha"] # 0x29c2 (en: 'circle with small circle to the right') + - "⧃": [T: "círculo con dos trazos horizontales a la derecha"] # 0x29c3 + - "⧄": [T: "cuadrado con diagonal ascendente"] # 0x29c4 (en: 'squared rising diagonal slash') + - "⧅": [T: "cuadrado con diagonal descendente"] # 0x29c5 (en: 'squared falling diagonal slash') + - "⧆": [T: "asterisco cuadrado"] # 0x29c6 (en: 'squared asterisk') + - "⧇": [T: "pequeño círculo cuadrado"] # 0x29c7 (en: 'squared small circle', google: 'círculo pequeño cuadrado') + - "⧈": [T: "cuadrado cuadrado"] # 0x29c8 (en: 'squared square') + - "⧉": [T: "dos cuadrados unidos"] # 0x29c9 (en: 'two joined squares') + - "⧊": [T: "triángulo con punto arriba"] # 0x29ca (en: 'triangle with dot above') + - "⧋": [T: "triángulo con barra inferior"] # 0x29cb (en: 'triangle with underbar', google: 'triángulo con debajo de la barra') + - "⧌": [T: "s dentro de un triangulo"] # 0x29cc (en: 's in triangle', google: 's en triángulo') + - "⧍": [T: "triángulo con serifs en la parte inferior"] # 0x29cd + - "⧎": [T: "triángulo hacia la derecha sobre triángulo hacia la izquierda"] # 0x29ce (en: 'right triangle above left triangle') + - "⧏": [T: "triángulo izquierdo al lado de barra vertical"] # 0x29cf (en: 'left triangle beside vertical bar') + - "⧐": [T: "barra vertical al lado de triángulo derecho"] # 0x29d0 (en: 'vertical bar beside right triangle') + - "⧑": [T: "pajarita Con Mitad Izquierda Negra"] # 0x29d1 (en: 'bowtie with left half black', google: 'bowtie con la mitad de la izquierda') + - "⧒": [T: "pajarita Con Mitad Derecha Negra"] # 0x29d2 (en: 'bowtie with right half black', google: 'bowtie con la mitad derecha negra') + - "⧓": [T: "pajarita Negra"] # 0x29d3 (en: 'black bowtie', google: 'bowtie negro') + - "⧔": [T: "multiplicado por con mitad izquierda negra"] # 0x29d4 (en: 'times with left half black', google: 'veces con la mitad de la izquierda') + - "⧕": [T: "multiplicado por con mitad derecha negra"] # 0x29d5 (en: 'times with right half black', google: 'veces con la mitad derecha negra') + - "⧖": [T: "reloj de arena blanco"] # 0x29d6 (en: 'white hourglass', google: 'hourglass blancos') + - "⧗": [T: "reloj de arena negro"] # 0x29d7 (en: 'black hourglass', google: 'hourglass negros') + - "⧘": [T: "valla izquierda ondulada"] # 0x29d8 (en: 'left wiggly fence', google: 'left fence wiggly') + - "⧙": [T: "valla derecha ondulada"] # 0x29d9 (en: 'right wiggly fence', google: 'derecha cerca ondulada') + - "⧚": [T: "valla doble izquierda ondulada"] # 0x29da + - "⧛": [T: "valla doble derecha ondulada"] # 0x29db + - "⧜": [T: "infinito incompleto"] # 0x29dc (en: 'incomplete infinity') + - "⧝": [T: "infinito"] # 0x29dd (en: 'tie over infinity', google: 'ate el infinito') + - "⧞": [T: "no infinito"] # 0x29de (en: 'infinity negated with vertical bar') + - "⧟": [T: "multimapa de doble extremo"] # 0x29df (en: 'double-ended multimap') + - "⧠": [T: "cuadrado con contorno delineado"] # 0x29e0 (en: 'square with contoured outline') + - "⧡": [T: "aumenta a medida que"] # 0x29e1 (en: 'increases as') + - "⧢": [T: "producto aleatorio"] # 0x29e2 (en: 'shuffle product', google: 'producto de baraja') + - "⧣": [T: "signo igual y paralela inclinada"] # 0x29e3 (en: 'equals sign and slanted parallel', MathPlayer: 'igual tachado doble', google: 'es igual a la señal y se inclinó paralelo') + - "⧤": [T: "signo igual y paralela inclinada con tilde por encima"] # 0x29e4 (en: 'equals sign and slanted parallel with tilde above') + - "⧥": [T: "idéntico a una paralela inclinada"] # 0x29e5 (en: 'identical to and slanted parallel') + - "⧦": [T: "gleich Stark"] # 0x29e6 (en: 'gleich stark', google: 'gleich stark') + - "⧧": [T: "termodinámica"] # 0x29e7 (en: 'thermodynamic', google: 'termodinámico') + - "⧨": [T: "triángulo apuntando hacia abajo con la mitad izquierda negra"] # 0x29e8 (en: 'down pointing triangle with left half black', google: 'down pointing triangle con la mitad izquierda') + - "⧩": [T: "triángulo apuntando hacia abajo con la mitad derecha negra"] # 0x29e9 (en: 'down pointing triangle with right half black', google: 'down apuntando al triángulo con la mitad derecha negra') + - "⧪": [T: "rombo negro con flecha hacia abajo"] # 0x29ea (en: 'black diamond with down arrow') + - "⧫": [T: "rombo relleno"] # 0x29eb (en: 'black lozenge') + - "⧬": [T: "círculo blanco con flecha hacia abajo"] # 0x29ec (en: 'white circle with down arrow') + - "⧭": [T: "círculo negro con flecha hacia abajo"] # 0x29ed (en: 'black circle with down arrow') + - "⧮": [T: "cuadrado blanco con error barrado"] # 0x29ee (en: 'error-barred white square', google: 'cuadrado blanco con barra de error') + - "⧯": [T: "cuadrado negro con error barrado"] # 0x29ef (en: 'error-barred black square', google: 'cuadrado negro con barra de error') + - "⧰": [T: "rombo blanco con error barrado"] # 0x29f0 (en: 'error-barred white diamond', google: 'diamante blanco con accesorios de error') + - "⧱": [T: "rombo negro con error barrado"] # 0x29f1 (en: 'error-barred black diamond', google: 'diamante negro con accesorios de error') + - "⧲": [T: "círculo blanco con error barrado"] # 0x29f2 (en: 'error-barred white circle', google: 'círculo blanco con barra de error') + - "⧳": [T: "círculo negro con error barrado"] # 0x29f3 (en: 'error-barred black circle', google: 'círculo negro con barra de error') + - "⧴": [T: "regla retardada"] # 0x29f4 (en: 'rule-delayed') + - "⧵": [T: "operador de Solidus Inverso"] # 0x29f5 (en: 'reverse solidus operator', google: 'operador reverso de solidus') + - "⧶": [T: "solidus con barra superior"] # 0x29f6 + - "⧷": [T: "solidus inverso con trazo horizontal"] # 0x29f7 (en: 'reverse solidus with horizontal stroke', google: 'reverse solidus con carrera horizontal') + - "⧸": [T: "sólido grande"] # 0x29f8 (en: 'big solidus', google: 'big solidus') + - "⧹": [T: "solidus inverso grande"] # 0x29f9 (en: 'big reverse solidus', google: 'big reverso solidus') + - "⧺": [T: "doble signo más"] # 0x29fa (en: 'double plus', google: 'doble más') + - "⧻": [T: "triple signo más"] # 0x29fb (en: 'triple plus', google: 'triple plus') + - "⧼": [T: "paréntesis con ángulo curvado hacia la izquierda"] # 0x29fc (en: 'left pointing curved angle bracket', google: 'soporte de ángulo curvo de apuntamiento izquierdo') + - "⧽": [T: "paréntesis con ángulo curvado hacia la derecha"] # 0x29fd (en: 'right pointing curved angle bracket', google: 'soporte de ángulo curvo apuntando a la derecha') + - "⧾": [T: "minúsculo"] # 0x29fe (en: 'tiny', google: 'diminuto') + - "⧿": [T: "miny"] # 0x29ff + - "⨀": [T: "operador de puntos circulares N-Ary"] # 0x2a00 (en: 'circled dot operator', google: 'operador de puntos en circulación') + - "⨁": [T: "operador N-Ary con signo más en un círculo"] # 0x2a01 (en: 'circled plus operator', google: 'operador circlado plus') + - "⨂": [T: "operador N-Ary con signo multiplicado por dentro de un círculo"] # 0x2a02 (en: 'circled times operator', google: 'operador de times en circulación') + - "⨃": [T: "operador de la unión N-Ary con punto"] # 0x2a03 (en: 'union operator with dot', google: 'operador sindical con dot') + - "⨄": [T: "n-Ary Union Operator con signo más"] # 0x2a04 (en: 'union operator with plus', google: 'operador sindical con más') + - "⨅": [T: "operador de intersecciones cuadradas N-Ary"] # 0x2a05 (en: 'square intersection operator', google: 'operador de intersección cuadrada') + - "⨆": [T: "n-Ary Square Union Operator"] # 0x2a06 (en: 'square union operator', google: 'operador de la unión square') + - "⨇": [T: "dos lógico y operador"] # 0x2a07 (en: 'two logical and operator', google: 'dos lógicos y operadores') + - "⨈": [T: "dos lógico u operador"] # 0x2a08 (en: 'two logical or operator', google: 'dos lógicos u operadores') + - "⨉": [T: "operador multiplicado por N-Ary Times"] # 0x2a09 (en: 'times operator', google: 'operador de tiempos') + - "⨊": [T: "módulo dos sumas"] # 0x2a0a (en: 'modulo two sum', google: 'módulo dos suma') + - "⨋": [T: "suma con Integral"] # 0x2a0b (en: 'summation with integral', google: 'suma con integral') + - "⨌": [T: "operador integral cuádruple"] # 0x2a0c (en: 'quadruple integral operator') + - "⨍": [T: "parte integral finita"] # 0x2a0d + - "⨎": [T: "integral con Doble Trazo"] # 0x2a0e (en: 'integral with double stroke', google: 'integral con doble trazo') + - "⨏": [T: "promedio Integral con barra discontinua"] # 0x2a0f (en: 'integral average with slash', google: 'promedio integral con corte') + - "⨐": [T: "circulation function"] # 0x2a10 + - "⨑": [T: "integral en sentido contrario a las agujas del reloj"] # 0x2a11 (en: 'anticlockwise integration') + - "⨒": [T: "integral lineal para rectángulo en polo"] # 0x2a12 (en: 'line integration with rectangular path around pole') + - "⨓": [T: "integral lineal para semicírculo en polo"] # 0x2a13 (en: 'line integration with semicircular path around pole') + - "⨔": [T: "integral lineal excluyendo el polo"] # 0x2a14 (en: 'line integration not including the pole') + - "⨕": [T: "integral en torno a un punto operador"] # 0x2a15 (en: 'integral around a point operator') + - "⨖": [T: "operador integral para cuaterniones"] # 0x2a16 (en: 'quaternion integral operator') + - "⨗": [T: "integral con flecha hacia la izquierda con garfio"] # 0x2a17 (en: 'integral with leftwards arrow with hook') + - "⨘": [T: "integral con signo multiplicado por"] # 0x2a18 (en: 'integral with times sign', google: 'integral con el signo de tiempos') + - "⨙": [T: "integral con Intersección"] # 0x2a19 (en: 'integral with intersection', google: 'integral con la intersección') + - "⨚": [T: "integral con unión"] # 0x2a1a (en: 'integral with union', google: 'integral con la unión') + - "⨛": [T: "integral con barra superior"] # 0x2a1b (en: 'integral with overbar', google: 'integral con overbar') + - "⨜": [T: "integral con barra inferior"] # 0x2a1c (en: 'integral with underbar', google: 'integral con underbar') + - "⨝": [T: "unir"] # 0x2a1d (en: 'join') + - "⨞": [T: "operador de triángulo izquierdo grande"] # 0x2a1e (en: 'large left triangle operator', google: 'gran operador del triángulo izquierdo') + - "⨟": [T: "composición de esquemas de notación Z"] # 0x2a1f (en: 'z notation schema composition', google: 'z composición de esquema de notación') + - "⨠": [T: "esquema de notación Z"] # 0x2a20 (en: 'z notation schema piping', google: 'z tubería de esquema de notación') + - "⨡": [T: "proyección del esquema de notación Z"] # 0x2a21 (en: 'z notation schema projection', google: 'z proyección de esquema de notación') + - "⨢": [T: "signo más con círculo encima"] # 0x2a22 (en: 'plus sign with circle above') + - "⨣": [T: "signo más con signo circunflejo encima"] # 0x2a23 (en: 'plus sign with circumflex accent above') + - "⨤": [T: "signo más con tilde encima"] # 0x2a24 (en: 'plus sign with tilde above') + - "⨥": [T: "signo más con punto inferior"] # 0x2a25 (en: 'plus sign with dot below') + - "⨦": [T: "signo más con tilde inferior"] # 0x2a26 (en: 'plus sign with tilde below') + - "⨧": [T: "signo más con 2 subíndice"] # 0x2a27 (en: 'plus sign with subscript two') + - "⨨": [T: "signo más con triángulo negro"] # 0x2a28 (en: 'plus sign with black triangle', google: 'más letrero con triángulo negro') + - "⨩": [T: "signo menos con coma encima"] # 0x2a29 (en: 'minus sign with comma above') + - "⨪": [T: "signo menos con punto inferior"] # 0x2a2a (en: 'minus sign with dot below') + - "⨫": [T: "signo menos con puntos descendentes"] # 0x2a2b (en: 'minus sign with falling dots', google: 'señal menos con puntos de caída') + - "⨬": [T: "signo menos con puntos ascendentes"] # 0x2a2c (en: 'minus sign with rising dots', google: 'minus firma con puntos ascendentes') + - "⨭": [T: "signo más en semicírculo izquierdo"] # 0x2a2d (en: 'plus sign in left half circle') + - "⨮": [T: "signo más en semicírculo derecho"] # 0x2a2e (en: 'plus sign in right half circle') + - "⨯": [T: "producto vectorial"] # 0x2a2f (en: 'cross product') + - "⨰": [T: "signo de multiplicación con punto encima"] # 0x2a30 (en: 'multiplication sign with dot above') + - "⨱": [T: "signo de multiplicación con barra inferior"] # 0x2a31 (en: 'multiplication sign with underbar') + - "⨲": [T: "producto semidirecto con fondo cerrado"] # 0x2a32 (en: 'semidirect product with bottom closed') + - "⨳": [T: "smash product"] # 0x2a33 + - "⨴": [T: "signo de multiplicación dentro de semicírculo izquierdo"] # 0x2a34 (en: 'multiplication sign in left half circle') + - "⨵": [T: "signo de multiplicación dentro de semicírculo derecho"] # 0x2a35 (en: 'multiplication sign in right half circle') + - "⨶": [T: "signo de multiplicación dentro de círculo con circunflejo"] # 0x2a36 (en: 'circled multiplication sign with circumflex accent') + - "⨷": [T: "signo de multiplicación en doble círculo"] # 0x2a37 (en: 'multiplication sign in double circle') + - "⨸": [T: "signo de división dentro de un círdulo"] # 0x2a38 (en: 'circled division sign') + - "⨹": [T: "signo más dentro de un triángulo"] # 0x2a39 (en: 'plus sign in triangle') + - "⨺": [T: "signo menos dentro de un triángulo"] # 0x2a3a (en: 'minus sign in triangle') + - "⨻": [T: "signo de multiplicación dentro de un triángulo"] # 0x2a3b (en: 'multiplication sign in triangle') + - "⨼": [T: "producto interior"] # 0x2a3c (en: 'interior product') + - "⨽": [T: "producto interior derecho"] # 0x2a3d (en: 'righthand interior product') + - "⨮": [T: "signo más en semicírculo derecho"] # 0x2a2e (en: 'z notation relational composition') + - "⨿": [T: "coproducto"] # 0x2a3f (en: 'amalgamation or coproduct') + - "⩀": [T: "intersección con punto"] # 0x2a40 (en: 'intersection with dot') + - "⩁": [T: "unión con signo menos"] # 0x2a41 (en: 'union with minus sign', google: 'unión con menos signo') + - "⩂": [T: "unión con barrasuperior"] # 0x2a42 (en: 'union with overbar') + - "⩃": [T: "intersección con barrasuperior"] # 0x2a43 (en: 'intersection with overbar') + - "⩄": [T: "intersección con and lógico"] # 0x2a44 (en: 'intersection with logical and') + - "⩅": [T: "unión con or lógico"] # 0x2a45 (en: 'union with logical or') + - "⩆": [T: "unión sobre intersección"] # 0x2a46 (en: 'union above intersection') + - "⩇": [T: "intersección sobre unión"] # 0x2a47 (en: 'intersection above union') + - "⩈": [T: "unión sobre barra sobre intersección"] # 0x2a48 (en: 'union above bar above intersection') + - "⩉": [T: "intersección sobre barra sobre unión"] # 0x2a49 (en: 'intersection above bar above union', MathPlayer: 'intersección sobre barra, sobre unión', google: 'intersección por encima de la barra por encima de la unión') + - "⩊": [T: "unión y unión"] # 0x2a4a (en: 'union beside and joined with union') + - "⩋": [T: "intersección e intersección"] # 0x2a4b (en: 'intersection beside and joined with intersection') + - "⩌": [T: "unión cerrada con serifs"] # 0x2a4c (en: 'closed union with serifs') + - "⩍": [T: "intersección cerrada con serifs"] # 0x2a4d (en: 'closed intersection with serifs') + - "⩎": [T: "intersección cuadrada doble"] # 0x2a4e (en: 'double square intersection', google: 'intersección doble cuadrado') + - "⩏": [T: "unión cuadrada doble"] # 0x2a4f (en: 'double square union', google: 'unión doble cuadrado') + - "⩐": [T: "unión cerrada con serifs y signo de multiplicación"] # 0x2a50 (en: 'closed union with serifs and smash product') + - "⩑": [T: "lógico y con punto arriba."] # 0x2a51 (en: 'logical and with dot above', google: 'lógico y con punto arriba') + - "⩒": [T: "lógico o con punto arriba"] # 0x2a52 (en: 'logical or with dot above') + - "⩓": [T: "Y"] # 0x2a53 (en: 'double logical and') + - "⩔": [T: "O"] # 0x2a54 (en: 'double logical or') + - "⩕": [T: "doble Y lógica intersecada"] # 0x2a55 + - "⩖": [T: "doble O lógica intersecada"] # 0x2a56 + - "⩗": [T: "O grande inclinada"] # 0x2a57 + - "⩘": [T: "Y grande inclinada"] # 0x2a58 + - "⩙": [T: "lógica O superpuesta a lógica Y"] # 0x2a59 (en: 'logical or overlapping logical and', google: 'lógico o superpuesto lógico y') + - "⩚": [T: "Y lógica con trazo en medio"] # 0x2a5a + - "⩛": [T: "O lógica con trazo en medio"] # 0x2a5b + - "⩜": [T: "Y lógica con barra horizontal discontinua"] # 0x2a5c + - "⩝": [T: "O lógica con barra horizontal discontinua"] # 0x2a5d + - "⩞": [T: "Y lógica con doble barra superior"] # 0x2a5e (en: 'logical and with double overbar', google: 'lógico y con doble overbar') + - "⩟": [T: "Y lógica con barra inferior"] # 0x2a5f + - "⩠": [T: "Y lógica con doble barra inferior."] # 0x2a60 (en: 'logical and with double underbar', google: 'lógico y con doble debajo de la barra') + - "⩡": [T: "pequeño Vee con barra inferior"] # 0x2a61 (en: 'small vee with underbar', google: 'pequeño vee con debajo de la barra') + - "⩢": [T: "O lógica con doble barra."] # 0x2a62 (en: 'logical or with double overbar', google: 'lógico o con doble overbar') + - "⩣": [T: "O lógica con doble barra inferior"] # 0x2a63 (en: 'logical or with double underbar', google: 'lógico o con doble bajo') + - "⩤": [T: "notación Z Dominio Antirestricción"] # 0x2a64 (en: 'z notation domain antirestriction', google: 'z dominio de notación antirestricción') + - "⩥": [T: "notación Z, rango antirrestrición"] # 0x2a65 (en: 'z notation range antirestriction', google: 'z rango de notación antirestricción') + - "⩦": [T: "signo igual con punto abajo"] # 0x2a66 (en: 'equals sign with dot below') + - "⩧": [T: "idéntico a con punto arriba"] # 0x2a67 (en: 'identical with dot above', google: 'idéntico al punto arriba') + - "⩨": [T: "triple barra horizontal con doble trazo vertical"] # 0x2a68 (en: 'triple horizontal bar with double vertical stroke', google: 'barra horizontal triple con doble carrera vertical') + - "⩩": [T: "triple barra horizontal con triple trazo vertical"] # 0x2a69 (en: 'triple horizontal bar with triple vertical stroke', google: 'barra horizontal triple con trazo vertical triple') + - "⩪": [T: "tilde con punto encima"] # 0x2a6a (en: 'tilde operator with dot above') + - "⩫": [T: "tilde con puntos ascendentes"] # 0x2a6b (en: 'tilde operator with rising dots', google: 'operador de tilde con puntos ascendentes') + - "⩬": [T: "similar menos similar"] # 0x2a6c (en: 'similar minus similar', google: 'similar menos similar') + - "⩭": [T: "congruente con punto encima"] # 0x2a6d (en: 'congruent with dot above') + - "⩮": [T: "igual a con Asterisco"] # 0x2a6e (en: 'equals with asterisk', google: 'igualmente con asterisco') + - "⩯": [T: "casi igual con acento circunflejo"] # 0x2a6f (en: 'almost equal to with circumflex accent') + - "⩰": [T: "aproximadamente igual o igual a"] # 0x2a70 (en: 'approximately equal to or equal to') + - "⩱": [T: "signo igual por encima de signo más"] # 0x2a71 (en: 'equals sign above plus sign') + - "⩲": [T: "signo más por encima de signo igual"] # 0x2a72 (en: 'plus sign above equals sign') + - "⩳": [T: "signo igual por encima de tilde"] # 0x2a73 (en: 'equals sign above tilde operator') + - "⩴": [T: "signo igual con dos puntos"] # 0x2a74 (en: 'double colon equal') + - "⩵": [T: "doble signo igual"] # 0x2a75 (en: 'two consecutive equals signs') + - "⩶": [T: "triple signo igual"] # 0x2a76 (en: 'three consecutive equals signs', google: 'tres signos consecutivos iguales') + - "⩷": [T: "signo igual entre dos puntos arriba y dos puntos abajo"] # 0x2a77 (en: 'equals sign with two dots above and two dots below') + - "⩸": [T: "equivalente a con cuatro puntos en la parte superior"] # 0x2a78 (en: 'equivalent with four dots above') + - "⩹": [T: "menor que con círculo dentro"] # 0x2a79 (en: 'less than with circle inside') + - "⩺": [T: "mayor que con círculo dentro"] # 0x2a7a (en: 'greater than with circle inside') + - "⩻": [T: "menor que con signo de interrogación en la parte superior"] # 0x2a7b (en: 'less than with question mark above') + - "⩼": [T: "mayor que con signo de interrogación en la parte superior"] # 0x2a7c (en: 'greater than with question mark above') + - "⩽": [T: "menor que o signo igual inclinado"] # 0x2a7d (en: 'less than or slanted equal to') + - "⩾": [T: "mayor que o signo igual inclinado"] # 0x2a7e (en: 'greater than or slanted equal to') + - "⩿": [T: "menor que o signo igual inclinado con punto en el interior"] # 0x2a7f (en: 'less than or slanted equal to with dot inside') + - "⪀": [T: "mayor que o signo igual inclinado con punto en el interior"] # 0x2a80 (en: 'greater than or slanted equal to with dot inside') + - "⪁": [T: "menor que o signo igual inclinado con punto en la parte superior"] # 0x2a81 (en: 'less than or slanted equal to with dot above') + - "⪂": [T: "mayor que o signo igual con punto en la parte superior"] # 0x2a82 (en: 'greater than or slanted equal to with dot above') + - "⪃": [T: "menor que o signo igual inclinado con punto superior a la derecha"] # 0x2a83 (en: 'less than or slanted equal to with dot above right') + - "⪄": [ T: "mayor que con signo igual inclinado con punto superior hacia la izquierda"] # 0x2a84 (en: 'greater than or slanted equal to with dot above left') + - "⪅": [T: "menor que o aproximado"] # 0x2a85 (en: 'less than or approximate', google: 'menos o aproximado') + - "⪆": [T: "mayor que o aproximado"] # 0x2a86 (en: 'greater than or approximate', google: 'mayor o aproximado') + - "⪇": [T: "menor que y una línea no es igual a"] # 0x2a87 (en: 'less than and single line not equal to', google: 'menos que y una sola línea no es igual a') + - "⪈": [T: "mayor que y una línea no es igual a"] # 0x2a88 (en: 'greater than and single line not equal to', google: 'mayor que y una sola línea no es igual a') + - "⪉": [T: "menor que y no aproximado a"] # 0x2a89 (en: 'less than and not approximate') + - "⪊": [T: "mayor que y no aproximado a"] # 0x2a8a (en: 'greater than and not approximate') + - "⪋": [T: "menor que por encima de línea doble, signo iguaal por encima de mayor que"] # 0x2a8b (en: 'less than above double line equal above greater than', google: 'menos que por encima de la doble línea igual por encima de más que') + - "⪌": [T: "mayor que por encima de doble línea, signo igual por encima de menor que"] # 0x2a8c (en: 'greater than above double line equal above less than', google: 'mayor que por encima de la doble línea igual por encima de menos que') + - "⪍": [T: "menor que por encima de similar o igual a"] # 0x2a8d (en: 'less than above similar or equal') + - "⪎": [T: "mayor que por encima de similar o igual a"] # 0x2a8e (en: 'greater than above similar or equal') + - "⪏": [T: "menor que por encima de similar por encima de mayor que"] # 0x2a8f (en: 'less than above similar above greater than') + - "⪐": [T: "mayor que por encima de similar por encima de menor que"] # 0x2a90 (en: 'greater than above similar above less than') + - "⪑": [T: "menor que por encima de mayor que por encima de doble línea igual"] # 0x2a91 (en: 'less than above greater than above double line equal') + - "⪒": [T: "mayor que por encima de menor que por encima de doble línea igual"] # 0x2a92 (en: 'greater than above less than above double line equal') + - "⪓": [T: "menor que por encima de signo igual inclinado por encima de mayor que por encima de signo igual inclinado"] # 0x2a93 (en: 'less than above slanted equal above greater than above slanted equal') + - "⪔": [T: "mayor que por encima de signo igual inclinado por encima de menor que por encima de signo igual inclinado"] # 0x2a94 (en: 'greater than above slanted equal above less than above slanted equal') + - "⪕": [T: "igual o menor que"] # 0x2a95 (en: 'slanted equal to or less than', google: 'inclinado igual o menos de') + - "⪖": [T: "igual o mayor que"] # 0x2a96 (en: 'slanted equal to or greater than') + - "⪗": [T: "igual o menor que con punto en el interior"] # 0x2a97 (en: 'slanted equal to or less than with dot inside') + - "⪘": [T: "igual o mayor que con punto en el interior"] # 0x2a98 (en: 'slanted equal to or greater than with dot inside') + - "⪙": [T: "doble línea igual a o menor que"] # 0x2a99 (en: 'double line equal to or less than') + - "⪚": [T: "doble línea igual a o mayor que"] # 0x2a9a (en: 'double line equal to or greater than') + - "⪛": [T: "doble línea inclinada igual a o menor que"] # 0x2a9b (en: 'double line slanted equal to or less than', google: 'doble línea inclinada igual o menos de') + - "⪜": [T: "doble línea inclinada igual a o mayor que"] # 0x2a9c (en: 'double line slanted equal to or greater than', google: 'línea doble inclinada igual o mayor que') + - "⪝": [T: "similar a o menor que"] # 0x2a9d (en: 'similar or less than') + - "⪞": [T: "similar a o mayor que"] # 0x2a9e (en: 'similar or greater than') + - "⪟": [T: "similar a por encima de menor que por encima de signo igual"] # 0x2a9f (en: 'similar above less than above equals sign') + - "⪠": [T: "similar a por encima de mayor que por encima de signo egual"] # 0x2aa0 (en: 'similar above greater than above equals sign') + - "⪡": [T: "mucho menor que"] # 0x2aa1 (en: 'double nested less than') + - "⪢": [T: "mucho mayor que"] # 0x2aa2 (en: 'double nested greater than') + - "⪣": [T: "signo menor que doblemente anidado con barra inferior"] # 0x2aa3 (en: 'double nested less than with underbar', google: 'doble anidado menos que con debajo de la barra') + - "⪤": [T: "signo mayor que superpuesto a signo menor que"] # 0x2aa4 (en: 'greater than overlapping less than') + - "⪥": [T: "signo mayor que al lado de signo enor que"] # 0x2aa5 (en: 'greater than beside less than') + - "⪦": [T: "menor que cerrado con curva"] # 0x2aa6 (en: 'less than closed by curve') + - "⪧": [T: "mayor que cerrado con curva"] # 0x2aa7 (en: 'greater than closed by curve') + - "⪨": [T: "signo menor que cerrado con curva por encima de signo igual inclinadoa"] # 0x2aa8 (en: 'less than closed by curve above slanted equal') + - "⪩": [T: "signo mayor que cerrado con curva por encima de signo igual inclinado"] # 0x2aa9 (en: 'greater than closed by curve above slanted equal') + - "⪪": [T: "más pequeño que"] # 0x2aaa (en: 'smaller than') + - "⪫": [T: "más grande que"] # 0x2aab (en: 'larger than') + - "⪬": [T: "más pequeño que o igual a"] # 0x2aac (en: 'smaller than or equal to') + - "⪭": [T: "más grande que o igual a"] # 0x2aad (en: 'larger than or equal to') + - "⪮": [T: "signo igual abultado en la parte superior"] # 0x2aae (en: 'equals sign with bumpy above') + - "⪯": [T: "precede o es igual a"] # 0x2aaf (en: 'precedes above single line equals sign') + - "⪰": [T: "sucede o es igual a"] # 0x2ab0 (en: 'succeeds above single line equals sign', google: 'tiene éxito por encima de la línea única es igual al signo') + - "⪱": [T: "precede no es igual a"] # 0x2ab1 (en: 'precedes above single line not equal to', google: 'precede por encima de una sola línea no es igual a') + - "⪲": [T: "sucede no es igual a"] # 0x2ab2 (en: 'succeeds above single line not equal to', google: 'tiene éxito por encima de una sola línea no es igual a') + - "⪳": [T: "precede por encima del signo igual"] # 0x2ab3 (en: 'precedes above equals sign', google: 'precede arriba es igual al signo') + - "⪴": [T: "sucede por encima del signo igual"] # 0x2ab4 (en: 'succeeds above equals sign', google: 'tiene éxito arriba es igual al signo') + - "⪵": [T: "precede por encima de no es igual a"] # 0x2ab5 (en: 'precedes above not equal to') + - "⪶": [T: "sucede por encima de no es igual a"] # 0x2ab6 (en: 'succeeds above not equal to') + - "⪷": [T: "precede por encima de casi igual a"] # 0x2ab7 (en: 'precedes above almost equal to') + - "⪸": [T: "sucede por encima de casi igual a"] # 0x2ab8 (en: 'succeeds above almost equal to') + - "⪹": [T: "precede por encima de no es casi igual a"] # 0x2ab9 (en: 'precedes above not almost equal to', google: 'precede arriba no casi igual a') + - "⪺": [T: "sucede por encima de casi igual a"] # 0x2aba (en: 'succeeds above not almost equal to', google: 'tiene éxito arriba no casi igual a') + - "⪻": [T: "es muy anterior a"] # 0x2abb (en: 'double precedes') + - "⪼": [T: "sigue mucho después"] # 0x2abc (en: 'double succeeds') + - "⪽": [T: "subconjunto con punto"] # 0x2abd (en: 'subset with dot') + - "⪾": [T: "superconjunto con punto"] # 0x2abe (en: 'superset with dot') + - "⪿": [T: "subconjunto con signo más debajo de"] # 0x2abf (en: 'subset with plus sign below') + - "⫁": [T: "subconjunto con signo de multiplicación debajo de"] # 0x2ac1 (en: 'subset with multiplication sign below') + - "⫀": [T: "superconjunto con signo más debajo de"] # 0x2ac0 (en: 'superset with plus sign below') + - "⫂": [T: "superconjunto con signo de multiplicación debajo de"] # 0x2ac2 (en: 'superset with multiplication sign below') + - "⫃": [T: "incluido con punto o es igual a"] # 0x2ac3 (en: 'subset of or equal to with dot above') + - "⫄": [T: "superconjunto de o igual a con punto encima"] # 0x2ac4 (en: 'superset of or equal to with dot above') + - "⫅": [T: "subconjunto de signo igual encima de"] # 0x2ac5 (en: 'subset of above equals sign', google: 'el subconjunto de arriba es igual al signo') + - "⫆": [T: "superconjunto de signo igual encima de"] # 0x2ac6 (en: 'superset of above equals sign', google: 'el superconjunto de arriba es igual al signo') + - "⫇": [T: "subconjunto por encima de tilde"] # 0x2ac7 (en: 'subset of above tilde operator') + - "⫈": [T: "superconjunto por encima de"] # 0x2ac8 (en: 'superset of above tilde operator') + - "⫉": [T: "subconjunto por encima de signo casi igual a"] # 0x2ac9 (en: 'subset of above almost equal to', google: 'subconjunto de arriba casi igual a') + - "⫊": [T: "superconjunto por encima de casi igual a"] # 0x2aca (en: 'superset of above almost equal to', google: 'superset de arriba casi igual a') + - "⫋": [T: "subconjunto por encima de signo no es igual a"] # 0x2acb (en: 'subset above not equal to', google: 'subconjunto arriba no igual a') + - "⫌": [T: "superconjunto por encima de signo no es igual a "] # 0x2acc (en: 'superset of above not equal to', google: 'superset de arriba no es igual a') + - "⫍": [T: "operador de caja abierta cuadrada a la izquierda"] # 0x2acd (en: 'square left open box operator', google: 'operador de caja abierta cuadrada izquierda') + - "⫎": [T: "operador de caja abierta cuadrada a la derecha"] # 0x2ace (en: 'square right open box operator', google: 'operador de caja abierta cuadrada derecha') + - "⫏": [T: "subconjunto cerrado"] # 0x2acf (en: 'closed subset') + - "⫐": [T: "superconjunto cerrado"] # 0x2ad0 (en: 'closed superset') + - "⫑": [T: "subconjunto cerrado o es igual a"] # 0x2ad1 (en: 'closed subset or equal to') + - "⫒": [T: "superconjunto cerrado o es igual a"] # 0x2ad2 (en: 'closed superset or equal to') + - "⫓": [T: "subconjunto por encima de superconjunto"] # 0x2ad3 (en: 'subset above superset') + - "⫔": [T: "superconjunto por encima de subconjunto"] # 0x2ad4 (en: 'superset above subset') + - "⫕": [T: "subconjunto por encima de subconjunto"] # 0x2ad5 (en: 'subset above subset') + - "⫖": [T: "superconjunto por encima de superconjunto"] # 0x2ad6 (en: 'superset above superset') + - "⫗": [T: "superconjunto al lado de subconjunto"] # 0x2ad7 (en: 'superset beside subset') + - "⫘": [T: "superconjunto al lado de y unido por barra discontinua a subconjunto"] # 0x2ad8 (en: 'superset beside and joined by dash with subset') + - "⫙": [T: "grupo de apertura hacia arriba y hacia abajo"] # 0x2ad9 (en: 'element of opening downwards') + - "⫚": [T: "bifurcación"] # 0x2ada + - "⫛": [T: "intersección transversal"] # 0x2adb + - "⫝̸": [T: "bifurcación"] # 0x2adc (en: 'forking') + - "⫝": [T: "sin bifurcación"] # 0x2add (google: 'no efectivo') + - "⫞": [T: "tack corto a la izquierda"] # 0x2ade (en: 'short left tack', google: 'tachuela a la izquierda corta') + - "⫟": [T: "tack corto hacia abajo"] # 0x2adf (en: 'short down tack', google: 'tachuela corta') + - "⫠": [T: "tack corto hacia arriba"] # 0x2ae0 (en: 'short up tack', google: 'tachuela corta') + - "⫡": [T: "perpendicular a s"] # 0x2ae1 (en: 'perpendicular with s') + - "⫢": [T: "barra vertical con triple torniquete a la derecha"] # 0x2ae2 (en: 'vertical bar triple right turnstile', google: 'barra vertical triple turnstile a la derecha') + - "⫣": [T: "doble barra vertical con torniquete a la izquierda"] # 0x2ae3 (en: 'double vertical bar left turnstile', google: 'doble barra vertical a la izquierda el torniquete') + - "⫤": [T: "barra vertical con doble torniquete a la izquierda"] # 0x2ae4 (en: 'vertical bar double left turnstile') + - "⫥": [T: "doble barra vertical doble torniquete a la izquierda"] # 0x2ae5 (en: 'double vertical bar double left turnstile', google: 'doble barra vertical de doble tornillo a la izquierda') + - "⫦": [T: "larga barra discontinua partiendo de doble barra vertical izquierda"] # 0x2ae6 + - "⫧": [T: "tack corto con barra superior"] # 0x2ae7 + - "⫨": [T: "tack corto arriba con barra inferior"] # 0x2ae8 (en: 'short up tack with underbar') + - "⫩": [T: "tack corto arriba sobre tack corto abajo"] # 0x2ae9 + - "⫪": [T: "doble tack hacia abajo"] # 0x2aea (en: 'double down tack', google: 'duplicar la tachuela') + - "⫫": [T: "doble tack hacia arriba"] # 0x2aeb + - "⫬": [T: "doble trazo sin signo"] # 0x2aec + - "⫭": [T: "doble trazo invertido sin signo"] # 0x2aed + - "⫮": [T: "no divide con barra invertida discontinua de negación"] # 0x2aee + - "⫯": [T: "línea vertical con círculo encima"] # 0x2aef (en: 'vertical line with circle above') + - "⫰": [T: "línea vertical con círculo abajo"] # 0x2af0 (en: 'vertical line with circle below') + - "⫱": [T: "tack hacia abajo con círculo abajo"] # 0x2af1 + - "⫲": [T: "paralela con trazo horizontal"] # 0x2af2 (en: 'parallel with horizontal stroke') + - "⫳": [T: "paralela con tilde"] # 0x2af3 (en: 'parallel with tilde operator') + - "⫴": [T: "relación binaria de barra vertical triple"] # 0x2af4 (en: 'triple vertical bar binary relation', google: 'relación binaria de la barra vertical triple') + - "⫵": [T: "barra vertical triple con trazo horizontal"] # 0x2af5 (en: 'triple vertical bar with horizontal stroke', google: 'barra vertical triple con carrera horizontal') + - "⫶": [T: "operador TripleC olon"] # 0x2af6 (en: 'triple colon operator', google: 'operador de triple colon') + - "⫷": [T: "signo menor que triplemente anidado"] # 0x2af7 (en: 'triple nested less than', google: 'triple anidado menos que') + - "⫸": [T: "signo mayor que triplemente anidado"] # 0x2af8 (en: 'triple nested greater than', google: 'triple anidado más grande que') + - "⫹": [T: "doble línea inclinada menor o igual a"] # 0x2af9 (en: 'double line slanted less than or equal to', google: 'doble línea inclinada menos o igual a') + - "⫺": [T: "doble línea inclinada mayor o igual a"] # 0x2afa (en: 'double line slanted greater than or equal to', google: 'línea doble inclinada mayor o igual a') + - "⫻": [T: "relación Binaria Triple Sólida"] # 0x2afb (en: 'triple solidus binary relation', google: 'triple relación binaria de solidus') + - "⫼": [T: "operador de barra vertical triple y grande"] # 0x2afc (en: 'large triple vertical bar operator', google: 'gran operador de barra vertical triple') + - "⫽": [T: "operador Doble Sólido"] # 0x2afd (en: 'double solidus operator', google: 'operador doble solidus') + - "⫾": [T: "barra vertical blanca"] # 0x2afe (en: 'white vertical bar') + - "⫿": [T: "barra vertical blanca N-Ary"] # 0x2aff (en: 'white vertical bar', google: 'barra vertical blanca') + - "⬀": [T: "flecha blanca apuntando al nordeste"] # 0x2b00 (en: 'north east white arrow', google: 'noreste de la flecha blanca') + - "⬁": [T: "flecha blanca apuntando a noroeste"] # 0x2b01 (en: 'north west white arrow', google: 'noroeste de flecha blanca') + - "⬂": [T: "flecha blanca apuntando al sudeste"] # 0x2b02 (en: 'south east white arrow', google: 'south east white arrow') + - "⬃": [T: "flecha blanca apuntando al sudoeste"] # 0x2b03 (en: 'south west white arrow', google: 'south west white arrow') + - "⬄": [T: "flecha blanca hacia izquierda y derecha"] # 0x2b04 (en: 'left right white arrow', google: 'flecha blanca derecha izquierda') + - "⬅": [T: "flecha negra hacia la izquierda"] # 0x2b05 (en: 'leftwards black arrow') + - "⬆": [T: "flecha negra hacia arriba"] # 0x2b06 (en: 'upwards black arrow', google: 'arrow negro hacia arriba') + - "⬇": [T: "flecha negra hacia abajo"] # 0x2b07 (en: 'downwards black arrow', google: 'arrow negra hacia abajo') + - "⬈": [T: "flecha negra apuntando al nordeste"] # 0x2b08 (en: 'north east black arrow', google: 'north east black arrow') + - "⬉": [T: "flecha negra apuntando al noroeste"] # 0x2b09 (en: 'north west black arrow', google: 'noroeste de flecha negra') + - "⬊": [T: "flecha negra apuntando al sudeste"] # 0x2b0a (en: 'south east black arrow', google: 'south east black arrow') + - "⬋": [T: "flecha negra apuntando al sudoeste"] # 0x2b0b (en: 'south west black arrow', google: 'south west arrow negro') + - "⬌": [T: "flecha negra hacia izquierda y derecha"] # 0x2b0c (en: 'left right black arrow', google: 'flecha negra derecha izquierda') + - "⬍": [T: "flecha negra hacia arriba y hacia abajo"] # 0x2b0d (en: 'up down black arrow', google: 'arrow black arrow') + - "⬎": [T: "flecha hacia la derecha con la punta hacia abajo"] # 0x2b0e (en: 'rightwards arrow with tip downwards') + - "⬏": [T: "flecha hacia la derecha con la punta hacia arriba"] # 0x2b0f (en: 'rightwards arrow with tip upwards') + - "⬐": [T: "flecha hacia la izquierda con la punta hacia abajo"] # 0x2b10 (en: 'leftwards arrow with tip downwards', google: 'flecha hacia la izquierda con punta hacia abajo') + - "⬑": [T: "flecha hacia la izquierda con la punta hacia arriba"] # 0x2b11 (en: 'leftwards arrow with tip upwards', google: 'flecha hacia la izquierda con punta hacia arriba') + - "⬒": [T: "cuadrado con mitad superior negra"] # 0x2b12 (en: 'square with top half black', google: 'cuadrado con la mitad superior negra') + - "⬓": [T: "cuadrado con mitad inferior negra"] # 0x2b13 (en: 'square with bottom half black', google: 'cuadrado con la mitad inferior negra') + - "⬔": [T: "cuadrado con mitad derecha superior diagonal negra"] # 0x2b14 (en: 'square with upper right diagonal half black', google: 'cuadrado con diagonal superior derecha de la parte superior negra') + - "⬕": [T: "cuadrado con mitad izquierda inferior diagonal negra"] # 0x2b15 (en: 'square with lower left diagonal half black', google: 'cuadrado con diagonal inferior izquierda mitad negra') + - "⬖": [T: "rombo con Mitad Izquierda Negro"] # 0x2b16 (en: 'diamond with left half black', google: 'diamante con la mitad de la izquierda') + - "⬗": [T: "rombo con mitad derecha negra"] # 0x2b17 (en: 'diamond with right half black', google: 'diamante con la mitad derecha negra') + - "⬘": [T: "rombo con mitad superior negra"] # 0x2b18 (en: 'diamond with top half black', google: 'diamante con mitad superior negro') + - "⬙": [T: "rojmbo con mitad inferior negra"] # 0x2b19 (en: 'diamond with bottom half black', google: 'diamante con la mitad de negro') + - "⬚": [T: "cuadrado punteado"] # 0x2b1a (en: 'box', google: 'caja') + - "⬛": [T: "cuadrado grande negro"] # 0x2b1b (en: 'black large square') + - "⬜": [T: "cuadrado grande blanco"] # 0x2b1c (en: 'white large square', google: 'cuadrado grande blanco') + - "⬝": [T: "cuadrado muy pequeño negro"] # 0x2b1d (en: 'black very small square', google: 'negro muy pequeño cuadrado') + - "⬞": [T: "cuadrado muy pequeño blanco"] # 0x2b1e (en: 'white very small square', google: 'blanco muy pequeño cuadrado') + - "⬟": [T: "pentágono blanco"] # 0x2b20 (en: 'white pentagon') + - "⬡": [T: "hexágono blanco"] # 0x2b21 (en: 'white hexagon') + - "⬢": [T: "hexágono negro"] # 0x2b22 (en: 'black hexagon') + - "⬣": [T: "hexágono hegro horizontal"] # 0x2b23 (en: 'horizontal black hexagon', google: 'hexagon negro horizontal') + - "⬤": [T: "circulo grande negro"] # 0x2b24 (en: 'black large circle', google: 'círculo negro negro') + - "⬥": [T: "rombo Mediano Negro"] # 0x2b25 (en: 'black medium diamond', google: 'diamante medio negro') + - "⬦": [T: "rombo mediano blanco"] # 0x2b26 (en: 'white medium diamond', google: 'diamante medio blanco') + - "⬧": [T: "rombo Mediano Negro"] # 0x2b27 (en: 'black medium lozenge', google: 'rombina media negra') + - "⬨": [T: "rombo mediano blanco"] # 0x2b28 (en: 'white medium lozenge', google: 'rombita media blanca') + - "⬩": [T: "rombo pequeño negro"] # 0x2b29 (en: 'black small diamond', google: 'diamante pequeño negro') + - "⬪": [T: "rombo pequeño negro"] # 0x2b2a (en: 'black small lozenge', google: 'pequeña barra negra') + - "⬫": [T: "rombo pequeño blanco"] # 0x2b2b (en: 'white small lozenge', google: 'pequeña barra blanca') + - "⬬": [T: "elipse horizontal negra"] # 0x2b2c (en: 'black horizontal ellipse') + - "⬭": [T: "elipse horizontal blanca"] # 0x2b2d (en: 'white horizontal ellipse') + - "⬮": [T: "elipse Vertical Negra"] # 0x2b2e (en: 'black vertical ellipse', google: 'elipse vertical negro') + - "⬯": [T: "elipse Vertical Blanca"] # 0x2b2f (en: 'white vertical ellipse', google: 'elipse vertical blanco') + - "⬰": [T: "flecha izquierda con círculo pequeño"] # 0x2b30 (en: 'left arrow with small circle') + - "⬱": [T: "tres flechas a la izquierda"] # 0x2b31 (en: 'three leftwards arrows', google: 'tres flechas de izquierda') + - "⬲": [T: "flecha izquierda con signo más en el interior de uncírculo"] # 0x2b32 (en: 'left arrow with circled plus', google: 'flecha izquierda con círculos plus') + - "⬳": [T: "flecha serpenteante larga hacia la izquierda"] # 0x2b33 (en: 'long leftwards squiggle arrow', google: 'larga flecha de tirantes de la izquierda') + - "⬴": [T: "flecha de dos cabezas hacia la izquierda con trazo vertical"] # 0x2b34 (en: 'leftwards two headed arrow with vertical stroke', google: 'a la izquierda, dos flechas con carrera vertical') + - "⬵": [T: "flecha de dos cabezas hacia la izquierda con doble trazo vertical"] # 0x2b35 (en: 'leftwards two headed arrow with double vertical stroke', google: 'a la izquierda, dos flechas con cabeza de carrera vertical doble') + - "⬶": [T: "flecha de dos cabezas hacia la izquierda partiendo de barra"] # 0x2b36 (en: 'leftwards two headed arrow from bar', google: 'a la izquierda, dos flechas de la cabeza del bar') + - "⬷": [T: "flecha de dos cabezas hacia la izquierda con triple barra discontinua"] # 0x2b37 (en: 'leftwards two headed triple dash arrow', google: 'a la izquierda, dos flechas del triple tablero') + - "⬸": [T: "flecha hacia la izquierda con trazo punteado"] # 0x2b38 (en: 'leftwards arrow with dotted stem') + - "⬹": [T: "flecha hacia la izquierda con cola con trazo vertical"] # 0x2b39 (en: 'leftwards arrow with tail with vertical stroke') + - "⬺": [T: "flecha hacia la izquierda con cola con doble trazo vertical"] # 0x2b3a (en: 'leftwards arrow with tail with double vertical stroke', google: 'flecha hacia la izquierda con cola con doble carrera vertical') + - "⬻": [T: "flecha de dos cabezas hacia la izquierda con cola"] # 0x2b3b (en: 'leftwards two headed arrow with tail', google: 'a la izquierda, dos flechas con la cola') + - "⬼": [T: "flecha de dos cabezas hacia la izquierda con cola con trazo vertical"] # 0x2b3c (en: 'leftwards two headed arrow with tail with vertical stroke', google: 'a la izquierda, dos flechas con cola con trazo vertical') + - "⬽": [T: "flecha de dos cabezas hacia la izquierda con cola con doble trazo vertical"] # 0x2b3d (en: 'leftwards two headed arrow with tail with double vertical stroke', google: 'a la izquierda, dos flechas con cola con trazo vertical doble') + - "⬾": [T: "flecha hacia la izquierda a través de X"] # 0x2b3e (en: 'leftwards arrow through x', google: 'flecha hacia la izquierda a través de x') + - "⬿": [T: "flecha ondulada apuntando directamente a la izquierda"] # 0x2b3f (en: 'wave arrow pointing directly left', google: 'flecha de onda apuntando directamente a la izquierda') + - "⭀": [T: "signo igual por encima de flecha hacia la izquierda"] # 0x2b40 (en: 'equals sign above leftwards arrow', google: 'igual de la señal de la flecha hacia la izquierda') + - "⭁": [T: "operador de tilde inverso sobre la flecha hacia la izquierda"] # 0x2b41 (en: 'reverse tilde operator above leftwards arrow', google: 'reverse del operador de tilde sobre la flecha de la izquierda') + - "⭂": [T: "flecha hacia la izquierda sobre el reverso de signo casi igual a"] # 0x2b42 (en: 'leftwards arrow above reverse almost equal to') + - "⭃": [T: "flecha hacia la derecha a través de signomayor que"] # 0x2b43 (en: 'rightwards arrow through greater than', google: 'flecha hacia la derecha a través de mayor que') + - "⭄": [T: "flecha hacia la derecha a través de superconjunto"] # 0x2b44 (en: 'rightwards arrow through superset', google: 'arrow hacia la derecha a través del superconjunto') + - "⭅": [T: "flecha cuádruple hacia la izquierda"] # 0x2b45 (en: 'leftwards quadruple arrow', google: 'flecha quadruple hacia la izquierda') + - "⭆": [T: "flecha cuádruple hacia la derecha"] # 0x2b46 (en: 'rightwards quadruple arrow', google: 'arrow cuádruple hacia la derecha') + - "⭇": [T: "operador de tilde inverso sobre flecha hacia la derecha"] # 0x2b47 (en: 'reverse tilde operator above rightwards arrow', google: 'reverse el operador de tilde sobre la flecha derecha hacia la derecha') + - "⭈": [T: "flecha hacia la derecha sobre el reverso de signo casi igual a"] # 0x2b48 (en: 'rightwards arrow above reverse almost equal to') + - "⭉": [T: "operador de tilde sobre flecha hacia la izquierda"] # 0x2b49 (en: 'tilde operator above leftwards arrow', google: 'operador de tilde sobre la flecha de la izquierda') + - "⭊": [T: "flecha hacia la izquierda por encima de signo casi igual a"] # 0x2b4a (en: 'leftwards arrow above almost equal to', google: 'flecha hacia la izquierda arriba casi igual a') + - "⭋": [T: "flecha hacia la izquierda sobre operador de tilde inverso"] # 0x2b4b (en: 'leftwards arrow above reverse tilde operator') + - "⭌": [T: "flecha hacia la derecha sobre operador de tilde inverso"] # 0x2b4c (en: 'rightwards arrow above reverse tilde operator') + - "⭐": [T: "estrella media vacía"] # 0x2b50 (en: 'white medium star') + - "⭑": [T: "estrella pequeña llena"] # 0x2b51 (en: 'black small star') + - "⭒": [T: "estrella pequeña vacía"] # 0x2b52 (en: 'white small star') + - "⭓": [T: "pentágono negro apuntando hacia la derecha"] # 0x2b53 (en: 'black right pointing pentagon', google: 'black derecha apuntando al pentágono') + - "⭔": [T: "pentágono blanco apuntando hacia la derecha"] # 0x2b54 (en: 'white right pointing pentagon', google: 'pentágono apuntando a la derecha blanca') + - "⭕": [T: "círculo grueso grande"] # 0x2b55 (en: 'heavy large circle', google: 'círculo grande y pesado') + - "⭖": [T: "óvalo grueso con óvalo en el interior"] # 0x2b56 (en: 'heavy oval with oval inside', google: 'ovalo pesado con óvalo en el interior') + - "⭗": [T: "círculo grueso con círculo en el interior"] # 0x2b57 (en: 'heavy circle with circle inside', google: 'círculo pesado con círculo interior') + - "⭘": [T: "círculo grueso"] # 0x2b58 (en: 'heavy circle') + - "⭙": [T: "saltire en círculo grueso"] # 0x2b59 (en: 'heavy circled saltire', google: 'saltire con círculo pesado') + - "⸀": [T: "marcador de sustitución en ángulo recto"] # 0x2e00 (en: 'right angle substitution marker', google translation) + - "⸁": [T: "marcador de sustitución punteado en ángulo recto"] # 0x2e01 (en: 'right angle dotted substitution marker', google translation) + - "⸂": [T: "soporte de sustitución izquierdo"] # 0x2e02 (en: 'left substitution bracket', google translation) + - "⸃": [T: "soporte de sustitución derecho"] # 0x2e03 (en: 'right substitution bracket', google translation) + - "⸄": [T: "soporte de sustitución punteado izquierdo"] # 0x2e04 (en: 'left dotted substitution bracket', google translation) + - "⸅": [T: "soporte de sustitución punteado derecho"] # 0x2e05 (en: 'right dotted substitution bracket', google translation) + - "⸆": [T: "marcador de interpolación elevado"] # 0x2e06 (en: 'raised interpolation marker', google translation) + - "⸇": [T: "marcador de interpolación punteado elevado"] # 0x2e07 (en: 'raised dotted interpolation marker', google translation) + - "⸈": [T: "marcador de marcador de transposición punteado"] # 0x2e08 (en: 'dotted transposition marker marker', google translation) + - "⸉": [T: "soporte de transposición izquierdo"] # 0x2e09 (en: 'left transposition bracket', google translation) + - "⸊": [T: "soporte de transposición derecho"] # 0x2e0a (en: 'right transposition bracket', google translation) + - "⸋": [T: "cuadrado elevado"] # 0x2e0b (en: 'raised square', google translation) + - "⸌": [T: "soporte de omisión izquierdo elevado"] # 0x2e0c (en: 'left raised omission bracket', google translation) + - "⸍": [T: "soporte de omisión derecho elevado"] # 0x2e0d (en: 'right raised omission bracket', google translation) + - "⸎": [T: "editorial coronis"] # 0x2e0e (google translation) + - "⸏": [T: "párrafos"] # 0x2e0f (en: 'paragraphos', google translation) + - "⸐": [T: "párrafos bifurcados"] # 0x2e10 (en: 'forked paragraphos', google translation) + - "⸑": [T: "párrafos invertidos bifurcados"] # 0x2e11 (en: 'reversed forked paragraphos', google translation) + - "⸒": [T: "hipodiastole"] # 0x2e12 (en: 'hypodiastole', google translation) + - "⸓": [T: "óbelos punteados"] # 0x2e13 (en: 'dotted obelos', google translation) + - "⸔": [T: "áncora hacia abajo"] # 0x2e14 (en: 'downwards ancora', google translation) + - "⸕": [T: "áncora hacia arriba"] # 0x2e15 (en: 'upwards ancora', google translation) + - "⸖": [T: "ángulo punteado apuntando hacia la derecha"] # 0x2e16 (en: 'dotted right pointing angle', google translation) + - "⸗": [T: "doble guión oblicuo"] # 0x2e17 (en: 'double oblique hyphen', google translation) + - "⸘": [T: "interrobang invertido"] # 0x2e18 (en: 'inverted interrobang', google translation) + - "⸙": [T: "rama de palma"] # 0x2e19 (en: 'palm branch', google translation) + - "⸚": [T: "guión con diéresis"] # 0x2e1a (en: 'hyphen with diaeresis', google translation) + - "⸛": [T: "tilde con anillo arriba"] # 0x2e1b (en: 'tilde with ring above', google translation) + - "⸜": [T: "soporte de paráfrasis bajo izquierdo"] # 0x2e1c (en: 'left low paraphrase bracket', google translation) + - "⸝": [T: "soporte de paráfrasis bajo derecho"] # 0x2e1d (en: 'right low paraphrase bracket', google translation) + - "⸞": [T: "tilde con punto arriba"] # 0x2e1e (en: 'tilde with dot above', google translation) + - "⸟": [T: "tilde con punto abajo"] # 0x2e1f (en: 'tilde with dot below', google translation) + - "⸠": [T: "barra vertical izquierda con pluma"] # 0x2e20 (en: 'left vertical bar with quill', google translation) + - "⸡": [T: "barra vertical derecha con pluma"] # 0x2e21 (en: 'right vertical bar with quill', google translation) + - "⸢": [T: "medio soporte superior izquierdo"] # 0x2e22 (en: 'top left half bracket', google: 'medio soporte superior izquierdo') + - "⸣": [T: "medio soporte superior derecho"] # 0x2e23 (en: 'top right half bracket', google: 'arroja superior derecha') + - "⸤": [T: "abrazadera inferior izquierda"] # 0x2e24 (en: 'bottom left half bracket', google: 'medio soporte inferior izquierdo') + - "⸥": [T: "medio soporte inferior derecho"] # 0x2e25 (en: 'bottom right half bracket') + - "⸦": [T: "soporte U lateral izquierdo"] # 0x2e26 (en: 'left sideways u bracket', google: 'izquierda lateral u soporte') + - "⸧": [T: "soporte U lateral derecho"] # 0x2e27 (en: 'right sideways u bracket', google: 'right sideways u soporte') + - "⸨": [T: "doble paréntesis izquierdo"] # 0x2e28 (en: 'left double parentheses', google: 'dejó doble paréntesis de tesas') + - "⸩": [T: "doble paréntesis derecho"] # 0x2e29 (en: 'right double parentheses', google: 'doble paréntesis derecha') + - "⸪": [T: "dos puntos sobre un punto de puntuación"] # 0x2e2a (en: 'two dots over one dot punctuation', google translation) + - "⸫": [T: "un punto sobre dos puntos de puntuación"] # 0x2e2b (en: 'one dot over two dots punctuation', google translation) + - "⸬": [T: "cuatro puntos de puntuación al cuadrado"] # 0x2e2c (en: 'squared four dot punctuation', google translation) + - "⸭": [T: "marca de cinco puntos"] # 0x2e2d (en: 'five dot mark', google translation) + - "⸮": [T: "signo de interrogación invertido"] # 0x2e2e (en: 'reversed question mark', google translation) + - "ⸯ": [T: "tilde vertical"] # 0x2e2f (en: 'vertical tilde', google translation) + - "⸰": [T: "punta del anillo"] # 0x2e30 (en: 'ring point', google translation) + - "⸱": [T: "punto medio separador de palabras"] # 0x2e31 (en: 'word separator middle dot', google translation) + - "⸲": [T: "convertido en coma"] # 0x2e32 (en: 'turned comma', google translation) + - "⸳": [T: "punto elevado"] # 0x2e33 (en: 'raised dot', google translation) + - "⸴": [T: "coma elevada"] # 0x2e34 (en: 'raised comma', google translation) + - "⸵": [T: "convertido en punto y coma"] # 0x2e35 (en: 'turned semicolon', google translation) + - "⸶": [T: "obelisco con portaestandarte izquierdo"] # 0x2e36 (en: 'dagger with left guard', google translation) + - "⸷": [T: "obelisco con portaestandarte derecho"] # 0x2e37 (en: 'dagger with right guard', google translation) + - "⸸": [T: "obelisco girado"] # 0x2e38 (en: 'turned dagger', google translation) + - "⸹": [T: "señal de la mitad superior de la sección"] # 0x2e39 (en: 'top half section sign', google translation) + - "⸺": [T: "dos em línea discontinua"] # 0x2e3a (en: 'two em dash', google translation) + - "⸻": [T: "tres em línea discontinua"] # 0x2e3b (en: 'three em dash', google translation) + - "〃": [T: "ídem mark"] # 0x3003 (en: 'ditto mark', google translation) + - "〈": [T: "soporte de ángulo izquierdo"] # 0x3008 (en: 'left angle bracket') + - "〉": [T: "soporte de ángulo derecho"] # 0x3009 (en: 'right angle bracket') + - "《": [T: "doble paréntesis angular izquierdo"] # 0x300a (en: 'left double angle bracket') + - "》": [T: "doble paréntesis angular derecho"] # 0x300b (en: 'right double angle bracket', MathPlayer: 'cierra paréntesis angular doble', google: 'soporte de doble ángulo derecho') + - "「": [T: "soporte de esquina izquierda"] # 0x300c (en: 'left corner bracket', google: 'soporte de esquina izquierda') + - "」": [T: "soporte de esquina derecha"] # 0x300d (en: 'right corner bracket') + - "『": [T: "soporte de esquina blanca izquierda"] # 0x300e (en: 'left white corner bracket', google: 'soporte de esquina blanca izquierda') + - "』": [T: "soporte de esquina blanca derecha"] # 0x300f (en: 'right white corner bracket', google: 'soporte de esquina blanca derecha') + - "【": [T: "soporte Lenticular negro izquierdo"] # 0x3010 (en: 'left black lenticular bracket', google: 'soporte lenticular negro izquierdo') + - "】": [T: "soporte Lenticular Negro Derecho"] # 0x3011 (en: 'right black lenticular bracket', google: 'soporte lenticular negro derecho') + - "〔": [T: "soporte de caparazón de tortuga izquierdo"] # 0x3014 + - "〕": [T: "soporte de caparazón de tortuga derecho"] # 0x3015 + - "〖": [T: "soporte lenticular blanco izquierdo"] # 0x3016 (en: 'left white lenticular bracket') + - "〗": [T: "soporte lenticular blanco derecho"] # 0x3017 (en: 'right white lenticular bracket') + - "〘": [T: "soporte de caparazón de tortuga blanco izquierdo"] # 0x3018 (en: 'left white tortoise shell bracket', google: 'soporte de carcasa de tortuga blanca izquierda') + - "〙": [T: "soporte de caparazón de tortuga blanco derecho"] # 0x3019 (en: 'right white tortoise shell bracket', google: 'soporte de carcasa de tortuga blanca derecha') + - "〚": [T: "corchete vacío izquierdo"] # 0x301a (en: 'left white square bracket') + - "〛": [T: "corchete vacío derecho"] # 0x301b (en: 'right white square bracket', MathPlayer: 'cierra corchete vacío', google: 'soporte cuadrado blanco derecho') + - "〜": [T: "línea discontinua ondulada"] # 0x301c (en: 'wave dash', google: 'ola de ola') + - "〰": [T: "línea discontinua en zigzag"] # 0x3030 (en: 'wavy dash', google: 'dash ondulado') + - "㉈": [T: "número diez rodeado por un círculo en un cuadrado negro"] # 0x3248 (en: 'circled number ten on black square', google: 'circlado número diez en black square') + - "㉉": [T: "número veinte rodeado por un círculo en un cuadrado negro"] # 0x3249 (en: 'circled number twenty on black square', google: 'número de círculo veinte en black square') + - "㉊": [T: "número treinta rodeado por un círculo en un cuadrado negro"] # 0x324a (en: 'circled number thirty on black square', google: 'número de círculo treinta en black square') + - "㉋": [T: "número cuarenta rodeado por un círculo en un cuadrado negro"] # 0x324b (en: 'circled number forty on blacks square', google: 'número de círculo cuarenta en blacks square') + - "㉌": [T: "número cincuenta rodeado por un círculo en un cuadrado negro"] # 0x324c (en: 'circled number fifty on black square', google: 'número de círculo cincuenta en black square') + - "㉍": [T: "número sesenta rodeado por un círculo en un cuadrado negro"] # 0x324d (en: 'circled number sixty on black square', google: 'número de círculos sesenta en black square') + - "㉎": [T: "número setenta rodeado por un círculo en un cuadrado negro"] # 0x324e (en: 'circled number seventy on black square', google: 'número de círculo setenta en black square') + - "㉏": [T: "número ochenta rodeado por un círculo en un cuadrado negro"] # 0x324f (en: 'circled number eighty on black square', google: 'número de círculo aty en black square') + - "㉑": [T: "número veintiuno rodeado por un círculo"] # 0x3251 (en: 'circled number twenty one', google translation) + - "㉒": [T: "número veintidós rodeado por un círculo"] # 0x3252 (en: 'circled number twenty two', google translation) + - "㉓": [T: "número veintitrés rodeado por un círculo"] # 0x3253 (en: 'circled number twenty three', google translation) + - "㉔": [T: "número veinticuatro rodeado por un círculo"] # 0x3254 (en: 'circled number twenty four', google translation) + - "㉕": [T: "número veinticinco rodeado por un círculo"] # 0x3255 (en: 'circled number twenty five', google translation) + - "㉖": [T: "número veintiséis rodeado por un círculo"] # 0x3256 (en: 'circled number twenty six', GPT-5.4 fixed translation) + - "㉗": [T: "número veintisiete rodeado por un círculo"] # 0x3257 (en: 'circled number twenty seven', google translation) + - "㉘": [T: "número veintiocho rodeado por un círculo"] # 0x3258 (en: 'circled number twenty eight', google translation) + - "㉙": [T: "número veintinueve rodeado por un círculo"] # 0x3259 (en: 'circled number twenty nine', GPT-5.4 fixed translation) + - "㉚": [T: "número treinta rodeado por un círculo"] # 0x325a (en: 'circled number thirty', google translation) + - "㉛": [T: "número treinta y uno rodeado por un círculo"] # 0x325b (en: 'circled number thirty one', GPT-5.4 fixed translation) + - "㉜": [T: "número treinta y dos rodeado por un círculo"] # 0x325c (en: 'circled number thirty two', google translation) + - "㉝": [T: "número treinta y tres rodeado por un círculo"] # 0x325d (en: 'circled number thirty three', google translation) + - "㉞": [T: "número treinta y cuatro rodeado por un círculo"] # 0x325e (en: 'circled number thirty four', google translation) + - "㉟": [T: "número treinta y cinco rodeado por un círculo"] # 0x325f (en: 'circled number thirty five', google translation) + - "㊱": [T: "número treinta y seis rodeado por un círculo"] # 0x32b1 (en: 'circled number thirty six', google translation) + - "㊲": [T: "número treinta y siete rodeado por un círculo"] # 0x32b2 (en: 'circled number thirty seven', GPT-5.4 translation) + - "㊳": [T: "número treinta y ocho rodeado por un círculo"] # 0x32b3 (en: 'circled number thirty eight', GPT-5.4 translation) + - "㊴": [T: "número treinta y nueve rodeado por un círculo"] # 0x32b4 (en: 'circled number thirty nine', GPT-5.4 translation) + - "㊵": [T: "número cuarenta rodeado por un círculo"] # 0x32b5 (en: 'circled number forty', GPT-5.4 translation) + - "㊶": [T: "número cuarenta y uno rodeado por un círculo"] # 0x32b6 (en: 'circled number forty one', GPT-5.4 translation) + - "㊷": [T: "número cuarenta y dos rodeado por un círculo"] # 0x32b7 (en: 'circled number forty two', GPT-5.4 translation) + - "㊸": [T: "número cuarenta y tres rodeado por un círculo"] # 0x32b8 (en: 'circled number forty three', GPT-5.4 translation) + - "㊹": [T: "número cuarenta y cuatro rodeado por un círculo"] # 0x32b9 (en: 'circled number forty four', GPT-5.4 translation) + - "㊺": [T: "número cuarenta y cinco rodeado por un círculo"] # 0x32ba (en: 'circled number forty five', GPT-5.4 translation) + - "㊻": [T: "número cuarenta y seis rodeado por un círculo"] # 0x32bb (en: 'circled number forty six', GPT-5.4 translation) + - "㊼": [T: "número cuarenta y siete rodeado por un círculo"] # 0x32bc (en: 'circled number forty seven', GPT-5.4 translation) + - "㊽": [T: "número cuarenta y ocho rodeado por un círculo"] # 0x32bd (en: 'circled number forty eight', GPT-5.4 translation) + - "㊾": [T: "número cuarenta y nueve rodeado por un círculo"] # 0x32be (en: 'circled number forty nine', GPT-5.4 translation) + - "㊿": [T: "número cincuenta rodeado por un círculo"] # 0x32bf (en: 'circled number fifty', GPT-5.4 translation) + - "㋌": [T: "mercurio"] # 0x32cc (en: 'mercury', google translation) + - "㋍": [T: "ergs"] # 0x32cd (google translation) + - "㋎": [T: "electronvoltios"] # 0x32ce (en: 'electron volts', google translation) + - "㋏": [T: "señal de responsabilidad limitada"] # 0x32cf (en: 'limited liability sign', google translation) + - "㍱": [T: "hectopascales"] # 0x3371 (en: 'hectopascals', google translation) + - "㍲": [T: "daltons"] # 0x3372 (google translation) + - "㍳": [T: "unidades astronómicas"] # 0x3373 (en: 'astronomical units', google translation) + - "㍴": [T: "barras"] # 0x3374 (en: 'bars', google translation) + - "㍵": [T: "o v"] # 0x3375 (google translation) + - "㍶": [T: "parsecs"] # 0x3376 (google translation) + - "㍷": [T: "decímetros"] # 0x3377 (en: 'decimeters', google translation) + - "㍸": [T: "decímetros al cuadrado"] # 0x3378 (en: 'decimeters squared', google translation) + - "㍹": [T: "decímetros al cubo"] # 0x3379 (en: 'decimeters cubed', google translation) + - "㍺": [T: "unidades instrumentales"] # 0x337a (en: 'instrumental units', google translation) + - "㎀": [T: "picoamperios"] # 0x3380 (google translation) + - "㎁": [T: "nanoamperios"] # 0x3381 (google translation) + - "㎂": [T: "microamperios"] # 0x3382 (google translation) + - "㎃": [T: "miliamperios"] # 0x3383 (en: 'milliamps', google translation) + - "㎄": [T: "kiloamperios"] # 0x3384 (google translation) + - "㎅": [T: "kilobytes"] # 0x3385 (google translation) + - "㎆": [T: "megabytes"] # 0x3386 (google translation) + - "㎇": [T: "gigabytes"] # 0x3387 (google translation) + - "㎈": [T: "calorías"] # 0x3388 (en: 'calories', google translation) + - "㎉": [T: "kilocalorías"] # 0x3389 (en: 'kilocalories', google translation) + - "㎊": [T: "picofaradios"] # 0x338a (google translation) + - "㎋": [T: "nanofaradios"] # 0x338b (google translation) + - "㎌": [T: "microfaradios"] # 0x338c (google translation) + - "㎍": [T: "microgramos"] # 0x338d (en: 'micrograms', google translation) + - "㎎": [T: "miligramos"] # 0x338e (en: 'milligrams', google translation) + - "㎏": [T: "kilogramos"] # 0x338f (en: 'kilograms', google translation) + - "㎐": [T: "hercios"] # 0x3390 (google translation) + - "㎑": [T: "kilohercios"] # 0x3391 (en: 'kilohertz', google translation) + - "㎒": [T: "megahercios"] # 0x3392 (en: 'megahertz', google translation) + - "㎓": [T: "gigahercios"] # 0x3393 (google translation) + - "㎔": [T: "terahercios"] # 0x3394 (google translation) + - "㎕": [T: "microlitros"] # 0x3395 (en: 'microliters', google translation) + - "㎖": [T: "mililitros"] # 0x3396 (google translation) + - "㎗": [T: "decilitros"] # 0x3397 (en: 'deciliters', google translation) + - "㎘": [T: "kilolitros"] # 0x3398 (en: 'kiloliters', google translation) + - "㎙": [T: "femtómetros"] # 0x3399 (en: 'femtometers', google translation) + - "㎚": [T: "micrómetros"] # 0x339b (en: 'micrometers', google translation) + - "㎜": [T: "milímetros"] # 0x339c (en: 'millimeters', google translation) + - "㎝": [T: "centímetros"] # 0x339d (en: 'centimeters', google translation) + - "㎞": [T: "kilómetros"] # 0x339e (en: 'kilometers', google translation) + - "㎟": [T: "milímetros cuadrados"] # 0x339f (en: 'millimeters squared', google translation) + - "㎠": [T: "centímetros cuadrados"] # 0x33a0 (en: 'centimeters squared', google translation) + - "㎡": [T: "metros cuadrados"] # 0x33a1 (en: 'meters squared', google translation) + - "㎢": [T: "kilómetros cuadrados"] # 0x33a2 (en: 'kilometers squared', google translation) + - "㎣": [T: "milímetros cúbicos"] # 0x33a3 (en: 'millimeters cubed', google translation) + - "㎤": [T: "centímetros cúbicos"] # 0x33a4 (en: 'centimeters cubed', google translation) + - "㎥": [T: "metros cúbicos"] # 0x33a5 (en: 'meters cubed', google translation) + - "㎦": [T: "kilómetros cúbicos"] # 0x33a6 (en: 'kilometers cubed', google translation) + - "㎧": [T: "metros por segundo"] # 0x33a7 (en: 'meters per second', google translation) + - "㎨": [T: "metros por segundo al cuadrado"] # 0x33a8 (en: 'meters per second squared', google translation) + - "㎩": [T: "pascales"] # 0x33a9 (en: 'pascals', google translation) + - "㎪": [T: "kilopascales"] # 0x33aa (en: 'kilopascals', google translation) + - "㎫": [T: "megapascales"] # 0x33ab (en: 'megapascals', google translation) + - "㎬": [T: "gigapascales"] # 0x33ac (en: 'gigapascals', google translation) + - "㎭": [T: "radián"] # 0x33ad (google translation) + - "㎮": [T: "radián por segundo"] # 0x33ae (en: 'rads per second', google translation) + - "㎯": [T: "radián por segundo al cuadrado"] # 0x33af (en: 'rads per second squared', google translation) + - "㎰": [T: "picosegundos"] # 0x33b0 (en: 'picoseconds', google translation) + - "㎱": [T: "nanosegundos"] # 0x33b1 (en: 'nanoseconds', google translation) + - "㎲": [T: "microsegundos"] # 0x33b2 (en: 'microseconds', google translation) + - "㎳": [T: "milisegundos"] # 0x33b3 (en: 'milliseconds', google translation) + - "㎴": [T: "picovoltios"] # 0x33b4 (google translation) + - "㎵": [T: "nanovoltios"] # 0x33b5 (en: 'nanovolts', google translation) + - "㎶": [T: "microvoltios"] # 0x33b6 (en: 'microvolts', google translation) + - "㎷": [T: "milivoltios"] # 0x33b7 (en: 'millivolts', google translation) + - "㎸": [T: "kilovoltios"] # 0x33b8 (en: 'kilovolts', google translation) + - "㎹": [T: "megavoltios"] # 0x33b9 (google translation) + - "㎺": [T: "picovatios"] # 0x33ba (google translation) + - "㎻": [T: "nanovatios"] # 0x33bb (google translation) + - "㎼": [T: "microvatios"] # 0x33bc (google translation) + - "㎽": [T: "milivatios"] # 0x33bd (google translation) + - "㎾": [T: "kilovatios"] # 0x33be (en: 'kilowatts', google translation) + - "㎿": [T: "megavatios"] # 0x33bf (google translation) + - "㏀": [T: "kiloohmios"] # 0x33c0 (google translation) + - "㏁": [T: "megaohmios"] # 0x33c1 (google translation) + - "㏂": [T: "attómetros"] # 0x33c2 (en: 'attometers', google translation) + - "㏃": [T: "becquerels"] # 0x33c3 (google translation) + - "㏄": [T: "centímetros cubicos"] # 0x33c4 (en: 'cubic centimeters', google translation) + - "㏅": [T: "candelas"] # 0x33c5 (google translation) + - "㏆": [T: "culombios por kilogramos"] # 0x33c6 (en: 'coulombs per kilogram', google translation) + - "㏇": [T: "volumen minuto"] # 0x33c7 (en: 'cardiac output', google translation) + - "㏈": [T: "decibelios"] # 0x33c8 (en: 'decibels', google translation) + - "㏉": [T: "grises"] # 0x33c9 (en: 'grays', google translation) + - "㏊": [T: "hectáreas"] # 0x33ca (en: 'hectares', google translation) + - "㏋": [T: "caballo de fuerza"] # 0x33cb (en: 'horsepower', google translation) + - "㏌": [T: "pulgadas"] # 0x33cc (en: 'inches', google translation) + - "㏍": [T: "kilokelvins"] # 0x33cd (google translation) + - "㏎": [T: "kilómetros"] # 0x33ce (en: 'kilometers', google translation) + - "㏏": [T: "nudos"] # 0x33cf (en: 'knots', google translation) + - "㏐": [T: "lúmenes"] # 0x33d0 (en: 'lumens', google translation) + - "㏑": [T: "logaritmo natural"] # 0x33d1 (en: 'natural log', google translation) + - "㏒": [T: "logaritmo"] # 0x33d2 (en: 'logarithm', google translation) + - "㏓": [T: "lux"] # 0x33d3 (google translation) + - "㏔": [T: "milibares"] # 0x33d4 (google translation) + - "㏕": [T: "mills"] # 0x33d5 (en: 'mills', google translation) + - "㏖": [T: "moles"] # 0x33d6 (google translation) + - "㏗": [T: "p h"] # 0x33d7 (google translation) + - "㏘": [T: "picómetros"] # 0x33d8 (en: 'picometers', google translation) + - "㏙": [T: "partes por millón"] # 0x33d9 (en: 'parts per million', google translation) + - "㏚": [T: "roentgens"] # 0x33da (en: 'petaroentgens', google translation) + - "㏛": [T: "estererradián"] # 0x33db (en: 'steradians', google translation) + - "㏜": [T: "sieverts"] # 0x33dc (google translation) + - "㏝": [T: "webers"] # 0x33dd (google translation) + - "㏞": [T: "voltios por metro"] # 0x33de (en: 'volts per meter', google translation) + - "㏟": [T: "amperios por metro"] # 0x33df (en: 'amps per meter', google translation) + - "㏿": [T: "galones"] # 0x33ff (en: 'gallons', google translation) + - "": [T: "sino igual a con sombrero debajo"] # 0xe900 (en: 'equals with hat below', google translation) + - "": [T: "es igual a con signo más encima"] # 0xe901 (en: 'equals with plus above', google translation) + - "⩲": [T: "es igual a con signo más encima"] # 0x2a72 (en: 'equals with plus above') + - "": [T: "es igual a con signo más debajo"] # 0xe902 (en: 'equals with plus below', google translation) + - "⩱": [T: "es igual a con signo más debajo"] # 0x2a71 (en: 'equals with plus below') + - "": [T: "tilde con más encima"] # 0xe903 (en: 'tilde with plus above', google translation) + - "⨦": [T: "tilde con signo más encima"] # 0x2a26 (en: 'tilde with plus above') + - "": [T: "tilde signo más debajo"] # 0xe904 (en: 'tilde with plus below', google translation) + - "⨤": [T: "tilde con signo más debajo"] # 0x2a24 (en: 'tilde with plus below') + - "": [T: "doble signo igual sobre mayor que"] # 0xe908 (en: 'equal double over greater than', google translation) + - "": [T: "doble signo igual sobre menor que"] # 0xe909 (en: 'equal double over less than', google translation) + - "⪙": [T: "doble signo igual sobre menor que"] # 0x2a99 (en: 'equal double over less than') + - "": [T: "contiene o igual a"] # 0xe90a (en: 'contains or equal to', google translation) + - "⋽": [T: "contiene o igual a"] # 0x22fd (en: 'contains or equal to') + - "": [T: "superconjunto de o igual a"] # 0xe90b (en: 'superset of or equal to', google translation) + - "": [T: "subconjunto de o igual a"] # 0xe90c (en: 'subset of or equal to', google translation) + - "": [T: "signo igual sobre signo menor que"] # 0xe90d (en: 'equal over less than', google translation) + - "": [T: "elemento de o igual a"] # 0xe912 (en: 'element of or equal to', google translation) + - "⋷": [T: "elemento de o igual a"] # 0x22f7 (en: 'element of or equal to') + - "": [T: "igual a o mayor que"] # 0xe913 (en: 'equal to or greater than', google translation) + - "⪚": [T: "mayor que o igual a"] # 0x2a9a (en: 'equal to or greater than') + - "": [T: "superconjunto aproximado de"] # 0xe914 (en: 'approximate superset of', google translation) + - "⫈": [T: "contiene aproximadamente a"] # 0x2ac8 (en: 'approximate superset of') + - "": [T: "subconjunto aproximado de"] # 0xe915 (en: 'approximate subset of', google translation) + - "⫇": [T: "incluido aproximadamente en"] # 0x2ac7 (en: 'approximate subset of') + - "": [T: "superconjunto de con punto incluido como sub-relación"] # 0xe916 (en: 'superset of with dot includes as sub relation', google translation) + - "⪾": [T: "contiene como sub-relación a"] # 0x2abe (en: 'superset of with dot includes as sub relation') + - "": [T: "el subconjunto de con dot se incluye en una subselección"] # 0xe917 (en: 'subset of with dot is included in as sub relation', google translation) + - "⪽": [T: "sub-relación de"] # 0x2abd (en: 'subset of with dot is included in as sub relation') + - "": [T: "signo igual a con punto debajo"] # 0xe918 (en: 'equal with dot below', google translation) + - "⩦": [T: "signo igual a con punto debajo"] # 0x2a66 (en: 'equal with dot below') + - "": [T: "punto izquierdo sobre signo menos sobre punto derecho"] # 0xe919 (en: 'left dot over minus over right dot', google translation) + - "": [T: "punto derecho sobre signo menos sobre punto izquierdo"] # 0xe91a (en: 'right dot over minus over left dot', google translation) + - "": [T: "casi igual a menos"] # 0xe91f (en: 'almost equal to minus', google translation) + - "": [T: "taza doble cuadrada"] # 0xe920 (en: 'double square cup', google translation) + - "": [T: "doble cuadrado en mayúsculas"] # 0xe921 (en: 'double square cap', google translation) + - "": [T: "menor que igual o mayor que"] # 0xe922 (en: 'less than equal to or greater than', google translation) + - "": [T: "tilde con punto"] # 0xe924 (en: 'tilde with dot', google translation) + - "⩪": [T: "tilde con punto"] # 0x2a6a (en: 'tilde with dot') + - "": [T: "tilde con dos puntos"] # 0xe925 (en: 'tilde with two dots', google translation) + - "": [T: "menor que mayor o igual a"] # 0xe926 (en: 'less than greater than or equal to', google translation) + - "⪑": [T: "menor que mayor que o igual a"] # 0x2a91 (en: 'less than greater than or equal to') + - "": [T: "mayor que menor que o igual a"] # 0xe927 (en: 'greater than less than or equal to', google translation) + - "⪒": [T: "mayor que menor que o igual a"] # 0x2a92 (en: 'greater than less than or equal to') + - "": [T: "equivalente a o menor que"] # 0xe928 (en: 'equivalent to or less than', google translation) + - "⪝": [T: "equivalente a o menor que"] # 0x2a9d (en: 'equivalent to or less than') + - "": [T: "equivalente a o mayor que"] # 0xe929 (en: 'equivalent to or greater than', google translation) + - "": [T: "operador de caja abierta izquierda"] # 0xe92a (en: 'left open box operator', google translation) + - "": [T: "operador de caja abierta derecha"] # 0xe92b (en: 'right open box operator', google translation) + - "": [T: "idéntico a con punto"] # 0xe92c (en: 'identical to with dot', google translation) + - "": [T: "mayor que igual a o menor que"] # 0xe92d (en: 'greater than equal to or less than', google translation) + - "": [T: "operador de barra"] # 0xe92e (en: 'bar operator', google translation) + - "": [T: "operador de doble barra"] # 0xe92f (en: 'double bar operator', google translation) + - "": [T: "operador de triple barra"] # 0xe930 (en: 'triple bar operator', google translation) + - "": [T: "menor que o aproximadamente igual a"] # 0xe932 (en: 'less than or approximately equal to', google translation) + - "": [T: "mayor que o aproximadamente igual a"] # 0xe933 (en: 'greater than or approximately equal to', google translation) + - "": [T: "menor que anidado"] # 0xe936 (en: 'nested less than', google translation) + - "⪡": [T: "mucho menor que"] # 0x2aa1 (en: 'nested less than') + - "": [T: "mayor que anidado"] # 0xe937 (en: 'nested greater than', google translation) + - "⪢": [T: "mucho mayor que"] # 0x2aa2 (en: 'nested greater than') + - "": [T: "precede o equivalente a"] # 0xe93a (en: 'precedes or equivalent to', google translation) + - "": [T: "sucede o equivalente a"] # 0xe93b (en: 'succeeds or equivalent to', google translation) + - "": [T: "precede sobre signo igual"] # 0xe940 (en: 'precedes over equal', google translation) + - "": [T: "sucede sobre signo igual"] # 0xe941 (en: 'succeeds over equal', google translation) + - "": [T: "menor igual inclinado mayor"] # 0xe942 (en: 'less equal slanted greater', google translation) + - "": [T: "mayor igual inclinado menor"] # 0xe943 (en: 'greater equal slanted less', google translation) + - "": [T: "satisfecho por"] # 0xe948 (en: 'satisfied by', google translation) + - "": [T: "lazy s"] # 0xe949 (en: 'lazy s', google translation) + - "": [T: "no afirmación"] # 0xe94a (en: 'not assertion', google translation) + - "": [T: "doble igual"] # 0xe94b (en: 'double equal', google translation) + - "⩵": [T: "doble igual"] # 0x2a75 (en: 'double equal') + - "": [T: "triple igual"] # 0xe94c (en: 'triple equal', google translation) + - "": [T: "regla retardada"] # 0xe94d (en: 'rule delayed', google translation) + - "⧴": [T: "regla retardada"] # 0x29f4 + - "": [T: "delimitador de alias"] # 0xe94e (en: 'alias delimiter', google translation) + - "": [T: "subgrupo normal de con barra"] # 0xe950 (en: 'normal subgroup of with bar', google translation) + - "⧏": [T: "subgrupo normal o igual a"] # 0x29cf (en: 'normal subgroup of with bar') + - "": [T: "contiene como subgrupo normal con barra"] # 0xe951 (en: 'contains as normal subgroup with bar', google translation) + - "⧐": [T: "contiene como subgrupo normal o es igual a"] # 0x29d0 (en: 'contains as normal subgroup with bar') + - "": [T: "implica circular"] # 0xe954 (en: 'round implies', google translation) + - "⥰": [T: "implica circular"] # 0x2970 + - "": [T: "emoticono de sonrisa debajo de una barra"] # 0xe955 (en: 'smile under bar', google translation) + - "": [T: "emoticono de ceño fruncido sobe barra"] # 0xe956 (en: 'frown over bar', google translation) + - "": [T: "superconjunto de o casi igual a"] # 0xe957 (en: 'superset of or almost equal to', google translation) + - "": [T: "subconjunto de o casi igual a"] # 0xe958 (en: 'subset of or almost equal to', google translation) + - "": [T: "mayor que casi igual a o menor que"] # 0xe959 (en: 'greater than almost equal to or less than', google translation) + - "": [T: "menor que casi igual a o mayor que"] # 0xe95a (en: 'less than almost equal or greater than', google translation) + - "": [T: "doble o lógica"] # 0xe95c (en: 'double logical or', google translation) + - "⩔": [T: "o"] # 0x2a54 (en: 'double logical or') + - "": [T: "doble y lógica"] # 0xe95d (en: 'double logical and', google translation) + - "⩓": [T: "y"] # 0x2a53 (en: 'double logical and') + - "": [T: "o lógica con doble barra debajo"] # 0xe95e (en: 'logical or with double bar below', google translation) + - "": [T: "o lógica con barra debajo"] # 0xe95f (en: 'logical or with bar below', google translation) + - "": [T: "casi igual sobre igual"] # 0xe962 (en: 'almost equal over equal', google translation) + - "": [T: "triángulo apuntando a la izquierda con barra bisectriz"] # 0xe964 + - "": [T: "triángulo apuntando a la derecha con barra bisectriz"] # 0xe965 (en: 'right pointing triangle with bisecting bar', google translation) + - "": [T: "es igual a la línea punteada superior"] # 0xe966 (en: 'equals with dotted top line', google translation) + - "": [T: "precede con dos puntos"] # 0xe967 (en: 'precedes with colon', google translation) + - "": [T: "sucede con dos puntos"] # 0xe968 (en: 'succeeds with colon', google translation) + - "": [T: "más pequeño o igual inclinado"] # 0xe969 (en: 'smaller than or equal slanted', google translation) + - "": [T: "más grande o igual inclinado"] # 0xe96a (en: 'larger than or equal slanted', google translation) + - "": [T: "mucho menor que anidado"] # 0xe96b (en: 'nested very much less than', google translation) + - "": [T: "mucho mayor que anidado"] # 0xe96c (en: 'nested very much greater than', google translation) + - "": [T: "diferencia entre variantes"] # 0xe96d (en: 'difference between variant', google translation) + - "⪮": [T: "diferencia entre"] # 0x2aae (en: 'difference between variant') + - "": [T: "superposición de menor que mayor que"] # 0xe96e (en: 'less than greater than overlay', google translation) + - "⪤": [T: "superposición de menor que mayor que"] # 0x2aa4 (en: 'less than greater than overlay') + - "": [T: "o lógica y lógica superpuestas"] # 0xe96f (en: 'logical or logical and overlay', google translation) + - "": [T: "superconjunto sobre superconjunto"] # 0xe970 (en: 'superset over superset', google translation) + - "⫖": [T: "superconjunto sobre superconjunto"] # 0x2ad6 (en: 'superset over superset') + - "": [T: "subconjunto sobre subconjunto"] # 0xe971 (en: 'subset over subset', google translation) + - "⫕": [T: "subconjunto por encima de subconjunto"] # 0x2ad5 (en: 'subset over subset') + - "": [T: "superconjunto sobre subconjunto"] # 0xe972 (en: 'superset over subset', google translation) + - "⫔": [T: "contiene o está incluido en"] # 0x2ad4 (en: 'superset over subset') + - "": [T: "subconjunto sobre superconjunto"] # 0xe973 (en: 'subset over superset', google translation) + - "⫓": [T: "está incluido o contiene a"] # 0x2ad3 (en: 'subset over superset') + - "": [T: "triple barra vertical"] # 0xe979 (en: 'triple vertical bar', google translation) + - "": [T: "puntos verticales cuádruples emparejados"] # 0xe97a (en: 'paired quadruple vertical dots', google translation) + - "": [T: "perpendicular sobre barra"] # 0xe97b (en: 'perpendicular over bar', google translation) + - "⫨": [T: "perpendicular sobre barra"] # 0x2ae8 (en: 'perpendicular over bar') + - "": [T: "doble barra vertical con torniquete a la izquierda"] # 0xe97c (en: 'left turnstile double vertical bar', google translation) + - "": [T: "doble barra vertical con doble torniquete a la izquierda"] # 0xe97d (en: 'double left turnstile double vertical bar', google translation) + - "": [T: "perpendicular sobre perpendicular invertida"] # 0xe97e (en: 'perpendicular over inverted perpendicular', google translation) + - "": [T: "barra vertical con doble torniquete a la izquierda"] # 0xe97f (en: 'double left turnstile vertical bar', google translation) + - "⫤": [T: "barra vertical con doble torniquete a la izquierda"] # 0x2ae4 + - "": [T: "apertura de ángulo esférico"] # 0xe980 (en: 'spherical angle opening up', google translation) + - "": [T: "doble barra"] # 0xe981 (en: 'double slash', google translation) + - "": [T: "ángulo recto con esquina"] # 0xe982 (en: 'right angle with corner', google translation) + - "": [T: "barra vertical rodeada por un círculo"] # 0xe984 (en: 'circled vertical bar', google translation) + - "⦶": [T: "barra vertical rodeada por un círculo"] # 0x29b6 (en: 'circled vertical bar') + - "": [T: "signo de división rodeado por un círculo"] # 0xe985 (en: 'circled division sign', google translation) + - "⨸": [T: "signo de división rodeado por un círculo"] # 0x2a38 (en: 'circled division sign') + - "": [T: "solidus discontinuo"] # 0xe986 (en: 'dashed solidus', google translation) + - "": [T: "barra inversa discontinua"] # 0xe987 (en: 'dashed backslash', google translation) + - "": [T: "línea media discontinua"] # 0xe988 (en: 'dashed mid line', google translation) + - "": [T: "barra vertical discontinua"] # 0xe989 (en: 'dashed vertical bar', google translation) + - "": [T: "perpendicular con s"] # 0xe98a (en: 'perpendicular with s', google translation) + - "": [T: "ángulo con s"] # 0xe98b (en: 'angle with s', google translation) + - "": [T: "apertura izquierda en ángulo esférico"] # 0xe98c (en: 'spherical angle opening left', google translation) + - "": [T: "apertura angular izquierda"] # 0xe98d (en: 'angle opening left', google translation) + - "": [T: "barra vertical con doble garfio"] # 0xe98e (en: 'vertical bar with double hook', google translation) + - "⥾": [T: "barra vertical con doble garfio"] # 0x297e (en: 'vertical bar with double hook') + - "": [T: "operador de punto medio radical libre"] # 0xe98f (en: 'medium dot operator free radical', google translation) + - "": [T: "blanco apuntando al triángulo sobre la barra"] # 0xe990 (en: 'white up pointing triangle above bar', google translation) + - "": [T: "idéntico y paralelo a"] # 0xe991 (en: 'identical and parallel to', google translation) + - "": [T: "smash product"] # 0xe992 (en: 'smash product', google translation) + - "⨳": [T: "smash product"] # 0x2a33 + - "": [T: "operador de triple barra con barra horizontal"] # 0xe993 (en: 'triple bar operator with horizontal bar', google translation) + - "": [T: "idéntico a con doble barra cortada"] # 0xe994 (en: 'identical to with double slash', google translation) + - "⧥": [T: "idéntico a con doble barra cortada"] # 0x29e5 (en: 'identical to with double slash') + - "": [T: "barras triples cruzadas"] # 0xe995 (en: 'triple crossed bars', google translation) + - "": [T: "barra vertical sobre círculo"] # 0xe996 (en: 'vertical bar over circle', google translation) + - "": [T: "vertical proporcional a"] # 0xe997 (en: 'vertical proportional to', google translation) + - "": [T: "luna en cuarto menguante"] # 0xe998 (google translation) + - "": [T: "cuarto creciente"] # 0xe999 (google translation) + - "": [T: "onda sinusoidal negativa"] # 0xe9a0 (en: 'negative sine wave', google translation) + - "": [T: "punto entre paréntesis"] # 0xe9a1 (en: 'parenthesized dot', google translation) + - "": [T: "paréntesis"] # 0xe9a2 (en: 'parens', google translation) + - "": [T: "emoticono de sonrisa blanca"] # 0xe9a3 (en: 'white smile', google translation) + - "": [T: "emoticono de ceño fruncido"] # 0xe9a4 (en: 'white frown', google translation) + - "": [T: "hexágono"] # 0xe9a5 (en: 'hexagon', google translation) + - "": [T: "equivalente a sobre signo más"] # 0xe9a6 (en: 'equivalent to over plus', google translation) + - "": [T: "signo más sobre equivalente a"] # 0xe9a7 (en: 'plus over equivalent to', google translation) + - "": [T: "intersección serifs"] # 0xe9b0 (en: 'intersection serifs', google translation) + - "": [T: "union serifs"] # 0xe9b1 (google translation) + - "": [T: "intersección cuadrada serifs"] # 0xe9b2 (en: 'square intersection serifs', google translation) + - "": [T: "unión cuadrada serifs"] # 0xe9b3 (google translation) + - "": [T: "precede equivalente a o sucede a"] # 0xe9e0 (en: 'precedes equivalent to or succeeds', google translation) + - "": [T: "sucede equivalente a o precede"] # 0xe9e1 (en: 'succeeds equivalent to or precedes', google translation) + - "": [T: "precede casi igual a o sucede a"] # 0xe9e2 (en: 'precedes almost equal to or succeeds', google translation) + - "": [T: "sucede casi igual o precede"] # 0xe9e3 (en: 'succeeds almost equal to or precedes', google translation) + - "": [T: "menor que equivalente a o mayor que"] # 0xe9f0 (en: 'less than equivalent to or greater than', google translation) + - "": [T: "mayor que equivalente a o menor que"] # 0xe9f1 (en: 'greater than equivalent to or less than', google translation) + - "": [T: "no vert mucho menor que"] # 0xea00 (en: 'not vert much less than', google translation) + - "": [T: "no vert mucho mayor que"] # 0xea01 (en: 'not vert much greater than', google translation) + - "": [T: "variante no mucho menor que"] # 0xea02 (en: 'not much less than variant', google translation) + - "": [T: "variante no mucho mayor que"] # 0xea03 (en: 'not much greater than variant', google translation) + - "": [T: "menor que vert no signos igual doble"] # 0xea04 (en: 'less vert not double equals', google translation) + - "": [T: "gt vert no doble signo igual"] # 0xea05 (en: 'gt vert not double equals', google translation) + - "": [T: "no menor que o igual a"] # 0xea06 (en: 'not less than or equal to', google translation) + - "": [T: "no mayor que o igual a"] # 0xea07 (en: 'not greater than or equal to', google translation) + - "": [T: "ni igual a ni menor que"] # 0xea09 (en: 'neither equal to nor less than', google translation) + - "": [T: "no contiene ni igual a"] # 0xea0a (en: 'does not contain or equal to', google translation) + - "": [T: "ni superconjunto ni igual a"] # 0xea0b (en: 'neither superset of nor equal to', google translation) + - "": [T: "ni subconjunto ni igual a"] # 0xea0c (en: 'neither subset of nor equal to', google translation) + - "": [T: "subconjunto con solidus invertido"] # 0xea0d (en: 'reverse solidus subset', google translation) + - "": [T: "ni igual a ni mayor que"] # 0xea0e (en: 'neither equal to nor greater than', google translation) + - "": [T: "no menos operador tilde"] # 0xea0f (en: 'not minus tilde operator', google translation) + - "": [T: "ni igual a ni menor que"] # 0xea10 (en: 'neither equal to nor less than', google translation) + - "": [T: "no operador tilde"] # 0xea11 (en: 'not tilde operator', google translation) + - "": [T: "ni elemento de ni igual a"] # 0xea12 (en: 'not element of or equal to', google translation) + - "": [T: "ni igual ni mayor que"] # 0xea13 (en: 'neither equal to nor greater than', google translation) + - "": [T: "no casi igual"] # 0xea14 (en: 'not almost equal', google translation) + - "": [T: "no sucede similar"] # 0xea15 (en: 'not succeeds similar', google translation) + - "": [T: "menor que o igual a inclinado con barra cortada"] # 0xea16 (en: 'less than or slanted equal to with slash', google translation) + - "": [T: "mayor que o igual a inclinado con barra cortada"] # 0xea17 (en: 'greater than or slanted equal to with slash', google translation) + - "": [T: "superconjunto solidus"] # 0xea1a (google translation) + - "": [T: "no contiene"] # 0xea1b (en: 'does not contain', google translation) + - "": [T: "no menor que o igual a"] # 0xea1d (en: 'not less than or equal to', google translation) + - "": [T: "no mayor que o igual a"] # 0xea1e (en: 'not greater than or equal to', google translation) + - "": [T: "no casi igual a menos"] # 0xea1f (en: 'not almost equal to minus', google translation) + - "": [T: "conjunto negado de afiliación con punto encima"] # 0xea22 (en: 'negated set membership dot above', google translation) + - "": [T: "no ángulo de vert"] # 0xea2c (en: 'not vert angle', google translation) + - "": [T: "no paralelo inclinado"] # 0xea2d (en: 'not parallel slanted', google translation) + - "": [T: "no operador de barra"] # 0xea2e (en: 'not bar operator', google translation) + - "": [T: "no operador de barra doble"] # 0xea2f (en: 'not double bar operator', google translation) + - "": [T: "no operador de triple barra"] # 0xea30 (en: 'not triple bar operator', google translation) + - "": [T: "menor que pero no aproximadamente igual a"] # 0xea32 (en: 'less than but not approximately equal to', google translation) + - "⪉": [T: "menor que pero no aproximadamente igual a"] # 0x2a89 (en: 'less than but not approximately equal to') + - "": [T: "mayor que pero no aproximadamente igual a"] # 0xea33 (en: 'greater than but not approximately equal to', google translation) + - "⪊": [T: "mayor que pero no aproximadamente igual a"] # 0x2a8a (en: 'greater than but not approximately equal to') + - "": [T: "menor que o no igual a"] # 0xea34 (en: 'less than or not equal to', google translation) + - "": [T: "mayor que o no igual a"] # 0xea35 (en: 'greater than or not equal to', google translation) + - "": [T: "menor que no anidado"] # 0xea36 (en: 'not nested less than', google translation) + - "": [T: "mayor que no anidado"] # 0xea37 (en: 'not nested greater than', google translation) + - "": [T: "no mucho menor que"] # 0xea38 (en: 'not much less than', google translation) + - "": [T: "no mucho mayor que"] # 0xea39 (en: 'not much greater than', google translation) + - "": [T: "precede pero no equivalente a"] # 0xea3a (en: 'precedes but not equivalent to', google translation) + - "": [T: "sucede pero no equivalente a"] # 0xea3b (en: 'succeeds but not equivalent to', google translation) + - "": [T: "precede pero no es igual a"] # 0xea3c (en: 'precedes but not equal to', google translation) + - "": [T: "sucede pero no es igual a"] # 0xea3d (en: 'succeeds but not equal to', google translation) + - "": [T: "ni es igual a ni precede"] # 0xea3e (en: 'does not equal or precede', google translation) + - "": [T: "ni es igual a ni sucede"] # 0xea3f (en: 'does not equal or succeed', google translation) + - "": [T: "precede pero no es igual a"] # 0xea40 (en: 'precedes but not equal to', google translation) + - "⪵": [T: "precede pero no es igual a"] # 0x2ab5 (en: 'precedes but not equal to') + - "": [T: "sucede pero no es igual a"] # 0xea41 (en: 'succeeds but not equal to', google translation) + - "⪶": [T: "sucede pero no es igual a"] # 0x2ab6 (en: 'succeeds but not equal to') + - "": [T: "ni subconjunto de ni igual a"] # 0xea42 (en: 'not subset of nor equal to', google translation) + - "": [T: "ni superconjunto de ni igual a"] # 0xea43 (en: 'not superset of nor equal to', google translation) + - "": [T: "subconjunto de o no igual a"] # 0xea44 (en: 'subset of or not equal to', google translation) + - "": [T: "superconjunto de o no igual a"] # 0xea45 (en: 'superset of or not equal to', google translation) + - "": [T: "ni subconjunto de ni igual a"] # 0xea46 (en: 'not subset of nor equal to', google translation) + - "": [T: "ni superconjunto de ni igual a"] # 0xea47 (en: 'not superset of nor equal to', google translation) + - "": [T: "no triple menor que"] # 0xea48 (en: 'not triple less than', google translation) + - "": [T: "no triple mayor que"] # 0xea49 (en: 'not triple greater than', google translation) + - "": [T: "no precede a igual"] + - "": [T: "no sucede a igual"] # 0xea4d (en: 'not succeeds equals', google translation) + - "": [T: "no subgrupo normal de con barra"] # 0xea50 (en: 'not normal subgroup of with bar', google translation) + - "": [T: "no contiene como subgrupo normal con barra"] # 0xea51 (en: 'does not contain as normal subgroup with bar', google translation) + - "": [T: "no diferencia entre"] # 0xea52 (en: 'not difference between', google translation) + - "": [T: "no geométricamente equivalente a"] # 0xea53 (en: 'not geometrically equivalent to', google translation) + - "": [T: "no vert similar"] # 0xea54 (en: 'not vert similar', google translation) + - "": [T: "no igual o similar"] # 0xea55 (en: 'not equal or similar', google translation) + - "": [T: "no vert aproximado"] # 0xea56 (en: 'not vert approximate', google translation) + - "": [T: "no aproximadamente idéntico a"] # 0xea57 (en: 'not approximately identical to', google translation) + - "": [T: "no bump igual"] # 0xea58 (en: 'not bumpy equals', google translation) + - "": [T: "ni un solo bumpy igual a"] # 0xea59 (en: 'not bumpy single equals', google translation) + - "": [T: "no punto igual"] # 0xea5a (en: 'not equal dot', google translation) + - "": [T: "inverso no equivalente"] # 0xea5b (en: 'reverse not equivalent', google translation) + - "": [T: "no subconjunto cuadrado"] # 0xea60 (en: 'not square subset', google translation) + - "": [T: "no superconjunto cuadrado"] # 0xea61 (en: 'not square superset', google translation) + - "": [T: "no casi igual sobre igual"] # 0xea62 (en: 'not almost equal over equal', google translation) + - "": [T: "no estrictamente equivalente a"] # 0xea63 (en: 'not strictly equivalent to', google translation) + - "": [T: "no congruente punto"] # 0xea64 (en: 'not congruent dot', google translation) + - "": [T: "reverso no es igual"] # 0xea65 (en: 'reverse not equal', google translation) + - "": [T: "no vert triángulo izquierdo es igual a"] # 0xea70 (en: 'not vert left triangle equals', google translation) + - "": [T: "no vert triángulo recto es igual a"] # 0xea71 (en: 'not vert right triangle equals', google translation) + - "": [T: "no parcial"] # 0xea80 (en: 'not partial', google translation) + - "": [T: "extensor de adornos de flecha"] # 0xeb00 (en: 'arrow embellishment extender', google translation) + - "": [T: "flecha hacia la derecha sobre flecha hacia la izquierda"] # 0xeb01 (en: 'arrow rightwards over arrow leftwards', google translation) + - "": [T: "flecha hacia la derecha sobre flecha hacia la izquierda"] # 0xeb02 (en: 'arrow rightwards over arrow leftwards', google translation) + - "": [T: "arpón a la derecha sobre arpón a la izquierda"] # 0xeb03 (en: 'harpoon right over harpoon left', google translation) + - "": [T: "arpón a la derecha sobre arpón a la izquierda"] # 0xeb04 (en: 'harpoon right over harpoon left', google translation) + - "": [T: "doble flecha al nordeste desde el sudoeste"] # 0xeb05 (en: 'double arrow northeast southwest', google translation) + - "": [T: "doble flecha al noroeste desde el sudeste"] # 0xeb06 (en: 'double arrow northwest southeast', google translation) + - "": [T: "extensor de arpón horizontal"] # 0xeb07 (en: 'horizontal harpoon extender', google translation) + - "": [T: "arco en sentido contrario a las agujas del reloj a la izquierda de flecha"] # 0xeb08 (en: 'anticlockwise arc leftwards arrow', google translation) + - "": [T: "arco en sentido contrario a las agujas del reloj a la derecha de flecha"] # 0xeb09 (en: 'anticlockwise arc rightwards arrow', google translation) + - "": [T: "acento con flecha grande hacia la derecha"] # 0xeb0b (en: 'large rightwards arrow accent', google translation) + - "": [T: "acento con flecha grande hacia la izquierda"] # 0xeb0c (en: 'large leftwards arrow accent', google translation) + - "": [T: "punta de flecha hacia la izquierda"] # 0xeb0d (en: 'leftwards arrowhead', google translation) + - "": [T: "punta de flecha hacia la derecha"] # 0xeb0e (en: 'rightwards arrowhead', google translation) + - "": [T: "gran flecha derecha izquierda con trazo"] # 0xeb0f (en: 'large left right arrow with stroke', google translation) + - "": [T: "extensor de flecha doble horizontal"] # 0xeb10 (en: 'horizontal double arrow extender', google translation) + - "": [T: "gran flecha doble izquierda derecha con trazo"] # 0xeb11 (en: 'large left right double arrow with stroke', google translation) + - "": [T: "flecha hacia abajo y hacia la izquierda de flecha hacia arriba"] # 0xeb12 (en: 'downwards arrow leftwards of upwards arrow', google translation) + - "⇵": [T: "flecha hacia arriba y a la derecha de flecha hacia abajo"] # 0x21f5 (en: 'downwards arrow leftwards of upwards arrow') + - "": [T: "flecha hacia la izquierda con la esquina hacia abajo"] # 0xeb13 (en: 'leftwards arrow with corner downwards', google translation) + - "": [T: "flecha hacia la derecha con la esquina hacia arriba"] # 0xeb14 (en: 'rightwards arrow with corner upwards', google translation) + - "": [T: "flecha hacia la izquierda con la esquina hacia arriba"] # 0xeb15 (en: 'leftwards arrow with corner upwards', google translation) + - "": [T: "flecha superior semicircular en sentido contrario a las agujas del reloj con signo más"] # 0xeb16 (en: 'anticlockwise top semicircle arrow with plus', google translation) + - "⤽": [T: "flecha superior semicircular en sentido contrario a las agujas del reloj con signo más"] # 0x293d (en: 'anticlockwise top semicircle arrow with plus') + - "": [T: "flecha superior semicircular en sentido a las agujas del reloj con signo menos"] # 0xeb17 (en: 'clockwise top semicircle arrow with minus', google translation) + - "⤼": [T: "flecha superior semicircular en sentido a las agujas del reloj con signo menos"] # 0x293c (en: 'clockwise top semicircle arrow with minus') + - "": [T: "flecha hacia la derecha con cola con trazo"] # 0xeb18 (en: 'rightwards arrow with tail with stroke', google translation) + - "": [T: "arpón derecho hacia abajo"] # 0xeb19 (en: 'right harpoon down', google translation) + - "": [T: "arpón izquierdo hacia abajo"] # 0xeb1a (en: 'left harpoon down', google translation) + - "": [T: "arpón derecho izquierdo hacia abajo"] # 0xeb1b (en: 'left right harpoon down', google translation) + - "⥐": [T: "arpón derecho izquierdo hacia abajo"] # 0x2950 (en: 'left right harpoon down', MathPlayer: 'arpón inferior derecha-izquierda', google: 'arpón derecho izquierdo hacia abajo') + - "": [T: "arpón derecho izquierdo hacia arriba"] # 0xeb1c (en: 'left right harpoon up', google translation) + - "⥎": [T: "arpón izquierdo derecho hacia arriba"] # 0x294e (en: 'left right harpoon up', MathPlayer: 'arpón superior derecha-izquierda', google: 'arpón derecho izquierdo hacia arriba') + - "": [T: "arpón izquierdo arriba y abajo"] # 0xeb1d (en: 'up down harpoon left', google translation) + - "⥑": [T: "arpón izquierdo arriba y abajo"] # 0x2951 (en: 'up down harpoon left') + - "": [T: "arpón derecho arriba y abajo"] # 0xeb1e (en: 'up down harpoon right', google translation) + - "⥏": [T: "arpón derecho arriba y abajo"] # 0x294f (en: 'up down harpoon right') + - "": [T: "flecha hacia arriba a la derecha de flecha hacia abajo"] # 0xeb1f (en: 'upwards arrow to the right of downwards arrow', google translation) + - "⇵": [T: "flecha hacia arriba a la derecha de flecha hacia abajo"] # 0x21f5 + - "": [T: "arpón hacia la izquierda a barra con punta hacia arriba"] # 0xeb20 (en: 'leftwards harpoon to bar with barb upwards', google translation) + - "⥒": [T: "arpón hacia la izquierda a barra con punta hacia arriba"] # 0x2952 (en: 'leftwards harpoon to bar with barb upwards', MathPlayer: 'leftwards harpoon to bar with barb upwards', google: 'arpón de la izquierda para bar con barb hacia arriba') + - "": [T: "arpón hacia la derecha a barra con punta hacia arriba"] # 0xeb21 (en: 'rightwards harpoon to bar with barb upwards', google translation) + - "⥓": [T: "arpón hacia la derechaa a barra con punta hacia arriba"] # 0x2953 (en: 'rightwards harpoon to bar with barb upwards', MathPlayer: 'rightwards harpoon to bar with barb upwards', google: 'arpoon a la derecha para bar con barb hacia arriba') + - "": [T: "arpón hacia la izquierda a barra con punta hacia abajo"] # 0xeb22 (en: 'leftwards harpoon to bar with barb downwards', google translation) + - "⥖": [T: "arpón hacia la izquierda a barra con punta hacia abajo"] # 0x2956 (en: 'leftwards harpoon to bar with barb downwards', MathPlayer: 'leftwards harpoon to bar with barb downwards', google: 'arpoon hacia la izquierda para bar con barb hacia abajo') + - "": [T: "arpón hacia la derecha a barra con punta hacia abajo"] # 0xeb23 (en: 'rightwards harpoon to bar with barb downwards', google translation) + - "⥗": [T: "arpón hacia la derecha a barra con punta hacia abajo"] # 0x2957 (en: 'rightwards harpoon to bar with barb downwards', MathPlayer: 'rightwards harpoon to bar with barb downwards', google: 'arpoon a la derecha para bar con barb hacia abajo') + - "": [T: "arpón hacia la izquierda partiendo de barra con punta hacia arriba"] # 0xeb24 (en: 'leftwards harpoon from bar with barb upwards', google translation) + - "⥚": [T: "arpón hacia la izquierda partiendo d barra con punta hacia arriba"] # 0x295a (en: 'leftwards harpoon from bar with barb upwards', MathPlayer: 'leftwards harpoon from bar with barb upwards', google: 'arpón de la izquierda desde el bar con barb al alza') + - "": [T: "arpón hacia la derecha partiendo de barra con punta hacia arriba"] # 0xeb25 (en: 'rightwards harpoon from bar with barb upwards', google translation) + - "⥛": [T: "arpón hacia la derecha partiendo de barra con punta hacia arriba"] # 0x295b (en: 'rightwards harpoon from bar with barb upwards', MathPlayer: 'rightwards harpoon from bar with barb upwards', google: 'arpoon a la derecha desde el bar con barb al alza') + - "": [T: "arpón hacia la izquierda partiendo de barra con punta hacia abajo"] # 0xeb26 (en: 'leftwards harpoon from bar with barb downwards', google translation) + - "⥞": [T: "arpón hacia la izquierda partiendo de barra con punta hacia abajo"] # 0x295e (en: 'leftwards harpoon from bar with barb downwards', MathPlayer: 'leftwards harpoon from bar with barb downwards', google: 'arpón de la izquierda desde el bar con barb hacia abajo') + - "": [T: "arpón hacia la derecha partiendo de barra con punta hacia abajo"] # 0xeb27 (en: 'rightwards harpoon from bar with barb downwards', google translation) + - "⥟": [T: "arpón hacia la derecha partiendo de barra con punta hacia abajo"] # 0x295f (en: 'rightwards harpoon from bar with barb downwards', MathPlayer: 'rightwards harpoon from bar with barb downwards', google: 'arpoon a la derecha desde el bar con barb hacia abajo') + - "": [T: "arpón hacia arriba a barra con punta a la izquierda"] # 0xeb28 (en: 'upwards harpoon to bar with barb leftwards', google translation) + - "⥘": [T: "arpón hacia arriba a barra con púa a la izquierda"] # 0x2958 (en: 'upwards harpoon to bar with barb leftwards', MathPlayer: 'upwards harpoon to bar with barb leftwards', google: 'hace arriba hacia arriba para bar con barb a la izquierda') + - "": [T: "arpón hacia abajo a barra con punta hacia la izquierda"] # 0xeb29 (en: 'downwards harpoon to bar with barb leftwards', google translation) + - "⥙": [T: "arpón hacia abajo a barra con punta hacia la izquierda"] # 0x2959 (en: 'downwards harpoon to bar with barb leftwards', MathPlayer: 'downwards harpoon to bar with barb leftwards', google: 'harpoon hacia abajo para bar con barb a la izquierda') + - "": [T: "arpón hacia arriba a barra con punta hacia la derecha"] # 0xeb2a (en: 'upwards harpoon to bar with barb rightwards', google translation) + - "⥔": [T: "arpón hacia arriba a barra con punta hacia la derecha"] # 0x2954 (en: 'upwards harpoon to bar with barb rightwards', MathPlayer: 'upwards harpoon to bar with barb rightwards', google: 'hace arriba hacia arriba para bar con barb a la derecha') + - "": [T: "arpón hacia abajo a barra con punta hacia la derecha"] # 0xeb2b (en: 'downwards harpoon to bar with barb rightwards', google translation) + - "⥕": [T: "arpón hacia abajo a barra con punta hacia la derecha"] # 0x2955 (en: 'downwards harpoon to bar with barb rightwards', MathPlayer: 'downwards harpoon to bar with barb rightwards', google: 'harpoon hacia abajo para bar con barb a la derecha') + - "": [T: "arpón hacia harriba partiendo de barra con punta hacia la izquierda"] # 0xeb2c (en: 'upwards harpoon from bar with barb leftwards', google translation) + - "⥠": [T: "arpón hacia arriba partiendo de barra con punta hacia la izquierda"] # 0x2960 (en: 'upwards harpoon from bar with barb leftwards', MathPlayer: 'upwards harpoon from bar with barb leftwards', google: 'hacia arriba hacia arriba desde el bar con barb a la izquierda') + - "": [T: "arpón hacia abajo partiendo de barra con punta hacia la izquierda"] # 0xeb2d (en: 'downwards harpoon from bar with barb leftwards', google translation) + - "⥡": [T: "arpón hacia abajo partiendo de barra con punta hacia la izquierda"] # 0x2961 (en: 'downwards harpoon from bar with barb leftwards', MathPlayer: 'downwards harpoon from bar with barb leftwards', google: 'hosto hacia abajo de bar con barb a la izquierda') + - "": [T: "arpón hacia arriba partiendo de barra con punta hacia la derecha"] # 0xeb2e (en: 'upwards harpoon from bar with barb rightwards', google translation) + - "⥜": [T: "arpón hacia arriba partiendo de barra con punta hacia la derecha"] # 0x295c (en: 'upwards harpoon from bar with barb rightwards', MathPlayer: 'upwards harpoon from bar with barb rightwards', google: 'hace arriba hacia arriba desde el bar con barb a la derecha') + - "": [T: "arpón hacia abajo partiendo de barra con punta hacia la derecha"] # 0xeb2f (en: 'downwards harpoon from bar with barb rightwards', google translation) + - "⥝": [T: "arpón hacia abajo partiendo de barra con punta hacia la derecha"] # 0x295d (en: 'downwards harpoon from bar with barb rightwards', MathPlayer: 'downwards harpoon from bar with barb rightwards', google: 'hosto hacia abajo desde el bar con barb a la derecha') + - "": [T: "flecha hacia arriba a barra"] # 0xeb30 (en: 'upwards arrow to bar', google translation) + - "⤒": [T: "flecha hacia arriba a barra"] # 0x2912 + - "": [T: "flecha hacia abajo a barra"] # 0xeb31 (en: 'downwards arrow to bar', google translation) + - "⤓": [T: "flecha hacia abajo a barra"] # 0x2913 + - "": [T: "arpón hacia arriba a la izquierda de arpón hacia abajo"] # 0xeb32 (en: 'upwards harpoon to the left of downwards harpoon', google translation) + - "⥮": [T: "arpón hacia arriba a la izquierda de arpón hacia abajo"] # 0x296e (en: 'upwards harpoon to the left of downwards harpoon', MathPlayer: 'upwards harpoon to the left of downwards harpoon', google: 'hacia arriba harpoon a la izquierda de la arpón hacia abajo') + - "": [T: "arpón hacia arriba a la derecha de arpón hacia abajo"] # 0xeb33 (en: 'upwards harpoon to the right of downwards harpoon', google translation) + - "⥯": [T: "arpón hacia arriba a la derecha de arpón hacia abajo"] # 0x296f (en: 'upwards harpoon to the right of downwards harpoon', MathPlayer: 'upwards harpoon to the right of downwards harpoon', google: 'hacia arriba hacia arriba a la derecha de la arpón hacia abajo') + - "": [T: "punta de flecha hacia arriba"] # 0xeb34 (en: 'upwards arrowhead', google translation) + - "": [T: "punta de flecha hacia abajo"] # 0xeb35 (en: 'downwards arrowhead', google translation) + - "": [T: "doble arpón con punta hacia abajo a la izquierda y punta hacia arriba a la derecha"] # 0xeb36 (en: 'double harpoon with leftwards barb down rightwards barb up', google translation) + - "": [T: "doble arpón con punta hacia arriba a la izquierda y con punta hacia abajo a la derecha"] # 0xeb37 (en: 'double harpoon with leftwards barb up rightwards barb down', google translation) + - "": [T: "flecha hacia la izquierda sobre barra"] # 0xeb38 (en: 'leftwards arrow over bar', google translation) + - "": [T: "flecha hacia la derecha sobre barra"] # 0xeb39 (en: 'rightwards arrow over bar', google translation) + - "": [T: "flecha hacia la izquierda debajo de barra"] # 0xeb3a (en: 'leftwards arrow under bar', google translation) + - "": [T: "flecha hacia la derecha debajo de barra"] # 0xeb3b (en: 'rightwards arrow under bar', google translation) + - "": [T: "triple flecha derecha e izquierda"] # 0xeb3c (en: 'left right triple arrow', google translation) + - "": [T: "doble flecha nordeste sudeste"] # 0xeb3f (en: 'double arrow northeast southeast', google translation) + - "": [T: "flecha semicircular izquierda en sentido contrario a las agujas del reloj"] # 0xeb40 (en: 'anticlockwise left semicircle arrow', google translation) + - "⤹": [T: "flecha semicircular izquierda en sentido contrario a las agujas del reloj"] # 0x2939 (en: 'anticlockwise left semicircle arrow') + - "": [T: "flecha semicircular izquierda en sentido a las agujas del reloj"] # 0xeb41 (en: 'clockwise left semicircle arrow', google translation) + - "": [T: "círculo abierto izquierdo flecha derecha izquierda"] # 0xeb42 (en: 'left open circle left right arrow', google translation) + - "": [T: "flecha hacia la derecha sobre tilde"] # 0xeb44 (en: 'rightwards arrow over tilde', google translation) + - "⥴": [T: "flecha hacia la derecha sobre tilde"] # 0x2974 (en: 'rightwards arrow over tilde') + - "": [T: "flecha hacia la izquierda sobre tilde"] # 0xeb45 (en: 'leftwards arrow over tilde', google translation) + - "⥳": [T: "flecha hacia la derecha sobre tilde"] # 0x2973 (en: 'leftwards arrow over tilde') + - "": [T: "arpón hacia la izquierda sobre barra"] # 0xeb48 (en: 'leftwards harpoon over bar', google translation) + - "⥪": [T: "arpón hacia la izquierda sobre barra"] # 0x296a (en: 'leftwards harpoon over bar') + - "": [T: "arpón hacia la derecha sobre barra"] # 0xeb49 (en: 'rightwards harpoon over bar', google translation) + - "⥬": [T: "arpón hacia la derecha sobre barra"] # 0x296c (en: 'rightwards harpoon over bar') + - "": [T: "arpón hacia la izquierda debajo de barra"] # 0xeb4a (en: 'leftwards harpoon under bar', google translation) + - "⥫": [T: "arpón hacia la izquierda debajo de barra"] # 0x296b (en: 'leftwards harpoon under bar') + - "": [T: "arpón hacia la derecha debajo de barra"] # 0xeb4b (en: 'rightwards harpoon under bar', google translation) + - "⥭": [T: "arpón hacia la derecha debajo de barra"] # 0x296d (en: 'rightwards harpoon under bar') + - "": [T: "flecha corta negra hacia la izquierda"] # 0xeb4c (en: 'squat black leftwards arrow', google translation) + - "": [T: "flecha semicircular derecha en sentido a las agujas del reloj"] # 0xeb50 (en: 'clockwise right semicircle arrow', google translation) + - "⤸": [T: "flecha semicircular derecha en sentido a las agujas del relojt"] # 0x2938 (en: 'clockwise right semicircle arrow') + - "": [T: "flecha semicircular derecha en sentido contrario a las agujas del reloj"] # 0xeb51 (en: 'anticlockwise right semicircle arrow', google translation) + - "": [T: "círculo abierto izquierdo arpón izquierdo derecho"] # 0xeb52 (en: 'left open circle left right harpoon', google translation) + - "": [T: "flecha hacia arriba y hacia la izquierda de barra vertical"] # 0xeb58 (en: 'upwards arrow leftwards of vertical bar', google translation) + - "": [T: "flecha hacia abajo hacia la izquierda de barra vertical"] # 0xeb59 (en: 'downwards arrow leftwards of vertical bar', google translation) + - "": [T: "flecha hacia arriba hacia la derecha de barra vertical"] # 0xeb5a (en: 'upwards arrow rightwards of vertical bar', google translation) + - "": [T: "flecha hacia abajo hacia la derecha de barra vertical"] # 0xeb5b (en: 'downwards arrow rightwards of vertical bar', google translation) + - "": [T: "flecha hacia la derecha con garfio hacia abajo extendido"] # 0xeb5c (en: 'rightwards arrow with extended downwards hook', google translation) + - "": [T: "flecha hacia la izquierda con gancho extendido"] # 0xeb5d (en: 'leftwards arrow with extended hook', google translation) + - "": [T: "flecha hacia la izquierda con gancho hacia abajo extendido"] # 0xeb5e (en: 'leftwards arrow with extended downwards hook', google translation) + - "": [T: "flecha hacia la derecha con garfio extendido"] # 0xeb5f (en: 'rightwards arrow with extended hook', google translation) + - "": [T: "no flecha derecha ondulada"] # 0xeb60 (en: 'not right arrow wavy', google translation) + - "": [T: "no flecha derecha curva"] # 0xeb61 (en: 'not right arrow curved', google translation) + - "": [T: "arpón hacia arriba hacia la izquierda de barra vertical"] # 0xeb68 (en: 'upwards harpoon leftwards of vertical bar', google translation) + - "": [T: "arpoon hacia abajo hacia la izquierda de barra vertical"] # 0xeb69 (en: 'downwards harpoon leftwards of vertical bar', google translation) + - "": [T: "arpón hacia arriba hacia la derecha de barra vertical"] # 0xeb6a (en: 'upwards harpoon rightwards of vertical bar', google translation) + - "": [T: "arpón hacia abajo hacia la derecha de barra vertical"] # 0xeb6b (en: 'downwards harpoon rightwards of vertical bar', google translation) + - "": [T: "extensor de flecha doble vertical"] # 0xeb6c (en: 'vertical double arrow extender', google translation) + - "": [T: "arpón vertical con extensor de punta izquierda"] # 0xeb6d (en: 'vertical harpoon with barb left extender', google translation) + - "": [T: "arpón vertical con extensor de punta derecha"] # 0xeb6e (en: 'vertical harpoon with barb right extender', google translation) + - "": [T: "arpón derecho sobre arpón izquierdo a la derecha"] # 0xeb6f (en: 'right harpoon over left harpoon right', google translation) + - "": [T: "arpón derecho sobre arpón izquierdo a la izquierda"] # 0xeb70 (en: 'right harpoon over left harpoon left', google translation) + - "": [T: "arpón izquierdo sobre arpón derecho a la derecha"] # 0xeb71 (en: 'left harpoon over right harpoon right', google translation) + - "": [T: "arpón izquierdo sobre arpón derecho a la izquierda"] # 0xeb72 (en: 'left harpoon over right harpoon left', google translation) + - "": [T: "flecha hacia la izquierda partiendo de punta de flecha de barra"] # 0xeb73 (en: 'leftwards arrow from bar arrowhead', google translation) + - "": [T: "flecha hacia la izquierda y derecha partiendo de extensor de barra"] # 0xeb74 (en: 'leftwards rightwards arrow from bar extender', google translation) + - "": [T: "flecha hacia la izquierda partiendo de cola de barra"] # 0xeb75 (en: 'leftwards arrow from bar tail', google translation) + - "": [T: "flecha hacia la derecha partiendo de cola de barra"] # 0xeb76 (en: 'rightwards arrow from bar tail', google translation) + - "": [T: "flecha hacia la derecha partiendo de punta de flecha de barra"] # 0xeb77 (en: 'rightwards arrow from bar arrowhead', google translation) + - "": [T: "arpón hacia arriba partiendo de barra punzante con punta de flecha hacia la izquierda"] # 0xeb78 (en: 'upwards harpoon from bar with barb leftwards arrowhead', google translation) + - "": [T: "flecha hacia la derecha sobre flecha derecha hacia la izquierda"] # 0xeb79 (en: 'rightwards arrow over leftwards arrow right', google translation) + - "": [T: "flecha derecha sobre flecha izquierda hacia la izquierda"] # 0xeb7a (en: 'rightwards arrow over leftwards arrow left', google translation) + - "": [T: "flecha hacia la izquierda sobre flecha derecha hacia la derecha"] # 0xeb7b (en: 'leftwards arrow over rightwards arrow right', google translation) + - "": [T: "flecha hacia la izquierda sobre flecha derecha hacia la izquierda"] # 0xeb7c (en: 'leftwards arrow over rightwards arrow left', google translation) + - "": [T: "flecha hacia arriba partiendo de punta de flecha de barra"] # 0xeb7d (en: 'upwards arrow from bar arrowhead', google translation) + - "": [T: "flecha hacia arriba partiendo de la cola de la barra"] # 0xeb7e (en: 'upwards arrow from bar tail', google translation) + - "": [T: "flecha hacia abajo partiendo de la cola de la barra"] # 0xeb7f (en: 'downwards arrow from bar tail', google translation) + - "": [T: "flecha hacia abajo partiendo de la punta de flecha de la barra"] # 0xeb80 (en: 'downwards arrow from bar arrowhead', google translation) + - "": [T: "arpón hacia abajo partiendo de punta de flecha derecha de barra punzante"] # 0xeb81 (en: 'downwards harpoon from bar with barb rightwards arrowhead', google translation) + - "": [T: "arpón hacia arriba a la izquierda del fondo del arpón hacia abajo"] # 0xeb82 (en: 'upwards harpoon to the left of downwards harpoon bottom', google translation) + - "": [T: "arpón hacia arriba a la izquierda de extensor de arpón hacia abajo"] # 0xeb83 (en: 'upwards harpoon to the left of downwards harpoon extender', google translation) + - "": [T: "arpón hacia abajo a la izquierda de parte superior de arpón hacia arriba"] # 0xeb84 (en: 'downwards harpoon to the left of upwards harpoon top', google translation) + - "": [T: "arpón hacia arriba a la izquierda de parte superior de arpón hacia abajo"] # 0xeb85 (en: 'upwards harpoon to the left of downwards harpoon top', google translation) + - "": [T: "arpón hacia abajo a la izquierda de extensor de arpón hacia arriba"] # 0xeb86 (en: 'downwards harpoon to the left of the upwards harpoon extender', google translation) + - "": [T: "arpón hacia arriba a la izquierda de parte inferior d arpón hacia abajo"] # 0xeb87 (en: 'downwards harpoon to the left of the upwards harpoon bottom', google translation) + - "": [T: "flecha hacia arriba hacia la izquierda del fondo de flecha hacia abajo"] # 0xeb88 (en: 'upwards arrow leftwards of downwards arrow bottom', google translation) + - "": [T: "flecha hacia abajo hacia la izquierda de la parte superiorde flecha hacia arriba"] # 0xeb89 (en: 'downwards arrow leftwards of upwards arrow top', google translation) + - "": [T: "flecha hacia arriba hacia la izquierda de la parte superior de flecha hacia abajo"] # 0xeb8a (en: 'upwards arrow leftwards of downwards arrow top', google translation) + - "": [T: "flecha hacia abajo hacia la izquierda de la parte inferior de flecha hacia arriba"] # 0xeb8b (en: 'downwards arrow leftwards of upwards arrow bottom', google translation) + - "": [T: "extensor de flechas hacia izquierda y derecha"] # 0xeb8c (en: 'leftwards rightwards arrows extender', google translation) + - "": [T: "extensor de flecha nordeste"] # 0xeb8d (google translation) + - "": [T: "extensor de flecha noroeste"] # 0xeb8e (google translation) + - "": [T: "paréntesis izquierdo apuntando hacia abajo"] # 0xec00 (en: 'down pointing brace left', google translation) + - "": [T: "paréntesis medio apuntando hacia abajo"] # 0xec01 (google translation) + - "": [T: "paréntesis derecho apuntando hacia abajo"] # 0xec02 (en: 'down pointing brace right', google translation) + - "": [T: "extensor de paréntesis horizontal"] # 0xec03 (en: 'horizontal brace extender', google translation) + - "": [T: "paréntesis izquierdo apuntando hacia arriba"] # 0xec04 (en: 'up pointing brace left', google translation) + - "": [T: "paréntesis medio apuntando hacia arriba"] # 0xec05 (en: 'up pointing brace mid', google translation) + - "": [T: "paréntesis derecho apuntando hacia arriba"] # 0xec06 (en: 'up-pointing brace right', google translation) + - "": [T: "barra vertical izquierda"] # 0xec07 (en: 'left vertical bar', google translation) + - "": [T: "barra vertical derecha"] # 0xec08 (en: 'right vertical bar', google translation) + - "": [T: "doble barra vertical izquierda"] # 0xec09 (en: 'left double vertical bar', google translation) + - "": [T: "doble barra vertical derecha"] # 0xec0a (en: 'right double vertical bar', google translation) + - "": [T: "extensor de soporte horizontal"] # 0xec0b (en: 'horizontal bracket extender', google translation) + - "": [T: "debajo de corchete"] # 0xec0c (en: 'under square bracket', google translation) + - "⎵": [T: "debajo de corchete"] # 0x23b5 (en: 'under square bracket') + - "": [T: "encima de corchete"] # 0xec0d (en: 'over square bracket', google translation) + - "⎴": [T: "encima de corchete"] # 0x23b4 (en: 'over square bracket') + - "": [T: "debajo de paréntesis izquierdo"] # 0xec0e (en: 'under bracket left', google translation) + - "": [T: "debajo de paréntesis derecho"] # 0xec0f (en: 'under bracket right', google translation) + - "": [T: "sobre paréntesis izquierdo"] # 0xec10 (en: 'over bracket left', google translation) + - "": [T: "encima de paréntesis derecho"] # 0xec11 (en: 'over bracket right', google translation) + - "": [T: "abrir paréntesis 1"] # 0xec12 (en: 'left parens 1', google translation) + - "": [T: "abrir paréntesis 2"] # 0xec13 (en: 'left parens 2', google translation) + - "": [T: "abrir paréntesis 3"] # 0xec14 (en: 'left parens 3', google translation) + - "": [T: "abrir paréntesis 4"] # 0xec15 (en: 'left parens 4', google translation) + - "": [T: "cerrar paréntesis 1"] # 0xec16 (en: 'right parens 1', google translation) + - "": [T: "cerrar paréntesis 2"] # 0xec17 (en: 'right parens 2', google translation) + - "": [T: "cerrar paréntesis 3"] # 0xec18 (en: 'right parens 3', google translation) + - "": [T: "cerrar paréntesis 4"] # 0xec19 (en: 'right parens 4', google translation) + - "": [T: "radical 1"] # 0xec1a (google translation) + - "": [T: "radical 2"] # 0xec1b (google translation) + - "": [T: "radical 3"] # 0xec1c (google translation) + - "": [T: "radical 4"] # 0xec1d (google translation) + - "": [T: "radical 5"] # 0xec1e (google translation) + - "": [T: "radical inferior"] # 0xec1f (en: 'radical bottom', google translation) + - "": [T: "extensor de radical vertical"] # 0xec20 (en: 'radical vertical extender', google translation) + - "": [T: "radical superior"] # 0xec21 (en: 'radical top', google translation) + - "": [T: "soporte blanco izquierdo superior"] # 0xec22 (en: 'left white bracket top', google translation) + - "": [T: "extensor de soporte blanco izquierdo"] # 0xec23 (en: 'left white bracket extender', google translation) + - "": [T: "soporte blanco izquierdo inferior"] # 0xec24 (en: 'left white bracket bottom', google translation) + - "": [T: "soporte blanco derecho superior"] # 0xec25 (en: 'right white bracket top', google translation) + - "": [T: "extensor de soporte blanco derecho"] # 0xec26 (en: 'right white bracket extender', google translation) + - "": [T: "soporte blanco derecho inferior"] # 0xec27 (en: 'right white bracket bottom', google translation) + - "": [T: "soporte blanco izquierdo rotacional"] # 0xec30 (en: 'left white curly bracket', google translation) + - "": [T: "soporte blanco derecho rotacional"] # 0xec31 (en: 'right white curly bracket', google translation) + - "": [T: "signo de división largo"] # 0xec32 (google translation) + - "": [T: "extensor de signo de división largo"] # 0xec33 (en: 'long division sign extender', google translation) + - "": [T: "división corta"] # 0xec34 (en: 'short division', google translation) + - "": [T: "doble sudoeste al nordeste unión em"] # 0xec40 (en: 'double southwest to northeast em bond', google translation) + - "": [T: "doble noroeste al sudeste unión em"] # 0xec41 (en: 'double northwest to southeast em bond', google translation) + - "": [T: "enlace em horizontal único"] # 0xec42 (en: 'single horizontal em bond', google translation) + - "": [T: "doble enlace em horizontal"] # 0xec43 (en: 'double horizontal em bond', google translation) + - "": [T: "triple enlace em horizontal"] # 0xec44 (en: 'triple horizontal em bond', google translation) + - "": [T: "enlace em único vertical"] # 0xec45 (en: 'single vertical em bond', google translation) + - "": [T: "doble enlace em vertical"] # 0xec46 (en: 'double vertical em bond', google translation) + - "": [T: "triple enlace em vertical"] # 0xec47 (en: 'triple vertical em bond', google translation) + - "": [T: "menr que enlace em"] # 0xec48 (en: 'less than em bond', google translation) + - "": [T: "mayor que enlace em"] # 0xec49 (en: 'greater than em bond', google translation) + - "": [T: "enlace único horizontal"] # 0xec4a (en: 'single horizontal en bond', google translation) + - "": [T: "doble enlace horizontal en"] # 0xec4b (en: 'double horizontal en bond', google translation) + - "": [T: "triple enlace horizontal en"] # 0xec4c (en: 'triple horizontal en bond', google translation) + - "": [T: "rectángulo superior izquierdo"] # 0xec80 (en: 'top left rectangle', google translation) + - "": [T: "rectángulo inferior izquierdo"] # 0xec81 (en: 'bottom left rectangle', google translation) + - "": [T: "rectángulo superior derecho"] # 0xec90 (en: 'top right rectangle', google translation) + - "": [T: "rectángulo inferior derecho"] # 0xec91 (en: 'bottom right rectangle', google translation) + - "": [T: "intersección de división sintética"] # 0xec92 (en: 'synthetic division corner', google translation) + - "": [T: "extensor horizontal de división sintética"] # 0xec93 (en: 'synthetic division horizontal extender', google translation) + - "": [T: "extensor vertical de división sintética"] # 0xec94 (en: 'synthetic division vertical extender', google translation) + - "": [T: "extensor de límite izquierdo del fondo"] # 0xec95 (en: 'left ceiling floor extender', google translation) + - "": [T: "extensor de límite derecho del fondo"] # 0xec96 (en: 'right ceiling floor extender', google translation) + - "": [T: "por encima de extensor de soporte"] # 0xec97 (en: 'over bracket extender', google translation) + - "": [T: "extensor de barra vertical"] # 0xec98 (en: 'vertical bar extender', google translation) + - "": [T: "extensor de barra vertical doble izquierda"] # 0xec99 (en: 'left double vertical bar extender', google translation) + - "": [T: "extensor de barra horizontal"] # 0xec9a (en: 'horizontal bar extender', google translation) + - "": [T: "debajo de extensor de soporte"] # 0xec9c (en: 'under bracket extender', google translation) + - "": [T: "apuntando hacia abajo de paréntesis derecho"] # 0xec9d (en: 'down pointing paren right', google translation) + - "": [T: "apuntando hacia abajo de extensor de paréntesis"] # 0xec9e (en: 'down pointing paren extender', google translation) + - "": [T: "apuntando hacia abajo de paréntesis izquierdo"] # 0xec9f (en: 'down pointing paren left', google translation) + - "": [T: "apuntando hacia arriba de extensor de paréntesis"] # 0xeca0 (en: 'up pointing brace extender', google translation) + - "": [T: "apuntando hacia arriba de paréntesis de izquierda"] # 0xeca1 (en: 'up pointing paren left', google translation) + - "": [T: "apuntando hacia arriba de extensor de paréntesis"] # 0xeca2 (en: 'up pointing paren extender', google translation) + - "": [T: "apuntando hacia arriba de paréntesis derecho"] # 0xeca3 (en: 'up pointing paren right', google translation) + - "": [T: "apuntando hacia abajo de extensor de paréntesis"] # 0xeca4 (google translation) + - "": [T: "constante de Planck sobre dos barras pi"] # 0xed00 (en: 'planck constant over two pi bar', google translation) + - "": [T: "espejo g"] # 0xed01 (en: 'mirror g', google translation) + - "": [T: "j sin puntos"] # 0xed02 (google translation) + - "": [T: "digamma"] # 0xed03 (google translation) + - "ϝ": [T: "digamma"] # 0x3dd + - "": [T: "d"] # 0xed10 (en: 'd', google translation) + - "": [T: "e"] # 0xed11 (en: 'e', google translation) + - "": [T: "i"] # 0xed12 (en: 'i', google translation) + - "": [T: "j"] # 0xed13 (en: 'j', google translation) + - "ⅅ": + - spell: "translate('.', 'ⅅ', 'DD')" # 0xed16, 0x2145 + +# The private use chars are efrom MathType + - "": [T: "bucle integral de contorno en sentido contrario a las agujas del reloj"] # 0xee00 (en: 'anticlockwise contour integral loop', google translation) + - "": [T: "bucle integral de contorno en sentido de las agujas del reloj"] # 0xee01 (en: 'clockwise contour integral loop', google translation) + - "": [t: ""] # 0xee04 + - "": [t: ""] # 0xee05 + - "": [t: ""] # 0xee06 + - "": [t: ""] # 0xee07 + - "": [t: ""] # 0xee08 + - "": [t: ""] # 0xee09 + - "": [t: ""] # 0xee0a + - "": [t: ""] # 0xee0b + - "": [t: ""] # 0xee0c + - "": [T: "ornamentación de estatus conjunto"] # 0xee0d (en: 'joint status embellishment', google translation) + - "": [T: "ornamentación de estatus conjunto"] # 0xee0e (en: 'joint status embellishment left', google translation) + - "": [T: "ornamentación derecha de estatus conjunto"] # 0xee0f (en: 'joint status embellishment right', google translation) + - "": [T: "extensión de ornamentos de estatus conjunto"] # 0xee10 (en: 'joint status embellishment extender', google translation) + - "": [T: "bucle integral"] # 0xee11 (en: 'integral loop', google translation) + - "": [T: "doble bucle integral"] # 0xee12 (en: 'integral loop double', google translation) + - "": [T: "triple bucle integral"] # 0xee13 (en: 'integral loop triple', google translation) + - "": [T: "doble expansión de bucle integral"] # 0xee15 (en: 'expanding integral loop double', google translation) + - "": [T: "triple expansión de bucle integral"] # 0xee16 (en: 'expanding integral loop triple', google translation) + - "": [T: "asintóticamente igual al acento"] # 0xee17 (en: 'asymptotically equal to accent', google translation) + - "": [T: "signo igual a acetno"] # 0xee18 (en: 'equal sign accent', google translation) + - "": [T: "prima cuádruple"] # 0xee19 (en: 'quadruple prime', google translation) + - "⁗": [T: "prima cuádruple"] # 0x2057 (en: 'quadruple prime', MathPlayer: 'cuarta', google: 'prime cuádruple') + - "": [T: "acento de barra con círculo abierto izquierdo"] # 0xee1a (en: 'bar accent with open circle left', google translation) + - "": [T: "acento de barra con círculo cerrado izquierdo"] # 0xee1b (en: 'bar accent with closed circle left', google translation) + - "": [T: "acento de barra con círculo abierto derecho"] # 0xee1c (en: 'bar accent with open circle right', google translation) + - "": [T: "acento de barra con punto encima"] # 0xee1d (en: 'bar accent with over dot', google translation) + - "": [T: "acento de barra con punto debajo"] # 0xee1e (en: 'bar accent with under dot', google translation) + - "": [T: "acento de barra con doble punto encima"] # 0xee1f (en: 'bar accent with double over dot', google translation) + - "": [T: "acento de barra con doble punto debajo"] # 0xee20 (en: 'bar accent with double under dot', google translation) + - "": [T: "acento de barra con signo de intercalación"] # 0xee21 (en: 'bar accent with caret', google translation) + - "": [T: "marcado debajo de acento de barra"] # 0xee22 (en: 'thick under bar accent', google translation) + - "": [T: "acento de barra con círculo cerrado a la derecha"] # 0xee23 (en: 'bar accent with closed circle right', google translation) + - "": [T: "gran punto arriba"] # 0xee24 (en: 'large dot above', google translation) + - "": [T: "marca de alineación"] # 0xef00 (en: 'alignment mark', google translation) + - "": [t: ""] # 0xef01 + - "​": [t: ""] # 0x200b + - "": [t: ""] # 0xef02 + - " ": [t: ""] # 0x2009 + - "": [t: ""] # 0xef03 + - " ": [t: ""] # 0x205f + - "": [t: ""] # 0xef04 + - "": [t: ""] # 0xef05 + - " ": [t: ""] # 0x2003 + - "": [t: ""] # 0xef06 + - "": [t: ""] # 0xef07 + - "": [t: ""] # 0xef08 + - "": [t: ""] # 0xef09 + - "": [t: ""] # 0xef0a + - " ": [t: ""] # 0x200a + - "": [t: ""] # 0xef22 + - "": [t: ""] # 0xef23 + - "": [t: ""] # 0xef24 + - "": [t: ""] # 0xef29 + - "": [T: "término ausente"] # 0xef41 (en: 'missing term', google translation) + - "": [T: "flecha integral de contorno en sentido de las agujas del reloj a la izquierda"] # 0xef80 (en: 'clockwise contour integral arrow on left', google translation) + - "": [T: "integral con cuadrado"] # 0xef81 (en: 'integral with square', google translation) + - "": [T: "integral con barra cortada"] # 0xef82 (en: 'integral with slash', google translation) + - "": [T: "integral invertida"] # 0xef83 (en: 'reversed integral', google translation) + - "": [T: "doble cero sobre doble cero"] # 0xef90 (en: 'double zero over double zero', google translation) + - "": [T: "cero con barra cortada"] # 0xef91 (en: 'zero with slash', google translation) + + # fraktur chars in math alphabetic block and also MathType private use area + # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display + - "𝔄-𝔜": # 0x1d504 - 0x1d51d ('z' version is reserved) + - T: "fraktur" # (google translation) + - spell: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" + + - "-": # 0xf000 - 0xf018 + - T: "fraktur" # (google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" + + - "𝔞-𝔷": # 0x1d51e - 0x1d537 + - T: "fraktur" # (google translation) + - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf01a - 0xf033 + - T: "fraktur" # (google translation) + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝕬-𝖅": # 0x1D56C - 0x1D585 + - T: "fraktur bold" # (google translation) + - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf040 - 0xf059 + - T: "fraktur bold" # (google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝖆-𝖟": # 0x1d586 - 0x1d59f + - T: "fraktur bold" # (google translation) + - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf05a - 0xf073 + - T: "fraktur bold" # (google translation) + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + # double struck (blackboard bold) chars in math alphabetic block and also MathType private use area + # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display + - "𝔸-𝕐": # 0x1d504 - 0x1d51d ('z' version is reserved) + - test: + if: "$Verbosity!='Terse'" + then: [T: "doble tachadura"] # (en: 'double struck', google translation) + - spell: "translate('.', '𝔸𝔹𝔺𝔻𝔼𝔽𝔾𝔿𝕀𝕁𝕂𝕃𝕄𝕅𝕆𝕇𝕈𝕉𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf080 - 0xf098 + - test: + if: "$Verbosity!='Terse'" + then: [T: "doble tachadura"] # (en: 'double struck', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝕒-𝕫": # 0x1d552 - 0x1d56b + - test: + if: "$Verbosity!='Terse'" + then: [T: "doble tachadura"] # (en: 'double struck', google translation) + - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf09a - 0xf0b3 + - test: + if: "$Verbosity!='Terse'" + then: [T: "doble tachadura"] # (en: 'double struck', google translation) + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 + - test: + if: "$Verbosity!='Terse'" + then: [T: "doble tachadura"] # (en: 'double struck', google translation) + - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" + - "-": # 0xf0c0 - 0xf0c9 + - test: + if: "$Verbosity!='Terse'" + then: [T: "doble tachadura"] # (en: 'double struck', google translation) + - spell: "translate('.', '', '0123456789')" + + - "": [T: "doble nabla tachada"] # 0xf0ca (en: 'double struck nabla', google translation) + - "": [T: "doble constante de Euler tachada"] # 0xf0cb (en: 'double struck euler constant', google translation) + + # script chars in math alphabetic block and also MathType private use area + - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 + - T: "guión" # (en: 'script', google translation) + - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf100 - 0xf119 + - T: "guión" # (en: 'script', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf + - T: "guión" # (en: 'script', google translation) + - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf11a - 0xf133 + - T: "guión" # (en: 'script', google translation) + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + # bold script chars in math alphabetic block and also MathType private use area + - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 + - T: "guión en negrita" # (en: 'script bold', google translation) + - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf140 - 0xf159 + - T: "guión en negrita" # (en: 'script bold', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝓪-𝔃": # 0x1d4ea - 0x1d503 + - T: "guión en negrita" # (en: 'script bold', google translation) + - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf15a - 0xf173 + - T: "guión en negrita" # (en: 'script bold', google translation) + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf180 - 0xf199 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "": # 0xf19a + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "mayúscula"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "ligadura ae"] # (en: 'ligature ae', google translation) + - "": # 0xf19b + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "mayúscula"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "s puntiaguda"] # (en: 'sharp s', google translation) + - "": # 0xf19c + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "mayúscula"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "o con trazo"] # (en: 'o with stroke', google translation) + + # MathType only has a few of the cap Greek letters in PUA + - "": # 0xf201 - 0xf209 + - test: + if: "$Verbosity!='Terse'" + then: [T: "doble tachadura"] # (en: 'double struck', google translation) + - spell: "translate('.', '', 'ΔΨΛΠΣΘΓΩΥ')" + + - "-": # 0xf220 - 0xf236 + - test: + if: "$Verbosity!='Terse'" + then: [T: "doble tachadura"] # (en: 'double struck', google translation) + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "": [T: "doble tachadura en sigma final"] # 0xf237 (en: 'double struck final sigma', google translation) + - "": [T: "doble tachadura en rho"] # 0xf250 (en: 'double struck rho', google translation) + - "": [T: "doble tachadura en phi"] # 0xf251 (en: 'double struck phi', google translation) + - "𝐀-𝐙": # 0x1d400 - 0x1d419 + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf260 - 0xf279 + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝐚-𝐳": # 0x1d41a - 0x1d433 + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf27a - 0xf293 + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝐴-𝑍": # 0x1d434 - 0x1d44d + - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf294 - 0xf2ad + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝑎-𝑧": # 0x1d44e - 0x1d467 + - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf2ae - 0xf2c7 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝑨-𝒁": # 0x1d468 - 0x1d481 + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf2c8 - 0xf2e1 + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝒂-𝒛": # 0x1d482 - 0x1d49b + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf2e2 - 0xf2fb + # - T: "negrita cursiva" # (en: 'bold', google translation) + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 + - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf300 - 0xf319 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 + - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf31a - 0xf333 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf334 - 0xf34d + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝗮-𝘇": # 0x1d5ee - 0x1d607 + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf34e - 0xf367 + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝘈-𝘡": # 0x1d608 - 0x1d621 + # - T: "cursiva" + - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": # 0xf368 - 0xf381 + # - T: "cursiva" + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝘢-𝘻": # 0x1d622 - 0x1d63b + # - T: "cursiva" + - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf382 - 0xf39b + # - T: "cursiva" + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝘼-𝙕": # 0x1d63c - 0x1d655 + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf39c - 0xf3b5 + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝙖-𝙯": # 0x1d656 - 0x1d66f + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf3b6 - 0xf3cf + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝙰-𝚉": # 0x1d670 - 0x1d689 + - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf3d0 - 0xf3e9 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 + - spell: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf3ea - 0xf403 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "": [T: "i sin punto"] # 0xf404 (google translation) + - "𝚤": [T: "ci cursiva sin punto"] # 0x1d6a4 (en: 'dotless i', google: 'dotless i') + - "𝚥": [T: "j cursiva sin punto"] # 0x1d6a5 (en: 'dotless j', google: 'dotless j') + + - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 + - T: "j cursiva sin punto" # (en: 'bold', google: 'atrevido') + - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf408 - 0xf420 + - T: "j cursiva sin punto" # (en: 'bold', google: 'atrevido') + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da + - T: "j cursiva sin punto" # (en: 'bold', google: 'atrevido') + - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf422 - 0xf43a + - T: "j cursiva sin punto" # (en: 'bold', google: 'atrevido') + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "": [T: "nabla en negrita"] # 0xf421 (google translation) + - "𝛁": [T: "nabla en negrita"] # 0x1d6c1 (google translation) + + - "𝛛𝛜𝛝𝛞𝛟𝛠𝛡": # 0x1D6DB - 0x1D6E1 + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" + + - "": # 0xF43C - 0xF441 + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '', '∂εθκφρπ')" + + - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa + # - T: "cursiva" + - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf442 - 0xf45a + # - T: "cursiva" + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝛼-𝜔": # 0x1d6fc - 0x1d714 + # - T: "cursiva" + - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓𝜔', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf45c - 0xf474 + # - T: "cursiva" + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "": [T: "nabla en cursiva"] # 0xf45b (en: 'italic nabla', google translation) + - "𝛻": [T: "nabla en cursiva"] # 0x1d6fb (en: 'italic nabla', google translation) + + - "𝜕𝜖𝜗𝜘𝜙𝜚𝜛": # 0x1d715 - 0x1d71b + # - T: "cursiva" + - spell: "translate('.', '𝜕𝜖𝜗𝜘𝜙𝜚𝜛', '∂εθκφρπ')" + + - "": # 0xf475 - 0xf47b + # - T: "cursiva" + - spell: "translate('.', '', '∂εθκφρπ')" + + - "𝜜-𝜴": # 0x1d71c - 0x1d734 + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf47c - 0xf494 + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝜶-𝝎": # 0x1d736 - 0x1d74e + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf496 - 0xf4ae + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": # 0x1d74f - 0x1d755 + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εθκφρπ')" + + - "": # 0xf422 - 0xf43a + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '', '∂εθκφρπ')" + + - "𝜵": [T: "nabla en cursiva y negrita"] # 0x1d735 (en: 'bold italic nabla', google translation) + - "": [T: "nabla en cursiva y negrita"] # 0xf495 (en: 'bold italic nabla', google translation) + + - "𝝖-𝝮": # 0x1d756 - 0x1d76e + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "-": # 0xf4b6 - 0xf4ce + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝝰-𝞈": # 0x1d770 - 0x1d788 + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇𝞈', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf4d0 - 0xf4e8 + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝞉𝞊𝞋𝞌𝞍𝞎𝞏": # 0x1d789 - 0x1d78f + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '𝞉𝞊𝞋𝞌𝞍𝞎𝞏', '∂εθκφρπ')" + + - "": # 0xf4e9 - 0xf4ef + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '', '∂εθκφρπ')" + + - "": [T: "nabla en negrita"] # 0xf4cf (google translation) + - "𝝯": [T: "nabla en negrita"] # 0x1d76f (google translation) + + - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf4f0 - 0xf508 + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝞪-𝟂": # 0x1d7aa - 0x1d7c2 + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf50a - 0xf522 + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": # 0x1d7c3 - 0x1d7c9 + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '𝟃𝟄𝟅𝟆𝟇𝟈𝟉', '∂εθκφρπ')" + + - "": # 0xf523 - 0xf529 + # - T: "negrita cursiva" + - T: "negrita" # (en: 'bold', google translation) + - spell: "translate('.', '', '∂εθκφρπ')" + + - "": [T: "nabla en negrita"] # 0xf509 (google translation) + - "𝞩": [T: "nabla en negrita"] # 0x1d7a9 (google translation) + + - "": [T: "cero en negrita"] # 0xf52e (en: 'bold zero', google translation) + - "𝟎": [T: "cero en negrita"] # 0x1d7ce (en: 'bold zero', google translation) + - "": [T: "uno en negrita"] # 0xf52f (en: 'bold one', google translation) + - "𝟏": [T: "negrita"] # 0x1d7cf (en: 'bold one', google translation) + - "": [T: "dos en negrita"] # 0xf530 (en: 'bold two', google translation) + - "𝟐": [T: "dos en negrita"] # 0x1d7d0 (en: 'bold two', google translation) + - "": [T: "tres en negrita"] # 0xf531 (en: 'bold three', google translation) + - "𝟑": [T: "tres en negrita"] # 0x1d7d1 (en: 'bold three', google translation) + - "": [T: "cuatro en negrita"] # 0xf532 (en: 'bold four', google translation) + - "𝟒": [T: "bold en negrita"] # 0x1d7d2 (en: 'bold four', google translation) + - "": [T: "cinco en negrita"] # 0xf533 (en: 'bold five', google translation) + - "𝟓": [T: "cinco en negrita"] # 0x1d7d3 (en: 'bold five', google translation) + - "": [T: "seis en negrita"] # 0xf534 (en: 'bold six', google translation) + - "𝟔": [T: "seis en negrita"] # 0x1d7d4 (en: 'bold six', google translation) + - "": [T: "siete en negrita"] # 0xf535 (en: 'bold seven', google translation) + - "𝟕": [T: "siete en negrita"] # 0x1d7d5 (en: 'bold seven', google translation) + - "": [T: "ocho en negrita"] # 0xf536 (en: 'bold eight', google translation) + - "𝟖": [T: "ocho en negrita"] # 0x1d7d6 (en: 'bold eight', google translation) + - "": [T: "nueve en negrita"] # 0xf537 (en: 'bold nine', google translation) + - "𝟗": [T: "nueve en negrita"] # 0x1d7d7 (en: 'bold nine', google translation) + - "": [T: "cero"] # 0xf542 (en: 'zero', google translation) + - "𝟢": [T: "cero"] # 0x1d7e2 (en: 'zero', google translation) + - "": [T: "uno"] # 0x1d7e3 (en: 'one', google translation) + - "": [T: "dos"] # 0xf544 (en: 'two', google translation) + - "𝟤": [T: "dos"] # 0x1d7e4 (en: 'two', google translation) + - "": [T: "tres"] # 0xf545 (en: 'three', google translation) + - "𝟥": [T: "tres"] # 0x1d7e5 (en: 'three', google translation) + - "": [T: "cuatro"] # 0xf546 (en: 'four', google translation) + - "𝟦": [T: "cuatro"] # 0x1d7e6 (en: 'four', google translation) + - "": [T: "cinco"] # 0xf547 (en: 'five', google translation) + - "𝟧": [T: "cinco"] # 0x1d7e7 (en: 'five', google translation) + - "": [T: "seis"] # 0xf548 (en: 'six', google translation) + - "𝟨": [T: "seis"] # 0x1d7e8 (en: 'six', google translation) + - "": [T: "siete"] # 0xf549 (en: 'seven', google translation) + - "𝟩": [T: "siete"] # 0x1d7e9 (en: 'seven', google translation) + - "": [T: "ocho"] # 0xf54a (en: 'eight', google translation) + - "𝟪": [T: "ocho"] # 0x1d7ea (en: 'eight', google translation) + - "": [T: "nueve"] # 0xf54b (en: 'nine', google translation) + - "𝟫": [T: "nueve"] # 0x1d7eb (en: 'nine', google translation) + - "": [T: "cero en negrita"] # 0xf54c (en: 'bold zero', google translation) + - "𝟬": [T: "cero en negrita"] # 0x1d7ec (en: 'bold zero', google translation) + - "": [T: "uno en negrita"] # 0xf54d (en: 'bold one', google translation) + - "𝟭": [T: "uno en negrita"] # 0x1d7ed (en: 'bold one', google translation) + - "": [T: "dos en negrita"] # 0xf54e (en: 'bold two', google translation) + - "𝟮": [T: "dos en negrita"] # 0x1d7ee (en: 'bold two', google translation) + - "": [T: "tres en negrita"] # 0xf54f (en: 'bold three', google translation) + - "𝟯": [T: "tres en negrita"] # 0x1d7ef (en: 'bold three', google translation) + - "": [T: "cuatro en negrita"] # 0xf550 (en: 'bold four', google translation) + - "𝟰": [T: "bold en negrita"] # 0x1d7f0 (en: 'bold four', google translation) + - "": [T: "cinco en negrita"] # 0xf551 (en: 'bold five', google translation) + - "𝟱": [T: "bcinco en negrita"] # 0x1d7f1 (en: 'bold five', google translation) + - "": [T: "seis negrita"] # 0xf552 (en: 'bold six', google translation) + - "𝟲": [T: "seis negrita"] # 0x1d7f2 (en: 'bold six', google translation) + - "": [T: "siete negrita"] # 0xf553 (en: 'bold seven', google translation) + - "𝟳": [T: "siete en negrita"] # 0x1d7f3 (en: 'bold seven', google translation) + - "": [T: "ocho en negrita"] # 0xf554 (en: 'bold eight', google translation) + - "𝟴": [T: "ocho en negrita"] # 0x1d7f4 (en: 'bold eight', google translation) + - "": [T: "nueve en negrita"] # 0xf555 (en: 'bold nine', google translation) + - "𝟵": [T: "nueve en negrita"] # 0x1d7f5 (en: 'bold nine', google translation) + - "": [T: "cero"] # 0xf556 (en: 'zero', google translation) + - "𝟶": [T: "cero"] # 0x1d7f6 (en: 'zero', google translation) + - "": [T: "uno"] # 0xf557 (en: 'one', google translation) + - "𝟷": [T: "uno"] # 0x1d7f7 (en: 'one', google translation) + - "": [T: "dos"] # 0xf558 (en: 'two', google translation) + - "𝟸": [T: "dos"] # 0x1d7f8 (en: 'two', google translation) + - "": [T: "tres"] # 0xf559 (en: 'three', google translation) + - "𝟹": [T: "tres"] # 0x1d7f9 (en: 'three', google translation) + - "": [T: "cuatro"] # 0xf55a (en: 'four', google translation) + - "𝟺": [T: "cuatro"] # 0x1d7fa (en: 'four', google translation) + - "": [T: "cinco"] # 0xf55b (en: 'five', google translation) + - "𝟻": [T: "cinco"] # 0x1d7fb (en: 'five', google translation) + - "": [T: "seis"] # 0xf55c (en: 'six', google translation) + - "𝟼": [T: "seis"] # 0x1d7fc (en: 'six', google translation) + - "": [T: "siete"] # 0xf55d (en: 'seven', google translation) + - "𝟽": [T: "siete"] # 0x1d7fd (en: 'seven', google translation) + - "": [T: "ocho"] # 0xf55e (en: 'eight', google translation) + - "𝟾": [T: "ocho"] # 0x1d7fe (en: 'eight', google translation) + - "": [T: "nueve"] # 0xf55f (en: 'nine', google translation) + - "𝟿": [T: "nueve"] # 0x1d7ff (en: 'nine', google translation) + - "": [T: "carácter desconocido"] # 0xf700 (en: 'unknown character', google translation) + - "": [T: "triángulos inferior derecho e inferior izquierdo"] # 0xf726 (en: 'lower right and lower left triangles', google translation) + - "": [T: "extensor de puntos suspensivos horizontales"] # 0xf72d (en: 'horizontal ellipsis extender', google translation) + - "": [T: "extensor de puntos suspensivos de línea media horizontal"] # 0xf72e (en: 'midline horizontal ellipsis extender', google translation) + - "": [T: "extensor radical"] # 0xf8e5 (en: 'radical extender', google translation) + - "": [T: "extensor de flecha vertical"] # 0xf8e6 (en: 'vertical arrow extender', google translation) + - "": [T: "extensor de flecha horizontal"] # 0xf8e7 (en: 'horizontal arrow extender', google translation) + - "": [T: "señal registrada sans serif"] # 0xf8e8 (en: 'registered sign sans serif', google translation) + - "": [T: "copyright sign sans serif"] # 0xf8e9 (google translation) + - "": [T: "signo de marca comercial sans serif"] # 0xf8ea (en: 'trade mark sign sans serif', google translation) + - "": [T: "paréntesis superior izquierdo"] # 0xf8eb (en: 'left paren top', google translation) + - "": [T: "extensor de paréntesis izquierdo"] # 0xf8ec (en: 'left paren extender', google translation) + - "": [T: "paréntesis izquierdo inferior"] # 0xf8ed (en: 'left paren bottom', google translation) + - "": [T: "soporte izquierdo superior"] # 0xf8ee (en: 'left bracket top', google translation) + - "": [T: "extensor de soporte izquierdo"] # 0xf8ef (en: 'left bracket extender', google translation) + - "": [T: "soporte izquierdo inferior"] # 0xf8f0 (en: 'left bracket bottom', google translation) + - "": [T: "soporte izquierdo superior"] # 0xf8f1 (en: 'left brace top', google translation) + - "": [T: "soporte izquierdo medio"] # 0xf8f2 (en: 'left brace mid', google translation) + - "": [T: "soporte izquierdo inferior"] # 0xf8f3 (en: 'left brace bottom', google translation) + - "": [T: "extensor de soporte"] # 0xf8f4 (en: 'brace extender', google translation) + - "": [T: "extensor integral"] # 0xf8f5 (en: 'integral extender', google translation) + - "": [T: "paréntesis superior derecho"] # 0xf8f6 (en: 'right paren top', google translation) + - "": [T: "extensor de paréntesis derecho"] # 0xf8f7 (en: 'right paren extender', google translation) + - "": [T: "paréntesis inferior derecho"] # 0xf8f8 (en: 'right paren bottom', google translation) + - "": [T: "soporte derecho superior"] # 0xf8f9 (en: 'right bracket top', google translation) + - "": [T: "extensor de soporte derecho"] # 0xf8fa (en: 'right bracket extender', google translation) + - "": [T: "soporte derecho inferior"] # 0xf8fc (en: 'right brace top', google translation) + - "": [T: "soporte derecho medio"] # 0xf8fd (en: 'right brace mid', google translation) + - "": [T: "soporte derecho inferior"] # 0xf8fe (en: 'right brace bottom', google translation) + - "": [T: "logotipo de apple"] # 0xf8ff (en: 'apple logo', google translation) + - "ff": [T: "ff ligadas"] # 0xfb00 (en: 'ff', google: 'ff') + - "fi": [T: "fi ligadas"] # 0xfb01 (en: 'fi', google: 'f') + - "fl": [T: "fl ligadas"] # 0xfb02 (en: 'fl', google: 'florida') + - "ffi": [T: "ffl ligadas"] # 0xfb04 (en: 'ffl', google: 'ffl') + - "ſt": [T: "pie"] # 0xfb05 (en: 'ft', google translation) + - "st": [T: "calle"] # 0xfb06 (en: 'st', google translation) + - "︠": [T: "mitad de ornamentación izquierda en ligadura"] # 0xfe20 (en: 'ligature left half embellishment', google translation) + - "︡": [T: "mitad de ornamentación derecha en ligadura"] # 0xfe21 (en: 'ligature right half embellishment', google translation) + - "︢": [T: "doble tilde con media ornamentación izquierda"] # 0xfe22 (en: 'double tilde left half embellishment', google translation) + - "︣": [T: "doble tilde medio adorno"] # 0xfe23 (en: 'double tilde right half embellishment', google translation) + - "︤": [T: "macron dejó medio adorno"] # 0xfe24 (en: 'macron left half embellishment', google translation) + - "︥": [T: "macron medio adorno"] # 0xfe25 (en: 'macron right half embellishment', google translation) + - "︦": [T: "unir el adorno de macron"] # 0xfe26 (en: 'conjoining macron embellishment', google translation) + - "︵": [T: "paréntesis superior"] # 0xfe35 (en: 'over paren') + - "︶": [T: "paréntesis inferior"] # 0xfe36 (en: 'under paren') + - "︷": [T: "llave superior"] # 0xfe37 (en: 'over brace') + - "︸": [T: "llave inferior"] # 0xfe38 (en: 'under brace') + - "︿": [T: "paréntesis angular superior"] # 0xfe3f (en: 'over angle bracket') + - "﹀": [T: "paréntesis angular inferior"] # 0xfe40 (en: 'under angle bracket') + - "﹨": [T: "división entera"] # 0xfe68 (en: 'integer divide') + - "": [T: "objeto desconocido o faltante"] # 0xfffc (en: 'unknown or missing object', google translation) + - "�": [T: "caracter desconocido o faltante"] # 0xfffd (en: 'unknown or missing character', google: 'personaje desconocido o faltante') + diff --git a/Rules/Languages/es/unicode.yaml b/Rules/Languages/es/unicode.yaml index dd7119ada..545b70516 100644 --- a/Rules/Languages/es/unicode.yaml +++ b/Rules/Languages/es/unicode.yaml @@ -1,466 +1,466 @@ ---- - # Note to translators: - # most languages don't have two ways to pronounce 'a' -- if not need, remove the rules and change "B-Z" to "A-Z" - # some languages say the word for "uppercase" after the letter. Make sure to change that where appropriate by moving some code around - - "a-z": - - test: - if: "$TTS='none'" - then: [T: "."] - else: [spell: "'.'"] - - "A-Z": - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "mayúscula"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] - - - "0-9": [T: "."] # (en: '.') - - - " ": [t: " "] # 0x20 - - - "!": [T: "factorial"] # 0x21 - - "\"": [T: "barra inversa"] # 0x22 (en: 'quotation mark') - - "#": [T: "almohadilla"] # 0x23 (en: 'number', MathPlayer: 'signo de número', google: 'número') - - "$": [T: "dólar"] # 0x24 (en: 'dollars') - - "%": [T: "porciento"] # 0x25 (en: 'percent') - - "&": [T: "ampersand"] # 0x26 - - "'": [T: "apóstrofo"] # 0x27 (en: 'apostrophe', MathPlayer: 'apóstrofo', google: 'apóstrofe') - - "(": # 0x28 - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then_test: - if: "$Verbosity='Terse'" - then: [T: "abrir paréntesis"] # (en: 'open', google translation) - else: [T: "se abren paréntesis"] # (en: 'open paren', MathPlayer: 'paréntesis', google: 'paréntesis abierto') - else: [T: "se abren paréntesis"] # (en: 'left paren', MathPlayer: 'paréntesis', google: 'paréntesis dejado') - - ")": # 0x29 - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then_test: - if: "$Verbosity='Terse'" - then: [T: "cerrar paréntesis"] # (en: 'close', google translation) - else: [T: "se cierran paréntesis"] # (en: 'close paren', MathPlayer: 'cierra paréntesis', google: 'paréntesis cercana') - else: [T: "se cierran paréntesis"] # (en: 'right paren', MathPlayer: 'cierra paréntesis') - - - "*": # 0x2a - test: - if: "parent::*[name(.)='msup' or name(.)='msubsup']" - then: [T: "estrella"] # (en: 'star', google translation) - else: [T: "por"] # (en: 'times') - - "+": [T: "más"] # 0x2b (en: 'plus') - - ",": # 0x2c - # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent - # that this test is here and not with "…" is not ideal, but seems simplest - test: - if: - - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " - # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' - # speak "comma" when not adjacent to '…' - - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " - # except if expression starts with '…' - - "../*[1][.='…'] " - then: - - T: "coma" # (en: 'comma', google translation) - - test: - if: "$Verbosity != Terse" - then: [pause: short] - # else silent - - - "-": [T: "menos"] # 0x2d (en: 'minus') - - ".": # 0x2e - - test: - if: "parent::*[1][self::m:mn]" - then: [T: "punto"] # (en: 'point', google translation) - else: [T: "punto"] # (en: 'dot') - - "/": [T: "barra oblicua"] # 0x2f (en: 'divided by') - - ":": [T: "dos puntos"] # 0x3a (en: 'colon') - - ";": [T: "punto y coma"] # 0x3b (en: 'semicolon') - - "<": # 0x3c - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "menor que" # (en: 'less than') - - "=": # 0x3d - - test: - if: "$Verbosity!='Terse'" - then: [T: "es igual a"] # (en: 'is equal to', google translation) - else: [T: "igual a"] # (en: 'equals', google: 'iguales') - - - ">": # 0x3e - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "mayor que" # (en: 'greater than') - - "?": [T: "interrogación derecha"] # 0x3f (en: 'question mark', MathPlayer: 'cierra interrogación', google: 'signo de interrogación') - - "@": [T: "arroba"] # 0x40 (en: 'at sign') - - "[": # 0x5b - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "abrir corchetes"] # (en: 'open bracket', google translation) - else: [T: "se abren corchetes"] # (en: 'left bracket', MathPlayer: 'abre corchetes', google: 'soporte izquierdo') - - "\\": [T: "se abren corchetes"] # 0x5c (en: 'back slash', MathPlayer: 'abre corchetes', google: 'back slash') - - "]": # 0x5d - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "cerrar corchetes"] # (en: 'close bracket', google translation) - else: [T: "se cierran corchetes"] # (en: 'right bracket', MathPlayer: 'cierra corchetes', google: 'soporte derecho') - - "^": [T: "acento circunflejo"] # 0x5e (en: 'hat') - - "_": [T: "subrayado"] # 0x5f (en: 'under bar') - - "`": [T: "acento grave"] # 0x60 (en: 'grave') - - "{": # 0x7b - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "abrir llaves"] # (en: 'open brace', google translation) - else: [T: "se abren llaves"] # (en: 'left brace', MathPlayer: 'abre llaves', google: 'abrazadera izquierda') - - "|": # 0x7c - # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' - - test: - - if: "$SpeechStyle != 'ClearSpeak' or not(preceding-sibling::*) or not(following-sibling::*)" - then: [T: "barra vertical"] # (en: 'vertical line', google translation) - - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" - then: [T: "tal que"] # (en: 'such that', google translation) - - else_if: "$ClearSpeak_VerticalLine = 'Given'" - then: [T: "dado"] # (en: 'given', google translation) - - else: [T: "barra vertical"] # (en: 'divides') - - - "}": # 0x7d - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "cerrar llaves"] # (en: 'close brace', google translation) - else: [T: "se cierran llaves"] # (en: 'right brace', MathPlayer: 'cierra llaves', google: 'abrazadera derecha') - - - "~": [T: "tilde"] # 0x7e - - " ": # 0xa0 - - test: - if: "@data-empty-in-2D" - then: [T: "vacío"] # want to say something for fraction (etc) with empty child (en: 'empty', google translation) - else: [T: ""] - - - "¢": [T: "centavo"] # 0xa2 (en: 'cents') - - "£": [T: "libra esterlina"] # 0xa3 (en: 'pounds') - - "¬": [T: "no"] # 0xac (en: 'not') - - "°": [T: "grado"] # 0xb0 (en: 'degrees') - - "±": [T: "más menos"] # 0xb1 (en: 'plus or minus') - - "´": [T: "acento agudo"] # 0xb4 (en: 'acute') - - "·": # 0xB7 - - test: - if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolDot = 'Auto'" - then_test: - if: "$Verbosity = 'Verbose'" - then: [T: "multiplicado por"] # (en: 'times', google translation) - else: [T: "por"] - else: [T: "punto medio"] # (en: 'dot') - - "×": # 0xd7 - - test: - if: "$Verbosity = 'Verbose'" - then: [T: "multiplicado por"] # (en: 'times', google translation) - else: [T: "por"] - - "÷": [T: "dividido por"] # 0xf7 (en: 'divided by') - - "̀": [T: "acento grave ornamentado"] # 0x300 (en: 'grave accent embellishment', google: 'embellido de acento grave') - - "́": [T: "acento agudo ornamentado"] # 0x301 (en: 'acute accent embellishment', google: 'embellido de acento agudo') - - "̂": [T: "acento circunflejo ornamentado"] # 0x302 (en: 'circumflex accent embellishment', google: 'embellamiento del acento circunflejo') - - "̃": [T: "tilde ornamentada"] # 0x303 (en: 'tilde embellishment', google: 'tilde adorno') - - "̄": [T: "barra ornamentada"] # 0x304 (en: 'macron embellishment', google: 'embellido de macron') - - "̅": [T: "barra encima con adorno"] # 0x305 (en: 'overbar embellishment', google: 'embellido de overbar') - - "̆": [T: "breve"] # 0x306 - - "̇": [T: "punto encima con adorno"] # 0x307 (en: 'dot above embellishment', google: 'punto por encima del adorno') - - # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong - - "Α-Ω": - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "mayúscula"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [spell: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] - - - "α": [T: "alfa"] # 0x3b1 (en: 'alpha') - - "β": [T: "beta"] # 0x3b2 - - "γ": [T: "gamma"] # 0x3b3 (google: 'gama') - - "δ": [T: "delta"] # 0x3b4 - - "ε": [T: "épsilon"] # 0x3b5 (en: 'epsilon', google: 'epsilon') - - "ζ": [T: "zeta"] # 0x3b6 - - "η": [T: "eta"] # 0x3b7 - - "θ": [T: "theta"] # 0x3b8 - - "ι": [T: "iota"] # 0x3b9 - - "κ": [T: "kappa"] # 0x3ba - - "λ": [T: "lambda"] # 0x3bb - - "μ": [T: "my"] # 0x3bc (en: 'mu', google: 'mu') - - "ν": [T: "ny"] # 0x3bd (en: 'nu', google: 'nu') - - "ξ": [T: "xi"] # 0x3be (en: 'zai', google: 'zai') - - "ο": [T: "ómicron"] # 0x3bf (en: 'omicron', google: 'omicron') - - "π": [T: "pi"] # 0x3c0 - - "ρ": [T: "rho"] # 0x3c1 - - "ς": [T: "sigma final"] # 0x3c2 (en: 'final sigma', google: 'final sigma') - - "σ": [T: "sigma"] # 0x3c3 - - "τ": [T: "tau"] # 0x3c4 - - "υ": [T: "ípsilon"] # 0x3c5 (en: 'upsilon', google: 'upsilon') - - "φ": [T: "phi"] # 0x3c6 (google: 'fi') - - "χ": [T: "ji"] # 0x3c7 (en: 'chi', google: 'chi') - - "ψ": [T: "psi"] # 0x3c8 - - "ω": [T: "omega"] # 0x3c9 - - "ϕ": [T: "phi recta"] # 0x3d5 (en: 'phi', google: 'fi') - - "ϖ": [T: "variante de pi"] # 0x3d6 (en: 'pi', google: 'pi') - - "ϵ": [T: "variante de épsilon"] # 0x3f5 (en: 'epsilon', google: 'epsilon') - - "϶": [T: "épsilon invertida"] # 0x3f6 (en: 'reversed epsilon') - - - "⁢": [T: ""] # 0x2062 - - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" - - T: "prima inversa" # (en: 'double-struck', google: 'doble golpe') - - spell: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" - - - "℃": [T: "grados Celsius"] # 0x2103 (en: 'degrees celsius', google: 'grados celsius') - - "ℋℛℓ": # 0x210b - - T: "grados Fahrenheit" # (en: 'script', google: 'guion') - - spell: "translate('.', 'ℋℛℓ', 'HRl')" - - "ℜ": # 0x211c - - T: "r mayúscula partida" # (en: 'fraktur', google: 'fraktur') - - spell: "'R'" - - - "ⅆⅇⅈⅉ": # 0x2146-9 - - T: "angstrom resaltado" # (en: 'double-struck italic') - - spell: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" - - - "∥": # 0x2225 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "paralelo a" # (en: 'parallel to') - - "∦": # 0x2226 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no paralela a" # (en: 'not parallel to') - - "≤": # 0x2264 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "menor o igual a" - - "≥": # 0x2265 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "mayor o igual a" # (en: 'greater than or equal to') - - # --- restored complex short definitions (prefer over unicode-full) --- - - "…": # 0x2026 - test: - if: - - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" - # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' - # speak '…' as 'and so on...' unless expr starts with '…' - - "../*[1][.='…']" - then: [T: "puntos suspensivos"] # (en: 'dot dot dot', google translation) - else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' - if: "count(following-sibling::*) = 0" - then: [T: "etcétera"] # (en: 'and so on', google translation) - else: [T: "puntos suspensivos"] # (en: 'and so on up to', MathPlayer: 'punto punteado punteado', google: 'y así sucesivamente') - - "⁡": # 0x2061 - - test: - # skip saying "of" when Terse and a trig function, when it is a shape (does this happen?), or we are in :literal mode - if: "not( - ( $Verbosity='Terse' or ($SpeechStyle = 'ClearSpeak' and IsNode(following-sibling::*[1],'simple')) and - preceding-sibling::*[1][IfThenElse($SpeechStyle='ClearSpeak', - IsInDefinition(., 'ClearSpeakTrigFunctionNames'), - IsInDefinition(., 'TrigFunctionNames') )] - ) or - preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')] or - (@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) - )" - then: [T: "de"] # (en: 'of', google translation) - - "→": # 0x2192 - - test: - if: "ancestor::*[2][self::m:limit]" - then: [T: "aproximaciones"] # (en: 'approaches', google translation) - else: [T: "flecha derecha"] # (en: 'right arrow', MathPlayer: 'flecha', google: 'flecha correcta') - - "∂": # 0x2202 - - test: - if: "$Verbosity='Terse'" - then: [T: "parcial"] # (en: 'partial', google translation) - else: [T: "derivada parcial"] # (en: 'partial derivative') - - "∆": # 0x2206 - - test: - if: "$Verbosity!='Terse'" - then: [T: "el"] # (en: 'the', google translation) - - T: "incremento" # (en: 'laplacian of') - - "∈": # 0x2208 - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: [T: "un elemento de"] # (en: 'an element of', google translation) - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "en"] # (en: 'in', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "miembro de"] # (en: 'member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "elemento de"] # (en: 'element of', google translation) - - else: [T: "pertenece a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "es miembro de"] # (en: 'is a member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "es un elemento de"] # (en: 'is an element of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "está en"] # (en: 'is in', google translation) - - else: [T: "pertenece a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') - - "∉": # 0x2209 - # rule is identical to 0x2208 - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: [T: "no es un elemento de"] # (en: 'is not an element of', google translation) - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "no está en"] # (en: 'not in', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "no es miembro de"] # (en: 'not member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "no es un elemento de"] # (en: 'not element of', google translation) - - else: [T: "no pertenece a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to') - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "no es miembro de"] # (en: 'is not a member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "no es un elemento de"] # (en: 'is not an element of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "no está incluido en"] # (en: 'is not in', google translation) - - else: [T: "no pertenece a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to') - - "∊": # 0x220a - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: [T: "es un elemento de"] # (en: 'is an element of', google translation) - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "en"] # (en: 'in', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "miembro de"] # (en: 'member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "elemento de"] # (en: 'element of', google translation) - - else: [T: "pertenece a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "es miembro de"] # (en: 'is a member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "es un elemento de"] # (en: 'is an element of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "está en"] # (en: 'is in', google translation) - - else: [T: "pertenece a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') - - "√": # 0x221a - - test: - if: "$Verbosity!='Terse'" - then: [T: "el"] # (en: 'the', google translation) - - T: "raíz cuadrada de" # (en: 'square root of') - - "∝": # 0x221d - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "proporcional a" # (en: 'proportional to') - - "∶": # 0x2236 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "a" # (en: 'to') - - "∾": # 0x223e - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "más positivo" # (en: 'most positive') - - "≠": # 0x2260 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no es igual a" # (en: 'not equal to', MathPlayer: 'distinto de', google: 'no igual a') - - "≡": # 0x2261 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "idéntico a" # (en: 'identical to') - - "⊂": # 0x2282 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es un"] # (en: 'is a', google translation) - - T: "subconjunto de" # (en: 'subset of') - - "⊃": # 0x2283 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es un"] # (en: 'is a', google translation) - - T: "superconjunto de" # (en: 'superset of') - - "⊄": # 0x2284 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no es un subconjunto de" # (en: 'not a subset of') - - "⊅": # 0x2285 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es"] # (en: 'is', google translation) - - T: "no esun superconjunto de" # (en: 'not a superset of') - - "⊆": # 0x2286 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es un"] # (en: 'is a', google translation) - - T: "subconjunto o igual a" # (en: 'subset of or equal to') - - "⊇": # 0x2287 - - test: - if: "$Verbosity!='Terse'" - then: [T: "es un"] # (en: 'is a', google translation) - - T: "superconjunto o igual a" # (en: 'superset of or equal to') - - # --- restored short definitions that differ from unicode-full --- - - "–": [T: "ene raya"] # 0x2013 (en: 'en dash') - - "—": [T: "eme raya"] # 0x2014 (en: 'em dash') - - "‖": [T: "barra vertical doble"] # 0x2016 (en: 'double vertical line') - - "″": [T: "segunda"] # 0x2033 (en: 'double prime', MathPlayer: 'segunda', google: 'doble primo') - - "‴": [T: "tercera"] # 0x2034 (en: 'triple prime', MathPlayer: 'tercera', google: 'triple prime') - - "‵": [T: "prima inversa"] # 0x2035 (en: 'reversed prime') - - "‶": [T: "segunda inversa"] # 0x2036 (en: 'reversed double prime') - - "‷": [T: "tercera inversa"] # 0x2037 (en: 'reversed triple prime', google: 'triple prime invertido') - - "℉": [T: "grados Fahrenheit"] # 0x2109 (en: 'degrees fahrenheit') - - "ℎ": [T: "constante de Planck"] # 0x210e (en: 'planck constant', MathPlayer: 'constante de Planck', google: 'planck constante') - - "K": [T: "grados Kelvin"] # 0x212a (en: 'kelvin') - - "←": [T: "flecha izquierda"] # 0x2190 (en: 'leftwards arrow') - - "↑": [T: "flecha arriba"] # 0x2191 (en: 'upwards arrow') - - "↓": [T: "flecha abajo"] # 0x2193 (en: 'downwards arrow') - - "⇒": [T: "flecha doble derecha"] # 0x21d2 (en: 'rightwards double arrow') - - "∘": [T: "compuesto"] # 0x2218 (en: 'composed with') - - "∣": [T: "divisible"] # 0x2223 (en: 'divides') - - "∤": [T: "indivisible"] # 0x2224 (en: 'does not divide') - - "∷": [T: "como"] # 0x2237 (en: 'as') - - "∼": [T: "distinto de"] # 0x223c (en: 'varies with') - - "∽": [T: "tilde inversa"] # 0x223d (en: 'reversed tilde') - - "∿": [T: "onda sinusoidal"] # 0x223f (en: 'sine wave') - - "≦": [T: "menor o igual a"] # 0x2266 (en: 'less than over equal to') - - "≧": [T: "mayor o igual a"] # 0x2267 (en: 'greater than over equal to') +--- + # Note to translators: + # most languages don't have two ways to pronounce 'a' -- if not need, remove the rules and change "B-Z" to "A-Z" + # some languages say the word for "uppercase" after the letter. Make sure to change that where appropriate by moving some code around + - "a-z": + - test: + if: "$TTS='none'" + then: [T: "."] + else: [spell: "'.'"] + - "A-Z": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "mayúscula"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] + + - "0-9": [T: "."] # (en: '.') + + - " ": [t: " "] # 0x20 + + - "!": [T: "factorial"] # 0x21 + - "\"": [T: "barra inversa"] # 0x22 (en: 'quotation mark') + - "#": [T: "almohadilla"] # 0x23 (en: 'number', MathPlayer: 'signo de número', google: 'número') + - "$": [T: "dólar"] # 0x24 (en: 'dollars') + - "%": [T: "porciento"] # 0x25 (en: 'percent') + - "&": [T: "ampersand"] # 0x26 + - "'": [T: "apóstrofo"] # 0x27 (en: 'apostrophe', MathPlayer: 'apóstrofo', google: 'apóstrofe') + - "(": # 0x28 + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [T: "abrir paréntesis"] # (en: 'open', google translation) + else: [T: "se abren paréntesis"] # (en: 'open paren', MathPlayer: 'paréntesis', google: 'paréntesis abierto') + else: [T: "se abren paréntesis"] # (en: 'left paren', MathPlayer: 'paréntesis', google: 'paréntesis dejado') + - ")": # 0x29 + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [T: "cerrar paréntesis"] # (en: 'close', google translation) + else: [T: "se cierran paréntesis"] # (en: 'close paren', MathPlayer: 'cierra paréntesis', google: 'paréntesis cercana') + else: [T: "se cierran paréntesis"] # (en: 'right paren', MathPlayer: 'cierra paréntesis') + + - "*": # 0x2a + test: + if: "parent::*[name(.)='msup' or name(.)='msubsup']" + then: [T: "estrella"] # (en: 'star', google translation) + else: [T: "por"] # (en: 'times') + - "+": [T: "más"] # 0x2b (en: 'plus') + - ",": # 0x2c + # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent + # that this test is here and not with "…" is not ideal, but seems simplest + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak "comma" when not adjacent to '…' + - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " + # except if expression starts with '…' + - "../*[1][.='…'] " + then: + - T: "coma" # (en: 'comma', google translation) + - test: + if: "$Verbosity != Terse" + then: [pause: short] + # else silent + + - "-": [T: "menos"] # 0x2d (en: 'minus') + - ".": # 0x2e + - test: + if: "parent::*[1][self::m:mn]" + then: [T: "punto"] # (en: 'point', google translation) + else: [T: "punto"] # (en: 'dot') + - "/": [T: "barra oblicua"] # 0x2f (en: 'divided by') + - ":": [T: "dos puntos"] # 0x3a (en: 'colon') + - ";": [T: "punto y coma"] # 0x3b (en: 'semicolon') + - "<": # 0x3c + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "menor que" # (en: 'less than') + - "=": # 0x3d + - test: + if: "$Verbosity!='Terse'" + then: [T: "es igual a"] # (en: 'is equal to', google translation) + else: [T: "igual a"] # (en: 'equals', google: 'iguales') + + - ">": # 0x3e + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "mayor que" # (en: 'greater than') + - "?": [T: "interrogación derecha"] # 0x3f (en: 'question mark', MathPlayer: 'cierra interrogación', google: 'signo de interrogación') + - "@": [T: "arroba"] # 0x40 (en: 'at sign') + - "[": # 0x5b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "abrir corchetes"] # (en: 'open bracket', google translation) + else: [T: "se abren corchetes"] # (en: 'left bracket', MathPlayer: 'abre corchetes', google: 'soporte izquierdo') + - "\\": [T: "se abren corchetes"] # 0x5c (en: 'back slash', MathPlayer: 'abre corchetes', google: 'back slash') + - "]": # 0x5d + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "cerrar corchetes"] # (en: 'close bracket', google translation) + else: [T: "se cierran corchetes"] # (en: 'right bracket', MathPlayer: 'cierra corchetes', google: 'soporte derecho') + - "^": [T: "acento circunflejo"] # 0x5e (en: 'hat') + - "_": [T: "subrayado"] # 0x5f (en: 'under bar') + - "`": [T: "acento grave"] # 0x60 (en: 'grave') + - "{": # 0x7b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "abrir llaves"] # (en: 'open brace', google translation) + else: [T: "se abren llaves"] # (en: 'left brace', MathPlayer: 'abre llaves', google: 'abrazadera izquierda') + - "|": # 0x7c + # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' + - test: + - if: "$SpeechStyle != 'ClearSpeak' or not(preceding-sibling::*) or not(following-sibling::*)" + then: [T: "barra vertical"] # (en: 'vertical line', google translation) + - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" + then: [T: "tal que"] # (en: 'such that', google translation) + - else_if: "$ClearSpeak_VerticalLine = 'Given'" + then: [T: "dado"] # (en: 'given', google translation) + - else: [T: "barra vertical"] # (en: 'divides') + + - "}": # 0x7d + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "cerrar llaves"] # (en: 'close brace', google translation) + else: [T: "se cierran llaves"] # (en: 'right brace', MathPlayer: 'cierra llaves', google: 'abrazadera derecha') + + - "~": [T: "tilde"] # 0x7e + - " ": # 0xa0 + - test: + if: "@data-empty-in-2D" + then: [T: "vacío"] # want to say something for fraction (etc) with empty child (en: 'empty', google translation) + else: [T: ""] + + - "¢": [T: "centavo"] # 0xa2 (en: 'cents') + - "£": [T: "libra esterlina"] # 0xa3 (en: 'pounds') + - "¬": [T: "no"] # 0xac (en: 'not') + - "°": [T: "grado"] # 0xb0 (en: 'degrees') + - "±": [T: "más menos"] # 0xb1 (en: 'plus or minus') + - "´": [T: "acento agudo"] # 0xb4 (en: 'acute') + - "·": # 0xB7 + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolDot = 'Auto'" + then_test: + if: "$Verbosity = 'Verbose'" + then: [T: "multiplicado por"] # (en: 'times', google translation) + else: [T: "por"] + else: [T: "punto medio"] # (en: 'dot') + - "×": # 0xd7 + - test: + if: "$Verbosity = 'Verbose'" + then: [T: "multiplicado por"] # (en: 'times', google translation) + else: [T: "por"] + - "÷": [T: "dividido por"] # 0xf7 (en: 'divided by') + - "̀": [T: "acento grave ornamentado"] # 0x300 (en: 'grave accent embellishment', google: 'embellido de acento grave') + - "́": [T: "acento agudo ornamentado"] # 0x301 (en: 'acute accent embellishment', google: 'embellido de acento agudo') + - "̂": [T: "acento circunflejo ornamentado"] # 0x302 (en: 'circumflex accent embellishment', google: 'embellamiento del acento circunflejo') + - "̃": [T: "tilde ornamentada"] # 0x303 (en: 'tilde embellishment', google: 'tilde adorno') + - "̄": [T: "barra ornamentada"] # 0x304 (en: 'macron embellishment', google: 'embellido de macron') + - "̅": [T: "barra encima con adorno"] # 0x305 (en: 'overbar embellishment', google: 'embellido de overbar') + - "̆": [T: "breve"] # 0x306 + - "̇": [T: "punto encima con adorno"] # 0x307 (en: 'dot above embellishment', google: 'punto por encima del adorno') + + # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong + - "Α-Ω": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "mayúscula"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [spell: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] + + - "α": [T: "alfa"] # 0x3b1 (en: 'alpha') + - "β": [T: "beta"] # 0x3b2 + - "γ": [T: "gamma"] # 0x3b3 (google: 'gama') + - "δ": [T: "delta"] # 0x3b4 + - "ε": [T: "épsilon"] # 0x3b5 (en: 'epsilon', google: 'epsilon') + - "ζ": [T: "zeta"] # 0x3b6 + - "η": [T: "eta"] # 0x3b7 + - "θ": [T: "theta"] # 0x3b8 + - "ι": [T: "iota"] # 0x3b9 + - "κ": [T: "kappa"] # 0x3ba + - "λ": [T: "lambda"] # 0x3bb + - "μ": [T: "my"] # 0x3bc (en: 'mu', google: 'mu') + - "ν": [T: "ny"] # 0x3bd (en: 'nu', google: 'nu') + - "ξ": [T: "xi"] # 0x3be (en: 'zai', google: 'zai') + - "ο": [T: "ómicron"] # 0x3bf (en: 'omicron', google: 'omicron') + - "π": [T: "pi"] # 0x3c0 + - "ρ": [T: "rho"] # 0x3c1 + - "ς": [T: "sigma final"] # 0x3c2 (en: 'final sigma', google: 'final sigma') + - "σ": [T: "sigma"] # 0x3c3 + - "τ": [T: "tau"] # 0x3c4 + - "υ": [T: "ípsilon"] # 0x3c5 (en: 'upsilon', google: 'upsilon') + - "φ": [T: "phi"] # 0x3c6 (google: 'fi') + - "χ": [T: "ji"] # 0x3c7 (en: 'chi', google: 'chi') + - "ψ": [T: "psi"] # 0x3c8 + - "ω": [T: "omega"] # 0x3c9 + - "ϕ": [T: "phi recta"] # 0x3d5 (en: 'phi', google: 'fi') + - "ϖ": [T: "variante de pi"] # 0x3d6 (en: 'pi', google: 'pi') + - "ϵ": [T: "variante de épsilon"] # 0x3f5 (en: 'epsilon', google: 'epsilon') + - "϶": [T: "épsilon invertida"] # 0x3f6 (en: 'reversed epsilon') + + - "⁢": [T: ""] # 0x2062 + - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" + - T: "prima inversa" # (en: 'double-struck', google: 'doble golpe') + - spell: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" + + - "℃": [T: "grados Celsius"] # 0x2103 (en: 'degrees celsius', google: 'grados celsius') + - "ℋℛℓ": # 0x210b + - T: "grados Fahrenheit" # (en: 'script', google: 'guion') + - spell: "translate('.', 'ℋℛℓ', 'HRl')" + - "ℜ": # 0x211c + - T: "r mayúscula partida" # (en: 'fraktur', google: 'fraktur') + - spell: "'R'" + + - "ⅆⅇⅈⅉ": # 0x2146-9 + - T: "angstrom resaltado" # (en: 'double-struck italic') + - spell: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" + + - "∥": # 0x2225 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "paralelo a" # (en: 'parallel to') + - "∦": # 0x2226 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no paralela a" # (en: 'not parallel to') + - "≤": # 0x2264 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "menor o igual a" + - "≥": # 0x2265 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "mayor o igual a" # (en: 'greater than or equal to') + + # --- restored complex short definitions (prefer over unicode-full) --- + - "…": # 0x2026 + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak '…' as 'and so on...' unless expr starts with '…' + - "../*[1][.='…']" + then: [T: "puntos suspensivos"] # (en: 'dot dot dot', google translation) + else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' + if: "count(following-sibling::*) = 0" + then: [T: "etcétera"] # (en: 'and so on', google translation) + else: [T: "puntos suspensivos"] # (en: 'and so on up to', MathPlayer: 'punto punteado punteado', google: 'y así sucesivamente') + - "⁡": # 0x2061 + - test: + # skip saying "of" when Terse and a trig function, when it is a shape (does this happen?), or we are in :literal mode + if: "not( + ( $Verbosity='Terse' or ($SpeechStyle = 'ClearSpeak' and IsNode(following-sibling::*[1],'simple')) and + preceding-sibling::*[1][IfThenElse($SpeechStyle='ClearSpeak', + IsInDefinition(., 'ClearSpeakTrigFunctionNames'), + IsInDefinition(., 'TrigFunctionNames') )] + ) or + preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')] or + (@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) + )" + then: [T: "de"] # (en: 'of', google translation) + - "→": # 0x2192 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "aproximaciones"] # (en: 'approaches', google translation) + else: [T: "flecha derecha"] # (en: 'right arrow', MathPlayer: 'flecha', google: 'flecha correcta') + - "∂": # 0x2202 + - test: + if: "$Verbosity='Terse'" + then: [T: "parcial"] # (en: 'partial', google translation) + else: [T: "derivada parcial"] # (en: 'partial derivative') + - "∆": # 0x2206 + - test: + if: "$Verbosity!='Terse'" + then: [T: "el"] # (en: 'the', google translation) + - T: "incremento" # (en: 'laplacian of') + - "∈": # 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: [T: "un elemento de"] # (en: 'an element of', google translation) + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "en"] # (en: 'in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "miembro de"] # (en: 'member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "elemento de"] # (en: 'element of', google translation) + - else: [T: "pertenece a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "es miembro de"] # (en: 'is a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "es un elemento de"] # (en: 'is an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "está en"] # (en: 'is in', google translation) + - else: [T: "pertenece a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - "∉": # 0x2209 + # rule is identical to 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: [T: "no es un elemento de"] # (en: 'is not an element of', google translation) + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "no está en"] # (en: 'not in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "no es miembro de"] # (en: 'not member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "no es un elemento de"] # (en: 'not element of', google translation) + - else: [T: "no pertenece a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "no es miembro de"] # (en: 'is not a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "no es un elemento de"] # (en: 'is not an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "no está incluido en"] # (en: 'is not in', google translation) + - else: [T: "no pertenece a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to') + - "∊": # 0x220a + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: [T: "es un elemento de"] # (en: 'is an element of', google translation) + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "en"] # (en: 'in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "miembro de"] # (en: 'member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "elemento de"] # (en: 'element of', google translation) + - else: [T: "pertenece a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "es miembro de"] # (en: 'is a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "es un elemento de"] # (en: 'is an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "está en"] # (en: 'is in', google translation) + - else: [T: "pertenece a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - "√": # 0x221a + - test: + if: "$Verbosity!='Terse'" + then: [T: "el"] # (en: 'the', google translation) + - T: "raíz cuadrada de" # (en: 'square root of') + - "∝": # 0x221d + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "proporcional a" # (en: 'proportional to') + - "∶": # 0x2236 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "a" # (en: 'to') + - "∾": # 0x223e + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "más positivo" # (en: 'most positive') + - "≠": # 0x2260 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no es igual a" # (en: 'not equal to', MathPlayer: 'distinto de', google: 'no igual a') + - "≡": # 0x2261 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "idéntico a" # (en: 'identical to') + - "⊂": # 0x2282 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es un"] # (en: 'is a', google translation) + - T: "subconjunto de" # (en: 'subset of') + - "⊃": # 0x2283 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es un"] # (en: 'is a', google translation) + - T: "superconjunto de" # (en: 'superset of') + - "⊄": # 0x2284 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no es un subconjunto de" # (en: 'not a subset of') + - "⊅": # 0x2285 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es"] # (en: 'is', google translation) + - T: "no esun superconjunto de" # (en: 'not a superset of') + - "⊆": # 0x2286 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es un"] # (en: 'is a', google translation) + - T: "subconjunto o igual a" # (en: 'subset of or equal to') + - "⊇": # 0x2287 + - test: + if: "$Verbosity!='Terse'" + then: [T: "es un"] # (en: 'is a', google translation) + - T: "superconjunto o igual a" # (en: 'superset of or equal to') + + # --- restored short definitions that differ from unicode-full --- + - "–": [T: "ene raya"] # 0x2013 (en: 'en dash') + - "—": [T: "eme raya"] # 0x2014 (en: 'em dash') + - "‖": [T: "barra vertical doble"] # 0x2016 (en: 'double vertical line') + - "″": [T: "segunda"] # 0x2033 (en: 'double prime', MathPlayer: 'segunda', google: 'doble primo') + - "‴": [T: "tercera"] # 0x2034 (en: 'triple prime', MathPlayer: 'tercera', google: 'triple prime') + - "‵": [T: "prima inversa"] # 0x2035 (en: 'reversed prime') + - "‶": [T: "segunda inversa"] # 0x2036 (en: 'reversed double prime') + - "‷": [T: "tercera inversa"] # 0x2037 (en: 'reversed triple prime', google: 'triple prime invertido') + - "℉": [T: "grados Fahrenheit"] # 0x2109 (en: 'degrees fahrenheit') + - "ℎ": [T: "constante de Planck"] # 0x210e (en: 'planck constant', MathPlayer: 'constante de Planck', google: 'planck constante') + - "K": [T: "grados Kelvin"] # 0x212a (en: 'kelvin') + - "←": [T: "flecha izquierda"] # 0x2190 (en: 'leftwards arrow') + - "↑": [T: "flecha arriba"] # 0x2191 (en: 'upwards arrow') + - "↓": [T: "flecha abajo"] # 0x2193 (en: 'downwards arrow') + - "⇒": [T: "flecha doble derecha"] # 0x21d2 (en: 'rightwards double arrow') + - "∘": [T: "compuesto"] # 0x2218 (en: 'composed with') + - "∣": [T: "divisible"] # 0x2223 (en: 'divides') + - "∤": [T: "indivisible"] # 0x2224 (en: 'does not divide') + - "∷": [T: "como"] # 0x2237 (en: 'as') + - "∼": [T: "distinto de"] # 0x223c (en: 'varies with') + - "∽": [T: "tilde inversa"] # 0x223d (en: 'reversed tilde') + - "∿": [T: "onda sinusoidal"] # 0x223f (en: 'sine wave') + - "≦": [T: "menor o igual a"] # 0x2266 (en: 'less than over equal to') + - "≧": [T: "mayor o igual a"] # 0x2267 (en: 'greater than over equal to') diff --git a/Rules/Languages/fi/unicode-full.yaml b/Rules/Languages/fi/unicode-full.yaml index a43408b28..cb48cd1cd 100644 --- a/Rules/Languages/fi/unicode-full.yaml +++ b/Rules/Languages/fi/unicode-full.yaml @@ -1,3435 +1,3435 @@ ---- - -# Translated with the help of https://jkorpela.fi/merkkien-nimet.html - - - "¢": [T: "senttiä"] # 0xa2 (en: 'cents') - - "£": [T: "puntaa"] # 0xa3 (en: 'pounds') - - "¤": [T: "valuuttamerkki"] # 0xa4 (en: 'currency sign') - - "¥": [T: "jeni"] # 0xa5 (en: 'yen', google: 'jeni') - - "¦": [T: "katkopystyviiva"] # 0xa6 (en: 'broken bar', google: 'rikkoutunut palkki') - - "§": [T: "pykälä"] # 0xa7 (en: 'section', google: 'osa') - - "¨": [T: "piste piste"] # 0xa8 (en: 'double dot', google: 'kaksinkertainen piste') # FI: use case with derivative? - - "©": [T: "tekijänoikeus"] # 0xa9 (en: 'copyright', google: 'tekijänoikeudet') # FI: in NVDA it's written "copyright" - - "ª": [T: "feminiininen järjestysluku"] # 0xaa (en: 'feminine ordinal indicator', google: 'naisellinen ordinaaliindikaattori') - - "«": [T: "vasemmalle osoittava kaksinkertainen kulmalainausmerkki"] # 0xab (en: 'left-pointing double angle quote mark', google: 'vasemman potentiaalinen kaksoiskulma lainausmerkki') - - "¯": # 0xaf - - test: - if: "ancestor::m:modified-variable and preceding-sibling::*[1][self::m:mi]" - then: [T: "viiva"] # (en: 'bar', google translation) - else: [T: "viiva"] # (en: 'line', google: 'linja') - - "²": [T: "yläindeksi kaksi"] # 0xb2 (en: 'two', google: 'kaksi') - - "³": [T: "yläindeksi kolme"] # 0xb3 (en: 'three', google: 'kolme') - - "µ": [T: "mikro"] # 0xb5 (en: 'micro') - - "¹": [T: "yläindeksi yksi"] # 0xb9 (en: 'one', google: 'yksi') - - "º": [T: "maskuliininen järjestysluku"] # 0xb9 (en: 'masculine ordinal indicator', google: 'maskuliininen ordinaaliindikaattori') # should be 0xba - - "ʰ": [T: "yläindeksi h"] # 0x2b0 (en: 'modifier small h', google translation) - - "ʱ": [T: "yläindeksi h koukulla"] # 0x2b1 (en: 'modifier small h with hook', google translation) - - "ʲ": [T: "yläindeksi j"] # 0x2b2 (en: 'modifier small j', google translation) - - "ʳ": [T: "yläindeksi r"] # 0x2b3 (en: 'modifier small r', google translation) - - "ʴ": [T: "yläindeksi käännetty r"] # 0x2b4 (en: 'modifier small turned r', google translation) - - "ʵ": [T: "yläindeksi käännetty r koukulla"] # 0x2b5 (en: 'modifier small turned r with hook', google translation) - - "ʶ": # 0x2b6 - - T: "yläindeksi käännetty R" # (en: 'modifier small inverted', google translation) - - SPELL: "translate('R', 'R', 'R')" - - - "ʷ": [T: "yläindeksi w"] # 0x2b7 (en: 'modifier small w', google translation) - - "ʸ": [T: "yläindeksi y"] # 0x2b8 (en: 'modifier small y', google translation) - - "ʹ": [T: "priimi"] # 0x2b9 (en: 'modifier prime', google translation) # FI: derivated once -> "pilkku" - - "ʺ": [T: "kaksoispriimi"] # 0x2ba (en: 'modifier double prime', google translation) # FI: derivated twice -> "pilkku pilkku" - - "ʻ": [T: "käänteispilkku"] # 0x2bb (en: 'modifier turned comma', google translation) - - "ʼ": [T: "heitto"] # 0x2bc (en: 'modifier apostrophe', google translation) - - "ʽ": [T: "peilikuvapilkku"] # 0x2bd (en: 'modifier reversed comma', google translation) - - "ʾ": [T: "tarke oikea puolikaari"] # 0x2be (en: 'modifier right half ring', google: 'muokkain oikea puolirengas') - - "ʿ": [T: "tarke vasen puolikaari"] # 0x2bf (en: 'modifier left half ring', google: 'muokkain vasemmalla puolirengas') - - "ˀ": [T: "glottaaliklusiilitarke"] # 0x2c0 (en: 'modifier glottal stop', google translation) - - "ˁ": [T: "käännetty glottaaliklusiilitarke"] # 0x2c1 (en: 'modifier reversed glottal stop', google translation) - - "˂": [T: "tarke vasen nuoli"] # 0x2c2 (en: 'modifier left arrowhead', google translation) - - "˃": [T: "tarke oikea nuoli"] # 0x2c3 (en: 'modifier right arrowhead', google translation) - - "˄": [T: "tarke nuoli ylös"] # 0x2c4 (en: 'modifier up arrowhead', google translation) - - "˅": [T: "tarke nuoli alas"] # 0x2c5 (en: 'modifier down arrowhead', google translation) - - "ˆ": [T: "sirkumfleksi"] # 0x2c6 (en: 'modifier circumflex accent', google: 'modifikaattorin ympäryssuoja aksentti') # FI: should maybe be "hat", "hattu" - - "ˇ": [T: "ylösalainen sirkumfleksi"] # 0x2c7 (en: 'caron', google: 'caron') # FI: "inverted hat"? "käännetty hattu" - - "ˈ": [T: "tarke pystyviiva"] # 0x2c8 (en: 'modifier vertical line', google translation) - - "ˉ": [T: "pituusmerkki"] # 0x2c9 (en: 'modifier macron', google: 'muokkain macron') - - "ˊ": [T: "tarke akuutti"] # 0x2ca (en: 'modifier acute accent', google translation) - - "ˋ": [T: "tarke gravis"] # 0x2cb (en: 'modifier grave accent', google translation) - - "ˌ": [T: "tarke alapystyviiva"] # 0x2cc (en: 'modifier low vertical line', google translation) - - "ˍ": [T: "alapituusmerkki"] # 0x2cd (en: 'modifier low macron', google translation) - - "ˎ": [T: "alagravis"] # 0x2ce (en: 'modifier low grave accent', google translation) - - "ˏ": [T: "ala-akuutti"] # 0x2cf (en: 'modifier low acute accent', google translation) - - "ː": [T: "kolmiokaksoispiste"] # 0x2d0 (en: 'modifier triangular colon', google translation) - - "ˑ": [T: "puolikas kolmiokaksoispiste"] # 0x2d1 (en: 'modifier half triangular colon', google translation) - - "˒": [T: "keskitetty oikea puolirengas"] # 0x2d2 (en: 'modifier centered right half ring', google translation) - - "˓": [T: "keskitetty vasen puolirengas"] # 0x2d3 (en: 'modifier centered left half ring', google translation) - - "˔": [T: "nupi ylöspäin"] # 0x2d4 (en: 'modifier up tadck', google translation) - - "˕": [T: "nupi alaspäin"] # 0x2d5 (en: 'modifier down tack', google translation) - - "˖": [T: "plus"] # 0x2d6 (en: 'modifier plus sign', google translation) - - "˗": [T: "miinus"] # 0x2d7 (en: 'modifier minus sign', google translation) - - "˘": [T: "lyhyysmerkki"] # 0x2d8 (en: 'breve', google: 'breve') - - "˙": [T: "piste"] # 0x2d9 (en: 'dot', google: 'piste') - - "˚": [T: "yläympyrä"] # 0x2da (en: 'ring above', google: 'rengas yläpuolella') - - "˛": [T: "ogonek"] # 0x2db - - "˜": [T: "pieni tilde"] # 0x2dc (en: 'small tilde', google: 'pieni tilde') - - "˝": [T: "kaksoisakuutti"] # 0x2dd (en: 'double acute accent', google: 'kaksinkertainen akuutti aksentti') - - "˞": [T: "rhoottinen koukku"] # 0x2de (en: 'modifier rhotic hook', google translation) - - "˟": [T: "risti"] # 0x2df (en: 'modifier cross accent', google translation) - - "ˠ": [T: "pieni gamma"] # 0x2e0 (en: 'modifier small gamma', google translation) # FI: should these be without "pieni" ("small")? - - "ˡ": [T: "pieni l"] # 0x2e1 (en: 'modifier small l', google translation) - - "ˢ": [T: "pieni s"] # 0x2e2 (en: 'modifier small s', google translation) - - "ˣ": [T: "pieni x"] # 0x2e3 (en: 'modifier small x', google translation) - - "ˤ": [T: "pieni käännetty glottaaliklusiili"] # 0x2e4 (en: 'modifier small reversed glottal stop', google translation) - - "˥": [T: "erittäin korkea äänipalkki"] # 0x2e5 (en: 'modifier extra-high tone bar', google translation) - - "˦": [T: "korkea äänipalkki"] # 0x2e6 (en: 'modifier high tone bar', google translation) - - "˧": [T: "keskiäänipalkki"] # 0x2e7 (en: 'modifier mid tone bar', google translation) - - "˨": [T: "matala äänipalkki"] # 0x2e8 (en: 'modifier low tone bar', google translation) - - "˩": [T: "erittäin matala äänipalkki"] # 0x2e9 (en: 'modifier extra-low tone bar', google translation) - - "˪": [T: "yin lähtöäänimerkki"] # 0x2ea (en: 'modifier yin departing tone mark', google translation) # FI: unclear - - "˫": [T: "yang lähtöäänimerkki"] # 0x2eb (en: 'modifier yang departing tone mark', google translation) # FI: unclear - - "ˬ": [T: "ääntämismerkki"] # 0x2ec (en: 'modifier voicing', google translation) - - "˭": [T: "aspiroitumattomuusmerkki"] # 0x2ed (en: 'modifier unaspirated', google translation) - - "ˮ": [T: "kaksoisheittomerkki"] # 0x2ee (en: 'modifier double apostrophe', google translation) - - "˯": [T: "alanuolenpää alas"] # 0x2ef (en: 'modifier low down arrowhead', google translation) - - "˰": [T: "alanuolenpää ylös"] # 0x2f0 (en: 'modifier low up arrowhead', google translation) - - "˱": [T: "alanuolenpää vasemmalle"] # 0x2f1 (en: 'modifier low left arrowhead', google translation) - - "˲": [T: "alanuolenpää oikealle"] # 0x2f2 (en: 'modifier low right arrowhead', google translation) - - "˳": [T: "alarengas"] # 0x2f3 (en: 'modifier low ring', google translation) - - "˴": [T: "keskitetty gravis"] # 0x2f4 (en: 'modifier middle grave accent', google translation) - - "˵": [T: "keskitetty tuplagravis"] # 0x2f5 (en: 'modifier middle double grave accent', google translation) - - "˶": [T: "keskitetty akuutti"] # 0x2f6 (en: 'modifier middle double acute accent', google translation) - - "˷": [T: "alatilde"] # 0x2f7 (en: 'modifier low tilde', google translation) - - "˸": [T: "nostettu kaksoispiste"] # 0x2f8 (en: 'modifier raised colon', google translation) - - "˹": [T: "korkea ääni alku"] # 0x2f9 (en: 'modifier begin high tone', google translation) - - "˺": [T: "korkea ääni loppu"] # 0x2fa (en: 'modifier end high tone', google translation) - - "˻": [T: "matala ääni alku"] # 0x2fb (en: 'modifier begin low tone', google translation) - - "˼": [T: "matala ääni loppu"] # 0x2fc (en: 'modifier end low tone', google translation) - - "˽": [T: "tarke hylly"] # 0x2fd (en: 'modifier shelf', google translation) - - "˾": [T: "tarke avoin hylly"] # 0x2fe (en: 'modifier open shelf', google translation) - - "˿": [T: "vasen alanuoli"] # 0x2ff (en: 'modifier low left arrow', google translation) - - "̈": [T: "treema"] # 0x308 (en: 'diaeresis embellishment', google: 'diaeresis -koriste') - - "̉": [T: "yläkoukku"] # 0x309 (en: 'hook above embellishment', google translation) - - "̊": [T: "yläympyrä"] # 0x30a (en: 'ring above embellishment', google: 'rengas koristelun yläpuolella') - - "̋": [T: "kakoisakuutti"] # 0x30b (en: 'double acute accent embellishment', google translation) - - "̌": [T: "hattu"] # 0x30c (en: 'check', google: 'tarkistaa') - - "̍": [T: "yläpuolinen pystyviiva"] # 0x30d (en: 'vertical line above embellishment', google translation) - - "̎": [T: "yläpuolinen kaksoispystyviiva"] # 0x30e (en: 'double vertical line above embellishment', google translation) - - "̏": [T: "kakoisgravis"] # 0x30f (en: 'double grave accent embellishment', google translation) - - "̐": [T: "candrabindu"] # 0x310 (en: 'candrabindu embellishment', google translation) - - "̑": [T: "ylösalainen lyhyysmerkki"] # 0x311 (en: 'inverted breve embellishment', google: 'käänteinen breve -koriste') - - "̒": [T: "yläpuolinen ylösalainen pilkku"] # 0x312 (en: 'turned comma above embellishment', google translation) - - "̓": [T: "yläoikealla oleva pilkku"] # 0x313 (en: 'comma above embellishment', google translation) - - "̔": [T: "yläpuolinen peilikuvapilkku"] # 0x314 (en: 'reversed comma above embellishment', google translation) - - "̕": [T: "yläpilkku"] # 0x315 (en: 'comma above right embellishment', google translation) - - "̖": [T: "alapuolinen gravis"] # 0x316 (en: 'grave accent below embellishment', google translation) - - "̗": [T: "alapuolinen akuutti"] # 0x317 (en: 'acute accent below embellishment', google translation) - - "̘": [T: "alapuolinen vasemmalle osoittava nupi"] # 0x318 (en: 'left tack below embellishment', google translation) - - "̙": [T: "alapuolinen oikealle osoittava nupi"] # 0x319 (en: 'right tack below embellishment', google translation) - - "̚": [T: "yläpuolinen vasen kulma"] # 0x31a (en: 'left angle above embellishment', google translation) - - "̛": [T: "sarvi"] # 0x31b (en: 'horn embellishment', google translation) - - "̜": [T: "alapuolinen vasen ympyränkaari"] # 0x31c (en: 'left half ring below embellishment', google translation) - - "̝": [T: "alapuolinen ylös osoittava nupi"] # 0x31d (en: 'up tack below embellishment', google translation) - - "̞": [T: "alapuolinen alas osoittava nupi"] # 0x31e (en: 'down tack below embellishment', google translation) - - "̟": [T: "alapuolinen plusmerkki"] # 0x31f (en: 'plus sign below embellishment', google translation) - - "̠": [T: "alapuolinen miinusmerkki"] # 0x320 (en: 'minus sign below embellishment', google translation) - - "̡": [T: "alapuolinen palataalisuuskoukku"] # 0x321 (en: 'palatalized hook below embellishment', google translation) - - "̢": [T: "alapuolinen retrofleksisuuskoukku"] # 0x322 (en: 'retroflex hook below embellishment', google translation) - - "̣": [T: "alapiste"] # 0x323 (en: 'dot below embellishment', google: 'piste koristelun alapuolella') - - "̤": [T: "alatreema"] # 0x324 (en: 'diaeresis below embellishment', google: 'diaeresis koristelun alapuolella') - - "̥": [T: "alaympyrä"] # 0x325 (en: 'ring below embellishment', google translation) - - "̦": [T: "alapilkku"] # 0x326 (en: 'comma below embellishment', google translation) - - "̧": [T: "sedilji"] # 0x327 (en: 'cedilla embellishment', google: 'cedilla -koriste') - - "̨": [T: "ogonek"] # 0x328 (en: 'ogonek embellishment', google translation) - - "̩": [T: "alapuolinen pystyviiva"] # 0x329 (en: 'vertical line below embellishment', google translation) - - "̪": [T: "alapuolinen silta"] # 0x32a (en: 'bridge below embellishment', google translation) - - "̫": [T: "alapuolinen ylösalainen kaksoiskaari"] # 0x32b (en: 'inverted double arch below embellishment', google translation) - - "̬": [T: "alapuolinen hattu"] # 0x32c (en: 'caron below embellishment', google translation) - - "̭": [T: "alapuolinen sirkumfleksi"] # 0x32d (en: 'circumflex accent below embellishment', google translation) - - "̮": [T: "alapuolinen lyhyysmerkki"] # 0x32e (en: 'breve below embellishment', google: 'breve koristelun alapuolella') - - "̯": [T: "alapuolinen ylösalainen lyhyysmerkki"] # 0x32f (en: 'inverted breve below embellishment', google translation) - - "̰": [T: "alatilde"] # 0x330 (en: 'tilde below embellishment', google: 'tilde koristelun alapuolella') - - "̱": [T: "alapuolinen pituusmerkki"] # 0x331 (en: 'macron below embellishment', google: 'macron koristelun alapuolella') - - "̲": [T: "alaviiva"] # 0x332 (en: 'low line embellishment', google: 'matala linjakoriste') - - "̳": [T: "kaksoisalaviiva"] # 0x333 (en: 'double low line embellishment', google translation) - - "̴": [T: "tilde päällä"] # 0x334 (en: 'tilde overlay embellishment', google translation) - - "̵": [T: "lyhyt yliviivaus"] # 0x335 (en: 'short stroke overlay embellishment', google translation) - - "̶": [T: "pitkä yliviivaus"] # 0x336 (en: 'long stroke overlay embellishment', google translation) - - "̷": [T: "lyhyt yliviivausvinoviiva"] # 0x337 (en: 'short solidus overlay embellishment', google translation) - - "̸": [T: "yliviivausvinoviiva"] # 0x338 (en: 'long solidus overlay embellishment', google: 'pitkä solidus -päällekkäisyys') - - "̹": [T: "oikea puolirengas alapuolella"] # 0x339 (en: 'right half ring below embellishment', google translation) - - "̺": [T: "käänteinen silta alapuolella"] # 0x33a (en: 'inverted bridge below embellishment', google translation) - - "̻": [T: "neliö alapuolella"] # 0x33b (en: 'square below embellishment', google translation) - - "̼": [T: "lokki alapuolella"] # 0x33c (en: 'seagull below embellishment', google translation) - - "̽": [T: "x yläpuolella"] # 0x33d (en: 'x above embellishment', google translation) - - "̾": [T: "pystysuora tilde"] # 0x33e (en: 'vertical tilde embellishment', google translation) - - "̿": [T: "kaksinkertainen yliviivaus"] # 0x33f (en: 'double overline embellishment', google translation) - - "̀": [T: "gravis"] # 0x340 (en: 'grave tone mark embellishment', google translation) - - "́": [T: "akuutti"] # 0x341 (en: 'acute tone mark embellishment', google translation) - - - "ΪΫϏ": # 0x3aa, 0x3ab, 0x3cf - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "iso"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [SPELL: "translate('.', 'ΪΫϏ', 'ιυϗ')"] - - T: "dialyytikalla" # (en: 'with dialytika', google translation) - - "ϊ": [T: "treema-ioota"] # 0x3ca (en: 'iota with dialytika', google translation) - - "ϋ": [T: "treema-ypsilon"] # 0x3cb (en: 'upsilon with dialytika', google translation) - - "ό": [T: "akuutti-omikron"] # 0x3cc (en: 'omicron with tonos', google translation) - - "ύ": [T: "akuutti-ypsilon"] # 0x3cd (en: 'upsilon with tonos', google translation) - - "ώ": [T: "akuutti-oomega"] # 0x3ce (en: 'omega with tonos', google translation) - - "ϐ": [T: "beeta"] # 0x3d0 (en: 'beta', google: 'beeta') - - "ϑ": [T: "theeta"] # 0x3d1 (en: 'theta', google: 'theta') - - "ϒ": [T: "ypsilon koukulla"] # 0x3d2 (en: 'upsilon with hook', google: 'upsilon koukkuun') - - "ϓ": [T: "upsilon akuutilla ja koukulla"] # 0x3d3 (en: 'upsilon with acute and hook', google translation) - - "ϔ": [T: "upsilon treemalla ja koukulla"] # 0x3d4 (en: 'upsilon with diaeresis and hook', google translation) - - "ϗ": [T: "kai"] # 0x3d7 (en: 'kai', google: 'kai') - - "А-Я": # 0x410 - 0x42f - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "iso"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [SPELL: "translate('.', 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ', 'абвгдежзийклмнопрстуфхцчшщъыьэюя')"] - - "а": [T: "a"] # 0x430 (google: 'а') - - "б": [T: "bee"] # 0x431 (google: 'olla') - - "в": [T: "vee"] # 0x432 - - "г": [T: "gee"] # 0x433 - - "д": [T: "dee"] # 0x434 - - "е": [T: "jee"] # 0x435 (google: 'eli') - - "ж": [T: "tzee"] # 0x436 - - "з": [T: "zee"] # 0x437 - - "и": [T: "i"] # 0x438 (google: 'и') - - "й": [T: "lyhyt i"] # 0x439 (en: 'short i') - - "к": [T: "kaa"] # 0x43a - - "л": [T: "el"] # 0x43b - - "м": [T: "em"] # 0x43c - - "н": [T: "en"] # 0x43d (google: 'fi') - - "о": [T: "o"] # 0x43e (google: 'о') - - "п": [T: "pee"] # 0x43f - - "р": [T: "er"] # 0x440 - - "с": [T: "es"] # 0x441 - - "т": [T: "tee"] # 0x442 - - "у": [T: "u"] # 0x443 (google: 'у') - - "ф": [T: "ef"] # 0x444 - - "х": [T: "haa"] # 0x445 - - "ц": [T: "tsee"] # 0x446 - - "ч": [T: "tshee"] # 0x447 - - "ш": [T: "shaa"] # 0x448 - - "щ": [T: "shtshaa"] # 0x449 - - "ъ": [T: "kova merkki"] # 0x44a (en: 'hard sign') - - "ы": [T: "jeru"] # 0x44b - - "ь": [T: "pehmeä merkki"] # 0x44c (en: 'soft sign') - - "э": [T: "käänteis-e"] # 0x44d (google: 'э') - - "ю": [T: "juu"] # 0x44e - - "я": [T: "jaa"] # 0x44f - - "‐": [T: "tavuviiva"] # 0x2010 (en: 'hyphen', google: 'tavuviiva') - - "‑": [T: "tavuviiva"] # 0x2011 (en: 'hyphen', google translation) - - "‒": [T: "numerotavuviiva"] # 0x2012 (en: 'figure dash', google translation) - - "–": [T: "lyhyt ajatusviiva"] # 0x2013 (en: 'en dash', google: 'fi dash') - - "—": [T: "pitkä ajatusviiva"] # 0x2014 (en: 'em dash', google: 'em dash') - - "‖": [T: "kaksinkertainen pystyviiva"] # 0x2016 (en: 'double vertical line', google: 'kaksinkertainen pystysuora viiva') - - "†": [T: "risti"] # 0x2020 (en: 'dagger', google: 'tikari') - - "‡": [T: "kaksoisristi"] # 0x2021 (en: 'double dagger', google: 'kaksinkertainen tikari') - - - "•": # 0x2022 - - test: - if: "@data-chem-formula-op" - then: [T: "piste"] # (en: 'dot', google translation) - else: [T: "luetelmapallo"] # (en: 'bullet', google: 'luoti') - - - "‰": [T: "promille"] # 0x2030 (en: 'per mille', google: 'per milli') - - "‱": [T: "kymmenestuhannesosa"] # 0x2031 (en: 'per ten thousand', google: 'kymmenentuhatta') - - "‵": [T: "käänteinen priimi"] # 0x2035 (en: 'reversed prime', google: 'kääntynyt pääministeri') # FI: "käänteinen pilkku" and for the next ones - - "‶": [T: "käänteinen kaskoispriimi"] # 0x2036 (en: 'reversed double prime', google: 'kääntynyt kaksinkertainen prime') - - "‷": [T: "käänteinen kolmoispriimi"] # 0x2037 (en: 'reversed triple prime', google translation) - - "‸": [T: "lisäys"] # 0x2038 - - "‹": [T: "vasemmalle osoittava kulmapuolilainaus"] # 0x2039 (en: 'single left pointing angle quote mark', google: 'yksi vasen piste -kulman lainausmerkki') - - "›": [T: "oikealle osoittava kulmapuolilainaus"] # 0x203a (en: 'single right pointing angle quote mark', google: 'yksi oikea osoituskulma lainausmerkki') - - "‼": [T: "kaksoiskertoma"] # 0x203c (en: 'double factorial', google translation) - - "⁄": [T: "murtoluvun vinoviiva"] # 0x2044 (en: 'divided by', google: 'jaettuna') # FI: check how this works in a sentence - - "⁅": [T: "piikillinen alkuhakasulku"] # 0x2045 (en: 'left square bracket with quill', google translation) - - "⁆": [T: "piikillinen loppuhakasulku"] # 0x2046 (en: 'right square bracket with quill', google translation) - - "⁗": [T: "neloispriimi"] # 0x2057 (en: 'quadruple prime', google: 'neljänneksen prime') # FI: maybe "pilkku pilkku pilkku pilkku" - - "⁠": [T: "rivinvaihdon esto"] # 0x2060 - - "⁰": [T: "potenssiin nolla"] # 0x2070 (en: 'to the zeroth power', google translation) - - "ⁱ": [T: "potenssiin i"] # 0x2071 (en: 'to the eihth power', google translation) - - "⁴": [T: "potenssiin neljä"] # 0x2074 (en: 'to the fourth power', google translation) - - "⁵": [T: "potenssiin viisi"] # 0x2075 (en: 'to the fifth power', google translation) - - "⁶": [T: "potenssiin kuusi"] # 0x2076 (en: 'to the sixth power', google translation) - - "⁷": [T: "potenssiin seitsemän"] # 0x2077 (en: 'to the seventh power', google translation) - - "⁸": [T: "potenssiin kahdeksan"] # 0x2078 (en: 'to the eighth power', google translation) - - "⁹": [T: "potenssiin yhdeksän"] # 0x2079 (en: 'to the ninth power', google translation) - - "⁺": [T: "yläindeksi plus"] # 0x207a (en: 'superscript plus sign', google translation) - - "⁻": [T: "yläindeksi miinus"] # 0x207b (en: 'superscript minus', google translation) - - "⁼": [T: "yläindeksi on yhtä suuri kuin"] # 0x207c (en: 'superscript equals sign', google translation) - - "⁽": [T: "yläindeksi vasen sulku"] # 0x207d (en: 'superscript left parenthesis', google translation) - - "⁾": [T: "yläindeksi oikea sulku"] # 0x207e (en: 'superscript right parenthesis', google translation) - - "ⁿ": [T: "potenssiin n"] # 0x207f (en: 'to the ennth power', google translation) - - "₀": [T: "alaindeksi nolla"] # 0x2080 (en: 'sub zero', google translation) - - "₁": [T: "alaindeksi yksi"] # 0x2081 (en: 'sub one', google translation) - - "₂": [T: "alaindeksi kaksi"] # 0x2082 (en: 'sub two', google translation) - - "₃": [T: "alaindeksi kolme"] # 0x2083 (en: 'sub three', google translation) - - "₄": [T: "alaindeksi neljä"] # 0x2084 (en: 'sub four', google translation) - - "₅": [T: "alaindeksi viisi"] # 0x2085 (google translation) - - "₆": [T: "alaindeksi kuusi"] # 0x2086 (google translation) - - "₇": [T: "alaindeksi seitsemän"] # 0x2087 (en: 'sub seven', google translation) - - "₈": [T: "alaindeksi kahdeksan"] # 0x2088 (en: 'sub eight', google translation) - - "₉": [T: "alaindeksi yhdeksän"] # 0x2089 (en: 'sub nine', google translation) - - "₊": [T: "alaindeksi plus"] # 0x208a (en: 'subscript plus sign', google translation) - - "₋": [T: "alaindeksi miinus"] # 0x208b (en: 'subscript minus sign', google translation) - - "₌": [T: "alaindeksi on yhtä suuri kuin"] # 0x208c (en: 'subscript equals sign', google translation) - - "₍": [T: "alaindeksi vasen sulku"] # 0x208d (en: 'subscript left parenthesis', google translation) - - "₎": [T: "alaindeksi oikea sulku"] # 0x208e (en: 'subscript right parenthesis', google translation) - - "ₐ": [T: "alaindeksi a"] # 0x2090 (en: 'sub A', google translation) - - "ₑ": [T: "alaindeksi e"] # 0x2091 (en: 'sub E', google translation) - - "ₒ": [T: "alaindeksi o"] # 0x2092 (en: 'sub O', google translation) - - "ₓ": [T: "alaindeksi x"] # 0x2093 (en: 'sub X', google translation) - - "ₕ": [T: "alaindeksi h"] # 0x2095 (en: 'sub H', google translation) - - "ₖ": [T: "alaindeksi k"] # 0x2096 (en: 'sub K', google translation) - - "ₗ": [T: "alaindeksi l"] # 0x2097 (en: 'sub L', google translation) - - "ₘ": [T: "alaindeksi m"] # 0x2098 (en: 'sub M', google translation) - - "ₙ": [T: "alaindeksi n"] # 0x2099 (en: 'sub N', google translation) - - "ₚ": [T: "alaindeksi p"] # 0x209a (en: 'sub P', google translation) - - "ₛ": [T: "alaindeksi s"] # 0x209b (en: 'sub S', google translation) - - "ₜ": [T: "alaindeksi t"] # 0x209c (en: 'sub T', google translation) - - "₠": [T: "eurooppalaiset valuuttayksiköt"] # 0x20a0 (en: 'european currenty units', google translation) - - "₡": [T: "colonia"] # 0x20a1 (en: 'colons', google: 'colons') - - "₢": [T: "cruzeiroa"] # 0x20a2 (en: 'cruzeiro', google: 'cruzeiro') - - "₣": [T: "frangia"] # 0x20a3 (en: 'franc', google: 'frangi') - - "₤": [T: "liiraa"] # 0x20a4 (en: 'lira', google: 'liira') - - "₥": [T: "milliä"] # 0x20a5 (en: 'mills', google: 'myllyt') - - "₦": [T: "nairaa"] # 0x20a6 (en: 'naira', google: 'naira') - - "₧": [T: "pesetaa"] # 0x20a7 (en: 'peseta', google: 'peseta') - - "₨": [T: "rupiaa"] # 0x20a8 (en: 'rupees', google: 'rupia') - - "₩": [T: "wonia"] # 0x20a9 (en: 'won', google: 'voitti') - - "₪": [T: "sekeliä"] # 0x20aa (en: 'new sheqels', google: 'uudet sheqels') - - "₫": [T: "dongia"] # 0x20ab (en: 'dong', google: 'dong') - - "€": [T: "euroa"] # 0x20ac (en: 'euros', google: 'eurot') - - "₭": [T: "kipia"] # 0x20ad (en: 'kip', google: 'kip') - - "₮": [T: "tugrikia"] # 0x20ae (en: 'tugrik', google: 'tugrik') - - "₯": [T: "drakhmaa"] # 0x20af (en: 'drachma', google: 'drachma') - - "₰": [T: "pfennigiä"] # 0x20b0 (en: 'german pennies', google: 'saksalaiset penniä') - - "₱": [T: "pesoa"] # 0x20b1 (en: 'pesos', google: 'pesot') - - "₲": [T: "guarania"] # 0x20b2 (en: 'guaranis', google: 'guaranis') - - "₳": [T: "australia"] # 0x20b3 (en: 'australs', google: 'itävaltait') - - "₴": [T: "hryvniaa"] # 0x20b4 (en: 'hryvnias', google: 'hryvnias') - - "₵": [T: "cediä"] # 0x20b5 (en: 'cedis', google: 'cedis') - - "₶": [T: "Toursin livreä"] # 0x20b6 (google translation) - - "₷": [T: "spesmiloa"] # 0x20b7 (google translation) - - "₸": [T: "tengeä"] # 0x20b8 (google translation) - - "₹": [T: "intialainen rupiaa"] # 0x20b9 (en: 'indian rupees', google translation) - - "₺": [T: "turkin liiraa"] # 0x20ba (en: 'turkish liras', google translation) - - "⃐": [T: "vasemmalle suuntautuva harppuuna"] # 0x20d0 (en: 'left harpoon above embellishment', google: 'vasen harppuon koristelun yläpuolella') - - "⃑": [T: "oikealle suuntautuva harppuuna"] # 0x20d1 (en: 'right harpoon above embellishment', google: 'oikea harppuuna koristelun yläpuolella') - - "⃒": [T: "pitkä yliviivauspystyviiva"] # 0x20d2 (en: 'long vertical line overlay embellishment', google translation) - - "⃓": [T: "lyhyt yliviivauspystyviiva"] # 0x20d3 (en: 'short vertical line overlay embellishment', google translation) - - "⃔": [T: "vastapäiväinen ylänuoli"] # 0x20d4 (en: 'anticlockwise arrow above embellishment', google translation) - - "⃕": [T: "myötäpäiväinen ylänuoli"] # 0x20d5 (en: 'clockwise arrow above embellishment', google translation) - - "⃖": [T: "vasemmalle suuntautuva nuoli"] # 0x20d6 (en: 'left arrow above embellishment', google: 'vasen nuoli koristelun yläpuolella') - - "⃗": [T: "oikealle suuntautuva nuoli"] # 0x20d7 (en: 'right arrow above embellishment', google: 'oikea nuoli koristelun yläpuolella') - - "⃘": [T: "rengas päällä"] # 0x20d8 (en: 'ring overlay embellishment', google translation) - - "⃙": [T: "rengas myötäpäivään päällä"] # 0x20d9 (en: 'clockwise ring overlay embellishment', google translation) - - "⃚": [T: "rengas vastapäivään päällä"] # 0x20da (en: 'anticlockwise ring overlay embellishment', google translation) - - "⃛": [T: "kolmoispiste"] # 0x20db (en: 'triple dot', google: 'kolminkertainen piste') - - "⃜": [T: "nelinkertainen piste"] # 0x20dc (en: 'quadruple dot', google: 'nelinkertainen piste') - - "⃝": [T: "sulkeva ympyrä"] # 0x20dd (en: 'enclosing circle embellishment', google translation) - - "⃞": [T: "sulkeva neliö"] # 0x20de (en: 'enclosing square embellishment', google translation) - - "⃟": [T: "sulkeva timantti"] # 0x20df (en: 'enclosing diamond embellishment', google translation) - - "⃠": [T: "sulkeva ympyrä kenoviivalla"] # 0x20e0 (en: 'enclosing circle backslash embellishment', google translation) - - "⃡": [T: "ylänuoli oikealle ja vasemmalle"] # 0x20e1 (en: 'left right arrow above embellishment', google: 'vasen oikea nuoli koristelun yläpuolella') - - "⃢": [T: "sulkeva ruutu"] # 0x20e2 (en: 'enclosing screen embellishment', google translation) - - "⃣": [T: "sulkeva näppäin"] # 0x20e3 (en: 'enclosing keycap embellishment', google translation) - - "⃤": [T: "sulkeva kolmio ylöspäin"] # 0x20e4 (en: 'enclosing upward pointing triangle embellishment', google translation) - - "⃥": [T: "kenoviiva päällä"] # 0x20e5 (en: 'reverse solidus overlay embellishment', google translation) - - "⃦": [T: "kaksinkertainen vaakaviiva päällä"] # 0x20e6 (en: 'double verticle stroke embellishment', google translation) - - "⃧": [T: "annuiteettisymboli"] # 0x20e7 (en: 'annuity symbol embellishment', google translation) - - "⃨": [T: "kolminkertainen alapiste"] # 0x20e8 (en: 'triple underdot', google translation) - - "⃩": [T: "leveä silta yläpuolella"] # 0x20e9 (en: 'wide bridge above embellishment', google translation) - - "⃪": [T: "vasen nuoli päällä"] # 0x20ea (en: 'leftwards arrow overlay embellishment', google translation) - - "⃫": [T: "pitkä kaksinkertainen vinoviiva päällä"] # 0x20eb (en: 'long double solidus overlay embellishment', google translation) - - "⃬": [T: "oikea alaharppuuna piikillä"] # 0x20ec (en: 'rightwards harpoon with barb downwards embellishment', google translation) - - "⃭": [T: "vasen alaharppuuna piikillä"] # 0x20ed (en: 'leftwards harpoon with barb downwards embellishment', google translation) - - "⃮": [T: "vasen alanuoli"] # 0x20ee (en: 'left arrow below embellishment', google translation) - - "⃯": [T: "oikea alanuoli"] # 0x20ef (en: 'right arrow below embellishment', google translation) - - "⃰": [T: "yläpuolinen asteriski"] # 0x20f0 (en: 'asterisk above embellishment', google translation) - - "℄": [T: "keskiviivasymboli"] # 0x2104 (en: 'center line symbol', google translation) - - "℅": [T: "C O"] # 0x2105 (google: 'hoito') - - "℆": [T: "C U"] # 0x2106 (google translation) - - "ℇ": [T: "eulerin vakio"] # 0x2107 (en: 'euler's constant', google: 'eulerin jatkuva') # FI: more German pronunciation? - - "℈": [T: "scruple"] # 0x2108 (en: 'scruples', google translation) - - "℉": [T: "astetta fahrenheitia"] # 0x2109 (en: 'degrees fahrenheit', google: 'fahrenheit-astetta') # FI: more German pronunciation? - - "ℊ": [T: "pieni g"] # 0x210a (en: 'script g', google: 'käsikirjoitus g') - - "ℌℑℨℭ": # 0x210c, 0x2111, 0x2128, 0x212d - - T: "fraktuura" # (en: 'fraktur', google: 'fraktur') - - SPELL: "translate('.', 'ℌℑℨℭ', 'HIZC')" - - - "ℍℙℾℿ": # 0x210d, 0x2119, 0x213e, 0x213f - - test: - if: "$Verbosity!='Terse'" - then: [T: "kaksiviivainen"] # (en: 'double struck', google translation) - - SPELL: "translate('.', 'ℍℙℾℿ', 'HPΓΠ')" - - - "ℎ": [T: "planckin vakio"] # 0x210e (en: 'planck constant', google: 'planck constant') - - "ℏ": # 0x210f - - test: - if: "($Verbosity='Terse')" - then: [T: "h viiva"] # (google translation) - else: [T: "redusoitu Planckin vakio"] # (en: 'reduced planck constant', google: 'vähentynyt planck -vakio') - - - "ℐℒ℘ℬℰℱℳ": # 0x2110, 0x2112, 0x2118, 0x2130, 0x2131, 0x2133 - - T: "kauno" # (en: 'script', google: 'käsikirjoitus') - - SPELL: "translate('.', 'ℐℒ℘ℬℰℱℳ', 'ILPBEFM')" - - - "℔": [T: "paunaa"] # 0x2114 (en: 'pounds', google translation) - - "№": [T: "numero"] # 0x2116 (en: 'number', google: 'määrä') - - "℥": [T: "unssia"] # 0x2125 (en: 'ounces', google: 'unssi') - - "Ω": [T: "ohmia"] # 0x2126 (en: 'ohms', google: 'ohmit') - - "℧": [T: "käännetty ohmi"] # 0x2127 (en: 'mhos', google: 'mhos') - - "℩": [T: "käännetty ioota"] # 0x2129 (en: 'turned iota', google: 'kääntyi iota') - - "Å": [T: "ångströmiä"] # 0x212b (en: 'angstroms', google: 'angstroms') - - "ℯ": [T: "kauno e"] # 0x212f (en: 'script e', google: 'käsikirjoitus e') - - # coalesced some chars that use cap letters - - "Ⅎ℺⅁⅂⅃⅄": # 0x2132, 0x213a, 0x2141, 0x2142, 0x2143, 0x2144 - - test: - - if: "'.' = '℺'" - then: [T: "kierretty"] # (en: 'rotated', google translation) - - else_if: "'.' = 'Ⅎ'" - then: [T: "käännetty"] # (en: 'turned', google translation) - - else_if: "'.' = '⅃'" - then: [T: "kääntynyt sans-serif"] # (en: 'reversed sans-serif', google translation) - else: [T: "käännetty sans-serif"] # (en: 'turned sans-serif', google: 'kääntyi sans-serif') - - SPELL: "translate('.', 'Ⅎ℺⅁⅂⅃⅄', 'FQGLLY')" - - - "ℴ": [T: "kauno o"] # 0x2134 (en: 'script o', google: 'käsikirjoitus o') - - "ℵ": [T: "alef"] # 0x2135 (en: 'first transfinite cardinal', google: 'ensimmäinen transfinite kardinaali') - - "ℶ": [T: "bet"] # 0x2136 (en: 'second transfinite cardinal', google: 'toinen transfinite kardinaali') - - "ℷ": [T: "gimel"] # 0x2137 (en: 'third transfinite cardinal', google: 'kolmas transfinite kardinaali') - - "ℸ": [T: "dalet"] # 0x2138 (en: 'fourth transfinite cardinal', google: 'neljäs transfinite kardinaali') - - "ℼ": [T: "kaksoisviivainen pii"] # 0x213c (en: 'double struck pi', google translation) - - "ℽ": [T: "kaksoisviivainen gamma"] # 0x213d (en: 'double struck gamma', google translation) - - "⅀": [T: "kaksoisviivainen sigma"] # 0x2140 (en: 'double struck n-ary summation', google translation) - - "⅋": [T: "käännetty et-merkki"] # 0x214b (en: 'turned ampersand', google translation) - - "⅌": [T: "per"] # 0x214c (google translation) - - "ⅎ": [T: "käännetty F"] # 0x214e (en: 'turned F', google translation) - - "⅐": [T: "yksi seitsemäsosa"] # 0x2150 (en: 'one seventh', google translation) - - "⅑": [T: "yksi yhdeksäsosa"] # 0x2151 (en: 'one ninth', google translation) - - "⅒": [T: "yksi kymmenesosa"] # 0x2152 (en: 'one tenth', google translation) - - "⅓": [T: "yksi kolmasosa"] # 0x2153 (en: 'one third', google: 'kolmasosa') - - "⅔": [T: "kaksi kolmasosaa"] # 0x2154 (en: 'two thirds') - - "⅕": [T: "yksi viidesosa"] # 0x2155 (en: 'one fifth', google: 'viidesosa') - - "⅖": [T: "kaksi viidesosaa"] # 0x2156 (en: 'two fifths') - - "⅗": [T: "kolme viidesosaa"] # 0x2157 (en: 'three fifths') - - "⅘": [T: "neljä viidesosaa"] # 0x2158 (en: 'four fifths') - - "⅙": [T: "yksi kuudesosa"] # 0x2159 (en: 'one sixth', google: 'kuudesosa') - - "⅚": [T: "viisi kuudesosaa"] # 0x215a (en: 'five sixths') - - "⅛": [T: "yksi kahdeksasosa"] # 0x215b (en: 'one eighth', google: 'yksi ath') - - "⅜": [T: "kolme kahdeksasosaa"] # 0x215c (en: 'three eighths', google: 'kolme aths') - - "⅝": [T: "viisi kahdeksasosaa"] # 0x215d (en: 'five eighths', google: 'viisi aths') - - "⅞": [T: "seitsemän kahdeksasosaa"] # 0x215e (en: 'seven eighths', google: 'seitsemän aths') - - "⅟": [T: "yksi per"] # 0x215f (en: 'one over', google translation) - - "Ⅰ": [T: "I"] # 0x2160 (en: 'I', google translation) - - "Ⅱ": [T: "I I"] # 0x2161 (en: 'I I', google translation) - - "Ⅲ": [T: "I I I"] # 0x2162 (en: 'I I I', google translation) - - "Ⅳ": [T: "I V"] # 0x2163 (en: 'I V', google translation) - - "Ⅴ": [T: "V"] # 0x2164 (en: 'V', google translation) - - "Ⅵ": [T: "V I"] # 0x2165 (en: 'V I', google translation) - - "Ⅶ": [T: "V I I"] # 0x2166 (en: 'V I I', google translation) - - "Ⅷ": [T: "V I I I"] # 0x2167 (en: 'V I I I', google translation) - - "Ⅸ": [T: "I X"] # 0x2168 (en: 'I X', google translation) - - "Ⅹ": [T: "X"] # 0x2169 (en: 'X', google translation) - - "Ⅺ": [T: "X I"] # 0x216a (en: 'X I', google translation) - - "Ⅻ": [T: "X I I"] # 0x216b (en: 'X I I', google translation) - - "Ⅼ": [T: "L"] # 0x216c (en: 'L', google translation) - - "Ⅽ": [T: "C"] # 0x216d (en: 'C', google translation) - - "Ⅾ": [T: "D"] # 0x216e (en: 'D', google translation) - - "Ⅿ": [T: "M"] # 0x216f (en: 'M', google translation) - - "ⅰ": [T: "i"] # 0x2170 (en: 'I', google translation) - - "ⅱ": [T: "i i"] # 0x2171 (en: 'I I', google translation) - - "ⅲ": [T: "i i i"] # 0x2172 (en: 'I I I', google translation) - - "ⅳ": [T: "i v"] # 0x2173 (en: 'I V', google translation) - - "ⅴ": [T: "ⅴ"] # 0x2174 (en: 'V', google translation) - - "ⅵ": [T: "v i"] # 0x2175 (en: 'V I', google translation) - - "ⅶ": [T: "v i i"] # 0x2176 (en: 'V I I', google translation) - - "ⅷ": [T: "v i i i"] # 0x2177 (en: 'V I I I', google translation) - - "ⅸ": [T: "i x"] # 0x2178 (en: 'I X', google translation) - - "ⅹ": [T: "ⅹ"] # 0x2179 (en: 'X', google translation) - - "ⅺ": [T: "x i"] # 0x217a (en: 'X I', google translation) - - "ⅻ": [T: "x i i"] # 0x217b (en: 'X I I', google translation) - - "ⅼ": [T: "ⅼ"] # 0x217c (en: 'L', google translation) - - "ⅽ": [T: "ⅽ"] # 0x217d (en: 'C', google translation) - - "ⅾ": [T: "ⅾ"] # 0x217e (en: 'D', google translation) - - "ⅿ": [T: "ⅿ"] # 0x217f (en: 'M', google translation) - - "↉": [T: "nolla kolmasosaa"] # 0x2189 (en: 'zero thirds', google translation) - - "←": [T: "nuoli vasemmalle"] # 0x2190 (en: 'leftwards arrow', google: 'vasen nuoli') - - "↑": [T: "nuoli ylös"] # 0x2191 (en: 'upwards arrow', google: 'ylöspäin nuoli') - - "↓": [T: "nuoli alas"] # 0x2193 (en: 'downwards arrow', google: 'alaspäin nuoli') - - "↔": [T: "nuoli vasemmalle ja oikealle"] # 0x2194 (en: 'left right arrow', google: 'vasen oikea nuoli') - - "↕": [T: "nuoli ylös ja alas"] # 0x2195 (en: 'up down arrow', google: 'ylöspäin nuoli') - - "↖": [T: "luoteeseen osoittava nuoli"] # 0x2196 (en: 'north west arrow', google: 'luoteis -nuoli') - - "↗": # 0x2197 - - test: - if: "ancestor::*[2][self::m:limit]" - then: [T: "lähestyy alhaalta"] # (en: 'approaches from below', google translation) - else: [T: "koilliseen osoittava nuoli"] # (en: 'north east arrow', google: 'koillis -nuoli') - - - "↘": # 0x2198 - - test: - if: "ancestor::*[2][self::m:limit]" - then: [T: "lähestyy ylhäältä"] # (en: 'approaches from above', google translation) - else: [T: "kaakkoon osoittava nuoli"] # (en: 'south east arrow', google: 'kaakkois -nuoli') - - - "↙": [T: "lounaaseen osoittava nuoli"] # 0x2199 (en: 'south west arrow', google: 'lounais -nuoli') - - "↚": [T: "nuoli vasemmalle poikkiviivalla"] # 0x219a (en: 'leftwards arrow with stroke', google: 'vasen nuoli aivohalvauksella') - - "↛": [T: "nuoli oikealle poikkiviivalla"] # 0x219b (en: 'rightwards arrow with stroke', google: 'oikealla nuolella aivohalvauksella') - - "↜": [T: "aaltonuoli vasemmalle"] # 0x219c (en: 'leftwards wave arrow', google: 'vasen aalto nuoli') - - "↝": [T: "aaltonuoli oikealle"] # 0x219d (en: 'rightwards wave arrow', google: 'oikealla aalto nuoli') - - "↞": [T: "kaksipäinen nuoli vasemmalle"] # 0x219e (en: 'leftwards two headed arrow', google: 'vasen kaksi päätä nuoli') - - "↟": [T: "kaksipäinen nuoli ylös"] # 0x219f (en: 'upwards two headed arrow', google: 'ylöspäin kaksi pääistä nuolta') - - "↠": [T: "kaksipäinen nuoli oikealle"] # 0x21a0 (en: 'rightwards two headed arrow', google: 'oikealle kaksi pääistä nuolta') - - "↡": [T: "kaksipäinen nuoli alas"] # 0x21a1 (en: 'downwards two headed arrow', google: 'alaspäin kaksi päätä nuolta') - - "↢": [T: "vasen nuoli pyrstöllä"] # 0x21a2 (en: 'leftwards arrow with tail', google: 'vasen nuoli hännän kanssa') - - "↣": [T: "oikea nuoli pyrstöllä"] # 0x21a3 (en: 'rightwards arrow with tail', google: 'oikealla nuolella hännän kanssa') - - "↤": [T: "vasen nuoli palkista"] # 0x21a4 (en: 'leftwards arrow from bar', google: 'vasen nuoli baarista') - - "↥": [T: "ylöspäin osoittava nuoli palkista"] # 0x21a5 (en: 'upwards arrow from bar', google: 'nuoli ylöspäin baarista') - - "↦": [T: "oikea nuoli palkista"] # 0x21a6 (en: 'rightwards arrow from bar', google: 'oikein nuoli baarista') - - "↧": [T: "alaspäin osoittava nuoli palkista"] # 0x21a7 (en: 'downwards arrow from bar', google: 'alaspäin nuoli baarista') - - "↨": [T: "ylös ja alas osoittava nuoli palkista"] # 0x21a8 (en: 'up down arrow with base', google: 'ylös nuoli pohjassa') - - "↩": [T: "vasen nuoli koukulla"] # 0x21a9 (en: 'leftwards arrow with hook', google: 'vasen nuoli koukussa') - - "↪": [T: "oikea nuoli koukulla"] # 0x21aa (en: 'rightwards arrow with hook', google: 'oikealla nuolella koukkulla') - - "↫": [T: "vasen nuoli silmukalla"] # 0x21ab (en: 'leftwards arrow with loop', google: 'vasen nuoli silmukka') - - "↬": [T: "oikea nuoli silmukalla"] # 0x21ac (en: 'rightwards arrow with loop', google: 'oikea nuoli silmukka') - - "↭": [T: "aaltonuoli oikealle ja vasemmalle"] # 0x21ad (en: 'left right wave arrow', google: 'vasen oikea aalto nuoli') - - "↮": [T: "nuoli oikealle ja vasemmalle poikkiviivalla"] # 0x21ae (en: 'left right arrow with stroke', google: 'vasen oikea nuoli aivohalvauksella') - - "↯": [T: "siksaknuoli alas"] # 0x21af (en: 'downwards zigzag arrow', google: 'alaspäin zigzag -nuoli') - - "↰": [T: "nuoli ylös ja kärki vasemmalle"] # 0x21b0 (en: 'upwards arrow with tip leftwards', google: 'ylöspäin nuoli vasemmalla kärkillä') - - "↱": [T: "nuoli ylös ja kärki oikealle"] # 0x21b1 (en: 'upwards arrow with tip rightwards', google: 'ylöspäin nuoli, joka on kärki oikealla') - - "↲": [T: "nuoli alas ja kärki vasemmalle"] # 0x21b2 (en: 'downwards arrow with tip leftwards', google: 'alaspäin nuoli vasemmalla kärkillä') - - "↳": [T: "nuoli alas ja kärki oikealle"] # 0x21b3 (en: 'downwards arrow with tip rightwards', google: 'alaspäin nuoli kärjen oikealla puolella') - - "↴": [T: "nuoli oikealle ja kulma alas"] # 0x21b4 (en: 'rightwards arrow with corner downwards', google: 'oikealla nuolella nurkkaan alaspäin') - - "↵": [T: "nuoli alas ja kulma oikealle"] # 0x21b5 (en: 'downwards arrow with corner leftwards', google: 'alaspäin nuoli vasemmalla kulmassa') - - "↶": [T: "yläpuoliympyränuoli vastapäivään"] # 0x21b6 (en: 'anticlockwise top semicircle arrow', google: 'vastapäivään puolipyöriin nuoli') - - "↷": [T: "yläpuoliympyränuoli myötäpäivään"] # 0x21b7 (en: 'clockwise top semicircle arrow', google: 'myötäpäivään puolipyöriin nuoli') - - "↸": [T: "nuoli ylävasemmalle pitkään viivaan"] # 0x21b8 (en: 'north west arrow to long bar', google: 'luoteis -nuoli pitkään baariin') - - "↹": [T: "nuoli oikealle ja vasemmalle palkkiin"] # 0x21b9 (en: 'leftwards arrow to bar over rightwards arrow to bar', google: 'vasen nuoli baariin oikeanpuoleisen nuolen yli baariin') - - "↺": [T: "vastapäiväinen avoimen ympyrän nuoli"] # 0x21ba (en: 'anticlockwise open circle arrow', google: 'vastapäivään avoin ympyrä nuoli') - - "↻": [T: "myötäpäiväinen avoimen ympyrän nuoli"] # 0x21bb (en: 'clockwise open circle arrow', google: 'myötäpäivään avoin ympyrä nuoli') - - "↼": [T: "puolinuoli vasemmalle väkä ylös"] # 0x21bc (en: 'left harpoon up', google: 'vasen harppuon ylös') - - "↽": [T: "puolinuoli vasemmalle väkä alas"] # 0x21bd (en: 'left harpoon down', google: 'vasen harppuon alas') - - "↾": [T: "puolinuoli ylös väkä oikealle"] # 0x21be (en: 'up harpoon right', google: 'up harpoon oikeassa') - - "↿": [T: "puolinuoli ylös väkä vasemmalle"] # 0x21bf (en: 'up harpoon left', google: 'up harpoon vasemmalle') - - "⇀": [T: "puolinuoli oikealle väkä ylös"] # 0x21c0 (en: 'right harpoon up', google: 'oikea harppuun') - - "⇁": [T: "puolinuoli oikealle väkä alas"] # 0x21c1 (en: 'right harpoon down', google: 'oikea harppuuna alas') - - "⇂": [T: "puolinuoli alas väkä oikealle"] # 0x21c2 (en: 'down harpoon right', google: 'alas harppuon oikealla') - - "⇃": [T: "puolinuoli alas väkä vasemmalle"] # 0x21c3 (en: 'down harpoon left', google: 'alas harppuun vasemmalle') - - "⇄": [T: "oikealle ja vasemmalle osoittavien nuolien pari"] # 0x21c4 (en: 'rightwards arrow over leftwards arrow', google: 'oikealla nuolella vasemmanpuoleisen nuolen yli') - - "⇅": [T: "ylös ja alas osoittavien nuolien pari"] # 0x21c5 (en: 'upwards arrow leftwards of downwards arrow', google: 'ylöspäin nuoli vasemmalle alaspäin nuolesta') - - "⇆": [T: "vasemmalle ja oikealle osoittavien nuolien pari"] # 0x21c6 (en: 'leftwards arrow over rightwards arrow', google: 'vasen nuoli oikealla nuolella') - - "⇇": [T: "nuolipari vasemmalle"] # 0x21c7 (en: 'leftwards paired arrows', google: 'vasen parit nuolet') - - "⇈": [T: "nuolipari ylös"] # 0x21c8 (en: 'upwards paired arrows', google: 'ylöspäin parilliset nuolet') - - "⇉": [T: "nuolipari oikealle"] # 0x21c9 (en: 'rightwards paired arrows', google: 'oikealla puolella nuolet') - - "⇊": [T: "nuolipari alas"] # 0x21ca (en: 'downwards paired arrows', google: 'alaspäin parit nuolet') - - "⇋": [T: "puolinuolipari vasemmalle ja oikealle"] # 0x21cb (en: 'left harpoon over right harpoon', google: 'vasen harpoon oikean harppuunin yli') - - "⇌": [T: "puolinuolipari oikealle ja vasemmalle"] # 0x21cc (en: 'right harpoon over left harpoon', google: 'oikea harppuuna vasemman harppuunin yli') - - "⇍": [T: "kaksiviivainen nuoli vasemmalle poikkiviivalla"] # 0x21cd (en: 'leftwards double arrow with stroke', google: 'vasen kaksinkertainen nuoli aivohalvauksella') - - "⇎": [T: "kaksiviivainen nuoli vasemmalle ja oikealle poikkiviivalla"] # 0x21ce (en: 'left right double arrow with stroke', google: 'vasen oikea kaksinkertainen nuoli aivohalvauksella') - - "⇏": [T: "kaksiviivainen nuoli oikealle poikkiviivalla"] # 0x21cf (en: 'rightwards double arrow with stroke', google: 'oikeasti kaksinkertainen nuoli aivohalvauksella') - - "⇐": [T: "vasemmalle osoittava kaksoisnuoli"] # 0x21d0 (en: 'leftwards double arrow', google: 'vasen kaksinkertainen nuoli') - - "⇑": [T: "ylös osoittava kaksoisnuoli"] # 0x21d1 (en: 'upwards double arrow', google: 'ylöspäin kaksoisnuoli') - - "⇓": [T: "alas osoittava kaksoisnuoli"] # 0x21d3 (en: 'downwards double arrow', google: 'alaspäin kaksinkertainen nuoli') - - "⇔": [T: "vasemmalle ja oikealle osoittava kaksoisnuoli"] # 0x21d4 (en: 'left right double arrow', google: 'vasen oikea kaksinkertainen nuoli') - - "⇕": [T: "ylös ja alas osoittava kaksoisnuoli"] # 0x21d5 (en: 'up down double arrow', google: 'ylös alas kaksinkertainen nuoli') - - "⇖": [T: "luoteeseen osoittava kaksoisnuoli"] # 0x21d6 (en: 'north west double arrow', google: 'luoteisosan kaksinkertainen nuoli') - - "⇗": [T: "koilliseen osoittava kaksoisnuoli"] # 0x21d7 (en: 'north east double arrow', google: 'koillis -kaksinkertainen nuoli') - - "⇘": [T: "kaakkoon osoittava kaksoisnuoli"] # 0x21d8 (en: 'south east double arrow', google: 'kaakkois -kaksinkertainen nuoli') - - "⇙": [T: "luoteeseen osoittava kaksoisnuoli"] # 0x21d9 (en: 'south west double arrow', google: 'lounais -kaksinkertainen nuoli') - - "⇚": [T: "kolmiviivainen nuoli vasemmalle"] # 0x21da (en: 'leftwards triple arrow', google: 'vasen kolminkertainen nuoli') - - "⇛": [T: "kolmiviivainen nuoli oikealle"] # 0x21db (en: 'rightwards triple arrow', google: 'oikealle kolminkertainen nuoli') - - "⇜": [T: "kiemuranuoli vasemmalle"] # 0x21dc (en: 'leftwards squiggle arrow', google: 'vasen nuoli') - - "⇝": [T: "kiemuranuoli oikealle"] # 0x21dd (en: 'rightwards squiggle arrow', google: 'oikealla puolella nuoli') - - "⇞": [T: "nuoli ylös kaksoispoikkiviivalla"] # 0x21de (en: 'upwards arrow with double stroke', google: 'ylöspäin nuoli kaksinkertaisella iskulla') - - "⇟": [T: "nuoli alas kaksoispoikkiviivalla"] # 0x21df (en: 'downwards arrow with double stroke', google: 'alaspäin nuoli kaksinkertaisella iskulla') - - "⇠": [T: "katkoviivanuoli vasemmalle"] # 0x21e0 (en: 'leftwards dashed arrow', google: 'vasen katkoviiva nuoli') - - "⇡": [T: "katkoviivanuoli ylös"] # 0x21e1 (en: 'upwards dashed arrow', google: 'ylöspäin katkoviiva nuoli') - - "⇢": [T: "katkoviivanuoli oikealle"] # 0x21e2 (en: 'rightwards dashed arrow', google: 'oikealla katkoviivalla nuolella') - - "⇣": [T: "katkoviivanuoli alas"] # 0x21e3 (en: 'downwards dashed arrow', google: 'alaspäin katkoviiva nuoli') - - "⇤": [T: "nuoli vasemmalle viivaan"] # 0x21e4 (en: 'leftwards arrow to bar', google: 'vasen nuoli baariin') - - "⇥": [T: "nuoli oikealle viivaan"] # 0x21e5 (en: 'rightwards arrow to bar', google: 'oikein nuoli baariin') - - "⇦": [T: "vasemmalle osoittava valkea nuoli"] # 0x21e6 (en: 'leftwards white arrow', google: 'vasen valkoinen nuoli') - - "⇧": [T: "ylös osoittava valkea nuoli"] # 0x21e7 (en: 'upwards white arrow', google: 'ylöspäin valkoinen nuoli') - - "⇨": [T: "oikealle osoittava valkea nuoli"] # 0x21e8 (en: 'rightwards white arrow', google: 'oikealle valkoinen nuoli') - - "⇩": [T: "alas osoittava valkea nuoli"] # 0x21e9 (en: 'downwards white arrow', google: 'alaspäin valkoinen nuoli') - - "⇪": [T: "palkista ylös osoittava valkea nuoli"] # 0x21ea (en: 'upwards white arrow from bar', google: 'ylöspäin valkoinen nuoli baarista') - - "⇫": [T: "valkoinen nuoli ylös jalustalla"] # 0x21eb (en: 'upwards white arrow on pedestal', google translation) - - "⇬": [T: "valkoinen nuoli ylös jalustalla ja vaakasuoralla palkilla"] # 0x21ec (en: 'upwards white arrow on pedestal with horizontal bar', google translation) - - "⇭": [T: "valkoinen nuoli ylös jalustalla ja pystysuoralla palkilla"] # 0x21ed (en: 'upwards white arrow on pedestal with vertical bar', google translation) - - "⇮": [T: "valkoinen kaksinkertainen nuoli ylös"] # 0x21ee (en: 'upwards white double arrow', google translation) - - "⇯": [T: "valkoinen kaksinkertainen nuoli ylös jalustalla"] # 0x21ef (en: 'upwards white double arrow on pedestal', google translation) - - "⇰": [T: "valkoinen nuoli oikealle seinästä"] # 0x21f0 (en: 'rightwards white arrow from wall', google translation) - - "⇱": [T: "ylävasemmalle osoittava nuoli nurkkaan"] # 0x21f1 (en: 'north west arrow to corner', google translation) - - "⇲": [T: "alaoikealle osoittava nuoli nurkkaan"] # 0x21f2 (en: 'south east arrow to corner', google translation) - - "⇳": [T: "ylös ja alas osoittava valkoinen nuoli"] # 0x21f3 (en: 'up down white arrow', google translation) - - "⇴": [T: "oikea nuoli pienellä ympyrällä"] # 0x21f4 (en: 'right arrow with small circle', google translation) - - "⇵": [T: "alas ja ylös osoittavat nuolet"] # 0x21f5 (en: 'downwards arrow leftwards of upwards arrow', google: 'alaspäin nuoli ylöspäin ylöspäin nuolesta') - - "⇶": [T: "kolmoisnuoli oikealle"] # 0x21f6 (en: 'three rightwards arrows', google translation) - - "⇷": [T: "vasen nuoli pystysuoralla viivalla"] # 0x21f7 (en: 'leftwards arrow with vertical stroke', google translation) - - "⇸": [T: "oikea nuoli pystysuoralla viivalla"] # 0x21f8 (en: 'rightwards arrow with vertical stroke', google translation) - - "⇹": [T: "vasemmalle ja oikealle osoittava nuoli pystysuoralla viivalla"] # 0x21f9 (en: 'left right arrow with vertical stroke', google translation) - - "⇺": [T: "vasen nuoli kaksinkertaisella pystysuoralla viivalla"] # 0x21fa (en: 'leftwards arrow with double vertical stroke', google translation) - - "⇻": [T: "oikea nuoli kaksinkertaisella pystysuoralla viivalla"] # 0x21fb (en: 'rightwards arrow with double vertical stroke', google translation) - - "⇼": [T: "vasemmalle ja oikealle osoittava nuoli kaksinkertaisella pystysuoralla viivalla"] # 0x21fc (en: 'left right arrow with double vertical stroke', google translation) - - "⇽": [T: "vasen avoin nuoli"] # 0x21fd (en: 'leftwards open headed arrow', google: 'vasen auki pää nuoli') - - "⇾": [T: "oikea avoin nuoli"] # 0x21fe (en: 'rightwards open headed arrow', google: 'oikea avaa pään nutrow') - - "⇿": [T: "oikealle ja vasemmalle osoittava avoin nuoli"] # 0x21ff (en: 'left right open headed arrow', google: 'vasen oikeaa auki nuoli') - - "∁": # 0x2201 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (google translation) - - T: "komplementti" # (en: 'complement of', google: 'täydennys') - - "∃": [T: "on olemassa"] # 0x2203 (en: 'there exists') - - "∄": [T: "ei ole olemassa"] # 0x2204 (en: 'there does not exist', google: 'ei ole') - - "∅": [T: "tyhjä joukko"] # 0x2205 (en: 'empty set', google: 'tyhjä sarja') - - "∇": # 0x2207 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (google translation) - - T: "nabla" # (en: 'gradient of', google: 'gradientti') - - "∋": [T: "sisältää alkion"] # 0x220b (en: 'contains the member', google: 'sisältää jäsenen') - - "∌": [T: "ei sisällä alkiota"] # 0x220c (en: 'does not contain the member', google: 'ei sisällä jäsentä') - - "∍": [T: "sisältää pienen alkion"] # 0x220d (en: 'contains the member', google: 'sisältää jäsenen') - - "∎": [T: "todistuksen loppu"] # 0x220e (en: 'end of proof', google: 'todistuksen loppu') - - "∏": [T: "tulo"] # 0x220f (en: 'product', google: 'tuote') - - "∐": [T: "kotulo"] # 0x2210 (google: 'kopiointi') - - "∑": [T: "summa"] # 0x2211 (en: 'sum') - - "−": [T: "miinus"] # 0x2212 (en: 'minus') - - "∓": [T: "miinus-plus"] # 0x2213 (en: 'minus or plus') # FI: check how the hyphen behaves - - "∔": [T: "piste-plus"] # 0x2214 (en: 'dot plus', google: 'dot plus') # FI: check how the hyphen behaves - - "∕": [T: "jakoviiva"] # 0x2215 (en: 'divided by', google: 'jaettuna') - - "∖": [T: "joukkomiinus"] # 0x2216 (en: 'set minus', google: 'aseta miinus') - - "∗": [T: "kertaa"] # 0x2217 (en: 'times', google: 'ajat') - - "∙": # 0x2219 - - test: - if: "@data-chem-formula-op" - then: [T: "piste"] # (en: 'dot', google translation) - else: [T: "kertaa"] # (en: 'times', google: 'ajat') - - - "∛": # 0x221b - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (google translation) - - T: "kuutiojuuri" # (en: 'cube root of') - - "∜": # 0x221c - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (google translation) - - T: "neljäs juuri" # (en: 'fourth root of') - - "∞": [T: "ääretön"] # 0x221e (en: 'infinity') - - "∟": [T: "suora kulma"] # 0x221f (en: 'right angle', google: 'oikea kulma') - - "∠": [T: "kulma"] # 0x2220 (en: 'angle') - - "∡": [T: "mitattu kulma"] # 0x2221 (en: 'measured angle') - - "∢": [T: "kaarellinen kulma"] # 0x2222 (en: 'spherical angle', google: 'pallomainen kulma') - - "∣": [T: "jakaa"] # 0x2223 (en: 'divides') - - "∤": [T: "ei jaa"] # 0x2224 (en: 'does not divide') - - "∩": [T: "leikkaus"] # 0x2229 (en: 'intersection', google: 'risteys') - - "∫": [T: "integraali"] # 0x222b (en: 'integral', google: 'olennainen') - - "∬": [T: "kaksoisintegraali"] # 0x222c (en: 'double integral', google: 'kaksinkertainen integraali') - - "∭": [T: "kolmoisintegraali"] # 0x222d (en: 'triple integral', google: 'kolminkertainen integraali') - - "∯": [T: "pintaintegraali"] # 0x222f (en: 'surface integral', google: 'pinta -integraali') - - "∰": [T: "tilavuusintegraali"] # 0x2230 (en: 'volume integral', google: 'volyymin integraali') - - "∱": [T: "integraali myötäpäivään"] # 0x2231 (en: 'clockwise integral', google: 'myötäpäivään olennainen') - - "∲": [T: "polkuintegraali myötäpäivään"] # 0x2232 (en: 'clockwise contour integral', google: 'myötäpäivään ääriviivat') - - "∳": [T: "polkuintegraali vastapäivään"] # 0x2233 (en: 'anticlockwise contour integral', google: 'vastapäivään ääriviivat') - - "∴": [T: "siis"] # 0x2234 (en: 'therefore', google: 'siksi') - - "∵": [T: "koska"] # 0x2235 (en: 'because') - - "∸": [T: "piste-miinus"] # 0x2238 (en: 'dot minus') - - "∹": [T: "ylitys"] # 0x2239 (en: 'has excess compared to', google: 'on ylimääräinen verrattuna') - - "∺": # 0x223a - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "geometrisesti verrannollinen" # (en: 'geometrically proportional to', google: 'geometrisesti verrannollinen') # FI: "geometrisesti verranollinen"? - - "∻": # 0x223b - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "homoteettinen" # (en: 'homothetic to', google: 'homotetiikka') - - "≀": [T: "punostulo"] # 0x2240 (en: 'wreath product', google: 'seppele tuote') - - "≁": [T: "ei tilde"] # 0x2241 (en: 'not tilde') - - "≂": [T: "miinus-tilde"] # 0x2242 (en: 'minus tilde') - - "≃": # 0x2243 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "asymptoottisesti yhtä suuri kuin" # (en: 'asymptotically equal to', google: 'asymptoottisesti yhtä suuri kuin') - - "≄": # 0x2244 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei asymptoottisesti yhtäsuuri kuin" # (en: 'not asymptotically equal to', google: 'ei asymptoottisesti yhtä suuri kuin') - - "≅": # 0x2245 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "likimäärin yhtä suuri kuin" # (en: 'approximately equal to', google: 'suunnilleen yhtä suuri kuin') - - "≆": # 0x2246 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "likimäärin mutta ei yhtä suuri kuin" # (en: 'approximately but not actually equal to', google: 'suunnilleen, mutta ei oikeastaan yhtä suuri kuin') - - "≇": # 0x2247 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei likimäärin eikä yhtä suuri kuin" # (en: 'neither approximately nor actually equal to', google: 'ei suunnilleen eikä oikeastaan yhtä suuri kuin') - - "≈": # 0x2248 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "likimäärin yhtä suuri kuin" # (en: 'almost equal to', google: 'melkein yhtä suuri kuin') - - "≉": # 0x2249 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei likimäärin yhtä suuri kuin" # (en: 'not almost equal to', google: 'ei melkein yhtä suuri kuin') - - "≊": # 0x224a - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "lähes tai tasan yhtä suuri kuin" # (en: 'almost equal or equal to', google: 'melkein yhtä suuri tai yhtä suuri kuin') - - "≋": [T: "kolmoistilde"] # 0x224b (en: 'triple tilde', google: 'kolminkertainen tilde') - - "≌": [T: "kaikki yhtäsuuria kuin"] # 0x224c (en: 'are all equal to', google: 'ovat kaikki yhtä suuret kuin') - - "≍": # 0x224d - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "yhtäpitävä" # (en: 'equivalent to', google: 'vastaa') - - "≎": # 0x224e - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "geometrisesti yhtäpitävä" # (en: 'geometrically equivalent to', google: 'geometrisesti vastaavat') - - "≏": # 0x224f - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (google translation) - - T: "ero välillä" # (en: 'difference between', google: 'ero välillä') - - "≐": [T: "lähestyy raja-arvoa"] # 0x2250 (en: 'approaches the limit') - - "≑": # 0x2251 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "geometrisesti yhtä kuin" # (en: 'geometrically equal to', google: 'geometrisesti yhtä suuri kuin') - - "≒": # 0x2252 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "likimäärin yhtä suuri kuin tai kohteen kuva" # (google: 'suunnilleen yhtä suuri tai kuva') - - "≓": # 0x2253 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is the', google translation) - - T: "kohteen kuva tai likimäärin yhtä suuri kuin" # (google: 'kuva tai suunnilleen yhtä suuri kuin') - - "≔": [T: "kaksoispiste yhtä suuri kuin"] # 0x2254 (en: 'colon equals', google: 'colol -eaksi') - - "≕": [T: "yhtä suuri kuin kaksoispiste"] # 0x2255 (en: 'equals colon', google: 'vastaa kaksoispistettä') - - "≖": [T: "ympyrän sisältävä yhtäläisyys"] # 0x2256 (en: 'ring in equal to', google: 'rengas yhtä suuri kuin') - - "≗": # 0x2257 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "ympyrä yhtä suuri kuin" # (en: 'approximately equal to', google: 'suunnilleen yhtä suuri kuin') - - "≘": [T: "kaari yhtä suuri kuin"] # 0x2258 (en: 'corresponds to', google: 'vastaa') - - "≙": [T: "vastaa"] # 0x2259 (en: 'estimates', google: 'arviot') - - "≚": # 0x225a - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "samakulmainen kuin" # (en: 'equiangular to', google: 'tasa -arvoinen') - - "≛": [T: "tähti yhtä suuri kuin"] # 0x225b (en: 'star equals', google: 'tähti on yhtä suuri kuin') - - "≜": [T: "delta yhtä suuri kuin"] # 0x225c (en: 'delta equals', google: 'delta on tasa -arvoinen') - - "≝": [T: "määritelmän mukaan yhtä kuin"] # 0x225d (en: 'is defined to be', google: 'on määritelty olevan') - - "≞": # 0x225e - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "mitatusti yhtä suuri kuin" # (en: 'measured by', google: 'mitattu') - - "≟": [T: "kyseenalaisesti yhtä kuin"] # 0x225f (en: 'has an unknown relationship with', google: 'on tuntematon suhde') - - "≢": # 0x2262 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "identtisesti eri kuin" # (en: 'not identical to', google: 'ei identtinen') - - "≣": # 0x2263 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "vahvasti ekvivalentti" # (en: 'strictly equivalent to', google: 'tiukasti vastaa') - - "≨": # 0x2268 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "pienempi mutta ei yhtä suuri kuin" # (en: 'less than but not equal to', google: 'vähemmän kuin, mutta ei yhtä suuri kuin') - - "≩": # 0x2269 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "suurempi mutta ei yhtä suuri kuin" # (en: 'greater than but not equal to', google: 'suurempi kuin, mutta ei yhtä suuri kuin') - - "≪": # 0x226a - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "paljon pienempi kuin" # (en: 'much less than', google: 'paljon vähemmän kuin') - - "≫": # 0x226b - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "paljon suurempi kuin" # (en: 'much greater than') - - "≬": # 0x226c - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "välissä" # (en: 'between', google: 'välillä') - - "≭": # 0x226d - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei yhtäpitävä" # (en: 'not equivalent to', google: 'ei vastaa') - - "≮": # 0x226e - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei aidosti pienempi kuin" # (en: 'not less than', google: 'ei vähempää kuin') - - "≯": # 0x226f - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei aidosti suurempi kuin" # (en: 'not greater than', google: 'enintään') - - "≰": # 0x2270 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei pienempi eikä yhtäsuuri kuin" # (en: 'neither less than nor equal to', google: 'ei vähemmän kuin yhtä suuri kuin') - - "≱": # 0x2271 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei suurempi eikä yhtäsuuri kuin" # (en: 'neither greater than nor equal to', google: 'ei suurempi kuin yhtä suuri kuin') - - "≲": # 0x2272 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "pienempi tai yhtäpitävä" # (en: 'less than or equivalent to', google: 'vähemmän tai vastaavat') - - "≳": # 0x2273 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "suurempi tai yhtäpitävä" # (en: 'greater than or equivalent to', google: 'suurempi tai vastaa') - - "≴": # 0x2274 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei pienempi eikä yhtäpitävä" # (en: 'neither less than nor equivalent to', google: 'ei vähemmän kuin vastaa') - - "≵": # 0x2275 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei suurempi eikä yhtäpitävä" # (en: 'neither greater than nor equivalent to', google: 'ei suurempi kuin vastaava') - - "≶": # 0x2276 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "aidosti pienempi tai suurempi kuin" # (en: 'less than or greater than', google: 'vähemmän tai suurempi kuin') - - "≷": # 0x2277 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "aidosti suurempi tai pienempi kuin" # (en: 'greater than or less than', google: 'suurempi tai vähemmän kuin') - - "≸": # 0x2278 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei aidosti pienempi eikä suurempi kuin" # (en: 'neither less than nor greater than', google: 'ei vähemmän kuin suurempi kuin') - - "≹": # 0x2279 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei aidosti suurempi eikä pienempi kuin" # (en: 'neither greater than nor less than', google: 'ei suurempi kuin vähemmän kuin') - - "≺": [T: "edeltää"] # 0x227a (en: 'precedes') - - "≻": [T: "seuraa"] # 0x227b (en: 'succeeds', google: 'onnistuu') - - "≼": [T: "edeltää tai on yhtä kuin"] # 0x227c (en: 'precedes or is equal to', google: 'edeltää tai on yhtä suuri kuin') - - "≽": [T: "seuraa tai on yhtä kuin"] # 0x227d (en: 'succeeds or is equal to', google: 'onnistuu tai on yhtä suuri') - - "≾": [T: "edeltää tai on yhtäpitävä"] # 0x227e (en: 'precedes or is equivalent to', google: 'edeltää tai vastaa') - - "≿": [T: "seuraa tai on yhtäpitävä"] # 0x227f (en: 'succeeds or is equivalent to', google: 'onnistuu tai vastaa') - - "⊀": [T: "ei edellä"] # 0x2280 (en: 'does not precede', google: 'ei edeltä') - - "⊁": [T: "ei seuraa"] # 0x2281 (en: 'does not succeed', google: 'ei onnistu') - - "⊈": # 0x2288 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei osajoukko eikä yhtä kuin" # (en: 'neither a subset of nor equal to', google: 'ei alajoukko eikä yhtä suuri kuin') - - "⊉": # 0x2289 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei sisällä osajoukkoa eikä yhtä kuin" # (en: 'neither a superset of nor equal to', google: 'ei ylenmääräinen eikä yhtä suuri kuin') - - "⊊": [T: "on aito osajoukko"] # 0x228a (en: 'subset of with not equal to', google: 'osajoukko, joka ei ole yhtä suuri kuin') - - "⊋": [T: "sisältää aidon osajoukon"] # 0x228b (en: 'superset of with not equal to', google: 'superset of with ei ole yhtä suuri kuin') - - "⊌": [T: "monijoukko"] # 0x228c (en: 'multiset', google: 'multiset') - - "⊍": [T: "monijoukkojen kerto"] # 0x228d (en: 'multiset multiplication', google: 'multiset -kertolasku') - - "⊎": [T: "monijoukkojen unioni"] # 0x228e (en: 'multiset union', google: 'multiset union') - - "⊏": [T: "kulmikas relaatio"] # 0x228f (en: 'square image of', google: 'neliökuva') - - "⊐": [T: "käänteinen kulmikas relaatio"] # 0x2290 (en: 'square original of', google: 'neliön alkuperäinen') - - "⊑": [T: "kulmikas relaatio tai yhtä kuin"] # 0x2291 (en: 'square image of or equal to', google: 'neliökuva tai yhtä suuri kuin') - - "⊒": [T: "käänteinen kulmikas relaatio tai yhtä suuri kuin"] # 0x2292 (en: 'square original of or equal to', google: 'neliön alkuperäinen tai yhtä suuri kuin') - - "⊓": [T: "kulmikas kupu"] # 0x2293 (en: 'square cap', google: 'neliö -isot') - - "⊔": [T: "kulmikas malja"] # 0x2294 (en: 'square cup', google: 'square cup') - - "⊕": [T: "ympyröity plus"] # 0x2295 (en: 'circled plus') - - "⊖": [T: "ympyröity miinus"] # 0x2296 (en: 'circled minus') - - "⊗": [T: "ympyröity kertaa"] # 0x2297 (en: 'circled times', google: 'ympyräajat') - - "⊘": [T: "ympyröity jakoviiva"] # 0x2298 (en: 'circled slash', google: 'ympyräviiva') - - "⊙": [T: "ympyröity piste"] # 0x2299 (en: 'circled dot operator', google: 'ympyräpisteoperaattori') - - "⊚": [T: "ympyröity pallo"] # 0x229a (en: 'circled ring', google: 'ympyrä rengas') - - "⊛": [T: "ympyröity tähti"] # 0x229b (en: 'circled asterisk', google: 'ympyrä tähdellä') - - "⊜": [T: "ympyröity yhtä kuin"] # 0x229c (en: 'circled equals', google: 'ympyröity tasa -arvoinen') - - "⊝": [T: "ympyröity viiva"] # 0x229d (en: 'circled dash') - - "⊞": [T: "neliöity plus"] # 0x229e (en: 'squared plus', google: 'squared plus') - - "⊟": [T: "neliöity miinus"] # 0x229f (en: 'squared minus', google: 'neliö miinus') - - "⊠": [T: "neliöity kertaa"] # 0x22a0 (en: 'squared times', google: 'neliöajat') - - "⊡": [T: "neliöity piste"] # 0x22a1 (en: 'squared dot operator', google: 'squared dot -operaattori') - - "⊢": [T: "oikealle osoittava nupi"] # 0x22a2 (en: 'proves', google: 'todistaa') - - "⊣": [T: "vasemmalle osoittava nupi"] # 0x22a3 (en: 'does not yield', google: 'ei tuota') - - "⊤": [T: "alas osoittava nupi"] # 0x22a4 (google: 'ylhäältä') - - "⊥": # 0x22a5 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "ylös osoittava nupi" # (google: 'pohja') - - "⊦": [T: "assertio"] # 0x22a6 (en: 'reduces to', google: 'vähentää') - - "⊧": [T: "toteuttaa mallina"] # 0x22a7 (en: 'models', google: 'malleja') - - "⊨": # 0x22a8 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "tosi" # (en: 'true', google: 'totta') - - "⊩": [T: "pakottaa"] # 0x22a9 (en: 'forces', google: 'voimat') - - "⊪": [T: "kolmoispystyviiva ja oikeanpuoleinen kääntöportti"] # 0x22aa (en: 'triple vertical bar right turnstile', google: 'kolminkertainen pystysuora palkki oikean kääntölaite') - - "⊫": [T: "kaksoispystyviiva ja oikeanpuoleinen kaksoiskääntöportti"] # 0x22ab (en: 'double vertical bar double right turnstile', google: 'kaksois pystysuora palkki kaksinkertainen oikea käänne') - - "⊬": [T: "ei todista"] # 0x22ac (en: 'does not prove', google: 'ei todista') - - "⊭": # 0x22ad - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "epätosi" # (en: 'not true', google: 'ei totta') - - "⊮": [T: "ei pakota"] # 0x22ae (en: 'does not force', google: 'ei pakota') - - "⊯": [T: "ei kaksoispystyviiva ja oikeanpuolenen kaksoiskääntöportti"] # 0x22af (en: 'negated double vertical bar double right turnstile', google: 'kielteinen kaksinkertainen pystysuora palkki kaksinkertainen oikea käänne') - - "⊰": [T: "edeltää relaatiossa"] # 0x22b0 (en: 'precedes under relation', google: 'edeltää suhteessa') - - "⊱": [T: "seuraa relaatiossa"] # 0x22b1 (en: 'succeeds under relation', google: 'onnistuu suhteessa') - - "⊲": # 0x22b2 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "normaali aliryhmä" # (en: 'a normal subgroup of', google: 'normaali alaryhmä') - - "⊳": [T: "sisältää normaalin aliryhmän"] # 0x22b3 (en: 'contains as a normal subgroup', google: 'sisältää normaalina alaryhmänä') - - "⊴": # 0x22b4 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "normaali aliryhmä tai yhtä kuin" # (en: 'a normal subgroup of or equal to', google: 'normaali alaryhmä tai yhtä suuri') - - "⊵": [T: "sisältää normaalin aliryhmän tai on yhtä kuin"] # 0x22b5 (en: 'contains as a normal subgroup or equal to', google: 'sisältää normaalina alaryhmänä tai yhtä suuri kuin') - - "⊶": # 0x22b6 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "alkukuva" # (en: 'the original of', google: 'alkuperäinen') - - "⊷": # 0x22b7 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "kuva" # (en: 'an image of', google: 'kuva') - - "⊸": [T: "monikuvaus"] # 0x22b8 - - "⊹": [T: "Hermiten konjugaattimatriisi"] # 0x22b9 (en: 'hermitian conjugate matrix', google: 'hermitian konjugaattimatriisi') - - "⊺": [T: "interkalaatio"] # 0x22ba (google: 'interkalaatti') - - "⊻": [T: "joko tai"] # 0x22bb - - "⊼": [T: "ja ei"] # 0x22bc - - "⊽": [T: "tai ei"] # 0x22bd (google: 'ei myöskään') - - "⊾": [T: "suora kulma kaarella"] # 0x22be (en: 'right angle with arc', google: 'suorakulma kaarilla') - - "⊿": [T: "oikeanpuoleinen kolmio"] # 0x22bf (en: 'right triangle') - - "⋀": [T: "monikkokonjuktio"] # 0x22c0 (en: 'logical and', google: 'looginen ja') - - "⋁": [T: "monikkodisjunktio"] # 0x22c1 (en: 'logical or', google: 'looginen tai') - - "⋂": [T: "monikkoleikkaus"] # 0x22c2 (en: 'intersection', google: 'risteys') - - "⋃": [T: "monikkounioni"] # 0x22c3 (en: 'union', google: 'liitto') - - "⋄": [T: "timantti"] # 0x22c4 (en: 'diamond operator', google: 'timanttioperaattori') - - "⋅": # 0x22c5 - - test: - if: "@data-chem-formula-op" - then: [T: "piste"] # (en: 'dot', google translation) - else: [T: "kertaa"] # (en: 'times', google: 'ajat') - - - "⋆": [T: "kertaa"] # 0x22c6 (en: 'times', google: 'ajat') - - "⋇": [T: "jako kertaa"] # 0x22c7 (en: 'division times', google: 'jako -ajat') - - "⋈": [T: "rusetti"] # 0x22c8 (en: 'bowtie', google: 'rusetti') - - "⋉": # 0x22c9 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "vasemmanpuoleinen normaalitekijäinen puolisuora tulo" # (en: 'the left normal factor semidirect product of', google: 'vasen normaali tekijä semidirect -tuote') - - "⋊": # 0x22ca - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "oikeanpuoleinen normaalitekijäinen puolisuora tulo" # (en: 'the right normal factor semidirect product of', google: 'oikea normaali tekijä semidirect -tuote') - - "⋋": # 0x22cb - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "vasemmanpuoleinen puolisuora tulo" # (en: 'the left semidirect product of', google: 'vasen puolisirektin tuote') - - "⋌": # 0x22cc - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "oikeanpuoleinen puolisuora tulo" # (en: 'the right semidirect product of', google: 'oikea semidirect -tuote') - - "⋍": [T: "käänteinen tilde yhtäsuuruus"] # 0x22cd (en: 'reversed tilde equals', google: 'käänteinen tilde on tasa -arvoinen') - - "⋎": [T: "kaareva looginen tai"] # 0x22ce (en: 'curly logical or', google: 'kihara looginen tai') - - "⋏": [T: "kaareva looginen ja"] # 0x22cf (en: 'curly logical and', google: 'curly looginen ja') - - "⋐": # 0x22d0 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "kaksoisosajoukko" # (en: 'a double subset of', google: 'kaksinkertainen osajoukko') - - "⋑": # 0x22d1 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "kaksoisylijoukko" # (en: 'a double superset of', google: 'kaksinkertainen superset') - - "⋒": # 0x22d2 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (google translation) - - T: "kaksoisleikkaus" # (en: 'double intersection of', google: 'kaksinkertainen risteys') - - "⋓": # 0x22d3 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (google translation) - - T: "kaksoisunioni" # (en: 'double union of', google: 'kaksinkertainen liitto') - - "⋔": # 0x22d4 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (google translation) - - T: "hanko" # (en: 'proper intersection of', google: 'oikea risteys') - - "⋕": # 0x22d5 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "yhtäsuuri ja yhdensuuntainen" # (en: 'equal to and parallel to', google: 'yhtä suuri kuin sen kanssa ja yhdensuuntainen') - - "⋖": [T: "piste pienempi kuin"] # 0x22d6 (en: 'less than with dot', google: 'vähemmän kuin pisteellä') - - "⋗": [T: "piste suurempi kuin"] # 0x22d7 (en: 'greater than with dot', google: 'suurempi kuin pisteellä') - - "⋘": # 0x22d8 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "hyvin paljon pienempi kuin" # (en: 'very much less than', google: 'hyvin vähemmän kuin') - - "⋙": # 0x22d9 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "hyvin paljon suurempi kuin" # (en: 'very much greater than', google: 'erittäin suurempi kuin') - - "⋚": # 0x22da - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "pienempi, yhtäsuuri tai suurempi kuin" # (en: 'less than equal to or greater than', google: 'vähemmän kuin yhtä suuri tai suurempi kuin') - - "⋛": # 0x22db - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "suurempi, yhtäsuuri tai pienempi kuin" # (en: 'greater than equal to or less than', google: 'suurempi kuin yhtä suuri tai vähemmän kuin') - - "⋜": # 0x22dc - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "yhtäsuuri tai pienempi kuin" # (en: 'equal to or less than', google: 'yhtä suuri tai vähemmän kuin') - - "⋝": # 0x22dd - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "yhtäsuuri tai suurempi kuin" # (en: 'equal to or greater than', google: 'yhtä suuri tai suurempi kuin') - - "⋞": # 0x22de - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "yhtä kuin tai edeltää" # (en: 'equal to or precedes', google: 'yhtä suuri tai edeltää') - - "⋟": # 0x22df - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "yhtä kuin tai seuraa" # (en: 'equal to or succeeds', google: 'yhtä suuri tai onnistuu') - - "⋠": [T: "ei edellä eikä yhtä kuin"] # 0x22e0 (en: 'does not precede nor is equal to', google: 'ei edeltä eikä ole yhtä suuri kuin') - - "⋡": [T: "ei seuraa eikä yhtä kuin"] # 0x22e1 (en: 'does not succeed nor is equal to', google: 'ei onnistu eikä ole yhtä suuri kuin') - - "⋢": [T: "ei kulmikas relaatio tai yhtä suuri kuin"] # 0x22e2 (en: 'not square image of or equal to', google: 'ei neliökuva tai yhtä suuri kuin') - - "⋣": [T: "ei käänteinen kulmikas relaatio tai yhtä suuri kuin"] # 0x22e3 (en: 'not square original of or equal to', google: 'ei neliömäinen alkuperäinen tai yhtä suuri kuin') - - "⋤": [T: "kulmikas relaatio ja ei yhtä suuri kuin"] # 0x22e4 (en: 'square image of or not equal to', google: 'neliökuva tai ei ole yhtä suuri kuin') - - "⋥": [T: "kulmikas käänteinen relaatio ja ei yhtä suuri kuin"] # 0x22e5 (en: 'square original of or not equal to', google: 'neliön alkuperäinen tai ei ole yhtä suuri kuin') - - "⋦": # 0x22e6 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "pienempi kuin mutta ei ekvivalentti" # (en: 'less than but not equivalent to', google: 'vähemmän kuin, mutta ei vastaava') - - "⋧": # 0x22e7 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "suurempi kuin mutta ei ekvivalentti" # (en: 'greater than but not equivalent to', google: 'suurempi kuin mutta ei vastaa') - - "⋨": [T: "edeltää mutta ei ole ekvivalentti"] # 0x22e8 (en: 'precedes but is not equivalent to', google: 'edeltää, mutta ei vastaa') - - "⋩": [T: "seuraa mutta ei ole ekvivalentti"] # 0x22e9 (en: 'succeeds but is not equivalent to', google: 'onnistuu, mutta ei vastaa') - - "⋪": # 0x22ea - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei ole normaali aliryhmä" # (en: 'not a normal subgroup of', google: 'ei normaali alaryhmä') - - "⋫": [T: "ei sisällä normaalia aliryhmää"] # 0x22eb (en: 'does not contain as a normal subgroup', google: 'ei sisällä normaalia alaryhmää') - - "⋬": # 0x22ec - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei ole normaali aliryhmä tai yhtä kuin" # (en: 'not a normal subgroup of nor is equal to', google: 'ei normaali alaryhmä, joka ei ole yhtä suuri') - - "⋭": [T: "ei sisällä normaalina aliryhmänä tai ole yhtä kuin"] # 0x22ed (en: 'does not contain as a normal subgroup nor is equal to', google: 'ei sisällä normaalia alaryhmää eikä ole yhtä suuri kuin') - - "⋮": [T: "pystyellipsi"] # 0x22ee (en: 'vertical ellipsis', google: 'pystysuora ellipsis') # FI: context? used in matrices? - - "⋯": [T: "piste piste piste"] # 0x22ef (en: 'dot dot dot', google: 'dot dot dot') - - "⋰": [T: "nouseva ellipsi"] # 0x22f0 (en: 'upwards diagonal ellipsis', google: 'ylöspäin diagonaalinen ellipsi') # FI: context? used in matrices? - - "⋱": [T: "laskeva ellipsi"] # 0x22f1 (en: 'diagonal ellipsis', google: 'diagonaalinen ellipsis') # FI: context? used in matrices? - - "⋲": [T: "poikkiviivainen kuulumismerkki"] # 0x22f2 (en: 'element of with long horizontal stroke', google: 'elementti pitkällä vaakasuoralla iskulla') - - "⋳": [T: "kuulumismerkki pystyviivaan päättyvällä poikkiviivalla"] # 0x22f3 (en: 'element of with vertical bar at end of horizontal stroke', google: 'elementti pystysuoralla tankolla vaakasuoran iskun lopussa') - - "⋴": [T: "pieni kuulumismerkki pystyviivaan päättyvällä poikkiviivalla"] # 0x22f4 (en: 'element of with vertical bar at end of horizontal stroke', google: 'elementti pystysuoralla tankolla vaakasuoran iskun lopussa') - - "⋵": [T: "kuuluu joukkoon pisteellä"] # 0x22f5 (en: 'element of with dot above', google: 'elementti yllä olevalla pisteellä') - - "⋶": [T: "kuuluu joukkoon yläviivalla"] # 0x22f6 (en: 'element of with overbar', google: 'elementti ylikuormituksella') - - "⋷": [T: "pieni kuuluu joukkoon yläviivalla"] # 0x22f7 (en: 'element of with overbar', google: 'elementti ylikuormituksella') - - "⋸": [T: "kuuluu joukkoon alaviivalla"] # 0x22f8 (en: 'element of with underbar', google: 'elementti alakerroksella') - - "⋹": [T: "kuuluu joukkoon kaksoispoikkiviivalla"] # 0x22f9 (en: 'element of with two horizontal strokes', google: 'elementti kahdella vaakasuuntaisella iskulla') - - "⋺": [T: "käänteinen kuuluu joukkoon poikkiviivalla"] # 0x22fa (en: 'contains with long horizontal stroke', google: 'sisältää pitkällä vaakasuoralla iskulla') - - "⋻": [T: "käänteinen kuuluu joukkoon pystyviivaan päättyvällä poikkiviivalla"] # 0x22fb (en: 'contains with vertical bar at end of horizontal stroke', google: 'sisältää pystysuoran palkin vaakasuoran iskun lopussa') - - "⋼": [T: "pieni käänteinen kuuluu joukkoon pystyviivaan päättyvällä poikkiviivalla"] # 0x22fc (en: 'contains with vertical bar at end of horizontal stroke', google: 'sisältää pystysuoran palkin vaakasuoran iskun lopussa') - - "⋽": [T: "sisältää tai on yhtä suuri kuin"] # 0x22fd (en: 'contains with overbar', google: 'sisältää ylikuormituksen kanssa') - - "⋾": [T: "pieni sisältää tai on yhtä suuri kuin"] # 0x22fe (en: 'contains with overbar', google: 'sisältää ylikuormituksen kanssa') - - "⋿": [T: "Z-notaation laukkuun kuulumisen merkki"] # 0x22ff (google: 'z -merkintälaukun jäsenyys') - - "⌀": [T: "halkaisija"] # 0x2300 (en: 'diameter') - - "⌁": [T: "sähkönuoli"] # 0x2301 (en: 'electric arrow', google translation) - - "⌂": [T: "talo"] # 0x2302 (en: 'house') - - "⌃": [T: "nuolenpää ylös"] # 0x2303 (en: 'up arrowhead', google translation) - - "⌄": [T: "nuolenpää alas"] # 0x2304 (en: 'down arrowhead', google translation) - - "⌅": [T: "projektio"] # 0x2305 (en: 'projective', google: 'projektiivinen') - - "⌆": [T: "perspektiivi"] # 0x2306 (en: 'perspective', google: 'näkökulma') - - "⌇": [T: "aaltoviiva"] # 0x2307 (en: 'wavy line', google translation) - - "⌈": [T: "vasen katto"] # 0x2308 (en: 'left ceiling') - - "⌉": [T: "oikea katto"] # 0x2309 (en: 'right ceiling') - - "⌊": [T: "vasen lattia"] # 0x230a (en: 'left floor') - - "⌋": [T: "oikea lattia"] # 0x230b (en: 'right floor', google: 'oikea kerros') - - "⌌": [T: "oikea alanurkkarajaus"] # 0x230c (en: 'bottom right crop', google: 'oikea alareuna') - - "⌍": [T: "vasen alanurkkarajaus"] # 0x230d (en: 'bottom left crop', google: 'vasen alakulma') - - "⌎": [T: "oikea ylänurkkarajaus"] # 0x230e (en: 'top right crop', google: 'oikea yläosa') - - "⌏": [T: "vasen ylänurkkarajaus"] # 0x230f (en: 'top left crop', google: 'vasen yläosa sato') - - "⌐": [T: "käännetty negaatio"] # 0x2310 (en: 'reversed not sign', google: 'kääntynyt ei allekirjoitettu') - - "⌑": [T: "tyynysymboli"] # 0x2311 (google translation) - - "⌒": [T: "yläkaari"] # 0x2312 (en: 'arc', google: 'kaari') - - "⌓": [T: "segmentti"] # 0x2313 (en: 'segment') - - "⌔": [T: "sektori"] # 0x2314 (en: 'sector', google translation) - - "⌕": [T: "suurennuslasi"] # 0x2315 (google: 'puhelintallistin') - - "⌖": [T: "tähtäin"] # 0x2316 (en: 'position indicator crosshairs', google: 'aseman ilmaisimen ristikkäit') - - "⌗": [T: "risuaita"] # 0x2317 (en: 'viewdata square', google translation) - - "⌘": [T: "hannunvaakuna"] # 0x2318 (en: 'place of interest sign', google: 'kiinnostuksen kohteena oleva merkki') - - "⌙": [T: "kääntynyt negaatio"] # 0x2319 (en: 'turned not sign', google translation) - - "⌚": [T: "kello"] # 0x231a (en: 'watch', google: 'katsella') - - "⌛": [T: "tiimalasi"] # 0x231b (en: 'hourglass', google translation) - - "⌜": [T: "vasen ylänurkka"] # 0x231c (en: 'top left corner', google: 'vasen yläkulma') - - "⌝": [T: "oikea ylänurkka"] # 0x231d (en: 'top right corner', google: 'oikea yläkulma') - - "⌞": [T: "vasen alanurkka"] # 0x231e (en: 'bottom left corner', google: 'vasen alakulma') - - "⌟": [T: "oikea alanurkka"] # 0x231f (en: 'bottom right corner', google: 'oikea alakulma') - - "⌠": [T: "integraalin yläpuoli"] # 0x2320 (en: 'top half integral', google: 'top -puoliksi olennainen') - - "⌡": [T: "integraalin alapuoli"] # 0x2321 (en: 'bottom half integral', google: 'pohjapuoliskon integraali') - - "⌢": [T: "yläkaari"] # 0x2322 (en: 'frown', google: 'kulma') - - "⌣": [T: "alakaari"] # 0x2323 (en: 'smile', google: 'hymy') - - "⌤": [T: "nuolenpää ylös kahden vaakasuoran palkin välissä"] # 0x2324 (en: 'up arrowhead between two horizontal bars', google translation) - - "⌥": [T: "option"] # 0x2325 (en: 'option key', google translation) - - "⌦": [T: "poista oikealle"] # 0x2326 (en: 'erase to the right', google translation) - - "⌧": [T: "suorakulmiossa oleva rasti"] # 0x2327 (en: 'x in a rectangle box', google translation) - - "⌨": [T: "näppäimistö"] # 0x2328 (en: 'keyboard', google translation) - - "〈": [T: "vasen kulmasulku"] # 0x2329 (en: 'left pointing angle bracket', google: 'vasen osoituskulmakiinnike') - - "〉": [T: "oikea kulmasulku"] # 0x232a (en: 'right pointing angle bracket', google: 'oikea osoituskulmakiinnike') - - "⌫": [T: "poista vasemmalle"] # 0x232b (en: 'erase to the left', google translation) - - "⌬": [T: "bentseenirengas"] # 0x232c (en: 'benzene ring', google translation) - - "⌭": [T: "sylinterisyys"] # 0x232d (google: 'sylinteryys') - - "⌮": [T: "profiilin ympäri"] # 0x232e (en: "all around profile" google: 'ympäri profiilia') # FI: translation unclear - - "⌯": [T: "symmetria"] # 0x232f (en: 'symmetry', google translation) - - "⌰": [T: "toleranssin yhteissumma"] # 0x2330 (en: 'total runout', google translation) # FI: meaning bit unclear, placeholder for correct - - "⌱": [T: "alkudimensio"] # 0x2331 (en: 'dimension origin', google translation) # FI: translation unclear - - "⌲": [T: "kartiovähentyminen"] # 0x2332 (en: 'conical taper', google translation) # FI: translation unclear - - "⌳": [T: "kaltevuus"] # 0x2333 (en: 'slope', google translation) - - "⌴": [T: "tasoupotin"] # 0x2334 (en: 'counterbore', google translation) - - "⌵": [T: "kärkiupotin"] # 0x2335 (en: 'countersink', google translation) - - "⍰": [T: "kysymysmerkki laatikossa"] # 0x2370 (en: 'unknown box', google: 'tuntematon laatikko') - - "⎕": [T: "laatikko"] # 0x2395 (en: 'box', google translation) - - "⏞": [T: "yläaaltosulku"] # 0x23DE (en: 'top brace', google: 'ylä ahdin') - - "⏟": [T: "ala-aaltosulku"] # 0x23DF (en: 'bottom brace', google: 'pohja ahdin') - - "①-⑨": # 0x2460 - 0x2469 - - T: "ympyröity" # (en: 'circled', google: 'ympyröi') - - SPELL: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" - - "⑩": [T: "ympyröity kymmenen"] # 0x2469 (en: 'circled ten', google translation) - - "⑪": [T: "ympyröity yksitoista"] # 0x246a (en: 'circled eleven', google translation) - - "⑫": [T: "ympyröity kaksitoista"] # 0x246b (en: 'circled twelve', google translation) - - "⑬": [T: "ympyröity kolmetoista"] # 0x246c (en: 'circled thirteen', google translation) - - "⑭": [T: "ympyröity neljätoista"] # 0x246d (en: 'circled fourteen', google translation) - - "⑮": [T: "ympyröity viisitoista"] # 0x246e (en: 'circled fifteen', google translation) - - "⑯": [T: "ympyröity kuusitoista"] # 0x246f (en: 'circled sixteen', google translation) - - "⑰": [T: "ympyröity seitsemäntoista"] # 0x2470 (en: 'circled seventeen', google translation) - - "⑱": [T: "ympyröity kahdeksantoista"] # 0x2471 (en: 'circled eighteen', google translation) - - "⑳": [T: "ympyröity kaksikymmentä"] # 0x2473 (en: 'circled twenty', google translation) - - "⑴-⑼": # 0x2474 - 0x247d - - T: "suluissa" # (en: 'parenthesized', google translation) - - SPELL: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" - - "⑽": [T: "suluissa kymmenen"] # 0x247d (en: 'parenthesized ten', google translation) - - "⑾": [T: "suluissa yksitoista"] # 0x247e (en: 'parenthesized eleven', google translation) - - "⑿": [T: "suluissa kaksitoista"] # 0x247f (en: 'parenthesized twelve', google translation) - - "⒀": [T: "suluissa kolmetoista"] # 0x2480 (en: 'parenthesized thirteen', google translation) - - "⒁": [T: "suluissa neljätoista"] # 0x2481 (en: 'parenthesized fourteen', google translation) - - "⒂": [T: "suluissa viisitoista"] # 0x2482 (en: 'parenthesized fifteen', google translation) - - "⒃": [T: "suluissa kuusitoista"] # 0x2483 (en: 'parenthesized sixteen', google translation) - - "⒄": [T: "suluissa seitsemäntoista"] # 0x2484 (en: 'parenthesized seventeen', google translation) - - "⒅": [T: "suluissa kahdeksantoista"] # 0x2485 (en: 'parenthesized eighteen', google translation) - - "⒆": [T: "suluissa yhdeksäntoista"] # 0x2486 (en: 'parenthesized nineteen', google translation) - - "⒇": [T: "suluissa kaksikymmentä"] # 0x2487 (en: 'parenthesized twenty', google translation) - - "⒈-⒐": # 0x2488 - 0x2491 # FI: should these be ordinals? - - SPELL: "translate('.', '⒈⒉⒊⒋⒌⒍⒎⒏⒐', '123456789')" - - T: "pisteellä" # (en: 'with period', google translation) - - "⒑": [T: "kymmenen pisteellä"] # 0x2491 (en: 'ten with period', google translation) - - "⒒": [T: "yksitoista pisteellä"] # 0x2492 (en: 'eleven with period', google translation) - - "⒓": [T: "kaksitoista pisteellä"] # 0x2493 (en: 'twelve with period', google translation) - - "⒔": [T: "kolmetoista pisteellä"] # 0x2494 (en: 'thirteen with period', google translation) - - "⒕": [T: "neljätoista pisteellä"] # 0x2495 (en: 'fourteen with period', google translation) - - "⒖": [T: "viisitoista pisteellä"] # 0x2496 (en: 'fifteen with period', google translation) - - "⒗": [T: "kuusitoista pisteellä"] # 0x2497 (en: 'sixteen with period', google translation) - - "⒘": [T: "seitsemäntoista pisteellä"] # 0x2498 (en: 'seventeen with period', google translation) - - "⒙": [T: "kahdeksantoista pisteellä"] # 0x2499 (en: 'eighteen with period', google translation) - - "⒚": [T: "yhdeksäntoista pisteellä"] # 0x249a (en: 'nineteen with period', google translation) - - "⒛": [T: "kaksikymmentä pisteellä"] # 0x249b (en: 'twenty with period', google translation) - - "⒜-⒵": # 0x249c - 0x24b5 - - T: "suluissa" # (en: 'parenthesized', google translation) - - SPELL: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" - - - "Ⓐ-Ⓩ": - - T: "ympyröity" # (en: 'circled', google translation) - - SPELL: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "🅐-🅩": # 0x1f150 - 0x1f169 - - T: "musta ympyröity" # (en: 'black circled', google translation) - - SPELL: "translate('.', '🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 - - T: "ympyröity" # (en: 'circled', google translation) - - SPELL: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" - - "⓪": [T: "ympyröity nolla"] # 0x24ea (en: 'circled zero', google translation) - - "⓫": [T: "musta ympyröity yksitoista"] # 0x24eb (en: 'black circled eleven', google translation) - - "⓬": [T: "musta ympyröity kaksitoista"] # 0x24ec (en: 'black circled twelve', google translation) - - "⓭": [T: "musta ympyröity kolmetoista"] # 0x24ed (en: 'black circled thirteen', google translation) - - "⓮": [T: "musta ympyröity neljätoista"] # 0x24ee (en: 'black circled fourteen', google translation) - - "⓯": [T: "musta ympyröity viisitoista"] # 0x24ef (en: 'black circled fifteen', google translation) - - "⓰": [T: "musta ympyröity kuusitoista"] # 0x24f0 (en: 'black circled sixteen', google translation) - - "⓱": [T: "musta ympyröity seitsemäntoista"] # 0x24f1 (en: 'black circled seventeen', google translation) - - "⓲": [T: "musta ympyröity kahdeksantoista"] # 0x24f2 (en: 'black circled eighteen', google translation) - - "⓳": [T: "musta ympyröity yhdeksäntoista"] # 0x24f3 (en: 'black circled nineteen', google translation) - - "⓴": [T: "musta ympyröity kaksikymmentä"] # 0x24f4 (en: 'black circled twenty', google translation) - - "⓵-⓽": # 0x24f5 - 0x24fe - - T: "kaksinkertaisesti ympyröity" # (en: 'double circled', google translation) - - SPELL: "translate('.', '⓵⓶⓷⓸⓹⓺⓻⓼⓽', '123456789')" - - "⓾": [T: "kaksinkertaisesti ympyröity kymmenen"] # 0x24fe (en: 'double circled ten', google translation) - - "⓿": [T: "musta ympyröity nolla"] # 0x24ff (en: 'black circled zero', google translation) - - "■": [T: "musta neliö"] # 0x25a0 (en: 'black square') - - "□": [T: "valkoinen neliö"] # 0x25a1 (en: 'white square') - - "▢": [T: "pyöreäkulmainen valkoinen neliö"] # 0x25a2 (en: 'white square with rounded corners', google translation) - - "▣": [T: "mustan neliön sisältävä valkoinen neliö"] # 0x25a3 (en: 'white square containing small black square', google translation) - - "▤": [T: "neliö vaakasuoralla värityksellä"] # 0x25a4 (en: 'square with horizontal fill', google translation) - - "▥": [T: "neliö pystysuoralla värityksellä"] # 0x25a5 (en: 'square with vertical fill', google translation) - - "▦": [T: "neliö ruudukkovärityksellä"] # 0x25a6 (en: 'square with orthogonal crosshatch fill', google translation) - - "▧": [T: "neliö värityksellä ylävasemmalta alaoikelle"] # 0x25a7 (en: 'square with upper left to lower right fill', google translation) - - "▨": [T: "neliö värityksellä yläoikealta alavasemmalle"] # 0x25a8 (en: 'square with upper right to lower left fill', google translation) - - "▩": [T: "neliö diagonaalisella ristikkovärityksellä"] # 0x25a9 (en: 'square with diagonal crosshatch fill', google translation) - - "▪": [T: "pieni musta neliö"] # 0x25aa (en: 'black small square', google: 'musta pieni neliö') - - "▫": [T: "pieni valkoinen neliö"] # 0x25ab (en: 'white small square', google: 'valkoinen pieni neliö') - - "▬": [T: "musta suorakaide"] # 0x25ac (en: 'black rectangle', google translation) - - "▭": [T: "valkoinen suorakaide"] # 0x25ad (en: 'white rectangle', google: 'valkoinen suorakulmio') - - "▮": [T: "musta pysty suorakaide"] # 0x25ae (en: 'black vertical rectangle', google: 'musta pystysuora suorakulmio') - - "▯": [T: "valkoinen pysty suorakaide"] # 0x25af (en: 'white vertical rectangle', google: 'valkoinen pystysuora suorakulmio') - - "▰": [T: "musta suunnikas"] # 0x25b0 (en: 'black parallelogram', google translation) - - "▱": [T: "valkoinen suunnikas"] # 0x25b1 (en: 'white parallelogram', google: 'valkoinen rinnakkainen ohjelma') - - "▲": [T: "musta ylös osoittava kolmio"] # 0x25b2 (en: 'black up pointing triangle', google: 'musta ylöspäin osoittava kolmio') - - "△": [T: "valkoinen ylös osoittava kolmio"] # 0x25b3 (en: 'white up pointing triangle', google: 'valkoinen osoitus kolmio') - - "▴": [T: "pieni musta ylös osoittava kolmio"] # 0x25b4 (en: 'black up pointing small triangle', google: 'musta ylös osoittaen pientä kolmiota') - - "▵": [T: "pieni valkoinen ylös osoittava kolmio"] # 0x25b5 (en: 'white up pointing small triangle', google: 'valkoinen osoittaen pientä kolmiota') - - "▶": [T: "musta oikealle osoittava kolmio"] # 0x25b6 (en: 'black right pointing triangle', google: 'musta oikea osoitus kolmio') - - "▷": [T: "valkoinen oikealle osoittava kolmio"] # 0x25b7 (en: 'white right pointing triangle', google: 'valkoinen oikea osoitus kolmio') - - "▸": [T: "pieni musta oikealle osoittava kolmio"] # 0x25b8 (en: 'black right pointing small triangle', google: 'musta oikea osoittaen pieni kolmio') - - "▹": [T: "pieni valkoinen oikealle osoittava kolmio"] # 0x25b9 (en: 'white right pointing small triangle', google: 'valkoinen oikea osoittaen pieni kolmio') - - "►": [T: "musta oikea osoitin"] # 0x25ba (en: 'black right pointing pointer', google translation) - - "▻": [T: "valkoinen oikea osoitin"] # 0x25bb (en: 'white right pointing pointer', google translation) - - "▼": [T: "musta alas osoittava kolmio"] # 0x25bc (en: 'black down pointing triangle', google: 'musta alaspäin osoittava kolmio') - - "▽": [T: "valkoinen alas osoittava kolmio"] # 0x25bd (en: 'white down pointing triangle', google: 'valkoinen alaspäin osoittava kolmio') - - "▾": [T: "pieni musta alas osoittava kolmio"] # 0x25be (en: 'black down pointing small triangle', google: 'musta alaspäin osoittaen pieni kolmio') - - "▿": [T: "pieni valkoinen alas osoittava kolmio"] # 0x25bf (en: 'white down pointing small triangle', google: 'valkoinen alas osoittaen pieni kolmio') - - "◀": [T: "musta vasemmalle osoittava kolmio"] # 0x25c0 (en: 'black left pointing triangle', google: 'musta vasen osoitus kolmio') - - "◁": [T: "valkoinen vasemmalle osoittava kolmio"] # 0x25c1 (en: 'white left pointing triangle', google: 'valkoinen vasen osoitus kolmio') - - "◂": [T: "pieni musta vasemmalle osoittava kolmio"] # 0x25c2 (en: 'black left pointing small triangle', google: 'musta vasen osoittaa pieni kolmio') - - "◃": [T: "pieni valkoinen vasemmalle osoittava kolmio"] # 0x25c3 (en: 'white left pointing small triangle', google: 'valkoinen vasen osoitus pieni kolmio') - - "◄": [T: "musta vasemmalle osoittava osoitin"] # 0x25c4 (en: 'black left pointing pointer', google: 'musta vasen osoitin') - - "◅": [T: "valkoinen vasemmalle osoittava osoitin"] # 0x25c5 (en: 'white left pointing pointer', google: 'valkoinen vasen osoitin') - - "◆": [T: "musta timantti"] # 0x25c6 (en: 'black diamond', google: 'musta timantti') - - "◇": [T: "valkoinen timantti"] # 0x25c7 (en: 'white diamond', google: 'valkoinen timantti') - - "◈": [T: "valkoinen timantti jonka sisällä musta timantti"] # 0x25c8 (en: 'white diamond containing black small diamond', google: 'valkoinen timantti, joka sisältää mustan pienen timantin') - - "◉": [T: "valkoinen ympyrä jonka sisällä musta ympyrä"] # 0x25c9 (en: 'fisheye', google: 'kalake') - - "◊": [T: "vinoneliö"] # 0x25ca (en: 'lozenge', google: 'pastilli') - - "○": [T: "valkoinen ympyrä"] # 0x25cb (en: 'white circle') - - "◌": [T: "pisteympyrä"] # 0x25cc (en: 'dotted circle', google: 'pisteympyrä') - - "◍": [T: "ympyrä ja pystysuora viivoitus"] # 0x25cd (en: 'circle with vertical fill', google: 'ympyrä pystysuoralla täyttöä') - - "◎": [T: "kaksi sisäkkäistä ympyrää"] # 0x25ce (en: 'bullseye', google: 'bullseye') - - "●": [T: "musta ympyrä"] # 0x25cf (en: 'black circle') - - "◐": [T: "ympyrä vasen puoli musta"] # 0x25d0 (en: 'circle with left half black', google: 'ympyrä vasemmalla puoliksi mustalla') - - "◑": [T: "ympyrä oikea puoli musta"] # 0x25d1 (en: 'circle with right half black', google: 'ympyrä oikealla puoliksi mustalla') - - "◒": [T: "ympyrä alapuoli musta"] # 0x25d2 (en: 'circle with lower half black', google: 'ympyrä, jossa on alaosa musta') - - "◓": [T: "ympyrä yläpuoli musta"] # 0x25d3 (en: 'circle with upper half black', google: 'ympyrä yläpuoliskolla mustalla') - - "◔": [T: "ympyrä yläoikea neljännes musta"] # 0x25d4 (en: 'circle with upper right quadrant black', google: 'ympyrä oikealla yläkulmalla kvadrantti musta') - - "◕": [T: "ympyrä ylävasen neljännes mustaamatta"] # 0x25d5 (en: 'circle with all but upper left quadrant black', google: 'ympyrä kaikilla paitsi vasemmalla yläosalla mustaa') - - "◖": [T: "musta vasen puoliympyrä"] # 0x25d6 (en: 'left half black circle', google: 'vasen puoli musta ympyrä') - - "◗": [T: "musta oikea puoliympyrä"] # 0x25d7 (en: 'right half black circle', google: 'oikea puoli musta ympyrä') - - "◘": [T: "luetelmapallon negatiivi"] # 0x25d8 (en: 'inverse bullet', google: 'käänteinen luoti') - - "◙": [T: "valkoisen ympyrän negatiivi"] # 0x25d9 (en: 'inverse white circle', google: 'käänteinen valkoinen ympyrä') - - "◚": [T: "valkoisen ympyrän negatiivin yläpuoli"] # 0x25da (en: 'upper half inverse white circle', google: 'yläosa käänteinen valkoinen ympyrä') - - "◛": [T: "valkoisen ympyrän negatiivin alapuoli"] # 0x25db (en: 'lower half inverse white circle', google: 'alempi puoli käänteinen valkoinen ympyrä') - - "◜": [T: "ympyrän kaaren vasen yläneljännes"] # 0x25dc (en: 'upper left quadrant circular arc', google: 'vasen yläosa kvadrantti pyöreä kaari') - - "◝": [T: "ympyrän kaaren oikea yläneljännes"] # 0x25dd (en: 'upper right quadrant circular arc', google: 'oikea yläosa kvadrantti pyöreä kaari') - - "◞": [T: "ympyrän kaaren oikea alaneljännes"] # 0x25de (en: 'lower right quadrant circular arc', google: 'oikea alaosa neljänneksen pyöreä kaari') - - "◟": [T: "ympyrän kaaren vasen alaneljännes"] # 0x25df (en: 'lower left quadrant circular arc', google: 'vasen alakulmainen kvadrantti pyöreä kaari') - - "◠": [T: "ympyrän kaaren yläpuolikas"] # 0x25e0 (en: 'upper half circle', google: 'yläosa ympyrä') - - "◡": [T: "ympyrän kaaren alapuolikas"] # 0x25e1 (en: 'lower half circle', google: 'alempi puoli ympyrä') - - "◢": [T: "musta oikea alakolmio"] # 0x25e2 (en: 'black lower right triangle', google: 'musta alaosa oikea kolmio') - - "◣": [T: "musta vasen alakolmio"] # 0x25e3 (en: 'black lower left triangle', google: 'musta vasen alaosa kolmio') - - "◤": [T: "musta vasen yläkolmio"] # 0x25e4 (en: 'black upper left triangle', google: 'musta vasen yläosa kolmio') - - "◥": [T: "musta oikea yläkolmio"] # 0x25e5 (en: 'black upper right triangle', google: 'musta oikea yläosa kolmio') - - "◦": [T: "valkoinen pallo"] # 0x25e6 (en: 'composition', google: 'sävellys') - - "◧": [T: "neliö vasen puoli musta"] # 0x25e7 (en: 'square with left half black', google: 'neliö vasemmalla puoliksi mustalla') - - "◨": [T: "neliö oikea puoli musta"] # 0x25e8 (en: 'square with right half black', google: 'neliö oikealla puoliksi mustalla') - - "◩": [T: "neliö vasen ylädiagonaali musta"] # 0x25e9 (en: 'square with upper left half black', google: 'neliö vasemmalla yläosa mustalla') - - "◪": [T: "neliö oikea aladiagonaali musta"] # 0x25ea (en: 'square with lower right half black', google: 'neliö oikealla alaosa mustalla') - - "◫": [T: "valkoinen neliö pystysuoralla poikkiviivalla"] # 0x25eb (en: 'white square with bisecting line', google: 'valkoinen neliö puolustamisviivalla') - - "◬": [T: "valkoinen ylös osoittava kolmio pisteellä"] # 0x25ec (en: 'white up pointing triangle with dot', google: 'valkoinen osoittava kolmio pisteellä') - - "◭": [T: "valkoinen ylös osoittava kolmio, vasen puoli musta"] # 0x25ed (en: 'up pointing triangle with left half black', google: 'ylöspäin osoittaen kolmio vasemmalla puoliksi mustalla') - - "◮": [T: "valkoinen ylös osoittava kolmio, oikea puoli musta"] # 0x25ee (en: 'up pointing triangle with right half black', google: 'ylös osoittaen kolmio oikealla puoliksi mustalla') - - "◯": [T: "valkoinen ympyrä"] # 0x25ef (en: 'large circle', google: 'suuri ympyrä') - - "◰": [T: "valkoinen neliö josta on erotettu ylävasen neljännes"] # 0x25f0 (en: 'white square with upper left quadrant', google translation) - - "◱": [T: "valkoinen neliö josta on erotettu alavasen neljännes"] # 0x25f1 (en: 'white square with lower left quadrant', google translation) - - "◲": [T: "valkoinen neliö josta on erotettu alaoikea neljännes"] # 0x25f2 (en: 'white square with lower right quadrant', google translation) - - "◳": [T: "valkoinen neliö josta on erotettu yläoikea neljännes"] # 0x25f3 (en: 'white square with upper right quadrant', google translation) - - "◴": [T: "valkoinen ympyrä josta on erotettu ylävasen neljännes"] # 0x25f4 (en: 'white circle with upper left quadrant', google translation) - - "◵": [T: "valkoinen ympyrä josta on erotettu alavasen neljännes"] # 0x25f5 (en: 'white circle with lower left quadrant', google translation) - - "◶": [T: "valkoinen ympyrä josta on erotettu alaoikea neljännes"] # 0x25f6 (en: 'white circle with lower right quadrant', google translation) - - "◷": [T: "valkoinen ympyrä josta on erotettu yläoikea neljännes"] # 0x25f7 (en: 'white circle with upper right quadrant', google translation) - - "◸": [T: "ylävasen kolmio"] # 0x25f8 (en: 'upper left triangle', google: 'vasen yläosa kolmio') - - "◹": [T: "yläoikea kolmio"] # 0x25f9 (en: 'upper right triangle', google: 'oikea yläosa kolmio') - - "◺": [T: "alavasen kolmio"] # 0x25fa (en: 'lower left triangle', google: 'vasen alaosa kolmio') - - "◻": [T: "keskikokoinen valkoinen neliö"] # 0x25fb (en: 'white medium square', google: 'valkoinen keskipitkä neliö') - - "◼": [T: "keskikokoinen musta neliö"] # 0x25fc (en: 'black medium square', google: 'musta keskipitkä neliö') - - "◽": [T: "pienehkö valkoinen neliö"] # 0x25fd (en: 'white medium small square', google: 'valkoinen keskipitkä pieni neliö') - - "◾": [T: "pienehkö musta neliö"] # 0x25fe (en: 'black medium small square', google: 'musta keskipitkä pieni neliö') - - "◿": [T: "alaoikea kolmio"] # 0x25ff (en: 'lower right triangle', google: 'oikea alaosa kolmio') - - "♠": [T: "musta pata"] # 0x2660 (en: 'black spade suit', google: 'musta lapio puku') - - "♡": [T: "valkoinen hertta"] # 0x2661 (en: 'white heart suit', google: 'valkoinen sydänpuku') - - "♢": [T: "valkoinen ruutu"] # 0x2662 (en: 'white diamond suit', google: 'valkoinen timanttipuku') - - "♣": [T: "musta risti"] # 0x2663 (en: 'black club suit', google: 'mustakerhopuku') - - "♤": [T: "valkoinen pata"] # 0x2664 (en: 'white spade suit', google: 'valkoinen lapiopuku') - - "♥": [T: "musta hertta"] # 0x2665 (en: 'black heart suit', google: 'musta sydänpuku') - - "♦": [T: "musta ruutu"] # 0x2666 (en: 'black diamond suit', google: 'musta timanttipuku') - - "♧": [T: "valkoinen risti"] # 0x2667 (en: 'white club suit', google: 'valkoinen klubipuku') - - "❨": [T: "keskikokoinen vasen sulkukoriste"] # 0x2768 (en: 'medium left parentheses ornament', google translation) - - "❩": [T: "keskikokoinen oikea sulkukoriste"] # 0x2769 (en: 'medium right parentheses ornament', google translation) - - "❪": [T: "keskikokoinen litistetty vasen sulkukoriste"] # 0x276a (en: 'medium flattened left parentheses ornament', google translation) - - "❫": [T: "keskikokoinen litistetty oikea sulkukoriste"] # 0x276b (en: 'medium flattened right parentheses ornament', google translation) - - "❬": [T: "keskikokoinen vasen kulmasulkukoriste"] # 0x276c (en: 'medium left-pointing angle bracket ornament', google translation) - - "❭": [T: "keskikokoinen oikea kulmasulkukoriste"] # 0x276d (en: 'medium right-pointing angle bracket ornament', google translation) - - "❮": [T: "raskas vasen kulmalainausmerkkikoriste"] # 0x276e (en: 'heavy left-pointing angle quotation mark ornament', google translation) - - "❯": [T: "raskas oikea kulmalainausmerkkikoriste"] # 0x276f (en: 'heavy right-pointing angle quotation mark ornament', google translation) - - "❰": [T: "raskas vasen kulmasulkukoriste"] # 0x2770 (en: 'heavy left-pointing angle bracket ornament', google translation) - - "❱": [T: "raskas oikea kulmasulkukoriste"] # 0x2771 (en: 'heavy right-pointing angle bracket ornament', google translation) - - "❲": [T: "kevyt vasen kilpikonnankuorisulkukoriste"] # 0x2772 (en: 'light left tortoise shell bracket ornament', google translation) - - "❳": [T: "kevyt oikea kilpikonnankuorisulkukoriste"] # 0x2773 (en: 'light right tortoise shell bracket ornament', google translation) - - "❴": [T: "keskikokoinen vasen aaltosulkukoriste"] # 0x2774 (en: 'medium left brace ornament', google translation) - - "❵": [T: "keskikokoinen oikea aaltosulkukoriste"] # 0x2775 (en: 'medium right brace ornament', google translation) - - "❶": [T: "musta ympyröity yksi"] # 0x2776 (en: 'black circled one', google translation) - - "❷": [T: "musta ympyröity kaksi"] # 0x2777 (en: 'black circled two', google translation) - - "❸": [T: "musta ympyröity kolme"] # 0x2778 (en: 'black circled three', google translation) - - "❹": [T: "musta ympyröity neljä"] # 0x2779 (en: 'black circled four', google translation) - - "❺": [T: "musta ympyröity viisi"] # 0x277a (en: 'black circled five', google translation) - - "❻": [T: "musta ympyröity kuusi"] # 0x277b (en: 'black circled six', google translation) - - "❼": [T: "musta ympyröity seitsemän"] # 0x277c (en: 'black circled seven', google translation) - - "❽": [T: "musta ympyröity kahdeksan"] # 0x277d (en: 'black circled eight', google translation) - - "❾": [T: "musta ympyröity yhdeksän"] # 0x277e (en: 'black circled nine', google translation) - - "❿": [T: "musta ympyröity kymmenen"] # 0x277f (en: 'black circled ten', google translation) - - "➀": [T: "ympyröity sans serif yksi"] # 0x2780 (en: 'circled sans serif one', google translation) - - "➁": [T: "ympyröity sans serif kaksi"] # 0x2781 (en: 'circled sans serif two', google translation) - - "➂": [T: "ympyröity sans serif kolme"] # 0x2782 (en: 'circled sans serif three', google translation) - - "➃": [T: "ympyröity sans serif neljä"] # 0x2783 (en: 'circled sans serif four', google translation) - - "➄": [T: "ympyröity sans serif viisi"] # 0x2784 (en: 'circled sans serif five', google translation) - - "➅": [T: "ympyröity sans serif kuusi"] # 0x2785 (en: 'circled sans serif six', google translation) - - "➆": [T: "ympyröity sans serif seitsemän"] # 0x2786 (en: 'circled sans serif seven', google translation) - - "➇": [T: "ympyröity sans serif kahdeksan"] # 0x2787 (en: 'circled sans serif eight', google translation) - - "➈": [T: "ympyröity sans serif yhdeksän"] # 0x2788 (en: 'circled sans serif nine', google translation) - - "➉": [T: "ympyröity sans serif kymmenen"] # 0x2789 (en: 'circled sans serif ten', google translation) - - "➊": [T: "musta ympyröity sans serif yksi"] # 0x278a (en: 'black circled sans serif one', google translation) - - "➋": [T: "musta ympyröity sans serif kaksi"] # 0x278b (en: 'black circled sans serif two', google translation) - - "➌": [T: "musta ympyröity sans serif kolme"] # 0x278c (en: 'black circled sans serif three', google translation) - - "➍": [T: "musta ympyröity sans serif neljä"] # 0x278d (en: 'black circled sans serif four', google translation) - - "➎": [T: "musta ympyröity sans serif viisi"] # 0x278e (en: 'black circled sans serif five', google translation) - - "➏": [T: "musta ympyröity sans serif kuusi"] # 0x278f (en: 'black circled sans serif six', google translation) - - "➐": [T: "musta ympyröity sans serif seitsemän"] # 0x2790 (en: 'black circled sans serif seven', google translation) - - "➑": [T: "musta ympyröity sans serif kahdeksan"] # 0x2791 (en: 'black circled sans serif eight', google translation) - - "➒": [T: "musta ympyröity sans serif yhdeksän"] # 0x2792 (en: 'black circled sans serif nine', google translation) - - "➓": [T: "musta ympyröity sans serif kymmenen"] # 0x2793 (en: 'black circled sans serif ten', google translation) - - "➔": [T: "raskas leveäpäinen oikea nuoli"] # 0x2794 (en: 'heavy wide-headed rightwards arrow', google translation) - - "➕": [T: "raskas plusmerkki"] # 0x2795 (en: 'heavy plus sign', google translation) - - "➖": [T: "raskas miinusmerkki"] # 0x2796 (en: 'heavy minus sign', google translation) - - "➗": [T: "raskas jakomerkki"] # 0x2797 (en: 'heavy division sign', google translation) - - "➘": [T: "raskas alaoikea nuoli"] # 0x2798 (en: 'heavy south east arrow', google translation) - - "➙": [T: "raskas oikea nuoli"] # 0x2799 (en: 'heavy rightwards arrow', google translation) - - "➚": [T: "raskas yläoikea nuoli"] # 0x279a (en: 'heavy north east arrow', google translation) - - "➛": [T: "laatimispiste oikealle nuoli"] # 0x279b (en: 'drafting point rightwards arrow', google translation) - - "➜": [T: "raskas pyöristetty oikea nuoli"] # 0x279c (en: 'heavy round-tipped rightwards arrow', google translation) - - "➝": [T: "kolmionpäinen oikea nuoli"] # 0x279d (en: 'triangle-headed rightwards arrow', google translation) - - "➞": [T: "raskas kolmiopäinen oikea nuoli"] # 0x279e (en: 'heavy triangle-headed rightwards arrow', google translation) - - "➟": [T: "kolmiopäinen oikea nuoli katkoviivalla"] # 0x279f (en: 'dashed triangle-headed rightwards arrow', google translation) - - "➠": [T: "raskas kolmiopäinen oikea nuoli katkoviivalla"] # 0x27a0 (en: 'heavy dashed triangle-headed rightwards arrow', google translation) - - "➡": [T: "oikealle osoittava musta nuoli"] # 0x27a1 (en: 'black rightwards arrow', google translation) - - "➢": [T: "yläpuolelta valkea oikealle osoittava nuolenpää"] # 0x27a2 (en: 'three d top lighted rightwards arrow', google translation) - - "➣": [T: "alapuolelta valkea oikealle osoittava nuolenpää"] # 0x27a3 (en: 'three d bottom lighted rightwards arrow', google translation) - - "➤": [T: "musta oikea nuolenpää"] # 0x27a4 (en: 'black rightwards arrowhead', google translation) - - "➥": [T: "raskas musta kaareva alas ja oikealle osoittava nuoli"] # 0x27a5 (en: 'heavy black curved downwards and rightwards arrow', google translation) - - "➦": [T: "raskas musta kaareva ylös ja oikealle osoittava nuoli"] # 0x27a6 (en: 'heavy black curved upwards and rightwards arrow', google translation) - - "➧": [T: "raskas musta lyhyt oikea nuoli"] # 0x27a7 (en: 'squat black rightwards arrow', google translation) - - "➨": [T: "raskas terävä musta oikea nuoli"] # 0x27a8 (en: 'heavy concave-pointed black rightwards arrow', google translation) - - "➩": [T: "oikea oikealle varjostettu valkoinen nuoli"] # 0x27a9 (en: 'right-shaded white rightwards arrow', google translation) - - "➪": [T: "oikea vasemmalle varjostettu valkoinen nuoli"] # 0x27aa (en: 'left-shaded white rightwards arrow', google translation) - - "➫": [T: "taaksepäin kallistettu varjostettu valkoinen oikealle osoittava nuoli"] # 0x27ab (en: 'back-tilted shadowed white rightwards arrow', google translation) - - "➬": [T: "eteenpäin kallistettu varjostettu valkoinen oikealle osoittava nuoli"] # 0x27ac (en: 'front-tilted shadowed white rightwards arrow', google translation) - - "➭": [T: "raskas oikea alhaalta varjostettu valkoinen nuoli"] # 0x27ad (en: 'heavy lower right-shadowed white rightwards arrow', google translation) - - "➮": [T: "raskas oikea ylhäältä varjostettu valkoinen nuoli"] # 0x27ae (en: 'heavy upper right-shadowed white rightwards arrow', google translation) - - "➯": [T: "raskas oikea alhaalta varjostettu valkoinen nuoli lovella"] # 0x27af (en: 'notched lower right-shadowed white rightwards arrow', google translation) - - "➱": [T: "raskas oikea ylhäältä varjostettu valkoinen nuoli lovella"] # 0x27b1 (en: 'notched upper right-shadowed white rightwards arrow', google translation) - - "➲": [T: "ympyröity raskas oikea valkoinen nuoli"] # 0x27b2 (en: 'circled heavy white rightwards arrow', google translation) - - "➳": [T: "oikea nuoli valkoisilla höyhenillä"] # 0x27b3 (en: 'white-feathered rightwards arrow', google translation) - - "➴": [T: "alaoikea nuoli mustilla höyhenillä"] # 0x27b4 (en: 'black-feathered south east arrow', google translation) - - "➵": [T: "oikea nuoli mustilla höyhenillä"] # 0x27b5 (en: 'black-feathered rightwards arrow', google translation) - - "➶": [T: "yläoikea nuoli mustilla höyhenillä"] # 0x27b6 (en: 'black-feathered north east arrow', google translation) - - "➷": [T: "raskas alaoikea nuoli mustilla höyhenillä"] # 0x27b7 (en: 'heavy black-feathered south east arrow', google translation) - - "➸": [T: "raskas oikea nuoli mustilla höyhenillä"] # 0x27b8 (en: 'heavy black-feathered rightwards arrow', google translation) - - "➹": [T: "raskas yläoikea nuoli mustilla höyhenillä"] # 0x27b9 (en: 'heavy black-feathered north east arrow', google translation) - - "➺": [T: "oikea nuoli kyynelpiikillä"] # 0x27ba (en: 'teradrop-barbed rightwards arrow', google translation) - - "➻": [T: "raskas nuoli kyynelpiikillä"] # 0x27bb (en: 'heavy teardrop-shanked rightwards arrow', google translation) - - "➼": [T: "oikea nuoli kiilalla"] # 0x27bc (en: 'wedge-tailed rightwards arrow', google translation) - - "➽": [T: "raskas oikea nuoli kiilalla"] # 0x27bd (en: 'heavy wedge-tailed rightwards arrow', google translation) - - "➾": [T: "oikea ääriviivanuoli"] # 0x27be (en: 'open-outlined rightwards arrow', google translation) - - "⟀": [T: "kolmiulotteinen kulma"] # 0x27c0 (en: 'three dimensional angle') - - "⟁": [T: "kaksi valkoista kolmiota sisäkkäin"] # 0x27c1 (en: 'white triangle containing small white triangle', google: 'valkoinen kolmio, joka sisältää pientä valkoista kolmiota') - - "⟂": # 0x27c2 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "kohtisuora" # (en: 'perpendicular to', google: 'kohtisuorassa') - - "⟃": # 0x27c3 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "avoin osajoukko" # (en: 'an open subset of') - - "⟄": # 0x27c4 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "avoin yläjoukko" # (en: 'an open superset of', google: 'avoin superset') - - "⟅": [T: "vasen s-muotoinen laukkuerottaja"] # 0x27c5 (google: 'vasen s-muotoinen laukku') - - "⟆": [T: "oikea s-muotoinen laukkuerottaja"] # 0x27c6 (google: 'oikea s-muotoinen laukku') - - "⟇": [T: "tai pisteellä"] # 0x27c7 (en: 'or with dot inside', google: 'tai pisteellä sisällä') - - "⟈": [T: "kenoviiva osajoukko"] # 0x27c8 (en: 'reverse solidus preceding subset', google: 'käänteinen solidus edeltävä alajoukko') - - "⟉": [T: "ylijoukko vinoviiva"] # 0x27c9 (en: 'superset preceding solidus', google: 'superset edeltävä solidus') - - "⟊": [T: "pystyviiva vaakasuoralla poikkiviivalla"] # 0x27ca (en: 'vertical bar with horizontal stroke', google: 'pystysuora palkki vaakasuuntaisella iskulla') - - "⟋": [T: "matemaattinen nouseva diagonaali"] # 0x27cb (en: 'mathematical rising diagonal', google translation) - - "⟌": [T: "jakokulma"] # 0x27cc (en: 'long division', google: 'jakolaskutoimitus') - - "⟍": [T: "matemaattinen laskeva diagonaali"] # 0x27cd (en: 'mathematical falling diagonal', google translation) - - "⟎": [T: "looginen ja neliössä"] # 0x27ce (en: 'squared logical and', google translation) - - "⟏": [T: "looginen tai neliössä"] # 0x27cf (en: 'squared logical or', google translation) - - "⟐": [T: "valkoinen timantti keskitetyllä pisteellä"] # 0x27d0 (en: 'white diamond with centered dot', google translation) - - "⟑": [T: "ja pisteellä"] # 0x27d1 (en: 'and with dot', google: 'ja pisteellä') - - "⟒": [T: "ylös aukeava kuuluu joukkoon"] # 0x27d2 (en: 'element of opening upwards', google: 'elementti avaamisesta ylöspäin') - - "⟓": [T: "oikea alakulma pisteellä"] # 0x27d3 (en: 'lower right corner with dot', google: 'oikea alakulma pisteellä') - - "⟔": [T: "vasen alakulma pisteellä"] # 0x27d4 (en: 'upper left corner with dot', google: 'vasen yläkulma pisteellä') - - "⟕": [T: "vasen ulkoinen liitos"] # 0x27d5 (google: 'vasen ulkoinen liittyminen') - - "⟖": [T: "oikea ulkoinen liitos"] # 0x27d6 (google: 'oikea ulkoinen liittyminen') - - "⟗": [T: "täysi ulkoinen liitos"] # 0x27d7 (google: 'täysi ulkoinen liittyminen') - - "⟘": [T: "suuri nupi ylöspäin"] # 0x27d8 (google: 'suuri ylöspäin') - - "⟙": [T: "suuri nupi alaspäin"] # 0x27d9 (google: 'suuri alaspäin') - - "⟚": [T: "tuplaportti vasemmalle ja oikealle"] # 0x27da (google: 'vasen ja oikea kaksoiskivi') - - "⟛": [T: "vasen ja oikea nupi"] # 0x27db (google: 'vasen ja oikea tarttuva') - - "⟜": [T: "vasen monikuvaus"] # 0x27dc (google: 'vasen multimep') # FI: meaning unclear - - "⟝": [T: "pitkä oikea nupi"] # 0x27dd (google: 'pitkä oikea tarttuva') - - "⟞": [T: "pitkä vasen nupi"] # 0x27de (google: 'pitkä vasen tarttuva') - - "⟟": [T: "nupi ylös ympyrällä"] # 0x27df (en: 'up tack with circle above', google: 'yllä oleva ympyrä') - - "⟠": [T: "vinoneliö vaakaviivalla"] # 0x27e0 (google: 'lozenge jaettuna vaakasuunnassa') - - "⟡": [T: "valkoinen terävä timantti"] # 0x27e1 (google: 'valkoinen koverapuolinen timantti') - - "⟢": [T: "valkoinen terävä timantti vasemmanpuoleisella nupilla"] # 0x27e2 (en: 'white concave sided diamond with leftwards tick', google: 'valkoinen koverapuolinen timantti vasemmalla rastilla') - - "⟣": [T: "valkoinen terävä timantti oikeanpuoleisella nupilla"] # 0x27e3 (en: 'white concave sided diamond with rightwards tick', google: 'valkoinen koverapuolinen timantti oikealla puolella') - - "⟤": [T: "valkoinen neliö vasemmanpuoleisella nupilla"] # 0x27e4 (en: 'white square with leftwards tick', google: 'valkoinen neliö vasemmalla rastilla') - - "⟥": [T: "valkoinen neliö oikeanpuoleisella nupilla"] # 0x27e5 (en: 'white square with rightwards tick', google: 'valkoinen neliö oikealla puolella') - - "⟦": [T: "valkoinen vasen hakasulku"] # 0x27e6 (en: 'left white square bracket', google: 'vasen valkoinen neliömäki') - - "⟧": [T: "valkoinen oikea hakasulku"] # 0x27e7 (en: 'right white square bracket', google: 'oikea valkoinen neliömäki') - - "⟨": [T: "vasen kulmasulku"] # 0x27e8 (en: 'left angle bracket', google: 'vasemman kulman kiinnike') - - "⟩": [T: "oikea kulmasulku"] # 0x27e9 (en: 'right angle bracket', google: 'suoren kulman kiinnike') - - "⟪": [T: "vasen kaksoiskulmasulku"] # 0x27ea (en: 'left double angle bracket', google: 'vasen kaksoiskulma kiinnike') - - "⟫": [T: "oikea kaksoiskulmasulku"] # 0x27eb (en: 'right double angle bracket', google: 'oikea kaksoiskulma kiinnike') - - "⟬": [T: "vasen valkoinen kilpikonnankuorisulku"] # 0x27ec (google: 'vasen valkoinen kilpikonnakuoren kiinnike') - - "⟭": [T: "oikea valkoinen kilpikonnankuorisulku"] # 0x27ed (google: 'oikea valkoinen kilpikonnakuoren kiinnike') - - "⟮": [T: "vasen litistetty sulku"] # 0x27ee (google: 'vasen litistetty sulkuteesi') - - "⟯": [T: "oikea litistetty sulku"] # 0x27ef (google: 'oikea litistetty sulkuteesi') - - "⟰": [T: "nelinkertainen nuoli ylös"] # 0x27f0 (en: 'upwards quadruple arrow', google translation) - - "⟱": [T: "nelinkertainen nuoli alas"] # 0x27f1 (en: 'downwards quadruple arrow', google translation) - - "⟲": [T: "avoin ympyränuoli vastapäivään"] # 0x27f2 (en: 'anticlockwise gapped circle arrow', google translation) - - "⟳": [T: "avoin ympyränuoli myötäpäivään"] # 0x27f3 (en: 'clockwise gapped circle arrow', google translation) - - "⟴": [T: "oikea nuoli ympyröidyllä plus-merkillä"] # 0x27f4 (en: 'right arrow with circled plus', google translation) - - "⟵": [T: "pitkä nuoli vasemmalle"] # 0x27f5 (en: 'long leftwards arrow', google: 'pitkä vasen nuoli') - - "⟶": [T: "pitkä nuoli oikealle"] # 0x27f6 (en: 'long rightwards arrow', google: 'pitkä oikea nuoli') - - "⟷": [T: "pitkä nuoli vasemmalle ja oikealle"] # 0x27f7 (en: 'long left right arrow', google: 'pitkä vasen oikea nuoli') - - "⟸": [T: "pitkä kaksoisnuoli vasemmalle"] # 0x27f8 (en: 'long leftwards double arrow', google: 'pitkä vasen kaksinkertainen nuoli') - - "⟹": [T: "pitkä kaksoisnuoli oikealle"] # 0x27f9 (en: 'long rightwards double arrow', google: 'pitkä oikea kaksinkertainen nuoli') - - "⟺": [T: "pitkä kaksoisnuoli vasemmalle ja oikealle"] # 0x27fa (en: 'long left right double arrow', google: 'pitkä vasen oikea kaksinkertainen nuoli') - - "⟻": [T: "pitkä vasen nuoli pystyviivasta"] # 0x27fb (en: 'long leftwards arrow from bar', google translation) - - "⟼": [T: "pitkä oikea nuoli pystyviivasta"] # 0x27fc (en: 'long rightwards arrow from bar', google: 'pitkä oikea nuoli baarista') - - "⟽": [T: "pitkä vasen kaksinkertainen nuoli pystyviivasta"] # 0x27fd (en: 'long leftwards double arrow from bar', google translation) - - "⟾": [T: "pitkä oikea kaksinkertainen nuoli pystyviivasta"] # 0x27fe (en: 'long rightwards double arrow from bar', google translation) - - "⟿": [T: "pitkä kiemuranuoli oikealle"] # 0x27ff (en: 'long rightwards squiggle arrow', google: 'pitkä oikeassa nuoli') - - "⤀": [T: "oikea kaksipäinen nuoli pystysuoralla viivalla"] # 0x2900 (en: 'rightwards two headed arrow with vertical stroke', google translation) - - "⤁": [T: "oikea kaksipäinen nuoli kaksinkertaisella pystysuoralla viivalla"] # 0x2901 (en: 'rightwards two headed arrow with double vertical stroke', google translation) - - "⤂": [T: "vasen kaksinkertainen nuoli pystysuoralla viivalla"] # 0x2902 (en: 'leftwards double arrow with vertical stroke', google translation) - - "⤃": [T: "oikea kaksinkertainen nuoli pystysuoralla viivalla"] # 0x2903 (en: 'rightwards double arrow with vertical stroke', google translation) - - "⤄": [T: "vasemmalle ja oikealle osoittava kaksinkertainen nuoli pystysuoralla viivalla"] # 0x2904 (en: 'left right double arrow with vertical stroke', google translation) - - "⤅": [T: "oikea kaksipäinen nuoli pystyviivasta"] # 0x2905 (google: 'oikealle kaksi päätä nuoli baarista') - - "⤆": [T: "vasen kaksinkertainen nuoli pystyviivasta"] # 0x2906 (en: 'leftwards double arrow from bar', google translation) - - "⤇": [T: "oikea kaksinkertainen nuoli pystyviivasta"] # 0x2907 (en: 'rightwards double arrow from bar', google translation) - - "⤈": [T: "alaspäin osoittava nuoli vaakaviivalla"] # 0x2908 (en: 'downwards arrow with horizontal stroke', google translation) - - "⤉": [T: "ylöspäin osoittava nuoli vaakaviivalla"] # 0x2909 (en: 'upwards arrow with horizontal stroke', google translation) - - "⤊": [T: "ylöspäin osoittava kolminkertainen nuoli"] # 0x290a (en: 'upwards triple arrow', google translation) - - "⤋": [T: "alaspäin osoittava kolminkertainen nuoli"] # 0x290b (en: 'downwards triple arrow', google translation) - - "⤌": [T: "vasen kaksoiskatkoviivannuoli"] # 0x290c (google: 'vasen kaksinkertainen viiva nuoli') - - "⤍": [T: "oikea kaksoiskatkoviivanuoli"] # 0x290d (google: 'oikealla puolella kaksoisnauhaa') - - "⤎": [T: "vasen kolmoiskatkoviivanuoli"] # 0x290e (google: 'vasen kolminkertainen viiva nuoli') - - "⤏": [T: "oikea kolmoiskatkoviivanuoli"] # 0x290f (google: 'oikealle kolminkertainen dash -nuoli') - - "⤐": [T: "oikea kaksipäinen katkoviivanuoli pyrstöllä"] # 0x2910 (google: 'oikealle kaksi päätä kolminkertainen viiva nuoli') - - "⤑": [T: "oikea pisteviivanuoli"] # 0x2911 (en: 'rightwards arrow with dotted stem', google: 'oikealla nuolella katkoviivalla') - - "⤒": [T: "nuoli ylös vaakaviivaan"] # 0x2912 (google: 'nuoli ylöspäin baariin') - - "⤓": [T: "nuoli alas vaakaviivaan"] # 0x2913 (google: 'alaspäin nuoli baariin') - - "⤔": [T: "oikea nuoli pystyviivalla ja pyrstöllä"] # 0x2914 (en: 'rightwards arrow with tail and vertical stroke', google translation) - - "⤕": [T: "oikea nuoli kaksoispystyviivalla ja pyrstöllä"] # 0x2915 (en: 'rightwards arrow with tail and double vertical stroke', google translation) - - "⤖": [T: "oikea kaksipäinen nuoli pyrstöllä"] # 0x2916 (en: 'rightwards two headed arrow with tail', google: 'oikealle kaksi päätä nuoli hännän kanssa') - - "⤗": [T: "oikea kaksipäinen nuoli pystyviivalla ja pyrstöllä"] # 0x2917 (en: 'rightwards two headed arrow with tail with vertical stroke', google translation) - - "⤘": [T: "oikea kaksipäinen nuoli kaksoispystyviivalla ja pyrstöllä"] # 0x2918 (en: 'rightwards two headed arrow with tail with double vertical stroke', google translation) - - "⤙": [T: "vasemmanpuoleisen nuolen häntä"] # 0x2919 (google: 'vasen nuoli häntä') - - "⤚": [T: "oikeanpuoleisen nuolen häntä"] # 0x291a (en: 'rightwards arrow tail', google translation) - - "⤛": [T: "vasemmanpuoleisen nuolen tuplahäntä"] # 0x291b (google: 'vasen kaksinkertainen nuoli häntä') - - "⤜": [T: "oikeanpuoleisen nuolen tuplahäntä"] # 0x291c (google: 'oikealla kaksoisnuoli') - - "⤝": [T: "vasen nuoli väritettyyn timanttiin"] # 0x291d (google: 'vasen nuoli täytetylle timantille') - - "⤞": [T: "oikea nuoli väritettyyn timanttiin"] # 0x291e (google: 'oikealla nuolella täytetylle timantille') - - "⤟": [T: "vasen nuoli pystyviivasta väritettyyn timanttiin"] # 0x291f (google: 'vasen nuoli baarista täytetylle timantille') - - "⤠": [T: "oikea nuoli pystyviivasta väritettyyn timanttiin"] # 0x2920 (google: 'suoraan nuoli baarista täytetylle timantille') - - "⤡": [T: "ylävasemmalle ja alaoikealle osoittava nuoli"] # 0x2921 (en: 'north west and south east arrow', google translation) - - "⤢": [T: "yläoikealle ja alavasemmalle osoittava nuoli"] # 0x2922 (en: 'north east and south west arrow', google translation) - - "⤣": [T: "ylävasen nuoli koukulla"] # 0x2923 (en: 'north west arrow with hook', google: 'luoteis -nuoli koukulla') - - "⤤": [T: "yläoikea nuoli koukulla"] # 0x2924 (en: 'north east arrow with hook', google: 'koillis -nuoli koukulla') - - "⤥": [T: "alaoikea nuoli koukulla"] # 0x2925 (en: 'south east arrow with hook', google: 'kaakkois -nuoli koukulla') - - "⤦": [T: "alavasen nuoli koukulla"] # 0x2926 (en: 'south west arrow with hook', google: 'lounais -nuoli koukulla') - - "⤧": [T: "nuoli yläoikealle ja nuoli ylävasemmalle"] # 0x2927 (google: 'luoteis arrow ja koillis -nuoli') - - "⤨": [T: "nuoli yläoikealle ja nuoli alaoikealle"] # 0x2928 (google: 'koillis -nuoli ja kaakkois -nuoli') - - "⤩": [T: "nuoli alaoikealle ja nuoli alavasemmalle"] # 0x2929 (google: 'kaakkois arrow ja south west arrow') - - "⤪": [T: "nuoli alavasemmalle ja nuoli ylävasemmalle"] # 0x292a (google: 'south west arrow ja north west arrow') - - "⤫": [T: "nouseva diagonaali laskevan diagonaalin päällä"] # 0x292b (en: 'rising diagonal crossing falling diagonal', google translation) - - "⤬": [T: "laskeva diagonaali nousevan diagonaalin päällä"] # 0x292c (en: 'falling diagonal crossing rising diagonal', google translation) - - "⤭": [T: "alaoikealle osoittava nuoli yläoikealle osoittavan nuolen päällä"] # 0x292d (en: 'south east arrow crossing north east arrow', google translation) - - "⤮": [T: "yläoikealle osoittava nuoli alaoikealle osoittavan nuolen päällä"] # 0x292e (en: 'north east arrow crossing south east arrow', google translation) - - "⤯": [T: "laskeva diagonaali yläoikealle osoittavan nuolen päällä"] # 0x292f (en: 'falling diagonal crossing north east arrow', google translation) - - "⤰": [T: "nouseva diagonaali alaoikealle osoittavan nuolen päällä"] # 0x2930 (en: 'rising diagonal crossing south east arrow', google translation) - - "⤱": [T: "yläoikealle osoittava nuoli ylävasemmalle osoittavan nuolen päällä"] # 0x2931 (en: 'north east arrow crossing north west arrow', google translation) - - "⤲": [T: "ylävasemmalle osoittava nuoli yläoikealle osoittavan nuolen päällä"] # 0x2932 (en: 'north west arrow crossing north east arrow', google translation) - - "⤳": [T: "aaltonuoli oikealle"] # 0x2933 (en: 'wave arrow pointing directly right', google: 'aalto nuoli osoittaa suoraan oikealle') - - "⤴": [T: "ylöspäin kaartuva oikea nuoli"] # 0x2934 (en: 'arrow pointing rightwards then curving upwards', google translation) - - "⤵": [T: "alaspäin kaartuva oikea nuoli"] # 0x2935 (google: 'nuoli osoittaa oikealle ja kaareutuu alaspäin') - - "⤶": [T: "vasemmalle kaartuva alavasemmalle osoittava nuoli"] # 0x2936 (google: 'nuoli osoittaa alaspäin ja kaareutuu vasemmalle') - - "⤷": [T: "oikealle kaartuva alaoikealle osoittava nuoli"] # 0x2937 (google: 'nuoli osoittaa alaspäin ja kaareutuu oikealle') - - "⤸": [T: "oikeanpuoleinen kaarinuoli myötäpäivään"] # 0x2938 (en: 'right side arc clockwise arrow', google: 'oikea sivukaari myötäpäivään nuoli') - - "⤹": [T: "vasemmanpuoleinen kaarinuoli vastapäivään"] # 0x2939 (en: 'left side arc anticlockwise arrow', google: 'vasen sivukaari vastapäivään') - - "⤺": [T: "yläkaarinuoli vastapäivään"] # 0x293a (en: 'top arc anticlockwise arrow', google translation) - - "⤻": [T: "alakaarinuoli vastapäivään"] # 0x293b (en: 'bottom arc anticlockwise arrow', google translation) - - "⤼": [T: "yläkaarinuoli myötäpäivään miinus-merkillä"] # 0x293c (en: 'top arc clockwise arrow with minus', google: 'yläkaari myötäpäivään nuoli miinus') - - "⤽": [T: "yläkaarinuoli vastapäivään plus-merkillä"] # 0x293d (en: 'top arc anticlockwise arrow with plus', google: 'yläkaari vastapäivään nuoli plus') - - "⤾": [T: "alaoikea kaarinuoli myötäpäivään"] # 0x293e (en: 'lower right semicircular clockwise arrow', google translation) - - "⤿": [T: "alavasen kaarinuoli vastapäivään"] # 0x293f (en: 'lower left semicircular anticlockwise arrow', google translation) - - "⥀": [T: "suljettu ympyränuoli vastapäivään"] # 0x2940 (en: 'anticlockwise closed circle arrow', google translation) - - "⥁": [T: "suljettu ympyränuoli myötäpäivään"] # 0x2941 (en: 'clockwise closed circle arrow', google translation) - - "⥂": [T: "oikea nuoli lyhyen vasemman nuolen yläpuolella"] # 0x2942 (en: 'rightwards arrow above short leftwards arrow', google translation) - - "⥃": [T: "vasen nuoli lyhyen oikean nuolen yläpuolella"] # 0x2943 (en: 'leftwards arrow above short rightwards arrow', google translation) - - "⥄": [T: "lyhyt oikea nuoli vasemman nuolen yläpuolella"] # 0x2944 (en: 'short rightwards arrow above leftwards arrow', google translation) - - "⥅": [T: "oikea nuoli ja plus-merkki alapuolella"] # 0x2945 (en: 'rightwards arrow with plus below', google: 'oikealla nuolella, jonka alla on plus') - - "⥆": [T: "vasen nuoli ja plus-merkki alanpuolella"] # 0x2946 (en: 'leftwards arrow with plus below', google translation) - - "⥇": [T: "oikea nuoli x:n läpi"] # 0x2947 (en: 'rightwards arrow through x', google translation) - - "⥈": [T: "oikealle ja vasemmalle osoittava nuoli ympyrän läpi"] # 0x2948 (google: 'vasen oikea nuoli ympyrän läpi') - - "⥉": [T: "ylöspäin osoittava kaksipäinen nuoli ympyrästä"] # 0x2949 (google: 'ylöspäin kaksi pääistä nuolta ympyrästä') - - "⥊": [T: "oikealle ja vasemmalle osoittava puolinuoli oikealla yläpiikillä ja vasemmalla alapiikillä"] # 0x294a (google: 'vasen barb ylös oikealle barb down harpoon') - - "⥋": [T: "oikealle ja vasemmalle osoittava puolinuoli oikealla alapiikillä ja vasemmalle yläpiikillä"] # 0x294b (google: 'vasen barb alas oikealla barb up harpoon') - - "⥌": [T: "ylös ja alas osoittava puolinuoli oikealla yläpiikillä ja vasemmalla alapiikillä"] # 0x294c (en: 'up barb right down barb left harpoon', google translation) - - "⥍": [T: "ylös ja alas osoittava puolinuoli vasemmalla yläpiikillä ja oikealla alapiikillä"] # 0x294d (en: 'up barb left down barb right harpoon', google translation) - - "⥎": [T: "oikealle ja vasemmalle osoittava puolinuoli, piikit yläpuolella"] # 0x294e (en: 'left barb up right barb up harpoon', google: 'vasen barb ylös oikealle barb up harpoon') - - "⥏": [T: "ylös ja alas osoittava puolinuoli, piikit oikealla"] # 0x294f (en: 'up barb right down barb right harpoon', google: 'ylös barb oikealla barbilla oikealla harpoonilla') - - "⥐": [T: "oikealle ja vasemmalle osoittava puolinuoli, piikit alapuolella"] # 0x2950 (en: 'left barb down right barb down harpoon', google: 'vasen barb alas oikealla barb down harpoon') - - "⥑": [T: "ylös ja alas osoittava puolinuoli, piikit vasemmalla"] # 0x2951 (en: 'up barb left down barb left harpoon', google: 'ylös barb vasemmalle barb vasen harpooni') - - "⥒": [T: "vasemmalle osoittava puolinuoli pystyviivaan, piikki yläpuolella"] # 0x2952 (en: 'leftwards harpoon with barb up to bar', google: 'vasen harppuuna barbin kanssa baariin') - - "⥓": [T: "oikealle osoittava puolinuoli pystyviivaan, piikki yläpuolella"] # 0x2953 (en: 'rightwards harpoon with barb up to bar', google: 'oikea harpoon barbin kanssa baariin') - - "⥔": [T: "ylös osoittava puolinuoli vaakaviivaan, piikki oikealla"] # 0x2954 (en: 'upwards harpoon with barb right to bar', google: 'ylöspäin harppuun barbin oikealla baarilla') - - "⥕": [T: "alas osoittava puolinuoli vaakaviivaan, piikki oikealla"] # 0x2955 (en: 'downwards harpoon with barb right to bar', google: 'downward harpoon barbin oikealla baarilla') - - "⥖": [T: "vasemmalle osoittava puolinuoli pystyviivaan, piikki alapuolella"] # 0x2956 (en: 'leftwards harpoon with barb down to bar', google: 'vasen harppuuna barbin kanssa baariin') - - "⥗": [T: "oikealle osoittava puolinuoli pystyviivaan, piikki alapuolella"] # 0x2957 (en: 'rightwards harpoon with barb down to bar', google: 'oikea harpoon barbin kanssa baariin') - - "⥘": [T: "ylös osoittava puolinuoli vaakaviivaan, piikki vasemmalla"] # 0x2958 (en: 'upwards harpoon with barb left to bar', google: 'ylös harppuon barbin kanssa vasemmalle baariin') - - "⥙": [T: "alas osoittava puolinuoli vaakaviivaan, piikki vasemmalla"] # 0x2959 (en: 'downwards harpoon with barb left to bar', google: 'downward harpoon barbin kanssa vasemmalle baariin') - - "⥚": [T: "vasemmalle osoittava puolinuoli vaakaviivasta, piikki yläpuolella"] # 0x295a (en: 'leftwards harpoon with barb up from bar', google: 'vasen harppuuna barb ylös baarista') - - "⥛": [T: "oikealle osoittava puolinuoli vaakaviivasta, piikki yläpuolella"] # 0x295b (en: 'rightwards harpoon with barb up from bar', google: 'oikealla harppuuna barbin kanssa baarista') - - "⥜": [T: "ylöspäin osoittava puolinuoli vaakaviivasta, piikki oikealla"] # 0x295c (en: 'upwards harpoon with barb right from bar', google: 'ylöspäin harppuun barbin kanssa heti baarista') - - "⥝": [T: "alaspäin osoittava puolinuoli vaakaviivasta, piikki oikealla"] # 0x295d (en: 'downwards harpoon with barb right from bar', google: 'downward harpoon barbin kanssa heti baarista') - - "⥞": [T: "vasemmalle osoittava puolinuoli vaakaviivasta, piikki alapuolella"] # 0x295e (en: 'leftwards harpoon with barb down from bar', google: 'vasen harppuuna barbin kanssa baarista') - - "⥟": [T: "oikealle osoittava puolinuoli vaakaviivasta, piikki alapuolella"] # 0x295f (en: 'rightwards harpoon with barb down from bar', google: 'oikea harpoon barbin kanssa baarista') - - "⥠": [T: "ylöspäin osoittava puolinuoli vaakaviivasta, piikki vasemmalla"] # 0x2960 (en: 'upwards harpoon with barb left from bar', google: 'ylös harppuun barbin vasemmalla baarista') - - "⥡": [T: "alaspäin osoittava puolinuoli vaakaviivasta, piikki vasemmalla"] # 0x2961 (en: 'downwards harpoon with barb left from bar', google: 'downward harpoon barbin vasemmalla baarista') - - "⥢": [T: "vasemmalle osoittava puolinuolipari"] # 0x2962 (en: 'leftwards harpoon with barb up above leftwards harpoon with barb down', google: 'vasen harppuuna barb ylös vasemmanpuoleisen harpoonin yläpuolella barb down') - - "⥣": [T: "ylöspäin osoittava puolinuolipari"] # 0x2963 (en: 'upwards harpoon with barb left beside upwards harpoon with barb right', google: 'yläpuolella harppuunia vasemmalla vasemmalla harpoon vieressä barbilla oikealla') - - "⥤": [T: "oikealle osoittava puolinuolipari"] # 0x2964 (en: 'rightwards harpoon with barb up above rightwards harpoon with barb down', google: 'oikealla harpoonilla barb ylös oikeanpuoleisen harpoonin yläpuolella barb down') - - "⥥": [T: "alaspäin osoittava puolinuolipari"] # 0x2965 (en: 'downwards harpoon with barb left beside downwards harpoon with barb right', google: 'downwards harpoon vasemmalla vasemmalla harppuunan vieressä barbilla oikealla') - - "⥦": [T: "vasen puolinuoli piikki ylös ja alapuolella oikea puolinuoli piikki ylös"] # 0x2966 (en: 'leftwards harpoon with barb up above rightwards harpoon with barb up', google: 'vasen harppuuna barb ylös oikeanpuoleisen harpoonin yläpuolella barb up') - - "⥧": [T: "vasen puolinuoli piikki alas ja alapuolella oikea puolinuoli piikki ylös"] # 0x2967 (en: 'leftwards harpoon with barb down above rightwards harpoon with barb down', google: 'vasen harppuuna barb alas oikeanpuoleisen harpoonin yläpuolella barb down') - - "⥨": [T: "oikea puolinuoli piikki ylös ja alapuolella vasen puolinuoli piikki ylös"] # 0x2968 (en: 'rightwards harpoon with barb up above leftwards harpoon with barb up', google: 'oikealla harpounalla barb ylös vasemmanpuoleisen harpoonin yläpuolella barb up') - - "⥩": [T: "oikea puolinuoli piikki alas ja alapuolella vasen puolinuoli piikki alas"] # 0x2969 (en: 'rightwards harpoon with barb down above leftwards harpoon with barb down', google: 'oikealla harpounalla barbin kanssa vasemmanpuoleisen harpoonin yläpuolella barb down') - - "⥪": [T: "vasen puolinuoli piikki ylös vaakaviivan yläpuolella"] # 0x296a (en: 'leftwards harpoon with barb up above long dash', google: 'vasen harppuuna barb ylös pitkän viivan yläpuolella') - - "⥫": [T: "vasen puolinuoli piikki alas vaakaviivan alapuolella"] # 0x296b (en: 'leftwards harpoon with barb down below long dash', google: 'vasen harppuuna barbin alapuolella pitkän viivan alapuolella') - - "⥬": [T: "oikea puolinuoli piikki ylös vaakaviivan yläpuolella"] # 0x296c (en: 'rightwards harpoon with barb up above long dash', google: 'oikealla harppuunilla barb up long dashin yläpuolella') - - "⥭": [T: "oikea puolinuoli piikki alas vaakaviivan alapuolella"] # 0x296d (en: 'rightwards harpoon with barb down below long dash', google: 'oikealla harppuuna barbin alapuolella pitkän viivan alapuolella') - - "⥮": [T: "ylös ja alas osoittava puolinuolipari"] # 0x296e (en: 'upwards harpoon with barb left beside downwards harpoon with barb right', google: 'ylös harppuunaa vasemmalla vasemmalla harpoonin vieressä barbilla oikealla') - - "⥯": [T: "alas ja ylös osoittava puolinuolipari"] # 0x296f (en: 'downwards harpoon with barb left beside upwards harpoon with barb right', google: 'downwards harpoon vasemmalla vasemmalla harppuunin vieressä barbilla oikealla') - - "⥰": [T: "oikea tuplanuoli pyöristetyllä yläpuolella"] # 0x2970 (en: 'right double arrow with rounded head', google: 'oikea kaksinkertainen nuoli pyöristetyllä pään kanssa') - - "⥱": [T: "yhtä suuri kuin oikean nuolen yläpuolella"] # 0x2971 (google: 'vastaa oikeanpuoleista nuolta') - - "⥲": [T: "tilde oikean nuolen yläpuolella"] # 0x2972 (google: 'tilde -operaattori oikeanpuoleisen nuolen yläpuolella') - - "⥳": [T: "vasen nuoli tilden yläpuolella"] # 0x2973 (en: 'leftwards arrow above tilde operator', google: 'vasen nuoli tilde -operaattorin yläpuolella') - - "⥴": [T: "oikea nuoli tilden yläpuolella"] # 0x2974 (en: 'rightwards arrow above tilde operator', google: 'oikealla nuolella tilde -operaattorin yläpuolella') - - "⥵": [T: "oikea nuoli melkein yhtä suuri kuin yläpuolella"] # 0x2975 (google: 'oikea nuoli yläpuolelle melkein yhtä suuri kuin') - - "⥶": [T: "pienempi kuin vasemman nuolen yläpuolella"] # 0x2976 (google: 'alle kuin vasemmanpuoleinen nuoli') - - "⥷": [T: "vasen nuoli pienempi kuin päällä"] # 0x2977 (en: 'leftwards arrow through less than', google translation) - - "⥸": [T: "suurempi kuin oikean nuolen yläpuolella"] # 0x2978 (google: 'suurempi kuin oikeanpuoleinen nuoli') - - "⥹": [T: "osajoukko oikean nuolen yläpuolella"] # 0x2979 (google: 'oikeanpuoleinen nuolen yläpuolella') - - "⥺": [T: "vasen nuoli osajoukon päällä"] # 0x297a (en: 'leftwards arrow through subset', google translation) - - "⥻": [T: "ylijoukko vasemman nuolen yläpuolella"] # 0x297b (google: 'superset vasemmanpuoleisen nuolen yläpuolella') - - "⥼": [T: "vasen kalanpyrstö"] # 0x297c (google: 'vasen kala häntä') - - "⥽": [T: "oikea kalanpyrstö"] # 0x297d (google: 'oikea kala häntä') - - "⥾": [T: "ylöspäin osoittava kalanpyrstö"] # 0x297e (en: 'up fish tail', google: 'ylös kalanhäntä') - - "⥿": [T: "alaspäin osoittava kalanpyrstö"] # 0x297f (google: 'alas kalan hännä') - - "⦀": [T: "kolminkertainen pystysuora palkki"] # 0x2980 (en: 'triple vertical bar delimiter', google translation) - - "⦁": [T: "Z-notaatio piste"] # 0x2981 (en: 'z notation spot', google translation) - - "⦂": [T: "Z-notaatio kaksoispiste"] # 0x2982 (en: 'z notation type colon', google translation) - - "⦃": [T: "vasen valkoinen aaltosulku"] # 0x2983 (en: 'left white brace', google translation) - - "⦄": [T: "oikea valkoinen aaltosulku"] # 0x2984 (en: 'right white brace', google translation) - - "⦅": [T: "vasen valkoinen kaarisulku"] # 0x2985 (en: 'left white parenthesis', google: 'vasen valkoinen sulkuteesi') - - "⦆": [T: "oikea valkoinen kaarisulku"] # 0x2986 (en: 'right white parenthesis', google: 'oikea valkoinen sulkuteesi') - - "⦇": [T: "Z-notaatio vasen kuva sulku"] # 0x2987 (en: 'z notation left image bracket', google translation) - - "⦈": [T: "Z-notaatio oikea kuva sulku"] # 0x2988 (en: 'z notation right image bracket', google translation) - - "⦉": [T: "Z-notaatio vasen sitova sulku"] # 0x2989 (google: 'z -merkintä jätti sitovan kiinnikkeen') - - "⦊": [T: "Z-notaatio oikea sitova sulku"] # 0x298a (google: 'z -merkintä oikea sitova kiinnike') - - "⦋": [T: "vasen hakasulku alaviivalla"] # 0x298b (en: 'left square bracket with underbar', google: 'vasen neliökiinnike alapalkin kanssa') - - "⦌": [T: "oikea hakasulku alaviivalla"] # 0x298c (en: 'right square bracket with underbar', google: 'oikea neliökiinnike alapalkin kanssa') - - "⦍": [T: "vasen hakasulku viivalla ylänurkassa"] # 0x298d (en: 'left square bracket with tick in top corner', google: 'vasen neliö kiinnike, punkki yläkulmassa') - - "⦎": [T: "oikea hakasulku viivalla alanurkassa"] # 0x298e (en: 'right square bracket with tick in bottom corner', google: 'oikea neliökiinnike, jossa punkki alakulmassa') - - "⦏": [T: "vasen hakasulku viivalla alanurkassa"] # 0x298f (en: 'left square bracket with tick in bottom corner', google: 'vasen neliö kiinnike, punkki alakulmassa') - - "⦐": [T: "oikea hakasulku viivalla ylänurkassa"] # 0x2990 (en: 'right square bracket with tick in top corner', google: 'oikea neliö kiinnike, punkki yläkulmassa') - - "⦑": [T: "vasen kulmasulku pisteellä"] # 0x2991 (en: 'left angle bracket with dot', google: 'vasemman kulman kiinnike pisteellä') - - "⦒": [T: "oikea kulmasulku pisteellä"] # 0x2992 (en: 'right angle bracket with dot', google: 'suoren kulman kiinnike pisteellä') - - "⦓": [T: "vasen kaari pienempi kuin sulku"] # 0x2993 (google: 'vasen kaari vähemmän kuin kiinnike') - - "⦔": [T: "oikea kaari suurempi kuin sulku"] # 0x2994 (google: 'oikea kaari suurempi kuin kiinnike') - - "⦕": [T: "vasen kaksoiskaari suurempi kuin sulku"] # 0x2995 (google: 'kaksinkertainen vasen kaari on suurempi kuin kiinnike') - - "⦖": [T: "oikea kaksoiskaari pienempi kuin sulku"] # 0x2996 (google: 'kaksinkertainen oikea kaari vähemmän kuin kiinnike') - - "⦗": [T: "vasen musta kilpikonnankuorisulku"] # 0x2997 (en: 'left black tortoise shell bracket', google translation) - - "⦘": [T: "oikea musta kilpikonnakuorisulku"] # 0x2998 (en: 'right black tortoise shell bracket', google translation) - - "⦙": [T: "pistetty aita"] # 0x2999 (en: 'dotted fence', google translation) - - "⦚": [T: "pystysuora siksak-viiva"] # 0x299a (google: 'pystysuora siksak -linja') - - "⦛": [T: "vasemmalle avautuva mitattu kulma"] # 0x299b (en: 'measured angle opening left', google translation) - - "⦜": [T: "neliöllä merkitty suora kulma"] # 0x299c (en: 'right angle variant with square', google translation) - - "⦝": [T: "kaarella merkitty suora kulma"] # 0x299d (en: 'measured right angle with dot', google: 'mitattu oikea kulma pisteellä') - - "⦞": [T: "kulma, jonka sisällä on s"] # 0x299e (en: 'angle with s inside', google translation) - - "⦟": [T: "terävä kulma"] # 0x299f (en: 'acute angle', google translation) - - "⦠": [T: "vasemmalle avautuva pallomainen kulma"] # 0x29a0 (en: 'spherical angle opening left', google translation) - - "⦡": [T: "ylös avautuva pallomainen kulma"] # 0x29a1 (en: 'spherical angle opening up', google translation) - - "⦢": [T: "käännetty kulma"] # 0x29a2 (en: 'turned angle', google translation) - - "⦣": [T: "käänteinen kulma"] # 0x29a3 (en: 'reversed angle', google translation) - - "⦤": [T: "kulma alaviivalla"] # 0x29a4 (en: 'angle with underbar', google: 'kulma alapalkin kanssa') - - "⦥": [T: "käännetty kulma alaviivalla"] # 0x29a5 (en: 'reversed angle with underbar', google: 'käännetty kulma alapalkin kanssa') - - "⦦": [T: "ylöspäin avautuva viisto kulma"] # 0x29a6 (google: 'vino kulma avautuu') - - "⦧": [T: "alaspäin avautuva viisto kulma"] # 0x29a7 (google: 'vino kulma avautuu') - - "⦨": [T: "mitattu kulma, jossa yläoikealle osoittava nuoli"] # 0x29a8 (en: 'measured angle with open arm ending in arrow pointing up and to the right', google: 'mitattu kulma, kun avoin käsivarsi päättyy nuoleen osoittaen ylös ja oikealle') - - "⦩": [T: "mitattu kulma, jossa ylävasemmalle osoittava nuoli"] # 0x29a9 (en: 'measured angle with open arm ending in arrow pointing up and to the left', google: 'mitattu kulma, jonka avoin käsivarsi päättyy nuoleen osoittaen ylös ja vasemmalle') - - "⦪": [T: "mitattu kulma, jossa alaoikealle osoittava nuoli"] # 0x29aa (en: 'measured angle with open arm ending in arrow pointing down and to the right', google: 'mitattu kulma, kun avoin käsivarsi päättyy nuolessa alaspäin ja oikealle') - - "⦫": [T: "mitattu kulma, jossa alavasemmalle osoittava nuoli"] # 0x29ab (en: 'measured angle with open arm ending in arrow pointing down and to the left', google: 'mitattu kulma, kun avoin käsivarsi päättyy nuolessa alaspäin ja vasemmalle') - - "⦬": [T: "mitattu kulma, jossa oikealle ja ylös osoittava nuoli"] # 0x29ac (en: 'measured angle with open arm ending in arrow pointing right and up', google: 'mitattu kulma, kun avoin käsivarsi päättyy nuoleen osoittaen oikealle ja ylöspäin') - - "⦭": [T: "mitattu kulma, jossa vasemmalle ja ylös osoittava nuoli"] # 0x29ad (en: 'measured angle with open arm ending in arrow pointing left and up', google: 'mitattu kulma, jonka avoin käsivarsi päättyy nuoleen osoittaen vasemmalle ja ylöspäin') - - "⦮": [T: "mitattu kulma, jossa oikealle ja alas osoittava nuoli"] # 0x29ae (en: 'measured angle with open arm ending in arrow pointing right and down', google: 'mitattu kulma, kun avoin käsivarsi päättyy nuoleen osoittaen oikealle ja alas') - - "⦯": [T: "mitattu kulma, jossa vasemmalle ja alas osoittava nuoli"] # 0x29af (en: 'measured angle with open arm ending in arrow pointing left and down', google: 'mitattu kulma, jonka nuolessa päättyy avoimeen käsivarteen, osoittaen vasemmalle ja alas') - - "⦰": [T: "käännetty tyhjä joukko"] # 0x29b0 (google: 'kääntynyt tyhjä sarja') - - "⦱": [T: "tyhjä joukko yläviivalla"] # 0x29b1 (en: 'empty set with overbar', google: 'tyhjä sarja ylikuormituksella') - - "⦲": [T: "tyhjä joukko ja pieni ympyrä yläpuolella"] # 0x29b2 (en: 'empty set with small circle above', google: 'tyhjä sarja, jossa on pieni ympyrä yllä') - - "⦳": [T: "tyhjä joukko ja oikea nuoli yläpuolella"] # 0x29b3 (en: 'empty set with right arrow above', google: 'tyhjä sarja oikealla nuolella yllä') - - "⦴": [T: "tyhjä joukko ja vasen nuoli yläpuolella"] # 0x29b4 (en: 'empty set with left arrow above', google: 'tyhjä sarja vasemmalla nuolella yllä') - - "⦵": [T: "vaakaviivallinen ympyrä"] # 0x29b5 (en: 'circle with horizontal bar', google: 'ympyrä vaakasuuntaisella palkilla') - - "⦶": [T: "ympyröity pystyviiva"] # 0x29b6 (google: 'ympyrä pystysuora palkki') - - "⦷": [T: "ympyröidyt samansuuntaiset pystyviivat"] # 0x29b7 (google: 'ympyröi rinnakkain') - - "⦸": [T: "ympyröity kenoviiva"] # 0x29b8 (en: 'circled reverse solidus', google translation) - - "⦹": [T: "ympyröity kohtisuoruusmerkki"] # 0x29b9 (google: 'ympyräsi kohtisuorassa') - - "⦺": [T: "ympyrä, joka on jaettu vaakaviivalla ja yläpuolisko on jaettu pystyviivalla"] # 0x29ba (en: 'circled divided by horizontal bar and top half divided by vertical bar', google translation) - - "⦻": [T: "ympyrä ja x päällekkäin"] # 0x29bb (en: 'circle with superimposed x', google: 'ympyrä päällekkäin x') - - "⦼": [T: "ympyröity vastapäivään käännetty jakomerkki"] # 0x29bc (en: 'circled anticlockwise rotated division sign', google: 'ympyröity vastapäivään kierretty jakomerkki') - - "⦽": [T: "nuoli ympyrän läpi"] # 0x29bd (en: 'up arrow through circle', google translation) - - "⦾": [T: "ympyröity valkoinen pieni ympyrä"] # 0x29be (google: 'ympyrävalkoinen luoti') - - "⦿": [T: "ympyröity pieni ympyrä"] # 0x29bf (google: 'ympyrä luoti') - - "⧀": [T: "ympyröity pienempi kuin"] # 0x29c0 (google: 'ympyräsi vähemmän kuin') - - "⧁": [T: "ympyröity suurempi kuin"] # 0x29c1 (google: 'ympyräsi suurempi kuin') - - "⧂": [T: "ympyrä ja pieni ympyrä oikealla"] # 0x29c2 (en: 'circle with small circle to the right', google: 'ympyrä pienellä ympyrällä oikealla') - - "⧃": [T: "ympyrä ja kaksi vaakaviivaa oikealla"] # 0x29c3 (en: 'circle with two horizontal strokes to the right', google: 'ympyrä kahdella vaakasuuntaisella iskulla oikealle') - - "⧄": [T: "neliöity kasvava diagonaalinen viiva"] # 0x29c4 (google: 'neliö nousevat diagonaaliset viiva') - - "⧅": [T: "neliöity laskeva diagonaalinen viiva"] # 0x29c5 (google: 'neliö putoava diagonaalinen viiva') - - "⧆": [T: "neliö tähdellä"] # 0x29c6 (en: 'squared asterisk', google translation) - - "⧇": [T: "neliöity pieni ympyrä"] # 0x29c7 (en: 'squared small circle', google translation) - - "⧈": [T: "neliöity pieni neliö"] # 0x29c8 (en: 'squared square', google translation) - - "⧉": [T: "kaksi limittäistä neliötä"] # 0x29c9 (google: 'kaksi liittyi neliötä') - - "⧊": [T: "kolmio ja piste yläpuolella"] # 0x29ca (en: 'triangle with dot above', google translation) - - "⧋": [T: "kolmio ja vaakaviiva alapuolella"] # 0x29cb (en: 'triangle with underbar', google translation) - - "⧌": [T: "s kolmiossa"] # 0x29cc (en: 's in triangle', google translation) - - "⧍": [T: "kolmio, jonka pohjassa serif"] # 0x29cd (en: 'triangle with serifs at bottom', google: 'kolmio alaosassa') - - "⧎": [T: "oikea kolmio vasemman kolmion yläpuolella"] # 0x29ce (google: 'oikea kolmio vasemman kolmion yläpuolella') - - "⧏": [T: "vasen kolmio pystyviivan vieressä"] # 0x29cf (en: 'left triangle beside vertical bar', google: 'vasen kolmio pystysuoran palkin vieressä') - - "⧐": [T: "pystyviiva oikean kolmion vieressä"] # 0x29d0 (en: 'vertical bar beside right triangle', google: 'pystysuora palkki oikean kolmion vieressä') - - "⧑": [T: "rusetti, jonka vasen puoli musta"] # 0x29d1 (en: 'bowtie with left half black', google translation) - - "⧒": [T: "rusetti, jonka oikea puoli musta"] # 0x29d2 (en: 'bowtie with right half black', google translation) - - "⧓": [T: "musta rusetti"] # 0x29d3 (en: 'black bowtie', google translation) - - "⧔": [T: "puolirusetti, jonka vasen puoli musta"] # 0x29d4 (en: 'times with left half black', google translation) - - "⧕": [T: "puolirusetti, jonka oikea puoli musta"] # 0x29d5 (en: 'times with right half black', google translation) - - "⧖": [T: "valkoinen tiimalasi"] # 0x29d6 (en: 'white hourglass', google translation) - - "⧗": [T: "musta tiimalasi"] # 0x29d7 (en: 'black hourglass', google translation) - - "⧘": [T: "vasen kiemurteleva viiva"] # 0x29d8 (en: 'left wiggly fence', google translation) - - "⧙": [T: "oikea kiemurteleva viiva"] # 0x29d9 (en: 'right wiggly fence', google translation) - - "⧚": [T: "vasen kaksinkertainen kiemurteleva viiva"] # 0x29da (en: 'left double wiggly fence', google: 'vasen kaksinkertainen aita') - - "⧛": [T: "oikea kaksinkertainen kiemurteleva viiva"] # 0x29db (en: 'right double wiggly fence', google: 'oikea kaksinkertainen aita') - - "⧜": [T: "epätäydellinen äärettömyys"] # 0x29dc (google: 'epätäydellinen äärettömyys') - - "⧝": [T: "yhdistetty äärettömyys"] # 0x29dd (en: 'tie over infinity', google translation) - - "⧞": [T: "äärettömyys negatoitu pystyviivalla"] # 0x29de (en: 'infinity negated with vertical bar', google: 'äärettömyys kielsi pystysuoralla palkilla') - - "⧟": [T: "kaksipäinen monikuvaus"] # 0x29df (en: 'double-ended multimap', google translation) # FI: "multimap", "monikuvaus" translation questionable - - "⧠": [T: "neliö korostetuilla ääreviivoilla"] # 0x29e0 (en: 'square with contoured outline', google translation) - - "⧡": [T: "kasvaa suhteessa"] # 0x29e1 (en: 'increases as', google translation) - - "⧢": [T: "sekoitetulo"] # 0x29e2 (en: 'shuffle product', google translation) - - "⧣": [T: "on yhtä suuri kuin kahdella vinolla yliviivalla"] # 0x29e3 (google: 'vastaa merkkiä ja viistot rinnakkain') - - "⧤": [T: "on yhtä suuri kuin kahdella vinolla yliviivalla ja tilde yläpuolella"] # 0x29e4 (en: 'equals sign and slanted parallel with tilde above', google: 'vastaa merkkiä ja viistot yhdensuuntaisen kanssa tilden kanssa yllä') - - "⧥": [T: "identtinen kuin kahdella vinolla yliviivalla"] # 0x29e5 (en: 'identical to and slanted parallel', google: 'identtinen ja vino rinnakkain') - - "⧦": [T: "tautologisesti ekvivalentti"] # 0x29e6 (google translation) - - "⧧": [T: "termodynaaminen"] # 0x29e7 (en: 'thermodynamic', google translation) - - "⧨": [T: "alaspäin osoittava kolmio ja vasen puoli musta"] # 0x29e8 (en: 'down pointing triangle with left half black', google translation) - - "⧩": [T: "alaspäin osoittava kolmio ja oikea puoli musta"] # 0x29e9 (en: 'down pointing triangle with right half black', google translation) - - "⧪": [T: "musta timantti alas osoittavalla nuolella"] # 0x29ea (en: 'black diamond with down arrow', google translation) - - "⧫": [T: "musta vinoneliö"] # 0x29eb (en: 'black lozenge', google: 'musta lozenge') - - "⧬": [T: "valkoinen ympyrä alaspäin osoittavalla nuolella"] # 0x29ec (en: 'white circle with down arrow', google translation) - - "⧭": [T: "musta ympyrä alaspäin osoittavalla nuolella"] # 0x29ed (en: 'black circle with down arrow', google translation) - - "⧮": [T: "valkoinen neliö virheviivoilla"] # 0x29ee (en: 'error-barred white square', google translation) - - "⧯": [T: "musta neliö virheviivoilla"] # 0x29ef (en: 'error-barred black square', google translation) - - "⧰": [T: "valkoinen timantti virheviivoilla"] # 0x29f0 (en: 'error-barred white diamond', google translation) - - "⧱": [T: "musta timantti virheviivoilla"] # 0x29f1 (en: 'error-barred black diamond', google translation) - - "⧲": [T: "valkoinen ympyrä virheviivoilla"] # 0x29f2 (en: 'error-barred white circle', google translation) - - "⧳": [T: "musta ympyrä virheviivoilla"] # 0x29f3 (en: 'error-barred black circle', google translation) - - "⧴": [T: "viivästetty sääntö"] # 0x29f4 (en: 'rule-delayed', google: 'sääntöviitettu') - - "⧵": [T: "kenoviiva"] # 0x29f5 (en: 'reverse solidus operator', google translation) - - "⧶": [T: "vinoviiva yläviivalla"] # 0x29f6 (en: 'solidus with overbar', google: 'solidus ylikuormituksen kanssa') - - "⧷": [T: "kenoviiva poikkiviivalla"] # 0x29f7 (en: 'reverse solidus with horizontal stroke', google translation) - - "⧸": [T: "iso vinoviiva"] # 0x29f8 (google translation) - - "⧹": [T: "iso kenoviiva"] # 0x29f9 (en: 'big reverse solidus', google translation) - - "⧺": [T: "kaksinkertainen plus"] # 0x29fa (en: 'double plus', google translation) - - "⧻": [T: "kolminkertainen plus"] # 0x29fb (google translation) - - "⧼": [T: "vasemmalle osoittava kaareva kulmahakasulku"] # 0x29fc (en: 'left pointing curved angle bracket', google translation) - - "⧽": [T: "oikealle osoittava kaareva kulmahakasulku"] # 0x29fd (en: 'right pointing curved angle bracket', google translation) - - "⧾": [T: "tiny"] # 0x29fe (en: 'tiny', google translation) - - "⧿": [T: "miny"] # 0x29ff (google translation) - - "⨀": [T: "monikollinen ympyrässä oleva kertopiste"] # 0x2a00 (en: 'circled dot operator', google translation) - - "⨁": [T: "monikollinen ympyrässä oleva plus"] # 0x2a01 (en: 'circled plus operator', google translation) - - "⨂": [T: "monikollinen ympyrässä oleva kertomerkki"] # 0x2a02 (en: 'circled times operator', google translation) - - "⨃": [T: "pisteellinen monikkounioni"] # 0x2a03 (en: 'union operator with dot', google translation) - - "⨄": [T: "monijoukkojen monikkounioni"] # 0x2a04 (en: 'union operator with plus', google translation) - - "⨅": [T: "kulmikas leikkauksen merkki"] # 0x2a05 (en: 'square intersection operator', google translation) - - "⨆": [T: "kulmikas unionin merkki"] # 0x2a06 (en: 'square union operator', google translation) - - "⨇": [T: "kaksi loogista ja-operaattoria"] # 0x2a07 (en: 'two logical and operator', google translation) - - "⨈": [T: "kaksi loogista tai-operaattoria"] # 0x2a08 (en: 'two logical or operator', google translation) - - "⨉": [T: "kertaa-operaattori"] # 0x2a09 (en: 'times operator', google translation) - - "⨊": [T: "modulo kaksi summaa"] # 0x2a0a (en: 'modulo two sum', google translation) - - "⨋": [T: "summa integraalilla"] # 0x2a0b (en: 'summation with integral', google translation) - - "⨌": [T: "nelinkertainen integraali"] # 0x2a0c (google: 'neljänneksen kiinteä operaattori') - - "⨍": [T: "pääarvointegraali"] # 0x2a0d (google: 'äärellinen osa integraali') - - "⨎": [T: "integraali kaksinkertaisella poikkiviivalla"] # 0x2a0e (en: 'integral with double stroke', google translation) - - "⨏": [T: "integraalikeskiarvo viistolla vaakaviivalla"] # 0x2a0f (en: 'integral average with slash', google translation) - - "⨐": [T: "kiertofunktio"] # 0x2a10 (google: 'kiertotoiminto') - - "⨑": [T: "integraali vastapäivään"] # 0x2a11 (google: 'vastapäivään integraatio') - - "⨒": [T: "viivaintegraali neliskulmaisella polulla navan ympäri"] # 0x2a12 (en: 'line integration with rectangular path around pole', google: 'line -integraatio suorakaiteen muotoisella polulla navan ympärillä') - - "⨓": [T: "viivaintegraali puoliympyräpolulla navan ympäri"] # 0x2a13 (en: 'line integration with semicircular path around pole', google: 'line -integrointi puolipyöreällä polulla navan ympärillä') - - "⨔": [T: "viivaintegraali ei sisällä napaa"] # 0x2a14 (google: 'linjan integrointi ei sisällä napaa') - - "⨕": [T: "integraali pisteoperaattorin ympärillä"] # 0x2a15 (google: 'integroitu pisteen operaattorin ympärillä') - - "⨖": [T: "kvaternionin integraalioperaattori"] # 0x2a16 en: 'quaternion integral operator' google: 'kvaternionin kiinteä operaattori' - - "⨗": [T: "integraali ja vasemmalle osoittava nuoli koukulla"] # 0x2a17 (en: 'integral with leftwards arrow with hook', google: 'integraali vasemmanpuoleisella nuolella koukussa') - - "⨘": [T: "integraali kertomerkillä"] # 0x2a18 (en: 'integral with times sign', google translation) - - "⨙": [T: "integraali leikkauksella"] # 0x2a19 (en: 'integral with intersection', google translation) - - "⨚": [T: "integraali unionilla"] # 0x2a1a (en: 'integral with union', google translation) - - "⨛": [T: "integraali yläviivalla"] # 0x2a1b (en: 'integral with overbar', google translation) - - "⨜": [T: "integraali alaviivalla"] # 0x2a1c (en: 'integral with underbar', google translation) - - "⨝": [T: "liitos"] # 0x2a1d (en: 'join', google translation) - - "⨞": [T: "suuri vasen kolmio -operaattori"] # 0x2a1e (en: 'large left triangle operator', google translation) - - "⨟": [T: "Z-notaatio skeemayhdiste"] # 0x2a1f (en: 'z notation schema composition', google translation) - - "⨠": [T: "Z-notaatio skeemapiping"] # 0x2a20 (en: 'z notation schema piping', google translation) - - "⨡": [T: "Z-notaatio skeemaprojektio"] # 0x2a21 (en: 'z notation schema projection', google translation) - - "⨢": [T: "plus ja ympyrä yläpuolella"] # 0x2a22 (en: 'plus sign with circle above', google: 'plus -merkki yllä olevalla ympyrällä') - - "⨣": [T: "plus ja sirkumfleksi yläpuolella"] # 0x2a23 (en: 'plus sign with circumflex accent above', google: 'plus -merkki yllä olevalla ympyrä -aksentilla') # FI: should this be "hat", "hattu"? - - "⨤": [T: "plus ja tilde yläpuolella"] # 0x2a24 (en: 'plus sign with tilde above', google: 'plus -merkki yllä olevan tilden kanssa') - - "⨥": [T: "plus ja piste alapuolella"] # 0x2a25 (en: 'plus sign with dot below', google: 'plus -merkki alla olevalla pisteellä') - - "⨦": [T: "plus ja tilde alapuolella"] # 0x2a26 (en: 'plus sign with tilde below', google: 'plus -merkki alla olevilla tildeillä') - - "⨧": [T: "plus alaindeksi kaksi"] # 0x2a27 (en: 'plus sign with subscript two', google: 'plus -merkki alaindeksi kaksi') - - "⨨": [T: "plus mustalla kolmiolla"] # 0x2a28 (en: 'plus sign with black triangle', google translation) - - "⨩": [T: "miinus ja piste yläpuolella"] # 0x2a29 (en: 'minus sign with comma above', google: 'miinus merkki yllä olevalla pilkulla') - - "⨪": [T: "miinus ja piste alapuolella"] # 0x2a2a (en: 'minus sign with dot below', google: 'miinusmerkki alla olevalla pisteellä') - - "⨫": [T: "miinus putoavilla pisteillä"] # 0x2a2b (en: 'minus sign with falling dots', google translation) - - "⨬": [T: "miinus nousevilla pisteillä"] # 0x2a2c (en: 'minus sign with rising dots', google translation) - - "⨭": [T: "plus vasemmalla puoliympyrällä"] # 0x2a2d (google: 'plus kirjaudu vasemmassa puolivälissä') - - "⨮": [T: "plus oikealla puoliympyrällä"] # 0x2a2e (google: 'plus kirjaudu oikeaan puoliväliin') - - "⨯": [T: "ristitulo"] # 0x2a2f (en: 'cross product', google: 'ristituote') - - "⨰": [T: "kertomerkki ja piste yläpuolella"] # 0x2a30 (en: 'multiplication sign with dot above', google: 'kertolaskulla olevan pisteen kanssa') - - "⨱": [T: "kertomerkki alaviivalla"] # 0x2a31 (en: 'multiplication sign with underbar', google: 'kertolasku aluskokouksella') - - "⨲": [T: "puolisuora tulo, jonka pohja suljettu"] # 0x2a32 (en: 'semidirect product with bottom closed', google translation) - - "⨳": [T: "smash tulo"] # 0x2a33 (en: 'smash product' google: 'smash -tuote') # FI: translation unclear - - "⨴": [T: "kertomerkki vasemmalla puoliympyrällä"] # 0x2a34 (google: 'kertolaskenta vasemmassa puolivälissä') - - "⨵": [T: "kertomerkki oikealla puoliympyrällä"] # 0x2a35 (google: 'kertokultaan oikea puoli ympyrä') - - "⨶": [T: "ympyröity kertomerkki sirkumfleksillä"] # 0x2a36 (en: 'circled multiplication sign with circumflex accent', google: 'ympyräkerroin merkki kehäkykyt aksentilla') # FI: should this be with "hat", "hattu"? - - "⨷": [T: "kaksoisympyröity kertomerkki"] # 0x2a37 (google: 'kertolaskenta kaksoisympyrässä') - - "⨸": [T: "ympyröity jakomerkki"] # 0x2a38 (google: 'ympyrädivisioonan merkki') - - "⨹": [T: "plus kolmiossa"] # 0x2a39 (google: 'plus kirjaudu kolmioon') - - "⨺": [T: "miinus kolmiossa"] # 0x2a3a (google: 'miinus kirjaudu kolmioon') - - "⨻": [T: "kertomerkki kolmiossa"] # 0x2a3b (google: 'kertokultaan kolmiossa') - - "⨼": [T: "sisäinen tulo"] # 0x2a3c (google: 'sisätuote') - - "⨽": [T: "oikeanpuoleinen sisäinen tulo"] # 0x2a3d (en: 'righthand interior product', google translation) - - "⨿": [T: "amalgamaatio tai kotulo"] # 0x2a3f (en: "amalgamation or coproduct", google: 'yhdistäminen tai yhteistyö') # FI: translation unclear - - "⩀": [T: "leikkaus pisteellä"] # 0x2a40 (en: 'intersection with dot', google: 'risteys pisteellä') - - "⩁": [T: "unioni miinuksella"] # 0x2a41 (en: 'union with minus sign', google translation) - - "⩂": [T: "unioni yläviivalla"] # 0x2a42 (en: 'union with overbar', google: 'unioni ylikuormituksen kanssa') - - "⩃": [T: "leikkaus yläviivalla"] # 0x2a43 (en: 'intersection with overbar', google: 'risteys ylikuormituksen kanssa') - - "⩄": [T: "leikkaus ja looginen ja"] # 0x2a44 (en: 'intersection with logical and', google: 'risteys loogisella ja') - - "⩅": [T: "unioni ja looginen tai"] # 0x2a45 (en: 'union with logical or', google: 'union loogisen tai') - - "⩆": [T: "unioni leikkauksen yläpuolella"] # 0x2a46 (google: 'unioni risteyksen yläpuolella') - - "⩇": [T: "leikkaus unionin yläpuolella"] # 0x2a47 (google: 'risteys liiton yläpuolella') - - "⩈": [T: "unioni alaviivalla leikkauksen yläpuolella"] # 0x2a48 (google: 'unioni yläpuolella risteyksen yläpuolella') - - "⩉": [T: "leikkaus alaviivalla leikkauksen yläpuolella"] # 0x2a49 (google: 'risteys yläpuolella liiton yläpuolella') - - "⩊": [T: "unioni unionin vieressä yhdistettynä"] # 0x2a4a (en: 'union beside and joined with union', google: 'unionin vieressä ja liittyi unioniin') - - "⩋": [T: "leikkaus leikkauksen vieressä yhdistettynä"] # 0x2a4b (en: 'intersection beside and joined with intersection', google: 'risteys risteyksen vieressä ja liitetty') - - "⩌": [T: "suljettu unioni serifillä"] # 0x2a4c (en: 'closed union with serifs', google: 'suljettu liitto serifien kanssa') - - "⩍": [T: "suljettu leikkaus serifillä"] # 0x2a4d (en: 'closed intersection with serifs', google: 'suljettu risteys serifien kanssa') - - "⩎": [T: "kaksinkertainen neliöleikkus"] # 0x2a4e (en: 'double square intersection', google translation) - - "⩏": [T: "kaksinkertainen neliöunioni"] # 0x2a4f (google translation) - - "⩐": [T: "suljettu unioni serifillä ja smash tulo"] # 0x2a50 (en: 'closed union with serifs and smash product', google: 'suljettu liitto serifien ja smash -tuotteen kanssa') - - "⩑": [T: "looginen ja yläpisteellä"] # 0x2a51 (en: 'logical and with dot above', google translation) - - "⩒": [T: "looginen tai yläpisteellä"] # 0x2a52 (en: 'logical or with dot above', google translation) - - "⩓": [T: "kaksinkertainen looginen ja"] # 0x2a53 (google: 'kaksinkertainen looginen ja') - - "⩔": [T: "kaksinkertainen looginen tai"] # 0x2a54 (google: 'kaksinkertainen looginen tai') - - "⩕": [T: "kaksi limittäistä loogista ja -merkkiä"] # 0x2a55 (google: 'kaksi risteävää loogista ja') - - "⩖": [T: "kaksi limittäistä loogista tai -merkkiä"] # 0x2a56 (google: 'kaksi risteävää loogista tai') - - "⩗": [T: "vino suuri tai"] # 0x2a57 (google: 'kalteva suuri tai') - - "⩘": [T: "vino suuri ja"] # 0x2a58 (google: 'kalteva iso ja') - - "⩙": [T: "looginen tai jonka päällä looginen ja"] # 0x2a59 (en: 'logical or overlapping logical and', google translation) - - "⩚": [T: "looginen ja pystyviivalla"] # 0x2a5a (en: 'logical and with middle stem', google: 'looginen ja keskimmäisellä varrella') - - "⩛": [T: "looginen tai pystyviivalla"] # 0x2a5b (en: 'logical or with middle stem', google: 'looginen tai keskimmäisellä varrella') - - "⩜": [T: "looginen ja vaakaviivalla"] # 0x2a5c (en: 'logical and with horizontal dash', google: 'looginen ja vaakasuuntaisella viivalla') - - "⩝": [T: "looginen tai vaakaviivalla"] # 0x2a5d (en: 'logical or with horizontal dash', google: 'looginen tai vaakasuuntaisella viivalla') - - "⩞": [T: "looginen ja kaksoisyläviivalla"] # 0x2a5e (en: 'logical and with double overbar', google translation) - - "⩟": [T: "looginen ja alaviivalla"] # 0x2a5f (en: 'logical and with underbar', google: 'looginen ja alikarjan kanssa') - - "⩠": [T: "looginen ja kaksoisalaviivalla"] # 0x2a60 (en: 'logical and with double underbar', google translation) - - "⩡": [T: "pieni vee alaviivalla"] # 0x2a61 (en: 'small vee with underbar', google translation) - - "⩢": [T: "looginen tai kaksoisyläviivalla"] # 0x2a62 (en: 'logical or with double overbar', google translation) - - "⩣": [T: "kaksoisalleviivattu looginen tai"] # 0x2a63 (en: 'logical or with double underbar', google translation) - - "⩤": [T: "Z-notaatio määrittelyjoukon vastarajoitus"] # 0x2a64 (en: 'z notation domain antirestriction', google translation) # FI: unclear translation - - "⩥": [T: "Z-notaatio kuvajoukon vastarajoitus"] # 0x2a65 (en: 'z notation range antirestriction', google translation) # FI: unclear translation - - "⩦": [T: "on yhtä suuri kuin alapisteellä"] # 0x2a66 (en: 'equals sign with dot below', google: 'vastaa alla olevaa pistettä') - - "⩧": [T: "identtinen yläpisteellä"] # 0x2a67 (en: 'identical with dot above', google translation) - - "⩨": [T: "kolminkertainen vaakasuora viiva kaksinkertaisella pystysuoralla viivalla"] # 0x2a68 (en: 'triple horizontal bar with double vertical stroke', google translation) - - "⩩": [T: "kolminkertainen vaakasuora viiva kolminkertaisella pystysuoralla viivalla"] # 0x2a69 (en: 'triple horizontal bar with triple vertical stroke', google translation) - - "⩪": [T: "tilde yläpisteellä"] # 0x2a6a (en: 'tilde operator with dot above', google: 'tilde -operaattori, jossa on pisteen yllä') - - "⩫": [T: "tilde nousevilla pisteillä"] # 0x2a6b (en: 'tilde operator with rising dots', google translation) - - "⩬": [T: "samankaltainen miinus samankaltainen"] # 0x2a6c (en: 'similar minus similar', google translation) - - "⩭": [T: "kongruentti yläpisteellä"] # 0x2a6d (en: 'congruent with dot above', google: 'yhteydet yllä olevan dot: n kanssa') - - "⩮": [T: "on yhtä suuri kuin tähdellä"] # 0x2a6e (en: 'equals with asterisk', google translation) - - "⩯": [T: "on lähes yhtä suuri kuin sirkumfleksillä"] # 0x2a6f (en: 'almost equal to with circumflex accent', google: 'lähes') - - "⩰": [T: "on suunnilleen yhtä suuri tai yhtä suuri kuin"] # 0x2a70 (en: 'approximately equal to or equal to', google translation) - - "⩱": [T: "on yhtä suuri kuin ja plus alapuolella"] # 0x2a71 (en: 'equals sign above plus sign', google: 'vastaa merkkiä yllä plus merkki') - - "⩲": [T: "on yhtä suuri kuin ja plus yläpuolella"] # 0x2a72 (en: 'plus sign above equals sign', google: 'plus -merkki yllä on yhtä suuri merkki') - - "⩳": [T: "on yhtä suuri kuin ja tilde alapuolella"] # 0x2a73 (google: 'yhtä suuri kuin merkki tilde -operaattorin yläpuolella') - - "⩴": [T: "tuplakaksoispiste on yhtä suuri kuin"] # 0x2a74 (google: 'kaksinkertainen paksusuolen tasainen') - - "⩵": [T: "kaksi peräkkäistä on yhtä suuri kuin -merkkiä"] # 0x2a75 (en: 'two consecutive equals signs', google: 'kaksi peräkkäistä vastaa merkkejä') - - "⩶": [T: "kolme peräkkäistä on yhtä suuri kuin -merkkiä"] # 0x2a76 (en: 'three consecutive equals signs', google translation) - - "⩷": [T: "on yhtä suuri kuin kahdella yläpisteellä ja kahdella alapisteellä"] # 0x2a77 (en: 'equals sign with two dots above and two dots below', google: 'yhtä suuri kuin kaksi pistettä yllä ja kaksi pistettä alla') - - "⩸": [T: "on yhtä suuri kuin neljällä yläpisteellä"] # 0x2a78 (en: 'equivalent with four dots above', google: 'vastaa neljällä pisteellä yllä') - - "⩹": [T: "pienempi kuin ja ympyrä sisällä"] # 0x2a79 (en: 'less than with circle inside', google: 'vähemmän kuin ympyrällä sisällä') - - "⩺": [T: "suurempi kuin ja ympyrä sisällä"] # 0x2a7a (en: 'greater than with circle inside', google: 'suurempi kuin ympyrällä sisällä') - - "⩻": [T: "pienempi kuin ja kysymysmerkki yläpuolella"] # 0x2a7b (en: 'less than with question mark above', google: 'vähemmän kuin yllä oleva kysymys') - - "⩼": [T: "suurempi kuin ja kysymysmerkki yläpuolella"] # 0x2a7c (en: 'greater than with question mark above', google: 'suurempi kuin yllä oleva kysymys') - - "⩽": [T: "pienempi kuin tai vino on yhtä suuri kuin"] # 0x2a7d (google: 'vähemmän kuin vino kuin') - - "⩾": [T: "suurempi kuin tai vino on yhtä suuri kuin"] # 0x2a7e (en: 'greater than or slanted equal to', google: 'suurempi kuin vino yhtä suuri kuin') - - "⩿": [T: "pienempi kuin tai vino on yhtä suuri kuin ja piste sisällä"] # 0x2a7f (en: 'less than or slanted equal to with dot inside', google: 'vähemmän tai vino yhtä suuri kuin pisteellä') - - "⪀": [T: "suurempi kuin tai vino on yhtä suuri kuin ja piste sisällä"] # 0x2a80 (en: 'greater than or slanted equal to with dot inside', google: 'suurempi tai viistot yhtä suuri kuin pisteellä') - - "⪁": [T: "pienempi kuin tai vino on yhtä suuri kuin ja piste yläpuolella"] # 0x2a81 (en: 'less than or slanted equal to with dot above', google: 'vähemmän kuin vino yhtä suuri kuin yllä olevalla pisteellä') - - "⪂": [T: "suurempi kuin tai vino on yhtä suuri kuin ja piste yläpuolella"] # 0x2a82 (en: 'greater than or slanted equal to with dot above', google: 'suurempi kuin vino kuin yllä olevalla pisteellä') - - "⪃": [T: "pienempi kuin tai vino on yhtä suuri kuin ja piste yläoikealla"] # 0x2a83 (en: 'less than or slanted equal to with dot above right', google: 'vähemmän tai viistot yhtä suuri kuin oikean yläpuolella') - - "⪄": [T: "suurempi kuin tai vino on yhtä suuri kuin ja piste ylävasemmalla"] # 0x2a84 (en: 'greater than or slanted equal to with dot above left', google: 'suurempi kuin vino kuin vasemman yläpuolella oleva piste') - - "⪅": [T: "vähemmän tai likimäärin"] # 0x2a85 (en: 'less than or approximate', google translation) - - "⪆": [T: "suurempi tai likimäärin"] # 0x2a86 (en: 'greater than or approximate', google translation) - - "⪇": [T: "pienempi kuin ja yksiviivainen ei yhtä suuri kuin"] # 0x2a87 (en: 'less than and single line not equal to', google translation) - - "⪈": [T: "suurempi kuin ja yksiviivainen ei yhtä suuri kuin"] # 0x2a88 (en: 'greater than and single line not equal to', google translation) - - "⪉": [T: "pienempi kuin mutta ei likimäärin"] # 0x2a89 (en: 'less than and not approximate', google: 'vähemmän kuin ja ei likimääräinen') - - "⪊": [T: "suurempi kuin mutta ei likimäärin"] # 0x2a8a (en: 'greater than and not approximate', google: 'suurempi kuin ja ei likimääräinen') - - "⪋": [T: "pienempi kuin jonka alapuolella vaakaviiva jonka alapuolella suurempi kuin"] # 0x2a8b (en: 'less than above double line equal above greater than', google translation) - - "⪌": [T: "suurempi kuin jonka alapuolella vaakaviiva jonka alapuolella pienempi kuin"] # 0x2a8c (en: 'greater than above double line equal above less than', google translation) - - "⪍": [T: "pienempi kuin jonka alapuolella yhtä suuri tai likimäärin yhtä suuri kuin"] # 0x2a8d (google: 'vähemmän kuin samanlainen tai tasainen') - - "⪎": [T: "suurempi kuin jonka alapuolella yhtä suuri tai limikäärin yhtä suuri kuin"] # 0x2a8e (google: 'suurempi kuin samanlainen tai tasainen') - - "⪏": [T: "pienempi kuin jonka alapuolella likimäärin jonka alapuolella suurempi kuin"] # 0x2a8f (google: 'vähemmän kuin yläpuolella yläpuolella suurempi kuin') - - "⪐": [T: "suurempi kuin jonka alapuolella likimäärin jonka alapuolella suurempi kuin"] # 0x2a90 (google: 'suurempi kuin edellä mainitussa yläpuolella') - - "⪑": [T: "pienempi kuin suurempi kuin tai yhtä suuri kuin"] # 0x2a91 (en: 'less than above greater than above double line equal', google: 'alle enemmän kuin yli suurempi kuin kaksoisviiva on yhtä suuri') - - "⪒": [T: "suurempi kuin pienempi kuin tai yhtä suuri kuin"] # 0x2a92 (en: 'greater than above less than above double line equal', google: 'suurempi kuin yläpuolella vähemmän kuin kaksoisviiva on yhtä suuri') - - "⪓": [T: "pienempi kuin tai vino on yhtä suuri kuin suurempi kuin tai vino on yhtä suuri kuin"] # 0x2a93 (google: 'vähemmän kuin yläpuolella viistot ovat yhtä suurempia kuin yläpuolella viistot ovat yhtä suuret') - - "⪔": [T: "suurempi kuin tai vino on yhtä suuri kuin pienempi kuin tai vino on yhtä suuri kuin"] # 0x2a94 (google: 'suurempi kuin yläpuolella viistot ovat yhtä suurempia kuin viistojen yläpuolella yhtä suuret') - - "⪕": [T: "vino on yhtä suuri kuin tai pienempi kuin"] # 0x2a95 (en: 'slanted equal to or less than', google translation) - - "⪖": [T: "vino on yhtä suuri kuin tai suurempi kuin"] # 0x2a96 (en: 'slanted equal to or greater than', google translation) - - "⪗": [T: "vino on yhtä suuri kuin tai pienempi kuin ja piste sisällä"] # 0x2a97 (en: 'slanted equal to or less than with dot inside', google: 'viisto yhtä tai vähemmän kuin pisteellä sisällä') - - "⪘": [T: "vino on yhtä suuri kuin tai suurempi kuin ja piste sisällä"] # 0x2a98 (en: 'slanted equal to or greater than with dot inside', google: 'viisto yhtä tai suurempi kuin pisteellä sisällä') - - "⪙": [T: "on yhtä suuri kuin tai pienempi kuin"] # 0x2a99 (en: 'double line equal to or less than', google: 'kaksoisviiva, joka on yhtä suuri tai vähemmän kuin') - - "⪚": [T: "on yhtä suuri kuin tai suurempi kuin"] # 0x2a9a (en: 'double line equal to or greater than', google: 'kaksoisviiva, joka on yhtä suuri tai suurempi') - - "⪛": [T: "kaksoisviivainen on yhtä suuri kuin tai pienempi kuin"] # 0x2a9b (en: 'double line slanted equal to or less than', google translation) - - "⪜": [T: "kaksoisviivainen on yhtä suuri kuin tai suurempi kuin"] # 0x2a9c (en: 'double line slanted equal to or greater than', google translation) - - "⪝": [T: "likimäärin tai pienempi kuin"] # 0x2a9d (en: 'similar or less than', google: 'samanlainen tai vähemmän kuin') - - "⪞": [T: "likimäärin tai suurempi kuin"] # 0x2a9e (google: 'samanlainen tai suurempi kuin') - - "⪟": [T: "likimäärin jonka alapuolella vähemmän kuin jonka alapuolella on yhtä suuri kuin"] # 0x2a9f (google: 'samanlainen yläpuolella vähemmän kuin yllä oleva merkki') - - "⪠": [T: "likimäärin jonka alapuolella suurempi kuin jonka alapuolella on yhtä suuri kuin"] # 0x2aa0 (google: 'samanlainen yläpuolella suurempi kuin yllä oleva merkki') - - "⪡": [T: "sisäkkäiset pienempi kuin"] # 0x2aa1 (en: 'double nested less than', google: 'kaksinkertainen sisäkkäin vähemmän kuin') - - "⪢": [T: "sisäkkäiset suurempi kuin"] # 0x2aa2 (en: 'double nested greater than', google: 'kaksinkertainen sisäkkäinen suurempi kuin') - - "⪣": [T: "kaksi sisälläistä pienempi kuin alaviivalla"] # 0x2aa3 (en: 'double nested less than with underbar', google translation) - - "⪤": [T: "pienempi kuin -merkki suurempi kuin -merkin päällä"] # 0x2aa4 (en: 'greater than overlapping less than', google: 'suurempi kuin päällekkäisyys vähemmän kuin') - - "⪥": [T: "suurempi kuin pienempi kuin"] # 0x2aa5 (google: 'suurempi kuin vähemmän kuin') - - "⪦": [T: "pienempi kuin suljettu käyrällä"] # 0x2aa6 (google: 'vähemmän kuin käyrä suljettu') - - "⪧": [T: "suurempi kuin suljettu käyrällä"] # 0x2aa7 (google: 'suurempi kuin käyrä suljettu') - - "⪨": [T: "pienempi kuin suljettu käyrällä tai yhtä suuri kuin"] # 0x2aa8 (google: 'vähemmän kuin suljettuna käyrällä viistolla tasavertaisesti') - - "⪩": [T: "suurempi kuin suljettu käyrällä tai yhtä suuri kuin"] # 0x2aa9 (google: 'suurempi kuin suljettu kaarulla, joka on viistolla yhtä suuri') - - "⪪": [T: "pienempi kuin vaakaviivalla"] # 0x2aaa (google: 'pienempi kuin') - - "⪫": [T: "suurempi kuin vaakaviivalla"] # 0x2aab (google: 'suurempi kuin') - - "⪬": [T: "pienempi kuin vaakaviivalla tai yhtä suuri kuin"] # 0x2aac (google: 'pienempi tai yhtä suuri kuin') - - "⪭": [T: "suurempi kuin vaakaviivalla tai yhtä suuri kuin"] # 0x2aad (google: 'suurempi tai yhtä suuri kuin') - - "⪮": [T: "ero välillä"] # 0x2aae (en: 'equals sign with bumpy above', google: 'yhtä suuri kuin kuohuttava yllä') # FI: translation unclear - - "⪯": [T: "edeltää jonka alapuolella yksiviivainen yhtä suuri kuin"] # 0x2aaf (google: 'ennen yhden rivin yläpuolella on yhtä suuri kuin merkki') - - "⪰": [T: "seuraa jonka alapuolella yksiviivainen yhtä suuri kuin"] # 0x2ab0 (en: 'succeeds above single line equals sign', google translation) - - "⪱": [T: "edeltää jonka alapuolella yksiviivainen ei yhtä suuri kuin"] # 0x2ab1 (en: 'precedes above single line not equal to', google translation) - - "⪲": [T: "seuraa jonka alapuolella yksiviivainen ei yhtä suuri kuin"] # 0x2ab2 (en: 'succeeds above single line not equal to', google translation) - - "⪳": [T: "edeltää jonka alapuolella yhtä suuri kuin"] # 0x2ab3 (en: 'precedes above equals sign', google translation) - - "⪴": [T: "seuraa jonka alapuolella yhtä suuri kuin"] # 0x2ab4 (en: 'succeeds above equals sign', google translation) - - "⪵": [T: "edeltää mutta ei ole yhtä suuri kuin"] # 0x2ab5 (en: 'precedes above not equal to', google: 'edellä on edellä, joka ei ole yhtä suuri kuin') - - "⪶": [T: "seuraa mutta ei ole yhtä suuri kuin"] # 0x2ab6 (en: 'succeeds above not equal to', google: 'onnistuu yläpuolella, ei ole yhtä suuri kuin') - - "⪷": [T: "edeltää ja on likimäärin"] # 0x2ab7 (en: 'precedes above almost equal to', google translation) - - "⪸": [T: "seuraa ja on likimäärin"] # 0x2ab8 (en: 'succeeds above almost equal to', google translation) - - "⪹": [T: "edeltää mutta ei ole likimäärin"] # 0x2ab9 (en: 'precedes above not almost equal to', google translation) - - "⪺": [T: "seuraa mutta ei ole likimäärin"] # 0x2aba (en: 'succeeds above not almost equal to', google translation) - - "⪻": [T: "kaksinkertainen edeltää"] # 0x2abb (google: 'kaksinkertainen edeltävä') - - "⪼": [T: "kaksinkertainen seuraa"] # 0x2abc (google: 'double onnistuu') - - "⪽": [T: "osajoukko pisteellä"] # 0x2abd (en: 'subset with dot', google: 'alajoukko pisteellä') - - "⪾": [T: "ylijoukko pisteellä"] # 0x2abe (en: 'superset with dot', google: 'superset pisteellä') - - "⪿": [T: "osajoukko ja alapuolella plus"] # 0x2abf (en: 'subset with plus sign below', google: 'alajoukko plus -merkki alla') - - "⫀": [T: "ylijoukko ja alapuolella plus"] # 0x2ac0 (en: 'superset with plus sign below', google: 'superset alla olevalla merkinnällä') - - "⫁": [T: "osajoukko ja alapuolella kertomerkki"] # 0x2ac1 (en: 'subset with multiplication sign below', google: 'alajoukko alla olevalla kertolaskulla') - - "⫂": [T: "ylijoukko ja alapuolella kertomerkki"] # 0x2ac2 (en: 'superset with multiplication sign below', google: 'superset alla olevalla kertolaskulla') - - "⫃": [T: "osajoukko tai yhtä suuri kuin ja yläpuolella piste"] # 0x2ac3 (en: 'subset of or equal to with dot above', google: 'alajoukko tai yhtä suuri kuin yllä olevalla pisteellä') - - "⫄": [T: "ylijoukko tai yhtä suuri kuin ja yläpuolella piste"] # 0x2ac4 (en: 'superset of or equal to with dot above', google: 'superset tai yhtä suuri kuin yllä olevalla pisteellä') - - "⫅": [T: "osajoukko tai yhtä suuri kuin"] # 0x2ac5 (en: 'subset of above equals sign', google translation) - - "⫆": [T: "ylijoukko tai yhtä suuri kuin"] # 0x2ac6 (en: 'superset of above equals sign', google translation) - - "⫇": [T: "likimäärin osajoukko"] # 0x2ac7 (en: 'subset of above tilde operator', google: 'yllä olevan tilde -operaattorin osajoukko') - - "⫈": [T: "likimäärin ylijoukko"] # 0x2ac8 (en: 'superset of above tilde operator', google: 'tilde -operaattorin yläpuolella') - - "⫉": [T: "osajoukko jonka alapuolella likimäärin yhtä suuri kuin"] # 0x2ac9 (en: 'subset of above almost equal to', google translation) - - "⫊": [T: "ylijoukko jonka alapuolella likimäärin yhtä suuri kuin"] # 0x2aca (en: 'superset of above almost equal to', google translation) - - "⫋": [T: "osajoukko mutta ei yhtä suuri kuin"] # 0x2acb (en: 'subset above not equal to', google translation) - - "⫌": [T: "ylijoukko mutta ei yhtä suuri kuin"] # 0x2acc (en: 'superset of above not equal to', google translation) - - "⫍": [T: "laatikko-operaattori jonka vasen puoli avoin"] # 0x2acd (en: 'square left open box operator', google translation) # FI: translation unclear - - "⫎": [T: "laatikko-operaattori jonka oikea puoli avoin"] # 0x2ace (en: 'square right open box operator', google translation) # FI: translation unclear - - "⫏": [T: "suljettu osajoukko"] # 0x2acf (google: 'suljettu alajoukko') - - "⫐": [T: "suljettu ylijoukko"] # 0x2ad0 (google: 'suljettu superset') - - "⫑": [T: "suljettu osajoukko tai yhtä suuri kuin"] # 0x2ad1 (google: 'suljettu osajoukko tai yhtä suuri kuin') - - "⫒": [T: "suljettu ylijoukko tai yhtä suuri kuin"] # 0x2ad2 (google: 'suljettu superset tai yhtä suuri kuin') - - "⫓": [T: "osajoukko ylijoukon yläpuolella"] # 0x2ad3 (en: 'subset above superset', google: 'supersetin yläpuolella') - - "⫔": [T: "ylijoukko osajoukon yläpuolella"] # 0x2ad4 (en: 'superset above subset', google: 'superset alajoukon yläpuolella') - - "⫕": [T: "osajoukko osajoukon yläpuolella"] # 0x2ad5 (en: 'subset above subset', google: 'alajoukko alajoukossa') - - "⫖": [T: "ylijoukko ylijoukon yläpuolella"] # 0x2ad6 (en: 'superset above superset', google: 'superset supersetin yläpuolella') - - "⫗": [T: "ylijoukko osajoukon vieressä"] # 0x2ad7 (google: 'superset alajoukon vieressä') - - "⫘": [T: "ylijoukko osajoukon vieressä yhdistettynä viivalla"] # 0x2ad8 (en: 'superset beside and joined by dash with subset', google: 'superset vieressä ja liittyi viivalla alajoukkoon') - - "⫙": [T: "alaspäin aukeava kuuluu joukkoon"] # 0x2ad9 (google: 'elementti avautumisesta alaspäin') - - "⫚": [T: "hanko t-yläosalla"] # 0x2ada (en: 'pitchfork with tee top', google: 'pitchfork tee -top') # FI: translation unclear - - "⫛": [T: "poikittainen leikkaus"] # 0x2adb (google: 'poikittainen risteys') # FI: translation unclear - - "⫝̸": [T: "haarukka"] # 0x2adc (en: 'forking', google translation) # FI: translation unclear - - "⫝": [T: "ei-haarukka"] # 0x2add (en: 'nonforking', google translation) # FI: translation unclear - - "⫞": [T: "lyhyt nasta vasemmalle"] # 0x2ade (en: 'short left tack', google translation) - - "⫟": [T: "lyhyt nasta alaspäin"] # 0x2adf (en: 'short down tack', google translation) - - "⫠": [T: "lyhyt nasta ylöspäin"] # 0x2ae0 (en: 'short up tack', google translation) - - "⫡": [T: "kohtisuora ja s"] # 0x2ae1 (en: 'perpendicular with s', google translation) - - "⫢": [T: "pystysuora palkki ja kolminkertainen oikea kääntöportti"] # 0x2ae2 (en: 'vertical bar triple right turnstile', google translation) - - "⫣": [T: "kaksinkertainen pystysuora viiva ja vasen kääntöportti"] # 0x2ae3 (en: 'double vertical bar left turnstile', google translation) - - "⫤": [T: "pystyviiva ja vasemmanpuoleinen kaksoiskääntöportti"] # 0x2ae4 (en: 'vertical bar double left turnstile', google: 'pystysuora palkki kaksinkertainen vasen kääntölaite') - - "⫥": [T: "kaksoispystyviiva ja vasemmanpuoleinen kaksoiskääntöportti"] # 0x2ae5 (en: 'double vertical bar double left turnstile', google translation) - - "⫦": [T: "pitkä viiva kahden pystyviivan vasemmanpuoleisesta viivasta"] # 0x2ae6 (google: 'pitkä viiva double pystysuoran vasemmalta jäseneltä') - - "⫧": [T: "lyhyt nasta alaspäin yläviivalla"] # 0x2ae7 (en: 'short down tack with overbar', google: 'lyhyt alaspäin tarttuva ylikuormitus') - - "⫨": [T: "lyhyt nasta ylöspäin alaviivalla"] # 0x2ae8 (en: 'short up tack with underbar', google: 'lyhyt up takki alapalkissa') - - "⫩": [T: "lyhyt nasta ylöspäin jonka alapuolella lyhyt nasta alaspäin"] # 0x2ae9 (google: 'lyhyt ylösnopeus lyhyen alaspäin') - - "⫪": [T: "kaksinkertainen nasta alaspäin"] # 0x2aea (en: 'double down tack', google translation) - - "⫫": [T: "kaksinkertainen nasta ylöspäin"] # 0x2aeb (google: 'kaksinkertainen tarttuva') - - "⫬": [T: "kaksoisviiva ei"] # 0x2aec (en: "double stroke not sign" google: 'kaksinkertainen isku ei allekirjoittaa') - - "⫭": [T: "käännetty kaksoisviiva ei"] # 0x2aed (en: "reversed double stroke not sign" google: 'käänteinen kaksoishalvaus ei allekirjoittaa') - - "⫮": [T: "ei jaa käännetyllä negaatioviivalla"] # 0x2aee (en: 'does not divide with reversed negation slash', google: 'ei jaa käännetyn kielteisen viivan kanssa') - - "⫯": [T: "pystyviiva ja ympyrä yläpuolella"] # 0x2aef (en: 'vertical line with circle above', google: 'pystysuora viiva ympyrän kanssa') - - "⫰": [T: "pystyviiva ja ympyrä alapuolella"] # 0x2af0 (en: 'vertical line with circle below', google: 'pystysuora viiva, jossa ympyrä alla') - - "⫱": [T: "nasta alaspäin ja ympyrä alapuolella"] # 0x2af1 (en: 'down tack with circle below', google: 'alaspäin ympyrä alla') - - "⫲": [T: "yhdensuuntainen poikkiviivalla"] # 0x2af2 (en: 'parallel with horizontal stroke', google: 'yhdensuuntainen vaakasuuntaisen iskun kanssa') - - "⫳": [T: "yhdensuuntainen tildellä"] # 0x2af3 (en: 'parallel with tilde operator', google: 'rinnakkain tilde -operaattorin kanssa') - - "⫴": [T: "kolminkertainen pystysuora viiva binäärirelaatiolla"] # 0x2af4 (en: 'triple vertical bar binary relation', google translation) - - "⫵": [T: "kolminkertainen pystysuora viiva poikkiviivalla"] # 0x2af5 (en: 'triple vertical bar with horizontal stroke', google translation) - - "⫶": [T: "kolmoispisteoperaattori"] # 0x2af6 (en: 'triple colon operator', google translation) - - "⫷": [T: "kolminkertainen sisäkkäinen vähemmän kuin"] # 0x2af7 (en: 'triple nested less than', google translation) - - "⫸": [T: "kolminkertainen sisäkkäinen suurempi kuin"] # 0x2af8 (en: 'triple nested greater than', google translation) - - "⫹": [T: "pienempi kuin tai vino kaksinkertainen on yhtä suuri kuin"] # 0x2af9 (en: 'double line slanted less than or equal to', google translation) - - "⫺": [T: "suurempi kuin tai vino kaksinkertainen on yhtä suuri kuin"] # 0x2afa (en: 'double line slanted greater than or equal to', google translation) - - "⫻": [T: "kolminkertainen vinoviiva binäärirelaatiolla"] # 0x2afb (en: 'triple solidus binary relation', google translation) - - "⫼": [T: "suuri kolminkertainen pystyviiva"] # 0x2afc (en: 'large triple vertical bar operator', google translation) - - "⫽": [T: "kaksoisvinoviiva"] # 0x2afd (en: 'double solidus operator', google translation) - - "⫾": [T: "valkoinen pystysuora palkki"] # 0x2afe (en: 'white vertical bar', google translation) - - "⫿": [T: "valkoinen pystysuora palkki"] # 0x2aff (en: 'white vertical bar', google translation) - - "⬀": [T: "yläoikealle osoittava valkoinen nuoli"] # 0x2b00 (en: 'north east white arrow', google translation) - - "⬁": [T: "ylävasemmalle osoittava valkoinen nuoli"] # 0x2b01 (en: 'north west white arrow', google translation) - - "⬂": [T: "alaoikealle osoittava valkoinen nuoli"] # 0x2b02 (en: 'south east white arrow', google translation) - - "⬃": [T: "alavasemmalle osoittava valkoinen nuoli"] # 0x2b03 (en: 'south west white arrow', google translation) - - "⬄": [T: "oikealle ja vasemmalle osoittava valkoinen nuoli"] # 0x2b04 (en: 'left right white arrow', google translation) - - "⬅": [T: "vasen musta nuoli"] # 0x2b05 (en: 'leftwards black arrow', google translation) - - "⬆": [T: "ylöspäin osoittava musta nuoli"] # 0x2b06 (en: 'upwards black arrow', google translation) - - "⬇": [T: "alaspäin osoittava musta nuoli"] # 0x2b07 (en: 'downwards black arrow', google translation) - - "⬈": [T: "yläoikealle osoittava musta nuoli"] # 0x2b08 (en: 'north east black arrow', google translation) - - "⬉": [T: "ylävasemmalle osoittava musta nuoli"] # 0x2b09 (en: 'north west black arrow', google translation) - - "⬊": [T: "alaoikealle osoittava musta nuoli"] # 0x2b0a (en: 'south east black arrow', google translation) - - "⬋": [T: "alavasemmalle osoittava musta nuoli"] # 0x2b0b (en: 'south west black arrow', google translation) - - "⬌": [T: "vasemmalle ja oikealle osoittava musta nuoli"] # 0x2b0c (en: 'left right black arrow', google translation) - - "⬍": [T: "ylös ja alas osoittava musta nuoli"] # 0x2b0d (en: 'up down black arrow', google translation) - - "⬎": [T: "oikealle ja alas osoittava nuoli"] # 0x2b0e (en: 'rightwards arrow with tip downwards', google translation) - - "⬏": [T: "oikealle ja ylös osoittava nuoli"] # 0x2b0f (en: 'rightwards arrow with tip upwards', google translation) - - "⬐": [T: "vasemmalle ja alas osoittava nuoli"] # 0x2b10 (en: 'leftwards arrow with tip downwards', google translation) - - "⬑": [T: "vasemmalle ja ylös osoittava nuoli"] # 0x2b11 (en: 'leftwards arrow with tip upwards', google translation) - - "⬒": [T: "neliö mustalla yläpuoliskolla"] # 0x2b12 (en: 'square with top half black', google translation) - - "⬓": [T: "neliö mustalla alapuoliskolla"] # 0x2b13 (en: 'square with bottom half black', google translation) - - "⬔": [T: "neliö jonka oikea diagonaali musta"] # 0x2b14 (en: 'square with upper right diagonal half black', google translation) - - "⬕": [T: "neliö jonka vasen diagonaali musta"] # 0x2b15 (en: 'square with lower left diagonal half black', google translation) - - "⬖": [T: "timantti jonka vasen puoli musta"] # 0x2b16 (en: 'diamond with left half black', google translation) - - "⬗": [T: "timantti jonka oikea puoli musta"] # 0x2b17 (en: 'diamond with right half black', google translation) - - "⬘": [T: "timantti mustalla yläpuoliskolla"] # 0x2b18 (en: 'diamond with top half black', google translation) - - "⬙": [T: "timantti mustalla alapuoliskolla"] # 0x2b19 (en: 'diamond with bottom half black', google translation) - - "⬚": [T: "laatikko"] # 0x2b1a (en: 'box', google translation) - - "⬛": [T: "musta iso neliö"] # 0x2b1b (en: 'black large square', google translation) - - "⬜": [T: "valkoinen iso neliö"] # 0x2b1c (en: 'white large square', google translation) - - "⬝": [T: "musta hyvin pieni neliö"] # 0x2b1d (en: 'black very small square', google translation) - - "⬞": [T: "valkoinen hyvin pieni neliö"] # 0x2b1e (en: 'white very small square', google translation) - - "⬟": [T: "musta viisikulmio"] # 0x2b1f (en: 'black pentagon', google translation) - - "⬠": [T: "valkoinen viisikulmio"] # 0x2b20 (en: 'white pentagon', google translation) - - "⬡": [T: "valkoinen kuusikulmio"] # 0x2b21 (en: 'white hexagon', google translation) - - "⬢": [T: "musta kuusikulmio"] # 0x2b22 (en: 'black hexagon', google translation) - - "⬣": [T: "vaaka musta kuusikulmio"] # 0x2b23 (en: 'horizontal black hexagon', google translation) - - "⬤": [T: "musta iso ympyrä"] # 0x2b24 (en: 'black large circle', google translation) - - "⬥": [T: "musta keskisuuri timantti"] # 0x2b25 (en: 'black medium diamond', google translation) - - "⬦": [T: "valkoinen keskisuuri timantti"] # 0x2b26 (en: 'white medium diamond', google translation) - - "⬧": [T: "musta keskipitkä vinoneliö"] # 0x2b27 (en: 'black medium lozenge', google translation) - - "⬨": [T: "valkoinen keskisuuri vinoneliö"] # 0x2b28 (en: 'white medium lozenge', google translation) - - "⬩": [T: "musta pieni timantti"] # 0x2b29 (en: 'black small diamond', google translation) - - "⬪": [T: "musta pieni vinoneliö"] # 0x2b2a (en: 'black small lozenge', google translation) - - "⬫": [T: "valkoinen pieni vinoneliö"] # 0x2b2b (en: 'white small lozenge', google translation) - - "⬬": [T: "musta vaakasuora ellipsi"] # 0x2b2c (en: 'black horizontal ellipse', google translation) - - "⬭": [T: "valkoinen vaakasuora ellipsi"] # 0x2b2d (en: 'white horizontal ellipse', google translation) - - "⬮": [T: "musta pystysuora ellipsi"] # 0x2b2e (en: 'black vertical ellipse', google translation) - - "⬯": [T: "valkoinen pystysuora ellipsi"] # 0x2b2f (en: 'white vertical ellipse', google translation) - - "⬰": [T: "vasen nuoli pienellä ympyrällä"] # 0x2b30 (en: 'left arrow with small circle', google translation) - - "⬱": [T: "kolme vasemmanpuoleista nuolta"] # 0x2b31 (en: 'three leftwards arrows', google translation) - - "⬲": [T: "vasen nuoli ympyröidulla plus-merkillä"] # 0x2b32 (en: 'left arrow with circled plus', google translation) - - "⬳": [T: "pitkä vasen kiemuranuoli"] # 0x2b33 (en: 'long leftwards squiggle arrow', google translation) - - "⬴": [T: "vasen kaksipäinen nuoli pystysuoralla viivalla"] # 0x2b34 (en: 'leftwards two headed arrow with vertical stroke', google translation) - - "⬵": [T: "vasen kaksipäinen nuoli kaksinkertaisella pystysuoralla viivalla"] # 0x2b35 (en: 'leftwards two headed arrow with double vertical stroke', google translation) - - "⬶": [T: "vasen kaksipäinen nuoli pystyviivasta"] # 0x2b36 (en: 'leftwards two headed arrow from bar', google translation) - - "⬷": [T: "vasen kaksipäinen kolmoiskatkoviivanuoli"] # 0x2b37 (en: 'leftwards two headed triple dash arrow', google translation) - - "⬸": [T: "vasen nuoli katkoviivalla"] # 0x2b38 (en: 'leftwards arrow with dotted stem', google translation) - - "⬹": [T: "vasen nuoli hännällä ja pystyviivalla"] # 0x2b39 (en: 'leftwards arrow with tail with vertical stroke', google translation) - - "⬺": [T: "vasen nuoli hännällä ja kaksinkertaisella pystyviivalla"] # 0x2b3a (en: 'leftwards arrow with tail with double vertical stroke', google translation) - - "⬻": [T: "vasen kaksipäinen nuoli hännällä"] # 0x2b3b (en: 'leftwards two headed arrow with tail', google translation) - - "⬼": [T: "vasen kaksipäinen nuoli hännällä ja pystysuoralla viivalla"] # 0x2b3c (en: 'leftwards two headed arrow with tail with vertical stroke', google translation) - - "⬽": [T: "vasen kaksipäinen nuoli hännällä ja kaksinkertaisella pystysuoralla viivalla"] # 0x2b3d (en: 'leftwards two headed arrow with tail with double vertical stroke', google translation) - - "⬾": [T: "vasen nuoli x:n läpi"] # 0x2b3e (en: 'leftwards arrow through x', google translation) - - "⬿": [T: "suoraan vasemmalle osoittava aaltonuoli"] # 0x2b3f (en: 'wave arrow pointing directly left', google translation) - - "⭀": [T: "on yhtä suuri kuin vasemman nuolen yläpuolella"] # 0x2b40 (en: 'equals sign above leftwards arrow', google translation) - - "⭁": [T: "käännetty tilde vasemman nuolen yläpuolella"] # 0x2b41 (en: 'reverse tilde operator above leftwards arrow', google translation) - - "⭂": [T: "likimäärin yhtä suuri kuin vasemman nuolen alapuolella"] # 0x2b42 (en: 'leftwards arrow above reverse almost equal to', google translation) - - "⭃": [T: "oikea nuoli suurempi kuin läpi"] # 0x2b43 (en: 'rightwards arrow through greater than', google translation) - - "⭄": [T: "oikea nuoli ylijoukon läpi"] # 0x2b44 (en: 'rightwards arrow through superset', google translation) - - "⭅": [T: "vasen nelinkertainen nuoli"] # 0x2b45 (en: 'leftwards quadruple arrow', google translation) - - "⭆": [T: "oikea nelinkertainen nuoli"] # 0x2b46 (en: 'rightwards quadruple arrow', google translation) - - "⭇": [T: "käännetty tilde oikean nuolen yläpuolella"] # 0x2b47 (en: 'reverse tilde operator above rightwards arrow', google translation) - - "⭈": [T: "käännetty likimäärin yhtä suuri kuin oikean nuolen alapuolella"] # 0x2b48 (en: 'rightwards arrow above reverse almost equal to', google translation) - - "⭉": [T: "tilde vasemman nuolen yläpuolella"] # 0x2b49 (en: 'tilde operator above leftwards arrow', google translation) - - "⭊": [T: "likimäärin yhtä suuri kuin vasemman nuolen alapuolella"] # 0x2b4a (en: 'leftwards arrow above almost equal to', google translation) - - "⭋": [T: "vasen nuoli käännetyn tilden yläpuolella"] # 0x2b4b (en: 'leftwards arrow above reverse tilde operator', google translation) - - "⭌": [T: "oikea nuoli käännetyn tilden yläpuolella"] # 0x2b4c (en: 'rightwards arrow above reverse tilde operator', google translation) - - "⭐": [T: "tähti"] # 0x2b50 (google: 'valkoinen keskisuuri tähti') - - "⭑": [T: "musta pieni tähti"] # 0x2b51 (google: 'musta pieni tähti') - - "⭒": [T: "valkoinen pieni tähti"] # 0x2b52 (google: 'valkoinen pieni tähti') - - "⭓": [T: "musta oikealle osoittava viisikulmio"] # 0x2b53 (en: 'black right pointing pentagon', google translation) - - "⭔": [T: "valkoinen oikealle osoittava viisikulmio"] # 0x2b54 (en: 'white right pointing pentagon', google translation) - - "⭕": [T: "raskas iso ympyrä"] # 0x2b55 (en: 'heavy large circle', google translation) - - "⭖": [T: "raskas ovaali jonka sisällä ovaali"] # 0x2b56 (en: 'heavy oval with oval inside', google translation) - - "⭗": [T: "raskas ympyrä jonka sisällä ympyrä"] # 0x2b57 (en: 'heavy circle with circle inside', google translation) - - "⭘": [T: "raskas ympyrä"] # 0x2b58 (en: 'heavy circle', google translation) - - "⭙": [T: "raskas ympyröity saltire"] # 0x2b59 (en: 'heavy circled saltire', google translation) - - "⸀": [T: "suoran kulman korvaamismerkki"] # 0x2e00 (en: 'right angle substitution marker', google translation) - - "⸁": [T: "suoran kulman korvaamismerkki pisteellä"] # 0x2e01 (en: 'right angle dotted substitution marker', google translation) - - "⸂": [T: "vasen korvaus hakasulku"] # 0x2e02 (en: 'left substitution bracket', google translation) - - "⸃": [T: "oikea korvaus hakasulku"] # 0x2e03 (en: 'right substitution bracket', google translation) - - "⸄": [T: "vasen korvaus hakasulku pisteellä"] # 0x2e04 (en: 'left dotted substitution bracket', google translation) - - "⸅": [T: "oikea korvaus hakasulku pisteellä"] # 0x2e05 (en: 'right dotted substitution bracket', google translation) - - "⸆": [T: "korotettu interpolointimerkki"] # 0x2e06 (en: 'raised interpolation marker', google translation) - - "⸇": [T: "korotettu interpolointimerkki pisteellä"] # 0x2e07 (en: 'raised dotted interpolation marker', google translation) - - "⸈": [T: "transposointimerkki pisteellä"] # 0x2e08 (en: 'dotted transposition marker marker', google translation) - - "⸉": [T: "vasen transponointi hakasulku"] # 0x2e09 (en: 'left transposition bracket', google translation) - - "⸊": [T: "oikea transponointi hakasulku"] # 0x2e0a (en: 'right transposition bracket', google translation) - - "⸋": [T: "korotettu neliö"] # 0x2e0b (en: 'raised square', google translation) - - "⸌": [T: "vasen korotettu poistosulku"] # 0x2e0c (en: 'left raised omission bracket', google translation) - - "⸍": [T: "oikea korotettu poistosulku"] # 0x2e0d (en: 'right raised omission bracket', google translation) - - "⸎": [T: "toimituskoronis"] # 0x2e0e (en: 'editorial coronis', google translation) - - "⸏": [T: "kappale"] # 0x2e0f (en: 'paragraphos', google translation) - - "⸐": [T: "haarukkakappale"] # 0x2e10 (en: 'forked paragraphos', google translation) - - "⸑": [T: "käännetty haarukkakappale"] # 0x2e11 (en: 'reversed forked paragraphos', google translation) - - "⸒": [T: "hypodiastoli"] # 0x2e12 (en: 'hypodiastole', google translation) - - "⸓": [T: "obelos pisteellä"] # 0x2e13 (en: 'dotted obelos', google translation) - - "⸔": [T: "ankkuri alaspäin"] # 0x2e14 (en: 'downwards ancora', google translation) - - "⸕": [T: "ankkuri ylöspäin"] # 0x2e15 (en: 'upwards ancora', google translation) - - "⸖": [T: "oikealle osoittava kulma pisteillä"] # 0x2e16 (en: 'dotted right pointing angle', google translation) - - "⸗": [T: "kaksinkertainen vino tavuviiva"] # 0x2e17 (en: 'double oblique hyphen', google translation) - - "⸘": [T: "käänteinen huutokysymys"] # 0x2e18 (en: 'inverted interrobang', google translation) - - "⸙": [T: "palmun oksa"] # 0x2e19 (en: 'palm branch', google translation) - - "⸚": [T: "tavuviiva treemalla"] # 0x2e1a (en: 'hyphen with diaeresis', google translation) - - "⸛": [T: "tilde ja rengas yläpuolella"] # 0x2e1b (en: 'tilde with ring above', google translation) - - "⸜": [T: "vasen matala parafraasi hakasulku"] # 0x2e1c (en: 'left low paraphrase bracket', google translation) - - "⸝": [T: "oikea matala parafraasi hakasulku"] # 0x2e1d (en: 'right low paraphrase bracket', google translation) - - "⸞": [T: "tilde ja piste yläpuolella"] # 0x2e1e (en: 'tilde with dot above', google translation) - - "⸟": [T: "tilde ja piste alapuolella"] # 0x2e1f (en: 'tilde with dot below', google translation) - - "⸠": [T: "vasen pystysuora palkki piikillä"] # 0x2e20 (en: 'left vertical bar with quill', google translation) - - "⸡": [T: "oikea pystysuora palkki piikillä"] # 0x2e21 (en: 'right vertical bar with quill', google translation) - - "⸢": [T: "ylävasen puolihakasulku"] # 0x2e22 (en: 'top left half bracket', google translation) - - "⸣": [T: "yläoikea puolihakasulku"] # 0x2e23 (en: 'top right half bracket', google translation) - - "⸤": [T: "alavasen puolihakasulku"] # 0x2e24 (en: 'bottom left half bracket', google translation) - - "⸥": [T: "alaoikea puolihakasulku"] # 0x2e25 (en: 'bottom right half bracket', google translation) - - "⸦": [T: "vasen sivusuuntainen u-hakasulku"] # 0x2e26 (en: 'left sideways u bracket', google translation) - - "⸧": [T: "oikea sivusuuntainen u-hakasulku"] # 0x2e27 (en: 'right sideways u bracket', google translation) - - "⸨": [T: "vasen kaksinkertainen sulku"] # 0x2e28 (en: 'left double parentheses', google translation) - - "⸩": [T: "oikea kaksinkertainen sulku"] # 0x2e29 (en: 'right double parentheses', google translation) - - "⸪": [T: "kaksi pistettä yhden pisteen päällä"] # 0x2e2a (en: 'two dots over one dot punctuation', google translation) - - "⸫": [T: "yksi piste kahden pisteen päällä"] # 0x2e2b (en: 'one dot over two dots punctuation', google translation) - - "⸬": [T: "neljä pistettä neliön muodossa"] # 0x2e2c (en: 'squared four dot punctuation', google translation) - - "⸭": [T: "viisi pistettä"] # 0x2e2d (en: 'five dot mark', google translation) - - "⸮": [T: "käännetty kysymysmerkki"] # 0x2e2e (en: 'reversed question mark', google translation) - - "ⸯ": [T: "pystysuora tilde"] # 0x2e2f (en: 'vertical tilde', google translation) - - "⸰": [T: "rengaspiste"] # 0x2e30 (en: 'ring point', google translation) - - "⸱": [T: "sanaerotinpiste"] # 0x2e31 (en: 'word separator middle dot', google translation) - - "⸲": [T: "käännetty pilkku"] # 0x2e32 (en: 'turned comma', google translation) - - "⸳": [T: "nostettu piste"] # 0x2e33 (en: 'raised dot', google translation) - - "⸴": [T: "nostettu pilkku"] # 0x2e34 (en: 'raised comma', google translation) - - "⸵": [T: "käännetty puolipiste"] # 0x2e35 (en: 'turned semicolon', google translation) - - "⸶": [T: "tikari vasemmalla suojalla"] # 0x2e36 (en: 'dagger with left guard', google translation) - - "⸷": [T: "tikari oikealla suojalla"] # 0x2e37 (en: 'dagger with right guard', google translation) - - "⸸": [T: "käännetty tikari"] # 0x2e38 (en: 'turned dagger', google translation) - - "⸹": [T: "yläpuolimerkki"] # 0x2e39 (en: 'top half section sign', google translation) # FI: translation unclear - - "⸺": [T: "kaksoisajatusviiva"] # 0x2e3a (en: 'two em dash', google translation) - - "⸻": [T: "kolmoisajatusviiva"] # 0x2e3b (en: 'three em dash', google translation) - - "〃": [T: "sama sisältö -merkki"] # 0x3003 (google translation) - - "〈": [T: "vasen kulmasulku"] # 0x3008 (en: 'left angle bracket', google translation) - - "〉": [T: "oikea kulmasulku"] # 0x3009 (en: 'right angle bracket', google translation) - - "《": [T: "vasen kaksoiskulmasulku"] # 0x300a (google: 'vasen kaksoiskulma kiinnike') - - "》": [T: "oikea kaksoiskulmasulku"] # 0x300b (google: 'oikea kaksoiskulma kiinnike') - - "「": [T: "vasen nurkka hakasulku"] # 0x300c (en: 'left corner bracket', google translation) - - "」": [T: "oikea nurkka hakasulku"] # 0x300d (en: 'right corner bracket', google translation) - - "『": [T: "vasen valkoinen nurkka hakasulku"] # 0x300e (en: 'left white corner bracket', google translation) - - "』": [T: "oikea valkoinen nurkkahakasulku"] # 0x300f (en: 'right white corner bracket', google translation) - - "【": [T: "vasen musta linssimäinen hakasulku"] # 0x3010 (en: 'left black lenticular bracket', google translation) - - "】": [T: "oikea musta linssimäinen hakasulku"] # 0x3011 (en: 'right black lenticular bracket', google translation) - - "〔": [T: "vasen kilpikonnankuori hakasulku"] # 0x3014 (google: 'vasen kilpikonnan kuoren kiinnike') - - "〕": [T: "oikea kilpikonnankuori hakasulku"] # 0x3015 (google: 'oikea kilpikonnakuoren kiinnike') - - "〖": [T: "vasen valkoinen linssimäinen hakasulku"] # 0x3016 (en: 'left white lenticular bracket', google translation) - - "〗": [T: "oikea valkoinen linssimäinen hakasulku"] # 0x3017 (en: 'right white lenticular bracket', google translation) - - "〘": [T: "vasen valkoinen kilpikonnakuori hakasulku"] # 0x3018 (en: 'left white tortoise shell bracket', google translation) - - "〙": [T: "oikea valkoinen kilpikonnakuori hakasulku"] # 0x3019 (en: 'right white tortoise shell bracket', google translation) - - "〚": [T: "vasen valkoinen neliö hakasulku"] # 0x301a (google: 'vasen valkoinen neliömäki') - - "〛": [T: "oikea valkoinen neliö hakasulku"] # 0x301b (google: 'oikea valkoinen neliömäki') - - "〜": [T: "aaltomainen viiva"] # 0x301c (en: 'wave dash', google translation) - - "〰": [T: "aaltoileva viiva"] # 0x3030 (en: 'wavy dash', google: 'aaltoileva viiva') - - "㉈": [T: "ympyröity numero kymmenen mustalla neliöllä"] # 0x3248 (en: 'circled number ten on black square', google translation) - - "㉉": [T: "ympyröity numero kaksikymmentä mustalla neliöllä"] # 0x3249 (en: 'circled number twenty on black square', google translation) - - "㉊": [T: "ympyröity numero kolmekymmentä mustalla neliöllä"] # 0x324a (en: 'circled number thirty on black square', google translation) - - "㉋": [T: "ympyröity numero neljäkymmentä mustalla neliöllä"] # 0x324b (en: 'circled number forty on blacks square', google translation) - - "㉌": [T: "ympyröity numero viisikymmentä mustalla neliöllä"] # 0x324c (en: 'circled number fifty on black square', google translation) - - "㉍": [T: "ympyröity numero kuusikymmentä mustalla neliöllä"] # 0x324d (en: 'circled number sixty on black square', google translation) - - "㉎": [T: "ympyröity numero seitsemänkymmentä mustalla neliöllä"] # 0x324e (en: 'circled number seventy on black square', google translation) - - "㉏": [T: "ympyröity numero kahdeksankymmentä mustalla neliöllä"] # 0x324f (en: 'circled number eighty on black square', google translation) - - "㉑": [T: "ympyröity numero kaksikymmentäyksi"] # 0x3251 (en: 'circled number twenty one', google translation) - - "㉒": [T: "ympyröity numero kaksikymmentäkaksi"] # 0x3252 (en: 'circled number twenty two', google translation) - - "㉓": [T: "ympyröity numero kaksikymmentäkolme"] # 0x3253 (en: 'circled number twenty three', google translation) - - "㉔": [T: "ympyröity numero kaksikymmentäneljä"] # 0x3254 (en: 'circled number twenty four', google translation) - - "㉕": [T: "ympyröity numero kaksikymmentäviisi"] # 0x3255 (en: 'circled number twenty five', google translation) - - "㉖": [T: "ympyröity numero kaksikymmentäkuusi"] # 0x3256 (en: 'circled number twenty six', google translation) - - "㉗": [T: "ympyröity numero kaksikymmentäseitsemän"] # 0x3257 (en: 'circled number twenty seven', google translation) - - "㉘": [T: "ympyröity numero kaksikymmentäkahdeksan"] # 0x3258 (en: 'circled number twenty eight', google translation) - - "㉙": [T: "ympyröity numero kaksikymmentäyhdeksän"] # 0x3259 (en: 'circled number twenty nine', google translation) - - "㉚": [T: "ympyröity numero kolmekymmentä"] # 0x325a (en: 'circled number thirty', google translation) - - "㉛": [T: "ympyröity numero kolmekymmentäyksi"] # 0x325b (en: 'circled number thirty one', google translation) - - "㉜": [T: "ympyröity numero kolmekymmentäkaksi"] # 0x325c (en: 'circled number thirty two', google translation) - - "㉝": [T: "ympyröity numero kolmekymmentäkolme"] # 0x325d (en: 'circled number thirty three', google translation) - - "㉞": [T: "ympyröity numero kolmekymmentäneljä"] # 0x325e (en: 'circled number thirty four', google translation) - - "㉟": [T: "ympyröity numero kolmekymmentäviisi"] # 0x325f (en: 'circled number thirty five', google translation) - - "㊱": [T: "ympyröity numero kolmekymmentäkuusi"] # 0x32b1 (en: 'circled number thirty six', google translation) - - "㊲": [T: "ympyröity numero kolmekymmentäseitsemän"] # 0x32b2 (en: 'circled number thirty seven', GPT-5.4 translation) - - "㊳": [T: "ympyröity numero kolmekymmentäkahdeksan"] # 0x32b3 (en: 'circled number thirty eight', GPT-5.4 translation) - - "㊴": [T: "ympyröity numero kolmekymmentäyhdeksän"] # 0x32b4 (en: 'circled number thirty nine', GPT-5.4 translation) - - "㊵": [T: "ympyröity numero neljäkymmentä"] # 0x32b5 (en: 'circled number forty', GPT-5.4 translation) - - "㊶": [T: "ympyröity numero neljäkymmentäyksi"] # 0x32b6 (en: 'circled number forty one', GPT-5.4 translation) - - "㊷": [T: "ympyröity numero neljäkymmentäkaksi"] # 0x32b7 (en: 'circled number forty two', GPT-5.4 translation) - - "㊸": [T: "ympyröity numero neljäkymmentäkolme"] # 0x32b8 (en: 'circled number forty three', GPT-5.4 translation) - - "㊹": [T: "ympyröity numero neljäkymmentäneljä"] # 0x32b9 (en: 'circled number forty four', GPT-5.4 translation) - - "㊺": [T: "ympyröity numero neljäkymmentäviisi"] # 0x32ba (en: 'circled number forty five', GPT-5.4 translation) - - "㊻": [T: "ympyröity numero neljäkymmentäkuusi"] # 0x32bb (en: 'circled number forty six', GPT-5.4 translation) - - "㊼": [T: "ympyröity numero neljäkymmentäseitsemän"] # 0x32bc (en: 'circled number forty seven', GPT-5.4 translation) - - "㊽": [T: "ympyröity numero neljäkymmentäkahdeksan"] # 0x32bd (en: 'circled number forty eight', GPT-5.4 translation) - - "㊾": [T: "ympyröity numero neljäkymmentäyhdeksän"] # 0x32be (en: 'circled number forty nine', GPT-5.4 translation) - - "㊿": [T: "ympyröity numero viisikymmentä"] # 0x32bf (en: 'circled number fifty', GPT-5.4 translation) - - "㋌": [T: "elohopea"] # 0x32cc (en: 'mercury', google translation) - - "㋍": [T: "ergiä"] # 0x32cd (google translation) - - "㋎": [T: "elektronivolttia"] # 0x32ce (en: 'electron volts', google translation) - - "㋏": [T: "L T D"] # 0x32cf (en: 'limited liability sign', google translation) - - "㍱": [T: "hehtopascalia"] # 0x3371 (en: 'hectopascals', google translation) - - "㍲": [T: "daltonia"] # 0x3372 (en: 'daltons', google translation) - - "㍳": [T: "tähtieteellistä yksikköä"] # 0x3373 (en: 'astronomical units', google translation) - - "㍴": [T: "baaria"] # 0x3374 (en: 'bars', google translation) - - "㍵": [T: "o V"] # 0x3375 (google translation) - - "㍶": [T: "parsekia"] # 0x3376 (google translation) - - "㍷": [T: "desimetriä"] # 0x3377 (en: 'decimeters', google translation) - - "㍸": [T: "neliödesimetriä"] # 0x3378 (en: 'decimeters squared', google translation) - - "㍹": [T: "kuutiodesimetriä"] # 0x3379 (en: 'decimeters cubed', google translation) - - "㍺": [T: "I U"] # 0x337a (en: 'instrumental units', google translation) - - "㎀": [T: "pikoampeeria"] # 0x3380 (google translation) - - "㎁": [T: "nanoampeeria"] # 0x3381 (google translation) - - "㎂": [T: "mikroampeeria"] # 0x3382 (en: 'microamps', google translation) - - "㎃": [T: "milliampeeria"] # 0x3383 (en: 'milliamps', google translation) - - "㎄": [T: "kiloampeeria"] # 0x3384 (google translation) - - "㎅": [T: "Kilobittiä"] # 0x3385 (en: 'kilobytes', google translation) - - "㎆": [T: "megatavua"] # 0x3386 (en: 'megabytes', google translation) - - "㎇": [T: "gigatavua"] # 0x3387 (en: 'gigabytes', google translation) - - "㎈": [T: "kaloria"] # 0x3388 (en: 'calories', google translation) - - "㎉": [T: "kilokaloria"] # 0x3389 (en: 'kilocalories', google translation) - - "㎊": [T: "pifaradayta"] # 0x338a (google translation) - - "㎋": [T: "nanofaradayta"] # 0x338b (en: 'nanofarads', google translation) - - "㎌": [T: "mikrofaradayta"] # 0x338c (en: 'microfarads', google translation) - - "㎍": [T: "mikrogrammaa"] # 0x338d (en: 'micrograms', google translation) - - "㎎": [T: "milligrammaa"] # 0x338e (en: 'milligrams', google translation) - - "㎏": [T: "kilogrammaa"] # 0x338f (en: 'kilograms', google translation) - - "㎐": [T: "hertsiä"] # 0x3390 (google translation) - - "㎑": [T: "kilohertsiä"] # 0x3391 (en: 'kilohertz', google translation) - - "㎒": [T: "megahertsiä"] # 0x3392 (en: 'megahertz', google translation) - - "㎓": [T: "gigahertsiä"] # 0x3393 (en: 'gigahertz', google translation) - - "㎔": [T: "terahertsiä"] # 0x3394 (en: 'terahertz', google translation) - - "㎕": [T: "mikrolitraa"] # 0x3395 (en: 'microliters', google translation) - - "㎖": [T: "millilitraa"] # 0x3396 (en: 'milliliters', google translation) - - "㎗": [T: "desilitraa"] # 0x3397 (google translation) - - "㎘": [T: "kilolitraa"] # 0x3398 (en: 'kiloliters', google translation) - - "㎙": [T: "femtometriä"] # 0x3399 (en: 'femtometers', google translation) - - "㎚": [T: "nanometriä"] # 0x339a (en: 'nanometers', google translation) - - "㎛": [T: "mikrometriä"] # 0x339b (en: 'micrometers', google translation) - - "㎜": [T: "millimetriä"] # 0x339c (en: 'millimeters', google translation) - - "㎝": [T: "senttimetriä"] # 0x339d (en: 'centimeters', google translation) - - "㎞": [T: "kilometriä"] # 0x339e (en: 'kilometers', google translation) - - "㎟": [T: "neliömillimetriä"] # 0x339f (en: 'millimeters squared', google translation) - - "㎠": [T: "neliösenttimetriä"] # 0x33a0 (en: 'centimeters squared', google translation) - - "㎡": [T: "neliömetriä"] # 0x33a1 (en: 'meters squared', google translation) - - "㎢": [T: "neliökilometriä"] # 0x33a2 (en: 'kilometers squared', google translation) - - "㎣": [T: "kuutiomillimetriä"] # 0x33a3 (en: 'millimeters cubed', google translation) - - "㎤": [T: "kuutiosenttimetriä"] # 0x33a4 (en: 'centimeters cubed', google translation) - - "㎥": [T: "kuutiometriä"] # 0x33a5 (en: 'meters cubed', google translation) - - "㎦": [T: "kuutiokilometriä"] # 0x33a6 (en: 'kilometers cubed', google translation) - - "㎧": [T: "metriä sekunnissa"] # 0x33a7 (en: 'meters per second', google translation) - - "㎨": [T: "metriä per neliösekunti"] # 0x33a8 (en: 'meters per second squared', google translation) - - "㎩": [T: "pascalia"] # 0x33a9 (google translation) - - "㎪": [T: "kilopascalia"] # 0x33aa (google translation) - - "㎫": [T: "megapascalia"] # 0x33ab (google translation) - - "㎬": [T: "gigapascalia"] # 0x33ac (google translation) - - "㎭": [T: "radiaania"] # 0x33ad (en: 'rads', google translation) - - "㎮": [T: "radiaania sekunnissa"] # 0x33ae (en: 'rads per second', google translation) - - "㎯": [T: "radiaania neliösekunnissa"] # 0x33af (en: 'rads per second squared', google translation) - - "㎰": [T: "pikosekuntia"] # 0x33b0 (en: 'picoseconds', google translation) - - "㎱": [T: "nanosekuntia"] # 0x33b1 (en: 'nanoseconds', google translation) - - "㎲": [T: "mikrosekuntia"] # 0x33b2 (en: 'microseconds', google translation) - - "㎳": [T: "millisekuntia"] # 0x33b3 (en: 'milliseconds', google translation) - - "㎴": [T: "pikovolttia"] # 0x33b4 (google translation) - - "㎵": [T: "nanovolttia"] # 0x33b5 (en: 'nanovolts', google translation) - - "㎶": [T: "mikrovolttia"] # 0x33b6 (en: 'microvolts', google translation) - - "㎷": [T: "millivolttia"] # 0x33b7 (google translation) - - "㎸": [T: "kilovolttia"] # 0x33b8 (en: 'kilovolts', google translation) - - "㎹": [T: "megavolttia"] # 0x33b9 (google translation) - - "㎺": [T: "pikowattia"] # 0x33ba (google translation) - - "㎻": [T: "nanowattia"] # 0x33bb (en: 'nanowatts', google translation) - - "㎼": [T: "mikrowattia"] # 0x33bc (en: 'microwatts', google translation) - - "㎽": [T: "milliwattia"] # 0x33bd (google translation) - - "㎾": [T: "kilowattia"] # 0x33be (en: 'kilowatts', google translation) - - "㎿": [T: "megawattia"] # 0x33bf (google translation) - - "㏀": [T: "kilo-ohmia"] # 0x33c0 (google translation) - - "㏁": [T: "megaohmia"] # 0x33c1 (google translation) - - "㏂": [T: "a m"] # 0x33c2 (en: 'attometers', google translation) - - "㏃": [T: "becquerelia"] # 0x33c3 (google translation) - - "㏄": [T: "kuutiosenttimetriä"] # 0x33c4 (en: 'cubic centimeters', google translation) - - "㏅": [T: "candelaa"] # 0x33c5 (google translation) - - "㏆": [T: "coulombia kilogrammassa"] # 0x33c6 (en: 'coulombs per kilogram', google translation) - - "㏇": [T: "C o piste"] # 0x33c7 (en: 'cardiac output', google translation) - - "㏈": [T: "desibeliä"] # 0x33c8 (en: 'decibels', google translation) - - "㏉": [T: "grayta"] # 0x33c9 (en: 'grays', google translation) - - "㏊": [T: "hehtaaria"] # 0x33ca (en: 'hectares', google translation) - - "㏋": [T: "hevosvoimaa"] # 0x33cb (en: 'horsepower', google translation) - - "㏌": [T: "tuumaa"] # 0x33cc (en: 'inches', google translation) - - "㏍": [T: "kilokelviniä"] # 0x33cd (google translation) - - "㏎": [T: "kilometriä"] # 0x33ce (en: 'kilometers', google translation) - - "㏏": [T: "solmua"] # 0x33cf (en: 'knots', google translation) - - "㏐": [T: "lumenia"] # 0x33d0 (google translation) - - "㏑": [T: "luonnollinen logaritmi"] # 0x33d1 (en: 'natural log', google translation) - - "㏒": [T: "logaritmi"] # 0x33d2 (en: 'logarithm', google translation) - - "㏓": [T: "luxia"] # 0x33d3 (google translation) - - "㏔": [T: "millibarnia"] # 0x33d4 (google translation) - - "㏕": [T: "milliä"] # 0x33d5 (en: 'mills', google translation) - - "㏖": [T: "moolia"] # 0x33d6 (en: 'moles', google translation) - - "㏗": [T: "p H"] # 0x33d7 (google translation) - - "㏘": [T: "pikometriä"] # 0x33d8 (en: 'picometers', google translation) - - "㏙": [T: "miljoonasosaa"] # 0x33d9 (en: 'parts per million', google translation) - - "㏚": [T: "petaröntgeniä"] # 0x33da (google translation) - - "㏛": [T: "steradiaania"] # 0x33db (en: 'steradians', google translation) - - "㏜": [T: "sievertiä"] # 0x33dc (en: 'sieverts', google translation) - - "㏝": [T: "weberiä"] # 0x33dd (google translation) - - "㏞": [T: "volttia per metri"] # 0x33de (en: 'volts per meter', google translation) - - "㏟": [T: "ampeeria per metri"] # 0x33df (en: 'amps per meter', google translation) - - "㏿": [T: "gallonaa"] # 0x33ff (en: 'gallons', google translation) - - "": [T: "on yhtä suuri kuin ja hattu alapuolella"] # 0xe900 (en: 'equals with hat below', google translation) - - "": [T: "on yhtä suuri kuin ja plus yläpuolella"] # 0xe901 (en: 'equals with plus above', google translation) - - "": [T: "on yhtä suuri kuin ja plus alapuolella"] # 0xe902 (en: 'equals with plus below', google translation) - - "": [T: "tilde ja plus yläpuolella"] # 0xe903 (en: 'tilde with plus above', google translation) - - "": [T: "tilde ja plus alapuolella"] # 0xe904 (en: 'tilde with plus below', google translation) - - "": [T: "kaksinkertainen on yhtä suuri kuin ja alapuolella suurempi kuin"] # 0xe908 (en: 'equal double over greater than', google translation) - - "": [T: "kaksinkertainen on yhtä suuri kuin ja alapuolella pienempi kuin"] # 0xe909 (en: 'equal double over less than', google translation) - - "": [T: "sisältää tai on yhtä suuri kuin"] # 0xe90a (en: 'contains or equal to', google translation) - - "": [T: "ylijoukko tai yhtä suuri kuin"] # 0xe90b (en: 'superset of or equal to', google translation) - - "": [T: "osajoukko tai yhtä suuri kuin"] # 0xe90c (en: 'subset of or equal to', google translation) - - "": [T: "on yhtä suuri kuin ja alapuolella pienempi kuin"] # 0xe90d (en: 'equal over less than', google translation) - - "": [T: "kuuluu joukkoon tai on yhtä kuin"] # 0xe912 (en: 'element of or equal to', google translation) - - "": [T: "yhtä suuri tai suurempi kuin"] # 0xe913 (en: 'equal to or greater than', google translation) - - "": [T: "likimäärin ylijoukko"] # 0xe914 (en: 'approximate superset of', google translation) - - "": [T: "likimäärin osajoukko"] # 0xe915 (en: 'approximate subset of', google translation) - - "": [T: "ylijoukko pisteellä sisältää alirelaationa"] # 0xe916 (en: 'superset of with dot includes as sub relation', google translation) # FI: translation unclear - - "": [T: "osajoukko pisteellä sisältyy alirelaationa"] # 0xe917 (en: 'subset of with dot is included in as sub relation', google translation) # FI: translation unclear - - "": [T: "on yhtä suuri kuin ja piste alapuolella"] # 0xe918 (en: 'equal with dot below', google translation) - - "": [T: "vasen piste jonka alapuolella miinus jonka alapuolella oikea piste"] # 0xe919 (en: 'left dot over minus over right dot', google translation) - - "": [T: "oikea piste jonka alapuolella miinus jonka alapuolella vasen piste"] # 0xe91a (en: 'right dot over minus over left dot', google translation) - - "": [T: "melkein yhtä suuri kuin miinus"] # 0xe91f (en: 'almost equal to minus', google translation) - - "": [T: "kaksinkertainen kulmikas malja"] # 0xe920 (en: 'double square cup', google translation) - - "": [T: "kaksinkertainen kulmikas kupu"] # 0xe921 (en: 'double square cap', google translation) - - "": [T: "pienempi kuin, yhtä suuri kuin tai suurempi kuin"] # 0xe922 (en: 'less than equal to or greater than', google translation) - - "": [T: "tilde pisteellä"] # 0xe924 (en: 'tilde with dot', google translation) - - "": [T: "tilde kahdella pisteellä"] # 0xe925 (en: 'tilde with two dots', google translation) - - "": [T: "pienempi kuin, suurempi kuin tai yhtä suuri kuin"] # 0xe926 (en: 'less than greater than or equal to', google translation) - - "": [T: "suurempi kuin, pienempi kuin tai yhtä suuri kuin"] # 0xe927 (en: 'greater than less than or equal to', google translation) - - "": [T: "vastaa tai on pienempi kuin"] # 0xe928 (en: 'equivalent to or less than', google translation) - - "": [T: "vastaa tai on suurempi kuin"] # 0xe929 (en: 'equivalent to or greater than', google translation) - - "": [T: "vasen avoin laatikkooperaattori"] # 0xe92a (en: 'left open box operator', google translation) - - "": [T: "oikea avoin laatikkooperaattori"] # 0xe92b (en: 'right open box operator', google translation) - - "": [T: "identtinen pisteellä"] # 0xe92c (en: 'identical to with dot', google translation) - - "": [T: "suurempi kuin, yhtä suuri kuin tai pienempi kuin"] # 0xe92d (en: 'greater than equal to or less than', google translation) - - "": [T: "palkkioperaattori"] # 0xe92e (en: 'bar operator', google translation) - - "": [T: "kaksinkertainen palkkioperaattori"] # 0xe92f (en: 'double bar operator', google translation) - - "": [T: "kolminkertainen palkkioperaattori"] # 0xe930 (en: 'triple bar operator', google translation) - - "": [T: "pienempi kuin tai likimäärin yhtä suuri kuin"] # 0xe932 (en: 'less than or approximately equal to', google translation) - - "": [T: "suuremmpi kuin tai likimäärin yhtä suuri kuin"] # 0xe933 (en: 'greater than or approximately equal to', google translation) - - "": [T: "sisäkkäinen vähemmän kuin"] # 0xe936 (en: 'nested less than', google translation) - - "": [T: "sisäkkäinen suurempi kuin"] # 0xe937 (en: 'nested greater than', google translation) - - "": [T: "edeltää tai vastaa"] # 0xe93a (en: 'precedes or equivalent to', google translation) - - "": [T: "seuraa tai vastaa"] # 0xe93b (en: 'succeeds or equivalent to', google translation) - - "": [T: "edeltää ja alapuolella on yhtä suuri kuin"] # 0xe940 (en: 'precedes over equal', google translation) - - "": [T: "seuraa ja alapuolella on yhtä suuri kuin"] # 0xe941 (en: 'succeeds over equal', google translation) - - "": [T: "vähemmän kuin, on yhtä suuri kuin, vino suurempi kuin"] # 0xe942 (en: 'less equal slanted greater', google translation) # FI: translation unclear - - "": [T: "suurempi kuin, on yhtä suuri kuin, vino pienempi kuin"] # 0xe943 (en: 'greater equal slanted less', google translation) - - "": [T: "täyttää ehdon"] # 0xe948 (en: 'satisfied by', google translation) # FI: translation unclear - - "": [T: "laiska s"] # 0xe949 (en: 'lazy s', google translation) - - "": [T: "ei väite"] # 0xe94a (en: 'not assertion', google translation) # FI: translation unclear - - "": [T: "kaksinkertainen on yhtä suuri kuin"] # 0xe94b (en: 'double equal', google translation) - - "": [T: "kolminkertainen on yhtä suuri kuin"] # 0xe94c (en: 'triple equal', google translation) - - "": [T: "sääntö viivästynyt"] # 0xe94d (en: 'rule delayed', google translation) # FI: translation unclear - - "": [T: "alias delimiter"] # 0xe94e (google translation) # FI: translation unclear - - "": [T: "normaali alaryhmä palkilla"] # 0xe950 (en: 'normal subgroup of with bar', google translation) - - "": [T: "sisältää normaalina alaryhmänä palkilla"] # 0xe951 (en: 'contains as normal subgroup with bar', google translation) - - "": [T: "pyöreä seuraa"] # 0xe954 (en: 'round implies', google translation) # FI: translation unclear - - "": [T: "hymy palkin alla"] # 0xe955 (en: 'smile under bar', google translation) # FI: translation unclear - - "": [T: "murjotus palkin alla"] # 0xe956 (en: 'frown over bar', google translation) # FI: translation unclear - - "": [T: "ylijoukko tai lähes yhtä kuin"] # 0xe957 (en: 'superset of or almost equal to', google translation) - - "": [T: "osajoukko tai lähes yhtä kuin"] # 0xe958 (en: 'subset of or almost equal to', google translation) - - "": [T: "suurempi kuin melkein yhtä suuri kuin tai pienempi kuin"] # 0xe959 (en: 'greater than almost equal to or less than', google translation) - - "": [T: "pienempi kuin melkein yhtä suuri kuin tai suurempi kuin"] # 0xe95a (en: 'less than almost equal or greater than', google translation) - - "": [T: "kaksinkertainen looginen tai"] # 0xe95c (en: 'double logical or', google translation) - - "": [T: "kaksinkertainen looginen ja"] # 0xe95d (en: 'double logical and', google translation) - - "": [T: "looginen tai ja kaksinkertainen palkki alapuolella"] # 0xe95e (en: 'logical or with double bar below', google translation) - - "": [T: "looginen tai ja palkki alapuolella"] # 0xe95f (en: 'logical or with bar below', google translation) - - "": [T: "melkein yhtä suuri kuin ja alapuolella yhtä suuri kuin"] # 0xe962 (en: 'almost equal over equal', google translation) - - "": [T: "vasemmalle osoittava kolmio kahtiajakavalla palkilla"] # 0xe964 (en: 'left pointing triangle with bisecting bar', google translation) - - "": [T: "oikealle osoittava kolmio kahtiajakavalla palkilla"] # 0xe965 (en: 'right pointing triangle with bisecting bar', google translation) - - "": [T: "on yhtä suuri kuin katkoviivoitetulla yläviivalla"] # 0xe966 (en: 'equals with dotted top line', google translation) - - "": [T: "edeltää kaksoispisteellä"] # 0xe967 (en: 'precedes with colon', google translation) - - "": [T: "seuraa kaksoispisteellä"] # 0xe968 (en: 'succeeds with colon', google translation) - - "": [T: "pienempi tai yhtä suuri kuin vino"] # 0xe969 (en: 'smaller than or equal slanted', google translation) # FI: : translation unclear - - "": [T: "suurempi kuin tai yhtä suuri kuin vino"] # 0xe96a (en: 'larger than or equal slanted', google translation) # FI: : translation unclear - - "": [T: "sisäkkäinen paljon pienempi kuin"] # 0xe96b (en: 'nested very much less than', google translation) - - "": [T: "sisäkkäinen paljon suurempi kuin"] # 0xe96c (en: 'nested very much greater than', google translation) - - "": [T: "ero variantin välillä"] # 0xe96d (en: 'difference between variant', google translation) # FI: unclear translation - - "": [T: "pienempi kuin jonka päällä suurempi kuin"] # 0xe96e (en: 'less than greater than overlay', google translation) - - "": [T: "looginen tai jonka päällä looginen tai"] # 0xe96f (en: 'logical or logical and overlay', google translation) - - "": [T: "ylijoukko ylijoukon yläpuolella"] # 0xe970 (en: 'superset over superset', google translation) - - "": [T: "osajoukko osajoukon yläpuolella"] # 0xe971 (en: 'subset over subset', google translation) - - "": [T: "ylijoukko osajoukon yläpuolella"] # 0xe972 (en: 'superset over subset', google translation) - - "": [T: "osajoukko ylijoukon yläpuolella"] # 0xe973 (en: 'subset over superset', google translation) - - "": [T: "kolminkertainen pystysuora palkki"] # 0xe979 (en: 'triple vertical bar', google translation) - - "": [T: "nelinkertainen pystysuora pistepari"] # 0xe97a (en: 'paired quadruple vertical dots', google translation) # FI: translation unclear - - "": [T: "kohtisuorassa ja alapuolella palkki"] # 0xe97b (en: 'perpendicular over bar', google translation) - - "": [T: "vasen kääntöportti kaksinkertainen pystysuora palkki"] # 0xe97c (en: 'left turnstile double vertical bar', google translation) - - "": [T: "kaksinkertainen vasen kääntöportti kaksinkertainen pystysuora palkki"] # 0xe97d (en: 'double left turnstile double vertical bar', google translation) - - "": [T: "kohtisuorassa jonka alapuolella käännetty kohtisuorassa"] # 0xe97e (en: 'perpendicular over inverted perpendicular', google translation) - - "": [T: "kaksinkertgainen vasen kääntöportti pystysuora palkki"] # 0xe97f (en: 'double left turnstile vertical bar', google translation) - - "": [T: "pallomainen kulma avautuu"] # 0xe980 (en: 'spherical angle opening up', google translation) - - "": [T: "kaksinkertainen vinoviiva"] # 0xe981 (en: 'double slash', google translation) - - "": [T: "suora kulma nurkalla"] # 0xe982 (en: 'right angle with corner', google translation) - - "": [T: "ympyröity pystysuora palkki"] # 0xe984 (en: 'circled vertical bar', google translation) - - "": [T: "ympyröity jakomerkki"] # 0xe985 (en: 'circled division sign', google translation) - - "": [T: "katkoviivoitettu vinoviiva"] # 0xe986 (en: 'dashed solidus', google translation) - - "": [T: "katkoviivoitettu kenoviiva"] # 0xe987 (en: 'dashed backslash', google translation) - - "": [T: "katkoviivoitettu puoliväliviiva"] # 0xe988 (en: 'dashed mid line', google translation) # FI: : translation unclear - - "": [T: "katkoviivoitettu pystysuora palkki"] # 0xe989 (en: 'dashed vertical bar', google translation) - - "": [T: "kohtisuorassa ja s"] # 0xe98a (en: 'perpendicular with s', google translation) - - "": [T: "kulma ja s"] # 0xe98b (en: 'angle with s', google translation) - - "": [T: "pallomainen kulma avautuu vasemmalle"] # 0xe98c (en: 'spherical angle opening left', google translation) - - "": [T: "vasemmalle avautuva kulma"] # 0xe98d (en: 'angle opening left', google translation) - - "": [T: "pystysuora palkki kaksoiskoukulla"] # 0xe98e (en: 'vertical bar with double hook', google translation) - - "": [T: "keskikokoinen pisteoperaattori vapaa radikaali"] # 0xe98f (en: 'medium dot operator free radical', google translation) - - "": [T: "valkoinen ylöspäin osoittava kolmio palkin yläpuolella"] # 0xe990 (en: 'white up pointing triangle above bar', google translation) - - "": [T: "identtinen ja yhdensuuntainen"] # 0xe991 (en: 'identical and parallel to', google translation) - - "": [T: "smash tulo"] # 0xe992 (en: 'smash product', google translation) # FI: meaning unclear - - "": [T: "kolminkertainen palkkioperaattori vaakasuoralla palkilla"] # 0xe993 (en: 'triple bar operator with horizontal bar', google translation) - - "": [T: "identtinen kaksoisvinoviivalla"] # 0xe994 (en: 'identical to with double slash', google translation) - - "": [T: "kolminkertaiset yliviivatut palkit"] # 0xe995 (en: 'triple crossed bars', google translation) # FI: : translation unclear - - "": [T: "pystysuora palkki ympyrän yläpuolella"] # 0xe996 (en: 'vertical bar over circle', google translation) - - "": [T: "pystysuora verrannollinen"] # 0xe997 (en: 'vertical proportional to', google translation) - - "": [T: "musta kuun viimeinen neljännes"] # 0xe998 (en: 'black last quarter moon', google translation) - - "": [T: "musta kuun ensimmäinen neljännes"] # 0xe999 (en: 'black first quarter moon', google translation) - - "": [T: "negatiivinen siniaalto"] # 0xe9a0 (en: 'negative sine wave', google translation) - - "": [T: "piste sulkujen sisällä"] # 0xe9a1 (en: 'parenthesized dot', google translation) - - "": [T: "sulku"] # 0xe9a2 (en: 'parens', google translation) # FI: translation unclear, "parenthesis"? - - "": [T: "valkoinen hymy"] # 0xe9a3 (en: 'white smile', google translation) - - "": [T: "valkoinen murjotus"] # 0xe9a4 (en: 'white frown', google translation) - - "": [T: "kuusikulmio"] # 0xe9a5 (en: 'hexagon', google translation) - - "": [T: "vastaa ja alapuolella plus"] # 0xe9a6 (en: 'equivalent to over plus', google translation) - - "": [T: "plus ja alapuolella vastaa"] # 0xe9a7 (en: 'plus over equivalent to', google translation) - - "": [T: "leikkaus serifillä"] # 0xe9b0 (en: 'intersection serifs', google translation) - - "": [T: "unioni serifillä"] # 0xe9b1 (google translation) - - "": [T: "neliömäinen leikkaus serifillä"] # 0xe9b2 (en: 'square intersection serifs', google translation) - - "": [T: "neliömäinen unioni serifillä"] # 0xe9b3 (google translation) - - "": [T: "edeltää, on yhtä kuin tai seuraa"] # 0xe9e0 (en: 'precedes equivalent to or succeeds', google translation) - - "": [T: "seuraa, on yhtä kuin tai edeltää"] # 0xe9e1 (en: 'succeeds equivalent to or precedes', google translation) - - "": [T: "edeltää, on lähes yhtä kuin tai seuraa"] # 0xe9e2 (en: 'precedes almost equal to or succeeds', google translation) - - "": [T: "seuraa, on lähes yhtä kuin tai edeltää"] # 0xe9e3 (en: 'succeeds almost equal to or precedes', google translation) - - "": [T: "vähemmän kuin, vastaa tai suurempi kuin"] # 0xe9f0 (en: 'less than equivalent to or greater than', google translation) - - "": [T: "suurempi kuin, vastaa tai vähemmän kuin"] # 0xe9f1 (en: 'greater than equivalent to or less than', google translation) - - "": [T: "ei hyvin paljon pienempi kuin"] # 0xea00 (en: 'not vert much less than', google translation) # FI: translation unclear, not sure if vert is very or vertical - - "": [T: "ei hyvin paljon suurempi kuin"] # 0xea01 (en: 'not vert much greater than', google translation) # FI: translation unclear, not sure if vert is very or vertical - - "": [T: "ei paljon pienempi kuin variantti"] # 0xea02 (en: 'not much less than variant', google translation) # FI: translation unclear - - "": [T: "ei paljon suurempi kuin variantti"] # 0xea03 (en: 'not much greater than variant', google translation) # FI: translation unclear - - "": [T: "pienempi kuin mutta ei yhtä suuri kuin"] # 0xea04 (en: 'less vert not double equals', google translation) # FI: translation unclear - - "": [T: "suurempi kuin mutta ei yhtä suuri kuin"] # 0xea05 (en: 'gt vert not double equals', google translation) # FI: translation unclear - - "": [T: "ei pienempi tai yhtä suuri kuin"] # 0xea06 (en: 'not less than or equal to', google translation) - - "": [T: "ei suurempi tai yhtä suuri kuin"] # 0xea07 (en: 'not greater than or equal to', google translation) - - "": [T: "ei yhtä suuri kuin eikä pienempi kuin"] # 0xea09 (en: 'neither equal to nor less than', google translation) - - "": [T: "ei sisällä tai ole yhtä suuri kuin"] # 0xea0a (en: 'does not contain or equal to', google translation) - - "": [T: "ei ylijoukko tai yhtä suuri kuin"] # 0xea0b (en: 'neither superset of nor equal to', google translation) - - "": [T: "ei osajoukko tai yhtä suuri kuin"] # 0xea0c (en: 'neither subset of nor equal to', google translation) - - "": [T: "kenoviiva osajoukko"] # 0xea0d (en: 'reverse solidus subset', google translation) - - "": [T: "ei yhtä suuri tai suurempi kuin"] # 0xea0e (en: 'neither equal to nor greater than', google translation) - - "": [T: "ei miinus tilde -operaattori"] # 0xea0f (en: 'not minus tilde operator', google translation) - - "": [T: "ei yhtä suuri kuin tai pienempi kuin"] # 0xea10 (en: 'neither equal to nor less than', google translation) - - "": [T: "ei tilde -operaattori"] # 0xea11 (en: 'not tilde operator', google translation) - - "": [T: "ei kuulu joukkoon tai ole yhtä suuri kuin"] # 0xea12 (en: 'not element of or equal to', google translation) - - "": [T: "ei yhtä suuri kuin tai suurempi kuin"] # 0xea13 (en: 'neither equal to nor greater than', google translation) - - "": [T: "ei melkein yhtä suuri"] # 0xea14 (en: 'not almost equal', google translation) - - "": [T: "ei seuraa vastaavaa"] # 0xea15 (en: 'not succeeds similar', google translation) # FI: translation unclear - - "": [T: "pienempi kuin tai vino yhtä suuri kuin vinoviivalla"] # 0xea16 (en: 'less than or slanted equal to with slash', google translation) - - "": [T: "suurempi kuin tai vino yhtä suuri kuin vinoviivalla"] # 0xea17 (en: 'greater than or slanted equal to with slash', google translation) - - "": [T: "ylijoukko vinoviiva"] # 0xea1a (google translation) - - "": [T: "ei sisällä"] # 0xea1b (en: 'does not contain', google translation) - - "": [T: "ei pienempi kuin tai yhtä suuri kuin"] # 0xea1d (en: 'not less than or equal to', google translation) - - "": [T: "ei suurempi kuin tai yhtä suuri kuin"] # 0xea1e (en: 'not greater than or equal to', google translation) - - "": [T: "ei melkein yhtä suuri kuin miinus"] # 0xea1f (en: 'not almost equal to minus', google translation) - - "": [T: "ei kuulu joukkoon yläpisteellä"] # 0xea22 (en: 'negated set membership dot above', google translation) - - "": [T: "ei vert kulma"] # 0xea2c (en: 'not vert angle', google translation) # FI: translation unclear - - "": [T: "ei yhdensuuntainen vino"] # 0xea2d (en: 'not parallel slanted', google translation) - - "": [T: "ei palkkioperaattori"] # 0xea2e (en: 'not bar operator', google translation) - - "": [T: "ei kaksoispalkkioperaattori"] # 0xea2f (en: 'not double bar operator', google translation) - - "": [T: "ei kolminkertainen palkkioperaattori"] # 0xea30 (en: 'not triple bar operator', google translation) - - "": [T: "vähemmän kuin, mutta ei suunnilleen yhtä suuri kuin"] # 0xea32 (en: 'less than but not approximately equal to', google translation) - - "": [T: "suurempi kuin, mutta ei suunnilleen yhtä suuri kuin"] # 0xea33 (en: 'greater than but not approximately equal to', google translation) - - "": [T: "vähemmän kuin tai ei yhtä suuri kuin"] # 0xea34 (en: 'less than or not equal to', google translation) - - "": [T: "suurempi kuin tai ei yhtä suuri kuin"] # 0xea35 (en: 'greater than or not equal to', google translation) - - "": [T: "ei sisäkkäinen vähemmän kuin"] # 0xea36 (en: 'not nested less than', google translation) # FI: translation unclear - - "": [T: "ei sisäkkäinen suurempi kuin"] # 0xea37 (en: 'not nested greater than', google translation) # FI: translation unclear - - "": [T: "ei paljon pienempi kuin"] # 0xea38 (en: 'not much less than', google translation) - - "": [T: "ei paljon suurempi kuin"] # 0xea39 (en: 'not much greater than', google translation) - - "": [T: "edeltää, mutta ei vastaa"] # 0xea3a (en: 'precedes but not equivalent to', google translation) - - "": [T: "onnistuu, mutta ei vastaa"] # 0xea3b (en: 'succeeds but not equivalent to', google translation) - - "": [T: "edeltää, mutta ei yhtä suuri kuin"] # 0xea3c (en: 'precedes but not equal to', google translation) - - "": [T: "seuraa, mutta ei yhtä suuri kuin"] # 0xea3d (en: 'succeeds but not equal to', google translation) - - "": [T: "ei ole yhtä suuri kuin tai edeltää"] # 0xea3e (en: 'does not equal or precede', google translation) - - "": [T: "ei ole yhtä suuri kuin tai seuraa"] # 0xea3f (en: 'does not equal or succeed', google translation) - - "": [T: "edeltää, mutta ei yhtä suuri kuin"] # 0xea40 (en: 'precedes but not equal to', google translation) - - "": [T: "seuraa, mutta ei yhtä suuri kuin"] # 0xea41 (en: 'succeeds but not equal to', google translation) - - "": [T: "ei osajoukko tai yhtä suuri kuin"] # 0xea42 (en: 'not subset of nor equal to', google translation) - - "": [T: "ei ylijoukko tai yhtä suuri kuin"] # 0xea43 (en: 'not superset of nor equal to', google translation) - - "": [T: "osajoukko tai ei yhtä suuri kuin"] # 0xea44 (en: 'subset of or not equal to', google translation) - - "": [T: "ylijoukko tai ei yhtä suuri kuin"] # 0xea45 (en: 'superset of or not equal to', google translation) - - "": [T: "ei osajoukko tai yhtä suuri kuin"] # 0xea46 (en: 'not subset of nor equal to', google translation) - - "": [T: "ei ylijoukko tai yhtä suuri kuin"] # 0xea47 (en: 'not superset of nor equal to', google translation) - - "": [T: "ei kolminkertainen pienempi kuin"] # 0xea48 (en: 'not triple less than', google translation) - - "": [T: "ei kolminkertainen suurempi kuin"] # 0xea49 (en: 'not triple greater than', google translation) - - "": [T: "ei edellä on yhtä suuri kuin"] # 0xea4c (en: 'not precedes equals', google translation) - - "": [T: "ei seuraa on yhtä suuri kuin"] # 0xea4d (en: 'not succeeds equals', google translation) - - "": [T: "ei normaali aliryhmä palkilla"] # 0xea50 (en: 'not normal subgroup of with bar', google translation) - - "": [T: "ei sisällä normaalina aliryhmänä palkilla"] # 0xea51 (en: 'does not contain as normal subgroup with bar', google translation) - - "": [T: "ei ero välillä"] # 0xea52 (en: 'not difference between', google translation) - - "": [T: "ei geometrisesti vastaa"] # 0xea53 (en: 'not geometrically equivalent to', google translation) - - "": [T: "ei vert samanlainen"] # 0xea54 (en: 'not vert similar', google translation) # FI: translation unclear - - "": [T: "ei yhtä suuri tai samanlainen"] # 0xea55 (en: 'not equal or similar', google translation) - - "": [T: "ei vert likimääräinen"] # 0xea56 (en: 'not vert approximate', google translation) - - "": [T: "ei likimääräisesti identtinen"] # 0xea57 (en: 'not approximately identical to', google translation) - - "": [T: "ei kumpu yhtä suuri kuin"] # 0xea58 (en: 'not bumpy equals', google translation) # FI: translation unclear - - "": [T: "ei kumpu yksiviivainen yhtä suuri kuin"] # 0xea59 (en: 'not bumpy single equals', google translation) # FI: translation unclear - - "": [T: "ei yhtä suuri kuin piste"] # 0xea5a (en: 'not equal dot', google translation) - - "": [T: "käännetty ei vastaa"] # 0xea5b (en: 'reverse not equivalent', google translation) - - "": [T: "ei neliömäinen osajoukko"] # 0xea60 (en: 'not square subset', google translation) - - "": [T: "ei nelimäinen ylijoukko"] # 0xea61 (en: 'not square superset', google translation) - - "": [T: "ei melkein yhtä suuri ja alapuolella yhtä suuri kuin"] # 0xea62 (en: 'not almost equal over equal', google translation) - - "": [T: "ei tiukasti vastaa"] # 0xea63 (en: 'not strictly equivalent to', google translation) - - "": [T: "ei kongruentti piste"] # 0xea64 (en: 'not congruent dot', google translation) - - "": [T: "käännetty ei ole yhtä suuri kuin"] # 0xea65 (en: 'reverse not equal', google translation) - - "": [T: "ei vasen kolmio on yhtä suuri kuin"] # 0xea70 (en: 'not vert left triangle equals', google translation) # FI: translation unclear - - "": [T: "ei oikea on yhtä suuri kuin"] # 0xea71 (en: 'not vert right triangle equals', google translation) # FI: translation unclear - - "": [T: "ei osittainen"] # 0xea80 (en: 'not partial', google translation) - - "": [T: "nuolen koristeiden pidennys"] # 0xeb00 (en: 'arrow embellishment extender', google translation) # FI: translation unclear - - "": [T: "oikea nuoli vasemman nuolen yläpuolella"] # 0xeb01 (en: 'arrow rightwards over arrow leftwards', google translation) - - "": [T: "oikea nuoli vasemman nuolen yläpuolella"] # 0xeb02 (en: 'arrow rightwards over arrow leftwards', google translation) - - "": [T: "oikea harppuuna vasemman harppuunan yläpuolella"] # 0xeb03 (en: 'harpoon right over harpoon left', google translation) - - "": [T: "oikea harppuuna vasemman harppuunan yläpuolella"] # 0xeb04 (en: 'harpoon right over harpoon left', google translation) - - "": [T: "koillis-lounaskaksoisnuoli"] # 0xeb05 (en: 'double arrow northeast southwest', google translation) - - "": [T: "luoteis-kaakkoiskaksoisnuoli"] # 0xeb06 (en: 'double arrow northwest southeast', google translation) - - "": [T: "vaakasuora harppuunapidennys"] # 0xeb07 (en: 'horizontal harpoon extender', google translation) # FI: translation unclear - - "": [T: "vasen kaarinuoli vastapäivään"] # 0xeb08 (en: 'anticlockwise arc leftwards arrow', google translation) - - "": [T: "oikea kaarinuoli vastapäivään"] # 0xeb09 (en: 'anticlockwise arc rightwards arrow', google translation) - - "": [T: "suuri oikean nuolen aksentti"] # 0xeb0b (en: 'large rightwards arrow accent', google translation) # FI: translation unclear - - "": [T: "suuri vasen nuolen aksentti"] # 0xeb0c (en: 'large leftwards arrow accent', google translation) # FI: translation unclear - - "": [T: "vasen nuolenpää"] # 0xeb0d (en: 'leftwards arrowhead', google translation) - - "": [T: "oikea nuolenpää"] # 0xeb0e (en: 'rightwards arrowhead', google translation) - - "": [T: "suuri vasen-oikea nuoli yliviivauksella"] # 0xeb0f (en: 'large left right arrow with stroke', google translation) - - "": [T: "vaakasuuntainen kaksoisnuolen pidennys"] # 0xeb10 (en: 'horizontal double arrow extender', google translation) # FI: translation unclear - - "": [T: "suuri vasen-oikea kaksinkertainen nuoli yliviivauksella"] # 0xeb11 (en: 'large left right double arrow with stroke', google translation) - - "": [T: "alaspäin osoittava nuoli ylöspäin osoittavan nuolen vasemmalla puolella"] # 0xeb12 (en: 'downwards arrow leftwards of upwards arrow', google translation) - - "": [T: "vasen nuoli kulmalla alaspäin"] # 0xeb13 (en: 'leftwards arrow with corner downwards', google translation) - - "": [T: "oikea nuoli kulmalla ylöspäin"] # 0xeb14 (en: 'rightwards arrow with corner upwards', google translation) - - "": [T: "vasen nuoli kuolmalla ylöspäin"] # 0xeb15 (en: 'leftwards arrow with corner upwards', google translation) - - "": [T: "ympyränuolen yläosa vastapäivään ja plus"] # 0xeb16 (en: 'anticlockwise top semicircle arrow with plus', google translation) - - "": [T: "ympyränuolen yläosa myötäpäivään ja miinus"] # 0xeb17 (en: 'clockwise top semicircle arrow with minus', google translation) - - "": [T: "oikea nuoli hännällä ja yliviivauksella"] # 0xeb18 (en: 'rightwards arrow with tail with stroke', google translation) - - "": [T: "oikea harppuuna alas"] # 0xeb19 (en: 'right harpoon down', google translation) - - "": [T: "vasen harppuon alas"] # 0xeb1a (en: 'left harpoon down', google translation) - - "": [T: "vasen-oikea harppuuna alas"] # 0xeb1b (en: 'left right harpoon down', google translation) - - "": [T: "vasen-oikea harppuuna ylös"] # 0xeb1c (en: 'left right harpoon up', google translation) - - "": [T: "ylös-alas harppuuna vasemmalle"] # 0xeb1d (en: 'up down harpoon left', google translation) - - "": [T: "ylös-alas harppuuna oikealle"] # 0xeb1e (en: 'up down harpoon right', google translation) - - "": [T: "ylänuoli alanuolen vasemmalla puolella"] # 0xeb1f (en: 'upwards arrow to the right of downwards arrow', google translation) - - "": [T: "vasen harppuuna palkkiin piikki ylöpäin"] # 0xeb20 (en: 'leftwards harpoon to bar with barb upwards', google translation) - - "": [T: "oikea harppuuna palkkiin piikki ylöspäin"] # 0xeb21 (en: 'rightwards harpoon to bar with barb upwards', google translation) - - "": [T: "vasen harppuuna palkkiin piikki alaspäin"] # 0xeb22 (en: 'leftwards harpoon to bar with barb downwards', google translation) - - "": [T: "oikea harppuuna palkkiin piikki alaspäin"] # 0xeb23 (en: 'rightwards harpoon to bar with barb downwards', google translation) - - "": [T: "vasen harppuuna palkista piikki ylöspäin"] # 0xeb24 (en: 'leftwards harpoon from bar with barb upwards', google translation) - - "": [T: "oikea harppuuna palkista piikki ylöspäin"] # 0xeb25 (en: 'rightwards harpoon from bar with barb upwards', google translation) - - "": [T: "vasen harppuuna palkista piikki alaspäin"] # 0xeb26 (en: 'leftwards harpoon from bar with barb downwards', google translation) - - "": [T: "oikea harppuuna palkista piikki alaspäin"] # 0xeb27 (en: 'rightwards harpoon from bar with barb downwards', google translation) - - "": [T: "harppuuna ylös palkkiin piikki vasemmalle"] # 0xeb28 (en: 'upwards harpoon to bar with barb leftwards', google translation) - - "": [T: "harppuuna alas palkkiin piikki vasemmalle"] # 0xeb29 (en: 'downwards harpoon to bar with barb leftwards', google translation) - - "": [T: "harppuuna ylös palkkiin piikki oikealle"] # 0xeb2a (en: 'upwards harpoon to bar with barb rightwards', google translation) - - "": [T: "harppuuna alas palkkiin piikki oikealle"] # 0xeb2b (en: 'downwards harpoon to bar with barb rightwards', google translation) - - "": [T: "harppuuna ylös palkista piikki vasemmalle"] # 0xeb2c (en: 'upwards harpoon from bar with barb leftwards', google translation) - - "": [T: "harppuuna alas palkista piikki vasemmalle"] # 0xeb2d (en: 'downwards harpoon from bar with barb leftwards', google translation) - - "": [T: "harppuuna ylös palkista piikki oikealle"] # 0xeb2e (en: 'upwards harpoon from bar with barb rightwards', google translation) - - "": [T: "harppuuna alas palkista piikki oikealle"] # 0xeb2f (en: 'downwards harpoon from bar with barb rightwards', google translation) - - "": [T: "nuoli ylöspäin palkkiin"] # 0xeb30 (en: 'upwards arrow to bar', google translation) - - "": [T: "nuoli alaspäin palkkiin"] # 0xeb31 (en: 'downwards arrow to bar', google translation) - - "": [T: "harppuuna ylös ja oikealla puolella harppuuna alas"] # 0xeb32 (en: 'upwards harpoon to the left of downwards harpoon', google translation) - - "": [T: "harppuuna ylös ja vasemmalla puolella harppuuna alas"] # 0xeb33 (en: 'upwards harpoon to the right of downwards harpoon', google translation) - - "": [T: "nuolenpää ylös"] # 0xeb34 (en: 'upwards arrowhead', google translation) - - "": [T: "nuolenpää alas"] # 0xeb35 (en: 'downwards arrowhead', google translation) - - "": [T: "kaksinkertainen harppuuna vasen piikki alas ja oikea piikki ylös"] # 0xeb36 (en: 'double harpoon with leftwards barb down rightwards barb up', google translation) - - "": [T: "kaksinkertainen harppuuna vasen piikki ylös ja oikea piikki alas"] # 0xeb37 (en: 'double harpoon with leftwards barb up rightwards barb down', google translation) - - "": [T: "vasen nuoli palkin yläpuolella"] # 0xeb38 (en: 'leftwards arrow over bar', google translation) - - "": [T: "oikea nuoli palkin yläpuolella"] # 0xeb39 (en: 'rightwards arrow over bar', google translation) - - "": [T: "vasen nuoli palkin alapuolella"] # 0xeb3a (en: 'leftwards arrow under bar', google translation) - - "": [T: "oikea nuoli palkin alapuolella"] # 0xeb3b (en: 'rightwards arrow under bar', google translation) - - "": [T: "vasen-oikea kolmoisnuoli"] # 0xeb3c (en: 'left right triple arrow', google translation) - - "": [T: "koillis-kaakko kaksoisnuoli"] # 0xeb3f (en: 'double arrow northeast southeast', google translation) - - "": [T: "vasen puoliympyränuoli vastapäivään"] # 0xeb40 (en: 'anticlockwise left semicircle arrow', google translation) - - "": [T: "vasen puoliympyränuoli myötäpäivään"] # 0xeb41 (en: 'clockwise left semicircle arrow', google translation) - - "": [T: "vasen avoin ympyrä vasen-oikea nuoli"] # 0xeb42 (en: 'left open circle left right arrow', google translation) # FI: translation unclear - - "": [T: "oikea nuoli tilden yläpuolella"] # 0xeb44 (en: 'rightwards arrow over tilde', google translation) - - "": [T: "vasen nuoli tilden yläpuolella"] # 0xeb45 (en: 'leftwards arrow over tilde', google translation) - - "": [T: "vasen harppuuna palkin yläpuolella"] # 0xeb48 (en: 'leftwards harpoon over bar', google translation) - - "": [T: "oikea harppuuna palkin yläpuolella"] # 0xeb49 (en: 'rightwards harpoon over bar', google translation) - - "": [T: "vasen harppuuna palkin alapuolella"] # 0xeb4a (en: 'leftwards harpoon under bar', google translation) - - "": [T: "oikea harppuuna palkin alapuolella"] # 0xeb4b (en: 'rightwards harpoon under bar', google translation) - - "": [T: "raskas musta lyhyt vasen nuoli"] # 0xeb4c (en: 'squat black leftwards arrow', google translation) - - "": [T: "oikea puoliympyränuoli myötäpäivään"] # 0xeb50 (en: 'clockwise right semicircle arrow', google translation) - - "": [T: "oikea puoliympyränuoli vastapäivään"] # 0xeb51 (en: 'anticlockwise right semicircle arrow', google translation) - - "": [T: "vasen-oikea ympyrä vasen-oikea harppuuna"] # 0xeb52 (en: 'left open circle left right harpoon', google translation) # FI: translation unclear - - "": [T: "nuoli ylös pystypalkin vasemmalla puolella"] # 0xeb58 (en: 'upwards arrow leftwards of vertical bar', google translation) - - "": [T: "nuoli alas pystypalkin vasemmalla puolella"] # 0xeb59 (en: 'downwards arrow leftwards of vertical bar', google translation) - - "": [T: "nuoli ylös pystypalkin oikealla puolella"] # 0xeb5a (en: 'upwards arrow rightwards of vertical bar', google translation) - - "": [T: "nuoli alas pystypalkin oikealla puolella"] # 0xeb5b (en: 'downwards arrow rightwards of vertical bar', google translation) - - "": [T: "oikea nuoli jatketulla koukulla alas"] # 0xeb5c (en: 'rightwards arrow with extended downwards hook', google translation) - - "": [T: "vasen nuoli jatketulla koukulla"] # 0xeb5d (en: 'leftwards arrow with extended hook', google translation) - - "": [T: "vasen nuoli jatketulla koukulla alas"] # 0xeb5e (en: 'leftwards arrow with extended downwards hook', google translation) - - "": [T: "oikea nuoli jatketulla koukulla"] # 0xeb5f (en: 'rightwards arrow with extended hook', google translation) - - "": [T: "ei oikea nuoli aaltoileva"] # 0xeb60 (en: 'not right arrow wavy', google translation) # FI: translation unclear - - "": [T: "ei oikea nuoli kaareva"] # 0xeb61 (en: 'not right arrow curved', google translation) # FI: translation unclear - - "": [T: "harppuula ylös pystypalkin vasemmalla puolella"] # 0xeb68 (en: 'upwards harpoon leftwards of vertical bar', google translation) - - "": [T: "harppuuna alas pystypalkin vasemmalla puolella"] # 0xeb69 (en: 'downwards harpoon leftwards of vertical bar', google translation) - - "": [T: "harppuuna ylös pystypalkin oikealla puolella"] # 0xeb6a (en: 'upwards harpoon rightwards of vertical bar', google translation) - - "": [T: "harppuuna alas pystypalkin oikealla puolella"] # 0xeb6b (en: 'downwards harpoon rightwards of vertical bar', google translation) - - "": [T: "pystysuora kaksoisnuolen pidennys"] # 0xeb6c (en: 'vertical double arrow extender', google translation) # FI: translation unclear - - "": [T: "pystysuora harppuuna piikki vasemmalle pidennys"] # 0xeb6d (en: 'vertical harpoon with barb left extender', google translation) - - "": [T: "pystysuora harppuuna piikki oikealle pidennys"] # 0xeb6e (en: 'vertical harpoon with barb right extender', google translation) - - "": [T: "oikea harppuuna vasemman harppuunan yläpuolella oikealla"] # 0xeb6f (en: 'right harpoon over left harpoon right', google translation) # FI: translation unclear - - "": [T: "oikea harppuuna vasemman harppuunan yläpuolella vasemmalla"] # 0xeb70 (en: 'right harpoon over left harpoon left', google translation) # FI: translation unclear - - "": [T: "vasen harppuuna oikean harppuunan yläpuolella oikealla"] # 0xeb71 (en: 'left harpoon over right harpoon right', google translation) # FI: translation unclear - - "": [T: "vasen harppuuna oikean harppuunan yläpuolella vasemmalla"] # 0xeb72 (en: 'left harpoon over right harpoon left', google translation) # FI: translation unclear - - "": [T: "vasen nuoli palkista nuolenpää"] # 0xeb73 (en: 'leftwards arrow from bar arrowhead', google translation) # FI: translation unclear - - "": [T: "vasen-oikea nuoli palkista pidennys"] # 0xeb74 (en: 'leftwards rightwards arrow from bar extender', google translation) - - "": [T: "vasen nuoli palkista häntä"] # 0xeb75 (en: 'leftwards arrow from bar tail', google translation) # FI: translation unclear - - "": [T: "oikea nuoli palkista häntä"] # 0xeb76 (en: 'rightwards arrow from bar tail', google translation) # FI: translation unclear - - "": [T: "oikea nuoli palkista nuolenpää"] # 0xeb77 (en: 'rightwards arrow from bar arrowhead', google translation) # FI: translation unclear - - "": [T: "harppuuna ylös palkista piikki vasemmalle nuolenpää"] # 0xeb78 (en: 'upwards harpoon from bar with barb leftwards arrowhead', google translation) # FI: translation unclear - - "": [T: "oikea nuoli vasemman nuolen yläpuolella oikealla"] # 0xeb79 (en: 'rightwards arrow over leftwards arrow right', google translation) # FI: translation unclear - - "": [T: "oikea nuoli vasemman nuolen yläpuolella vasemmalla"] # 0xeb7a (en: 'rightwards arrow over leftwards arrow left', google translation) # FI: translation unclear - - "": [T: "vasen nuoli oikean nuolen yläpuolella oikealla"] # 0xeb7b (en: 'leftwards arrow over rightwards arrow right', google translation) # FI: translation unclear - - "": [T: "vasen nuoli oikean nuolen yläpuolella vasemmalla"] # 0xeb7c (en: 'leftwards arrow over rightwards arrow left', google translation) # FI: translation unclear - - "": [T: "nuoli ylös palkista nuolenpää"] # 0xeb7d (en: 'upwards arrow from bar arrowhead', google translation) # FI: translation unclear - - "": [T: "nuoli ylös palkista häntä"] # 0xeb7e (en: 'upwards arrow from bar tail', google translation) # FI: translation unclear - - "": [T: "nuoli alaspäin palkista häntä"] # 0xeb7f (en: 'downwards arrow from bar tail', google translation) # FI: translation unclear - - "": [T: "nuoli alaspäin palkista nuolenpää"] # 0xeb80 (en: 'downwards arrow from bar arrowhead', google translation) # FI: translation unclear - - "": [T: "harppuuna alas palkista piikki oikealle nuolenpää"] # 0xeb81 (en: 'downwards harpoon from bar with barb rightwards arrowhead', google translation) # FI: translation unclear - - "": [T: "harppuuna ylös ja oikealla puolella harppuuna alas alas"] # 0xeb82 (en: 'upwards harpoon to the left of downwards harpoon bottom', google translation) # FI: translation unclear - - "": [T: "harppuuna ylös ja oikealla harppuuna alas"] # 0xeb83 (en: 'upwards harpoon to the left of downwards harpoon', google translation) - - "": [T: "harppuuna alas ja oikealla harppuuna ylös ylös"] # 0xeb84 (en: 'downwards harpoon to the left of upwards harpoon top', google translation) # FI: translation unclear - - "": [T: "harppuuna ylös ja oikealla harppuuna alas ylös"] # 0xeb85 (en: 'upwards harpoon to the left of downwards harpoon top', google translation) # FI: translation unclear - - "": [T: "harppuuna alas ja oikealla harppuuna ylös pidennys"] # 0xeb86 (en: 'downwards harpoon to the left of the upwards harpoon extender', google translation) - - "": [T: "harppuuna alas ja oikealla harppuuna ylös alas"] # 0xeb87 (en: 'downwards harpoon to the left of the upwards harpoon bottom', google translation) # FI: translation unclear - - "": [T: "harppuuna ylös ja oikealla harppuuna alas alas"] # 0xeb88 (en: 'upwards arrow leftwards of downwards arrow bottom', google translation) # FI: translation unclear - - "": [T: "nuoli alas ja oikealla nuoli ylös ylös"] # 0xeb89 (en: 'downwards arrow leftwards of upwards arrow top', google translation) # FI: translation unclear - - "": [T: "nuoli ylös ja oikealla nuoli alas ylös"] # 0xeb8a (en: 'upwards arrow leftwards of downwards arrow top', google translation) # FI: translation unclear - - "": [T: "nuoli alas ja oikealla nuoli ylös alas"] # 0xeb8b (en: 'downwards arrow leftwards of upwards arrow bottom', google translation) # FI: translation unclear - - "": [T: "vasen-oikeanuolipidennys"] # 0xeb8c (en: 'leftwards rightwards arrows extender', google translation) - - "": [T: "koillisnuolipidennys"] # 0xeb8d (en: 'north east arrow extender', google translation) - - "": [T: "luoteisnuolipidennys"] # 0xeb8e (en: 'north west arrow extender', google translation) - - "": [T: "alas osoittava aaltosulku vasen"] # 0xec00 (en: 'down pointing brace left', google translation) - - "": [T: "alas osoittava aaltosulku keski"] # 0xec01 (en: 'down pointing brace mid', google translation) - - "": [T: "alas osoittava aaltosulku oikea"] # 0xec02 (en: 'down pointing brace right', google translation) - - "": [T: "vaakasuora aaltosulku pidennys"] # 0xec03 (en: 'horizontal brace extender', google translation) - - "": [T: "ylös osoittava aaltosulku vasen"] # 0xec04 (en: 'up pointing brace left', google translation) - - "": [T: "ylös osoittava aaltosulku keski"] # 0xec05 (en: 'up pointing brace mid', google translation) - - "": [T: "ylös osoittava aaltosulku oikea"] # 0xec06 (en: 'up-pointing brace right', google translation) - - "": [T: "vasen pystypalkki"] # 0xec07 (en: 'left vertical bar', google translation) - - "": [T: "oikea pystypalkki"] # 0xec08 (en: 'right vertical bar', google translation) - - "": [T: "vasen kaksinkertainen pystypalkki"] # 0xec09 (en: 'left double vertical bar', google translation) - - "": [T: "oikea kaksinkertainen pystypalkki"] # 0xec0a (en: 'right double vertical bar', google translation) - - "": [T: "vaakasuora hakasulku pidennys"] # 0xec0b (en: 'horizontal bracket extender', google translation) - - "": [T: "neliön alapuoli hakasulku"] # 0xec0c (en: 'under square bracket', google translation) # FI: translation unclear - - "⎵": [T: "neliön alapuoli hakasulku"] # 0x23b5 (google: 'neliön alla') # FI: translation unclear - - "": [T: "neliön yläpuoli hakasulku"] # 0xec0d (en: 'over square bracket', google translation) # FI: translation unclear - - "⎴": [T: "neliön yläpuoli hakasulku"] # 0x23b4 (google: 'neliömäisen kiinnikkeen yli') # FI: translation unclear - - "": [T: "alahakasulku vasen"] # 0xec0e (en: 'under bracket left', google translation) # FI: translation unclear - - "": [T: "alahakasulku oikea"] # 0xec0f (en: 'under bracket right', google translation) # FI: translation unclear - - "": [T: "ylähakasulku vasen"] # 0xec10 (en: 'over bracket left', google translation) # FI: translation unclear - - "": [T: "alahakasulku oikea"] # 0xec11 (en: 'over bracket right', google translation) # FI: translation unclear - - "": [T: "vasen kaarisulku 1"] # 0xec12 (en: 'left parens 1', google translation) - - "": [T: "vasen kaarisulku 2"] # 0xec13 (en: 'left parens 2', google translation) - - "": [T: "vasen kaarisulku 3"] # 0xec14 (en: 'left parens 3', google translation) - - "": [T: "vasen kaarisulku 4"] # 0xec15 (en: 'left parens 4', google translation) - - "": [T: "oikea kaarisulku 1"] # 0xec16 (en: 'right parens 1', google translation) - - "": [T: "oikea kaarisulku 2"] # 0xec17 (en: 'right parens 2', google translation) - - "": [T: "oikea kaarisulku 3"] # 0xec18 (en: 'right parens 3', google translation) - - "": [T: "oikea kaarisulku 4"] # 0xec19 (en: 'right parens 4', google translation) - - "": [T: "radikaali 1"] # 0xec1a (en: 'radical 1', google translation) # FI: context? Radical as in root sign? - - "": [T: "radikaali 2"] # 0xec1b (en: 'radical 2', google translation) # FI: context? - - "": [T: "radikaali 3"] # 0xec1c (en: 'radical 3', google translation) # FI: context? - - "": [T: "radikaali 4"] # 0xec1d (en: 'radical 4', google translation) # FI: context? - - "": [T: "radikaali 5"] # 0xec1e (en: 'radical 5', google translation) # FI: context? - - "": [T: "radikaali pohja"] # 0xec1f (en: 'radical bottom', google translation) # FI: context? - - "": [T: "radikaali pystysuora pidennys"] # 0xec20 (en: 'radical vertical extender', google translation) # FI: context? - - "": [T: "radikaali yläosa"] # 0xec21 (en: 'radical top', google translation) # FI: context? - - "": [T: "vasen valkoinen hakasulku ylös"] # 0xec22 (en: 'left white bracket top', google translation) - - "": [T: "vasen valkoinen hakasulku pidennys"] # 0xec23 (en: 'left white bracket extender', google translation) - - "": [T: "vasen valkoinen hakasulku alas"] # 0xec24 (en: 'left white bracket bottom', google translation) - - "": [T: "oikea valkoinen hakasulku ylös"] # 0xec25 (en: 'right white bracket top', google translation) - - "": [T: "oikea valkoinen hakasulku pidennys"] # 0xec26 (en: 'right white bracket extender', google translation) - - "": [T: "oikea valkoinen hakasulku alas"] # 0xec27 (en: 'right white bracket bottom', google translation) - - "": [T: "vasen valkoinen aaltosulku"] # 0xec30 (en: 'left white curly bracket', google translation) - - "": [T: "oikea valkoinen aaltosulku"] # 0xec31 (en: 'right white curly bracket', google translation) - - "": [T: "jakokulmamerkki"] # 0xec32 (en: 'long division sign', google translation) - - "": [T: "jakokulmamerkki pidennys"] # 0xec33 (en: 'long division sign extender', google translation) - - "": [T: "lyhyt jakokulma"] # 0xec34 (en: 'short division', google translation) - - "": [T: "kaksinkertainen m-sidos lounaasta koilliseen"] # 0xec40 (en: 'double southwest to northeast em bond', google translation) - - "": [T: "kaksinkertainen m-sidos luoteesta kaakkoon"] # 0xec41 (en: 'double northwest to southeast em bond', google translation) - - "": [T: "yksinkertainen vaakasuora m-sidos"] # 0xec42 (en: 'single horizontal em bond', google translation) # FI: not happy with translations - - "": [T: "kaksinkertainen vaakasuora m-sidos"] # 0xec43 (en: 'double horizontal em bond', google translation) - - "": [T: "kolminkertainen vaakasuora m-sidos"] # 0xec44 (en: 'triple horizontal em bond', google translation) - - "": [T: "yksinkertainen pystysuora m-sidos"] # 0xec45 (en: 'single vertical em bond', google translation) - - "": [T: "kaksinkertainen pystysuora m-sidos"] # 0xec46 (en: 'double vertical em bond', google translation) - - "": [T: "kolminkertainen pystysuora m-sidos"] # 0xec47 (en: 'triple vertical em bond', google translation) - - "": [T: "pienempi kuin m-sidos"] # 0xec48 (en: 'less than em bond', google translation) - - "": [T: "suurempi kuin m-sidos"] # 0xec49 (en: 'greater than em bond', google translation) - - "": [T: "yksinkertainen vaakasuora n-sidos"] # 0xec4a (en: 'single horizontal en bond', google translation) - - "": [T: "kaksinkertainen vaakasuora n-sidos"] # 0xec4b (en: 'double horizontal en bond', google translation) - - "": [T: "kolminkertainen vaakasuora n-sidos"] # 0xec4c (en: 'triple horizontal en bond', google translation) - - "": [T: "ylävasen suorakulmio"] # 0xec80 (en: 'top left rectangle', google translation) - - "": [T: "alavasen suorakulmio"] # 0xec81 (en: 'bottom left rectangle', google translation) - - "": [T: "yläoikea suorakulmio"] # 0xec90 (en: 'top right rectangle', google translation) - - "": [T: "alaoikea suorakulmio"] # 0xec91 (en: 'bottom right rectangle', google translation) - - "": [T: "synteettinen jakokulma"] # 0xec92 (en: 'synthetic division corner', google translation) # FI: translation unclear - - "": [T: "synteettinen jakokulma vaakasuora pidennys"] # 0xec93 (en: 'synthetic division horizontal extender', google translation) # FI: translation unclear - - "": [T: "synteettinen jakokulma pystysuora pidennys"] # 0xec94 (en: 'synthetic division vertical extender', google translation) # FI: translation unclear - - "": [T: "vasen katto lattia pidennys"] # 0xec95 (en: 'left ceiling floor extender', google translation) - - "": [T: "oikea katto lattia pidennys"] # 0xec96 (en: 'right ceiling floor extender', google translation) - - "": [T: "yli hakasulku pidennys"] # 0xec97 (en: 'over bracket extender', google translation) # FI: translation unclear - - "": [T: "pystypalkki pidennys"] # 0xec98 (en: 'vertical bar extender', google translation) - - "": [T: "vasen kaksinkertainen pystypalkki pidennys"] # 0xec99 (en: 'left double vertical bar extender', google translation) - - "": [T: "vaakasuora palkki pidennys"] # 0xec9a (en: 'horizontal bar extender', google translation) - - "": [T: "ala hakasulku pidennys"] # 0xec9c (en: 'under bracket extender', google translation) # FI: translation unclear - - "": [T: "alaspäin osoittava kaarisulku oikea"] # 0xec9d (en: 'down pointing paren right', google translation) - - "": [T: "alaspäin osoittava kaarisulku pidennys"] # 0xec9e (en: 'down pointing paren extender', google translation) - - "": [T: "alaspäin osoittava kaarisulku vasen"] # 0xec9f (en: 'down pointing paren left', google translation) - - "": [T: "ylöspäin osoittava hakasulku pidennys"] # 0xeca0 (en: 'up pointing brace extender', google translation) - - "": [T: "ylöspäin osoittava kaarisulku vasen"] # 0xeca1 (en: 'up pointing paren left', google translation) - - "": [T: "ylöspäin osoittava kaarisulku pidennys"] # 0xeca2 (en: 'up pointing paren extender', google translation) - - "": [T: "ylöspäin osoittava kaarisulku oikea"] # 0xeca3 (en: 'up pointing paren right', google translation) - - "": [T: "alaspäin osoittava kaarisulku pidennys"] # 0xeca4 (en: 'down pointing brace extender', google translation) - - "": [T: "planckin vakio kahden piin yläpuolella palkki"] # 0xed00 (en: 'planck constant over two pi bar', google translation) # FI: translation unclear - - "": [T: "peili g"] # 0xed01 (en: 'mirror g', google translation) - - "": [T: "pisteetön j"] # 0xed02 (google translation) - - "": [T: "digamma"] # 0xed03 (google translation) # FI: translation unclear - - "ϝ": [T: "digamma"] # 0x3dd # FI: : translation unclear - - "": [T: "d"] # 0xed10 (en: 'd', google translation) - - "": [T: "e"] # 0xed11 (en: 'e', google translation) - - "": [T: "i"] # 0xed12 (en: 'i', google translation) - - "": [T: "j"] # 0xed13 (en: 'j', google translation) - - "ⅅ": - - SPELL: "translate('.', 'ⅅ', 'DD')" # 0xed16, 0x2145 - -# The private use chars are from MathType - - "": [T: "käyräintegraalisilmukka vastapäivään"] # 0xee00 (en: 'anticlockwise contour integral loop', google translation) - - "": [T: "käyräintegraalisilmukka myötäpäivään"] # 0xee01 (en: 'clockwise contour integral loop', google translation) - - "": [T: ""] # 0xee04 - - "": [T: ""] # 0xee05 - - "": [T: ""] # 0xee06 - - "": [T: ""] # 0xee07 - - "": [T: ""] # 0xee08 - - "": [T: ""] # 0xee09 - - "": [T: ""] # 0xee0a - - "": [T: ""] # 0xee0b - - "": [T: ""] # 0xee0c - - "": [T: "yhteinen tila koriste"] # 0xee0d (en: 'joint status embellishment', google translation) # FI: translation unclear, context? - - "": [T: "yhteinen tila korite vasen"] # 0xee0e (en: 'joint status embellishment left', google translation) # FI: translation unclear, context? - - "": [T: "yhteinen tila koriste oikea"] # 0xee0f (en: 'joint status embellishment right', google translation) # FI: translation unclear, context? - - "": [T: "yhteinen tila koriste pidennys"] # 0xee10 (en: 'joint status embellishment extender', google translation) # FI: translation unclear, context? - - "": [T: "integraalisilmukka"] # 0xee11 (en: 'integral loop', google translation) - - "": [T: "kaksinkertainen integraalisilmukka"] # 0xee12 (en: 'integral loop double', google translation) - - "": [T: "kolminkertainen integraalisilmukka"] # 0xee13 (en: 'integral loop triple', google translation) - - "": [T: "laajentuva kaksinkertainen integraalisilmukka"] # 0xee15 (en: 'expanding integral loop double', google translation) - - "": [T: "laajentuva kolminkertainen integraalisilmukka"] # 0xee16 (en: 'expanding integral loop triple', google translation) - - "": [T: "asymptoottisesti yhtä suuri kuin aksentti"] # 0xee17 (en: 'asymptotically equal to accent', google translation) - - "": [T: "yhtä suuri kuin -merkki aksentti"] # 0xee18 (en: 'equal sign accent', google translation) - - "": [T: "neljäs derivaatta"] # 0xee19 (en: 'quadruple prime', google translation) # FI: 4th derivative? - - "": [T: "palkkiaksentti avoimella ympyrällä vasen"] # 0xee1a (en: 'bar accent with open circle left', google translation) # FI: translation unclear - - "": [T: "palkkiaksentti suljetulla ympyrällä vasen"] # 0xee1b (en: 'bar accent with closed circle left', google translation) # FI: translation unclear - - "": [T: "palkkiaksentti avoimella ympyrällä oikea"] # 0xee1c (en: 'bar accent with open circle right', google translation) # FI: translation unclear - - "": [T: "palkkiaksentti ja piste yläpuolella"] # 0xee1d (en: 'bar accent with over dot', google translation) # FI: translation unclear - - "": [T: "palkkiaksentti ja piste alapuolella"] # 0xee1e (en: 'bar accent with under dot', google translation) # FI: translation unclear - - "": [T: "palkkiaksentti ja kaksinkertainen piste yläpuolella"] # 0xee1f (en: 'bar accent with double over dot', google translation) # FI: translation unclear - - "": [T: "palkkiaksentti ja kaksinkertainen piste alapuolella"] # 0xee20 (en: 'bar accent with double under dot', google translation) # FI: translation unclear - - "": [T: "palkkiaksentti sirkumfleksillä"] # 0xee21 (en: 'bar accent with caret', google translation) # FI: translation unclear - - "": [T: "paksu alapalkkiaksentti"] # 0xee22 (en: 'thick under bar accent', google translation) # FI: translation unclear - - "": [T: "palkkiaksentti suljetulla ympyrällä oikea"] # 0xee23 (en: 'bar accent with closed circle right', google translation) # FI: translation unclear - - "": [T: "suuri piste yläpuolella"] # 0xee24 (en: 'large dot above', google translation) # FI: translation unclear - - "": [T: "kohdistusmerkki"] # 0xef00 (en: 'alignment mark', google translation) # FI: translation unclear - - "": [T: ""] # 0xef01 - - "​": [T: ""] # 0x200b - - "": [T: ""] # 0xef02 - - " ": [T: ""] # 0x2009 - - "": [T: ""] # 0xef03 - - " ": [T: ""] # 0x205f - - "": [T: ""] # 0xef04 - - "": [T: ""] # 0xef05 - - " ": [T: ""] # 0x2003 - - "": [T: ""] # 0xef06 - - "": [T: ""] # 0xef07 - - "": [T: ""] # 0xef08 - - "": [T: ""] # 0xef09 - - "": [T: ""] # 0xef0a - - " ": [T: ""] # 0x200a - - "": [T: ""] # 0xef22 - - "": [T: ""] # 0xef23 - - "": [T: ""] # 0xef24 - - "": [T: ""] # 0xef29 - - "": [T: "puuttuva termi"] # 0xef41 (en: 'missing term', google translation) - - "": [T: "käyräintegraalinuoli myötäväivään vasemmalla"] # 0xef80 (en: 'clockwise contour integral arrow on left', google translation) - - "": [T: "integraali neliöllä"] # 0xef81 (en: 'integral with square', google translation) - - "": [T: "integraali vinoviivalla"] # 0xef82 (en: 'integral with slash', google translation) - - "": [T: "käännetty integraali"] # 0xef83 (en: 'reversed integral', google translation) - - "": [T: "kaksinkertainen nolla yli kaksinkertaisen nollan"] # 0xef90 (en: 'double zero over double zero', google translation) - - "": [T: "nolla vinoviivalla"] # 0xef91 (en: 'zero with slash', google translation) - - # fraktur chars in math alphabetic block and also MathType private use area - # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display - - "𝔄-𝔜": # 0x1d504 - 0x1d51d ('z' version is reserved) - - T: "fraktuura" # (google translation) - - SPELL: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" - - - "-": # 0xf000 - 0xf018 - - T: "fraktuura" # (google translation) - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" - - - "𝔞-𝔷": # 0x1d51e - 0x1d537 - - T: "fraktuura" # (google translation) - - SPELL: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" - - "-": # 0xf01a - 0xf033 - - T: "fraktuura" # (google translation) - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝕬-𝖅": # 0x1D56C - 0x1D585 - - T: "fraktuura lihavoitu" # (google translation) - - SPELL: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf040 - 0xf059 - - T: "fraktuura lihavoitu" # (google translation) - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝖆-𝖟": # 0x1d586 - 0x1d59f - - T: "fraktuura lihavoitu" # (google translation) - - SPELL: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" - - "-": # 0xf05a - 0xf073 - - T: "fraktuura lihavoitu" # (google translation) - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - # double struck (blackboard bold) chars in math alphabetic block and also MathType private use area - # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display - - "𝔸-𝕐": # 0x1d504 - 0x1d51d ('z' version is reserved) - - test: - if: "$Verbosity!='Terse'" - then: [T: "kaksoisviivainen"] # (en: 'double struck', google translation) - - SPELL: "translate('.', '𝔸𝔹𝔺𝔻𝔼𝔽𝔾𝔿𝕀𝕁𝕂𝕃𝕄𝕅𝕆𝕇𝕈𝕉𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf080 - 0xf098 - - test: - if: "$Verbosity!='Terse'" - then: [T: "kaksoisviivainen"] # (en: 'double struck', google translation) - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝕒-𝕫": # 0x1d552 - 0x1d56b - - test: - if: "$Verbosity!='Terse'" - then: [T: "kaksoisviivainen"] # (en: 'double struck', google translation) - - SPELL: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" - - "-": # 0xf09a - 0xf0b3 - - test: - if: "$Verbosity!='Terse'" - then: [T: "kaksoisviivainen"] # (en: 'double struck', google translation) - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 - - test: - if: "$Verbosity!='Terse'" - then: [T: "kaksoisviivainen"] # (en: 'double struck', google translation) - - SPELL: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" - - "-": # 0xf0c0 - 0xf0c9 - - test: - if: "$Verbosity!='Terse'" - then: [T: "kaksoisviivainen"] # (en: 'double struck', google translation) - - SPELL: "translate('.', '', '0123456789')" - - - "": [T: "kaksoisviivainen nabla"] # 0xf0ca (en: 'double struck nabla', google translation) - - "": [T: "kaksoisviivainen eulerin vakio"] # 0xf0cb (en: 'double struck euler constant', google translation) - - # script chars in math alphabetic block and also MathType private use area - - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 - - T: "kauno" # (en: 'script', google translation) - - SPELL: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf100 - 0xf119 - - T: "kauno" # (en: 'script', google translation) - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf - - T: "kauno" # (en: 'script', google translation) - - SPELL: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" - - "-": # 0xf11a - 0xf133 - - T: "kauno" # (en: 'script', google translation) - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - # bold script chars in math alphabetic block and also MathType private use area - - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 - - T: "lihavoitu kauno" # (en: 'script bold', google translation) - - SPELL: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf140 - 0xf159 - - T: "lihavoitu kauno" # (en: 'script bold', google translation) - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝓪-𝔃": # 0x1d4ea - 0x1d503 - - T: "lihavoitu kauno" # (en: 'script bold', google translation) - - SPELL: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" - - "-": # 0xf15a - 0xf173 - - T: "lihavoitu kauno" # (en: 'script bold', google translation) - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf180 - 0xf199 - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "": # 0xf19a - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "iso"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [T: "ligatuuri a e"] # (google translation) - - "": # 0xf19b - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "iso"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [T: "terävä s"] # (en: 'sharp s', google translation) # FI: : translation unclear - - "": # 0xf19c - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "iso"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [T: "o yliviivauksella"] # (en: 'o with stroke', google translation) - - # MathType only has a few of the cap Greek letters in PUA - - "": # 0xf201 - 0xf209 - - test: - if: "$Verbosity!='Terse'" - then: [T: "kaksoisviivainen"] # (en: 'double struck', google translation) - - SPELL: "translate('.', '', 'ΔΨΛΠΣΘΓΩΥ')" - - - "-": # 0xf220 - 0xf236 - - test: - if: "$Verbosity!='Terse'" - then: [T: "kaksoisviivainen"] # (en: 'double struck', google translation) - - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "": [T: "kaksoisviivainen viimeinen sigma"] # 0xf237 (en: 'double struck final sigma', google translation) - - "": [T: "kaksoisviivainen rho"] # 0xf250 (en: 'double struck rho', google translation) - - "": [T: "kaksoisviivainen fii"] # 0xf251 (google translation) - - "𝐀-𝐙": # 0x1d400 - 0x1d419 - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf260 - 0xf279 - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝐚-𝐳": # 0x1d41a - 0x1d433 - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf27a - 0xf293 - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝐴-𝑍": # 0x1d434 - 0x1d44d - - SPELL: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf294 - 0xf2ad - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝑎-𝑧": # 0x1d44e - 0x1d467 - - SPELL: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf2ae - 0xf2c7 - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝑨-𝒁": # 0x1d468 - 0x1d481 - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf2c8 - 0xf2e1 - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝒂-𝒛": # 0x1d482 - 0x1d49b - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf2e2 - 0xf2fb - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 - - SPELL: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf300 - 0xf319 - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 - - SPELL: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf31a - 0xf333 - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf334 - 0xf34d - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝗮-𝘇": # 0x1d5ee - 0x1d607 - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf34e - 0xf367 - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - "𝘈-𝘡": # 0x1d608 - 0x1d621 - # - t: "italic" - - SPELL: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - "-": # 0xf368 - 0xf381 - # - t: "italic" - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝘢-𝘻": # 0x1d622 - 0x1d63b - # - t: "italic" - - SPELL: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf382 - 0xf39b - # - t: "italic" - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝘼-𝙕": # 0x1d63c - 0x1d655 - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf39c - 0xf3b5 - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝙖-𝙯": # 0x1d656 - 0x1d66f - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf3b6 - 0xf3cf - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝙰-𝚉": # 0x1d670 - 0x1d689 - - SPELL: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf3d0 - 0xf3e9 - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 - - SPELL: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf3ea - 0xf403 - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "": [T: "pisteetön i"] # 0xf404 (google translation) - - "𝚤": [T: "pisteetön i"] # 0x1d6a4 (en: 'dotless i', google: 'dotless i') - - "𝚥": [T: "pisteetön j"] # 0x1d6a5 (en: 'dotless j', google: 'dotless j') - - - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 - - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') - - SPELL: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "-": # 0xf408 - 0xf420 - - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') - - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da - - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') - - SPELL: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf422 - 0xf43a - - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') - - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "": [T: "lihavoitu nabla"] # 0xf421 (en: 'bold nabla', google translation) - - "𝛁": [T: "lihavoitu nabla"] # 0x1d6c1 (en: 'bold nabla') - - - "𝛛𝛜𝛝𝛞𝛟𝛠𝛡": # 0x1D6DB - 0x1D6E1 - - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') - - SPELL: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" - - - "": # 0xF43C - 0xF441 - - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') - - SPELL: "translate('.', '', '∂εθκφρπ')" - - - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa - # - t: "italic" - - SPELL: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "-": # 0xf442 - 0xf45a - # - t: "italic" - - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝛼-𝜔": # 0x1d6fc - 0x1d714 - # - t: "italic" - - SPELL: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓𝜔', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf45c - 0xf474 - # - t: "italic" - - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "": [T: "kursivoitu nabla"] # 0xf45b (en: 'italic nabla', google translation) - - "𝛻": [T: "lihavoitu nabla"] # 0x1d6fb (en: 'italic nabla', google: 'kursivoitu nabla') - - - "𝜕𝜖𝜗𝜘𝜙𝜚𝜛": # 0x1d715 - 0x1d71b - # - t: "italic" - - SPELL: "translate('.', '𝜕𝜖𝜗𝜘𝜙𝜚𝜛', '∂εθκφρπ')" - - - "": # 0xf475 - 0xf47b - # - t: "italic" - - SPELL: "translate('.', '', '∂εθκφρπ')" - - - "𝜜-𝜴": # 0x1d71c - 0x1d734 - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') - - SPELL: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "-": # 0xf47c - 0xf494 - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') - - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝜶-𝝎": # 0x1d736 - 0x1d74e - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') - - SPELL: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf496 - 0xf4ae - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') - - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": # 0x1d74f - 0x1d755 - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') - - SPELL: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εθκφρπ')" - - - "": # 0xf422 - 0xf43a - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') - - SPELL: "translate('.', '', '∂εθκφρπ')" - - - "𝜵": [T: "lihavoitu kursivoitu nabla"] # 0x1d735 (en: 'bold italic nabla', google: 'rohkea kursivoitu nabla') - - "": [T: "lihavoitu kursivoitu nabla"] # 0xf495 (en: 'bold italic nabla', google translation) - - - "𝝖-𝝮": # 0x1d756 - 0x1d76e - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - "-": # 0xf4b6 - 0xf4ce - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝝰-𝞈": # 0x1d770 - 0x1d788 - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇𝞈', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf4d0 - 0xf4e8 - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "𝞉𝞊𝞋𝞌𝞍𝞎𝞏": # 0x1d789 - 0x1d78f - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '𝞉𝞊𝞋𝞌𝞍𝞎𝞏', '∂εθκφρπ')" - - - "": # 0xf4e9 - 0xf4ef - - T: "lihavoitu" # (en: 'bold', google translation) - - SPELL: "translate('.', '', '∂εθκφρπ')" - - - "": [T: "lihavoitu nabla"] # 0xf4cf (en: 'bold nabla', google translation) - - "𝝯": [T: "lihavoitu nabla"] # 0x1d76f (en: 'bold nabla') - - - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') - - SPELL: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "-": # 0xf4f0 - 0xf508 - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') - - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝞪-𝟂": # 0x1d7aa - 0x1d7c2 - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') - - SPELL: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf50a - 0xf522 - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') - - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": # 0x1d7c3 - 0x1d7c9 - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') - - SPELL: "translate('.', '𝟃𝟄𝟅𝟆𝟇𝟈𝟉', '∂εθκφρπ')" - - - "": # 0xf523 - 0xf529 - # - t: "bold italic" - - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') - - SPELL: "translate('.', '', '∂εθκφρπ')" - - - "": [T: "lihavoitu nabla"] # 0xf509 (en: 'bold nabla', google translation) - - "𝞩": [T: "lihavoitu nabla"] # 0x1d7a9 (en: 'bold nabla') - - - "": [T: "lihavoitu nolla"] # 0xf52e (en: 'bold zero', google translation) - - "𝟎": [T: "lihavoitu nolla"] # 0x1d7ce (en: 'bold zero') - - "": [T: "lihavoitu yksi"] # 0xf52f (en: 'bold one', google translation) - - "𝟏": [T: "lihavoitu yksi"] # 0x1d7cf (en: 'bold one', google: 'lihavoitu') - - "": [T: "lihavoitu kaksi"] # 0xf530 (en: 'bold two', google translation) - - "𝟐": [T: "lihavoitu kaksi"] # 0x1d7d0 (en: 'bold two') - - "": [T: "lihavoitu kolme"] # 0xf531 (en: 'bold three', google translation) - - "𝟑": [T: "lihavoitu kolme"] # 0x1d7d1 (en: 'bold three') - - "": [T: "lihavoitu neljä"] # 0xf532 (en: 'bold four', google translation) - - "𝟒": [T: "lihavoitu neljä"] # 0x1d7d2 (en: 'bold four', google: 'bold neljä') - - "": [T: "lihavoitu viisi"] # 0xf533 (en: 'bold five', google translation) - - "𝟓": [T: "lihavoitu viisi"] # 0x1d7d3 (en: 'bold five') - - "": [T: "lihavoitu kuusi"] # 0xf534 (en: 'bold six', google translation) - - "𝟔": [T: "lihavoitu kuusi"] # 0x1d7d4 (en: 'bold six') - - "": [T: "lihavoitu seitsemän"] # 0xf535 (en: 'bold seven', google translation) - - "𝟕": [T: "lihavoitu seitsemän"] # 0x1d7d5 (en: 'bold seven', google: 'rohkea seitsemän') - - "": [T: "lihavoitu kahdeksan"] # 0xf536 (en: 'bold eight', google translation) - - "𝟖": [T: "lihavoitu kahdeksan"] # 0x1d7d6 (en: 'bold eight', google: 'lihavoitu') - - "": [T: "lihavoitu yhdeksän"] # 0xf537 (en: 'bold nine', google translation) - - "𝟗": [T: "lihavoitu yhdeksän"] # 0x1d7d7 (en: 'bold nine') - - "": [T: "nolla"] # 0xf542 (en: 'zero', google translation) - - "𝟢": [T: "nolla"] # 0x1d7e2 (en: 'zero') - - "": [T: "yksi"] # 0xf543 (en: 'one', google translation) - - "𝟣": [T: "yksi"] # 0x1d7e3 (en: 'one') - - "": [T: "kaksi"] # 0xf544 (en: 'two', google translation) - - "𝟤": [T: "kaksi"] # 0x1d7e4 (en: 'two') - - "": [T: "kolme"] # 0xf545 (en: 'three', google translation) - - "𝟥": [T: "kolme"] # 0x1d7e5 (en: 'three') - - "": [T: "neljä"] # 0xf546 (en: 'four', google translation) - - "𝟦": [T: "neljä"] # 0x1d7e6 (en: 'four') - - "": [T: "viisi"] # 0xf547 (en: 'five', google translation) - - "𝟧": [T: "viisi"] # 0x1d7e7 (en: 'five') - - "": [T: "kuusi"] # 0xf548 (en: 'six', google translation) - - "𝟨": [T: "kuusi"] # 0x1d7e8 (en: 'six') - - "": [T: "seitsemän"] # 0xf549 (en: 'seven', google translation) - - "𝟩": [T: "seitsemän"] # 0x1d7e9 (en: 'seven') - - "": [T: "kahdeksan"] # 0xf54a (en: 'eight', google translation) - - "𝟪": [T: "kahdeksan"] # 0x1d7ea (en: 'eight', google: 'at') - - "": [T: "yhdeksän"] # 0xf54b (en: 'nine', google translation) - - "𝟫": [T: "yhdeksän"] # 0x1d7eb (en: 'nine') - - "": [T: "lihavoitu nolla"] # 0xf54c (en: 'bold zero', google translation) - - "𝟬": [T: "lihavoitu nolla"] # 0x1d7ec (en: 'bold zero') - - "": [T: "lihavoitu yksi"] # 0xf54d (en: 'bold one', google translation) - - "𝟭": [T: "lihavoitu yksi"] # 0x1d7ed (en: 'bold one', google: 'lihavoitu') - - "": [T: "lihavoitu kaksi"] # 0xf54e (en: 'bold two', google translation) - - "𝟮": [T: "lihavoitu kaksi"] # 0x1d7ee (en: 'bold two') - - "": [T: "lihavoitu kolme"] # 0xf54f (en: 'bold three', google translation) - - "𝟯": [T: "lihavoitu kolme"] # 0x1d7ef (en: 'bold three') - - "": [T: "lihavoitu neljä"] # 0xf550 (en: 'bold four', google translation) - - "𝟰": [T: "lihavoitu neljä"] # 0x1d7f0 (en: 'bold four', google: 'bold neljä') - - "": [T: "lihavoitu viisi"] # 0xf551 (en: 'bold five', google translation) - - "𝟱": [T: "lihavoitu viisi"] # 0x1d7f1 (en: 'bold five') - - "": [T: "lihavoitu kuusi"] # 0xf552 (en: 'bold six', google translation) - - "𝟲": [T: "lihavoitu kuusi"] # 0x1d7f2 (en: 'bold six') - - "": [T: "lihavoitu seitsemän"] # 0xf553 (en: 'bold seven', google translation) - - "𝟳": [T: "lihavoitu seitsemän"] # 0x1d7f3 (en: 'bold seven', google: 'rohkea seitsemän') - - "": [T: "lihavoitu kahdeksan"] # 0xf554 (en: 'bold eight', google translation) - - "𝟴": [T: "lihavoitu kahdeksan"] # 0x1d7f4 (en: 'bold eight', google: 'lihavoitu') - - "": [T: "lihavoitu yhdeksän"] # 0xf555 (en: 'bold nine', google translation) - - "𝟵": [T: "lihavoitu yhdeksän"] # 0x1d7f5 (en: 'bold nine') - - "": [T: "nolla"] # 0xf556 (en: 'zero', google translation) - - "𝟶": [T: "nolla"] # 0x1d7f6 (en: 'zero') - - "": [T: "yksi"] # 0xf557 (en: 'one', google translation) - - "𝟷": [T: "yksi"] # 0x1d7f7 (en: 'one') - - "": [T: "kaksi"] # 0xf558 (en: 'two', google translation) - - "𝟸": [T: "kaksi"] # 0x1d7f8 (en: 'two') - - "": [T: "kolme"] # 0xf559 (en: 'three', google translation) - - "𝟹": [T: "kolme"] # 0x1d7f9 (en: 'three') - - "": [T: "neljä"] # 0xf55a (en: 'four', google translation) - - "𝟺": [T: "neljä"] # 0x1d7fa (en: 'four') - - "": [T: "viisi"] # 0xf55b (en: 'five', google translation) - - "𝟻": [T: "viisi"] # 0x1d7fb (en: 'five') - - "": [T: "kuusi"] # 0xf55c (en: 'six', google translation) - - "𝟼": [T: "kuusi"] # 0x1d7fc (en: 'six') - - "": [T: "seitsemän"] # 0xf55d (en: 'seven', google translation) - - "𝟽": [T: "seitsemän"] # 0x1d7fd (en: 'seven') - - "": [T: "kahdeksan"] # 0xf55e (en: 'eight', google translation) - - "𝟾": [T: "kahdeksan"] # 0x1d7fe (en: 'eight', google: 'at') - - "": [T: "yhdeksän"] # 0xf55f (en: 'nine', google translation) - - "𝟿": [T: "yhdeksän"] # 0x1d7ff (en: 'nine') - - "": [T: "tuntematon merkki"] # 0xf700 (en: 'unknown character', google translation) - - "": [T: "alaoikea ja alavasen kolmio"] # 0xf726 (en: 'lower right and lower left triangles', google translation) - - "": [T: "vaakasuora pistekolmikko pidennys"] # 0xf72d (en: 'horizontal ellipsis extender', google translation) - - "": [T: "keskiviivan vaakasuora pistekolmikko pidennys"] # 0xf72e (en: 'midline horizontal ellipsis extender', google translation) - - "": [T: "radikaali pidennys"] # 0xf8e5 (en: 'radical extender', google translation) # FI: unclear translation, root? - - "": [T: "pystysuora nuoli pidennys"] # 0xf8e6 (en: 'vertical arrow extender', google translation) - - "": [T: "vaakasuora nuoli pidennys"] # 0xf8e7 (en: 'horizontal arrow extender', google translation) - - "": [T: "rekisteröity merkki sans serif"] # 0xf8e8 (en: 'registered sign sans serif', google translation) - - "": [T: "tekijänoikeusmerkki sans serif"] # 0xf8e9 (en: 'copyright sign sans serif', google translation) - - "": [T: "trademark -merkki sans serif"] # 0xf8ea (en: 'trade mark sign sans serif', google translation) - - "": [T: "vasen kaarisulku ylä"] # 0xf8eb (en: 'left paren top', google translation) - - "": [T: "vasen kaarisulku pidennys"] # 0xf8ec (en: 'left paren extender', google translation) - - "": [T: "vasen kaarisulku ala"] # 0xf8ed (en: 'left paren bottom', google translation) - - "": [T: "vasen hakasulku ylä"] # 0xf8ee (en: 'left bracket top', google translation) - - "": [T: "vasen hakasulku pidennys"] # 0xf8ef (en: 'left bracket extender', google translation) - - "": [T: "vasen hakasulku ala"] # 0xf8f0 (en: 'left bracket bottom', google translation) - - "": [T: "vasen hakasulku ylä"] # 0xf8f1 (en: 'left brace top', google translation) - - "": [T: "vasen aaltosulku keski"] # 0xf8f2 (en: 'left brace mid', google translation) - - "": [T: "vasen aaltosulku ala"] # 0xf8f3 (en: 'left brace bottom', google translation) - - "": [T: "aaltosulku pidennys"] # 0xf8f4 (en: 'brace extender', google translation) - - "": [T: "integraali pidennys"] # 0xf8f5 (en: 'integral extender', google translation) - - "": [T: "oikea kaarisulku ylä"] # 0xf8f6 (en: 'right paren top', google translation) - - "": [T: "oikea kaarisulku pidennys"] # 0xf8f7 (en: 'right paren extender', google translation) - - "": [T: "oikea kaarisulku ala"] # 0xf8f8 (en: 'right paren bottom', google translation) - - "": [T: "oikea hakasulku ylä"] # 0xf8f9 (en: 'right bracket top', google translation) - - "": [T: "oikea hakasulku pidennys"] # 0xf8fa (en: 'right bracket extender', google translation) - - "": [T: "oikea hakasulku ala"] # 0xf8fb (en: 'right bracket bottom', google translation) - - "": [T: "oikea aaltosulku ylä"] # 0xf8fc (en: 'right brace top', google translation) - - "": [T: "oikea aaltosulku keski"] # 0xf8fd (en: 'right brace mid', google translation) - - "": [T: "oikea aaltosulku ala"] # 0xf8fe (en: 'right brace bottom', google translation) - - "": [T: "apple-logo"] # 0xf8ff (en: 'apple logo', google translation) - - "ff": [T: "f f"] # 0xfb00 (en: 'ff', google: 'ff') - - "fi": [T: "f i"] # 0xfb01 (en: 'fi', google: 'fi') - - "fl": [T: "f l"] # 0xfb02 (en: 'fl', google: 'fl') - - "ffi": [T: "f f i"] # 0xfb03 (en: 'ffi', google: 'ffi') - - "ffl": [T: "f f l"] # 0xfb04 (en: 'ffl', google: 'ffl') - - "ſt": [T: "f t"] # 0xfb05 (google translation) - - "st": [T: "s t"] # 0xfb06 (google translation) - - "︠": [T: "ligatuuri vasen puolikas koriste"] # 0xfe20 (en: 'ligature left half embellishment', google translation) # FI: : translation unclear - - "︡": [T: "ligatuuri oikea puolikas koriste"] # 0xfe21 (en: 'ligature right half embellishment', google translation) # FI: : translation unclear - - "︢": [T: "kaksoistilde vasen puolikas koriste"] # 0xfe22 (en: 'double tilde left half embellishment', google translation) # FI: : translation unclear - - "︣": [T: "kaksoistilde oikea puolikas koriste"] # 0xfe23 (en: 'double tilde right half embellishment', google translation) - - "︤": [T: "pituusmerkki vasen puolikas koriste"] # 0xfe24 (en: 'macron left half embellishment', google translation) - - "︥": [T: "pituusmerkki oikea puolikas koriste"] # 0xfe25 (en: 'macron right half embellishment', google translation) - - "︦": [T: "yhdistävä pituusmerkkikoriste"] # 0xfe26 (en: 'conjoining macron embellishment', google translation) - - "︵": [T: "yläsulku"] # 0xfe35 (google: 'yli sulku') - - "︶": [T: "alasulku"] # 0xfe36 (google: 'suluissa') - - "︷": [T: "yläaaltosulku"] # 0xfe37 (en: 'over brace', google: 'yli ahdin') - - "︸": [T: "ala-aaltosulku"] # 0xfe38 (en: 'under brace', google: 'ahdin alla') - - "︿": [T: "yläkulmasulku"] # 0xfe3f (google: 'yli kulmakiinnike') - - "﹀": [T: "alakulmasulku"] # 0xfe40 (google: 'kulmakiinnikkeessä') - - "﹨": [T: "kokonaislukujen jakomerkki"] # 0xfe68 (google: 'kokonaislukujako') - - "": [T: "tuntematon tai puuttuva objekti"] # 0xfffc (en: 'unknown or missing object', google translation) - - "�": [T: "tuntematon tai puuttuva merkki"] # 0xfffd (en: 'unknown or missing character') +--- + +# Translated with the help of https://jkorpela.fi/merkkien-nimet.html + + - "¢": [T: "senttiä"] # 0xa2 (en: 'cents') + - "£": [T: "puntaa"] # 0xa3 (en: 'pounds') + - "¤": [T: "valuuttamerkki"] # 0xa4 (en: 'currency sign') + - "¥": [T: "jeni"] # 0xa5 (en: 'yen', google: 'jeni') + - "¦": [T: "katkopystyviiva"] # 0xa6 (en: 'broken bar', google: 'rikkoutunut palkki') + - "§": [T: "pykälä"] # 0xa7 (en: 'section', google: 'osa') + - "¨": [T: "piste piste"] # 0xa8 (en: 'double dot', google: 'kaksinkertainen piste') # FI: use case with derivative? + - "©": [T: "tekijänoikeus"] # 0xa9 (en: 'copyright', google: 'tekijänoikeudet') # FI: in NVDA it's written "copyright" + - "ª": [T: "feminiininen järjestysluku"] # 0xaa (en: 'feminine ordinal indicator', google: 'naisellinen ordinaaliindikaattori') + - "«": [T: "vasemmalle osoittava kaksinkertainen kulmalainausmerkki"] # 0xab (en: 'left-pointing double angle quote mark', google: 'vasemman potentiaalinen kaksoiskulma lainausmerkki') + - "¯": # 0xaf + - test: + if: "ancestor::m:modified-variable and preceding-sibling::*[1][self::m:mi]" + then: [T: "viiva"] # (en: 'bar', google translation) + else: [T: "viiva"] # (en: 'line', google: 'linja') + - "²": [T: "yläindeksi kaksi"] # 0xb2 (en: 'two', google: 'kaksi') + - "³": [T: "yläindeksi kolme"] # 0xb3 (en: 'three', google: 'kolme') + - "µ": [T: "mikro"] # 0xb5 (en: 'micro') + - "¹": [T: "yläindeksi yksi"] # 0xb9 (en: 'one', google: 'yksi') + - "º": [T: "maskuliininen järjestysluku"] # 0xb9 (en: 'masculine ordinal indicator', google: 'maskuliininen ordinaaliindikaattori') # should be 0xba + - "ʰ": [T: "yläindeksi h"] # 0x2b0 (en: 'modifier small h', google translation) + - "ʱ": [T: "yläindeksi h koukulla"] # 0x2b1 (en: 'modifier small h with hook', google translation) + - "ʲ": [T: "yläindeksi j"] # 0x2b2 (en: 'modifier small j', google translation) + - "ʳ": [T: "yläindeksi r"] # 0x2b3 (en: 'modifier small r', google translation) + - "ʴ": [T: "yläindeksi käännetty r"] # 0x2b4 (en: 'modifier small turned r', google translation) + - "ʵ": [T: "yläindeksi käännetty r koukulla"] # 0x2b5 (en: 'modifier small turned r with hook', google translation) + - "ʶ": # 0x2b6 + - T: "yläindeksi käännetty R" # (en: 'modifier small inverted', google translation) + - SPELL: "translate('R', 'R', 'R')" + + - "ʷ": [T: "yläindeksi w"] # 0x2b7 (en: 'modifier small w', google translation) + - "ʸ": [T: "yläindeksi y"] # 0x2b8 (en: 'modifier small y', google translation) + - "ʹ": [T: "priimi"] # 0x2b9 (en: 'modifier prime', google translation) # FI: derivated once -> "pilkku" + - "ʺ": [T: "kaksoispriimi"] # 0x2ba (en: 'modifier double prime', google translation) # FI: derivated twice -> "pilkku pilkku" + - "ʻ": [T: "käänteispilkku"] # 0x2bb (en: 'modifier turned comma', google translation) + - "ʼ": [T: "heitto"] # 0x2bc (en: 'modifier apostrophe', google translation) + - "ʽ": [T: "peilikuvapilkku"] # 0x2bd (en: 'modifier reversed comma', google translation) + - "ʾ": [T: "tarke oikea puolikaari"] # 0x2be (en: 'modifier right half ring', google: 'muokkain oikea puolirengas') + - "ʿ": [T: "tarke vasen puolikaari"] # 0x2bf (en: 'modifier left half ring', google: 'muokkain vasemmalla puolirengas') + - "ˀ": [T: "glottaaliklusiilitarke"] # 0x2c0 (en: 'modifier glottal stop', google translation) + - "ˁ": [T: "käännetty glottaaliklusiilitarke"] # 0x2c1 (en: 'modifier reversed glottal stop', google translation) + - "˂": [T: "tarke vasen nuoli"] # 0x2c2 (en: 'modifier left arrowhead', google translation) + - "˃": [T: "tarke oikea nuoli"] # 0x2c3 (en: 'modifier right arrowhead', google translation) + - "˄": [T: "tarke nuoli ylös"] # 0x2c4 (en: 'modifier up arrowhead', google translation) + - "˅": [T: "tarke nuoli alas"] # 0x2c5 (en: 'modifier down arrowhead', google translation) + - "ˆ": [T: "sirkumfleksi"] # 0x2c6 (en: 'modifier circumflex accent', google: 'modifikaattorin ympäryssuoja aksentti') # FI: should maybe be "hat", "hattu" + - "ˇ": [T: "ylösalainen sirkumfleksi"] # 0x2c7 (en: 'caron', google: 'caron') # FI: "inverted hat"? "käännetty hattu" + - "ˈ": [T: "tarke pystyviiva"] # 0x2c8 (en: 'modifier vertical line', google translation) + - "ˉ": [T: "pituusmerkki"] # 0x2c9 (en: 'modifier macron', google: 'muokkain macron') + - "ˊ": [T: "tarke akuutti"] # 0x2ca (en: 'modifier acute accent', google translation) + - "ˋ": [T: "tarke gravis"] # 0x2cb (en: 'modifier grave accent', google translation) + - "ˌ": [T: "tarke alapystyviiva"] # 0x2cc (en: 'modifier low vertical line', google translation) + - "ˍ": [T: "alapituusmerkki"] # 0x2cd (en: 'modifier low macron', google translation) + - "ˎ": [T: "alagravis"] # 0x2ce (en: 'modifier low grave accent', google translation) + - "ˏ": [T: "ala-akuutti"] # 0x2cf (en: 'modifier low acute accent', google translation) + - "ː": [T: "kolmiokaksoispiste"] # 0x2d0 (en: 'modifier triangular colon', google translation) + - "ˑ": [T: "puolikas kolmiokaksoispiste"] # 0x2d1 (en: 'modifier half triangular colon', google translation) + - "˒": [T: "keskitetty oikea puolirengas"] # 0x2d2 (en: 'modifier centered right half ring', google translation) + - "˓": [T: "keskitetty vasen puolirengas"] # 0x2d3 (en: 'modifier centered left half ring', google translation) + - "˔": [T: "nupi ylöspäin"] # 0x2d4 (en: 'modifier up tadck', google translation) + - "˕": [T: "nupi alaspäin"] # 0x2d5 (en: 'modifier down tack', google translation) + - "˖": [T: "plus"] # 0x2d6 (en: 'modifier plus sign', google translation) + - "˗": [T: "miinus"] # 0x2d7 (en: 'modifier minus sign', google translation) + - "˘": [T: "lyhyysmerkki"] # 0x2d8 (en: 'breve', google: 'breve') + - "˙": [T: "piste"] # 0x2d9 (en: 'dot', google: 'piste') + - "˚": [T: "yläympyrä"] # 0x2da (en: 'ring above', google: 'rengas yläpuolella') + - "˛": [T: "ogonek"] # 0x2db + - "˜": [T: "pieni tilde"] # 0x2dc (en: 'small tilde', google: 'pieni tilde') + - "˝": [T: "kaksoisakuutti"] # 0x2dd (en: 'double acute accent', google: 'kaksinkertainen akuutti aksentti') + - "˞": [T: "rhoottinen koukku"] # 0x2de (en: 'modifier rhotic hook', google translation) + - "˟": [T: "risti"] # 0x2df (en: 'modifier cross accent', google translation) + - "ˠ": [T: "pieni gamma"] # 0x2e0 (en: 'modifier small gamma', google translation) # FI: should these be without "pieni" ("small")? + - "ˡ": [T: "pieni l"] # 0x2e1 (en: 'modifier small l', google translation) + - "ˢ": [T: "pieni s"] # 0x2e2 (en: 'modifier small s', google translation) + - "ˣ": [T: "pieni x"] # 0x2e3 (en: 'modifier small x', google translation) + - "ˤ": [T: "pieni käännetty glottaaliklusiili"] # 0x2e4 (en: 'modifier small reversed glottal stop', google translation) + - "˥": [T: "erittäin korkea äänipalkki"] # 0x2e5 (en: 'modifier extra-high tone bar', google translation) + - "˦": [T: "korkea äänipalkki"] # 0x2e6 (en: 'modifier high tone bar', google translation) + - "˧": [T: "keskiäänipalkki"] # 0x2e7 (en: 'modifier mid tone bar', google translation) + - "˨": [T: "matala äänipalkki"] # 0x2e8 (en: 'modifier low tone bar', google translation) + - "˩": [T: "erittäin matala äänipalkki"] # 0x2e9 (en: 'modifier extra-low tone bar', google translation) + - "˪": [T: "yin lähtöäänimerkki"] # 0x2ea (en: 'modifier yin departing tone mark', google translation) # FI: unclear + - "˫": [T: "yang lähtöäänimerkki"] # 0x2eb (en: 'modifier yang departing tone mark', google translation) # FI: unclear + - "ˬ": [T: "ääntämismerkki"] # 0x2ec (en: 'modifier voicing', google translation) + - "˭": [T: "aspiroitumattomuusmerkki"] # 0x2ed (en: 'modifier unaspirated', google translation) + - "ˮ": [T: "kaksoisheittomerkki"] # 0x2ee (en: 'modifier double apostrophe', google translation) + - "˯": [T: "alanuolenpää alas"] # 0x2ef (en: 'modifier low down arrowhead', google translation) + - "˰": [T: "alanuolenpää ylös"] # 0x2f0 (en: 'modifier low up arrowhead', google translation) + - "˱": [T: "alanuolenpää vasemmalle"] # 0x2f1 (en: 'modifier low left arrowhead', google translation) + - "˲": [T: "alanuolenpää oikealle"] # 0x2f2 (en: 'modifier low right arrowhead', google translation) + - "˳": [T: "alarengas"] # 0x2f3 (en: 'modifier low ring', google translation) + - "˴": [T: "keskitetty gravis"] # 0x2f4 (en: 'modifier middle grave accent', google translation) + - "˵": [T: "keskitetty tuplagravis"] # 0x2f5 (en: 'modifier middle double grave accent', google translation) + - "˶": [T: "keskitetty akuutti"] # 0x2f6 (en: 'modifier middle double acute accent', google translation) + - "˷": [T: "alatilde"] # 0x2f7 (en: 'modifier low tilde', google translation) + - "˸": [T: "nostettu kaksoispiste"] # 0x2f8 (en: 'modifier raised colon', google translation) + - "˹": [T: "korkea ääni alku"] # 0x2f9 (en: 'modifier begin high tone', google translation) + - "˺": [T: "korkea ääni loppu"] # 0x2fa (en: 'modifier end high tone', google translation) + - "˻": [T: "matala ääni alku"] # 0x2fb (en: 'modifier begin low tone', google translation) + - "˼": [T: "matala ääni loppu"] # 0x2fc (en: 'modifier end low tone', google translation) + - "˽": [T: "tarke hylly"] # 0x2fd (en: 'modifier shelf', google translation) + - "˾": [T: "tarke avoin hylly"] # 0x2fe (en: 'modifier open shelf', google translation) + - "˿": [T: "vasen alanuoli"] # 0x2ff (en: 'modifier low left arrow', google translation) + - "̈": [T: "treema"] # 0x308 (en: 'diaeresis embellishment', google: 'diaeresis -koriste') + - "̉": [T: "yläkoukku"] # 0x309 (en: 'hook above embellishment', google translation) + - "̊": [T: "yläympyrä"] # 0x30a (en: 'ring above embellishment', google: 'rengas koristelun yläpuolella') + - "̋": [T: "kakoisakuutti"] # 0x30b (en: 'double acute accent embellishment', google translation) + - "̌": [T: "hattu"] # 0x30c (en: 'check', google: 'tarkistaa') + - "̍": [T: "yläpuolinen pystyviiva"] # 0x30d (en: 'vertical line above embellishment', google translation) + - "̎": [T: "yläpuolinen kaksoispystyviiva"] # 0x30e (en: 'double vertical line above embellishment', google translation) + - "̏": [T: "kakoisgravis"] # 0x30f (en: 'double grave accent embellishment', google translation) + - "̐": [T: "candrabindu"] # 0x310 (en: 'candrabindu embellishment', google translation) + - "̑": [T: "ylösalainen lyhyysmerkki"] # 0x311 (en: 'inverted breve embellishment', google: 'käänteinen breve -koriste') + - "̒": [T: "yläpuolinen ylösalainen pilkku"] # 0x312 (en: 'turned comma above embellishment', google translation) + - "̓": [T: "yläoikealla oleva pilkku"] # 0x313 (en: 'comma above embellishment', google translation) + - "̔": [T: "yläpuolinen peilikuvapilkku"] # 0x314 (en: 'reversed comma above embellishment', google translation) + - "̕": [T: "yläpilkku"] # 0x315 (en: 'comma above right embellishment', google translation) + - "̖": [T: "alapuolinen gravis"] # 0x316 (en: 'grave accent below embellishment', google translation) + - "̗": [T: "alapuolinen akuutti"] # 0x317 (en: 'acute accent below embellishment', google translation) + - "̘": [T: "alapuolinen vasemmalle osoittava nupi"] # 0x318 (en: 'left tack below embellishment', google translation) + - "̙": [T: "alapuolinen oikealle osoittava nupi"] # 0x319 (en: 'right tack below embellishment', google translation) + - "̚": [T: "yläpuolinen vasen kulma"] # 0x31a (en: 'left angle above embellishment', google translation) + - "̛": [T: "sarvi"] # 0x31b (en: 'horn embellishment', google translation) + - "̜": [T: "alapuolinen vasen ympyränkaari"] # 0x31c (en: 'left half ring below embellishment', google translation) + - "̝": [T: "alapuolinen ylös osoittava nupi"] # 0x31d (en: 'up tack below embellishment', google translation) + - "̞": [T: "alapuolinen alas osoittava nupi"] # 0x31e (en: 'down tack below embellishment', google translation) + - "̟": [T: "alapuolinen plusmerkki"] # 0x31f (en: 'plus sign below embellishment', google translation) + - "̠": [T: "alapuolinen miinusmerkki"] # 0x320 (en: 'minus sign below embellishment', google translation) + - "̡": [T: "alapuolinen palataalisuuskoukku"] # 0x321 (en: 'palatalized hook below embellishment', google translation) + - "̢": [T: "alapuolinen retrofleksisuuskoukku"] # 0x322 (en: 'retroflex hook below embellishment', google translation) + - "̣": [T: "alapiste"] # 0x323 (en: 'dot below embellishment', google: 'piste koristelun alapuolella') + - "̤": [T: "alatreema"] # 0x324 (en: 'diaeresis below embellishment', google: 'diaeresis koristelun alapuolella') + - "̥": [T: "alaympyrä"] # 0x325 (en: 'ring below embellishment', google translation) + - "̦": [T: "alapilkku"] # 0x326 (en: 'comma below embellishment', google translation) + - "̧": [T: "sedilji"] # 0x327 (en: 'cedilla embellishment', google: 'cedilla -koriste') + - "̨": [T: "ogonek"] # 0x328 (en: 'ogonek embellishment', google translation) + - "̩": [T: "alapuolinen pystyviiva"] # 0x329 (en: 'vertical line below embellishment', google translation) + - "̪": [T: "alapuolinen silta"] # 0x32a (en: 'bridge below embellishment', google translation) + - "̫": [T: "alapuolinen ylösalainen kaksoiskaari"] # 0x32b (en: 'inverted double arch below embellishment', google translation) + - "̬": [T: "alapuolinen hattu"] # 0x32c (en: 'caron below embellishment', google translation) + - "̭": [T: "alapuolinen sirkumfleksi"] # 0x32d (en: 'circumflex accent below embellishment', google translation) + - "̮": [T: "alapuolinen lyhyysmerkki"] # 0x32e (en: 'breve below embellishment', google: 'breve koristelun alapuolella') + - "̯": [T: "alapuolinen ylösalainen lyhyysmerkki"] # 0x32f (en: 'inverted breve below embellishment', google translation) + - "̰": [T: "alatilde"] # 0x330 (en: 'tilde below embellishment', google: 'tilde koristelun alapuolella') + - "̱": [T: "alapuolinen pituusmerkki"] # 0x331 (en: 'macron below embellishment', google: 'macron koristelun alapuolella') + - "̲": [T: "alaviiva"] # 0x332 (en: 'low line embellishment', google: 'matala linjakoriste') + - "̳": [T: "kaksoisalaviiva"] # 0x333 (en: 'double low line embellishment', google translation) + - "̴": [T: "tilde päällä"] # 0x334 (en: 'tilde overlay embellishment', google translation) + - "̵": [T: "lyhyt yliviivaus"] # 0x335 (en: 'short stroke overlay embellishment', google translation) + - "̶": [T: "pitkä yliviivaus"] # 0x336 (en: 'long stroke overlay embellishment', google translation) + - "̷": [T: "lyhyt yliviivausvinoviiva"] # 0x337 (en: 'short solidus overlay embellishment', google translation) + - "̸": [T: "yliviivausvinoviiva"] # 0x338 (en: 'long solidus overlay embellishment', google: 'pitkä solidus -päällekkäisyys') + - "̹": [T: "oikea puolirengas alapuolella"] # 0x339 (en: 'right half ring below embellishment', google translation) + - "̺": [T: "käänteinen silta alapuolella"] # 0x33a (en: 'inverted bridge below embellishment', google translation) + - "̻": [T: "neliö alapuolella"] # 0x33b (en: 'square below embellishment', google translation) + - "̼": [T: "lokki alapuolella"] # 0x33c (en: 'seagull below embellishment', google translation) + - "̽": [T: "x yläpuolella"] # 0x33d (en: 'x above embellishment', google translation) + - "̾": [T: "pystysuora tilde"] # 0x33e (en: 'vertical tilde embellishment', google translation) + - "̿": [T: "kaksinkertainen yliviivaus"] # 0x33f (en: 'double overline embellishment', google translation) + - "̀": [T: "gravis"] # 0x340 (en: 'grave tone mark embellishment', google translation) + - "́": [T: "akuutti"] # 0x341 (en: 'acute tone mark embellishment', google translation) + + - "ΪΫϏ": # 0x3aa, 0x3ab, 0x3cf + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "iso"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [SPELL: "translate('.', 'ΪΫϏ', 'ιυϗ')"] + - T: "dialyytikalla" # (en: 'with dialytika', google translation) + - "ϊ": [T: "treema-ioota"] # 0x3ca (en: 'iota with dialytika', google translation) + - "ϋ": [T: "treema-ypsilon"] # 0x3cb (en: 'upsilon with dialytika', google translation) + - "ό": [T: "akuutti-omikron"] # 0x3cc (en: 'omicron with tonos', google translation) + - "ύ": [T: "akuutti-ypsilon"] # 0x3cd (en: 'upsilon with tonos', google translation) + - "ώ": [T: "akuutti-oomega"] # 0x3ce (en: 'omega with tonos', google translation) + - "ϐ": [T: "beeta"] # 0x3d0 (en: 'beta', google: 'beeta') + - "ϑ": [T: "theeta"] # 0x3d1 (en: 'theta', google: 'theta') + - "ϒ": [T: "ypsilon koukulla"] # 0x3d2 (en: 'upsilon with hook', google: 'upsilon koukkuun') + - "ϓ": [T: "upsilon akuutilla ja koukulla"] # 0x3d3 (en: 'upsilon with acute and hook', google translation) + - "ϔ": [T: "upsilon treemalla ja koukulla"] # 0x3d4 (en: 'upsilon with diaeresis and hook', google translation) + - "ϗ": [T: "kai"] # 0x3d7 (en: 'kai', google: 'kai') + - "А-Я": # 0x410 - 0x42f + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "iso"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [SPELL: "translate('.', 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ', 'абвгдежзийклмнопрстуфхцчшщъыьэюя')"] + - "а": [T: "a"] # 0x430 (google: 'а') + - "б": [T: "bee"] # 0x431 (google: 'olla') + - "в": [T: "vee"] # 0x432 + - "г": [T: "gee"] # 0x433 + - "д": [T: "dee"] # 0x434 + - "е": [T: "jee"] # 0x435 (google: 'eli') + - "ж": [T: "tzee"] # 0x436 + - "з": [T: "zee"] # 0x437 + - "и": [T: "i"] # 0x438 (google: 'и') + - "й": [T: "lyhyt i"] # 0x439 (en: 'short i') + - "к": [T: "kaa"] # 0x43a + - "л": [T: "el"] # 0x43b + - "м": [T: "em"] # 0x43c + - "н": [T: "en"] # 0x43d (google: 'fi') + - "о": [T: "o"] # 0x43e (google: 'о') + - "п": [T: "pee"] # 0x43f + - "р": [T: "er"] # 0x440 + - "с": [T: "es"] # 0x441 + - "т": [T: "tee"] # 0x442 + - "у": [T: "u"] # 0x443 (google: 'у') + - "ф": [T: "ef"] # 0x444 + - "х": [T: "haa"] # 0x445 + - "ц": [T: "tsee"] # 0x446 + - "ч": [T: "tshee"] # 0x447 + - "ш": [T: "shaa"] # 0x448 + - "щ": [T: "shtshaa"] # 0x449 + - "ъ": [T: "kova merkki"] # 0x44a (en: 'hard sign') + - "ы": [T: "jeru"] # 0x44b + - "ь": [T: "pehmeä merkki"] # 0x44c (en: 'soft sign') + - "э": [T: "käänteis-e"] # 0x44d (google: 'э') + - "ю": [T: "juu"] # 0x44e + - "я": [T: "jaa"] # 0x44f + - "‐": [T: "tavuviiva"] # 0x2010 (en: 'hyphen', google: 'tavuviiva') + - "‑": [T: "tavuviiva"] # 0x2011 (en: 'hyphen', google translation) + - "‒": [T: "numerotavuviiva"] # 0x2012 (en: 'figure dash', google translation) + - "–": [T: "lyhyt ajatusviiva"] # 0x2013 (en: 'en dash', google: 'fi dash') + - "—": [T: "pitkä ajatusviiva"] # 0x2014 (en: 'em dash', google: 'em dash') + - "‖": [T: "kaksinkertainen pystyviiva"] # 0x2016 (en: 'double vertical line', google: 'kaksinkertainen pystysuora viiva') + - "†": [T: "risti"] # 0x2020 (en: 'dagger', google: 'tikari') + - "‡": [T: "kaksoisristi"] # 0x2021 (en: 'double dagger', google: 'kaksinkertainen tikari') + + - "•": # 0x2022 + - test: + if: "@data-chem-formula-op" + then: [T: "piste"] # (en: 'dot', google translation) + else: [T: "luetelmapallo"] # (en: 'bullet', google: 'luoti') + + - "‰": [T: "promille"] # 0x2030 (en: 'per mille', google: 'per milli') + - "‱": [T: "kymmenestuhannesosa"] # 0x2031 (en: 'per ten thousand', google: 'kymmenentuhatta') + - "‵": [T: "käänteinen priimi"] # 0x2035 (en: 'reversed prime', google: 'kääntynyt pääministeri') # FI: "käänteinen pilkku" and for the next ones + - "‶": [T: "käänteinen kaskoispriimi"] # 0x2036 (en: 'reversed double prime', google: 'kääntynyt kaksinkertainen prime') + - "‷": [T: "käänteinen kolmoispriimi"] # 0x2037 (en: 'reversed triple prime', google translation) + - "‸": [T: "lisäys"] # 0x2038 + - "‹": [T: "vasemmalle osoittava kulmapuolilainaus"] # 0x2039 (en: 'single left pointing angle quote mark', google: 'yksi vasen piste -kulman lainausmerkki') + - "›": [T: "oikealle osoittava kulmapuolilainaus"] # 0x203a (en: 'single right pointing angle quote mark', google: 'yksi oikea osoituskulma lainausmerkki') + - "‼": [T: "kaksoiskertoma"] # 0x203c (en: 'double factorial', google translation) + - "⁄": [T: "murtoluvun vinoviiva"] # 0x2044 (en: 'divided by', google: 'jaettuna') # FI: check how this works in a sentence + - "⁅": [T: "piikillinen alkuhakasulku"] # 0x2045 (en: 'left square bracket with quill', google translation) + - "⁆": [T: "piikillinen loppuhakasulku"] # 0x2046 (en: 'right square bracket with quill', google translation) + - "⁗": [T: "neloispriimi"] # 0x2057 (en: 'quadruple prime', google: 'neljänneksen prime') # FI: maybe "pilkku pilkku pilkku pilkku" + - "⁠": [T: "rivinvaihdon esto"] # 0x2060 + - "⁰": [T: "potenssiin nolla"] # 0x2070 (en: 'to the zeroth power', google translation) + - "ⁱ": [T: "potenssiin i"] # 0x2071 (en: 'to the eihth power', google translation) + - "⁴": [T: "potenssiin neljä"] # 0x2074 (en: 'to the fourth power', google translation) + - "⁵": [T: "potenssiin viisi"] # 0x2075 (en: 'to the fifth power', google translation) + - "⁶": [T: "potenssiin kuusi"] # 0x2076 (en: 'to the sixth power', google translation) + - "⁷": [T: "potenssiin seitsemän"] # 0x2077 (en: 'to the seventh power', google translation) + - "⁸": [T: "potenssiin kahdeksan"] # 0x2078 (en: 'to the eighth power', google translation) + - "⁹": [T: "potenssiin yhdeksän"] # 0x2079 (en: 'to the ninth power', google translation) + - "⁺": [T: "yläindeksi plus"] # 0x207a (en: 'superscript plus sign', google translation) + - "⁻": [T: "yläindeksi miinus"] # 0x207b (en: 'superscript minus', google translation) + - "⁼": [T: "yläindeksi on yhtä suuri kuin"] # 0x207c (en: 'superscript equals sign', google translation) + - "⁽": [T: "yläindeksi vasen sulku"] # 0x207d (en: 'superscript left parenthesis', google translation) + - "⁾": [T: "yläindeksi oikea sulku"] # 0x207e (en: 'superscript right parenthesis', google translation) + - "ⁿ": [T: "potenssiin n"] # 0x207f (en: 'to the ennth power', google translation) + - "₀": [T: "alaindeksi nolla"] # 0x2080 (en: 'sub zero', google translation) + - "₁": [T: "alaindeksi yksi"] # 0x2081 (en: 'sub one', google translation) + - "₂": [T: "alaindeksi kaksi"] # 0x2082 (en: 'sub two', google translation) + - "₃": [T: "alaindeksi kolme"] # 0x2083 (en: 'sub three', google translation) + - "₄": [T: "alaindeksi neljä"] # 0x2084 (en: 'sub four', google translation) + - "₅": [T: "alaindeksi viisi"] # 0x2085 (google translation) + - "₆": [T: "alaindeksi kuusi"] # 0x2086 (google translation) + - "₇": [T: "alaindeksi seitsemän"] # 0x2087 (en: 'sub seven', google translation) + - "₈": [T: "alaindeksi kahdeksan"] # 0x2088 (en: 'sub eight', google translation) + - "₉": [T: "alaindeksi yhdeksän"] # 0x2089 (en: 'sub nine', google translation) + - "₊": [T: "alaindeksi plus"] # 0x208a (en: 'subscript plus sign', google translation) + - "₋": [T: "alaindeksi miinus"] # 0x208b (en: 'subscript minus sign', google translation) + - "₌": [T: "alaindeksi on yhtä suuri kuin"] # 0x208c (en: 'subscript equals sign', google translation) + - "₍": [T: "alaindeksi vasen sulku"] # 0x208d (en: 'subscript left parenthesis', google translation) + - "₎": [T: "alaindeksi oikea sulku"] # 0x208e (en: 'subscript right parenthesis', google translation) + - "ₐ": [T: "alaindeksi a"] # 0x2090 (en: 'sub A', google translation) + - "ₑ": [T: "alaindeksi e"] # 0x2091 (en: 'sub E', google translation) + - "ₒ": [T: "alaindeksi o"] # 0x2092 (en: 'sub O', google translation) + - "ₓ": [T: "alaindeksi x"] # 0x2093 (en: 'sub X', google translation) + - "ₕ": [T: "alaindeksi h"] # 0x2095 (en: 'sub H', google translation) + - "ₖ": [T: "alaindeksi k"] # 0x2096 (en: 'sub K', google translation) + - "ₗ": [T: "alaindeksi l"] # 0x2097 (en: 'sub L', google translation) + - "ₘ": [T: "alaindeksi m"] # 0x2098 (en: 'sub M', google translation) + - "ₙ": [T: "alaindeksi n"] # 0x2099 (en: 'sub N', google translation) + - "ₚ": [T: "alaindeksi p"] # 0x209a (en: 'sub P', google translation) + - "ₛ": [T: "alaindeksi s"] # 0x209b (en: 'sub S', google translation) + - "ₜ": [T: "alaindeksi t"] # 0x209c (en: 'sub T', google translation) + - "₠": [T: "eurooppalaiset valuuttayksiköt"] # 0x20a0 (en: 'european currenty units', google translation) + - "₡": [T: "colonia"] # 0x20a1 (en: 'colons', google: 'colons') + - "₢": [T: "cruzeiroa"] # 0x20a2 (en: 'cruzeiro', google: 'cruzeiro') + - "₣": [T: "frangia"] # 0x20a3 (en: 'franc', google: 'frangi') + - "₤": [T: "liiraa"] # 0x20a4 (en: 'lira', google: 'liira') + - "₥": [T: "milliä"] # 0x20a5 (en: 'mills', google: 'myllyt') + - "₦": [T: "nairaa"] # 0x20a6 (en: 'naira', google: 'naira') + - "₧": [T: "pesetaa"] # 0x20a7 (en: 'peseta', google: 'peseta') + - "₨": [T: "rupiaa"] # 0x20a8 (en: 'rupees', google: 'rupia') + - "₩": [T: "wonia"] # 0x20a9 (en: 'won', google: 'voitti') + - "₪": [T: "sekeliä"] # 0x20aa (en: 'new sheqels', google: 'uudet sheqels') + - "₫": [T: "dongia"] # 0x20ab (en: 'dong', google: 'dong') + - "€": [T: "euroa"] # 0x20ac (en: 'euros', google: 'eurot') + - "₭": [T: "kipia"] # 0x20ad (en: 'kip', google: 'kip') + - "₮": [T: "tugrikia"] # 0x20ae (en: 'tugrik', google: 'tugrik') + - "₯": [T: "drakhmaa"] # 0x20af (en: 'drachma', google: 'drachma') + - "₰": [T: "pfennigiä"] # 0x20b0 (en: 'german pennies', google: 'saksalaiset penniä') + - "₱": [T: "pesoa"] # 0x20b1 (en: 'pesos', google: 'pesot') + - "₲": [T: "guarania"] # 0x20b2 (en: 'guaranis', google: 'guaranis') + - "₳": [T: "australia"] # 0x20b3 (en: 'australs', google: 'itävaltait') + - "₴": [T: "hryvniaa"] # 0x20b4 (en: 'hryvnias', google: 'hryvnias') + - "₵": [T: "cediä"] # 0x20b5 (en: 'cedis', google: 'cedis') + - "₶": [T: "Toursin livreä"] # 0x20b6 (google translation) + - "₷": [T: "spesmiloa"] # 0x20b7 (google translation) + - "₸": [T: "tengeä"] # 0x20b8 (google translation) + - "₹": [T: "intialainen rupiaa"] # 0x20b9 (en: 'indian rupees', google translation) + - "₺": [T: "turkin liiraa"] # 0x20ba (en: 'turkish liras', google translation) + - "⃐": [T: "vasemmalle suuntautuva harppuuna"] # 0x20d0 (en: 'left harpoon above embellishment', google: 'vasen harppuon koristelun yläpuolella') + - "⃑": [T: "oikealle suuntautuva harppuuna"] # 0x20d1 (en: 'right harpoon above embellishment', google: 'oikea harppuuna koristelun yläpuolella') + - "⃒": [T: "pitkä yliviivauspystyviiva"] # 0x20d2 (en: 'long vertical line overlay embellishment', google translation) + - "⃓": [T: "lyhyt yliviivauspystyviiva"] # 0x20d3 (en: 'short vertical line overlay embellishment', google translation) + - "⃔": [T: "vastapäiväinen ylänuoli"] # 0x20d4 (en: 'anticlockwise arrow above embellishment', google translation) + - "⃕": [T: "myötäpäiväinen ylänuoli"] # 0x20d5 (en: 'clockwise arrow above embellishment', google translation) + - "⃖": [T: "vasemmalle suuntautuva nuoli"] # 0x20d6 (en: 'left arrow above embellishment', google: 'vasen nuoli koristelun yläpuolella') + - "⃗": [T: "oikealle suuntautuva nuoli"] # 0x20d7 (en: 'right arrow above embellishment', google: 'oikea nuoli koristelun yläpuolella') + - "⃘": [T: "rengas päällä"] # 0x20d8 (en: 'ring overlay embellishment', google translation) + - "⃙": [T: "rengas myötäpäivään päällä"] # 0x20d9 (en: 'clockwise ring overlay embellishment', google translation) + - "⃚": [T: "rengas vastapäivään päällä"] # 0x20da (en: 'anticlockwise ring overlay embellishment', google translation) + - "⃛": [T: "kolmoispiste"] # 0x20db (en: 'triple dot', google: 'kolminkertainen piste') + - "⃜": [T: "nelinkertainen piste"] # 0x20dc (en: 'quadruple dot', google: 'nelinkertainen piste') + - "⃝": [T: "sulkeva ympyrä"] # 0x20dd (en: 'enclosing circle embellishment', google translation) + - "⃞": [T: "sulkeva neliö"] # 0x20de (en: 'enclosing square embellishment', google translation) + - "⃟": [T: "sulkeva timantti"] # 0x20df (en: 'enclosing diamond embellishment', google translation) + - "⃠": [T: "sulkeva ympyrä kenoviivalla"] # 0x20e0 (en: 'enclosing circle backslash embellishment', google translation) + - "⃡": [T: "ylänuoli oikealle ja vasemmalle"] # 0x20e1 (en: 'left right arrow above embellishment', google: 'vasen oikea nuoli koristelun yläpuolella') + - "⃢": [T: "sulkeva ruutu"] # 0x20e2 (en: 'enclosing screen embellishment', google translation) + - "⃣": [T: "sulkeva näppäin"] # 0x20e3 (en: 'enclosing keycap embellishment', google translation) + - "⃤": [T: "sulkeva kolmio ylöspäin"] # 0x20e4 (en: 'enclosing upward pointing triangle embellishment', google translation) + - "⃥": [T: "kenoviiva päällä"] # 0x20e5 (en: 'reverse solidus overlay embellishment', google translation) + - "⃦": [T: "kaksinkertainen vaakaviiva päällä"] # 0x20e6 (en: 'double verticle stroke embellishment', google translation) + - "⃧": [T: "annuiteettisymboli"] # 0x20e7 (en: 'annuity symbol embellishment', google translation) + - "⃨": [T: "kolminkertainen alapiste"] # 0x20e8 (en: 'triple underdot', google translation) + - "⃩": [T: "leveä silta yläpuolella"] # 0x20e9 (en: 'wide bridge above embellishment', google translation) + - "⃪": [T: "vasen nuoli päällä"] # 0x20ea (en: 'leftwards arrow overlay embellishment', google translation) + - "⃫": [T: "pitkä kaksinkertainen vinoviiva päällä"] # 0x20eb (en: 'long double solidus overlay embellishment', google translation) + - "⃬": [T: "oikea alaharppuuna piikillä"] # 0x20ec (en: 'rightwards harpoon with barb downwards embellishment', google translation) + - "⃭": [T: "vasen alaharppuuna piikillä"] # 0x20ed (en: 'leftwards harpoon with barb downwards embellishment', google translation) + - "⃮": [T: "vasen alanuoli"] # 0x20ee (en: 'left arrow below embellishment', google translation) + - "⃯": [T: "oikea alanuoli"] # 0x20ef (en: 'right arrow below embellishment', google translation) + - "⃰": [T: "yläpuolinen asteriski"] # 0x20f0 (en: 'asterisk above embellishment', google translation) + - "℄": [T: "keskiviivasymboli"] # 0x2104 (en: 'center line symbol', google translation) + - "℅": [T: "C O"] # 0x2105 (google: 'hoito') + - "℆": [T: "C U"] # 0x2106 (google translation) + - "ℇ": [T: "eulerin vakio"] # 0x2107 (en: 'euler's constant', google: 'eulerin jatkuva') # FI: more German pronunciation? + - "℈": [T: "scruple"] # 0x2108 (en: 'scruples', google translation) + - "℉": [T: "astetta fahrenheitia"] # 0x2109 (en: 'degrees fahrenheit', google: 'fahrenheit-astetta') # FI: more German pronunciation? + - "ℊ": [T: "pieni g"] # 0x210a (en: 'script g', google: 'käsikirjoitus g') + - "ℌℑℨℭ": # 0x210c, 0x2111, 0x2128, 0x212d + - T: "fraktuura" # (en: 'fraktur', google: 'fraktur') + - SPELL: "translate('.', 'ℌℑℨℭ', 'HIZC')" + + - "ℍℙℾℿ": # 0x210d, 0x2119, 0x213e, 0x213f + - test: + if: "$Verbosity!='Terse'" + then: [T: "kaksiviivainen"] # (en: 'double struck', google translation) + - SPELL: "translate('.', 'ℍℙℾℿ', 'HPΓΠ')" + + - "ℎ": [T: "planckin vakio"] # 0x210e (en: 'planck constant', google: 'planck constant') + - "ℏ": # 0x210f + - test: + if: "($Verbosity='Terse')" + then: [T: "h viiva"] # (google translation) + else: [T: "redusoitu Planckin vakio"] # (en: 'reduced planck constant', google: 'vähentynyt planck -vakio') + + - "ℐℒ℘ℬℰℱℳ": # 0x2110, 0x2112, 0x2118, 0x2130, 0x2131, 0x2133 + - T: "kauno" # (en: 'script', google: 'käsikirjoitus') + - SPELL: "translate('.', 'ℐℒ℘ℬℰℱℳ', 'ILPBEFM')" + + - "℔": [T: "paunaa"] # 0x2114 (en: 'pounds', google translation) + - "№": [T: "numero"] # 0x2116 (en: 'number', google: 'määrä') + - "℥": [T: "unssia"] # 0x2125 (en: 'ounces', google: 'unssi') + - "Ω": [T: "ohmia"] # 0x2126 (en: 'ohms', google: 'ohmit') + - "℧": [T: "käännetty ohmi"] # 0x2127 (en: 'mhos', google: 'mhos') + - "℩": [T: "käännetty ioota"] # 0x2129 (en: 'turned iota', google: 'kääntyi iota') + - "Å": [T: "ångströmiä"] # 0x212b (en: 'angstroms', google: 'angstroms') + - "ℯ": [T: "kauno e"] # 0x212f (en: 'script e', google: 'käsikirjoitus e') + + # coalesced some chars that use cap letters + - "Ⅎ℺⅁⅂⅃⅄": # 0x2132, 0x213a, 0x2141, 0x2142, 0x2143, 0x2144 + - test: + - if: "'.' = '℺'" + then: [T: "kierretty"] # (en: 'rotated', google translation) + - else_if: "'.' = 'Ⅎ'" + then: [T: "käännetty"] # (en: 'turned', google translation) + - else_if: "'.' = '⅃'" + then: [T: "kääntynyt sans-serif"] # (en: 'reversed sans-serif', google translation) + else: [T: "käännetty sans-serif"] # (en: 'turned sans-serif', google: 'kääntyi sans-serif') + - SPELL: "translate('.', 'Ⅎ℺⅁⅂⅃⅄', 'FQGLLY')" + + - "ℴ": [T: "kauno o"] # 0x2134 (en: 'script o', google: 'käsikirjoitus o') + - "ℵ": [T: "alef"] # 0x2135 (en: 'first transfinite cardinal', google: 'ensimmäinen transfinite kardinaali') + - "ℶ": [T: "bet"] # 0x2136 (en: 'second transfinite cardinal', google: 'toinen transfinite kardinaali') + - "ℷ": [T: "gimel"] # 0x2137 (en: 'third transfinite cardinal', google: 'kolmas transfinite kardinaali') + - "ℸ": [T: "dalet"] # 0x2138 (en: 'fourth transfinite cardinal', google: 'neljäs transfinite kardinaali') + - "ℼ": [T: "kaksoisviivainen pii"] # 0x213c (en: 'double struck pi', google translation) + - "ℽ": [T: "kaksoisviivainen gamma"] # 0x213d (en: 'double struck gamma', google translation) + - "⅀": [T: "kaksoisviivainen sigma"] # 0x2140 (en: 'double struck n-ary summation', google translation) + - "⅋": [T: "käännetty et-merkki"] # 0x214b (en: 'turned ampersand', google translation) + - "⅌": [T: "per"] # 0x214c (google translation) + - "ⅎ": [T: "käännetty F"] # 0x214e (en: 'turned F', google translation) + - "⅐": [T: "yksi seitsemäsosa"] # 0x2150 (en: 'one seventh', google translation) + - "⅑": [T: "yksi yhdeksäsosa"] # 0x2151 (en: 'one ninth', google translation) + - "⅒": [T: "yksi kymmenesosa"] # 0x2152 (en: 'one tenth', google translation) + - "⅓": [T: "yksi kolmasosa"] # 0x2153 (en: 'one third', google: 'kolmasosa') + - "⅔": [T: "kaksi kolmasosaa"] # 0x2154 (en: 'two thirds') + - "⅕": [T: "yksi viidesosa"] # 0x2155 (en: 'one fifth', google: 'viidesosa') + - "⅖": [T: "kaksi viidesosaa"] # 0x2156 (en: 'two fifths') + - "⅗": [T: "kolme viidesosaa"] # 0x2157 (en: 'three fifths') + - "⅘": [T: "neljä viidesosaa"] # 0x2158 (en: 'four fifths') + - "⅙": [T: "yksi kuudesosa"] # 0x2159 (en: 'one sixth', google: 'kuudesosa') + - "⅚": [T: "viisi kuudesosaa"] # 0x215a (en: 'five sixths') + - "⅛": [T: "yksi kahdeksasosa"] # 0x215b (en: 'one eighth', google: 'yksi ath') + - "⅜": [T: "kolme kahdeksasosaa"] # 0x215c (en: 'three eighths', google: 'kolme aths') + - "⅝": [T: "viisi kahdeksasosaa"] # 0x215d (en: 'five eighths', google: 'viisi aths') + - "⅞": [T: "seitsemän kahdeksasosaa"] # 0x215e (en: 'seven eighths', google: 'seitsemän aths') + - "⅟": [T: "yksi per"] # 0x215f (en: 'one over', google translation) + - "Ⅰ": [T: "I"] # 0x2160 (en: 'I', google translation) + - "Ⅱ": [T: "I I"] # 0x2161 (en: 'I I', google translation) + - "Ⅲ": [T: "I I I"] # 0x2162 (en: 'I I I', google translation) + - "Ⅳ": [T: "I V"] # 0x2163 (en: 'I V', google translation) + - "Ⅴ": [T: "V"] # 0x2164 (en: 'V', google translation) + - "Ⅵ": [T: "V I"] # 0x2165 (en: 'V I', google translation) + - "Ⅶ": [T: "V I I"] # 0x2166 (en: 'V I I', google translation) + - "Ⅷ": [T: "V I I I"] # 0x2167 (en: 'V I I I', google translation) + - "Ⅸ": [T: "I X"] # 0x2168 (en: 'I X', google translation) + - "Ⅹ": [T: "X"] # 0x2169 (en: 'X', google translation) + - "Ⅺ": [T: "X I"] # 0x216a (en: 'X I', google translation) + - "Ⅻ": [T: "X I I"] # 0x216b (en: 'X I I', google translation) + - "Ⅼ": [T: "L"] # 0x216c (en: 'L', google translation) + - "Ⅽ": [T: "C"] # 0x216d (en: 'C', google translation) + - "Ⅾ": [T: "D"] # 0x216e (en: 'D', google translation) + - "Ⅿ": [T: "M"] # 0x216f (en: 'M', google translation) + - "ⅰ": [T: "i"] # 0x2170 (en: 'I', google translation) + - "ⅱ": [T: "i i"] # 0x2171 (en: 'I I', google translation) + - "ⅲ": [T: "i i i"] # 0x2172 (en: 'I I I', google translation) + - "ⅳ": [T: "i v"] # 0x2173 (en: 'I V', google translation) + - "ⅴ": [T: "ⅴ"] # 0x2174 (en: 'V', google translation) + - "ⅵ": [T: "v i"] # 0x2175 (en: 'V I', google translation) + - "ⅶ": [T: "v i i"] # 0x2176 (en: 'V I I', google translation) + - "ⅷ": [T: "v i i i"] # 0x2177 (en: 'V I I I', google translation) + - "ⅸ": [T: "i x"] # 0x2178 (en: 'I X', google translation) + - "ⅹ": [T: "ⅹ"] # 0x2179 (en: 'X', google translation) + - "ⅺ": [T: "x i"] # 0x217a (en: 'X I', google translation) + - "ⅻ": [T: "x i i"] # 0x217b (en: 'X I I', google translation) + - "ⅼ": [T: "ⅼ"] # 0x217c (en: 'L', google translation) + - "ⅽ": [T: "ⅽ"] # 0x217d (en: 'C', google translation) + - "ⅾ": [T: "ⅾ"] # 0x217e (en: 'D', google translation) + - "ⅿ": [T: "ⅿ"] # 0x217f (en: 'M', google translation) + - "↉": [T: "nolla kolmasosaa"] # 0x2189 (en: 'zero thirds', google translation) + - "←": [T: "nuoli vasemmalle"] # 0x2190 (en: 'leftwards arrow', google: 'vasen nuoli') + - "↑": [T: "nuoli ylös"] # 0x2191 (en: 'upwards arrow', google: 'ylöspäin nuoli') + - "↓": [T: "nuoli alas"] # 0x2193 (en: 'downwards arrow', google: 'alaspäin nuoli') + - "↔": [T: "nuoli vasemmalle ja oikealle"] # 0x2194 (en: 'left right arrow', google: 'vasen oikea nuoli') + - "↕": [T: "nuoli ylös ja alas"] # 0x2195 (en: 'up down arrow', google: 'ylöspäin nuoli') + - "↖": [T: "luoteeseen osoittava nuoli"] # 0x2196 (en: 'north west arrow', google: 'luoteis -nuoli') + - "↗": # 0x2197 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "lähestyy alhaalta"] # (en: 'approaches from below', google translation) + else: [T: "koilliseen osoittava nuoli"] # (en: 'north east arrow', google: 'koillis -nuoli') + + - "↘": # 0x2198 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "lähestyy ylhäältä"] # (en: 'approaches from above', google translation) + else: [T: "kaakkoon osoittava nuoli"] # (en: 'south east arrow', google: 'kaakkois -nuoli') + + - "↙": [T: "lounaaseen osoittava nuoli"] # 0x2199 (en: 'south west arrow', google: 'lounais -nuoli') + - "↚": [T: "nuoli vasemmalle poikkiviivalla"] # 0x219a (en: 'leftwards arrow with stroke', google: 'vasen nuoli aivohalvauksella') + - "↛": [T: "nuoli oikealle poikkiviivalla"] # 0x219b (en: 'rightwards arrow with stroke', google: 'oikealla nuolella aivohalvauksella') + - "↜": [T: "aaltonuoli vasemmalle"] # 0x219c (en: 'leftwards wave arrow', google: 'vasen aalto nuoli') + - "↝": [T: "aaltonuoli oikealle"] # 0x219d (en: 'rightwards wave arrow', google: 'oikealla aalto nuoli') + - "↞": [T: "kaksipäinen nuoli vasemmalle"] # 0x219e (en: 'leftwards two headed arrow', google: 'vasen kaksi päätä nuoli') + - "↟": [T: "kaksipäinen nuoli ylös"] # 0x219f (en: 'upwards two headed arrow', google: 'ylöspäin kaksi pääistä nuolta') + - "↠": [T: "kaksipäinen nuoli oikealle"] # 0x21a0 (en: 'rightwards two headed arrow', google: 'oikealle kaksi pääistä nuolta') + - "↡": [T: "kaksipäinen nuoli alas"] # 0x21a1 (en: 'downwards two headed arrow', google: 'alaspäin kaksi päätä nuolta') + - "↢": [T: "vasen nuoli pyrstöllä"] # 0x21a2 (en: 'leftwards arrow with tail', google: 'vasen nuoli hännän kanssa') + - "↣": [T: "oikea nuoli pyrstöllä"] # 0x21a3 (en: 'rightwards arrow with tail', google: 'oikealla nuolella hännän kanssa') + - "↤": [T: "vasen nuoli palkista"] # 0x21a4 (en: 'leftwards arrow from bar', google: 'vasen nuoli baarista') + - "↥": [T: "ylöspäin osoittava nuoli palkista"] # 0x21a5 (en: 'upwards arrow from bar', google: 'nuoli ylöspäin baarista') + - "↦": [T: "oikea nuoli palkista"] # 0x21a6 (en: 'rightwards arrow from bar', google: 'oikein nuoli baarista') + - "↧": [T: "alaspäin osoittava nuoli palkista"] # 0x21a7 (en: 'downwards arrow from bar', google: 'alaspäin nuoli baarista') + - "↨": [T: "ylös ja alas osoittava nuoli palkista"] # 0x21a8 (en: 'up down arrow with base', google: 'ylös nuoli pohjassa') + - "↩": [T: "vasen nuoli koukulla"] # 0x21a9 (en: 'leftwards arrow with hook', google: 'vasen nuoli koukussa') + - "↪": [T: "oikea nuoli koukulla"] # 0x21aa (en: 'rightwards arrow with hook', google: 'oikealla nuolella koukkulla') + - "↫": [T: "vasen nuoli silmukalla"] # 0x21ab (en: 'leftwards arrow with loop', google: 'vasen nuoli silmukka') + - "↬": [T: "oikea nuoli silmukalla"] # 0x21ac (en: 'rightwards arrow with loop', google: 'oikea nuoli silmukka') + - "↭": [T: "aaltonuoli oikealle ja vasemmalle"] # 0x21ad (en: 'left right wave arrow', google: 'vasen oikea aalto nuoli') + - "↮": [T: "nuoli oikealle ja vasemmalle poikkiviivalla"] # 0x21ae (en: 'left right arrow with stroke', google: 'vasen oikea nuoli aivohalvauksella') + - "↯": [T: "siksaknuoli alas"] # 0x21af (en: 'downwards zigzag arrow', google: 'alaspäin zigzag -nuoli') + - "↰": [T: "nuoli ylös ja kärki vasemmalle"] # 0x21b0 (en: 'upwards arrow with tip leftwards', google: 'ylöspäin nuoli vasemmalla kärkillä') + - "↱": [T: "nuoli ylös ja kärki oikealle"] # 0x21b1 (en: 'upwards arrow with tip rightwards', google: 'ylöspäin nuoli, joka on kärki oikealla') + - "↲": [T: "nuoli alas ja kärki vasemmalle"] # 0x21b2 (en: 'downwards arrow with tip leftwards', google: 'alaspäin nuoli vasemmalla kärkillä') + - "↳": [T: "nuoli alas ja kärki oikealle"] # 0x21b3 (en: 'downwards arrow with tip rightwards', google: 'alaspäin nuoli kärjen oikealla puolella') + - "↴": [T: "nuoli oikealle ja kulma alas"] # 0x21b4 (en: 'rightwards arrow with corner downwards', google: 'oikealla nuolella nurkkaan alaspäin') + - "↵": [T: "nuoli alas ja kulma oikealle"] # 0x21b5 (en: 'downwards arrow with corner leftwards', google: 'alaspäin nuoli vasemmalla kulmassa') + - "↶": [T: "yläpuoliympyränuoli vastapäivään"] # 0x21b6 (en: 'anticlockwise top semicircle arrow', google: 'vastapäivään puolipyöriin nuoli') + - "↷": [T: "yläpuoliympyränuoli myötäpäivään"] # 0x21b7 (en: 'clockwise top semicircle arrow', google: 'myötäpäivään puolipyöriin nuoli') + - "↸": [T: "nuoli ylävasemmalle pitkään viivaan"] # 0x21b8 (en: 'north west arrow to long bar', google: 'luoteis -nuoli pitkään baariin') + - "↹": [T: "nuoli oikealle ja vasemmalle palkkiin"] # 0x21b9 (en: 'leftwards arrow to bar over rightwards arrow to bar', google: 'vasen nuoli baariin oikeanpuoleisen nuolen yli baariin') + - "↺": [T: "vastapäiväinen avoimen ympyrän nuoli"] # 0x21ba (en: 'anticlockwise open circle arrow', google: 'vastapäivään avoin ympyrä nuoli') + - "↻": [T: "myötäpäiväinen avoimen ympyrän nuoli"] # 0x21bb (en: 'clockwise open circle arrow', google: 'myötäpäivään avoin ympyrä nuoli') + - "↼": [T: "puolinuoli vasemmalle väkä ylös"] # 0x21bc (en: 'left harpoon up', google: 'vasen harppuon ylös') + - "↽": [T: "puolinuoli vasemmalle väkä alas"] # 0x21bd (en: 'left harpoon down', google: 'vasen harppuon alas') + - "↾": [T: "puolinuoli ylös väkä oikealle"] # 0x21be (en: 'up harpoon right', google: 'up harpoon oikeassa') + - "↿": [T: "puolinuoli ylös väkä vasemmalle"] # 0x21bf (en: 'up harpoon left', google: 'up harpoon vasemmalle') + - "⇀": [T: "puolinuoli oikealle väkä ylös"] # 0x21c0 (en: 'right harpoon up', google: 'oikea harppuun') + - "⇁": [T: "puolinuoli oikealle väkä alas"] # 0x21c1 (en: 'right harpoon down', google: 'oikea harppuuna alas') + - "⇂": [T: "puolinuoli alas väkä oikealle"] # 0x21c2 (en: 'down harpoon right', google: 'alas harppuon oikealla') + - "⇃": [T: "puolinuoli alas väkä vasemmalle"] # 0x21c3 (en: 'down harpoon left', google: 'alas harppuun vasemmalle') + - "⇄": [T: "oikealle ja vasemmalle osoittavien nuolien pari"] # 0x21c4 (en: 'rightwards arrow over leftwards arrow', google: 'oikealla nuolella vasemmanpuoleisen nuolen yli') + - "⇅": [T: "ylös ja alas osoittavien nuolien pari"] # 0x21c5 (en: 'upwards arrow leftwards of downwards arrow', google: 'ylöspäin nuoli vasemmalle alaspäin nuolesta') + - "⇆": [T: "vasemmalle ja oikealle osoittavien nuolien pari"] # 0x21c6 (en: 'leftwards arrow over rightwards arrow', google: 'vasen nuoli oikealla nuolella') + - "⇇": [T: "nuolipari vasemmalle"] # 0x21c7 (en: 'leftwards paired arrows', google: 'vasen parit nuolet') + - "⇈": [T: "nuolipari ylös"] # 0x21c8 (en: 'upwards paired arrows', google: 'ylöspäin parilliset nuolet') + - "⇉": [T: "nuolipari oikealle"] # 0x21c9 (en: 'rightwards paired arrows', google: 'oikealla puolella nuolet') + - "⇊": [T: "nuolipari alas"] # 0x21ca (en: 'downwards paired arrows', google: 'alaspäin parit nuolet') + - "⇋": [T: "puolinuolipari vasemmalle ja oikealle"] # 0x21cb (en: 'left harpoon over right harpoon', google: 'vasen harpoon oikean harppuunin yli') + - "⇌": [T: "puolinuolipari oikealle ja vasemmalle"] # 0x21cc (en: 'right harpoon over left harpoon', google: 'oikea harppuuna vasemman harppuunin yli') + - "⇍": [T: "kaksiviivainen nuoli vasemmalle poikkiviivalla"] # 0x21cd (en: 'leftwards double arrow with stroke', google: 'vasen kaksinkertainen nuoli aivohalvauksella') + - "⇎": [T: "kaksiviivainen nuoli vasemmalle ja oikealle poikkiviivalla"] # 0x21ce (en: 'left right double arrow with stroke', google: 'vasen oikea kaksinkertainen nuoli aivohalvauksella') + - "⇏": [T: "kaksiviivainen nuoli oikealle poikkiviivalla"] # 0x21cf (en: 'rightwards double arrow with stroke', google: 'oikeasti kaksinkertainen nuoli aivohalvauksella') + - "⇐": [T: "vasemmalle osoittava kaksoisnuoli"] # 0x21d0 (en: 'leftwards double arrow', google: 'vasen kaksinkertainen nuoli') + - "⇑": [T: "ylös osoittava kaksoisnuoli"] # 0x21d1 (en: 'upwards double arrow', google: 'ylöspäin kaksoisnuoli') + - "⇓": [T: "alas osoittava kaksoisnuoli"] # 0x21d3 (en: 'downwards double arrow', google: 'alaspäin kaksinkertainen nuoli') + - "⇔": [T: "vasemmalle ja oikealle osoittava kaksoisnuoli"] # 0x21d4 (en: 'left right double arrow', google: 'vasen oikea kaksinkertainen nuoli') + - "⇕": [T: "ylös ja alas osoittava kaksoisnuoli"] # 0x21d5 (en: 'up down double arrow', google: 'ylös alas kaksinkertainen nuoli') + - "⇖": [T: "luoteeseen osoittava kaksoisnuoli"] # 0x21d6 (en: 'north west double arrow', google: 'luoteisosan kaksinkertainen nuoli') + - "⇗": [T: "koilliseen osoittava kaksoisnuoli"] # 0x21d7 (en: 'north east double arrow', google: 'koillis -kaksinkertainen nuoli') + - "⇘": [T: "kaakkoon osoittava kaksoisnuoli"] # 0x21d8 (en: 'south east double arrow', google: 'kaakkois -kaksinkertainen nuoli') + - "⇙": [T: "luoteeseen osoittava kaksoisnuoli"] # 0x21d9 (en: 'south west double arrow', google: 'lounais -kaksinkertainen nuoli') + - "⇚": [T: "kolmiviivainen nuoli vasemmalle"] # 0x21da (en: 'leftwards triple arrow', google: 'vasen kolminkertainen nuoli') + - "⇛": [T: "kolmiviivainen nuoli oikealle"] # 0x21db (en: 'rightwards triple arrow', google: 'oikealle kolminkertainen nuoli') + - "⇜": [T: "kiemuranuoli vasemmalle"] # 0x21dc (en: 'leftwards squiggle arrow', google: 'vasen nuoli') + - "⇝": [T: "kiemuranuoli oikealle"] # 0x21dd (en: 'rightwards squiggle arrow', google: 'oikealla puolella nuoli') + - "⇞": [T: "nuoli ylös kaksoispoikkiviivalla"] # 0x21de (en: 'upwards arrow with double stroke', google: 'ylöspäin nuoli kaksinkertaisella iskulla') + - "⇟": [T: "nuoli alas kaksoispoikkiviivalla"] # 0x21df (en: 'downwards arrow with double stroke', google: 'alaspäin nuoli kaksinkertaisella iskulla') + - "⇠": [T: "katkoviivanuoli vasemmalle"] # 0x21e0 (en: 'leftwards dashed arrow', google: 'vasen katkoviiva nuoli') + - "⇡": [T: "katkoviivanuoli ylös"] # 0x21e1 (en: 'upwards dashed arrow', google: 'ylöspäin katkoviiva nuoli') + - "⇢": [T: "katkoviivanuoli oikealle"] # 0x21e2 (en: 'rightwards dashed arrow', google: 'oikealla katkoviivalla nuolella') + - "⇣": [T: "katkoviivanuoli alas"] # 0x21e3 (en: 'downwards dashed arrow', google: 'alaspäin katkoviiva nuoli') + - "⇤": [T: "nuoli vasemmalle viivaan"] # 0x21e4 (en: 'leftwards arrow to bar', google: 'vasen nuoli baariin') + - "⇥": [T: "nuoli oikealle viivaan"] # 0x21e5 (en: 'rightwards arrow to bar', google: 'oikein nuoli baariin') + - "⇦": [T: "vasemmalle osoittava valkea nuoli"] # 0x21e6 (en: 'leftwards white arrow', google: 'vasen valkoinen nuoli') + - "⇧": [T: "ylös osoittava valkea nuoli"] # 0x21e7 (en: 'upwards white arrow', google: 'ylöspäin valkoinen nuoli') + - "⇨": [T: "oikealle osoittava valkea nuoli"] # 0x21e8 (en: 'rightwards white arrow', google: 'oikealle valkoinen nuoli') + - "⇩": [T: "alas osoittava valkea nuoli"] # 0x21e9 (en: 'downwards white arrow', google: 'alaspäin valkoinen nuoli') + - "⇪": [T: "palkista ylös osoittava valkea nuoli"] # 0x21ea (en: 'upwards white arrow from bar', google: 'ylöspäin valkoinen nuoli baarista') + - "⇫": [T: "valkoinen nuoli ylös jalustalla"] # 0x21eb (en: 'upwards white arrow on pedestal', google translation) + - "⇬": [T: "valkoinen nuoli ylös jalustalla ja vaakasuoralla palkilla"] # 0x21ec (en: 'upwards white arrow on pedestal with horizontal bar', google translation) + - "⇭": [T: "valkoinen nuoli ylös jalustalla ja pystysuoralla palkilla"] # 0x21ed (en: 'upwards white arrow on pedestal with vertical bar', google translation) + - "⇮": [T: "valkoinen kaksinkertainen nuoli ylös"] # 0x21ee (en: 'upwards white double arrow', google translation) + - "⇯": [T: "valkoinen kaksinkertainen nuoli ylös jalustalla"] # 0x21ef (en: 'upwards white double arrow on pedestal', google translation) + - "⇰": [T: "valkoinen nuoli oikealle seinästä"] # 0x21f0 (en: 'rightwards white arrow from wall', google translation) + - "⇱": [T: "ylävasemmalle osoittava nuoli nurkkaan"] # 0x21f1 (en: 'north west arrow to corner', google translation) + - "⇲": [T: "alaoikealle osoittava nuoli nurkkaan"] # 0x21f2 (en: 'south east arrow to corner', google translation) + - "⇳": [T: "ylös ja alas osoittava valkoinen nuoli"] # 0x21f3 (en: 'up down white arrow', google translation) + - "⇴": [T: "oikea nuoli pienellä ympyrällä"] # 0x21f4 (en: 'right arrow with small circle', google translation) + - "⇵": [T: "alas ja ylös osoittavat nuolet"] # 0x21f5 (en: 'downwards arrow leftwards of upwards arrow', google: 'alaspäin nuoli ylöspäin ylöspäin nuolesta') + - "⇶": [T: "kolmoisnuoli oikealle"] # 0x21f6 (en: 'three rightwards arrows', google translation) + - "⇷": [T: "vasen nuoli pystysuoralla viivalla"] # 0x21f7 (en: 'leftwards arrow with vertical stroke', google translation) + - "⇸": [T: "oikea nuoli pystysuoralla viivalla"] # 0x21f8 (en: 'rightwards arrow with vertical stroke', google translation) + - "⇹": [T: "vasemmalle ja oikealle osoittava nuoli pystysuoralla viivalla"] # 0x21f9 (en: 'left right arrow with vertical stroke', google translation) + - "⇺": [T: "vasen nuoli kaksinkertaisella pystysuoralla viivalla"] # 0x21fa (en: 'leftwards arrow with double vertical stroke', google translation) + - "⇻": [T: "oikea nuoli kaksinkertaisella pystysuoralla viivalla"] # 0x21fb (en: 'rightwards arrow with double vertical stroke', google translation) + - "⇼": [T: "vasemmalle ja oikealle osoittava nuoli kaksinkertaisella pystysuoralla viivalla"] # 0x21fc (en: 'left right arrow with double vertical stroke', google translation) + - "⇽": [T: "vasen avoin nuoli"] # 0x21fd (en: 'leftwards open headed arrow', google: 'vasen auki pää nuoli') + - "⇾": [T: "oikea avoin nuoli"] # 0x21fe (en: 'rightwards open headed arrow', google: 'oikea avaa pään nutrow') + - "⇿": [T: "oikealle ja vasemmalle osoittava avoin nuoli"] # 0x21ff (en: 'left right open headed arrow', google: 'vasen oikeaa auki nuoli') + - "∁": # 0x2201 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (google translation) + - T: "komplementti" # (en: 'complement of', google: 'täydennys') + - "∃": [T: "on olemassa"] # 0x2203 (en: 'there exists') + - "∄": [T: "ei ole olemassa"] # 0x2204 (en: 'there does not exist', google: 'ei ole') + - "∅": [T: "tyhjä joukko"] # 0x2205 (en: 'empty set', google: 'tyhjä sarja') + - "∇": # 0x2207 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (google translation) + - T: "nabla" # (en: 'gradient of', google: 'gradientti') + - "∋": [T: "sisältää alkion"] # 0x220b (en: 'contains the member', google: 'sisältää jäsenen') + - "∌": [T: "ei sisällä alkiota"] # 0x220c (en: 'does not contain the member', google: 'ei sisällä jäsentä') + - "∍": [T: "sisältää pienen alkion"] # 0x220d (en: 'contains the member', google: 'sisältää jäsenen') + - "∎": [T: "todistuksen loppu"] # 0x220e (en: 'end of proof', google: 'todistuksen loppu') + - "∏": [T: "tulo"] # 0x220f (en: 'product', google: 'tuote') + - "∐": [T: "kotulo"] # 0x2210 (google: 'kopiointi') + - "∑": [T: "summa"] # 0x2211 (en: 'sum') + - "−": [T: "miinus"] # 0x2212 (en: 'minus') + - "∓": [T: "miinus-plus"] # 0x2213 (en: 'minus or plus') # FI: check how the hyphen behaves + - "∔": [T: "piste-plus"] # 0x2214 (en: 'dot plus', google: 'dot plus') # FI: check how the hyphen behaves + - "∕": [T: "jakoviiva"] # 0x2215 (en: 'divided by', google: 'jaettuna') + - "∖": [T: "joukkomiinus"] # 0x2216 (en: 'set minus', google: 'aseta miinus') + - "∗": [T: "kertaa"] # 0x2217 (en: 'times', google: 'ajat') + - "∙": # 0x2219 + - test: + if: "@data-chem-formula-op" + then: [T: "piste"] # (en: 'dot', google translation) + else: [T: "kertaa"] # (en: 'times', google: 'ajat') + + - "∛": # 0x221b + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (google translation) + - T: "kuutiojuuri" # (en: 'cube root of') + - "∜": # 0x221c + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (google translation) + - T: "neljäs juuri" # (en: 'fourth root of') + - "∞": [T: "ääretön"] # 0x221e (en: 'infinity') + - "∟": [T: "suora kulma"] # 0x221f (en: 'right angle', google: 'oikea kulma') + - "∠": [T: "kulma"] # 0x2220 (en: 'angle') + - "∡": [T: "mitattu kulma"] # 0x2221 (en: 'measured angle') + - "∢": [T: "kaarellinen kulma"] # 0x2222 (en: 'spherical angle', google: 'pallomainen kulma') + - "∣": [T: "jakaa"] # 0x2223 (en: 'divides') + - "∤": [T: "ei jaa"] # 0x2224 (en: 'does not divide') + - "∩": [T: "leikkaus"] # 0x2229 (en: 'intersection', google: 'risteys') + - "∫": [T: "integraali"] # 0x222b (en: 'integral', google: 'olennainen') + - "∬": [T: "kaksoisintegraali"] # 0x222c (en: 'double integral', google: 'kaksinkertainen integraali') + - "∭": [T: "kolmoisintegraali"] # 0x222d (en: 'triple integral', google: 'kolminkertainen integraali') + - "∯": [T: "pintaintegraali"] # 0x222f (en: 'surface integral', google: 'pinta -integraali') + - "∰": [T: "tilavuusintegraali"] # 0x2230 (en: 'volume integral', google: 'volyymin integraali') + - "∱": [T: "integraali myötäpäivään"] # 0x2231 (en: 'clockwise integral', google: 'myötäpäivään olennainen') + - "∲": [T: "polkuintegraali myötäpäivään"] # 0x2232 (en: 'clockwise contour integral', google: 'myötäpäivään ääriviivat') + - "∳": [T: "polkuintegraali vastapäivään"] # 0x2233 (en: 'anticlockwise contour integral', google: 'vastapäivään ääriviivat') + - "∴": [T: "siis"] # 0x2234 (en: 'therefore', google: 'siksi') + - "∵": [T: "koska"] # 0x2235 (en: 'because') + - "∸": [T: "piste-miinus"] # 0x2238 (en: 'dot minus') + - "∹": [T: "ylitys"] # 0x2239 (en: 'has excess compared to', google: 'on ylimääräinen verrattuna') + - "∺": # 0x223a + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "geometrisesti verrannollinen" # (en: 'geometrically proportional to', google: 'geometrisesti verrannollinen') # FI: "geometrisesti verranollinen"? + - "∻": # 0x223b + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "homoteettinen" # (en: 'homothetic to', google: 'homotetiikka') + - "≀": [T: "punostulo"] # 0x2240 (en: 'wreath product', google: 'seppele tuote') + - "≁": [T: "ei tilde"] # 0x2241 (en: 'not tilde') + - "≂": [T: "miinus-tilde"] # 0x2242 (en: 'minus tilde') + - "≃": # 0x2243 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "asymptoottisesti yhtä suuri kuin" # (en: 'asymptotically equal to', google: 'asymptoottisesti yhtä suuri kuin') + - "≄": # 0x2244 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei asymptoottisesti yhtäsuuri kuin" # (en: 'not asymptotically equal to', google: 'ei asymptoottisesti yhtä suuri kuin') + - "≅": # 0x2245 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "likimäärin yhtä suuri kuin" # (en: 'approximately equal to', google: 'suunnilleen yhtä suuri kuin') + - "≆": # 0x2246 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "likimäärin mutta ei yhtä suuri kuin" # (en: 'approximately but not actually equal to', google: 'suunnilleen, mutta ei oikeastaan yhtä suuri kuin') + - "≇": # 0x2247 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei likimäärin eikä yhtä suuri kuin" # (en: 'neither approximately nor actually equal to', google: 'ei suunnilleen eikä oikeastaan yhtä suuri kuin') + - "≈": # 0x2248 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "likimäärin yhtä suuri kuin" # (en: 'almost equal to', google: 'melkein yhtä suuri kuin') + - "≉": # 0x2249 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei likimäärin yhtä suuri kuin" # (en: 'not almost equal to', google: 'ei melkein yhtä suuri kuin') + - "≊": # 0x224a + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "lähes tai tasan yhtä suuri kuin" # (en: 'almost equal or equal to', google: 'melkein yhtä suuri tai yhtä suuri kuin') + - "≋": [T: "kolmoistilde"] # 0x224b (en: 'triple tilde', google: 'kolminkertainen tilde') + - "≌": [T: "kaikki yhtäsuuria kuin"] # 0x224c (en: 'are all equal to', google: 'ovat kaikki yhtä suuret kuin') + - "≍": # 0x224d + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "yhtäpitävä" # (en: 'equivalent to', google: 'vastaa') + - "≎": # 0x224e + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "geometrisesti yhtäpitävä" # (en: 'geometrically equivalent to', google: 'geometrisesti vastaavat') + - "≏": # 0x224f + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (google translation) + - T: "ero välillä" # (en: 'difference between', google: 'ero välillä') + - "≐": [T: "lähestyy raja-arvoa"] # 0x2250 (en: 'approaches the limit') + - "≑": # 0x2251 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "geometrisesti yhtä kuin" # (en: 'geometrically equal to', google: 'geometrisesti yhtä suuri kuin') + - "≒": # 0x2252 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "likimäärin yhtä suuri kuin tai kohteen kuva" # (google: 'suunnilleen yhtä suuri tai kuva') + - "≓": # 0x2253 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is the', google translation) + - T: "kohteen kuva tai likimäärin yhtä suuri kuin" # (google: 'kuva tai suunnilleen yhtä suuri kuin') + - "≔": [T: "kaksoispiste yhtä suuri kuin"] # 0x2254 (en: 'colon equals', google: 'colol -eaksi') + - "≕": [T: "yhtä suuri kuin kaksoispiste"] # 0x2255 (en: 'equals colon', google: 'vastaa kaksoispistettä') + - "≖": [T: "ympyrän sisältävä yhtäläisyys"] # 0x2256 (en: 'ring in equal to', google: 'rengas yhtä suuri kuin') + - "≗": # 0x2257 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "ympyrä yhtä suuri kuin" # (en: 'approximately equal to', google: 'suunnilleen yhtä suuri kuin') + - "≘": [T: "kaari yhtä suuri kuin"] # 0x2258 (en: 'corresponds to', google: 'vastaa') + - "≙": [T: "vastaa"] # 0x2259 (en: 'estimates', google: 'arviot') + - "≚": # 0x225a + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "samakulmainen kuin" # (en: 'equiangular to', google: 'tasa -arvoinen') + - "≛": [T: "tähti yhtä suuri kuin"] # 0x225b (en: 'star equals', google: 'tähti on yhtä suuri kuin') + - "≜": [T: "delta yhtä suuri kuin"] # 0x225c (en: 'delta equals', google: 'delta on tasa -arvoinen') + - "≝": [T: "määritelmän mukaan yhtä kuin"] # 0x225d (en: 'is defined to be', google: 'on määritelty olevan') + - "≞": # 0x225e + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "mitatusti yhtä suuri kuin" # (en: 'measured by', google: 'mitattu') + - "≟": [T: "kyseenalaisesti yhtä kuin"] # 0x225f (en: 'has an unknown relationship with', google: 'on tuntematon suhde') + - "≢": # 0x2262 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "identtisesti eri kuin" # (en: 'not identical to', google: 'ei identtinen') + - "≣": # 0x2263 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "vahvasti ekvivalentti" # (en: 'strictly equivalent to', google: 'tiukasti vastaa') + - "≨": # 0x2268 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "pienempi mutta ei yhtä suuri kuin" # (en: 'less than but not equal to', google: 'vähemmän kuin, mutta ei yhtä suuri kuin') + - "≩": # 0x2269 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "suurempi mutta ei yhtä suuri kuin" # (en: 'greater than but not equal to', google: 'suurempi kuin, mutta ei yhtä suuri kuin') + - "≪": # 0x226a + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "paljon pienempi kuin" # (en: 'much less than', google: 'paljon vähemmän kuin') + - "≫": # 0x226b + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "paljon suurempi kuin" # (en: 'much greater than') + - "≬": # 0x226c + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "välissä" # (en: 'between', google: 'välillä') + - "≭": # 0x226d + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei yhtäpitävä" # (en: 'not equivalent to', google: 'ei vastaa') + - "≮": # 0x226e + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei aidosti pienempi kuin" # (en: 'not less than', google: 'ei vähempää kuin') + - "≯": # 0x226f + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei aidosti suurempi kuin" # (en: 'not greater than', google: 'enintään') + - "≰": # 0x2270 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei pienempi eikä yhtäsuuri kuin" # (en: 'neither less than nor equal to', google: 'ei vähemmän kuin yhtä suuri kuin') + - "≱": # 0x2271 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei suurempi eikä yhtäsuuri kuin" # (en: 'neither greater than nor equal to', google: 'ei suurempi kuin yhtä suuri kuin') + - "≲": # 0x2272 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "pienempi tai yhtäpitävä" # (en: 'less than or equivalent to', google: 'vähemmän tai vastaavat') + - "≳": # 0x2273 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "suurempi tai yhtäpitävä" # (en: 'greater than or equivalent to', google: 'suurempi tai vastaa') + - "≴": # 0x2274 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei pienempi eikä yhtäpitävä" # (en: 'neither less than nor equivalent to', google: 'ei vähemmän kuin vastaa') + - "≵": # 0x2275 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei suurempi eikä yhtäpitävä" # (en: 'neither greater than nor equivalent to', google: 'ei suurempi kuin vastaava') + - "≶": # 0x2276 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "aidosti pienempi tai suurempi kuin" # (en: 'less than or greater than', google: 'vähemmän tai suurempi kuin') + - "≷": # 0x2277 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "aidosti suurempi tai pienempi kuin" # (en: 'greater than or less than', google: 'suurempi tai vähemmän kuin') + - "≸": # 0x2278 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei aidosti pienempi eikä suurempi kuin" # (en: 'neither less than nor greater than', google: 'ei vähemmän kuin suurempi kuin') + - "≹": # 0x2279 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei aidosti suurempi eikä pienempi kuin" # (en: 'neither greater than nor less than', google: 'ei suurempi kuin vähemmän kuin') + - "≺": [T: "edeltää"] # 0x227a (en: 'precedes') + - "≻": [T: "seuraa"] # 0x227b (en: 'succeeds', google: 'onnistuu') + - "≼": [T: "edeltää tai on yhtä kuin"] # 0x227c (en: 'precedes or is equal to', google: 'edeltää tai on yhtä suuri kuin') + - "≽": [T: "seuraa tai on yhtä kuin"] # 0x227d (en: 'succeeds or is equal to', google: 'onnistuu tai on yhtä suuri') + - "≾": [T: "edeltää tai on yhtäpitävä"] # 0x227e (en: 'precedes or is equivalent to', google: 'edeltää tai vastaa') + - "≿": [T: "seuraa tai on yhtäpitävä"] # 0x227f (en: 'succeeds or is equivalent to', google: 'onnistuu tai vastaa') + - "⊀": [T: "ei edellä"] # 0x2280 (en: 'does not precede', google: 'ei edeltä') + - "⊁": [T: "ei seuraa"] # 0x2281 (en: 'does not succeed', google: 'ei onnistu') + - "⊈": # 0x2288 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei osajoukko eikä yhtä kuin" # (en: 'neither a subset of nor equal to', google: 'ei alajoukko eikä yhtä suuri kuin') + - "⊉": # 0x2289 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei sisällä osajoukkoa eikä yhtä kuin" # (en: 'neither a superset of nor equal to', google: 'ei ylenmääräinen eikä yhtä suuri kuin') + - "⊊": [T: "on aito osajoukko"] # 0x228a (en: 'subset of with not equal to', google: 'osajoukko, joka ei ole yhtä suuri kuin') + - "⊋": [T: "sisältää aidon osajoukon"] # 0x228b (en: 'superset of with not equal to', google: 'superset of with ei ole yhtä suuri kuin') + - "⊌": [T: "monijoukko"] # 0x228c (en: 'multiset', google: 'multiset') + - "⊍": [T: "monijoukkojen kerto"] # 0x228d (en: 'multiset multiplication', google: 'multiset -kertolasku') + - "⊎": [T: "monijoukkojen unioni"] # 0x228e (en: 'multiset union', google: 'multiset union') + - "⊏": [T: "kulmikas relaatio"] # 0x228f (en: 'square image of', google: 'neliökuva') + - "⊐": [T: "käänteinen kulmikas relaatio"] # 0x2290 (en: 'square original of', google: 'neliön alkuperäinen') + - "⊑": [T: "kulmikas relaatio tai yhtä kuin"] # 0x2291 (en: 'square image of or equal to', google: 'neliökuva tai yhtä suuri kuin') + - "⊒": [T: "käänteinen kulmikas relaatio tai yhtä suuri kuin"] # 0x2292 (en: 'square original of or equal to', google: 'neliön alkuperäinen tai yhtä suuri kuin') + - "⊓": [T: "kulmikas kupu"] # 0x2293 (en: 'square cap', google: 'neliö -isot') + - "⊔": [T: "kulmikas malja"] # 0x2294 (en: 'square cup', google: 'square cup') + - "⊕": [T: "ympyröity plus"] # 0x2295 (en: 'circled plus') + - "⊖": [T: "ympyröity miinus"] # 0x2296 (en: 'circled minus') + - "⊗": [T: "ympyröity kertaa"] # 0x2297 (en: 'circled times', google: 'ympyräajat') + - "⊘": [T: "ympyröity jakoviiva"] # 0x2298 (en: 'circled slash', google: 'ympyräviiva') + - "⊙": [T: "ympyröity piste"] # 0x2299 (en: 'circled dot operator', google: 'ympyräpisteoperaattori') + - "⊚": [T: "ympyröity pallo"] # 0x229a (en: 'circled ring', google: 'ympyrä rengas') + - "⊛": [T: "ympyröity tähti"] # 0x229b (en: 'circled asterisk', google: 'ympyrä tähdellä') + - "⊜": [T: "ympyröity yhtä kuin"] # 0x229c (en: 'circled equals', google: 'ympyröity tasa -arvoinen') + - "⊝": [T: "ympyröity viiva"] # 0x229d (en: 'circled dash') + - "⊞": [T: "neliöity plus"] # 0x229e (en: 'squared plus', google: 'squared plus') + - "⊟": [T: "neliöity miinus"] # 0x229f (en: 'squared minus', google: 'neliö miinus') + - "⊠": [T: "neliöity kertaa"] # 0x22a0 (en: 'squared times', google: 'neliöajat') + - "⊡": [T: "neliöity piste"] # 0x22a1 (en: 'squared dot operator', google: 'squared dot -operaattori') + - "⊢": [T: "oikealle osoittava nupi"] # 0x22a2 (en: 'proves', google: 'todistaa') + - "⊣": [T: "vasemmalle osoittava nupi"] # 0x22a3 (en: 'does not yield', google: 'ei tuota') + - "⊤": [T: "alas osoittava nupi"] # 0x22a4 (google: 'ylhäältä') + - "⊥": # 0x22a5 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "ylös osoittava nupi" # (google: 'pohja') + - "⊦": [T: "assertio"] # 0x22a6 (en: 'reduces to', google: 'vähentää') + - "⊧": [T: "toteuttaa mallina"] # 0x22a7 (en: 'models', google: 'malleja') + - "⊨": # 0x22a8 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "tosi" # (en: 'true', google: 'totta') + - "⊩": [T: "pakottaa"] # 0x22a9 (en: 'forces', google: 'voimat') + - "⊪": [T: "kolmoispystyviiva ja oikeanpuoleinen kääntöportti"] # 0x22aa (en: 'triple vertical bar right turnstile', google: 'kolminkertainen pystysuora palkki oikean kääntölaite') + - "⊫": [T: "kaksoispystyviiva ja oikeanpuoleinen kaksoiskääntöportti"] # 0x22ab (en: 'double vertical bar double right turnstile', google: 'kaksois pystysuora palkki kaksinkertainen oikea käänne') + - "⊬": [T: "ei todista"] # 0x22ac (en: 'does not prove', google: 'ei todista') + - "⊭": # 0x22ad + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "epätosi" # (en: 'not true', google: 'ei totta') + - "⊮": [T: "ei pakota"] # 0x22ae (en: 'does not force', google: 'ei pakota') + - "⊯": [T: "ei kaksoispystyviiva ja oikeanpuolenen kaksoiskääntöportti"] # 0x22af (en: 'negated double vertical bar double right turnstile', google: 'kielteinen kaksinkertainen pystysuora palkki kaksinkertainen oikea käänne') + - "⊰": [T: "edeltää relaatiossa"] # 0x22b0 (en: 'precedes under relation', google: 'edeltää suhteessa') + - "⊱": [T: "seuraa relaatiossa"] # 0x22b1 (en: 'succeeds under relation', google: 'onnistuu suhteessa') + - "⊲": # 0x22b2 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "normaali aliryhmä" # (en: 'a normal subgroup of', google: 'normaali alaryhmä') + - "⊳": [T: "sisältää normaalin aliryhmän"] # 0x22b3 (en: 'contains as a normal subgroup', google: 'sisältää normaalina alaryhmänä') + - "⊴": # 0x22b4 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "normaali aliryhmä tai yhtä kuin" # (en: 'a normal subgroup of or equal to', google: 'normaali alaryhmä tai yhtä suuri') + - "⊵": [T: "sisältää normaalin aliryhmän tai on yhtä kuin"] # 0x22b5 (en: 'contains as a normal subgroup or equal to', google: 'sisältää normaalina alaryhmänä tai yhtä suuri kuin') + - "⊶": # 0x22b6 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "alkukuva" # (en: 'the original of', google: 'alkuperäinen') + - "⊷": # 0x22b7 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "kuva" # (en: 'an image of', google: 'kuva') + - "⊸": [T: "monikuvaus"] # 0x22b8 + - "⊹": [T: "Hermiten konjugaattimatriisi"] # 0x22b9 (en: 'hermitian conjugate matrix', google: 'hermitian konjugaattimatriisi') + - "⊺": [T: "interkalaatio"] # 0x22ba (google: 'interkalaatti') + - "⊻": [T: "joko tai"] # 0x22bb + - "⊼": [T: "ja ei"] # 0x22bc + - "⊽": [T: "tai ei"] # 0x22bd (google: 'ei myöskään') + - "⊾": [T: "suora kulma kaarella"] # 0x22be (en: 'right angle with arc', google: 'suorakulma kaarilla') + - "⊿": [T: "oikeanpuoleinen kolmio"] # 0x22bf (en: 'right triangle') + - "⋀": [T: "monikkokonjuktio"] # 0x22c0 (en: 'logical and', google: 'looginen ja') + - "⋁": [T: "monikkodisjunktio"] # 0x22c1 (en: 'logical or', google: 'looginen tai') + - "⋂": [T: "monikkoleikkaus"] # 0x22c2 (en: 'intersection', google: 'risteys') + - "⋃": [T: "monikkounioni"] # 0x22c3 (en: 'union', google: 'liitto') + - "⋄": [T: "timantti"] # 0x22c4 (en: 'diamond operator', google: 'timanttioperaattori') + - "⋅": # 0x22c5 + - test: + if: "@data-chem-formula-op" + then: [T: "piste"] # (en: 'dot', google translation) + else: [T: "kertaa"] # (en: 'times', google: 'ajat') + + - "⋆": [T: "kertaa"] # 0x22c6 (en: 'times', google: 'ajat') + - "⋇": [T: "jako kertaa"] # 0x22c7 (en: 'division times', google: 'jako -ajat') + - "⋈": [T: "rusetti"] # 0x22c8 (en: 'bowtie', google: 'rusetti') + - "⋉": # 0x22c9 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "vasemmanpuoleinen normaalitekijäinen puolisuora tulo" # (en: 'the left normal factor semidirect product of', google: 'vasen normaali tekijä semidirect -tuote') + - "⋊": # 0x22ca + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "oikeanpuoleinen normaalitekijäinen puolisuora tulo" # (en: 'the right normal factor semidirect product of', google: 'oikea normaali tekijä semidirect -tuote') + - "⋋": # 0x22cb + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "vasemmanpuoleinen puolisuora tulo" # (en: 'the left semidirect product of', google: 'vasen puolisirektin tuote') + - "⋌": # 0x22cc + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "oikeanpuoleinen puolisuora tulo" # (en: 'the right semidirect product of', google: 'oikea semidirect -tuote') + - "⋍": [T: "käänteinen tilde yhtäsuuruus"] # 0x22cd (en: 'reversed tilde equals', google: 'käänteinen tilde on tasa -arvoinen') + - "⋎": [T: "kaareva looginen tai"] # 0x22ce (en: 'curly logical or', google: 'kihara looginen tai') + - "⋏": [T: "kaareva looginen ja"] # 0x22cf (en: 'curly logical and', google: 'curly looginen ja') + - "⋐": # 0x22d0 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "kaksoisosajoukko" # (en: 'a double subset of', google: 'kaksinkertainen osajoukko') + - "⋑": # 0x22d1 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "kaksoisylijoukko" # (en: 'a double superset of', google: 'kaksinkertainen superset') + - "⋒": # 0x22d2 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (google translation) + - T: "kaksoisleikkaus" # (en: 'double intersection of', google: 'kaksinkertainen risteys') + - "⋓": # 0x22d3 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (google translation) + - T: "kaksoisunioni" # (en: 'double union of', google: 'kaksinkertainen liitto') + - "⋔": # 0x22d4 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (google translation) + - T: "hanko" # (en: 'proper intersection of', google: 'oikea risteys') + - "⋕": # 0x22d5 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "yhtäsuuri ja yhdensuuntainen" # (en: 'equal to and parallel to', google: 'yhtä suuri kuin sen kanssa ja yhdensuuntainen') + - "⋖": [T: "piste pienempi kuin"] # 0x22d6 (en: 'less than with dot', google: 'vähemmän kuin pisteellä') + - "⋗": [T: "piste suurempi kuin"] # 0x22d7 (en: 'greater than with dot', google: 'suurempi kuin pisteellä') + - "⋘": # 0x22d8 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "hyvin paljon pienempi kuin" # (en: 'very much less than', google: 'hyvin vähemmän kuin') + - "⋙": # 0x22d9 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "hyvin paljon suurempi kuin" # (en: 'very much greater than', google: 'erittäin suurempi kuin') + - "⋚": # 0x22da + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "pienempi, yhtäsuuri tai suurempi kuin" # (en: 'less than equal to or greater than', google: 'vähemmän kuin yhtä suuri tai suurempi kuin') + - "⋛": # 0x22db + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "suurempi, yhtäsuuri tai pienempi kuin" # (en: 'greater than equal to or less than', google: 'suurempi kuin yhtä suuri tai vähemmän kuin') + - "⋜": # 0x22dc + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "yhtäsuuri tai pienempi kuin" # (en: 'equal to or less than', google: 'yhtä suuri tai vähemmän kuin') + - "⋝": # 0x22dd + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "yhtäsuuri tai suurempi kuin" # (en: 'equal to or greater than', google: 'yhtä suuri tai suurempi kuin') + - "⋞": # 0x22de + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "yhtä kuin tai edeltää" # (en: 'equal to or precedes', google: 'yhtä suuri tai edeltää') + - "⋟": # 0x22df + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "yhtä kuin tai seuraa" # (en: 'equal to or succeeds', google: 'yhtä suuri tai onnistuu') + - "⋠": [T: "ei edellä eikä yhtä kuin"] # 0x22e0 (en: 'does not precede nor is equal to', google: 'ei edeltä eikä ole yhtä suuri kuin') + - "⋡": [T: "ei seuraa eikä yhtä kuin"] # 0x22e1 (en: 'does not succeed nor is equal to', google: 'ei onnistu eikä ole yhtä suuri kuin') + - "⋢": [T: "ei kulmikas relaatio tai yhtä suuri kuin"] # 0x22e2 (en: 'not square image of or equal to', google: 'ei neliökuva tai yhtä suuri kuin') + - "⋣": [T: "ei käänteinen kulmikas relaatio tai yhtä suuri kuin"] # 0x22e3 (en: 'not square original of or equal to', google: 'ei neliömäinen alkuperäinen tai yhtä suuri kuin') + - "⋤": [T: "kulmikas relaatio ja ei yhtä suuri kuin"] # 0x22e4 (en: 'square image of or not equal to', google: 'neliökuva tai ei ole yhtä suuri kuin') + - "⋥": [T: "kulmikas käänteinen relaatio ja ei yhtä suuri kuin"] # 0x22e5 (en: 'square original of or not equal to', google: 'neliön alkuperäinen tai ei ole yhtä suuri kuin') + - "⋦": # 0x22e6 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "pienempi kuin mutta ei ekvivalentti" # (en: 'less than but not equivalent to', google: 'vähemmän kuin, mutta ei vastaava') + - "⋧": # 0x22e7 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "suurempi kuin mutta ei ekvivalentti" # (en: 'greater than but not equivalent to', google: 'suurempi kuin mutta ei vastaa') + - "⋨": [T: "edeltää mutta ei ole ekvivalentti"] # 0x22e8 (en: 'precedes but is not equivalent to', google: 'edeltää, mutta ei vastaa') + - "⋩": [T: "seuraa mutta ei ole ekvivalentti"] # 0x22e9 (en: 'succeeds but is not equivalent to', google: 'onnistuu, mutta ei vastaa') + - "⋪": # 0x22ea + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei ole normaali aliryhmä" # (en: 'not a normal subgroup of', google: 'ei normaali alaryhmä') + - "⋫": [T: "ei sisällä normaalia aliryhmää"] # 0x22eb (en: 'does not contain as a normal subgroup', google: 'ei sisällä normaalia alaryhmää') + - "⋬": # 0x22ec + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei ole normaali aliryhmä tai yhtä kuin" # (en: 'not a normal subgroup of nor is equal to', google: 'ei normaali alaryhmä, joka ei ole yhtä suuri') + - "⋭": [T: "ei sisällä normaalina aliryhmänä tai ole yhtä kuin"] # 0x22ed (en: 'does not contain as a normal subgroup nor is equal to', google: 'ei sisällä normaalia alaryhmää eikä ole yhtä suuri kuin') + - "⋮": [T: "pystyellipsi"] # 0x22ee (en: 'vertical ellipsis', google: 'pystysuora ellipsis') # FI: context? used in matrices? + - "⋯": [T: "piste piste piste"] # 0x22ef (en: 'dot dot dot', google: 'dot dot dot') + - "⋰": [T: "nouseva ellipsi"] # 0x22f0 (en: 'upwards diagonal ellipsis', google: 'ylöspäin diagonaalinen ellipsi') # FI: context? used in matrices? + - "⋱": [T: "laskeva ellipsi"] # 0x22f1 (en: 'diagonal ellipsis', google: 'diagonaalinen ellipsis') # FI: context? used in matrices? + - "⋲": [T: "poikkiviivainen kuulumismerkki"] # 0x22f2 (en: 'element of with long horizontal stroke', google: 'elementti pitkällä vaakasuoralla iskulla') + - "⋳": [T: "kuulumismerkki pystyviivaan päättyvällä poikkiviivalla"] # 0x22f3 (en: 'element of with vertical bar at end of horizontal stroke', google: 'elementti pystysuoralla tankolla vaakasuoran iskun lopussa') + - "⋴": [T: "pieni kuulumismerkki pystyviivaan päättyvällä poikkiviivalla"] # 0x22f4 (en: 'element of with vertical bar at end of horizontal stroke', google: 'elementti pystysuoralla tankolla vaakasuoran iskun lopussa') + - "⋵": [T: "kuuluu joukkoon pisteellä"] # 0x22f5 (en: 'element of with dot above', google: 'elementti yllä olevalla pisteellä') + - "⋶": [T: "kuuluu joukkoon yläviivalla"] # 0x22f6 (en: 'element of with overbar', google: 'elementti ylikuormituksella') + - "⋷": [T: "pieni kuuluu joukkoon yläviivalla"] # 0x22f7 (en: 'element of with overbar', google: 'elementti ylikuormituksella') + - "⋸": [T: "kuuluu joukkoon alaviivalla"] # 0x22f8 (en: 'element of with underbar', google: 'elementti alakerroksella') + - "⋹": [T: "kuuluu joukkoon kaksoispoikkiviivalla"] # 0x22f9 (en: 'element of with two horizontal strokes', google: 'elementti kahdella vaakasuuntaisella iskulla') + - "⋺": [T: "käänteinen kuuluu joukkoon poikkiviivalla"] # 0x22fa (en: 'contains with long horizontal stroke', google: 'sisältää pitkällä vaakasuoralla iskulla') + - "⋻": [T: "käänteinen kuuluu joukkoon pystyviivaan päättyvällä poikkiviivalla"] # 0x22fb (en: 'contains with vertical bar at end of horizontal stroke', google: 'sisältää pystysuoran palkin vaakasuoran iskun lopussa') + - "⋼": [T: "pieni käänteinen kuuluu joukkoon pystyviivaan päättyvällä poikkiviivalla"] # 0x22fc (en: 'contains with vertical bar at end of horizontal stroke', google: 'sisältää pystysuoran palkin vaakasuoran iskun lopussa') + - "⋽": [T: "sisältää tai on yhtä suuri kuin"] # 0x22fd (en: 'contains with overbar', google: 'sisältää ylikuormituksen kanssa') + - "⋾": [T: "pieni sisältää tai on yhtä suuri kuin"] # 0x22fe (en: 'contains with overbar', google: 'sisältää ylikuormituksen kanssa') + - "⋿": [T: "Z-notaation laukkuun kuulumisen merkki"] # 0x22ff (google: 'z -merkintälaukun jäsenyys') + - "⌀": [T: "halkaisija"] # 0x2300 (en: 'diameter') + - "⌁": [T: "sähkönuoli"] # 0x2301 (en: 'electric arrow', google translation) + - "⌂": [T: "talo"] # 0x2302 (en: 'house') + - "⌃": [T: "nuolenpää ylös"] # 0x2303 (en: 'up arrowhead', google translation) + - "⌄": [T: "nuolenpää alas"] # 0x2304 (en: 'down arrowhead', google translation) + - "⌅": [T: "projektio"] # 0x2305 (en: 'projective', google: 'projektiivinen') + - "⌆": [T: "perspektiivi"] # 0x2306 (en: 'perspective', google: 'näkökulma') + - "⌇": [T: "aaltoviiva"] # 0x2307 (en: 'wavy line', google translation) + - "⌈": [T: "vasen katto"] # 0x2308 (en: 'left ceiling') + - "⌉": [T: "oikea katto"] # 0x2309 (en: 'right ceiling') + - "⌊": [T: "vasen lattia"] # 0x230a (en: 'left floor') + - "⌋": [T: "oikea lattia"] # 0x230b (en: 'right floor', google: 'oikea kerros') + - "⌌": [T: "oikea alanurkkarajaus"] # 0x230c (en: 'bottom right crop', google: 'oikea alareuna') + - "⌍": [T: "vasen alanurkkarajaus"] # 0x230d (en: 'bottom left crop', google: 'vasen alakulma') + - "⌎": [T: "oikea ylänurkkarajaus"] # 0x230e (en: 'top right crop', google: 'oikea yläosa') + - "⌏": [T: "vasen ylänurkkarajaus"] # 0x230f (en: 'top left crop', google: 'vasen yläosa sato') + - "⌐": [T: "käännetty negaatio"] # 0x2310 (en: 'reversed not sign', google: 'kääntynyt ei allekirjoitettu') + - "⌑": [T: "tyynysymboli"] # 0x2311 (google translation) + - "⌒": [T: "yläkaari"] # 0x2312 (en: 'arc', google: 'kaari') + - "⌓": [T: "segmentti"] # 0x2313 (en: 'segment') + - "⌔": [T: "sektori"] # 0x2314 (en: 'sector', google translation) + - "⌕": [T: "suurennuslasi"] # 0x2315 (google: 'puhelintallistin') + - "⌖": [T: "tähtäin"] # 0x2316 (en: 'position indicator crosshairs', google: 'aseman ilmaisimen ristikkäit') + - "⌗": [T: "risuaita"] # 0x2317 (en: 'viewdata square', google translation) + - "⌘": [T: "hannunvaakuna"] # 0x2318 (en: 'place of interest sign', google: 'kiinnostuksen kohteena oleva merkki') + - "⌙": [T: "kääntynyt negaatio"] # 0x2319 (en: 'turned not sign', google translation) + - "⌚": [T: "kello"] # 0x231a (en: 'watch', google: 'katsella') + - "⌛": [T: "tiimalasi"] # 0x231b (en: 'hourglass', google translation) + - "⌜": [T: "vasen ylänurkka"] # 0x231c (en: 'top left corner', google: 'vasen yläkulma') + - "⌝": [T: "oikea ylänurkka"] # 0x231d (en: 'top right corner', google: 'oikea yläkulma') + - "⌞": [T: "vasen alanurkka"] # 0x231e (en: 'bottom left corner', google: 'vasen alakulma') + - "⌟": [T: "oikea alanurkka"] # 0x231f (en: 'bottom right corner', google: 'oikea alakulma') + - "⌠": [T: "integraalin yläpuoli"] # 0x2320 (en: 'top half integral', google: 'top -puoliksi olennainen') + - "⌡": [T: "integraalin alapuoli"] # 0x2321 (en: 'bottom half integral', google: 'pohjapuoliskon integraali') + - "⌢": [T: "yläkaari"] # 0x2322 (en: 'frown', google: 'kulma') + - "⌣": [T: "alakaari"] # 0x2323 (en: 'smile', google: 'hymy') + - "⌤": [T: "nuolenpää ylös kahden vaakasuoran palkin välissä"] # 0x2324 (en: 'up arrowhead between two horizontal bars', google translation) + - "⌥": [T: "option"] # 0x2325 (en: 'option key', google translation) + - "⌦": [T: "poista oikealle"] # 0x2326 (en: 'erase to the right', google translation) + - "⌧": [T: "suorakulmiossa oleva rasti"] # 0x2327 (en: 'x in a rectangle box', google translation) + - "⌨": [T: "näppäimistö"] # 0x2328 (en: 'keyboard', google translation) + - "〈": [T: "vasen kulmasulku"] # 0x2329 (en: 'left pointing angle bracket', google: 'vasen osoituskulmakiinnike') + - "〉": [T: "oikea kulmasulku"] # 0x232a (en: 'right pointing angle bracket', google: 'oikea osoituskulmakiinnike') + - "⌫": [T: "poista vasemmalle"] # 0x232b (en: 'erase to the left', google translation) + - "⌬": [T: "bentseenirengas"] # 0x232c (en: 'benzene ring', google translation) + - "⌭": [T: "sylinterisyys"] # 0x232d (google: 'sylinteryys') + - "⌮": [T: "profiilin ympäri"] # 0x232e (en: "all around profile" google: 'ympäri profiilia') # FI: translation unclear + - "⌯": [T: "symmetria"] # 0x232f (en: 'symmetry', google translation) + - "⌰": [T: "toleranssin yhteissumma"] # 0x2330 (en: 'total runout', google translation) # FI: meaning bit unclear, placeholder for correct + - "⌱": [T: "alkudimensio"] # 0x2331 (en: 'dimension origin', google translation) # FI: translation unclear + - "⌲": [T: "kartiovähentyminen"] # 0x2332 (en: 'conical taper', google translation) # FI: translation unclear + - "⌳": [T: "kaltevuus"] # 0x2333 (en: 'slope', google translation) + - "⌴": [T: "tasoupotin"] # 0x2334 (en: 'counterbore', google translation) + - "⌵": [T: "kärkiupotin"] # 0x2335 (en: 'countersink', google translation) + - "⍰": [T: "kysymysmerkki laatikossa"] # 0x2370 (en: 'unknown box', google: 'tuntematon laatikko') + - "⎕": [T: "laatikko"] # 0x2395 (en: 'box', google translation) + - "⏞": [T: "yläaaltosulku"] # 0x23DE (en: 'top brace', google: 'ylä ahdin') + - "⏟": [T: "ala-aaltosulku"] # 0x23DF (en: 'bottom brace', google: 'pohja ahdin') + - "①-⑨": # 0x2460 - 0x2469 + - T: "ympyröity" # (en: 'circled', google: 'ympyröi') + - SPELL: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" + - "⑩": [T: "ympyröity kymmenen"] # 0x2469 (en: 'circled ten', google translation) + - "⑪": [T: "ympyröity yksitoista"] # 0x246a (en: 'circled eleven', google translation) + - "⑫": [T: "ympyröity kaksitoista"] # 0x246b (en: 'circled twelve', google translation) + - "⑬": [T: "ympyröity kolmetoista"] # 0x246c (en: 'circled thirteen', google translation) + - "⑭": [T: "ympyröity neljätoista"] # 0x246d (en: 'circled fourteen', google translation) + - "⑮": [T: "ympyröity viisitoista"] # 0x246e (en: 'circled fifteen', google translation) + - "⑯": [T: "ympyröity kuusitoista"] # 0x246f (en: 'circled sixteen', google translation) + - "⑰": [T: "ympyröity seitsemäntoista"] # 0x2470 (en: 'circled seventeen', google translation) + - "⑱": [T: "ympyröity kahdeksantoista"] # 0x2471 (en: 'circled eighteen', google translation) + - "⑳": [T: "ympyröity kaksikymmentä"] # 0x2473 (en: 'circled twenty', google translation) + - "⑴-⑼": # 0x2474 - 0x247d + - T: "suluissa" # (en: 'parenthesized', google translation) + - SPELL: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" + - "⑽": [T: "suluissa kymmenen"] # 0x247d (en: 'parenthesized ten', google translation) + - "⑾": [T: "suluissa yksitoista"] # 0x247e (en: 'parenthesized eleven', google translation) + - "⑿": [T: "suluissa kaksitoista"] # 0x247f (en: 'parenthesized twelve', google translation) + - "⒀": [T: "suluissa kolmetoista"] # 0x2480 (en: 'parenthesized thirteen', google translation) + - "⒁": [T: "suluissa neljätoista"] # 0x2481 (en: 'parenthesized fourteen', google translation) + - "⒂": [T: "suluissa viisitoista"] # 0x2482 (en: 'parenthesized fifteen', google translation) + - "⒃": [T: "suluissa kuusitoista"] # 0x2483 (en: 'parenthesized sixteen', google translation) + - "⒄": [T: "suluissa seitsemäntoista"] # 0x2484 (en: 'parenthesized seventeen', google translation) + - "⒅": [T: "suluissa kahdeksantoista"] # 0x2485 (en: 'parenthesized eighteen', google translation) + - "⒆": [T: "suluissa yhdeksäntoista"] # 0x2486 (en: 'parenthesized nineteen', google translation) + - "⒇": [T: "suluissa kaksikymmentä"] # 0x2487 (en: 'parenthesized twenty', google translation) + - "⒈-⒐": # 0x2488 - 0x2491 # FI: should these be ordinals? + - SPELL: "translate('.', '⒈⒉⒊⒋⒌⒍⒎⒏⒐', '123456789')" + - T: "pisteellä" # (en: 'with period', google translation) + - "⒑": [T: "kymmenen pisteellä"] # 0x2491 (en: 'ten with period', google translation) + - "⒒": [T: "yksitoista pisteellä"] # 0x2492 (en: 'eleven with period', google translation) + - "⒓": [T: "kaksitoista pisteellä"] # 0x2493 (en: 'twelve with period', google translation) + - "⒔": [T: "kolmetoista pisteellä"] # 0x2494 (en: 'thirteen with period', google translation) + - "⒕": [T: "neljätoista pisteellä"] # 0x2495 (en: 'fourteen with period', google translation) + - "⒖": [T: "viisitoista pisteellä"] # 0x2496 (en: 'fifteen with period', google translation) + - "⒗": [T: "kuusitoista pisteellä"] # 0x2497 (en: 'sixteen with period', google translation) + - "⒘": [T: "seitsemäntoista pisteellä"] # 0x2498 (en: 'seventeen with period', google translation) + - "⒙": [T: "kahdeksantoista pisteellä"] # 0x2499 (en: 'eighteen with period', google translation) + - "⒚": [T: "yhdeksäntoista pisteellä"] # 0x249a (en: 'nineteen with period', google translation) + - "⒛": [T: "kaksikymmentä pisteellä"] # 0x249b (en: 'twenty with period', google translation) + - "⒜-⒵": # 0x249c - 0x24b5 + - T: "suluissa" # (en: 'parenthesized', google translation) + - SPELL: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" + + - "Ⓐ-Ⓩ": + - T: "ympyröity" # (en: 'circled', google translation) + - SPELL: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "🅐-🅩": # 0x1f150 - 0x1f169 + - T: "musta ympyröity" # (en: 'black circled', google translation) + - SPELL: "translate('.', '🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 + - T: "ympyröity" # (en: 'circled', google translation) + - SPELL: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" + - "⓪": [T: "ympyröity nolla"] # 0x24ea (en: 'circled zero', google translation) + - "⓫": [T: "musta ympyröity yksitoista"] # 0x24eb (en: 'black circled eleven', google translation) + - "⓬": [T: "musta ympyröity kaksitoista"] # 0x24ec (en: 'black circled twelve', google translation) + - "⓭": [T: "musta ympyröity kolmetoista"] # 0x24ed (en: 'black circled thirteen', google translation) + - "⓮": [T: "musta ympyröity neljätoista"] # 0x24ee (en: 'black circled fourteen', google translation) + - "⓯": [T: "musta ympyröity viisitoista"] # 0x24ef (en: 'black circled fifteen', google translation) + - "⓰": [T: "musta ympyröity kuusitoista"] # 0x24f0 (en: 'black circled sixteen', google translation) + - "⓱": [T: "musta ympyröity seitsemäntoista"] # 0x24f1 (en: 'black circled seventeen', google translation) + - "⓲": [T: "musta ympyröity kahdeksantoista"] # 0x24f2 (en: 'black circled eighteen', google translation) + - "⓳": [T: "musta ympyröity yhdeksäntoista"] # 0x24f3 (en: 'black circled nineteen', google translation) + - "⓴": [T: "musta ympyröity kaksikymmentä"] # 0x24f4 (en: 'black circled twenty', google translation) + - "⓵-⓽": # 0x24f5 - 0x24fe + - T: "kaksinkertaisesti ympyröity" # (en: 'double circled', google translation) + - SPELL: "translate('.', '⓵⓶⓷⓸⓹⓺⓻⓼⓽', '123456789')" + - "⓾": [T: "kaksinkertaisesti ympyröity kymmenen"] # 0x24fe (en: 'double circled ten', google translation) + - "⓿": [T: "musta ympyröity nolla"] # 0x24ff (en: 'black circled zero', google translation) + - "■": [T: "musta neliö"] # 0x25a0 (en: 'black square') + - "□": [T: "valkoinen neliö"] # 0x25a1 (en: 'white square') + - "▢": [T: "pyöreäkulmainen valkoinen neliö"] # 0x25a2 (en: 'white square with rounded corners', google translation) + - "▣": [T: "mustan neliön sisältävä valkoinen neliö"] # 0x25a3 (en: 'white square containing small black square', google translation) + - "▤": [T: "neliö vaakasuoralla värityksellä"] # 0x25a4 (en: 'square with horizontal fill', google translation) + - "▥": [T: "neliö pystysuoralla värityksellä"] # 0x25a5 (en: 'square with vertical fill', google translation) + - "▦": [T: "neliö ruudukkovärityksellä"] # 0x25a6 (en: 'square with orthogonal crosshatch fill', google translation) + - "▧": [T: "neliö värityksellä ylävasemmalta alaoikelle"] # 0x25a7 (en: 'square with upper left to lower right fill', google translation) + - "▨": [T: "neliö värityksellä yläoikealta alavasemmalle"] # 0x25a8 (en: 'square with upper right to lower left fill', google translation) + - "▩": [T: "neliö diagonaalisella ristikkovärityksellä"] # 0x25a9 (en: 'square with diagonal crosshatch fill', google translation) + - "▪": [T: "pieni musta neliö"] # 0x25aa (en: 'black small square', google: 'musta pieni neliö') + - "▫": [T: "pieni valkoinen neliö"] # 0x25ab (en: 'white small square', google: 'valkoinen pieni neliö') + - "▬": [T: "musta suorakaide"] # 0x25ac (en: 'black rectangle', google translation) + - "▭": [T: "valkoinen suorakaide"] # 0x25ad (en: 'white rectangle', google: 'valkoinen suorakulmio') + - "▮": [T: "musta pysty suorakaide"] # 0x25ae (en: 'black vertical rectangle', google: 'musta pystysuora suorakulmio') + - "▯": [T: "valkoinen pysty suorakaide"] # 0x25af (en: 'white vertical rectangle', google: 'valkoinen pystysuora suorakulmio') + - "▰": [T: "musta suunnikas"] # 0x25b0 (en: 'black parallelogram', google translation) + - "▱": [T: "valkoinen suunnikas"] # 0x25b1 (en: 'white parallelogram', google: 'valkoinen rinnakkainen ohjelma') + - "▲": [T: "musta ylös osoittava kolmio"] # 0x25b2 (en: 'black up pointing triangle', google: 'musta ylöspäin osoittava kolmio') + - "△": [T: "valkoinen ylös osoittava kolmio"] # 0x25b3 (en: 'white up pointing triangle', google: 'valkoinen osoitus kolmio') + - "▴": [T: "pieni musta ylös osoittava kolmio"] # 0x25b4 (en: 'black up pointing small triangle', google: 'musta ylös osoittaen pientä kolmiota') + - "▵": [T: "pieni valkoinen ylös osoittava kolmio"] # 0x25b5 (en: 'white up pointing small triangle', google: 'valkoinen osoittaen pientä kolmiota') + - "▶": [T: "musta oikealle osoittava kolmio"] # 0x25b6 (en: 'black right pointing triangle', google: 'musta oikea osoitus kolmio') + - "▷": [T: "valkoinen oikealle osoittava kolmio"] # 0x25b7 (en: 'white right pointing triangle', google: 'valkoinen oikea osoitus kolmio') + - "▸": [T: "pieni musta oikealle osoittava kolmio"] # 0x25b8 (en: 'black right pointing small triangle', google: 'musta oikea osoittaen pieni kolmio') + - "▹": [T: "pieni valkoinen oikealle osoittava kolmio"] # 0x25b9 (en: 'white right pointing small triangle', google: 'valkoinen oikea osoittaen pieni kolmio') + - "►": [T: "musta oikea osoitin"] # 0x25ba (en: 'black right pointing pointer', google translation) + - "▻": [T: "valkoinen oikea osoitin"] # 0x25bb (en: 'white right pointing pointer', google translation) + - "▼": [T: "musta alas osoittava kolmio"] # 0x25bc (en: 'black down pointing triangle', google: 'musta alaspäin osoittava kolmio') + - "▽": [T: "valkoinen alas osoittava kolmio"] # 0x25bd (en: 'white down pointing triangle', google: 'valkoinen alaspäin osoittava kolmio') + - "▾": [T: "pieni musta alas osoittava kolmio"] # 0x25be (en: 'black down pointing small triangle', google: 'musta alaspäin osoittaen pieni kolmio') + - "▿": [T: "pieni valkoinen alas osoittava kolmio"] # 0x25bf (en: 'white down pointing small triangle', google: 'valkoinen alas osoittaen pieni kolmio') + - "◀": [T: "musta vasemmalle osoittava kolmio"] # 0x25c0 (en: 'black left pointing triangle', google: 'musta vasen osoitus kolmio') + - "◁": [T: "valkoinen vasemmalle osoittava kolmio"] # 0x25c1 (en: 'white left pointing triangle', google: 'valkoinen vasen osoitus kolmio') + - "◂": [T: "pieni musta vasemmalle osoittava kolmio"] # 0x25c2 (en: 'black left pointing small triangle', google: 'musta vasen osoittaa pieni kolmio') + - "◃": [T: "pieni valkoinen vasemmalle osoittava kolmio"] # 0x25c3 (en: 'white left pointing small triangle', google: 'valkoinen vasen osoitus pieni kolmio') + - "◄": [T: "musta vasemmalle osoittava osoitin"] # 0x25c4 (en: 'black left pointing pointer', google: 'musta vasen osoitin') + - "◅": [T: "valkoinen vasemmalle osoittava osoitin"] # 0x25c5 (en: 'white left pointing pointer', google: 'valkoinen vasen osoitin') + - "◆": [T: "musta timantti"] # 0x25c6 (en: 'black diamond', google: 'musta timantti') + - "◇": [T: "valkoinen timantti"] # 0x25c7 (en: 'white diamond', google: 'valkoinen timantti') + - "◈": [T: "valkoinen timantti jonka sisällä musta timantti"] # 0x25c8 (en: 'white diamond containing black small diamond', google: 'valkoinen timantti, joka sisältää mustan pienen timantin') + - "◉": [T: "valkoinen ympyrä jonka sisällä musta ympyrä"] # 0x25c9 (en: 'fisheye', google: 'kalake') + - "◊": [T: "vinoneliö"] # 0x25ca (en: 'lozenge', google: 'pastilli') + - "○": [T: "valkoinen ympyrä"] # 0x25cb (en: 'white circle') + - "◌": [T: "pisteympyrä"] # 0x25cc (en: 'dotted circle', google: 'pisteympyrä') + - "◍": [T: "ympyrä ja pystysuora viivoitus"] # 0x25cd (en: 'circle with vertical fill', google: 'ympyrä pystysuoralla täyttöä') + - "◎": [T: "kaksi sisäkkäistä ympyrää"] # 0x25ce (en: 'bullseye', google: 'bullseye') + - "●": [T: "musta ympyrä"] # 0x25cf (en: 'black circle') + - "◐": [T: "ympyrä vasen puoli musta"] # 0x25d0 (en: 'circle with left half black', google: 'ympyrä vasemmalla puoliksi mustalla') + - "◑": [T: "ympyrä oikea puoli musta"] # 0x25d1 (en: 'circle with right half black', google: 'ympyrä oikealla puoliksi mustalla') + - "◒": [T: "ympyrä alapuoli musta"] # 0x25d2 (en: 'circle with lower half black', google: 'ympyrä, jossa on alaosa musta') + - "◓": [T: "ympyrä yläpuoli musta"] # 0x25d3 (en: 'circle with upper half black', google: 'ympyrä yläpuoliskolla mustalla') + - "◔": [T: "ympyrä yläoikea neljännes musta"] # 0x25d4 (en: 'circle with upper right quadrant black', google: 'ympyrä oikealla yläkulmalla kvadrantti musta') + - "◕": [T: "ympyrä ylävasen neljännes mustaamatta"] # 0x25d5 (en: 'circle with all but upper left quadrant black', google: 'ympyrä kaikilla paitsi vasemmalla yläosalla mustaa') + - "◖": [T: "musta vasen puoliympyrä"] # 0x25d6 (en: 'left half black circle', google: 'vasen puoli musta ympyrä') + - "◗": [T: "musta oikea puoliympyrä"] # 0x25d7 (en: 'right half black circle', google: 'oikea puoli musta ympyrä') + - "◘": [T: "luetelmapallon negatiivi"] # 0x25d8 (en: 'inverse bullet', google: 'käänteinen luoti') + - "◙": [T: "valkoisen ympyrän negatiivi"] # 0x25d9 (en: 'inverse white circle', google: 'käänteinen valkoinen ympyrä') + - "◚": [T: "valkoisen ympyrän negatiivin yläpuoli"] # 0x25da (en: 'upper half inverse white circle', google: 'yläosa käänteinen valkoinen ympyrä') + - "◛": [T: "valkoisen ympyrän negatiivin alapuoli"] # 0x25db (en: 'lower half inverse white circle', google: 'alempi puoli käänteinen valkoinen ympyrä') + - "◜": [T: "ympyrän kaaren vasen yläneljännes"] # 0x25dc (en: 'upper left quadrant circular arc', google: 'vasen yläosa kvadrantti pyöreä kaari') + - "◝": [T: "ympyrän kaaren oikea yläneljännes"] # 0x25dd (en: 'upper right quadrant circular arc', google: 'oikea yläosa kvadrantti pyöreä kaari') + - "◞": [T: "ympyrän kaaren oikea alaneljännes"] # 0x25de (en: 'lower right quadrant circular arc', google: 'oikea alaosa neljänneksen pyöreä kaari') + - "◟": [T: "ympyrän kaaren vasen alaneljännes"] # 0x25df (en: 'lower left quadrant circular arc', google: 'vasen alakulmainen kvadrantti pyöreä kaari') + - "◠": [T: "ympyrän kaaren yläpuolikas"] # 0x25e0 (en: 'upper half circle', google: 'yläosa ympyrä') + - "◡": [T: "ympyrän kaaren alapuolikas"] # 0x25e1 (en: 'lower half circle', google: 'alempi puoli ympyrä') + - "◢": [T: "musta oikea alakolmio"] # 0x25e2 (en: 'black lower right triangle', google: 'musta alaosa oikea kolmio') + - "◣": [T: "musta vasen alakolmio"] # 0x25e3 (en: 'black lower left triangle', google: 'musta vasen alaosa kolmio') + - "◤": [T: "musta vasen yläkolmio"] # 0x25e4 (en: 'black upper left triangle', google: 'musta vasen yläosa kolmio') + - "◥": [T: "musta oikea yläkolmio"] # 0x25e5 (en: 'black upper right triangle', google: 'musta oikea yläosa kolmio') + - "◦": [T: "valkoinen pallo"] # 0x25e6 (en: 'composition', google: 'sävellys') + - "◧": [T: "neliö vasen puoli musta"] # 0x25e7 (en: 'square with left half black', google: 'neliö vasemmalla puoliksi mustalla') + - "◨": [T: "neliö oikea puoli musta"] # 0x25e8 (en: 'square with right half black', google: 'neliö oikealla puoliksi mustalla') + - "◩": [T: "neliö vasen ylädiagonaali musta"] # 0x25e9 (en: 'square with upper left half black', google: 'neliö vasemmalla yläosa mustalla') + - "◪": [T: "neliö oikea aladiagonaali musta"] # 0x25ea (en: 'square with lower right half black', google: 'neliö oikealla alaosa mustalla') + - "◫": [T: "valkoinen neliö pystysuoralla poikkiviivalla"] # 0x25eb (en: 'white square with bisecting line', google: 'valkoinen neliö puolustamisviivalla') + - "◬": [T: "valkoinen ylös osoittava kolmio pisteellä"] # 0x25ec (en: 'white up pointing triangle with dot', google: 'valkoinen osoittava kolmio pisteellä') + - "◭": [T: "valkoinen ylös osoittava kolmio, vasen puoli musta"] # 0x25ed (en: 'up pointing triangle with left half black', google: 'ylöspäin osoittaen kolmio vasemmalla puoliksi mustalla') + - "◮": [T: "valkoinen ylös osoittava kolmio, oikea puoli musta"] # 0x25ee (en: 'up pointing triangle with right half black', google: 'ylös osoittaen kolmio oikealla puoliksi mustalla') + - "◯": [T: "valkoinen ympyrä"] # 0x25ef (en: 'large circle', google: 'suuri ympyrä') + - "◰": [T: "valkoinen neliö josta on erotettu ylävasen neljännes"] # 0x25f0 (en: 'white square with upper left quadrant', google translation) + - "◱": [T: "valkoinen neliö josta on erotettu alavasen neljännes"] # 0x25f1 (en: 'white square with lower left quadrant', google translation) + - "◲": [T: "valkoinen neliö josta on erotettu alaoikea neljännes"] # 0x25f2 (en: 'white square with lower right quadrant', google translation) + - "◳": [T: "valkoinen neliö josta on erotettu yläoikea neljännes"] # 0x25f3 (en: 'white square with upper right quadrant', google translation) + - "◴": [T: "valkoinen ympyrä josta on erotettu ylävasen neljännes"] # 0x25f4 (en: 'white circle with upper left quadrant', google translation) + - "◵": [T: "valkoinen ympyrä josta on erotettu alavasen neljännes"] # 0x25f5 (en: 'white circle with lower left quadrant', google translation) + - "◶": [T: "valkoinen ympyrä josta on erotettu alaoikea neljännes"] # 0x25f6 (en: 'white circle with lower right quadrant', google translation) + - "◷": [T: "valkoinen ympyrä josta on erotettu yläoikea neljännes"] # 0x25f7 (en: 'white circle with upper right quadrant', google translation) + - "◸": [T: "ylävasen kolmio"] # 0x25f8 (en: 'upper left triangle', google: 'vasen yläosa kolmio') + - "◹": [T: "yläoikea kolmio"] # 0x25f9 (en: 'upper right triangle', google: 'oikea yläosa kolmio') + - "◺": [T: "alavasen kolmio"] # 0x25fa (en: 'lower left triangle', google: 'vasen alaosa kolmio') + - "◻": [T: "keskikokoinen valkoinen neliö"] # 0x25fb (en: 'white medium square', google: 'valkoinen keskipitkä neliö') + - "◼": [T: "keskikokoinen musta neliö"] # 0x25fc (en: 'black medium square', google: 'musta keskipitkä neliö') + - "◽": [T: "pienehkö valkoinen neliö"] # 0x25fd (en: 'white medium small square', google: 'valkoinen keskipitkä pieni neliö') + - "◾": [T: "pienehkö musta neliö"] # 0x25fe (en: 'black medium small square', google: 'musta keskipitkä pieni neliö') + - "◿": [T: "alaoikea kolmio"] # 0x25ff (en: 'lower right triangle', google: 'oikea alaosa kolmio') + - "♠": [T: "musta pata"] # 0x2660 (en: 'black spade suit', google: 'musta lapio puku') + - "♡": [T: "valkoinen hertta"] # 0x2661 (en: 'white heart suit', google: 'valkoinen sydänpuku') + - "♢": [T: "valkoinen ruutu"] # 0x2662 (en: 'white diamond suit', google: 'valkoinen timanttipuku') + - "♣": [T: "musta risti"] # 0x2663 (en: 'black club suit', google: 'mustakerhopuku') + - "♤": [T: "valkoinen pata"] # 0x2664 (en: 'white spade suit', google: 'valkoinen lapiopuku') + - "♥": [T: "musta hertta"] # 0x2665 (en: 'black heart suit', google: 'musta sydänpuku') + - "♦": [T: "musta ruutu"] # 0x2666 (en: 'black diamond suit', google: 'musta timanttipuku') + - "♧": [T: "valkoinen risti"] # 0x2667 (en: 'white club suit', google: 'valkoinen klubipuku') + - "❨": [T: "keskikokoinen vasen sulkukoriste"] # 0x2768 (en: 'medium left parentheses ornament', google translation) + - "❩": [T: "keskikokoinen oikea sulkukoriste"] # 0x2769 (en: 'medium right parentheses ornament', google translation) + - "❪": [T: "keskikokoinen litistetty vasen sulkukoriste"] # 0x276a (en: 'medium flattened left parentheses ornament', google translation) + - "❫": [T: "keskikokoinen litistetty oikea sulkukoriste"] # 0x276b (en: 'medium flattened right parentheses ornament', google translation) + - "❬": [T: "keskikokoinen vasen kulmasulkukoriste"] # 0x276c (en: 'medium left-pointing angle bracket ornament', google translation) + - "❭": [T: "keskikokoinen oikea kulmasulkukoriste"] # 0x276d (en: 'medium right-pointing angle bracket ornament', google translation) + - "❮": [T: "raskas vasen kulmalainausmerkkikoriste"] # 0x276e (en: 'heavy left-pointing angle quotation mark ornament', google translation) + - "❯": [T: "raskas oikea kulmalainausmerkkikoriste"] # 0x276f (en: 'heavy right-pointing angle quotation mark ornament', google translation) + - "❰": [T: "raskas vasen kulmasulkukoriste"] # 0x2770 (en: 'heavy left-pointing angle bracket ornament', google translation) + - "❱": [T: "raskas oikea kulmasulkukoriste"] # 0x2771 (en: 'heavy right-pointing angle bracket ornament', google translation) + - "❲": [T: "kevyt vasen kilpikonnankuorisulkukoriste"] # 0x2772 (en: 'light left tortoise shell bracket ornament', google translation) + - "❳": [T: "kevyt oikea kilpikonnankuorisulkukoriste"] # 0x2773 (en: 'light right tortoise shell bracket ornament', google translation) + - "❴": [T: "keskikokoinen vasen aaltosulkukoriste"] # 0x2774 (en: 'medium left brace ornament', google translation) + - "❵": [T: "keskikokoinen oikea aaltosulkukoriste"] # 0x2775 (en: 'medium right brace ornament', google translation) + - "❶": [T: "musta ympyröity yksi"] # 0x2776 (en: 'black circled one', google translation) + - "❷": [T: "musta ympyröity kaksi"] # 0x2777 (en: 'black circled two', google translation) + - "❸": [T: "musta ympyröity kolme"] # 0x2778 (en: 'black circled three', google translation) + - "❹": [T: "musta ympyröity neljä"] # 0x2779 (en: 'black circled four', google translation) + - "❺": [T: "musta ympyröity viisi"] # 0x277a (en: 'black circled five', google translation) + - "❻": [T: "musta ympyröity kuusi"] # 0x277b (en: 'black circled six', google translation) + - "❼": [T: "musta ympyröity seitsemän"] # 0x277c (en: 'black circled seven', google translation) + - "❽": [T: "musta ympyröity kahdeksan"] # 0x277d (en: 'black circled eight', google translation) + - "❾": [T: "musta ympyröity yhdeksän"] # 0x277e (en: 'black circled nine', google translation) + - "❿": [T: "musta ympyröity kymmenen"] # 0x277f (en: 'black circled ten', google translation) + - "➀": [T: "ympyröity sans serif yksi"] # 0x2780 (en: 'circled sans serif one', google translation) + - "➁": [T: "ympyröity sans serif kaksi"] # 0x2781 (en: 'circled sans serif two', google translation) + - "➂": [T: "ympyröity sans serif kolme"] # 0x2782 (en: 'circled sans serif three', google translation) + - "➃": [T: "ympyröity sans serif neljä"] # 0x2783 (en: 'circled sans serif four', google translation) + - "➄": [T: "ympyröity sans serif viisi"] # 0x2784 (en: 'circled sans serif five', google translation) + - "➅": [T: "ympyröity sans serif kuusi"] # 0x2785 (en: 'circled sans serif six', google translation) + - "➆": [T: "ympyröity sans serif seitsemän"] # 0x2786 (en: 'circled sans serif seven', google translation) + - "➇": [T: "ympyröity sans serif kahdeksan"] # 0x2787 (en: 'circled sans serif eight', google translation) + - "➈": [T: "ympyröity sans serif yhdeksän"] # 0x2788 (en: 'circled sans serif nine', google translation) + - "➉": [T: "ympyröity sans serif kymmenen"] # 0x2789 (en: 'circled sans serif ten', google translation) + - "➊": [T: "musta ympyröity sans serif yksi"] # 0x278a (en: 'black circled sans serif one', google translation) + - "➋": [T: "musta ympyröity sans serif kaksi"] # 0x278b (en: 'black circled sans serif two', google translation) + - "➌": [T: "musta ympyröity sans serif kolme"] # 0x278c (en: 'black circled sans serif three', google translation) + - "➍": [T: "musta ympyröity sans serif neljä"] # 0x278d (en: 'black circled sans serif four', google translation) + - "➎": [T: "musta ympyröity sans serif viisi"] # 0x278e (en: 'black circled sans serif five', google translation) + - "➏": [T: "musta ympyröity sans serif kuusi"] # 0x278f (en: 'black circled sans serif six', google translation) + - "➐": [T: "musta ympyröity sans serif seitsemän"] # 0x2790 (en: 'black circled sans serif seven', google translation) + - "➑": [T: "musta ympyröity sans serif kahdeksan"] # 0x2791 (en: 'black circled sans serif eight', google translation) + - "➒": [T: "musta ympyröity sans serif yhdeksän"] # 0x2792 (en: 'black circled sans serif nine', google translation) + - "➓": [T: "musta ympyröity sans serif kymmenen"] # 0x2793 (en: 'black circled sans serif ten', google translation) + - "➔": [T: "raskas leveäpäinen oikea nuoli"] # 0x2794 (en: 'heavy wide-headed rightwards arrow', google translation) + - "➕": [T: "raskas plusmerkki"] # 0x2795 (en: 'heavy plus sign', google translation) + - "➖": [T: "raskas miinusmerkki"] # 0x2796 (en: 'heavy minus sign', google translation) + - "➗": [T: "raskas jakomerkki"] # 0x2797 (en: 'heavy division sign', google translation) + - "➘": [T: "raskas alaoikea nuoli"] # 0x2798 (en: 'heavy south east arrow', google translation) + - "➙": [T: "raskas oikea nuoli"] # 0x2799 (en: 'heavy rightwards arrow', google translation) + - "➚": [T: "raskas yläoikea nuoli"] # 0x279a (en: 'heavy north east arrow', google translation) + - "➛": [T: "laatimispiste oikealle nuoli"] # 0x279b (en: 'drafting point rightwards arrow', google translation) + - "➜": [T: "raskas pyöristetty oikea nuoli"] # 0x279c (en: 'heavy round-tipped rightwards arrow', google translation) + - "➝": [T: "kolmionpäinen oikea nuoli"] # 0x279d (en: 'triangle-headed rightwards arrow', google translation) + - "➞": [T: "raskas kolmiopäinen oikea nuoli"] # 0x279e (en: 'heavy triangle-headed rightwards arrow', google translation) + - "➟": [T: "kolmiopäinen oikea nuoli katkoviivalla"] # 0x279f (en: 'dashed triangle-headed rightwards arrow', google translation) + - "➠": [T: "raskas kolmiopäinen oikea nuoli katkoviivalla"] # 0x27a0 (en: 'heavy dashed triangle-headed rightwards arrow', google translation) + - "➡": [T: "oikealle osoittava musta nuoli"] # 0x27a1 (en: 'black rightwards arrow', google translation) + - "➢": [T: "yläpuolelta valkea oikealle osoittava nuolenpää"] # 0x27a2 (en: 'three d top lighted rightwards arrow', google translation) + - "➣": [T: "alapuolelta valkea oikealle osoittava nuolenpää"] # 0x27a3 (en: 'three d bottom lighted rightwards arrow', google translation) + - "➤": [T: "musta oikea nuolenpää"] # 0x27a4 (en: 'black rightwards arrowhead', google translation) + - "➥": [T: "raskas musta kaareva alas ja oikealle osoittava nuoli"] # 0x27a5 (en: 'heavy black curved downwards and rightwards arrow', google translation) + - "➦": [T: "raskas musta kaareva ylös ja oikealle osoittava nuoli"] # 0x27a6 (en: 'heavy black curved upwards and rightwards arrow', google translation) + - "➧": [T: "raskas musta lyhyt oikea nuoli"] # 0x27a7 (en: 'squat black rightwards arrow', google translation) + - "➨": [T: "raskas terävä musta oikea nuoli"] # 0x27a8 (en: 'heavy concave-pointed black rightwards arrow', google translation) + - "➩": [T: "oikea oikealle varjostettu valkoinen nuoli"] # 0x27a9 (en: 'right-shaded white rightwards arrow', google translation) + - "➪": [T: "oikea vasemmalle varjostettu valkoinen nuoli"] # 0x27aa (en: 'left-shaded white rightwards arrow', google translation) + - "➫": [T: "taaksepäin kallistettu varjostettu valkoinen oikealle osoittava nuoli"] # 0x27ab (en: 'back-tilted shadowed white rightwards arrow', google translation) + - "➬": [T: "eteenpäin kallistettu varjostettu valkoinen oikealle osoittava nuoli"] # 0x27ac (en: 'front-tilted shadowed white rightwards arrow', google translation) + - "➭": [T: "raskas oikea alhaalta varjostettu valkoinen nuoli"] # 0x27ad (en: 'heavy lower right-shadowed white rightwards arrow', google translation) + - "➮": [T: "raskas oikea ylhäältä varjostettu valkoinen nuoli"] # 0x27ae (en: 'heavy upper right-shadowed white rightwards arrow', google translation) + - "➯": [T: "raskas oikea alhaalta varjostettu valkoinen nuoli lovella"] # 0x27af (en: 'notched lower right-shadowed white rightwards arrow', google translation) + - "➱": [T: "raskas oikea ylhäältä varjostettu valkoinen nuoli lovella"] # 0x27b1 (en: 'notched upper right-shadowed white rightwards arrow', google translation) + - "➲": [T: "ympyröity raskas oikea valkoinen nuoli"] # 0x27b2 (en: 'circled heavy white rightwards arrow', google translation) + - "➳": [T: "oikea nuoli valkoisilla höyhenillä"] # 0x27b3 (en: 'white-feathered rightwards arrow', google translation) + - "➴": [T: "alaoikea nuoli mustilla höyhenillä"] # 0x27b4 (en: 'black-feathered south east arrow', google translation) + - "➵": [T: "oikea nuoli mustilla höyhenillä"] # 0x27b5 (en: 'black-feathered rightwards arrow', google translation) + - "➶": [T: "yläoikea nuoli mustilla höyhenillä"] # 0x27b6 (en: 'black-feathered north east arrow', google translation) + - "➷": [T: "raskas alaoikea nuoli mustilla höyhenillä"] # 0x27b7 (en: 'heavy black-feathered south east arrow', google translation) + - "➸": [T: "raskas oikea nuoli mustilla höyhenillä"] # 0x27b8 (en: 'heavy black-feathered rightwards arrow', google translation) + - "➹": [T: "raskas yläoikea nuoli mustilla höyhenillä"] # 0x27b9 (en: 'heavy black-feathered north east arrow', google translation) + - "➺": [T: "oikea nuoli kyynelpiikillä"] # 0x27ba (en: 'teradrop-barbed rightwards arrow', google translation) + - "➻": [T: "raskas nuoli kyynelpiikillä"] # 0x27bb (en: 'heavy teardrop-shanked rightwards arrow', google translation) + - "➼": [T: "oikea nuoli kiilalla"] # 0x27bc (en: 'wedge-tailed rightwards arrow', google translation) + - "➽": [T: "raskas oikea nuoli kiilalla"] # 0x27bd (en: 'heavy wedge-tailed rightwards arrow', google translation) + - "➾": [T: "oikea ääriviivanuoli"] # 0x27be (en: 'open-outlined rightwards arrow', google translation) + - "⟀": [T: "kolmiulotteinen kulma"] # 0x27c0 (en: 'three dimensional angle') + - "⟁": [T: "kaksi valkoista kolmiota sisäkkäin"] # 0x27c1 (en: 'white triangle containing small white triangle', google: 'valkoinen kolmio, joka sisältää pientä valkoista kolmiota') + - "⟂": # 0x27c2 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "kohtisuora" # (en: 'perpendicular to', google: 'kohtisuorassa') + - "⟃": # 0x27c3 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "avoin osajoukko" # (en: 'an open subset of') + - "⟄": # 0x27c4 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "avoin yläjoukko" # (en: 'an open superset of', google: 'avoin superset') + - "⟅": [T: "vasen s-muotoinen laukkuerottaja"] # 0x27c5 (google: 'vasen s-muotoinen laukku') + - "⟆": [T: "oikea s-muotoinen laukkuerottaja"] # 0x27c6 (google: 'oikea s-muotoinen laukku') + - "⟇": [T: "tai pisteellä"] # 0x27c7 (en: 'or with dot inside', google: 'tai pisteellä sisällä') + - "⟈": [T: "kenoviiva osajoukko"] # 0x27c8 (en: 'reverse solidus preceding subset', google: 'käänteinen solidus edeltävä alajoukko') + - "⟉": [T: "ylijoukko vinoviiva"] # 0x27c9 (en: 'superset preceding solidus', google: 'superset edeltävä solidus') + - "⟊": [T: "pystyviiva vaakasuoralla poikkiviivalla"] # 0x27ca (en: 'vertical bar with horizontal stroke', google: 'pystysuora palkki vaakasuuntaisella iskulla') + - "⟋": [T: "matemaattinen nouseva diagonaali"] # 0x27cb (en: 'mathematical rising diagonal', google translation) + - "⟌": [T: "jakokulma"] # 0x27cc (en: 'long division', google: 'jakolaskutoimitus') + - "⟍": [T: "matemaattinen laskeva diagonaali"] # 0x27cd (en: 'mathematical falling diagonal', google translation) + - "⟎": [T: "looginen ja neliössä"] # 0x27ce (en: 'squared logical and', google translation) + - "⟏": [T: "looginen tai neliössä"] # 0x27cf (en: 'squared logical or', google translation) + - "⟐": [T: "valkoinen timantti keskitetyllä pisteellä"] # 0x27d0 (en: 'white diamond with centered dot', google translation) + - "⟑": [T: "ja pisteellä"] # 0x27d1 (en: 'and with dot', google: 'ja pisteellä') + - "⟒": [T: "ylös aukeava kuuluu joukkoon"] # 0x27d2 (en: 'element of opening upwards', google: 'elementti avaamisesta ylöspäin') + - "⟓": [T: "oikea alakulma pisteellä"] # 0x27d3 (en: 'lower right corner with dot', google: 'oikea alakulma pisteellä') + - "⟔": [T: "vasen alakulma pisteellä"] # 0x27d4 (en: 'upper left corner with dot', google: 'vasen yläkulma pisteellä') + - "⟕": [T: "vasen ulkoinen liitos"] # 0x27d5 (google: 'vasen ulkoinen liittyminen') + - "⟖": [T: "oikea ulkoinen liitos"] # 0x27d6 (google: 'oikea ulkoinen liittyminen') + - "⟗": [T: "täysi ulkoinen liitos"] # 0x27d7 (google: 'täysi ulkoinen liittyminen') + - "⟘": [T: "suuri nupi ylöspäin"] # 0x27d8 (google: 'suuri ylöspäin') + - "⟙": [T: "suuri nupi alaspäin"] # 0x27d9 (google: 'suuri alaspäin') + - "⟚": [T: "tuplaportti vasemmalle ja oikealle"] # 0x27da (google: 'vasen ja oikea kaksoiskivi') + - "⟛": [T: "vasen ja oikea nupi"] # 0x27db (google: 'vasen ja oikea tarttuva') + - "⟜": [T: "vasen monikuvaus"] # 0x27dc (google: 'vasen multimep') # FI: meaning unclear + - "⟝": [T: "pitkä oikea nupi"] # 0x27dd (google: 'pitkä oikea tarttuva') + - "⟞": [T: "pitkä vasen nupi"] # 0x27de (google: 'pitkä vasen tarttuva') + - "⟟": [T: "nupi ylös ympyrällä"] # 0x27df (en: 'up tack with circle above', google: 'yllä oleva ympyrä') + - "⟠": [T: "vinoneliö vaakaviivalla"] # 0x27e0 (google: 'lozenge jaettuna vaakasuunnassa') + - "⟡": [T: "valkoinen terävä timantti"] # 0x27e1 (google: 'valkoinen koverapuolinen timantti') + - "⟢": [T: "valkoinen terävä timantti vasemmanpuoleisella nupilla"] # 0x27e2 (en: 'white concave sided diamond with leftwards tick', google: 'valkoinen koverapuolinen timantti vasemmalla rastilla') + - "⟣": [T: "valkoinen terävä timantti oikeanpuoleisella nupilla"] # 0x27e3 (en: 'white concave sided diamond with rightwards tick', google: 'valkoinen koverapuolinen timantti oikealla puolella') + - "⟤": [T: "valkoinen neliö vasemmanpuoleisella nupilla"] # 0x27e4 (en: 'white square with leftwards tick', google: 'valkoinen neliö vasemmalla rastilla') + - "⟥": [T: "valkoinen neliö oikeanpuoleisella nupilla"] # 0x27e5 (en: 'white square with rightwards tick', google: 'valkoinen neliö oikealla puolella') + - "⟦": [T: "valkoinen vasen hakasulku"] # 0x27e6 (en: 'left white square bracket', google: 'vasen valkoinen neliömäki') + - "⟧": [T: "valkoinen oikea hakasulku"] # 0x27e7 (en: 'right white square bracket', google: 'oikea valkoinen neliömäki') + - "⟨": [T: "vasen kulmasulku"] # 0x27e8 (en: 'left angle bracket', google: 'vasemman kulman kiinnike') + - "⟩": [T: "oikea kulmasulku"] # 0x27e9 (en: 'right angle bracket', google: 'suoren kulman kiinnike') + - "⟪": [T: "vasen kaksoiskulmasulku"] # 0x27ea (en: 'left double angle bracket', google: 'vasen kaksoiskulma kiinnike') + - "⟫": [T: "oikea kaksoiskulmasulku"] # 0x27eb (en: 'right double angle bracket', google: 'oikea kaksoiskulma kiinnike') + - "⟬": [T: "vasen valkoinen kilpikonnankuorisulku"] # 0x27ec (google: 'vasen valkoinen kilpikonnakuoren kiinnike') + - "⟭": [T: "oikea valkoinen kilpikonnankuorisulku"] # 0x27ed (google: 'oikea valkoinen kilpikonnakuoren kiinnike') + - "⟮": [T: "vasen litistetty sulku"] # 0x27ee (google: 'vasen litistetty sulkuteesi') + - "⟯": [T: "oikea litistetty sulku"] # 0x27ef (google: 'oikea litistetty sulkuteesi') + - "⟰": [T: "nelinkertainen nuoli ylös"] # 0x27f0 (en: 'upwards quadruple arrow', google translation) + - "⟱": [T: "nelinkertainen nuoli alas"] # 0x27f1 (en: 'downwards quadruple arrow', google translation) + - "⟲": [T: "avoin ympyränuoli vastapäivään"] # 0x27f2 (en: 'anticlockwise gapped circle arrow', google translation) + - "⟳": [T: "avoin ympyränuoli myötäpäivään"] # 0x27f3 (en: 'clockwise gapped circle arrow', google translation) + - "⟴": [T: "oikea nuoli ympyröidyllä plus-merkillä"] # 0x27f4 (en: 'right arrow with circled plus', google translation) + - "⟵": [T: "pitkä nuoli vasemmalle"] # 0x27f5 (en: 'long leftwards arrow', google: 'pitkä vasen nuoli') + - "⟶": [T: "pitkä nuoli oikealle"] # 0x27f6 (en: 'long rightwards arrow', google: 'pitkä oikea nuoli') + - "⟷": [T: "pitkä nuoli vasemmalle ja oikealle"] # 0x27f7 (en: 'long left right arrow', google: 'pitkä vasen oikea nuoli') + - "⟸": [T: "pitkä kaksoisnuoli vasemmalle"] # 0x27f8 (en: 'long leftwards double arrow', google: 'pitkä vasen kaksinkertainen nuoli') + - "⟹": [T: "pitkä kaksoisnuoli oikealle"] # 0x27f9 (en: 'long rightwards double arrow', google: 'pitkä oikea kaksinkertainen nuoli') + - "⟺": [T: "pitkä kaksoisnuoli vasemmalle ja oikealle"] # 0x27fa (en: 'long left right double arrow', google: 'pitkä vasen oikea kaksinkertainen nuoli') + - "⟻": [T: "pitkä vasen nuoli pystyviivasta"] # 0x27fb (en: 'long leftwards arrow from bar', google translation) + - "⟼": [T: "pitkä oikea nuoli pystyviivasta"] # 0x27fc (en: 'long rightwards arrow from bar', google: 'pitkä oikea nuoli baarista') + - "⟽": [T: "pitkä vasen kaksinkertainen nuoli pystyviivasta"] # 0x27fd (en: 'long leftwards double arrow from bar', google translation) + - "⟾": [T: "pitkä oikea kaksinkertainen nuoli pystyviivasta"] # 0x27fe (en: 'long rightwards double arrow from bar', google translation) + - "⟿": [T: "pitkä kiemuranuoli oikealle"] # 0x27ff (en: 'long rightwards squiggle arrow', google: 'pitkä oikeassa nuoli') + - "⤀": [T: "oikea kaksipäinen nuoli pystysuoralla viivalla"] # 0x2900 (en: 'rightwards two headed arrow with vertical stroke', google translation) + - "⤁": [T: "oikea kaksipäinen nuoli kaksinkertaisella pystysuoralla viivalla"] # 0x2901 (en: 'rightwards two headed arrow with double vertical stroke', google translation) + - "⤂": [T: "vasen kaksinkertainen nuoli pystysuoralla viivalla"] # 0x2902 (en: 'leftwards double arrow with vertical stroke', google translation) + - "⤃": [T: "oikea kaksinkertainen nuoli pystysuoralla viivalla"] # 0x2903 (en: 'rightwards double arrow with vertical stroke', google translation) + - "⤄": [T: "vasemmalle ja oikealle osoittava kaksinkertainen nuoli pystysuoralla viivalla"] # 0x2904 (en: 'left right double arrow with vertical stroke', google translation) + - "⤅": [T: "oikea kaksipäinen nuoli pystyviivasta"] # 0x2905 (google: 'oikealle kaksi päätä nuoli baarista') + - "⤆": [T: "vasen kaksinkertainen nuoli pystyviivasta"] # 0x2906 (en: 'leftwards double arrow from bar', google translation) + - "⤇": [T: "oikea kaksinkertainen nuoli pystyviivasta"] # 0x2907 (en: 'rightwards double arrow from bar', google translation) + - "⤈": [T: "alaspäin osoittava nuoli vaakaviivalla"] # 0x2908 (en: 'downwards arrow with horizontal stroke', google translation) + - "⤉": [T: "ylöspäin osoittava nuoli vaakaviivalla"] # 0x2909 (en: 'upwards arrow with horizontal stroke', google translation) + - "⤊": [T: "ylöspäin osoittava kolminkertainen nuoli"] # 0x290a (en: 'upwards triple arrow', google translation) + - "⤋": [T: "alaspäin osoittava kolminkertainen nuoli"] # 0x290b (en: 'downwards triple arrow', google translation) + - "⤌": [T: "vasen kaksoiskatkoviivannuoli"] # 0x290c (google: 'vasen kaksinkertainen viiva nuoli') + - "⤍": [T: "oikea kaksoiskatkoviivanuoli"] # 0x290d (google: 'oikealla puolella kaksoisnauhaa') + - "⤎": [T: "vasen kolmoiskatkoviivanuoli"] # 0x290e (google: 'vasen kolminkertainen viiva nuoli') + - "⤏": [T: "oikea kolmoiskatkoviivanuoli"] # 0x290f (google: 'oikealle kolminkertainen dash -nuoli') + - "⤐": [T: "oikea kaksipäinen katkoviivanuoli pyrstöllä"] # 0x2910 (google: 'oikealle kaksi päätä kolminkertainen viiva nuoli') + - "⤑": [T: "oikea pisteviivanuoli"] # 0x2911 (en: 'rightwards arrow with dotted stem', google: 'oikealla nuolella katkoviivalla') + - "⤒": [T: "nuoli ylös vaakaviivaan"] # 0x2912 (google: 'nuoli ylöspäin baariin') + - "⤓": [T: "nuoli alas vaakaviivaan"] # 0x2913 (google: 'alaspäin nuoli baariin') + - "⤔": [T: "oikea nuoli pystyviivalla ja pyrstöllä"] # 0x2914 (en: 'rightwards arrow with tail and vertical stroke', google translation) + - "⤕": [T: "oikea nuoli kaksoispystyviivalla ja pyrstöllä"] # 0x2915 (en: 'rightwards arrow with tail and double vertical stroke', google translation) + - "⤖": [T: "oikea kaksipäinen nuoli pyrstöllä"] # 0x2916 (en: 'rightwards two headed arrow with tail', google: 'oikealle kaksi päätä nuoli hännän kanssa') + - "⤗": [T: "oikea kaksipäinen nuoli pystyviivalla ja pyrstöllä"] # 0x2917 (en: 'rightwards two headed arrow with tail with vertical stroke', google translation) + - "⤘": [T: "oikea kaksipäinen nuoli kaksoispystyviivalla ja pyrstöllä"] # 0x2918 (en: 'rightwards two headed arrow with tail with double vertical stroke', google translation) + - "⤙": [T: "vasemmanpuoleisen nuolen häntä"] # 0x2919 (google: 'vasen nuoli häntä') + - "⤚": [T: "oikeanpuoleisen nuolen häntä"] # 0x291a (en: 'rightwards arrow tail', google translation) + - "⤛": [T: "vasemmanpuoleisen nuolen tuplahäntä"] # 0x291b (google: 'vasen kaksinkertainen nuoli häntä') + - "⤜": [T: "oikeanpuoleisen nuolen tuplahäntä"] # 0x291c (google: 'oikealla kaksoisnuoli') + - "⤝": [T: "vasen nuoli väritettyyn timanttiin"] # 0x291d (google: 'vasen nuoli täytetylle timantille') + - "⤞": [T: "oikea nuoli väritettyyn timanttiin"] # 0x291e (google: 'oikealla nuolella täytetylle timantille') + - "⤟": [T: "vasen nuoli pystyviivasta väritettyyn timanttiin"] # 0x291f (google: 'vasen nuoli baarista täytetylle timantille') + - "⤠": [T: "oikea nuoli pystyviivasta väritettyyn timanttiin"] # 0x2920 (google: 'suoraan nuoli baarista täytetylle timantille') + - "⤡": [T: "ylävasemmalle ja alaoikealle osoittava nuoli"] # 0x2921 (en: 'north west and south east arrow', google translation) + - "⤢": [T: "yläoikealle ja alavasemmalle osoittava nuoli"] # 0x2922 (en: 'north east and south west arrow', google translation) + - "⤣": [T: "ylävasen nuoli koukulla"] # 0x2923 (en: 'north west arrow with hook', google: 'luoteis -nuoli koukulla') + - "⤤": [T: "yläoikea nuoli koukulla"] # 0x2924 (en: 'north east arrow with hook', google: 'koillis -nuoli koukulla') + - "⤥": [T: "alaoikea nuoli koukulla"] # 0x2925 (en: 'south east arrow with hook', google: 'kaakkois -nuoli koukulla') + - "⤦": [T: "alavasen nuoli koukulla"] # 0x2926 (en: 'south west arrow with hook', google: 'lounais -nuoli koukulla') + - "⤧": [T: "nuoli yläoikealle ja nuoli ylävasemmalle"] # 0x2927 (google: 'luoteis arrow ja koillis -nuoli') + - "⤨": [T: "nuoli yläoikealle ja nuoli alaoikealle"] # 0x2928 (google: 'koillis -nuoli ja kaakkois -nuoli') + - "⤩": [T: "nuoli alaoikealle ja nuoli alavasemmalle"] # 0x2929 (google: 'kaakkois arrow ja south west arrow') + - "⤪": [T: "nuoli alavasemmalle ja nuoli ylävasemmalle"] # 0x292a (google: 'south west arrow ja north west arrow') + - "⤫": [T: "nouseva diagonaali laskevan diagonaalin päällä"] # 0x292b (en: 'rising diagonal crossing falling diagonal', google translation) + - "⤬": [T: "laskeva diagonaali nousevan diagonaalin päällä"] # 0x292c (en: 'falling diagonal crossing rising diagonal', google translation) + - "⤭": [T: "alaoikealle osoittava nuoli yläoikealle osoittavan nuolen päällä"] # 0x292d (en: 'south east arrow crossing north east arrow', google translation) + - "⤮": [T: "yläoikealle osoittava nuoli alaoikealle osoittavan nuolen päällä"] # 0x292e (en: 'north east arrow crossing south east arrow', google translation) + - "⤯": [T: "laskeva diagonaali yläoikealle osoittavan nuolen päällä"] # 0x292f (en: 'falling diagonal crossing north east arrow', google translation) + - "⤰": [T: "nouseva diagonaali alaoikealle osoittavan nuolen päällä"] # 0x2930 (en: 'rising diagonal crossing south east arrow', google translation) + - "⤱": [T: "yläoikealle osoittava nuoli ylävasemmalle osoittavan nuolen päällä"] # 0x2931 (en: 'north east arrow crossing north west arrow', google translation) + - "⤲": [T: "ylävasemmalle osoittava nuoli yläoikealle osoittavan nuolen päällä"] # 0x2932 (en: 'north west arrow crossing north east arrow', google translation) + - "⤳": [T: "aaltonuoli oikealle"] # 0x2933 (en: 'wave arrow pointing directly right', google: 'aalto nuoli osoittaa suoraan oikealle') + - "⤴": [T: "ylöspäin kaartuva oikea nuoli"] # 0x2934 (en: 'arrow pointing rightwards then curving upwards', google translation) + - "⤵": [T: "alaspäin kaartuva oikea nuoli"] # 0x2935 (google: 'nuoli osoittaa oikealle ja kaareutuu alaspäin') + - "⤶": [T: "vasemmalle kaartuva alavasemmalle osoittava nuoli"] # 0x2936 (google: 'nuoli osoittaa alaspäin ja kaareutuu vasemmalle') + - "⤷": [T: "oikealle kaartuva alaoikealle osoittava nuoli"] # 0x2937 (google: 'nuoli osoittaa alaspäin ja kaareutuu oikealle') + - "⤸": [T: "oikeanpuoleinen kaarinuoli myötäpäivään"] # 0x2938 (en: 'right side arc clockwise arrow', google: 'oikea sivukaari myötäpäivään nuoli') + - "⤹": [T: "vasemmanpuoleinen kaarinuoli vastapäivään"] # 0x2939 (en: 'left side arc anticlockwise arrow', google: 'vasen sivukaari vastapäivään') + - "⤺": [T: "yläkaarinuoli vastapäivään"] # 0x293a (en: 'top arc anticlockwise arrow', google translation) + - "⤻": [T: "alakaarinuoli vastapäivään"] # 0x293b (en: 'bottom arc anticlockwise arrow', google translation) + - "⤼": [T: "yläkaarinuoli myötäpäivään miinus-merkillä"] # 0x293c (en: 'top arc clockwise arrow with minus', google: 'yläkaari myötäpäivään nuoli miinus') + - "⤽": [T: "yläkaarinuoli vastapäivään plus-merkillä"] # 0x293d (en: 'top arc anticlockwise arrow with plus', google: 'yläkaari vastapäivään nuoli plus') + - "⤾": [T: "alaoikea kaarinuoli myötäpäivään"] # 0x293e (en: 'lower right semicircular clockwise arrow', google translation) + - "⤿": [T: "alavasen kaarinuoli vastapäivään"] # 0x293f (en: 'lower left semicircular anticlockwise arrow', google translation) + - "⥀": [T: "suljettu ympyränuoli vastapäivään"] # 0x2940 (en: 'anticlockwise closed circle arrow', google translation) + - "⥁": [T: "suljettu ympyränuoli myötäpäivään"] # 0x2941 (en: 'clockwise closed circle arrow', google translation) + - "⥂": [T: "oikea nuoli lyhyen vasemman nuolen yläpuolella"] # 0x2942 (en: 'rightwards arrow above short leftwards arrow', google translation) + - "⥃": [T: "vasen nuoli lyhyen oikean nuolen yläpuolella"] # 0x2943 (en: 'leftwards arrow above short rightwards arrow', google translation) + - "⥄": [T: "lyhyt oikea nuoli vasemman nuolen yläpuolella"] # 0x2944 (en: 'short rightwards arrow above leftwards arrow', google translation) + - "⥅": [T: "oikea nuoli ja plus-merkki alapuolella"] # 0x2945 (en: 'rightwards arrow with plus below', google: 'oikealla nuolella, jonka alla on plus') + - "⥆": [T: "vasen nuoli ja plus-merkki alanpuolella"] # 0x2946 (en: 'leftwards arrow with plus below', google translation) + - "⥇": [T: "oikea nuoli x:n läpi"] # 0x2947 (en: 'rightwards arrow through x', google translation) + - "⥈": [T: "oikealle ja vasemmalle osoittava nuoli ympyrän läpi"] # 0x2948 (google: 'vasen oikea nuoli ympyrän läpi') + - "⥉": [T: "ylöspäin osoittava kaksipäinen nuoli ympyrästä"] # 0x2949 (google: 'ylöspäin kaksi pääistä nuolta ympyrästä') + - "⥊": [T: "oikealle ja vasemmalle osoittava puolinuoli oikealla yläpiikillä ja vasemmalla alapiikillä"] # 0x294a (google: 'vasen barb ylös oikealle barb down harpoon') + - "⥋": [T: "oikealle ja vasemmalle osoittava puolinuoli oikealla alapiikillä ja vasemmalle yläpiikillä"] # 0x294b (google: 'vasen barb alas oikealla barb up harpoon') + - "⥌": [T: "ylös ja alas osoittava puolinuoli oikealla yläpiikillä ja vasemmalla alapiikillä"] # 0x294c (en: 'up barb right down barb left harpoon', google translation) + - "⥍": [T: "ylös ja alas osoittava puolinuoli vasemmalla yläpiikillä ja oikealla alapiikillä"] # 0x294d (en: 'up barb left down barb right harpoon', google translation) + - "⥎": [T: "oikealle ja vasemmalle osoittava puolinuoli, piikit yläpuolella"] # 0x294e (en: 'left barb up right barb up harpoon', google: 'vasen barb ylös oikealle barb up harpoon') + - "⥏": [T: "ylös ja alas osoittava puolinuoli, piikit oikealla"] # 0x294f (en: 'up barb right down barb right harpoon', google: 'ylös barb oikealla barbilla oikealla harpoonilla') + - "⥐": [T: "oikealle ja vasemmalle osoittava puolinuoli, piikit alapuolella"] # 0x2950 (en: 'left barb down right barb down harpoon', google: 'vasen barb alas oikealla barb down harpoon') + - "⥑": [T: "ylös ja alas osoittava puolinuoli, piikit vasemmalla"] # 0x2951 (en: 'up barb left down barb left harpoon', google: 'ylös barb vasemmalle barb vasen harpooni') + - "⥒": [T: "vasemmalle osoittava puolinuoli pystyviivaan, piikki yläpuolella"] # 0x2952 (en: 'leftwards harpoon with barb up to bar', google: 'vasen harppuuna barbin kanssa baariin') + - "⥓": [T: "oikealle osoittava puolinuoli pystyviivaan, piikki yläpuolella"] # 0x2953 (en: 'rightwards harpoon with barb up to bar', google: 'oikea harpoon barbin kanssa baariin') + - "⥔": [T: "ylös osoittava puolinuoli vaakaviivaan, piikki oikealla"] # 0x2954 (en: 'upwards harpoon with barb right to bar', google: 'ylöspäin harppuun barbin oikealla baarilla') + - "⥕": [T: "alas osoittava puolinuoli vaakaviivaan, piikki oikealla"] # 0x2955 (en: 'downwards harpoon with barb right to bar', google: 'downward harpoon barbin oikealla baarilla') + - "⥖": [T: "vasemmalle osoittava puolinuoli pystyviivaan, piikki alapuolella"] # 0x2956 (en: 'leftwards harpoon with barb down to bar', google: 'vasen harppuuna barbin kanssa baariin') + - "⥗": [T: "oikealle osoittava puolinuoli pystyviivaan, piikki alapuolella"] # 0x2957 (en: 'rightwards harpoon with barb down to bar', google: 'oikea harpoon barbin kanssa baariin') + - "⥘": [T: "ylös osoittava puolinuoli vaakaviivaan, piikki vasemmalla"] # 0x2958 (en: 'upwards harpoon with barb left to bar', google: 'ylös harppuon barbin kanssa vasemmalle baariin') + - "⥙": [T: "alas osoittava puolinuoli vaakaviivaan, piikki vasemmalla"] # 0x2959 (en: 'downwards harpoon with barb left to bar', google: 'downward harpoon barbin kanssa vasemmalle baariin') + - "⥚": [T: "vasemmalle osoittava puolinuoli vaakaviivasta, piikki yläpuolella"] # 0x295a (en: 'leftwards harpoon with barb up from bar', google: 'vasen harppuuna barb ylös baarista') + - "⥛": [T: "oikealle osoittava puolinuoli vaakaviivasta, piikki yläpuolella"] # 0x295b (en: 'rightwards harpoon with barb up from bar', google: 'oikealla harppuuna barbin kanssa baarista') + - "⥜": [T: "ylöspäin osoittava puolinuoli vaakaviivasta, piikki oikealla"] # 0x295c (en: 'upwards harpoon with barb right from bar', google: 'ylöspäin harppuun barbin kanssa heti baarista') + - "⥝": [T: "alaspäin osoittava puolinuoli vaakaviivasta, piikki oikealla"] # 0x295d (en: 'downwards harpoon with barb right from bar', google: 'downward harpoon barbin kanssa heti baarista') + - "⥞": [T: "vasemmalle osoittava puolinuoli vaakaviivasta, piikki alapuolella"] # 0x295e (en: 'leftwards harpoon with barb down from bar', google: 'vasen harppuuna barbin kanssa baarista') + - "⥟": [T: "oikealle osoittava puolinuoli vaakaviivasta, piikki alapuolella"] # 0x295f (en: 'rightwards harpoon with barb down from bar', google: 'oikea harpoon barbin kanssa baarista') + - "⥠": [T: "ylöspäin osoittava puolinuoli vaakaviivasta, piikki vasemmalla"] # 0x2960 (en: 'upwards harpoon with barb left from bar', google: 'ylös harppuun barbin vasemmalla baarista') + - "⥡": [T: "alaspäin osoittava puolinuoli vaakaviivasta, piikki vasemmalla"] # 0x2961 (en: 'downwards harpoon with barb left from bar', google: 'downward harpoon barbin vasemmalla baarista') + - "⥢": [T: "vasemmalle osoittava puolinuolipari"] # 0x2962 (en: 'leftwards harpoon with barb up above leftwards harpoon with barb down', google: 'vasen harppuuna barb ylös vasemmanpuoleisen harpoonin yläpuolella barb down') + - "⥣": [T: "ylöspäin osoittava puolinuolipari"] # 0x2963 (en: 'upwards harpoon with barb left beside upwards harpoon with barb right', google: 'yläpuolella harppuunia vasemmalla vasemmalla harpoon vieressä barbilla oikealla') + - "⥤": [T: "oikealle osoittava puolinuolipari"] # 0x2964 (en: 'rightwards harpoon with barb up above rightwards harpoon with barb down', google: 'oikealla harpoonilla barb ylös oikeanpuoleisen harpoonin yläpuolella barb down') + - "⥥": [T: "alaspäin osoittava puolinuolipari"] # 0x2965 (en: 'downwards harpoon with barb left beside downwards harpoon with barb right', google: 'downwards harpoon vasemmalla vasemmalla harppuunan vieressä barbilla oikealla') + - "⥦": [T: "vasen puolinuoli piikki ylös ja alapuolella oikea puolinuoli piikki ylös"] # 0x2966 (en: 'leftwards harpoon with barb up above rightwards harpoon with barb up', google: 'vasen harppuuna barb ylös oikeanpuoleisen harpoonin yläpuolella barb up') + - "⥧": [T: "vasen puolinuoli piikki alas ja alapuolella oikea puolinuoli piikki ylös"] # 0x2967 (en: 'leftwards harpoon with barb down above rightwards harpoon with barb down', google: 'vasen harppuuna barb alas oikeanpuoleisen harpoonin yläpuolella barb down') + - "⥨": [T: "oikea puolinuoli piikki ylös ja alapuolella vasen puolinuoli piikki ylös"] # 0x2968 (en: 'rightwards harpoon with barb up above leftwards harpoon with barb up', google: 'oikealla harpounalla barb ylös vasemmanpuoleisen harpoonin yläpuolella barb up') + - "⥩": [T: "oikea puolinuoli piikki alas ja alapuolella vasen puolinuoli piikki alas"] # 0x2969 (en: 'rightwards harpoon with barb down above leftwards harpoon with barb down', google: 'oikealla harpounalla barbin kanssa vasemmanpuoleisen harpoonin yläpuolella barb down') + - "⥪": [T: "vasen puolinuoli piikki ylös vaakaviivan yläpuolella"] # 0x296a (en: 'leftwards harpoon with barb up above long dash', google: 'vasen harppuuna barb ylös pitkän viivan yläpuolella') + - "⥫": [T: "vasen puolinuoli piikki alas vaakaviivan alapuolella"] # 0x296b (en: 'leftwards harpoon with barb down below long dash', google: 'vasen harppuuna barbin alapuolella pitkän viivan alapuolella') + - "⥬": [T: "oikea puolinuoli piikki ylös vaakaviivan yläpuolella"] # 0x296c (en: 'rightwards harpoon with barb up above long dash', google: 'oikealla harppuunilla barb up long dashin yläpuolella') + - "⥭": [T: "oikea puolinuoli piikki alas vaakaviivan alapuolella"] # 0x296d (en: 'rightwards harpoon with barb down below long dash', google: 'oikealla harppuuna barbin alapuolella pitkän viivan alapuolella') + - "⥮": [T: "ylös ja alas osoittava puolinuolipari"] # 0x296e (en: 'upwards harpoon with barb left beside downwards harpoon with barb right', google: 'ylös harppuunaa vasemmalla vasemmalla harpoonin vieressä barbilla oikealla') + - "⥯": [T: "alas ja ylös osoittava puolinuolipari"] # 0x296f (en: 'downwards harpoon with barb left beside upwards harpoon with barb right', google: 'downwards harpoon vasemmalla vasemmalla harppuunin vieressä barbilla oikealla') + - "⥰": [T: "oikea tuplanuoli pyöristetyllä yläpuolella"] # 0x2970 (en: 'right double arrow with rounded head', google: 'oikea kaksinkertainen nuoli pyöristetyllä pään kanssa') + - "⥱": [T: "yhtä suuri kuin oikean nuolen yläpuolella"] # 0x2971 (google: 'vastaa oikeanpuoleista nuolta') + - "⥲": [T: "tilde oikean nuolen yläpuolella"] # 0x2972 (google: 'tilde -operaattori oikeanpuoleisen nuolen yläpuolella') + - "⥳": [T: "vasen nuoli tilden yläpuolella"] # 0x2973 (en: 'leftwards arrow above tilde operator', google: 'vasen nuoli tilde -operaattorin yläpuolella') + - "⥴": [T: "oikea nuoli tilden yläpuolella"] # 0x2974 (en: 'rightwards arrow above tilde operator', google: 'oikealla nuolella tilde -operaattorin yläpuolella') + - "⥵": [T: "oikea nuoli melkein yhtä suuri kuin yläpuolella"] # 0x2975 (google: 'oikea nuoli yläpuolelle melkein yhtä suuri kuin') + - "⥶": [T: "pienempi kuin vasemman nuolen yläpuolella"] # 0x2976 (google: 'alle kuin vasemmanpuoleinen nuoli') + - "⥷": [T: "vasen nuoli pienempi kuin päällä"] # 0x2977 (en: 'leftwards arrow through less than', google translation) + - "⥸": [T: "suurempi kuin oikean nuolen yläpuolella"] # 0x2978 (google: 'suurempi kuin oikeanpuoleinen nuoli') + - "⥹": [T: "osajoukko oikean nuolen yläpuolella"] # 0x2979 (google: 'oikeanpuoleinen nuolen yläpuolella') + - "⥺": [T: "vasen nuoli osajoukon päällä"] # 0x297a (en: 'leftwards arrow through subset', google translation) + - "⥻": [T: "ylijoukko vasemman nuolen yläpuolella"] # 0x297b (google: 'superset vasemmanpuoleisen nuolen yläpuolella') + - "⥼": [T: "vasen kalanpyrstö"] # 0x297c (google: 'vasen kala häntä') + - "⥽": [T: "oikea kalanpyrstö"] # 0x297d (google: 'oikea kala häntä') + - "⥾": [T: "ylöspäin osoittava kalanpyrstö"] # 0x297e (en: 'up fish tail', google: 'ylös kalanhäntä') + - "⥿": [T: "alaspäin osoittava kalanpyrstö"] # 0x297f (google: 'alas kalan hännä') + - "⦀": [T: "kolminkertainen pystysuora palkki"] # 0x2980 (en: 'triple vertical bar delimiter', google translation) + - "⦁": [T: "Z-notaatio piste"] # 0x2981 (en: 'z notation spot', google translation) + - "⦂": [T: "Z-notaatio kaksoispiste"] # 0x2982 (en: 'z notation type colon', google translation) + - "⦃": [T: "vasen valkoinen aaltosulku"] # 0x2983 (en: 'left white brace', google translation) + - "⦄": [T: "oikea valkoinen aaltosulku"] # 0x2984 (en: 'right white brace', google translation) + - "⦅": [T: "vasen valkoinen kaarisulku"] # 0x2985 (en: 'left white parenthesis', google: 'vasen valkoinen sulkuteesi') + - "⦆": [T: "oikea valkoinen kaarisulku"] # 0x2986 (en: 'right white parenthesis', google: 'oikea valkoinen sulkuteesi') + - "⦇": [T: "Z-notaatio vasen kuva sulku"] # 0x2987 (en: 'z notation left image bracket', google translation) + - "⦈": [T: "Z-notaatio oikea kuva sulku"] # 0x2988 (en: 'z notation right image bracket', google translation) + - "⦉": [T: "Z-notaatio vasen sitova sulku"] # 0x2989 (google: 'z -merkintä jätti sitovan kiinnikkeen') + - "⦊": [T: "Z-notaatio oikea sitova sulku"] # 0x298a (google: 'z -merkintä oikea sitova kiinnike') + - "⦋": [T: "vasen hakasulku alaviivalla"] # 0x298b (en: 'left square bracket with underbar', google: 'vasen neliökiinnike alapalkin kanssa') + - "⦌": [T: "oikea hakasulku alaviivalla"] # 0x298c (en: 'right square bracket with underbar', google: 'oikea neliökiinnike alapalkin kanssa') + - "⦍": [T: "vasen hakasulku viivalla ylänurkassa"] # 0x298d (en: 'left square bracket with tick in top corner', google: 'vasen neliö kiinnike, punkki yläkulmassa') + - "⦎": [T: "oikea hakasulku viivalla alanurkassa"] # 0x298e (en: 'right square bracket with tick in bottom corner', google: 'oikea neliökiinnike, jossa punkki alakulmassa') + - "⦏": [T: "vasen hakasulku viivalla alanurkassa"] # 0x298f (en: 'left square bracket with tick in bottom corner', google: 'vasen neliö kiinnike, punkki alakulmassa') + - "⦐": [T: "oikea hakasulku viivalla ylänurkassa"] # 0x2990 (en: 'right square bracket with tick in top corner', google: 'oikea neliö kiinnike, punkki yläkulmassa') + - "⦑": [T: "vasen kulmasulku pisteellä"] # 0x2991 (en: 'left angle bracket with dot', google: 'vasemman kulman kiinnike pisteellä') + - "⦒": [T: "oikea kulmasulku pisteellä"] # 0x2992 (en: 'right angle bracket with dot', google: 'suoren kulman kiinnike pisteellä') + - "⦓": [T: "vasen kaari pienempi kuin sulku"] # 0x2993 (google: 'vasen kaari vähemmän kuin kiinnike') + - "⦔": [T: "oikea kaari suurempi kuin sulku"] # 0x2994 (google: 'oikea kaari suurempi kuin kiinnike') + - "⦕": [T: "vasen kaksoiskaari suurempi kuin sulku"] # 0x2995 (google: 'kaksinkertainen vasen kaari on suurempi kuin kiinnike') + - "⦖": [T: "oikea kaksoiskaari pienempi kuin sulku"] # 0x2996 (google: 'kaksinkertainen oikea kaari vähemmän kuin kiinnike') + - "⦗": [T: "vasen musta kilpikonnankuorisulku"] # 0x2997 (en: 'left black tortoise shell bracket', google translation) + - "⦘": [T: "oikea musta kilpikonnakuorisulku"] # 0x2998 (en: 'right black tortoise shell bracket', google translation) + - "⦙": [T: "pistetty aita"] # 0x2999 (en: 'dotted fence', google translation) + - "⦚": [T: "pystysuora siksak-viiva"] # 0x299a (google: 'pystysuora siksak -linja') + - "⦛": [T: "vasemmalle avautuva mitattu kulma"] # 0x299b (en: 'measured angle opening left', google translation) + - "⦜": [T: "neliöllä merkitty suora kulma"] # 0x299c (en: 'right angle variant with square', google translation) + - "⦝": [T: "kaarella merkitty suora kulma"] # 0x299d (en: 'measured right angle with dot', google: 'mitattu oikea kulma pisteellä') + - "⦞": [T: "kulma, jonka sisällä on s"] # 0x299e (en: 'angle with s inside', google translation) + - "⦟": [T: "terävä kulma"] # 0x299f (en: 'acute angle', google translation) + - "⦠": [T: "vasemmalle avautuva pallomainen kulma"] # 0x29a0 (en: 'spherical angle opening left', google translation) + - "⦡": [T: "ylös avautuva pallomainen kulma"] # 0x29a1 (en: 'spherical angle opening up', google translation) + - "⦢": [T: "käännetty kulma"] # 0x29a2 (en: 'turned angle', google translation) + - "⦣": [T: "käänteinen kulma"] # 0x29a3 (en: 'reversed angle', google translation) + - "⦤": [T: "kulma alaviivalla"] # 0x29a4 (en: 'angle with underbar', google: 'kulma alapalkin kanssa') + - "⦥": [T: "käännetty kulma alaviivalla"] # 0x29a5 (en: 'reversed angle with underbar', google: 'käännetty kulma alapalkin kanssa') + - "⦦": [T: "ylöspäin avautuva viisto kulma"] # 0x29a6 (google: 'vino kulma avautuu') + - "⦧": [T: "alaspäin avautuva viisto kulma"] # 0x29a7 (google: 'vino kulma avautuu') + - "⦨": [T: "mitattu kulma, jossa yläoikealle osoittava nuoli"] # 0x29a8 (en: 'measured angle with open arm ending in arrow pointing up and to the right', google: 'mitattu kulma, kun avoin käsivarsi päättyy nuoleen osoittaen ylös ja oikealle') + - "⦩": [T: "mitattu kulma, jossa ylävasemmalle osoittava nuoli"] # 0x29a9 (en: 'measured angle with open arm ending in arrow pointing up and to the left', google: 'mitattu kulma, jonka avoin käsivarsi päättyy nuoleen osoittaen ylös ja vasemmalle') + - "⦪": [T: "mitattu kulma, jossa alaoikealle osoittava nuoli"] # 0x29aa (en: 'measured angle with open arm ending in arrow pointing down and to the right', google: 'mitattu kulma, kun avoin käsivarsi päättyy nuolessa alaspäin ja oikealle') + - "⦫": [T: "mitattu kulma, jossa alavasemmalle osoittava nuoli"] # 0x29ab (en: 'measured angle with open arm ending in arrow pointing down and to the left', google: 'mitattu kulma, kun avoin käsivarsi päättyy nuolessa alaspäin ja vasemmalle') + - "⦬": [T: "mitattu kulma, jossa oikealle ja ylös osoittava nuoli"] # 0x29ac (en: 'measured angle with open arm ending in arrow pointing right and up', google: 'mitattu kulma, kun avoin käsivarsi päättyy nuoleen osoittaen oikealle ja ylöspäin') + - "⦭": [T: "mitattu kulma, jossa vasemmalle ja ylös osoittava nuoli"] # 0x29ad (en: 'measured angle with open arm ending in arrow pointing left and up', google: 'mitattu kulma, jonka avoin käsivarsi päättyy nuoleen osoittaen vasemmalle ja ylöspäin') + - "⦮": [T: "mitattu kulma, jossa oikealle ja alas osoittava nuoli"] # 0x29ae (en: 'measured angle with open arm ending in arrow pointing right and down', google: 'mitattu kulma, kun avoin käsivarsi päättyy nuoleen osoittaen oikealle ja alas') + - "⦯": [T: "mitattu kulma, jossa vasemmalle ja alas osoittava nuoli"] # 0x29af (en: 'measured angle with open arm ending in arrow pointing left and down', google: 'mitattu kulma, jonka nuolessa päättyy avoimeen käsivarteen, osoittaen vasemmalle ja alas') + - "⦰": [T: "käännetty tyhjä joukko"] # 0x29b0 (google: 'kääntynyt tyhjä sarja') + - "⦱": [T: "tyhjä joukko yläviivalla"] # 0x29b1 (en: 'empty set with overbar', google: 'tyhjä sarja ylikuormituksella') + - "⦲": [T: "tyhjä joukko ja pieni ympyrä yläpuolella"] # 0x29b2 (en: 'empty set with small circle above', google: 'tyhjä sarja, jossa on pieni ympyrä yllä') + - "⦳": [T: "tyhjä joukko ja oikea nuoli yläpuolella"] # 0x29b3 (en: 'empty set with right arrow above', google: 'tyhjä sarja oikealla nuolella yllä') + - "⦴": [T: "tyhjä joukko ja vasen nuoli yläpuolella"] # 0x29b4 (en: 'empty set with left arrow above', google: 'tyhjä sarja vasemmalla nuolella yllä') + - "⦵": [T: "vaakaviivallinen ympyrä"] # 0x29b5 (en: 'circle with horizontal bar', google: 'ympyrä vaakasuuntaisella palkilla') + - "⦶": [T: "ympyröity pystyviiva"] # 0x29b6 (google: 'ympyrä pystysuora palkki') + - "⦷": [T: "ympyröidyt samansuuntaiset pystyviivat"] # 0x29b7 (google: 'ympyröi rinnakkain') + - "⦸": [T: "ympyröity kenoviiva"] # 0x29b8 (en: 'circled reverse solidus', google translation) + - "⦹": [T: "ympyröity kohtisuoruusmerkki"] # 0x29b9 (google: 'ympyräsi kohtisuorassa') + - "⦺": [T: "ympyrä, joka on jaettu vaakaviivalla ja yläpuolisko on jaettu pystyviivalla"] # 0x29ba (en: 'circled divided by horizontal bar and top half divided by vertical bar', google translation) + - "⦻": [T: "ympyrä ja x päällekkäin"] # 0x29bb (en: 'circle with superimposed x', google: 'ympyrä päällekkäin x') + - "⦼": [T: "ympyröity vastapäivään käännetty jakomerkki"] # 0x29bc (en: 'circled anticlockwise rotated division sign', google: 'ympyröity vastapäivään kierretty jakomerkki') + - "⦽": [T: "nuoli ympyrän läpi"] # 0x29bd (en: 'up arrow through circle', google translation) + - "⦾": [T: "ympyröity valkoinen pieni ympyrä"] # 0x29be (google: 'ympyrävalkoinen luoti') + - "⦿": [T: "ympyröity pieni ympyrä"] # 0x29bf (google: 'ympyrä luoti') + - "⧀": [T: "ympyröity pienempi kuin"] # 0x29c0 (google: 'ympyräsi vähemmän kuin') + - "⧁": [T: "ympyröity suurempi kuin"] # 0x29c1 (google: 'ympyräsi suurempi kuin') + - "⧂": [T: "ympyrä ja pieni ympyrä oikealla"] # 0x29c2 (en: 'circle with small circle to the right', google: 'ympyrä pienellä ympyrällä oikealla') + - "⧃": [T: "ympyrä ja kaksi vaakaviivaa oikealla"] # 0x29c3 (en: 'circle with two horizontal strokes to the right', google: 'ympyrä kahdella vaakasuuntaisella iskulla oikealle') + - "⧄": [T: "neliöity kasvava diagonaalinen viiva"] # 0x29c4 (google: 'neliö nousevat diagonaaliset viiva') + - "⧅": [T: "neliöity laskeva diagonaalinen viiva"] # 0x29c5 (google: 'neliö putoava diagonaalinen viiva') + - "⧆": [T: "neliö tähdellä"] # 0x29c6 (en: 'squared asterisk', google translation) + - "⧇": [T: "neliöity pieni ympyrä"] # 0x29c7 (en: 'squared small circle', google translation) + - "⧈": [T: "neliöity pieni neliö"] # 0x29c8 (en: 'squared square', google translation) + - "⧉": [T: "kaksi limittäistä neliötä"] # 0x29c9 (google: 'kaksi liittyi neliötä') + - "⧊": [T: "kolmio ja piste yläpuolella"] # 0x29ca (en: 'triangle with dot above', google translation) + - "⧋": [T: "kolmio ja vaakaviiva alapuolella"] # 0x29cb (en: 'triangle with underbar', google translation) + - "⧌": [T: "s kolmiossa"] # 0x29cc (en: 's in triangle', google translation) + - "⧍": [T: "kolmio, jonka pohjassa serif"] # 0x29cd (en: 'triangle with serifs at bottom', google: 'kolmio alaosassa') + - "⧎": [T: "oikea kolmio vasemman kolmion yläpuolella"] # 0x29ce (google: 'oikea kolmio vasemman kolmion yläpuolella') + - "⧏": [T: "vasen kolmio pystyviivan vieressä"] # 0x29cf (en: 'left triangle beside vertical bar', google: 'vasen kolmio pystysuoran palkin vieressä') + - "⧐": [T: "pystyviiva oikean kolmion vieressä"] # 0x29d0 (en: 'vertical bar beside right triangle', google: 'pystysuora palkki oikean kolmion vieressä') + - "⧑": [T: "rusetti, jonka vasen puoli musta"] # 0x29d1 (en: 'bowtie with left half black', google translation) + - "⧒": [T: "rusetti, jonka oikea puoli musta"] # 0x29d2 (en: 'bowtie with right half black', google translation) + - "⧓": [T: "musta rusetti"] # 0x29d3 (en: 'black bowtie', google translation) + - "⧔": [T: "puolirusetti, jonka vasen puoli musta"] # 0x29d4 (en: 'times with left half black', google translation) + - "⧕": [T: "puolirusetti, jonka oikea puoli musta"] # 0x29d5 (en: 'times with right half black', google translation) + - "⧖": [T: "valkoinen tiimalasi"] # 0x29d6 (en: 'white hourglass', google translation) + - "⧗": [T: "musta tiimalasi"] # 0x29d7 (en: 'black hourglass', google translation) + - "⧘": [T: "vasen kiemurteleva viiva"] # 0x29d8 (en: 'left wiggly fence', google translation) + - "⧙": [T: "oikea kiemurteleva viiva"] # 0x29d9 (en: 'right wiggly fence', google translation) + - "⧚": [T: "vasen kaksinkertainen kiemurteleva viiva"] # 0x29da (en: 'left double wiggly fence', google: 'vasen kaksinkertainen aita') + - "⧛": [T: "oikea kaksinkertainen kiemurteleva viiva"] # 0x29db (en: 'right double wiggly fence', google: 'oikea kaksinkertainen aita') + - "⧜": [T: "epätäydellinen äärettömyys"] # 0x29dc (google: 'epätäydellinen äärettömyys') + - "⧝": [T: "yhdistetty äärettömyys"] # 0x29dd (en: 'tie over infinity', google translation) + - "⧞": [T: "äärettömyys negatoitu pystyviivalla"] # 0x29de (en: 'infinity negated with vertical bar', google: 'äärettömyys kielsi pystysuoralla palkilla') + - "⧟": [T: "kaksipäinen monikuvaus"] # 0x29df (en: 'double-ended multimap', google translation) # FI: "multimap", "monikuvaus" translation questionable + - "⧠": [T: "neliö korostetuilla ääreviivoilla"] # 0x29e0 (en: 'square with contoured outline', google translation) + - "⧡": [T: "kasvaa suhteessa"] # 0x29e1 (en: 'increases as', google translation) + - "⧢": [T: "sekoitetulo"] # 0x29e2 (en: 'shuffle product', google translation) + - "⧣": [T: "on yhtä suuri kuin kahdella vinolla yliviivalla"] # 0x29e3 (google: 'vastaa merkkiä ja viistot rinnakkain') + - "⧤": [T: "on yhtä suuri kuin kahdella vinolla yliviivalla ja tilde yläpuolella"] # 0x29e4 (en: 'equals sign and slanted parallel with tilde above', google: 'vastaa merkkiä ja viistot yhdensuuntaisen kanssa tilden kanssa yllä') + - "⧥": [T: "identtinen kuin kahdella vinolla yliviivalla"] # 0x29e5 (en: 'identical to and slanted parallel', google: 'identtinen ja vino rinnakkain') + - "⧦": [T: "tautologisesti ekvivalentti"] # 0x29e6 (google translation) + - "⧧": [T: "termodynaaminen"] # 0x29e7 (en: 'thermodynamic', google translation) + - "⧨": [T: "alaspäin osoittava kolmio ja vasen puoli musta"] # 0x29e8 (en: 'down pointing triangle with left half black', google translation) + - "⧩": [T: "alaspäin osoittava kolmio ja oikea puoli musta"] # 0x29e9 (en: 'down pointing triangle with right half black', google translation) + - "⧪": [T: "musta timantti alas osoittavalla nuolella"] # 0x29ea (en: 'black diamond with down arrow', google translation) + - "⧫": [T: "musta vinoneliö"] # 0x29eb (en: 'black lozenge', google: 'musta lozenge') + - "⧬": [T: "valkoinen ympyrä alaspäin osoittavalla nuolella"] # 0x29ec (en: 'white circle with down arrow', google translation) + - "⧭": [T: "musta ympyrä alaspäin osoittavalla nuolella"] # 0x29ed (en: 'black circle with down arrow', google translation) + - "⧮": [T: "valkoinen neliö virheviivoilla"] # 0x29ee (en: 'error-barred white square', google translation) + - "⧯": [T: "musta neliö virheviivoilla"] # 0x29ef (en: 'error-barred black square', google translation) + - "⧰": [T: "valkoinen timantti virheviivoilla"] # 0x29f0 (en: 'error-barred white diamond', google translation) + - "⧱": [T: "musta timantti virheviivoilla"] # 0x29f1 (en: 'error-barred black diamond', google translation) + - "⧲": [T: "valkoinen ympyrä virheviivoilla"] # 0x29f2 (en: 'error-barred white circle', google translation) + - "⧳": [T: "musta ympyrä virheviivoilla"] # 0x29f3 (en: 'error-barred black circle', google translation) + - "⧴": [T: "viivästetty sääntö"] # 0x29f4 (en: 'rule-delayed', google: 'sääntöviitettu') + - "⧵": [T: "kenoviiva"] # 0x29f5 (en: 'reverse solidus operator', google translation) + - "⧶": [T: "vinoviiva yläviivalla"] # 0x29f6 (en: 'solidus with overbar', google: 'solidus ylikuormituksen kanssa') + - "⧷": [T: "kenoviiva poikkiviivalla"] # 0x29f7 (en: 'reverse solidus with horizontal stroke', google translation) + - "⧸": [T: "iso vinoviiva"] # 0x29f8 (google translation) + - "⧹": [T: "iso kenoviiva"] # 0x29f9 (en: 'big reverse solidus', google translation) + - "⧺": [T: "kaksinkertainen plus"] # 0x29fa (en: 'double plus', google translation) + - "⧻": [T: "kolminkertainen plus"] # 0x29fb (google translation) + - "⧼": [T: "vasemmalle osoittava kaareva kulmahakasulku"] # 0x29fc (en: 'left pointing curved angle bracket', google translation) + - "⧽": [T: "oikealle osoittava kaareva kulmahakasulku"] # 0x29fd (en: 'right pointing curved angle bracket', google translation) + - "⧾": [T: "tiny"] # 0x29fe (en: 'tiny', google translation) + - "⧿": [T: "miny"] # 0x29ff (google translation) + - "⨀": [T: "monikollinen ympyrässä oleva kertopiste"] # 0x2a00 (en: 'circled dot operator', google translation) + - "⨁": [T: "monikollinen ympyrässä oleva plus"] # 0x2a01 (en: 'circled plus operator', google translation) + - "⨂": [T: "monikollinen ympyrässä oleva kertomerkki"] # 0x2a02 (en: 'circled times operator', google translation) + - "⨃": [T: "pisteellinen monikkounioni"] # 0x2a03 (en: 'union operator with dot', google translation) + - "⨄": [T: "monijoukkojen monikkounioni"] # 0x2a04 (en: 'union operator with plus', google translation) + - "⨅": [T: "kulmikas leikkauksen merkki"] # 0x2a05 (en: 'square intersection operator', google translation) + - "⨆": [T: "kulmikas unionin merkki"] # 0x2a06 (en: 'square union operator', google translation) + - "⨇": [T: "kaksi loogista ja-operaattoria"] # 0x2a07 (en: 'two logical and operator', google translation) + - "⨈": [T: "kaksi loogista tai-operaattoria"] # 0x2a08 (en: 'two logical or operator', google translation) + - "⨉": [T: "kertaa-operaattori"] # 0x2a09 (en: 'times operator', google translation) + - "⨊": [T: "modulo kaksi summaa"] # 0x2a0a (en: 'modulo two sum', google translation) + - "⨋": [T: "summa integraalilla"] # 0x2a0b (en: 'summation with integral', google translation) + - "⨌": [T: "nelinkertainen integraali"] # 0x2a0c (google: 'neljänneksen kiinteä operaattori') + - "⨍": [T: "pääarvointegraali"] # 0x2a0d (google: 'äärellinen osa integraali') + - "⨎": [T: "integraali kaksinkertaisella poikkiviivalla"] # 0x2a0e (en: 'integral with double stroke', google translation) + - "⨏": [T: "integraalikeskiarvo viistolla vaakaviivalla"] # 0x2a0f (en: 'integral average with slash', google translation) + - "⨐": [T: "kiertofunktio"] # 0x2a10 (google: 'kiertotoiminto') + - "⨑": [T: "integraali vastapäivään"] # 0x2a11 (google: 'vastapäivään integraatio') + - "⨒": [T: "viivaintegraali neliskulmaisella polulla navan ympäri"] # 0x2a12 (en: 'line integration with rectangular path around pole', google: 'line -integraatio suorakaiteen muotoisella polulla navan ympärillä') + - "⨓": [T: "viivaintegraali puoliympyräpolulla navan ympäri"] # 0x2a13 (en: 'line integration with semicircular path around pole', google: 'line -integrointi puolipyöreällä polulla navan ympärillä') + - "⨔": [T: "viivaintegraali ei sisällä napaa"] # 0x2a14 (google: 'linjan integrointi ei sisällä napaa') + - "⨕": [T: "integraali pisteoperaattorin ympärillä"] # 0x2a15 (google: 'integroitu pisteen operaattorin ympärillä') + - "⨖": [T: "kvaternionin integraalioperaattori"] # 0x2a16 en: 'quaternion integral operator' google: 'kvaternionin kiinteä operaattori' + - "⨗": [T: "integraali ja vasemmalle osoittava nuoli koukulla"] # 0x2a17 (en: 'integral with leftwards arrow with hook', google: 'integraali vasemmanpuoleisella nuolella koukussa') + - "⨘": [T: "integraali kertomerkillä"] # 0x2a18 (en: 'integral with times sign', google translation) + - "⨙": [T: "integraali leikkauksella"] # 0x2a19 (en: 'integral with intersection', google translation) + - "⨚": [T: "integraali unionilla"] # 0x2a1a (en: 'integral with union', google translation) + - "⨛": [T: "integraali yläviivalla"] # 0x2a1b (en: 'integral with overbar', google translation) + - "⨜": [T: "integraali alaviivalla"] # 0x2a1c (en: 'integral with underbar', google translation) + - "⨝": [T: "liitos"] # 0x2a1d (en: 'join', google translation) + - "⨞": [T: "suuri vasen kolmio -operaattori"] # 0x2a1e (en: 'large left triangle operator', google translation) + - "⨟": [T: "Z-notaatio skeemayhdiste"] # 0x2a1f (en: 'z notation schema composition', google translation) + - "⨠": [T: "Z-notaatio skeemapiping"] # 0x2a20 (en: 'z notation schema piping', google translation) + - "⨡": [T: "Z-notaatio skeemaprojektio"] # 0x2a21 (en: 'z notation schema projection', google translation) + - "⨢": [T: "plus ja ympyrä yläpuolella"] # 0x2a22 (en: 'plus sign with circle above', google: 'plus -merkki yllä olevalla ympyrällä') + - "⨣": [T: "plus ja sirkumfleksi yläpuolella"] # 0x2a23 (en: 'plus sign with circumflex accent above', google: 'plus -merkki yllä olevalla ympyrä -aksentilla') # FI: should this be "hat", "hattu"? + - "⨤": [T: "plus ja tilde yläpuolella"] # 0x2a24 (en: 'plus sign with tilde above', google: 'plus -merkki yllä olevan tilden kanssa') + - "⨥": [T: "plus ja piste alapuolella"] # 0x2a25 (en: 'plus sign with dot below', google: 'plus -merkki alla olevalla pisteellä') + - "⨦": [T: "plus ja tilde alapuolella"] # 0x2a26 (en: 'plus sign with tilde below', google: 'plus -merkki alla olevilla tildeillä') + - "⨧": [T: "plus alaindeksi kaksi"] # 0x2a27 (en: 'plus sign with subscript two', google: 'plus -merkki alaindeksi kaksi') + - "⨨": [T: "plus mustalla kolmiolla"] # 0x2a28 (en: 'plus sign with black triangle', google translation) + - "⨩": [T: "miinus ja piste yläpuolella"] # 0x2a29 (en: 'minus sign with comma above', google: 'miinus merkki yllä olevalla pilkulla') + - "⨪": [T: "miinus ja piste alapuolella"] # 0x2a2a (en: 'minus sign with dot below', google: 'miinusmerkki alla olevalla pisteellä') + - "⨫": [T: "miinus putoavilla pisteillä"] # 0x2a2b (en: 'minus sign with falling dots', google translation) + - "⨬": [T: "miinus nousevilla pisteillä"] # 0x2a2c (en: 'minus sign with rising dots', google translation) + - "⨭": [T: "plus vasemmalla puoliympyrällä"] # 0x2a2d (google: 'plus kirjaudu vasemmassa puolivälissä') + - "⨮": [T: "plus oikealla puoliympyrällä"] # 0x2a2e (google: 'plus kirjaudu oikeaan puoliväliin') + - "⨯": [T: "ristitulo"] # 0x2a2f (en: 'cross product', google: 'ristituote') + - "⨰": [T: "kertomerkki ja piste yläpuolella"] # 0x2a30 (en: 'multiplication sign with dot above', google: 'kertolaskulla olevan pisteen kanssa') + - "⨱": [T: "kertomerkki alaviivalla"] # 0x2a31 (en: 'multiplication sign with underbar', google: 'kertolasku aluskokouksella') + - "⨲": [T: "puolisuora tulo, jonka pohja suljettu"] # 0x2a32 (en: 'semidirect product with bottom closed', google translation) + - "⨳": [T: "smash tulo"] # 0x2a33 (en: 'smash product' google: 'smash -tuote') # FI: translation unclear + - "⨴": [T: "kertomerkki vasemmalla puoliympyrällä"] # 0x2a34 (google: 'kertolaskenta vasemmassa puolivälissä') + - "⨵": [T: "kertomerkki oikealla puoliympyrällä"] # 0x2a35 (google: 'kertokultaan oikea puoli ympyrä') + - "⨶": [T: "ympyröity kertomerkki sirkumfleksillä"] # 0x2a36 (en: 'circled multiplication sign with circumflex accent', google: 'ympyräkerroin merkki kehäkykyt aksentilla') # FI: should this be with "hat", "hattu"? + - "⨷": [T: "kaksoisympyröity kertomerkki"] # 0x2a37 (google: 'kertolaskenta kaksoisympyrässä') + - "⨸": [T: "ympyröity jakomerkki"] # 0x2a38 (google: 'ympyrädivisioonan merkki') + - "⨹": [T: "plus kolmiossa"] # 0x2a39 (google: 'plus kirjaudu kolmioon') + - "⨺": [T: "miinus kolmiossa"] # 0x2a3a (google: 'miinus kirjaudu kolmioon') + - "⨻": [T: "kertomerkki kolmiossa"] # 0x2a3b (google: 'kertokultaan kolmiossa') + - "⨼": [T: "sisäinen tulo"] # 0x2a3c (google: 'sisätuote') + - "⨽": [T: "oikeanpuoleinen sisäinen tulo"] # 0x2a3d (en: 'righthand interior product', google translation) + - "⨿": [T: "amalgamaatio tai kotulo"] # 0x2a3f (en: "amalgamation or coproduct", google: 'yhdistäminen tai yhteistyö') # FI: translation unclear + - "⩀": [T: "leikkaus pisteellä"] # 0x2a40 (en: 'intersection with dot', google: 'risteys pisteellä') + - "⩁": [T: "unioni miinuksella"] # 0x2a41 (en: 'union with minus sign', google translation) + - "⩂": [T: "unioni yläviivalla"] # 0x2a42 (en: 'union with overbar', google: 'unioni ylikuormituksen kanssa') + - "⩃": [T: "leikkaus yläviivalla"] # 0x2a43 (en: 'intersection with overbar', google: 'risteys ylikuormituksen kanssa') + - "⩄": [T: "leikkaus ja looginen ja"] # 0x2a44 (en: 'intersection with logical and', google: 'risteys loogisella ja') + - "⩅": [T: "unioni ja looginen tai"] # 0x2a45 (en: 'union with logical or', google: 'union loogisen tai') + - "⩆": [T: "unioni leikkauksen yläpuolella"] # 0x2a46 (google: 'unioni risteyksen yläpuolella') + - "⩇": [T: "leikkaus unionin yläpuolella"] # 0x2a47 (google: 'risteys liiton yläpuolella') + - "⩈": [T: "unioni alaviivalla leikkauksen yläpuolella"] # 0x2a48 (google: 'unioni yläpuolella risteyksen yläpuolella') + - "⩉": [T: "leikkaus alaviivalla leikkauksen yläpuolella"] # 0x2a49 (google: 'risteys yläpuolella liiton yläpuolella') + - "⩊": [T: "unioni unionin vieressä yhdistettynä"] # 0x2a4a (en: 'union beside and joined with union', google: 'unionin vieressä ja liittyi unioniin') + - "⩋": [T: "leikkaus leikkauksen vieressä yhdistettynä"] # 0x2a4b (en: 'intersection beside and joined with intersection', google: 'risteys risteyksen vieressä ja liitetty') + - "⩌": [T: "suljettu unioni serifillä"] # 0x2a4c (en: 'closed union with serifs', google: 'suljettu liitto serifien kanssa') + - "⩍": [T: "suljettu leikkaus serifillä"] # 0x2a4d (en: 'closed intersection with serifs', google: 'suljettu risteys serifien kanssa') + - "⩎": [T: "kaksinkertainen neliöleikkus"] # 0x2a4e (en: 'double square intersection', google translation) + - "⩏": [T: "kaksinkertainen neliöunioni"] # 0x2a4f (google translation) + - "⩐": [T: "suljettu unioni serifillä ja smash tulo"] # 0x2a50 (en: 'closed union with serifs and smash product', google: 'suljettu liitto serifien ja smash -tuotteen kanssa') + - "⩑": [T: "looginen ja yläpisteellä"] # 0x2a51 (en: 'logical and with dot above', google translation) + - "⩒": [T: "looginen tai yläpisteellä"] # 0x2a52 (en: 'logical or with dot above', google translation) + - "⩓": [T: "kaksinkertainen looginen ja"] # 0x2a53 (google: 'kaksinkertainen looginen ja') + - "⩔": [T: "kaksinkertainen looginen tai"] # 0x2a54 (google: 'kaksinkertainen looginen tai') + - "⩕": [T: "kaksi limittäistä loogista ja -merkkiä"] # 0x2a55 (google: 'kaksi risteävää loogista ja') + - "⩖": [T: "kaksi limittäistä loogista tai -merkkiä"] # 0x2a56 (google: 'kaksi risteävää loogista tai') + - "⩗": [T: "vino suuri tai"] # 0x2a57 (google: 'kalteva suuri tai') + - "⩘": [T: "vino suuri ja"] # 0x2a58 (google: 'kalteva iso ja') + - "⩙": [T: "looginen tai jonka päällä looginen ja"] # 0x2a59 (en: 'logical or overlapping logical and', google translation) + - "⩚": [T: "looginen ja pystyviivalla"] # 0x2a5a (en: 'logical and with middle stem', google: 'looginen ja keskimmäisellä varrella') + - "⩛": [T: "looginen tai pystyviivalla"] # 0x2a5b (en: 'logical or with middle stem', google: 'looginen tai keskimmäisellä varrella') + - "⩜": [T: "looginen ja vaakaviivalla"] # 0x2a5c (en: 'logical and with horizontal dash', google: 'looginen ja vaakasuuntaisella viivalla') + - "⩝": [T: "looginen tai vaakaviivalla"] # 0x2a5d (en: 'logical or with horizontal dash', google: 'looginen tai vaakasuuntaisella viivalla') + - "⩞": [T: "looginen ja kaksoisyläviivalla"] # 0x2a5e (en: 'logical and with double overbar', google translation) + - "⩟": [T: "looginen ja alaviivalla"] # 0x2a5f (en: 'logical and with underbar', google: 'looginen ja alikarjan kanssa') + - "⩠": [T: "looginen ja kaksoisalaviivalla"] # 0x2a60 (en: 'logical and with double underbar', google translation) + - "⩡": [T: "pieni vee alaviivalla"] # 0x2a61 (en: 'small vee with underbar', google translation) + - "⩢": [T: "looginen tai kaksoisyläviivalla"] # 0x2a62 (en: 'logical or with double overbar', google translation) + - "⩣": [T: "kaksoisalleviivattu looginen tai"] # 0x2a63 (en: 'logical or with double underbar', google translation) + - "⩤": [T: "Z-notaatio määrittelyjoukon vastarajoitus"] # 0x2a64 (en: 'z notation domain antirestriction', google translation) # FI: unclear translation + - "⩥": [T: "Z-notaatio kuvajoukon vastarajoitus"] # 0x2a65 (en: 'z notation range antirestriction', google translation) # FI: unclear translation + - "⩦": [T: "on yhtä suuri kuin alapisteellä"] # 0x2a66 (en: 'equals sign with dot below', google: 'vastaa alla olevaa pistettä') + - "⩧": [T: "identtinen yläpisteellä"] # 0x2a67 (en: 'identical with dot above', google translation) + - "⩨": [T: "kolminkertainen vaakasuora viiva kaksinkertaisella pystysuoralla viivalla"] # 0x2a68 (en: 'triple horizontal bar with double vertical stroke', google translation) + - "⩩": [T: "kolminkertainen vaakasuora viiva kolminkertaisella pystysuoralla viivalla"] # 0x2a69 (en: 'triple horizontal bar with triple vertical stroke', google translation) + - "⩪": [T: "tilde yläpisteellä"] # 0x2a6a (en: 'tilde operator with dot above', google: 'tilde -operaattori, jossa on pisteen yllä') + - "⩫": [T: "tilde nousevilla pisteillä"] # 0x2a6b (en: 'tilde operator with rising dots', google translation) + - "⩬": [T: "samankaltainen miinus samankaltainen"] # 0x2a6c (en: 'similar minus similar', google translation) + - "⩭": [T: "kongruentti yläpisteellä"] # 0x2a6d (en: 'congruent with dot above', google: 'yhteydet yllä olevan dot: n kanssa') + - "⩮": [T: "on yhtä suuri kuin tähdellä"] # 0x2a6e (en: 'equals with asterisk', google translation) + - "⩯": [T: "on lähes yhtä suuri kuin sirkumfleksillä"] # 0x2a6f (en: 'almost equal to with circumflex accent', google: 'lähes') + - "⩰": [T: "on suunnilleen yhtä suuri tai yhtä suuri kuin"] # 0x2a70 (en: 'approximately equal to or equal to', google translation) + - "⩱": [T: "on yhtä suuri kuin ja plus alapuolella"] # 0x2a71 (en: 'equals sign above plus sign', google: 'vastaa merkkiä yllä plus merkki') + - "⩲": [T: "on yhtä suuri kuin ja plus yläpuolella"] # 0x2a72 (en: 'plus sign above equals sign', google: 'plus -merkki yllä on yhtä suuri merkki') + - "⩳": [T: "on yhtä suuri kuin ja tilde alapuolella"] # 0x2a73 (google: 'yhtä suuri kuin merkki tilde -operaattorin yläpuolella') + - "⩴": [T: "tuplakaksoispiste on yhtä suuri kuin"] # 0x2a74 (google: 'kaksinkertainen paksusuolen tasainen') + - "⩵": [T: "kaksi peräkkäistä on yhtä suuri kuin -merkkiä"] # 0x2a75 (en: 'two consecutive equals signs', google: 'kaksi peräkkäistä vastaa merkkejä') + - "⩶": [T: "kolme peräkkäistä on yhtä suuri kuin -merkkiä"] # 0x2a76 (en: 'three consecutive equals signs', google translation) + - "⩷": [T: "on yhtä suuri kuin kahdella yläpisteellä ja kahdella alapisteellä"] # 0x2a77 (en: 'equals sign with two dots above and two dots below', google: 'yhtä suuri kuin kaksi pistettä yllä ja kaksi pistettä alla') + - "⩸": [T: "on yhtä suuri kuin neljällä yläpisteellä"] # 0x2a78 (en: 'equivalent with four dots above', google: 'vastaa neljällä pisteellä yllä') + - "⩹": [T: "pienempi kuin ja ympyrä sisällä"] # 0x2a79 (en: 'less than with circle inside', google: 'vähemmän kuin ympyrällä sisällä') + - "⩺": [T: "suurempi kuin ja ympyrä sisällä"] # 0x2a7a (en: 'greater than with circle inside', google: 'suurempi kuin ympyrällä sisällä') + - "⩻": [T: "pienempi kuin ja kysymysmerkki yläpuolella"] # 0x2a7b (en: 'less than with question mark above', google: 'vähemmän kuin yllä oleva kysymys') + - "⩼": [T: "suurempi kuin ja kysymysmerkki yläpuolella"] # 0x2a7c (en: 'greater than with question mark above', google: 'suurempi kuin yllä oleva kysymys') + - "⩽": [T: "pienempi kuin tai vino on yhtä suuri kuin"] # 0x2a7d (google: 'vähemmän kuin vino kuin') + - "⩾": [T: "suurempi kuin tai vino on yhtä suuri kuin"] # 0x2a7e (en: 'greater than or slanted equal to', google: 'suurempi kuin vino yhtä suuri kuin') + - "⩿": [T: "pienempi kuin tai vino on yhtä suuri kuin ja piste sisällä"] # 0x2a7f (en: 'less than or slanted equal to with dot inside', google: 'vähemmän tai vino yhtä suuri kuin pisteellä') + - "⪀": [T: "suurempi kuin tai vino on yhtä suuri kuin ja piste sisällä"] # 0x2a80 (en: 'greater than or slanted equal to with dot inside', google: 'suurempi tai viistot yhtä suuri kuin pisteellä') + - "⪁": [T: "pienempi kuin tai vino on yhtä suuri kuin ja piste yläpuolella"] # 0x2a81 (en: 'less than or slanted equal to with dot above', google: 'vähemmän kuin vino yhtä suuri kuin yllä olevalla pisteellä') + - "⪂": [T: "suurempi kuin tai vino on yhtä suuri kuin ja piste yläpuolella"] # 0x2a82 (en: 'greater than or slanted equal to with dot above', google: 'suurempi kuin vino kuin yllä olevalla pisteellä') + - "⪃": [T: "pienempi kuin tai vino on yhtä suuri kuin ja piste yläoikealla"] # 0x2a83 (en: 'less than or slanted equal to with dot above right', google: 'vähemmän tai viistot yhtä suuri kuin oikean yläpuolella') + - "⪄": [T: "suurempi kuin tai vino on yhtä suuri kuin ja piste ylävasemmalla"] # 0x2a84 (en: 'greater than or slanted equal to with dot above left', google: 'suurempi kuin vino kuin vasemman yläpuolella oleva piste') + - "⪅": [T: "vähemmän tai likimäärin"] # 0x2a85 (en: 'less than or approximate', google translation) + - "⪆": [T: "suurempi tai likimäärin"] # 0x2a86 (en: 'greater than or approximate', google translation) + - "⪇": [T: "pienempi kuin ja yksiviivainen ei yhtä suuri kuin"] # 0x2a87 (en: 'less than and single line not equal to', google translation) + - "⪈": [T: "suurempi kuin ja yksiviivainen ei yhtä suuri kuin"] # 0x2a88 (en: 'greater than and single line not equal to', google translation) + - "⪉": [T: "pienempi kuin mutta ei likimäärin"] # 0x2a89 (en: 'less than and not approximate', google: 'vähemmän kuin ja ei likimääräinen') + - "⪊": [T: "suurempi kuin mutta ei likimäärin"] # 0x2a8a (en: 'greater than and not approximate', google: 'suurempi kuin ja ei likimääräinen') + - "⪋": [T: "pienempi kuin jonka alapuolella vaakaviiva jonka alapuolella suurempi kuin"] # 0x2a8b (en: 'less than above double line equal above greater than', google translation) + - "⪌": [T: "suurempi kuin jonka alapuolella vaakaviiva jonka alapuolella pienempi kuin"] # 0x2a8c (en: 'greater than above double line equal above less than', google translation) + - "⪍": [T: "pienempi kuin jonka alapuolella yhtä suuri tai likimäärin yhtä suuri kuin"] # 0x2a8d (google: 'vähemmän kuin samanlainen tai tasainen') + - "⪎": [T: "suurempi kuin jonka alapuolella yhtä suuri tai limikäärin yhtä suuri kuin"] # 0x2a8e (google: 'suurempi kuin samanlainen tai tasainen') + - "⪏": [T: "pienempi kuin jonka alapuolella likimäärin jonka alapuolella suurempi kuin"] # 0x2a8f (google: 'vähemmän kuin yläpuolella yläpuolella suurempi kuin') + - "⪐": [T: "suurempi kuin jonka alapuolella likimäärin jonka alapuolella suurempi kuin"] # 0x2a90 (google: 'suurempi kuin edellä mainitussa yläpuolella') + - "⪑": [T: "pienempi kuin suurempi kuin tai yhtä suuri kuin"] # 0x2a91 (en: 'less than above greater than above double line equal', google: 'alle enemmän kuin yli suurempi kuin kaksoisviiva on yhtä suuri') + - "⪒": [T: "suurempi kuin pienempi kuin tai yhtä suuri kuin"] # 0x2a92 (en: 'greater than above less than above double line equal', google: 'suurempi kuin yläpuolella vähemmän kuin kaksoisviiva on yhtä suuri') + - "⪓": [T: "pienempi kuin tai vino on yhtä suuri kuin suurempi kuin tai vino on yhtä suuri kuin"] # 0x2a93 (google: 'vähemmän kuin yläpuolella viistot ovat yhtä suurempia kuin yläpuolella viistot ovat yhtä suuret') + - "⪔": [T: "suurempi kuin tai vino on yhtä suuri kuin pienempi kuin tai vino on yhtä suuri kuin"] # 0x2a94 (google: 'suurempi kuin yläpuolella viistot ovat yhtä suurempia kuin viistojen yläpuolella yhtä suuret') + - "⪕": [T: "vino on yhtä suuri kuin tai pienempi kuin"] # 0x2a95 (en: 'slanted equal to or less than', google translation) + - "⪖": [T: "vino on yhtä suuri kuin tai suurempi kuin"] # 0x2a96 (en: 'slanted equal to or greater than', google translation) + - "⪗": [T: "vino on yhtä suuri kuin tai pienempi kuin ja piste sisällä"] # 0x2a97 (en: 'slanted equal to or less than with dot inside', google: 'viisto yhtä tai vähemmän kuin pisteellä sisällä') + - "⪘": [T: "vino on yhtä suuri kuin tai suurempi kuin ja piste sisällä"] # 0x2a98 (en: 'slanted equal to or greater than with dot inside', google: 'viisto yhtä tai suurempi kuin pisteellä sisällä') + - "⪙": [T: "on yhtä suuri kuin tai pienempi kuin"] # 0x2a99 (en: 'double line equal to or less than', google: 'kaksoisviiva, joka on yhtä suuri tai vähemmän kuin') + - "⪚": [T: "on yhtä suuri kuin tai suurempi kuin"] # 0x2a9a (en: 'double line equal to or greater than', google: 'kaksoisviiva, joka on yhtä suuri tai suurempi') + - "⪛": [T: "kaksoisviivainen on yhtä suuri kuin tai pienempi kuin"] # 0x2a9b (en: 'double line slanted equal to or less than', google translation) + - "⪜": [T: "kaksoisviivainen on yhtä suuri kuin tai suurempi kuin"] # 0x2a9c (en: 'double line slanted equal to or greater than', google translation) + - "⪝": [T: "likimäärin tai pienempi kuin"] # 0x2a9d (en: 'similar or less than', google: 'samanlainen tai vähemmän kuin') + - "⪞": [T: "likimäärin tai suurempi kuin"] # 0x2a9e (google: 'samanlainen tai suurempi kuin') + - "⪟": [T: "likimäärin jonka alapuolella vähemmän kuin jonka alapuolella on yhtä suuri kuin"] # 0x2a9f (google: 'samanlainen yläpuolella vähemmän kuin yllä oleva merkki') + - "⪠": [T: "likimäärin jonka alapuolella suurempi kuin jonka alapuolella on yhtä suuri kuin"] # 0x2aa0 (google: 'samanlainen yläpuolella suurempi kuin yllä oleva merkki') + - "⪡": [T: "sisäkkäiset pienempi kuin"] # 0x2aa1 (en: 'double nested less than', google: 'kaksinkertainen sisäkkäin vähemmän kuin') + - "⪢": [T: "sisäkkäiset suurempi kuin"] # 0x2aa2 (en: 'double nested greater than', google: 'kaksinkertainen sisäkkäinen suurempi kuin') + - "⪣": [T: "kaksi sisälläistä pienempi kuin alaviivalla"] # 0x2aa3 (en: 'double nested less than with underbar', google translation) + - "⪤": [T: "pienempi kuin -merkki suurempi kuin -merkin päällä"] # 0x2aa4 (en: 'greater than overlapping less than', google: 'suurempi kuin päällekkäisyys vähemmän kuin') + - "⪥": [T: "suurempi kuin pienempi kuin"] # 0x2aa5 (google: 'suurempi kuin vähemmän kuin') + - "⪦": [T: "pienempi kuin suljettu käyrällä"] # 0x2aa6 (google: 'vähemmän kuin käyrä suljettu') + - "⪧": [T: "suurempi kuin suljettu käyrällä"] # 0x2aa7 (google: 'suurempi kuin käyrä suljettu') + - "⪨": [T: "pienempi kuin suljettu käyrällä tai yhtä suuri kuin"] # 0x2aa8 (google: 'vähemmän kuin suljettuna käyrällä viistolla tasavertaisesti') + - "⪩": [T: "suurempi kuin suljettu käyrällä tai yhtä suuri kuin"] # 0x2aa9 (google: 'suurempi kuin suljettu kaarulla, joka on viistolla yhtä suuri') + - "⪪": [T: "pienempi kuin vaakaviivalla"] # 0x2aaa (google: 'pienempi kuin') + - "⪫": [T: "suurempi kuin vaakaviivalla"] # 0x2aab (google: 'suurempi kuin') + - "⪬": [T: "pienempi kuin vaakaviivalla tai yhtä suuri kuin"] # 0x2aac (google: 'pienempi tai yhtä suuri kuin') + - "⪭": [T: "suurempi kuin vaakaviivalla tai yhtä suuri kuin"] # 0x2aad (google: 'suurempi tai yhtä suuri kuin') + - "⪮": [T: "ero välillä"] # 0x2aae (en: 'equals sign with bumpy above', google: 'yhtä suuri kuin kuohuttava yllä') # FI: translation unclear + - "⪯": [T: "edeltää jonka alapuolella yksiviivainen yhtä suuri kuin"] # 0x2aaf (google: 'ennen yhden rivin yläpuolella on yhtä suuri kuin merkki') + - "⪰": [T: "seuraa jonka alapuolella yksiviivainen yhtä suuri kuin"] # 0x2ab0 (en: 'succeeds above single line equals sign', google translation) + - "⪱": [T: "edeltää jonka alapuolella yksiviivainen ei yhtä suuri kuin"] # 0x2ab1 (en: 'precedes above single line not equal to', google translation) + - "⪲": [T: "seuraa jonka alapuolella yksiviivainen ei yhtä suuri kuin"] # 0x2ab2 (en: 'succeeds above single line not equal to', google translation) + - "⪳": [T: "edeltää jonka alapuolella yhtä suuri kuin"] # 0x2ab3 (en: 'precedes above equals sign', google translation) + - "⪴": [T: "seuraa jonka alapuolella yhtä suuri kuin"] # 0x2ab4 (en: 'succeeds above equals sign', google translation) + - "⪵": [T: "edeltää mutta ei ole yhtä suuri kuin"] # 0x2ab5 (en: 'precedes above not equal to', google: 'edellä on edellä, joka ei ole yhtä suuri kuin') + - "⪶": [T: "seuraa mutta ei ole yhtä suuri kuin"] # 0x2ab6 (en: 'succeeds above not equal to', google: 'onnistuu yläpuolella, ei ole yhtä suuri kuin') + - "⪷": [T: "edeltää ja on likimäärin"] # 0x2ab7 (en: 'precedes above almost equal to', google translation) + - "⪸": [T: "seuraa ja on likimäärin"] # 0x2ab8 (en: 'succeeds above almost equal to', google translation) + - "⪹": [T: "edeltää mutta ei ole likimäärin"] # 0x2ab9 (en: 'precedes above not almost equal to', google translation) + - "⪺": [T: "seuraa mutta ei ole likimäärin"] # 0x2aba (en: 'succeeds above not almost equal to', google translation) + - "⪻": [T: "kaksinkertainen edeltää"] # 0x2abb (google: 'kaksinkertainen edeltävä') + - "⪼": [T: "kaksinkertainen seuraa"] # 0x2abc (google: 'double onnistuu') + - "⪽": [T: "osajoukko pisteellä"] # 0x2abd (en: 'subset with dot', google: 'alajoukko pisteellä') + - "⪾": [T: "ylijoukko pisteellä"] # 0x2abe (en: 'superset with dot', google: 'superset pisteellä') + - "⪿": [T: "osajoukko ja alapuolella plus"] # 0x2abf (en: 'subset with plus sign below', google: 'alajoukko plus -merkki alla') + - "⫀": [T: "ylijoukko ja alapuolella plus"] # 0x2ac0 (en: 'superset with plus sign below', google: 'superset alla olevalla merkinnällä') + - "⫁": [T: "osajoukko ja alapuolella kertomerkki"] # 0x2ac1 (en: 'subset with multiplication sign below', google: 'alajoukko alla olevalla kertolaskulla') + - "⫂": [T: "ylijoukko ja alapuolella kertomerkki"] # 0x2ac2 (en: 'superset with multiplication sign below', google: 'superset alla olevalla kertolaskulla') + - "⫃": [T: "osajoukko tai yhtä suuri kuin ja yläpuolella piste"] # 0x2ac3 (en: 'subset of or equal to with dot above', google: 'alajoukko tai yhtä suuri kuin yllä olevalla pisteellä') + - "⫄": [T: "ylijoukko tai yhtä suuri kuin ja yläpuolella piste"] # 0x2ac4 (en: 'superset of or equal to with dot above', google: 'superset tai yhtä suuri kuin yllä olevalla pisteellä') + - "⫅": [T: "osajoukko tai yhtä suuri kuin"] # 0x2ac5 (en: 'subset of above equals sign', google translation) + - "⫆": [T: "ylijoukko tai yhtä suuri kuin"] # 0x2ac6 (en: 'superset of above equals sign', google translation) + - "⫇": [T: "likimäärin osajoukko"] # 0x2ac7 (en: 'subset of above tilde operator', google: 'yllä olevan tilde -operaattorin osajoukko') + - "⫈": [T: "likimäärin ylijoukko"] # 0x2ac8 (en: 'superset of above tilde operator', google: 'tilde -operaattorin yläpuolella') + - "⫉": [T: "osajoukko jonka alapuolella likimäärin yhtä suuri kuin"] # 0x2ac9 (en: 'subset of above almost equal to', google translation) + - "⫊": [T: "ylijoukko jonka alapuolella likimäärin yhtä suuri kuin"] # 0x2aca (en: 'superset of above almost equal to', google translation) + - "⫋": [T: "osajoukko mutta ei yhtä suuri kuin"] # 0x2acb (en: 'subset above not equal to', google translation) + - "⫌": [T: "ylijoukko mutta ei yhtä suuri kuin"] # 0x2acc (en: 'superset of above not equal to', google translation) + - "⫍": [T: "laatikko-operaattori jonka vasen puoli avoin"] # 0x2acd (en: 'square left open box operator', google translation) # FI: translation unclear + - "⫎": [T: "laatikko-operaattori jonka oikea puoli avoin"] # 0x2ace (en: 'square right open box operator', google translation) # FI: translation unclear + - "⫏": [T: "suljettu osajoukko"] # 0x2acf (google: 'suljettu alajoukko') + - "⫐": [T: "suljettu ylijoukko"] # 0x2ad0 (google: 'suljettu superset') + - "⫑": [T: "suljettu osajoukko tai yhtä suuri kuin"] # 0x2ad1 (google: 'suljettu osajoukko tai yhtä suuri kuin') + - "⫒": [T: "suljettu ylijoukko tai yhtä suuri kuin"] # 0x2ad2 (google: 'suljettu superset tai yhtä suuri kuin') + - "⫓": [T: "osajoukko ylijoukon yläpuolella"] # 0x2ad3 (en: 'subset above superset', google: 'supersetin yläpuolella') + - "⫔": [T: "ylijoukko osajoukon yläpuolella"] # 0x2ad4 (en: 'superset above subset', google: 'superset alajoukon yläpuolella') + - "⫕": [T: "osajoukko osajoukon yläpuolella"] # 0x2ad5 (en: 'subset above subset', google: 'alajoukko alajoukossa') + - "⫖": [T: "ylijoukko ylijoukon yläpuolella"] # 0x2ad6 (en: 'superset above superset', google: 'superset supersetin yläpuolella') + - "⫗": [T: "ylijoukko osajoukon vieressä"] # 0x2ad7 (google: 'superset alajoukon vieressä') + - "⫘": [T: "ylijoukko osajoukon vieressä yhdistettynä viivalla"] # 0x2ad8 (en: 'superset beside and joined by dash with subset', google: 'superset vieressä ja liittyi viivalla alajoukkoon') + - "⫙": [T: "alaspäin aukeava kuuluu joukkoon"] # 0x2ad9 (google: 'elementti avautumisesta alaspäin') + - "⫚": [T: "hanko t-yläosalla"] # 0x2ada (en: 'pitchfork with tee top', google: 'pitchfork tee -top') # FI: translation unclear + - "⫛": [T: "poikittainen leikkaus"] # 0x2adb (google: 'poikittainen risteys') # FI: translation unclear + - "⫝̸": [T: "haarukka"] # 0x2adc (en: 'forking', google translation) # FI: translation unclear + - "⫝": [T: "ei-haarukka"] # 0x2add (en: 'nonforking', google translation) # FI: translation unclear + - "⫞": [T: "lyhyt nasta vasemmalle"] # 0x2ade (en: 'short left tack', google translation) + - "⫟": [T: "lyhyt nasta alaspäin"] # 0x2adf (en: 'short down tack', google translation) + - "⫠": [T: "lyhyt nasta ylöspäin"] # 0x2ae0 (en: 'short up tack', google translation) + - "⫡": [T: "kohtisuora ja s"] # 0x2ae1 (en: 'perpendicular with s', google translation) + - "⫢": [T: "pystysuora palkki ja kolminkertainen oikea kääntöportti"] # 0x2ae2 (en: 'vertical bar triple right turnstile', google translation) + - "⫣": [T: "kaksinkertainen pystysuora viiva ja vasen kääntöportti"] # 0x2ae3 (en: 'double vertical bar left turnstile', google translation) + - "⫤": [T: "pystyviiva ja vasemmanpuoleinen kaksoiskääntöportti"] # 0x2ae4 (en: 'vertical bar double left turnstile', google: 'pystysuora palkki kaksinkertainen vasen kääntölaite') + - "⫥": [T: "kaksoispystyviiva ja vasemmanpuoleinen kaksoiskääntöportti"] # 0x2ae5 (en: 'double vertical bar double left turnstile', google translation) + - "⫦": [T: "pitkä viiva kahden pystyviivan vasemmanpuoleisesta viivasta"] # 0x2ae6 (google: 'pitkä viiva double pystysuoran vasemmalta jäseneltä') + - "⫧": [T: "lyhyt nasta alaspäin yläviivalla"] # 0x2ae7 (en: 'short down tack with overbar', google: 'lyhyt alaspäin tarttuva ylikuormitus') + - "⫨": [T: "lyhyt nasta ylöspäin alaviivalla"] # 0x2ae8 (en: 'short up tack with underbar', google: 'lyhyt up takki alapalkissa') + - "⫩": [T: "lyhyt nasta ylöspäin jonka alapuolella lyhyt nasta alaspäin"] # 0x2ae9 (google: 'lyhyt ylösnopeus lyhyen alaspäin') + - "⫪": [T: "kaksinkertainen nasta alaspäin"] # 0x2aea (en: 'double down tack', google translation) + - "⫫": [T: "kaksinkertainen nasta ylöspäin"] # 0x2aeb (google: 'kaksinkertainen tarttuva') + - "⫬": [T: "kaksoisviiva ei"] # 0x2aec (en: "double stroke not sign" google: 'kaksinkertainen isku ei allekirjoittaa') + - "⫭": [T: "käännetty kaksoisviiva ei"] # 0x2aed (en: "reversed double stroke not sign" google: 'käänteinen kaksoishalvaus ei allekirjoittaa') + - "⫮": [T: "ei jaa käännetyllä negaatioviivalla"] # 0x2aee (en: 'does not divide with reversed negation slash', google: 'ei jaa käännetyn kielteisen viivan kanssa') + - "⫯": [T: "pystyviiva ja ympyrä yläpuolella"] # 0x2aef (en: 'vertical line with circle above', google: 'pystysuora viiva ympyrän kanssa') + - "⫰": [T: "pystyviiva ja ympyrä alapuolella"] # 0x2af0 (en: 'vertical line with circle below', google: 'pystysuora viiva, jossa ympyrä alla') + - "⫱": [T: "nasta alaspäin ja ympyrä alapuolella"] # 0x2af1 (en: 'down tack with circle below', google: 'alaspäin ympyrä alla') + - "⫲": [T: "yhdensuuntainen poikkiviivalla"] # 0x2af2 (en: 'parallel with horizontal stroke', google: 'yhdensuuntainen vaakasuuntaisen iskun kanssa') + - "⫳": [T: "yhdensuuntainen tildellä"] # 0x2af3 (en: 'parallel with tilde operator', google: 'rinnakkain tilde -operaattorin kanssa') + - "⫴": [T: "kolminkertainen pystysuora viiva binäärirelaatiolla"] # 0x2af4 (en: 'triple vertical bar binary relation', google translation) + - "⫵": [T: "kolminkertainen pystysuora viiva poikkiviivalla"] # 0x2af5 (en: 'triple vertical bar with horizontal stroke', google translation) + - "⫶": [T: "kolmoispisteoperaattori"] # 0x2af6 (en: 'triple colon operator', google translation) + - "⫷": [T: "kolminkertainen sisäkkäinen vähemmän kuin"] # 0x2af7 (en: 'triple nested less than', google translation) + - "⫸": [T: "kolminkertainen sisäkkäinen suurempi kuin"] # 0x2af8 (en: 'triple nested greater than', google translation) + - "⫹": [T: "pienempi kuin tai vino kaksinkertainen on yhtä suuri kuin"] # 0x2af9 (en: 'double line slanted less than or equal to', google translation) + - "⫺": [T: "suurempi kuin tai vino kaksinkertainen on yhtä suuri kuin"] # 0x2afa (en: 'double line slanted greater than or equal to', google translation) + - "⫻": [T: "kolminkertainen vinoviiva binäärirelaatiolla"] # 0x2afb (en: 'triple solidus binary relation', google translation) + - "⫼": [T: "suuri kolminkertainen pystyviiva"] # 0x2afc (en: 'large triple vertical bar operator', google translation) + - "⫽": [T: "kaksoisvinoviiva"] # 0x2afd (en: 'double solidus operator', google translation) + - "⫾": [T: "valkoinen pystysuora palkki"] # 0x2afe (en: 'white vertical bar', google translation) + - "⫿": [T: "valkoinen pystysuora palkki"] # 0x2aff (en: 'white vertical bar', google translation) + - "⬀": [T: "yläoikealle osoittava valkoinen nuoli"] # 0x2b00 (en: 'north east white arrow', google translation) + - "⬁": [T: "ylävasemmalle osoittava valkoinen nuoli"] # 0x2b01 (en: 'north west white arrow', google translation) + - "⬂": [T: "alaoikealle osoittava valkoinen nuoli"] # 0x2b02 (en: 'south east white arrow', google translation) + - "⬃": [T: "alavasemmalle osoittava valkoinen nuoli"] # 0x2b03 (en: 'south west white arrow', google translation) + - "⬄": [T: "oikealle ja vasemmalle osoittava valkoinen nuoli"] # 0x2b04 (en: 'left right white arrow', google translation) + - "⬅": [T: "vasen musta nuoli"] # 0x2b05 (en: 'leftwards black arrow', google translation) + - "⬆": [T: "ylöspäin osoittava musta nuoli"] # 0x2b06 (en: 'upwards black arrow', google translation) + - "⬇": [T: "alaspäin osoittava musta nuoli"] # 0x2b07 (en: 'downwards black arrow', google translation) + - "⬈": [T: "yläoikealle osoittava musta nuoli"] # 0x2b08 (en: 'north east black arrow', google translation) + - "⬉": [T: "ylävasemmalle osoittava musta nuoli"] # 0x2b09 (en: 'north west black arrow', google translation) + - "⬊": [T: "alaoikealle osoittava musta nuoli"] # 0x2b0a (en: 'south east black arrow', google translation) + - "⬋": [T: "alavasemmalle osoittava musta nuoli"] # 0x2b0b (en: 'south west black arrow', google translation) + - "⬌": [T: "vasemmalle ja oikealle osoittava musta nuoli"] # 0x2b0c (en: 'left right black arrow', google translation) + - "⬍": [T: "ylös ja alas osoittava musta nuoli"] # 0x2b0d (en: 'up down black arrow', google translation) + - "⬎": [T: "oikealle ja alas osoittava nuoli"] # 0x2b0e (en: 'rightwards arrow with tip downwards', google translation) + - "⬏": [T: "oikealle ja ylös osoittava nuoli"] # 0x2b0f (en: 'rightwards arrow with tip upwards', google translation) + - "⬐": [T: "vasemmalle ja alas osoittava nuoli"] # 0x2b10 (en: 'leftwards arrow with tip downwards', google translation) + - "⬑": [T: "vasemmalle ja ylös osoittava nuoli"] # 0x2b11 (en: 'leftwards arrow with tip upwards', google translation) + - "⬒": [T: "neliö mustalla yläpuoliskolla"] # 0x2b12 (en: 'square with top half black', google translation) + - "⬓": [T: "neliö mustalla alapuoliskolla"] # 0x2b13 (en: 'square with bottom half black', google translation) + - "⬔": [T: "neliö jonka oikea diagonaali musta"] # 0x2b14 (en: 'square with upper right diagonal half black', google translation) + - "⬕": [T: "neliö jonka vasen diagonaali musta"] # 0x2b15 (en: 'square with lower left diagonal half black', google translation) + - "⬖": [T: "timantti jonka vasen puoli musta"] # 0x2b16 (en: 'diamond with left half black', google translation) + - "⬗": [T: "timantti jonka oikea puoli musta"] # 0x2b17 (en: 'diamond with right half black', google translation) + - "⬘": [T: "timantti mustalla yläpuoliskolla"] # 0x2b18 (en: 'diamond with top half black', google translation) + - "⬙": [T: "timantti mustalla alapuoliskolla"] # 0x2b19 (en: 'diamond with bottom half black', google translation) + - "⬚": [T: "laatikko"] # 0x2b1a (en: 'box', google translation) + - "⬛": [T: "musta iso neliö"] # 0x2b1b (en: 'black large square', google translation) + - "⬜": [T: "valkoinen iso neliö"] # 0x2b1c (en: 'white large square', google translation) + - "⬝": [T: "musta hyvin pieni neliö"] # 0x2b1d (en: 'black very small square', google translation) + - "⬞": [T: "valkoinen hyvin pieni neliö"] # 0x2b1e (en: 'white very small square', google translation) + - "⬟": [T: "musta viisikulmio"] # 0x2b1f (en: 'black pentagon', google translation) + - "⬠": [T: "valkoinen viisikulmio"] # 0x2b20 (en: 'white pentagon', google translation) + - "⬡": [T: "valkoinen kuusikulmio"] # 0x2b21 (en: 'white hexagon', google translation) + - "⬢": [T: "musta kuusikulmio"] # 0x2b22 (en: 'black hexagon', google translation) + - "⬣": [T: "vaaka musta kuusikulmio"] # 0x2b23 (en: 'horizontal black hexagon', google translation) + - "⬤": [T: "musta iso ympyrä"] # 0x2b24 (en: 'black large circle', google translation) + - "⬥": [T: "musta keskisuuri timantti"] # 0x2b25 (en: 'black medium diamond', google translation) + - "⬦": [T: "valkoinen keskisuuri timantti"] # 0x2b26 (en: 'white medium diamond', google translation) + - "⬧": [T: "musta keskipitkä vinoneliö"] # 0x2b27 (en: 'black medium lozenge', google translation) + - "⬨": [T: "valkoinen keskisuuri vinoneliö"] # 0x2b28 (en: 'white medium lozenge', google translation) + - "⬩": [T: "musta pieni timantti"] # 0x2b29 (en: 'black small diamond', google translation) + - "⬪": [T: "musta pieni vinoneliö"] # 0x2b2a (en: 'black small lozenge', google translation) + - "⬫": [T: "valkoinen pieni vinoneliö"] # 0x2b2b (en: 'white small lozenge', google translation) + - "⬬": [T: "musta vaakasuora ellipsi"] # 0x2b2c (en: 'black horizontal ellipse', google translation) + - "⬭": [T: "valkoinen vaakasuora ellipsi"] # 0x2b2d (en: 'white horizontal ellipse', google translation) + - "⬮": [T: "musta pystysuora ellipsi"] # 0x2b2e (en: 'black vertical ellipse', google translation) + - "⬯": [T: "valkoinen pystysuora ellipsi"] # 0x2b2f (en: 'white vertical ellipse', google translation) + - "⬰": [T: "vasen nuoli pienellä ympyrällä"] # 0x2b30 (en: 'left arrow with small circle', google translation) + - "⬱": [T: "kolme vasemmanpuoleista nuolta"] # 0x2b31 (en: 'three leftwards arrows', google translation) + - "⬲": [T: "vasen nuoli ympyröidulla plus-merkillä"] # 0x2b32 (en: 'left arrow with circled plus', google translation) + - "⬳": [T: "pitkä vasen kiemuranuoli"] # 0x2b33 (en: 'long leftwards squiggle arrow', google translation) + - "⬴": [T: "vasen kaksipäinen nuoli pystysuoralla viivalla"] # 0x2b34 (en: 'leftwards two headed arrow with vertical stroke', google translation) + - "⬵": [T: "vasen kaksipäinen nuoli kaksinkertaisella pystysuoralla viivalla"] # 0x2b35 (en: 'leftwards two headed arrow with double vertical stroke', google translation) + - "⬶": [T: "vasen kaksipäinen nuoli pystyviivasta"] # 0x2b36 (en: 'leftwards two headed arrow from bar', google translation) + - "⬷": [T: "vasen kaksipäinen kolmoiskatkoviivanuoli"] # 0x2b37 (en: 'leftwards two headed triple dash arrow', google translation) + - "⬸": [T: "vasen nuoli katkoviivalla"] # 0x2b38 (en: 'leftwards arrow with dotted stem', google translation) + - "⬹": [T: "vasen nuoli hännällä ja pystyviivalla"] # 0x2b39 (en: 'leftwards arrow with tail with vertical stroke', google translation) + - "⬺": [T: "vasen nuoli hännällä ja kaksinkertaisella pystyviivalla"] # 0x2b3a (en: 'leftwards arrow with tail with double vertical stroke', google translation) + - "⬻": [T: "vasen kaksipäinen nuoli hännällä"] # 0x2b3b (en: 'leftwards two headed arrow with tail', google translation) + - "⬼": [T: "vasen kaksipäinen nuoli hännällä ja pystysuoralla viivalla"] # 0x2b3c (en: 'leftwards two headed arrow with tail with vertical stroke', google translation) + - "⬽": [T: "vasen kaksipäinen nuoli hännällä ja kaksinkertaisella pystysuoralla viivalla"] # 0x2b3d (en: 'leftwards two headed arrow with tail with double vertical stroke', google translation) + - "⬾": [T: "vasen nuoli x:n läpi"] # 0x2b3e (en: 'leftwards arrow through x', google translation) + - "⬿": [T: "suoraan vasemmalle osoittava aaltonuoli"] # 0x2b3f (en: 'wave arrow pointing directly left', google translation) + - "⭀": [T: "on yhtä suuri kuin vasemman nuolen yläpuolella"] # 0x2b40 (en: 'equals sign above leftwards arrow', google translation) + - "⭁": [T: "käännetty tilde vasemman nuolen yläpuolella"] # 0x2b41 (en: 'reverse tilde operator above leftwards arrow', google translation) + - "⭂": [T: "likimäärin yhtä suuri kuin vasemman nuolen alapuolella"] # 0x2b42 (en: 'leftwards arrow above reverse almost equal to', google translation) + - "⭃": [T: "oikea nuoli suurempi kuin läpi"] # 0x2b43 (en: 'rightwards arrow through greater than', google translation) + - "⭄": [T: "oikea nuoli ylijoukon läpi"] # 0x2b44 (en: 'rightwards arrow through superset', google translation) + - "⭅": [T: "vasen nelinkertainen nuoli"] # 0x2b45 (en: 'leftwards quadruple arrow', google translation) + - "⭆": [T: "oikea nelinkertainen nuoli"] # 0x2b46 (en: 'rightwards quadruple arrow', google translation) + - "⭇": [T: "käännetty tilde oikean nuolen yläpuolella"] # 0x2b47 (en: 'reverse tilde operator above rightwards arrow', google translation) + - "⭈": [T: "käännetty likimäärin yhtä suuri kuin oikean nuolen alapuolella"] # 0x2b48 (en: 'rightwards arrow above reverse almost equal to', google translation) + - "⭉": [T: "tilde vasemman nuolen yläpuolella"] # 0x2b49 (en: 'tilde operator above leftwards arrow', google translation) + - "⭊": [T: "likimäärin yhtä suuri kuin vasemman nuolen alapuolella"] # 0x2b4a (en: 'leftwards arrow above almost equal to', google translation) + - "⭋": [T: "vasen nuoli käännetyn tilden yläpuolella"] # 0x2b4b (en: 'leftwards arrow above reverse tilde operator', google translation) + - "⭌": [T: "oikea nuoli käännetyn tilden yläpuolella"] # 0x2b4c (en: 'rightwards arrow above reverse tilde operator', google translation) + - "⭐": [T: "tähti"] # 0x2b50 (google: 'valkoinen keskisuuri tähti') + - "⭑": [T: "musta pieni tähti"] # 0x2b51 (google: 'musta pieni tähti') + - "⭒": [T: "valkoinen pieni tähti"] # 0x2b52 (google: 'valkoinen pieni tähti') + - "⭓": [T: "musta oikealle osoittava viisikulmio"] # 0x2b53 (en: 'black right pointing pentagon', google translation) + - "⭔": [T: "valkoinen oikealle osoittava viisikulmio"] # 0x2b54 (en: 'white right pointing pentagon', google translation) + - "⭕": [T: "raskas iso ympyrä"] # 0x2b55 (en: 'heavy large circle', google translation) + - "⭖": [T: "raskas ovaali jonka sisällä ovaali"] # 0x2b56 (en: 'heavy oval with oval inside', google translation) + - "⭗": [T: "raskas ympyrä jonka sisällä ympyrä"] # 0x2b57 (en: 'heavy circle with circle inside', google translation) + - "⭘": [T: "raskas ympyrä"] # 0x2b58 (en: 'heavy circle', google translation) + - "⭙": [T: "raskas ympyröity saltire"] # 0x2b59 (en: 'heavy circled saltire', google translation) + - "⸀": [T: "suoran kulman korvaamismerkki"] # 0x2e00 (en: 'right angle substitution marker', google translation) + - "⸁": [T: "suoran kulman korvaamismerkki pisteellä"] # 0x2e01 (en: 'right angle dotted substitution marker', google translation) + - "⸂": [T: "vasen korvaus hakasulku"] # 0x2e02 (en: 'left substitution bracket', google translation) + - "⸃": [T: "oikea korvaus hakasulku"] # 0x2e03 (en: 'right substitution bracket', google translation) + - "⸄": [T: "vasen korvaus hakasulku pisteellä"] # 0x2e04 (en: 'left dotted substitution bracket', google translation) + - "⸅": [T: "oikea korvaus hakasulku pisteellä"] # 0x2e05 (en: 'right dotted substitution bracket', google translation) + - "⸆": [T: "korotettu interpolointimerkki"] # 0x2e06 (en: 'raised interpolation marker', google translation) + - "⸇": [T: "korotettu interpolointimerkki pisteellä"] # 0x2e07 (en: 'raised dotted interpolation marker', google translation) + - "⸈": [T: "transposointimerkki pisteellä"] # 0x2e08 (en: 'dotted transposition marker marker', google translation) + - "⸉": [T: "vasen transponointi hakasulku"] # 0x2e09 (en: 'left transposition bracket', google translation) + - "⸊": [T: "oikea transponointi hakasulku"] # 0x2e0a (en: 'right transposition bracket', google translation) + - "⸋": [T: "korotettu neliö"] # 0x2e0b (en: 'raised square', google translation) + - "⸌": [T: "vasen korotettu poistosulku"] # 0x2e0c (en: 'left raised omission bracket', google translation) + - "⸍": [T: "oikea korotettu poistosulku"] # 0x2e0d (en: 'right raised omission bracket', google translation) + - "⸎": [T: "toimituskoronis"] # 0x2e0e (en: 'editorial coronis', google translation) + - "⸏": [T: "kappale"] # 0x2e0f (en: 'paragraphos', google translation) + - "⸐": [T: "haarukkakappale"] # 0x2e10 (en: 'forked paragraphos', google translation) + - "⸑": [T: "käännetty haarukkakappale"] # 0x2e11 (en: 'reversed forked paragraphos', google translation) + - "⸒": [T: "hypodiastoli"] # 0x2e12 (en: 'hypodiastole', google translation) + - "⸓": [T: "obelos pisteellä"] # 0x2e13 (en: 'dotted obelos', google translation) + - "⸔": [T: "ankkuri alaspäin"] # 0x2e14 (en: 'downwards ancora', google translation) + - "⸕": [T: "ankkuri ylöspäin"] # 0x2e15 (en: 'upwards ancora', google translation) + - "⸖": [T: "oikealle osoittava kulma pisteillä"] # 0x2e16 (en: 'dotted right pointing angle', google translation) + - "⸗": [T: "kaksinkertainen vino tavuviiva"] # 0x2e17 (en: 'double oblique hyphen', google translation) + - "⸘": [T: "käänteinen huutokysymys"] # 0x2e18 (en: 'inverted interrobang', google translation) + - "⸙": [T: "palmun oksa"] # 0x2e19 (en: 'palm branch', google translation) + - "⸚": [T: "tavuviiva treemalla"] # 0x2e1a (en: 'hyphen with diaeresis', google translation) + - "⸛": [T: "tilde ja rengas yläpuolella"] # 0x2e1b (en: 'tilde with ring above', google translation) + - "⸜": [T: "vasen matala parafraasi hakasulku"] # 0x2e1c (en: 'left low paraphrase bracket', google translation) + - "⸝": [T: "oikea matala parafraasi hakasulku"] # 0x2e1d (en: 'right low paraphrase bracket', google translation) + - "⸞": [T: "tilde ja piste yläpuolella"] # 0x2e1e (en: 'tilde with dot above', google translation) + - "⸟": [T: "tilde ja piste alapuolella"] # 0x2e1f (en: 'tilde with dot below', google translation) + - "⸠": [T: "vasen pystysuora palkki piikillä"] # 0x2e20 (en: 'left vertical bar with quill', google translation) + - "⸡": [T: "oikea pystysuora palkki piikillä"] # 0x2e21 (en: 'right vertical bar with quill', google translation) + - "⸢": [T: "ylävasen puolihakasulku"] # 0x2e22 (en: 'top left half bracket', google translation) + - "⸣": [T: "yläoikea puolihakasulku"] # 0x2e23 (en: 'top right half bracket', google translation) + - "⸤": [T: "alavasen puolihakasulku"] # 0x2e24 (en: 'bottom left half bracket', google translation) + - "⸥": [T: "alaoikea puolihakasulku"] # 0x2e25 (en: 'bottom right half bracket', google translation) + - "⸦": [T: "vasen sivusuuntainen u-hakasulku"] # 0x2e26 (en: 'left sideways u bracket', google translation) + - "⸧": [T: "oikea sivusuuntainen u-hakasulku"] # 0x2e27 (en: 'right sideways u bracket', google translation) + - "⸨": [T: "vasen kaksinkertainen sulku"] # 0x2e28 (en: 'left double parentheses', google translation) + - "⸩": [T: "oikea kaksinkertainen sulku"] # 0x2e29 (en: 'right double parentheses', google translation) + - "⸪": [T: "kaksi pistettä yhden pisteen päällä"] # 0x2e2a (en: 'two dots over one dot punctuation', google translation) + - "⸫": [T: "yksi piste kahden pisteen päällä"] # 0x2e2b (en: 'one dot over two dots punctuation', google translation) + - "⸬": [T: "neljä pistettä neliön muodossa"] # 0x2e2c (en: 'squared four dot punctuation', google translation) + - "⸭": [T: "viisi pistettä"] # 0x2e2d (en: 'five dot mark', google translation) + - "⸮": [T: "käännetty kysymysmerkki"] # 0x2e2e (en: 'reversed question mark', google translation) + - "ⸯ": [T: "pystysuora tilde"] # 0x2e2f (en: 'vertical tilde', google translation) + - "⸰": [T: "rengaspiste"] # 0x2e30 (en: 'ring point', google translation) + - "⸱": [T: "sanaerotinpiste"] # 0x2e31 (en: 'word separator middle dot', google translation) + - "⸲": [T: "käännetty pilkku"] # 0x2e32 (en: 'turned comma', google translation) + - "⸳": [T: "nostettu piste"] # 0x2e33 (en: 'raised dot', google translation) + - "⸴": [T: "nostettu pilkku"] # 0x2e34 (en: 'raised comma', google translation) + - "⸵": [T: "käännetty puolipiste"] # 0x2e35 (en: 'turned semicolon', google translation) + - "⸶": [T: "tikari vasemmalla suojalla"] # 0x2e36 (en: 'dagger with left guard', google translation) + - "⸷": [T: "tikari oikealla suojalla"] # 0x2e37 (en: 'dagger with right guard', google translation) + - "⸸": [T: "käännetty tikari"] # 0x2e38 (en: 'turned dagger', google translation) + - "⸹": [T: "yläpuolimerkki"] # 0x2e39 (en: 'top half section sign', google translation) # FI: translation unclear + - "⸺": [T: "kaksoisajatusviiva"] # 0x2e3a (en: 'two em dash', google translation) + - "⸻": [T: "kolmoisajatusviiva"] # 0x2e3b (en: 'three em dash', google translation) + - "〃": [T: "sama sisältö -merkki"] # 0x3003 (google translation) + - "〈": [T: "vasen kulmasulku"] # 0x3008 (en: 'left angle bracket', google translation) + - "〉": [T: "oikea kulmasulku"] # 0x3009 (en: 'right angle bracket', google translation) + - "《": [T: "vasen kaksoiskulmasulku"] # 0x300a (google: 'vasen kaksoiskulma kiinnike') + - "》": [T: "oikea kaksoiskulmasulku"] # 0x300b (google: 'oikea kaksoiskulma kiinnike') + - "「": [T: "vasen nurkka hakasulku"] # 0x300c (en: 'left corner bracket', google translation) + - "」": [T: "oikea nurkka hakasulku"] # 0x300d (en: 'right corner bracket', google translation) + - "『": [T: "vasen valkoinen nurkka hakasulku"] # 0x300e (en: 'left white corner bracket', google translation) + - "』": [T: "oikea valkoinen nurkkahakasulku"] # 0x300f (en: 'right white corner bracket', google translation) + - "【": [T: "vasen musta linssimäinen hakasulku"] # 0x3010 (en: 'left black lenticular bracket', google translation) + - "】": [T: "oikea musta linssimäinen hakasulku"] # 0x3011 (en: 'right black lenticular bracket', google translation) + - "〔": [T: "vasen kilpikonnankuori hakasulku"] # 0x3014 (google: 'vasen kilpikonnan kuoren kiinnike') + - "〕": [T: "oikea kilpikonnankuori hakasulku"] # 0x3015 (google: 'oikea kilpikonnakuoren kiinnike') + - "〖": [T: "vasen valkoinen linssimäinen hakasulku"] # 0x3016 (en: 'left white lenticular bracket', google translation) + - "〗": [T: "oikea valkoinen linssimäinen hakasulku"] # 0x3017 (en: 'right white lenticular bracket', google translation) + - "〘": [T: "vasen valkoinen kilpikonnakuori hakasulku"] # 0x3018 (en: 'left white tortoise shell bracket', google translation) + - "〙": [T: "oikea valkoinen kilpikonnakuori hakasulku"] # 0x3019 (en: 'right white tortoise shell bracket', google translation) + - "〚": [T: "vasen valkoinen neliö hakasulku"] # 0x301a (google: 'vasen valkoinen neliömäki') + - "〛": [T: "oikea valkoinen neliö hakasulku"] # 0x301b (google: 'oikea valkoinen neliömäki') + - "〜": [T: "aaltomainen viiva"] # 0x301c (en: 'wave dash', google translation) + - "〰": [T: "aaltoileva viiva"] # 0x3030 (en: 'wavy dash', google: 'aaltoileva viiva') + - "㉈": [T: "ympyröity numero kymmenen mustalla neliöllä"] # 0x3248 (en: 'circled number ten on black square', google translation) + - "㉉": [T: "ympyröity numero kaksikymmentä mustalla neliöllä"] # 0x3249 (en: 'circled number twenty on black square', google translation) + - "㉊": [T: "ympyröity numero kolmekymmentä mustalla neliöllä"] # 0x324a (en: 'circled number thirty on black square', google translation) + - "㉋": [T: "ympyröity numero neljäkymmentä mustalla neliöllä"] # 0x324b (en: 'circled number forty on blacks square', google translation) + - "㉌": [T: "ympyröity numero viisikymmentä mustalla neliöllä"] # 0x324c (en: 'circled number fifty on black square', google translation) + - "㉍": [T: "ympyröity numero kuusikymmentä mustalla neliöllä"] # 0x324d (en: 'circled number sixty on black square', google translation) + - "㉎": [T: "ympyröity numero seitsemänkymmentä mustalla neliöllä"] # 0x324e (en: 'circled number seventy on black square', google translation) + - "㉏": [T: "ympyröity numero kahdeksankymmentä mustalla neliöllä"] # 0x324f (en: 'circled number eighty on black square', google translation) + - "㉑": [T: "ympyröity numero kaksikymmentäyksi"] # 0x3251 (en: 'circled number twenty one', google translation) + - "㉒": [T: "ympyröity numero kaksikymmentäkaksi"] # 0x3252 (en: 'circled number twenty two', google translation) + - "㉓": [T: "ympyröity numero kaksikymmentäkolme"] # 0x3253 (en: 'circled number twenty three', google translation) + - "㉔": [T: "ympyröity numero kaksikymmentäneljä"] # 0x3254 (en: 'circled number twenty four', google translation) + - "㉕": [T: "ympyröity numero kaksikymmentäviisi"] # 0x3255 (en: 'circled number twenty five', google translation) + - "㉖": [T: "ympyröity numero kaksikymmentäkuusi"] # 0x3256 (en: 'circled number twenty six', google translation) + - "㉗": [T: "ympyröity numero kaksikymmentäseitsemän"] # 0x3257 (en: 'circled number twenty seven', google translation) + - "㉘": [T: "ympyröity numero kaksikymmentäkahdeksan"] # 0x3258 (en: 'circled number twenty eight', google translation) + - "㉙": [T: "ympyröity numero kaksikymmentäyhdeksän"] # 0x3259 (en: 'circled number twenty nine', google translation) + - "㉚": [T: "ympyröity numero kolmekymmentä"] # 0x325a (en: 'circled number thirty', google translation) + - "㉛": [T: "ympyröity numero kolmekymmentäyksi"] # 0x325b (en: 'circled number thirty one', google translation) + - "㉜": [T: "ympyröity numero kolmekymmentäkaksi"] # 0x325c (en: 'circled number thirty two', google translation) + - "㉝": [T: "ympyröity numero kolmekymmentäkolme"] # 0x325d (en: 'circled number thirty three', google translation) + - "㉞": [T: "ympyröity numero kolmekymmentäneljä"] # 0x325e (en: 'circled number thirty four', google translation) + - "㉟": [T: "ympyröity numero kolmekymmentäviisi"] # 0x325f (en: 'circled number thirty five', google translation) + - "㊱": [T: "ympyröity numero kolmekymmentäkuusi"] # 0x32b1 (en: 'circled number thirty six', google translation) + - "㊲": [T: "ympyröity numero kolmekymmentäseitsemän"] # 0x32b2 (en: 'circled number thirty seven', GPT-5.4 translation) + - "㊳": [T: "ympyröity numero kolmekymmentäkahdeksan"] # 0x32b3 (en: 'circled number thirty eight', GPT-5.4 translation) + - "㊴": [T: "ympyröity numero kolmekymmentäyhdeksän"] # 0x32b4 (en: 'circled number thirty nine', GPT-5.4 translation) + - "㊵": [T: "ympyröity numero neljäkymmentä"] # 0x32b5 (en: 'circled number forty', GPT-5.4 translation) + - "㊶": [T: "ympyröity numero neljäkymmentäyksi"] # 0x32b6 (en: 'circled number forty one', GPT-5.4 translation) + - "㊷": [T: "ympyröity numero neljäkymmentäkaksi"] # 0x32b7 (en: 'circled number forty two', GPT-5.4 translation) + - "㊸": [T: "ympyröity numero neljäkymmentäkolme"] # 0x32b8 (en: 'circled number forty three', GPT-5.4 translation) + - "㊹": [T: "ympyröity numero neljäkymmentäneljä"] # 0x32b9 (en: 'circled number forty four', GPT-5.4 translation) + - "㊺": [T: "ympyröity numero neljäkymmentäviisi"] # 0x32ba (en: 'circled number forty five', GPT-5.4 translation) + - "㊻": [T: "ympyröity numero neljäkymmentäkuusi"] # 0x32bb (en: 'circled number forty six', GPT-5.4 translation) + - "㊼": [T: "ympyröity numero neljäkymmentäseitsemän"] # 0x32bc (en: 'circled number forty seven', GPT-5.4 translation) + - "㊽": [T: "ympyröity numero neljäkymmentäkahdeksan"] # 0x32bd (en: 'circled number forty eight', GPT-5.4 translation) + - "㊾": [T: "ympyröity numero neljäkymmentäyhdeksän"] # 0x32be (en: 'circled number forty nine', GPT-5.4 translation) + - "㊿": [T: "ympyröity numero viisikymmentä"] # 0x32bf (en: 'circled number fifty', GPT-5.4 translation) + - "㋌": [T: "elohopea"] # 0x32cc (en: 'mercury', google translation) + - "㋍": [T: "ergiä"] # 0x32cd (google translation) + - "㋎": [T: "elektronivolttia"] # 0x32ce (en: 'electron volts', google translation) + - "㋏": [T: "L T D"] # 0x32cf (en: 'limited liability sign', google translation) + - "㍱": [T: "hehtopascalia"] # 0x3371 (en: 'hectopascals', google translation) + - "㍲": [T: "daltonia"] # 0x3372 (en: 'daltons', google translation) + - "㍳": [T: "tähtieteellistä yksikköä"] # 0x3373 (en: 'astronomical units', google translation) + - "㍴": [T: "baaria"] # 0x3374 (en: 'bars', google translation) + - "㍵": [T: "o V"] # 0x3375 (google translation) + - "㍶": [T: "parsekia"] # 0x3376 (google translation) + - "㍷": [T: "desimetriä"] # 0x3377 (en: 'decimeters', google translation) + - "㍸": [T: "neliödesimetriä"] # 0x3378 (en: 'decimeters squared', google translation) + - "㍹": [T: "kuutiodesimetriä"] # 0x3379 (en: 'decimeters cubed', google translation) + - "㍺": [T: "I U"] # 0x337a (en: 'instrumental units', google translation) + - "㎀": [T: "pikoampeeria"] # 0x3380 (google translation) + - "㎁": [T: "nanoampeeria"] # 0x3381 (google translation) + - "㎂": [T: "mikroampeeria"] # 0x3382 (en: 'microamps', google translation) + - "㎃": [T: "milliampeeria"] # 0x3383 (en: 'milliamps', google translation) + - "㎄": [T: "kiloampeeria"] # 0x3384 (google translation) + - "㎅": [T: "Kilobittiä"] # 0x3385 (en: 'kilobytes', google translation) + - "㎆": [T: "megatavua"] # 0x3386 (en: 'megabytes', google translation) + - "㎇": [T: "gigatavua"] # 0x3387 (en: 'gigabytes', google translation) + - "㎈": [T: "kaloria"] # 0x3388 (en: 'calories', google translation) + - "㎉": [T: "kilokaloria"] # 0x3389 (en: 'kilocalories', google translation) + - "㎊": [T: "pifaradayta"] # 0x338a (google translation) + - "㎋": [T: "nanofaradayta"] # 0x338b (en: 'nanofarads', google translation) + - "㎌": [T: "mikrofaradayta"] # 0x338c (en: 'microfarads', google translation) + - "㎍": [T: "mikrogrammaa"] # 0x338d (en: 'micrograms', google translation) + - "㎎": [T: "milligrammaa"] # 0x338e (en: 'milligrams', google translation) + - "㎏": [T: "kilogrammaa"] # 0x338f (en: 'kilograms', google translation) + - "㎐": [T: "hertsiä"] # 0x3390 (google translation) + - "㎑": [T: "kilohertsiä"] # 0x3391 (en: 'kilohertz', google translation) + - "㎒": [T: "megahertsiä"] # 0x3392 (en: 'megahertz', google translation) + - "㎓": [T: "gigahertsiä"] # 0x3393 (en: 'gigahertz', google translation) + - "㎔": [T: "terahertsiä"] # 0x3394 (en: 'terahertz', google translation) + - "㎕": [T: "mikrolitraa"] # 0x3395 (en: 'microliters', google translation) + - "㎖": [T: "millilitraa"] # 0x3396 (en: 'milliliters', google translation) + - "㎗": [T: "desilitraa"] # 0x3397 (google translation) + - "㎘": [T: "kilolitraa"] # 0x3398 (en: 'kiloliters', google translation) + - "㎙": [T: "femtometriä"] # 0x3399 (en: 'femtometers', google translation) + - "㎚": [T: "nanometriä"] # 0x339a (en: 'nanometers', google translation) + - "㎛": [T: "mikrometriä"] # 0x339b (en: 'micrometers', google translation) + - "㎜": [T: "millimetriä"] # 0x339c (en: 'millimeters', google translation) + - "㎝": [T: "senttimetriä"] # 0x339d (en: 'centimeters', google translation) + - "㎞": [T: "kilometriä"] # 0x339e (en: 'kilometers', google translation) + - "㎟": [T: "neliömillimetriä"] # 0x339f (en: 'millimeters squared', google translation) + - "㎠": [T: "neliösenttimetriä"] # 0x33a0 (en: 'centimeters squared', google translation) + - "㎡": [T: "neliömetriä"] # 0x33a1 (en: 'meters squared', google translation) + - "㎢": [T: "neliökilometriä"] # 0x33a2 (en: 'kilometers squared', google translation) + - "㎣": [T: "kuutiomillimetriä"] # 0x33a3 (en: 'millimeters cubed', google translation) + - "㎤": [T: "kuutiosenttimetriä"] # 0x33a4 (en: 'centimeters cubed', google translation) + - "㎥": [T: "kuutiometriä"] # 0x33a5 (en: 'meters cubed', google translation) + - "㎦": [T: "kuutiokilometriä"] # 0x33a6 (en: 'kilometers cubed', google translation) + - "㎧": [T: "metriä sekunnissa"] # 0x33a7 (en: 'meters per second', google translation) + - "㎨": [T: "metriä per neliösekunti"] # 0x33a8 (en: 'meters per second squared', google translation) + - "㎩": [T: "pascalia"] # 0x33a9 (google translation) + - "㎪": [T: "kilopascalia"] # 0x33aa (google translation) + - "㎫": [T: "megapascalia"] # 0x33ab (google translation) + - "㎬": [T: "gigapascalia"] # 0x33ac (google translation) + - "㎭": [T: "radiaania"] # 0x33ad (en: 'rads', google translation) + - "㎮": [T: "radiaania sekunnissa"] # 0x33ae (en: 'rads per second', google translation) + - "㎯": [T: "radiaania neliösekunnissa"] # 0x33af (en: 'rads per second squared', google translation) + - "㎰": [T: "pikosekuntia"] # 0x33b0 (en: 'picoseconds', google translation) + - "㎱": [T: "nanosekuntia"] # 0x33b1 (en: 'nanoseconds', google translation) + - "㎲": [T: "mikrosekuntia"] # 0x33b2 (en: 'microseconds', google translation) + - "㎳": [T: "millisekuntia"] # 0x33b3 (en: 'milliseconds', google translation) + - "㎴": [T: "pikovolttia"] # 0x33b4 (google translation) + - "㎵": [T: "nanovolttia"] # 0x33b5 (en: 'nanovolts', google translation) + - "㎶": [T: "mikrovolttia"] # 0x33b6 (en: 'microvolts', google translation) + - "㎷": [T: "millivolttia"] # 0x33b7 (google translation) + - "㎸": [T: "kilovolttia"] # 0x33b8 (en: 'kilovolts', google translation) + - "㎹": [T: "megavolttia"] # 0x33b9 (google translation) + - "㎺": [T: "pikowattia"] # 0x33ba (google translation) + - "㎻": [T: "nanowattia"] # 0x33bb (en: 'nanowatts', google translation) + - "㎼": [T: "mikrowattia"] # 0x33bc (en: 'microwatts', google translation) + - "㎽": [T: "milliwattia"] # 0x33bd (google translation) + - "㎾": [T: "kilowattia"] # 0x33be (en: 'kilowatts', google translation) + - "㎿": [T: "megawattia"] # 0x33bf (google translation) + - "㏀": [T: "kilo-ohmia"] # 0x33c0 (google translation) + - "㏁": [T: "megaohmia"] # 0x33c1 (google translation) + - "㏂": [T: "a m"] # 0x33c2 (en: 'attometers', google translation) + - "㏃": [T: "becquerelia"] # 0x33c3 (google translation) + - "㏄": [T: "kuutiosenttimetriä"] # 0x33c4 (en: 'cubic centimeters', google translation) + - "㏅": [T: "candelaa"] # 0x33c5 (google translation) + - "㏆": [T: "coulombia kilogrammassa"] # 0x33c6 (en: 'coulombs per kilogram', google translation) + - "㏇": [T: "C o piste"] # 0x33c7 (en: 'cardiac output', google translation) + - "㏈": [T: "desibeliä"] # 0x33c8 (en: 'decibels', google translation) + - "㏉": [T: "grayta"] # 0x33c9 (en: 'grays', google translation) + - "㏊": [T: "hehtaaria"] # 0x33ca (en: 'hectares', google translation) + - "㏋": [T: "hevosvoimaa"] # 0x33cb (en: 'horsepower', google translation) + - "㏌": [T: "tuumaa"] # 0x33cc (en: 'inches', google translation) + - "㏍": [T: "kilokelviniä"] # 0x33cd (google translation) + - "㏎": [T: "kilometriä"] # 0x33ce (en: 'kilometers', google translation) + - "㏏": [T: "solmua"] # 0x33cf (en: 'knots', google translation) + - "㏐": [T: "lumenia"] # 0x33d0 (google translation) + - "㏑": [T: "luonnollinen logaritmi"] # 0x33d1 (en: 'natural log', google translation) + - "㏒": [T: "logaritmi"] # 0x33d2 (en: 'logarithm', google translation) + - "㏓": [T: "luxia"] # 0x33d3 (google translation) + - "㏔": [T: "millibarnia"] # 0x33d4 (google translation) + - "㏕": [T: "milliä"] # 0x33d5 (en: 'mills', google translation) + - "㏖": [T: "moolia"] # 0x33d6 (en: 'moles', google translation) + - "㏗": [T: "p H"] # 0x33d7 (google translation) + - "㏘": [T: "pikometriä"] # 0x33d8 (en: 'picometers', google translation) + - "㏙": [T: "miljoonasosaa"] # 0x33d9 (en: 'parts per million', google translation) + - "㏚": [T: "petaröntgeniä"] # 0x33da (google translation) + - "㏛": [T: "steradiaania"] # 0x33db (en: 'steradians', google translation) + - "㏜": [T: "sievertiä"] # 0x33dc (en: 'sieverts', google translation) + - "㏝": [T: "weberiä"] # 0x33dd (google translation) + - "㏞": [T: "volttia per metri"] # 0x33de (en: 'volts per meter', google translation) + - "㏟": [T: "ampeeria per metri"] # 0x33df (en: 'amps per meter', google translation) + - "㏿": [T: "gallonaa"] # 0x33ff (en: 'gallons', google translation) + - "": [T: "on yhtä suuri kuin ja hattu alapuolella"] # 0xe900 (en: 'equals with hat below', google translation) + - "": [T: "on yhtä suuri kuin ja plus yläpuolella"] # 0xe901 (en: 'equals with plus above', google translation) + - "": [T: "on yhtä suuri kuin ja plus alapuolella"] # 0xe902 (en: 'equals with plus below', google translation) + - "": [T: "tilde ja plus yläpuolella"] # 0xe903 (en: 'tilde with plus above', google translation) + - "": [T: "tilde ja plus alapuolella"] # 0xe904 (en: 'tilde with plus below', google translation) + - "": [T: "kaksinkertainen on yhtä suuri kuin ja alapuolella suurempi kuin"] # 0xe908 (en: 'equal double over greater than', google translation) + - "": [T: "kaksinkertainen on yhtä suuri kuin ja alapuolella pienempi kuin"] # 0xe909 (en: 'equal double over less than', google translation) + - "": [T: "sisältää tai on yhtä suuri kuin"] # 0xe90a (en: 'contains or equal to', google translation) + - "": [T: "ylijoukko tai yhtä suuri kuin"] # 0xe90b (en: 'superset of or equal to', google translation) + - "": [T: "osajoukko tai yhtä suuri kuin"] # 0xe90c (en: 'subset of or equal to', google translation) + - "": [T: "on yhtä suuri kuin ja alapuolella pienempi kuin"] # 0xe90d (en: 'equal over less than', google translation) + - "": [T: "kuuluu joukkoon tai on yhtä kuin"] # 0xe912 (en: 'element of or equal to', google translation) + - "": [T: "yhtä suuri tai suurempi kuin"] # 0xe913 (en: 'equal to or greater than', google translation) + - "": [T: "likimäärin ylijoukko"] # 0xe914 (en: 'approximate superset of', google translation) + - "": [T: "likimäärin osajoukko"] # 0xe915 (en: 'approximate subset of', google translation) + - "": [T: "ylijoukko pisteellä sisältää alirelaationa"] # 0xe916 (en: 'superset of with dot includes as sub relation', google translation) # FI: translation unclear + - "": [T: "osajoukko pisteellä sisältyy alirelaationa"] # 0xe917 (en: 'subset of with dot is included in as sub relation', google translation) # FI: translation unclear + - "": [T: "on yhtä suuri kuin ja piste alapuolella"] # 0xe918 (en: 'equal with dot below', google translation) + - "": [T: "vasen piste jonka alapuolella miinus jonka alapuolella oikea piste"] # 0xe919 (en: 'left dot over minus over right dot', google translation) + - "": [T: "oikea piste jonka alapuolella miinus jonka alapuolella vasen piste"] # 0xe91a (en: 'right dot over minus over left dot', google translation) + - "": [T: "melkein yhtä suuri kuin miinus"] # 0xe91f (en: 'almost equal to minus', google translation) + - "": [T: "kaksinkertainen kulmikas malja"] # 0xe920 (en: 'double square cup', google translation) + - "": [T: "kaksinkertainen kulmikas kupu"] # 0xe921 (en: 'double square cap', google translation) + - "": [T: "pienempi kuin, yhtä suuri kuin tai suurempi kuin"] # 0xe922 (en: 'less than equal to or greater than', google translation) + - "": [T: "tilde pisteellä"] # 0xe924 (en: 'tilde with dot', google translation) + - "": [T: "tilde kahdella pisteellä"] # 0xe925 (en: 'tilde with two dots', google translation) + - "": [T: "pienempi kuin, suurempi kuin tai yhtä suuri kuin"] # 0xe926 (en: 'less than greater than or equal to', google translation) + - "": [T: "suurempi kuin, pienempi kuin tai yhtä suuri kuin"] # 0xe927 (en: 'greater than less than or equal to', google translation) + - "": [T: "vastaa tai on pienempi kuin"] # 0xe928 (en: 'equivalent to or less than', google translation) + - "": [T: "vastaa tai on suurempi kuin"] # 0xe929 (en: 'equivalent to or greater than', google translation) + - "": [T: "vasen avoin laatikkooperaattori"] # 0xe92a (en: 'left open box operator', google translation) + - "": [T: "oikea avoin laatikkooperaattori"] # 0xe92b (en: 'right open box operator', google translation) + - "": [T: "identtinen pisteellä"] # 0xe92c (en: 'identical to with dot', google translation) + - "": [T: "suurempi kuin, yhtä suuri kuin tai pienempi kuin"] # 0xe92d (en: 'greater than equal to or less than', google translation) + - "": [T: "palkkioperaattori"] # 0xe92e (en: 'bar operator', google translation) + - "": [T: "kaksinkertainen palkkioperaattori"] # 0xe92f (en: 'double bar operator', google translation) + - "": [T: "kolminkertainen palkkioperaattori"] # 0xe930 (en: 'triple bar operator', google translation) + - "": [T: "pienempi kuin tai likimäärin yhtä suuri kuin"] # 0xe932 (en: 'less than or approximately equal to', google translation) + - "": [T: "suuremmpi kuin tai likimäärin yhtä suuri kuin"] # 0xe933 (en: 'greater than or approximately equal to', google translation) + - "": [T: "sisäkkäinen vähemmän kuin"] # 0xe936 (en: 'nested less than', google translation) + - "": [T: "sisäkkäinen suurempi kuin"] # 0xe937 (en: 'nested greater than', google translation) + - "": [T: "edeltää tai vastaa"] # 0xe93a (en: 'precedes or equivalent to', google translation) + - "": [T: "seuraa tai vastaa"] # 0xe93b (en: 'succeeds or equivalent to', google translation) + - "": [T: "edeltää ja alapuolella on yhtä suuri kuin"] # 0xe940 (en: 'precedes over equal', google translation) + - "": [T: "seuraa ja alapuolella on yhtä suuri kuin"] # 0xe941 (en: 'succeeds over equal', google translation) + - "": [T: "vähemmän kuin, on yhtä suuri kuin, vino suurempi kuin"] # 0xe942 (en: 'less equal slanted greater', google translation) # FI: translation unclear + - "": [T: "suurempi kuin, on yhtä suuri kuin, vino pienempi kuin"] # 0xe943 (en: 'greater equal slanted less', google translation) + - "": [T: "täyttää ehdon"] # 0xe948 (en: 'satisfied by', google translation) # FI: translation unclear + - "": [T: "laiska s"] # 0xe949 (en: 'lazy s', google translation) + - "": [T: "ei väite"] # 0xe94a (en: 'not assertion', google translation) # FI: translation unclear + - "": [T: "kaksinkertainen on yhtä suuri kuin"] # 0xe94b (en: 'double equal', google translation) + - "": [T: "kolminkertainen on yhtä suuri kuin"] # 0xe94c (en: 'triple equal', google translation) + - "": [T: "sääntö viivästynyt"] # 0xe94d (en: 'rule delayed', google translation) # FI: translation unclear + - "": [T: "alias delimiter"] # 0xe94e (google translation) # FI: translation unclear + - "": [T: "normaali alaryhmä palkilla"] # 0xe950 (en: 'normal subgroup of with bar', google translation) + - "": [T: "sisältää normaalina alaryhmänä palkilla"] # 0xe951 (en: 'contains as normal subgroup with bar', google translation) + - "": [T: "pyöreä seuraa"] # 0xe954 (en: 'round implies', google translation) # FI: translation unclear + - "": [T: "hymy palkin alla"] # 0xe955 (en: 'smile under bar', google translation) # FI: translation unclear + - "": [T: "murjotus palkin alla"] # 0xe956 (en: 'frown over bar', google translation) # FI: translation unclear + - "": [T: "ylijoukko tai lähes yhtä kuin"] # 0xe957 (en: 'superset of or almost equal to', google translation) + - "": [T: "osajoukko tai lähes yhtä kuin"] # 0xe958 (en: 'subset of or almost equal to', google translation) + - "": [T: "suurempi kuin melkein yhtä suuri kuin tai pienempi kuin"] # 0xe959 (en: 'greater than almost equal to or less than', google translation) + - "": [T: "pienempi kuin melkein yhtä suuri kuin tai suurempi kuin"] # 0xe95a (en: 'less than almost equal or greater than', google translation) + - "": [T: "kaksinkertainen looginen tai"] # 0xe95c (en: 'double logical or', google translation) + - "": [T: "kaksinkertainen looginen ja"] # 0xe95d (en: 'double logical and', google translation) + - "": [T: "looginen tai ja kaksinkertainen palkki alapuolella"] # 0xe95e (en: 'logical or with double bar below', google translation) + - "": [T: "looginen tai ja palkki alapuolella"] # 0xe95f (en: 'logical or with bar below', google translation) + - "": [T: "melkein yhtä suuri kuin ja alapuolella yhtä suuri kuin"] # 0xe962 (en: 'almost equal over equal', google translation) + - "": [T: "vasemmalle osoittava kolmio kahtiajakavalla palkilla"] # 0xe964 (en: 'left pointing triangle with bisecting bar', google translation) + - "": [T: "oikealle osoittava kolmio kahtiajakavalla palkilla"] # 0xe965 (en: 'right pointing triangle with bisecting bar', google translation) + - "": [T: "on yhtä suuri kuin katkoviivoitetulla yläviivalla"] # 0xe966 (en: 'equals with dotted top line', google translation) + - "": [T: "edeltää kaksoispisteellä"] # 0xe967 (en: 'precedes with colon', google translation) + - "": [T: "seuraa kaksoispisteellä"] # 0xe968 (en: 'succeeds with colon', google translation) + - "": [T: "pienempi tai yhtä suuri kuin vino"] # 0xe969 (en: 'smaller than or equal slanted', google translation) # FI: : translation unclear + - "": [T: "suurempi kuin tai yhtä suuri kuin vino"] # 0xe96a (en: 'larger than or equal slanted', google translation) # FI: : translation unclear + - "": [T: "sisäkkäinen paljon pienempi kuin"] # 0xe96b (en: 'nested very much less than', google translation) + - "": [T: "sisäkkäinen paljon suurempi kuin"] # 0xe96c (en: 'nested very much greater than', google translation) + - "": [T: "ero variantin välillä"] # 0xe96d (en: 'difference between variant', google translation) # FI: unclear translation + - "": [T: "pienempi kuin jonka päällä suurempi kuin"] # 0xe96e (en: 'less than greater than overlay', google translation) + - "": [T: "looginen tai jonka päällä looginen tai"] # 0xe96f (en: 'logical or logical and overlay', google translation) + - "": [T: "ylijoukko ylijoukon yläpuolella"] # 0xe970 (en: 'superset over superset', google translation) + - "": [T: "osajoukko osajoukon yläpuolella"] # 0xe971 (en: 'subset over subset', google translation) + - "": [T: "ylijoukko osajoukon yläpuolella"] # 0xe972 (en: 'superset over subset', google translation) + - "": [T: "osajoukko ylijoukon yläpuolella"] # 0xe973 (en: 'subset over superset', google translation) + - "": [T: "kolminkertainen pystysuora palkki"] # 0xe979 (en: 'triple vertical bar', google translation) + - "": [T: "nelinkertainen pystysuora pistepari"] # 0xe97a (en: 'paired quadruple vertical dots', google translation) # FI: translation unclear + - "": [T: "kohtisuorassa ja alapuolella palkki"] # 0xe97b (en: 'perpendicular over bar', google translation) + - "": [T: "vasen kääntöportti kaksinkertainen pystysuora palkki"] # 0xe97c (en: 'left turnstile double vertical bar', google translation) + - "": [T: "kaksinkertainen vasen kääntöportti kaksinkertainen pystysuora palkki"] # 0xe97d (en: 'double left turnstile double vertical bar', google translation) + - "": [T: "kohtisuorassa jonka alapuolella käännetty kohtisuorassa"] # 0xe97e (en: 'perpendicular over inverted perpendicular', google translation) + - "": [T: "kaksinkertgainen vasen kääntöportti pystysuora palkki"] # 0xe97f (en: 'double left turnstile vertical bar', google translation) + - "": [T: "pallomainen kulma avautuu"] # 0xe980 (en: 'spherical angle opening up', google translation) + - "": [T: "kaksinkertainen vinoviiva"] # 0xe981 (en: 'double slash', google translation) + - "": [T: "suora kulma nurkalla"] # 0xe982 (en: 'right angle with corner', google translation) + - "": [T: "ympyröity pystysuora palkki"] # 0xe984 (en: 'circled vertical bar', google translation) + - "": [T: "ympyröity jakomerkki"] # 0xe985 (en: 'circled division sign', google translation) + - "": [T: "katkoviivoitettu vinoviiva"] # 0xe986 (en: 'dashed solidus', google translation) + - "": [T: "katkoviivoitettu kenoviiva"] # 0xe987 (en: 'dashed backslash', google translation) + - "": [T: "katkoviivoitettu puoliväliviiva"] # 0xe988 (en: 'dashed mid line', google translation) # FI: : translation unclear + - "": [T: "katkoviivoitettu pystysuora palkki"] # 0xe989 (en: 'dashed vertical bar', google translation) + - "": [T: "kohtisuorassa ja s"] # 0xe98a (en: 'perpendicular with s', google translation) + - "": [T: "kulma ja s"] # 0xe98b (en: 'angle with s', google translation) + - "": [T: "pallomainen kulma avautuu vasemmalle"] # 0xe98c (en: 'spherical angle opening left', google translation) + - "": [T: "vasemmalle avautuva kulma"] # 0xe98d (en: 'angle opening left', google translation) + - "": [T: "pystysuora palkki kaksoiskoukulla"] # 0xe98e (en: 'vertical bar with double hook', google translation) + - "": [T: "keskikokoinen pisteoperaattori vapaa radikaali"] # 0xe98f (en: 'medium dot operator free radical', google translation) + - "": [T: "valkoinen ylöspäin osoittava kolmio palkin yläpuolella"] # 0xe990 (en: 'white up pointing triangle above bar', google translation) + - "": [T: "identtinen ja yhdensuuntainen"] # 0xe991 (en: 'identical and parallel to', google translation) + - "": [T: "smash tulo"] # 0xe992 (en: 'smash product', google translation) # FI: meaning unclear + - "": [T: "kolminkertainen palkkioperaattori vaakasuoralla palkilla"] # 0xe993 (en: 'triple bar operator with horizontal bar', google translation) + - "": [T: "identtinen kaksoisvinoviivalla"] # 0xe994 (en: 'identical to with double slash', google translation) + - "": [T: "kolminkertaiset yliviivatut palkit"] # 0xe995 (en: 'triple crossed bars', google translation) # FI: : translation unclear + - "": [T: "pystysuora palkki ympyrän yläpuolella"] # 0xe996 (en: 'vertical bar over circle', google translation) + - "": [T: "pystysuora verrannollinen"] # 0xe997 (en: 'vertical proportional to', google translation) + - "": [T: "musta kuun viimeinen neljännes"] # 0xe998 (en: 'black last quarter moon', google translation) + - "": [T: "musta kuun ensimmäinen neljännes"] # 0xe999 (en: 'black first quarter moon', google translation) + - "": [T: "negatiivinen siniaalto"] # 0xe9a0 (en: 'negative sine wave', google translation) + - "": [T: "piste sulkujen sisällä"] # 0xe9a1 (en: 'parenthesized dot', google translation) + - "": [T: "sulku"] # 0xe9a2 (en: 'parens', google translation) # FI: translation unclear, "parenthesis"? + - "": [T: "valkoinen hymy"] # 0xe9a3 (en: 'white smile', google translation) + - "": [T: "valkoinen murjotus"] # 0xe9a4 (en: 'white frown', google translation) + - "": [T: "kuusikulmio"] # 0xe9a5 (en: 'hexagon', google translation) + - "": [T: "vastaa ja alapuolella plus"] # 0xe9a6 (en: 'equivalent to over plus', google translation) + - "": [T: "plus ja alapuolella vastaa"] # 0xe9a7 (en: 'plus over equivalent to', google translation) + - "": [T: "leikkaus serifillä"] # 0xe9b0 (en: 'intersection serifs', google translation) + - "": [T: "unioni serifillä"] # 0xe9b1 (google translation) + - "": [T: "neliömäinen leikkaus serifillä"] # 0xe9b2 (en: 'square intersection serifs', google translation) + - "": [T: "neliömäinen unioni serifillä"] # 0xe9b3 (google translation) + - "": [T: "edeltää, on yhtä kuin tai seuraa"] # 0xe9e0 (en: 'precedes equivalent to or succeeds', google translation) + - "": [T: "seuraa, on yhtä kuin tai edeltää"] # 0xe9e1 (en: 'succeeds equivalent to or precedes', google translation) + - "": [T: "edeltää, on lähes yhtä kuin tai seuraa"] # 0xe9e2 (en: 'precedes almost equal to or succeeds', google translation) + - "": [T: "seuraa, on lähes yhtä kuin tai edeltää"] # 0xe9e3 (en: 'succeeds almost equal to or precedes', google translation) + - "": [T: "vähemmän kuin, vastaa tai suurempi kuin"] # 0xe9f0 (en: 'less than equivalent to or greater than', google translation) + - "": [T: "suurempi kuin, vastaa tai vähemmän kuin"] # 0xe9f1 (en: 'greater than equivalent to or less than', google translation) + - "": [T: "ei hyvin paljon pienempi kuin"] # 0xea00 (en: 'not vert much less than', google translation) # FI: translation unclear, not sure if vert is very or vertical + - "": [T: "ei hyvin paljon suurempi kuin"] # 0xea01 (en: 'not vert much greater than', google translation) # FI: translation unclear, not sure if vert is very or vertical + - "": [T: "ei paljon pienempi kuin variantti"] # 0xea02 (en: 'not much less than variant', google translation) # FI: translation unclear + - "": [T: "ei paljon suurempi kuin variantti"] # 0xea03 (en: 'not much greater than variant', google translation) # FI: translation unclear + - "": [T: "pienempi kuin mutta ei yhtä suuri kuin"] # 0xea04 (en: 'less vert not double equals', google translation) # FI: translation unclear + - "": [T: "suurempi kuin mutta ei yhtä suuri kuin"] # 0xea05 (en: 'gt vert not double equals', google translation) # FI: translation unclear + - "": [T: "ei pienempi tai yhtä suuri kuin"] # 0xea06 (en: 'not less than or equal to', google translation) + - "": [T: "ei suurempi tai yhtä suuri kuin"] # 0xea07 (en: 'not greater than or equal to', google translation) + - "": [T: "ei yhtä suuri kuin eikä pienempi kuin"] # 0xea09 (en: 'neither equal to nor less than', google translation) + - "": [T: "ei sisällä tai ole yhtä suuri kuin"] # 0xea0a (en: 'does not contain or equal to', google translation) + - "": [T: "ei ylijoukko tai yhtä suuri kuin"] # 0xea0b (en: 'neither superset of nor equal to', google translation) + - "": [T: "ei osajoukko tai yhtä suuri kuin"] # 0xea0c (en: 'neither subset of nor equal to', google translation) + - "": [T: "kenoviiva osajoukko"] # 0xea0d (en: 'reverse solidus subset', google translation) + - "": [T: "ei yhtä suuri tai suurempi kuin"] # 0xea0e (en: 'neither equal to nor greater than', google translation) + - "": [T: "ei miinus tilde -operaattori"] # 0xea0f (en: 'not minus tilde operator', google translation) + - "": [T: "ei yhtä suuri kuin tai pienempi kuin"] # 0xea10 (en: 'neither equal to nor less than', google translation) + - "": [T: "ei tilde -operaattori"] # 0xea11 (en: 'not tilde operator', google translation) + - "": [T: "ei kuulu joukkoon tai ole yhtä suuri kuin"] # 0xea12 (en: 'not element of or equal to', google translation) + - "": [T: "ei yhtä suuri kuin tai suurempi kuin"] # 0xea13 (en: 'neither equal to nor greater than', google translation) + - "": [T: "ei melkein yhtä suuri"] # 0xea14 (en: 'not almost equal', google translation) + - "": [T: "ei seuraa vastaavaa"] # 0xea15 (en: 'not succeeds similar', google translation) # FI: translation unclear + - "": [T: "pienempi kuin tai vino yhtä suuri kuin vinoviivalla"] # 0xea16 (en: 'less than or slanted equal to with slash', google translation) + - "": [T: "suurempi kuin tai vino yhtä suuri kuin vinoviivalla"] # 0xea17 (en: 'greater than or slanted equal to with slash', google translation) + - "": [T: "ylijoukko vinoviiva"] # 0xea1a (google translation) + - "": [T: "ei sisällä"] # 0xea1b (en: 'does not contain', google translation) + - "": [T: "ei pienempi kuin tai yhtä suuri kuin"] # 0xea1d (en: 'not less than or equal to', google translation) + - "": [T: "ei suurempi kuin tai yhtä suuri kuin"] # 0xea1e (en: 'not greater than or equal to', google translation) + - "": [T: "ei melkein yhtä suuri kuin miinus"] # 0xea1f (en: 'not almost equal to minus', google translation) + - "": [T: "ei kuulu joukkoon yläpisteellä"] # 0xea22 (en: 'negated set membership dot above', google translation) + - "": [T: "ei vert kulma"] # 0xea2c (en: 'not vert angle', google translation) # FI: translation unclear + - "": [T: "ei yhdensuuntainen vino"] # 0xea2d (en: 'not parallel slanted', google translation) + - "": [T: "ei palkkioperaattori"] # 0xea2e (en: 'not bar operator', google translation) + - "": [T: "ei kaksoispalkkioperaattori"] # 0xea2f (en: 'not double bar operator', google translation) + - "": [T: "ei kolminkertainen palkkioperaattori"] # 0xea30 (en: 'not triple bar operator', google translation) + - "": [T: "vähemmän kuin, mutta ei suunnilleen yhtä suuri kuin"] # 0xea32 (en: 'less than but not approximately equal to', google translation) + - "": [T: "suurempi kuin, mutta ei suunnilleen yhtä suuri kuin"] # 0xea33 (en: 'greater than but not approximately equal to', google translation) + - "": [T: "vähemmän kuin tai ei yhtä suuri kuin"] # 0xea34 (en: 'less than or not equal to', google translation) + - "": [T: "suurempi kuin tai ei yhtä suuri kuin"] # 0xea35 (en: 'greater than or not equal to', google translation) + - "": [T: "ei sisäkkäinen vähemmän kuin"] # 0xea36 (en: 'not nested less than', google translation) # FI: translation unclear + - "": [T: "ei sisäkkäinen suurempi kuin"] # 0xea37 (en: 'not nested greater than', google translation) # FI: translation unclear + - "": [T: "ei paljon pienempi kuin"] # 0xea38 (en: 'not much less than', google translation) + - "": [T: "ei paljon suurempi kuin"] # 0xea39 (en: 'not much greater than', google translation) + - "": [T: "edeltää, mutta ei vastaa"] # 0xea3a (en: 'precedes but not equivalent to', google translation) + - "": [T: "onnistuu, mutta ei vastaa"] # 0xea3b (en: 'succeeds but not equivalent to', google translation) + - "": [T: "edeltää, mutta ei yhtä suuri kuin"] # 0xea3c (en: 'precedes but not equal to', google translation) + - "": [T: "seuraa, mutta ei yhtä suuri kuin"] # 0xea3d (en: 'succeeds but not equal to', google translation) + - "": [T: "ei ole yhtä suuri kuin tai edeltää"] # 0xea3e (en: 'does not equal or precede', google translation) + - "": [T: "ei ole yhtä suuri kuin tai seuraa"] # 0xea3f (en: 'does not equal or succeed', google translation) + - "": [T: "edeltää, mutta ei yhtä suuri kuin"] # 0xea40 (en: 'precedes but not equal to', google translation) + - "": [T: "seuraa, mutta ei yhtä suuri kuin"] # 0xea41 (en: 'succeeds but not equal to', google translation) + - "": [T: "ei osajoukko tai yhtä suuri kuin"] # 0xea42 (en: 'not subset of nor equal to', google translation) + - "": [T: "ei ylijoukko tai yhtä suuri kuin"] # 0xea43 (en: 'not superset of nor equal to', google translation) + - "": [T: "osajoukko tai ei yhtä suuri kuin"] # 0xea44 (en: 'subset of or not equal to', google translation) + - "": [T: "ylijoukko tai ei yhtä suuri kuin"] # 0xea45 (en: 'superset of or not equal to', google translation) + - "": [T: "ei osajoukko tai yhtä suuri kuin"] # 0xea46 (en: 'not subset of nor equal to', google translation) + - "": [T: "ei ylijoukko tai yhtä suuri kuin"] # 0xea47 (en: 'not superset of nor equal to', google translation) + - "": [T: "ei kolminkertainen pienempi kuin"] # 0xea48 (en: 'not triple less than', google translation) + - "": [T: "ei kolminkertainen suurempi kuin"] # 0xea49 (en: 'not triple greater than', google translation) + - "": [T: "ei edellä on yhtä suuri kuin"] # 0xea4c (en: 'not precedes equals', google translation) + - "": [T: "ei seuraa on yhtä suuri kuin"] # 0xea4d (en: 'not succeeds equals', google translation) + - "": [T: "ei normaali aliryhmä palkilla"] # 0xea50 (en: 'not normal subgroup of with bar', google translation) + - "": [T: "ei sisällä normaalina aliryhmänä palkilla"] # 0xea51 (en: 'does not contain as normal subgroup with bar', google translation) + - "": [T: "ei ero välillä"] # 0xea52 (en: 'not difference between', google translation) + - "": [T: "ei geometrisesti vastaa"] # 0xea53 (en: 'not geometrically equivalent to', google translation) + - "": [T: "ei vert samanlainen"] # 0xea54 (en: 'not vert similar', google translation) # FI: translation unclear + - "": [T: "ei yhtä suuri tai samanlainen"] # 0xea55 (en: 'not equal or similar', google translation) + - "": [T: "ei vert likimääräinen"] # 0xea56 (en: 'not vert approximate', google translation) + - "": [T: "ei likimääräisesti identtinen"] # 0xea57 (en: 'not approximately identical to', google translation) + - "": [T: "ei kumpu yhtä suuri kuin"] # 0xea58 (en: 'not bumpy equals', google translation) # FI: translation unclear + - "": [T: "ei kumpu yksiviivainen yhtä suuri kuin"] # 0xea59 (en: 'not bumpy single equals', google translation) # FI: translation unclear + - "": [T: "ei yhtä suuri kuin piste"] # 0xea5a (en: 'not equal dot', google translation) + - "": [T: "käännetty ei vastaa"] # 0xea5b (en: 'reverse not equivalent', google translation) + - "": [T: "ei neliömäinen osajoukko"] # 0xea60 (en: 'not square subset', google translation) + - "": [T: "ei nelimäinen ylijoukko"] # 0xea61 (en: 'not square superset', google translation) + - "": [T: "ei melkein yhtä suuri ja alapuolella yhtä suuri kuin"] # 0xea62 (en: 'not almost equal over equal', google translation) + - "": [T: "ei tiukasti vastaa"] # 0xea63 (en: 'not strictly equivalent to', google translation) + - "": [T: "ei kongruentti piste"] # 0xea64 (en: 'not congruent dot', google translation) + - "": [T: "käännetty ei ole yhtä suuri kuin"] # 0xea65 (en: 'reverse not equal', google translation) + - "": [T: "ei vasen kolmio on yhtä suuri kuin"] # 0xea70 (en: 'not vert left triangle equals', google translation) # FI: translation unclear + - "": [T: "ei oikea on yhtä suuri kuin"] # 0xea71 (en: 'not vert right triangle equals', google translation) # FI: translation unclear + - "": [T: "ei osittainen"] # 0xea80 (en: 'not partial', google translation) + - "": [T: "nuolen koristeiden pidennys"] # 0xeb00 (en: 'arrow embellishment extender', google translation) # FI: translation unclear + - "": [T: "oikea nuoli vasemman nuolen yläpuolella"] # 0xeb01 (en: 'arrow rightwards over arrow leftwards', google translation) + - "": [T: "oikea nuoli vasemman nuolen yläpuolella"] # 0xeb02 (en: 'arrow rightwards over arrow leftwards', google translation) + - "": [T: "oikea harppuuna vasemman harppuunan yläpuolella"] # 0xeb03 (en: 'harpoon right over harpoon left', google translation) + - "": [T: "oikea harppuuna vasemman harppuunan yläpuolella"] # 0xeb04 (en: 'harpoon right over harpoon left', google translation) + - "": [T: "koillis-lounaskaksoisnuoli"] # 0xeb05 (en: 'double arrow northeast southwest', google translation) + - "": [T: "luoteis-kaakkoiskaksoisnuoli"] # 0xeb06 (en: 'double arrow northwest southeast', google translation) + - "": [T: "vaakasuora harppuunapidennys"] # 0xeb07 (en: 'horizontal harpoon extender', google translation) # FI: translation unclear + - "": [T: "vasen kaarinuoli vastapäivään"] # 0xeb08 (en: 'anticlockwise arc leftwards arrow', google translation) + - "": [T: "oikea kaarinuoli vastapäivään"] # 0xeb09 (en: 'anticlockwise arc rightwards arrow', google translation) + - "": [T: "suuri oikean nuolen aksentti"] # 0xeb0b (en: 'large rightwards arrow accent', google translation) # FI: translation unclear + - "": [T: "suuri vasen nuolen aksentti"] # 0xeb0c (en: 'large leftwards arrow accent', google translation) # FI: translation unclear + - "": [T: "vasen nuolenpää"] # 0xeb0d (en: 'leftwards arrowhead', google translation) + - "": [T: "oikea nuolenpää"] # 0xeb0e (en: 'rightwards arrowhead', google translation) + - "": [T: "suuri vasen-oikea nuoli yliviivauksella"] # 0xeb0f (en: 'large left right arrow with stroke', google translation) + - "": [T: "vaakasuuntainen kaksoisnuolen pidennys"] # 0xeb10 (en: 'horizontal double arrow extender', google translation) # FI: translation unclear + - "": [T: "suuri vasen-oikea kaksinkertainen nuoli yliviivauksella"] # 0xeb11 (en: 'large left right double arrow with stroke', google translation) + - "": [T: "alaspäin osoittava nuoli ylöspäin osoittavan nuolen vasemmalla puolella"] # 0xeb12 (en: 'downwards arrow leftwards of upwards arrow', google translation) + - "": [T: "vasen nuoli kulmalla alaspäin"] # 0xeb13 (en: 'leftwards arrow with corner downwards', google translation) + - "": [T: "oikea nuoli kulmalla ylöspäin"] # 0xeb14 (en: 'rightwards arrow with corner upwards', google translation) + - "": [T: "vasen nuoli kuolmalla ylöspäin"] # 0xeb15 (en: 'leftwards arrow with corner upwards', google translation) + - "": [T: "ympyränuolen yläosa vastapäivään ja plus"] # 0xeb16 (en: 'anticlockwise top semicircle arrow with plus', google translation) + - "": [T: "ympyränuolen yläosa myötäpäivään ja miinus"] # 0xeb17 (en: 'clockwise top semicircle arrow with minus', google translation) + - "": [T: "oikea nuoli hännällä ja yliviivauksella"] # 0xeb18 (en: 'rightwards arrow with tail with stroke', google translation) + - "": [T: "oikea harppuuna alas"] # 0xeb19 (en: 'right harpoon down', google translation) + - "": [T: "vasen harppuon alas"] # 0xeb1a (en: 'left harpoon down', google translation) + - "": [T: "vasen-oikea harppuuna alas"] # 0xeb1b (en: 'left right harpoon down', google translation) + - "": [T: "vasen-oikea harppuuna ylös"] # 0xeb1c (en: 'left right harpoon up', google translation) + - "": [T: "ylös-alas harppuuna vasemmalle"] # 0xeb1d (en: 'up down harpoon left', google translation) + - "": [T: "ylös-alas harppuuna oikealle"] # 0xeb1e (en: 'up down harpoon right', google translation) + - "": [T: "ylänuoli alanuolen vasemmalla puolella"] # 0xeb1f (en: 'upwards arrow to the right of downwards arrow', google translation) + - "": [T: "vasen harppuuna palkkiin piikki ylöpäin"] # 0xeb20 (en: 'leftwards harpoon to bar with barb upwards', google translation) + - "": [T: "oikea harppuuna palkkiin piikki ylöspäin"] # 0xeb21 (en: 'rightwards harpoon to bar with barb upwards', google translation) + - "": [T: "vasen harppuuna palkkiin piikki alaspäin"] # 0xeb22 (en: 'leftwards harpoon to bar with barb downwards', google translation) + - "": [T: "oikea harppuuna palkkiin piikki alaspäin"] # 0xeb23 (en: 'rightwards harpoon to bar with barb downwards', google translation) + - "": [T: "vasen harppuuna palkista piikki ylöspäin"] # 0xeb24 (en: 'leftwards harpoon from bar with barb upwards', google translation) + - "": [T: "oikea harppuuna palkista piikki ylöspäin"] # 0xeb25 (en: 'rightwards harpoon from bar with barb upwards', google translation) + - "": [T: "vasen harppuuna palkista piikki alaspäin"] # 0xeb26 (en: 'leftwards harpoon from bar with barb downwards', google translation) + - "": [T: "oikea harppuuna palkista piikki alaspäin"] # 0xeb27 (en: 'rightwards harpoon from bar with barb downwards', google translation) + - "": [T: "harppuuna ylös palkkiin piikki vasemmalle"] # 0xeb28 (en: 'upwards harpoon to bar with barb leftwards', google translation) + - "": [T: "harppuuna alas palkkiin piikki vasemmalle"] # 0xeb29 (en: 'downwards harpoon to bar with barb leftwards', google translation) + - "": [T: "harppuuna ylös palkkiin piikki oikealle"] # 0xeb2a (en: 'upwards harpoon to bar with barb rightwards', google translation) + - "": [T: "harppuuna alas palkkiin piikki oikealle"] # 0xeb2b (en: 'downwards harpoon to bar with barb rightwards', google translation) + - "": [T: "harppuuna ylös palkista piikki vasemmalle"] # 0xeb2c (en: 'upwards harpoon from bar with barb leftwards', google translation) + - "": [T: "harppuuna alas palkista piikki vasemmalle"] # 0xeb2d (en: 'downwards harpoon from bar with barb leftwards', google translation) + - "": [T: "harppuuna ylös palkista piikki oikealle"] # 0xeb2e (en: 'upwards harpoon from bar with barb rightwards', google translation) + - "": [T: "harppuuna alas palkista piikki oikealle"] # 0xeb2f (en: 'downwards harpoon from bar with barb rightwards', google translation) + - "": [T: "nuoli ylöspäin palkkiin"] # 0xeb30 (en: 'upwards arrow to bar', google translation) + - "": [T: "nuoli alaspäin palkkiin"] # 0xeb31 (en: 'downwards arrow to bar', google translation) + - "": [T: "harppuuna ylös ja oikealla puolella harppuuna alas"] # 0xeb32 (en: 'upwards harpoon to the left of downwards harpoon', google translation) + - "": [T: "harppuuna ylös ja vasemmalla puolella harppuuna alas"] # 0xeb33 (en: 'upwards harpoon to the right of downwards harpoon', google translation) + - "": [T: "nuolenpää ylös"] # 0xeb34 (en: 'upwards arrowhead', google translation) + - "": [T: "nuolenpää alas"] # 0xeb35 (en: 'downwards arrowhead', google translation) + - "": [T: "kaksinkertainen harppuuna vasen piikki alas ja oikea piikki ylös"] # 0xeb36 (en: 'double harpoon with leftwards barb down rightwards barb up', google translation) + - "": [T: "kaksinkertainen harppuuna vasen piikki ylös ja oikea piikki alas"] # 0xeb37 (en: 'double harpoon with leftwards barb up rightwards barb down', google translation) + - "": [T: "vasen nuoli palkin yläpuolella"] # 0xeb38 (en: 'leftwards arrow over bar', google translation) + - "": [T: "oikea nuoli palkin yläpuolella"] # 0xeb39 (en: 'rightwards arrow over bar', google translation) + - "": [T: "vasen nuoli palkin alapuolella"] # 0xeb3a (en: 'leftwards arrow under bar', google translation) + - "": [T: "oikea nuoli palkin alapuolella"] # 0xeb3b (en: 'rightwards arrow under bar', google translation) + - "": [T: "vasen-oikea kolmoisnuoli"] # 0xeb3c (en: 'left right triple arrow', google translation) + - "": [T: "koillis-kaakko kaksoisnuoli"] # 0xeb3f (en: 'double arrow northeast southeast', google translation) + - "": [T: "vasen puoliympyränuoli vastapäivään"] # 0xeb40 (en: 'anticlockwise left semicircle arrow', google translation) + - "": [T: "vasen puoliympyränuoli myötäpäivään"] # 0xeb41 (en: 'clockwise left semicircle arrow', google translation) + - "": [T: "vasen avoin ympyrä vasen-oikea nuoli"] # 0xeb42 (en: 'left open circle left right arrow', google translation) # FI: translation unclear + - "": [T: "oikea nuoli tilden yläpuolella"] # 0xeb44 (en: 'rightwards arrow over tilde', google translation) + - "": [T: "vasen nuoli tilden yläpuolella"] # 0xeb45 (en: 'leftwards arrow over tilde', google translation) + - "": [T: "vasen harppuuna palkin yläpuolella"] # 0xeb48 (en: 'leftwards harpoon over bar', google translation) + - "": [T: "oikea harppuuna palkin yläpuolella"] # 0xeb49 (en: 'rightwards harpoon over bar', google translation) + - "": [T: "vasen harppuuna palkin alapuolella"] # 0xeb4a (en: 'leftwards harpoon under bar', google translation) + - "": [T: "oikea harppuuna palkin alapuolella"] # 0xeb4b (en: 'rightwards harpoon under bar', google translation) + - "": [T: "raskas musta lyhyt vasen nuoli"] # 0xeb4c (en: 'squat black leftwards arrow', google translation) + - "": [T: "oikea puoliympyränuoli myötäpäivään"] # 0xeb50 (en: 'clockwise right semicircle arrow', google translation) + - "": [T: "oikea puoliympyränuoli vastapäivään"] # 0xeb51 (en: 'anticlockwise right semicircle arrow', google translation) + - "": [T: "vasen-oikea ympyrä vasen-oikea harppuuna"] # 0xeb52 (en: 'left open circle left right harpoon', google translation) # FI: translation unclear + - "": [T: "nuoli ylös pystypalkin vasemmalla puolella"] # 0xeb58 (en: 'upwards arrow leftwards of vertical bar', google translation) + - "": [T: "nuoli alas pystypalkin vasemmalla puolella"] # 0xeb59 (en: 'downwards arrow leftwards of vertical bar', google translation) + - "": [T: "nuoli ylös pystypalkin oikealla puolella"] # 0xeb5a (en: 'upwards arrow rightwards of vertical bar', google translation) + - "": [T: "nuoli alas pystypalkin oikealla puolella"] # 0xeb5b (en: 'downwards arrow rightwards of vertical bar', google translation) + - "": [T: "oikea nuoli jatketulla koukulla alas"] # 0xeb5c (en: 'rightwards arrow with extended downwards hook', google translation) + - "": [T: "vasen nuoli jatketulla koukulla"] # 0xeb5d (en: 'leftwards arrow with extended hook', google translation) + - "": [T: "vasen nuoli jatketulla koukulla alas"] # 0xeb5e (en: 'leftwards arrow with extended downwards hook', google translation) + - "": [T: "oikea nuoli jatketulla koukulla"] # 0xeb5f (en: 'rightwards arrow with extended hook', google translation) + - "": [T: "ei oikea nuoli aaltoileva"] # 0xeb60 (en: 'not right arrow wavy', google translation) # FI: translation unclear + - "": [T: "ei oikea nuoli kaareva"] # 0xeb61 (en: 'not right arrow curved', google translation) # FI: translation unclear + - "": [T: "harppuula ylös pystypalkin vasemmalla puolella"] # 0xeb68 (en: 'upwards harpoon leftwards of vertical bar', google translation) + - "": [T: "harppuuna alas pystypalkin vasemmalla puolella"] # 0xeb69 (en: 'downwards harpoon leftwards of vertical bar', google translation) + - "": [T: "harppuuna ylös pystypalkin oikealla puolella"] # 0xeb6a (en: 'upwards harpoon rightwards of vertical bar', google translation) + - "": [T: "harppuuna alas pystypalkin oikealla puolella"] # 0xeb6b (en: 'downwards harpoon rightwards of vertical bar', google translation) + - "": [T: "pystysuora kaksoisnuolen pidennys"] # 0xeb6c (en: 'vertical double arrow extender', google translation) # FI: translation unclear + - "": [T: "pystysuora harppuuna piikki vasemmalle pidennys"] # 0xeb6d (en: 'vertical harpoon with barb left extender', google translation) + - "": [T: "pystysuora harppuuna piikki oikealle pidennys"] # 0xeb6e (en: 'vertical harpoon with barb right extender', google translation) + - "": [T: "oikea harppuuna vasemman harppuunan yläpuolella oikealla"] # 0xeb6f (en: 'right harpoon over left harpoon right', google translation) # FI: translation unclear + - "": [T: "oikea harppuuna vasemman harppuunan yläpuolella vasemmalla"] # 0xeb70 (en: 'right harpoon over left harpoon left', google translation) # FI: translation unclear + - "": [T: "vasen harppuuna oikean harppuunan yläpuolella oikealla"] # 0xeb71 (en: 'left harpoon over right harpoon right', google translation) # FI: translation unclear + - "": [T: "vasen harppuuna oikean harppuunan yläpuolella vasemmalla"] # 0xeb72 (en: 'left harpoon over right harpoon left', google translation) # FI: translation unclear + - "": [T: "vasen nuoli palkista nuolenpää"] # 0xeb73 (en: 'leftwards arrow from bar arrowhead', google translation) # FI: translation unclear + - "": [T: "vasen-oikea nuoli palkista pidennys"] # 0xeb74 (en: 'leftwards rightwards arrow from bar extender', google translation) + - "": [T: "vasen nuoli palkista häntä"] # 0xeb75 (en: 'leftwards arrow from bar tail', google translation) # FI: translation unclear + - "": [T: "oikea nuoli palkista häntä"] # 0xeb76 (en: 'rightwards arrow from bar tail', google translation) # FI: translation unclear + - "": [T: "oikea nuoli palkista nuolenpää"] # 0xeb77 (en: 'rightwards arrow from bar arrowhead', google translation) # FI: translation unclear + - "": [T: "harppuuna ylös palkista piikki vasemmalle nuolenpää"] # 0xeb78 (en: 'upwards harpoon from bar with barb leftwards arrowhead', google translation) # FI: translation unclear + - "": [T: "oikea nuoli vasemman nuolen yläpuolella oikealla"] # 0xeb79 (en: 'rightwards arrow over leftwards arrow right', google translation) # FI: translation unclear + - "": [T: "oikea nuoli vasemman nuolen yläpuolella vasemmalla"] # 0xeb7a (en: 'rightwards arrow over leftwards arrow left', google translation) # FI: translation unclear + - "": [T: "vasen nuoli oikean nuolen yläpuolella oikealla"] # 0xeb7b (en: 'leftwards arrow over rightwards arrow right', google translation) # FI: translation unclear + - "": [T: "vasen nuoli oikean nuolen yläpuolella vasemmalla"] # 0xeb7c (en: 'leftwards arrow over rightwards arrow left', google translation) # FI: translation unclear + - "": [T: "nuoli ylös palkista nuolenpää"] # 0xeb7d (en: 'upwards arrow from bar arrowhead', google translation) # FI: translation unclear + - "": [T: "nuoli ylös palkista häntä"] # 0xeb7e (en: 'upwards arrow from bar tail', google translation) # FI: translation unclear + - "": [T: "nuoli alaspäin palkista häntä"] # 0xeb7f (en: 'downwards arrow from bar tail', google translation) # FI: translation unclear + - "": [T: "nuoli alaspäin palkista nuolenpää"] # 0xeb80 (en: 'downwards arrow from bar arrowhead', google translation) # FI: translation unclear + - "": [T: "harppuuna alas palkista piikki oikealle nuolenpää"] # 0xeb81 (en: 'downwards harpoon from bar with barb rightwards arrowhead', google translation) # FI: translation unclear + - "": [T: "harppuuna ylös ja oikealla puolella harppuuna alas alas"] # 0xeb82 (en: 'upwards harpoon to the left of downwards harpoon bottom', google translation) # FI: translation unclear + - "": [T: "harppuuna ylös ja oikealla harppuuna alas"] # 0xeb83 (en: 'upwards harpoon to the left of downwards harpoon', google translation) + - "": [T: "harppuuna alas ja oikealla harppuuna ylös ylös"] # 0xeb84 (en: 'downwards harpoon to the left of upwards harpoon top', google translation) # FI: translation unclear + - "": [T: "harppuuna ylös ja oikealla harppuuna alas ylös"] # 0xeb85 (en: 'upwards harpoon to the left of downwards harpoon top', google translation) # FI: translation unclear + - "": [T: "harppuuna alas ja oikealla harppuuna ylös pidennys"] # 0xeb86 (en: 'downwards harpoon to the left of the upwards harpoon extender', google translation) + - "": [T: "harppuuna alas ja oikealla harppuuna ylös alas"] # 0xeb87 (en: 'downwards harpoon to the left of the upwards harpoon bottom', google translation) # FI: translation unclear + - "": [T: "harppuuna ylös ja oikealla harppuuna alas alas"] # 0xeb88 (en: 'upwards arrow leftwards of downwards arrow bottom', google translation) # FI: translation unclear + - "": [T: "nuoli alas ja oikealla nuoli ylös ylös"] # 0xeb89 (en: 'downwards arrow leftwards of upwards arrow top', google translation) # FI: translation unclear + - "": [T: "nuoli ylös ja oikealla nuoli alas ylös"] # 0xeb8a (en: 'upwards arrow leftwards of downwards arrow top', google translation) # FI: translation unclear + - "": [T: "nuoli alas ja oikealla nuoli ylös alas"] # 0xeb8b (en: 'downwards arrow leftwards of upwards arrow bottom', google translation) # FI: translation unclear + - "": [T: "vasen-oikeanuolipidennys"] # 0xeb8c (en: 'leftwards rightwards arrows extender', google translation) + - "": [T: "koillisnuolipidennys"] # 0xeb8d (en: 'north east arrow extender', google translation) + - "": [T: "luoteisnuolipidennys"] # 0xeb8e (en: 'north west arrow extender', google translation) + - "": [T: "alas osoittava aaltosulku vasen"] # 0xec00 (en: 'down pointing brace left', google translation) + - "": [T: "alas osoittava aaltosulku keski"] # 0xec01 (en: 'down pointing brace mid', google translation) + - "": [T: "alas osoittava aaltosulku oikea"] # 0xec02 (en: 'down pointing brace right', google translation) + - "": [T: "vaakasuora aaltosulku pidennys"] # 0xec03 (en: 'horizontal brace extender', google translation) + - "": [T: "ylös osoittava aaltosulku vasen"] # 0xec04 (en: 'up pointing brace left', google translation) + - "": [T: "ylös osoittava aaltosulku keski"] # 0xec05 (en: 'up pointing brace mid', google translation) + - "": [T: "ylös osoittava aaltosulku oikea"] # 0xec06 (en: 'up-pointing brace right', google translation) + - "": [T: "vasen pystypalkki"] # 0xec07 (en: 'left vertical bar', google translation) + - "": [T: "oikea pystypalkki"] # 0xec08 (en: 'right vertical bar', google translation) + - "": [T: "vasen kaksinkertainen pystypalkki"] # 0xec09 (en: 'left double vertical bar', google translation) + - "": [T: "oikea kaksinkertainen pystypalkki"] # 0xec0a (en: 'right double vertical bar', google translation) + - "": [T: "vaakasuora hakasulku pidennys"] # 0xec0b (en: 'horizontal bracket extender', google translation) + - "": [T: "neliön alapuoli hakasulku"] # 0xec0c (en: 'under square bracket', google translation) # FI: translation unclear + - "⎵": [T: "neliön alapuoli hakasulku"] # 0x23b5 (google: 'neliön alla') # FI: translation unclear + - "": [T: "neliön yläpuoli hakasulku"] # 0xec0d (en: 'over square bracket', google translation) # FI: translation unclear + - "⎴": [T: "neliön yläpuoli hakasulku"] # 0x23b4 (google: 'neliömäisen kiinnikkeen yli') # FI: translation unclear + - "": [T: "alahakasulku vasen"] # 0xec0e (en: 'under bracket left', google translation) # FI: translation unclear + - "": [T: "alahakasulku oikea"] # 0xec0f (en: 'under bracket right', google translation) # FI: translation unclear + - "": [T: "ylähakasulku vasen"] # 0xec10 (en: 'over bracket left', google translation) # FI: translation unclear + - "": [T: "alahakasulku oikea"] # 0xec11 (en: 'over bracket right', google translation) # FI: translation unclear + - "": [T: "vasen kaarisulku 1"] # 0xec12 (en: 'left parens 1', google translation) + - "": [T: "vasen kaarisulku 2"] # 0xec13 (en: 'left parens 2', google translation) + - "": [T: "vasen kaarisulku 3"] # 0xec14 (en: 'left parens 3', google translation) + - "": [T: "vasen kaarisulku 4"] # 0xec15 (en: 'left parens 4', google translation) + - "": [T: "oikea kaarisulku 1"] # 0xec16 (en: 'right parens 1', google translation) + - "": [T: "oikea kaarisulku 2"] # 0xec17 (en: 'right parens 2', google translation) + - "": [T: "oikea kaarisulku 3"] # 0xec18 (en: 'right parens 3', google translation) + - "": [T: "oikea kaarisulku 4"] # 0xec19 (en: 'right parens 4', google translation) + - "": [T: "radikaali 1"] # 0xec1a (en: 'radical 1', google translation) # FI: context? Radical as in root sign? + - "": [T: "radikaali 2"] # 0xec1b (en: 'radical 2', google translation) # FI: context? + - "": [T: "radikaali 3"] # 0xec1c (en: 'radical 3', google translation) # FI: context? + - "": [T: "radikaali 4"] # 0xec1d (en: 'radical 4', google translation) # FI: context? + - "": [T: "radikaali 5"] # 0xec1e (en: 'radical 5', google translation) # FI: context? + - "": [T: "radikaali pohja"] # 0xec1f (en: 'radical bottom', google translation) # FI: context? + - "": [T: "radikaali pystysuora pidennys"] # 0xec20 (en: 'radical vertical extender', google translation) # FI: context? + - "": [T: "radikaali yläosa"] # 0xec21 (en: 'radical top', google translation) # FI: context? + - "": [T: "vasen valkoinen hakasulku ylös"] # 0xec22 (en: 'left white bracket top', google translation) + - "": [T: "vasen valkoinen hakasulku pidennys"] # 0xec23 (en: 'left white bracket extender', google translation) + - "": [T: "vasen valkoinen hakasulku alas"] # 0xec24 (en: 'left white bracket bottom', google translation) + - "": [T: "oikea valkoinen hakasulku ylös"] # 0xec25 (en: 'right white bracket top', google translation) + - "": [T: "oikea valkoinen hakasulku pidennys"] # 0xec26 (en: 'right white bracket extender', google translation) + - "": [T: "oikea valkoinen hakasulku alas"] # 0xec27 (en: 'right white bracket bottom', google translation) + - "": [T: "vasen valkoinen aaltosulku"] # 0xec30 (en: 'left white curly bracket', google translation) + - "": [T: "oikea valkoinen aaltosulku"] # 0xec31 (en: 'right white curly bracket', google translation) + - "": [T: "jakokulmamerkki"] # 0xec32 (en: 'long division sign', google translation) + - "": [T: "jakokulmamerkki pidennys"] # 0xec33 (en: 'long division sign extender', google translation) + - "": [T: "lyhyt jakokulma"] # 0xec34 (en: 'short division', google translation) + - "": [T: "kaksinkertainen m-sidos lounaasta koilliseen"] # 0xec40 (en: 'double southwest to northeast em bond', google translation) + - "": [T: "kaksinkertainen m-sidos luoteesta kaakkoon"] # 0xec41 (en: 'double northwest to southeast em bond', google translation) + - "": [T: "yksinkertainen vaakasuora m-sidos"] # 0xec42 (en: 'single horizontal em bond', google translation) # FI: not happy with translations + - "": [T: "kaksinkertainen vaakasuora m-sidos"] # 0xec43 (en: 'double horizontal em bond', google translation) + - "": [T: "kolminkertainen vaakasuora m-sidos"] # 0xec44 (en: 'triple horizontal em bond', google translation) + - "": [T: "yksinkertainen pystysuora m-sidos"] # 0xec45 (en: 'single vertical em bond', google translation) + - "": [T: "kaksinkertainen pystysuora m-sidos"] # 0xec46 (en: 'double vertical em bond', google translation) + - "": [T: "kolminkertainen pystysuora m-sidos"] # 0xec47 (en: 'triple vertical em bond', google translation) + - "": [T: "pienempi kuin m-sidos"] # 0xec48 (en: 'less than em bond', google translation) + - "": [T: "suurempi kuin m-sidos"] # 0xec49 (en: 'greater than em bond', google translation) + - "": [T: "yksinkertainen vaakasuora n-sidos"] # 0xec4a (en: 'single horizontal en bond', google translation) + - "": [T: "kaksinkertainen vaakasuora n-sidos"] # 0xec4b (en: 'double horizontal en bond', google translation) + - "": [T: "kolminkertainen vaakasuora n-sidos"] # 0xec4c (en: 'triple horizontal en bond', google translation) + - "": [T: "ylävasen suorakulmio"] # 0xec80 (en: 'top left rectangle', google translation) + - "": [T: "alavasen suorakulmio"] # 0xec81 (en: 'bottom left rectangle', google translation) + - "": [T: "yläoikea suorakulmio"] # 0xec90 (en: 'top right rectangle', google translation) + - "": [T: "alaoikea suorakulmio"] # 0xec91 (en: 'bottom right rectangle', google translation) + - "": [T: "synteettinen jakokulma"] # 0xec92 (en: 'synthetic division corner', google translation) # FI: translation unclear + - "": [T: "synteettinen jakokulma vaakasuora pidennys"] # 0xec93 (en: 'synthetic division horizontal extender', google translation) # FI: translation unclear + - "": [T: "synteettinen jakokulma pystysuora pidennys"] # 0xec94 (en: 'synthetic division vertical extender', google translation) # FI: translation unclear + - "": [T: "vasen katto lattia pidennys"] # 0xec95 (en: 'left ceiling floor extender', google translation) + - "": [T: "oikea katto lattia pidennys"] # 0xec96 (en: 'right ceiling floor extender', google translation) + - "": [T: "yli hakasulku pidennys"] # 0xec97 (en: 'over bracket extender', google translation) # FI: translation unclear + - "": [T: "pystypalkki pidennys"] # 0xec98 (en: 'vertical bar extender', google translation) + - "": [T: "vasen kaksinkertainen pystypalkki pidennys"] # 0xec99 (en: 'left double vertical bar extender', google translation) + - "": [T: "vaakasuora palkki pidennys"] # 0xec9a (en: 'horizontal bar extender', google translation) + - "": [T: "ala hakasulku pidennys"] # 0xec9c (en: 'under bracket extender', google translation) # FI: translation unclear + - "": [T: "alaspäin osoittava kaarisulku oikea"] # 0xec9d (en: 'down pointing paren right', google translation) + - "": [T: "alaspäin osoittava kaarisulku pidennys"] # 0xec9e (en: 'down pointing paren extender', google translation) + - "": [T: "alaspäin osoittava kaarisulku vasen"] # 0xec9f (en: 'down pointing paren left', google translation) + - "": [T: "ylöspäin osoittava hakasulku pidennys"] # 0xeca0 (en: 'up pointing brace extender', google translation) + - "": [T: "ylöspäin osoittava kaarisulku vasen"] # 0xeca1 (en: 'up pointing paren left', google translation) + - "": [T: "ylöspäin osoittava kaarisulku pidennys"] # 0xeca2 (en: 'up pointing paren extender', google translation) + - "": [T: "ylöspäin osoittava kaarisulku oikea"] # 0xeca3 (en: 'up pointing paren right', google translation) + - "": [T: "alaspäin osoittava kaarisulku pidennys"] # 0xeca4 (en: 'down pointing brace extender', google translation) + - "": [T: "planckin vakio kahden piin yläpuolella palkki"] # 0xed00 (en: 'planck constant over two pi bar', google translation) # FI: translation unclear + - "": [T: "peili g"] # 0xed01 (en: 'mirror g', google translation) + - "": [T: "pisteetön j"] # 0xed02 (google translation) + - "": [T: "digamma"] # 0xed03 (google translation) # FI: translation unclear + - "ϝ": [T: "digamma"] # 0x3dd # FI: : translation unclear + - "": [T: "d"] # 0xed10 (en: 'd', google translation) + - "": [T: "e"] # 0xed11 (en: 'e', google translation) + - "": [T: "i"] # 0xed12 (en: 'i', google translation) + - "": [T: "j"] # 0xed13 (en: 'j', google translation) + - "ⅅ": + - SPELL: "translate('.', 'ⅅ', 'DD')" # 0xed16, 0x2145 + +# The private use chars are from MathType + - "": [T: "käyräintegraalisilmukka vastapäivään"] # 0xee00 (en: 'anticlockwise contour integral loop', google translation) + - "": [T: "käyräintegraalisilmukka myötäpäivään"] # 0xee01 (en: 'clockwise contour integral loop', google translation) + - "": [T: ""] # 0xee04 + - "": [T: ""] # 0xee05 + - "": [T: ""] # 0xee06 + - "": [T: ""] # 0xee07 + - "": [T: ""] # 0xee08 + - "": [T: ""] # 0xee09 + - "": [T: ""] # 0xee0a + - "": [T: ""] # 0xee0b + - "": [T: ""] # 0xee0c + - "": [T: "yhteinen tila koriste"] # 0xee0d (en: 'joint status embellishment', google translation) # FI: translation unclear, context? + - "": [T: "yhteinen tila korite vasen"] # 0xee0e (en: 'joint status embellishment left', google translation) # FI: translation unclear, context? + - "": [T: "yhteinen tila koriste oikea"] # 0xee0f (en: 'joint status embellishment right', google translation) # FI: translation unclear, context? + - "": [T: "yhteinen tila koriste pidennys"] # 0xee10 (en: 'joint status embellishment extender', google translation) # FI: translation unclear, context? + - "": [T: "integraalisilmukka"] # 0xee11 (en: 'integral loop', google translation) + - "": [T: "kaksinkertainen integraalisilmukka"] # 0xee12 (en: 'integral loop double', google translation) + - "": [T: "kolminkertainen integraalisilmukka"] # 0xee13 (en: 'integral loop triple', google translation) + - "": [T: "laajentuva kaksinkertainen integraalisilmukka"] # 0xee15 (en: 'expanding integral loop double', google translation) + - "": [T: "laajentuva kolminkertainen integraalisilmukka"] # 0xee16 (en: 'expanding integral loop triple', google translation) + - "": [T: "asymptoottisesti yhtä suuri kuin aksentti"] # 0xee17 (en: 'asymptotically equal to accent', google translation) + - "": [T: "yhtä suuri kuin -merkki aksentti"] # 0xee18 (en: 'equal sign accent', google translation) + - "": [T: "neljäs derivaatta"] # 0xee19 (en: 'quadruple prime', google translation) # FI: 4th derivative? + - "": [T: "palkkiaksentti avoimella ympyrällä vasen"] # 0xee1a (en: 'bar accent with open circle left', google translation) # FI: translation unclear + - "": [T: "palkkiaksentti suljetulla ympyrällä vasen"] # 0xee1b (en: 'bar accent with closed circle left', google translation) # FI: translation unclear + - "": [T: "palkkiaksentti avoimella ympyrällä oikea"] # 0xee1c (en: 'bar accent with open circle right', google translation) # FI: translation unclear + - "": [T: "palkkiaksentti ja piste yläpuolella"] # 0xee1d (en: 'bar accent with over dot', google translation) # FI: translation unclear + - "": [T: "palkkiaksentti ja piste alapuolella"] # 0xee1e (en: 'bar accent with under dot', google translation) # FI: translation unclear + - "": [T: "palkkiaksentti ja kaksinkertainen piste yläpuolella"] # 0xee1f (en: 'bar accent with double over dot', google translation) # FI: translation unclear + - "": [T: "palkkiaksentti ja kaksinkertainen piste alapuolella"] # 0xee20 (en: 'bar accent with double under dot', google translation) # FI: translation unclear + - "": [T: "palkkiaksentti sirkumfleksillä"] # 0xee21 (en: 'bar accent with caret', google translation) # FI: translation unclear + - "": [T: "paksu alapalkkiaksentti"] # 0xee22 (en: 'thick under bar accent', google translation) # FI: translation unclear + - "": [T: "palkkiaksentti suljetulla ympyrällä oikea"] # 0xee23 (en: 'bar accent with closed circle right', google translation) # FI: translation unclear + - "": [T: "suuri piste yläpuolella"] # 0xee24 (en: 'large dot above', google translation) # FI: translation unclear + - "": [T: "kohdistusmerkki"] # 0xef00 (en: 'alignment mark', google translation) # FI: translation unclear + - "": [T: ""] # 0xef01 + - "​": [T: ""] # 0x200b + - "": [T: ""] # 0xef02 + - " ": [T: ""] # 0x2009 + - "": [T: ""] # 0xef03 + - " ": [T: ""] # 0x205f + - "": [T: ""] # 0xef04 + - "": [T: ""] # 0xef05 + - " ": [T: ""] # 0x2003 + - "": [T: ""] # 0xef06 + - "": [T: ""] # 0xef07 + - "": [T: ""] # 0xef08 + - "": [T: ""] # 0xef09 + - "": [T: ""] # 0xef0a + - " ": [T: ""] # 0x200a + - "": [T: ""] # 0xef22 + - "": [T: ""] # 0xef23 + - "": [T: ""] # 0xef24 + - "": [T: ""] # 0xef29 + - "": [T: "puuttuva termi"] # 0xef41 (en: 'missing term', google translation) + - "": [T: "käyräintegraalinuoli myötäväivään vasemmalla"] # 0xef80 (en: 'clockwise contour integral arrow on left', google translation) + - "": [T: "integraali neliöllä"] # 0xef81 (en: 'integral with square', google translation) + - "": [T: "integraali vinoviivalla"] # 0xef82 (en: 'integral with slash', google translation) + - "": [T: "käännetty integraali"] # 0xef83 (en: 'reversed integral', google translation) + - "": [T: "kaksinkertainen nolla yli kaksinkertaisen nollan"] # 0xef90 (en: 'double zero over double zero', google translation) + - "": [T: "nolla vinoviivalla"] # 0xef91 (en: 'zero with slash', google translation) + + # fraktur chars in math alphabetic block and also MathType private use area + # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display + - "𝔄-𝔜": # 0x1d504 - 0x1d51d ('z' version is reserved) + - T: "fraktuura" # (google translation) + - SPELL: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" + + - "-": # 0xf000 - 0xf018 + - T: "fraktuura" # (google translation) + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" + + - "𝔞-𝔷": # 0x1d51e - 0x1d537 + - T: "fraktuura" # (google translation) + - SPELL: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf01a - 0xf033 + - T: "fraktuura" # (google translation) + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝕬-𝖅": # 0x1D56C - 0x1D585 + - T: "fraktuura lihavoitu" # (google translation) + - SPELL: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf040 - 0xf059 + - T: "fraktuura lihavoitu" # (google translation) + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝖆-𝖟": # 0x1d586 - 0x1d59f + - T: "fraktuura lihavoitu" # (google translation) + - SPELL: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf05a - 0xf073 + - T: "fraktuura lihavoitu" # (google translation) + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + # double struck (blackboard bold) chars in math alphabetic block and also MathType private use area + # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display + - "𝔸-𝕐": # 0x1d504 - 0x1d51d ('z' version is reserved) + - test: + if: "$Verbosity!='Terse'" + then: [T: "kaksoisviivainen"] # (en: 'double struck', google translation) + - SPELL: "translate('.', '𝔸𝔹𝔺𝔻𝔼𝔽𝔾𝔿𝕀𝕁𝕂𝕃𝕄𝕅𝕆𝕇𝕈𝕉𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf080 - 0xf098 + - test: + if: "$Verbosity!='Terse'" + then: [T: "kaksoisviivainen"] # (en: 'double struck', google translation) + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝕒-𝕫": # 0x1d552 - 0x1d56b + - test: + if: "$Verbosity!='Terse'" + then: [T: "kaksoisviivainen"] # (en: 'double struck', google translation) + - SPELL: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf09a - 0xf0b3 + - test: + if: "$Verbosity!='Terse'" + then: [T: "kaksoisviivainen"] # (en: 'double struck', google translation) + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 + - test: + if: "$Verbosity!='Terse'" + then: [T: "kaksoisviivainen"] # (en: 'double struck', google translation) + - SPELL: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" + - "-": # 0xf0c0 - 0xf0c9 + - test: + if: "$Verbosity!='Terse'" + then: [T: "kaksoisviivainen"] # (en: 'double struck', google translation) + - SPELL: "translate('.', '', '0123456789')" + + - "": [T: "kaksoisviivainen nabla"] # 0xf0ca (en: 'double struck nabla', google translation) + - "": [T: "kaksoisviivainen eulerin vakio"] # 0xf0cb (en: 'double struck euler constant', google translation) + + # script chars in math alphabetic block and also MathType private use area + - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 + - T: "kauno" # (en: 'script', google translation) + - SPELL: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf100 - 0xf119 + - T: "kauno" # (en: 'script', google translation) + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf + - T: "kauno" # (en: 'script', google translation) + - SPELL: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf11a - 0xf133 + - T: "kauno" # (en: 'script', google translation) + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + # bold script chars in math alphabetic block and also MathType private use area + - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 + - T: "lihavoitu kauno" # (en: 'script bold', google translation) + - SPELL: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf140 - 0xf159 + - T: "lihavoitu kauno" # (en: 'script bold', google translation) + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝓪-𝔃": # 0x1d4ea - 0x1d503 + - T: "lihavoitu kauno" # (en: 'script bold', google translation) + - SPELL: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf15a - 0xf173 + - T: "lihavoitu kauno" # (en: 'script bold', google translation) + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf180 - 0xf199 + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "": # 0xf19a + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "iso"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "ligatuuri a e"] # (google translation) + - "": # 0xf19b + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "iso"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "terävä s"] # (en: 'sharp s', google translation) # FI: : translation unclear + - "": # 0xf19c + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "iso"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "o yliviivauksella"] # (en: 'o with stroke', google translation) + + # MathType only has a few of the cap Greek letters in PUA + - "": # 0xf201 - 0xf209 + - test: + if: "$Verbosity!='Terse'" + then: [T: "kaksoisviivainen"] # (en: 'double struck', google translation) + - SPELL: "translate('.', '', 'ΔΨΛΠΣΘΓΩΥ')" + + - "-": # 0xf220 - 0xf236 + - test: + if: "$Verbosity!='Terse'" + then: [T: "kaksoisviivainen"] # (en: 'double struck', google translation) + - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "": [T: "kaksoisviivainen viimeinen sigma"] # 0xf237 (en: 'double struck final sigma', google translation) + - "": [T: "kaksoisviivainen rho"] # 0xf250 (en: 'double struck rho', google translation) + - "": [T: "kaksoisviivainen fii"] # 0xf251 (google translation) + - "𝐀-𝐙": # 0x1d400 - 0x1d419 + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf260 - 0xf279 + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝐚-𝐳": # 0x1d41a - 0x1d433 + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf27a - 0xf293 + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝐴-𝑍": # 0x1d434 - 0x1d44d + - SPELL: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf294 - 0xf2ad + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝑎-𝑧": # 0x1d44e - 0x1d467 + - SPELL: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf2ae - 0xf2c7 + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝑨-𝒁": # 0x1d468 - 0x1d481 + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf2c8 - 0xf2e1 + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝒂-𝒛": # 0x1d482 - 0x1d49b + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf2e2 - 0xf2fb + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 + - SPELL: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf300 - 0xf319 + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 + - SPELL: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf31a - 0xf333 + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf334 - 0xf34d + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝗮-𝘇": # 0x1d5ee - 0x1d607 + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf34e - 0xf367 + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝘈-𝘡": # 0x1d608 - 0x1d621 + # - t: "italic" + - SPELL: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": # 0xf368 - 0xf381 + # - t: "italic" + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝘢-𝘻": # 0x1d622 - 0x1d63b + # - t: "italic" + - SPELL: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf382 - 0xf39b + # - t: "italic" + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝘼-𝙕": # 0x1d63c - 0x1d655 + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf39c - 0xf3b5 + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝙖-𝙯": # 0x1d656 - 0x1d66f + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf3b6 - 0xf3cf + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝙰-𝚉": # 0x1d670 - 0x1d689 + - SPELL: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf3d0 - 0xf3e9 + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 + - SPELL: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf3ea - 0xf403 + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "": [T: "pisteetön i"] # 0xf404 (google translation) + - "𝚤": [T: "pisteetön i"] # 0x1d6a4 (en: 'dotless i', google: 'dotless i') + - "𝚥": [T: "pisteetön j"] # 0x1d6a5 (en: 'dotless j', google: 'dotless j') + + - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 + - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') + - SPELL: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf408 - 0xf420 + - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') + - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da + - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') + - SPELL: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf422 - 0xf43a + - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') + - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "": [T: "lihavoitu nabla"] # 0xf421 (en: 'bold nabla', google translation) + - "𝛁": [T: "lihavoitu nabla"] # 0x1d6c1 (en: 'bold nabla') + + - "𝛛𝛜𝛝𝛞𝛟𝛠𝛡": # 0x1D6DB - 0x1D6E1 + - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') + - SPELL: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" + + - "": # 0xF43C - 0xF441 + - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') + - SPELL: "translate('.', '', '∂εθκφρπ')" + + - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa + # - t: "italic" + - SPELL: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf442 - 0xf45a + # - t: "italic" + - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝛼-𝜔": # 0x1d6fc - 0x1d714 + # - t: "italic" + - SPELL: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓𝜔', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf45c - 0xf474 + # - t: "italic" + - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "": [T: "kursivoitu nabla"] # 0xf45b (en: 'italic nabla', google translation) + - "𝛻": [T: "lihavoitu nabla"] # 0x1d6fb (en: 'italic nabla', google: 'kursivoitu nabla') + + - "𝜕𝜖𝜗𝜘𝜙𝜚𝜛": # 0x1d715 - 0x1d71b + # - t: "italic" + - SPELL: "translate('.', '𝜕𝜖𝜗𝜘𝜙𝜚𝜛', '∂εθκφρπ')" + + - "": # 0xf475 - 0xf47b + # - t: "italic" + - SPELL: "translate('.', '', '∂εθκφρπ')" + + - "𝜜-𝜴": # 0x1d71c - 0x1d734 + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') + - SPELL: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf47c - 0xf494 + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') + - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝜶-𝝎": # 0x1d736 - 0x1d74e + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') + - SPELL: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf496 - 0xf4ae + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') + - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": # 0x1d74f - 0x1d755 + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') + - SPELL: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εθκφρπ')" + + - "": # 0xf422 - 0xf43a + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') + - SPELL: "translate('.', '', '∂εθκφρπ')" + + - "𝜵": [T: "lihavoitu kursivoitu nabla"] # 0x1d735 (en: 'bold italic nabla', google: 'rohkea kursivoitu nabla') + - "": [T: "lihavoitu kursivoitu nabla"] # 0xf495 (en: 'bold italic nabla', google translation) + + - "𝝖-𝝮": # 0x1d756 - 0x1d76e + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "-": # 0xf4b6 - 0xf4ce + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝝰-𝞈": # 0x1d770 - 0x1d788 + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇𝞈', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf4d0 - 0xf4e8 + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝞉𝞊𝞋𝞌𝞍𝞎𝞏": # 0x1d789 - 0x1d78f + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '𝞉𝞊𝞋𝞌𝞍𝞎𝞏', '∂εθκφρπ')" + + - "": # 0xf4e9 - 0xf4ef + - T: "lihavoitu" # (en: 'bold', google translation) + - SPELL: "translate('.', '', '∂εθκφρπ')" + + - "": [T: "lihavoitu nabla"] # 0xf4cf (en: 'bold nabla', google translation) + - "𝝯": [T: "lihavoitu nabla"] # 0x1d76f (en: 'bold nabla') + + - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') + - SPELL: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf4f0 - 0xf508 + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') + - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝞪-𝟂": # 0x1d7aa - 0x1d7c2 + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') + - SPELL: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf50a - 0xf522 + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') + - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": # 0x1d7c3 - 0x1d7c9 + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') + - SPELL: "translate('.', '𝟃𝟄𝟅𝟆𝟇𝟈𝟉', '∂εθκφρπ')" + + - "": # 0xf523 - 0xf529 + # - t: "bold italic" + - T: "lihavoitu" # (en: 'bold', google: 'lihavoitu') + - SPELL: "translate('.', '', '∂εθκφρπ')" + + - "": [T: "lihavoitu nabla"] # 0xf509 (en: 'bold nabla', google translation) + - "𝞩": [T: "lihavoitu nabla"] # 0x1d7a9 (en: 'bold nabla') + + - "": [T: "lihavoitu nolla"] # 0xf52e (en: 'bold zero', google translation) + - "𝟎": [T: "lihavoitu nolla"] # 0x1d7ce (en: 'bold zero') + - "": [T: "lihavoitu yksi"] # 0xf52f (en: 'bold one', google translation) + - "𝟏": [T: "lihavoitu yksi"] # 0x1d7cf (en: 'bold one', google: 'lihavoitu') + - "": [T: "lihavoitu kaksi"] # 0xf530 (en: 'bold two', google translation) + - "𝟐": [T: "lihavoitu kaksi"] # 0x1d7d0 (en: 'bold two') + - "": [T: "lihavoitu kolme"] # 0xf531 (en: 'bold three', google translation) + - "𝟑": [T: "lihavoitu kolme"] # 0x1d7d1 (en: 'bold three') + - "": [T: "lihavoitu neljä"] # 0xf532 (en: 'bold four', google translation) + - "𝟒": [T: "lihavoitu neljä"] # 0x1d7d2 (en: 'bold four', google: 'bold neljä') + - "": [T: "lihavoitu viisi"] # 0xf533 (en: 'bold five', google translation) + - "𝟓": [T: "lihavoitu viisi"] # 0x1d7d3 (en: 'bold five') + - "": [T: "lihavoitu kuusi"] # 0xf534 (en: 'bold six', google translation) + - "𝟔": [T: "lihavoitu kuusi"] # 0x1d7d4 (en: 'bold six') + - "": [T: "lihavoitu seitsemän"] # 0xf535 (en: 'bold seven', google translation) + - "𝟕": [T: "lihavoitu seitsemän"] # 0x1d7d5 (en: 'bold seven', google: 'rohkea seitsemän') + - "": [T: "lihavoitu kahdeksan"] # 0xf536 (en: 'bold eight', google translation) + - "𝟖": [T: "lihavoitu kahdeksan"] # 0x1d7d6 (en: 'bold eight', google: 'lihavoitu') + - "": [T: "lihavoitu yhdeksän"] # 0xf537 (en: 'bold nine', google translation) + - "𝟗": [T: "lihavoitu yhdeksän"] # 0x1d7d7 (en: 'bold nine') + - "": [T: "nolla"] # 0xf542 (en: 'zero', google translation) + - "𝟢": [T: "nolla"] # 0x1d7e2 (en: 'zero') + - "": [T: "yksi"] # 0xf543 (en: 'one', google translation) + - "𝟣": [T: "yksi"] # 0x1d7e3 (en: 'one') + - "": [T: "kaksi"] # 0xf544 (en: 'two', google translation) + - "𝟤": [T: "kaksi"] # 0x1d7e4 (en: 'two') + - "": [T: "kolme"] # 0xf545 (en: 'three', google translation) + - "𝟥": [T: "kolme"] # 0x1d7e5 (en: 'three') + - "": [T: "neljä"] # 0xf546 (en: 'four', google translation) + - "𝟦": [T: "neljä"] # 0x1d7e6 (en: 'four') + - "": [T: "viisi"] # 0xf547 (en: 'five', google translation) + - "𝟧": [T: "viisi"] # 0x1d7e7 (en: 'five') + - "": [T: "kuusi"] # 0xf548 (en: 'six', google translation) + - "𝟨": [T: "kuusi"] # 0x1d7e8 (en: 'six') + - "": [T: "seitsemän"] # 0xf549 (en: 'seven', google translation) + - "𝟩": [T: "seitsemän"] # 0x1d7e9 (en: 'seven') + - "": [T: "kahdeksan"] # 0xf54a (en: 'eight', google translation) + - "𝟪": [T: "kahdeksan"] # 0x1d7ea (en: 'eight', google: 'at') + - "": [T: "yhdeksän"] # 0xf54b (en: 'nine', google translation) + - "𝟫": [T: "yhdeksän"] # 0x1d7eb (en: 'nine') + - "": [T: "lihavoitu nolla"] # 0xf54c (en: 'bold zero', google translation) + - "𝟬": [T: "lihavoitu nolla"] # 0x1d7ec (en: 'bold zero') + - "": [T: "lihavoitu yksi"] # 0xf54d (en: 'bold one', google translation) + - "𝟭": [T: "lihavoitu yksi"] # 0x1d7ed (en: 'bold one', google: 'lihavoitu') + - "": [T: "lihavoitu kaksi"] # 0xf54e (en: 'bold two', google translation) + - "𝟮": [T: "lihavoitu kaksi"] # 0x1d7ee (en: 'bold two') + - "": [T: "lihavoitu kolme"] # 0xf54f (en: 'bold three', google translation) + - "𝟯": [T: "lihavoitu kolme"] # 0x1d7ef (en: 'bold three') + - "": [T: "lihavoitu neljä"] # 0xf550 (en: 'bold four', google translation) + - "𝟰": [T: "lihavoitu neljä"] # 0x1d7f0 (en: 'bold four', google: 'bold neljä') + - "": [T: "lihavoitu viisi"] # 0xf551 (en: 'bold five', google translation) + - "𝟱": [T: "lihavoitu viisi"] # 0x1d7f1 (en: 'bold five') + - "": [T: "lihavoitu kuusi"] # 0xf552 (en: 'bold six', google translation) + - "𝟲": [T: "lihavoitu kuusi"] # 0x1d7f2 (en: 'bold six') + - "": [T: "lihavoitu seitsemän"] # 0xf553 (en: 'bold seven', google translation) + - "𝟳": [T: "lihavoitu seitsemän"] # 0x1d7f3 (en: 'bold seven', google: 'rohkea seitsemän') + - "": [T: "lihavoitu kahdeksan"] # 0xf554 (en: 'bold eight', google translation) + - "𝟴": [T: "lihavoitu kahdeksan"] # 0x1d7f4 (en: 'bold eight', google: 'lihavoitu') + - "": [T: "lihavoitu yhdeksän"] # 0xf555 (en: 'bold nine', google translation) + - "𝟵": [T: "lihavoitu yhdeksän"] # 0x1d7f5 (en: 'bold nine') + - "": [T: "nolla"] # 0xf556 (en: 'zero', google translation) + - "𝟶": [T: "nolla"] # 0x1d7f6 (en: 'zero') + - "": [T: "yksi"] # 0xf557 (en: 'one', google translation) + - "𝟷": [T: "yksi"] # 0x1d7f7 (en: 'one') + - "": [T: "kaksi"] # 0xf558 (en: 'two', google translation) + - "𝟸": [T: "kaksi"] # 0x1d7f8 (en: 'two') + - "": [T: "kolme"] # 0xf559 (en: 'three', google translation) + - "𝟹": [T: "kolme"] # 0x1d7f9 (en: 'three') + - "": [T: "neljä"] # 0xf55a (en: 'four', google translation) + - "𝟺": [T: "neljä"] # 0x1d7fa (en: 'four') + - "": [T: "viisi"] # 0xf55b (en: 'five', google translation) + - "𝟻": [T: "viisi"] # 0x1d7fb (en: 'five') + - "": [T: "kuusi"] # 0xf55c (en: 'six', google translation) + - "𝟼": [T: "kuusi"] # 0x1d7fc (en: 'six') + - "": [T: "seitsemän"] # 0xf55d (en: 'seven', google translation) + - "𝟽": [T: "seitsemän"] # 0x1d7fd (en: 'seven') + - "": [T: "kahdeksan"] # 0xf55e (en: 'eight', google translation) + - "𝟾": [T: "kahdeksan"] # 0x1d7fe (en: 'eight', google: 'at') + - "": [T: "yhdeksän"] # 0xf55f (en: 'nine', google translation) + - "𝟿": [T: "yhdeksän"] # 0x1d7ff (en: 'nine') + - "": [T: "tuntematon merkki"] # 0xf700 (en: 'unknown character', google translation) + - "": [T: "alaoikea ja alavasen kolmio"] # 0xf726 (en: 'lower right and lower left triangles', google translation) + - "": [T: "vaakasuora pistekolmikko pidennys"] # 0xf72d (en: 'horizontal ellipsis extender', google translation) + - "": [T: "keskiviivan vaakasuora pistekolmikko pidennys"] # 0xf72e (en: 'midline horizontal ellipsis extender', google translation) + - "": [T: "radikaali pidennys"] # 0xf8e5 (en: 'radical extender', google translation) # FI: unclear translation, root? + - "": [T: "pystysuora nuoli pidennys"] # 0xf8e6 (en: 'vertical arrow extender', google translation) + - "": [T: "vaakasuora nuoli pidennys"] # 0xf8e7 (en: 'horizontal arrow extender', google translation) + - "": [T: "rekisteröity merkki sans serif"] # 0xf8e8 (en: 'registered sign sans serif', google translation) + - "": [T: "tekijänoikeusmerkki sans serif"] # 0xf8e9 (en: 'copyright sign sans serif', google translation) + - "": [T: "trademark -merkki sans serif"] # 0xf8ea (en: 'trade mark sign sans serif', google translation) + - "": [T: "vasen kaarisulku ylä"] # 0xf8eb (en: 'left paren top', google translation) + - "": [T: "vasen kaarisulku pidennys"] # 0xf8ec (en: 'left paren extender', google translation) + - "": [T: "vasen kaarisulku ala"] # 0xf8ed (en: 'left paren bottom', google translation) + - "": [T: "vasen hakasulku ylä"] # 0xf8ee (en: 'left bracket top', google translation) + - "": [T: "vasen hakasulku pidennys"] # 0xf8ef (en: 'left bracket extender', google translation) + - "": [T: "vasen hakasulku ala"] # 0xf8f0 (en: 'left bracket bottom', google translation) + - "": [T: "vasen hakasulku ylä"] # 0xf8f1 (en: 'left brace top', google translation) + - "": [T: "vasen aaltosulku keski"] # 0xf8f2 (en: 'left brace mid', google translation) + - "": [T: "vasen aaltosulku ala"] # 0xf8f3 (en: 'left brace bottom', google translation) + - "": [T: "aaltosulku pidennys"] # 0xf8f4 (en: 'brace extender', google translation) + - "": [T: "integraali pidennys"] # 0xf8f5 (en: 'integral extender', google translation) + - "": [T: "oikea kaarisulku ylä"] # 0xf8f6 (en: 'right paren top', google translation) + - "": [T: "oikea kaarisulku pidennys"] # 0xf8f7 (en: 'right paren extender', google translation) + - "": [T: "oikea kaarisulku ala"] # 0xf8f8 (en: 'right paren bottom', google translation) + - "": [T: "oikea hakasulku ylä"] # 0xf8f9 (en: 'right bracket top', google translation) + - "": [T: "oikea hakasulku pidennys"] # 0xf8fa (en: 'right bracket extender', google translation) + - "": [T: "oikea hakasulku ala"] # 0xf8fb (en: 'right bracket bottom', google translation) + - "": [T: "oikea aaltosulku ylä"] # 0xf8fc (en: 'right brace top', google translation) + - "": [T: "oikea aaltosulku keski"] # 0xf8fd (en: 'right brace mid', google translation) + - "": [T: "oikea aaltosulku ala"] # 0xf8fe (en: 'right brace bottom', google translation) + - "": [T: "apple-logo"] # 0xf8ff (en: 'apple logo', google translation) + - "ff": [T: "f f"] # 0xfb00 (en: 'ff', google: 'ff') + - "fi": [T: "f i"] # 0xfb01 (en: 'fi', google: 'fi') + - "fl": [T: "f l"] # 0xfb02 (en: 'fl', google: 'fl') + - "ffi": [T: "f f i"] # 0xfb03 (en: 'ffi', google: 'ffi') + - "ffl": [T: "f f l"] # 0xfb04 (en: 'ffl', google: 'ffl') + - "ſt": [T: "f t"] # 0xfb05 (google translation) + - "st": [T: "s t"] # 0xfb06 (google translation) + - "︠": [T: "ligatuuri vasen puolikas koriste"] # 0xfe20 (en: 'ligature left half embellishment', google translation) # FI: : translation unclear + - "︡": [T: "ligatuuri oikea puolikas koriste"] # 0xfe21 (en: 'ligature right half embellishment', google translation) # FI: : translation unclear + - "︢": [T: "kaksoistilde vasen puolikas koriste"] # 0xfe22 (en: 'double tilde left half embellishment', google translation) # FI: : translation unclear + - "︣": [T: "kaksoistilde oikea puolikas koriste"] # 0xfe23 (en: 'double tilde right half embellishment', google translation) + - "︤": [T: "pituusmerkki vasen puolikas koriste"] # 0xfe24 (en: 'macron left half embellishment', google translation) + - "︥": [T: "pituusmerkki oikea puolikas koriste"] # 0xfe25 (en: 'macron right half embellishment', google translation) + - "︦": [T: "yhdistävä pituusmerkkikoriste"] # 0xfe26 (en: 'conjoining macron embellishment', google translation) + - "︵": [T: "yläsulku"] # 0xfe35 (google: 'yli sulku') + - "︶": [T: "alasulku"] # 0xfe36 (google: 'suluissa') + - "︷": [T: "yläaaltosulku"] # 0xfe37 (en: 'over brace', google: 'yli ahdin') + - "︸": [T: "ala-aaltosulku"] # 0xfe38 (en: 'under brace', google: 'ahdin alla') + - "︿": [T: "yläkulmasulku"] # 0xfe3f (google: 'yli kulmakiinnike') + - "﹀": [T: "alakulmasulku"] # 0xfe40 (google: 'kulmakiinnikkeessä') + - "﹨": [T: "kokonaislukujen jakomerkki"] # 0xfe68 (google: 'kokonaislukujako') + - "": [T: "tuntematon tai puuttuva objekti"] # 0xfffc (en: 'unknown or missing object', google translation) + - "�": [T: "tuntematon tai puuttuva merkki"] # 0xfffd (en: 'unknown or missing character') diff --git a/Rules/Languages/fi/unicode.yaml b/Rules/Languages/fi/unicode.yaml index f5bfc53c9..8e5d02aa4 100644 --- a/Rules/Languages/fi/unicode.yaml +++ b/Rules/Languages/fi/unicode.yaml @@ -1,482 +1,482 @@ ---- - - "a-z": - - test: - if: "$TTS='none'" - then: [T: "."] # (en: '.', google translation) - else: [SPELL: "'.'"] # Meaning? - - # Capital letters are a little tricky: users can pick their favorite word (something that was requested) and - # screen readers have options to use pitch changes or beeps instead of or in addition to say "cap" - # Also, if a user can see the screen, they probably don't need to hear "cap", but if they specified an override, they must want to hear the override. - - - "A-Z": - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "iso"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - # note: is there a need for Å/Ä/Ö here? - replace: [SPELL: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] - - - "0-9": [T: "."] # (en: '.', google: 'A') - - - "!": # 0x21 - - test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':structure:')]" - then_test: - if: "$Verbosity = 'Terse'" - then: [T: "huuto"] # 0x21 (en: 'bang', google translation) - else: [T: "huutomerkki"] # 0x21 (en: 'exclamation point', google: 'huutomerkki'); might be obsolete - else: [T: "kertoma"] # 0x21 (en: 'factorial', google: 'tekijä') - - - "\"": [T: "lainaus"] # 0x22 (en: 'quotation mark', google: 'lainausmerkki'); could also be "sitaatti" - - "#": [T: "numero"] # 0x23 (en: 'number', google: 'määrä'); could also be "ruutu" but "ristikkomerkki" is more clear - - "$": [T: "dollaria"] # 0x24 (en: 'dollars', google: 'dollarit') - - "%": [T: "prosenttia"] # 0x25 (en: 'percent') - - "&": [T: "et-merkki"] # 0x26 (en: 'ampersand', google: 'ampersand') - - "'": [T: "heittomerkki"] # 0x27 (en: 'apostrophe') - - "(": # 0x28 - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then_test: - if: "$Verbosity='Terse'" - then: [T: "auki"] # 0x28 (en: 'open', google translation) - else: [T: "auki sulku"] # 0x28 (en: 'open paren', google: 'avoin sulku') - else: [T: "vasen sulku"] # 0x28 (en: 'left paren', google: 'vasen sulku') - - ")": # 0x29 - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then_test: - if: "$Verbosity='Terse'" - then: [T: "kiinni"] # 0x29 (en: 'close', google translation) - else: [T: "kiinni sulku"] # 0x29 (en: 'close paren', google: 'sulje sulku') - else: [T: "oikea sulku"] # 0x29 (en: 'right paren', google: 'oikea sulku') - - - "*": # 0x2a - test: - if: "parent::*[name(.)='msup' or name(.)='msubsup' or name(.)='skip-super']" - then: [T: "tähti"] # 0x2a (en: 'star', google translation) - else: [T: "kertaa"] # 0x2a (en: 'times', google: 'ajat') - - "+": [T: "plus"] # 0x2b - - ",": # 0x2c - # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent - # that this test is here and not with "…" is not ideal, but seems simplest - test: - if: - - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " - # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' - # speak "comma" when not adjacent to '…' - - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " - # except if expression starts with '…' - - "../*[1][.='…'] " - then: - - T: "pilkku" # (en: 'comma', google translation) - - test: - if: "$Verbosity != Terse" - then: [pause: short] - # else silent - - - "-": [T: "miinus"] # 0x2d (en: 'minus') - - ".": # 0x2e - - test: - if: "parent::*[1][self::m:mn]" - then: [T: "piste"] # (en: 'point', google translation) - else: [T: "piste"] # (en: 'dot'); possibly obsolete if-else - - "/": [T: "jaettuna"] # 0x2f (en: 'divided by', google: 'jaettuna') - - ":": [T: "kaksoispiste"] # 0x3a (en: 'colon') - - ";": [T: "puolipiste"] # 0x3b (en: 'semicolon') - - "<": # 0x3c - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "pienempi kuin" # (en: 'less than', google: 'vähemmän kuin') - - "=": # 0x3d - - test: - if: "$Verbosity!='Terse'" - then: [T: "on yhtä suuri kuin"] # (en: 'is equal to', google translation) - else: [T: "on"] # (en: 'equals', google: 'yhtä suuri') - - - ">": # 0x3e - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "suurempi kuin" # (en: 'greater than', google: 'suurempi kuin') - - "?": [T: "kysymysmerkki"] # 0x3f (en: 'question mark') - - "@": [T: "ät-merkki"] # 0x40 (en: 'at sign', google: 'kylttiä') - - "[": # 0x5b - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "auki hakasulku"] # (en: 'open bracket', google translation) - else: [T: "vasen hakasulku"] # (en: 'left bracket', google: 'vasen kiinnike') - - "\\": [T: "kenoviiva"] # 0x5c (en: 'back slash', google: 'takaviiva') - - "]": # 0x5d - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "kiinni hakasulku"] # (en: 'close bracket', google translation) - else: [T: "oikea hakasulku"] # (en: 'right bracket', google: 'oikea kiinnike') - - "^": [T: "hattu"] # 0x5e (en: 'hat', google: 'hattu') - - "_": [T: "alaviiva"] # 0x5f (en: 'under bar', google: 'baarin alla') - - "`": [T: "gravis"] # 0x60 (en: 'grave', google: 'hauta') # FI: not sure - - "{": # 0x7b - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "auki aaltosulku"] # (en: 'open brace', google translation) - else: [T: "vasen aaltosulku"] # (en: 'left brace', google: 'vasen ahdin') - - "|": # 0x7c - # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' - - with: - variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) - replace: - - test: - - if: "$SpeechStyle != 'ClearSpeak'" - then_test: - - if: "$DefaultToGiven" - then: [T: "ehdolla"] - - else_if: "preceding-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))] and - following-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))]" - then: [T: "jakaa"] - else: [T: "pystysuora viiva"] - - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" - then: [T: "pystysuora viiva"] - - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" - then: [T: "siten että"] - - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" - then: [T: "ehdolla"] - - else: [T: "jakaa"] - - - "}": # 0x7d - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "kiinni aaltosulku"] # (en: 'close brace', google translation) - else: [T: "oikea aaltosulku"] # (en: 'right brace', google: 'oikea ahdin') - - - "~": [T: "tilde"] # 0x7e - - " ": # 0xa0 - - test: - if: "@data-empty-in-2D and ../../../../*[name(.)!='system-of-equations']" - then: [T: "tyhjä"] # want to say something for fraction (etc) with empty child (en: 'empty', google translation) - else: [T: ""] - - - "¬": [T: "ei"] # 0xac (en: 'not', google: 'ei') # Terse logic? - - "°": [T: "astetta"] # 0xb0 (en: 'degrees', google: 'asteet') - - "±": [T: "plus-miinus"] # 0xb1 (en: 'plus or minus', google: 'plus tai miinus') - - "´": [T: "akuutti"] # 0xb4 (en: 'acute') - - "·": # 0xB7 - - test: - if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolDot = 'Auto'" - then: [T: "kertaa"] # (en: 'times', google translation) - else: [T: "piste"] # (en: 'dot', google: 'piste') - - "×": # 0xd7 - - test: - if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolX = 'Auto'" - then: [T: "kertaa"] # (en: 'times', google translation) - else_test: - if: $ClearSpeak_MultSymbolX = 'By' - then: [T: "kertaa"] # (en: 2 'by' 2 matrice) fi: (2 kertaa 2 matriisi) translator's note - else: [T: "risti"] # (en: 'cross', google: 'ylittää') - - "÷": [T: "jaettuna"] # 0xf7 (en: 'divided by') - - "̀": [T: "gravis korostus"] # 0x300 (en: 'grave accent embellishment', google: 'vakava korostuskoriste') - - "́": [T: "akuutti korostus"] # 0x301 (en: 'acute accent embellishment', google: 'akuutti korostuskoriste') - - "̂": [T: "sirkumfleksi korostus"] # 0x302 (en: 'circumflex accent embellishment', google: 'ympyräkorotuskoriste') - - "̃": [T: "tilde"] # 0x303 (en: 'tilde embellishment', google: 'tilde -koriste') - - "̄": [T: "pituusmerkki"] # 0x304 (en: 'macron embellishment', google: 'macronin koriste') - - "̅": [T: "yläviiva"] # 0x305 (en: 'overbar embellishment', google: 'ylipalkin koriste') - - "̆": [T: "lyhyysmerkki"] # 0x306 (en: 'breve', google: 'breve') - - "̇": [T: "piste"] # 0x307 (en: 'dot above embellishment', google: 'piste koristelun yläpuolella') - - # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong - - "Α-Ω": - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "iso"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [SPELL: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] - - - "α": [T: "alfa"] # 0x3b1 (en: 'alpha') - - "β": [T: "beeta"] # 0x3b2 (en: 'beta') - - "γ": [T: "gamma"] # 0x3b3 - - "δ": [T: "delta"] # 0x3b4 - - "ε": [T: "epsilon"] # 0x3b5 - - "ζ": [T: "zeeta"] # 0x3b6 (en: 'zeta', google: 'zeta') - - "η": [T: "eeta"] # 0x3b7 (en: 'eta', google: 'eta') - - "θ": [T: "theeta"] # 0x3b8 (en: 'theta', google: 'theta') - - "ι": [T: "ioota"] # 0x3b9 (en: 'iota', google: 'iota') - - "κ": [T: "kappa"] # 0x3ba - - "λ": [T: "lambda"] # 0x3bb - - "μ": [T: "myy"] # 0x3bc (en: 'mu', google: 'mu') - - "ν": [T: "nyy"] # 0x3bd (en: 'nu', google: 'nu') - - "ξ": [T: "ksii"] # 0x3be (en: 'zai', google: 'zai') - - "ο": [T: "omikron"] # 0x3bf (en: 'omicron', google: 'omicron') - - "π": [T: "pii"] # 0x3c0 (en: 'pi', google: 'pi') - - "ρ": [T: "rhoo"] # 0x3c1 (en: 'rho', google: 'rho') - - "ς": [T: "loppu-sigma"] # 0x3c2 (en: 'final sigma', google: 'viimeinen sigma') - - "σ": [T: "sigma"] # 0x3c3 - - "τ": [T: "tau"] # 0x3c4 - - "υ": [T: "ypsilon"] # 0x3c5 (en: 'upsilon', google: 'upsilon') - - "φ": [T: "fii"] # 0x3c6 (en: 'phi', google: 'phi') - - "χ": [T: "khii"] # 0x3c7 (en: 'chi', google: 'chi') - - "ψ": [T: "psii"] # 0x3c8 (en: 'psi', google: 'psi') - - "ω": [T: "oomega"] # 0x3c9 (en: 'omega', google: 'omega') - - "ϕ": [T: "suora fii"] # 0x3d5 (en: 'phi', google: 'phi') - - "ϖ": [T: "kreikkalainen pii"] # 0x3d6 (en: 'pi', google: 'pi') - - "ϵ": [T: "epsilon"] # 0x3f5 - - "϶": [T: "käännetty epsilon"] # 0x3f6 (en: 'reversed epsilon', google: 'kääntynyt epsilon') - - - "⁡": # 0x2061 - - test: - # skip saying "of" when Terse and a trig function, when it is a shape (does this happen?), or we are in :literal mode - # log is treated differently than trig functions - # Note: this differs from 'en' because the ClearSpeak and default rules are different from 'en' - if: "not( - ( $Verbosity='Terse' or ($SpeechStyle = 'ClearSpeak' and IsNode(following-sibling::*[1],'simple')) and - preceding-sibling::*[1][IfThenElse($SpeechStyle='ClearSpeak', - IsInDefinition(., 'ClearSpeakTrigFunctionNames'), - IsInDefinition(., 'TrigFunctionNames') )] - ) or - preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')] or - (@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) - )" - then: [T: "arvolla"] - - "⁢": [T: ""] # 0x2062 # invisible 'times', fi: should this have a value? - - "⁣": [T: ""] # 0x2063 # invisible 'separator', fi: should this have a value? - - "⁤": [T: "ja"] # 0x2064 (en: 'and', google translation) - - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" - - T: "kaksoisviivainen" # (en: 'double-struck', google: 'kaksinkertainen') # not satisfied - - SPELL: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" - - - "℃": [T: "astetta celsiusta"] # 0x2103 (en: 'degrees celsius', google: 'celsius astetta') - - "ℋℛℓ": # 0x210b - - T: "skripti" # (en: 'script', google: 'käsikirjoitus') # not satisfied - - SPELL: "translate('.', 'ℋℛℓ', 'HRl')" - - "ℜ": # 0x211c - - T: "fraktuura iso r" # (en: 'fraktur', google: 'fraktur') - - SPELL: "'R'" - - - "ⅆⅇⅈⅉ": # 0x2146-9 - - T: "kaksoisviivainen kursiivi" # (en: 'double-struck italic', google: 'kaksinkertainen kursivoitu') - - SPELL: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" - - - "∥": # 0x2225 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "yhdensuuntainen" # (en: 'parallel to', google: 'samansuuntainen') - - "∦": # 0x2226 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei ole yhdensuuntainen" # (en: 'not parallel to', google: 'ei rinnakkain') - - "≤": # 0x2264 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "pienempi tai yhtä suuri kuin" - - "≥": # 0x2265 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "suurempi tai yhtä suuri kuin" # (en: 'greater than or equal to', google: 'suurempi tai yhtä suuri kuin') - - # --- restored complex short definitions (prefer over unicode-full) --- - - "…": # 0x2026 - test: - if: - - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" - # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' - # speak '…' as 'and so on...' unless expr starts with '…' - - "../*[1][.='…']" - then: [T: "piste piste piste"] # (google translation) - else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' - if: "count(following-sibling::*) = 0" - then: [T: "ja niin edelleen"] # (en: 'and so on', google translation) - else: [T: "ja niin edelleen kunnes"] # (en: 'and so on up to', google: 'ja niin edelleen'); possibly obsolete if-else - - "→": # 0x2192 - - test: - if: "ancestor::*[2][self::m:limit]" - then: [T: "lähestyy"] # (en: 'approaches', google translation) - else: [T: "nuoli oikealle"] # (en: 'right arrow', google: 'oikea nuoli') - - "∂": # 0x2202 - - test: - if: "$Verbosity='Terse'" - then: [T: "osittaisderivaatta"] # (en: 'partial', google translation) # might be other possibilities - else: [T: "osittaisderivaatta"] # (en: 'partial derivative', google: 'osittainen johdannainen') - - "∆": # 0x2206 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (google translation) - - T: "Laplacen operaattori" # (en: 'laplacian of', google: 'laplacian of') - - "∈": # 0x2208 # fi: some elements (pun) of this translation has to be tested - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: [T: "kuuluu"] # (en: 'an element of', google translation) - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "kuuluu"] # (en: 'in', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "kuuluu"] # (en: 'member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "kuuluu"] # (en: 'element of', google translation) - - else: [T: "kuuluu joukkoon"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to', google: 'kuulua') - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "kuuluu"] # (en: 'is a member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "kuuluu"] # (en: 'is an element of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "kuuluu"] # (en: 'is in', google translation) - - else: [T: "kuuluu joukkoon"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to', google: 'kuuluu') - - "∉": # 0x2209 # fi: some elements (pun) of this translation has to be tested - # rule is identical to 0x2208 - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: [T: "ei kuulu"] # (en: 'is not an element of', google translation) - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "ei kuulu"] # (en: 'not in', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "ei kuulu"] # (en: 'not member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "ei kuulu"] # (en: 'not element of', google translation) - - else: [T: "ei kuulu joukkoon"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to', google: 'ei kuulu') - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "ei kuulu"] # (en: 'is not a member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "ei kuulu"] # (en: 'is not an element of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "ei ole joukossa"] # (en: 'is not in', google translation) - - else: [T: "ei kuulu joukkoon"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to', google: 'ei kuulu') - - "∊": # 0x220a # fi: some elements (pun) of this translation has to be tested - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: [T: "kuuluu"] # (en: 'is an element of', google translation) - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "kuuluu"] # (en: 'in', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "kuuluu"] # (en: 'member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "kuuluu"] # (en: 'element of', google translation) - - else: [T: "kuuluu joukkoon"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to', google: 'kuulua') - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "kuuluu"] # (en: 'is a member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "kuuluu"] # (en: 'is an element of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "kuuluu"] # (en: 'is in', google translation) - - else: [T: "kuuluu joukkoon"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to', google: 'kuuluu') - - "√": # 0x221a - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (google translation) - - T: "neliöjuuri" # (en: 'square root of') - - "∝": # 0x221d - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "verrannollinen" # (en: 'proportional to', google: 'suhteessa') - - "∶": # 0x2236 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "suhde" # (en: 'to', google: 'to') - - "∾": # 0x223e - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "käännetty kaatunut S-kirjain" # (en: 'most positive', google: 'positiivisin') # fi: no good translation - - "≠": # 0x2260 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei ole yhtä suuri kuin" # (en: 'not equal to', google: 'ei yhtä suuri kuin') - - "≡": # 0x2261 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is', google translation) - - T: "identtinen" # (en: 'identical to', google: 'yhtäläinen') - - "⊂": # 0x2282 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is a', google translation) - - T: "osajoukko" # (en: 'subset of', google: 'alajoukko') - - "⊃": # 0x2283 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is a', google translation) - - T: "ylijoukko" # (en: 'superset of', google: 'superset of') # fi: not common, source for Finnish: https://fi.wikibooks.org/wiki/Diskreetti_matematiikka/Joukko-oppi - - "⊄": # 0x2284 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei ole osajoukko" # (en: 'not a subset of', google: 'ei osa') - - "⊅": # 0x2285 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', google translation) - - T: "ei ole ylijoukko" # (en: 'not a superset of', google: 'ei ylimääräistä') # fi: not common, source for Finnish: https://fi.wikibooks.org/wiki/Diskreetti_matematiikka/Joukko-oppi - - "⊆": # 0x2286 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is a', google translation) - - T: "osajoukko tai yhtä kuin" # (en: 'subset of or equal to', google: 'alajoukko tai yhtä suuri kuin') - - "⊇": # 0x2287 - - test: - if: "$Verbosity!='Terse'" - then: [T: "on"] # (en: 'is a', google translation) - - T: "ylijoukko tai yhtä kuin" # (en: 'superset of or equal to', google: 'superset tai yhtä suuri kuin') - - # --- restored short definitions that differ from unicode-full --- - - "―": [T: "vaakaviiva"] # 0x2015 (en: 'horizontal bar', google: 'vaakasuora viiva') - - "′": [T: "pilkku"] # 0x2032 (en: 'prime', google: 'ensisijainen') - - "″": [T: "pilkku pilkku"] # 0x2033 (en: 'double prime', google: 'kaksinkertainen prime') - - "‴": [T: "pilkku pilkku pilkku"] # 0x2034 (en: 'triple prime', google: 'kolminkertainen') - - "K": [T: "astetta kelviniä"] # 0x212a (en: 'kelvin', google: 'kelvin') - - "⇒": [T: "kaksiviivainen nuoli oikealle"] # 0x21d2 (en: 'rightwards double arrow', google: 'oikealla kaksinkertaisella nuolella') - - "∀": [T: "kaikille"] # 0x2200 (en: 'for all') - - "∘": [T: "yhdistetty"] # 0x2218 (en: 'composed with', google: 'koostuu') #fi: is this composite function? - - "∧": [T: "looginen ja"] # 0x2227 (en: 'and', google: 'ja') # should there be logic for "logical and" and "logical or"? - - "∨": [T: "looginen tai"] # 0x2228 (en: 'or', google: 'tai') - - "∪": [T: "yhdiste"] # 0x222a (en: 'union', google: 'liitto') - - "∮": [T: "suljettu polkuintegraali"] # 0x222e (en: 'contour integral', google: 'muoto -integraali') - - "∷": [T: "kuten"] # 0x2237 (en: 'as', google: 'kuten') - - "∼": [T: "jakautunut"] # 0x223c (en: 'varies with', google: 'vaihtelee') - - "∽": [T: "käännetty tilde"] # 0x223d (en: 'reversed tilde', google: 'kääntynyt tilde') - - "∿": [T: "sinikäyrä"] # 0x223f (en: 'sine wave', google: 'siniaalto') - - "≦": [T: "pienempi tai yhtä suuri kuin"] # 0x2266 (en: 'less than over equal to', google: 'vähemmän kuin yli yhtä suuri kuin') # based on https://jkorpela.fi/merkkien-nimet.html#, the meaning is the same as with =< - - "≧": [T: "suurempi tai yhtä suuri kuin"] # 0x2267 (en: 'greater than over equal to', google: 'suurempi kuin yli yhtä suuri kuin') +--- + - "a-z": + - test: + if: "$TTS='none'" + then: [T: "."] # (en: '.', google translation) + else: [SPELL: "'.'"] # Meaning? + + # Capital letters are a little tricky: users can pick their favorite word (something that was requested) and + # screen readers have options to use pitch changes or beeps instead of or in addition to say "cap" + # Also, if a user can see the screen, they probably don't need to hear "cap", but if they specified an override, they must want to hear the override. + + - "A-Z": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "iso"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + # note: is there a need for Å/Ä/Ö here? + replace: [SPELL: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] + + - "0-9": [T: "."] # (en: '.', google: 'A') + + - "!": # 0x21 + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':structure:')]" + then_test: + if: "$Verbosity = 'Terse'" + then: [T: "huuto"] # 0x21 (en: 'bang', google translation) + else: [T: "huutomerkki"] # 0x21 (en: 'exclamation point', google: 'huutomerkki'); might be obsolete + else: [T: "kertoma"] # 0x21 (en: 'factorial', google: 'tekijä') + + - "\"": [T: "lainaus"] # 0x22 (en: 'quotation mark', google: 'lainausmerkki'); could also be "sitaatti" + - "#": [T: "numero"] # 0x23 (en: 'number', google: 'määrä'); could also be "ruutu" but "ristikkomerkki" is more clear + - "$": [T: "dollaria"] # 0x24 (en: 'dollars', google: 'dollarit') + - "%": [T: "prosenttia"] # 0x25 (en: 'percent') + - "&": [T: "et-merkki"] # 0x26 (en: 'ampersand', google: 'ampersand') + - "'": [T: "heittomerkki"] # 0x27 (en: 'apostrophe') + - "(": # 0x28 + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [T: "auki"] # 0x28 (en: 'open', google translation) + else: [T: "auki sulku"] # 0x28 (en: 'open paren', google: 'avoin sulku') + else: [T: "vasen sulku"] # 0x28 (en: 'left paren', google: 'vasen sulku') + - ")": # 0x29 + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [T: "kiinni"] # 0x29 (en: 'close', google translation) + else: [T: "kiinni sulku"] # 0x29 (en: 'close paren', google: 'sulje sulku') + else: [T: "oikea sulku"] # 0x29 (en: 'right paren', google: 'oikea sulku') + + - "*": # 0x2a + test: + if: "parent::*[name(.)='msup' or name(.)='msubsup' or name(.)='skip-super']" + then: [T: "tähti"] # 0x2a (en: 'star', google translation) + else: [T: "kertaa"] # 0x2a (en: 'times', google: 'ajat') + - "+": [T: "plus"] # 0x2b + - ",": # 0x2c + # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent + # that this test is here and not with "…" is not ideal, but seems simplest + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak "comma" when not adjacent to '…' + - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " + # except if expression starts with '…' + - "../*[1][.='…'] " + then: + - T: "pilkku" # (en: 'comma', google translation) + - test: + if: "$Verbosity != Terse" + then: [pause: short] + # else silent + + - "-": [T: "miinus"] # 0x2d (en: 'minus') + - ".": # 0x2e + - test: + if: "parent::*[1][self::m:mn]" + then: [T: "piste"] # (en: 'point', google translation) + else: [T: "piste"] # (en: 'dot'); possibly obsolete if-else + - "/": [T: "jaettuna"] # 0x2f (en: 'divided by', google: 'jaettuna') + - ":": [T: "kaksoispiste"] # 0x3a (en: 'colon') + - ";": [T: "puolipiste"] # 0x3b (en: 'semicolon') + - "<": # 0x3c + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "pienempi kuin" # (en: 'less than', google: 'vähemmän kuin') + - "=": # 0x3d + - test: + if: "$Verbosity!='Terse'" + then: [T: "on yhtä suuri kuin"] # (en: 'is equal to', google translation) + else: [T: "on"] # (en: 'equals', google: 'yhtä suuri') + + - ">": # 0x3e + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "suurempi kuin" # (en: 'greater than', google: 'suurempi kuin') + - "?": [T: "kysymysmerkki"] # 0x3f (en: 'question mark') + - "@": [T: "ät-merkki"] # 0x40 (en: 'at sign', google: 'kylttiä') + - "[": # 0x5b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "auki hakasulku"] # (en: 'open bracket', google translation) + else: [T: "vasen hakasulku"] # (en: 'left bracket', google: 'vasen kiinnike') + - "\\": [T: "kenoviiva"] # 0x5c (en: 'back slash', google: 'takaviiva') + - "]": # 0x5d + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "kiinni hakasulku"] # (en: 'close bracket', google translation) + else: [T: "oikea hakasulku"] # (en: 'right bracket', google: 'oikea kiinnike') + - "^": [T: "hattu"] # 0x5e (en: 'hat', google: 'hattu') + - "_": [T: "alaviiva"] # 0x5f (en: 'under bar', google: 'baarin alla') + - "`": [T: "gravis"] # 0x60 (en: 'grave', google: 'hauta') # FI: not sure + - "{": # 0x7b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "auki aaltosulku"] # (en: 'open brace', google translation) + else: [T: "vasen aaltosulku"] # (en: 'left brace', google: 'vasen ahdin') + - "|": # 0x7c + # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' + - with: + variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) + replace: + - test: + - if: "$SpeechStyle != 'ClearSpeak'" + then_test: + - if: "$DefaultToGiven" + then: [T: "ehdolla"] + - else_if: "preceding-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))] and + following-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))]" + then: [T: "jakaa"] + else: [T: "pystysuora viiva"] + - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" + then: [T: "pystysuora viiva"] + - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" + then: [T: "siten että"] + - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" + then: [T: "ehdolla"] + - else: [T: "jakaa"] + + - "}": # 0x7d + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "kiinni aaltosulku"] # (en: 'close brace', google translation) + else: [T: "oikea aaltosulku"] # (en: 'right brace', google: 'oikea ahdin') + + - "~": [T: "tilde"] # 0x7e + - " ": # 0xa0 + - test: + if: "@data-empty-in-2D and ../../../../*[name(.)!='system-of-equations']" + then: [T: "tyhjä"] # want to say something for fraction (etc) with empty child (en: 'empty', google translation) + else: [T: ""] + + - "¬": [T: "ei"] # 0xac (en: 'not', google: 'ei') # Terse logic? + - "°": [T: "astetta"] # 0xb0 (en: 'degrees', google: 'asteet') + - "±": [T: "plus-miinus"] # 0xb1 (en: 'plus or minus', google: 'plus tai miinus') + - "´": [T: "akuutti"] # 0xb4 (en: 'acute') + - "·": # 0xB7 + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolDot = 'Auto'" + then: [T: "kertaa"] # (en: 'times', google translation) + else: [T: "piste"] # (en: 'dot', google: 'piste') + - "×": # 0xd7 + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolX = 'Auto'" + then: [T: "kertaa"] # (en: 'times', google translation) + else_test: + if: $ClearSpeak_MultSymbolX = 'By' + then: [T: "kertaa"] # (en: 2 'by' 2 matrice) fi: (2 kertaa 2 matriisi) translator's note + else: [T: "risti"] # (en: 'cross', google: 'ylittää') + - "÷": [T: "jaettuna"] # 0xf7 (en: 'divided by') + - "̀": [T: "gravis korostus"] # 0x300 (en: 'grave accent embellishment', google: 'vakava korostuskoriste') + - "́": [T: "akuutti korostus"] # 0x301 (en: 'acute accent embellishment', google: 'akuutti korostuskoriste') + - "̂": [T: "sirkumfleksi korostus"] # 0x302 (en: 'circumflex accent embellishment', google: 'ympyräkorotuskoriste') + - "̃": [T: "tilde"] # 0x303 (en: 'tilde embellishment', google: 'tilde -koriste') + - "̄": [T: "pituusmerkki"] # 0x304 (en: 'macron embellishment', google: 'macronin koriste') + - "̅": [T: "yläviiva"] # 0x305 (en: 'overbar embellishment', google: 'ylipalkin koriste') + - "̆": [T: "lyhyysmerkki"] # 0x306 (en: 'breve', google: 'breve') + - "̇": [T: "piste"] # 0x307 (en: 'dot above embellishment', google: 'piste koristelun yläpuolella') + + # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong + - "Α-Ω": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "iso"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [SPELL: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] + + - "α": [T: "alfa"] # 0x3b1 (en: 'alpha') + - "β": [T: "beeta"] # 0x3b2 (en: 'beta') + - "γ": [T: "gamma"] # 0x3b3 + - "δ": [T: "delta"] # 0x3b4 + - "ε": [T: "epsilon"] # 0x3b5 + - "ζ": [T: "zeeta"] # 0x3b6 (en: 'zeta', google: 'zeta') + - "η": [T: "eeta"] # 0x3b7 (en: 'eta', google: 'eta') + - "θ": [T: "theeta"] # 0x3b8 (en: 'theta', google: 'theta') + - "ι": [T: "ioota"] # 0x3b9 (en: 'iota', google: 'iota') + - "κ": [T: "kappa"] # 0x3ba + - "λ": [T: "lambda"] # 0x3bb + - "μ": [T: "myy"] # 0x3bc (en: 'mu', google: 'mu') + - "ν": [T: "nyy"] # 0x3bd (en: 'nu', google: 'nu') + - "ξ": [T: "ksii"] # 0x3be (en: 'zai', google: 'zai') + - "ο": [T: "omikron"] # 0x3bf (en: 'omicron', google: 'omicron') + - "π": [T: "pii"] # 0x3c0 (en: 'pi', google: 'pi') + - "ρ": [T: "rhoo"] # 0x3c1 (en: 'rho', google: 'rho') + - "ς": [T: "loppu-sigma"] # 0x3c2 (en: 'final sigma', google: 'viimeinen sigma') + - "σ": [T: "sigma"] # 0x3c3 + - "τ": [T: "tau"] # 0x3c4 + - "υ": [T: "ypsilon"] # 0x3c5 (en: 'upsilon', google: 'upsilon') + - "φ": [T: "fii"] # 0x3c6 (en: 'phi', google: 'phi') + - "χ": [T: "khii"] # 0x3c7 (en: 'chi', google: 'chi') + - "ψ": [T: "psii"] # 0x3c8 (en: 'psi', google: 'psi') + - "ω": [T: "oomega"] # 0x3c9 (en: 'omega', google: 'omega') + - "ϕ": [T: "suora fii"] # 0x3d5 (en: 'phi', google: 'phi') + - "ϖ": [T: "kreikkalainen pii"] # 0x3d6 (en: 'pi', google: 'pi') + - "ϵ": [T: "epsilon"] # 0x3f5 + - "϶": [T: "käännetty epsilon"] # 0x3f6 (en: 'reversed epsilon', google: 'kääntynyt epsilon') + + - "⁡": # 0x2061 + - test: + # skip saying "of" when Terse and a trig function, when it is a shape (does this happen?), or we are in :literal mode + # log is treated differently than trig functions + # Note: this differs from 'en' because the ClearSpeak and default rules are different from 'en' + if: "not( + ( $Verbosity='Terse' or ($SpeechStyle = 'ClearSpeak' and IsNode(following-sibling::*[1],'simple')) and + preceding-sibling::*[1][IfThenElse($SpeechStyle='ClearSpeak', + IsInDefinition(., 'ClearSpeakTrigFunctionNames'), + IsInDefinition(., 'TrigFunctionNames') )] + ) or + preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')] or + (@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) + )" + then: [T: "arvolla"] + - "⁢": [T: ""] # 0x2062 # invisible 'times', fi: should this have a value? + - "⁣": [T: ""] # 0x2063 # invisible 'separator', fi: should this have a value? + - "⁤": [T: "ja"] # 0x2064 (en: 'and', google translation) + - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" + - T: "kaksoisviivainen" # (en: 'double-struck', google: 'kaksinkertainen') # not satisfied + - SPELL: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" + + - "℃": [T: "astetta celsiusta"] # 0x2103 (en: 'degrees celsius', google: 'celsius astetta') + - "ℋℛℓ": # 0x210b + - T: "skripti" # (en: 'script', google: 'käsikirjoitus') # not satisfied + - SPELL: "translate('.', 'ℋℛℓ', 'HRl')" + - "ℜ": # 0x211c + - T: "fraktuura iso r" # (en: 'fraktur', google: 'fraktur') + - SPELL: "'R'" + + - "ⅆⅇⅈⅉ": # 0x2146-9 + - T: "kaksoisviivainen kursiivi" # (en: 'double-struck italic', google: 'kaksinkertainen kursivoitu') + - SPELL: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" + + - "∥": # 0x2225 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "yhdensuuntainen" # (en: 'parallel to', google: 'samansuuntainen') + - "∦": # 0x2226 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei ole yhdensuuntainen" # (en: 'not parallel to', google: 'ei rinnakkain') + - "≤": # 0x2264 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "pienempi tai yhtä suuri kuin" + - "≥": # 0x2265 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "suurempi tai yhtä suuri kuin" # (en: 'greater than or equal to', google: 'suurempi tai yhtä suuri kuin') + + # --- restored complex short definitions (prefer over unicode-full) --- + - "…": # 0x2026 + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak '…' as 'and so on...' unless expr starts with '…' + - "../*[1][.='…']" + then: [T: "piste piste piste"] # (google translation) + else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' + if: "count(following-sibling::*) = 0" + then: [T: "ja niin edelleen"] # (en: 'and so on', google translation) + else: [T: "ja niin edelleen kunnes"] # (en: 'and so on up to', google: 'ja niin edelleen'); possibly obsolete if-else + - "→": # 0x2192 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "lähestyy"] # (en: 'approaches', google translation) + else: [T: "nuoli oikealle"] # (en: 'right arrow', google: 'oikea nuoli') + - "∂": # 0x2202 + - test: + if: "$Verbosity='Terse'" + then: [T: "osittaisderivaatta"] # (en: 'partial', google translation) # might be other possibilities + else: [T: "osittaisderivaatta"] # (en: 'partial derivative', google: 'osittainen johdannainen') + - "∆": # 0x2206 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (google translation) + - T: "Laplacen operaattori" # (en: 'laplacian of', google: 'laplacian of') + - "∈": # 0x2208 # fi: some elements (pun) of this translation has to be tested + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: [T: "kuuluu"] # (en: 'an element of', google translation) + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "kuuluu"] # (en: 'in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "kuuluu"] # (en: 'member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "kuuluu"] # (en: 'element of', google translation) + - else: [T: "kuuluu joukkoon"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to', google: 'kuulua') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "kuuluu"] # (en: 'is a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "kuuluu"] # (en: 'is an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "kuuluu"] # (en: 'is in', google translation) + - else: [T: "kuuluu joukkoon"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to', google: 'kuuluu') + - "∉": # 0x2209 # fi: some elements (pun) of this translation has to be tested + # rule is identical to 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: [T: "ei kuulu"] # (en: 'is not an element of', google translation) + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "ei kuulu"] # (en: 'not in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "ei kuulu"] # (en: 'not member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "ei kuulu"] # (en: 'not element of', google translation) + - else: [T: "ei kuulu joukkoon"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to', google: 'ei kuulu') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "ei kuulu"] # (en: 'is not a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "ei kuulu"] # (en: 'is not an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "ei ole joukossa"] # (en: 'is not in', google translation) + - else: [T: "ei kuulu joukkoon"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to', google: 'ei kuulu') + - "∊": # 0x220a # fi: some elements (pun) of this translation has to be tested + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: [T: "kuuluu"] # (en: 'is an element of', google translation) + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "kuuluu"] # (en: 'in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "kuuluu"] # (en: 'member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "kuuluu"] # (en: 'element of', google translation) + - else: [T: "kuuluu joukkoon"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to', google: 'kuulua') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "kuuluu"] # (en: 'is a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "kuuluu"] # (en: 'is an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "kuuluu"] # (en: 'is in', google translation) + - else: [T: "kuuluu joukkoon"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to', google: 'kuuluu') + - "√": # 0x221a + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (google translation) + - T: "neliöjuuri" # (en: 'square root of') + - "∝": # 0x221d + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "verrannollinen" # (en: 'proportional to', google: 'suhteessa') + - "∶": # 0x2236 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "suhde" # (en: 'to', google: 'to') + - "∾": # 0x223e + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "käännetty kaatunut S-kirjain" # (en: 'most positive', google: 'positiivisin') # fi: no good translation + - "≠": # 0x2260 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei ole yhtä suuri kuin" # (en: 'not equal to', google: 'ei yhtä suuri kuin') + - "≡": # 0x2261 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is', google translation) + - T: "identtinen" # (en: 'identical to', google: 'yhtäläinen') + - "⊂": # 0x2282 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is a', google translation) + - T: "osajoukko" # (en: 'subset of', google: 'alajoukko') + - "⊃": # 0x2283 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is a', google translation) + - T: "ylijoukko" # (en: 'superset of', google: 'superset of') # fi: not common, source for Finnish: https://fi.wikibooks.org/wiki/Diskreetti_matematiikka/Joukko-oppi + - "⊄": # 0x2284 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei ole osajoukko" # (en: 'not a subset of', google: 'ei osa') + - "⊅": # 0x2285 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', google translation) + - T: "ei ole ylijoukko" # (en: 'not a superset of', google: 'ei ylimääräistä') # fi: not common, source for Finnish: https://fi.wikibooks.org/wiki/Diskreetti_matematiikka/Joukko-oppi + - "⊆": # 0x2286 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is a', google translation) + - T: "osajoukko tai yhtä kuin" # (en: 'subset of or equal to', google: 'alajoukko tai yhtä suuri kuin') + - "⊇": # 0x2287 + - test: + if: "$Verbosity!='Terse'" + then: [T: "on"] # (en: 'is a', google translation) + - T: "ylijoukko tai yhtä kuin" # (en: 'superset of or equal to', google: 'superset tai yhtä suuri kuin') + + # --- restored short definitions that differ from unicode-full --- + - "―": [T: "vaakaviiva"] # 0x2015 (en: 'horizontal bar', google: 'vaakasuora viiva') + - "′": [T: "pilkku"] # 0x2032 (en: 'prime', google: 'ensisijainen') + - "″": [T: "pilkku pilkku"] # 0x2033 (en: 'double prime', google: 'kaksinkertainen prime') + - "‴": [T: "pilkku pilkku pilkku"] # 0x2034 (en: 'triple prime', google: 'kolminkertainen') + - "K": [T: "astetta kelviniä"] # 0x212a (en: 'kelvin', google: 'kelvin') + - "⇒": [T: "kaksiviivainen nuoli oikealle"] # 0x21d2 (en: 'rightwards double arrow', google: 'oikealla kaksinkertaisella nuolella') + - "∀": [T: "kaikille"] # 0x2200 (en: 'for all') + - "∘": [T: "yhdistetty"] # 0x2218 (en: 'composed with', google: 'koostuu') #fi: is this composite function? + - "∧": [T: "looginen ja"] # 0x2227 (en: 'and', google: 'ja') # should there be logic for "logical and" and "logical or"? + - "∨": [T: "looginen tai"] # 0x2228 (en: 'or', google: 'tai') + - "∪": [T: "yhdiste"] # 0x222a (en: 'union', google: 'liitto') + - "∮": [T: "suljettu polkuintegraali"] # 0x222e (en: 'contour integral', google: 'muoto -integraali') + - "∷": [T: "kuten"] # 0x2237 (en: 'as', google: 'kuten') + - "∼": [T: "jakautunut"] # 0x223c (en: 'varies with', google: 'vaihtelee') + - "∽": [T: "käännetty tilde"] # 0x223d (en: 'reversed tilde', google: 'kääntynyt tilde') + - "∿": [T: "sinikäyrä"] # 0x223f (en: 'sine wave', google: 'siniaalto') + - "≦": [T: "pienempi tai yhtä suuri kuin"] # 0x2266 (en: 'less than over equal to', google: 'vähemmän kuin yli yhtä suuri kuin') # based on https://jkorpela.fi/merkkien-nimet.html#, the meaning is the same as with =< + - "≧": [T: "suurempi tai yhtä suuri kuin"] # 0x2267 (en: 'greater than over equal to', google: 'suurempi kuin yli yhtä suuri kuin') diff --git a/Rules/Languages/hu/ClearSpeak_Rules.yaml b/Rules/Languages/hu/ClearSpeak_Rules.yaml index 434034698..3e5df3c76 100644 --- a/Rules/Languages/hu/ClearSpeak_Rules.yaml +++ b/Rules/Languages/hu/ClearSpeak_Rules.yaml @@ -1,840 +1,840 @@ ---- -- name: pause - tag: "!*" - match: "not(self::m:math) and not($MatchingPause) and @data-intent-property[contains(., ':pause')]" - replace: - - with: - variables: [MatchingPause: "true()"] - replace: - - test: - - if: "contains(@data-intent-property, ':pause-long')" - then: [pause: long] - - else_if: "contains(@data-intent-property, ':pause-short')" - then: [pause: short] - else: [pause: medium] - - x: "." - -- name: intent-literal-silent - tag: [mi, mo, mn] - match: "contains(@data-intent-property, ':silent:')" - # say nothing - replace: [] - -# handling of negative numbers that come from 'intent' is hard -- we do something that is close to right here -- name: intent-literal-negative-number - tag: mn - match: "starts-with(text(), '-')" - replace: - - T: "mínusz" # phrase(10 'minus' 4 equals 6) - - x: "translate(text(), '-_', '')" - -- name: default - tag: square-root - match: "." - replace: - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # phrase('the' square root of 25) - - test: - if: "$ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" - then: - - bookmark: "*[1]/@id" - - test: - if: "parent::*[self::m:minus and count(*)=1]" - then: [T: "negatív"] # phrase(minus 4 is a 'negative' number) - else: [T: "pozitív"] # phrase(10 is a 'positive' number) - - T: "négyzetgyök" # phrase(8 is the 'square root' of 64) - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # phrase(the square root 'of' 5) - magyarban nem kell kötőszó - else: [pause: short] - - x: "*[1]" - - test: - - if: "$ClearSpeak_Roots = 'RootEnd' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" - then: - - pause: short - - T: "gyök vége" # phrase(the square root of x 'end root') - - pause: medium - - else_if: "IsNode(*[1], 'simple')" - then: [pause: short] - else: [pause: long] - -- name: default - tag: root - match: "." - replace: - - test: - if: "$Verbosity!='Terse'" - then: [T: "a"] # phrase(6 is 'the' square root of 36) - - test: - if: "$ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" - then: - - test: - if: "parent::*[(self::m:minus or self::m:plus) and count(*)=1]" - then: [bookmark: "parent/@id"] - - test: - if: "parent::m:minus" - then: [T: "negatív"] # phrase(minus 6 is a 'negative' number) - else: [T: "pozitív"] # phrase(10 is a 'positive' number) - - test: - if: "*[2][self::m:mn and not(contains(., '.'))]" - then_test: - - if: "*[2][.='2']" - then: [T: "négyzetgyök"] # phrase(5 is the 'square root' of 25) - - else_if: "*[2][.='3']" - then: [T: "köbgyök"] # phrase(5 is the 'cube root' of 625) - - else: [x: "ToOrdinal(*[2])", T: "gyök"] # phrase(the square 'root' of 25) - else: - - test: - if: "*[2][self::m:mi][string-length(.)=1]" - then: - - x: "*[2]" - - pronounce: [text: "-edik", ipa: "ɛdik", sapi5: "edik", eloquence: "edik"] - else: [x: "*[2]"] - - T: "gyök" # phrase(the square 'root' of 36) - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # phrase(the square root 'of' 36) - - x: "*[1]" - - test: - if: "$ClearSpeak_Roots = 'RootEnd' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" - then: - - pause: short - - T: "gyök vége" # phrase(start the fifth root of x 'end root') - - pause: medium - else_test: - if: "IsNode(*[1], 'simple')" - then: [pause: short] - else: [pause: long] - -# The 'negative' rule interacts with the msqrt/mroot rules as those might pick off this case ("the negative square root of x") -- name: negative_and_positive - tag: [plus, minus] - match: "count(*)=1 and contains(@data-intent-property, ':prefix:')" - replace: - - test: - if: - - "*[1][self::m:square-root or self::m:root] and" - - "($ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd')" - then: [T: ""] - else: - - bookmark: "@id" - - test: - if: "self::m:minus" - then: [T: "negatív"] # phrase(minus 5 is a 'negative' number) - else: [T: "pozitív"] # phrase(7 is a 'positive' number) - - x: "*[1]" - -# Fraction rules -# Mixed numbers mostly "just work" because the invisible char reads as "and" and other parts read properly on their own - -# Units (e.g., meters per second) -- name: per-fraction - tag: fraction - match: - - "$ClearSpeak_Fractions='Per' or" - - "(BaseNode(*[1])[contains(@data-intent-property, ':unit') or" - - " ( self::m:mrow and count(*)=3 and" # maybe a bit paranoid checking the structure... - - " *[1][self::m:mn] and *[2][.='\u2062'] and BaseNode(*[3])[contains(@data-intent-property, ':unit')] ) ] and" - - " BaseNode(*[2])[contains(@data-intent-property, ':unit')] )" - replace: - - x: "*[1]" - - T: "per" # phrase('5 meters 'per' second) - - x: "*[2]" - -- name: common-fraction - tag: fraction - match: - - "($ClearSpeak_Fractions='Auto' or $ClearSpeak_Fractions='Ordinal' or $ClearSpeak_Fractions='EndFrac') and" - - "*[1][self::m:mn][not(contains(., $DecimalSeparators)) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and" - - "*[2][self::m:mn][not(contains(., $DecimalSeparators)) and ($ClearSpeak_Fractions='Ordinal' or (2<= text() and text()<=10))]" - variables: [IsPlural: "*[1]!=1"] - replace: - - x: "*[1]" - - x: "ToOrdinal(*[2], true(), $IsPlural)" # extra args specify fractional ordinal and whether it is plural - -- name: fraction-over-simple - tag: fraction - match: - - "($ClearSpeak_Fractions='Over' or $ClearSpeak_Fractions='FracOver' or $ClearSpeak_Fractions='OverEndFrac') or" - - "( not($ClearSpeak_Fractions='General' or $ClearSpeak_Fractions='GeneralEndFrac') and" - - " (IsNode(*[1],'simple') and IsNode(*[2],'simple')) )" # simple fraction in ClearSpeak spec - replace: - - test: - if: "$ClearSpeak_Fractions='FracOver'" - then: - - test: - if: "$Verbosity!='Terse'" - then: [OT: "a"] - - T: "tört" # phrase(the 'fraction' with 3 over 4) - - x: "*[1]" - - T: "per" # phrase(the fraction 3 'over' 4) - magyarban a "per" a leggyakoribb - - x: "*[2]" - - test: - # very ugly!!! -- replicate nested ordinal fraction as they are an exception - if: "$ClearSpeak_Fractions='OverEndFrac' or ($ClearSpeak_Fractions='EndFrac' and not( ($ClearSpeak_Fractions='Auto' or $ClearSpeak_Fractions='Ordinal' or $ClearSpeak_Fractions='EndFrac') and *[1][*[1][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and *[2][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or (2<= text() and text()<=10))] ] and *[2][*[1][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and *[2][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or (2<= text() and text()<=10))] ] ) )" - then: - - pause: short - - T: "tört vége" # phrase(7 over 8 'end fraction') - - pause: short - -- # fraction with text or numbers followed by text in both numerator and denominator - name: fraction-over-text - tag: fraction - match: - - "not($ClearSpeak_Fractions='General' or $ClearSpeak_Fractions='GeneralEndFrac') and" - - "( " - - " ((*[1][self::m:mi or self::m:mtext][string-length(.)>1]) or " # fractions with text - - " (*[1][self::m:mrow][count(*)=3][ " - - " *[1][self::m:mn] and " - - " *[2][self::m:mo][.='⁢'] and " # invisible times - - " *[3][self::m:mi or self::m:mtext][string-length(.)>1] ]) ) and" - - " ((*[2][self::m:mi or self::m:mtext][string-length(.)>1]) or " # fractions with text - - " (*[2][self::m:mrow][count(*)=3][ " - - " *[1][self::m:mn] and " - - " *[2][self::m:mo][.='⁢'] and " # invisible times - - " *[3][self::m:mi or self::m:mtext][string-length(.)>1] ]) )" - - ")" - replace: - - x: "*[1]" - - T: "per" # phrase(the fraction 3 'over' 4) - - x: "*[2]" - - test: - if: "$ClearSpeak_Fractions='EndFrac' or $ClearSpeak_Fractions='OverEndFrac'" - then: - - pause: short - - T: "tört vége" # phrase(7 over 8 'end fraction') - - pause: short - -- name: default - tag: fraction - match: "." - replace: - - OT: "a" # phrase(5 is 'the' square toot of 25) - - T: "tört, melynek számlálója" # phrase(the 'fraction with numerator' 6) - - test: - if: "not(IsNode(*[1], 'simple'))" - then: [pause: medium] - - x: "*[1]" - - pause: medium - - T: "nevezője pedig" # phrase(the fraction with numerator 5 'and denominator' 8) - - x: "*[2]" - - pause: long - - test: - if: "$ClearSpeak_Fractions='EndFrac' or $ClearSpeak_Fractions='GeneralEndFrac'" - then: - - pause: short - - T: "tört vége" # phrase(the fraction with 3 over 4 'end fraction') - - pause: short - -# rules for functions raised to a power -# these could have been written on 'mrow' but putting them on msup seems more specific -# to see if it is a function, we look right to see if the following sibling is apply-function -- name: ClearSpeak-function-inverse - tag: inverse-function - match: "." - replace: - - test: - if: "$ClearSpeak_Trig = 'TrigInverse'" - then: [x: "*[1]", bookmark: "*[2]/@id", T: "inverz"] # phrase(8 over 5 is the 'inverse' of 5 over 8) - else_test: - if: "$ClearSpeak_Trig = 'ArcTrig'" - then: [bookmark: "*[2]/@id", T: "arkusz", x: "*[1]"] # phrase(the 'arc' of a circle) - else: [bookmark: "*[2]/@id", T: "inverz", x: "*[1]"] # default/Auto # phrase(8 over 5 is the 'inverse' of 5 over 8) - -# Handles functions squared or cubed, where the base is not a trig function. -- name: function-squared-or-cubed # audit-ignore - tag: power - match: - - "*[2][self::m:mn][.='2' or .='3'] and" # the exponent is 2 or 3 - - "following-sibling::*[1][self::m:mo][.='⁡']" #invisible function apply - replace: - - x: "*[1]" # say the trig function name - - bookmark: "*[2]/@id" - - test: - if: "not(IsInDefinition(*[1], 'TrigFunctionNames')) and *[2][.='2']" # the base is not a trig function - then: [T: "a négyzeten"] # say "squared" - else_test: - if: "not(IsInDefinition(*[1], 'TrigFunctionNames'))" # the base is not a trig function - then: [T: "a köbön"] # say "cubed" - else: [T: ""] - -# Handles trig functions with simple arguments (mi or mn), for both 2, 3 and general exponents. -- name: trig-power-argument-before-exponent-general # audit-ignore - tag: [mi, mn] - match: - - "preceding-sibling::*[1][self::m:mo][.='⁡'] and" - - "preceding-sibling::*[2][self::m:power[IsInDefinition(*[1], 'TrigFunctionNames')]]" # if the previous sibling is function-apply and previous previous sibling is trig power - replace: - - test: - - if: "preceding-sibling::*[2]/*[2][self::m:mn][.='2']" # if the exponent is 2 - then: - - x: "text()" # say the argument of the trig function - - T: "a négyzeten" - - else_if: "preceding-sibling::*[2]/*[2][self::m:mn][.='3']" # if the exponent is 3 - then: - - x: "text()" # say the argument of the trig function - - T: "a köbön" - else: - - pause: short - - x: "text()" # say the argument of the function - - pause: short - - T: "a(z)" - - test: - if: "preceding-sibling::*[2]/*[2][self::m:mn][not(contains(., '.'))]" # if the exponent is an integer - then: [x: "ToOrdinal(preceding-sibling::*[2]/*[2])"] # say the ordinal form - else: [x: "preceding-sibling::*[2]/*[2]"] # else, say the exponent - - T: "hatványon" - -# Handles trig functions with grouped arguments (parenthesized or bracketed mrow), for both 2, 3 and general exponents. -- name: trig-power-grouped-argument-before-exponent-general # audit-ignore - tag: [mo, mrow] - match: - - "(self::m:mo[.=')'] and preceding-sibling::*[2][self::m:mo][.='⁡'] and preceding-sibling::*[3][self::m:power[IsInDefinition(*[1], 'TrigFunctionNames')]])" - - "or" - - "(self::m:mrow[IsBracketed(., '(', ')')] and preceding-sibling::*[1][self::m:mo][.='⁡'] and preceding-sibling::*[2][self::m:power[IsInDefinition(*[1], 'TrigFunctionNames')]])" - replace: - - test: - if: "self::m:mo" # if the current node is ) - then: - - x: "text()" # say the argument of the function - - test: - - if: "preceding-sibling::*[3]/*[2][self::m:mn][.='2']" # if the exponent is 2 - then: [T: "a négyzeten"] - - else_if: "preceding-sibling::*[3]/*[2][self::m:mn][.='3']" # if the exponent is 3 - then: [T: "a köbön"] - else: - - T: "a(z)" - - test: - if: "preceding-sibling::*[3]/*[2][self::m:mn][not(contains(., '.'))]" # if the exponent is an integer - then: [x: "ToOrdinal(preceding-sibling::*[3]/*[2])"] # say the ordinal form - else: [x: "preceding-sibling::*[3]/*[2]"] # else, say the exponent - - T: "hatványon" - else: # if the current node is an with parentheses - - x: "*[1]" - - x: "*[2]" - - x: "*[3]" - - test: - - if: "preceding-sibling::*[2]/*[2][self::m:mn][.='2']" # if the exponent is 2 - then: [T: "a négyzeten"] - - else_if: "preceding-sibling::*[2]/*[2][self::m:mn][.='3']" # if the exponent is 3 - then: [T: "a köbön"] - else: - - T: "a(z)" - - test: - if: "preceding-sibling::*[2]/*[2][self::m:mn][not(contains(., '.'))]" # if the exponent is an integer - then: [x: "ToOrdinal(preceding-sibling::*[2]/*[2])"] # say the ordinal form - else: [x: "preceding-sibling::*[2]/*[2]"] # else, say the exponent - - T: "hatványon" - -- name: function-power # audit-ignore - tag: power - match: - - "following-sibling::*[1][self::m:mo][.='⁡'] and" #invisible function apply - - "not(*[1][IsInDefinition(., 'TrigFunctionNames')])" - replace: - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # phrase('the' third power of 2) - - bookmark: "*[2]/@id" - - test: - if: "*[2][self::m:mn][not(contains(., '.'))]" - then: [x: "ToOrdinal(*[2])"] - else: [x: "*[2]"] - - T: "hatványon" # phrase(the third 'power of' 6) - - pause: short - - x: "*[1]" - -# Handles trig function powers (non-2/3) at the base node so generic power rules do not speak the base/exponent too early. -- name: trig-function-power-base-only # audit-ignore - tag: power - match: - - "following-sibling::*[1][self::m:mo][.='⁡'] and" - - "*[1][IsInDefinition(., 'TrigFunctionNames')] and" - - "not(*[2][self::m:mn][.='2' or .='3'])" - replace: - - x: "*[1]" - -- name: AfterPower-nested - tag: power - match: # directly a superscript or an mrow that contains a superscript - - "$ClearSpeak_Exponents = 'AfterPower' and" - - "*[2][self::m:power or self::m:power or self::m:mrow[m:power]]" - replace: - - x: "*[1]" - - T: "a következő kitevőre emelve:" # phrase(5 'raised to the exponent' x plus 1) - - pause: short - - x: "*[2]" - - pause: short - - T: "kitevő vége" # phrase(5 raised to the exponent x plus 1 'end exponent') - -- name: AfterPower-default - tag: power - match: "$ClearSpeak_Exponents = 'AfterPower'" - replace: - - x: "*[1]" - - T: "a következő hatványra emelve:" # phrase(x is 'raised to the power' 4) - - x: "*[2]" - - pause: short - -- name: squared - tag: power - match: "*[2][self::m:mn][.='2'] and $ClearSpeak_Exponents = 'Auto'" - replace: - - x: "*[1]" - - bookmark: "*[2]/@id" - - T: "a négyzeten" # phrase(7 'squared' equals 49) - -- name: cubed - tag: power - match: "*[2][self::m:mn][.='3'] and $ClearSpeak_Exponents = 'Auto'" - replace: - - x: "*[1]" - - bookmark: "*[2]/@id" - - T: "a köbön" # phrase(5 'cubed' equals 125) - -- name: simple-integer # audit-ignore - tag: power - match: "*[2][self::m:mn][not(contains(., '.'))]" - replace: - - x: "*[1]" - - T: "a(z)" # phrase(2 raised 'to the' power 7) - - test: - if: "*[2][.>=0]" - then: [x: "ToOrdinal(*[2])"] - else: [x: "*[2]"] - - T: "hatványon" - -- name: simple-negative-integer # audit-ignore - tag: power - match: - - "*[2][self::m:minus and count(*)=1 and " - - " *[1][self::m:mn][not(contains(., '.'))]" - - " ]" - replace: - - x: "*[1]" - - T: "a" # phrase(2 raised 'to the' power 7) - - x: "*[2]" - - T: "hatványon" - -- name: simple-var # audit-ignore - tag: power - match: "*[2][self::m:mi][string-length(.)=1]" - replace: - - x: "*[1]" - - T: "a(z)" # phrase(3 raised 'to the' power 7) - - x: "*[2]" - - pronounce: [text: "-edik", ipa: "ɛdik", sapi5: "edik", eloquence: "edik"] - - T: "hatványon" - -# match nested exponent, where the nested exponent is has the power 2 or 3 (n below) -# [xxx]^n, - [xxx]^n, [xxx] var^n, -[xxx] var^n -# where xxx is a number or common fraction (or a var in the first two forms) -# short of creating a specialized built-in function, I don't see a way to eliminate a lot of repetition in the matches -# also really bad is that the test of a common fraction is replicated here (four times!) -# Note: the ClearSpeak doc doesn't say these only apply when the pref is "Auto", -# but the test cases all fall back to "raised to the exponent" when not "Auto" -# If these are allowed for non-Auto values, then you end up with "...power power...". -- # [xxx]^n - name: nested-squared-or-cubed - tag: power - match: - - "$ClearSpeak_Exponents = 'Auto' and" - - "*[2][self::m:power][" - - " *[2][self::m:mn][.='2' or .='3'] and " # exp is 2 or 3 - # base is mn, mi, common fraction ([xxx] case) - - " *[1][self::m:mn or self::m:mi or " - - " self::m:fraction[*[1][self::m:mn][not(contains(., '.')) and text()<20] and" - - " *[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]]" - - " ]" - - " ]" - replace: - - x: "*[1]" - - T: "emelve a(z)" # phrase(x 'raised to the' second power) - - x: "*[2]" - - T: "hatványra" # phrase(x raised to the second 'power') - -- # - [xxx]^n - name: nested-negative-squared-or-cubed - tag: power - match: - - "$ClearSpeak_Exponents = 'Auto' and" - - " *[2][self::m:minus and count(*)=1 and " - - " *[1]/*[1][self::m:power][" - - " *[2][self::m:mn][.='2' or .='3'] and " # exp is 2 or 3" - # base is mn, mi, common fraction ([xxx] case) - - " *[1][self::m:mn or self::m:mi or " - - " self::m:fraction[*[1][self::m:mn][not(contains(., '.')) and text()<20] and" - - " *[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]]" - - " ]" - - " ]" - - " ]" - replace: - - x: "*[1]" - - T: "emelve a(z)" # phrase(x 'raised to the' second power) - - x: "*[2]" - - T: "hatványra" # phrase(x raised to the second 'power') - -- # [xxx] var^n - name: nested-var-squared-or-cubed - tag: power - match: - - "$ClearSpeak_Exponents = 'Auto' and" - - " *[2][self::m:mrow][count(*)=3][ " - - " *[3][self::m:power][" - - " *[2][self::m:mn][.='2' or .='3'] and " # exp is 2 or 3 - - " *[1][self::m:mi]" - - " ] and " - - " *[2][self::m:mo][.='⁢'] and " # invisible times - # base is mn, or common fraction ([xxx] case) - - " *[1][self::m:mn or " - - " self::m:fraction[*[1][self::m:mn][not(contains(., '.')) and text()<20] and" - - " *[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]]" - - " ]" - - " ]" - replace: - - x: "*[1]" - - T: "emelve a(z)" # phrase(x 'raised to the' second power) - - x: "*[2]" - - T: "hatványra" # phrase(x raised to the second 'power') - -- # -[xxx] var^n - name: nested-negative-var-squared-or-cubed - tag: power - match: - - "$ClearSpeak_Exponents = 'Auto' and" - - " *[2][self::m:mrow][count(*)=3][ " - - " *[3][self::m:power][" - - " *[2][self::m:mn][.='2' or .='3'] and " # exp is 2 or 3 - - " *[1][self::m:mi]" - - " ] and " - - " *[2][self::m:mo][.='⁢'] and " # invisible times - - " *[1][self::m:minus and count(*)=1 and " - # base is mn, or common fraction ([xxx] case) - - " *[1][self::m:mn or " - - " self::m:fraction[*[1][self::m:mn][not(contains(., '.')) and text()<20] and" - - " *[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]]" - - " ]" - - " ]" - - " ]" - replace: - - x: "*[1]" - - T: "emelve a" # phrase(x 'raised to the' second power) - - x: "*[2]" - - T: "hatványra" # phrase(x raised to the second 'power') - -- name: default-exponent-power - tag: power - match: # directly a superscript or an mrow that contains a superscript - - "*[2][self::m:power or self::m:power or self::m:mrow[m:power]]" - replace: - - x: "*[1]" - - T: "emelve a következő kitevőre:" # phrase(x is 'raised to the exponent') - - pause: short - - x: "*[2]" - - pause: short - - T: "kitevő vége" # phrase(and now 'end exponent' has been reached) - -- name: default - tag: power - match: "." - replace: - - x: "*[1]" - - T: "a(z)" # phrase(x 'raised to the' second power) - - x: "*[2]" - - T: "hatványon" # phrase(x raised to the second 'power') - -# -# Some rules on mrows -# -- # the inference rules lump absolute value and cardinality together, so those rules are implemented here - name: ClearSpeak-absolute-value - tag: absolute-value - match: "." - variables: [WordToSay: "IfThenElse($ClearSpeak_AbsoluteValue = 'Cardinality', 'számossága', 'abszolút értéke')"] - replace: - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # phrase('the' absolute value of 25) - - x: "*[1]" - - x: "$WordToSay" - - test: - if: "$ClearSpeak_AbsoluteValue = 'AbsEnd'" - then: - - pause: short - - T: "vége az" # phrase('end' absolute value) - - T: "abszolút értéknek" - - pause: short - -- name: set - tag: set - # Empty set and braced/{set-builder} forms (typically 0–1 child). - # Multi-arg intent set($x,$y,...) and set($x) with @arg fall through to function-intent - # ("the set of …"). - match: "count(*)=0 or (count(*)=1 and not(*[1][@arg]))" - replace: - - test: - - if: "count(*)=0" - then: [T: "az üres halmaz"] # phrase('the empty set') - - else_if: "count(*[1]/*)=3 and *[1]/*[2][self::m:mo][.=':' or .='|' or .='∣']" - then: - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # phrase('the' empty set) - - T: "" # phrase(the 'empty set') - - test: - if: "$ClearSpeak_Sets != 'woAll'" - then: [T: "minden"] # phrase(the set of 'all' integers) - - x: "*[1]/*[1]" - - T: "melyekre teljesül, hogy" # phrase(the set S 'such that' x is less than y) - - x: "*[1]/*[3]" - else: - - test: - if: "$ClearSpeak_Sets != 'SilentBracket'" - then: - - test: - if: "$Verbosity!='Terse'" - then: [T: "a"] # phrase('the' set of integers) - - T: "halmaz" # phrase(this is a 'set' of integers) - - x: "*[1]" - -- # intervals are controlled by a ClearSpeak Preference -- parens/brackets don't have to match, so we avoid IsBracketed - # alternatively, we could have four (or ten) rules, but there is a lot of duplication if we do that - # this one rule handles all ten cases listed as part $ClearSpeak_Paren = 'Interval' - # note that *[2] is an mrow with X, ",", Y, so getting X or Y is a double index - name: ClearSpeak-intervals # audit-ignore # avoid overriding with default "intervals" name - variables: - - is_intervals_start_infinity: "*[1][self::m:minus and count(*)=1 and *[1][.='∞']]" - - T: "elemet" - - is_intervals_end_infinity: "*[2][.='∞'or (self::m:plus and count(*)=1 and *[1][.='∞'])]" - tag: [open-interval, open-closed-interval, closed-interval, closed-open-interval] - match: "." - replace: - - x: "*[1]" - - T: "től" - - x: "*[2]" - - T: "ig terjedő intervallum" - - pause: short - - test: - if: "not($is_intervals_start_infinity)" - then: - - test: - if: "starts-with(name(.), 'open')" - then: [T: "nem"] # phrase(the interval from a to b 'not' including b) - - T: "tartalmazza a(z)" # phrase(the interval from a to b not 'including' b) - - x: "*[1]" - - T: "elemet" - # logic to deal with [not] arg #1 - - test: - if: "not($is_intervals_start_infinity or $is_intervals_end_infinity)" - then_test: - - if: "name(.)='open-interval'" - then: [T: "vagy"] # phrase(the interval including a 'or' b ) - - else_if: "name(.)='closed-interval'" - then: [T: "és"] # phrase(the interval including a 'and' b) - else: [T: "de"] # phrase(the interval including a 'but' not b) - # some ugly logic dealing with connectives: or, but, but, and (cleaner to be part of next clause?) - - test: - if: "not($is_intervals_end_infinity)" - then: - - test: - # there is some asymmetry to the test because of the and/or/but logic above - if: "not( name(.)='open-interval' or name(.)='closed-interval' ) or $is_intervals_start_infinity" - then: - - test: - if: "name(.) = 'open-interval' or name(.) = 'closed-open-interval'" - then: [T: "nem"] # phrase(the interval 'not' including a) - - T: "tartalmazza" # phrase(the interval not 'including' a) - - T: "a(z)" - - x: "*[2]" - - T: "elemet" - # onto the [not] [including]... part - -- name: binomial-frac-vector - tag: matrix - match: - - "$ClearSpeak_Matrix = 'Combinatorics' and " - - "count(*[1]/*)=1 and count(*)=2" - replace: - - x: "*[1]/*[1]/*" # mtable/mtr/mtd - - T: "alatt a" # phrase(the binomial coefficient n 'choose' m) - - x: "*[2]/*[1]/*" - -- name: ClearSpeak-default - tag: [mtr, mlabeledtr] - match: "parent::m:matrix or parent::m:determinant" - variables: [NextLineIsContinuedRow: "following-sibling::*[1][contains(@data-intent-property, ':continued-row:')]"] - replace: - - pause: medium - - x: "count(preceding-sibling::*)+1" - - T: ". sor" # phrase(the first 'row' of a matrix) - - test: - if: ".[self::m:mlabeledtr]" - then: - - T: "címkéje:" # phrase(the line 'with label' first equation) - - x: "*[1]/*" - - pause: short - - pause: medium - - test: - if: ".[self::m:mlabeledtr]" - then: [x: "*[position()>1]"] - else: [x: "*"] - -- # handle both log and ln - name: ClearSpeak-log - tag: mi - match: ".='log' or .='ln'" - replace: - - bookmark: "@id" - - test: - if: "$Verbosity!='Terse' and not(IsNode(following-sibling::*[2],'simple'))" - then: [T: "a"] # phrase('the' square root of 25) - - test: - - if: ".='log'" - then: [T: "logaritmus"] - - else_if: "$ClearSpeak_Log = 'LnAsNaturalLog'" - then: [T: "természetes alapú logaritmus"] # phrase(the 'natural log' of x) - else: [T: "l n"] - -- name: ClearSpeak-multi-line # audit-ignore - tag: [piecewise, system-of-equations, lines] # these are ignored in favor of the ClearSpeak prefs - match: "." - variables: - # Wikipedia has some tables where all the entire first column is empty (e.g., https://en.wikipedia.org/wiki/List_of_trigonometric_identities) - - LineCount: "count(*[not(contains(@data-intent-property, ':continued-row:'))])" - - NextLineIsContinuedRow: "false()" # default value - - IsColumnSilent: true() - replace: - - test: - - if: "$ClearSpeak_MultiLineOverview = 'Auto'" - then: - - x: "$LineCount" - - test: - - if: "($ClearSpeak_MultiLineLabel = 'Auto' and self::m:piecewise) or $ClearSpeak_MultiLineLabel = 'Case'" - then: [T: "eset"] # phrase(this is the first 'case' of three cases) - - else_if: "$ClearSpeak_MultiLineLabel = 'Auto' or $ClearSpeak_MultiLineLabel = 'Line' or $ClearSpeak_MultiLineLabel = 'None'" # already dealt with Auto/Case - then: [T: "sor"] # phrase(this is the first 'line' of three lines) - - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" - then: [T: "feltétel"] # phrase(this is the first 'constraint' of three constraints) - - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" - then: [T: "egyenlet"] # phrase(this is the first 'equation' of three equations) - - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" - then: [T: "sor"] # phrase(this is the first 'row' of three rows) - - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" - then: [T: "lépés"] # phrase(this is the first 'step' of three steps) - # else 'None -- don't say anything' - - pause: short - - x: "*" - - pause: long - -- name: ClearSpeak-default-multiline - tag: [mtr, mlabeledtr] - match: "parent::m:piecewise or parent::m:system-of-equations or parent::m:lines" - variables: [NextLineIsContinuedRow: "following-sibling::*[1][contains(@data-intent-property, ':continued-row:')]"] - replace: - - test: - if: "not($LineCount=1 or $ClearSpeak_MultiLineLabel='None' or contains(@data-intent-property, ':continued-row:'))" - then: - - pause: medium - - x: "count(preceding-sibling::*[not(contains(@data-intent-property, ':continued-row:'))]) + 1" - - test: - - if: "($ClearSpeak_MultiLineLabel = 'Auto' and parent::m:piecewise) or $ClearSpeak_MultiLineLabel = 'Case'" - then: [T: ". eset"] # phrase(in this 'case' x is not equal to y) - - else_if: "$ClearSpeak_MultiLineLabel = 'Auto' or $ClearSpeak_MultiLineLabel = 'Line'" # already dealt with Auto/Case - then: [T: ". sor"] # phrase(the straight 'line' between x and y) - - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" - then: [T: ". feltétel"] # phrase(there is a 'constraint' on possible values) - - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" - then: [T: ". egyenlet"] # phrase(the 'equation' pi r squared gives the area of a circle) - - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" - then: [T: ". sor"] # phrase(the values on the top 'row' are relevant) - - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" - then: [T: ". lépés"] # phrase(this is a 'step' by step process) - # else 'None -- don't say anything' - - test: - if: "self::m:mlabeledtr" - then: - - T: "címkével:" # phrase(the diagram is complete 'with label') - - x: "*[1]/*" - - test: - - if: "$ClearSpeak_MultiLineLabel='None'" - then: [pause: xlong] # need a very long pause with no line labels - - else_if: "not(contains(@data-intent-property, ':continued-row:'))" - then: [pause: medium] - - test: - if: "self::m:mlabeledtr" - then: [x: "*[position()>1]"] - else: [x: "*"] - -- name: ClearSpeak_Functions_None - tag: mo - match: - - ".='⁡' and $ClearSpeak_Functions = 'None' and" - - "not(preceding-sibling::*[1][IsInDefinition(., 'TrigFunctionNames')])" # Functions=None does not apply to "trig" functions - replace: - test: - if: "$ClearSpeak_ImpliedTimes = 'None'" - then: [T: ""] - else: [T: "szorozva"] # phrase(5 'times' 3 equals 15) - -- name: no-times - tag: mo - match: - # Note: this rule is also part of the paren rule so that the parens speak - - ".='⁢' and $ClearSpeak_ImpliedTimes = 'None'" - replace: - - T: "" - -- name: ClearSpeak-times - tag: mo - match: - # say "times" when invisible times is followed by parens or a superscript that has a base with parens or "|"s - # if we aren't sure if it is times or not, don't say anything - - ".='⁢' and (not(@data-function-guess) or $ClearSpeak_Functions = 'None') and" - - "not(ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) and (" - - " $ClearSpeak_ImpliedTimes = 'MoreImpliedTimes'" - - " or " - - " following-sibling::*[1][" - - " IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|') or " - # most of these aren't mentioned in ClearSpeak spec, but are (I think) expected uses of "times" - - " self::m:matrix or self::m:determinant or self::m:binomial or" # followed by parens - - " self::m:square-root or self::m:msqrt or self::m:root or self::m:mroot or" - - " (self::m:msub or self::m:msubsup or" - - " ((self::m:msup or self::m:power) and not(IsNode(*[1], 'leaf') and *[2][self::m:mn and (.=2 or '.=3')]))) and " # followed by msup, etc. - - " (*[1][self::m:mrow[IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')] or " - - " self::m:matrix or self::m:determinant] or" # base has parens - - " not(IsNode(*[2], 'simple')) or " - - " (self::m:msubsup and not(IsNode(*[3], 'simple')))" - - " )" - - " ]" - # other possibility is the preceding element has parens (but not the following) - # this is not mentioned in the ClearSpeak rules or examples but seems like it should say "times". E.g, |x| y - - " or " - - " preceding-sibling::*[1][" - - " IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')]" # followed by parens - - " )" - replace: - - T: "szorozva" # phrase(5 'times' 3 equals 15) - -- name: no-say-parens - tag: mrow - match: - - "parent::*[not(self::m:msup) and not(self::m:msub) and not(self::m:msubsup) and not(self::m:power) and" - - " not(self::m:math) ] and " # rule out [x] standing alone - - "( IsBracketed(., '(', ')') or IsBracketed(., '[', ']') ) and " - - "not( $ClearSpeak_Functions = 'None' and " - - " (preceding-sibling::*[1][.='⁡'] or following-sibling::*[1][.='⁡']) ) and " - - "not( $ClearSpeak_ImpliedTimes = 'None' and " - - " (preceding-sibling::*[1][.='⁢'] or following-sibling::*[1][.='⁢']) ) and " - - "IsNode(*[2], 'simple') and" - - "not(preceding-sibling::*[1][.='\u2062' and @data-function-guess]) and" - - "not(ancestor-or-self::*[contains(@data-intent-property, ':literal:')])" - # missing clause: 'a positive fraction that is spoken as an ordinal - # (either by the Ordinal preference or by the default rules)' - replace: - - x: "*[2]" - -- include: "SharedRules/geometry.yaml" -- include: "SharedRules/linear-algebra.yaml" -- include: "SharedRules/general.yaml" -- include: "SharedRules/default.yaml" +--- +- name: pause + tag: "!*" + match: "not(self::m:math) and not($MatchingPause) and @data-intent-property[contains(., ':pause')]" + replace: + - with: + variables: [MatchingPause: "true()"] + replace: + - test: + - if: "contains(@data-intent-property, ':pause-long')" + then: [pause: long] + - else_if: "contains(@data-intent-property, ':pause-short')" + then: [pause: short] + else: [pause: medium] + - x: "." + +- name: intent-literal-silent + tag: [mi, mo, mn] + match: "contains(@data-intent-property, ':silent:')" + # say nothing + replace: [] + +# handling of negative numbers that come from 'intent' is hard -- we do something that is close to right here +- name: intent-literal-negative-number + tag: mn + match: "starts-with(text(), '-')" + replace: + - T: "mínusz" # phrase(10 'minus' 4 equals 6) + - x: "translate(text(), '-_', '')" + +- name: default + tag: square-root + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # phrase('the' square root of 25) + - test: + if: "$ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" + then: + - bookmark: "*[1]/@id" + - test: + if: "parent::*[self::m:minus and count(*)=1]" + then: [T: "negatív"] # phrase(minus 4 is a 'negative' number) + else: [T: "pozitív"] # phrase(10 is a 'positive' number) + - T: "négyzetgyök" # phrase(8 is the 'square root' of 64) + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # phrase(the square root 'of' 5) - magyarban nem kell kötőszó + else: [pause: short] + - x: "*[1]" + - test: + - if: "$ClearSpeak_Roots = 'RootEnd' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" + then: + - pause: short + - T: "gyök vége" # phrase(the square root of x 'end root') + - pause: medium + - else_if: "IsNode(*[1], 'simple')" + then: [pause: short] + else: [pause: long] + +- name: default + tag: root + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "a"] # phrase(6 is 'the' square root of 36) + - test: + if: "$ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" + then: + - test: + if: "parent::*[(self::m:minus or self::m:plus) and count(*)=1]" + then: [bookmark: "parent/@id"] + - test: + if: "parent::m:minus" + then: [T: "negatív"] # phrase(minus 6 is a 'negative' number) + else: [T: "pozitív"] # phrase(10 is a 'positive' number) + - test: + if: "*[2][self::m:mn and not(contains(., '.'))]" + then_test: + - if: "*[2][.='2']" + then: [T: "négyzetgyök"] # phrase(5 is the 'square root' of 25) + - else_if: "*[2][.='3']" + then: [T: "köbgyök"] # phrase(5 is the 'cube root' of 625) + - else: [x: "ToOrdinal(*[2])", T: "gyök"] # phrase(the square 'root' of 25) + else: + - test: + if: "*[2][self::m:mi][string-length(.)=1]" + then: + - x: "*[2]" + - pronounce: [text: "-edik", ipa: "ɛdik", sapi5: "edik", eloquence: "edik"] + else: [x: "*[2]"] + - T: "gyök" # phrase(the square 'root' of 36) + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # phrase(the square root 'of' 36) + - x: "*[1]" + - test: + if: "$ClearSpeak_Roots = 'RootEnd' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" + then: + - pause: short + - T: "gyök vége" # phrase(start the fifth root of x 'end root') + - pause: medium + else_test: + if: "IsNode(*[1], 'simple')" + then: [pause: short] + else: [pause: long] + +# The 'negative' rule interacts with the msqrt/mroot rules as those might pick off this case ("the negative square root of x") +- name: negative_and_positive + tag: [plus, minus] + match: "count(*)=1 and contains(@data-intent-property, ':prefix:')" + replace: + - test: + if: + - "*[1][self::m:square-root or self::m:root] and" + - "($ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd')" + then: [T: ""] + else: + - bookmark: "@id" + - test: + if: "self::m:minus" + then: [T: "negatív"] # phrase(minus 5 is a 'negative' number) + else: [T: "pozitív"] # phrase(7 is a 'positive' number) + - x: "*[1]" + +# Fraction rules +# Mixed numbers mostly "just work" because the invisible char reads as "and" and other parts read properly on their own + +# Units (e.g., meters per second) +- name: per-fraction + tag: fraction + match: + - "$ClearSpeak_Fractions='Per' or" + - "(BaseNode(*[1])[contains(@data-intent-property, ':unit') or" + - " ( self::m:mrow and count(*)=3 and" # maybe a bit paranoid checking the structure... + - " *[1][self::m:mn] and *[2][.='\u2062'] and BaseNode(*[3])[contains(@data-intent-property, ':unit')] ) ] and" + - " BaseNode(*[2])[contains(@data-intent-property, ':unit')] )" + replace: + - x: "*[1]" + - T: "per" # phrase('5 meters 'per' second) + - x: "*[2]" + +- name: common-fraction + tag: fraction + match: + - "($ClearSpeak_Fractions='Auto' or $ClearSpeak_Fractions='Ordinal' or $ClearSpeak_Fractions='EndFrac') and" + - "*[1][self::m:mn][not(contains(., $DecimalSeparators)) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and" + - "*[2][self::m:mn][not(contains(., $DecimalSeparators)) and ($ClearSpeak_Fractions='Ordinal' or (2<= text() and text()<=10))]" + variables: [IsPlural: "*[1]!=1"] + replace: + - x: "*[1]" + - x: "ToOrdinal(*[2], true(), $IsPlural)" # extra args specify fractional ordinal and whether it is plural + +- name: fraction-over-simple + tag: fraction + match: + - "($ClearSpeak_Fractions='Over' or $ClearSpeak_Fractions='FracOver' or $ClearSpeak_Fractions='OverEndFrac') or" + - "( not($ClearSpeak_Fractions='General' or $ClearSpeak_Fractions='GeneralEndFrac') and" + - " (IsNode(*[1],'simple') and IsNode(*[2],'simple')) )" # simple fraction in ClearSpeak spec + replace: + - test: + if: "$ClearSpeak_Fractions='FracOver'" + then: + - test: + if: "$Verbosity!='Terse'" + then: [OT: "a"] + - T: "tört" # phrase(the 'fraction' with 3 over 4) + - x: "*[1]" + - T: "per" # phrase(the fraction 3 'over' 4) - magyarban a "per" a leggyakoribb + - x: "*[2]" + - test: + # very ugly!!! -- replicate nested ordinal fraction as they are an exception + if: "$ClearSpeak_Fractions='OverEndFrac' or ($ClearSpeak_Fractions='EndFrac' and not( ($ClearSpeak_Fractions='Auto' or $ClearSpeak_Fractions='Ordinal' or $ClearSpeak_Fractions='EndFrac') and *[1][*[1][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and *[2][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or (2<= text() and text()<=10))] ] and *[2][*[1][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and *[2][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or (2<= text() and text()<=10))] ] ) )" + then: + - pause: short + - T: "tört vége" # phrase(7 over 8 'end fraction') + - pause: short + +- # fraction with text or numbers followed by text in both numerator and denominator + name: fraction-over-text + tag: fraction + match: + - "not($ClearSpeak_Fractions='General' or $ClearSpeak_Fractions='GeneralEndFrac') and" + - "( " + - " ((*[1][self::m:mi or self::m:mtext][string-length(.)>1]) or " # fractions with text + - " (*[1][self::m:mrow][count(*)=3][ " + - " *[1][self::m:mn] and " + - " *[2][self::m:mo][.='⁢'] and " # invisible times + - " *[3][self::m:mi or self::m:mtext][string-length(.)>1] ]) ) and" + - " ((*[2][self::m:mi or self::m:mtext][string-length(.)>1]) or " # fractions with text + - " (*[2][self::m:mrow][count(*)=3][ " + - " *[1][self::m:mn] and " + - " *[2][self::m:mo][.='⁢'] and " # invisible times + - " *[3][self::m:mi or self::m:mtext][string-length(.)>1] ]) )" + - ")" + replace: + - x: "*[1]" + - T: "per" # phrase(the fraction 3 'over' 4) + - x: "*[2]" + - test: + if: "$ClearSpeak_Fractions='EndFrac' or $ClearSpeak_Fractions='OverEndFrac'" + then: + - pause: short + - T: "tört vége" # phrase(7 over 8 'end fraction') + - pause: short + +- name: default + tag: fraction + match: "." + replace: + - OT: "a" # phrase(5 is 'the' square toot of 25) + - T: "tört, melynek számlálója" # phrase(the 'fraction with numerator' 6) + - test: + if: "not(IsNode(*[1], 'simple'))" + then: [pause: medium] + - x: "*[1]" + - pause: medium + - T: "nevezője pedig" # phrase(the fraction with numerator 5 'and denominator' 8) + - x: "*[2]" + - pause: long + - test: + if: "$ClearSpeak_Fractions='EndFrac' or $ClearSpeak_Fractions='GeneralEndFrac'" + then: + - pause: short + - T: "tört vége" # phrase(the fraction with 3 over 4 'end fraction') + - pause: short + +# rules for functions raised to a power +# these could have been written on 'mrow' but putting them on msup seems more specific +# to see if it is a function, we look right to see if the following sibling is apply-function +- name: ClearSpeak-function-inverse + tag: inverse-function + match: "." + replace: + - test: + if: "$ClearSpeak_Trig = 'TrigInverse'" + then: [x: "*[1]", bookmark: "*[2]/@id", T: "inverz"] # phrase(8 over 5 is the 'inverse' of 5 over 8) + else_test: + if: "$ClearSpeak_Trig = 'ArcTrig'" + then: [bookmark: "*[2]/@id", T: "arkusz", x: "*[1]"] # phrase(the 'arc' of a circle) + else: [bookmark: "*[2]/@id", T: "inverz", x: "*[1]"] # default/Auto # phrase(8 over 5 is the 'inverse' of 5 over 8) + +# Handles functions squared or cubed, where the base is not a trig function. +- name: function-squared-or-cubed # audit-ignore + tag: power + match: + - "*[2][self::m:mn][.='2' or .='3'] and" # the exponent is 2 or 3 + - "following-sibling::*[1][self::m:mo][.='⁡']" #invisible function apply + replace: + - x: "*[1]" # say the trig function name + - bookmark: "*[2]/@id" + - test: + if: "not(IsInDefinition(*[1], 'TrigFunctionNames')) and *[2][.='2']" # the base is not a trig function + then: [T: "a négyzeten"] # say "squared" + else_test: + if: "not(IsInDefinition(*[1], 'TrigFunctionNames'))" # the base is not a trig function + then: [T: "a köbön"] # say "cubed" + else: [T: ""] + +# Handles trig functions with simple arguments (mi or mn), for both 2, 3 and general exponents. +- name: trig-power-argument-before-exponent-general # audit-ignore + tag: [mi, mn] + match: + - "preceding-sibling::*[1][self::m:mo][.='⁡'] and" + - "preceding-sibling::*[2][self::m:power[IsInDefinition(*[1], 'TrigFunctionNames')]]" # if the previous sibling is function-apply and previous previous sibling is trig power + replace: + - test: + - if: "preceding-sibling::*[2]/*[2][self::m:mn][.='2']" # if the exponent is 2 + then: + - x: "text()" # say the argument of the trig function + - T: "a négyzeten" + - else_if: "preceding-sibling::*[2]/*[2][self::m:mn][.='3']" # if the exponent is 3 + then: + - x: "text()" # say the argument of the trig function + - T: "a köbön" + else: + - pause: short + - x: "text()" # say the argument of the function + - pause: short + - T: "a(z)" + - test: + if: "preceding-sibling::*[2]/*[2][self::m:mn][not(contains(., '.'))]" # if the exponent is an integer + then: [x: "ToOrdinal(preceding-sibling::*[2]/*[2])"] # say the ordinal form + else: [x: "preceding-sibling::*[2]/*[2]"] # else, say the exponent + - T: "hatványon" + +# Handles trig functions with grouped arguments (parenthesized or bracketed mrow), for both 2, 3 and general exponents. +- name: trig-power-grouped-argument-before-exponent-general # audit-ignore + tag: [mo, mrow] + match: + - "(self::m:mo[.=')'] and preceding-sibling::*[2][self::m:mo][.='⁡'] and preceding-sibling::*[3][self::m:power[IsInDefinition(*[1], 'TrigFunctionNames')]])" + - "or" + - "(self::m:mrow[IsBracketed(., '(', ')')] and preceding-sibling::*[1][self::m:mo][.='⁡'] and preceding-sibling::*[2][self::m:power[IsInDefinition(*[1], 'TrigFunctionNames')]])" + replace: + - test: + if: "self::m:mo" # if the current node is ) + then: + - x: "text()" # say the argument of the function + - test: + - if: "preceding-sibling::*[3]/*[2][self::m:mn][.='2']" # if the exponent is 2 + then: [T: "a négyzeten"] + - else_if: "preceding-sibling::*[3]/*[2][self::m:mn][.='3']" # if the exponent is 3 + then: [T: "a köbön"] + else: + - T: "a(z)" + - test: + if: "preceding-sibling::*[3]/*[2][self::m:mn][not(contains(., '.'))]" # if the exponent is an integer + then: [x: "ToOrdinal(preceding-sibling::*[3]/*[2])"] # say the ordinal form + else: [x: "preceding-sibling::*[3]/*[2]"] # else, say the exponent + - T: "hatványon" + else: # if the current node is an with parentheses + - x: "*[1]" + - x: "*[2]" + - x: "*[3]" + - test: + - if: "preceding-sibling::*[2]/*[2][self::m:mn][.='2']" # if the exponent is 2 + then: [T: "a négyzeten"] + - else_if: "preceding-sibling::*[2]/*[2][self::m:mn][.='3']" # if the exponent is 3 + then: [T: "a köbön"] + else: + - T: "a(z)" + - test: + if: "preceding-sibling::*[2]/*[2][self::m:mn][not(contains(., '.'))]" # if the exponent is an integer + then: [x: "ToOrdinal(preceding-sibling::*[2]/*[2])"] # say the ordinal form + else: [x: "preceding-sibling::*[2]/*[2]"] # else, say the exponent + - T: "hatványon" + +- name: function-power # audit-ignore + tag: power + match: + - "following-sibling::*[1][self::m:mo][.='⁡'] and" #invisible function apply + - "not(*[1][IsInDefinition(., 'TrigFunctionNames')])" + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # phrase('the' third power of 2) + - bookmark: "*[2]/@id" + - test: + if: "*[2][self::m:mn][not(contains(., '.'))]" + then: [x: "ToOrdinal(*[2])"] + else: [x: "*[2]"] + - T: "hatványon" # phrase(the third 'power of' 6) + - pause: short + - x: "*[1]" + +# Handles trig function powers (non-2/3) at the base node so generic power rules do not speak the base/exponent too early. +- name: trig-function-power-base-only # audit-ignore + tag: power + match: + - "following-sibling::*[1][self::m:mo][.='⁡'] and" + - "*[1][IsInDefinition(., 'TrigFunctionNames')] and" + - "not(*[2][self::m:mn][.='2' or .='3'])" + replace: + - x: "*[1]" + +- name: AfterPower-nested + tag: power + match: # directly a superscript or an mrow that contains a superscript + - "$ClearSpeak_Exponents = 'AfterPower' and" + - "*[2][self::m:power or self::m:power or self::m:mrow[m:power]]" + replace: + - x: "*[1]" + - T: "a következő kitevőre emelve:" # phrase(5 'raised to the exponent' x plus 1) + - pause: short + - x: "*[2]" + - pause: short + - T: "kitevő vége" # phrase(5 raised to the exponent x plus 1 'end exponent') + +- name: AfterPower-default + tag: power + match: "$ClearSpeak_Exponents = 'AfterPower'" + replace: + - x: "*[1]" + - T: "a következő hatványra emelve:" # phrase(x is 'raised to the power' 4) + - x: "*[2]" + - pause: short + +- name: squared + tag: power + match: "*[2][self::m:mn][.='2'] and $ClearSpeak_Exponents = 'Auto'" + replace: + - x: "*[1]" + - bookmark: "*[2]/@id" + - T: "a négyzeten" # phrase(7 'squared' equals 49) + +- name: cubed + tag: power + match: "*[2][self::m:mn][.='3'] and $ClearSpeak_Exponents = 'Auto'" + replace: + - x: "*[1]" + - bookmark: "*[2]/@id" + - T: "a köbön" # phrase(5 'cubed' equals 125) + +- name: simple-integer # audit-ignore + tag: power + match: "*[2][self::m:mn][not(contains(., '.'))]" + replace: + - x: "*[1]" + - T: "a(z)" # phrase(2 raised 'to the' power 7) + - test: + if: "*[2][.>=0]" + then: [x: "ToOrdinal(*[2])"] + else: [x: "*[2]"] + - T: "hatványon" + +- name: simple-negative-integer # audit-ignore + tag: power + match: + - "*[2][self::m:minus and count(*)=1 and " + - " *[1][self::m:mn][not(contains(., '.'))]" + - " ]" + replace: + - x: "*[1]" + - T: "a" # phrase(2 raised 'to the' power 7) + - x: "*[2]" + - T: "hatványon" + +- name: simple-var # audit-ignore + tag: power + match: "*[2][self::m:mi][string-length(.)=1]" + replace: + - x: "*[1]" + - T: "a(z)" # phrase(3 raised 'to the' power 7) + - x: "*[2]" + - pronounce: [text: "-edik", ipa: "ɛdik", sapi5: "edik", eloquence: "edik"] + - T: "hatványon" + +# match nested exponent, where the nested exponent is has the power 2 or 3 (n below) +# [xxx]^n, - [xxx]^n, [xxx] var^n, -[xxx] var^n +# where xxx is a number or common fraction (or a var in the first two forms) +# short of creating a specialized built-in function, I don't see a way to eliminate a lot of repetition in the matches +# also really bad is that the test of a common fraction is replicated here (four times!) +# Note: the ClearSpeak doc doesn't say these only apply when the pref is "Auto", +# but the test cases all fall back to "raised to the exponent" when not "Auto" +# If these are allowed for non-Auto values, then you end up with "...power power...". +- # [xxx]^n + name: nested-squared-or-cubed + tag: power + match: + - "$ClearSpeak_Exponents = 'Auto' and" + - "*[2][self::m:power][" + - " *[2][self::m:mn][.='2' or .='3'] and " # exp is 2 or 3 + # base is mn, mi, common fraction ([xxx] case) + - " *[1][self::m:mn or self::m:mi or " + - " self::m:fraction[*[1][self::m:mn][not(contains(., '.')) and text()<20] and" + - " *[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]]" + - " ]" + - " ]" + replace: + - x: "*[1]" + - T: "emelve a(z)" # phrase(x 'raised to the' second power) + - x: "*[2]" + - T: "hatványra" # phrase(x raised to the second 'power') + +- # - [xxx]^n + name: nested-negative-squared-or-cubed + tag: power + match: + - "$ClearSpeak_Exponents = 'Auto' and" + - " *[2][self::m:minus and count(*)=1 and " + - " *[1]/*[1][self::m:power][" + - " *[2][self::m:mn][.='2' or .='3'] and " # exp is 2 or 3" + # base is mn, mi, common fraction ([xxx] case) + - " *[1][self::m:mn or self::m:mi or " + - " self::m:fraction[*[1][self::m:mn][not(contains(., '.')) and text()<20] and" + - " *[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]]" + - " ]" + - " ]" + - " ]" + replace: + - x: "*[1]" + - T: "emelve a(z)" # phrase(x 'raised to the' second power) + - x: "*[2]" + - T: "hatványra" # phrase(x raised to the second 'power') + +- # [xxx] var^n + name: nested-var-squared-or-cubed + tag: power + match: + - "$ClearSpeak_Exponents = 'Auto' and" + - " *[2][self::m:mrow][count(*)=3][ " + - " *[3][self::m:power][" + - " *[2][self::m:mn][.='2' or .='3'] and " # exp is 2 or 3 + - " *[1][self::m:mi]" + - " ] and " + - " *[2][self::m:mo][.='⁢'] and " # invisible times + # base is mn, or common fraction ([xxx] case) + - " *[1][self::m:mn or " + - " self::m:fraction[*[1][self::m:mn][not(contains(., '.')) and text()<20] and" + - " *[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]]" + - " ]" + - " ]" + replace: + - x: "*[1]" + - T: "emelve a(z)" # phrase(x 'raised to the' second power) + - x: "*[2]" + - T: "hatványra" # phrase(x raised to the second 'power') + +- # -[xxx] var^n + name: nested-negative-var-squared-or-cubed + tag: power + match: + - "$ClearSpeak_Exponents = 'Auto' and" + - " *[2][self::m:mrow][count(*)=3][ " + - " *[3][self::m:power][" + - " *[2][self::m:mn][.='2' or .='3'] and " # exp is 2 or 3 + - " *[1][self::m:mi]" + - " ] and " + - " *[2][self::m:mo][.='⁢'] and " # invisible times + - " *[1][self::m:minus and count(*)=1 and " + # base is mn, or common fraction ([xxx] case) + - " *[1][self::m:mn or " + - " self::m:fraction[*[1][self::m:mn][not(contains(., '.')) and text()<20] and" + - " *[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]]" + - " ]" + - " ]" + - " ]" + replace: + - x: "*[1]" + - T: "emelve a" # phrase(x 'raised to the' second power) + - x: "*[2]" + - T: "hatványra" # phrase(x raised to the second 'power') + +- name: default-exponent-power + tag: power + match: # directly a superscript or an mrow that contains a superscript + - "*[2][self::m:power or self::m:power or self::m:mrow[m:power]]" + replace: + - x: "*[1]" + - T: "emelve a következő kitevőre:" # phrase(x is 'raised to the exponent') + - pause: short + - x: "*[2]" + - pause: short + - T: "kitevő vége" # phrase(and now 'end exponent' has been reached) + +- name: default + tag: power + match: "." + replace: + - x: "*[1]" + - T: "a(z)" # phrase(x 'raised to the' second power) + - x: "*[2]" + - T: "hatványon" # phrase(x raised to the second 'power') + +# +# Some rules on mrows +# +- # the inference rules lump absolute value and cardinality together, so those rules are implemented here + name: ClearSpeak-absolute-value + tag: absolute-value + match: "." + variables: [WordToSay: "IfThenElse($ClearSpeak_AbsoluteValue = 'Cardinality', 'számossága', 'abszolút értéke')"] + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # phrase('the' absolute value of 25) + - x: "*[1]" + - x: "$WordToSay" + - test: + if: "$ClearSpeak_AbsoluteValue = 'AbsEnd'" + then: + - pause: short + - T: "vége az" # phrase('end' absolute value) + - T: "abszolút értéknek" + - pause: short + +- name: set + tag: set + # Empty set and braced/{set-builder} forms (typically 0–1 child). + # Multi-arg intent set($x,$y,...) and set($x) with @arg fall through to function-intent + # ("the set of …"). + match: "count(*)=0 or (count(*)=1 and not(*[1][@arg]))" + replace: + - test: + - if: "count(*)=0" + then: [T: "az üres halmaz"] # phrase('the empty set') + - else_if: "count(*[1]/*)=3 and *[1]/*[2][self::m:mo][.=':' or .='|' or .='∣']" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # phrase('the' empty set) + - T: "" # phrase(the 'empty set') + - test: + if: "$ClearSpeak_Sets != 'woAll'" + then: [T: "minden"] # phrase(the set of 'all' integers) + - x: "*[1]/*[1]" + - T: "melyekre teljesül, hogy" # phrase(the set S 'such that' x is less than y) + - x: "*[1]/*[3]" + else: + - test: + if: "$ClearSpeak_Sets != 'SilentBracket'" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: "a"] # phrase('the' set of integers) + - T: "halmaz" # phrase(this is a 'set' of integers) + - x: "*[1]" + +- # intervals are controlled by a ClearSpeak Preference -- parens/brackets don't have to match, so we avoid IsBracketed + # alternatively, we could have four (or ten) rules, but there is a lot of duplication if we do that + # this one rule handles all ten cases listed as part $ClearSpeak_Paren = 'Interval' + # note that *[2] is an mrow with X, ",", Y, so getting X or Y is a double index + name: ClearSpeak-intervals # audit-ignore # avoid overriding with default "intervals" name + variables: + - is_intervals_start_infinity: "*[1][self::m:minus and count(*)=1 and *[1][.='∞']]" + - T: "elemet" + - is_intervals_end_infinity: "*[2][.='∞'or (self::m:plus and count(*)=1 and *[1][.='∞'])]" + tag: [open-interval, open-closed-interval, closed-interval, closed-open-interval] + match: "." + replace: + - x: "*[1]" + - T: "től" + - x: "*[2]" + - T: "ig terjedő intervallum" + - pause: short + - test: + if: "not($is_intervals_start_infinity)" + then: + - test: + if: "starts-with(name(.), 'open')" + then: [T: "nem"] # phrase(the interval from a to b 'not' including b) + - T: "tartalmazza a(z)" # phrase(the interval from a to b not 'including' b) + - x: "*[1]" + - T: "elemet" + # logic to deal with [not] arg #1 + - test: + if: "not($is_intervals_start_infinity or $is_intervals_end_infinity)" + then_test: + - if: "name(.)='open-interval'" + then: [T: "vagy"] # phrase(the interval including a 'or' b ) + - else_if: "name(.)='closed-interval'" + then: [T: "és"] # phrase(the interval including a 'and' b) + else: [T: "de"] # phrase(the interval including a 'but' not b) + # some ugly logic dealing with connectives: or, but, but, and (cleaner to be part of next clause?) + - test: + if: "not($is_intervals_end_infinity)" + then: + - test: + # there is some asymmetry to the test because of the and/or/but logic above + if: "not( name(.)='open-interval' or name(.)='closed-interval' ) or $is_intervals_start_infinity" + then: + - test: + if: "name(.) = 'open-interval' or name(.) = 'closed-open-interval'" + then: [T: "nem"] # phrase(the interval 'not' including a) + - T: "tartalmazza" # phrase(the interval not 'including' a) + - T: "a(z)" + - x: "*[2]" + - T: "elemet" + # onto the [not] [including]... part + +- name: binomial-frac-vector + tag: matrix + match: + - "$ClearSpeak_Matrix = 'Combinatorics' and " + - "count(*[1]/*)=1 and count(*)=2" + replace: + - x: "*[1]/*[1]/*" # mtable/mtr/mtd + - T: "alatt a" # phrase(the binomial coefficient n 'choose' m) + - x: "*[2]/*[1]/*" + +- name: ClearSpeak-default + tag: [mtr, mlabeledtr] + match: "parent::m:matrix or parent::m:determinant" + variables: [NextLineIsContinuedRow: "following-sibling::*[1][contains(@data-intent-property, ':continued-row:')]"] + replace: + - pause: medium + - x: "count(preceding-sibling::*)+1" + - T: ". sor" # phrase(the first 'row' of a matrix) + - test: + if: ".[self::m:mlabeledtr]" + then: + - T: "címkéje:" # phrase(the line 'with label' first equation) + - x: "*[1]/*" + - pause: short + - pause: medium + - test: + if: ".[self::m:mlabeledtr]" + then: [x: "*[position()>1]"] + else: [x: "*"] + +- # handle both log and ln + name: ClearSpeak-log + tag: mi + match: ".='log' or .='ln'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity!='Terse' and not(IsNode(following-sibling::*[2],'simple'))" + then: [T: "a"] # phrase('the' square root of 25) + - test: + - if: ".='log'" + then: [T: "logaritmus"] + - else_if: "$ClearSpeak_Log = 'LnAsNaturalLog'" + then: [T: "természetes alapú logaritmus"] # phrase(the 'natural log' of x) + else: [T: "l n"] + +- name: ClearSpeak-multi-line # audit-ignore + tag: [piecewise, system-of-equations, lines] # these are ignored in favor of the ClearSpeak prefs + match: "." + variables: + # Wikipedia has some tables where all the entire first column is empty (e.g., https://en.wikipedia.org/wiki/List_of_trigonometric_identities) + - LineCount: "count(*[not(contains(@data-intent-property, ':continued-row:'))])" + - NextLineIsContinuedRow: "false()" # default value + - IsColumnSilent: true() + replace: + - test: + - if: "$ClearSpeak_MultiLineOverview = 'Auto'" + then: + - x: "$LineCount" + - test: + - if: "($ClearSpeak_MultiLineLabel = 'Auto' and self::m:piecewise) or $ClearSpeak_MultiLineLabel = 'Case'" + then: [T: "eset"] # phrase(this is the first 'case' of three cases) + - else_if: "$ClearSpeak_MultiLineLabel = 'Auto' or $ClearSpeak_MultiLineLabel = 'Line' or $ClearSpeak_MultiLineLabel = 'None'" # already dealt with Auto/Case + then: [T: "sor"] # phrase(this is the first 'line' of three lines) + - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" + then: [T: "feltétel"] # phrase(this is the first 'constraint' of three constraints) + - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" + then: [T: "egyenlet"] # phrase(this is the first 'equation' of three equations) + - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" + then: [T: "sor"] # phrase(this is the first 'row' of three rows) + - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" + then: [T: "lépés"] # phrase(this is the first 'step' of three steps) + # else 'None -- don't say anything' + - pause: short + - x: "*" + - pause: long + +- name: ClearSpeak-default-multiline + tag: [mtr, mlabeledtr] + match: "parent::m:piecewise or parent::m:system-of-equations or parent::m:lines" + variables: [NextLineIsContinuedRow: "following-sibling::*[1][contains(@data-intent-property, ':continued-row:')]"] + replace: + - test: + if: "not($LineCount=1 or $ClearSpeak_MultiLineLabel='None' or contains(@data-intent-property, ':continued-row:'))" + then: + - pause: medium + - x: "count(preceding-sibling::*[not(contains(@data-intent-property, ':continued-row:'))]) + 1" + - test: + - if: "($ClearSpeak_MultiLineLabel = 'Auto' and parent::m:piecewise) or $ClearSpeak_MultiLineLabel = 'Case'" + then: [T: ". eset"] # phrase(in this 'case' x is not equal to y) + - else_if: "$ClearSpeak_MultiLineLabel = 'Auto' or $ClearSpeak_MultiLineLabel = 'Line'" # already dealt with Auto/Case + then: [T: ". sor"] # phrase(the straight 'line' between x and y) + - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" + then: [T: ". feltétel"] # phrase(there is a 'constraint' on possible values) + - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" + then: [T: ". egyenlet"] # phrase(the 'equation' pi r squared gives the area of a circle) + - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" + then: [T: ". sor"] # phrase(the values on the top 'row' are relevant) + - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" + then: [T: ". lépés"] # phrase(this is a 'step' by step process) + # else 'None -- don't say anything' + - test: + if: "self::m:mlabeledtr" + then: + - T: "címkével:" # phrase(the diagram is complete 'with label') + - x: "*[1]/*" + - test: + - if: "$ClearSpeak_MultiLineLabel='None'" + then: [pause: xlong] # need a very long pause with no line labels + - else_if: "not(contains(@data-intent-property, ':continued-row:'))" + then: [pause: medium] + - test: + if: "self::m:mlabeledtr" + then: [x: "*[position()>1]"] + else: [x: "*"] + +- name: ClearSpeak_Functions_None + tag: mo + match: + - ".='⁡' and $ClearSpeak_Functions = 'None' and" + - "not(preceding-sibling::*[1][IsInDefinition(., 'TrigFunctionNames')])" # Functions=None does not apply to "trig" functions + replace: + test: + if: "$ClearSpeak_ImpliedTimes = 'None'" + then: [T: ""] + else: [T: "szorozva"] # phrase(5 'times' 3 equals 15) + +- name: no-times + tag: mo + match: + # Note: this rule is also part of the paren rule so that the parens speak + - ".='⁢' and $ClearSpeak_ImpliedTimes = 'None'" + replace: + - T: "" + +- name: ClearSpeak-times + tag: mo + match: + # say "times" when invisible times is followed by parens or a superscript that has a base with parens or "|"s + # if we aren't sure if it is times or not, don't say anything + - ".='⁢' and (not(@data-function-guess) or $ClearSpeak_Functions = 'None') and" + - "not(ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) and (" + - " $ClearSpeak_ImpliedTimes = 'MoreImpliedTimes'" + - " or " + - " following-sibling::*[1][" + - " IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|') or " + # most of these aren't mentioned in ClearSpeak spec, but are (I think) expected uses of "times" + - " self::m:matrix or self::m:determinant or self::m:binomial or" # followed by parens + - " self::m:square-root or self::m:msqrt or self::m:root or self::m:mroot or" + - " (self::m:msub or self::m:msubsup or" + - " ((self::m:msup or self::m:power) and not(IsNode(*[1], 'leaf') and *[2][self::m:mn and (.=2 or '.=3')]))) and " # followed by msup, etc. + - " (*[1][self::m:mrow[IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')] or " + - " self::m:matrix or self::m:determinant] or" # base has parens + - " not(IsNode(*[2], 'simple')) or " + - " (self::m:msubsup and not(IsNode(*[3], 'simple')))" + - " )" + - " ]" + # other possibility is the preceding element has parens (but not the following) + # this is not mentioned in the ClearSpeak rules or examples but seems like it should say "times". E.g, |x| y + - " or " + - " preceding-sibling::*[1][" + - " IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')]" # followed by parens + - " )" + replace: + - T: "szorozva" # phrase(5 'times' 3 equals 15) + +- name: no-say-parens + tag: mrow + match: + - "parent::*[not(self::m:msup) and not(self::m:msub) and not(self::m:msubsup) and not(self::m:power) and" + - " not(self::m:math) ] and " # rule out [x] standing alone + - "( IsBracketed(., '(', ')') or IsBracketed(., '[', ']') ) and " + - "not( $ClearSpeak_Functions = 'None' and " + - " (preceding-sibling::*[1][.='⁡'] or following-sibling::*[1][.='⁡']) ) and " + - "not( $ClearSpeak_ImpliedTimes = 'None' and " + - " (preceding-sibling::*[1][.='⁢'] or following-sibling::*[1][.='⁢']) ) and " + - "IsNode(*[2], 'simple') and" + - "not(preceding-sibling::*[1][.='\u2062' and @data-function-guess]) and" + - "not(ancestor-or-self::*[contains(@data-intent-property, ':literal:')])" + # missing clause: 'a positive fraction that is spoken as an ordinal + # (either by the Ordinal preference or by the default rules)' + replace: + - x: "*[2]" + +- include: "SharedRules/geometry.yaml" +- include: "SharedRules/linear-algebra.yaml" +- include: "SharedRules/general.yaml" +- include: "SharedRules/default.yaml" diff --git a/Rules/Languages/hu/unicode.yaml b/Rules/Languages/hu/unicode.yaml index 16561b733..caf1e9557 100644 --- a/Rules/Languages/hu/unicode.yaml +++ b/Rules/Languages/hu/unicode.yaml @@ -1,508 +1,508 @@ ---- - - "a-z": # audit-ignore - - test: - if: "$TTS='none'" - then: [T: "."] - else: [SPELL: "'.'"] - # Note to translators: - # most languages don't have two ways to pronounce 'a' -- if not need, remove the rules and change "B-Z" to "A-Z" - # some languages say the word for "uppercase" after the letter. Make sure to change that where appropriate by moving some code around - # Capital letters are a little tricky: users can pick their favorite word (something that was requested) and - # screen readers have options to use pitch changes or beeps instead of or in addition to say "cap" - # Also, if a user can see the screen, they probably don't need to hear "cap", but if they specified an override, they must want to hear the override. - # Some languages say the word for "uppercase" after the letter. Make sure to change that where appropriate by moving some code around - - "A-Z": # audit-ignore - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "nagy"] - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [SPELL: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] - - - "0-9": [T: "."] # (en: '.', DeepL translation) - - - " ": [T: " "] # 0x20 (DeepL translation) - - - "!": # 0x21 - - test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then_test: - if: "$Verbosity = 'Terse'" - then: [T: "felkiáltójel"] # 0x21 (DeepL translation) - else: [T: "felkiáltójel"] # 0x21 (en: 'exclamation point', DeepL translation) - else: [T: "faktoriális"] # 0x21 (en: 'factorial', DeepL translation) - - - "\"": [T: "idézőjel"] # 0x22 (en: 'quotation mark', DeepL translation) - - "#": [T: "kettőskereszt"] # 0x23 (DeepL translation) - - "$": [T: "dollár"] # 0x24 (en: 'dollars', DeepL translation) - - "%": [T: "százalék"] # 0x25 (en: 'percent', DeepL translation) - - "&": [T: "zárójel"] # 0x26 (en: 'ampersand', DeepL translation) - - "'": [T: "aposztróf"] # 0x27 (en: 'apostrophe', DeepL translation) - - "(": # 0x28 - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then_test: - if: "$Verbosity='Terse'" - then: [T: "nyitott zárójel"] # 0x28 (DeepL translation) - else: [T: "nyitott zárójel"] # 0x28 (en: 'open paren', DeepL translation) - else: [T: "bal zárójel"] # 0x28 (en: 'left paren', DeepL translation) - - ")": # 0x29 - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then_test: - if: "$Verbosity='Terse'" - then: [T: "zárt zárójel"] # 0x29 (en: 'close', DeepL translation) - else: [T: "zárt zárójel"] # 0x29 (en: 'close paren', DeepL translation) - else: [T: "jobb zárójel"] # 0x29 (en: 'right paren', DeepL translation) - - - "*": # 0x2a - test: - if: "parent::*[name(.)='msup' or name(.)='msubsup' or name(.)='skip-super']" - then: [T: "csillag"] # 0x2a (en: 'star', DeepL translation) - else: [T: "szorozva"] # 0x2a (DeepL translation) - - "+": [T: "plusz"] # 0x2b (en: 'plus', DeepL translation) - - ",": # 0x2c - # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent - # that this test is here and not with "…" is not ideal, but seems simplest - test: - if: - - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " - # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' - # speak "comma" when not adjacent to '…' - - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " - # except if expression starts with '…' - - "../*[1][.='…'] " - then: - - T: "vessző" # (en: 'comma', google translation) - - test: - if: "$Verbosity != Terse" - then: [pause: short] - # else silent - - - "-": [T: "mínusz"] # 0x2d (en: 'minus', DeepL translation) - - ".": # 0x2e - - test: - if: "parent::*[1][self::m:mn]" - then: [T: "pont"] # (en: 'point', DeepL translation) - else: [T: "pont"] # (en: 'dot', DeepL translation) - - "/": # 0x2f - - test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [T: "per"] # 0x2f (DeepL translation) - else: [T: "osztva"] # 0x2f (en: 'divided by', DeepL translation) - - - ":": [T: "kettőspont"] # 0x3a (en: 'colon', DeepL translation) - - ";": [T: "pontosvessző"] # 0x3b (en: 'semicolon', DeepL translation) - - "<": # 0x3c - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', DeepL translation) - - T: "kisebb, mint" # (en: 'less than', DeepL translation) - - "=": # 0x3d - - test: - if: "$Verbosity!='Terse'" - then: [T: "egyenlő"] # (en: 'is equal to', DeepL translation) - else: [T: "egyenlő"] # (en: 'equals', DeepL translation) - - - ">": # 0x3e - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', DeepL translation) - - T: "nagyobb, mint" # (en: 'greater than', DeepL translation) - - "?": [T: "kérdőjel"] # 0x3f (en: 'question mark', DeepL translation) - - "@": [T: "kukac"] # 0x40 (en: 'at sign', DeepL translation) - - "[": # 0x5b - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "nyitott zárójel"] # (en: 'open bracket', DeepL translation) - else: [T: "bal oldali zárójel"] # (en: 'left bracket', DeepL translation) - - "\\": [T: "bexles"] # 0x5c (en: 'back slash', DeepL translation) - - "]": # 0x5d - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "zárójel"] # (en: 'close bracket', DeepL translation) - else: [T: "jobb oldali zárójel"] # (en: 'right bracket', DeepL translation) - - "^": # 0x5e - - test: - if: "parent::m:modified-variable or parent::m:mover" - then: [T: "kalap"] # (en: 'hat', DeepL translation) - else: [T: "fölfelényíl"] # (DeepL translation) - - "_": [T: "aláhúzás"] # 0x5f (en: 'under bar', DeepL translation) - - "`": [T: "súlyozott"] # 0x60 (en: 'grave', DeepL translation) - - "{": # 0x7b - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "nyitott zárójel"] # (en: 'open brace', DeepL translation) - else: [T: "bal oldali zárójel"] # (en: 'left brace', DeepL translation) - - "|": # 0x7c - # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' - - with: - variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) - replace: - - test: - - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [T: "függőleges vonal"] # (en: 'vertical line', DeepL translation) - - else_if: "$SpeechStyle != 'ClearSpeak'" - then_test: - - if: "$DefaultToGiven" - then: [T: "adott"] # (en: 'given', DeepL translation) - - else_if: "preceding-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))] and - following-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))]" - then: [T: "osztja"] # (en: 'divides', DeepL translation) - else: [T: "függőleges vonal"] # (en: 'vertical line', DeepL translation) - - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" - then: [T: "függőleges vonal"] # (en: 'vertical line', DeepL translation) - - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" - then: [T: "olyan, hogy"] # (en: 'such that', DeepL translation) - - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" - then: [T: "adott"] # (en: 'given', DeepL translation) - - else: [T: "osztja"] # (en: 'divides', DeepL translation) - - - "}": # 0x7d - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "zárt zárójel"] # (en: 'close brace', DeepL translation) - else: [T: "jobb oldali zárójel"] # (en: 'right brace', DeepL translation) - - - "~": [T: "tilde"] # 0x7e (DeepL translation) - - " ": # 0xa0 - - test: - # could be mtext in mtd or mtext in an mrow that is a concatenation of mtd's. Is there a better solution? - if: "@data-empty-in-2D and not(ancestor::*[self::m:piecewise or self::m:system-of-equations or self::m:lines])" - then: [T: "üres"] # want to say something for fraction (etc) with empty child (en: 'empty', DeepL translation) - else: [T: ""] - - - "¬": [T: "logikai nem"] # 0xac (en: 'not', DeepL translation) - - "°": [T: "fok"] # 0xb0 (en: 'degrees', DeepL translation) - - "±": [T: "plusz vagy mínusz"] # 0xb1 (en: 'plus or minus', DeepL translation) - - "´": [T: "éles ékezet"] # 0xb4 (en: 'acute', DeepL translation) - - "·": # 0xB7 - - test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')] or not($SpeechStyle = 'ClearSpeak' and $ClearSpeak_MultSymbolDot = 'Auto')" - then: [T: "pont"] # (en: 'dot', DeepL translation) - else: [T: "szorozva"] # (DeepL translation) - - "×": # 0xd7 - - test: - if: "$SpeechStyle = 'ClearSpeak'" - then_test: - - if: "$ClearSpeak_MultSymbolX = 'Auto'" - then: [T: "szorozva"] # (DeepL translation) - - else_if: "$ClearSpeak_MultSymbolX = 'By'" - then: [T: "szorozva"] # (DeepL translation) - else: [T: "kereszt"] # (en: 'cross', DeepL translation) - else_test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [T: "kereszt"] # (en: 'cross', DeepL translation) - else: [T: "szorozva"] # (DeepL translation) - - - "÷": [T: "osztva"] # 0xf7 (en: 'divided by', DeepL translation) - - "̀": [T: "súlyos ékezet díszítés"] # 0x300 (en: 'grave accent embellishment', DeepL translation) - - "́": [T: "akut ékezet díszítés"] # 0x301 (en: 'acute accent embellishment', DeepL translation) - - "̂": [T: "cirkumflex ékezet díszítés"] # 0x302 (en: 'circumflex accent embellishment', DeepL translation) - - "̃": [T: "tilde"] # 0x303 (en: 'tilde embellishment', DeepL translation) - - "̄": [T: "makron"] # 0x304 (en: 'macron embellishment', DeepL translation) - - "̅": [T: "túlszárnyaló díszítés"] # 0x305 (en: 'overbar embellishment', DeepL translation) - - "̆": [T: "rövid"] # 0x306 (DeepL translation) - - "̇": [T: "pont a díszítés felett"] # 0x307 (en: 'dot above embellishment', DeepL translation) - - # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong - - "Α-Ω": - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "nagy"] # (en: 'cap', DeepL translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [SPELL: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] - - - "α": [T: "alfa"] # 0x3b1 (en: 'alpha', DeepL translation) - - "β": [T: "béta"] # 0x3b2 (en: 'beta', DeepL translation) - - "γ": [T: "gamma"] # 0x3b3 (DeepL translation) - - "δ": [T: "delta"] # 0x3b4 (DeepL translation) - - "ε": [T: "epszilon"] # 0x3b5 (DeepL translation) - - "ζ": [T: "zéta"] # 0x3b6 (en: 'zeta', DeepL translation) - - "η": [T: "éta"] # 0x3b7 (DeepL translation) - - "θ": [T: "théta"] # 0x3b8 (en: 'theta', DeepL translation) - - "ι": [T: "ióta"] # 0x3b9 (DeepL translation) - - "κ": [T: "kappa"] # 0x3ba (DeepL translation) - - "λ": [T: "lambda"] # 0x3bb (DeepL translation) - - "μ": [T: "mű"] # 0x3bc (DeepL translation) - - "ν": [T: "nű"] # 0x3bd (DeepL translation) - - "ξ": [T: "kszí"] # 0x3be (DeepL translation) - - "ο": [T: "omikron"] # 0x3bf (en: 'omicron', DeepL translation) - - "π": [T: "pí"] # 0x3c0 (DeepL translation) - - "ρ": [T: "ró"] # 0x3c1 (DeepL translation) - - "ς": [T: "szóvégi szigma"] # 0x3c2 (en: 'final sigma', DeepL translation) - - "σ": [T: "szigma"] # 0x3c3 (DeepL translation) - - "τ": [T: "tau"] # 0x3c4 (DeepL translation) - - "υ": [T: "üpszilon"] # 0x3c5 (DeepL translation) - - "φ": [T: "fí"] # 0x3c6 (DeepL translation) - - "χ": [T: "khí"] # 0x3c7 (DeepL translation) - - "ψ": [T: "pszí"] # 0x3c8 (DeepL translation) - - "ω": [T: "omega"] # 0x3c9 (DeepL translation) - - "ϕ": [T: "phi"] # 0x3d5 (DeepL translation) - - "ϖ": [T: "pí"] # 0x3d6 (DeepL translation) - - "ϵ": [T: "holdkóros epszilon"] # 0x3f5 (DeepL translation) - - "϶": [T: "félhold alakú tükrözött görög epszilon"] # 0x3f6 (en: 'reversed epsilon', DeepL translation) - - - "…": # 0x2026 - test: - if: - - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" - # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' - # speak '…' as 'and so on...' unless expr starts with '…' - - "../*[1][.='…']" - then: [T: "pont pont pont"] # (en: 'dot dot dot', DeepL translation) - else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' - if: "count(following-sibling::*) = 0" - then: [T: "és így tovább"] # (en: 'and so on', DeepL translation) - else: [T: "és így tovább egészen az alábbi értékig:"] # (en: 'and so on up to', DeepL translation) - - - "⁡": # 0x2061 - - test: - # skip saying "of" when Terse and a trig function, when it is a shape (does this happen?), or we are in :literal mode - if: "not( - ( $Verbosity='Terse' or ($SpeechStyle = 'ClearSpeak' and IsNode(following-sibling::*[1],'simple')) and - preceding-sibling::*[1][IfThenElse($SpeechStyle='ClearSpeak', - IsInDefinition(., 'ClearSpeakTrigFunctionNames'), - IsInDefinition(., 'TrigFunctionNames') )] - ) or - preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')] or - (@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) - )" - then: [T: ""] # (DeepL translation) - - "⁢": [T: ""] # 0x2062 - - "⁣": [T: "láthatatlan elválasztó"] # 0x2063 - - "⁤": [T: "és"] # 0x2064 (en: 'and', DeepL translation) - - - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" - - T: "duplán leütött" # (en: 'double-struck', DeepL translation) - - SPELL: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" - - - "℃": [T: "celsius fok"] # 0x2103 (en: 'degrees celsius', DeepL translation) - - "ℋℛℓ": # 0x210b - - T: "alsó index" # (DeepL translation) - - SPELL: "translate('.', 'ℋℛℓ', 'HRl')" - - "ℜ": # 0x211c - - T: "fraktur" # (DeepL translation) - - SPELL: "'R'" - - - "ⅆⅇⅈⅉ": # 0x2146-9 - - T: "duplán dőlt betűs" # (en: 'double-struck italic', DeepL translation) - - SPELL: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" - - - "←": [T: "balra nyíl"] # 0x2190 (en: 'left arrow', DeepL translation) - - "↑": [T: "felfelé nyíl"] # 0x2191 (en: 'up arrow', DeepL translation) - - "→": # 0x2192 - - test: - if: "ancestor::*[2][self::m:limit]" - then: [T: "megközelítések"] # (en: 'approaches', DeepL translation) - else: [T: "jobbra nyíl"] # (en: 'right arrow', DeepL translation) - - - "↓": [T: "lefelé nyíl"] # 0x2193 (en: 'down arrow', DeepL translation) - - "⇒": [T: "dupla jobbranyíl"] # 0x21d2 (en: 'right double arrow', DeepL translation) - - "∂": # 0x2202 - - test: - if: "$Verbosity='Terse'" - then: [T: "részleges"] # (en: 'partial', DeepL translation) - else: [T: "parciális derivált"] # (en: 'partial derivative', DeepL translation) - - "∆": # 0x2206 - - test: - if: "$Verbosity!='Terse'" - then: [T: "a"] # (en: 'the', DeepL translation) - - T: "növekménye" # (en: 'laplacian of', DeepL translation) - - "∈": # 0x2208 - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: - - test: - if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" - then: [T: ""] # (en: 'is', DeepL translation) - - T: "eleme ennek:" # (en: 'an element of', DeepL translation) - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [T: ""] # (DeepL translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "tagja"] # (en: 'member of', DeepL translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "eleme ennek:"] # (en: 'element of', DeepL translation) - - else: [T: "hozzátartozó eleme ennek:"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to', DeepL translation) - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "tagja az alábbi halmaznak:"] # (en: 'is a member of', DeepL translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "egy eleme ennek:"] # (en: 'is an element of', DeepL translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "benne van ebben:"] # (en: 'is in', DeepL translation) - - else: [T: "ebbe a halmazba tartozik:"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to', DeepL translation) - - "∉": # 0x2209 - # rule is identical to 0x2208 - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', DeepL translation) - - T: "nem eleme ennek:" # (en: 'not an element of', DeepL translation) - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "nincs benne ebben:"] # (en: 'not in', DeepL translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "nem tagja az alábbi halmaznak:"] # (en: 'not member of', DeepL translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "nem eleme ennek:"] # (en: 'not element of', DeepL translation) - - else: [T: "nem tartozik ebbe:"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to', DeepL translation) - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "nem tagja az alábbi halmaznak:"] # (en: 'is not a member of', DeepL translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "nem eleme ennek:"] # (en: 'is not an element of', DeepL translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "nincs benne az alábbi halmazban:"] # (en: 'is not in', DeepL translation) - - else: [T: "nem tartozik ebbe:"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to', DeepL translation) - - "∊": # 0x220a - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: - - test: - if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" - then: [T: "van"] # (en: 'is', DeepL translation) - - T: "egy eleme" # (en: 'an element of', DeepL translation) - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [T: ""] # (DeepL translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "tagja ennek:"] # (en: 'member of', DeepL translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "kisbetűs eleme ennek:"] # (en: 'element of', DeepL translation) - - else: [T: "hozzátartozó eleme ennek:"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to', DeepL translation) - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: "nem tagja az alábbi halmaznak:"] # (en: 'is a member of', DeepL translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "egy eleme ennek:"] # (en: 'is an element of', DeepL translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "benne van ebben:"] # (en: 'is in', DeepL translation) - - else: [T: "ebbe a halmazba tartozik:"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to', DeepL translation) - - "∐": [T: "diszjunkt unió"] # 0x2210 (en: 'co-product', DeepL translation) - - "√": # 0x221a - - test: - if: "$Verbosity!='Terse'" - then: [T: "a"] # (en: 'the', DeepL translation) - - T: "négyzetgyöke" # (en: 'square root of', DeepL translation) - - "∝": # 0x221d - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', DeepL translation) - - T: "arányos" # (en: 'proportional to', DeepL translation) - - "∥": # 0x2225 - - test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [T: "dupla függőleges vonal"] # (en: 'double vertical line', DeepL translation) - else: - - test: - if: "$Verbosity!='Terse'" - then: [T: "van"] # (en: 'is', DeepL translation) - - T: "párhuzamos" # (en: 'parallel to', DeepL translation) - - "∦": # 0x2226 - - test: - if: "$Verbosity!='Terse'" - then: [T: "van"] # (en: 'is', DeepL translation) - - T: "nem párhuzamos" # (en: 'not parallel to', DeepL translation) - - "∶": # 0x2236 - - test: - if: "$Verbosity!='Terse'" - then: [T: "van"] # (en: 'is', DeepL translation) - - T: "hogy" # (DeepL translation) - - "∾": # 0x223e - - test: - if: "$Verbosity!='Terse'" - then: [T: "van"] # (en: 'is', DeepL translation) - - T: "legpozitívabb" # (en: 'most positive', DeepL translation) - - "≠": # 0x2260 - - test: - if: "$Verbosity!='Terse'" - then: [T: "van"] # (en: 'is', DeepL translation) - - T: "nem egyenlő" # (en: 'not equal to', DeepL translation) - - "≡": # 0x2261 - - test: - if: "$Verbosity!='Terse'" - then: [T: "van"] # (en: 'is', DeepL translation) - - T: "azonos" # (en: 'identical to', DeepL translation) - - "≤": # 0x2264 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', DeepL translation) - - T: "kisebb vagy egyenlő" # (en: 'less than or equal to', DeepL translation) - - "≥": # 0x2265 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] # (en: 'is', DeepL translation) - - T: "nagyobb vagy egyenlő" # (en: 'greater than or equal to', DeepL translation) - - "⊂": # 0x2282 - - test: - if: "$Verbosity!='Terse'" - then: [T: "egy"] # (DeepL translation) - - T: "részhalmaza" # (en: 'subset of', DeepL translation) - - "⊃": # 0x2283 - - test: - if: "$Verbosity!='Terse'" - then: [T: "egy"] # (DeepL translation) - - T: "szuperhalmaza ennek:" # (en: 'superset of', DeepL translation) - - "⊄": # 0x2284 - - test: - if: "$Verbosity!='Terse'" - then: [T: "egy"] # (en: 'is', DeepL translation) - - T: "nem részhalmaza ennek:" # (en: 'not a subset of', DeepL translation) - - "⊅": # 0x2285 - - test: - if: "$Verbosity!='Terse'" - then: [T: "egy"] # (en: 'is', DeepL translation) - - T: "nem szuperhalmaza ennek:" # (DeepL translation) - - "⊆": # 0x2286 - - test: - if: "$Verbosity!='Terse'" - then: [T: "egy"] # (DeepL translation) - - T: "részhalmaza vagy egyenlő" # (en: 'subset of or equal to', DeepL translation) - - "⊇": # 0x2287 - - test: - if: "$Verbosity!='Terse'" - then: [T: "egy"] # (DeepL translation) - - T: "szuperhalmaza vagy egyenlő" # (en: 'superset of or equal to', DeepL translation) - - # --- restored short definitions that differ from unicode-full --- - - "⇒": [T: "dupla jobbranyíl"] # 0x21d2 (en: 'right double arrow', DeepL translation) - - "∐": [T: "diszjunkt unió"] # 0x2210 (en: 'co-product', DeepL translation) - +--- + - "a-z": # audit-ignore + - test: + if: "$TTS='none'" + then: [T: "."] + else: [SPELL: "'.'"] + # Note to translators: + # most languages don't have two ways to pronounce 'a' -- if not need, remove the rules and change "B-Z" to "A-Z" + # some languages say the word for "uppercase" after the letter. Make sure to change that where appropriate by moving some code around + # Capital letters are a little tricky: users can pick their favorite word (something that was requested) and + # screen readers have options to use pitch changes or beeps instead of or in addition to say "cap" + # Also, if a user can see the screen, they probably don't need to hear "cap", but if they specified an override, they must want to hear the override. + # Some languages say the word for "uppercase" after the letter. Make sure to change that where appropriate by moving some code around + - "A-Z": # audit-ignore + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "nagy"] + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [SPELL: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] + + - "0-9": [T: "."] # (en: '.', DeepL translation) + + - " ": [T: " "] # 0x20 (DeepL translation) + + - "!": # 0x21 + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then_test: + if: "$Verbosity = 'Terse'" + then: [T: "felkiáltójel"] # 0x21 (DeepL translation) + else: [T: "felkiáltójel"] # 0x21 (en: 'exclamation point', DeepL translation) + else: [T: "faktoriális"] # 0x21 (en: 'factorial', DeepL translation) + + - "\"": [T: "idézőjel"] # 0x22 (en: 'quotation mark', DeepL translation) + - "#": [T: "kettőskereszt"] # 0x23 (DeepL translation) + - "$": [T: "dollár"] # 0x24 (en: 'dollars', DeepL translation) + - "%": [T: "százalék"] # 0x25 (en: 'percent', DeepL translation) + - "&": [T: "zárójel"] # 0x26 (en: 'ampersand', DeepL translation) + - "'": [T: "aposztróf"] # 0x27 (en: 'apostrophe', DeepL translation) + - "(": # 0x28 + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [T: "nyitott zárójel"] # 0x28 (DeepL translation) + else: [T: "nyitott zárójel"] # 0x28 (en: 'open paren', DeepL translation) + else: [T: "bal zárójel"] # 0x28 (en: 'left paren', DeepL translation) + - ")": # 0x29 + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [T: "zárt zárójel"] # 0x29 (en: 'close', DeepL translation) + else: [T: "zárt zárójel"] # 0x29 (en: 'close paren', DeepL translation) + else: [T: "jobb zárójel"] # 0x29 (en: 'right paren', DeepL translation) + + - "*": # 0x2a + test: + if: "parent::*[name(.)='msup' or name(.)='msubsup' or name(.)='skip-super']" + then: [T: "csillag"] # 0x2a (en: 'star', DeepL translation) + else: [T: "szorozva"] # 0x2a (DeepL translation) + - "+": [T: "plusz"] # 0x2b (en: 'plus', DeepL translation) + - ",": # 0x2c + # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent + # that this test is here and not with "…" is not ideal, but seems simplest + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak "comma" when not adjacent to '…' + - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " + # except if expression starts with '…' + - "../*[1][.='…'] " + then: + - T: "vessző" # (en: 'comma', google translation) + - test: + if: "$Verbosity != Terse" + then: [pause: short] + # else silent + + - "-": [T: "mínusz"] # 0x2d (en: 'minus', DeepL translation) + - ".": # 0x2e + - test: + if: "parent::*[1][self::m:mn]" + then: [T: "pont"] # (en: 'point', DeepL translation) + else: [T: "pont"] # (en: 'dot', DeepL translation) + - "/": # 0x2f + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [T: "per"] # 0x2f (DeepL translation) + else: [T: "osztva"] # 0x2f (en: 'divided by', DeepL translation) + + - ":": [T: "kettőspont"] # 0x3a (en: 'colon', DeepL translation) + - ";": [T: "pontosvessző"] # 0x3b (en: 'semicolon', DeepL translation) + - "<": # 0x3c + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', DeepL translation) + - T: "kisebb, mint" # (en: 'less than', DeepL translation) + - "=": # 0x3d + - test: + if: "$Verbosity!='Terse'" + then: [T: "egyenlő"] # (en: 'is equal to', DeepL translation) + else: [T: "egyenlő"] # (en: 'equals', DeepL translation) + + - ">": # 0x3e + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', DeepL translation) + - T: "nagyobb, mint" # (en: 'greater than', DeepL translation) + - "?": [T: "kérdőjel"] # 0x3f (en: 'question mark', DeepL translation) + - "@": [T: "kukac"] # 0x40 (en: 'at sign', DeepL translation) + - "[": # 0x5b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "nyitott zárójel"] # (en: 'open bracket', DeepL translation) + else: [T: "bal oldali zárójel"] # (en: 'left bracket', DeepL translation) + - "\\": [T: "bexles"] # 0x5c (en: 'back slash', DeepL translation) + - "]": # 0x5d + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "zárójel"] # (en: 'close bracket', DeepL translation) + else: [T: "jobb oldali zárójel"] # (en: 'right bracket', DeepL translation) + - "^": # 0x5e + - test: + if: "parent::m:modified-variable or parent::m:mover" + then: [T: "kalap"] # (en: 'hat', DeepL translation) + else: [T: "fölfelényíl"] # (DeepL translation) + - "_": [T: "aláhúzás"] # 0x5f (en: 'under bar', DeepL translation) + - "`": [T: "súlyozott"] # 0x60 (en: 'grave', DeepL translation) + - "{": # 0x7b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "nyitott zárójel"] # (en: 'open brace', DeepL translation) + else: [T: "bal oldali zárójel"] # (en: 'left brace', DeepL translation) + - "|": # 0x7c + # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' + - with: + variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) + replace: + - test: + - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [T: "függőleges vonal"] # (en: 'vertical line', DeepL translation) + - else_if: "$SpeechStyle != 'ClearSpeak'" + then_test: + - if: "$DefaultToGiven" + then: [T: "adott"] # (en: 'given', DeepL translation) + - else_if: "preceding-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))] and + following-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))]" + then: [T: "osztja"] # (en: 'divides', DeepL translation) + else: [T: "függőleges vonal"] # (en: 'vertical line', DeepL translation) + - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" + then: [T: "függőleges vonal"] # (en: 'vertical line', DeepL translation) + - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" + then: [T: "olyan, hogy"] # (en: 'such that', DeepL translation) + - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" + then: [T: "adott"] # (en: 'given', DeepL translation) + - else: [T: "osztja"] # (en: 'divides', DeepL translation) + + - "}": # 0x7d + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "zárt zárójel"] # (en: 'close brace', DeepL translation) + else: [T: "jobb oldali zárójel"] # (en: 'right brace', DeepL translation) + + - "~": [T: "tilde"] # 0x7e (DeepL translation) + - " ": # 0xa0 + - test: + # could be mtext in mtd or mtext in an mrow that is a concatenation of mtd's. Is there a better solution? + if: "@data-empty-in-2D and not(ancestor::*[self::m:piecewise or self::m:system-of-equations or self::m:lines])" + then: [T: "üres"] # want to say something for fraction (etc) with empty child (en: 'empty', DeepL translation) + else: [T: ""] + + - "¬": [T: "logikai nem"] # 0xac (en: 'not', DeepL translation) + - "°": [T: "fok"] # 0xb0 (en: 'degrees', DeepL translation) + - "±": [T: "plusz vagy mínusz"] # 0xb1 (en: 'plus or minus', DeepL translation) + - "´": [T: "éles ékezet"] # 0xb4 (en: 'acute', DeepL translation) + - "·": # 0xB7 + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')] or not($SpeechStyle = 'ClearSpeak' and $ClearSpeak_MultSymbolDot = 'Auto')" + then: [T: "pont"] # (en: 'dot', DeepL translation) + else: [T: "szorozva"] # (DeepL translation) + - "×": # 0xd7 + - test: + if: "$SpeechStyle = 'ClearSpeak'" + then_test: + - if: "$ClearSpeak_MultSymbolX = 'Auto'" + then: [T: "szorozva"] # (DeepL translation) + - else_if: "$ClearSpeak_MultSymbolX = 'By'" + then: [T: "szorozva"] # (DeepL translation) + else: [T: "kereszt"] # (en: 'cross', DeepL translation) + else_test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [T: "kereszt"] # (en: 'cross', DeepL translation) + else: [T: "szorozva"] # (DeepL translation) + + - "÷": [T: "osztva"] # 0xf7 (en: 'divided by', DeepL translation) + - "̀": [T: "súlyos ékezet díszítés"] # 0x300 (en: 'grave accent embellishment', DeepL translation) + - "́": [T: "akut ékezet díszítés"] # 0x301 (en: 'acute accent embellishment', DeepL translation) + - "̂": [T: "cirkumflex ékezet díszítés"] # 0x302 (en: 'circumflex accent embellishment', DeepL translation) + - "̃": [T: "tilde"] # 0x303 (en: 'tilde embellishment', DeepL translation) + - "̄": [T: "makron"] # 0x304 (en: 'macron embellishment', DeepL translation) + - "̅": [T: "túlszárnyaló díszítés"] # 0x305 (en: 'overbar embellishment', DeepL translation) + - "̆": [T: "rövid"] # 0x306 (DeepL translation) + - "̇": [T: "pont a díszítés felett"] # 0x307 (en: 'dot above embellishment', DeepL translation) + + # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong + - "Α-Ω": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "nagy"] # (en: 'cap', DeepL translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [SPELL: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] + + - "α": [T: "alfa"] # 0x3b1 (en: 'alpha', DeepL translation) + - "β": [T: "béta"] # 0x3b2 (en: 'beta', DeepL translation) + - "γ": [T: "gamma"] # 0x3b3 (DeepL translation) + - "δ": [T: "delta"] # 0x3b4 (DeepL translation) + - "ε": [T: "epszilon"] # 0x3b5 (DeepL translation) + - "ζ": [T: "zéta"] # 0x3b6 (en: 'zeta', DeepL translation) + - "η": [T: "éta"] # 0x3b7 (DeepL translation) + - "θ": [T: "théta"] # 0x3b8 (en: 'theta', DeepL translation) + - "ι": [T: "ióta"] # 0x3b9 (DeepL translation) + - "κ": [T: "kappa"] # 0x3ba (DeepL translation) + - "λ": [T: "lambda"] # 0x3bb (DeepL translation) + - "μ": [T: "mű"] # 0x3bc (DeepL translation) + - "ν": [T: "nű"] # 0x3bd (DeepL translation) + - "ξ": [T: "kszí"] # 0x3be (DeepL translation) + - "ο": [T: "omikron"] # 0x3bf (en: 'omicron', DeepL translation) + - "π": [T: "pí"] # 0x3c0 (DeepL translation) + - "ρ": [T: "ró"] # 0x3c1 (DeepL translation) + - "ς": [T: "szóvégi szigma"] # 0x3c2 (en: 'final sigma', DeepL translation) + - "σ": [T: "szigma"] # 0x3c3 (DeepL translation) + - "τ": [T: "tau"] # 0x3c4 (DeepL translation) + - "υ": [T: "üpszilon"] # 0x3c5 (DeepL translation) + - "φ": [T: "fí"] # 0x3c6 (DeepL translation) + - "χ": [T: "khí"] # 0x3c7 (DeepL translation) + - "ψ": [T: "pszí"] # 0x3c8 (DeepL translation) + - "ω": [T: "omega"] # 0x3c9 (DeepL translation) + - "ϕ": [T: "phi"] # 0x3d5 (DeepL translation) + - "ϖ": [T: "pí"] # 0x3d6 (DeepL translation) + - "ϵ": [T: "holdkóros epszilon"] # 0x3f5 (DeepL translation) + - "϶": [T: "félhold alakú tükrözött görög epszilon"] # 0x3f6 (en: 'reversed epsilon', DeepL translation) + + - "…": # 0x2026 + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak '…' as 'and so on...' unless expr starts with '…' + - "../*[1][.='…']" + then: [T: "pont pont pont"] # (en: 'dot dot dot', DeepL translation) + else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' + if: "count(following-sibling::*) = 0" + then: [T: "és így tovább"] # (en: 'and so on', DeepL translation) + else: [T: "és így tovább egészen az alábbi értékig:"] # (en: 'and so on up to', DeepL translation) + + - "⁡": # 0x2061 + - test: + # skip saying "of" when Terse and a trig function, when it is a shape (does this happen?), or we are in :literal mode + if: "not( + ( $Verbosity='Terse' or ($SpeechStyle = 'ClearSpeak' and IsNode(following-sibling::*[1],'simple')) and + preceding-sibling::*[1][IfThenElse($SpeechStyle='ClearSpeak', + IsInDefinition(., 'ClearSpeakTrigFunctionNames'), + IsInDefinition(., 'TrigFunctionNames') )] + ) or + preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')] or + (@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) + )" + then: [T: ""] # (DeepL translation) + - "⁢": [T: ""] # 0x2062 + - "⁣": [T: "láthatatlan elválasztó"] # 0x2063 + - "⁤": [T: "és"] # 0x2064 (en: 'and', DeepL translation) + + - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" + - T: "duplán leütött" # (en: 'double-struck', DeepL translation) + - SPELL: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" + + - "℃": [T: "celsius fok"] # 0x2103 (en: 'degrees celsius', DeepL translation) + - "ℋℛℓ": # 0x210b + - T: "alsó index" # (DeepL translation) + - SPELL: "translate('.', 'ℋℛℓ', 'HRl')" + - "ℜ": # 0x211c + - T: "fraktur" # (DeepL translation) + - SPELL: "'R'" + + - "ⅆⅇⅈⅉ": # 0x2146-9 + - T: "duplán dőlt betűs" # (en: 'double-struck italic', DeepL translation) + - SPELL: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" + + - "←": [T: "balra nyíl"] # 0x2190 (en: 'left arrow', DeepL translation) + - "↑": [T: "felfelé nyíl"] # 0x2191 (en: 'up arrow', DeepL translation) + - "→": # 0x2192 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "megközelítések"] # (en: 'approaches', DeepL translation) + else: [T: "jobbra nyíl"] # (en: 'right arrow', DeepL translation) + + - "↓": [T: "lefelé nyíl"] # 0x2193 (en: 'down arrow', DeepL translation) + - "⇒": [T: "dupla jobbranyíl"] # 0x21d2 (en: 'right double arrow', DeepL translation) + - "∂": # 0x2202 + - test: + if: "$Verbosity='Terse'" + then: [T: "részleges"] # (en: 'partial', DeepL translation) + else: [T: "parciális derivált"] # (en: 'partial derivative', DeepL translation) + - "∆": # 0x2206 + - test: + if: "$Verbosity!='Terse'" + then: [T: "a"] # (en: 'the', DeepL translation) + - T: "növekménye" # (en: 'laplacian of', DeepL translation) + - "∈": # 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - test: + if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" + then: [T: ""] # (en: 'is', DeepL translation) + - T: "eleme ennek:" # (en: 'an element of', DeepL translation) + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: ""] # (DeepL translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "tagja"] # (en: 'member of', DeepL translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "eleme ennek:"] # (en: 'element of', DeepL translation) + - else: [T: "hozzátartozó eleme ennek:"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to', DeepL translation) + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "tagja az alábbi halmaznak:"] # (en: 'is a member of', DeepL translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "egy eleme ennek:"] # (en: 'is an element of', DeepL translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "benne van ebben:"] # (en: 'is in', DeepL translation) + - else: [T: "ebbe a halmazba tartozik:"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to', DeepL translation) + - "∉": # 0x2209 + # rule is identical to 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', DeepL translation) + - T: "nem eleme ennek:" # (en: 'not an element of', DeepL translation) + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "nincs benne ebben:"] # (en: 'not in', DeepL translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "nem tagja az alábbi halmaznak:"] # (en: 'not member of', DeepL translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "nem eleme ennek:"] # (en: 'not element of', DeepL translation) + - else: [T: "nem tartozik ebbe:"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to', DeepL translation) + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "nem tagja az alábbi halmaznak:"] # (en: 'is not a member of', DeepL translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "nem eleme ennek:"] # (en: 'is not an element of', DeepL translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "nincs benne az alábbi halmazban:"] # (en: 'is not in', DeepL translation) + - else: [T: "nem tartozik ebbe:"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to', DeepL translation) + - "∊": # 0x220a + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - test: + if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" + then: [T: "van"] # (en: 'is', DeepL translation) + - T: "egy eleme" # (en: 'an element of', DeepL translation) + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: ""] # (DeepL translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "tagja ennek:"] # (en: 'member of', DeepL translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "kisbetűs eleme ennek:"] # (en: 'element of', DeepL translation) + - else: [T: "hozzátartozó eleme ennek:"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to', DeepL translation) + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "nem tagja az alábbi halmaznak:"] # (en: 'is a member of', DeepL translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "egy eleme ennek:"] # (en: 'is an element of', DeepL translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "benne van ebben:"] # (en: 'is in', DeepL translation) + - else: [T: "ebbe a halmazba tartozik:"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to', DeepL translation) + - "∐": [T: "diszjunkt unió"] # 0x2210 (en: 'co-product', DeepL translation) + - "√": # 0x221a + - test: + if: "$Verbosity!='Terse'" + then: [T: "a"] # (en: 'the', DeepL translation) + - T: "négyzetgyöke" # (en: 'square root of', DeepL translation) + - "∝": # 0x221d + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', DeepL translation) + - T: "arányos" # (en: 'proportional to', DeepL translation) + - "∥": # 0x2225 + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [T: "dupla függőleges vonal"] # (en: 'double vertical line', DeepL translation) + else: + - test: + if: "$Verbosity!='Terse'" + then: [T: "van"] # (en: 'is', DeepL translation) + - T: "párhuzamos" # (en: 'parallel to', DeepL translation) + - "∦": # 0x2226 + - test: + if: "$Verbosity!='Terse'" + then: [T: "van"] # (en: 'is', DeepL translation) + - T: "nem párhuzamos" # (en: 'not parallel to', DeepL translation) + - "∶": # 0x2236 + - test: + if: "$Verbosity!='Terse'" + then: [T: "van"] # (en: 'is', DeepL translation) + - T: "hogy" # (DeepL translation) + - "∾": # 0x223e + - test: + if: "$Verbosity!='Terse'" + then: [T: "van"] # (en: 'is', DeepL translation) + - T: "legpozitívabb" # (en: 'most positive', DeepL translation) + - "≠": # 0x2260 + - test: + if: "$Verbosity!='Terse'" + then: [T: "van"] # (en: 'is', DeepL translation) + - T: "nem egyenlő" # (en: 'not equal to', DeepL translation) + - "≡": # 0x2261 + - test: + if: "$Verbosity!='Terse'" + then: [T: "van"] # (en: 'is', DeepL translation) + - T: "azonos" # (en: 'identical to', DeepL translation) + - "≤": # 0x2264 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', DeepL translation) + - T: "kisebb vagy egyenlő" # (en: 'less than or equal to', DeepL translation) + - "≥": # 0x2265 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is', DeepL translation) + - T: "nagyobb vagy egyenlő" # (en: 'greater than or equal to', DeepL translation) + - "⊂": # 0x2282 + - test: + if: "$Verbosity!='Terse'" + then: [T: "egy"] # (DeepL translation) + - T: "részhalmaza" # (en: 'subset of', DeepL translation) + - "⊃": # 0x2283 + - test: + if: "$Verbosity!='Terse'" + then: [T: "egy"] # (DeepL translation) + - T: "szuperhalmaza ennek:" # (en: 'superset of', DeepL translation) + - "⊄": # 0x2284 + - test: + if: "$Verbosity!='Terse'" + then: [T: "egy"] # (en: 'is', DeepL translation) + - T: "nem részhalmaza ennek:" # (en: 'not a subset of', DeepL translation) + - "⊅": # 0x2285 + - test: + if: "$Verbosity!='Terse'" + then: [T: "egy"] # (en: 'is', DeepL translation) + - T: "nem szuperhalmaza ennek:" # (DeepL translation) + - "⊆": # 0x2286 + - test: + if: "$Verbosity!='Terse'" + then: [T: "egy"] # (DeepL translation) + - T: "részhalmaza vagy egyenlő" # (en: 'subset of or equal to', DeepL translation) + - "⊇": # 0x2287 + - test: + if: "$Verbosity!='Terse'" + then: [T: "egy"] # (DeepL translation) + - T: "szuperhalmaza vagy egyenlő" # (en: 'superset of or equal to', DeepL translation) + + # --- restored short definitions that differ from unicode-full --- + - "⇒": [T: "dupla jobbranyíl"] # 0x21d2 (en: 'right double arrow', DeepL translation) + - "∐": [T: "diszjunkt unió"] # 0x2210 (en: 'co-product', DeepL translation) + diff --git a/Rules/Languages/nb/unicode-full.yaml b/Rules/Languages/nb/unicode-full.yaml index b4ad93780..b100bd8dc 100644 --- a/Rules/Languages/nb/unicode-full.yaml +++ b/Rules/Languages/nb/unicode-full.yaml @@ -1,3671 +1,3671 @@ ---- - -#C1 Controls and Latin-1 Supplement OK - - "¢": [T: "cent"] # 0xa2 (en: 'cents') - - "£": [T: "pund"] # 0xa3 (en: 'pounds') - - "¤": [T: "valutategn"] # 0xa4 (en: 'currency sign') - - "¥": [T: "yen"] # 0xa5 - - "¦": [T: "brutt vertikalstrek"] # 0xa6 (en: 'broken bar') - - "§": [T: "paragraf"] # 0xa7 (en: 'section') - - "¨": [T: "trema"] # 0xa8 (en: 'double dot', MathPlayer: 'trema', google: 'dubbel prick') - - "©": [T: "opphavsrett"] # 0xa9 (en: 'copyright') - - "ª": [T: "feminin ordenstallindikator"] # 0xaa (en: 'feminine ordinal indicator', MathPlayer: 'feminine ordinal indicator', google: 'feminin ordinär indikator') - - "«": [T: "venstre sitattegn"] # 0xab (en: 'left-pointing double angle quote mark') - - "¯": # 0xaf - - test: - if: "ancestor::m:modified-variable and preceding-sibling::*[1][self::m:mi]" - then: [T: "bar"] # (google translation) - else: [T: "strek"] # (en: 'line') - - "²": [T: "i andre"] # 0xb2 (en: 'two', MathPlayer: 'exponent två', google: 'två') - - "³": [T: "i tredje"] # 0xb3 (en: 'three', MathPlayer: 'exponent tre', google: 'tre') - - "µ": [T: "mikro"] # 0xb5 (en: 'micro') - - "¹": [T: "eksponent én"] # 0xb9 (en: 'one', google: 'ett') - - "º": [T: "maskulin ordenstallindikator"] # 0xba (en: 'masculine ordinal indicator', MathPlayer: 'masculine ordinal indicator', google: 'maskulina ordinära indikatorer') - - "¡": [T: "omvendt utropstegn"] # 0xa1 - - "¶": [T: "paragraftegn"] # 0xb6 - - "¿": [T: "omvendt spørsmålstegn"] # 0xbf - #------------------------------------------------------------------------------------------------------- - # SWEDISH: The Swedish character translations are based on the placement and appearance of the characters rather than their function, as function might be context-dependent. Placement above is used as the baseline, and low characters are translated as "låg(t)" (eng "low"). In most cases, no difference has been made in the translation between non-combining, modifier (Spacing Modifier Letters), and combining/embellishment characters. However, in the case of alphabetical letters and punctuation marks as modifier characters (such as modifier small h or comma embellishment), the construction "med ...( efter)" (eng "with ...( placed after it)") is used to prevent any possible ambiguity. - # Norwegian: Same as Swedish -#Spacing Modifier Letters -#Latin superscript modifier letters OK - - "ʰ": [T: "med liten h etter"] # 0x2b0 (en: 'modifier small h', google translation) - - "ʱ": [T: "med liten h med krok etter"] # 0x2b1 (en: 'modifier small h with hook', google translation) - - "ʲ": [T: "med liten j etter"] # 0x2b2 (en: 'modifier small j', google translation) - - "ʳ": [T: "med liten r etter"] # 0x2b3 (en: 'modifier small r', google translation) - - "ʴ": [T: "med liten rotert r etter"] # 0x2b4 (en: 'modifier small turned r', google translation) - - "ʵ": [T: "med liten rotert r med krok etter"] # 0x2b5 (en: 'modifier small turned r with hook', google translation) - - "ʶ": # 0x2b6 - - T: "med liten rotert" # (en: 'modifier small inverted', google translation) - - SPELL: "translate('R', 'R', 'R')" - - "ʷ": [T: "med liten w etter"] # 0x2b7 (en: 'modifier small w', google translation) - - "ʸ": [T: "med liten y etter"] # 0x2b8 (en: 'modifier small y', google translation) - #-------------------------- - #Miscellaneous phonetic modifiers OK - - "ʹ": [T: "primtegn"] # 0x2b9 (en: 'modifier prime', google: 'modifier prime') - - "ʺ": [T: "dobbelt primtegn"] # 0x2ba (en: 'modifier double prime', google: 'modifier double prime') - - "ʻ": [T: "rotert komma"] # 0x2bb (en: 'modifier turned comma', google translation) - - "ʼ": [T: "apostrof"] # 0x2bc (google translation) - - "ʽ": [T: "speilvendt komma"] # 0x2bd (en: 'modifier reversed comma', google translation) - - "ʾ": [T: "høyrevendt halv ring"] # 0x2be (en: 'modifier right half ring', google: 'modifierare höger halva ring') - - "ʿ": [T: "venstrevendt halv ring"] # 0x2bf (en: 'modifier left half ring', google: 'modifierare lämnade halva ringen') - - "ˀ": [T: "glottal plosiv"] # 0x2c0 (google translation) - - "ˁ": [T: "speilvendt glottal plosiv"] # 0x2c1 (en: 'modifier reversed glottal stop', google translation) - - "˂": [T: "venstrevendt pilspiss"] # 0x2c2 (en: 'modifier left arrowhead', google translation) - - "˃": [T: "høyrevendt pilspiss"] # 0x2c3 (en: 'modifier right arrowhead', google translation) - - "˄": [T: "oppovervendt pilspiss"] # 0x2c4 (en: 'modifier up arrowhead', google translation) - - "˅": [T: "nedovervendt pilspiss"] # 0x2c5 (en: 'modifier down arrowhead', google translation) - - "ˆ": [T: "cirkumfleks"] # 0x2c6 (en: 'modifier circumflex accent', google: 'modifiercirumflex accent') - - "ˇ": [T: "hake"] # 0x2c7 (en: 'caron', google: 'caron') - - "ˈ": [T: "vertikal strek"] # 0x2c8 (en: 'modifier vertical line', google translation) - - "ˉ": [T: "makron"] # 0x2c9 (google translation) - - "ˊ": [T: "akutt aksent"] # 0x2ca (en: 'modifier acute accent', google translation) - - "ˋ": [T: "grav aksent"] # 0x2cb (en: 'modifier grave accent', google translation) - - "ˌ": [T: "lav vertikal strek"] # 0x2cc (en: 'modifier low vertical line', google translation) - - "ˍ": [T: "lav makron"] # 0x2cd (google translation) - - "ˎ": [T: "lav grav aksent"] # 0x2ce (en: 'modifier low grave accent', google translation) - - "ˏ": [T: "lav akutt aksent"] # 0x2cf (en: 'modifier low acute accent', google translation) - - "ː": [T: "kolon lengdetegn"] # 0x2d0 (en: 'modifier triangular colon', google translation) - - "ˑ": [T: "halvt kolon lengdetegn"] # 0x2d1 (en: 'modifier half triangular colon', google translation) - - "˒": [T: "lav høyrevendt halv ring"] # 0x2d2 (en: 'modifier centered right half ring', google translation) - - "˓": [T: "lav venstrevendt halv ring"] # 0x2d3 (en: 'modifier centered left half ring', google translation) - - "˔": [T: "lavt oppovervendt dreiekors"] # 0x2d4 (en: 'modifier up tadck', google translation) - - "˕": [T: "lavt nedovervendt dreiekors"] # 0x2d5 (en: 'modifier down tack', google translation) - - "˖": [T: "lavt plusstegn"] # 0x2d6 (google translation) - - "˗": [T: "lavt minustegn"] # 0x2d7 (en: 'modifier minus sign', google translation) - #---------------------------- - #Spacing clones of diacritics OK - - "˘": [T: "breve"] # 0x2d8 (en: 'breve') - - "˙": [T: "prikk"] # 0x2d9 (en: 'dot') - - "˚": [T: "ring"] # 0x2da (en: 'ring above') - - "˛": [T: "kvist"] # 0x2db (en: 'ogonek') - - "˜": [T: "liten tilde"] # 0x2dc (en: 'small tilde') - - "˝": [T: "dobbel akutt aksent"] # 0x2dd (en: 'double acute accent') - #----------------------------- - #Additions based on 1989 IPA OK - - "˞": [T: "rotisk hake"] # 0x2de (google translation) - - "˟": [T: "kryssaksent"] # 0x2df (en: 'modifier cross accent', google translation) - - "ˠ": [T: "med liten gamma etter"] # 0x2e0 (en: 'modifier small gamma', google translation) - - "ˡ": [T: "med liten l etter"] # 0x2e1 (en: 'modifier small l', google translation) - - "ˢ": [T: "med liten s etter"] # 0x2e2 (google translation) - - "ˣ": [T: "med liten x etter"] # 0x2e3 (en: 'modifier small x', google translation) - - "ˤ": [T: "liten speilvendt glottal plosiv"] # 0x2e4 (google translation) - #----------------------------- - #Tone letters OK - - "˥": [T: "ekstra høyt tonetegn"] # 0x2e5 (en: 'modifier extra-high tone bar', google translation) - - "˦": [T: "høyt tonetegn"] # 0x2e6 (google translation) - - "˧": [T: "mellom-tonetegn"] # 0x2e7 (en: 'modifier mid tone bar', google translation) - - "˨": [T: "lavt tonetegn"] # 0x2e8 (en: 'modifier low tone bar', google translation) - - "˩": [T: "ekstra lavt tonetegn"] # 0x2e9 (en: 'modifier extra-low tone bar', google translation) - #----------------------------- - #Extended Bopomofo tone marks OK - - "˪": [T: "mørkt fallende tonetegn"] # 0x2ea (en: 'modifier yin departing tone mark', google translation) - - "˫": [T: "lyst fallende tonetegn"] # 0x2eb (en: 'modifier yang departing tone mark', google translation) - #--------------------------- - #IPA modifiers OK - - "ˬ": [T: "lavt tonende tegn"] # 0x2ec (en: 'modifier voicing', google translation) - - "˭": [T: "ikke aspirert tegn"] # 0x2ed (en: 'modifier unaspirated', google translation) - #------------------------- - #Other modifier letter OK - - "ˮ": [T: "dobbel apostrof"] # 0x2ee (en: 'modifier double apostrophe', google translation) - #---------------------------- - #UPA modifiers OK - - "˯": [T: "lav nedoverpekende pilspiss"] # 0x2ef (en: 'modifier low down arrowhead', google translation) - - "˰": [T: "lav oppoverpekende pilspiss"] # 0x2f0 (google translation) - - "˱": [T: "lav venstrepekende pilspiss"] # 0x2f1 (en: 'modifier low left arrowhead', google translation) - - "˲": [T: "lav høyrepekende pilspiss"] # 0x2f2 (en: 'modifier low right arrowhead', google translation) - - "˳": [T: "lav ring"] # 0x2f3 (en: 'modifier low ring', google translation) - - "˴": [T: "lav grav aksent"] # 0x2f4 (google translation) - - "˵": [T: "lav dobbel grav aksent"] # 0x2f5 (en: 'modifier middle double grave accent', google translation) - - "˶": [T: "lav dobbel akutt aksent"] # 0x2f6 (en: 'modifier middle double acute accent', google translation) - - "˷": [T: "lav tilde"] # 0x2f7 (en: 'modifier low tilde', google translation) - - "˸": [T: "hevet kolon"] # 0x2f8 (en: 'modifier raised colon', google translation) - - "˹": [T: "start høy tone"] # 0x2f9 (en: 'modifier begin high tone', google translation) - - "˺": [T: "slutt høy tone"] # 0x2fa (en: 'modifier end high tone', google translation) - - "˻": [T: "start lav tone"] # 0x2fb (en: 'modifier begin low tone', google translation) - - "˼": [T: "slutt lav tone"] # 0x2fc (en: 'modifier end low tone', google translation) - - "˽": [T: "lav hylle"] # 0x2fd (en: 'modifier shelf', google translation) - - "˾": [T: "lav åpen hylle"] # 0x2fe (en: 'modifier open shelf', google translation) - - "˿": [T: "lav venstrepil"] # 0x2ff (en: 'modifier low left arrow', google translation) - #--------------------------------------------------------------------------------------------------------- - #Combining Diacritical Marks - #Ordinary diacritics OK - - "̈": [T: "trema"] # 0x308 (en: 'diaeresis embellishment', google: 'diaeresis utsmyckning') - - "̉": [T: "krok"] # 0x309 (en: 'hook above embellishment', google translation) - - "̊": [T: "ring"] # 0x30a (en: 'ring above embellishment', google: 'ring över utsmyckning') - - "̋": [T: "dobbel akutt aksent"] # 0x30b (en: 'double acute accent embellishment', google translation) - - "̌": [T: "hake"] # 0x30c (en: 'check', google: 'kolla upp') - - "̍": [T: "vertikal linje"] # 0x30d (en: 'vertical line above embellishment', google translation) - - "̎": [T: "dobbel vertikal linje"] # 0x30e (en: 'double vertical line above embellishment', google translation) - - "̏": [T: "dobbel grav aksent"] # 0x30f (en: 'double grave accent embellishment', google translation) - - "̐": [T: "Chandrabindu"] # 0x310 (en: 'candrabindu embellishment', google translation) - - "̑": [T: "omvendt breve"] # 0x311 (en: 'inverted breve embellishment', google: 'inverterad breve -utsmyckning') - - "̒": [T: "med rotert komma"] # 0x312 (en: 'turned comma above embellishment', google translation) - - "̓": [T: "med komma"] # 0x313 (en: 'comma above embellishment', google translation) - - "̔": [T: "med omvendt komma"] # 0x314 (en: 'reversed comma above embellishment', google translation) - - "̕": [T: "med høyrestilt komma"] # 0x315 (en: 'comma above right embellishment', google translation) - - "̖": [T: "lav grav aksent"] # 0x316 (en: 'grave accent below embellishment', google translation) - - "̗": [T: "lav akutt aksent"] # 0x317 (en: 'acute accent below embellishment', google translation) - - "̘": [T: "lavt venstre dreiekors"] # 0x318 (en: 'left tack below embellishment', google translation) - - "̙": [T: "lavt høyre dreiekors"] # 0x319 (en: 'right tack below embellishment', google translation) - - "̚": [T: "venstrevendt vinkeltegn"] # 0x31a (en: 'left angle above embellishment', google translation) - - "̛": [T: "horn"] # 0x31b (en: 'horn embellishment', google translation) - - "̜": [T: "lav venstrevendt halvring"] # 0x31c (en: 'left half ring below embellishment', google translation) - - "̝": [T: "lavt oppoverrotert dreiekors"] # 0x31d (en: 'up tack below embellishment', google translation) - - "̞": [T: "lavt nedoverrotert dreiekors"] # 0x31e (en: 'down tack below embellishment', google translation) - - "̟": [T: "lav pluss"] # 0x31f (en: 'plus sign below embellishment', google translation) - - "̠": [T: "lav minus"] # 0x320 (en: 'minus sign below embellishment', google translation) - - "̡": [T: "palatal krok"] # 0x321 (en: 'palatalized hook below embellishment', google translation) - - "̢": [T: "retrofleks krok"] # 0x322 (en: 'retroflex hook below embellishment', google translation) - - "̣": [T: "lav prikk"] # 0x323 (google: 'prick under utsmyckningen') - - "̤": [T: "lav trema"] # 0x324 (en: 'diaeresis below embellishment', google: 'diaeres under utsmyckning') - - "̥": [T: "lav ring"] # 0x325 (en: 'ring below embellishment', google translation) - - "̦": [T: "lavt komma"] # 0x326 (en: 'comma below embellishment', google translation) - - "̧": [T: "lav cédille"] # 0x327 (en: 'cedilla embellishment', google: 'cedilla -utsmyckning') - - "̨": [T: "lav kvist"] # 0x328 (en: 'ogonek embellishment', google translation) - - "̩": [T: "lav vertikal strek"] # 0x329 (en: 'vertical line below embellishment', google translation) - - "̪": [T: "lav bro"] # 0x32a (en: 'bridge below embellishment', google translation) - - "̫": [T: "lav omvendt dobbel bue"] # 0x32b (en: 'inverted double arch below embellishment', google translation) - - "̬": [T: "lav hake"] # 0x32c (en: 'caron below embellishment', google translation) - - "̭": [T: "lav omvendt cirkumfleks"] # 0x32d (en: 'circumflex accent below embellishment', google translation) - - "̮": [T: "lav breve"] # 0x32e (en: 'breve below embellishment', google: 'breve under utsmyckning') - - "̯": [T: "lav omvendt breve"] # 0x32f (en: 'inverted breve below embellishment', google translation) - - "̰": [T: "lav tilde"] # 0x330 (en: 'tilde below embellishment', google: 'tilde under utsmyckning') - - "̱": [T: "lav makron"] # 0x331 (en: 'macron below embellishment', google: 'macron under utsmyckning') - - "̲": [T: "lav strek"] # 0x332 (en: 'low line embellishment', google: 'låg linje utsmyckning') - - "̳": [T: "lav dobbeltstrek"] # 0x333 (en: 'double low line embellishment', google translation) - #------------------------------------------ - #Overstruck diacritics OK - - "̴": [T: "tilde i midten"] # 0x334 (en: 'tilde overlay embellishment', google translation) - - "̵": [T: "strek i midten"] # 0x335 (en: 'short stroke overlay embellishment', google translation) - - "̶": [T: "lang strek i midten"] # 0x336 (en: 'long stroke overlay embellishment', google translation) - - "̷": [T: "med kort skråstrek"] # 0x337 (en: 'short solidus overlay embellishment', google translation) - - "̸": [T: "med lang skråstrek"] # 0x338 (en: 'long solidus overlay embellishment', google: 'long solidus overlay embelling') - #------------------------------------ - #Miscellaneous additions OK - - "̹": [T: "lav høyrevendt halvring"] # 0x339 (en: 'right half ring below embellishment', google translation) - - "̺": [T: "lav omvendt bro"] # 0x33a (en: 'inverted bridge below embellishment', google translation) - - "̻": [T: "lavt kvadrat"] # 0x33b (en: 'square below embellishment', google translation) - - "̼": [T: "lavt måketegn"] # 0x33c (en: 'seagull below embellishment', google translation) - - "̽": [T: "med x over"] # 0x33d (en: 'x above embellishment', google translation) - - "̾": [T: "vertikal tilde"] # 0x33e (en: 'vertical tilde embellishment', google translation) - - "̿": [T: "dobbel strek"] # 0x33f (en: 'double overline embellishment', google translation) - - "̀": [T: "grav tone"] # 0x340 (en: 'grave tone mark embellishment', google translation) - - "́": [T: "akutt tone"] # 0x341 (en: 'acute tone mark embellishment', google translation) - - "͆": [T: "bro"] # 0x346 -#---------------------------------------------------------------------------------------------------------------- -# Greek and Coptic OK - - "ΪΫϏ": # 0x3aa, 0x3ab, 0x3cf - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "stor"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [SPELL: "translate('.', 'ΪΫϏ', 'ιυϗ')"] - - T: "med dialytika" # (en: 'with dialytika', google translation) - - "ϊ": [T: "iota med dialytika"] # 0x3ca (en: 'iota with dialytika', google translation) - - "ϋ": [T: "ypsilon med dialytika"] # 0x3cb (en: 'upsilon with dialytika', google translation) - - "ό": [T: "omikron med tonos"] # 0x3cc (en: 'omicron with tonos', google translation) - - "ύ": [T: "ypsilon med tonos"] # 0x3cd (en: 'upsilon with tonos', google translation) - - "ώ": [T: "omega med tonos"] # 0x3ce (en: 'omega with tonos', google translation) - - "ϐ": [T: "beta"] # 0x3d0 (en: 'beta') - - "ϑ": [T: "theta"] # 0x3d1 (en: 'theta', google: 'theta') - - "ϒ": [T: "ypsilon med krok"] # 0x3d2 (en: 'upsilon with hook', google: 'upsilon med krok') - - "ϓ": [T: "ypsilon med akutt aksent og krok"] # 0x3d3 (en: 'upsilon with acute and hook', google translation) - - "ϔ": [T: "ypsilon med trema og krok"] # 0x3d4 (en: 'upsilon with diaeresis and hook', google translation) - - "ϗ": [T: "kai"] # 0x3d7 (en: 'kai') - - "Ϙ": [T: "stor arkaisk koppa"] # 0x3d8 - - "ϙ": [T: "arkaisk koppa"] # 0x3d9 - - "А-Я": # 0x410 - 0x42f - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "stor"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [SPELL: "translate('.', 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ', 'абвгдежзийклмнопрстуфхцчшщъыьэюя')", pause: short] - - "а": [T: "a"] # 0x430 (google: 'а') - - "б": [T: "be"] # 0x431 (google: 'vara') - - "в": [T: "ve"] # 0x432 - - "г": [T: "ge"] # 0x433 - - "д": [T: "de"] # 0x434 - - "е": [T: "je"] # 0x435 (google: 'dvs') - - "ж": [T: "zhe"] # 0x436 - - "з": [T: "ze"] # 0x437 - - "и": [T: "i"] # 0x438 (google: 'и') - - "й": [T: "kort i"] # 0x439 (en: 'short i') - - "к": [T: "ka"] # 0x43a - - "л": [T: "el"] # 0x43b - - "м": [T: "em"] # 0x43c - - "н": [T: "en"] # 0x43d - - "о": [T: "o"] # 0x43e (google: 'о') - - "п": [T: "pe"] # 0x43f - - "р": [T: "er"] # 0x440 - - "с": [T: "es"] # 0x441 - - "т": [T: "te"] # 0x442 - - "у": [T: "u"] # 0x443 (google: 'у') - - "ф": [T: "ef"] # 0x444 - - "х": [T: "ha"] # 0x445 - - "ц": [T: "tse"] # 0x446 - - "ч": [T: "tsje"] # 0x447 - - "ш": [T: "sja"] # 0x448 - - "щ": [T: "sjtja"] # 0x449 - - "ъ": [T: "hardt tegn"] # 0x44a (en: 'hard sign') - - "ы": [T: "jeru"] # 0x44b - - "ь": [T: "mykt tegn"] # 0x44c (en: 'soft sign', google: 'mjukt skylt') - - "э": [T: "e"] # 0x44d (google: 'э') - - "ю": [T: "ju"] # 0x44e - - "я": [T: "ja"] # 0x44f - - "؆": [T: "arabisk-indisk kubikkrot"] # 0x606 - - "؇": [T: "arabisk-indisk fjerderot"] # 0x607 - - "؈": [T: "arabisk stråle"] # 0x608 - #----------------------------------------------------------------------------------------------------------- - #General punctuation OK - - "‐": [T: "bindestrek"] # 0x2010 (en: 'hyphen') - - "‑": [T: "bindestrek"] # 0x2011 (en: 'hyphen', google: 'bindestrek') - - "‒": [T: "tankestrek"] # 0x2012 (en: 'figure dash', google: 'figurstreck') - - "–": [T: "tankestrek"] # 0x2013 (en: 'en dash') - - "—": [T: "lang tankestrek"] # 0x2014 (en: 'em dash') - - "―": [T: "horisontal strek"] # 0x2015 (en: 'horizontal bar') - - "‖": [T: "dobbel loddrett strek"] # 0x2016 (en: 'double vertical line') - - "†": [T: "kors"] # 0x2020 (en: 'dagger') - - "‡": [T: "dobbelt kors"] # 0x2021 (en: 'double dagger') - - - " - ": [T: " "] # 0x2000 - 0x2007 - - - "•": # 0x2022 - - test: - if: "@data-chem-formula-op" - then: [T: "ganger"] # (en: 'dot', google translation) - else: [T: "listeelement"] # (en: 'bullet') - - - "‰": [T: "promille"] # 0x2030 (en: 'per mille', MathPlayer: 'promilletecken') - - "‱": [T: "per titusen"] # 0x2031 (en: 'per ten thousand') - - "′": [T: "primtegn"] # 0x2032 (en: 'prime') - - "″": [T: "dobbelt primtegn"] # 0x2033 (en: 'double prime') - - "‴": [T: "trippelt primtegn"] # 0x2034 (en: 'triple prime') - - "‵": [T: "omvendt primtegn"] # 0x2035 (en: 'reversed prime') - - "‶": [T: "omvendt dobbelt primtegn"] # 0x2036 (en: 'reversed double prime') - - "‷": [T: "omvendt trippelt primtegn"] # 0x2037 (en: 'reversed triple prime', google: 'omvänd trippelprime') - - "‸": [T: "innsettingstegn"] # 0x2038 (en: 'to the', google: 'till') - - "‹": [T: "venstrepekende vinkel-sitattegn"] # 0x2039 (en: 'single left pointing angle quote mark') - - "›": [T: "høyrepekende vinkel-sitattegn"] # 0x203a (en: 'single right pointing angle quote mark') - - "‼": # 0x203c - - test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [T: "dobbelt utropstegn"] # 0x203c - else: [T: "dobbel fakultet"] # 0x203c - - "⁄": # 0x2044 - - test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [T: "stor skråstrek"] # 0x203c - else: [T: "delt på"] # 0x203c - - "⁅": [T: "venstre piggparentes"] # 0x2045 (en: 'left square bracket with quill', google: 'vänster fyrkantig konsol med quill') - - "⁆": [T: "høyre piggparentes"] # 0x2046 (en: 'right square bracket with quill', google: 'höger fyrkantig konsol med quill') - - "※": [T: "referansetegn"] # 0x203b - - "‿": [T: "underbinding"] # 0x203F - - "⁀": [T: "bindetegn"] # 0x2040 - - "⁎": [T: "lav asterisk"] # 0x204e - - "⁏": [T: "omvendt semikolon"] # 0x204f - - "⁐": [T: "sammentrekksmerke"] # 0x2050 - - "⁑": [T: "to vertikale asterisk"] # 0x2051 - - "⁒": [T: "kommersielt minustegn"] # 0x2052 - - "⁗": [T: "firedobbelt primtegn"] # 0x2057 (en: 'quadruple prime', MathPlayer: 'quadruple prime', google: 'fyrdubbla prime') - - "⁠": [T: ""] # 0x2060 - #------------------------------------------------------------------------------------------------------------------------- - # Superscripts and subscripts OK - - "⁰": [T: "opphøyd i null"] # 0x2070 (en: 'to the zeroth power', google translation) - - "ⁱ": [T: "opphøyd i i"] # 0x2071 (en: 'to the eihth power', google: 'till eihth power') - - "⁴": [T: "opphøyd i fire"] # 0x2074 (en: 'to the fourth power', google translation) - - "⁵": [T: "opphøyd i fem"] # 0x2075 (en: 'to the fifth power', google translation) - - "⁶": [T: "opphøyd i seks"] # 0x2076 (en: 'to the sixth power', google translation) - - "⁷": [T: "opphøyd i sju"] # 0x2077 (en: 'to the seventh power', google translation) - - "⁸": [T: "opphøyd i åtte"] # 0x2078 (en: 'to the eighth power', google translation) - - "⁹": [T: "opphøyd i ni"] # 0x2079 (en: 'to the ninth power', google translation) - - "⁺": [T: "hevet pluss"] # 0x207a (en: 'superscript plus sign', google: 'superscript plus -skylt') - - "⁻": [T: "hevet minus"] # 0x207b (en: 'superscript minus', google: 'superscript minus') - - "⁼": [T: "hevet likhetstegn"] # 0x207c (en: 'superscript equals sign', google: 'superscript är lika med tecken') - - "⁽": [T: "hevet venstreparentes"] # 0x207d (en: 'superscript left parenthesis', google: 'superscript lämnade parentesen') - - "⁾": [T: "hevet høyreparentes"] # 0x207e (en: 'superscript right parenthesis', google: 'superscript höger parentes') - - "ⁿ": [T: "opphøyd i n"] # 0x207f (en: 'to the ennth power', google: 'till den ena kraften') - - "₀": [T: "senket null"] # 0x2080 (en: 'sub zero', google translation) - - "₁": [T: "senket én"] # 0x2081 (en: 'sub one', google translation) - - "₂": [T: "senket to"] # 0x2082 (en: 'sub two', google translation) - - "₃": [T: "senket tre"] # 0x2083 (en: 'sub three', google translation) - - "₄": [T: "senket fire"] # 0x2084 (en: 'sub four', google translation) - - "₅": [T: "senket fem"] # 0x2085 (en: 'sub five', google translation) - - "₆": [T: "senket seks"] # 0x2086 (en: 'sub six', google translation) - - "₇": [T: "senket sju"] # 0x2087 (en: 'sub seven', google translation) - - "₈": [T: "senket åtte"] # 0x2088 (en: 'sub eight', google translation) - - "₉": [T: "senket ni"] # 0x2089 (en: 'sub nine', google translation) - - "₊": [T: "senket pluss"] # 0x208a (en: 'subscript plus sign', google: 'subscript plus -skylt') - - "₋": [T: "senket minus"] # 0x208b (en: 'subscript minus sign', google: 'subscript minus sign') - - "₌": [T: "senket likhetstegn"] # 0x208c (en: 'subscript equals sign', google: 'subscript är lika med tecken') - - "₍": [T: "senket venstreparentes"] # 0x208d (en: 'subscript left parenthesis', google: 'subscript vänster-parentes av sig') - - "₎": [T: "senket høyreparentes"] # 0x208e (en: 'subscript right parenthesis', google: 'subscript höger parentes') - - "ₐ": [T: "senket a"] # 0x2090 (en: 'sub A', google: 'sub a') - - "ₑ": [T: "senket e"] # 0x2091 (en: 'sub E', google: 'sub e') - - "ₒ": [T: "senket o"] # 0x2092 (en: 'sub O', google: 'under o') - - "ₓ": [T: "senket x"] # 0x2093 (en: 'sub X', google: 'under x') - - "ₕ": [T: "senket h"] # 0x2095 (en: 'sub H', google: 'under h') - - "ₖ": [T: "senket k"] # 0x2096 (en: 'sub K', google: 'under k') - - "ₗ": [T: "senket l"] # 0x2097 (en: 'sub L', google: 'under l') - - "ₘ": [T: "senket m"] # 0x2098 (en: 'sub M', google: 'sub m') - - "ₙ": [T: "senket n"] # 0x2099 (en: 'sub N', google: 'under n') - - "ₚ": [T: "senket p"] # 0x209a (en: 'sub P', google: 'sub p') - - "ₛ": [T: "senket s"] # 0x209b (en: 'sub S', google: 'sub s') - - "ₜ": [T: "senket t"] # 0x209c (en: 'sub T', google: 'under t') - #-------------------------------------------------------------------------------------------------------------------- - #Currency symbols OK - - "₠": [T: "europeisk valutaenhet"] # 0x20a0 (en: 'european currenty units', google translation) - - "₡": [T: "colón"] # 0x20a1 - - "₢": [T: "cruzeiro"] # 0x20a2 - - "₣": [T: "franc"] # 0x20a3 - - "₤": [T: "lira"] # 0x20a4 (google: 'lire') - - "₥": [T: "mill"] # 0x20a5 - - "₦": [T: "naira"] # 0x20a6 - - "₧": [T: "peseta"] # 0x20a7 - - "₨": [T: "rupi"] # 0x20a8 (google: 'rupier') - - "₩": [T: "won"] # 0x20a9 (google: 'vann') - - "₪": [T: "ny shekel"] # 0x20aa (google: 'shekel') - - "₫": [T: "dong"] # 0x20ab - - "€": [T: "euro"] # 0x20ac (en: 'euros') - - "₭": [T: "kip"] # 0x20ad (google: 'slaf') - - "₮": [T: "tugrik"] # 0x20ae - - "₯": [T: "drakmer"] # 0x20af (google: 'drakma') - - "₰": [T: "pfenniger"] # 0x20b0 (google: 'tyska pennies') - - "₱": [T: "peso"] # 0x20b1 - - "₲": [T: "guaranier"] # 0x20b2 - - "₳": [T: "australes"] # 0x20b3 (google: 'österral') - - "₴": [T: "hryvnjaer"] # 0x20b4 - - "₵": [T: "cedi"] # 0x20b5 - - "₶": [T: "livre tournois"] # 0x20b6 (google translation) - - "₷": [T: "spesmilo"] # 0x20b7 (google translation) - - "₸": [T: "tenge"] # 0x20b8 (google translation) - - "₹": [T: "indiske rupi"] # 0x20b9 (en: 'indian rupees', google translation) - - "₺": [T: "tyrkiske lira"] # 0x20ba (en: 'turkish liras', google translation) - #-------------------------------------------------------------------------------------------------------------- - #Combining Diacritical Marks for Symbols OK - - "⃐": [T: "venstre-harpun"] # 0x20d0 (en: 'left harpoon above embellishment', google: 'vänster harpoon ovanför utsmyckning') - - "⃑": [T: "høyre-harpun"] # 0x20d1 (en: 'right harpoon above embellishment', google: 'höger harpoon ovanför utsmyckning') - - "⃒": [T: "lang vertikal strek"] # 0x20d2 (en: 'long vertical line overlay embellishment', google translation) - - "⃓": [T: "kort vertikal strek"] # 0x20d3 (en: 'short vertical line overlay embellishment', google translation) - - "⃔": [T: "pil mot klokken"] # 0x20d4 (en: 'anticlockwise arrow above embellishment', google translation) - - "⃕": [T: "pil med klokken"] # 0x20d5 (en: 'clockwise arrow above embellishment', google translation) - - "⃖": [T: "venstrepil"] # 0x20d6 (en: 'left arrow above embellishment', google: 'vänster pil över utsmyckningen') - - "⃗": [T: "høyrepil"] # 0x20d7 (en: 'right arrow above embellishment', google: 'höger-pil över utsmyckning') - - "⃘": [T: "ring"] # 0x20d8 (en: 'ring overlay embellishment', google translation) - - "⃙": [T: "ring med klokken"] # 0x20d9 (en: 'clockwise ring overlay embellishment', google translation) - - "⃚": [T: "ring mot klokken"] # 0x20da (en: 'anticlockwise ring overlay embellishment', google translation) - - "⃛": [T: "trippel prikk"] # 0x20db (en: 'triple dot', google: 'triple dot') - - "⃜": [T: "fire prikker"] # 0x20dc (en: 'quadruple dot', google: 'fyrdubbla prick') - - "⃝": [T: "i sirkel"] # 0x20dd (en: 'enclosing circle embellishment', google translation) - - "⃞": [T: "i firkant"] # 0x20de (en: 'enclosing square embellishment', google translation) - - "⃟": [T: "i diamant"] # 0x20df (en: 'enclosing diamond embellishment', google translation) - - "⃠": [T: "i sirkel med omvendt skråstrek"] # 0x20e0 (en: 'enclosing circle backslash embellishment', google translation) - - "⃡": [T: "venstre-høyre-pil"] # 0x20e1 (en: 'left right arrow above embellishment', google: 'vänster höger pil över utsmyckningen') - - "⃢": [T: "omsluttende skjerm"] # 0x20e2 (en: 'enclosing screen embellishment', google translation) - - "⃣": [T: "omsluttende tastehette"] # 0x20e3 (en: 'enclosing keycap embellishment', google translation) - - "⃤": [T: "i oppoverpekende trekant"] # 0x20e4 (en: 'enclosing upward pointing triangle embellishment', google translation) - - "⃥": [T: "omvendt skråstrek"] # 0x20e5 (en: 'reverse solidus overlay embellishment', google translation) - - "⃦": [T: "dobbel loddrett strek"] # 0x20e6 (en: 'double verticle stroke embellishment', google translation) - - "⃧": [T: "livrentesymbol"] # 0x20e7 (en: 'annuity symbol embellishment', google translation) - - "⃨": [T: "trippel prikk"] # 0x20e8 (en: 'triple underdot', google translation) - - "⃩": [T: "bred bro"] # 0x20e9 (en: 'wide bridge above embellishment', google translation) - - "⃪": [T: "venstrepil"] # 0x20ea (en: 'leftwards arrow overlay embellishment', google translation) - - "⃫": [T: "lang dobbel skråstrek"] # 0x20eb (en: 'long double solidus overlay embellishment', google translation) - - "⃬": [T: "høyre-harpun mothake ned"] # 0x20ec (en: 'rightwards harpoon with barb downwards embellishment', google translation) - - "⃭": [T: "venstre-harpun mothake ned"] # 0x20ed (en: 'leftwards harpoon with barb downwards embellishment', google translation) - - "⃮": [T: "venstrepil under"] # 0x20ee (en: 'left arrow below embellishment', google translation) - - "⃯": [T: "høyrepil under"] # 0x20ef (en: 'right arrow below embellishment', google translation) - - "⃰": [T: "asterisk"] # 0x20f0 (en: 'asterisk above embellishment', google translation) - #----------------------------------------------------------------------------------------------------- - #Letterlike Symbols OK - - "℄": [T: "midtlinjesymbol"] # 0x2104 (google translation) - - "℅": [T: "care of"] # 0x2105 (google: 'bry sig om') - - "℆": [T: "cada una"] # 0x2106 (google translation) - - "ℇ": [T: "eulers konstant"] # 0x2107 (en: 'euler's constant', google: 'eulers konstant') - - "℈": [T: "scruple"] # 0x2108 (en: 'scruples', google translation) - - "℉": [T: "grader fahrenheit"] # 0x2109 (en: 'degrees fahrenheit') - - "ℊ": [T: "script font g"] # 0x210a (en: 'script g') - - "ℌℑℨℭ": # 0x210c, 0x2111, 0x2128, 0x212d - - T: "fraktur" # (en: 'fraktur', google: 'fraktur') - - SPELL: "translate('.', 'ℌℑℨℭ', 'HIZC')" - - - "ℍℙℾℿ": # 0x210d, 0x2119, 0x213e, 0x213f - - T: "dobbeltstreket" # (en: 'double struck', google translation) - - SPELL: "translate('.', 'ℍℙℾℿ', 'HPΓΠ')" - - - "ℎ": [T: "plancks konstant"] # 0x210e - - "ℏ": [T: "h strek"] # 0x210f - # SWEDISH: finns bara ett sätt att säga h strek - - - "ℐℒ℘ℬℰℱℳ": # 0x2110, 0x2112, 0x2118, 0x2130, 0x2131, 0x2133 - - T: "script font" # (en: 'script') - - SPELL: "translate('.', 'ℐℒ℘ℬℰℱℳ', 'ILPBEFM')" - - - "℔": [T: "pund"] # 0x2114 (en: 'pounds', google: 'pund') - - "№": [T: "numero"] # 0x2116 (en: 'number') - - "℥": [T: "ounce"] # 0x2125 (en: 'ounces') - - "Ω": [T: "ohm"] # 0x2126 (en: 'ohms') - - "℧": [T: "mho"] # 0x2127 (en: 'mhos') - - "℩": [T: "rotert iota"] # 0x2129 (en: 'turned iota', google: 'vände iota') - - "Å": [T: "ångstrøm"] # 0x212b - - "ℯ": [T: "script font e"] # 0x212f (en: 'script e') - - # coalesced some chars that use cap letters - - "Ⅎ℺⅁⅂⅃⅄": # 0x2132, 0x213a, 0x2141, 0x2142, 0x2143, 0x2144 - - test: - - if: "'.' = '℺'" - then: [T: "rotert"] # (en: 'rotated', google translation) - - else_if: "'.' = 'Ⅎ'" - then: [T: "rotert"] # (en: 'turned', google translation) - - else_if: "'.' = '⅃'" - then: [T: "omvendt sans-serif"] # (en: 'reversed sans-serif', google translation) - else: [T: "rotert sans-serif"] # (en: 'turned sans-serif', google: 'vände sans-serif') - - SPELL: "translate('.', 'Ⅎ℺⅁⅂⅃⅄', 'FQGLLY')" - - - "ℴ": [T: "script font o"] # 0x2134 (en: 'script o') - - "ℵ": [T: "alef"] # 0x2135 (en: 'first transfinite cardinal') - - "ℶ": [T: "bet"] # 0x2136 (en: 'second transfinite cardinal') - - "ℷ": [T: "gimel"] # 0x2137 (en: 'third transfinite cardinal') - - "ℸ": [T: "dalet"] # 0x2138 (en: 'fourth transfinite cardinal') - - "ℼ": [T: "dobbeltstreket pi"] # 0x213c (en: 'double struck pi', google: 'dobbelslaget pi') - - "ℽ": [T: "dobbeltstreket gamma"] # 0x213d (en: 'double struck gamma', google: 'dobbelslaget gamma') - - "⅀": [T: "dobbeltstreket summetegn"] # 0x2140 (en: 'double struck n-ary summation', google: 'dubbelslaget n-ary-sammanfattning') - - "⅋": [T: "rotert og-tegn"] # 0x214b (en: 'turned ampersand', google: 'vände ampersand') - - "⅌": [T: "per"] # 0x214c (en: 'per', google: 'per') - - "ⅎ": [T: "rotert f"] # 0x214e (en: 'turned F', google: 'vände f') - #-------------------------------------------------------------------------------------------------------------- - #Number formats OK - - "¼": [T: "én fjerdedel"] # 0x00bc - - "½": [T: "én halv"] # 0x00bd - - "¾": [T: "tre fjerdedeler"] # 0x00be - - "⅐": [T: "én sjudel"] # 0x2150 (en: 'one seventh', google: 'en sjunde') - - "⅑": [T: "én nidel"] # 0x2151 (en: 'one ninth', google: 'en nionde') - - "⅒": [T: "én tidel"] # 0x2152 (en: 'one tenth') - - "⅓": [T: "én tredjedel"] # 0x2153 (en: 'one third') - - "⅔": [T: "to tredjedeler"] # 0x2154 (en: 'two thirds') - - "⅕": [T: "én femtedel"] # 0x2155 (en: 'one fifth') - - "⅖": [T: "to femtedeler"] # 0x2156 (en: 'two fifths') - - "⅗": [T: "tre femtedeler"] # 0x2157 (en: 'three fifths') - - "⅘": [T: "fire femtedeler"] # 0x2158 (en: 'four fifths') - - "⅙": [T: "én sjettedel"] # 0x2159 (en: 'one sixth') - - "⅚": [T: "fem sjettedeler"] # 0x215a (en: 'five sixths') - - "⅛": [T: "én åttedel"] # 0x215b (en: 'one eighth') - - "⅜": [T: "tre åttedeler"] # 0x215c (en: 'three eighths') - - "⅝": [T: "fem åttedeler"] # 0x215d (en: 'five eighths') - - "⅞": [T: "sju åttedeler"] # 0x215e (en: 'seven eighths') - - "⅟": [T: "én over"] # 0x215f (en: 'one over', google: 'en över') - - "Ⅰ": [T: "i"] # 0x2160 (en: 'I', google translation) - - "Ⅱ": [T: "i i"] # 0x2161 (en: 'I I', google translation) - - "Ⅲ": [T: "i i i"] # 0x2162 (en: 'I I I', google translation) - - "Ⅳ": [T: "i v"] # 0x2163 (en: 'I V', google translation) - - "Ⅴ": [T: "v"] # 0x2164 (en: 'V', google translation) - - "Ⅵ": [T: "v i"] # 0x2165 (en: 'V I', google translation) - - "Ⅶ": [T: "v i i"] # 0x2166 (en: 'V I I', google translation) - - "Ⅷ": [T: "v i i i"] # 0x2167 (en: 'V I I I', google translation) - - "Ⅸ": [T: "i x"] # 0x2168 (en: 'I X', google translation) - - "Ⅹ": [T: "x"] # 0x2169 (en: 'X', google translation) - - "Ⅺ": [T: "x i"] # 0x216a (en: 'X I', google translation) - - "Ⅻ": [T: "x i i"] # 0x216b (en: 'X I I', google translation) - - "Ⅼ": [T: "l"] # 0x216c (en: 'L', google translation) - - "Ⅽ": [T: "c"] # 0x216d (en: 'C', google translation) - - "Ⅾ": [T: "d"] # 0x216e (en: 'D', google translation) - - "Ⅿ": [T: "m"] # 0x216f (en: 'M', google translation) - - "ⅰ": [T: "i"] # 0x2170 (en: 'I', google translation) - - "ⅱ": [T: "i i"] # 0x2171 (en: 'I I', google translation) - - "ⅲ": [T: "i i i"] # 0x2172 (en: 'I I I', google translation) - - "ⅳ": [T: "i v"] # 0x2173 (en: 'I V', google translation) - - "ⅴ": [T: "v"] # 0x2174 (en: 'V', google translation) - - "ⅵ": [T: "v i"] # 0x2175 (en: 'V I', google translation) - - "ⅶ": [T: "v i i"] # 0x2176 (en: 'V I I', google translation) - - "ⅷ": [T: "v i i i"] # 0x2177 (en: 'V I I I', google translation) - - "ⅸ": [T: "i x"] # 0x2178 (en: 'I X', google translation) - - "ⅹ": [T: "x"] # 0x2179 (en: 'X', google translation) - - "ⅺ": [T: "x i"] # 0x217a (en: 'X I', google translation) - - "ⅻ": [T: "x i i"] # 0x217b (en: 'X I I', google translation) - - "ⅼ": [T: "l"] # 0x217c (en: 'L', google translation) - - "ⅽ": [T: "c"] # 0x217d (en: 'C', google translation) - - "ⅾ": [T: "d"] # 0x217e (en: 'D', google translation) - - "ⅿ": [T: "m"] # 0x217f (en: 'M', google translation) - - "↉": [T: "null tredjedeler"] # 0x2189 (en: 'zero thirds') - #----------------------------------------------------------------------------------------------------- - #Arrows OK - - "←": [T: "venstrepil"] # 0x2190 (en: 'leftwards arrow') - - "↑": [T: "oppoverpil"] # 0x2191 (en: 'upwards arrow') - - "↓": [T: "nedoverpil"] # 0x2193 (en: 'downwards arrow') - - "↔": [T: "venstre-høyre-pil"] # 0x2194 (en: 'left right arrow') - - "↕": [T: "opp-ned-pil"] # 0x2195 (en: 'up down arrow') - - "↖": [T: "nordvest-pil"] # 0x2196 (en: 'north west arrow') - - "↗": # 0x2197 - - test: - if: "ancestor::*[2][self::m:limit]" - then: [T: "går fra venstre mot"] # (en: 'approaches from below', google translation) - else: [T: "nordøst-pil"] # (en: 'north east arrow') - - - "↘": # 0x2198 - - test: - if: "ancestor::*[2][self::m:limit]" - then: [T: "går fra høyre mot"] # (en: 'approaches from above', google translation) - else: [T: "sørøst-pil"] # (en: 'south east arrow') - - - "↙": [T: "sørvest-pil"] # 0x2199 (en: 'south west arrow') - - "↚": [T: "overstrøket venstrepil"] # 0x219a (en: 'leftwards arrow with stroke') - - "↛": [T: "overstrøket høyrepil"] # 0x219b (en: 'rightwards arrow with stroke') - - "↜": [T: "bølget venstrepil"] # 0x219c (en: 'leftwards wave arrow') - - "↝": [T: "bølget høyrepil"] # 0x219d (en: 'rightwards wave arrow') - - "↞": [T: "venstrepil med to spisser"] # 0x219e (en: 'leftwards two headed arrow') - - "↟": [T: "oppoverpil med to spisser"] # 0x219f (en: 'upwards two headed arrow') - - "↠": [T: "høyrepil med to spisser"] # 0x21a0 (en: 'rightwards two headed arrow') - - "↡": [T: "nedoverpil med to spisser"] # 0x21a1 (en: 'downwards two headed arrow') - - "↢": [T: "venstrepil med hale"] # 0x21a2 (en: 'leftwards arrow with tail') - - "↣": [T: "høyrepil med hale"] # 0x21a3 (en: 'rightwards arrow with tail') - - "↤": [T: "venstrepil fra strek"] # 0x21a4 (en: 'leftwards arrow from bar') - - "↥": [T: "oppoverpil fra strek"] # 0x21a5 (en: 'upwards arrow from bar') - - "↦": [T: "høyrepil fra strek"] # 0x21a6 (en: 'rightwards arrow from bar') - - "↧": [T: "nedoverpil fra strek"] # 0x21a7 (en: 'downwards arrow from bar') - - "↨": [T: "opp-ned-pil med base"] # 0x21a8 (en: 'up down arrow with base') - - "↩": [T: "venstrepil med krok"] # 0x21a9 (en: 'leftwards arrow with hook') - - "↪": [T: "høyrepil med krok"] # 0x21aa (en: 'rightwards arrow with hook') - - "↫": [T: "venstrepil med løkke"] # 0x21ab (en: 'leftwards arrow with loop') - - "↬": [T: "høyrepil med løkke"] # 0x21ac (en: 'rightwards arrow with loop') - - "↭": [T: "bølget venstre-høyre-pil"] # 0x21ad (en: 'left right wave arrow') - - "↮": [T: "overstrøket venstre-høyre-pil"] # 0x21ae (en: 'left right arrow with stroke') - - "↯": [T: "sikksakk nedoverpil"] # 0x21af (en: 'downwards zigzag arrow') - - "↰": [T: "oppoverpil med spissen mot venstre"] # 0x21b0 (en: 'upwards arrow with tip leftwards') - - "↱": [T: "oppoverpil med spissen mot høyre"] # 0x21b1 (en: 'upwards arrow with tip rightwards') - - "↲": [T: "nedoverpil med spissen mot venstre"] # 0x21b2 (en: 'downwards arrow with tip leftwards') - - "↳": [T: "nedoverpil med spissen mot høyre"] # 0x21b3 (en: 'downwards arrow with tip rightwards') - - "↴": [T: "høyrepil med hjørnet ned"] # 0x21b4 (en: 'rightwards arrow with corner downwards') - - "↵": [T: "nedoverpil med hjørnet mot venstre"] # 0x21b5 (en: 'downwards arrow with corner leftwards') - - "↶": [T: "øvre halvsirkelpil mot klokken"] # 0x21b6 (en: 'anticlockwise top semicircle arrow') - - "↷": [T: "øvre halvsirkelpil med klokken"] # 0x21b7 (en: 'clockwise top semicircle arrow') - - "↸": [T: "nordvest-pil mot strek"] # 0x21b8 (en: 'north west arrow to long bar') - - "↹": [T: "venstrepil mot strek over høyrepil mot strek"] # 0x21b9 (en: 'leftwards arrow to bar over rightwards arrow to bar') - - "↺": [T: "åpen sirkelpil mot klokken"] # 0x21ba (en: 'anticlockwise open circle arrow') - - "↻": [T: "åpen sirkelpil med klokken"] # 0x21bb (en: 'clockwise open circle arrow') - - "↼": [T: "venstre-harpun mothake opp"] # 0x21bc (en: 'left harpoon up') - - "↽": [T: "venstre-harpun mothake ned"] # 0x21bd (en: 'left harpoon down') - - "↾": [T: "opp-harpun mothake høyre"] # 0x21be (en: 'up harpoon right') - - "↿": [T: "opp-harpun mothake venstre"] # 0x21bf (en: 'up harpoon left') - - "⇀": [T: "høyre-harpun mothake opp"] # 0x21c0 (en: 'right harpoon up') - - "⇁": [T: "høyre-harpun mothake ned"] # 0x21c1 (en: 'right harpoon down') - - "⇂": [T: "ned-harpun mothake høyre"] # 0x21c2 (en: 'down harpoon right') - - "⇃": [T: "ned-harpun mothake venstre"] # 0x21c3 (en: 'down harpoon left') - - "⇄": [T: "høyrepil over venstrepil"] # 0x21c4 (en: 'rightwards arrow over leftwards arrow') - - "⇅": [T: "oppoverpil til venstre for nedoverpil"] # 0x21c5 (en: 'upwards arrow leftwards of downwards arrow') - - "⇆": [T: "venstrepil over høyrepil"] # 0x21c6 (en: 'leftwards arrow over rightwards arrow') - - "⇇": [T: "to venstrepiler"] # 0x21c7 (en: 'leftwards paired arrows') - - "⇈": [T: "to oppoverpiler"] # 0x21c8 (en: 'upwards paired arrows') - - "⇉": [T: "to høyrepiler"] # 0x21c9 (en: 'rightwards paired arrows') - - "⇊": [T: "to nedoverpiler"] # 0x21ca (en: 'downwards paired arrows') - - "⇋": [T: "venstre-harpun over høyre-harpun"] # 0x21cb (en: 'left harpoon over right harpoon') - - "⇌": [T: "høyre-harpun over venstre-harpun"] # 0x21cc (en: 'right harpoon over left harpoon') - - "⇍": [T: "overstrøket dobbeltstreket venstrepil"] # 0x21cd (en: 'leftwards double arrow with stroke') - - "⇎": [T: "overstrøket dobbeltstreket venstre-høyre-pil"] # 0x21ce (en: 'left right double arrow with stroke') - - "⇏": [T: "overstrøket dobbeltstreket høyrepil"] # 0x21cf (en: 'rightwards double arrow with stroke') - - "⇐": [T: "dobbeltstreket venstrepil"] # 0x21d0 (en: 'leftwards double arrow') - - "⇑": [T: "dobbeltstreket oppoverpil"] # 0x21d1 (en: 'upwards double arrow') - - "⇒": [T: "impliserer"] # 0x21d2 (en: 'rightwards double arrow') - - "⇓": [T: "dobbeltstreket nedoverpil"] # 0x21d3 (en: 'downwards double arrow') - - "⇔": [T: "er ekvivalent med"] # 0x21d4 (en: 'left right double arrow') - - "⇕": [T: "dobbeltstreket opp-ned-pil"] # 0x21d5 (en: 'up down double arrow') - - "⇖": [T: "dobbeltstreket nordvest-pil"] # 0x21d6 (en: 'north west double arrow') - - "⇗": [T: "dobbeltstreket nordøst-pil"] # 0x21d7 (en: 'north east double arrow') - - "⇘": [T: "dobbeltstreket sørøst-pil"] # 0x21d8 (en: 'south east double arrow') - - "⇙": [T: "dobbeltstreket sørvest-pil"] # 0x21d9 (en: 'south west double arrow') - - "⇚": [T: "trippelstreket venstrepil"] # 0x21da (en: 'leftwards triple arrow') - - "⇛": [T: "trippelstreket høyrepil"] # 0x21db (en: 'rightwards triple arrow') - - "⇜": [T: "slingrete venstrepil"] # 0x21dc (en: 'leftwards squiggle arrow') - - "⇝": [T: "slingrete høyrepil"] # 0x21dd (en: 'rightwards squiggle arrow') - - "⇞": [T: "oppoverpil med dobbel horisontal strek"] # 0x21de (en: 'upwards arrow with double stroke') - - "⇟": [T: "nedoverpil med dobbel horisontal strek"] # 0x21df (en: 'downwards arrow with double stroke') - - "⇠": [T: "stiplet venstrepil"] # 0x21e0 (en: 'leftwards dashed arrow') - - "⇡": [T: "stiplet oppoverpil"] # 0x21e1 (en: 'upwards dashed arrow') - - "⇢": [T: "stiplet høyrepil"] # 0x21e2 (en: 'rightwards dashed arrow') - - "⇣": [T: "stiplet nedoverpil"] # 0x21e3 (en: 'downwards dashed arrow') - - "⇤": [T: "venstrepil mot strek"] # 0x21e4 (en: 'leftwards arrow to bar') - - "⇥": [T: "høyrepil mot strek"] # 0x21e5 (en: 'rightwards arrow to bar') - - "⇦": [T: "hvit venstrepil"] # 0x21e6 (en: 'leftwards white arrow') - - "⇧": [T: "hvit oppoverpil"] # 0x21e7 (en: 'upwards white arrow') - - "⇨": [T: "hvit høyrepil"] # 0x21e8 (en: 'rightwards white arrow') - - "⇩": [T: "hvit nedoverpil"] # 0x21e9 (en: 'downwards white arrow') - - "⇪": [T: "hvit oppoverpil fra strek"] # 0x21ea (en: 'upwards white arrow from bar') - - "⇫": [T: "hvit oppoverpil på sokkel"] # 0x21eb (en: 'upwards white arrow on pedestal', google: 'uppåt vit pil på piedestal') - - "⇬": [T: "hvit oppoverpil på sokkel med horisontal strek"] # 0x21ec (en: 'upwards white arrow on pedestal with horizontal bar', google: 'uppåt vit pil på piedestal med horisontell stång') - - "⇭": [T: "hvit oppoverpil på sokkel med vertikal strek"] # 0x21ed (en: 'upwards white arrow on pedestal with vertical bar', google: 'uppåt vit pil på piedestal med vertikal bar') - - "⇮": [T: "hvit dobbel oppoverpil"] # 0x21ee (en: 'upwards white double arrow', google: 'uppåt vit dubbelpil') - - "⇯": [T: "hvit dobbel oppoverpil på sokkel"] # 0x21ef (en: 'upwards white double arrow on pedestal', google: 'uppåt vit dubbelpil på piedestal') - - "⇰": [T: "hvit høyrepil fra vegg"] # 0x21f0 (en: 'rightwards white arrow from wall', google: 'åtgärder vit pil från vägg') - - "⇱": [T: "nordvest-pil mot hjørne"] # 0x21f1 (en: 'north west arrow to corner', google: 'north west arrow till hörnet') - - "⇲": [T: "sørøst-pil mot hjørne"] # 0x21f2 (en: 'south east arrow to corner', google: 'south east arrow till corner') - - "⇳": [T: "hvit opp-ned-pil"] # 0x21f3 (en: 'up down white arrow', google: 'upp ner white arrow') - - "⇴": [T: "høyrepil med liten sirkel"] # 0x21f4 (en: 'right arrow with small circle') - - "⇵": [T: "nedoverpil til venstre for oppoverpil"] # 0x21f5 (en: 'downwards arrow leftwards of upwards arrow') - - "⇶": [T: "tre høyrepiler"] # 0x21f6 (en: 'three rightwards arrows', google: 'tre pilar med höger') - - "⇷": [T: "venstrepil med vertikal strek"] # 0x21f7 (en: 'leftwards arrow with vertical stroke', google: 'vänster pil med lodslag') - - "⇸": [T: "høyrepil med vertikal strek"] # 0x21f8 (en: 'rightwards arrow with vertical stroke', google: 'åtgärdspil med vertikal stroke') - - "⇹": [T: "venstre-høyre-pil med vertikal strek"] # 0x21f9 (en: 'left right arrow with vertical stroke', google: 'vänster höger pil med vertikalt slag') - - "⇺": [T: "venstrepil med dobbel vertikal strek"] # 0x21fa (en: 'leftwards arrow with double vertical stroke', google: 'vänster pil med dubbel vertikal stroke') - - "⇻": [T: "høyrepil med dobbel vertikal strek"] # 0x21fb (en: 'rightwards arrow with double vertical stroke', google: 'åtgärdspil med dubbel vertikal stroke') - - "⇼": [T: "venstre-høyre-pil med dobbel vertikal strek"] # 0x21fc (en: 'left right arrow with double vertical stroke', google: 'vänster höger pil med dubbel vertikal stroke') - - "⇽": [T: "venstrepil med åpen spiss"] # 0x21fd (en: 'leftwards open headed arrow') - - "⇾": [T: "høyrepil med åpen spiss"] # 0x21fe (en: 'rightwards open headed arrow') - - "⇿": [T: "venstre-høyre-pil med åpen spiss"] # 0x21ff (en: 'left right open headed arrow') - #---------------------------------------------------------------------------------------------------------------- - #Mathematical operators OK - - "∀": [T: "for alle"] # 0x2200 (en: 'for all') - - "∁": # 0x2201 # audit-ignore - - T: "komplementet til" # (en: 'complement of') - - "∃": [T: "det eksisterer"] # 0x2203 (en: 'there exists') - - "∄": [T: "det eksisterer ikke"] # 0x2204 (en: 'there does not exist') - - "∅": [T: "den tomme mengden"] # 0x2205 (en: 'empty set') - - "∇": [T: "nabla"] # 0x2207 (en: 'gradient of', google: 'lutning av') - - "∋": [T: "inneholder elementet"] # 0x220b (en: 'contains the member') - - "∌": [T: "inneholder ikke elementet"] # 0x220c (en: 'does not contain the member') - - "∍": [T: "inneholder elementet"] # 0x220d (en: 'contains the member') - - "∎": [T: "som skulle bevises"] # 0x220e (en: 'end of proof') - - "∏": [T: "produktet"] # 0x220f (en: 'product') - - "∐": [T: "koproduktet"] # 0x2210 (en: 'coproduct', MathPlayer: 'coproduct', google: 'coprodukt') - - "∑": [T: "sum"] # 0x2211 (en: 'sum') - - "−": [T: "minus"] # 0x2212 - - "∓": [T: "minus pluss"] # 0x2213 (en: 'minus or plus') - - "∔": [T: "prikk pluss"] # 0x2214 (en: 'dot plus') - - "∕": [T: "delt på"] # 0x2215 (en: 'divided by') - - "∖": [T: "minus"] # 0x2216 (en: 'set minus') - - "∗": [T: "ganger"] # 0x2217 (en: 'times') - - "∘": [T: "sammensatt med"] # 0x2218 (en: 'composed with') - - "∙": # 0x2219 - - test: - if: "@data-chem-formula-op" - then: [T: "ganger"] # (en: 'dot', google translation) - else: [T: "ganger"] # (en: 'times') - - - "∛": # 0x221b # audit-ignore - - T: "kubikkroten av" # (en: 'cube root of') - - "∜": # 0x221c # audit-ignore - - T: "fjerderoten av" # (en: 'fourth root of') - - "∞": [T: "uendelig"] # 0x221e (en: 'infinity') - - "∟": [T: "rett vinkel"] # 0x221f (en: 'right angle') - - "∠": [T: "vinkel"] # 0x2220 (en: 'angle') - - "∡": [T: "målt vinkel"] # 0x2221 (en: 'measured angle') - - "∢": [T: "sfærisk vinkel"] # 0x2222 (en: 'spherical angle') - - "∣": [T: "deler"] # 0x2223 (en: 'divides') - - "∤": [T: "deler ikke"] # 0x2224 (en: 'does not divide') - - "∧": [T: "og"] # 0x2227 (en: 'and') - - "∨": [T: "eller"] # 0x2228 (en: 'or') - - "∩": [T: "snitt"] # 0x2229 (en: 'intersection') - - "∪": [T: "union"] # 0x222a - - "∫": [T: "integralet"] # 0x222b - - "∬": [T: "dobbeltintegralet"] # 0x222c (en: 'double integral') - - "∭": [T: "trippelintegralet"] # 0x222d (en: 'triple integral') - - "∮": [T: "kurveintegralet"] # 0x222e (en: 'contour integral') - - "∯": [T: "flateintegralet"] # 0x222f (en: 'surface integral') - - "∰": [T: "volumintegralet"] # 0x2230 (en: 'volume integral') - - "∱": [T: "integralet med klokken"] # 0x2231 (en: 'clockwise integral', MathPlayer: 'clockwise integral', google: 'medurs integrerad') - - "∲": [T: "kurveintegralet med klokken"] # 0x2232 (en: 'clockwise contour integral', MathPlayer: 'clockwise contour integral (arrow on höger)', google: 'medurs konturintegral') - - "∳": [T: "kurveintegralet mot klokken"] # 0x2233 (en: 'anticlockwise contour integral', MathPlayer: 'anticlockwise contour integral', google: 'antikvis konturintegral') - - "∴": [T: "derfor"] # 0x2234 (en: 'therefore') - - "∵": [T: "ettersom"] # 0x2235 (en: 'because') - - "∶": # 0x2236 # audit-ignore - - T: "til" # (en: 'to') - - "∷": [T: "som"] # 0x2237 (en: 'as', MathPlayer: 'proportion', google: 'som') - - "∸": [T: "prikk minus"] # 0x2238 (en: 'dot minus') - - "∹": [T: "har overskudd sammenlignet med"] # 0x2239 (en: 'has excess compared to', MathPlayer: 'excess', google: 'har överskott jämfört med') - - "∺": # 0x223a - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "geometrisk proporsjonal med" # (en: 'geometrically proportional to') - - "∻": # 0x223b - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "homotetisk til" # (en: 'homothetic to', MathPlayer: 'homothetic', google: 'homotetisk till') - - "∽": [T: "omvendt tilde"] # 0x223d (en: 'reversed tilde') - - "∾": # 0x223e # audit-ignore - - T: "omvendt langstrakt s" # (en: 'most positive', MathPlayer: 'inverted lazy s', google: 'mest positiva') - - "∿": [T: "sinuskurve"] # 0x223f (en: 'sine wave') - - "≀": [T: "kransprodukt"] # 0x2240 (en: 'wreath product') - - "≁": # 0x2241 (en: 'not tilde') # audit-ignore - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] - - T: "ikke proporsjonal med" - - "≂": [T: "minus tilde"] # 0x2242 (SRE: 'minus och tilde') - - "≃": # 0x2243 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] - - T: "asymptotisk lik" # (en: 'asymptotically equal to', MathPlayer: 'asymptotically lika med', google: 'asymptotisk lik') - - "≄": # 0x2244 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] - - T: "ikke asymptotisk lik" # (en: 'not asymptotically equal to', MathPlayer: 'inte asymptotically lika med', google: 'ikke asymptotisk lik') - - "≅": # 0x2245 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] - - T: "tilnærmet lik" # (en: 'approximately equal to', MathPlayer: 'approximativt lika med', google: 'omtrent lik') - - "≆": # 0x2246 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] - - T: "tilnærmet men faktisk ikke lik" # (en: 'approximately but not actually equal to', MathPlayer: 'approximativt men inte faktiskt lika med', google: 'omtrentlig men faktisk ikke lik') - - "≇": # 0x2247 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] - - T: "verken tilnærmet eller faktisk lik" # (en: 'neither approximately nor actually equal to', MathPlayer: 'varken approximativt eller fakiskt lika med', google: 'varken ungefär eller faktiskt lika med') - - "≈": # 0x2248 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] - - T: "tilnærmet lik" # (en: 'almost equal to', SRE: 'är nästan lika med') - - "≉": # 0x2249 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] - - T: "ikke tilnærmet lik" # (en: 'not almost equal to', SRE: 'är inte nästan lika med') - - "≊": # 0x224a - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] - - T: "tilnærmet lik eller lik" # (en: 'almost equal or equal to', SRE: 'är nästan lika eller lika med') - - "≋": [T: "trippel tilde"] # 0x224b (en: 'triple tilde') - - "≌": [T: "er alle like med"] # 0x224c (en: 'are all equal to', MathPlayer: 'alla lika med') - - "≍": # 0x224d - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "ekvivalent med" # (en: 'equivalent to') - - "≎": # 0x224e - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "geometrisk ekvivalent med" # (en: 'geometrically equivalent to', MathPlayer: 'geometriskt lika med', google: 'geometriskt motsvarande') - - "≏": # 0x224f # audit-ignore - - T: "differansen mellom" # (en: 'difference between') - - "≐": [T: "nærmer seg grenseverdien"] # 0x2250 (en: 'approaches the limit') - - "≑": # 0x2251 # audit-ignore - - T: "geometrisk lik" # (en: 'geometrically equal to', SRE: 'är geometriskt lika med') - - "≒": # 0x2252 # audit-ignore - - T: "tilnærmet lik" # (en: 'approximately equal to or the image of', MathPlayer: 'uppskattningsvis lika med eller i likhet med', google: 'ungefär lika med eller bilden av') - - "≓": # 0x2253 # audit-ignore - - T: "tilnærmet lik" # (en: 'image of or approximately equal to', MathPlayer: 'i likhet med eller uppskattningsvis lika med', google: 'bild av eller ungefär lika med') - - "≔": [T: "definert som"] # 0x2254 (en: 'colon equals', MathPlayer: 'kolon lika med', google: 'kolon är lika med') - - "≕": [T: "lik kolon"] # 0x2255 (en: 'equals colon', MathPlayer: 'lika med kolon') - - "≖": [T: "ring i likhetstegn"] # 0x2256 (en: 'ring in equal to', SRE: 'är ring i lika med') - - "≗": # 0x2257 # audit-ignore - - T: "ring likhetstegn" # (en: 'approximately equal to') - - "≘": [T: "tilsvarer"] # 0x2258 (en: 'corresponds to') - - "≙": [T: "anslår"] # 0x2259 (en: 'estimates') - - "≚": # 0x225a - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "likevinklet med" # (en: 'equiangular to') - - "≛": [T: "stjerne lik"] # 0x225b (en: 'star equals') - # SWEDISH: misspelled delta to fix pronunciation - - "≜": [T: "delta lik"] # 0x225c (en: 'delta equals') - - "≝": [T: "er per definisjon lik"] # 0x225d (en: 'is defined to be') - - "≞": # 0x225e # audit-ignore - - T: "måles med" # (en: 'measured by') - - "≟": [T: "spørsmål ved likhet"] # 0x225f (en: 'has an unknown relationship with') - - "≢": # 0x2262 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "ikke identisk med" # (en: 'not identical to') - - "≣": # 0x2263 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "strengt ekvivalent med" # (en: 'strictly equivalent to') - - "≨": # 0x2268 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "mindre enn men ikke lik" # (en: 'less than but not equal to') - - "≩": # 0x2269 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "større enn men ikke lik" # (en: 'greater than but not equal to') - - "≪": # 0x226a - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "mye mindre enn" # (en: 'much less than') - - "≫": # 0x226b - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "mye større enn" # (en: 'much greater than') - - "≬": # 0x226c - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "mellom" # (en: 'between') - - "≭": # 0x226d - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "ikke ekvivalent med" # (en: 'not equivalent to') - - "≮": # 0x226e - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "ikke mindre enn" # (en: 'not less than') - - "≯": # 0x226f - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "ikke større enn" # (en: 'not greater than') - - "≰": # 0x2270 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "verken mindre enn eller lik" # (en: 'neither less than nor equal to') - - "≱": # 0x2271 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "verken større enn eller lik" # (en: 'neither greater than nor equal to') - - "≲": # 0x2272 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "mindre enn eller tilnærmet lik" # (en: 'less than or equivalent to') - - "≳": # 0x2273 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "større enn eller tilnærmet lik" # (en: 'greater than or equivalent to') - - "≴": # 0x2274 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "verken mindre enn eller tilnærmet lik" # (en: 'neither less than nor equivalent to') - - "≵": # 0x2275 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "verken større enn eller tilnærmet lik" # (en: 'neither greater than nor equivalent to') - - "≶": # 0x2276 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "mindre enn eller større enn" # (en: 'less than or greater than') - - "≷": # 0x2277 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "større enn eller mindre enn" # (en: 'greater than or less than') - - "≸": # 0x2278 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "verken mindre enn eller større enn" # (en: 'neither less than nor greater than') - - "≹": # 0x2279 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "verken større enn eller mindre enn" # (en: 'neither greater than nor less than') - - "≺": [T: "foregår"] # 0x227a (en: 'precedes') - - "≻": [T: "følger"] # 0x227b (en: 'succeeds') - - "≼": [T: "foregår eller er lik"] # 0x227c (en: 'precedes or is equal to') - - "≽": [T: "følger eller er lik"] # 0x227d (en: 'succeeds or is equal to') - - "≾": [T: "foregår eller er ekvivalent med"] # 0x227e (en: 'precedes or is equivalent to') - - "≿": [T: "følger eller er ekvivalent med"] # 0x227f (en: 'succeeds or is equivalent to') - - "⊀": [T: "foregår ikke"] # 0x2280 (en: 'does not precede') - - "⊁": [T: "følger ikke"] # 0x2281 (en: 'does not succeed') - - "⊈": # 0x2288 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "verken en delmengde av eller lik" # (en: 'neither a subset of nor equal to') - - "⊉": # 0x2289 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "verken en overmengde av eller lik" # (en: 'neither a superset of nor equal to') - - "⊊": # 0x228a (en: 'subset of with not equal to') # audit-ignore -# SWEDISH: added test - - test: - if: "$Verbosity!='Terse'" - then: [T: "er en"] - - T: "ekte delmengde av" - - "⊋": # 0x228b (en: 'superset of with not equal to') # audit-ignore - # SWEDISH: added test - - test: - if: "$Verbosity!='Terse'" - then: [T: "er en"] - - T: "ekte overmengde av" - - "⊌": [T: "multimengde"] # 0x228c (SRE: 'multimängd') - - "⊍": [T: "multimengde multiplikasjon"] # 0x228d (en: 'multiset multiplication') - - "⊎": [T: "multimengde union"] # 0x228e (SRE: 'multimängdunion') - - "⊏": [T: "kvadratisk bilde av"] # 0x228f (en: 'square image of', MathPlayer: 'square image of', google: 'fyrkantig bild av') - - "⊐": [T: "kvadratisk original av"] # 0x2290 (en: 'square original of', MathPlayer: 'square original of', google: 'fyrkantig original av') - - "⊑": [T: "kvadratisk bilde av eller lik"] # 0x2291 (en: 'square image of or equal to', MathPlayer: 'square image of or equal to', google: 'fyrkantig bild av eller lika med') - - "⊒": [T: "kvadratisk original av eller lik"] # 0x2292 (en: 'square original of or equal to', MathPlayer: 'square original of or equal to', google: 'fyrkantig original av eller lika med') - # SWEDISH: misspelled to fix pronunciation - - "⊓": [T: "kvadratisk snitt"] # 0x2293 (en: 'square cap') - - "⊔": [T: "kvadratisk union"] # 0x2294 (SRE: 'kvadratisk kopp') - - "⊕": [T: "direkte sum"] # 0x2295 (en: 'circled plus') - - "⊖": [T: "symmetrisk differanse"] # 0x2296 (en: 'circled minus') - - "⊗": [T: "tensorprodukt"] # 0x2297 (en: 'circled times') - - "⊘": [T: "divisjon i sirkel"] # 0x2298 (en: 'circled slash') - - "⊙": [T: "direkte produkt"] # 0x2299 (en: 'circled dot operator') - - "⊚": [T: "ring-operator i sirkel"] # 0x229a (en: 'circled ring') - - "⊛": [T: "asterisk-operator i sirkel"] # 0x229b (en: 'circled asterisk') - - "⊜": [T: "likhetstegn i sirkel"] # 0x229c (en: 'circled equals') - - "⊝": [T: "tankestrek i sirkel"] # 0x229d (en: 'circled dash') - - "⊞": [T: "plusstegn i kvadrat"] # 0x229e (en: 'squared plus') - - "⊟": [T: "minustegn i kvadrat"] # 0x229f (en: 'squared minus') - - "⊠": [T: "multiplikasjonstegn i kvadrat"] # 0x22a0 (en: 'squared times') - - "⊡": [T: "dot-operator i kvadrat"] # 0x22a1 (en: 'squared dot operator') - - "⊢": [T: "beviser"] # 0x22a2 (en: 'proves') - - "⊣": [T: "beviser ikke"] # 0x22a3 (en: 'does not yield') - - "⊤": [T: "topp"] # 0x22a4 (en: 'top') - - "⊥": # 0x22a5 # audit-ignore - - T: "bunn" # (en: 'bottom', MathPlayer: 'up tack', google: 'botten') - - "⊦": [T: "reduseres til"] # 0x22a6 (en: 'reduces to') - - "⊧": [T: "modellerer"] # 0x22a7 (en: 'models', MathPlayer: 'models') - - "⊨": # 0x22a8 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "sant" # (en: 'true') - - "⊩": [T: "tvinger"] # 0x22a9 (en: 'forces') - - "⊪": [T: "tre vertikale streker høyre dreiekors"] # 0x22aa (en: 'triple vertical bar right turnstile') - - "⊫": [T: "dobbel vertikal strek dobbelt høyre dreiekors"] # 0x22ab (en: 'double vertical bar double right turnstile') - - "⊬": [T: "beviser ikke"] # 0x22ac (en: 'does not prove') - - "⊭": # 0x22ad - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "ikke sant" # (en: 'not true') - - "⊮": [T: "tvinger ikke"] # 0x22ae (en: 'does not force') - - "⊯": [T: "overstrøket dobbel vertikal strek dobbelt høyre dreiekors"] # 0x22af (en: 'negated double vertical bar double right turnstile') - - "⊰": [T: "foregår under relasjon"] # 0x22b0 (en: 'precedes under relation', MathPlayer: 'precedes under relation', google: 'går foran under relasjon') - - "⊱": [T: "følger under relasjon"] # 0x22b1 (en: 'succeeds under relation', MathPlayer: 'succeeds under relation', google: 'lyckas under relation') - - "⊲": # 0x22b2 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er en"] # (en: 'is', google translation) - - T: "normal undergruppe av" # (en: 'a normal subgroup of') - - "⊳": [T: "inneholder som normal undergruppe"] # 0x22b3 (en: 'contains as a normal subgroup') - - "⊴": # 0x22b4 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er en"] # (en: 'is', google translation) - - T: "normal undergruppe av eller lik" # (en: 'a normal subgroup of or equal to') - - "⊵": [T: "inneholder som normal undergruppe eller lik"] # 0x22b5 (en: 'contains as a normal subgroup or equal to') - - "⊶": # 0x22b6 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "definisjonsmengden til" # (en: 'the original of', MathPlayer: 'original of', google: 'originalet av') - - "⊷": # 0x22b7 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "verdimengden til" # (en: 'an image of', MathPlayer: 'image of', google: 'en bild av') - - "⊸": [T: "multimap"] # 0x22b8 (SRE: 'multimatris') - - "⊹": [T: "hermitisk matrise"] # 0x22b9 (SRE: 'hermetisk konjugatmatris') - - "⊺": [T: "innskudd"] # 0x22ba (en: 'intercalate', MathPlayer: 'intercalate', google: 'interkalat') - - "⊻": [T: "eksklusiv eller"] # 0x22bb (en: 'xor') - - "⊼": [T: "ikke-og"] # 0x22bc (en: 'nand') - - "⊽": [T: "ikke-eller"] # 0x22bd (en: 'nor') - - "⊾": [T: "rett vinkel med bue"] # 0x22be (en: 'right angle with arc') - - "⊿": [T: "rettvinklet trekant"] # 0x22bf (en: 'right triangle') - - "⋀": [T: "logisk og"] # 0x22c0 (en: 'logical and') - - "⋁": [T: "logisk eller"] # 0x22c1 (en: 'logical or') - # SWEDISH: misspelled to fix pronunciation - - "⋂": [T: "snitt"] # 0x22c2 (en: 'intersection') - - "⋃": [T: "union"] # 0x22c3 - - "⋄": [T: "diamant-operator"] # 0x22c4 - - "⋅": # 0x22c5 - - test: - if: "@data-chem-formula-op" - then: [T: "ganger"] # (en: 'dot', google translation) - else: [T: "ganger"] # (en: 'times') - - - "⋆": [T: "stjerne"] # 0x22c6 (en: 'times') - - "⋇": [T: "divisjon ganger"] # 0x22c7 (en: 'division times') - - "⋈": [T: "naturlig join"] # 0x22c8 (en: 'bowtie', MathPlayer: 'bowtie') - - "⋉": # 0x22c9 # audit-ignore - - T: "venstre semi-join" # (en: 'the left normal factor semidirect product of') - - "⋊": # 0x22ca # audit-ignore - - T: "høyre semi-join" # (en: 'the right normal factor semidirect product of') - - "⋋": # 0x22cb # audit-ignore - - T: "venstre semi-direkte produkt" # (en: 'the left semidirect product of') - - "⋌": # 0x22cc # audit-ignore - - T: "høyre semi-direkte produkt" # (en: 'the right semidirect product of') - - "⋍": [T: "omvendt tilde likhetstegn"] # 0x22cd (en: 'reversed tilde equals') - - "⋎": [T: "krøllete logisk eller"] # 0x22ce - - "⋏": [T: "krøllete logisk og"] # 0x22cf (en: 'curly logical and') - - "⋐": # 0x22d0 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er en"] # (en: 'is', google translation) - - T: "dobbel delmengde av" # (en: 'a double subset of') - - "⋑": # 0x22d1 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er en"] # (en: 'is', google translation) - - T: "dobbel overmengde av" # (en: 'a double superset of') - - "⋒": # 0x22d2 # audit-ignore - - T: "det doble snittet av" # (en: 'double intersection of') - - "⋓": # 0x22d3 # audit-ignore - - T: "den doble unionen av" # (en: 'double union of') - - "⋔": # 0x22d4 # audit-ignore - - T: "det ekte snittet av" # (en: 'proper intersection of', MathPlayer: 'pitchfork', google: 'korrekt skärningspunkt av') - - "⋕": # 0x22d5 # audit-ignore - - T: "lik og parallell med" # (en: 'equal to and parallel to') - - "⋖": [T: "mindre enn med prikk"] # 0x22d6 (en: 'less than with dot') - - "⋗": [T: "større enn med prikk"] # 0x22d7 (en: 'greater than with dot') - - "⋘": # 0x22d8 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "veldig mye mindre enn" # (en: 'very much less than') - - "⋙": # 0x22d9 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "veldig mye større enn" # (en: 'very much greater than') - - "⋚": # 0x22da - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "mindre enn lik eller større enn" # (en: 'less than equal to or greater than') - - "⋛": # 0x22db - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "større enn lik eller mindre enn" # (en: 'greater than equal to or less than') - - "⋜": # 0x22dc - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "lik eller mindre enn" # (en: 'equal to or less than') - - "⋝": # 0x22dd - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "lik eller større enn" # (en: 'equal to or greater than') - - "⋞": # 0x22de - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "lik eller foregår" # (en: 'equal to or precedes') - - "⋟": # 0x22df - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "lik eller følger" # (en: 'equal to or succeeds') - - "⋠": [T: "verken foregår eller er lik"] # 0x22e0 (en: 'does not precede nor is equal to') - - "⋡": [T: "verken følger eller er lik"] # 0x22e1 (en: 'does not succeed nor is equal to') - - "⋢": [T: "verken et kvadratisk bilde av eller lik"] # 0x22e2 - - "⋣": [T: "verken kvadratisk original av eller lik"] # 0x22e3 - - "⋤": [T: "kvadratisk bilde av eller ikke lik"] # 0x22e4 - - "⋥": [T: "kvadratisk original av eller ikke lik"] # 0x22e5 - - "⋦": # 0x22e6 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "mindre enn men ikke ekvivalent med" # (en: 'less than but not equivalent to') - - "⋧": # 0x22e7 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "større enn men ikke ekvivalent med" # (en: 'greater than but not equivalent to') - - "⋨": [T: "foregår men er ikke ekvivalent med"] # 0x22e8 (en: 'precedes but is not equivalent to') - - "⋩": [T: "følger men er ikke ekvivalent med"] # 0x22e9 (en: 'succeeds but is not equivalent to') - - "⋪": # 0x22ea - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "ikke en normal undergruppe av" # (en: 'not a normal subgroup of') - - "⋫": [T: "inneholder ikke som normal undergruppe"] # 0x22eb (en: 'does not contain as a normal subgroup') - - "⋬": # 0x22ec - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "verken en normal undergruppe av eller lik" # (en: 'not a normal subgroup of nor is equal to') - - "⋭": [T: "verken inneholder som normal undergruppe eller er lik"] # 0x22ed (en: 'does not contain as a normal subgroup nor is equal to') - - "⋮": [T: "vertikal ellipse"] # 0x22ee (en: 'vertical ellipsis') - - "⋯": [T: "halvhøy horisontal ellipse"] # 0x22ef (en: 'dot dot dot') - - "⋰": [T: "diagonal ellipse oppover"] # 0x22f0 (en: 'upwards diagonal ellipsis') - - "⋱": [T: "diagonal ellipse nedover"] # 0x22f1 (en: 'diagonal ellipsis') - - "⋲": [T: "tilhører med lang horisontal strek"] # 0x22f2 (en: 'element of with long horizontal stroke') - - "⋳": [T: "tilhører med vertikal strek på slutten av horisontal strek"] # 0x22f3 (en: 'element of with vertical bar at end of horizontal stroke') - - "⋴": [T: "tilhører med vertikal strek på slutten av horisontal strek"] # 0x22f4 (en: 'element of with vertical bar at end of horizontal stroke') - - "⋵": [T: "tilhører med prikk over"] # 0x22f5 (en: 'element of with dot above') - - "⋶": [T: "tilhører med strek over"] # 0x22f6 (en: 'element of with overbar') - - "⋷": [T: "tilhører med strek over"] # 0x22f7 (en: 'element of with overbar', MathPlayer: 'element of or equal to', google: 'element av med överbar') - - "⋸": [T: "tilhører med strek under"] # 0x22f8 (en: 'element of with underbar') - - "⋹": [T: "tilhører med to horisontale streker"] # 0x22f9 (en: 'element of with two horizontal strokes') - - "⋺": [T: "inneholder med lang horisontal strek"] # 0x22fa (en: 'contains with long horizontal stroke') - - "⋻": [T: "inneholder med vertikal strek på slutten av horisontal strek"] # 0x22fb (en: 'contains with vertical bar at end of horizontal stroke') - - "⋼": [T: "inneholder med vertikal strek på slutten av horisontal strek"] # 0x22fc (en: 'contains with vertical bar at end of horizontal stroke') - - "⋽": [T: "inneholder med strek over"] # 0x22fd (en: 'contains with overbar', MathPlayer: 'contains or equal to', google: 'innehåller med overbar') - - "⋾": [T: "inneholder med strek over"] # 0x22fe (en: 'contains with overbar') - - "⋿": [T: "tilhører ifølge z-notation"] # 0x22ff (en: 'z notation bag membership', MathPlayer: 'z notation bag membership', google: 'z medlemskap för notation bag') - #------------------------------------------------------------------------------------------------------------- - #Miscellaneous Technical OK - - "⌀": [T: "diameter"] # 0x2300 - - "⌁": [T: "elektrisk pil"] # 0x2301 (en: 'electric arrow') - - "⌂": [T: "hus"] # 0x2302 (en: 'house') - - "⌃": [T: "pilspiss opp"] # 0x2303 (en: 'up arrowhead', google: 'upp pilspetsen') - - "⌄": [T: "pilspiss ned"] # 0x2304 (en: 'down arrowhead', google: 'ner pilspetsen') - - "⌅": [T: "projektiv"] # 0x2305 (en: 'projective') - - "⌆": [T: "perspektiv"] # 0x2306 (en: 'perspective') - - "⌇": [T: "bølget linje"] # 0x2307 (en: 'wavy line', google: 'wavy line') - - "⌈": [T: "venstre tak"] # 0x2308 (en: 'left ceiling') - - "⌉": [T: "høyre tak"] # 0x2309 (en: 'right ceiling') - - "⌊": [T: "venstre gulv"] # 0x230a (en: 'left floor') - - "⌋": [T: "høyre gulv"] # 0x230b (en: 'right floor') - - "⌌": [T: "nedre høyre utsnitt"] # 0x230c (en: 'bottom right crop') - - "⌍": [T: "nedre venstre utsnitt"] # 0x230d (en: 'bottom left crop') - - "⌎": [T: "øvre høyre utsnitt"] # 0x230e (en: 'top right crop') - - "⌏": [T: "øvre venstre utsnitt"] # 0x230f (en: 'top left crop') - - "⌐": [T: "omvendt ikke"] # 0x2310 (en: 'reversed not sign') - - "⌑": [T: "kvadratisk rombe"] # 0x2311 (en: 'square lozenge', google: 'square pastill') - - "⌒": [T: "bue"] # 0x2312 (en: 'arc') - - "⌓": [T: "segment"] # 0x2313 - - "⌔": [T: "sektor"] # 0x2314 (en: 'sector') - - "⌕": [T: "telefonopptaker"] # 0x2315 (en: 'telephone recorder', google: 'telefoninspelare') - - "⌖": [T: "trådkors"] # 0x2316 (en: 'position indicator crosshairs', google: 'positionindikator korsstolar') - - "⌗": [T: "firkant"] # 0x2317 (google translation) - - "⌘": [T: "severdighet"] # 0x2318 (en: 'place of interest sign', google: 'plats för räntetecken') - - "⌙": [T: "rotert ikke"] # 0x2319 (en: 'turned not sign', google translation) - - "⌚": [T: "klokke"] # 0x231a (en: 'watch', google: 'kolla på') - - "⌛": [T: "timeglass"] # 0x231b (en: 'hourglass', google translation) - - "⌜": [T: "øvre venstre hjørne"] # 0x231c (en: 'top left corner') - - "⌝": [T: "øvre høyre hjørne"] # 0x231d (en: 'top right corner') - - "⌞": [T: "nedre venstre hjørne"] # 0x231e (en: 'bottom left corner') - - "⌟": [T: "nedre høyre hjørne"] # 0x231f (en: 'bottom right corner') - - "⌠": [T: "øvre halvdel integral"] # 0x2320 (en: 'top half integral') - - "⌡": [T: "nedre halvdel integral"] # 0x2321 (en: 'bottom half integral') - - "⌢": [T: "rynke"] # 0x2322 (en: 'frown', google: 'rynka pannan') - - "⌣": [T: "smil"] # 0x2323 (en: 'smile') - - "⌤": [T: "enter"] # 0x2324 (en: 'up arrowhead between two horizontal bars', google: 'upp pilspetsen mellan två horisontella staplar') - - "⌥": [T: "option-tast"] # 0x2325 (en: 'option key', google translation) - - "⌦": [T: "delete"] # 0x2326 (en: 'erase to the right', google translation) - - "⌧": [T: "clear"] # 0x2327 (en: 'x in a rectangle box', google translation) - - "⌨": [T: "tastatur"] # 0x2328 (en: 'keyboard', google translation) - - "〈": [T: "venstre vinkelparentes"] # 0x2329 (en: 'left pointing angle bracket') - - "〉": [T: "høyre vinkelparentes"] # 0x232a (en: 'right pointing angle bracket') - - "⌫": [T: "backspace"] # 0x232b (en: 'erase to the left', google translation) - - "⌬": [T: "benzenring"] # 0x232c (en: 'benzene ring', google translation) - - "⌭": [T: "sylindrisitet"] # 0x232d - - "⌮": [T: "all around profile"] # 0x232e (google: 'runt profilen') - - "⌯": [T: "symmetri"] # 0x232f (en: 'symmetry', google translation) - - "⌰": [T: "total runout"] # 0x2330 (google translation) - - "⌱": [T: "dimensjon origo"] # 0x2331 (google translation) - - "⌲": [T: "konisk avsmalning"] # 0x2332 (en: 'conical taper', google translation) - - "⌳": [T: "helning"] # 0x2333 (en: 'slope', google translation) - - "⌴": [T: "plansenkning"] # 0x2334 (en: 'counterbore', google translation) - - "⌵": [T: "forsenkning"] # 0x2335 (en: 'countersink', google translation) - - "⌶": [T: "apl i beam"] # 0x2336 - - "⌽": [T: "apl circle stile"] # 0x233d - - "⌿": [T: "apl slash bar"] # 0x233f - - "⍼": [T: "rett vinkel med nedover sikksakk-pil"] # 0x237c - - "⎔": [T: "heksagon"] # 0x2394 - - "⎶": [T: "nedre hakeparentes over øvre hakeparentes"] # 0x23b6 - - "⏜": [T: "øvre parentes"] # 0x23dc - - "⏝": [T: "nedre parentes"] # 0x23dd - - "⍰": [T: "ukjent boks"] # 0x2370 (en: 'unknown box', google: 'okänd ruta') - - "⎕": [T: "boks"] # 0x2395 (en: 'box', google translation) - - "⏞": [T: "øvre krøllparentes"] # 0x23DE (en: 'top brace') - - "⏟": [T: "nedre krøllparentes"] # 0x23DF (en: 'bottom brace') - - "⏠": [T: "øvre skilpaddeskall-parentes"] # 0x23e0 - - "⏡": [T: "nedre skilpaddeskall-parentes"] # 0x23e1 - - "⏢": [T: "hvit trapes"] # 0x23e2 - - "⏣": [T: "benzenring med sirkel"] # 0x23e3 - - "⏤": [T: "retthet"] # 0x23e4 - - "⏥": [T: "flathet"] # 0x23e5 - - "⏦": [T: "vekselstrøm"] # 0x23e6 - - "⏧": [T: "elektrisk skjæring"] # 0x23e7 - #---------------------------------------------------------------------------------------------------- - #Enclosed Alphanumerics OK - - "①-⑨": # 0x2460 - 0x2469 - # SWEDISH: switched order - - SPELL: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" - - T: "i sirkel" # (en: 'circled') - - "⑩": [T: "ti i sirkel"] # 0x2469 (en: 'circled ten', google translation) - - "⑪": [T: "elleve i sirkel"] # 0x246a (en: 'circled eleven', google translation) - - "⑫": [T: "tolv i sirkel"] # 0x246b (en: 'circled twelve', google translation) - - "⑬": [T: "tretten i sirkel"] # 0x246c (en: 'circled thirteen', google translation) - - "⑭": [T: "fjorten i sirkel"] # 0x246d (en: 'circled fourteen', google translation) - - "⑮": [T: "femten i sirkel"] # 0x246e (en: 'circled fifteen', google translation) - - "⑯": [T: "seksten i sirkel"] # 0x246f (en: 'circled sixteen', google translation) - - "⑰": [T: "sytten i sirkel"] # 0x2470 (en: 'circled seventeen', google translation) - - "⑱": [T: "atten i sirkel"] # 0x2471 (en: 'circled eighteen', google translation) - - "⑳": [T: "tjue i sirkel"] # 0x2473 (en: 'circled twenty', google translation) - - "⑴-⑼": # 0x2474 - 0x247d - # SWEDISH: switched order - - SPELL: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" - - T: "i parentes" # (en: 'parenthesized', google translation) - - "⑽": [T: "ti i parentes"] # 0x247d (en: 'parenthesized ten', google translation) - - "⑾": [T: "elleve i parentes"] # 0x247e (en: 'parenthesized eleven', google translation) - - "⑿": [T: "tolv i parentes"] # 0x247f (en: 'parenthesized twelve', google translation) - - "⒀": [T: "tretten i parentes"] # 0x2480 (en: 'parenthesized thirteen', google translation) - - "⒁": [T: "fjorten i parentes"] # 0x2481 (en: 'parenthesized fourteen', google translation) - - "⒂": [T: "femten i parentes"] # 0x2482 (en: 'parenthesized fifteen', google translation) - - "⒃": [T: "seksten i parentes"] # 0x2483 (en: 'parenthesized sixteen', google translation) - - "⒄": [T: "sytten i parentes"] # 0x2484 (en: 'parenthesized seventeen', google translation) - - "⒅": [T: "atten i parentes"] # 0x2485 (en: 'parenthesized eighteen', google translation) - - "⒆": [T: "nitten i parentes"] # 0x2486 (en: 'parenthesized nineteen', google translation) - - "⒇": [T: "tjue i parentes"] # 0x2487 (en: 'parenthesized twenty', google translation) - - "⒈-⒐": # 0x2488 - 0x2491 - - SPELL: "translate('.', '⒈⒉⒊⒋⒌⒍⒎⒏⒐', '123456789')" - - T: "med punktum" # (en: 'with period', google translation) - - "⒑": [T: "ti med punktum"] # 0x2491 (en: 'ten with period', google translation) - - "⒒": [T: "elleve med punktum"] # 0x2492 (en: 'eleven with period', google translation) - - "⒓": [T: "tolv med punktum"] # 0x2493 (en: 'twelve with period', google translation) - - "⒔": [T: "tretten med punktum"] # 0x2494 (en: 'thirteen with period', google translation) - - "⒕": [T: "fjorten med punktum"] # 0x2495 (en: 'fourteen with period', google translation) - - "⒖": [T: "femten med punktum"] # 0x2496 (en: 'fifteen with period', google translation) - - "⒗": [T: "seksten med punktum"] # 0x2497 (en: 'sixteen with period', google translation) - - "⒘": [T: "sytten med punktum"] # 0x2498 (en: 'seventeen with period', google translation) - - "⒙": [T: "atten med punktum"] # 0x2499 (en: 'eighteen with period', google translation) - - "⒚": [T: "nitten med punktum"] # 0x249a (en: 'nineteen with period', google translation) - - "⒛": [T: "tjue med punktum"] # 0x249b (en: 'twenty with period', google translation) - - "⒜-⒵": # 0x249c - 0x24b5 - # SWEDISH: switched order - - SPELL: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" - - T: "i parentes" # (en: 'parenthesized', google translation) - - - "Ⓐ-Ⓩ": # 0x24b6 - 0x24cf - # SWEDISH: switched order - - SPELL: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - T: "i sirkel" # (en: 'circled', google translation) - - - "🅐-🅩": # 0x1f150 - 0x1f169 - # switched order - - SPELL: "translate('.', '🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - T: "i fylt sirkel" # (en: 'black circled', google translation) - - - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 - # SWEDISH: switched order - - SPELL: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" - - T: "i sirkel" # (en: 'circled', google translation) - - "⓪": [T: "null i sirkel"] # 0x24ea (google translation) - - "⓫": [T: "elleve i fylt sirkel"] # 0x24eb (en: 'black circled eleven', google translation) - - "⓬": [T: "tolv i fylt sirkel"] # 0x24ec (en: 'black circled twelve', google translation) - - "⓭": [T: "tretten i fylt sirkel"] # 0x24ed (en: 'black circled thirteen', google translation) - - "⓮": [T: "fjorten i fylt sirkel"] # 0x24ee (en: 'black circled fourteen', google translation) - - "⓯": [T: "femten i fylt sirkel"] # 0x24ef (en: 'black circled fifteen', google translation) - - "⓰": [T: "seksten i fylt sirkel"] # 0x24f0 (en: 'black circled sixteen', google translation) - - "⓱": [T: "sytten i fylt sirkel"] # 0x24f1 (en: 'black circled seventeen', google translation) - - "⓲": [T: "atten i fylt sirkel"] # 0x24f2 (en: 'black circled eighteen', google translation) - - "⓳": [T: "nitten i fylt sirkel"] # 0x24f3 (en: 'black circled nineteen', google translation) - - "⓴": [T: "tjue i fylt sirkel"] # 0x24f4 (en: 'black circled twenty', google translation) - - "⓵-⓽": # 0x24f5 - 0x24fe - # SWEDISH: switched order - - SPELL: "translate('.', '⓵⓶⓷⓸⓹⓺⓻⓼⓽', '123456789')" - - T: "i dobbel sirkel" # (en: 'double circled', google translation) - - "⓾": [T: "ti i dobbel sirkel"] # 0x24fe (en: 'double circled ten', google translation) - - "⓿": [T: "null i fylt sirkel"] # 0x24ff (en: 'black circled zero', google translation) - #------------------------------------------------------------------------------------------------------------------ - #Geometric shapes OK - - "■": [T: "svart kvadrat"] # 0x25a0 (en: 'black square') - - "□": [T: "hvitt kvadrat"] # 0x25a1 (en: 'white square') - - "▢": [T: "hvitt kvadrat med avrundede hjørner"] # 0x25a2 (en: 'white square with rounded corners', google: 'vit fyrkant med rundade hörn') - - "▣": [T: "lite svart kvadrat i hvitt kvadrat"] # 0x25a3 (en: 'white square containing small black square', google: 'vit fyrkant som innehåller en liten svart fyrkant') - - "▤": [T: "kvadrat med horisontalt fyll"] # 0x25a4 (en: 'square with horizontal fill', google: 'fyrkantig med horisontell fyllning') - - "▥": [T: "kvadrat med vertikalt fyll"] # 0x25a5 (en: 'square with vertical fill', google: 'fyrkantig med vertikal fyllning') - - "▦": [T: "kvadrat med ortogonal skravering"] # 0x25a6 (en: 'square with orthogonal crosshatch fill', google: 'fyrkantig med ortogonal crosshatch -fyllning') - - "▧": [T: "kvadrat med fyll fra øvre venstre til nedre høyre"] # 0x25a7 (en: 'square with upper left to lower right fill', google: 'fyrkantig med övre vänster till nedre högra fyllning') - - "▨": [T: "kvadrat med fyll fra øvre høyre til nedre venstre"] # 0x25a8 (en: 'square with upper right to lower left fill', google: 'fyrkantig med övre höger till nedre vänsterfyllning') - - "▩": [T: "kvadrat med diagonal skravering"] # 0x25a9 (en: 'square with diagonal crosshatch fill', google: 'fyrkantig med diagonal korshatchfyllning') - - "▪": [T: "lite svart kvadrat"] # 0x25aa (en: 'black small square') - - "▫": [T: "lite hvitt kvadrat"] # 0x25ab (en: 'white small square') - - "▬": [T: "svart rektangel"] # 0x25ac (en: 'black rectangle') - - "▭": [T: "hvitt rektangel"] # 0x25ad (en: 'white rectangle') - - "▮": [T: "svart vertikalt rektangel"] # 0x25ae (en: 'black vertical rectangle') - - "▯": [T: "hvitt vertikalt rektangel"] # 0x25af (en: 'white vertical rectangle') - - "▰": [T: "svart parallellogram"] # 0x25b0 (en: 'black parallelogram') - - "▱": [T: "hvitt parallellogram"] # 0x25b1 (en: 'white parallelogram') - - "▲": [T: "svart oppoverpekende trekant"] # 0x25b2 (en: 'black up pointing triangle') - - "△": [T: "hvit oppoverpekende trekant"] # 0x25b3 (en: 'white up pointing triangle') - - "▴": [T: "liten svart oppoverpekende trekant"] # 0x25b4 (en: 'black up pointing small triangle') - - "▵": [T: "liten hvit oppoverpekende trekant"] # 0x25b5 (en: 'white up pointing small triangle') - - "▶": [T: "svart høyrepekende trekant"] # 0x25b6 (en: 'black right pointing triangle') - - "▷": [T: "hvit høyrepekende trekant"] # 0x25b7 (en: 'white right pointing triangle') - - "▸": [T: "liten svart høyrepekende trekant"] # 0x25b8 (en: 'black right pointing small triangle') - - "▹": [T: "liten hvit høyrepekende trekant"] # 0x25b9 (en: 'white right pointing small triangle') - - "►": [T: "svart høyre-peker"] # 0x25ba (en: 'black right pointing pointer', google: 'svart höger pekande pekare') - - "▻": [T: "hvit høyre-peker"] # 0x25bb (en: 'white right pointing pointer', google: 'vit höger pekande pekare') - - "▼": [T: "svart nedoverpekende trekant"] # 0x25bc (en: 'black down pointing triangle', MathPlayer: 'svart triangel med spetsen neråt', google: 'svart ner pekande triangel') - - "▽": [T: "hvit nedoverpekende trekant"] # 0x25bd (en: 'white down pointing triangle', MathPlayer: 'vit triangel med spetsen neråt', google: 'vit ner pekande triangel') - - "▾": [T: "liten svart nedoverpekende trekant"] # 0x25be (en: 'black down pointing small triangle', MathPlayer: 'svart triangel med spetsen neråt', google: 'svart ner pekande liten triangel') - - "▿": [T: "liten hvit nedoverpekende trekant"] # 0x25bf (en: 'white down pointing small triangle', MathPlayer: 'vit triangel med spetsen neråt', google: 'vit ner pekande liten triangel') - - "◀": [T: "svart venstrepekende trekant"] # 0x25c0 (en: 'black left pointing triangle') - - "◁": [T: "hvit venstrepekende trekant"] # 0x25c1 (en: 'white left pointing triangle') - - "◂": [T: "liten svart venstrepekende trekant"] # 0x25c2 (en: 'black left pointing small triangle') - - "◃": [T: "liten hvit venstrepekende trekant"] # 0x25c3 (en: 'white left pointing small triangle') - - "◄": [T: "svart venstre-peker"] # 0x25c4 (en: 'black left pointing pointer') - - "◅": [T: "hvit venstre-peker"] # 0x25c5 (en: 'white left pointing pointer') - - "◆": [T: "svart diamant"] # 0x25c6 (en: 'black diamond') - - "◇": [T: "hvit diamant"] # 0x25c7 (en: 'white diamond') - - "◈": [T: "svart diamant i hvit diamant"] # 0x25c8 (en: 'white diamond containing black small diamond') - - "◉": [T: "fiskeøye"] # 0x25c9 (en: 'fisheye') - - "◊": [T: "rombe"] # 0x25ca (en: 'lozenge') - - "○": [T: "hvit sirkel"] # 0x25cb (en: 'white circle') - - "◌": [T: "stiplet sirkel"] # 0x25cc (en: 'dotted circle') - - "◍": [T: "sirkel med vertikalt fyll"] # 0x25cd (en: 'circle with vertical fill') - - "◎": [T: "bullseye"] # 0x25ce (SRE: 'mitt-i-prick') - - "●": [T: "svart sirkel"] # 0x25cf (en: 'black circle') - - "◐": [T: "sirkel med venstre halvdel fylt"] # 0x25d0 (en: 'circle with left half black') - - "◑": [T: "sirkel med høyre halvdel fylt"] # 0x25d1 (en: 'circle with right half black') - - "◒": [T: "sirkel med nedre halvdel fylt"] # 0x25d2 (en: 'circle with lower half black') - - "◓": [T: "sirkel med øvre halvdel fylt"] # 0x25d3 (en: 'circle with upper half black') - - "◔": [T: "sirkel med øvre høyre kvadrant fylt"] # 0x25d4 (en: 'circle with upper right quadrant black') - - "◕": [T: "sirkel fylt bortsett fra øvre venstre kvadrant"] # 0x25d5 (en: 'circle with all but upper left quadrant black') - - "◖": [T: "venstre halvsirkel"] # 0x25d6 (en: 'left half black circle') - - "◗": [T: "høyre halvsirkel"] # 0x25d7 (en: 'right half black circle') - - "◘": [T: "invertert punkt"] # 0x25d8 (en: 'inverse bullet') - - "◙": [T: "invertert hvit sirkel"] # 0x25d9 (en: 'inverse white circle') - - "◚": [T: "invertert hvit øvre halvsirkel"] # 0x25da (en: 'upper half inverse white circle') - - "◛": [T: "invertert hvit nedre halvsirkel"] # 0x25db (en: 'lower half inverse white circle') - - "◜": [T: "øvre venstre kvadrant av sirkelbue"] # 0x25dc (en: 'upper left quadrant circular arc') - - "◝": [T: "øvre høyre kvadrant av sirkelbue"] # 0x25dd (en: 'upper right quadrant circular arc') - - "◞": [T: "nedre høyre kvadrant av sirkelbue"] # 0x25de (en: 'lower right quadrant circular arc') - - "◟": [T: "nedre venstre kvadrant av sirkelbue"] # 0x25df (en: 'lower left quadrant circular arc') - - "◠": [T: "øvre halvsirkel"] # 0x25e0 (en: 'upper half circle') - - "◡": [T: "nedre halvsirkel"] # 0x25e1 (en: 'lower half circle') - - "◢": [T: "svart trekant ned til høyre"] # 0x25e2 (en: 'black lower right triangle', MathPlayer: 'svart triangel neråt höger', google: 'svart nedre höger triangel') - - "◣": [T: "svart trekant ned til venstre"] # 0x25e3 (en: 'black lower left triangle', MathPlayer: 'svart triangel neråt vänster', google: 'svart nedre vänster triangel') - - "◤": [T: "svart trekant oppe til venstre"] # 0x25e4 (en: 'black upper left triangle') - - "◥": [T: "svart trekant oppe til høyre"] # 0x25e5 (en: 'black upper right triangle') - - "◦": [T: "hvitt punkt"] # 0x25e6 (en: 'composition') - - "◧": [T: "kvadrat med venstre halvdel fylt"] # 0x25e7 (en: 'square with left half black') - - "◨": [T: "kvadrat med høyre halvdel fylt"] # 0x25e8 (en: 'square with right half black') - - "◩": [T: "kvadrat med øvre venstre halvdel fylt"] # 0x25e9 (en: 'square with upper left half black') - - "◪": [T: "kvadrat med nedre høyre halvdel fylt"] # 0x25ea (en: 'square with lower right half black') - - "◫": [T: "hvitt kvadrat med midtlinje"] # 0x25eb (en: 'white square with bisecting line') - - "◬": [T: "hvit oppoverpekende trekant med prikk"] # 0x25ec (en: 'white up pointing triangle with dot') - - "◭": [T: "oppoverpekende trekant med venstre halvdel fylt"] # 0x25ed (en: 'up pointing triangle with left half black') - - "◮": [T: "oppoverpekende trekant med høyre halvdel fylt"] # 0x25ee (en: 'up pointing triangle with right half black') - - "◯": [T: "stor sirkel"] # 0x25ef (en: 'large circle') - - "◰": [T: "hvitt kvadrat med øvre venstre kvadrant"] # 0x25f0 (en: 'white square with upper left quadrant', google: 'vit fyrkant med övre vänstra kvadrant') - - "◱": [T: "hvitt kvadrat med nedre venstre kvadrant"] # 0x25f1 (en: 'white square with lower left quadrant', google: 'vit fyrkant med nedre vänster kvadrant') - - "◲": [T: "hvitt kvadrat med nedre høyre kvadrant"] # 0x25f2 (en: 'white square with lower right quadrant', google: 'vit fyrkant med nedre högra kvadrant') - - "◳": [T: "hvitt kvadrat med øvre høyre kvadrant"] # 0x25f3 (en: 'white square with upper right quadrant', google: 'vit fyrkant med övre högra kvadrant') - - "◴": [T: "hvit sirkel med øvre venstre kvadrant"] # 0x25f4 (en: 'white circle with upper left quadrant', google: 'vit cirkel med övre vänstra kvadrant') - - "◵": [T: "hvit sirkel med nedre venstre kvadrant"] # 0x25f5 (en: 'white circle with lower left quadrant') - - "◶": [T: "hvit sirkel med nedre høyre kvadrant"] # 0x25f6 (en: 'white circle with lower right quadrant', google: 'vit cirkel med nedre högra kvadrant') - - "◷": [T: "hvit sirkel med øvre høyre kvadrant"] # 0x25f7 (en: 'white circle with upper right quadrant', google: 'vit cirkel med övre högra kvadrant') - - "◸": [T: "trekant oppe til venstre"] # 0x25f8 (en: 'upper left triangle') - - "◹": [T: "trekant oppe til høyre"] # 0x25f9 (en: 'upper right triangle') - - "◺": [T: "trekant ned til venstre"] # 0x25fa (en: 'lower left triangle') - - "◻": [T: "mellomstort hvitt kvadrat"] # 0x25fb (en: 'white medium square') - - "◼": [T: "mellomstort svart kvadrat"] # 0x25fc (en: 'black medium square') - - "◽": [T: "hvitt middels lite kvadrat"] # 0x25fd (en: 'white medium small square') - - "◾": [T: "svart middels lite kvadrat"] # 0x25fe (en: 'black medium small square') - - "◿": [T: "trekant ned til høyre"] # 0x25ff (en: 'lower right triangle') - #------------------------------------------------------------------------------------------------ - #Miscellaneous symbols OK - - "★": [T: "svart stjerne"] # 0x2605 - - "☆": [T: "hvit stjerne"] # 0x2606 - - "☉": [T: "sol"] # 0x2609 - - "☌": [T: "konjunksjon"] # 0x260c - - "☒": [T: "avkrysningsboks med kryss"] # 0x2612 - - "☽": [T: "tiltagende måne"] # 0x263d - - "☾": [T: "avtagende måne"] # 0x263e - - "☿": [T: "merkur"] # 0x263f - - "♀": [T: "kvinne"] # 0x2640 - - "♁": [T: "jorda"] # 0x2641 - - "♂": [T: "mann"] # 0x2642 - - "♃": [T: "jupiter"] # 0x2643 - - "♄": [T: "saturn"] # 0x2644 - - "♅": [T: "uranus"] # 0x2645 - - "♆": [T: "neptun"] # 0x2646 - - "♇": [T: "pluto"] # 0x2647 - - "♈": [T: "væren"] # 0x2648 - - "♉": [T: "tyren"] # 0x2649 - - "♩": [T: "fjerdedelsnote"] # 0x2669 - - "♭": [T: "musikalsk b"] # 0x266d - - "♮": [T: "musikalsk oppløsningstegn"] # 0x266e - - "♯": [T: "musikalsk kryss"] # 0x266f - - "♠": [T: "svart spar"] # 0x2660 (en: 'black spade suit', google: 'svart spade kostym') - - "♡": [T: "hvit hjerter"] # 0x2661 (en: 'white heart suit', google: 'vit hjärtdräkt') - - "♢": [T: "hvit ruter"] # 0x2662 (en: 'white diamond suit', google: 'vit diamantdräkt') - - "♣": [T: "svart kløver"] # 0x2663 (en: 'black club suit', google: 'svart klubbdräkt') - - "♤": [T: "hvit spar"] # 0x2664 (en: 'white spade suit', google: 'vit spade kostym') - - "♥": [T: "svart hjerter"] # 0x2665 (en: 'black heart suit', google: 'black heart suit') - - "♦": [T: "svart ruter"] # 0x2666 (en: 'black diamond suit', google: 'svart diamantdräkt') - - "♧": [T: "hvit kløver"] # 0x2667 (en: 'white club suit', google: 'vit klubbdräkt') - - "⚀": [T: "terningkast 1"] # 0x2680 - - "⚁": [T: "terningkast 2"] # 0x2681 - - "⚂": [T: "terningkast 3"] # 0x2682 - - "⚃": [T: "terningkast 4"] # 0x2683 - - "⚄": [T: "terningkast 5"] # 0x2684 - - "⚅": [T: "terningkast 6"] # 0x2685 - - "⚆": [T: "hvit sirkel med prikk til høyre"] # 0x2686 - - "⚇": [T: "hvit sirkel med to prikker"] # 0x2687 - - "⚈": [T: "svart sirkel med prikk til høyre"] # 0x2688 - - "⚉": [T: "svart sirkel med to prikker"] # 0x2689 - - "⚪": [T: "mellomstor hvit sirkel"] # 0x26aa - - "⚫": [T: "mellomstor svart sirkel"] # 0x26ab - - "⚬": [T: "middels liten hvit sirkel"] # 0x26ac - - "⚲": [T: "nøytral"] # 0x26b2 - - #------------------------------------------------------------------------------------------------ - #Dingbats OK - - "✓": [T: "avkrysningshake"] # 0x2713 - - "✠": [T: "malteserkors"] # 0x2720 - - "✪": [T: "sirkel med hvit stjerne"] # 0x272a - - "✶": [T: "svart heksagram"] # 0x2736 - - "❨": [T: "venstreparentes"] # 0x2768 (en: 'medium left parentheses ornament', google: 'medium vänster-parentesesprydnad') - - "❩": [T: "høyreparentes"] # 0x2769 (en: 'medium right parentheses ornament', google: 'medium höger parentesetheses ornament') - - "❪": [T: "avflatet venstreparentes"] # 0x276a (en: 'medium flattened left parentheses ornament', google: 'medium plattad vänster parentese -prydnad') - - "❫": [T: "avflatet høyreparentes"] # 0x276b (en: 'medium flattened right parentheses ornament', google: 'medium platta höger parentesetheses prydnad') - - "❬": [T: "venstre vinkel-parentes"] # 0x276c (en: 'medium left-pointing angle bracket ornament', google: 'medium vänsterpekande vinkelfäste prydnad') - - "❭": [T: "høyre vinkel-parentes"] # 0x276d (en: 'medium right-pointing angle bracket ornament', google: 'medium högerpekande vinkelfäste prydnad') - - "❮": [T: "fet venstre anførselstegn"] # 0x276e (en: 'heavy left-pointing angle quotation mark ornament', google: 'tung vänsterpekande vinkelcitationsmärke prydnad') - - "❯": [T: "fet høyre anførselstegn"] # 0x276f (en: 'heavy right-pointing angle quotation mark ornament', google: 'tung högerpekande vinkelcitationsmärke prydnad') - - "❰": [T: "fet venstre vinkel-parentes"] # 0x2770 (en: 'heavy left-pointing angle bracket ornament', google: 'tung vänsterpekande vinkelfäste prydnad') - - "❱": [T: "fet høyre vinkel-parentes"] # 0x2771 (en: 'heavy right-pointing angle bracket ornament', google: 'tung högerpekande vinkelfäste prydnad') - - "❲": [T: "venstre skilpaddeskall-parentes"] # 0x2772 (en: 'light left tortoise shell bracket ornament', google: 'ljus vänster sköldpaddsskalfäste prydnad') - - "❳": [T: "høyre skilpaddeskall-parentes"] # 0x2773 (en: 'light right tortoise shell bracket ornament', google: 'lätt höger sköldpaddsskalfäste prydnad') - - "❴": [T: "fet venstre krøllparentes"] # 0x2774 (en: 'medium left brace ornament', google: 'medium vänster stagprydnad') - - "❵": [T: "fet høyre krøllparentes"] # 0x2775 (en: 'medium right brace ornament', google: 'medium höger stagprydnad') - - "❶": [T: "én i fylt sirkel"] # 0x2776 (en: 'black circled one', google translation) - - "❷": [T: "to i fylt sirkel"] # 0x2777 (en: 'black circled two', google translation) - - "❸": [T: "tre i fylt sirkel"] # 0x2778 (en: 'black circled three', google translation) - - "❹": [T: "fire i fylt sirkel"] # 0x2779 (en: 'black circled four', google translation) - - "❺": [T: "fem i fylt sirkel"] # 0x277a (en: 'black circled five', google translation) - - "❻": [T: "seks i fylt sirkel"] # 0x277b (en: 'black circled six', google translation) - - "❼": [T: "sju i fylt sirkel"] # 0x277c (en: 'black circled seven', google translation) - - "❽": [T: "åtte i fylt sirkel"] # 0x277d (en: 'black circled eight', google translation) - - "❾": [T: "ni i fylt sirkel"] # 0x277e (en: 'black circled nine', google translation) - - "❿": [T: "ti i fylt sirkel"] # 0x277f (en: 'black circled ten', google translation) - - "➀": [T: "sans-serif én i sirkel"] # 0x2780 (en: 'circled sans serif one', google translation) - - "➁": [T: "sans-serif to i sirkel"] # 0x2781 (en: 'circled sans serif two', google translation) - - "➂": [T: "sans-serif tre i sirkel"] # 0x2782 (en: 'circled sans serif three', google translation) - - "➃": [T: "sans-serif fire i sirkel"] # 0x2783 (en: 'circled sans serif four', google translation) - - "➄": [T: "sans-serif fem i sirkel"] # 0x2784 (en: 'circled sans serif five', google translation) - - "➅": [T: "sans-serif seks i sirkel"] # 0x2785 (google translation) - - "➆": [T: "sans-serif sju i sirkel"] # 0x2786 (en: 'circled sans serif seven', google translation) - - "➇": [T: "sans-serif åtte i sirkel"] # 0x2787 (en: 'circled sans serif eight', google translation) - - "➈": [T: "sans-serif ni i sirkel"] # 0x2788 (en: 'circled sans serif nine', google translation) - - "➉": [T: "sans-serif ti i sirkel"] # 0x2789 (en: 'circled sans serif ten', google translation) - - "➊": [T: "sans-serif én i fylt sirkel"] # 0x278a (en: 'black circled sans serif one', google translation) - - "➋": [T: "sans-serif to i fylt sirkel"] # 0x278b (en: 'black circled sans serif two', google translation) - - "➌": [T: "sans-serif tre i fylt sirkel"] # 0x278c (en: 'black circled sans serif three', google translation) - - "➍": [T: "sans-serif fire i fylt sirkel"] # 0x278d (google translation) - - "➎": [T: "sans-serif fem i fylt sirkel"] # 0x278e (google translation) - - "➏": [T: "sans-serif seks i fylt sirkel"] # 0x278f (google translation) - - "➐": [T: "sans-serif sju i fylt sirkel"] # 0x2790 (google translation) - - "➑": [T: "sans-serif åtte i fylt sirkel"] # 0x2791 (en: 'black circled sans serif eight', google translation) - - "➒": [T: "sans-serif ni i fylt sirkel"] # 0x2792 (en: 'black circled sans serif nine', google translation) - - "➓": [T: "sans-serif ti i fylt sirkel"] # 0x2793 (google translation) - - "➔": [T: "fet høyrepil"] # 0x2794 (en: 'heavy wide-headed rightwards arrow', google: 'tungt huvud med höger om höger pil') - - "➕": [T: "fet pluss"] # 0x2795 (en: 'heavy plus sign', google: 'tungt plus -tecken') - - "➖": [T: "fet minus"] # 0x2796 (en: 'heavy minus sign', google: 'tung minusskylt') - - "➗": [T: "fet division"] # 0x2797 (en: 'heavy division sign', google: 'tung uppdelningstecken') - - "➘": [T: "fet sørøst-pil"] # 0x2798 (en: 'heavy south east arrow', google: 'tung south east arrow') - - "➙": [T: "fet høyrepil"] # 0x2799 (en: 'heavy rightwards arrow', google: 'tung åt höger-pil') - - "➚": [T: "fet nordøst-pil"] # 0x279a (en: 'heavy north east arrow', google: 'tung north east arrow') - - "➛": [T: "høyrepil"] # 0x279b (en: 'drafting point rightwards arrow', google: 'utarbetningspunkt åt höger pil') - - "➜": [T: "fet høyrepil med avrundet spiss"] # 0x279c (en: 'heavy round-tipped rightwards arrow', google: 'tung rundtippad höger-pil') - - "➝": [T: "høyrepil"] # 0x279d (en: 'triangle-headed rightwards arrow', google: 'triangelhuvud med höger pil') - - "➞": [T: "fet høyrepil"] # 0x279e (en: 'heavy triangle-headed rightwards arrow', google: 'tung triangelhuvud med höger pil') - - "➟": [T: "stiplet høyrepil"] # 0x279f (en: 'dashed triangle-headed rightwards arrow', google: 'streckad triangelhuvud med höger pil') - - "➠": [T: "fet stiplet høyrepil"] # 0x27a0 (en: 'heavy dashed triangle-headed rightwards arrow', google: 'tung streckad triangelhuvud med höger pil') - - "➡": [T: "høyrepil"] # 0x27a1 (en: 'black rightwards arrow', google: 'black rightwards arrow') - - "➢": [T: "3D-høyrepil med lys øvre del"] # 0x27a2 (en: 'three d top lighted rightwards arrow', google: 'tre d topplyst höger pil') - - "➣": [T: "3D-høyrepil med lys nedre del"] # 0x27a3 (en: 'three d bottom lighted rightwards arrow', google: 'tre d botten tände höger pil') - - "➤": [T: "pilspiss til høyre"] # 0x27a4 (en: 'black rightwards arrowhead', google: 'svart höger pilspets') - - "➥": [T: "fet høyrepil med hale oppover"] # 0x27a5 (en: 'heavy black curved downwards and rightwards arrow', google: 'tung svart krökt nedåt och höger-pil') - - "➦": [T: "fet høyrepil med hale nedover"] # 0x27a6 (en: 'heavy black curved upwards and rightwards arrow', google: 'tung svart krökt uppåt och pil med höger') - - "➧": [T: "kompakt høyrepil"] # 0x27a7 (en: 'squat black rightwards arrow', google: 'squat black rightwards arrow') - - "➨": [T: "fet høyrepil med konkav spiss"] # 0x27a8 (en: 'heavy concave-pointed black rightwards arrow', google: 'tung konkavspetsad svart höger-pil') - - "➩": [T: "høyre-skyggelagt hvit høyrepil"] # 0x27a9 (en: 'right-shaded white rightwards arrow', google: 'högerskuggad vit åt höger pil') - - "➪": [T: "venstre-skyggelagt hvit høyrepil"] # 0x27aa (en: 'left-shaded white rightwards arrow', google: 'vänsterskuggad vit åt höger pil') - - "➫": [T: "bakovervippet skyggelagt hvit høyrepil"] # 0x27ab (en: 'back-tilted shadowed white rightwards arrow', google: 'back-tiled shadowed white rightward arrow') - - "➬": [T: "fremoverlent skyggelagt hvit høyrepil"] # 0x27ac (en: 'front-tilted shadowed white rightwards arrow', google: 'front-lutad skuggad vit höger pil') - - "➭": [T: "hvit høyrepil skyggelagt under"] # 0x27ad (en: 'heavy lower right-shadowed white rightwards arrow', google: 'tung nedre högerskuggad vit höger pil') - - "➮": [T: "hvit høyrepil skyggelagt over"] # 0x27ae (en: 'heavy upper right-shadowed white rightwards arrow', google: 'tung övre högra skuggade vita höger-pil') - - "➯": [T: "hvit høyrepil med hakk skyggelagt under"] # 0x27af (en: 'notched lower right-shadowed white rightwards arrow', google: 'skåpad nedre högerskuggad vit åt höger pil') - - "➱": [T: "hvit høyrepil med hakk skyggelagt over"] # 0x27b1 (en: 'notched upper right-shadowed white rightwards arrow', google: 'skärmad övre högra skuggade vita höger-pil') - - "➲": [T: "fet hvit høyrepil med sirkel"] # 0x27b2 (en: 'circled heavy white rightwards arrow', google: 'circled heavy white rightwards arrow') - - "➳": [T: "hvit høyrepil med fjær"] # 0x27b3 (en: 'white-feathered rightwards arrow', google: 'vitfödd åt höger pil') - - "➴": [T: "sørøst-pil med fjær"] # 0x27b4 (en: 'black-feathered south east arrow', google: 'svartfödd south east arrow') - - "➵": [T: "høyrepil med fjær"] # 0x27b5 (en: 'black-feathered rightwards arrow', google: 'black-feeded rightwards arrow') - - "➶": [T: "nordøst-pil med fjær"] # 0x27b6 (en: 'black-feathered north east arrow', google: 'svartfödd nord-ostra pilen') - - "➷": [T: "fet sørøst-pil med fjær"] # 0x27b7 (en: 'heavy black-feathered south east arrow', google: 'tung svartfönad syd-ostpil') - - "➸": [T: "fet høyrepil med fjær"] # 0x27b8 (en: 'heavy black-feathered rightwards arrow', google: 'tung svartfjäder med höger pil') - - "➹": [T: "fet nordøst-pil med fjær"] # 0x27b9 (en: 'heavy black-feathered north east arrow', google: 'tung svartfönad nord-ostra pilen') - - "➺": [T: "høyrepil med mothaker"] # 0x27ba (en: 'teradrop-barbed rightwards arrow', google: 'teradrop-barbed till höger pil') - - "➻": [T: "tåreformet høyrepil"] # 0x27bb (en: 'heavy teardrop-shanked rightwards arrow', google: 'tung teardrop-shanked höger-pil') - - "➼": [T: "høyrepil med kileformet hale"] # 0x27bc (en: 'wedge-tailed rightwards arrow', google: 'wedge-tailed åt höger pil') - - "➽": [T: "fet høyrepil med kileformet hale"] # 0x27bd (en: 'heavy wedge-tailed rightwards arrow', google: 'tung kil-tailed höger-pil') - - "➾": [T: "høyrepil med åpne konturer"] # 0x27be (en: 'open-outlined rightwards arrow', google: 'öppen-outlinerad höger-pil') - #---------------------------------------------------------------------------------------------------------------------------------- - #Miscellaneous mathematical symbols-A OK - - "⟀": [T: "tredimensjonal vinkel"] # 0x27c0 (en: 'three dimensional angle') - - "⟁": [T: "hvit trekant med liten hvit trekant"] # 0x27c1 (en: 'white triangle containing small white triangle') - - "⟂": # 0x27c2 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "vinkelrett på" # (en: 'perpendicular to') - - "⟃": # 0x27c3 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er en"] # (en: 'is', google translation) - - T: "åpen delmengde av" # (en: 'an open subset of') - - "⟄": # 0x27c4 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er en"] # (en: 'is', google translation) - - T: "åpen overmengde av" # (en: 'an open superset of') - - "⟅": [T: "venstre s-formet bag delimiter"] # 0x27c5 (en: 'left s-shaped bag delimiter') - - "⟆": [T: "høyre s-formet bag delimiter"] # 0x27c6 (en: 'right s-shaped bag delimiter') - - "⟇": [T: "eller med prikk"] # 0x27c7 (en: 'or with dot inside') - - "⟈": [T: "omvendt skråstrek før delmengde"] # 0x27c8 (en: 'reverse solidus preceding subset') - - "⟉": [T: "overmengde før skråstrek"] # 0x27c9 (en: 'superset preceding solidus') - - "⟊": [T: "vertikal strek med horisontal strek"] # 0x27ca (en: 'vertical bar with horizontal stroke') - - "⟋": [T: "stigende diagonal"] # 0x27cb (en: 'mathematical rising diagonal', google: 'matematisk stigande diagonal') - - "⟌": [T: "lang divisjon"] # 0x27cc (en: 'long division') - - "⟍": [T: "synkende diagonal"] # 0x27cd (en: 'mathematical falling diagonal', google: 'matematisk fallande diagonal') - - "⟎": [T: "logisk og i kvadrat"] # 0x27ce (en: 'squared logical and', google: 'squared logical och') - - "⟏": [T: "logisk eller i kvadrat"] # 0x27cf (en: 'squared logical or', google: 'kvadratiska logiska eller') - - "⟐": [T: "hvit diamant med prikk i midten"] # 0x27d0 (en: 'white diamond with centered dot', google: 'vit diamant med centrerad prick') - - "⟑": [T: "og med prikk"] # 0x27d1 (en: 'and with dot') - - "⟒": [T: "tilhører med åpning oppover"] # 0x27d2 (en: 'element of opening upwards') - - "⟓": [T: "nedre høyre hjørne med prikk"] # 0x27d3 (en: 'lower right corner with dot') - - "⟔": [T: "øvre venstre hjørne med prikk"] # 0x27d4 (en: 'upper left corner with dot') - - "⟕": [T: "venstre outer join"] # 0x27d5 (en: 'left outer join') - - "⟖": [T: "høyre outer join"] # 0x27d6 (en: 'right outer join') - - "⟗": [T: "full outer join"] # 0x27d7 (en: 'full outer join') - - "⟘": [T: "stort oppoverrotert dreiekors"] # 0x27d8 (en: 'large up tack') - - "⟙": [T: "stort nedoverrotert dreiekors"] # 0x27d9 (en: 'large down tack') - - "⟚": [T: "venstre og høyre dobbelt dreiekors"] # 0x27da (en: 'left and right double turnstile') - - "⟛": [T: "venstre og høyre dreiekors"] # 0x27db (en: 'left and right tack') - - "⟜": [T: "venstre multimap"] # 0x27dc (en: 'left multimap') - - "⟝": [T: "langt høyre dreiekors"] # 0x27dd (en: 'long right tack') - - "⟞": [T: "langt venstre dreiekors"] # 0x27de (en: 'long left tack') - - "⟟": [T: "oppoverrotert dreiekors med sirkel over"] # 0x27df (en: 'up tack with circle above') - - "⟠": [T: "rombe delt med horisontal strek"] # 0x27e0 (en: 'lozenge divided by horizontal rule') - - "⟡": [T: "hvit konkav-sidet diamant"] # 0x27e1 (en: 'white concave sided diamond') - - "⟢": [T: "hvit konkav-sidet diamant med strek til venstre"] # 0x27e2 (en: 'white concave sided diamond with leftwards tick') - - "⟣": [T: "hvit konkav-sidet diamant med strek til høyre"] # 0x27e3 (en: 'white concave sided diamond with rightwards tick') - - "⟤": [T: "hvitt kvadrat med strek til venstre"] # 0x27e4 (en: 'white square with leftwards tick') - - "⟥": [T: "hvitt kvadrat med strek til høyre"] # 0x27e5 (en: 'white square with rightwards tick') - - "⟦": [T: "hvit venstre hakeparentes"] # 0x27e6 (en: 'left white square bracket') - - "⟧": [T: "hvit høyre hakeparentes"] # 0x27e7 (en: 'right white square bracket') - - "⟨": [T: "venstre vinkel-parentes"] # 0x27e8 (en: 'left angle bracket') - - "⟩": [T: "høyre vinkel-parentes"] # 0x27e9 (en: 'right angle bracket') - - "⟪": [T: "venstre dobbel vinkel-parentes"] # 0x27ea (en: 'left double angle bracket') - - "⟫": [T: "høyre dobbel vinkel-parentes"] # 0x27eb (en: 'right double angle bracket') - - "⟬": [T: "venstre hvit skilpaddeskall-parentes"] # 0x27ec (en: 'left white tortoise shell bracket') - - "⟭": [T: "høyre hvit skilpaddeskall-parentes"] # 0x27ed (en: 'right white tortoise shell bracket') - - "⟮": [T: "avflatet høyreparentes"] # 0x27ee (en: 'left flattened parenthesis') - - "⟯": [T: "avflatet venstreparentes"] # 0x27ef (en: 'right flattened parenthesis') - #-------------------------------------------------------------------------------------------------- - # Supplemental arrows-A OK - - "⟰": [T: "kvadrupel-streket oppoverpil"] # 0x27f0 (en: 'upwards quadruple arrow', google: 'uppåt fyrdubbla pilen') - - "⟱": [T: "kvadrupel-streket nedoverpil"] # 0x27f1 (en: 'downwards quadruple arrow', google: 'nedåt fyrdubbla pilen') - - "⟲": [T: "åpen sirkelpil mot klokken"] # 0x27f2 (en: 'anticlockwise gapped circle arrow', google: 'antikvis gappad cirkelpil') - - "⟳": [T: "åpen sirkelpil med klokken"] # 0x27f3 (en: 'clockwise gapped circle arrow', google: 'medurs gappad cirkelpil') - - "⟴": [T: "høyrepil med pluss i sirkel"] # 0x27f4 (en: 'right arrow with circled plus', google: 'höger-pil med circled plus') - - "⟵": [T: "lang venstrepil"] # 0x27f5 (en: 'long leftwards arrow') - - "⟶": [T: "lang høyrepil"] # 0x27f6 (en: 'long rightwards arrow') - - "⟷": [T: "lang venstre-høyre-pil"] # 0x27f7 (en: 'long left right arrow') - - "⟸": [T: "lang dobbeltstreket venstrepil"] # 0x27f8 (en: 'long leftwards double arrow') - - "⟹": [T: "lang dobbeltstreket høyrepil"] # 0x27f9 (en: 'long rightwards double arrow') - - "⟺": [T: "lang dobbeltstreket venstre-høyre-pil"] # 0x27fa (en: 'long left right double arrow') - - "⟻": [T: "lang venstrepil fra strek"] # 0x27fb (en: 'long leftwards arrow from bar', google: 'lång vänster pil från bar') - - "⟼": [T: "lang høyrepil fra strek"] # 0x27fc (en: 'long rightwards arrow from bar') - - "⟽": [T: "lang dobbeltstreket venstrepil fra strek"] # 0x27fd (en: 'long leftwards double arrow from bar', google: 'lång vänster dubbelpil från bar') - - "⟾": [T: "lang dobbeltstreket høyrepil fra strek"] # 0x27fe (en: 'long rightwards double arrow from bar', google: 'långt höger-pil från bar') - - "⟿": [T: "lang svingete høyrepil"] # 0x27ff (en: 'long rightwards squiggle arrow') - #------------------------------------------------------------------------------------------------------ - #Supplemental arrows-B OK - - "⤀": [T: "høyrepil med to spisser og vertikal strek"] # 0x2900 (en: 'rightwards two headed arrow with vertical stroke', google: 'åtgärd två ledde pil med vertikalt slag') - - "⤁": [T: "høyrepil med to spisser og dobbel vertikal strek"] # 0x2901 (en: 'rightwards two headed arrow with double vertical stroke', google: 'åtgärder två pil med dubbel vertikal stroke') - - "⤂": [T: "dobbeltstreket venstrepil med vertikal strek"] # 0x2902 (en: 'leftwards double arrow with vertical stroke', google: 'vänster dubbelpil med vertikalt slag') - - "⤃": [T: "dobbeltstreket høyrepil med vertikal strek"] # 0x2903 (en: 'rightwards double arrow with vertical stroke', google: 'åtgärd med höger med vertikal stroke') - - "⤄": [T: "dobbeltstreket venstre-høyre-pil med vertikal strek"] # 0x2904 (en: 'left right double arrow with vertical stroke', google: 'vänster höger dubbelpil med vertikalt slag') - - "⤅": [T: "høyrepil fra strek med dobbel spiss"] # 0x2905 (en: 'rightwards two headed arrow from bar') - - "⤆": [T: "dobbeltstreket venstrepil fra strek"] # 0x2906 (en: 'leftwards double arrow from bar', google: 'vänster dubbelpil från bar') - - "⤇": [T: "dobbeltstreket høyrepil fra strek"] # 0x2907 (en: 'rightwards double arrow from bar', google: 'åtgärd med höger pil från stången') - - "⤈": [T: "nedoverpil med horisontal strek"] # 0x2908 (en: 'downwards arrow with horizontal stroke', google: 'nedåt pil med horisontellt slag') - - "⤉": [T: "oppoverpil med horisontal strek"] # 0x2909 (en: 'upwards arrow with horizontal stroke', google: 'uppåt pil med horisontellt slag') - - "⤊": [T: "trippel-streket oppoverpil"] # 0x290a (en: 'upwards triple arrow', google: 'uppåt trippelpil') - - "⤋": [T: "trippel-streket nedoverpil"] # 0x290b (en: 'downwards triple arrow', google: 'nedåt trippelpil') - - "⤌": [T: "stiplet venstrepil"] # 0x290c (en: 'leftwards double dash arrow') - - "⤍": [T: "stiplet høyrepil"] # 0x290d (en: 'rightwards double dash arrow') - - "⤎": [T: "stiplet venstrepil"] # 0x290e (en: 'leftwards triple dash arrow') - - "⤏": [T: "stiplet høyrepil"] # 0x290f (en: 'rightwards triple dash arrow') - - "⤐": [T: "stiplet høyrepil med to spisser"] # 0x2910 (en: 'rightwards two headed triple dash arrow') - - "⤑": [T: "prikket høyrepil"] # 0x2911 (en: 'rightwards arrow with dotted stem') - - "⤒": [T: "oppoverpil mot strek"] # 0x2912 - - "⤓": [T: "nedoverpil mot strek"] # 0x2913 - - "⤔": [T: "høyrepil med hale og vertikal strek"] # 0x2914 (en: 'rightwards arrow with tail and vertical stroke', google: 'åtgärdspil med svans och vertikalt slag') - - "⤕": [T: "høyrepil med hale og dobbel vertikal strek"] # 0x2915 (en: 'rightwards arrow with tail and double vertical stroke', google: 'åtgärdspil med svans och dubbel vertikal stroke') - - "⤖": [T: "høyrepil med dobbel spiss og hale"] # 0x2916 (en: 'rightwards two headed arrow with tail') - - "⤗": [T: "høyrepil med dobbel spiss og hale og vertikal strek"] # 0x2917 (en: 'rightwards two headed arrow with tail with vertical stroke', google: 'åt höger två pil med svans med vertikalt stroke') - - "⤘": [T: "høyrepil med dobbel spiss og hale og dobbel vertikal strek"] # 0x2918 (en: 'rightwards two headed arrow with tail with double vertical stroke', google: 'åt höger två pil med svans med dubbel vertikal stroke') - - "⤙": [T: "venstre pil-hale"] # 0x2919 (en: 'leftwards arrow tail') - - "⤚": [T: "høyre pil-hale"] # 0x291a (en: 'rightwards arrow tail', google: 'åtgärder med höger pil') - - "⤛": [T: "dobbel venstre pil-hale"] # 0x291b (en: 'leftwards double arrow tail') - - "⤜": [T: "dobbel høyre pil-hale"] # 0x291c (en: 'rightwards double arrow tail') - - "⤝": [T: "venstrepil mot fylt diamant"] # 0x291d (en: 'leftwards arrow to filled diamond') - - "⤞": [T: "høyrepil mot fylt diamant"] # 0x291e (en: 'rightwards arrow to filled diamond') - - "⤟": [T: "venstrepil fra strek til fylt diamant"] # 0x291f (en: 'leftwards arrow from bar to filled diamond') - - "⤠": [T: "høyrepil fra strek til fylt diamant"] # 0x2920 (en: 'rightwards arrow from bar to filled diamond') - - "⤡": [T: "nordvest- og sørøst-pil"] # 0x2921 (en: 'north west and south east arrow', google: 'north west och south east arrow') - - "⤢": [T: "nordøst- og sørvest-pil"] # 0x2922 (en: 'north east and south west arrow', google: 'north east and south west arrow') - - "⤣": [T: "nordvest-pil med krok"] # 0x2923 (en: 'north west arrow with hook') - - "⤤": [T: "nordøst-pil med krok"] # 0x2924 (en: 'north east arrow with hook') - - "⤥": [T: "sørøst-pil med krok"] # 0x2925 (en: 'south east arrow with hook') - - "⤦": [T: "sørvest-pil med krok"] # 0x2926 (en: 'south west arrow with hook') - - "⤧": [T: "nordvest-pil og nordøst-pil"] # 0x2927 (en: 'north west arrow and north east arrow') - - "⤨": [T: "nordøst-pil og sørøst-pil"] # 0x2928 (en: 'north east arrow and south east arrow') - - "⤩": [T: "sørøst-pil og sørvest-pil"] # 0x2929 (en: 'south east arrow and south west arrow') - - "⤪": [T: "sørvest-pil og nordvest-pil"] # 0x292a (en: 'south west arrow and north west arrow') - - "⤫": [T: "stigende diagonal krysser synkende diagonal"] # 0x292b (en: 'rising diagonal crossing falling diagonal', google: 'stigande diagonal korsning fallande diagonal') - - "⤬": [T: "synkende diagonal krysser stigende diagonal"] # 0x292c (en: 'falling diagonal crossing rising diagonal', google: 'fallande diagonal korsning stigande diagonal') - - "⤭": [T: "sørøst-pil krysser nordøst-pil"] # 0x292d (en: 'south east arrow crossing north east arrow', google: 'south east arrow crossing north east arrow') - - "⤮": [T: "nordøst-pil krysser sørøst-pil"] # 0x292e (en: 'north east arrow crossing south east arrow', google: 'north east arrow crossing south east arrow') - - "⤯": [T: "synkende diagonal krysser nordøst-pil"] # 0x292f (en: 'falling diagonal crossing north east arrow', google: 'fallande diagonal korsar nord-ostra pilen') - - "⤰": [T: "stigende diagonal krysser sørøst-pil"] # 0x2930 (en: 'rising diagonal crossing south east arrow', google: 'rising diagonal crossing south east arrow') - - "⤱": [T: "nordøst-pil krysser nordvest-pil"] # 0x2931 (en: 'north east arrow crossing north west arrow', google: 'north east arrow crossing north west arrow') - - "⤲": [T: "nordvest-pil krysser nordøst-pil"] # 0x2932 (en: 'north west arrow crossing north east arrow', google: 'north west arrow crossing north east arrow') - - "⤳": [T: "bølgete høyrepil"] # 0x2933 (en: 'wave arrow pointing directly right') - - "⤴": [T: "høyrepil med vinkel oppover"] # 0x2934 (en: 'arrow pointing rightwards then curving upwards', google: 'arrow pekar åt höger och böjer sig sedan uppåt') - - "⤵": [T: "høyrepil med vinkel nedover"] # 0x2935 (en: 'arrow pointing rightwards then curving downwards') - - "⤶": [T: "nedoverpil med vinkel til venstre"] # 0x2936 (en: 'arrow pointing downwards then curving leftwards') - - "⤷": [T: "nedoverpil med vinkel til høyre"] # 0x2937 (en: 'arrow pointing downwards then curving rightwards') - - "⤸": [T: "halvsirkelpil med klokken"] # 0x2938 (en: 'right side arc clockwise arrow') - - "⤹": [T: "halvsirkelpil mot klokken"] # 0x2939 (en: 'left side arc anticlockwise arrow') - - "⤺": [T: "øvre halvsirkelpil mot klokken"] # 0x293a (en: 'top arc anticlockwise arrow', google: 'toppbåge moturs pil') - - "⤻": [T: "nedre halvsirkelpil mot klokken"] # 0x293b (en: 'bottom arc anticlockwise arrow', google: 'nedre båge anticurs pil') - - "⤼": [T: "øvre halvsirkelpil med klokken med minus"] # 0x293c (en: 'top arc clockwise arrow with minus') - - "⤽": [T: "øvre halvsirkelpil mot klokken med pluss"] # 0x293d (en: 'top arc anticlockwise arrow with plus') - - "⤾": [T: "halvsirkelpil med klokken"] # 0x293e (en: 'lower right semicircular clockwise arrow', google: 'nedre högra halvcirkelformade medurs pil') - - "⤿": [T: "halvsirkelpil mot klokken"] # 0x293f (en: 'lower left semicircular anticlockwise arrow', google: 'nedre vänstra halvcirkelformade pil moturs') - - "⥀": [T: "sirkel-pil mot klokken"] # 0x2940 (en: 'anticlockwise closed circle arrow', google: 'antikvis stängd cirkelpil') - - "⥁": [T: "sirkel-pil med klokken"] # 0x2941 (en: 'clockwise closed circle arrow', google: 'medurs stängd cirkelpil') - - "⥂": [T: "høyrepil over kort venstrepil"] # 0x2942 (en: 'rightwards arrow above short leftwards arrow', google: 'åtgärdspil över kort vänster pil') - - "⥃": [T: "venstrepil over kort høyrepil"] # 0x2943 (en: 'leftwards arrow above short rightwards arrow', google: 'vänster pil ovanför kort höger-pil') - - "⥄": [T: "kort høyrepil over venstrepil"] # 0x2944 (en: 'short rightwards arrow above leftwards arrow', google: 'kort höger-pil ovanför vänster pil') - - "⥅": [T: "høyrepil med pluss under"] # 0x2945 (en: 'rightwards arrow with plus below') - - "⥆": [T: "venstrepil med pluss under"] # 0x2946 (en: 'leftwards arrow with plus below', google: 'vänster pil med plus nedan') - - "⥇": [T: "høyrepil gjennom x"] # 0x2947 (en: 'rightwards arrow through x', google: 'åtgärdspil genom x') - - "⥈": [T: "venstre-høyre-pil gjennom sirkel"] # 0x2948 (en: 'left right arrow through circle') - - "⥉": [T: "oppoverpil med dobbel spiss fra sirkel"] # 0x2949 (en: 'upwards two headed arrow from circle') - - "⥊": [T: "toveis harpun venstre mothake opp høyre mothake ned"] # 0x294a (en: 'left barb up right barb down harpoon') - - "⥋": [T: "toveis harpun venstre mothake ned høyre mothake opp"] # 0x294b (en: 'left barb down right barb up harpoon') - - "⥌": [T: "toveis vertikal harpun øvre mothake høyre nedre mothake venstre"] # 0x294c (en: 'up barb right down barb left harpoon', google: 'upp barb höger ner barb vänster harpun') - - "⥍": [T: "toveis vertikal harpun øvre mothake venstre nedre mothake høyre"] # 0x294d (en: 'up barb left down barb right harpoon', google: 'upp barb vänster ner barb höger harpoon') - - "⥎": [T: "toveis harpun mothaker opp"] # 0x294e (en: 'left barb up right barb up harpoon', MathPlayer: 'vänster höger harpoon up', google: 'vänster barb upp höger barb upp harpoon') - - "⥏": [T: "toveis vertikal harpun mothaker høyre"] # 0x294f (en: 'up barb right down barb right harpoon') - - "⥐": [T: "toveis harpun mothaker ned"] # 0x2950 (en: 'left barb down right barb down harpoon', MathPlayer: 'vänster höger harpoon ner') - - "⥑": [T: "toveis vertikal harpun mothaker venstre"] # 0x2951 (en: 'up barb left down barb left harpoon') - - "⥒": [T: "venstre-harpun mot strek mothake opp"] # 0x2952 (en: 'leftwards harpoon with barb up to bar') - - "⥓": [T: "høyre-harpun mot strek mothake opp"] # 0x2953 (en: 'rightwards harpoon with barb up to bar') - - "⥔": [T: "opp-harpun mot strek mothake høyre"] # 0x2954 (en: 'upwards harpoon with barb right to bar') - - "⥕": [T: "ned-harpun mot strek mothake høyre"] # 0x2955 (en: 'downwards harpoon with barb right to bar') - - "⥖": [T: "venstre-harpun mot strek mothake ned"] # 0x2956 (en: 'leftwards harpoon with barb down to bar') - - "⥗": [T: "høyre-harpun mot strek mothake ned"] # 0x2957 (en: 'rightwards harpoon with barb down to bar') - - "⥘": [T: "opp-harpun mot strek mothake venstre"] # 0x2958 (en: 'upwards harpoon with barb left to bar') - - "⥙": [T: "ned-harpun mot strek mothake venstre"] # 0x2959 (en: 'downwards harpoon with barb left to bar') - - "⥚": [T: "venstre-harpun fra strek mothake opp"] # 0x295a (en: 'leftwards harpoon with barb up from bar') - - "⥛": [T: "høyre-harpun fra strek mothake opp"] # 0x295b (en: 'rightwards harpoon with barb up from bar') - - "⥜": [T: "opp-harpun fra strek mothake høyre"] # 0x295c (en: 'upwards harpoon with barb right from bar') - - "⥝": [T: "ned-harpun fra strek mothake høyre"] # 0x295d (en: 'downwards harpoon with barb right from bar') - - "⥞": [T: "venstre-harpun fra strek mothake ned"] # 0x295e (en: 'leftwards harpoon with barb down from bar') - - "⥟": [T: "høyre-harpun fra strek mothake ned"] # 0x295f (en: 'rightwards harpoon with barb down from bar') - - "⥠": [T: "opp-harpun fra strek mothake venstre"] # 0x2960 (en: 'upwards harpoon with barb left from bar') - - "⥡": [T: "ned-harpun fra strek mothake venstre"] # 0x2961 (en: 'downwards harpoon with barb left from bar') - - "⥢": [T: "venstre-harpun mothake opp over venstre-harpun mothake ned"] # 0x2962 (en: 'leftwards harpoon with barb up above leftwards harpoon with barb down') - - "⥣": [T: "opp-harpun mothake venstre ved siden av opp-harpun mothake høyre"] # 0x2963 (en: 'upwards harpoon with barb left beside upwards harpoon with barb right') - - "⥤": [T: "høyre-harpun mothake opp over høyre-harpun mothake ned"] # 0x2964 (en: 'rightwards harpoon with barb up above rightwards harpoon with barb down') - - "⥥": [T: "ned-harpun mothake venstre ved siden av ned-harpun mothake høyre"] # 0x2965 (en: 'downwards harpoon with barb left beside downwards harpoon with barb right') - - "⥦": [T: "venstre-harpun mothake opp over høyre-harpun mothake opp"] # 0x2966 (en: 'leftwards harpoon with barb up above rightwards harpoon with barb up') - - "⥧": [T: "venstre-harpun mothake ned over høyre-harpun mothake ned"] # 0x2967 (en: 'leftwards harpoon with barb down above rightwards harpoon with barb down') - - "⥨": [T: "høyre-harpun mothake opp over venstre-harpun mothake opp"] # 0x2968 (en: 'rightwards harpoon with barb up above leftwards harpoon with barb up') - - "⥩": [T: "høyre-harpun mothake ned over venstre-harpun mothake ned"] # 0x2969 (en: 'rightwards harpoon with barb down above leftwards harpoon with barb down') - - "⥪": [T: "venstre-harpun mothake opp over strek"] # 0x296a (en: 'leftwards harpoon with barb up above long dash') - - "⥫": [T: "venstre-harpun mothake ned under strek"] # 0x296b (en: 'leftwards harpoon with barb down below long dash') - - "⥬": [T: "høyre-harpun mothake opp over strek"] # 0x296c (en: 'rightwards harpoon with barb up above long dash') - - "⥭": [T: "høyre-harpun mothake ned under strek"] # 0x296d (en: 'rightwards harpoon with barb down below long dash') - - "⥮": [T: "opp-harpun mothake venstre ved siden av ned-harpun mothake høyre"] # 0x296e (en: 'upwards harpoon with barb left beside downwards harpoon with barb right') - - "⥯": [T: "ned-harpun mothake venstre ved siden av opp-harpun mothake høyre"] # 0x296f (en: 'downwards harpoon with barb left beside upwards harpoon with barb right') - - "⥰": [T: "dobbeltstreket høyrepil med avrundet spiss"] # 0x2970 (en: 'right double arrow with rounded head') - - "⥱": [T: "lik over høyrepil"] # 0x2971 (en: 'equals above rightwards arrow') - - "⥲": [T: "tilde over høyrepil"] # 0x2972 (en: 'tilde operator above rightwards arrow') - - "⥳": [T: "venstrepil over tilde"] # 0x2973 (en: 'leftwards arrow above tilde operator') - - "⥴": [T: "høyrepil over tilde"] # 0x2974 (en: 'rightwards arrow above tilde operator') - - "⥵": [T: "høyrepil over tilnærmet lik"] # 0x2975 (en: 'rightwards arrow above almost equal to') - - "⥶": [T: "mindre enn over venstrepil"] # 0x2976 (en: 'less than above leftwards arrow') - - "⥷": [T: "venstrepil gjennom mindre enn"] # 0x2977 (en: 'leftwards arrow through less than', google: 'vänster pil genom mindre än') - - "⥸": [T: "større enn over høyrepil"] # 0x2978 (en: 'greater than above rightwards arrow') - - "⥹": [T: "delmengde over høyrepil"] # 0x2979 (en: 'subset above rightwards arrow') - - "⥺": [T: "venstrepil gjennom delmengde"] # 0x297a (en: 'leftwards arrow through subset', google: 'vänster pil genom undergruppen') - - "⥻": [T: "overmengde over venstrepil"] # 0x297b (en: 'superset above leftwards arrow') - - "⥼": [T: "fiskehale til venstre"] # 0x297c (en: 'left fish tail') - - "⥽": [T: "fiskehale til høyre"] # 0x297d (en: 'right fish tail') - - "⥾": [T: "fiskehale oppover"] # 0x297e (en: 'up fish tail') - - "⥿": [T: "fiskehale nedover"] # 0x297f (en: 'down fish tail') - #--------------------------------------------------------------------------------------------- - # Miscellaneous Mathematical symbols-B OK - - "⦀": [T: "trippel loddrett strek"] # 0x2980 (en: 'triple vertical bar delimiter', google: 'trippel vertikal bar avgränsare') - - "⦁": [T: "punkt z-notasjon"] # 0x2981 (en: 'z notation spot', google: 'z notation spot') - - "⦂": [T: "kolon z-notasjon"] # 0x2982 (en: 'z notation type colon', google: 'z notationstyp kolon') - - "⦃": [T: "venstre hvit krøllparentes"] # 0x2983 (en: 'left white brace', google: 'vänster vit stag') - - "⦄": [T: "høyre hvit krøllparentes"] # 0x2984 (en: 'right white brace', google: 'höger vit stag') - - "⦅": [T: "hvit venstreparentes"] # 0x2985 (en: 'left white parenthesis') - - "⦆": [T: "hvit høyreparentes"] # 0x2986 (en: 'right white parenthesis') - - "⦇": [T: "venstre bilde-parentes z-notasjon"] # 0x2987 (en: 'z notation left image bracket', google: 'z notation vänster bildfäste') - - "⦈": [T: "høyre bilde-parentes z-notasjon"] # 0x2988 (en: 'z notation right image bracket', google: 'z notation rätt bildfäste') - - "⦉": [T: "venstre bindende parentes z-notasjon"] # 0x2989 (en: 'z notation left binding bracket') - - "⦊": [T: "høyre bindende parentes z-notasjon"] # 0x298a (en: 'z notation right binding bracket') - - "⦋": [T: "venstre hakeparentes med strek under"] # 0x298b (en: 'left square bracket with underbar') - - "⦌": [T: "høyre hakeparentes med strek under"] # 0x298c (en: 'right square bracket with underbar') - - "⦍": [T: "venstre hakeparentes med strek i øvre hjørne"] # 0x298d (en: 'left square bracket with tick in top corner') - - "⦎": [T: "høyre hakeparentes med strek i nedre hjørne"] # 0x298e (en: 'right square bracket with tick in bottom corner') - - "⦏": [T: "venstre hakeparentes med strek i nedre hjørne"] # 0x298f (en: 'left square bracket with tick in bottom corner') - - "⦐": [T: "høyre hakeparentes med strek i øvre hjørne"] # 0x2990 (en: 'right square bracket with tick in top corner') - - "⦑": [T: "venstre vinkelparentes med prikk"] # 0x2991 (en: 'left angle bracket with dot') - - "⦒": [T: "høyre vinkelparentes med prikk"] # 0x2992 (en: 'right angle bracket with dot') - - "⦓": [T: "venstre mindre enn parentes"] # 0x2993 (en: 'left arc less than bracket') - - "⦔": [T: "høyre større enn parentes"] # 0x2994 (en: 'right arc greater than bracket') - - "⦕": [T: "venstre dobbel større enn parentes"] # 0x2995 (en: 'double left arc greater than bracket') - - "⦖": [T: "høyre dobbel mindre enn parentes"] # 0x2996 (en: 'double right arc less than bracket') - - "⦗": [T: "venstre skilpaddeskall-parentes"] # 0x2997 (en: 'left black tortoise shell bracket', google: 'vänster svart sköldpaddsskalfäste') - - "⦘": [T: "høyre skilpaddeskall-parentes"] # 0x2998 (en: 'right black tortoise shell bracket', google: 'höger svart sköldpaddsskalfäste') - - "⦙": [T: "prikket loddrett strek"] # 0x2999 (en: 'dotted fence', google: 'prickat staket') - - "⦚": [T: "sikksakk loddrett strek"] # 0x299a (en: 'vertical zigzag line') - - "⦛": [T: "målt vinkel til venstre"] # 0x299b (en: 'measured angle opening left', google: 'uppmätt vinkelöppning vänster') - - "⦜": [T: "rett vinkel"] # 0x299c (en: 'right angle variant with square', google: 'rätt vinkelvariant med fyrkant') - - "⦝": [T: "målt rett vinkel med prikk"] # 0x299d (en: 'measured right angle with dot') - - "⦞": [T: "vinkel med s i"] # 0x299e (en: 'angle with s inside') - - "⦟": [T: "spiss vinkel"] # 0x299f (en: 'acute angle') - - "⦠": [T: "sfærisk vinkel til venstre"] # 0x29a0 (en: 'spherical angle opening left', google: 'sfärisk vinkelöppning vänster') - - "⦡": [T: "sfærisk vinkel oppover"] # 0x29a1 (en: 'spherical angle opening up', google: 'sfärisk vinkel öppnas') - - "⦢": [T: "snudd vinkel"] # 0x29a2 (en: 'turned angle', google: 'vände vinkel') - - "⦣": [T: "speilvendt vinkel"] # 0x29a3 (en: 'reversed angle') - - "⦤": [T: "vinkel med strek under"] # 0x29a4 (en: 'angle with underbar') - - "⦥": [T: "speilvendt vinkel med strek under"] # 0x29a5 (en: 'reversed angle with underbar') - - "⦦": [T: "stump vinkel oppover"] # 0x29a6 (en: 'oblique angle opening up') - - "⦧": [T: "stump vinkel nedover"] # 0x29a7 (en: 'oblique angle opening down') - - "⦨": [T: "målt vinkel med nordøst-pil i enden av øvre vinkelben"] # 0x29a8 (en: 'measured angle with open arm ending in arrow pointing up and to the right') - - "⦩": [T: "målt vinkel med nordvest-pil i enden av øvre vinkelben"] # 0x29a9 (en: 'measured angle with open arm ending in arrow pointing up and to the left') - - "⦪": [T: "målt vinkel med sørøst-pil i enden av nedre vinkelben"] # 0x29aa (en: 'measured angle with open arm ending in arrow pointing down and to the right') - - "⦫": [T: "målt vinkel med sørvest-pil i enden av nedre vinkelben"] # 0x29ab (en: 'measured angle with open arm ending in arrow pointing down and to the left') - - "⦬": [T: "målt vinkel med nordøst-pil i enden av høyre vinkelben"] # 0x29ac (en: 'measured angle with open arm ending in arrow pointing right and up') - - "⦭": [T: "målt vinkel med nordvest-pil i enden av venstre vinkelben"] # 0x29ad (en: 'measured angle with open arm ending in arrow pointing left and up') - - "⦮": [T: "målt vinkel med sørøst-pil i enden av høyre vinkelben"] # 0x29ae (en: 'measured angle with open arm ending in arrow pointing right and down') - - "⦯": [T: "målt vinkel med sørvest-pil i enden av venstre vinkelben"] # 0x29af (en: 'measured angle with open arm ending in arrow pointing left and down') - - "⦰": [T: "den tomme mengden speilvendt"] # 0x29b0 (en: 'reversed empty set') - - "⦱": [T: "den tomme mengden med strek over"] # 0x29b1 (en: 'empty set with overbar') - - "⦲": [T: "den tomme mengden med sirkel over"] # 0x29b2 (en: 'empty set with small circle above') - - "⦳": [T: "den tomme mengden med høyrepil over"] # 0x29b3 (en: 'empty set with right arrow above') - - "⦴": [T: "den tomme mengden med venstrepil over"] # 0x29b4 (en: 'empty set with left arrow above') - - "⦵": [T: "sirkel med horisontal strek"] # 0x29b5 (en: 'circle with horizontal bar') - - "⦶": [T: "sirkel med vertikal strek"] # 0x29b6 (SRE: 'vertikalt streck i cirkel') - - "⦷": [T: "parallell i sirkel"] # 0x29b7 (en: 'circled parallel') - - "⦸": [T: "sirkel med omvendt skråstrek"] # 0x29b8 (en: 'circled reverse solidus', google: 'circled reverse solidus') - - "⦹": [T: "vinkelrett i sirkel"] # 0x29b9 (en: 'circled perpendicular') - - "⦺": [T: "sirkel delt med horisontal strek og øvre del delt med vertikal strek"] # 0x29ba (en: 'circled divided by horizontal bar and top half divided by vertical bar', google: 'cirklade dividerat med horisontell stång och den övre halvan dividerad med vertikal stång') - - "⦻": [T: "sirkel med x"] # 0x29bb (en: 'circle with superimposed x') - - "⦼": [T: "sirkel med divisjon rotert mot klokken"] # 0x29bc (en: 'circled anticlockwise rotated division sign') - - "⦽": [T: "oppoverpil gjennom sirkel"] # 0x29bd (en: 'up arrow through circle', google: 'upp pilen genom cirkeln') - - "⦾": [T: "hvitt punkt i sirkel"] # 0x29be (en: 'circled white bullet') - - "⦿": [T: "punkt i sirkel"] # 0x29bf (en: 'circled bullet') - - "⧀": [T: "mindre enn i sirkel"] # 0x29c0 (en: 'circled less than') - - "⧁": [T: "større enn i sirkel"] # 0x29c1 (en: 'circled greater than') - - "⧂": [T: "sirkel med liten sirkel til høyre"] # 0x29c2 (en: 'circle with small circle to the right') - - "⧃": [T: "sirkel med to horisontale streker til høyre"] # 0x29c3 (en: 'circle with two horizontal strokes to the right') - - "⧄": [T: "kvadrat med diagonal oppover"] # 0x29c4 (en: 'squared rising diagonal slash') - - "⧅": [T: "kvadrat med diagonal nedover"] # 0x29c5 (en: 'squared falling diagonal slash') - - "⧆": [T: "asterisk i kvadrat"] # 0x29c6 (en: 'squared asterisk', google: 'kvadratisk asterisk') - - "⧇": [T: "liten sirkel i kvadrat"] # 0x29c7 (en: 'squared small circle', google: 'kvadrat liten cirkel') - - "⧈": [T: "kvadrat i kvadrat"] # 0x29c8 (en: 'squared square', google: 'squared square') - - "⧉": [T: "to sammenføyde kvadrat"] # 0x29c9 (en: 'two joined squares') - - "⧊": [T: "trekant med prikk over"] # 0x29ca (en: 'triangle with dot above', google: 'triangel med prick ovan') - - "⧋": [T: "trekant med strek under"] # 0x29cb (en: 'triangle with underbar', google: 'triangel med underbar') - - "⧌": [T: "trekant med s"] # 0x29cc (en: 's in triangle') - - "⧍": [T: "trekant med seriffer på bunnen"] # 0x29cd (en: 'triangle with serifs at bottom') - - "⧎": [T: "høyre trekant over venstre trekant"] # 0x29ce (en: 'right triangle above left triangle') - - "⧏": [T: "venstre trekant ved siden av vertikal strek"] # 0x29cf (en: 'left triangle beside vertical bar') - - "⧐": [T: "vertikal strek ved siden av høyre trekant"] # 0x29d0 (en: 'vertical bar beside right triangle') - - "⧑": [T: "sløyfe med venstre halvdel fylt"] # 0x29d1 (en: 'bowtie with left half black', google: 'bowtie med vänster halva svart') - - "⧒": [T: "sløyfe med høyre halvdel fylt"] # 0x29d2 (en: 'bowtie with right half black', google: 'bowtie med höger halv svart') - - "⧓": [T: "fylt sløyfe"] # 0x29d3 (en: 'black bowtie', google: 'svart bowtie') - - "⧔": [T: "sløyfe med venstre halvdel fylt og høyre halvdel åpen"] # 0x29d4 (en: 'times with left half black', google: 'gånger med vänster halva svart') - - "⧕": [T: "sløyfe med venstre halvdel åpen og høyre halvdel fylt"] # 0x29d5 (en: 'times with right half black', google: 'gånger med höger halv svart') - - "⧖": [T: "hvitt timeglass"] # 0x29d6 (en: 'white hourglass', google: 'vit timglas') - - "⧗": [T: "fylt timeglass"] # 0x29d7 (en: 'black hourglass') - - "⧘": [T: "venstre sikksakk gjerde"] # 0x29d8 (en: 'left wiggly fence', google: 'vänster wiggly staket') - - "⧙": [T: "høyre sikksakk gjerde"] # 0x29d9 (en: 'right wiggly fence', google: 'höger vinglt staket') - - "⧚": [T: "dobbelt venstre sikksakk gjerde"] # 0x29da (en: 'left double wiggly fence', MathPlayer: 'left double wiggly fence', google: 'vänster dubbel wiggly staket') - - "⧛": [T: "dobbelt høyre sikksakk gjerde"] # 0x29db (en: 'right double wiggly fence', MathPlayer: 'right double wiggly fence', google: 'höger dubbel wiggly staket') - - "⧜": [T: "ufullstendig uendelig"] # 0x29dc (en: 'incomplete infinity') - - "⧝": [T: "bånd over uendelighetstegn"] # 0x29dd (en: 'tie over infinity', google: 'bind över oändligheten') - - "⧞": [T: "uendelig med vertikal strek"] # 0x29de (en: 'infinity negated with vertical bar') - - "⧟": [T: "tosidig multimap"] # 0x29df (en: 'double-ended multimap', google: 'dubbel-sluten multimap') - - "⧠": [T: "kvadrat med omriss"] # 0x29e0 (en: 'square with contoured outline', google: 'fyrkantig med konturerad kontur') - - "⧡": [T: "øker som"] # 0x29e1 (en: 'increases as') - - "⧢": [T: "shuffle-produkt"] # 0x29e2 (en: 'shuffle product', google: 'shuffle -produkt') - - "⧣": [T: "likhetstegn og skråstilt parallell"] # 0x29e3 (en: 'equals sign and slanted parallel') - - "⧤": [T: "likhetstegn og skråstilt parallell med tilde over"] # 0x29e4 (en: 'equals sign and slanted parallel with tilde above') - - "⧥": [T: "identisk med og skråstilt parallell"] # 0x29e5 (en: 'identical to and slanted parallel') - - "⧦": [T: "gleich stark"] # 0x29e6 - - "⧧": [T: "termodynamisk"] # 0x29e7 (en: 'thermodynamic', google: 'termodynamisk') - - "⧨": [T: "trekant nedover venstre halvdel fylt"] # 0x29e8 (en: 'down pointing triangle with left half black', google: 'ner pekande triangel med vänster halvsvart') - - "⧩": [T: "trekant nedover høyre halvdel fylt"] # 0x29e9 (en: 'down pointing triangle with right half black', google: 'ner pekande triangel med höger halvsvart') - - "⧪": [T: "fylt diamant med pil ned"] # 0x29ea (en: 'black diamond with down arrow', google: 'svart diamant med nedpil') - - "⧫": [T: "fylt rombe"] # 0x29eb (en: 'black lozenge') - - "⧬": [T: "sirkel med pil ned"] # 0x29ec (en: 'white circle with down arrow', google: 'vit cirkel med nedpilen') - - "⧭": [T: "fylt sirkel med pil ned"] # 0x29ed (en: 'black circle with down arrow', google: 'svart cirkel med nedpilen') - - "⧮": [T: "firkant med utstikkere"] # 0x29ee (en: 'error-barred white square', google: 'fel-spärrvit fyrkant') - - "⧯": [T: "fylt firkant med utstikkere"] # 0x29ef (en: 'error-barred black square', google: 'fel-barred black square') - - "⧰": [T: "diamant med utstikkere"] # 0x29f0 (en: 'error-barred white diamond', google: 'fel-spärrad vit diamant') - - "⧱": [T: "fylt diamant med utstikkere"] # 0x29f1 (en: 'error-barred black diamond', google: 'fel-barred black diamond') - - "⧲": [T: "sirkel med utstikkere"] # 0x29f2 (en: 'error-barred white circle', google: 'fel-spärrad vit cirkel') - - "⧳": [T: "fylt sirkel med utstikkere"] # 0x29f3 (en: 'error-barred black circle', google: 'fel-barred black circle') - - "⧴": [T: "kolon høyrepil"] # 0x29f4 (en: 'rule-delayed', MathPlayer: 'rule delayed', google: 'regelförsenad') - - "⧵": [T: "omvendt skråstrek"] # 0x29f5 (en: 'reverse solidus operator', google: 'omvänd solidus -operatör') - - "⧶": [T: "skråstrek med strek over"] # 0x29f6 (en: 'solidus with overbar') - - "⧷": [T: "omvendt skråstrek med horisontal strek"] # 0x29f7 (en: 'reverse solidus with horizontal stroke', google: 'omvänd solidus med horisontellt slag') - - "⧸": [T: "stor skråstrek"] # 0x29f8 (en: 'big solidus', google: 'big solidus') - - "⧹": [T: "stor omvendt skråstrek"] # 0x29f9 (en: 'big reverse solidus', google: 'big reverse solidus') - - "⧺": [T: "dobbel pluss"] # 0x29fa (en: 'double plus', google: 'dubbel plus') - - "⧻": [T: "trippel pluss"] # 0x29fb (en: 'triple plus', google: 'trippel plus') - - "⧼": [T: "venstre buet vinkelparentes"] # 0x29fc (en: 'left pointing curved angle bracket', google: 'vänster pekande krökt vinkelfäste') - - "⧽": [T: "høyre buet vinkelparentes"] # 0x29fd (en: 'right pointing curved angle bracket', google: 'höger pekande krökt vinkelfäste') - # SWEDISH: kept English tiny & miny but changed spelling to get pronunciation right - - "⧾": [T: "tainy"] # 0x29fe (en: 'tiny', google: 'mycket liten') - - "⧿": [T: "mainy"] # 0x29ff (en: 'miny', google: 'miny') - #-------------------------------------------------------------------------------------------------------------- - # Supplemental Mathematical operators OK - - "⨀": [T: "dot-operator i sirkel"] # 0x2a00 (en: 'circled dot operator', google: 'circled dot operator') - - "⨁": [T: "pluss i sirkel"] # 0x2a01 (en: 'circled plus operator', google: 'circled plus operator') - - "⨂": [T: "multiplikasjon i sirkel"] # 0x2a02 (en: 'circled times operator', google: 'circled times operator') - - "⨃": [T: "union med prikk"] # 0x2a03 (en: 'union operator with dot', google: 'unionoperatör med dot') - - "⨄": [T: "union med pluss"] # 0x2a04 (en: 'union operator with plus', google: 'unionoperatör med plus') - - "⨅": [T: "kvadratisk snitt-operator"] # 0x2a05 (en: 'square intersection operator', google: 'square -korsningsoperatör') - - "⨆": [T: "kvadratisk union-operator"] # 0x2a06 (en: 'square union operator', google: 'square union operator') - - "⨇": [T: "to logiske og"] # 0x2a07 (en: 'two logical and operator', google: 'två logiska och operatörer') - - "⨈": [T: "to logiske eller"] # 0x2a08 (en: 'two logical or operator', google: 'två logiska eller operatörer') - - "⨉": [T: "ganger"] # 0x2a09 (en: 'times operator', google: 'times operator') - - "⨊": [T: "modulo to sum"] # 0x2a0a (en: 'modulo two sum', google: 'modulo två summa') - - "⨋": [T: "sum med integral"] # 0x2a0b (en: 'summation with integral', google: 'summering med integrerad') - - "⨌": [T: "firedobbelt integral"] # 0x2a0c (en: 'quadruple integral operator') - - "⨍": [T: "integral med horisontal strek"] # 0x2a0d (en: 'finite part integral') - - "⨎": [T: "integral med dobbel horisontal strek"] # 0x2a0e (en: 'integral with double stroke', google: 'integrerad med dubbelslag') - - "⨏": [T: "integral med skråstrek"] # 0x2a0f (en: 'integral average with slash', google: 'integrerat medelvärde med snedstreck') - - "⨐": [T: "sirkulasjons-funksjon"] # 0x2a10 (en: 'circulation function') - - "⨑": [T: "integrasjon mot klokka"] # 0x2a11 (en: 'anticlockwise integration') - - "⨒": [T: "linjeintegral med rektangulær vei rundt pol"] # 0x2a12 (en: 'line integration with rectangular path around pole') - - "⨓": [T: "linjeintegral med halvsirkel-vei rundt pol"] # 0x2a13 (en: 'line integration with semicircular path around pole') - - "⨔": [T: "linjeintegral eksklusiv polen"] # 0x2a14 (en: 'line integration not including the pole', MathPlayer: 'line integration not including the pole', google: 'linjeintegration inkluderar inte polen') - - "⨕": [T: "integral rund punkt-operator"] # 0x2a15 - - "⨖": [T: "integral med firkant"] # 0x2a16 - - "⨗": [T: "integral med venstrepil med krok"] # 0x2a17 (en: 'integral with leftwards arrow with hook') - - "⨘": [T: "integral med multiplikasjonstegn"] # 0x2a18 (en: 'integral with times sign', google: 'integrerad med times sign') - - "⨙": [T: "integral med snitt"] # 0x2a19 (en: 'integral with intersection', google: 'integrerad med korsning') - - "⨚": [T: "integral med union"] # 0x2a1a (en: 'integral with union', google: 'integrerad med unionen') - - "⨛": [T: "integral med horisontal strek over"] # 0x2a1b (en: 'integral with overbar', google: 'integrerad med overbar') - - "⨜": [T: "integral med horisontal strek under"] # 0x2a1c (en: 'integral with underbar', google: 'integrerad med underbar') - - "⨝": [T: "join"] # 0x2a1d (en: 'join', google: 'ansluta sig') - - "⨞": [T: "stor venstre trekant"] # 0x2a1e (en: 'large left triangle operator', google: 'stor vänster triangeloperatör') - - "⨟": [T: "skjema-sammensetning z-notasjon"] # 0x2a1f (en: 'z notation schema composition', google: 'z notationsschema komposition') - - "⨠": [T: "skjema-sluse z-notasjon"] # 0x2a20 (en: 'z notation schema piping', google: 'z notation schema piping') - - "⨡": [T: "skjema-projeksjon z-notasjon"] # 0x2a21 (en: 'z notation schema projection', google: 'z notation schema projection') - - "⨢": [T: "pluss med sirkel over"] # 0x2a22 (en: 'plus sign with circle above', MathPlayer: 'plustecken med ring över', google: 'plus skylt med cirkel ovan') - - "⨣": [T: "pluss med cirkumfleks over"] # 0x2a23 (en: 'plus sign with circumflex accent above', MathPlayer: 'plustecken med cirkumflex accent över', google: 'plus -tecken med circumflex -accent ovan') - - "⨤": [T: "pluss med tilde over"] # 0x2a24 (en: 'plus sign with tilde above') - - "⨥": [T: "pluss med prikk under"] # 0x2a25 (en: 'plus sign with dot below', MathPlayer: 'plustecken med punkt under', google: 'plus skylt med dot nedan') - - "⨦": [T: "pluss med tilde under"] # 0x2a26 (en: 'plus sign with tilde below') - - "⨧": [T: "pluss med nedre indeks to"] # 0x2a27 (en: 'plus sign with subscript two', MathPlayer: 'plustecken med index två', google: 'plus skylt med prenumeration två') - - "⨨": [T: "pluss med fylt trekant"] # 0x2a28 (en: 'plus sign with black triangle', google: 'plus skylt med svart triangel') - - "⨩": [T: "minus med komma over"] # 0x2a29 (en: 'minus sign with comma above', MathPlayer: 'minustecken med komma över', google: 'minus tecken med komma ovan') - - "⨪": [T: "minus med prikk under"] # 0x2a2a (en: 'minus sign with dot below', MathPlayer: 'minustecken med punkt under', google: 'minus tecken med prick nedan') - - "⨫": [T: "minus med fallende prikker"] # 0x2a2b (en: 'minus sign with falling dots', google: 'minus tecken med fallande prickar') - - "⨬": [T: "minus med stigende prikker"] # 0x2a2c (en: 'minus sign with rising dots', google: 'minus tecken med stigande prickar') - - "⨭": [T: "pluss i venstre halvsirkel"] # 0x2a2d (en: 'plus sign in left half circle', MathPlayer: 'plustecken i vänster halvcirkel', google: 'plus logga in vänster halva cirkeln') - - "⨮": [T: "pluss i høyre halvsirkel"] # 0x2a2e (en: 'plus sign in right half circle', MathPlayer: 'plustecken i höger halvcirkel', google: 'plus logga in höger halv cirkel') - - "⨯": # 0x2a2f - - test: - if: "$Verbosity='Terse'" - then: [T: "kryss"] - else: [T: "kryssprodukt"] - - "⨰": [T: "multiplikasjon med prikk over"] # 0x2a30 (en: 'multiplication sign with dot above') - - "⨱": [T: "multiplikasjon med strek under"] # 0x2a31 (en: 'multiplication sign with underbar') - - "⨲": [T: "semi-direkte produkt med lukket bunn"] # 0x2a32 (en: 'semidirect product with bottom closed', google: 'semidirect -produkt med botten stängd') - - "⨳": [T: "smash-produkt"] # 0x2a33 (en: 'smash product', MathPlayer: 'smash product', google: 'krossa produkten') - - "⨴": [T: "multiplikasjon i venstre halvsirkel"] # 0x2a34 (en: 'multiplication sign in left half circle') - - "⨵": [T: "multiplikasjon i høyre halvsirkel"] # 0x2a35 (en: 'multiplication sign in right half circle') - - "⨶": [T: "multiplikasjon i sirkel med cirkumfleks"] # 0x2a36 (en: 'circled multiplication sign with circumflex accent') - - "⨷": [T: "multiplikasjon i dobbel sirkel"] # 0x2a37 (en: 'multiplication sign in double circle') - - "⨸": [T: "divisjon i sirkel"] # 0x2a38 - - "⨹": [T: "pluss i trekant"] # 0x2a39 (en: 'plus sign in triangle', MathPlayer: 'plustecken i triangel', google: 'plus inloggning av triangeln') - - "⨺": [T: "minus i trekant"] # 0x2a3a (en: 'minus sign in triangle', MathPlayer: 'minustecken i triangel', google: 'minus logga in triangel') - - "⨻": [T: "multiplikasjon i trekant"] # 0x2a3b (en: 'multiplication sign in triangle') - - "⨼": [T: "interior product"] # 0x2a3c (en: 'interior product', MathPlayer: 'interior product', google: 'interiörprodukt') - - "⨽": [T: "invers interior product"] # 0x2a3d (en: 'righthand interior product', google: 'högra interiörprodukt') - - "⨾": [T: "relasjonssammensetning z-notasjon"] # 0x2a3e - - "⨿": [T: "koprodukt"] # 0x2a3f (en: 'amalgamation or coproduct', MathPlayer: 'amalgamation or coproduct', google: 'amalgamation eller coprodukt') - - "⩀": [T: "snitt med prikk"] # 0x2a40 (en: 'intersection with dot') - - "⩁": [T: "union med minus"] # 0x2a41 (en: 'union with minus sign', google: 'union med minus tecken') - - "⩂": [T: "union med horisontal strek over"] # 0x2a42 (en: 'union with overbar') - - "⩃": [T: "snitt med horisontal strek over"] # 0x2a43 (en: 'intersection with overbar') - - "⩄": [T: "snitt med logisk og"] # 0x2a44 (en: 'intersection with logical and') - - "⩅": [T: "union med logisk eller"] # 0x2a45 (en: 'union with logical or') - - "⩆": [T: "union over snitt"] # 0x2a46 (en: 'union above intersection') - - "⩇": [T: "snitt over union"] # 0x2a47 (en: 'intersection above union') - - "⩈": [T: "union over strek over snitt"] # 0x2a48 (en: 'union above bar above intersection') - - "⩉": [T: "snitt over strek over union"] # 0x2a49 (en: 'intersection above bar above union') - - "⩊": [T: "union ved siden av og sammensatt med union"] # 0x2a4a (en: 'union beside and joined with union') - - "⩋": [T: "snitt ved siden av og sammensatt med snitt"] # 0x2a4b (en: 'intersection beside and joined with intersection') - - "⩌": [T: "lukket union med seriffer"] # 0x2a4c (en: 'closed union with serifs') - - "⩍": [T: "lukket snitt med seriffer"] # 0x2a4d (en: 'closed intersection with serifs') - - "⩎": [T: "dobbelt kvadratisk snitt"] # 0x2a4e (en: 'double square intersection', google: 'korsning av dubbel kvadrat') - - "⩏": [T: "dobbel kvadratisk union"] # 0x2a4f (en: 'double square union', google: 'double square union') - - "⩐": [T: "lukket union med seriffer og smash-produkt"] # 0x2a50 (en: 'closed union with serifs and smash product') - - "⩑": [T: "logisk og med prikk over"] # 0x2a51 (en: 'logical and with dot above', google: 'logisk och med punkt ovan') - - "⩒": [T: "logisk eller med prikk over"] # 0x2a52 (en: 'logical or with dot above', google: 'logisk eller med punkt ovan') - - "⩓": [T: "dobbel logisk og"] # 0x2a53 (en: 'double logical and') - - "⩔": [T: "dobbel logisk eller"] # 0x2a54 (en: 'double logical or') - - "⩕": [T: "to kryssende logiske og"] # 0x2a55 (en: 'two intersecting logical and') - - "⩖": [T: "to kryssende logiske eller"] # 0x2a56 (en: 'two intersecting logical or') - - "⩗": [T: "skrånende eller"] # 0x2a57 (en: 'sloping large or') - - "⩘": [T: "skrånende og"] # 0x2a58 (en: 'sloping large and') - - "⩙": [T: "logisk eller overlapper logisk og"] # 0x2a59 (en: 'logical or overlapping logical and', google: 'logisk eller överlappande logisk och') - - "⩚": [T: "logisk og med vertikal strek"] # 0x2a5a (en: 'logical and with middle stem') - - "⩛": [T: "logisk eller med vertikal strek"] # 0x2a5b (en: 'logical or with middle stem') - - "⩜": [T: "logisk og med horisontal strek"] # 0x2a5c (en: 'logical and with horizontal dash') - - "⩝": [T: "logisk eller med horisontal strek"] # 0x2a5d (en: 'logical or with horizontal dash') - - "⩞": [T: "logisk og med dobbel horisontal strek over"] # 0x2a5e (en: 'logical and with double overbar', google: 'logiskt och med dubbelt överbar') - - "⩟": [T: "logisk og med understrek"] # 0x2a5f (en: 'logical and with underbar') - - "⩠": [T: "logisk og med dobbel understrek"] # 0x2a60 (en: 'logical and with double underbar', google: 'logisk och med dubbel underbar') - - "⩡": [T: "liten v med understrek"] # 0x2a61 (en: 'small vee with underbar', google: 'liten vee med underbar') - - "⩢": [T: "logisk eller med dobbel horisontal strek over"] # 0x2a62 (en: 'logical or with double overbar', google: 'logisk eller med dubbel överbar') - - "⩣": [T: "logisk eller med dobbel understrek"] # 0x2a63 (en: 'logical or with double underbar', google: 'logisk eller med dubbel underbar') - - "⩤": [T: "definisjonsmengde antibegrensning z-notasjon"] # 0x2a64 (en: 'z notation domain antirestriction', google: 'z notation domain antirestriction') - - "⩥": [T: "verdimengde antibegrensning z-notasjon"] # 0x2a65 (en: 'z notation range antirestriction', google: 'z notation range antirestriction') - - "⩦": [T: "lik med prikk under"] # 0x2a66 (en: 'equals sign with dot below') - - "⩧": [T: "prikk over identisk med"] # 0x2a67 (en: 'identical with dot above', google: 'identisk med prick ovan') - - "⩨": [T: "trippel horisontal strek med dobbel vertikal strek"] # 0x2a68 (en: 'triple horizontal bar with double vertical stroke', google: 'trippel horisontell stång med dubbel vertikal stroke') - - "⩩": [T: "trippel horisontal strek med trippel vertikal strek"] # 0x2a69 (en: 'triple horizontal bar with triple vertical stroke', google: 'trippel horisontell stång med trippel vertikal stroke') - - "⩪": [T: "tilde med prikk over"] # 0x2a6a (en: 'tilde operator with dot above') - - "⩫": [T: "tilde med stigende prikker"] # 0x2a6b (en: 'tilde operator with rising dots', google: 'tilde -operatör med stigande prickar') - - "⩬": [T: "asymptotisk lik over tilde"] # 0x2a6c (en: 'similar minus similar', google: 'liknande minus liknande') - - "⩭": [T: "tilnærmet lik med prikk over"] # 0x2a6d (en: 'congruent with dot above') - - "⩮": [T: "lik med asterisk over"] # 0x2a6e (en: 'equals with asterisk', google: 'lika med asterisk') - - "⩯": [T: "tilnærmet lik med cirkumfleks"] # 0x2a6f (en: 'almost equal to with circumflex accent') - - "⩰": [T: "tilnærmet lik eller lik"] # 0x2a70 (en: 'approximately equal to or equal to', google: 'ungefär lika med eller lika med') - - "⩱": [T: "lik over pluss"] # 0x2a71 (en: 'equals sign above plus sign') - - "⩲": [T: "pluss over lik"] # 0x2a72 (en: 'plus sign above equals sign') - - "⩳": [T: "lik over tilde"] # 0x2a73 (en: 'equals sign above tilde operator') - - "⩴": [T: "dobbelt kolon lik"] # 0x2a74 (en: 'double colon equal') - - "⩵": [T: "dobbelt likhetstegn"] # 0x2a75 (en: 'two consecutive equals signs') - - "⩶": [T: "trippelt likhetstegn"] # 0x2a76 (en: 'three consecutive equals signs', google: 'tre på varandra följande tecken') - - "⩷": [T: "lik med to prikker over og to prikker under"] # 0x2a77 (en: 'equals sign with two dots above and two dots below') - - "⩸": [T: "fire prikker over identisk med"] # 0x2a78 (en: 'equivalent with four dots above') - - "⩹": [T: "mindre enn med sirkel i"] # 0x2a79 (en: 'less than with circle inside') - - "⩺": [T: "større enn med sirkel i"] # 0x2a7a (en: 'greater than with circle inside') - - "⩻": [T: "mindre enn med spørsmålstegn over"] # 0x2a7b (en: 'less than with question mark above') - - "⩼": [T: "større enn med spørsmålstegn over"] # 0x2a7c (en: 'greater than with question mark above') - - "⩽": [T: "mindre enn eller lik"] # 0x2a7d (en: 'less than or slanted equal to') - - "⩾": [T: "større enn eller lik"] # 0x2a7e (en: 'greater than or slanted equal to') - - "⩿": [T: "mindre enn eller lik med prikk"] # 0x2a7f (en: 'less than or slanted equal to with dot inside') - - "⪀": [T: "større enn eller lik med prikk"] # 0x2a80 (en: 'greater than or slanted equal to with dot inside') - - "⪁": [T: "mindre enn eller lik med prikk over til venstre"] # 0x2a81 (en: 'less than or slanted equal to with dot above') - - "⪂": [T: "større enn eller lik med prikk over til høyre"] # 0x2a82 (en: 'greater than or slanted equal to with dot above') - - "⪃": [T: "mindre enn eller lik med prikk over til høyre"] # 0x2a83 (en: 'less than or slanted equal to with dot above right') - - "⪄": [T: "større enn eller lik med prikk over til venstre"] # 0x2a84 (en: 'greater than or slanted equal to with dot above left') - - "⪅": [T: "mindre enn eller tilnærmet lik"] # 0x2a85 (en: 'less than or approximate', google: 'mindre än eller ungefärligt') - - "⪆": [T: "større enn eller tilnærmet lik"] # 0x2a86 (en: 'greater than or approximate', google: 'större än eller ungefärligt') - - "⪇": [T: "mindre enn men ikke lik"] # 0x2a87 (en: 'less than and single line not equal to', google: 'mindre än och enstaka linjer inte lika med') - - "⪈": [T: "større enn men ikke lik"] # 0x2a88 (en: 'greater than and single line not equal to', google: 'större än och enstaka linjer inte lika med') - - "⪉": [T: "mindre enn men ikke tilnærmet lik"] # 0x2a89 (en: 'less than and not approximate') - - "⪊": [T: "større enn men ikke tilnærmet lik"] # 0x2a8a (en: 'greater than and not approximate') - - "⪋": [T: "mindre enn over lik over større enn"] # 0x2a8b (en: 'less than above double line equal above greater than', google: 'mindre än över dubbel linje lika över större än') - - "⪌": [T: "større enn over lik over mindre enn"] # 0x2a8c (en: 'greater than above double line equal above less than', google: 'större än över dubbel linje lika över mindre än') - - "⪍": [T: "mindre enn over asymptotisk lik"] # 0x2a8d (en: 'less than above similar or equal') - - "⪎": [T: "større enn over asymptotisk lik"] # 0x2a8e (en: 'greater than above similar or equal') - - "⪏": [T: "mindre enn over tilde over større enn"] # 0x2a8f (en: 'less than above similar above greater than') - - "⪐": [T: "større enn over tilde over mindre enn"] # 0x2a90 (en: 'greater than above similar above less than') - - "⪑": [T: "mindre enn over større enn over lik"] # 0x2a91 (en: 'less than above greater than above double line equal') - - "⪒": [T: "større enn over mindre enn over lik"] # 0x2a92 (en: 'greater than above less than above double line equal') - - "⪓": [T: "mindre enn eller lik over større enn eller lik"] # 0x2a93 (en: 'less than above slanted equal above greater than above slanted equal') - - "⪔": [T: "større enn eller lik over mindre enn eller lik"] # 0x2a94 (en: 'greater than above slanted equal above less than above slanted equal') - - "⪕": [T: "lik eller mindre enn"] # 0x2a95 (en: 'slanted equal to or less than', google: 'lutt lika med eller mindre än') - - "⪖": [T: "lik eller større enn"] # 0x2a96 (en: 'slanted equal to or greater than', google: 'lutt lika med eller större än') - - "⪗": [T: "lik eller mindre enn med prikk"] # 0x2a97 (en: 'slanted equal to or less than with dot inside') - - "⪘": [T: "lik eller større enn med prikk"] # 0x2a98 (en: 'slanted equal to or greater than with dot inside') - - "⪙": [T: "lik eller mindre enn"] # 0x2a99 (en: 'double line equal to or less than', MathPlayer: 'equal (dubbel) over less than', google: 'dubbel linje lika med eller mindre än') - - "⪚": [T: "lik eller større enn"] # 0x2a9a (en: 'double line equal to or greater than') - - "⪛": [T: "lik eller mindre enn"] # 0x2a9b (en: 'double line slanted equal to or less than', google: 'dubbel linje lutad lika med eller mindre än') - - "⪜": [T: "lik eller større enn"] # 0x2a9c (en: 'double line slanted equal to or greater than', google: 'dubbel linje lutad lika med eller större än') - - "⪝": [T: "tilnærmet lik eller mindre enn"] # 0x2a9d (en: 'similar or less than') - - "⪞": [T: "tilnærmet lik eller større enn"] # 0x2a9e (en: 'similar or greater than') - - "⪟": [T: "tilnærmet lik over mindre enn over lik"] # 0x2a9f (en: 'similar above less than above equals sign') - - "⪠": [T: "tilnærmet lik over større enn over lik"] # 0x2aa0 (en: 'similar above greater than above equals sign') - - "⪡": [T: "dobbel mindre enn"] # 0x2aa1 (en: 'double nested less than') - - "⪢": [T: "dobbel større enn"] # 0x2aa2 (en: 'double nested greater than') - - "⪣": [T: "dobbel mindre enn med strek under"] # 0x2aa3 (en: 'double nested less than with underbar', google: 'dubbel kapslad mindre än med underbar') - - "⪤": [T: "større enn overlapper mindre enn"] # 0x2aa4 (en: 'greater than overlapping less than') - - "⪥": [T: "større enn ved siden av mindre enn"] # 0x2aa5 (en: 'greater than beside less than') - - "⪦": [T: "mindre enn lukket av kurve"] # 0x2aa6 (en: 'less than closed by curve') - - "⪧": [T: "større enn lukket av kurve"] # 0x2aa7 (en: 'greater than closed by curve') - - "⪨": [T: "mindre enn lukket av kurve over lik"] # 0x2aa8 (en: 'less than closed by curve above slanted equal') - - "⪩": [T: "større enn lukket av kurve over lik"] # 0x2aa9 (en: 'greater than closed by curve above slanted equal') - - "⪪": [T: "mindre enn"] # 0x2aaa (en: 'smaller than') - - "⪫": [T: "større enn"] # 0x2aab (en: 'larger than') - - "⪬": [T: "mindre enn eller lik"] # 0x2aac (en: 'smaller than or equal to') - - "⪭": [T: "større enn eller lik"] # 0x2aad (en: 'larger than or equal to') - - "⪮": [T: "lik med hump over"] # 0x2aae (en: 'equals sign with bumpy above', MathPlayer: 'difference between (grav accentnt)', google: 'är lika med tecken med ojämn ovan') - - "⪯": [T: "foregår over likhetsstrek"] # 0x2aaf (en: 'precedes above single line equals sign') - - "⪰": [T: "følger over likhetsstrek"] # 0x2ab0 (en: 'succeeds above single line equals sign', google: 'lyckas över enstaka linjen är lika med tecken') - - "⪱": [T: "foregår over utstrøket likhetsstrek"] # 0x2ab1 (en: 'precedes above single line not equal to', google: 'föregår över enstaka linjer som inte är lika med') - - "⪲": [T: "følger over utstrøket likhetsstrek"] # 0x2ab2 (en: 'succeeds above single line not equal to', google: 'lyckas över enstaka linjer som inte är lika med') - - "⪳": [T: "foregår over lik"] # 0x2ab3 (en: 'precedes above equals sign', google: 'föregår över lika tecken') - - "⪴": [T: "følger over lik"] # 0x2ab4 (en: 'succeeds above equals sign', google: 'lyckas över lika tecken') - - "⪵": [T: "foregår over ikke lik"] # 0x2ab5 (en: 'precedes above not equal to') - - "⪶": [T: "følger over ikke lik"] # 0x2ab6 (en: 'succeeds above not equal to') - - "⪷": [T: "foregår over tilnærmet lik"] # 0x2ab7 (en: 'precedes above almost equal to', google: 'föregår över nästan lika med') - - "⪸": [T: "følger over tilnærmet lik"] # 0x2ab8 (en: 'succeeds above almost equal to', google: 'lyckas över nästan lika med') - - "⪹": [T: "foregår over ikke tilnærmet lik"] # 0x2ab9 (en: 'precedes above not almost equal to', google: 'föregår ovan inte nästan lika med') - - "⪺": [T: "følger over ikke tilnærmet lik"] # 0x2aba (en: 'succeeds above not almost equal to', google: 'lyckas ovan inte nästan lika med') - - "⪻": [T: "dobbel foregår"] # 0x2abb (en: 'double precedes') - - "⪼": [T: "dobbel følger"] # 0x2abc (en: 'double succeeds') - - "⪽": [T: "delmengde med prikk"] # 0x2abd (en: 'subset with dot') - - "⪾": [T: "overmengde med prikk"] # 0x2abe (en: 'superset with dot') - - "⪿": [T: "delmengde med pluss under"] # 0x2abf (en: 'subset with plus sign below', MathPlayer: 'delmängd med plustecken under', google: 'delmängd med plus -skylt nedan') - - "⫀": [T: "overmengde med pluss under"] # 0x2ac0 (en: 'superset with plus sign below', MathPlayer: 'delmängd med plustecken under', google: 'superset med plus -skylt nedan') - - "⫁": [T: "delmengde med multiplikasjon under"] # 0x2ac1 (en: 'subset with multiplication sign below') - - "⫂": [T: "overmengde med multiplikasjon under"] # 0x2ac2 (en: 'superset with multiplication sign below') - - "⫃": [T: "delmengde av eller lik med prikk over"] # 0x2ac3 (en: 'subset of or equal to with dot above') - - "⫄": [T: "overmengde av eller lik med prikk over"] # 0x2ac4 (en: 'superset of or equal to with dot above') - - "⫅": [T: "delmenge av over lik"] # 0x2ac5 (en: 'subset of above equals sign', google: 'undergruppen ovan är lika med tecken') - - "⫆": [T: "overmengde av over lik"] # 0x2ac6 (en: 'superset of above equals sign', google: 'superset av ovan är lika med tecken') - - "⫇": [T: "delmengde av over tilde"] # 0x2ac7 (en: 'subset of above tilde operator') - - "⫈": [T: "overmengde av over tilde"] # 0x2ac8 (en: 'superset of above tilde operator') - - "⫉": [T: "delmengde av over tilnærmet lik"] # 0x2ac9 (en: 'subset of above almost equal to', google: 'delmängd över nästan lika med') - - "⫊": [T: "overmengde av over tilnærmet lik"] # 0x2aca (en: 'superset of above almost equal to', google: 'superset över nästan lika med') - - "⫋": [T: "delmengde av over ikke lik"] # 0x2acb (en: 'subset above not equal to', google: 'delmängd ovan inte lika med') - - "⫌": [T: "overmengde av over ikke lik"] # 0x2acc (en: 'superset of above not equal to', google: 'superset av ovan inte lika med') - - "⫍": [T: "venstre kvadratisk åpen boks"] # 0x2acd (en: 'square left open box operator', google: 'square left open box operator') - - "⫎": [T: "høyre kvadratisk åpen boks"] # 0x2ace (en: 'square right open box operator', google: 'square right open box operator') - - "⫏": [T: "lukket delmengde"] # 0x2acf (en: 'closed subset') - - "⫐": [T: "lukket overmengde"] # 0x2ad0 (en: 'closed superset') - - "⫑": [T: "lukket delmengde eller lik"] # 0x2ad1 (en: 'closed subset or equal to') - - "⫒": [T: "lukket overmengde eller lik"] # 0x2ad2 (en: 'closed superset or equal to') - - "⫓": [T: "delmengde over overmengde"] # 0x2ad3 (en: 'subset above superset') - - "⫔": [T: "overmengde over delmengde"] # 0x2ad4 (en: 'superset above subset') - - "⫕": [T: "delmengde over delmengde"] # 0x2ad5 (en: 'subset above subset') - - "⫖": [T: "overmengde over overmengde"] # 0x2ad6 (en: 'superset above superset') - - "⫗": [T: "overmengde ved siden av delmengde"] # 0x2ad7 (en: 'superset beside subset') - - "⫘": [T: "overmengde ved siden av og sammenføyd med delmengde"] # 0x2ad8 (en: 'superset beside and joined by dash with subset') - - "⫙": [T: "tilhører med åpning nedover"] # 0x2ad9 (en: 'element of opening downwards') - - "⫚": [T: "høygaffel med t øverst"] # 0x2ada (en: 'pitchfork with tee top') - - "⫛": [T: "tverrgående snitt"] # 0x2adb (en: 'transversal intersection') - - "⫝̸": [T: "avhengig"] # 0x2adc (en: 'forking', google: 'gaffel') - - "⫝": [T: "uavhengig"] # 0x2add (en: 'nonforking', google: 'icke -förflyttning') - - "⫞": [T: "kort venstre dreiekors"] # 0x2ade (en: 'short left tack', google: 'kort vänster tack') - - "⫟": [T: "kort nedoverrotert dreiekors"] # 0x2adf (en: 'short down tack', google: 'kort ner') - - "⫠": [T: "kort oppoverrotert dreiekors"] # 0x2ae0 (en: 'short up tack', google: 'kort upp tack') - - "⫡": [T: "vinkelrett med s"] # 0x2ae1 (en: 'perpendicular with s', google: 'vinkelrätt med s') - - "⫢": [T: "vertikal strek trippelt høyre dreiekors"] # 0x2ae2 (en: 'vertical bar triple right turnstile', google: 'vertikal bar trippel höger turnstile') - - "⫣": [T: "dobbel vertikal strek venstre dreiekors"] # 0x2ae3 (en: 'double vertical bar left turnstile', google: 'dubbel vertikal stång vänster turnstile') - - "⫤": [T: "vertikal strek dobbelt venstre dreiekors"] # 0x2ae4 (en: 'vertical bar double left turnstile') - - "⫥": [T: "dobbel vertikal strek dobbelt venstre dreiekors"] # 0x2ae5 (en: 'double vertical bar double left turnstile', google: 'dubbel vertikal stång dubbel vänster vridstil') - - "⫦": [T: "dreiekors med vertikal strek"] # 0x2ae6 (en: 'long dash from left member of double vertical') - - "⫧": [T: "nedoverrotert kort dreiekors med horisontal strek over"] # 0x2ae7 (en: 'short down tack with overbar') - - "⫨": [T: "oppoverrotert kort dreiekors med horisontal strek under"] # 0x2ae8 (en: 'short up tack with underbar') - - "⫩": [T: "oppoverrotert kort dreiekors over nedoverrotert kort dreiekors"] # 0x2ae9 (en: 'short up tack above short down tack') - - "⫪": [T: "nedoverrotert dobbelt dreiekors"] # 0x2aea (en: 'double down tack', google: 'dubbel down tack') - - "⫫": [T: "oppoverrotert dobbelt dreiekors"] # 0x2aeb (en: 'double up tack') - - "⫬": [T: "dobbeltstreket ikke"] # 0x2aec (en: 'double stroke not sign') - - "⫭": [T: "omvendt dobbeltstreket ikke"] # 0x2aed (en: 'reversed double stroke not sign') - - "⫮": [T: "deler ikke med omvendt skråstrek"] # 0x2aee (en: 'does not divide with reversed negation slash') - - "⫯": [T: "vertikal strek med sirkel over"] # 0x2aef (en: 'vertical line with circle above') - - "⫰": [T: "vertikal strek med sirkel under"] # 0x2af0 (en: 'vertical line with circle below') - - "⫱": [T: "nedoverrotert dreiekors med sirkel under"] # 0x2af1 (en: 'down tack with circle below') - - "⫲": [T: "parallel med horisontal strek"] # 0x2af2 (en: 'parallel with horizontal stroke') - - "⫳": [T: "parallel med tilde"] # 0x2af3 (en: 'parallel with tilde operator') - - "⫴": [T: "trippel loddrett strek"] # 0x2af4 (en: 'triple vertical bar binary relation', google: 'trippel vertikal bar binär relation') - - "⫵": [T: "trippel loddrett strek med horisontal strek"] # 0x2af5 (en: 'triple vertical bar with horizontal stroke', google: 'trippel vertikal stång med horisontellt slag') - - "⫶": [T: "trippelkolon"] # 0x2af6 (en: 'triple colon operator', google: 'trippel kolonoperatör') - - "⫷": [T: "trippel mindre enn"] # 0x2af7 (en: 'triple nested less than', google: 'trippel kapslade mindre än') - - "⫸": [T: "trippel større enn"] # 0x2af8 (en: 'triple nested greater than', google: 'trippel kapslad större än') - - "⫹": [T: "mindre enn eller lik"] # 0x2af9 (en: 'double line slanted less than or equal to', google: 'dubbel linje lutad mindre än eller lika med') - - "⫺": [T: "større enn eller lik"] # 0x2afa (en: 'double line slanted greater than or equal to', google: 'dubbel linje lutad större än eller lika med') - - "⫻": [T: "trippel skråstrek"] # 0x2afb (en: 'triple solidus binary relation', google: 'trippel solidus binär relation') - - "⫼": [T: "stor trippel vertikal strek"] # 0x2afc (en: 'large triple vertical bar operator', google: 'stor trippel vertikal stångoperatör') - - "⫽": [T: "dobbel skråstrek"] # 0x2afd (en: 'double solidus operator', google: 'dubbel solidus -operatör') - - "⫾": [T: "hvit loddrett strek"] # 0x2afe (en: 'white vertical bar', google: 'vit vertikal stång') - - "⫿": [T: "hvit loddrett strek"] # 0x2aff (en: 'white vertical bar', google: 'vit vertikal stång') - #-------------------------------------------------------------------------------------------------------------- - # Miscellaneous symbols and arrows OK - - "⬀": [T: "hvit nordøst-pil"] # 0x2b00 (en: 'north east white arrow', google: 'north east white arrow') - - "⬁": [T: "hvit nordvest-pil"] # 0x2b01 (en: 'north west white arrow', google: 'north west white arrow') - - "⬂": [T: "hvit sørøst-pil"] # 0x2b02 (en: 'south east white arrow', google: 'south east white arrow') - - "⬃": [T: "hvit sørvest-pil"] # 0x2b03 (en: 'south west white arrow', google: 'south west white arrow') - - "⬄": [T: "hvit venstre-høyre-pil"] # 0x2b04 (en: 'left right white arrow', google: 'vänster höger vit pil') - - "⬅": [T: "fylt venstrepil"] # 0x2b05 (en: 'leftwards black arrow', google: 'vänster svart pil') - - "⬆": [T: "fylt oppoverpil"] # 0x2b06 (en: 'upwards black arrow', google: 'uppåt svart pil') - - "⬇": [T: "fylt nedoverpil"] # 0x2b07 (en: 'downwards black arrow', google: 'nedåt svart pil') - - "⬈": [T: "fylt nordøst-pil"] # 0x2b08 (en: 'north east black arrow', google: 'north east black arrow') - - "⬉": [T: "fylt nordvest-pil"] # 0x2b09 (en: 'north west black arrow', google: 'north west black arrow') - - "⬊": [T: "fylt sørøst-pil"] # 0x2b0a (en: 'south east black arrow', google: 'south east black arrow') - - "⬋": [T: "fylt sørvest-pil"] # 0x2b0b (en: 'south west black arrow', google: 'south west black arrow') - - "⬌": [T: "fylt venstre-høyre-pil"] # 0x2b0c (en: 'left right black arrow', google: 'vänster höger svart pil') - - "⬍": [T: "fylt opp-ned-pil"] # 0x2b0d (en: 'up down black arrow', google: 'upp ner black arrow') - - "⬎": [T: "høyrepil med spiss ned"] # 0x2b0e (en: 'rightwards arrow with tip downwards', google: 'åtgärdspil med spets nedåt') - - "⬏": [T: "høyrepil med spiss opp"] # 0x2b0f (en: 'rightwards arrow with tip upwards', google: 'åtgärdspil med spetsen uppåt') - - "⬐": [T: "venstrepil med spiss ned"] # 0x2b10 (en: 'leftwards arrow with tip downwards', google: 'vänster pil med spetsen nedåt') - - "⬑": [T: "venstrepil med spiss opp"] # 0x2b11 (en: 'leftwards arrow with tip upwards', google: 'vänster pil med spetsen uppåt') - - "⬒": [T: "kvadrat med øvre halvdel fylt"] # 0x2b12 (en: 'square with top half black', google: 'fyrkantig med topphalva svart') - - "⬓": [T: "kvadrat med nedre halvdel fylt"] # 0x2b13 (en: 'square with bottom half black', google: 'fyrkantig med botten halvsvart') - - "⬔": [T: "kvadrat med øvre høyre diagonal halvfylt"] # 0x2b14 (en: 'square with upper right diagonal half black', google: 'fyrkantig med övre högra diagonala halvsvart') - - "⬕": [T: "kvadrat med nedre venstre diagonal halvfylt"] # 0x2b15 (en: 'square with lower left diagonal half black', google: 'fyrkantig med nedre vänster diagonal halvsvart') - - "⬖": [T: "diamant med venstre halvdel fylt"] # 0x2b16 (en: 'diamond with left half black', google: 'diamant med vänster halvsvart') - - "⬗": [T: "diamant med høyre halvdel fylt"] # 0x2b17 (en: 'diamond with right half black', google: 'diamant med höger halv svart') - - "⬘": [T: "diamant med øvre halvdel fylt"] # 0x2b18 (en: 'diamond with top half black', google: 'diamant med topp halva svart') - - "⬙": [T: "diamant med nedre halvdel fylt"] # 0x2b19 (en: 'diamond with bottom half black', google: 'diamant med botten halvsvart') - - "⬚": [T: "prikket kvadrat"] # 0x2b1a (en: 'box', google: 'låda') - - "⬛": [T: "stort svart kvadrat"] # 0x2b1b (en: 'black large square', google: 'svart stort fyrkant') - - "⬜": [T: "stort hvitt kvadrat"] # 0x2b1c (en: 'white large square', google: 'vit stor fyrkant') - - "⬝": [T: "veldig lite svart kvadrat"] # 0x2b1d (en: 'black very small square', google: 'svart mycket litet fyrkant') - - "⬞": [T: "veldig lite hvitt kvadrat"] # 0x2b1e (en: 'white very small square', google: 'vit mycket liten fyrkant') - - "⬟": [T: "svart femkant"] # 0x2b1f (en: 'black pentagon', google: 'svart pentagon') - - "⬠": [T: "hvit femkant"] # 0x2b20 (en: 'white pentagon', google: 'vit pentagon') - - "⬡": [T: "hvit sekskant"] # 0x2b21 (en: 'white hexagon', google: 'vit hexagon') - - "⬢": [T: "svart sekskant"] # 0x2b22 (en: 'black hexagon', google: 'svart hexagon') - - "⬣": [T: "horisontal svart sekskant"] # 0x2b23 (en: 'horizontal black hexagon', google: 'horisontell svart hexagon') - - "⬤": [T: "stor svart sirkel"] # 0x2b24 (en: 'black large circle', google: 'svart stor cirkel') - - "⬥": [T: "svart diamant"] # 0x2b25 (en: 'black medium diamond', google: 'svart medium diamant') - - "⬦": [T: "hvit diamant"] # 0x2b26 (en: 'white medium diamond', google: 'vit medium diamant') - - "⬧": [T: "svart rombe"] # 0x2b27 (en: 'black medium lozenge', google: 'svart medium pastill') - - "⬨": [T: "hvit rombe"] # 0x2b28 (en: 'white medium lozenge', google: 'vit medium pastill') - - "⬩": [T: "liten svart diamant"] # 0x2b29 (en: 'black small diamond') - - "⬪": [T: "liten svart rombe"] # 0x2b2a (en: 'black small lozenge', google: 'svart liten pastill') - - "⬫": [T: "liten hvit rombe"] # 0x2b2b (en: 'white small lozenge', google: 'vit liten pastill') - - "⬬": [T: "svart horisontal ellipse"] # 0x2b2c (en: 'black horizontal ellipse') - - "⬭": [T: "hvit horisontal ellipse"] # 0x2b2d (en: 'white horizontal ellipse') - - "⬮": [T: "svart vertikal ellipse"] # 0x2b2e (en: 'black vertical ellipse', google: 'svart vertikalt ellips') - - "⬯": [T: "hvit vertikal ellipse"] # 0x2b2f (en: 'white vertical ellipse') - - "⬰": [T: "venstrepil med liten sirkel"] # 0x2b30 (en: 'left arrow with small circle', google: 'vänster pil med liten cirkel') - - "⬱": [T: "tre venstrepiler"] # 0x2b31 (en: 'three leftwards arrows') - - "⬲": [T: "venstrepil med pluss i sirkel"] # 0x2b32 (en: 'left arrow with circled plus', google: 'vänster pil med circled plus') - - "⬳": [T: "lang sikksakk venstrepil"] # 0x2b33 (en: 'long leftwards squiggle arrow', google: 'långt vänster squiggle pil') - - "⬴": [T: "venstrepil med dobbel spiss og vertikal strek"] # 0x2b34 (en: 'leftwards two headed arrow with vertical stroke', google: 'vänster två ledde pil med vertikalt slag') - - "⬵": [T: "venstrepil med dobbel spiss og dobbel vertikal strek"] # 0x2b35 (en: 'leftwards two headed arrow with double vertical stroke', google: 'vänster två ledde pil med dubbel vertikal stroke') - - "⬶": [T: "venstrepil med dobbel spiss fra strek"] # 0x2b36 (en: 'leftwards two headed arrow from bar', google: 'vänster två ledde pil från bar') - - "⬷": [T: "stiplet venstrepil med dobbel spiss"] # 0x2b37 (en: 'leftwards two headed triple dash arrow', google: 'vänster två ledde trippelstreckpil') - - "⬸": [T: "stiplet venstrepil"] # 0x2b38 (en: 'leftwards arrow with dotted stem', google: 'vänster pil med prickad stam') - - "⬹": [T: "venstrepil med vertikal strek og hale"] # 0x2b39 (en: 'leftwards arrow with tail with vertical stroke', google: 'vänster pil med svans med vertikalt slag') - - "⬺": [T: "venstrepil med hale og dobbel vertikal strek"] # 0x2b3a (en: 'leftwards arrow with tail with double vertical stroke', google: 'vänster pil med svans med dubbel vertikal stroke') - - "⬻": [T: "venstrepil med dobbel spiss og hale"] # 0x2b3b (en: 'leftwards two headed arrow with tail', google: 'vänster två ledde pil med svans') - - "⬼": [T: "venstrepil med dobbel spiss, hale og vertikal strek"] # 0x2b3c (en: 'leftwards two headed arrow with tail with vertical stroke', google: 'vänster två ledde pilen med svans med vertikal stroke') - - "⬽": [T: "venstrepil med dobbel spiss, hale og dobbel vertikal strek"] # 0x2b3d (en: 'leftwards two headed arrow with tail with double vertical stroke', google: 'vänster två ledde pilen med svans med dubbel vertikal stroke') - - "⬾": [T: "venstrepil gjennom x"] # 0x2b3e (en: 'leftwards arrow through x', google: 'vänster pil genom x') - - "⬿": [T: "bølget venstrepil"] # 0x2b3f (en: 'wave arrow pointing directly left', google: 'wave arrow pekade direkt kvar') - - "⭀": [T: "venstrepil med likhetstegn"] # 0x2b40 (en: 'equals sign above leftwards arrow', google: 'är lika med skylt över vänster pil') - - "⭁": [T: "venstrepil med speilvendt tilde"] # 0x2b41 (en: 'reverse tilde operator above leftwards arrow', google: 'omvänd tilde -operatör över vänster pil') - - "⭂": [T: "venstrepil over speilvendt omtrent lik"] # 0x2b42 (en: 'leftwards arrow above reverse almost equal to', google: 'vänster pil över omvänd nästan lika med') - - "⭃": [T: "høyrepil gjennom større enn"] # 0x2b43 (en: 'rightwards arrow through greater than', google: 'åtgärdspil genom större än') - - "⭄": [T: "høyrepil gjennom overmengde"] # 0x2b44 (en: 'rightwards arrow through superset', google: 'åtgärdspil genom superset') - - "⭅": [T: "kvadrupel-streket venstrepil"] # 0x2b45 (en: 'leftwards quadruple arrow', google: 'vänster fyrdubbla pil') - - "⭆": [T: "kvadrupel-streket høyrepil"] # 0x2b46 (en: 'rightwards quadruple arrow', google: 'åtgärd med höger fyrdubbla') - - "⭇": [T: "høyrepil med speilvendt tilde"] # 0x2b47 (en: 'reverse tilde operator above rightwards arrow', google: 'omvänd tilde -operatör ovanför höger-pilen') - - "⭈": [T: "høyrepil over speilvendt omtrent lik"] # 0x2b48 (en: 'rightwards arrow above reverse almost equal to', google: 'åtgärdspilen över omvänd nästan lika med') - - "⭉": [T: "venstrepil med tilde"] # 0x2b49 (en: 'tilde operator above leftwards arrow', google: 'tilde -operatören ovanför vänster pil') - - "⭊": [T: "venstrepil over omtrent lik"] # 0x2b4a (en: 'leftwards arrow above almost equal to', google: 'vänster pil över nästan lika med') - - "⭋": [T: "venstrepil over speilvendt tilde"] # 0x2b4b (en: 'leftwards arrow above reverse tilde operator', google: 'vänster pil ovanför omvänd tilde -operatör') - - "⭌": [T: "høyrepil over speilvendt tilde"] # 0x2b4c (en: 'rightwards arrow above reverse tilde operator', google: 'åtgärdspil över omvänd tilde -operatör') - - "⭐": [T: "hvit stjerne"] # 0x2b50 (en: 'white medium star') - - "⭑": [T: "liten svart stjerne"] # 0x2b51 (en: 'black small star') - - "⭒": [T: "liten hvit stjerne"] # 0x2b52 (en: 'white small star') - - "⭓": [T: "svart femkant som peker til høyre"] # 0x2b53 (en: 'black right pointing pentagon', google: 'svart höger pekande pentagon') - - "⭔": [T: "hvit femkant som peker til høyre"] # 0x2b54 (en: 'white right pointing pentagon', google: 'vit höger pekande pentagon') - - "⭕": [T: "fet stor sirkel"] # 0x2b55 (en: 'heavy large circle', google: 'tung stor cirkel') - - "⭖": [T: "fet oval med oval i"] # 0x2b56 (en: 'heavy oval with oval inside', google: 'tung oval med oval inuti') - - "⭗": [T: "fet sirkel med sirkel i"] # 0x2b57 (en: 'heavy circle with circle inside', google: 'tung cirkel med cirkel inuti') - - "⭘": [T: "fet sirkel"] # 0x2b58 (en: 'heavy circle', google: 'tung cirkel') - - "⭙": [T: "fet kryss i sirkel"] # 0x2b59 (en: 'heavy circled saltire', google: 'tung cirklad saltire') - #------------------------------------------------------------------------------------------------------------ - # Supplemental punctuation OK - - "⸀": [T: "rett vinkel erstatningsmarkør"] # 0x2e00 (en: 'right angle substitution marker', google translation) - - "⸁": [T: "rett vinkel erstatningsmarkør med prikk"] # 0x2e01 (en: 'right angle dotted substitution marker', google translation) - - "⸂": [T: "venstre erstatningsparentes"] # 0x2e02 (en: 'left substitution bracket', google translation) - - "⸃": [T: "høyre erstatningsparentes"] # 0x2e03 (en: 'right substitution bracket', google translation) - - "⸄": [T: "venstre erstatningsparentes med prikk"] # 0x2e04 (en: 'left dotted substitution bracket', google translation) - - "⸅": [T: "høyre erstatningsparentes med prikk"] # 0x2e05 (en: 'right dotted substitution bracket', google translation) - - "⸆": [T: "hevet interpolasjonsmarkør"] # 0x2e06 (en: 'raised interpolation marker', google translation) - - "⸇": [T: "hevet interpolasjonsmarkør med prikk"] # 0x2e07 (en: 'raised dotted interpolation marker', google translation) - - "⸈": [T: "venstre transposisjonsmarkør med prikk"] # 0x2e08 (en: 'dotted transposition marker marker', google translation) - - "⸉": [T: "venstre transposisjonsparentes"] # 0x2e09 (en: 'left transposition bracket', google translation) - - "⸊": [T: "høyre transposisjonsparentes"] # 0x2e0a (en: 'right transposition bracket', google translation) - - "⸋": [T: "hevet kvadrat"] # 0x2e0b (en: 'raised square', google translation) - - "⸌": [T: "venstre hevet utelatelses-parentes"] # 0x2e0c (en: 'left raised omission bracket', google translation) - - "⸍": [T: "høyre hevet utelatelses-parentes"] # 0x2e0d (en: 'right raised omission bracket', google translation) - - "⸎": [T: "redaksjonell coronis"] # 0x2e0e (en: 'editorial coronis', google translation) - - "⸏": [T: "paragraphos"] # 0x2e0f (google translation) - - "⸐": [T: "forgreinet paragraphos"] # 0x2e10 (en: 'forked paragraphos', google translation) - - "⸑": [T: "speilvendt forgreinet paragraphos"] # 0x2e11 (en: 'reversed forked paragraphos', google translation) - - "⸒": [T: "hypodiastol"] # 0x2e12 (google translation) - - "⸓": [T: "prikket obelus"] # 0x2e13 (en: 'dotted obelos', google translation) - - "⸔": [T: "nedover ancora"] # 0x2e14 (en: 'downwards ancora', google translation) - - "⸕": [T: "oppover ancora"] # 0x2e15 (en: 'upwards ancora', google translation) - - "⸖": [T: "prikket høyrepekende vinkel"] # 0x2e16 (en: 'dotted right pointing angle', google translation) - - "⸗": [T: "dobbel skrå bindestrek"] # 0x2e17 (en: 'double oblique hyphen', google translation) - - "⸘": [T: "omvendt interrobang"] # 0x2e18 (en: 'inverted interrobang', google translation) - - "⸙": [T: "palmegren"] # 0x2e19 (google translation) - - "⸚": [T: "bindestrek med trema"] # 0x2e1a (en: 'hyphen with diaeresis', google translation) - - "⸛": [T: "tilde med ring"] # 0x2e1b (en: 'tilde with ring above', google translation) - - "⸜": [T: "lav venstre parafraseparentes"] # 0x2e1c (en: 'left low paraphrase bracket', google translation) - - "⸝": [T: "lav høyre parafraseparentes"] # 0x2e1d (en: 'right low paraphrase bracket', google translation) - - "⸞": [T: "tilde med prikk over"] # 0x2e1e (en: 'tilde with dot above', google translation) - - "⸟": [T: "tilde med prikk under"] # 0x2e1f (en: 'tilde with dot below', google translation) - - "⸠": [T: "vertikal strek med pigg til høyre"] # 0x2e20 (en: 'left vertical bar with quill', google translation) - - "⸡": [T: "vertikal strek med pigg til venstre"] # 0x2e21 (en: 'right vertical bar with quill', google translation) - - "⸢": [T: "øvre venstre halv hakeparentes"] # 0x2e22 (en: 'top left half bracket', google: 'överst till vänster halvfäste') - - "⸣": [T: "øvre høyre halv hakeparentes"] # 0x2e23 (en: 'top right half bracket', google: 'överst till höger halva konsol') - - "⸤": [T: "nedre venstre halv hakeparentes"] # 0x2e24 (en: 'bottom left half bracket', google: 'nedre vänstra halvfästet') - - "⸥": [T: "nedre høyre halv hakeparentes"] # 0x2e25 (en: 'bottom right half bracket', google: 'nedre högra halvfästet') - - "⸦": [T: "venstre u-parentes"] # 0x2e26 (en: 'left sideways u bracket', google: 'vänster i sidled u konsol') - - "⸧": [T: "høyre u-parentes"] # 0x2e27 (en: 'right sideways u bracket', google: 'höger i sidled u konsol') - - "⸨": [T: "dobbel venstreparentes"] # 0x2e28 (en: 'left double parentheses', google: 'vänster dubbla parenteser') - - "⸩": [T: "dobbel høyreparentes"] # 0x2e29 (en: 'right double parentheses', google: 'höger dubbel parentes') - - "⸪": [T: "to prikker over én prikk"] # 0x2e2a (en: 'two dots over one dot punctuation', google translation) - - "⸫": [T: "én prikk over to prikker"] # 0x2e2b (en: 'one dot over two dots punctuation', google translation) - - "⸬": [T: "fire prikker i kvadrat"] # 0x2e2c (en: 'squared four dot punctuation', google translation) - - "⸭": [T: "fem prikker i kryss"] # 0x2e2d (en: 'five dot mark', google translation) - - "⸮": [T: "speilvendt spørsmålstegn"] # 0x2e2e (en: 'reversed question mark', google translation) - - "ⸯ": [T: "vertikal tilde"] # 0x2e2f (en: 'vertical tilde', google translation) - - "⸰": [T: "ringpunkt"] # 0x2e30 (en: 'ring point', google translation) - - "⸱": [T: "ordskille-punkt"] # 0x2e31 (google translation) - - "⸲": [T: "rotert komma"] # 0x2e32 (en: 'turned comma', google translation) - - "⸳": [T: "hevet prikk"] # 0x2e33 (en: 'raised dot', google translation) - - "⸴": [T: "hevet komma"] # 0x2e34 (en: 'raised comma', google translation) - - "⸵": [T: "rotert semikolon"] # 0x2e35 (en: 'turned semicolon', google translation) - - "⸶": [T: "dolk med venstre vaktstang"] # 0x2e36 (en: 'dagger with left guard', google translation) - - "⸷": [T: "dolk med høyre vaktstang"] # 0x2e37 (en: 'dagger with right guard', google translation) - - "⸸": [T: "rotert dolk"] # 0x2e38 (en: 'turned dagger', google translation) - - "⸹": [T: "øvre halvt avsnittssymbol"] # 0x2e39 (en: 'top half section sign', google translation) - - "⸺": [T: "dobbel tankestrek"] # 0x2e3a (en: 'two em dash', google translation) - - "⸻": [T: "trippel tankestrek"] # 0x2e3b (en: 'three em dash', google translation) - #------------------------------------------------------------------------------------------------------------------- - # CJK symbols and punctuation OK - - "〃": [T: "gjentategn"] # 0x3003 (google translation) - - "〈": [T: "venstre vinkelparentes"] # 0x3008 (en: 'left angle bracket', google: 'vänster vinkelfäste') - - "〉": [T: "høyre vinkelparentes"] # 0x3009 (en: 'right angle bracket', google: 'rätt vinkelfäste') - - "《": [T: "dobbel venstre vinkelparentes"] # 0x300a (en: 'left double angle bracket') - - "》": [T: "dobbel høyre vinkelparentes"] # 0x300b (en: 'right double angle bracket') - - "「": [T: "venstre hjørneparentes"] # 0x300c (en: 'left corner bracket', google: 'vänster hörnfäste') - - "」": [T: "høyre hjørneparentes"] # 0x300d (en: 'right corner bracket', google: 'höger hörnfäste') - - "『": [T: "venstre hvit hjørneparentes"] # 0x300e (en: 'left white corner bracket', google: 'vänster vit hörnfäste') - - "』": [T: "høyre hvit hjørneparentes"] # 0x300f (en: 'right white corner bracket', google: 'höger vit hörnfäste') - - "【": [T: "venstre svart linseformet hakeparentes"] # 0x3010 (en: 'left black lenticular bracket', google: 'vänster svart linsformell konsol') - - "】": [T: "høyre svart linseformet hakeparentes"] # 0x3011 (en: 'right black lenticular bracket', google: 'höger svart linsformell konsol') - - "〔": [T: "venstre skilpaddeskall-parentes"] # 0x3014 (en: 'left tortoise shell bracket') - - "〕": [T: "høyre skilpaddeskall-parentes"] # 0x3015 (en: 'right tortoise shell bracket') - - "〖": [T: "venstre hvit linseformet hakeparentes"] # 0x3016 (en: 'left white lenticular bracket', google: 'vänster vit linsformad konsol') - - "〗": [T: "høyre hvit linseformet hakeparentes"] # 0x3017 (en: 'right white lenticular bracket', google: 'höger vit linsformad konsol') - - "〘": [T: "venstre hvit skilpaddeskall-parentes"] # 0x3018 (en: 'left white tortoise shell bracket', google: 'vänster vit sköldpaddsskalfäste') - - "〙": [T: "høyre hvit skilpaddeskall-parentes"] # 0x3019 (en: 'right white tortoise shell bracket', google: 'höger vit sköldpaddsskalfäste') - - "〚": [T: "venstre hvit hakeparentes"] # 0x301a (en: 'left white square bracket') - - "〛": [T: "høyre hvit hakeparentes"] # 0x301b (en: 'right white square bracket') - - "〜": [T: "bølgestrek"] # 0x301c (en: 'wave dash', google: 'wave dash') - - "〰": [T: "bølget strek"] # 0x3030 (en: 'wavy dash', google: 'wavy dash') - #---------------------------------------------------------------------------------------------------------------------------------- - # Enclosed CJK letters and months OK - - "㉈": [T: "ti i sirkel på fylt kvadrat"] # 0x3248 (en: 'circled number ten on black square', google: 'cirklat nummer tio på black square') - - "㉉": [T: "tjue i sirkel på fylt kvadrat"] # 0x3249 (en: 'circled number twenty on black square', google: 'cirklat nummer tjugo på black square') - - "㉊": [T: "tretti i sirkel på fylt kvadrat"] # 0x324a (en: 'circled number thirty on black square', google: 'cirklat nummer trettio på black square') - - "㉋": [T: "førti i sirkel på fylt kvadrat"] # 0x324b (en: 'circled number forty on blacks square', google: 'cirklat nummer fyrtio på blacks square') - - "㉌": [T: "femti i sirkel på fylt kvadrat"] # 0x324c (en: 'circled number fifty on black square', google: 'cirklat nummer femtio på black square') - - "㉍": [T: "seksti i sirkel på fylt kvadrat"] # 0x324d (en: 'circled number sixty on black square', google: 'cirklat nummer sextio på black square') - - "㉎": [T: "sytti i sirkel på fylt kvadrat"] # 0x324e (en: 'circled number seventy on black square', google: 'cirklat nummer sjuttio på black square') - - "㉏": [T: "åtti i sirkel på fylt kvadrat"] # 0x324f (en: 'circled number eighty on black square', google: 'cirklat nummer aty på black square') - - "㉑": [T: "tjueen i sirkel"] # 0x3251 (en: 'circled number twenty one', google translation) - - "㉒": [T: "tjueto i sirkel"] # 0x3252 (en: 'circled number twenty two', google translation) - - "㉓": [T: "tjuetre i sirkel"] # 0x3253 (en: 'circled number twenty three', google translation) - - "㉔": [T: "tjuefire i sirkel"] # 0x3254 (en: 'circled number twenty four', google translation) - - "㉕": [T: "tjuefem i sirkel"] # 0x3255 (google translation) - - "㉖": [T: "tjueseks i sirkel"] # 0x3256 (google translation) - - "㉗": [T: "tjuesju i sirkel"] # 0x3257 (en: 'circled number twenty seven', google translation) - - "㉘": [T: "tjueåtte i sirkel"] # 0x3258 (en: 'circled number twenty eight', google translation) - - "㉙": [T: "tjueni i sirkel"] # 0x3259 (en: 'circled number twenty nine', google translation) - - "㉚": [T: "tretti i sirkel"] # 0x325a (en: 'circled number thirty', google translation) - - "㉛": [T: "trettien i sirkel"] # 0x325b (en: 'circled number thirty one', google translation) - - "㉜": [T: "trettito i sirkel"] # 0x325c (en: 'circled number thirty two', google translation) - - "㉝": [T: "trettitre i sirkel"] # 0x325d (google translation) - - "㉞": [T: "trettifire i sirkel"] # 0x325e (en: 'circled number thirty four', google translation) - - "㉟": [T: "trettifem i sirkel"] # 0x325f (en: 'circled number thirty five', google translation) - - "㊱": [T: "trettiseks i sirkel"] # 0x32b1 (en: 'circled number thirty six', google translation) - - "㊲": [T: "trettisju i sirkel"] # 0x32b2 (en: 'circled number thirty seven', GPT-5.4 translation) - - "㊳": [T: "trettiåtte i sirkel"] # 0x32b3 (en: 'circled number thirty eight', GPT-5.4 translation) - - "㊴": [T: "trettini i sirkel"] # 0x32b4 (en: 'circled number thirty nine', GPT-5.4 translation) - - "㊵": [T: "førti i sirkel"] # 0x32b5 (en: 'circled number forty', GPT-5.4 translation) - - "㊶": [T: "førtien i sirkel"] # 0x32b6 (en: 'circled number forty one', GPT-5.4 translation) - - "㊷": [T: "førtito i sirkel"] # 0x32b7 (en: 'circled number forty two', GPT-5.4 translation) - - "㊸": [T: "førtitre i sirkel"] # 0x32b8 (en: 'circled number forty three', GPT-5.4 translation) - - "㊹": [T: "førtifire i sirkel"] # 0x32b9 (en: 'circled number forty four', GPT-5.4 translation) - - "㊺": [T: "førtifem i sirkel"] # 0x32ba (en: 'circled number forty five', GPT-5.4 translation) - - "㊻": [T: "førtiseks i sirkel"] # 0x32bb (en: 'circled number forty six', GPT-5.4 translation) - - "㊼": [T: "førtisju i sirkel"] # 0x32bc (en: 'circled number forty seven', GPT-5.4 translation) - - "㊽": [T: "førtiåtte i sirkel"] # 0x32bd (en: 'circled number forty eight', GPT-5.4 translation) - - "㊾": [T: "førtini i sirkel"] # 0x32be (en: 'circled number forty nine', GPT-5.4 translation) - - "㊿": [T: "femti i sirkel"] # 0x32bf (en: 'circled number fifty', GPT-5.4 translation) - - "㋌": [T: "kvikksølv"] # 0x32cc (en: 'mercury', google translation) - - "㋍": [T: "erg"] # 0x32cd (google translation) - - "㋎": [T: "elektronvolt"] # 0x32ce (en: 'electron volts', google translation) - - "㋏": [T: "begrenset ansvar"] # 0x32cf (en: 'limited liability sign', google translation) - #----------------------------------------------------------------------------------------------------------------------- - # CJK compatibility OK - - "㍱": [T: "hektopascal"] # 0x3371 (en: 'hectopascals', google translation) - - "㍲": [T: "dalton"] # 0x3372 (google translation) - - "㍳": [T: "astronomisk enhet"] # 0x3373 (en: 'astronomical units', google translation) - - "㍴": [T: "bar"] # 0x3374 (en: 'bars', google translation) - - "㍵": [T: "o v"] # 0x3375 (google translation) - - "㍶": [T: "parsec"] # 0x3376 (google translation) - - "㍷": [T: "desimeter"] # 0x3377 (en: 'decimeters', google translation) - - "㍸": [T: "kvadratdesimeter"] # 0x3378 (en: 'decimeters squared', google translation) - - "㍹": [T: "kubikkdesimeter"] # 0x3379 (en: 'decimeters cubed', google translation) - - "㍺": [T: "kvadratisk I U"] # 0x337a (en: 'instrumental units', google translation) - - "㎀": [T: "piko-ampere"] # 0x3380 (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen - - "㎁": [T: "nanoampere"] # 0x3381 (google translation) - - "㎂": [T: "mikroampere"] # 0x3382 (google translation) - - "㎃": [T: "milliampere"] # 0x3383 (google translation) - - "㎄": [T: "kiloampere"] # 0x3384 (google translation) - - "㎅": [T: "kilobyte"] # 0x3385 (google translation) - - "㎆": [T: "mega-byte"] # 0x3386 (en: 'megabytes', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen - - "㎇": [T: "gigabyte"] # 0x3387 (en: 'gigabytes', google translation) - - "㎈": [T: "kalorier"] # 0x3388 (en: 'calories', google translation) - - "㎉": [T: "kilokalorier"] # 0x3389 (en: 'kilocalories', google translation) - - "㎊": [T: "piko-farad"] # 0x338a (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen - - "㎋": [T: "nano-farad"] # 0x338b (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen - - "㎌": [T: "mikrofarad"] # 0x338c (google translation) - - "㎍": [T: "mikro-gram"] # 0x338d (en: 'micrograms', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen - - "㎎": [T: "milligram"] # 0x338e (google translation) - - "㎏": [T: "kilogram"] # 0x338f (en: 'kilograms', google translation) - - "㎐": [T: "hertz"] # 0x3390 (google translation) - - "㎑": [T: "kilohertz"] # 0x3391 (google translation) - - "㎒": [T: "megahertz"] # 0x3392 (google translation) - - "㎓": [T: "gigahertz"] # 0x3393 (google translation) - - "㎔": [T: "tera-hertz"] # 0x3394 (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen - - "㎕": [T: "mikroliter"] # 0x3395 (google translation) - - "㎖": [T: "milliliter"] # 0x3396 (google translation) - - "㎗": [T: "desiliter"] # 0x3397 (google translation) - - "㎘": [T: "kiloliter"] # 0x3398 (en: 'kiloliters', google translation) - - "㎙": [T: "femto-meter"] # 0x3399 (en: 'femtometers', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen - - "㎚": [T: "nanometer"] # 0x339a (en: 'nanometers', google translation) - - "㎛": [T: "mikro-meter"] # 0x339b (en: 'micrometers', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen - - "㎜": [T: "millimeter"] # 0x339c (en: 'millimeters', google translation) - - "㎝": [T: "centimeter"] # 0x339d (en: 'centimeters', google translation) - - "㎞": [T: "kilometer"] # 0x339e (en: 'kilometers', google translation) - - "㎟": [T: "kvadratmillimeter"] # 0x339f (en: 'millimeters squared', google translation) - - "㎠": [T: "kvadratcentimeter"] # 0x33a0 (en: 'centimeters squared', google translation) - - "㎡": [T: "kvadratmeter"] # 0x33a1 (en: 'meters squared', google translation) - - "㎢": [T: "kvadratkilometer"] # 0x33a2 (en: 'kilometers squared', google translation) - - "㎣": [T: "kubikkmillimeter"] # 0x33a3 (en: 'millimeters cubed', google translation) - - "㎤": [T: "kubikkcentimeter"] # 0x33a4 (en: 'centimeters cubed', google translation) - - "㎥": [T: "kubikkmeter"] # 0x33a5 (en: 'meters cubed', google translation) - - "㎦": [T: "kubikk-kilometer"] # 0x33a6 (en: 'kilometers cubed', google translation) - - "㎧": [T: "meter per sekund"] # 0x33a7 (en: 'meters per second', google translation) - - "㎨": [T: "meter per sekund i andre"] # 0x33a8 (en: 'meters per second squared', google translation) - - "㎩": [T: "pascal"] # 0x33a9 (google translation) - - "㎪": [T: "kilopascal"] # 0x33aa (google translation) - - "㎫": [T: "megapascal"] # 0x33ab (google translation) - - "㎬": [T: "giga-pascal"] # 0x33ac (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen - - "㎭": [T: "radianer"] # 0x33ad (google translation) - - "㎮": [T: "radianer per sekund"] # 0x33ae (en: 'rads per second', google translation) - - "㎯": [T: "radianer per sekund i andre"] # 0x33af (en: 'rads per second squared', google translation) - - "㎰": [T: "piko-sekunder"] # 0x33b0 (en: 'picoseconds', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen - - "㎱": [T: "nanosekunder"] # 0x33b1 (en: 'nanoseconds', google translation) - - "㎲": [T: "mikrosekunder"] # 0x33b2 (en: 'microseconds', google translation) - - "㎳": [T: "millisekunder"] # 0x33b3 (en: 'milliseconds', google translation) - - "㎴": [T: "piko-volt"] # 0x33b4 (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen - - "㎵": [T: "nanovolt"] # 0x33b5 (google translation) - - "㎶": [T: "mikrovolt"] # 0x33b6 (google translation) - - "㎷": [T: "millivolt"] # 0x33b7 (google translation) - - "㎸": [T: "kilovolt"] # 0x33b8 (google translation) - - "㎹": [T: "megavolt"] # 0x33b9 (google translation) - - "㎺": [T: "piko-watt"] # 0x33ba (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen - - "㎻": [T: "nano-watt"] # 0x33bb (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen - - "㎼": [T: "mikrowatt"] # 0x33bc (en: 'microwatts', google translation) - - "㎽": [T: "milliwatt"] # 0x33bd (google translation) - - "㎾": [T: "kilowatt"] # 0x33be (google translation) - - "㎿": [T: "mega-watt"] # 0x33bf (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen - - "㏀": [T: "kiloohm"] # 0x33c0 (google translation) - - "㏁": [T: "megaohm"] # 0x33c1 (google translation) - - "㏂": [T: "atto-meter"] # 0x33c2 (en: 'attometers', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen - - "㏃": [T: "becquerel"] # 0x33c3 (google translation) - - "㏄": [T: "kubikkcentimeter"] # 0x33c4 (en: 'cubic centimeters', google translation) - - "㏅": [T: "candela"] # 0x33c5 (google translation) - - "㏆": [T: "coulomb per kilogram"] # 0x33c6 (en: 'coulombs per kilogram', google translation) - - "㏇": [T: "kvadratisk C O"] # 0x33c7 (en: 'cardiac output', google translation) - - "㏈": [T: "desibel"] # 0x33c8 (en: 'decibels', google translation) - - "㏉": [T: "gray"] # 0x33c9 (en: 'grays', google translation) - - "㏊": [T: "hektar"] # 0x33ca (en: 'hectares', google translation) - - "㏋": [T: "hestekraft"] # 0x33cb (en: 'horsepower', google translation) - - "㏌": [T: "tomme"] # 0x33cc (en: 'inches', google translation) - - "㏍": [T: "kilokelvin"] # 0x33cd (google translation) - - "㏎": [T: "kilometer"] # 0x33ce (en: 'kilometers', google translation) - - "㏏": [T: "knop"] # 0x33cf (en: 'knots', google translation) - - "㏐": [T: "lumen"] # 0x33d0 (en: 'lumens', google translation) - - "㏑": [T: "den naturlige logaritmen"] # 0x33d1 (en: 'natural log', google translation) - - "㏒": [T: "logaritmen"] # 0x33d2 (en: 'logarithm', google translation) - - "㏓": [T: "lux"] # 0x33d3 (google translation) - - "㏔": [T: "millibarn"] # 0x33d4 (en: 'millibarns', google translation) - - "㏕": [T: "mill"] # 0x33d5 (google translation) - - "㏖": [T: "mol"] # 0x33d6 (en: 'moles', google translation) - - "㏗": [T: "p h"] # 0x33d7 (google translation) - - "㏘": [T: "piko-meter"] # 0x33d8 (en: 'picometers', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen - - "㏙": [T: "milliondeler"] # 0x33d9 (en: 'parts per million', google translation) - - "㏚": [T: "petarøntgen"] # 0x33da (google translation) - - "㏛": [T: "steradianer"] # 0x33db (google translation) - - "㏜": [T: "sievert"] # 0x33dc (google translation) - - "㏝": [T: "weber"] # 0x33dd (google translation) - - "㏞": [T: "volt per meter"] # 0x33de (en: 'volts per meter', google translation) - - "㏟": [T: "ampere per meter"] # 0x33df (google translation) - - "㏿": [T: "gallon"] # 0x33ff (en: 'gallons', google translation) - #---------------------------------------------------------------------------------------------------------- - # Private use area OK - - "": [T: "lik med hatt under"] # 0xe900 (en: 'equals with hat below', google translation) - - "": [T: "lik med pluss over"] # 0xe901 (en: 'equals with plus above', google translation) - - "": [T: "lik med pluss under"] # 0xe902 (en: 'equals with plus below', google translation) - - "": [T: "tilde med pluss over"] # 0xe903 (en: 'tilde with plus above', google translation) - - "": [T: "tilde med pluss under"] # 0xe904 (en: 'tilde with plus below', google translation) - - "": [T: "dobbel lik over større enn"] # 0xe908 (en: 'equal double over greater than', google translation) - - "": [T: "dobbel lik over mindre enn"] # 0xe909 (en: 'equal double over less than', google translation) - - "": [T: "inneholder eller er lik"] # 0xe90a (en: 'contains or equal to', google translation) - - "": [T: "overmengde av eller lik"] # 0xe90b (en: 'superset of or equal to', google translation) - - "": [T: "delmengde av eller lik"] # 0xe90c (en: 'subset of or equal to', google translation) - - "": [T: "lik over mindre enn"] # 0xe90d (en: 'equal over less than', google translation) - - "": [T: "tilhører eller lik"] # 0xe912 (en: 'element of or equal to', google translation) - - "": [T: "lik eller større enn"] # 0xe913 (en: 'equal to or greater than', google translation) - - "": [T: "tilnærmet overmengde av"] # 0xe914 (en: 'approximate superset of', google translation) - - "": [T: "tilnærmet delmengde av"] # 0xe915 (en: 'approximate subset of', google translation) - - "": [T: "overmengde av med prikk inkluderer som underrelasjon"] # 0xe916 (en: 'superset of with dot includes as sub relation', google translation) - - "": [T: "delmengde av med prikk inkluderes i som underrelasjon"] # 0xe917 (en: 'subset of with dot is included in as sub relation', google translation) - - "": [T: "lik med prikk under"] # 0xe918 (en: 'equal with dot below', google translation) - - "": [T: "venstre prikk over minus over høyre prikk"] # 0xe919 (en: 'left dot over minus over right dot', google translation) - - "": [T: "høyre prikk over minus over venstre prikk"] # 0xe91a (en: 'right dot over minus over left dot', google translation) - - "": [T: "nesten lik minus"] # 0xe91f (en: 'almost equal to minus', google translation) - - "": [T: "dobbel kvadratisk union"] # 0xe920 (en: 'double square cup', google translation) - - "": [T: "dobbelt kvadratisk snitt"] # 0xe921 (en: 'double square cap', google translation) - - "": [T: "mindre enn lik eller større enn"] # 0xe922 (en: 'less than equal to or greater than', google translation) - - "": [T: "tilde med prikk"] # 0xe924 (en: 'tilde with dot', google translation) - - "": [T: "tilde med to prikker"] # 0xe925 (en: 'tilde with two dots', google translation) - - "": [T: "mindre enn større enn eller lik"] #0xe926 (en: 'less than greater than or equal to', google translation) - - "": [T: "større enn mindre enn eller lik"] # 0xe927 (en: 'greater than less than or equal to', google translation) - - "": [T: "ekvivalent med eller mindre enn"] # 0xe928 (en: 'equivalent to or less than', google translation) - - "": [T: "ekvivalent med eller større enn"] # 0xe929 (en: 'equivalent to or greater than', google translation) - - "": [T: "venstre åpen boks"] # 0xe92a (en: 'left open box operator', google translation) - - "": [T: "høyre åpen boks"] # 0xe92b (en: 'right open box operator', google translation) - - "": [T: "identisk med med prikk"] # 0xe92c (en: 'identical to with dot', google translation) - - "": [T: "større enn lik eller mindre enn"] # 0xe92d (en: 'greater than equal to or less than', google translation) - - "": [T: "bar"] # 0xe92e (en: 'bar operator', google translation) - - "": [T: "dobbel bar"] # 0xe92f (en: 'double bar operator', google translation) - - "": [T: "trippel bar"] # 0xe930 (google translation) - - "": [T: "mindre enn eller tilnærmet lik"] # 0xe932 (en: 'less than or approximately equal to', google translation) - - "": [T: "større enn eller tilnærmet lik"] # 0xe933 (en: 'greater than or approximately equal to', google translation) - - "": [T: "nøstet mindre enn"] # 0xe936 (en: 'nested less than', google translation) - - "": [T: "nøstet større enn"] # 0xe937 (en: 'nested greater than', google translation) - - "": [T: "foregår eller ekvivalent med"] # 0xe93a (en: 'precedes or equivalent to', google translation) - - "": [T: "følger eller ekvivalent med"] # 0xe93b (en: 'succeeds or equivalent to', google translation) - - "": [T: "foregår over lik"] # 0xe940 (en: 'precedes over equal', google translation) - - "": [T: "følger over lik"] # 0xe941 (en: 'succeeds over equal', google translation) - - "": [T: "mindre enn eller lik"] # 0xe942 (en: 'less equal slanted greater', google translation) - - "": [T: "større enn eller lik"] # 0xe943 (en: 'greater equal slanted less', google translation) - - "": [T: "oppfylles av"] # 0xe948 (en: 'satisfied by', google translation) - - "": [T: "langstrakt s"] # 0xe949 (en: 'lazy s', google translation) - - "": [T: "ikke påstand"] # 0xe94a (en: 'not assertion', google translation) - - "": [T: "dobbel lik"] # 0xe94b (en: 'double equal', google translation) - - "": [T: "trippel lik"] # 0xe94c (en: 'triple equal', google translation) - - "": [T: "regel forsinket"] # 0xe94d (en: 'rule delayed', google translation) - - "": [T: "alias skilletegn"] # 0xe94e (en: 'alias delimiter', google translation) - - "": [T: "normal undergruppe av med strek"] # 0xe950 (en: 'normal subgroup of with bar', google translation) - - "": [T: "inneholder som normal undergruppe med strek"] # 0xe951 (en: 'contains as normal subgroup with bar', google translation) - - "": [T: "rund impliserer"] # 0xe954 (en: 'round implies', google translation) - - "": [T: "smil under strek"] # 0xe955 (en: 'smile under bar', google translation) - - "": [T: "rynke over strek"] # 0xe956 (en: 'frown over bar', google translation) - - "": [T: "overmengde av eller tilnærmet lik"] # 0xe957 (en: 'superset of or almost equal to', google translation) - - "": [T: "delmengde av eller tilnærmet lik"] # 0xe958 (en: 'subset of or almost equal to', google translation) - - "": [T: "større enn tilnærmet lik eller mindre enn"] # 0xe959 (en: 'greater than almost equal to or less than', google translation) - - "": [T: "mindre enn tilnærmet lik eller større enn"] # 0xe95a (en: 'less than almost equal or greater than', google translation) - - "": [T: "dobbel logisk eller"] # 0xe95c (en: 'double logical or', google translation) - - "": [T: "dobbel logisk og"] # 0xe95d (en: 'double logical and', google translation) - - "": [T: "logisk eller med dobbel strek under"] # 0xe95e (en: 'logical or with double bar below', google translation) - - "": [T: "logisk eller med strek under"] # 0xe95f (en: 'logical or with bar below', google translation) - - "": [T: "tilnærmet lik"] # 0xe962 (en: 'almost equal over equal', google translation) - - "": [T: "venstre trekant med midtstrek"] # 0xe964 (en: 'left pointing triangle with bisecting bar', google translation) - - "": [T: "høyre trekant med midtstrek"] # 0xe965 (en: 'right pointing triangle with bisecting bar', google translation) - - "": [T: "lik med prikket øvre linje"] # 0xe966 (en: 'equals with dotted top line', google translation) - - "": [T: "foregår med kolon"] # 0xe967 (en: 'precedes with colon', google translation) - - "": [T: "følger med kolon"] # 0xe968 (en: 'succeeds with colon', google translation) - - "": [T: "mindre enn eller lik"] # 0xe969 (en: 'smaller than or equal slanted', google translation) - - "": [T: "større enn eller lik"] # 0xe96a (en: 'larger than or equal slanted', google translation) - - "": [T: "nøstet veldig mye mindre enn"] # 0xe96b (en: 'nested very much less than', google translation) - - "": [T: "nøstet veldig mye større enn"] # 0xe96c (en: 'nested very much greater than', google translation) - - "": [T: "forskjell mellom"] # 0xe96d (en: 'difference between variant', google translation) - - "": [T: "mindre enn som overlapper med større enn"] # 0xe96e (en: 'less than greater than overlay', google translation) - - "": [T: "logisk eller som overlapper med logisk og"] # 0xe96f (en: 'logical or logical and overlay', google translation) - - "": [T: "overmengde over overmengde"] # 0xe970 (google translation) - - "": [T: "delmengde over delmengde"] # 0xe971 (en: 'subset over subset', google translation) - - "": [T: "overmengde over delmengde"] # 0xe972 (en: 'superset over subset', google translation) - - "": [T: "delmengde over overmengde"] # 0xe973 (en: 'subset over superset', google translation) - - "": [T: "trippel vertikal strek"] # 0xe979 (google translation) - - "": [T: "parvise firedoble vertikale prikker"] # 0xe97a (en: 'paired quadruple vertical dots', google translation) - - "": [T: "vinkelrett over strek"] # 0xe97b (en: 'perpendicular over bar', google translation) - - "": [T: "venstre dreiekors dobbel vertikal strek"] # 0xe97c (en: 'left turnstile double vertical bar', google translation) - - "": [T: "dobbelt venstre dreiekors dobbel vertikal strek"] # 0xe97d (en: 'double left turnstile double vertical bar', google translation) - - "": [T: "vinkelrett over rotert vinkelrett"] # 0xe97e (en: 'perpendicular over inverted perpendicular', google translation) - - "": [T: "dobbelt venstre dreiekors vertikal strek"] # 0xe97f (en: 'double left turnstile vertical bar', google translation) - - "": [T: "sfærisk vinkel oppover"] # 0xe980 (en: 'spherical angle opening up', google translation) - - "": [T: "dobbel skråstrek"] # 0xe981 (en: 'double slash', google translation) - - "": [T: "rett vinkel med hjørne"] # 0xe982 (en: 'right angle with corner', google translation) - - "": [T: "sirkel med vertikal strek"] # 0xe984 (google translation) - - "": [T: "sirkel med divisjon"] # 0xe985 (google translation) - - "": [T: "stiplet skråstrek"] # 0xe986 (en: 'dashed solidus', google translation) - - "": [T: "stiplet omvendt skråstrek"] # 0xe987 (en: 'dashed backslash', google translation) - - "": [T: "stiplet midtlinje"] # 0xe988 (en: 'dashed mid line', google translation) - - "": [T: "stiplet vertikal strek"] # 0xe989 (en: 'dashed vertical bar', google translation) - - "": [T: "vinkelrett med s"] # 0xe98a (en: 'perpendicular with s', google translation) - - "": [T: "vinkel med s"] # 0xe98b (en: 'angle with s', google translation) - - "": [T: "sfærisk vinkel mot venstre"] # 0xe98c (en: 'spherical angle opening left', google translation) - - "": [T: "vinkel mot venstre"] # 0xe98d (en: 'angle opening left', google translation) - - "": [T: "vertikal strek med dobbel krok"] # 0xe98e (en: 'vertical bar with double hook', google translation) - - "": [T: "medium dot-operator fri radikal"] # 0xe98f (google translation) - - "": [T: "hvit oppoverpekende trekant over strek"] # 0xe990 (en: 'white up pointing triangle above bar', google translation) - - "": [T: "identisk og parallell med"] # 0xe991 (en: 'identical and parallel to', google translation) - - "": [T: "smash-produkt"] # 0xe992 (en: 'smash product', google translation) - - "": [T: "trippel vertikal strek med horisontal strek"] # 0xe993 (en: 'triple bar operator with horizontal bar', google translation) - - "": [T: "identisk med med dobbel skråstrek"] # 0xe994 (en: 'identical to with double slash', google translation) - - "": [T: "triple kryssende streker"] # 0xe995 (en: 'triple crossed bars', google translation) - - "": [T: "sirkel med vertikal strek"] # 0xe996 (en: 'vertical bar over circle', google translation) - - "": [T: "vertikal proporsjonal med"] # 0xe997 (en: 'vertical proportional to', google translation) - - "": [T: "måne i siste kvarter"] # 0xe998 (en: 'black last quarter moon', google translation) - - "": [T: "måne i første kvarter"] # 0xe999 (google translation) - - "": [T: "negativ sinusbølge"] # 0xe9a0 (en: 'negative sine wave', google translation) - - "": [T: "prikk i parentes"] # 0xe9a1 (en: 'parenthesized dot', google translation) - - "": [T: "parenteser"] # 0xe9a2 (en: 'parens', google translation) - - "": [T: "hvitt smil"] # 0xe9a3 (en: 'white smile', google translation) - - "": [T: "hvit rynke"] # 0xe9a4 (en: 'white frown', google translation) - - "": [T: "heksagon"] # 0xe9a5 (en: 'hexagon', google translation) - - "": [T: "ekvivalent med over pluss"] # 0xe9a6 (en: 'equivalent to over plus', google translation) - - "": [T: "pluss over ekvivalent med"] # 0xe9a7 (en: 'plus over equivalent to', google translation) - - "": [T: "snitt"] # 0xe9b0 (en: 'intersection serifs', google translation) - - "": [T: "union"] # 0xe9b1 (google translation) - - "": [T: "kvadratisk snitt"] # 0xe9b2 (en: 'square intersection serifs', google translation) - - "": [T: "kvadratisk union"] # 0xe9b3 (google translation) - - "": [T: "foregår ekvivalent med eller følger"] # 0xe9e0 (en: 'precedes equivalent to or succeeds', google translation) - - "": [T: "følger ekvivalent med eller foregår"] # 0xe9e1 (en: 'succeeds equivalent to or precedes', google translation) - - "": [T: "foregår tilnærmet lik eller følger"] # 0xe9e2 (en: 'precedes almost equal to or succeeds', google translation) - - "": [T: "følger tilnærmet lik eller foregår"] # 0xe9e3 (en: 'succeeds almost equal to or precedes', google translation) - - "": [T: "mindre enn ekvivalent med eller større enn"] # 0xe9f0 (en: 'less than equivalent to or greater than', google translation) - - "": [T: "større enn ekvivalent med eller mindre enn"] # 0xe9f1 (en: 'greater than equivalent to or less than', google translation) - - "": [T: "ikke mye mindre enn"] # 0xea00 (en: 'not vert much less than', google translation) - - "": [T: "ikke mye større enn"] # 0xea01 (en: 'not vert much greater than', google translation) - - "": [T: "ikke mye mindre enn"] # 0xea02 (en: 'not much less than variant', google translation) - - "": [T: "ikke mye større enn"] # 0xea03 (en: 'not much greater than variant', google translation) - - "": [T: "mindre enn vertikal ikke dobbel lik"] # 0xea04 (en: 'less vert not double equals', google translation) - - "": [T: "større enn vertikal ikke dobbel lik"] # 0xea05 (en: 'gt vert not double equals', google translation) - - "": [T: "ikke mindre enn eller lik"] # 0xea06 (en: 'not less than or equal to', google translation) - - "": [T: "ikke større enn eller lik"] # 0xea07 (en: 'not greater than or equal to', google translation) - - "": [T: "verken lik eller mindre enn"] # 0xea09 (en: 'neither equal to nor less than', google translation) - - "": [T: "inneholder ikke eller er lik"] # 0xea0a (en: 'does not contain or equal to', google translation) - - "": [T: "verken overmengde av eller lik"] # 0xea0b (en: 'neither superset of nor equal to', google translation) - - "": [T: "verken delmengde av eller lik"] # 0xea0c (en: 'neither subset of nor equal to', google translation) - - "": [T: "omvendt skråstrek delmengde"] # 0xea0d (en: 'reverse solidus subset', google translation) - - "": [T: "verken lik eller større enn"] # 0xea0e (en: 'neither equal to nor greater than', google translation) - - "": [T: "ikke minus tilde"] # 0xea0f (en: 'not minus tilde operator', google translation) - - "": [T: "verken lik eller mindre enn"] # 0xea10 (en: 'neither equal to nor less than', google translation) - - "": [T: "ikke tilde"] # 0xea11 (en: 'not tilde operator', google translation) - - "": [T: "ikke element i eller lik"] # 0xea12 (en: 'not element of or equal to', google translation) - - "": [T: "verken lik eller større enn"] # 0xea13 (en: 'neither equal to nor greater than', google translation) - - "": [T: "ikke tilnærmet lik"] # 0xea14 (en: 'not almost equal', google translation) - - "": [T: "ikke følger tilnærmet lik"] # 0xea15 (en: 'not succeeds similar', google translation) - - "": [T: "mindre enn eller lik med skråstrek"] # 0xea16 (en: 'less than or slanted equal to with slash', google translation) - - "": [T: "større enn eller lik med skråstrek"] # 0xea17 (en: 'greater than or slanted equal to with slash', google translation) - - "": [T: "overmengde skråstrek"] # 0xea1a (google translation) - - "": [T: "inneholder ikke"] # 0xea1b (en: 'does not contain', google translation) - - "": [T: "ikke mindre enn eller lik"] # 0xea1d (en: 'not less than or equal to', google translation) - - "": [T: "ikke større enn eller lik"] # 0xea1e (en: 'not greater than or equal to', google translation) - - "": [T: "ikke nesten lik minus"] # 0xea1f (en: 'not almost equal to minus', google translation) - - "": [T: "tilhører ikke mengde med prikk"] # 0xea22 (en: 'negated set membership dot above', google translation) - - "": [T: "ikke rett vinkel"] # 0xea2c (en: 'not vert angle', google translation) - - "": [T: "ikke parallell"] # 0xea2d (en: 'not parallel slanted', google translation) - - "": [T: "ikke strek"] # 0xea2e (en: 'not bar operator', google translation) - - "": [T: "ikke dobbel strek"] # 0xea2f (en: 'not double bar operator', google translation) - - "": [T: "ikke trippel strek"] # 0xea30 (en: 'not triple bar operator', google translation) - - "": [T: "mindre enn men ikke tilnærmet lik"] # 0xea32 (en: 'less than but not approximately equal to', google translation) - - "": [T: "større enn men ikke tilnærmet lik"] # 0xea33 (en: 'greater than but not approximately equal to', google translation) - - "": [T: "mindre enn eller ikke lik"] # 0xea34 (en: 'less than or not equal to', google translation) - - "": [T: "større enn eller ikke lik"] # 0xea35 (en: 'greater than or not equal to', google translation) - - "": [T: "ikke nøstet mindre enn"] # 0xea36 (en: 'not nested less than', google translation) - - "": [T: "ikke nøstet større enn"] # 0xea37 (en: 'not nested greater than', google translation) - - "": [T: "ikke mye mindre enn"] # 0xea38 (en: 'not much less than', google translation) - - "": [T: "ikke mye større enn"] # 0xea39 (en: 'not much greater than', google translation) - - "": [T: "foregår men ikke ekvivalent med"] # 0xea3a (en: 'precedes but not equivalent to', google translation) - - "": [T: "følger men ikke ekvivalent med"] # 0xea3b (en: 'succeeds but not equivalent to', google translation) - - "": [T: "foregår men ikke lik"] # 0xea3c (en: 'precedes but not equal to', google translation) - - "": [T: "følger men ikke lik"] # 0xea3d (en: 'succeeds but not equal to', google translation) - - "": [T: "ikke lik eller foregår"] # 0xea3e (en: 'does not equal or precede', google translation) - - "": [T: "ikke lik eller følger"] # 0xea3f (en: 'does not equal or succeed', google translation) - - "": [T: "foregår men ikke lik"] # 0xea40 (en: 'precedes but not equal to', google translation) - - "": [T: "følger men ikke lik"] # 0xea41 (en: 'succeeds but not equal to', google translation) - - "": [T: "ikke delmengde av eller lik"] # 0xea42 (en: 'not subset of nor equal to', google translation) - - "": [T: "ikke overmengde av eller lik"] # 0xea43 (en: 'not superset of nor equal to', google translation) - - "": [T: "delmengde av eller ikke lik"] # 0xea44 (en: 'subset of or not equal to', google translation) - - "": [T: "overmengde av eller ikke lik"] # 0xea45 (en: 'superset of or not equal to', google translation) - - "": [T: "ikke delmengde av eller lik"] # 0xea46 (en: 'not subset of nor equal to', google translation) - - "": [T: "ikke overmengde av eller lik"] # 0xea47 (en: 'not superset of nor equal to', google translation) - - "": [T: "ikke trippel mindre enn"] # 0xea48 (en: 'not triple less than', google translation) - - "": [T: "ikke trippel større enn"] # 0xea49 (en: 'not triple greater than', google translation) - - "": [T: "ikke foregår lik"] # 0xea4c (en: 'not precedes equals', google translation) - - "": [T: "ikke følger lik"] # 0xea4d (en: 'not succeeds equals', google translation) - - "": [T: "ikke normal undergruppe av med strek"] # 0xea50 (en: 'not normal subgroup of with bar', google translation) - - "": [T: "inneholder ikke som normal undergruppe med strek"] # 0xea51 (en: 'does not contain as normal subgroup with bar', google translation) - - "": [T: "ikke forskjell mellom"] # 0xea52 (en: 'not difference between', google translation) - - "": [T: "ikke geometrisk ekvivalent med"] # 0xea53 (en: 'not geometrically equivalent to', google translation) - - "": [T: "ikke vertikal tilnærmet lik"] # 0xea54 (en: 'not vert similar', google translation) - - "": [T: "ikke lik eller tilnærmet lik"] # 0xea55 (en: 'not equal or similar', google translation) - - "": [T: "ikke vertikal tilnærmet lik"] # 0xea56 (en: 'not vert approximate', google translation) - - "": [T: "ikke tilnærmet identisk med"] # 0xea57 (en: 'not approximately identical to', google translation) - - "": [T: "ikke differansen mellom"] # 0xea58 (en: 'not bumpy equals', google translation) - - "": [T: "ikke differansen mellom"] # 0xea59 (en: 'not bumpy single equals', google translation) - - "": [T: "ikke lik prikk"] # 0xea5a (en: 'not equal dot', google translation) - - "": [T: "speilvendt ikke ekvivalent med"] # 0xea5b (en: 'reverse not equivalent', google translation) - - "": [T: "ikke kvadratisk delmengde"] # 0xea60 (en: 'not square subset', google translation) - - "": [T: "ikke kvadratisk overmengde"] # 0xea61 (en: 'not square superset', google translation) - - "": [T: "ikke tilnærmet lik over lik"] # 0xea62 (en: 'not almost equal over equal', google translation) - - "": [T: "ikke strengt ekvivalent med"] # 0xea63 (en: 'not strictly equivalent to', google translation) - - "": [T: "ikke kongruent prikk"] # 0xea64 (en: 'not congruent dot', google translation) - - "": [T: "speilvendt ikke lik"] # 0xea65 (en: 'reverse not equal', google translation) - - "": [T: "ikke vertikal venstre trekant lik"] # 0xea70 (en: 'not vert left triangle equals', google translation) - - "": [T: "ikke vertikal høyre trekant lik"] # 0xea71 (en: 'not vert right triangle equals', google translation) - - "": [T: "ikke partiell"] # 0xea80 (en: 'not partial', google translation) - - "": [T: "pilforlenger"] # 0xeb00 (en: 'arrow embellishment extender', google translation) - - "": [T: "høyrepil over venstrepil"] # 0xeb01 (en: 'arrow rightwards over arrow leftwards', google translation) - - "": [T: "høyrepil over venstrepil"] # 0xeb02 (en: 'arrow rightwards over arrow leftwards', google translation) - - "": [T: "høyre-harpun over venstre-harpun"] # 0xeb03 (en: 'harpoon right over harpoon left', google translation) - - "": [T: "høyre-harpun over venstre-harpun"] # 0xeb04 (en: 'harpoon right over harpoon left', google translation) - - "": [T: "dobbel-pil nordøst sørvest"] # 0xeb05 (en: 'double arrow northeast southwest', google translation) - - "": [T: "dobbel-pil nordvest sørøst"] # 0xeb06 (en: 'double arrow northwest southeast', google translation) - - "": [T: "horisontal harpun-forlenger"] # 0xeb07 (en: 'horizontal harpoon extender', google translation) - - "": [T: "venstrepil i bue mot klokka"] # 0xeb08 (en: 'anticlockwise arc leftwards arrow', google translation) - - "": [T: "høyrepil i bue mot klokka"] # 0xeb09 (en: 'anticlockwise arc rightwards arrow', google translation) - - "": [T: "stor høyrepil"] # 0xeb0b (en: 'large rightwards arrow accent', google translation) - - "": [T: "stor venstrepil"] # 0xeb0c (en: 'large leftwards arrow accent', google translation) - - "": [T: "venstre pilspiss"] # 0xeb0d (en: 'leftwards arrowhead', google translation) - - "": [T: "høyre pilspiss"] # 0xeb0e (en: 'rightwards arrowhead', google translation) - - "": [T: "stor venstre-høyre-pil med strek"] # 0xeb0f (en: 'large left right arrow with stroke', google translation) - - "": [T: "horisontal dobbel pil-forlenger"] # 0xeb10 (en: 'horizontal double arrow extender', google translation) - - "": [T: "stor venstre-høyre-pil med strek"] # 0xeb11 (en: 'large left right double arrow with stroke', google translation) - - "": [T: "nedoverpil til venstre for oppoverpil"] # 0xeb12 (en: 'downwards arrow leftwards of upwards arrow', google translation) - - "": [T: "venstrepil med hjørne nedover"] # 0xeb13 (en: 'leftwards arrow with corner downwards', google translation) - - "": [T: "høyrepil med hjørne oppover"] # 0xeb14 (en: 'rightwards arrow with corner upwards', google translation) - - "": [T: "venstrepil med hjørne oppover"] # 0xeb15 (en: 'leftwards arrow with corner upwards', google translation) - - "": [T: "øvre halvsirkel-pil mot klokka med pluss"] # 0xeb16 (en: 'anticlockwise top semicircle arrow with plus', google translation) - - "": [T: "øvre halvsirkel-pil med klokka med minus"] # 0xeb17 (en: 'clockwise top semicircle arrow with minus', google translation) - - "": [T: "høyrepil med hale og strek"] # 0xeb18 (en: 'rightwards arrow with tail with stroke', google translation) - - "": [T: "høyre-harpun mothake ned"] # 0xeb19 (en: 'right harpoon down', google translation) - - "": [T: "venstre-harpun mothake ned"] # 0xeb1a (en: 'left harpoon down', google translation) - - "": [T: "venstre-høyre-harpun mothake ned"] # 0xeb1b (en: 'left right harpoon down', google translation) - - "": [T: "venstre-høyre-harpun mothake opp"] # 0xeb1c (en: 'left right harpoon up', google translation) - - "": [T: "opp-ned-harpun mothake venstre"] # 0xeb1d (en: 'up down harpoon left', google translation) - - "": [T: "opp-ned-harpun mothake høyre"] # 0xeb1e (en: 'up down harpoon right', google translation) - - "": [T: "oppoverpil til høyre for nedoverpil"] # 0xeb1f (en: 'upwards arrow to the right of downwards arrow', google translation) - - "": [T: "venstre-harpun mot strek mothake opp"] # 0xeb20 (en: 'leftwards harpoon to bar with barb upwards', google translation) - - "": [T: "høyre-harpun mot strek mothake opp"] # 0xeb21 (en: 'rightwards harpoon to bar with barb upwards', google translation) - - "": [T: "venstre-harpun mot strek mothake ned"] # 0xeb22 (en: 'leftwards harpoon to bar with barb downwards', google translation) - - "": [T: "høyre-harpun mot strek mothake ned"] # 0xeb23 (en: 'rightwards harpoon to bar with barb downwards', google translation) - - "": [T: "venstre-harpun fra strek mothake opp"] # 0xeb24 (en: 'leftwards harpoon from bar with barb upwards', google translation) - - "": [T: "høyre-harpun fra strek mothake opp"] # 0xeb25 (en: 'rightwards harpoon from bar with barb upwards', google translation) - - "": [T: "venstre-harpun fra strek mothake ned"] # 0xeb26 (en: 'leftwards harpoon from bar with barb downwards', google translation) - - "": [T: "høyre-harpun fra strek mothake ned"] # 0xeb27 (en: 'rightwards harpoon from bar with barb downwards', google translation) - - "": [T: "opp-harpun mot strek mothake venstre"] # 0xeb28 (en: 'upwards harpoon to bar with barb leftwards', google translation) - - "": [T: "ned-harpun mot strek mothake venstre"] # 0xeb29 (en: 'downwards harpoon to bar with barb leftwards', google translation) - - "": [T: "opp-harpun mot strek mothake høyre"] # 0xeb2a (en: 'upwards harpoon to bar with barb rightwards', google translation) - - "": [T: "ned-harpun mot strek mothake høyre"] # 0xeb2b (en: 'downwards harpoon to bar with barb rightwards', google translation) - - "": [T: "opp-harpun fra strek mothake venstre"] # 0xeb2c (en: 'upwards harpoon from bar with barb leftwards', google translation) - - "": [T: "ned-harpun fra strek mothake venstre"] # 0xeb2d (en: 'downwards harpoon from bar with barb leftwards', google translation) - - "": [T: "opp-harpun fra strek mothake høyre"] # 0xeb2e (en: 'upwards harpoon from bar with barb rightwards', google translation) - - "": [T: "ned-harpun fra strek mothake høyre"] # 0xeb2f (en: 'downwards harpoon from bar with barb rightwards', google translation) - - "": [T: "oppoverpil mot strek"] # 0xeb30 (en: 'upwards arrow to bar', google translation) - - "": [T: "nedoverpil mot strek"] # 0xeb31 (en: 'downwards arrow to bar', google translation) - - "": [T: "opp-harpun til venstre for ned-harpun"] # 0xeb32 (en: 'upwards harpoon to the left of downwards harpoon', google translation) - - "": [T: "opp-harpun til høyre for ned-harpun"] # 0xeb33 (en: 'upwards harpoon to the right of downwards harpoon', google translation) - - "": [T: "pilspiss oppover"] # 0xeb34 (en: 'upwards arrowhead', google translation) - - "": [T: "pilspiss nedover"] # 0xeb35 (en: 'downwards arrowhead', google translation) - - "": [T: "dobbel harpun venstre mothake ned høyre mothake opp"] # 0xeb36 (en: 'double harpoon with leftwards barb down rightwards barb up', google translation) - - "": [T: "dobbel harpun venstre mothake opp høyre mothake ned"] # 0xeb37 (en: 'double harpoon with leftwards barb up rightwards barb down', google translation) - - "": [T: "venstrepil over strek"] # 0xeb38 (en: 'leftwards arrow over bar', google translation) - - "": [T: "høyrepil over strek"] # 0xeb39 (en: 'rightwards arrow over bar', google translation) - - "": [T: "venstrepil under strek"] # 0xeb3a (en: 'leftwards arrow under bar', google translation) - - "": [T: "høyrepil under strek"] # 0xeb3b (en: 'rightwards arrow under bar', google translation) - - "": [T: "venstre-høyre trippel pil"] # 0xeb3c (en: 'left right triple arrow', google translation) - - "": [T: "dobbel-pil nordøst sørøst"] # 0xeb3f (en: 'double arrow northeast southeast', google translation) - - "": [T: "venstre halvsirkel-pil mot klokka"] # 0xeb40 (en: 'anticlockwise left semicircle arrow', google translation) - - "": [T: "venstre halvsirkel-pil med klokka"] # 0xeb41 (en: 'clockwise left semicircle arrow', google translation) - - "": [T: "venstre-høyre-pil i venstre åpen sirkel"] # 0xeb42 (en: 'left open circle left right arrow', google translation) - - "": [T: "høyrepil over tilde"] # 0xeb44 (en: 'rightwards arrow over tilde', google translation) - - "": [T: "venstrepil over tilde"] # 0xeb45 (en: 'leftwards arrow over tilde', google translation) - - "": [T: "venstre-harpun over strek"] # 0xeb48 (en: 'leftwards harpoon over bar', google translation) - - "": [T: "høyre-harpun over strek"] # 0xeb49 (en: 'rightwards harpoon over bar', google translation) - - "": [T: "venstre-harpun under strek"] # 0xeb4a (en: 'leftwards harpoon under bar', google translation) - - "": [T: "høyre-harpun under strek"] # 0xeb4b (en: 'rightwards harpoon under bar', google translation) - - "": [T: "sammenpresset venstrepil"] # 0xeb4c (en: 'squat black leftwards arrow', google translation) - - "": [T: "høyre halvsirkel-pil med klokka"] # 0xeb50 (en: 'clockwise right semicircle arrow', google translation) - - "": [T: "høyre halvsirkel-pil mot klokka"] # 0xeb51 (en: 'anticlockwise right semicircle arrow', google translation) - - "": [T: "venstre-høyre-harpun i venstre åpen sirkel"] # 0xeb52 (en: 'left open circle left right harpoon', google translation) - - "": [T: "oppoverpil til venstre for vertikal strek"] # 0xeb58 (en: 'upwards arrow leftwards of vertical bar', google translation) - - "": [T: "nedoverpil til venstre for vertikal strek"] # 0xeb59 (en: 'downwards arrow leftwards of vertical bar', google translation) - - "": [T: "oppoverpil til høyre for vertikal strek"] # 0xeb5a (en: 'upwards arrow rightwards of vertical bar', google translation) - - "": [T: "nedoverpil til høyre for vertikal strek"] # 0xeb5b (en: 'downwards arrow rightwards of vertical bar', google translation) - - "": [T: "høyrepil med krok ned"] # 0xeb5c (en: 'rightwards arrow with extended downwards hook', google translation) - - "": [T: "venstrepil med krok"] # 0xeb5d (en: 'leftwards arrow with extended hook', google translation) - - "": [T: "venstrepil med krok ned"] # 0xeb5e (en: 'leftwards arrow with extended downwards hook', google translation) - - "": [T: "høyrepil med krok"] # 0xeb5f (en: 'rightwards arrow with extended hook', google translation) - - "": [T: "ikke bølgete høyrepil"] # 0xeb60 (en: 'not right arrow wavy', google translation) - - "": [T: "ikke buet høyrepil"] # 0xeb61 (en: 'not right arrow curved', google translation) - - "": [T: "opp-harpun til venstre for vertikal strek"] # 0xeb68 (en: 'upwards harpoon leftwards of vertical bar', google translation) - - "": [T: "ned-harpun til venstre for vertikal strek"] # 0xeb69 (en: 'downwards harpoon leftwards of vertical bar', google translation) - - "": [T: "opp-harpun til høyre for vertikal strek"] # 0xeb6a (en: 'upwards harpoon rightwards of vertical bar', google translation) - - "": [T: "ned-harpun til høyre for vertikal strek"] # 0xeb6b (en: 'downwards harpoon rightwards of vertical bar', google translation) - - "": [T: "vertikal dobbel pil-forlenger"] # 0xeb6c (en: 'vertical double arrow extender', google translation) - - "": [T: "vertikal harpun med mothake venstre forlenger"] # 0xeb6d (en: 'vertical harpoon with barb left extender', google translation) - - "": [T: "vertikal harpun med mothake høyre forlenger"] # 0xeb6e (en: 'vertical harpoon with barb right extender', google translation) - - "": [T: "høyre-harpun over venstre-harpun høyre"] # 0xeb6f (en: 'right harpoon over left harpoon right', google translation) - - "": [T: "høyre-harpun over venstre-harpun venstre"] # 0xeb70 (en: 'right harpoon over left harpoon left', google translation) - - "": [T: "venstre-harpun over høyre-harpun høyre"] # 0xeb71 (en: 'left harpoon over right harpoon right', google translation) - - "": [T: "venstre-harpun over høyre-harpun venstre"] # 0xeb72 (en: 'left harpoon over right harpoon left', google translation) - - "": [T: "venstrepil fra strek pilspiss"] # 0xeb73 (en: 'leftwards arrow from bar arrowhead', google translation) - - "": [T: "venstre-høyre-pil fra strek forlenger"] # 0xeb74 (en: 'leftwards rightwards arrow from bar extender', google translation) - - "": [T: "venstrepil fra strek med hale"] # 0xeb75 (en: 'leftwards arrow from bar tail', google translation) - - "": [T: "høyrepil fra strek med hale"] # 0xeb76 (en: 'rightwards arrow from bar tail', google translation) - - "": [T: "høyrepil fra strek pilspiss"] # 0xeb77 (en: 'rightwards arrow from bar arrowhead', google translation) - - "": [T: "opp-harpun fra strek med mothake venstre pilspiss"] # 0xeb78 (en: 'upwards harpoon from bar with barb leftwards arrowhead', google translation) - - "": [T: "høyrepil over venstrepil høyre"] # 0xeb79 (en: 'rightwards arrow over leftwards arrow right', google translation) - - "": [T: "høyrepil over venstrepil venstre"] # 0xeb7a (en: 'rightwards arrow over leftwards arrow left', google translation) - - "": [T: "venstrepil over høyrepil høyre"] # 0xeb7b (en: 'leftwards arrow over rightwards arrow right', google translation) - - "": [T: "venstrepil over høyrepil venstre"] # 0xeb7c (en: 'leftwards arrow over rightwards arrow left', google translation) - - "": [T: "oppoverpil fra strek pilspiss"] # 0xeb7d (en: 'upwards arrow from bar arrowhead', google translation) - - "": [T: "oppoverpil fra strek hale"] # 0xeb7e (en: 'upwards arrow from bar tail', google translation) - - "": [T: "nedoverpil fra strek hale"] # 0xeb7f (en: 'downwards arrow from bar tail', google translation) - - "": [T: "nedoverpil fra strek pilspiss"] # 0xeb80 (en: 'downwards arrow from bar arrowhead', google translation) - - "": [T: "ned-harpun fra strek med mothake høyre pilspiss"] # 0xeb81 (en: 'downwards harpoon from bar with barb rightwards arrowhead', google translation) - - "": [T: "opp-harpun til venstre for ned-harpun bunn"] # 0xeb82 (en: 'upwards harpoon to the left of downwards harpoon bottom', google translation) - - "": [T: "opp-harpun til venstre for ned-harpun forlenger"] # 0xeb83 (en: 'upwards harpoon to the left of downwards harpoon extender', google translation) - - "": [T: "ned-harpun til venstre for opp-harpun topp"] # 0xeb84 (en: 'downwards harpoon to the left of upwards harpoon top', google translation) - - "": [T: "opp-harpun til venstre for ned-harpun topp"] # 0xeb85 (en: 'upwards harpoon to the left of downwards harpoon top', google translation) - - "": [T: "ned-harpun til venstre for opp-harpunens forlenger"] # 0xeb86 (en: 'downwards harpoon to the left of the upwards harpoon extender', google translation) - - "": [T: "ned-harpun til venstre for opp-harpunens bunn"] # 0xeb87 (en: 'downwards harpoon to the left of the upwards harpoon bottom', google translation) - - "": [T: "oppoverpil til venstre for nedoverpil bunn"] # 0xeb88 (en: 'upwards arrow leftwards of downwards arrow bottom', google translation) - - "": [T: "nedoverpil til venstre for oppoverpil topp"] # 0xeb89 (en: 'downwards arrow leftwards of upwards arrow top', google translation) - - "": [T: "oppoverpil til venstre for nedoverpil topp"] # 0xeb8a (en: 'upwards arrow leftwards of downwards arrow top', google translation) - - "": [T: "nedoverpil til venstre for oppoverpil bunn"] # 0xeb8b (en: 'downwards arrow leftwards of upwards arrow bottom', google translation) - - "": [T: "venstre-høyre-pil forlenger"] # 0xeb8c (en: 'leftwards rightwards arrows extender', google translation) - - "": [T: "nordøst-pil forlenger"] # 0xeb8d (google translation) - - "": [T: "nordvest-pil forlenger"] # 0xeb8e (google translation) - - "": [T: "nedoverpekende krøllparentes venstre"] # 0xec00 (en: 'down pointing brace left', google translation) - - "": [T: "nedoverpekende krøllparentes midten"] # 0xec01 (en: 'down pointing brace mid', google translation) - - "": [T: "nedoverpekende krøllparentes høyre"] # 0xec02 (en: 'down pointing brace right', google translation) - - "": [T: "horisontal krøllparentes forlenger"] # 0xec03 (en: 'horizontal brace extender', google translation) - - "": [T: "oppoverpekende krøllparentes venstre"] # 0xec04 (en: 'up pointing brace left', google translation) - - "": [T: "oppoverpekende krøllparentes midten"] # 0xec05 (en: 'up pointing brace mid', google translation) - - "": [T: "oppoverpekende krøllparentes høyre"] # 0xec06 (en: 'up-pointing brace right', google translation) - - "": [T: "venstre vertikal strek"] # 0xec07 (en: 'left vertical bar', google translation) - - "": [T: "høyre vertikal strek"] # 0xec08 (en: 'right vertical bar', google translation) - - "": [T: "venstre dobbel vertikal strek"] # 0xec09 (en: 'left double vertical bar', google translation) - - "": [T: "høyre dobbel vertikal strek"] # 0xec0a (en: 'right double vertical bar', google translation) - - "": [T: "horisontal hakeparentes forlenger"] # 0xec0b (en: 'horizontal bracket extender', google translation) - - "": [T: "under hakeparentes"] # 0xec0c (en: 'under square bracket', google translation) - - "⎵": [T: "under hakeparentes"] # 0x23b5 - - "": [T: "over hakeparentes"] # 0xec0d (en: 'over square bracket', google translation) - - "⎴": [T: "over hakeparentes"] # 0x23b4 - - "": [T: "under hakeparentes venstre"] # 0xec0e (en: 'under bracket left', google translation) - - "": [T: "under hakeparentes høyre"] # 0xec0f (en: 'under bracket right', google translation) - - "": [T: "over hakeparentes venstre"] # 0xec10 (en: 'over bracket left', google translation) - - "": [T: "over hakeparentes høyre"] # 0xec11 (en: 'over bracket right', google translation) - - "": [T: "venstreparentes 1"] # 0xec12 (en: 'left parens 1', google translation) - - "": [T: "venstreparentes 2"] # 0xec13 (en: 'left parens 2', google translation) - - "": [T: "venstreparentes 3"] # 0xec14 (en: 'left parens 3', google translation) - - "": [T: "venstreparentes 4"] # 0xec15 (en: 'left parens 4', google translation) - - "": [T: "høyreparentes 1"] # 0xec16 (en: 'right parens 1', google translation) - - "": [T: "høyreparentes 2"] # 0xec17 (en: 'right parens 2', google translation) - - "": [T: "høyreparentes 3"] # 0xec18 (en: 'right parens 3', google translation) - - "": [T: "høyreparentes 4"] # 0xec19 (en: 'right parens 4', google translation) - - "": [T: "radikal 1"] # 0xec1a (en: 'radical 1', google translation) - - "": [T: "radikal 2"] # 0xec1b (en: 'radical 2', google translation) - - "": [T: "radikal 3"] # 0xec1c (en: 'radical 3', google translation) - - "": [T: "radikal 4"] # 0xec1d (en: 'radical 4', google translation) - - "": [T: "radikal 5"] # 0xec1e (en: 'radical 5', google translation) - - "": [T: "radikal bunn"] # 0xec1f (en: 'radical bottom', google translation) - - "": [T: "radikal vertikal forlenger"] # 0xec20 (en: 'radical vertical extender', google translation) - - "": [T: "radikal topp"] # 0xec21 (en: 'radical top', google translation) - - "": [T: "venstre hvit hakeparentes topp"] # 0xec22 (en: 'left white bracket top', google translation) - - "": [T: "venstre hvit hakeparentes forlenger"] # 0xec23 (en: 'left white bracket extender', google translation) - - "": [T: "venstre hvit hakeparentes bunn"] # 0xec24 (en: 'left white bracket bottom', google translation) - - "": [T: "høyre hvit hakeparentes topp"] # 0xec25 (en: 'right white bracket top', google translation) - - "": [T: "høyre hvit hakeparentes forlenger"] # 0xec26 (en: 'right white bracket extender', google translation) - - "": [T: "høyre hvit hakeparentes bunn"] # 0xec27 (en: 'right white bracket bottom', google translation) - - "": [T: "venstre hvit krøllparentes"] # 0xec30 (en: 'left white curly bracket', google translation) - - "": [T: "høyre hvit krøllparentes"] # 0xec31 (en: 'right white curly bracket', google translation) - - "": [T: "lang divisjon"] # 0xec32 (en: 'long division sign', google translation) - - "": [T: "lang divisjon forlenger"] # 0xec33 (google translation) - - "": [T: "kort divisjon"] # 0xec34 (en: 'short division', google translation) - - "": [T: "dobbel sørvest til nordøst em-binding"] # 0xec40 (en: 'double southwest to northeast em bond', google translation) - - "": [T: "dobbel nordvest til sørøst em-binding"] # 0xec41 (en: 'double northwest to southeast em bond', google translation) - - "": [T: "enkel horisontal em-binding"] # 0xec42 (en: 'single horizontal em bond', google translation) - - "": [T: "dobbel horisontal em-binding"] # 0xec43 (en: 'double horizontal em bond', google translation) - - "": [T: "trippel horisontal em-binding"] # 0xec44 (en: 'triple horizontal em bond', google translation) - - "": [T: "enkel vertikal em-binding"] # 0xec45 (en: 'single vertical em bond', google translation) - - "": [T: "dobbel vertikal em-binding"] # 0xec46 (en: 'double vertical em bond', google translation) - - "": [T: "trippel vertikal em-binding"] # 0xec47 (google translation) - - "": [T: "mindre enn em-binding"] # 0xec48 (en: 'less than em bond', google translation) - - "": [T: "større enn em-binding"] # 0xec49 (en: 'greater than em bond', google translation) - - "": [T: "enkel horisontal en-binding"] # 0xec4a (en: 'single horizontal en bond', google translation) - - "": [T: "dobbel horisontal en-binding"] # 0xec4b (en: 'double horizontal en bond', google translation) - - "": [T: "trippel horisontal en-binding"] # 0xec4c (en: 'triple horizontal en bond', google translation) - - "": [T: "øvre venstre rektangel"] # 0xec80 (en: 'top left rectangle', google translation) - - "": [T: "nedre venstre rektangel"] # 0xec81 (en: 'bottom left rectangle', google translation) - - "": [T: "øvre høyre rektangel"] # 0xec90 (en: 'top right rectangle', google translation) - - "": [T: "nedre høyre rektangel"] # 0xec91 (en: 'bottom right rectangle', google translation) - - "": [T: "syntetisk divisjon hjørne"] # 0xec92 (en: 'synthetic division corner', google translation) - - "": [T: "syntetisk divisjon horisontal forlenger"] # 0xec93 (en: 'synthetic division horizontal extender', google translation) - - "": [T: "syntetisk divisjon vertikal forlenger"] # 0xec94 (en: 'synthetic division vertical extender', google translation) - - "": [T: "venstre tak gulv forlenger"] # 0xec95 (en: 'left ceiling floor extender', google translation) - - "": [T: "høyre tak gulv forlenger"] # 0xec96 (en: 'right ceiling floor extender', google translation) - - "": [T: "over hakeparentes forlenger"] # 0xec97 (en: 'over bracket extender', google translation) - - "": [T: "vertikal strek forlenger"] # 0xec98 (en: 'vertical bar extender', google translation) - - "": [T: "venstre dobbel vertikal strek forlenger"] # 0xec99 (en: 'left double vertical bar extender', google translation) - - "": [T: "horisontal strek forlenger"] # 0xec9a (en: 'horizontal bar extender', google translation) - - "": [T: "under hakeparentes forlenger"] # 0xec9c (en: 'under bracket extender', google translation) - - "": [T: "nedoverpekende parentes høyre"] # 0xec9d (en: 'down pointing paren right', google translation) - - "": [T: "nedoverpekende parentes forlenger"] # 0xec9e (en: 'down pointing paren extender', google translation) - - "": [T: "nedoverpekende parentes venstre"] # 0xec9f (en: 'down pointing paren left', google translation) - - "": [T: "oppoverpekende krøllparentes forlenger"] # 0xeca0 (en: 'up pointing brace extender', google translation) - - "": [T: "oppoverpekende parentes venstre"] # 0xeca1 (en: 'up pointing paren left', google translation) - - "": [T: "oppoverpekende parentes forlenger"] # 0xeca2 (en: 'up pointing paren extender', google translation) - - "": [T: "oppoverpekende parentes høyre"] # 0xeca3 (en: 'up pointing paren right', google translation) - - "": [T: "nedoverpekende krøllparentes forlenger"] # 0xeca4 (en: 'down pointing brace extender', google translation) - - "": [T: "plancks konstant over to pi strek"] # 0xed00 (en: 'planck constant over two pi bar', google translation) - - "": [T: "speilvendt g"] # 0xed01 (en: 'mirror g', google translation) - - "": [T: "j uten prikk"] # 0xed02 (google translation) - - "": [T: "digamma"] # 0xed03 (google translation) - - "ϝ": [T: "digamma"] # 0x3dd - - "": [t: ""] # 0xed10 (en: 'd', google translation) - - "": [t: ""] # 0xed11 (en: 'e', google translation) - - "": [t: ""] # 0xed12 (en: 'i', google translation) - - "": [T: ""] # 0xed13 (en: 'j', google translation) - - "ⅅ": - - SPELL: "translate('.', 'ⅅ', 'DD')" # 0xed16, 0x2145 - -# The private use chars are from MathType - - "": [T: "kurveintegral-loop mot klokka"] # 0xee00 (en: 'anticlockwise contour integral loop', google translation) - - "": [T: "kurveintegral-loop med klokka"] # 0xee01 (en: 'clockwise contour integral loop', google translation) - - "": [T: ""] # 0xee04 - - "": [T: ""] # 0xee05 - - "": [T: ""] # 0xee06 - - "": [T: ""] # 0xee07 - - "": [T: ""] # 0xee08 - - "": [T: ""] # 0xee09 - - "": [T: ""] # 0xee0a - - "": [T: ""] # 0xee0b - - "": [T: ""] # 0xee0c - - "": [T: "joint status"] # 0xee0d (en: 'joint status embellishment', google translation) - - "": [T: "joint status venstre"] # 0xee0e (en: 'joint status embellishment left', google translation) - - "": [T: "joint status høyre"] # 0xee0f (en: 'joint status embellishment right', google translation) - - "": [T: "joint status forlenger"] # 0xee10 (en: 'joint status embellishment extender', google translation) - - "": [T: "integral-loop"] # 0xee11 (en: 'integral loop', google translation) - - "": [T: "dobbel integral-loop"] # 0xee12 (google translation) - - "": [T: "trippel integral-loop"] # 0xee13 (en: 'integral loop triple', google translation) - - "": [T: "ekspanderende dobbel integral-loop"] # 0xee15 (google translation) - - "": [T: "ekspanderende trippel integral-loop"] # 0xee16 (en: 'expanding integral loop triple', google translation) - - "": [T: "asymptotisk lik"] # 0xee17 (en: 'asymptotically equal to accent', google translation) - - "": [T: "lik"] # 0xee18 (en: 'equal sign accent', google translation) - - "": [T: "kvadrupelt primtegn"] # 0xee19 (en: 'quadruple prime', google translation) - - "": [T: "strek med åpen sirkel venstre"] # 0xee1a (en: 'bar accent with open circle left', google translation) - - "": [T: "strek med lukket sirkel venstre"] # 0xee1b (en: 'bar accent with closed circle left', google translation) - - "": [T: "strek med åpen sirkel høyre"] # 0xee1c (en: 'bar accent with open circle right', google translation) - - "": [T: "strek med prikk"] # 0xee1d (en: 'bar accent with over dot', google translation) - - "": [T: "strek over prikk"] # 0xee1e (en: 'bar accent with under dot', google translation) - - "": [T: "strek med dobbel prikk over"] # 0xee1f (en: 'bar accent with double over dot', google translation) - - "": [T: "strek over dobbel prikk"] # 0xee20 (en: 'bar accent with double under dot', google translation) - - "": [T: "strek med hatt"] # 0xee21 (en: 'bar accent with caret', google translation) - - "": [T: "fet understrek"] # 0xee22 (en: 'thick under bar accent', google translation) - - "": [T: "strek med lukket sirkel høyre"] # 0xee23 (en: 'bar accent with closed circle right', google translation) - - "": [T: "stor prikk"] # 0xee24 (en: 'large dot above', google translation) - - "": [T: "justeringsmerke"] # 0xef00 (en: 'alignment mark', google translation) - - "": [T: ""] # 0xef01 - - "​": [T: ""] # 0x200b - - "": [T: ""] # 0xef02 - - " ": [T: ""] # 0x2009 - - "": [T: ""] # 0xef03 - - " ": [T: ""] # 0x205f - - "": [T: ""] # 0xef04 - - "": [T: ""] # 0xef05 - - "": [T: ""] # 0xef06 - - "": [T: ""] # 0xef07 - - "": [T: ""] # 0xef08 - - "": [T: ""] # 0xef09 - - "": [T: ""] # 0xef0a - - " ": [T: ""] # 0x200a - - "": [T: ""] # 0xef22 - - "": [T: ""] # 0xef23 - - "": [T: ""] # 0xef24 - - "": [T: ""] # 0xef29 - - "": [T: "savnet begrep"] # 0xef41 (en: 'missing term', google translation) - - "": [T: "kurveintegral med klokka pil til venstre"] # 0xef80 (en: 'clockwise contour integral arrow on left', google translation) - - "": [T: "integral med kvadrat"] # 0xef81 (en: 'integral with square', google translation) - - "": [T: "integral med skråstrek"] # 0xef82 (en: 'integral with slash', google translation) - - "": [T: "speilvendt integral"] # 0xef83 (en: 'reversed integral', google translation) - - "": [T: "dobbel null over dobbel null"] # 0xef90 (en: 'double zero over double zero', google translation) - - "": [T: "null med skråstrek"] # 0xef91 (en: 'zero with slash', google translation) - #------------------------------------------------------------------------------------------------------------- - # fraktur chars in math alphabetic block and also MathType private use area - # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display - - "𝔄-𝔜": # 0x1d504 - 0x1d51d ('z' version is reserved) - - T: "fraktur" # (google translation) - - SPELL: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" - - "-": # 0xf000 - 0xf018 - - T: "fraktur" # (google translation) - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" - - - "𝔞-𝔷": # 0x1d51e - 0x1d537 - - T: "fraktur" # (google translation) - - SPELL: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" - - "-": # 0xf01a - 0xf033 - - T: "fraktur" # (google translation) - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝕬-𝖅": # 0x1D56C - 0x1D585 - - T: "fraktur" # (google translation) - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf040 - 0xf059 - - T: "fraktur" # (google translation) - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝖆-𝖟": # 0x1d586 - 0x1d59f - - T: "fraktur" # (google translation) - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" - - "-": # 0xf05a - 0xf073 - - T: "fraktur" # (google translation) - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - # double struck (blackboard bold) chars in math alphabetic block and also MathType private use area - # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display - - "𝔸-𝕐": # 0x1d504 - 0x1d51d ('z' version is reserved) - - T: "dobbeltstreket" # (en: 'double struck', google translation) - - SPELL: "translate('.', '𝔸𝔹𝔺𝔻𝔼𝔽𝔾𝔿𝕀𝕁𝕂𝕃𝕄𝕅𝕆𝕇𝕈𝕉𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf080 - 0xf098 - - T: "dobbeltstreket" # (en: 'double struck', google translation) - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝕒-𝕫": # 0x1d552 - 0x1d56b - - T: "dobbeltstreket" # (en: 'double struck', google translation) - - SPELL: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf09a - 0xf0b3 - - T: "dobbeltstreket" # (en: 'double struck', google translation) - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 - - T: "dobbeltstreket" # (en: 'double struck', google translation) - - SPELL: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" - - "-": # 0xf0c0 - 0xf0c9 - - T: "dobbeltstreket" # (en: 'double struck', google translation) - - SPELL: "translate('.', '', '0123456789')" - - - "": [T: "dobbeltstreket nabla"] # 0xf0ca (en: 'double struck nabla', google translation) - - "": [T: "dobbeltstreket eulerkonstant"] # 0xf0cb (en: 'double struck euler constant', google translation) - - # script chars in math alphabetic block and also MathType private use area - # SWEDISH: We've used "skrivstilt" instead of skript for clarity - # NORWEGIAN: Used "script font" - - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 - - T: "script font" # (en: 'script', google translation) - - SPELL: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf100 - 0xf119 - - T: "script font" # (en: 'script', google translation) - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf - - T: "script font" # (en: 'script', google translation) - - SPELL: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf11a - 0xf133 - - T: "script font" # (en: 'script', google translation) - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - # bold script chars in math alphabetic block and also MathType private use area - - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 - - T: "script font" # (en: 'script bold', google translation) - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf140 - 0xf159 - - T: "script font" # (en: 'script bold', google translation) - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝓪-𝔃": # 0x1d4ea - 0x1d503 - - T: "script font" # (en: 'script bold', google translation) - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf15a - 0xf173 - - T: "script font" # (en: 'script bold', google translation) - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf180 - 0xf199 - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "": # 0xf19a - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "stor"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [T: "ligatur a e"] # (en: 'ligature ae', google translation) - - "": # 0xf19b - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "stor"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [T: "dobbel s"] # (en: 'sharp s', google translation) - - "": # 0xf19c - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "stor"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [T: "ø"] # (en: 'o with stroke', google translation) - - # MathType only has a few of the cap Greek letters in PUA - - "": # 0xf201 - 0xf209 - - T: "dobbeltstreket" # (en: 'double struck', google translation) - - SPELL: "translate('.', '', 'ΔΨΛΠΣΘΓΩΥ')" - - - "-": # 0xf220 - 0xf236 - - T: "dobbeltstreket" # (en: 'double struck', google translation) - - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "": [T: "dobbeltstreket sluttsigma"] # 0xf237 (en: 'double struck final sigma', google translation) - - "": [T: "dobbeltstreket rho"] # 0xf250 (en: 'double struck rho', google translation) - - "": [T: "dobbeltstreket fi"] # 0xf251 (en: 'double struck phi', google translation) - - "𝐀-𝐙": # 0x1d400 - 0x1d419 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf260 - 0xf279 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝐚-𝐳": # 0x1d41a - 0x1d433 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf27a - 0xf293 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝐴-𝑍": # 0x1d434 - 0x1d44d - - SPELL: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf294 - 0xf2ad - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝑎-𝑧": # 0x1d44e - 0x1d467 - - SPELL: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf2ae - 0xf2c7 - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝑨-𝒁": # 0x1d468 - 0x1d481 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf2c8 - 0xf2e1 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝒂-𝒛": # 0x1d482 - 0x1d49b - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf2e2 - 0xf2fb - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 - - SPELL: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf300 - 0xf319 - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 - - SPELL: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf31a - 0xf333 - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf334 - 0xf34d - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝗮-𝘇": # 0x1d5ee - 0x1d607 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf34e - 0xf367 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - "𝘈-𝘡": # 0x1d608 - 0x1d621 - - SPELL: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - "-": # 0xf368 - 0xf381 - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝘢-𝘻": # 0x1d622 - 0x1d63b - - SPELL: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf382 - 0xf39b - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝘼-𝙕": # 0x1d63c - 0x1d655 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf39c - 0xf3b5 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝙖-𝙯": # 0x1d656 - 0x1d66f - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf3b6 - 0xf3cf - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝙰-𝚉": # 0x1d670 - 0x1d689 - - SPELL: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf3d0 - 0xf3e9 - - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 - - SPELL: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf3ea - 0xf403 - - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "": [T: "i uten prikk"] # 0xf404 (google translation) - - "𝚤": [T: "kursiv i uten prikk"] # 0x1d6a4 (en: 'dotless i', google: 'dotless i') - - "𝚥": [T: "kursiv j uten prikk"] # 0x1d6a5 (en: 'dotless j', google: 'dotless j') - - - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "-": # 0xf408 - 0xf420 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf422 - 0xf43a - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "": [T: "fet nabla"] # 0xf421 (en: 'bold nabla', google translation) - - "𝛁": [T: "fet nabla"] # 0x1d6c1 (en: 'bold nabla', google translation) - - - "𝛛𝛜𝛝𝛞𝛟𝛠𝛡": # 0x1D6DB - 0x1D6E1 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" - - - "": # 0xF43C - 0xF441 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', '∂εθκφρπ')" - - - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa - - SPELL: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "-": # 0xf442 - 0xf45a - - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝛼-𝜔": # 0x1d6fc - 0x1d714 - - SPELL: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓𝜔', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf45c - 0xf474 - - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "": [T: "kursiv nabla"] # 0xf45b (en: 'italic nabla', google translation) - - "𝛻": [T: "kursiv nabla"] # 0x1d6fb (en: 'italic nabla', google translation) - - - "𝜕𝜖𝜗𝜘𝜙𝜚𝜛": # 0x1d715 - 0x1d71b - - SPELL: "translate('.', '𝜕𝜖𝜗𝜘𝜙𝜚𝜛', '∂εθκφρπ')" - - - "": # 0xf475 - 0xf47b - - SPELL: "translate('.', '', '∂εθκφρπ')" - - - "𝜜-𝜴": # 0x1d71c - 0x1d734 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "-": # 0xf47c - 0xf494 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝜶-𝝎": # 0x1d736 - 0x1d74e - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf496 - 0xf4ae - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": # 0x1d74f - 0x1d755 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εθκφρπ')" - - - "": # 0xf422 - 0xf43a - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', '∂εθκφρπ')" - - - "𝜵": [T: "fet kursiv nabla"] # 0x1d735 (en: 'bold italic nabla', google translation) - - "": [T: "fet kursiv nabla"] # 0xf495 (en: 'bold italic nabla', google translation) - - - "𝝖-𝝮": # 0x1d756 - 0x1d76e - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - "-": # 0xf4b6 - 0xf4ce - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝝰-𝞈": # 0x1d770 - 0x1d788 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇𝞈', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf4d0 - 0xf4e8 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "𝞉𝞊𝞋𝞌𝞍𝞎𝞏": # 0x1d789 - 0x1d78f - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝞉𝞊𝞋𝞌𝞍𝞎𝞏', '∂εθκφρπ')" - - - "": # 0xf4e9 - 0xf4ef - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', '∂εθκφρπ')" - - - "": [T: "fet nabla"] # 0xf4cf (en: 'bold nabla', google translation) - - "𝝯": [T: "fet nabla"] # 0x1d76f (en: 'bold nabla', google translation) - - - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "-": # 0xf4f0 - 0xf508 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝞪-𝟂": # 0x1d7aa - 0x1d7c2 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf50a - 0xf522 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": # 0x1d7c3 - 0x1d7c9 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝟃𝟄𝟅𝟆𝟇𝟈𝟉', '∂εθκφρπ')" - - - "": # 0xf523 - 0xf529 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', '∂εθκφρπ')" - - - "": [T: "fet nabla"] # 0xf509 (en: 'bold nabla', google translation) - - "𝞩": [T: "fet nabla"] # 0x1d7a9 (en: 'bold nabla', google translation) - - - "-": # 0xf52e - 0xf537 (old MathType) - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', '0123456789')" - - - "𝟎-𝟗": # 0x1d7ce - 0x1d7d7 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" - - - "-": # 0xf542 - 0xf54b (old MathType) - - SPELL: "translate('.', '', '0123456789')" - - - "𝟢-𝟫": # 0x1d7e2 - 0x1d7eb (old MathType) - - SPELL: "translate('.', '𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫', '0123456789')" - - - "-": # 0xf54c - 0xf555 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '', '0123456789')" - - - "𝟬-𝟵": # 0x1d7ec - 0x1d7f5 - - test: - if: "not($IgnoreBold)" - then: [T: "fet"] - - SPELL: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" - - - "-": # 0xf556 - 0xf55f (old MathType) - - SPELL: "translate('.', '', '0123456789')" - - - "𝟶-𝟿": # 0x1d7f6 - 0x1d7ff - - SPELL: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" - - - "": [T: "ukjent tegn"] # 0xf700 (en: 'unknown character', google translation) - - "": [T: "nedre høyre og nedre venstre trekanter"] # 0xf726 (en: 'lower right and lower left triangles', google translation) - - "": [T: "horisontal ellipse forlenger"] # 0xf72d (en: 'horizontal ellipsis extender', google translation) - - "": [T: "midtlinje horisontal ellipse forlenger"] # 0xf72e (en: 'midline horizontal ellipsis extender', google translation) - - "": [T: "radikal forlenger"] # 0xf8e5 (en: 'radical extender', google translation) - - "": [T: "vertikal pil-forlenger"] # 0xf8e6 (en: 'vertical arrow extender', google translation) - - "": [T: "horisontal pil-forlenger"] # 0xf8e7 (en: 'horizontal arrow extender', google translation) - - "": [T: "registrert"] # 0xf8e8 (en: 'registered sign sans serif', google translation) - - "": [T: "opphavsrett"] # 0xf8e9 (google translation) - - "": [T: "varemerke"] # 0xf8ea (google translation) - - "": [T: "venstreparentes topp"] # 0xf8eb (en: 'left paren top', google translation) - - "": [T: "venstreparentes forlenger"] # 0xf8ec (en: 'left paren extender', google translation) - - "": [T: "venstreparentes bunn"] # 0xf8ed (en: 'left paren bottom', google translation) - - "": [T: "venstre hakeparentes topp"] # 0xf8ee (en: 'left bracket top', google translation) - - "": [T: "venstre hakeparentes forlenger"] # 0xf8ef (en: 'left bracket extender', google translation) - - "": [T: "venstre hakeparentes bunn"] # 0xf8f0 (en: 'left bracket bottom', google translation) - - "": [T: "venstre krøllparentes topp"] # 0xf8f1 (en: 'left brace top', google translation) - - "": [T: "venstre krøllparentes midten"] # 0xf8f2 (en: 'left brace mid', google translation) - - "": [T: "venstre krøllparentes bunn"] # 0xf8f3 (en: 'left brace bottom', google translation) - - "": [T: "krøllparentes forlenger"] # 0xf8f4 (en: 'brace extender', google translation) - - "": [T: "integral forlenger"] # 0xf8f5 (en: 'integral extender', google translation) - - "": [T: "høyreparentes topp"] # 0xf8f6 (en: 'right paren top', google translation) - - "": [T: "høyreparentes forlenger"] # 0xf8f7 (en: 'right paren extender', google translation) - - "": [T: "høyreparentes bunn"] # 0xf8f8 (en: 'right paren bottom', google translation) - - "": [T: "høyre hakeparentes topp"] # 0xf8f9 (en: 'right bracket top', google translation) - - "": [T: "høyre hakeparentes forlenger"] # 0xf8fa (en: 'right bracket extender', google translation) - - "": [T: "høyre hakeparentes bunn"] # 0xf8fb (en: 'right bracket bottom', google translation) - - "": [T: "høyre krøllparentes topp"] # 0xf8fc (en: 'right brace top', google translation) - - "": [T: "høyre krøllparentes midten"] # 0xf8fd (en: 'right brace mid', google translation) - - "": [T: "høyre krøllparentes bunn"] # 0xf8fe (en: 'right brace bottom', google translation) - - "": [T: "apple logo"] # 0xf8ff (en: 'apple logo', google translation) - #-------------------------------------------------------------------------------------------------------------- - #Alphabetic presentation forms - - "ff": [T: "f f"] # 0xfb00 (en: 'ff', google: 'ff') - - "fi": [T: "f i"] # 0xfb01 (en: 'fi', google: 'fi') - - "fl": [T: "f l"] # 0xfb02 (en: 'fl', google: 'fl') - - "ffi": [T: "f f i"] # 0xfb03 (en: 'ffi', google: 'ffi') - - "ffl": [T: "f f l"] # 0xfb04 (en: 'ffl', google: 'ffl') - - "ſt": [T: "f t"] # 0xfb05 (en: 'ft', google translation) - - "st": [T: "s t"] # 0xfb06 (google translation) - - "﬩": [T: "hebraisk bokstav alternativ pluss"] # 0xfb29 - #------------------------------------------------------------------------------------------------------------------ - # Combining half marks - - "︠": [T: "ligatur venstre halvdel"] # 0xfe20 (en: 'ligature left half embellishment', google translation) - - "︡": [T: "ligatur høyre halvdel"] # 0xfe21 (en: 'ligature right half embellishment', google translation) - - "︢": [T: "dobbel tilde venstre halvdel"] # 0xfe22 (en: 'double tilde left half embellishment', google translation) - - "︣": [T: "dobbel tilde høyre halvdel"] # 0xfe23 (en: 'double tilde right half embellishment', google translation) - - "︤": [T: "makron venstre halvdel"] # 0xfe24 (en: 'macron left half embellishment', google translation) - - "︥": [T: "makron høyre halvdel"] # 0xfe25 (en: 'macron right half embellishment', google translation) - - "︦": [T: "sammenkoblet makron"] # 0xfe26 (en: 'conjoining macron embellishment', google translation) - #----------------------------------------------------------------------------------------------------------------- - #CJK compatibility forms - - "︵": [T: "parentes over"] # 0xfe35 - - "︶": [T: "parentes under"] # 0xfe36 - - "︷": [T: "krøllparentes over"] # 0xfe37 (en: 'over brace') - - "︸": [T: "krøllparentes under"] # 0xfe38 (en: 'under brace') - - "︿": [T: "vinkelparentes over"] # 0xfe3f - - "﹀": [T: "vinkelparentes under"] # 0xfe40 -#------------------------------------------------------------------------------------------------------------------ -#Halfwidth and Fullwidth forms - - "﹡": [T: "liten asterisk"] # 0xfe61 - - "﹢": [T: "liten pluss"] # 0xfe62 - - "﹣": [T: "liten minus"] # 0xfe63 - - "﹤": [T: "liten mindre enn"] # 0xfe64 - - "﹥": [T: "liten større enn"] # 0xfe65 - - "﹦": [T: "lite likhetstegn"] # 0xfe66 - - "+": [T: "pluss"] # 0xff0b - - "<": [T: "mindre enn"] # 0xff1c - - "=": [T: "lik"] # 0xff1d - - ">": [T: "større enn"] # 0xff1e - - "\": [T: "omvendt skråstrek"] # 0xff3c - - "^": [T: "hatt"] # 0xff3e - - "|": # 0xff5c - # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' - - with: - variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) - replace: - - test: - - if: "$SpeechStyle != 'ClearSpeak'" - then_test: - if: "$DefaultToGiven" - then: [pause: short, T: "gitt"] - else: [T: "vertikal strek"] - - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" - then: [T: "vertikal strek"] - - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" - then: [T: "slik at"] - - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" - then: [pause: short, T: "gitt"] - - else: [T: "deler"] - - "~": [T: "tilde"] # 0xff5e - - "¬": [T: "ikke"] # 0xffe2 - - "←": [T: "venstrepil"] # 0xffe9 - - "↑": [T: "oppoverpil"] # 0xffea - - "→": [T: "høyrepil"] # 0xffeb - - "↓": [T: "nedoverpil"] # 0xffec - #-------------------------------------------------------------------------------------------------------------------- - #Small form variants - - "﹨": [T: "liten speilvendt skråstrek"] # 0xfe68 - #--------------------------------------------------------------------------------------------------------------------- - #Specials - - "": [T: "ukjent eller savnet objekt"] # 0xfffc (en: 'unknown or missing object', google translation) - - "�": [T: "ukjent eller savnet tegn"] # 0xfffd (google: 'okänd eller saknad karaktär') - - - "🣑": [T: "er i likevekt med"] # 0x1F8D1 - - "🣒": [T: "er i likevekt, forskjøvet mot høyre, med"] # 0x1F8D2 - - "🣓": [T: "er i likevekt, forskjøvet mot venstre, med"] # 0x1F8D3 - -# MathJax v4 has adopted these PUA values for some partial chem bonds that aren't in Unicode - - "\uE410": [T: "delvis enkeltbinding"] # 0xe410 - - "\uE411": [T: "delvis dobbeltbinding"] # 0xe411 - - "\uE412": [T: "delvis trippelbinding"] # 0xe412 - -# MathJax v4 also adopted these PUA values for some arrows thar are in Unicode -# Hopefully these will be exported properly in future versions of MathJax - - "\uE428": [SPELL: "'⟵'"] # 0xe428 defer to def of arrow - - "\uE429": [SPELL: "'⟶'"] # 0xe429 defer to def of arrow - - "\uE42A": [SPELL: "'⟷'"] # 0xe42a defer to def of arrow - - "\uE408": [SPELL: "'🣑'"] # 0xe408 defer to def of arrow - - "\uE409": [SPELL: "'🣒'"] # 0xe409 defer to def of arrow - - "\uE40A": [SPELL: "'🣓'"] # 0xe40a defer to def of arrow - - "\uE42B": [SPELL: "'⇄'"] # 0xe42b defer to def of arrow - - "\uE42C": [SPELL: "'←'"] # 0xe42c defer to def of arrow - - "\uE42D": [SPELL: "'→'"] # 0xe42d defer to def of arrow - - "\uE42E": [SPELL: "'⇄'"] # 0xe42e defer to def of arrow +--- + +#C1 Controls and Latin-1 Supplement OK + - "¢": [T: "cent"] # 0xa2 (en: 'cents') + - "£": [T: "pund"] # 0xa3 (en: 'pounds') + - "¤": [T: "valutategn"] # 0xa4 (en: 'currency sign') + - "¥": [T: "yen"] # 0xa5 + - "¦": [T: "brutt vertikalstrek"] # 0xa6 (en: 'broken bar') + - "§": [T: "paragraf"] # 0xa7 (en: 'section') + - "¨": [T: "trema"] # 0xa8 (en: 'double dot', MathPlayer: 'trema', google: 'dubbel prick') + - "©": [T: "opphavsrett"] # 0xa9 (en: 'copyright') + - "ª": [T: "feminin ordenstallindikator"] # 0xaa (en: 'feminine ordinal indicator', MathPlayer: 'feminine ordinal indicator', google: 'feminin ordinär indikator') + - "«": [T: "venstre sitattegn"] # 0xab (en: 'left-pointing double angle quote mark') + - "¯": # 0xaf + - test: + if: "ancestor::m:modified-variable and preceding-sibling::*[1][self::m:mi]" + then: [T: "bar"] # (google translation) + else: [T: "strek"] # (en: 'line') + - "²": [T: "i andre"] # 0xb2 (en: 'two', MathPlayer: 'exponent två', google: 'två') + - "³": [T: "i tredje"] # 0xb3 (en: 'three', MathPlayer: 'exponent tre', google: 'tre') + - "µ": [T: "mikro"] # 0xb5 (en: 'micro') + - "¹": [T: "eksponent én"] # 0xb9 (en: 'one', google: 'ett') + - "º": [T: "maskulin ordenstallindikator"] # 0xba (en: 'masculine ordinal indicator', MathPlayer: 'masculine ordinal indicator', google: 'maskulina ordinära indikatorer') + - "¡": [T: "omvendt utropstegn"] # 0xa1 + - "¶": [T: "paragraftegn"] # 0xb6 + - "¿": [T: "omvendt spørsmålstegn"] # 0xbf + #------------------------------------------------------------------------------------------------------- + # SWEDISH: The Swedish character translations are based on the placement and appearance of the characters rather than their function, as function might be context-dependent. Placement above is used as the baseline, and low characters are translated as "låg(t)" (eng "low"). In most cases, no difference has been made in the translation between non-combining, modifier (Spacing Modifier Letters), and combining/embellishment characters. However, in the case of alphabetical letters and punctuation marks as modifier characters (such as modifier small h or comma embellishment), the construction "med ...( efter)" (eng "with ...( placed after it)") is used to prevent any possible ambiguity. + # Norwegian: Same as Swedish +#Spacing Modifier Letters +#Latin superscript modifier letters OK + - "ʰ": [T: "med liten h etter"] # 0x2b0 (en: 'modifier small h', google translation) + - "ʱ": [T: "med liten h med krok etter"] # 0x2b1 (en: 'modifier small h with hook', google translation) + - "ʲ": [T: "med liten j etter"] # 0x2b2 (en: 'modifier small j', google translation) + - "ʳ": [T: "med liten r etter"] # 0x2b3 (en: 'modifier small r', google translation) + - "ʴ": [T: "med liten rotert r etter"] # 0x2b4 (en: 'modifier small turned r', google translation) + - "ʵ": [T: "med liten rotert r med krok etter"] # 0x2b5 (en: 'modifier small turned r with hook', google translation) + - "ʶ": # 0x2b6 + - T: "med liten rotert" # (en: 'modifier small inverted', google translation) + - SPELL: "translate('R', 'R', 'R')" + - "ʷ": [T: "med liten w etter"] # 0x2b7 (en: 'modifier small w', google translation) + - "ʸ": [T: "med liten y etter"] # 0x2b8 (en: 'modifier small y', google translation) + #-------------------------- + #Miscellaneous phonetic modifiers OK + - "ʹ": [T: "primtegn"] # 0x2b9 (en: 'modifier prime', google: 'modifier prime') + - "ʺ": [T: "dobbelt primtegn"] # 0x2ba (en: 'modifier double prime', google: 'modifier double prime') + - "ʻ": [T: "rotert komma"] # 0x2bb (en: 'modifier turned comma', google translation) + - "ʼ": [T: "apostrof"] # 0x2bc (google translation) + - "ʽ": [T: "speilvendt komma"] # 0x2bd (en: 'modifier reversed comma', google translation) + - "ʾ": [T: "høyrevendt halv ring"] # 0x2be (en: 'modifier right half ring', google: 'modifierare höger halva ring') + - "ʿ": [T: "venstrevendt halv ring"] # 0x2bf (en: 'modifier left half ring', google: 'modifierare lämnade halva ringen') + - "ˀ": [T: "glottal plosiv"] # 0x2c0 (google translation) + - "ˁ": [T: "speilvendt glottal plosiv"] # 0x2c1 (en: 'modifier reversed glottal stop', google translation) + - "˂": [T: "venstrevendt pilspiss"] # 0x2c2 (en: 'modifier left arrowhead', google translation) + - "˃": [T: "høyrevendt pilspiss"] # 0x2c3 (en: 'modifier right arrowhead', google translation) + - "˄": [T: "oppovervendt pilspiss"] # 0x2c4 (en: 'modifier up arrowhead', google translation) + - "˅": [T: "nedovervendt pilspiss"] # 0x2c5 (en: 'modifier down arrowhead', google translation) + - "ˆ": [T: "cirkumfleks"] # 0x2c6 (en: 'modifier circumflex accent', google: 'modifiercirumflex accent') + - "ˇ": [T: "hake"] # 0x2c7 (en: 'caron', google: 'caron') + - "ˈ": [T: "vertikal strek"] # 0x2c8 (en: 'modifier vertical line', google translation) + - "ˉ": [T: "makron"] # 0x2c9 (google translation) + - "ˊ": [T: "akutt aksent"] # 0x2ca (en: 'modifier acute accent', google translation) + - "ˋ": [T: "grav aksent"] # 0x2cb (en: 'modifier grave accent', google translation) + - "ˌ": [T: "lav vertikal strek"] # 0x2cc (en: 'modifier low vertical line', google translation) + - "ˍ": [T: "lav makron"] # 0x2cd (google translation) + - "ˎ": [T: "lav grav aksent"] # 0x2ce (en: 'modifier low grave accent', google translation) + - "ˏ": [T: "lav akutt aksent"] # 0x2cf (en: 'modifier low acute accent', google translation) + - "ː": [T: "kolon lengdetegn"] # 0x2d0 (en: 'modifier triangular colon', google translation) + - "ˑ": [T: "halvt kolon lengdetegn"] # 0x2d1 (en: 'modifier half triangular colon', google translation) + - "˒": [T: "lav høyrevendt halv ring"] # 0x2d2 (en: 'modifier centered right half ring', google translation) + - "˓": [T: "lav venstrevendt halv ring"] # 0x2d3 (en: 'modifier centered left half ring', google translation) + - "˔": [T: "lavt oppovervendt dreiekors"] # 0x2d4 (en: 'modifier up tadck', google translation) + - "˕": [T: "lavt nedovervendt dreiekors"] # 0x2d5 (en: 'modifier down tack', google translation) + - "˖": [T: "lavt plusstegn"] # 0x2d6 (google translation) + - "˗": [T: "lavt minustegn"] # 0x2d7 (en: 'modifier minus sign', google translation) + #---------------------------- + #Spacing clones of diacritics OK + - "˘": [T: "breve"] # 0x2d8 (en: 'breve') + - "˙": [T: "prikk"] # 0x2d9 (en: 'dot') + - "˚": [T: "ring"] # 0x2da (en: 'ring above') + - "˛": [T: "kvist"] # 0x2db (en: 'ogonek') + - "˜": [T: "liten tilde"] # 0x2dc (en: 'small tilde') + - "˝": [T: "dobbel akutt aksent"] # 0x2dd (en: 'double acute accent') + #----------------------------- + #Additions based on 1989 IPA OK + - "˞": [T: "rotisk hake"] # 0x2de (google translation) + - "˟": [T: "kryssaksent"] # 0x2df (en: 'modifier cross accent', google translation) + - "ˠ": [T: "med liten gamma etter"] # 0x2e0 (en: 'modifier small gamma', google translation) + - "ˡ": [T: "med liten l etter"] # 0x2e1 (en: 'modifier small l', google translation) + - "ˢ": [T: "med liten s etter"] # 0x2e2 (google translation) + - "ˣ": [T: "med liten x etter"] # 0x2e3 (en: 'modifier small x', google translation) + - "ˤ": [T: "liten speilvendt glottal plosiv"] # 0x2e4 (google translation) + #----------------------------- + #Tone letters OK + - "˥": [T: "ekstra høyt tonetegn"] # 0x2e5 (en: 'modifier extra-high tone bar', google translation) + - "˦": [T: "høyt tonetegn"] # 0x2e6 (google translation) + - "˧": [T: "mellom-tonetegn"] # 0x2e7 (en: 'modifier mid tone bar', google translation) + - "˨": [T: "lavt tonetegn"] # 0x2e8 (en: 'modifier low tone bar', google translation) + - "˩": [T: "ekstra lavt tonetegn"] # 0x2e9 (en: 'modifier extra-low tone bar', google translation) + #----------------------------- + #Extended Bopomofo tone marks OK + - "˪": [T: "mørkt fallende tonetegn"] # 0x2ea (en: 'modifier yin departing tone mark', google translation) + - "˫": [T: "lyst fallende tonetegn"] # 0x2eb (en: 'modifier yang departing tone mark', google translation) + #--------------------------- + #IPA modifiers OK + - "ˬ": [T: "lavt tonende tegn"] # 0x2ec (en: 'modifier voicing', google translation) + - "˭": [T: "ikke aspirert tegn"] # 0x2ed (en: 'modifier unaspirated', google translation) + #------------------------- + #Other modifier letter OK + - "ˮ": [T: "dobbel apostrof"] # 0x2ee (en: 'modifier double apostrophe', google translation) + #---------------------------- + #UPA modifiers OK + - "˯": [T: "lav nedoverpekende pilspiss"] # 0x2ef (en: 'modifier low down arrowhead', google translation) + - "˰": [T: "lav oppoverpekende pilspiss"] # 0x2f0 (google translation) + - "˱": [T: "lav venstrepekende pilspiss"] # 0x2f1 (en: 'modifier low left arrowhead', google translation) + - "˲": [T: "lav høyrepekende pilspiss"] # 0x2f2 (en: 'modifier low right arrowhead', google translation) + - "˳": [T: "lav ring"] # 0x2f3 (en: 'modifier low ring', google translation) + - "˴": [T: "lav grav aksent"] # 0x2f4 (google translation) + - "˵": [T: "lav dobbel grav aksent"] # 0x2f5 (en: 'modifier middle double grave accent', google translation) + - "˶": [T: "lav dobbel akutt aksent"] # 0x2f6 (en: 'modifier middle double acute accent', google translation) + - "˷": [T: "lav tilde"] # 0x2f7 (en: 'modifier low tilde', google translation) + - "˸": [T: "hevet kolon"] # 0x2f8 (en: 'modifier raised colon', google translation) + - "˹": [T: "start høy tone"] # 0x2f9 (en: 'modifier begin high tone', google translation) + - "˺": [T: "slutt høy tone"] # 0x2fa (en: 'modifier end high tone', google translation) + - "˻": [T: "start lav tone"] # 0x2fb (en: 'modifier begin low tone', google translation) + - "˼": [T: "slutt lav tone"] # 0x2fc (en: 'modifier end low tone', google translation) + - "˽": [T: "lav hylle"] # 0x2fd (en: 'modifier shelf', google translation) + - "˾": [T: "lav åpen hylle"] # 0x2fe (en: 'modifier open shelf', google translation) + - "˿": [T: "lav venstrepil"] # 0x2ff (en: 'modifier low left arrow', google translation) + #--------------------------------------------------------------------------------------------------------- + #Combining Diacritical Marks + #Ordinary diacritics OK + - "̈": [T: "trema"] # 0x308 (en: 'diaeresis embellishment', google: 'diaeresis utsmyckning') + - "̉": [T: "krok"] # 0x309 (en: 'hook above embellishment', google translation) + - "̊": [T: "ring"] # 0x30a (en: 'ring above embellishment', google: 'ring över utsmyckning') + - "̋": [T: "dobbel akutt aksent"] # 0x30b (en: 'double acute accent embellishment', google translation) + - "̌": [T: "hake"] # 0x30c (en: 'check', google: 'kolla upp') + - "̍": [T: "vertikal linje"] # 0x30d (en: 'vertical line above embellishment', google translation) + - "̎": [T: "dobbel vertikal linje"] # 0x30e (en: 'double vertical line above embellishment', google translation) + - "̏": [T: "dobbel grav aksent"] # 0x30f (en: 'double grave accent embellishment', google translation) + - "̐": [T: "Chandrabindu"] # 0x310 (en: 'candrabindu embellishment', google translation) + - "̑": [T: "omvendt breve"] # 0x311 (en: 'inverted breve embellishment', google: 'inverterad breve -utsmyckning') + - "̒": [T: "med rotert komma"] # 0x312 (en: 'turned comma above embellishment', google translation) + - "̓": [T: "med komma"] # 0x313 (en: 'comma above embellishment', google translation) + - "̔": [T: "med omvendt komma"] # 0x314 (en: 'reversed comma above embellishment', google translation) + - "̕": [T: "med høyrestilt komma"] # 0x315 (en: 'comma above right embellishment', google translation) + - "̖": [T: "lav grav aksent"] # 0x316 (en: 'grave accent below embellishment', google translation) + - "̗": [T: "lav akutt aksent"] # 0x317 (en: 'acute accent below embellishment', google translation) + - "̘": [T: "lavt venstre dreiekors"] # 0x318 (en: 'left tack below embellishment', google translation) + - "̙": [T: "lavt høyre dreiekors"] # 0x319 (en: 'right tack below embellishment', google translation) + - "̚": [T: "venstrevendt vinkeltegn"] # 0x31a (en: 'left angle above embellishment', google translation) + - "̛": [T: "horn"] # 0x31b (en: 'horn embellishment', google translation) + - "̜": [T: "lav venstrevendt halvring"] # 0x31c (en: 'left half ring below embellishment', google translation) + - "̝": [T: "lavt oppoverrotert dreiekors"] # 0x31d (en: 'up tack below embellishment', google translation) + - "̞": [T: "lavt nedoverrotert dreiekors"] # 0x31e (en: 'down tack below embellishment', google translation) + - "̟": [T: "lav pluss"] # 0x31f (en: 'plus sign below embellishment', google translation) + - "̠": [T: "lav minus"] # 0x320 (en: 'minus sign below embellishment', google translation) + - "̡": [T: "palatal krok"] # 0x321 (en: 'palatalized hook below embellishment', google translation) + - "̢": [T: "retrofleks krok"] # 0x322 (en: 'retroflex hook below embellishment', google translation) + - "̣": [T: "lav prikk"] # 0x323 (google: 'prick under utsmyckningen') + - "̤": [T: "lav trema"] # 0x324 (en: 'diaeresis below embellishment', google: 'diaeres under utsmyckning') + - "̥": [T: "lav ring"] # 0x325 (en: 'ring below embellishment', google translation) + - "̦": [T: "lavt komma"] # 0x326 (en: 'comma below embellishment', google translation) + - "̧": [T: "lav cédille"] # 0x327 (en: 'cedilla embellishment', google: 'cedilla -utsmyckning') + - "̨": [T: "lav kvist"] # 0x328 (en: 'ogonek embellishment', google translation) + - "̩": [T: "lav vertikal strek"] # 0x329 (en: 'vertical line below embellishment', google translation) + - "̪": [T: "lav bro"] # 0x32a (en: 'bridge below embellishment', google translation) + - "̫": [T: "lav omvendt dobbel bue"] # 0x32b (en: 'inverted double arch below embellishment', google translation) + - "̬": [T: "lav hake"] # 0x32c (en: 'caron below embellishment', google translation) + - "̭": [T: "lav omvendt cirkumfleks"] # 0x32d (en: 'circumflex accent below embellishment', google translation) + - "̮": [T: "lav breve"] # 0x32e (en: 'breve below embellishment', google: 'breve under utsmyckning') + - "̯": [T: "lav omvendt breve"] # 0x32f (en: 'inverted breve below embellishment', google translation) + - "̰": [T: "lav tilde"] # 0x330 (en: 'tilde below embellishment', google: 'tilde under utsmyckning') + - "̱": [T: "lav makron"] # 0x331 (en: 'macron below embellishment', google: 'macron under utsmyckning') + - "̲": [T: "lav strek"] # 0x332 (en: 'low line embellishment', google: 'låg linje utsmyckning') + - "̳": [T: "lav dobbeltstrek"] # 0x333 (en: 'double low line embellishment', google translation) + #------------------------------------------ + #Overstruck diacritics OK + - "̴": [T: "tilde i midten"] # 0x334 (en: 'tilde overlay embellishment', google translation) + - "̵": [T: "strek i midten"] # 0x335 (en: 'short stroke overlay embellishment', google translation) + - "̶": [T: "lang strek i midten"] # 0x336 (en: 'long stroke overlay embellishment', google translation) + - "̷": [T: "med kort skråstrek"] # 0x337 (en: 'short solidus overlay embellishment', google translation) + - "̸": [T: "med lang skråstrek"] # 0x338 (en: 'long solidus overlay embellishment', google: 'long solidus overlay embelling') + #------------------------------------ + #Miscellaneous additions OK + - "̹": [T: "lav høyrevendt halvring"] # 0x339 (en: 'right half ring below embellishment', google translation) + - "̺": [T: "lav omvendt bro"] # 0x33a (en: 'inverted bridge below embellishment', google translation) + - "̻": [T: "lavt kvadrat"] # 0x33b (en: 'square below embellishment', google translation) + - "̼": [T: "lavt måketegn"] # 0x33c (en: 'seagull below embellishment', google translation) + - "̽": [T: "med x over"] # 0x33d (en: 'x above embellishment', google translation) + - "̾": [T: "vertikal tilde"] # 0x33e (en: 'vertical tilde embellishment', google translation) + - "̿": [T: "dobbel strek"] # 0x33f (en: 'double overline embellishment', google translation) + - "̀": [T: "grav tone"] # 0x340 (en: 'grave tone mark embellishment', google translation) + - "́": [T: "akutt tone"] # 0x341 (en: 'acute tone mark embellishment', google translation) + - "͆": [T: "bro"] # 0x346 +#---------------------------------------------------------------------------------------------------------------- +# Greek and Coptic OK + - "ΪΫϏ": # 0x3aa, 0x3ab, 0x3cf + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "stor"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [SPELL: "translate('.', 'ΪΫϏ', 'ιυϗ')"] + - T: "med dialytika" # (en: 'with dialytika', google translation) + - "ϊ": [T: "iota med dialytika"] # 0x3ca (en: 'iota with dialytika', google translation) + - "ϋ": [T: "ypsilon med dialytika"] # 0x3cb (en: 'upsilon with dialytika', google translation) + - "ό": [T: "omikron med tonos"] # 0x3cc (en: 'omicron with tonos', google translation) + - "ύ": [T: "ypsilon med tonos"] # 0x3cd (en: 'upsilon with tonos', google translation) + - "ώ": [T: "omega med tonos"] # 0x3ce (en: 'omega with tonos', google translation) + - "ϐ": [T: "beta"] # 0x3d0 (en: 'beta') + - "ϑ": [T: "theta"] # 0x3d1 (en: 'theta', google: 'theta') + - "ϒ": [T: "ypsilon med krok"] # 0x3d2 (en: 'upsilon with hook', google: 'upsilon med krok') + - "ϓ": [T: "ypsilon med akutt aksent og krok"] # 0x3d3 (en: 'upsilon with acute and hook', google translation) + - "ϔ": [T: "ypsilon med trema og krok"] # 0x3d4 (en: 'upsilon with diaeresis and hook', google translation) + - "ϗ": [T: "kai"] # 0x3d7 (en: 'kai') + - "Ϙ": [T: "stor arkaisk koppa"] # 0x3d8 + - "ϙ": [T: "arkaisk koppa"] # 0x3d9 + - "А-Я": # 0x410 - 0x42f + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "stor"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [SPELL: "translate('.', 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ', 'абвгдежзийклмнопрстуфхцчшщъыьэюя')", pause: short] + - "а": [T: "a"] # 0x430 (google: 'а') + - "б": [T: "be"] # 0x431 (google: 'vara') + - "в": [T: "ve"] # 0x432 + - "г": [T: "ge"] # 0x433 + - "д": [T: "de"] # 0x434 + - "е": [T: "je"] # 0x435 (google: 'dvs') + - "ж": [T: "zhe"] # 0x436 + - "з": [T: "ze"] # 0x437 + - "и": [T: "i"] # 0x438 (google: 'и') + - "й": [T: "kort i"] # 0x439 (en: 'short i') + - "к": [T: "ka"] # 0x43a + - "л": [T: "el"] # 0x43b + - "м": [T: "em"] # 0x43c + - "н": [T: "en"] # 0x43d + - "о": [T: "o"] # 0x43e (google: 'о') + - "п": [T: "pe"] # 0x43f + - "р": [T: "er"] # 0x440 + - "с": [T: "es"] # 0x441 + - "т": [T: "te"] # 0x442 + - "у": [T: "u"] # 0x443 (google: 'у') + - "ф": [T: "ef"] # 0x444 + - "х": [T: "ha"] # 0x445 + - "ц": [T: "tse"] # 0x446 + - "ч": [T: "tsje"] # 0x447 + - "ш": [T: "sja"] # 0x448 + - "щ": [T: "sjtja"] # 0x449 + - "ъ": [T: "hardt tegn"] # 0x44a (en: 'hard sign') + - "ы": [T: "jeru"] # 0x44b + - "ь": [T: "mykt tegn"] # 0x44c (en: 'soft sign', google: 'mjukt skylt') + - "э": [T: "e"] # 0x44d (google: 'э') + - "ю": [T: "ju"] # 0x44e + - "я": [T: "ja"] # 0x44f + - "؆": [T: "arabisk-indisk kubikkrot"] # 0x606 + - "؇": [T: "arabisk-indisk fjerderot"] # 0x607 + - "؈": [T: "arabisk stråle"] # 0x608 + #----------------------------------------------------------------------------------------------------------- + #General punctuation OK + - "‐": [T: "bindestrek"] # 0x2010 (en: 'hyphen') + - "‑": [T: "bindestrek"] # 0x2011 (en: 'hyphen', google: 'bindestrek') + - "‒": [T: "tankestrek"] # 0x2012 (en: 'figure dash', google: 'figurstreck') + - "–": [T: "tankestrek"] # 0x2013 (en: 'en dash') + - "—": [T: "lang tankestrek"] # 0x2014 (en: 'em dash') + - "―": [T: "horisontal strek"] # 0x2015 (en: 'horizontal bar') + - "‖": [T: "dobbel loddrett strek"] # 0x2016 (en: 'double vertical line') + - "†": [T: "kors"] # 0x2020 (en: 'dagger') + - "‡": [T: "dobbelt kors"] # 0x2021 (en: 'double dagger') + + - " - ": [T: " "] # 0x2000 - 0x2007 + + - "•": # 0x2022 + - test: + if: "@data-chem-formula-op" + then: [T: "ganger"] # (en: 'dot', google translation) + else: [T: "listeelement"] # (en: 'bullet') + + - "‰": [T: "promille"] # 0x2030 (en: 'per mille', MathPlayer: 'promilletecken') + - "‱": [T: "per titusen"] # 0x2031 (en: 'per ten thousand') + - "′": [T: "primtegn"] # 0x2032 (en: 'prime') + - "″": [T: "dobbelt primtegn"] # 0x2033 (en: 'double prime') + - "‴": [T: "trippelt primtegn"] # 0x2034 (en: 'triple prime') + - "‵": [T: "omvendt primtegn"] # 0x2035 (en: 'reversed prime') + - "‶": [T: "omvendt dobbelt primtegn"] # 0x2036 (en: 'reversed double prime') + - "‷": [T: "omvendt trippelt primtegn"] # 0x2037 (en: 'reversed triple prime', google: 'omvänd trippelprime') + - "‸": [T: "innsettingstegn"] # 0x2038 (en: 'to the', google: 'till') + - "‹": [T: "venstrepekende vinkel-sitattegn"] # 0x2039 (en: 'single left pointing angle quote mark') + - "›": [T: "høyrepekende vinkel-sitattegn"] # 0x203a (en: 'single right pointing angle quote mark') + - "‼": # 0x203c + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [T: "dobbelt utropstegn"] # 0x203c + else: [T: "dobbel fakultet"] # 0x203c + - "⁄": # 0x2044 + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [T: "stor skråstrek"] # 0x203c + else: [T: "delt på"] # 0x203c + - "⁅": [T: "venstre piggparentes"] # 0x2045 (en: 'left square bracket with quill', google: 'vänster fyrkantig konsol med quill') + - "⁆": [T: "høyre piggparentes"] # 0x2046 (en: 'right square bracket with quill', google: 'höger fyrkantig konsol med quill') + - "※": [T: "referansetegn"] # 0x203b + - "‿": [T: "underbinding"] # 0x203F + - "⁀": [T: "bindetegn"] # 0x2040 + - "⁎": [T: "lav asterisk"] # 0x204e + - "⁏": [T: "omvendt semikolon"] # 0x204f + - "⁐": [T: "sammentrekksmerke"] # 0x2050 + - "⁑": [T: "to vertikale asterisk"] # 0x2051 + - "⁒": [T: "kommersielt minustegn"] # 0x2052 + - "⁗": [T: "firedobbelt primtegn"] # 0x2057 (en: 'quadruple prime', MathPlayer: 'quadruple prime', google: 'fyrdubbla prime') + - "⁠": [T: ""] # 0x2060 + #------------------------------------------------------------------------------------------------------------------------- + # Superscripts and subscripts OK + - "⁰": [T: "opphøyd i null"] # 0x2070 (en: 'to the zeroth power', google translation) + - "ⁱ": [T: "opphøyd i i"] # 0x2071 (en: 'to the eihth power', google: 'till eihth power') + - "⁴": [T: "opphøyd i fire"] # 0x2074 (en: 'to the fourth power', google translation) + - "⁵": [T: "opphøyd i fem"] # 0x2075 (en: 'to the fifth power', google translation) + - "⁶": [T: "opphøyd i seks"] # 0x2076 (en: 'to the sixth power', google translation) + - "⁷": [T: "opphøyd i sju"] # 0x2077 (en: 'to the seventh power', google translation) + - "⁸": [T: "opphøyd i åtte"] # 0x2078 (en: 'to the eighth power', google translation) + - "⁹": [T: "opphøyd i ni"] # 0x2079 (en: 'to the ninth power', google translation) + - "⁺": [T: "hevet pluss"] # 0x207a (en: 'superscript plus sign', google: 'superscript plus -skylt') + - "⁻": [T: "hevet minus"] # 0x207b (en: 'superscript minus', google: 'superscript minus') + - "⁼": [T: "hevet likhetstegn"] # 0x207c (en: 'superscript equals sign', google: 'superscript är lika med tecken') + - "⁽": [T: "hevet venstreparentes"] # 0x207d (en: 'superscript left parenthesis', google: 'superscript lämnade parentesen') + - "⁾": [T: "hevet høyreparentes"] # 0x207e (en: 'superscript right parenthesis', google: 'superscript höger parentes') + - "ⁿ": [T: "opphøyd i n"] # 0x207f (en: 'to the ennth power', google: 'till den ena kraften') + - "₀": [T: "senket null"] # 0x2080 (en: 'sub zero', google translation) + - "₁": [T: "senket én"] # 0x2081 (en: 'sub one', google translation) + - "₂": [T: "senket to"] # 0x2082 (en: 'sub two', google translation) + - "₃": [T: "senket tre"] # 0x2083 (en: 'sub three', google translation) + - "₄": [T: "senket fire"] # 0x2084 (en: 'sub four', google translation) + - "₅": [T: "senket fem"] # 0x2085 (en: 'sub five', google translation) + - "₆": [T: "senket seks"] # 0x2086 (en: 'sub six', google translation) + - "₇": [T: "senket sju"] # 0x2087 (en: 'sub seven', google translation) + - "₈": [T: "senket åtte"] # 0x2088 (en: 'sub eight', google translation) + - "₉": [T: "senket ni"] # 0x2089 (en: 'sub nine', google translation) + - "₊": [T: "senket pluss"] # 0x208a (en: 'subscript plus sign', google: 'subscript plus -skylt') + - "₋": [T: "senket minus"] # 0x208b (en: 'subscript minus sign', google: 'subscript minus sign') + - "₌": [T: "senket likhetstegn"] # 0x208c (en: 'subscript equals sign', google: 'subscript är lika med tecken') + - "₍": [T: "senket venstreparentes"] # 0x208d (en: 'subscript left parenthesis', google: 'subscript vänster-parentes av sig') + - "₎": [T: "senket høyreparentes"] # 0x208e (en: 'subscript right parenthesis', google: 'subscript höger parentes') + - "ₐ": [T: "senket a"] # 0x2090 (en: 'sub A', google: 'sub a') + - "ₑ": [T: "senket e"] # 0x2091 (en: 'sub E', google: 'sub e') + - "ₒ": [T: "senket o"] # 0x2092 (en: 'sub O', google: 'under o') + - "ₓ": [T: "senket x"] # 0x2093 (en: 'sub X', google: 'under x') + - "ₕ": [T: "senket h"] # 0x2095 (en: 'sub H', google: 'under h') + - "ₖ": [T: "senket k"] # 0x2096 (en: 'sub K', google: 'under k') + - "ₗ": [T: "senket l"] # 0x2097 (en: 'sub L', google: 'under l') + - "ₘ": [T: "senket m"] # 0x2098 (en: 'sub M', google: 'sub m') + - "ₙ": [T: "senket n"] # 0x2099 (en: 'sub N', google: 'under n') + - "ₚ": [T: "senket p"] # 0x209a (en: 'sub P', google: 'sub p') + - "ₛ": [T: "senket s"] # 0x209b (en: 'sub S', google: 'sub s') + - "ₜ": [T: "senket t"] # 0x209c (en: 'sub T', google: 'under t') + #-------------------------------------------------------------------------------------------------------------------- + #Currency symbols OK + - "₠": [T: "europeisk valutaenhet"] # 0x20a0 (en: 'european currenty units', google translation) + - "₡": [T: "colón"] # 0x20a1 + - "₢": [T: "cruzeiro"] # 0x20a2 + - "₣": [T: "franc"] # 0x20a3 + - "₤": [T: "lira"] # 0x20a4 (google: 'lire') + - "₥": [T: "mill"] # 0x20a5 + - "₦": [T: "naira"] # 0x20a6 + - "₧": [T: "peseta"] # 0x20a7 + - "₨": [T: "rupi"] # 0x20a8 (google: 'rupier') + - "₩": [T: "won"] # 0x20a9 (google: 'vann') + - "₪": [T: "ny shekel"] # 0x20aa (google: 'shekel') + - "₫": [T: "dong"] # 0x20ab + - "€": [T: "euro"] # 0x20ac (en: 'euros') + - "₭": [T: "kip"] # 0x20ad (google: 'slaf') + - "₮": [T: "tugrik"] # 0x20ae + - "₯": [T: "drakmer"] # 0x20af (google: 'drakma') + - "₰": [T: "pfenniger"] # 0x20b0 (google: 'tyska pennies') + - "₱": [T: "peso"] # 0x20b1 + - "₲": [T: "guaranier"] # 0x20b2 + - "₳": [T: "australes"] # 0x20b3 (google: 'österral') + - "₴": [T: "hryvnjaer"] # 0x20b4 + - "₵": [T: "cedi"] # 0x20b5 + - "₶": [T: "livre tournois"] # 0x20b6 (google translation) + - "₷": [T: "spesmilo"] # 0x20b7 (google translation) + - "₸": [T: "tenge"] # 0x20b8 (google translation) + - "₹": [T: "indiske rupi"] # 0x20b9 (en: 'indian rupees', google translation) + - "₺": [T: "tyrkiske lira"] # 0x20ba (en: 'turkish liras', google translation) + #-------------------------------------------------------------------------------------------------------------- + #Combining Diacritical Marks for Symbols OK + - "⃐": [T: "venstre-harpun"] # 0x20d0 (en: 'left harpoon above embellishment', google: 'vänster harpoon ovanför utsmyckning') + - "⃑": [T: "høyre-harpun"] # 0x20d1 (en: 'right harpoon above embellishment', google: 'höger harpoon ovanför utsmyckning') + - "⃒": [T: "lang vertikal strek"] # 0x20d2 (en: 'long vertical line overlay embellishment', google translation) + - "⃓": [T: "kort vertikal strek"] # 0x20d3 (en: 'short vertical line overlay embellishment', google translation) + - "⃔": [T: "pil mot klokken"] # 0x20d4 (en: 'anticlockwise arrow above embellishment', google translation) + - "⃕": [T: "pil med klokken"] # 0x20d5 (en: 'clockwise arrow above embellishment', google translation) + - "⃖": [T: "venstrepil"] # 0x20d6 (en: 'left arrow above embellishment', google: 'vänster pil över utsmyckningen') + - "⃗": [T: "høyrepil"] # 0x20d7 (en: 'right arrow above embellishment', google: 'höger-pil över utsmyckning') + - "⃘": [T: "ring"] # 0x20d8 (en: 'ring overlay embellishment', google translation) + - "⃙": [T: "ring med klokken"] # 0x20d9 (en: 'clockwise ring overlay embellishment', google translation) + - "⃚": [T: "ring mot klokken"] # 0x20da (en: 'anticlockwise ring overlay embellishment', google translation) + - "⃛": [T: "trippel prikk"] # 0x20db (en: 'triple dot', google: 'triple dot') + - "⃜": [T: "fire prikker"] # 0x20dc (en: 'quadruple dot', google: 'fyrdubbla prick') + - "⃝": [T: "i sirkel"] # 0x20dd (en: 'enclosing circle embellishment', google translation) + - "⃞": [T: "i firkant"] # 0x20de (en: 'enclosing square embellishment', google translation) + - "⃟": [T: "i diamant"] # 0x20df (en: 'enclosing diamond embellishment', google translation) + - "⃠": [T: "i sirkel med omvendt skråstrek"] # 0x20e0 (en: 'enclosing circle backslash embellishment', google translation) + - "⃡": [T: "venstre-høyre-pil"] # 0x20e1 (en: 'left right arrow above embellishment', google: 'vänster höger pil över utsmyckningen') + - "⃢": [T: "omsluttende skjerm"] # 0x20e2 (en: 'enclosing screen embellishment', google translation) + - "⃣": [T: "omsluttende tastehette"] # 0x20e3 (en: 'enclosing keycap embellishment', google translation) + - "⃤": [T: "i oppoverpekende trekant"] # 0x20e4 (en: 'enclosing upward pointing triangle embellishment', google translation) + - "⃥": [T: "omvendt skråstrek"] # 0x20e5 (en: 'reverse solidus overlay embellishment', google translation) + - "⃦": [T: "dobbel loddrett strek"] # 0x20e6 (en: 'double verticle stroke embellishment', google translation) + - "⃧": [T: "livrentesymbol"] # 0x20e7 (en: 'annuity symbol embellishment', google translation) + - "⃨": [T: "trippel prikk"] # 0x20e8 (en: 'triple underdot', google translation) + - "⃩": [T: "bred bro"] # 0x20e9 (en: 'wide bridge above embellishment', google translation) + - "⃪": [T: "venstrepil"] # 0x20ea (en: 'leftwards arrow overlay embellishment', google translation) + - "⃫": [T: "lang dobbel skråstrek"] # 0x20eb (en: 'long double solidus overlay embellishment', google translation) + - "⃬": [T: "høyre-harpun mothake ned"] # 0x20ec (en: 'rightwards harpoon with barb downwards embellishment', google translation) + - "⃭": [T: "venstre-harpun mothake ned"] # 0x20ed (en: 'leftwards harpoon with barb downwards embellishment', google translation) + - "⃮": [T: "venstrepil under"] # 0x20ee (en: 'left arrow below embellishment', google translation) + - "⃯": [T: "høyrepil under"] # 0x20ef (en: 'right arrow below embellishment', google translation) + - "⃰": [T: "asterisk"] # 0x20f0 (en: 'asterisk above embellishment', google translation) + #----------------------------------------------------------------------------------------------------- + #Letterlike Symbols OK + - "℄": [T: "midtlinjesymbol"] # 0x2104 (google translation) + - "℅": [T: "care of"] # 0x2105 (google: 'bry sig om') + - "℆": [T: "cada una"] # 0x2106 (google translation) + - "ℇ": [T: "eulers konstant"] # 0x2107 (en: 'euler's constant', google: 'eulers konstant') + - "℈": [T: "scruple"] # 0x2108 (en: 'scruples', google translation) + - "℉": [T: "grader fahrenheit"] # 0x2109 (en: 'degrees fahrenheit') + - "ℊ": [T: "script font g"] # 0x210a (en: 'script g') + - "ℌℑℨℭ": # 0x210c, 0x2111, 0x2128, 0x212d + - T: "fraktur" # (en: 'fraktur', google: 'fraktur') + - SPELL: "translate('.', 'ℌℑℨℭ', 'HIZC')" + + - "ℍℙℾℿ": # 0x210d, 0x2119, 0x213e, 0x213f + - T: "dobbeltstreket" # (en: 'double struck', google translation) + - SPELL: "translate('.', 'ℍℙℾℿ', 'HPΓΠ')" + + - "ℎ": [T: "plancks konstant"] # 0x210e + - "ℏ": [T: "h strek"] # 0x210f + # SWEDISH: finns bara ett sätt att säga h strek + + - "ℐℒ℘ℬℰℱℳ": # 0x2110, 0x2112, 0x2118, 0x2130, 0x2131, 0x2133 + - T: "script font" # (en: 'script') + - SPELL: "translate('.', 'ℐℒ℘ℬℰℱℳ', 'ILPBEFM')" + + - "℔": [T: "pund"] # 0x2114 (en: 'pounds', google: 'pund') + - "№": [T: "numero"] # 0x2116 (en: 'number') + - "℥": [T: "ounce"] # 0x2125 (en: 'ounces') + - "Ω": [T: "ohm"] # 0x2126 (en: 'ohms') + - "℧": [T: "mho"] # 0x2127 (en: 'mhos') + - "℩": [T: "rotert iota"] # 0x2129 (en: 'turned iota', google: 'vände iota') + - "Å": [T: "ångstrøm"] # 0x212b + - "ℯ": [T: "script font e"] # 0x212f (en: 'script e') + + # coalesced some chars that use cap letters + - "Ⅎ℺⅁⅂⅃⅄": # 0x2132, 0x213a, 0x2141, 0x2142, 0x2143, 0x2144 + - test: + - if: "'.' = '℺'" + then: [T: "rotert"] # (en: 'rotated', google translation) + - else_if: "'.' = 'Ⅎ'" + then: [T: "rotert"] # (en: 'turned', google translation) + - else_if: "'.' = '⅃'" + then: [T: "omvendt sans-serif"] # (en: 'reversed sans-serif', google translation) + else: [T: "rotert sans-serif"] # (en: 'turned sans-serif', google: 'vände sans-serif') + - SPELL: "translate('.', 'Ⅎ℺⅁⅂⅃⅄', 'FQGLLY')" + + - "ℴ": [T: "script font o"] # 0x2134 (en: 'script o') + - "ℵ": [T: "alef"] # 0x2135 (en: 'first transfinite cardinal') + - "ℶ": [T: "bet"] # 0x2136 (en: 'second transfinite cardinal') + - "ℷ": [T: "gimel"] # 0x2137 (en: 'third transfinite cardinal') + - "ℸ": [T: "dalet"] # 0x2138 (en: 'fourth transfinite cardinal') + - "ℼ": [T: "dobbeltstreket pi"] # 0x213c (en: 'double struck pi', google: 'dobbelslaget pi') + - "ℽ": [T: "dobbeltstreket gamma"] # 0x213d (en: 'double struck gamma', google: 'dobbelslaget gamma') + - "⅀": [T: "dobbeltstreket summetegn"] # 0x2140 (en: 'double struck n-ary summation', google: 'dubbelslaget n-ary-sammanfattning') + - "⅋": [T: "rotert og-tegn"] # 0x214b (en: 'turned ampersand', google: 'vände ampersand') + - "⅌": [T: "per"] # 0x214c (en: 'per', google: 'per') + - "ⅎ": [T: "rotert f"] # 0x214e (en: 'turned F', google: 'vände f') + #-------------------------------------------------------------------------------------------------------------- + #Number formats OK + - "¼": [T: "én fjerdedel"] # 0x00bc + - "½": [T: "én halv"] # 0x00bd + - "¾": [T: "tre fjerdedeler"] # 0x00be + - "⅐": [T: "én sjudel"] # 0x2150 (en: 'one seventh', google: 'en sjunde') + - "⅑": [T: "én nidel"] # 0x2151 (en: 'one ninth', google: 'en nionde') + - "⅒": [T: "én tidel"] # 0x2152 (en: 'one tenth') + - "⅓": [T: "én tredjedel"] # 0x2153 (en: 'one third') + - "⅔": [T: "to tredjedeler"] # 0x2154 (en: 'two thirds') + - "⅕": [T: "én femtedel"] # 0x2155 (en: 'one fifth') + - "⅖": [T: "to femtedeler"] # 0x2156 (en: 'two fifths') + - "⅗": [T: "tre femtedeler"] # 0x2157 (en: 'three fifths') + - "⅘": [T: "fire femtedeler"] # 0x2158 (en: 'four fifths') + - "⅙": [T: "én sjettedel"] # 0x2159 (en: 'one sixth') + - "⅚": [T: "fem sjettedeler"] # 0x215a (en: 'five sixths') + - "⅛": [T: "én åttedel"] # 0x215b (en: 'one eighth') + - "⅜": [T: "tre åttedeler"] # 0x215c (en: 'three eighths') + - "⅝": [T: "fem åttedeler"] # 0x215d (en: 'five eighths') + - "⅞": [T: "sju åttedeler"] # 0x215e (en: 'seven eighths') + - "⅟": [T: "én over"] # 0x215f (en: 'one over', google: 'en över') + - "Ⅰ": [T: "i"] # 0x2160 (en: 'I', google translation) + - "Ⅱ": [T: "i i"] # 0x2161 (en: 'I I', google translation) + - "Ⅲ": [T: "i i i"] # 0x2162 (en: 'I I I', google translation) + - "Ⅳ": [T: "i v"] # 0x2163 (en: 'I V', google translation) + - "Ⅴ": [T: "v"] # 0x2164 (en: 'V', google translation) + - "Ⅵ": [T: "v i"] # 0x2165 (en: 'V I', google translation) + - "Ⅶ": [T: "v i i"] # 0x2166 (en: 'V I I', google translation) + - "Ⅷ": [T: "v i i i"] # 0x2167 (en: 'V I I I', google translation) + - "Ⅸ": [T: "i x"] # 0x2168 (en: 'I X', google translation) + - "Ⅹ": [T: "x"] # 0x2169 (en: 'X', google translation) + - "Ⅺ": [T: "x i"] # 0x216a (en: 'X I', google translation) + - "Ⅻ": [T: "x i i"] # 0x216b (en: 'X I I', google translation) + - "Ⅼ": [T: "l"] # 0x216c (en: 'L', google translation) + - "Ⅽ": [T: "c"] # 0x216d (en: 'C', google translation) + - "Ⅾ": [T: "d"] # 0x216e (en: 'D', google translation) + - "Ⅿ": [T: "m"] # 0x216f (en: 'M', google translation) + - "ⅰ": [T: "i"] # 0x2170 (en: 'I', google translation) + - "ⅱ": [T: "i i"] # 0x2171 (en: 'I I', google translation) + - "ⅲ": [T: "i i i"] # 0x2172 (en: 'I I I', google translation) + - "ⅳ": [T: "i v"] # 0x2173 (en: 'I V', google translation) + - "ⅴ": [T: "v"] # 0x2174 (en: 'V', google translation) + - "ⅵ": [T: "v i"] # 0x2175 (en: 'V I', google translation) + - "ⅶ": [T: "v i i"] # 0x2176 (en: 'V I I', google translation) + - "ⅷ": [T: "v i i i"] # 0x2177 (en: 'V I I I', google translation) + - "ⅸ": [T: "i x"] # 0x2178 (en: 'I X', google translation) + - "ⅹ": [T: "x"] # 0x2179 (en: 'X', google translation) + - "ⅺ": [T: "x i"] # 0x217a (en: 'X I', google translation) + - "ⅻ": [T: "x i i"] # 0x217b (en: 'X I I', google translation) + - "ⅼ": [T: "l"] # 0x217c (en: 'L', google translation) + - "ⅽ": [T: "c"] # 0x217d (en: 'C', google translation) + - "ⅾ": [T: "d"] # 0x217e (en: 'D', google translation) + - "ⅿ": [T: "m"] # 0x217f (en: 'M', google translation) + - "↉": [T: "null tredjedeler"] # 0x2189 (en: 'zero thirds') + #----------------------------------------------------------------------------------------------------- + #Arrows OK + - "←": [T: "venstrepil"] # 0x2190 (en: 'leftwards arrow') + - "↑": [T: "oppoverpil"] # 0x2191 (en: 'upwards arrow') + - "↓": [T: "nedoverpil"] # 0x2193 (en: 'downwards arrow') + - "↔": [T: "venstre-høyre-pil"] # 0x2194 (en: 'left right arrow') + - "↕": [T: "opp-ned-pil"] # 0x2195 (en: 'up down arrow') + - "↖": [T: "nordvest-pil"] # 0x2196 (en: 'north west arrow') + - "↗": # 0x2197 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "går fra venstre mot"] # (en: 'approaches from below', google translation) + else: [T: "nordøst-pil"] # (en: 'north east arrow') + + - "↘": # 0x2198 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "går fra høyre mot"] # (en: 'approaches from above', google translation) + else: [T: "sørøst-pil"] # (en: 'south east arrow') + + - "↙": [T: "sørvest-pil"] # 0x2199 (en: 'south west arrow') + - "↚": [T: "overstrøket venstrepil"] # 0x219a (en: 'leftwards arrow with stroke') + - "↛": [T: "overstrøket høyrepil"] # 0x219b (en: 'rightwards arrow with stroke') + - "↜": [T: "bølget venstrepil"] # 0x219c (en: 'leftwards wave arrow') + - "↝": [T: "bølget høyrepil"] # 0x219d (en: 'rightwards wave arrow') + - "↞": [T: "venstrepil med to spisser"] # 0x219e (en: 'leftwards two headed arrow') + - "↟": [T: "oppoverpil med to spisser"] # 0x219f (en: 'upwards two headed arrow') + - "↠": [T: "høyrepil med to spisser"] # 0x21a0 (en: 'rightwards two headed arrow') + - "↡": [T: "nedoverpil med to spisser"] # 0x21a1 (en: 'downwards two headed arrow') + - "↢": [T: "venstrepil med hale"] # 0x21a2 (en: 'leftwards arrow with tail') + - "↣": [T: "høyrepil med hale"] # 0x21a3 (en: 'rightwards arrow with tail') + - "↤": [T: "venstrepil fra strek"] # 0x21a4 (en: 'leftwards arrow from bar') + - "↥": [T: "oppoverpil fra strek"] # 0x21a5 (en: 'upwards arrow from bar') + - "↦": [T: "høyrepil fra strek"] # 0x21a6 (en: 'rightwards arrow from bar') + - "↧": [T: "nedoverpil fra strek"] # 0x21a7 (en: 'downwards arrow from bar') + - "↨": [T: "opp-ned-pil med base"] # 0x21a8 (en: 'up down arrow with base') + - "↩": [T: "venstrepil med krok"] # 0x21a9 (en: 'leftwards arrow with hook') + - "↪": [T: "høyrepil med krok"] # 0x21aa (en: 'rightwards arrow with hook') + - "↫": [T: "venstrepil med løkke"] # 0x21ab (en: 'leftwards arrow with loop') + - "↬": [T: "høyrepil med løkke"] # 0x21ac (en: 'rightwards arrow with loop') + - "↭": [T: "bølget venstre-høyre-pil"] # 0x21ad (en: 'left right wave arrow') + - "↮": [T: "overstrøket venstre-høyre-pil"] # 0x21ae (en: 'left right arrow with stroke') + - "↯": [T: "sikksakk nedoverpil"] # 0x21af (en: 'downwards zigzag arrow') + - "↰": [T: "oppoverpil med spissen mot venstre"] # 0x21b0 (en: 'upwards arrow with tip leftwards') + - "↱": [T: "oppoverpil med spissen mot høyre"] # 0x21b1 (en: 'upwards arrow with tip rightwards') + - "↲": [T: "nedoverpil med spissen mot venstre"] # 0x21b2 (en: 'downwards arrow with tip leftwards') + - "↳": [T: "nedoverpil med spissen mot høyre"] # 0x21b3 (en: 'downwards arrow with tip rightwards') + - "↴": [T: "høyrepil med hjørnet ned"] # 0x21b4 (en: 'rightwards arrow with corner downwards') + - "↵": [T: "nedoverpil med hjørnet mot venstre"] # 0x21b5 (en: 'downwards arrow with corner leftwards') + - "↶": [T: "øvre halvsirkelpil mot klokken"] # 0x21b6 (en: 'anticlockwise top semicircle arrow') + - "↷": [T: "øvre halvsirkelpil med klokken"] # 0x21b7 (en: 'clockwise top semicircle arrow') + - "↸": [T: "nordvest-pil mot strek"] # 0x21b8 (en: 'north west arrow to long bar') + - "↹": [T: "venstrepil mot strek over høyrepil mot strek"] # 0x21b9 (en: 'leftwards arrow to bar over rightwards arrow to bar') + - "↺": [T: "åpen sirkelpil mot klokken"] # 0x21ba (en: 'anticlockwise open circle arrow') + - "↻": [T: "åpen sirkelpil med klokken"] # 0x21bb (en: 'clockwise open circle arrow') + - "↼": [T: "venstre-harpun mothake opp"] # 0x21bc (en: 'left harpoon up') + - "↽": [T: "venstre-harpun mothake ned"] # 0x21bd (en: 'left harpoon down') + - "↾": [T: "opp-harpun mothake høyre"] # 0x21be (en: 'up harpoon right') + - "↿": [T: "opp-harpun mothake venstre"] # 0x21bf (en: 'up harpoon left') + - "⇀": [T: "høyre-harpun mothake opp"] # 0x21c0 (en: 'right harpoon up') + - "⇁": [T: "høyre-harpun mothake ned"] # 0x21c1 (en: 'right harpoon down') + - "⇂": [T: "ned-harpun mothake høyre"] # 0x21c2 (en: 'down harpoon right') + - "⇃": [T: "ned-harpun mothake venstre"] # 0x21c3 (en: 'down harpoon left') + - "⇄": [T: "høyrepil over venstrepil"] # 0x21c4 (en: 'rightwards arrow over leftwards arrow') + - "⇅": [T: "oppoverpil til venstre for nedoverpil"] # 0x21c5 (en: 'upwards arrow leftwards of downwards arrow') + - "⇆": [T: "venstrepil over høyrepil"] # 0x21c6 (en: 'leftwards arrow over rightwards arrow') + - "⇇": [T: "to venstrepiler"] # 0x21c7 (en: 'leftwards paired arrows') + - "⇈": [T: "to oppoverpiler"] # 0x21c8 (en: 'upwards paired arrows') + - "⇉": [T: "to høyrepiler"] # 0x21c9 (en: 'rightwards paired arrows') + - "⇊": [T: "to nedoverpiler"] # 0x21ca (en: 'downwards paired arrows') + - "⇋": [T: "venstre-harpun over høyre-harpun"] # 0x21cb (en: 'left harpoon over right harpoon') + - "⇌": [T: "høyre-harpun over venstre-harpun"] # 0x21cc (en: 'right harpoon over left harpoon') + - "⇍": [T: "overstrøket dobbeltstreket venstrepil"] # 0x21cd (en: 'leftwards double arrow with stroke') + - "⇎": [T: "overstrøket dobbeltstreket venstre-høyre-pil"] # 0x21ce (en: 'left right double arrow with stroke') + - "⇏": [T: "overstrøket dobbeltstreket høyrepil"] # 0x21cf (en: 'rightwards double arrow with stroke') + - "⇐": [T: "dobbeltstreket venstrepil"] # 0x21d0 (en: 'leftwards double arrow') + - "⇑": [T: "dobbeltstreket oppoverpil"] # 0x21d1 (en: 'upwards double arrow') + - "⇒": [T: "impliserer"] # 0x21d2 (en: 'rightwards double arrow') + - "⇓": [T: "dobbeltstreket nedoverpil"] # 0x21d3 (en: 'downwards double arrow') + - "⇔": [T: "er ekvivalent med"] # 0x21d4 (en: 'left right double arrow') + - "⇕": [T: "dobbeltstreket opp-ned-pil"] # 0x21d5 (en: 'up down double arrow') + - "⇖": [T: "dobbeltstreket nordvest-pil"] # 0x21d6 (en: 'north west double arrow') + - "⇗": [T: "dobbeltstreket nordøst-pil"] # 0x21d7 (en: 'north east double arrow') + - "⇘": [T: "dobbeltstreket sørøst-pil"] # 0x21d8 (en: 'south east double arrow') + - "⇙": [T: "dobbeltstreket sørvest-pil"] # 0x21d9 (en: 'south west double arrow') + - "⇚": [T: "trippelstreket venstrepil"] # 0x21da (en: 'leftwards triple arrow') + - "⇛": [T: "trippelstreket høyrepil"] # 0x21db (en: 'rightwards triple arrow') + - "⇜": [T: "slingrete venstrepil"] # 0x21dc (en: 'leftwards squiggle arrow') + - "⇝": [T: "slingrete høyrepil"] # 0x21dd (en: 'rightwards squiggle arrow') + - "⇞": [T: "oppoverpil med dobbel horisontal strek"] # 0x21de (en: 'upwards arrow with double stroke') + - "⇟": [T: "nedoverpil med dobbel horisontal strek"] # 0x21df (en: 'downwards arrow with double stroke') + - "⇠": [T: "stiplet venstrepil"] # 0x21e0 (en: 'leftwards dashed arrow') + - "⇡": [T: "stiplet oppoverpil"] # 0x21e1 (en: 'upwards dashed arrow') + - "⇢": [T: "stiplet høyrepil"] # 0x21e2 (en: 'rightwards dashed arrow') + - "⇣": [T: "stiplet nedoverpil"] # 0x21e3 (en: 'downwards dashed arrow') + - "⇤": [T: "venstrepil mot strek"] # 0x21e4 (en: 'leftwards arrow to bar') + - "⇥": [T: "høyrepil mot strek"] # 0x21e5 (en: 'rightwards arrow to bar') + - "⇦": [T: "hvit venstrepil"] # 0x21e6 (en: 'leftwards white arrow') + - "⇧": [T: "hvit oppoverpil"] # 0x21e7 (en: 'upwards white arrow') + - "⇨": [T: "hvit høyrepil"] # 0x21e8 (en: 'rightwards white arrow') + - "⇩": [T: "hvit nedoverpil"] # 0x21e9 (en: 'downwards white arrow') + - "⇪": [T: "hvit oppoverpil fra strek"] # 0x21ea (en: 'upwards white arrow from bar') + - "⇫": [T: "hvit oppoverpil på sokkel"] # 0x21eb (en: 'upwards white arrow on pedestal', google: 'uppåt vit pil på piedestal') + - "⇬": [T: "hvit oppoverpil på sokkel med horisontal strek"] # 0x21ec (en: 'upwards white arrow on pedestal with horizontal bar', google: 'uppåt vit pil på piedestal med horisontell stång') + - "⇭": [T: "hvit oppoverpil på sokkel med vertikal strek"] # 0x21ed (en: 'upwards white arrow on pedestal with vertical bar', google: 'uppåt vit pil på piedestal med vertikal bar') + - "⇮": [T: "hvit dobbel oppoverpil"] # 0x21ee (en: 'upwards white double arrow', google: 'uppåt vit dubbelpil') + - "⇯": [T: "hvit dobbel oppoverpil på sokkel"] # 0x21ef (en: 'upwards white double arrow on pedestal', google: 'uppåt vit dubbelpil på piedestal') + - "⇰": [T: "hvit høyrepil fra vegg"] # 0x21f0 (en: 'rightwards white arrow from wall', google: 'åtgärder vit pil från vägg') + - "⇱": [T: "nordvest-pil mot hjørne"] # 0x21f1 (en: 'north west arrow to corner', google: 'north west arrow till hörnet') + - "⇲": [T: "sørøst-pil mot hjørne"] # 0x21f2 (en: 'south east arrow to corner', google: 'south east arrow till corner') + - "⇳": [T: "hvit opp-ned-pil"] # 0x21f3 (en: 'up down white arrow', google: 'upp ner white arrow') + - "⇴": [T: "høyrepil med liten sirkel"] # 0x21f4 (en: 'right arrow with small circle') + - "⇵": [T: "nedoverpil til venstre for oppoverpil"] # 0x21f5 (en: 'downwards arrow leftwards of upwards arrow') + - "⇶": [T: "tre høyrepiler"] # 0x21f6 (en: 'three rightwards arrows', google: 'tre pilar med höger') + - "⇷": [T: "venstrepil med vertikal strek"] # 0x21f7 (en: 'leftwards arrow with vertical stroke', google: 'vänster pil med lodslag') + - "⇸": [T: "høyrepil med vertikal strek"] # 0x21f8 (en: 'rightwards arrow with vertical stroke', google: 'åtgärdspil med vertikal stroke') + - "⇹": [T: "venstre-høyre-pil med vertikal strek"] # 0x21f9 (en: 'left right arrow with vertical stroke', google: 'vänster höger pil med vertikalt slag') + - "⇺": [T: "venstrepil med dobbel vertikal strek"] # 0x21fa (en: 'leftwards arrow with double vertical stroke', google: 'vänster pil med dubbel vertikal stroke') + - "⇻": [T: "høyrepil med dobbel vertikal strek"] # 0x21fb (en: 'rightwards arrow with double vertical stroke', google: 'åtgärdspil med dubbel vertikal stroke') + - "⇼": [T: "venstre-høyre-pil med dobbel vertikal strek"] # 0x21fc (en: 'left right arrow with double vertical stroke', google: 'vänster höger pil med dubbel vertikal stroke') + - "⇽": [T: "venstrepil med åpen spiss"] # 0x21fd (en: 'leftwards open headed arrow') + - "⇾": [T: "høyrepil med åpen spiss"] # 0x21fe (en: 'rightwards open headed arrow') + - "⇿": [T: "venstre-høyre-pil med åpen spiss"] # 0x21ff (en: 'left right open headed arrow') + #---------------------------------------------------------------------------------------------------------------- + #Mathematical operators OK + - "∀": [T: "for alle"] # 0x2200 (en: 'for all') + - "∁": # 0x2201 # audit-ignore + - T: "komplementet til" # (en: 'complement of') + - "∃": [T: "det eksisterer"] # 0x2203 (en: 'there exists') + - "∄": [T: "det eksisterer ikke"] # 0x2204 (en: 'there does not exist') + - "∅": [T: "den tomme mengden"] # 0x2205 (en: 'empty set') + - "∇": [T: "nabla"] # 0x2207 (en: 'gradient of', google: 'lutning av') + - "∋": [T: "inneholder elementet"] # 0x220b (en: 'contains the member') + - "∌": [T: "inneholder ikke elementet"] # 0x220c (en: 'does not contain the member') + - "∍": [T: "inneholder elementet"] # 0x220d (en: 'contains the member') + - "∎": [T: "som skulle bevises"] # 0x220e (en: 'end of proof') + - "∏": [T: "produktet"] # 0x220f (en: 'product') + - "∐": [T: "koproduktet"] # 0x2210 (en: 'coproduct', MathPlayer: 'coproduct', google: 'coprodukt') + - "∑": [T: "sum"] # 0x2211 (en: 'sum') + - "−": [T: "minus"] # 0x2212 + - "∓": [T: "minus pluss"] # 0x2213 (en: 'minus or plus') + - "∔": [T: "prikk pluss"] # 0x2214 (en: 'dot plus') + - "∕": [T: "delt på"] # 0x2215 (en: 'divided by') + - "∖": [T: "minus"] # 0x2216 (en: 'set minus') + - "∗": [T: "ganger"] # 0x2217 (en: 'times') + - "∘": [T: "sammensatt med"] # 0x2218 (en: 'composed with') + - "∙": # 0x2219 + - test: + if: "@data-chem-formula-op" + then: [T: "ganger"] # (en: 'dot', google translation) + else: [T: "ganger"] # (en: 'times') + + - "∛": # 0x221b # audit-ignore + - T: "kubikkroten av" # (en: 'cube root of') + - "∜": # 0x221c # audit-ignore + - T: "fjerderoten av" # (en: 'fourth root of') + - "∞": [T: "uendelig"] # 0x221e (en: 'infinity') + - "∟": [T: "rett vinkel"] # 0x221f (en: 'right angle') + - "∠": [T: "vinkel"] # 0x2220 (en: 'angle') + - "∡": [T: "målt vinkel"] # 0x2221 (en: 'measured angle') + - "∢": [T: "sfærisk vinkel"] # 0x2222 (en: 'spherical angle') + - "∣": [T: "deler"] # 0x2223 (en: 'divides') + - "∤": [T: "deler ikke"] # 0x2224 (en: 'does not divide') + - "∧": [T: "og"] # 0x2227 (en: 'and') + - "∨": [T: "eller"] # 0x2228 (en: 'or') + - "∩": [T: "snitt"] # 0x2229 (en: 'intersection') + - "∪": [T: "union"] # 0x222a + - "∫": [T: "integralet"] # 0x222b + - "∬": [T: "dobbeltintegralet"] # 0x222c (en: 'double integral') + - "∭": [T: "trippelintegralet"] # 0x222d (en: 'triple integral') + - "∮": [T: "kurveintegralet"] # 0x222e (en: 'contour integral') + - "∯": [T: "flateintegralet"] # 0x222f (en: 'surface integral') + - "∰": [T: "volumintegralet"] # 0x2230 (en: 'volume integral') + - "∱": [T: "integralet med klokken"] # 0x2231 (en: 'clockwise integral', MathPlayer: 'clockwise integral', google: 'medurs integrerad') + - "∲": [T: "kurveintegralet med klokken"] # 0x2232 (en: 'clockwise contour integral', MathPlayer: 'clockwise contour integral (arrow on höger)', google: 'medurs konturintegral') + - "∳": [T: "kurveintegralet mot klokken"] # 0x2233 (en: 'anticlockwise contour integral', MathPlayer: 'anticlockwise contour integral', google: 'antikvis konturintegral') + - "∴": [T: "derfor"] # 0x2234 (en: 'therefore') + - "∵": [T: "ettersom"] # 0x2235 (en: 'because') + - "∶": # 0x2236 # audit-ignore + - T: "til" # (en: 'to') + - "∷": [T: "som"] # 0x2237 (en: 'as', MathPlayer: 'proportion', google: 'som') + - "∸": [T: "prikk minus"] # 0x2238 (en: 'dot minus') + - "∹": [T: "har overskudd sammenlignet med"] # 0x2239 (en: 'has excess compared to', MathPlayer: 'excess', google: 'har överskott jämfört med') + - "∺": # 0x223a + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "geometrisk proporsjonal med" # (en: 'geometrically proportional to') + - "∻": # 0x223b + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "homotetisk til" # (en: 'homothetic to', MathPlayer: 'homothetic', google: 'homotetisk till') + - "∽": [T: "omvendt tilde"] # 0x223d (en: 'reversed tilde') + - "∾": # 0x223e # audit-ignore + - T: "omvendt langstrakt s" # (en: 'most positive', MathPlayer: 'inverted lazy s', google: 'mest positiva') + - "∿": [T: "sinuskurve"] # 0x223f (en: 'sine wave') + - "≀": [T: "kransprodukt"] # 0x2240 (en: 'wreath product') + - "≁": # 0x2241 (en: 'not tilde') # audit-ignore + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "ikke proporsjonal med" + - "≂": [T: "minus tilde"] # 0x2242 (SRE: 'minus och tilde') + - "≃": # 0x2243 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "asymptotisk lik" # (en: 'asymptotically equal to', MathPlayer: 'asymptotically lika med', google: 'asymptotisk lik') + - "≄": # 0x2244 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "ikke asymptotisk lik" # (en: 'not asymptotically equal to', MathPlayer: 'inte asymptotically lika med', google: 'ikke asymptotisk lik') + - "≅": # 0x2245 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "tilnærmet lik" # (en: 'approximately equal to', MathPlayer: 'approximativt lika med', google: 'omtrent lik') + - "≆": # 0x2246 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "tilnærmet men faktisk ikke lik" # (en: 'approximately but not actually equal to', MathPlayer: 'approximativt men inte faktiskt lika med', google: 'omtrentlig men faktisk ikke lik') + - "≇": # 0x2247 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "verken tilnærmet eller faktisk lik" # (en: 'neither approximately nor actually equal to', MathPlayer: 'varken approximativt eller fakiskt lika med', google: 'varken ungefär eller faktiskt lika med') + - "≈": # 0x2248 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "tilnærmet lik" # (en: 'almost equal to', SRE: 'är nästan lika med') + - "≉": # 0x2249 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "ikke tilnærmet lik" # (en: 'not almost equal to', SRE: 'är inte nästan lika med') + - "≊": # 0x224a + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "tilnærmet lik eller lik" # (en: 'almost equal or equal to', SRE: 'är nästan lika eller lika med') + - "≋": [T: "trippel tilde"] # 0x224b (en: 'triple tilde') + - "≌": [T: "er alle like med"] # 0x224c (en: 'are all equal to', MathPlayer: 'alla lika med') + - "≍": # 0x224d + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ekvivalent med" # (en: 'equivalent to') + - "≎": # 0x224e + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "geometrisk ekvivalent med" # (en: 'geometrically equivalent to', MathPlayer: 'geometriskt lika med', google: 'geometriskt motsvarande') + - "≏": # 0x224f # audit-ignore + - T: "differansen mellom" # (en: 'difference between') + - "≐": [T: "nærmer seg grenseverdien"] # 0x2250 (en: 'approaches the limit') + - "≑": # 0x2251 # audit-ignore + - T: "geometrisk lik" # (en: 'geometrically equal to', SRE: 'är geometriskt lika med') + - "≒": # 0x2252 # audit-ignore + - T: "tilnærmet lik" # (en: 'approximately equal to or the image of', MathPlayer: 'uppskattningsvis lika med eller i likhet med', google: 'ungefär lika med eller bilden av') + - "≓": # 0x2253 # audit-ignore + - T: "tilnærmet lik" # (en: 'image of or approximately equal to', MathPlayer: 'i likhet med eller uppskattningsvis lika med', google: 'bild av eller ungefär lika med') + - "≔": [T: "definert som"] # 0x2254 (en: 'colon equals', MathPlayer: 'kolon lika med', google: 'kolon är lika med') + - "≕": [T: "lik kolon"] # 0x2255 (en: 'equals colon', MathPlayer: 'lika med kolon') + - "≖": [T: "ring i likhetstegn"] # 0x2256 (en: 'ring in equal to', SRE: 'är ring i lika med') + - "≗": # 0x2257 # audit-ignore + - T: "ring likhetstegn" # (en: 'approximately equal to') + - "≘": [T: "tilsvarer"] # 0x2258 (en: 'corresponds to') + - "≙": [T: "anslår"] # 0x2259 (en: 'estimates') + - "≚": # 0x225a + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "likevinklet med" # (en: 'equiangular to') + - "≛": [T: "stjerne lik"] # 0x225b (en: 'star equals') + # SWEDISH: misspelled delta to fix pronunciation + - "≜": [T: "delta lik"] # 0x225c (en: 'delta equals') + - "≝": [T: "er per definisjon lik"] # 0x225d (en: 'is defined to be') + - "≞": # 0x225e # audit-ignore + - T: "måles med" # (en: 'measured by') + - "≟": [T: "spørsmål ved likhet"] # 0x225f (en: 'has an unknown relationship with') + - "≢": # 0x2262 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke identisk med" # (en: 'not identical to') + - "≣": # 0x2263 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "strengt ekvivalent med" # (en: 'strictly equivalent to') + - "≨": # 0x2268 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "mindre enn men ikke lik" # (en: 'less than but not equal to') + - "≩": # 0x2269 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "større enn men ikke lik" # (en: 'greater than but not equal to') + - "≪": # 0x226a + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "mye mindre enn" # (en: 'much less than') + - "≫": # 0x226b + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "mye større enn" # (en: 'much greater than') + - "≬": # 0x226c + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "mellom" # (en: 'between') + - "≭": # 0x226d + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke ekvivalent med" # (en: 'not equivalent to') + - "≮": # 0x226e + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke mindre enn" # (en: 'not less than') + - "≯": # 0x226f + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke større enn" # (en: 'not greater than') + - "≰": # 0x2270 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verken mindre enn eller lik" # (en: 'neither less than nor equal to') + - "≱": # 0x2271 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verken større enn eller lik" # (en: 'neither greater than nor equal to') + - "≲": # 0x2272 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "mindre enn eller tilnærmet lik" # (en: 'less than or equivalent to') + - "≳": # 0x2273 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "større enn eller tilnærmet lik" # (en: 'greater than or equivalent to') + - "≴": # 0x2274 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verken mindre enn eller tilnærmet lik" # (en: 'neither less than nor equivalent to') + - "≵": # 0x2275 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verken større enn eller tilnærmet lik" # (en: 'neither greater than nor equivalent to') + - "≶": # 0x2276 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "mindre enn eller større enn" # (en: 'less than or greater than') + - "≷": # 0x2277 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "større enn eller mindre enn" # (en: 'greater than or less than') + - "≸": # 0x2278 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verken mindre enn eller større enn" # (en: 'neither less than nor greater than') + - "≹": # 0x2279 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verken større enn eller mindre enn" # (en: 'neither greater than nor less than') + - "≺": [T: "foregår"] # 0x227a (en: 'precedes') + - "≻": [T: "følger"] # 0x227b (en: 'succeeds') + - "≼": [T: "foregår eller er lik"] # 0x227c (en: 'precedes or is equal to') + - "≽": [T: "følger eller er lik"] # 0x227d (en: 'succeeds or is equal to') + - "≾": [T: "foregår eller er ekvivalent med"] # 0x227e (en: 'precedes or is equivalent to') + - "≿": [T: "følger eller er ekvivalent med"] # 0x227f (en: 'succeeds or is equivalent to') + - "⊀": [T: "foregår ikke"] # 0x2280 (en: 'does not precede') + - "⊁": [T: "følger ikke"] # 0x2281 (en: 'does not succeed') + - "⊈": # 0x2288 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verken en delmengde av eller lik" # (en: 'neither a subset of nor equal to') + - "⊉": # 0x2289 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verken en overmengde av eller lik" # (en: 'neither a superset of nor equal to') + - "⊊": # 0x228a (en: 'subset of with not equal to') # audit-ignore +# SWEDISH: added test + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] + - T: "ekte delmengde av" + - "⊋": # 0x228b (en: 'superset of with not equal to') # audit-ignore + # SWEDISH: added test + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] + - T: "ekte overmengde av" + - "⊌": [T: "multimengde"] # 0x228c (SRE: 'multimängd') + - "⊍": [T: "multimengde multiplikasjon"] # 0x228d (en: 'multiset multiplication') + - "⊎": [T: "multimengde union"] # 0x228e (SRE: 'multimängdunion') + - "⊏": [T: "kvadratisk bilde av"] # 0x228f (en: 'square image of', MathPlayer: 'square image of', google: 'fyrkantig bild av') + - "⊐": [T: "kvadratisk original av"] # 0x2290 (en: 'square original of', MathPlayer: 'square original of', google: 'fyrkantig original av') + - "⊑": [T: "kvadratisk bilde av eller lik"] # 0x2291 (en: 'square image of or equal to', MathPlayer: 'square image of or equal to', google: 'fyrkantig bild av eller lika med') + - "⊒": [T: "kvadratisk original av eller lik"] # 0x2292 (en: 'square original of or equal to', MathPlayer: 'square original of or equal to', google: 'fyrkantig original av eller lika med') + # SWEDISH: misspelled to fix pronunciation + - "⊓": [T: "kvadratisk snitt"] # 0x2293 (en: 'square cap') + - "⊔": [T: "kvadratisk union"] # 0x2294 (SRE: 'kvadratisk kopp') + - "⊕": [T: "direkte sum"] # 0x2295 (en: 'circled plus') + - "⊖": [T: "symmetrisk differanse"] # 0x2296 (en: 'circled minus') + - "⊗": [T: "tensorprodukt"] # 0x2297 (en: 'circled times') + - "⊘": [T: "divisjon i sirkel"] # 0x2298 (en: 'circled slash') + - "⊙": [T: "direkte produkt"] # 0x2299 (en: 'circled dot operator') + - "⊚": [T: "ring-operator i sirkel"] # 0x229a (en: 'circled ring') + - "⊛": [T: "asterisk-operator i sirkel"] # 0x229b (en: 'circled asterisk') + - "⊜": [T: "likhetstegn i sirkel"] # 0x229c (en: 'circled equals') + - "⊝": [T: "tankestrek i sirkel"] # 0x229d (en: 'circled dash') + - "⊞": [T: "plusstegn i kvadrat"] # 0x229e (en: 'squared plus') + - "⊟": [T: "minustegn i kvadrat"] # 0x229f (en: 'squared minus') + - "⊠": [T: "multiplikasjonstegn i kvadrat"] # 0x22a0 (en: 'squared times') + - "⊡": [T: "dot-operator i kvadrat"] # 0x22a1 (en: 'squared dot operator') + - "⊢": [T: "beviser"] # 0x22a2 (en: 'proves') + - "⊣": [T: "beviser ikke"] # 0x22a3 (en: 'does not yield') + - "⊤": [T: "topp"] # 0x22a4 (en: 'top') + - "⊥": # 0x22a5 # audit-ignore + - T: "bunn" # (en: 'bottom', MathPlayer: 'up tack', google: 'botten') + - "⊦": [T: "reduseres til"] # 0x22a6 (en: 'reduces to') + - "⊧": [T: "modellerer"] # 0x22a7 (en: 'models', MathPlayer: 'models') + - "⊨": # 0x22a8 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "sant" # (en: 'true') + - "⊩": [T: "tvinger"] # 0x22a9 (en: 'forces') + - "⊪": [T: "tre vertikale streker høyre dreiekors"] # 0x22aa (en: 'triple vertical bar right turnstile') + - "⊫": [T: "dobbel vertikal strek dobbelt høyre dreiekors"] # 0x22ab (en: 'double vertical bar double right turnstile') + - "⊬": [T: "beviser ikke"] # 0x22ac (en: 'does not prove') + - "⊭": # 0x22ad + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke sant" # (en: 'not true') + - "⊮": [T: "tvinger ikke"] # 0x22ae (en: 'does not force') + - "⊯": [T: "overstrøket dobbel vertikal strek dobbelt høyre dreiekors"] # 0x22af (en: 'negated double vertical bar double right turnstile') + - "⊰": [T: "foregår under relasjon"] # 0x22b0 (en: 'precedes under relation', MathPlayer: 'precedes under relation', google: 'går foran under relasjon') + - "⊱": [T: "følger under relasjon"] # 0x22b1 (en: 'succeeds under relation', MathPlayer: 'succeeds under relation', google: 'lyckas under relation') + - "⊲": # 0x22b2 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is', google translation) + - T: "normal undergruppe av" # (en: 'a normal subgroup of') + - "⊳": [T: "inneholder som normal undergruppe"] # 0x22b3 (en: 'contains as a normal subgroup') + - "⊴": # 0x22b4 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is', google translation) + - T: "normal undergruppe av eller lik" # (en: 'a normal subgroup of or equal to') + - "⊵": [T: "inneholder som normal undergruppe eller lik"] # 0x22b5 (en: 'contains as a normal subgroup or equal to') + - "⊶": # 0x22b6 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "definisjonsmengden til" # (en: 'the original of', MathPlayer: 'original of', google: 'originalet av') + - "⊷": # 0x22b7 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verdimengden til" # (en: 'an image of', MathPlayer: 'image of', google: 'en bild av') + - "⊸": [T: "multimap"] # 0x22b8 (SRE: 'multimatris') + - "⊹": [T: "hermitisk matrise"] # 0x22b9 (SRE: 'hermetisk konjugatmatris') + - "⊺": [T: "innskudd"] # 0x22ba (en: 'intercalate', MathPlayer: 'intercalate', google: 'interkalat') + - "⊻": [T: "eksklusiv eller"] # 0x22bb (en: 'xor') + - "⊼": [T: "ikke-og"] # 0x22bc (en: 'nand') + - "⊽": [T: "ikke-eller"] # 0x22bd (en: 'nor') + - "⊾": [T: "rett vinkel med bue"] # 0x22be (en: 'right angle with arc') + - "⊿": [T: "rettvinklet trekant"] # 0x22bf (en: 'right triangle') + - "⋀": [T: "logisk og"] # 0x22c0 (en: 'logical and') + - "⋁": [T: "logisk eller"] # 0x22c1 (en: 'logical or') + # SWEDISH: misspelled to fix pronunciation + - "⋂": [T: "snitt"] # 0x22c2 (en: 'intersection') + - "⋃": [T: "union"] # 0x22c3 + - "⋄": [T: "diamant-operator"] # 0x22c4 + - "⋅": # 0x22c5 + - test: + if: "@data-chem-formula-op" + then: [T: "ganger"] # (en: 'dot', google translation) + else: [T: "ganger"] # (en: 'times') + + - "⋆": [T: "stjerne"] # 0x22c6 (en: 'times') + - "⋇": [T: "divisjon ganger"] # 0x22c7 (en: 'division times') + - "⋈": [T: "naturlig join"] # 0x22c8 (en: 'bowtie', MathPlayer: 'bowtie') + - "⋉": # 0x22c9 # audit-ignore + - T: "venstre semi-join" # (en: 'the left normal factor semidirect product of') + - "⋊": # 0x22ca # audit-ignore + - T: "høyre semi-join" # (en: 'the right normal factor semidirect product of') + - "⋋": # 0x22cb # audit-ignore + - T: "venstre semi-direkte produkt" # (en: 'the left semidirect product of') + - "⋌": # 0x22cc # audit-ignore + - T: "høyre semi-direkte produkt" # (en: 'the right semidirect product of') + - "⋍": [T: "omvendt tilde likhetstegn"] # 0x22cd (en: 'reversed tilde equals') + - "⋎": [T: "krøllete logisk eller"] # 0x22ce + - "⋏": [T: "krøllete logisk og"] # 0x22cf (en: 'curly logical and') + - "⋐": # 0x22d0 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is', google translation) + - T: "dobbel delmengde av" # (en: 'a double subset of') + - "⋑": # 0x22d1 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is', google translation) + - T: "dobbel overmengde av" # (en: 'a double superset of') + - "⋒": # 0x22d2 # audit-ignore + - T: "det doble snittet av" # (en: 'double intersection of') + - "⋓": # 0x22d3 # audit-ignore + - T: "den doble unionen av" # (en: 'double union of') + - "⋔": # 0x22d4 # audit-ignore + - T: "det ekte snittet av" # (en: 'proper intersection of', MathPlayer: 'pitchfork', google: 'korrekt skärningspunkt av') + - "⋕": # 0x22d5 # audit-ignore + - T: "lik og parallell med" # (en: 'equal to and parallel to') + - "⋖": [T: "mindre enn med prikk"] # 0x22d6 (en: 'less than with dot') + - "⋗": [T: "større enn med prikk"] # 0x22d7 (en: 'greater than with dot') + - "⋘": # 0x22d8 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "veldig mye mindre enn" # (en: 'very much less than') + - "⋙": # 0x22d9 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "veldig mye større enn" # (en: 'very much greater than') + - "⋚": # 0x22da + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "mindre enn lik eller større enn" # (en: 'less than equal to or greater than') + - "⋛": # 0x22db + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "større enn lik eller mindre enn" # (en: 'greater than equal to or less than') + - "⋜": # 0x22dc + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "lik eller mindre enn" # (en: 'equal to or less than') + - "⋝": # 0x22dd + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "lik eller større enn" # (en: 'equal to or greater than') + - "⋞": # 0x22de + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "lik eller foregår" # (en: 'equal to or precedes') + - "⋟": # 0x22df + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "lik eller følger" # (en: 'equal to or succeeds') + - "⋠": [T: "verken foregår eller er lik"] # 0x22e0 (en: 'does not precede nor is equal to') + - "⋡": [T: "verken følger eller er lik"] # 0x22e1 (en: 'does not succeed nor is equal to') + - "⋢": [T: "verken et kvadratisk bilde av eller lik"] # 0x22e2 + - "⋣": [T: "verken kvadratisk original av eller lik"] # 0x22e3 + - "⋤": [T: "kvadratisk bilde av eller ikke lik"] # 0x22e4 + - "⋥": [T: "kvadratisk original av eller ikke lik"] # 0x22e5 + - "⋦": # 0x22e6 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "mindre enn men ikke ekvivalent med" # (en: 'less than but not equivalent to') + - "⋧": # 0x22e7 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "større enn men ikke ekvivalent med" # (en: 'greater than but not equivalent to') + - "⋨": [T: "foregår men er ikke ekvivalent med"] # 0x22e8 (en: 'precedes but is not equivalent to') + - "⋩": [T: "følger men er ikke ekvivalent med"] # 0x22e9 (en: 'succeeds but is not equivalent to') + - "⋪": # 0x22ea + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke en normal undergruppe av" # (en: 'not a normal subgroup of') + - "⋫": [T: "inneholder ikke som normal undergruppe"] # 0x22eb (en: 'does not contain as a normal subgroup') + - "⋬": # 0x22ec + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verken en normal undergruppe av eller lik" # (en: 'not a normal subgroup of nor is equal to') + - "⋭": [T: "verken inneholder som normal undergruppe eller er lik"] # 0x22ed (en: 'does not contain as a normal subgroup nor is equal to') + - "⋮": [T: "vertikal ellipse"] # 0x22ee (en: 'vertical ellipsis') + - "⋯": [T: "halvhøy horisontal ellipse"] # 0x22ef (en: 'dot dot dot') + - "⋰": [T: "diagonal ellipse oppover"] # 0x22f0 (en: 'upwards diagonal ellipsis') + - "⋱": [T: "diagonal ellipse nedover"] # 0x22f1 (en: 'diagonal ellipsis') + - "⋲": [T: "tilhører med lang horisontal strek"] # 0x22f2 (en: 'element of with long horizontal stroke') + - "⋳": [T: "tilhører med vertikal strek på slutten av horisontal strek"] # 0x22f3 (en: 'element of with vertical bar at end of horizontal stroke') + - "⋴": [T: "tilhører med vertikal strek på slutten av horisontal strek"] # 0x22f4 (en: 'element of with vertical bar at end of horizontal stroke') + - "⋵": [T: "tilhører med prikk over"] # 0x22f5 (en: 'element of with dot above') + - "⋶": [T: "tilhører med strek over"] # 0x22f6 (en: 'element of with overbar') + - "⋷": [T: "tilhører med strek over"] # 0x22f7 (en: 'element of with overbar', MathPlayer: 'element of or equal to', google: 'element av med överbar') + - "⋸": [T: "tilhører med strek under"] # 0x22f8 (en: 'element of with underbar') + - "⋹": [T: "tilhører med to horisontale streker"] # 0x22f9 (en: 'element of with two horizontal strokes') + - "⋺": [T: "inneholder med lang horisontal strek"] # 0x22fa (en: 'contains with long horizontal stroke') + - "⋻": [T: "inneholder med vertikal strek på slutten av horisontal strek"] # 0x22fb (en: 'contains with vertical bar at end of horizontal stroke') + - "⋼": [T: "inneholder med vertikal strek på slutten av horisontal strek"] # 0x22fc (en: 'contains with vertical bar at end of horizontal stroke') + - "⋽": [T: "inneholder med strek over"] # 0x22fd (en: 'contains with overbar', MathPlayer: 'contains or equal to', google: 'innehåller med overbar') + - "⋾": [T: "inneholder med strek over"] # 0x22fe (en: 'contains with overbar') + - "⋿": [T: "tilhører ifølge z-notation"] # 0x22ff (en: 'z notation bag membership', MathPlayer: 'z notation bag membership', google: 'z medlemskap för notation bag') + #------------------------------------------------------------------------------------------------------------- + #Miscellaneous Technical OK + - "⌀": [T: "diameter"] # 0x2300 + - "⌁": [T: "elektrisk pil"] # 0x2301 (en: 'electric arrow') + - "⌂": [T: "hus"] # 0x2302 (en: 'house') + - "⌃": [T: "pilspiss opp"] # 0x2303 (en: 'up arrowhead', google: 'upp pilspetsen') + - "⌄": [T: "pilspiss ned"] # 0x2304 (en: 'down arrowhead', google: 'ner pilspetsen') + - "⌅": [T: "projektiv"] # 0x2305 (en: 'projective') + - "⌆": [T: "perspektiv"] # 0x2306 (en: 'perspective') + - "⌇": [T: "bølget linje"] # 0x2307 (en: 'wavy line', google: 'wavy line') + - "⌈": [T: "venstre tak"] # 0x2308 (en: 'left ceiling') + - "⌉": [T: "høyre tak"] # 0x2309 (en: 'right ceiling') + - "⌊": [T: "venstre gulv"] # 0x230a (en: 'left floor') + - "⌋": [T: "høyre gulv"] # 0x230b (en: 'right floor') + - "⌌": [T: "nedre høyre utsnitt"] # 0x230c (en: 'bottom right crop') + - "⌍": [T: "nedre venstre utsnitt"] # 0x230d (en: 'bottom left crop') + - "⌎": [T: "øvre høyre utsnitt"] # 0x230e (en: 'top right crop') + - "⌏": [T: "øvre venstre utsnitt"] # 0x230f (en: 'top left crop') + - "⌐": [T: "omvendt ikke"] # 0x2310 (en: 'reversed not sign') + - "⌑": [T: "kvadratisk rombe"] # 0x2311 (en: 'square lozenge', google: 'square pastill') + - "⌒": [T: "bue"] # 0x2312 (en: 'arc') + - "⌓": [T: "segment"] # 0x2313 + - "⌔": [T: "sektor"] # 0x2314 (en: 'sector') + - "⌕": [T: "telefonopptaker"] # 0x2315 (en: 'telephone recorder', google: 'telefoninspelare') + - "⌖": [T: "trådkors"] # 0x2316 (en: 'position indicator crosshairs', google: 'positionindikator korsstolar') + - "⌗": [T: "firkant"] # 0x2317 (google translation) + - "⌘": [T: "severdighet"] # 0x2318 (en: 'place of interest sign', google: 'plats för räntetecken') + - "⌙": [T: "rotert ikke"] # 0x2319 (en: 'turned not sign', google translation) + - "⌚": [T: "klokke"] # 0x231a (en: 'watch', google: 'kolla på') + - "⌛": [T: "timeglass"] # 0x231b (en: 'hourglass', google translation) + - "⌜": [T: "øvre venstre hjørne"] # 0x231c (en: 'top left corner') + - "⌝": [T: "øvre høyre hjørne"] # 0x231d (en: 'top right corner') + - "⌞": [T: "nedre venstre hjørne"] # 0x231e (en: 'bottom left corner') + - "⌟": [T: "nedre høyre hjørne"] # 0x231f (en: 'bottom right corner') + - "⌠": [T: "øvre halvdel integral"] # 0x2320 (en: 'top half integral') + - "⌡": [T: "nedre halvdel integral"] # 0x2321 (en: 'bottom half integral') + - "⌢": [T: "rynke"] # 0x2322 (en: 'frown', google: 'rynka pannan') + - "⌣": [T: "smil"] # 0x2323 (en: 'smile') + - "⌤": [T: "enter"] # 0x2324 (en: 'up arrowhead between two horizontal bars', google: 'upp pilspetsen mellan två horisontella staplar') + - "⌥": [T: "option-tast"] # 0x2325 (en: 'option key', google translation) + - "⌦": [T: "delete"] # 0x2326 (en: 'erase to the right', google translation) + - "⌧": [T: "clear"] # 0x2327 (en: 'x in a rectangle box', google translation) + - "⌨": [T: "tastatur"] # 0x2328 (en: 'keyboard', google translation) + - "〈": [T: "venstre vinkelparentes"] # 0x2329 (en: 'left pointing angle bracket') + - "〉": [T: "høyre vinkelparentes"] # 0x232a (en: 'right pointing angle bracket') + - "⌫": [T: "backspace"] # 0x232b (en: 'erase to the left', google translation) + - "⌬": [T: "benzenring"] # 0x232c (en: 'benzene ring', google translation) + - "⌭": [T: "sylindrisitet"] # 0x232d + - "⌮": [T: "all around profile"] # 0x232e (google: 'runt profilen') + - "⌯": [T: "symmetri"] # 0x232f (en: 'symmetry', google translation) + - "⌰": [T: "total runout"] # 0x2330 (google translation) + - "⌱": [T: "dimensjon origo"] # 0x2331 (google translation) + - "⌲": [T: "konisk avsmalning"] # 0x2332 (en: 'conical taper', google translation) + - "⌳": [T: "helning"] # 0x2333 (en: 'slope', google translation) + - "⌴": [T: "plansenkning"] # 0x2334 (en: 'counterbore', google translation) + - "⌵": [T: "forsenkning"] # 0x2335 (en: 'countersink', google translation) + - "⌶": [T: "apl i beam"] # 0x2336 + - "⌽": [T: "apl circle stile"] # 0x233d + - "⌿": [T: "apl slash bar"] # 0x233f + - "⍼": [T: "rett vinkel med nedover sikksakk-pil"] # 0x237c + - "⎔": [T: "heksagon"] # 0x2394 + - "⎶": [T: "nedre hakeparentes over øvre hakeparentes"] # 0x23b6 + - "⏜": [T: "øvre parentes"] # 0x23dc + - "⏝": [T: "nedre parentes"] # 0x23dd + - "⍰": [T: "ukjent boks"] # 0x2370 (en: 'unknown box', google: 'okänd ruta') + - "⎕": [T: "boks"] # 0x2395 (en: 'box', google translation) + - "⏞": [T: "øvre krøllparentes"] # 0x23DE (en: 'top brace') + - "⏟": [T: "nedre krøllparentes"] # 0x23DF (en: 'bottom brace') + - "⏠": [T: "øvre skilpaddeskall-parentes"] # 0x23e0 + - "⏡": [T: "nedre skilpaddeskall-parentes"] # 0x23e1 + - "⏢": [T: "hvit trapes"] # 0x23e2 + - "⏣": [T: "benzenring med sirkel"] # 0x23e3 + - "⏤": [T: "retthet"] # 0x23e4 + - "⏥": [T: "flathet"] # 0x23e5 + - "⏦": [T: "vekselstrøm"] # 0x23e6 + - "⏧": [T: "elektrisk skjæring"] # 0x23e7 + #---------------------------------------------------------------------------------------------------- + #Enclosed Alphanumerics OK + - "①-⑨": # 0x2460 - 0x2469 + # SWEDISH: switched order + - SPELL: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" + - T: "i sirkel" # (en: 'circled') + - "⑩": [T: "ti i sirkel"] # 0x2469 (en: 'circled ten', google translation) + - "⑪": [T: "elleve i sirkel"] # 0x246a (en: 'circled eleven', google translation) + - "⑫": [T: "tolv i sirkel"] # 0x246b (en: 'circled twelve', google translation) + - "⑬": [T: "tretten i sirkel"] # 0x246c (en: 'circled thirteen', google translation) + - "⑭": [T: "fjorten i sirkel"] # 0x246d (en: 'circled fourteen', google translation) + - "⑮": [T: "femten i sirkel"] # 0x246e (en: 'circled fifteen', google translation) + - "⑯": [T: "seksten i sirkel"] # 0x246f (en: 'circled sixteen', google translation) + - "⑰": [T: "sytten i sirkel"] # 0x2470 (en: 'circled seventeen', google translation) + - "⑱": [T: "atten i sirkel"] # 0x2471 (en: 'circled eighteen', google translation) + - "⑳": [T: "tjue i sirkel"] # 0x2473 (en: 'circled twenty', google translation) + - "⑴-⑼": # 0x2474 - 0x247d + # SWEDISH: switched order + - SPELL: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" + - T: "i parentes" # (en: 'parenthesized', google translation) + - "⑽": [T: "ti i parentes"] # 0x247d (en: 'parenthesized ten', google translation) + - "⑾": [T: "elleve i parentes"] # 0x247e (en: 'parenthesized eleven', google translation) + - "⑿": [T: "tolv i parentes"] # 0x247f (en: 'parenthesized twelve', google translation) + - "⒀": [T: "tretten i parentes"] # 0x2480 (en: 'parenthesized thirteen', google translation) + - "⒁": [T: "fjorten i parentes"] # 0x2481 (en: 'parenthesized fourteen', google translation) + - "⒂": [T: "femten i parentes"] # 0x2482 (en: 'parenthesized fifteen', google translation) + - "⒃": [T: "seksten i parentes"] # 0x2483 (en: 'parenthesized sixteen', google translation) + - "⒄": [T: "sytten i parentes"] # 0x2484 (en: 'parenthesized seventeen', google translation) + - "⒅": [T: "atten i parentes"] # 0x2485 (en: 'parenthesized eighteen', google translation) + - "⒆": [T: "nitten i parentes"] # 0x2486 (en: 'parenthesized nineteen', google translation) + - "⒇": [T: "tjue i parentes"] # 0x2487 (en: 'parenthesized twenty', google translation) + - "⒈-⒐": # 0x2488 - 0x2491 + - SPELL: "translate('.', '⒈⒉⒊⒋⒌⒍⒎⒏⒐', '123456789')" + - T: "med punktum" # (en: 'with period', google translation) + - "⒑": [T: "ti med punktum"] # 0x2491 (en: 'ten with period', google translation) + - "⒒": [T: "elleve med punktum"] # 0x2492 (en: 'eleven with period', google translation) + - "⒓": [T: "tolv med punktum"] # 0x2493 (en: 'twelve with period', google translation) + - "⒔": [T: "tretten med punktum"] # 0x2494 (en: 'thirteen with period', google translation) + - "⒕": [T: "fjorten med punktum"] # 0x2495 (en: 'fourteen with period', google translation) + - "⒖": [T: "femten med punktum"] # 0x2496 (en: 'fifteen with period', google translation) + - "⒗": [T: "seksten med punktum"] # 0x2497 (en: 'sixteen with period', google translation) + - "⒘": [T: "sytten med punktum"] # 0x2498 (en: 'seventeen with period', google translation) + - "⒙": [T: "atten med punktum"] # 0x2499 (en: 'eighteen with period', google translation) + - "⒚": [T: "nitten med punktum"] # 0x249a (en: 'nineteen with period', google translation) + - "⒛": [T: "tjue med punktum"] # 0x249b (en: 'twenty with period', google translation) + - "⒜-⒵": # 0x249c - 0x24b5 + # SWEDISH: switched order + - SPELL: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" + - T: "i parentes" # (en: 'parenthesized', google translation) + + - "Ⓐ-Ⓩ": # 0x24b6 - 0x24cf + # SWEDISH: switched order + - SPELL: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - T: "i sirkel" # (en: 'circled', google translation) + + - "🅐-🅩": # 0x1f150 - 0x1f169 + # switched order + - SPELL: "translate('.', '🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - T: "i fylt sirkel" # (en: 'black circled', google translation) + + - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 + # SWEDISH: switched order + - SPELL: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" + - T: "i sirkel" # (en: 'circled', google translation) + - "⓪": [T: "null i sirkel"] # 0x24ea (google translation) + - "⓫": [T: "elleve i fylt sirkel"] # 0x24eb (en: 'black circled eleven', google translation) + - "⓬": [T: "tolv i fylt sirkel"] # 0x24ec (en: 'black circled twelve', google translation) + - "⓭": [T: "tretten i fylt sirkel"] # 0x24ed (en: 'black circled thirteen', google translation) + - "⓮": [T: "fjorten i fylt sirkel"] # 0x24ee (en: 'black circled fourteen', google translation) + - "⓯": [T: "femten i fylt sirkel"] # 0x24ef (en: 'black circled fifteen', google translation) + - "⓰": [T: "seksten i fylt sirkel"] # 0x24f0 (en: 'black circled sixteen', google translation) + - "⓱": [T: "sytten i fylt sirkel"] # 0x24f1 (en: 'black circled seventeen', google translation) + - "⓲": [T: "atten i fylt sirkel"] # 0x24f2 (en: 'black circled eighteen', google translation) + - "⓳": [T: "nitten i fylt sirkel"] # 0x24f3 (en: 'black circled nineteen', google translation) + - "⓴": [T: "tjue i fylt sirkel"] # 0x24f4 (en: 'black circled twenty', google translation) + - "⓵-⓽": # 0x24f5 - 0x24fe + # SWEDISH: switched order + - SPELL: "translate('.', '⓵⓶⓷⓸⓹⓺⓻⓼⓽', '123456789')" + - T: "i dobbel sirkel" # (en: 'double circled', google translation) + - "⓾": [T: "ti i dobbel sirkel"] # 0x24fe (en: 'double circled ten', google translation) + - "⓿": [T: "null i fylt sirkel"] # 0x24ff (en: 'black circled zero', google translation) + #------------------------------------------------------------------------------------------------------------------ + #Geometric shapes OK + - "■": [T: "svart kvadrat"] # 0x25a0 (en: 'black square') + - "□": [T: "hvitt kvadrat"] # 0x25a1 (en: 'white square') + - "▢": [T: "hvitt kvadrat med avrundede hjørner"] # 0x25a2 (en: 'white square with rounded corners', google: 'vit fyrkant med rundade hörn') + - "▣": [T: "lite svart kvadrat i hvitt kvadrat"] # 0x25a3 (en: 'white square containing small black square', google: 'vit fyrkant som innehåller en liten svart fyrkant') + - "▤": [T: "kvadrat med horisontalt fyll"] # 0x25a4 (en: 'square with horizontal fill', google: 'fyrkantig med horisontell fyllning') + - "▥": [T: "kvadrat med vertikalt fyll"] # 0x25a5 (en: 'square with vertical fill', google: 'fyrkantig med vertikal fyllning') + - "▦": [T: "kvadrat med ortogonal skravering"] # 0x25a6 (en: 'square with orthogonal crosshatch fill', google: 'fyrkantig med ortogonal crosshatch -fyllning') + - "▧": [T: "kvadrat med fyll fra øvre venstre til nedre høyre"] # 0x25a7 (en: 'square with upper left to lower right fill', google: 'fyrkantig med övre vänster till nedre högra fyllning') + - "▨": [T: "kvadrat med fyll fra øvre høyre til nedre venstre"] # 0x25a8 (en: 'square with upper right to lower left fill', google: 'fyrkantig med övre höger till nedre vänsterfyllning') + - "▩": [T: "kvadrat med diagonal skravering"] # 0x25a9 (en: 'square with diagonal crosshatch fill', google: 'fyrkantig med diagonal korshatchfyllning') + - "▪": [T: "lite svart kvadrat"] # 0x25aa (en: 'black small square') + - "▫": [T: "lite hvitt kvadrat"] # 0x25ab (en: 'white small square') + - "▬": [T: "svart rektangel"] # 0x25ac (en: 'black rectangle') + - "▭": [T: "hvitt rektangel"] # 0x25ad (en: 'white rectangle') + - "▮": [T: "svart vertikalt rektangel"] # 0x25ae (en: 'black vertical rectangle') + - "▯": [T: "hvitt vertikalt rektangel"] # 0x25af (en: 'white vertical rectangle') + - "▰": [T: "svart parallellogram"] # 0x25b0 (en: 'black parallelogram') + - "▱": [T: "hvitt parallellogram"] # 0x25b1 (en: 'white parallelogram') + - "▲": [T: "svart oppoverpekende trekant"] # 0x25b2 (en: 'black up pointing triangle') + - "△": [T: "hvit oppoverpekende trekant"] # 0x25b3 (en: 'white up pointing triangle') + - "▴": [T: "liten svart oppoverpekende trekant"] # 0x25b4 (en: 'black up pointing small triangle') + - "▵": [T: "liten hvit oppoverpekende trekant"] # 0x25b5 (en: 'white up pointing small triangle') + - "▶": [T: "svart høyrepekende trekant"] # 0x25b6 (en: 'black right pointing triangle') + - "▷": [T: "hvit høyrepekende trekant"] # 0x25b7 (en: 'white right pointing triangle') + - "▸": [T: "liten svart høyrepekende trekant"] # 0x25b8 (en: 'black right pointing small triangle') + - "▹": [T: "liten hvit høyrepekende trekant"] # 0x25b9 (en: 'white right pointing small triangle') + - "►": [T: "svart høyre-peker"] # 0x25ba (en: 'black right pointing pointer', google: 'svart höger pekande pekare') + - "▻": [T: "hvit høyre-peker"] # 0x25bb (en: 'white right pointing pointer', google: 'vit höger pekande pekare') + - "▼": [T: "svart nedoverpekende trekant"] # 0x25bc (en: 'black down pointing triangle', MathPlayer: 'svart triangel med spetsen neråt', google: 'svart ner pekande triangel') + - "▽": [T: "hvit nedoverpekende trekant"] # 0x25bd (en: 'white down pointing triangle', MathPlayer: 'vit triangel med spetsen neråt', google: 'vit ner pekande triangel') + - "▾": [T: "liten svart nedoverpekende trekant"] # 0x25be (en: 'black down pointing small triangle', MathPlayer: 'svart triangel med spetsen neråt', google: 'svart ner pekande liten triangel') + - "▿": [T: "liten hvit nedoverpekende trekant"] # 0x25bf (en: 'white down pointing small triangle', MathPlayer: 'vit triangel med spetsen neråt', google: 'vit ner pekande liten triangel') + - "◀": [T: "svart venstrepekende trekant"] # 0x25c0 (en: 'black left pointing triangle') + - "◁": [T: "hvit venstrepekende trekant"] # 0x25c1 (en: 'white left pointing triangle') + - "◂": [T: "liten svart venstrepekende trekant"] # 0x25c2 (en: 'black left pointing small triangle') + - "◃": [T: "liten hvit venstrepekende trekant"] # 0x25c3 (en: 'white left pointing small triangle') + - "◄": [T: "svart venstre-peker"] # 0x25c4 (en: 'black left pointing pointer') + - "◅": [T: "hvit venstre-peker"] # 0x25c5 (en: 'white left pointing pointer') + - "◆": [T: "svart diamant"] # 0x25c6 (en: 'black diamond') + - "◇": [T: "hvit diamant"] # 0x25c7 (en: 'white diamond') + - "◈": [T: "svart diamant i hvit diamant"] # 0x25c8 (en: 'white diamond containing black small diamond') + - "◉": [T: "fiskeøye"] # 0x25c9 (en: 'fisheye') + - "◊": [T: "rombe"] # 0x25ca (en: 'lozenge') + - "○": [T: "hvit sirkel"] # 0x25cb (en: 'white circle') + - "◌": [T: "stiplet sirkel"] # 0x25cc (en: 'dotted circle') + - "◍": [T: "sirkel med vertikalt fyll"] # 0x25cd (en: 'circle with vertical fill') + - "◎": [T: "bullseye"] # 0x25ce (SRE: 'mitt-i-prick') + - "●": [T: "svart sirkel"] # 0x25cf (en: 'black circle') + - "◐": [T: "sirkel med venstre halvdel fylt"] # 0x25d0 (en: 'circle with left half black') + - "◑": [T: "sirkel med høyre halvdel fylt"] # 0x25d1 (en: 'circle with right half black') + - "◒": [T: "sirkel med nedre halvdel fylt"] # 0x25d2 (en: 'circle with lower half black') + - "◓": [T: "sirkel med øvre halvdel fylt"] # 0x25d3 (en: 'circle with upper half black') + - "◔": [T: "sirkel med øvre høyre kvadrant fylt"] # 0x25d4 (en: 'circle with upper right quadrant black') + - "◕": [T: "sirkel fylt bortsett fra øvre venstre kvadrant"] # 0x25d5 (en: 'circle with all but upper left quadrant black') + - "◖": [T: "venstre halvsirkel"] # 0x25d6 (en: 'left half black circle') + - "◗": [T: "høyre halvsirkel"] # 0x25d7 (en: 'right half black circle') + - "◘": [T: "invertert punkt"] # 0x25d8 (en: 'inverse bullet') + - "◙": [T: "invertert hvit sirkel"] # 0x25d9 (en: 'inverse white circle') + - "◚": [T: "invertert hvit øvre halvsirkel"] # 0x25da (en: 'upper half inverse white circle') + - "◛": [T: "invertert hvit nedre halvsirkel"] # 0x25db (en: 'lower half inverse white circle') + - "◜": [T: "øvre venstre kvadrant av sirkelbue"] # 0x25dc (en: 'upper left quadrant circular arc') + - "◝": [T: "øvre høyre kvadrant av sirkelbue"] # 0x25dd (en: 'upper right quadrant circular arc') + - "◞": [T: "nedre høyre kvadrant av sirkelbue"] # 0x25de (en: 'lower right quadrant circular arc') + - "◟": [T: "nedre venstre kvadrant av sirkelbue"] # 0x25df (en: 'lower left quadrant circular arc') + - "◠": [T: "øvre halvsirkel"] # 0x25e0 (en: 'upper half circle') + - "◡": [T: "nedre halvsirkel"] # 0x25e1 (en: 'lower half circle') + - "◢": [T: "svart trekant ned til høyre"] # 0x25e2 (en: 'black lower right triangle', MathPlayer: 'svart triangel neråt höger', google: 'svart nedre höger triangel') + - "◣": [T: "svart trekant ned til venstre"] # 0x25e3 (en: 'black lower left triangle', MathPlayer: 'svart triangel neråt vänster', google: 'svart nedre vänster triangel') + - "◤": [T: "svart trekant oppe til venstre"] # 0x25e4 (en: 'black upper left triangle') + - "◥": [T: "svart trekant oppe til høyre"] # 0x25e5 (en: 'black upper right triangle') + - "◦": [T: "hvitt punkt"] # 0x25e6 (en: 'composition') + - "◧": [T: "kvadrat med venstre halvdel fylt"] # 0x25e7 (en: 'square with left half black') + - "◨": [T: "kvadrat med høyre halvdel fylt"] # 0x25e8 (en: 'square with right half black') + - "◩": [T: "kvadrat med øvre venstre halvdel fylt"] # 0x25e9 (en: 'square with upper left half black') + - "◪": [T: "kvadrat med nedre høyre halvdel fylt"] # 0x25ea (en: 'square with lower right half black') + - "◫": [T: "hvitt kvadrat med midtlinje"] # 0x25eb (en: 'white square with bisecting line') + - "◬": [T: "hvit oppoverpekende trekant med prikk"] # 0x25ec (en: 'white up pointing triangle with dot') + - "◭": [T: "oppoverpekende trekant med venstre halvdel fylt"] # 0x25ed (en: 'up pointing triangle with left half black') + - "◮": [T: "oppoverpekende trekant med høyre halvdel fylt"] # 0x25ee (en: 'up pointing triangle with right half black') + - "◯": [T: "stor sirkel"] # 0x25ef (en: 'large circle') + - "◰": [T: "hvitt kvadrat med øvre venstre kvadrant"] # 0x25f0 (en: 'white square with upper left quadrant', google: 'vit fyrkant med övre vänstra kvadrant') + - "◱": [T: "hvitt kvadrat med nedre venstre kvadrant"] # 0x25f1 (en: 'white square with lower left quadrant', google: 'vit fyrkant med nedre vänster kvadrant') + - "◲": [T: "hvitt kvadrat med nedre høyre kvadrant"] # 0x25f2 (en: 'white square with lower right quadrant', google: 'vit fyrkant med nedre högra kvadrant') + - "◳": [T: "hvitt kvadrat med øvre høyre kvadrant"] # 0x25f3 (en: 'white square with upper right quadrant', google: 'vit fyrkant med övre högra kvadrant') + - "◴": [T: "hvit sirkel med øvre venstre kvadrant"] # 0x25f4 (en: 'white circle with upper left quadrant', google: 'vit cirkel med övre vänstra kvadrant') + - "◵": [T: "hvit sirkel med nedre venstre kvadrant"] # 0x25f5 (en: 'white circle with lower left quadrant') + - "◶": [T: "hvit sirkel med nedre høyre kvadrant"] # 0x25f6 (en: 'white circle with lower right quadrant', google: 'vit cirkel med nedre högra kvadrant') + - "◷": [T: "hvit sirkel med øvre høyre kvadrant"] # 0x25f7 (en: 'white circle with upper right quadrant', google: 'vit cirkel med övre högra kvadrant') + - "◸": [T: "trekant oppe til venstre"] # 0x25f8 (en: 'upper left triangle') + - "◹": [T: "trekant oppe til høyre"] # 0x25f9 (en: 'upper right triangle') + - "◺": [T: "trekant ned til venstre"] # 0x25fa (en: 'lower left triangle') + - "◻": [T: "mellomstort hvitt kvadrat"] # 0x25fb (en: 'white medium square') + - "◼": [T: "mellomstort svart kvadrat"] # 0x25fc (en: 'black medium square') + - "◽": [T: "hvitt middels lite kvadrat"] # 0x25fd (en: 'white medium small square') + - "◾": [T: "svart middels lite kvadrat"] # 0x25fe (en: 'black medium small square') + - "◿": [T: "trekant ned til høyre"] # 0x25ff (en: 'lower right triangle') + #------------------------------------------------------------------------------------------------ + #Miscellaneous symbols OK + - "★": [T: "svart stjerne"] # 0x2605 + - "☆": [T: "hvit stjerne"] # 0x2606 + - "☉": [T: "sol"] # 0x2609 + - "☌": [T: "konjunksjon"] # 0x260c + - "☒": [T: "avkrysningsboks med kryss"] # 0x2612 + - "☽": [T: "tiltagende måne"] # 0x263d + - "☾": [T: "avtagende måne"] # 0x263e + - "☿": [T: "merkur"] # 0x263f + - "♀": [T: "kvinne"] # 0x2640 + - "♁": [T: "jorda"] # 0x2641 + - "♂": [T: "mann"] # 0x2642 + - "♃": [T: "jupiter"] # 0x2643 + - "♄": [T: "saturn"] # 0x2644 + - "♅": [T: "uranus"] # 0x2645 + - "♆": [T: "neptun"] # 0x2646 + - "♇": [T: "pluto"] # 0x2647 + - "♈": [T: "væren"] # 0x2648 + - "♉": [T: "tyren"] # 0x2649 + - "♩": [T: "fjerdedelsnote"] # 0x2669 + - "♭": [T: "musikalsk b"] # 0x266d + - "♮": [T: "musikalsk oppløsningstegn"] # 0x266e + - "♯": [T: "musikalsk kryss"] # 0x266f + - "♠": [T: "svart spar"] # 0x2660 (en: 'black spade suit', google: 'svart spade kostym') + - "♡": [T: "hvit hjerter"] # 0x2661 (en: 'white heart suit', google: 'vit hjärtdräkt') + - "♢": [T: "hvit ruter"] # 0x2662 (en: 'white diamond suit', google: 'vit diamantdräkt') + - "♣": [T: "svart kløver"] # 0x2663 (en: 'black club suit', google: 'svart klubbdräkt') + - "♤": [T: "hvit spar"] # 0x2664 (en: 'white spade suit', google: 'vit spade kostym') + - "♥": [T: "svart hjerter"] # 0x2665 (en: 'black heart suit', google: 'black heart suit') + - "♦": [T: "svart ruter"] # 0x2666 (en: 'black diamond suit', google: 'svart diamantdräkt') + - "♧": [T: "hvit kløver"] # 0x2667 (en: 'white club suit', google: 'vit klubbdräkt') + - "⚀": [T: "terningkast 1"] # 0x2680 + - "⚁": [T: "terningkast 2"] # 0x2681 + - "⚂": [T: "terningkast 3"] # 0x2682 + - "⚃": [T: "terningkast 4"] # 0x2683 + - "⚄": [T: "terningkast 5"] # 0x2684 + - "⚅": [T: "terningkast 6"] # 0x2685 + - "⚆": [T: "hvit sirkel med prikk til høyre"] # 0x2686 + - "⚇": [T: "hvit sirkel med to prikker"] # 0x2687 + - "⚈": [T: "svart sirkel med prikk til høyre"] # 0x2688 + - "⚉": [T: "svart sirkel med to prikker"] # 0x2689 + - "⚪": [T: "mellomstor hvit sirkel"] # 0x26aa + - "⚫": [T: "mellomstor svart sirkel"] # 0x26ab + - "⚬": [T: "middels liten hvit sirkel"] # 0x26ac + - "⚲": [T: "nøytral"] # 0x26b2 + + #------------------------------------------------------------------------------------------------ + #Dingbats OK + - "✓": [T: "avkrysningshake"] # 0x2713 + - "✠": [T: "malteserkors"] # 0x2720 + - "✪": [T: "sirkel med hvit stjerne"] # 0x272a + - "✶": [T: "svart heksagram"] # 0x2736 + - "❨": [T: "venstreparentes"] # 0x2768 (en: 'medium left parentheses ornament', google: 'medium vänster-parentesesprydnad') + - "❩": [T: "høyreparentes"] # 0x2769 (en: 'medium right parentheses ornament', google: 'medium höger parentesetheses ornament') + - "❪": [T: "avflatet venstreparentes"] # 0x276a (en: 'medium flattened left parentheses ornament', google: 'medium plattad vänster parentese -prydnad') + - "❫": [T: "avflatet høyreparentes"] # 0x276b (en: 'medium flattened right parentheses ornament', google: 'medium platta höger parentesetheses prydnad') + - "❬": [T: "venstre vinkel-parentes"] # 0x276c (en: 'medium left-pointing angle bracket ornament', google: 'medium vänsterpekande vinkelfäste prydnad') + - "❭": [T: "høyre vinkel-parentes"] # 0x276d (en: 'medium right-pointing angle bracket ornament', google: 'medium högerpekande vinkelfäste prydnad') + - "❮": [T: "fet venstre anførselstegn"] # 0x276e (en: 'heavy left-pointing angle quotation mark ornament', google: 'tung vänsterpekande vinkelcitationsmärke prydnad') + - "❯": [T: "fet høyre anførselstegn"] # 0x276f (en: 'heavy right-pointing angle quotation mark ornament', google: 'tung högerpekande vinkelcitationsmärke prydnad') + - "❰": [T: "fet venstre vinkel-parentes"] # 0x2770 (en: 'heavy left-pointing angle bracket ornament', google: 'tung vänsterpekande vinkelfäste prydnad') + - "❱": [T: "fet høyre vinkel-parentes"] # 0x2771 (en: 'heavy right-pointing angle bracket ornament', google: 'tung högerpekande vinkelfäste prydnad') + - "❲": [T: "venstre skilpaddeskall-parentes"] # 0x2772 (en: 'light left tortoise shell bracket ornament', google: 'ljus vänster sköldpaddsskalfäste prydnad') + - "❳": [T: "høyre skilpaddeskall-parentes"] # 0x2773 (en: 'light right tortoise shell bracket ornament', google: 'lätt höger sköldpaddsskalfäste prydnad') + - "❴": [T: "fet venstre krøllparentes"] # 0x2774 (en: 'medium left brace ornament', google: 'medium vänster stagprydnad') + - "❵": [T: "fet høyre krøllparentes"] # 0x2775 (en: 'medium right brace ornament', google: 'medium höger stagprydnad') + - "❶": [T: "én i fylt sirkel"] # 0x2776 (en: 'black circled one', google translation) + - "❷": [T: "to i fylt sirkel"] # 0x2777 (en: 'black circled two', google translation) + - "❸": [T: "tre i fylt sirkel"] # 0x2778 (en: 'black circled three', google translation) + - "❹": [T: "fire i fylt sirkel"] # 0x2779 (en: 'black circled four', google translation) + - "❺": [T: "fem i fylt sirkel"] # 0x277a (en: 'black circled five', google translation) + - "❻": [T: "seks i fylt sirkel"] # 0x277b (en: 'black circled six', google translation) + - "❼": [T: "sju i fylt sirkel"] # 0x277c (en: 'black circled seven', google translation) + - "❽": [T: "åtte i fylt sirkel"] # 0x277d (en: 'black circled eight', google translation) + - "❾": [T: "ni i fylt sirkel"] # 0x277e (en: 'black circled nine', google translation) + - "❿": [T: "ti i fylt sirkel"] # 0x277f (en: 'black circled ten', google translation) + - "➀": [T: "sans-serif én i sirkel"] # 0x2780 (en: 'circled sans serif one', google translation) + - "➁": [T: "sans-serif to i sirkel"] # 0x2781 (en: 'circled sans serif two', google translation) + - "➂": [T: "sans-serif tre i sirkel"] # 0x2782 (en: 'circled sans serif three', google translation) + - "➃": [T: "sans-serif fire i sirkel"] # 0x2783 (en: 'circled sans serif four', google translation) + - "➄": [T: "sans-serif fem i sirkel"] # 0x2784 (en: 'circled sans serif five', google translation) + - "➅": [T: "sans-serif seks i sirkel"] # 0x2785 (google translation) + - "➆": [T: "sans-serif sju i sirkel"] # 0x2786 (en: 'circled sans serif seven', google translation) + - "➇": [T: "sans-serif åtte i sirkel"] # 0x2787 (en: 'circled sans serif eight', google translation) + - "➈": [T: "sans-serif ni i sirkel"] # 0x2788 (en: 'circled sans serif nine', google translation) + - "➉": [T: "sans-serif ti i sirkel"] # 0x2789 (en: 'circled sans serif ten', google translation) + - "➊": [T: "sans-serif én i fylt sirkel"] # 0x278a (en: 'black circled sans serif one', google translation) + - "➋": [T: "sans-serif to i fylt sirkel"] # 0x278b (en: 'black circled sans serif two', google translation) + - "➌": [T: "sans-serif tre i fylt sirkel"] # 0x278c (en: 'black circled sans serif three', google translation) + - "➍": [T: "sans-serif fire i fylt sirkel"] # 0x278d (google translation) + - "➎": [T: "sans-serif fem i fylt sirkel"] # 0x278e (google translation) + - "➏": [T: "sans-serif seks i fylt sirkel"] # 0x278f (google translation) + - "➐": [T: "sans-serif sju i fylt sirkel"] # 0x2790 (google translation) + - "➑": [T: "sans-serif åtte i fylt sirkel"] # 0x2791 (en: 'black circled sans serif eight', google translation) + - "➒": [T: "sans-serif ni i fylt sirkel"] # 0x2792 (en: 'black circled sans serif nine', google translation) + - "➓": [T: "sans-serif ti i fylt sirkel"] # 0x2793 (google translation) + - "➔": [T: "fet høyrepil"] # 0x2794 (en: 'heavy wide-headed rightwards arrow', google: 'tungt huvud med höger om höger pil') + - "➕": [T: "fet pluss"] # 0x2795 (en: 'heavy plus sign', google: 'tungt plus -tecken') + - "➖": [T: "fet minus"] # 0x2796 (en: 'heavy minus sign', google: 'tung minusskylt') + - "➗": [T: "fet division"] # 0x2797 (en: 'heavy division sign', google: 'tung uppdelningstecken') + - "➘": [T: "fet sørøst-pil"] # 0x2798 (en: 'heavy south east arrow', google: 'tung south east arrow') + - "➙": [T: "fet høyrepil"] # 0x2799 (en: 'heavy rightwards arrow', google: 'tung åt höger-pil') + - "➚": [T: "fet nordøst-pil"] # 0x279a (en: 'heavy north east arrow', google: 'tung north east arrow') + - "➛": [T: "høyrepil"] # 0x279b (en: 'drafting point rightwards arrow', google: 'utarbetningspunkt åt höger pil') + - "➜": [T: "fet høyrepil med avrundet spiss"] # 0x279c (en: 'heavy round-tipped rightwards arrow', google: 'tung rundtippad höger-pil') + - "➝": [T: "høyrepil"] # 0x279d (en: 'triangle-headed rightwards arrow', google: 'triangelhuvud med höger pil') + - "➞": [T: "fet høyrepil"] # 0x279e (en: 'heavy triangle-headed rightwards arrow', google: 'tung triangelhuvud med höger pil') + - "➟": [T: "stiplet høyrepil"] # 0x279f (en: 'dashed triangle-headed rightwards arrow', google: 'streckad triangelhuvud med höger pil') + - "➠": [T: "fet stiplet høyrepil"] # 0x27a0 (en: 'heavy dashed triangle-headed rightwards arrow', google: 'tung streckad triangelhuvud med höger pil') + - "➡": [T: "høyrepil"] # 0x27a1 (en: 'black rightwards arrow', google: 'black rightwards arrow') + - "➢": [T: "3D-høyrepil med lys øvre del"] # 0x27a2 (en: 'three d top lighted rightwards arrow', google: 'tre d topplyst höger pil') + - "➣": [T: "3D-høyrepil med lys nedre del"] # 0x27a3 (en: 'three d bottom lighted rightwards arrow', google: 'tre d botten tände höger pil') + - "➤": [T: "pilspiss til høyre"] # 0x27a4 (en: 'black rightwards arrowhead', google: 'svart höger pilspets') + - "➥": [T: "fet høyrepil med hale oppover"] # 0x27a5 (en: 'heavy black curved downwards and rightwards arrow', google: 'tung svart krökt nedåt och höger-pil') + - "➦": [T: "fet høyrepil med hale nedover"] # 0x27a6 (en: 'heavy black curved upwards and rightwards arrow', google: 'tung svart krökt uppåt och pil med höger') + - "➧": [T: "kompakt høyrepil"] # 0x27a7 (en: 'squat black rightwards arrow', google: 'squat black rightwards arrow') + - "➨": [T: "fet høyrepil med konkav spiss"] # 0x27a8 (en: 'heavy concave-pointed black rightwards arrow', google: 'tung konkavspetsad svart höger-pil') + - "➩": [T: "høyre-skyggelagt hvit høyrepil"] # 0x27a9 (en: 'right-shaded white rightwards arrow', google: 'högerskuggad vit åt höger pil') + - "➪": [T: "venstre-skyggelagt hvit høyrepil"] # 0x27aa (en: 'left-shaded white rightwards arrow', google: 'vänsterskuggad vit åt höger pil') + - "➫": [T: "bakovervippet skyggelagt hvit høyrepil"] # 0x27ab (en: 'back-tilted shadowed white rightwards arrow', google: 'back-tiled shadowed white rightward arrow') + - "➬": [T: "fremoverlent skyggelagt hvit høyrepil"] # 0x27ac (en: 'front-tilted shadowed white rightwards arrow', google: 'front-lutad skuggad vit höger pil') + - "➭": [T: "hvit høyrepil skyggelagt under"] # 0x27ad (en: 'heavy lower right-shadowed white rightwards arrow', google: 'tung nedre högerskuggad vit höger pil') + - "➮": [T: "hvit høyrepil skyggelagt over"] # 0x27ae (en: 'heavy upper right-shadowed white rightwards arrow', google: 'tung övre högra skuggade vita höger-pil') + - "➯": [T: "hvit høyrepil med hakk skyggelagt under"] # 0x27af (en: 'notched lower right-shadowed white rightwards arrow', google: 'skåpad nedre högerskuggad vit åt höger pil') + - "➱": [T: "hvit høyrepil med hakk skyggelagt over"] # 0x27b1 (en: 'notched upper right-shadowed white rightwards arrow', google: 'skärmad övre högra skuggade vita höger-pil') + - "➲": [T: "fet hvit høyrepil med sirkel"] # 0x27b2 (en: 'circled heavy white rightwards arrow', google: 'circled heavy white rightwards arrow') + - "➳": [T: "hvit høyrepil med fjær"] # 0x27b3 (en: 'white-feathered rightwards arrow', google: 'vitfödd åt höger pil') + - "➴": [T: "sørøst-pil med fjær"] # 0x27b4 (en: 'black-feathered south east arrow', google: 'svartfödd south east arrow') + - "➵": [T: "høyrepil med fjær"] # 0x27b5 (en: 'black-feathered rightwards arrow', google: 'black-feeded rightwards arrow') + - "➶": [T: "nordøst-pil med fjær"] # 0x27b6 (en: 'black-feathered north east arrow', google: 'svartfödd nord-ostra pilen') + - "➷": [T: "fet sørøst-pil med fjær"] # 0x27b7 (en: 'heavy black-feathered south east arrow', google: 'tung svartfönad syd-ostpil') + - "➸": [T: "fet høyrepil med fjær"] # 0x27b8 (en: 'heavy black-feathered rightwards arrow', google: 'tung svartfjäder med höger pil') + - "➹": [T: "fet nordøst-pil med fjær"] # 0x27b9 (en: 'heavy black-feathered north east arrow', google: 'tung svartfönad nord-ostra pilen') + - "➺": [T: "høyrepil med mothaker"] # 0x27ba (en: 'teradrop-barbed rightwards arrow', google: 'teradrop-barbed till höger pil') + - "➻": [T: "tåreformet høyrepil"] # 0x27bb (en: 'heavy teardrop-shanked rightwards arrow', google: 'tung teardrop-shanked höger-pil') + - "➼": [T: "høyrepil med kileformet hale"] # 0x27bc (en: 'wedge-tailed rightwards arrow', google: 'wedge-tailed åt höger pil') + - "➽": [T: "fet høyrepil med kileformet hale"] # 0x27bd (en: 'heavy wedge-tailed rightwards arrow', google: 'tung kil-tailed höger-pil') + - "➾": [T: "høyrepil med åpne konturer"] # 0x27be (en: 'open-outlined rightwards arrow', google: 'öppen-outlinerad höger-pil') + #---------------------------------------------------------------------------------------------------------------------------------- + #Miscellaneous mathematical symbols-A OK + - "⟀": [T: "tredimensjonal vinkel"] # 0x27c0 (en: 'three dimensional angle') + - "⟁": [T: "hvit trekant med liten hvit trekant"] # 0x27c1 (en: 'white triangle containing small white triangle') + - "⟂": # 0x27c2 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "vinkelrett på" # (en: 'perpendicular to') + - "⟃": # 0x27c3 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is', google translation) + - T: "åpen delmengde av" # (en: 'an open subset of') + - "⟄": # 0x27c4 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is', google translation) + - T: "åpen overmengde av" # (en: 'an open superset of') + - "⟅": [T: "venstre s-formet bag delimiter"] # 0x27c5 (en: 'left s-shaped bag delimiter') + - "⟆": [T: "høyre s-formet bag delimiter"] # 0x27c6 (en: 'right s-shaped bag delimiter') + - "⟇": [T: "eller med prikk"] # 0x27c7 (en: 'or with dot inside') + - "⟈": [T: "omvendt skråstrek før delmengde"] # 0x27c8 (en: 'reverse solidus preceding subset') + - "⟉": [T: "overmengde før skråstrek"] # 0x27c9 (en: 'superset preceding solidus') + - "⟊": [T: "vertikal strek med horisontal strek"] # 0x27ca (en: 'vertical bar with horizontal stroke') + - "⟋": [T: "stigende diagonal"] # 0x27cb (en: 'mathematical rising diagonal', google: 'matematisk stigande diagonal') + - "⟌": [T: "lang divisjon"] # 0x27cc (en: 'long division') + - "⟍": [T: "synkende diagonal"] # 0x27cd (en: 'mathematical falling diagonal', google: 'matematisk fallande diagonal') + - "⟎": [T: "logisk og i kvadrat"] # 0x27ce (en: 'squared logical and', google: 'squared logical och') + - "⟏": [T: "logisk eller i kvadrat"] # 0x27cf (en: 'squared logical or', google: 'kvadratiska logiska eller') + - "⟐": [T: "hvit diamant med prikk i midten"] # 0x27d0 (en: 'white diamond with centered dot', google: 'vit diamant med centrerad prick') + - "⟑": [T: "og med prikk"] # 0x27d1 (en: 'and with dot') + - "⟒": [T: "tilhører med åpning oppover"] # 0x27d2 (en: 'element of opening upwards') + - "⟓": [T: "nedre høyre hjørne med prikk"] # 0x27d3 (en: 'lower right corner with dot') + - "⟔": [T: "øvre venstre hjørne med prikk"] # 0x27d4 (en: 'upper left corner with dot') + - "⟕": [T: "venstre outer join"] # 0x27d5 (en: 'left outer join') + - "⟖": [T: "høyre outer join"] # 0x27d6 (en: 'right outer join') + - "⟗": [T: "full outer join"] # 0x27d7 (en: 'full outer join') + - "⟘": [T: "stort oppoverrotert dreiekors"] # 0x27d8 (en: 'large up tack') + - "⟙": [T: "stort nedoverrotert dreiekors"] # 0x27d9 (en: 'large down tack') + - "⟚": [T: "venstre og høyre dobbelt dreiekors"] # 0x27da (en: 'left and right double turnstile') + - "⟛": [T: "venstre og høyre dreiekors"] # 0x27db (en: 'left and right tack') + - "⟜": [T: "venstre multimap"] # 0x27dc (en: 'left multimap') + - "⟝": [T: "langt høyre dreiekors"] # 0x27dd (en: 'long right tack') + - "⟞": [T: "langt venstre dreiekors"] # 0x27de (en: 'long left tack') + - "⟟": [T: "oppoverrotert dreiekors med sirkel over"] # 0x27df (en: 'up tack with circle above') + - "⟠": [T: "rombe delt med horisontal strek"] # 0x27e0 (en: 'lozenge divided by horizontal rule') + - "⟡": [T: "hvit konkav-sidet diamant"] # 0x27e1 (en: 'white concave sided diamond') + - "⟢": [T: "hvit konkav-sidet diamant med strek til venstre"] # 0x27e2 (en: 'white concave sided diamond with leftwards tick') + - "⟣": [T: "hvit konkav-sidet diamant med strek til høyre"] # 0x27e3 (en: 'white concave sided diamond with rightwards tick') + - "⟤": [T: "hvitt kvadrat med strek til venstre"] # 0x27e4 (en: 'white square with leftwards tick') + - "⟥": [T: "hvitt kvadrat med strek til høyre"] # 0x27e5 (en: 'white square with rightwards tick') + - "⟦": [T: "hvit venstre hakeparentes"] # 0x27e6 (en: 'left white square bracket') + - "⟧": [T: "hvit høyre hakeparentes"] # 0x27e7 (en: 'right white square bracket') + - "⟨": [T: "venstre vinkel-parentes"] # 0x27e8 (en: 'left angle bracket') + - "⟩": [T: "høyre vinkel-parentes"] # 0x27e9 (en: 'right angle bracket') + - "⟪": [T: "venstre dobbel vinkel-parentes"] # 0x27ea (en: 'left double angle bracket') + - "⟫": [T: "høyre dobbel vinkel-parentes"] # 0x27eb (en: 'right double angle bracket') + - "⟬": [T: "venstre hvit skilpaddeskall-parentes"] # 0x27ec (en: 'left white tortoise shell bracket') + - "⟭": [T: "høyre hvit skilpaddeskall-parentes"] # 0x27ed (en: 'right white tortoise shell bracket') + - "⟮": [T: "avflatet høyreparentes"] # 0x27ee (en: 'left flattened parenthesis') + - "⟯": [T: "avflatet venstreparentes"] # 0x27ef (en: 'right flattened parenthesis') + #-------------------------------------------------------------------------------------------------- + # Supplemental arrows-A OK + - "⟰": [T: "kvadrupel-streket oppoverpil"] # 0x27f0 (en: 'upwards quadruple arrow', google: 'uppåt fyrdubbla pilen') + - "⟱": [T: "kvadrupel-streket nedoverpil"] # 0x27f1 (en: 'downwards quadruple arrow', google: 'nedåt fyrdubbla pilen') + - "⟲": [T: "åpen sirkelpil mot klokken"] # 0x27f2 (en: 'anticlockwise gapped circle arrow', google: 'antikvis gappad cirkelpil') + - "⟳": [T: "åpen sirkelpil med klokken"] # 0x27f3 (en: 'clockwise gapped circle arrow', google: 'medurs gappad cirkelpil') + - "⟴": [T: "høyrepil med pluss i sirkel"] # 0x27f4 (en: 'right arrow with circled plus', google: 'höger-pil med circled plus') + - "⟵": [T: "lang venstrepil"] # 0x27f5 (en: 'long leftwards arrow') + - "⟶": [T: "lang høyrepil"] # 0x27f6 (en: 'long rightwards arrow') + - "⟷": [T: "lang venstre-høyre-pil"] # 0x27f7 (en: 'long left right arrow') + - "⟸": [T: "lang dobbeltstreket venstrepil"] # 0x27f8 (en: 'long leftwards double arrow') + - "⟹": [T: "lang dobbeltstreket høyrepil"] # 0x27f9 (en: 'long rightwards double arrow') + - "⟺": [T: "lang dobbeltstreket venstre-høyre-pil"] # 0x27fa (en: 'long left right double arrow') + - "⟻": [T: "lang venstrepil fra strek"] # 0x27fb (en: 'long leftwards arrow from bar', google: 'lång vänster pil från bar') + - "⟼": [T: "lang høyrepil fra strek"] # 0x27fc (en: 'long rightwards arrow from bar') + - "⟽": [T: "lang dobbeltstreket venstrepil fra strek"] # 0x27fd (en: 'long leftwards double arrow from bar', google: 'lång vänster dubbelpil från bar') + - "⟾": [T: "lang dobbeltstreket høyrepil fra strek"] # 0x27fe (en: 'long rightwards double arrow from bar', google: 'långt höger-pil från bar') + - "⟿": [T: "lang svingete høyrepil"] # 0x27ff (en: 'long rightwards squiggle arrow') + #------------------------------------------------------------------------------------------------------ + #Supplemental arrows-B OK + - "⤀": [T: "høyrepil med to spisser og vertikal strek"] # 0x2900 (en: 'rightwards two headed arrow with vertical stroke', google: 'åtgärd två ledde pil med vertikalt slag') + - "⤁": [T: "høyrepil med to spisser og dobbel vertikal strek"] # 0x2901 (en: 'rightwards two headed arrow with double vertical stroke', google: 'åtgärder två pil med dubbel vertikal stroke') + - "⤂": [T: "dobbeltstreket venstrepil med vertikal strek"] # 0x2902 (en: 'leftwards double arrow with vertical stroke', google: 'vänster dubbelpil med vertikalt slag') + - "⤃": [T: "dobbeltstreket høyrepil med vertikal strek"] # 0x2903 (en: 'rightwards double arrow with vertical stroke', google: 'åtgärd med höger med vertikal stroke') + - "⤄": [T: "dobbeltstreket venstre-høyre-pil med vertikal strek"] # 0x2904 (en: 'left right double arrow with vertical stroke', google: 'vänster höger dubbelpil med vertikalt slag') + - "⤅": [T: "høyrepil fra strek med dobbel spiss"] # 0x2905 (en: 'rightwards two headed arrow from bar') + - "⤆": [T: "dobbeltstreket venstrepil fra strek"] # 0x2906 (en: 'leftwards double arrow from bar', google: 'vänster dubbelpil från bar') + - "⤇": [T: "dobbeltstreket høyrepil fra strek"] # 0x2907 (en: 'rightwards double arrow from bar', google: 'åtgärd med höger pil från stången') + - "⤈": [T: "nedoverpil med horisontal strek"] # 0x2908 (en: 'downwards arrow with horizontal stroke', google: 'nedåt pil med horisontellt slag') + - "⤉": [T: "oppoverpil med horisontal strek"] # 0x2909 (en: 'upwards arrow with horizontal stroke', google: 'uppåt pil med horisontellt slag') + - "⤊": [T: "trippel-streket oppoverpil"] # 0x290a (en: 'upwards triple arrow', google: 'uppåt trippelpil') + - "⤋": [T: "trippel-streket nedoverpil"] # 0x290b (en: 'downwards triple arrow', google: 'nedåt trippelpil') + - "⤌": [T: "stiplet venstrepil"] # 0x290c (en: 'leftwards double dash arrow') + - "⤍": [T: "stiplet høyrepil"] # 0x290d (en: 'rightwards double dash arrow') + - "⤎": [T: "stiplet venstrepil"] # 0x290e (en: 'leftwards triple dash arrow') + - "⤏": [T: "stiplet høyrepil"] # 0x290f (en: 'rightwards triple dash arrow') + - "⤐": [T: "stiplet høyrepil med to spisser"] # 0x2910 (en: 'rightwards two headed triple dash arrow') + - "⤑": [T: "prikket høyrepil"] # 0x2911 (en: 'rightwards arrow with dotted stem') + - "⤒": [T: "oppoverpil mot strek"] # 0x2912 + - "⤓": [T: "nedoverpil mot strek"] # 0x2913 + - "⤔": [T: "høyrepil med hale og vertikal strek"] # 0x2914 (en: 'rightwards arrow with tail and vertical stroke', google: 'åtgärdspil med svans och vertikalt slag') + - "⤕": [T: "høyrepil med hale og dobbel vertikal strek"] # 0x2915 (en: 'rightwards arrow with tail and double vertical stroke', google: 'åtgärdspil med svans och dubbel vertikal stroke') + - "⤖": [T: "høyrepil med dobbel spiss og hale"] # 0x2916 (en: 'rightwards two headed arrow with tail') + - "⤗": [T: "høyrepil med dobbel spiss og hale og vertikal strek"] # 0x2917 (en: 'rightwards two headed arrow with tail with vertical stroke', google: 'åt höger två pil med svans med vertikalt stroke') + - "⤘": [T: "høyrepil med dobbel spiss og hale og dobbel vertikal strek"] # 0x2918 (en: 'rightwards two headed arrow with tail with double vertical stroke', google: 'åt höger två pil med svans med dubbel vertikal stroke') + - "⤙": [T: "venstre pil-hale"] # 0x2919 (en: 'leftwards arrow tail') + - "⤚": [T: "høyre pil-hale"] # 0x291a (en: 'rightwards arrow tail', google: 'åtgärder med höger pil') + - "⤛": [T: "dobbel venstre pil-hale"] # 0x291b (en: 'leftwards double arrow tail') + - "⤜": [T: "dobbel høyre pil-hale"] # 0x291c (en: 'rightwards double arrow tail') + - "⤝": [T: "venstrepil mot fylt diamant"] # 0x291d (en: 'leftwards arrow to filled diamond') + - "⤞": [T: "høyrepil mot fylt diamant"] # 0x291e (en: 'rightwards arrow to filled diamond') + - "⤟": [T: "venstrepil fra strek til fylt diamant"] # 0x291f (en: 'leftwards arrow from bar to filled diamond') + - "⤠": [T: "høyrepil fra strek til fylt diamant"] # 0x2920 (en: 'rightwards arrow from bar to filled diamond') + - "⤡": [T: "nordvest- og sørøst-pil"] # 0x2921 (en: 'north west and south east arrow', google: 'north west och south east arrow') + - "⤢": [T: "nordøst- og sørvest-pil"] # 0x2922 (en: 'north east and south west arrow', google: 'north east and south west arrow') + - "⤣": [T: "nordvest-pil med krok"] # 0x2923 (en: 'north west arrow with hook') + - "⤤": [T: "nordøst-pil med krok"] # 0x2924 (en: 'north east arrow with hook') + - "⤥": [T: "sørøst-pil med krok"] # 0x2925 (en: 'south east arrow with hook') + - "⤦": [T: "sørvest-pil med krok"] # 0x2926 (en: 'south west arrow with hook') + - "⤧": [T: "nordvest-pil og nordøst-pil"] # 0x2927 (en: 'north west arrow and north east arrow') + - "⤨": [T: "nordøst-pil og sørøst-pil"] # 0x2928 (en: 'north east arrow and south east arrow') + - "⤩": [T: "sørøst-pil og sørvest-pil"] # 0x2929 (en: 'south east arrow and south west arrow') + - "⤪": [T: "sørvest-pil og nordvest-pil"] # 0x292a (en: 'south west arrow and north west arrow') + - "⤫": [T: "stigende diagonal krysser synkende diagonal"] # 0x292b (en: 'rising diagonal crossing falling diagonal', google: 'stigande diagonal korsning fallande diagonal') + - "⤬": [T: "synkende diagonal krysser stigende diagonal"] # 0x292c (en: 'falling diagonal crossing rising diagonal', google: 'fallande diagonal korsning stigande diagonal') + - "⤭": [T: "sørøst-pil krysser nordøst-pil"] # 0x292d (en: 'south east arrow crossing north east arrow', google: 'south east arrow crossing north east arrow') + - "⤮": [T: "nordøst-pil krysser sørøst-pil"] # 0x292e (en: 'north east arrow crossing south east arrow', google: 'north east arrow crossing south east arrow') + - "⤯": [T: "synkende diagonal krysser nordøst-pil"] # 0x292f (en: 'falling diagonal crossing north east arrow', google: 'fallande diagonal korsar nord-ostra pilen') + - "⤰": [T: "stigende diagonal krysser sørøst-pil"] # 0x2930 (en: 'rising diagonal crossing south east arrow', google: 'rising diagonal crossing south east arrow') + - "⤱": [T: "nordøst-pil krysser nordvest-pil"] # 0x2931 (en: 'north east arrow crossing north west arrow', google: 'north east arrow crossing north west arrow') + - "⤲": [T: "nordvest-pil krysser nordøst-pil"] # 0x2932 (en: 'north west arrow crossing north east arrow', google: 'north west arrow crossing north east arrow') + - "⤳": [T: "bølgete høyrepil"] # 0x2933 (en: 'wave arrow pointing directly right') + - "⤴": [T: "høyrepil med vinkel oppover"] # 0x2934 (en: 'arrow pointing rightwards then curving upwards', google: 'arrow pekar åt höger och böjer sig sedan uppåt') + - "⤵": [T: "høyrepil med vinkel nedover"] # 0x2935 (en: 'arrow pointing rightwards then curving downwards') + - "⤶": [T: "nedoverpil med vinkel til venstre"] # 0x2936 (en: 'arrow pointing downwards then curving leftwards') + - "⤷": [T: "nedoverpil med vinkel til høyre"] # 0x2937 (en: 'arrow pointing downwards then curving rightwards') + - "⤸": [T: "halvsirkelpil med klokken"] # 0x2938 (en: 'right side arc clockwise arrow') + - "⤹": [T: "halvsirkelpil mot klokken"] # 0x2939 (en: 'left side arc anticlockwise arrow') + - "⤺": [T: "øvre halvsirkelpil mot klokken"] # 0x293a (en: 'top arc anticlockwise arrow', google: 'toppbåge moturs pil') + - "⤻": [T: "nedre halvsirkelpil mot klokken"] # 0x293b (en: 'bottom arc anticlockwise arrow', google: 'nedre båge anticurs pil') + - "⤼": [T: "øvre halvsirkelpil med klokken med minus"] # 0x293c (en: 'top arc clockwise arrow with minus') + - "⤽": [T: "øvre halvsirkelpil mot klokken med pluss"] # 0x293d (en: 'top arc anticlockwise arrow with plus') + - "⤾": [T: "halvsirkelpil med klokken"] # 0x293e (en: 'lower right semicircular clockwise arrow', google: 'nedre högra halvcirkelformade medurs pil') + - "⤿": [T: "halvsirkelpil mot klokken"] # 0x293f (en: 'lower left semicircular anticlockwise arrow', google: 'nedre vänstra halvcirkelformade pil moturs') + - "⥀": [T: "sirkel-pil mot klokken"] # 0x2940 (en: 'anticlockwise closed circle arrow', google: 'antikvis stängd cirkelpil') + - "⥁": [T: "sirkel-pil med klokken"] # 0x2941 (en: 'clockwise closed circle arrow', google: 'medurs stängd cirkelpil') + - "⥂": [T: "høyrepil over kort venstrepil"] # 0x2942 (en: 'rightwards arrow above short leftwards arrow', google: 'åtgärdspil över kort vänster pil') + - "⥃": [T: "venstrepil over kort høyrepil"] # 0x2943 (en: 'leftwards arrow above short rightwards arrow', google: 'vänster pil ovanför kort höger-pil') + - "⥄": [T: "kort høyrepil over venstrepil"] # 0x2944 (en: 'short rightwards arrow above leftwards arrow', google: 'kort höger-pil ovanför vänster pil') + - "⥅": [T: "høyrepil med pluss under"] # 0x2945 (en: 'rightwards arrow with plus below') + - "⥆": [T: "venstrepil med pluss under"] # 0x2946 (en: 'leftwards arrow with plus below', google: 'vänster pil med plus nedan') + - "⥇": [T: "høyrepil gjennom x"] # 0x2947 (en: 'rightwards arrow through x', google: 'åtgärdspil genom x') + - "⥈": [T: "venstre-høyre-pil gjennom sirkel"] # 0x2948 (en: 'left right arrow through circle') + - "⥉": [T: "oppoverpil med dobbel spiss fra sirkel"] # 0x2949 (en: 'upwards two headed arrow from circle') + - "⥊": [T: "toveis harpun venstre mothake opp høyre mothake ned"] # 0x294a (en: 'left barb up right barb down harpoon') + - "⥋": [T: "toveis harpun venstre mothake ned høyre mothake opp"] # 0x294b (en: 'left barb down right barb up harpoon') + - "⥌": [T: "toveis vertikal harpun øvre mothake høyre nedre mothake venstre"] # 0x294c (en: 'up barb right down barb left harpoon', google: 'upp barb höger ner barb vänster harpun') + - "⥍": [T: "toveis vertikal harpun øvre mothake venstre nedre mothake høyre"] # 0x294d (en: 'up barb left down barb right harpoon', google: 'upp barb vänster ner barb höger harpoon') + - "⥎": [T: "toveis harpun mothaker opp"] # 0x294e (en: 'left barb up right barb up harpoon', MathPlayer: 'vänster höger harpoon up', google: 'vänster barb upp höger barb upp harpoon') + - "⥏": [T: "toveis vertikal harpun mothaker høyre"] # 0x294f (en: 'up barb right down barb right harpoon') + - "⥐": [T: "toveis harpun mothaker ned"] # 0x2950 (en: 'left barb down right barb down harpoon', MathPlayer: 'vänster höger harpoon ner') + - "⥑": [T: "toveis vertikal harpun mothaker venstre"] # 0x2951 (en: 'up barb left down barb left harpoon') + - "⥒": [T: "venstre-harpun mot strek mothake opp"] # 0x2952 (en: 'leftwards harpoon with barb up to bar') + - "⥓": [T: "høyre-harpun mot strek mothake opp"] # 0x2953 (en: 'rightwards harpoon with barb up to bar') + - "⥔": [T: "opp-harpun mot strek mothake høyre"] # 0x2954 (en: 'upwards harpoon with barb right to bar') + - "⥕": [T: "ned-harpun mot strek mothake høyre"] # 0x2955 (en: 'downwards harpoon with barb right to bar') + - "⥖": [T: "venstre-harpun mot strek mothake ned"] # 0x2956 (en: 'leftwards harpoon with barb down to bar') + - "⥗": [T: "høyre-harpun mot strek mothake ned"] # 0x2957 (en: 'rightwards harpoon with barb down to bar') + - "⥘": [T: "opp-harpun mot strek mothake venstre"] # 0x2958 (en: 'upwards harpoon with barb left to bar') + - "⥙": [T: "ned-harpun mot strek mothake venstre"] # 0x2959 (en: 'downwards harpoon with barb left to bar') + - "⥚": [T: "venstre-harpun fra strek mothake opp"] # 0x295a (en: 'leftwards harpoon with barb up from bar') + - "⥛": [T: "høyre-harpun fra strek mothake opp"] # 0x295b (en: 'rightwards harpoon with barb up from bar') + - "⥜": [T: "opp-harpun fra strek mothake høyre"] # 0x295c (en: 'upwards harpoon with barb right from bar') + - "⥝": [T: "ned-harpun fra strek mothake høyre"] # 0x295d (en: 'downwards harpoon with barb right from bar') + - "⥞": [T: "venstre-harpun fra strek mothake ned"] # 0x295e (en: 'leftwards harpoon with barb down from bar') + - "⥟": [T: "høyre-harpun fra strek mothake ned"] # 0x295f (en: 'rightwards harpoon with barb down from bar') + - "⥠": [T: "opp-harpun fra strek mothake venstre"] # 0x2960 (en: 'upwards harpoon with barb left from bar') + - "⥡": [T: "ned-harpun fra strek mothake venstre"] # 0x2961 (en: 'downwards harpoon with barb left from bar') + - "⥢": [T: "venstre-harpun mothake opp over venstre-harpun mothake ned"] # 0x2962 (en: 'leftwards harpoon with barb up above leftwards harpoon with barb down') + - "⥣": [T: "opp-harpun mothake venstre ved siden av opp-harpun mothake høyre"] # 0x2963 (en: 'upwards harpoon with barb left beside upwards harpoon with barb right') + - "⥤": [T: "høyre-harpun mothake opp over høyre-harpun mothake ned"] # 0x2964 (en: 'rightwards harpoon with barb up above rightwards harpoon with barb down') + - "⥥": [T: "ned-harpun mothake venstre ved siden av ned-harpun mothake høyre"] # 0x2965 (en: 'downwards harpoon with barb left beside downwards harpoon with barb right') + - "⥦": [T: "venstre-harpun mothake opp over høyre-harpun mothake opp"] # 0x2966 (en: 'leftwards harpoon with barb up above rightwards harpoon with barb up') + - "⥧": [T: "venstre-harpun mothake ned over høyre-harpun mothake ned"] # 0x2967 (en: 'leftwards harpoon with barb down above rightwards harpoon with barb down') + - "⥨": [T: "høyre-harpun mothake opp over venstre-harpun mothake opp"] # 0x2968 (en: 'rightwards harpoon with barb up above leftwards harpoon with barb up') + - "⥩": [T: "høyre-harpun mothake ned over venstre-harpun mothake ned"] # 0x2969 (en: 'rightwards harpoon with barb down above leftwards harpoon with barb down') + - "⥪": [T: "venstre-harpun mothake opp over strek"] # 0x296a (en: 'leftwards harpoon with barb up above long dash') + - "⥫": [T: "venstre-harpun mothake ned under strek"] # 0x296b (en: 'leftwards harpoon with barb down below long dash') + - "⥬": [T: "høyre-harpun mothake opp over strek"] # 0x296c (en: 'rightwards harpoon with barb up above long dash') + - "⥭": [T: "høyre-harpun mothake ned under strek"] # 0x296d (en: 'rightwards harpoon with barb down below long dash') + - "⥮": [T: "opp-harpun mothake venstre ved siden av ned-harpun mothake høyre"] # 0x296e (en: 'upwards harpoon with barb left beside downwards harpoon with barb right') + - "⥯": [T: "ned-harpun mothake venstre ved siden av opp-harpun mothake høyre"] # 0x296f (en: 'downwards harpoon with barb left beside upwards harpoon with barb right') + - "⥰": [T: "dobbeltstreket høyrepil med avrundet spiss"] # 0x2970 (en: 'right double arrow with rounded head') + - "⥱": [T: "lik over høyrepil"] # 0x2971 (en: 'equals above rightwards arrow') + - "⥲": [T: "tilde over høyrepil"] # 0x2972 (en: 'tilde operator above rightwards arrow') + - "⥳": [T: "venstrepil over tilde"] # 0x2973 (en: 'leftwards arrow above tilde operator') + - "⥴": [T: "høyrepil over tilde"] # 0x2974 (en: 'rightwards arrow above tilde operator') + - "⥵": [T: "høyrepil over tilnærmet lik"] # 0x2975 (en: 'rightwards arrow above almost equal to') + - "⥶": [T: "mindre enn over venstrepil"] # 0x2976 (en: 'less than above leftwards arrow') + - "⥷": [T: "venstrepil gjennom mindre enn"] # 0x2977 (en: 'leftwards arrow through less than', google: 'vänster pil genom mindre än') + - "⥸": [T: "større enn over høyrepil"] # 0x2978 (en: 'greater than above rightwards arrow') + - "⥹": [T: "delmengde over høyrepil"] # 0x2979 (en: 'subset above rightwards arrow') + - "⥺": [T: "venstrepil gjennom delmengde"] # 0x297a (en: 'leftwards arrow through subset', google: 'vänster pil genom undergruppen') + - "⥻": [T: "overmengde over venstrepil"] # 0x297b (en: 'superset above leftwards arrow') + - "⥼": [T: "fiskehale til venstre"] # 0x297c (en: 'left fish tail') + - "⥽": [T: "fiskehale til høyre"] # 0x297d (en: 'right fish tail') + - "⥾": [T: "fiskehale oppover"] # 0x297e (en: 'up fish tail') + - "⥿": [T: "fiskehale nedover"] # 0x297f (en: 'down fish tail') + #--------------------------------------------------------------------------------------------- + # Miscellaneous Mathematical symbols-B OK + - "⦀": [T: "trippel loddrett strek"] # 0x2980 (en: 'triple vertical bar delimiter', google: 'trippel vertikal bar avgränsare') + - "⦁": [T: "punkt z-notasjon"] # 0x2981 (en: 'z notation spot', google: 'z notation spot') + - "⦂": [T: "kolon z-notasjon"] # 0x2982 (en: 'z notation type colon', google: 'z notationstyp kolon') + - "⦃": [T: "venstre hvit krøllparentes"] # 0x2983 (en: 'left white brace', google: 'vänster vit stag') + - "⦄": [T: "høyre hvit krøllparentes"] # 0x2984 (en: 'right white brace', google: 'höger vit stag') + - "⦅": [T: "hvit venstreparentes"] # 0x2985 (en: 'left white parenthesis') + - "⦆": [T: "hvit høyreparentes"] # 0x2986 (en: 'right white parenthesis') + - "⦇": [T: "venstre bilde-parentes z-notasjon"] # 0x2987 (en: 'z notation left image bracket', google: 'z notation vänster bildfäste') + - "⦈": [T: "høyre bilde-parentes z-notasjon"] # 0x2988 (en: 'z notation right image bracket', google: 'z notation rätt bildfäste') + - "⦉": [T: "venstre bindende parentes z-notasjon"] # 0x2989 (en: 'z notation left binding bracket') + - "⦊": [T: "høyre bindende parentes z-notasjon"] # 0x298a (en: 'z notation right binding bracket') + - "⦋": [T: "venstre hakeparentes med strek under"] # 0x298b (en: 'left square bracket with underbar') + - "⦌": [T: "høyre hakeparentes med strek under"] # 0x298c (en: 'right square bracket with underbar') + - "⦍": [T: "venstre hakeparentes med strek i øvre hjørne"] # 0x298d (en: 'left square bracket with tick in top corner') + - "⦎": [T: "høyre hakeparentes med strek i nedre hjørne"] # 0x298e (en: 'right square bracket with tick in bottom corner') + - "⦏": [T: "venstre hakeparentes med strek i nedre hjørne"] # 0x298f (en: 'left square bracket with tick in bottom corner') + - "⦐": [T: "høyre hakeparentes med strek i øvre hjørne"] # 0x2990 (en: 'right square bracket with tick in top corner') + - "⦑": [T: "venstre vinkelparentes med prikk"] # 0x2991 (en: 'left angle bracket with dot') + - "⦒": [T: "høyre vinkelparentes med prikk"] # 0x2992 (en: 'right angle bracket with dot') + - "⦓": [T: "venstre mindre enn parentes"] # 0x2993 (en: 'left arc less than bracket') + - "⦔": [T: "høyre større enn parentes"] # 0x2994 (en: 'right arc greater than bracket') + - "⦕": [T: "venstre dobbel større enn parentes"] # 0x2995 (en: 'double left arc greater than bracket') + - "⦖": [T: "høyre dobbel mindre enn parentes"] # 0x2996 (en: 'double right arc less than bracket') + - "⦗": [T: "venstre skilpaddeskall-parentes"] # 0x2997 (en: 'left black tortoise shell bracket', google: 'vänster svart sköldpaddsskalfäste') + - "⦘": [T: "høyre skilpaddeskall-parentes"] # 0x2998 (en: 'right black tortoise shell bracket', google: 'höger svart sköldpaddsskalfäste') + - "⦙": [T: "prikket loddrett strek"] # 0x2999 (en: 'dotted fence', google: 'prickat staket') + - "⦚": [T: "sikksakk loddrett strek"] # 0x299a (en: 'vertical zigzag line') + - "⦛": [T: "målt vinkel til venstre"] # 0x299b (en: 'measured angle opening left', google: 'uppmätt vinkelöppning vänster') + - "⦜": [T: "rett vinkel"] # 0x299c (en: 'right angle variant with square', google: 'rätt vinkelvariant med fyrkant') + - "⦝": [T: "målt rett vinkel med prikk"] # 0x299d (en: 'measured right angle with dot') + - "⦞": [T: "vinkel med s i"] # 0x299e (en: 'angle with s inside') + - "⦟": [T: "spiss vinkel"] # 0x299f (en: 'acute angle') + - "⦠": [T: "sfærisk vinkel til venstre"] # 0x29a0 (en: 'spherical angle opening left', google: 'sfärisk vinkelöppning vänster') + - "⦡": [T: "sfærisk vinkel oppover"] # 0x29a1 (en: 'spherical angle opening up', google: 'sfärisk vinkel öppnas') + - "⦢": [T: "snudd vinkel"] # 0x29a2 (en: 'turned angle', google: 'vände vinkel') + - "⦣": [T: "speilvendt vinkel"] # 0x29a3 (en: 'reversed angle') + - "⦤": [T: "vinkel med strek under"] # 0x29a4 (en: 'angle with underbar') + - "⦥": [T: "speilvendt vinkel med strek under"] # 0x29a5 (en: 'reversed angle with underbar') + - "⦦": [T: "stump vinkel oppover"] # 0x29a6 (en: 'oblique angle opening up') + - "⦧": [T: "stump vinkel nedover"] # 0x29a7 (en: 'oblique angle opening down') + - "⦨": [T: "målt vinkel med nordøst-pil i enden av øvre vinkelben"] # 0x29a8 (en: 'measured angle with open arm ending in arrow pointing up and to the right') + - "⦩": [T: "målt vinkel med nordvest-pil i enden av øvre vinkelben"] # 0x29a9 (en: 'measured angle with open arm ending in arrow pointing up and to the left') + - "⦪": [T: "målt vinkel med sørøst-pil i enden av nedre vinkelben"] # 0x29aa (en: 'measured angle with open arm ending in arrow pointing down and to the right') + - "⦫": [T: "målt vinkel med sørvest-pil i enden av nedre vinkelben"] # 0x29ab (en: 'measured angle with open arm ending in arrow pointing down and to the left') + - "⦬": [T: "målt vinkel med nordøst-pil i enden av høyre vinkelben"] # 0x29ac (en: 'measured angle with open arm ending in arrow pointing right and up') + - "⦭": [T: "målt vinkel med nordvest-pil i enden av venstre vinkelben"] # 0x29ad (en: 'measured angle with open arm ending in arrow pointing left and up') + - "⦮": [T: "målt vinkel med sørøst-pil i enden av høyre vinkelben"] # 0x29ae (en: 'measured angle with open arm ending in arrow pointing right and down') + - "⦯": [T: "målt vinkel med sørvest-pil i enden av venstre vinkelben"] # 0x29af (en: 'measured angle with open arm ending in arrow pointing left and down') + - "⦰": [T: "den tomme mengden speilvendt"] # 0x29b0 (en: 'reversed empty set') + - "⦱": [T: "den tomme mengden med strek over"] # 0x29b1 (en: 'empty set with overbar') + - "⦲": [T: "den tomme mengden med sirkel over"] # 0x29b2 (en: 'empty set with small circle above') + - "⦳": [T: "den tomme mengden med høyrepil over"] # 0x29b3 (en: 'empty set with right arrow above') + - "⦴": [T: "den tomme mengden med venstrepil over"] # 0x29b4 (en: 'empty set with left arrow above') + - "⦵": [T: "sirkel med horisontal strek"] # 0x29b5 (en: 'circle with horizontal bar') + - "⦶": [T: "sirkel med vertikal strek"] # 0x29b6 (SRE: 'vertikalt streck i cirkel') + - "⦷": [T: "parallell i sirkel"] # 0x29b7 (en: 'circled parallel') + - "⦸": [T: "sirkel med omvendt skråstrek"] # 0x29b8 (en: 'circled reverse solidus', google: 'circled reverse solidus') + - "⦹": [T: "vinkelrett i sirkel"] # 0x29b9 (en: 'circled perpendicular') + - "⦺": [T: "sirkel delt med horisontal strek og øvre del delt med vertikal strek"] # 0x29ba (en: 'circled divided by horizontal bar and top half divided by vertical bar', google: 'cirklade dividerat med horisontell stång och den övre halvan dividerad med vertikal stång') + - "⦻": [T: "sirkel med x"] # 0x29bb (en: 'circle with superimposed x') + - "⦼": [T: "sirkel med divisjon rotert mot klokken"] # 0x29bc (en: 'circled anticlockwise rotated division sign') + - "⦽": [T: "oppoverpil gjennom sirkel"] # 0x29bd (en: 'up arrow through circle', google: 'upp pilen genom cirkeln') + - "⦾": [T: "hvitt punkt i sirkel"] # 0x29be (en: 'circled white bullet') + - "⦿": [T: "punkt i sirkel"] # 0x29bf (en: 'circled bullet') + - "⧀": [T: "mindre enn i sirkel"] # 0x29c0 (en: 'circled less than') + - "⧁": [T: "større enn i sirkel"] # 0x29c1 (en: 'circled greater than') + - "⧂": [T: "sirkel med liten sirkel til høyre"] # 0x29c2 (en: 'circle with small circle to the right') + - "⧃": [T: "sirkel med to horisontale streker til høyre"] # 0x29c3 (en: 'circle with two horizontal strokes to the right') + - "⧄": [T: "kvadrat med diagonal oppover"] # 0x29c4 (en: 'squared rising diagonal slash') + - "⧅": [T: "kvadrat med diagonal nedover"] # 0x29c5 (en: 'squared falling diagonal slash') + - "⧆": [T: "asterisk i kvadrat"] # 0x29c6 (en: 'squared asterisk', google: 'kvadratisk asterisk') + - "⧇": [T: "liten sirkel i kvadrat"] # 0x29c7 (en: 'squared small circle', google: 'kvadrat liten cirkel') + - "⧈": [T: "kvadrat i kvadrat"] # 0x29c8 (en: 'squared square', google: 'squared square') + - "⧉": [T: "to sammenføyde kvadrat"] # 0x29c9 (en: 'two joined squares') + - "⧊": [T: "trekant med prikk over"] # 0x29ca (en: 'triangle with dot above', google: 'triangel med prick ovan') + - "⧋": [T: "trekant med strek under"] # 0x29cb (en: 'triangle with underbar', google: 'triangel med underbar') + - "⧌": [T: "trekant med s"] # 0x29cc (en: 's in triangle') + - "⧍": [T: "trekant med seriffer på bunnen"] # 0x29cd (en: 'triangle with serifs at bottom') + - "⧎": [T: "høyre trekant over venstre trekant"] # 0x29ce (en: 'right triangle above left triangle') + - "⧏": [T: "venstre trekant ved siden av vertikal strek"] # 0x29cf (en: 'left triangle beside vertical bar') + - "⧐": [T: "vertikal strek ved siden av høyre trekant"] # 0x29d0 (en: 'vertical bar beside right triangle') + - "⧑": [T: "sløyfe med venstre halvdel fylt"] # 0x29d1 (en: 'bowtie with left half black', google: 'bowtie med vänster halva svart') + - "⧒": [T: "sløyfe med høyre halvdel fylt"] # 0x29d2 (en: 'bowtie with right half black', google: 'bowtie med höger halv svart') + - "⧓": [T: "fylt sløyfe"] # 0x29d3 (en: 'black bowtie', google: 'svart bowtie') + - "⧔": [T: "sløyfe med venstre halvdel fylt og høyre halvdel åpen"] # 0x29d4 (en: 'times with left half black', google: 'gånger med vänster halva svart') + - "⧕": [T: "sløyfe med venstre halvdel åpen og høyre halvdel fylt"] # 0x29d5 (en: 'times with right half black', google: 'gånger med höger halv svart') + - "⧖": [T: "hvitt timeglass"] # 0x29d6 (en: 'white hourglass', google: 'vit timglas') + - "⧗": [T: "fylt timeglass"] # 0x29d7 (en: 'black hourglass') + - "⧘": [T: "venstre sikksakk gjerde"] # 0x29d8 (en: 'left wiggly fence', google: 'vänster wiggly staket') + - "⧙": [T: "høyre sikksakk gjerde"] # 0x29d9 (en: 'right wiggly fence', google: 'höger vinglt staket') + - "⧚": [T: "dobbelt venstre sikksakk gjerde"] # 0x29da (en: 'left double wiggly fence', MathPlayer: 'left double wiggly fence', google: 'vänster dubbel wiggly staket') + - "⧛": [T: "dobbelt høyre sikksakk gjerde"] # 0x29db (en: 'right double wiggly fence', MathPlayer: 'right double wiggly fence', google: 'höger dubbel wiggly staket') + - "⧜": [T: "ufullstendig uendelig"] # 0x29dc (en: 'incomplete infinity') + - "⧝": [T: "bånd over uendelighetstegn"] # 0x29dd (en: 'tie over infinity', google: 'bind över oändligheten') + - "⧞": [T: "uendelig med vertikal strek"] # 0x29de (en: 'infinity negated with vertical bar') + - "⧟": [T: "tosidig multimap"] # 0x29df (en: 'double-ended multimap', google: 'dubbel-sluten multimap') + - "⧠": [T: "kvadrat med omriss"] # 0x29e0 (en: 'square with contoured outline', google: 'fyrkantig med konturerad kontur') + - "⧡": [T: "øker som"] # 0x29e1 (en: 'increases as') + - "⧢": [T: "shuffle-produkt"] # 0x29e2 (en: 'shuffle product', google: 'shuffle -produkt') + - "⧣": [T: "likhetstegn og skråstilt parallell"] # 0x29e3 (en: 'equals sign and slanted parallel') + - "⧤": [T: "likhetstegn og skråstilt parallell med tilde over"] # 0x29e4 (en: 'equals sign and slanted parallel with tilde above') + - "⧥": [T: "identisk med og skråstilt parallell"] # 0x29e5 (en: 'identical to and slanted parallel') + - "⧦": [T: "gleich stark"] # 0x29e6 + - "⧧": [T: "termodynamisk"] # 0x29e7 (en: 'thermodynamic', google: 'termodynamisk') + - "⧨": [T: "trekant nedover venstre halvdel fylt"] # 0x29e8 (en: 'down pointing triangle with left half black', google: 'ner pekande triangel med vänster halvsvart') + - "⧩": [T: "trekant nedover høyre halvdel fylt"] # 0x29e9 (en: 'down pointing triangle with right half black', google: 'ner pekande triangel med höger halvsvart') + - "⧪": [T: "fylt diamant med pil ned"] # 0x29ea (en: 'black diamond with down arrow', google: 'svart diamant med nedpil') + - "⧫": [T: "fylt rombe"] # 0x29eb (en: 'black lozenge') + - "⧬": [T: "sirkel med pil ned"] # 0x29ec (en: 'white circle with down arrow', google: 'vit cirkel med nedpilen') + - "⧭": [T: "fylt sirkel med pil ned"] # 0x29ed (en: 'black circle with down arrow', google: 'svart cirkel med nedpilen') + - "⧮": [T: "firkant med utstikkere"] # 0x29ee (en: 'error-barred white square', google: 'fel-spärrvit fyrkant') + - "⧯": [T: "fylt firkant med utstikkere"] # 0x29ef (en: 'error-barred black square', google: 'fel-barred black square') + - "⧰": [T: "diamant med utstikkere"] # 0x29f0 (en: 'error-barred white diamond', google: 'fel-spärrad vit diamant') + - "⧱": [T: "fylt diamant med utstikkere"] # 0x29f1 (en: 'error-barred black diamond', google: 'fel-barred black diamond') + - "⧲": [T: "sirkel med utstikkere"] # 0x29f2 (en: 'error-barred white circle', google: 'fel-spärrad vit cirkel') + - "⧳": [T: "fylt sirkel med utstikkere"] # 0x29f3 (en: 'error-barred black circle', google: 'fel-barred black circle') + - "⧴": [T: "kolon høyrepil"] # 0x29f4 (en: 'rule-delayed', MathPlayer: 'rule delayed', google: 'regelförsenad') + - "⧵": [T: "omvendt skråstrek"] # 0x29f5 (en: 'reverse solidus operator', google: 'omvänd solidus -operatör') + - "⧶": [T: "skråstrek med strek over"] # 0x29f6 (en: 'solidus with overbar') + - "⧷": [T: "omvendt skråstrek med horisontal strek"] # 0x29f7 (en: 'reverse solidus with horizontal stroke', google: 'omvänd solidus med horisontellt slag') + - "⧸": [T: "stor skråstrek"] # 0x29f8 (en: 'big solidus', google: 'big solidus') + - "⧹": [T: "stor omvendt skråstrek"] # 0x29f9 (en: 'big reverse solidus', google: 'big reverse solidus') + - "⧺": [T: "dobbel pluss"] # 0x29fa (en: 'double plus', google: 'dubbel plus') + - "⧻": [T: "trippel pluss"] # 0x29fb (en: 'triple plus', google: 'trippel plus') + - "⧼": [T: "venstre buet vinkelparentes"] # 0x29fc (en: 'left pointing curved angle bracket', google: 'vänster pekande krökt vinkelfäste') + - "⧽": [T: "høyre buet vinkelparentes"] # 0x29fd (en: 'right pointing curved angle bracket', google: 'höger pekande krökt vinkelfäste') + # SWEDISH: kept English tiny & miny but changed spelling to get pronunciation right + - "⧾": [T: "tainy"] # 0x29fe (en: 'tiny', google: 'mycket liten') + - "⧿": [T: "mainy"] # 0x29ff (en: 'miny', google: 'miny') + #-------------------------------------------------------------------------------------------------------------- + # Supplemental Mathematical operators OK + - "⨀": [T: "dot-operator i sirkel"] # 0x2a00 (en: 'circled dot operator', google: 'circled dot operator') + - "⨁": [T: "pluss i sirkel"] # 0x2a01 (en: 'circled plus operator', google: 'circled plus operator') + - "⨂": [T: "multiplikasjon i sirkel"] # 0x2a02 (en: 'circled times operator', google: 'circled times operator') + - "⨃": [T: "union med prikk"] # 0x2a03 (en: 'union operator with dot', google: 'unionoperatör med dot') + - "⨄": [T: "union med pluss"] # 0x2a04 (en: 'union operator with plus', google: 'unionoperatör med plus') + - "⨅": [T: "kvadratisk snitt-operator"] # 0x2a05 (en: 'square intersection operator', google: 'square -korsningsoperatör') + - "⨆": [T: "kvadratisk union-operator"] # 0x2a06 (en: 'square union operator', google: 'square union operator') + - "⨇": [T: "to logiske og"] # 0x2a07 (en: 'two logical and operator', google: 'två logiska och operatörer') + - "⨈": [T: "to logiske eller"] # 0x2a08 (en: 'two logical or operator', google: 'två logiska eller operatörer') + - "⨉": [T: "ganger"] # 0x2a09 (en: 'times operator', google: 'times operator') + - "⨊": [T: "modulo to sum"] # 0x2a0a (en: 'modulo two sum', google: 'modulo två summa') + - "⨋": [T: "sum med integral"] # 0x2a0b (en: 'summation with integral', google: 'summering med integrerad') + - "⨌": [T: "firedobbelt integral"] # 0x2a0c (en: 'quadruple integral operator') + - "⨍": [T: "integral med horisontal strek"] # 0x2a0d (en: 'finite part integral') + - "⨎": [T: "integral med dobbel horisontal strek"] # 0x2a0e (en: 'integral with double stroke', google: 'integrerad med dubbelslag') + - "⨏": [T: "integral med skråstrek"] # 0x2a0f (en: 'integral average with slash', google: 'integrerat medelvärde med snedstreck') + - "⨐": [T: "sirkulasjons-funksjon"] # 0x2a10 (en: 'circulation function') + - "⨑": [T: "integrasjon mot klokka"] # 0x2a11 (en: 'anticlockwise integration') + - "⨒": [T: "linjeintegral med rektangulær vei rundt pol"] # 0x2a12 (en: 'line integration with rectangular path around pole') + - "⨓": [T: "linjeintegral med halvsirkel-vei rundt pol"] # 0x2a13 (en: 'line integration with semicircular path around pole') + - "⨔": [T: "linjeintegral eksklusiv polen"] # 0x2a14 (en: 'line integration not including the pole', MathPlayer: 'line integration not including the pole', google: 'linjeintegration inkluderar inte polen') + - "⨕": [T: "integral rund punkt-operator"] # 0x2a15 + - "⨖": [T: "integral med firkant"] # 0x2a16 + - "⨗": [T: "integral med venstrepil med krok"] # 0x2a17 (en: 'integral with leftwards arrow with hook') + - "⨘": [T: "integral med multiplikasjonstegn"] # 0x2a18 (en: 'integral with times sign', google: 'integrerad med times sign') + - "⨙": [T: "integral med snitt"] # 0x2a19 (en: 'integral with intersection', google: 'integrerad med korsning') + - "⨚": [T: "integral med union"] # 0x2a1a (en: 'integral with union', google: 'integrerad med unionen') + - "⨛": [T: "integral med horisontal strek over"] # 0x2a1b (en: 'integral with overbar', google: 'integrerad med overbar') + - "⨜": [T: "integral med horisontal strek under"] # 0x2a1c (en: 'integral with underbar', google: 'integrerad med underbar') + - "⨝": [T: "join"] # 0x2a1d (en: 'join', google: 'ansluta sig') + - "⨞": [T: "stor venstre trekant"] # 0x2a1e (en: 'large left triangle operator', google: 'stor vänster triangeloperatör') + - "⨟": [T: "skjema-sammensetning z-notasjon"] # 0x2a1f (en: 'z notation schema composition', google: 'z notationsschema komposition') + - "⨠": [T: "skjema-sluse z-notasjon"] # 0x2a20 (en: 'z notation schema piping', google: 'z notation schema piping') + - "⨡": [T: "skjema-projeksjon z-notasjon"] # 0x2a21 (en: 'z notation schema projection', google: 'z notation schema projection') + - "⨢": [T: "pluss med sirkel over"] # 0x2a22 (en: 'plus sign with circle above', MathPlayer: 'plustecken med ring över', google: 'plus skylt med cirkel ovan') + - "⨣": [T: "pluss med cirkumfleks over"] # 0x2a23 (en: 'plus sign with circumflex accent above', MathPlayer: 'plustecken med cirkumflex accent över', google: 'plus -tecken med circumflex -accent ovan') + - "⨤": [T: "pluss med tilde over"] # 0x2a24 (en: 'plus sign with tilde above') + - "⨥": [T: "pluss med prikk under"] # 0x2a25 (en: 'plus sign with dot below', MathPlayer: 'plustecken med punkt under', google: 'plus skylt med dot nedan') + - "⨦": [T: "pluss med tilde under"] # 0x2a26 (en: 'plus sign with tilde below') + - "⨧": [T: "pluss med nedre indeks to"] # 0x2a27 (en: 'plus sign with subscript two', MathPlayer: 'plustecken med index två', google: 'plus skylt med prenumeration två') + - "⨨": [T: "pluss med fylt trekant"] # 0x2a28 (en: 'plus sign with black triangle', google: 'plus skylt med svart triangel') + - "⨩": [T: "minus med komma over"] # 0x2a29 (en: 'minus sign with comma above', MathPlayer: 'minustecken med komma över', google: 'minus tecken med komma ovan') + - "⨪": [T: "minus med prikk under"] # 0x2a2a (en: 'minus sign with dot below', MathPlayer: 'minustecken med punkt under', google: 'minus tecken med prick nedan') + - "⨫": [T: "minus med fallende prikker"] # 0x2a2b (en: 'minus sign with falling dots', google: 'minus tecken med fallande prickar') + - "⨬": [T: "minus med stigende prikker"] # 0x2a2c (en: 'minus sign with rising dots', google: 'minus tecken med stigande prickar') + - "⨭": [T: "pluss i venstre halvsirkel"] # 0x2a2d (en: 'plus sign in left half circle', MathPlayer: 'plustecken i vänster halvcirkel', google: 'plus logga in vänster halva cirkeln') + - "⨮": [T: "pluss i høyre halvsirkel"] # 0x2a2e (en: 'plus sign in right half circle', MathPlayer: 'plustecken i höger halvcirkel', google: 'plus logga in höger halv cirkel') + - "⨯": # 0x2a2f + - test: + if: "$Verbosity='Terse'" + then: [T: "kryss"] + else: [T: "kryssprodukt"] + - "⨰": [T: "multiplikasjon med prikk over"] # 0x2a30 (en: 'multiplication sign with dot above') + - "⨱": [T: "multiplikasjon med strek under"] # 0x2a31 (en: 'multiplication sign with underbar') + - "⨲": [T: "semi-direkte produkt med lukket bunn"] # 0x2a32 (en: 'semidirect product with bottom closed', google: 'semidirect -produkt med botten stängd') + - "⨳": [T: "smash-produkt"] # 0x2a33 (en: 'smash product', MathPlayer: 'smash product', google: 'krossa produkten') + - "⨴": [T: "multiplikasjon i venstre halvsirkel"] # 0x2a34 (en: 'multiplication sign in left half circle') + - "⨵": [T: "multiplikasjon i høyre halvsirkel"] # 0x2a35 (en: 'multiplication sign in right half circle') + - "⨶": [T: "multiplikasjon i sirkel med cirkumfleks"] # 0x2a36 (en: 'circled multiplication sign with circumflex accent') + - "⨷": [T: "multiplikasjon i dobbel sirkel"] # 0x2a37 (en: 'multiplication sign in double circle') + - "⨸": [T: "divisjon i sirkel"] # 0x2a38 + - "⨹": [T: "pluss i trekant"] # 0x2a39 (en: 'plus sign in triangle', MathPlayer: 'plustecken i triangel', google: 'plus inloggning av triangeln') + - "⨺": [T: "minus i trekant"] # 0x2a3a (en: 'minus sign in triangle', MathPlayer: 'minustecken i triangel', google: 'minus logga in triangel') + - "⨻": [T: "multiplikasjon i trekant"] # 0x2a3b (en: 'multiplication sign in triangle') + - "⨼": [T: "interior product"] # 0x2a3c (en: 'interior product', MathPlayer: 'interior product', google: 'interiörprodukt') + - "⨽": [T: "invers interior product"] # 0x2a3d (en: 'righthand interior product', google: 'högra interiörprodukt') + - "⨾": [T: "relasjonssammensetning z-notasjon"] # 0x2a3e + - "⨿": [T: "koprodukt"] # 0x2a3f (en: 'amalgamation or coproduct', MathPlayer: 'amalgamation or coproduct', google: 'amalgamation eller coprodukt') + - "⩀": [T: "snitt med prikk"] # 0x2a40 (en: 'intersection with dot') + - "⩁": [T: "union med minus"] # 0x2a41 (en: 'union with minus sign', google: 'union med minus tecken') + - "⩂": [T: "union med horisontal strek over"] # 0x2a42 (en: 'union with overbar') + - "⩃": [T: "snitt med horisontal strek over"] # 0x2a43 (en: 'intersection with overbar') + - "⩄": [T: "snitt med logisk og"] # 0x2a44 (en: 'intersection with logical and') + - "⩅": [T: "union med logisk eller"] # 0x2a45 (en: 'union with logical or') + - "⩆": [T: "union over snitt"] # 0x2a46 (en: 'union above intersection') + - "⩇": [T: "snitt over union"] # 0x2a47 (en: 'intersection above union') + - "⩈": [T: "union over strek over snitt"] # 0x2a48 (en: 'union above bar above intersection') + - "⩉": [T: "snitt over strek over union"] # 0x2a49 (en: 'intersection above bar above union') + - "⩊": [T: "union ved siden av og sammensatt med union"] # 0x2a4a (en: 'union beside and joined with union') + - "⩋": [T: "snitt ved siden av og sammensatt med snitt"] # 0x2a4b (en: 'intersection beside and joined with intersection') + - "⩌": [T: "lukket union med seriffer"] # 0x2a4c (en: 'closed union with serifs') + - "⩍": [T: "lukket snitt med seriffer"] # 0x2a4d (en: 'closed intersection with serifs') + - "⩎": [T: "dobbelt kvadratisk snitt"] # 0x2a4e (en: 'double square intersection', google: 'korsning av dubbel kvadrat') + - "⩏": [T: "dobbel kvadratisk union"] # 0x2a4f (en: 'double square union', google: 'double square union') + - "⩐": [T: "lukket union med seriffer og smash-produkt"] # 0x2a50 (en: 'closed union with serifs and smash product') + - "⩑": [T: "logisk og med prikk over"] # 0x2a51 (en: 'logical and with dot above', google: 'logisk och med punkt ovan') + - "⩒": [T: "logisk eller med prikk over"] # 0x2a52 (en: 'logical or with dot above', google: 'logisk eller med punkt ovan') + - "⩓": [T: "dobbel logisk og"] # 0x2a53 (en: 'double logical and') + - "⩔": [T: "dobbel logisk eller"] # 0x2a54 (en: 'double logical or') + - "⩕": [T: "to kryssende logiske og"] # 0x2a55 (en: 'two intersecting logical and') + - "⩖": [T: "to kryssende logiske eller"] # 0x2a56 (en: 'two intersecting logical or') + - "⩗": [T: "skrånende eller"] # 0x2a57 (en: 'sloping large or') + - "⩘": [T: "skrånende og"] # 0x2a58 (en: 'sloping large and') + - "⩙": [T: "logisk eller overlapper logisk og"] # 0x2a59 (en: 'logical or overlapping logical and', google: 'logisk eller överlappande logisk och') + - "⩚": [T: "logisk og med vertikal strek"] # 0x2a5a (en: 'logical and with middle stem') + - "⩛": [T: "logisk eller med vertikal strek"] # 0x2a5b (en: 'logical or with middle stem') + - "⩜": [T: "logisk og med horisontal strek"] # 0x2a5c (en: 'logical and with horizontal dash') + - "⩝": [T: "logisk eller med horisontal strek"] # 0x2a5d (en: 'logical or with horizontal dash') + - "⩞": [T: "logisk og med dobbel horisontal strek over"] # 0x2a5e (en: 'logical and with double overbar', google: 'logiskt och med dubbelt överbar') + - "⩟": [T: "logisk og med understrek"] # 0x2a5f (en: 'logical and with underbar') + - "⩠": [T: "logisk og med dobbel understrek"] # 0x2a60 (en: 'logical and with double underbar', google: 'logisk och med dubbel underbar') + - "⩡": [T: "liten v med understrek"] # 0x2a61 (en: 'small vee with underbar', google: 'liten vee med underbar') + - "⩢": [T: "logisk eller med dobbel horisontal strek over"] # 0x2a62 (en: 'logical or with double overbar', google: 'logisk eller med dubbel överbar') + - "⩣": [T: "logisk eller med dobbel understrek"] # 0x2a63 (en: 'logical or with double underbar', google: 'logisk eller med dubbel underbar') + - "⩤": [T: "definisjonsmengde antibegrensning z-notasjon"] # 0x2a64 (en: 'z notation domain antirestriction', google: 'z notation domain antirestriction') + - "⩥": [T: "verdimengde antibegrensning z-notasjon"] # 0x2a65 (en: 'z notation range antirestriction', google: 'z notation range antirestriction') + - "⩦": [T: "lik med prikk under"] # 0x2a66 (en: 'equals sign with dot below') + - "⩧": [T: "prikk over identisk med"] # 0x2a67 (en: 'identical with dot above', google: 'identisk med prick ovan') + - "⩨": [T: "trippel horisontal strek med dobbel vertikal strek"] # 0x2a68 (en: 'triple horizontal bar with double vertical stroke', google: 'trippel horisontell stång med dubbel vertikal stroke') + - "⩩": [T: "trippel horisontal strek med trippel vertikal strek"] # 0x2a69 (en: 'triple horizontal bar with triple vertical stroke', google: 'trippel horisontell stång med trippel vertikal stroke') + - "⩪": [T: "tilde med prikk over"] # 0x2a6a (en: 'tilde operator with dot above') + - "⩫": [T: "tilde med stigende prikker"] # 0x2a6b (en: 'tilde operator with rising dots', google: 'tilde -operatör med stigande prickar') + - "⩬": [T: "asymptotisk lik over tilde"] # 0x2a6c (en: 'similar minus similar', google: 'liknande minus liknande') + - "⩭": [T: "tilnærmet lik med prikk over"] # 0x2a6d (en: 'congruent with dot above') + - "⩮": [T: "lik med asterisk over"] # 0x2a6e (en: 'equals with asterisk', google: 'lika med asterisk') + - "⩯": [T: "tilnærmet lik med cirkumfleks"] # 0x2a6f (en: 'almost equal to with circumflex accent') + - "⩰": [T: "tilnærmet lik eller lik"] # 0x2a70 (en: 'approximately equal to or equal to', google: 'ungefär lika med eller lika med') + - "⩱": [T: "lik over pluss"] # 0x2a71 (en: 'equals sign above plus sign') + - "⩲": [T: "pluss over lik"] # 0x2a72 (en: 'plus sign above equals sign') + - "⩳": [T: "lik over tilde"] # 0x2a73 (en: 'equals sign above tilde operator') + - "⩴": [T: "dobbelt kolon lik"] # 0x2a74 (en: 'double colon equal') + - "⩵": [T: "dobbelt likhetstegn"] # 0x2a75 (en: 'two consecutive equals signs') + - "⩶": [T: "trippelt likhetstegn"] # 0x2a76 (en: 'three consecutive equals signs', google: 'tre på varandra följande tecken') + - "⩷": [T: "lik med to prikker over og to prikker under"] # 0x2a77 (en: 'equals sign with two dots above and two dots below') + - "⩸": [T: "fire prikker over identisk med"] # 0x2a78 (en: 'equivalent with four dots above') + - "⩹": [T: "mindre enn med sirkel i"] # 0x2a79 (en: 'less than with circle inside') + - "⩺": [T: "større enn med sirkel i"] # 0x2a7a (en: 'greater than with circle inside') + - "⩻": [T: "mindre enn med spørsmålstegn over"] # 0x2a7b (en: 'less than with question mark above') + - "⩼": [T: "større enn med spørsmålstegn over"] # 0x2a7c (en: 'greater than with question mark above') + - "⩽": [T: "mindre enn eller lik"] # 0x2a7d (en: 'less than or slanted equal to') + - "⩾": [T: "større enn eller lik"] # 0x2a7e (en: 'greater than or slanted equal to') + - "⩿": [T: "mindre enn eller lik med prikk"] # 0x2a7f (en: 'less than or slanted equal to with dot inside') + - "⪀": [T: "større enn eller lik med prikk"] # 0x2a80 (en: 'greater than or slanted equal to with dot inside') + - "⪁": [T: "mindre enn eller lik med prikk over til venstre"] # 0x2a81 (en: 'less than or slanted equal to with dot above') + - "⪂": [T: "større enn eller lik med prikk over til høyre"] # 0x2a82 (en: 'greater than or slanted equal to with dot above') + - "⪃": [T: "mindre enn eller lik med prikk over til høyre"] # 0x2a83 (en: 'less than or slanted equal to with dot above right') + - "⪄": [T: "større enn eller lik med prikk over til venstre"] # 0x2a84 (en: 'greater than or slanted equal to with dot above left') + - "⪅": [T: "mindre enn eller tilnærmet lik"] # 0x2a85 (en: 'less than or approximate', google: 'mindre än eller ungefärligt') + - "⪆": [T: "større enn eller tilnærmet lik"] # 0x2a86 (en: 'greater than or approximate', google: 'större än eller ungefärligt') + - "⪇": [T: "mindre enn men ikke lik"] # 0x2a87 (en: 'less than and single line not equal to', google: 'mindre än och enstaka linjer inte lika med') + - "⪈": [T: "større enn men ikke lik"] # 0x2a88 (en: 'greater than and single line not equal to', google: 'större än och enstaka linjer inte lika med') + - "⪉": [T: "mindre enn men ikke tilnærmet lik"] # 0x2a89 (en: 'less than and not approximate') + - "⪊": [T: "større enn men ikke tilnærmet lik"] # 0x2a8a (en: 'greater than and not approximate') + - "⪋": [T: "mindre enn over lik over større enn"] # 0x2a8b (en: 'less than above double line equal above greater than', google: 'mindre än över dubbel linje lika över större än') + - "⪌": [T: "større enn over lik over mindre enn"] # 0x2a8c (en: 'greater than above double line equal above less than', google: 'större än över dubbel linje lika över mindre än') + - "⪍": [T: "mindre enn over asymptotisk lik"] # 0x2a8d (en: 'less than above similar or equal') + - "⪎": [T: "større enn over asymptotisk lik"] # 0x2a8e (en: 'greater than above similar or equal') + - "⪏": [T: "mindre enn over tilde over større enn"] # 0x2a8f (en: 'less than above similar above greater than') + - "⪐": [T: "større enn over tilde over mindre enn"] # 0x2a90 (en: 'greater than above similar above less than') + - "⪑": [T: "mindre enn over større enn over lik"] # 0x2a91 (en: 'less than above greater than above double line equal') + - "⪒": [T: "større enn over mindre enn over lik"] # 0x2a92 (en: 'greater than above less than above double line equal') + - "⪓": [T: "mindre enn eller lik over større enn eller lik"] # 0x2a93 (en: 'less than above slanted equal above greater than above slanted equal') + - "⪔": [T: "større enn eller lik over mindre enn eller lik"] # 0x2a94 (en: 'greater than above slanted equal above less than above slanted equal') + - "⪕": [T: "lik eller mindre enn"] # 0x2a95 (en: 'slanted equal to or less than', google: 'lutt lika med eller mindre än') + - "⪖": [T: "lik eller større enn"] # 0x2a96 (en: 'slanted equal to or greater than', google: 'lutt lika med eller större än') + - "⪗": [T: "lik eller mindre enn med prikk"] # 0x2a97 (en: 'slanted equal to or less than with dot inside') + - "⪘": [T: "lik eller større enn med prikk"] # 0x2a98 (en: 'slanted equal to or greater than with dot inside') + - "⪙": [T: "lik eller mindre enn"] # 0x2a99 (en: 'double line equal to or less than', MathPlayer: 'equal (dubbel) over less than', google: 'dubbel linje lika med eller mindre än') + - "⪚": [T: "lik eller større enn"] # 0x2a9a (en: 'double line equal to or greater than') + - "⪛": [T: "lik eller mindre enn"] # 0x2a9b (en: 'double line slanted equal to or less than', google: 'dubbel linje lutad lika med eller mindre än') + - "⪜": [T: "lik eller større enn"] # 0x2a9c (en: 'double line slanted equal to or greater than', google: 'dubbel linje lutad lika med eller större än') + - "⪝": [T: "tilnærmet lik eller mindre enn"] # 0x2a9d (en: 'similar or less than') + - "⪞": [T: "tilnærmet lik eller større enn"] # 0x2a9e (en: 'similar or greater than') + - "⪟": [T: "tilnærmet lik over mindre enn over lik"] # 0x2a9f (en: 'similar above less than above equals sign') + - "⪠": [T: "tilnærmet lik over større enn over lik"] # 0x2aa0 (en: 'similar above greater than above equals sign') + - "⪡": [T: "dobbel mindre enn"] # 0x2aa1 (en: 'double nested less than') + - "⪢": [T: "dobbel større enn"] # 0x2aa2 (en: 'double nested greater than') + - "⪣": [T: "dobbel mindre enn med strek under"] # 0x2aa3 (en: 'double nested less than with underbar', google: 'dubbel kapslad mindre än med underbar') + - "⪤": [T: "større enn overlapper mindre enn"] # 0x2aa4 (en: 'greater than overlapping less than') + - "⪥": [T: "større enn ved siden av mindre enn"] # 0x2aa5 (en: 'greater than beside less than') + - "⪦": [T: "mindre enn lukket av kurve"] # 0x2aa6 (en: 'less than closed by curve') + - "⪧": [T: "større enn lukket av kurve"] # 0x2aa7 (en: 'greater than closed by curve') + - "⪨": [T: "mindre enn lukket av kurve over lik"] # 0x2aa8 (en: 'less than closed by curve above slanted equal') + - "⪩": [T: "større enn lukket av kurve over lik"] # 0x2aa9 (en: 'greater than closed by curve above slanted equal') + - "⪪": [T: "mindre enn"] # 0x2aaa (en: 'smaller than') + - "⪫": [T: "større enn"] # 0x2aab (en: 'larger than') + - "⪬": [T: "mindre enn eller lik"] # 0x2aac (en: 'smaller than or equal to') + - "⪭": [T: "større enn eller lik"] # 0x2aad (en: 'larger than or equal to') + - "⪮": [T: "lik med hump over"] # 0x2aae (en: 'equals sign with bumpy above', MathPlayer: 'difference between (grav accentnt)', google: 'är lika med tecken med ojämn ovan') + - "⪯": [T: "foregår over likhetsstrek"] # 0x2aaf (en: 'precedes above single line equals sign') + - "⪰": [T: "følger over likhetsstrek"] # 0x2ab0 (en: 'succeeds above single line equals sign', google: 'lyckas över enstaka linjen är lika med tecken') + - "⪱": [T: "foregår over utstrøket likhetsstrek"] # 0x2ab1 (en: 'precedes above single line not equal to', google: 'föregår över enstaka linjer som inte är lika med') + - "⪲": [T: "følger over utstrøket likhetsstrek"] # 0x2ab2 (en: 'succeeds above single line not equal to', google: 'lyckas över enstaka linjer som inte är lika med') + - "⪳": [T: "foregår over lik"] # 0x2ab3 (en: 'precedes above equals sign', google: 'föregår över lika tecken') + - "⪴": [T: "følger over lik"] # 0x2ab4 (en: 'succeeds above equals sign', google: 'lyckas över lika tecken') + - "⪵": [T: "foregår over ikke lik"] # 0x2ab5 (en: 'precedes above not equal to') + - "⪶": [T: "følger over ikke lik"] # 0x2ab6 (en: 'succeeds above not equal to') + - "⪷": [T: "foregår over tilnærmet lik"] # 0x2ab7 (en: 'precedes above almost equal to', google: 'föregår över nästan lika med') + - "⪸": [T: "følger over tilnærmet lik"] # 0x2ab8 (en: 'succeeds above almost equal to', google: 'lyckas över nästan lika med') + - "⪹": [T: "foregår over ikke tilnærmet lik"] # 0x2ab9 (en: 'precedes above not almost equal to', google: 'föregår ovan inte nästan lika med') + - "⪺": [T: "følger over ikke tilnærmet lik"] # 0x2aba (en: 'succeeds above not almost equal to', google: 'lyckas ovan inte nästan lika med') + - "⪻": [T: "dobbel foregår"] # 0x2abb (en: 'double precedes') + - "⪼": [T: "dobbel følger"] # 0x2abc (en: 'double succeeds') + - "⪽": [T: "delmengde med prikk"] # 0x2abd (en: 'subset with dot') + - "⪾": [T: "overmengde med prikk"] # 0x2abe (en: 'superset with dot') + - "⪿": [T: "delmengde med pluss under"] # 0x2abf (en: 'subset with plus sign below', MathPlayer: 'delmängd med plustecken under', google: 'delmängd med plus -skylt nedan') + - "⫀": [T: "overmengde med pluss under"] # 0x2ac0 (en: 'superset with plus sign below', MathPlayer: 'delmängd med plustecken under', google: 'superset med plus -skylt nedan') + - "⫁": [T: "delmengde med multiplikasjon under"] # 0x2ac1 (en: 'subset with multiplication sign below') + - "⫂": [T: "overmengde med multiplikasjon under"] # 0x2ac2 (en: 'superset with multiplication sign below') + - "⫃": [T: "delmengde av eller lik med prikk over"] # 0x2ac3 (en: 'subset of or equal to with dot above') + - "⫄": [T: "overmengde av eller lik med prikk over"] # 0x2ac4 (en: 'superset of or equal to with dot above') + - "⫅": [T: "delmenge av over lik"] # 0x2ac5 (en: 'subset of above equals sign', google: 'undergruppen ovan är lika med tecken') + - "⫆": [T: "overmengde av over lik"] # 0x2ac6 (en: 'superset of above equals sign', google: 'superset av ovan är lika med tecken') + - "⫇": [T: "delmengde av over tilde"] # 0x2ac7 (en: 'subset of above tilde operator') + - "⫈": [T: "overmengde av over tilde"] # 0x2ac8 (en: 'superset of above tilde operator') + - "⫉": [T: "delmengde av over tilnærmet lik"] # 0x2ac9 (en: 'subset of above almost equal to', google: 'delmängd över nästan lika med') + - "⫊": [T: "overmengde av over tilnærmet lik"] # 0x2aca (en: 'superset of above almost equal to', google: 'superset över nästan lika med') + - "⫋": [T: "delmengde av over ikke lik"] # 0x2acb (en: 'subset above not equal to', google: 'delmängd ovan inte lika med') + - "⫌": [T: "overmengde av over ikke lik"] # 0x2acc (en: 'superset of above not equal to', google: 'superset av ovan inte lika med') + - "⫍": [T: "venstre kvadratisk åpen boks"] # 0x2acd (en: 'square left open box operator', google: 'square left open box operator') + - "⫎": [T: "høyre kvadratisk åpen boks"] # 0x2ace (en: 'square right open box operator', google: 'square right open box operator') + - "⫏": [T: "lukket delmengde"] # 0x2acf (en: 'closed subset') + - "⫐": [T: "lukket overmengde"] # 0x2ad0 (en: 'closed superset') + - "⫑": [T: "lukket delmengde eller lik"] # 0x2ad1 (en: 'closed subset or equal to') + - "⫒": [T: "lukket overmengde eller lik"] # 0x2ad2 (en: 'closed superset or equal to') + - "⫓": [T: "delmengde over overmengde"] # 0x2ad3 (en: 'subset above superset') + - "⫔": [T: "overmengde over delmengde"] # 0x2ad4 (en: 'superset above subset') + - "⫕": [T: "delmengde over delmengde"] # 0x2ad5 (en: 'subset above subset') + - "⫖": [T: "overmengde over overmengde"] # 0x2ad6 (en: 'superset above superset') + - "⫗": [T: "overmengde ved siden av delmengde"] # 0x2ad7 (en: 'superset beside subset') + - "⫘": [T: "overmengde ved siden av og sammenføyd med delmengde"] # 0x2ad8 (en: 'superset beside and joined by dash with subset') + - "⫙": [T: "tilhører med åpning nedover"] # 0x2ad9 (en: 'element of opening downwards') + - "⫚": [T: "høygaffel med t øverst"] # 0x2ada (en: 'pitchfork with tee top') + - "⫛": [T: "tverrgående snitt"] # 0x2adb (en: 'transversal intersection') + - "⫝̸": [T: "avhengig"] # 0x2adc (en: 'forking', google: 'gaffel') + - "⫝": [T: "uavhengig"] # 0x2add (en: 'nonforking', google: 'icke -förflyttning') + - "⫞": [T: "kort venstre dreiekors"] # 0x2ade (en: 'short left tack', google: 'kort vänster tack') + - "⫟": [T: "kort nedoverrotert dreiekors"] # 0x2adf (en: 'short down tack', google: 'kort ner') + - "⫠": [T: "kort oppoverrotert dreiekors"] # 0x2ae0 (en: 'short up tack', google: 'kort upp tack') + - "⫡": [T: "vinkelrett med s"] # 0x2ae1 (en: 'perpendicular with s', google: 'vinkelrätt med s') + - "⫢": [T: "vertikal strek trippelt høyre dreiekors"] # 0x2ae2 (en: 'vertical bar triple right turnstile', google: 'vertikal bar trippel höger turnstile') + - "⫣": [T: "dobbel vertikal strek venstre dreiekors"] # 0x2ae3 (en: 'double vertical bar left turnstile', google: 'dubbel vertikal stång vänster turnstile') + - "⫤": [T: "vertikal strek dobbelt venstre dreiekors"] # 0x2ae4 (en: 'vertical bar double left turnstile') + - "⫥": [T: "dobbel vertikal strek dobbelt venstre dreiekors"] # 0x2ae5 (en: 'double vertical bar double left turnstile', google: 'dubbel vertikal stång dubbel vänster vridstil') + - "⫦": [T: "dreiekors med vertikal strek"] # 0x2ae6 (en: 'long dash from left member of double vertical') + - "⫧": [T: "nedoverrotert kort dreiekors med horisontal strek over"] # 0x2ae7 (en: 'short down tack with overbar') + - "⫨": [T: "oppoverrotert kort dreiekors med horisontal strek under"] # 0x2ae8 (en: 'short up tack with underbar') + - "⫩": [T: "oppoverrotert kort dreiekors over nedoverrotert kort dreiekors"] # 0x2ae9 (en: 'short up tack above short down tack') + - "⫪": [T: "nedoverrotert dobbelt dreiekors"] # 0x2aea (en: 'double down tack', google: 'dubbel down tack') + - "⫫": [T: "oppoverrotert dobbelt dreiekors"] # 0x2aeb (en: 'double up tack') + - "⫬": [T: "dobbeltstreket ikke"] # 0x2aec (en: 'double stroke not sign') + - "⫭": [T: "omvendt dobbeltstreket ikke"] # 0x2aed (en: 'reversed double stroke not sign') + - "⫮": [T: "deler ikke med omvendt skråstrek"] # 0x2aee (en: 'does not divide with reversed negation slash') + - "⫯": [T: "vertikal strek med sirkel over"] # 0x2aef (en: 'vertical line with circle above') + - "⫰": [T: "vertikal strek med sirkel under"] # 0x2af0 (en: 'vertical line with circle below') + - "⫱": [T: "nedoverrotert dreiekors med sirkel under"] # 0x2af1 (en: 'down tack with circle below') + - "⫲": [T: "parallel med horisontal strek"] # 0x2af2 (en: 'parallel with horizontal stroke') + - "⫳": [T: "parallel med tilde"] # 0x2af3 (en: 'parallel with tilde operator') + - "⫴": [T: "trippel loddrett strek"] # 0x2af4 (en: 'triple vertical bar binary relation', google: 'trippel vertikal bar binär relation') + - "⫵": [T: "trippel loddrett strek med horisontal strek"] # 0x2af5 (en: 'triple vertical bar with horizontal stroke', google: 'trippel vertikal stång med horisontellt slag') + - "⫶": [T: "trippelkolon"] # 0x2af6 (en: 'triple colon operator', google: 'trippel kolonoperatör') + - "⫷": [T: "trippel mindre enn"] # 0x2af7 (en: 'triple nested less than', google: 'trippel kapslade mindre än') + - "⫸": [T: "trippel større enn"] # 0x2af8 (en: 'triple nested greater than', google: 'trippel kapslad större än') + - "⫹": [T: "mindre enn eller lik"] # 0x2af9 (en: 'double line slanted less than or equal to', google: 'dubbel linje lutad mindre än eller lika med') + - "⫺": [T: "større enn eller lik"] # 0x2afa (en: 'double line slanted greater than or equal to', google: 'dubbel linje lutad större än eller lika med') + - "⫻": [T: "trippel skråstrek"] # 0x2afb (en: 'triple solidus binary relation', google: 'trippel solidus binär relation') + - "⫼": [T: "stor trippel vertikal strek"] # 0x2afc (en: 'large triple vertical bar operator', google: 'stor trippel vertikal stångoperatör') + - "⫽": [T: "dobbel skråstrek"] # 0x2afd (en: 'double solidus operator', google: 'dubbel solidus -operatör') + - "⫾": [T: "hvit loddrett strek"] # 0x2afe (en: 'white vertical bar', google: 'vit vertikal stång') + - "⫿": [T: "hvit loddrett strek"] # 0x2aff (en: 'white vertical bar', google: 'vit vertikal stång') + #-------------------------------------------------------------------------------------------------------------- + # Miscellaneous symbols and arrows OK + - "⬀": [T: "hvit nordøst-pil"] # 0x2b00 (en: 'north east white arrow', google: 'north east white arrow') + - "⬁": [T: "hvit nordvest-pil"] # 0x2b01 (en: 'north west white arrow', google: 'north west white arrow') + - "⬂": [T: "hvit sørøst-pil"] # 0x2b02 (en: 'south east white arrow', google: 'south east white arrow') + - "⬃": [T: "hvit sørvest-pil"] # 0x2b03 (en: 'south west white arrow', google: 'south west white arrow') + - "⬄": [T: "hvit venstre-høyre-pil"] # 0x2b04 (en: 'left right white arrow', google: 'vänster höger vit pil') + - "⬅": [T: "fylt venstrepil"] # 0x2b05 (en: 'leftwards black arrow', google: 'vänster svart pil') + - "⬆": [T: "fylt oppoverpil"] # 0x2b06 (en: 'upwards black arrow', google: 'uppåt svart pil') + - "⬇": [T: "fylt nedoverpil"] # 0x2b07 (en: 'downwards black arrow', google: 'nedåt svart pil') + - "⬈": [T: "fylt nordøst-pil"] # 0x2b08 (en: 'north east black arrow', google: 'north east black arrow') + - "⬉": [T: "fylt nordvest-pil"] # 0x2b09 (en: 'north west black arrow', google: 'north west black arrow') + - "⬊": [T: "fylt sørøst-pil"] # 0x2b0a (en: 'south east black arrow', google: 'south east black arrow') + - "⬋": [T: "fylt sørvest-pil"] # 0x2b0b (en: 'south west black arrow', google: 'south west black arrow') + - "⬌": [T: "fylt venstre-høyre-pil"] # 0x2b0c (en: 'left right black arrow', google: 'vänster höger svart pil') + - "⬍": [T: "fylt opp-ned-pil"] # 0x2b0d (en: 'up down black arrow', google: 'upp ner black arrow') + - "⬎": [T: "høyrepil med spiss ned"] # 0x2b0e (en: 'rightwards arrow with tip downwards', google: 'åtgärdspil med spets nedåt') + - "⬏": [T: "høyrepil med spiss opp"] # 0x2b0f (en: 'rightwards arrow with tip upwards', google: 'åtgärdspil med spetsen uppåt') + - "⬐": [T: "venstrepil med spiss ned"] # 0x2b10 (en: 'leftwards arrow with tip downwards', google: 'vänster pil med spetsen nedåt') + - "⬑": [T: "venstrepil med spiss opp"] # 0x2b11 (en: 'leftwards arrow with tip upwards', google: 'vänster pil med spetsen uppåt') + - "⬒": [T: "kvadrat med øvre halvdel fylt"] # 0x2b12 (en: 'square with top half black', google: 'fyrkantig med topphalva svart') + - "⬓": [T: "kvadrat med nedre halvdel fylt"] # 0x2b13 (en: 'square with bottom half black', google: 'fyrkantig med botten halvsvart') + - "⬔": [T: "kvadrat med øvre høyre diagonal halvfylt"] # 0x2b14 (en: 'square with upper right diagonal half black', google: 'fyrkantig med övre högra diagonala halvsvart') + - "⬕": [T: "kvadrat med nedre venstre diagonal halvfylt"] # 0x2b15 (en: 'square with lower left diagonal half black', google: 'fyrkantig med nedre vänster diagonal halvsvart') + - "⬖": [T: "diamant med venstre halvdel fylt"] # 0x2b16 (en: 'diamond with left half black', google: 'diamant med vänster halvsvart') + - "⬗": [T: "diamant med høyre halvdel fylt"] # 0x2b17 (en: 'diamond with right half black', google: 'diamant med höger halv svart') + - "⬘": [T: "diamant med øvre halvdel fylt"] # 0x2b18 (en: 'diamond with top half black', google: 'diamant med topp halva svart') + - "⬙": [T: "diamant med nedre halvdel fylt"] # 0x2b19 (en: 'diamond with bottom half black', google: 'diamant med botten halvsvart') + - "⬚": [T: "prikket kvadrat"] # 0x2b1a (en: 'box', google: 'låda') + - "⬛": [T: "stort svart kvadrat"] # 0x2b1b (en: 'black large square', google: 'svart stort fyrkant') + - "⬜": [T: "stort hvitt kvadrat"] # 0x2b1c (en: 'white large square', google: 'vit stor fyrkant') + - "⬝": [T: "veldig lite svart kvadrat"] # 0x2b1d (en: 'black very small square', google: 'svart mycket litet fyrkant') + - "⬞": [T: "veldig lite hvitt kvadrat"] # 0x2b1e (en: 'white very small square', google: 'vit mycket liten fyrkant') + - "⬟": [T: "svart femkant"] # 0x2b1f (en: 'black pentagon', google: 'svart pentagon') + - "⬠": [T: "hvit femkant"] # 0x2b20 (en: 'white pentagon', google: 'vit pentagon') + - "⬡": [T: "hvit sekskant"] # 0x2b21 (en: 'white hexagon', google: 'vit hexagon') + - "⬢": [T: "svart sekskant"] # 0x2b22 (en: 'black hexagon', google: 'svart hexagon') + - "⬣": [T: "horisontal svart sekskant"] # 0x2b23 (en: 'horizontal black hexagon', google: 'horisontell svart hexagon') + - "⬤": [T: "stor svart sirkel"] # 0x2b24 (en: 'black large circle', google: 'svart stor cirkel') + - "⬥": [T: "svart diamant"] # 0x2b25 (en: 'black medium diamond', google: 'svart medium diamant') + - "⬦": [T: "hvit diamant"] # 0x2b26 (en: 'white medium diamond', google: 'vit medium diamant') + - "⬧": [T: "svart rombe"] # 0x2b27 (en: 'black medium lozenge', google: 'svart medium pastill') + - "⬨": [T: "hvit rombe"] # 0x2b28 (en: 'white medium lozenge', google: 'vit medium pastill') + - "⬩": [T: "liten svart diamant"] # 0x2b29 (en: 'black small diamond') + - "⬪": [T: "liten svart rombe"] # 0x2b2a (en: 'black small lozenge', google: 'svart liten pastill') + - "⬫": [T: "liten hvit rombe"] # 0x2b2b (en: 'white small lozenge', google: 'vit liten pastill') + - "⬬": [T: "svart horisontal ellipse"] # 0x2b2c (en: 'black horizontal ellipse') + - "⬭": [T: "hvit horisontal ellipse"] # 0x2b2d (en: 'white horizontal ellipse') + - "⬮": [T: "svart vertikal ellipse"] # 0x2b2e (en: 'black vertical ellipse', google: 'svart vertikalt ellips') + - "⬯": [T: "hvit vertikal ellipse"] # 0x2b2f (en: 'white vertical ellipse') + - "⬰": [T: "venstrepil med liten sirkel"] # 0x2b30 (en: 'left arrow with small circle', google: 'vänster pil med liten cirkel') + - "⬱": [T: "tre venstrepiler"] # 0x2b31 (en: 'three leftwards arrows') + - "⬲": [T: "venstrepil med pluss i sirkel"] # 0x2b32 (en: 'left arrow with circled plus', google: 'vänster pil med circled plus') + - "⬳": [T: "lang sikksakk venstrepil"] # 0x2b33 (en: 'long leftwards squiggle arrow', google: 'långt vänster squiggle pil') + - "⬴": [T: "venstrepil med dobbel spiss og vertikal strek"] # 0x2b34 (en: 'leftwards two headed arrow with vertical stroke', google: 'vänster två ledde pil med vertikalt slag') + - "⬵": [T: "venstrepil med dobbel spiss og dobbel vertikal strek"] # 0x2b35 (en: 'leftwards two headed arrow with double vertical stroke', google: 'vänster två ledde pil med dubbel vertikal stroke') + - "⬶": [T: "venstrepil med dobbel spiss fra strek"] # 0x2b36 (en: 'leftwards two headed arrow from bar', google: 'vänster två ledde pil från bar') + - "⬷": [T: "stiplet venstrepil med dobbel spiss"] # 0x2b37 (en: 'leftwards two headed triple dash arrow', google: 'vänster två ledde trippelstreckpil') + - "⬸": [T: "stiplet venstrepil"] # 0x2b38 (en: 'leftwards arrow with dotted stem', google: 'vänster pil med prickad stam') + - "⬹": [T: "venstrepil med vertikal strek og hale"] # 0x2b39 (en: 'leftwards arrow with tail with vertical stroke', google: 'vänster pil med svans med vertikalt slag') + - "⬺": [T: "venstrepil med hale og dobbel vertikal strek"] # 0x2b3a (en: 'leftwards arrow with tail with double vertical stroke', google: 'vänster pil med svans med dubbel vertikal stroke') + - "⬻": [T: "venstrepil med dobbel spiss og hale"] # 0x2b3b (en: 'leftwards two headed arrow with tail', google: 'vänster två ledde pil med svans') + - "⬼": [T: "venstrepil med dobbel spiss, hale og vertikal strek"] # 0x2b3c (en: 'leftwards two headed arrow with tail with vertical stroke', google: 'vänster två ledde pilen med svans med vertikal stroke') + - "⬽": [T: "venstrepil med dobbel spiss, hale og dobbel vertikal strek"] # 0x2b3d (en: 'leftwards two headed arrow with tail with double vertical stroke', google: 'vänster två ledde pilen med svans med dubbel vertikal stroke') + - "⬾": [T: "venstrepil gjennom x"] # 0x2b3e (en: 'leftwards arrow through x', google: 'vänster pil genom x') + - "⬿": [T: "bølget venstrepil"] # 0x2b3f (en: 'wave arrow pointing directly left', google: 'wave arrow pekade direkt kvar') + - "⭀": [T: "venstrepil med likhetstegn"] # 0x2b40 (en: 'equals sign above leftwards arrow', google: 'är lika med skylt över vänster pil') + - "⭁": [T: "venstrepil med speilvendt tilde"] # 0x2b41 (en: 'reverse tilde operator above leftwards arrow', google: 'omvänd tilde -operatör över vänster pil') + - "⭂": [T: "venstrepil over speilvendt omtrent lik"] # 0x2b42 (en: 'leftwards arrow above reverse almost equal to', google: 'vänster pil över omvänd nästan lika med') + - "⭃": [T: "høyrepil gjennom større enn"] # 0x2b43 (en: 'rightwards arrow through greater than', google: 'åtgärdspil genom större än') + - "⭄": [T: "høyrepil gjennom overmengde"] # 0x2b44 (en: 'rightwards arrow through superset', google: 'åtgärdspil genom superset') + - "⭅": [T: "kvadrupel-streket venstrepil"] # 0x2b45 (en: 'leftwards quadruple arrow', google: 'vänster fyrdubbla pil') + - "⭆": [T: "kvadrupel-streket høyrepil"] # 0x2b46 (en: 'rightwards quadruple arrow', google: 'åtgärd med höger fyrdubbla') + - "⭇": [T: "høyrepil med speilvendt tilde"] # 0x2b47 (en: 'reverse tilde operator above rightwards arrow', google: 'omvänd tilde -operatör ovanför höger-pilen') + - "⭈": [T: "høyrepil over speilvendt omtrent lik"] # 0x2b48 (en: 'rightwards arrow above reverse almost equal to', google: 'åtgärdspilen över omvänd nästan lika med') + - "⭉": [T: "venstrepil med tilde"] # 0x2b49 (en: 'tilde operator above leftwards arrow', google: 'tilde -operatören ovanför vänster pil') + - "⭊": [T: "venstrepil over omtrent lik"] # 0x2b4a (en: 'leftwards arrow above almost equal to', google: 'vänster pil över nästan lika med') + - "⭋": [T: "venstrepil over speilvendt tilde"] # 0x2b4b (en: 'leftwards arrow above reverse tilde operator', google: 'vänster pil ovanför omvänd tilde -operatör') + - "⭌": [T: "høyrepil over speilvendt tilde"] # 0x2b4c (en: 'rightwards arrow above reverse tilde operator', google: 'åtgärdspil över omvänd tilde -operatör') + - "⭐": [T: "hvit stjerne"] # 0x2b50 (en: 'white medium star') + - "⭑": [T: "liten svart stjerne"] # 0x2b51 (en: 'black small star') + - "⭒": [T: "liten hvit stjerne"] # 0x2b52 (en: 'white small star') + - "⭓": [T: "svart femkant som peker til høyre"] # 0x2b53 (en: 'black right pointing pentagon', google: 'svart höger pekande pentagon') + - "⭔": [T: "hvit femkant som peker til høyre"] # 0x2b54 (en: 'white right pointing pentagon', google: 'vit höger pekande pentagon') + - "⭕": [T: "fet stor sirkel"] # 0x2b55 (en: 'heavy large circle', google: 'tung stor cirkel') + - "⭖": [T: "fet oval med oval i"] # 0x2b56 (en: 'heavy oval with oval inside', google: 'tung oval med oval inuti') + - "⭗": [T: "fet sirkel med sirkel i"] # 0x2b57 (en: 'heavy circle with circle inside', google: 'tung cirkel med cirkel inuti') + - "⭘": [T: "fet sirkel"] # 0x2b58 (en: 'heavy circle', google: 'tung cirkel') + - "⭙": [T: "fet kryss i sirkel"] # 0x2b59 (en: 'heavy circled saltire', google: 'tung cirklad saltire') + #------------------------------------------------------------------------------------------------------------ + # Supplemental punctuation OK + - "⸀": [T: "rett vinkel erstatningsmarkør"] # 0x2e00 (en: 'right angle substitution marker', google translation) + - "⸁": [T: "rett vinkel erstatningsmarkør med prikk"] # 0x2e01 (en: 'right angle dotted substitution marker', google translation) + - "⸂": [T: "venstre erstatningsparentes"] # 0x2e02 (en: 'left substitution bracket', google translation) + - "⸃": [T: "høyre erstatningsparentes"] # 0x2e03 (en: 'right substitution bracket', google translation) + - "⸄": [T: "venstre erstatningsparentes med prikk"] # 0x2e04 (en: 'left dotted substitution bracket', google translation) + - "⸅": [T: "høyre erstatningsparentes med prikk"] # 0x2e05 (en: 'right dotted substitution bracket', google translation) + - "⸆": [T: "hevet interpolasjonsmarkør"] # 0x2e06 (en: 'raised interpolation marker', google translation) + - "⸇": [T: "hevet interpolasjonsmarkør med prikk"] # 0x2e07 (en: 'raised dotted interpolation marker', google translation) + - "⸈": [T: "venstre transposisjonsmarkør med prikk"] # 0x2e08 (en: 'dotted transposition marker marker', google translation) + - "⸉": [T: "venstre transposisjonsparentes"] # 0x2e09 (en: 'left transposition bracket', google translation) + - "⸊": [T: "høyre transposisjonsparentes"] # 0x2e0a (en: 'right transposition bracket', google translation) + - "⸋": [T: "hevet kvadrat"] # 0x2e0b (en: 'raised square', google translation) + - "⸌": [T: "venstre hevet utelatelses-parentes"] # 0x2e0c (en: 'left raised omission bracket', google translation) + - "⸍": [T: "høyre hevet utelatelses-parentes"] # 0x2e0d (en: 'right raised omission bracket', google translation) + - "⸎": [T: "redaksjonell coronis"] # 0x2e0e (en: 'editorial coronis', google translation) + - "⸏": [T: "paragraphos"] # 0x2e0f (google translation) + - "⸐": [T: "forgreinet paragraphos"] # 0x2e10 (en: 'forked paragraphos', google translation) + - "⸑": [T: "speilvendt forgreinet paragraphos"] # 0x2e11 (en: 'reversed forked paragraphos', google translation) + - "⸒": [T: "hypodiastol"] # 0x2e12 (google translation) + - "⸓": [T: "prikket obelus"] # 0x2e13 (en: 'dotted obelos', google translation) + - "⸔": [T: "nedover ancora"] # 0x2e14 (en: 'downwards ancora', google translation) + - "⸕": [T: "oppover ancora"] # 0x2e15 (en: 'upwards ancora', google translation) + - "⸖": [T: "prikket høyrepekende vinkel"] # 0x2e16 (en: 'dotted right pointing angle', google translation) + - "⸗": [T: "dobbel skrå bindestrek"] # 0x2e17 (en: 'double oblique hyphen', google translation) + - "⸘": [T: "omvendt interrobang"] # 0x2e18 (en: 'inverted interrobang', google translation) + - "⸙": [T: "palmegren"] # 0x2e19 (google translation) + - "⸚": [T: "bindestrek med trema"] # 0x2e1a (en: 'hyphen with diaeresis', google translation) + - "⸛": [T: "tilde med ring"] # 0x2e1b (en: 'tilde with ring above', google translation) + - "⸜": [T: "lav venstre parafraseparentes"] # 0x2e1c (en: 'left low paraphrase bracket', google translation) + - "⸝": [T: "lav høyre parafraseparentes"] # 0x2e1d (en: 'right low paraphrase bracket', google translation) + - "⸞": [T: "tilde med prikk over"] # 0x2e1e (en: 'tilde with dot above', google translation) + - "⸟": [T: "tilde med prikk under"] # 0x2e1f (en: 'tilde with dot below', google translation) + - "⸠": [T: "vertikal strek med pigg til høyre"] # 0x2e20 (en: 'left vertical bar with quill', google translation) + - "⸡": [T: "vertikal strek med pigg til venstre"] # 0x2e21 (en: 'right vertical bar with quill', google translation) + - "⸢": [T: "øvre venstre halv hakeparentes"] # 0x2e22 (en: 'top left half bracket', google: 'överst till vänster halvfäste') + - "⸣": [T: "øvre høyre halv hakeparentes"] # 0x2e23 (en: 'top right half bracket', google: 'överst till höger halva konsol') + - "⸤": [T: "nedre venstre halv hakeparentes"] # 0x2e24 (en: 'bottom left half bracket', google: 'nedre vänstra halvfästet') + - "⸥": [T: "nedre høyre halv hakeparentes"] # 0x2e25 (en: 'bottom right half bracket', google: 'nedre högra halvfästet') + - "⸦": [T: "venstre u-parentes"] # 0x2e26 (en: 'left sideways u bracket', google: 'vänster i sidled u konsol') + - "⸧": [T: "høyre u-parentes"] # 0x2e27 (en: 'right sideways u bracket', google: 'höger i sidled u konsol') + - "⸨": [T: "dobbel venstreparentes"] # 0x2e28 (en: 'left double parentheses', google: 'vänster dubbla parenteser') + - "⸩": [T: "dobbel høyreparentes"] # 0x2e29 (en: 'right double parentheses', google: 'höger dubbel parentes') + - "⸪": [T: "to prikker over én prikk"] # 0x2e2a (en: 'two dots over one dot punctuation', google translation) + - "⸫": [T: "én prikk over to prikker"] # 0x2e2b (en: 'one dot over two dots punctuation', google translation) + - "⸬": [T: "fire prikker i kvadrat"] # 0x2e2c (en: 'squared four dot punctuation', google translation) + - "⸭": [T: "fem prikker i kryss"] # 0x2e2d (en: 'five dot mark', google translation) + - "⸮": [T: "speilvendt spørsmålstegn"] # 0x2e2e (en: 'reversed question mark', google translation) + - "ⸯ": [T: "vertikal tilde"] # 0x2e2f (en: 'vertical tilde', google translation) + - "⸰": [T: "ringpunkt"] # 0x2e30 (en: 'ring point', google translation) + - "⸱": [T: "ordskille-punkt"] # 0x2e31 (google translation) + - "⸲": [T: "rotert komma"] # 0x2e32 (en: 'turned comma', google translation) + - "⸳": [T: "hevet prikk"] # 0x2e33 (en: 'raised dot', google translation) + - "⸴": [T: "hevet komma"] # 0x2e34 (en: 'raised comma', google translation) + - "⸵": [T: "rotert semikolon"] # 0x2e35 (en: 'turned semicolon', google translation) + - "⸶": [T: "dolk med venstre vaktstang"] # 0x2e36 (en: 'dagger with left guard', google translation) + - "⸷": [T: "dolk med høyre vaktstang"] # 0x2e37 (en: 'dagger with right guard', google translation) + - "⸸": [T: "rotert dolk"] # 0x2e38 (en: 'turned dagger', google translation) + - "⸹": [T: "øvre halvt avsnittssymbol"] # 0x2e39 (en: 'top half section sign', google translation) + - "⸺": [T: "dobbel tankestrek"] # 0x2e3a (en: 'two em dash', google translation) + - "⸻": [T: "trippel tankestrek"] # 0x2e3b (en: 'three em dash', google translation) + #------------------------------------------------------------------------------------------------------------------- + # CJK symbols and punctuation OK + - "〃": [T: "gjentategn"] # 0x3003 (google translation) + - "〈": [T: "venstre vinkelparentes"] # 0x3008 (en: 'left angle bracket', google: 'vänster vinkelfäste') + - "〉": [T: "høyre vinkelparentes"] # 0x3009 (en: 'right angle bracket', google: 'rätt vinkelfäste') + - "《": [T: "dobbel venstre vinkelparentes"] # 0x300a (en: 'left double angle bracket') + - "》": [T: "dobbel høyre vinkelparentes"] # 0x300b (en: 'right double angle bracket') + - "「": [T: "venstre hjørneparentes"] # 0x300c (en: 'left corner bracket', google: 'vänster hörnfäste') + - "」": [T: "høyre hjørneparentes"] # 0x300d (en: 'right corner bracket', google: 'höger hörnfäste') + - "『": [T: "venstre hvit hjørneparentes"] # 0x300e (en: 'left white corner bracket', google: 'vänster vit hörnfäste') + - "』": [T: "høyre hvit hjørneparentes"] # 0x300f (en: 'right white corner bracket', google: 'höger vit hörnfäste') + - "【": [T: "venstre svart linseformet hakeparentes"] # 0x3010 (en: 'left black lenticular bracket', google: 'vänster svart linsformell konsol') + - "】": [T: "høyre svart linseformet hakeparentes"] # 0x3011 (en: 'right black lenticular bracket', google: 'höger svart linsformell konsol') + - "〔": [T: "venstre skilpaddeskall-parentes"] # 0x3014 (en: 'left tortoise shell bracket') + - "〕": [T: "høyre skilpaddeskall-parentes"] # 0x3015 (en: 'right tortoise shell bracket') + - "〖": [T: "venstre hvit linseformet hakeparentes"] # 0x3016 (en: 'left white lenticular bracket', google: 'vänster vit linsformad konsol') + - "〗": [T: "høyre hvit linseformet hakeparentes"] # 0x3017 (en: 'right white lenticular bracket', google: 'höger vit linsformad konsol') + - "〘": [T: "venstre hvit skilpaddeskall-parentes"] # 0x3018 (en: 'left white tortoise shell bracket', google: 'vänster vit sköldpaddsskalfäste') + - "〙": [T: "høyre hvit skilpaddeskall-parentes"] # 0x3019 (en: 'right white tortoise shell bracket', google: 'höger vit sköldpaddsskalfäste') + - "〚": [T: "venstre hvit hakeparentes"] # 0x301a (en: 'left white square bracket') + - "〛": [T: "høyre hvit hakeparentes"] # 0x301b (en: 'right white square bracket') + - "〜": [T: "bølgestrek"] # 0x301c (en: 'wave dash', google: 'wave dash') + - "〰": [T: "bølget strek"] # 0x3030 (en: 'wavy dash', google: 'wavy dash') + #---------------------------------------------------------------------------------------------------------------------------------- + # Enclosed CJK letters and months OK + - "㉈": [T: "ti i sirkel på fylt kvadrat"] # 0x3248 (en: 'circled number ten on black square', google: 'cirklat nummer tio på black square') + - "㉉": [T: "tjue i sirkel på fylt kvadrat"] # 0x3249 (en: 'circled number twenty on black square', google: 'cirklat nummer tjugo på black square') + - "㉊": [T: "tretti i sirkel på fylt kvadrat"] # 0x324a (en: 'circled number thirty on black square', google: 'cirklat nummer trettio på black square') + - "㉋": [T: "førti i sirkel på fylt kvadrat"] # 0x324b (en: 'circled number forty on blacks square', google: 'cirklat nummer fyrtio på blacks square') + - "㉌": [T: "femti i sirkel på fylt kvadrat"] # 0x324c (en: 'circled number fifty on black square', google: 'cirklat nummer femtio på black square') + - "㉍": [T: "seksti i sirkel på fylt kvadrat"] # 0x324d (en: 'circled number sixty on black square', google: 'cirklat nummer sextio på black square') + - "㉎": [T: "sytti i sirkel på fylt kvadrat"] # 0x324e (en: 'circled number seventy on black square', google: 'cirklat nummer sjuttio på black square') + - "㉏": [T: "åtti i sirkel på fylt kvadrat"] # 0x324f (en: 'circled number eighty on black square', google: 'cirklat nummer aty på black square') + - "㉑": [T: "tjueen i sirkel"] # 0x3251 (en: 'circled number twenty one', google translation) + - "㉒": [T: "tjueto i sirkel"] # 0x3252 (en: 'circled number twenty two', google translation) + - "㉓": [T: "tjuetre i sirkel"] # 0x3253 (en: 'circled number twenty three', google translation) + - "㉔": [T: "tjuefire i sirkel"] # 0x3254 (en: 'circled number twenty four', google translation) + - "㉕": [T: "tjuefem i sirkel"] # 0x3255 (google translation) + - "㉖": [T: "tjueseks i sirkel"] # 0x3256 (google translation) + - "㉗": [T: "tjuesju i sirkel"] # 0x3257 (en: 'circled number twenty seven', google translation) + - "㉘": [T: "tjueåtte i sirkel"] # 0x3258 (en: 'circled number twenty eight', google translation) + - "㉙": [T: "tjueni i sirkel"] # 0x3259 (en: 'circled number twenty nine', google translation) + - "㉚": [T: "tretti i sirkel"] # 0x325a (en: 'circled number thirty', google translation) + - "㉛": [T: "trettien i sirkel"] # 0x325b (en: 'circled number thirty one', google translation) + - "㉜": [T: "trettito i sirkel"] # 0x325c (en: 'circled number thirty two', google translation) + - "㉝": [T: "trettitre i sirkel"] # 0x325d (google translation) + - "㉞": [T: "trettifire i sirkel"] # 0x325e (en: 'circled number thirty four', google translation) + - "㉟": [T: "trettifem i sirkel"] # 0x325f (en: 'circled number thirty five', google translation) + - "㊱": [T: "trettiseks i sirkel"] # 0x32b1 (en: 'circled number thirty six', google translation) + - "㊲": [T: "trettisju i sirkel"] # 0x32b2 (en: 'circled number thirty seven', GPT-5.4 translation) + - "㊳": [T: "trettiåtte i sirkel"] # 0x32b3 (en: 'circled number thirty eight', GPT-5.4 translation) + - "㊴": [T: "trettini i sirkel"] # 0x32b4 (en: 'circled number thirty nine', GPT-5.4 translation) + - "㊵": [T: "førti i sirkel"] # 0x32b5 (en: 'circled number forty', GPT-5.4 translation) + - "㊶": [T: "førtien i sirkel"] # 0x32b6 (en: 'circled number forty one', GPT-5.4 translation) + - "㊷": [T: "førtito i sirkel"] # 0x32b7 (en: 'circled number forty two', GPT-5.4 translation) + - "㊸": [T: "førtitre i sirkel"] # 0x32b8 (en: 'circled number forty three', GPT-5.4 translation) + - "㊹": [T: "førtifire i sirkel"] # 0x32b9 (en: 'circled number forty four', GPT-5.4 translation) + - "㊺": [T: "førtifem i sirkel"] # 0x32ba (en: 'circled number forty five', GPT-5.4 translation) + - "㊻": [T: "førtiseks i sirkel"] # 0x32bb (en: 'circled number forty six', GPT-5.4 translation) + - "㊼": [T: "førtisju i sirkel"] # 0x32bc (en: 'circled number forty seven', GPT-5.4 translation) + - "㊽": [T: "førtiåtte i sirkel"] # 0x32bd (en: 'circled number forty eight', GPT-5.4 translation) + - "㊾": [T: "førtini i sirkel"] # 0x32be (en: 'circled number forty nine', GPT-5.4 translation) + - "㊿": [T: "femti i sirkel"] # 0x32bf (en: 'circled number fifty', GPT-5.4 translation) + - "㋌": [T: "kvikksølv"] # 0x32cc (en: 'mercury', google translation) + - "㋍": [T: "erg"] # 0x32cd (google translation) + - "㋎": [T: "elektronvolt"] # 0x32ce (en: 'electron volts', google translation) + - "㋏": [T: "begrenset ansvar"] # 0x32cf (en: 'limited liability sign', google translation) + #----------------------------------------------------------------------------------------------------------------------- + # CJK compatibility OK + - "㍱": [T: "hektopascal"] # 0x3371 (en: 'hectopascals', google translation) + - "㍲": [T: "dalton"] # 0x3372 (google translation) + - "㍳": [T: "astronomisk enhet"] # 0x3373 (en: 'astronomical units', google translation) + - "㍴": [T: "bar"] # 0x3374 (en: 'bars', google translation) + - "㍵": [T: "o v"] # 0x3375 (google translation) + - "㍶": [T: "parsec"] # 0x3376 (google translation) + - "㍷": [T: "desimeter"] # 0x3377 (en: 'decimeters', google translation) + - "㍸": [T: "kvadratdesimeter"] # 0x3378 (en: 'decimeters squared', google translation) + - "㍹": [T: "kubikkdesimeter"] # 0x3379 (en: 'decimeters cubed', google translation) + - "㍺": [T: "kvadratisk I U"] # 0x337a (en: 'instrumental units', google translation) + - "㎀": [T: "piko-ampere"] # 0x3380 (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎁": [T: "nanoampere"] # 0x3381 (google translation) + - "㎂": [T: "mikroampere"] # 0x3382 (google translation) + - "㎃": [T: "milliampere"] # 0x3383 (google translation) + - "㎄": [T: "kiloampere"] # 0x3384 (google translation) + - "㎅": [T: "kilobyte"] # 0x3385 (google translation) + - "㎆": [T: "mega-byte"] # 0x3386 (en: 'megabytes', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎇": [T: "gigabyte"] # 0x3387 (en: 'gigabytes', google translation) + - "㎈": [T: "kalorier"] # 0x3388 (en: 'calories', google translation) + - "㎉": [T: "kilokalorier"] # 0x3389 (en: 'kilocalories', google translation) + - "㎊": [T: "piko-farad"] # 0x338a (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎋": [T: "nano-farad"] # 0x338b (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎌": [T: "mikrofarad"] # 0x338c (google translation) + - "㎍": [T: "mikro-gram"] # 0x338d (en: 'micrograms', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎎": [T: "milligram"] # 0x338e (google translation) + - "㎏": [T: "kilogram"] # 0x338f (en: 'kilograms', google translation) + - "㎐": [T: "hertz"] # 0x3390 (google translation) + - "㎑": [T: "kilohertz"] # 0x3391 (google translation) + - "㎒": [T: "megahertz"] # 0x3392 (google translation) + - "㎓": [T: "gigahertz"] # 0x3393 (google translation) + - "㎔": [T: "tera-hertz"] # 0x3394 (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎕": [T: "mikroliter"] # 0x3395 (google translation) + - "㎖": [T: "milliliter"] # 0x3396 (google translation) + - "㎗": [T: "desiliter"] # 0x3397 (google translation) + - "㎘": [T: "kiloliter"] # 0x3398 (en: 'kiloliters', google translation) + - "㎙": [T: "femto-meter"] # 0x3399 (en: 'femtometers', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎚": [T: "nanometer"] # 0x339a (en: 'nanometers', google translation) + - "㎛": [T: "mikro-meter"] # 0x339b (en: 'micrometers', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎜": [T: "millimeter"] # 0x339c (en: 'millimeters', google translation) + - "㎝": [T: "centimeter"] # 0x339d (en: 'centimeters', google translation) + - "㎞": [T: "kilometer"] # 0x339e (en: 'kilometers', google translation) + - "㎟": [T: "kvadratmillimeter"] # 0x339f (en: 'millimeters squared', google translation) + - "㎠": [T: "kvadratcentimeter"] # 0x33a0 (en: 'centimeters squared', google translation) + - "㎡": [T: "kvadratmeter"] # 0x33a1 (en: 'meters squared', google translation) + - "㎢": [T: "kvadratkilometer"] # 0x33a2 (en: 'kilometers squared', google translation) + - "㎣": [T: "kubikkmillimeter"] # 0x33a3 (en: 'millimeters cubed', google translation) + - "㎤": [T: "kubikkcentimeter"] # 0x33a4 (en: 'centimeters cubed', google translation) + - "㎥": [T: "kubikkmeter"] # 0x33a5 (en: 'meters cubed', google translation) + - "㎦": [T: "kubikk-kilometer"] # 0x33a6 (en: 'kilometers cubed', google translation) + - "㎧": [T: "meter per sekund"] # 0x33a7 (en: 'meters per second', google translation) + - "㎨": [T: "meter per sekund i andre"] # 0x33a8 (en: 'meters per second squared', google translation) + - "㎩": [T: "pascal"] # 0x33a9 (google translation) + - "㎪": [T: "kilopascal"] # 0x33aa (google translation) + - "㎫": [T: "megapascal"] # 0x33ab (google translation) + - "㎬": [T: "giga-pascal"] # 0x33ac (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎭": [T: "radianer"] # 0x33ad (google translation) + - "㎮": [T: "radianer per sekund"] # 0x33ae (en: 'rads per second', google translation) + - "㎯": [T: "radianer per sekund i andre"] # 0x33af (en: 'rads per second squared', google translation) + - "㎰": [T: "piko-sekunder"] # 0x33b0 (en: 'picoseconds', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎱": [T: "nanosekunder"] # 0x33b1 (en: 'nanoseconds', google translation) + - "㎲": [T: "mikrosekunder"] # 0x33b2 (en: 'microseconds', google translation) + - "㎳": [T: "millisekunder"] # 0x33b3 (en: 'milliseconds', google translation) + - "㎴": [T: "piko-volt"] # 0x33b4 (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎵": [T: "nanovolt"] # 0x33b5 (google translation) + - "㎶": [T: "mikrovolt"] # 0x33b6 (google translation) + - "㎷": [T: "millivolt"] # 0x33b7 (google translation) + - "㎸": [T: "kilovolt"] # 0x33b8 (google translation) + - "㎹": [T: "megavolt"] # 0x33b9 (google translation) + - "㎺": [T: "piko-watt"] # 0x33ba (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎻": [T: "nano-watt"] # 0x33bb (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎼": [T: "mikrowatt"] # 0x33bc (en: 'microwatts', google translation) + - "㎽": [T: "milliwatt"] # 0x33bd (google translation) + - "㎾": [T: "kilowatt"] # 0x33be (google translation) + - "㎿": [T: "mega-watt"] # 0x33bf (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㏀": [T: "kiloohm"] # 0x33c0 (google translation) + - "㏁": [T: "megaohm"] # 0x33c1 (google translation) + - "㏂": [T: "atto-meter"] # 0x33c2 (en: 'attometers', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㏃": [T: "becquerel"] # 0x33c3 (google translation) + - "㏄": [T: "kubikkcentimeter"] # 0x33c4 (en: 'cubic centimeters', google translation) + - "㏅": [T: "candela"] # 0x33c5 (google translation) + - "㏆": [T: "coulomb per kilogram"] # 0x33c6 (en: 'coulombs per kilogram', google translation) + - "㏇": [T: "kvadratisk C O"] # 0x33c7 (en: 'cardiac output', google translation) + - "㏈": [T: "desibel"] # 0x33c8 (en: 'decibels', google translation) + - "㏉": [T: "gray"] # 0x33c9 (en: 'grays', google translation) + - "㏊": [T: "hektar"] # 0x33ca (en: 'hectares', google translation) + - "㏋": [T: "hestekraft"] # 0x33cb (en: 'horsepower', google translation) + - "㏌": [T: "tomme"] # 0x33cc (en: 'inches', google translation) + - "㏍": [T: "kilokelvin"] # 0x33cd (google translation) + - "㏎": [T: "kilometer"] # 0x33ce (en: 'kilometers', google translation) + - "㏏": [T: "knop"] # 0x33cf (en: 'knots', google translation) + - "㏐": [T: "lumen"] # 0x33d0 (en: 'lumens', google translation) + - "㏑": [T: "den naturlige logaritmen"] # 0x33d1 (en: 'natural log', google translation) + - "㏒": [T: "logaritmen"] # 0x33d2 (en: 'logarithm', google translation) + - "㏓": [T: "lux"] # 0x33d3 (google translation) + - "㏔": [T: "millibarn"] # 0x33d4 (en: 'millibarns', google translation) + - "㏕": [T: "mill"] # 0x33d5 (google translation) + - "㏖": [T: "mol"] # 0x33d6 (en: 'moles', google translation) + - "㏗": [T: "p h"] # 0x33d7 (google translation) + - "㏘": [T: "piko-meter"] # 0x33d8 (en: 'picometers', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㏙": [T: "milliondeler"] # 0x33d9 (en: 'parts per million', google translation) + - "㏚": [T: "petarøntgen"] # 0x33da (google translation) + - "㏛": [T: "steradianer"] # 0x33db (google translation) + - "㏜": [T: "sievert"] # 0x33dc (google translation) + - "㏝": [T: "weber"] # 0x33dd (google translation) + - "㏞": [T: "volt per meter"] # 0x33de (en: 'volts per meter', google translation) + - "㏟": [T: "ampere per meter"] # 0x33df (google translation) + - "㏿": [T: "gallon"] # 0x33ff (en: 'gallons', google translation) + #---------------------------------------------------------------------------------------------------------- + # Private use area OK + - "": [T: "lik med hatt under"] # 0xe900 (en: 'equals with hat below', google translation) + - "": [T: "lik med pluss over"] # 0xe901 (en: 'equals with plus above', google translation) + - "": [T: "lik med pluss under"] # 0xe902 (en: 'equals with plus below', google translation) + - "": [T: "tilde med pluss over"] # 0xe903 (en: 'tilde with plus above', google translation) + - "": [T: "tilde med pluss under"] # 0xe904 (en: 'tilde with plus below', google translation) + - "": [T: "dobbel lik over større enn"] # 0xe908 (en: 'equal double over greater than', google translation) + - "": [T: "dobbel lik over mindre enn"] # 0xe909 (en: 'equal double over less than', google translation) + - "": [T: "inneholder eller er lik"] # 0xe90a (en: 'contains or equal to', google translation) + - "": [T: "overmengde av eller lik"] # 0xe90b (en: 'superset of or equal to', google translation) + - "": [T: "delmengde av eller lik"] # 0xe90c (en: 'subset of or equal to', google translation) + - "": [T: "lik over mindre enn"] # 0xe90d (en: 'equal over less than', google translation) + - "": [T: "tilhører eller lik"] # 0xe912 (en: 'element of or equal to', google translation) + - "": [T: "lik eller større enn"] # 0xe913 (en: 'equal to or greater than', google translation) + - "": [T: "tilnærmet overmengde av"] # 0xe914 (en: 'approximate superset of', google translation) + - "": [T: "tilnærmet delmengde av"] # 0xe915 (en: 'approximate subset of', google translation) + - "": [T: "overmengde av med prikk inkluderer som underrelasjon"] # 0xe916 (en: 'superset of with dot includes as sub relation', google translation) + - "": [T: "delmengde av med prikk inkluderes i som underrelasjon"] # 0xe917 (en: 'subset of with dot is included in as sub relation', google translation) + - "": [T: "lik med prikk under"] # 0xe918 (en: 'equal with dot below', google translation) + - "": [T: "venstre prikk over minus over høyre prikk"] # 0xe919 (en: 'left dot over minus over right dot', google translation) + - "": [T: "høyre prikk over minus over venstre prikk"] # 0xe91a (en: 'right dot over minus over left dot', google translation) + - "": [T: "nesten lik minus"] # 0xe91f (en: 'almost equal to minus', google translation) + - "": [T: "dobbel kvadratisk union"] # 0xe920 (en: 'double square cup', google translation) + - "": [T: "dobbelt kvadratisk snitt"] # 0xe921 (en: 'double square cap', google translation) + - "": [T: "mindre enn lik eller større enn"] # 0xe922 (en: 'less than equal to or greater than', google translation) + - "": [T: "tilde med prikk"] # 0xe924 (en: 'tilde with dot', google translation) + - "": [T: "tilde med to prikker"] # 0xe925 (en: 'tilde with two dots', google translation) + - "": [T: "mindre enn større enn eller lik"] #0xe926 (en: 'less than greater than or equal to', google translation) + - "": [T: "større enn mindre enn eller lik"] # 0xe927 (en: 'greater than less than or equal to', google translation) + - "": [T: "ekvivalent med eller mindre enn"] # 0xe928 (en: 'equivalent to or less than', google translation) + - "": [T: "ekvivalent med eller større enn"] # 0xe929 (en: 'equivalent to or greater than', google translation) + - "": [T: "venstre åpen boks"] # 0xe92a (en: 'left open box operator', google translation) + - "": [T: "høyre åpen boks"] # 0xe92b (en: 'right open box operator', google translation) + - "": [T: "identisk med med prikk"] # 0xe92c (en: 'identical to with dot', google translation) + - "": [T: "større enn lik eller mindre enn"] # 0xe92d (en: 'greater than equal to or less than', google translation) + - "": [T: "bar"] # 0xe92e (en: 'bar operator', google translation) + - "": [T: "dobbel bar"] # 0xe92f (en: 'double bar operator', google translation) + - "": [T: "trippel bar"] # 0xe930 (google translation) + - "": [T: "mindre enn eller tilnærmet lik"] # 0xe932 (en: 'less than or approximately equal to', google translation) + - "": [T: "større enn eller tilnærmet lik"] # 0xe933 (en: 'greater than or approximately equal to', google translation) + - "": [T: "nøstet mindre enn"] # 0xe936 (en: 'nested less than', google translation) + - "": [T: "nøstet større enn"] # 0xe937 (en: 'nested greater than', google translation) + - "": [T: "foregår eller ekvivalent med"] # 0xe93a (en: 'precedes or equivalent to', google translation) + - "": [T: "følger eller ekvivalent med"] # 0xe93b (en: 'succeeds or equivalent to', google translation) + - "": [T: "foregår over lik"] # 0xe940 (en: 'precedes over equal', google translation) + - "": [T: "følger over lik"] # 0xe941 (en: 'succeeds over equal', google translation) + - "": [T: "mindre enn eller lik"] # 0xe942 (en: 'less equal slanted greater', google translation) + - "": [T: "større enn eller lik"] # 0xe943 (en: 'greater equal slanted less', google translation) + - "": [T: "oppfylles av"] # 0xe948 (en: 'satisfied by', google translation) + - "": [T: "langstrakt s"] # 0xe949 (en: 'lazy s', google translation) + - "": [T: "ikke påstand"] # 0xe94a (en: 'not assertion', google translation) + - "": [T: "dobbel lik"] # 0xe94b (en: 'double equal', google translation) + - "": [T: "trippel lik"] # 0xe94c (en: 'triple equal', google translation) + - "": [T: "regel forsinket"] # 0xe94d (en: 'rule delayed', google translation) + - "": [T: "alias skilletegn"] # 0xe94e (en: 'alias delimiter', google translation) + - "": [T: "normal undergruppe av med strek"] # 0xe950 (en: 'normal subgroup of with bar', google translation) + - "": [T: "inneholder som normal undergruppe med strek"] # 0xe951 (en: 'contains as normal subgroup with bar', google translation) + - "": [T: "rund impliserer"] # 0xe954 (en: 'round implies', google translation) + - "": [T: "smil under strek"] # 0xe955 (en: 'smile under bar', google translation) + - "": [T: "rynke over strek"] # 0xe956 (en: 'frown over bar', google translation) + - "": [T: "overmengde av eller tilnærmet lik"] # 0xe957 (en: 'superset of or almost equal to', google translation) + - "": [T: "delmengde av eller tilnærmet lik"] # 0xe958 (en: 'subset of or almost equal to', google translation) + - "": [T: "større enn tilnærmet lik eller mindre enn"] # 0xe959 (en: 'greater than almost equal to or less than', google translation) + - "": [T: "mindre enn tilnærmet lik eller større enn"] # 0xe95a (en: 'less than almost equal or greater than', google translation) + - "": [T: "dobbel logisk eller"] # 0xe95c (en: 'double logical or', google translation) + - "": [T: "dobbel logisk og"] # 0xe95d (en: 'double logical and', google translation) + - "": [T: "logisk eller med dobbel strek under"] # 0xe95e (en: 'logical or with double bar below', google translation) + - "": [T: "logisk eller med strek under"] # 0xe95f (en: 'logical or with bar below', google translation) + - "": [T: "tilnærmet lik"] # 0xe962 (en: 'almost equal over equal', google translation) + - "": [T: "venstre trekant med midtstrek"] # 0xe964 (en: 'left pointing triangle with bisecting bar', google translation) + - "": [T: "høyre trekant med midtstrek"] # 0xe965 (en: 'right pointing triangle with bisecting bar', google translation) + - "": [T: "lik med prikket øvre linje"] # 0xe966 (en: 'equals with dotted top line', google translation) + - "": [T: "foregår med kolon"] # 0xe967 (en: 'precedes with colon', google translation) + - "": [T: "følger med kolon"] # 0xe968 (en: 'succeeds with colon', google translation) + - "": [T: "mindre enn eller lik"] # 0xe969 (en: 'smaller than or equal slanted', google translation) + - "": [T: "større enn eller lik"] # 0xe96a (en: 'larger than or equal slanted', google translation) + - "": [T: "nøstet veldig mye mindre enn"] # 0xe96b (en: 'nested very much less than', google translation) + - "": [T: "nøstet veldig mye større enn"] # 0xe96c (en: 'nested very much greater than', google translation) + - "": [T: "forskjell mellom"] # 0xe96d (en: 'difference between variant', google translation) + - "": [T: "mindre enn som overlapper med større enn"] # 0xe96e (en: 'less than greater than overlay', google translation) + - "": [T: "logisk eller som overlapper med logisk og"] # 0xe96f (en: 'logical or logical and overlay', google translation) + - "": [T: "overmengde over overmengde"] # 0xe970 (google translation) + - "": [T: "delmengde over delmengde"] # 0xe971 (en: 'subset over subset', google translation) + - "": [T: "overmengde over delmengde"] # 0xe972 (en: 'superset over subset', google translation) + - "": [T: "delmengde over overmengde"] # 0xe973 (en: 'subset over superset', google translation) + - "": [T: "trippel vertikal strek"] # 0xe979 (google translation) + - "": [T: "parvise firedoble vertikale prikker"] # 0xe97a (en: 'paired quadruple vertical dots', google translation) + - "": [T: "vinkelrett over strek"] # 0xe97b (en: 'perpendicular over bar', google translation) + - "": [T: "venstre dreiekors dobbel vertikal strek"] # 0xe97c (en: 'left turnstile double vertical bar', google translation) + - "": [T: "dobbelt venstre dreiekors dobbel vertikal strek"] # 0xe97d (en: 'double left turnstile double vertical bar', google translation) + - "": [T: "vinkelrett over rotert vinkelrett"] # 0xe97e (en: 'perpendicular over inverted perpendicular', google translation) + - "": [T: "dobbelt venstre dreiekors vertikal strek"] # 0xe97f (en: 'double left turnstile vertical bar', google translation) + - "": [T: "sfærisk vinkel oppover"] # 0xe980 (en: 'spherical angle opening up', google translation) + - "": [T: "dobbel skråstrek"] # 0xe981 (en: 'double slash', google translation) + - "": [T: "rett vinkel med hjørne"] # 0xe982 (en: 'right angle with corner', google translation) + - "": [T: "sirkel med vertikal strek"] # 0xe984 (google translation) + - "": [T: "sirkel med divisjon"] # 0xe985 (google translation) + - "": [T: "stiplet skråstrek"] # 0xe986 (en: 'dashed solidus', google translation) + - "": [T: "stiplet omvendt skråstrek"] # 0xe987 (en: 'dashed backslash', google translation) + - "": [T: "stiplet midtlinje"] # 0xe988 (en: 'dashed mid line', google translation) + - "": [T: "stiplet vertikal strek"] # 0xe989 (en: 'dashed vertical bar', google translation) + - "": [T: "vinkelrett med s"] # 0xe98a (en: 'perpendicular with s', google translation) + - "": [T: "vinkel med s"] # 0xe98b (en: 'angle with s', google translation) + - "": [T: "sfærisk vinkel mot venstre"] # 0xe98c (en: 'spherical angle opening left', google translation) + - "": [T: "vinkel mot venstre"] # 0xe98d (en: 'angle opening left', google translation) + - "": [T: "vertikal strek med dobbel krok"] # 0xe98e (en: 'vertical bar with double hook', google translation) + - "": [T: "medium dot-operator fri radikal"] # 0xe98f (google translation) + - "": [T: "hvit oppoverpekende trekant over strek"] # 0xe990 (en: 'white up pointing triangle above bar', google translation) + - "": [T: "identisk og parallell med"] # 0xe991 (en: 'identical and parallel to', google translation) + - "": [T: "smash-produkt"] # 0xe992 (en: 'smash product', google translation) + - "": [T: "trippel vertikal strek med horisontal strek"] # 0xe993 (en: 'triple bar operator with horizontal bar', google translation) + - "": [T: "identisk med med dobbel skråstrek"] # 0xe994 (en: 'identical to with double slash', google translation) + - "": [T: "triple kryssende streker"] # 0xe995 (en: 'triple crossed bars', google translation) + - "": [T: "sirkel med vertikal strek"] # 0xe996 (en: 'vertical bar over circle', google translation) + - "": [T: "vertikal proporsjonal med"] # 0xe997 (en: 'vertical proportional to', google translation) + - "": [T: "måne i siste kvarter"] # 0xe998 (en: 'black last quarter moon', google translation) + - "": [T: "måne i første kvarter"] # 0xe999 (google translation) + - "": [T: "negativ sinusbølge"] # 0xe9a0 (en: 'negative sine wave', google translation) + - "": [T: "prikk i parentes"] # 0xe9a1 (en: 'parenthesized dot', google translation) + - "": [T: "parenteser"] # 0xe9a2 (en: 'parens', google translation) + - "": [T: "hvitt smil"] # 0xe9a3 (en: 'white smile', google translation) + - "": [T: "hvit rynke"] # 0xe9a4 (en: 'white frown', google translation) + - "": [T: "heksagon"] # 0xe9a5 (en: 'hexagon', google translation) + - "": [T: "ekvivalent med over pluss"] # 0xe9a6 (en: 'equivalent to over plus', google translation) + - "": [T: "pluss over ekvivalent med"] # 0xe9a7 (en: 'plus over equivalent to', google translation) + - "": [T: "snitt"] # 0xe9b0 (en: 'intersection serifs', google translation) + - "": [T: "union"] # 0xe9b1 (google translation) + - "": [T: "kvadratisk snitt"] # 0xe9b2 (en: 'square intersection serifs', google translation) + - "": [T: "kvadratisk union"] # 0xe9b3 (google translation) + - "": [T: "foregår ekvivalent med eller følger"] # 0xe9e0 (en: 'precedes equivalent to or succeeds', google translation) + - "": [T: "følger ekvivalent med eller foregår"] # 0xe9e1 (en: 'succeeds equivalent to or precedes', google translation) + - "": [T: "foregår tilnærmet lik eller følger"] # 0xe9e2 (en: 'precedes almost equal to or succeeds', google translation) + - "": [T: "følger tilnærmet lik eller foregår"] # 0xe9e3 (en: 'succeeds almost equal to or precedes', google translation) + - "": [T: "mindre enn ekvivalent med eller større enn"] # 0xe9f0 (en: 'less than equivalent to or greater than', google translation) + - "": [T: "større enn ekvivalent med eller mindre enn"] # 0xe9f1 (en: 'greater than equivalent to or less than', google translation) + - "": [T: "ikke mye mindre enn"] # 0xea00 (en: 'not vert much less than', google translation) + - "": [T: "ikke mye større enn"] # 0xea01 (en: 'not vert much greater than', google translation) + - "": [T: "ikke mye mindre enn"] # 0xea02 (en: 'not much less than variant', google translation) + - "": [T: "ikke mye større enn"] # 0xea03 (en: 'not much greater than variant', google translation) + - "": [T: "mindre enn vertikal ikke dobbel lik"] # 0xea04 (en: 'less vert not double equals', google translation) + - "": [T: "større enn vertikal ikke dobbel lik"] # 0xea05 (en: 'gt vert not double equals', google translation) + - "": [T: "ikke mindre enn eller lik"] # 0xea06 (en: 'not less than or equal to', google translation) + - "": [T: "ikke større enn eller lik"] # 0xea07 (en: 'not greater than or equal to', google translation) + - "": [T: "verken lik eller mindre enn"] # 0xea09 (en: 'neither equal to nor less than', google translation) + - "": [T: "inneholder ikke eller er lik"] # 0xea0a (en: 'does not contain or equal to', google translation) + - "": [T: "verken overmengde av eller lik"] # 0xea0b (en: 'neither superset of nor equal to', google translation) + - "": [T: "verken delmengde av eller lik"] # 0xea0c (en: 'neither subset of nor equal to', google translation) + - "": [T: "omvendt skråstrek delmengde"] # 0xea0d (en: 'reverse solidus subset', google translation) + - "": [T: "verken lik eller større enn"] # 0xea0e (en: 'neither equal to nor greater than', google translation) + - "": [T: "ikke minus tilde"] # 0xea0f (en: 'not minus tilde operator', google translation) + - "": [T: "verken lik eller mindre enn"] # 0xea10 (en: 'neither equal to nor less than', google translation) + - "": [T: "ikke tilde"] # 0xea11 (en: 'not tilde operator', google translation) + - "": [T: "ikke element i eller lik"] # 0xea12 (en: 'not element of or equal to', google translation) + - "": [T: "verken lik eller større enn"] # 0xea13 (en: 'neither equal to nor greater than', google translation) + - "": [T: "ikke tilnærmet lik"] # 0xea14 (en: 'not almost equal', google translation) + - "": [T: "ikke følger tilnærmet lik"] # 0xea15 (en: 'not succeeds similar', google translation) + - "": [T: "mindre enn eller lik med skråstrek"] # 0xea16 (en: 'less than or slanted equal to with slash', google translation) + - "": [T: "større enn eller lik med skråstrek"] # 0xea17 (en: 'greater than or slanted equal to with slash', google translation) + - "": [T: "overmengde skråstrek"] # 0xea1a (google translation) + - "": [T: "inneholder ikke"] # 0xea1b (en: 'does not contain', google translation) + - "": [T: "ikke mindre enn eller lik"] # 0xea1d (en: 'not less than or equal to', google translation) + - "": [T: "ikke større enn eller lik"] # 0xea1e (en: 'not greater than or equal to', google translation) + - "": [T: "ikke nesten lik minus"] # 0xea1f (en: 'not almost equal to minus', google translation) + - "": [T: "tilhører ikke mengde med prikk"] # 0xea22 (en: 'negated set membership dot above', google translation) + - "": [T: "ikke rett vinkel"] # 0xea2c (en: 'not vert angle', google translation) + - "": [T: "ikke parallell"] # 0xea2d (en: 'not parallel slanted', google translation) + - "": [T: "ikke strek"] # 0xea2e (en: 'not bar operator', google translation) + - "": [T: "ikke dobbel strek"] # 0xea2f (en: 'not double bar operator', google translation) + - "": [T: "ikke trippel strek"] # 0xea30 (en: 'not triple bar operator', google translation) + - "": [T: "mindre enn men ikke tilnærmet lik"] # 0xea32 (en: 'less than but not approximately equal to', google translation) + - "": [T: "større enn men ikke tilnærmet lik"] # 0xea33 (en: 'greater than but not approximately equal to', google translation) + - "": [T: "mindre enn eller ikke lik"] # 0xea34 (en: 'less than or not equal to', google translation) + - "": [T: "større enn eller ikke lik"] # 0xea35 (en: 'greater than or not equal to', google translation) + - "": [T: "ikke nøstet mindre enn"] # 0xea36 (en: 'not nested less than', google translation) + - "": [T: "ikke nøstet større enn"] # 0xea37 (en: 'not nested greater than', google translation) + - "": [T: "ikke mye mindre enn"] # 0xea38 (en: 'not much less than', google translation) + - "": [T: "ikke mye større enn"] # 0xea39 (en: 'not much greater than', google translation) + - "": [T: "foregår men ikke ekvivalent med"] # 0xea3a (en: 'precedes but not equivalent to', google translation) + - "": [T: "følger men ikke ekvivalent med"] # 0xea3b (en: 'succeeds but not equivalent to', google translation) + - "": [T: "foregår men ikke lik"] # 0xea3c (en: 'precedes but not equal to', google translation) + - "": [T: "følger men ikke lik"] # 0xea3d (en: 'succeeds but not equal to', google translation) + - "": [T: "ikke lik eller foregår"] # 0xea3e (en: 'does not equal or precede', google translation) + - "": [T: "ikke lik eller følger"] # 0xea3f (en: 'does not equal or succeed', google translation) + - "": [T: "foregår men ikke lik"] # 0xea40 (en: 'precedes but not equal to', google translation) + - "": [T: "følger men ikke lik"] # 0xea41 (en: 'succeeds but not equal to', google translation) + - "": [T: "ikke delmengde av eller lik"] # 0xea42 (en: 'not subset of nor equal to', google translation) + - "": [T: "ikke overmengde av eller lik"] # 0xea43 (en: 'not superset of nor equal to', google translation) + - "": [T: "delmengde av eller ikke lik"] # 0xea44 (en: 'subset of or not equal to', google translation) + - "": [T: "overmengde av eller ikke lik"] # 0xea45 (en: 'superset of or not equal to', google translation) + - "": [T: "ikke delmengde av eller lik"] # 0xea46 (en: 'not subset of nor equal to', google translation) + - "": [T: "ikke overmengde av eller lik"] # 0xea47 (en: 'not superset of nor equal to', google translation) + - "": [T: "ikke trippel mindre enn"] # 0xea48 (en: 'not triple less than', google translation) + - "": [T: "ikke trippel større enn"] # 0xea49 (en: 'not triple greater than', google translation) + - "": [T: "ikke foregår lik"] # 0xea4c (en: 'not precedes equals', google translation) + - "": [T: "ikke følger lik"] # 0xea4d (en: 'not succeeds equals', google translation) + - "": [T: "ikke normal undergruppe av med strek"] # 0xea50 (en: 'not normal subgroup of with bar', google translation) + - "": [T: "inneholder ikke som normal undergruppe med strek"] # 0xea51 (en: 'does not contain as normal subgroup with bar', google translation) + - "": [T: "ikke forskjell mellom"] # 0xea52 (en: 'not difference between', google translation) + - "": [T: "ikke geometrisk ekvivalent med"] # 0xea53 (en: 'not geometrically equivalent to', google translation) + - "": [T: "ikke vertikal tilnærmet lik"] # 0xea54 (en: 'not vert similar', google translation) + - "": [T: "ikke lik eller tilnærmet lik"] # 0xea55 (en: 'not equal or similar', google translation) + - "": [T: "ikke vertikal tilnærmet lik"] # 0xea56 (en: 'not vert approximate', google translation) + - "": [T: "ikke tilnærmet identisk med"] # 0xea57 (en: 'not approximately identical to', google translation) + - "": [T: "ikke differansen mellom"] # 0xea58 (en: 'not bumpy equals', google translation) + - "": [T: "ikke differansen mellom"] # 0xea59 (en: 'not bumpy single equals', google translation) + - "": [T: "ikke lik prikk"] # 0xea5a (en: 'not equal dot', google translation) + - "": [T: "speilvendt ikke ekvivalent med"] # 0xea5b (en: 'reverse not equivalent', google translation) + - "": [T: "ikke kvadratisk delmengde"] # 0xea60 (en: 'not square subset', google translation) + - "": [T: "ikke kvadratisk overmengde"] # 0xea61 (en: 'not square superset', google translation) + - "": [T: "ikke tilnærmet lik over lik"] # 0xea62 (en: 'not almost equal over equal', google translation) + - "": [T: "ikke strengt ekvivalent med"] # 0xea63 (en: 'not strictly equivalent to', google translation) + - "": [T: "ikke kongruent prikk"] # 0xea64 (en: 'not congruent dot', google translation) + - "": [T: "speilvendt ikke lik"] # 0xea65 (en: 'reverse not equal', google translation) + - "": [T: "ikke vertikal venstre trekant lik"] # 0xea70 (en: 'not vert left triangle equals', google translation) + - "": [T: "ikke vertikal høyre trekant lik"] # 0xea71 (en: 'not vert right triangle equals', google translation) + - "": [T: "ikke partiell"] # 0xea80 (en: 'not partial', google translation) + - "": [T: "pilforlenger"] # 0xeb00 (en: 'arrow embellishment extender', google translation) + - "": [T: "høyrepil over venstrepil"] # 0xeb01 (en: 'arrow rightwards over arrow leftwards', google translation) + - "": [T: "høyrepil over venstrepil"] # 0xeb02 (en: 'arrow rightwards over arrow leftwards', google translation) + - "": [T: "høyre-harpun over venstre-harpun"] # 0xeb03 (en: 'harpoon right over harpoon left', google translation) + - "": [T: "høyre-harpun over venstre-harpun"] # 0xeb04 (en: 'harpoon right over harpoon left', google translation) + - "": [T: "dobbel-pil nordøst sørvest"] # 0xeb05 (en: 'double arrow northeast southwest', google translation) + - "": [T: "dobbel-pil nordvest sørøst"] # 0xeb06 (en: 'double arrow northwest southeast', google translation) + - "": [T: "horisontal harpun-forlenger"] # 0xeb07 (en: 'horizontal harpoon extender', google translation) + - "": [T: "venstrepil i bue mot klokka"] # 0xeb08 (en: 'anticlockwise arc leftwards arrow', google translation) + - "": [T: "høyrepil i bue mot klokka"] # 0xeb09 (en: 'anticlockwise arc rightwards arrow', google translation) + - "": [T: "stor høyrepil"] # 0xeb0b (en: 'large rightwards arrow accent', google translation) + - "": [T: "stor venstrepil"] # 0xeb0c (en: 'large leftwards arrow accent', google translation) + - "": [T: "venstre pilspiss"] # 0xeb0d (en: 'leftwards arrowhead', google translation) + - "": [T: "høyre pilspiss"] # 0xeb0e (en: 'rightwards arrowhead', google translation) + - "": [T: "stor venstre-høyre-pil med strek"] # 0xeb0f (en: 'large left right arrow with stroke', google translation) + - "": [T: "horisontal dobbel pil-forlenger"] # 0xeb10 (en: 'horizontal double arrow extender', google translation) + - "": [T: "stor venstre-høyre-pil med strek"] # 0xeb11 (en: 'large left right double arrow with stroke', google translation) + - "": [T: "nedoverpil til venstre for oppoverpil"] # 0xeb12 (en: 'downwards arrow leftwards of upwards arrow', google translation) + - "": [T: "venstrepil med hjørne nedover"] # 0xeb13 (en: 'leftwards arrow with corner downwards', google translation) + - "": [T: "høyrepil med hjørne oppover"] # 0xeb14 (en: 'rightwards arrow with corner upwards', google translation) + - "": [T: "venstrepil med hjørne oppover"] # 0xeb15 (en: 'leftwards arrow with corner upwards', google translation) + - "": [T: "øvre halvsirkel-pil mot klokka med pluss"] # 0xeb16 (en: 'anticlockwise top semicircle arrow with plus', google translation) + - "": [T: "øvre halvsirkel-pil med klokka med minus"] # 0xeb17 (en: 'clockwise top semicircle arrow with minus', google translation) + - "": [T: "høyrepil med hale og strek"] # 0xeb18 (en: 'rightwards arrow with tail with stroke', google translation) + - "": [T: "høyre-harpun mothake ned"] # 0xeb19 (en: 'right harpoon down', google translation) + - "": [T: "venstre-harpun mothake ned"] # 0xeb1a (en: 'left harpoon down', google translation) + - "": [T: "venstre-høyre-harpun mothake ned"] # 0xeb1b (en: 'left right harpoon down', google translation) + - "": [T: "venstre-høyre-harpun mothake opp"] # 0xeb1c (en: 'left right harpoon up', google translation) + - "": [T: "opp-ned-harpun mothake venstre"] # 0xeb1d (en: 'up down harpoon left', google translation) + - "": [T: "opp-ned-harpun mothake høyre"] # 0xeb1e (en: 'up down harpoon right', google translation) + - "": [T: "oppoverpil til høyre for nedoverpil"] # 0xeb1f (en: 'upwards arrow to the right of downwards arrow', google translation) + - "": [T: "venstre-harpun mot strek mothake opp"] # 0xeb20 (en: 'leftwards harpoon to bar with barb upwards', google translation) + - "": [T: "høyre-harpun mot strek mothake opp"] # 0xeb21 (en: 'rightwards harpoon to bar with barb upwards', google translation) + - "": [T: "venstre-harpun mot strek mothake ned"] # 0xeb22 (en: 'leftwards harpoon to bar with barb downwards', google translation) + - "": [T: "høyre-harpun mot strek mothake ned"] # 0xeb23 (en: 'rightwards harpoon to bar with barb downwards', google translation) + - "": [T: "venstre-harpun fra strek mothake opp"] # 0xeb24 (en: 'leftwards harpoon from bar with barb upwards', google translation) + - "": [T: "høyre-harpun fra strek mothake opp"] # 0xeb25 (en: 'rightwards harpoon from bar with barb upwards', google translation) + - "": [T: "venstre-harpun fra strek mothake ned"] # 0xeb26 (en: 'leftwards harpoon from bar with barb downwards', google translation) + - "": [T: "høyre-harpun fra strek mothake ned"] # 0xeb27 (en: 'rightwards harpoon from bar with barb downwards', google translation) + - "": [T: "opp-harpun mot strek mothake venstre"] # 0xeb28 (en: 'upwards harpoon to bar with barb leftwards', google translation) + - "": [T: "ned-harpun mot strek mothake venstre"] # 0xeb29 (en: 'downwards harpoon to bar with barb leftwards', google translation) + - "": [T: "opp-harpun mot strek mothake høyre"] # 0xeb2a (en: 'upwards harpoon to bar with barb rightwards', google translation) + - "": [T: "ned-harpun mot strek mothake høyre"] # 0xeb2b (en: 'downwards harpoon to bar with barb rightwards', google translation) + - "": [T: "opp-harpun fra strek mothake venstre"] # 0xeb2c (en: 'upwards harpoon from bar with barb leftwards', google translation) + - "": [T: "ned-harpun fra strek mothake venstre"] # 0xeb2d (en: 'downwards harpoon from bar with barb leftwards', google translation) + - "": [T: "opp-harpun fra strek mothake høyre"] # 0xeb2e (en: 'upwards harpoon from bar with barb rightwards', google translation) + - "": [T: "ned-harpun fra strek mothake høyre"] # 0xeb2f (en: 'downwards harpoon from bar with barb rightwards', google translation) + - "": [T: "oppoverpil mot strek"] # 0xeb30 (en: 'upwards arrow to bar', google translation) + - "": [T: "nedoverpil mot strek"] # 0xeb31 (en: 'downwards arrow to bar', google translation) + - "": [T: "opp-harpun til venstre for ned-harpun"] # 0xeb32 (en: 'upwards harpoon to the left of downwards harpoon', google translation) + - "": [T: "opp-harpun til høyre for ned-harpun"] # 0xeb33 (en: 'upwards harpoon to the right of downwards harpoon', google translation) + - "": [T: "pilspiss oppover"] # 0xeb34 (en: 'upwards arrowhead', google translation) + - "": [T: "pilspiss nedover"] # 0xeb35 (en: 'downwards arrowhead', google translation) + - "": [T: "dobbel harpun venstre mothake ned høyre mothake opp"] # 0xeb36 (en: 'double harpoon with leftwards barb down rightwards barb up', google translation) + - "": [T: "dobbel harpun venstre mothake opp høyre mothake ned"] # 0xeb37 (en: 'double harpoon with leftwards barb up rightwards barb down', google translation) + - "": [T: "venstrepil over strek"] # 0xeb38 (en: 'leftwards arrow over bar', google translation) + - "": [T: "høyrepil over strek"] # 0xeb39 (en: 'rightwards arrow over bar', google translation) + - "": [T: "venstrepil under strek"] # 0xeb3a (en: 'leftwards arrow under bar', google translation) + - "": [T: "høyrepil under strek"] # 0xeb3b (en: 'rightwards arrow under bar', google translation) + - "": [T: "venstre-høyre trippel pil"] # 0xeb3c (en: 'left right triple arrow', google translation) + - "": [T: "dobbel-pil nordøst sørøst"] # 0xeb3f (en: 'double arrow northeast southeast', google translation) + - "": [T: "venstre halvsirkel-pil mot klokka"] # 0xeb40 (en: 'anticlockwise left semicircle arrow', google translation) + - "": [T: "venstre halvsirkel-pil med klokka"] # 0xeb41 (en: 'clockwise left semicircle arrow', google translation) + - "": [T: "venstre-høyre-pil i venstre åpen sirkel"] # 0xeb42 (en: 'left open circle left right arrow', google translation) + - "": [T: "høyrepil over tilde"] # 0xeb44 (en: 'rightwards arrow over tilde', google translation) + - "": [T: "venstrepil over tilde"] # 0xeb45 (en: 'leftwards arrow over tilde', google translation) + - "": [T: "venstre-harpun over strek"] # 0xeb48 (en: 'leftwards harpoon over bar', google translation) + - "": [T: "høyre-harpun over strek"] # 0xeb49 (en: 'rightwards harpoon over bar', google translation) + - "": [T: "venstre-harpun under strek"] # 0xeb4a (en: 'leftwards harpoon under bar', google translation) + - "": [T: "høyre-harpun under strek"] # 0xeb4b (en: 'rightwards harpoon under bar', google translation) + - "": [T: "sammenpresset venstrepil"] # 0xeb4c (en: 'squat black leftwards arrow', google translation) + - "": [T: "høyre halvsirkel-pil med klokka"] # 0xeb50 (en: 'clockwise right semicircle arrow', google translation) + - "": [T: "høyre halvsirkel-pil mot klokka"] # 0xeb51 (en: 'anticlockwise right semicircle arrow', google translation) + - "": [T: "venstre-høyre-harpun i venstre åpen sirkel"] # 0xeb52 (en: 'left open circle left right harpoon', google translation) + - "": [T: "oppoverpil til venstre for vertikal strek"] # 0xeb58 (en: 'upwards arrow leftwards of vertical bar', google translation) + - "": [T: "nedoverpil til venstre for vertikal strek"] # 0xeb59 (en: 'downwards arrow leftwards of vertical bar', google translation) + - "": [T: "oppoverpil til høyre for vertikal strek"] # 0xeb5a (en: 'upwards arrow rightwards of vertical bar', google translation) + - "": [T: "nedoverpil til høyre for vertikal strek"] # 0xeb5b (en: 'downwards arrow rightwards of vertical bar', google translation) + - "": [T: "høyrepil med krok ned"] # 0xeb5c (en: 'rightwards arrow with extended downwards hook', google translation) + - "": [T: "venstrepil med krok"] # 0xeb5d (en: 'leftwards arrow with extended hook', google translation) + - "": [T: "venstrepil med krok ned"] # 0xeb5e (en: 'leftwards arrow with extended downwards hook', google translation) + - "": [T: "høyrepil med krok"] # 0xeb5f (en: 'rightwards arrow with extended hook', google translation) + - "": [T: "ikke bølgete høyrepil"] # 0xeb60 (en: 'not right arrow wavy', google translation) + - "": [T: "ikke buet høyrepil"] # 0xeb61 (en: 'not right arrow curved', google translation) + - "": [T: "opp-harpun til venstre for vertikal strek"] # 0xeb68 (en: 'upwards harpoon leftwards of vertical bar', google translation) + - "": [T: "ned-harpun til venstre for vertikal strek"] # 0xeb69 (en: 'downwards harpoon leftwards of vertical bar', google translation) + - "": [T: "opp-harpun til høyre for vertikal strek"] # 0xeb6a (en: 'upwards harpoon rightwards of vertical bar', google translation) + - "": [T: "ned-harpun til høyre for vertikal strek"] # 0xeb6b (en: 'downwards harpoon rightwards of vertical bar', google translation) + - "": [T: "vertikal dobbel pil-forlenger"] # 0xeb6c (en: 'vertical double arrow extender', google translation) + - "": [T: "vertikal harpun med mothake venstre forlenger"] # 0xeb6d (en: 'vertical harpoon with barb left extender', google translation) + - "": [T: "vertikal harpun med mothake høyre forlenger"] # 0xeb6e (en: 'vertical harpoon with barb right extender', google translation) + - "": [T: "høyre-harpun over venstre-harpun høyre"] # 0xeb6f (en: 'right harpoon over left harpoon right', google translation) + - "": [T: "høyre-harpun over venstre-harpun venstre"] # 0xeb70 (en: 'right harpoon over left harpoon left', google translation) + - "": [T: "venstre-harpun over høyre-harpun høyre"] # 0xeb71 (en: 'left harpoon over right harpoon right', google translation) + - "": [T: "venstre-harpun over høyre-harpun venstre"] # 0xeb72 (en: 'left harpoon over right harpoon left', google translation) + - "": [T: "venstrepil fra strek pilspiss"] # 0xeb73 (en: 'leftwards arrow from bar arrowhead', google translation) + - "": [T: "venstre-høyre-pil fra strek forlenger"] # 0xeb74 (en: 'leftwards rightwards arrow from bar extender', google translation) + - "": [T: "venstrepil fra strek med hale"] # 0xeb75 (en: 'leftwards arrow from bar tail', google translation) + - "": [T: "høyrepil fra strek med hale"] # 0xeb76 (en: 'rightwards arrow from bar tail', google translation) + - "": [T: "høyrepil fra strek pilspiss"] # 0xeb77 (en: 'rightwards arrow from bar arrowhead', google translation) + - "": [T: "opp-harpun fra strek med mothake venstre pilspiss"] # 0xeb78 (en: 'upwards harpoon from bar with barb leftwards arrowhead', google translation) + - "": [T: "høyrepil over venstrepil høyre"] # 0xeb79 (en: 'rightwards arrow over leftwards arrow right', google translation) + - "": [T: "høyrepil over venstrepil venstre"] # 0xeb7a (en: 'rightwards arrow over leftwards arrow left', google translation) + - "": [T: "venstrepil over høyrepil høyre"] # 0xeb7b (en: 'leftwards arrow over rightwards arrow right', google translation) + - "": [T: "venstrepil over høyrepil venstre"] # 0xeb7c (en: 'leftwards arrow over rightwards arrow left', google translation) + - "": [T: "oppoverpil fra strek pilspiss"] # 0xeb7d (en: 'upwards arrow from bar arrowhead', google translation) + - "": [T: "oppoverpil fra strek hale"] # 0xeb7e (en: 'upwards arrow from bar tail', google translation) + - "": [T: "nedoverpil fra strek hale"] # 0xeb7f (en: 'downwards arrow from bar tail', google translation) + - "": [T: "nedoverpil fra strek pilspiss"] # 0xeb80 (en: 'downwards arrow from bar arrowhead', google translation) + - "": [T: "ned-harpun fra strek med mothake høyre pilspiss"] # 0xeb81 (en: 'downwards harpoon from bar with barb rightwards arrowhead', google translation) + - "": [T: "opp-harpun til venstre for ned-harpun bunn"] # 0xeb82 (en: 'upwards harpoon to the left of downwards harpoon bottom', google translation) + - "": [T: "opp-harpun til venstre for ned-harpun forlenger"] # 0xeb83 (en: 'upwards harpoon to the left of downwards harpoon extender', google translation) + - "": [T: "ned-harpun til venstre for opp-harpun topp"] # 0xeb84 (en: 'downwards harpoon to the left of upwards harpoon top', google translation) + - "": [T: "opp-harpun til venstre for ned-harpun topp"] # 0xeb85 (en: 'upwards harpoon to the left of downwards harpoon top', google translation) + - "": [T: "ned-harpun til venstre for opp-harpunens forlenger"] # 0xeb86 (en: 'downwards harpoon to the left of the upwards harpoon extender', google translation) + - "": [T: "ned-harpun til venstre for opp-harpunens bunn"] # 0xeb87 (en: 'downwards harpoon to the left of the upwards harpoon bottom', google translation) + - "": [T: "oppoverpil til venstre for nedoverpil bunn"] # 0xeb88 (en: 'upwards arrow leftwards of downwards arrow bottom', google translation) + - "": [T: "nedoverpil til venstre for oppoverpil topp"] # 0xeb89 (en: 'downwards arrow leftwards of upwards arrow top', google translation) + - "": [T: "oppoverpil til venstre for nedoverpil topp"] # 0xeb8a (en: 'upwards arrow leftwards of downwards arrow top', google translation) + - "": [T: "nedoverpil til venstre for oppoverpil bunn"] # 0xeb8b (en: 'downwards arrow leftwards of upwards arrow bottom', google translation) + - "": [T: "venstre-høyre-pil forlenger"] # 0xeb8c (en: 'leftwards rightwards arrows extender', google translation) + - "": [T: "nordøst-pil forlenger"] # 0xeb8d (google translation) + - "": [T: "nordvest-pil forlenger"] # 0xeb8e (google translation) + - "": [T: "nedoverpekende krøllparentes venstre"] # 0xec00 (en: 'down pointing brace left', google translation) + - "": [T: "nedoverpekende krøllparentes midten"] # 0xec01 (en: 'down pointing brace mid', google translation) + - "": [T: "nedoverpekende krøllparentes høyre"] # 0xec02 (en: 'down pointing brace right', google translation) + - "": [T: "horisontal krøllparentes forlenger"] # 0xec03 (en: 'horizontal brace extender', google translation) + - "": [T: "oppoverpekende krøllparentes venstre"] # 0xec04 (en: 'up pointing brace left', google translation) + - "": [T: "oppoverpekende krøllparentes midten"] # 0xec05 (en: 'up pointing brace mid', google translation) + - "": [T: "oppoverpekende krøllparentes høyre"] # 0xec06 (en: 'up-pointing brace right', google translation) + - "": [T: "venstre vertikal strek"] # 0xec07 (en: 'left vertical bar', google translation) + - "": [T: "høyre vertikal strek"] # 0xec08 (en: 'right vertical bar', google translation) + - "": [T: "venstre dobbel vertikal strek"] # 0xec09 (en: 'left double vertical bar', google translation) + - "": [T: "høyre dobbel vertikal strek"] # 0xec0a (en: 'right double vertical bar', google translation) + - "": [T: "horisontal hakeparentes forlenger"] # 0xec0b (en: 'horizontal bracket extender', google translation) + - "": [T: "under hakeparentes"] # 0xec0c (en: 'under square bracket', google translation) + - "⎵": [T: "under hakeparentes"] # 0x23b5 + - "": [T: "over hakeparentes"] # 0xec0d (en: 'over square bracket', google translation) + - "⎴": [T: "over hakeparentes"] # 0x23b4 + - "": [T: "under hakeparentes venstre"] # 0xec0e (en: 'under bracket left', google translation) + - "": [T: "under hakeparentes høyre"] # 0xec0f (en: 'under bracket right', google translation) + - "": [T: "over hakeparentes venstre"] # 0xec10 (en: 'over bracket left', google translation) + - "": [T: "over hakeparentes høyre"] # 0xec11 (en: 'over bracket right', google translation) + - "": [T: "venstreparentes 1"] # 0xec12 (en: 'left parens 1', google translation) + - "": [T: "venstreparentes 2"] # 0xec13 (en: 'left parens 2', google translation) + - "": [T: "venstreparentes 3"] # 0xec14 (en: 'left parens 3', google translation) + - "": [T: "venstreparentes 4"] # 0xec15 (en: 'left parens 4', google translation) + - "": [T: "høyreparentes 1"] # 0xec16 (en: 'right parens 1', google translation) + - "": [T: "høyreparentes 2"] # 0xec17 (en: 'right parens 2', google translation) + - "": [T: "høyreparentes 3"] # 0xec18 (en: 'right parens 3', google translation) + - "": [T: "høyreparentes 4"] # 0xec19 (en: 'right parens 4', google translation) + - "": [T: "radikal 1"] # 0xec1a (en: 'radical 1', google translation) + - "": [T: "radikal 2"] # 0xec1b (en: 'radical 2', google translation) + - "": [T: "radikal 3"] # 0xec1c (en: 'radical 3', google translation) + - "": [T: "radikal 4"] # 0xec1d (en: 'radical 4', google translation) + - "": [T: "radikal 5"] # 0xec1e (en: 'radical 5', google translation) + - "": [T: "radikal bunn"] # 0xec1f (en: 'radical bottom', google translation) + - "": [T: "radikal vertikal forlenger"] # 0xec20 (en: 'radical vertical extender', google translation) + - "": [T: "radikal topp"] # 0xec21 (en: 'radical top', google translation) + - "": [T: "venstre hvit hakeparentes topp"] # 0xec22 (en: 'left white bracket top', google translation) + - "": [T: "venstre hvit hakeparentes forlenger"] # 0xec23 (en: 'left white bracket extender', google translation) + - "": [T: "venstre hvit hakeparentes bunn"] # 0xec24 (en: 'left white bracket bottom', google translation) + - "": [T: "høyre hvit hakeparentes topp"] # 0xec25 (en: 'right white bracket top', google translation) + - "": [T: "høyre hvit hakeparentes forlenger"] # 0xec26 (en: 'right white bracket extender', google translation) + - "": [T: "høyre hvit hakeparentes bunn"] # 0xec27 (en: 'right white bracket bottom', google translation) + - "": [T: "venstre hvit krøllparentes"] # 0xec30 (en: 'left white curly bracket', google translation) + - "": [T: "høyre hvit krøllparentes"] # 0xec31 (en: 'right white curly bracket', google translation) + - "": [T: "lang divisjon"] # 0xec32 (en: 'long division sign', google translation) + - "": [T: "lang divisjon forlenger"] # 0xec33 (google translation) + - "": [T: "kort divisjon"] # 0xec34 (en: 'short division', google translation) + - "": [T: "dobbel sørvest til nordøst em-binding"] # 0xec40 (en: 'double southwest to northeast em bond', google translation) + - "": [T: "dobbel nordvest til sørøst em-binding"] # 0xec41 (en: 'double northwest to southeast em bond', google translation) + - "": [T: "enkel horisontal em-binding"] # 0xec42 (en: 'single horizontal em bond', google translation) + - "": [T: "dobbel horisontal em-binding"] # 0xec43 (en: 'double horizontal em bond', google translation) + - "": [T: "trippel horisontal em-binding"] # 0xec44 (en: 'triple horizontal em bond', google translation) + - "": [T: "enkel vertikal em-binding"] # 0xec45 (en: 'single vertical em bond', google translation) + - "": [T: "dobbel vertikal em-binding"] # 0xec46 (en: 'double vertical em bond', google translation) + - "": [T: "trippel vertikal em-binding"] # 0xec47 (google translation) + - "": [T: "mindre enn em-binding"] # 0xec48 (en: 'less than em bond', google translation) + - "": [T: "større enn em-binding"] # 0xec49 (en: 'greater than em bond', google translation) + - "": [T: "enkel horisontal en-binding"] # 0xec4a (en: 'single horizontal en bond', google translation) + - "": [T: "dobbel horisontal en-binding"] # 0xec4b (en: 'double horizontal en bond', google translation) + - "": [T: "trippel horisontal en-binding"] # 0xec4c (en: 'triple horizontal en bond', google translation) + - "": [T: "øvre venstre rektangel"] # 0xec80 (en: 'top left rectangle', google translation) + - "": [T: "nedre venstre rektangel"] # 0xec81 (en: 'bottom left rectangle', google translation) + - "": [T: "øvre høyre rektangel"] # 0xec90 (en: 'top right rectangle', google translation) + - "": [T: "nedre høyre rektangel"] # 0xec91 (en: 'bottom right rectangle', google translation) + - "": [T: "syntetisk divisjon hjørne"] # 0xec92 (en: 'synthetic division corner', google translation) + - "": [T: "syntetisk divisjon horisontal forlenger"] # 0xec93 (en: 'synthetic division horizontal extender', google translation) + - "": [T: "syntetisk divisjon vertikal forlenger"] # 0xec94 (en: 'synthetic division vertical extender', google translation) + - "": [T: "venstre tak gulv forlenger"] # 0xec95 (en: 'left ceiling floor extender', google translation) + - "": [T: "høyre tak gulv forlenger"] # 0xec96 (en: 'right ceiling floor extender', google translation) + - "": [T: "over hakeparentes forlenger"] # 0xec97 (en: 'over bracket extender', google translation) + - "": [T: "vertikal strek forlenger"] # 0xec98 (en: 'vertical bar extender', google translation) + - "": [T: "venstre dobbel vertikal strek forlenger"] # 0xec99 (en: 'left double vertical bar extender', google translation) + - "": [T: "horisontal strek forlenger"] # 0xec9a (en: 'horizontal bar extender', google translation) + - "": [T: "under hakeparentes forlenger"] # 0xec9c (en: 'under bracket extender', google translation) + - "": [T: "nedoverpekende parentes høyre"] # 0xec9d (en: 'down pointing paren right', google translation) + - "": [T: "nedoverpekende parentes forlenger"] # 0xec9e (en: 'down pointing paren extender', google translation) + - "": [T: "nedoverpekende parentes venstre"] # 0xec9f (en: 'down pointing paren left', google translation) + - "": [T: "oppoverpekende krøllparentes forlenger"] # 0xeca0 (en: 'up pointing brace extender', google translation) + - "": [T: "oppoverpekende parentes venstre"] # 0xeca1 (en: 'up pointing paren left', google translation) + - "": [T: "oppoverpekende parentes forlenger"] # 0xeca2 (en: 'up pointing paren extender', google translation) + - "": [T: "oppoverpekende parentes høyre"] # 0xeca3 (en: 'up pointing paren right', google translation) + - "": [T: "nedoverpekende krøllparentes forlenger"] # 0xeca4 (en: 'down pointing brace extender', google translation) + - "": [T: "plancks konstant over to pi strek"] # 0xed00 (en: 'planck constant over two pi bar', google translation) + - "": [T: "speilvendt g"] # 0xed01 (en: 'mirror g', google translation) + - "": [T: "j uten prikk"] # 0xed02 (google translation) + - "": [T: "digamma"] # 0xed03 (google translation) + - "ϝ": [T: "digamma"] # 0x3dd + - "": [t: ""] # 0xed10 (en: 'd', google translation) + - "": [t: ""] # 0xed11 (en: 'e', google translation) + - "": [t: ""] # 0xed12 (en: 'i', google translation) + - "": [T: ""] # 0xed13 (en: 'j', google translation) + - "ⅅ": + - SPELL: "translate('.', 'ⅅ', 'DD')" # 0xed16, 0x2145 + +# The private use chars are from MathType + - "": [T: "kurveintegral-loop mot klokka"] # 0xee00 (en: 'anticlockwise contour integral loop', google translation) + - "": [T: "kurveintegral-loop med klokka"] # 0xee01 (en: 'clockwise contour integral loop', google translation) + - "": [T: ""] # 0xee04 + - "": [T: ""] # 0xee05 + - "": [T: ""] # 0xee06 + - "": [T: ""] # 0xee07 + - "": [T: ""] # 0xee08 + - "": [T: ""] # 0xee09 + - "": [T: ""] # 0xee0a + - "": [T: ""] # 0xee0b + - "": [T: ""] # 0xee0c + - "": [T: "joint status"] # 0xee0d (en: 'joint status embellishment', google translation) + - "": [T: "joint status venstre"] # 0xee0e (en: 'joint status embellishment left', google translation) + - "": [T: "joint status høyre"] # 0xee0f (en: 'joint status embellishment right', google translation) + - "": [T: "joint status forlenger"] # 0xee10 (en: 'joint status embellishment extender', google translation) + - "": [T: "integral-loop"] # 0xee11 (en: 'integral loop', google translation) + - "": [T: "dobbel integral-loop"] # 0xee12 (google translation) + - "": [T: "trippel integral-loop"] # 0xee13 (en: 'integral loop triple', google translation) + - "": [T: "ekspanderende dobbel integral-loop"] # 0xee15 (google translation) + - "": [T: "ekspanderende trippel integral-loop"] # 0xee16 (en: 'expanding integral loop triple', google translation) + - "": [T: "asymptotisk lik"] # 0xee17 (en: 'asymptotically equal to accent', google translation) + - "": [T: "lik"] # 0xee18 (en: 'equal sign accent', google translation) + - "": [T: "kvadrupelt primtegn"] # 0xee19 (en: 'quadruple prime', google translation) + - "": [T: "strek med åpen sirkel venstre"] # 0xee1a (en: 'bar accent with open circle left', google translation) + - "": [T: "strek med lukket sirkel venstre"] # 0xee1b (en: 'bar accent with closed circle left', google translation) + - "": [T: "strek med åpen sirkel høyre"] # 0xee1c (en: 'bar accent with open circle right', google translation) + - "": [T: "strek med prikk"] # 0xee1d (en: 'bar accent with over dot', google translation) + - "": [T: "strek over prikk"] # 0xee1e (en: 'bar accent with under dot', google translation) + - "": [T: "strek med dobbel prikk over"] # 0xee1f (en: 'bar accent with double over dot', google translation) + - "": [T: "strek over dobbel prikk"] # 0xee20 (en: 'bar accent with double under dot', google translation) + - "": [T: "strek med hatt"] # 0xee21 (en: 'bar accent with caret', google translation) + - "": [T: "fet understrek"] # 0xee22 (en: 'thick under bar accent', google translation) + - "": [T: "strek med lukket sirkel høyre"] # 0xee23 (en: 'bar accent with closed circle right', google translation) + - "": [T: "stor prikk"] # 0xee24 (en: 'large dot above', google translation) + - "": [T: "justeringsmerke"] # 0xef00 (en: 'alignment mark', google translation) + - "": [T: ""] # 0xef01 + - "​": [T: ""] # 0x200b + - "": [T: ""] # 0xef02 + - " ": [T: ""] # 0x2009 + - "": [T: ""] # 0xef03 + - " ": [T: ""] # 0x205f + - "": [T: ""] # 0xef04 + - "": [T: ""] # 0xef05 + - "": [T: ""] # 0xef06 + - "": [T: ""] # 0xef07 + - "": [T: ""] # 0xef08 + - "": [T: ""] # 0xef09 + - "": [T: ""] # 0xef0a + - " ": [T: ""] # 0x200a + - "": [T: ""] # 0xef22 + - "": [T: ""] # 0xef23 + - "": [T: ""] # 0xef24 + - "": [T: ""] # 0xef29 + - "": [T: "savnet begrep"] # 0xef41 (en: 'missing term', google translation) + - "": [T: "kurveintegral med klokka pil til venstre"] # 0xef80 (en: 'clockwise contour integral arrow on left', google translation) + - "": [T: "integral med kvadrat"] # 0xef81 (en: 'integral with square', google translation) + - "": [T: "integral med skråstrek"] # 0xef82 (en: 'integral with slash', google translation) + - "": [T: "speilvendt integral"] # 0xef83 (en: 'reversed integral', google translation) + - "": [T: "dobbel null over dobbel null"] # 0xef90 (en: 'double zero over double zero', google translation) + - "": [T: "null med skråstrek"] # 0xef91 (en: 'zero with slash', google translation) + #------------------------------------------------------------------------------------------------------------- + # fraktur chars in math alphabetic block and also MathType private use area + # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display + - "𝔄-𝔜": # 0x1d504 - 0x1d51d ('z' version is reserved) + - T: "fraktur" # (google translation) + - SPELL: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" + - "-": # 0xf000 - 0xf018 + - T: "fraktur" # (google translation) + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" + + - "𝔞-𝔷": # 0x1d51e - 0x1d537 + - T: "fraktur" # (google translation) + - SPELL: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf01a - 0xf033 + - T: "fraktur" # (google translation) + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝕬-𝖅": # 0x1D56C - 0x1D585 + - T: "fraktur" # (google translation) + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf040 - 0xf059 + - T: "fraktur" # (google translation) + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝖆-𝖟": # 0x1d586 - 0x1d59f + - T: "fraktur" # (google translation) + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf05a - 0xf073 + - T: "fraktur" # (google translation) + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + # double struck (blackboard bold) chars in math alphabetic block and also MathType private use area + # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display + - "𝔸-𝕐": # 0x1d504 - 0x1d51d ('z' version is reserved) + - T: "dobbeltstreket" # (en: 'double struck', google translation) + - SPELL: "translate('.', '𝔸𝔹𝔺𝔻𝔼𝔽𝔾𝔿𝕀𝕁𝕂𝕃𝕄𝕅𝕆𝕇𝕈𝕉𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf080 - 0xf098 + - T: "dobbeltstreket" # (en: 'double struck', google translation) + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝕒-𝕫": # 0x1d552 - 0x1d56b + - T: "dobbeltstreket" # (en: 'double struck', google translation) + - SPELL: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf09a - 0xf0b3 + - T: "dobbeltstreket" # (en: 'double struck', google translation) + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 + - T: "dobbeltstreket" # (en: 'double struck', google translation) + - SPELL: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" + - "-": # 0xf0c0 - 0xf0c9 + - T: "dobbeltstreket" # (en: 'double struck', google translation) + - SPELL: "translate('.', '', '0123456789')" + + - "": [T: "dobbeltstreket nabla"] # 0xf0ca (en: 'double struck nabla', google translation) + - "": [T: "dobbeltstreket eulerkonstant"] # 0xf0cb (en: 'double struck euler constant', google translation) + + # script chars in math alphabetic block and also MathType private use area + # SWEDISH: We've used "skrivstilt" instead of skript for clarity + # NORWEGIAN: Used "script font" + - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 + - T: "script font" # (en: 'script', google translation) + - SPELL: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf100 - 0xf119 + - T: "script font" # (en: 'script', google translation) + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf + - T: "script font" # (en: 'script', google translation) + - SPELL: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf11a - 0xf133 + - T: "script font" # (en: 'script', google translation) + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + # bold script chars in math alphabetic block and also MathType private use area + - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 + - T: "script font" # (en: 'script bold', google translation) + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf140 - 0xf159 + - T: "script font" # (en: 'script bold', google translation) + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝓪-𝔃": # 0x1d4ea - 0x1d503 + - T: "script font" # (en: 'script bold', google translation) + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf15a - 0xf173 + - T: "script font" # (en: 'script bold', google translation) + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf180 - 0xf199 + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "": # 0xf19a + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "stor"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "ligatur a e"] # (en: 'ligature ae', google translation) + - "": # 0xf19b + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "stor"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "dobbel s"] # (en: 'sharp s', google translation) + - "": # 0xf19c + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "stor"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "ø"] # (en: 'o with stroke', google translation) + + # MathType only has a few of the cap Greek letters in PUA + - "": # 0xf201 - 0xf209 + - T: "dobbeltstreket" # (en: 'double struck', google translation) + - SPELL: "translate('.', '', 'ΔΨΛΠΣΘΓΩΥ')" + + - "-": # 0xf220 - 0xf236 + - T: "dobbeltstreket" # (en: 'double struck', google translation) + - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "": [T: "dobbeltstreket sluttsigma"] # 0xf237 (en: 'double struck final sigma', google translation) + - "": [T: "dobbeltstreket rho"] # 0xf250 (en: 'double struck rho', google translation) + - "": [T: "dobbeltstreket fi"] # 0xf251 (en: 'double struck phi', google translation) + - "𝐀-𝐙": # 0x1d400 - 0x1d419 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf260 - 0xf279 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝐚-𝐳": # 0x1d41a - 0x1d433 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf27a - 0xf293 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝐴-𝑍": # 0x1d434 - 0x1d44d + - SPELL: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf294 - 0xf2ad + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝑎-𝑧": # 0x1d44e - 0x1d467 + - SPELL: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf2ae - 0xf2c7 + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝑨-𝒁": # 0x1d468 - 0x1d481 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf2c8 - 0xf2e1 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝒂-𝒛": # 0x1d482 - 0x1d49b + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf2e2 - 0xf2fb + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 + - SPELL: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf300 - 0xf319 + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 + - SPELL: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf31a - 0xf333 + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf334 - 0xf34d + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝗮-𝘇": # 0x1d5ee - 0x1d607 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf34e - 0xf367 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝘈-𝘡": # 0x1d608 - 0x1d621 + - SPELL: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": # 0xf368 - 0xf381 + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝘢-𝘻": # 0x1d622 - 0x1d63b + - SPELL: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf382 - 0xf39b + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝘼-𝙕": # 0x1d63c - 0x1d655 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf39c - 0xf3b5 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝙖-𝙯": # 0x1d656 - 0x1d66f + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf3b6 - 0xf3cf + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝙰-𝚉": # 0x1d670 - 0x1d689 + - SPELL: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf3d0 - 0xf3e9 + - SPELL: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 + - SPELL: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf3ea - 0xf403 + - SPELL: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "": [T: "i uten prikk"] # 0xf404 (google translation) + - "𝚤": [T: "kursiv i uten prikk"] # 0x1d6a4 (en: 'dotless i', google: 'dotless i') + - "𝚥": [T: "kursiv j uten prikk"] # 0x1d6a5 (en: 'dotless j', google: 'dotless j') + + - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf408 - 0xf420 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf422 - 0xf43a + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "": [T: "fet nabla"] # 0xf421 (en: 'bold nabla', google translation) + - "𝛁": [T: "fet nabla"] # 0x1d6c1 (en: 'bold nabla', google translation) + + - "𝛛𝛜𝛝𝛞𝛟𝛠𝛡": # 0x1D6DB - 0x1D6E1 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" + + - "": # 0xF43C - 0xF441 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', '∂εθκφρπ')" + + - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa + - SPELL: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf442 - 0xf45a + - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝛼-𝜔": # 0x1d6fc - 0x1d714 + - SPELL: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓𝜔', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf45c - 0xf474 + - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "": [T: "kursiv nabla"] # 0xf45b (en: 'italic nabla', google translation) + - "𝛻": [T: "kursiv nabla"] # 0x1d6fb (en: 'italic nabla', google translation) + + - "𝜕𝜖𝜗𝜘𝜙𝜚𝜛": # 0x1d715 - 0x1d71b + - SPELL: "translate('.', '𝜕𝜖𝜗𝜘𝜙𝜚𝜛', '∂εθκφρπ')" + + - "": # 0xf475 - 0xf47b + - SPELL: "translate('.', '', '∂εθκφρπ')" + + - "𝜜-𝜴": # 0x1d71c - 0x1d734 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf47c - 0xf494 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝜶-𝝎": # 0x1d736 - 0x1d74e + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf496 - 0xf4ae + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": # 0x1d74f - 0x1d755 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εθκφρπ')" + + - "": # 0xf422 - 0xf43a + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', '∂εθκφρπ')" + + - "𝜵": [T: "fet kursiv nabla"] # 0x1d735 (en: 'bold italic nabla', google translation) + - "": [T: "fet kursiv nabla"] # 0xf495 (en: 'bold italic nabla', google translation) + + - "𝝖-𝝮": # 0x1d756 - 0x1d76e + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "-": # 0xf4b6 - 0xf4ce + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝝰-𝞈": # 0x1d770 - 0x1d788 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇𝞈', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf4d0 - 0xf4e8 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝞉𝞊𝞋𝞌𝞍𝞎𝞏": # 0x1d789 - 0x1d78f + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝞉𝞊𝞋𝞌𝞍𝞎𝞏', '∂εθκφρπ')" + + - "": # 0xf4e9 - 0xf4ef + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', '∂εθκφρπ')" + + - "": [T: "fet nabla"] # 0xf4cf (en: 'bold nabla', google translation) + - "𝝯": [T: "fet nabla"] # 0x1d76f (en: 'bold nabla', google translation) + + - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf4f0 - 0xf508 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝞪-𝟂": # 0x1d7aa - 0x1d7c2 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf50a - 0xf522 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": # 0x1d7c3 - 0x1d7c9 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝟃𝟄𝟅𝟆𝟇𝟈𝟉', '∂εθκφρπ')" + + - "": # 0xf523 - 0xf529 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', '∂εθκφρπ')" + + - "": [T: "fet nabla"] # 0xf509 (en: 'bold nabla', google translation) + - "𝞩": [T: "fet nabla"] # 0x1d7a9 (en: 'bold nabla', google translation) + + - "-": # 0xf52e - 0xf537 (old MathType) + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', '0123456789')" + + - "𝟎-𝟗": # 0x1d7ce - 0x1d7d7 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" + + - "-": # 0xf542 - 0xf54b (old MathType) + - SPELL: "translate('.', '', '0123456789')" + + - "𝟢-𝟫": # 0x1d7e2 - 0x1d7eb (old MathType) + - SPELL: "translate('.', '𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫', '0123456789')" + + - "-": # 0xf54c - 0xf555 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '', '0123456789')" + + - "𝟬-𝟵": # 0x1d7ec - 0x1d7f5 + - test: + if: "not($IgnoreBold)" + then: [T: "fet"] + - SPELL: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" + + - "-": # 0xf556 - 0xf55f (old MathType) + - SPELL: "translate('.', '', '0123456789')" + + - "𝟶-𝟿": # 0x1d7f6 - 0x1d7ff + - SPELL: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" + + - "": [T: "ukjent tegn"] # 0xf700 (en: 'unknown character', google translation) + - "": [T: "nedre høyre og nedre venstre trekanter"] # 0xf726 (en: 'lower right and lower left triangles', google translation) + - "": [T: "horisontal ellipse forlenger"] # 0xf72d (en: 'horizontal ellipsis extender', google translation) + - "": [T: "midtlinje horisontal ellipse forlenger"] # 0xf72e (en: 'midline horizontal ellipsis extender', google translation) + - "": [T: "radikal forlenger"] # 0xf8e5 (en: 'radical extender', google translation) + - "": [T: "vertikal pil-forlenger"] # 0xf8e6 (en: 'vertical arrow extender', google translation) + - "": [T: "horisontal pil-forlenger"] # 0xf8e7 (en: 'horizontal arrow extender', google translation) + - "": [T: "registrert"] # 0xf8e8 (en: 'registered sign sans serif', google translation) + - "": [T: "opphavsrett"] # 0xf8e9 (google translation) + - "": [T: "varemerke"] # 0xf8ea (google translation) + - "": [T: "venstreparentes topp"] # 0xf8eb (en: 'left paren top', google translation) + - "": [T: "venstreparentes forlenger"] # 0xf8ec (en: 'left paren extender', google translation) + - "": [T: "venstreparentes bunn"] # 0xf8ed (en: 'left paren bottom', google translation) + - "": [T: "venstre hakeparentes topp"] # 0xf8ee (en: 'left bracket top', google translation) + - "": [T: "venstre hakeparentes forlenger"] # 0xf8ef (en: 'left bracket extender', google translation) + - "": [T: "venstre hakeparentes bunn"] # 0xf8f0 (en: 'left bracket bottom', google translation) + - "": [T: "venstre krøllparentes topp"] # 0xf8f1 (en: 'left brace top', google translation) + - "": [T: "venstre krøllparentes midten"] # 0xf8f2 (en: 'left brace mid', google translation) + - "": [T: "venstre krøllparentes bunn"] # 0xf8f3 (en: 'left brace bottom', google translation) + - "": [T: "krøllparentes forlenger"] # 0xf8f4 (en: 'brace extender', google translation) + - "": [T: "integral forlenger"] # 0xf8f5 (en: 'integral extender', google translation) + - "": [T: "høyreparentes topp"] # 0xf8f6 (en: 'right paren top', google translation) + - "": [T: "høyreparentes forlenger"] # 0xf8f7 (en: 'right paren extender', google translation) + - "": [T: "høyreparentes bunn"] # 0xf8f8 (en: 'right paren bottom', google translation) + - "": [T: "høyre hakeparentes topp"] # 0xf8f9 (en: 'right bracket top', google translation) + - "": [T: "høyre hakeparentes forlenger"] # 0xf8fa (en: 'right bracket extender', google translation) + - "": [T: "høyre hakeparentes bunn"] # 0xf8fb (en: 'right bracket bottom', google translation) + - "": [T: "høyre krøllparentes topp"] # 0xf8fc (en: 'right brace top', google translation) + - "": [T: "høyre krøllparentes midten"] # 0xf8fd (en: 'right brace mid', google translation) + - "": [T: "høyre krøllparentes bunn"] # 0xf8fe (en: 'right brace bottom', google translation) + - "": [T: "apple logo"] # 0xf8ff (en: 'apple logo', google translation) + #-------------------------------------------------------------------------------------------------------------- + #Alphabetic presentation forms + - "ff": [T: "f f"] # 0xfb00 (en: 'ff', google: 'ff') + - "fi": [T: "f i"] # 0xfb01 (en: 'fi', google: 'fi') + - "fl": [T: "f l"] # 0xfb02 (en: 'fl', google: 'fl') + - "ffi": [T: "f f i"] # 0xfb03 (en: 'ffi', google: 'ffi') + - "ffl": [T: "f f l"] # 0xfb04 (en: 'ffl', google: 'ffl') + - "ſt": [T: "f t"] # 0xfb05 (en: 'ft', google translation) + - "st": [T: "s t"] # 0xfb06 (google translation) + - "﬩": [T: "hebraisk bokstav alternativ pluss"] # 0xfb29 + #------------------------------------------------------------------------------------------------------------------ + # Combining half marks + - "︠": [T: "ligatur venstre halvdel"] # 0xfe20 (en: 'ligature left half embellishment', google translation) + - "︡": [T: "ligatur høyre halvdel"] # 0xfe21 (en: 'ligature right half embellishment', google translation) + - "︢": [T: "dobbel tilde venstre halvdel"] # 0xfe22 (en: 'double tilde left half embellishment', google translation) + - "︣": [T: "dobbel tilde høyre halvdel"] # 0xfe23 (en: 'double tilde right half embellishment', google translation) + - "︤": [T: "makron venstre halvdel"] # 0xfe24 (en: 'macron left half embellishment', google translation) + - "︥": [T: "makron høyre halvdel"] # 0xfe25 (en: 'macron right half embellishment', google translation) + - "︦": [T: "sammenkoblet makron"] # 0xfe26 (en: 'conjoining macron embellishment', google translation) + #----------------------------------------------------------------------------------------------------------------- + #CJK compatibility forms + - "︵": [T: "parentes over"] # 0xfe35 + - "︶": [T: "parentes under"] # 0xfe36 + - "︷": [T: "krøllparentes over"] # 0xfe37 (en: 'over brace') + - "︸": [T: "krøllparentes under"] # 0xfe38 (en: 'under brace') + - "︿": [T: "vinkelparentes over"] # 0xfe3f + - "﹀": [T: "vinkelparentes under"] # 0xfe40 +#------------------------------------------------------------------------------------------------------------------ +#Halfwidth and Fullwidth forms + - "﹡": [T: "liten asterisk"] # 0xfe61 + - "﹢": [T: "liten pluss"] # 0xfe62 + - "﹣": [T: "liten minus"] # 0xfe63 + - "﹤": [T: "liten mindre enn"] # 0xfe64 + - "﹥": [T: "liten større enn"] # 0xfe65 + - "﹦": [T: "lite likhetstegn"] # 0xfe66 + - "+": [T: "pluss"] # 0xff0b + - "<": [T: "mindre enn"] # 0xff1c + - "=": [T: "lik"] # 0xff1d + - ">": [T: "større enn"] # 0xff1e + - "\": [T: "omvendt skråstrek"] # 0xff3c + - "^": [T: "hatt"] # 0xff3e + - "|": # 0xff5c + # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' + - with: + variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) + replace: + - test: + - if: "$SpeechStyle != 'ClearSpeak'" + then_test: + if: "$DefaultToGiven" + then: [pause: short, T: "gitt"] + else: [T: "vertikal strek"] + - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" + then: [T: "vertikal strek"] + - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" + then: [T: "slik at"] + - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" + then: [pause: short, T: "gitt"] + - else: [T: "deler"] + - "~": [T: "tilde"] # 0xff5e + - "¬": [T: "ikke"] # 0xffe2 + - "←": [T: "venstrepil"] # 0xffe9 + - "↑": [T: "oppoverpil"] # 0xffea + - "→": [T: "høyrepil"] # 0xffeb + - "↓": [T: "nedoverpil"] # 0xffec + #-------------------------------------------------------------------------------------------------------------------- + #Small form variants + - "﹨": [T: "liten speilvendt skråstrek"] # 0xfe68 + #--------------------------------------------------------------------------------------------------------------------- + #Specials + - "": [T: "ukjent eller savnet objekt"] # 0xfffc (en: 'unknown or missing object', google translation) + - "�": [T: "ukjent eller savnet tegn"] # 0xfffd (google: 'okänd eller saknad karaktär') + + - "🣑": [T: "er i likevekt med"] # 0x1F8D1 + - "🣒": [T: "er i likevekt, forskjøvet mot høyre, med"] # 0x1F8D2 + - "🣓": [T: "er i likevekt, forskjøvet mot venstre, med"] # 0x1F8D3 + +# MathJax v4 has adopted these PUA values for some partial chem bonds that aren't in Unicode + - "\uE410": [T: "delvis enkeltbinding"] # 0xe410 + - "\uE411": [T: "delvis dobbeltbinding"] # 0xe411 + - "\uE412": [T: "delvis trippelbinding"] # 0xe412 + +# MathJax v4 also adopted these PUA values for some arrows thar are in Unicode +# Hopefully these will be exported properly in future versions of MathJax + - "\uE428": [SPELL: "'⟵'"] # 0xe428 defer to def of arrow + - "\uE429": [SPELL: "'⟶'"] # 0xe429 defer to def of arrow + - "\uE42A": [SPELL: "'⟷'"] # 0xe42a defer to def of arrow + - "\uE408": [SPELL: "'🣑'"] # 0xe408 defer to def of arrow + - "\uE409": [SPELL: "'🣒'"] # 0xe409 defer to def of arrow + - "\uE40A": [SPELL: "'🣓'"] # 0xe40a defer to def of arrow + - "\uE42B": [SPELL: "'⇄'"] # 0xe42b defer to def of arrow + - "\uE42C": [SPELL: "'←'"] # 0xe42c defer to def of arrow + - "\uE42D": [SPELL: "'→'"] # 0xe42d defer to def of arrow + - "\uE42E": [SPELL: "'⇄'"] # 0xe42e defer to def of arrow diff --git a/Rules/Languages/nb/unicode.yaml b/Rules/Languages/nb/unicode.yaml index c14cfa759..ee5c5a931 100644 --- a/Rules/Languages/nb/unicode.yaml +++ b/Rules/Languages/nb/unicode.yaml @@ -1,486 +1,486 @@ ---- - - "a-z": - - test: - if: "$TTS='none'" - then: [T: "."] # (en: '.', google translation) - else: [SPELL: "'.'"] - - # Capital letters are a little tricky: users can pick their favorite word (something that was requested) and - # screen readers have options to use pitch changes or beeps instead of or in addition to say "cap" - # Also, if a user can see the screen, they probably don't need to hear "cap", but if they specified an override, they must want to hear the override. - - - "A-Z": - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "stor"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [SPELL: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] - - - "0-9": [T: "."] # (en: '.', google: 'A') - - - " ": [T: " "] # 0x20 #NORWEGIAN: Added from English version. Not in Swedish version. - - - "!": # 0x21 - - test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" #NORWEGIAN: Changed from ":structure" to be equal to English translation - then_test: - if: "$Verbosity = 'Terse'" - then: [T: "utropstegn"] # 0x21 (en: 'bang', google translation) - else: [T: "utropstegn"] # 0x21 (en: 'exclamation point') - else: [T: "fakultet"] # 0x21 (en: 'factorial') - - - "\"": [T: "anførselstegn"] # 0x22 (en: 'quotation mark') - - "#": [T: "nummertegn"] # 0x23 (en: 'number', MathPlayer: 'numeriskt tecken', google: 'siffra') - - "$": [T: "dollar"] # 0x24 (en: 'dollars') - - "%": [T: "prosent"] # 0x25 (en: 'percent') - - "&": [T: "og-tegn"] # 0x26 (en: 'ampersand') - - "'": [T: "apostrof"] # 0x27 (en: 'apostrophe') - - "(": # 0x28 - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then_test: - if: "$Verbosity='Terse'" - then: [pause: short, T: "startparentes"] # 0x28 (en: 'open', google translation) - else: [pause: short, T: "startparentes"] # 0x28 (en: 'open paren') - else: [T: "venstreparentes"] # 0x28 (en: 'left paren') - - pause: short - - ")": # 0x29 - - pause: short - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then_test: - if: "$Verbosity='Terse'" - then: [T: "sluttparentes"] # 0x29 (en: 'close', google translation) - else: [T: "sluttparentes"] # 0x29 (en: 'close paren') - else: [T: "høyreparentes"] # 0x29 (en: 'right paren') - - - "*": # 0x2a - test: - if: "parent::*[name(.)='msup' or name(.)='msubsup' or name(.)='skip-super']" - then: [T: "stjerne"] # 0x2a (en: 'star', google translation) - else: [T: "ganger"] # 0x2a (en: 'times') - - "+": [T: "pluss"] # 0x2b - - ",": # 0x2c - # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent - # that this test is here and not with "…" is not ideal, but seems simplest - test: - if: - - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " - # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' - # speak "comma" when not adjacent to '…' - - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " - # except if expression starts with '…' - - "../*[1][.='…'] " - then: - - T: "komma" # (en: 'comma', google translation) - - test: - if: "$Verbosity != Terse" - then: [pause: short] - # else silent - - - "-": [T: "minus"] # 0x2d - - ".": # 0x2e - - test: - if: "parent::*[1][self::m:mn]" - then: [T: "punktum"] # (en: 'point', google translation) - else: [T: "prikk"] # (en: 'dot') - - "/": # 0x2f (en: 'divided by') - - test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [T: "skråstrek"] # 0x2f - else: [T: "delt på"] # 0x2f - - ":": [T: "kolon"] # 0x3a (en: 'colon') - - ";": [T: "semikolon"] # 0x3b (en: 'semicolon') - - "<": # 0x3c - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "mindre enn" # (en: 'less than') - - "=": # 0x3d # audit-ignore - # SWEDISH: We remove "är" from all occurrences of = after consulting our mathematician advisor. - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] - - T: "lik" # (en: 'equals', MathPlayer: 'lik', google: 'lika') - - - ">": # 0x3e - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "større enn" # (en: 'greater than') - - "?": [T: "spørsmålstegn"] # 0x3f (en: 'question mark') - - "@": [T: "krøllalfa"] # 0x40 (en: 'at sign') - - "[": # 0x5b - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "start hakeparentes"] # (en: 'open bracket', google translation) - else: [T: "venstre hakeparentes"] # (en: 'left bracket') - - pause: short - - "\\": [T: "omvendt skråstrek"] # 0x5c (en: 'back slash') - - "]": # 0x5d - - pause: short - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "slutt hakeparentes"] # (en: 'close bracket', google translation) - else: [T: "høyre hakeparentes"] # (en: 'right bracket') - - "^": [T: "hatt"] # 0x5e (en: 'hat') # audit-ignore - - "_": [T: "understrek"] # 0x5f (en: 'under bar', MathPlayer: 'streck under', google: 'under bar') - - "`": [T: "grav aksent"] # 0x60 (en: 'grave') - - "{": # 0x7b - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "start krøllparentes"] # (en: 'open brace', google translation) - else: [T: "venstre krøllparentes"] # (en: 'left brace') - - pause: short - - "|": # 0x7c - # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' - - with: - variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) - replace: - - test: - - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [T: "vertikal strek"] - - else_if: "$SpeechStyle != 'ClearSpeak'" - then_test: - - if: "$DefaultToGiven" - then: [pause: short, T: "gitt"] - - else_if: "preceding-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))] and - following-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))]" - then: [T: "deler"] - else: [T: "vertikal strek"] - - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" - then: [T: "vertikal strek"] - - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" - then: [T: "slik at"] - - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" - then: [pause: short, T: "gitt"] - - else: [T: "deler"] - - - "}": # 0x7d - - pause: short - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: "slutt krøllparentes"] # (en: 'close brace', google translation) - else: [T: "høyre krøllparentes"] # (en: 'right brace') - - - "~": [T: "tilde"] # 0x7e - - " ": # 0xa0 - - test: - if: "@data-empty-in-2D and not(ancestor::*[self::m:piecewise or self::m:system-of-equations or self::m:lines])" #NORWEGIAN: Changed to English version. Now it doesn't speak "tom tom" for continued_row - then: [T: "tom"] # want to say something for fraction (etc) with empty child (en: 'empty', google translation) - else: [T: ""] - - - "¬": [T: "ikke"] # 0xac (en: 'not') - - "°": [T: "grader"] # 0xb0 (en: 'degrees') - - "±": [T: "pluss minus"] # 0xb1 (en: 'plus or minus') - - "´": [T: "akutt aksent"] # 0xb4 (en: 'acute') - - "·": # 0xB7 - - test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')] or not($SpeechStyle = 'ClearSpeak' and $ClearSpeak_MultSymbolDot = 'Auto')" - then: [T: "midtstilt prikk"] # (en: 'times', google translation) - else: [T: "ganger"] # (en: 'dot', MathPlayer: 'mellanpunkt', google: 'punkt') - - "×": # 0xd7 - - test: - if: "$SpeechStyle = 'ClearSpeak'" - then_test: - - if: "$ClearSpeak_MultSymbolX = 'Auto'" - then: [T: "ganger"] - - else_if: "$ClearSpeak_MultSymbolX = 'By'" - then: [T: "ganger"] - else: [T: "kryss"] - else_test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [T: "kryss"] - else: [T: "ganger"] - - "÷": [T: "delt på"] # 0xf7 (en: 'divided by') - - "̀": [T: "grav aksent"] # 0x300 (en: 'grave accent embellishment', google: 'allvarlig accentutsmyckning') - - "́": [T: "akutt aksent"] # 0x301 (en: 'acute accent embellishment', google: 'akut accentutsmyckning') - - "̂": [T: "cirkumfleks"] # 0x302 (en: 'circumflex accent embellishment', google: 'circumflex accent utsmyckning') - - "̃": [T: "tilde"] # 0x303 (google: 'tilde utsmyckning') - - "̄": [T: "makron"] # 0x304 (en: 'macron embellishment', google: 'macron -utsmyckning') - - "̅": [T: "strek"] # 0x305 (google: 'överbar utsmyckning') - - "̆": [T: "breve"] # 0x306 (en: 'breve', google: 'breve') - - "̇": [T: "prikk"] # 0x307 (google: 'prick ovanför utsmyckning') - - # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong - - "Α-Ω": - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [T: "stor"] # (en: 'cap', google translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [SPELL: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] - - - "α": [T: "alfa"] # 0x3b1 (en: 'alpha') - - "β": [T: "beta"] # 0x3b2 - - "γ": [T: "gamma"] # 0x3b3 - - "δ": [T: "delta"] # 0x3b4 - - "ε": [T: "epsilon"] # 0x3b5 - - "ζ": [T: "zeta"] # 0x3b6 - - "η": [T: "eta"] # 0x3b7 - - "θ": [T: "theta"] # 0x3b8 - - "ι": [T: "jota"] # 0x3b9 (en: 'iota', google: 'iota') - - "κ": [T: "kappa"] # 0x3ba - - "λ": [T: "lambda"] # 0x3bb (en: 'lambda', google: 'lambda') - - "μ": [T: "my"] # 0x3bc (en: 'mu', google: 'mu') - - "ν": [T: "ny"] # 0x3bd (en: 'nu', google: 'nu') - - "ξ": [T: "ksi"] # 0x3be (en: 'zai', google: 'zai') - - "ο": [T: "omikron"] # 0x3bf (en: 'omicron', google: 'omicron') - - "π": [T: "pi"] # 0x3c0 - - "ρ": [T: "rho"] # 0x3c1 - - "ς": [T: "sluttsigma"] # 0x3c2 (en: 'final sigma', google: 'slutlig sigma') - - "σ": [T: "sigma"] # 0x3c3 - - "τ": [T: "tau"] # 0x3c4 - - "υ": [T: "ypsilon"] # 0x3c5 (en: 'upsilon', google: 'upsilon') - - "φ": [T: "fi"] # 0x3c6 (en: 'phi', google: 'phi') - - "χ": [T: "khi"] # 0x3c7 - - "ψ": [T: "psi"] # 0x3c8 - - "ω": [T: "omega"] # 0x3c9 - - "ϕ": [T: "fi"] # 0x3d5 (en: 'phi', google: 'phi') - - "ϖ": [T: "pi"] # 0x3d6 (en: 'pi', google: 'pi') - - "ϵ": [T: "epsilon"] # 0x3f5 - - "϶": [T: "omvendt epsilon"] # 0x3f6 (en: 'reversed epsilon') - - - "⁡": # 0x2061 # audit-ignore - - test: - if: "preceding-sibling::*[1][.='log' or .='ln' or .='lg' or .='exp'] or - not( - ( $Verbosity='Terse' or ($SpeechStyle = 'ClearSpeak' and IsNode(following-sibling::*[1],'simple')) and - preceding-sibling::*[1][IfThenElse($SpeechStyle='ClearSpeak', - IsInDefinition(., 'Speech', 'ClearSpeakTrigFunctionNames'), - IsInDefinition(., 'Speech', 'TrigFunctionNames') )] - ) or - preceding-sibling::*[1][IsInDefinition(., 'Speech', 'GeometryShapes')] or - (@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) - )" - then: [T: "av"] # (en: 'of', google translation) - - - "⁢": [T: ""] # 0x2062 - - "⁣": [T: ""] # 0x2063 - - "⁤": [T: "og"] # 0x2064 (en: 'and', google: 'og') - - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" - - T: "dobbeltstreket" # (en: 'double-struck') - - SPELL: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" - - - "℃": [T: "grader celsius"] # 0x2103 (en: 'degrees celsius') - - "ℋℛℓ": # 0x210b - - T: "script font" # (en: 'script', google: 'manus') - - SPELL: "translate('.', 'ℋℛℓ', 'HRl')" - - "ℜ": # 0x211c - - T: "fraktur" # (en: 'fraktur', google: 'fraktur') - - SPELL: "'R'" - - - "ⅆⅇⅈⅉ": # 0x2146-9 - - T: "dobbeltstreket kursiv" # (en: 'double-struck italic') - - SPELL: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" - - - "∥": # 0x2225 - - test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [T: "dobbel vertikal linje"] - else: - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] - - T: "parallell med" - - "∦": # 0x2226 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "ikke parallell med" # (en: 'not parallel to') - - "≤": # 0x2264 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] - - T: "mindre enn eller lik" - - - "≥": # 0x2265 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] - - T: "større enn eller lik" - - - # --- restored complex short definitions (prefer over unicode-full) --- - - "…": # 0x2026 - test: - if: - - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" - # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' - # speak '…' as 'and so on...' unless expr starts with '…' - - "../*[1][.='…']" - then: [T: "prikk prikk prikk"] # (en: 'dot dot dot', google translation) - else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' - if: "count(following-sibling::*) = 0" - then: [T: "og så videre"] # (en: 'and so on', google translation) - else: [T: "og så videre opp til"] # (en: 'and so on up to') - - "→": # 0x2192 - - test: - if: "ancestor::*[2][self::m:limit]" - then: [T: "går mot"] # (en: 'approaches', google translation) - else: [T: "høyrepil"] # (en: 'right arrow') - - "∆": # 0x2206 - - test: - if: "following-sibling::*" - then: [T: "laplas av"] # (en: 'laplacian of') # Norwegian: "laplace" is not pronounced correctly - else: [T: "laplas"] - - "∈": # 0x2208 # audit-ignore - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: - - T: "i" #(en: "is an element of") - # NORWEGIAN: "i" sounds best in all cases for the non-ClearSpeak case - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - # SWEDISH/NORWEGIAN: The word "medlem" is not commonly used in set theory, so we removed that rule. If the parsing has set the parameter to "Member" it will fall under the "else" case. - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "i"] # (en: 'in', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "element i"] # (en: 'element of', google translation) - - else: [T: "tilhørende"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "i"] # NORWEGIAN: Set the "auto" case to be "i" - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "er et element i"] # (en: 'is in', google translation) - - else: [T: "tilhører"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') - - "∉": # 0x2209 # audit-ignore - # rule is identical to 0x2208 - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: - - test: - if: "not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" - then: [T: "er"] - - T: "ikke et element i" - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - # SWEDISH/NORWEGIAN: The word "medlem" is not commonly used in set theory, so we removed that rule. If the parsing has set the parameter to "Member" it will fall under the "else" case. - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "ikke i"] # (en: 'not in', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "ikke element i"] # (en: 'not element of', google translation) - - else: [T: "ikke tilhørende"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to') - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "er ikke et element i"] # (en: 'is not an element of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "er ikke i"] # (en: 'is not in', google translation) - - else: [T: "tilhører ikke"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to') - - "∊": # 0x220a # audit-ignore - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: - - T: "i" #(en: "is an element of") - # NORWEGIAN: "i" sounds best in all cases for the non-ClearSpeak case - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - # SWEDISH/NORWEGIAN: The word "medlem" is not commonly used in set theory, so we removed that rule. If the parsing has set the parameter to "Member" it will fall under the "else" case. - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "i"] # (en: 'in', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "element i"] # (en: 'element of', google translation) - - else: [T: "tilhørende"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [T: "i"] # (en: 'is an element of', google translation) #NORWEGIAN: Set the "auto" case to be "i" - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: "er et element i"] # (en: 'is in', google translation) - - else: [T: "tilhører"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') - - "∝": # 0x221d - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "proporsjonal med" # (en: 'proportional to') - - "∼": # 0x223c (en: 'varies with') # audit-ignore - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] - - T: "proporsjonal med" - - "≠": # 0x2260 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] - - T: "ikke lik" # (en: 'not equal to') - - "≡": # 0x2261 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] - - T: "identisk med" # (en: 'identical to') - - "≦": # 0x2266 (en: 'less than over equal to') # audit-ignore - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] - - T: "mindre enn eller lik" - - "≧": # 0x2267 (en: 'greater than over equal to') # audit-ignore - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] - - T: "større enn eller lik" - - "⊂": # 0x2282 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er en"] # (en: 'is a', google translation) - - T: "ekte delmengde av" - - "⊃": # 0x2283 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er en"] # (en: 'is a', google translation) - - T: "ekte overmengde av" - - "⊄": # 0x2284 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "ikke en ekte delmengde av" - - "⊅": # 0x2285 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er"] # (en: 'is', google translation) - - T: "ikke en ekte overmengde av" - - "⊆": # 0x2286 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er en"] # (en: 'is a', google translation) - - T: "delmengde av" - - "⊇": # 0x2287 - - test: - if: "$Verbosity!='Terse'" - then: [T: "er en"] # (en: 'is a', google translation) - - T: "overmengde av" - - # --- restored short definitions that differ from unicode-full --- - - "K": [T: "kelvin"] # 0x212a (en: 'kelvin') - - "∂": [T: "partiell derivert"] # 0x2202 # audit-ignore - # SWEDISH: This is only refered to as "del" in Swedish, but we write "dell" for correct pronounciation. - - "√": [T: "kvadratroten av"] # 0x221a (en: 'square root of') # audit-ignore +--- + - "a-z": + - test: + if: "$TTS='none'" + then: [T: "."] # (en: '.', google translation) + else: [SPELL: "'.'"] + + # Capital letters are a little tricky: users can pick their favorite word (something that was requested) and + # screen readers have options to use pitch changes or beeps instead of or in addition to say "cap" + # Also, if a user can see the screen, they probably don't need to hear "cap", but if they specified an override, they must want to hear the override. + + - "A-Z": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "stor"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [SPELL: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] + + - "0-9": [T: "."] # (en: '.', google: 'A') + + - " ": [T: " "] # 0x20 #NORWEGIAN: Added from English version. Not in Swedish version. + + - "!": # 0x21 + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" #NORWEGIAN: Changed from ":structure" to be equal to English translation + then_test: + if: "$Verbosity = 'Terse'" + then: [T: "utropstegn"] # 0x21 (en: 'bang', google translation) + else: [T: "utropstegn"] # 0x21 (en: 'exclamation point') + else: [T: "fakultet"] # 0x21 (en: 'factorial') + + - "\"": [T: "anførselstegn"] # 0x22 (en: 'quotation mark') + - "#": [T: "nummertegn"] # 0x23 (en: 'number', MathPlayer: 'numeriskt tecken', google: 'siffra') + - "$": [T: "dollar"] # 0x24 (en: 'dollars') + - "%": [T: "prosent"] # 0x25 (en: 'percent') + - "&": [T: "og-tegn"] # 0x26 (en: 'ampersand') + - "'": [T: "apostrof"] # 0x27 (en: 'apostrophe') + - "(": # 0x28 + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [pause: short, T: "startparentes"] # 0x28 (en: 'open', google translation) + else: [pause: short, T: "startparentes"] # 0x28 (en: 'open paren') + else: [T: "venstreparentes"] # 0x28 (en: 'left paren') + - pause: short + - ")": # 0x29 + - pause: short + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [T: "sluttparentes"] # 0x29 (en: 'close', google translation) + else: [T: "sluttparentes"] # 0x29 (en: 'close paren') + else: [T: "høyreparentes"] # 0x29 (en: 'right paren') + + - "*": # 0x2a + test: + if: "parent::*[name(.)='msup' or name(.)='msubsup' or name(.)='skip-super']" + then: [T: "stjerne"] # 0x2a (en: 'star', google translation) + else: [T: "ganger"] # 0x2a (en: 'times') + - "+": [T: "pluss"] # 0x2b + - ",": # 0x2c + # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent + # that this test is here and not with "…" is not ideal, but seems simplest + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak "comma" when not adjacent to '…' + - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " + # except if expression starts with '…' + - "../*[1][.='…'] " + then: + - T: "komma" # (en: 'comma', google translation) + - test: + if: "$Verbosity != Terse" + then: [pause: short] + # else silent + + - "-": [T: "minus"] # 0x2d + - ".": # 0x2e + - test: + if: "parent::*[1][self::m:mn]" + then: [T: "punktum"] # (en: 'point', google translation) + else: [T: "prikk"] # (en: 'dot') + - "/": # 0x2f (en: 'divided by') + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [T: "skråstrek"] # 0x2f + else: [T: "delt på"] # 0x2f + - ":": [T: "kolon"] # 0x3a (en: 'colon') + - ";": [T: "semikolon"] # 0x3b (en: 'semicolon') + - "<": # 0x3c + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "mindre enn" # (en: 'less than') + - "=": # 0x3d # audit-ignore + # SWEDISH: We remove "är" from all occurrences of = after consulting our mathematician advisor. + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "lik" # (en: 'equals', MathPlayer: 'lik', google: 'lika') + + - ">": # 0x3e + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "større enn" # (en: 'greater than') + - "?": [T: "spørsmålstegn"] # 0x3f (en: 'question mark') + - "@": [T: "krøllalfa"] # 0x40 (en: 'at sign') + - "[": # 0x5b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "start hakeparentes"] # (en: 'open bracket', google translation) + else: [T: "venstre hakeparentes"] # (en: 'left bracket') + - pause: short + - "\\": [T: "omvendt skråstrek"] # 0x5c (en: 'back slash') + - "]": # 0x5d + - pause: short + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "slutt hakeparentes"] # (en: 'close bracket', google translation) + else: [T: "høyre hakeparentes"] # (en: 'right bracket') + - "^": [T: "hatt"] # 0x5e (en: 'hat') # audit-ignore + - "_": [T: "understrek"] # 0x5f (en: 'under bar', MathPlayer: 'streck under', google: 'under bar') + - "`": [T: "grav aksent"] # 0x60 (en: 'grave') + - "{": # 0x7b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "start krøllparentes"] # (en: 'open brace', google translation) + else: [T: "venstre krøllparentes"] # (en: 'left brace') + - pause: short + - "|": # 0x7c + # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' + - with: + variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) + replace: + - test: + - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [T: "vertikal strek"] + - else_if: "$SpeechStyle != 'ClearSpeak'" + then_test: + - if: "$DefaultToGiven" + then: [pause: short, T: "gitt"] + - else_if: "preceding-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))] and + following-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))]" + then: [T: "deler"] + else: [T: "vertikal strek"] + - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" + then: [T: "vertikal strek"] + - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" + then: [T: "slik at"] + - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" + then: [pause: short, T: "gitt"] + - else: [T: "deler"] + + - "}": # 0x7d + - pause: short + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "slutt krøllparentes"] # (en: 'close brace', google translation) + else: [T: "høyre krøllparentes"] # (en: 'right brace') + + - "~": [T: "tilde"] # 0x7e + - " ": # 0xa0 + - test: + if: "@data-empty-in-2D and not(ancestor::*[self::m:piecewise or self::m:system-of-equations or self::m:lines])" #NORWEGIAN: Changed to English version. Now it doesn't speak "tom tom" for continued_row + then: [T: "tom"] # want to say something for fraction (etc) with empty child (en: 'empty', google translation) + else: [T: ""] + + - "¬": [T: "ikke"] # 0xac (en: 'not') + - "°": [T: "grader"] # 0xb0 (en: 'degrees') + - "±": [T: "pluss minus"] # 0xb1 (en: 'plus or minus') + - "´": [T: "akutt aksent"] # 0xb4 (en: 'acute') + - "·": # 0xB7 + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')] or not($SpeechStyle = 'ClearSpeak' and $ClearSpeak_MultSymbolDot = 'Auto')" + then: [T: "midtstilt prikk"] # (en: 'times', google translation) + else: [T: "ganger"] # (en: 'dot', MathPlayer: 'mellanpunkt', google: 'punkt') + - "×": # 0xd7 + - test: + if: "$SpeechStyle = 'ClearSpeak'" + then_test: + - if: "$ClearSpeak_MultSymbolX = 'Auto'" + then: [T: "ganger"] + - else_if: "$ClearSpeak_MultSymbolX = 'By'" + then: [T: "ganger"] + else: [T: "kryss"] + else_test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [T: "kryss"] + else: [T: "ganger"] + - "÷": [T: "delt på"] # 0xf7 (en: 'divided by') + - "̀": [T: "grav aksent"] # 0x300 (en: 'grave accent embellishment', google: 'allvarlig accentutsmyckning') + - "́": [T: "akutt aksent"] # 0x301 (en: 'acute accent embellishment', google: 'akut accentutsmyckning') + - "̂": [T: "cirkumfleks"] # 0x302 (en: 'circumflex accent embellishment', google: 'circumflex accent utsmyckning') + - "̃": [T: "tilde"] # 0x303 (google: 'tilde utsmyckning') + - "̄": [T: "makron"] # 0x304 (en: 'macron embellishment', google: 'macron -utsmyckning') + - "̅": [T: "strek"] # 0x305 (google: 'överbar utsmyckning') + - "̆": [T: "breve"] # 0x306 (en: 'breve', google: 'breve') + - "̇": [T: "prikk"] # 0x307 (google: 'prick ovanför utsmyckning') + + # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong + - "Α-Ω": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "stor"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [SPELL: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] + + - "α": [T: "alfa"] # 0x3b1 (en: 'alpha') + - "β": [T: "beta"] # 0x3b2 + - "γ": [T: "gamma"] # 0x3b3 + - "δ": [T: "delta"] # 0x3b4 + - "ε": [T: "epsilon"] # 0x3b5 + - "ζ": [T: "zeta"] # 0x3b6 + - "η": [T: "eta"] # 0x3b7 + - "θ": [T: "theta"] # 0x3b8 + - "ι": [T: "jota"] # 0x3b9 (en: 'iota', google: 'iota') + - "κ": [T: "kappa"] # 0x3ba + - "λ": [T: "lambda"] # 0x3bb (en: 'lambda', google: 'lambda') + - "μ": [T: "my"] # 0x3bc (en: 'mu', google: 'mu') + - "ν": [T: "ny"] # 0x3bd (en: 'nu', google: 'nu') + - "ξ": [T: "ksi"] # 0x3be (en: 'zai', google: 'zai') + - "ο": [T: "omikron"] # 0x3bf (en: 'omicron', google: 'omicron') + - "π": [T: "pi"] # 0x3c0 + - "ρ": [T: "rho"] # 0x3c1 + - "ς": [T: "sluttsigma"] # 0x3c2 (en: 'final sigma', google: 'slutlig sigma') + - "σ": [T: "sigma"] # 0x3c3 + - "τ": [T: "tau"] # 0x3c4 + - "υ": [T: "ypsilon"] # 0x3c5 (en: 'upsilon', google: 'upsilon') + - "φ": [T: "fi"] # 0x3c6 (en: 'phi', google: 'phi') + - "χ": [T: "khi"] # 0x3c7 + - "ψ": [T: "psi"] # 0x3c8 + - "ω": [T: "omega"] # 0x3c9 + - "ϕ": [T: "fi"] # 0x3d5 (en: 'phi', google: 'phi') + - "ϖ": [T: "pi"] # 0x3d6 (en: 'pi', google: 'pi') + - "ϵ": [T: "epsilon"] # 0x3f5 + - "϶": [T: "omvendt epsilon"] # 0x3f6 (en: 'reversed epsilon') + + - "⁡": # 0x2061 # audit-ignore + - test: + if: "preceding-sibling::*[1][.='log' or .='ln' or .='lg' or .='exp'] or + not( + ( $Verbosity='Terse' or ($SpeechStyle = 'ClearSpeak' and IsNode(following-sibling::*[1],'simple')) and + preceding-sibling::*[1][IfThenElse($SpeechStyle='ClearSpeak', + IsInDefinition(., 'Speech', 'ClearSpeakTrigFunctionNames'), + IsInDefinition(., 'Speech', 'TrigFunctionNames') )] + ) or + preceding-sibling::*[1][IsInDefinition(., 'Speech', 'GeometryShapes')] or + (@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) + )" + then: [T: "av"] # (en: 'of', google translation) + + - "⁢": [T: ""] # 0x2062 + - "⁣": [T: ""] # 0x2063 + - "⁤": [T: "og"] # 0x2064 (en: 'and', google: 'og') + - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" + - T: "dobbeltstreket" # (en: 'double-struck') + - SPELL: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" + + - "℃": [T: "grader celsius"] # 0x2103 (en: 'degrees celsius') + - "ℋℛℓ": # 0x210b + - T: "script font" # (en: 'script', google: 'manus') + - SPELL: "translate('.', 'ℋℛℓ', 'HRl')" + - "ℜ": # 0x211c + - T: "fraktur" # (en: 'fraktur', google: 'fraktur') + - SPELL: "'R'" + + - "ⅆⅇⅈⅉ": # 0x2146-9 + - T: "dobbeltstreket kursiv" # (en: 'double-struck italic') + - SPELL: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" + + - "∥": # 0x2225 + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [T: "dobbel vertikal linje"] + else: + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "parallell med" + - "∦": # 0x2226 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke parallell med" # (en: 'not parallel to') + - "≤": # 0x2264 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "mindre enn eller lik" + + - "≥": # 0x2265 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "større enn eller lik" + + + # --- restored complex short definitions (prefer over unicode-full) --- + - "…": # 0x2026 + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak '…' as 'and so on...' unless expr starts with '…' + - "../*[1][.='…']" + then: [T: "prikk prikk prikk"] # (en: 'dot dot dot', google translation) + else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' + if: "count(following-sibling::*) = 0" + then: [T: "og så videre"] # (en: 'and so on', google translation) + else: [T: "og så videre opp til"] # (en: 'and so on up to') + - "→": # 0x2192 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "går mot"] # (en: 'approaches', google translation) + else: [T: "høyrepil"] # (en: 'right arrow') + - "∆": # 0x2206 + - test: + if: "following-sibling::*" + then: [T: "laplas av"] # (en: 'laplacian of') # Norwegian: "laplace" is not pronounced correctly + else: [T: "laplas"] + - "∈": # 0x2208 # audit-ignore + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - T: "i" #(en: "is an element of") + # NORWEGIAN: "i" sounds best in all cases for the non-ClearSpeak case + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + # SWEDISH/NORWEGIAN: The word "medlem" is not commonly used in set theory, so we removed that rule. If the parsing has set the parameter to "Member" it will fall under the "else" case. + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "i"] # (en: 'in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "element i"] # (en: 'element of', google translation) + - else: [T: "tilhørende"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "i"] # NORWEGIAN: Set the "auto" case to be "i" + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "er et element i"] # (en: 'is in', google translation) + - else: [T: "tilhører"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - "∉": # 0x2209 # audit-ignore + # rule is identical to 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - test: + if: "not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" + then: [T: "er"] + - T: "ikke et element i" + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + # SWEDISH/NORWEGIAN: The word "medlem" is not commonly used in set theory, so we removed that rule. If the parsing has set the parameter to "Member" it will fall under the "else" case. + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "ikke i"] # (en: 'not in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "ikke element i"] # (en: 'not element of', google translation) + - else: [T: "ikke tilhørende"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "er ikke et element i"] # (en: 'is not an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "er ikke i"] # (en: 'is not in', google translation) + - else: [T: "tilhører ikke"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to') + - "∊": # 0x220a # audit-ignore + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - T: "i" #(en: "is an element of") + # NORWEGIAN: "i" sounds best in all cases for the non-ClearSpeak case + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + # SWEDISH/NORWEGIAN: The word "medlem" is not commonly used in set theory, so we removed that rule. If the parsing has set the parameter to "Member" it will fall under the "else" case. + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "i"] # (en: 'in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "element i"] # (en: 'element of', google translation) + - else: [T: "tilhørende"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "i"] # (en: 'is an element of', google translation) #NORWEGIAN: Set the "auto" case to be "i" + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "er et element i"] # (en: 'is in', google translation) + - else: [T: "tilhører"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - "∝": # 0x221d + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "proporsjonal med" # (en: 'proportional to') + - "∼": # 0x223c (en: 'varies with') # audit-ignore + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "proporsjonal med" + - "≠": # 0x2260 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "ikke lik" # (en: 'not equal to') + - "≡": # 0x2261 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "identisk med" # (en: 'identical to') + - "≦": # 0x2266 (en: 'less than over equal to') # audit-ignore + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "mindre enn eller lik" + - "≧": # 0x2267 (en: 'greater than over equal to') # audit-ignore + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "større enn eller lik" + - "⊂": # 0x2282 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is a', google translation) + - T: "ekte delmengde av" + - "⊃": # 0x2283 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is a', google translation) + - T: "ekte overmengde av" + - "⊄": # 0x2284 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke en ekte delmengde av" + - "⊅": # 0x2285 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke en ekte overmengde av" + - "⊆": # 0x2286 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is a', google translation) + - T: "delmengde av" + - "⊇": # 0x2287 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is a', google translation) + - T: "overmengde av" + + # --- restored short definitions that differ from unicode-full --- + - "K": [T: "kelvin"] # 0x212a (en: 'kelvin') + - "∂": [T: "partiell derivert"] # 0x2202 # audit-ignore + # SWEDISH: This is only refered to as "del" in Swedish, but we write "dell" for correct pronounciation. + - "√": [T: "kvadratroten av"] # 0x221a (en: 'square root of') # audit-ignore diff --git a/Rules/Languages/ru/unicode.yaml b/Rules/Languages/ru/unicode.yaml index 66401b086..a1a38bcce 100644 --- a/Rules/Languages/ru/unicode.yaml +++ b/Rules/Languages/ru/unicode.yaml @@ -1,548 +1,548 @@ ---- - # Note to translators: - # most languages don't have two ways to pronounce 'a' -- if not need, remove the rules and change "B-Z" to "A-Z" - # some languages say the word for "uppercase" after the letter. Make sure to change that where appropriate by moving some code around - - "a": [t: "а"] - - "b": [t: "бэ"] - - "c": [t: "цэ"] - - "d": [t: "дэ"] - - "e": [t: "е"] - - "f": [t: "эф"] - - "g": [t: "джи"] - - "h": [t: "аш"] - - "i": [t: "и"] - - "j": [t: "джей"] - - "k": [t: "ка"] - - "l": [t: "эль"] - - "m": [t: "эм"] - - "n": [t: "эн"] - - "o": [t: "о"] - - "p": [t: "пэ"] - - "q": [t: "ку"] - - "r": [t: "эр"] - - "s": [t: "эс"] - - "t": [t: "тэ"] - - "u": [t: "у"] - - "v": [t: "вэ"] - - "w": [t: "дабл-ю"] - - "x": [t: "икс"] - - "y": [t: "игрек"] - - "z": [t: "зэт"] - - # Capital letters are a little tricky: users can pick their favorite word (something that was requested) and - # screen readers have options to use pitch changes or beeps instead of or in addition to say "cap" - # Also, if a user can see the screen, they probably don't need to hear "cap", but if they specified an override, they must want to hear the override. - - - - "A-Z": - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [t: "заглавная"] # (en: 'cap') - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [x: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] - - - "0-9": [t: "."] # (en: '.', google translation) - - - " ": [t: " "] # 0x20 (google translation) - - - "!": # 0x21 - - test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then_test: - if: "$Verbosity = 'Terse'" - then: [t: "восклицательный знак"] # 0x21 (en: 'bang', google translation) - else: [t: "восклицательный знак"] # 0x21 (en: 'exclamation point', google translation) - else: [t: "факториал"] # 0x21 (en: 'factorial', google translation) - - - "\"": [t: "кавычка"] # 0x22 (en: 'quotation mark', google translation) - - "#": [t: "номер"] # 0x23 (en: 'number', google translation) - - "$": [t: "доллар"] # 0x24 (en: 'dollars', google translation) - - "%": [t: "процент"] # 0x25 (en: 'percent') - - "&": [t: "амперсанд"] # 0x26 (google translation) - - "'": [t: "штрих"] # 0x27 (en: 'apostrophe') - - "(": # 0x28 - - test: - - if: "$SpeechStyle='LiteralSpeak' or ancestor-or-self::*[contains(@data-intent-property, ':literal:')] or @data-changed='added' or ancestor::*[@data-changed='added'] or preceding-sibling::*[1][.='P'] or following-sibling::*[.='|' or .='∩' or contains(., 'and')]" - then: [t: "открывающая круглая скобка"] - else_test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then_test: - if: "$Verbosity='Terse'" - then: [t: "скобка открывается"] # 0x28 (en: 'open', google translation) - else: [t: "открывающая круглая скобка"] # 0x28 (en: 'open paren', google translation) - else: [t: "левая круглая скобка"] # 0x28 (en: 'left paren', google translation) - - ")": # 0x29 - - test: - - if: "$SpeechStyle='LiteralSpeak' or ancestor-or-self::*[contains(@data-intent-property, ':literal:')] or @data-changed='added' or ancestor::*[@data-changed='added'] or preceding-sibling::*[.='P' or .='|' or .='∩' or contains(., 'and')]" - then: [t: "закрывающая круглая скобка"] - else_test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then_test: - if: "$Verbosity='Terse'" - then: [t: "скобка закрывается"] # 0x29 (en: 'close', google translation) - else: [t: "закрывающая круглая скобка"] # 0x29 (en: 'close paren', google translation) - else: [t: "правая круглая скобка"] # 0x29 (en: 'right paren', google translation) - - - "*": # 0x2a - test: - if: "parent::*[name(.)='msup' or name(.)='msubsup' or name(.)='skip-super']" - then: [t: "звёздочка"] # 0x2a (en: 'star', google translation) - else: [t: "умножить"] # 0x2a (en: 'times', google translation) - - "+": # 0x2b - - test: - if: "preceding-sibling::*[1][name(.)='mover' or name(.)='modified-variable'] and - following-sibling::*[1][name(.)='mover' or name(.)='modified-variable'] and - not(following-sibling::*[1][name(.)='mover' and *[2][.='→']])" - then: [pause: medium] - - t: "плюс" # (en: 'plus') - - test: - if: "$ClearSpeak_Functions='None' and following-sibling::*[1][self::m:mi] and not(ancestor::*[IsBracketed(., '(', ')')])" - then: [pause: short] - - ",": # 0x2c - # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent - # that this test is here and not with "…" is not ideal, but seems simplest - test: - if: - - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " - # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' - # speak "comma" when not adjacent to '…' - - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " - # except if expression starts with '…' - - "../*[1][.='…'] " - then: - - test: - - if: "preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]" - then: [pause: short] - else: - - T: "запятая" # (en: 'comma', google translation) - - test: - if: "$Verbosity != Terse" - then: [pause: short] - # else silent - - - "-": [t: "минус"] # 0x2d (en: 'minus') - - ".": # 0x2e - - test: - if: "parent::*[1][self::m:mn]" - then: [t: "точка"] # (en: 'point', google translation) - else: [t: "точка"] # (en: 'dot', google translation) - - "/": [t: "разделить на"] # 0x2f (en: 'divided by') - - ":": [t: "двоеточие"] # 0x3a (en: 'colon') - - ";": [t: "точка с запятой"] # 0x3b (en: 'semicolon', google translation) - - "<": # 0x3c - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'is', google translation) - - t: "меньше" # (en: 'less than') - - "=": # 0x3d - - test: - if: "$Verbosity!='Terse'" - then: [t: "равно"] # (en: 'is equal to', google translation) - else: [t: "равно"] # (en: 'equals') - - test: - - if: "(following-sibling::*[1][.='c'] and following-sibling::*[2][.='\u2062']) or - (following-sibling::*[1][.='P'] and following-sibling::*[2][IsBracketed(., '(', ')')] and following-sibling::*[3][.='='])" - then: [pause: medium] - - else_if: "following-sibling::*[1][.='P'] and following-sibling::*[2][IsBracketed(., '(', ')')]" - then: [pause: short] - - - ">": # 0x3e - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'is', google translation) - - t: "больше" # (en: 'greater than') - - "?": [t: "вопросительный знак"] # 0x3f (en: 'question mark', google translation) - - "@": [t: "собака"] # 0x40 (en: 'at sign', google translation) - - "[": # 0x5b - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [t: "открывающая квадратная скобка"] # (en: 'open bracket', google translation) - else: [t: "левая квадратная скобка"] # (en: 'left bracket', google translation) - - "\\": [t: "обратная косая черта"] # 0x5c (en: 'back slash', google translation) - - "]": # 0x5d - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [t: "закрывающая квадратная скобка"] # (en: 'close bracket', google translation) - else: [t: "правая квадратная скобка"] # (en: 'right bracket', google translation) - - "^": # 0x5e - - test: - if: "parent::m:modified-variable or parent::m:mover" - then: [t: "циркумфлекс"] # (en: 'hat', google translation) - else: [t: "крышка"] # (en: 'caret', google translation) - - "_": [t: "подчёркивание"] # 0x5f (en: 'under bar', google translation) - - "`": [t: "гравис"] # 0x60 (en: 'grave', google translation) - - "{": # 0x7b - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [t: "открывающая фигурная скобка"] # (en: 'open brace', google translation) - else: [t: "левая фигурная скобка"] # (en: 'left brace', google translation) - - "|": # 0x7c - # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' - - with: - variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) - replace: - - test: - - if: "$SpeechStyle != 'ClearSpeak'" - then_test: - if: "$DefaultToGiven" - then: [t: "при условии"] # (en: 'given', google translation) - else: [t: "вертикальная черта"] # (en: 'vertical line') - - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" - then: [t: "вертикальная черта"] # (en: 'vertical line', google translation) - - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" - then: [t: "такой, что"] # (en: 'such that', google translation) - - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" - then: [t: "при условии"] # (en: 'given', google translation) - - else: [t: "делит"] # (en: 'divides') - - - "}": # 0x7d - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [t: "закрывающая фигурная скобка"] # (en: 'close brace', google translation) - else: [t: "правая фигурная скобка"] # (en: 'right brace', google translation) - - - "~": [t: "тильда"] # 0x7e (en: 'tilde', google translation) - - " ": # 0xa0 - - test: - # could be mtext in mtd or mtext in an mrow that is a concatenation of mtd's. Is there a better solution? - if: "@data-empty-in-2D and not(ancestor::*[self::m:piecewise or self::m:system-of-equations or self::m:lines])" - then: [t: "пустой"] # want to say something for fraction (etc) with empty child (en: 'empty', google translation) - else: [t: ""] - - - "¬": [t: "не"] # 0xac (en: 'not', google translation) - - "°": [t: "градусы"] # 0xb0 (en: 'degrees', google translation) - - "±": [t: "плюс минус"] # 0xb1 (en: 'plus or minus') - - "´": [t: "акут"] # 0xb4 (en: 'acute', google translation) - - "·": # 0xB7 - - test: - if: "$SpeechStyle = 'LiteralSpeak' or not($SpeechStyle = 'ClearSpeak' and $ClearSpeak_MultSymbolDot = 'Auto')" - then: [t: "точка"] # (en: 'dot', google translation) - else: [t: "умножить"] # (en: 'times') - - "×": # 0xd7 - - test: - if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolX = 'Auto'" - then: [t: "умножить на"] # (en: 'times', google translation) - else_test: - if: $ClearSpeak_MultSymbolX = 'By' - then: [t: "умножить на"] # (en: 'by') - else: [t: "векторное произведение"] # (en: 'cross') - - "÷": [t: "разделить на"] # 0xf7 (en: 'divided by') - - "̀": [t: "знак грависа"] # 0x300 (en: 'grave accent embellishment', google translation) - - "́": [t: "акут"] # 0x301 (en: 'acute accent embellishment', google translation) - - "̂": [t: "циркумфлекс"] # 0x302 (en: 'circumflex accent embellishment', google translation) - - "̃": [t: "тильда"] # 0x303 (en: 'tilde embellishment', google translation) - - "̄": [t: "макрон"] # 0x304 (en: 'macron embellishment', google translation) - - "̅": [t: "надчёркивание"] # 0x305 (en: 'overbar embellishment', google translation) - - "̆": [t: "брэвэ"] # 0x306 (en: 'breve', google translation) - - "̇": [t: "точка сверху"] # 0x307 (en: 'dot above embellishment', google translation) - - # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong - - "Α-Ω": - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [t: "заглавная"] # (en: 'cap') - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [x: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] - - - "α": [t: "альфа"] # 0x3b1 (en: 'alpha') - - "β": [t: "бета"] # 0x3b2 (en: 'beta') - - "γ": [t: "гамма"] # 0x3b3 (en: 'gamma') - - "δ": [t: "дельта"] # 0x3b4 (en: 'delta') - - "ε": [t: "эпсилон"] # 0x3b5 (en: 'epsilon') - - "ζ": [t: "дзета"] # 0x3b6 (en: 'zeta') - - "η": [t: "эта"] # 0x3b7 (en: 'eta') - - "θ": [t: "тета"] # 0x3b8 (en: 'theta') - - "ι": [t: "йота"] # 0x3b9 (en: 'iota') - - "κ": [t: "каппа"] # 0x3ba (en: 'kappa') - - "λ": [t: "лямбда"] # 0x3bb (en: 'lambda') - - "μ": [t: "мю"] # 0x3bc (en: 'mu') - - "ν": [t: "ню"] # 0x3bd (en: 'nu') - - "ξ": [t: "кси"] # 0x3be (en: 'zai') - - "ο": [t: "омикрон"] # 0x3bf (en: 'omicron') - - "π": [t: "пи"] # 0x3c0 (en: 'pi') - - "ρ": [t: "ро"] # 0x3c1 (en: 'rho') - - "ς": [t: "финальная сигма"] # 0x3c2 (en: 'final sigma') - - "σ": [t: "сигма"] # 0x3c3 (en: 'sigma') - - "τ": [t: "тау"] # 0x3c4 (en: 'tau') - - "υ": [t: "ипсилон"] # 0x3c5 (en: 'upsilon') - - "φ": [t: "фи"] # 0x3c6 (en: 'phi') - - "χ": [t: "хи"] # 0x3c7 (en: 'chi') - - "ψ": [t: "пси"] # 0x3c8 (en: 'psi') - - "ω": [t: "омега"] # 0x3c9 (en: 'omega') - - "ϕ": [t: "фи"] # 0x3d5 (en: 'phi') - - "ϖ": [t: "пи"] # 0x3d6 (en: 'pi') - - "ϵ": [t: "эпсилон"] # 0x3f5 (en: 'epsilon') - - "϶": [t: "обратный эпсилон"] # 0x3f6 (en: 'reversed epsilon') - - - "⁡": # 0x2061 - - test: - # skip saying "of" after trig functions, geometry shapes, or in :literal mode - if: "not(preceding-sibling::*[1][IsInDefinition(., 'TrigFunctionNames') or self::m:inverse-function or (self::m:power and IsInDefinition(*[1], 'TrigFunctionNames'))]) and not(preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')]) and - not(@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')])" - then: [t: "от"] # (en: 'of', google translation) - - "⁢": # 0x2062 - - test: - if: "@data-function-guess and following-sibling::*[1][self::m:mrow and IsBracketed(., '(', ')')] and $ClearSpeak_Functions!='None'" - then: [pause: short] - - "⁣": [t: ""] # 0x2063 - - "⁤": [t: "и"] # 0x2064 (en: 'and', google translation) - - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" - - t: "двойное" # (en: 'double-struck') - - spell: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" - - - "℃": [t: "градусы цельсия"] # 0x2103 (en: 'degrees celsius', google translation) - - "ℋℛℓ": # 0x210b - - t: "рукописное" # (en: 'script', google translation) - - spell: "translate('.', 'ℋℛℓ', 'HRl')" - - "ℜ": # 0x211c - - t: "готическая" # (en: 'fraktur', google translation) - - spell: "'R'" - - - "ⅆⅇⅈⅉ": # 0x2146-9 - - t: "двойной курсив" # (en: 'double-struck italic', google translation) - - spell: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" - - - "←": [t: "стрелка влево"] # 0x2190 (en: 'leftwards arrow', google translation) - - "↑": [t: "стрелка вверх"] # 0x2191 (en: 'upwards arrow', google translation) - - "→": # 0x2192 - - test: - if: "(parent::m:mover or parent::m:modified-variable) and ($SpeechStyle='LiteralSpeak' or ancestor-or-self::*[contains(@data-intent-property, ':literal:')])" - then: [t: "со стрелкой"] - else_test: - if: "ancestor::*[2][self::m:limit]" - then: [t: "стремящемся к"] # (en: 'approaches', google translation) - else: [t: "стрелка вправо"] # (en: 'right arrow', google translation) - - - "↓": [t: "стрелка вниз"] # 0x2193 (en: 'downwards arrow', google translation) - - "∈": # 0x2208 - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: - - test: - if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" - then: [t: ""] # (en: 'is', google translation) - - t: "принадлежит" # (en: 'an element of') - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "в"] # (en: 'in', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "член"] # (en: 'member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "элемент"] # (en: 'element of', google translation) - - else: [t: "принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "член"] # (en: 'is a member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "элемент"] # (en: 'is an element of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "находится в"] # (en: 'is in', google translation) - - else: [t: "принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') - - "∥": # 0x2225 - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'is', google translation) - - t: "параллельно" # (en: 'parallel to') - - "∦": # 0x2226 - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'is', google translation) - - t: "не параллельно" # (en: 'not parallel to') - - "≤": # 0x2264 - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'is', google translation) - - t: "меньше или равно" - - "≥": # 0x2265 - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'is', google translation) - - t: "больше или равно" # (en: 'greater than or equal to') - - # --- restored complex short definitions (prefer over unicode-full) --- - - "…": # 0x2026 - test: - if: - - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" - # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' - # speak '…' as 'and so on...' unless expr starts with '…' - - "../*[1][.='…']" - then: [t: "многоточие"] # (en: 'dot dot dot') - else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' - if: "count(following-sibling::*) = 0" - then: [t: "и так далее"] # (en: 'and so on', google translation) - else: [t: "и так далее до"] # (en: 'and so on up to', google translation) - - "∂": # 0x2202 - - test: - if: "$Verbosity='Terse'" - then: [t: "частная производная"] # (en: 'partial', google translation) - else: [t: "частная производная"] # (en: 'partial derivative') - - "∆": # 0x2206 - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'the', google translation) - - t: "инкремент" # (en: 'laplacian of') - - "∉": # 0x2209 - # rule is identical to 0x2208 - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'is', google translation) - - t: "не принадлежит" # (en: 'not an element of') - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "не в"] # (en: 'not in', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "не член"] # (en: 'not member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "не элемент"] # (en: 'not element of', google translation) - - else: [t: "не принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to') - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "не член"] # (en: 'is not a member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "не элемент"] # (en: 'is not an element of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "не в"] # (en: 'is not in', google translation) - - else: [t: "не принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to') - - "∊": # 0x220a - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: - - test: - if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" - then: [t: ""] # (en: 'is', google translation) - - t: "малое принадлежит" # (en: 'an element of') - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "в"] # (en: 'in', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "член"] # (en: 'member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "элемент"] # (en: 'element of', google translation) - - else: [t: "малое принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "член"] # (en: 'is a member of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "элемент"] # (en: 'is an element of', google translation) - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "находится в"] # (en: 'is in', google translation) - - else: [t: "малое принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') - - "√": # 0x221a - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'the', google translation) - - t: "квадратный корень" # (en: 'square root of') - - "∝": # 0x221d - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'is', google translation) - - t: "пропорционально" # (en: 'proportional to') - - "∶": # 0x2236 - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'is', google translation) - - t: "отношение" # (en: 'to') - - "∾": # 0x223e - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'is', google translation) - - t: "изогнутая эс" # (en: 'most positive') - - "≠": # 0x2260 - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'is', google translation) - - t: "не равно" # (en: 'not equal to') - - "≡": # 0x2261 - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'is', google translation) - - t: "тождественно равно" # (en: 'identical to') - - "⊂": # 0x2282 - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'is a', google translation) - - t: "подмножество" # (en: 'subset of') - - "⊃": # 0x2283 - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'is a', google translation) - - t: "надмножество" # (en: 'superset of') - - "⊄": # 0x2284 - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'is', google translation) - - t: "не подмножество" # (en: 'not a subset of') - - "⊅": # 0x2285 - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'is', google translation) - - t: "не надмножество" # (en: 'not a superset of') - - "⊆": # 0x2286 - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'is a', google translation) - - t: "подмножество или равно" # (en: 'subset of or equal to') - - "⊇": # 0x2287 - - test: - if: "$Verbosity!='Terse'" - then: [t: ""] # (en: 'is a', google translation) - - t: "надмножество или равно" # (en: 'superset of or equal to') - - # --- restored short definitions that differ from unicode-full --- - - "‖": [t: "двойная вертикальная черта"] # 0x2016 (en: 'double vertical line', google translation) - - "℉": [t: "градусы фаренгейта"] # 0x2109 (en: 'degrees fahrenheit', google translation) - - "Ω": [t: "ом"] # 0x2126 (en: 'ohms', google translation) - - "Å": [t: "ангстрем"] # 0x212b (en: 'angstroms', google translation) - - "⇒": [t: "двойная стрелка вправо"] # 0x21d2 (en: 'rightwards double arrow', google translation) - - "∐": [t: "эн-арный сомножитель"] # 0x2210 (en: 'co-product') - - "∓": [t: "минус плюс"] # 0x2213 (en: 'minus or plus') - - "∗": [t: "звёздочка"] # 0x2217 (en: 'times') - - "∘": [t: "композиция"] # 0x2218 (en: 'composed with') - - "∧": [t: "логическое и"] # 0x2227 (en: 'and') - - "∨": [t: "логическое или"] # 0x2228 (en: 'or') - - "∮": [t: "интеграл по контуру"] # 0x222e (en: 'contour integral') - - "∷": [t: "пропорция"] # 0x2237 (en: 'as') - - "∼": [t: "тильда"] # 0x223c (en: 'varies with') - - "∿": [t: "синусоидальная волна"] # 0x223f (en: 'sine wave') - - "≦": [t: "меньше над равно"] # 0x2266 (en: 'less than over equal to') - - "≧": [t: "больше над равно"] # 0x2267 (en: 'greater than over equal to') - - "≻": [t: "следует за"] # 0x227b (en: 'succeeds') +--- + # Note to translators: + # most languages don't have two ways to pronounce 'a' -- if not need, remove the rules and change "B-Z" to "A-Z" + # some languages say the word for "uppercase" after the letter. Make sure to change that where appropriate by moving some code around + - "a": [t: "а"] + - "b": [t: "бэ"] + - "c": [t: "цэ"] + - "d": [t: "дэ"] + - "e": [t: "е"] + - "f": [t: "эф"] + - "g": [t: "джи"] + - "h": [t: "аш"] + - "i": [t: "и"] + - "j": [t: "джей"] + - "k": [t: "ка"] + - "l": [t: "эль"] + - "m": [t: "эм"] + - "n": [t: "эн"] + - "o": [t: "о"] + - "p": [t: "пэ"] + - "q": [t: "ку"] + - "r": [t: "эр"] + - "s": [t: "эс"] + - "t": [t: "тэ"] + - "u": [t: "у"] + - "v": [t: "вэ"] + - "w": [t: "дабл-ю"] + - "x": [t: "икс"] + - "y": [t: "игрек"] + - "z": [t: "зэт"] + + # Capital letters are a little tricky: users can pick their favorite word (something that was requested) and + # screen readers have options to use pitch changes or beeps instead of or in addition to say "cap" + # Also, if a user can see the screen, they probably don't need to hear "cap", but if they specified an override, they must want to hear the override. + + + - "A-Z": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [t: "заглавная"] # (en: 'cap') + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [x: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] + + - "0-9": [t: "."] # (en: '.', google translation) + + - " ": [t: " "] # 0x20 (google translation) + + - "!": # 0x21 + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then_test: + if: "$Verbosity = 'Terse'" + then: [t: "восклицательный знак"] # 0x21 (en: 'bang', google translation) + else: [t: "восклицательный знак"] # 0x21 (en: 'exclamation point', google translation) + else: [t: "факториал"] # 0x21 (en: 'factorial', google translation) + + - "\"": [t: "кавычка"] # 0x22 (en: 'quotation mark', google translation) + - "#": [t: "номер"] # 0x23 (en: 'number', google translation) + - "$": [t: "доллар"] # 0x24 (en: 'dollars', google translation) + - "%": [t: "процент"] # 0x25 (en: 'percent') + - "&": [t: "амперсанд"] # 0x26 (google translation) + - "'": [t: "штрих"] # 0x27 (en: 'apostrophe') + - "(": # 0x28 + - test: + - if: "$SpeechStyle='LiteralSpeak' or ancestor-or-self::*[contains(@data-intent-property, ':literal:')] or @data-changed='added' or ancestor::*[@data-changed='added'] or preceding-sibling::*[1][.='P'] or following-sibling::*[.='|' or .='∩' or contains(., 'and')]" + then: [t: "открывающая круглая скобка"] + else_test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [t: "скобка открывается"] # 0x28 (en: 'open', google translation) + else: [t: "открывающая круглая скобка"] # 0x28 (en: 'open paren', google translation) + else: [t: "левая круглая скобка"] # 0x28 (en: 'left paren', google translation) + - ")": # 0x29 + - test: + - if: "$SpeechStyle='LiteralSpeak' or ancestor-or-self::*[contains(@data-intent-property, ':literal:')] or @data-changed='added' or ancestor::*[@data-changed='added'] or preceding-sibling::*[.='P' or .='|' or .='∩' or contains(., 'and')]" + then: [t: "закрывающая круглая скобка"] + else_test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [t: "скобка закрывается"] # 0x29 (en: 'close', google translation) + else: [t: "закрывающая круглая скобка"] # 0x29 (en: 'close paren', google translation) + else: [t: "правая круглая скобка"] # 0x29 (en: 'right paren', google translation) + + - "*": # 0x2a + test: + if: "parent::*[name(.)='msup' or name(.)='msubsup' or name(.)='skip-super']" + then: [t: "звёздочка"] # 0x2a (en: 'star', google translation) + else: [t: "умножить"] # 0x2a (en: 'times', google translation) + - "+": # 0x2b + - test: + if: "preceding-sibling::*[1][name(.)='mover' or name(.)='modified-variable'] and + following-sibling::*[1][name(.)='mover' or name(.)='modified-variable'] and + not(following-sibling::*[1][name(.)='mover' and *[2][.='→']])" + then: [pause: medium] + - t: "плюс" # (en: 'plus') + - test: + if: "$ClearSpeak_Functions='None' and following-sibling::*[1][self::m:mi] and not(ancestor::*[IsBracketed(., '(', ')')])" + then: [pause: short] + - ",": # 0x2c + # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent + # that this test is here and not with "…" is not ideal, but seems simplest + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak "comma" when not adjacent to '…' + - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " + # except if expression starts with '…' + - "../*[1][.='…'] " + then: + - test: + - if: "preceding-sibling::*[1][self::m:mi] and following-sibling::*[1][self::m:mi]" + then: [pause: short] + else: + - T: "запятая" # (en: 'comma', google translation) + - test: + if: "$Verbosity != Terse" + then: [pause: short] + # else silent + + - "-": [t: "минус"] # 0x2d (en: 'minus') + - ".": # 0x2e + - test: + if: "parent::*[1][self::m:mn]" + then: [t: "точка"] # (en: 'point', google translation) + else: [t: "точка"] # (en: 'dot', google translation) + - "/": [t: "разделить на"] # 0x2f (en: 'divided by') + - ":": [t: "двоеточие"] # 0x3a (en: 'colon') + - ";": [t: "точка с запятой"] # 0x3b (en: 'semicolon', google translation) + - "<": # 0x3c + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'is', google translation) + - t: "меньше" # (en: 'less than') + - "=": # 0x3d + - test: + if: "$Verbosity!='Terse'" + then: [t: "равно"] # (en: 'is equal to', google translation) + else: [t: "равно"] # (en: 'equals') + - test: + - if: "(following-sibling::*[1][.='c'] and following-sibling::*[2][.='\u2062']) or + (following-sibling::*[1][.='P'] and following-sibling::*[2][IsBracketed(., '(', ')')] and following-sibling::*[3][.='='])" + then: [pause: medium] + - else_if: "following-sibling::*[1][.='P'] and following-sibling::*[2][IsBracketed(., '(', ')')]" + then: [pause: short] + + - ">": # 0x3e + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'is', google translation) + - t: "больше" # (en: 'greater than') + - "?": [t: "вопросительный знак"] # 0x3f (en: 'question mark', google translation) + - "@": [t: "собака"] # 0x40 (en: 'at sign', google translation) + - "[": # 0x5b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [t: "открывающая квадратная скобка"] # (en: 'open bracket', google translation) + else: [t: "левая квадратная скобка"] # (en: 'left bracket', google translation) + - "\\": [t: "обратная косая черта"] # 0x5c (en: 'back slash', google translation) + - "]": # 0x5d + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [t: "закрывающая квадратная скобка"] # (en: 'close bracket', google translation) + else: [t: "правая квадратная скобка"] # (en: 'right bracket', google translation) + - "^": # 0x5e + - test: + if: "parent::m:modified-variable or parent::m:mover" + then: [t: "циркумфлекс"] # (en: 'hat', google translation) + else: [t: "крышка"] # (en: 'caret', google translation) + - "_": [t: "подчёркивание"] # 0x5f (en: 'under bar', google translation) + - "`": [t: "гравис"] # 0x60 (en: 'grave', google translation) + - "{": # 0x7b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [t: "открывающая фигурная скобка"] # (en: 'open brace', google translation) + else: [t: "левая фигурная скобка"] # (en: 'left brace', google translation) + - "|": # 0x7c + # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' + - with: + variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) + replace: + - test: + - if: "$SpeechStyle != 'ClearSpeak'" + then_test: + if: "$DefaultToGiven" + then: [t: "при условии"] # (en: 'given', google translation) + else: [t: "вертикальная черта"] # (en: 'vertical line') + - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" + then: [t: "вертикальная черта"] # (en: 'vertical line', google translation) + - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" + then: [t: "такой, что"] # (en: 'such that', google translation) + - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" + then: [t: "при условии"] # (en: 'given', google translation) + - else: [t: "делит"] # (en: 'divides') + + - "}": # 0x7d + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [t: "закрывающая фигурная скобка"] # (en: 'close brace', google translation) + else: [t: "правая фигурная скобка"] # (en: 'right brace', google translation) + + - "~": [t: "тильда"] # 0x7e (en: 'tilde', google translation) + - " ": # 0xa0 + - test: + # could be mtext in mtd or mtext in an mrow that is a concatenation of mtd's. Is there a better solution? + if: "@data-empty-in-2D and not(ancestor::*[self::m:piecewise or self::m:system-of-equations or self::m:lines])" + then: [t: "пустой"] # want to say something for fraction (etc) with empty child (en: 'empty', google translation) + else: [t: ""] + + - "¬": [t: "не"] # 0xac (en: 'not', google translation) + - "°": [t: "градусы"] # 0xb0 (en: 'degrees', google translation) + - "±": [t: "плюс минус"] # 0xb1 (en: 'plus or minus') + - "´": [t: "акут"] # 0xb4 (en: 'acute', google translation) + - "·": # 0xB7 + - test: + if: "$SpeechStyle = 'LiteralSpeak' or not($SpeechStyle = 'ClearSpeak' and $ClearSpeak_MultSymbolDot = 'Auto')" + then: [t: "точка"] # (en: 'dot', google translation) + else: [t: "умножить"] # (en: 'times') + - "×": # 0xd7 + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolX = 'Auto'" + then: [t: "умножить на"] # (en: 'times', google translation) + else_test: + if: $ClearSpeak_MultSymbolX = 'By' + then: [t: "умножить на"] # (en: 'by') + else: [t: "векторное произведение"] # (en: 'cross') + - "÷": [t: "разделить на"] # 0xf7 (en: 'divided by') + - "̀": [t: "знак грависа"] # 0x300 (en: 'grave accent embellishment', google translation) + - "́": [t: "акут"] # 0x301 (en: 'acute accent embellishment', google translation) + - "̂": [t: "циркумфлекс"] # 0x302 (en: 'circumflex accent embellishment', google translation) + - "̃": [t: "тильда"] # 0x303 (en: 'tilde embellishment', google translation) + - "̄": [t: "макрон"] # 0x304 (en: 'macron embellishment', google translation) + - "̅": [t: "надчёркивание"] # 0x305 (en: 'overbar embellishment', google translation) + - "̆": [t: "брэвэ"] # 0x306 (en: 'breve', google translation) + - "̇": [t: "точка сверху"] # 0x307 (en: 'dot above embellishment', google translation) + + # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong + - "Α-Ω": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [t: "заглавная"] # (en: 'cap') + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [x: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] + + - "α": [t: "альфа"] # 0x3b1 (en: 'alpha') + - "β": [t: "бета"] # 0x3b2 (en: 'beta') + - "γ": [t: "гамма"] # 0x3b3 (en: 'gamma') + - "δ": [t: "дельта"] # 0x3b4 (en: 'delta') + - "ε": [t: "эпсилон"] # 0x3b5 (en: 'epsilon') + - "ζ": [t: "дзета"] # 0x3b6 (en: 'zeta') + - "η": [t: "эта"] # 0x3b7 (en: 'eta') + - "θ": [t: "тета"] # 0x3b8 (en: 'theta') + - "ι": [t: "йота"] # 0x3b9 (en: 'iota') + - "κ": [t: "каппа"] # 0x3ba (en: 'kappa') + - "λ": [t: "лямбда"] # 0x3bb (en: 'lambda') + - "μ": [t: "мю"] # 0x3bc (en: 'mu') + - "ν": [t: "ню"] # 0x3bd (en: 'nu') + - "ξ": [t: "кси"] # 0x3be (en: 'zai') + - "ο": [t: "омикрон"] # 0x3bf (en: 'omicron') + - "π": [t: "пи"] # 0x3c0 (en: 'pi') + - "ρ": [t: "ро"] # 0x3c1 (en: 'rho') + - "ς": [t: "финальная сигма"] # 0x3c2 (en: 'final sigma') + - "σ": [t: "сигма"] # 0x3c3 (en: 'sigma') + - "τ": [t: "тау"] # 0x3c4 (en: 'tau') + - "υ": [t: "ипсилон"] # 0x3c5 (en: 'upsilon') + - "φ": [t: "фи"] # 0x3c6 (en: 'phi') + - "χ": [t: "хи"] # 0x3c7 (en: 'chi') + - "ψ": [t: "пси"] # 0x3c8 (en: 'psi') + - "ω": [t: "омега"] # 0x3c9 (en: 'omega') + - "ϕ": [t: "фи"] # 0x3d5 (en: 'phi') + - "ϖ": [t: "пи"] # 0x3d6 (en: 'pi') + - "ϵ": [t: "эпсилон"] # 0x3f5 (en: 'epsilon') + - "϶": [t: "обратный эпсилон"] # 0x3f6 (en: 'reversed epsilon') + + - "⁡": # 0x2061 + - test: + # skip saying "of" after trig functions, geometry shapes, or in :literal mode + if: "not(preceding-sibling::*[1][IsInDefinition(., 'TrigFunctionNames') or self::m:inverse-function or (self::m:power and IsInDefinition(*[1], 'TrigFunctionNames'))]) and not(preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')]) and + not(@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')])" + then: [t: "от"] # (en: 'of', google translation) + - "⁢": # 0x2062 + - test: + if: "@data-function-guess and following-sibling::*[1][self::m:mrow and IsBracketed(., '(', ')')] and $ClearSpeak_Functions!='None'" + then: [pause: short] + - "⁣": [t: ""] # 0x2063 + - "⁤": [t: "и"] # 0x2064 (en: 'and', google translation) + - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" + - t: "двойное" # (en: 'double-struck') + - spell: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" + + - "℃": [t: "градусы цельсия"] # 0x2103 (en: 'degrees celsius', google translation) + - "ℋℛℓ": # 0x210b + - t: "рукописное" # (en: 'script', google translation) + - spell: "translate('.', 'ℋℛℓ', 'HRl')" + - "ℜ": # 0x211c + - t: "готическая" # (en: 'fraktur', google translation) + - spell: "'R'" + + - "ⅆⅇⅈⅉ": # 0x2146-9 + - t: "двойной курсив" # (en: 'double-struck italic', google translation) + - spell: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" + + - "←": [t: "стрелка влево"] # 0x2190 (en: 'leftwards arrow', google translation) + - "↑": [t: "стрелка вверх"] # 0x2191 (en: 'upwards arrow', google translation) + - "→": # 0x2192 + - test: + if: "(parent::m:mover or parent::m:modified-variable) and ($SpeechStyle='LiteralSpeak' or ancestor-or-self::*[contains(@data-intent-property, ':literal:')])" + then: [t: "со стрелкой"] + else_test: + if: "ancestor::*[2][self::m:limit]" + then: [t: "стремящемся к"] # (en: 'approaches', google translation) + else: [t: "стрелка вправо"] # (en: 'right arrow', google translation) + + - "↓": [t: "стрелка вниз"] # 0x2193 (en: 'downwards arrow', google translation) + - "∈": # 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - test: + if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" + then: [t: ""] # (en: 'is', google translation) + - t: "принадлежит" # (en: 'an element of') + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [t: "в"] # (en: 'in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [t: "член"] # (en: 'member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [t: "элемент"] # (en: 'element of', google translation) + - else: [t: "принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [t: "член"] # (en: 'is a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [t: "элемент"] # (en: 'is an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [t: "находится в"] # (en: 'is in', google translation) + - else: [t: "принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - "∥": # 0x2225 + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'is', google translation) + - t: "параллельно" # (en: 'parallel to') + - "∦": # 0x2226 + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'is', google translation) + - t: "не параллельно" # (en: 'not parallel to') + - "≤": # 0x2264 + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'is', google translation) + - t: "меньше или равно" + - "≥": # 0x2265 + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'is', google translation) + - t: "больше или равно" # (en: 'greater than or equal to') + + # --- restored complex short definitions (prefer over unicode-full) --- + - "…": # 0x2026 + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak '…' as 'and so on...' unless expr starts with '…' + - "../*[1][.='…']" + then: [t: "многоточие"] # (en: 'dot dot dot') + else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' + if: "count(following-sibling::*) = 0" + then: [t: "и так далее"] # (en: 'and so on', google translation) + else: [t: "и так далее до"] # (en: 'and so on up to', google translation) + - "∂": # 0x2202 + - test: + if: "$Verbosity='Terse'" + then: [t: "частная производная"] # (en: 'partial', google translation) + else: [t: "частная производная"] # (en: 'partial derivative') + - "∆": # 0x2206 + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'the', google translation) + - t: "инкремент" # (en: 'laplacian of') + - "∉": # 0x2209 + # rule is identical to 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'is', google translation) + - t: "не принадлежит" # (en: 'not an element of') + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [t: "не в"] # (en: 'not in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [t: "не член"] # (en: 'not member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [t: "не элемент"] # (en: 'not element of', google translation) + - else: [t: "не принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [t: "не член"] # (en: 'is not a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [t: "не элемент"] # (en: 'is not an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [t: "не в"] # (en: 'is not in', google translation) + - else: [t: "не принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to') + - "∊": # 0x220a + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - test: + if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" + then: [t: ""] # (en: 'is', google translation) + - t: "малое принадлежит" # (en: 'an element of') + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [t: "в"] # (en: 'in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [t: "член"] # (en: 'member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [t: "элемент"] # (en: 'element of', google translation) + - else: [t: "малое принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [t: "член"] # (en: 'is a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [t: "элемент"] # (en: 'is an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [t: "находится в"] # (en: 'is in', google translation) + - else: [t: "малое принадлежит"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - "√": # 0x221a + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'the', google translation) + - t: "квадратный корень" # (en: 'square root of') + - "∝": # 0x221d + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'is', google translation) + - t: "пропорционально" # (en: 'proportional to') + - "∶": # 0x2236 + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'is', google translation) + - t: "отношение" # (en: 'to') + - "∾": # 0x223e + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'is', google translation) + - t: "изогнутая эс" # (en: 'most positive') + - "≠": # 0x2260 + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'is', google translation) + - t: "не равно" # (en: 'not equal to') + - "≡": # 0x2261 + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'is', google translation) + - t: "тождественно равно" # (en: 'identical to') + - "⊂": # 0x2282 + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'is a', google translation) + - t: "подмножество" # (en: 'subset of') + - "⊃": # 0x2283 + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'is a', google translation) + - t: "надмножество" # (en: 'superset of') + - "⊄": # 0x2284 + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'is', google translation) + - t: "не подмножество" # (en: 'not a subset of') + - "⊅": # 0x2285 + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'is', google translation) + - t: "не надмножество" # (en: 'not a superset of') + - "⊆": # 0x2286 + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'is a', google translation) + - t: "подмножество или равно" # (en: 'subset of or equal to') + - "⊇": # 0x2287 + - test: + if: "$Verbosity!='Terse'" + then: [t: ""] # (en: 'is a', google translation) + - t: "надмножество или равно" # (en: 'superset of or equal to') + + # --- restored short definitions that differ from unicode-full --- + - "‖": [t: "двойная вертикальная черта"] # 0x2016 (en: 'double vertical line', google translation) + - "℉": [t: "градусы фаренгейта"] # 0x2109 (en: 'degrees fahrenheit', google translation) + - "Ω": [t: "ом"] # 0x2126 (en: 'ohms', google translation) + - "Å": [t: "ангстрем"] # 0x212b (en: 'angstroms', google translation) + - "⇒": [t: "двойная стрелка вправо"] # 0x21d2 (en: 'rightwards double arrow', google translation) + - "∐": [t: "эн-арный сомножитель"] # 0x2210 (en: 'co-product') + - "∓": [t: "минус плюс"] # 0x2213 (en: 'minus or plus') + - "∗": [t: "звёздочка"] # 0x2217 (en: 'times') + - "∘": [t: "композиция"] # 0x2218 (en: 'composed with') + - "∧": [t: "логическое и"] # 0x2227 (en: 'and') + - "∨": [t: "логическое или"] # 0x2228 (en: 'or') + - "∮": [t: "интеграл по контуру"] # 0x222e (en: 'contour integral') + - "∷": [t: "пропорция"] # 0x2237 (en: 'as') + - "∼": [t: "тильда"] # 0x223c (en: 'varies with') + - "∿": [t: "синусоидальная волна"] # 0x223f (en: 'sine wave') + - "≦": [t: "меньше над равно"] # 0x2266 (en: 'less than over equal to') + - "≧": [t: "больше над равно"] # 0x2267 (en: 'greater than over equal to') + - "≻": [t: "следует за"] # 0x227b (en: 'succeeds') diff --git a/Rules/Languages/vi/unicode-full.yaml b/Rules/Languages/vi/unicode-full.yaml index f79caf2cf..7d3d53b59 100644 --- a/Rules/Languages/vi/unicode-full.yaml +++ b/Rules/Languages/vi/unicode-full.yaml @@ -1,3382 +1,3382 @@ ---- - - - - "¤": [t: "dấu hiệu tiền tệ"] # 0xa4 (en: 'currency sign') - - "¥": [t: "yên"] # 0xa5 (en: 'yen') - - "¦": [t: "thanh bị hỏng"] # 0xa6 (en: 'broken bar') - - "§": [t: "tiết diện"] # 0xa7 (en: 'section') - - "¨": [t: "chấm đôi"] # 0xa8 (en: 'double dot') - - "©": [t: "bản quyền"] # 0xa9 (en: 'copyright') - - "ª": [t: "chỉ số thứ tự nữ tính"] # 0xaa (en: 'feminine ordinal indicator') - - "«": [t: "dấu ý nghĩa góc cạnh trái"] # 0xab (en: 'left-pointing double angle quote mark') - - "¯": # 0xaf - - test: - if: "ancestor::m:modified-variable and preceding-sibling::*[1][self::m:mi]" - then: [T: "ngang"] # (en: 'bar') -- as in "x bar", a shorthand way to speak this - else: [t: "dòng"] # (en: 'line') - - "²": [t: "hai"] # 0xb2 (en: 'two') - - "³": [t: "số ba"] # 0xb3 (en: 'three') - - "µ": [t: "vi mô"] # 0xb5 (en: 'micro') - - "¹": [t: "một"] # 0xb9 (en: 'one') - - "º": [t: "chỉ số thứ tự nam tính"] # 0xb9 (en: 'masculine ordinal indicator') - - "ʰ": [t: "công cụ sửa đổi nhỏ h"] # 0x2b0 (en: 'modifier small h') - - "ʱ": [t: "công cụ sửa đổi h nhỏ với móc"] # 0x2b1 (en: 'modifier small h with hook') - - "ʲ": [t: "sửa đổi nhỏ j"] # 0x2b2 (en: 'modifier small j') - - "ʳ": [t: "công cụ sửa đổi nhỏ r"] # 0x2b3 (en: 'modifier small r') - - "ʴ": [t: "công cụ sửa đổi nhỏ quay r"] # 0x2b4 (en: 'modifier small turned r') - - "ʵ": [t: "công cụ sửa đổi nhỏ quay r với móc"] # 0x2b5 (en: 'modifier small turned r with hook') - - "ʶ": # 0x2b6 - - t: "sửa đổi nhỏ đảo ngược" # (en: 'modifier small inverted') - - spell: "translate('R', 'R', 'R')" - - - "ʷ": [t: "sửa đổi nhỏ w"] # 0x2b7 (en: 'modifier small w') - - "ʸ": [t: "công cụ sửa đổi nhỏ y"] # 0x2b8 (en: 'modifier small y') - - "ʹ": [t: "công cụ sửa đổi prime"] # 0x2b9 (en: 'modifier prime') - - "ʺ": [t: "công cụ sửa đổi double prime"] # 0x2ba (en: 'modifier double prime') - - "ʻ": [t: "công cụ sửa đổi đã trở thành dấu phẩy"] # 0x2bb (en: 'modifier turned comma') - - "ʼ": [t: "ăn dây sửa đổi"] # 0x2bc (en: 'modifier apostrophe') - - "ʽ": [t: "công cụ sửa đổi đảo ngược dấu phẩy"] # 0x2bd (en: 'modifier reversed comma') - - "ʾ": [t: "công cụ sửa đổi một nửa vòng"] # 0x2be (en: 'modifier right half ring') - - "ʿ": [t: "công cụ sửa đổi một nửa vòng"] # 0x2bf (en: 'modifier left half ring') - - "ˀ": [t: "công cụ sửa đổi glottal stop"] # 0x2c0 (en: 'modifier glottal stop') - - "ˁ": [t: "công cụ sửa đổi đảo ngược điểm dừng glottal"] # 0x2c1 (en: 'modifier reversed glottal stop') - - "˂": [t: "công cụ sửa đổi mũi tên trái"] # 0x2c2 (en: 'modifier left arrowhead') - - "˃": [t: "công cụ sửa đổi mũi tên phải"] # 0x2c3 (en: 'modifier right arrowhead') - - "˄": [t: "công cụ sửa đổi lên đầu mũi tên"] # 0x2c4 (en: 'modifier up arrowhead') - - "˅": [t: "công cụ sửa đổi xuống mũi tên"] # 0x2c5 (en: 'modifier down arrowhead') - - "ˆ": [t: "điểm nhấn của circleflex"] # 0x2c6 (en: 'modifier circumflex accent') - - "ˇ": [t: "caron"] # 0x2c7 - - "ˈ": [t: "công cụ sửa đổi đường thẳng đứng"] # 0x2c8 (en: 'modifier vertical line') - - "ˉ": [t: "macron công cụ sửa đổi"] # 0x2c9 (en: 'modifier macron') - - "ˊ": [t: "modifier điểm nhấn cấp tính"] # 0x2ca (en: 'modifier acute accent') - - "ˋ": [t: "điểm nhấn nghiêm trọng của công cụ sửa đổi"] # 0x2cb (en: 'modifier grave accent') - - "ˌ": [t: "công cụ sửa đổi đường thẳng đứng thấp"] # 0x2cc (en: 'modifier low vertical line') - - "ˍ": [t: "công cụ sửa đổi macron thấp"] # 0x2cd (en: 'modifier low macron') - - "ˎ": [t: "công cụ sửa đổi giọng mộ thấp"] # 0x2ce (en: 'modifier low grave accent') - - "ˏ": [t: "công cụ sửa đổi điểm nhấn cấp tính thấp"] # 0x2cf (en: 'modifier low acute accent') - - "ː": [t: "công cụ sửa đổi đại tràng hình tam giác"] # 0x2d0 (en: 'modifier triangular colon') - - "ˑ": [t: "công cụ sửa đổi một nửa đại tràng hình tam giác"] # 0x2d1 (en: 'modifier half triangular colon') - - "˒": [t: "công cụ sửa đổi tập trung nửa vòng"] # 0x2d2 (en: 'modifier centered right half ring') - - "˓": [t: "công cụ sửa đổi tập trung nửa vòng trái"] # 0x2d3 (en: 'modifier centered left half ring') - - "˔": [t: "công cụ sửa đổi lên tadck"] # 0x2d4 (en: 'modifier up tadck') - - "˕": [t: "công cụ sửa đổi xuống"] # 0x2d5 (en: 'modifier down tack') - - "˖": [t: "công cụ sửa đổi cộng với dấu hiệu"] # 0x2d6 (en: 'modifier plus sign') - - "˗": [t: "công cụ sửa đổi trừ dấu hiệu"] # 0x2d7 (en: 'modifier minus sign') - - "˘": [t: "breve"] # 0x2d8 - - "˙": [t: "chấm"] # 0x2d9 (en: 'dot') - - "˚": [t: "nhẫn ở trên"] # 0x2da (en: 'ring above') - - "˛": [t: "ogonek"] # 0x2db - - "˜": [t: "tilde nhỏ"] # 0x2dc (en: 'small tilde') - - "˝": [t: "giọng cấp tính gấp đôi"] # 0x2dd (en: 'double acute accent') - - "˞": [t: "mod soditoter mood"] # 0x2de (en: 'modifier rhotic hook') - - "˟": [t: "máy điều chỉnh điểm nhấn chéo"] # 0x2df (en: 'modifier cross accent') - - "ˠ": [t: "công cụ sửa đổi gamma nhỏ"] # 0x2e0 (en: 'modifier small gamma') - - "ˡ": [t: "sửa đổi nhỏ l"] # 0x2e1 (en: 'modifier small l') - - "ˢ": [t: "sửa đổi nhỏ s"] # 0x2e2 (en: 'modifier small s') - - "ˣ": [t: "công cụ sửa đổi nhỏ x"] # 0x2e3 (en: 'modifier small x') - - "ˤ": [t: "công cụ sửa đổi điểm dừng glottal đảo ngược nhỏ"] # 0x2e4 (en: 'modifier small reversed glottal stop') - - "˥": [t: "công cụ sửa đổi thanh âm cực cao"] # 0x2e5 (en: 'modifier extra-high tone bar') - - "˦": [t: "công cụ sửa đổi thanh âm cao"] # 0x2e6 (en: 'modifier high tone bar') - - "˧": [t: "công cụ sửa đổi thanh giữa giai điệu"] # 0x2e7 (en: 'modifier mid tone bar') - - "˨": [t: "công cụ sửa đổi thanh âm thấp"] # 0x2e8 (en: 'modifier low tone bar') - - "˩": [t: "công cụ sửa đổi thanh âm thấp"] # 0x2e9 (en: 'modifier extra-low tone bar') - - "˪": [t: "công cụ sửa đổi yin khởi hành dấu ấn"] # 0x2ea (en: 'modifier yin departing tone mark') - - "˫": [t: "công cụ sửa đổi yang khởi hành dấu ấn"] # 0x2eb (en: 'modifier yang departing tone mark') - - "ˬ": [t: "công cụ sửa đổi lồng tiếng"] # 0x2ec (en: 'modifier voicing') - - "˭": [t: "người sửa đổi không được khám phá"] # 0x2ed (en: 'modifier unaspirated') - - "ˮ": [t: "bản mô tín hiệu nhân đôi"] # 0x2ee (en: 'modifier double apostrophe') - - "˯": [t: "công cụ sửa đổi mũi tên thấp xuống"] # 0x2ef (en: 'modifier low down arrowhead') - - "˰": [t: "công cụ sửa đổi mũi tên thấp"] # 0x2f0 (en: 'modifier low up arrowhead') - - "˱": [t: "công cụ sửa đổi mũi tên thấp bên trái"] # 0x2f1 (en: 'modifier low left arrowhead') - - "˲": [t: "công cụ sửa đổi mũi tên thấp phải"] # 0x2f2 (en: 'modifier low right arrowhead') - - "˳": [t: "công cụ sửa đổi vòng thấp"] # 0x2f3 (en: 'modifier low ring') - - "˴": [t: "máy điều chỉnh giọng giới thiệu giữa"] # 0x2f4 (en: 'modifier middle grave accent') - - "˵": [t: "modifier middle double grave accent"] # 0x2f5 - - "˶": [t: "công cụ sửa đổi trung tâm cấp tính cấp tính"] # 0x2f6 (en: 'modifier middle double acute accent') - - "˷": [t: "công cụ sửa đổi tilde thấp"] # 0x2f7 (en: 'modifier low tilde') - - "˸": [t: "công cụ sửa đổi nâng đại tràng"] # 0x2f8 (en: 'modifier raised colon') - - "˹": [t: "công cụ sửa đổi bắt đầu âm cao"] # 0x2f9 (en: 'modifier begin high tone') - - "˺": [t: "công cụ sửa đổi kết thúc âm cao"] # 0x2fa (en: 'modifier end high tone') - - "˻": [t: "công cụ sửa đổi bắt đầu âm thấp"] # 0x2fb (en: 'modifier begin low tone') - - "˼": [t: "công cụ sửa đổi kết thúc âm thấp"] # 0x2fc (en: 'modifier end low tone') - - "˽": [t: "kệ điều chỉnh"] # 0x2fd (en: 'modifier shelf') - - "˾": [t: "công cụ sửa đổi kệ mở"] # 0x2fe (en: 'modifier open shelf') - - "˿": [t: "công cụ sửa đổi mũi tên thấp bên trái"] # 0x2ff (en: 'modifier low left arrow') - - "̈": [t: "tinh chỉnh diaeresis"] # 0x308 (en: 'diaeresis embellishment') - - "̉": [t: "móc trên tô điểm"] # 0x309 (en: 'hook above embellishment') - - "̊": [t: "ring trên tôn tạo"] # 0x30a (en: 'ring above embellishment') - - "̋": [t: "double cấp tính tô điểm"] # 0x30b (en: 'double acute accent embellishment') - - "̌": [t: "kiểm tra"] # 0x30c (en: 'check') - - "̍": [t: "đường thẳng đứng trên tô điểm"] # 0x30d (en: 'vertical line above embellishment') - - "̎": [t: "double dòng thẳng đứng trên tô điểm"] # 0x30e (en: 'double vertical line above embellishment') - - "̏": [t: "double grave ecrent song sự"] # 0x30f (en: 'double grave accent embellishment') - - "̐": [t: "tinh chỉnh candrabindu"] # 0x310 (en: 'candrabindu embellishment') - - "̑": [t: "đảo ngược sự tô điểm breve"] # 0x311 (en: 'inverted breve embellishment') - - "̒": [t: "biến dấu phẩy trên tôn tạo"] # 0x312 (en: 'turned comma above embellishment') - - "̓": [t: "dấu phẩy trên tôn tạo"] # 0x313 (en: 'comma above embellishment') - - "̔": [t: "pháo đảo dấu phẩy trên tôn tạo"] # 0x314 (en: 'reversed comma above embellishment') - - "̕": [t: "dấu phẩy ở trên chỉnh trang bên phải"] # 0x315 (en: 'comma above right embellishment') - - "̖": [t: "điểm nhấn nghiêm trọng dưới sự tôn tạo"] # 0x316 (en: 'grave accent below embellishment') - - "̗": [t: "điểm nhấn cấp tính dưới sự tô điểm"] # 0x317 (en: 'acute accent below embellishment') - - "̘": [t: "trái bên dưới sự tôn tạo"] # 0x318 (en: 'left tack below embellishment') - - "̙": [t: "phải tad dưới sự tôn tạo"] # 0x319 (en: 'right tack below embellishment') - - "̚": [t: "góc trái phía trên sự tô điểm"] # 0x31a (en: 'left angle above embellishment') - - "̛": [t: "sừng tô điểm"] # 0x31b (en: 'horn embellishment') - - "̜": [t: "một nửa vòng trái bên dưới sự tô điểm"] # 0x31c (en: 'left half ring below embellishment') - - "̝": [t: "up tack bên dưới sự tô điểm"] # 0x31d (en: 'up tack below embellishment') - - "̞": [t: "xuống dưới sự tôn tạo"] # 0x31e (en: 'down tack below embellishment') - - "̟": [t: "cộng với dấu hiệu dưới đây tô điểm"] # 0x31f (en: 'plus sign below embellishment') - - "̠": [t: "trừ dấu hiệu dưới đây tô điểm"] # 0x320 (en: 'minus sign below embellishment') - - "̡": [t: "móc vòm miệng bên dưới sự tô điểm"] # 0x321 (en: 'palatalized hook below embellishment') - - "̢": [t: "retroflex hook dưới sự tô điểm"] # 0x322 (en: 'retroflex hook below embellishment') - - "̣": [t: "dot dưới sự tô điểm"] # 0x323 (en: 'dot below embellishment') - - "̤": [t: "diaeresis dưới sự tô điểm"] # 0x324 (en: 'diaeresis below embellishment') - - "̥": [t: "nhẫn dưới sự tô điểm"] # 0x325 (en: 'ring below embellishment') - - "̦": [t: "dấu phẩy dưới sự tôn tạo"] # 0x326 (en: 'comma below embellishment') - - "̧": [t: "tinh chỉnh cedilla"] # 0x327 (en: 'cedilla embellishment') - - "̨": [t: "ogonek tô điểm"] # 0x328 (en: 'ogonek embellishment') - - "̩": [t: "đường thẳng đứng dưới sự tô điểm"] # 0x329 (en: 'vertical line below embellishment') - - "̪": [t: "cầu dưới sự tô điểm"] # 0x32a (en: 'bridge below embellishment') - - "̫": [t: "đảo ngược đôi vòm dưới sự tô điểm"] # 0x32b (en: 'inverted double arch below embellishment') - - "̬": [t: "caron dưới sự tôn tạo"] # 0x32c (en: 'caron below embellishment') - - "̭": [t: "vòng tròn âm thanh dưới sự tô điểm"] # 0x32d (en: 'circumflex accent below embellishment') - - "̮": [t: "breve dưới sự tôn tạo"] # 0x32e (en: 'breve below embellishment') - - "̯": [t: "đảo ngược breve dưới sự tô điểm"] # 0x32f (en: 'inverted breve below embellishment') - - "̰": [t: "tilde dưới sự tôn tạo"] # 0x330 (en: 'tilde below embellishment') - - "̱": [t: "macron dưới sự tô điểm"] # 0x331 (en: 'macron below embellishment') - - "̲": [t: "tinh chỉnh dòng thấp"] # 0x332 (en: 'low line embellishment') - - "̳": [t: "double line dòng tô điểm"] # 0x333 (en: 'double low line embellishment') - - "̴": [t: "tinh chỉnh lớp phủ tilde"] # 0x334 (en: 'tilde overlay embellishment') - - "̵": [t: "tiếng gạch ngắn tô điểm"] # 0x335 (en: 'short stroke overlay embellishment') - - "̶": [t: "tinh chỉnh lớp phủ dài"] # 0x336 (en: 'long stroke overlay embellishment') - - "̷": [t: "slidus lớp phủ ngắn gọn"] # 0x337 (en: 'short solidus overlay embellishment') - - "̸": [t: "tinh chỉnh lớp phủ solidus dài"] # 0x338 (en: 'long solidus overlay embellishment') - - "̹": [t: "một nửa vòng bên phải bên dưới sự tô điểm"] # 0x339 (en: 'right half ring below embellishment') - - "̺": [t: "cầu đảo dưới sự tôn tạo"] # 0x33a (en: 'inverted bridge below embellishment') - - "̻": [t: "hình vuông dưới sự tô điểm"] # 0x33b (en: 'square below embellishment') - - "̼": [t: "seagull dưới sự tôn tạo"] # 0x33c (en: 'seagull below embellishment') - - "̽": [t: "x trên tô điểm"] # 0x33d (en: 'x above embellishment') - - "̾": [t: "tinh chỉnh tilde dọc"] # 0x33e (en: 'vertical tilde embellishment') - - "̿": [t: "double overline tô điểm"] # 0x33f (en: 'double overline embellishment') - - "̀": [t: "grave tone đánh dấu dấu ấn"] # 0x340 (en: 'grave tone mark embellishment') - - "́": [t: "giai điệu cấp tính đánh dấu dấu ấn"] # 0x341 (en: 'acute tone mark embellishment') - - - "ΪΫϏ": # 0x3aa, 0x3ab, 0x3cf - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [t: "hậu quả"] # (en: 'cap') - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [spell: "translate('.', 'ΪΫϏ', 'ιυϗ')"] - - t: "với dialytika" # (en: 'with dialytika') - - "ϊ": [t: "iota với dialytika"] # 0x3ca (en: 'iota with dialytika') - - "ϋ": [t: "upsilon với dialytika"] # 0x3cb (en: 'upsilon with dialytika') - - "ό": [t: "omicron với tonos"] # 0x3cc (en: 'omicron with tonos') - - "ύ": [t: "upsilon với tonos"] # 0x3cd (en: 'upsilon with tonos') - - "ώ": [t: "omega với tonos"] # 0x3ce (en: 'omega with tonos') - - "ϐ": [t: "beta"] # 0x3d0 - - "ϑ": [t: "theta"] # 0x3d1 - - "ϒ": [t: "upsilon với móc"] # 0x3d2 (en: 'upsilon with hook') - - "ϓ": [t: "upsilon với cấp tính và móc"] # 0x3d3 (en: 'upsilon with acute and hook') - - "ϔ": [t: "upsilon với dieresis và hook"] # 0x3d4 (en: 'upsilon with diaeresis and hook') - - "ϗ": [t: "kai"] # 0x3d7 - - "А-Я": # 0x410 - 0x42f - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [t: "hậu quả"] # (en: 'cap') - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [spell: "translate('.', 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ', 'абвгдежзийклмнопрстуфхцчшщъыьэюя')"] - - "а": [t: "а"] # 0x430 (en: 'a') - - "б": [t: "thì là ở"] # 0x431 (en: 'be') - - "в": [t: "đã"] # 0x432 (en: 've') - - "г": [t: "ghe"] # 0x433 - - "д": [t: "de"] # 0x434 - - "е": [t: "i e"] # 0x435 (en: 'ie') - - "ж": [t: "zhe"] # 0x436 - - "з": [t: "ze"] # 0x437 - - "и": [t: "и"] # 0x438 (en: 'i') - - "й": [t: "ngắn i"] # 0x439 (en: 'short i') - - "к": [t: "ka"] # 0x43a - - "л": [t: "el"] # 0x43b - - "м": [t: "em"] # 0x43c - - "н": [t: "en"] # 0x43d - - "о": [t: "о"] # 0x43e (en: 'o') - - "п": [t: "thể dục"] # 0x43f (en: 'pe') - - "р": [t: "er"] # 0x440 - - "с": [t: "es"] # 0x441 - - "т": [t: "te"] # 0x442 - - "у": [t: "у"] # 0x443 (en: 'u') - - "ф": [t: "ef"] # 0x444 - - "х": [t: "ha"] # 0x445 - - "ц": [t: "tse"] # 0x446 - - "ч": [t: "che"] # 0x447 - - "ш": [t: "sha"] # 0x448 - - "щ": [t: "shcha"] # 0x449 - - "ъ": [t: "dấu hiệu khó"] # 0x44a (en: 'hard sign') - - "ы": [t: "yeru"] # 0x44b - - "ь": [t: "dấu hiệu mềm"] # 0x44c (en: 'soft sign') - - "э": [t: "э"] # 0x44d (en: 'e') - - "ю": [t: "yu"] # 0x44e - - "я": [t: "ya"] # 0x44f - - "‐": [t: "bắt gạch"] # 0x2010 (en: 'hyphen') - - "‑": [t: "bắt gạch"] # 0x2011 (en: 'hyphen') - - "‒": [t: "hình dash"] # 0x2012 (en: 'figure dash') - - "•": [t: "đạn"] # 0x2022 (en: 'bullet') - - "‰": [t: "mỗi mille"] # 0x2030 (en: 'per mille') - - "‱": [t: "mỗi mười nghìn"] # 0x2031 (en: 'per ten thousand') - - "‸": [t: "đến"] # 0x2038 (en: 'to the') - - "‹": [t: "một bên trái chỉ góc trích dẫn dấu hiệu"] # 0x2039 (en: 'single left pointing angle quote mark') - - "›": [t: "độc thân chỉ góc trích dẫn dấu hiệu"] # 0x203a (en: 'single right pointing angle quote mark') - - "‼": [t: "nhân đôi nhân đôi"] # 0x203c (en: 'double factorial') - - "⁄": [T: "trên"] # 0x2044 - - "⁅": [t: "khung vuông bên trái với quill"] # 0x2045 (en: 'left square bracket with quill') - - "⁆": [t: "khung vuông bên phải với quill"] # 0x2046 (en: 'right square bracket with quill') - - "⁗": [t: "quadruple prime"] # 0x2057 - - "⁠": [t: ""] # 0x2060 - - "⁰": [T: "mũ không"] # 0x2070 (en: 'to the zeroth power') - - "ⁱ": [T: "mũ tám"] # 0x2071 (en: 'to the eihth power') - - "⁴": [T: "mũ bốn"] # 0x2074 (en: 'to the fourth power') - - "⁵": [T: "mũ năm"] # 0x2075 (en: 'to the fifth power') - - "⁶": [T: "mũ sáu"] # 0x2076 (en: 'to the sixth power') - - "⁷": [T: "mũ bảy"] # 0x2077 (en: 'to the seventh power') - - "⁸": [T: "mũ tám"] # 0x2078 (en: 'to the eighth power') - - "⁹": [T: "mũ chín"] # 0x2079 (en: 'to the ninth power') - - "⁺": [t: "superscript plus dấu hiệu"] # 0x207a (en: 'superscript plus sign') - - "⁻": [t: "superscript trừ"] # 0x207b (en: 'superscript minus') - - "⁼": [t: "superscript bằng dấu hiệu"] # 0x207c (en: 'superscript equals sign') - - "⁽": [t: "superscript trái dấu ngoặc đơn"] # 0x207d (en: 'superscript left parenthesis') - - "⁾": [t: "superscript bên phải dấu ngoặc đơn"] # 0x207e (en: 'superscript right parenthesis') - - "ⁿ": [t: "đến sức mạnh ennth"] # 0x207f (en: 'to the ennth power') - - "₀": [t: "âm độ"] # 0x2080 (en: 'sub zero') - - "₁": [t: "phụ một"] # 0x2081 (en: 'sub one') - - "₂": [t: "phụ hai"] # 0x2082 (en: 'sub two') - - "₃": [t: "phụ ba"] # 0x2083 (en: 'sub three') - - "₄": [t: "phụ bốn"] # 0x2084 (en: 'sub four') - - "₅": [t: "phụ năm"] # 0x2085 (en: 'sub five') - - "₆": [t: "sub six"] # 0x2086 - - "₇": [t: "phụ bảy"] # 0x2087 (en: 'sub seven') - - "₈": [t: "phụ tại"] # 0x2088 (en: 'sub eight') - - "₉": [t: "sub nine"] # 0x2089 - - "₊": [t: "scorstcript plus dấu hiệu"] # 0x208a (en: 'subscript plus sign') - - "₋": [t: "scorstript minu dấu hiệu"] # 0x208b (en: 'subscript minus sign') - - "₌": [t: "chỉ số bằng dấu hiệu"] # 0x208c (en: 'subscript equals sign') - - "₍": [t: "chỉ số bên trái dấu ngoặc đơn"] # 0x208d (en: 'subscript left parenthesis') - - "₎": [t: "scorstist quyền quyền"] # 0x208e (en: 'subscript right parenthesis') - - "ₐ": [t: "sub a"] # 0x2090 (en: 'sub A') - - "ₑ": [t: "sub e"] # 0x2091 (en: 'sub E') - - "ₒ": [t: "sub o"] # 0x2092 (en: 'sub O') - - "ₓ": [t: "sub x"] # 0x2093 (en: 'sub X') - - "ₕ": [t: "sub h"] # 0x2095 (en: 'sub H') - - "ₖ": [t: "sub k"] # 0x2096 (en: 'sub K') - - "ₗ": [t: "sub l"] # 0x2097 (en: 'sub L') - - "ₘ": [t: "sub m"] # 0x2098 (en: 'sub M') - - "ₙ": [t: "sub n"] # 0x2099 (en: 'sub N') - - "ₚ": [t: "sub p"] # 0x209a (en: 'sub P') - - "ₛ": [t: "sub s"] # 0x209b (en: 'sub S') - - "ₜ": [t: "sub t"] # 0x209c (en: 'sub T') - - "₠": [t: "các đơn vị hiện tại của châu âu"] # 0x20a0 (en: 'european currenty units') - - "₡": [t: "phối tử"] # 0x20a1 (en: 'colons') - - "₢": [t: "cruzeiro"] # 0x20a2 - - "₣": [t: "franc"] # 0x20a3 - - "₤": [t: "lira"] # 0x20a4 - - "₥": [t: "nhà máy"] # 0x20a5 (en: 'mills') - - "₦": [t: "naira"] # 0x20a6 - - "₧": [t: "peseta"] # 0x20a7 - - "₨": [t: "rupee"] # 0x20a8 (en: 'rupees') - - "₩": [t: "thắng"] # 0x20a9 (en: 'won') - - "₪": [t: "sheqels mới"] # 0x20aa (en: 'new sheqels') - - "₫": [t: "dong"] # 0x20ab - - "€": [t: "euro"] # 0x20ac (en: 'euros') - - "₭": [t: "kip"] # 0x20ad - - "₮": [t: "tugrik"] # 0x20ae - - "₯": [t: "drachma"] # 0x20af - - "₰": [t: "đồng xu đức"] # 0x20b0 (en: 'german pennies') - - "₱": [t: "peso"] # 0x20b1 (en: 'pesos') - - "₲": [t: "guaranis"] # 0x20b2 - - "₳": [t: "austral"] # 0x20b3 (en: 'australs') - - "₴": [t: "hryvnias"] # 0x20b4 - - "₵": [t: "cedis"] # 0x20b5 - - "₶": [t: "livre tournois"] # 0x20b6 - - "₷": [t: "spesmilos"] # 0x20b7 - - "₸": [t: "tenges"] # 0x20b8 - - "₹": [t: "đồng rupee ấn độ"] # 0x20b9 (en: 'indian rupees') - - "₺": [t: "liras thổ nhĩ kỳ"] # 0x20ba (en: 'turkish liras') - - "⃐": [t: "trái harpoon phía trên sự tôn tạo"] # 0x20d0 (en: 'left harpoon above embellishment') - - "⃑": [t: "harpoon bên phải trên tôn tạo"] # 0x20d1 (en: 'right harpoon above embellishment') - - "⃒": [t: "tinh chỉnh lớp phủ dọc dài"] # 0x20d2 (en: 'long vertical line overlay embellishment') - - "⃓": [t: "tinh chỉnh lớp phủ thẳng đứng ngắn"] # 0x20d3 (en: 'short vertical line overlay embellishment') - - "⃔": [t: "mũi tên ngược chiều kim đồng hồ phía trên sự tô điểm"] # 0x20d4 (en: 'anticlockwise arrow above embellishment') - - "⃕": [t: "mũi tên theo chiều kim đồng hồ phía trên sự tô điểm"] # 0x20d5 (en: 'clockwise arrow above embellishment') - - "⃖": [t: "mũi tên trái phía trên sự tô điểm"] # 0x20d6 (en: 'left arrow above embellishment') - - "⃗": [t: "mũi tên bên phải trên tôn tạo"] # 0x20d7 (en: 'right arrow above embellishment') - - "⃘": [t: "đoạn lên lớp trang phục"] # 0x20d8 (en: 'ring overlay embellishment') - - "⃙": [t: "đoàn chiều theo chiều kim đồng hồ tô điểm"] # 0x20d9 (en: 'clockwise ring overlay embellishment') - - "⃚": [t: "tinh chỉnh lớp phủ vòng ngược chiều kim đồng hồ"] # 0x20da (en: 'anticlockwise ring overlay embellishment') - - "⃛": [t: "ba chấm"] # 0x20db (en: 'triple dot') - - "⃜": [t: "chấm bốn"] # 0x20dc (en: 'quadruple dot') - - "⃝": [t: "bao quanh tô điểm vòng tròn"] # 0x20dd (en: 'enclosing circle embellishment') - - "⃞": [t: "kèm theo tô điểm vuông"] # 0x20de (en: 'enclosing square embellishment') - - "⃟": [t: "kèm theo tô điểm kim cương"] # 0x20df (en: 'enclosing diamond embellishment') - - "⃠": [t: "kèm theo hình ảnh chao đảo"] # 0x20e0 (en: 'enclosing circle backslash embellishment') - - "⃡": [t: "mũi tên trái bên phải phía trên sự tô điểm"] # 0x20e1 (en: 'left right arrow above embellishment') - - "⃢": [t: "kèm theo tô điểm màn hình"] # 0x20e2 (en: 'enclosing screen embellishment') - - "⃣": [t: "kèm theo tô điểm khóa"] # 0x20e3 (en: 'enclosing keycap embellishment') - - "⃤": [t: "kèm theo tô điểm hình tam giác hướng lên"] # 0x20e4 (en: 'enclosing upward pointing triangle embellishment') - - "⃥": [t: "đảo ngược solidus overlay tô điểm"] # 0x20e5 (en: 'reverse solidus overlay embellishment') - - "⃦": [t: "tinh chỉnh gạch đôi"] # 0x20e6 (en: 'double verticle stroke embellishment') - - "⃧": [t: "tổ chức biểu tượng niên kim"] # 0x20e7 (en: 'annuity symbol embellishment') - - "⃨": [t: "triple underdot"] # 0x20e8 - - "⃩": [t: "cầu rộng phía trên sự tô điểm"] # 0x20e9 (en: 'wide bridge above embellishment') - - "⃪": [t: "bên trái mũi tên phủ lên sự tô điểm"] # 0x20ea (en: 'leftwards arrow overlay embellishment') - - "⃫": [t: "double solidus overlay overlay tô điểm"] # 0x20eb (en: 'long double solidus overlay embellishment') - - "⃬": [t: "quyền harpoon với barb downwards tallingation"] # 0x20ec (en: 'rightwards harpoon with barb downwards embellishment') - - "⃭": [t: "harpoon bên trái với barb downwwards song sự"] # 0x20ed (en: 'leftwards harpoon with barb downwards embellishment') - - "⃮": [t: "mũi tên trái bên dưới sự tô điểm"] # 0x20ee (en: 'left arrow below embellishment') - - "⃯": [t: "mũi tên phải dưới sự tôn tạo"] # 0x20ef (en: 'right arrow below embellishment') - - "⃰": [t: "astersik trên tôn tạo"] # 0x20f0 (en: 'astersik above embellishment') - - "℄": [t: "biểu tượng đường trung tâm"] # 0x2104 (en: 'center line symbol') - - "℅": [t: "quan tâm"] # 0x2105 (en: 'care of') - - "℆": [t: "cada una"] # 0x2106 - - "ℇ": [t: "hằng số của euler"] # 0x2107 (en: 'euler's constant') - - "℈": [t: "scruples"] # 0x2108 - - "ℊ": [t: "kịch bản g"] # 0x210a (en: 'script g') - - "ℌℑℨℭ": # 0x210c, 0x2111, 0x2128, 0x212d - - t: "fraktur" - - spell: "translate('.', 'ℌℑℨℭ', 'HIZC')" - - - "ℍℙℾℿ": # 0x210d, 0x2119, 0x213e, 0x213f - - test: - if: "$Verbosity!='Terse'" - then: [t: "cú đúp"] # (en: 'double struck') - - spell: "translate('.', 'ℍℙℾℿ', 'HPΓΠ')" - - - "ℏ": # 0x210f - - test: - if: "($Verbosity='Terse')" - then: [t: "h bar"] - else: [t: "giảm planck hằng số"] # (en: 'reduced planck constant') - - - "ℐℒ℘ℬℰℱℳ": # 0x2110, 0x2112, 0x2118, 0x2130, 0x2131, 0x2133 - - t: "script" - - spell: "translate('.', 'ℐℒ℘ℬℰℱℳ', 'ILPBEFM')" - - - "℔": [t: "bảng"] # 0x2114 (en: 'pounds') - - "№": [t: "số"] # 0x2116 (en: 'number') - - "℥": [t: "ounce"] # 0x2125 (en: 'ounces') - - "℧": [t: "mhos"] # 0x2127 - - "℩": [t: "đã quay iota"] # 0x2129 (en: 'turned iota') - - "ℯ": [t: "kịch bản e"] # 0x212f (en: 'script e') - - # coalesced some chars that use cap letters - - "Ⅎ℺⅁⅂⅃⅄": # 0x2132, 0x213a, 0x2141, 0x2142, 0x2143, 0x2144 - - test: - - if: "'.' = '℺'" - then: [t: "xoay"] # (en: 'rotated') - - else_if: "'.' = 'Ⅎ'" - then: [t: "quay"] # (en: 'turned') - - else_if: "'.' = '⅃'" - then: [t: "đảo ngược sans-serif"] # (en: 'reversed sans-serif') - else: [t: "biến sans-serif"] # (en: 'turned sans-serif') - - spell: "translate('.', 'Ⅎ℺⅁⅂⅃⅄', 'FQGLLY')" - - - "ℴ": [t: "kịch bản o"] # 0x2134 (en: 'script o') - - "ℵ": [t: "hồng y chuyển tiếp đầu tiên"] # 0x2135 (en: 'first transfinite cardinal') - - "ℶ": [t: "hồng y chuyển tiếp thứ hai"] # 0x2136 (en: 'second transfinite cardinal') - - "ℷ": [t: "hồng y transfinite thứ ba"] # 0x2137 (en: 'third transfinite cardinal') - - "ℸ": [t: "hồng y chuyển tiếp thứ tư"] # 0x2138 (en: 'fourth transfinite cardinal') - - "ℼ": [t: "double tấn công pi"] # 0x213c (en: 'double struck pi') - - "ℽ": [t: "double tấn công gamma"] # 0x213d (en: 'double struck gamma') - - "⅀": [t: "double tấn công tổng n-ary"] # 0x2140 (en: 'double struck n-ary summation') - - "⅋": [t: "quay ampersand"] # 0x214b (en: 'turned ampersand') - - "⅌": [t: "mỗi"] # 0x214c (en: 'per') - - "ⅎ": [t: "bật f"] # 0x214e (en: 'turned F') - - "⅐": [T: "một phần bảy"] # 0x2150 (en: 'one seventh') - - "⅑": [T: "một phần chín"] # 0x2151 (en: 'one ninth') - - "⅒": [T: "một phần mười"] # 0x2152 (en: 'one tenth') - - "⅓": [T: "một phần ba"] # 0x2153 (en: 'one third') - - "⅔": [T: "hai phần ba"] # 0x2154 (en: 'two thirds') - - "⅕": [T: "một phần năm"] # 0x2155 (en: 'one fifth') - - "⅖": [T: "hai phần năm"] # 0x2156 (en: 'two fifths') - - "⅗": [T: "ba phần năm"] # 0x2157 (en: 'three fifths') - - "⅘": [T: "bốn phần năm"] # 0x2158 (en: 'four fifths') - - "⅙": [T: "một phần sáu"] # 0x2159 (en: 'one sixth') - - "⅚": [T: "năm phần sáu"] # 0x215a (en: 'five sixths') - - "⅛": [T: "một phần tám"] # 0x215b (en: 'one eighth') - - "⅜": [T: "ba phần tám"] # 0x215c (en: 'three eighths') - - "⅝": [T: "năm phần tám"] # 0x215d (en: 'five eighths') - - "⅞": [T: "bảy phần tám"] # 0x215e (en: 'seven eighths') - - "⅟": [T: "một trên"] # 0x215f (en: 'one over') - - "Ⅰ": [t: "Ⅰ"] # 0x2160 (en: 'I') - - "Ⅱ": [t: "tôi i"] # 0x2161 (en: 'I I') - - "Ⅲ": [t: "tôi i i"] # 0x2162 (en: 'I I I') - - "Ⅳ": [t: "tôi v"] # 0x2163 (en: 'I V') - - "Ⅴ": [t: "Ⅴ"] # 0x2164 (en: 'V') - - "Ⅵ": [t: "v i"] # 0x2165 (en: 'V I') - - "Ⅶ": [t: "v i i"] # 0x2166 (en: 'V I I') - - "Ⅷ": [t: "v i i i"] # 0x2167 (en: 'V I I I') - - "Ⅸ": [t: "tôi x"] # 0x2168 (en: 'I X') - - "Ⅹ": [t: "Ⅹ"] # 0x2169 (en: 'X') - - "Ⅺ": [t: "x i"] # 0x216a (en: 'X I') - - "Ⅻ": [t: "x i i"] # 0x216b (en: 'X I I') - - "Ⅼ": [t: "Ⅼ"] # 0x216c (en: 'L') - - "Ⅽ": [t: "Ⅽ"] # 0x216d (en: 'C') - - "Ⅾ": [t: "Ⅾ"] # 0x216e (en: 'D') - - "Ⅿ": [t: "Ⅿ"] # 0x216f (en: 'M') - - "ⅰ": [t: "ⅰ"] # 0x2170 (en: 'I') - - "ⅱ": [t: "tôi i"] # 0x2171 (en: 'I I') - - "ⅲ": [t: "tôi i i"] # 0x2172 (en: 'I I I') - - "ⅳ": [t: "tôi v"] # 0x2173 (en: 'I V') - - "ⅴ": [t: "ⅴ"] # 0x2174 (en: 'V') - - "ⅵ": [t: "v i"] # 0x2175 (en: 'V I') - - "ⅶ": [t: "v i i"] # 0x2176 (en: 'V I I') - - "ⅷ": [t: "v i i i"] # 0x2177 (en: 'V I I I') - - "ⅸ": [t: "tôi x"] # 0x2178 (en: 'I X') - - "ⅹ": [t: "ⅹ"] # 0x2179 (en: 'X') - - "ⅺ": [t: "x i"] # 0x217a (en: 'X I') - - "ⅻ": [t: "x i i"] # 0x217b (en: 'X I I') - - "ⅼ": [t: "ⅼ"] # 0x217c (en: 'L') - - "ⅽ": [t: "ⅽ"] # 0x217d (en: 'C') - - "ⅾ": [t: "ⅾ"] # 0x217e (en: 'D') - - "ⅿ": [t: "ⅿ"] # 0x217f (en: 'M') - - "↉": [t: "không có một phần ba"] # 0x2189 (en: 'zero thirds') - - "↔": [t: "tương đương"] # 0x2194 (en: 'left right arrow') - - "↕": [t: "lên mũi tên xuống"] # 0x2195 (en: 'up down arrow') - - "↖": [t: "mũi tên tây bắc"] # 0x2196 (en: 'north west arrow') - - "↗": # 0x2197 - - test: - if: "ancestor::*[2][self::m:limit]" - then: [t: "cách tiếp cận từ bên dưới"] # (en: 'approaches from below') - else: [t: "mũi tên đông bắc"] # (en: 'north east arrow') - - - "↘": # 0x2198 - - test: - if: "ancestor::*[2][self::m:limit]" - then: [t: "cách tiếp cận từ trên cao"] # (en: 'approaches from above') - else: [t: "mũi tên đông nam"] # (en: 'south east arrow') - - - "↙": [t: "mũi tên tây nam"] # 0x2199 (en: 'south west arrow') - - "↚": [t: "mũi tên trái với gạch"] # 0x219a (en: 'leftwards arrow with stroke') - - "↛": [t: "mũi tên phải với gạch"] # 0x219b (en: 'rightwards arrow with stroke') - - "↜": [t: "mũi tên sóng trái"] # 0x219c (en: 'leftwards wave arrow') - - "↝": [t: "mũi tên sóng bên phải"] # 0x219d (en: 'rightwards wave arrow') - - "↞": [t: "bên trái hai mũi tên đầu"] # 0x219e (en: 'leftwards two headed arrow') - - "↟": [t: "lên tới hai mũi tên đầu"] # 0x219f (en: 'upwards two headed arrow') - - "↠": [t: "phải hai mũi tên hai đầu"] # 0x21a0 (en: 'rightwards two headed arrow') - - "↡": [t: "xuống hai mũi tên đầu"] # 0x21a1 (en: 'downwards two headed arrow') - - "↢": [t: "mũi tên trái có đuôi"] # 0x21a2 (en: 'leftwards arrow with tail') - - "↣": [t: "mũi tên phải có đuôi"] # 0x21a3 (en: 'rightwards arrow with tail') - - "↤": [t: "mũi tên trái từ thanh"] # 0x21a4 (en: 'leftwards arrow from bar') - - "↥": [t: "mũi tên hướng lên từ thanh"] # 0x21a5 (en: 'upwards arrow from bar') - - "↦": [t: "mũi tên bên phải từ thanh"] # 0x21a6 (en: 'rightwards arrow from bar') - - "↧": [t: "mũi tên xuống từ thanh"] # 0x21a7 (en: 'downwards arrow from bar') - - "↨": [t: "lên mũi tên xuống với cơ sở"] # 0x21a8 (en: 'up down arrow with base') - - "↩": [t: "mũi tên trái với móc"] # 0x21a9 (en: 'leftwards arrow with hook') - - "↪": [t: "mũi tên bên phải với móc"] # 0x21aa (en: 'rightwards arrow with hook') - - "↫": [t: "mũi tên trái với vòng lặp"] # 0x21ab (en: 'leftwards arrow with loop') - - "↬": [t: "mũi tên phải với vòng lặp"] # 0x21ac (en: 'rightwards arrow with loop') - - "↭": [t: "mũi tên bên trái bên phải"] # 0x21ad (en: 'left right wave arrow') - - "↮": [t: "mũi tên trái bên phải với gạch"] # 0x21ae (en: 'left right arrow with stroke') - - "↯": [t: "mũi tên ngoằn ngoèo xuống"] # 0x21af (en: 'downwards zigzag arrow') - - "↰": [t: "mũi tên hướng lên với đầu trái"] # 0x21b0 (en: 'upwards arrow with tip leftwards') - - "↱": [t: "mũi tên hướng lên với đầu bên phải"] # 0x21b1 (en: 'upwards arrow with tip rightwards') - - "↲": [t: "mũi tên xuống với đầu trái"] # 0x21b2 (en: 'downwards arrow with tip leftwards') - - "↳": [t: "mũi tên xuống với đầu bên phải"] # 0x21b3 (en: 'downwards arrow with tip rightwards') - - "↴": [t: "mũi tên bên phải với góc xuống"] # 0x21b4 (en: 'rightwards arrow with corner downwards') - - "↵": [t: "mũi tên xuống với góc trái"] # 0x21b5 (en: 'downwards arrow with corner leftwards') - - "↶": [t: "mũi tên bán nguyệt trên cùng theo chiều kim đồng hồ"] # 0x21b6 (en: 'anticlockwise top semicircle arrow') - - "↷": [t: "mũi tên bán nguyệt trên cùng theo chiều kim đồng hồ"] # 0x21b7 (en: 'clockwise top semicircle arrow') - - "↸": [t: "mũi tên tây bắc đến long bar"] # 0x21b8 (en: 'north west arrow to long bar') - - "↹": [t: "mũi tên trái để thanh trên mũi tên phải vào thanh"] # 0x21b9 (en: 'leftwards arrow to bar over rightwards arrow to bar') - - "↺": [t: "mũi tên vòng tròn mở theo chiều kim đồng hồ"] # 0x21ba (en: 'anticlockwise open circle arrow') - - "↻": [t: "mũi tên vòng tròn mở theo chiều kim đồng hồ"] # 0x21bb (en: 'clockwise open circle arrow') - - "↼": [t: "trái harpoon lên"] # 0x21bc (en: 'left harpoon up') - - "↽": [t: "rời harpoon xuống"] # 0x21bd (en: 'left harpoon down') - - "↾": [t: "up harpoon phải"] # 0x21be (en: 'up harpoon right') - - "↿": [t: "lên harpoon trái"] # 0x21bf (en: 'up harpoon left') - - "⇀": [t: "quyền harpoon lên"] # 0x21c0 (en: 'right harpoon up') - - "⇁": [t: "harpoon phải xuống"] # 0x21c1 (en: 'right harpoon down') - - "⇂": [t: "xuống harpoon phải"] # 0x21c2 (en: 'down harpoon right') - - "⇃": [t: "xuống harpoon trái"] # 0x21c3 (en: 'down harpoon left') - - "⇄": [t: "mũi tên phải qua mũi tên trái"] # 0x21c4 (en: 'rightwards arrow over leftwards arrow') - - "⇅": [t: "mũi tên hướng lên bên trái của mũi tên xuống"] # 0x21c5 (en: 'upwards arrow leftwards of downwards arrow') - - "⇆": [t: "mũi tên trái qua mũi tên phải"] # 0x21c6 (en: 'leftwards arrow over rightwards arrow') - - "⇇": [t: "mũi tên được ghép nối trái"] # 0x21c7 (en: 'leftwards paired arrows') - - "⇈": [t: "mũi tên đi lên trên"] # 0x21c8 (en: 'upwards paired arrows') - - "⇉": [t: "mũi tên được ghép ngay"] # 0x21c9 (en: 'rightwards paired arrows') - - "⇊": [t: "mũi tên đi xuống"] # 0x21ca (en: 'downwards paired arrows') - - "⇋": [t: "trái harpoon qua harpoon phải"] # 0x21cb (en: 'left harpoon over right harpoon') - - "⇌": [t: "harpoon phải qua harpoon trái"] # 0x21cc (en: 'right harpoon over left harpoon') - - "⇍": [t: "mũi tên đôi bên trái với gạch"] # 0x21cd (en: 'leftwards double arrow with stroke') - - "⇎": [t: "mũi tên kép bên trái với gạch"] # 0x21ce (en: 'left right double arrow with stroke') - - "⇏": [t: "mũi tên kép phải với gạch"] # 0x21cf (en: 'rightwards double arrow with stroke') - - "⇐": [t: "mũi tên đôi trái"] # 0x21d0 (en: 'leftwards double arrow') - - "⇑": [t: "mũi tên tăng gấp đôi"] # 0x21d1 (en: 'upwards double arrow') - - "⇓": [t: "xuống mũi tên đôi"] # 0x21d3 (en: 'downwards double arrow') - - "⇔": [t: "tương đương"] # 0x21d4 (en: 'left right double arrow') - - "⇕": [t: "lên xuống mũi tên đôi"] # 0x21d5 (en: 'up down double arrow') - - "⇖": [t: "mũi tên đôi tây bắc"] # 0x21d6 (en: 'north west double arrow') - - "⇗": [t: "mũi tên đôi đông bắc"] # 0x21d7 (en: 'north east double arrow') - - "⇘": [t: "mũi tên đôi đông nam"] # 0x21d8 (en: 'south east double arrow') - - "⇙": [t: "mũi tên đôi tây nam"] # 0x21d9 (en: 'south west double arrow') - - "⇚": [t: "mũi tên ba bên trái"] # 0x21da (en: 'leftwards triple arrow') - - "⇛": [t: "mũi tên ba bên phải"] # 0x21db (en: 'rightwards triple arrow') - - "⇜": [t: "mũi tên bên trái"] # 0x21dc (en: 'leftwards squiggle arrow') - - "⇝": [t: "mũi tên squiggle phải"] # 0x21dd (en: 'rightwards squiggle arrow') - - "⇞": [t: "mũi tên hướng lên với cú đánh đôi"] # 0x21de (en: 'upwards arrow with double stroke') - - "⇟": [t: "mũi tên xuống với cú đánh đôi"] # 0x21df (en: 'downwards arrow with double stroke') - - "⇠": [t: "mũi tên bên trái lao"] # 0x21e0 (en: 'leftwards dashed arrow') - - "⇡": [t: "mũi tên đi xuống"] # 0x21e1 (en: 'upwards dashed arrow') - - "⇢": [t: "mũi tên đứt phải bên phải"] # 0x21e2 (en: 'rightwards dashed arrow') - - "⇣": [t: "mũi tên xuống xuống"] # 0x21e3 (en: 'downwards dashed arrow') - - "⇤": [t: "mũi tên trái vào thanh"] # 0x21e4 (en: 'leftwards arrow to bar') - - "⇥": [t: "mũi tên phải vào thanh"] # 0x21e5 (en: 'rightwards arrow to bar') - - "⇦": [t: "mũi tên trắng bên trái"] # 0x21e6 (en: 'leftwards white arrow') - - "⇧": [t: "mũi tên trắng hướng lên trên"] # 0x21e7 (en: 'upwards white arrow') - - "⇨": [t: "mũi tên trắng bên phải"] # 0x21e8 (en: 'rightwards white arrow') - - "⇩": [t: "mũi tên trắng xuống"] # 0x21e9 (en: 'downwards white arrow') - - "⇪": [t: "mũi tên trắng hướng lên từ thanh"] # 0x21ea (en: 'upwards white arrow from bar') - - "⇫": [t: "mũi tên màu trắng lên trên bệ"] # 0x21eb (en: 'upwards white arrow on pedestal') - - "⇬": [t: "mũi tên màu trắng lên trên bệ với thanh ngang"] # 0x21ec (en: 'upwards white arrow on pedestal with horizontal bar') - - "⇭": [t: "mũi tên màu trắng lên trên bệ với thanh dọc"] # 0x21ed (en: 'upwards white arrow on pedestal with vertical bar') - - "⇮": [t: "mũi tên đôi màu trắng"] # 0x21ee (en: 'upwards white double arrow') - - "⇯": [t: "mũi tên đôi màu trắng lên trên bệ"] # 0x21ef (en: 'upwards white double arrow on pedestal') - - "⇰": [t: "mũi tên trắng bên phải từ tường"] # 0x21f0 (en: 'rightwards white arrow from wall') - - "⇱": [t: "mũi tên tây bắc đến góc"] # 0x21f1 (en: 'north west arrow to corner') - - "⇲": [t: "mũi phía đông mũi tên đến góc"] # 0x21f2 (en: 'south east arrow to corner') - - "⇳": [t: "lên mũi tên trắng"] # 0x21f3 (en: 'up down white arrow') - - "⇴": [t: "mũi tên phải với vòng tròn nhỏ"] # 0x21f4 (en: 'right arrow with small circle') - - "⇵": [t: "mũi tên xuống bên trái của mũi tên hướng lên"] # 0x21f5 (en: 'downwards arrow leftwards of upwards arrow') - - "⇶": [t: "ba mũi tên phải"] # 0x21f6 (en: 'three rightwards arrows') - - "⇷": [t: "mũi tên trái với gạch dọc"] # 0x21f7 (en: 'leftwards arrow with vertical stroke') - - "⇸": [t: "mũi tên phải với gạch dọc"] # 0x21f8 (en: 'rightwards arrow with vertical stroke') - - "⇹": [t: "mũi tên trái bên trái với gạch dọc"] # 0x21f9 (en: 'left right arrow with vertical stroke') - - "⇺": [t: "mũi tên trái với gạch dọc"] # 0x21fa (en: 'leftwards arrow with double vertical stroke') - - "⇻": [t: "mũi tên phải với gạch dọc"] # 0x21fb (en: 'rightwards arrow with double vertical stroke') - - "⇼": [t: "mũi tên trái bên trái với gạch dọc"] # 0x21fc (en: 'left right arrow with double vertical stroke') - - "⇽": [t: "mũi tên mở bên trái"] # 0x21fd (en: 'leftwards open headed arrow') - - "⇾": [t: "mũi tên mở bên phải"] # 0x21fe (en: 'rightwards open headed arrow') - - "⇿": [t: "bên trái mũi tên mở đầu"] # 0x21ff (en: 'left right open headed arrow') - - "∁": # 0x2201 - - test: - if: "$Verbosity!='Terse'" - then: [t: "các"] # (en: 'the') - - t: "bổ sung" # (en: 'complement of') - - "∋": [t: "chứa thành viên"] # 0x220b (en: 'contains the member') - - "∌": [t: "không chứa thành viên"] # 0x220c (en: 'does not contain the member') - - "∍": [t: "chứa thành viên"] # 0x220d (en: 'contains the member') - - "∎": [t: "kết thúc bằng chứng"] # 0x220e (en: 'end of proof') - - "∔": [t: "dot plus"] # 0x2214 - - "∕": [T: "chia"] # 0x2215 - - "∖": [t: "hiệu"] # 0x2216 (en: 'set minus') - - "∙": [T: "nhân"] # 0x2219 - - "∛": # 0x221b - - test: - if: "$Verbosity!='Terse'" - then: [t: "các"] # (en: 'the') - - t: "rễ khối của" # (en: 'cube root of') - - "∜": # 0x221c - - test: - if: "$Verbosity!='Terse'" - then: [t: "các"] # (en: 'the') - - t: "gốc thứ tư của" # (en: 'fourth root of') - - "∢": [t: "góc hình cầu"] # 0x2222 (en: 'spherical angle') - - "∯": [t: "tích hợp bề mặt"] # 0x222f (en: 'surface integral') - - "∰": [t: "khối lượng tích phân"] # 0x2230 (en: 'volume integral') - - "∱": [t: "tích hợp theo chiều kim đồng hồ"] # 0x2231 (en: 'clockwise integral') - - "∲": [t: "tích hợp đường viền theo chiều kim đồng hồ"] # 0x2232 (en: 'clockwise contour integral') - - "∳": [t: "tích hợp đường viền ngược chiều kim đồng hồ"] # 0x2233 (en: 'anticlockwise contour integral') - - "∴": [t: "vì thế"] # 0x2234 (en: 'therefore') - - "∵": [t: "tại vì"] # 0x2235 (en: 'because') - - "∸": [t: "chấm trừ"] # 0x2238 (en: 'dot minus') - - "∹": [t: "có dư thừa so với"] # 0x2239 (en: 'has excess compared to') - - "∺": # 0x223a - - test: - if: "$Verbosity!='Terse'" - then: [t: "là thuận lợi về mặt hình học"] # (en: 'is geometrically proportinal to') - - "∻": # 0x223b - - test: - if: "$Verbosity!='Terse'" - then: [t: "là homothetic để"] # (en: 'is homothetic to') - - "≀": [t: "sản phẩm vòng hoa"] # 0x2240 (en: 'wreath product') - - "≁": [t: "không phải tilde"] # 0x2241 (en: 'not tilde') - - "≂": [t: "trừ tilde"] # 0x2242 (en: 'minus tilde') - - "≃": # 0x2243 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là không có triệu chứng bằng"] # (en: 'is asymptotically equal to') - - "≄": # 0x2244 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "không có triệu chứng bằng" # (en: 'not asymptotically equal to') - - "≅": # 0x2245 - - test: - if: "$Verbosity!='Terse'" - then: [t: "xấp xỉ bằng"] # (en: 'is approximately equal to') - - "≆": # 0x2246 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "xấp xỉ nhưng không thực sự bằng" # (en: 'approximately but not actually equal to') - - "≇": # 0x2247 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "không xấp xỉ cũng không thực sự bằng" # (en: 'neither approximately nor actually equal to') - - "≈": # 0x2248 - - test: - if: "$Verbosity!='Terse'" - then: [t: "xấp xỉ"] # (en: 'is almost equal to') - - "≉": # 0x2249 - - test: - if: "$Verbosity!='Terse'" - then: [t: " "] # (en: 'is') - - t: "không gần bằng" # (en: 'not almost equal to') - - "≊": # 0x224a - - test: - if: "$Verbosity!='Terse'" - then: [t: "xấp xỉ hoặc bằng"] # (en: 'is almost equal or equal to') - - "≋": [t: "triple tilde"] # 0x224b - - "≌": [t: "đều bằng"] # 0x224c (en: 'are all equal to') - - "≍": # 0x224d - - test: - if: "$Verbosity!='Terse'" - then: [t: "tương đương với"] # (en: 'is equivalent to') - - "≎": # 0x224e - - test: - if: "$Verbosity!='Terse'" - then: [t: "là tương đương về mặt hình học"] # (en: 'is geometrically equivalent to') - - "≏": # 0x224f - - test: - if: "$Verbosity!='Terse'" - then: [t: "các"] # (en: 'the') - - t: "sự khác biệt giữa" # (en: 'difference between') - - "≐": [t: "tiếp cận giới hạn"] # 0x2250 (en: 'approaches the limit') - - "≑": # 0x2251 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là bằng hình học bằng"] # (en: 'is geometrically equal to') - - "≒": # 0x2252 - - test: - if: "$Verbosity!='Terse'" - then: [t: "xấp xỉ bằng hoặc hình ảnh của"] # (en: 'is approximately equal to or the image of') - - "≓": # 0x2253 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là hình ảnh hoặc xấp xỉ bằng"] # (en: 'is the image of or approximately equal to') - - "≔": [t: "đại tá bằng"] # 0x2254 (en: 'colon equals') - - "≕": [t: "bằng đại tràng"] # 0x2255 (en: 'equals colon') - - "≖": [t: "nhẫn bằng"] # 0x2256 (en: 'ring in equal to') - - "≗": # 0x2257 - - test: - if: "$Verbosity!='Terse'" - then: [t: "xấp xỉ bằng"] # (en: 'is approximately equal to') - - "≘": [t: "tương ứng với"] # 0x2258 (en: 'corresponds to') - - "≙": [t: "ước tính"] # 0x2259 (en: 'estimates') - - "≚": # 0x225a - - test: - if: "$Verbosity!='Terse'" - then: [t: "là tương đương với"] # (en: 'is equiangular to') - - "≛": [t: "ngôi sao bằng"] # 0x225b (en: 'star equals') - - "≜": [t: "đen ta bằng"] # 0x225c (en: 'delta equals') - - "≝": [t: "được xác định là được"] # 0x225d (en: 'is defined to be') - - "≞": # 0x225e - - test: - if: "$Verbosity!='Terse'" - then: [t: "được đo bằng"] # (en: 'is measured by') - - "≟": [t: "có một mối quan hệ không xác định với"] # 0x225f (en: 'has an unknown relationship with') - - "≢": # 0x2262 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "không giống hệt nhau" # (en: 'not identical to') - - "≣": # 0x2263 - - test: - if: "$Verbosity!='Terse'" - then: [t: "hoàn toàn tương đương với"] # (en: 'is strictly equivalent to') - - "≨": # 0x2268 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là ít hơn nhưng không bằng"] # (en: 'is less than but not equal to') - - "≩": # 0x2269 - - test: - if: "$Verbosity!='Terse'" - then: [t: "lớn hơn nhưng không bằng"] # (en: 'is greater than but not equal to') - - "≪": # 0x226a - - test: - if: "$Verbosity!='Terse'" - then: [t: "là ít hơn nhiều"] # (en: 'is much less than') - - "≫": # 0x226b - - test: - if: "$Verbosity!='Terse'" - then: [t: "là lớn hơn nhiều so với"] # (en: 'is much greater than') - - "≬": # 0x226c - - test: - if: "$Verbosity!='Terse'" - then: [t: "ở giữa"] # (en: 'is between') - - "≭": # 0x226d - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "không tương đương với" # (en: 'not equivalent to') - - "≮": # 0x226e - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "không ít hơn" # (en: 'not less than') - - "≯": # 0x226f - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "không lớn hơn" # (en: 'not greater than') - - "≰": # 0x2270 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "không ít hơn cũng không bằng" # (en: 'neither less than nor equal to') - - "≱": # 0x2271 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "không lớn hơn cũng không bằng" # (en: 'neither greater than nor equal to') - - "≲": # 0x2272 - - test: - if: "$Verbosity!='Terse'" - then: [t: "ít hơn hoặc tương đương với"] # (en: 'is less than or equivalent to') - - "≳": # 0x2273 - - test: - if: "$Verbosity!='Terse'" - then: [t: "lớn hơn hoặc tương đương với"] # (en: 'is greater than or equivalent to') - - "≴": # 0x2274 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "không ít hơn cũng không tương đương với" # (en: 'neither less than nor equivalent to') - - "≵": # 0x2275 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "không lớn hơn cũng không tương đương với" # (en: 'neither greater than nor equivalent to') - - "≶": # 0x2276 - - test: - if: "$Verbosity!='Terse'" - then: [t: "nhỏ hơn hoặc lớn hơn"] # (en: 'is less than or greater than') - - "≷": # 0x2277 - - test: - if: "$Verbosity!='Terse'" - then: [t: "lớn hơn hoặc ít hơn"] # (en: 'is greater than or less than') - - "≸": # 0x2278 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "không ít hơn cũng không lớn hơn" # (en: 'neither less than nor greater than') - - "≹": # 0x2279 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "không lớn hơn cũng không ít hơn" # (en: 'neither greater than nor less than') - - "≼": [t: "trước hoặc bằng"] # 0x227c (en: 'precedes or is equal to') - - "≽": [t: "thành công hoặc bằng"] # 0x227d (en: 'succeeds or is equal to') - - "≾": [t: "trước hoặc tương đương với"] # 0x227e (en: 'precedes or is equivalent to') - - "≿": [t: "thành công hoặc tương đương với"] # 0x227f (en: 'succeeds or is equivalent to') - - "⊀": [t: "không đi trước"] # 0x2280 (en: 'does not precede') - - "⊁": [t: "không thành công"] # 0x2281 (en: 'does not succeed') - - "⊈": # 0x2288 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "không phải là một tập hợp con cũng không bằng" # (en: 'neither a subset of nor equal to') - - "⊉": # 0x2289 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "không phải là một siêu sao cũng không bằng" # (en: 'neither a superset of nor equal to') - - "⊊": [t: "tập hợp con không bằng"] # 0x228a (en: 'subset of with not equal to') - - "⊋": [t: "superset của không bằng"] # 0x228b (en: 'superset of with not equal to') - - "⊌": [t: "multiset"] # 0x228c - - "⊍": [t: "nhân đa nhân"] # 0x228d (en: 'multiset multiplication') - - "⊎": [t: "liên minh multiset"] # 0x228e (en: 'multiset union') - - "⊏": [t: "hình ảnh vuông của"] # 0x228f (en: 'square image of') - - "⊐": [t: "bản gốc vuông của"] # 0x2290 (en: 'square original of') - - "⊑": [t: "hình ảnh vuông hoặc bằng"] # 0x2291 (en: 'square image of or equal to') - - "⊒": [t: "bản gốc vuông hoặc bằng"] # 0x2292 (en: 'square original of or equal to') - - "⊓": [t: "square flowase"] # 0x2293 (en: 'square cap') - - "⊔": [t: "cốc vuông"] # 0x2294 (en: 'square cup') - - "⊕": [t: "bao quanh cộng"] # 0x2295 (en: 'circled plus') - - "⊖": [t: "khoanh tròn trừ đi"] # 0x2296 (en: 'circled minus') - - "⊗": [t: "thời gian khoanh tròn"] # 0x2297 (en: 'circled times') - - "⊘": [t: "chia"] # 0x2298 (en: 'circled slash') - - "⊙": [t: "toán tử chấm được khoanh tròn"] # 0x2299 (en: 'circled dot operator') - - "⊚": [t: "vòng tròn"] # 0x229a (en: 'circled ring') - - "⊛": [t: "asterisk bao quanh"] # 0x229b (en: 'circled asterisk') - - "⊜": [t: "được khoanh tròn bằng"] # 0x229c (en: 'circled equals') - - "⊝": [t: "dash được khoanh tròn"] # 0x229d (en: 'circled dash') - - "⊞": [t: "bình phương cộng"] # 0x229e (en: 'squared plus') - - "⊟": [t: "bình phương trừ"] # 0x229f (en: 'squared minus') - - "⊠": [t: "thời gian bình phương"] # 0x22a0 (en: 'squared times') - - "⊡": [t: "toán tử dot squared"] # 0x22a1 (en: 'squared dot operator') - - "⊢": [t: "chứng minh"] # 0x22a2 (en: 'proves') - - "⊣": [t: "không mang lại"] # 0x22a3 (en: 'does not yield') - - "⊤": [t: "đứng đầu"] # 0x22a4 (en: 'top') - - "⊥": # 0x22a5 - - test: - if: "$Verbosity!='Terse'" - then: [t: "đáy"] # (en: 'is bottom') - - "⊦": [t: "giảm xuống"] # 0x22a6 (en: 'reduces to') - - "⊧": [t: "mô hình"] # 0x22a7 (en: 'models') - - "⊨": # 0x22a8 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "đúng vậy" # (en: 'true') - - "⊩": [t: "lực lượng"] # 0x22a9 (en: 'forces') - - "⊪": [t: "thanh ba thẳng đứng phía bên phải"] # 0x22aa (en: 'triple vertical bar right turnstile') - - "⊫": [t: "thanh dọc theo kép rẽ phải"] # 0x22ab (en: 'double vertical bar double right turnstile') - - "⊬": [t: "không chứng minh"] # 0x22ac (en: 'does not prove') - - "⊭": # 0x22ad - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "không đúng" # (en: 'not true') - - "⊮": [t: "không ép buộc"] # 0x22ae (en: 'does not force') - - "⊯": [t: "thanh dọc được phủ định đôi bên phải turnstile"] # 0x22af (en: 'negated double vertical bar double right turnstile') - - "⊰": [t: "trước mối quan hệ"] # 0x22b0 (en: 'precedes under relation') - - "⊱": [t: "thành công dưới sự quan hệ"] # 0x22b1 (en: 'succeeds under relation') - - "⊲": # 0x22b2 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "một nhóm con bình thường của" # (en: 'a normal subgroup of') - - "⊳": [t: "chứa như một nhóm con bình thường"] # 0x22b3 (en: 'contains as a normal subgroup') - - "⊴": # 0x22b4 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "một nhóm con bình thường hoặc bằng" # (en: 'a normal subgroup of or equal to') - - "⊵": [t: "chứa một nhóm con bình thường hoặc bằng"] # 0x22b5 (en: 'contains as a normal subgroup or equal to') - - "⊶": # 0x22b6 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "bản gốc của" # (en: 'the original of') - - "⊷": # 0x22b7 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "một hình ảnh của" # (en: 'an image of') - - "⊸": [t: "multimap"] # 0x22b8 - - "⊹": [t: "ma trận liên hợp hermitian"] # 0x22b9 (en: 'hermitian conjugate matrix') - - "⊺": [t: "xen kẽ"] # 0x22ba (en: 'intercalate') - - "⊻": [t: "xor"] # 0x22bb - - "⊼": [t: "nand"] # 0x22bc - - "⊽": [t: "cũng không"] # 0x22bd (en: 'nor') - - "⊾": [t: "góc vuông với hồ quang"] # 0x22be (en: 'right angle with arc') - - "⊿": [t: "tam giác vuông"] # 0x22bf (en: 'right triangle') - - "⋀": [t: "hợp lý và"] # 0x22c0 (en: 'logical and') - - "⋁": [t: "hợp lý hoặc"] # 0x22c1 (en: 'logical or') - - "⋂": [t: "ngã tư"] # 0x22c2 (en: 'intersection') - - "⋃": [t: "liên hiệp"] # 0x22c3 (en: 'union') - - "⋄": [t: "người vận hành kim cương"] # 0x22c4 (en: 'diamond operator') - - "⋅": [T: "nhân"] # 0x22c5 - - "⋆": [T: "nhân"] # 0x22c6 - - "⋇": [T: "nhân chia"] # 0x22c7 (en: 'division times') - - "⋈": [t: "bowtie"] # 0x22c8 - - "⋉": # 0x22c9 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "các yếu tố bình thường bên trái sản phẩm của" # (en: 'the left normal factor semidirect product of') - - "⋊": # 0x22ca - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "các yếu tố bình thường đúng sản phẩm của" # (en: 'the right normal factor semidirect product of') - - "⋋": # 0x22cb - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "sản phẩm bán kết trái của" # (en: 'the left semidirect product of') - - "⋌": # 0x22cc - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "sản phẩm bán kết đúng của" # (en: 'the right semidirect product of') - - "⋍": [t: "tilde đảo ngược bằng"] # 0x22cd (en: 'reversed tilde equals') - - "⋎": [t: "xoăn logic hoặc"] # 0x22ce (en: 'curly logical or') - - "⋏": [t: "xoăn logic và"] # 0x22cf (en: 'curly logical and') - - "⋐": # 0x22d0 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "một tập hợp con kép của" # (en: 'a double subset of') - - "⋑": # 0x22d1 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "một siêu siêu nhân của" # (en: 'a double superset of') - - "⋒": # 0x22d2 - - test: - if: "$Verbosity!='Terse'" - then: [t: "các"] # (en: 'the') - - t: "giao lộ kép của" # (en: 'double intersection of') - - "⋓": # 0x22d3 - - test: - if: "$Verbosity!='Terse'" - then: [t: "các"] # (en: 'the') - - t: "liên minh kép của" # (en: 'double union of') - - "⋔": # 0x22d4 - - test: - if: "$Verbosity!='Terse'" - then: [t: "các"] # (en: 'the') - - t: "giao lộ thích hợp của" # (en: 'proper intersection of') - - "⋕": # 0x22d5 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "bằng và song song với" # (en: 'equal to and parallel to') - - "⋖": [t: "ít hơn với dấu chấm"] # 0x22d6 (en: 'less than with dot') - - "⋗": [t: "lớn hơn với dấu chấm"] # 0x22d7 (en: 'greater than with dot') - - "⋘": # 0x22d8 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "rất ít hơn nhiều" # (en: 'very much less than') - - "⋙": # 0x22d9 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "rất lớn hơn nhiều so với" # (en: 'very much greater than') - - "⋚": # 0x22da - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "ít hơn bằng hoặc lớn hơn" # (en: 'less than equal to or greater than') - - "⋛": # 0x22db - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "lớn hơn bằng hoặc nhỏ hơn" # (en: 'greater than equal to or less than') - - "⋜": # 0x22dc - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "bằng hoặc nhỏ hơn" # (en: 'equal to or less than') - - "⋝": # 0x22dd - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "bằng hoặc lớn hơn" # (en: 'equal to or greater than') - - "⋞": # 0x22de - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "bằng hoặc trước" # (en: 'equal to or precedes') - - "⋟": # 0x22df - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "bằng hoặc thành công" # (en: 'equal to or succeeds') - - "⋠": [t: "không đi trước cũng như không bằng"] # 0x22e0 (en: 'does not precede nor is equal to') - - "⋡": [t: "không thành công cũng như không bằng"] # 0x22e1 (en: 'does not succeed nor is equal to') - - "⋢": [t: "không phải hình ảnh vuông hoặc bằng"] # 0x22e2 (en: 'not square image of or equal to') - - "⋣": [t: "không phải bản gốc vuông hoặc bằng"] # 0x22e3 (en: 'not square original of or equal to') - - "⋤": [t: "hình ảnh vuông hoặc không bằng"] # 0x22e4 (en: 'square image of or not equal to') - - "⋥": [t: "bản gốc vuông hoặc không bằng"] # 0x22e5 (en: 'square original of or not equal to') - - "⋦": # 0x22e6 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "ít hơn nhưng không tương đương với" # (en: 'less than but not equivalent to') - - "⋧": # 0x22e7 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "lớn hơn nhưng không tương đương với" # (en: 'greater than but not equivalent to') - - "⋨": [t: "đi trước nhưng không tương đương với"] # 0x22e8 (en: 'precedes but is not equivalent to') - - "⋩": [t: "thành công nhưng không tương đương với"] # 0x22e9 (en: 'succeeds but is not equivalent to') - - "⋪": # 0x22ea - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "không phải là một nhóm con bình thường của" # (en: 'not a normal subgroup of') - - "⋫": [t: "không chứa như một nhóm con bình thường"] # 0x22eb (en: 'does not contain as a normal subgroup') - - "⋬": # 0x22ec - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "không phải là một nhóm con bình thường cũng không bằng" # (en: 'not a normal subgroup of nor is equal to') - - "⋭": [t: "không chứa như một nhóm con bình thường cũng như không bằng"] # 0x22ed (en: 'does not contain as a normal subgroup nor is equal to') - - "⋮": [T: "chia hết cho"] # 0x22ee (en: 'vertical ellipsis') - - "⋯": [t: "chấm chấm chấm"] # 0x22ef (en: 'dot dot dot') - - "⋰": [t: "elip chéo lên trên"] # 0x22f0 (en: 'upwards diagonal ellipsis') - - "⋱": [t: "dấu chấm lửng chéo"] # 0x22f1 (en: 'diagonal ellipsis') - - "⋲": [t: "yếu tố của với gạch ngang dài"] # 0x22f2 (en: 'element of with long horizontal stroke') - - "⋳": [t: "yếu tố của thanh dọc ở cuối gạch ngang"] # 0x22f3 (en: 'element of with vertical bar at end of horizontal stroke') - - "⋴": [t: "yếu tố của thanh dọc ở cuối gạch ngang"] # 0x22f4 (en: 'element of with vertical bar at end of horizontal stroke') - - "⋵": [t: "phần tử của với dấu chấm ở trên"] # 0x22f5 (en: 'element of with dot above') - - "⋶": [t: "yếu tố của với overbar"] # 0x22f6 (en: 'element of with overbar') - - "⋷": [t: "yếu tố của với overbar"] # 0x22f7 (en: 'element of with overbar') - - "⋸": [t: "yếu tố của với atarbar"] # 0x22f8 (en: 'element of with underbar') - - "⋹": [t: "yếu tố của hai nét ngang"] # 0x22f9 (en: 'element of with two horizontal strokes') - - "⋺": [t: "chứa với gạch ngang dài"] # 0x22fa (en: 'contains with long horizontal stroke') - - "⋻": [t: "chứa với thanh dọc ở cuối gạch ngang"] # 0x22fb (en: 'contains with vertical bar at end of horizontal stroke') - - "⋼": [t: "chứa với thanh dọc ở cuối gạch ngang"] # 0x22fc (en: 'contains with vertical bar at end of horizontal stroke') - - "⋽": [t: "chứa với overbar"] # 0x22fd (en: 'contains with overbar') - - "⋾": [t: "chứa với overbar"] # 0x22fe (en: 'contains with overbar') - - "⋿": [t: "z ký hiệu thành viên túi"] # 0x22ff (en: 'z notation bag membership') - - "⌀": [t: "đường kính"] # 0x2300 (en: 'diameter') - - "⌁": [t: "mũi tên điện"] # 0x2301 (en: 'electric arrow') - - "⌂": [t: "nhà ở"] # 0x2302 (en: 'house') - - "⌃": [t: "lên đầu mũi tên"] # 0x2303 (en: 'up arrowhead') - - "⌄": [t: "xuống đầu mũi tên"] # 0x2304 (en: 'down arrowhead') - - "⌅": [t: "phóng chiếu"] # 0x2305 (en: 'projective') - - "⌆": [t: "luật xa gần"] # 0x2306 (en: 'perspective') - - "⌇": [t: "đường lượn sóng"] # 0x2307 (en: 'wavy line') - - "⌈": [t: "trần trái"] # 0x2308 (en: 'left ceiling') - - "⌉": [t: "trần phải"] # 0x2309 (en: 'right ceiling') - - "⌊": [t: "tầng trái"] # 0x230a (en: 'left floor') - - "⌋": [t: "tầng phải"] # 0x230b (en: 'right floor') - - "⌌": [t: "đáy bên phải"] # 0x230c (en: 'bottom right crop') - - "⌍": [t: "cây trồng phía dưới bên trái"] # 0x230d (en: 'bottom left crop') - - "⌎": [t: "cây trồng trên cùng bên phải"] # 0x230e (en: 'top right crop') - - "⌏": [t: "cây trồng trên cùng bên trái"] # 0x230f (en: 'top left crop') - - "⌐": [t: "đảo ngược không ký"] # 0x2310 (en: 'reversed not sign') - - "⌑": [t: "hình vuông"] # 0x2311 (en: 'square lozenge') - - "⌒": [t: "cung"] # 0x2312 (en: 'arc') - - "⌓": [t: "bộ phận"] # 0x2313 (en: 'segment') - - "⌔": [t: "khu vực"] # 0x2314 (en: 'sector') - - "⌕": [t: "máy ghi âm điện thoại"] # 0x2315 (en: 'telephone recorder') - - "⌖": [t: "chỉ số vị trí crosshairs"] # 0x2316 (en: 'position indicator crosshairs') - - "⌗": [t: "quảng trường viewdata"] # 0x2317 (en: 'viewdata square') - - "⌘": [t: "nơi có dấu hiệu quan tâm"] # 0x2318 (en: 'place of interest sign') - - "⌙": [t: "biến không ký"] # 0x2319 (en: 'turned not sign') - - "⌚": [t: "đồng hồ"] # 0x231a (en: 'watch') - - "⌛": [t: "đồng hồ cát"] # 0x231b (en: 'hourglass') - - "⌜": [t: "góc trên bên trái"] # 0x231c (en: 'top left corner') - - "⌝": [t: "góc trên bên phải"] # 0x231d (en: 'top right corner') - - "⌞": [t: "góc dưới bên trái"] # 0x231e (en: 'bottom left corner') - - "⌟": [t: "góc dưới bên phải"] # 0x231f (en: 'bottom right corner') - - "⌠": [t: "nửa đầu tích phân"] # 0x2320 (en: 'top half integral') - - "⌡": [t: "nửa dưới tích phân"] # 0x2321 (en: 'bottom half integral') - - "⌢": [t: "nhăn mặt"] # 0x2322 (en: 'frown') - - "⌣": [t: "nụ cười"] # 0x2323 (en: 'smile') - - "⌤": [t: "lên đầu mũi tên giữa hai thanh ngang"] # 0x2324 (en: 'up arrowhead between two horizontal bars') - - "⌥": [t: "khóa tùy chọn"] # 0x2325 (en: 'option key') - - "⌦": [t: "xóa sang phải"] # 0x2326 (en: 'erase to the right') - - "⌧": [t: "x trong một hộp hình chữ nhật"] # 0x2327 (en: 'x in a rectangle box') - - "⌨": [t: "bàn phím"] # 0x2328 (en: 'keyboard') - - "〈": [t: "bên trái chỉ khung góc"] # 0x2329 (en: 'left pointing angle bracket') - - "〉": [t: "bên phải góc khung"] # 0x232a (en: 'right pointing angle bracket') - - "⌫": [t: "xóa sang trái"] # 0x232b (en: 'erase to the left') - - "⌬": [t: "vòng benzen"] # 0x232c (en: 'benzene ring') - - "⌭": [t: "hình trụ"] # 0x232d (en: 'cylindricity') - - "⌮": [t: "tất cả xung quanh hồ sơ"] # 0x232e (en: 'all around profile') - - "⌯": [t: "đối diện"] # 0x232f (en: 'symmetry') - - "⌰": [t: "tổng số chạy"] # 0x2330 (en: 'total runout') - - "⌱": [t: "nguồn gốc kích thước"] # 0x2331 (en: 'dimension origin') - - "⌲": [t: "hình nón côn"] # 0x2332 (en: 'conical taper') - - "⌳": [t: "dốc"] # 0x2333 (en: 'slope') - - "⌴": [t: "đối trọng"] # 0x2334 (en: 'counterbore') - - "⌵": [t: "cấm"] # 0x2335 (en: 'countersink') - - "⍰": [t: "hộp không xác định"] # 0x2370 (en: 'unknown box') - - "⎕": [t: "hộp"] # 0x2395 (en: 'box') - - "⏜": [t: "cung"] # 0x23DC (en: 'top paren') - - "⏞": [t: "nẹp trên cùng"] # 0x23DE (en: 'top brace') - - "⏟": [t: "niềng răng dưới cùng"] # 0x23DF (en: 'bottom brace') - - "①-⑨": # 0x2460 - 0x2469 - - t: "khoanh tròn" # (en: 'circled') - - spell: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" - - "⑩": [t: "bao quanh mười"] # 0x2469 (en: 'circled ten') - - "⑪": [t: "vòng mười một"] # 0x246a (en: 'circled eleven') - - "⑫": [t: "bao quanh mười hai"] # 0x246b (en: 'circled twelve') - - "⑬": [t: "bao quanh mười ba"] # 0x246c (en: 'circled thirteen') - - "⑭": [t: "vòng mười bốn"] # 0x246d (en: 'circled fourteen') - - "⑮": [t: "bao quanh mười lăm"] # 0x246e (en: 'circled fifteen') - - "⑯": [t: "vòng mười sáu"] # 0x246f (en: 'circled sixteen') - - "⑰": [t: "vòng mười bảy"] # 0x2470 (en: 'circled seventeen') - - "⑱": [t: "khoanh tròn ateen"] # 0x2471 (en: 'circled eighteen') - - "⑱": [t: "vòng mười chín"] # 0x2471 (en: 'circled nineteen') - - "⑳": [t: "bao quanh hai mươi"] # 0x2473 (en: 'circled twenty') - - "⑴-⑼": # 0x2474 - 0x247d - - t: "dấu ngoặc đơn" # (en: 'parenthesized') - - spell: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" - - "⑽": [t: "dấu ngoặc đơn mười"] # 0x247d (en: 'parenthesized ten') - - "⑾": [t: "dấu ngoặc đơn mười một"] # 0x247e (en: 'parenthesized eleven') - - "⑿": [t: "dấu ngoặc đơn mười hai"] # 0x247f (en: 'parenthesized twelve') - - "⒀": [t: "ngoặc đơn mười ba"] # 0x2480 (en: 'parenthesized thirteen') - - "⒁": [t: "dấu ngoặc đơn mười bốn"] # 0x2481 (en: 'parenthesized fourteen') - - "⒂": [t: "dấu ngoặc đơn mười lăm"] # 0x2482 (en: 'parenthesized fifteen') - - "⒃": [t: "dấu ngoặc đơn mười sáu"] # 0x2483 (en: 'parenthesized sixteen') - - "⒄": [t: "dấu ngoặc đơn mười bảy"] # 0x2484 (en: 'parenthesized seventeen') - - "⒅": [t: "dấu ngoặc đơn ateen"] # 0x2485 (en: 'parenthesized eighteen') - - "⒆": [t: "dấu ngoặc đơn mười chín"] # 0x2486 (en: 'parenthesized nineteen') - - "⒇": [t: "ngoặc đơn hai mươi"] # 0x2487 (en: 'parenthesized twenty') - - "⒈-⒐": # 0x2488 - 0x2491 - - spell: "translate('.', '⒈⒉⒊⒋⒌⒍⒎⒏⒐', '123456789')" - - t: "với thời gian" # (en: 'with period') - - "⒑": [t: "mười với thời gian"] # 0x2491 (en: 'ten with period') - - "⒒": [t: "mười một với thời gian"] # 0x2492 (en: 'eleven with period') - - "⒓": [t: "mười hai với thời gian"] # 0x2493 (en: 'twelve with period') - - "⒔": [t: "mười ba với thời gian"] # 0x2494 (en: 'thirteen with period') - - "⒕": [t: "mười bốn với thời gian"] # 0x2495 (en: 'fourteen with period') - - "⒖": [t: "mười lăm với thời gian"] # 0x2496 (en: 'fifteen with period') - - "⒗": [t: "mười sáu thời gian"] # 0x2497 (en: 'sixteen with period') - - "⒘": [t: "mười bảy với thời gian"] # 0x2498 (en: 'seventeen with period') - - "⒙": [t: "ateen có thời gian"] # 0x2499 (en: 'eighteen with period') - - "⒚": [t: "mười chín với thời gian"] # 0x249a (en: 'nineteen with period') - - "⒛": [t: "hai mươi với thời gian"] # 0x249b (en: 'twenty with period') - - "⒜-⒵": # 0x249c - 0x24b5 - - t: "dấu ngoặc đơn" # (en: 'parenthesized') - - spell: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" - - - "Ⓐ-Ⓩ": - - t: "khoanh tròn" # (en: 'circled') - - spell: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "🅐-🅩": # 0x1f150 - 0x1f169 - - t: "khoanh tròn đen" # (en: 'black circled') - - spell: "translate('.', '🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 - - t: "khoanh tròn" # (en: 'circled') - - spell: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" - - "⓪": [t: "vòng tròn số không"] # 0x24ea (en: 'circled zero') - - "⓫": [t: "màu đen vòng mười một"] # 0x24eb (en: 'black circled eleven') - - "⓬": [t: "mười hai vòng màu đen"] # 0x24ec (en: 'black circled twelve') - - "⓭": [t: "mười ba vòng màu đen"] # 0x24ed (en: 'black circled thirteen') - - "⓮": [t: "mười bốn vòng màu đen"] # 0x24ee (en: 'black circled fourteen') - - "⓯": [t: "mười lăm vòng màu đen"] # 0x24ef (en: 'black circled fifteen') - - "⓰": [t: "mười sáu vòng màu đen"] # 0x24f0 (en: 'black circled sixteen') - - "⓱": [t: "mười bảy vòng màu đen"] # 0x24f1 (en: 'black circled seventeen') - - "⓲": [t: "màu đen khoanh tròn ateen"] # 0x24f2 (en: 'black circled eighteen') - - "⓳": [t: "mười chín vòng màu đen"] # 0x24f3 (en: 'black circled nineteen') - - "⓴": [t: "đen vòng hai mươi"] # 0x24f4 (en: 'black circled twenty') - - "⓵-⓽": # 0x24f5 - 0x24fe - - t: "gấp đôi khoanh tròn" # (en: 'double circled') - - spell: "translate('.', '⓵⓶⓷⓸⓹⓺⓻⓼⓽', '123456789')" - - "⓾": [t: "gấp đôi vòng mười"] # 0x24fe (en: 'double circled ten') - - "⓿": [t: "màu đen vòng không"] # 0x24ff (en: 'black circled zero') - - "■": [t: "quảng trường đen"] # 0x25a0 (en: 'black square') - - "□": [t: "quảng trường trắng"] # 0x25a1 (en: 'white square') - - "▢": [t: "quảng trường trắng với các góc tròn"] # 0x25a2 (en: 'white square with rounded corners') - - "▣": [t: "quảng trường trắng chứa hình vuông nhỏ màu đen"] # 0x25a3 (en: 'white square containing small black square') - - "▤": [t: "hình vuông với lấp đầy ngang"] # 0x25a4 (en: 'square with horizontal fill') - - "▥": [t: "hình vuông với điền vào đỉnh"] # 0x25a5 (en: 'square with verticle fill') - - "▦": [t: "hình vuông với lấp đầy hình chữ thập trực giao"] # 0x25a6 (en: 'square with orthogonal crosshatch fill') - - "▧": [t: "hình vuông với phần trên bên trái đến dưới bên phải"] # 0x25a7 (en: 'square with upper left to lower right fill') - - "▨": [t: "hình vuông với phần trên bên phải đến thấp hơn bên trái"] # 0x25a8 (en: 'square with upper right to lower left fill') - - "▩": [t: "hình vuông với hình chữ thập chéo"] # 0x25a9 (en: 'square with diagonal crosshatch fill') - - "▪": [t: "quảng trường nhỏ màu đen"] # 0x25aa (en: 'black small square') - - "▫": [t: "quảng trường nhỏ màu trắng"] # 0x25ab (en: 'white small square') - - "▬": [t: "hình chữ nhật màu đen"] # 0x25ac (en: 'black rectangle') - - "▭": [t: "hình chữ nhật màu trắng"] # 0x25ad (en: 'white rectangle') - - "▮": [t: "hình chữ nhật thẳng đứng màu đen"] # 0x25ae (en: 'black vertical rectangle') - - "▯": [t: "hình chữ nhật thẳng đứng màu trắng"] # 0x25af (en: 'white vertical rectangle') - - "▰": [t: "hình bình hành đen"] # 0x25b0 (en: 'black parallelogram') - - "▱": [t: "hình bình hành"] # 0x25b1 (en: 'white parallelogram') - - "▲": [t: "màu đen lên tam giác"] # 0x25b2 (en: 'black up pointing triangle') - - "△": [t: "tam giác"] # 0x25b3 (en: 'white up pointing triangle') - - "▴": [t: "màu đen lên hình tam giác nhỏ"] # 0x25b4 (en: 'black up pointing small triangle') - - "▵": [t: "trắng lên hình tam giác nhỏ"] # 0x25b5 (en: 'white up pointing small triangle') - - "▶": [t: "triangle chân phải màu đen"] # 0x25b6 (en: 'black right pointing triangle') - - "▷": [t: "trắng phải hình tam giác"] # 0x25b7 (en: 'white right pointing triangle') - - "▸": [t: "đen phải chỉ hình tam giác nhỏ"] # 0x25b8 (en: 'black right pointing small triangle') - - "▹": [t: "trắng phải chỉ hình tam giác nhỏ"] # 0x25b9 (en: 'white right pointing small triangle') - - "►": [t: "đen bên phải trỏ trỏ"] # 0x25ba (en: 'black right pointing pointer') - - "▻": [t: "trao màu trắng trỏ"] # 0x25bb (en: 'white right pointing pointer') - - "▼": [t: "màu đen xuống hình tam giác"] # 0x25bc (en: 'black down pointing triangle') - - "▽": [t: "trắng xuống hình tam giác"] # 0x25bd (en: 'white down pointing triangle') - - "▾": [t: "đen xuống chỉ hình tam giác nhỏ"] # 0x25be (en: 'black down pointing small triangle') - - "▿": [t: "trắng xuống chỉ hình tam giác nhỏ"] # 0x25bf (en: 'white down pointing small triangle') - - "◀": [t: "tam giác phía bên trái màu đen"] # 0x25c0 (en: 'black left pointing triangle') - - "◁": [t: "trắng bên trái hình tam giác"] # 0x25c1 (en: 'white left pointing triangle') - - "◂": [t: "đen bên trái trỏ tam giác nhỏ"] # 0x25c2 (en: 'black left pointing small triangle') - - "◃": [t: "trắng bên trái trỏ tam giác nhỏ"] # 0x25c3 (en: 'white left pointing small triangle') - - "◄": [t: "đen bên trái trỏ trỏ"] # 0x25c4 (en: 'black left pointing pointer') - - "◅": [t: "trao màu trắng trỏ"] # 0x25c5 (en: 'white left pointing pointer') - - "◆": [t: "kim cương đen"] # 0x25c6 (en: 'black diamond') - - "◇": [t: "kim cương trắng"] # 0x25c7 (en: 'white diamond') - - "◈": [t: "kim cương trắng chứa kim cương nhỏ màu đen"] # 0x25c8 (en: 'white diamond containing black small diamond') - - "◉": [t: "cá"] # 0x25c9 (en: 'fisheye') - - "◊": [t: "hình thoi"] # 0x25ca (en: 'lozenge') - - "○": [t: "vòng tròn màu trắng"] # 0x25cb (en: 'white circle') - - "◌": [t: "vòng tròn chấm"] # 0x25cc (en: 'dotted circle') - - "◍": [t: "vòng tròn với điền dọc"] # 0x25cd (en: 'circle with vertical fill') - - "◎": [t: "bullseye"] # 0x25ce - - "●": [t: "vòng tròn màu đen"] # 0x25cf (en: 'black circle') - - "◐": [t: "vòng tròn với nửa màu đen"] # 0x25d0 (en: 'circle with left half black') - - "◑": [t: "vòng tròn với nửa màu đen bên phải"] # 0x25d1 (en: 'circle with right half black') - - "◒": [t: "vòng tròn với nửa màu đen"] # 0x25d2 (en: 'circle with lower half black') - - "◓": [t: "vòng tròn với nửa màu đen"] # 0x25d3 (en: 'circle with upper half black') - - "◔": [t: "vòng tròn với phần tư phía trên bên phải màu đen"] # 0x25d4 (en: 'circle with upper right quadrant black') - - "◕": [t: "vòng tròn với tất cả trừ phần tư phía trên bên trái màu đen"] # 0x25d5 (en: 'circle with all but upper left quadrant black') - - "◖": [t: "một nửa vòng tròn màu đen"] # 0x25d6 (en: 'left half black circle') - - "◗": [t: "một nửa vòng tròn màu đen"] # 0x25d7 (en: 'right half black circle') - - "◘": [t: "bullet nghịch đảo"] # 0x25d8 (en: 'inverse bullet') - - "◙": [t: "vòng tròn trắng nghịch đảo"] # 0x25d9 (en: 'inverse white circle') - - "◚": [t: "vòng tròn màu trắng nghịch đảo trên"] # 0x25da (en: 'upper half inverse white circle') - - "◛": [t: "vòng tròn trắng nửa dưới"] # 0x25db (en: 'lower half inverse white circle') - - "◜": [t: "vòng cung vòng tròn phía trên bên trái"] # 0x25dc (en: 'upper left quadrant circular arc') - - "◝": [t: "vòng cung tròn góc phần tư phía trên bên phải"] # 0x25dd (en: 'upper right quadrant circular arc') - - "◞": [t: "hồ quang hình tròn góc phần tư dưới bên phải"] # 0x25de (en: 'lower right quadrant circular arc') - - "◟": [t: "vòng cung tròn góc dưới bên trái"] # 0x25df (en: 'lower left quadrant circular arc') - - "◠": [t: "vòng tròn trên"] # 0x25e0 (en: 'upper half circle') - - "◡": [t: "vòng tròn thấp hơn"] # 0x25e1 (en: 'lower half circle') - - "◢": [t: "tam giác bên phải màu đen"] # 0x25e2 (en: 'black lower right triangle') - - "◣": [t: "tam giác bên trái màu đen"] # 0x25e3 (en: 'black lower left triangle') - - "◤": [t: "tam giác màu đen bên trái"] # 0x25e4 (en: 'black upper left triangle') - - "◥": [t: "tam giác phía trên bên phải màu đen"] # 0x25e5 (en: 'black upper right triangle') - - "◦": [t: "thành phần"] # 0x25e6 (en: 'composition') - - "◧": [t: "hình vuông với nửa màu đen"] # 0x25e7 (en: 'square with left half black') - - "◨": [t: "hình vuông với nửa màu đen bên phải"] # 0x25e8 (en: 'square with right half black') - - "◩": [t: "hình vuông với nửa màu đen bên trái"] # 0x25e9 (en: 'square with upper left half black') - - "◪": [t: "hình vuông với nửa bên phải màu đen"] # 0x25ea (en: 'square with lower right half black') - - "◫": [t: "quảng trường trắng với đường chia đôi"] # 0x25eb (en: 'white square with bisecting line') - - "◬": [t: "trắng lên tam giác với dấu chấm"] # 0x25ec (en: 'white up pointing triangle with dot') - - "◭": [t: "lên tam giác chỉ với nửa màu đen trái"] # 0x25ed (en: 'up pointing triangle with left half black') - - "◮": [t: "lên tam giác chỉ với nửa màu đen bên phải"] # 0x25ee (en: 'up pointing triangle with right half black') - - "◯": [t: "vòng tròn lớn"] # 0x25ef (en: 'large circle') - - "◰": [t: "quảng trường trắng với góc phần tư phía trên bên trái"] # 0x25f0 (en: 'white square with upper left quadrant') - - "◱": [t: "quảng trường trắng với góc phần tư phía dưới bên trái"] # 0x25f1 (en: 'white square with lower left quadrant') - - "◲": [t: "quảng trường trắng với góc phần tư phía dưới bên phải"] # 0x25f2 (en: 'white square with lower right quadrant') - - "◳": [t: "quảng trường trắng với góc phần tư phía trên bên phải"] # 0x25f3 (en: 'white square with upper right quadrant') - - "◴": [t: "vòng tròn màu trắng với góc phần tư phía trên bên trái"] # 0x25f4 (en: 'white circle with upper left quadrant') - - "◵": [t: "vòng tròn màu trắng với góc phần tư phía dưới bên trái"] # 0x25f5 (en: 'white circle with lower left quadrant') - - "◶": [t: "vòng tròn màu trắng với góc phần tư phía dưới bên phải"] # 0x25f6 (en: 'white circle with lower right quadrant') - - "◷": [t: "vòng tròn màu trắng với góc phần tư phía trên bên phải"] # 0x25f7 (en: 'white circle with upper right quadrant') - - "◸": [t: "tam giác phía trên bên trái"] # 0x25f8 (en: 'upper left triangle') - - "◹": [t: "tam giác phía trên bên phải"] # 0x25f9 (en: 'upper right triangle') - - "◺": [t: "tam giác dưới bên trái"] # 0x25fa (en: 'lower left triangle') - - "◻": [t: "quảng trường trung bình màu trắng"] # 0x25fb (en: 'white medium square') - - "◼": [t: "quảng trường trung bình màu đen"] # 0x25fc (en: 'black medium square') - - "◽": [t: "quảng trường nhỏ vừa"] # 0x25fd (en: 'white medium small square') - - "◾": [t: "quảng trường nhỏ màu đen"] # 0x25fe (en: 'black medium small square') - - "◿": [t: "tam giác dưới bên phải"] # 0x25ff (en: 'lower right triangle') - - "♠": [t: "bộ đồ thuổng đen"] # 0x2660 (en: 'black spade suit') - - "♡": [t: "bộ đồ trái tim trắng"] # 0x2661 (en: 'white heart suit') - - "♢": [t: "bộ đồ kim cương trắng"] # 0x2662 (en: 'white diamond suit') - - "♣": [t: "bộ đồ câu lạc bộ màu đen"] # 0x2663 (en: 'black club suit') - - "♤": [t: "bộ đồ thuổng trắng"] # 0x2664 (en: 'white spade suit') - - "♥": [t: "bộ đồ trái tim đen"] # 0x2665 (en: 'black heart suit') - - "♦": [t: "bộ đồ kim cương đen"] # 0x2666 (en: 'black diamond suit') - - "♧": [t: "bộ đồ câu lạc bộ trắng"] # 0x2667 (en: 'white club suit') - - "❨": [t: "trung bình bên trái dấu ngoặc đơn trang trí"] # 0x2768 (en: 'medium left parentheses ornament') - - "❩": [t: "dấu ngoặc đơn trung bình trang trí"] # 0x2769 (en: 'medium right parentheses ornament') - - "❪": [t: "trung bình phẳng bên trái dấu ngoặc đơn trang trí"] # 0x276a (en: 'medium flattened left parentheses ornament') - - "❫": [t: "trung bình phẳng bên phải trang trí"] # 0x276b (en: 'medium flattened right parentheses ornament') - - "❬": [t: "trung bình bên trái giá trang trí khung góc"] # 0x276c (en: 'medium left-pointing angle bracket ornament') - - "❭": [t: "trung bình bên phải-góc chỉ trang trí"] # 0x276d (en: 'medium right--pointing angle bracked ornament') - - "❮": [t: "độ nặng góc bên trái dấu ngoặc kép trang trí"] # 0x276e (en: 'heavy left-pointing angle quotation mark ornament') - - "❯": [t: "độ nặng góc phải góc trích dẫn trang trí trang trí"] # 0x276f (en: 'heavy right-pointing angle quotation mark ornament') - - "❰": [t: "giá trang trí góc cực lớn bên trái"] # 0x2770 (en: 'heavy left-pointing angle bracket ornament') - - "❱": [t: "giá trang trí góc phải nặng bên phải"] # 0x2771 (en: 'heavy right-pointing angle bracket ornament') - - "❲": [t: "ánh sáng bên trái chân vật trang trí vỏ rùa"] # 0x2772 (en: 'light left tortoise shell bracket ornament') - - "❳": [t: "ánh sáng bên phải vỏ sò trang trí"] # 0x2773 (en: 'light right tortoise shell bracket ornament') - - "❴": [t: "trung bình bên trái trang trí"] # 0x2774 (en: 'medium left brace ornament') - - "❵": [t: "trang trí nẹp trung bình bên phải"] # 0x2775 (en: 'medium right brace ornament') - - "❶": [t: "màu đen khoanh tròn một"] # 0x2776 (en: 'black circled one') - - "❷": [t: "đen vòng hai"] # 0x2777 (en: 'black circled two') - - "❸": [t: "đen vòng ba"] # 0x2778 (en: 'black circled three') - - "❹": [t: "đen vòng bốn"] # 0x2779 (en: 'black circled four') - - "❺": [t: "đen khoanh tròn năm"] # 0x277a (en: 'black circled five') - - "❻": [t: "đen vòng sáu"] # 0x277b (en: 'black circled six') - - "❼": [t: "đen bao quanh bảy"] # 0x277c (en: 'black circled seven') - - "❽": [t: "màu đen khoanh tròn tại"] # 0x277d (en: 'black circled eight') - - "❾": [t: "đen vòng chín"] # 0x277e (en: 'black circled nine') - - "❿": [t: "mười vòng màu đen"] # 0x277f (en: 'black circled ten') - - "➀": [t: "khoanh tròn sans serif một"] # 0x2780 (en: 'circled sans serif one') - - "➁": [t: "bao quanh sans serif hai"] # 0x2781 (en: 'circled sans serif two') - - "➂": [t: "bao quanh sans serif ba"] # 0x2782 (en: 'circled sans serif three') - - "➃": [t: "bao quanh sans serif bốn"] # 0x2783 (en: 'circled sans serif four') - - "➄": [t: "bao quanh sans serif năm"] # 0x2784 (en: 'circled sans serif five') - - "➅": [t: "bao quanh sans serif sáu"] # 0x2785 (en: 'circled sans serif six') - - "➆": [t: "bao quanh sans serif bảy"] # 0x2786 (en: 'circled sans serif seven') - - "➇": [t: "bao quanh sans serif tại"] # 0x2787 (en: 'circled sans serif eight') - - "➈": [t: "bao quanh sans serif chín"] # 0x2788 (en: 'circled sans serif nine') - - "➉": [t: "bao quanh sans serif mười"] # 0x2789 (en: 'circled sans serif ten') - - "➊": [t: "màu đen khoanh tròn sans serif một"] # 0x278a (en: 'black circled sans serif one') - - "➋": [t: "đen khoanh tròn sans serif hai"] # 0x278b (en: 'black circled sans serif two') - - "➌": [t: "đen kho tròn sans serif ba"] # 0x278c (en: 'black circled sans serif three') - - "➍": [t: "đen kho tròn sans serif bốn"] # 0x278d (en: 'black circled sans serif four') - - "➎": [t: "đen kho tròn sans serif năm"] # 0x278e (en: 'black circled sans serif five') - - "➏": [t: "đen kho tròn sans serif sáu"] # 0x278f (en: 'black circled sans serif six') - - "➐": [t: "đen khoanh tròn sans serif seven"] # 0x2790 (en: 'black circled sans serif seven') - - "➑": [t: "màu đen khoanh tròn sans serif tại"] # 0x2791 (en: 'black circled sans serif eight') - - "➒": [t: "đen kho tròn sans serif chín"] # 0x2792 (en: 'black circled sans serif nine') - - "➓": [t: "màu đen khoanh tròn sans serif ten"] # 0x2793 (en: 'black circled sans serif ten') - - "➔": [t: "mũi tên bên phải nặng"] # 0x2794 (en: 'heavy wide-headed rightwards arrow') - - "➕": [t: "dấu hiệu cộng nặng"] # 0x2795 (en: 'heavy plus sign') - - "➖": [t: "dấu hiệu nặng"] # 0x2796 (en: 'heavy minus sign') - - "➗": [t: "dấu hiệu divison nặng"] # 0x2797 (en: 'heavy divison sign') - - "➘": [t: "mũi tên đông nam nặng"] # 0x2798 (en: 'heavy south east arrow') - - "➙": [t: "mũi tên nặng"] # 0x2799 (en: 'heavy rightwards arrow') - - "➚": [t: "mũi tên đông bắc nặng"] # 0x279a (en: 'heavy north east arrow') - - "➛": [t: "bản thảo điểm bên phải mũi tên"] # 0x279b (en: 'drafting point rightwards arrow') - - "➜": [t: "mũi tên tròn nặng"] # 0x279c (en: 'heavy round-tipped rightwards arrow') - - "➝": [t: "mũi tên phải đầu tam giác"] # 0x279d (en: 'triangle-headed rightwards arrow') - - "➞": [t: "mũi tên đầu phải hình tam giác nặng"] # 0x279e (en: 'heavy triangle-headed rightwards arrow') - - "➟": [t: "mũi tên đầu cơ hình tam giác đứt"] # 0x279f (en: 'dashed triangle-headed rightwards arrow') - - "➠": [t: "mũi tên đầu cơ hình tam giác nặng nề"] # 0x27a0 (en: 'heavy dashed triangle-headed rightwards arrow') - - "➡": [t: "mũi tên bên phải màu đen"] # 0x27a1 (en: 'black rightwards arrow') - - "➢": [t: "ba d trên cùng thắp sáng mũi tên bên phải"] # 0x27a2 (en: 'three d top lighted rightwards arrow') - - "➣": [t: "ba d dưới cùng ánh sáng mũi tên bên phải"] # 0x27a3 (en: 'three d bottom lighted rightwards arrow') - - "➤": [t: "mũi tên bên phải màu đen"] # 0x27a4 (en: 'black rightwards arrowhead') - - "➥": [t: "đen nặng cong xuống và mũi tên phải"] # 0x27a5 (en: 'heavy black curved downwards and rightwards arrow') - - "➦": [t: "đen nặng cong lên trên và mũi tên phải"] # 0x27a6 (en: 'heavy black curved upwards and rightwards arrow') - - "➧": [t: "squat màu đen mũi tên bên phải"] # 0x27a7 (en: 'squat black rightwards arrow') - - "➨": [t: "mũi tên bên phải bên lõm nặng"] # 0x27a8 (en: 'heavy concave-pointed black rightwards arrow') - - "➩": [t: "mũi tên bên phải màu trắng bóng phải"] # 0x27a9 (en: 'right-shaded white rightwards arrow') - - "➪": [t: "mũi tên bên phải màu trắng bên trái"] # 0x27aa (en: 'left-shaded white rightwards arrow') - - "➫": [t: "mũi tên bên phải bị nghiêng mặt về phía sau"] # 0x27ab (en: 'back-tilted shadowed white rightwards arrow') - - "➬": [t: "mũi tên bên phải bóng tối nghiêng trước"] # 0x27ac (en: 'front-tilted shadowed white rightwards arrow') - - "➭": [t: "mũi tên bên phải bóng bên phải thấp"] # 0x27ad (en: 'heavy lower right-shadowed white rightwards arrow') - - "➮": [t: "mũi tên bên phải bóng bên phải nặng"] # 0x27ae (en: 'heavy upper right-shadowed white rightwards arrow') - - "➯": [t: "nổi lên mũi tên bên phải bóng phải dưới bên phải"] # 0x27af (en: 'notched lower right-shadowed white rightwards arrow') - - "➱": [t: "nổi bật trên mũi tên bên phải bóng bên phải"] # 0x27b1 (en: 'notched upper right-shadowed white rightwards arrow') - - "➲": [t: "khoanh tròn mũi tên bên phải màu trắng nặng"] # 0x27b2 (en: 'circled heavy white rightwards arrow') - - "➳": [t: "mũi tên bên phải màu trắng"] # 0x27b3 (en: 'white-feathered rightwards arrow') - - "➴": [t: "mũi tên phía đông nam lông đen"] # 0x27b4 (en: 'black-feathered south east arrow') - - "➵": [t: "mũi tên bên phải màu đen"] # 0x27b5 (en: 'black-feathered rightwards arrow') - - "➶": [t: "mũi tên đông bắc lông đen"] # 0x27b6 (en: 'black-feathered north east arrow') - - "➷": [t: "mũi tên đông nam hạng nặng"] # 0x27b7 (en: 'heavy black-feathered south east arrow') - - "➸": [t: "mũi tên bên phải màu đen nặng"] # 0x27b8 (en: 'heavy black-feathered rightwards arrow') - - "➹": [t: "mũi tên đông bắc hạng nặng"] # 0x27b9 (en: 'heavy black-feathered north east arrow') - - "➺": [t: "teradrop-barbed mũi tên phải"] # 0x27ba (en: 'teradrop-barbed rightwards arrow') - - "➻": [t: "mũi tên bên phải nặng"] # 0x27bb (en: 'heavy teardrop-shanked rightwards arrow') - - "➼": [t: "mũi tên đuôi nêm"] # 0x27bc (en: 'wedge-tailed rightwards arrow') - - "➽": [t: "mũi tên bên phải nặng"] # 0x27bd (en: 'heavy wedge-tailed rightwards arrow') - - "➾": [t: "mở mũi tên bên phải"] # 0x27be (en: 'open-outlined rightwards arrow') - - "⟀": [t: "góc ba chiều"] # 0x27c0 (en: 'three dimensional angle') - - "⟁": [t: "tam giác trắng chứa tam giác nhỏ màu trắng"] # 0x27c1 (en: 'white triangle containing small white triangle') - - "⟂": # 0x27c2 - - test: - if: "$Verbosity!='Terse'" - then: [t: "vuông góc với"] # (en: 'is perpendicular to') - - "⟃": # 0x27c3 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "một tập hợp con mở của" # (en: 'an open subset of') - - "⟄": # 0x27c4 - - test: - if: "$Verbosity!='Terse'" - then: [t: "là"] # (en: 'is') - - t: "một siêu sao mở của" # (en: 'an open superset of') - - "⟅": [t: "phân dấu túi hình chữ s"] # 0x27c5 (en: 'left s-shaped bag delimiter') - - "⟆": [t: "phân dấu túi hình chữ s phải"] # 0x27c6 (en: 'right s-shaped bag delimiter') - - "⟇": [t: "hoặc với dấu chấm bên trong"] # 0x27c7 (en: 'or with dot inside') - - "⟈": [t: "đảo ngược solidus preeding tập hợp con"] # 0x27c8 (en: 'reverse solidus preceeding subset') - - "⟉": [t: "superset preceding solidus"] # 0x27c9 (en: 'superset preceeding solidus') - - "⟊": [t: "thanh dọc với gạch ngang"] # 0x27ca (en: 'vertical bar with horizontal stroke') - - "⟋": [t: "đường chéo tăng toán"] # 0x27cb (en: 'mathematical rising diagonal') - - "⟌": [t: "phân chia dài"] # 0x27cc (en: 'long division') - - "⟍": [t: "đường chéo giảm toán"] # 0x27cd (en: 'mathematical falling diagonal') - - "⟎": [t: "bình phương logic và"] # 0x27ce (en: 'squared logical and') - - "⟏": [t: "bình phương logic hoặc"] # 0x27cf (en: 'squared logical or') - - "⟐": [t: "kim cương trắng với chấm giữa"] # 0x27d0 (en: 'white diamond with centered dot') - - "⟑": [t: "và với dấu chấm"] # 0x27d1 (en: 'and with dot') - - "⟒": [t: "yếu tố mở lên trên"] # 0x27d2 (en: 'element of openning upwards') - - "⟓": [t: "góc dưới bên phải với dấu chấm"] # 0x27d3 (en: 'lower right corner with dot') - - "⟔": [t: "góc trên bên trái với dấu chấm"] # 0x27d4 (en: 'upper left corner with dot') - - "⟕": [t: "bên ngoài tham gia"] # 0x27d5 (en: 'left outer join') - - "⟖": [t: "bên ngoài tham gia"] # 0x27d6 (en: 'right outer join') - - "⟗": [t: "tham gia đầy đủ bên ngoài"] # 0x27d7 (en: 'full outer join') - - "⟘": [t: "lớn lên tack"] # 0x27d8 (en: 'large up tack') - - "⟙": [t: "lớn xuống tack"] # 0x27d9 (en: 'large down tack') - - "⟚": [t: "trái và bên phải turnstile"] # 0x27da (en: 'left and right double turnstile') - - "⟛": [t: "bên trái và bên phải"] # 0x27db (en: 'left and right tack') - - "⟜": [t: "multimap trái"] # 0x27dc (en: 'left multimap') - - "⟝": [t: "long phải tack"] # 0x27dd (en: 'long right tack') - - "⟞": [t: "long trái tack"] # 0x27de (en: 'long left tack') - - "⟟": [t: "lên tack với vòng tròn ở trên"] # 0x27df (en: 'up tack with circle above') - - "⟠": [t: "lozenge chia cho quy tắc ngang"] # 0x27e0 (en: 'lozenge divided by horizontal rule') - - "⟡": [t: "kim cương mặt lõm màu trắng"] # 0x27e1 (en: 'white concave sided diamond') - - "⟢": [t: "kim cương mặt lõm màu trắng với tick trái"] # 0x27e2 (en: 'white concave sided diamond with leftwards tick') - - "⟣": [t: "kim cương mặt lõm màu trắng với tick bên phải"] # 0x27e3 (en: 'white concave sided diamond with rightwards tick') - - "⟤": [t: "quảng trường trắng với đánh dấu trái"] # 0x27e4 (en: 'white square with leftwards tick') - - "⟥": [t: "quảng trường trắng với đánh dấu phải"] # 0x27e5 (en: 'white square with rightwards tick') - - "⟦": [t: "khung vuông màu trắng"] # 0x27e6 (en: 'left white square bracket') - - "⟧": [t: "khung vuông trắng bên phải"] # 0x27e7 (en: 'right white square bracket') - - "⟨": [t: "khung góc trái"] # 0x27e8 (en: 'left angle bracket') - - "⟩": [t: "khung góc phải"] # 0x27e9 (en: 'right angle bracket') - - "⟪": [t: "khung góc hai góc"] # 0x27ea (en: 'left double angle bracket') - - "⟫": [t: "khung góc gấp đôi"] # 0x27eb (en: 'right double angle bracket') - - "⟬": [t: "bên trái khung vỏ rùa trắng"] # 0x27ec (en: 'left white tortoise shell bracket') - - "⟭": [t: "bên phải khung vỏ rùa trắng"] # 0x27ed (en: 'right white tortoise shell bracket') - - "⟮": [t: "bên trái phẳng dấu ngoặc đơn"] # 0x27ee (en: 'left flattened parenthesis') - - "⟯": [t: "bên phải phẳng ngoặc đơn"] # 0x27ef (en: 'right flattened parenthesis') - - "⟰": [t: "mũi tên tăng bốn lần"] # 0x27f0 (en: 'upwards quadruple arrow') - - "⟱": [t: "mũi tên bốn lần xuống"] # 0x27f1 (en: 'downwards quadruple arrow') - - "⟲": [t: "mũi tên vòng tròn ngược chiều kim đồng hồ"] # 0x27f2 (en: 'anticlockwise gapped circle arrow') - - "⟳": [t: "mũi tên vòng tròn theo chiều kim đồng hồ"] # 0x27f3 (en: 'clockwise gapped circle arrow') - - "⟴": [t: "mũi tên phải với vòng tròn"] # 0x27f4 (en: 'right arrow with circled plus') - - "⟵": [t: "mũi tên dài trái"] # 0x27f5 (en: 'long leftwards arrow') - - "⟶": [t: "mũi tên dài phải"] # 0x27f6 (en: 'long rightwards arrow') - - "⟷": [t: "mũi tên dài bên trái"] # 0x27f7 (en: 'long left right arrow') - - "⟸": [t: "mũi tên đôi dài trái"] # 0x27f8 (en: 'long leftwards double arrow') - - "⟹": [t: "mũi tên đôi dài phải"] # 0x27f9 (en: 'long rightwards double arrow') - - "⟺": [t: "mũi tên đôi dài trái bên trái"] # 0x27fa (en: 'long left right double arrow') - - "⟻": [t: "mũi tên dài trái từ thanh"] # 0x27fb (en: 'long leftwards arrow from bar') - - "⟼": [t: "mũi tên dài phải từ thanh"] # 0x27fc (en: 'long rightwards arrow from bar') - - "⟽": [t: "mũi tên đôi dài trái từ thanh"] # 0x27fd (en: 'long leftwards double arrow from bar') - - "⟾": [t: "mũi tên dài gấp đôi từ thanh"] # 0x27fe (en: 'long rightwards double arrow from bar') - - "⟿": [t: "mũi tên squiggle dài phải"] # 0x27ff (en: 'long rightwards squiggle arrow') - - "⤀": [t: "phải hai mũi tên hai đầu với gạch thẳng đứng"] # 0x2900 (en: 'rightwards two headed arrow with vertical stroke') - - "⤁": [t: "phải hai mũi tên hai đầu với gạch thẳng đứng"] # 0x2901 (en: 'rightwards two headed arrow with double vertical stroke') - - "⤂": [t: "mũi tên đôi bên trái với gạch dọc"] # 0x2902 (en: 'leftwards double arrow with vertical stroke') - - "⤃": [t: "mũi tên kép phải với gạch dọc"] # 0x2903 (en: 'rightwards double arrow with vertical stroke') - - "⤄": [t: "mũi tên kép bên trái với gạch dọc"] # 0x2904 (en: 'left right double arrow with vertical stroke') - - "⤅": [t: "phải hai mũi tên hai đầu từ thanh"] # 0x2905 (en: 'rightwards two headed arrow from bar') - - "⤆": [t: "mũi tên đôi bên trái từ thanh"] # 0x2906 (en: 'leftwards double arrow from bar') - - "⤇": [t: "mũi tên kép bên phải từ thanh"] # 0x2907 (en: 'rightwards double arrow from bar') - - "⤈": [t: "mũi tên xuống với gạch ngang"] # 0x2908 (en: 'downwards arrow with horizontal stroke') - - "⤉": [t: "mũi tên hướng lên với gạch ngang"] # 0x2909 (en: 'upwards arrow with horizontal stroke') - - "⤊": [t: "mũi tên tăng ba"] # 0x290a (en: 'upwards triple arrow') - - "⤋": [t: "mũi tên ba xuống xuống"] # 0x290b (en: 'downwards triple arrow') - - "⤌": [t: "mũi tên double double bên trái"] # 0x290c (en: 'leftwards double dash arrow') - - "⤍": [t: "mũi tên double double bên phải"] # 0x290d (en: 'rightwards double dash arrow') - - "⤎": [t: "mũi tên ba dash bên trái"] # 0x290e (en: 'leftwards triple dash arrow') - - "⤏": [t: "mũi tên ba bên phải"] # 0x290f (en: 'rightwards triple dash arrow') - - "⤐": [t: "phải hai mũi tên ba đầu"] # 0x2910 (en: 'rightwards two headed triple dash arrow') - - "⤑": [t: "mũi tên phải với thân chấm chấm"] # 0x2911 (en: 'rightwards arrow with dotted stem') - - "⤒": [t: "mũi tên hướng lên đến thanh"] # 0x2912 (en: 'upwards arrow to bar') - - "⤓": [t: "mũi tên xuống thanh"] # 0x2913 (en: 'downwards arrow to bar') - - "⤔": [t: "mũi tên phải với đuôi và gạch dọc"] # 0x2914 (en: 'rightwards arrow with tail and vertical stroke') - - "⤕": [t: "mũi tên phải với đuôi và gạch dọc"] # 0x2915 (en: 'rightwards arrow with tail and double vertical stroke') - - "⤖": [t: "phải hai mũi tên hai đầu với đuôi"] # 0x2916 (en: 'rightwards two headed arrow with tail') - - "⤗": [t: "phải hai mũi tên hai đầu với đuôi với gạch thẳng đứng"] # 0x2917 (en: 'rightwards two headed arrow with tail with vertical stroke') - - "⤘": [t: "phải hai mũi tên hai đầu với đuôi với gạch thẳng đứng"] # 0x2918 (en: 'rightwards two headed arrow with tail with double vertical stroke') - - "⤙": [t: "đuôi mũi tên trái"] # 0x2919 (en: 'leftwards arrow tail') - - "⤚": [t: "đuôi mũi tên phải"] # 0x291a (en: 'rightwards arrow tail') - - "⤛": [t: "đuôi hai mũi tên trái"] # 0x291b (en: 'leftwards double arrow tail') - - "⤜": [t: "đuôi mũi tên kép phải"] # 0x291c (en: 'rightwards double arrow tail') - - "⤝": [t: "mũi tên trái vào kim cương đầy"] # 0x291d (en: 'leftwards arrow to filled diamond') - - "⤞": [t: "mũi tên bên phải vào kim cương đầy"] # 0x291e (en: 'rightwards arrow to filled diamond') - - "⤟": [t: "mũi tên trái từ thanh đến kim cương đầy"] # 0x291f (en: 'leftwards arrow from bar to filled diamond') - - "⤠": [t: "mũi tên bên phải từ thanh đến kim cương đầy"] # 0x2920 (en: 'rightwards arrow from bar to filled diamond') - - "⤡": [t: "mũi tên tây bắc và đông nam"] # 0x2921 (en: 'north west and south east arrow') - - "⤢": [t: "mũi tên đông bắc và tây nam"] # 0x2922 (en: 'north east and south west arrow') - - "⤣": [t: "mũi tên tây bắc với móc"] # 0x2923 (en: 'north west arrow with hook') - - "⤤": [t: "mũi tên đông bắc với móc"] # 0x2924 (en: 'north east arrow with hook') - - "⤥": [t: "mũi tên đông nam với móc"] # 0x2925 (en: 'south east arrow with hook') - - "⤦": [t: "mũi tên tây nam với móc"] # 0x2926 (en: 'south west arrow with hook') - - "⤧": [t: "mũi tên tây bắc và mũi tên đông bắc"] # 0x2927 (en: 'north west arrow and north east arrow') - - "⤨": [t: "mũi tên đông bắc và mũi tên đông nam"] # 0x2928 (en: 'north east arrow and south east arrow') - - "⤩": [t: "mũi tên đông nam và mũi tên tây nam"] # 0x2929 (en: 'south east arrow and south west arrow') - - "⤪": [t: "mũi tên tây nam và mũi tên tây bắc"] # 0x292a (en: 'south west arrow and north west arrow') - - "⤫": [t: "vượt qua đường chéo đi chéo"] # 0x292b (en: 'rising diagonal crossing falling diagonal') - - "⤬": [t: "ngã đường chéo chéo chéo"] # 0x292c (en: 'falling diagonal crossing rising diagonal') - - "⤭": [t: "mũi tên đông nam băng qua mũi tên đông bắc"] # 0x292d (en: 'south east arrow crossing north east arrow') - - "⤮": [t: "mũi tên đông bắc băng qua mũi tên đông nam"] # 0x292e (en: 'north east arrow crossing south east arrow') - - "⤯": [t: "ngã đường chéo băng qua mũi tên đông bắc"] # 0x292f (en: 'falling diagonal crossing north east arrow') - - "⤰": [t: "tăng đường chéo băng qua mũi tên đông nam"] # 0x2930 (en: 'rising diagonal crossing south east arrow') - - "⤱": [t: "mũi tên đông bắc băng qua mũi tên tây bắc"] # 0x2931 (en: 'north east arrow crossing north west arrow') - - "⤲": [t: "mũi tên tây bắc băng qua mũi tên đông bắc"] # 0x2932 (en: 'north west arrow crossing north east arrow') - - "⤳": [t: "mũi tên sóng chỉ trực tiếp bên phải"] # 0x2933 (en: 'wave arrow pointing directly right') - - "⤴": [t: "mũi tên chỉ ngay sau đó cong lên trên"] # 0x2934 (en: 'arrow pointing rightwards then curving upwards') - - "⤵": [t: "mũi tên chỉ ngay sau đó cong xuống"] # 0x2935 (en: 'arrow pointing rightwards then curving downwards') - - "⤶": [t: "mũi tên hướng xuống dưới rồi cong trái"] # 0x2936 (en: 'arrow pointing downwards then curving leftwards') - - "⤷": [t: "mũi tên chỉ xuống dưới rồi cong phải"] # 0x2937 (en: 'arrow pointing downwards then curving rightwards') - - "⤸": [t: "bên bên phải arc mũi tên theo chiều kim đồng hồ"] # 0x2938 (en: 'right side arc clockwise arrow') - - "⤹": [t: "bên bên trái arc mũi tên ngược chiều kim đồng hồ"] # 0x2939 (en: 'left side arc anticlockwise arrow') - - "⤺": [t: "vòng cung hàng đầu mũi tên chống theo chiều kim đồng hồ"] # 0x293a (en: 'top arc anticlockwise arrow') - - "⤻": [t: "vòng cung dưới cùng mũi tên chống theo chiều kim đồng hồ"] # 0x293b (en: 'bottom arc anticlockwise arrow') - - "⤼": [t: "mũi tên vòng cung trên cùng theo chiều kim đồng hồ với điểm trừ"] # 0x293c (en: 'top arc clockwise arrow with minus') - - "⤽": [t: "mũi tên phản kháng hàng đầu với plus"] # 0x293d (en: 'top arc anticlockwise arrow with plus') - - "⤾": [t: "hạ mũi tên bán nguyệt bên phải"] # 0x293e (en: 'lower right semicircular clockwise arrow') - - "⤿": [t: "mũi tên phản kháng dưới hình bán nguyệt bên trái"] # 0x293f (en: 'lower left semicircular anticlockwise arrow') - - "⥀": [t: "mũi tên vòng tròn kín ngược chiều kim đồng hồ"] # 0x2940 (en: 'anticlockwise closed circle arrow') - - "⥁": [t: "mũi tên vòng tròn kín theo chiều kim đồng hồ"] # 0x2941 (en: 'clockwise closed circle arrow') - - "⥂": [t: "mũi tên bên phải phía trên mũi tên ngắn trái"] # 0x2942 (en: 'rightwards arrow above short leftwards arrow') - - "⥃": [t: "mũi tên trái phía trên mũi tên ngắn phải"] # 0x2943 (en: 'leftwards arrow above short rightwards arrow') - - "⥄": [t: "mũi tên ngắn bên phải phía trên mũi tên trái"] # 0x2944 (en: 'short rightwards arrow above leftwards arrow') - - "⥅": [t: "mũi tên bên phải với cộng với bên dưới"] # 0x2945 (en: 'rightwards arrow with plus below') - - "⥆": [t: "mũi tên trái với cộng với bên dưới"] # 0x2946 (en: 'leftwards arrow with plus below') - - "⥇": [t: "mũi tên phải qua x"] # 0x2947 (en: 'rightwards arrow through x') - - "⥈": [t: "mũi tên trái qua vòng tròn"] # 0x2948 (en: 'left right arrow through circle') - - "⥉": [t: "lên tới hai mũi tên đầu từ circle"] # 0x2949 (en: 'upwards two headed arrow from circle') - - "⥊": [t: "bên trái barb lên bên phải barb xuống harpoon"] # 0x294a (en: 'left barb up right barb down harpoon') - - "⥋": [t: "bên trái barb xuống bên phải barb up harpoon"] # 0x294b (en: 'left barb down right barb up harpoon') - - "⥌": [t: "lên barb phải xuống barb trái harpoon"] # 0x294c (en: 'up barb right down barb left harpoon') - - "⥍": [t: "lên barb trái xuống barb phải harpoon"] # 0x294d (en: 'up barb left down barb right harpoon') - - "⥎": [t: "bên trái barb lên bên phải barb lên harpoon"] # 0x294e (en: 'left barb up right barb up harpoon') - - "⥏": [t: "lên barb ngay xuống barb phải harpoon"] # 0x294f (en: 'up barb right down barb right harpoon') - - "⥐": [t: "bên trái barb xuống bên phải barb xuống harpoon"] # 0x2950 (en: 'left barb down right barb down harpoon') - - "⥑": [t: "lên barb trái xuống barb trái harpoon"] # 0x2951 (en: 'up barb left down barb left harpoon') - - "⥒": [t: "harpoon trái với barb lên đến bar"] # 0x2952 (en: 'leftwards harpoon with barb up to bar') - - "⥓": [t: "harpoon phải với barb lên đến bar"] # 0x2953 (en: 'rightwards harpoon with barb up to bar') - - "⥔": [t: "harpoon hướng lên với barb ngay để thanh"] # 0x2954 (en: 'upwards harpoon with barb right to bar') - - "⥕": [t: "downwards harpoon với barb ngay để thanh"] # 0x2955 (en: 'downwards harpoon with barb right to bar') - - "⥖": [t: "harpoon trái với barb xuống bar"] # 0x2956 (en: 'leftwards harpoon with barb down to bar') - - "⥗": [t: "harpoon phải với barb xuống bar"] # 0x2957 (en: 'rightwards harpoon with barb down to bar') - - "⥘": [t: "harpoon đi lên với barb trái để thanh"] # 0x2958 (en: 'upwards harpoon with barb left to bar') - - "⥙": [t: "downwards harpoon với barb rời khỏi quán bar"] # 0x2959 (en: 'downwards harpoon with barb left to bar') - - "⥚": [t: "harpoon trái với barb lên từ quán bar"] # 0x295a (en: 'leftwards harpoon with barb up from bar') - - "⥛": [t: "harpoon phải với barb lên từ bar"] # 0x295b (en: 'rightwards harpoon with barb up from bar') - - "⥜": [t: "harpoon đi lên với barb ngay từ quán bar"] # 0x295c (en: 'upwards harpoon with barb right from bar') - - "⥝": [t: "downwards harpoon với barb ngay từ quán bar"] # 0x295d (en: 'downwards harpoon with barb right from bar') - - "⥞": [t: "harpoon trái với barb xuống từ bar"] # 0x295e (en: 'leftwards harpoon with barb down from bar') - - "⥟": [t: "harpoon phải với barb xuống từ bar"] # 0x295f (en: 'rightwards harpoon with barb down from bar') - - "⥠": [t: "harpoon đi lên với barb còn lại từ quán bar"] # 0x2960 (en: 'upwards harpoon with barb left from bar') - - "⥡": [t: "downwards harpoon với barb rời khỏi quán bar"] # 0x2961 (en: 'downwards harpoon with barb left from bar') - - "⥢": [t: "harpoon bên trái với barb lên trên harpoon bên trái với barb down"] # 0x2962 (en: 'leftwards harpoon with barb up above leftwards harpoon with barb down') - - "⥣": [t: "harpoon đi lên với barb bên trái bên cạnh harpoon với barb phải"] # 0x2963 (en: 'upwards harpoon with barb left beside upwards harpoon with barb right') - - "⥤": [t: "harpoon phải với barb lên trên harpoon bên phải với barb down"] # 0x2964 (en: 'rightwards harpoon with barb up above rightwards harpoon with barb down') - - "⥥": [t: "downwards harpoon với barb bên trái bên cạnh harpoon với barb phải"] # 0x2965 (en: 'downwards harpoon with barb left beside downwards harpoon with barb right') - - "⥦": [t: "harpoon bên trái với barb lên trên harpoon bên phải với barb up"] # 0x2966 (en: 'leftwards harpoon with barb up above rightwards harpoon with barb up') - - "⥧": [t: "harpoon bên trái với barb xuống phía trên harpoon bên phải với barb down"] # 0x2967 (en: 'leftwards harpoon with barb down above rightwards harpoon with barb down') - - "⥨": [t: "harpoon phải với barb lên trên harpoon bên trái với barb up"] # 0x2968 (en: 'rightwards harpoon with barb up above leftwards harpoon with barb up') - - "⥩": [t: "harpoon phải với barb xuống phía trên harpoon bên trái với barb down"] # 0x2969 (en: 'rightwards harpoon with barb down above leftwards harpoon with barb down') - - "⥪": [t: "harpoon bên trái với barb lên trên dash dài"] # 0x296a (en: 'leftwards harpoon with barb up above long dash') - - "⥫": [t: "harpoon bên trái với barb xuống bên dưới dấu gạch ngang dài"] # 0x296b (en: 'leftwards harpoon with barb down below long dash') - - "⥬": [t: "harpoon bên phải với barb lên trên dash dài"] # 0x296c (en: 'rightwards harpoon with barb up above long dash') - - "⥭": [t: "harpoon bên phải với barb xuống bên dưới dash dài"] # 0x296d (en: 'rightwards harpoon with barb down below long dash') - - "⥮": [t: "harpoon đi lên với barb bên trái bên cạnh harpoon với barb phải"] # 0x296e (en: 'upwards harpoon with barb left beside downwards harpoon with barb right') - - "⥯": [t: "downwards harpoon với barb bên trái bên cạnh harpoon với barb phải"] # 0x296f (en: 'downwards harpoon with barb left beside upwards harpoon with barb right') - - "⥰": [t: "mũi tên đôi phải với đầu tròn"] # 0x2970 (en: 'right double arrow with rounded head') - - "⥱": [t: "bằng với mũi tên bên phải"] # 0x2971 (en: 'equals above rightwards arrow') - - "⥲": [t: "toán tử tilde phía trên mũi tên bên phải"] # 0x2972 (en: 'tilde operator above rightwards arrow') - - "⥳": [t: "mũi tên trái phía trên toán tử tilde"] # 0x2973 (en: 'leftwards arrow above tilde operator') - - "⥴": [t: "mũi tên bên phải phía trên toán tử tilde"] # 0x2974 (en: 'rightwards arrow above tilde operator') - - "⥵": [t: "mũi tên bên phải trên gần như bằng"] # 0x2975 (en: 'rightwards arrow above almost equal to') - - "⥶": [t: "ít hơn mũi tên bên trái"] # 0x2976 (en: 'less than above leftwards arrow') - - "⥷": [t: "mũi tên trái qua ít hơn"] # 0x2977 (en: 'leftwards arrow through less than') - - "⥸": [t: "lớn hơn mũi tên bên phải trên"] # 0x2978 (en: 'greater than above rightwards arrow') - - "⥹": [t: "tập hợp con trên mũi tên phải"] # 0x2979 (en: 'subset above rightwards arrow') - - "⥺": [t: "mũi tên trái qua tập hợp con"] # 0x297a (en: 'leftwards arrow through subset') - - "⥻": [t: "superset phía trên mũi tên trái"] # 0x297b (en: 'superset above leftwards arrow') - - "⥼": [t: "đuôi cá trái"] # 0x297c (en: 'left fish tail') - - "⥽": [t: "đuôi cá phải"] # 0x297d (en: 'right fish tail') - - "⥾": [t: "lên đuôi cá"] # 0x297e (en: 'up fish tail') - - "⥿": [t: "xuống đuôi cá"] # 0x297f (en: 'down fish tail') - - "⦀": [t: "triple dọc thanh phân định"] # 0x2980 (en: 'triple vertical bar delimiter') - - "⦁": [t: "z ký hiệu ký hiệu"] # 0x2981 (en: 'z notation spot') - - "⦂": [t: "z ký hiệu loại đại tràng"] # 0x2982 (en: 'z notation type colon') - - "⦃": [t: "nẹp trắng"] # 0x2983 (en: 'left white brace') - - "⦄": [t: "niềng răng trắng phải"] # 0x2984 (en: 'right white brace') - - "⦅": [t: "dấu ngoặc đơn trắng"] # 0x2985 (en: 'left white parenthesis') - - "⦆": [t: "dấu ngoặc đơn trắng bên phải"] # 0x2986 (en: 'right white parenthesis') - - "⦇": [t: "z ký hiệu bên trái khung hình ảnh"] # 0x2987 (en: 'z notation left image bracket') - - "⦈": [t: "z ký hiệu bên phải khung hình ảnh"] # 0x2988 (en: 'z notation right image bracket') - - "⦉": [t: "z ký hiệu bên trái khung liên kết"] # 0x2989 (en: 'z notation left binding bracket') - - "⦊": [t: "z ký hiệu bên phải khung liên kết"] # 0x298a (en: 'z notation right binding bracket') - - "⦋": [t: "khung vuông bên trái với unterbar"] # 0x298b (en: 'left square bracket with underbar') - - "⦌": [t: "khung vuông bên phải với atarbar"] # 0x298c (en: 'right square bracket with underbar') - - "⦍": [t: "khung vuông bên trái với tích tắc ở góc trên cùng"] # 0x298d (en: 'left square bracket with tick in top corner') - - "⦎": [t: "khung vuông bên phải với tích tắc ở góc dưới cùng"] # 0x298e (en: 'right square bracket with tick in bottom corner') - - "⦏": [t: "khung vuông bên trái với tích tắc ở góc dưới cùng"] # 0x298f (en: 'left square bracket with tick in bottom corner') - - "⦐": [t: "khung vuông bên phải với tích tắc ở góc trên cùng"] # 0x2990 (en: 'right square bracket with tick in top corner') - - "⦑": [t: "khung góc trái với dấu chấm"] # 0x2991 (en: 'left angle bracket with dot') - - "⦒": [t: "khung góc phải với dấu chấm"] # 0x2992 (en: 'right angle bracket with dot') - - "⦓": [t: "vòng cung trái ít hơn khung"] # 0x2993 (en: 'left arc less than bracket') - - "⦔": [t: "arc bên phải lớn hơn giá đỡ"] # 0x2994 (en: 'right arc greater than bracket') - - "⦕": [t: "double left arc lớn hơn giá đỡ"] # 0x2995 (en: 'double left arc greater than bracket') - - "⦖": [t: "double bên phải vòng cung ít hơn khung"] # 0x2996 (en: 'double right arc less than bracket') - - "⦗": [t: "để lại khung vỏ rùa đen"] # 0x2997 (en: 'left black tortoise shell bracket') - - "⦘": [t: "bên phải khung vỏ rùa đen"] # 0x2998 (en: 'right black tortoise shell bracket') - - "⦙": [t: "hàng rào chấm"] # 0x2999 (en: 'dotted fence') - - "⦚": [t: "đường ngoằn ngoèo dọc"] # 0x299a (en: 'vertical zigzag line') - - "⦛": [t: "đo góc mở bên trái"] # 0x299b (en: 'measured angle opening left') - - "⦜": [t: "biến góc bên phải với hình vuông"] # 0x299c (en: 'right angle varient with square') - - "⦝": [t: "đo góc bên phải với dấu chấm"] # 0x299d (en: 'measured right angle with dot') - - "⦞": [t: "góc với s bên trong"] # 0x299e (en: 'angle with s inside') - - "⦟": [t: "góc nhọn"] # 0x299f (en: 'acute angle') - - "⦠": [t: "góc spehrical mở bên trái"] # 0x29a0 (en: 'spehrical angle opening left') - - "⦡": [t: "góc spehrical mở ra"] # 0x29a1 (en: 'spehrical angle opening up') - - "⦢": [t: "quay góc"] # 0x29a2 (en: 'turned angle') - - "⦣": [t: "góc đảo ngược"] # 0x29a3 (en: 'reversed angle') - - "⦤": [t: "góc với atarbar"] # 0x29a4 (en: 'angle with underbar') - - "⦥": [t: "góc đảo ngược với unterbar"] # 0x29a5 (en: 'reversed angle with underbar') - - "⦦": [t: "góc xiên mở ra"] # 0x29a6 (en: 'oblique angle opening up') - - "⦧": [t: "góc xiên mở xuống"] # 0x29a7 (en: 'oblique angle opening down') - - "⦨": [t: "đo góc với đầu cánh tay mở trong mũi tên chỉ lên và sang phải"] # 0x29a8 (en: 'measured angle with open arm ending in arrow pointing up and to the right') - - "⦩": [t: "đo góc với đầu cánh tay mở trong mũi tên hướng lên và bên trái"] # 0x29a9 (en: 'measured angle with open arm ending in arrow pointing up and to the left') - - "⦪": [t: "đo góc với đầu cánh tay mở trong mũi tên chỉ xuống và bên phải"] # 0x29aa (en: 'measured angle with open arm ending in arrow pointing down and to the right') - - "⦫": [t: "đo góc với đầu cánh tay mở trong mũi tên chỉ xuống và bên trái"] # 0x29ab (en: 'measured angle with open arm ending in arrow pointing down and to the left') - - "⦬": [t: "đo góc với đầu cánh tay mở trong mũi tên hướng thẳng và lên"] # 0x29ac (en: 'measured angle with open arm ending in arrow pointing right and up') - - "⦭": [t: "đo góc với đầu cánh tay mở trong mũi tên hướng sang trái và lên"] # 0x29ad (en: 'measured angle with open arm ending in arrow pointing left and up') - - "⦮": [t: "đo góc với đầu cánh tay mở trong mũi tên chỉ thẳng và xuống"] # 0x29ae (en: 'measured angle with open arm ending in arrow pointing right and down') - - "⦯": [t: "đo góc với đầu cánh tay mở trong mũi tên hướng sang trái và xuống"] # 0x29af (en: 'measured angle with open arm ending in arrow pointing left and down') - - "⦰": [t: "đảo ngược bộ trống"] # 0x29b0 (en: 'reversed empty set') - - "⦱": [t: "bộ trống với thanh toán quá mức"] # 0x29b1 (en: 'empty set with overbar') - - "⦲": [t: "bộ trống với vòng tròn nhỏ ở trên"] # 0x29b2 (en: 'empty set with small circle above') - - "⦳": [t: "bộ trống với mũi tên phải ở trên"] # 0x29b3 (en: 'empty set with right arrow above') - - "⦴": [t: "bộ trống với mũi tên trái ở trên"] # 0x29b4 (en: 'empty set with left arrow above') - - "⦵": [t: "vòng tròn với thanh ngang"] # 0x29b5 (en: 'circle with horizontal bar') - - "⦶": [t: "bao quanh thanh dọc"] # 0x29b6 (en: 'circled vertical bar') - - "⦷": [t: "bao quanh song song"] # 0x29b7 (en: 'circled parallel') - - "⦸": [t: "khoanh tròn đảo ngược solidus"] # 0x29b8 (en: 'circled reverse solidus') - - "⦹": [t: "khoanh tròn vuông góc"] # 0x29b9 (en: 'circled perpendicular') - - "⦺": [t: "được khoanh tròn chia cho thanh ngang và nửa trên chia cho thanh dọc"] # 0x29ba (en: 'circled divided by horizontal bar and top half divided by vertical bar') - - "⦻": [t: "vòng tròn với x chồng chất x"] # 0x29bb (en: 'circle with superimposed x') - - "⦼": [t: "bao quanh dấu hiệu phân chia quay ngược chiều kim đồng hồ"] # 0x29bc (en: 'circled anticlockwise rotated division sign') - - "⦽": [t: "lên mũi tên qua vòng tròn"] # 0x29bd (en: 'up arrow through circle') - - "⦾": [t: "vòng đạn trắng bao quanh"] # 0x29be (en: 'circled white bullet') - - "⦿": [t: "vòng đạn khoanh tròn"] # 0x29bf (en: 'circled bullet') - - "⧀": [t: "khoanh tròn ít hơn"] # 0x29c0 (en: 'circled less than') - - "⧁": [t: "bao quanh lớn hơn"] # 0x29c1 (en: 'circled greater than') - - "⧂": [t: "vòng tròn với vòng tròn nhỏ ở bên phải"] # 0x29c2 (en: 'circle with small circle to the right') - - "⧃": [t: "vòng tròn với hai nét ngang ở bên phải"] # 0x29c3 (en: 'circle with two horizontal strokes to the right') - - "⧄": [t: "squared tăng chéo chéo"] # 0x29c4 (en: 'squared rising diagonal slash') - - "⧅": [t: "squared rơi chéo chéo"] # 0x29c5 (en: 'squared falling diagonal slash') - - "⧆": [t: "dấu hoa thị bình phương"] # 0x29c6 (en: 'squared asterisk') - - "⧇": [t: "vòng tròn nhỏ bình phương"] # 0x29c7 (en: 'squared small circle') - - "⧈": [t: "quảng trường bình phương"] # 0x29c8 (en: 'squared square') - - "⧉": [t: "hai người tham gia quảng trường"] # 0x29c9 (en: 'two joined squares') - - "⧊": [t: "tam giác với dấu chấm ở trên"] # 0x29ca (en: 'triangle with dot above') - - "⧋": [t: "tam giác với atarbar"] # 0x29cb (en: 'triangle with underbar') - - "⧌": [t: "s trong tam giác"] # 0x29cc (en: 's in triangle') - - "⧍": [t: "tam giác với serifs ở dưới cùng"] # 0x29cd (en: 'triangle with serifs at bottom') - - "⧎": [t: "tam giác phải phía trên tam giác trái"] # 0x29ce (en: 'right triangle above left triangle') - - "⧏": [t: "trái timgle bên cạnh thanh dọc"] # 0x29cf (en: 'left triangle beside vertical bar') - - "⧐": [t: "thanh dọc bên cạnh tam giác phải"] # 0x29d0 (en: 'vertical bar beside right triangle') - - "⧑": [t: "bowtie với một nửa màu đen"] # 0x29d1 (en: 'bowtie with left half black') - - "⧒": [t: "bowtie với nửa đen phải"] # 0x29d2 (en: 'bowtie with right half black') - - "⧓": [t: "bowtie đen"] # 0x29d3 (en: 'black bowtie') - - "⧔": [t: "lần với một nửa màu đen"] # 0x29d4 (en: 'times with left half black') - - "⧕": [t: "lần với nửa màu đen bên phải"] # 0x29d5 (en: 'times with right half black') - - "⧖": [t: "đồng hồ cát trắng"] # 0x29d6 (en: 'white hourglass') - - "⧗": [t: "đồng hồ cát đen"] # 0x29d7 (en: 'black hourglass') - - "⧘": [t: "để lại hàng rào đau khổ"] # 0x29d8 (en: 'left wiggly fence') - - "⧙": [t: "hàng rào phải"] # 0x29d9 (en: 'right wiggly fence') - - "⧚": [t: "để lại đôi hàng rào"] # 0x29da (en: 'left double wiggly fence') - - "⧛": [t: "phải đôi hàng rào wiggly"] # 0x29db (en: 'right double wiggly fence') - - "⧜": [t: "infinity không đầy đủ"] # 0x29dc (en: 'incomplete infinity') - - "⧝": [t: "buộc vô cực"] # 0x29dd (en: 'tie over infinity') - - "⧞": [t: "infinity phủ định với thanh thẳng đứng"] # 0x29de (en: 'infinity negated with vertical bar') - - "⧟": [t: "multimap kết thúc hai lần"] # 0x29df (en: 'double-ended multimap') - - "⧠": [t: "hình vuông với đường viền đường viền"] # 0x29e0 (en: 'square with contoured outline') - - "⧡": [t: "tăng như"] # 0x29e1 (en: 'increases as') - - "⧢": [t: "sản phẩm xáo trộn"] # 0x29e2 (en: 'shuffle product') - - "⧣": [t: "bằng dấu hiệu và song song nghiêng"] # 0x29e3 (en: 'equals sign and slanted parallel') - - "⧤": [t: "bằng dấu hiệu và song song nghiêng với tilde ở trên"] # 0x29e4 (en: 'equals sign and slanted parallel with tilde above') - - "⧥": [t: "giống hệt và nghiêng song song"] # 0x29e5 (en: 'identical to and slanted parallel') - - "⧦": [t: "gleich stark"] # 0x29e6 - - "⧧": [t: "đo nhiệt"] # 0x29e7 (en: 'thermydynamic') - - "⧨": [t: "xuống hình tam giác với nửa màu đen trái"] # 0x29e8 (en: 'down pointing triangle with left half black') - - "⧩": [t: "xuống hình tam giác với nửa màu đen bên phải"] # 0x29e9 (en: 'down pointing triangle with right half black') - - "⧪": [t: "kim cương đen với mũi tên xuống"] # 0x29ea (en: 'black diamond with down arrow') - - "⧫": [t: "black lozenge"] # 0x29eb - - "⧬": [t: "vòng tròn màu trắng với mũi tên xuống"] # 0x29ec (en: 'white circle with down arrow') - - "⧭": [t: "vòng tròn màu đen với mũi tên xuống"] # 0x29ed (en: 'black circle with down arrow') - - "⧮": [t: "quảng trường trắng lỗi"] # 0x29ee (en: 'error-barred white square') - - "⧯": [t: "quảng trường đen lỗi lỗi"] # 0x29ef (en: 'error-barred black square') - - "⧰": [t: "kim cương trắng lỗi lỗi"] # 0x29f0 (en: 'error-barred white diamond') - - "⧱": [t: "kim cương đen lỗi lỗi"] # 0x29f1 (en: 'error-barred black diamond') - - "⧲": [t: "vòng tròn trắng lỗi"] # 0x29f2 (en: 'error-barred white circle') - - "⧳": [t: "vòng tròn đen lỗi"] # 0x29f3 (en: 'error-barred black circle') - - "⧴": [t: "sự triệt tiêu quy tắc"] # 0x29f4 (en: 'rule-delayed') - - "⧵": [t: "hiệu"] # 0x29f5 (en: 'reverse solidus operator') - - "⧶": [t: "solidus với overbar"] # 0x29f6 (en: 'solidus with overbar') - - "⧷": [t: "đảo ngược solidus với gạch ngang"] # 0x29f7 (en: 'reverse solidus with horizontal stroke') - - "⧸": [t: "solidus lớn"] # 0x29f8 (en: 'big solidus') - - "⧹": [t: "solidus đảo ngược lớn"] # 0x29f9 (en: 'big reverse solidus') - - "⧺": [t: "double plus"] # 0x29fa - - "⧻": [t: "triple plus"] # 0x29fb - - "⧼": [t: "bên trái, giá đỡ góc cong"] # 0x29fc (en: 'left pointing curved angle bracket') - - "⧽": [t: "chân phải cong khung góc cong"] # 0x29fd (en: 'right pointing curved angle bracket') - - "⧾": [t: "nhỏ bé"] # 0x29fe (en: 'tiny') - - "⧿": [t: "miny"] # 0x29ff - - "⨀": [t: "toán tử chấm được khoanh tròn"] # 0x2a00 (en: 'circled dot operator') - - "⨁": [t: "tuyến đường cộng với toán tử cộng với"] # 0x2a01 (en: 'circled plus operator') - - "⨂": [t: "nhà điều hành thời gian được khoanh tròn"] # 0x2a02 (en: 'circled times operator') - - "⨃": [t: "nhà điều hành công đoàn với dot"] # 0x2a03 (en: 'union operator with dot') - - "⨄": [t: "nhà điều hành công đoàn với plus"] # 0x2a04 (en: 'union operator with plus') - - "⨅": [t: "toán tử giao lộ vuông"] # 0x2a05 (en: 'square intersection operator') - - "⨆": [t: "nhà điều hành liên minh vuông"] # 0x2a06 (en: 'square union operator') - - "⨇": [t: "hai logic và toán tử"] # 0x2a07 (en: 'two logical and operator') - - "⨈": [t: "hai logic hoặc toán tử"] # 0x2a08 (en: 'two logical or operator') - - "⨉": [t: "nhà điều hành lần"] # 0x2a09 (en: 'times operator') - - "⨊": [t: "modulo hai tổng"] # 0x2a0a (en: 'modulo two sum') - - "⨋": [t: "tổng hợp với tích phân"] # 0x2a0b (en: 'summation with integral') - - "⨌": [t: "toán tử tích phân tứ giác"] # 0x2a0c (en: 'quadruple integral operator') - - "⨍": [t: "tích hợp phần hữu hạn"] # 0x2a0d (en: 'finite part integral') - - "⨎": [t: "tích hợp với gạch đôi"] # 0x2a0e (en: 'integral with double stroke') - - "⨏": [t: "tích hợp trung bình với chém"] # 0x2a0f (en: 'integral average with slash') - - "⨐": [t: "chức năng lưu thông"] # 0x2a10 (en: 'circulation function') - - "⨑": [t: "tích hợp ngược chiều kim đồng hồ"] # 0x2a11 (en: 'anticlockwise integration') - - "⨒": [t: "tích hợp đường với đường hình chữ nhật xung quanh cực"] # 0x2a12 (en: 'line integration with rectangular path around pole') - - "⨓": [t: "tích hợp dòng với đường dẫn hình bán nguyệt xung quanh cực"] # 0x2a13 (en: 'line integration with semicircular path around pole') - - "⨔": [t: "tích hợp dòng không bao gồm cực"] # 0x2a14 (en: 'line integration not including the pole') - - "⨕": [t: "tích hợp xung quanh một toán tử điểm"] # 0x2a15 (en: 'integral around a point operator') - - "⨖": [t: "toán tử tích phân quarternion"] # 0x2a16 (en: 'quaternion integral operator') - - "⨗": [t: "tích hợp với mũi tên trái với móc"] # 0x2a17 (en: 'integral with leftwards arrow with hook') - - "⨘": [t: "tích hợp với dấu hiệu thời gian"] # 0x2a18 (en: 'integral with times sign') - - "⨙": [t: "tích hợp với giao điểm"] # 0x2a19 (en: 'integral with intersection') - - "⨚": [t: "tích hợp với liên minh"] # 0x2a1a (en: 'integral with union') - - "⨛": [t: "tích hợp với overbar"] # 0x2a1b (en: 'integral with overbar') - - "⨜": [t: "tích hợp với underbar"] # 0x2a1c (en: 'integral with underbar') - - "⨝": [t: "tham gia"] # 0x2a1d (en: 'join') - - "⨞": [t: "người vận hành tam giác lớn bên trái"] # 0x2a1e (en: 'large left triangle operator') - - "⨟": [t: "thành phần lược đồ ký hiệu z"] # 0x2a1f (en: 'z notation schema composition') - - "⨠": [t: "z ký hiệu ký đồ đường ống"] # 0x2a20 (en: 'z notation schema piping') - - "⨡": [t: "z ký đồ ký đồ"] # 0x2a21 (en: 'z notation schema projection') - - "⨢": [t: "cộng với dấu hiệu với vòng tròn ở trên"] # 0x2a22 (en: 'plus sign with circle above') - - "⨣": [t: "cộng với dấu hiệu với giọng nói ở trên"] # 0x2a23 (en: 'plus sign with circumflex accent above') - - "⨤": [t: "cộng với dấu hiệu với tilde ở trên"] # 0x2a24 (en: 'plus sign with tilde above') - - "⨥": [t: "cộng với dấu hiệu với dấu chấm dưới đây"] # 0x2a25 (en: 'plus sign with dot below') - - "⨦": [t: "cộng với dấu hiệu với tilde dưới đây"] # 0x2a26 (en: 'plus sign with tilde below') - - "⨧": [t: "cộng với dấu hiệu với chỉ số hai"] # 0x2a27 (en: 'plus sign with subscript two') - - "⨨": [t: "cộng với dấu hiệu với tam giác đen"] # 0x2a28 (en: 'plus sign with black triangle') - - "⨩": [t: "điểm trừ dấu hiệu với dấu phẩy ở trên"] # 0x2a29 (en: 'minus sign with comma above') - - "⨪": [t: "điểm trừ với dấu chấm dưới đây"] # 0x2a2a (en: 'minus sign with dot below') - - "⨫": [t: "điểm trừ với dấu chấm rơi"] # 0x2a2b (en: 'minus sign with falling dots') - - "⨬": [t: "điểm trừ với dấu hiệu tăng"] # 0x2a2c (en: 'minus sign with rising dots') - - "⨭": [t: "cộng với dấu hiệu trong nửa vòng tròn trái"] # 0x2a2d (en: 'plus sign in left half circle') - - "⨮": [t: "cộng với đăng nhập vào nửa vòng tròn bên phải"] # 0x2a2e (en: 'plus sign in right half circle') - - "⨯": [t: "sản phẩm chéo"] # 0x2a2f (en: 'cross product') - - "⨰": [t: "dấu hiệu nhân với dấu chấm ở trên"] # 0x2a30 (en: 'multiplication sign with dot above') - - "⨱": [t: "dấu hiệu nhân với inderbar"] # 0x2a31 (en: 'multiplication sign with underbar') - - "⨲": [t: "sản phẩm bán kết với đóng đáy đóng"] # 0x2a32 (en: 'semidirect product with bottom closed') - - "⨳": [t: "smash sản phẩm"] # 0x2a33 (en: 'smash product') - - "⨴": [t: "dấu nhân trong nửa vòng tròn trái"] # 0x2a34 (en: 'multiplication sign in left half circle') - - "⨵": [t: "đăng nhập nhân trong nửa vòng tròn bên phải"] # 0x2a35 (en: 'multiplication sign in right half circle') - - "⨶": [t: "dấu hiệu nhân được khoanh tròn với giọng nói chu vi"] # 0x2a36 (en: 'circled multiplication sign with circumflex accent') - - "⨷": [t: "hiệu số nhân trong vòng tròn đôi"] # 0x2a37 (en: 'multiplication sign in double circle') - - "⨸": [t: "dấu hiệu phân chia vòng tròn"] # 0x2a38 (en: 'circled division sign') - - "⨹": [t: "cộng với dấu hiệu trong tam giác"] # 0x2a39 (en: 'plus sign in triangle') - - "⨺": [t: "trừ dấu hiệu trong tam giác"] # 0x2a3a (en: 'minus sign in triangle') - - "⨻": [t: "dấu hiệu nhân trong tam giác"] # 0x2a3b (en: 'multiplication sign in triangle') - - "⨼": [t: "sản phẩm nội thất"] # 0x2a3c (en: 'interior product') - - "⨽": [t: "sản phẩm nội thất bên tay"] # 0x2a3d (en: 'righthand interior product') - - "⨮": [t: "z ký hiệu thành phần quan hệ"] # 0x2a2e (en: 'z notation relational composition') - - "⨿": [t: "hợp nhất hoặc coproduct"] # 0x2a3f (en: 'amalgamation or coproduct') - - "⩀": [t: "giao lộ với dấu chấm"] # 0x2a40 (en: 'intersection with dot') - - "⩁": [t: "liên minh với dấu hiệu trừ"] # 0x2a41 (en: 'union with minus sign') - - "⩂": [t: "liên minh với overbar"] # 0x2a42 (en: 'union with overbar') - - "⩃": [t: "giao lộ với overbar"] # 0x2a43 (en: 'intersection with overbar') - - "⩄": [t: "giao lộ với logic và"] # 0x2a44 (en: 'intersection with logical and') - - "⩅": [t: "liên kết với logic hoặc"] # 0x2a45 (en: 'union with logical or') - - "⩆": [t: "liên minh trên giao lộ"] # 0x2a46 (en: 'union above intersection') - - "⩇": [t: "giao lộ trên liên minh"] # 0x2a47 (en: 'intersection above union') - - "⩈": [t: "liên minh trên thanh trên giao lộ"] # 0x2a48 (en: 'union above bar above intersection') - - "⩉": [t: "giao lộ trên thanh trên liên minh"] # 0x2a49 (en: 'intersection above bar above union') - - "⩊": [t: "liên minh bên cạnh và tham gia với liên minh"] # 0x2a4a (en: 'union beside and joined with union') - - "⩋": [t: "giao lộ bên cạnh và tham gia với giao lộ"] # 0x2a4b (en: 'intersection beside and joined with intersection') - - "⩌": [t: "đóng kết hợp với serifs"] # 0x2a4c (en: 'closed union with serifs') - - "⩍": [t: "giao lộ đóng với serifs"] # 0x2a4d (en: 'closed intersection with serifs') - - "⩎": [t: "giao lộ kép vuông"] # 0x2a4e (en: 'double square intersection') - - "⩏": [t: "double square union"] # 0x2a4f - - "⩐": [t: "đóng liên minh với serifs và smash sản phẩm"] # 0x2a50 (en: 'closed union with serifs and smash product') - - "⩑": [t: "logic và với dấu chấm ở trên"] # 0x2a51 (en: 'logical and with dot above') - - "⩒": [t: "logic hoặc với dấu chấm ở trên"] # 0x2a52 (en: 'logical or with dot above') - - "⩓": [t: "gấp đôi logic và"] # 0x2a53 (en: 'double logical and') - - "⩔": [t: "gấp đôi logic hoặc"] # 0x2a54 (en: 'double logical or') - - "⩕": [t: "hai giao nhau logic và"] # 0x2a55 (en: 'two intersecting logical and') - - "⩖": [t: "hai giao nhau logic hoặc"] # 0x2a56 (en: 'two intersecting logical or') - - "⩗": [t: "dốc lớn hoặc"] # 0x2a57 (en: 'sloping large or') - - "⩘": [t: "dốc lớn và"] # 0x2a58 (en: 'sloping large and') - - "⩙": [t: "logic hoặc chồng chéo logic và"] # 0x2a59 (en: 'logical or overlapping logical and') - - "⩚": [t: "logic và với thân giữa"] # 0x2a5a (en: 'logical and with middle stem') - - "⩛": [t: "logic hoặc với thân giữa"] # 0x2a5b (en: 'logical or with middle stem') - - "⩜": [t: "logic và với dấu gạch ngang ngang"] # 0x2a5c (en: 'logical and with horizontal dash') - - "⩝": [t: "logic hoặc với dấu gạch ngang ngang"] # 0x2a5d (en: 'logical or with horizontal dash') - - "⩞": [t: "logic và với gấp đôi obbar"] # 0x2a5e (en: 'logical and with double overbar') - - "⩟": [t: "logic và với unterbar"] # 0x2a5f (en: 'logical and with underbar') - - "⩠": [t: "logic và với đôi bên dưới"] # 0x2a60 (en: 'logical and with double underbar') - - "⩡": [t: "vee nhỏ với atarbar"] # 0x2a61 (en: 'small vee with underbar') - - "⩢": [t: "logic hoặc với gấp đôi obbar"] # 0x2a62 (en: 'logical or with double overbar') - - "⩣": [t: "logic hoặc với đôi bên dưới"] # 0x2a63 (en: 'logical or with double underbar') - - "⩤": [t: "z ký hiệu kháng thể"] # 0x2a64 (en: 'z notation domain antirestriction') - - "⩥": [t: "z ký hiệu phạm vi chống trọng yếu"] # 0x2a65 (en: 'z notation range antirestriction') - - "⩦": [t: "bằng dấu hiệu với dấu chấm dưới đây"] # 0x2a66 (en: 'equals sign with dot below') - - "⩧": [t: "giống hệt với dấu chấm trên"] # 0x2a67 (en: 'identical with dot above') - - "⩨": [t: "thanh ba ngang với gạch dọc"] # 0x2a68 (en: 'triple horizontal bar with double vertical stroke') - - "⩩": [t: "thanh ba ngang với cú đánh thẳng đứng ba"] # 0x2a69 (en: 'triple horizontal bar with triple vertical stroke') - - "⩪": [t: "toán tử tilde với dấu chấm ở trên"] # 0x2a6a (en: 'tilde operator with dot above') - - "⩫": [t: "nhà điều hành tilde với các chấm tăng"] # 0x2a6b (en: 'tilde operator with rising dots') - - "⩬": [t: "tương tự trừ tương tự"] # 0x2a6c (en: 'similar minus similar') - - "⩭": [t: "đồng dạng với dấu chấm ở trên"] # 0x2a6d (en: 'congruent with dot above') - - "⩮": [t: "bằng với dấu hoa thị"] # 0x2a6e (en: 'equals with asterisk') - - "⩯": [t: "gần như bằng với giọng nói chu vi"] # 0x2a6f (en: 'almost equal to with circumflex accent') - - "⩰": [t: "xấp xỉ bằng hoặc bằng"] # 0x2a70 (en: 'approximately equal to or equal to') - - "⩱": [t: "bằng dấu hiệu trên cộng với dấu hiệu"] # 0x2a71 (en: 'equals sign above plus sign') - - "⩲": [t: "cộng với dấu hiệu trên bằng dấu hiệu"] # 0x2a72 (en: 'plus sign above equals sign') - - "⩳": [t: "bằng dấu hiệu trên toán tử tilde"] # 0x2a73 (en: 'equals sign above tilde operator') - - "⩴": [t: "đại tràng gấp đôi bằng nhau"] # 0x2a74 (en: 'double colon equal') - - "⩵": [t: "hai dấu hiệu liên tiếp"] # 0x2a75 (en: 'two consecutive equals signs') - - "⩶": [t: "ba dấu hiệu liên tiếp"] # 0x2a76 (en: 'three consecutive equals signs') - - "⩷": [t: "bằng dấu hiệu với hai chấm trên và hai dấu chấm bên dưới"] # 0x2a77 (en: 'equals sign with two dots above and two dots below') - - "⩸": [t: "tương đương với bốn chấm trên"] # 0x2a78 (en: 'equivalent with four dots above') - - "⩹": [t: "ít hơn với vòng tròn bên trong"] # 0x2a79 (en: 'less than with circle inside') - - "⩺": [t: "lớn hơn với vòng tròn bên trong"] # 0x2a7a (en: 'greater than with circle inside') - - "⩻": [t: "ít hơn với dấu hỏi ở trên"] # 0x2a7b (en: 'less than with question mark above') - - "⩼": [t: "lớn hơn với dấu hỏi ở trên"] # 0x2a7c (en: 'greater than with question mark above') - - "⩽": [t: "nhỏ hơn hoặc nghiêng bằng"] # 0x2a7d (en: 'less than or slanted equal to') - - "⩾": [t: "lớn hơn hoặc nghiêng bằng"] # 0x2a7e (en: 'greater than or slanted equal to') - - "⩿": [t: "nhỏ hơn hoặc nghiêng bằng với dấu chấm bên trong"] # 0x2a7f (en: 'less than or slanted equal to with dot inside') - - "⪀": [t: "lớn hơn hoặc nghiêng bằng với dấu chấm bên trong"] # 0x2a80 (en: 'greater than or slanted equal to with dot inside') - - "⪁": [t: "nhỏ hơn hoặc nghiêng bằng với dấu chấm trên"] # 0x2a81 (en: 'less than or slanted equal to with dot above') - - "⪂": [t: "lớn hơn hoặc nghiêng bằng với dấu chấm trên"] # 0x2a82 (en: 'greater than or slanted equal to with dot above') - - "⪃": [t: "nhỏ hơn hoặc nghiêng bằng với dấu chấm phía trên bên phải"] # 0x2a83 (en: 'less than or slanted equal to with dot above right') - - "⪄": [t: "lớn hơn hoặc nghiêng bằng với dấu chấm phía trên bên trái"] # 0x2a84 (en: 'greater than or slanted equal to with dot above left') - - "⪅": [t: "ít hơn hoặc gần đúng"] # 0x2a85 (en: 'less than or approximate') - - "⪆": [t: "lớn hơn hoặc gần đúng"] # 0x2a86 (en: 'greater than or approximate') - - "⪇": [t: "nhỏ hơn và dòng đơn không bằng"] # 0x2a87 (en: 'less than and single line not equal to') - - "⪈": [t: "lớn hơn và dòng đơn không bằng"] # 0x2a88 (en: 'greater than and single line not equal to') - - "⪉": [t: "ít hơn và không gần đúng"] # 0x2a89 (en: 'less than and not approximate') - - "⪊": [t: "lớn hơn và không gần đúng"] # 0x2a8a (en: 'greater than and not approximate') - - "⪋": [t: "ít hơn so với dòng gấp đôi bằng nhau trên lớn hơn"] # 0x2a8b (en: 'less than above double line equal above greater than') - - "⪌": [t: "lớn hơn dòng gấp đôi trên bằng thấp hơn"] # 0x2a8c (en: 'greater than above double line equal above less than') - - "⪍": [t: "ít hơn trên tương tự hoặc bằng nhau"] # 0x2a8d (en: 'less than above similar or equal') - - "⪎": [t: "lớn hơn trên tương tự hoặc bằng nhau"] # 0x2a8e (en: 'greater than above similar or equal') - - "⪏": [t: "ít hơn trên tương tự ở trên lớn hơn"] # 0x2a8f (en: 'less than above similar above greater than') - - "⪐": [t: "lớn hơn ở trên tương tự ở trên nhỏ hơn"] # 0x2a90 (en: 'greater than above similar above less than') - - "⪑": [t: "ít hơn trên lớn hơn so với dòng kép trên bằng nhau"] # 0x2a91 (en: 'less than above greater than above double line equal') - - "⪒": [t: "lớn hơn trên nhỏ hơn so với dòng gấp đôi bằng nhau"] # 0x2a92 (en: 'greater than above less than above double line equal') - - "⪓": [t: "ít hơn trên nghiêng bằng nhau trên lớn hơn so với trên nghiêng bằng nhau"] # 0x2a93 (en: 'less than above slanted equal above greater than above slanted equal') - - "⪔": [t: "lớn hơn trên nghiêng bằng nhau trên thấp hơn trên nghiêng bằng nhau"] # 0x2a94 (en: 'greater than above slanted equal above less than above slanted equal') - - "⪕": [t: "nghiêng bằng hoặc nhỏ hơn"] # 0x2a95 (en: 'slanted equal to or less than') - - "⪖": [t: "nghiêng bằng hoặc lớn hơn"] # 0x2a96 (en: 'slanted equal to or greater than') - - "⪗": [t: "nghiêng bằng hoặc ít hơn với dấu chấm bên trong"] # 0x2a97 (en: 'slanted equal to or less than with dot inside') - - "⪘": [t: "nghiêng bằng hoặc lớn hơn với dấu chấm bên trong"] # 0x2a98 (en: 'slanted equal to or greater than with dot inside') - - "⪙": [t: "dòng hai bằng hoặc nhỏ hơn"] # 0x2a99 (en: 'double line equal to or less than') - - "⪚": [t: "double dòng bằng hoặc lớn hơn"] # 0x2a9a (en: 'double line equal to or greater than') - - "⪛": [t: "đường đôi nghiêng bằng hoặc nhỏ hơn"] # 0x2a9b (en: 'double line slanted equal to or less than') - - "⪜": [t: "đường đôi nghiêng bằng hoặc lớn hơn"] # 0x2a9c (en: 'double line slanted equal to or greater than') - - "⪝": [t: "tương tự hoặc ít hơn"] # 0x2a9d (en: 'similar or less than') - - "⪞": [t: "tương tự hoặc lớn hơn"] # 0x2a9e (en: 'similar or greater than') - - "⪟": [t: "tương tự ở trên nhỏ hơn trên bằng dấu hiệu"] # 0x2a9f (en: 'similar above less than above equals sign') - - "⪠": [t: "tương tự ở trên lớn hơn trên bằng dấu hiệu"] # 0x2aa0 (en: 'similar above greater than above equals sign') - - "⪡": [t: "kép lồng ít hơn"] # 0x2aa1 (en: 'double nested less than') - - "⪢": [t: "kép lồng nhau lớn hơn"] # 0x2aa2 (en: 'double nested greater than') - - "⪣": [t: "kép lồng ít hơn với atarbar"] # 0x2aa3 (en: 'double nested less than with underbar') - - "⪤": [t: "lớn hơn chồng chéo ít hơn"] # 0x2aa4 (en: 'greater than overlapping less than') - - "⪥": [t: "lớn hơn bên cạnh ít hơn"] # 0x2aa5 (en: 'greater than beside less than') - - "⪦": [t: "ít hơn đóng bởi đường cong"] # 0x2aa6 (en: 'less than closed by curve') - - "⪧": [t: "lớn hơn đóng bởi đường cong"] # 0x2aa7 (en: 'greater than closed by curve') - - "⪨": [t: "ít hơn đóng bởi đường cong trên nghiêng bằng nhau"] # 0x2aa8 (en: 'less than closed by curve above slanted equal') - - "⪩": [t: "lớn hơn đóng bởi đường cong trên nghiêng bằng nhau"] # 0x2aa9 (en: 'greater than closed by curve above slanted equal') - - "⪪": [t: "nhỏ hơn"] # 0x2aaa (en: 'smaller than') - - "⪫": [t: "to hơn"] # 0x2aab (en: 'larger than') - - "⪬": [t: "nhỏ hơn hoặc bằng"] # 0x2aac (en: 'smaller than or equal to') - - "⪭": [t: "lớn hơn hoặc bằng"] # 0x2aad (en: 'larger than or equal to') - - "⪮": [t: "bằng dấu hiệu với gập ghềnh ở trên"] # 0x2aae (en: 'equals sign with bumpy above') - - "⪯": [t: "trước dòng đơn bằng dấu hiệu"] # 0x2aaf (en: 'precedes above single line equals sign') - - "⪰": [t: "thành công trên một dòng tương đương với dấu hiệu"] # 0x2ab0 (en: 'succeeds above single line equals sign') - - "⪱": [t: "tiền định trên dòng đơn không bằng"] # 0x2ab1 (en: 'prededes above single line not equal to') - - "⪲": [t: "thành công trên dòng đơn không bằng"] # 0x2ab2 (en: 'succeeds above single line not equal to') - - "⪳": [t: "trước dấu hiệu tương đương"] # 0x2ab3 (en: 'precedes above equals sign') - - "⪴": [t: "thành công trên dấu bằng"] # 0x2ab4 (en: 'succeeds above equals sign') - - "⪵": [t: "tiền định ở trên không bằng"] # 0x2ab5 (en: 'prededes above not equal to') - - "⪶": [t: "thành công ở trên không bằng"] # 0x2ab6 (en: 'succeeds above not equal to') - - "⪷": [t: "tiền định trên gần như bằng"] # 0x2ab7 (en: 'prededes above almost equal to') - - "⪸": [t: "thành công trên gần như bằng"] # 0x2ab8 (en: 'succeeds above almost equal to') - - "⪹": [t: "trước ở trên không gần như bằng"] # 0x2ab9 (en: 'precedes above not almost equal to') - - "⪺": [t: "thành công ở trên không gần như bằng"] # 0x2aba (en: 'succeeds above not almost equal to') - - "⪻": [t: "gấp đôi trước"] # 0x2abb (en: 'double precedes') - - "⪼": [t: "gấp đôi thành công"] # 0x2abc (en: 'double succeeds') - - "⪽": [t: "tập hợp con với dấu chấm"] # 0x2abd (en: 'subset with dot') - - "⪾": [t: "superset với dấu chấm"] # 0x2abe (en: 'superset with dot') - - "⪿": [t: "tập hợp con với dấu cộng dưới đây"] # 0x2abf (en: 'subset with plus sign below') - - "⫀": [t: "superset với dấu cộng dưới đây"] # 0x2ac0 (en: 'superset with plus sign below') - - "⫁": [t: "tập hợp con với dấu hiệu nhân dưới đây"] # 0x2ac1 (en: 'subset with multiplication sign below') - - "⫂": [t: "superset với dấu hiệu nhân dưới đây"] # 0x2ac2 (en: 'superset with multiplication sign below') - - "⫃": [t: "tập hợp con hoặc bằng với dấu chấm trên"] # 0x2ac3 (en: 'subset of or equal to with dot above') - - "⫄": [t: "superset của hoặc bằng với dấu chấm trên"] # 0x2ac4 (en: 'superset of or equal to with dot above') - - "⫅": [t: "tập hợp con trên bằng dấu hiệu"] # 0x2ac5 (en: 'subset of above equals sign') - - "⫆": [t: "superset của dấu hiệu trên bằng"] # 0x2ac6 (en: 'superset of above equals sign') - - "⫇": [t: "tập hợp con của toán tử tilde trên"] # 0x2ac7 (en: 'subset of above tilde operator') - - "⫈": [t: "superset của toán tử tilde trên"] # 0x2ac8 (en: 'superset of above tilde operator') - - "⫉": [t: "tập hợp con trên gần như bằng"] # 0x2ac9 (en: 'subset of above almost equal to') - - "⫊": [t: "superset của trên gần như bằng"] # 0x2aca (en: 'superset of above almost equal to') - - "⫋": [t: "tập hợp con trên không bằng"] # 0x2acb (en: 'subset above not equal to') - - "⫌": [t: "superset của ở trên không bằng"] # 0x2acc (en: 'superset of above not equal to') - - "⫍": [t: "khối lượng vận hành hộp mở bên trái"] # 0x2acd (en: 'square left open box operator') - - "⫎": [t: "thao tác hộp mở bên phải"] # 0x2ace (en: 'square right open box operator') - - "⫏": [t: "tập hợp con đóng"] # 0x2acf (en: 'closed subset') - - "⫐": [t: "superset khép kín"] # 0x2ad0 (en: 'closed superset') - - "⫑": [t: "tập hợp con đóng hoặc bằng"] # 0x2ad1 (en: 'closed subset or equal to') - - "⫒": [t: "superset đóng hoặc bằng"] # 0x2ad2 (en: 'closed superset or equal to') - - "⫓": [t: "tập hợp con trên superset"] # 0x2ad3 (en: 'subset above superset') - - "⫔": [t: "superset trên tập hợp con"] # 0x2ad4 (en: 'superset above subset') - - "⫕": [t: "tập hợp con trên tập hợp con"] # 0x2ad5 (en: 'subset above subset') - - "⫖": [t: "superset trên superset"] # 0x2ad6 (en: 'superset above superset') - - "⫗": [t: "superset bên cạnh tập hợp con"] # 0x2ad7 (en: 'superset beside subset') - - "⫘": [t: "superset bên cạnh và tham gia bởi dash với tập hợp con"] # 0x2ad8 (en: 'superset beside and joined by dash with subset') - - "⫙": [t: "yếu tố mở xuống dưới"] # 0x2ad9 (en: 'element of opening downwards') - - "⫚": [t: "pitchfork với tee top"] # 0x2ada (en: 'pitchfork with tee top') - - "⫛": [t: "giao lộ ngang"] # 0x2adb (en: 'transversal intersection') - - "⫝̸": [t: "đi"] # 0x2adc (en: 'forking') - - "⫝": [t: "không hợp lệ"] # 0x2add (en: 'nonforking') - - "⫞": [t: "shrot rời khỏi tack"] # 0x2ade (en: 'shrot left tack') - - "⫟": [t: "ngắn xuống tack"] # 0x2adf (en: 'short down tack') - - "⫠": [t: "ngắn lên tack"] # 0x2ae0 (en: 'short up tack') - - "⫡": [t: "vuông góc với s"] # 0x2ae1 (en: 'perpendicular with s') - - "⫢": [t: "thanh dọc ba vòng phải"] # 0x2ae2 (en: 'vertical bar triple right turnstile') - - "⫣": [t: "thanh gấp đôi rẽ trái"] # 0x2ae3 (en: 'double vertical bar left turnstile') - - "⫤": [t: "thanh dọc gấp đôi rẽ trái"] # 0x2ae4 (en: 'vertical bar double left turnstile') - - "⫥": [t: "thanh dọc theo kép rẽ trái"] # 0x2ae5 (en: 'double vertical bar double left turnstile') - - "⫦": [t: "dash dài từ thành viên bên trái của double dọc"] # 0x2ae6 (en: 'long dash from left member of double vertical') - - "⫧": [t: "tóm lại ngắn với overbar"] # 0x2ae7 (en: 'short down tack with overbar') - - "⫨": [t: "short up tack với underbar"] # 0x2ae8 (en: 'short up tack with underbar') - - "⫩": [t: "short up tack trên ngắn xuống tack"] # 0x2ae9 (en: 'short up tack above short down tack') - - "⫪": [t: "nhân đôi tack xuống"] # 0x2aea (en: 'double down tack') - - "⫫": [t: "nhân đôi tack"] # 0x2aeb (en: 'double up tack') - - "⫬": [t: "cú đánh đôi không ký"] # 0x2aec (en: 'double stroke not sign') - - "⫭": [t: "đảo ngược gạch đôi không ký"] # 0x2aed (en: 'reversed double stroke not sign') - - "⫮": [t: "không phân chia với sự phủ định đảo ngược"] # 0x2aee (en: 'does not divide with reversed negation slash') - - "⫯": [t: "đường thẳng đứng với vòng tròn ở trên"] # 0x2aef (en: 'vertical line with circle above') - - "⫰": [t: "đường thẳng đứng với vòng tròn dưới đây"] # 0x2af0 (en: 'vertical line with circle below') - - "⫱": [t: "xuống tack với vòng tròn bên dưới"] # 0x2af1 (en: 'down tack with circle below') - - "⫲": [t: "song song với gạch ngang"] # 0x2af2 (en: 'parallel with horizontal stroke') - - "⫳": [t: "song song với toán tử tilde"] # 0x2af3 (en: 'parallel with tilde operator') - - "⫴": [t: "triple dọc quan hệ nhị phân thanh dọc"] # 0x2af4 (en: 'triple vertical bar binary relation') - - "⫵": [t: "thanh ba dọc với gạch ngang"] # 0x2af5 (en: 'triple vertical bar with horizontal stroke') - - "⫶": [t: "triple colon toán tử"] # 0x2af6 (en: 'triple colon operator') - - "⫷": [t: "triple lồng ít hơn"] # 0x2af7 (en: 'triple nested less than') - - "⫸": [t: "triple lồng nhau lớn hơn"] # 0x2af8 (en: 'triple nested greater than') - - "⫹": [t: "đường đôi nghiêng ít hơn hoặc bằng"] # 0x2af9 (en: 'double line slanted less than or equal to') - - "⫺": [t: "đường đôi nghiêng lớn hơn hoặc bằng"] # 0x2afa (en: 'double line slanted greater than or equal to') - - "⫻": [t: "triple solidus quan hệ nhị phân"] # 0x2afb (en: 'triple solidus binary relation') - - "⫼": [t: "toán tử thanh dọc lớn"] # 0x2afc (en: 'large triple vertical bar operator') - - "⫽": [t: "toán tử đôi solidus"] # 0x2afd (en: 'double solidus operator') - - "⫾": [t: "thanh dọc trắng"] # 0x2afe (en: 'white vertical bar') - - "⫿": [t: "thanh dọc trắng"] # 0x2aff (en: 'white vertical bar') - - "⬀": [t: "mũi tên trắng đông bắc"] # 0x2b00 (en: 'north east white arrow') - - "⬁": [t: "mũi tên tây bắc"] # 0x2b01 (en: 'north west white arrow') - - "⬂": [t: "mũi tên trắng đông nam"] # 0x2b02 (en: 'south east white arrow') - - "⬃": [t: "mũi tên tây nam trắng"] # 0x2b03 (en: 'south west white arrow') - - "⬄": [t: "mũi tên trắng bên trái"] # 0x2b04 (en: 'left right white arrow') - - "⬅": [t: "mũi tên đen trái"] # 0x2b05 (en: 'leftwards black arrow') - - "⬆": [t: "mũi tên màu đen hướng lên trên"] # 0x2b06 (en: 'upwards black arrow') - - "⬇": [t: "mũi tên đen xuống"] # 0x2b07 (en: 'downwards black arrow') - - "⬈": [t: "mũi tên đen đông bắc"] # 0x2b08 (en: 'north east black arrow') - - "⬉": [t: "mũi tên đen tây bắc"] # 0x2b09 (en: 'north west black arrow') - - "⬊": [t: "mũi tên đen đông nam"] # 0x2b0a (en: 'south east black arrow') - - "⬋": [t: "mũi tên đen tây nam"] # 0x2b0b (en: 'south west black arrow') - - "⬌": [t: "mũi tên đen trái bên trái"] # 0x2b0c (en: 'left right black arrow') - - "⬍": [t: "lên xuống mũi tên đen"] # 0x2b0d (en: 'up down black arrow') - - "⬎": [t: "mũi tên bên phải với đầu xuống"] # 0x2b0e (en: 'rightwards arrow with tip downwards') - - "⬏": [t: "mũi tên bên phải với đầu hướng lên"] # 0x2b0f (en: 'rightwards arrow with tip upwards') - - "⬐": [t: "mũi tên trái với đầu xuống"] # 0x2b10 (en: 'leftwards arrow with tip downwards') - - "⬑": [t: "mũi tên trái với đầu hướng lên"] # 0x2b11 (en: 'leftwards arrow with tip upwards') - - "⬒": [t: "hình vuông với nửa màu đen"] # 0x2b12 (en: 'square with top half black') - - "⬓": [t: "hình vuông với nửa màu đen"] # 0x2b13 (en: 'square with bottom half black') - - "⬔": [t: "hình vuông với đường chéo phía trên bên phải màu đen"] # 0x2b14 (en: 'square with upper right diagonal half black') - - "⬕": [t: "hình vuông với một nửa đường chéo bên trái màu đen"] # 0x2b15 (en: 'square with lower left diagonal half black') - - "⬖": [t: "kim cương với nửa màu đen"] # 0x2b16 (en: 'diamond with left half black') - - "⬗": [t: "kim cương với nửa màu đen"] # 0x2b17 (en: 'diamond with right half black') - - "⬘": [t: "kim cương với nửa màu đen"] # 0x2b18 (en: 'diamond with top half black') - - "⬙": [t: "kim cương với nửa màu đen"] # 0x2b19 (en: 'diamond with bottom half black') - - "⬚": [t: "hộp"] # 0x2b1a (en: 'box') - - "⬛": [t: "quảng trường lớn màu đen"] # 0x2b1b (en: 'black large square') - - "⬜": [t: "quảng trường lớn màu trắng"] # 0x2b1c (en: 'white large square') - - "⬝": [t: "quảng trường rất nhỏ"] # 0x2b1d (en: 'black very small square') - - "⬞": [t: "quảng trường màu trắng rất nhỏ"] # 0x2b1e (en: 'white very small square') - - "⬟": [t: "lầu năm góc đen"] # 0x2b1f (en: 'black pentagon') - - "⬠": [t: "lầu năm góc trắng"] # 0x2b20 (en: 'white pentagon') - - "⬡": [t: "hình lục giác trắng"] # 0x2b21 (en: 'white hexagon') - - "⬢": [t: "hình lục giác đen"] # 0x2b22 (en: 'black hexagon') - - "⬣": [t: "hình lục giác đen ngang"] # 0x2b23 (en: 'horizontal black hexagon') - - "⬤": [t: "vòng tròn lớn màu đen"] # 0x2b24 (en: 'black large circle') - - "⬥": [t: "kim cương trung bình màu đen"] # 0x2b25 (en: 'black medium diamond') - - "⬦": [t: "kim cương trung bình màu trắng"] # 0x2b26 (en: 'white medium diamond') - - "⬧": [t: "black medium lozenge"] # 0x2b27 - - "⬨": [t: "trắng trung bình vô hình"] # 0x2b28 (en: 'white medium lozenge') - - "⬩": [t: "kim cương nhỏ màu đen"] # 0x2b29 (en: 'black small diamond') - - "⬪": [t: "black small lozenge"] # 0x2b2a - - "⬫": [t: "màu trắng hình thoi"] # 0x2b2b (en: 'white small lozenge') - - "⬬": [t: "hình elip ngang màu đen"] # 0x2b2c (en: 'black horizontal ellipse') - - "⬭": [t: "hình elip ngang màu trắng"] # 0x2b2d (en: 'white horizontal ellipse') - - "⬮": [t: "hình elip dọc màu đen"] # 0x2b2e (en: 'black vertical ellipse') - - "⬯": [t: "hình elip dọc trắng"] # 0x2b2f (en: 'white vertical ellipse') - - "⬰": [t: "mũi tên trái với vòng tròn nhỏ"] # 0x2b30 (en: 'left arrow with small circle') - - "⬱": [t: "ba mũi tên trái"] # 0x2b31 (en: 'three leftwards arrows') - - "⬲": [t: "mũi tên trái với circled plus"] # 0x2b32 (en: 'left arrow with circled plus') - - "⬳": [t: "mũi tên vỗ tay dài sang trái"] # 0x2b33 (en: 'long leftwards squiggle arrow') - - "⬴": [t: "bên trái hai mũi tên đầu với gạch thẳng đứng"] # 0x2b34 (en: 'leftwards two headed arrow with vertical stroke') - - "⬵": [t: "lettwards hai mũi tên đầu với gạch dọc"] # 0x2b35 (en: 'lettwards two headed arrow with double vertical stroke') - - "⬶": [t: "bên trái hai mũi tên đầu từ thanh"] # 0x2b36 (en: 'leftwards two headed arrow from bar') - - "⬷": [t: "bên trái hai mũi tên ba đầu"] # 0x2b37 (en: 'leftwards two headed triple dash arrow') - - "⬸": [t: "mũi tên trái với thân chấm chấm"] # 0x2b38 (en: 'leftwards arrow with dotted stem') - - "⬹": [t: "mũi tên trái với đuôi với gạch dọc"] # 0x2b39 (en: 'leftwards arrow with tail with vertical stroke') - - "⬺": [t: "mũi tên trái với đuôi với gạch dọc"] # 0x2b3a (en: 'leftwards arrow with tail with double vertical stroke') - - "⬻": [t: "bên trái hai mũi tên đầu với đuôi"] # 0x2b3b (en: 'leftwards two headed arrow with tail') - - "⬼": [t: "bên trái hai mũi tên đầu với đuôi với gạch thẳng đứng"] # 0x2b3c (en: 'leftwards two headed arrow with tail with vertical stroke') - - "⬽": [t: "bên trái hai mũi tên đầu với đuôi với gạch thẳng đứng"] # 0x2b3d (en: 'leftwards two headed arrow with tail with double vertical stroke') - - "⬾": [t: "mũi tên trái qua x"] # 0x2b3e (en: 'leftwards arrow through x') - - "⬿": [t: "mũi tên sóng hướng trực tiếp bên trái"] # 0x2b3f (en: 'wave arrow pointing directly left') - - "⭀": [t: "bằng dấu hiệu phía trên mũi tên trái"] # 0x2b40 (en: 'equals sign above leftwards arrow') - - "⭁": [t: "toán tử tilde đảo ngược phía trên mũi tên trái"] # 0x2b41 (en: 'reverse tilde operator above leftwards arrow') - - "⭂": [t: "mũi tên trái phía trên đảo ngược gần như bằng"] # 0x2b42 (en: 'leftwards arrow above reverse almost equal to') - - "⭃": [t: "mũi tên phải qua lớn hơn"] # 0x2b43 (en: 'rightwards arrow through greater than') - - "⭄": [t: "mũi tên phải qua superret"] # 0x2b44 (en: 'rightwards arrow through superret') - - "⭅": [t: "mũi tên quadurple trái"] # 0x2b45 (en: 'leftwards quadurple arrow') - - "⭆": [t: "mũi tên tăng gấp bốn lần"] # 0x2b46 (en: 'rightwards quadruple arrow') - - "⭇": [t: "toán tử tilde đảo ngược phía trên mũi tên bên phải"] # 0x2b47 (en: 'reverse tilde operator above rightwards arrow') - - "⭈": [t: "mũi tên bên phải phía trên rerverse gần như bằng"] # 0x2b48 (en: 'rightwards arrow above rerverse almost equal to') - - "⭉": [t: "toán tử tilde phía trên mũi tên trái"] # 0x2b49 (en: 'tilde operator above leftwards arrow') - - "⭊": [t: "mũi tên trái trên gần như bằng"] # 0x2b4a (en: 'leftwards arrow above almost equal to') - - "⭋": [t: "mũi tên trái phía trên toán tử tilde ngược"] # 0x2b4b (en: 'leftwards arrow above reverse tilde operator') - - "⭌": [t: "mũi tên bên phải phía trên toán tử tilde ngược"] # 0x2b4c (en: 'rightwards arrow above reverse tilde operator') - - "⭐": [t: "ngôi sao trung bình màu trắng"] # 0x2b50 (en: 'white medium star') - - "⭑": [t: "ngôi sao nhỏ màu đen"] # 0x2b51 (en: 'black small star') - - "⭒": [t: "ngôi sao nhỏ màu trắng"] # 0x2b52 (en: 'white small star') - - "⭓": [t: "đen bên phải chỉ hình lầu năm góc"] # 0x2b53 (en: 'black right pointing pentagon') - - "⭔": [t: "lầu năm góc bên phải màu trắng"] # 0x2b54 (en: 'white right pointing pentagon') - - "⭕": [t: "vòng tròn lớn nặng"] # 0x2b55 (en: 'heavy large circle') - - "⭖": [t: "oval nặng với hình bầu dục bên trong"] # 0x2b56 (en: 'heavy oval with oval inside') - - "⭗": [t: "vòng tròn nặng với vòng tròn bên trong"] # 0x2b57 (en: 'heavy circle with circle inside') - - "⭘": [t: "vòng tròn nặng"] # 0x2b58 (en: 'heavy circle') - - "⭙": [t: "muối nặng"] # 0x2b59 (en: 'heavy circled saltire') - - "⸀": [t: "điểm thay thế góc phải"] # 0x2e00 (en: 'right angle substitution marker') - - "⸁": [t: "góc bên phải chấm đánh dấu thay thế"] # 0x2e01 (en: 'right angle dotted substitution marker') - - "⸂": [t: "khung thay thế trái"] # 0x2e02 (en: 'left substitution bracket') - - "⸃": [t: "khung thay thế đúng"] # 0x2e03 (en: 'right substitution bracket') - - "⸄": [t: "khung thay thế chấm trái"] # 0x2e04 (en: 'left dotted substitution bracket') - - "⸅": [t: "khung thay thế chấm bên phải"] # 0x2e05 (en: 'right dotted substitution bracket') - - "⸆": [t: "nâng cao điểm đánh dấu nội suy"] # 0x2e06 (en: 'raised interpolation marker') - - "⸇": [t: "nâng cao điểm nội suy chấm"] # 0x2e07 (en: 'raised dotted interpolation marker') - - "⸈": [t: "điểm đánh dấu chuyển vị chấm chấm"] # 0x2e08 (en: 'dotted transposition marker marker') - - "⸉": [t: "khung chuyển vị trái"] # 0x2e09 (en: 'left transposition bracket') - - "⸊": [t: "khung chuyển vị bên phải"] # 0x2e0a (en: 'right transposition bracket') - - "⸋": [t: "quảng trường nâng lên"] # 0x2e0b (en: 'raised square') - - "⸌": [t: "bên trái nâng cao khung thiếu sót"] # 0x2e0c (en: 'left raised omission bracket') - - "⸍": [t: "quyền nâng cao khung thiếu sót"] # 0x2e0d (en: 'right raised omission bracket') - - "⸎": [t: "biên tập coronis"] # 0x2e0e (en: 'editorial coronis') - - "⸏": [t: "đoạn văn"] # 0x2e0f (en: 'paragraphos') - - "⸐": [t: "phân đoạn đoạn văn"] # 0x2e10 (en: 'forked paragraphos') - - "⸑": [t: "đảo ngược các đoạn báo"] # 0x2e11 (en: 'reversed forked paragraphos') - - "⸒": [t: "hypodiastole"] # 0x2e12 - - "⸓": [t: "obelos chấm"] # 0x2e13 (en: 'dotted obelos') - - "⸔": [t: "xuống ở ancora"] # 0x2e14 (en: 'downwards ancora') - - "⸕": [t: "lên cao hơn ancora"] # 0x2e15 (en: 'upwards ancora') - - "⸖": [t: "chấm bên phải góc chỉ"] # 0x2e16 (en: 'dotted right pointing angle') - - "⸗": [t: "double xiên dấu gạch nối"] # 0x2e17 (en: 'double oblique hyphen') - - "⸘": [t: "đảo ngược interrobang"] # 0x2e18 (en: 'inverted interrobang') - - "⸙": [t: "nhánh cọ"] # 0x2e19 (en: 'palm branch') - - "⸚": [t: "hyphen với dieresis"] # 0x2e1a (en: 'hyphen with diaeresis') - - "⸛": [t: "tilde với vòng trên"] # 0x2e1b (en: 'tilde with ring above') - - "⸜": [t: "để lại giá thấp"] # 0x2e1c (en: 'left low paraphrase bracket') - - "⸝": [t: "đóng giá trị thấp phải"] # 0x2e1d (en: 'right low paraphrase bracket') - - "⸞": [t: "tilde với dấu chấm ở trên"] # 0x2e1e (en: 'tilde with dot above') - - "⸟": [t: "tilde với dấu chấm dưới đây"] # 0x2e1f (en: 'tilde with dot below') - - "⸠": [t: "thanh thẳng đứng trái với quill"] # 0x2e20 (en: 'left vertical bar with quill') - - "⸡": [t: "thanh thẳng đứng bên phải với quill"] # 0x2e21 (en: 'right vertical bar with quill') - - "⸢": [t: "đỉnh trái giá đỡ"] # 0x2e22 (en: 'top left half bracket') - - "⸣": [t: "đầu tiên bắt đầu bắt đầu"] # 0x2e23 (en: 'top right half bracket') - - "⸤": [t: "dưới cùng bên trái giá đỡ"] # 0x2e24 (en: 'bottom left half bracket') - - "⸥": [t: "dưới cùng bên phải giá đỡ"] # 0x2e25 (en: 'bottom right half bracket') - - "⸦": [t: "bên trái phía bên bạn khung"] # 0x2e26 (en: 'left sideways u bracket') - - "⸧": [t: "bên phải bên bạn khung"] # 0x2e27 (en: 'right sideways u bracket') - - "⸨": [t: "dấu ngoặc đơn trái"] # 0x2e28 (en: 'left double parentheses') - - "⸩": [t: "dấu ngoặc đơn bên phải"] # 0x2e29 (en: 'right double parentheses') - - "⸪": [t: "hai chấm trên một dấu chấm chấm"] # 0x2e2a (en: 'two dots over one dot punctuation') - - "⸫": [t: "một chấm trên hai dấu chấm câu"] # 0x2e2b (en: 'one dot over two dots punctuation') - - "⸬": [t: "bình phương bốn dấu chấm chấm"] # 0x2e2c (en: 'squared four dot punctuation') - - "⸭": [t: "năm dấu chấm"] # 0x2e2d (en: 'five dot mark') - - "⸮": [t: "dấu ấn câu hỏi"] # 0x2e2e (en: 'reversed question mark') - - "ⸯ": [t: "tilde dọc"] # 0x2e2f (en: 'vertical tilde') - - "⸰": [t: "điểm nhẫn"] # 0x2e30 (en: 'ring point') - - "⸱": [t: "từ chấm tách giữa chấm"] # 0x2e31 (en: 'word seperator middle dot') - - "⸲": [t: "biến dấu phẩy"] # 0x2e32 (en: 'turned comma') - - "⸳": [t: "nâng cao chấm"] # 0x2e33 (en: 'raised dot') - - "⸴": [t: "dấu phẩy lớn lên"] # 0x2e34 (en: 'raised comma') - - "⸵": [t: "biến bán nguyệt"] # 0x2e35 (en: 'turned semicolon') - - "⸶": [t: "dao găm với bảo vệ bên trái"] # 0x2e36 (en: 'dagger with left guard') - - "⸷": [t: "dao găm với bảo vệ bên phải"] # 0x2e37 (en: 'dagger with right guard') - - "⸸": [t: "biến dao găm"] # 0x2e38 (en: 'turned dagger') - - "⸹": [t: "dấu hiệu nửa đầu"] # 0x2e39 (en: 'top half section sign') - - "⸺": [t: "hai em đập"] # 0x2e3a (en: 'two em dash') - - "⸻": [t: "ba em đập"] # 0x2e3b (en: 'three em dash') - - "〃": [t: "ditto mark"] # 0x3003 - - "〈": [t: "khung góc trái"] # 0x3008 (en: 'left angle bracket') - - "〉": [t: "khung góc phải"] # 0x3009 (en: 'right angle bracket') - - "《": [t: "khung góc hai góc"] # 0x300a (en: 'left double angle bracket') - - "》": [t: "khung góc gấp đôi"] # 0x300b (en: 'right double angle bracket') - - "「": [t: "khung góc trái"] # 0x300c (en: 'left corner bracket') - - "」": [t: "khung góc phải"] # 0x300d (en: 'right corner bracket') - - "『": [t: "khung góc trắng"] # 0x300e (en: 'left white corner bracket') - - "』": [t: "khung góc trắng bên phải"] # 0x300f (en: 'right white corner bracket') - - "【": [t: "khung màu đen trái"] # 0x3010 (en: 'left black lenticular bracket') - - "】": [t: "bên phải khung hình dạng thấu kính màu đen"] # 0x3011 (en: 'right black lenticular bracket') - - "〔": [t: "khung vỏ rùa trái"] # 0x3014 (en: 'left tortoise shell bracket') - - "〕": [t: "chân sắc con rùa phải"] # 0x3015 (en: 'right tortoise shell bracket') - - "〖": [t: "khung màu trắng trái"] # 0x3016 (en: 'left white lenticular bracket') - - "〗": [t: "quyền trắng trắng trắng"] # 0x3017 (en: 'right white lenticular bracket') - - "〘": [t: "bên trái khung vỏ rùa trắng"] # 0x3018 (en: 'left white tortoise shell bracket') - - "〙": [t: "bên phải khung vỏ rùa trắng"] # 0x3019 (en: 'right white tortoise shell bracket') - - "〚": [t: "khung vuông màu trắng"] # 0x301a (en: 'left white square bracket') - - "〛": [t: "khung vuông trắng bên phải"] # 0x301b (en: 'right white square bracket') - - "〜": [t: "dash sóng"] # 0x301c (en: 'wave dash') - - "〰": [t: "dấu gạch ngang"] # 0x3030 (en: 'wavy dash') - - "㉈": [t: "số mười vòng trên quảng trường đen"] # 0x3248 (en: 'circled number ten on black square') - - "㉉": [t: "số vòng tròn hai mươi trên quảng trường đen"] # 0x3249 (en: 'circled number twenty on black square') - - "㉊": [t: "số vòng tròn ba mươi trên quảng trường đen"] # 0x324a (en: 'circled number thirty on black square') - - "㉋": [t: "số vòng tròn bốn mươi trên quare blacks"] # 0x324b (en: 'circled number forty on blacks quare') - - "㉌": [t: "số lượng số năm mươi trên quảng trường đen"] # 0x324c (en: 'circled number fifty on black square') - - "㉍": [t: "manh số sáu mươi trên quảng trường đen"] # 0x324d (en: 'circled number sixty on black square') - - "㉎": [t: "số vòng tròn bảy mươi trên quảng trường đen"] # 0x324e (en: 'circled number seventy on black square') - - "㉏": [t: "số được khoanh tròn aty trên quảng trường đen"] # 0x324f (en: 'circled number eighty on black square') - - "㉑": [t: "được khoanh tròn số hai mươi mốt"] # 0x3251 (en: 'circled number twenty one') - - "㉒": [t: "được khoanh tròn số hai mươi hai"] # 0x3252 (en: 'circled number twenty two') - - "㉓": [t: "được khoanh tròn số hai mươi ba"] # 0x3253 (en: 'circled number twenty three') - - "㉔": [t: "được khoanh tròn số hai mươi bốn"] # 0x3254 (en: 'circled number twenty four') - - "㉕": [t: "được khoanh tròn số hai mươi lăm"] # 0x3255 (en: 'circled number twenty five') - - "㉖": [t: "được khoanh tròn số hai mươi sáu"] # 0x3256 (en: 'circled number twenty six') - - "㉗": [t: "được khoanh tròn số hai mươi bảy"] # 0x3257 (en: 'circled number twenty seven') - - "㉘": [t: "được khoanh tròn số hai mươi tám"] # 0x3258 (en: 'circled number twenty eight' GPT-5.4 fixed translation) - - "㉙": [t: "được khoanh tròn số hai mươi chín"] # 0x3259 (en: 'circled number twenty nine') - - "㉚": [t: "được khoanh tròn số ba mươi"] # 0x325a (en: 'circled number thirty' GPT-5.4 fixed translation) - - "㉛": [t: "được khoanh tròn số ba mươi mốt"] # 0x325b (en: 'circled number thirty one' GPT-5.4 fixed translation) - - "㉜": [t: "được khoanh tròn số ba mươi hai"] # 0x325c (en: 'circled number thirty two' GPT-5.4 fixed translation) - - "㉝": [t: "được khoanh tròn số ba mươi ba"] # 0x325d (en: 'circled number thirty three' GPT-5.4 fixed translation) - - "㉞": [t: "được khoanh tròn số ba mươi bốn"] # 0x325e (en: 'circled number thirty four') - - "㉟": [t: "được khoanh tròn số ba mươi lăm"] # 0x325f (en: 'circled number thirty five' GPT-5.4 fixed translation) - - "㊱": [t: "được khoanh tròn số ba mươi sáu"] # 0x32b1 (en: 'circled number thirty six' GPT-5.4 fixed translation) - - "㊲": [t: "được khoanh tròn số ba mươi bảy"] # 0x32b2 (en: 'circled number thirty seven', GPT-5.4 fixed translation) - - "㊳": [t: "được khoanh tròn số ba mươi tám"] # 0x32b3 (en: 'circled number thirty eight', GPT-5.4 fixed translation) - - "㊴": [t: "được khoanh tròn số ba mươi chín"] # 0x32b4 (en: 'circled number thirty nine', GPT-5.4 fixed translation) - - "㊵": [t: "được khoanh tròn số bốn mươi"] # 0x32b5 (en: 'circled number forty', GPT-5.4 fixed translation) - - "㊶": [t: "được khoanh tròn số bốn mươi mốt"] # 0x32b6 (en: 'circled number forty one', GPT-5.4 fixed translation) - - "㊷": [t: "được khoanh tròn số bốn mươi hai"] # 0x32b7 (en: 'circled number forty two', GPT-5.4 fixed translation) - - "㊸": [t: "được khoanh tròn số bốn mươi ba"] # 0x32b8 (en: 'circled number forty three', GPT-5.4 fixed translation) - - "㊹": [t: "được khoanh tròn số bốn mươi bốn"] # 0x32b9 (en: 'circled number forty four', GPT-5.4 fixed translation) - - "㊺": [t: "được khoanh tròn số bốn mươi lăm"] # 0x32ba (en: 'circled number forty five', GPT-5.4 fixed translation) - - "㊻": [t: "được khoanh tròn số bốn mươi sáu"] # 0x32bb (en: 'circled number forty six', GPT-5.4 fixed translation) - - "㊼": [t: "được khoanh tròn số bốn mươi bảy"] # 0x32bc (en: 'circled number forty seven', GPT-5.4 fixed translation) - - "㊽": [t: "được khoanh tròn số bốn mươi tám"] # 0x32bd (en: 'circled number forty eight', GPT-5.4 fixed translation) - - "㊾": [t: "được khoanh tròn số bốn mươi chín"] # 0x32be (en: 'circled number forty nine', GPT-5.4 fixed translation) - - "㊿": [t: "được khoanh tròn số năm mươi"] # 0x32bf (en: 'circled number fifty', GPT-5.4 fixed translation) - - "㋌": [t: "thủy ngân"] # 0x32cc (en: 'mercury') - - "㋍": [t: "ergs"] # 0x32cd - - "㋎": [t: "volt điện tử"] # 0x32ce (en: 'electron volts') - - "㋏": [t: "dấu hiệu trách nhiệm hữu hạn"] # 0x32cf (en: 'limited liability sign') - - "㍱": [t: "hectopascals"] # 0x3371 - - "㍲": [t: "daltons"] # 0x3372 - - "㍳": [t: "các đơn vị thiên văn"] # 0x3373 (en: 'astronomical units') - - "㍴": [t: "thanh"] # 0x3374 (en: 'bars') - - "㍵": [t: "o v"] # 0x3375 - - "㍶": [t: "parsecs"] # 0x3376 - - "㍷": [t: "thập phân"] # 0x3377 (en: 'decimeters') - - "㍸": [t: "decimeter bình phương"] # 0x3378 (en: 'decimeters squared') - - "㍹": [t: "decimeter khối"] # 0x3379 (en: 'decimeters cubed') - - "㍺": [t: "đơn vị công cụ"] # 0x337a (en: 'instrumental units') - - "㎀": [t: "picoamp"] # 0x3380 (en: 'picoamps') - - "㎁": [t: "nanoamp"] # 0x3381 (en: 'nanoamps') - - "㎂": [t: "microamp"] # 0x3382 (en: 'microamps') - - "㎃": [t: "milliamps"] # 0x3383 - - "㎄": [t: "kiloamp"] # 0x3384 (en: 'kiloamps') - - "㎅": [t: "kilobyte"] # 0x3385 (en: 'kilobytes') - - "㎆": [t: "megabyte"] # 0x3386 (en: 'megabytes') - - "㎇": [t: "gigabyte"] # 0x3387 (en: 'gigabytes') - - "㎈": [t: "calo"] # 0x3388 (en: 'calories') - - "㎉": [t: "kilocalories"] # 0x3389 - - "㎊": [t: "picofarads"] # 0x338a - - "㎋": [t: "nanofarads"] # 0x338b - - "㎌": [t: "microfarads"] # 0x338c - - "㎍": [t: "micrograms"] # 0x338d - - "㎎": [t: "miligam"] # 0x338e (en: 'milligrams') - - "㎏": [t: "kilôgam"] # 0x338f (en: 'kilograms') - - "㎐": [t: "hertz"] # 0x3390 - - "㎑": [t: "kilohertz"] # 0x3391 - - "㎒": [t: "megahertz"] # 0x3392 - - "㎓": [t: "gigahertz"] # 0x3393 - - "㎔": [t: "terahertz"] # 0x3394 - - "㎕": [t: "microliter"] # 0x3395 (en: 'microliters') - - "㎖": [t: "millileter"] # 0x3396 (en: 'millileters') - - "㎗": [t: "deciliter"] # 0x3397 (en: 'deciliters') - - "㎘": [t: "kiloliter"] # 0x3398 (en: 'kiloliters') - - "㎙": [t: "femtometer"] # 0x3399 (en: 'femtometers') - - "㎚": [t: "nanomet"] # 0x339a (en: 'nanometers') - - "㎛": [t: "micromet"] # 0x339b (en: 'micrometers') - - "㎜": [t: "milimet"] # 0x339c (en: 'millimeters') - - "㎝": [t: "centimet"] # 0x339d (en: 'centimeters') - - "㎞": [t: "km"] # 0x339e (en: 'kilometers') - - "㎟": [t: "bình phương milimet"] # 0x339f (en: 'millimeters squared') - - "㎠": [t: "centimet bình phương"] # 0x33a0 (en: 'centimeters squared') - - "㎡": [t: "mét bình phương"] # 0x33a1 (en: 'meters squared') - - "㎢": [t: "km bình phương"] # 0x33a2 (en: 'kilometers squared') - - "㎣": [t: "milimet khối"] # 0x33a3 (en: 'millimeters cubed') - - "㎤": [t: "centimet hình khối"] # 0x33a4 (en: 'centimeters cubed') - - "㎥": [t: "mét khối"] # 0x33a5 (en: 'meters cubed') - - "㎦": [t: "km khối"] # 0x33a6 (en: 'kilometers cubed') - - "㎧": [t: "mét mỗi giây"] # 0x33a7 (en: 'meters per second') - - "㎨": [t: "mét mỗi giây bình phương"] # 0x33a8 (en: 'meters per second squared') - - "㎩": [t: "pascals"] # 0x33a9 - - "㎪": [t: "kilopascals"] # 0x33aa - - "㎫": [t: "megapascals"] # 0x33ab - - "㎬": [t: "gigapascals"] # 0x33ac - - "㎭": [t: "rads"] # 0x33ad - - "㎮": [t: "rads mỗi giây"] # 0x33ae (en: 'rads per second') - - "㎯": [t: "rads trên bình phương thứ hai"] # 0x33af (en: 'rads per second squared') - - "㎰": [t: "picoseconds"] # 0x33b0 - - "㎱": [t: "nanoseconds"] # 0x33b1 - - "㎲": [t: "micro giây"] # 0x33b2 (en: 'microseconds') - - "㎳": [t: "mili giây"] # 0x33b3 (en: 'milliseconds') - - "㎴": [t: "picovolts"] # 0x33b4 - - "㎵": [t: "nanovolts"] # 0x33b5 - - "㎶": [t: "microvolts"] # 0x33b6 - - "㎷": [t: "millivolts"] # 0x33b7 - - "㎸": [t: "kilovolts"] # 0x33b8 - - "㎹": [t: "megavolts"] # 0x33b9 - - "㎺": [t: "picowatt"] # 0x33ba (en: 'picowatts') - - "㎻": [t: "nanowatt"] # 0x33bb (en: 'nanowatts') - - "㎼": [t: "microwatt"] # 0x33bc (en: 'microwatts') - - "㎽": [t: "milliwatts"] # 0x33bd - - "㎾": [t: "kilowatt"] # 0x33be (en: 'kilowatts') - - "㎿": [t: "megawatt"] # 0x33bf (en: 'megawatts') - - "㏀": [t: "kilo-ohms"] # 0x33c0 - - "㏁": [t: "megaohms"] # 0x33c1 - - "㏂": [t: "attometer"] # 0x33c2 (en: 'attometers') - - "㏃": [t: "becquerels"] # 0x33c3 - - "㏄": [t: "centimet khối"] # 0x33c4 (en: 'cubic centimeters') - - "㏅": [t: "nến"] # 0x33c5 (en: 'candelas') - - "㏆": [t: "coulomb mỗi kg"] # 0x33c6 (en: 'coulombs per kilogram') - - "㏇": [t: "lượng máu tim bơm ra"] # 0x33c7 (en: 'cardiac output') - - "㏈": [t: "decibel"] # 0x33c8 (en: 'decibels') - - "㏉": [t: "grays"] # 0x33c9 - - "㏊": [t: "ha"] # 0x33ca (en: 'hectares') - - "㏋": [t: "mã lực"] # 0x33cb (en: 'horsepower') - - "㏌": [t: "inch"] # 0x33cc (en: 'inches') - - "㏍": [t: "kilokelvins"] # 0x33cd - - "㏎": [t: "km"] # 0x33ce (en: 'kilometers') - - "㏏": [t: "nút thắt"] # 0x33cf (en: 'knots') - - "㏐": [t: "lumens"] # 0x33d0 - - "㏑": [t: "nhật ký tự nhiên"] # 0x33d1 (en: 'natural log') - - "㏒": [t: "logarit"] # 0x33d2 (en: 'logarithm') - - "㏓": [t: "lux"] # 0x33d3 - - "㏔": [t: "millibarns"] # 0x33d4 - - "㏕": [t: "nhà máy"] # 0x33d5 (en: 'mills') - - "㏖": [t: "nốt ruồi"] # 0x33d6 (en: 'moles') - - "㏗": [t: "p h"] # 0x33d7 - - "㏘": [t: "buông điện"] # 0x33d8 (en: 'picometers') - - "㏙": [t: "phần triệu"] # 0x33d9 (en: 'parts per million') - - "㏚": [t: "petaroentgens"] # 0x33da - - "㏛": [t: "steradians"] # 0x33db - - "㏜": [t: "sieverts"] # 0x33dc - - "㏝": [t: "webers"] # 0x33dd - - "㏞": [t: "volt mỗi mét"] # 0x33de (en: 'volts per meter') - - "㏟": [t: "amps mỗi mét"] # 0x33df (en: 'amps per meter') - - "㏿": [t: "gallon"] # 0x33ff (en: 'gallons') - - "": [t: "bằng với mũ bên dưới"] # 0xe900 (en: 'equals with hat below') - - "": [t: "bằng với cộng với ở trên"] # 0xe901 (en: 'equals with plus above') - - "⩲": [t: "bằng với cộng với ở trên"] # 0x2a72 (en: 'equals with plus above') - - "": [t: "bằng với cộng với bên dưới"] # 0xe902 (en: 'equals with plus below') - - "⩱": [t: "bằng với cộng với bên dưới"] # 0x2a71 (en: 'equals with plus below') - - "": [t: "tilde với cộng với ở trên"] # 0xe903 (en: 'tilde with plus above') - - "⨦": [t: "tilde với cộng với ở trên"] # 0x2a26 (en: 'tilde with plus above') - - "": [t: "tilde với cộng với bên dưới"] # 0xe904 (en: 'tilde with plus below') - - "⨤": [t: "tilde với cộng với bên dưới"] # 0x2a24 (en: 'tilde with plus below') - - "": [t: "bằng gấp đôi trên lớn hơn"] # 0xe908 (en: 'equal double over greater than') - - "": [t: "bằng gấp đôi so với ít hơn"] # 0xe909 (en: 'equal double over less than') - - "⪙": [t: "bằng gấp đôi so với ít hơn"] # 0x2a99 (en: 'equal double over less than') - - "": [t: "chứa hoặc bằng"] # 0xe90a (en: 'contains or equal to') - - "⋽": [t: "chứa hoặc bằng"] # 0x22fd (en: 'contains or equal to') - - "": [t: "superset của hoặc bằng"] # 0xe90b (en: 'superset of or equal to') - - "": [t: "tập hợp con hoặc bằng"] # 0xe90c (en: 'subset of or equal to') - - "": [t: "bằng nhau hơn ít hơn"] # 0xe90d (en: 'equal over less than') - - "": [t: "yếu tố hoặc bằng"] # 0xe912 (en: 'element of or equal to') - - "⋷": [t: "yếu tố hoặc bằng"] # 0x22f7 (en: 'element of or equal to') - - "": [t: "bằng hoặc lớn hơn"] # 0xe913 (en: 'equal to or greater than') - - "⪚": [t: "bằng hoặc lớn hơn"] # 0x2a9a (en: 'equal to or greater than') - - "": [t: "superset gần đúng của"] # 0xe914 (en: 'approximate superset of') - - "⫈": [t: "superset gần đúng của"] # 0x2ac8 (en: 'approximate superset of') - - "": [t: "tập hợp con gần đúng của"] # 0xe915 (en: 'approximate subset of') - - "⫇": [t: "tập hợp con gần đúng của"] # 0x2ac7 (en: 'approximate subset of') - - "": [t: "superset của với dot bao gồm như mối quan hệ phụ"] # 0xe916 (en: 'superset of with dot includes as sub relation') - - "⪾": [t: "superset của với dot bao gồm như mối quan hệ phụ"] # 0x2abe (en: 'superset of with dot includes as sub relation') - - "": [t: "tập hợp con với dot được bao gồm trong mối quan hệ phụ"] # 0xe917 (en: 'subset of with dot is included in as sub relation') - - "⪽": [t: "tập hợp con với dot được bao gồm trong mối quan hệ phụ"] # 0x2abd (en: 'subset of with dot is included in as sub relation') - - "": [t: "bằng với dấu chấm bên dưới"] # 0xe918 (en: 'equal with dot below') - - "⩦": [t: "bằng với dấu chấm bên dưới"] # 0x2a66 (en: 'equal with dot below') - - "": [t: "bên trái chấm trên trừ chấm bên phải"] # 0xe919 (en: 'left dot over minus over right dot') - - "": [t: "dấu chấm bên phải trên trừ chấm bên trái"] # 0xe91a (en: 'right dot over minus over left dot') - - "": [t: "gần như bằng trừ"] # 0xe91f (en: 'almost equal to minus') - - "": [t: "cúp vuông đôi"] # 0xe920 (en: 'double square cup') - - "": [t: "double square squalase"] # 0xe921 (en: 'double square cap') - - "": [t: "ít hơn bằng hoặc lớn hơn"] # 0xe922 (en: 'less than equal to or greater than') - - "": [t: "tilde với dấu chấm"] # 0xe924 (en: 'tilde with dot') - - "⩪": [t: "tilde với dấu chấm"] # 0x2a6a (en: 'tilde with dot') - - "": [t: "tilde với hai chấm"] # 0xe925 (en: 'tilde with two dots') - - "": [t: "nhỏ hơn lớn hơn hoặc bằng"] # 0xe926 (en: 'less than greater than or equal to') - - "⪑": [t: "nhỏ hơn lớn hơn hoặc bằng"] # 0x2a91 (en: 'less than greater than or equal to') - - "": [t: "lớn hơn ít hơn hoặc bằng"] # 0xe927 (en: 'greater than less than or equal to') - - "⪒": [t: "lớn hơn ít hơn hoặc bằng"] # 0x2a92 (en: 'greater than less than or equal to') - - "": [t: "tương đương hoặc ít hơn"] # 0xe928 (en: 'equivalent to or less than') - - "⪝": [t: "tương đương hoặc ít hơn"] # 0x2a9d (en: 'equivalent to or less than') - - "": [t: "tương đương hoặc lớn hơn"] # 0xe929 (en: 'equivalent to or greater than') - - "": [t: "toán tử hộp mở"] # 0xe92a (en: 'left open box operator') - - "": [t: "toán tử hộp mở bên phải"] # 0xe92b (en: 'right open box operator') - - "": [t: "giống hệt với dấu chấm"] # 0xe92c (en: 'identical to with dot') - - "": [t: "lớn hơn bằng hoặc nhỏ hơn"] # 0xe92d (en: 'greater than equal to or less than') - - "": [t: "nhà điều hành thanh"] # 0xe92e (en: 'bar operator') - - "": [t: "nhà điều hành thanh đôi"] # 0xe92f (en: 'double bar operator') - - "": [t: "nhà điều hành ba thanh"] # 0xe930 (en: 'triple bar operator') - - "": [t: "nhỏ hơn hoặc xấp xỉ bằng"] # 0xe932 (en: 'less than or approximately equal to') - - "": [t: "lớn hơn hoặc xấp xỉ bằng"] # 0xe933 (en: 'greater than or approximately equal to') - - "": [t: "lồng ít hơn"] # 0xe936 (en: 'nested less than') - - "⪡": [t: "lồng ít hơn"] # 0x2aa1 (en: 'nested less than') - - "": [t: "lồng nhau lớn hơn"] # 0xe937 (en: 'nested greater than') - - "⪢": [t: "lồng nhau lớn hơn"] # 0x2aa2 (en: 'nested greater than') - - "": [t: "trước hoặc tương đương với"] # 0xe93a (en: 'precedes or equivalent to') - - "": [t: "thành công hoặc tương đương với"] # 0xe93b (en: 'succeeds or equivalent to') - - "": [t: "đi trước bằng bằng nhau"] # 0xe940 (en: 'precedes over equal') - - "": [t: "thành công quá bình đẳng"] # 0xe941 (en: 'succeeds over equal') - - "": [t: "ít bằng nhau hơn nghiêng lớn hơn"] # 0xe942 (en: 'less equal slanted greater') - - "": [t: "lớn hơn bằng ít hơn"] # 0xe943 (en: 'greater equal slanted less') - - "": [t: "hài lòng bởi"] # 0xe948 (en: 'satisfied by') - - "": [t: "lười biếng s"] # 0xe949 (en: 'lazy s') - - "": [t: "không khẳng định"] # 0xe94a (en: 'not assertion') - - "": [t: "gấp đôi bằng nhau"] # 0xe94b (en: 'double equal') - - "⩵": [t: "gấp đôi bằng nhau"] # 0x2a75 (en: 'double equal') - - "": [t: "triple bằng nhau"] # 0xe94c (en: 'triple equal') - - "": [t: "quy tắc bị trì hoãn"] # 0xe94d (en: 'rule delayed') - - "⧴": [t: "quy tắc bị trì hoãn"] # 0x29f4 (en: 'rule delayed') - - "": [t: "phân định bí danh"] # 0xe94e (en: 'alias delimiter') - - "": [t: "nhóm con bình thường của thanh"] # 0xe950 (en: 'normal subgroup of with bar') - - "⧏": [t: "nhóm con bình thường của thanh"] # 0x29cf (en: 'normal subgroup of with bar') - - "": [t: "chứa như phân nhóm bình thường với thanh"] # 0xe951 (en: 'contains as normal subgroup with bar') - - "⧐": [t: "chứa như phân nhóm bình thường với thanh"] # 0x29d0 (en: 'contains as normal subgroup with bar') - - "": [t: "vòng ngụ ý"] # 0xe954 (en: 'round implies') - - "⥰": [t: "vòng ngụ ý"] # 0x2970 (en: 'round implies') - - "": [t: "nụ cười dưới quán bar"] # 0xe955 (en: 'smile under bar') - - "": [t: "cau mày trên quán bar"] # 0xe956 (en: 'frown over bar') - - "": [t: "superset của hoặc gần như bằng"] # 0xe957 (en: 'superset of or almost equal to') - - "": [t: "tập hợp con hoặc gần như bằng"] # 0xe958 (en: 'subset of or almost equal to') - - "": [t: "lớn hơn gần như bằng hoặc ít hơn"] # 0xe959 (en: 'greater than almost equal to or less than') - - "": [t: "ít hơn gần như bằng hoặc lớn hơn"] # 0xe95a (en: 'less than almost equal or greater than') - - "": [t: "gấp đôi logic hoặc"] # 0xe95c (en: 'double logical or') - - "⩔": [t: "gấp đôi logic hoặc"] # 0x2a54 (en: 'double logical or') - - "": [t: "gấp đôi logic và"] # 0xe95d (en: 'double logical and') - - "⩓": [t: "gấp đôi logic và"] # 0x2a53 (en: 'double logical and') - - "": [t: "logic hoặc với thanh đôi dưới đây"] # 0xe95e (en: 'logical or with double bar below') - - "": [t: "logic hoặc với thanh dưới đây"] # 0xe95f (en: 'logical or with bar below') - - "": [t: "gần như bằng nhau trên"] # 0xe962 (en: 'almost equal over equal') - - "": [t: "hình tam giác trỏ trái với thanh chia đôi"] # 0xe964 (en: 'left pointing triangle with bisecting bar') - - "": [t: "tam giác chỉ bên phải với thanh chia đôi"] # 0xe965 (en: 'right pointing triangle with bisecting bar') - - "": [t: "bằng với dòng trên cùng chấm"] # 0xe966 (en: 'equals with dotted top line') - - "": [t: "đi trước với đại tràng"] # 0xe967 (en: 'precedes with colon') - - "": [t: "thành công với đại tràng"] # 0xe968 (en: 'succeeds with colon') - - "": [t: "nhỏ hơn hoặc bằng nghiêng"] # 0xe969 (en: 'smaller than or equal slanted') - - "": [t: "lớn hơn hoặc bằng nghiêng"] # 0xe96a (en: 'larger than or equal slanted') - - "": [t: "lồng nhau rất ít hơn"] # 0xe96b (en: 'nested very much less than') - - "": [t: "lồng nhau rất lớn hơn nhiều so với"] # 0xe96c (en: 'nested very much greater than') - - "": [t: "sự khác biệt giữa biến thể"] # 0xe96d (en: 'difference between variant') - - "⪮": [t: "sự khác biệt giữa biến thể"] # 0x2aae (en: 'difference between variant') - - "": [t: "ít hơn so với lớp phủ"] # 0xe96e (en: 'less than greater than overlay') - - "⪤": [t: "ít hơn so với lớp phủ"] # 0x2aa4 (en: 'less than greater than overlay') - - "": [t: "logic hoặc logic và lớp phủ"] # 0xe96f (en: 'logical or logical and overlay') - - "": [t: "superset trên superset"] # 0xe970 (en: 'superset over superset') - - "⫖": [t: "superset trên superset"] # 0x2ad6 (en: 'superset over superset') - - "": [t: "tập hợp con qua tập hợp con"] # 0xe971 (en: 'subset over subset') - - "⫕": [t: "tập hợp con qua tập hợp con"] # 0x2ad5 (en: 'subset over subset') - - "": [t: "superset trên tập hợp con"] # 0xe972 (en: 'superset over subset') - - "⫔": [t: "superset trên tập hợp con"] # 0x2ad4 (en: 'superset over subset') - - "": [t: "tập hợp con trên superset"] # 0xe973 (en: 'subset over superset') - - "⫓": [t: "tập hợp con trên superset"] # 0x2ad3 (en: 'subset over superset') - - "": [t: "thanh ba thẳng đứng"] # 0xe979 (en: 'triple vertical bar') - - "": [t: "ghép các chấm dọc"] # 0xe97a (en: 'paired quadruple vertical dots') - - "": [t: "vuông góc trên thanh"] # 0xe97b (en: 'perpendicular over bar') - - "⫨": [t: "vuông góc trên thanh"] # 0x2ae8 (en: 'perpendicular over bar') - - "": [t: "bar let -bretstile bar du trường"] # 0xe97c (en: 'left turnstile double vertical bar') - - "": [t: "double bên trái thanh dọc kép"] # 0xe97d (en: 'double left turnstile double vertical bar') - - "": [t: "vuông góc trên đảo ngược vuông góc"] # 0xe97e (en: 'perpendicular over inverted perpendicular') - - "": [t: "double bên trái thanh dọc"] # 0xe97f (en: 'double left turnstile vertical bar') - - "⫤": [t: "double bên trái thanh dọc"] # 0x2ae4 (en: 'double left turnstile vertical bar') - - "": [t: "góc hình cầu mở ra"] # 0xe980 (en: 'spherical angle opening up') - - "": [t: "chém đôi"] # 0xe981 (en: 'double slash') - - "": [t: "góc vuông với góc"] # 0xe982 (en: 'right angle with corner') - - "": [t: "bao quanh thanh dọc"] # 0xe984 (en: 'circled vertical bar') - - "⦶": [t: "bao quanh thanh dọc"] # 0x29b6 (en: 'circled vertical bar') - - "": [t: "dấu hiệu phân chia vòng tròn"] # 0xe985 (en: 'circled division sign') - - "⨸": [t: "dấu hiệu phân chia vòng tròn"] # 0x2a38 (en: 'circled division sign') - - "": [t: "solidus đứt nét"] # 0xe986 (en: 'dashed solidus') - - "": [t: "backslash bị đứt nét"] # 0xe987 (en: 'dashed backslash') - - "": [t: "đường giữa đứt"] # 0xe988 (en: 'dashed mid line') - - "": [t: "thanh dọc đứt"] # 0xe989 (en: 'dashed vertical bar') - - "": [t: "vuông góc với s"] # 0xe98a (en: 'perpendicular with s') - - "": [t: "góc với s"] # 0xe98b (en: 'angle with s') - - "": [t: "góc hình cầu mở bên trái"] # 0xe98c (en: 'spherical angle opening left') - - "": [t: "góc mở bên trái"] # 0xe98d (en: 'angle opening left') - - "": [t: "thanh dọc với móc đôi"] # 0xe98e (en: 'vertical bar with double hook') - - "⥾": [t: "thanh dọc với móc đôi"] # 0x297e (en: 'vertical bar with double hook') - - "": [t: "toán tử chấm trung bình gốc tự do"] # 0xe98f (en: 'medium dot operator free radical') - - "": [t: "trắng lên hình tam giác phía trên thanh"] # 0xe990 (en: 'white up pointing triangle above bar') - - "": [t: "giống hệt nhau và song song với"] # 0xe991 (en: 'identical and parallel to') - - "": [t: "smash sản phẩm"] # 0xe992 (en: 'smash product') - - "⨳": [t: "smash sản phẩm"] # 0x2a33 (en: 'smash product') - - "": [t: "toán tử ba thanh với thanh ngang"] # 0xe993 (en: 'triple bar operator with horizontal bar') - - "": [t: "giống hệt với cắt đôi"] # 0xe994 (en: 'identical to with double slash') - - "⧥": [t: "giống hệt với cắt đôi"] # 0x29e5 (en: 'identical to with double slash') - - "": [t: "triple crossed bars"] # 0xe995 - - "": [t: "thanh dọc trên vòng tròn"] # 0xe996 (en: 'vertical bar over circle') - - "": [t: "tỷ lệ dọc so với"] # 0xe997 (en: 'vertical proportional to') - - "": [t: "đen quý trước mặt trăng"] # 0xe998 (en: 'black last quarter moon') - - "": [t: "mặt trăng quý đầu tiên màu đen"] # 0xe999 (en: 'black first quarter moon') - - "": [t: "sóng sin âm"] # 0xe9a0 (en: 'negative sine wave') - - "": [t: "dấu ngoặc đơn"] # 0xe9a1 (en: 'parenthesized dot') - - "": [t: "dấu ngoặc đơn"] # 0xe9a2 (en: 'parens') - - "": [t: "nụ cười trắng"] # 0xe9a3 (en: 'white smile') - - "": [t: "trắng cau mày"] # 0xe9a4 (en: 'white frown') - - "": [t: "hình lục giác"] # 0xe9a5 (en: 'hexagon') - - "": [t: "tương đương với hơn cộng"] # 0xe9a6 (en: 'equivalent to over plus') - - "": [t: "cộng với quá mức tương đương với"] # 0xe9a7 (en: 'plus over equivalent to') - - "": [t: "giao lộ serifs"] # 0xe9b0 (en: 'intersection serifs') - - "": [t: "liên minh serifs"] # 0xe9b1 (en: 'union serifs') - - "": [t: "giao lộ vuông serifs"] # 0xe9b2 (en: 'square intersection serifs') - - "": [t: "square union serifs"] # 0xe9b3 - - "": [t: "trước tương đương hoặc thành công"] # 0xe9e0 (en: 'precedes equivalent to or succeeds') - - "": [t: "thành công tương đương với hoặc trước"] # 0xe9e1 (en: 'succeeds equivalent to or precedes') - - "": [t: "đi trước gần như bằng hoặc thành công"] # 0xe9e2 (en: 'precedes almost equal to or succeeds') - - "": [t: "thành công gần như bằng hoặc trước"] # 0xe9e3 (en: 'succeeds almost equal to or precedes') - - "": [t: "ít hơn tương đương với hoặc lớn hơn"] # 0xe9f0 (en: 'less than equivalent to or greater than') - - "": [t: "lớn hơn tương đương với hoặc ít hơn"] # 0xe9f1 (en: 'greater than equivalent to or less than') - - "": [t: "không phải là ít hơn nhiều"] # 0xea00 (en: 'not vert much less than') - - "": [t: "không phải là lớn hơn nhiều so với"] # 0xea01 (en: 'not vert much greater than') - - "": [t: "không ít hơn nhiều biến thể"] # 0xea02 (en: 'not much less than variant') - - "": [t: "không lớn hơn nhiều so với biến thể"] # 0xea03 (en: 'not much greater than variant') - - "": [t: "ít vert không bằng kép bằng"] # 0xea04 (en: 'less vert not double equals') - - "": [t: "gt vert không bằng kép"] # 0xea05 (en: 'gt vert not double equals') - - "": [t: "không ít hơn hoặc bằng"] # 0xea06 (en: 'not less than or equal to') - - "": [t: "không lớn hơn hoặc bằng"] # 0xea07 (en: 'not greater than or equal to') - - "": [t: "không bằng cũng không ít hơn"] # 0xea09 (en: 'neither equal to nor less than') - - "": [t: "không chứa hoặc bằng"] # 0xea0a (en: 'does not contain or equal to') - - "": [t: "không phải siêu sao cũng không bằng"] # 0xea0b (en: 'neither superset of nor equal to') - - "": [t: "không phải tập hợp con cũng không bằng"] # 0xea0c (en: 'neither subset of nor equal to') - - "": [t: "đảo ngược solidus tập hợp con"] # 0xea0d (en: 'reverse solidus subset') - - "": [t: "không bằng cũng không lớn hơn"] # 0xea0e (en: 'neither equal to nor greater than') - - "": [t: "không trừ đi toán tử tilde"] # 0xea0f (en: 'not minus tilde operator') - - "": [t: "không bằng cũng không ít hơn"] # 0xea10 (en: 'neither equal to nor less than') - - "": [t: "không phải nhà điều hành tilde"] # 0xea11 (en: 'not tilde operator') - - "": [t: "không phải là yếu tố hoặc bằng"] # 0xea12 (en: 'not element of or equal to') - - "": [t: "không bằng cũng không lớn hơn"] # 0xea13 (en: 'neither equal to nor greater than') - - "": [t: "không gần như bằng nhau"] # 0xea14 (en: 'not almost equal') - - "": [t: "không thành công tương tự"] # 0xea15 (en: 'not succeeds similar') - - "": [t: "ít hơn hoặc nghiêng bằng với dấu gạch chéo"] # 0xea16 (en: 'less than or slanted equal to with slash') - - "": [t: "lớn hơn hoặc nghiêng bằng với dấu gạch chéo"] # 0xea17 (en: 'greater than or slanted equal to with slash') - - "": [t: "superset solidus"] # 0xea1a - - "": [t: "không chứa"] # 0xea1b (en: 'does not contain') - - "": [t: "không ít hơn hoặc bằng"] # 0xea1d (en: 'not less than or equal to') - - "": [t: "không lớn hơn hoặc bằng"] # 0xea1e (en: 'not greater than or equal to') - - "": [t: "không gần như bằng trừ"] # 0xea1f (en: 'not almost equal to minus') - - "": [t: "tiêu cực đặt thành viên chấm ở trên"] # 0xea22 (en: 'negated set membership dot above') - - "": [t: "không góc góc"] # 0xea2c (en: 'not vert angle') - - "": [t: "không song song nghiêng"] # 0xea2d (en: 'not parallel slanted') - - "": [t: "không phải nhà điều hành thanh"] # 0xea2e (en: 'not bar operator') - - "": [t: "không phải nhà điều hành thanh đôi"] # 0xea2f (en: 'not double bar operator') - - "": [t: "không phải nhà điều hành ba thanh"] # 0xea30 (en: 'not triple bar operator') - - "": [t: "ít hơn nhưng không xấp xỉ bằng"] # 0xea32 (en: 'less than but not approximately equal to') - - "⪉": [t: "ít hơn nhưng không xấp xỉ bằng"] # 0x2a89 (en: 'less than but not approximately equal to') - - "": [t: "lớn hơn nhưng không xấp xỉ bằng"] # 0xea33 (en: 'greater than but not approximately equal to') - - "⪊": [t: "lớn hơn nhưng không xấp xỉ bằng"] # 0x2a8a (en: 'greater than but not approximately equal to') - - "": [t: "nhỏ hơn hoặc không bằng"] # 0xea34 (en: 'less than or not equal to') - - "": [t: "lớn hơn hoặc không bằng"] # 0xea35 (en: 'greater than or not equal to') - - "": [t: "không lồng nhau ít hơn"] # 0xea36 (en: 'not nested less than') - - "": [t: "không lồng nhau lớn hơn"] # 0xea37 (en: 'not nested greater than') - - "": [t: "không ít hơn nhiều"] # 0xea38 (en: 'not much less than') - - "": [t: "không lớn hơn nhiều so với"] # 0xea39 (en: 'not much greater than') - - "": [t: "đi trước nhưng không tương đương với"] # 0xea3a (en: 'precedes but not equivalent to') - - "": [t: "thành công nhưng không tương đương với"] # 0xea3b (en: 'succeeds but not equivalent to') - - "": [t: "đi trước nhưng không bằng"] # 0xea3c (en: 'precedes but not equal to') - - "": [t: "thành công nhưng không bằng"] # 0xea3d (en: 'succeeds but not equal to') - - "": [t: "không bằng hoặc trước"] # 0xea3e (en: 'does not equal or precede') - - "": [t: "không bằng hoặc thành công"] # 0xea3f (en: 'does not equal or succeed') - - "": [t: "đi trước nhưng không bằng"] # 0xea40 (en: 'precedes but not equal to') - - "⪵": [t: "đi trước nhưng không bằng"] # 0x2ab5 (en: 'precedes but not equal to') - - "": [t: "thành công nhưng không bằng"] # 0xea41 (en: 'succeeds but not equal to') - - "⪶": [t: "thành công nhưng không bằng"] # 0x2ab6 (en: 'succeeds but not equal to') - - "": [t: "không phải là tập hợp con cũng không bằng"] # 0xea42 (en: 'not subset of nor equal to') - - "": [t: "không phải siêu sao cũng không bằng"] # 0xea43 (en: 'not superset of nor equal to') - - "": [t: "tập hợp con hoặc không bằng"] # 0xea44 (en: 'subset of or not equal to') - - "": [t: "superset của hoặc không bằng"] # 0xea45 (en: 'superset of or not equal to') - - "": [t: "không phải là tập hợp con cũng không bằng"] # 0xea46 (en: 'not subset of nor equal to') - - "": [t: "không phải siêu sao cũng không bằng"] # 0xea47 (en: 'not superset of nor equal to') - - "": [t: "không nhỏ hơn ba"] # 0xea48 (en: 'not triple less than') - - "": [t: "không lớn hơn gấp ba lần"] # 0xea49 (en: 'not triple greater than') - - "": [t: "không đi trước bằng"] # 0xea4c (en: 'not precedes equals') - - "": [t: "không thành công bằng nhau"] # 0xea4d (en: 'not succeeds equals') - - "": [t: "không phải nhóm con bình thường của thanh"] # 0xea50 (en: 'not normal subgroup of with bar') - - "": [t: "không chứa như phân nhóm bình thường với thanh"] # 0xea51 (en: 'does not contain as normal subgroup with bar') - - "": [t: "không phải là sự khác biệt giữa"] # 0xea52 (en: 'not difference between') - - "": [t: "không tương đương về mặt hình học"] # 0xea53 (en: 'not geometrically equivalent to') - - "": [t: "không phải là tương tự"] # 0xea54 (en: 'not vert similar') - - "": [t: "không bằng hoặc tương tự"] # 0xea55 (en: 'not equal or similar') - - "": [t: "không gần đúng"] # 0xea56 (en: 'not vert approximate') - - "": [t: "không xấp xỉ giống hệt nhau"] # 0xea57 (en: 'not approximately identical to') - - "": [t: "không gập ghềnh bằng nhau"] # 0xea58 (en: 'not bumpy equals') - - "": [t: "không gập ghềnh bằng nhau"] # 0xea59 (en: 'not bumpy single equals') - - "": [t: "không phải dấu chấm bằng nhau"] # 0xea5a (en: 'not equal dot') - - "": [t: "đảo ngược không tương đương"] # 0xea5b (en: 'reverse not equivalent') - - "": [t: "không phải tập hợp con vuông"] # 0xea60 (en: 'not square subset') - - "": [t: "không phải là siêu siêu hình"] # 0xea61 (en: 'not square superset') - - "": [t: "không gần như bằng nhau"] # 0xea62 (en: 'not almost equal over equal') - - "": [t: "không hoàn toàn tương đương với"] # 0xea63 (en: 'not strictly equivalent to') - - "": [t: "không đồng dạng chấm"] # 0xea64 (en: 'not congruent dot') - - "": [t: "đảo ngược không bằng nhau"] # 0xea65 (en: 'reverse not equal') - - "": [t: "không phải đỉnh bên trái bằng nhau"] # 0xea70 (en: 'not vert left triangle equals') - - "": [t: "không phải hình tam giác bên phải bằng"] # 0xea71 (en: 'not vert right triangle equals') - - "": [t: "không một phần"] # 0xea80 (en: 'not partial') - - "": [t: "mũi tên extender"] # 0xeb00 (en: 'arrow embellishment extender') - - "": [t: "mũi tên phải qua mũi tên trái"] # 0xeb01 (en: 'arrow rightwards over arrow leftwards') - - "": [t: "mũi tên phải qua mũi tên trái"] # 0xeb02 (en: 'arrow rightwards over arrow leftwards') - - "": [t: "harpoon ngay trên harpoon trái"] # 0xeb03 (en: 'harpoon right over harpoon left') - - "": [t: "harpoon ngay trên harpoon trái"] # 0xeb04 (en: 'harpoon right over harpoon left') - - "": [t: "mũi tên kép đông nam tây nam"] # 0xeb05 (en: 'double arrow northeast southwest') - - "": [t: "mũi tên kép phía tây bắc đông nam"] # 0xeb06 (en: 'double arrow northwest southeast') - - "": [t: "bộ mở rộng harpoon ngang"] # 0xeb07 (en: 'horizontal harpoon extender') - - "": [t: "mũi tên trái ngược chiều kim đồng hồ"] # 0xeb08 (en: 'anticlockwise arc leftwards arrow') - - "": [t: "vòng cung ngược chiều kim đồng hồ mũi tên bên phải"] # 0xeb09 (en: 'anticlockwise arc rightwards arrow') - - "": [t: "giọng mũi phải lớn"] # 0xeb0b (en: 'large rightwards arrow accent') - - "": [t: "điểm nhấn mũi tên lớn bên trái"] # 0xeb0c (en: 'large leftwards arrow accent') - - "": [t: "đầu mũi tên trái"] # 0xeb0d (en: 'leftwards arrowhead') - - "": [t: "đầu mũi tên phải"] # 0xeb0e (en: 'rightwards arrowhead') - - "": [t: "mũi tên lớn bên trái với gạch"] # 0xeb0f (en: 'large left right arrow with stroke') - - "": [t: "bộ mở rộng mũi tên kép ngang"] # 0xeb10 (en: 'horizontal double arrow extender') - - "": [t: "mũi tên đôi bên trái lớn bên trái với gạch"] # 0xeb11 (en: 'large left right double arrow with stroke') - - "": [t: "mũi tên xuống bên trái của mũi tên hướng lên"] # 0xeb12 (en: 'downwards arrow leftwards of upwards arrow') - - "⇵": [t: "mũi tên xuống bên trái của mũi tên hướng lên"] # 0x21f5 (en: 'downwards arrow leftwards of upwards arrow') - - "": [t: "mũi tên trái với góc xuống"] # 0xeb13 (en: 'leftwards arrow with corner downwards') - - "": [t: "mũi tên bên phải với góc hướng lên trên"] # 0xeb14 (en: 'rightwards arrow with corner upwards') - - "": [t: "mũi tên trái với góc hướng lên trên"] # 0xeb15 (en: 'leftwards arrow with corner upwards') - - "": [t: "mũi tên bán nguyệt trên cùng theo chiều kim đồng hồ với plus"] # 0xeb16 (en: 'anticlockwise top semicircle arrow with plus') - - "⤽": [t: "mũi tên bán nguyệt trên cùng theo chiều kim đồng hồ với plus"] # 0x293d (en: 'anticlockwise top semicircle arrow with plus') - - "": [t: "mũi tên bán nguyệt trên cùng theo chiều kim đồng hồ với điểm trừ"] # 0xeb17 (en: 'clockwise top semicircle arrow with minus') - - "⤼": [t: "mũi tên bán nguyệt trên cùng theo chiều kim đồng hồ với điểm trừ"] # 0x293c (en: 'clockwise top semicircle arrow with minus') - - "": [t: "mũi tên bên phải với đuôi với gạch"] # 0xeb18 (en: 'rightwards arrow with tail with stroke') - - "": [t: "harpoon phải xuống"] # 0xeb19 (en: 'right harpoon down') - - "": [t: "rời harpoon xuống"] # 0xeb1a (en: 'left harpoon down') - - "": [t: "bên trái harpoon xuống"] # 0xeb1b (en: 'left right harpoon down') - - "⥐": [t: "bên trái harpoon xuống"] # 0x2950 (en: 'left right harpoon down') - - "": [t: "bên trái harpoon lên"] # 0xeb1c (en: 'left right harpoon up') - - "⥎": [t: "bên trái harpoon lên"] # 0x294e (en: 'left right harpoon up') - - "": [t: "lên xuống harpoon trái"] # 0xeb1d (en: 'up down harpoon left') - - "⥑": [t: "lên xuống harpoon trái"] # 0x2951 (en: 'up down harpoon left') - - "": [t: "lên xuống harpoon phải"] # 0xeb1e (en: 'up down harpoon right') - - "⥏": [t: "lên xuống harpoon phải"] # 0x294f (en: 'up down harpoon right') - - "": [t: "mũi tên hướng lên bên phải của mũi tên xuống"] # 0xeb1f (en: 'upwards arrow to the right of downwards arrow') - - "⇵": [t: "mũi tên hướng lên bên phải của mũi tên xuống"] # 0x21f5 (en: 'upwards arrow to the right of downwards arrow') - - "": [t: "harpoon trái để bar với barb lên trên"] # 0xeb20 (en: 'leftwards harpoon to bar with barb upwards') - - "⥒": [t: "harpoon trái để bar với barb lên trên"] # 0x2952 (en: 'leftwards harpoon to bar with barb upwards') - - "": [t: "quyền harpoon đến bar với barb lên trên"] # 0xeb21 (en: 'rightwards harpoon to bar with barb upwards') - - "⥓": [t: "quyền harpoon đến bar với barb lên trên"] # 0x2953 (en: 'rightwards harpoon to bar with barb upwards') - - "": [t: "harpoon bên trái để bar với barb xuống dưới"] # 0xeb22 (en: 'leftwards harpoon to bar with barb downwards') - - "⥖": [t: "harpoon bên trái để bar với barb xuống dưới"] # 0x2956 (en: 'leftwards harpoon to bar with barb downwards') - - "": [t: "quyền harpoon đến bar với barb xuống dưới"] # 0xeb23 (en: 'rightwards harpoon to bar with barb downwards') - - "⥗": [t: "quyền harpoon đến bar với barb xuống dưới"] # 0x2957 (en: 'rightwards harpoon to bar with barb downwards') - - "": [t: "harpoon trái từ quán bar với barb trở lên"] # 0xeb24 (en: 'leftwards harpoon from bar with barb upwards') - - "⥚": [t: "harpoon trái từ quán bar với barb trở lên"] # 0x295a (en: 'leftwards harpoon from bar with barb upwards') - - "": [t: "harpoon ngay từ quán bar với barb trở lên"] # 0xeb25 (en: 'rightwards harpoon from bar with barb upwards') - - "⥛": [t: "harpoon ngay từ quán bar với barb trở lên"] # 0x295b (en: 'rightwards harpoon from bar with barb upwards') - - "": [t: "harpoon bên trái từ quán bar với barb trở xuống"] # 0xeb26 (en: 'leftwards harpoon from bar with barb downwards') - - "⥞": [t: "harpoon bên trái từ quán bar với barb trở xuống"] # 0x295e (en: 'leftwards harpoon from bar with barb downwards') - - "": [t: "harpoon bên phải từ quán bar với barb trở xuống"] # 0xeb27 (en: 'rightwards harpoon from bar with barb downwards') - - "⥟": [t: "harpoon bên phải từ quán bar với barb trở xuống"] # 0x295f (en: 'rightwards harpoon from bar with barb downwards') - - "": [t: "hướng lên trên harpoon để bar với barb trái"] # 0xeb28 (en: 'upwards harpoon to bar with barb leftwards') - - "⥘": [t: "hướng lên trên harpoon để bar với barb trái"] # 0x2958 (en: 'upwards harpoon to bar with barb leftwards') - - "": [t: "downwards harpoon đến bar với barb leftwards"] # 0xeb29 (en: 'downwards harpoon to bar with barb leftwards') - - "⥙": [t: "downwards harpoon đến bar với barb leftwards"] # 0x2959 (en: 'downwards harpoon to bar with barb leftwards') - - "": [t: "hướng lên trên harpoon để bar với barb phải"] # 0xeb2a (en: 'upwards harpoon to bar with barb rightwards') - - "⥔": [t: "hướng lên trên harpoon để bar với barb phải"] # 0x2954 (en: 'upwards harpoon to bar with barb rightwards') - - "": [t: "xuống harpoon để bar với barb ngay"] # 0xeb2b (en: 'downwards harpoon to bar with barb rightwards') - - "⥕": [t: "xuống harpoon để bar với barb ngay"] # 0x2955 (en: 'downwards harpoon to bar with barb rightwards') - - "": [t: "harpoon đi lên từ quán bar với barb trái"] # 0xeb2c (en: 'upwards harpoon from bar with barb leftwards') - - "⥠": [t: "harpoon đi lên từ quán bar với barb trái"] # 0x2960 (en: 'upwards harpoon from bar with barb leftwards') - - "": [t: "downwards harpoon từ quán bar với barb trái"] # 0xeb2d (en: 'downwards harpoon from bar with barb leftwards') - - "⥡": [t: "downwards harpoon từ quán bar với barb trái"] # 0x2961 (en: 'downwards harpoon from bar with barb leftwards') - - "": [t: "harpoon đi lên từ quán bar với barb phải"] # 0xeb2e (en: 'upwards harpoon from bar with barb rightwards') - - "⥜": [t: "harpoon đi lên từ quán bar với barb phải"] # 0x295c (en: 'upwards harpoon from bar with barb rightwards') - - "": [t: "downwards harpoon từ bar với barb phải"] # 0xeb2f (en: 'downwards harpoon from bar with barb rightwards') - - "⥝": [t: "downwards harpoon từ bar với barb phải"] # 0x295d (en: 'downwards harpoon from bar with barb rightwards') - - "": [t: "mũi tên hướng lên đến thanh"] # 0xeb30 (en: 'upwards arrow to bar') - - "⤒": [t: "mũi tên hướng lên đến thanh"] # 0x2912 (en: 'upwards arrow to bar') - - "": [t: "mũi tên xuống thanh"] # 0xeb31 (en: 'downwards arrow to bar') - - "⤓": [t: "mũi tên xuống thanh"] # 0x2913 (en: 'downwards arrow to bar') - - "": [t: "harpoon hướng lên bên trái của harpoon xuống"] # 0xeb32 (en: 'upwards harpoon to the left of downwards harpoon') - - "⥮": [t: "harpoon hướng lên bên trái của harpoon xuống"] # 0x296e (en: 'upwards harpoon to the left of downwards harpoon') - - "": [t: "harpoon hướng lên bên phải của harpoon xuống"] # 0xeb33 (en: 'upwards harpoon to the right of downwards harpoon') - - "⥯": [t: "harpoon hướng lên bên phải của harpoon xuống"] # 0x296f (en: 'upwards harpoon to the right of downwards harpoon') - - "": [t: "đầu mũi tên hướng lên"] # 0xeb34 (en: 'upwards arrowhead') - - "": [t: "đầu mũi tên xuống"] # 0xeb35 (en: 'downwards arrowhead') - - "": [t: "double harpoon với barb bên trái xuống bên phải barb lên"] # 0xeb36 (en: 'double harpoon with leftwards barb down rightwards barb up') - - "": [t: "double harpoon với barb bên trái lên bên phải barb xuống"] # 0xeb37 (en: 'double harpoon with leftwards barb up rightwards barb down') - - "": [t: "mũi tên trái trên thanh"] # 0xeb38 (en: 'leftwards arrow over bar') - - "": [t: "mũi tên bên phải trên thanh"] # 0xeb39 (en: 'rightwards arrow over bar') - - "": [t: "mũi tên trái dưới thanh"] # 0xeb3a (en: 'leftwards arrow under bar') - - "": [t: "mũi tên bên phải dưới thanh"] # 0xeb3b (en: 'rightwards arrow under bar') - - "": [t: "mũi tên ba bên trái"] # 0xeb3c (en: 'left right triple arrow') - - "": [t: "mũi tên kép đông nam đông nam"] # 0xeb3f (en: 'double arrow northeast southeast') - - "": [t: "mũi tên bán nguyệt trái ngược chiều kim đồng hồ"] # 0xeb40 (en: 'anticlockwise left semicircle arrow') - - "⤹": [t: "mũi tên bán nguyệt trái ngược chiều kim đồng hồ"] # 0x2939 (en: 'anticlockwise left semicircle arrow') - - "": [t: "mũi tên bán nguyệt trái theo chiều kim đồng hồ"] # 0xeb41 (en: 'clockwise left semicircle arrow') - - "": [t: "bên trái vòng tròn bên trái mũi tên phải"] # 0xeb42 (en: 'left open circle left right arrow') - - "": [t: "mũi tên bên phải trên tilde"] # 0xeb44 (en: 'rightwards arrow over tilde') - - "⥴": [t: "mũi tên bên phải trên tilde"] # 0x2974 (en: 'rightwards arrow over tilde') - - "": [t: "mũi tên trái trên tilde"] # 0xeb45 (en: 'leftwards arrow over tilde') - - "⥳": [t: "mũi tên trái trên tilde"] # 0x2973 (en: 'leftwards arrow over tilde') - - "": [t: "harpoon trái qua thanh"] # 0xeb48 (en: 'leftwards harpoon over bar') - - "⥪": [t: "harpoon trái qua thanh"] # 0x296a (en: 'leftwards harpoon over bar') - - "": [t: "quyền harpoon trên quán bar"] # 0xeb49 (en: 'rightwards harpoon over bar') - - "⥬": [t: "quyền harpoon trên quán bar"] # 0x296c (en: 'rightwards harpoon over bar') - - "": [t: "harpoon bên trái dưới quán bar"] # 0xeb4a (en: 'leftwards harpoon under bar') - - "⥫": [t: "harpoon bên trái dưới quán bar"] # 0x296b (en: 'leftwards harpoon under bar') - - "": [t: "quyền harpoon dưới quán bar"] # 0xeb4b (en: 'rightwards harpoon under bar') - - "⥭": [t: "quyền harpoon dưới quán bar"] # 0x296d (en: 'rightwards harpoon under bar') - - "": [t: "squat mũi tên trái màu đen"] # 0xeb4c (en: 'squat black leftwards arrow') - - "": [t: "mũi tên bán nguyệt phải theo chiều kim đồng hồ"] # 0xeb50 (en: 'clockwise right semicircle arrow') - - "⤸": [t: "mũi tên bán nguyệt phải theo chiều kim đồng hồ"] # 0x2938 (en: 'clockwise right semicircle arrow') - - "": [t: "mũi tên bán nguyệt phải ngược chiều kim đồng hồ"] # 0xeb51 (en: 'anticlockwise right semicircle arrow') - - "": [t: "vòng tròn bên trái bên trái harpoon"] # 0xeb52 (en: 'left open circle left right harpoon') - - "": [t: "mũi tên hướng lên bên trái của thanh dọc"] # 0xeb58 (en: 'upwards arrow leftwards of vertical bar') - - "": [t: "mũi tên xuống bên trái của thanh dọc"] # 0xeb59 (en: 'downwards arrow leftwards of vertical bar') - - "": [t: "mũi tên hướng lên bên phải của thanh dọc"] # 0xeb5a (en: 'upwards arrow rightwards of vertical bar') - - "": [t: "mũi tên xuống bên phải của thanh dọc"] # 0xeb5b (en: 'downwards arrow rightwards of vertical bar') - - "": [t: "mũi tên bên phải với móc mở rộng xuống"] # 0xeb5c (en: 'rightwards arrow with extended downwards hook') - - "": [t: "mũi tên trái với móc mở rộng"] # 0xeb5d (en: 'leftwards arrow with extended hook') - - "": [t: "mũi tên trái với móc mở rộng xuống"] # 0xeb5e (en: 'leftwards arrow with extended downwards hook') - - "": [t: "mũi tên bên phải với móc mở rộng"] # 0xeb5f (en: 'rightwards arrow with extended hook') - - "": [t: "không đúng mũi tên lượn sóng"] # 0xeb60 (en: 'not right arrow wavy') - - "": [t: "không đúng mũi tên cong"] # 0xeb61 (en: 'not right arrow curved') - - "": [t: "hướng lên trên harpoon bên trái của thanh dọc"] # 0xeb68 (en: 'upwards harpoon leftwards of vertical bar') - - "": [t: "xuống harpoon trái của thanh dọc"] # 0xeb69 (en: 'downwards harpoon leftwards of vertical bar') - - "": [t: "hướng lên trên harpoon ngay của thanh dọc"] # 0xeb6a (en: 'upwards harpoon rightwards of vertical bar') - - "": [t: "xuống harpoon ngay bên phải của thanh dọc"] # 0xeb6b (en: 'downwards harpoon rightwards of vertical bar') - - "": [t: "bộ mở rộng mũi tên đôi dọc"] # 0xeb6c (en: 'vertical double arrow extender') - - "": [t: "harpoon thẳng đứng với barb left extender"] # 0xeb6d (en: 'vertical harpoon with barb left extender') - - "": [t: "harpoon thẳng đứng với barb bên phải extender"] # 0xeb6e (en: 'vertical harpoon with barb right extender') - - "": [t: "harpoon bên phải bên trái harpoon phải"] # 0xeb6f (en: 'right harpoon over left harpoon right') - - "": [t: "harpoon bên trái bên trái harpoon trái"] # 0xeb70 (en: 'right harpoon over left harpoon left') - - "": [t: "bên trái harpoon trên bên phải harpoon phải"] # 0xeb71 (en: 'left harpoon over right harpoon right') - - "": [t: "bên trái harpoon qua harpoon phải trái"] # 0xeb72 (en: 'left harpoon over right harpoon left') - - "": [t: "mũi tên trái từ đầu mũi tên"] # 0xeb73 (en: 'leftwards arrow from bar arrowhead') - - "": [t: "mũi tên trái từ bên phải từ thanh mở rộng"] # 0xeb74 (en: 'leftwards rightwards arrow from bar extender') - - "": [t: "mũi tên trái từ đuôi thanh"] # 0xeb75 (en: 'leftwards arrow from bar tail') - - "": [t: "mũi tên bên phải từ đuôi thanh"] # 0xeb76 (en: 'rightwards arrow from bar tail') - - "": [t: "mũi tên bên phải từ đầu arrowhead"] # 0xeb77 (en: 'rightwards arrow from bar arrowhead') - - "": [t: "harpoon đi lên từ quán bar với đầu mũi tên trái"] # 0xeb78 (en: 'upwards harpoon from bar with barb leftwards arrowhead') - - "": [t: "mũi tên phải qua mũi tên trái bên phải"] # 0xeb79 (en: 'rightwards arrow over leftwards arrow right') - - "": [t: "mũi tên phải qua mũi tên trái bên trái"] # 0xeb7a (en: 'rightwards arrow over leftwards arrow left') - - "": [t: "mũi tên trái qua mũi tên phải bên phải"] # 0xeb7b (en: 'leftwards arrow over rightwards arrow right') - - "": [t: "mũi tên trái qua mũi tên bên phải"] # 0xeb7c (en: 'leftwards arrow over rightwards arrow leftt') - - "": [t: "mũi tên hướng lên từ đầu mũi tên"] # 0xeb7d (en: 'upwards arrow from bar arrowhead') - - "": [t: "mũi tên hướng lên từ đuôi thanh"] # 0xeb7e (en: 'upwards arrow from bar tail') - - "": [t: "mũi tên xuống từ đuôi thanh"] # 0xeb7f (en: 'downwards arrow from bar tail') - - "": [t: "mũi tên xuống từ đầu mũi tên"] # 0xeb80 (en: 'downwards arrow from bar arrowhead') - - "": [t: "downwards harpoon từ quán bar với đầu mũi tên bên phải"] # 0xeb81 (en: 'downwards harpoon from bar with barb rightwards arrowhead') - - "": [t: "harpoon hướng lên bên trái của đáy harpoon"] # 0xeb82 (en: 'upwards harpoon to the left of downwards harpoon bottom') - - "": [t: "harpoon hướng lên bên trái của downwards harpoon extender"] # 0xeb83 (en: 'upwards harpoon to the left of downwards harpoon extender') - - "": [t: "downwards harpoon ở bên trái của harpoon top"] # 0xeb84 (en: 'downwards harpoon to the left of upwards harpoon top') - - "": [t: "lên trên harppoon ở bên trái của harpoon xuống trên"] # 0xeb85 (en: 'upwards harppoon to the left of downwards harpoon top') - - "": [t: "xuống harpoon bên trái của bộ mở rộng harpoon lên trên"] # 0xeb86 (en: 'downwards harpoon to the left of the upwards harpoon extender') - - "": [t: "downwards harpoon ở bên trái của đáy harpoon hướng lên"] # 0xeb87 (en: 'downwards harpoon to the left of the upwards harpoon bottom') - - "": [t: "mũi tên hướng lên bên trái của phía dưới mũi tên xuống"] # 0xeb88 (en: 'upwards arrow leftwards of downwards arrow bottom') - - "": [t: "mũi tên xuống bên trái của đầu mũi tên lên trên"] # 0xeb89 (en: 'downwards arrow leftwards of upwards arrow top') - - "": [t: "mũi tên hướng lên bên trái của đầu mũi tên xuống"] # 0xeb8a (en: 'upwards arrow leftwards of downwards arrow top') - - "": [t: "mũi tên xuống bên trái của phía dưới mũi tên hướng lên"] # 0xeb8b (en: 'downwards arrow leftwards of upwards arrow bottom') - - "": [t: "bên trái mũi tên phải mở rộng"] # 0xeb8c (en: 'leftwards rightwards arrows extender') - - "": [t: "east east arrow extender"] # 0xeb8d (en: 'north east arrow extender') - - "": [t: "nội thu mũi tên tây bắc"] # 0xeb8e (en: 'north west arrow extender') - - "": [t: "xuống niềng răng trái"] # 0xec00 (en: 'down pointing brace left') - - "": [t: "xuống chỉ nẹp giữa"] # 0xec01 (en: 'down pointing brace mid') - - "": [t: "xuống chỉ nẹp đúng"] # 0xec02 (en: 'down pointing brace right') - - "": [t: "máy mở rộng nẹp ngang"] # 0xec03 (en: 'horizontal brace extender') - - "": [t: "lên niềng răng trái"] # 0xec04 (en: 'up pointing brace left') - - "": [t: "lên niềng răng giữa"] # 0xec05 (en: 'up pointing brace mid') - - "": [t: "nẹp lên chỉ đúng"] # 0xec06 (en: 'up-pointing brace right') - - "": [t: "thanh thẳng đứng trái"] # 0xec07 (en: 'left vertical bar') - - "": [t: "thanh dọc bên phải"] # 0xec08 (en: 'right vertical bar') - - "": [t: "thanh dọc trái"] # 0xec09 (en: 'left double vertical bar') - - "": [t: "thanh dọc bên phải"] # 0xec0a (en: 'right double vertical bar') - - "": [t: "bộ mở rộng khung ngang"] # 0xec0b (en: 'horizontal bracket extender') - - "": [t: "dưới khung vuông"] # 0xec0c (en: 'under square bracket') - - "⎵": [t: "dưới khung vuông"] # 0x23b5 (en: 'under square bracket') - - "": [t: "trên khung vuông"] # 0xec0d (en: 'over square bracket') - - "⎴": [t: "trên khung vuông"] # 0x23b4 (en: 'over square bracket') - - "": [t: "dưới khung trái"] # 0xec0e (en: 'under bracket left') - - "": [t: "dưới khung đúng"] # 0xec0f (en: 'under bracket right') - - "": [t: "qua giá đỡ trái"] # 0xec10 (en: 'over bracket left') - - "": [t: "trên khung đúng"] # 0xec11 (en: 'over bracket right') - - "": [t: "dấu ngoặc trái 1"] # 0xec12 (en: 'left parens 1') - - "": [t: "dấu ngoặc trái 2"] # 0xec13 (en: 'left parens 2') - - "": [t: "dấu ngoặc đơn 3"] # 0xec14 (en: 'left parens 3') - - "": [t: "dấu ngoặc trái 4"] # 0xec15 (en: 'left parens 4') - - "": [t: "dấu ngoặc đơn phải 1"] # 0xec16 (en: 'right parens 1') - - "": [t: "dấu ngoặc đơn phải 2"] # 0xec17 (en: 'right parens 2') - - "": [t: "dấu ngoặc đơn 3"] # 0xec18 (en: 'right parens 3') - - "": [t: "dấu ngoặc đơn phải 4"] # 0xec19 (en: 'right parens 4') - - "": [t: "triệt để 1"] # 0xec1a (en: 'radical 1') - - "": [t: "triệt để 2"] # 0xec1b (en: 'radical 2') - - "": [t: "triệt để 3"] # 0xec1c (en: 'radical 3') - - "": [t: "triệt để 4"] # 0xec1d (en: 'radical 4') - - "": [t: "triệt để 5"] # 0xec1e (en: 'radical 5') - - "": [t: "đáy triệt để"] # 0xec1f (en: 'radical bottom') - - "": [t: "bộ mở rộng thẳng đứng triệt để"] # 0xec20 (en: 'radical vertical extender') - - "": [t: "top cấp tiến"] # 0xec21 (en: 'radical top') - - "": [t: "mặt trái giá đỡ đầu trắng"] # 0xec22 (en: 'left white bracket top') - - "": [t: "dây mở rộng khung màu trắng"] # 0xec23 (en: 'left white bracket extender') - - "": [t: "mặt trái phía dưới khung màu trắng"] # 0xec24 (en: 'left white bracket bottom') - - "": [t: "bên phải khung màu trắng"] # 0xec25 (en: 'right white bracket top') - - "": [t: "bên phải bộ mở rộng khung trắng"] # 0xec26 (en: 'right white bracket extender') - - "": [t: "đáy khung trắng bên phải"] # 0xec27 (en: 'right white bracket bottom') - - "": [t: "khung màu trắng trái"] # 0xec30 (en: 'left white curly bracket') - - "": [t: "quyền trắng trắng trắng"] # 0xec31 (en: 'right white curly bracket') - - "": [t: "dấu hiệu phân chia dài"] # 0xec32 (en: 'long division sign') - - "": [t: "bộ mở rộng dấu hiệu phân chia dài"] # 0xec33 (en: 'long division sign extender') - - "": [t: "phân chia ngắn"] # 0xec34 (en: 'short division') - - "": [t: "double tây nam đến đông bắc em bond"] # 0xec40 (en: 'double southwest to northeast em bond') - - "": [t: "double tây bắc đến đông nam bond bond"] # 0xec41 (en: 'double northwest to southeast em bond') - - "": [t: "liên kết em ngang đơn"] # 0xec42 (en: 'single horizontal em bond') - - "": [t: "double ngang liên kết em"] # 0xec43 (en: 'double horizontal em bond') - - "": [t: "triple ngang liên kết em"] # 0xec44 (en: 'triple horizontal em bond') - - "": [t: "liên kết em thẳng đứng"] # 0xec45 (en: 'single vertical em bond') - - "": [t: "double dọc liên kết em"] # 0xec46 (en: 'double vertical em bond') - - "": [t: "triple thẳng đứng liên kết em"] # 0xec47 (en: 'triple vertical em bond') - - "": [t: "ít hơn trái phiếu em"] # 0xec48 (en: 'less than em bond') - - "": [t: "lớn hơn liên kết em"] # 0xec49 (en: 'greater than em bond') - - "": [t: "liên kết en ngang đơn"] # 0xec4a (en: 'single horizontal en bond') - - "": [t: "double ngang liên kết en"] # 0xec4b (en: 'double horizontal en bond') - - "": [t: "triple hormanontal en liên kết"] # 0xec4c (en: 'triple horizontal en bond') - - "": [t: "trên cùng bên trái hình chữ nhật"] # 0xec80 (en: 'top left rectangle') - - "": [t: "hình chữ nhật phía dưới bên trái"] # 0xec81 (en: 'bottom left rectangle') - - "": [t: "trên cùng bên phải hình chữ nhật"] # 0xec90 (en: 'top right rectangle') - - "": [t: "dưới cùng bên phải hình chữ nhật"] # 0xec91 (en: 'bottom right rectangle') - - "": [t: "phân chia tổng hợp góc"] # 0xec92 (en: 'synthetic division corner') - - "": [t: "phân chia tổng hợp mở rộng ngang"] # 0xec93 (en: 'synthetic division horizontal extender') - - "": [t: "phân chia tổng hợp mở rộng dọc"] # 0xec94 (en: 'synthetic division vertical extender') - - "": [t: "bên trái sàn mở rộng"] # 0xec95 (en: 'left ceiling floor extender') - - "": [t: "bên phải sàn mở rộng"] # 0xec96 (en: 'right ceiling floor extender') - - "": [t: "qua bộ mở rộng khung"] # 0xec97 (en: 'over bracket extender') - - "": [t: "máy mở rộng thanh dọc"] # 0xec98 (en: 'vertical bar extender') - - "": [t: "bên trái đôi mở rộng thanh dọc"] # 0xec99 (en: 'left double vertical bar extender') - - "": [t: "máy mở rộng thanh ngang"] # 0xec9a (en: 'horizontal bar extender') - - "": [t: "dưới phần mở rộng khung"] # 0xec9c (en: 'under bracket extender') - - "": [t: "xuống dấu ngoặc đơn đúng"] # 0xec9d (en: 'down pointing paren right') - - "": [t: "xuống chỉ dấu ngoặc đơn"] # 0xec9e (en: 'down pointing paren extender') - - "": [t: "down chỉ dấu ngoặc đơn trái"] # 0xec9f (en: 'down pointing paren left') - - "": [t: "lên chỉ dây mở rộng nẹp"] # 0xeca0 (en: 'up pointing brace extender') - - "": [t: "lên dấu ngoặc đơn còn lại"] # 0xeca1 (en: 'up pointing paren left') - - "": [t: "lên dấu ngoặc đơn"] # 0xeca2 (en: 'up pointing paren extender') - - "": [t: "lên dấu ngoặc đơn đúng"] # 0xeca3 (en: 'up pointing paren right') - - "": [t: "xuống chỉ dây mở rộng nẹp"] # 0xeca4 (en: 'down pointing brace extender') - - "": [t: "planck hằng số trên hai thanh pi"] # 0xed00 (en: 'planck constant over two pi bar') - - "": [t: "gương g"] # 0xed01 (en: 'mirror g') - - "": [t: "dotless j"] # 0xed02 - - "": [t: "digamma"] # 0xed03 - - "ϝ": [t: "digamma"] # 0x3dd - - "": [t: ""] # 0xed10 (en: 'd') - - "": [t: ""] # 0xed11 (en: 'e') - - "": [t: ""] # 0xed12 (en: 'i') - - "": [t: ""] # 0xed13 (en: 'j') - - "ⅅ": - - spell: "translate('.', 'ⅅ', 'DD')" # 0xed16, 0x2145 - -# The private use chars are from MathType - - "": [t: "vòng lặp tích hợp đường viền ngược chiều kim đồng hồ"] # 0xee00 (en: 'anticlockwise contour integral loop') - - "": [t: "vòng lặp tích phân theo chiều kim đồng hồ"] # 0xee01 (en: 'clockwise contour integral loop') - - "": [t: ""] # 0xee04 - - "": [t: ""] # 0xee05 - - "": [t: ""] # 0xee06 - - "": [t: ""] # 0xee07 - - "": [t: ""] # 0xee08 - - "": [t: ""] # 0xee09 - - "": [t: ""] # 0xee0a - - "": [t: ""] # 0xee0b - - "": [t: ""] # 0xee0c - - "": [t: "tinh chỉnh trạng thái chung"] # 0xee0d (en: 'joint status embellishment') - - "": [t: "tinh chỉnh trạng thái chung trái"] # 0xee0e (en: 'joint status embellishment left') - - "": [t: "tinh chỉnh trạng thái chung quyền"] # 0xee0f (en: 'joint status embellishment right') - - "": [t: "trạng thái chung extender"] # 0xee10 (en: 'joint status embellishment extender') - - "": [t: "vòng lặp tích hợp"] # 0xee11 (en: 'integral loop') - - "": [t: "vòng lặp tích phân đôi"] # 0xee12 (en: 'integral loop double') - - "": [t: "tích hợp vòng ba"] # 0xee13 (en: 'integral loop triple') - - "": [t: "mở rộng đôi vòng lặp tích phân"] # 0xee15 (en: 'expanding integral loop double') - - "": [t: "mở rộng ba vòng lặp tích phân"] # 0xee16 (en: 'expanding integral loop triple') - - "": [t: "không có triệu chứng bằng giọng"] # 0xee17 (en: 'asymptotically equal to accent') - - "": [t: "dấu hiệu bằng giọng"] # 0xee18 (en: 'equal sign accent') - - "": [T: "đạo hàm cấp bốn"] # 0xee19 - - "⁗": [T: "đạo hàm cấp bốn"] # 0x2057 - - "": [t: "tăng điểm số với vòng tròn mở bên trái"] # 0xee1a (en: 'bar accent with open circle left') - - "": [t: "điểm nhấn thanh với vòng tròn kín trái"] # 0xee1b (en: 'bar accent with closed circle left') - - "": [t: "tăng điểm số với vòng tròn mở phải"] # 0xee1c (en: 'bar accent with open circle right') - - "": [t: "tăng điểm số với dot"] # 0xee1d (en: 'bar accent with over dot') - - "": [t: "tăng điểm số với dưới chấm"] # 0xee1e (en: 'bar accent with under dot') - - "": [t: "tăng điểm số với gấp đôi so với chấm"] # 0xee1f (en: 'bar accent with double over dot') - - "": [t: "tăng điểm số với gấp đôi dưới dấu chấm"] # 0xee20 (en: 'bar accent with double under dot') - - "": [t: "giọng nói với caret"] # 0xee21 (en: 'bar accent with caret') - - "": [t: "dày dưới điểm nhấn thanh"] # 0xee22 (en: 'thick under bar accent') - - "": [t: "tăng điểm số với vòng tròn kín phải"] # 0xee23 (en: 'bar accent with closed circle right') - - "": [t: "chấm lớn ở trên"] # 0xee24 (en: 'large dot above') - - "": [t: "đánh dấu căn chỉnh"] # 0xef00 (en: 'alignment mark') - - "": [t: ""] # 0xef01 - - "​": [t: ""] # 0x200b - - "": [t: ""] # 0xef02 - - " ": [t: ""] # 0x2009 - - "": [t: ""] # 0xef03 - - " ": [t: ""] # 0x205f - - "": [t: ""] # 0xef04 - - "": [t: ""] # 0xef05 - - " ": [t: ""] # 0x2003 - - "": [t: ""] # 0xef06 - - "": [t: ""] # 0xef07 - - "": [t: ""] # 0xef08 - - "": [t: ""] # 0xef09 - - "": [t: ""] # 0xef0a - - " ": [t: ""] # 0x200a - - "": [t: ""] # 0xef22 - - "": [t: ""] # 0xef23 - - "": [t: ""] # 0xef24 - - "": [t: ""] # 0xef29 - - "": [t: "thiếu nhiệm kỳ"] # 0xef41 (en: 'missing term') - - "": [t: "mũi tên tích phân đường theo chiều kim đồng hồ bên trái"] # 0xef80 (en: 'clockwise contour integral arrow on left') - - "": [t: "tích hợp với hình vuông"] # 0xef81 (en: 'integral with square') - - "": [t: "tích hợp với chém"] # 0xef82 (en: 'integral with slash') - - "": [t: "đảo ngược tích phân"] # 0xef83 (en: 'reversed integral') - - "": [t: "double zero trên gấp đôi 0"] # 0xef90 (en: 'double zero over double zero') - - "": [t: "zero với chém"] # 0xef91 (en: 'zero with slash') - - # fraktur chars in math alphabetic block and also MathType private use area - # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display - - "𝔄-𝔜": # 0x1d504 - 0x1d51d ('z' version is reserved) - - t: "fraktur" - - spell: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" - - - "-": # 0xf000 - 0xf018 - - t: "fraktur" - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" - - - "𝔞-𝔷": # 0x1d51e - 0x1d537 - - t: "fraktur" - - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" - - "-": # 0xf01a - 0xf033 - - t: "fraktur" - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝕬-𝖅": # 0x1D56C - 0x1D585 - - t: "fraktur táo bạo" # (en: 'fraktur bold') - - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf040 - 0xf059 - - t: "fraktur táo bạo" # (en: 'fraktur bold') - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝖆-𝖟": # 0x1d586 - 0x1d59f - - t: "fraktur táo bạo" # (en: 'fraktur bold') - - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" - - "-": # 0xf05a - 0xf073 - - t: "fraktur táo bạo" # (en: 'fraktur bold') - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - # double struck (blackboard bold) chars in math alphabetic block and also MathType private use area - # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display - - "𝔸-𝕐": # 0x1d504 - 0x1d51d ('z' version is reserved) - - test: - if: "$Verbosity!='Terse'" - then: [t: "cú đúp"] # (en: 'double struck') - - spell: "translate('.', '𝔸𝔹𝔺𝔻𝔼𝔽𝔾𝔿𝕀𝕁𝕂𝕃𝕄𝕅𝕆𝕇𝕈𝕉𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf080 - 0xf098 - - test: - if: "$Verbosity!='Terse'" - then: [t: "cú đúp"] # (en: 'double struck') - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝕒-𝕫": # 0x1d552 - 0x1d56b - - test: - if: "$Verbosity!='Terse'" - then: [t: "cú đúp"] # (en: 'double struck') - - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" - - "-": # 0xf09a - 0xf0b3 - - test: - if: "$Verbosity!='Terse'" - then: [t: "cú đúp"] # (en: 'double struck') - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 - - test: - if: "$Verbosity!='Terse'" - then: [t: "cú đúp"] # (en: 'double struck') - - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" - - "-": # 0xf0c0 - 0xf0c9 - - test: - if: "$Verbosity!='Terse'" - then: [t: "cú đúp"] # (en: 'double struck') - - spell: "translate('.', '', '0123456789')" - - - "": [t: "double tấn công nabla"] # 0xf0ca (en: 'double struck nabla') - - "": [t: "double tấn công hằng số euler"] # 0xf0cb (en: 'double struck euler constant') - - # script chars in math alphabetic block and also MathType private use area - - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 - - t: "script" - - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf100 - 0xf119 - - t: "script" - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf - - t: "script" - - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" - - "-": # 0xf11a - 0xf133 - - t: "script" - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - # bold script chars in math alphabetic block and also MathType private use area - - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 - - t: "kịch bản in đậm" # (en: 'script bold') - - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf140 - 0xf159 - - t: "kịch bản in đậm" # (en: 'script bold') - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝓪-𝔃": # 0x1d4ea - 0x1d503 - - t: "kịch bản in đậm" # (en: 'script bold') - - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" - - "-": # 0xf15a - 0xf173 - - t: "kịch bản in đậm" # (en: 'script bold') - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf180 - 0xf199 - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "": # 0xf19a - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [t: "hậu quả"] # (en: 'cap') - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [t: "ligature ae"] - - "": # 0xf19b - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [t: "hậu quả"] # (en: 'cap') - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [t: "sắc s"] # (en: 'sharp s') - - "": # 0xf19c - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [t: "hậu quả"] # (en: 'cap') - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [t: "o với gạch"] # (en: 'o with stroke') - - # MathType only has a few of the cap Greek letters in PUA - - "": # 0xf201 - 0xf209 - - test: - if: "$Verbosity!='Terse'" - then: [t: "cú đúp"] # (en: 'double struck') - - spell: "translate('.', '', 'ΔΨΛΠΣΘΓΩΥ')" - - - "-": # 0xf220 - 0xf236 - - test: - if: "$Verbosity!='Terse'" - then: [t: "cú đúp"] # (en: 'double struck') - - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "": [t: "double tấn công sigma cuối cùng"] # 0xf237 (en: 'double struck final sigma') - - "": [t: "double tấn công rho"] # 0xf250 (en: 'double struck rho') - - "": [t: "double tấn công phi"] # 0xf251 (en: 'double struck phi') - - "𝐀-𝐙": # 0x1d400 - 0x1d419 - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf260 - 0xf279 - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝐚-𝐳": # 0x1d41a - 0x1d433 - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf27a - 0xf293 - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝐴-𝑍": # 0x1d434 - 0x1d44d - - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf294 - 0xf2ad - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝑎-𝑧": # 0x1d44e - 0x1d467 - - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf2ae - 0xf2c7 - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝑨-𝒁": # 0x1d468 - 0x1d481 - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf2c8 - 0xf2e1 - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝒂-𝒛": # 0x1d482 - 0x1d49b - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf2e2 - 0xf2fb - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 - - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf300 - 0xf319 - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 - - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf31a - 0xf333 - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf334 - 0xf34d - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝗮-𝘇": # 0x1d5ee - 0x1d607 - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf34e - 0xf367 - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - "𝘈-𝘡": # 0x1d608 - 0x1d621 - # - t: "chữ in nghiêng" # (en: 'italic') - - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - "-": # 0xf368 - 0xf381 - # - t: "chữ in nghiêng" # (en: 'italic') - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝘢-𝘻": # 0x1d622 - 0x1d63b - # - t: "chữ in nghiêng" # (en: 'italic') - - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf382 - 0xf39b - # - t: "chữ in nghiêng" # (en: 'italic') - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝘼-𝙕": # 0x1d63c - 0x1d655 - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf39c - 0xf3b5 - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝙖-𝙯": # 0x1d656 - 0x1d66f - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf3b6 - 0xf3cf - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝙰-𝚉": # 0x1d670 - 0x1d689 - - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf3d0 - 0xf3e9 - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 - - spell: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" - - - "-": # 0xf3ea - 0xf403 - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - - "": [t: "dotless i"] # 0xf404 - - "𝚤": [t: "dotless i"] # 0x1d6a4 - - "𝚥": [t: "dotless j"] # 0x1d6a5 - - - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "-": # 0xf408 - 0xf420 - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf422 - 0xf43a - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "": [t: "nabla táo bạo"] # 0xf421 (en: 'bold nabla') - - "𝛁": [t: "nabla táo bạo"] # 0x1d6c1 (en: 'bold nabla') - - - "𝛛𝛜𝛝𝛞𝛟𝛠𝛡": # 0x1D6DB - 0x1D6E1 - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" - - - "": # 0xF43C - 0xF441 - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '', '∂εθκφρπ')" - - - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa - # - t: "chữ in nghiêng" # (en: 'italic') - - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "-": # 0xf442 - 0xf45a - # - t: "chữ in nghiêng" # (en: 'italic') - - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝛼-𝜔": # 0x1d6fc - 0x1d714 - # - t: "chữ in nghiêng" # (en: 'italic') - - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓𝜔', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf45c - 0xf474 - # - t: "chữ in nghiêng" # (en: 'italic') - - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "": [t: "nabla in nghiêng"] # 0xf45b (en: 'italic nabla') - - "𝛻": [t: "nabla in nghiêng"] # 0x1d6fb (en: 'italic nabla') - - - "𝜕𝜖𝜗𝜘𝜙𝜚𝜛": # 0x1d715 - 0x1d71b - # - t: "chữ in nghiêng" # (en: 'italic') - - spell: "translate('.', '𝜕𝜖𝜗𝜘𝜙𝜚𝜛', '∂εθκφρπ')" - - - "": # 0xf475 - 0xf47b - # - t: "chữ in nghiêng" # (en: 'italic') - - spell: "translate('.', '', '∂εθκφρπ')" - - - "𝜜-𝜴": # 0x1d71c - 0x1d734 - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "-": # 0xf47c - 0xf494 - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝜶-𝝎": # 0x1d736 - 0x1d74e - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf496 - 0xf4ae - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": # 0x1d74f - 0x1d755 - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εθκφρπ')" - - - "": # 0xf422 - 0xf43a - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '', '∂εθκφρπ')" - - - "𝜵": [t: "nabla italic in đậm"] # 0x1d735 (en: 'bold italic nabla') - - "": [t: "nabla italic in đậm"] # 0xf495 (en: 'bold italic nabla') - - - "𝝖-𝝮": # 0x1d756 - 0x1d76e - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - "-": # 0xf4b6 - 0xf4ce - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝝰-𝞈": # 0x1d770 - 0x1d788 - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇𝞈', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf4d0 - 0xf4e8 - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "𝞉𝞊𝞋𝞌𝞍𝞎𝞏": # 0x1d789 - 0x1d78f - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '𝞉𝞊𝞋𝞌𝞍𝞎𝞏', '∂εθκφρπ')" - - - "": # 0xf4e9 - 0xf4ef - - t: "dũng cảm" # (en: 'bold') - - spell: "translate('.', '', '∂εθκφρπ')" - - - "": [t: "nabla táo bạo"] # 0xf4cf (en: 'bold nabla') - - "𝝯": [t: "nabla táo bạo"] # 0x1d76f (en: 'bold nabla') - - - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "-": # 0xf4f0 - 0xf508 - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - - "𝞪-𝟂": # 0x1d7aa - 0x1d7c2 - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "-": # 0xf50a - 0xf522 - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": # 0x1d7c3 - 0x1d7c9 - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '𝟃𝟄𝟅𝟆𝟇𝟈𝟉', '∂εθκφρπ')" - - - "": # 0xf523 - 0xf529 - - t: "in nghiêng" # (en: 'bold italic') - - spell: "translate('.', '', '∂εθκφρπ')" - - - "": [t: "nabla táo bạo"] # 0xf509 (en: 'bold nabla') - - "𝞩": [t: "nabla táo bạo"] # 0x1d7a9 (en: 'bold nabla') - - - "": [t: "bold zero"] # 0xf52e - - "𝟎": [t: "bold zero"] # 0x1d7ce - - "": [t: "táo bạo"] # 0xf52f (en: 'bold one') - - "𝟏": [t: "táo bạo"] # 0x1d7cf (en: 'bold one') - - "": [t: "táo bạo hai"] # 0xf530 (en: 'bold two') - - "𝟐": [t: "táo bạo hai"] # 0x1d7d0 (en: 'bold two') - - "": [t: "bold ba"] # 0xf531 (en: 'bold three') - - "𝟑": [t: "bold ba"] # 0x1d7d1 (en: 'bold three') - - "": [t: "bold bốn"] # 0xf532 (en: 'bold four') - - "𝟒": [t: "bold bốn"] # 0x1d7d2 (en: 'bold four') - - "": [t: "bold năm"] # 0xf533 (en: 'bold five') - - "𝟓": [t: "bold năm"] # 0x1d7d3 (en: 'bold five') - - "": [t: "thứ sáu"] # 0xf534 (en: 'bold six') - - "𝟔": [t: "thứ sáu"] # 0x1d7d4 (en: 'bold six') - - "": [t: "bold seven"] # 0xf535 - - "𝟕": [t: "bold seven"] # 0x1d7d5 - - "": [t: "in đậm tại"] # 0xf536 (en: 'bold eight') - - "𝟖": [t: "in đậm tại"] # 0x1d7d6 (en: 'bold eight') - - "": [t: "bold nine"] # 0xf537 - - "𝟗": [t: "bold nine"] # 0x1d7d7 - - "": [t: "số không"] # 0xf542 (en: 'zero') - - "𝟢": [t: "số không"] # 0x1d7e2 (en: 'zero') - - "": [t: "một"] # 0xf543 (en: 'one') - - "𝟣": [t: "một"] # 0x1d7e3 (en: 'one') - - "": [t: "hai"] # 0xf544 (en: 'two') - - "𝟤": [t: "hai"] # 0x1d7e4 (en: 'two') - - "": [t: "số ba"] # 0xf545 (en: 'three') - - "𝟥": [t: "số ba"] # 0x1d7e5 (en: 'three') - - "": [t: "bốn"] # 0xf546 (en: 'four') - - "𝟦": [t: "bốn"] # 0x1d7e6 (en: 'four') - - "": [t: "số năm"] # 0xf547 (en: 'five') - - "𝟧": [t: "số năm"] # 0x1d7e7 (en: 'five') - - "": [t: "sáu"] # 0xf548 (en: 'six') - - "𝟨": [t: "sáu"] # 0x1d7e8 (en: 'six') - - "": [t: "bảy"] # 0xf549 (en: 'seven') - - "𝟩": [t: "bảy"] # 0x1d7e9 (en: 'seven') - - "": [t: "tại"] # 0xf54a (en: 'eight') - - "𝟪": [t: "tại"] # 0x1d7ea (en: 'eight') - - "": [t: "chín"] # 0xf54b (en: 'nine') - - "𝟫": [t: "chín"] # 0x1d7eb (en: 'nine') - - "": [t: "bold zero"] # 0xf54c - - "𝟬": [t: "bold zero"] # 0x1d7ec - - "": [t: "táo bạo"] # 0xf54d (en: 'bold one') - - "𝟭": [t: "táo bạo"] # 0x1d7ed (en: 'bold one') - - "": [t: "táo bạo hai"] # 0xf54e (en: 'bold two') - - "𝟮": [t: "táo bạo hai"] # 0x1d7ee (en: 'bold two') - - "": [t: "bold ba"] # 0xf54f (en: 'bold three') - - "𝟯": [t: "bold ba"] # 0x1d7ef (en: 'bold three') - - "": [t: "bold bốn"] # 0xf550 (en: 'bold four') - - "𝟰": [t: "bold bốn"] # 0x1d7f0 (en: 'bold four') - - "": [t: "bold năm"] # 0xf551 (en: 'bold five') - - "𝟱": [t: "bold năm"] # 0x1d7f1 (en: 'bold five') - - "": [t: "thứ sáu"] # 0xf552 (en: 'bold six') - - "𝟲": [t: "thứ sáu"] # 0x1d7f2 (en: 'bold six') - - "": [t: "bold seven"] # 0xf553 - - "𝟳": [t: "bold seven"] # 0x1d7f3 - - "": [t: "in đậm tại"] # 0xf554 (en: 'bold eight') - - "𝟴": [t: "in đậm tại"] # 0x1d7f4 (en: 'bold eight') - - "": [t: "bold nine"] # 0xf555 - - "𝟵": [t: "bold nine"] # 0x1d7f5 - - "": [t: "số không"] # 0xf556 (en: 'zero') - - "𝟶": [t: "số không"] # 0x1d7f6 (en: 'zero') - - "": [t: "một"] # 0xf557 (en: 'one') - - "𝟷": [t: "một"] # 0x1d7f7 (en: 'one') - - "": [t: "hai"] # 0xf558 (en: 'two') - - "𝟸": [t: "hai"] # 0x1d7f8 (en: 'two') - - "": [t: "số ba"] # 0xf559 (en: 'three') - - "𝟹": [t: "số ba"] # 0x1d7f9 (en: 'three') - - "": [t: "bốn"] # 0xf55a (en: 'four') - - "𝟺": [t: "bốn"] # 0x1d7fa (en: 'four') - - "": [t: "số năm"] # 0xf55b (en: 'five') - - "𝟻": [t: "số năm"] # 0x1d7fb (en: 'five') - - "": [t: "sáu"] # 0xf55c (en: 'six') - - "𝟼": [t: "sáu"] # 0x1d7fc (en: 'six') - - "": [t: "bảy"] # 0xf55d (en: 'seven') - - "𝟽": [t: "bảy"] # 0x1d7fd (en: 'seven') - - "": [t: "tại"] # 0xf55e (en: 'eight') - - "𝟾": [t: "tại"] # 0x1d7fe (en: 'eight') - - "": [t: "chín"] # 0xf55f (en: 'nine') - - "𝟿": [t: "chín"] # 0x1d7ff (en: 'nine') - - "": [t: "nhân vật chưa biết"] # 0xf700 (en: 'unknown character') - - "": [t: "hình tam giác dưới bên phải và dưới bên trái"] # 0xf726 (en: 'lower right and lower left triangles') - - "": [t: "bộ mở rộng hình elip ngang"] # 0xf72d (en: 'horizontal ellipsis extender') - - "": [t: "midline ngang elipsis mở rộng"] # 0xf72e (en: 'midline horizontal ellipsis extender') - - "": [t: "bộ mở rộng triệt để"] # 0xf8e5 (en: 'radical extender') - - "": [t: "máy mở rộng mũi tên dọc"] # 0xf8e6 (en: 'vertical arrow extender') - - "": [t: "máy mở rộng mũi tên ngang"] # 0xf8e7 (en: 'horizontal arrow extender') - - "": [t: "đăng ký ký sans serif"] # 0xf8e8 (en: 'registered sign sans serif') - - "": [t: "dấu hiệu bản quyền sans serif"] # 0xf8e9 (en: 'copyright sign sans serif') - - "": [t: "dấu thương mại dấu hiệu sans serif"] # 0xf8ea (en: 'trade mark sign sans serif') - - "": [t: "dấu ngoặc đơn hàng đầu"] # 0xf8eb (en: 'left paren top') - - "": [t: "phần mở rộng dấu ngoặc đơn"] # 0xf8ec (en: 'left paren extender') - - "": [t: "dấu ngoặc đơn phía dưới"] # 0xf8ed (en: 'left paren bottom') - - "": [t: "chân trái trên cùng"] # 0xf8ee (en: 'left bracket top') - - "": [t: "bộ mở rộng khung trái"] # 0xf8ef (en: 'left bracket extender') - - "": [t: "đáy khung trái"] # 0xf8f0 (en: 'left bracket bottom') - - "": [t: "bên trái nẹp trên cùng"] # 0xf8f1 (en: 'left brace top') - - "": [t: "nẹp trái giữa"] # 0xf8f2 (en: 'left brace mid') - - "": [t: "mặt trái phía dưới"] # 0xf8f3 (en: 'left brace bottom') - - "": [t: "niềng mở rộng"] # 0xf8f4 (en: 'brace extender') - - "": [t: "tích hợp mở rộng"] # 0xf8f5 (en: 'integral extender') - - "": [t: "dấu ngoặc đơn bên phải"] # 0xf8f6 (en: 'right paren top') - - "": [t: "dấu ngoặc đơn bên phải"] # 0xf8f7 (en: 'right paren extender') - - "": [t: "dấu ngoặc đơn bên dưới"] # 0xf8f8 (en: 'right paren bottom') - - "": [t: "giá đỡ bên phải"] # 0xf8f9 (en: 'right bracket top') - - "": [t: "bộ mở rộng khung phải"] # 0xf8fa (en: 'right bracket extender') - - "": [t: "đáy khung bên phải"] # 0xf8fb (en: 'right bracket bottom') - - "": [t: "đóng tay phải"] # 0xf8fc (en: 'right brace top') - - "": [t: "nẹp phải giữa"] # 0xf8fd (en: 'right brace mid') - - "": [t: "đáy giằng bên phải"] # 0xf8fe (en: 'right brace bottom') - - "": [t: "logo apple"] # 0xf8ff (en: 'apple logo') - - "ff": [t: "ff"] # 0xfb00 - - "fi": [t: "fi"] # 0xfb01 - - "fl": [t: "fl"] # 0xfb02 - - "ffi": [t: "ffi"] # 0xfb03 - - "ffl": [t: "ffl"] # 0xfb04 - - "ſt": [t: "ft"] # 0xfb05 - - "st": [t: "st"] # 0xfb06 - - "︠": [t: "ligature trái một nửa tô điểm"] # 0xfe20 (en: 'ligature left half embellishment') - - "︡": [t: "ligature bên phải một nửa tô điểm"] # 0xfe21 (en: 'ligature right half embellishment') - - "︢": [t: "double tilde để lại một nửa tô điểm"] # 0xfe22 (en: 'double tilde left half embellishment') - - "︣": [t: "double tilde phải nửa chỉnh trang"] # 0xfe23 (en: 'double tilde right half embellishment') - - "︤": [t: "macron để lại một nửa tô điểm"] # 0xfe24 (en: 'macron left half embellishment') - - "︥": [t: "macron phải nửa chỉnh trang"] # 0xfe25 (en: 'macron right half embellishment') - - "︦": [t: "tinh chỉnh macron liên kết"] # 0xfe26 (en: 'conjoining macron embellishment') - - "︵": [t: "trên dấu ngoặc đơn"] # 0xfe35 (en: 'over paren') - - "︶": [t: "dưới dấu ngoặc đơn"] # 0xfe36 (en: 'under paren') - - "︷": [t: "qua nẹp"] # 0xfe37 (en: 'over brace') - - "︸": [t: "dưới nẹp"] # 0xfe38 (en: 'under brace') - - "︿": [t: "trên khung góc"] # 0xfe3f (en: 'over angle bracket') - - "﹀": [t: "dưới khung góc"] # 0xfe40 (en: 'under angle bracket') - - "﹨": [t: "phân chia số nguyên"] # 0xfe68 (en: 'integer divide') - - "": [t: "đối tượng không xác định hoặc thiếu"] # 0xfffc (en: 'unknown or missing object') - - "�": [t: "nhân vật không rõ hoặc thiếu"] # 0xfffd (en: 'unknown or missing character') +--- + + + - "¤": [t: "dấu hiệu tiền tệ"] # 0xa4 (en: 'currency sign') + - "¥": [t: "yên"] # 0xa5 (en: 'yen') + - "¦": [t: "thanh bị hỏng"] # 0xa6 (en: 'broken bar') + - "§": [t: "tiết diện"] # 0xa7 (en: 'section') + - "¨": [t: "chấm đôi"] # 0xa8 (en: 'double dot') + - "©": [t: "bản quyền"] # 0xa9 (en: 'copyright') + - "ª": [t: "chỉ số thứ tự nữ tính"] # 0xaa (en: 'feminine ordinal indicator') + - "«": [t: "dấu ý nghĩa góc cạnh trái"] # 0xab (en: 'left-pointing double angle quote mark') + - "¯": # 0xaf + - test: + if: "ancestor::m:modified-variable and preceding-sibling::*[1][self::m:mi]" + then: [T: "ngang"] # (en: 'bar') -- as in "x bar", a shorthand way to speak this + else: [t: "dòng"] # (en: 'line') + - "²": [t: "hai"] # 0xb2 (en: 'two') + - "³": [t: "số ba"] # 0xb3 (en: 'three') + - "µ": [t: "vi mô"] # 0xb5 (en: 'micro') + - "¹": [t: "một"] # 0xb9 (en: 'one') + - "º": [t: "chỉ số thứ tự nam tính"] # 0xb9 (en: 'masculine ordinal indicator') + - "ʰ": [t: "công cụ sửa đổi nhỏ h"] # 0x2b0 (en: 'modifier small h') + - "ʱ": [t: "công cụ sửa đổi h nhỏ với móc"] # 0x2b1 (en: 'modifier small h with hook') + - "ʲ": [t: "sửa đổi nhỏ j"] # 0x2b2 (en: 'modifier small j') + - "ʳ": [t: "công cụ sửa đổi nhỏ r"] # 0x2b3 (en: 'modifier small r') + - "ʴ": [t: "công cụ sửa đổi nhỏ quay r"] # 0x2b4 (en: 'modifier small turned r') + - "ʵ": [t: "công cụ sửa đổi nhỏ quay r với móc"] # 0x2b5 (en: 'modifier small turned r with hook') + - "ʶ": # 0x2b6 + - t: "sửa đổi nhỏ đảo ngược" # (en: 'modifier small inverted') + - spell: "translate('R', 'R', 'R')" + + - "ʷ": [t: "sửa đổi nhỏ w"] # 0x2b7 (en: 'modifier small w') + - "ʸ": [t: "công cụ sửa đổi nhỏ y"] # 0x2b8 (en: 'modifier small y') + - "ʹ": [t: "công cụ sửa đổi prime"] # 0x2b9 (en: 'modifier prime') + - "ʺ": [t: "công cụ sửa đổi double prime"] # 0x2ba (en: 'modifier double prime') + - "ʻ": [t: "công cụ sửa đổi đã trở thành dấu phẩy"] # 0x2bb (en: 'modifier turned comma') + - "ʼ": [t: "ăn dây sửa đổi"] # 0x2bc (en: 'modifier apostrophe') + - "ʽ": [t: "công cụ sửa đổi đảo ngược dấu phẩy"] # 0x2bd (en: 'modifier reversed comma') + - "ʾ": [t: "công cụ sửa đổi một nửa vòng"] # 0x2be (en: 'modifier right half ring') + - "ʿ": [t: "công cụ sửa đổi một nửa vòng"] # 0x2bf (en: 'modifier left half ring') + - "ˀ": [t: "công cụ sửa đổi glottal stop"] # 0x2c0 (en: 'modifier glottal stop') + - "ˁ": [t: "công cụ sửa đổi đảo ngược điểm dừng glottal"] # 0x2c1 (en: 'modifier reversed glottal stop') + - "˂": [t: "công cụ sửa đổi mũi tên trái"] # 0x2c2 (en: 'modifier left arrowhead') + - "˃": [t: "công cụ sửa đổi mũi tên phải"] # 0x2c3 (en: 'modifier right arrowhead') + - "˄": [t: "công cụ sửa đổi lên đầu mũi tên"] # 0x2c4 (en: 'modifier up arrowhead') + - "˅": [t: "công cụ sửa đổi xuống mũi tên"] # 0x2c5 (en: 'modifier down arrowhead') + - "ˆ": [t: "điểm nhấn của circleflex"] # 0x2c6 (en: 'modifier circumflex accent') + - "ˇ": [t: "caron"] # 0x2c7 + - "ˈ": [t: "công cụ sửa đổi đường thẳng đứng"] # 0x2c8 (en: 'modifier vertical line') + - "ˉ": [t: "macron công cụ sửa đổi"] # 0x2c9 (en: 'modifier macron') + - "ˊ": [t: "modifier điểm nhấn cấp tính"] # 0x2ca (en: 'modifier acute accent') + - "ˋ": [t: "điểm nhấn nghiêm trọng của công cụ sửa đổi"] # 0x2cb (en: 'modifier grave accent') + - "ˌ": [t: "công cụ sửa đổi đường thẳng đứng thấp"] # 0x2cc (en: 'modifier low vertical line') + - "ˍ": [t: "công cụ sửa đổi macron thấp"] # 0x2cd (en: 'modifier low macron') + - "ˎ": [t: "công cụ sửa đổi giọng mộ thấp"] # 0x2ce (en: 'modifier low grave accent') + - "ˏ": [t: "công cụ sửa đổi điểm nhấn cấp tính thấp"] # 0x2cf (en: 'modifier low acute accent') + - "ː": [t: "công cụ sửa đổi đại tràng hình tam giác"] # 0x2d0 (en: 'modifier triangular colon') + - "ˑ": [t: "công cụ sửa đổi một nửa đại tràng hình tam giác"] # 0x2d1 (en: 'modifier half triangular colon') + - "˒": [t: "công cụ sửa đổi tập trung nửa vòng"] # 0x2d2 (en: 'modifier centered right half ring') + - "˓": [t: "công cụ sửa đổi tập trung nửa vòng trái"] # 0x2d3 (en: 'modifier centered left half ring') + - "˔": [t: "công cụ sửa đổi lên tadck"] # 0x2d4 (en: 'modifier up tadck') + - "˕": [t: "công cụ sửa đổi xuống"] # 0x2d5 (en: 'modifier down tack') + - "˖": [t: "công cụ sửa đổi cộng với dấu hiệu"] # 0x2d6 (en: 'modifier plus sign') + - "˗": [t: "công cụ sửa đổi trừ dấu hiệu"] # 0x2d7 (en: 'modifier minus sign') + - "˘": [t: "breve"] # 0x2d8 + - "˙": [t: "chấm"] # 0x2d9 (en: 'dot') + - "˚": [t: "nhẫn ở trên"] # 0x2da (en: 'ring above') + - "˛": [t: "ogonek"] # 0x2db + - "˜": [t: "tilde nhỏ"] # 0x2dc (en: 'small tilde') + - "˝": [t: "giọng cấp tính gấp đôi"] # 0x2dd (en: 'double acute accent') + - "˞": [t: "mod soditoter mood"] # 0x2de (en: 'modifier rhotic hook') + - "˟": [t: "máy điều chỉnh điểm nhấn chéo"] # 0x2df (en: 'modifier cross accent') + - "ˠ": [t: "công cụ sửa đổi gamma nhỏ"] # 0x2e0 (en: 'modifier small gamma') + - "ˡ": [t: "sửa đổi nhỏ l"] # 0x2e1 (en: 'modifier small l') + - "ˢ": [t: "sửa đổi nhỏ s"] # 0x2e2 (en: 'modifier small s') + - "ˣ": [t: "công cụ sửa đổi nhỏ x"] # 0x2e3 (en: 'modifier small x') + - "ˤ": [t: "công cụ sửa đổi điểm dừng glottal đảo ngược nhỏ"] # 0x2e4 (en: 'modifier small reversed glottal stop') + - "˥": [t: "công cụ sửa đổi thanh âm cực cao"] # 0x2e5 (en: 'modifier extra-high tone bar') + - "˦": [t: "công cụ sửa đổi thanh âm cao"] # 0x2e6 (en: 'modifier high tone bar') + - "˧": [t: "công cụ sửa đổi thanh giữa giai điệu"] # 0x2e7 (en: 'modifier mid tone bar') + - "˨": [t: "công cụ sửa đổi thanh âm thấp"] # 0x2e8 (en: 'modifier low tone bar') + - "˩": [t: "công cụ sửa đổi thanh âm thấp"] # 0x2e9 (en: 'modifier extra-low tone bar') + - "˪": [t: "công cụ sửa đổi yin khởi hành dấu ấn"] # 0x2ea (en: 'modifier yin departing tone mark') + - "˫": [t: "công cụ sửa đổi yang khởi hành dấu ấn"] # 0x2eb (en: 'modifier yang departing tone mark') + - "ˬ": [t: "công cụ sửa đổi lồng tiếng"] # 0x2ec (en: 'modifier voicing') + - "˭": [t: "người sửa đổi không được khám phá"] # 0x2ed (en: 'modifier unaspirated') + - "ˮ": [t: "bản mô tín hiệu nhân đôi"] # 0x2ee (en: 'modifier double apostrophe') + - "˯": [t: "công cụ sửa đổi mũi tên thấp xuống"] # 0x2ef (en: 'modifier low down arrowhead') + - "˰": [t: "công cụ sửa đổi mũi tên thấp"] # 0x2f0 (en: 'modifier low up arrowhead') + - "˱": [t: "công cụ sửa đổi mũi tên thấp bên trái"] # 0x2f1 (en: 'modifier low left arrowhead') + - "˲": [t: "công cụ sửa đổi mũi tên thấp phải"] # 0x2f2 (en: 'modifier low right arrowhead') + - "˳": [t: "công cụ sửa đổi vòng thấp"] # 0x2f3 (en: 'modifier low ring') + - "˴": [t: "máy điều chỉnh giọng giới thiệu giữa"] # 0x2f4 (en: 'modifier middle grave accent') + - "˵": [t: "modifier middle double grave accent"] # 0x2f5 + - "˶": [t: "công cụ sửa đổi trung tâm cấp tính cấp tính"] # 0x2f6 (en: 'modifier middle double acute accent') + - "˷": [t: "công cụ sửa đổi tilde thấp"] # 0x2f7 (en: 'modifier low tilde') + - "˸": [t: "công cụ sửa đổi nâng đại tràng"] # 0x2f8 (en: 'modifier raised colon') + - "˹": [t: "công cụ sửa đổi bắt đầu âm cao"] # 0x2f9 (en: 'modifier begin high tone') + - "˺": [t: "công cụ sửa đổi kết thúc âm cao"] # 0x2fa (en: 'modifier end high tone') + - "˻": [t: "công cụ sửa đổi bắt đầu âm thấp"] # 0x2fb (en: 'modifier begin low tone') + - "˼": [t: "công cụ sửa đổi kết thúc âm thấp"] # 0x2fc (en: 'modifier end low tone') + - "˽": [t: "kệ điều chỉnh"] # 0x2fd (en: 'modifier shelf') + - "˾": [t: "công cụ sửa đổi kệ mở"] # 0x2fe (en: 'modifier open shelf') + - "˿": [t: "công cụ sửa đổi mũi tên thấp bên trái"] # 0x2ff (en: 'modifier low left arrow') + - "̈": [t: "tinh chỉnh diaeresis"] # 0x308 (en: 'diaeresis embellishment') + - "̉": [t: "móc trên tô điểm"] # 0x309 (en: 'hook above embellishment') + - "̊": [t: "ring trên tôn tạo"] # 0x30a (en: 'ring above embellishment') + - "̋": [t: "double cấp tính tô điểm"] # 0x30b (en: 'double acute accent embellishment') + - "̌": [t: "kiểm tra"] # 0x30c (en: 'check') + - "̍": [t: "đường thẳng đứng trên tô điểm"] # 0x30d (en: 'vertical line above embellishment') + - "̎": [t: "double dòng thẳng đứng trên tô điểm"] # 0x30e (en: 'double vertical line above embellishment') + - "̏": [t: "double grave ecrent song sự"] # 0x30f (en: 'double grave accent embellishment') + - "̐": [t: "tinh chỉnh candrabindu"] # 0x310 (en: 'candrabindu embellishment') + - "̑": [t: "đảo ngược sự tô điểm breve"] # 0x311 (en: 'inverted breve embellishment') + - "̒": [t: "biến dấu phẩy trên tôn tạo"] # 0x312 (en: 'turned comma above embellishment') + - "̓": [t: "dấu phẩy trên tôn tạo"] # 0x313 (en: 'comma above embellishment') + - "̔": [t: "pháo đảo dấu phẩy trên tôn tạo"] # 0x314 (en: 'reversed comma above embellishment') + - "̕": [t: "dấu phẩy ở trên chỉnh trang bên phải"] # 0x315 (en: 'comma above right embellishment') + - "̖": [t: "điểm nhấn nghiêm trọng dưới sự tôn tạo"] # 0x316 (en: 'grave accent below embellishment') + - "̗": [t: "điểm nhấn cấp tính dưới sự tô điểm"] # 0x317 (en: 'acute accent below embellishment') + - "̘": [t: "trái bên dưới sự tôn tạo"] # 0x318 (en: 'left tack below embellishment') + - "̙": [t: "phải tad dưới sự tôn tạo"] # 0x319 (en: 'right tack below embellishment') + - "̚": [t: "góc trái phía trên sự tô điểm"] # 0x31a (en: 'left angle above embellishment') + - "̛": [t: "sừng tô điểm"] # 0x31b (en: 'horn embellishment') + - "̜": [t: "một nửa vòng trái bên dưới sự tô điểm"] # 0x31c (en: 'left half ring below embellishment') + - "̝": [t: "up tack bên dưới sự tô điểm"] # 0x31d (en: 'up tack below embellishment') + - "̞": [t: "xuống dưới sự tôn tạo"] # 0x31e (en: 'down tack below embellishment') + - "̟": [t: "cộng với dấu hiệu dưới đây tô điểm"] # 0x31f (en: 'plus sign below embellishment') + - "̠": [t: "trừ dấu hiệu dưới đây tô điểm"] # 0x320 (en: 'minus sign below embellishment') + - "̡": [t: "móc vòm miệng bên dưới sự tô điểm"] # 0x321 (en: 'palatalized hook below embellishment') + - "̢": [t: "retroflex hook dưới sự tô điểm"] # 0x322 (en: 'retroflex hook below embellishment') + - "̣": [t: "dot dưới sự tô điểm"] # 0x323 (en: 'dot below embellishment') + - "̤": [t: "diaeresis dưới sự tô điểm"] # 0x324 (en: 'diaeresis below embellishment') + - "̥": [t: "nhẫn dưới sự tô điểm"] # 0x325 (en: 'ring below embellishment') + - "̦": [t: "dấu phẩy dưới sự tôn tạo"] # 0x326 (en: 'comma below embellishment') + - "̧": [t: "tinh chỉnh cedilla"] # 0x327 (en: 'cedilla embellishment') + - "̨": [t: "ogonek tô điểm"] # 0x328 (en: 'ogonek embellishment') + - "̩": [t: "đường thẳng đứng dưới sự tô điểm"] # 0x329 (en: 'vertical line below embellishment') + - "̪": [t: "cầu dưới sự tô điểm"] # 0x32a (en: 'bridge below embellishment') + - "̫": [t: "đảo ngược đôi vòm dưới sự tô điểm"] # 0x32b (en: 'inverted double arch below embellishment') + - "̬": [t: "caron dưới sự tôn tạo"] # 0x32c (en: 'caron below embellishment') + - "̭": [t: "vòng tròn âm thanh dưới sự tô điểm"] # 0x32d (en: 'circumflex accent below embellishment') + - "̮": [t: "breve dưới sự tôn tạo"] # 0x32e (en: 'breve below embellishment') + - "̯": [t: "đảo ngược breve dưới sự tô điểm"] # 0x32f (en: 'inverted breve below embellishment') + - "̰": [t: "tilde dưới sự tôn tạo"] # 0x330 (en: 'tilde below embellishment') + - "̱": [t: "macron dưới sự tô điểm"] # 0x331 (en: 'macron below embellishment') + - "̲": [t: "tinh chỉnh dòng thấp"] # 0x332 (en: 'low line embellishment') + - "̳": [t: "double line dòng tô điểm"] # 0x333 (en: 'double low line embellishment') + - "̴": [t: "tinh chỉnh lớp phủ tilde"] # 0x334 (en: 'tilde overlay embellishment') + - "̵": [t: "tiếng gạch ngắn tô điểm"] # 0x335 (en: 'short stroke overlay embellishment') + - "̶": [t: "tinh chỉnh lớp phủ dài"] # 0x336 (en: 'long stroke overlay embellishment') + - "̷": [t: "slidus lớp phủ ngắn gọn"] # 0x337 (en: 'short solidus overlay embellishment') + - "̸": [t: "tinh chỉnh lớp phủ solidus dài"] # 0x338 (en: 'long solidus overlay embellishment') + - "̹": [t: "một nửa vòng bên phải bên dưới sự tô điểm"] # 0x339 (en: 'right half ring below embellishment') + - "̺": [t: "cầu đảo dưới sự tôn tạo"] # 0x33a (en: 'inverted bridge below embellishment') + - "̻": [t: "hình vuông dưới sự tô điểm"] # 0x33b (en: 'square below embellishment') + - "̼": [t: "seagull dưới sự tôn tạo"] # 0x33c (en: 'seagull below embellishment') + - "̽": [t: "x trên tô điểm"] # 0x33d (en: 'x above embellishment') + - "̾": [t: "tinh chỉnh tilde dọc"] # 0x33e (en: 'vertical tilde embellishment') + - "̿": [t: "double overline tô điểm"] # 0x33f (en: 'double overline embellishment') + - "̀": [t: "grave tone đánh dấu dấu ấn"] # 0x340 (en: 'grave tone mark embellishment') + - "́": [t: "giai điệu cấp tính đánh dấu dấu ấn"] # 0x341 (en: 'acute tone mark embellishment') + + - "ΪΫϏ": # 0x3aa, 0x3ab, 0x3cf + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [t: "hậu quả"] # (en: 'cap') + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [spell: "translate('.', 'ΪΫϏ', 'ιυϗ')"] + - t: "với dialytika" # (en: 'with dialytika') + - "ϊ": [t: "iota với dialytika"] # 0x3ca (en: 'iota with dialytika') + - "ϋ": [t: "upsilon với dialytika"] # 0x3cb (en: 'upsilon with dialytika') + - "ό": [t: "omicron với tonos"] # 0x3cc (en: 'omicron with tonos') + - "ύ": [t: "upsilon với tonos"] # 0x3cd (en: 'upsilon with tonos') + - "ώ": [t: "omega với tonos"] # 0x3ce (en: 'omega with tonos') + - "ϐ": [t: "beta"] # 0x3d0 + - "ϑ": [t: "theta"] # 0x3d1 + - "ϒ": [t: "upsilon với móc"] # 0x3d2 (en: 'upsilon with hook') + - "ϓ": [t: "upsilon với cấp tính và móc"] # 0x3d3 (en: 'upsilon with acute and hook') + - "ϔ": [t: "upsilon với dieresis và hook"] # 0x3d4 (en: 'upsilon with diaeresis and hook') + - "ϗ": [t: "kai"] # 0x3d7 + - "А-Я": # 0x410 - 0x42f + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [t: "hậu quả"] # (en: 'cap') + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [spell: "translate('.', 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ', 'абвгдежзийклмнопрстуфхцчшщъыьэюя')"] + - "а": [t: "а"] # 0x430 (en: 'a') + - "б": [t: "thì là ở"] # 0x431 (en: 'be') + - "в": [t: "đã"] # 0x432 (en: 've') + - "г": [t: "ghe"] # 0x433 + - "д": [t: "de"] # 0x434 + - "е": [t: "i e"] # 0x435 (en: 'ie') + - "ж": [t: "zhe"] # 0x436 + - "з": [t: "ze"] # 0x437 + - "и": [t: "и"] # 0x438 (en: 'i') + - "й": [t: "ngắn i"] # 0x439 (en: 'short i') + - "к": [t: "ka"] # 0x43a + - "л": [t: "el"] # 0x43b + - "м": [t: "em"] # 0x43c + - "н": [t: "en"] # 0x43d + - "о": [t: "о"] # 0x43e (en: 'o') + - "п": [t: "thể dục"] # 0x43f (en: 'pe') + - "р": [t: "er"] # 0x440 + - "с": [t: "es"] # 0x441 + - "т": [t: "te"] # 0x442 + - "у": [t: "у"] # 0x443 (en: 'u') + - "ф": [t: "ef"] # 0x444 + - "х": [t: "ha"] # 0x445 + - "ц": [t: "tse"] # 0x446 + - "ч": [t: "che"] # 0x447 + - "ш": [t: "sha"] # 0x448 + - "щ": [t: "shcha"] # 0x449 + - "ъ": [t: "dấu hiệu khó"] # 0x44a (en: 'hard sign') + - "ы": [t: "yeru"] # 0x44b + - "ь": [t: "dấu hiệu mềm"] # 0x44c (en: 'soft sign') + - "э": [t: "э"] # 0x44d (en: 'e') + - "ю": [t: "yu"] # 0x44e + - "я": [t: "ya"] # 0x44f + - "‐": [t: "bắt gạch"] # 0x2010 (en: 'hyphen') + - "‑": [t: "bắt gạch"] # 0x2011 (en: 'hyphen') + - "‒": [t: "hình dash"] # 0x2012 (en: 'figure dash') + - "•": [t: "đạn"] # 0x2022 (en: 'bullet') + - "‰": [t: "mỗi mille"] # 0x2030 (en: 'per mille') + - "‱": [t: "mỗi mười nghìn"] # 0x2031 (en: 'per ten thousand') + - "‸": [t: "đến"] # 0x2038 (en: 'to the') + - "‹": [t: "một bên trái chỉ góc trích dẫn dấu hiệu"] # 0x2039 (en: 'single left pointing angle quote mark') + - "›": [t: "độc thân chỉ góc trích dẫn dấu hiệu"] # 0x203a (en: 'single right pointing angle quote mark') + - "‼": [t: "nhân đôi nhân đôi"] # 0x203c (en: 'double factorial') + - "⁄": [T: "trên"] # 0x2044 + - "⁅": [t: "khung vuông bên trái với quill"] # 0x2045 (en: 'left square bracket with quill') + - "⁆": [t: "khung vuông bên phải với quill"] # 0x2046 (en: 'right square bracket with quill') + - "⁗": [t: "quadruple prime"] # 0x2057 + - "⁠": [t: ""] # 0x2060 + - "⁰": [T: "mũ không"] # 0x2070 (en: 'to the zeroth power') + - "ⁱ": [T: "mũ tám"] # 0x2071 (en: 'to the eihth power') + - "⁴": [T: "mũ bốn"] # 0x2074 (en: 'to the fourth power') + - "⁵": [T: "mũ năm"] # 0x2075 (en: 'to the fifth power') + - "⁶": [T: "mũ sáu"] # 0x2076 (en: 'to the sixth power') + - "⁷": [T: "mũ bảy"] # 0x2077 (en: 'to the seventh power') + - "⁸": [T: "mũ tám"] # 0x2078 (en: 'to the eighth power') + - "⁹": [T: "mũ chín"] # 0x2079 (en: 'to the ninth power') + - "⁺": [t: "superscript plus dấu hiệu"] # 0x207a (en: 'superscript plus sign') + - "⁻": [t: "superscript trừ"] # 0x207b (en: 'superscript minus') + - "⁼": [t: "superscript bằng dấu hiệu"] # 0x207c (en: 'superscript equals sign') + - "⁽": [t: "superscript trái dấu ngoặc đơn"] # 0x207d (en: 'superscript left parenthesis') + - "⁾": [t: "superscript bên phải dấu ngoặc đơn"] # 0x207e (en: 'superscript right parenthesis') + - "ⁿ": [t: "đến sức mạnh ennth"] # 0x207f (en: 'to the ennth power') + - "₀": [t: "âm độ"] # 0x2080 (en: 'sub zero') + - "₁": [t: "phụ một"] # 0x2081 (en: 'sub one') + - "₂": [t: "phụ hai"] # 0x2082 (en: 'sub two') + - "₃": [t: "phụ ba"] # 0x2083 (en: 'sub three') + - "₄": [t: "phụ bốn"] # 0x2084 (en: 'sub four') + - "₅": [t: "phụ năm"] # 0x2085 (en: 'sub five') + - "₆": [t: "sub six"] # 0x2086 + - "₇": [t: "phụ bảy"] # 0x2087 (en: 'sub seven') + - "₈": [t: "phụ tại"] # 0x2088 (en: 'sub eight') + - "₉": [t: "sub nine"] # 0x2089 + - "₊": [t: "scorstcript plus dấu hiệu"] # 0x208a (en: 'subscript plus sign') + - "₋": [t: "scorstript minu dấu hiệu"] # 0x208b (en: 'subscript minus sign') + - "₌": [t: "chỉ số bằng dấu hiệu"] # 0x208c (en: 'subscript equals sign') + - "₍": [t: "chỉ số bên trái dấu ngoặc đơn"] # 0x208d (en: 'subscript left parenthesis') + - "₎": [t: "scorstist quyền quyền"] # 0x208e (en: 'subscript right parenthesis') + - "ₐ": [t: "sub a"] # 0x2090 (en: 'sub A') + - "ₑ": [t: "sub e"] # 0x2091 (en: 'sub E') + - "ₒ": [t: "sub o"] # 0x2092 (en: 'sub O') + - "ₓ": [t: "sub x"] # 0x2093 (en: 'sub X') + - "ₕ": [t: "sub h"] # 0x2095 (en: 'sub H') + - "ₖ": [t: "sub k"] # 0x2096 (en: 'sub K') + - "ₗ": [t: "sub l"] # 0x2097 (en: 'sub L') + - "ₘ": [t: "sub m"] # 0x2098 (en: 'sub M') + - "ₙ": [t: "sub n"] # 0x2099 (en: 'sub N') + - "ₚ": [t: "sub p"] # 0x209a (en: 'sub P') + - "ₛ": [t: "sub s"] # 0x209b (en: 'sub S') + - "ₜ": [t: "sub t"] # 0x209c (en: 'sub T') + - "₠": [t: "các đơn vị hiện tại của châu âu"] # 0x20a0 (en: 'european currenty units') + - "₡": [t: "phối tử"] # 0x20a1 (en: 'colons') + - "₢": [t: "cruzeiro"] # 0x20a2 + - "₣": [t: "franc"] # 0x20a3 + - "₤": [t: "lira"] # 0x20a4 + - "₥": [t: "nhà máy"] # 0x20a5 (en: 'mills') + - "₦": [t: "naira"] # 0x20a6 + - "₧": [t: "peseta"] # 0x20a7 + - "₨": [t: "rupee"] # 0x20a8 (en: 'rupees') + - "₩": [t: "thắng"] # 0x20a9 (en: 'won') + - "₪": [t: "sheqels mới"] # 0x20aa (en: 'new sheqels') + - "₫": [t: "dong"] # 0x20ab + - "€": [t: "euro"] # 0x20ac (en: 'euros') + - "₭": [t: "kip"] # 0x20ad + - "₮": [t: "tugrik"] # 0x20ae + - "₯": [t: "drachma"] # 0x20af + - "₰": [t: "đồng xu đức"] # 0x20b0 (en: 'german pennies') + - "₱": [t: "peso"] # 0x20b1 (en: 'pesos') + - "₲": [t: "guaranis"] # 0x20b2 + - "₳": [t: "austral"] # 0x20b3 (en: 'australs') + - "₴": [t: "hryvnias"] # 0x20b4 + - "₵": [t: "cedis"] # 0x20b5 + - "₶": [t: "livre tournois"] # 0x20b6 + - "₷": [t: "spesmilos"] # 0x20b7 + - "₸": [t: "tenges"] # 0x20b8 + - "₹": [t: "đồng rupee ấn độ"] # 0x20b9 (en: 'indian rupees') + - "₺": [t: "liras thổ nhĩ kỳ"] # 0x20ba (en: 'turkish liras') + - "⃐": [t: "trái harpoon phía trên sự tôn tạo"] # 0x20d0 (en: 'left harpoon above embellishment') + - "⃑": [t: "harpoon bên phải trên tôn tạo"] # 0x20d1 (en: 'right harpoon above embellishment') + - "⃒": [t: "tinh chỉnh lớp phủ dọc dài"] # 0x20d2 (en: 'long vertical line overlay embellishment') + - "⃓": [t: "tinh chỉnh lớp phủ thẳng đứng ngắn"] # 0x20d3 (en: 'short vertical line overlay embellishment') + - "⃔": [t: "mũi tên ngược chiều kim đồng hồ phía trên sự tô điểm"] # 0x20d4 (en: 'anticlockwise arrow above embellishment') + - "⃕": [t: "mũi tên theo chiều kim đồng hồ phía trên sự tô điểm"] # 0x20d5 (en: 'clockwise arrow above embellishment') + - "⃖": [t: "mũi tên trái phía trên sự tô điểm"] # 0x20d6 (en: 'left arrow above embellishment') + - "⃗": [t: "mũi tên bên phải trên tôn tạo"] # 0x20d7 (en: 'right arrow above embellishment') + - "⃘": [t: "đoạn lên lớp trang phục"] # 0x20d8 (en: 'ring overlay embellishment') + - "⃙": [t: "đoàn chiều theo chiều kim đồng hồ tô điểm"] # 0x20d9 (en: 'clockwise ring overlay embellishment') + - "⃚": [t: "tinh chỉnh lớp phủ vòng ngược chiều kim đồng hồ"] # 0x20da (en: 'anticlockwise ring overlay embellishment') + - "⃛": [t: "ba chấm"] # 0x20db (en: 'triple dot') + - "⃜": [t: "chấm bốn"] # 0x20dc (en: 'quadruple dot') + - "⃝": [t: "bao quanh tô điểm vòng tròn"] # 0x20dd (en: 'enclosing circle embellishment') + - "⃞": [t: "kèm theo tô điểm vuông"] # 0x20de (en: 'enclosing square embellishment') + - "⃟": [t: "kèm theo tô điểm kim cương"] # 0x20df (en: 'enclosing diamond embellishment') + - "⃠": [t: "kèm theo hình ảnh chao đảo"] # 0x20e0 (en: 'enclosing circle backslash embellishment') + - "⃡": [t: "mũi tên trái bên phải phía trên sự tô điểm"] # 0x20e1 (en: 'left right arrow above embellishment') + - "⃢": [t: "kèm theo tô điểm màn hình"] # 0x20e2 (en: 'enclosing screen embellishment') + - "⃣": [t: "kèm theo tô điểm khóa"] # 0x20e3 (en: 'enclosing keycap embellishment') + - "⃤": [t: "kèm theo tô điểm hình tam giác hướng lên"] # 0x20e4 (en: 'enclosing upward pointing triangle embellishment') + - "⃥": [t: "đảo ngược solidus overlay tô điểm"] # 0x20e5 (en: 'reverse solidus overlay embellishment') + - "⃦": [t: "tinh chỉnh gạch đôi"] # 0x20e6 (en: 'double verticle stroke embellishment') + - "⃧": [t: "tổ chức biểu tượng niên kim"] # 0x20e7 (en: 'annuity symbol embellishment') + - "⃨": [t: "triple underdot"] # 0x20e8 + - "⃩": [t: "cầu rộng phía trên sự tô điểm"] # 0x20e9 (en: 'wide bridge above embellishment') + - "⃪": [t: "bên trái mũi tên phủ lên sự tô điểm"] # 0x20ea (en: 'leftwards arrow overlay embellishment') + - "⃫": [t: "double solidus overlay overlay tô điểm"] # 0x20eb (en: 'long double solidus overlay embellishment') + - "⃬": [t: "quyền harpoon với barb downwards tallingation"] # 0x20ec (en: 'rightwards harpoon with barb downwards embellishment') + - "⃭": [t: "harpoon bên trái với barb downwwards song sự"] # 0x20ed (en: 'leftwards harpoon with barb downwards embellishment') + - "⃮": [t: "mũi tên trái bên dưới sự tô điểm"] # 0x20ee (en: 'left arrow below embellishment') + - "⃯": [t: "mũi tên phải dưới sự tôn tạo"] # 0x20ef (en: 'right arrow below embellishment') + - "⃰": [t: "astersik trên tôn tạo"] # 0x20f0 (en: 'astersik above embellishment') + - "℄": [t: "biểu tượng đường trung tâm"] # 0x2104 (en: 'center line symbol') + - "℅": [t: "quan tâm"] # 0x2105 (en: 'care of') + - "℆": [t: "cada una"] # 0x2106 + - "ℇ": [t: "hằng số của euler"] # 0x2107 (en: 'euler's constant') + - "℈": [t: "scruples"] # 0x2108 + - "ℊ": [t: "kịch bản g"] # 0x210a (en: 'script g') + - "ℌℑℨℭ": # 0x210c, 0x2111, 0x2128, 0x212d + - t: "fraktur" + - spell: "translate('.', 'ℌℑℨℭ', 'HIZC')" + + - "ℍℙℾℿ": # 0x210d, 0x2119, 0x213e, 0x213f + - test: + if: "$Verbosity!='Terse'" + then: [t: "cú đúp"] # (en: 'double struck') + - spell: "translate('.', 'ℍℙℾℿ', 'HPΓΠ')" + + - "ℏ": # 0x210f + - test: + if: "($Verbosity='Terse')" + then: [t: "h bar"] + else: [t: "giảm planck hằng số"] # (en: 'reduced planck constant') + + - "ℐℒ℘ℬℰℱℳ": # 0x2110, 0x2112, 0x2118, 0x2130, 0x2131, 0x2133 + - t: "script" + - spell: "translate('.', 'ℐℒ℘ℬℰℱℳ', 'ILPBEFM')" + + - "℔": [t: "bảng"] # 0x2114 (en: 'pounds') + - "№": [t: "số"] # 0x2116 (en: 'number') + - "℥": [t: "ounce"] # 0x2125 (en: 'ounces') + - "℧": [t: "mhos"] # 0x2127 + - "℩": [t: "đã quay iota"] # 0x2129 (en: 'turned iota') + - "ℯ": [t: "kịch bản e"] # 0x212f (en: 'script e') + + # coalesced some chars that use cap letters + - "Ⅎ℺⅁⅂⅃⅄": # 0x2132, 0x213a, 0x2141, 0x2142, 0x2143, 0x2144 + - test: + - if: "'.' = '℺'" + then: [t: "xoay"] # (en: 'rotated') + - else_if: "'.' = 'Ⅎ'" + then: [t: "quay"] # (en: 'turned') + - else_if: "'.' = '⅃'" + then: [t: "đảo ngược sans-serif"] # (en: 'reversed sans-serif') + else: [t: "biến sans-serif"] # (en: 'turned sans-serif') + - spell: "translate('.', 'Ⅎ℺⅁⅂⅃⅄', 'FQGLLY')" + + - "ℴ": [t: "kịch bản o"] # 0x2134 (en: 'script o') + - "ℵ": [t: "hồng y chuyển tiếp đầu tiên"] # 0x2135 (en: 'first transfinite cardinal') + - "ℶ": [t: "hồng y chuyển tiếp thứ hai"] # 0x2136 (en: 'second transfinite cardinal') + - "ℷ": [t: "hồng y transfinite thứ ba"] # 0x2137 (en: 'third transfinite cardinal') + - "ℸ": [t: "hồng y chuyển tiếp thứ tư"] # 0x2138 (en: 'fourth transfinite cardinal') + - "ℼ": [t: "double tấn công pi"] # 0x213c (en: 'double struck pi') + - "ℽ": [t: "double tấn công gamma"] # 0x213d (en: 'double struck gamma') + - "⅀": [t: "double tấn công tổng n-ary"] # 0x2140 (en: 'double struck n-ary summation') + - "⅋": [t: "quay ampersand"] # 0x214b (en: 'turned ampersand') + - "⅌": [t: "mỗi"] # 0x214c (en: 'per') + - "ⅎ": [t: "bật f"] # 0x214e (en: 'turned F') + - "⅐": [T: "một phần bảy"] # 0x2150 (en: 'one seventh') + - "⅑": [T: "một phần chín"] # 0x2151 (en: 'one ninth') + - "⅒": [T: "một phần mười"] # 0x2152 (en: 'one tenth') + - "⅓": [T: "một phần ba"] # 0x2153 (en: 'one third') + - "⅔": [T: "hai phần ba"] # 0x2154 (en: 'two thirds') + - "⅕": [T: "một phần năm"] # 0x2155 (en: 'one fifth') + - "⅖": [T: "hai phần năm"] # 0x2156 (en: 'two fifths') + - "⅗": [T: "ba phần năm"] # 0x2157 (en: 'three fifths') + - "⅘": [T: "bốn phần năm"] # 0x2158 (en: 'four fifths') + - "⅙": [T: "một phần sáu"] # 0x2159 (en: 'one sixth') + - "⅚": [T: "năm phần sáu"] # 0x215a (en: 'five sixths') + - "⅛": [T: "một phần tám"] # 0x215b (en: 'one eighth') + - "⅜": [T: "ba phần tám"] # 0x215c (en: 'three eighths') + - "⅝": [T: "năm phần tám"] # 0x215d (en: 'five eighths') + - "⅞": [T: "bảy phần tám"] # 0x215e (en: 'seven eighths') + - "⅟": [T: "một trên"] # 0x215f (en: 'one over') + - "Ⅰ": [t: "Ⅰ"] # 0x2160 (en: 'I') + - "Ⅱ": [t: "tôi i"] # 0x2161 (en: 'I I') + - "Ⅲ": [t: "tôi i i"] # 0x2162 (en: 'I I I') + - "Ⅳ": [t: "tôi v"] # 0x2163 (en: 'I V') + - "Ⅴ": [t: "Ⅴ"] # 0x2164 (en: 'V') + - "Ⅵ": [t: "v i"] # 0x2165 (en: 'V I') + - "Ⅶ": [t: "v i i"] # 0x2166 (en: 'V I I') + - "Ⅷ": [t: "v i i i"] # 0x2167 (en: 'V I I I') + - "Ⅸ": [t: "tôi x"] # 0x2168 (en: 'I X') + - "Ⅹ": [t: "Ⅹ"] # 0x2169 (en: 'X') + - "Ⅺ": [t: "x i"] # 0x216a (en: 'X I') + - "Ⅻ": [t: "x i i"] # 0x216b (en: 'X I I') + - "Ⅼ": [t: "Ⅼ"] # 0x216c (en: 'L') + - "Ⅽ": [t: "Ⅽ"] # 0x216d (en: 'C') + - "Ⅾ": [t: "Ⅾ"] # 0x216e (en: 'D') + - "Ⅿ": [t: "Ⅿ"] # 0x216f (en: 'M') + - "ⅰ": [t: "ⅰ"] # 0x2170 (en: 'I') + - "ⅱ": [t: "tôi i"] # 0x2171 (en: 'I I') + - "ⅲ": [t: "tôi i i"] # 0x2172 (en: 'I I I') + - "ⅳ": [t: "tôi v"] # 0x2173 (en: 'I V') + - "ⅴ": [t: "ⅴ"] # 0x2174 (en: 'V') + - "ⅵ": [t: "v i"] # 0x2175 (en: 'V I') + - "ⅶ": [t: "v i i"] # 0x2176 (en: 'V I I') + - "ⅷ": [t: "v i i i"] # 0x2177 (en: 'V I I I') + - "ⅸ": [t: "tôi x"] # 0x2178 (en: 'I X') + - "ⅹ": [t: "ⅹ"] # 0x2179 (en: 'X') + - "ⅺ": [t: "x i"] # 0x217a (en: 'X I') + - "ⅻ": [t: "x i i"] # 0x217b (en: 'X I I') + - "ⅼ": [t: "ⅼ"] # 0x217c (en: 'L') + - "ⅽ": [t: "ⅽ"] # 0x217d (en: 'C') + - "ⅾ": [t: "ⅾ"] # 0x217e (en: 'D') + - "ⅿ": [t: "ⅿ"] # 0x217f (en: 'M') + - "↉": [t: "không có một phần ba"] # 0x2189 (en: 'zero thirds') + - "↔": [t: "tương đương"] # 0x2194 (en: 'left right arrow') + - "↕": [t: "lên mũi tên xuống"] # 0x2195 (en: 'up down arrow') + - "↖": [t: "mũi tên tây bắc"] # 0x2196 (en: 'north west arrow') + - "↗": # 0x2197 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [t: "cách tiếp cận từ bên dưới"] # (en: 'approaches from below') + else: [t: "mũi tên đông bắc"] # (en: 'north east arrow') + + - "↘": # 0x2198 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [t: "cách tiếp cận từ trên cao"] # (en: 'approaches from above') + else: [t: "mũi tên đông nam"] # (en: 'south east arrow') + + - "↙": [t: "mũi tên tây nam"] # 0x2199 (en: 'south west arrow') + - "↚": [t: "mũi tên trái với gạch"] # 0x219a (en: 'leftwards arrow with stroke') + - "↛": [t: "mũi tên phải với gạch"] # 0x219b (en: 'rightwards arrow with stroke') + - "↜": [t: "mũi tên sóng trái"] # 0x219c (en: 'leftwards wave arrow') + - "↝": [t: "mũi tên sóng bên phải"] # 0x219d (en: 'rightwards wave arrow') + - "↞": [t: "bên trái hai mũi tên đầu"] # 0x219e (en: 'leftwards two headed arrow') + - "↟": [t: "lên tới hai mũi tên đầu"] # 0x219f (en: 'upwards two headed arrow') + - "↠": [t: "phải hai mũi tên hai đầu"] # 0x21a0 (en: 'rightwards two headed arrow') + - "↡": [t: "xuống hai mũi tên đầu"] # 0x21a1 (en: 'downwards two headed arrow') + - "↢": [t: "mũi tên trái có đuôi"] # 0x21a2 (en: 'leftwards arrow with tail') + - "↣": [t: "mũi tên phải có đuôi"] # 0x21a3 (en: 'rightwards arrow with tail') + - "↤": [t: "mũi tên trái từ thanh"] # 0x21a4 (en: 'leftwards arrow from bar') + - "↥": [t: "mũi tên hướng lên từ thanh"] # 0x21a5 (en: 'upwards arrow from bar') + - "↦": [t: "mũi tên bên phải từ thanh"] # 0x21a6 (en: 'rightwards arrow from bar') + - "↧": [t: "mũi tên xuống từ thanh"] # 0x21a7 (en: 'downwards arrow from bar') + - "↨": [t: "lên mũi tên xuống với cơ sở"] # 0x21a8 (en: 'up down arrow with base') + - "↩": [t: "mũi tên trái với móc"] # 0x21a9 (en: 'leftwards arrow with hook') + - "↪": [t: "mũi tên bên phải với móc"] # 0x21aa (en: 'rightwards arrow with hook') + - "↫": [t: "mũi tên trái với vòng lặp"] # 0x21ab (en: 'leftwards arrow with loop') + - "↬": [t: "mũi tên phải với vòng lặp"] # 0x21ac (en: 'rightwards arrow with loop') + - "↭": [t: "mũi tên bên trái bên phải"] # 0x21ad (en: 'left right wave arrow') + - "↮": [t: "mũi tên trái bên phải với gạch"] # 0x21ae (en: 'left right arrow with stroke') + - "↯": [t: "mũi tên ngoằn ngoèo xuống"] # 0x21af (en: 'downwards zigzag arrow') + - "↰": [t: "mũi tên hướng lên với đầu trái"] # 0x21b0 (en: 'upwards arrow with tip leftwards') + - "↱": [t: "mũi tên hướng lên với đầu bên phải"] # 0x21b1 (en: 'upwards arrow with tip rightwards') + - "↲": [t: "mũi tên xuống với đầu trái"] # 0x21b2 (en: 'downwards arrow with tip leftwards') + - "↳": [t: "mũi tên xuống với đầu bên phải"] # 0x21b3 (en: 'downwards arrow with tip rightwards') + - "↴": [t: "mũi tên bên phải với góc xuống"] # 0x21b4 (en: 'rightwards arrow with corner downwards') + - "↵": [t: "mũi tên xuống với góc trái"] # 0x21b5 (en: 'downwards arrow with corner leftwards') + - "↶": [t: "mũi tên bán nguyệt trên cùng theo chiều kim đồng hồ"] # 0x21b6 (en: 'anticlockwise top semicircle arrow') + - "↷": [t: "mũi tên bán nguyệt trên cùng theo chiều kim đồng hồ"] # 0x21b7 (en: 'clockwise top semicircle arrow') + - "↸": [t: "mũi tên tây bắc đến long bar"] # 0x21b8 (en: 'north west arrow to long bar') + - "↹": [t: "mũi tên trái để thanh trên mũi tên phải vào thanh"] # 0x21b9 (en: 'leftwards arrow to bar over rightwards arrow to bar') + - "↺": [t: "mũi tên vòng tròn mở theo chiều kim đồng hồ"] # 0x21ba (en: 'anticlockwise open circle arrow') + - "↻": [t: "mũi tên vòng tròn mở theo chiều kim đồng hồ"] # 0x21bb (en: 'clockwise open circle arrow') + - "↼": [t: "trái harpoon lên"] # 0x21bc (en: 'left harpoon up') + - "↽": [t: "rời harpoon xuống"] # 0x21bd (en: 'left harpoon down') + - "↾": [t: "up harpoon phải"] # 0x21be (en: 'up harpoon right') + - "↿": [t: "lên harpoon trái"] # 0x21bf (en: 'up harpoon left') + - "⇀": [t: "quyền harpoon lên"] # 0x21c0 (en: 'right harpoon up') + - "⇁": [t: "harpoon phải xuống"] # 0x21c1 (en: 'right harpoon down') + - "⇂": [t: "xuống harpoon phải"] # 0x21c2 (en: 'down harpoon right') + - "⇃": [t: "xuống harpoon trái"] # 0x21c3 (en: 'down harpoon left') + - "⇄": [t: "mũi tên phải qua mũi tên trái"] # 0x21c4 (en: 'rightwards arrow over leftwards arrow') + - "⇅": [t: "mũi tên hướng lên bên trái của mũi tên xuống"] # 0x21c5 (en: 'upwards arrow leftwards of downwards arrow') + - "⇆": [t: "mũi tên trái qua mũi tên phải"] # 0x21c6 (en: 'leftwards arrow over rightwards arrow') + - "⇇": [t: "mũi tên được ghép nối trái"] # 0x21c7 (en: 'leftwards paired arrows') + - "⇈": [t: "mũi tên đi lên trên"] # 0x21c8 (en: 'upwards paired arrows') + - "⇉": [t: "mũi tên được ghép ngay"] # 0x21c9 (en: 'rightwards paired arrows') + - "⇊": [t: "mũi tên đi xuống"] # 0x21ca (en: 'downwards paired arrows') + - "⇋": [t: "trái harpoon qua harpoon phải"] # 0x21cb (en: 'left harpoon over right harpoon') + - "⇌": [t: "harpoon phải qua harpoon trái"] # 0x21cc (en: 'right harpoon over left harpoon') + - "⇍": [t: "mũi tên đôi bên trái với gạch"] # 0x21cd (en: 'leftwards double arrow with stroke') + - "⇎": [t: "mũi tên kép bên trái với gạch"] # 0x21ce (en: 'left right double arrow with stroke') + - "⇏": [t: "mũi tên kép phải với gạch"] # 0x21cf (en: 'rightwards double arrow with stroke') + - "⇐": [t: "mũi tên đôi trái"] # 0x21d0 (en: 'leftwards double arrow') + - "⇑": [t: "mũi tên tăng gấp đôi"] # 0x21d1 (en: 'upwards double arrow') + - "⇓": [t: "xuống mũi tên đôi"] # 0x21d3 (en: 'downwards double arrow') + - "⇔": [t: "tương đương"] # 0x21d4 (en: 'left right double arrow') + - "⇕": [t: "lên xuống mũi tên đôi"] # 0x21d5 (en: 'up down double arrow') + - "⇖": [t: "mũi tên đôi tây bắc"] # 0x21d6 (en: 'north west double arrow') + - "⇗": [t: "mũi tên đôi đông bắc"] # 0x21d7 (en: 'north east double arrow') + - "⇘": [t: "mũi tên đôi đông nam"] # 0x21d8 (en: 'south east double arrow') + - "⇙": [t: "mũi tên đôi tây nam"] # 0x21d9 (en: 'south west double arrow') + - "⇚": [t: "mũi tên ba bên trái"] # 0x21da (en: 'leftwards triple arrow') + - "⇛": [t: "mũi tên ba bên phải"] # 0x21db (en: 'rightwards triple arrow') + - "⇜": [t: "mũi tên bên trái"] # 0x21dc (en: 'leftwards squiggle arrow') + - "⇝": [t: "mũi tên squiggle phải"] # 0x21dd (en: 'rightwards squiggle arrow') + - "⇞": [t: "mũi tên hướng lên với cú đánh đôi"] # 0x21de (en: 'upwards arrow with double stroke') + - "⇟": [t: "mũi tên xuống với cú đánh đôi"] # 0x21df (en: 'downwards arrow with double stroke') + - "⇠": [t: "mũi tên bên trái lao"] # 0x21e0 (en: 'leftwards dashed arrow') + - "⇡": [t: "mũi tên đi xuống"] # 0x21e1 (en: 'upwards dashed arrow') + - "⇢": [t: "mũi tên đứt phải bên phải"] # 0x21e2 (en: 'rightwards dashed arrow') + - "⇣": [t: "mũi tên xuống xuống"] # 0x21e3 (en: 'downwards dashed arrow') + - "⇤": [t: "mũi tên trái vào thanh"] # 0x21e4 (en: 'leftwards arrow to bar') + - "⇥": [t: "mũi tên phải vào thanh"] # 0x21e5 (en: 'rightwards arrow to bar') + - "⇦": [t: "mũi tên trắng bên trái"] # 0x21e6 (en: 'leftwards white arrow') + - "⇧": [t: "mũi tên trắng hướng lên trên"] # 0x21e7 (en: 'upwards white arrow') + - "⇨": [t: "mũi tên trắng bên phải"] # 0x21e8 (en: 'rightwards white arrow') + - "⇩": [t: "mũi tên trắng xuống"] # 0x21e9 (en: 'downwards white arrow') + - "⇪": [t: "mũi tên trắng hướng lên từ thanh"] # 0x21ea (en: 'upwards white arrow from bar') + - "⇫": [t: "mũi tên màu trắng lên trên bệ"] # 0x21eb (en: 'upwards white arrow on pedestal') + - "⇬": [t: "mũi tên màu trắng lên trên bệ với thanh ngang"] # 0x21ec (en: 'upwards white arrow on pedestal with horizontal bar') + - "⇭": [t: "mũi tên màu trắng lên trên bệ với thanh dọc"] # 0x21ed (en: 'upwards white arrow on pedestal with vertical bar') + - "⇮": [t: "mũi tên đôi màu trắng"] # 0x21ee (en: 'upwards white double arrow') + - "⇯": [t: "mũi tên đôi màu trắng lên trên bệ"] # 0x21ef (en: 'upwards white double arrow on pedestal') + - "⇰": [t: "mũi tên trắng bên phải từ tường"] # 0x21f0 (en: 'rightwards white arrow from wall') + - "⇱": [t: "mũi tên tây bắc đến góc"] # 0x21f1 (en: 'north west arrow to corner') + - "⇲": [t: "mũi phía đông mũi tên đến góc"] # 0x21f2 (en: 'south east arrow to corner') + - "⇳": [t: "lên mũi tên trắng"] # 0x21f3 (en: 'up down white arrow') + - "⇴": [t: "mũi tên phải với vòng tròn nhỏ"] # 0x21f4 (en: 'right arrow with small circle') + - "⇵": [t: "mũi tên xuống bên trái của mũi tên hướng lên"] # 0x21f5 (en: 'downwards arrow leftwards of upwards arrow') + - "⇶": [t: "ba mũi tên phải"] # 0x21f6 (en: 'three rightwards arrows') + - "⇷": [t: "mũi tên trái với gạch dọc"] # 0x21f7 (en: 'leftwards arrow with vertical stroke') + - "⇸": [t: "mũi tên phải với gạch dọc"] # 0x21f8 (en: 'rightwards arrow with vertical stroke') + - "⇹": [t: "mũi tên trái bên trái với gạch dọc"] # 0x21f9 (en: 'left right arrow with vertical stroke') + - "⇺": [t: "mũi tên trái với gạch dọc"] # 0x21fa (en: 'leftwards arrow with double vertical stroke') + - "⇻": [t: "mũi tên phải với gạch dọc"] # 0x21fb (en: 'rightwards arrow with double vertical stroke') + - "⇼": [t: "mũi tên trái bên trái với gạch dọc"] # 0x21fc (en: 'left right arrow with double vertical stroke') + - "⇽": [t: "mũi tên mở bên trái"] # 0x21fd (en: 'leftwards open headed arrow') + - "⇾": [t: "mũi tên mở bên phải"] # 0x21fe (en: 'rightwards open headed arrow') + - "⇿": [t: "bên trái mũi tên mở đầu"] # 0x21ff (en: 'left right open headed arrow') + - "∁": # 0x2201 + - test: + if: "$Verbosity!='Terse'" + then: [t: "các"] # (en: 'the') + - t: "bổ sung" # (en: 'complement of') + - "∋": [t: "chứa thành viên"] # 0x220b (en: 'contains the member') + - "∌": [t: "không chứa thành viên"] # 0x220c (en: 'does not contain the member') + - "∍": [t: "chứa thành viên"] # 0x220d (en: 'contains the member') + - "∎": [t: "kết thúc bằng chứng"] # 0x220e (en: 'end of proof') + - "∔": [t: "dot plus"] # 0x2214 + - "∕": [T: "chia"] # 0x2215 + - "∖": [t: "hiệu"] # 0x2216 (en: 'set minus') + - "∙": [T: "nhân"] # 0x2219 + - "∛": # 0x221b + - test: + if: "$Verbosity!='Terse'" + then: [t: "các"] # (en: 'the') + - t: "rễ khối của" # (en: 'cube root of') + - "∜": # 0x221c + - test: + if: "$Verbosity!='Terse'" + then: [t: "các"] # (en: 'the') + - t: "gốc thứ tư của" # (en: 'fourth root of') + - "∢": [t: "góc hình cầu"] # 0x2222 (en: 'spherical angle') + - "∯": [t: "tích hợp bề mặt"] # 0x222f (en: 'surface integral') + - "∰": [t: "khối lượng tích phân"] # 0x2230 (en: 'volume integral') + - "∱": [t: "tích hợp theo chiều kim đồng hồ"] # 0x2231 (en: 'clockwise integral') + - "∲": [t: "tích hợp đường viền theo chiều kim đồng hồ"] # 0x2232 (en: 'clockwise contour integral') + - "∳": [t: "tích hợp đường viền ngược chiều kim đồng hồ"] # 0x2233 (en: 'anticlockwise contour integral') + - "∴": [t: "vì thế"] # 0x2234 (en: 'therefore') + - "∵": [t: "tại vì"] # 0x2235 (en: 'because') + - "∸": [t: "chấm trừ"] # 0x2238 (en: 'dot minus') + - "∹": [t: "có dư thừa so với"] # 0x2239 (en: 'has excess compared to') + - "∺": # 0x223a + - test: + if: "$Verbosity!='Terse'" + then: [t: "là thuận lợi về mặt hình học"] # (en: 'is geometrically proportinal to') + - "∻": # 0x223b + - test: + if: "$Verbosity!='Terse'" + then: [t: "là homothetic để"] # (en: 'is homothetic to') + - "≀": [t: "sản phẩm vòng hoa"] # 0x2240 (en: 'wreath product') + - "≁": [t: "không phải tilde"] # 0x2241 (en: 'not tilde') + - "≂": [t: "trừ tilde"] # 0x2242 (en: 'minus tilde') + - "≃": # 0x2243 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là không có triệu chứng bằng"] # (en: 'is asymptotically equal to') + - "≄": # 0x2244 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "không có triệu chứng bằng" # (en: 'not asymptotically equal to') + - "≅": # 0x2245 + - test: + if: "$Verbosity!='Terse'" + then: [t: "xấp xỉ bằng"] # (en: 'is approximately equal to') + - "≆": # 0x2246 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "xấp xỉ nhưng không thực sự bằng" # (en: 'approximately but not actually equal to') + - "≇": # 0x2247 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "không xấp xỉ cũng không thực sự bằng" # (en: 'neither approximately nor actually equal to') + - "≈": # 0x2248 + - test: + if: "$Verbosity!='Terse'" + then: [t: "xấp xỉ"] # (en: 'is almost equal to') + - "≉": # 0x2249 + - test: + if: "$Verbosity!='Terse'" + then: [t: " "] # (en: 'is') + - t: "không gần bằng" # (en: 'not almost equal to') + - "≊": # 0x224a + - test: + if: "$Verbosity!='Terse'" + then: [t: "xấp xỉ hoặc bằng"] # (en: 'is almost equal or equal to') + - "≋": [t: "triple tilde"] # 0x224b + - "≌": [t: "đều bằng"] # 0x224c (en: 'are all equal to') + - "≍": # 0x224d + - test: + if: "$Verbosity!='Terse'" + then: [t: "tương đương với"] # (en: 'is equivalent to') + - "≎": # 0x224e + - test: + if: "$Verbosity!='Terse'" + then: [t: "là tương đương về mặt hình học"] # (en: 'is geometrically equivalent to') + - "≏": # 0x224f + - test: + if: "$Verbosity!='Terse'" + then: [t: "các"] # (en: 'the') + - t: "sự khác biệt giữa" # (en: 'difference between') + - "≐": [t: "tiếp cận giới hạn"] # 0x2250 (en: 'approaches the limit') + - "≑": # 0x2251 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là bằng hình học bằng"] # (en: 'is geometrically equal to') + - "≒": # 0x2252 + - test: + if: "$Verbosity!='Terse'" + then: [t: "xấp xỉ bằng hoặc hình ảnh của"] # (en: 'is approximately equal to or the image of') + - "≓": # 0x2253 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là hình ảnh hoặc xấp xỉ bằng"] # (en: 'is the image of or approximately equal to') + - "≔": [t: "đại tá bằng"] # 0x2254 (en: 'colon equals') + - "≕": [t: "bằng đại tràng"] # 0x2255 (en: 'equals colon') + - "≖": [t: "nhẫn bằng"] # 0x2256 (en: 'ring in equal to') + - "≗": # 0x2257 + - test: + if: "$Verbosity!='Terse'" + then: [t: "xấp xỉ bằng"] # (en: 'is approximately equal to') + - "≘": [t: "tương ứng với"] # 0x2258 (en: 'corresponds to') + - "≙": [t: "ước tính"] # 0x2259 (en: 'estimates') + - "≚": # 0x225a + - test: + if: "$Verbosity!='Terse'" + then: [t: "là tương đương với"] # (en: 'is equiangular to') + - "≛": [t: "ngôi sao bằng"] # 0x225b (en: 'star equals') + - "≜": [t: "đen ta bằng"] # 0x225c (en: 'delta equals') + - "≝": [t: "được xác định là được"] # 0x225d (en: 'is defined to be') + - "≞": # 0x225e + - test: + if: "$Verbosity!='Terse'" + then: [t: "được đo bằng"] # (en: 'is measured by') + - "≟": [t: "có một mối quan hệ không xác định với"] # 0x225f (en: 'has an unknown relationship with') + - "≢": # 0x2262 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "không giống hệt nhau" # (en: 'not identical to') + - "≣": # 0x2263 + - test: + if: "$Verbosity!='Terse'" + then: [t: "hoàn toàn tương đương với"] # (en: 'is strictly equivalent to') + - "≨": # 0x2268 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là ít hơn nhưng không bằng"] # (en: 'is less than but not equal to') + - "≩": # 0x2269 + - test: + if: "$Verbosity!='Terse'" + then: [t: "lớn hơn nhưng không bằng"] # (en: 'is greater than but not equal to') + - "≪": # 0x226a + - test: + if: "$Verbosity!='Terse'" + then: [t: "là ít hơn nhiều"] # (en: 'is much less than') + - "≫": # 0x226b + - test: + if: "$Verbosity!='Terse'" + then: [t: "là lớn hơn nhiều so với"] # (en: 'is much greater than') + - "≬": # 0x226c + - test: + if: "$Verbosity!='Terse'" + then: [t: "ở giữa"] # (en: 'is between') + - "≭": # 0x226d + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "không tương đương với" # (en: 'not equivalent to') + - "≮": # 0x226e + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "không ít hơn" # (en: 'not less than') + - "≯": # 0x226f + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "không lớn hơn" # (en: 'not greater than') + - "≰": # 0x2270 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "không ít hơn cũng không bằng" # (en: 'neither less than nor equal to') + - "≱": # 0x2271 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "không lớn hơn cũng không bằng" # (en: 'neither greater than nor equal to') + - "≲": # 0x2272 + - test: + if: "$Verbosity!='Terse'" + then: [t: "ít hơn hoặc tương đương với"] # (en: 'is less than or equivalent to') + - "≳": # 0x2273 + - test: + if: "$Verbosity!='Terse'" + then: [t: "lớn hơn hoặc tương đương với"] # (en: 'is greater than or equivalent to') + - "≴": # 0x2274 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "không ít hơn cũng không tương đương với" # (en: 'neither less than nor equivalent to') + - "≵": # 0x2275 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "không lớn hơn cũng không tương đương với" # (en: 'neither greater than nor equivalent to') + - "≶": # 0x2276 + - test: + if: "$Verbosity!='Terse'" + then: [t: "nhỏ hơn hoặc lớn hơn"] # (en: 'is less than or greater than') + - "≷": # 0x2277 + - test: + if: "$Verbosity!='Terse'" + then: [t: "lớn hơn hoặc ít hơn"] # (en: 'is greater than or less than') + - "≸": # 0x2278 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "không ít hơn cũng không lớn hơn" # (en: 'neither less than nor greater than') + - "≹": # 0x2279 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "không lớn hơn cũng không ít hơn" # (en: 'neither greater than nor less than') + - "≼": [t: "trước hoặc bằng"] # 0x227c (en: 'precedes or is equal to') + - "≽": [t: "thành công hoặc bằng"] # 0x227d (en: 'succeeds or is equal to') + - "≾": [t: "trước hoặc tương đương với"] # 0x227e (en: 'precedes or is equivalent to') + - "≿": [t: "thành công hoặc tương đương với"] # 0x227f (en: 'succeeds or is equivalent to') + - "⊀": [t: "không đi trước"] # 0x2280 (en: 'does not precede') + - "⊁": [t: "không thành công"] # 0x2281 (en: 'does not succeed') + - "⊈": # 0x2288 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "không phải là một tập hợp con cũng không bằng" # (en: 'neither a subset of nor equal to') + - "⊉": # 0x2289 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "không phải là một siêu sao cũng không bằng" # (en: 'neither a superset of nor equal to') + - "⊊": [t: "tập hợp con không bằng"] # 0x228a (en: 'subset of with not equal to') + - "⊋": [t: "superset của không bằng"] # 0x228b (en: 'superset of with not equal to') + - "⊌": [t: "multiset"] # 0x228c + - "⊍": [t: "nhân đa nhân"] # 0x228d (en: 'multiset multiplication') + - "⊎": [t: "liên minh multiset"] # 0x228e (en: 'multiset union') + - "⊏": [t: "hình ảnh vuông của"] # 0x228f (en: 'square image of') + - "⊐": [t: "bản gốc vuông của"] # 0x2290 (en: 'square original of') + - "⊑": [t: "hình ảnh vuông hoặc bằng"] # 0x2291 (en: 'square image of or equal to') + - "⊒": [t: "bản gốc vuông hoặc bằng"] # 0x2292 (en: 'square original of or equal to') + - "⊓": [t: "square flowase"] # 0x2293 (en: 'square cap') + - "⊔": [t: "cốc vuông"] # 0x2294 (en: 'square cup') + - "⊕": [t: "bao quanh cộng"] # 0x2295 (en: 'circled plus') + - "⊖": [t: "khoanh tròn trừ đi"] # 0x2296 (en: 'circled minus') + - "⊗": [t: "thời gian khoanh tròn"] # 0x2297 (en: 'circled times') + - "⊘": [t: "chia"] # 0x2298 (en: 'circled slash') + - "⊙": [t: "toán tử chấm được khoanh tròn"] # 0x2299 (en: 'circled dot operator') + - "⊚": [t: "vòng tròn"] # 0x229a (en: 'circled ring') + - "⊛": [t: "asterisk bao quanh"] # 0x229b (en: 'circled asterisk') + - "⊜": [t: "được khoanh tròn bằng"] # 0x229c (en: 'circled equals') + - "⊝": [t: "dash được khoanh tròn"] # 0x229d (en: 'circled dash') + - "⊞": [t: "bình phương cộng"] # 0x229e (en: 'squared plus') + - "⊟": [t: "bình phương trừ"] # 0x229f (en: 'squared minus') + - "⊠": [t: "thời gian bình phương"] # 0x22a0 (en: 'squared times') + - "⊡": [t: "toán tử dot squared"] # 0x22a1 (en: 'squared dot operator') + - "⊢": [t: "chứng minh"] # 0x22a2 (en: 'proves') + - "⊣": [t: "không mang lại"] # 0x22a3 (en: 'does not yield') + - "⊤": [t: "đứng đầu"] # 0x22a4 (en: 'top') + - "⊥": # 0x22a5 + - test: + if: "$Verbosity!='Terse'" + then: [t: "đáy"] # (en: 'is bottom') + - "⊦": [t: "giảm xuống"] # 0x22a6 (en: 'reduces to') + - "⊧": [t: "mô hình"] # 0x22a7 (en: 'models') + - "⊨": # 0x22a8 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "đúng vậy" # (en: 'true') + - "⊩": [t: "lực lượng"] # 0x22a9 (en: 'forces') + - "⊪": [t: "thanh ba thẳng đứng phía bên phải"] # 0x22aa (en: 'triple vertical bar right turnstile') + - "⊫": [t: "thanh dọc theo kép rẽ phải"] # 0x22ab (en: 'double vertical bar double right turnstile') + - "⊬": [t: "không chứng minh"] # 0x22ac (en: 'does not prove') + - "⊭": # 0x22ad + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "không đúng" # (en: 'not true') + - "⊮": [t: "không ép buộc"] # 0x22ae (en: 'does not force') + - "⊯": [t: "thanh dọc được phủ định đôi bên phải turnstile"] # 0x22af (en: 'negated double vertical bar double right turnstile') + - "⊰": [t: "trước mối quan hệ"] # 0x22b0 (en: 'precedes under relation') + - "⊱": [t: "thành công dưới sự quan hệ"] # 0x22b1 (en: 'succeeds under relation') + - "⊲": # 0x22b2 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "một nhóm con bình thường của" # (en: 'a normal subgroup of') + - "⊳": [t: "chứa như một nhóm con bình thường"] # 0x22b3 (en: 'contains as a normal subgroup') + - "⊴": # 0x22b4 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "một nhóm con bình thường hoặc bằng" # (en: 'a normal subgroup of or equal to') + - "⊵": [t: "chứa một nhóm con bình thường hoặc bằng"] # 0x22b5 (en: 'contains as a normal subgroup or equal to') + - "⊶": # 0x22b6 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "bản gốc của" # (en: 'the original of') + - "⊷": # 0x22b7 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "một hình ảnh của" # (en: 'an image of') + - "⊸": [t: "multimap"] # 0x22b8 + - "⊹": [t: "ma trận liên hợp hermitian"] # 0x22b9 (en: 'hermitian conjugate matrix') + - "⊺": [t: "xen kẽ"] # 0x22ba (en: 'intercalate') + - "⊻": [t: "xor"] # 0x22bb + - "⊼": [t: "nand"] # 0x22bc + - "⊽": [t: "cũng không"] # 0x22bd (en: 'nor') + - "⊾": [t: "góc vuông với hồ quang"] # 0x22be (en: 'right angle with arc') + - "⊿": [t: "tam giác vuông"] # 0x22bf (en: 'right triangle') + - "⋀": [t: "hợp lý và"] # 0x22c0 (en: 'logical and') + - "⋁": [t: "hợp lý hoặc"] # 0x22c1 (en: 'logical or') + - "⋂": [t: "ngã tư"] # 0x22c2 (en: 'intersection') + - "⋃": [t: "liên hiệp"] # 0x22c3 (en: 'union') + - "⋄": [t: "người vận hành kim cương"] # 0x22c4 (en: 'diamond operator') + - "⋅": [T: "nhân"] # 0x22c5 + - "⋆": [T: "nhân"] # 0x22c6 + - "⋇": [T: "nhân chia"] # 0x22c7 (en: 'division times') + - "⋈": [t: "bowtie"] # 0x22c8 + - "⋉": # 0x22c9 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "các yếu tố bình thường bên trái sản phẩm của" # (en: 'the left normal factor semidirect product of') + - "⋊": # 0x22ca + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "các yếu tố bình thường đúng sản phẩm của" # (en: 'the right normal factor semidirect product of') + - "⋋": # 0x22cb + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "sản phẩm bán kết trái của" # (en: 'the left semidirect product of') + - "⋌": # 0x22cc + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "sản phẩm bán kết đúng của" # (en: 'the right semidirect product of') + - "⋍": [t: "tilde đảo ngược bằng"] # 0x22cd (en: 'reversed tilde equals') + - "⋎": [t: "xoăn logic hoặc"] # 0x22ce (en: 'curly logical or') + - "⋏": [t: "xoăn logic và"] # 0x22cf (en: 'curly logical and') + - "⋐": # 0x22d0 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "một tập hợp con kép của" # (en: 'a double subset of') + - "⋑": # 0x22d1 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "một siêu siêu nhân của" # (en: 'a double superset of') + - "⋒": # 0x22d2 + - test: + if: "$Verbosity!='Terse'" + then: [t: "các"] # (en: 'the') + - t: "giao lộ kép của" # (en: 'double intersection of') + - "⋓": # 0x22d3 + - test: + if: "$Verbosity!='Terse'" + then: [t: "các"] # (en: 'the') + - t: "liên minh kép của" # (en: 'double union of') + - "⋔": # 0x22d4 + - test: + if: "$Verbosity!='Terse'" + then: [t: "các"] # (en: 'the') + - t: "giao lộ thích hợp của" # (en: 'proper intersection of') + - "⋕": # 0x22d5 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "bằng và song song với" # (en: 'equal to and parallel to') + - "⋖": [t: "ít hơn với dấu chấm"] # 0x22d6 (en: 'less than with dot') + - "⋗": [t: "lớn hơn với dấu chấm"] # 0x22d7 (en: 'greater than with dot') + - "⋘": # 0x22d8 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "rất ít hơn nhiều" # (en: 'very much less than') + - "⋙": # 0x22d9 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "rất lớn hơn nhiều so với" # (en: 'very much greater than') + - "⋚": # 0x22da + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "ít hơn bằng hoặc lớn hơn" # (en: 'less than equal to or greater than') + - "⋛": # 0x22db + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "lớn hơn bằng hoặc nhỏ hơn" # (en: 'greater than equal to or less than') + - "⋜": # 0x22dc + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "bằng hoặc nhỏ hơn" # (en: 'equal to or less than') + - "⋝": # 0x22dd + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "bằng hoặc lớn hơn" # (en: 'equal to or greater than') + - "⋞": # 0x22de + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "bằng hoặc trước" # (en: 'equal to or precedes') + - "⋟": # 0x22df + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "bằng hoặc thành công" # (en: 'equal to or succeeds') + - "⋠": [t: "không đi trước cũng như không bằng"] # 0x22e0 (en: 'does not precede nor is equal to') + - "⋡": [t: "không thành công cũng như không bằng"] # 0x22e1 (en: 'does not succeed nor is equal to') + - "⋢": [t: "không phải hình ảnh vuông hoặc bằng"] # 0x22e2 (en: 'not square image of or equal to') + - "⋣": [t: "không phải bản gốc vuông hoặc bằng"] # 0x22e3 (en: 'not square original of or equal to') + - "⋤": [t: "hình ảnh vuông hoặc không bằng"] # 0x22e4 (en: 'square image of or not equal to') + - "⋥": [t: "bản gốc vuông hoặc không bằng"] # 0x22e5 (en: 'square original of or not equal to') + - "⋦": # 0x22e6 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "ít hơn nhưng không tương đương với" # (en: 'less than but not equivalent to') + - "⋧": # 0x22e7 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "lớn hơn nhưng không tương đương với" # (en: 'greater than but not equivalent to') + - "⋨": [t: "đi trước nhưng không tương đương với"] # 0x22e8 (en: 'precedes but is not equivalent to') + - "⋩": [t: "thành công nhưng không tương đương với"] # 0x22e9 (en: 'succeeds but is not equivalent to') + - "⋪": # 0x22ea + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "không phải là một nhóm con bình thường của" # (en: 'not a normal subgroup of') + - "⋫": [t: "không chứa như một nhóm con bình thường"] # 0x22eb (en: 'does not contain as a normal subgroup') + - "⋬": # 0x22ec + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "không phải là một nhóm con bình thường cũng không bằng" # (en: 'not a normal subgroup of nor is equal to') + - "⋭": [t: "không chứa như một nhóm con bình thường cũng như không bằng"] # 0x22ed (en: 'does not contain as a normal subgroup nor is equal to') + - "⋮": [T: "chia hết cho"] # 0x22ee (en: 'vertical ellipsis') + - "⋯": [t: "chấm chấm chấm"] # 0x22ef (en: 'dot dot dot') + - "⋰": [t: "elip chéo lên trên"] # 0x22f0 (en: 'upwards diagonal ellipsis') + - "⋱": [t: "dấu chấm lửng chéo"] # 0x22f1 (en: 'diagonal ellipsis') + - "⋲": [t: "yếu tố của với gạch ngang dài"] # 0x22f2 (en: 'element of with long horizontal stroke') + - "⋳": [t: "yếu tố của thanh dọc ở cuối gạch ngang"] # 0x22f3 (en: 'element of with vertical bar at end of horizontal stroke') + - "⋴": [t: "yếu tố của thanh dọc ở cuối gạch ngang"] # 0x22f4 (en: 'element of with vertical bar at end of horizontal stroke') + - "⋵": [t: "phần tử của với dấu chấm ở trên"] # 0x22f5 (en: 'element of with dot above') + - "⋶": [t: "yếu tố của với overbar"] # 0x22f6 (en: 'element of with overbar') + - "⋷": [t: "yếu tố của với overbar"] # 0x22f7 (en: 'element of with overbar') + - "⋸": [t: "yếu tố của với atarbar"] # 0x22f8 (en: 'element of with underbar') + - "⋹": [t: "yếu tố của hai nét ngang"] # 0x22f9 (en: 'element of with two horizontal strokes') + - "⋺": [t: "chứa với gạch ngang dài"] # 0x22fa (en: 'contains with long horizontal stroke') + - "⋻": [t: "chứa với thanh dọc ở cuối gạch ngang"] # 0x22fb (en: 'contains with vertical bar at end of horizontal stroke') + - "⋼": [t: "chứa với thanh dọc ở cuối gạch ngang"] # 0x22fc (en: 'contains with vertical bar at end of horizontal stroke') + - "⋽": [t: "chứa với overbar"] # 0x22fd (en: 'contains with overbar') + - "⋾": [t: "chứa với overbar"] # 0x22fe (en: 'contains with overbar') + - "⋿": [t: "z ký hiệu thành viên túi"] # 0x22ff (en: 'z notation bag membership') + - "⌀": [t: "đường kính"] # 0x2300 (en: 'diameter') + - "⌁": [t: "mũi tên điện"] # 0x2301 (en: 'electric arrow') + - "⌂": [t: "nhà ở"] # 0x2302 (en: 'house') + - "⌃": [t: "lên đầu mũi tên"] # 0x2303 (en: 'up arrowhead') + - "⌄": [t: "xuống đầu mũi tên"] # 0x2304 (en: 'down arrowhead') + - "⌅": [t: "phóng chiếu"] # 0x2305 (en: 'projective') + - "⌆": [t: "luật xa gần"] # 0x2306 (en: 'perspective') + - "⌇": [t: "đường lượn sóng"] # 0x2307 (en: 'wavy line') + - "⌈": [t: "trần trái"] # 0x2308 (en: 'left ceiling') + - "⌉": [t: "trần phải"] # 0x2309 (en: 'right ceiling') + - "⌊": [t: "tầng trái"] # 0x230a (en: 'left floor') + - "⌋": [t: "tầng phải"] # 0x230b (en: 'right floor') + - "⌌": [t: "đáy bên phải"] # 0x230c (en: 'bottom right crop') + - "⌍": [t: "cây trồng phía dưới bên trái"] # 0x230d (en: 'bottom left crop') + - "⌎": [t: "cây trồng trên cùng bên phải"] # 0x230e (en: 'top right crop') + - "⌏": [t: "cây trồng trên cùng bên trái"] # 0x230f (en: 'top left crop') + - "⌐": [t: "đảo ngược không ký"] # 0x2310 (en: 'reversed not sign') + - "⌑": [t: "hình vuông"] # 0x2311 (en: 'square lozenge') + - "⌒": [t: "cung"] # 0x2312 (en: 'arc') + - "⌓": [t: "bộ phận"] # 0x2313 (en: 'segment') + - "⌔": [t: "khu vực"] # 0x2314 (en: 'sector') + - "⌕": [t: "máy ghi âm điện thoại"] # 0x2315 (en: 'telephone recorder') + - "⌖": [t: "chỉ số vị trí crosshairs"] # 0x2316 (en: 'position indicator crosshairs') + - "⌗": [t: "quảng trường viewdata"] # 0x2317 (en: 'viewdata square') + - "⌘": [t: "nơi có dấu hiệu quan tâm"] # 0x2318 (en: 'place of interest sign') + - "⌙": [t: "biến không ký"] # 0x2319 (en: 'turned not sign') + - "⌚": [t: "đồng hồ"] # 0x231a (en: 'watch') + - "⌛": [t: "đồng hồ cát"] # 0x231b (en: 'hourglass') + - "⌜": [t: "góc trên bên trái"] # 0x231c (en: 'top left corner') + - "⌝": [t: "góc trên bên phải"] # 0x231d (en: 'top right corner') + - "⌞": [t: "góc dưới bên trái"] # 0x231e (en: 'bottom left corner') + - "⌟": [t: "góc dưới bên phải"] # 0x231f (en: 'bottom right corner') + - "⌠": [t: "nửa đầu tích phân"] # 0x2320 (en: 'top half integral') + - "⌡": [t: "nửa dưới tích phân"] # 0x2321 (en: 'bottom half integral') + - "⌢": [t: "nhăn mặt"] # 0x2322 (en: 'frown') + - "⌣": [t: "nụ cười"] # 0x2323 (en: 'smile') + - "⌤": [t: "lên đầu mũi tên giữa hai thanh ngang"] # 0x2324 (en: 'up arrowhead between two horizontal bars') + - "⌥": [t: "khóa tùy chọn"] # 0x2325 (en: 'option key') + - "⌦": [t: "xóa sang phải"] # 0x2326 (en: 'erase to the right') + - "⌧": [t: "x trong một hộp hình chữ nhật"] # 0x2327 (en: 'x in a rectangle box') + - "⌨": [t: "bàn phím"] # 0x2328 (en: 'keyboard') + - "〈": [t: "bên trái chỉ khung góc"] # 0x2329 (en: 'left pointing angle bracket') + - "〉": [t: "bên phải góc khung"] # 0x232a (en: 'right pointing angle bracket') + - "⌫": [t: "xóa sang trái"] # 0x232b (en: 'erase to the left') + - "⌬": [t: "vòng benzen"] # 0x232c (en: 'benzene ring') + - "⌭": [t: "hình trụ"] # 0x232d (en: 'cylindricity') + - "⌮": [t: "tất cả xung quanh hồ sơ"] # 0x232e (en: 'all around profile') + - "⌯": [t: "đối diện"] # 0x232f (en: 'symmetry') + - "⌰": [t: "tổng số chạy"] # 0x2330 (en: 'total runout') + - "⌱": [t: "nguồn gốc kích thước"] # 0x2331 (en: 'dimension origin') + - "⌲": [t: "hình nón côn"] # 0x2332 (en: 'conical taper') + - "⌳": [t: "dốc"] # 0x2333 (en: 'slope') + - "⌴": [t: "đối trọng"] # 0x2334 (en: 'counterbore') + - "⌵": [t: "cấm"] # 0x2335 (en: 'countersink') + - "⍰": [t: "hộp không xác định"] # 0x2370 (en: 'unknown box') + - "⎕": [t: "hộp"] # 0x2395 (en: 'box') + - "⏜": [t: "cung"] # 0x23DC (en: 'top paren') + - "⏞": [t: "nẹp trên cùng"] # 0x23DE (en: 'top brace') + - "⏟": [t: "niềng răng dưới cùng"] # 0x23DF (en: 'bottom brace') + - "①-⑨": # 0x2460 - 0x2469 + - t: "khoanh tròn" # (en: 'circled') + - spell: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" + - "⑩": [t: "bao quanh mười"] # 0x2469 (en: 'circled ten') + - "⑪": [t: "vòng mười một"] # 0x246a (en: 'circled eleven') + - "⑫": [t: "bao quanh mười hai"] # 0x246b (en: 'circled twelve') + - "⑬": [t: "bao quanh mười ba"] # 0x246c (en: 'circled thirteen') + - "⑭": [t: "vòng mười bốn"] # 0x246d (en: 'circled fourteen') + - "⑮": [t: "bao quanh mười lăm"] # 0x246e (en: 'circled fifteen') + - "⑯": [t: "vòng mười sáu"] # 0x246f (en: 'circled sixteen') + - "⑰": [t: "vòng mười bảy"] # 0x2470 (en: 'circled seventeen') + - "⑱": [t: "khoanh tròn ateen"] # 0x2471 (en: 'circled eighteen') + - "⑱": [t: "vòng mười chín"] # 0x2471 (en: 'circled nineteen') + - "⑳": [t: "bao quanh hai mươi"] # 0x2473 (en: 'circled twenty') + - "⑴-⑼": # 0x2474 - 0x247d + - t: "dấu ngoặc đơn" # (en: 'parenthesized') + - spell: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" + - "⑽": [t: "dấu ngoặc đơn mười"] # 0x247d (en: 'parenthesized ten') + - "⑾": [t: "dấu ngoặc đơn mười một"] # 0x247e (en: 'parenthesized eleven') + - "⑿": [t: "dấu ngoặc đơn mười hai"] # 0x247f (en: 'parenthesized twelve') + - "⒀": [t: "ngoặc đơn mười ba"] # 0x2480 (en: 'parenthesized thirteen') + - "⒁": [t: "dấu ngoặc đơn mười bốn"] # 0x2481 (en: 'parenthesized fourteen') + - "⒂": [t: "dấu ngoặc đơn mười lăm"] # 0x2482 (en: 'parenthesized fifteen') + - "⒃": [t: "dấu ngoặc đơn mười sáu"] # 0x2483 (en: 'parenthesized sixteen') + - "⒄": [t: "dấu ngoặc đơn mười bảy"] # 0x2484 (en: 'parenthesized seventeen') + - "⒅": [t: "dấu ngoặc đơn ateen"] # 0x2485 (en: 'parenthesized eighteen') + - "⒆": [t: "dấu ngoặc đơn mười chín"] # 0x2486 (en: 'parenthesized nineteen') + - "⒇": [t: "ngoặc đơn hai mươi"] # 0x2487 (en: 'parenthesized twenty') + - "⒈-⒐": # 0x2488 - 0x2491 + - spell: "translate('.', '⒈⒉⒊⒋⒌⒍⒎⒏⒐', '123456789')" + - t: "với thời gian" # (en: 'with period') + - "⒑": [t: "mười với thời gian"] # 0x2491 (en: 'ten with period') + - "⒒": [t: "mười một với thời gian"] # 0x2492 (en: 'eleven with period') + - "⒓": [t: "mười hai với thời gian"] # 0x2493 (en: 'twelve with period') + - "⒔": [t: "mười ba với thời gian"] # 0x2494 (en: 'thirteen with period') + - "⒕": [t: "mười bốn với thời gian"] # 0x2495 (en: 'fourteen with period') + - "⒖": [t: "mười lăm với thời gian"] # 0x2496 (en: 'fifteen with period') + - "⒗": [t: "mười sáu thời gian"] # 0x2497 (en: 'sixteen with period') + - "⒘": [t: "mười bảy với thời gian"] # 0x2498 (en: 'seventeen with period') + - "⒙": [t: "ateen có thời gian"] # 0x2499 (en: 'eighteen with period') + - "⒚": [t: "mười chín với thời gian"] # 0x249a (en: 'nineteen with period') + - "⒛": [t: "hai mươi với thời gian"] # 0x249b (en: 'twenty with period') + - "⒜-⒵": # 0x249c - 0x24b5 + - t: "dấu ngoặc đơn" # (en: 'parenthesized') + - spell: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" + + - "Ⓐ-Ⓩ": + - t: "khoanh tròn" # (en: 'circled') + - spell: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "🅐-🅩": # 0x1f150 - 0x1f169 + - t: "khoanh tròn đen" # (en: 'black circled') + - spell: "translate('.', '🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 + - t: "khoanh tròn" # (en: 'circled') + - spell: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" + - "⓪": [t: "vòng tròn số không"] # 0x24ea (en: 'circled zero') + - "⓫": [t: "màu đen vòng mười một"] # 0x24eb (en: 'black circled eleven') + - "⓬": [t: "mười hai vòng màu đen"] # 0x24ec (en: 'black circled twelve') + - "⓭": [t: "mười ba vòng màu đen"] # 0x24ed (en: 'black circled thirteen') + - "⓮": [t: "mười bốn vòng màu đen"] # 0x24ee (en: 'black circled fourteen') + - "⓯": [t: "mười lăm vòng màu đen"] # 0x24ef (en: 'black circled fifteen') + - "⓰": [t: "mười sáu vòng màu đen"] # 0x24f0 (en: 'black circled sixteen') + - "⓱": [t: "mười bảy vòng màu đen"] # 0x24f1 (en: 'black circled seventeen') + - "⓲": [t: "màu đen khoanh tròn ateen"] # 0x24f2 (en: 'black circled eighteen') + - "⓳": [t: "mười chín vòng màu đen"] # 0x24f3 (en: 'black circled nineteen') + - "⓴": [t: "đen vòng hai mươi"] # 0x24f4 (en: 'black circled twenty') + - "⓵-⓽": # 0x24f5 - 0x24fe + - t: "gấp đôi khoanh tròn" # (en: 'double circled') + - spell: "translate('.', '⓵⓶⓷⓸⓹⓺⓻⓼⓽', '123456789')" + - "⓾": [t: "gấp đôi vòng mười"] # 0x24fe (en: 'double circled ten') + - "⓿": [t: "màu đen vòng không"] # 0x24ff (en: 'black circled zero') + - "■": [t: "quảng trường đen"] # 0x25a0 (en: 'black square') + - "□": [t: "quảng trường trắng"] # 0x25a1 (en: 'white square') + - "▢": [t: "quảng trường trắng với các góc tròn"] # 0x25a2 (en: 'white square with rounded corners') + - "▣": [t: "quảng trường trắng chứa hình vuông nhỏ màu đen"] # 0x25a3 (en: 'white square containing small black square') + - "▤": [t: "hình vuông với lấp đầy ngang"] # 0x25a4 (en: 'square with horizontal fill') + - "▥": [t: "hình vuông với điền vào đỉnh"] # 0x25a5 (en: 'square with verticle fill') + - "▦": [t: "hình vuông với lấp đầy hình chữ thập trực giao"] # 0x25a6 (en: 'square with orthogonal crosshatch fill') + - "▧": [t: "hình vuông với phần trên bên trái đến dưới bên phải"] # 0x25a7 (en: 'square with upper left to lower right fill') + - "▨": [t: "hình vuông với phần trên bên phải đến thấp hơn bên trái"] # 0x25a8 (en: 'square with upper right to lower left fill') + - "▩": [t: "hình vuông với hình chữ thập chéo"] # 0x25a9 (en: 'square with diagonal crosshatch fill') + - "▪": [t: "quảng trường nhỏ màu đen"] # 0x25aa (en: 'black small square') + - "▫": [t: "quảng trường nhỏ màu trắng"] # 0x25ab (en: 'white small square') + - "▬": [t: "hình chữ nhật màu đen"] # 0x25ac (en: 'black rectangle') + - "▭": [t: "hình chữ nhật màu trắng"] # 0x25ad (en: 'white rectangle') + - "▮": [t: "hình chữ nhật thẳng đứng màu đen"] # 0x25ae (en: 'black vertical rectangle') + - "▯": [t: "hình chữ nhật thẳng đứng màu trắng"] # 0x25af (en: 'white vertical rectangle') + - "▰": [t: "hình bình hành đen"] # 0x25b0 (en: 'black parallelogram') + - "▱": [t: "hình bình hành"] # 0x25b1 (en: 'white parallelogram') + - "▲": [t: "màu đen lên tam giác"] # 0x25b2 (en: 'black up pointing triangle') + - "△": [t: "tam giác"] # 0x25b3 (en: 'white up pointing triangle') + - "▴": [t: "màu đen lên hình tam giác nhỏ"] # 0x25b4 (en: 'black up pointing small triangle') + - "▵": [t: "trắng lên hình tam giác nhỏ"] # 0x25b5 (en: 'white up pointing small triangle') + - "▶": [t: "triangle chân phải màu đen"] # 0x25b6 (en: 'black right pointing triangle') + - "▷": [t: "trắng phải hình tam giác"] # 0x25b7 (en: 'white right pointing triangle') + - "▸": [t: "đen phải chỉ hình tam giác nhỏ"] # 0x25b8 (en: 'black right pointing small triangle') + - "▹": [t: "trắng phải chỉ hình tam giác nhỏ"] # 0x25b9 (en: 'white right pointing small triangle') + - "►": [t: "đen bên phải trỏ trỏ"] # 0x25ba (en: 'black right pointing pointer') + - "▻": [t: "trao màu trắng trỏ"] # 0x25bb (en: 'white right pointing pointer') + - "▼": [t: "màu đen xuống hình tam giác"] # 0x25bc (en: 'black down pointing triangle') + - "▽": [t: "trắng xuống hình tam giác"] # 0x25bd (en: 'white down pointing triangle') + - "▾": [t: "đen xuống chỉ hình tam giác nhỏ"] # 0x25be (en: 'black down pointing small triangle') + - "▿": [t: "trắng xuống chỉ hình tam giác nhỏ"] # 0x25bf (en: 'white down pointing small triangle') + - "◀": [t: "tam giác phía bên trái màu đen"] # 0x25c0 (en: 'black left pointing triangle') + - "◁": [t: "trắng bên trái hình tam giác"] # 0x25c1 (en: 'white left pointing triangle') + - "◂": [t: "đen bên trái trỏ tam giác nhỏ"] # 0x25c2 (en: 'black left pointing small triangle') + - "◃": [t: "trắng bên trái trỏ tam giác nhỏ"] # 0x25c3 (en: 'white left pointing small triangle') + - "◄": [t: "đen bên trái trỏ trỏ"] # 0x25c4 (en: 'black left pointing pointer') + - "◅": [t: "trao màu trắng trỏ"] # 0x25c5 (en: 'white left pointing pointer') + - "◆": [t: "kim cương đen"] # 0x25c6 (en: 'black diamond') + - "◇": [t: "kim cương trắng"] # 0x25c7 (en: 'white diamond') + - "◈": [t: "kim cương trắng chứa kim cương nhỏ màu đen"] # 0x25c8 (en: 'white diamond containing black small diamond') + - "◉": [t: "cá"] # 0x25c9 (en: 'fisheye') + - "◊": [t: "hình thoi"] # 0x25ca (en: 'lozenge') + - "○": [t: "vòng tròn màu trắng"] # 0x25cb (en: 'white circle') + - "◌": [t: "vòng tròn chấm"] # 0x25cc (en: 'dotted circle') + - "◍": [t: "vòng tròn với điền dọc"] # 0x25cd (en: 'circle with vertical fill') + - "◎": [t: "bullseye"] # 0x25ce + - "●": [t: "vòng tròn màu đen"] # 0x25cf (en: 'black circle') + - "◐": [t: "vòng tròn với nửa màu đen"] # 0x25d0 (en: 'circle with left half black') + - "◑": [t: "vòng tròn với nửa màu đen bên phải"] # 0x25d1 (en: 'circle with right half black') + - "◒": [t: "vòng tròn với nửa màu đen"] # 0x25d2 (en: 'circle with lower half black') + - "◓": [t: "vòng tròn với nửa màu đen"] # 0x25d3 (en: 'circle with upper half black') + - "◔": [t: "vòng tròn với phần tư phía trên bên phải màu đen"] # 0x25d4 (en: 'circle with upper right quadrant black') + - "◕": [t: "vòng tròn với tất cả trừ phần tư phía trên bên trái màu đen"] # 0x25d5 (en: 'circle with all but upper left quadrant black') + - "◖": [t: "một nửa vòng tròn màu đen"] # 0x25d6 (en: 'left half black circle') + - "◗": [t: "một nửa vòng tròn màu đen"] # 0x25d7 (en: 'right half black circle') + - "◘": [t: "bullet nghịch đảo"] # 0x25d8 (en: 'inverse bullet') + - "◙": [t: "vòng tròn trắng nghịch đảo"] # 0x25d9 (en: 'inverse white circle') + - "◚": [t: "vòng tròn màu trắng nghịch đảo trên"] # 0x25da (en: 'upper half inverse white circle') + - "◛": [t: "vòng tròn trắng nửa dưới"] # 0x25db (en: 'lower half inverse white circle') + - "◜": [t: "vòng cung vòng tròn phía trên bên trái"] # 0x25dc (en: 'upper left quadrant circular arc') + - "◝": [t: "vòng cung tròn góc phần tư phía trên bên phải"] # 0x25dd (en: 'upper right quadrant circular arc') + - "◞": [t: "hồ quang hình tròn góc phần tư dưới bên phải"] # 0x25de (en: 'lower right quadrant circular arc') + - "◟": [t: "vòng cung tròn góc dưới bên trái"] # 0x25df (en: 'lower left quadrant circular arc') + - "◠": [t: "vòng tròn trên"] # 0x25e0 (en: 'upper half circle') + - "◡": [t: "vòng tròn thấp hơn"] # 0x25e1 (en: 'lower half circle') + - "◢": [t: "tam giác bên phải màu đen"] # 0x25e2 (en: 'black lower right triangle') + - "◣": [t: "tam giác bên trái màu đen"] # 0x25e3 (en: 'black lower left triangle') + - "◤": [t: "tam giác màu đen bên trái"] # 0x25e4 (en: 'black upper left triangle') + - "◥": [t: "tam giác phía trên bên phải màu đen"] # 0x25e5 (en: 'black upper right triangle') + - "◦": [t: "thành phần"] # 0x25e6 (en: 'composition') + - "◧": [t: "hình vuông với nửa màu đen"] # 0x25e7 (en: 'square with left half black') + - "◨": [t: "hình vuông với nửa màu đen bên phải"] # 0x25e8 (en: 'square with right half black') + - "◩": [t: "hình vuông với nửa màu đen bên trái"] # 0x25e9 (en: 'square with upper left half black') + - "◪": [t: "hình vuông với nửa bên phải màu đen"] # 0x25ea (en: 'square with lower right half black') + - "◫": [t: "quảng trường trắng với đường chia đôi"] # 0x25eb (en: 'white square with bisecting line') + - "◬": [t: "trắng lên tam giác với dấu chấm"] # 0x25ec (en: 'white up pointing triangle with dot') + - "◭": [t: "lên tam giác chỉ với nửa màu đen trái"] # 0x25ed (en: 'up pointing triangle with left half black') + - "◮": [t: "lên tam giác chỉ với nửa màu đen bên phải"] # 0x25ee (en: 'up pointing triangle with right half black') + - "◯": [t: "vòng tròn lớn"] # 0x25ef (en: 'large circle') + - "◰": [t: "quảng trường trắng với góc phần tư phía trên bên trái"] # 0x25f0 (en: 'white square with upper left quadrant') + - "◱": [t: "quảng trường trắng với góc phần tư phía dưới bên trái"] # 0x25f1 (en: 'white square with lower left quadrant') + - "◲": [t: "quảng trường trắng với góc phần tư phía dưới bên phải"] # 0x25f2 (en: 'white square with lower right quadrant') + - "◳": [t: "quảng trường trắng với góc phần tư phía trên bên phải"] # 0x25f3 (en: 'white square with upper right quadrant') + - "◴": [t: "vòng tròn màu trắng với góc phần tư phía trên bên trái"] # 0x25f4 (en: 'white circle with upper left quadrant') + - "◵": [t: "vòng tròn màu trắng với góc phần tư phía dưới bên trái"] # 0x25f5 (en: 'white circle with lower left quadrant') + - "◶": [t: "vòng tròn màu trắng với góc phần tư phía dưới bên phải"] # 0x25f6 (en: 'white circle with lower right quadrant') + - "◷": [t: "vòng tròn màu trắng với góc phần tư phía trên bên phải"] # 0x25f7 (en: 'white circle with upper right quadrant') + - "◸": [t: "tam giác phía trên bên trái"] # 0x25f8 (en: 'upper left triangle') + - "◹": [t: "tam giác phía trên bên phải"] # 0x25f9 (en: 'upper right triangle') + - "◺": [t: "tam giác dưới bên trái"] # 0x25fa (en: 'lower left triangle') + - "◻": [t: "quảng trường trung bình màu trắng"] # 0x25fb (en: 'white medium square') + - "◼": [t: "quảng trường trung bình màu đen"] # 0x25fc (en: 'black medium square') + - "◽": [t: "quảng trường nhỏ vừa"] # 0x25fd (en: 'white medium small square') + - "◾": [t: "quảng trường nhỏ màu đen"] # 0x25fe (en: 'black medium small square') + - "◿": [t: "tam giác dưới bên phải"] # 0x25ff (en: 'lower right triangle') + - "♠": [t: "bộ đồ thuổng đen"] # 0x2660 (en: 'black spade suit') + - "♡": [t: "bộ đồ trái tim trắng"] # 0x2661 (en: 'white heart suit') + - "♢": [t: "bộ đồ kim cương trắng"] # 0x2662 (en: 'white diamond suit') + - "♣": [t: "bộ đồ câu lạc bộ màu đen"] # 0x2663 (en: 'black club suit') + - "♤": [t: "bộ đồ thuổng trắng"] # 0x2664 (en: 'white spade suit') + - "♥": [t: "bộ đồ trái tim đen"] # 0x2665 (en: 'black heart suit') + - "♦": [t: "bộ đồ kim cương đen"] # 0x2666 (en: 'black diamond suit') + - "♧": [t: "bộ đồ câu lạc bộ trắng"] # 0x2667 (en: 'white club suit') + - "❨": [t: "trung bình bên trái dấu ngoặc đơn trang trí"] # 0x2768 (en: 'medium left parentheses ornament') + - "❩": [t: "dấu ngoặc đơn trung bình trang trí"] # 0x2769 (en: 'medium right parentheses ornament') + - "❪": [t: "trung bình phẳng bên trái dấu ngoặc đơn trang trí"] # 0x276a (en: 'medium flattened left parentheses ornament') + - "❫": [t: "trung bình phẳng bên phải trang trí"] # 0x276b (en: 'medium flattened right parentheses ornament') + - "❬": [t: "trung bình bên trái giá trang trí khung góc"] # 0x276c (en: 'medium left-pointing angle bracket ornament') + - "❭": [t: "trung bình bên phải-góc chỉ trang trí"] # 0x276d (en: 'medium right--pointing angle bracked ornament') + - "❮": [t: "độ nặng góc bên trái dấu ngoặc kép trang trí"] # 0x276e (en: 'heavy left-pointing angle quotation mark ornament') + - "❯": [t: "độ nặng góc phải góc trích dẫn trang trí trang trí"] # 0x276f (en: 'heavy right-pointing angle quotation mark ornament') + - "❰": [t: "giá trang trí góc cực lớn bên trái"] # 0x2770 (en: 'heavy left-pointing angle bracket ornament') + - "❱": [t: "giá trang trí góc phải nặng bên phải"] # 0x2771 (en: 'heavy right-pointing angle bracket ornament') + - "❲": [t: "ánh sáng bên trái chân vật trang trí vỏ rùa"] # 0x2772 (en: 'light left tortoise shell bracket ornament') + - "❳": [t: "ánh sáng bên phải vỏ sò trang trí"] # 0x2773 (en: 'light right tortoise shell bracket ornament') + - "❴": [t: "trung bình bên trái trang trí"] # 0x2774 (en: 'medium left brace ornament') + - "❵": [t: "trang trí nẹp trung bình bên phải"] # 0x2775 (en: 'medium right brace ornament') + - "❶": [t: "màu đen khoanh tròn một"] # 0x2776 (en: 'black circled one') + - "❷": [t: "đen vòng hai"] # 0x2777 (en: 'black circled two') + - "❸": [t: "đen vòng ba"] # 0x2778 (en: 'black circled three') + - "❹": [t: "đen vòng bốn"] # 0x2779 (en: 'black circled four') + - "❺": [t: "đen khoanh tròn năm"] # 0x277a (en: 'black circled five') + - "❻": [t: "đen vòng sáu"] # 0x277b (en: 'black circled six') + - "❼": [t: "đen bao quanh bảy"] # 0x277c (en: 'black circled seven') + - "❽": [t: "màu đen khoanh tròn tại"] # 0x277d (en: 'black circled eight') + - "❾": [t: "đen vòng chín"] # 0x277e (en: 'black circled nine') + - "❿": [t: "mười vòng màu đen"] # 0x277f (en: 'black circled ten') + - "➀": [t: "khoanh tròn sans serif một"] # 0x2780 (en: 'circled sans serif one') + - "➁": [t: "bao quanh sans serif hai"] # 0x2781 (en: 'circled sans serif two') + - "➂": [t: "bao quanh sans serif ba"] # 0x2782 (en: 'circled sans serif three') + - "➃": [t: "bao quanh sans serif bốn"] # 0x2783 (en: 'circled sans serif four') + - "➄": [t: "bao quanh sans serif năm"] # 0x2784 (en: 'circled sans serif five') + - "➅": [t: "bao quanh sans serif sáu"] # 0x2785 (en: 'circled sans serif six') + - "➆": [t: "bao quanh sans serif bảy"] # 0x2786 (en: 'circled sans serif seven') + - "➇": [t: "bao quanh sans serif tại"] # 0x2787 (en: 'circled sans serif eight') + - "➈": [t: "bao quanh sans serif chín"] # 0x2788 (en: 'circled sans serif nine') + - "➉": [t: "bao quanh sans serif mười"] # 0x2789 (en: 'circled sans serif ten') + - "➊": [t: "màu đen khoanh tròn sans serif một"] # 0x278a (en: 'black circled sans serif one') + - "➋": [t: "đen khoanh tròn sans serif hai"] # 0x278b (en: 'black circled sans serif two') + - "➌": [t: "đen kho tròn sans serif ba"] # 0x278c (en: 'black circled sans serif three') + - "➍": [t: "đen kho tròn sans serif bốn"] # 0x278d (en: 'black circled sans serif four') + - "➎": [t: "đen kho tròn sans serif năm"] # 0x278e (en: 'black circled sans serif five') + - "➏": [t: "đen kho tròn sans serif sáu"] # 0x278f (en: 'black circled sans serif six') + - "➐": [t: "đen khoanh tròn sans serif seven"] # 0x2790 (en: 'black circled sans serif seven') + - "➑": [t: "màu đen khoanh tròn sans serif tại"] # 0x2791 (en: 'black circled sans serif eight') + - "➒": [t: "đen kho tròn sans serif chín"] # 0x2792 (en: 'black circled sans serif nine') + - "➓": [t: "màu đen khoanh tròn sans serif ten"] # 0x2793 (en: 'black circled sans serif ten') + - "➔": [t: "mũi tên bên phải nặng"] # 0x2794 (en: 'heavy wide-headed rightwards arrow') + - "➕": [t: "dấu hiệu cộng nặng"] # 0x2795 (en: 'heavy plus sign') + - "➖": [t: "dấu hiệu nặng"] # 0x2796 (en: 'heavy minus sign') + - "➗": [t: "dấu hiệu divison nặng"] # 0x2797 (en: 'heavy divison sign') + - "➘": [t: "mũi tên đông nam nặng"] # 0x2798 (en: 'heavy south east arrow') + - "➙": [t: "mũi tên nặng"] # 0x2799 (en: 'heavy rightwards arrow') + - "➚": [t: "mũi tên đông bắc nặng"] # 0x279a (en: 'heavy north east arrow') + - "➛": [t: "bản thảo điểm bên phải mũi tên"] # 0x279b (en: 'drafting point rightwards arrow') + - "➜": [t: "mũi tên tròn nặng"] # 0x279c (en: 'heavy round-tipped rightwards arrow') + - "➝": [t: "mũi tên phải đầu tam giác"] # 0x279d (en: 'triangle-headed rightwards arrow') + - "➞": [t: "mũi tên đầu phải hình tam giác nặng"] # 0x279e (en: 'heavy triangle-headed rightwards arrow') + - "➟": [t: "mũi tên đầu cơ hình tam giác đứt"] # 0x279f (en: 'dashed triangle-headed rightwards arrow') + - "➠": [t: "mũi tên đầu cơ hình tam giác nặng nề"] # 0x27a0 (en: 'heavy dashed triangle-headed rightwards arrow') + - "➡": [t: "mũi tên bên phải màu đen"] # 0x27a1 (en: 'black rightwards arrow') + - "➢": [t: "ba d trên cùng thắp sáng mũi tên bên phải"] # 0x27a2 (en: 'three d top lighted rightwards arrow') + - "➣": [t: "ba d dưới cùng ánh sáng mũi tên bên phải"] # 0x27a3 (en: 'three d bottom lighted rightwards arrow') + - "➤": [t: "mũi tên bên phải màu đen"] # 0x27a4 (en: 'black rightwards arrowhead') + - "➥": [t: "đen nặng cong xuống và mũi tên phải"] # 0x27a5 (en: 'heavy black curved downwards and rightwards arrow') + - "➦": [t: "đen nặng cong lên trên và mũi tên phải"] # 0x27a6 (en: 'heavy black curved upwards and rightwards arrow') + - "➧": [t: "squat màu đen mũi tên bên phải"] # 0x27a7 (en: 'squat black rightwards arrow') + - "➨": [t: "mũi tên bên phải bên lõm nặng"] # 0x27a8 (en: 'heavy concave-pointed black rightwards arrow') + - "➩": [t: "mũi tên bên phải màu trắng bóng phải"] # 0x27a9 (en: 'right-shaded white rightwards arrow') + - "➪": [t: "mũi tên bên phải màu trắng bên trái"] # 0x27aa (en: 'left-shaded white rightwards arrow') + - "➫": [t: "mũi tên bên phải bị nghiêng mặt về phía sau"] # 0x27ab (en: 'back-tilted shadowed white rightwards arrow') + - "➬": [t: "mũi tên bên phải bóng tối nghiêng trước"] # 0x27ac (en: 'front-tilted shadowed white rightwards arrow') + - "➭": [t: "mũi tên bên phải bóng bên phải thấp"] # 0x27ad (en: 'heavy lower right-shadowed white rightwards arrow') + - "➮": [t: "mũi tên bên phải bóng bên phải nặng"] # 0x27ae (en: 'heavy upper right-shadowed white rightwards arrow') + - "➯": [t: "nổi lên mũi tên bên phải bóng phải dưới bên phải"] # 0x27af (en: 'notched lower right-shadowed white rightwards arrow') + - "➱": [t: "nổi bật trên mũi tên bên phải bóng bên phải"] # 0x27b1 (en: 'notched upper right-shadowed white rightwards arrow') + - "➲": [t: "khoanh tròn mũi tên bên phải màu trắng nặng"] # 0x27b2 (en: 'circled heavy white rightwards arrow') + - "➳": [t: "mũi tên bên phải màu trắng"] # 0x27b3 (en: 'white-feathered rightwards arrow') + - "➴": [t: "mũi tên phía đông nam lông đen"] # 0x27b4 (en: 'black-feathered south east arrow') + - "➵": [t: "mũi tên bên phải màu đen"] # 0x27b5 (en: 'black-feathered rightwards arrow') + - "➶": [t: "mũi tên đông bắc lông đen"] # 0x27b6 (en: 'black-feathered north east arrow') + - "➷": [t: "mũi tên đông nam hạng nặng"] # 0x27b7 (en: 'heavy black-feathered south east arrow') + - "➸": [t: "mũi tên bên phải màu đen nặng"] # 0x27b8 (en: 'heavy black-feathered rightwards arrow') + - "➹": [t: "mũi tên đông bắc hạng nặng"] # 0x27b9 (en: 'heavy black-feathered north east arrow') + - "➺": [t: "teradrop-barbed mũi tên phải"] # 0x27ba (en: 'teradrop-barbed rightwards arrow') + - "➻": [t: "mũi tên bên phải nặng"] # 0x27bb (en: 'heavy teardrop-shanked rightwards arrow') + - "➼": [t: "mũi tên đuôi nêm"] # 0x27bc (en: 'wedge-tailed rightwards arrow') + - "➽": [t: "mũi tên bên phải nặng"] # 0x27bd (en: 'heavy wedge-tailed rightwards arrow') + - "➾": [t: "mở mũi tên bên phải"] # 0x27be (en: 'open-outlined rightwards arrow') + - "⟀": [t: "góc ba chiều"] # 0x27c0 (en: 'three dimensional angle') + - "⟁": [t: "tam giác trắng chứa tam giác nhỏ màu trắng"] # 0x27c1 (en: 'white triangle containing small white triangle') + - "⟂": # 0x27c2 + - test: + if: "$Verbosity!='Terse'" + then: [t: "vuông góc với"] # (en: 'is perpendicular to') + - "⟃": # 0x27c3 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "một tập hợp con mở của" # (en: 'an open subset of') + - "⟄": # 0x27c4 + - test: + if: "$Verbosity!='Terse'" + then: [t: "là"] # (en: 'is') + - t: "một siêu sao mở của" # (en: 'an open superset of') + - "⟅": [t: "phân dấu túi hình chữ s"] # 0x27c5 (en: 'left s-shaped bag delimiter') + - "⟆": [t: "phân dấu túi hình chữ s phải"] # 0x27c6 (en: 'right s-shaped bag delimiter') + - "⟇": [t: "hoặc với dấu chấm bên trong"] # 0x27c7 (en: 'or with dot inside') + - "⟈": [t: "đảo ngược solidus preeding tập hợp con"] # 0x27c8 (en: 'reverse solidus preceeding subset') + - "⟉": [t: "superset preceding solidus"] # 0x27c9 (en: 'superset preceeding solidus') + - "⟊": [t: "thanh dọc với gạch ngang"] # 0x27ca (en: 'vertical bar with horizontal stroke') + - "⟋": [t: "đường chéo tăng toán"] # 0x27cb (en: 'mathematical rising diagonal') + - "⟌": [t: "phân chia dài"] # 0x27cc (en: 'long division') + - "⟍": [t: "đường chéo giảm toán"] # 0x27cd (en: 'mathematical falling diagonal') + - "⟎": [t: "bình phương logic và"] # 0x27ce (en: 'squared logical and') + - "⟏": [t: "bình phương logic hoặc"] # 0x27cf (en: 'squared logical or') + - "⟐": [t: "kim cương trắng với chấm giữa"] # 0x27d0 (en: 'white diamond with centered dot') + - "⟑": [t: "và với dấu chấm"] # 0x27d1 (en: 'and with dot') + - "⟒": [t: "yếu tố mở lên trên"] # 0x27d2 (en: 'element of openning upwards') + - "⟓": [t: "góc dưới bên phải với dấu chấm"] # 0x27d3 (en: 'lower right corner with dot') + - "⟔": [t: "góc trên bên trái với dấu chấm"] # 0x27d4 (en: 'upper left corner with dot') + - "⟕": [t: "bên ngoài tham gia"] # 0x27d5 (en: 'left outer join') + - "⟖": [t: "bên ngoài tham gia"] # 0x27d6 (en: 'right outer join') + - "⟗": [t: "tham gia đầy đủ bên ngoài"] # 0x27d7 (en: 'full outer join') + - "⟘": [t: "lớn lên tack"] # 0x27d8 (en: 'large up tack') + - "⟙": [t: "lớn xuống tack"] # 0x27d9 (en: 'large down tack') + - "⟚": [t: "trái và bên phải turnstile"] # 0x27da (en: 'left and right double turnstile') + - "⟛": [t: "bên trái và bên phải"] # 0x27db (en: 'left and right tack') + - "⟜": [t: "multimap trái"] # 0x27dc (en: 'left multimap') + - "⟝": [t: "long phải tack"] # 0x27dd (en: 'long right tack') + - "⟞": [t: "long trái tack"] # 0x27de (en: 'long left tack') + - "⟟": [t: "lên tack với vòng tròn ở trên"] # 0x27df (en: 'up tack with circle above') + - "⟠": [t: "lozenge chia cho quy tắc ngang"] # 0x27e0 (en: 'lozenge divided by horizontal rule') + - "⟡": [t: "kim cương mặt lõm màu trắng"] # 0x27e1 (en: 'white concave sided diamond') + - "⟢": [t: "kim cương mặt lõm màu trắng với tick trái"] # 0x27e2 (en: 'white concave sided diamond with leftwards tick') + - "⟣": [t: "kim cương mặt lõm màu trắng với tick bên phải"] # 0x27e3 (en: 'white concave sided diamond with rightwards tick') + - "⟤": [t: "quảng trường trắng với đánh dấu trái"] # 0x27e4 (en: 'white square with leftwards tick') + - "⟥": [t: "quảng trường trắng với đánh dấu phải"] # 0x27e5 (en: 'white square with rightwards tick') + - "⟦": [t: "khung vuông màu trắng"] # 0x27e6 (en: 'left white square bracket') + - "⟧": [t: "khung vuông trắng bên phải"] # 0x27e7 (en: 'right white square bracket') + - "⟨": [t: "khung góc trái"] # 0x27e8 (en: 'left angle bracket') + - "⟩": [t: "khung góc phải"] # 0x27e9 (en: 'right angle bracket') + - "⟪": [t: "khung góc hai góc"] # 0x27ea (en: 'left double angle bracket') + - "⟫": [t: "khung góc gấp đôi"] # 0x27eb (en: 'right double angle bracket') + - "⟬": [t: "bên trái khung vỏ rùa trắng"] # 0x27ec (en: 'left white tortoise shell bracket') + - "⟭": [t: "bên phải khung vỏ rùa trắng"] # 0x27ed (en: 'right white tortoise shell bracket') + - "⟮": [t: "bên trái phẳng dấu ngoặc đơn"] # 0x27ee (en: 'left flattened parenthesis') + - "⟯": [t: "bên phải phẳng ngoặc đơn"] # 0x27ef (en: 'right flattened parenthesis') + - "⟰": [t: "mũi tên tăng bốn lần"] # 0x27f0 (en: 'upwards quadruple arrow') + - "⟱": [t: "mũi tên bốn lần xuống"] # 0x27f1 (en: 'downwards quadruple arrow') + - "⟲": [t: "mũi tên vòng tròn ngược chiều kim đồng hồ"] # 0x27f2 (en: 'anticlockwise gapped circle arrow') + - "⟳": [t: "mũi tên vòng tròn theo chiều kim đồng hồ"] # 0x27f3 (en: 'clockwise gapped circle arrow') + - "⟴": [t: "mũi tên phải với vòng tròn"] # 0x27f4 (en: 'right arrow with circled plus') + - "⟵": [t: "mũi tên dài trái"] # 0x27f5 (en: 'long leftwards arrow') + - "⟶": [t: "mũi tên dài phải"] # 0x27f6 (en: 'long rightwards arrow') + - "⟷": [t: "mũi tên dài bên trái"] # 0x27f7 (en: 'long left right arrow') + - "⟸": [t: "mũi tên đôi dài trái"] # 0x27f8 (en: 'long leftwards double arrow') + - "⟹": [t: "mũi tên đôi dài phải"] # 0x27f9 (en: 'long rightwards double arrow') + - "⟺": [t: "mũi tên đôi dài trái bên trái"] # 0x27fa (en: 'long left right double arrow') + - "⟻": [t: "mũi tên dài trái từ thanh"] # 0x27fb (en: 'long leftwards arrow from bar') + - "⟼": [t: "mũi tên dài phải từ thanh"] # 0x27fc (en: 'long rightwards arrow from bar') + - "⟽": [t: "mũi tên đôi dài trái từ thanh"] # 0x27fd (en: 'long leftwards double arrow from bar') + - "⟾": [t: "mũi tên dài gấp đôi từ thanh"] # 0x27fe (en: 'long rightwards double arrow from bar') + - "⟿": [t: "mũi tên squiggle dài phải"] # 0x27ff (en: 'long rightwards squiggle arrow') + - "⤀": [t: "phải hai mũi tên hai đầu với gạch thẳng đứng"] # 0x2900 (en: 'rightwards two headed arrow with vertical stroke') + - "⤁": [t: "phải hai mũi tên hai đầu với gạch thẳng đứng"] # 0x2901 (en: 'rightwards two headed arrow with double vertical stroke') + - "⤂": [t: "mũi tên đôi bên trái với gạch dọc"] # 0x2902 (en: 'leftwards double arrow with vertical stroke') + - "⤃": [t: "mũi tên kép phải với gạch dọc"] # 0x2903 (en: 'rightwards double arrow with vertical stroke') + - "⤄": [t: "mũi tên kép bên trái với gạch dọc"] # 0x2904 (en: 'left right double arrow with vertical stroke') + - "⤅": [t: "phải hai mũi tên hai đầu từ thanh"] # 0x2905 (en: 'rightwards two headed arrow from bar') + - "⤆": [t: "mũi tên đôi bên trái từ thanh"] # 0x2906 (en: 'leftwards double arrow from bar') + - "⤇": [t: "mũi tên kép bên phải từ thanh"] # 0x2907 (en: 'rightwards double arrow from bar') + - "⤈": [t: "mũi tên xuống với gạch ngang"] # 0x2908 (en: 'downwards arrow with horizontal stroke') + - "⤉": [t: "mũi tên hướng lên với gạch ngang"] # 0x2909 (en: 'upwards arrow with horizontal stroke') + - "⤊": [t: "mũi tên tăng ba"] # 0x290a (en: 'upwards triple arrow') + - "⤋": [t: "mũi tên ba xuống xuống"] # 0x290b (en: 'downwards triple arrow') + - "⤌": [t: "mũi tên double double bên trái"] # 0x290c (en: 'leftwards double dash arrow') + - "⤍": [t: "mũi tên double double bên phải"] # 0x290d (en: 'rightwards double dash arrow') + - "⤎": [t: "mũi tên ba dash bên trái"] # 0x290e (en: 'leftwards triple dash arrow') + - "⤏": [t: "mũi tên ba bên phải"] # 0x290f (en: 'rightwards triple dash arrow') + - "⤐": [t: "phải hai mũi tên ba đầu"] # 0x2910 (en: 'rightwards two headed triple dash arrow') + - "⤑": [t: "mũi tên phải với thân chấm chấm"] # 0x2911 (en: 'rightwards arrow with dotted stem') + - "⤒": [t: "mũi tên hướng lên đến thanh"] # 0x2912 (en: 'upwards arrow to bar') + - "⤓": [t: "mũi tên xuống thanh"] # 0x2913 (en: 'downwards arrow to bar') + - "⤔": [t: "mũi tên phải với đuôi và gạch dọc"] # 0x2914 (en: 'rightwards arrow with tail and vertical stroke') + - "⤕": [t: "mũi tên phải với đuôi và gạch dọc"] # 0x2915 (en: 'rightwards arrow with tail and double vertical stroke') + - "⤖": [t: "phải hai mũi tên hai đầu với đuôi"] # 0x2916 (en: 'rightwards two headed arrow with tail') + - "⤗": [t: "phải hai mũi tên hai đầu với đuôi với gạch thẳng đứng"] # 0x2917 (en: 'rightwards two headed arrow with tail with vertical stroke') + - "⤘": [t: "phải hai mũi tên hai đầu với đuôi với gạch thẳng đứng"] # 0x2918 (en: 'rightwards two headed arrow with tail with double vertical stroke') + - "⤙": [t: "đuôi mũi tên trái"] # 0x2919 (en: 'leftwards arrow tail') + - "⤚": [t: "đuôi mũi tên phải"] # 0x291a (en: 'rightwards arrow tail') + - "⤛": [t: "đuôi hai mũi tên trái"] # 0x291b (en: 'leftwards double arrow tail') + - "⤜": [t: "đuôi mũi tên kép phải"] # 0x291c (en: 'rightwards double arrow tail') + - "⤝": [t: "mũi tên trái vào kim cương đầy"] # 0x291d (en: 'leftwards arrow to filled diamond') + - "⤞": [t: "mũi tên bên phải vào kim cương đầy"] # 0x291e (en: 'rightwards arrow to filled diamond') + - "⤟": [t: "mũi tên trái từ thanh đến kim cương đầy"] # 0x291f (en: 'leftwards arrow from bar to filled diamond') + - "⤠": [t: "mũi tên bên phải từ thanh đến kim cương đầy"] # 0x2920 (en: 'rightwards arrow from bar to filled diamond') + - "⤡": [t: "mũi tên tây bắc và đông nam"] # 0x2921 (en: 'north west and south east arrow') + - "⤢": [t: "mũi tên đông bắc và tây nam"] # 0x2922 (en: 'north east and south west arrow') + - "⤣": [t: "mũi tên tây bắc với móc"] # 0x2923 (en: 'north west arrow with hook') + - "⤤": [t: "mũi tên đông bắc với móc"] # 0x2924 (en: 'north east arrow with hook') + - "⤥": [t: "mũi tên đông nam với móc"] # 0x2925 (en: 'south east arrow with hook') + - "⤦": [t: "mũi tên tây nam với móc"] # 0x2926 (en: 'south west arrow with hook') + - "⤧": [t: "mũi tên tây bắc và mũi tên đông bắc"] # 0x2927 (en: 'north west arrow and north east arrow') + - "⤨": [t: "mũi tên đông bắc và mũi tên đông nam"] # 0x2928 (en: 'north east arrow and south east arrow') + - "⤩": [t: "mũi tên đông nam và mũi tên tây nam"] # 0x2929 (en: 'south east arrow and south west arrow') + - "⤪": [t: "mũi tên tây nam và mũi tên tây bắc"] # 0x292a (en: 'south west arrow and north west arrow') + - "⤫": [t: "vượt qua đường chéo đi chéo"] # 0x292b (en: 'rising diagonal crossing falling diagonal') + - "⤬": [t: "ngã đường chéo chéo chéo"] # 0x292c (en: 'falling diagonal crossing rising diagonal') + - "⤭": [t: "mũi tên đông nam băng qua mũi tên đông bắc"] # 0x292d (en: 'south east arrow crossing north east arrow') + - "⤮": [t: "mũi tên đông bắc băng qua mũi tên đông nam"] # 0x292e (en: 'north east arrow crossing south east arrow') + - "⤯": [t: "ngã đường chéo băng qua mũi tên đông bắc"] # 0x292f (en: 'falling diagonal crossing north east arrow') + - "⤰": [t: "tăng đường chéo băng qua mũi tên đông nam"] # 0x2930 (en: 'rising diagonal crossing south east arrow') + - "⤱": [t: "mũi tên đông bắc băng qua mũi tên tây bắc"] # 0x2931 (en: 'north east arrow crossing north west arrow') + - "⤲": [t: "mũi tên tây bắc băng qua mũi tên đông bắc"] # 0x2932 (en: 'north west arrow crossing north east arrow') + - "⤳": [t: "mũi tên sóng chỉ trực tiếp bên phải"] # 0x2933 (en: 'wave arrow pointing directly right') + - "⤴": [t: "mũi tên chỉ ngay sau đó cong lên trên"] # 0x2934 (en: 'arrow pointing rightwards then curving upwards') + - "⤵": [t: "mũi tên chỉ ngay sau đó cong xuống"] # 0x2935 (en: 'arrow pointing rightwards then curving downwards') + - "⤶": [t: "mũi tên hướng xuống dưới rồi cong trái"] # 0x2936 (en: 'arrow pointing downwards then curving leftwards') + - "⤷": [t: "mũi tên chỉ xuống dưới rồi cong phải"] # 0x2937 (en: 'arrow pointing downwards then curving rightwards') + - "⤸": [t: "bên bên phải arc mũi tên theo chiều kim đồng hồ"] # 0x2938 (en: 'right side arc clockwise arrow') + - "⤹": [t: "bên bên trái arc mũi tên ngược chiều kim đồng hồ"] # 0x2939 (en: 'left side arc anticlockwise arrow') + - "⤺": [t: "vòng cung hàng đầu mũi tên chống theo chiều kim đồng hồ"] # 0x293a (en: 'top arc anticlockwise arrow') + - "⤻": [t: "vòng cung dưới cùng mũi tên chống theo chiều kim đồng hồ"] # 0x293b (en: 'bottom arc anticlockwise arrow') + - "⤼": [t: "mũi tên vòng cung trên cùng theo chiều kim đồng hồ với điểm trừ"] # 0x293c (en: 'top arc clockwise arrow with minus') + - "⤽": [t: "mũi tên phản kháng hàng đầu với plus"] # 0x293d (en: 'top arc anticlockwise arrow with plus') + - "⤾": [t: "hạ mũi tên bán nguyệt bên phải"] # 0x293e (en: 'lower right semicircular clockwise arrow') + - "⤿": [t: "mũi tên phản kháng dưới hình bán nguyệt bên trái"] # 0x293f (en: 'lower left semicircular anticlockwise arrow') + - "⥀": [t: "mũi tên vòng tròn kín ngược chiều kim đồng hồ"] # 0x2940 (en: 'anticlockwise closed circle arrow') + - "⥁": [t: "mũi tên vòng tròn kín theo chiều kim đồng hồ"] # 0x2941 (en: 'clockwise closed circle arrow') + - "⥂": [t: "mũi tên bên phải phía trên mũi tên ngắn trái"] # 0x2942 (en: 'rightwards arrow above short leftwards arrow') + - "⥃": [t: "mũi tên trái phía trên mũi tên ngắn phải"] # 0x2943 (en: 'leftwards arrow above short rightwards arrow') + - "⥄": [t: "mũi tên ngắn bên phải phía trên mũi tên trái"] # 0x2944 (en: 'short rightwards arrow above leftwards arrow') + - "⥅": [t: "mũi tên bên phải với cộng với bên dưới"] # 0x2945 (en: 'rightwards arrow with plus below') + - "⥆": [t: "mũi tên trái với cộng với bên dưới"] # 0x2946 (en: 'leftwards arrow with plus below') + - "⥇": [t: "mũi tên phải qua x"] # 0x2947 (en: 'rightwards arrow through x') + - "⥈": [t: "mũi tên trái qua vòng tròn"] # 0x2948 (en: 'left right arrow through circle') + - "⥉": [t: "lên tới hai mũi tên đầu từ circle"] # 0x2949 (en: 'upwards two headed arrow from circle') + - "⥊": [t: "bên trái barb lên bên phải barb xuống harpoon"] # 0x294a (en: 'left barb up right barb down harpoon') + - "⥋": [t: "bên trái barb xuống bên phải barb up harpoon"] # 0x294b (en: 'left barb down right barb up harpoon') + - "⥌": [t: "lên barb phải xuống barb trái harpoon"] # 0x294c (en: 'up barb right down barb left harpoon') + - "⥍": [t: "lên barb trái xuống barb phải harpoon"] # 0x294d (en: 'up barb left down barb right harpoon') + - "⥎": [t: "bên trái barb lên bên phải barb lên harpoon"] # 0x294e (en: 'left barb up right barb up harpoon') + - "⥏": [t: "lên barb ngay xuống barb phải harpoon"] # 0x294f (en: 'up barb right down barb right harpoon') + - "⥐": [t: "bên trái barb xuống bên phải barb xuống harpoon"] # 0x2950 (en: 'left barb down right barb down harpoon') + - "⥑": [t: "lên barb trái xuống barb trái harpoon"] # 0x2951 (en: 'up barb left down barb left harpoon') + - "⥒": [t: "harpoon trái với barb lên đến bar"] # 0x2952 (en: 'leftwards harpoon with barb up to bar') + - "⥓": [t: "harpoon phải với barb lên đến bar"] # 0x2953 (en: 'rightwards harpoon with barb up to bar') + - "⥔": [t: "harpoon hướng lên với barb ngay để thanh"] # 0x2954 (en: 'upwards harpoon with barb right to bar') + - "⥕": [t: "downwards harpoon với barb ngay để thanh"] # 0x2955 (en: 'downwards harpoon with barb right to bar') + - "⥖": [t: "harpoon trái với barb xuống bar"] # 0x2956 (en: 'leftwards harpoon with barb down to bar') + - "⥗": [t: "harpoon phải với barb xuống bar"] # 0x2957 (en: 'rightwards harpoon with barb down to bar') + - "⥘": [t: "harpoon đi lên với barb trái để thanh"] # 0x2958 (en: 'upwards harpoon with barb left to bar') + - "⥙": [t: "downwards harpoon với barb rời khỏi quán bar"] # 0x2959 (en: 'downwards harpoon with barb left to bar') + - "⥚": [t: "harpoon trái với barb lên từ quán bar"] # 0x295a (en: 'leftwards harpoon with barb up from bar') + - "⥛": [t: "harpoon phải với barb lên từ bar"] # 0x295b (en: 'rightwards harpoon with barb up from bar') + - "⥜": [t: "harpoon đi lên với barb ngay từ quán bar"] # 0x295c (en: 'upwards harpoon with barb right from bar') + - "⥝": [t: "downwards harpoon với barb ngay từ quán bar"] # 0x295d (en: 'downwards harpoon with barb right from bar') + - "⥞": [t: "harpoon trái với barb xuống từ bar"] # 0x295e (en: 'leftwards harpoon with barb down from bar') + - "⥟": [t: "harpoon phải với barb xuống từ bar"] # 0x295f (en: 'rightwards harpoon with barb down from bar') + - "⥠": [t: "harpoon đi lên với barb còn lại từ quán bar"] # 0x2960 (en: 'upwards harpoon with barb left from bar') + - "⥡": [t: "downwards harpoon với barb rời khỏi quán bar"] # 0x2961 (en: 'downwards harpoon with barb left from bar') + - "⥢": [t: "harpoon bên trái với barb lên trên harpoon bên trái với barb down"] # 0x2962 (en: 'leftwards harpoon with barb up above leftwards harpoon with barb down') + - "⥣": [t: "harpoon đi lên với barb bên trái bên cạnh harpoon với barb phải"] # 0x2963 (en: 'upwards harpoon with barb left beside upwards harpoon with barb right') + - "⥤": [t: "harpoon phải với barb lên trên harpoon bên phải với barb down"] # 0x2964 (en: 'rightwards harpoon with barb up above rightwards harpoon with barb down') + - "⥥": [t: "downwards harpoon với barb bên trái bên cạnh harpoon với barb phải"] # 0x2965 (en: 'downwards harpoon with barb left beside downwards harpoon with barb right') + - "⥦": [t: "harpoon bên trái với barb lên trên harpoon bên phải với barb up"] # 0x2966 (en: 'leftwards harpoon with barb up above rightwards harpoon with barb up') + - "⥧": [t: "harpoon bên trái với barb xuống phía trên harpoon bên phải với barb down"] # 0x2967 (en: 'leftwards harpoon with barb down above rightwards harpoon with barb down') + - "⥨": [t: "harpoon phải với barb lên trên harpoon bên trái với barb up"] # 0x2968 (en: 'rightwards harpoon with barb up above leftwards harpoon with barb up') + - "⥩": [t: "harpoon phải với barb xuống phía trên harpoon bên trái với barb down"] # 0x2969 (en: 'rightwards harpoon with barb down above leftwards harpoon with barb down') + - "⥪": [t: "harpoon bên trái với barb lên trên dash dài"] # 0x296a (en: 'leftwards harpoon with barb up above long dash') + - "⥫": [t: "harpoon bên trái với barb xuống bên dưới dấu gạch ngang dài"] # 0x296b (en: 'leftwards harpoon with barb down below long dash') + - "⥬": [t: "harpoon bên phải với barb lên trên dash dài"] # 0x296c (en: 'rightwards harpoon with barb up above long dash') + - "⥭": [t: "harpoon bên phải với barb xuống bên dưới dash dài"] # 0x296d (en: 'rightwards harpoon with barb down below long dash') + - "⥮": [t: "harpoon đi lên với barb bên trái bên cạnh harpoon với barb phải"] # 0x296e (en: 'upwards harpoon with barb left beside downwards harpoon with barb right') + - "⥯": [t: "downwards harpoon với barb bên trái bên cạnh harpoon với barb phải"] # 0x296f (en: 'downwards harpoon with barb left beside upwards harpoon with barb right') + - "⥰": [t: "mũi tên đôi phải với đầu tròn"] # 0x2970 (en: 'right double arrow with rounded head') + - "⥱": [t: "bằng với mũi tên bên phải"] # 0x2971 (en: 'equals above rightwards arrow') + - "⥲": [t: "toán tử tilde phía trên mũi tên bên phải"] # 0x2972 (en: 'tilde operator above rightwards arrow') + - "⥳": [t: "mũi tên trái phía trên toán tử tilde"] # 0x2973 (en: 'leftwards arrow above tilde operator') + - "⥴": [t: "mũi tên bên phải phía trên toán tử tilde"] # 0x2974 (en: 'rightwards arrow above tilde operator') + - "⥵": [t: "mũi tên bên phải trên gần như bằng"] # 0x2975 (en: 'rightwards arrow above almost equal to') + - "⥶": [t: "ít hơn mũi tên bên trái"] # 0x2976 (en: 'less than above leftwards arrow') + - "⥷": [t: "mũi tên trái qua ít hơn"] # 0x2977 (en: 'leftwards arrow through less than') + - "⥸": [t: "lớn hơn mũi tên bên phải trên"] # 0x2978 (en: 'greater than above rightwards arrow') + - "⥹": [t: "tập hợp con trên mũi tên phải"] # 0x2979 (en: 'subset above rightwards arrow') + - "⥺": [t: "mũi tên trái qua tập hợp con"] # 0x297a (en: 'leftwards arrow through subset') + - "⥻": [t: "superset phía trên mũi tên trái"] # 0x297b (en: 'superset above leftwards arrow') + - "⥼": [t: "đuôi cá trái"] # 0x297c (en: 'left fish tail') + - "⥽": [t: "đuôi cá phải"] # 0x297d (en: 'right fish tail') + - "⥾": [t: "lên đuôi cá"] # 0x297e (en: 'up fish tail') + - "⥿": [t: "xuống đuôi cá"] # 0x297f (en: 'down fish tail') + - "⦀": [t: "triple dọc thanh phân định"] # 0x2980 (en: 'triple vertical bar delimiter') + - "⦁": [t: "z ký hiệu ký hiệu"] # 0x2981 (en: 'z notation spot') + - "⦂": [t: "z ký hiệu loại đại tràng"] # 0x2982 (en: 'z notation type colon') + - "⦃": [t: "nẹp trắng"] # 0x2983 (en: 'left white brace') + - "⦄": [t: "niềng răng trắng phải"] # 0x2984 (en: 'right white brace') + - "⦅": [t: "dấu ngoặc đơn trắng"] # 0x2985 (en: 'left white parenthesis') + - "⦆": [t: "dấu ngoặc đơn trắng bên phải"] # 0x2986 (en: 'right white parenthesis') + - "⦇": [t: "z ký hiệu bên trái khung hình ảnh"] # 0x2987 (en: 'z notation left image bracket') + - "⦈": [t: "z ký hiệu bên phải khung hình ảnh"] # 0x2988 (en: 'z notation right image bracket') + - "⦉": [t: "z ký hiệu bên trái khung liên kết"] # 0x2989 (en: 'z notation left binding bracket') + - "⦊": [t: "z ký hiệu bên phải khung liên kết"] # 0x298a (en: 'z notation right binding bracket') + - "⦋": [t: "khung vuông bên trái với unterbar"] # 0x298b (en: 'left square bracket with underbar') + - "⦌": [t: "khung vuông bên phải với atarbar"] # 0x298c (en: 'right square bracket with underbar') + - "⦍": [t: "khung vuông bên trái với tích tắc ở góc trên cùng"] # 0x298d (en: 'left square bracket with tick in top corner') + - "⦎": [t: "khung vuông bên phải với tích tắc ở góc dưới cùng"] # 0x298e (en: 'right square bracket with tick in bottom corner') + - "⦏": [t: "khung vuông bên trái với tích tắc ở góc dưới cùng"] # 0x298f (en: 'left square bracket with tick in bottom corner') + - "⦐": [t: "khung vuông bên phải với tích tắc ở góc trên cùng"] # 0x2990 (en: 'right square bracket with tick in top corner') + - "⦑": [t: "khung góc trái với dấu chấm"] # 0x2991 (en: 'left angle bracket with dot') + - "⦒": [t: "khung góc phải với dấu chấm"] # 0x2992 (en: 'right angle bracket with dot') + - "⦓": [t: "vòng cung trái ít hơn khung"] # 0x2993 (en: 'left arc less than bracket') + - "⦔": [t: "arc bên phải lớn hơn giá đỡ"] # 0x2994 (en: 'right arc greater than bracket') + - "⦕": [t: "double left arc lớn hơn giá đỡ"] # 0x2995 (en: 'double left arc greater than bracket') + - "⦖": [t: "double bên phải vòng cung ít hơn khung"] # 0x2996 (en: 'double right arc less than bracket') + - "⦗": [t: "để lại khung vỏ rùa đen"] # 0x2997 (en: 'left black tortoise shell bracket') + - "⦘": [t: "bên phải khung vỏ rùa đen"] # 0x2998 (en: 'right black tortoise shell bracket') + - "⦙": [t: "hàng rào chấm"] # 0x2999 (en: 'dotted fence') + - "⦚": [t: "đường ngoằn ngoèo dọc"] # 0x299a (en: 'vertical zigzag line') + - "⦛": [t: "đo góc mở bên trái"] # 0x299b (en: 'measured angle opening left') + - "⦜": [t: "biến góc bên phải với hình vuông"] # 0x299c (en: 'right angle varient with square') + - "⦝": [t: "đo góc bên phải với dấu chấm"] # 0x299d (en: 'measured right angle with dot') + - "⦞": [t: "góc với s bên trong"] # 0x299e (en: 'angle with s inside') + - "⦟": [t: "góc nhọn"] # 0x299f (en: 'acute angle') + - "⦠": [t: "góc spehrical mở bên trái"] # 0x29a0 (en: 'spehrical angle opening left') + - "⦡": [t: "góc spehrical mở ra"] # 0x29a1 (en: 'spehrical angle opening up') + - "⦢": [t: "quay góc"] # 0x29a2 (en: 'turned angle') + - "⦣": [t: "góc đảo ngược"] # 0x29a3 (en: 'reversed angle') + - "⦤": [t: "góc với atarbar"] # 0x29a4 (en: 'angle with underbar') + - "⦥": [t: "góc đảo ngược với unterbar"] # 0x29a5 (en: 'reversed angle with underbar') + - "⦦": [t: "góc xiên mở ra"] # 0x29a6 (en: 'oblique angle opening up') + - "⦧": [t: "góc xiên mở xuống"] # 0x29a7 (en: 'oblique angle opening down') + - "⦨": [t: "đo góc với đầu cánh tay mở trong mũi tên chỉ lên và sang phải"] # 0x29a8 (en: 'measured angle with open arm ending in arrow pointing up and to the right') + - "⦩": [t: "đo góc với đầu cánh tay mở trong mũi tên hướng lên và bên trái"] # 0x29a9 (en: 'measured angle with open arm ending in arrow pointing up and to the left') + - "⦪": [t: "đo góc với đầu cánh tay mở trong mũi tên chỉ xuống và bên phải"] # 0x29aa (en: 'measured angle with open arm ending in arrow pointing down and to the right') + - "⦫": [t: "đo góc với đầu cánh tay mở trong mũi tên chỉ xuống và bên trái"] # 0x29ab (en: 'measured angle with open arm ending in arrow pointing down and to the left') + - "⦬": [t: "đo góc với đầu cánh tay mở trong mũi tên hướng thẳng và lên"] # 0x29ac (en: 'measured angle with open arm ending in arrow pointing right and up') + - "⦭": [t: "đo góc với đầu cánh tay mở trong mũi tên hướng sang trái và lên"] # 0x29ad (en: 'measured angle with open arm ending in arrow pointing left and up') + - "⦮": [t: "đo góc với đầu cánh tay mở trong mũi tên chỉ thẳng và xuống"] # 0x29ae (en: 'measured angle with open arm ending in arrow pointing right and down') + - "⦯": [t: "đo góc với đầu cánh tay mở trong mũi tên hướng sang trái và xuống"] # 0x29af (en: 'measured angle with open arm ending in arrow pointing left and down') + - "⦰": [t: "đảo ngược bộ trống"] # 0x29b0 (en: 'reversed empty set') + - "⦱": [t: "bộ trống với thanh toán quá mức"] # 0x29b1 (en: 'empty set with overbar') + - "⦲": [t: "bộ trống với vòng tròn nhỏ ở trên"] # 0x29b2 (en: 'empty set with small circle above') + - "⦳": [t: "bộ trống với mũi tên phải ở trên"] # 0x29b3 (en: 'empty set with right arrow above') + - "⦴": [t: "bộ trống với mũi tên trái ở trên"] # 0x29b4 (en: 'empty set with left arrow above') + - "⦵": [t: "vòng tròn với thanh ngang"] # 0x29b5 (en: 'circle with horizontal bar') + - "⦶": [t: "bao quanh thanh dọc"] # 0x29b6 (en: 'circled vertical bar') + - "⦷": [t: "bao quanh song song"] # 0x29b7 (en: 'circled parallel') + - "⦸": [t: "khoanh tròn đảo ngược solidus"] # 0x29b8 (en: 'circled reverse solidus') + - "⦹": [t: "khoanh tròn vuông góc"] # 0x29b9 (en: 'circled perpendicular') + - "⦺": [t: "được khoanh tròn chia cho thanh ngang và nửa trên chia cho thanh dọc"] # 0x29ba (en: 'circled divided by horizontal bar and top half divided by vertical bar') + - "⦻": [t: "vòng tròn với x chồng chất x"] # 0x29bb (en: 'circle with superimposed x') + - "⦼": [t: "bao quanh dấu hiệu phân chia quay ngược chiều kim đồng hồ"] # 0x29bc (en: 'circled anticlockwise rotated division sign') + - "⦽": [t: "lên mũi tên qua vòng tròn"] # 0x29bd (en: 'up arrow through circle') + - "⦾": [t: "vòng đạn trắng bao quanh"] # 0x29be (en: 'circled white bullet') + - "⦿": [t: "vòng đạn khoanh tròn"] # 0x29bf (en: 'circled bullet') + - "⧀": [t: "khoanh tròn ít hơn"] # 0x29c0 (en: 'circled less than') + - "⧁": [t: "bao quanh lớn hơn"] # 0x29c1 (en: 'circled greater than') + - "⧂": [t: "vòng tròn với vòng tròn nhỏ ở bên phải"] # 0x29c2 (en: 'circle with small circle to the right') + - "⧃": [t: "vòng tròn với hai nét ngang ở bên phải"] # 0x29c3 (en: 'circle with two horizontal strokes to the right') + - "⧄": [t: "squared tăng chéo chéo"] # 0x29c4 (en: 'squared rising diagonal slash') + - "⧅": [t: "squared rơi chéo chéo"] # 0x29c5 (en: 'squared falling diagonal slash') + - "⧆": [t: "dấu hoa thị bình phương"] # 0x29c6 (en: 'squared asterisk') + - "⧇": [t: "vòng tròn nhỏ bình phương"] # 0x29c7 (en: 'squared small circle') + - "⧈": [t: "quảng trường bình phương"] # 0x29c8 (en: 'squared square') + - "⧉": [t: "hai người tham gia quảng trường"] # 0x29c9 (en: 'two joined squares') + - "⧊": [t: "tam giác với dấu chấm ở trên"] # 0x29ca (en: 'triangle with dot above') + - "⧋": [t: "tam giác với atarbar"] # 0x29cb (en: 'triangle with underbar') + - "⧌": [t: "s trong tam giác"] # 0x29cc (en: 's in triangle') + - "⧍": [t: "tam giác với serifs ở dưới cùng"] # 0x29cd (en: 'triangle with serifs at bottom') + - "⧎": [t: "tam giác phải phía trên tam giác trái"] # 0x29ce (en: 'right triangle above left triangle') + - "⧏": [t: "trái timgle bên cạnh thanh dọc"] # 0x29cf (en: 'left triangle beside vertical bar') + - "⧐": [t: "thanh dọc bên cạnh tam giác phải"] # 0x29d0 (en: 'vertical bar beside right triangle') + - "⧑": [t: "bowtie với một nửa màu đen"] # 0x29d1 (en: 'bowtie with left half black') + - "⧒": [t: "bowtie với nửa đen phải"] # 0x29d2 (en: 'bowtie with right half black') + - "⧓": [t: "bowtie đen"] # 0x29d3 (en: 'black bowtie') + - "⧔": [t: "lần với một nửa màu đen"] # 0x29d4 (en: 'times with left half black') + - "⧕": [t: "lần với nửa màu đen bên phải"] # 0x29d5 (en: 'times with right half black') + - "⧖": [t: "đồng hồ cát trắng"] # 0x29d6 (en: 'white hourglass') + - "⧗": [t: "đồng hồ cát đen"] # 0x29d7 (en: 'black hourglass') + - "⧘": [t: "để lại hàng rào đau khổ"] # 0x29d8 (en: 'left wiggly fence') + - "⧙": [t: "hàng rào phải"] # 0x29d9 (en: 'right wiggly fence') + - "⧚": [t: "để lại đôi hàng rào"] # 0x29da (en: 'left double wiggly fence') + - "⧛": [t: "phải đôi hàng rào wiggly"] # 0x29db (en: 'right double wiggly fence') + - "⧜": [t: "infinity không đầy đủ"] # 0x29dc (en: 'incomplete infinity') + - "⧝": [t: "buộc vô cực"] # 0x29dd (en: 'tie over infinity') + - "⧞": [t: "infinity phủ định với thanh thẳng đứng"] # 0x29de (en: 'infinity negated with vertical bar') + - "⧟": [t: "multimap kết thúc hai lần"] # 0x29df (en: 'double-ended multimap') + - "⧠": [t: "hình vuông với đường viền đường viền"] # 0x29e0 (en: 'square with contoured outline') + - "⧡": [t: "tăng như"] # 0x29e1 (en: 'increases as') + - "⧢": [t: "sản phẩm xáo trộn"] # 0x29e2 (en: 'shuffle product') + - "⧣": [t: "bằng dấu hiệu và song song nghiêng"] # 0x29e3 (en: 'equals sign and slanted parallel') + - "⧤": [t: "bằng dấu hiệu và song song nghiêng với tilde ở trên"] # 0x29e4 (en: 'equals sign and slanted parallel with tilde above') + - "⧥": [t: "giống hệt và nghiêng song song"] # 0x29e5 (en: 'identical to and slanted parallel') + - "⧦": [t: "gleich stark"] # 0x29e6 + - "⧧": [t: "đo nhiệt"] # 0x29e7 (en: 'thermydynamic') + - "⧨": [t: "xuống hình tam giác với nửa màu đen trái"] # 0x29e8 (en: 'down pointing triangle with left half black') + - "⧩": [t: "xuống hình tam giác với nửa màu đen bên phải"] # 0x29e9 (en: 'down pointing triangle with right half black') + - "⧪": [t: "kim cương đen với mũi tên xuống"] # 0x29ea (en: 'black diamond with down arrow') + - "⧫": [t: "black lozenge"] # 0x29eb + - "⧬": [t: "vòng tròn màu trắng với mũi tên xuống"] # 0x29ec (en: 'white circle with down arrow') + - "⧭": [t: "vòng tròn màu đen với mũi tên xuống"] # 0x29ed (en: 'black circle with down arrow') + - "⧮": [t: "quảng trường trắng lỗi"] # 0x29ee (en: 'error-barred white square') + - "⧯": [t: "quảng trường đen lỗi lỗi"] # 0x29ef (en: 'error-barred black square') + - "⧰": [t: "kim cương trắng lỗi lỗi"] # 0x29f0 (en: 'error-barred white diamond') + - "⧱": [t: "kim cương đen lỗi lỗi"] # 0x29f1 (en: 'error-barred black diamond') + - "⧲": [t: "vòng tròn trắng lỗi"] # 0x29f2 (en: 'error-barred white circle') + - "⧳": [t: "vòng tròn đen lỗi"] # 0x29f3 (en: 'error-barred black circle') + - "⧴": [t: "sự triệt tiêu quy tắc"] # 0x29f4 (en: 'rule-delayed') + - "⧵": [t: "hiệu"] # 0x29f5 (en: 'reverse solidus operator') + - "⧶": [t: "solidus với overbar"] # 0x29f6 (en: 'solidus with overbar') + - "⧷": [t: "đảo ngược solidus với gạch ngang"] # 0x29f7 (en: 'reverse solidus with horizontal stroke') + - "⧸": [t: "solidus lớn"] # 0x29f8 (en: 'big solidus') + - "⧹": [t: "solidus đảo ngược lớn"] # 0x29f9 (en: 'big reverse solidus') + - "⧺": [t: "double plus"] # 0x29fa + - "⧻": [t: "triple plus"] # 0x29fb + - "⧼": [t: "bên trái, giá đỡ góc cong"] # 0x29fc (en: 'left pointing curved angle bracket') + - "⧽": [t: "chân phải cong khung góc cong"] # 0x29fd (en: 'right pointing curved angle bracket') + - "⧾": [t: "nhỏ bé"] # 0x29fe (en: 'tiny') + - "⧿": [t: "miny"] # 0x29ff + - "⨀": [t: "toán tử chấm được khoanh tròn"] # 0x2a00 (en: 'circled dot operator') + - "⨁": [t: "tuyến đường cộng với toán tử cộng với"] # 0x2a01 (en: 'circled plus operator') + - "⨂": [t: "nhà điều hành thời gian được khoanh tròn"] # 0x2a02 (en: 'circled times operator') + - "⨃": [t: "nhà điều hành công đoàn với dot"] # 0x2a03 (en: 'union operator with dot') + - "⨄": [t: "nhà điều hành công đoàn với plus"] # 0x2a04 (en: 'union operator with plus') + - "⨅": [t: "toán tử giao lộ vuông"] # 0x2a05 (en: 'square intersection operator') + - "⨆": [t: "nhà điều hành liên minh vuông"] # 0x2a06 (en: 'square union operator') + - "⨇": [t: "hai logic và toán tử"] # 0x2a07 (en: 'two logical and operator') + - "⨈": [t: "hai logic hoặc toán tử"] # 0x2a08 (en: 'two logical or operator') + - "⨉": [t: "nhà điều hành lần"] # 0x2a09 (en: 'times operator') + - "⨊": [t: "modulo hai tổng"] # 0x2a0a (en: 'modulo two sum') + - "⨋": [t: "tổng hợp với tích phân"] # 0x2a0b (en: 'summation with integral') + - "⨌": [t: "toán tử tích phân tứ giác"] # 0x2a0c (en: 'quadruple integral operator') + - "⨍": [t: "tích hợp phần hữu hạn"] # 0x2a0d (en: 'finite part integral') + - "⨎": [t: "tích hợp với gạch đôi"] # 0x2a0e (en: 'integral with double stroke') + - "⨏": [t: "tích hợp trung bình với chém"] # 0x2a0f (en: 'integral average with slash') + - "⨐": [t: "chức năng lưu thông"] # 0x2a10 (en: 'circulation function') + - "⨑": [t: "tích hợp ngược chiều kim đồng hồ"] # 0x2a11 (en: 'anticlockwise integration') + - "⨒": [t: "tích hợp đường với đường hình chữ nhật xung quanh cực"] # 0x2a12 (en: 'line integration with rectangular path around pole') + - "⨓": [t: "tích hợp dòng với đường dẫn hình bán nguyệt xung quanh cực"] # 0x2a13 (en: 'line integration with semicircular path around pole') + - "⨔": [t: "tích hợp dòng không bao gồm cực"] # 0x2a14 (en: 'line integration not including the pole') + - "⨕": [t: "tích hợp xung quanh một toán tử điểm"] # 0x2a15 (en: 'integral around a point operator') + - "⨖": [t: "toán tử tích phân quarternion"] # 0x2a16 (en: 'quaternion integral operator') + - "⨗": [t: "tích hợp với mũi tên trái với móc"] # 0x2a17 (en: 'integral with leftwards arrow with hook') + - "⨘": [t: "tích hợp với dấu hiệu thời gian"] # 0x2a18 (en: 'integral with times sign') + - "⨙": [t: "tích hợp với giao điểm"] # 0x2a19 (en: 'integral with intersection') + - "⨚": [t: "tích hợp với liên minh"] # 0x2a1a (en: 'integral with union') + - "⨛": [t: "tích hợp với overbar"] # 0x2a1b (en: 'integral with overbar') + - "⨜": [t: "tích hợp với underbar"] # 0x2a1c (en: 'integral with underbar') + - "⨝": [t: "tham gia"] # 0x2a1d (en: 'join') + - "⨞": [t: "người vận hành tam giác lớn bên trái"] # 0x2a1e (en: 'large left triangle operator') + - "⨟": [t: "thành phần lược đồ ký hiệu z"] # 0x2a1f (en: 'z notation schema composition') + - "⨠": [t: "z ký hiệu ký đồ đường ống"] # 0x2a20 (en: 'z notation schema piping') + - "⨡": [t: "z ký đồ ký đồ"] # 0x2a21 (en: 'z notation schema projection') + - "⨢": [t: "cộng với dấu hiệu với vòng tròn ở trên"] # 0x2a22 (en: 'plus sign with circle above') + - "⨣": [t: "cộng với dấu hiệu với giọng nói ở trên"] # 0x2a23 (en: 'plus sign with circumflex accent above') + - "⨤": [t: "cộng với dấu hiệu với tilde ở trên"] # 0x2a24 (en: 'plus sign with tilde above') + - "⨥": [t: "cộng với dấu hiệu với dấu chấm dưới đây"] # 0x2a25 (en: 'plus sign with dot below') + - "⨦": [t: "cộng với dấu hiệu với tilde dưới đây"] # 0x2a26 (en: 'plus sign with tilde below') + - "⨧": [t: "cộng với dấu hiệu với chỉ số hai"] # 0x2a27 (en: 'plus sign with subscript two') + - "⨨": [t: "cộng với dấu hiệu với tam giác đen"] # 0x2a28 (en: 'plus sign with black triangle') + - "⨩": [t: "điểm trừ dấu hiệu với dấu phẩy ở trên"] # 0x2a29 (en: 'minus sign with comma above') + - "⨪": [t: "điểm trừ với dấu chấm dưới đây"] # 0x2a2a (en: 'minus sign with dot below') + - "⨫": [t: "điểm trừ với dấu chấm rơi"] # 0x2a2b (en: 'minus sign with falling dots') + - "⨬": [t: "điểm trừ với dấu hiệu tăng"] # 0x2a2c (en: 'minus sign with rising dots') + - "⨭": [t: "cộng với dấu hiệu trong nửa vòng tròn trái"] # 0x2a2d (en: 'plus sign in left half circle') + - "⨮": [t: "cộng với đăng nhập vào nửa vòng tròn bên phải"] # 0x2a2e (en: 'plus sign in right half circle') + - "⨯": [t: "sản phẩm chéo"] # 0x2a2f (en: 'cross product') + - "⨰": [t: "dấu hiệu nhân với dấu chấm ở trên"] # 0x2a30 (en: 'multiplication sign with dot above') + - "⨱": [t: "dấu hiệu nhân với inderbar"] # 0x2a31 (en: 'multiplication sign with underbar') + - "⨲": [t: "sản phẩm bán kết với đóng đáy đóng"] # 0x2a32 (en: 'semidirect product with bottom closed') + - "⨳": [t: "smash sản phẩm"] # 0x2a33 (en: 'smash product') + - "⨴": [t: "dấu nhân trong nửa vòng tròn trái"] # 0x2a34 (en: 'multiplication sign in left half circle') + - "⨵": [t: "đăng nhập nhân trong nửa vòng tròn bên phải"] # 0x2a35 (en: 'multiplication sign in right half circle') + - "⨶": [t: "dấu hiệu nhân được khoanh tròn với giọng nói chu vi"] # 0x2a36 (en: 'circled multiplication sign with circumflex accent') + - "⨷": [t: "hiệu số nhân trong vòng tròn đôi"] # 0x2a37 (en: 'multiplication sign in double circle') + - "⨸": [t: "dấu hiệu phân chia vòng tròn"] # 0x2a38 (en: 'circled division sign') + - "⨹": [t: "cộng với dấu hiệu trong tam giác"] # 0x2a39 (en: 'plus sign in triangle') + - "⨺": [t: "trừ dấu hiệu trong tam giác"] # 0x2a3a (en: 'minus sign in triangle') + - "⨻": [t: "dấu hiệu nhân trong tam giác"] # 0x2a3b (en: 'multiplication sign in triangle') + - "⨼": [t: "sản phẩm nội thất"] # 0x2a3c (en: 'interior product') + - "⨽": [t: "sản phẩm nội thất bên tay"] # 0x2a3d (en: 'righthand interior product') + - "⨮": [t: "z ký hiệu thành phần quan hệ"] # 0x2a2e (en: 'z notation relational composition') + - "⨿": [t: "hợp nhất hoặc coproduct"] # 0x2a3f (en: 'amalgamation or coproduct') + - "⩀": [t: "giao lộ với dấu chấm"] # 0x2a40 (en: 'intersection with dot') + - "⩁": [t: "liên minh với dấu hiệu trừ"] # 0x2a41 (en: 'union with minus sign') + - "⩂": [t: "liên minh với overbar"] # 0x2a42 (en: 'union with overbar') + - "⩃": [t: "giao lộ với overbar"] # 0x2a43 (en: 'intersection with overbar') + - "⩄": [t: "giao lộ với logic và"] # 0x2a44 (en: 'intersection with logical and') + - "⩅": [t: "liên kết với logic hoặc"] # 0x2a45 (en: 'union with logical or') + - "⩆": [t: "liên minh trên giao lộ"] # 0x2a46 (en: 'union above intersection') + - "⩇": [t: "giao lộ trên liên minh"] # 0x2a47 (en: 'intersection above union') + - "⩈": [t: "liên minh trên thanh trên giao lộ"] # 0x2a48 (en: 'union above bar above intersection') + - "⩉": [t: "giao lộ trên thanh trên liên minh"] # 0x2a49 (en: 'intersection above bar above union') + - "⩊": [t: "liên minh bên cạnh và tham gia với liên minh"] # 0x2a4a (en: 'union beside and joined with union') + - "⩋": [t: "giao lộ bên cạnh và tham gia với giao lộ"] # 0x2a4b (en: 'intersection beside and joined with intersection') + - "⩌": [t: "đóng kết hợp với serifs"] # 0x2a4c (en: 'closed union with serifs') + - "⩍": [t: "giao lộ đóng với serifs"] # 0x2a4d (en: 'closed intersection with serifs') + - "⩎": [t: "giao lộ kép vuông"] # 0x2a4e (en: 'double square intersection') + - "⩏": [t: "double square union"] # 0x2a4f + - "⩐": [t: "đóng liên minh với serifs và smash sản phẩm"] # 0x2a50 (en: 'closed union with serifs and smash product') + - "⩑": [t: "logic và với dấu chấm ở trên"] # 0x2a51 (en: 'logical and with dot above') + - "⩒": [t: "logic hoặc với dấu chấm ở trên"] # 0x2a52 (en: 'logical or with dot above') + - "⩓": [t: "gấp đôi logic và"] # 0x2a53 (en: 'double logical and') + - "⩔": [t: "gấp đôi logic hoặc"] # 0x2a54 (en: 'double logical or') + - "⩕": [t: "hai giao nhau logic và"] # 0x2a55 (en: 'two intersecting logical and') + - "⩖": [t: "hai giao nhau logic hoặc"] # 0x2a56 (en: 'two intersecting logical or') + - "⩗": [t: "dốc lớn hoặc"] # 0x2a57 (en: 'sloping large or') + - "⩘": [t: "dốc lớn và"] # 0x2a58 (en: 'sloping large and') + - "⩙": [t: "logic hoặc chồng chéo logic và"] # 0x2a59 (en: 'logical or overlapping logical and') + - "⩚": [t: "logic và với thân giữa"] # 0x2a5a (en: 'logical and with middle stem') + - "⩛": [t: "logic hoặc với thân giữa"] # 0x2a5b (en: 'logical or with middle stem') + - "⩜": [t: "logic và với dấu gạch ngang ngang"] # 0x2a5c (en: 'logical and with horizontal dash') + - "⩝": [t: "logic hoặc với dấu gạch ngang ngang"] # 0x2a5d (en: 'logical or with horizontal dash') + - "⩞": [t: "logic và với gấp đôi obbar"] # 0x2a5e (en: 'logical and with double overbar') + - "⩟": [t: "logic và với unterbar"] # 0x2a5f (en: 'logical and with underbar') + - "⩠": [t: "logic và với đôi bên dưới"] # 0x2a60 (en: 'logical and with double underbar') + - "⩡": [t: "vee nhỏ với atarbar"] # 0x2a61 (en: 'small vee with underbar') + - "⩢": [t: "logic hoặc với gấp đôi obbar"] # 0x2a62 (en: 'logical or with double overbar') + - "⩣": [t: "logic hoặc với đôi bên dưới"] # 0x2a63 (en: 'logical or with double underbar') + - "⩤": [t: "z ký hiệu kháng thể"] # 0x2a64 (en: 'z notation domain antirestriction') + - "⩥": [t: "z ký hiệu phạm vi chống trọng yếu"] # 0x2a65 (en: 'z notation range antirestriction') + - "⩦": [t: "bằng dấu hiệu với dấu chấm dưới đây"] # 0x2a66 (en: 'equals sign with dot below') + - "⩧": [t: "giống hệt với dấu chấm trên"] # 0x2a67 (en: 'identical with dot above') + - "⩨": [t: "thanh ba ngang với gạch dọc"] # 0x2a68 (en: 'triple horizontal bar with double vertical stroke') + - "⩩": [t: "thanh ba ngang với cú đánh thẳng đứng ba"] # 0x2a69 (en: 'triple horizontal bar with triple vertical stroke') + - "⩪": [t: "toán tử tilde với dấu chấm ở trên"] # 0x2a6a (en: 'tilde operator with dot above') + - "⩫": [t: "nhà điều hành tilde với các chấm tăng"] # 0x2a6b (en: 'tilde operator with rising dots') + - "⩬": [t: "tương tự trừ tương tự"] # 0x2a6c (en: 'similar minus similar') + - "⩭": [t: "đồng dạng với dấu chấm ở trên"] # 0x2a6d (en: 'congruent with dot above') + - "⩮": [t: "bằng với dấu hoa thị"] # 0x2a6e (en: 'equals with asterisk') + - "⩯": [t: "gần như bằng với giọng nói chu vi"] # 0x2a6f (en: 'almost equal to with circumflex accent') + - "⩰": [t: "xấp xỉ bằng hoặc bằng"] # 0x2a70 (en: 'approximately equal to or equal to') + - "⩱": [t: "bằng dấu hiệu trên cộng với dấu hiệu"] # 0x2a71 (en: 'equals sign above plus sign') + - "⩲": [t: "cộng với dấu hiệu trên bằng dấu hiệu"] # 0x2a72 (en: 'plus sign above equals sign') + - "⩳": [t: "bằng dấu hiệu trên toán tử tilde"] # 0x2a73 (en: 'equals sign above tilde operator') + - "⩴": [t: "đại tràng gấp đôi bằng nhau"] # 0x2a74 (en: 'double colon equal') + - "⩵": [t: "hai dấu hiệu liên tiếp"] # 0x2a75 (en: 'two consecutive equals signs') + - "⩶": [t: "ba dấu hiệu liên tiếp"] # 0x2a76 (en: 'three consecutive equals signs') + - "⩷": [t: "bằng dấu hiệu với hai chấm trên và hai dấu chấm bên dưới"] # 0x2a77 (en: 'equals sign with two dots above and two dots below') + - "⩸": [t: "tương đương với bốn chấm trên"] # 0x2a78 (en: 'equivalent with four dots above') + - "⩹": [t: "ít hơn với vòng tròn bên trong"] # 0x2a79 (en: 'less than with circle inside') + - "⩺": [t: "lớn hơn với vòng tròn bên trong"] # 0x2a7a (en: 'greater than with circle inside') + - "⩻": [t: "ít hơn với dấu hỏi ở trên"] # 0x2a7b (en: 'less than with question mark above') + - "⩼": [t: "lớn hơn với dấu hỏi ở trên"] # 0x2a7c (en: 'greater than with question mark above') + - "⩽": [t: "nhỏ hơn hoặc nghiêng bằng"] # 0x2a7d (en: 'less than or slanted equal to') + - "⩾": [t: "lớn hơn hoặc nghiêng bằng"] # 0x2a7e (en: 'greater than or slanted equal to') + - "⩿": [t: "nhỏ hơn hoặc nghiêng bằng với dấu chấm bên trong"] # 0x2a7f (en: 'less than or slanted equal to with dot inside') + - "⪀": [t: "lớn hơn hoặc nghiêng bằng với dấu chấm bên trong"] # 0x2a80 (en: 'greater than or slanted equal to with dot inside') + - "⪁": [t: "nhỏ hơn hoặc nghiêng bằng với dấu chấm trên"] # 0x2a81 (en: 'less than or slanted equal to with dot above') + - "⪂": [t: "lớn hơn hoặc nghiêng bằng với dấu chấm trên"] # 0x2a82 (en: 'greater than or slanted equal to with dot above') + - "⪃": [t: "nhỏ hơn hoặc nghiêng bằng với dấu chấm phía trên bên phải"] # 0x2a83 (en: 'less than or slanted equal to with dot above right') + - "⪄": [t: "lớn hơn hoặc nghiêng bằng với dấu chấm phía trên bên trái"] # 0x2a84 (en: 'greater than or slanted equal to with dot above left') + - "⪅": [t: "ít hơn hoặc gần đúng"] # 0x2a85 (en: 'less than or approximate') + - "⪆": [t: "lớn hơn hoặc gần đúng"] # 0x2a86 (en: 'greater than or approximate') + - "⪇": [t: "nhỏ hơn và dòng đơn không bằng"] # 0x2a87 (en: 'less than and single line not equal to') + - "⪈": [t: "lớn hơn và dòng đơn không bằng"] # 0x2a88 (en: 'greater than and single line not equal to') + - "⪉": [t: "ít hơn và không gần đúng"] # 0x2a89 (en: 'less than and not approximate') + - "⪊": [t: "lớn hơn và không gần đúng"] # 0x2a8a (en: 'greater than and not approximate') + - "⪋": [t: "ít hơn so với dòng gấp đôi bằng nhau trên lớn hơn"] # 0x2a8b (en: 'less than above double line equal above greater than') + - "⪌": [t: "lớn hơn dòng gấp đôi trên bằng thấp hơn"] # 0x2a8c (en: 'greater than above double line equal above less than') + - "⪍": [t: "ít hơn trên tương tự hoặc bằng nhau"] # 0x2a8d (en: 'less than above similar or equal') + - "⪎": [t: "lớn hơn trên tương tự hoặc bằng nhau"] # 0x2a8e (en: 'greater than above similar or equal') + - "⪏": [t: "ít hơn trên tương tự ở trên lớn hơn"] # 0x2a8f (en: 'less than above similar above greater than') + - "⪐": [t: "lớn hơn ở trên tương tự ở trên nhỏ hơn"] # 0x2a90 (en: 'greater than above similar above less than') + - "⪑": [t: "ít hơn trên lớn hơn so với dòng kép trên bằng nhau"] # 0x2a91 (en: 'less than above greater than above double line equal') + - "⪒": [t: "lớn hơn trên nhỏ hơn so với dòng gấp đôi bằng nhau"] # 0x2a92 (en: 'greater than above less than above double line equal') + - "⪓": [t: "ít hơn trên nghiêng bằng nhau trên lớn hơn so với trên nghiêng bằng nhau"] # 0x2a93 (en: 'less than above slanted equal above greater than above slanted equal') + - "⪔": [t: "lớn hơn trên nghiêng bằng nhau trên thấp hơn trên nghiêng bằng nhau"] # 0x2a94 (en: 'greater than above slanted equal above less than above slanted equal') + - "⪕": [t: "nghiêng bằng hoặc nhỏ hơn"] # 0x2a95 (en: 'slanted equal to or less than') + - "⪖": [t: "nghiêng bằng hoặc lớn hơn"] # 0x2a96 (en: 'slanted equal to or greater than') + - "⪗": [t: "nghiêng bằng hoặc ít hơn với dấu chấm bên trong"] # 0x2a97 (en: 'slanted equal to or less than with dot inside') + - "⪘": [t: "nghiêng bằng hoặc lớn hơn với dấu chấm bên trong"] # 0x2a98 (en: 'slanted equal to or greater than with dot inside') + - "⪙": [t: "dòng hai bằng hoặc nhỏ hơn"] # 0x2a99 (en: 'double line equal to or less than') + - "⪚": [t: "double dòng bằng hoặc lớn hơn"] # 0x2a9a (en: 'double line equal to or greater than') + - "⪛": [t: "đường đôi nghiêng bằng hoặc nhỏ hơn"] # 0x2a9b (en: 'double line slanted equal to or less than') + - "⪜": [t: "đường đôi nghiêng bằng hoặc lớn hơn"] # 0x2a9c (en: 'double line slanted equal to or greater than') + - "⪝": [t: "tương tự hoặc ít hơn"] # 0x2a9d (en: 'similar or less than') + - "⪞": [t: "tương tự hoặc lớn hơn"] # 0x2a9e (en: 'similar or greater than') + - "⪟": [t: "tương tự ở trên nhỏ hơn trên bằng dấu hiệu"] # 0x2a9f (en: 'similar above less than above equals sign') + - "⪠": [t: "tương tự ở trên lớn hơn trên bằng dấu hiệu"] # 0x2aa0 (en: 'similar above greater than above equals sign') + - "⪡": [t: "kép lồng ít hơn"] # 0x2aa1 (en: 'double nested less than') + - "⪢": [t: "kép lồng nhau lớn hơn"] # 0x2aa2 (en: 'double nested greater than') + - "⪣": [t: "kép lồng ít hơn với atarbar"] # 0x2aa3 (en: 'double nested less than with underbar') + - "⪤": [t: "lớn hơn chồng chéo ít hơn"] # 0x2aa4 (en: 'greater than overlapping less than') + - "⪥": [t: "lớn hơn bên cạnh ít hơn"] # 0x2aa5 (en: 'greater than beside less than') + - "⪦": [t: "ít hơn đóng bởi đường cong"] # 0x2aa6 (en: 'less than closed by curve') + - "⪧": [t: "lớn hơn đóng bởi đường cong"] # 0x2aa7 (en: 'greater than closed by curve') + - "⪨": [t: "ít hơn đóng bởi đường cong trên nghiêng bằng nhau"] # 0x2aa8 (en: 'less than closed by curve above slanted equal') + - "⪩": [t: "lớn hơn đóng bởi đường cong trên nghiêng bằng nhau"] # 0x2aa9 (en: 'greater than closed by curve above slanted equal') + - "⪪": [t: "nhỏ hơn"] # 0x2aaa (en: 'smaller than') + - "⪫": [t: "to hơn"] # 0x2aab (en: 'larger than') + - "⪬": [t: "nhỏ hơn hoặc bằng"] # 0x2aac (en: 'smaller than or equal to') + - "⪭": [t: "lớn hơn hoặc bằng"] # 0x2aad (en: 'larger than or equal to') + - "⪮": [t: "bằng dấu hiệu với gập ghềnh ở trên"] # 0x2aae (en: 'equals sign with bumpy above') + - "⪯": [t: "trước dòng đơn bằng dấu hiệu"] # 0x2aaf (en: 'precedes above single line equals sign') + - "⪰": [t: "thành công trên một dòng tương đương với dấu hiệu"] # 0x2ab0 (en: 'succeeds above single line equals sign') + - "⪱": [t: "tiền định trên dòng đơn không bằng"] # 0x2ab1 (en: 'prededes above single line not equal to') + - "⪲": [t: "thành công trên dòng đơn không bằng"] # 0x2ab2 (en: 'succeeds above single line not equal to') + - "⪳": [t: "trước dấu hiệu tương đương"] # 0x2ab3 (en: 'precedes above equals sign') + - "⪴": [t: "thành công trên dấu bằng"] # 0x2ab4 (en: 'succeeds above equals sign') + - "⪵": [t: "tiền định ở trên không bằng"] # 0x2ab5 (en: 'prededes above not equal to') + - "⪶": [t: "thành công ở trên không bằng"] # 0x2ab6 (en: 'succeeds above not equal to') + - "⪷": [t: "tiền định trên gần như bằng"] # 0x2ab7 (en: 'prededes above almost equal to') + - "⪸": [t: "thành công trên gần như bằng"] # 0x2ab8 (en: 'succeeds above almost equal to') + - "⪹": [t: "trước ở trên không gần như bằng"] # 0x2ab9 (en: 'precedes above not almost equal to') + - "⪺": [t: "thành công ở trên không gần như bằng"] # 0x2aba (en: 'succeeds above not almost equal to') + - "⪻": [t: "gấp đôi trước"] # 0x2abb (en: 'double precedes') + - "⪼": [t: "gấp đôi thành công"] # 0x2abc (en: 'double succeeds') + - "⪽": [t: "tập hợp con với dấu chấm"] # 0x2abd (en: 'subset with dot') + - "⪾": [t: "superset với dấu chấm"] # 0x2abe (en: 'superset with dot') + - "⪿": [t: "tập hợp con với dấu cộng dưới đây"] # 0x2abf (en: 'subset with plus sign below') + - "⫀": [t: "superset với dấu cộng dưới đây"] # 0x2ac0 (en: 'superset with plus sign below') + - "⫁": [t: "tập hợp con với dấu hiệu nhân dưới đây"] # 0x2ac1 (en: 'subset with multiplication sign below') + - "⫂": [t: "superset với dấu hiệu nhân dưới đây"] # 0x2ac2 (en: 'superset with multiplication sign below') + - "⫃": [t: "tập hợp con hoặc bằng với dấu chấm trên"] # 0x2ac3 (en: 'subset of or equal to with dot above') + - "⫄": [t: "superset của hoặc bằng với dấu chấm trên"] # 0x2ac4 (en: 'superset of or equal to with dot above') + - "⫅": [t: "tập hợp con trên bằng dấu hiệu"] # 0x2ac5 (en: 'subset of above equals sign') + - "⫆": [t: "superset của dấu hiệu trên bằng"] # 0x2ac6 (en: 'superset of above equals sign') + - "⫇": [t: "tập hợp con của toán tử tilde trên"] # 0x2ac7 (en: 'subset of above tilde operator') + - "⫈": [t: "superset của toán tử tilde trên"] # 0x2ac8 (en: 'superset of above tilde operator') + - "⫉": [t: "tập hợp con trên gần như bằng"] # 0x2ac9 (en: 'subset of above almost equal to') + - "⫊": [t: "superset của trên gần như bằng"] # 0x2aca (en: 'superset of above almost equal to') + - "⫋": [t: "tập hợp con trên không bằng"] # 0x2acb (en: 'subset above not equal to') + - "⫌": [t: "superset của ở trên không bằng"] # 0x2acc (en: 'superset of above not equal to') + - "⫍": [t: "khối lượng vận hành hộp mở bên trái"] # 0x2acd (en: 'square left open box operator') + - "⫎": [t: "thao tác hộp mở bên phải"] # 0x2ace (en: 'square right open box operator') + - "⫏": [t: "tập hợp con đóng"] # 0x2acf (en: 'closed subset') + - "⫐": [t: "superset khép kín"] # 0x2ad0 (en: 'closed superset') + - "⫑": [t: "tập hợp con đóng hoặc bằng"] # 0x2ad1 (en: 'closed subset or equal to') + - "⫒": [t: "superset đóng hoặc bằng"] # 0x2ad2 (en: 'closed superset or equal to') + - "⫓": [t: "tập hợp con trên superset"] # 0x2ad3 (en: 'subset above superset') + - "⫔": [t: "superset trên tập hợp con"] # 0x2ad4 (en: 'superset above subset') + - "⫕": [t: "tập hợp con trên tập hợp con"] # 0x2ad5 (en: 'subset above subset') + - "⫖": [t: "superset trên superset"] # 0x2ad6 (en: 'superset above superset') + - "⫗": [t: "superset bên cạnh tập hợp con"] # 0x2ad7 (en: 'superset beside subset') + - "⫘": [t: "superset bên cạnh và tham gia bởi dash với tập hợp con"] # 0x2ad8 (en: 'superset beside and joined by dash with subset') + - "⫙": [t: "yếu tố mở xuống dưới"] # 0x2ad9 (en: 'element of opening downwards') + - "⫚": [t: "pitchfork với tee top"] # 0x2ada (en: 'pitchfork with tee top') + - "⫛": [t: "giao lộ ngang"] # 0x2adb (en: 'transversal intersection') + - "⫝̸": [t: "đi"] # 0x2adc (en: 'forking') + - "⫝": [t: "không hợp lệ"] # 0x2add (en: 'nonforking') + - "⫞": [t: "shrot rời khỏi tack"] # 0x2ade (en: 'shrot left tack') + - "⫟": [t: "ngắn xuống tack"] # 0x2adf (en: 'short down tack') + - "⫠": [t: "ngắn lên tack"] # 0x2ae0 (en: 'short up tack') + - "⫡": [t: "vuông góc với s"] # 0x2ae1 (en: 'perpendicular with s') + - "⫢": [t: "thanh dọc ba vòng phải"] # 0x2ae2 (en: 'vertical bar triple right turnstile') + - "⫣": [t: "thanh gấp đôi rẽ trái"] # 0x2ae3 (en: 'double vertical bar left turnstile') + - "⫤": [t: "thanh dọc gấp đôi rẽ trái"] # 0x2ae4 (en: 'vertical bar double left turnstile') + - "⫥": [t: "thanh dọc theo kép rẽ trái"] # 0x2ae5 (en: 'double vertical bar double left turnstile') + - "⫦": [t: "dash dài từ thành viên bên trái của double dọc"] # 0x2ae6 (en: 'long dash from left member of double vertical') + - "⫧": [t: "tóm lại ngắn với overbar"] # 0x2ae7 (en: 'short down tack with overbar') + - "⫨": [t: "short up tack với underbar"] # 0x2ae8 (en: 'short up tack with underbar') + - "⫩": [t: "short up tack trên ngắn xuống tack"] # 0x2ae9 (en: 'short up tack above short down tack') + - "⫪": [t: "nhân đôi tack xuống"] # 0x2aea (en: 'double down tack') + - "⫫": [t: "nhân đôi tack"] # 0x2aeb (en: 'double up tack') + - "⫬": [t: "cú đánh đôi không ký"] # 0x2aec (en: 'double stroke not sign') + - "⫭": [t: "đảo ngược gạch đôi không ký"] # 0x2aed (en: 'reversed double stroke not sign') + - "⫮": [t: "không phân chia với sự phủ định đảo ngược"] # 0x2aee (en: 'does not divide with reversed negation slash') + - "⫯": [t: "đường thẳng đứng với vòng tròn ở trên"] # 0x2aef (en: 'vertical line with circle above') + - "⫰": [t: "đường thẳng đứng với vòng tròn dưới đây"] # 0x2af0 (en: 'vertical line with circle below') + - "⫱": [t: "xuống tack với vòng tròn bên dưới"] # 0x2af1 (en: 'down tack with circle below') + - "⫲": [t: "song song với gạch ngang"] # 0x2af2 (en: 'parallel with horizontal stroke') + - "⫳": [t: "song song với toán tử tilde"] # 0x2af3 (en: 'parallel with tilde operator') + - "⫴": [t: "triple dọc quan hệ nhị phân thanh dọc"] # 0x2af4 (en: 'triple vertical bar binary relation') + - "⫵": [t: "thanh ba dọc với gạch ngang"] # 0x2af5 (en: 'triple vertical bar with horizontal stroke') + - "⫶": [t: "triple colon toán tử"] # 0x2af6 (en: 'triple colon operator') + - "⫷": [t: "triple lồng ít hơn"] # 0x2af7 (en: 'triple nested less than') + - "⫸": [t: "triple lồng nhau lớn hơn"] # 0x2af8 (en: 'triple nested greater than') + - "⫹": [t: "đường đôi nghiêng ít hơn hoặc bằng"] # 0x2af9 (en: 'double line slanted less than or equal to') + - "⫺": [t: "đường đôi nghiêng lớn hơn hoặc bằng"] # 0x2afa (en: 'double line slanted greater than or equal to') + - "⫻": [t: "triple solidus quan hệ nhị phân"] # 0x2afb (en: 'triple solidus binary relation') + - "⫼": [t: "toán tử thanh dọc lớn"] # 0x2afc (en: 'large triple vertical bar operator') + - "⫽": [t: "toán tử đôi solidus"] # 0x2afd (en: 'double solidus operator') + - "⫾": [t: "thanh dọc trắng"] # 0x2afe (en: 'white vertical bar') + - "⫿": [t: "thanh dọc trắng"] # 0x2aff (en: 'white vertical bar') + - "⬀": [t: "mũi tên trắng đông bắc"] # 0x2b00 (en: 'north east white arrow') + - "⬁": [t: "mũi tên tây bắc"] # 0x2b01 (en: 'north west white arrow') + - "⬂": [t: "mũi tên trắng đông nam"] # 0x2b02 (en: 'south east white arrow') + - "⬃": [t: "mũi tên tây nam trắng"] # 0x2b03 (en: 'south west white arrow') + - "⬄": [t: "mũi tên trắng bên trái"] # 0x2b04 (en: 'left right white arrow') + - "⬅": [t: "mũi tên đen trái"] # 0x2b05 (en: 'leftwards black arrow') + - "⬆": [t: "mũi tên màu đen hướng lên trên"] # 0x2b06 (en: 'upwards black arrow') + - "⬇": [t: "mũi tên đen xuống"] # 0x2b07 (en: 'downwards black arrow') + - "⬈": [t: "mũi tên đen đông bắc"] # 0x2b08 (en: 'north east black arrow') + - "⬉": [t: "mũi tên đen tây bắc"] # 0x2b09 (en: 'north west black arrow') + - "⬊": [t: "mũi tên đen đông nam"] # 0x2b0a (en: 'south east black arrow') + - "⬋": [t: "mũi tên đen tây nam"] # 0x2b0b (en: 'south west black arrow') + - "⬌": [t: "mũi tên đen trái bên trái"] # 0x2b0c (en: 'left right black arrow') + - "⬍": [t: "lên xuống mũi tên đen"] # 0x2b0d (en: 'up down black arrow') + - "⬎": [t: "mũi tên bên phải với đầu xuống"] # 0x2b0e (en: 'rightwards arrow with tip downwards') + - "⬏": [t: "mũi tên bên phải với đầu hướng lên"] # 0x2b0f (en: 'rightwards arrow with tip upwards') + - "⬐": [t: "mũi tên trái với đầu xuống"] # 0x2b10 (en: 'leftwards arrow with tip downwards') + - "⬑": [t: "mũi tên trái với đầu hướng lên"] # 0x2b11 (en: 'leftwards arrow with tip upwards') + - "⬒": [t: "hình vuông với nửa màu đen"] # 0x2b12 (en: 'square with top half black') + - "⬓": [t: "hình vuông với nửa màu đen"] # 0x2b13 (en: 'square with bottom half black') + - "⬔": [t: "hình vuông với đường chéo phía trên bên phải màu đen"] # 0x2b14 (en: 'square with upper right diagonal half black') + - "⬕": [t: "hình vuông với một nửa đường chéo bên trái màu đen"] # 0x2b15 (en: 'square with lower left diagonal half black') + - "⬖": [t: "kim cương với nửa màu đen"] # 0x2b16 (en: 'diamond with left half black') + - "⬗": [t: "kim cương với nửa màu đen"] # 0x2b17 (en: 'diamond with right half black') + - "⬘": [t: "kim cương với nửa màu đen"] # 0x2b18 (en: 'diamond with top half black') + - "⬙": [t: "kim cương với nửa màu đen"] # 0x2b19 (en: 'diamond with bottom half black') + - "⬚": [t: "hộp"] # 0x2b1a (en: 'box') + - "⬛": [t: "quảng trường lớn màu đen"] # 0x2b1b (en: 'black large square') + - "⬜": [t: "quảng trường lớn màu trắng"] # 0x2b1c (en: 'white large square') + - "⬝": [t: "quảng trường rất nhỏ"] # 0x2b1d (en: 'black very small square') + - "⬞": [t: "quảng trường màu trắng rất nhỏ"] # 0x2b1e (en: 'white very small square') + - "⬟": [t: "lầu năm góc đen"] # 0x2b1f (en: 'black pentagon') + - "⬠": [t: "lầu năm góc trắng"] # 0x2b20 (en: 'white pentagon') + - "⬡": [t: "hình lục giác trắng"] # 0x2b21 (en: 'white hexagon') + - "⬢": [t: "hình lục giác đen"] # 0x2b22 (en: 'black hexagon') + - "⬣": [t: "hình lục giác đen ngang"] # 0x2b23 (en: 'horizontal black hexagon') + - "⬤": [t: "vòng tròn lớn màu đen"] # 0x2b24 (en: 'black large circle') + - "⬥": [t: "kim cương trung bình màu đen"] # 0x2b25 (en: 'black medium diamond') + - "⬦": [t: "kim cương trung bình màu trắng"] # 0x2b26 (en: 'white medium diamond') + - "⬧": [t: "black medium lozenge"] # 0x2b27 + - "⬨": [t: "trắng trung bình vô hình"] # 0x2b28 (en: 'white medium lozenge') + - "⬩": [t: "kim cương nhỏ màu đen"] # 0x2b29 (en: 'black small diamond') + - "⬪": [t: "black small lozenge"] # 0x2b2a + - "⬫": [t: "màu trắng hình thoi"] # 0x2b2b (en: 'white small lozenge') + - "⬬": [t: "hình elip ngang màu đen"] # 0x2b2c (en: 'black horizontal ellipse') + - "⬭": [t: "hình elip ngang màu trắng"] # 0x2b2d (en: 'white horizontal ellipse') + - "⬮": [t: "hình elip dọc màu đen"] # 0x2b2e (en: 'black vertical ellipse') + - "⬯": [t: "hình elip dọc trắng"] # 0x2b2f (en: 'white vertical ellipse') + - "⬰": [t: "mũi tên trái với vòng tròn nhỏ"] # 0x2b30 (en: 'left arrow with small circle') + - "⬱": [t: "ba mũi tên trái"] # 0x2b31 (en: 'three leftwards arrows') + - "⬲": [t: "mũi tên trái với circled plus"] # 0x2b32 (en: 'left arrow with circled plus') + - "⬳": [t: "mũi tên vỗ tay dài sang trái"] # 0x2b33 (en: 'long leftwards squiggle arrow') + - "⬴": [t: "bên trái hai mũi tên đầu với gạch thẳng đứng"] # 0x2b34 (en: 'leftwards two headed arrow with vertical stroke') + - "⬵": [t: "lettwards hai mũi tên đầu với gạch dọc"] # 0x2b35 (en: 'lettwards two headed arrow with double vertical stroke') + - "⬶": [t: "bên trái hai mũi tên đầu từ thanh"] # 0x2b36 (en: 'leftwards two headed arrow from bar') + - "⬷": [t: "bên trái hai mũi tên ba đầu"] # 0x2b37 (en: 'leftwards two headed triple dash arrow') + - "⬸": [t: "mũi tên trái với thân chấm chấm"] # 0x2b38 (en: 'leftwards arrow with dotted stem') + - "⬹": [t: "mũi tên trái với đuôi với gạch dọc"] # 0x2b39 (en: 'leftwards arrow with tail with vertical stroke') + - "⬺": [t: "mũi tên trái với đuôi với gạch dọc"] # 0x2b3a (en: 'leftwards arrow with tail with double vertical stroke') + - "⬻": [t: "bên trái hai mũi tên đầu với đuôi"] # 0x2b3b (en: 'leftwards two headed arrow with tail') + - "⬼": [t: "bên trái hai mũi tên đầu với đuôi với gạch thẳng đứng"] # 0x2b3c (en: 'leftwards two headed arrow with tail with vertical stroke') + - "⬽": [t: "bên trái hai mũi tên đầu với đuôi với gạch thẳng đứng"] # 0x2b3d (en: 'leftwards two headed arrow with tail with double vertical stroke') + - "⬾": [t: "mũi tên trái qua x"] # 0x2b3e (en: 'leftwards arrow through x') + - "⬿": [t: "mũi tên sóng hướng trực tiếp bên trái"] # 0x2b3f (en: 'wave arrow pointing directly left') + - "⭀": [t: "bằng dấu hiệu phía trên mũi tên trái"] # 0x2b40 (en: 'equals sign above leftwards arrow') + - "⭁": [t: "toán tử tilde đảo ngược phía trên mũi tên trái"] # 0x2b41 (en: 'reverse tilde operator above leftwards arrow') + - "⭂": [t: "mũi tên trái phía trên đảo ngược gần như bằng"] # 0x2b42 (en: 'leftwards arrow above reverse almost equal to') + - "⭃": [t: "mũi tên phải qua lớn hơn"] # 0x2b43 (en: 'rightwards arrow through greater than') + - "⭄": [t: "mũi tên phải qua superret"] # 0x2b44 (en: 'rightwards arrow through superret') + - "⭅": [t: "mũi tên quadurple trái"] # 0x2b45 (en: 'leftwards quadurple arrow') + - "⭆": [t: "mũi tên tăng gấp bốn lần"] # 0x2b46 (en: 'rightwards quadruple arrow') + - "⭇": [t: "toán tử tilde đảo ngược phía trên mũi tên bên phải"] # 0x2b47 (en: 'reverse tilde operator above rightwards arrow') + - "⭈": [t: "mũi tên bên phải phía trên rerverse gần như bằng"] # 0x2b48 (en: 'rightwards arrow above rerverse almost equal to') + - "⭉": [t: "toán tử tilde phía trên mũi tên trái"] # 0x2b49 (en: 'tilde operator above leftwards arrow') + - "⭊": [t: "mũi tên trái trên gần như bằng"] # 0x2b4a (en: 'leftwards arrow above almost equal to') + - "⭋": [t: "mũi tên trái phía trên toán tử tilde ngược"] # 0x2b4b (en: 'leftwards arrow above reverse tilde operator') + - "⭌": [t: "mũi tên bên phải phía trên toán tử tilde ngược"] # 0x2b4c (en: 'rightwards arrow above reverse tilde operator') + - "⭐": [t: "ngôi sao trung bình màu trắng"] # 0x2b50 (en: 'white medium star') + - "⭑": [t: "ngôi sao nhỏ màu đen"] # 0x2b51 (en: 'black small star') + - "⭒": [t: "ngôi sao nhỏ màu trắng"] # 0x2b52 (en: 'white small star') + - "⭓": [t: "đen bên phải chỉ hình lầu năm góc"] # 0x2b53 (en: 'black right pointing pentagon') + - "⭔": [t: "lầu năm góc bên phải màu trắng"] # 0x2b54 (en: 'white right pointing pentagon') + - "⭕": [t: "vòng tròn lớn nặng"] # 0x2b55 (en: 'heavy large circle') + - "⭖": [t: "oval nặng với hình bầu dục bên trong"] # 0x2b56 (en: 'heavy oval with oval inside') + - "⭗": [t: "vòng tròn nặng với vòng tròn bên trong"] # 0x2b57 (en: 'heavy circle with circle inside') + - "⭘": [t: "vòng tròn nặng"] # 0x2b58 (en: 'heavy circle') + - "⭙": [t: "muối nặng"] # 0x2b59 (en: 'heavy circled saltire') + - "⸀": [t: "điểm thay thế góc phải"] # 0x2e00 (en: 'right angle substitution marker') + - "⸁": [t: "góc bên phải chấm đánh dấu thay thế"] # 0x2e01 (en: 'right angle dotted substitution marker') + - "⸂": [t: "khung thay thế trái"] # 0x2e02 (en: 'left substitution bracket') + - "⸃": [t: "khung thay thế đúng"] # 0x2e03 (en: 'right substitution bracket') + - "⸄": [t: "khung thay thế chấm trái"] # 0x2e04 (en: 'left dotted substitution bracket') + - "⸅": [t: "khung thay thế chấm bên phải"] # 0x2e05 (en: 'right dotted substitution bracket') + - "⸆": [t: "nâng cao điểm đánh dấu nội suy"] # 0x2e06 (en: 'raised interpolation marker') + - "⸇": [t: "nâng cao điểm nội suy chấm"] # 0x2e07 (en: 'raised dotted interpolation marker') + - "⸈": [t: "điểm đánh dấu chuyển vị chấm chấm"] # 0x2e08 (en: 'dotted transposition marker marker') + - "⸉": [t: "khung chuyển vị trái"] # 0x2e09 (en: 'left transposition bracket') + - "⸊": [t: "khung chuyển vị bên phải"] # 0x2e0a (en: 'right transposition bracket') + - "⸋": [t: "quảng trường nâng lên"] # 0x2e0b (en: 'raised square') + - "⸌": [t: "bên trái nâng cao khung thiếu sót"] # 0x2e0c (en: 'left raised omission bracket') + - "⸍": [t: "quyền nâng cao khung thiếu sót"] # 0x2e0d (en: 'right raised omission bracket') + - "⸎": [t: "biên tập coronis"] # 0x2e0e (en: 'editorial coronis') + - "⸏": [t: "đoạn văn"] # 0x2e0f (en: 'paragraphos') + - "⸐": [t: "phân đoạn đoạn văn"] # 0x2e10 (en: 'forked paragraphos') + - "⸑": [t: "đảo ngược các đoạn báo"] # 0x2e11 (en: 'reversed forked paragraphos') + - "⸒": [t: "hypodiastole"] # 0x2e12 + - "⸓": [t: "obelos chấm"] # 0x2e13 (en: 'dotted obelos') + - "⸔": [t: "xuống ở ancora"] # 0x2e14 (en: 'downwards ancora') + - "⸕": [t: "lên cao hơn ancora"] # 0x2e15 (en: 'upwards ancora') + - "⸖": [t: "chấm bên phải góc chỉ"] # 0x2e16 (en: 'dotted right pointing angle') + - "⸗": [t: "double xiên dấu gạch nối"] # 0x2e17 (en: 'double oblique hyphen') + - "⸘": [t: "đảo ngược interrobang"] # 0x2e18 (en: 'inverted interrobang') + - "⸙": [t: "nhánh cọ"] # 0x2e19 (en: 'palm branch') + - "⸚": [t: "hyphen với dieresis"] # 0x2e1a (en: 'hyphen with diaeresis') + - "⸛": [t: "tilde với vòng trên"] # 0x2e1b (en: 'tilde with ring above') + - "⸜": [t: "để lại giá thấp"] # 0x2e1c (en: 'left low paraphrase bracket') + - "⸝": [t: "đóng giá trị thấp phải"] # 0x2e1d (en: 'right low paraphrase bracket') + - "⸞": [t: "tilde với dấu chấm ở trên"] # 0x2e1e (en: 'tilde with dot above') + - "⸟": [t: "tilde với dấu chấm dưới đây"] # 0x2e1f (en: 'tilde with dot below') + - "⸠": [t: "thanh thẳng đứng trái với quill"] # 0x2e20 (en: 'left vertical bar with quill') + - "⸡": [t: "thanh thẳng đứng bên phải với quill"] # 0x2e21 (en: 'right vertical bar with quill') + - "⸢": [t: "đỉnh trái giá đỡ"] # 0x2e22 (en: 'top left half bracket') + - "⸣": [t: "đầu tiên bắt đầu bắt đầu"] # 0x2e23 (en: 'top right half bracket') + - "⸤": [t: "dưới cùng bên trái giá đỡ"] # 0x2e24 (en: 'bottom left half bracket') + - "⸥": [t: "dưới cùng bên phải giá đỡ"] # 0x2e25 (en: 'bottom right half bracket') + - "⸦": [t: "bên trái phía bên bạn khung"] # 0x2e26 (en: 'left sideways u bracket') + - "⸧": [t: "bên phải bên bạn khung"] # 0x2e27 (en: 'right sideways u bracket') + - "⸨": [t: "dấu ngoặc đơn trái"] # 0x2e28 (en: 'left double parentheses') + - "⸩": [t: "dấu ngoặc đơn bên phải"] # 0x2e29 (en: 'right double parentheses') + - "⸪": [t: "hai chấm trên một dấu chấm chấm"] # 0x2e2a (en: 'two dots over one dot punctuation') + - "⸫": [t: "một chấm trên hai dấu chấm câu"] # 0x2e2b (en: 'one dot over two dots punctuation') + - "⸬": [t: "bình phương bốn dấu chấm chấm"] # 0x2e2c (en: 'squared four dot punctuation') + - "⸭": [t: "năm dấu chấm"] # 0x2e2d (en: 'five dot mark') + - "⸮": [t: "dấu ấn câu hỏi"] # 0x2e2e (en: 'reversed question mark') + - "ⸯ": [t: "tilde dọc"] # 0x2e2f (en: 'vertical tilde') + - "⸰": [t: "điểm nhẫn"] # 0x2e30 (en: 'ring point') + - "⸱": [t: "từ chấm tách giữa chấm"] # 0x2e31 (en: 'word seperator middle dot') + - "⸲": [t: "biến dấu phẩy"] # 0x2e32 (en: 'turned comma') + - "⸳": [t: "nâng cao chấm"] # 0x2e33 (en: 'raised dot') + - "⸴": [t: "dấu phẩy lớn lên"] # 0x2e34 (en: 'raised comma') + - "⸵": [t: "biến bán nguyệt"] # 0x2e35 (en: 'turned semicolon') + - "⸶": [t: "dao găm với bảo vệ bên trái"] # 0x2e36 (en: 'dagger with left guard') + - "⸷": [t: "dao găm với bảo vệ bên phải"] # 0x2e37 (en: 'dagger with right guard') + - "⸸": [t: "biến dao găm"] # 0x2e38 (en: 'turned dagger') + - "⸹": [t: "dấu hiệu nửa đầu"] # 0x2e39 (en: 'top half section sign') + - "⸺": [t: "hai em đập"] # 0x2e3a (en: 'two em dash') + - "⸻": [t: "ba em đập"] # 0x2e3b (en: 'three em dash') + - "〃": [t: "ditto mark"] # 0x3003 + - "〈": [t: "khung góc trái"] # 0x3008 (en: 'left angle bracket') + - "〉": [t: "khung góc phải"] # 0x3009 (en: 'right angle bracket') + - "《": [t: "khung góc hai góc"] # 0x300a (en: 'left double angle bracket') + - "》": [t: "khung góc gấp đôi"] # 0x300b (en: 'right double angle bracket') + - "「": [t: "khung góc trái"] # 0x300c (en: 'left corner bracket') + - "」": [t: "khung góc phải"] # 0x300d (en: 'right corner bracket') + - "『": [t: "khung góc trắng"] # 0x300e (en: 'left white corner bracket') + - "』": [t: "khung góc trắng bên phải"] # 0x300f (en: 'right white corner bracket') + - "【": [t: "khung màu đen trái"] # 0x3010 (en: 'left black lenticular bracket') + - "】": [t: "bên phải khung hình dạng thấu kính màu đen"] # 0x3011 (en: 'right black lenticular bracket') + - "〔": [t: "khung vỏ rùa trái"] # 0x3014 (en: 'left tortoise shell bracket') + - "〕": [t: "chân sắc con rùa phải"] # 0x3015 (en: 'right tortoise shell bracket') + - "〖": [t: "khung màu trắng trái"] # 0x3016 (en: 'left white lenticular bracket') + - "〗": [t: "quyền trắng trắng trắng"] # 0x3017 (en: 'right white lenticular bracket') + - "〘": [t: "bên trái khung vỏ rùa trắng"] # 0x3018 (en: 'left white tortoise shell bracket') + - "〙": [t: "bên phải khung vỏ rùa trắng"] # 0x3019 (en: 'right white tortoise shell bracket') + - "〚": [t: "khung vuông màu trắng"] # 0x301a (en: 'left white square bracket') + - "〛": [t: "khung vuông trắng bên phải"] # 0x301b (en: 'right white square bracket') + - "〜": [t: "dash sóng"] # 0x301c (en: 'wave dash') + - "〰": [t: "dấu gạch ngang"] # 0x3030 (en: 'wavy dash') + - "㉈": [t: "số mười vòng trên quảng trường đen"] # 0x3248 (en: 'circled number ten on black square') + - "㉉": [t: "số vòng tròn hai mươi trên quảng trường đen"] # 0x3249 (en: 'circled number twenty on black square') + - "㉊": [t: "số vòng tròn ba mươi trên quảng trường đen"] # 0x324a (en: 'circled number thirty on black square') + - "㉋": [t: "số vòng tròn bốn mươi trên quare blacks"] # 0x324b (en: 'circled number forty on blacks quare') + - "㉌": [t: "số lượng số năm mươi trên quảng trường đen"] # 0x324c (en: 'circled number fifty on black square') + - "㉍": [t: "manh số sáu mươi trên quảng trường đen"] # 0x324d (en: 'circled number sixty on black square') + - "㉎": [t: "số vòng tròn bảy mươi trên quảng trường đen"] # 0x324e (en: 'circled number seventy on black square') + - "㉏": [t: "số được khoanh tròn aty trên quảng trường đen"] # 0x324f (en: 'circled number eighty on black square') + - "㉑": [t: "được khoanh tròn số hai mươi mốt"] # 0x3251 (en: 'circled number twenty one') + - "㉒": [t: "được khoanh tròn số hai mươi hai"] # 0x3252 (en: 'circled number twenty two') + - "㉓": [t: "được khoanh tròn số hai mươi ba"] # 0x3253 (en: 'circled number twenty three') + - "㉔": [t: "được khoanh tròn số hai mươi bốn"] # 0x3254 (en: 'circled number twenty four') + - "㉕": [t: "được khoanh tròn số hai mươi lăm"] # 0x3255 (en: 'circled number twenty five') + - "㉖": [t: "được khoanh tròn số hai mươi sáu"] # 0x3256 (en: 'circled number twenty six') + - "㉗": [t: "được khoanh tròn số hai mươi bảy"] # 0x3257 (en: 'circled number twenty seven') + - "㉘": [t: "được khoanh tròn số hai mươi tám"] # 0x3258 (en: 'circled number twenty eight' GPT-5.4 fixed translation) + - "㉙": [t: "được khoanh tròn số hai mươi chín"] # 0x3259 (en: 'circled number twenty nine') + - "㉚": [t: "được khoanh tròn số ba mươi"] # 0x325a (en: 'circled number thirty' GPT-5.4 fixed translation) + - "㉛": [t: "được khoanh tròn số ba mươi mốt"] # 0x325b (en: 'circled number thirty one' GPT-5.4 fixed translation) + - "㉜": [t: "được khoanh tròn số ba mươi hai"] # 0x325c (en: 'circled number thirty two' GPT-5.4 fixed translation) + - "㉝": [t: "được khoanh tròn số ba mươi ba"] # 0x325d (en: 'circled number thirty three' GPT-5.4 fixed translation) + - "㉞": [t: "được khoanh tròn số ba mươi bốn"] # 0x325e (en: 'circled number thirty four') + - "㉟": [t: "được khoanh tròn số ba mươi lăm"] # 0x325f (en: 'circled number thirty five' GPT-5.4 fixed translation) + - "㊱": [t: "được khoanh tròn số ba mươi sáu"] # 0x32b1 (en: 'circled number thirty six' GPT-5.4 fixed translation) + - "㊲": [t: "được khoanh tròn số ba mươi bảy"] # 0x32b2 (en: 'circled number thirty seven', GPT-5.4 fixed translation) + - "㊳": [t: "được khoanh tròn số ba mươi tám"] # 0x32b3 (en: 'circled number thirty eight', GPT-5.4 fixed translation) + - "㊴": [t: "được khoanh tròn số ba mươi chín"] # 0x32b4 (en: 'circled number thirty nine', GPT-5.4 fixed translation) + - "㊵": [t: "được khoanh tròn số bốn mươi"] # 0x32b5 (en: 'circled number forty', GPT-5.4 fixed translation) + - "㊶": [t: "được khoanh tròn số bốn mươi mốt"] # 0x32b6 (en: 'circled number forty one', GPT-5.4 fixed translation) + - "㊷": [t: "được khoanh tròn số bốn mươi hai"] # 0x32b7 (en: 'circled number forty two', GPT-5.4 fixed translation) + - "㊸": [t: "được khoanh tròn số bốn mươi ba"] # 0x32b8 (en: 'circled number forty three', GPT-5.4 fixed translation) + - "㊹": [t: "được khoanh tròn số bốn mươi bốn"] # 0x32b9 (en: 'circled number forty four', GPT-5.4 fixed translation) + - "㊺": [t: "được khoanh tròn số bốn mươi lăm"] # 0x32ba (en: 'circled number forty five', GPT-5.4 fixed translation) + - "㊻": [t: "được khoanh tròn số bốn mươi sáu"] # 0x32bb (en: 'circled number forty six', GPT-5.4 fixed translation) + - "㊼": [t: "được khoanh tròn số bốn mươi bảy"] # 0x32bc (en: 'circled number forty seven', GPT-5.4 fixed translation) + - "㊽": [t: "được khoanh tròn số bốn mươi tám"] # 0x32bd (en: 'circled number forty eight', GPT-5.4 fixed translation) + - "㊾": [t: "được khoanh tròn số bốn mươi chín"] # 0x32be (en: 'circled number forty nine', GPT-5.4 fixed translation) + - "㊿": [t: "được khoanh tròn số năm mươi"] # 0x32bf (en: 'circled number fifty', GPT-5.4 fixed translation) + - "㋌": [t: "thủy ngân"] # 0x32cc (en: 'mercury') + - "㋍": [t: "ergs"] # 0x32cd + - "㋎": [t: "volt điện tử"] # 0x32ce (en: 'electron volts') + - "㋏": [t: "dấu hiệu trách nhiệm hữu hạn"] # 0x32cf (en: 'limited liability sign') + - "㍱": [t: "hectopascals"] # 0x3371 + - "㍲": [t: "daltons"] # 0x3372 + - "㍳": [t: "các đơn vị thiên văn"] # 0x3373 (en: 'astronomical units') + - "㍴": [t: "thanh"] # 0x3374 (en: 'bars') + - "㍵": [t: "o v"] # 0x3375 + - "㍶": [t: "parsecs"] # 0x3376 + - "㍷": [t: "thập phân"] # 0x3377 (en: 'decimeters') + - "㍸": [t: "decimeter bình phương"] # 0x3378 (en: 'decimeters squared') + - "㍹": [t: "decimeter khối"] # 0x3379 (en: 'decimeters cubed') + - "㍺": [t: "đơn vị công cụ"] # 0x337a (en: 'instrumental units') + - "㎀": [t: "picoamp"] # 0x3380 (en: 'picoamps') + - "㎁": [t: "nanoamp"] # 0x3381 (en: 'nanoamps') + - "㎂": [t: "microamp"] # 0x3382 (en: 'microamps') + - "㎃": [t: "milliamps"] # 0x3383 + - "㎄": [t: "kiloamp"] # 0x3384 (en: 'kiloamps') + - "㎅": [t: "kilobyte"] # 0x3385 (en: 'kilobytes') + - "㎆": [t: "megabyte"] # 0x3386 (en: 'megabytes') + - "㎇": [t: "gigabyte"] # 0x3387 (en: 'gigabytes') + - "㎈": [t: "calo"] # 0x3388 (en: 'calories') + - "㎉": [t: "kilocalories"] # 0x3389 + - "㎊": [t: "picofarads"] # 0x338a + - "㎋": [t: "nanofarads"] # 0x338b + - "㎌": [t: "microfarads"] # 0x338c + - "㎍": [t: "micrograms"] # 0x338d + - "㎎": [t: "miligam"] # 0x338e (en: 'milligrams') + - "㎏": [t: "kilôgam"] # 0x338f (en: 'kilograms') + - "㎐": [t: "hertz"] # 0x3390 + - "㎑": [t: "kilohertz"] # 0x3391 + - "㎒": [t: "megahertz"] # 0x3392 + - "㎓": [t: "gigahertz"] # 0x3393 + - "㎔": [t: "terahertz"] # 0x3394 + - "㎕": [t: "microliter"] # 0x3395 (en: 'microliters') + - "㎖": [t: "millileter"] # 0x3396 (en: 'millileters') + - "㎗": [t: "deciliter"] # 0x3397 (en: 'deciliters') + - "㎘": [t: "kiloliter"] # 0x3398 (en: 'kiloliters') + - "㎙": [t: "femtometer"] # 0x3399 (en: 'femtometers') + - "㎚": [t: "nanomet"] # 0x339a (en: 'nanometers') + - "㎛": [t: "micromet"] # 0x339b (en: 'micrometers') + - "㎜": [t: "milimet"] # 0x339c (en: 'millimeters') + - "㎝": [t: "centimet"] # 0x339d (en: 'centimeters') + - "㎞": [t: "km"] # 0x339e (en: 'kilometers') + - "㎟": [t: "bình phương milimet"] # 0x339f (en: 'millimeters squared') + - "㎠": [t: "centimet bình phương"] # 0x33a0 (en: 'centimeters squared') + - "㎡": [t: "mét bình phương"] # 0x33a1 (en: 'meters squared') + - "㎢": [t: "km bình phương"] # 0x33a2 (en: 'kilometers squared') + - "㎣": [t: "milimet khối"] # 0x33a3 (en: 'millimeters cubed') + - "㎤": [t: "centimet hình khối"] # 0x33a4 (en: 'centimeters cubed') + - "㎥": [t: "mét khối"] # 0x33a5 (en: 'meters cubed') + - "㎦": [t: "km khối"] # 0x33a6 (en: 'kilometers cubed') + - "㎧": [t: "mét mỗi giây"] # 0x33a7 (en: 'meters per second') + - "㎨": [t: "mét mỗi giây bình phương"] # 0x33a8 (en: 'meters per second squared') + - "㎩": [t: "pascals"] # 0x33a9 + - "㎪": [t: "kilopascals"] # 0x33aa + - "㎫": [t: "megapascals"] # 0x33ab + - "㎬": [t: "gigapascals"] # 0x33ac + - "㎭": [t: "rads"] # 0x33ad + - "㎮": [t: "rads mỗi giây"] # 0x33ae (en: 'rads per second') + - "㎯": [t: "rads trên bình phương thứ hai"] # 0x33af (en: 'rads per second squared') + - "㎰": [t: "picoseconds"] # 0x33b0 + - "㎱": [t: "nanoseconds"] # 0x33b1 + - "㎲": [t: "micro giây"] # 0x33b2 (en: 'microseconds') + - "㎳": [t: "mili giây"] # 0x33b3 (en: 'milliseconds') + - "㎴": [t: "picovolts"] # 0x33b4 + - "㎵": [t: "nanovolts"] # 0x33b5 + - "㎶": [t: "microvolts"] # 0x33b6 + - "㎷": [t: "millivolts"] # 0x33b7 + - "㎸": [t: "kilovolts"] # 0x33b8 + - "㎹": [t: "megavolts"] # 0x33b9 + - "㎺": [t: "picowatt"] # 0x33ba (en: 'picowatts') + - "㎻": [t: "nanowatt"] # 0x33bb (en: 'nanowatts') + - "㎼": [t: "microwatt"] # 0x33bc (en: 'microwatts') + - "㎽": [t: "milliwatts"] # 0x33bd + - "㎾": [t: "kilowatt"] # 0x33be (en: 'kilowatts') + - "㎿": [t: "megawatt"] # 0x33bf (en: 'megawatts') + - "㏀": [t: "kilo-ohms"] # 0x33c0 + - "㏁": [t: "megaohms"] # 0x33c1 + - "㏂": [t: "attometer"] # 0x33c2 (en: 'attometers') + - "㏃": [t: "becquerels"] # 0x33c3 + - "㏄": [t: "centimet khối"] # 0x33c4 (en: 'cubic centimeters') + - "㏅": [t: "nến"] # 0x33c5 (en: 'candelas') + - "㏆": [t: "coulomb mỗi kg"] # 0x33c6 (en: 'coulombs per kilogram') + - "㏇": [t: "lượng máu tim bơm ra"] # 0x33c7 (en: 'cardiac output') + - "㏈": [t: "decibel"] # 0x33c8 (en: 'decibels') + - "㏉": [t: "grays"] # 0x33c9 + - "㏊": [t: "ha"] # 0x33ca (en: 'hectares') + - "㏋": [t: "mã lực"] # 0x33cb (en: 'horsepower') + - "㏌": [t: "inch"] # 0x33cc (en: 'inches') + - "㏍": [t: "kilokelvins"] # 0x33cd + - "㏎": [t: "km"] # 0x33ce (en: 'kilometers') + - "㏏": [t: "nút thắt"] # 0x33cf (en: 'knots') + - "㏐": [t: "lumens"] # 0x33d0 + - "㏑": [t: "nhật ký tự nhiên"] # 0x33d1 (en: 'natural log') + - "㏒": [t: "logarit"] # 0x33d2 (en: 'logarithm') + - "㏓": [t: "lux"] # 0x33d3 + - "㏔": [t: "millibarns"] # 0x33d4 + - "㏕": [t: "nhà máy"] # 0x33d5 (en: 'mills') + - "㏖": [t: "nốt ruồi"] # 0x33d6 (en: 'moles') + - "㏗": [t: "p h"] # 0x33d7 + - "㏘": [t: "buông điện"] # 0x33d8 (en: 'picometers') + - "㏙": [t: "phần triệu"] # 0x33d9 (en: 'parts per million') + - "㏚": [t: "petaroentgens"] # 0x33da + - "㏛": [t: "steradians"] # 0x33db + - "㏜": [t: "sieverts"] # 0x33dc + - "㏝": [t: "webers"] # 0x33dd + - "㏞": [t: "volt mỗi mét"] # 0x33de (en: 'volts per meter') + - "㏟": [t: "amps mỗi mét"] # 0x33df (en: 'amps per meter') + - "㏿": [t: "gallon"] # 0x33ff (en: 'gallons') + - "": [t: "bằng với mũ bên dưới"] # 0xe900 (en: 'equals with hat below') + - "": [t: "bằng với cộng với ở trên"] # 0xe901 (en: 'equals with plus above') + - "⩲": [t: "bằng với cộng với ở trên"] # 0x2a72 (en: 'equals with plus above') + - "": [t: "bằng với cộng với bên dưới"] # 0xe902 (en: 'equals with plus below') + - "⩱": [t: "bằng với cộng với bên dưới"] # 0x2a71 (en: 'equals with plus below') + - "": [t: "tilde với cộng với ở trên"] # 0xe903 (en: 'tilde with plus above') + - "⨦": [t: "tilde với cộng với ở trên"] # 0x2a26 (en: 'tilde with plus above') + - "": [t: "tilde với cộng với bên dưới"] # 0xe904 (en: 'tilde with plus below') + - "⨤": [t: "tilde với cộng với bên dưới"] # 0x2a24 (en: 'tilde with plus below') + - "": [t: "bằng gấp đôi trên lớn hơn"] # 0xe908 (en: 'equal double over greater than') + - "": [t: "bằng gấp đôi so với ít hơn"] # 0xe909 (en: 'equal double over less than') + - "⪙": [t: "bằng gấp đôi so với ít hơn"] # 0x2a99 (en: 'equal double over less than') + - "": [t: "chứa hoặc bằng"] # 0xe90a (en: 'contains or equal to') + - "⋽": [t: "chứa hoặc bằng"] # 0x22fd (en: 'contains or equal to') + - "": [t: "superset của hoặc bằng"] # 0xe90b (en: 'superset of or equal to') + - "": [t: "tập hợp con hoặc bằng"] # 0xe90c (en: 'subset of or equal to') + - "": [t: "bằng nhau hơn ít hơn"] # 0xe90d (en: 'equal over less than') + - "": [t: "yếu tố hoặc bằng"] # 0xe912 (en: 'element of or equal to') + - "⋷": [t: "yếu tố hoặc bằng"] # 0x22f7 (en: 'element of or equal to') + - "": [t: "bằng hoặc lớn hơn"] # 0xe913 (en: 'equal to or greater than') + - "⪚": [t: "bằng hoặc lớn hơn"] # 0x2a9a (en: 'equal to or greater than') + - "": [t: "superset gần đúng của"] # 0xe914 (en: 'approximate superset of') + - "⫈": [t: "superset gần đúng của"] # 0x2ac8 (en: 'approximate superset of') + - "": [t: "tập hợp con gần đúng của"] # 0xe915 (en: 'approximate subset of') + - "⫇": [t: "tập hợp con gần đúng của"] # 0x2ac7 (en: 'approximate subset of') + - "": [t: "superset của với dot bao gồm như mối quan hệ phụ"] # 0xe916 (en: 'superset of with dot includes as sub relation') + - "⪾": [t: "superset của với dot bao gồm như mối quan hệ phụ"] # 0x2abe (en: 'superset of with dot includes as sub relation') + - "": [t: "tập hợp con với dot được bao gồm trong mối quan hệ phụ"] # 0xe917 (en: 'subset of with dot is included in as sub relation') + - "⪽": [t: "tập hợp con với dot được bao gồm trong mối quan hệ phụ"] # 0x2abd (en: 'subset of with dot is included in as sub relation') + - "": [t: "bằng với dấu chấm bên dưới"] # 0xe918 (en: 'equal with dot below') + - "⩦": [t: "bằng với dấu chấm bên dưới"] # 0x2a66 (en: 'equal with dot below') + - "": [t: "bên trái chấm trên trừ chấm bên phải"] # 0xe919 (en: 'left dot over minus over right dot') + - "": [t: "dấu chấm bên phải trên trừ chấm bên trái"] # 0xe91a (en: 'right dot over minus over left dot') + - "": [t: "gần như bằng trừ"] # 0xe91f (en: 'almost equal to minus') + - "": [t: "cúp vuông đôi"] # 0xe920 (en: 'double square cup') + - "": [t: "double square squalase"] # 0xe921 (en: 'double square cap') + - "": [t: "ít hơn bằng hoặc lớn hơn"] # 0xe922 (en: 'less than equal to or greater than') + - "": [t: "tilde với dấu chấm"] # 0xe924 (en: 'tilde with dot') + - "⩪": [t: "tilde với dấu chấm"] # 0x2a6a (en: 'tilde with dot') + - "": [t: "tilde với hai chấm"] # 0xe925 (en: 'tilde with two dots') + - "": [t: "nhỏ hơn lớn hơn hoặc bằng"] # 0xe926 (en: 'less than greater than or equal to') + - "⪑": [t: "nhỏ hơn lớn hơn hoặc bằng"] # 0x2a91 (en: 'less than greater than or equal to') + - "": [t: "lớn hơn ít hơn hoặc bằng"] # 0xe927 (en: 'greater than less than or equal to') + - "⪒": [t: "lớn hơn ít hơn hoặc bằng"] # 0x2a92 (en: 'greater than less than or equal to') + - "": [t: "tương đương hoặc ít hơn"] # 0xe928 (en: 'equivalent to or less than') + - "⪝": [t: "tương đương hoặc ít hơn"] # 0x2a9d (en: 'equivalent to or less than') + - "": [t: "tương đương hoặc lớn hơn"] # 0xe929 (en: 'equivalent to or greater than') + - "": [t: "toán tử hộp mở"] # 0xe92a (en: 'left open box operator') + - "": [t: "toán tử hộp mở bên phải"] # 0xe92b (en: 'right open box operator') + - "": [t: "giống hệt với dấu chấm"] # 0xe92c (en: 'identical to with dot') + - "": [t: "lớn hơn bằng hoặc nhỏ hơn"] # 0xe92d (en: 'greater than equal to or less than') + - "": [t: "nhà điều hành thanh"] # 0xe92e (en: 'bar operator') + - "": [t: "nhà điều hành thanh đôi"] # 0xe92f (en: 'double bar operator') + - "": [t: "nhà điều hành ba thanh"] # 0xe930 (en: 'triple bar operator') + - "": [t: "nhỏ hơn hoặc xấp xỉ bằng"] # 0xe932 (en: 'less than or approximately equal to') + - "": [t: "lớn hơn hoặc xấp xỉ bằng"] # 0xe933 (en: 'greater than or approximately equal to') + - "": [t: "lồng ít hơn"] # 0xe936 (en: 'nested less than') + - "⪡": [t: "lồng ít hơn"] # 0x2aa1 (en: 'nested less than') + - "": [t: "lồng nhau lớn hơn"] # 0xe937 (en: 'nested greater than') + - "⪢": [t: "lồng nhau lớn hơn"] # 0x2aa2 (en: 'nested greater than') + - "": [t: "trước hoặc tương đương với"] # 0xe93a (en: 'precedes or equivalent to') + - "": [t: "thành công hoặc tương đương với"] # 0xe93b (en: 'succeeds or equivalent to') + - "": [t: "đi trước bằng bằng nhau"] # 0xe940 (en: 'precedes over equal') + - "": [t: "thành công quá bình đẳng"] # 0xe941 (en: 'succeeds over equal') + - "": [t: "ít bằng nhau hơn nghiêng lớn hơn"] # 0xe942 (en: 'less equal slanted greater') + - "": [t: "lớn hơn bằng ít hơn"] # 0xe943 (en: 'greater equal slanted less') + - "": [t: "hài lòng bởi"] # 0xe948 (en: 'satisfied by') + - "": [t: "lười biếng s"] # 0xe949 (en: 'lazy s') + - "": [t: "không khẳng định"] # 0xe94a (en: 'not assertion') + - "": [t: "gấp đôi bằng nhau"] # 0xe94b (en: 'double equal') + - "⩵": [t: "gấp đôi bằng nhau"] # 0x2a75 (en: 'double equal') + - "": [t: "triple bằng nhau"] # 0xe94c (en: 'triple equal') + - "": [t: "quy tắc bị trì hoãn"] # 0xe94d (en: 'rule delayed') + - "⧴": [t: "quy tắc bị trì hoãn"] # 0x29f4 (en: 'rule delayed') + - "": [t: "phân định bí danh"] # 0xe94e (en: 'alias delimiter') + - "": [t: "nhóm con bình thường của thanh"] # 0xe950 (en: 'normal subgroup of with bar') + - "⧏": [t: "nhóm con bình thường của thanh"] # 0x29cf (en: 'normal subgroup of with bar') + - "": [t: "chứa như phân nhóm bình thường với thanh"] # 0xe951 (en: 'contains as normal subgroup with bar') + - "⧐": [t: "chứa như phân nhóm bình thường với thanh"] # 0x29d0 (en: 'contains as normal subgroup with bar') + - "": [t: "vòng ngụ ý"] # 0xe954 (en: 'round implies') + - "⥰": [t: "vòng ngụ ý"] # 0x2970 (en: 'round implies') + - "": [t: "nụ cười dưới quán bar"] # 0xe955 (en: 'smile under bar') + - "": [t: "cau mày trên quán bar"] # 0xe956 (en: 'frown over bar') + - "": [t: "superset của hoặc gần như bằng"] # 0xe957 (en: 'superset of or almost equal to') + - "": [t: "tập hợp con hoặc gần như bằng"] # 0xe958 (en: 'subset of or almost equal to') + - "": [t: "lớn hơn gần như bằng hoặc ít hơn"] # 0xe959 (en: 'greater than almost equal to or less than') + - "": [t: "ít hơn gần như bằng hoặc lớn hơn"] # 0xe95a (en: 'less than almost equal or greater than') + - "": [t: "gấp đôi logic hoặc"] # 0xe95c (en: 'double logical or') + - "⩔": [t: "gấp đôi logic hoặc"] # 0x2a54 (en: 'double logical or') + - "": [t: "gấp đôi logic và"] # 0xe95d (en: 'double logical and') + - "⩓": [t: "gấp đôi logic và"] # 0x2a53 (en: 'double logical and') + - "": [t: "logic hoặc với thanh đôi dưới đây"] # 0xe95e (en: 'logical or with double bar below') + - "": [t: "logic hoặc với thanh dưới đây"] # 0xe95f (en: 'logical or with bar below') + - "": [t: "gần như bằng nhau trên"] # 0xe962 (en: 'almost equal over equal') + - "": [t: "hình tam giác trỏ trái với thanh chia đôi"] # 0xe964 (en: 'left pointing triangle with bisecting bar') + - "": [t: "tam giác chỉ bên phải với thanh chia đôi"] # 0xe965 (en: 'right pointing triangle with bisecting bar') + - "": [t: "bằng với dòng trên cùng chấm"] # 0xe966 (en: 'equals with dotted top line') + - "": [t: "đi trước với đại tràng"] # 0xe967 (en: 'precedes with colon') + - "": [t: "thành công với đại tràng"] # 0xe968 (en: 'succeeds with colon') + - "": [t: "nhỏ hơn hoặc bằng nghiêng"] # 0xe969 (en: 'smaller than or equal slanted') + - "": [t: "lớn hơn hoặc bằng nghiêng"] # 0xe96a (en: 'larger than or equal slanted') + - "": [t: "lồng nhau rất ít hơn"] # 0xe96b (en: 'nested very much less than') + - "": [t: "lồng nhau rất lớn hơn nhiều so với"] # 0xe96c (en: 'nested very much greater than') + - "": [t: "sự khác biệt giữa biến thể"] # 0xe96d (en: 'difference between variant') + - "⪮": [t: "sự khác biệt giữa biến thể"] # 0x2aae (en: 'difference between variant') + - "": [t: "ít hơn so với lớp phủ"] # 0xe96e (en: 'less than greater than overlay') + - "⪤": [t: "ít hơn so với lớp phủ"] # 0x2aa4 (en: 'less than greater than overlay') + - "": [t: "logic hoặc logic và lớp phủ"] # 0xe96f (en: 'logical or logical and overlay') + - "": [t: "superset trên superset"] # 0xe970 (en: 'superset over superset') + - "⫖": [t: "superset trên superset"] # 0x2ad6 (en: 'superset over superset') + - "": [t: "tập hợp con qua tập hợp con"] # 0xe971 (en: 'subset over subset') + - "⫕": [t: "tập hợp con qua tập hợp con"] # 0x2ad5 (en: 'subset over subset') + - "": [t: "superset trên tập hợp con"] # 0xe972 (en: 'superset over subset') + - "⫔": [t: "superset trên tập hợp con"] # 0x2ad4 (en: 'superset over subset') + - "": [t: "tập hợp con trên superset"] # 0xe973 (en: 'subset over superset') + - "⫓": [t: "tập hợp con trên superset"] # 0x2ad3 (en: 'subset over superset') + - "": [t: "thanh ba thẳng đứng"] # 0xe979 (en: 'triple vertical bar') + - "": [t: "ghép các chấm dọc"] # 0xe97a (en: 'paired quadruple vertical dots') + - "": [t: "vuông góc trên thanh"] # 0xe97b (en: 'perpendicular over bar') + - "⫨": [t: "vuông góc trên thanh"] # 0x2ae8 (en: 'perpendicular over bar') + - "": [t: "bar let -bretstile bar du trường"] # 0xe97c (en: 'left turnstile double vertical bar') + - "": [t: "double bên trái thanh dọc kép"] # 0xe97d (en: 'double left turnstile double vertical bar') + - "": [t: "vuông góc trên đảo ngược vuông góc"] # 0xe97e (en: 'perpendicular over inverted perpendicular') + - "": [t: "double bên trái thanh dọc"] # 0xe97f (en: 'double left turnstile vertical bar') + - "⫤": [t: "double bên trái thanh dọc"] # 0x2ae4 (en: 'double left turnstile vertical bar') + - "": [t: "góc hình cầu mở ra"] # 0xe980 (en: 'spherical angle opening up') + - "": [t: "chém đôi"] # 0xe981 (en: 'double slash') + - "": [t: "góc vuông với góc"] # 0xe982 (en: 'right angle with corner') + - "": [t: "bao quanh thanh dọc"] # 0xe984 (en: 'circled vertical bar') + - "⦶": [t: "bao quanh thanh dọc"] # 0x29b6 (en: 'circled vertical bar') + - "": [t: "dấu hiệu phân chia vòng tròn"] # 0xe985 (en: 'circled division sign') + - "⨸": [t: "dấu hiệu phân chia vòng tròn"] # 0x2a38 (en: 'circled division sign') + - "": [t: "solidus đứt nét"] # 0xe986 (en: 'dashed solidus') + - "": [t: "backslash bị đứt nét"] # 0xe987 (en: 'dashed backslash') + - "": [t: "đường giữa đứt"] # 0xe988 (en: 'dashed mid line') + - "": [t: "thanh dọc đứt"] # 0xe989 (en: 'dashed vertical bar') + - "": [t: "vuông góc với s"] # 0xe98a (en: 'perpendicular with s') + - "": [t: "góc với s"] # 0xe98b (en: 'angle with s') + - "": [t: "góc hình cầu mở bên trái"] # 0xe98c (en: 'spherical angle opening left') + - "": [t: "góc mở bên trái"] # 0xe98d (en: 'angle opening left') + - "": [t: "thanh dọc với móc đôi"] # 0xe98e (en: 'vertical bar with double hook') + - "⥾": [t: "thanh dọc với móc đôi"] # 0x297e (en: 'vertical bar with double hook') + - "": [t: "toán tử chấm trung bình gốc tự do"] # 0xe98f (en: 'medium dot operator free radical') + - "": [t: "trắng lên hình tam giác phía trên thanh"] # 0xe990 (en: 'white up pointing triangle above bar') + - "": [t: "giống hệt nhau và song song với"] # 0xe991 (en: 'identical and parallel to') + - "": [t: "smash sản phẩm"] # 0xe992 (en: 'smash product') + - "⨳": [t: "smash sản phẩm"] # 0x2a33 (en: 'smash product') + - "": [t: "toán tử ba thanh với thanh ngang"] # 0xe993 (en: 'triple bar operator with horizontal bar') + - "": [t: "giống hệt với cắt đôi"] # 0xe994 (en: 'identical to with double slash') + - "⧥": [t: "giống hệt với cắt đôi"] # 0x29e5 (en: 'identical to with double slash') + - "": [t: "triple crossed bars"] # 0xe995 + - "": [t: "thanh dọc trên vòng tròn"] # 0xe996 (en: 'vertical bar over circle') + - "": [t: "tỷ lệ dọc so với"] # 0xe997 (en: 'vertical proportional to') + - "": [t: "đen quý trước mặt trăng"] # 0xe998 (en: 'black last quarter moon') + - "": [t: "mặt trăng quý đầu tiên màu đen"] # 0xe999 (en: 'black first quarter moon') + - "": [t: "sóng sin âm"] # 0xe9a0 (en: 'negative sine wave') + - "": [t: "dấu ngoặc đơn"] # 0xe9a1 (en: 'parenthesized dot') + - "": [t: "dấu ngoặc đơn"] # 0xe9a2 (en: 'parens') + - "": [t: "nụ cười trắng"] # 0xe9a3 (en: 'white smile') + - "": [t: "trắng cau mày"] # 0xe9a4 (en: 'white frown') + - "": [t: "hình lục giác"] # 0xe9a5 (en: 'hexagon') + - "": [t: "tương đương với hơn cộng"] # 0xe9a6 (en: 'equivalent to over plus') + - "": [t: "cộng với quá mức tương đương với"] # 0xe9a7 (en: 'plus over equivalent to') + - "": [t: "giao lộ serifs"] # 0xe9b0 (en: 'intersection serifs') + - "": [t: "liên minh serifs"] # 0xe9b1 (en: 'union serifs') + - "": [t: "giao lộ vuông serifs"] # 0xe9b2 (en: 'square intersection serifs') + - "": [t: "square union serifs"] # 0xe9b3 + - "": [t: "trước tương đương hoặc thành công"] # 0xe9e0 (en: 'precedes equivalent to or succeeds') + - "": [t: "thành công tương đương với hoặc trước"] # 0xe9e1 (en: 'succeeds equivalent to or precedes') + - "": [t: "đi trước gần như bằng hoặc thành công"] # 0xe9e2 (en: 'precedes almost equal to or succeeds') + - "": [t: "thành công gần như bằng hoặc trước"] # 0xe9e3 (en: 'succeeds almost equal to or precedes') + - "": [t: "ít hơn tương đương với hoặc lớn hơn"] # 0xe9f0 (en: 'less than equivalent to or greater than') + - "": [t: "lớn hơn tương đương với hoặc ít hơn"] # 0xe9f1 (en: 'greater than equivalent to or less than') + - "": [t: "không phải là ít hơn nhiều"] # 0xea00 (en: 'not vert much less than') + - "": [t: "không phải là lớn hơn nhiều so với"] # 0xea01 (en: 'not vert much greater than') + - "": [t: "không ít hơn nhiều biến thể"] # 0xea02 (en: 'not much less than variant') + - "": [t: "không lớn hơn nhiều so với biến thể"] # 0xea03 (en: 'not much greater than variant') + - "": [t: "ít vert không bằng kép bằng"] # 0xea04 (en: 'less vert not double equals') + - "": [t: "gt vert không bằng kép"] # 0xea05 (en: 'gt vert not double equals') + - "": [t: "không ít hơn hoặc bằng"] # 0xea06 (en: 'not less than or equal to') + - "": [t: "không lớn hơn hoặc bằng"] # 0xea07 (en: 'not greater than or equal to') + - "": [t: "không bằng cũng không ít hơn"] # 0xea09 (en: 'neither equal to nor less than') + - "": [t: "không chứa hoặc bằng"] # 0xea0a (en: 'does not contain or equal to') + - "": [t: "không phải siêu sao cũng không bằng"] # 0xea0b (en: 'neither superset of nor equal to') + - "": [t: "không phải tập hợp con cũng không bằng"] # 0xea0c (en: 'neither subset of nor equal to') + - "": [t: "đảo ngược solidus tập hợp con"] # 0xea0d (en: 'reverse solidus subset') + - "": [t: "không bằng cũng không lớn hơn"] # 0xea0e (en: 'neither equal to nor greater than') + - "": [t: "không trừ đi toán tử tilde"] # 0xea0f (en: 'not minus tilde operator') + - "": [t: "không bằng cũng không ít hơn"] # 0xea10 (en: 'neither equal to nor less than') + - "": [t: "không phải nhà điều hành tilde"] # 0xea11 (en: 'not tilde operator') + - "": [t: "không phải là yếu tố hoặc bằng"] # 0xea12 (en: 'not element of or equal to') + - "": [t: "không bằng cũng không lớn hơn"] # 0xea13 (en: 'neither equal to nor greater than') + - "": [t: "không gần như bằng nhau"] # 0xea14 (en: 'not almost equal') + - "": [t: "không thành công tương tự"] # 0xea15 (en: 'not succeeds similar') + - "": [t: "ít hơn hoặc nghiêng bằng với dấu gạch chéo"] # 0xea16 (en: 'less than or slanted equal to with slash') + - "": [t: "lớn hơn hoặc nghiêng bằng với dấu gạch chéo"] # 0xea17 (en: 'greater than or slanted equal to with slash') + - "": [t: "superset solidus"] # 0xea1a + - "": [t: "không chứa"] # 0xea1b (en: 'does not contain') + - "": [t: "không ít hơn hoặc bằng"] # 0xea1d (en: 'not less than or equal to') + - "": [t: "không lớn hơn hoặc bằng"] # 0xea1e (en: 'not greater than or equal to') + - "": [t: "không gần như bằng trừ"] # 0xea1f (en: 'not almost equal to minus') + - "": [t: "tiêu cực đặt thành viên chấm ở trên"] # 0xea22 (en: 'negated set membership dot above') + - "": [t: "không góc góc"] # 0xea2c (en: 'not vert angle') + - "": [t: "không song song nghiêng"] # 0xea2d (en: 'not parallel slanted') + - "": [t: "không phải nhà điều hành thanh"] # 0xea2e (en: 'not bar operator') + - "": [t: "không phải nhà điều hành thanh đôi"] # 0xea2f (en: 'not double bar operator') + - "": [t: "không phải nhà điều hành ba thanh"] # 0xea30 (en: 'not triple bar operator') + - "": [t: "ít hơn nhưng không xấp xỉ bằng"] # 0xea32 (en: 'less than but not approximately equal to') + - "⪉": [t: "ít hơn nhưng không xấp xỉ bằng"] # 0x2a89 (en: 'less than but not approximately equal to') + - "": [t: "lớn hơn nhưng không xấp xỉ bằng"] # 0xea33 (en: 'greater than but not approximately equal to') + - "⪊": [t: "lớn hơn nhưng không xấp xỉ bằng"] # 0x2a8a (en: 'greater than but not approximately equal to') + - "": [t: "nhỏ hơn hoặc không bằng"] # 0xea34 (en: 'less than or not equal to') + - "": [t: "lớn hơn hoặc không bằng"] # 0xea35 (en: 'greater than or not equal to') + - "": [t: "không lồng nhau ít hơn"] # 0xea36 (en: 'not nested less than') + - "": [t: "không lồng nhau lớn hơn"] # 0xea37 (en: 'not nested greater than') + - "": [t: "không ít hơn nhiều"] # 0xea38 (en: 'not much less than') + - "": [t: "không lớn hơn nhiều so với"] # 0xea39 (en: 'not much greater than') + - "": [t: "đi trước nhưng không tương đương với"] # 0xea3a (en: 'precedes but not equivalent to') + - "": [t: "thành công nhưng không tương đương với"] # 0xea3b (en: 'succeeds but not equivalent to') + - "": [t: "đi trước nhưng không bằng"] # 0xea3c (en: 'precedes but not equal to') + - "": [t: "thành công nhưng không bằng"] # 0xea3d (en: 'succeeds but not equal to') + - "": [t: "không bằng hoặc trước"] # 0xea3e (en: 'does not equal or precede') + - "": [t: "không bằng hoặc thành công"] # 0xea3f (en: 'does not equal or succeed') + - "": [t: "đi trước nhưng không bằng"] # 0xea40 (en: 'precedes but not equal to') + - "⪵": [t: "đi trước nhưng không bằng"] # 0x2ab5 (en: 'precedes but not equal to') + - "": [t: "thành công nhưng không bằng"] # 0xea41 (en: 'succeeds but not equal to') + - "⪶": [t: "thành công nhưng không bằng"] # 0x2ab6 (en: 'succeeds but not equal to') + - "": [t: "không phải là tập hợp con cũng không bằng"] # 0xea42 (en: 'not subset of nor equal to') + - "": [t: "không phải siêu sao cũng không bằng"] # 0xea43 (en: 'not superset of nor equal to') + - "": [t: "tập hợp con hoặc không bằng"] # 0xea44 (en: 'subset of or not equal to') + - "": [t: "superset của hoặc không bằng"] # 0xea45 (en: 'superset of or not equal to') + - "": [t: "không phải là tập hợp con cũng không bằng"] # 0xea46 (en: 'not subset of nor equal to') + - "": [t: "không phải siêu sao cũng không bằng"] # 0xea47 (en: 'not superset of nor equal to') + - "": [t: "không nhỏ hơn ba"] # 0xea48 (en: 'not triple less than') + - "": [t: "không lớn hơn gấp ba lần"] # 0xea49 (en: 'not triple greater than') + - "": [t: "không đi trước bằng"] # 0xea4c (en: 'not precedes equals') + - "": [t: "không thành công bằng nhau"] # 0xea4d (en: 'not succeeds equals') + - "": [t: "không phải nhóm con bình thường của thanh"] # 0xea50 (en: 'not normal subgroup of with bar') + - "": [t: "không chứa như phân nhóm bình thường với thanh"] # 0xea51 (en: 'does not contain as normal subgroup with bar') + - "": [t: "không phải là sự khác biệt giữa"] # 0xea52 (en: 'not difference between') + - "": [t: "không tương đương về mặt hình học"] # 0xea53 (en: 'not geometrically equivalent to') + - "": [t: "không phải là tương tự"] # 0xea54 (en: 'not vert similar') + - "": [t: "không bằng hoặc tương tự"] # 0xea55 (en: 'not equal or similar') + - "": [t: "không gần đúng"] # 0xea56 (en: 'not vert approximate') + - "": [t: "không xấp xỉ giống hệt nhau"] # 0xea57 (en: 'not approximately identical to') + - "": [t: "không gập ghềnh bằng nhau"] # 0xea58 (en: 'not bumpy equals') + - "": [t: "không gập ghềnh bằng nhau"] # 0xea59 (en: 'not bumpy single equals') + - "": [t: "không phải dấu chấm bằng nhau"] # 0xea5a (en: 'not equal dot') + - "": [t: "đảo ngược không tương đương"] # 0xea5b (en: 'reverse not equivalent') + - "": [t: "không phải tập hợp con vuông"] # 0xea60 (en: 'not square subset') + - "": [t: "không phải là siêu siêu hình"] # 0xea61 (en: 'not square superset') + - "": [t: "không gần như bằng nhau"] # 0xea62 (en: 'not almost equal over equal') + - "": [t: "không hoàn toàn tương đương với"] # 0xea63 (en: 'not strictly equivalent to') + - "": [t: "không đồng dạng chấm"] # 0xea64 (en: 'not congruent dot') + - "": [t: "đảo ngược không bằng nhau"] # 0xea65 (en: 'reverse not equal') + - "": [t: "không phải đỉnh bên trái bằng nhau"] # 0xea70 (en: 'not vert left triangle equals') + - "": [t: "không phải hình tam giác bên phải bằng"] # 0xea71 (en: 'not vert right triangle equals') + - "": [t: "không một phần"] # 0xea80 (en: 'not partial') + - "": [t: "mũi tên extender"] # 0xeb00 (en: 'arrow embellishment extender') + - "": [t: "mũi tên phải qua mũi tên trái"] # 0xeb01 (en: 'arrow rightwards over arrow leftwards') + - "": [t: "mũi tên phải qua mũi tên trái"] # 0xeb02 (en: 'arrow rightwards over arrow leftwards') + - "": [t: "harpoon ngay trên harpoon trái"] # 0xeb03 (en: 'harpoon right over harpoon left') + - "": [t: "harpoon ngay trên harpoon trái"] # 0xeb04 (en: 'harpoon right over harpoon left') + - "": [t: "mũi tên kép đông nam tây nam"] # 0xeb05 (en: 'double arrow northeast southwest') + - "": [t: "mũi tên kép phía tây bắc đông nam"] # 0xeb06 (en: 'double arrow northwest southeast') + - "": [t: "bộ mở rộng harpoon ngang"] # 0xeb07 (en: 'horizontal harpoon extender') + - "": [t: "mũi tên trái ngược chiều kim đồng hồ"] # 0xeb08 (en: 'anticlockwise arc leftwards arrow') + - "": [t: "vòng cung ngược chiều kim đồng hồ mũi tên bên phải"] # 0xeb09 (en: 'anticlockwise arc rightwards arrow') + - "": [t: "giọng mũi phải lớn"] # 0xeb0b (en: 'large rightwards arrow accent') + - "": [t: "điểm nhấn mũi tên lớn bên trái"] # 0xeb0c (en: 'large leftwards arrow accent') + - "": [t: "đầu mũi tên trái"] # 0xeb0d (en: 'leftwards arrowhead') + - "": [t: "đầu mũi tên phải"] # 0xeb0e (en: 'rightwards arrowhead') + - "": [t: "mũi tên lớn bên trái với gạch"] # 0xeb0f (en: 'large left right arrow with stroke') + - "": [t: "bộ mở rộng mũi tên kép ngang"] # 0xeb10 (en: 'horizontal double arrow extender') + - "": [t: "mũi tên đôi bên trái lớn bên trái với gạch"] # 0xeb11 (en: 'large left right double arrow with stroke') + - "": [t: "mũi tên xuống bên trái của mũi tên hướng lên"] # 0xeb12 (en: 'downwards arrow leftwards of upwards arrow') + - "⇵": [t: "mũi tên xuống bên trái của mũi tên hướng lên"] # 0x21f5 (en: 'downwards arrow leftwards of upwards arrow') + - "": [t: "mũi tên trái với góc xuống"] # 0xeb13 (en: 'leftwards arrow with corner downwards') + - "": [t: "mũi tên bên phải với góc hướng lên trên"] # 0xeb14 (en: 'rightwards arrow with corner upwards') + - "": [t: "mũi tên trái với góc hướng lên trên"] # 0xeb15 (en: 'leftwards arrow with corner upwards') + - "": [t: "mũi tên bán nguyệt trên cùng theo chiều kim đồng hồ với plus"] # 0xeb16 (en: 'anticlockwise top semicircle arrow with plus') + - "⤽": [t: "mũi tên bán nguyệt trên cùng theo chiều kim đồng hồ với plus"] # 0x293d (en: 'anticlockwise top semicircle arrow with plus') + - "": [t: "mũi tên bán nguyệt trên cùng theo chiều kim đồng hồ với điểm trừ"] # 0xeb17 (en: 'clockwise top semicircle arrow with minus') + - "⤼": [t: "mũi tên bán nguyệt trên cùng theo chiều kim đồng hồ với điểm trừ"] # 0x293c (en: 'clockwise top semicircle arrow with minus') + - "": [t: "mũi tên bên phải với đuôi với gạch"] # 0xeb18 (en: 'rightwards arrow with tail with stroke') + - "": [t: "harpoon phải xuống"] # 0xeb19 (en: 'right harpoon down') + - "": [t: "rời harpoon xuống"] # 0xeb1a (en: 'left harpoon down') + - "": [t: "bên trái harpoon xuống"] # 0xeb1b (en: 'left right harpoon down') + - "⥐": [t: "bên trái harpoon xuống"] # 0x2950 (en: 'left right harpoon down') + - "": [t: "bên trái harpoon lên"] # 0xeb1c (en: 'left right harpoon up') + - "⥎": [t: "bên trái harpoon lên"] # 0x294e (en: 'left right harpoon up') + - "": [t: "lên xuống harpoon trái"] # 0xeb1d (en: 'up down harpoon left') + - "⥑": [t: "lên xuống harpoon trái"] # 0x2951 (en: 'up down harpoon left') + - "": [t: "lên xuống harpoon phải"] # 0xeb1e (en: 'up down harpoon right') + - "⥏": [t: "lên xuống harpoon phải"] # 0x294f (en: 'up down harpoon right') + - "": [t: "mũi tên hướng lên bên phải của mũi tên xuống"] # 0xeb1f (en: 'upwards arrow to the right of downwards arrow') + - "⇵": [t: "mũi tên hướng lên bên phải của mũi tên xuống"] # 0x21f5 (en: 'upwards arrow to the right of downwards arrow') + - "": [t: "harpoon trái để bar với barb lên trên"] # 0xeb20 (en: 'leftwards harpoon to bar with barb upwards') + - "⥒": [t: "harpoon trái để bar với barb lên trên"] # 0x2952 (en: 'leftwards harpoon to bar with barb upwards') + - "": [t: "quyền harpoon đến bar với barb lên trên"] # 0xeb21 (en: 'rightwards harpoon to bar with barb upwards') + - "⥓": [t: "quyền harpoon đến bar với barb lên trên"] # 0x2953 (en: 'rightwards harpoon to bar with barb upwards') + - "": [t: "harpoon bên trái để bar với barb xuống dưới"] # 0xeb22 (en: 'leftwards harpoon to bar with barb downwards') + - "⥖": [t: "harpoon bên trái để bar với barb xuống dưới"] # 0x2956 (en: 'leftwards harpoon to bar with barb downwards') + - "": [t: "quyền harpoon đến bar với barb xuống dưới"] # 0xeb23 (en: 'rightwards harpoon to bar with barb downwards') + - "⥗": [t: "quyền harpoon đến bar với barb xuống dưới"] # 0x2957 (en: 'rightwards harpoon to bar with barb downwards') + - "": [t: "harpoon trái từ quán bar với barb trở lên"] # 0xeb24 (en: 'leftwards harpoon from bar with barb upwards') + - "⥚": [t: "harpoon trái từ quán bar với barb trở lên"] # 0x295a (en: 'leftwards harpoon from bar with barb upwards') + - "": [t: "harpoon ngay từ quán bar với barb trở lên"] # 0xeb25 (en: 'rightwards harpoon from bar with barb upwards') + - "⥛": [t: "harpoon ngay từ quán bar với barb trở lên"] # 0x295b (en: 'rightwards harpoon from bar with barb upwards') + - "": [t: "harpoon bên trái từ quán bar với barb trở xuống"] # 0xeb26 (en: 'leftwards harpoon from bar with barb downwards') + - "⥞": [t: "harpoon bên trái từ quán bar với barb trở xuống"] # 0x295e (en: 'leftwards harpoon from bar with barb downwards') + - "": [t: "harpoon bên phải từ quán bar với barb trở xuống"] # 0xeb27 (en: 'rightwards harpoon from bar with barb downwards') + - "⥟": [t: "harpoon bên phải từ quán bar với barb trở xuống"] # 0x295f (en: 'rightwards harpoon from bar with barb downwards') + - "": [t: "hướng lên trên harpoon để bar với barb trái"] # 0xeb28 (en: 'upwards harpoon to bar with barb leftwards') + - "⥘": [t: "hướng lên trên harpoon để bar với barb trái"] # 0x2958 (en: 'upwards harpoon to bar with barb leftwards') + - "": [t: "downwards harpoon đến bar với barb leftwards"] # 0xeb29 (en: 'downwards harpoon to bar with barb leftwards') + - "⥙": [t: "downwards harpoon đến bar với barb leftwards"] # 0x2959 (en: 'downwards harpoon to bar with barb leftwards') + - "": [t: "hướng lên trên harpoon để bar với barb phải"] # 0xeb2a (en: 'upwards harpoon to bar with barb rightwards') + - "⥔": [t: "hướng lên trên harpoon để bar với barb phải"] # 0x2954 (en: 'upwards harpoon to bar with barb rightwards') + - "": [t: "xuống harpoon để bar với barb ngay"] # 0xeb2b (en: 'downwards harpoon to bar with barb rightwards') + - "⥕": [t: "xuống harpoon để bar với barb ngay"] # 0x2955 (en: 'downwards harpoon to bar with barb rightwards') + - "": [t: "harpoon đi lên từ quán bar với barb trái"] # 0xeb2c (en: 'upwards harpoon from bar with barb leftwards') + - "⥠": [t: "harpoon đi lên từ quán bar với barb trái"] # 0x2960 (en: 'upwards harpoon from bar with barb leftwards') + - "": [t: "downwards harpoon từ quán bar với barb trái"] # 0xeb2d (en: 'downwards harpoon from bar with barb leftwards') + - "⥡": [t: "downwards harpoon từ quán bar với barb trái"] # 0x2961 (en: 'downwards harpoon from bar with barb leftwards') + - "": [t: "harpoon đi lên từ quán bar với barb phải"] # 0xeb2e (en: 'upwards harpoon from bar with barb rightwards') + - "⥜": [t: "harpoon đi lên từ quán bar với barb phải"] # 0x295c (en: 'upwards harpoon from bar with barb rightwards') + - "": [t: "downwards harpoon từ bar với barb phải"] # 0xeb2f (en: 'downwards harpoon from bar with barb rightwards') + - "⥝": [t: "downwards harpoon từ bar với barb phải"] # 0x295d (en: 'downwards harpoon from bar with barb rightwards') + - "": [t: "mũi tên hướng lên đến thanh"] # 0xeb30 (en: 'upwards arrow to bar') + - "⤒": [t: "mũi tên hướng lên đến thanh"] # 0x2912 (en: 'upwards arrow to bar') + - "": [t: "mũi tên xuống thanh"] # 0xeb31 (en: 'downwards arrow to bar') + - "⤓": [t: "mũi tên xuống thanh"] # 0x2913 (en: 'downwards arrow to bar') + - "": [t: "harpoon hướng lên bên trái của harpoon xuống"] # 0xeb32 (en: 'upwards harpoon to the left of downwards harpoon') + - "⥮": [t: "harpoon hướng lên bên trái của harpoon xuống"] # 0x296e (en: 'upwards harpoon to the left of downwards harpoon') + - "": [t: "harpoon hướng lên bên phải của harpoon xuống"] # 0xeb33 (en: 'upwards harpoon to the right of downwards harpoon') + - "⥯": [t: "harpoon hướng lên bên phải của harpoon xuống"] # 0x296f (en: 'upwards harpoon to the right of downwards harpoon') + - "": [t: "đầu mũi tên hướng lên"] # 0xeb34 (en: 'upwards arrowhead') + - "": [t: "đầu mũi tên xuống"] # 0xeb35 (en: 'downwards arrowhead') + - "": [t: "double harpoon với barb bên trái xuống bên phải barb lên"] # 0xeb36 (en: 'double harpoon with leftwards barb down rightwards barb up') + - "": [t: "double harpoon với barb bên trái lên bên phải barb xuống"] # 0xeb37 (en: 'double harpoon with leftwards barb up rightwards barb down') + - "": [t: "mũi tên trái trên thanh"] # 0xeb38 (en: 'leftwards arrow over bar') + - "": [t: "mũi tên bên phải trên thanh"] # 0xeb39 (en: 'rightwards arrow over bar') + - "": [t: "mũi tên trái dưới thanh"] # 0xeb3a (en: 'leftwards arrow under bar') + - "": [t: "mũi tên bên phải dưới thanh"] # 0xeb3b (en: 'rightwards arrow under bar') + - "": [t: "mũi tên ba bên trái"] # 0xeb3c (en: 'left right triple arrow') + - "": [t: "mũi tên kép đông nam đông nam"] # 0xeb3f (en: 'double arrow northeast southeast') + - "": [t: "mũi tên bán nguyệt trái ngược chiều kim đồng hồ"] # 0xeb40 (en: 'anticlockwise left semicircle arrow') + - "⤹": [t: "mũi tên bán nguyệt trái ngược chiều kim đồng hồ"] # 0x2939 (en: 'anticlockwise left semicircle arrow') + - "": [t: "mũi tên bán nguyệt trái theo chiều kim đồng hồ"] # 0xeb41 (en: 'clockwise left semicircle arrow') + - "": [t: "bên trái vòng tròn bên trái mũi tên phải"] # 0xeb42 (en: 'left open circle left right arrow') + - "": [t: "mũi tên bên phải trên tilde"] # 0xeb44 (en: 'rightwards arrow over tilde') + - "⥴": [t: "mũi tên bên phải trên tilde"] # 0x2974 (en: 'rightwards arrow over tilde') + - "": [t: "mũi tên trái trên tilde"] # 0xeb45 (en: 'leftwards arrow over tilde') + - "⥳": [t: "mũi tên trái trên tilde"] # 0x2973 (en: 'leftwards arrow over tilde') + - "": [t: "harpoon trái qua thanh"] # 0xeb48 (en: 'leftwards harpoon over bar') + - "⥪": [t: "harpoon trái qua thanh"] # 0x296a (en: 'leftwards harpoon over bar') + - "": [t: "quyền harpoon trên quán bar"] # 0xeb49 (en: 'rightwards harpoon over bar') + - "⥬": [t: "quyền harpoon trên quán bar"] # 0x296c (en: 'rightwards harpoon over bar') + - "": [t: "harpoon bên trái dưới quán bar"] # 0xeb4a (en: 'leftwards harpoon under bar') + - "⥫": [t: "harpoon bên trái dưới quán bar"] # 0x296b (en: 'leftwards harpoon under bar') + - "": [t: "quyền harpoon dưới quán bar"] # 0xeb4b (en: 'rightwards harpoon under bar') + - "⥭": [t: "quyền harpoon dưới quán bar"] # 0x296d (en: 'rightwards harpoon under bar') + - "": [t: "squat mũi tên trái màu đen"] # 0xeb4c (en: 'squat black leftwards arrow') + - "": [t: "mũi tên bán nguyệt phải theo chiều kim đồng hồ"] # 0xeb50 (en: 'clockwise right semicircle arrow') + - "⤸": [t: "mũi tên bán nguyệt phải theo chiều kim đồng hồ"] # 0x2938 (en: 'clockwise right semicircle arrow') + - "": [t: "mũi tên bán nguyệt phải ngược chiều kim đồng hồ"] # 0xeb51 (en: 'anticlockwise right semicircle arrow') + - "": [t: "vòng tròn bên trái bên trái harpoon"] # 0xeb52 (en: 'left open circle left right harpoon') + - "": [t: "mũi tên hướng lên bên trái của thanh dọc"] # 0xeb58 (en: 'upwards arrow leftwards of vertical bar') + - "": [t: "mũi tên xuống bên trái của thanh dọc"] # 0xeb59 (en: 'downwards arrow leftwards of vertical bar') + - "": [t: "mũi tên hướng lên bên phải của thanh dọc"] # 0xeb5a (en: 'upwards arrow rightwards of vertical bar') + - "": [t: "mũi tên xuống bên phải của thanh dọc"] # 0xeb5b (en: 'downwards arrow rightwards of vertical bar') + - "": [t: "mũi tên bên phải với móc mở rộng xuống"] # 0xeb5c (en: 'rightwards arrow with extended downwards hook') + - "": [t: "mũi tên trái với móc mở rộng"] # 0xeb5d (en: 'leftwards arrow with extended hook') + - "": [t: "mũi tên trái với móc mở rộng xuống"] # 0xeb5e (en: 'leftwards arrow with extended downwards hook') + - "": [t: "mũi tên bên phải với móc mở rộng"] # 0xeb5f (en: 'rightwards arrow with extended hook') + - "": [t: "không đúng mũi tên lượn sóng"] # 0xeb60 (en: 'not right arrow wavy') + - "": [t: "không đúng mũi tên cong"] # 0xeb61 (en: 'not right arrow curved') + - "": [t: "hướng lên trên harpoon bên trái của thanh dọc"] # 0xeb68 (en: 'upwards harpoon leftwards of vertical bar') + - "": [t: "xuống harpoon trái của thanh dọc"] # 0xeb69 (en: 'downwards harpoon leftwards of vertical bar') + - "": [t: "hướng lên trên harpoon ngay của thanh dọc"] # 0xeb6a (en: 'upwards harpoon rightwards of vertical bar') + - "": [t: "xuống harpoon ngay bên phải của thanh dọc"] # 0xeb6b (en: 'downwards harpoon rightwards of vertical bar') + - "": [t: "bộ mở rộng mũi tên đôi dọc"] # 0xeb6c (en: 'vertical double arrow extender') + - "": [t: "harpoon thẳng đứng với barb left extender"] # 0xeb6d (en: 'vertical harpoon with barb left extender') + - "": [t: "harpoon thẳng đứng với barb bên phải extender"] # 0xeb6e (en: 'vertical harpoon with barb right extender') + - "": [t: "harpoon bên phải bên trái harpoon phải"] # 0xeb6f (en: 'right harpoon over left harpoon right') + - "": [t: "harpoon bên trái bên trái harpoon trái"] # 0xeb70 (en: 'right harpoon over left harpoon left') + - "": [t: "bên trái harpoon trên bên phải harpoon phải"] # 0xeb71 (en: 'left harpoon over right harpoon right') + - "": [t: "bên trái harpoon qua harpoon phải trái"] # 0xeb72 (en: 'left harpoon over right harpoon left') + - "": [t: "mũi tên trái từ đầu mũi tên"] # 0xeb73 (en: 'leftwards arrow from bar arrowhead') + - "": [t: "mũi tên trái từ bên phải từ thanh mở rộng"] # 0xeb74 (en: 'leftwards rightwards arrow from bar extender') + - "": [t: "mũi tên trái từ đuôi thanh"] # 0xeb75 (en: 'leftwards arrow from bar tail') + - "": [t: "mũi tên bên phải từ đuôi thanh"] # 0xeb76 (en: 'rightwards arrow from bar tail') + - "": [t: "mũi tên bên phải từ đầu arrowhead"] # 0xeb77 (en: 'rightwards arrow from bar arrowhead') + - "": [t: "harpoon đi lên từ quán bar với đầu mũi tên trái"] # 0xeb78 (en: 'upwards harpoon from bar with barb leftwards arrowhead') + - "": [t: "mũi tên phải qua mũi tên trái bên phải"] # 0xeb79 (en: 'rightwards arrow over leftwards arrow right') + - "": [t: "mũi tên phải qua mũi tên trái bên trái"] # 0xeb7a (en: 'rightwards arrow over leftwards arrow left') + - "": [t: "mũi tên trái qua mũi tên phải bên phải"] # 0xeb7b (en: 'leftwards arrow over rightwards arrow right') + - "": [t: "mũi tên trái qua mũi tên bên phải"] # 0xeb7c (en: 'leftwards arrow over rightwards arrow leftt') + - "": [t: "mũi tên hướng lên từ đầu mũi tên"] # 0xeb7d (en: 'upwards arrow from bar arrowhead') + - "": [t: "mũi tên hướng lên từ đuôi thanh"] # 0xeb7e (en: 'upwards arrow from bar tail') + - "": [t: "mũi tên xuống từ đuôi thanh"] # 0xeb7f (en: 'downwards arrow from bar tail') + - "": [t: "mũi tên xuống từ đầu mũi tên"] # 0xeb80 (en: 'downwards arrow from bar arrowhead') + - "": [t: "downwards harpoon từ quán bar với đầu mũi tên bên phải"] # 0xeb81 (en: 'downwards harpoon from bar with barb rightwards arrowhead') + - "": [t: "harpoon hướng lên bên trái của đáy harpoon"] # 0xeb82 (en: 'upwards harpoon to the left of downwards harpoon bottom') + - "": [t: "harpoon hướng lên bên trái của downwards harpoon extender"] # 0xeb83 (en: 'upwards harpoon to the left of downwards harpoon extender') + - "": [t: "downwards harpoon ở bên trái của harpoon top"] # 0xeb84 (en: 'downwards harpoon to the left of upwards harpoon top') + - "": [t: "lên trên harppoon ở bên trái của harpoon xuống trên"] # 0xeb85 (en: 'upwards harppoon to the left of downwards harpoon top') + - "": [t: "xuống harpoon bên trái của bộ mở rộng harpoon lên trên"] # 0xeb86 (en: 'downwards harpoon to the left of the upwards harpoon extender') + - "": [t: "downwards harpoon ở bên trái của đáy harpoon hướng lên"] # 0xeb87 (en: 'downwards harpoon to the left of the upwards harpoon bottom') + - "": [t: "mũi tên hướng lên bên trái của phía dưới mũi tên xuống"] # 0xeb88 (en: 'upwards arrow leftwards of downwards arrow bottom') + - "": [t: "mũi tên xuống bên trái của đầu mũi tên lên trên"] # 0xeb89 (en: 'downwards arrow leftwards of upwards arrow top') + - "": [t: "mũi tên hướng lên bên trái của đầu mũi tên xuống"] # 0xeb8a (en: 'upwards arrow leftwards of downwards arrow top') + - "": [t: "mũi tên xuống bên trái của phía dưới mũi tên hướng lên"] # 0xeb8b (en: 'downwards arrow leftwards of upwards arrow bottom') + - "": [t: "bên trái mũi tên phải mở rộng"] # 0xeb8c (en: 'leftwards rightwards arrows extender') + - "": [t: "east east arrow extender"] # 0xeb8d (en: 'north east arrow extender') + - "": [t: "nội thu mũi tên tây bắc"] # 0xeb8e (en: 'north west arrow extender') + - "": [t: "xuống niềng răng trái"] # 0xec00 (en: 'down pointing brace left') + - "": [t: "xuống chỉ nẹp giữa"] # 0xec01 (en: 'down pointing brace mid') + - "": [t: "xuống chỉ nẹp đúng"] # 0xec02 (en: 'down pointing brace right') + - "": [t: "máy mở rộng nẹp ngang"] # 0xec03 (en: 'horizontal brace extender') + - "": [t: "lên niềng răng trái"] # 0xec04 (en: 'up pointing brace left') + - "": [t: "lên niềng răng giữa"] # 0xec05 (en: 'up pointing brace mid') + - "": [t: "nẹp lên chỉ đúng"] # 0xec06 (en: 'up-pointing brace right') + - "": [t: "thanh thẳng đứng trái"] # 0xec07 (en: 'left vertical bar') + - "": [t: "thanh dọc bên phải"] # 0xec08 (en: 'right vertical bar') + - "": [t: "thanh dọc trái"] # 0xec09 (en: 'left double vertical bar') + - "": [t: "thanh dọc bên phải"] # 0xec0a (en: 'right double vertical bar') + - "": [t: "bộ mở rộng khung ngang"] # 0xec0b (en: 'horizontal bracket extender') + - "": [t: "dưới khung vuông"] # 0xec0c (en: 'under square bracket') + - "⎵": [t: "dưới khung vuông"] # 0x23b5 (en: 'under square bracket') + - "": [t: "trên khung vuông"] # 0xec0d (en: 'over square bracket') + - "⎴": [t: "trên khung vuông"] # 0x23b4 (en: 'over square bracket') + - "": [t: "dưới khung trái"] # 0xec0e (en: 'under bracket left') + - "": [t: "dưới khung đúng"] # 0xec0f (en: 'under bracket right') + - "": [t: "qua giá đỡ trái"] # 0xec10 (en: 'over bracket left') + - "": [t: "trên khung đúng"] # 0xec11 (en: 'over bracket right') + - "": [t: "dấu ngoặc trái 1"] # 0xec12 (en: 'left parens 1') + - "": [t: "dấu ngoặc trái 2"] # 0xec13 (en: 'left parens 2') + - "": [t: "dấu ngoặc đơn 3"] # 0xec14 (en: 'left parens 3') + - "": [t: "dấu ngoặc trái 4"] # 0xec15 (en: 'left parens 4') + - "": [t: "dấu ngoặc đơn phải 1"] # 0xec16 (en: 'right parens 1') + - "": [t: "dấu ngoặc đơn phải 2"] # 0xec17 (en: 'right parens 2') + - "": [t: "dấu ngoặc đơn 3"] # 0xec18 (en: 'right parens 3') + - "": [t: "dấu ngoặc đơn phải 4"] # 0xec19 (en: 'right parens 4') + - "": [t: "triệt để 1"] # 0xec1a (en: 'radical 1') + - "": [t: "triệt để 2"] # 0xec1b (en: 'radical 2') + - "": [t: "triệt để 3"] # 0xec1c (en: 'radical 3') + - "": [t: "triệt để 4"] # 0xec1d (en: 'radical 4') + - "": [t: "triệt để 5"] # 0xec1e (en: 'radical 5') + - "": [t: "đáy triệt để"] # 0xec1f (en: 'radical bottom') + - "": [t: "bộ mở rộng thẳng đứng triệt để"] # 0xec20 (en: 'radical vertical extender') + - "": [t: "top cấp tiến"] # 0xec21 (en: 'radical top') + - "": [t: "mặt trái giá đỡ đầu trắng"] # 0xec22 (en: 'left white bracket top') + - "": [t: "dây mở rộng khung màu trắng"] # 0xec23 (en: 'left white bracket extender') + - "": [t: "mặt trái phía dưới khung màu trắng"] # 0xec24 (en: 'left white bracket bottom') + - "": [t: "bên phải khung màu trắng"] # 0xec25 (en: 'right white bracket top') + - "": [t: "bên phải bộ mở rộng khung trắng"] # 0xec26 (en: 'right white bracket extender') + - "": [t: "đáy khung trắng bên phải"] # 0xec27 (en: 'right white bracket bottom') + - "": [t: "khung màu trắng trái"] # 0xec30 (en: 'left white curly bracket') + - "": [t: "quyền trắng trắng trắng"] # 0xec31 (en: 'right white curly bracket') + - "": [t: "dấu hiệu phân chia dài"] # 0xec32 (en: 'long division sign') + - "": [t: "bộ mở rộng dấu hiệu phân chia dài"] # 0xec33 (en: 'long division sign extender') + - "": [t: "phân chia ngắn"] # 0xec34 (en: 'short division') + - "": [t: "double tây nam đến đông bắc em bond"] # 0xec40 (en: 'double southwest to northeast em bond') + - "": [t: "double tây bắc đến đông nam bond bond"] # 0xec41 (en: 'double northwest to southeast em bond') + - "": [t: "liên kết em ngang đơn"] # 0xec42 (en: 'single horizontal em bond') + - "": [t: "double ngang liên kết em"] # 0xec43 (en: 'double horizontal em bond') + - "": [t: "triple ngang liên kết em"] # 0xec44 (en: 'triple horizontal em bond') + - "": [t: "liên kết em thẳng đứng"] # 0xec45 (en: 'single vertical em bond') + - "": [t: "double dọc liên kết em"] # 0xec46 (en: 'double vertical em bond') + - "": [t: "triple thẳng đứng liên kết em"] # 0xec47 (en: 'triple vertical em bond') + - "": [t: "ít hơn trái phiếu em"] # 0xec48 (en: 'less than em bond') + - "": [t: "lớn hơn liên kết em"] # 0xec49 (en: 'greater than em bond') + - "": [t: "liên kết en ngang đơn"] # 0xec4a (en: 'single horizontal en bond') + - "": [t: "double ngang liên kết en"] # 0xec4b (en: 'double horizontal en bond') + - "": [t: "triple hormanontal en liên kết"] # 0xec4c (en: 'triple horizontal en bond') + - "": [t: "trên cùng bên trái hình chữ nhật"] # 0xec80 (en: 'top left rectangle') + - "": [t: "hình chữ nhật phía dưới bên trái"] # 0xec81 (en: 'bottom left rectangle') + - "": [t: "trên cùng bên phải hình chữ nhật"] # 0xec90 (en: 'top right rectangle') + - "": [t: "dưới cùng bên phải hình chữ nhật"] # 0xec91 (en: 'bottom right rectangle') + - "": [t: "phân chia tổng hợp góc"] # 0xec92 (en: 'synthetic division corner') + - "": [t: "phân chia tổng hợp mở rộng ngang"] # 0xec93 (en: 'synthetic division horizontal extender') + - "": [t: "phân chia tổng hợp mở rộng dọc"] # 0xec94 (en: 'synthetic division vertical extender') + - "": [t: "bên trái sàn mở rộng"] # 0xec95 (en: 'left ceiling floor extender') + - "": [t: "bên phải sàn mở rộng"] # 0xec96 (en: 'right ceiling floor extender') + - "": [t: "qua bộ mở rộng khung"] # 0xec97 (en: 'over bracket extender') + - "": [t: "máy mở rộng thanh dọc"] # 0xec98 (en: 'vertical bar extender') + - "": [t: "bên trái đôi mở rộng thanh dọc"] # 0xec99 (en: 'left double vertical bar extender') + - "": [t: "máy mở rộng thanh ngang"] # 0xec9a (en: 'horizontal bar extender') + - "": [t: "dưới phần mở rộng khung"] # 0xec9c (en: 'under bracket extender') + - "": [t: "xuống dấu ngoặc đơn đúng"] # 0xec9d (en: 'down pointing paren right') + - "": [t: "xuống chỉ dấu ngoặc đơn"] # 0xec9e (en: 'down pointing paren extender') + - "": [t: "down chỉ dấu ngoặc đơn trái"] # 0xec9f (en: 'down pointing paren left') + - "": [t: "lên chỉ dây mở rộng nẹp"] # 0xeca0 (en: 'up pointing brace extender') + - "": [t: "lên dấu ngoặc đơn còn lại"] # 0xeca1 (en: 'up pointing paren left') + - "": [t: "lên dấu ngoặc đơn"] # 0xeca2 (en: 'up pointing paren extender') + - "": [t: "lên dấu ngoặc đơn đúng"] # 0xeca3 (en: 'up pointing paren right') + - "": [t: "xuống chỉ dây mở rộng nẹp"] # 0xeca4 (en: 'down pointing brace extender') + - "": [t: "planck hằng số trên hai thanh pi"] # 0xed00 (en: 'planck constant over two pi bar') + - "": [t: "gương g"] # 0xed01 (en: 'mirror g') + - "": [t: "dotless j"] # 0xed02 + - "": [t: "digamma"] # 0xed03 + - "ϝ": [t: "digamma"] # 0x3dd + - "": [t: ""] # 0xed10 (en: 'd') + - "": [t: ""] # 0xed11 (en: 'e') + - "": [t: ""] # 0xed12 (en: 'i') + - "": [t: ""] # 0xed13 (en: 'j') + - "ⅅ": + - spell: "translate('.', 'ⅅ', 'DD')" # 0xed16, 0x2145 + +# The private use chars are from MathType + - "": [t: "vòng lặp tích hợp đường viền ngược chiều kim đồng hồ"] # 0xee00 (en: 'anticlockwise contour integral loop') + - "": [t: "vòng lặp tích phân theo chiều kim đồng hồ"] # 0xee01 (en: 'clockwise contour integral loop') + - "": [t: ""] # 0xee04 + - "": [t: ""] # 0xee05 + - "": [t: ""] # 0xee06 + - "": [t: ""] # 0xee07 + - "": [t: ""] # 0xee08 + - "": [t: ""] # 0xee09 + - "": [t: ""] # 0xee0a + - "": [t: ""] # 0xee0b + - "": [t: ""] # 0xee0c + - "": [t: "tinh chỉnh trạng thái chung"] # 0xee0d (en: 'joint status embellishment') + - "": [t: "tinh chỉnh trạng thái chung trái"] # 0xee0e (en: 'joint status embellishment left') + - "": [t: "tinh chỉnh trạng thái chung quyền"] # 0xee0f (en: 'joint status embellishment right') + - "": [t: "trạng thái chung extender"] # 0xee10 (en: 'joint status embellishment extender') + - "": [t: "vòng lặp tích hợp"] # 0xee11 (en: 'integral loop') + - "": [t: "vòng lặp tích phân đôi"] # 0xee12 (en: 'integral loop double') + - "": [t: "tích hợp vòng ba"] # 0xee13 (en: 'integral loop triple') + - "": [t: "mở rộng đôi vòng lặp tích phân"] # 0xee15 (en: 'expanding integral loop double') + - "": [t: "mở rộng ba vòng lặp tích phân"] # 0xee16 (en: 'expanding integral loop triple') + - "": [t: "không có triệu chứng bằng giọng"] # 0xee17 (en: 'asymptotically equal to accent') + - "": [t: "dấu hiệu bằng giọng"] # 0xee18 (en: 'equal sign accent') + - "": [T: "đạo hàm cấp bốn"] # 0xee19 + - "⁗": [T: "đạo hàm cấp bốn"] # 0x2057 + - "": [t: "tăng điểm số với vòng tròn mở bên trái"] # 0xee1a (en: 'bar accent with open circle left') + - "": [t: "điểm nhấn thanh với vòng tròn kín trái"] # 0xee1b (en: 'bar accent with closed circle left') + - "": [t: "tăng điểm số với vòng tròn mở phải"] # 0xee1c (en: 'bar accent with open circle right') + - "": [t: "tăng điểm số với dot"] # 0xee1d (en: 'bar accent with over dot') + - "": [t: "tăng điểm số với dưới chấm"] # 0xee1e (en: 'bar accent with under dot') + - "": [t: "tăng điểm số với gấp đôi so với chấm"] # 0xee1f (en: 'bar accent with double over dot') + - "": [t: "tăng điểm số với gấp đôi dưới dấu chấm"] # 0xee20 (en: 'bar accent with double under dot') + - "": [t: "giọng nói với caret"] # 0xee21 (en: 'bar accent with caret') + - "": [t: "dày dưới điểm nhấn thanh"] # 0xee22 (en: 'thick under bar accent') + - "": [t: "tăng điểm số với vòng tròn kín phải"] # 0xee23 (en: 'bar accent with closed circle right') + - "": [t: "chấm lớn ở trên"] # 0xee24 (en: 'large dot above') + - "": [t: "đánh dấu căn chỉnh"] # 0xef00 (en: 'alignment mark') + - "": [t: ""] # 0xef01 + - "​": [t: ""] # 0x200b + - "": [t: ""] # 0xef02 + - " ": [t: ""] # 0x2009 + - "": [t: ""] # 0xef03 + - " ": [t: ""] # 0x205f + - "": [t: ""] # 0xef04 + - "": [t: ""] # 0xef05 + - " ": [t: ""] # 0x2003 + - "": [t: ""] # 0xef06 + - "": [t: ""] # 0xef07 + - "": [t: ""] # 0xef08 + - "": [t: ""] # 0xef09 + - "": [t: ""] # 0xef0a + - " ": [t: ""] # 0x200a + - "": [t: ""] # 0xef22 + - "": [t: ""] # 0xef23 + - "": [t: ""] # 0xef24 + - "": [t: ""] # 0xef29 + - "": [t: "thiếu nhiệm kỳ"] # 0xef41 (en: 'missing term') + - "": [t: "mũi tên tích phân đường theo chiều kim đồng hồ bên trái"] # 0xef80 (en: 'clockwise contour integral arrow on left') + - "": [t: "tích hợp với hình vuông"] # 0xef81 (en: 'integral with square') + - "": [t: "tích hợp với chém"] # 0xef82 (en: 'integral with slash') + - "": [t: "đảo ngược tích phân"] # 0xef83 (en: 'reversed integral') + - "": [t: "double zero trên gấp đôi 0"] # 0xef90 (en: 'double zero over double zero') + - "": [t: "zero với chém"] # 0xef91 (en: 'zero with slash') + + # fraktur chars in math alphabetic block and also MathType private use area + # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display + - "𝔄-𝔜": # 0x1d504 - 0x1d51d ('z' version is reserved) + - t: "fraktur" + - spell: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" + + - "-": # 0xf000 - 0xf018 + - t: "fraktur" + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" + + - "𝔞-𝔷": # 0x1d51e - 0x1d537 + - t: "fraktur" + - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf01a - 0xf033 + - t: "fraktur" + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝕬-𝖅": # 0x1D56C - 0x1D585 + - t: "fraktur táo bạo" # (en: 'fraktur bold') + - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf040 - 0xf059 + - t: "fraktur táo bạo" # (en: 'fraktur bold') + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝖆-𝖟": # 0x1d586 - 0x1d59f + - t: "fraktur táo bạo" # (en: 'fraktur bold') + - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf05a - 0xf073 + - t: "fraktur táo bạo" # (en: 'fraktur bold') + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + # double struck (blackboard bold) chars in math alphabetic block and also MathType private use area + # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display + - "𝔸-𝕐": # 0x1d504 - 0x1d51d ('z' version is reserved) + - test: + if: "$Verbosity!='Terse'" + then: [t: "cú đúp"] # (en: 'double struck') + - spell: "translate('.', '𝔸𝔹𝔺𝔻𝔼𝔽𝔾𝔿𝕀𝕁𝕂𝕃𝕄𝕅𝕆𝕇𝕈𝕉𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf080 - 0xf098 + - test: + if: "$Verbosity!='Terse'" + then: [t: "cú đúp"] # (en: 'double struck') + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝕒-𝕫": # 0x1d552 - 0x1d56b + - test: + if: "$Verbosity!='Terse'" + then: [t: "cú đúp"] # (en: 'double struck') + - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf09a - 0xf0b3 + - test: + if: "$Verbosity!='Terse'" + then: [t: "cú đúp"] # (en: 'double struck') + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 + - test: + if: "$Verbosity!='Terse'" + then: [t: "cú đúp"] # (en: 'double struck') + - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" + - "-": # 0xf0c0 - 0xf0c9 + - test: + if: "$Verbosity!='Terse'" + then: [t: "cú đúp"] # (en: 'double struck') + - spell: "translate('.', '', '0123456789')" + + - "": [t: "double tấn công nabla"] # 0xf0ca (en: 'double struck nabla') + - "": [t: "double tấn công hằng số euler"] # 0xf0cb (en: 'double struck euler constant') + + # script chars in math alphabetic block and also MathType private use area + - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 + - t: "script" + - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf100 - 0xf119 + - t: "script" + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf + - t: "script" + - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf11a - 0xf133 + - t: "script" + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + # bold script chars in math alphabetic block and also MathType private use area + - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 + - t: "kịch bản in đậm" # (en: 'script bold') + - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf140 - 0xf159 + - t: "kịch bản in đậm" # (en: 'script bold') + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝓪-𝔃": # 0x1d4ea - 0x1d503 + - t: "kịch bản in đậm" # (en: 'script bold') + - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf15a - 0xf173 + - t: "kịch bản in đậm" # (en: 'script bold') + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf180 - 0xf199 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "": # 0xf19a + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [t: "hậu quả"] # (en: 'cap') + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [t: "ligature ae"] + - "": # 0xf19b + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [t: "hậu quả"] # (en: 'cap') + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [t: "sắc s"] # (en: 'sharp s') + - "": # 0xf19c + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [t: "hậu quả"] # (en: 'cap') + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [t: "o với gạch"] # (en: 'o with stroke') + + # MathType only has a few of the cap Greek letters in PUA + - "": # 0xf201 - 0xf209 + - test: + if: "$Verbosity!='Terse'" + then: [t: "cú đúp"] # (en: 'double struck') + - spell: "translate('.', '', 'ΔΨΛΠΣΘΓΩΥ')" + + - "-": # 0xf220 - 0xf236 + - test: + if: "$Verbosity!='Terse'" + then: [t: "cú đúp"] # (en: 'double struck') + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "": [t: "double tấn công sigma cuối cùng"] # 0xf237 (en: 'double struck final sigma') + - "": [t: "double tấn công rho"] # 0xf250 (en: 'double struck rho') + - "": [t: "double tấn công phi"] # 0xf251 (en: 'double struck phi') + - "𝐀-𝐙": # 0x1d400 - 0x1d419 + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf260 - 0xf279 + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝐚-𝐳": # 0x1d41a - 0x1d433 + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf27a - 0xf293 + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝐴-𝑍": # 0x1d434 - 0x1d44d + - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf294 - 0xf2ad + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝑎-𝑧": # 0x1d44e - 0x1d467 + - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf2ae - 0xf2c7 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝑨-𝒁": # 0x1d468 - 0x1d481 + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf2c8 - 0xf2e1 + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝒂-𝒛": # 0x1d482 - 0x1d49b + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf2e2 - 0xf2fb + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 + - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf300 - 0xf319 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 + - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf31a - 0xf333 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf334 - 0xf34d + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝗮-𝘇": # 0x1d5ee - 0x1d607 + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf34e - 0xf367 + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝘈-𝘡": # 0x1d608 - 0x1d621 + # - t: "chữ in nghiêng" # (en: 'italic') + - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": # 0xf368 - 0xf381 + # - t: "chữ in nghiêng" # (en: 'italic') + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝘢-𝘻": # 0x1d622 - 0x1d63b + # - t: "chữ in nghiêng" # (en: 'italic') + - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf382 - 0xf39b + # - t: "chữ in nghiêng" # (en: 'italic') + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝘼-𝙕": # 0x1d63c - 0x1d655 + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf39c - 0xf3b5 + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝙖-𝙯": # 0x1d656 - 0x1d66f + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf3b6 - 0xf3cf + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝙰-𝚉": # 0x1d670 - 0x1d689 + - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf3d0 - 0xf3e9 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 + - spell: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf3ea - 0xf403 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "": [t: "dotless i"] # 0xf404 + - "𝚤": [t: "dotless i"] # 0x1d6a4 + - "𝚥": [t: "dotless j"] # 0x1d6a5 + + - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf408 - 0xf420 + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf422 - 0xf43a + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "": [t: "nabla táo bạo"] # 0xf421 (en: 'bold nabla') + - "𝛁": [t: "nabla táo bạo"] # 0x1d6c1 (en: 'bold nabla') + + - "𝛛𝛜𝛝𝛞𝛟𝛠𝛡": # 0x1D6DB - 0x1D6E1 + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" + + - "": # 0xF43C - 0xF441 + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '', '∂εθκφρπ')" + + - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa + # - t: "chữ in nghiêng" # (en: 'italic') + - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf442 - 0xf45a + # - t: "chữ in nghiêng" # (en: 'italic') + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝛼-𝜔": # 0x1d6fc - 0x1d714 + # - t: "chữ in nghiêng" # (en: 'italic') + - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓𝜔', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf45c - 0xf474 + # - t: "chữ in nghiêng" # (en: 'italic') + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "": [t: "nabla in nghiêng"] # 0xf45b (en: 'italic nabla') + - "𝛻": [t: "nabla in nghiêng"] # 0x1d6fb (en: 'italic nabla') + + - "𝜕𝜖𝜗𝜘𝜙𝜚𝜛": # 0x1d715 - 0x1d71b + # - t: "chữ in nghiêng" # (en: 'italic') + - spell: "translate('.', '𝜕𝜖𝜗𝜘𝜙𝜚𝜛', '∂εθκφρπ')" + + - "": # 0xf475 - 0xf47b + # - t: "chữ in nghiêng" # (en: 'italic') + - spell: "translate('.', '', '∂εθκφρπ')" + + - "𝜜-𝜴": # 0x1d71c - 0x1d734 + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf47c - 0xf494 + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝜶-𝝎": # 0x1d736 - 0x1d74e + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf496 - 0xf4ae + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": # 0x1d74f - 0x1d755 + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εθκφρπ')" + + - "": # 0xf422 - 0xf43a + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '', '∂εθκφρπ')" + + - "𝜵": [t: "nabla italic in đậm"] # 0x1d735 (en: 'bold italic nabla') + - "": [t: "nabla italic in đậm"] # 0xf495 (en: 'bold italic nabla') + + - "𝝖-𝝮": # 0x1d756 - 0x1d76e + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "-": # 0xf4b6 - 0xf4ce + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝝰-𝞈": # 0x1d770 - 0x1d788 + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇𝞈', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf4d0 - 0xf4e8 + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝞉𝞊𝞋𝞌𝞍𝞎𝞏": # 0x1d789 - 0x1d78f + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '𝞉𝞊𝞋𝞌𝞍𝞎𝞏', '∂εθκφρπ')" + + - "": # 0xf4e9 - 0xf4ef + - t: "dũng cảm" # (en: 'bold') + - spell: "translate('.', '', '∂εθκφρπ')" + + - "": [t: "nabla táo bạo"] # 0xf4cf (en: 'bold nabla') + - "𝝯": [t: "nabla táo bạo"] # 0x1d76f (en: 'bold nabla') + + - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf4f0 - 0xf508 + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝞪-𝟂": # 0x1d7aa - 0x1d7c2 + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf50a - 0xf522 + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": # 0x1d7c3 - 0x1d7c9 + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '𝟃𝟄𝟅𝟆𝟇𝟈𝟉', '∂εθκφρπ')" + + - "": # 0xf523 - 0xf529 + - t: "in nghiêng" # (en: 'bold italic') + - spell: "translate('.', '', '∂εθκφρπ')" + + - "": [t: "nabla táo bạo"] # 0xf509 (en: 'bold nabla') + - "𝞩": [t: "nabla táo bạo"] # 0x1d7a9 (en: 'bold nabla') + + - "": [t: "bold zero"] # 0xf52e + - "𝟎": [t: "bold zero"] # 0x1d7ce + - "": [t: "táo bạo"] # 0xf52f (en: 'bold one') + - "𝟏": [t: "táo bạo"] # 0x1d7cf (en: 'bold one') + - "": [t: "táo bạo hai"] # 0xf530 (en: 'bold two') + - "𝟐": [t: "táo bạo hai"] # 0x1d7d0 (en: 'bold two') + - "": [t: "bold ba"] # 0xf531 (en: 'bold three') + - "𝟑": [t: "bold ba"] # 0x1d7d1 (en: 'bold three') + - "": [t: "bold bốn"] # 0xf532 (en: 'bold four') + - "𝟒": [t: "bold bốn"] # 0x1d7d2 (en: 'bold four') + - "": [t: "bold năm"] # 0xf533 (en: 'bold five') + - "𝟓": [t: "bold năm"] # 0x1d7d3 (en: 'bold five') + - "": [t: "thứ sáu"] # 0xf534 (en: 'bold six') + - "𝟔": [t: "thứ sáu"] # 0x1d7d4 (en: 'bold six') + - "": [t: "bold seven"] # 0xf535 + - "𝟕": [t: "bold seven"] # 0x1d7d5 + - "": [t: "in đậm tại"] # 0xf536 (en: 'bold eight') + - "𝟖": [t: "in đậm tại"] # 0x1d7d6 (en: 'bold eight') + - "": [t: "bold nine"] # 0xf537 + - "𝟗": [t: "bold nine"] # 0x1d7d7 + - "": [t: "số không"] # 0xf542 (en: 'zero') + - "𝟢": [t: "số không"] # 0x1d7e2 (en: 'zero') + - "": [t: "một"] # 0xf543 (en: 'one') + - "𝟣": [t: "một"] # 0x1d7e3 (en: 'one') + - "": [t: "hai"] # 0xf544 (en: 'two') + - "𝟤": [t: "hai"] # 0x1d7e4 (en: 'two') + - "": [t: "số ba"] # 0xf545 (en: 'three') + - "𝟥": [t: "số ba"] # 0x1d7e5 (en: 'three') + - "": [t: "bốn"] # 0xf546 (en: 'four') + - "𝟦": [t: "bốn"] # 0x1d7e6 (en: 'four') + - "": [t: "số năm"] # 0xf547 (en: 'five') + - "𝟧": [t: "số năm"] # 0x1d7e7 (en: 'five') + - "": [t: "sáu"] # 0xf548 (en: 'six') + - "𝟨": [t: "sáu"] # 0x1d7e8 (en: 'six') + - "": [t: "bảy"] # 0xf549 (en: 'seven') + - "𝟩": [t: "bảy"] # 0x1d7e9 (en: 'seven') + - "": [t: "tại"] # 0xf54a (en: 'eight') + - "𝟪": [t: "tại"] # 0x1d7ea (en: 'eight') + - "": [t: "chín"] # 0xf54b (en: 'nine') + - "𝟫": [t: "chín"] # 0x1d7eb (en: 'nine') + - "": [t: "bold zero"] # 0xf54c + - "𝟬": [t: "bold zero"] # 0x1d7ec + - "": [t: "táo bạo"] # 0xf54d (en: 'bold one') + - "𝟭": [t: "táo bạo"] # 0x1d7ed (en: 'bold one') + - "": [t: "táo bạo hai"] # 0xf54e (en: 'bold two') + - "𝟮": [t: "táo bạo hai"] # 0x1d7ee (en: 'bold two') + - "": [t: "bold ba"] # 0xf54f (en: 'bold three') + - "𝟯": [t: "bold ba"] # 0x1d7ef (en: 'bold three') + - "": [t: "bold bốn"] # 0xf550 (en: 'bold four') + - "𝟰": [t: "bold bốn"] # 0x1d7f0 (en: 'bold four') + - "": [t: "bold năm"] # 0xf551 (en: 'bold five') + - "𝟱": [t: "bold năm"] # 0x1d7f1 (en: 'bold five') + - "": [t: "thứ sáu"] # 0xf552 (en: 'bold six') + - "𝟲": [t: "thứ sáu"] # 0x1d7f2 (en: 'bold six') + - "": [t: "bold seven"] # 0xf553 + - "𝟳": [t: "bold seven"] # 0x1d7f3 + - "": [t: "in đậm tại"] # 0xf554 (en: 'bold eight') + - "𝟴": [t: "in đậm tại"] # 0x1d7f4 (en: 'bold eight') + - "": [t: "bold nine"] # 0xf555 + - "𝟵": [t: "bold nine"] # 0x1d7f5 + - "": [t: "số không"] # 0xf556 (en: 'zero') + - "𝟶": [t: "số không"] # 0x1d7f6 (en: 'zero') + - "": [t: "một"] # 0xf557 (en: 'one') + - "𝟷": [t: "một"] # 0x1d7f7 (en: 'one') + - "": [t: "hai"] # 0xf558 (en: 'two') + - "𝟸": [t: "hai"] # 0x1d7f8 (en: 'two') + - "": [t: "số ba"] # 0xf559 (en: 'three') + - "𝟹": [t: "số ba"] # 0x1d7f9 (en: 'three') + - "": [t: "bốn"] # 0xf55a (en: 'four') + - "𝟺": [t: "bốn"] # 0x1d7fa (en: 'four') + - "": [t: "số năm"] # 0xf55b (en: 'five') + - "𝟻": [t: "số năm"] # 0x1d7fb (en: 'five') + - "": [t: "sáu"] # 0xf55c (en: 'six') + - "𝟼": [t: "sáu"] # 0x1d7fc (en: 'six') + - "": [t: "bảy"] # 0xf55d (en: 'seven') + - "𝟽": [t: "bảy"] # 0x1d7fd (en: 'seven') + - "": [t: "tại"] # 0xf55e (en: 'eight') + - "𝟾": [t: "tại"] # 0x1d7fe (en: 'eight') + - "": [t: "chín"] # 0xf55f (en: 'nine') + - "𝟿": [t: "chín"] # 0x1d7ff (en: 'nine') + - "": [t: "nhân vật chưa biết"] # 0xf700 (en: 'unknown character') + - "": [t: "hình tam giác dưới bên phải và dưới bên trái"] # 0xf726 (en: 'lower right and lower left triangles') + - "": [t: "bộ mở rộng hình elip ngang"] # 0xf72d (en: 'horizontal ellipsis extender') + - "": [t: "midline ngang elipsis mở rộng"] # 0xf72e (en: 'midline horizontal ellipsis extender') + - "": [t: "bộ mở rộng triệt để"] # 0xf8e5 (en: 'radical extender') + - "": [t: "máy mở rộng mũi tên dọc"] # 0xf8e6 (en: 'vertical arrow extender') + - "": [t: "máy mở rộng mũi tên ngang"] # 0xf8e7 (en: 'horizontal arrow extender') + - "": [t: "đăng ký ký sans serif"] # 0xf8e8 (en: 'registered sign sans serif') + - "": [t: "dấu hiệu bản quyền sans serif"] # 0xf8e9 (en: 'copyright sign sans serif') + - "": [t: "dấu thương mại dấu hiệu sans serif"] # 0xf8ea (en: 'trade mark sign sans serif') + - "": [t: "dấu ngoặc đơn hàng đầu"] # 0xf8eb (en: 'left paren top') + - "": [t: "phần mở rộng dấu ngoặc đơn"] # 0xf8ec (en: 'left paren extender') + - "": [t: "dấu ngoặc đơn phía dưới"] # 0xf8ed (en: 'left paren bottom') + - "": [t: "chân trái trên cùng"] # 0xf8ee (en: 'left bracket top') + - "": [t: "bộ mở rộng khung trái"] # 0xf8ef (en: 'left bracket extender') + - "": [t: "đáy khung trái"] # 0xf8f0 (en: 'left bracket bottom') + - "": [t: "bên trái nẹp trên cùng"] # 0xf8f1 (en: 'left brace top') + - "": [t: "nẹp trái giữa"] # 0xf8f2 (en: 'left brace mid') + - "": [t: "mặt trái phía dưới"] # 0xf8f3 (en: 'left brace bottom') + - "": [t: "niềng mở rộng"] # 0xf8f4 (en: 'brace extender') + - "": [t: "tích hợp mở rộng"] # 0xf8f5 (en: 'integral extender') + - "": [t: "dấu ngoặc đơn bên phải"] # 0xf8f6 (en: 'right paren top') + - "": [t: "dấu ngoặc đơn bên phải"] # 0xf8f7 (en: 'right paren extender') + - "": [t: "dấu ngoặc đơn bên dưới"] # 0xf8f8 (en: 'right paren bottom') + - "": [t: "giá đỡ bên phải"] # 0xf8f9 (en: 'right bracket top') + - "": [t: "bộ mở rộng khung phải"] # 0xf8fa (en: 'right bracket extender') + - "": [t: "đáy khung bên phải"] # 0xf8fb (en: 'right bracket bottom') + - "": [t: "đóng tay phải"] # 0xf8fc (en: 'right brace top') + - "": [t: "nẹp phải giữa"] # 0xf8fd (en: 'right brace mid') + - "": [t: "đáy giằng bên phải"] # 0xf8fe (en: 'right brace bottom') + - "": [t: "logo apple"] # 0xf8ff (en: 'apple logo') + - "ff": [t: "ff"] # 0xfb00 + - "fi": [t: "fi"] # 0xfb01 + - "fl": [t: "fl"] # 0xfb02 + - "ffi": [t: "ffi"] # 0xfb03 + - "ffl": [t: "ffl"] # 0xfb04 + - "ſt": [t: "ft"] # 0xfb05 + - "st": [t: "st"] # 0xfb06 + - "︠": [t: "ligature trái một nửa tô điểm"] # 0xfe20 (en: 'ligature left half embellishment') + - "︡": [t: "ligature bên phải một nửa tô điểm"] # 0xfe21 (en: 'ligature right half embellishment') + - "︢": [t: "double tilde để lại một nửa tô điểm"] # 0xfe22 (en: 'double tilde left half embellishment') + - "︣": [t: "double tilde phải nửa chỉnh trang"] # 0xfe23 (en: 'double tilde right half embellishment') + - "︤": [t: "macron để lại một nửa tô điểm"] # 0xfe24 (en: 'macron left half embellishment') + - "︥": [t: "macron phải nửa chỉnh trang"] # 0xfe25 (en: 'macron right half embellishment') + - "︦": [t: "tinh chỉnh macron liên kết"] # 0xfe26 (en: 'conjoining macron embellishment') + - "︵": [t: "trên dấu ngoặc đơn"] # 0xfe35 (en: 'over paren') + - "︶": [t: "dưới dấu ngoặc đơn"] # 0xfe36 (en: 'under paren') + - "︷": [t: "qua nẹp"] # 0xfe37 (en: 'over brace') + - "︸": [t: "dưới nẹp"] # 0xfe38 (en: 'under brace') + - "︿": [t: "trên khung góc"] # 0xfe3f (en: 'over angle bracket') + - "﹀": [t: "dưới khung góc"] # 0xfe40 (en: 'under angle bracket') + - "﹨": [t: "phân chia số nguyên"] # 0xfe68 (en: 'integer divide') + - "": [t: "đối tượng không xác định hoặc thiếu"] # 0xfffc (en: 'unknown or missing object') + - "�": [t: "nhân vật không rõ hoặc thiếu"] # 0xfffd (en: 'unknown or missing character') diff --git a/Rules/Languages/vi/unicode.yaml b/Rules/Languages/vi/unicode.yaml index 95835bec3..6dfa9184e 100644 --- a/Rules/Languages/vi/unicode.yaml +++ b/Rules/Languages/vi/unicode.yaml @@ -1,518 +1,518 @@ ---- - - "a-z": [T: "."] - - - "A-Z": - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - pitch: - value: "$CapitalLetters_Pitch" - # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness' and $Verbosity='Verbose'" - then: [t: "hoa"] - else: [x: "$SpeechOverrides_CapitalLetters"] - - - "0-9": [T: "."] - - - " ": [t: " "] # 0x20 - - - "!": [T: giai thừa] # 0x21 - - "\"": [T: nháy kép] # 0x22 - - "#": [T: báo số] # 0x23 - - "$": [T: đô-la] # 0x24 - - "%": [T: phần trăm] # 0x25 - - "&": [T: và] # 0x26 - - "'": [T: nháy đơn] # 0x27 - - "(": # 0x28 - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [test: {if: "$Verbosity='Terse'", then: [T: mở ngoặc], else: [T: mở ngoặc đơn]}] - else: [T: mở ngoặc đơn] - - ")": # 0x29 - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [test: {if: "$Verbosity='Terse'", then: [T: đóng ngoặc], else: [T: đóng ngoặc đơn]}] - else: [T: đóng ngoặc đơn] - - - "*": [T: nhân] # 0x2a - - "+": [T: cộng] # 0x2b - - ",": # 0x2c - # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent - # that this test is here and not with "…" is not ideal, but seems simplest - test: - if: - - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " - # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' - # speak "comma" when not adjacent to '…' - - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " - # except if expression starts with '…' - - " ../*[1][.='…'] " - then: [T: phẩy] - # else silent - - - "-": [T: trừ] # 0x2d - - ".": # 0x2e - - test: - if: "parent::*[1][self::m:mn]" - then: [T: "chấm"] - else: [T: "chấm"] - - "/": [T: chia] # 0x2f - - ":": [T: hai chấm] # 0x3a - - ";": [T: chấm phẩy] # 0x3b - - "<": # 0x3c - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] - - T: nhỏ hơn - - "=": [T: bằng] # 0x3d - - ">": # 0x3e - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] - - T: lớn hơn - - "?": [T: chấm hỏi] # 0x3f - - "@": [T: a móc] # 0x40 - - "[": # 0x5b - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: mở ngoặc vuông] - else: [T: ngoặc vuông trái] - - "\\": [T: hiệu] # 0x5c - - "]": # 0x5d - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: đóng ngoặc vuông] - else: [T: ngoặc vuông phải] - - "^": [T: mũ] # 0x5e - - "_": [T: gạch dưới] # 0x5f - - "`": [T: dấu huyền] # 0x60 - - "{": # 0x7b - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: mở ngoặc nhọn] - else: [T: ngoặc nhọn trái] - - "|": # 0x7c - # note: for ClearSpeak and SimpleSpeak, "|" in side of sets is handled at the mrow level, same for 'sets' - - with: - variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) - replace: - - test: - - if: "$SpeechStyle != 'ClearSpeak'" - then_test: - - if: "$DefaultToGiven" - then: [T: sao cho] # given - - else_if: "preceding-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))] and - following-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))]" - then: [T: sao cho] # divides - else: [T: gạch đứng] # vertical line - - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" - then: [T: gạch đứng] - - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" - then: [T: sao cho] # such that - - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" - then: [T: sao cho] # given - - else: [T: sao cho] # divides - - - "}": # 0x7d - - test: - if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [T: đóng ngoặc nhọn] - else: [T: ngoặc nhọn phải] - - - "~": [T: dấu ngã] # 0x7e - - " ": [T: ""] # 0xa0 - - "¢": [T: cents] # 0xa2 - - "£": [T: bảng Anh] # 0xa3 - - "¬": [T: không] # 0xac - - "°": [T: "độ"] # 0xb0 - - "±": [T: cộng trừ] # 0xb1 - - "´": [T: "dấu nháy đơn"] # 0xb4 - - "·": - - test: - if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolDot = 'Auto'" - then: [T: nhân] - else: [T: chấm] - - "×": # 0xd7 - - test: - if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolX = 'Auto'" - then: [T: nhân] - else_test: - if: $ClearSpeak_MultSymbolX = 'By' - then: [T: cho] - else: [T: nhân] - - "÷": [T: chia] # 0xf7 - - "̀": [T: dấu huyền] # 0x300 - - "́": [T: dấu sắc embellishment] # 0x301 - - "̂": [T: dấu mũ embellishment] # 0x302 - - "̃": [T: dấu ngã] # 0x303 - - "̄": [T: dấu nhấn] # 0x304 - - "̅": [T: thanh ngang] # 0x305 - - "̆": [T: mũ ngược] # 0x306 - - "̇": [T: dot above embellishment] # 0x307 - - # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong - - "Α-Ω": - - test: - if: "$CapitalLetters_Beep" - then: - - audio: - value: "beep.mp4" - replace: [] - - pitch: - value: "$CapitalLetters_Pitch" - # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [spell: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] - - test: - if: "$CapitalLetters_UseWord" - then_test: - if: "$SpeechOverrides_CapitalLetters = ''" - then_test: - if: "$Impairment = 'Blindness'" - then: [t: "hoa"] - else: [x: "$SpeechOverrides_CapitalLetters"] - - - "α": [T: an pha] # 0x3b1 - - "β": [T: bê ta] # 0x3b2 - - "γ": [T: gam ma] # 0x3b3 - - "δ": [T: đen ta] # 0x3b4 - - "ε": [T: ép si lon] # 0x3b5 - - "ζ": [T: dê ta] # 0x3b6 - - "η": [T: ê ta] # 0x3b7 - - "θ": [T: tê ta] # 0x3b8 - - "ι": [T: i ô ta] # 0x3b9 - - "κ": [T: k pa] # 0x3ba - - "λ": [T: lam đa] # 0x3bb - - "μ": [T: mu] # 0x3bc - - "ν": [T: nu] # 0x3bd - - "ξ": [T: xi] # 0x3be - - "ο": [T: o mi rong] # 0x3bf - - "π": [T: pi] # 0x3c0 - - "ρ": [T: rô] # 0x3c1 - - "ς": [T: xích ma cuối] # 0x3c2 - - "σ": [T: xích ma] # 0x3c3 - - "τ": [T: tô] # 0x3c4 - - "υ": [T: ấp si lon] # 0x3c5 - - "φ": [T: phi] # 0x3c6 - - "χ": [T: cai] # 0x3c7 - - "ψ": [T: bờ si] # 0x3c8 - - "ω": [T: ô mê ga] # 0x3c9 - - "ϕ": [T: phi] # 0x3d5 - - "ϖ": [T: pi] # 0x3d6 - - "ϵ": [T: ép si lon] # 0x3f5 - - "϶": [T: ép si lon đảo ngược] # 0x3f6 - - "ℂ": # 0x2102 - - T: C - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: "hoa"] - - T: gạch đôi - - "℃": [T: độ C] # 0x2103 - - "ℋ": # 0x210b - - T: h - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: "hoa"] - - T: viết tay - - - "ℕ": # 0x2115 - - T: n - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: "hoa"] - - T: gạch đôi - - "ℚ": # 0x211a - - T: q - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: "hoa"] - - T: gạch đôi - - "ℛ": # 0x211b - - T: r - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: "hoa"] - - T: viết tay - - "ℜ": # 0x211c - - T: r - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: "hoa"] - - T: kiểu chữ tiếng Đức - - "ℝ": # 0x211d - - T: r - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: "hoa"] - - T: gạch đôi - - "ℤ": # 0x2124 - - T: z - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: "hoa"] - - T: gạch đôi - - "ⅉ": [T: J nghiêng gạch đôi] # 0x2149 - - "∇": # 0x2207 - - test: - if: "$Verbosity!='Terse'" - then: [t: "các"] # (en: 'the') - - t: "độ dốc của" # (en: 'gradient of') - - # --- restored complex short definitions (prefer over unicode-full) --- - - "А": # 0x410 - - T: a - - test: - if: "($Blind or $Verbosity!='Terse')" - then: [T: "hoa"] - - "…": # 0x2026 - test: - if: - - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" - # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' - # speak '…' as 'and so on...' unless expr starts with '…' - - "../*[1][.='…']" - then: [T: chấm chấm chấm] - else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' - if: "count(following-sibling::*) = 0" - then: [T: và như thế] - else: [T: và như vậy cho đến] - - "⁡": # 0x2061 - - test: - # skip saying "of" when Terse and a trig function, when it is a shape (does this happen?), or we are in :literal mode - if: "not( - ( $Verbosity='Terse' or ($SpeechStyle = 'ClearSpeak' and IsNode(following-sibling::*[1],'simple')) and - preceding-sibling::*[1][IfThenElse($SpeechStyle='ClearSpeak', - IsInDefinition(., 'ClearSpeakTrigFunctionNames'), - IsInDefinition(., 'TrigFunctionNames') )] - ) or - preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')] or - (@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) - )" - then: [T: "của"] - - "→": # 0x2192 - - test: - if: "ancestor::*[2][self::m:limit]" - then: [T: "tiến đến"] - else: [T: "mũi tên phải"] - - "∂": # 0x2202 - - test: - if: "$Verbosity='Terse'" - then: [T: phần] - else: [T: đạo hàm riêng] - - "∆": # 0x2206 - # - test: - # if: "$Verbosity!='Terse'" - # then: [T: "the"] - - T: đen ta - - "∈": # 0x2208 - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: [T: là phần tử của] - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [T: thuộc] - - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: phần tử của] - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: phần tử của] - - else: [T: thuộc về] # $ClearSpeak_SetMemberSymbol = 'Belongs' - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: thuộc] - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: thuộc] - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [T: thuộc] - - else: [T: thuộc] # $ClearSpeak_SetMemberSymbol = 'Belongs' - - "∉": # 0x2209 - # rule is identical to 0x2208 - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: [T: không thuộc] - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [T: không thuộc] - - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: không thuộc] - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: không thuộc] - - else: [T: không thuộc về] # $ClearSpeak_SetMemberSymbol = 'Belongs' - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: không thuộc] - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: không thuộc] - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [T: không thuộc] - - else: [T: không thuộc] # $ClearSpeak_SetMemberSymbol = 'Belongs' - - "∊": # 0x220a - - test: - if: "$SpeechStyle != 'ClearSpeak'" - then: [T: thuộc] - # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option - else_test: - if: "../../self::m:set or ../../../self::m:set" # inside a set - then_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [T: thuộc] - - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: thuộc] - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: thuộc] - - else: [T: thuộc] # $ClearSpeak_SetMemberSymbol = 'Belongs' - else_test: - - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [T: thuộc] - - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [T: thuộc] - - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [T: thuộc] - - else: [T: thuộc] # $ClearSpeak_SetMemberSymbol = 'Belongs' - - "√": # 0x221a - # - test: - # if: "$Verbosity!='Terse'" - # then: [T: ""] - - T: căn bậc 2 của - - "∝": # 0x221d - # - test: - # if: "$Verbosity!='Terse'" - # then: [T: is] - - T: tỉ lệ với - - "∥": # 0x2225 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] - - T: song song với - - "∦": # 0x2226 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] - - T: không song song với - - "∶": # 0x2236 - #- test: - # if: "$Verbosity!='Terse'" - # then: [T: is] - - T: tỉ suất - - "∾": # 0x223e - # - test: - # if: "$Verbosity!='Terse'" - # then: [T: is] - - T: đồng dạng - - "≠": # 0x2260 - - test: - if: "$Verbosity!='Terse'" - then: [T: ""] - - T: khác - - "≡": # 0x2261 - - test: - if: "$Verbosity!='Terse'" - then: [T: trùng với] - - "≤": [T: nhỏ hơn hoặc bằng] # 0x2264 - #- test: - #if: "$Verbosity!='Terse'" - #then: [T: nhỏ hơn hoặc bằng] - - "≥": [T: lớn hơn hoặc bằng] # 0x2265 - #- test: - #if: "$Verbosity!='Terse'" - #then: [T: lớn hơn hoặc bằng] - - "⊂": [T: chứa trong] # 0x2282 - #- test: - #if: "$Verbosity!='Terse'" - #then: [T: chứa trong] - - "⊃": [T: chứa] # 0x2283 - #- test: - #if: "$Verbosity!='Terse'" - #then: [T: chứa] - - "⊄": # 0x2284 - # - test: - # if: "$Verbosity!='Terse'" - # then: [T: is] - - T: không chứa trong - - "⊅": # 0x2285 - # - test: - # if: "$Verbosity!='Terse'" - # then: [T: is] - - T: không chứa - - "⊆": [T: chứa trong hoặc bằng] # 0x2286 - #- test: - #if: "$Verbosity!='Terse'" - #then: [T: chứa trong] - - "⊇": [T: chứa hoặc bằng] # 0x2287 - #- test: - #if: "$Verbosity!='Terse'" - #then: [T: chứa] - - # --- restored short definitions that differ from unicode-full --- - - "–": [T: gạch nối] # 0x2013 - - "—": [T: gạch ngang] # 0x2014 - - "―": [T: gạch ngang dài] # 0x2015 - - "‖": [T: đường thẳng đứng kép] # 0x2016 - - "⁢": [T: ""] # 0x2062 - - "⁣": [T: ""] # 0x2063 - - "⁤": [T: "và"] # 0x2064 - - "′": [T: phẩy] # 0x2032 - - "″": [T: đạo hàm cấp hai] # 0x2033 - - "‴": [T: đạo hàm cấp ba] # 0x2034 - - "‵": [T: nguyên hàm] # 0x2035 - - "‶": [T: nguyên hàm cấp hai] # 0x2036 - - "‷": [T: nguyên hàm cấp ba] # 0x2037 - - "℉": [T: độ F] # 0x2109 - - "ℎ": [T: hằng số plankc] # 0x210e - - "ℓ": [T: l viết tay] # 0x2113 - - "Ω": [T: ohms] # 0x2126 - - "K": [T: kelvin] # 0x212a - - "Å": [T: angstroms] # 0x212b - - "ⅆ": [T: D nghiêng gạch đôi] # 0x2146 - - "ⅇ": [T: E nghiêng gạch đôi] # 0x2147 - - "ⅈ": [T: I nghiêng gạch đôi] # 0x2148 - - "←": [T: mũi tên trái] # 0x2190 - - "↑": [T: mũi tên lên] # 0x2191 - - "↓": [T: mũi tên xuống] # 0x2193 - - "⇒": [T: suy ra] # 0x21d2 - - "∀": [T: với mọi] # 0x2200 - - "∃": [T: tồn tại ít nhất] # 0x2203 - - "∄": [T: không tồn tại] # 0x2204 - - "∅": [T: tập hợp rỗng] # 0x2205 - - "∏": [T: pi] # 0x220f - - "∐": [T: pi ngược] # 0x2210 - - "∑": [T: tổng] # 0x2211 - - "−": [T: trừ] # 0x2212 - - "∓": [T: trừ cộng] # 0x2213 - - "∗": [T: nhân] # 0x2217 - - "∘": [T: hàm hợp] # 0x2218 - - "∞": [T: "vô cực"] # 0x221e - - "∟": [T: góc vuông] # 0x221f - - "∠": [T: góc] # 0x2220 - - "∡": [T: góc được đo] # 0x2221 - - "∣": [T: chia hết] # 0x2223 - - "∤": [T: không chia hết] # 0x2224 - - "∧": [T: và] # 0x2227 - - "∨": [T: hoặc] # 0x2228 - - "∩": [T: giao] # 0x2229 - - "∪": [T: hợp] # 0x222a - - "∫": [T: tích phân] # 0x222b - - "∬": [T: tích phân 2 lớp] # 0x222c - - "∭": [T: tích phân 3 lớp] # 0x222d - - "∮": [T: tích phân vòng] # 0x222e - - "∷": [T: tỉ lệ] # 0x2237 - - "∼": [T: tương tự với] # 0x223c - - "∽": [T: dấu ngã ngược] # 0x223d - - "∿": [T: hình sin] # 0x223f - - "≦": [T: nhỏ hơn hoặc bằng] # 0x2266 - - "≧": [T: lớn hơn hoặc bằng] # 0x2267 - - "≺": [T: precedes] # 0x227a - - "≻": [T: succeeds] # 0x227b +--- + - "a-z": [T: "."] + + - "A-Z": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness' and $Verbosity='Verbose'" + then: [t: "hoa"] + else: [x: "$SpeechOverrides_CapitalLetters"] + + - "0-9": [T: "."] + + - " ": [t: " "] # 0x20 + + - "!": [T: giai thừa] # 0x21 + - "\"": [T: nháy kép] # 0x22 + - "#": [T: báo số] # 0x23 + - "$": [T: đô-la] # 0x24 + - "%": [T: phần trăm] # 0x25 + - "&": [T: và] # 0x26 + - "'": [T: nháy đơn] # 0x27 + - "(": # 0x28 + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [test: {if: "$Verbosity='Terse'", then: [T: mở ngoặc], else: [T: mở ngoặc đơn]}] + else: [T: mở ngoặc đơn] + - ")": # 0x29 + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [test: {if: "$Verbosity='Terse'", then: [T: đóng ngoặc], else: [T: đóng ngoặc đơn]}] + else: [T: đóng ngoặc đơn] + + - "*": [T: nhân] # 0x2a + - "+": [T: cộng] # 0x2b + - ",": # 0x2c + # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent + # that this test is here and not with "…" is not ideal, but seems simplest + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak "comma" when not adjacent to '…' + - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " + # except if expression starts with '…' + - " ../*[1][.='…'] " + then: [T: phẩy] + # else silent + + - "-": [T: trừ] # 0x2d + - ".": # 0x2e + - test: + if: "parent::*[1][self::m:mn]" + then: [T: "chấm"] + else: [T: "chấm"] + - "/": [T: chia] # 0x2f + - ":": [T: hai chấm] # 0x3a + - ";": [T: chấm phẩy] # 0x3b + - "<": # 0x3c + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] + - T: nhỏ hơn + - "=": [T: bằng] # 0x3d + - ">": # 0x3e + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] + - T: lớn hơn + - "?": [T: chấm hỏi] # 0x3f + - "@": [T: a móc] # 0x40 + - "[": # 0x5b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: mở ngoặc vuông] + else: [T: ngoặc vuông trái] + - "\\": [T: hiệu] # 0x5c + - "]": # 0x5d + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: đóng ngoặc vuông] + else: [T: ngoặc vuông phải] + - "^": [T: mũ] # 0x5e + - "_": [T: gạch dưới] # 0x5f + - "`": [T: dấu huyền] # 0x60 + - "{": # 0x7b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: mở ngoặc nhọn] + else: [T: ngoặc nhọn trái] + - "|": # 0x7c + # note: for ClearSpeak and SimpleSpeak, "|" in side of sets is handled at the mrow level, same for 'sets' + - with: + variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) + replace: + - test: + - if: "$SpeechStyle != 'ClearSpeak'" + then_test: + - if: "$DefaultToGiven" + then: [T: sao cho] # given + - else_if: "preceding-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))] and + following-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))]" + then: [T: sao cho] # divides + else: [T: gạch đứng] # vertical line + - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" + then: [T: gạch đứng] + - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" + then: [T: sao cho] # such that + - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" + then: [T: sao cho] # given + - else: [T: sao cho] # divides + + - "}": # 0x7d + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: đóng ngoặc nhọn] + else: [T: ngoặc nhọn phải] + + - "~": [T: dấu ngã] # 0x7e + - " ": [T: ""] # 0xa0 + - "¢": [T: cents] # 0xa2 + - "£": [T: bảng Anh] # 0xa3 + - "¬": [T: không] # 0xac + - "°": [T: "độ"] # 0xb0 + - "±": [T: cộng trừ] # 0xb1 + - "´": [T: "dấu nháy đơn"] # 0xb4 + - "·": + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolDot = 'Auto'" + then: [T: nhân] + else: [T: chấm] + - "×": # 0xd7 + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolX = 'Auto'" + then: [T: nhân] + else_test: + if: $ClearSpeak_MultSymbolX = 'By' + then: [T: cho] + else: [T: nhân] + - "÷": [T: chia] # 0xf7 + - "̀": [T: dấu huyền] # 0x300 + - "́": [T: dấu sắc embellishment] # 0x301 + - "̂": [T: dấu mũ embellishment] # 0x302 + - "̃": [T: dấu ngã] # 0x303 + - "̄": [T: dấu nhấn] # 0x304 + - "̅": [T: thanh ngang] # 0x305 + - "̆": [T: mũ ngược] # 0x306 + - "̇": [T: dot above embellishment] # 0x307 + + # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong + - "Α-Ω": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [spell: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [t: "hoa"] + else: [x: "$SpeechOverrides_CapitalLetters"] + + - "α": [T: an pha] # 0x3b1 + - "β": [T: bê ta] # 0x3b2 + - "γ": [T: gam ma] # 0x3b3 + - "δ": [T: đen ta] # 0x3b4 + - "ε": [T: ép si lon] # 0x3b5 + - "ζ": [T: dê ta] # 0x3b6 + - "η": [T: ê ta] # 0x3b7 + - "θ": [T: tê ta] # 0x3b8 + - "ι": [T: i ô ta] # 0x3b9 + - "κ": [T: k pa] # 0x3ba + - "λ": [T: lam đa] # 0x3bb + - "μ": [T: mu] # 0x3bc + - "ν": [T: nu] # 0x3bd + - "ξ": [T: xi] # 0x3be + - "ο": [T: o mi rong] # 0x3bf + - "π": [T: pi] # 0x3c0 + - "ρ": [T: rô] # 0x3c1 + - "ς": [T: xích ma cuối] # 0x3c2 + - "σ": [T: xích ma] # 0x3c3 + - "τ": [T: tô] # 0x3c4 + - "υ": [T: ấp si lon] # 0x3c5 + - "φ": [T: phi] # 0x3c6 + - "χ": [T: cai] # 0x3c7 + - "ψ": [T: bờ si] # 0x3c8 + - "ω": [T: ô mê ga] # 0x3c9 + - "ϕ": [T: phi] # 0x3d5 + - "ϖ": [T: pi] # 0x3d6 + - "ϵ": [T: ép si lon] # 0x3f5 + - "϶": [T: ép si lon đảo ngược] # 0x3f6 + - "ℂ": # 0x2102 + - T: C + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: "hoa"] + - T: gạch đôi + - "℃": [T: độ C] # 0x2103 + - "ℋ": # 0x210b + - T: h + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: "hoa"] + - T: viết tay + + - "ℕ": # 0x2115 + - T: n + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: "hoa"] + - T: gạch đôi + - "ℚ": # 0x211a + - T: q + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: "hoa"] + - T: gạch đôi + - "ℛ": # 0x211b + - T: r + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: "hoa"] + - T: viết tay + - "ℜ": # 0x211c + - T: r + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: "hoa"] + - T: kiểu chữ tiếng Đức + - "ℝ": # 0x211d + - T: r + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: "hoa"] + - T: gạch đôi + - "ℤ": # 0x2124 + - T: z + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: "hoa"] + - T: gạch đôi + - "ⅉ": [T: J nghiêng gạch đôi] # 0x2149 + - "∇": # 0x2207 + - test: + if: "$Verbosity!='Terse'" + then: [t: "các"] # (en: 'the') + - t: "độ dốc của" # (en: 'gradient of') + + # --- restored complex short definitions (prefer over unicode-full) --- + - "А": # 0x410 + - T: a + - test: + if: "($Blind or $Verbosity!='Terse')" + then: [T: "hoa"] + - "…": # 0x2026 + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak '…' as 'and so on...' unless expr starts with '…' + - "../*[1][.='…']" + then: [T: chấm chấm chấm] + else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' + if: "count(following-sibling::*) = 0" + then: [T: và như thế] + else: [T: và như vậy cho đến] + - "⁡": # 0x2061 + - test: + # skip saying "of" when Terse and a trig function, when it is a shape (does this happen?), or we are in :literal mode + if: "not( + ( $Verbosity='Terse' or ($SpeechStyle = 'ClearSpeak' and IsNode(following-sibling::*[1],'simple')) and + preceding-sibling::*[1][IfThenElse($SpeechStyle='ClearSpeak', + IsInDefinition(., 'ClearSpeakTrigFunctionNames'), + IsInDefinition(., 'TrigFunctionNames') )] + ) or + preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')] or + (@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) + )" + then: [T: "của"] + - "→": # 0x2192 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "tiến đến"] + else: [T: "mũi tên phải"] + - "∂": # 0x2202 + - test: + if: "$Verbosity='Terse'" + then: [T: phần] + else: [T: đạo hàm riêng] + - "∆": # 0x2206 + # - test: + # if: "$Verbosity!='Terse'" + # then: [T: "the"] + - T: đen ta + - "∈": # 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: [T: là phần tử của] + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: thuộc] + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: phần tử của] + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: phần tử của] + - else: [T: thuộc về] # $ClearSpeak_SetMemberSymbol = 'Belongs' + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: thuộc] + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: thuộc] + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: thuộc] + - else: [T: thuộc] # $ClearSpeak_SetMemberSymbol = 'Belongs' + - "∉": # 0x2209 + # rule is identical to 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: [T: không thuộc] + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: không thuộc] + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: không thuộc] + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: không thuộc] + - else: [T: không thuộc về] # $ClearSpeak_SetMemberSymbol = 'Belongs' + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: không thuộc] + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: không thuộc] + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: không thuộc] + - else: [T: không thuộc] # $ClearSpeak_SetMemberSymbol = 'Belongs' + - "∊": # 0x220a + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: [T: thuộc] + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: thuộc] + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: thuộc] + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: thuộc] + - else: [T: thuộc] # $ClearSpeak_SetMemberSymbol = 'Belongs' + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: thuộc] + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: thuộc] + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: thuộc] + - else: [T: thuộc] # $ClearSpeak_SetMemberSymbol = 'Belongs' + - "√": # 0x221a + # - test: + # if: "$Verbosity!='Terse'" + # then: [T: ""] + - T: căn bậc 2 của + - "∝": # 0x221d + # - test: + # if: "$Verbosity!='Terse'" + # then: [T: is] + - T: tỉ lệ với + - "∥": # 0x2225 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] + - T: song song với + - "∦": # 0x2226 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] + - T: không song song với + - "∶": # 0x2236 + #- test: + # if: "$Verbosity!='Terse'" + # then: [T: is] + - T: tỉ suất + - "∾": # 0x223e + # - test: + # if: "$Verbosity!='Terse'" + # then: [T: is] + - T: đồng dạng + - "≠": # 0x2260 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] + - T: khác + - "≡": # 0x2261 + - test: + if: "$Verbosity!='Terse'" + then: [T: trùng với] + - "≤": [T: nhỏ hơn hoặc bằng] # 0x2264 + #- test: + #if: "$Verbosity!='Terse'" + #then: [T: nhỏ hơn hoặc bằng] + - "≥": [T: lớn hơn hoặc bằng] # 0x2265 + #- test: + #if: "$Verbosity!='Terse'" + #then: [T: lớn hơn hoặc bằng] + - "⊂": [T: chứa trong] # 0x2282 + #- test: + #if: "$Verbosity!='Terse'" + #then: [T: chứa trong] + - "⊃": [T: chứa] # 0x2283 + #- test: + #if: "$Verbosity!='Terse'" + #then: [T: chứa] + - "⊄": # 0x2284 + # - test: + # if: "$Verbosity!='Terse'" + # then: [T: is] + - T: không chứa trong + - "⊅": # 0x2285 + # - test: + # if: "$Verbosity!='Terse'" + # then: [T: is] + - T: không chứa + - "⊆": [T: chứa trong hoặc bằng] # 0x2286 + #- test: + #if: "$Verbosity!='Terse'" + #then: [T: chứa trong] + - "⊇": [T: chứa hoặc bằng] # 0x2287 + #- test: + #if: "$Verbosity!='Terse'" + #then: [T: chứa] + + # --- restored short definitions that differ from unicode-full --- + - "–": [T: gạch nối] # 0x2013 + - "—": [T: gạch ngang] # 0x2014 + - "―": [T: gạch ngang dài] # 0x2015 + - "‖": [T: đường thẳng đứng kép] # 0x2016 + - "⁢": [T: ""] # 0x2062 + - "⁣": [T: ""] # 0x2063 + - "⁤": [T: "và"] # 0x2064 + - "′": [T: phẩy] # 0x2032 + - "″": [T: đạo hàm cấp hai] # 0x2033 + - "‴": [T: đạo hàm cấp ba] # 0x2034 + - "‵": [T: nguyên hàm] # 0x2035 + - "‶": [T: nguyên hàm cấp hai] # 0x2036 + - "‷": [T: nguyên hàm cấp ba] # 0x2037 + - "℉": [T: độ F] # 0x2109 + - "ℎ": [T: hằng số plankc] # 0x210e + - "ℓ": [T: l viết tay] # 0x2113 + - "Ω": [T: ohms] # 0x2126 + - "K": [T: kelvin] # 0x212a + - "Å": [T: angstroms] # 0x212b + - "ⅆ": [T: D nghiêng gạch đôi] # 0x2146 + - "ⅇ": [T: E nghiêng gạch đôi] # 0x2147 + - "ⅈ": [T: I nghiêng gạch đôi] # 0x2148 + - "←": [T: mũi tên trái] # 0x2190 + - "↑": [T: mũi tên lên] # 0x2191 + - "↓": [T: mũi tên xuống] # 0x2193 + - "⇒": [T: suy ra] # 0x21d2 + - "∀": [T: với mọi] # 0x2200 + - "∃": [T: tồn tại ít nhất] # 0x2203 + - "∄": [T: không tồn tại] # 0x2204 + - "∅": [T: tập hợp rỗng] # 0x2205 + - "∏": [T: pi] # 0x220f + - "∐": [T: pi ngược] # 0x2210 + - "∑": [T: tổng] # 0x2211 + - "−": [T: trừ] # 0x2212 + - "∓": [T: trừ cộng] # 0x2213 + - "∗": [T: nhân] # 0x2217 + - "∘": [T: hàm hợp] # 0x2218 + - "∞": [T: "vô cực"] # 0x221e + - "∟": [T: góc vuông] # 0x221f + - "∠": [T: góc] # 0x2220 + - "∡": [T: góc được đo] # 0x2221 + - "∣": [T: chia hết] # 0x2223 + - "∤": [T: không chia hết] # 0x2224 + - "∧": [T: và] # 0x2227 + - "∨": [T: hoặc] # 0x2228 + - "∩": [T: giao] # 0x2229 + - "∪": [T: hợp] # 0x222a + - "∫": [T: tích phân] # 0x222b + - "∬": [T: tích phân 2 lớp] # 0x222c + - "∭": [T: tích phân 3 lớp] # 0x222d + - "∮": [T: tích phân vòng] # 0x222e + - "∷": [T: tỉ lệ] # 0x2237 + - "∼": [T: tương tự với] # 0x223c + - "∽": [T: dấu ngã ngược] # 0x223d + - "∿": [T: hình sin] # 0x223f + - "≦": [T: nhỏ hơn hoặc bằng] # 0x2266 + - "≧": [T: lớn hơn hoặc bằng] # 0x2267 + - "≺": [T: precedes] # 0x227a + - "≻": [T: succeeds] # 0x227b From 18f1cf960e0b1b0d77fb0ce4d4d757060288d317 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Thu, 1 Oct 2026 18:35:19 +0200 Subject: [PATCH 156/157] Create rule coverage functionality (#834) (#845) * v1 of rule coverage report * Add Python script to generate Markdown and HTML rule coverage reports * clarify name of logfiles * Switch rule coverage events to JSONL format * switch to jinja2 templates * Exclude Unicode mapping files from rule coverage report and improve report generation * Exclude definition files from rule coverage report and update related documentation * Add hit counts and test details to rule coverage report Enhance the rule coverage report to include hit counts, test details, and hoverable tooltips for matched rules. Improve report formatting and coverage fraction calculation. Update related tests and documentation to reflect these changes. * fix title * Simplify rule coverage event recording * Stream rule coverage events and trim unused report fields * Suppress unused variable warning when `rule-coverage` feature is disabled * Migrate `rule_coverage` implementation to a dedicated `rulecoverage` package, separating logic, templates, and CLI. * uv run ruff format * simplify dataclasses in Python * remove "loaded" as statistic for rule coverage * remove MD report and only keep HTML. simplify rest accordingly. * uv ruff format --- Cargo.lock | 26 +++ Cargo.toml | 2 + PythonScripts/README.md | 9 + PythonScripts/audit_translations/README.md | 3 + PythonScripts/audit_translations/cli.py | 13 +- .../rulecoverage/__init__.py | 1 + .../rulecoverage/rule_coverage.html | 93 +++++++++++ .../rulecoverage/rule_coverage.py | 116 +++++++++++++ .../rulecoverage/rule_coverage_report.py | 66 ++++++++ .../tests/test_rule_coverage_cli.py | 156 ++++++++++++++++++ PythonScripts/pyproject.toml | 1 + PythonScripts/uv.lock | 44 +++++ src/lib.rs | 2 + src/rule_coverage.rs | 58 +++++++ src/speech.rs | 12 ++ 15 files changed, 600 insertions(+), 2 deletions(-) create mode 100644 PythonScripts/audit_translations/rulecoverage/__init__.py create mode 100644 PythonScripts/audit_translations/rulecoverage/rule_coverage.html create mode 100644 PythonScripts/audit_translations/rulecoverage/rule_coverage.py create mode 100644 PythonScripts/audit_translations/rulecoverage/rule_coverage_report.py create mode 100644 PythonScripts/audit_translations/tests/test_rule_coverage_cli.py create mode 100644 src/rule_coverage.rs diff --git a/Cargo.lock b/Cargo.lock index 529029471..66743aed7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -651,6 +651,12 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + [[package]] name = "jiff" version = "0.2.20" @@ -805,6 +811,7 @@ dependencies = [ "radix_fmt", "regex", "roman-numerals-rs", + "serde_json", "strum", "sxd-document-no-unsafe", "sxd-xpath-no-unsafe", @@ -1362,6 +1369,19 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "serde_json" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + [[package]] name = "shlex" version = "2.0.1" @@ -2074,6 +2094,12 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7948af682ccbc3342b6e9420e8c51c1fe5d7bf7756002b4a3c6cabfe96a7e3c" +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" + [[package]] name = "zopfli" version = "0.8.3" diff --git a/Cargo.toml b/Cargo.toml index e07193031..a51507536 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ exclude = ["src/main.rs", "docs", "BrailleDocs", "PythonScripts"] # should ha [features] +"rule-coverage" = ["dep:serde_json"] "include-zip" = [] "enable-logs" = ["android_logger"] "tts" = [ "natural-tts" ] @@ -38,6 +39,7 @@ cfg-if = "1.0.1" fastrand = { version = "2.3.0" } clap = { version = "4.5.60", features = ["derive"] } html-escape = "0.2.13" +serde_json = { version = "1.0", optional = true } elements_rs = { version = "0.2.8", default-features = false } # Runtime extracts inner language/braille zips (BZIP2). The package-rules binary also diff --git a/PythonScripts/README.md b/PythonScripts/README.md index 9eb6ed44e..d79d97dca 100644 --- a/PythonScripts/README.md +++ b/PythonScripts/README.md @@ -9,3 +9,12 @@ If you run from the repo root instead of inside `PythonScripts`, point uv at the uv sync --project PythonScripts uv run --project PythonScripts audit-translations de ``` + +To run rule YAML coverage from the repo root, use the audit tool: + +```bash +uv run --project PythonScripts audit-translations --rule-coverage +``` + +The tool opens `target/rule-coverage/index.html` in a browser when the run finishes. Expand a YAML file to see each active rule's name, tag, hit count, and match status. Hover over a rule to see which tests hit it. Coverage fractions include percentages. +The Rust test output remains at `target/rule-coverage/test.log`. diff --git a/PythonScripts/audit_translations/README.md b/PythonScripts/audit_translations/README.md index 5ebf83203..3e6d67add 100644 --- a/PythonScripts/audit_translations/README.md +++ b/PythonScripts/audit_translations/README.md @@ -67,11 +67,13 @@ The tool automatically adjusts its matching logic based on the file type: uv run audit-translations [--file ] uv run audit-translations --source uv run audit-translations --list +uv run audit-translations --rule-coverage # If running from the repo root, point uv at the project: uv run --project PythonScripts audit-translations uv run --project PythonScripts audit-translations --source uv run --project PythonScripts audit-translations --list +uv run --project PythonScripts audit-translations --rule-coverage ``` **Convenience Features:** @@ -82,6 +84,7 @@ uv run --project PythonScripts audit-translations --list * `--rules-dir`: Override the Rules/Languages directory path. * `--only`: Filter issue types (comma-separated): `missing`, `untranslated`, `extra`, `diffs`, `all`. * `--verbose`: Show detailed output including source/target snippets for rule differences. +* `--rule-coverage`: Run the full Rust test suite, generate file- and rule-level pattern coverage under `target/rule-coverage/`, and open the HTML report. File coverage includes files with active rules; empty and include-only files are not separate coverage targets. Expand a file to inspect matched and unmatched rules by name and tag, their hit counts, and hover over a rule to see the tests that matched it. Coverage fractions include percentages. This runs independently of a language audit. * **Summary Stats:** Provides a statistical summary after every run. **Examples:** diff --git a/PythonScripts/audit_translations/cli.py b/PythonScripts/audit_translations/cli.py index 6916a636e..81cac0dd0 100644 --- a/PythonScripts/audit_translations/cli.py +++ b/PythonScripts/audit_translations/cli.py @@ -10,6 +10,7 @@ from .auditor import audit_language, list_languages from .errors import AuditError from .renderer import console +from .rulecoverage.rule_coverage import run as run_rule_coverage def main() -> None: @@ -17,7 +18,7 @@ def main() -> None: sys.stdout.reconfigure(encoding="utf-8") parser = argparse.ArgumentParser( - description="Audit MathCAT translation files against a source language", + description="Audit MathCAT translations or report rule YAML test coverage", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: @@ -25,6 +26,7 @@ def main() -> None: uv run audit-translations nb --source sv uv run audit-translations de --file SharedRules/default.yaml uv run audit-translations --list + uv run audit-translations --rule-coverage """, ) @@ -32,6 +34,9 @@ def main() -> None: parser.add_argument("--source", default="en", help="Source/reference language code (default: 'en')") parser.add_argument("--file", dest="specific_file", help="Audit only a specific file (e.g., 'SharedRules/default.yaml')") parser.add_argument("--list", action="store_true", help="List available languages") + parser.add_argument( + "--rule-coverage", action="store_true", help="Run the full Rust tests and open the rule YAML coverage report" + ) parser.add_argument("--rules-dir", help="Override Rules/Languages directory path") parser.add_argument( "--only", @@ -45,7 +50,11 @@ def main() -> None: args = parser.parse_args() - if args.list: + if args.rule_coverage: + if args.language or args.list or args.specific_file or args.rules_dir or args.only or args.verbose or args.source != "en": + parser.error("--rule-coverage cannot be combined with translation audit options") + sys.exit(run_rule_coverage()) + elif args.list: list_languages(args.rules_dir) elif not args.language: parser.print_help() diff --git a/PythonScripts/audit_translations/rulecoverage/__init__.py b/PythonScripts/audit_translations/rulecoverage/__init__.py new file mode 100644 index 000000000..f9de05fe7 --- /dev/null +++ b/PythonScripts/audit_translations/rulecoverage/__init__.py @@ -0,0 +1 @@ +"""Rule coverage collection and report generation.""" diff --git a/PythonScripts/audit_translations/rulecoverage/rule_coverage.html b/PythonScripts/audit_translations/rulecoverage/rule_coverage.html new file mode 100644 index 000000000..c5235df79 --- /dev/null +++ b/PythonScripts/audit_translations/rulecoverage/rule_coverage.html @@ -0,0 +1,93 @@ + + + + + +Rule YAML coverage + + + +

Rule YAML coverage

+

Status: {{ status }}

+
{{ rule_file_count }} files with active rules{{ file_coverage }} rule files matched +{{ rule_coverage }} active rules matched
+

Paths are relative to Rules/. Files with active rules are coverage targets; +a file is matched when a rule from it completes its replacement successfully.

+{% if errors %} +

Problems

    +{% for error in errors %}
  • {{ error }}
  • {% endfor %} +
+{% endif %} +
+
+
+{% for file in files %} +
+{{ 'Matched' if file.matched else 'No match' }} +{{ file.path }} {{ file.coverage }} rules +

{{ file.coverage }} active rules matched

    +{% set file_index = loop.index0 %} +{% for rule in file.rules %} +
  • +{{ 'Matched' if rule.matched else 'No match' }} +{{ rule.name }} {{ rule.tag }} {{ rule.hits }} {{ 'hit' if rule.hits == 1 else 'hits' }} +{{ rule.tooltip }}
  • +{% endfor %} +
+
+{% endfor %} +
+ + + + diff --git a/PythonScripts/audit_translations/rulecoverage/rule_coverage.py b/PythonScripts/audit_translations/rulecoverage/rule_coverage.py new file mode 100644 index 000000000..a06178336 --- /dev/null +++ b/PythonScripts/audit_translations/rulecoverage/rule_coverage.py @@ -0,0 +1,116 @@ +"""Run the full Rust test suite and report which rule YAML files it exercises.""" + +import json +import shutil +import subprocess +import sys +import webbrowser +from collections import Counter, defaultdict +from pathlib import Path, PurePosixPath + +from .rule_coverage_report import RuleKey, coverage, render_html + +ROOT = Path(__file__).resolve().parents[3] +OUTPUT = ROOT / "target" / "rule-coverage" +EVENTS = OUTPUT / "events" + + +def read_events() -> tuple[set[RuleKey], dict[RuleKey, Counter[str]], list[str]]: + defined_rules: set[RuleKey] = set() + hits_by_test: dict[RuleKey, Counter[str]] = defaultdict(Counter) + errors: list[str] = [] + for event_file in sorted(EVENTS.glob("*.jsonl")): + for number, line in enumerate(event_file.read_text(encoding="utf-8").splitlines(), 1): + try: + event = json.loads(line) + except json.JSONDecodeError: + errors.append(f"Invalid JSON in {event_file.name}:{number}") + continue + if not isinstance(event, dict): + errors.append(f"Invalid event in {event_file.name}:{number}") + continue + kind = event.get("kind") + path = event.get("path") + if not isinstance(path, str): + errors.append(f"Invalid event in {event_file.name}:{number}") + continue + path = path.replace("\\", "/") + parts = PurePosixPath(path).parts + if ( + not parts + or PurePosixPath(path).is_absolute() + or ".." in parts + or PurePosixPath(path).suffix not in (".yaml", ".yml") + ): + errors.append(f"Invalid event in {event_file.name}:{number}") + elif kind in ("defined-rule", "matched-rule") and {"name", "tag"} <= event.keys(): + name, tag = event["name"], event["tag"] + if not isinstance(name, str) or not isinstance(tag, str) or not name or not tag: + errors.append(f"Empty rule identity in {event_file.name}:{number}") + elif kind == "defined-rule" and event.keys() == {"kind", "path", "name", "tag"}: + defined_rules.add((path, name, tag)) + elif ( + kind == "matched-rule" + and event.keys() == {"kind", "path", "name", "tag", "test"} + and isinstance(event["test"], str) + and event["test"] + ): + key = (path, name, tag) + hits_by_test[key][event["test"]] += 1 + else: + errors.append(f"Invalid event in {event_file.name}:{number}") + else: + errors.append(f"Invalid event in {event_file.name}:{number}") + return defined_rules, dict(hits_by_test), errors + + +def run() -> int: + """Generate the HTML report and open it when the run finishes.""" + OUTPUT.mkdir(parents=True, exist_ok=True) + (OUTPUT / "report.md").unlink(missing_ok=True) + if EVENTS.exists(): + shutil.rmtree(EVENTS) + EVENTS.mkdir() + + command = ["cargo", "test", "--features", "rule-coverage"] + log_path = OUTPUT / "test.log" + print(f"Running {' '.join(command)}; saving output to {log_path.relative_to(ROOT)}", flush=True) + with log_path.open("w", encoding="utf-8") as log: + try: + result = subprocess.run(command, cwd=ROOT, stdout=log, stderr=subprocess.STDOUT, check=False) + test_status = result.returncode + except OSError as error: + log.write(f"Could not run cargo: {error}\n") + test_status = 1 + + defined_rules, hits_by_test, errors = read_events() + matched_rules = set(hits_by_test) + rule_files = {path for path, _, _ in defined_rules} + matched_files = {path for path, _, _ in matched_rules} + if test_status: + errors.insert(0, f"cargo test failed (exit status {test_status}); see test.log") + if not defined_rules: + errors.append("No active rule definitions found") + if not matched_rules: + errors.append("No matched rule events found") + if matched_rules - defined_rules: + errors.append("Matched rules lack definition events") + + status = "Incomplete" if errors else "Complete" + html_path = OUTPUT / "index.html" + html_path.write_text(render_html(defined_rules, hits_by_test, errors), encoding="utf-8") + print( + f"{status}: {coverage(len(matched_files), len(rule_files))} rule files matched; " + f"{coverage(len(matched_rules), len(defined_rules))} rules matched; report: {html_path}" + ) + try: + opened = webbrowser.open(html_path.resolve().as_uri()) + except OSError, webbrowser.Error: + opened = False + if not opened: + print(f"Browser unavailable; open {html_path} manually") + return 1 if errors else 0 + + +if __name__ == "__main__": + sys.exit(run()) diff --git a/PythonScripts/audit_translations/rulecoverage/rule_coverage_report.py b/PythonScripts/audit_translations/rulecoverage/rule_coverage_report.py new file mode 100644 index 000000000..e266a9cee --- /dev/null +++ b/PythonScripts/audit_translations/rulecoverage/rule_coverage_report.py @@ -0,0 +1,66 @@ +"""Format file and rule coverage events as an interactive HTML report.""" + +from collections import Counter, defaultdict +from pathlib import Path + +from jinja2 import Environment, FileSystemLoader, select_autoescape + +type RuleKey = tuple[str, str, str] + +TEMPLATE = Environment( + loader=FileSystemLoader(Path(__file__).parent), + autoescape=select_autoescape(("html",)), +).get_template("rule_coverage.html") + + +def coverage(count: int, total: int) -> str: + """Show the matched fraction and its percentage, including empty groups.""" + return f"{count}/{total} ({100 * count / total:.0f}%)" if total else "0/0 (0%)" + + +def render_html( + defined_rules: set[RuleKey], + hits_by_test: dict[RuleKey, Counter[str]], + errors: list[str], +) -> str: + """Show file coverage and searchable rule details in a standalone page.""" + rule_files = {path for path, _, _ in defined_rules} + matched_files = {path for path, _, _ in hits_by_test} + rules_by_path: dict[str, list[dict]] = defaultdict(list) + for path, name, tag in defined_rules: + key = (path, name, tag) + tests = hits_by_test.get(key, {}) + total_hits = sum(tests.values()) + rules_by_path[path].append( + { + "name": name, + "tag": tag, + "matched": key in hits_by_test, + "hits": total_hits, + "tooltip": "Tests:\n" + + "\n".join(f"{test} ({count} {'hit' if count == 1 else 'hits'})" for test, count in sorted(tests.items())) + if total_hits + else "No test hits", + } + ) + + files = [] + for path in sorted(rule_files): + rules = sorted(rules_by_path.get(path, []), key=lambda rule: (rule["name"], rule["tag"])) + files.append( + { + "path": path, + "matched": path in matched_files, + "coverage": coverage(sum(rule["matched"] for rule in rules), len(rules)), + "rules": rules, + } + ) + + return TEMPLATE.render( + status="Incomplete" if errors else "Complete", + rule_file_count=len(rule_files), + file_coverage=coverage(len(matched_files), len(rule_files)), + rule_coverage=coverage(len(hits_by_test), len(defined_rules)), + errors=errors, + files=files, + ) diff --git a/PythonScripts/audit_translations/tests/test_rule_coverage_cli.py b/PythonScripts/audit_translations/tests/test_rule_coverage_cli.py new file mode 100644 index 000000000..33709d1e6 --- /dev/null +++ b/PythonScripts/audit_translations/tests/test_rule_coverage_cli.py @@ -0,0 +1,156 @@ +"""Checks the rule coverage command without rerunning the Rust test suite.""" + +import json +import subprocess +import sys +from pathlib import Path + +import pytest + +from .. import cli +from ..rulecoverage import rule_coverage + + +def test_coverage_command_generates_html_and_opens_browser(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: + """The CLI writes only the HTML report, removes an old Markdown report, and opens the page.""" + output = tmp_path / "target" / "rule-coverage" + output.mkdir(parents=True) + (output / "report.md").write_text("old report", encoding="utf-8") + monkeypatch.setattr(rule_coverage, "ROOT", tmp_path) + monkeypatch.setattr(rule_coverage, "OUTPUT", output) + monkeypatch.setattr(rule_coverage, "EVENTS", output / "events") + + def fake_cargo(command: list[str], **kwargs: object) -> subprocess.CompletedProcess[str]: + assert command == ["cargo", "test", "--features", "rule-coverage"] + assert kwargs["cwd"] == tmp_path + events = [ + {"kind": "defined-rule", "path": "Languages/en/SimpleSpeak_Rules.yaml", "name": "simple", "tag": "mi"}, + {"kind": "defined-rule", "path": "Languages/en/SimpleSpeak_Rules.yaml", "name": "default", "tag": "mi"}, + {"kind": "defined-rule", "path": "Languages/en/Z_Rules.yaml", "name": "unused", "tag": "mn"}, + { + "kind": "matched-rule", + "path": "Languages/en/SimpleSpeak_Rules.yaml", + "name": "simple", + "tag": "mi", + "test": "test_alpha", + }, + { + "kind": "matched-rule", + "path": "Languages/en/SimpleSpeak_Rules.yaml", + "name": "simple", + "tag": "mi", + "test": "test_alpha", + }, + { + "kind": "matched-rule", + "path": "Languages/en/SimpleSpeak_Rules.yaml", + "name": "simple", + "tag": "mi", + "test": "test_beta", + }, + ] + (output / "events" / "pid-123.jsonl").write_text( + "\n".join(json.dumps(event) for event in events) + "\n", + encoding="utf-8", + ) + return subprocess.CompletedProcess(command, 0) + + opened: list[str] = [] + monkeypatch.setattr(rule_coverage.subprocess, "run", fake_cargo) + monkeypatch.setattr(rule_coverage.webbrowser, "open", lambda url: opened.append(url) or True) + monkeypatch.setattr(sys, "argv", ["audit-translations", "--rule-coverage"]) + + with pytest.raises(SystemExit) as result: + cli.main() + + assert result.value.code == 0 + assert opened == [(output / "index.html").as_uri()] + assert not (output / "report.md").exists() + html = (output / "index.html").read_text(encoding="utf-8") + assert "Status: Complete" in html + assert "1/2 (50%) rule files matched" in html + assert "Languages/en/Z_Rules.yaml" in html + assert 'data-rule-search="simple mi" data-status="matched"' in html + assert 'data-rule-search="default mi" data-status="unmatched"' in html + assert "1/3 (33%) active rules matched" in html + assert "1/2 (50%) rules" in html + assert 'role="tooltip">Tests:\ntest_alpha (2 hits)\ntest_beta (1 hit)' in html + assert ".rules li:hover .rule-tooltip, .rules li:focus .rule-tooltip { display: block; }" in html + assert 'aria-describedby="rule-tooltip-0-1"' in html + assert "3 hits" in html + assert "0 hits" in html + assert "2 files with active rules" in html + assert (output / "test.log").is_file() + + +def test_failed_coverage_run_opens_incomplete_report(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: + """A failed test run remains unsuccessful but still produces and opens a useful report.""" + output = tmp_path / "target" / "rule-coverage" + monkeypatch.setattr(rule_coverage, "ROOT", tmp_path) + monkeypatch.setattr(rule_coverage, "OUTPUT", output) + monkeypatch.setattr(rule_coverage, "EVENTS", output / "events") + monkeypatch.setattr( + rule_coverage.subprocess, + "run", + lambda command, **kwargs: subprocess.CompletedProcess(command, 1), + ) + opened: list[str] = [] + monkeypatch.setattr(rule_coverage.webbrowser, "open", lambda url: opened.append(url) or True) + + assert rule_coverage.run() == 1 + assert opened == [(output / "index.html").as_uri()] + html = (output / "index.html").read_text(encoding="utf-8") + assert "Status: Incomplete" in html + assert "No active rule definitions found" in html + assert not (output / "report.md").exists() + + +def test_jsonl_rule_identity_preserves_separators_and_unicode(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: + """JSONL rule names survive tabs, newlines, and Unicode without splitting events.""" + events = tmp_path / "events" + events.mkdir() + monkeypatch.setattr(rule_coverage, "EVENTS", events) + name = "fraction\tname\nüber" + path = "Languages/en/SimpleSpeak_Rules.yaml" + (events / "pid-123.jsonl").write_text( + json.dumps({"kind": "defined-rule", "path": path, "name": name, "tag": "mfrac"}) + "\n", + encoding="utf-8", + ) + + defined, hits_by_test, errors = rule_coverage.read_events() + + assert hits_by_test == {} + assert defined == {(path, name, "mfrac")} + assert errors == [] + + +def test_invalid_and_unknown_rule_events_make_report_incomplete(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: + """Malformed events and hits without definitions must keep the report incomplete.""" + output = tmp_path / "target" / "rule-coverage" + monkeypatch.setattr(rule_coverage, "ROOT", tmp_path) + monkeypatch.setattr(rule_coverage, "OUTPUT", output) + monkeypatch.setattr(rule_coverage, "EVENTS", output / "events") + path = "Languages/en/SimpleSpeak_Rules.yaml" + + def fake_cargo(command: list[str], **kwargs: object) -> subprocess.CompletedProcess[str]: + events = [ + {"kind": "loaded", "path": path}, + {"kind": "defined-rule", "path": path, "name": "known", "tag": "mi"}, + {"kind": "matched-rule", "path": path, "name": "unknown", "tag": "mi", "test": "test_alpha"}, + ] + (output / "events" / "pid-123.jsonl").write_text( + "\n".join(json.dumps(event) for event in events) + "\n{bad json\n", + encoding="utf-8", + ) + return subprocess.CompletedProcess(command, 0) + + monkeypatch.setattr(rule_coverage.subprocess, "run", fake_cargo) + monkeypatch.setattr(rule_coverage.webbrowser, "open", lambda url: True) + + assert rule_coverage.run() == 1 + html = (output / "index.html").read_text(encoding="utf-8") + assert "Status: Incomplete" in html + assert "Invalid event in pid-123.jsonl:1" in html + assert "Invalid JSON in pid-123.jsonl:4" in html + assert "Matched rules lack definition events" in html + assert not (output / "report.md").exists() diff --git a/PythonScripts/pyproject.toml b/PythonScripts/pyproject.toml index 7b9adf68d..e1f579a31 100644 --- a/PythonScripts/pyproject.toml +++ b/PythonScripts/pyproject.toml @@ -14,6 +14,7 @@ dependencies = [ "deepl", "googletrans", "html-table-extractor", + "jinja2>=3.1.6", "jsonpath-ng>=1.8.0", "pyyaml", "rich", diff --git a/PythonScripts/uv.lock b/PythonScripts/uv.lock index 81e0404c4..d2323646c 100644 --- a/PythonScripts/uv.lock +++ b/PythonScripts/uv.lock @@ -200,6 +200,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + [[package]] name = "jsonpath-ng" version = "1.8.0" @@ -221,6 +233,36 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, ] +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +] + [[package]] name = "mdurl" version = "0.1.2" @@ -282,6 +324,7 @@ dependencies = [ { name = "deepl" }, { name = "googletrans" }, { name = "html-table-extractor" }, + { name = "jinja2" }, { name = "jsonpath-ng" }, { name = "pyyaml" }, { name = "rich" }, @@ -300,6 +343,7 @@ requires-dist = [ { name = "deepl" }, { name = "googletrans" }, { name = "html-table-extractor" }, + { name = "jinja2", specifier = ">=3.1.6" }, { name = "jsonpath-ng", specifier = ">=1.8.0" }, { name = "pyyaml" }, { name = "rich" }, diff --git a/src/lib.rs b/src/lib.rs index ac577a47f..97cf10d08 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,6 +38,8 @@ mod prefs; mod tts; mod xpath_functions; mod definitions; +#[cfg(feature = "rule-coverage")] +mod rule_coverage; pub mod pretty_print; mod chemistry; diff --git a/src/rule_coverage.rs b/src/rule_coverage.rs new file mode 100644 index 000000000..f0277d5ca --- /dev/null +++ b/src/rule_coverage.rs @@ -0,0 +1,58 @@ +//! Per-process YAML rule coverage events, enabled only by `rule-coverage`. + +use std::collections::HashSet; +use std::fs::{self, File, OpenOptions}; +use std::io::Write; +use std::path::{Path, PathBuf}; +use std::sync::{Mutex, OnceLock}; + +struct Recorder { + output: File, + recorded: HashSet<(PathBuf, String, String)>, +} + +static RECORDER: OnceLock> = OnceLock::new(); + +fn recorder() -> &'static Mutex { + RECORDER.get_or_init(|| { + let event_dir = Path::new(env!("CARGO_MANIFEST_DIR")) + .join("target/rule-coverage/events"); + fs::create_dir_all(&event_dir).expect("cannot create rule coverage event directory"); + let event_file = event_dir.join(format!("pid-{}.jsonl", std::process::id())); + let output = OpenOptions::new().create(true).append(true).open(event_file) + .expect("cannot open rule coverage event file"); + Mutex::new(Recorder { output, recorded: HashSet::new() }) + }) +} + +fn rule_relative_path(path: &Path) -> Option { + let rules_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("Rules"); + let relative = path.strip_prefix(&rules_dir) + .or_else(|_| path.strip_prefix("Rules")) + .ok()?; + if relative.as_os_str().is_empty() || !matches!(relative.extension().and_then(|s| s.to_str()), Some("yaml" | "yml")) { + return None; + } + Some(relative.to_path_buf()) +} + +pub(crate) fn defined_rule(path: &Path, name: &str, tag: &str) { + let Some(relative) = rule_relative_path(path) else { return }; + let mut recorder = recorder().lock().unwrap_or_else(|poisoned| poisoned.into_inner()); + if !recorder.recorded.insert((relative.clone(), name.to_string(), tag.to_string())) { + return; + } + let path = relative.to_string_lossy(); + let event = serde_json::json!({"kind": "defined-rule", "path": path, "name": name, "tag": tag}); + writeln!(recorder.output, "{event}").expect("cannot write rule coverage event"); +} + +pub(crate) fn matched_rule(path: &Path, name: &str, tag: &str) { + let Some(relative) = rule_relative_path(path) else { return }; + let mut recorder = recorder().lock().unwrap_or_else(|poisoned| poisoned.into_inner()); + let event = serde_json::json!({ + "kind": "matched-rule", "path": relative.to_string_lossy(), "name": name, "tag": tag, + "test": std::thread::current().name().unwrap_or("(unnamed thread)"), + }); + writeln!(recorder.output, "{event}").expect("cannot write rule coverage event"); +} diff --git a/src/speech.rs b/src/speech.rs index 4b6691bec..b667cb612 100644 --- a/src/speech.rs +++ b/src/speech.rs @@ -2291,6 +2291,14 @@ impl SpeechRules { if self.rules.is_empty() || !self.rule_files.is_file_up_to_date(&rule_file, should_ignore_file_time) { self.rules.clear(); let files_read = self.read_patterns(&rule_file)?; + #[cfg(feature = "rule-coverage")] + for patterns in self.rules.values() { + for pattern in patterns { + crate::rule_coverage::defined_rule( + Path::new(&pattern.file_name), &pattern.pattern_name, &pattern.tag_name + ); + } + } self.rule_files.set_files_and_times(files_read); } @@ -2511,6 +2519,10 @@ impl<'c, 's:'c, 'r, 'm:'c> SpeechRulesWithContext<'c, 's,'m> { } return match result { Ok(s) => { + #[cfg(feature = "rule-coverage")] + crate::rule_coverage::matched_rule( + Path::new(&pattern.file_name), &pattern.pattern_name, &pattern.tag_name + ); // for all except braille and navigation, nav_node_id will be an empty string and will not match if self.nav_node_id.is_empty() { Ok( Some(s) ) From 05e32aaa0ad3544097236c447da0ecc4476944c3 Mon Sep 17 00:00:00 2001 From: Danil <81031453+Kostenkov-2021@users.noreply.github.com> Date: Mon, 5 Oct 2026 16:28:48 +0300 Subject: [PATCH 157/157] Improve Russian math speech rules Adds Russian-specific speech handling for arrays, gathered derivations, function aliases, typographic quotes, and linear algebra constructs such as vector products, projections, and norms. It also introduces a RussianFunctionAliases definition table so common names like det, arctan, and Cauchy are spoken correctly in ClearSpeak and SimpleSpeak. --- Rules/Languages/ru/SharedRules/default.yaml | 45 ++++++++++++++++++ Rules/Languages/ru/SharedRules/general.yaml | 21 +++++++++ .../ru/SharedRules/linear-algebra.yaml | 47 +++++++++++++++++++ Rules/Languages/ru/definitions.yaml | 23 +++++++++ 4 files changed, 136 insertions(+) diff --git a/Rules/Languages/ru/SharedRules/default.yaml b/Rules/Languages/ru/SharedRules/default.yaml index 247eb84b8..558695376 100644 --- a/Rules/Languages/ru/SharedRules/default.yaml +++ b/Rules/Languages/ru/SharedRules/default.yaml @@ -1,5 +1,50 @@ --- #default rules shared among several speech rules +- name: russian-array-name + tag: array + match: "$SpeechStyle='ClearSpeak' or $SpeechStyle='SimpleSpeak'" + replace: + - T: "таблица" + - pause: short + - x: "*" + +# A repeated equality across a gathered line break marks one derivation. +# Priority is necessary because ClearSpeak's general table rule matches first. +- name: russian-gathered-derivation + tag: "!*" + match: "($SpeechStyle='ClearSpeak' or $SpeechStyle='SimpleSpeak') and (self::m:lines or self::m:system-of-equations) and contains(@class, 'gathered') and (*[1]//*[not(*)])[last()][.='='] and (*[2]//*[not(*)])[1][.='=']" + variables: + - LineCount: "count(*)" + - IsColumnSilent: "true()" + replace: + - x: "$LineCount" + - T: "строки" + - test: + if: "$SpeechStyle='ClearSpeak'" + then: [pause: short] + else: [pause: medium] + - x: "*" + +- name: russian-gathered-derivation-row + tag: "!*" + match: "($SpeechStyle='ClearSpeak' or $SpeechStyle='SimpleSpeak') and self::m:mtr and parent::*[contains(@class, 'gathered') and (*[1]//*[not(*)])[last()][.='='] and (*[2]//*[not(*)])[1][.='=']]" + replace: + - T: "строка" + - x: "count(preceding-sibling::*)+1" + - pause: medium + - x: "*" + - pause: medium + +- name: russian-gathered-repeated-equality + tag: mo + match: "($SpeechStyle='ClearSpeak' or $SpeechStyle='SimpleSpeak') and .='=' and not(following-sibling::*) and ancestor::m:mtr[following-sibling::*[1][(.//*[not(*)])[1][.='=']]] and ancestor::*[contains(@class, 'gathered')]" + replace: [] + +- name: russian-gathered-sentence-period + tag: mo + match: "($SpeechStyle='ClearSpeak' or $SpeechStyle='SimpleSpeak') and .='.' and not(following-sibling::*) and ancestor::m:mtr[not(following-sibling::*)] and ancestor::*[contains(@class, 'gathered')]" + replace: [] + - name: probability-given tag: math match: "count(*)=6 and *[1][.='P'] and *[2][.='('] and *[4][.='|'] and *[6][.=')']" diff --git a/Rules/Languages/ru/SharedRules/general.yaml b/Rules/Languages/ru/SharedRules/general.yaml index fba36a536..9c0bb02e7 100644 --- a/Rules/Languages/ru/SharedRules/general.yaml +++ b/Rules/Languages/ru/SharedRules/general.yaml @@ -1,4 +1,25 @@ --- +# Names confirmed in Russian mathematical notation. Do not rewrite MathML. +- name: russian-function-alias + tag: [mi, mtext] + match: "($SpeechStyle='ClearSpeak' or $SpeechStyle='SimpleSpeak') and DefinitionValue(normalize-space(.), 'Speech', 'RussianFunctionAliases') != '' and (contains(@class, 'qopname') or following-sibling::*[1][.='⁡' or IsBracketed(., '(', ')')] or (parent::m:apply-function and not(preceding-sibling::*)))" + replace: + - bookmark: "@id" + - x: "DefinitionValue(normalize-space(.), 'Speech', 'RussianFunctionAliases')" + +- name: russian-cauchy-name + tag: [mi, mtext] + match: "($SpeechStyle='ClearSpeak' or $SpeechStyle='SimpleSpeak') and normalize-space(.)='Cauchy'" + replace: + - bookmark: "@id" + - T: "Коши" + +- name: russian-typographic-quotation-mark + tag: [mi, mo] + match: "($SpeechStyle='ClearSpeak' or $SpeechStyle='SimpleSpeak') and (.='”' or .='“')" + replace: + - bookmark: "@id" + - T: "кавычка" - name: capital-letter-as-big tag: mi diff --git a/Rules/Languages/ru/SharedRules/linear-algebra.yaml b/Rules/Languages/ru/SharedRules/linear-algebra.yaml index 13345ccea..24be26c17 100644 --- a/Rules/Languages/ru/SharedRules/linear-algebra.yaml +++ b/Rules/Languages/ru/SharedRules/linear-algebra.yaml @@ -1,5 +1,52 @@ --- +# Intent inference creates childless operator nodes. The generic leaf fallback +# speaks their English XML names instead of using translated infix mappings. +- name: russian-vector-product-leaf + tag: [dot-product, cross-product] + match: "($SpeechStyle='ClearSpeak' or $SpeechStyle='SimpleSpeak') and count(*)=0" + replace: + - bookmark: "@id" + - x: "SpeakIntentName(name(.), $Verbosity, 'infix')" + +# Pr is also a probability notation: expand only with a vector direction index. +- name: russian-vector-projection-name + tag: mi + match: "($SpeechStyle='ClearSpeak' or $SpeechStyle='SimpleSpeak') and normalize-space(.)='Pr' and ancestor::*[self::m:indexed-by or self::m:sub or self::m:msub][*[2][self::m:vector or .//m:vector or .//m:mover[*[2]='→']]]" + replace: + - bookmark: "@id" + - T: "проекция" + +# TeX4ht can attach the index to the closing bar, rather than the whole norm. +- name: russian-closing-bar-norm + tag: mrow + match: "($SpeechStyle='ClearSpeak' or $SpeechStyle='SimpleSpeak') and count(*)=3 and *[1][self::m:mo and .='∥'] and *[3][self::m:indexed-by and *[1][self::m:mo and .='∥']]" + replace: + - T: "норма" + - test: + if: "*[2][self::m:mi and string-length(.)=1 and translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', '')='']" + then: + - T: "заглавной" + - x: "translate(*[2], 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" + else: [x: "*[2]"] + - T: "с индексом" + - test: + if: "*[3]/*[2]='∞'" + then: [T: "бесконечность"] + else: [x: "*[3]/*[2]"] + +- name: russian-doubled-closing-bar-norm + tag: "!*" + match: "($SpeechStyle='ClearSpeak' or $SpeechStyle='SimpleSpeak') and self::m:indexed-by and count(*)=2 and *[1][self::m:absolute-value and *[1][self::m:absolute-value]]" + replace: + - T: "норма" + - x: "*[1]/*[1]/*[1]" + - T: "с индексом" + - test: + if: "*[2]='∞'" + then: [T: "бесконечность"] + else: [x: "*[2]"] + - name: scalar-determinant tag: determinant match: "count(*)=1 and not(*[1][self::m:mtr])" diff --git a/Rules/Languages/ru/definitions.yaml b/Rules/Languages/ru/definitions.yaml index 73874fa6e..40c3d3f23 100644 --- a/Rules/Languages/ru/definitions.yaml +++ b/Rules/Languages/ru/definitions.yaml @@ -534,3 +534,26 @@ "", "тысячные", "миллионные", "миллиардные", "триллионные", "квадриллионные", "квинтиллионные", "секстиллионные", "септиллионные", "октиллионные", "нониллионные" ] + +# Operator spellings used in Russian mathematical texts. +- RussianFunctionAliases: { + "sh": "гиперболический синус", + "ch": "гиперболический косинус", + "th": "гиперболический тангенс", + "cth": "гиперболический котангенс", + "ctg": "котангенс", + "arctg": "арктангенс", + "arctan": "арктангенс", + "arcsin": "арксинус", + "arccos": "арккосинус", + "arccot": "арккотангенс", + "arcctg": "арккотангенс", + "det": "определитель", + "rang": "ранг", + "rank": "ранг", + "arg": "аргумент", + "Cov": "ковариация", + "Var": "дисперсия", + "Cauchy": "распределение Коши", + "maj": "мажоритарная функция", + }