diff --git a/.gitignore b/.gitignore index 43514cfa..939c367e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.idea target build.rs.orig Python/libmathcat.pyd diff --git a/README.md b/README.md index d9c3219a..a6d46af0 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,19 @@ -# MathCAT: Math Capable Assistive Technology +# MathCATde: German Translation for MathCAT: Math Capable Assistive Technology is a library that supports conversion of MathML to: * Speech strings (in several languages) with embedded speech engine commands -* Braille (Nemeth, UEB Technical, CMU, and many others) +* (later: Braille (Nemeth, UEB Technical, CMU, and many others)) * Navigation of math (in multiple ways including overviews) +This is the fork of [MathCAT](https://github.com/NSoiffer/MathCAT) of Neil Soiffer focussed on the translations to the German speaking contexts. -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). -- [A C/C++ interface for MathCAT](https://github.com/NSoiffer/MathCATForC) -- [A Java interface for MathCAT](https://github.com/mwhapples/MathCAT4J) (thanks to Michael Whapples for working on that) +## Status +This translation project was launched in the summer 2025 it is quite new still. -MathCAT is used in many assistive technologies including NVDA and JAWS. +## How to contribute? +This project is untertaken by the team of IT&Tech at the [IU University of Applied Sciences](https://www.iu.org/) and welcomes test-reports in the form of issues and proposed changes in the form of pull-requests. -For more information, see the [full documentation](https://nsoiffer.github.io/MathCAT/). +For process questions, raising an issue is probably the best idea too. \ No newline at end of file diff --git a/Rules/Languages/de/ClearSpeak_Rules.yaml b/Rules/Languages/de/ClearSpeak_Rules.yaml new file mode 100644 index 00000000..6a7b28be --- /dev/null +++ b/Rules/Languages/de/ClearSpeak_Rules.yaml @@ -0,0 +1,786 @@ +--- +- 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: "minus" + - x: "translate(text(), '-_', '')" + +- name: default + tag: square-root + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: {T: "die"} + - test: + if: $ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd' + then: + - bookmark: "*[1]/@id" + - test: + if: parent::*[self::m:minus and count(*)=1] + then: [{T: "minus"}] + else: [{T: "plus"}] + - T: "quadratwurzel" + - test: + if: "$Verbosity!='Terse'" + then: {T: "von"} + else: {pause: short} + - x: "*[1]" + - test: + - if: "$ClearSpeak_Roots = 'RootEnd' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" + then: + - pause: short + - T: "ende der wurzel" + - 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: "die"} + - 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: "negative"}] + else: [{T: "positive"}] + - test: + if: "*[2][self::m:mn]" + then_test: + - if: "*[2][.='2']" + then: {T: "quadratwurzel"} + - else_if: "*[2][.='3']" + then: {T: "kubikwurzel"} + - else_if: "*[2][not(contains(., '.'))]" + then: [{x: "ToOrdinal(*[2])"}, {T: "Wurzel"}] + else: + - test: + if: "*[2][self::m:mi][string-length(.)=1]" + then: + - x: "*[2]" + - pronounce: [{text: "-th"}, {ipa: "θ"}, {sapi5: "th"}, {eloquence: "T"}] + else: {x: "*[2]"} + - T: "wurzel" + - test: + if: "$Verbosity!='Terse'" + then: {T: "von"} + - x: "*[1]" + - test: + if: $ClearSpeak_Roots = 'RootEnd' or $ClearSpeak_Roots = 'PosNegSqRootEnd' + then: + - pause: short + - T: "ende der wurzel" + - 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: "negative"}] + else: [{T: "positive"}] + - 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: "pro" # 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(., '.')) 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: "der"}] + - T: "bruch" + - x: "*[1]" + - T: "durch" + - 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: "ende des bruchs" + - 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: "durch" + - x: "*[2]" + - test: + if: "$ClearSpeak_Fractions='EndFrac' or $ClearSpeak_Fractions='OverEndFrac'" + then: + - pause: short + - T: "ende des bruchs" + - pause: short + +- name: default + tag: fraction + match: "." + replace: + - OT: "der" + - T: "bruch mit zähler" + - test: + if: not(IsNode(*[1], 'simple')) + then: {pause: medium} + - x: "*[1]" + - pause: medium + - T: "und nenner" + - x: "*[2]" + - pause: long + - test: + if: "$ClearSpeak_Fractions='EndFrac' or $ClearSpeak_Fractions='GeneralEndFrac'" + then: + - pause: short + - T: "ende des bruchs" + - 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: "umgekehrte"}] + else_test: + if: $ClearSpeak_Trig = 'ArcTrig' + then: [{bookmark: "*[2]/@id"}, {T: "ark"}, {x: "*[1]"}] + else: [{bookmark: "*[2]/@id"}, {T: "umgekehrte"}, {x: "*[1]"}] # default/Auto + +- 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: "hoch zwei"] + else: [T: "quadrat"] + else: {T: "hoch 3"} + +- name: function-power + tag: power + match: + - "following-sibling::*[1][self::m:mo][.='⁡']" #invisible function apply + replace: + - test: + if: "$Verbosity!='Terse'" + then: {T: ""} + - bookmark: "*[2]/@id" + - test: + if: "*[2][self::m:mn][not(contains(., '.'))]" + then: [{x: "ToOrdinal(*[2])"}] + else: [{x: "*[2]"}] + - T: "hoch" + - 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: "zum exponent" + - pause: short + - x: "*[2]" + - pause: short + - T: "ende exponent" + +- name: AfterPower-default + tag: power + match: "$ClearSpeak_Exponents = 'AfterPower'" + replace: + - x: "*[1]" + - T: "zum exponent" + - 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: "quadrat" + +- name: cubed + tag: power + match: "*[2][self::m:mn][.='3'] and $ClearSpeak_Exponents = 'Auto'" + replace: + - x: "*[1]" + - bookmark: "*[2]/@id" + - T: "hoch 3" + +- name: simple-integer + tag: power + match: "*[2][self::m:mn][not(contains(., '.'))]" + replace: + - x: "*[1]" + - T: "hoch" + - test: + if: "*[2][.>0]" + then: {x: "ToOrdinal(*[2])"} + else: {x: "*[2]"} + - test: + if: "$ClearSpeak_Exponents != 'Ordinal'" + then: [{T: "hoch"}] + +- 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: "hoch" + - x: "*[2]" + - test: + if: "$ClearSpeak_Exponents != 'Ordinal'" + then: [{T: "hoch"}] + +- name: simple-var + tag: power + match: "*[2][self::m:mi][string-length(.)=1]" + replace: + - 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 +# 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: "zum exponent" + - 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: "hoch" + - 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: "hoch" + - 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: "hoch" + - 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: "zum Exponent" + - pause: short + - x: "*[2]" + - pause: short + - T: "Ende Exponent" + +- name: default + tag: power + match: "." + replace: + - x: "*[1]" + - T: "hoch" + - 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 + tag: absolute-value + match: "." + variables: [{WordToSay: "IfThenElse($ClearSpeak_AbsoluteValue = 'Kardinalität', 'Kardinalität', 'Betrag')"}] + replace: + - test: + if: "$Verbosity!='Terse'" + then: {T: "der"} + - x: "$WordToSay" + - T: "von" + - x: "*[1]" + - test: + if: "$ClearSpeak_AbsoluteValue = 'AbsEnd'" + then: + - pause: short + - T: "end" + - x: "$WordToSay" + - pause: short + +- name: set + tag: set + match: "." + replace: + - test: + - if: "count(*)=0" + then: [{T: "leere Menge"}] + - else_if: "count(*)=2" + then: + - test: + if: "$Verbosity!='Terse'" + then: {T: "die"} + - T: "leere Menge" + - else_if: "count(*[1]/*)=3 and *[1]/*[2][self::m:mo][.=':' or .='|' or .='∣']" + then: + - test: + if: "$Verbosity!='Terse'" + then: {T: "die"} + - T: "Menge" + - test: + if: $ClearSpeak_Sets != 'woAll' + then: [{T: "alle"}] + - x: "*[1]/*[1]" + - T: "so dass" + - x: "*[1]/*[3]" + else: + - test: + if: $ClearSpeak_Sets != 'SilentBracket' + then: + - test: + if: "$Verbosity!='Terse'" + then: {T: "die"} + - T: "Menge" + - 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: "das Intervall" + - x: "*[1]" + - T: "bis" + - x: "*[2]" + - pause: short + - test: + if: "not($is_intervals_start_infinity)" + 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) + 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" + - 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: + - T: "wähle" + - x: "*[1]/*[1]/*" # mtable/mtr/mtd + - T: "aus" + - x: "*[2]/*[1]/*" + +- name: ClearSpeak-default + tag: [mtr, mlabeledtr] + match: "parent::m:matrix or parent::m:determinant" + replace: + - pause: medium + - T: "zeile" + - x: "count(preceding-sibling::*)+1" + - test: + if: .[self::m:mlabeledtr] + then: + - T: "mit bezeichnung" + - 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: "spalte" + - 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: mrow + variables: [{log_is_simple: "IsNode(*[3],'simple')"}] + match: + - "count(*)=3 and" + - "*[1][self::m:mi][.='log' or .='ln'] and" + - "*[2][self::m:mo][.='⁡']" + replace: + - test: + if: "$log_is_simple" + then_test: + - if: "*[1][.='log']" + then: [{T: "log"}] + - else_if: $ClearSpeak_Log = 'LnAsNaturalLog' + then: [{T: "Natürliche Logarithmus"}] + else: [{spell: "'ln'"}] + else: + - test: + if: "$Verbosity!='Terse' and not(log_is_simple)" + then: {T: "der"} + - test: + - if: "*[1][.='log']" + then: [{T: "log"}] + - else_if: $ClearSpeak_Log = 'LnAsNaturalLog' + then: [{T: "Natürliche Logarithmus"}] + else: [{spell: "'ln'"}] + - T: "von" + - pause: short + - x: "*[3]" + +- name: ClearSpeak-multi-line + 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: "fall"] # 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: "zeile"] # phrase(this is the first 'line' of three lines) + - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" + then: [t: "bedingung"] # phrase(this is the first 'constraint' of three constraints) + - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" + then: [t: "gleichung"] # phrase(this is the first 'equation' of three equations) + - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" + then: [t: "reihe"] # phrase(this is the first 'row' of three rows) + - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" + then: [t: "stufe"] # phrase(this is the first 'step' of three steps) + # else 'None -- don't say anything' + - test: + - if: "$LineCount != 1" + then: [ct: "s"] # plural # phrase(shown by the letter 's') + - 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 + - test: + - if: "($ClearSpeak_MultiLineLabel = 'Auto' and parent::m:piecewise) or $ClearSpeak_MultiLineLabel = 'Case'" + then: [t: "fall"] # 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: "zeile"] # phrase(the straight 'line' between x and y) + - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" + then: [t: "bedingung"] # phrase(there is a 'constraint' on possible values) + - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" + then: [t: "gleichung"] # phrase(the 'equation' pi r squared gives the area of a circle) + - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" + then: [t: "reihe"] # phrase(the values on the top 'row' are relevant) + - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" + then: [t: "stufe"] # 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: + if: "self::m:mlabeledtr" + then: + - t: "with label" # 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: "mal"}] + +- 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 (" + - " $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: + - T: "mal" + +- 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') )" + # 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/de/SharedRules/calculus.yaml b/Rules/Languages/de/SharedRules/calculus.yaml new file mode 100644 index 00000000..0a86ce5e --- /dev/null +++ b/Rules/Languages/de/SharedRules/calculus.yaml @@ -0,0 +1,38 @@ +--- + +- name: divergence + tag: divergence + match: "." + replace: + - test: + if: "$Verbosity='Verbose'" + then: [t: "divergenz"] # phrase('divergence' from the mean) + else: [t: "div"] # phrase('divergence' from the mean) + - t: "von" # phrase(systems 'of' linear equations) + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [pause: short] + - x: "*[1]" + +- name: curl + tag: curl + match: "." + replace: + - t: "rotation von" # phrase(the 'curl of' a field) + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [pause: short] + - x: "*[1]" + +- name: gradient + tag: gradient + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [t: "gradient von"] # phrase('divergence' from the mean) + else: [t: "grad"] # phrase('divergence' from the mean) + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [pause: short] + - x: "*[1]" diff --git a/Rules/Languages/de/SharedRules/default.yaml b/Rules/Languages/de/SharedRules/default.yaml new file mode 100644 index 00000000..7dd92d02 --- /dev/null +++ b/Rules/Languages/de/SharedRules/default.yaml @@ -0,0 +1,716 @@ +--- +#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)" + + - MatchingPause: false() + # 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" + - 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()"] + - else_if: "@data-chem-element" # NavMode=Character needs this + then: [spell: "text()", pause: "short"] + else: [x: "translate(., '-_\u00A0', ' ')"] # from intent literals or from extra spaces added (which get deleted) + +- name: default + tag: ms + match: "." + replace: + - T: "die Zeichenfolge" # phrase('the string' is long) + - 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: "durch" # phrase("the fraction x 'over' y") + - x: "*[2]" + - pause: short + +- name: literal-default + tag: mfrac + match: "." + replace: + - T: "beginn" # phrase("'start' fraction x over y end of fraction") + - pause: short + - x: "*[1]" + - test: + if: "not(IsNode(*[1],'leaf'))" + then: [pause: short] + - T: "durch" # phrase("the fraction x 'over' y") + - test: + if: "not(IsNode(*[2],'leaf'))" + then: [pause: short] + - x: "*[2]" + - pause: short + - test: + if: "$Impairment = 'Blindness'" + then: [T: "ende des bruchs"] # phrase("start of fraction x over y 'end over'") + - pause: medium + + +# not sure what really should be said for these since we should not assume they are square roots +- name: literal-default + tag: msqrt + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # phrase("'the' root of x") + - T: "wurzel" + - test: + if: "$Verbosity!='Terse'" + then: [T: "aus"] # phrase("the root 'of' x") + - x: "*[1]" + - pause: short + - test: + if: "not(IsNode(*[1],'leaf')) or $Impairment = 'Blindness'" + then: [T: "ende der wurzel"] # phrase("root of x 'end root symbol'") + +# not sure what really should be said for these since we should not assume they are square roots +- name: literal-default + tag: mroot + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # phrase("'the' root of x") + - T: "wurzel mit index " # phrase("the 'root with index' 3 of 5") + - x: "*[1]" + - pause: short + - T: "von" # phrase("the root 'of' x") + - x: "*[2]" + - pause: short + - test: + if: "not(IsNode(*[2],'leaf'))" + then: [T: "ende der wurzel"] # phrase("root of x 'end root symbol'") + + +- 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 + match: "count(*)=2 and *[2][self::m:mrow and *[2][.='⁣']]" + replace: + - x: "*[1]" + - T: "Index" # phrase(x 'sub' 2) + - x: "*[2]" + - pause: short + +# otherwise let definitions/default infix handle it + +- name: literal + tag: msub + match: "." + replace: + - x: "*[1]" + - test: + if: "not($Verbosity='Terse' and *[2][self::m:mn and not(translate(., '.,', '')!=.)])" # just say "x 1" for terse vs "x sub 1" + then: [T: "index"] # phrase(x 'sub' 2) + - x: "*[2]" + + +- name: literal + tag: [msup, msubsup] + match: "." + replace: + - x: "*[1]" + - test: + if: "name(.)='msubsup'" + then: + - T: "index" # phrase(x 'sub' 2) + - 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: "hoch" # phrase(x 'super' 2) + - x: "*[last()]" + - test: + if: "not(IsNode(*[last()], 'simple')) or $Impairment = 'Blindness'" + then: [T: "ende der hochstellung"] # phrase(x super 2 'end of super') + else: + - test: + if: "$Verbosity='Verbose'" + then: [T: "hochstellung"] + else: [T: "hochstellung"] + - x: "*[last()]" + - test: + if: "$Verbosity='Verbose'" + then: [T: "ende der hochstellung"] + else: [T: "ende der hochstellung"] + +- name: default + tag: munder + match: "." + replace: + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [T: "größe"] # phrase(phrase(x 'quantity' with y above it) + - x: "*[1]" + - T: "mit" # phrase(x 'with' z below it) + - x: "*[2]" + - T: "darunter" # phrase(x with z 'below' it) + +- name: diacriticals + tag: mover + match: "*[1][self::m:mi] and *[2][translate(., '\u0306\u030c.\u00A8\u02D9\u20DB\u20DC`^ˇ~→¯_', '')='']" + replace: + - x: "*[1]" + - x: "*[2]" + +- name: default + tag: mover + match: "." + replace: + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [T: "größe"] # phrase(phrase(the 'quantity' x plus 1 with y above it) + - x: "*[1]" + - T: "mit" # phrase(x modified 'with' y above it) + - x: "*[2]" + - T: "darüber" # phrase(x modified with y 'above' it) + +- name: default + tag: munderover + match: "." + replace: + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [T: "größe"] # phrase(the 'quantity' x plus 1 with y above it) + - x: "*[1]" + - T: "mit" # phrase(x modified 'with' y above it) + - x: "*[2]" + - T: "darunter und" # phrase(x modified with y 'below and' y above it) + - x: "*[3]" + - T: "darüber" # 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 + # 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', 'pre subscript', 'pre sub')" + - PreSuperscript: "IfThenElse($Verbosity='Verbose', 'pre superscript', 'pre super')" + replace: + - test: # only bother announcing if there is more than one prescript + if: "count($Prescripts) > 2" + then: + - T: "durch" # phrase(substitute x 'with' y) + - x: "count($Prescripts) div 2" + - T: "präskripte" # phrase(in this equation certain 'prescripts' apply) + - 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: "und"] # phrase(10 is greater than 8 'and' less than 15) + - 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: "und"] # phrase(10 is grater than 8 'and' less than 15) + - 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: "und abwechselnde präskripte" # phrase(in this case there are values 'and alternating prescripts') + - x: "$Prescripts[position() > 4]" + - T: "ende der präskripte" # phrase(This is where 'end prescripts' occurs) + - test: + if: "$Postscripts" + then: + - with: + variables: + - PostSubscript: "IfThenElse($Verbosity='Verbose', 'subscript', 'sub')" + - PostSuperscript: "IfThenElse($Verbosity='Verbose', 'superscript', 'super')" + replace: + - test: # only bother announcing if there is more than one postscript + if: "count($Postscripts) > 2" + then: + - test: + if: "$Prescripts" + then: [T: "und"] # phrase(10 is greater than 8 'and' less than 15) + - T: "durch" # phrase(substitute x 'with' y) + - x: "count($Postscripts) div 2" + - T: "postskripte" # phrase(this material includes several 'postscripts') + - 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: "und"] # phrase(10 is greater than 8 'and' less than 15) + - 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: "und"] # phrase(10 is greater than 8 'and' less than 15) + - 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: "und"] # phrase(10 is greater than 8 'and' less than 15) + - 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: "und"] # phrase(10 is less than 15 'and' greater than 5) + - 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: "und wechselnde skripte" # phrase(this situation involves complexities 'and alternating scripts') + - x: "$Postscripts[position() > 8]" + - T: "ende der skripte" # phrase(At this point 'end scripts' occurs) + +- name: default + tag: mtable + variables: + - IsColumnSilent: "false()" + - NumColumns: "count(*[1]/*) - IfThenElse(*/self::m:mlabeledtr, 1, 0)" + match: "." + replace: + - T: "tabelle mit" # phrase(the 'table with' 3 rows) + - x: count(*) + - test: + if: count(*)=1 + then: [T: "zeile"] # phrase(the table with 1 'row') + else: [T: "zeilen"] # phrase(the table with 3 'rows') + - T: "und" # phrase(the table with 3 rows 'and' 4 columns) + - x: "$NumColumns" + - test: + if: "NumColumns=1" + then: [T: "spalte"] # phrase(the table with 3 rows and 1 'column') + else: [T: "spalten"] # phrase(the table with 3 rows and 4 'columns') + - pause: long + - x: "*" + +- name: default + # callers/context should do that. + # this may get called from navigation -- in that case, there is no context to speak the row #, so don't do it + tag: [mtr, mlabeledtr] + match: "." + replace: + - pause: medium + - T: "zeile" # phrase(the first 'row' of a matrix) + - x: "count(preceding-sibling::*)+1" + - test: + if: "self::m:mlabeledtr" + then: + - T: "mit der bezeichnung" # phrase(the line 'with label' first equation) + - x: "*[1]/*" + - pause: short + - pause: medium + - test: + if: "self::m:mlabeledtr" + then: [x: "*[position()>1]"] + else: {x: "*"} + +- name: default + tag: mtd + match: "." + 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: "spalte" # phrase(the first 'column' of the matrix) + - 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: count(following-sibling::*) > 0 + then: [pause: short] + - else_if: count(../following-sibling::*) > 0 + then: [pause: medium] + 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 + tag: menclose + match: "@notation='box' and *[self::m:mtext and .=' ']" + replace: + - T: "leere box" # 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 + # Note: @notation can contain more than one value + tag: menclose + match: "." + replace: + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' box ')]" + then: [T: "box", pause: short] # phrase(the 'box' around the expression) + - test: + if: ".[contains(@notation,'roundedbox')]" + then: [T: "runde box", pause: short] # phrase(the 'round box' around the expression) + - test: + if: ".[contains(@notation,'circle')]" + then: [T: "kreis", 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: "linie" # phrase(draw a straight 'line' on the page) + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' left ')]" + then: [T: "links", pause: short] # phrase(line on 'left' of the expression) + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' right ')]" + then: [T: "rechts", pause: short] # phrase(line on 'right' of the expression) + - test: + if: ".[contains(@notation,'top')]" + then: [T: "oben", pause: short] # phrase(line on 'top' of the expression) + - test: + if: ".[contains(@notation,'bottom')]" + then: [T: "unten", 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: + - 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 nach oben", pause: short] # phrase(the line runs 'up diagonal') + - test: + if: ".[contains(@notation,'downdiagonalstrike')]" + then: [T: "diagonal nach unten", pause: short] # phrase(the line runs 'down diagonal') + - test: + if: ".[contains(@notation,'verticalstrike')]" + then: [T: "vertikal", pause: short] # phrase(the line is 'vertical') + - test: + if: ".[contains(@notation,'horizontalstrike')]" + then: [T: "horizontal", pause: short] # phrase(the line is 'horizontal') + - T: "durchstreichen" # phrase(please 'cross out' the incorrect answer) + - pause: short + - test: + if: ".[contains(@notation,'uparrow')]" + then: [T: "pfeil nach oben", pause: short] # phrase(direction is shown by the 'up arrow') + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' downarrow ')]" + then: [T: "pfeil nach unten", pause: short] # phrase(the trend is shown by the 'down arrow') + - test: + if: ".[contains(@notation,'leftarrow')]" + then: [T: "pfeil nach links", pause: short] # phrase(the 'left arrow' indicates going back) + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' rightarrow ')]" + then: [T: "pfeil nach rechts", pause: short] # phrase(the 'right arrow' indicates moving forward) + - test: + if: ".[contains(@notation,'northeastarrow')]" + then: [T: "pfeil nach nordost", pause: short] # phrase(direction is indicated by the 'northeast arrow') + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' southeastarrow ')]" + then: [T: "pfeil nach südost", pause: short] # phrase(direction is shown by the 'southeast arrow') + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' southwestarrow ')]" + then: [T: "pfeil nach südwest", pause: short] # phrase(direction is shown by the 'southwest arrow') + - test: + if: ".[contains(@notation,'northwestarrow')]" + then: [T: "pfeil nach nordwest", pause: short] # phrase(direction is shown by the 'northwest arrow') + - test: + if: ".[contains(@notation,'updownarrow')]" + then: [T: "doppelpfeil nach oben und unten", pause: short] # phrase(upward movement is indicated by the 'double ended vertical arrow') + - test: + if: ".[contains(@notation,'leftrightarrow')]" + then: [T: "doppelpfeil nach links und rechts", pause: short] # phrase(progress is indicated by the 'double ended horizontal arrow') + - test: + if: ".[contains(@notation,'northeastsouthwestarrow')]" + then: [T: "doppelpfeil diagonal nach oben", pause: short] # phrase(trend is indicated by the 'double ended up diagonal arrow') + - test: + if: ".[contains(@notation,'northwestsoutheastarrow')]" + then: [T: "doppelpfeil diagonal nach unten", pause: short] # phrase(trend is indicated by the 'double ended down diagonal arrow') + - test: + if: ".[contains(@notation,'actuarial')]" + then: [T: "versicherungsmathematische symbol", pause: short] # phrase(the 'actuarial symbol' represents a specific quantity) + - test: + if: ".[contains(@notation,'madrub')]" + then: [T: "arabisches faktor-symbol", pause: short] # phrase(the 'arabic factorial symbol' represents a factorial operation) + - test: + if: ".[contains(@notation,'phasorangle')]" + then: [T: "phasenwinkel", 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: "symbol für schriftliche division", pause: short] # phrase(the 'long division symbol' indicates a long division calculation) + - test: + if: ".[contains(@notation,'radical')]" + then: [T: "quadratwurzel", pause: short] # phrase(5 is the 'square root' of 25) + - T: "einschließen" # phrase(parentheses are 'enclosing' part of the equation) + - test: + if: "*[self::m:mtext and .=' ']" + then: [T: "leerzeichen"] # 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: "ende der einschliessung"] # phrase(reached the 'end enclosure' point) + - 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: "angewandt auf" # phrase(the function sine 'applied to' x plus y) + - x: "*[2]" + + +# Here are the intent hints that need to be handled: 'prefix' | 'infix' | 'postfix' | 'function' | 'silent' +- 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:')" + replace: + - x: "*" + - test: + if: "IsNode(., '2D')" + then: [pause: short] + else: [pause: auto] + +- 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: "$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: "von", pause: auto] # phrase(sine 'of' 5) + - insert: + nodes: "*" + replace: + - test: + if: "not(contains(@data-intent-property, ':literal:'))" + then: [x: "','"] + - 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')] )" + 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/de/SharedRules/general.yaml b/Rules/Languages/de/SharedRules/general.yaml new file mode 100644 index 00000000..27b95dda --- /dev/null +++ b/Rules/Languages/de/SharedRules/general.yaml @@ -0,0 +1,1056 @@ +--- + +# 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: "die" # phrase('the' square root of 25 equals 5) + - bookmark: "*[2]/@id" + - test: + - if: "*[2][.='+']" + then: [T: "positiven"] # phrase(set of all 'positive' integers less than 10) + else: [T: "negativen"] # phrase(set of all 'negative' integers less than minus 10) + - bookmark: "*[1]/@id" + - test: + - if: "*[1][.='ℂ']" + then: [T: "komplexe zahlen"] # phrase('complex numbers' consist of two parts) + - else_if: "*[1][.='ℕ']" + then: [T: "natürliche zahlen"] # phrase('natural numbers' are numbers from 1 to infinity) + - else_if: "*[1][.='ℚ']" + then: [T: "rationale zahlen"] # phrase('rational numbers' are the fraction of 2 integers) + - else_if: "*[1][.='ℝ']" + then: [T: "reelle zahlen"] # phrase('real numbers' can be both positive and negative) + - else_if: "*[1][.='ℤ']" + then: [T: "ganze zahlen"] # phrase(positive 'integers' are natural numbers above 0) + 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"] # phrase(the letter 'C' used to represent complex number) + - else_if: "*[1][.='ℕ']" + then: [T: "n"] # phrase(the letter 'N' may represent natural numbers) + - else_if: "*[1][.='ℚ']" + then: [T: "q"] # phrase(the letter 'Q' may represent rational numbers) + - else_if: "*[1][.='ℝ']" + then: [T: "r"] # phrase(the letter 'R' may represent real numbers) + - else_if: "*[1][.='ℤ']" + then: [T: "z"] # phrase(the letter 'Z' may represent integers) + 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: "die komplexen zahlen"] # phrase('the complex numbers' include 2 parts) + - else_if: ".='ℕ'" + then: [T: "die natürlichen zahlen"] # phrase('the natural numbers' begin at 1) + - else_if: ".='ℚ'" + then: [T: "die rationalen zahlen"] # phrase('the rational numbers' are the fraction of 2 integers) + - else_if: ".='ℝ'" + then: [T: "die reellen zahlen"] # phrase('the real numbers' can be both positive and negative) + - else_if: ".='ℤ'" + then: [T: "die ganzen zahlen"] # phrase('the integers' are natural numbers above 0) + else: [x: "text()"] # shouldn't happen + +- name: real-part + tag: real-part + match: "." + replace: + - bookmark: "@id" + - T: "realteil" # 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: "imaginärteil" # phrase('the imaginary part' is part of a complex number) + +# rules on scripted vertical bars ('evaluated at') +- name: evaluated-at-2 + tag: evaluate + match: "count(*)=2" + replace: + - x: "*[1]" + - pause: auto + - T: "ausgewertet bei" # phrase(results were 'evaluated at' a given point) + - pause: auto + - x: "*[2]" + +- name: evaluated-at-3 + tag: evaluate + match: "count(*)=3" + replace: + - x: "*[1]" + - pause: auto + - T: "ausgewertet zwischen" # phrase(results were 'evaluated at' this point) + - pause: auto + - x: "*[3]" + - T: "und" # phrase(this result is 'minus the same expression evaluated at' an earlier point) + - x: "*[2]" + +- name: permutation + # Not a default because the order of the args is reversed + tag: pochhammer + match: "count(*)=2 and contains(@data-intent-property, ':infix:')" + replace: + - x: "*[2]" + - T: "permutationen von" # phrase(the solution involves several 'permutations of' values) + - 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: "die" # phrase('the' square root of 25 equals 5) + - x: "translate(name(.),'-', ' ')" + - test: + if: "$Verbosity!='Terse'" + then: + - T: "von" # phrase(subtracting 5 'from' 10 gives 5) + - x: "*[1]" + - T: "bis" # phrase(adding 6 'to' 6 equals 12) + - x: "*[2]" + else: + - x: "*[1]" + - T: "komma" # phrase(use a 'comma' to divide large numbers or as a decimal point) + - x: "*[2]" + +- name: default-point + tag: point + match: "count(*)=2" + replace: + - test: + if: "$Verbosity!='Terse'" + then: + - T: "die" # phrase('the' square root of 25 equals 5) + - T: "punkt" # phrase(a decimal 'point' indicates the fraction component of a number) + - x: "*[1]" + - T: "komma" # phrase(use a 'comma' to divide large numbers or as a decimal point) + - x: "*[2]" + +- name: bigop-both + tag: large-op + match: "count(*) = 3" + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # phrase('the' square root of 25 equals 5) + - x: "*[1]" + - T: "von" # phrase(subtracting 5 'from' 10 gives 5) + - x: "*[2]" + - T: "bis" # phrase(adding 6 'to' 6 equals 12) + - x: "*[3]" + - test: + if: "following-sibling::*" + then: [T: "von"] # phrase(the square root 'of' 25 equals 5) + +- name: bigop-under + tag: large-op + match: "count(*)=2" + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # phrase('the' square root of 25 equals 5) + - x: "*[1]" + - T: "durch" # phrase(2 'over' 3 equals two thirds) + - x: "*[2]" + - test: + if: "following-sibling::*" + then: [T: "von"] # phrase(the square root 'of' 25 equals 5) + +- name: largeop + tag: mrow + match: "count(*)=2 and IsInDefinition(*[1], 'LargeOperators')" + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # phrase('the' square root of 25 equals 5) + - x: "*[1]" + - T: "von" # phrase(the square root 'of' 25 equals 5) + - x: "*[2]" + +- name: repeating-decimal + tag: repeating-decimal + match: "." + replace: + - x: "*[1]" + - T: "mit wiederholten ziffern" # phrase('with repeating digits') + - spell: "*[2]" + +- name: msubsup-skip-super + # handles single, double, etc., prime + tag: [skip-super, say-super] + match: "count(*)=3" + replace: + - x: "*[1]" + - test: + if: "$Verbosity='Verbose'" + then: [T: "index"] # phrase(a 'subscript' may be used to indicate an index) + else: [T: "sub"] # phrase(the result is 'sub' optimal) + - x: "*[2]" + - test: + if: "not(IsNode(*[2],'leaf') and $Impairment = 'Blindness')" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "ende -index"] # phrase(this is the 'end subscript' position) + else: [T: "ende -sub"] # phrase(this is the 'end sub' position) + - 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: "superscript"] # phrase(a 'superscript' number indicates raised to a power) + else: [T: "super"] # phrase(this is a 'super' set of numbers) + - 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" +- name: unit + tag: unit + match: "$Verbosity != 'Terse' and contains(@data-intent-property, ':unit')" + 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 power/mrow) + # But it might be in a fraction as (C) "3 m/s" (parent is fraction/mrow) or (D) "3 m^2/s^2" (parent is power/fraction/mrow) + # or even (E) {3 m^2}/s (parent is power/mrow) + # If in a fraction, only look in the numerator to find the coefficient + # Note: we have a special case for pseudo-scripts like "°" (degrees) which are not powers -- they are essentially "1^°" + # The following "IfThenElse" logic returns the mrow that potentially contains the coefficient, if it exists + # The tests are in the order A, B & E, C, D + - 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(DEBUG($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()" + + # 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 concatenated to the base + then: [x: "$Word"] + - else_if: "DefinitionValue($Word, 'Speech', 'PluralForms') != ''" + then: [x: "DefinitionValue($Word, 'Speech', 'PluralForms')"] + else: [x: "$Word", ct: "s"] + else: + - x: "$Prefix" + - ct: "-" + - test: + - 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') != ''" + then: [x: "concat('\uF8FE', DefinitionValue($Word, 'Speech', 'PluralForms'))"] + else: [x: "concat('\uF8FE', $Word)", ct: "s"] + + +- name: sin + tag: mi + match: ".='sin'" + replace: + - bookmark: "@id" + - T: "sinus" # phrase(the 'sine' of the angle) +- name: cos + tag: mi + match: ".='cos'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: "cos"] # phrase('cos' is the abbreviation for cosine) + else: [T: "kosinus"] # phrase(find the 'cosine' in a right-angle triangle) +- name: tan + tag: mi + match: ".='tan' or .='tg'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: "tan"] # 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 + match: ".='sec'" + replace: + - 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) +- name: csc + tag: mi + match: ".='csc'" + replace: + - 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) +- name: cot + tag: mi + match: ".='cot'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: "kotangens"] # phrase(find the 'cotangent' in a right-angle triangle) + else: [T: "kotangens"] # phrase(the 'cotangent' is the reciprocal of the tangent) + +- name: sinh + tag: mi + match: ".='sinh'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: "sinch"] # phrase(the word 'sinch' is an abbreviation for hyperbolic sine) + else: [T: "hyperbolischer sinus"] # phrase(the 'hyperbolic sine' is used in mathematics) +- name: cosh + tag: mi + match: ".='cosh'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: "cosh"] # phrase('cosh' is an abbreviation of hyperbolic cosine) + else: [T: "hyperbolischer cosinus"] # phrase(the 'hyperbolic cosine' is a mathematical function) +- name: tanh + tag: mi + match: ".='tanh'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: "tanch"] # phrase('tanch' is shorthand for hyperbolic tangent) + else: [T: "hyperbolischer tangens"] # phrase('hyperbolic tangent' is a mathematical function) +- name: sech + tag: mi + match: ".='sech'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: "sheck"] # phrase('sheck' is shorthand for hyperbolic secant) + else: [T: "hyperbolischer sekans"] # phrase('hyperbolic secant' is a mathematical function) +- name: csch + tag: mi + match: ".='csch'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: "cosheck"] # phrase('cosheck' is shorthand for hyperbolic cosecant) + else: [T: "hyperbolischer kosekans"] # phrase('hyperbolic cosecant' is a mathematical function) +- name: coth + tag: mi + match: ".='coth'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: "cotanch"] # phrase('cotanch' is shorthand for hyperbolic cotangent) + else: [T: "hyperbolischer kotangens"] # phrase(the 'hyperbolic cotangent' is a mathematical function) +- name: exponential + tag: mi + match: ".='exp'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: "exp"] # phrase('exp' means exponential function) + else: [T: "exponent"] # phrase('exponential' function) +- name: covariance + tag: mi + match: ".='Cov'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: "cov"] # phrase('Cov' is shorthand for the covariance function) + else: [T: "kovarianz"] # phrase('covariance' function) + +- + name: log # handle both log and ln (if in an mrow, 'intents' are used) + tag: mi + match: ".='log' or .='ln'" + replace: + - bookmark: "@id" + - test: + - if: "$Verbosity!='Terse'" + then: [T: "der"] # phrase('the' logarithm function is used in mathematics) + + - test: + - if: ".= 'log'" + then: [T: "log"] # phrase(the 'log' function is used in mathematics) + - else_if: "$Verbosity='Terse'" + then: [spell: "'ln'"] + else: [T: "natürliche logarithmus"] # phrase(the 'natural log' function is used in mathematics) + + +- name: multi-line + # 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: + # 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: + - x: "$LineCount" + - test: + - if: "self::m:piecewise" + then: [T: "fall"] # phrase(this is the first 'case' of three cases) + - else_if: "self::m:system-of-equations" + then: [T: "gleichung"] # phrase(this is the first 'equation' of three equations) + else: [T: "zeile"] # phrase(this is the first 'line' of three lines) + - test: + - if: "$LineCount != 1" + then: [ct: "s"] # plural + - pause: short + - x: "*" + - pause: long + + +- name: 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 contains(@data-intent-property, ':continued-row:'))" + then: + - pause: medium + - test: + - if: "parent::m:piecewise" + then: [T: "fall"] # phrase('case' 1 of 10 cases) + - else_if: "parent::m:system-of-equations" + then: [T: "gleichung"] # phrase('equation' 1 of 10 equations) + else: [T: "zeile"] # phrase('line 1 of 10 lines) + - x: "count(preceding-sibling::*[not(contains(@data-intent-property, ':continued-row:'))]) + 1" + - test: + if: "self::m:mlabeledtr" + then: + - T: "mit der bezeichnung" # phrase(the diagram is complete 'with label') + - x: "*[1]/*" + - test: + if: "not(contains(@data-intent-property, ':continued-row:'))" + then: [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: + - test: + if: "IsInDefinition(*[1], 'ComparisonOperators')" + then: [pause: short] + - test: + if: "*[1][@data-added!='missing-content']" + then: [x: "*"] + - test: + # no 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 and not($NextLineIsContinuedRow)" + then_test: + if: "count(../following-sibling::*) > 0" + then_test: + if: "$LongPause" + then: [pause: long] + else: [pause: medium] + else_test: + if: "IsInDefinition(*[1], 'ComparisonOperators')" + then: [pause: short] + else: [pause: auto] + +# 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 +- name: 1x1-matrix + tag: [matrix, determinant] + variables: [IsColumnSilent: true()] + match: "count(*)=1 and *[self::m:mtr][count(*) = 1]" + replace: + - ot: "die" # phrase('the' 1 by 1 matrix M) + - T: "1 mal 1" # 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: "determinante"] # phrase(the 2 by 2 'determinant')) + else: [T: "matrix"] # phrase(the 2 by 2 'matrix') + + - T: "mit eintrag" # phrase(the 2 by 2 matrix 'with entry' x) + - x: "*[1]/*" + +# simpler reading methods for special case matrices +- name: zero-matrix + tag: matrix + # select all the non-zero entries -- if there are none of them, then it is a zero matrix + match: "not( */*/*[not(self::m:mn and .= 0)] )" + replace: + - T: "die" # phrase('the' 1 by 2 matrix M) + - x: count(*) + - T: "mal" # phrase(the 1 'by' 2 matrix) + - x: count(*[self::m:mtr][1]/*) + - T: "nullmatrix" # phrase(the 2 by 2 'zero matrix') + - pause: long + +- name: identity-matrix + tag: matrix + # select all the non-zero entries...if they are not on the diagonal, or are != 1 + # if there are any of them, then this isn't an identity matrix + match: + - "count(*) = count(*[1]/*) and " + - "not( */*/*[not(self::m:mn and .= 0)]" + - " [count(../preceding-sibling::*)!=count(../../preceding-sibling::*) or .!= 1]" + - " )" + replace: + - T: "die" # phrase('the' 1 by 2 matrix M) + - x: count(*) + - T: "mal" # phrase(the 1 'by' 2 matrix) + - x: count(*[self::m:mtr][1]/*) + - T: "identitätsmatrix" # phrase(the 2 by 2 'identity matrix') + - pause: long + +- name: diagonal-matrix + tag: matrix + # select all the non-zero entries...if they are not on the diagonal + # if there are any of them, then this isn't an identity matrix + match: + - "count(*) = count(*[1]/*) and " + - "not( */*/*[not(self::m:mn and .= 0)]" + - " [count(../preceding-sibling::*)!=count(../../preceding-sibling::*)]" + - " )" + replace: + - T: "die" # phrase('the' 1 by 2 matrix) + - x: count(*) + - T: "mal" # phrase(the 1 'by' 2 matrix) + - x: count(*[self::m:mtr][1]/*) + - T: "diagonalmatrix" # 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 + # there seems to be an xpath bug -- without the parens, the match fails for the + # test Languages::en::mtable::diagonal_matrix due to match failure (the third matching element seems to be missing) + 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: + - T: "die" # phrase('the' 2 by 2 matrix M) + - x: count(*) + - T: "mal 1 spalte" # phrase(the 2 'by 1 column' matrix) + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "vektor"] # phrase(the 2 by 2 'vector') + else: [T: "matrix"] # phrase(the 2 by 2 'matrix') + - pause: long + - x: "*/*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: "ende" # phrase('end' of matrix) + - test: + if: $ClearSpeak_Matrix = 'EndVector' + then: [T: "vektor"] # phrase(the 2 column 'vector') + else: [T: "matrix"] # phrase(the 2 by 2 'matrix') + +- name: default-column-matrix + tag: matrix + variables: [IsColumnSilent: true()] + match: "*[self::m:mtr][count(*) = 1]" + replace: + - T: "die" # phrase('the' 2 by 2 matrix M) + - x: "count(*)" + - T: "mal 1 spalte" # phrase(the 2 'by 1 column' matrix) + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "vektor"] # phrase(the 2 column 'vector') + else: [T: "matrix"] # phrase(the 2 by 2 'matrix') + - pause: long + - x: "*" # select the rows (mtr) + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "ende der matrix"] # phrase(the 'end of matrix' has been reached) + +- name: 1x2-or-3-matrix + tag: matrix + variables: [IsColumnSilent: "$SpeechStyle = 'SimpleSpeak' or ($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: + - T: "die 1 mal" # phrase('the 1 by' 2 matrix) + - x: count(*/*) + - T: "Zeile" # phrase(the 1 by 4 'row' matrix) + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "die 1 mal"] # phrase('the 1 by' 2 row 'vector') + else: [T: "die 1 mal"] # phrase('the 1 by' 2 'matrix') + - pause: long + - x: "*/*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: "ende" # phrase(the 'end' of matrix has been reached) + - test: + if: $ClearSpeak_Matrix = 'EndMatrix' + then: [T: "matrix"] # phrase(the 2 by 2 'matrix') + else: [T: "vektor"] # phrase(the 2 by 1 'vector') + +- name: default-row-matrix + tag: matrix + variables: [IsColumnSilent: "$SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix = 'SilentColNum'"] + match: "count(*)=1" # one row + replace: + - T: "die 1 mal" # phrase('the 1 by' 2 matrix) + - x: "count(*/*)" + - T: "zeile" # phrase(the 1 by 2 'row' matrix) + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "vektor"] # phrase(the 2 by 1 'vector') + else: [T: "matrix"] # phrase(the 2 by 2 'matrix') + - pause: long + - pause: medium + - x: "*/*" # select the cols (mtd) + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: "ende" # phrase(the 'end' of matrix has been reached) + - test: + if: $ClearSpeak_Matrix = 'EndMatrix' + then: [T: "matrix"] # phrase(the 2 by 2 'matrix') + else: [T: "vektor"] # phrase(the 2 by 1 'vector') + +- 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 = 'SimpleSpeak' or ($SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix != 'SpeakColNum')"] + replace: + - T: "die" # phrase('the' 1 by 2 matrix M) + - x: count(*) + - T: "mal" # phrase(the 1 'by' 2 matrix) + - x: count(*[self::m:mtr][1]/*) + - test: + if: "self::m:determinant" + then: [T: "determinante"] # phrase(the 2 by 2 'determinant') + else: [T: "matrix"] # phrase(the 2 by 2 'matrix') + - pause: long + - x: "*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: "ende" # phrase(the 'end' of matrix has been reached) + - test: + if: "self::m:determinant" + then: [T: "determinante"] # phrase(the 2 by 2 'determinant') + else: [T: "matrix"] # phrase(the 2 by 2 'matrix') + +- name: default-matrix + tag: [matrix, determinant] + variables: [IsColumnSilent: "$SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix = 'SilentColNum'"] + match: "." + replace: + - T: "die" # phrase('the' 1 by 2 matrix M) + - x: "count(*)" + - T: "mal" # phrase(the 1 'by' 2 matrix) + - x: "count(*[self::m:mtr][1]/*)" + - test: + if: "self::m:determinant" + then: [T: "determinante"] # phrase(the 2 by 2 'determinant') + else: [T: "matrix"] # phrase(the 2 by 2 'matrix') + - pause: long + - x: "*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: "ende" # phrase(the 'end' of matrix has been reached) + - test: + if: "self::m:determinant" + then: [T: "determinante"] # phrase(the 2 by 2 'determinant') + else: [T: "matrix"] # phrase(the 2 by 2 'matrix's) + +- name: chemistry-msub + tag: [chemical-formula] + match: "*[1][.='msub']" + replace: + - x: "*[2]" + - test: + if: "$Verbosity='Verbose'" + then: [T: "index"] # phrase(H 'subscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] # phrase(H 'sub' 2) + - x: "*[3]" + +- name: dimension-by + tag: mrow + match: dimension-product + replace: + - insert: + nodes: "*" + replace: [T: "mal", pause: auto] # phrase(3 'by' 5 matrix) + +- name: chemistry-msup + tag: [chemical-formula] + match: "count(*)=3 and *[1][.='msup']" + replace: + - x: "*[2]" + - test: + if: "$Verbosity='Verbose'" + then: [T: "superscript"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] # phrase(H 'super' 2) + - 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: "superscript"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] # phrase(H 'super' 2) + - x: "$Prescripts[2]" + - pause: "short" + - test: + if: "not($Prescripts[1][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "index"] # phrase(a 'subscript' may be used to indicate an index) + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] # phrase(here is a 'sub' total) + - 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: "superscript"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] # phrase(H 'super' 2) + - x: "$Prescripts[4]" + - pause: "short" + - test: + if: "not($Prescripts[3][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "index"] # phrase(H 'subscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] # phrase(H 'sub' 2) + - 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: "index"] # phrase(phrase(H 'subscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] # phrase(phrase(H 'sub' 2) + - x: "$Postscripts[1]" + - pause: "short" + - test: + if: "not($Postscripts[2][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "superscript"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] # phrase(H 'super' 2) + - 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: "index"] # phrase(H 'subscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] # phrase(H 'sub' 2) + - x: "$Postscripts[3]" + - pause: "short" + - test: + if: "not($Postscripts[4][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "superscript"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] # phrase(H 'super' 2) + - 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: "index"] # phrase(H 'subscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] # phrase(H 'sub' 2) + - x: "$Postscripts[5]" + - pause: "short" + - test: + if: "not($Postscripts[6][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "superscript"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] # phrase(H 'super' 2) + - 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: "index"] # phrase(H 'subscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] # phrase(H 'sub' 2) + - x: "$Postscripts[7]" + - pause: "short" + - test: + if: "not($Postscripts[8][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "superscript"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] # phrase(H 'super' 2) + - 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: "solide"] # phrase(Boron is a 'solid' in its natural state) + - else_if: ".='l'" + then: [T: "flüssigkeit"] # 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) + - 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: "einzelbindung"] # phrase(a 'single bond' is formed when two atoms share one pair of electrons) + - else_if: ".='=' or .='∷'" + then: [T: "doppelbindung"] # phrase(a 'double bond' may occur when two atoms share two pairs of electrons) + - else_if: ".='≡'" + then: [T: "dreifachbindung"] # phrase(a 'triple bond' occurs when two atoms share three pairs of electrons) + - else_if: ".='≣'" + then: [T: "vierfachbindung"] # phrase(a 'quadruple bond' occurs when two atoms share four pairs of electrons) + 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: "formen"] # phrase(hydrogen and oxygen 'forms' water ) + else: [T: "reagiert auf die form"] # phrase(hydrogen and oxygen 'reacts to form' water) + - else_if: ".='⇌' or .='\u1f8d2'" + then: [T: "ist im gleichgewicht mit"] # phrase(a reactant 'is in equilibrium with' a product) + - else_if: ".='\u1f8d4'" + then: [T: "ist im gleichgewicht nach links vorgespannt mit"] # phrase(the reactant 'is in equilibrium biased to the left with' the product) + - else_if: ".='\u1f8d3'" + then: [T: "ist im gleichgewicht nach rechts vorgespannt mit"] # phrase(the reactant 'is in equilibrium biased to the right with' the product) + 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 + +- name: ignore-intent-wrapper + tag: intent-wrapper + match: "." + replace: + - x: "*" diff --git a/Rules/Languages/de/SharedRules/geometry.yaml b/Rules/Languages/de/SharedRules/geometry.yaml new file mode 100644 index 00000000..4ac49066 --- /dev/null +++ b/Rules/Languages/de/SharedRules/geometry.yaml @@ -0,0 +1,79 @@ +--- + +- name: line-segment + tag: line-segment + match: "count(*)=2" + replace: + - test: + if: "$Verbosity='Verbose'" + then: + - T: "die strecke von" # phrase('the line segment from' A to B) + - x: "*[1]" + - T: "nach" # phrase(the line segment from A 'to' B) + - x: "*[2]" + else: + - T: "strecke" # phrase(the 'line segment' A B) + - x: "*[1]" + - x: "*[2]" + +- name: geometry-ray + tag: ray + match: "count(*)=2" + replace: + - test: + if: "$Verbosity='Verbose'" + then: + - T: "der strahl von" # phrase('the ray from' A to B) + - x: "*[1]" + - T: "nach" # phrase(the ray from A 'to' B) + - x: "*[2]" + else: + - T: "ray" # phrase(the 'ray'A B) + - x: "*[1]" + - x: "*[2]" + +- name: geometry-arc + tag: arc + match: "count(*)=2" + replace: + - test: + if: "$Verbosity='Verbose'" + then: [T: "der"] # phrase('the' arc A B C) + - T: "bogen" # phrase(the 'arc' A B C) + - x: "*[1]" + - x: "*[2]" + +- name: measure-of-angle + tag: measure-of-angle + match: "count(*)=3" + replace: + - test: + if: "$Verbosity='Verbose'" + then: + - T: "das maß des winkels" # phrase('the measure of the angle' ABC) + else: + - T: "maß für den winkel" # phrase('measure of angle' ABC) + - x: "*[1]" + - x: "*[2]" + - x: "*[3]" + + +- name: coordinate + tag: coordinate + match: "." + replace: + - test: + if: "$Verbosity='Verbose'" + then: [T: "der"] # phrase('the' point at 1, 2) + - T: "punkt" # phrase(the 'point' at 1, 2) + - test: + if: "$Verbosity='Verbose'" + then: [T: "bei"] # phrase(the point 'at' 1, 2) + - pause: short + - insert: + nodes: "*" + replace: [T: "komma", pause: auto] # phrase(f of x 'comma' y) + - pause: short + - test: + if: "($SpeechStyle='ClearSpeak' and $Verbosity='Verbose') or not(IsNode(*[last()],'leaf'))" + then: [T: "ende des punktes"] # phrase(start point, 'end point') diff --git a/Rules/Languages/de/SharedRules/linear-algebra.yaml b/Rules/Languages/de/SharedRules/linear-algebra.yaml new file mode 100644 index 00000000..4969c062 --- /dev/null +++ b/Rules/Languages/de/SharedRules/linear-algebra.yaml @@ -0,0 +1,36 @@ +--- + +- name: scalar-determinant + tag: determinant + match: "count(*)=1 and not(*[1][self::m:mtr])" + replace: + - test: + if: "$Verbosity='Verbose'" + then: + - T: "die" # phrase('the' square root of 25 equals 5) + - T: "determinante" # phrase(the 'determinant' of a matrix) + - test: + if: "$Verbosity!='Terse'" + then: + - T: "von" # phrase(systems 'of' linear equations) + - x: "*[1]" + - test: + if: "not(IsNode(*[1], 'simple')) and $Impairment = 'Blindness'" + then: [T: "ende der determinante"] # phrase('end determinant' of a matrix) + + +- name: subscripted-norm + tag: subscripted-norm + match: "count(*)=2" + replace: + - test: + if: "$Verbosity='Verbose'" + then: + - T: "die" # phrase('the' square root of 25 equals 5) + - x: "*[2]" + - T: "norm" # phrase(the 'norm' can be a measure of distance) + - test: + if: "$Verbosity!='Terse'" + then: + - T: "von" # phrase(systems 'of' linear equations) + - x: "*[1]" diff --git a/Rules/Languages/de/SimpleSpeak_Rules.yaml b/Rules/Languages/de/SimpleSpeak_Rules.yaml new file mode 100644 index 00000000..3ba520e8 --- /dev/null +++ b/Rules/Languages/de/SimpleSpeak_Rules.yaml @@ -0,0 +1,350 @@ +--- +- 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: "minus" # phrase(x 'minus' y) + - x: "translate(text(), '-_', '')" + +- name: default + tag: square-root + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # phrase('the' square root of x) + - T: "quadratwurzel" # phrase(the 'square root' of x) + - test: + if: "$Verbosity!='Terse'" + then: [T: "von"] # phrase(the square root 'of' x) + else: [pause: short] + - x: "*[1]" + - test: + if: "IsNode(*[1], 'leaf') or $Impairment != 'Blindness'" + then: [pause: short] + else: [T: "ende der wurzel", pause: short] # phrase(start the square root of x 'end of root') + +- name: default + tag: root + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] + - test: + if: "*[2][self::m:mn and not(contains(., '.'))]" + then_test: + - if: "*[2][.='2']" + then: [T: "quadratwurzel"] # phrase(the 'square root' of x) + - else_if: "*[2][.='3']" + then: [T: "kubikwurzel"] # phrase(the 'cube root' of x) + - else: [x: "ToOrdinal(*[2])",T: "wurzel"] # phrase(the square 'root' of 25) + else: + - test: + if: "*[2][self::m:mi][string-length(.)=1]" + then: + - x: "*[2]" + - pronounce: [{text: "-th"}, {ipa: "θ"}, {sapi5: "th"}, {eloquence: "T"}] + else: [x: "*[2]"] + - T: "wurzel" # phrase(the square 'root' of) + - test: + if: "$Verbosity!='Terse'" + then: [T: "von"] # phrase(the square root 'of' x) + - x: "*[1]" + - test: + if: "IsNode(*[1], 'leaf') or $Impairment != 'Blindness'" + then: [pause: short] + else: [T: "ende der wurzel", pause: short] # phrase(start the fifth root of x 'end of root') + +# 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]" + variables: [IsPlural: "*[1]!=1"] + replace: + - x: "*[1]" + - x: "ToOrdinal(*[2], true(), $IsPlural)" # extra args specify fractional ordinal and whether it is plural + +- 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(., '.'))]" + variables: [IsPlural: "*[1]!=1"] + replace: + - x: "*[1]" + - x: "ToOrdinal(*[2], true(), $IsPlural)" # extra args specify fractional ordinal and whether it is plural + + +# 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: "5 meter" # phrase('5 meters 'per' second) + - 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: "über" # phrase(the fraction 3 'over' 4) + - x: "*[2]" + - pause: short + +- name: default + tag: fraction + match: "." + replace: + - test: + if: "$Impairment = 'Blindness'" + then: [T: "bruch"] # phrase(the 'fraction' 3 over 4) + - pause: short + - x: "*[1]" + - test: + if: "not(IsNode(*[1],'leaf'))" + then: [pause: short] + - T: "über" # phrase(the fraction 3 'over' 4) + - test: + if: "not(IsNode(*[2],'leaf'))" + then: [pause: short] + - x: "*[2]" + - pause: short + - test: + if: "$Impairment = 'Blindness'" + then: [T: "ende des bruchs"] # phrase(start 7 over 8 'end of fraction') + - 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: "umgekehrte" # 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: [T: "quadrat"] # phrase(5 'squared' equals 25) + else: [T: "hoch drei"] # phrase(5 'cubed' equals 125) +- name: function-power + tag: power + match: + - "following-sibling::*[1][self::m:mo][.='⁡']" #invisible function apply + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # # phrase('the' fourth power of 10) + - bookmark: "*[2]/@id" + - test: + if: "*[2][self::m:mn][not(contains(., '.'))]" + then: [x: "ToOrdinal(*[2])"] + else: [x: "*[2]"] + - T: "potenz von" # phrase(the fourth 'power of' 2) + - 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: [T: "quadrat"] # phrase(5 'squared' equals 25) + else: [T: "hoch drei"] # phrase(5 'cubed' equals 125) + +- name: simple-integer + tag: power + 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]"} +- 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: "hoch" # phrase(15 raised 'to the' second power equals 225) + - x: "*[2]" +- name: simple-var + tag: power + match: "*[2][self::m:mi][string-length(.)=1]" + replace: + - 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 + match: "IsNode(*[2], 'leaf')" + replace: + - x: "*[1]" + - T: "hoch" # phrase(15 raised 'to the' second power equals 225) + - 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: "hoch" # phrase(15 'raised to the' second power equals 225) + - x: "*[2]" + - pause: short + - test: + if: "$Impairment = 'Blindness'" + then: + - T: "ende des exponenten" # phrase(start 2 raised to the exponent 4 'end of exponent') + - pause: short + else: + - pause: medium + +- name: default + tag: power + match: "." + replace: + - x: "*[1]" + - T: "hoch" # phrase(15 'raised to the' second power equals 225) + - x: "*[2]" + - T: "potenz" # phrase(15 raised to the second 'power' equals 225) + - pause: short + +# +# Some rules on mrows +# +- name: set + tag: set + match: "." + replace: + - test: + - if: "count(*)=0" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: "das"] # phrase('the' empty set) + - T: "leere Menge" # phrase(when a set contains no value it is called an 'empty set' and this is valid) + - else_if: "count(*[1]/*)=3 and *[1]/*[2][self::m:mo][.=':' or .='|' or .='∣']" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # phrase('the' set of all integers) + - T: "Menge aller" # phrase(the 'set of all' positive integers less than 10) + - x: "*[1]/*[1]" + - T: "so dass" # phrase(x 'such that' x is less than y) + - x: "*[1]/*[3]" + else: + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # phrase('the' set of integers) + - T: "Menge" # phrase(here is a 'set' of numbers) + - x: "*[1]" + +- name: times + tag: mo + match: + # say "times" when invisible times is followed by parens or a superscript that has a base with parens or "|"s + # 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: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) + - " or " + - " preceding-sibling::*[1][" + - " IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')]" # followed by parens + - " )" + replace: + - T: "mal" # phrase(7 'times' 5 equals 35) + +- 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') ) 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/de/definitions.yaml b/Rules/Languages/de/definitions.yaml new file mode 100644 index 00000000..4e5ccf04 --- /dev/null +++ b/Rules/Languages/de/definitions.yaml @@ -0,0 +1,267 @@ +--- +- 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: { + "indexed-by": "infix= ; sub; ende sub: ende sub: ende subskript", + "modified-variable": "silent= ", + "say-super": "infix=super: hochstellung: hochstellung", + "skip-super": "silent=", + "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", + "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", + "minus": "infix=minus || prefix=negativ", + "plus": "infix=plus || prefix=positiv", + "real-part": "function=der reale teil", + "transpose": "postfix=transponieren || function=transponieren", + "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", + "curl": "function= ; rotation; ende rotation", + "gradient": "function= ; grad: gradient: gradient; ende gradient", + "laplacian": "function=laplace", + "chemistry-concentration": "function= ; konzentration: konzentration von: die konzentration von; ende konzentration" + } + +- NavigationParts: { + "large-op": "basis; untergrenze; obergrenze", + "mfrac": "zähler; nenner", + "fraction": "zähler; nenner", + "msqrt": "wurzel", + "square-root": "wurzel", + "mroot": "wurzel; wurzelexponent", + "root": "wurzel; wurzelexponent", + "msub": "basis; subskript", + "sub": "basis; subskript", + "msup": "basis; hochstellung", + "say-super": "basis; hochstellung", + "skip-super": "basis; hochstellung", + "power": "basis; exponent", + "msubsup": "basis; subskript; hochstellung", + "munder": "basis; untere grenze", + "mover": "basis; obere grenze", + "munderover": "basis; untere grenze; obere grenze", + "in": "in", + "out": "außerhalb von" + } + +- SIPrefixes: { + "Q": "quetta", "R": "ronna", "Y": "yotta", "Z": "zetta", "E": "exa", "P": "peta", "T": "tera", "G": "giga", + "M": "mega", "k": "kilo", "h": "hekto", "da": "deka", "d": "dezi", "c": "zenti", "m": "milli", "µ": "mikro", + "n": "nano", "p": "piko", "f": "femto", "a": "atto", "z": "zepto", "y": "yocto", "r": "ronto", "q": "quecto" + } + +- SIUnits: { + "A": "ampere", "cd": "candela", "K": "kelvin", "K": "kelvin", + "g": "gramm", "m": "meter", "mol": "mol", "s": "sekunde", "sec": "sekunde", + "Bq": "becquerel", "C": "coulomb", "°C": "grad celsius", "℃": "grad celsius", + "F": "farad", "Gy": "gray", "H": "henry", "Hz": "hertz", "J": "joule", "kat": "katal", + "lm": "lumen", "lx": "lux", "N": "newton", "Ω": "ohm", "Ω": "ohm", "Pa": "pascal", + "S": "siemens", "Sv": "sievert", "T": "tesla", "V": "volt", "W": "watt", "Wb": "weber", + "l": "liter", "L": "liter", "ℓ": "liter", "t": "tonne", "Da": "dalton", "Np": "neper", + "u": "atommasse-einheit", "eV": "elektronenvolt", "rad": "radiant", "sr": "steradiant", + "a": "jahr", "as": "bogensekunde", "b": "bit", "B": "byte", "Bd": "baud" + } + +- UnitsWithoutPrefixes: { + "″": "sekunde", "\"": "sekunde", + "′": "minute", "'": "minute", "min": "minute", + "h": "stunde", "hr": "stunde", "Hr": "stunde", + "d": "tag", "dy": "tag", "w": "woche", "wk": "woche", "y": "jahr", "yr": "jahr", + "°": "grad", "deg": "grad", "arcmin": "bogenminute", "amin": "bogenminute", "am": "bogenminute", + "MOA": "bogenminute", "arcsec": "bogensekunde", "asec": "bogensekunde", + "au": "astronomische einheit", "AU": "astronomische einheit", "ltyr": "lichtjahr", "ly": "lichtjahr", + "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", + "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", + "ZiB": "zebi-byte", "YiB": "yobi-byte" + } + +- EnglishUnits: { + # length + "in": "zoll", + "ft": "fuß", + "mi": "meile", + "rd": "ruthe", + "li": "glied", + "ch": "kette", + + # area + "sq in": "quadratzoll", "sq. in": "quadratzoll", "sq. in.": "quadratzoll", + "sq ft": "quadratfuß", "sq. ft": "quadratfuß", "sq. ft.": "quadratfuß", + "sq yd": "quadratyard", "sq. yd": "quadratyard", "sq. yd.": "quadratyard", + "sq mi": "quadratmeile", "sq. mi": "quadratmeile", "sq. mi.": "quadratmeile", + "ac": "morgen", + "FBM": "brettfuß", + + # volume + "cu in": "kubikzoll", "cu. in": "kubikzoll", "cu. in.": "kubikzoll", + "cu ft": "kubikfuß", "cu. ft": "kubikfuß", "cu. ft.": "kubikfuß", + "cu yd": "kubikyard", "cu. yd": "kubikyard", "cu. yd.": "kubikyard", + "bbl": "fass", "BBL": "fass", + "pk": "buschelmaß", + "bu": "buschel", + "tsp": "teelöffel", + "tbl": "esslöffel", + + # liquid + "fl dr": "flüssige dram", + "fl oz": "flüssige unze", + "gi": "gill", + "cp": "tasse", "cup": "tasse", + "pt": "pint", + "qt": "quart", + "gal": "gallone", + + # weight + "gr": "korn", + "dr": "dram", + "oz": "unze", "℥": "unze", + "lb": "pfund", + "cwt": "zentner", + "dwt": "feingewicht", + "oz t": "troy-unze", + "lb t": "troy-pfund", + + # energy + "hp": "ps", + "BTU": "britische wärmeeinheit", + "°F": "grad fahrenheit", "℉": "grad fahrenheit", + + # other + "mph": "meile pro stunde", + "mpg": "meile pro gallone", + } + +- PluralForms: { + "inch": "zoll", "square inch": "quadratzoll", "cubic inch": "kubikzoll", + "foot": "füße", "square foot": "quadratfuß", "cubic foot": "kubikfuß", + "board foot": "brettfuß", + "degree celsius": "grad celsius", + "degree fahrenheit": "grad fahrenheit", + "hertz": "hertz", + "siemens": "siemens", + "revolution per minute": "umdrehungen pro minute", + "mile per hour": "meilen pro stunde", + "mile per gallon": "meilen pro gallone" + } + + +# ---------------- 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).:w + +# All definitions start 0, 10, 100, etc. + +# The definitions for the "ones" should extend until a regular pattern begins +# The minimum length is 10. + +# For English, a regular pattern starts at twenty +- NumbersOnes: [ + "null", "eins", "zwei", "drei", "vier", "fünf", "sechs", "sieben", "acht", "neun", + "zehn", "elf", "zwölf", "dreizehn", "vierzehn", "fünfzehn", "sechzehn", + "siebzehn", "achtzehn", "neunzehn" + ] + +- NumbersOrdinalOnes: [ + "nullte", "erste", "zweite", "dritte", "vierte", "fünfte", "sechste", "siebte", "achte", "neunte", + "zehnte", "elfte", "zwölfte", "dreizehnte", "vierzehnte", "fünfzehnte", "sechzehnte", + "siebzehnte", "achtzehnte", "neunzehnte" + ] + +- NumbersOrdinalPluralOnes: [ + "nullte", "erste", "zweite", "dritte", "vierte", "fünfte", "sechste", "siebte", "achte", "neunte", + "zehnte", "elfte", "zwölfte", "dreizehnte", "vierzehnte", "fünfzehnte", "sechzehnte", + "siebzehnte", "achtzehnte", "neunzehnte" + ] + + # stop when regularity begins +- NumbersOrdinalFractionalOnes: [ + "null", "erste", "hälfte", "drittel", "viertel", "fünftel", "sechstel", "siebtel", "achtel", "neuntel", "zehntel", + "elftel", "zwölftel", "dreizehntel", "vierzehntel", "fünfzehntel", "sechzehntel", + "siebzehntel", "achtzehntel", "neunzehntel" + ] + + # stop when regularity begins +- NumbersOrdinalFractionalPluralOnes: [ + "nulle", "erste", "hälften" + ] + + # What to use for multiples of 10 +- NumbersTens: [ + "", "zehn", "zwanzig", "dreißig", "vierzig", "fünfzig", "sechzig", "siebzig", "achtzig", "neunzig" + ] + +- NumbersOrdinalTens: [ + "", "zehnte", "zwanzigste", "dreißigste", "vierzigste", "fünfzigste", "sechzigste", "siebzigste", "achtzigste", "neunzigste" + ] + +- NumbersOrdinalPluralTens: [ + "", "zehnte", "zwanzigste", "dreißigste", "vierzigste", "fünfzigste", "sechzigste", "siebzigste", "achtzigste", "neunzigste" + ] + +- NumbersHundreds: [ + "", "einhundert", "zweihundert", "dreihundert", "vierhundert", "fünfhundert", + "sechshundert", "siebenhundert", "achthundert", "neunhundert" + ] + +- NumbersOrdinalHundreds: [ + "", "einhundertste", "zweihundertste", "dreihundertste", "vierhundertste", "fünfhundertste", + "sechshundertste", "siebenhundertste", "achthundertste", "neunhundertste" + ] + +- NumbersOrdinalPluralHundreds: [ + "", "einhundertste", "zweihundertste", "dreihundertste", "vierhundertste", "fünfhundertste", + "sechshundertste", "siebenhundertste", "achthundertste", "neunhundertste" + ] + + # At this point, hopefully the language is regular. If not, code needs to be written +- NumbersLarge: [ + "", "tausend", "million", "milliarde", "billion", "billiarde", + "trillion", "trilliarde", "quadrillion", "quadrilliarde", "quintillion" + ] + +- NumbersOrdinalLarge: [ + "", "tausendste", "millionste", "milliardste", "billionste", "billiardste", + "trillionste", "trilliardste", "quadrillionste", "quadrilliardste", "quintillionste" + ] + +- NumbersOrdinalPluralLarge: [ + "", "tausendste", "millionste", "milliardste", "billionste", "billiardste", + "trillionste", "trilliardste", "quadrillionste", "quadrilliardste", "quintillionste" + ] + diff --git a/Rules/Languages/de/navigate.yaml b/Rules/Languages/de/navigate.yaml new file mode 100644 index 00000000..72ad5bb5 --- /dev/null +++ b/Rules/Languages/de/navigate.yaml @@ -0,0 +1,1669 @@ +--- +# 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 + +# Note: the rules for saying a command and announcing what is said when moving in/out of a 2d exprs are hacks +# They depend upon special variables "SayCommand" and "Move2D" being set and if they are, the rules are activated. +# If/when functions can be defined in a rules file, it is likely these would be much better done via those functions +# as they would likely be much more efficient and also cleaner. + +# Rules for announcing the command +- name: say-command + tag: "!*" + match: "$SayCommand != ''" # value should be '', 'true', or 'false' + variables: [Prefix: "''"] + replace: + - test: + - if: "$MatchCounter = 0 and $SayCommand = 'true'" + then_test: + - if: "self::m:math and starts-with($NavCommand, 'ZoomOut')" + then: [T: "den ganzen weg vergrenzt", pause: "medium"] + - else_if: "IsNode(., 'leaf') and starts-with($NavCommand, 'ZoomIn')" + then: [T: "auf den ganzen weg vergrenzt", pause: "medium"] + else: + - test: + - if: "starts-with($NavCommand, 'Zoom')" + then: [set_variables: [Prefix: "'zoom'"]] # 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) + - else_if: "starts-with($NavCommand, 'Read')" + then: [set_variables: [Prefix: "'read'"]] # 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) + - test: + if: "$Prefix != ''" + then: + - x: "$Prefix" + - test: + - if: "substring($NavCommand, string-length($Prefix)+1) = 'In'" + then: [T: "in"] # phrase(zoom 'in' to see more details) + - else_if: "substring($NavCommand, string-length($Prefix)+1) = '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'" + then: [T: "raus"] # phrase(zoom 'out' to see more details) + - else_if: "substring($NavCommand, string-length($Prefix)+1) = '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'" + then: [T: "rechten"] # phrase(move to the 'right') + - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Previous'" + then: [T: "linken"] # phrase(move to the 'left') + - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Current'" + then: [T: "aktuelle"] # phrase(who is the 'current' president) + - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'LineStart'" + then: [T: "start der linie"] # phrase(move 'to start of line') + - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'LineEnd'" + then: [T: "bis zum ende der linie"] # phrase(move 'to end of line') + - pause: "medium" + - set_variables: [MatchCounter: "1"] + +- name: into-or-out-of-silent + tag: "*" + # saying "out of row n" is not very useful, so skip it + match: "$Move2D != '' and (not(@data-from-mathml) or @data-from-mathml = name(.)) and + (name(.)='mrow' or name(.) = 'mtr' or name(.) = 'mlabeledtr' or @data-from-mathml = 'mtable')" + replace: [] + +- name: into-or-out-of-mtr + tag: [mtr, mlabeledtr] + match: "$Move2D = 'in'" + replace: + - T: "spalte" + - x: "count($Child2D/preceding-sibling::*)+1" + - pause: "medium" + +- name: into-or-out-of-mmultiscripts + tag: "*" + match: "$Move2D != '' and (@data-from-mathml='mmultiscripts' or self::m:mmultiscripts)" + replace: + - test: + if: "name($Child2D)!='none'" + then: + - with: + variables: + - NumPrecedingSiblings: "count($Child2D/preceding-sibling::*)" + replace: + - x: "$Move2D" + - test: + - if: "$NumPrecedingSiblings=0" + then: [T: "basis"] # phrase(the 'base' of the power) + - 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: "index"] # phrase(x with 'subscript' 2) + else: [T: "superscript"] # phrase(x with 'superscript' 2) + else: + - test: + if: "$NumPrecedingSiblings mod 2 = 0" + then: [T: "pre-superscript"] # phrase(x with 'pre-superscript' 2) + else: [T: "pre-subscript"] # phrase(x with 'pre-subscript' 2) + - pause: "medium" + +# Rules for speaking what happens when moving into or out of a notation +- name: into-or-out-of-intent + tag: "*" + # saying "out of row n" is not very useful, so skip it + # match: "$Move2D != '' and @data-from-mathml and @data-from-mathml != name(.) and count(./*)>1 and @data-from-mathml != 'mtable'" + match: "$Move2D != '' and count(./*)>1 and @data-from-mathml != 'mtable'" + replace: + - with: + variables: + - PartNumber: "count($Child2D/preceding-sibling::*)" + - PartName: "GetNavigationPartName(name(.), $PartNumber)" + replace: + - x: "$Move2D" + - test: + if: "$PartName != ''" + then: [x: "$PartName"] + else: + - T: "teil" # phrase(the 'part' of the expression) + - 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: "zoom in"] # phrase('undo zoom in') + - else_if: "$PreviousNavCommand = 'ZoomOut'" + then: [T: "zoomen"] # phrase('undo zoom out') + - else_if: "$PreviousNavCommand = 'ZoomInAll'" + then: [T: "das reinzoomen ganz ausschalten"] # phrase('undo zooming in all the way') + - else_if: "$PreviousNavCommand = 'ZoomOutAll'" + then: [T: "das auszoomen ganz ausschalten"] # phrase('undo zooming out all the way') + - else_if: "$PreviousNavCommand = 'MovePrevious' or $PreviousNavCommand = 'MovePreviousZoom'" + then: [T: "rückgängig links"] # phrase('undo move left') + - else_if: "$PreviousNavCommand = 'MoveNext' or $PreviousNavCommand = 'MoveNextZoom'" + then: [T: "rückgängig rechts"] # phrase('undo move right') + - else_if: "$PreviousNavCommand = 'None'" + then: [T: "kein vorheriger befehl"] # phrase('no previous command') + - pause: "medium" + - 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: "ganz eingezommt", pause: "long"] # phrase('zoomed in all of the way') + - test: + if: "$ReadZoomLevel!=-1" + then: + - set_variables: [ReadZoomLevel: "0"] + - set_variables: [NavNode: "@id"] + +# special case of zooming into a table -- move to the first row (if only one row, first column) +- name: zoom-in-table + tag: "*" + match: "$NavCommand = 'ZoomIn' and (name(.) = 'mtable' or (count(*)=1 and *[1][@data-from-mathml='mtable']))" + replace: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - test: + if: "count(*)=1" + then: + - set_variables: [NavNode: "*[1]/*[1]/@id"] + else: + - set_variables: [NavNode: "*[1]/@id"] + +- name: zoom-in-mrow-in-math + # zooming in only once is meaningless because 'math' has only a single child and it was spoken at the math level -- dig inside and do it again + tag: math + match: "$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 or @data-from-mathml='mrow'] and + not(@data-from-mathml='msqrt' or self::m:msqrt or @data-from-mathml='menclose' or self::m:menclose))" + replace: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - test: + if: "name(*[1]) != 'mrow'" + then: + - with: + variables: [Move2D: "'in'", Child2D: "IfThenElse(count(*)=0, $Move2D, $Move2D)"] # phrase('in' the denominator) + replace: [x: "IfThenElse($NavCommand = 'MovePreviousZoom', 1, $Child2D)"] + - test: + if: "$NavCommand = 'MovePreviousZoom'" + then: [x: "*[last()]"] + else: [x: "*[1]"] + +- name: zoom-in-enhanced + tag: "*" + match: "$NavCommand = 'ZoomIn' and $NavMode='Enhanced'" + replace: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - test: + - if: "self::m:mtr or self::m:mlabeledtr" + then: + - with: + variables: [Move2D: "'in'", Child2D: "*[1]/*[1]"] # phrase('in' the denominator) + 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: "'in'", Child2D: "*[1]"] # phrase('in' the denominator) + replace: [x: "."] + - set_variables: [NavNode: "*[1]/*[2]/@id"] # skip parens/brackets + else: + - with: + variables: [Move2D: "'in'", Child2D: "*[1]"] # phrase('in' the denominator) + replace: [x: "."] + - set_variables: [NavNode: "*[1]/@id"] + +- name: zoom-in-2D-not-enhanced + tag: "*" + match: "$NavCommand = 'ZoomIn' and $NavMode!='Enhanced' and (IsNode(., '2D') or not(IsNode(., 'mathml')))" + replace: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - with: + variables: [Move2D: "'in'", Child2D: "*[1]"] # phrase('in' the denominator) + replace: [x: "."] + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "*[1]"] + +- name: zoom-in-default + tag: "*" + match: "$NavCommand = 'ZoomIn'" + replace: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - with: + variables: [Move2D: "'in'", Child2D: "*[1]"] # phrase('in' the denominator) + replace: [x: "."] + - test: + if: "$NavMode='Character'" + then: [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: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - with: + variables: [Move2D: "'in'", Child2D: "*[1]"] # phrase('in' the denominator) + replace: [x: "."] + - x: "*[1]" + +- name: zoom-out + tag: math + match: "$NavCommand = 'ZoomOut' or $NavCommand = 'ZoomOutAll'" + replace: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - set_variables: [NavNode: "*[1]/@id"] # no-op for $NavCommand = 'ZoomOut' + +- 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-top + tag: "*" + match: + - "($NavCommand = 'ZoomOut' or $NavCommand = 'ZoomOutAll') and" + - "parent::m:math " + replace: + - x: ".." # let math rule deal with it + +- name: zoom-out-all-default + tag: "*" + match: "$NavCommand = 'ZoomOutAll'" + replace: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - with: + variables: [Move2D: "'aus'", Child2D: "."] + replace: [x: ".."] + - 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: + - with: + variables: [Move2D: "'im'", Child2D: "*[1]"] # phrase('in' the denominator) + replace: [x: "."] + - test: + - if: "count(*)> 1 or IsNode(., 'leaf') or + @data-from-mathml='msqrt' or self::m:msqrt or @data-from-mathml='menclose' 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: "'in'", Child2D: "following-sibling::*[1]"] # phrase('in' the denominator) + # replace: [x: ".."] + - set_variables: [NavNode: "@id"] + else: + - with: + variables: [Move2D: "'in'", Child2D: "*[1]"] # phrase('in' the denominator) + 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: "'in'", Child2D: "preceding-sibling::*[1]"] # phrase('in' the denominator) + # replace: [x: ".."] + - set_variables: [NavNode: "@id"] + else: + - with: + variables: [Move2D: "'im'", Child2D: "*[last()]"] # phrase('in' the denominator) + replace: [x: "."] + - x: "*[last()]" + +# ********* ZoomOut *************** +- name: zoom-out-default + + + tag: mtd + match: "$Move2D = '' and ($NavCommand = 'ZoomOut')" + replace: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + # we need to speak it here + # - T: "Zeile" # phrase(the first 'row' of the matrix) + # # 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: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - 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: "'aus'", 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: "gehe zum start der formel"] # phrase('move to start of math') + - else_if: "$NavCommand = 'MoveLineStart'" + then: [T: "gehe zum start der linie"] # phrase('move to start of line') + - else_if: "$NavCommand = 'MoveEnd'" + then: [T: "gehe zum ende der formel"] # phrase('move to end of math') + else: [T: "gehe zur ende der linie"] # "$NavCommand = 'MoveLineEnd'" # phrase('move to end of line') + - 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) + # Note: an apparent bug in the xpath code doesn't let me use IfThenElse for the 2 if: then: below + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: + - test: + if: "*[1]/*[1]" # could be a x, so no grandchild + then: [x: "*[1]/*[1]"] + else: [x: "*[1]"] + else: + - with: + variables: [NavCommand: "'MovePreviousZoom'"] + replace: + - test: + if: "*[last()]/*[last()]" # could be a x, so no grandchild + then: [x: "*[last()]/*[last()]"] + else: [x: "*[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::*[1][self::m:msub or self::m:msup or self::m:msubsup or self::m:mmultiscripts or" + - " @data-from-mathml and" + - " (@data-from-mathml='msub' or @data-from-mathml='msup' or" + - " @data-from-mathml='msubsup' or @data-from-mathml='mmultiscripts')" + - " ] )" + replace: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - test: + if: "$NavCommand = 'MoveLineStart'" + then: [T: "bewegen sie sich zum start der linie"] # phrase('move to start of line') + else: [T: "bewegen sie sich zum ende der linie"] # "$NavCommand = 'MoveLineEnd'" # phrase('move to end of line') + - pause: "medium" + - test: + if: "self::m:mrow or @data-from-mathml = '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: "nicht in der tabelle" # phrase('not in table') + - 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: "nach links" # phrase('move left') + - pause: short + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "spalte" # phrase(the first 'column' of the table) + - 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: "keine vorherige spalte" # phrase('no previous column' in the table) + - 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: "rechts" # phrase('move right') + - pause: short + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "spalte" # phrase(the first 'column' in the table) + - 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: "keine nächste spalte" # phrase('no next column' in the table) + - 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: "gehe nach oben in der tabelle" # phrase('move up' to previous row in the table) + - pause: short + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "zeile" # phrase(the previous 'row' in the table) + - x: "count(../preceding-sibling::*)" + - pause: short + - T: "spalte" # phrase(the previous 'column' in the table) + - 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: "keine vorherige zeile" # phrase('no previous row' in the table) + - 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: "gehe nach unten" # phrase('move down to the next row in the table) + - pause: short + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "reihe" # phrase(the next 'row' in the table) + - x: "count(../preceding-sibling::*)+2" + - pause: short + - T: "spalte" # phrase(the next 'column' in the table) + - 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: "keine nächste Zeile" # phrase('no next row' in the table) + - set_variables: [SpeakExpression: "'false'"] + +- name: move-cell-up + tag: [mtr, mlabeledtr] + match: "$NavCommand='MoveCellUp'" + replace: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "zur vorherigen zeile" # phrase('move to previous row' to the previous row in the table) + - pause: medium + - test: + if: "preceding-sibling::*" + then: + - test: + if: "$NavMode='Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "preceding-sibling::*[1]"] + else: + - set_variables: [NavNode: "preceding-sibling::*[1]/@id"] + else: + - T: "keine vorherige zeile" # phrase('no previous row' in the table) + - set_variables: [SpeakExpression: "'false'"] + +- name: move-cell-down + tag: [mtr, mlabeledtr] + match: "$NavCommand='MoveCellDown'" + replace: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "zur nächsten Zeile" # phrase('move to next row' to the next row in the table) + - pause: medium + - test: + if: "following-sibling::*" + then: + - test: + if: "$NavMode='Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "following-sibling::*[1]"] + else: + - set_variables: [NavNode: "following-sibling::*[1]/@id"] + else: + - T: "keine nächste Zeile" # phrase('no next row' in the table) + - set_variables: [SpeakExpression: "'false'"] + +- name: move-cell-previous + # if a row is selected, there is no previous/next column, so this is trivial + tag: [mtr, mlabeledtr] + match: "$NavCommand='MoveCellPrevious'" + replace: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "übergehen sie zur vorherigen spalte" # phrase('move to previous column' to the previous row in the table) + - pause: medium + - T: "keine vorherige spalte" # phrase('no previous column' in the table) + - set_variables: [SpeakExpression: "'false'"] + +- name: move-cell-next + # if a row is selected, there is no previous/next column, so this is trivial + tag: [mtr, mlabeledtr] + match: "$NavCommand='MoveCellNext'" + replace: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "gehe nach oben" # phrase('move up' to the previous row in the table) + - pause: medium + - T: "keine nächste Zeile" # phrase('no next row' in the table) + - 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: "aktuelle eintrag lesen" # phrase('read current entry' in the table) + - pause: medium + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "zeile" # phrase(the previous 'row' in the table) + - x: "count($MTD[1]/../preceding-sibling::*)+1" + - pause: short + - T: "spalte" # phrase(the previous 'column' in the table) + - x: "count($MTD[1]/preceding-sibling::*)+1" + - pause: short + - set_variables: [NavNode: "$MTD[1]/*[1]/@id"] + else: + - T: "nicht in tabelle" # phrase('not in table' or matrix) + - 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: "nicht in tabelle" # phrase('not in table' or matrix) + - pause: long + - set_variables: [SpeakExpression: "'false'"] + +# ======== Move/Read/Describe Next rules ================= + +# skip 'none' +- name: move-next-none + tag: "none" + 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: "'in'", Child2D: "$Following"] # phrase('in' the denominator) + replace: [x: ".."] + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "$Following"] + +# skip 'none' +- name: move-previous-none + tag: "none" + 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: "'in'", Child2D: "$Preceding"] # phrase('in' the denominator) + 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: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - test: + if: "following-sibling::*[1][.='\u2062' or .='\u2064'] and + ($NavMode='Enhanced' or ($NavMode='Simple' and following-sibling::*[2][not(IsNode(., 'mathml'))]))" # 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 = 'Verbose'" + then: + - T: "kann nicht nach rechts bewegen" # phrase('cannot move right') + - pause: medium + - with: + variables: [Move2D: "'end of'", 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 = 'Verbose'" + then: + - T: "kann nicht" # phrase('cannot' move right in expression) + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: "bewegen sie"] # phrase('move' to next entry in table) + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "lesen sie"] # phrase('read' next entry in table) + else: [T: "beschreiben"] # phrase('describe' next entry in table) + - T: "rechts" # phrase(move 'right') + - pause: short + - T: "ende der formel" # phrase(move 'end of math') + - 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: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - test: + if: "following-sibling::*" + then: + - with: + variables: [Move2D: "'in'", Child2D: "."] # phrase('in' the denominator) + replace: [x: ".."] + else: + - with: + variables: [Move2D: "'out of'", Child2D: "."] + replace: [x: ".."] + - 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: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - test: + if: "following-sibling::*" + then: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "spalte" # phrase(the previous 'column' in the table) + - 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') and + following-sibling::*" + replace: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - test: + if: "$NavMode = 'Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "following-sibling::*[1]"] + else: + - set_variables: [NavNode: "following-sibling::*[1]/@id"] + +- 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: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - 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: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - 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: "'out of'", Child2D: "."] + replace: [x: ".."] + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: "following-sibling::*[1]"] # skip over 'none' + else: + - with: + variables: [Move2D: "'in'", Child2D: "following-sibling::*[1]"] # phrase('in' the denominator) + 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: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - test: + if: "following-sibling::*[1][@data-from-mathml='none' or @data-from-mathml='mprescripts']" + then: [x: "following-sibling::*[1]"] + else: + - test: + if: "IsNode(.., '2D') or not(IsNode(.., 'mathml'))" + then: + - with: + variables: [Move2D: "'in'", Child2D: "following-sibling::*[1]"] # phrase('in' the denominator) + 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: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - 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 left +- name: move-previous-no-auto-zoom-at-edge + # at edge of 2D and in a mode where moving left 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 = 'Verbose' and $NavCommand = 'MovePrevious'" + then: + - T: "kann sich nicht links bewegen" # phrase('cannot move left' in expression) + - pause: medium + - with: + variables: [Move2D: "'end of'", 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: "start der mathematik" # phrase('start of math') + - pause: long + - set_variables: [SpeakExpression: "'false'"] + +- name: move-previous-at-end + tag: "*" + match: + - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious') and" + - "name(EdgeNode(., 'left', 'math'))='math'" # at edge of math + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - T: "kann nicht nach links bewegen" # phrase('cannot move left') + - pause: short + - with: + variables: [Move2D: "'start of'", Child2D: "."] + replace: [x: "."] + - 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: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - test: + if: "preceding-sibling::*" + then: + - with: + variables: [Move2D: "'in'", Child2D: "."] # phrase('in' the denominator) + replace: [x: ".."] + else: + - with: + variables: [Move2D: "'out of'", Child2D: "."] + replace: [x: ".."] + - x: ".." + +- name: move-previous-auto-zoom-parens + # 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: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - test: + if: "not(parent::m:mrow)" + then: + - with: + variables: [Move2D: "'in'", Child2D: "preceding-sibling::*[1]"] # phrase('in' the denominator) + 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') and + preceding-sibling::*" + replace: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "spalte" # phrase(the first 'column' in the table) + - 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"]] + +- name: move-previous-default + tag: [mtr, mlabeledtr] + match: "$Move2D = '' and ($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious')" + replace: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - test: + if: "preceding-sibling::*" + then: + - test: + if: "$NavMode = 'Character'" + then: + - with: + variables: [NavCommand: "'MovePreviousZoom'"] + replace: [x: "preceding-sibling::*[1]"] + else: + - set_variables: [NavNode: "preceding-sibling::*[1]/@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: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - 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: "'out of'", Child2D: "."] + replace: [x: ".."] + - x: "preceding-sibling::*[1]" # skip over 'none' + else: + - with: + variables: [Move2D: "'in'", Child2D: "preceding-sibling::*[1]"] # phrase('in' the denominator) + replace: [x: ".."] + - with: + variables: [NavCommand: "'MovePreviousZoom'"] + replace: [x: "preceding-sibling::*[1]"] + +- name: move-previous-default + tag: "*" + match: "$NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious'" + replace: + - with: + variables: [SayCommand: "string($NavVerbosity = 'Verbose')"] + replace: [x: "."] + - test: + if: "preceding-sibling::*[1][@data-from-mathml='none' or @data-from-mathml='mprescripts']" + then: [x: "preceding-sibling::*[1]"] + else: + - test: + if: "IsNode(.., '2D') or not(IsNode(.., 'mathml'))" + then: + - with: + variables: [Move2D: "'in'", Child2D: "preceding-sibling::*[1]"] # phrase('in' the denominator) + 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: "Zeichen" # phrase(a mathematical 'character') + - set_variables: [NavMode: "'Character'", ReadZoomLevel: "1"] + - else_if: "$NavMode = 'Character'" + then: + - T: "einfache" # phrase(a 'simple' way to do something) + - set_variables: [NavMode: "'Simple'", ReadZoomLevel: "1"] + - else: + - T: "verbesserte" # phrase(an 'enhanced' way to do something) + - set_variables: [NavMode: "'Enhanced'", ReadZoomLevel: "-1"] + - T: "Art" # phrase(a simple 'mode' of use) + - 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: "einfache" # phrase(an 'simple' way to do something) + - set_variables: [NavMode: "'Simple'", ReadZoomLevel: "1"] + - else_if: "$NavMode = 'Character'" + then: + - T: "verbesserte" # phrase(an 'enhanced' way to do something) + - set_variables: [NavMode: "'Enhanced'", ReadZoomLevel: "-1"] + - else: + - T: "Zeichen" # phrase(a mathematical 'character') + - set_variables: [NavMode: "'Character'", ReadZoomLevel: "1"] + - T: "modus" # phrase(a simple 'mode' of use) + - 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: "ausdruck nach der bewegung sprechen" # phrase('speak expression after move') + - pause: long + - set_variables: [Overview: "'false'"] + else: + - T: "überblick des ausdrucks nach der bewegung sprechen" # phrase('overview of expression after move') + - pause: long + - set_variables: [Overview: "'true'"] + +- name: current + tag: "*" + match: "$NavCommand = 'ReadCurrent' or $NavCommand = 'DescribeCurrent'" + replace: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'ReadCurrent'" + then: [T: "lese"] # phrase('read' next entry in table) + else: [T: "beschreibe"] # phrase('describe' next entry in table) + - T: "aktueller" # phrase('current' entry in table) + - pause: long + - set_variables: [NavNode: "@id"] + +# 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: "lese"] # phrase('read' next entry in table) + - else_if: "starts-with($NavCommand, 'Describe')" + then: [T: "beschreibe"] # phrase('describe' next entry in table) + - else_if: "starts-with($NavCommand, 'MoveTo')" + then: [T: "wechsel zu"] # phrase('move to' the next entry in table) + else: [T: "setze"] # phrase('set' the value of the next entry in table) + - T: "platzhalter" # phrase('placeholder' for the value) + - x: "$PlaceMarkerIndex" + - pause: long + - set_variables: [NavNode: "$PlaceMarker"] + +- name: set-placemarker + tag: "*" + match: "starts-with($NavCommand, 'SetPlacemarker')" + replace: + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "platzhalter" # phrase('set placeholder' to the value) + - 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: "in nichts mehr" # phrase('inside of nothing more') + - pause: long + - set_variables: [SpeakExpression: "'false'"] + else: + - T: "inside" # phrase('inside' a big expression) + - pause: medium + - set_variables: [NavNode: "@id"] + +- name: where-am-i-middle + tag: "*" + match: "$NavCommand = 'WhereAmI' or $NavCommand = 'WhereAmIAll'" + replace: + - T: "in" # phrase('inside' a big expression) + - 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/de/overview.yaml b/Rules/Languages/de/overview.yaml new file mode 100644 index 00000000..346734e2 --- /dev/null +++ b/Rules/Languages/de/overview.yaml @@ -0,0 +1,121 @@ +--- +# 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: [mfrac, fraction] + match: "." + replace: + - test: + if: "IsNode(*[1], 'simple') and IsNode(*[2], 'simple')" + then: + - x: "*[1]" + - T: "durch" + - x: "*[2]" + else: + - T: "bruch" + +- name: overview-default + tag: [msqrt, "square-root"] + match: "." + replace: + - T: "quadratwurzel" + - test: + if: "IsNode(*[1], 'simple')" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: "von"] + - x: "*[1]" + +- name: overview-default + tag: [mroot, root] + match: "." + replace: + - test: + if: "*[2][self::m:mn]" + then_test: + - if: "*[2][.='2']" + then: [T: "quadratwurzel"] + - else_if: "*[2][.='3']" + then: [T: "dritte wurzel"] + - else_if: "*[2][not(contains(., '.'))]" + then: [x: "ToOrdinal(*[2])", T: "wurzel"] + else: + - test: + if: "*[2][self::m:mi][string-length(.)=1]" + then: + - x: "*[2]" + - pronounce: [{text: "-te"}, {ipa: "te"}, {sapi5: "te"}, {eloquence: "T"}] + else: {x: "*[2]"} + - T: "wurzel" + - test: + if: "IsNode(*[1], 'simple')" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: "von"] + - x: "*[1]" + +- name: matrix-override + tag: mrow + match: + - "*[2][self::m:mtable] and" + - "(IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|'))" + replace: + - T: "die" + - x: count(*[2]/*) + - T: "von" + - 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: "determinante"] + else: [T: "matrix"] + +- name: overview-default + tag: mtable + match: "." + replace: + - T: "die" + - x: count(*[2]/*) + - T: "von" + - x: count(*[2]/*[self::m:mtr][1]/*) + - T: "tabelle" + +- 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: "und so weiter" + +- T "dd" +- include: "SimpleSpeak_Rules.yaml" diff --git a/Rules/Languages/de/unicode-full.yaml b/Rules/Languages/de/unicode-full.yaml new file mode 100644 index 00000000..a3a8d6be --- /dev/null +++ b/Rules/Languages/de/unicode-full.yaml @@ -0,0 +1,3623 @@ +--- + + + - "¢": [T: "Cent"] # 0xa2 (en: 'cents') + - "£": [T: "Pfund"] # 0xa3 (en: 'pounds') + - "¤": [T: "währungszeichen"] # 0xa4 (en: 'currency sign') + - "¥": [T: "yen"] # 0xa5 + - "¦": [T: "gebrochene Linie"] # 0xa6 (en: 'broken bar') + - "§": [T: "Abschnitt"] # 0xa7 (en: 'section') + - "¨": [T: "diaeresis"] # 0xa8 (en: 'double dot') + - "©": [T: "Copyright"] # 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: + if: "ancestor::m:modified-variable and preceding-sibling::*[1][self::m:mi]" + then: [T: "bar"] # (google translation) + 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: "Acuteakzent"] # 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: "modifikator klein h"] # 0x2b0 (en: 'modifier small h', google translation) + - "ʱ": [T: "modifikator klein h mit haken"] # 0x2b1 (en: 'modifier small h with hook', google translation) + - "ʲ": [T: "modifikator klein j"] # 0x2b2 (en: 'modifier small j', google translation) + - "ʳ": [T: "modifikator klein r"] # 0x2b3 (en: 'modifier small r', google translation) + - "ʴ": [T: "modifikator gedrehtes kleines r"] # 0x2b4 (en: 'modifier small turned r', google translation) + - "ʵ": [T: "modifikator gedrehtes kleines r mit haken"] # 0x2b5 (en: 'modifier small turned r with hook', google translation) + - "ʶ": # 0x2b6 + - T: "modifikator klein invertiert" # (en: 'modifier small inverted', google translation) + - spell: "translate('R', 'R', 'R')" + + - "ʷ": [T: "modifikator klein w"] # 0x2b7 (en: 'modifier small w', google translation) + - "ʸ": [T: "modifikator klein y"] # 0x2b8 (en: 'modifier small y', google translation) + - "ʹ": [T: "Strich"] # 0x2b9 (en: 'modifier prime', google: 'modifikator prime') + - "ʺ": [T: "zwei Striche"] # 0x2ba (en: 'modifier double prime', google: 'modifikator double prime') + - "ʻ": [T: "modifikator wurde komma"] # 0x2bb (en: 'modifier turned comma', google translation) + - "ʼ": [T: "modifikator apostroph"] # 0x2bc (en: 'modifier apostrophe', google translation) + - "ʽ": [T: "modifikator umgekehrtes Komma"] # 0x2bd (en: 'modifier reversed comma', google translation) + - "ʾ": [T: "modifikator halber ring rechts"] # 0x2be (en: 'modifier right half ring', google: 'modifikator rechts halbe ring') + - "ʿ": [T: "modifikator halber ring links"] # 0x2bf (en: 'modifier left half ring', google: 'modifikator verließ den halben ring') + - "ˀ": [T: "modifikator glottal stop"] # 0x2c0 (en: 'modifier glottal stop', google translation) + - "ˁ": [T: "modifikator umgekehrt glottal stop"] # 0x2c1 (en: 'modifier reversed glottal stop', google translation) + - "˂": [T: "modifikator pfeilspitze von links"] # 0x2c2 (en: 'modifier left arrowhead', google translation) + - "˃": [T: "modifikator pfeilspitze von rechts"] # 0x2c3 (en: 'modifier right arrowhead', google translation) + - "˄": [T: "modifikator pfeil aufwärts"] # 0x2c4 (en: 'modifier up arrowhead', google translation) + - "˅": [T: "modifikator pfeil abwärts"] # 0x2c5 (en: 'modifier down arrowhead', google translation) + - "ˆ": [T: "modifier letter circumflex accent"] # 0x2c6 (en: 'modifier circumflex accent', google: 'modifikator circumflex akzent') + - "ˇ": [T: "caron"] # 0x2c7 + - "ˈ": [T: "modifikator vertikale linie"] # 0x2c8 (en: 'modifier vertical line', google translation) + - "ˉ": [T: "modifikator macron"] # 0x2c9 (en: 'modifier macron', google translation) + - "ˊ": [T: "modifikator akuter akzent"] # 0x2ca (en: 'modifier acute accent', google translation) + - "ˋ": [T: "modifikator grabakzent"] # 0x2cb (en: 'modifier grave accent', google translation) + - "ˌ": [T: "modifikator niedrige vertikale linie"] # 0x2cc (en: 'modifier low vertical line', google translation) + - "ˍ": [T: "modifikator low macron"] # 0x2cd (en: 'modifier low macron', google translation) + - "ˎ": [T: "modifikator niedriger schwerer akzent"] # 0x2ce (en: 'modifier low grave accent', google translation) + - "ˏ": [T: "modifikator niedriger akuter akzent"] # 0x2cf (en: 'modifier low acute accent', google translation) + - "ː": [T: "modifikator dreieckiger doppelpunkt"] # 0x2d0 (en: 'modifier triangular colon', google translation) + - "ˑ": [T: "modifikator halbdreiecksdoppelpunkt"] # 0x2d1 (en: 'modifier half triangular colon', google translation) + - "˒": [T: "modifikator zentrierter halbring von rechts"] # 0x2d2 (en: 'modifier centered right half ring', google translation) + - "˓": [T: "modifikator zentrierter halbring von links"] # 0x2d3 (en: 'modifier centered left half ring', google translation) + - "˔": [T: "modifikator aufgerichtet"] # 0x2d4 (en: 'modifier up tadck', google translation) + - "˕": [T: "modifikator abwärts gerichtet"] # 0x2d5 (en: 'modifier down tack', google translation) + - "˖": [T: "modifikator pluszeichen"] # 0x2d6 (en: 'modifier plus sign', google translation) + - "˗": [T: "modifikator minuszeichen"] # 0x2d7 (en: 'modifier minus sign', google translation) + - "˘": [T: "kurz"] # 0x2d8 (SRE: 'Breve') + - "˙": [T: "Punkt oberhalb"] # 0x2d9 (en: 'dot', MathPlayer: 'Punkt darüber', google: 'punkt') + - "˚": [T: "Ring oberhalb"] # 0x2da (en: 'ring above', MathPlayer: 'Ring darüber', google: 'oben läuten') + - "˛": [T: "ogonek"] # 0x2db (SRE: 'Ogonek') + - "˜": [T: "Tilde"] # 0x2dc (en: 'small tilde') + - "˝": [T: "Doppleakutakzent"] # 0x2dd (en: 'double acute accent', MathPlayer: 'double acute accent', google: 'doppelter akuter akzent') + - "˞": [T: "modifikator rhotischer haken"] # 0x2de (en: 'modifier rhotic hook', google translation) + - "˟": [T: "modifikator kreuzakzent"] # 0x2df (en: 'modifier cross accent', google translation) + - "ˠ": [T: "modifikator kleines gamma"] # 0x2e0 (en: 'modifier small gamma', google translation) + - "ˡ": [T: "modifikator klein l"] # 0x2e1 (en: 'modifier small l', google translation) + - "ˢ": [T: "modifikator klein s"] # 0x2e2 (en: 'modifier small s', google translation) + - "ˣ": [T: "modifikator klein x"] # 0x2e3 (en: 'modifier small x', google translation) + - "ˤ": [T: "modifikator kleiner umgekehrter glottal stopp"] # 0x2e4 (en: 'modifier small reversed glottal stop', google translation) + - "˥": [T: "modifikator extra hoher Tonbalken"] # 0x2e5 (en: 'modifier extra-high tone bar', google translation) + - "˦": [T: "modifikator hoher Tonbalken"] # 0x2e6 (en: 'modifier high tone bar', google translation) + - "˧": [T: "modifikator mittlerer Balken"] # 0x2e7 (en: 'modifier mid tone bar', google translation) + - "˨": [T: "modifikator niedrige tonleiste"] # 0x2e8 (en: 'modifier low tone bar', google translation) + - "˩": [T: "modifikator extra niedrige tonleiste"] # 0x2e9 (en: 'modifier extra-low tone bar', google translation) + - "˪": [T: "modifikator yin abgabetonmarke"] # 0x2ea (en: 'modifier yin departing tone mark', google translation) + - "˫": [T: "modifikator yang abgassing tonmarke"] # 0x2eb (en: 'modifier yang departing tone mark', google translation) + - "ˬ": [T: "modifikator -stimmen"] # 0x2ec (en: 'modifier voicing', google translation) + - "˭": [T: "modifikator ungebildet"] # 0x2ed (en: 'modifier unaspirated', google translation) + - "ˮ": [T: "modifikator doppel apostroph"] # 0x2ee (en: 'modifier double apostrophe', google translation) + - "˯": [T: "modifikator niedrige pfeilspitze nach unten gerichtet"] # 0x2ef (en: 'modifier low down arrowhead', google translation) + - "˰": [T: "modifikator niedrige pfeilspitze aufwärts gerichtet"] # 0x2f0 (en: 'modifier low up arrowhead', google translation) + - "˱": [T: "modifikator niedrige pfeilspitze nach links gerichtet"] # 0x2f1 (en: 'modifier low left arrowhead', google translation) + - "˲": [T: "modifikator niedrige pfeilspitze nach rechts gerichtet"] # 0x2f2 (en: 'modifier low right arrowhead', google translation) + - "˳": [T: "modifikator niedriger ring"] # 0x2f3 (en: 'modifier low ring', google translation) + - "˴": [T: "modifikator mittlerer grabakzent"] # 0x2f4 (en: 'modifier middle grave accent', google translation) + - "˵": [T: "modifikator mittlerer doppelt grabakzent"] # 0x2f5 (en: 'modifier middle double grave accent', google translation) + - "˶": [T: "modifikator mit mittlerem doppelt akutem akzent"] # 0x2f6 (en: 'modifier middle double acute accent', google translation) + - "˷": [T: "modifikator niedrige tilde"] # 0x2f7 (en: 'modifier low tilde', google translation) + - "˸": [T: "modifikator hoch gestellter Doppelpunkt"] # 0x2f8 (en: 'modifier raised colon', google translation) + - "˹": [T: "der modifikator beginnt mit hohem ton"] # 0x2f9 (en: 'modifier begin high tone', google translation) + - "˺": [T: "modifikator endet mit hohem ton"] # 0x2fa (en: 'modifier end high tone', google translation) + - "˻": [T: "der modifikator beginnt niedrig"] # 0x2fb (en: 'modifier begin low tone', google translation) + - "˼": [T: "modifikator ende niedriger ton"] # 0x2fc (en: 'modifier end low tone', google translation) + - "˽": [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: "Akzent auf dem Grave"] # 0x300 (en: 'grave accent embellishment', google: 'grabakzentverzierung') + - "́": [T: "Akzentverzierung"] # 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: "Macronkombination"] # 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: "combining ring above"] # 0x30a (en: 'ring above embellishment', google: 'ring über verzierung') + - "̋": [T: "doppelte akute akzentverzierung"] # 0x30b (en: 'double acute accent embellishment', google translation) + - "̌": [T: "combining caron"] # 0x30c (en: 'check', google: 'überprüfen') + - "̍": [T: "vertikale linie über verzierung"] # 0x30d (en: 'vertical line above embellishment', google translation) + - "̎": [T: "doppelte vertikale linie über verzierung"] # 0x30e (en: 'double vertical line above embellishment', google translation) + - "̏": [T: "doppelgrabes akzentverzierung"] # 0x30f (en: 'double grave accent embellishment', google translation) + - "̐": [T: "candrabindu -verzierung"] # 0x310 (en: 'candrabindu embellishment', google translation) + - "̑": [T: "combining inverted breve"] # 0x311 (en: 'inverted breve embellishment', google: 'umgekehrte breve -verzierung') + - "̒": [T: "komma über der verzierung gedreht"] # 0x312 (en: 'turned comma above embellishment', google translation) + - "̓": [T: "komma über verzierung"] # 0x313 (en: 'comma above embellishment', google translation) + - "̔": [T: "umgekehrter komma über verzierung"] # 0x314 (en: 'reversed comma above embellishment', google translation) + - "̕": [T: "komma über der rechten verzierung"] # 0x315 (en: 'comma above right embellishment', google translation) + - "̖": [T: "grabakzent unter der verzierung"] # 0x316 (en: 'grave accent below embellishment', google translation) + - "̗": [T: "akuter akzent unter der verzierung"] # 0x317 (en: 'acute accent below embellishment', google translation) + - "̘": [T: "linke Klammer unter Verzierung"] # 0x318 (en: 'left tack below embellishment', google translation) + - "̙": [T: "rechte Klammer unter Verzierung"] # 0x319 (en: 'right tack below embellishment', google translation) + - "̚": [T: "linker winkel über verzierung"] # 0x31a (en: 'left angle above embellishment', google translation) + - "̛": [T: "hornverzierung"] # 0x31b (en: 'horn embellishment', google translation) + - "̜": [T: "halber ring links unter der verzierung"] # 0x31c (en: 'left half ring below embellishment', google translation) + - "̝": [T: "aufwärtsklammer unter Verzierung"] # 0x31d (en: 'up tack below embellishment', google translation) + - "̞": [T: "abwärtsklammer unter der verzierung"] # 0x31e (en: 'down tack below embellishment', google translation) + - "̟": [T: "plus unterschreiben unten verschönern"] # 0x31f (en: 'plus sign below embellishment', google translation) + - "̠": [T: "minus zeichen unten verzierung"] # 0x320 (en: 'minus sign below embellishment', google translation) + - "̡": [T: "palatalisierter haken unter der verzierung"] # 0x321 (en: 'palatalized hook below embellishment', google translation) + - "̢": [T: "retroflex -haken unter der verzierung"] # 0x322 (en: 'retroflex hook below embellishment', google translation) + - "̣": [T: "dot below embellishment"] # 0x323 (google: 'punkt unter der verzierung') + - "̤": [T: "double dot below embellishment"] # 0x324 (en: 'diaeresis below embellishment', google: 'diaerese unter der verzierung') + - "̥": [T: "ring unter der verzierung"] # 0x325 (en: 'ring below embellishment', google translation) + - "̦": [T: "komma unter der verzierung"] # 0x326 (en: 'comma below embellishment', google translation) + - "̧": [T: "cedilla embellishment"] # 0x327 (google: 'cedilla -verzierung') + - "̨": [T: "ogonek -verzierung"] # 0x328 (en: 'ogonek embellishment', google translation) + - "̩": [T: "vertikale linie unter der verzierung"] # 0x329 (en: 'vertical line below embellishment', google translation) + - "̪": [T: "brücke unterhalb der verzierung"] # 0x32a (en: 'bridge below embellishment', google translation) + - "̫": [T: "umgekehrter doppelbogen unter der verzierung"] # 0x32b (en: 'inverted double arch below embellishment', google translation) + - "̬": [T: "caron unter der verzierung"] # 0x32c (en: 'caron below embellishment', google translation) + - "̭": [T: "circumflex -akzent unter der verzierung"] # 0x32d (en: 'circumflex accent below embellishment', google translation) + - "̮": [T: "combining breve below"] # 0x32e (en: 'breve below embellishment', google: 'breve unter der verzierung') + - "̯": [T: "umgekehrte breve unterhalb der verzierung"] # 0x32f (en: 'inverted breve below embellishment', google translation) + - "̰": [T: "tilde below embellishment"] # 0x330 (google: 'tilde unter der verzierung') + - "̱": [T: "macron below embellishment"] # 0x331 (google: 'macron unter der verzierung') + - "̲": [T: "combining low line"] # 0x332 (en: 'low line embellishment', google: 'niedriglinienverzerrung') + - "̳": [T: "doppelte leitung verschönern"] # 0x333 (en: 'double low line embellishment', google translation) + - "̴": [T: "tilde overlay -verzierung"] # 0x334 (en: 'tilde overlay embellishment', google translation) + - "̵": [T: "kurzhub -overlay -verzierung"] # 0x335 (en: 'short stroke overlay embellishment', google translation) + - "̶": [T: "langstreicher -overlay -verzierung"] # 0x336 (en: 'long stroke overlay embellishment', google translation) + - "̷": [T: "kurze solidus -overlay -verzierung"] # 0x337 (en: 'short solidus overlay embellishment', google translation) + - "̸": [T: "forward slash embellishment"] # 0x338 (en: 'long solidus overlay embellishment', google: 'long solidus overlay -verzierung') + - "̹": [T: "halber ring rechts unter der verzierung"] # 0x339 (en: 'right half ring below embellishment', google translation) + - "̺": [T: "umgekehrte brücke unter der verzierung"] # 0x33a (en: 'inverted bridge below embellishment', google translation) + - "̻": [T: "quadrat unterhalb der verzierung"] # 0x33b (en: 'square below embellishment', google translation) + - "̼": [T: "möwen unter der verzierung"] # 0x33c (en: 'seagull below embellishment', google translation) + - "̽": [T: "x über verzierung"] # 0x33d (en: 'x above embellishment', google translation) + - "̾": [T: "vertikale tilde verzierung"] # 0x33e (en: 'vertical tilde embellishment', google translation) + - "̿": [T: "doppelte überlaufverzerrung"] # 0x33f (en: 'double overline embellishment', google translation) + - "̀": [T: "grabtonmarke verzierung"] # 0x340 (en: 'grave tone mark embellishment', google translation) + - "́": [T: "akute tonmarkierungsverzerrung"] # 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: "großbuchstaben"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [spell: "translate('.', 'ΪΫϏ', 'ιυϗ')"] + - T: "mit dialytika" # (en: 'with dialytika', google translation) + - "ϊ": [T: "iota mit dialytika"] # 0x3ca (en: 'iota with dialytika', google translation) + - "ϋ": [T: "upsilon mit dialytika"] # 0x3cb (en: 'upsilon with dialytika', google translation) + - "ό": [T: "omicron mit tonos"] # 0x3cc (en: 'omicron with tonos', google translation) + - "ύ": [T: "upsilon mit tonos"] # 0x3cd (en: 'upsilon with tonos', google translation) + - "ώ": [T: "omega mit tonos"] # 0x3ce (en: 'omega with tonos', google translation) + - "ϐ": [T: "beta"] # 0x3d0 (MathPlayer: 'greek beta') + - "ϑ": [T: "variant theta"] # 0x3d1 (en: 'theta', google: 'theta') + - "ϒ": [T: "variant upsilon with hook"] # 0x3d2 (en: 'upsilon with hook', google: 'upsilon mit haken') + - "ϓ": [T: "upsilon mit akuter und haken"] # 0x3d3 (en: 'upsilon with acute and hook', google translation) + - "ϔ": [T: "upsilon mit diaerse und haken"] # 0x3d4 (en: 'upsilon with diaeresis and hook', google translation) + - "ϕ": [T: "straight phi"] # 0x3d5 (en: 'phi', google: 'phi') + - "ϖ": [T: "variant pi"] # 0x3d6 (en: 'pi', google: 'pi') + - "ϗ": [T: "kai"] # 0x3d7 (MathPlayer: 'variant kai') + - "ϵ": [T: "epsilon"] # 0x3f5 + - "϶": [T: "umgekehrtes epsilon"] # 0x3f6 (en: 'reversed epsilon', MathPlayer: 'reversed epsilon', google: 'umgekehrter epsilon') + - "А-Я": # 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: "großbuchstaben"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [spell: "translate('.', 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ', 'абвгдежзийклмнопрстуфхцчшщъыьэюя')"] + - "а": [T: "a"] # 0x430 (google: 'а') + - "б": [T: "be"] # 0x431 (google: 'sei') + - "в": [T: "ve"] # 0x432 + - "г": [T: "ghe"] # 0x433 + - "д": [T: "de"] # 0x434 + - "е": [T: "ie"] # 0x435 (google: 'dh') + - "ж": [T: "zhe"] # 0x436 + - "з": [T: "ze"] # 0x437 + - "и": [T: "i"] # 0x438 (google: 'и') + - "й": [T: "short i"] # 0x439 (google: 'kurz ich') + - "к": [T: "ka"] # 0x43a + - "л": [T: "el"] # 0x43b + - "м": [T: "em"] # 0x43c + - "н": [T: "en"] # 0x43d + - "о": [T: "o"] # 0x43e (google: 'о') + - "п": [T: "pe"] # 0x43f (google: 'sport') + - "р": [T: "er"] # 0x440 (google: 'ähm') + - "с": [T: "es"] # 0x441 + - "т": [T: "te"] # 0x442 + - "у": [T: "u"] # 0x443 (google: 'у') + - "ф": [T: "ef"] # 0x444 + - "х": [T: "ha"] # 0x445 + - "ц": [T: "tse"] # 0x446 + - "ч": [T: "che"] # 0x447 + - "ш": [T: "sha"] # 0x448 + - "щ": [T: "shcha"] # 0x449 + - "ъ": [T: "hard sign"] # 0x44a (google: 'hartes zeichen') + - "ы": [T: "yeru"] # 0x44b + - "ь": [T: "soft sign"] # 0x44c (google: 'weiches zeichen') + - "э": [T: "e"] # 0x44d (google: 'э') + - "ю": [T: "yu"] # 0x44e + - "я": [T: "ya"] # 0x44f + - "‐": [T: "Bindestrich"] # 0x2010 (en: 'hyphen', MathPlayer: 'minus', google: 'bindestrich') + - "‑": [T: "Nicht brechender Bindestrich"] # 0x2011 (en: 'hyphen', google: 'bindestrich') + - "‒": [T: "Abbildung Bindestrich"] # 0x2012 (en: 'figure dash', google: 'figur dash') + - "–": [T: "en dash"] # 0x2013 (SRE: 'En Dash') + - "—": [T: "em dash"] # 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') + + - "•": # 0x2022 + - test: + if: "@data-chem-formula-op" + 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: "strich invertiert"] # 0x2035 (en: 'reversed prime', MathPlayer: 'reversed prime', google: 'umgekehrt prime') + - "‶": [T: "zwei Striche invertiert"] # 0x2036 (en: 'reversed double prime', MathPlayer: 'reversed double prime', google: 'umgekehrt doppelte prime') + - "‷": [T: "drei Striche invertiert"] # 0x2037 (en: 'reversed triple prime', google: 'triple prime umgekehrt') + - "‸": [T: "Caret"] # 0x2038 (en: 'to the', google: 'zum') + - "‹": [T: "einfaches linkes Anführungszeichen"] # 0x2039 (en: 'single left pointing angle quote mark', MathPlayer: 'single left pointing angle quote mark', google: 'single linke zitat angle -zitat marke') + - "›": [T: "einfaches rechtes Anführungszeichen"] # 0x203a (en: 'single right pointing angle quote mark', MathPlayer: 'single right pointing angle quote mark', google: 'single rechts zeigewinkel zitatmarke') + - "‼": [T: "Doppelausrufezeichen"] # 0x203c (en: 'double factorial', google: 'doppelfaktor') + - "⁄": [T: "Schrägstrich"] # 0x2044 (en: 'divided by', MathPlayer: 'slash', google: 'geteilt durch') + - "⁅": [T: "Linke eckige Klammer mit Feder"] # 0x2045 (en: 'left square bracket with quill', google: 'linksquadratische klammer mit feder') + - "⁆": [T: "Rechte eckige Klammer mit Feder"] # 0x2046 (en: 'right square bracket with quill', google: 'rechte quadratische halterung mit feder') + - "⁗": [T: "vier Striche"] # 0x2057 (en: 'quadruple prime', MathPlayer: 'quadruple prime', google: 'vierfache prime') + - "⁠": [T: ""] # 0x2060 + - "‵": [T: "strich invertiert"] # 0x2035 (en: 'reversed prime', MathPlayer: 'reversed prime', google: 'umgekehrt prime') + - "‶": [T: "zwei Striche invertiert"] # 0x2036 (en: 'reversed double prime', MathPlayer: 'reversed double prime', google: 'umgekehrt doppelte prime') + - "‷": [T: "drei Striche invertiert"] # 0x2037 (en: 'reversed triple prime', google: 'triple prime umgekehrt') + - "⁰": [T: "zur nullten Potenz"] # 0x2070 (en: 'to the zeroth power', google translation) + - "ⁱ": [T: "zur i-ten Potenz"] # 0x2071 (en: 'to the ith power', google: 'zur eihth -macht') + - "⁴": [T: "zur vierten Potenz"] # 0x2074 (en: 'to the fourth power', google translation) + - "⁵": [T: "zur fünften Potenz"] # 0x2075 (en: 'to the fifth power', google translation) + - "⁶": [T: "zur sechsten Potenz"] # 0x2076 (en: 'to the sixth power', google translation) + - "⁷": [T: "zur siebten Potenz"] # 0x2077 (en: 'to the seventh power', google translation) + - "⁸": [T: "zur achten Potenz"] # 0x2078 (en: 'to the eighth power', google translation) + - "⁹": [T: "zur neunten Potenz"] # 0x2079 (en: 'to the ninth power', google translation) + - "⁺": [T: "Hochgestelltes Pluszeichen"] # 0x207a (en: 'superscript plus sign', google: 'superscript plus zeichen') + - "⁻": [T: "Hochgestelltes Minus"] # 0x207b (en: 'superscript minus', google: 'superscript minus') + - "⁼": [T: "Hochgestelltes Gleichheitszeichen"] # 0x207c (en: 'superscript equals sign', google: 'superscript ist gleichzeichen') + - "⁽": [T: "Hochgestellte linke Klammer"] # 0x207d (en: 'superscript left parenthesis', google: 'superscript links klammern') + - "⁾": [T: "Hochgestellte rechte Klammer"] # 0x207e (en: 'superscript right parenthesis', google: 'superscript right parenthesisthese') + - "ⁿ": [T: "hochgestelltes n"] # 0x207f (en: 'to the ennth power', google: 'zur ahnten kraft') + - "₀": [T: "unter null"] # 0x2080 (en: 'sub zero', google translation) + - "₁": [T: "sub eins"] # 0x2081 (en: 'sub one', google translation) + - "₂": [T: "sub zwei"] # 0x2082 (en: 'sub two', google translation) + - "₃": [T: "unter drei"] # 0x2083 (en: 'sub three', google translation) + - "₄": [T: "unter vier"] # 0x2084 (en: 'sub four', google translation) + - "₅": [T: "sub fünf"] # 0x2085 (en: 'sub five', google translation) + - "₆": [T: "sub sechs"] # 0x2086 (en: 'sub six', google translation) + - "₇": [T: "sub sieben"] # 0x2087 (en: 'sub seven', google translation) + - "₈": [T: "sub acht"] # 0x2088 (en: 'sub eight', google translation) + - "₉": [T: "sub neun"] # 0x2089 (google translation) + - "₊": [T: "Index Pluszeichen"] # 0x208a (en: 'subscript plus sign', google: 'index plus -zeichen') + - "₋": [T: "Tiefgestelltes Minuszeichen"] # 0x208b (en: 'subscript minus sign', google: 'index minuszeichen') + - "₌": [T: "Tiefgestelltes Gleichheitszeichen"] # 0x208c (en: 'subscript equals sign', google: 'index gleicher bestandteil des zeichens') + - "₍": [T: "Tiefgestellte linke Klammer"] # 0x208d (en: 'subscript left parenthesis', google: 'untergangsklammern von klammern') + - "₎": [T: "Tiefgestellte rechte Klammer"] # 0x208e (en: 'subscript right parenthesis', google: 'index right parenthesisthese') + - "ₐ": [T: "tiefgestelltes a"] # 0x2090 (en: 'sub A', google: 'sub a') + - "ₑ": [T: "tiefgestelltes e"] # 0x2091 (en: 'sub E', google: 'sub e') + - "ₒ": [T: "tiefgestelltes o"] # 0x2092 (en: 'sub O', google: 'sub o') + - "ₓ": [T: "tiefgestelltes x"] # 0x2093 (en: 'sub X', google: 'sub x') + - "ₕ": [T: "tiefgestelltes h"] # 0x2095 (en: 'sub H', google: 'sub h') + - "ₖ": [T: "tiefgestelltes k"] # 0x2096 (en: 'sub K', google: 'subk') + - "ₗ": [T: "tiefgestelltes l"] # 0x2097 (en: 'sub L', google: 'sub l') + - "ₘ": [T: "tiefgestelltes m"] # 0x2098 (en: 'sub M', google: 'sub m') + - "ₙ": [T: "tiefgestelltes n"] # 0x2099 (en: 'sub N', google: 'sub n') + - "ₚ": [T: "tiefgestelltes p"] # 0x209a (en: 'sub P', google: 'sub p') + - "ₛ": [T: "tiefgestelltes s"] # 0x209b (en: 'sub S', google: 'sub s') + - "ₜ": [T: "tiefgestelltes t"] # 0x209c (en: 'sub T', google: 'sub t') + - "₠": [T: "europäische Währungseinheiten"] # 0x20a0 (en: 'european currenty units', google translation) + - "₡": [T: "colons"] # 0x20a1 (google: 'kolons') + - "₢": [T: "cruzeiro"] # 0x20a2 + - "₣": [T: "franc"] # 0x20a3 + - "₤": [T: "lira"] # 0x20a4 + - "₥": [T: "mills"] # 0x20a5 (google: 'mühlen') + - "₦": [T: "naira"] # 0x20a6 + - "₧": [T: "peseta"] # 0x20a7 + - "₨": [T: "rupees"] # 0x20a8 (google: 'rupien') + - "₩": [T: "won"] # 0x20a9 (google: 'gewonnen') + - "₪": [T: "new sheqels"] # 0x20aa (google: 'neue sheqels') + - "₫": [T: "dong"] # 0x20ab + - "€": [T: "euros"] # 0x20ac (google: 'euro') + - "₭": [T: "kip"] # 0x20ad (google: 'pennen') + - "₮": [T: "tugrik"] # 0x20ae + - "₯": [T: "drachma"] # 0x20af (google: 'drachme') + - "₰": [T: "german pennies"] # 0x20b0 (google: 'deutsche pennys') + - "₱": [T: "pesos"] # 0x20b1 + - "₲": [T: "guaranis"] # 0x20b2 + - "₳": [T: "australs"] # 0x20b3 (google: 'österrale') + - "₴": [T: "hryvnias"] # 0x20b4 + - "₵": [T: "cedis"] # 0x20b5 + - "₶": [T: "livre tournois"] # 0x20b6 (google translation) + - "₷": [T: "spesmilos"] # 0x20b7 (google translation) + - "₸": [T: "tenges"] # 0x20b8 (google translation) + - "₹": [T: "indische rupien"] # 0x20b9 (en: 'indian rupees', google translation) + - "₺": [T: "türkische liras"] # 0x20ba (en: 'turkish liras', google translation) + - "⃐": [T: "linke Harpune über Verzierung"] # 0x20d0 (en: 'left harpoon above embellishment', google: 'links harpoon über verzierung') + - "⃑": [T: 'rechte Harpune über Verzierung"] # 0x20d1 (en: 'right harpoon above embellishment', google: 'rechte harpoon über verzierung') + - "⃒": [T: "Verzierung mit langer vertikaler Linie] # 0x20d2 (en: 'long vertical line overlay embellishment', google translation) + - "⃓": [T: "Verzierung mit kurzer vertikaler Linie"] # 0x20d3 (en: 'short vertical line overlay embellishment', google translation) + - "⃔": [T: "Pfeil gegen den Uhrzeigersinn über Verzierung"] # 0x20d4 (en: 'anticlockwise arrow above embellishment', google translation) + - "⃕": [T: "Pfeil im Uhrzeigersinn über Verzierung"] # 0x20d5 (en: 'clockwise arrow above embellishment', google translation) + - "⃖": [T: "Pfeil nach links über Verzierung"] # 0x20d6 (en: 'left arrow above embellishment', google: 'links pfeil über die verzierung') + - "⃗": [T: "Pfeil nach rechts über Verzierung"] # 0x20d7 (en: 'right arrow above embellishment', google: 'richtiger pfeil über die verzierung') + - "⃘": [T: "Ringüberlagerung als Verzierung"] # 0x20d8 (en: 'ring overlay embellishment', google translation) + - "⃙": [T: "ringüberlagerung im uhrzeigersinn"] # 0x20d9 (en: 'clockwise ring overlay embellishment', google translation) + - "⃚": [T: "ringüberlagerung gegen den uhrzeigersinn"] # 0x20da (en: 'anticlockwise ring overlay embellishment', google translation) + - "⃛": [T: "dreifacher punkt"] # 0x20db (en: 'triple dot', google: 'dreifacher punkt') + - "⃜": [T: "vierfacher punkt"] # 0x20dc (en: 'quadruple dot', google: 'vierfachpunkt punkt') + - "⃝": [T: "umschließender Kreis als Verzierung"] # 0x20dd (en: 'enclosing circle embellishment', google translation) + - "⃞": [T: "umschließendes Quadrat als Verzierung"] # 0x20de (en: 'enclosing square embellishment', google translation) + - "⃟": [T: "umschließender Diamant als Verzierung"] # 0x20df (en: 'enclosing diamond embellishment', google translation) + - "⃠": [T: "schließen sie den kreis -rückstand verschönern"] # 0x20e0 (en: 'enclosing circle backslash embellishment', google translation) + - "⃡": [T: "left right arrow embellishment"] # 0x20e1 (en: 'left right arrow above embellishment', google: 'links rechts pfeil über verzierung') + - "⃢": [T: "einschließende bildschirmverzierung"] # 0x20e2 (en: 'enclosing screen embellishment', google translation) + - "⃣": [T: "Umschließende Tastenkappenverzierung"] # 0x20e3 (en: 'enclosing keycap embellishment', google translation) + - "⃤": [T: "umschließende, nach oben zeigende Dreiecksverzierung"] # 0x20e4 (en: 'enclosing upward pointing triangle embellishment', google translation) + - "⃥": [T: "Umgekehrte Solidus-Überlagerung als Verzierung"] # 0x20e5 (en: 'reverse solidus overlay embellishment', google translation) + - "⃦": [T: "Doppelte vertikale Strichverzierung"] # 0x20e6 (en: 'double verticle stroke embellishment', google translation) + - "⃧": [T: "rentensymbol verzierung"] # 0x20e7 (en: 'Verzierung mit Annuitätensymbol', google translation) + - "⃨": [T: "Dreifach-Unterpunkt"] # 0x20e8 (en: 'triple underdot', google translation) + - "⃩": [T: "breite brücke über verzierung"] # 0x20e9 (en: 'wide bridge above embellishment', google translation) + - "⃪": [T: "Verzierung mit nach links zeigendem Pfeil"] # 0x20ea (en: 'leftwards arrow overlay embellishment', google translation) + - "⃫": [T: "Verzierung mit langem, doppeltem Strichüberzug"] # 0x20eb (en: 'long double solidus overlay embellishment', google translation) + - "⃬": [T: "Rechtshaken mit Widerhaken nach unten verziert"] # 0x20ec (en: 'rightwards harpoon with barb downwards embellishment', google translation) + - "⃭": [T: "Linkshaken mit Widerhaken nach unten verziert"] # 0x20ed (en: 'leftwards harpoon with barb downwards embellishment', google translation) + - "⃮": [T: "Pfeil nach links unter Verzierung"] # 0x20ee (en: 'left arrow below embellishment', google translation) + - "⃯": [T: "Pfeil nach rechts unter Verzierung"] # 0x20ef (en: 'right arrow below embellishment', google translation) + - "⃰": [T: "sternchen über verzierung"] # 0x20f0 (en: 'asterisk above embellishment', google translation) + - "℄": [T: "mittelliniensymbol"] # 0x2104 (en: 'center line symbol', google translation) + - "℅": [T: "im Auftrag von"] # 0x2105 (google: 'pflege von') + - "℆": [T: "cada una"] # 0x2106 (google translation) + - "ℇ": [T: "euler constant"] # 0x2107 (en: 'euler's constant', google: 'eulers konstante') + - "℈": [T: "skrupel"] # 0x2108 (en: 'scruples', google translation) + - "℉": [T: "degrees fahrenheit"] # 0x2109 (google: 'grad fahrenheit') + - "ℊ": [T: "script g"] # 0x210a (google: 'skript g') + - "ℌℑℨℭ": # 0x210c, 0x2111, 0x2128, 0x212d + - T: "script g" # (en: 'fraktur', google: 'fraktur') + - spell: "translate('.', 'ℌℑℨℭ', 'HIZC')" + + - "ℍℙℾℿ": # 0x210d, 0x2119, 0x213e, 0x213f + - test: + if: "$Verbosity!='Terse'" + 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')" + then: [T: "h bar"] # (google translation) + else: [T: "Planck-Konstante über zwei Pi"] # (en: 'reduced planck constant', MathPlayer: 'h bar', google: 'reduzierte planckkonstante') + + - "ℐℒ℘ℬℰℱℳ": # 0x2110, 0x2112, 0x2118, 0x2130, 0x2131, 0x2133 + - T: "Planck-Konstante über zwei Pi" # (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: "turned 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: "script e"] # 0x212f (google: 'skript e') + + # coalesced some chars that use cap letters + - "Ⅎ℺⅁⅂⅃⅄": # 0x2132, 0x213a, 0x2141, 0x2142, 0x2143, 0x2144 + - test: + - if: "'.' = '℺'" + then: [T: "gedreht"] # (en: 'rotated', google translation) + - else_if: "'.' = 'Ⅎ'" + then: [T: "gedreht"] # (en: 'turned', google translation) + - else_if: "'.' = '⅃'" + then: [T: "umgekehrt ohne serif"] # (en: 'reversed sans-serif', google translation) + else: [T: "script e"] # (en: 'turned sans-serif', google: 'drehte ohne serif') + - spell: "translate('.', 'Ⅎ℺⅁⅂⅃⅄', 'FQGLLY')" + + - "ℴ": [T: "script o"] # 0x2134 (google: 'skript o') + - "ℵ": [T: "Alef-Symbol"] # 0x2135 (en: 'first transfinite cardinal', MathPlayer: 'alef', google: 'erster transfinite kardinal') + - "ℶ": [T: "Bet-Symbol"] # 0x2136 (en: 'second transfinite cardinal', MathPlayer: 'bet', google: 'zweiter transfinite kardinal') + - "ℷ": [T: "Gimel-Symbol"] # 0x2137 (en: 'third transfinite cardinal', MathPlayer: 'gimel', google: 'dritter transfinite kardinal') + - "ℸ": [T: "Dalet-Symbol"] # 0x2138 (en: 'fourth transfinite cardinal', MathPlayer: 'dalet', google: 'viertes transfinite kardinal') + - "ℼ": [T: "pi mit Doppelstrich"] # 0x213c (en: 'double struck pi', google: 'doppelt geschlagen pi') + - "ℽ": [T: "gamma mit Doppelstrich"] # 0x213d (en: 'double struck gamma', google: 'doppelt geschlagen gamma') + - "⅀": [T: "Summenzeichen mit Doppelstrich"] # 0x2140 (en: 'double struck n-ary summation', google: 'doppelte n-ary-summierung') + - "⅋": [T: "Ampersand gedreht"] # 0x214b (en: 'turned ampersand', google: 'ampers umgedreht') + - "⅌": [T: "Pro Zeichen"] # 0x214c (en: 'per', google: 'pro') + - "ⅎ": [T: "Gedreht klein F"] # 0x214e (en: 'turned F', google: 'drehte f') + - "⅐": [T: "ein siebtel"] # 0x2150 (en: 'one seventh') + - "⅑": [T: "ein neuntel"] # 0x2151 (en: 'one ninth', google: 'ein neunter') + - "⅒": [T: "ein zehntel"] # 0x2152 (en: 'one tenth') + - "⅓": [T: "ein drittel"] # 0x2153 (en: 'one third', MathPlayer: 'vulgar fraction one third') + - "⅔": [T: "zwei drittel"] # 0x2154 (en: 'two thirds', MathPlayer: 'vulgar fraction two thirds') + - "⅕": [T: "ein fünftel"] # 0x2155 (en: 'one fifth', MathPlayer: 'vulgar fraction one fifth') + - "⅖": [T: "zwei fünftel"] # 0x2156 (en: 'two fifths', MathPlayer: 'vulgar fraction two fifths') + - "⅗": [T: "drei fünftel"] # 0x2157 (en: 'three fifths', MathPlayer: 'vulgar fraction three fifths') + - "⅘": [T: "vier fünftel"] # 0x2158 (en: 'four fifths', MathPlayer: 'vulgar fraction four fifths') + - "⅙": [T: "ein sechstel"] # 0x2159 (en: 'one sixth', MathPlayer: 'vulgar fraction one sixth') + - "⅚": [T: "fünf sechstel"] # 0x215a (en: 'five sixths', MathPlayer: 'vulgar fraction five sixths') + - "⅛": [T: "ein achtel"] # 0x215b (en: 'one eighth', MathPlayer: 'vulgar fraction one eighth', google: 'ein ath') + - "⅜": [T: "drei achtel"] # 0x215c (en: 'three eighths', MathPlayer: 'vulgar fraction three eighths', google: 'drei aths') + - "⅝": [T: "fünf achtel"] # 0x215d (en: 'five eighths', MathPlayer: 'vulgar fraction five eighths', google: 'fünf aths') + - "⅞": [T: "sieben achtel"] # 0x215e (en: 'seven eighths', MathPlayer: 'vulgar fraction seven eighths', google: 'sieben aths') + - "⅟": [T: "Bruchzähler eins"] # 0x215f (en: 'one over', google: 'eins vorbei') + - "Ⅰ": [T: "Ⅰ"] # 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: "Ⅴ"] # 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: "Ⅹ"] # 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: "Ⅼ"] # 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 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: "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: "Linker rechter Pfeil"] # 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') + - "↗": # 0x2197 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "annähernd von unten"] # (en: 'approaches from below', google translation) + else: [T: "Nordostpfeil"] # (en: 'north east arrow', MathPlayer: 'north east arrow', google: 'nordostpfeil') + + - "↘": # 0x2198 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "nähert sich von oben"] # (en: 'approaches from above', google translation) + else: [T: "Südostpfeil"] # (en: 'south east arrow', MathPlayer: 'south east arrow', google: 'south east pfeil') + + - "↙": [T: "Südwestpfeil"] # 0x2199 (en: 'south west arrow', MathPlayer: 'south west arrow', google: 'südwestpfeil') + - "↚": [T: "Pfeil nach links mit Strich"] # 0x219a (en: 'leftwards arrow with stroke', MathPlayer: 'leftwards arrow with stroke', google: 'links pfeil mit schlaganfall') + - "↛": [T: "Pfeil nach rechts mit Strich"] # 0x219b (en: 'rightwards arrow with stroke', MathPlayer: 'rightwards arrow with stroke', google: 'richtiger pfeil mit schlaganfall') + - "↜": [T: "Wellenpfeil nach links"] # 0x219c (en: 'leftwards wave arrow', MathPlayer: 'leftwards wave arrow', google: 'linkswellenpfeil') + - "↝": [T: "Wellenpfeil nach rechts"] # 0x219d (en: 'rightwards wave arrow', MathPlayer: 'rightwards wave arrow', google: 'rightwards wave pfeil') + - "↞": [T: "Pfeil mit zwei Spitzen nach links "] # 0x219e (en: 'leftwards two headed arrow', MathPlayer: 'leftwards two headed arrow', google: 'links zwei köpfe pfeil') + - "↟": [T: "Aufwärts gerichteter Doppelpfeil"] # 0x219f (en: 'upwards two headed arrow', MathPlayer: 'upwards two headed arrow', google: 'auf zwei köpfe pfeil') + - "↠": [T: "Pfeil mit zwei Spitzen nach rechts"] # 0x21a0 (en: 'rightwards two headed arrow', MathPlayer: 'rightwards two headed arrow', google: 'richtig zwei köpfe pfeil') + - "↡": [T: "Abwärts gerichteter Doppelpfeil"] # 0x21a1 (en: 'downwards two headed arrow', MathPlayer: 'downwards two headed arrow', google: 'nach unten zwei köpfe pfeil') + - "↢": [T: "Pfeil nach links mit Schwanz"] # 0x21a2 (en: 'leftwards arrow with tail', MathPlayer: 'leftwards arrow with tail', google: 'linkspfeil mit schwanz') + - "↣": [T: "Pfeil nach rechts mit Schwanz"] # 0x21a3 (en: 'rightwards arrow with tail', MathPlayer: 'rightwards arrow with tail', google: 'richtiger pfeil mit schwanz') + - "↤": [T: "Pfeil nach links von der Leiste"] # 0x21a4 (en: 'leftwards arrow from bar', MathPlayer: 'leftwards arrow from bar', google: 'links pfeil aus der bar') + - "↥": [T: "Aufwärtspfeil von der Leiste"] # 0x21a5 (en: 'upwards arrow from bar', MathPlayer: 'upwards arrow from bar', google: 'aufwärter pfeil aus der bar') + - "↦": [T: "Pfeil nach rechts von der Leiste"] # 0x21a6 (en: 'rightwards arrow from bar', MathPlayer: 'rightwards arrow from bar', google: 'richtiger pfeil aus der bar') + - "↧": [T: "Abwärtspfeil von der Leiste"] # 0x21a7 (en: 'downwards arrow from bar', MathPlayer: 'downwards arrow from bar', google: 'nach unten pfeil aus der bar') + - "↨": [T: "Aufwärts-/Abwärtspfeil mit Sockel"] # 0x21a8 (en: 'up down arrow with base', MathPlayer: 'up down arrow with base', google: 'mit der basis auf pfeil runter') + - "↩": [T: "Pfeil nach links mit Haken"] # 0x21a9 (en: 'leftwards arrow with hook', MathPlayer: 'leftwards arrow with hook', google: 'links pfeil mit haken') + - "↪": [T: "Pfeil nach rechts mit Haken"] # 0x21aa (en: 'rightwards arrow with hook', MathPlayer: 'rightwards arrow with hook', google: 'richtiger pfeil mit haken') + - "↫": [T: "Pfeil nach links mit Schleife"] # 0x21ab (en: 'leftwards arrow with loop', MathPlayer: 'leftwards arrow with loop', google: 'linkspfeil mit schleife') + - "↬": [T: "Pfeil nach rechts mit Schleife"] # 0x21ac (en: 'rightwards arrow with loop', MathPlayer: 'rightwards arrow with loop', google: 'richtiger pfeil mit schleife') + - "↭": [T: "Linker rechter Wellenpfeil"] # 0x21ad (en: 'left right wave arrow', MathPlayer: 'left right wave arrow', google: 'linke rechte wellenpfeil') + - "↮": [T: "Linker rechter Pfeil mit Strich"] # 0x21ae (en: 'left right arrow with stroke', MathPlayer: 'left right arrow with stroke', google: 'links rechts pfeil mit schlaganfall') + - "↯": [T: "Zickzack-Pfeil nach unten"] # 0x21af (en: 'downwards zigzag arrow', MathPlayer: 'downwards zigzag arrow', google: 'nach unten zickzack pfeil') + - "↰": [T: "Aufwärtspfeil mit Spitze nach links"] # 0x21b0 (en: 'upwards arrow with tip leftwards', MathPlayer: 'upwards arrow with tip leftwards', google: 'aufwärts mit tipp links nach oben') + - "↱": [T: "Aufwärtspfeil mit Spitze nach rechts"] # 0x21b1 (en: 'upwards arrow with tip rightwards', MathPlayer: 'upwards arrow with tip rightwards', google: 'aufwärts mit tipp nach oben nach oben') + - "↲": [T: "Abwärtspfeil mit Spitze nach links"] # 0x21b2 (en: 'downwards arrow with tip leftwards', MathPlayer: 'downwards arrow with tip leftwards', google: 'nach links nach unten pfeil nach unten') + - "↳": [T: "Abwärtspfeil mit Spitze nach rechts"] # 0x21b3 (en: 'downwards arrow with tip rightwards', MathPlayer: 'downwards arrow with tip rightwards', google: 'nach unten pfeil mit tipp nach rechts') + - "↴": [T: "Pfeil nach rechts mit nach unten gerichteter Ecke"] # 0x21b4 (en: 'rightwards arrow with corner downwards', MathPlayer: 'rightwards arrow with corner downwards', google: 'richtiger pfeil mit ecke nach unten') + - "↵": [T: "Pfeil nach unten mit Ecke nach links"] # 0x21b5 (en: 'downwards arrow with corner leftwards', MathPlayer: 'downwards arrow with corner leftwards', google: 'nach links von ecke nach unten pfeil nach unten') + - "↶": [T: "oberer halbkreisförmiger Pfeil gegen den Uhrzeigersinn "] # 0x21b6 (en: 'anticlockwise top semicircle arrow', MathPlayer: 'anticlockwise top semicircle arrow', google: 'top -semicircle -pfeil gegen den uhrzeigersinn') + - "↷": [T: "oberer halbkreisförmiger Pfeil im Uhrzeigersinn"] # 0x21b7 (en: 'clockwise top semicircle arrow', MathPlayer: 'clockwise top semicircle arrow', google: 'im uhrzeigersinn oberen halbkreispfeil') + - "↸": [T: "Nordwestpfeil zu langem Sockel"] # 0x21b8 (en: 'north west arrow to long bar', MathPlayer: 'north west arrow to long bar', google: 'nordwestpfeil in die lange bar') + - "↹": [T: "Pfeil nach links über Pfeil nach rechts"] # 0x21b9 (en: 'leftwards arrow to bar over rightwards arrow to bar', MathPlayer: 'leftwards arrow to bar over rightwards arrow to bar', google: 'der pfeil nach links, um über den pfeil nach rechts in die bar zu barken') + - "↺": [T: "Offener Kreispfeil gegen den Uhrzeigersinn"] # 0x21ba (en: 'anticlockwise open circle arrow', MathPlayer: 'anticlockwise open circle arrow', google: 'open circle arrow gegen den uhrzeigersinn') + - "↻": [T: "Offener Kreispfeil im Uhrzeigersinn"] # 0x21bb (en: 'clockwise open circle arrow', MathPlayer: 'clockwise open circle arrow', google: 'pfeil im uhrzeigersinn') + - "↼": [T: "Linke Harpune oben"] # 0x21bc (en: 'left harpoon up', MathPlayer: 'left harpoon up', google: 'ließ harpoon hoch') + - "↽": [T: "Linke Harpune unten"] # 0x21bd (en: 'left harpoon down', MathPlayer: 'left harpoon down', google: 'ließ harpoon nieder') + - "↾": [T: "Harpune rechts oben"] # 0x21be (en: 'up harpoon right', MathPlayer: 'up harpoon right', google: 'harpoon rechts') + - "↿": [T: "Harpune links oben"] # 0x21bf (en: 'up harpoon left', MathPlayer: 'up harpoon left', google: 'harpune nach oben') + - "⇀": [T: "Rechte Harpune oben"] # 0x21c0 (en: 'right harpoon up', MathPlayer: 'right harpoon up', google: 'richtige harpoon hoch') + - "⇁": [T: "Rechte Harpune unten"] # 0x21c1 (en: 'right harpoon down', MathPlayer: 'right harpoon down', google: 'richtige harpune unten') + - "⇂": [T: "Harpune rechts unten"] # 0x21c2 (en: 'down harpoon right', MathPlayer: 'down harpoon right', google: 'harpoon rechts') + - "⇃": [T: "Harpune links unten"] # 0x21c3 (en: 'down harpoon left', MathPlayer: 'down harpoon left', google: 'harpoon nach unten') + - "⇄": [T: "Pfeil nach rechts über Pfeil nach links"] # 0x21c4 (en: 'rightwards arrow over leftwards arrow', MathPlayer: 'rightwards arrow over leftwards arrow', google: 'rechten pfeil über den linken pfeil') + - "⇅": [T: "Pfeil nach oben links neben Pfeil nach unten"] # 0x21c5 (en: 'upwards arrow leftwards of downwards arrow', MathPlayer: 'upwards arrow leftwards of downwards arrow', google: 'aufwärts links vom abwärtsspfeil nach oben') + - "⇆": [T: "Pfeil nach links über Pfeil nach rechts"] # 0x21c6 (en: 'leftwards arrow over rightwards arrow', MathPlayer: 'leftwards arrow over rightwards arrow', google: 'links pfeil über rechts pfeil') + - "⇇": [T: "Links gepaarte Pfeile"] # 0x21c7 (en: 'leftwards paired arrows', MathPlayer: 'leftwards paired arrows', google: 'links gepaarte pfeile') + - "⇈": [T: "Aufwärts gepaarte Pfeile"] # 0x21c8 (en: 'upwards paired arrows', MathPlayer: 'upwards paired arrows', google: 'nach oben gepaarte pfeile') + - "⇉": [T: "Rechts gepaarte Pfeile"] # 0x21c9 (en: 'rightwards paired arrows', MathPlayer: 'rightwards paired arrows', google: 'rechtspaare pfeile') + - "⇊": [T: "Abwärts gepaarte Pfeile"] # 0x21ca (en: 'downwards paired arrows', MathPlayer: 'downwards paired arrows', google: 'abwärts gepaarte pfeile') + - "⇋": [T: "Harpune nach links über Harpune nach rechts"] # 0x21cb (en: 'left harpoon over right harpoon', MathPlayer: 'left harpoon over right harpoon', google: 'linke harpoon über die rechte harpune') + - "⇌": [T: "Harpune nach rechts über Harpune nach links"] # 0x21cc (en: 'right harpoon over left harpoon', MathPlayer: 'right harpoon over left harpoon', google: 'rechte harpune über die linke harpune') + - "⇍": [T: "Doppelpfeil nach links mit Strich"] # 0x21cd (en: 'leftwards double arrow with stroke', MathPlayer: 'leftwards double arrow with stroke', google: 'links -doppelpfeil mit schlaganfall') + - "⇎": [T: "Links Rechts Doppelpfeil mit Strich"] # 0x21ce (en: 'left right double arrow with stroke', MathPlayer: 'left right double arrow with stroke', google: 'links rechts doppelpfeil mit schlaganfall') + - "⇏": [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') + - "⇖": [T: "Nordwest-Doppelpfeil"] # 0x21d6 (en: 'north west double arrow', MathPlayer: 'north west double arrow', google: 'nordwesten doppelpfeil') + - "⇗": [T: "Nordost-Doppelpfeil"] # 0x21d7 (en: 'north east double arrow', MathPlayer: 'north east double arrow', google: 'nordost -doppelpfeil') + - "⇘": [T: "Südost Doppelpfeil"] # 0x21d8 (en: 'south east double arrow', MathPlayer: 'south east double arrow', google: 'south east doppelpfeil') + - "⇙": [T: "Südwest-Doppelpfeil"] # 0x21d9 (en: 'south west double arrow', MathPlayer: 'south west double arrow', google: 'south west doppelpfeil') + - "⇚": [T: "Dreifacher Pfeil nach links"] # 0x21da (en: 'leftwards triple arrow', MathPlayer: 'leftwards triple arrow', google: 'links dreifach pfeil') + - "⇛": [T: "Dreifacher Pfeil nach rechts"] # 0x21db (SRE: 'Dreifacher Pfeil nach rechts') + - "⇜": [T: "Nach links gekrümmter Pfeil"] # 0x21dc (en: 'leftwards squiggle arrow', MathPlayer: 'leftwards squiggle arrow', google: 'linkskundgier pfeil') + - "⇝": [T: "Nach rechts gekrümmter Pfeil"] # 0x21dd (en: 'rightwards squiggle arrow', MathPlayer: 'rightwards squiggle arrow', google: 'rightwards squiggle pfeil') + - "⇞": [T: "Aufwärtspfeil mit Doppelstrich"] # 0x21de (en: 'upwards arrow with double stroke', MathPlayer: 'upwards arrow with double stroke', google: 'aufwärts mit doppelhub') + - "⇟": [T: "Abwärtspfeil mit Doppelstrich"] # 0x21df (en: 'downwards arrow with double stroke', MathPlayer: 'downwards arrow with double stroke', google: 'nach unten pfeil mit doppelhub') + - "⇠": [T: "Gestrichelter Pfeil nach links"] # 0x21e0 (en: 'leftwards dashed arrow', MathPlayer: 'leftwards dashed arrow', google: 'links gestrichelten pfeil') + - "⇡": [T: "Gestrichelter Pfeil nach oben"] # 0x21e1 (en: 'upwards dashed arrow', MathPlayer: 'upwards dashed arrow', google: 'nach oben gestrichelter pfeil') + - "⇢": [T: "Gestrichelter Pfeil nach rechts"] # 0x21e2 (en: 'rightwards dashed arrow', MathPlayer: 'rightwards dashed arrow', google: 'rightwards gestrichelten pfeil') + - "⇣": [T: "Abwärts gestrichelter Pfeil"] # 0x21e3 (en: 'downwards dashed arrow', MathPlayer: 'downwards dashed arrow', google: 'abwärts gestrichelten pfeil') + - "⇤": [T: "Pfeil nach links zur Sockel"] # 0x21e4 (en: 'leftwards arrow to bar', MathPlayer: 'leftwards arrow to bar', google: 'links pfeil in die bar') + - "⇥": [T: "Pfeil nach rechts zur Sockel"] # 0x21e5 (en: 'rightwards arrow to bar', MathPlayer: 'rightwards arrow to bar', google: 'rightwards pfeil in die bar') + - "⇦": [T: "Weißer Pfeil nach links"] # 0x21e6 (en: 'leftwards white arrow', MathPlayer: 'leftwards white arrow', google: 'links weißer pfeil') + - "⇧": [T: "Aufwärts weißer Pfeil"] # 0x21e7 (en: 'upwards white arrow', MathPlayer: 'upwards white arrow', google: 'nach oben weißer pfeil') + - "⇨": [T: "Rechts weißer Pfeil"] # 0x21e8 (en: 'rightwards white arrow', MathPlayer: 'rightwards white arrow', google: 'richtiger weißer pfeil') + - "⇩": [T: "Abwärts weißer Pfeil"] # 0x21e9 (en: 'downwards white arrow', MathPlayer: 'downwards white arrow', google: 'nach unten weißer pfeil') + - "⇪": [T: "Aufwärts weißer Pfeil von der Stange"] # 0x21ea (en: 'upwards white arrow from bar', MathPlayer: 'upwards white arrow from bar', google: 'nach oben weißer pfeil aus der bar') + - "⇫": [T: "Aufwärts weißer Pfeil auf Sockel"] # 0x21eb (en: 'upwards white arrow on pedestal', google: 'nach oben weißer pfeil auf sockel') + - "⇬": [T: "Aufwärts weißer Pfeil auf Sockel mit horizontaler Stange"] # 0x21ec (en: 'upwards white arrow on pedestal with horizontal bar', google: 'nach oben weißer pfeil auf sockel mit horizontaler balken') + - "⇭": [T: "Aufwärts weißer Pfeil auf Sockel mit vertikaler Stange"] # 0x21ed (en: 'upwards white arrow on pedestal with vertical bar', google: 'nach oben weißer pfeil auf sockel mit vertikaler balken') + - "⇮": [T: "Aufwärts weißer Doppelpfeil"] # 0x21ee (en: 'upwards white double arrow', google: 'nach oben weißer doppelpfeil') + - "⇯": [T: "Aufwärts weißer doppelter Pfeil auf Sockel"] # 0x21ef (en: 'upwards white double arrow on pedestal', google: 'nach oben weißer doppelpfeil auf sockel') + - "⇰": [T: "Rechts weißer Pfeil von der Wand"] # 0x21f0 (en: 'rightwards white arrow from wall', google: 'richtiger weißer pfeil von der wand') + - "⇱": [T: "Nordwestpfeil zur Ecke"] # 0x21f1 (en: 'north west arrow to corner', google: 'nordwestpfeil zur ecke') + - "⇲": [T: "Südostpfeil zur Ecke"] # 0x21f2 (en: 'south east arrow to corner', google: 'south east pfeil zur ecke') + - "⇳": [T: "Weißer Pfeil nach unten und oben"] # 0x21f3 (en: 'up down white arrow', google: 'runter weißer pfeil') + - "⇴": [T: "rechter Pfeil mit kleinem Kreis"] # 0x21f4 (en: 'right arrow with small circle', google: 'rechts pfeil mit kleinem kreis') + - "⇵": [T: "Abwärtspfeil links von Aufwärtspfeil"] # 0x21f5 (en: 'downwards arrow leftwards of upwards arrow', MathPlayer: 'upwards arrow to the right of downwards arrow', google: 'abwärts links nach oben auf pfeil') + - "⇶": [T: "Drei nach rechts gerichtete Pfeile"] # 0x21f6 (en: 'three rightwards arrows', google: 'drei rechts pfeile') + - "⇷": [T: "Pfeil nach links mit vertikalem Strich"] # 0x21f7 (en: 'leftwards arrow with vertical stroke', google: 'linkspfeil mit vertikalem schlaganfall') + - "⇸": [T: "Pfeil nach rechts mit vertikalem Strich"] # 0x21f8 (en: 'rightwards arrow with vertical stroke', google: 'richtiger pfeil mit vertikalem schlaganfall') + - "⇹": [T: "Linker rechter Pfeil mit vertikalem Strich"] # 0x21f9 (en: 'left right arrow with vertical stroke', google: 'links rechts pfeil mit vertikalem schlaganfall') + - "⇺": [T: "Pfeil nach links mit doppeltem vertikalem Strich"] # 0x21fa (en: 'leftwards arrow with double vertical stroke', google: 'linkspfeil mit doppelter vertikaler hub') + - "⇻": [T: "Pfeil nach rechts mit doppeltem vertikalem Strich"] # 0x21fb (en: 'rightwards arrow with double vertical stroke', google: 'richtiger pfeil mit doppelter vertikaler schlaganfall') + - "⇼": [T: "Linker rechter Pfeil mit doppeltem vertikalem Strich"] # 0x21fc (en: 'left right arrow with double vertical stroke', google: 'links rechts pfeil mit doppelter vertikaler hub') + - "⇽": [T: "Pfeil nach links mit offenem Kopf"] # 0x21fd (en: 'leftwards open headed arrow', MathPlayer: 'leftwards open headed arrow', google: 'links offene köpfe pfeil') + - "⇾": [T: "Pfeil nach rechts mit offenem Kopf"] # 0x21fe (en: 'rightwards open headed arrow', MathPlayer: 'rightwards open headed arrow', google: 'rightwards open headed pfeil') + - "⇿": [T: "Linker rechter Pfeil mit offenem Kopf"] # 0x21ff (en: 'left right open headed arrow', MathPlayer: 'left right open headed arrow', google: 'links rechts geöffneter köpfe') + - "∀": [T: "für alle"] # 0x2200 (en: 'for all') + - "∁": # 0x2201 + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # (en: 'the', google translation) + - T: "Komplement" # (en: 'complement of') + - "∂": # 0x2202 + - test: + if: "$Verbosity='Terse'" + then: [T: "teilweise"] # (en: 'partial', google translation) + else: [T: "rundes d"] # (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: "Differenz" # (en: 'laplacian of', MathPlayer: 'increment', google: 'laplace von') + - "∇": # 0x2207 + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # (en: 'the', google translation) + - T: "gradient (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: "Mitglied 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 Mitglied 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: "nicht Mitglied 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 Mitglied 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: "Mitglied 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 Mitglied 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: + if: "@data-chem-formula-op" + 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'" + then: [T: "die"] # (en: 'the', google translation) + - T: "Kubikwurzel" # (en: 'cube root of', MathPlayer: 'dritte Wurzel', google: 'würfelwurzel von') + - "∜": # 0x221c + - test: + 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') + - "∲": [T: "Kurvenintegral im Uhrzeigersinn"] # 0x2232 (en: 'clockwise contour integral', MathPlayer: 'Kontur-Integral im Uhrzeigersinn', google: 'konturintegral im uhrzeigersinn') + - "∳": [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 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "geometrische Proportion" # (en: 'geometrically proportional to') + - "∻": # 0x223b + - test: + 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') + - "≃": # 0x2243 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "asymptotisch gleich" # (en: 'asymptotically equal to') + - "≄": # 0x2244 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "nicht asymptotisch gleich" # (en: 'not asymptotically equal to') + - "≅": # 0x2245 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "ungefähr gleich" # (en: 'approximately equal to') + - "≆": # 0x2246 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "ungefähr, aber nicht ganz gleich" # (en: 'approximately but not actually equal to') + - "≇": # 0x2247 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "weder ungefähr noch ganz gleich" # (en: 'neither approximately nor actually equal to') + - "≈": # 0x2248 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "beinahe gleich" # (en: 'almost equal to') + - "≉": # 0x2249 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "nicht beinahe gleich" # (en: 'not almost equal to') + - "≊": # 0x224a + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "beinahe gleich oder gleich" # (en: 'almost equal or equal to', MathPlayer: 'beinahe oder ganz gleich', google: 'fast gleich oder gleich') + - "≋": [T: "dreifache Tilde"] # 0x224b (en: 'triple tilde', MathPlayer: 'triple tilde', google: 'dreifach tilde') + - "≌": [T: "alles gleich"] # 0x224c (en: 'are all equal to', MathPlayer: 'all equal to', google: 'sind alle gleich') + - "≍": # 0x224d + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "äquivalent zu" # (en: 'equivalent to') + - "≎": # 0x224e + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "geometrisch äquivalent zu" # (en: 'geometrically equivalent to') + - "≏": # 0x224f + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # (en: 'the', google translation) + - T: "Differenz zwischen" # (en: 'difference between') + - "≐": [T: "nähert sich der Grenze"] # 0x2250 (en: 'approaches the limit') + - "≑": # 0x2251 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "geometrisch gleich" # (en: 'geometrically equal to') + - "≒": # 0x2252 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "Ungefähr gleich oder das Bild von" # (en: 'approximately equal to or the image of', MathPlayer: 'approximately equal to or the image of', google: 'ungefähr gleich oder das bild von') + - "≓": # 0x2253 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist der"] # (en: 'is the', google translation) + - T: "Bild von oder ungefähr gleich" # (en: 'image of or approximately equal to', MathPlayer: 'image of or approximately equal to', google: 'bild von oder ungefähr gleich') + - "≔": [T: "definiert als"] # 0x2254 (en: 'colon equals') + - "≕": [T: "definiert als von rechts"] # 0x2255 (en: 'equals colon', MathPlayer: 'equals colon', google: 'gleich') + - "≖": [T: "ungefähr gleich"] # 0x2256 (en: 'ring in equal to', MathPlayer: 'ring in equal to', google: 'in gleich rufen') + - "≗": # 0x2257 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "ungefähr gleich" # (en: 'approximately equal to', MathPlayer: 'ring equal to') + - "≘": [T: "entspricht"] # 0x2258 (en: 'corresponds to') + - "≙": [T: "entspricht"] # 0x2259 (en: 'estimates', MathPlayer: 'estimates', google: 'schätzungen') + - "≚": # 0x225a + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "gleichwinklig zu" # (en: 'equiangular to', MathPlayer: 'equiangular to', google: 'gleiche zu') + - "≛": [T: "gleich mit Stern"] # 0x225b (en: 'star equals', MathPlayer: 'star equals', google: 'stern ist gleich') + - "≜": [T: "gleich mit Delta"] # 0x225c (en: 'delta equals', MathPlayer: 'delta equal to', google: 'delta gleich') + - "≝": [T: "definitionsgemäß gleich"] # 0x225d (en: 'is defined to be') + - "≞": # 0x225e + - test: + if: "$Verbosity!='Terse'" + 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'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "nicht identisch mit" # (en: 'not identical to', SRE: 'nicht kongruent mit') + - "≣": # 0x2263 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "genau äquivalent mit" # (en: 'strictly equivalent to', MathPlayer: 'streng äquivalent mit', google: 'streng äquivalent zu') + - "≦": [T: "kleiner als über gleich"] # 0x2266 (en: 'less than over equal to', MathPlayer: 'less than over equal to', google: 'weniger als überweg') + - "≧": [T: "größer als über gleich"] # 0x2267 (en: 'greater than over equal to', MathPlayer: 'greater than over equal to', google: 'größer als überweg') + - "≨": # 0x2268 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "kleiner als, aber nicht gleich" # (en: 'less than but not equal to') + - "≩": # 0x2269 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "größer als, aber nicht gleich" # (en: 'greater than but not equal to') + - "≪": # 0x226a + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "viel kleiner als" # (en: 'much less than') + - "≫": # 0x226b + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "viel größer als" # (en: 'much greater than') + - "≬": # 0x226c + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "zwischen" # (en: 'between') + - "≭": # 0x226d + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "nicht äquivalent mit" # (en: 'not equivalent to') + - "≮": # 0x226e + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "nicht kleiner als" # (en: 'not less than') + - "≯": # 0x226f + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "nicht größer als" # (en: 'not greater than') + - "≰": # 0x2270 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "weder kleiner als noch gleich" # (en: 'neither less than nor equal to') + - "≱": # 0x2271 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "weder größer als noch gleich" # (en: 'neither greater than nor equal to') + - "≲": # 0x2272 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "kleiner als oder äquivalent" # (en: 'less than or equivalent to') + - "≳": # 0x2273 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "größer als oder äquivalent" # (en: 'greater than or equivalent to') + - "≴": # 0x2274 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "weder kleiner als noch äquivalent" # (en: 'neither less than nor equivalent to') + - "≵": # 0x2275 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "weder größer als noch äquivalent" # (en: 'neither greater than nor equivalent to') + - "≶": # 0x2276 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "kleiner oder größer als" # (en: 'less than or greater than') + - "≷": # 0x2277 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "größer oder kleiner als" # (en: 'greater than or less than') + - "≸": # 0x2278 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "weder kleiner noch größer als" # (en: 'neither less than nor greater than') + - "≹": # 0x2279 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "weder größer noch kleiner als" # (en: 'neither greater than nor less than') + - "≺": [T: "vorangehend"] # 0x227a (en: 'precedes', MathPlayer: 'precedes', google: 'voraus') + - "≻": [T: "nachfolgend"] # 0x227b (en: 'succeeds', MathPlayer: 'succeeds', google: 'gelingt es') + - "≼": [T: "vorangehend oder gleich"] # 0x227c (en: 'precedes or is equal to', MathPlayer: 'precedes or equal to', google: 'vorausgeht oder ist gleich') + - "≽": [T: "nachfolgend oder gleich"] # 0x227d (en: 'succeeds or is equal to', MathPlayer: 'succeeds or equal to', google: 'erfolg oder ist gleich') + - "≾": [T: "vorangehend oder äquivalent"] # 0x227e (en: 'precedes or is equivalent to', MathPlayer: 'precedes or equivalent to', google: 'vorausgeht oder ist gleichbedeutend mit') + - "≿": [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: "kein 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'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "weder Teilmenge noch gleich" # (en: 'neither a subset of nor equal to', MathPlayer: 'weder Teilmenge von noch gleich', google: 'weder eine untergruppe von noch gleich') + - "⊉": # 0x2289 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "weder Obermenge noch gleich" # (en: 'neither a superset of nor equal to', MathPlayer: 'weder Obermenge von noch gleich', google: 'weder ein superset von noch gleich') + - "⊊": [T: "Teilmenge aber nicht gleich"] # 0x228a (en: 'subset of with not equal to', MathPlayer: 'Teilmenge von, aber nicht gleich', google: 'teilmenge von mit nicht gleich') + - "⊋": [T: "Obermenge aber nicht gleich"] # 0x228b (en: 'superset of with not equal to', MathPlayer: 'Obermenge von, aber nicht gleich', google: 'superset von mit nicht gleich') + - "⊌": [T: "Mehrfachmenget"] # 0x228c (SRE: 'Multimenge') + - "⊍": [T: "Multimengenmultiplikation"] # 0x228d (en: 'multiset multiplication', MathPlayer: 'multiset multiplication', google: 'multiset -multiplikation') + - "⊎": [T: "Multimengenvereinigung"] # 0x228e (SRE: 'Multimengenvereinigung') + - "⊏": [T: "quadratisches Bild von"] # 0x228f (en: 'square image of', MathPlayer: 'square image of', google: 'square bild von') + - "⊐": [T: "quadratisches Original von"] # 0x2290 (en: 'square original of', MathPlayer: 'square original of', google: 'square original von') + - "⊑": [T: "quadratisches Bild oder gleich"] # 0x2291 (en: 'square image of or equal to', MathPlayer: 'square image of or equal to', google: 'quadratisches bild von oder gleich') + - "⊒": [T: "quadratisches Original oder gleich"] # 0x2292 (en: 'square original of or equal to', MathPlayer: 'square original of or equal to', google: 'square original von oder gleich') + - "⊓": [T: "quadratische Schnittmenge"] # 0x2293 (en: 'square cap', MathPlayer: 'square cap', google: 'quadratische großbuchstaben') + - "⊔": [T: "quadratische Vereinigungsmenge"] # 0x2294 (en: 'square cup', MathPlayer: 'square cup', google: 'quadratbecher') + - "⊕": [T: "eingekreistes Pluszeichen"] # 0x2295 (en: 'circled plus', MathPlayer: 'circle plus', google: 'umgekreist plus') + - "⊖": [T: "eingekreistes Minuszeichen"] # 0x2296 (en: 'circled minus', MathPlayer: 'circle minus', google: 'eingekreist minus') + - "⊗": [T: "eingekreiste Multiplikation"] # 0x2297 (en: 'circled times', MathPlayer: 'circle times', google: 'kreiste zeiten') + - "⊘": [T: "eingekreiste Division"] # 0x2298 (en: 'circled slash', MathPlayer: 'circle slash', google: 'eingekreist') + - "⊙": [T: "eingekreister Punktoperator"] # 0x2299 (en: 'circled dot operator', MathPlayer: 'circle dot', google: 'eingekreister punktbetreiber') + - "⊚": [T: "eingekreister Ringoperator"] # 0x229a (en: 'circled ring', MathPlayer: 'circle ring', google: 'eingekreister ring') + - "⊛": [T: "eingekreister Sternoperator"] # 0x229b (en: 'circled asterisk', MathPlayer: 'circle asterisk', google: 'eingekreistes sternchen') + - "⊜": [T: "eingekreistes Gleich"] # 0x229c (en: 'circled equals', MathPlayer: 'circle equals', google: 'kreist gleich') + - "⊝": [T: "eingekreister Gedankenstrich"] # 0x229d (en: 'circled dash', MathPlayer: 'circle dash', google: 'kreislauf') + - "⊞": [T: "eingerahmtes Plus"] # 0x229e (en: 'squared plus', MathPlayer: 'square plus', google: 'quadrat plus') + - "⊟": [T: "eingerahmtes Minus"] # 0x229f (en: 'squared minus', MathPlayer: 'square minus', google: 'quadratisch minus') + - "⊠": [T: "eingerahmte Multiplikation"] # 0x22a0 (en: 'squared times', MathPlayer: 'square times', google: 'quadratische zeiten') + - "⊡": [T: "eingerahmter Punktoperator"] # 0x22a1 (en: 'squared dot operator', MathPlayer: 'square dot', google: 'quadratischer punktbetreiber') + - "⊢": [T: "ergibt"] # 0x22a2 (en: 'proves', MathPlayer: 'right tack', google: 'beweist') + - "⊣": [T: "ergibt nicht"] # 0x22a3 (en: 'does not yield', MathPlayer: 'left tack', google: 'ergeben nicht') + - "⊤": [T: "senkrecht von"] # 0x22a4 (en: 'top', MathPlayer: 'down tack', google: 'spitze') + - "⊥": # 0x22a5 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "senkrecht auf" # (en: 'bottom', MathPlayer: 'up tack', google: 'unten') + - "⊦": [T: "Behauptung"] # 0x22a6 (en: 'reduces to', MathPlayer: 'assertion', google: 'reduziert zu') + - "⊧": [T: "Model"] # 0x22a7 (en: 'models', MathPlayer: 'models', google: 'modelle') + - "⊨": # 0x22a8 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "wahr" # (en: 'true', MathPlayer: 'true') + - "⊩": [T: "erzwingen"] # 0x22a9 (en: 'forces', MathPlayer: 'forces', google: 'kräfte') + - "⊪": [T: "dreifache vertikale Leiste mit rechtem Drehkreuz"] # 0x22aa (en: 'triple vertical bar right turnstile', MathPlayer: 'triple vertical bar right turnstile', google: 'triple vertikale bar rechtsummens') + - "⊫": [T: "doppelte vertikale Leiste mit doppeltem rechtem Drehkreuz"] # 0x22ab (en: 'double vertical bar double right turnstile', MathPlayer: 'double vertical bar double right turnstile', google: 'doppelte vertikale balken doppelte rechte kurve') + - "⊬": [T: "beweist nicht"] # 0x22ac (en: 'does not prove', MathPlayer: 'does not prove') + - "⊭": # 0x22ad + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "nicht wahr" # (en: 'not true', MathPlayer: 'not true') + - "⊮": [T: "nicht erzwingen"] # 0x22ae (en: 'does not force', MathPlayer: 'does not force', google: 'zwingt nicht') + - "⊯": [T: "negierte doppelte vertikale Leiste mit doppeltem rechten Drehkreuz"] # 0x22af (en: 'negated double vertical bar double right turnstile', MathPlayer: 'negated double vertical bar double right turnstile', google: 'negierter doppelter vertikaler balken doppelte rechte kurve') + - "⊰": [T: "vorangehend in Relation"] # 0x22b0 (en: 'precedes under relation', MathPlayer: 'precedes under relation', google: 'vorausgegangen in beziehung') + - "⊱": [T: "nachfolgend in Relation"] # 0x22b1 (en: 'succeeds under relation', MathPlayer: 'succeeds under relation', google: 'erfolgreich in beziehung') + - "⊲": # 0x22b2 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "normale Untergruppe" # (en: 'a normal subgroup of', MathPlayer: 'normal subgroup of', google: 'eine normale untergruppe von') + - "⊳": [T: "enthält normale Untergruppe"] # 0x22b3 (en: 'contains as a normal subgroup', MathPlayer: 'contains as normal subgroup', google: 'enthält als normale untergruppe') + - "⊴": # 0x22b4 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "normale Untergruppe von oder gleich" # (en: 'a normal subgroup of or equal to', MathPlayer: 'normal subgroup of or equal to', google: 'eine normale untergruppe von oder gleich') + - "⊵": [T: "enthält normale Untergruppe oder gleich"] # 0x22b5 (en: 'contains as a normal subgroup or equal to', MathPlayer: 'contains as normal subgroup or equal to', google: 'enthält als normale untergruppe oder gleich') + - "⊶": # 0x22b6 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "Original von" # (en: 'the original of', MathPlayer: 'original of', google: 'das original von') + - "⊷": # 0x22b7 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "Bild von" # (en: 'an image of', MathPlayer: 'image of', google: 'ein bild von') + - "⊸": [T: "multimap"] # 0x22b8 (SRE: 'Mehrfachzuordnung') + - "⊹": [T: "hermitesch konjugierte Matrix"] # 0x22b9 (en: 'hermitian conjugate matrix', MathPlayer: 'hermitian conjugate matrix', google: 'hermitische konjugierte matrix') + - "⊺": [T: "einschalten"] # 0x22ba (en: 'intercalate', MathPlayer: 'intercalate', google: 'interkalieren') + - "⊻": [T: "Ausschließendes Oder"] # 0x22bb (SRE: 'Ausschließendes Oder') + - "⊼": [T: "nand"] # 0x22bc (SRE: 'Nand verknüpft mit') + - "⊽": [T: "Nor verknüpft mit"] # 0x22bd (en: 'nor', MathPlayer: 'nor', google: 'noch') + - "⊾": [T: "rechter Winkel mit Bogen"] # 0x22be (en: 'right angle with arc', MathPlayer: 'right angle with arc', google: 'rechtwinkel mit bogen') + - "⊿": [T: "rechtwinkliges Dreieck"] # 0x22bf (en: 'right triangle', MathPlayer: 'right triangle', google: 'rechtwinkliges dreieck') + - "⋀": [T: "logisch und"] # 0x22c0 (en: 'logical and', SRE: 'N-stufiges logisches Und') + - "⋁": [T: "logisch oder"] # 0x22c1 (en: 'logical or', SRE: 'N-stufiges logisches Oder') + - "⋂": [T: "N-stufiger Durchschnitt"] # 0x22c2 (en: 'intersection', MathPlayer: 'Durchschnitt', google: 'überschneidung') + - "⋃": [T: "N-stufige Vereinigung"] # 0x22c3 (en: 'union', MathPlayer: 'Vereinigung', google: 'union') + - "⋄": [T: "Rautenoperator"] # 0x22c4 (en: 'diamond operator', MathPlayer: 'diamond operator', google: 'diamantbetreiber') + - "⋅": # 0x22c5 + - test: + if: "@data-chem-formula-op" + then: [T: "punkt"] # (en: 'dot', google translation) + else: [T: "mal"] # (en: 'times', MathPlayer: 'dot') + + - "⋆": [T: "Sternoperator"] # 0x22c6 (en: 'times', MathPlayer: 'star', google: 'mal') + - "⋇": [T: "Divisionsanzahl"] # 0x22c7 (en: 'division times', MathPlayer: 'division times', google: 'divisionszeiten') + - "⋈": [T: "Schleife"] # 0x22c8 (en: 'bowtie', MathPlayer: 'bowtie', google: 'krawatte') + - "⋉": # 0x22c9 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "linkes halbdirektes Produkt" # (en: 'the left normal factor semidirect product of', MathPlayer: 'left normal factor semidirect product', google: 'das linke normale faktor semidirekte produkt von') + - "⋊": # 0x22ca + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "rechtes halbdirektes Produkt" # (en: 'the right normal factor semidirect product of', MathPlayer: 'right normal factor semidirect product', google: 'der richtige normale faktor semidirect -produkt von') + - "⋋": # 0x22cb + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "linkes halbdirektes Produkt" # (en: 'the left semidirect product of', MathPlayer: 'left semidirect product', google: 'das linke semidirect -produkt von') + - "⋌": # 0x22cc + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "rechtes halbdirektes Produkt" # (en: 'the right semidirect product of', MathPlayer: 'right semidirect product', google: 'das richtige semidirect -produkt von') + - "⋍": [T: "umgekehrte Tilde gleich"] # 0x22cd (en: 'reversed tilde equals', MathPlayer: 'reversed tilde equals', google: 'umgekehrte tilde gleich') + - "⋎": [T: "geschweiftes logisches Oder"] # 0x22ce (en: 'curly logical or', MathPlayer: 'curly logical or', google: 'lockiges logisch oder') + - "⋏": [T: "geschweiftes logisches Und"] # 0x22cf (en: 'curly logical and', MathPlayer: 'curly logical and', google: 'lockiges logisch und') + - "⋐": # 0x22d0 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "doppelte Teilmenge" # (en: 'a double subset of', MathPlayer: 'double subset', google: 'eine doppelte untergruppe von') + - "⋑": # 0x22d1 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "doppelte Obermenge" # (en: 'a double superset of', MathPlayer: 'double superset', google: 'ein doppeltes superset von') + - "⋒": # 0x22d2 + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # (en: 'the', google translation) + - T: "doppelter Durchschnitt" # (en: 'double intersection of', MathPlayer: 'double intersection', google: 'doppelte kreuzung von') + - "⋓": # 0x22d3 + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # (en: 'the', google translation) + - T: "doppelte Vereinigung" # (en: 'double union of', MathPlayer: 'double union', google: 'doppelte vereinigung von') + - "⋔": # 0x22d4 + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # (en: 'the', google translation) + - T: "echter Durchschnitt" # (en: 'proper intersection of', MathPlayer: 'pitchfork', google: 'richtige schnittpunkt von') + - "⋕": # 0x22d5 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "gleich und parallel" # (en: 'equal to and parallel to', MathPlayer: 'equal and parallel to', google: 'gleich und parallel zu') + - "⋖": [T: "kleiner als mit Punkt"] # 0x22d6 (en: 'less than with dot', MathPlayer: 'less than with dot', google: 'weniger als mit punkt') + - "⋗": [T: "größer als mit Punkt"] # 0x22d7 (en: 'greater than with dot', MathPlayer: 'greater than with dot', google: 'größer als mit punkt') + - "⋘": # 0x22d8 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "sehr viel kleiner als" # (en: 'very much less than', MathPlayer: 'very much less than', google: 'sehr viel weniger als') + - "⋙": # 0x22d9 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "sehr viel größer als" # (en: 'very much greater than', MathPlayer: 'very much greater than') + - "⋚": # 0x22da + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "kleiner als, gleich oder größer als" # (en: 'less than equal to or greater than', MathPlayer: 'less than equal to or greater than', google: 'weniger als gleich oder größer als') + - "⋛": # 0x22db + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "größer als, gleich oder kleiner als" # (en: 'greater than equal to or less than', MathPlayer: 'greater than equal to or less than', google: 'größer als gleich oder weniger als') + - "⋜": # 0x22dc + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "gleich oder kleiner als" # (en: 'equal to or less than', MathPlayer: 'equal to or less than', google: 'gleich oder weniger als') + - "⋝": # 0x22dd + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "gleich oder größer als" # (en: 'equal to or greater than', MathPlayer: 'equal to or greater than') + - "⋞": # 0x22de + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "gleich oder vorangehend" # (en: 'equal to or precedes', MathPlayer: 'equal to or precedes', google: 'gleich oder voraus') + - "⋟": # 0x22df + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "gleich oder nachfolgend" # (en: 'equal to or succeeds', MathPlayer: 'equal to or succeeds', google: 'gleich oder erfolgreich') + - "⋠": [T: "weder vorangehend oder gleich"] # 0x22e0 (en: 'does not precede nor is equal to', MathPlayer: 'does not precede or equal', google: 'geht nicht voraus und ist nicht gleich') + - "⋡": [T: "weder nachfolgend oder gleich"] # 0x22e1 (en: 'does not succeed nor is equal to', MathPlayer: 'does not succeed or equal', google: 'gelingt weder noch ist es gleich') + - "⋢": [T: "kein quadratisches Bild oder gleich"] # 0x22e2 (en: 'not square image of or equal to', MathPlayer: 'not square image of or equal to', google: 'kein quadratisches bild von oder gleich') + - "⋣": [T: "kein quadratisches Original oder gleich"] # 0x22e3 (en: 'not square original of or equal to', MathPlayer: 'not square original of or equal to', google: 'kein quadratisches original von oder gleich') + - "⋤": [T: "quadratisches Bild oder nicht gleich"] # 0x22e4 (en: 'square image of or not equal to', MathPlayer: 'square image of or not equal to', google: 'quadratisches bild von oder nicht gleich') + - "⋥": [T: "quadratisches Original oder nicht gleich"] # 0x22e5 (en: 'square original of or not equal to', MathPlayer: 'square original of or not equal to', google: 'square original von oder nicht gleich') + - "⋦": # 0x22e6 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "kleiner als, aber nicht äquivalent" # (en: 'less than but not equivalent to', MathPlayer: 'less than but not equivalent to', google: 'weniger als aber nicht gleichbedeutend mit') + - "⋧": # 0x22e7 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "größer als, aber nicht äquivalent" # (en: 'greater than but not equivalent to', MathPlayer: 'greater than but not equivalent to', google: 'größer als aber nicht gleichbedeutend mit') + - "⋨": [T: "vorangehend, aber nicht äquivalent"] # 0x22e8 (en: 'precedes but is not equivalent to', MathPlayer: 'precedes but not equivalent to', google: 'vorausgesetzt, ist aber nicht gleichwertig zu') + - "⋩": [T: "nachfolgend, aber nicht äquivalent"] # 0x22e9 (en: 'succeeds but is not equivalent to', MathPlayer: 'succeeds but not equivalent to', google: 'erfolg, ist aber nicht gleichwertig zu') + - "⋪": # 0x22ea + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "nicht normale Untergruppe von" # (en: 'not a normal subgroup of', MathPlayer: 'not normal subgroup of', google: 'keine normale untergruppe von') + - "⋫": [T: "enthält keine normale Untergruppe"] # 0x22eb (en: 'does not contain as a normal subgroup', MathPlayer: 'does not contain as normal subgroup', google: 'enthält nicht als normale untergruppe') + - "⋬": # 0x22ec + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "keine normale Untergruppe von oder gleich" # (en: 'not a normal subgroup of nor is equal to', MathPlayer: 'not normal subgroup of or equal to', google: 'keine normale untergruppe von und nicht gleich') + - "⋭": [T: "enthält nicht als normale Untergruppe oder gleich"] # 0x22ed (en: 'does not contain as a normal subgroup nor is equal to', MathPlayer: 'does not contain as normal subgroup or equal', google: 'enthält weder eine normale untergruppe noch') + - "⋮": [T: "Vertikale Ellipsis"] # 0x22ee (en: 'vertical ellipsis', MathPlayer: 'vertical ellipsis', google: 'vertikale ellipse') + - "⋯": [T: "Zentrierte horizontale Ellipse"] # 0x22ef (en: 'dot dot dot', MathPlayer: 'math axis ellipsis', google: 'punkt punkt punkt') + - "⋰": [T: "Diagonale Ellipse unten links nach oben rechts"] # 0x22f0 (en: 'upwards diagonal ellipsis', MathPlayer: 'up right diagonal ellipsis', google: 'aufwärts diagonale ellipsis') + - "⋱": [T: "Diagonale Ellipse, oben links nach unten rechts"] # 0x22f1 (en: 'diagonal ellipsis', MathPlayer: 'down right diagonal ellipsis', google: 'diagonale ellipsis') + - "⋲": [T: "Element mit langem horizontalen Strich"] # 0x22f2 (en: 'element of with long horizontal stroke', MathPlayer: 'element of with long horizontal stroke', google: 'element von mit langem horizontalem schlaganfall') + - "⋳": [T: "Element mit vertikalem Strich am Ende des horizontalen Strichs"] # 0x22f3 (en: 'element of with vertical bar at end of horizontal stroke', MathPlayer: 'element of with vertical bar at end of horizontal stroke', google: 'element von mit vertikalem balken am ende des horizontalen strich') + - "⋴": [T: "kleines Element mit vertikalem Strich am Ende des horizontalen Strichs"] # 0x22f4 (en: 'element of with vertical bar at end of horizontal stroke', MathPlayer: 'element of with vertical bar at end of horizontal stroke', google: 'element von mit vertikalem balken am ende des horizontalen strich') + - "⋵": [T: "Element mit Punkt"] # 0x22f5 (en: 'element of with dot above', MathPlayer: 'element of with dot above', google: 'element von mit punkt oben') + - "⋶": [T: "Element mit Überstrich"] # 0x22f6 (en: 'element of with overbar', MathPlayer: 'element of with overbar', google: 'element von overbar') + - "⋷": [T: "kleines Element mit Überstrich"] # 0x22f7 (en: 'element of with overbar', MathPlayer: 'element of or equal to', google: 'element von overbar') + - "⋸": [T: "Element mit Unterstrich"] # 0x22f8 (en: 'element of with underbar', MathPlayer: 'element of with underbar', google: 'element von mit unterbar') + - "⋹": [T: "Element mit 2 horizontalen Strichen"] # 0x22f9 (en: 'element of with two horizontal strokes', MathPlayer: 'element of with two horizontal strokes', google: 'element von mit zwei horizontalen strichen') + - "⋺": [T: "umgekehrtes Elementzeichen mit langem horizontalen Strich"] # 0x22fa (en: 'contains with long horizontal stroke', MathPlayer: 'contains with long horizontal stroke', google: 'enthält mit langem horizontalem schlaganfall') + - "⋻": [T: "umgekehrtes Elementzeichen mit vertikalem Strich am Ende des horizontalen Strichs"] # 0x22fb (en: 'contains with vertical bar at end of horizontal stroke', MathPlayer: 'contains with vertical bar at end of horizontal stroke', google: 'enthält mit vertikaler balken am ende des horizontalen schlaganfalls') + - "⋼": [T: "kleines umgekehrtes Elementzeichen mit vertikalem Strich am Ende des horizontalen Strichs"] # 0x22fc (en: 'contains with vertical bar at end of horizontal stroke', MathPlayer: 'contains with vertical bar at end of horizontal stroke', google: 'enthält mit vertikaler balken am ende des horizontalen schlaganfalls') + - "⋽": [T: "umgekehrtes Elementzeichen mit Überstrich"] # 0x22fd (en: 'contains with overbar', MathPlayer: 'contains or equal to', google: 'enthält mit überbar') + - "⋾": [T: "kleines umgekehrtes Elementzeichen mit Überstrich"] # 0x22fe (en: 'contains with overbar', MathPlayer: 'small contains with overbar', google: 'enthält mit überbar') + - "⋿": [T: "Z-Notation-Bag-Mitgliedschaft"] # 0x22ff (en: 'z notation bag membership', MathPlayer: 'z notation bag membership', google: 'z notation bag mitgliedschaft') + - "⌀": [T: "Durchmesser-Zeichen"] # 0x2300 (en: 'diameter', MathPlayer: 'diameter', google: 'durchmesser') + - "⌁": [T: "Elektrischer Pfeil"] # 0x2301 (en: 'electric arrow', google: 'elektrischer pfeil') + - "⌂": [T: "Haus"] # 0x2302 (en: 'house', MathPlayer: 'house', google: 'haus') + - "⌃": [T: "Pfeilkopf nach oben"] # 0x2303 (en: 'up arrowhead', google: 'auf pfeilspitze') + - "⌄": [T: "Pfeilkopf nach unten"] # 0x2304 (en: 'down arrowhead', google: 'pfeilspitze') + - "⌅": [T: "Projektiv"] # 0x2305 (en: 'projective', MathPlayer: 'projective', google: 'projektiv') + - "⌆": [T: "Perspektive"] # 0x2306 (en: 'perspective', MathPlayer: 'perspective', google: 'perspektive') + - "⌇": [T: "Schlangenlinie"] # 0x2307 (en: 'wavy line', google: 'schlangenlinie') + - "⌈": [T: "linke Aufrundungsklammer"] # 0x2308 (en: 'left ceiling', MathPlayer: 'left ceiling', google: 'linke decke') + - "⌉": [T: "rechte Aufrundungsklammer"] # 0x2309 (en: 'right ceiling', MathPlayer: 'right ceiling', google: 'rechte decke') + - "⌊": [T: "linke Abrundungsklammer"] # 0x230a (en: 'left floor', MathPlayer: 'left floor', google: 'linker boden') + - "⌋": [T: "rechter Abrundungsklammer"] # 0x230b (en: 'right floor', MathPlayer: 'right floor', google: 'rechts boden') + - "⌌": [T: "unterer rechter Abschnitt"] # 0x230c (en: 'bottom right crop', MathPlayer: 'bottom right crop', google: 'unten rechts ernte') + - "⌍": [T: "Unterer linker Abschnitt"] # 0x230d (en: 'bottom left crop', MathPlayer: 'bottom left crop', google: 'unten linke ernte') + - "⌎": [T: "Oberer rechter Abschnitt"] # 0x230e (en: 'top right crop', MathPlayer: 'top right crop', google: 'oben rechts ernte') + - "⌏": [T: "Oberer linker Abschnitt"] # 0x230f (en: 'top left crop', MathPlayer: 'top left crop', google: 'oben linke ernte') + - "⌐": [T: "Umgekehrtes Nichtzeichen"] # 0x2310 (en: 'reversed not sign', MathPlayer: 'reversed not', google: 'umgekehrt nicht unterschreiben') + - "⌑": [T: "Quadratische Raute"] # 0x2311 (en: 'square lozenge', google: 'square rautege') + - "⌒": [T: "Bogen"] # 0x2312 (en: 'arc', MathPlayer: 'arc', google: 'bogen') + - "⌓": [T: "segment"] # 0x2313 (SRE: 'Segment') + - "⌔": [T: "Sektor"] # 0x2314 (en: 'sector', google: 'sektor') + - "⌕": [T: "telephone recorder"] # 0x2315 (google: 'telefonrekorder') + - "⌖": [T: "position indicator; crosshairs"] # 0x2316 (en: 'position indicator crosshairs', google: 'positionsindikator crosshairs') + - "⌗": [T: "Datenanzeigefeld"] # 0x2317 (google translation) + - "⌘": [T: "Sehenswürdigkeitszeichen"] # 0x2318 (google: 'spole von interschlage') + - "⌙": [T: "nicht gedrehtes zeichen"] # 0x2319 (en: 'turned not sign', google translation) + - "⌚": [T: "Uhr"] # 0x231a (google: 'betrachten') + - "⌛": [T: "sanduhr"] # 0x231b (en: 'hourglass', google translation) + - "⌜": [T: "Obere linke Ecke"] # 0x231c (en: 'top left corner', MathPlayer: 'top left corner', google: 'obere linke ecke') + - "⌝": [T: "Obere rechte Ecke"] # 0x231d (en: 'top right corner', MathPlayer: 'top right corner', google: 'obere rechte ecke') + - "⌞": [T: "Untere linke Ecke"] # 0x231e (en: 'bottom left corner', MathPlayer: 'bottom left corner', google: 'untere linke ecke') + - "⌟": [T: "Rechte untere Ecke"] # 0x231f (en: 'bottom right corner', MathPlayer: 'bottom right corner', google: 'rechte untere ecke') + - "⌠": [T: "Obere Hälfte eines Integrals"] # 0x2320 (en: 'top half integral', MathPlayer: 'top half integral', google: 'top -hälfte integral') + - "⌡": [T: "Untere Hälfte eines Integrals"] # 0x2321 (en: 'bottom half integral', MathPlayer: 'bottom half integral', google: 'untere hälfte integral') + - "⌢": [T: "Stirnrunzeln"] # 0x2322 (google: 'stirnrunzeln') + - "⌣": [T: "Lächeln"] # 0x2323 (google: 'lächeln') + - "⌤": [T: "Pfeilspitze zwischen zwei horizontalen Balken"] # 0x2324 (en: 'up arrowhead between two horizontal bars', google: 'auf der pfeilspitze zwischen zwei horizontalen balken') + - "⌥": [T: "optionschlüssel"] # 0x2325 (en: 'option key', google translation) + - "⌦": [T: "nach rechts löschen"] # 0x2326 (en: 'erase to the right', google translation) + - "⌧": [T: "x in einer rechteckbox"] # 0x2327 (en: 'x in a rectangle box', google translation) + - "⌨": [T: "tastatur"] # 0x2328 (en: 'keyboard', google translation) + - "〈": [T: "Linke spitze Klammer"] # 0x2329 (en: 'left pointing angle bracket', MathPlayer: 'left pointing angle bracket', google: 'links zeigewinkelhalterung') + - "〉": [T: "Rechte spitze Klammer"] # 0x232a (en: 'right pointing angle bracket', MathPlayer: 'right pointing angle bracket', google: 'rechte zeigewinkelhalterung') + - "⌫": [T: "links löschen"] # 0x232b (en: 'erase to the left', google translation) + - "⌬": [T: "benzolring"] # 0x232c (en: 'benzene ring', google translation) + - "⌭": [T: "Zylindrizität"] # 0x232d (google: 'zylinderheit') + - "⌮": [T: "Runsumpfeil"] # 0x232e (google: 'rund um das profil') + - "⌯": [T: "symmetrie"] # 0x232f (en: 'symmetry', google translation) + - "⌰": [T: "totaler auslauf"] # 0x2330 (en: 'total runout', google translation) + - "⌱": [T: "dimension ursprung"] # 0x2331 (en: 'dimension origin', google translation) + - "⌲": [T: "konische verjüngung"] # 0x2332 (en: 'conical taper', google translation) + - "⌳": [T: "neigung"] # 0x2333 (en: 'slope', google translation) + - "⌴": [T: "gegenbore"] # 0x2334 (en: 'counterbore', google translation) + - "⌵": [T: "versenken"] # 0x2335 (en: 'countersink', google translation) + - "⍰": [T: "eingerahmtes Fragezeichen"] # 0x2370 (en: 'unknown box', google: 'unbekannte box') + - "⎕": [T: "kasten"] # 0x2395 (en: 'box', google translation) + - "⏞": [T: "Obere geschweifte Klammer"] # 0x23DE (en: 'top brace', MathPlayer: 'top curly bracket', google: 'spitzenklammer') + - "⏟": [T: "Untere geschweifte Klammer"] # 0x23DF (en: 'bottom brace', MathPlayer: 'bottom curly bracket', google: 'bottom -klammer') + - "①-⑨": # 0x2460 - 0x2469 + - T: "umkreiste" # (en: 'circled', MathPlayer: 'bottom curly bracket', google: 'eingekreist') + - spell: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" + - "⑩": [T: "zehn umkreist"] # 0x2469 (en: 'circled ten', google translation) + - "⑪": [T: "elf umkreist"] # 0x246a (en: 'circled eleven', google translation) + - "⑫": [T: "zwölf umkreist"] # 0x246b (en: 'circled twelve', google translation) + - "⑬": [T: "dreizehn umkreist"] # 0x246c (en: 'circled thirteen', google translation) + - "⑭": [T: "vierzehn umkreist"] # 0x246d (en: 'circled fourteen', google translation) + - "⑮": [T: "fünfzehn umkreist"] # 0x246e (en: 'circled fifteen', google translation) + - "⑯": [T: "umkreiste sechzehn"] # 0x246f (en: 'circled sixteen', google translation) + - "⑰": [T: "siebzehn umkreist"] # 0x2470 (en: 'circled seventeen', google translation) + - "⑱": [T: "eingekreist"] # 0x2471 (en: 'circled eighteen', google translation) + - "⑳": [T: "zwanzig umkreist"] # 0x2473 (en: 'circled twenty', google translation) + - "⑴-⑼": # 0x2474 - 0x247d + - T: "klammern" # (en: 'parenthesized', google translation) + - spell: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" + - "⑽": [T: "klammern zehn"] # 0x247d (en: 'parenthesized ten', google translation) + - "⑾": [T: "klammern elf"] # 0x247e (en: 'parenthesized eleven', google translation) + - "⑿": [T: "klammern zwölf"] # 0x247f (en: 'parenthesized twelve', google translation) + - "⒀": [T: "klammern dreizehn"] # 0x2480 (en: 'parenthesized thirteen', google translation) + - "⒁": [T: "klammern vierzehn"] # 0x2481 (en: 'parenthesized fourteen', google translation) + - "⒂": [T: "klammern fünfzehn"] # 0x2482 (en: 'parenthesized fifteen', google translation) + - "⒃": [T: "klammern sechzehn"] # 0x2483 (en: 'parenthesized sixteen', google translation) + - "⒄": [T: "klammern siebzehn"] # 0x2484 (en: 'parenthesized seventeen', google translation) + - "⒅": [T: "klammern"] # 0x2485 (en: 'parenthesized eighteen', google translation) + - "⒆": [T: "klammern neunzehn"] # 0x2486 (en: 'parenthesized nineteen', google translation) + - "⒇": [T: "klammern von zwanzig"] # 0x2487 (en: 'parenthesized twenty', google translation) + - "⒈-⒐": # 0x2488 - 0x2491 + - spell: "translate('.', '⒈⒉⒊⒋⒌⒍⒎⒏⒐', '123456789')" + - T: "mit periode" # (en: 'with period', google translation) + - "⒑": [T: "zehn mit periode"] # 0x2491 (en: 'ten with period', google translation) + - "⒒": [T: "elf mit periode"] # 0x2492 (en: 'eleven with period', google translation) + - "⒓": [T: "zwölf mit periode"] # 0x2493 (en: 'twelve with period', google translation) + - "⒔": [T: "dreizehn mit periode"] # 0x2494 (en: 'thirteen with period', google translation) + - "⒕": [T: "vierzehn mit periode"] # 0x2495 (en: 'fourteen with period', google translation) + - "⒖": [T: "fünfzehn mit periode"] # 0x2496 (en: 'fifteen with period', google translation) + - "⒗": [T: "16 mit periode"] # 0x2497 (en: 'sixteen with period', google translation) + - "⒘": [T: "siebzehn mit periode"] # 0x2498 (en: 'seventeen with period', google translation) + - "⒙": [T: "mit periode gefressen"] # 0x2499 (en: 'eighteen with period', google translation) + - "⒚": [T: "neunzehn mit periode"] # 0x249a (en: 'nineteen with period', google translation) + - "⒛": [T: "zwanzig mit periode"] # 0x249b (en: 'twenty with period', google translation) + - "⒜-⒵": # 0x249c - 0x24b5 + - T: "klammern" # (en: 'parenthesized', google translation) + - spell: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" + + - "Ⓐ-Ⓩ": + - T: "eingekreist" # (en: 'circled', google translation) + - spell: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 + - T: "eingekreist" # (en: 'circled', google translation) + - spell: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" + - "⓪": [T: "eingekreist null"] # 0x24ea (en: 'circled zero', google translation) + - "⓫": [T: "schwarz eingekreiste elf"] # 0x24eb (en: 'black circled eleven', google translation) + - "⓬": [T: "schwarz eingekreiste zwölf"] # 0x24ec (en: 'black circled twelve', google translation) + - "⓭": [T: "schwarz eingekreiste dreizehn"] # 0x24ed (en: 'black circled thirteen', google translation) + - "⓮": [T: "schwarz eingekreiste vierzehn"] # 0x24ee (en: 'black circled fourteen', google translation) + - "⓯": [T: "schwarz eingekreiste fünfzehn"] # 0x24ef (en: 'black circled fifteen', google translation) + - "⓰": [T: "schwarz eingekreiste sechzehn"] # 0x24f0 (en: 'black circled sixteen', google translation) + - "⓱": [T: "schwarz eingekreiste siebzehn"] # 0x24f1 (en: 'black circled seventeen', google translation) + - "⓲": [T: "schwarz eingekreiste achtzehn"] # 0x24f2 (en: 'black circled eighteen', google translation) + - "⓳": [T: "schwarz eingekreiste neunzehn"] # 0x24f3 (en: 'black circled nineteen', google translation) + - "⓴": [T: "schwarz eingekreiste zwanzig"] # 0x24f4 (en: 'black circled twenty', google translation) + - "⓵-⓽": # 0x24f5 - 0x24fe + - T: "doppelt umkreist" # (en: 'double circled', google translation) + - spell: "translate('.', '⓵⓶⓷⓸⓹⓺⓻⓼⓽', '123456789')" + - "⓾": [T: "doppelt umgekreiste zehn"] # 0x24fe (en: 'double circled ten', google translation) + - "⓿": [T: "schwarz eingekreiste null"] # 0x24ff (en: 'black circled zero', google translation) + - "■": [T: "Schwarzes Quadrat"] # 0x25a0 (en: 'black square', MathPlayer: 'black square', google: 'schwarzes quadrat') + - "□": [T: "Weißes Quadrat"] # 0x25a1 (en: 'white square', MathPlayer: 'white square', google: 'weißes quadrat') + - "▢": [T: "Weißes Quadrat mit abgerundeten Ecken"] # 0x25a2 (en: 'white square with rounded corners', google: 'weißes quadrat mit abgerundeten ecken') + - "▣": [T: "Weißes Quadrat, das schwarzes kleines Quadrat enthält"] # 0x25a3 (en: 'white square containing small black square', google: 'weißes quadrat mit kleinem schwarzem quadrat') + - "▤": [T: "Quadrat mit horizontaler Füllung"] # 0x25a4 (en: 'square with horizontal fill', google: 'quadrat mit horizontaler füllung') + - "▥": [T: "Quadrat mit vertikaler Füllung"] # 0x25a5 (en: 'square with vertical fill', google: 'quadrat mit vertikaler füllung') + - "▦": [T: "Quadrat mit orthogonaler Schraffurfüllung"] # 0x25a6 (en: 'square with orthogonal crosshatch fill', google: 'quadrat mit orthogonaler kreuzungsfüllung') + - "▧": [T: "Quadrat mit Füllung von oben links nach rechts unten"] # 0x25a7 (en: 'square with upper left to lower right fill', google: 'quadratisch mit oberen links nach unten rechts füllung') + - "▨": [T: "Quadrat mit Füllung von oben recht nach links unten"] # 0x25a8 (en: 'square with upper right to lower left fill', google: 'quadrat mit der oberen rechten linken füllung') + - "▩": [T: "Quadrat mit diagonaler Schraffurfüllung"] # 0x25a9 (en: 'square with diagonal crosshatch fill', google: 'quadrat mit diagonaler kreuzungsfüllung') + - "▪": [T: "Schwarzes kleines Quadrat"] # 0x25aa (en: 'black small square', MathPlayer: 'black square', google: 'schwarzes kleines quadrat') + - "▫": [T: "Weißes kleines Quadrat"] # 0x25ab (en: 'white small square', MathPlayer: 'white square', google: 'weißes kleines quadrat') + - "▬": [T: "Schwarzes Rechteck"] # 0x25ac (en: 'black rectangle', google: 'schwarzes rechteck') + - "▭": [T: "Weißes Rechteck"] # 0x25ad (en: 'white rectangle', MathPlayer: 'white rectangle', google: 'weißes rechteck') + - "▮": [T: "Schwarzes vertikales Rechteck"] # 0x25ae (en: 'black vertical rectangle', MathPlayer: 'black vertical rectangle', google: 'schwarzes vertikales rechteck') + - "▯": [T: "Weißes vertikales Rechteck"] # 0x25af (en: 'white vertical rectangle', MathPlayer: 'white vertical rectangle', google: 'weißes vertikales rechteck') + - "▰": [T: "Schwarzes Parallelogramm"] # 0x25b0 (en: 'black parallelogram', google: 'schwarzes parallelogramm') + - "▱": [T: "Weißes Parallelogramm"] # 0x25b1 (en: 'white parallelogram', MathPlayer: 'white parallelogram', google: 'weißes parallelogramm') + - "▲": [T: "Schwarzes nach oben zeigendes Dreieck"] # 0x25b2 (en: 'black up pointing triangle', MathPlayer: 'black up pointing triangle', google: 'schwarz nach oben zeigt dreieck') + - "△": [T: "Weißes nach oben zeigendes Dreieck"] # 0x25b3 (en: 'white up pointing triangle', MathPlayer: 'white up pointing triangle', google: 'weiß nach oben zeigendreieck') + - "▴": [T: "Schwarzes nach oben zeigendes kleines Dreieck"] # 0x25b4 (en: 'black up pointing small triangle', MathPlayer: 'black up pointing triangle', google: 'schwarz nach oben zeigt ein kleines dreieck') + - "▵": [T: "Weißes nach oben zeigendes kleines Dreieck"] # 0x25b5 (en: 'white up pointing small triangle', MathPlayer: 'white up pointing triangle', google: 'weiß nach oben zeigt ein kleines dreieck') + - "▶": [T: "Schwarzes nach rechts zeigendes Dreieck"] # 0x25b6 (en: 'black right pointing triangle', MathPlayer: 'black right pointing triangle', google: 'schwarzes rechte dreieck') + - "▷": [T: "Weißes nach rechts zeigendes Dreieck"] # 0x25b7 (en: 'white right pointing triangle', MathPlayer: 'white right pointing triangle', google: 'weißes rechtes dreieck') + - "▸": [T: "Schwarzes nach rechts zeigendes kleines Dreieck"] # 0x25b8 (en: 'black right pointing small triangle', MathPlayer: 'black right pointing triangle', google: 'schwarzer rechts kleines dreieck') + - "▹": [T: "Weißes nach rechts zeigendes kleines Dreieck"] # 0x25b9 (en: 'white right pointing small triangle', MathPlayer: 'right pointing triangle', google: 'weißer rechts kleines dreieck') + - "►": [T: "Schwarzer nach rechts zeigender Zeiger"] # 0x25ba (en: 'black right pointing pointer', google: 'schwarzer rechter zeiger') + - "▻": [T: "Weißer nach rechts zeigender Zeiger"] # 0x25bb (en: 'white right pointing pointer', google: 'weißer rechts zeiger') + - "▼": [T: "Schwarzes Abwärtsdreieck"] # 0x25bc (en: 'black down pointing triangle', MathPlayer: 'black down pointing triangle', google: 'schwarzes down -dreieck') + - "▽": [T: "Weißes Abwärtsdreieck"] # 0x25bd (en: 'white down pointing triangle', MathPlayer: 'white down pointing triangle', google: 'weiß down dreieck') + - "▾": [T: "Schwarzes kleines Abwärtsdreieck"] # 0x25be (en: 'black down pointing small triangle', MathPlayer: 'black down pointing triangle', google: 'schwarz unten zeigt ein kleines dreieck') + - "▿": [T: "Weißes kleines Abwärtsdreieck"] # 0x25bf (en: 'white down pointing small triangle', MathPlayer: 'white down pointing triangle', google: 'weiß down zeigt kleines dreieck') + - "◀": [T: "Schwarzes nach links zeigendes Dreieck"] # 0x25c0 (en: 'black left pointing triangle', MathPlayer: 'black left pointing triangle', google: 'schwarzes linker dreieck') + - "◁": [T: "Weißes nach links zeigendes Dreieck"] # 0x25c1 (en: 'white left pointing triangle', MathPlayer: 'white left pointing triangle', google: 'weißes linker dreieck') + - "◂": [T: "Schwarzes nach links zeigendes kleines Dreieck"] # 0x25c2 (en: 'black left pointing small triangle', MathPlayer: 'black left pointing triangle', google: 'schwarz links zeigt ein kleines dreieck') + - "◃": [T: "Weißes nach links zeigendes kleines Dreieck"] # 0x25c3 (en: 'white left pointing small triangle', MathPlayer: 'white left pointing triangle', google: 'weiß links kleines dreieck') + - "◄": [T: "Schwarzer nach links zeigender Zeiger"] # 0x25c4 (en: 'black left pointing pointer', MathPlayer: 'black left pointing pointer', google: 'schwarzer links zeigter zeiger') + - "◅": [T: "Weißer nach links zeigender Zeiger"] # 0x25c5 (en: 'white left pointing pointer', MathPlayer: 'white left pointing pointer', google: 'weißer links zeiger zeiger') + - "◆": [T: "Schwarzer Diamant"] # 0x25c6 (en: 'black diamond', MathPlayer: 'black diamond', google: 'schwarzer diamant') + - "◇": [T: "Weißer Diamant"] # 0x25c7 (en: 'white diamond', MathPlayer: 'white diamond', google: 'weißer diamant') + - "◈": [T: "Weißer Diamant mit schwarzem kleinem Diamant"] # 0x25c8 (en: 'white diamond containing black small diamond', MathPlayer: 'white diamond containing black diamond', google: 'weißer diamant mit schwarzem kleinem diamanten') + - "◉": [T: "Fischauge"] # 0x25c9 (SRE: 'Fischauge') + - "◊": [T: "Raute"] # 0x25ca (en: 'lozenge', MathPlayer: 'lozenge', google: 'pastille') + - "○": [T: "Weißer Kreis"] # 0x25cb (en: 'white circle', MathPlayer: 'white circle', google: 'weißer kreis') + - "◌": [T: "Gepunkteter weißer Kreis"] # 0x25cc (en: 'dotted circle', MathPlayer: 'dotted circle', google: 'gepunkteter kreis') + - "◍": [T: "Kreis mit vertikaler Füllung"] # 0x25cd (en: 'circle with vertical fill', MathPlayer: 'circle with vertical fill', google: 'kreis mit vertikaler füllung') + - "◎": [T: "Volltreffer"] # 0x25ce (SRE: 'Bullseye') + - "●": [T: "Schwarzer Kreis"] # 0x25cf (en: 'black circle', MathPlayer: 'black circle', google: 'schwarzer kreis') + - "◐": [T: "Kreis mit linker Hälfte schwarz"] # 0x25d0 (en: 'circle with left half black', MathPlayer: 'circle with left half black', google: 'kreis mit dem linken halben schwarz') + - "◑": [T: "Kreis mit rechter Hälfte schwarz"] # 0x25d1 (en: 'circle with right half black', MathPlayer: 'circle with right half black', google: 'kreis mit dem rechten halb schwarz') + - "◒": [T: "Kreis mit unterer Hälfte schwarz"] # 0x25d2 (en: 'circle with lower half black', MathPlayer: 'circle with lower half black', google: 'kreis mit unterer halb schwarz') + - "◓": [T: "Kreis mit oberer Hälfte schwarz"] # 0x25d3 (en: 'circle with upper half black', MathPlayer: 'circle with upper half black', google: 'kreis mit der oberen hälfte schwarz') + - "◔": [T: "Kreis mit oberem rechten Quadranten schwarz"] # 0x25d4 (en: 'circle with upper right quadrant black', MathPlayer: 'circle with upper right quadrant black', google: 'kreis mit dem oberen rechten quadranten schwarz') + - "◕": [T: "Kreis mit ganzem oberen linken Quadranten schwarz"] # 0x25d5 (en: 'circle with all but upper left quadrant black', MathPlayer: 'circle with all but upper left quadrant black', google: 'kreisen sie mit allen außer oberen linken quadranten schwarz') + - "◖": [T: "Linker halber schwarzer Kreis"] # 0x25d6 (en: 'left half black circle', MathPlayer: 'left half black circle', google: 'links halb schwarzer kreis') + - "◗": [T: "rechter halber schwarzer Kreis"] # 0x25d7 (en: 'right half black circle', MathPlayer: 'right half black circle', google: 'rechte halbe schwarze kreis') + - "◘": [T: "Inverse Kugel"] # 0x25d8 (en: 'inverse bullet', MathPlayer: 'inverse bullet', google: 'inverse kugel') + - "◙": [T: "Inverser weißer Kreis"] # 0x25d9 (en: 'inverse white circle', MathPlayer: 'inverse white circle', google: 'inverser weißer kreis') + - "◚": [T: "Umgekehrter weißer Kreis der oberen Hälfte"] # 0x25da (en: 'upper half inverse white circle', MathPlayer: 'upper half inverse white circle', google: 'inverse weißer kreis der oberen hälfte') + - "◛": [T: "Umgekehrter weißer Kreis der unteren Hälfte"] # 0x25db (en: 'lower half inverse white circle', MathPlayer: 'lower half inverse white circle', google: 'untere hälfte inverser weißer kreis') + - "◜": [T: "Kreisbogen im oberen linken Quadranten"] # 0x25dc (en: 'upper left quadrant circular arc', MathPlayer: 'upper left quadrant circular arc', google: 'oberer linker quadrantenkreisbogen') + - "◝": [T: "Kreisbogen im oberen rechten Quadranten"] # 0x25dd (en: 'upper right quadrant circular arc', MathPlayer: 'upper right quadrant circular arc', google: 'oberer rechter quadrant kreisbogen') + - "◞": [T: "Kreisbogen im rechten unteren Quadranten"] # 0x25de (en: 'lower right quadrant circular arc', MathPlayer: 'lower right quadrant circular arc', google: 'unterer rechts quadrant zirkularbogen') + - "◟": [T: "Kreisbogen im unteren linken Quadranten"] # 0x25df (en: 'lower left quadrant circular arc', MathPlayer: 'lower left quadrant circular arc', google: 'unterer linker quadrantenkreisbogen') + - "◠": [T: "Oberer Halbkreis"] # 0x25e0 (en: 'upper half circle', MathPlayer: 'upper half circle', google: 'oberer halbkreis') + - "◡": [T: "Unterer Halbkreis"] # 0x25e1 (en: 'lower half circle', MathPlayer: 'lower half circle', google: 'unterer halbkreis') + - "◢": [T: "Schwarzes unteres rechtes Dreieck"] # 0x25e2 (en: 'black lower right triangle', MathPlayer: 'black lower right triangle', google: 'schwarz unten rechts dreieck') + - "◣": [T: "Schwarzes unteres linkes Dreieck"] # 0x25e3 (en: 'black lower left triangle', MathPlayer: 'black lower left triangle', google: 'schwarzes unteres linke dreieck') + - "◤": [T: "Schwarzes oberes linkes Dreieck"] # 0x25e4 (en: 'black upper left triangle', MathPlayer: 'black upper left triangle', google: 'schwarzes oberes linksdreieck') + - "◥": [T: "Schwarzes oberes rechtes Dreieck"] # 0x25e5 (en: 'black upper right triangle', MathPlayer: 'black upper right triangle', google: 'schwarzes oberes rechtes dreieck') + - "◦": [T: "Weiße Kugel"] # 0x25e6 (en: 'composition', MathPlayer: 'composition', google: 'komposition') + - "◧": [T: "Quadrat mit linker Hälfte schwarz"] # 0x25e7 (en: 'square with left half black', MathPlayer: 'square with left half black', google: 'quadrat mit linksem halb schwarz') + - "◨": [T: "Quadrat mit rechter Hälfte schwarz"] # 0x25e8 (en: 'square with right half black', MathPlayer: 'square with right half black', google: 'quadrat mit dem rechten halben schwarz') + - "◩": [T: "Quadrat mit der oberen linken Diagonalenhälfte schwarz"] # 0x25e9 (en: 'square with upper left half black', MathPlayer: 'square with upper left half black', google: 'quadrat mit oberen linken halben schwarz') + - "◪": [T: "Quadrat mit unterer rechter Diagonalhälfte schwarz"] # 0x25ea (en: 'square with lower right half black', MathPlayer: 'square with lower right half black', google: 'quadratisch mit unterer rechter halb schwarz') + - "◫": [T: "Weißes Quadrat mit senkrechter Linie"] # 0x25eb (en: 'white square with bisecting line', MathPlayer: 'white square with bisecting line', google: 'weißes quadrat mit halbierender linie') + - "◬": [T: "Weißes nach oben zeigendes Dreieck mit Punkt"] # 0x25ec (en: 'white up pointing triangle with dot', MathPlayer: 'white up pointing triangle with dot', google: 'weiß nach oben zeigte dreieck mit punkt') + - "◭": [T: "Aufwärtszeigendes Dreieck mit linker Hälfte schwarz"] # 0x25ed (en: 'up pointing triangle with left half black', MathPlayer: 'up pointing triangle with left half black', google: 'dreieck mit dem linken halben schwarz zeigen') + - "◮": [T: "Aufwärtszeigendes Dreieck mit rechter Hälfte schwarz"] # 0x25ee (en: 'up pointing triangle with right half black', MathPlayer: 'up pointing triangle with right half black', google: 'dreieck mit dem rechten halben schwarz zeigen') + - "◯": [T: "Großer Kreis"] # 0x25ef (en: 'large circle', MathPlayer: 'large circle', google: 'großer kreis') + - "◰": [T: "Weißes Quadrat mit kleinem Quadrat im oberem linken Quadranten"] # 0x25f0 (en: 'white square with upper left quadrant', google: 'weißes quadrat mit oberen linken quadrant') + - "◱": [T: "Weißes Quadrat mit kleinem Quadrat im unterem linken Quadranten"] # 0x25f1 (en: 'white square with lower left quadrant', google: 'weißes quadrat mit unteren linken quadranten') + - "◲": [T: "Weißes Quadrat mit kleinem Quadrat im unterem rechten Quadranten"] # 0x25f2 (en: 'white square with lower right quadrant', google: 'weißes quadrat mit unten rechts quadrant') + - "◳": [T: "Weißes Quadrat mit kleinem Quadrat im rechtem oberen Quadranten"] # 0x25f3 (en: 'white square with upper right quadrant', google: 'weißes quadrat mit oberen rechten quadrant') + - "◴": [T: "Weißer Kreis mit kleinem Kreis im oberem linkem Quadranten"] # 0x25f4 (en: 'white circle with upper left quadrant', google: 'weißer kreis mit oberen linken quadrant') + - "◵": [T: "Weißer Kreis mit kleinem Kreis im unterem linken Quadranten"] # 0x25f5 (en: 'white circle with lower left quadrant', google: 'weißer kreis mit unteren linken quadranten') + - "◶": [T: "Weißer Kreis mit kleinem Kreis im unterem rechten Quadranten"] # 0x25f6 (en: 'white circle with lower right quadrant', google: 'weißer kreis mit unten rechts quadrant') + - "◷": [T: "Weißer Kreis mit kleinem Kreis im rechtem oberen Quadranten"] # 0x25f7 (en: 'white circle with upper right quadrant', google: 'weißer kreis mit oben rechts quadrant') + - "◸": [T: "Oberes linkes Dreieck"] # 0x25f8 (en: 'upper left triangle', MathPlayer: 'upper left triangle', google: 'oberes linker dreieck') + - "◹": [T: "Oberes rechtes Dreieck"] # 0x25f9 (en: 'upper right triangle', MathPlayer: 'upper right triangle triangle', google: 'ober rechtes dreieck') + - "◺": [T: "Unteres linkes Dreieck"] # 0x25fa (en: 'lower left triangle', MathPlayer: 'lower left triangle', google: 'unteres linker dreieck') + - "◻": [T: "Weißes mittleres Quadrat"] # 0x25fb (en: 'white medium square', MathPlayer: 'white medium square', google: 'weißes mittleres quadrat') + - "◼": [T: "Schwarzes mittleres kleines Quadrat"] # 0x25fc (en: 'black medium square', MathPlayer: 'black medium square', google: 'schwarzes mittleres quadrat') + - "◽": [T: "Weißes mittleres Quadrat"] # 0x25fd (en: 'white medium small square', MathPlayer: 'white medium square', google: 'weißes mittleres kleines quadrat') + - "◾": [T: "Schwarzes mittleres Quadrat"] # 0x25fe (en: 'black medium small square', MathPlayer: 'black medium square', google: 'schwarzes mittel kleiner quadrat') + - "◿": [T: "Unteres rechtes Dreieck"] # 0x25ff (en: 'lower right triangle', MathPlayer: 'lower right triangle', google: 'unten rechts dreieck') + - "♠": [T: "schwarzes Piksymbol"] # 0x2660 (google: 'schwarzer spatenanzug') + - "♡": [T: "weißes Herz"] # 0x2661 (google: 'weißer herzanzug') + - "♢": [T: "weißes Karo"] # 0x2662 (google: 'weißer diamantanzug') + - "♣": [T: "schwarzes Kreuzsymbol"] # 0x2663 (google: 'schwarzer clubanzug') + - "♤": [T: "weißes Piksymbol"] # 0x2664 (google: 'weißer spatenanzug') + - "♥": [T: "schwarzes Herz"] # 0x2665 (google: 'schwarzer herzanzug') + - "♦": [T: "schwarzes Karo"] # 0x2666 (google: 'schwarzer diamantanzug') + - "♧": [T: "weißes Kreuzsymbol"] # 0x2667 (google: 'weißer clubanzug') + - "❨": [T: "Mittlere linke Klammerverzierung"] # 0x2768 (en: 'medium left parentheses ornament', google: 'mittel linke klammern') + - "❩": [T: "Mittlere rechte Klammerverzierung"] # 0x2769 (en: 'medium right parentheses ornament', google: 'mittel rechts klammernsthesis ornament') + - "❪": [T: "Mittlere abgeflachte linke Klammerverzierung"] # 0x276a (en: 'medium flattened left parentheses ornament', google: 'medium abgeflachtes linker klammern') + - "❫": [T: "Mittlere abgeflachte rechte Klammerverzierung"] # 0x276b (en: 'medium flattened right parentheses ornament', google: 'mittel abgeflacht rechte klammerthese -ornament') + - "❬": [T: "Mittlere nach links weisende Winkelhalterung"] # 0x276c (en: 'medium left-pointing angle bracket ornament', google: 'mittelgroße linkswinkel-klammerverzierung') + - "❭": [T: "Mittlere, rechtwinklige Winkelhalterung"] # 0x276d (en: 'medium right-pointing angle bracket ornament', google: 'mittel mit dem rechten zeigungswinkelhalterung') + - "❮": [T: "Dickes nach links weisendes Anführungszeichen"] # 0x276e (en: 'heavy left-pointing angle quotation mark ornament', google: 'schwerer zitat für den linken zeigungswinkel mark ornament') + - "❯": [T: "Dickes nach links weisendes Anführungszeichen"] # 0x276f (en: 'heavy right-pointing angle quotation mark ornament', google: 'schwerer rechts zeigter winkel zitat mark ornament') + - "❰": [T: "schweres, nach links zeigendes eckiges Klammerornament"] # 0x2770 (en: 'heavy left-pointing angle bracket ornament', google: 'schwere linkswinkel-halterung') + - "❱": [T: "schweres, nach rechts zeigendes eckiges Klammerornament"] # 0x2771 (en: 'heavy right-pointing angle bracket ornament', google: 'schwere rechtshalterung mit rechts zeigter winkel') + - "❲": [T: "Leichte Halterung aus Schildpatt, links"] # 0x2772 (en: 'light left tortoise shell bracket ornament', google: 'leichte linke schildkröte -hülle -halterung') + - "❳": [T: "Leichte Halterung aus Schildpatt, rechts"] # 0x2773 (en: 'light right tortoise shell bracket ornament', google: 'leichte rechte schildkröte -hülle -halterung') + - "❴": [T: "Mittlere linke geschweifte Klammerverzierung"] # 0x2774 (en: 'medium left brace ornament', google: 'medium linke klammerverzierung') + - "❵": [T: "Mittlere rechte geschweifte Klammerverzierung"] # 0x2775 (en: 'medium right brace ornament', google: 'mittlere rechte klammerverzierung') + - "❶": [T: "schwarz umkreiste eins"] # 0x2776 (en: 'black circled one', google translation) + - "❷": [T: "schwarz umkreiste zwei"] # 0x2777 (en: 'black circled two', google translation) + - "❸": [T: "schwarz umkreiste drei"] # 0x2778 (en: 'black circled three', google translation) + - "❹": [T: "schwarz umkreiste vier"] # 0x2779 (en: 'black circled four', google translation) + - "❺": [T: "schwarz umkreiste fünf"] # 0x277a (en: 'black circled five', google translation) + - "❻": [T: "schwarz umkreiste sechs"] # 0x277b (en: 'black circled six', google translation) + - "❼": [T: "schwarz umkreiste sieben"] # 0x277c (en: 'black circled seven', google translation) + - "❽": [T: "schwarz umumkreist nach"] # 0x277d (en: 'black circled eight', google translation) + - "❾": [T: "schwarz umreiste neun"] # 0x277e (en: 'black circled nine', google translation) + - "❿": [T: "schwarz umkreiste zehn"] # 0x277f (en: 'black circled ten', google translation) + - "➀": [T: "umkreiste eins ohne serife"] # 0x2780 (en: 'circled sans serif one', google translation) + - "➁": [T: "umkreiste zwei ohne serife"] # 0x2781 (en: 'circled sans serif two', google translation) + - "➂": [T: "umkreiste drei hne serife "] # 0x2782 (en: 'circled sans serif three', google translation) + - "➃": [T: "umkreiste vier ohne serife"] # 0x2783 (en: 'circled sans serif four', google translation) + - "➄": [T: "umkreite fünf ohne serife"] # 0x2784 (en: 'circled sans serif five', google translation) + - "➅": [T: "umkreiste sechs ohne serife"] # 0x2785 (en: 'circled sans serif six', google translation) + - "➆": [T: "umkreiste sieben ohne serife"] # 0x2786 (en: 'circled sans serif seven', google translation) + - "➇": [T: "umkreiste acht ohne serife"] # 0x2787 (en: 'circled sans serif eight', google translation) + - "➈": [T: "umkreiste neun ohne serife"] # 0x2788 (en: 'circled sans serif nine', google translation) + - "➉": [T: "umkreiste zehn ohne serife"] # 0x2789 (en: 'circled sans serif ten', google translation) + - "➊": [T: "schwarz umkreiste eins ohne serife"] # 0x278a (en: 'black circled sans serif one', google translation) + - "➋": [T: "schwarz umkreiste zwei ohne serife"] # 0x278b (en: 'black circled sans serif two', google translation) + - "➌": [T: "schwarz umkreiste drei ohne serife"] # 0x278c (en: 'black circled sans serif three', google translation) + - "➍": [T: "schwarz umkreiste vier ohne serife"] # 0x278d (en: 'black circled sans serif four', google translation) + - "➎": [T: "schwarz umkreiste fünf ohne serife"] # 0x278e (en: 'black circled sans serif five', google translation) + - "➏": [T: "schwarz umkreiste sechs ohne serife"] # 0x278f (en: 'black circled sans serif six', google translation) + - "➐": [T: "schwarz umkreiste sieben ohne serife"] # 0x2790 (en: 'black circled sans serif seven', google translation) + - "➑": [T: "schwarz umkreiste acht ohne serife "] # 0x2791 (en: 'black circled sans serif eight', google translation) + - "➒": [T: "schwarz umkreiste neun ohne serife"] # 0x2792 (en: 'black circled sans serif nine', google translation) + - "➓": [T: "schwarz umkreiste zehn ohne serife"] # 0x2793 (en: 'black circled sans serif ten', google translation) + - "➔": [T: "Schwerer, breitköpfiger nach rechts gerichteter Pfeil"] # 0x2794 (en: 'heavy wide-headed rightwards arrow', google: 'schwerer breiter arrow') + - "➕": [T: "dickes großes Pluszeichen"] # 0x2795 (en: 'heavy plus sign', google: 'schweres pluszeichen') + - "➖": [T: "dickes großes Minuszeichen"] # 0x2796 (en: 'heavy minus sign', google: 'schweres minuszeichen') + - "➗": [T: "dickes großes Divisionszeichen"] # 0x2797 (en: 'heavy division sign', google: 'schweres divisionszeichen') + - "➘": [T: "Starker Südostpfeil"] # 0x2798 (en: 'heavy south east arrow', google: 'schwerer südostpfeil') + - "➙": [T: "Starker Pfeil nach rechts"] # 0x2799 (en: 'heavy rightwards arrow', google: 'schwerer rechts pfeil') + - "➚": [T: "Starker Nordostpfeil"] # 0x279a (en: 'heavy north east arrow', google: 'schwerer nordostpfeil') + - "➛": [T: "Zeichnungszeichen Pfeil nach rechts"] # 0x279b (en: 'drafting point rightwards arrow', google: 'ausgangspunkt rechts von pfeil') + - "➜": [T: "Starker Pfeil mit runder Spitze nach rechts"] # 0x279c (en: 'heavy round-tipped rightwards arrow', google: 'schwerer pfeil nach rechts') + - "➝": [T: "Dreieckköpfiger Pfeil nach rechts"] # 0x279d (en: 'triangle-headed rightwards arrow', google: 'dreieck köpfig mit rechtsem pfeil') + - "➞": [T: "Schwerer Dreieckspfeil nach rechts"] # 0x279e (en: 'heavy triangle-headed rightwards arrow', google: 'schwerer pfeil mit dreieck-köpfen') + - "➟": [T: "Dicker Pfeil nach rechts"] # 0x279f (en: 'dashed triangle-headed rightwards arrow', google: 'dreieck köpfig nach rechtsem pfeil') + - "➠": [T: "Dicker, gestrichelter Dreieckspfeil nach rechts"] # 0x27a0 (en: 'heavy dashed triangle-headed rightwards arrow', google: 'schwerer, geschnittenes dreieck-köpfiger pfeil nach rechts') + - "➡": [T: "Dicker Pfeil nach rechts"] # 0x27a1 (en: 'black rightwards arrow', google: 'schwarzer pfeil nach rechts') + - "➢": [T: "Dreidimensionale, nach oben beleuchtete Pfeilspitze nach rechts"] # 0x27a2 (en: 'three d top lighted rightwards arrow', google: 'drei d top leuchtet nach rechts') + - "➣": [T: "Dreidimensionale, von unten beleuchtete Pfeilspitze nach rechts"] # 0x27a3 (en: 'three d bottom lighted rightwards arrow', google: 'drei d bottom beleuchtet nach rechts') + - "➤": [T: "Schwarze Pfeilspitze nach rechts"] # 0x27a4 (en: 'black rightwards arrowhead', google: 'schwarz rechts pfeilspitze') + - "➥": [T: "Schwerer schwarzer Pfeil nach unten und rechts gebogen"] # 0x27a5 (en: 'heavy black curved downwards and rightwards arrow', google: 'schwerer schwarz gebrüht nach unten und rechts pfeil') + - "➦": [T: "Schwerer schwarzer Pfeil nach oben und rechts gebogen"] # 0x27a6 (en: 'heavy black curved upwards and rightwards arrow', google: 'schwerer schwarz nach oben gebogen und rechts pfeil') + - "➧": [T: "Schwarzer kurzer nach rechts gerichteter Pfeil"] # 0x27a7 (en: 'squat black rightwards arrow', google: 'hocke black rightwards pfeil') + - "➨": [T: "Schwerer konkaver Spitze-Pfeil nach rechts"] # 0x27a8 (en: 'heavy concave-pointed black rightwards arrow', google: 'schwerer konkavspunkter schwarzer pfeil nach rechts') + - "➩": [T: "Rechts geschatteter weißer Pfeil nach rechts"] # 0x27a9 (en: 'right-shaded white rightwards arrow', google: 'right shaded white rightwards pfeil') + - "➪": [T: "Links schattierter weißer Pfeil nach rechts"] # 0x27aa (en: 'left-shaded white rightwards arrow', google: 'linksschattierte weiße pfeil nach rechts') + - "➫": [T: "Zurückgekippter, beschatteter weißer Pfeil nach rechts"] # 0x27ab (en: 'back-tilted shadowed white rightwards arrow', google: 'rückgedünnter weißer weißer pfeil nach rechts') + - "➬": [T: "Vorne geneigter, beschatteter weißer Pfeil nach rechts"] # 0x27ac (en: 'front-tilted shadowed white rightwards arrow', google: 'frontgeflodeltes weißer weißer pfeil nach rechts') + - "➭": [T: "Schwerer unterer rechter Schatten mit weißem Pfeil nach rechts"] # 0x27ad (en: 'heavy lower right-shadowed white rightwards arrow', google: 'schwere, rechte schatten mit weißem recht nach rechts') + - "➮": [T: "Schwerer oberer rechter Schatten mit weißem Pfeil nach rechts"] # 0x27ae (en: 'heavy upper right-shadowed white rightwards arrow', google: 'schwere obere rechte schattenhafte weiße rechts pfeil') + - "➯": [T: "Unten gekerbter Pfeil nach rechts"] # 0x27af (en: 'notched lower right-shadowed white rightwards arrow', google: 'gekerbte rechte rechten weißen pfeil nach rechts') + - "➱": [T: "Uben gekerbter Pfeil nach rechts"] # 0x27b1 (en: 'notched upper right-shadowed white rightwards arrow', google: 'gekerbte obere rechte schattenhafte weiße pfeil nach rechts') + - "➲": [T: "Eingekreister schwerer weißer Pfeil nach rechts"] # 0x27b2 (en: 'circled heavy white rightwards arrow', google: 'umgekreist schweren weißen pfeil nach rechts') + - "➳": [T: "Pfeil mit weißer Feder nach rechts"] # 0x27b3 (en: 'white-feathered rightwards arrow', google: 'weiß gefiederter pfeil nach rechts') + - "➴": [T: "Schwarz-gefiederter Südostpfeil"] # 0x27b4 (en: 'black-feathered south east arrow', google: 'schwarz gefiederter südöstlicher pfeil') + - "➵": [T: "chwarz-gefiederter Pfeil nach rechts"] # 0x27b5 (en: 'black-feathered rightwards arrow', google: 'schwarz gefiederter pfeil nach rechts') + - "➶": [T: "Schwarzgefiederter Nordostpfeil"] # 0x27b6 (en: 'black-feathered north east arrow', google: 'schwarz gefiederter nordostpfeil') + - "➷": [T: "Schwerer schwarzgefiederter Südostpfeil"] # 0x27b7 (en: 'heavy black-feathered south east arrow', google: 'schwerer schwarz gefiederter südostpfeil') + - "➸": [T: "Schwarzgefiederter Pfeil nach rechts"] # 0x27b8 (en: 'heavy black-feathered rightwards arrow', google: 'schwerer schwarz gefiederter pfeil nach rechts') + - "➹": [T: "Schwarzgefiederter Nordostpfeil"] # 0x27b9 (en: 'heavy black-feathered north east arrow', google: 'schwerer schwarz gefiederter nordostpfeil') + - "➺": [T: "Teradrop-Pfeil nach rechts mit Haken"] # 0x27ba (en: 'teradrop-barbed rightwards arrow', google: 'teradrop-barded mit rechtsem pfeil') + - "➻": [T: "Schwerer Pfeil mit tropfenförmigem Schaft, nach rechts gebogen"] # 0x27bb (en: 'heavy teardrop-shanked rightwards arrow', google: 'schwere tränenverschiebung nach rechts pfeil') + - "➼": [T: "Keilförmiger Pfeil nach rechts"] # 0x27bc (en: 'wedge-tailed rightwards arrow', google: 'keilschwanz rechts pfeil') + - "➽": [T: "Schwerer, nach rechts gekeilter Pfeil"] # 0x27bd (en: 'heavy wedge-tailed rightwards arrow', google: 'schwerer keilschwanz rechts pfeil') + - "➾": [T: "Offener Pfeil nach rechts"] # 0x27be (en: 'open-outlined rightwards arrow', google: 'open-out-line-rightwards-pfeil') + - "⟀": [T: "Dreidimensionaler Winkel"] # 0x27c0 (en: 'three dimensional angle', MathPlayer: 'three dimensional angle', google: 'dreidimensionaler winkel') + - "⟁": [T: "Weißes Dreieck, das ein kleines weißes Dreieck enthält"] # 0x27c1 (en: 'white triangle containing small white triangle', MathPlayer: 'white triangle containing small white triangle', google: 'weißes dreieck mit einem kleinen weißen dreieck') + - "⟂": # 0x27c2 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "Aufrecht" # (en: 'perpendicular to', MathPlayer: 'perpendicular', google: 'senkrecht zu') + - "⟃": # 0x27c3 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "Subset öffnen" # (en: 'an open subset of', MathPlayer: 'open subset', google: 'eine offene teilmenge von') + - "⟄": # 0x27c4 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) + - T: "Superset öffnen" # (en: 'an open superset of', MathPlayer: 'open superset', google: 'ein offenes superet von') + - "⟅": [T: "Linker S-förmiger Taschenbegrenzer"] # 0x27c5 (en: 'left s-shaped bag delimiter', MathPlayer: 'left s-shaped bag delimiter', google: 'links s-förmiger tasche gremiter') + - "⟆": [T: "rechter S-förmiger Taschenbegrenzer"] # 0x27c6 (en: 'right s-shaped bag delimiter', MathPlayer: 'right s-shaped bag delimiter', google: 'rechte s-förmige tasche grenzwerbung') + - "⟇": [T: "Oder mit innerem Punkt"] # 0x27c7 (en: 'or with dot inside', MathPlayer: 'or with dot inside', google: 'oder mit punkt im inneren') + - "⟈": [T: "Umgekehrter Schrägstrich Vorhergehender Teilsatz"] # 0x27c8 (en: 'reverse solidus preceding subset', MathPlayer: 'back slash preceeding subset', google: 'reverse solidus vor der untergruppe') + - "⟉": [T: "Superset Vorgänger Schrägstrich"] # 0x27c9 (en: 'superset preceding solidus', MathPlayer: 'superset preceeding slash', google: 'superset vor solidus') + - "⟊": [T: "Vertikaler Balken mit horizontalem Hub"] # 0x27ca (en: 'vertical bar with horizontal stroke', MathPlayer: 'vertical bar with horizontal stroke', google: 'vertikale balken mit horizontalem schlaganfall') + - "⟋": [T: "Mathematische aufsteigende Diagonale"] # 0x27cb (en: 'mathematical rising diagonal', google: 'mathematische steigende diagonale') + - "⟌": [T: "Lange Abteilung"] # 0x27cc (en: 'long division', MathPlayer: 'long division', google: 'lange division') + - "⟍": [T: "Mathematische fallende Diagonale"] # 0x27cd (en: 'mathematical falling diagonal', google: 'mathematische fallende diagonale') + - "⟎": [T: "quadratisches und"] # 0x27ce (en: 'squared logical and', google: 'quadratisch logisch und') + - "⟏": [T: "quadratisches oder"] # 0x27cf (en: 'squared logical or', google: 'quadratisch logisch oder') + - "⟐": [T: "Weißer Diamant mit zentriertem Punkt"] # 0x27d0 (en: 'white diamond with centered dot', google: 'weißer diamant mit zentriertem punkt') + - "⟑": [T: "Und mit Punkt"] # 0x27d1 (en: 'and with dot', MathPlayer: 'and with dot inside', google: 'und mit punkt') + - "⟒": [T: "Element der Öffnung nach oben"] # 0x27d2 (en: 'element of opening upwards', MathPlayer: 'element of openning upwards', google: 'element der öffnung nach oben') + - "⟓": [T: "Untere rechte Ecke mit Punkt"] # 0x27d3 (en: 'lower right corner with dot', MathPlayer: 'lower right corner with dot', google: 'untere rechte ecke mit punkt') + - "⟔": [T: "Obere linke Ecke mit Punkt"] # 0x27d4 (en: 'upper left corner with dot', MathPlayer: 'lower left corner with dot', google: 'obere linke ecke mit punkt') + - "⟕": [T: "Linke äußere Verbindung"] # 0x27d5 (en: 'left outer join', MathPlayer: 'left outer join', google: 'linke äußere verbindung') + - "⟖": [T: "Rechte äußere Verbindung"] # 0x27d6 (en: 'right outer join', MathPlayer: 'right outer join', google: 'rechts äußerer join') + - "⟗": [T: "Volle äußere Verbindung"] # 0x27d7 (en: 'full outer join', MathPlayer: 'full outer join', google: 'voller äußerer join') + - "⟘": [T: "Großer Aufwärtsstrich"] # 0x27d8 (en: 'large up tack', MathPlayer: 'large up tack', google: 'groß nach oben') + - "⟙": [T: "Großer Abwärtsstrich"] # 0x27d9 (en: 'large down tack', MathPlayer: 'large down tack', google: 'groß nach unten') + - "⟚": [T: "Linkes und rechtes doppeltes Drehkreuz"] # 0x27da (en: 'left and right double turnstile', MathPlayer: 'left and right double turnstile', google: 'linke und rechte doppeldrehung') + - "⟛": [T: "Linker und rechter Tack"] # 0x27db (en: 'left and right tack', MathPlayer: 'left and right tack', google: 'linker und rechter angriff') + - "⟜": [T: "Linke Multikarte"] # 0x27dc (en: 'left multimap', MathPlayer: 'left multimap', google: 'links multimap') + - "⟝": [T: "Langer rechter Strich"] # 0x27dd (en: 'long right tack', MathPlayer: 'long right tack', google: 'langer richtiger tack') + - "⟞": [T: "Langer linker Strich"] # 0x27de (en: 'long left tack', MathPlayer: 'long left tack', google: 'lange linke tack') + - "⟟": [T: "Aufwärtsstrich mit Kreis oben"] # 0x27df (en: 'up tack with circle above', MathPlayer: 'up tack with circle above', google: 'auf kreis oben') + - "⟠": [T: "Raute durch horizontale Regel geteilt"] # 0x27e0 (en: 'lozenge divided by horizontal rule', MathPlayer: 'lozenge divided by horizontal rule', google: 'rautengeschwindigkeit geteilt durch horizontale herrschaft') + - "⟡": [T: "Weißer konkavseitiger Diamant"] # 0x27e1 (en: 'white concave sided diamond', MathPlayer: 'white concave sided diamond', google: 'weißer konkaves diamant') + - "⟢": [T: "Weißer konkavseitiger Diamant mit Häkchen nach links"] # 0x27e2 (en: 'white concave sided diamond with leftwards tick', MathPlayer: 'white concave sided diamond with leftwards tick', google: 'weißer konkaves diamant mit linkser zecke') + - "⟣": [T: "Weißer konkavseitiger Diamant mit Häkchen nach rechts"] # 0x27e3 (en: 'white concave sided diamond with rightwards tick', MathPlayer: 'white concave sided diamond with rightwards tick', google: 'weißer konkaves diamant mit rightwards tick') + - "⟤": [T: "Weißes Quadrat mit Häkchen nach links"] # 0x27e4 (en: 'white square with leftwards tick', MathPlayer: 'white square with leftwards tick', google: 'weißes quadrat mit links. tick') + - "⟥": [T: "Weißes Quadrat mit Häkchen nach rechts"] # 0x27e5 (en: 'white square with rightwards tick', MathPlayer: 'white square with rightwards tick', google: 'weißes quadrat mit rechtsem häkchen') + - "⟦": [T: "Mathematische linke weiße eckige Klammer"] # 0x27e6 (en: 'left white square bracket', MathPlayer: 'left white square bracket', google: 'linke weiße quadratklammer') + - "⟧": [T: "Mathematische rechte weiße eckige Klammer"] # 0x27e7 (en: 'right white square bracket', MathPlayer: 'right white square bracket', google: 'rechte weiße quadratklasse') + - "⟨": [T: "Mathematische linke Winkelklammer"] # 0x27e8 (en: 'left angle bracket', MathPlayer: 'left angle bracket', google: 'linkswinkelhalter') + - "⟩": [T: "Mathematische rechtwinklige Klammer"] # 0x27e9 (en: 'right angle bracket', MathPlayer: 'right angle bracket', google: 'rechtswinkelhalterung') + - "⟪": [T: "Mathematische linke doppelte Winkelklammer"] # 0x27ea (en: 'left double angle bracket', MathPlayer: 'left double angle bracket', google: 'links zwei winkelhalterungen') + - "⟫": [T: "Mathematische rechtwinklige eckige Klammer"] # 0x27eb (en: 'right double angle bracket', MathPlayer: 'right double angle bracket', google: 'rechte doppelwinkelhalterung') + - "⟬": [T: "Mathematische linke weiße Schildpatt-Klammer"] # 0x27ec (en: 'left white tortoise shell bracket', MathPlayer: 'left white tortoise shell bracket', google: 'links weiße schildkröte') + - "⟭": [T: "Mathematische rechte weiße Schildpatt-Klammer"] # 0x27ed (en: 'right white tortoise shell bracket', MathPlayer: 'right white tortoise shell bracket', google: 'richtige weiße schildkrabbungshalterung') + - "⟮": [T: "Mathematische linke abgeflachte Klammer"] # 0x27ee (en: 'left flattened parenthesis', MathPlayer: 'left flattened parenthesis', google: 'links abgeflachte klammern') + - "⟯": [T: "Mathematische rechte abgeflachte Klammer"] # 0x27ef (en: 'right flattened parenthesis', MathPlayer: 'right flattened parenthesis', google: 'rechte abgeflachte klammern') + - "⟰": [T: "Vierfachpfeil nach oben"] # 0x27f0 (en: 'upwards quadruple arrow', google: 'vierfache pfeil nach oben') + - "⟱": [T: "Vierfacher Pfeil nach unten"] # 0x27f1 (en: 'downwards quadruple arrow', google: 'abwärtsvervierter pfeil') + - "⟲": [T: "Kreispfeil gegen den Uhrzeigersinn"] # 0x27f2 (en: 'anticlockwise gapped circle arrow', google: 'gezitterkreis pfeil gegen den gegen den lockzuseigersinn') + - "⟳": [T: "Kreispfeil im Uhrzeigersinn"] # 0x27f3 (en: 'clockwise gapped circle arrow', google: 'geteilte kreispfeil im uhrzeigersinn') + - "⟴": [T: "rechter Pfeil mit Circled Plus"] # 0x27f4 (en: 'right arrow with circled plus', google: 'richtiger pfeil mit eingekreistem plus') + - "⟵": [T: "Langer Pfeil nach links"] # 0x27f5 (en: 'long leftwards arrow', MathPlayer: 'long leftwards arrow', google: 'langer pfeil nach links') + - "⟶": [T: "Langer Pfeil nach rechts"] # 0x27f6 (en: 'long rightwards arrow', MathPlayer: 'long rightwards arrow', google: 'langer rechts pfeil') + - "⟷": [T: "Langer linker rechter Pfeil"] # 0x27f7 (en: 'long left right arrow', MathPlayer: 'long left right arrow', google: 'langer links rechts pfeil') + - "⟸": [T: "Langer Doppelpfeil nach links"] # 0x27f8 (en: 'long leftwards double arrow', MathPlayer: 'long leftwards double arrow', google: 'langer links doppelpfeil') + - "⟹": [T: "Langer Doppelpfeil nach rechts"] # 0x27f9 (en: 'long rightwards double arrow', MathPlayer: 'long rightwards double arrow', google: 'langer rechts doppelpfeil') + - "⟺": [T: "Langer linker rechter Doppelpfeil"] # 0x27fa (en: 'long left right double arrow', MathPlayer: 'long left right double arrow', google: 'langer links rechts doppelpfeil') + - "⟻": [T: "Langer Pfeil nach links mit Sockel"] # 0x27fb (en: 'long leftwards arrow from bar', google: 'langer links pfeil aus der bar') + - "⟼": [T: "Langer Pfeil nach rechts mit Sockel"] # 0x27fc (en: 'long rightwards arrow from bar', MathPlayer: 'long rightwards arrow from bar', google: 'langer rechts pfeil aus der bar') + - "⟽": [T: "Langer Doppelpfeil nach links mit Sockel"] # 0x27fd (en: 'long leftwards double arrow from bar', google: 'langer links doppelpfeil aus der bar') + - "⟾": [T: "Langer Doppelpfeil nach rechts mit Sockel"] # 0x27fe (en: 'long rightwards double arrow from bar', google: 'langer rechts doppelpfeil aus der bar') + - "⟿": [T: "Langer, nach rechts gekrümmter Pfeil"] # 0x27ff (en: 'long rightwards squiggle arrow', MathPlayer: 'long rightwards squiggle arrow', google: 'langer rechts squiggle -pfeil') + - "⤀": [T: "Nach rechts gerichteter Doppelpfeil mit vertikalem Strich"] # 0x2900 (en: 'rightwards two headed arrow with vertical stroke', google: 'rechten zweiköpfigen pfeil mit vertikalem schlaganfall') + - "⤁": [T: "Nach rechts gerichteter Doppelpfeil mit doppeltem vertikalem Strich"] # 0x2901 (en: 'rightwards two headed arrow with double vertical stroke', google: 'rechten zweiköpfigen pfeil mit doppelter vertikaler hub') + - "⤂": [T: "Doppelpfeil nach links mit vertikalem Strich"] # 0x2902 (en: 'leftwards double arrow with vertical stroke', google: 'links doppelpfeil mit vertikalem schlaganfall') + - "⤃": [T: "Doppelpfeil nach rechts mit vertikalem Strich"] # 0x2903 (en: 'rightwards double arrow with vertical stroke', google: 'richtiger doppelpfeil mit vertikalem schlaganfall') + - "⤄": [T: "Linker rechter Doppelpfeil mit vertikalem Strich"] # 0x2904 (en: 'left right double arrow with vertical stroke', google: 'links rechts doppelpfeil mit vertikalem schlaganfall') + - "⤅": [T: "Zwei Pfeile nach rechts mit Sockel "] # 0x2905 (en: 'rightwards two headed arrow from bar', MathPlayer: 'rightwards two headed arrow from bar', google: 'rightwards zwei köpfe pfeil aus der bar') + - "⤆": [T: "Doppelpfeil nach links mit Sockel"] # 0x2906 (en: 'leftwards double arrow from bar', google: 'links doppelpfeil aus der bar') + - "⤇": [T: "Doppelter Pfeil nach rechts mit Sockel"] # 0x2907 (en: 'rightwards double arrow from bar', google: 'richtiger doppelpfeil aus der bar') + - "⤈": [T: "Abwärtspfeil mit horizontalem Strich"] # 0x2908 (en: 'downwards arrow with horizontal stroke', google: 'nach unten pfeil mit horizontalem schlaganfall nach unten') + - "⤉": [T: "Aufwärtspfeil mit horizontalem Anschlag"] # 0x2909 (en: 'upwards arrow with horizontal stroke', google: 'aufwärter pfeil mit horizontalem schlaganfall') + - "⤊": [T: "Dreifachpfeil nach oben"] # 0x290a (en: 'upwards triple arrow', google: 'dreifach pfeil nach oben') + - "⤋": [T: "Dreifacher Pfeil nach unten"] # 0x290b (en: 'downwards triple arrow', google: 'dreifach pfeil nach unten') + - "⤌": [T: "Doppelpfeil nach links"] # 0x290c (en: 'leftwards double dash arrow', MathPlayer: 'leftwards double dash arrow', google: 'links -doppel -dash -pfeil') + - "⤍": [T: "Doppelpfeil nach rechts"] # 0x290d (en: 'rightwards double dash arrow', MathPlayer: 'rightwards double dash arrow', google: 'rightwards double dash -pfeil') + - "⤎": [T: "Dreifacher Strichpfeil nach links"] # 0x290e (en: 'leftwards triple dash arrow', MathPlayer: 'leftwards triple dash arrow', google: 'links dreifach dash -pfeil') + - "⤏": [T: "Dreifacher Strichpfeil nach rechts"] # 0x290f (en: 'rightwards triple dash arrow', MathPlayer: 'rightwards triple dash arrow', google: 'rightwards triple dash pfeil') + - "⤐": [T: "Dreipoliger Pfeil nach rechts"] # 0x2910 (en: 'rightwards two headed triple dash arrow', MathPlayer: 'rightwards two headed triple dash arrow', google: 'rightwards zwei köpfe triple dash -pfeil') + - "⤑": [T: "Pfeil nach rechts mit gepunktetem Stamm"] # 0x2911 (en: 'rightwards arrow with dotted stem', MathPlayer: 'rightwards arrow with dotted stem', google: 'richtiger pfeil mit gepunktetem stiel') + - "⤒": [T: "Aufwärtspfeil zur Sockel"] # 0x2912 (en: 'upwards arrow to bar', MathPlayer: 'upwards arrow to bar', google: 'aufwärter pfeil in die bar') + - "⤓": [T: "Abwärtspfeil zur Sockel"] # 0x2913 (en: 'downwards arrow to bar', MathPlayer: 'downwards arrow to bar', google: 'nach unten pfeil in die bar') + - "⤔": [T: "Pfeil nach rechts mit Schwanz mit vertikalem Strich"] # 0x2914 (en: 'rightwards arrow with tail and vertical stroke', google: 'rechten pfeil mit schwanz und vertikalem schlaganfall') + - "⤕": [T: "Pfeil nach rechts mit Schwanz mit doppeltem vertikalen Strich"] # 0x2915 (en: 'rightwards arrow with tail and double vertical stroke', google: 'rechten pfeil mit schwanz und doppelter vertikaler schlaganfall') + - "⤖": [T: "Nach rechts gerichteter zweiköpfiger Pfeil mit Schwanz"] # 0x2916 (en: 'rightwards two headed arrow with tail', MathPlayer: 'rightwards two headed arrow with tail', google: 'rechten zweiköpfigen pfeil mit schwanz') + - "⤗": [T: "Nach rechts gerichteter Doppelpfeil mit Schwanz mit senkrechtem Anschlag"] # 0x2917 (en: 'rightwards two headed arrow with tail with vertical stroke', google: 'rechten zweiköpfigen pfeil mit schwanz mit vertikalem schlaganfall') + - "⤘": [T: "Nach rechts gerichteter Doppelpfeil mit Schwanz mit doppeltem vertikalen Strich"] # 0x2918 (en: 'rightwards two headed arrow with tail with double vertical stroke', google: 'rechten zweiköpfigen pfeil mit schwanz mit doppelter vertikaler hub') + - "⤙": [T: "Pfeilspitze nach links"] # 0x2919 (en: 'leftwards arrow tail', MathPlayer: 'leftwards arrow tail', google: 'links pfeilschwanz') + - "⤚": [T: "Pfeilspitze nach rechts"] # 0x291a (en: 'rightwards arrow tail', google: 'richtiger pfeilschwanz') + - "⤛": [T: "Doppelter Pfeilschwanz nach links"] # 0x291b (en: 'leftwards double arrow tail', MathPlayer: 'leftwards double arrow tail', google: 'links doppelpfeilschwanz') + - "⤜": [T: "Doppelter Pfeilschwanz nach rechts"] # 0x291c (en: 'rightwards double arrow tail', MathPlayer: 'rightwards double arrow tail', google: 'rightwards double pfeilschwanz') + - "⤝": [T: "Pfeil nach links zu Black Diamond"] # 0x291d (en: 'leftwards arrow to filled diamond', MathPlayer: 'leftwards arrow to filled diamond', google: 'pfeil nach links zum gefüllten diamanten') + - "⤞": [T: "Pfeil nach rechts zu Black Diamond"] # 0x291e (en: 'rightwards arrow to filled diamond', MathPlayer: 'rightwards arrow to filled diamond', google: 'richtiger pfeil zum gefüllten diamanten') + - "⤟": [T: "Pfeil nach links von Bar zu Black Diamond"] # 0x291f (en: 'leftwards arrow from bar to filled diamond', MathPlayer: 'leftwards arrow from bar to filled diamond', google: 'pfeil von der bar zum gefüllten diamanten links') + - "⤠": [T: "Pfeil nach rechts von Bar zu Black Diamond"] # 0x2920 (en: 'rightwards arrow from bar to filled diamond', MathPlayer: 'rightwards arrow from bar to filled diamond', google: 'richtiger pfeil von bar zum gefüllten diamanten') + - "⤡": [T: "Nordwest- und Südostpfeil"] # 0x2921 (en: 'north west and south east arrow', google: 'nordwest- und südostpfeil') + - "⤢": [T: "Nordost- und Südwestpfeil"] # 0x2922 (en: 'north east and south west arrow', google: 'nordost- und südwestpfeil') + - "⤣": [T: "Nordwestpfeil mit Haken"] # 0x2923 (en: 'north west arrow with hook', MathPlayer: 'north west arrow with hook', google: 'nordwestpfeil mit haken') + - "⤤": [T: "Nordostpfeil mit Haken"] # 0x2924 (en: 'north east arrow with hook', MathPlayer: 'north east arrow with hook', google: 'nordostpfeil mit haken') + - "⤥": [T: "Südostpfeil mit Haken"] # 0x2925 (en: 'south east arrow with hook', MathPlayer: 'south east arrow with hook', google: 'südostpfeil mit haken') + - "⤦": [T: "Südwestpfeil mit Haken"] # 0x2926 (en: 'south west arrow with hook', MathPlayer: 'south west arrow with hook', google: 'südwestpfeil mit haken') + - "⤧": [T: "Nordwestpfeil und Nordostpfeil"] # 0x2927 (en: 'north west arrow and north east arrow', MathPlayer: 'north west arrow and north east arrow', google: 'north west arrow und north east pfeil') + - "⤨": [T: "Nordostpfeil und Südostpfeil"] # 0x2928 (en: 'north east arrow and south east arrow', MathPlayer: 'north east arrow and south east arrow', google: 'north east arrow und south east pfeil') + - "⤩": [T: "Südostpfeil und Südwestpfeil"] # 0x2929 (en: 'south east arrow and south west arrow', MathPlayer: 'south east arrow and south west arrow', google: 'south east arrow und south west arrow') + - "⤪": [T: "Südwestpfeil und Nordwestpfeil"] # 0x292a (en: 'south west arrow and north west arrow', MathPlayer: 'south west arrow and north west arrow', google: 'südwestpfeil und nordwestpfeil') + - "⤫": [T: "Steigende diagonale Kreuzung fallende Diagonale"] # 0x292b (en: 'rising diagonal crossing falling diagonal', google: 'steigende diagonale kreuzung fallende diagonale') + - "⤬": [T: "Fallende diagonale Kreuzung steigende Diagonale"] # 0x292c (en: 'falling diagonal crossing rising diagonal', google: 'fallende diagonale kreuzende diagonale diagonale kreuzung') + - "⤭": [T: "Südostpfeil Kreuzung Nordostpfeil"] # 0x292d (en: 'south east arrow crossing north east arrow', google: 'south east arrow crossed north east pfeil') + - "⤮": [T: "Nordostpfeil Kreuzung Südostpfeil"] # 0x292e (en: 'north east arrow crossing south east arrow', google: 'north east arrow crossed south east pfeil') + - "⤯": [T: "Fallende Diagonale, die Nordostpfeil kreuzt"] # 0x292f (en: 'falling diagonal crossing north east arrow', google: 'fallende diagonale kreuzung north east pfeil') + - "⤰": [T: "Steigende Diagonale, die Südostpfeil kreuzt"] # 0x2930 (en: 'rising diagonal crossing south east arrow', google: 'steigende diagonale kreuzung südostpfeil') + - "⤱": [T: "Nordostpfeilüberquerung Nordwestpfeil"] # 0x2931 (en: 'north east arrow crossing north west arrow', google: 'nordostpfeil der nordwestpfeil') + - "⤲": [T: "Nordwestpfeilüberquerung Nordostpfeil"] # 0x2932 (en: 'north west arrow crossing north east arrow', google: 'nordwest -pfeil überqueren north east pfeil') + - "⤳": [T: "Wellenpfeil, der nach rechts zeigt"] # 0x2933 (en: 'wave arrow pointing directly right', MathPlayer: 'wave arrow pointing directly to the right', google: 'wellenpfeil direkt nach rechts zeigen') + - "⤴": [T: "Pfeil nach rechts, dann nach oben gekrümmt"] # 0x2934 (en: 'arrow pointing rightwards then curving upwards', google: 'pfeil nach rechts zeigt und dann nach oben krümmt') + - "⤵": [T: "Pfeil nach rechts, dann nach unten gekrümmt"] # 0x2935 (en: 'arrow pointing rightwards then curving downwards', MathPlayer: 'arrow pointing rightwards then curving downwards', google: 'pfeil nach rechts zeigt und dann nach unten krümmt') + - "⤶": [T: "Pfeil nach unten, dann nach links gekrümmt"] # 0x2936 (en: 'arrow pointing downwards then curving leftwards', MathPlayer: 'arrow pointing downwards then curving leftwards', google: 'pfeil nach unten zeigt und dann nach links krümmt') + - "⤷": [T: "Pfeil nach unten, dann nach rechts gekrümmt"] # 0x2937 (en: 'arrow pointing downwards then curving rightwards', MathPlayer: 'arrow pointing downwards then curving rightwards', google: 'pfeil nach unten zeigt und dann nach rechts krümmt') + - "⤸": [T: "Rechtsseitiger Bogen im Uhrzeigersinn"] # 0x2938 (en: 'right side arc clockwise arrow', MathPlayer: 'clockwise right semicircle arrow', google: 'rechte seite arc im uhrzeigersinn') + - "⤹": [T: "Bogen von der linken Seite gegen den Uhrzeigersinn"] # 0x2939 (en: 'left side arc anticlockwise arrow', MathPlayer: 'anticlockwise left semicircle arrow', google: 'linker side arc arc gegen den pfeil gegen gesamtzusehen') + - "⤺": [T: "Pfeil von rechts oben gegen den Uhrzeigersinn"] # 0x293a (en: 'top arc anticlockwise arrow', google: 'top -arc -arc gegen den pfeil gegen den uhrzeigersinn') + - "⤻": [T: "Pfeil von links unten gegen den Uhrzeigersinn"] # 0x293b (en: 'bottom arc anticlockwise arrow', google: 'bogenzeigero -pfeil gegen den unteren lichtbogen') + - "⤼": [T: "Pfeil von links unten im Uhrzeigersinn mit Minuszeichen links"] # 0x293c (en: 'top arc clockwise arrow with minus', MathPlayer: 'clockwise top semicircle arrow with minus', google: 'bogenzusuell -pfeil mit minus') + - "⤽": [T: "Pfeil von rechts unten gegen den Uhrzeigersinn mit Pluszeichen rechts"] # 0x293d (en: 'top arc anticlockwise arrow with plus', MathPlayer: 'anticlockwise top semicircle arrow with plus', google: 'top -arc -arc gegen plus gegen den arrow') + - "⤾": [T: "Rechter halbkreisförmiger Pfeil im Uhrzeigersinn"] # 0x293e (en: 'lower right semicircular clockwise arrow', google: 'unterhalb des rechten halbkreisförmigen pfeils im uhrzeigersinn') + - "⤿": [T: "Linker halbkreisförmiger Pfeil gegen den Uhrzeigersinn"] # 0x293f (en: 'lower left semicircular anticlockwise arrow', google: 'unterer linker halbkreisförmiger arrow gegen den gegen den gegen den uhrzeigersinn') + - "⥀": [T: "Geschlossener Kreispfeil gegen den Uhrzeigersinn"] # 0x2940 (en: 'anticlockwise closed circle arrow', google: 'schleigender kirckeisprohl') + - "⥁": [T: "Geschlossener Kreispfeil im Uhrzeigersinn"] # 0x2941 (en: 'clockwise closed circle arrow', google: 'pfeil im uhrzeigersinn geschlossen') + - "⥂": [T: "Pfeil nach rechts über einem kurzen Pfeil nach links"] # 0x2942 (en: 'rightwards arrow above short leftwards arrow', google: 'rechten pfeil über dem kurzen linken pfeil') + - "⥃": [T: "Pfeil nach links über einem kurzen Pfeil nach rechts"] # 0x2943 (en: 'leftwards arrow above short rightwards arrow', google: 'links pfeil über kurzer rechts pfeil') + - "⥄": [T: "Kurzer Pfeil nach rechts Über Pfeil nach links"] # 0x2944 (en: 'short rightwards arrow above leftwards arrow', google: 'kurz nach rechts pfeil über links') + - "⥅": [T: "Pfeil nach rechts mit Pluszeichen unten"] # 0x2945 (en: 'rightwards arrow with plus below', MathPlayer: 'rightwards arrow with plus below', google: 'rightwards pfeil mit plus unten') + - "⥆": [T: "Pfeil nach links mit Pluszeichen unten"] # 0x2946 (en: 'leftwards arrow with plus below', google: 'links pfeil mit plus unten') + - "⥇": [T: "Pfeil nach rechts durch X"] # 0x2947 (en: 'rightwards arrow through x', google: 'richtiger pfeil durch x') + - "⥈": [T: "Linker rechter Pfeil durch kleinen Kreis"] # 0x2948 (en: 'left right arrow through circle', MathPlayer: 'left right arrow through circle', google: 'links rechts pfeil durch den kreis') + - "⥉": [T: "Aufwärts zweiköpfiger Pfeil vom kleinen Kreis ausgehend"] # 0x2949 (en: 'upwards two headed arrow from circle', MathPlayer: 'upwards two headed arrow from circle', google: 'auf zwei köpfe pfeil aus dem kreis') + - "⥊": [T: "Linker Haken oben mit rechtem Haken unten"] # 0x294a (en: 'left barb up right barb down harpoon', MathPlayer: 'left barb up right barb down harpoon', google: 'links barb oben rechte barb down harpoon') + - "⥋": [T: "Linker Haken unten mit rechtem Haken oben"] # 0x294b (en: 'left barb down right barb up harpoon', MathPlayer: 'left barb down right barb up harpoon', google: 'linker barb unten rechte barb auf harpoon') + - "⥌": [T: "Aufwärtshaken rechts, Abwärtshaken links"] # 0x294c (en: 'up barb right down barb left harpoon', google: 'auf barb rechts runter barb links harpune') + - "⥍": [T: "Aufwärtshaken links, Abwärtshaken rechts"] # 0x294d (en: 'up barb left down barb right harpoon', google: 'auf barb nach links nach unten abharpoon') + - "⥎": [T: "Linker Haken oben mit rechtem Haken oben"] # 0x294e (en: 'left barb up right barb up harpoon', MathPlayer: 'left right harpoon up', google: 'links barby up up barb up harpoon') + - "⥏": [T: "Aufwärtshaken rechts, Abwärtshaken rechts"] # 0x294f (en: 'up barb right down barb right harpoon', MathPlayer: 'up down harpoon right', google: 'auf barb direkt nach barb rechts rechts harpune') + - "⥐": [T: "Linker Haken unten mit rechtem Haken unten"] # 0x2950 (en: 'left barb down right barb down harpoon', MathPlayer: 'left right harpoon down', google: 'linker barb unten rechte barb nach unten harpoon') + - "⥑": [T: "Aufwärtshaken links, Abwärtshaken links"] # 0x2951 (en: 'up barb left down barb left harpoon', MathPlayer: 'up down harpoon left', google: 'auf barb ließ barb nach barb ließ harpoon') + - "⥒": [T: "Linker Haken oben mit Sockel links"] # 0x2952 (en: 'leftwards harpoon with barb up to bar', MathPlayer: 'leftwards harpoon to bar with barb upwards', google: 'links harpoon mit barb bis zur bar') + - "⥓": [T: "rechter Haken oben mit Sockel rechts"] # 0x2953 (en: 'rightwards harpoon with barb up to bar', MathPlayer: 'rightwards harpoon to bar with barb upwards', google: 'rightwards harpoon mit barb bis zur bar') + - "⥔": [T: "Aufwärtshaken rechts mit Sockel oben"] # 0x2954 (en: 'upwards harpoon with barb right to bar', MathPlayer: 'upwards harpoon to bar with barb rightwards', google: 'harpune nach oben mit barb right to bar') + - "⥕": [T: "Abwärtshaken rechts mit Sockel unten"] # 0x2955 (en: 'downwards harpoon with barb right to bar', MathPlayer: 'downwards harpoon to bar with barb rightwards', google: 'nach unten harpoon mit barb right to bar') + - "⥖": [T: "Linker Haken unten mit Sockel links"] # 0x2956 (en: 'leftwards harpoon with barb down to bar', MathPlayer: 'leftwards harpoon to bar with barb downwards', google: 'links harpoon mit barb in die bar') + - "⥗": [T: "Rechter Haken unten mit Sockel rechts"] # 0x2957 (en: 'rightwards harpoon with barb down to bar', MathPlayer: 'rightwards harpoon to bar with barb downwards', google: 'rightwards harpoon mit barb nach unten in die bar') + - "⥘": [T: "Aufwärtshaken links mit Sockel oben"] # 0x2958 (en: 'upwards harpoon with barb left to bar', MathPlayer: 'upwards harpoon to bar with barb leftwards', google: 'harpoon mit barb in der bar nach oben') + - "⥙": [T: "Abwärtshaken links mit Sockel unten"] # 0x2959 (en: 'downwards harpoon with barb left to bar', MathPlayer: 'downwards harpoon to bar with barb leftwards', google: 'abwärtsharpune mit barb in der bar nach unten') + - "⥚": [T: "Linker Haken oben mit Sockel rechts"] # 0x295a (en: 'leftwards harpoon with barb up from bar', MathPlayer: 'leftwards harpoon from bar with barb upwards', google: 'links -harpoon mit barb aus der bar') + - "⥛": [T: "Rechter Haken oben mit Sockel links"] # 0x295b (en: 'rightwards harpoon with barb up from bar', MathPlayer: 'rightwards harpoon from bar with barb upwards', google: 'rightwards harpoon mit barb auf der bar') + - "⥜": [T: "Aufwärtshaken rechts mit Sockel unten"] # 0x295c (en: 'upwards harpoon with barb right from bar', MathPlayer: 'upwards harpoon from bar with barb rightwards', google: 'harpune nach oben mit barb direkt aus der bar') + - "⥝": [T: "Abwärtshaken rechts mit Sockel oben"] # 0x295d (en: 'downwards harpoon with barb right from bar', MathPlayer: 'downwards harpoon from bar with barb rightwards', google: 'harpunen nach unten mit barb direkt aus der bar') + - "⥞": [T: "Linker Haken unten mit Sockel rechts"] # 0x295e (en: 'leftwards harpoon with barb down from bar', MathPlayer: 'leftwards harpoon from bar with barb downwards', google: 'links harpoon mit barb von bar aus der bar') + - "⥟": [T: "Rechter Haken unten mit Sockel links"] # 0x295f (en: 'rightwards harpoon with barb down from bar', MathPlayer: 'rightwards harpoon from bar with barb downwards', google: 'rightwards harpoon mit barb von bar aus der bar') + - "⥠": [T: "Aufwärtshaken links mit Sockel unten"] # 0x2960 (en: 'upwards harpoon with barb left from bar', MathPlayer: 'upwards harpoon from bar with barb leftwards', google: 'harpoon mit barb aus der bar nach oben') + - "⥡": [T: "Abwärtshaken links mit Sockel oben"] # 0x2961 (en: 'downwards harpoon with barb left from bar', MathPlayer: 'downwards harpoon from bar with barb leftwards', google: 'abwärtsharpune mit barb aus der bar weg') + - "⥢": [T: "Harpune nach links mit Widerhaken nach oben Harpune nach links mit Widerhaken nach unten"] # 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: 'links harpoon mit barb oben links harpoon mit barb nach unten') + - "⥣": [T: "Harpune nach oben mit Widerhaken links neben Harpune nach oben Widerhaken Barb rechts"] # 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: 'harpoon nach oben mit barb neben harpoon nach oben mit barb rechts') + - "⥤": [T: "Harpune nach rechts mit Widerhaken nach oben Harpune nach rechts mit Widerhaken nach unten"] # 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: 'rightwards harpoon mit barb oben rechts harpoon mit barb down') + - "⥥": [T: "Harpune nach unten mit Widerhaken nach unten Harpune nach unten mit Widerhaken nach rechts"] # 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: 'harpoon nach unten mit barb neben der abwärtsharpoon mit barb rechts') + - "⥦": [T: "Harpune nach links mit Widerhaken nach oben Harpune nach rechts mit Widerhaken nach oben"] # 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: 'links harpoon mit barb oben rechts harpoon mit barb hoch') + - "⥧": [T: "Linke Harpune mit Widerhaken nach unten rechts Harpune mit Widerhaken nach unten"] # 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: 'links harpoon mit barb oben rechts harpoon mit barb nach unten') + - "⥨": [T: "Harpune nach rechts mit Widerhaken nach oben Harpune nach links mit Widerhaken nach oben"] # 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: 'harpoon nach rechts mit barb oben links mit barb auf harpoon') + - "⥩": [T: "Harpune nach rechts mit Widerhaken nach unten Harpune nach links mit Widerhaken nach unten"] # 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: 'harpoon nach rechts mit barb oben links mit barb mit barb') + - "⥪": [T: "nach links gerichtete Harpune mit Widerhaken über einem langen Strich"] # 0x296a (en: 'leftwards harpoon with barb up above long dash', MathPlayer: 'leftwards harpoon over bar', google: 'links -harpoon mit barb über langen schuss') + - "⥫": [T: "nach links gerichtete Harpune mit Widerhaken unten, lang gestrichelt"] # 0x296b (en: 'leftwards harpoon with barb down below long dash', MathPlayer: 'leftwards harpoon under bar', google: 'links -harpoon mit barb unter longem armaturenbrett') + - "⥬": [T: "Rechtshaken mit Widerhaken über langem Strich"] # 0x296c (en: 'rightwards harpoon with barb up above long dash', MathPlayer: 'rightwards harpoon over bar', google: 'rightwards harpoon mit barb über langen schuss') + - "⥭": [T: "Rechtshaken mit Widerhaken unten, lang"] # 0x296d (en: 'rightwards harpoon with barb down below long dash', MathPlayer: 'rightwards harpoon under bar', google: 'rightwards harpoon mit barb unter longem armaturenbrett') + - "⥮": [T: "aufwärts gerichtete Harpune mit Widerhaken links neben unten gerichteter Harpune mit Widerhaken rechts"] # 0x296e (en: 'upwards harpoon with barb left beside downwards harpoon with barb right', MathPlayer: 'upwards harpoon to the left of downwards harpoon', google: 'harpune nach oben mit barb, der neben der abwärtsharpoon mit barb rechts bleibt') + - "⥯": [T: "Abwärtsharpune mit Widerhaken links neben Abwärtsharpune mit Widerhaken rechts"] # 0x296f (en: 'downwards harpoon with barb left beside upwards harpoon with barb right', MathPlayer: 'upwards harpoon to the right of downwards harpoon', google: 'harpoon nach unten mit barb neben harpoon nach oben mit barb rechts') + - "⥰": [T: "Rechter Doppelpfeil mit abgerundeter Spitze"] # 0x2970 (en: 'right double arrow with rounded head') + - "⥱": [T: "Gleichheitszeichen über dem Pfeil nach rechts"] # 0x2971 (en: 'equals above rightwards arrow', MathPlayer: 'equals above rightwards arrow', google: 'entspricht dem rechten pfeil') + - "⥲": [T: "Tilde-Operator über dem Pfeil nach rechts"] # 0x2972 (en: 'tilde operator above rightwards arrow', MathPlayer: 'tilde operator above rightwards arrow', google: 'tilde -operator über rechtsem pfeil') + - "⥳": [T: "Pfeil nach links über Tilde-Operator"] # 0x2973 (en: 'leftwards arrow above tilde operator', MathPlayer: 'leftwards arrow over tilde', google: 'pfeil links über dem tilde -operator') + - "⥴": [T: "Pfeil nach rechts über Tilde-Operator"] # 0x2974 (en: 'rightwards arrow above tilde operator', MathPlayer: 'rightwards arrow over tilde', google: 'rightwards pfeil über dem tilde -operator') + - "⥵": [T: "Pfeil nach rechts über fast gleich"] # 0x2975 (en: 'rightwards arrow above almost equal to', MathPlayer: 'rightwards arrow above almost equal to', google: 'richtiger pfeil über fast gleich') + - "⥶": [T: "Weniger als über Pfeil nach links"] # 0x2976 (en: 'less than above leftwards arrow', MathPlayer: 'less than above leftwards arrow', google: 'weniger als links in pfeil') + - "⥷": [T: "Pfeil nach links durch weniger als"] # 0x2977 (en: 'leftwards arrow through less than', google: 'links pfeil durch weniger als') + - "⥸": [T: "Größer als über dem Pfeil nach rechts"] # 0x2978 (en: 'greater than above rightwards arrow', MathPlayer: 'greater than above rightwards arrow', google: 'größer als über rechts nach rechts') + - "⥹": [T: "Untersatz über dem Pfeil nach rechts"] # 0x2979 (en: 'subset above rightwards arrow', MathPlayer: 'subset above rightwards arrow', google: 'untergruppe über rechts nach rechts') + - "⥺": [T: "Pfeil nach links durch Teilmenge"] # 0x297a (en: 'leftwards arrow through subset', google: 'pfeil durch die teilmenge links') + - "⥻": [T: "Superset über dem Pfeil nach links"] # 0x297b (en: 'superset above leftwards arrow', MathPlayer: 'superset above leftwards arrow', google: 'superset über dem linken pfeil') + - "⥼": [T: "linker Fischschwanz"] # 0x297c (en: 'left fish tail', MathPlayer: 'left fish tail', google: 'links fischschwanz') + - "⥽": [T: "rechter Fischschwanz"] # 0x297d (en: 'right fish tail', MathPlayer: 'right fish tail', google: 'rechts fischschwanz') + - "⥾": [T: "Fischschwanz oben"] # 0x297e (en: 'up fish tail', MathPlayer: 'vertical bar with double hook', google: 'up fischschwanz') + - "⥿": [T: "Fischschwanz unten"] # 0x297f (en: 'down fish tail', MathPlayer: 'down fish tail', google: 'down fischschwanz') + - "⦀": [T: "Dreifacher vertikaler Balkenbegrenzer"] # 0x2980 (en: 'triple vertical bar delimiter', google: 'triple vertical bar gremiter') + - "⦁": [T: "Z Notationspunkt"] # 0x2981 (en: 'z notation spot', google: 'z notationspunkt') + - "⦂": [T: "Z Notationstyp Doppelpunkt"] # 0x2982 (en: 'z notation type colon', google: 'z notation typ dickdarm') + - "⦃": [T: "Linke weiße geschweifte Klammer"] # 0x2983 (en: 'left white brace', google: 'links weiße klammer') + - "⦄": [T: "Rechte weiße geschweifte Klammer"] # 0x2984 (en: 'right white brace', google: 'rechte weiße klammer') + - "⦅": [T: "Linke weiße Klammer"] # 0x2985 (en: 'left white parenthesis', MathPlayer: 'left white paren', google: 'linke weiße klammern') + - "⦆": [T: "Rechte weiße Klammer"] # 0x2986 (en: 'right white parenthesis', MathPlayer: 'right white paren', google: 'rechte weiße klammern') + - "⦇": [T: "Z-Notation linke Bildklammer"] # 0x2987 (en: 'z notation left image bracket', google: 'z notation linke bildklasse') + - "⦈": [T: "Z-Notation rechte Bildklammer"] # 0x2988 (en: 'z notation right image bracket', google: 'z notation rechtsbildklasse') + - "⦉": [T: "Z-Notation linke Klammer"] # 0x2989 (en: 'z notation left binding bracket', MathPlayer: 'z notation left binding bracket', google: 'z notation links bindungshalterung') + - "⦊": [T: "Z-Notation rechte Klammer"] # 0x298a (en: 'z notation right binding bracket', MathPlayer: 'z notation right binding bracket', google: 'z notation recht bindungshalterung') + - "⦋": [T: "Linke eckige Klammer mit Unterlenker"] # 0x298b (en: 'left square bracket with underbar', MathPlayer: 'left bracket with underbar', google: 'linksquadratische klammer mit unterbar') + - "⦌": [T: "Rechte eckige Klammer mit Unterlenker"] # 0x298c (en: 'right square bracket with underbar', MathPlayer: 'right bracket with underbar', google: 'rechte quadratische halterung mit unterbar') + - "⦍": [T: "Linke eckige Klammer mit Häkchen in der oberen Ecke"] # 0x298d (en: 'left square bracket with tick in top corner', MathPlayer: 'left bracket with tick in top corner', google: 'linksquadratische halterung mit zecke in der oberen ecke') + - "⦎": [T: "Rechte eckige Klammer mit Tick in der unteren Ecke"] # 0x298e (en: 'right square bracket with tick in bottom corner', MathPlayer: 'right bracket with tick in bottom corner', google: 'rechte quadratische halterung mit tick in der unteren ecke') + - "⦏": [T: "Linke eckige Klammer mit Tick in der unteren Ecke"] # 0x298f (en: 'left square bracket with tick in bottom corner', MathPlayer: 'left bracket with tick in bottom corner', google: 'links quadratische halterung mit tick in der unteren ecke') + - "⦐": [T: "Rechte eckige Klammer mit Tick in der oberen Ecke"] # 0x2990 (en: 'right square bracket with tick in top corner', MathPlayer: 'right bracket with tick in top corner', google: 'rechte quadratische halterung mit zecke in der oberen ecke') + - "⦑": [T: "Linke Winkelklammer mit Punkt"] # 0x2991 (en: 'left angle bracket with dot', MathPlayer: 'left angle bracket with dot', google: 'linkswinkelhalter mit punkt') + - "⦒": [T: "Rechtwinklige Klammer mit Punkt"] # 0x2992 (en: 'right angle bracket with dot', MathPlayer: 'right angle bracket with dot', google: 'rechtswinkelhalterung mit punkt') + - "⦓": [T: "Linker Bogen weniger als Halterung"] # 0x2993 (en: 'left arc less than bracket', MathPlayer: 'left arc less than bracket', google: 'links bogen weniger als klammer') + - "⦔": [T: "rechter Bogen größer als Halterung"] # 0x2994 (en: 'right arc greater than bracket', MathPlayer: 'right arc greater than bracket', google: 'richtiger bogen größer als die klammer') + - "⦕": [T: "Doppelter linker Bogen größer als Halterung"] # 0x2995 (en: 'double left arc greater than bracket', MathPlayer: 'double left arc greater than bracket', google: 'doppelter linker bogen größer als die klammer') + - "⦖": [T: "Doppelter rechter Bogen weniger als Halterung"] # 0x2996 (en: 'double right arc less than bracket', MathPlayer: 'double right arc less than bracket', google: 'doppeler rechts bogen weniger als klammer') + - "⦗": [T: "Linke schwarze Schildpatt-Klammer"] # 0x2997 (en: 'left black tortoise shell bracket', google: 'links black tortoise muschelhalterung') + - "⦘": [T: "Rechte schwarze Schildpatt-Klammer"] # 0x2998 (en: 'right black tortoise shell bracket', google: 'rechte schwarze schildkröte') + - "⦙": [T: "Gepunkteter Zaun"] # 0x2999 (en: 'dotted fence', google: 'gepunkteter zaun') + - "⦚": [T: "Vertikale Zickzacklinie"] # 0x299a (en: 'vertical zigzag line', MathPlayer: 'vertical zigzag line', google: 'vertikale zick -zack -linie') + - "⦛": [T: "Gemessene Winkelöffnung links"] # 0x299b (en: 'measured angle opening left', google: 'gemessene winkelöffnung links') + - "⦜": [T: "Rechtwinklige Variante mit Quadrat"] # 0x299c (en: 'right angle variant with square', google: 'rechtswinkelvariante mit quadrat') + - "⦝": [T: "rechter Winkel mit Punkt gemessen"] # 0x299d (en: 'measured right angle with dot', MathPlayer: 'measured right angle with dot', google: 'gemessener rechter winkel mit punkt') + - "⦞": [T: "Winkel mit S nach innen"] # 0x299e (en: 'angle with s inside', google: 'winkel mit s im inneren') + - "⦟": [T: "Spitzer Winkel"] # 0x299f (en: 'acute angle', google: 'spitzer winkel') + - "⦠": [T: "Sphärischer Öffnungswinkel nach links"] # 0x29a0 (en: 'spherical angle opening left', google: 'kugelwinkelöffnung nach links') + - "⦡": [T: "Sphärischer Öffnungswinkel nach unten"] # 0x29a1 (en: 'spherical angle opening up', google: 'kugelwinkel öffnen sich') + - "⦢": [T: "Gedrehter Winkel"] # 0x29a2 (en: 'turned angle', google: 'drehwinkel') + - "⦣": [T: "Umgekehrter Winkel"] # 0x29a3 (en: 'reversed angle', google: 'umgekehrter winkel') + - "⦤": [T: "Winkel mit Unterstrich"] # 0x29a4 (en: 'angle with underbar', MathPlayer: 'angle with underbar', google: 'winkel mit unterbar') + - "⦥": [T: "Umgekehrter Winkel mit Unterstrich"] # 0x29a5 (en: 'reversed angle with underbar', MathPlayer: 'reversed angle with underbar', google: 'umgekehrter winkel mit unterbar') + - "⦦": [T: "Schräger Winkel, der sich nach oben öffnet"] # 0x29a6 (en: 'oblique angle opening up', MathPlayer: 'oblique angle opening up', google: 'schräge winkelöffnung') + - "⦧": [T: "Schräger Winkel, der sich nach unten öffnet"] # 0x29a7 (en: 'oblique angle opening down', MathPlayer: 'oblique angle opening down', google: 'schräge winkel öffnet sich') + - "⦨": [T: "Gemessener Winkel mit offenem Arm endet im Pfeil nach oben und rechts"] # 0x29a8 (en: 'measured angle with open arm ending in arrow pointing up and to the right', MathPlayer: 'measured angle with open arm ending in arrow pointing up and to the right', google: 'der gemessene winkel mit offenem arm in pfeil und nach rechts') + - "⦩": [T: "Gemessener Winkel mit offenem Arm und Pfeil nach oben und links"] # 0x29a9 (en: 'measured angle with open arm ending in arrow pointing up and to the left', MathPlayer: 'measured angle with open arm ending in arrow pointing up and to the left', google: 'der gemessene winkel mit offenem arm in pfeil und nach links') + - "⦪": [T: "Gemessener Winkel mit offenem Arm endet im nach unten zeigenden Pfeil und rechts"] # 0x29aa (en: 'measured angle with open arm ending in arrow pointing down and to the right', MathPlayer: 'measured angle with open arm ending in arrow pointing down and to the right', google: 'der gemessene winkel mit offenem arm in pfeil nach unten und nach rechts') + - "⦫": [T: "Gemessener Winkel mit offenem Arm endet im nach unten zeigenden Pfeil"] # 0x29ab (en: 'measured angle with open arm ending in arrow pointing down and to the left', MathPlayer: 'measured angle with open arm ending in arrow pointing down and to the left', google: 'der gemessene winkel mit offenem arm in pfeil, der nach unten und nach links zeigt') + - "⦬": [T: "Gemessener Winkel mit offenem Arm endet im Pfeil nach rechts und oben"] # 0x29ac (en: 'measured angle with open arm ending in arrow pointing right and up', MathPlayer: 'measured angle with open arm ending in arrow pointing right and up', google: 'der gemessene winkel mit offenem arm in pfeil nach rechts und nach oben zeigt') + - "⦭": [T: "Gemessener Winkel mit offenem Arm endet im Pfeil nach links und oben"] # 0x29ad (en: 'measured angle with open arm ending in arrow pointing left and up', MathPlayer: 'measured angle with open arm ending in arrow pointing left and up', google: 'der gemessene winkel mit offenem arm in pfeil nach links und nach oben zeigt') + - "⦮": [T: "Gemessener Winkel mit offenem Arm endet im nach rechts und unten zeigenden Pfeil"] # 0x29ae (en: 'measured angle with open arm ending in arrow pointing right and down', MathPlayer: 'measured angle with open arm ending in arrow pointing right and down', google: 'der gemessene winkel mit offenem arm in pfeil nach rechts und unten zeigt') + - "⦯": [T: "Gemessener Winkel mit offenem Arm und Pfeil nach links und unten"] # 0x29af (en: 'measured angle with open arm ending in arrow pointing left and down', MathPlayer: 'measured angle with open arm ending in arrow pointing left and down', google: 'der gemessene winkel mit offenem arm in pfeil nach links und unten zeigt') + - "⦰": [T: "Umgekehrte leere Menge"] # 0x29b0 (en: 'reversed empty set', MathPlayer: 'reversed empty set', google: 'umgekehrter leerer satz') + - "⦱": [T: "Leere Menge mit Strich oberhalb"] # 0x29b1 (en: 'empty set with overbar', MathPlayer: 'empty set with overbar', google: 'leeres set mit überbar') + - "⦲": [T: "Leere Menge mit kleinem Kreis oben"] # 0x29b2 (en: 'empty set with small circle above', MathPlayer: 'empty set with circle above', google: 'leeres set mit kleinem kreis oben') + - "⦳": [T: "Leere Menge mit Pfeil rechts oben"] # 0x29b3 (en: 'empty set with right arrow above', MathPlayer: 'empty set with right arrow above', google: 'leer mit dem rechten pfeil oben') + - "⦴": [T: "Leere Menge mit linkem Pfeil oben"] # 0x29b4 (en: 'empty set with left arrow above', MathPlayer: 'empty set with left arrow above', google: 'leeres set mit dem linken pfeil oben') + - "⦵": [T: "Kreis mit horizontaler Leiste"] # 0x29b5 (en: 'circle with horizontal bar', MathPlayer: 'circle with horizontal bar', google: 'kreis mit horizontaler balken') + - "⦶": [T: "Kreis mit vertikaler Linie"] # 0x29b6 + - "⦷": [T: "eingekreiste Parallele"] # 0x29b7 (en: 'circled parallel', MathPlayer: 'circled parallel', google: 'parallel eingekreist') + - "⦸": [T: "eingekreister umgekehrter Schrägstrich"] # 0x29b8 (en: 'circled reverse solidus', google: 'umgekreist reverse solidus') + - "⦹": [T: "eingekreistes Senkrecht"] # 0x29b9 (en: 'circled perpendicular', MathPlayer: 'circled perpendicular', google: 'senkrecht umkreist') + - "⦺": [T: "Kreis geteilt durch horizontale Leiste und obere Hälfte geteilt durch vertikale Leiste"] # 0x29ba (en: 'circled divided by horizontal bar and top half divided by vertical bar', google: 'durch den horizontalen balken und die obere hälfte geteilt durch vertikale balken eingekreist') + - "⦻": [T: "Kreis mit überlagertem X"] # 0x29bb (en: 'circle with superimposed x', MathPlayer: 'circle with superimposed x', google: 'kreis mit überlagertem x') + - "⦼": [T: "eingekreistes, gegen den Uhrzeigersinn gedrehtes Divisionszeichen"] # 0x29bc (en: 'circled anticlockwise rotated division sign', MathPlayer: 'circled anticlockwise rotated division', google: 'umgedrehtes divisionszeichen gegen den uhrzeigersinn') + - "⦽": [T: "Pfeil nach oben durch Kreis"] # 0x29bd (en: 'up arrow through circle', google: 'pfeil durch den kreis') + - "⦾": [T: "eingekreiste weiße Kugel"] # 0x29be (en: 'circled white bullet', MathPlayer: 'circled white bullet', google: 'eingekreiste weiße kugel') + - "⦿": [T: "eingekreiste Kugel"] # 0x29bf (en: 'circled bullet', MathPlayer: 'circled bullet', google: 'eingekreist') + - "⧀": [T: "eingekreist weniger als"] # 0x29c0 (en: 'circled less than', MathPlayer: 'circled less than', google: 'kreiste weniger als') + - "⧁": [T: "eingekreist größer als"] # 0x29c1 (en: 'circled greater than', MathPlayer: 'circled greater than', google: 'umgekreist größer als') + - "⧂": [T: "Kreis mit kleinem Kreis nach rechts"] # 0x29c2 (en: 'circle with small circle to the right', MathPlayer: 'circle with circle to the right', google: 'kreis mit kleinem kreis nach rechts') + - "⧃": [T: "Kreis mit zwei horizontalen Strichen nach rechts"] # 0x29c3 (en: 'circle with two horizontal strokes to the right', MathPlayer: 'circle with two horizontal strokes to the right', google: 'kreisen sie mit zwei horizontalen strichen rechts') + - "⧄": [T: "Quadrat mit Diagonale links unten nach rechts oben"] # 0x29c4 (en: 'squared rising diagonal slash', MathPlayer: 'squared rising diagonal slash', google: 'quadratischer steigender diagonaler schrägstrich') + - "⧅": [T: "Quadrat mit Diagonale links oben nach rechts unten"] # 0x29c5 (en: 'squared falling diagonal slash', MathPlayer: 'squared falling diagonal slash', google: 'quadratische fallende diagonale schrägstriche') + - "⧆": [T: "Quadrat mit Sternchen"] # 0x29c6 (en: 'squared asterisk', google: 'quadratischer sternchen') + - "⧇": [T: "Quadrat mir kleinem Kreis"] # 0x29c7 (en: 'squared small circle', google: 'quadratischer kleiner kreis') + - "⧈": [T: "Doppelquadrat"] # 0x29c8 (en: 'squared square', google: 'quadratisch quadratisch') + - "⧉": [T: "Zwei verbundene Quadrate"] # 0x29c9 (en: 'two joined squares', MathPlayer: 'two joined squares', google: 'zwei traten quadrate an') + - "⧊": [T: "Dreieck mit Punkt oben"] # 0x29ca (en: 'triangle with dot above', google: 'dreieck mit punkt oben') + - "⧋": [T: "Dreieck mit Unterleiste"] # 0x29cb (en: 'triangle with underbar', google: 'dreieck mit underbar') + - "⧌": [T: "S im Dreieck"] # 0x29cc (en: 's in triangle', google: 's im dreieck') + - "⧍": [T: "Dreieck mit Serifen unten"] # 0x29cd (en: 'triangle with serifs at bottom', MathPlayer: 'triangle with serifs at bottom', google: 'dreieck mit serifen unten') + - "⧎": [T: "Rechtes Dreieck über linkem Dreieck"] # 0x29ce (en: 'right triangle above left triangle', MathPlayer: 'right triangle above left triangle', google: 'rechts dreieck über dem linken dreieck') + - "⧏": [T: "Linkes Dreieck neben vertikaler Leiste"] # 0x29cf (en: 'left triangle beside vertical bar', MathPlayer: 'normal subgroup of with bar', google: 'links dreieck neben vertikaler balken') + - "⧐": [T: "Vertikale Leiste neben rechtem Dreieck"] # 0x29d0 (en: 'vertical bar beside right triangle', MathPlayer: 'contains as normal subgroup with bar', google: 'vertikale bar neben dem rechten dreieck') + - "⧑": [T: "Fliege mit linker Hälfte schwarz"] # 0x29d1 (en: 'bowtie with left half black', google: 'bowtie mit linksem halb schwarz') + - "⧒": [T: "Fliege mit rechter Hälfte schwarz"] # 0x29d2 (en: 'bowtie with right half black', google: 'bowtie mit rechts halb schwarz') + - "⧓": [T: "Schwarze Fliege"] # 0x29d3 (en: 'black bowtie', google: 'schwarzer bowtie') + - "⧔": [T: "Zeiten mit linker Hälfte schwarz"] # 0x29d4 (en: 'times with left half black', google: 'mal mit links halb schwarz') + - "⧕": [T: "Mal mit rechter Hälfte Schwarz"] # 0x29d5 (en: 'times with right half black', google: 'mal mit dem rechten halb schwarz') + - "⧖": [T: "Weiße Sanduhr"] # 0x29d6 (en: 'white hourglass', google: 'weiße sanduhr') + - "⧗": [T: "Schwarze Sanduhr"] # 0x29d7 (en: 'black hourglass', google: 'schwarze sanduhr') + - "⧘": [T: "Linker wackeliger Zaun"] # 0x29d8 (en: 'left wiggly fence', google: 'links wackeliger zaun') + - "⧙": [T: "rechter wackeliger Zaun"] # 0x29d9 (en: 'right wiggly fence', google: 'rechts wackeliges zaun') + - "⧚": [T: "Linker doppelter wackeliger Zaun"] # 0x29da (en: 'left double wiggly fence', MathPlayer: 'left double wiggly fence', google: 'links doppelter wackeliger zaun') + - "⧛": [T: "rechter doppelter wackeliger Zaun"] # 0x29db (en: 'right double wiggly fence', MathPlayer: 'right double wiggly fence', google: 'rechts doppelter wackeliger zaun') + - "⧜": [T: "Unvollständige Unendlichkeit"] # 0x29dc (en: 'incomplete infinity', MathPlayer: 'incomplete infinity', google: 'unvollständige unendlichkeit') + - "⧝": [T: "Krawatte über Unendlichkeit"] # 0x29dd (en: 'tie over infinity', google: 'unendlich binden') + - "⧞": [T: "Unendlichkeit mit vertikaler Leiste negiert"] # 0x29de (en: 'infinity negated with vertical bar', MathPlayer: 'infinity negated with vertical bar', google: 'unendlich negiert mit vertikaler balken') + - "⧟": [T: "Doppelter Multimap"] # 0x29df (en: 'double-ended multimap', google: 'doppel-multimap') + - "⧠": [T: "Quadrat mit konturierter Kontur"] # 0x29e0 (en: 'square with contoured outline', google: 'quadrat mit konturierten umriss') + - "⧡": [T: "Erhöht als"] # 0x29e1 (en: 'increases as', google: 'erhöht sich als') + - "⧢": [T: "Produkt mischen"] # 0x29e2 (en: 'shuffle product', google: 'shuffle -produkt') + - "⧣": [T: "Gleichheitszeichen und geneigte Parallele"] # 0x29e3 (en: 'equals sign and slanted parallel', MathPlayer: 'equals sign and slanted parallel', google: 'gleicher zeichen und schräg parallel') + - "⧤": [T: "Gleichheitszeichen und schräge Parallele zu Tilde oben"] # 0x29e4 (en: 'equals sign and slanted parallel with tilde above', MathPlayer: 'equals sign and slanted parallel with tilde above', google: 'gleicher zeichen und schräg parallel zu tilde oben') + - "⧥": [T: "Identisch und schräg parallel"] # 0x29e5 (en: 'identical to and slanted parallel', MathPlayer: 'identical to with double slash', google: 'identisch mit und schräg parallel') + - "⧦": [T: "Gleich Stark"] # 0x29e6 (en: 'gleich stark', google: 'gleich stark') + - "⧧": [T: "Thermodynamisch"] # 0x29e7 (en: 'thermodynamic', google: 'thermodynamisch') + - "⧨": [T: "Abwärtszeigendes Dreieck mit linker Hälfte schwarz"] # 0x29e8 (en: 'down pointing triangle with left half black', google: 'down dreieck mit linksem halb schwarz') + - "⧩": [T: "Abwärtszeigendes Dreieck mit rechter Hälfte schwarz"] # 0x29e9 (en: 'down pointing triangle with right half black', google: 'down dreieck mit dem rechten halben schwarz') + - "⧪": [T: "Schwarzer Diamant mit Pfeil nach unten"] # 0x29ea (en: 'black diamond with down arrow', google: 'schwarzer diamant mit pfeil') + - "⧫": [T: "Schwarze Raute"] # 0x29eb (en: 'black lozenge', MathPlayer: 'filled lozenge', google: 'schwarze raute') + - "⧬": [T: "Weißer Kreis mit Pfeil nach unten"] # 0x29ec (en: 'white circle with down arrow', google: 'weißer kreis mit pfeil') + - "⧭": [T: "Schwarzer Kreis mit Pfeil nach unten"] # 0x29ed (en: 'black circle with down arrow', google: 'schwarzer kreis mit pfeil') + - "⧮": [T: "Fehlergesperrtes weißes Quadrat"] # 0x29ee (en: 'error-barred white square', google: 'irrtum mit dem irrtümlichen weißen quadrat') + - "⧯": [T: "Fehlerfreies schwarzes Quadrat"] # 0x29ef (en: 'error-barred black square', google: 'fehler mit dem schwarzen quadrat') + - "⧰": [T: "Fehlergesperrter weißer Diamant"] # 0x29f0 (en: 'error-barred white diamond', google: 'fehler mit dem fehler mit weißem diamanten') + - "⧱": [T: "Fehlergesperrter schwarzer Diamant"] # 0x29f1 (en: 'error-barred black diamond', google: 'fehlerfreier schwarzer diamant') + - "⧲": [T: "Fehlergesperrter weißer Kreis"] # 0x29f2 (en: 'error-barred white circle', google: 'fehlerer weißer weißer kreis') + - "⧳": [T: "Fehlergesperrter schwarzer Kreis"] # 0x29f3 (en: 'error-barred black circle', google: 'fehlerer schwarzer kreis') + - "⧴": [T: "regelverzögert"] # 0x29f4 (en: 'rule-delayed') + - "⧵": [T: "Umgekehrter Schrägstrich Operator"] # 0x29f5 (en: 'reverse solidus operator', google: 'umgekehrter solidus -operator') + - "⧶": [T: "Schrägstrich mit vertikaler Leiste oben"] # 0x29f6 (en: 'solidus with overbar', MathPlayer: 'solidus with overbar', google: 'solidus mit overbar') + - "⧷": [T: "Umgekehrter Schrägstrich mit horizontalem Hub"] # 0x29f7 (en: 'reverse solidus with horizontal stroke', google: 'mit horizontalem schlaganfall solidus umkehren') + - "⧸": [T: "Großer Schrägstrich"] # 0x29f8 (en: 'big solidus', google: 'big solidus') + - "⧹": [T: "Großer umgekehrter Schrägstrich"] # 0x29f9 (en: 'big reverse solidus', google: 'big reverse solidus') + - "⧺": [T: "Doppel plus"] # 0x29fa (en: 'double plus', google: 'doppelte plus') + - "⧻": [T: "Triple Plus"] # 0x29fb (en: 'triple plus', google: 'triple plus') + - "⧼": [T: "Nach links zeigender gebogener Winkelhalter"] # 0x29fc (en: 'left pointing curved angle bracket', google: 'links gezeigt, gekrümmte winkelhalterung') + - "⧽": [T: "Nach rechts zeigender gebogener Winkelhalter"] # 0x29fd (en: 'right pointing curved angle bracket', google: 'rechte spitze gekrümmte winkelhalterung') + - "⧾": [T: "Winzig"] # 0x29fe (en: 'tiny', google: 'winzig') + - "⧿": [T: "Miny"] # 0x29ff (en: 'miny', google: 'miny') + - "⨀": [T: "Operator mit eingekreistem Punkt"] # 0x2a00 (en: 'circled dot operator', google: 'eingekreister punktbetreiber') + - "⨁": [T: "Operator mit eingekreistem Plus"] # 0x2a01 (en: 'circled plus operator', google: 'kreis plus operator') + - "⨂": [T: "Operator mit eingekreistem Kreuz"] # 0x2a02 (en: 'circled times operator', google: 'eingekreistes times operator') + - "⨃": [T: "Vereinigungs-Operator mit Punkt"] # 0x2a03 (en: 'union operator with dot', google: 'gewerkschaftsbetreiber mit punkt') + - "⨄": [T: "Vereinigungs-Operator mit Plus"] # 0x2a04 (en: 'union operator with plus', google: 'gewerkschaftsbetreiber mit plus') + - "⨅": [T: "quadratischer Schnittmengen-Operator"] # 0x2a05 (en: 'square intersection operator', google: 'square intersection operator') + - "⨆": [T: "quadratischer Vereinigungs-Operator"] # 0x2a06 (en: 'square union operator', google: 'square union operator') + - "⨇": [T: "Zwei logische Und-Operator"] # 0x2a07 (en: 'two logical and operator', google: 'zwei logische und operator') + - "⨈": [T: "Zwei logische Oder-Operator"] # 0x2a08 (en: 'two logical or operator', google: 'zwei logische oder operator') + - "⨉": [T: "Kreuz-Operator"] # 0x2a09 (en: 'times operator', google: 'times operator') + - "⨊": [T: "Modulo Zwei Summe"] # 0x2a0a (en: 'modulo two sum', google: 'modulo zwei summe') + - "⨋": [T: "Summation mit Integral"] # 0x2a0b (en: 'summation with integral', google: 'summierung mit integral') + - "⨌": [T: "Vierfach-Integral-Operator"] # 0x2a0c (SRE: 'Vierfach-Integral-Operator') + - "⨍": [T: "endliches Teilintegral"] # 0x2a0d (en: 'finite part integral', MathPlayer: 'finite part integral', google: 'finite -teil -integral') + - "⨎": [T: "Integral mit Doppelhub"] # 0x2a0e (en: 'integral with double stroke', google: 'integral mit doppelter hub') + - "⨏": [T: "Integraler Durchschnitt mit Schrägstrich"] # 0x2a0f (en: 'integral average with slash', google: 'integraler durchschnitt mit schrägstrich') + - "⨐": [T: "Zirkulationsfunktion"] # 0x2a10 (en: 'circulation function', MathPlayer: 'circulation function', google: 'zirkulationsfunktion') + - "⨑": [T: "Integration gegen den Uhrzeigersinn"] # 0x2a11 (en: 'anticlockwise integration', MathPlayer: 'anticlockwise integration', google: 'integration gegen den uhrzeigersinn') + - "⨒": [T: "Linienintegration mit rechteckigem Pfad um die Pole"] # 0x2a12 (en: 'line integration with rectangular path around pole', MathPlayer: 'line integration with rectangular path around pole', google: 'linienintegration mit einem rechteckigen pfad um pol') + - "⨓": [T: "Linienintegration mit halbkreisförmigem Pfad um den Pol"] # 0x2a13 (en: 'line integration with semicircular path around pole', MathPlayer: 'line integration with semicircular path around pole', google: 'linienintegration mit halbkreisförmigem pfad um pol') + - "⨔": [T: "Leitungsintegration ohne Pole"] # 0x2a14 (en: 'line integration not including the pole', MathPlayer: 'line integration not including the pole', google: 'linienintegration ohne stange') + - "⨕": [T: "Integral um einen Punktoperator"] # 0x2a15 (en: 'integral around a point operator', MathPlayer: 'integral around a point operator', google: 'integral um einen punktbetreiber') + - "⨖": [T: "quaternion Integral-Operator"] # 0x2a16 (SRE: 'Quaternion Integral Operator') + - "⨗": [T: "Integral mit Pfeil nach links mit Haken"] # 0x2a17 (en: 'integral with leftwards arrow with hook', MathPlayer: 'integral with leftwards arrow with hook', google: 'integraler mit linksem pfeil mit haken') + - "⨘": [T: "Integral mit Kreuzproduktzeichen"] # 0x2a18 (en: 'integral with times sign', google: 'integral mit times sign') + - "⨙": [T: "Integral mit Schnittmenge-Zeichen"] # 0x2a19 (en: 'integral with intersection', google: 'integral mit der kreuzung') + - "⨚": [T: "Integral mit Vereinigungs-Zeichen"] # 0x2a1a (en: 'integral with union', google: 'integral mit union') + - "⨛": [T: "Integral mit Overbar"] # 0x2a1b (en: 'integral with overbar', google: 'integral mit overbar') + - "⨜": [T: "Integral mit Underbar"] # 0x2a1c (en: 'integral with underbar', google: 'integral mit underbar') + - "⨝": [T: "Beitreten"] # 0x2a1d (en: 'join', google: 'verbinden') + - "⨞": [T: "Großes linkes Dreieckbediener"] # 0x2a1e (en: 'large left triangle operator', google: 'großer linker dreieck operator') + - "⨟": [T: "Z-Notationsschema-Zusammensetzung"] # 0x2a1f (en: 'z notation schema composition', google: 'z notationschema -zusammensetzung') + - "⨠": [T: "Z-Notationsschema-Piping"] # 0x2a20 (en: 'z notation schema piping', google: 'z notationschema -rohrleitungen') + - "⨡": [T: "Z-Notationsschema-Projektion"] # 0x2a21 (en: 'z notation schema projection', google: 'z notationschemaprojektion') + - "⨢": [T: "Pluszeichen mit kleinem Kreis oben"] # 0x2a22 (en: 'plus sign with circle above', MathPlayer: 'plus sign with circle above', google: 'plus zeichen mit kreis oben') + - "⨣": [T: "Pluszeichen mit Zirkumflex-Akzent oben"] # 0x2a23 (en: 'plus sign with circumflex accent above', MathPlayer: 'plus sign with circumflex accent above', google: 'plus -zeichen mit dem obigen zirkelakzent') + - "⨤": [T: "Pluszeichen mit Tilde oben"] # 0x2a24 (en: 'plus sign with tilde above', MathPlayer: 'tilde with plus below', google: 'plus zeichen mit tilde oben') + - "⨥": [T: "Pluszeichen mit Punkt unten"] # 0x2a25 (en: 'plus sign with dot below', MathPlayer: 'plus sign with dot below', google: 'plus zeichen mit punkt unten') + - "⨦": [T: "Pluszeichen mit Tilde unter"] # 0x2a26 (en: 'plus sign with tilde below', MathPlayer: 'tilde with plus above', google: 'plus zeichen mit tilde unten') + - "⨧": [T: "Pluszeichen mit Index Zwei"] # 0x2a27 (en: 'plus sign with subscript two', MathPlayer: 'plus sign with subscript two', google: 'plus sign sign mit dem index two') + - "⨨": [T: "Pluszeichen mit schwarzem Dreieck"] # 0x2a28 (en: 'plus sign with black triangle', google: 'plus zeichen mit schwarzem dreieck') + - "⨩": [T: "Minuszeichen mit Komma oben"] # 0x2a29 (en: 'minus sign with comma above', MathPlayer: 'minus sign with comma above', google: 'minus zeichen mit komma oben') + - "⨪": [T: "Minuszeichen mit Punkt unten"] # 0x2a2a (en: 'minus sign with dot below', MathPlayer: 'minus sign with dot below', google: 'minus zeichen mit punkt unten') + - "⨫": [T: "Minuszeichen mit fallenden Punkten"] # 0x2a2b (en: 'minus sign with falling dots', google: 'minus zeichen mit fallenden punkten') + - "⨬": [T: "Minuszeichen mit steigenden Punkten"] # 0x2a2c (en: 'minus sign with rising dots', google: 'minus zeichen mit steigenden punkten') + - "⨭": [T: "Pluszeichen Im linken Halbkreis"] # 0x2a2d (en: 'plus sign in left half circle', MathPlayer: 'plus sign in left half circle', google: 'plus melden sie sich im linken halbkreis an') + - "⨮": [T: "Pluszeichen Im rechten Halbkreis"] # 0x2a2e (en: 'plus sign in right half circle', MathPlayer: 'plus sign in right half circle', google: 'plus im rechten halbkreis anzeigen') + - "⨯": [T: "Vektor- oder Kreuzprodukt"] # 0x2a2f (en: 'cross product', MathPlayer: 'vector or cross product', google: 'kreuzprodukt') + - "⨰": [T: "Multiplikationszeichen mit Punkt oben"] # 0x2a30 (en: 'multiplication sign with dot above', MathPlayer: 'multiplication sign with dot above', google: 'multiplikationszeichen mit punkt oben') + - "⨱": [T: "Multiplikationszeichen mit Unterleiste"] # 0x2a31 (en: 'multiplication sign with underbar', MathPlayer: 'multiplication sign with underbar', google: 'multiplikationszeichen mit underbar') + - "⨲": [T: "Semidirektprodukt mit geschlossenem Boden"] # 0x2a32 (en: 'semidirect product with bottom closed', google: 'semidirect -produkt mit unten geschlossen') + - "⨳": [T: "smash product"] # 0x2a33 + - "⨴": [T: "Multiplikationszeichen im linken Halbkreis"] # 0x2a34 (en: 'multiplication sign in left half circle', MathPlayer: 'multiplication sign in left half circle', google: 'multiplikationszeichen im linken halbkreis') + - "⨵": [T: "Multiplikationszeichen im rechten Halbkreis"] # 0x2a35 (en: 'multiplication sign in right half circle', MathPlayer: 'multiplication sign in right half circle', google: 'multiplikationszeichen im rechten halbkreis') + - "⨶": [T: "eingekreistes Multiplikationszeichen mit Circumflex-Akzent"] # 0x2a36 (en: 'circled multiplication sign with circumflex accent', MathPlayer: 'circled multiplication sign with circumflex accent', google: 'umkreistes multiplikationszeichen mit circumflex -akzent') + - "⨷": [T: "Multiplikationszeichen im doppelten Kreis"] # 0x2a37 (en: 'multiplication sign in double circle', MathPlayer: 'multiplication sign in double circle', google: 'multiplikationszeichen im doppelkreis') + - "⨸": [T: "circled division sign"] # 0x2a38 + - "⨹": [T: "Pluszeichen im Dreieck"] # 0x2a39 (en: 'plus sign in triangle', MathPlayer: 'plus sign in triangle', google: 'plus melden sie sich im dreieck an') + - "⨺": [T: "Minuszeichen im Dreieck"] # 0x2a3a (en: 'minus sign in triangle', MathPlayer: 'minus sign in triangle', google: 'minus zeichen im dreieck') + - "⨻": [T: "Multiplikationszeichen im Dreieck"] # 0x2a3b (en: 'multiplication sign in triangle', MathPlayer: 'multiplication sign in triangle', google: 'multiplikationszeichen im dreieck') + - "⨼": [T: "Innenprodukt"] # 0x2a3c (en: 'interior product', MathPlayer: 'interior product', google: 'innenprodukt') + - "⨽": [T: "Produkt für den rechten Innenraum"] # 0x2a3d (en: 'righthand interior product', google: 'righthand innenprodukt') + - "⨿": [T: "Verschmelzung oder Koprodukt"] # 0x2a3f (en: 'amalgamation or coproduct', MathPlayer: 'amalgamation or coproduct', google: 'verschmelzung oder koprodukt') + - "⩀": [T: "Schnittpunkt mit Punkt"] # 0x2a40 (en: 'intersection with dot', MathPlayer: 'intersection with dot', google: 'kreuzung mit punkt') + - "⩁": [T: "Union mit Minuszeichen"] # 0x2a41 (en: 'union with minus sign', google: 'gewerkschaft mit minus zeichen') + - "⩂": [T: "Union mit Overbar"] # 0x2a42 (en: 'union with overbar', MathPlayer: 'union with overbar', google: 'gewerkschaft mit overbar') + - "⩃": [T: "Kreuzung mit Overbar"] # 0x2a43 (en: 'intersection with overbar', MathPlayer: 'intersection with overbar', google: 'kreuzung mit überbär') + - "⩄": [T: "Überschneidung mit logischem und"] # 0x2a44 (en: 'intersection with logical and', MathPlayer: 'intersection with logical and', google: 'schnittpunkt mit logisch und') + - "⩅": [T: "Vereinigung mit logischem Or"] # 0x2a45 (en: 'union with logical or', MathPlayer: 'union with logical or', google: 'vereinigung mit logisch oder') + - "⩆": [T: "Vereinigung über dem Schnittpunkt"] # 0x2a46 (en: 'union above intersection', MathPlayer: 'union above intersection', google: 'union über der kreuzung') + - "⩇": [T: "Schnittpunkt über Union"] # 0x2a47 (en: 'intersection above union', MathPlayer: 'intersection above union', google: 'kreuzung über union') + - "⩈": [T: "Vereinigung über Stab über Kreuzung"] # 0x2a48 (en: 'union above bar above intersection', MathPlayer: 'union above bar above intersection', google: 'gewerkschaft über der bar über der kreuzung') + - "⩉": [T: "Schnittpunkt oberhalb der Stange oberhalb der Union"] # 0x2a49 (en: 'intersection above bar above union', MathPlayer: 'intersection above bar above union', google: 'kreuzung über bar über union') + - "⩊": [T: "Union daneben und mit Union verbunden"] # 0x2a4a (en: 'union beside and joined with union', MathPlayer: 'union beside and joined with union', google: 'gewerkschaft neben der union') + - "⩋": [T: "Kreuzung neben und mit Kreuzung verbunden"] # 0x2a4b (en: 'intersection beside and joined with intersection', MathPlayer: 'intersection beside and joined with intersection', google: 'kreuzung neben und zusammen mit der kreuzung') + - "⩌": [T: "Geschlossene Vereinigung mit Serifen"] # 0x2a4c (en: 'closed union with serifs', MathPlayer: 'closed union with serifs', google: 'geschlossene vereinigung mit serifen') + - "⩍": [T: "Geschlossener Schnittpunkt mit Serifen"] # 0x2a4d (en: 'closed intersection with serifs', MathPlayer: 'closed intersection with serifs', google: 'geschlossener kreuzung mit serifen') + - "⩎": [T: "Doppelter Quadratschnitt"] # 0x2a4e (en: 'double square intersection', google: 'doppelquadratische kreuzung') + - "⩏": [T: "Double Square Union"] # 0x2a4f (en: 'double square union', google: 'doppelquadratische gewerkschaft') + - "⩐": [T: "Closed Union mit Serifen und Smash-Produkten"] # 0x2a50 (en: 'closed union with serifs and smash product', MathPlayer: 'closed union with serifs and smash product', google: 'geschlossene vereinigung mit serifen und smash -produkt') + - "⩑": [T: "Logisch und mit Punkt oben"] # 0x2a51 (en: 'logical and with dot above', google: 'logisch und mit punkt oben') + - "⩒": [T: "Logisch oder mit Punkt oben"] # 0x2a52 (en: 'logical or with dot above', google: 'logisch oder mit punkt oben') + - "⩓": [T: "double logical and"] # 0x2a53 + - "⩔": [T: "double logical or"] # 0x2a54 + - "⩕": [T: "Zwei durchschneiden logisch und"] # 0x2a55 (en: 'two intersecting logical and', MathPlayer: 'two intersecting logical and', google: 'zwei kreuzende logische und') + - "⩖": [T: "Zwei sich überschneidende logische Oder"] # 0x2a56 (en: 'two intersecting logical or', MathPlayer: 'two intersecting logical or', google: 'zwei kreuzende logische oder') + - "⩗": [T: "Abfallend großes oder"] # 0x2a57 (en: 'sloping large or', MathPlayer: 'sloping large or', google: 'groß oder') + - "⩘": [T: "Abfallend großes und"] # 0x2a58 (en: 'sloping large and', MathPlayer: 'sloping large and', google: 'groß und') + - "⩙": [T: "Logisch oder Überlappend Logisch Und"] # 0x2a59 (en: 'logical or overlapping logical and', google: 'logisch oder überlappend logisch und') + - "⩚": [T: "Logisch und mit Middle Stem"] # 0x2a5a (en: 'logical and with middle stem', MathPlayer: 'logical and with middle stem', google: 'logisch und mit mittlerem stiel') + - "⩛": [T: "Logisch oder mit Middle Stem"] # 0x2a5b (en: 'logical or with middle stem', MathPlayer: 'logical or with middle stem', google: 'logisch oder mit mittlerem stiel') + - "⩜": [T: "Logisch und mit Horizontalstrich"] # 0x2a5c (en: 'logical and with horizontal dash', MathPlayer: 'logical and with horizontal dash', google: 'logisch und mit horizontalem armaturenbrett') + - "⩝": [T: "Logisch oder mit Horizontalstrich"] # 0x2a5d (en: 'logical or with horizontal dash', MathPlayer: 'logical or with horizontal dash', google: 'logisch oder mit horizontalem strich') + - "⩞": [T: "Logisch und mit Double Overbar"] # 0x2a5e (en: 'logical and with double overbar', google: 'logisch und mit doppelter überbärung') + - "⩟": [T: "Logisch und mit Underbar"] # 0x2a5f (en: 'logical and with underbar', MathPlayer: 'logical and with underbar', google: 'logisch und mit unterbar') + - "⩠": [T: "Logisch und mit Double Underbar"] # 0x2a60 (en: 'logical and with double underbar', google: 'logisch und mit doppelter unterbarung') + - "⩡": [T: "kleines Vee mit Underbar"] # 0x2a61 (en: 'small vee with underbar', google: 'kleiner vee mit unterbar') + - "⩢": [T: "Logisch oder mit Double Overbar"] # 0x2a62 (en: 'logical or with double overbar', google: 'logisch oder mit doppelter überbärung') + - "⩣": [T: "Logisch oder mit doppelter Unterleiste"] # 0x2a63 (en: 'logical or with double underbar', google: 'logisch oder mit doppelter unterbarung') + - "⩤": [T: "Z-Notation Domain Antirestriction"] # 0x2a64 (en: 'z notation domain antirestriction', google: 'z notation domain antirestriktion') + - "⩥": [T: "Z Notationsbereich Antirestriction"] # 0x2a65 (en: 'z notation range antirestriction', google: 'z notation range antirestriktion') + - "⩦": [T: "Gleichheitszeichen mit Punkt unten"] # 0x2a66 (en: 'equals sign with dot below', MathPlayer: 'equal with dot below', google: 'gleiches zeichen mit punkt unten') + - "⩧": [T: "Identisch mit dem obigen Punkt"] # 0x2a67 (en: 'identical with dot above', google: 'identisch mit punkt oben') + - "⩨": [T: "Dreifacher Horizontalbalken mit doppeltem vertikalem Hub"] # 0x2a68 (en: 'triple horizontal bar with double vertical stroke', google: 'dreifache horizontale balken mit doppelter vertikaler hub') + - "⩩": [T: "Dreifacher Horizontalbalken mit dreifachem vertikalem Hub"] # 0x2a69 (en: 'triple horizontal bar with triple vertical stroke', google: 'dreifache horizontale stange mit dreifachem vertikalem schlaganfall') + - "⩪": [T: "Tilde-Operator mit Punkt oben"] # 0x2a6a (en: 'tilde operator with dot above', MathPlayer: 'tilde with dot', google: 'tilde -operator mit punkt oben') + - "⩫": [T: "Tilde-Operator mit steigenden Punkten"] # 0x2a6b (en: 'tilde operator with rising dots', google: 'tilde -operator mit steigenden punkten') + - "⩬": [T: "Ähnlich Minus Ähnlich"] # 0x2a6c (en: 'similar minus similar', google: 'ähnlich minus ähnlich') + - "⩭": [T: "Kongruent mit Punkt oben"] # 0x2a6d (en: 'congruent with dot above', MathPlayer: 'congruent with dot above', google: 'kongruent mit punkten oben') + - "⩮": [T: "Entspricht Asterisk"] # 0x2a6e (en: 'equals with asterisk', google: 'entspricht mit sternchen') + - "⩯": [T: "Fast gleichwertig mit dem Circumflex Accent"] # 0x2a6f (en: 'almost equal to with circumflex accent', MathPlayer: 'almost equal to with circumflex accent', google: 'fast gleich mit dem zirkumflexakzent') + - "⩰": [T: "Ungefähr gleich oder gleich zu"] # 0x2a70 (en: 'approximately equal to or equal to', google: 'ungefähr gleich oder gleich') + - "⩱": [T: "Gleichheitszeichen über Pluszeichen"] # 0x2a71 (en: 'equals sign above plus sign', MathPlayer: 'equals with plus below', google: 'gleiches zeichen oben plus zeichen') + - "⩲": [T: "Pluszeichen über Gleichheitszeichen"] # 0x2a72 (en: 'plus sign above equals sign', MathPlayer: 'equals with plus above', google: 'plus -zeichen oben gleiches zeichen') + - "⩳": [T: "Gleichheitszeichen über Tilde-Operator"] # 0x2a73 (en: 'equals sign above tilde operator', MathPlayer: 'equals sign above tilde operator', google: 'gleicher vorzeichen über dem tilde -operator') + - "⩴": [T: "Doppelpunkt gleich"] # 0x2a74 (en: 'double colon equal', MathPlayer: 'double colon equal', google: 'doppelter dickdarm gleich') + - "⩵": [T: "double equal"] # 0x2a75 (en: 'two consecutive equals signs') + - "⩶": [T: "Drei aufeinander folgende Gleichheitszeichen"] # 0x2a76 (en: 'three consecutive equals signs', google: 'drei aufeinanderfolgende anzeichen') + - "⩷": [T: "Gleichheitszeichen mit zwei Punkten oben und zwei Punkten unten"] # 0x2a77 (en: 'equals sign with two dots above and two dots below', MathPlayer: 'equals sign with two dots above and two dots below', google: 'gleiches zeichen mit zwei punkten oben und zwei punkten unten') + - "⩸": [T: "Gleichwertig mit vier Punkten oben"] # 0x2a78 (en: 'equivalent with four dots above', MathPlayer: 'equivalent with four dots above', google: 'äquivalent mit vier punkten oben') + - "⩹": [T: "Weniger als mit Circle Inside"] # 0x2a79 (en: 'less than with circle inside', MathPlayer: 'less than with circle inside', google: 'weniger als mit kreis im inneren') + - "⩺": [T: "Größer als mit Kreis nach innen"] # 0x2a7a (en: 'greater than with circle inside', MathPlayer: 'greater than with circle inside', google: 'größer als mit kreis im inneren') + - "⩻": [T: "Weniger als mit Fragezeichen oben"] # 0x2a7b (en: 'less than with question mark above', MathPlayer: 'less than with question mark above', google: 'weniger als mit fragezeichen oben') + - "⩼": [T: "Größer als mit Fragezeichen oben"] # 0x2a7c (en: 'greater than with question mark above', MathPlayer: 'greater than with question mark above', google: 'größer als mit dem obigen fragezeichen') + - "⩽": [T: "Weniger als oder schräg gleich"] # 0x2a7d (en: 'less than or slanted equal to', MathPlayer: 'less than or slanted equal to', google: 'weniger als oder schräg gleich') + - "⩾": [T: "Größer als oder schräg gleich"] # 0x2a7e (en: 'greater than or slanted equal to', MathPlayer: 'greater than or slanted equal', google: 'größer als oder schräg gleich') + - "⩿": [T: "Weniger als oder schräg gleich mit Punkt nach innen"] # 0x2a7f (en: 'less than or slanted equal to with dot inside', MathPlayer: 'less than or slanted equal to with dot inside', google: 'weniger als oder schräg gleich mit punkt im inneren') + - "⪀": [T: "Größer als oder schräg gleich mit Punkt nach innen"] # 0x2a80 (en: 'greater than or slanted equal to with dot inside', MathPlayer: 'greater than or slanted equal to with dot inside', google: 'größer als oder schräg gleich mit punkt im inneren') + - "⪁": [T: "Weniger als oder schräg gleich mit Punkt oben"] # 0x2a81 (en: 'less than or slanted equal to with dot above', MathPlayer: 'less than or slanted equal to with dot above', google: 'weniger als oder schräg gleich mit punkt oben') + - "⪂": [T: "Größer als oder schräg gleich mit Punkt oben"] # 0x2a82 (en: 'greater than or slanted equal to with dot above', MathPlayer: 'greater than or slanted equal to with dot above', google: 'größer als oder schräg gleich mit punkt oben') + - "⪃": [T: "Weniger als oder schräg gleich mit Punkt oben rechts"] # 0x2a83 (en: 'less than or slanted equal to with dot above right', MathPlayer: 'less than or slanted equal to with dot above right', google: 'weniger oder schräg gleich mit dem punkt oben rechts') + - "⪄": [T: "Größer als oder schräg gleich mit Punkt oben links"] # 0x2a84 (en: 'greater than or slanted equal to with dot above left', MathPlayer: 'greater than or slanted equal to with dot above left', google: 'größer als oder schräg gleich mit punkt oben links') + - "⪅": [T: "Weniger als oder ungefähr"] # 0x2a85 (en: 'less than or approximate', google: 'weniger als oder ungefähr') + - "⪆": [T: "Größer als oder ungefähr"] # 0x2a86 (en: 'greater than or approximate', google: 'größer als oder ungefähr') + - "⪇": [T: "Kleiner als aber nicht gleich"] # 0x2a87 (en: 'less than and single line not equal to', google: 'weniger als und eine einzelne linie nicht gleich') + - "⪈": [T: "Größer als aber nicht gleich"] # 0x2a88 (en: 'greater than and single line not equal to', google: 'größer als und eine einzelne linie nicht gleich') + - "⪉": [T: "Kleiner als aber nicht ungefähr gleich"] # 0x2a89 (en: 'less than and not approximate', MathPlayer: 'less than but not approximately equal to', google: 'weniger als und nicht ungefähr') + - "⪊": [T: "Größer als aber nicht ungefähr gleich"] # 0x2a8a (en: 'greater than and not approximate', MathPlayer: 'greater than but not approximately equal to', google: 'größer als und nicht ungefähr') + - "⪋": [T: "Weniger als aber größer als oben"] # 0x2a8b (en: 'less than above double line equal above greater than', google: 'weniger als über der doppelten linie gleich über größer als höher als') + - "⪌": [T: "Größer als aber weniger als unten und größer als oben"] # 0x2a8c (en: 'greater than above double line equal above less than', google: 'größer als über der doppelten linie, die über weniger als über weniger als übertroffen werden') + - "⪍": [T: "Weniger als oben ähnlich oder gleich"] # 0x2a8d (en: 'less than above similar or equal', MathPlayer: 'less than above similar or equal', google: 'weniger als über ähnlich oder gleich') + - "⪎": [T: "Größer als oben ähnlich oder gleich"] # 0x2a8e (en: 'greater than above similar or equal', MathPlayer: 'greater than above similar or equal', google: 'größer als über ähnlich oder gleich') + - "⪏": [T: "Weniger als oben ähnlich oben größer als"] # 0x2a8f (en: 'less than above similar above greater than', MathPlayer: 'less than above similar above greater than', google: 'weniger als über ähnlich oben höher als größer als') + - "⪐": [T: "Größer als oben Ähnlich oben"] # 0x2a90 (en: 'greater than above similar above less than', MathPlayer: 'greater than above similar above less than', google: 'größer als über ähnlich über ähnlichem') + - "⪑": [T: "less than greater than or equal to"] # 0x2a91 (en: 'less than above greater than above double line equal') + - "⪒": [T: "greater than less than or equal to"] # 0x2a92 (en: 'greater than above less than above double line equal') + - "⪓": [T: "Weniger als oben schräg gleich oben Größer als oben schräg gleich"] # 0x2a93 (en: 'less than above slanted equal above greater than above slanted equal', MathPlayer: 'less than above slanted equal above greater than above slanted equal', google: 'weniger als über dem überdurchschnittlich überdurchschnittlich überdurchschnittlich ist es gleich') + - "⪔": [T: "Größer als oben schräg gleich oben kleiner als oben schräg gleich groß"] # 0x2a94 (en: 'greater than above slanted equal above less than above slanted equal', MathPlayer: 'greater than above slanted equal above less than above slanted equal', google: 'größer als über dem schrägen gleich über dem gleichen schrägen gleich') + - "⪕": [T: "Schräg gleich oder kleiner als"] # 0x2a95 (en: 'slanted equal to or less than', google: 'schräg gleich oder weniger als') + - "⪖": [T: "Schräg gleich oder größer als"] # 0x2a96 (en: 'slanted equal to or greater than', google: 'schräg gleich oder größer als') + - "⪗": [T: "Schräg gleich oder kleiner als mit innenliegendem Punkt"] # 0x2a97 (en: 'slanted equal to or less than with dot inside', MathPlayer: 'slanted equal to or less than with dot inside', google: 'schräg gleich oder weniger als mit punkt im inneren') + - "⪘": [T: "Schräg gleich oder größer als mit Punkt nach innen"] # 0x2a98 (en: 'slanted equal to or greater than with dot inside', MathPlayer: 'slanted equal to or greater than with dot inside', google: 'schräg gleich oder größer als mit punkt im inneren') + - "⪙": [T: "Gleich oder kleiner als"] # 0x2a99 (en: 'double line equal to or less than', MathPlayer: 'equal (double) over less than', google: 'doppellinie gleich oder weniger als') + - "⪚": [T: "Gleich oder größer als"] # 0x2a9a (en: 'double line equal to or greater than', MathPlayer: 'equal to or greater than', google: 'doppellinie gleich oder größer als') + - "⪛": [T: "Doppelte Linie schräg gleich oder kleiner als"] # 0x2a9b (en: 'double line slanted equal to or less than', google: 'doppelzeile, die gleich oder weniger als weniger als') + - "⪜": [T: "Doppelte Linie schräg gleich oder größer als"] # 0x2a9c (en: 'double line slanted equal to or greater than', google: 'doppelte linie schräg gleich oder größer als') + - "⪝": [T: "Äquivalent oder kleiner als"] # 0x2a9d (en: 'similar or less than', MathPlayer: 'equivalent to or less than', google: 'ähnlich oder weniger als') + - "⪞": [T: "Ähnlich oder größer als"] # 0x2a9e (en: 'similar or greater than', MathPlayer: 'similar or greater than', google: 'ähnlich oder größer als') + - "⪟": [T: "Ähnlich oben Weniger als Gleiches Gleichheitszeichen"] # 0x2a9f (en: 'similar above less than above equals sign', MathPlayer: 'similar above less than above equals sign', google: 'ähnlich oben weniger als über oben gleiches zeichen') + - "⪠": [T: "Ähnlich oben größer als oben Gleichheitszeichen"] # 0x2aa0 (en: 'similar above greater than above equals sign', MathPlayer: 'similar above greater than above equals sign', google: 'ähnlich oben größer als über oben gleiches zeichen') + - "⪡": [T: "Verschachteltes kleiner als"] # 0x2aa1 (en: 'double nested less than', MathPlayer: 'nested less than', google: 'doppelt weniger verschachtelt als') + - "⪢": [T: "Verschachteltes größer als"] # 0x2aa2 (en: 'double nested greater than', MathPlayer: 'nested greater than', google: 'doppelt verschachtelt größer als') + - "⪣": [T: "Doppelt verschachtelt, weniger als mit Unterleiste"] # 0x2aa3 (en: 'double nested less than with underbar', google: 'doppelte verschachtel weniger als mit underbar') + - "⪤": [T: "less than greater than overlay"] # 0x2aa4 (en: 'greater than overlapping less than') + - "⪥": [T: "Größer als weniger als"] # 0x2aa5 (en: 'greater than beside less than', MathPlayer: 'greater than beside less than', google: 'größer als weniger als weniger als') + - "⪦": [T: "Weniger als durch Kurve geschlossen"] # 0x2aa6 (en: 'less than closed by curve', MathPlayer: 'less than closed by curve', google: 'weniger als durch kurve geschlossen') + - "⪧": [T: "Größer als durch Kurve geschlossen"] # 0x2aa7 (en: 'greater than closed by curve', MathPlayer: 'greater than closed by curve', google: 'größer als durch kurve geschlossen') + - "⪨": [T: "Weniger als dann geschlossen durch Kurve oberhalb der gleichen Neigung"] # 0x2aa8 (en: 'less than closed by curve above slanted equal', MathPlayer: 'less than closed by curve above slanted equal', google: 'weniger als geschlossen durch kurve über schräg gleich') + - "⪩": [T: "Größer als geschlossen durch Kurve oberhalb der gleichen Neigung"] # 0x2aa9 (en: 'greater than closed by curve above slanted equal', MathPlayer: 'greater than closed by curve above slanted equal', google: 'größer als durch kurve über schräg gleich geschlossen') + - "⪪": [T: "kleiner als"] # 0x2aaa (en: 'smaller than', MathPlayer: 'smaller than') + - "⪫": [T: "Größer als"] # 0x2aab (en: 'larger than', MathPlayer: 'larger than', google: 'größer als') + - "⪬": [T: "kleiner als oder gleich"] # 0x2aac (en: 'smaller than or equal to', MathPlayer: 'smaller than or equal to') + - "⪭": [T: "Größer als oder gleich"] # 0x2aad (en: 'larger than or equal to', MathPlayer: 'larger than or equal to', google: 'größer als oder gleich') + - "⪮": [T: "difference between (variant"] # 0x2aae (en: 'equals sign with bumpy above', MathPlayer: 'difference between (variant)', google: 'gleiches zeichen mit holprigem oben') + - "⪯": [T: "Stellt über dem einzeiligen Gleichheitszeichen ein"] # 0x2aaf (en: 'precedes above single line equals sign', MathPlayer: 'precedes above single line equals sign', google: 'vorausgesetzt über ein einzelner zeile ist gleich ein zeichen') + - "⪰": [T: "Erfolg über dem einzeiligen Gleichheitszeichen"] # 0x2ab0 (en: 'succeeds above single line equals sign', google: 'nachfolger über eine einzelne zeile gleich zeichen') + - "⪱": [T: "Vorangehende Single-Line ist nicht gleich"] # 0x2ab1 (en: 'precedes above single line not equal to', google: 'vor voraussichtlich nicht gleich einzelner linie gleich') + - "⪲": [T: "Erfolg über Single-Line nicht gleich"] # 0x2ab2 (en: 'succeeds above single line not equal to', google: 'nachfolger über eine einzelne linie nicht gleich') + - "⪳": [T: "Vorangegangenes Gleichheitszeichen"] # 0x2ab3 (en: 'precedes above equals sign', google: 'vor dem gleichen vorzeichen voraus') + - "⪴": [T: "Erfolgreich über Gleichheitszeichen"] # 0x2ab4 (en: 'succeeds above equals sign', google: 'nachfolger über gleiches zeichen') + - "⪵": [T: "precedes but not equal to"] # 0x2ab5 (en: 'precedes above not equal to') + - "⪶": [T: "succeeds but not equal to"] # 0x2ab6 (en: 'succeeds above not equal to') + - "⪷": [T: "Vorangegangenes fast gleich zu"] # 0x2ab7 (en: 'precedes above almost equal to', google: 'vor voraussichtlich fast gleich gleich') + - "⪸": [T: "Erreicht über fast gleich viel"] # 0x2ab8 (en: 'succeeds above almost equal to', google: 'erfolgreich ist über fast gleich') + - "⪹": [T: "Vorangegangene nicht annähernd gleich"] # 0x2ab9 (en: 'precedes above not almost equal to', google: 'vorkommen oben nicht annähernd gleich') + - "⪺": [T: "Erreicht oben nicht annähernd gleich"] # 0x2aba (en: 'succeeds above not almost equal to', google: 'es ist nicht annähernd gleich') + - "⪻": [T: "Doppelter Vorgänger"] # 0x2abb (en: 'double precedes', MathPlayer: 'double precedes', google: 'double geht vor') + - "⪼": [T: "Doppelter Erfolg"] # 0x2abc (en: 'double succeeds', MathPlayer: 'double succeeds', google: 'doppelt erfolgreich') + - "⪽": [T: "Teilmenge mit Punkt"] # 0x2abd (en: 'subset with dot', MathPlayer: 'subset of with dot; is included in as sub relation', google: 'untergruppe mit punkt') + - "⪾": [T: "Superset mit Punkt"] # 0x2abe (en: 'superset with dot', MathPlayer: 'superset of with dot; includes as sub relation', google: 'superset mit punkt') + - "⪿": [T: "Teilmenge mit Pluszeichen unten"] # 0x2abf (en: 'subset with plus sign below', MathPlayer: 'subset with plus sign below', google: 'untergruppe mit pluszeichen unten') + - "⫀": [T: "Superset mit Pluszeichen unten"] # 0x2ac0 (en: 'superset with plus sign below', MathPlayer: 'superset with plus sign below', google: 'superset mit plus -zeichen unten') + - "⫁": [T: "Teilmenge mit Multiplikationszeichen unten"] # 0x2ac1 (en: 'subset with multiplication sign below', MathPlayer: 'subset with multiplication sign below', google: 'untergruppe mit multiplikationszeichen unten') + - "⫂": [T: "Superset mit Multiplikationszeichen unten"] # 0x2ac2 (en: 'superset with multiplication sign below', MathPlayer: 'superset with multiplication sign below', google: 'superset mit multiplikationszeichen unten') + - "⫃": [T: "Teilmenge oder gleich mit dem obigen Punkt"] # 0x2ac3 (en: 'subset of or equal to with dot above', MathPlayer: 'subset of or equal to with dot above', google: 'teilmenge von oder gleich mit punkt oben') + - "⫄": [T: "Superset von oder gleich mit Punkt oben"] # 0x2ac4 (en: 'superset of or equal to with dot above', MathPlayer: 'superset of or equal to with dot above', google: 'superset von oder gleich mit punkt oben') + - "⫅": [T: "Teilmenge des obigen Gleichheitszeichens"] # 0x2ac5 (en: 'subset of above equals sign', google: 'teilmenge von oben gleichen vorzeichen') + - "⫆": [T: "Superset des obigen Gleichheitszeichens"] # 0x2ac6 (en: 'superset of above equals sign', google: 'superset von oben gleichen vorzeichen') + - "⫇": [T: "approximate subset of"] # 0x2ac7 (en: 'subset of above tilde operator') + - "⫈": [T: "approximate superset of"] # 0x2ac8 (en: 'superset of above tilde operator') + - "⫉": [T: "Teilmenge von oben fast gleich"] # 0x2ac9 (en: 'subset of above almost equal to', google: 'untergruppe von oben fast gleich') + - "⫊": [T: "Superset von oben fast gleichwertig"] # 0x2aca (en: 'superset of above almost equal to', google: 'superset von oben fast gleich') + - "⫋": [T: "Teilmenge von oben nicht gleich"] # 0x2acb (en: 'subset above not equal to', google: 'untergruppe oben nicht gleich') + - "⫌": [T: "Superset von oben nicht gleich"] # 0x2acc (en: 'superset of above not equal to', google: 'superset von oben nicht gleich') + - "⫍": [T: "Platz links Feldbetreiber geöffnet"] # 0x2acd (en: 'square left open box operator', google: 'quadratische linke offene box -bediener') + - "⫎": [T: "Rechteckige Box mit offener Box"] # 0x2ace (en: 'square right open box operator', google: 'square right open box operator') + - "⫏": [T: "Geschlossener Teilsatz"] # 0x2acf (en: 'closed subset', MathPlayer: 'closed subset', google: 'geschlossene untergruppe') + - "⫐": [T: "Superset geschlossen"] # 0x2ad0 (en: 'closed superset', MathPlayer: 'closed superset', google: 'geschlossener superset') + - "⫑": [T: "Geschlossene Untermenge oder gleich"] # 0x2ad1 (en: 'closed subset or equal to', MathPlayer: 'closed subset or equal to', google: 'geschlossene untergruppe oder gleich') + - "⫒": [T: "Superset geschlossen oder gleich"] # 0x2ad2 (en: 'closed superset or equal to', MathPlayer: 'closed superset or equal to', google: 'geschlossene superset oder gleich') + - "⫓": [T: "subset over superset"] # 0x2ad3 (en: 'subset above superset') + - "⫔": [T: "superset over subset"] # 0x2ad4 (en: 'superset above subset') + - "⫕": [T: "subset over subset"] # 0x2ad5 (en: 'subset above subset') + - "⫖": [T: "superset over superset"] # 0x2ad6 (en: 'superset above superset') + - "⫗": [T: "Superset neben dem Subset"] # 0x2ad7 (en: 'superset beside subset', MathPlayer: 'superset beside subset', google: 'superset neben untergruppe') + - "⫘": [T: "Superset Neben und Joined von Dash mit Subset"] # 0x2ad8 (en: 'superset beside and joined by dash with subset', MathPlayer: 'superset beside and joined by dash with subset', google: 'superset neben dem dash mit der untergruppe') + - "⫙": [T: "Element der Öffnung nach unten"] # 0x2ad9 (en: 'element of opening downwards', MathPlayer: 'element of opening downwards', google: 'element der abwärts öffnen') + - "⫚": [T: "Heugabel mit T-Stück"] # 0x2ada (en: 'pitchfork with tee top', MathPlayer: 'pitchfork with tee top', google: 'pitchfork mit t -shirt top') + - "⫛": [T: "Transversalschnitt"] # 0x2adb (en: 'transversal intersection', MathPlayer: 'transversal intersection', google: 'transversal -kreuzung') + - "⫝̸": [T: "Gabelung"] # 0x2adc (en: 'forking', google: 'gabel') + - "⫝": [T: "Nicht Gabeln"] # 0x2add (en: 'nonforking', google: 'nicht -forking') + - "⫞": [T: "Kurzer Linker Tack"] # 0x2ade (en: 'short left tack', google: 'kurzer linker tack') + - "⫟": [T: "Kurzer Down Tack"] # 0x2adf (en: 'short down tack', google: 'kurzer tack') + - "⫠": [T: "Short Up Tack"] # 0x2ae0 (en: 'short up tack', google: 'kurzer tack') + - "⫡": [T: "Rechtwinklig zu S"] # 0x2ae1 (en: 'perpendicular with s', google: 'senkrecht mit s') + - "⫢": [T: "Vertikales Dreifach-Drehkreuz"] # 0x2ae2 (en: 'vertical bar triple right turnstile', google: 'vertikale bar dreifache rechte drehstil') + - "⫣": [T: "Doppelter vertikaler Balken linkes Drehkreuz"] # 0x2ae3 (en: 'double vertical bar left turnstile', google: 'doppelte vertikale balken linke drehkreuze') + - "⫤": [T: "double left turnstile vertical bar"] # 0x2ae4 (en: 'vertical bar double left turnstile') + - "⫥": [T: "Doppelter vertikaler Balken Doppelter linker Drehkreuz"] # 0x2ae5 (en: 'double vertical bar double left turnstile', google: 'doppelte vertikale balken doppelte linke drehkreuze') + - "⫦": [T: "Long Dash von Left Member von Double Vertical"] # 0x2ae6 (en: 'long dash from left member of double vertical', MathPlayer: 'long dash from left member of double vertical', google: 'langer dash vom linken mitglied des doppel vertikalen') + - "⫧": [T: "Short Down Tack mit Overbar"] # 0x2ae7 (en: 'short down tack with overbar', MathPlayer: 'short down tack with overbar', google: 'kurzer tack mit overbar') + - "⫨": [T: "perpendicular over bar"] # 0x2ae8 (en: 'short up tack with underbar') + - "⫩": [T: "Short Up Tack Über Short Down Tack"] # 0x2ae9 (en: 'short up tack above short down tack', MathPlayer: 'short up tack above short down tack', google: 'kurzschluss über kurzer tack') + - "⫪": [T: "Double Down Tack"] # 0x2aea (en: 'double down tack', google: 'double down tack') + - "⫫": [T: "Verdoppeln Sie Tack"] # 0x2aeb (en: 'double up tack', MathPlayer: 'double up tack', google: 'doppelte tack') + - "⫬": [T: "Doppelstrich nicht unterschreiben"] # 0x2aec (en: 'double stroke not sign', MathPlayer: 'double stroke not sign', google: 'doppelhub nicht unterschreiben') + - "⫭": [T: "Umgekehrter Doppelstrich nicht unterschrieben"] # 0x2aed (en: 'reversed double stroke not sign', MathPlayer: 'reversed double stroke not sign', google: 'umgekehrter doppelstrich nicht unterschreiben') + - "⫮": [T: "Teilt sich nicht mit umgekehrten Negationsschrägstrich"] # 0x2aee (en: 'does not divide with reversed negation slash', MathPlayer: 'does not divide with reversed negation slash', google: 'teilt sich nicht mit umgekehrter negationsschrägung') + - "⫯": [T: "Vertikale Linie mit Kreis oben"] # 0x2aef (en: 'vertical line with circle above', MathPlayer: 'vertical line with circle above', google: 'vertikale linie mit dem obigen kreis') + - "⫰": [T: "Vertikale Linie mit Kreis unten"] # 0x2af0 (en: 'vertical line with circle below', MathPlayer: 'vertical line with circle below', google: 'vertikale linie mit kreis unten') + - "⫱": [T: "Down Tack mit Kreis unten"] # 0x2af1 (en: 'down tack with circle below', MathPlayer: 'down tack with circle below', google: 'down tack mit kreis unten') + - "⫲": [T: "Parallel zum horizontalen Anschlag"] # 0x2af2 (en: 'parallel with horizontal stroke', MathPlayer: 'parallel with horizontal stroke', google: 'parallel zu horizontalem schlaganfall') + - "⫳": [T: "Parallel zu Tilde Operator"] # 0x2af3 (en: 'parallel with tilde operator', MathPlayer: 'parallel with tilde operator', google: 'parallel zum tilde -operator') + - "⫴": [T: "Dreifache vertikale Balken-Binärbeziehung"] # 0x2af4 (en: 'triple vertical bar binary relation', google: 'triple vertical bar binärbeziehung') + - "⫵": [T: "Dreifacher vertikaler Strich mit horizontalem Hub"] # 0x2af5 (en: 'triple vertical bar with horizontal stroke', google: 'dreifache vertikale balken mit horizontalem schlaganfall') + - "⫶": [T: "Triple Colon Operator"] # 0x2af6 (en: 'triple colon operator', google: 'dreifacher dickdarmbetreiber') + - "⫷": [T: "Dreifach verschachtelt weniger als"] # 0x2af7 (en: 'triple nested less than', google: 'dreifach verschachtelte weniger als') + - "⫸": [T: "Dreifach verschachteltes Größeres als"] # 0x2af8 (en: 'triple nested greater than', google: 'dreifach verschachteltes als') + - "⫹": [T: "Doppellinie schräg, weniger als oder gleich"] # 0x2af9 (en: 'double line slanted less than or equal to', google: 'doppelzeile, die weniger oder gleich sind') + - "⫺": [T: "Doppelte Linie schräg größer als oder gleich"] # 0x2afa (en: 'double line slanted greater than or equal to', google: 'doppelte linie schräg größer als oder gleich') + - "⫻": [T: "Dreifache Schrägstrich-Binärbeziehung"] # 0x2afb (en: 'triple solidus binary relation', google: 'triple solidus binärbeziehung') + - "⫼": [T: "Großer dreifacher vertikaler Barbediener"] # 0x2afc (en: 'large triple vertical bar operator', google: 'großer dreifacher vertikaler barbetreiber') + - "⫽": [T: "Doppelter Schrägstrich-Operator"] # 0x2afd (en: 'double solidus operator', google: 'doppeler solidus -operator') + - "⫾": [T: "Weiße vertikale Leiste"] # 0x2afe (en: 'white vertical bar', google: 'weiße vertikale balken') + - "⫿": [T: "N-Ary White Vertical Bar"] # 0x2aff (en: 'white vertical bar', google: 'weiße vertikale balken') + - "⬀": [T: "North East White Arrow"] # 0x2b00 (en: 'north east white arrow', google: 'north east white arrow') + - "⬁": [T: "Nordwestlicher weißer Pfeil"] # 0x2b01 (en: 'north west white arrow', google: 'north west white arrow') + - "⬂": [T: "Südostweißer Pfeil"] # 0x2b02 (en: 'south east white arrow', google: 'südostweißer pfeil') + - "⬃": [T: "Südwestweißer Pfeil"] # 0x2b03 (en: 'south west white arrow', google: 'south west white arrow') + - "⬄": [T: "Linker rechter weißer Pfeil"] # 0x2b04 (en: 'left right white arrow', google: 'links rechts weißer pfeil') + - "⬅": [T: "Schwarzer Pfeil nach links"] # 0x2b05 (en: 'leftwards black arrow', google: 'links schwarzer pfeil') + - "⬆": [T: "Aufwärts schwarzer Pfeil"] # 0x2b06 (en: 'upwards black arrow', google: 'aufwärts schwarze pfeil') + - "⬇": [T: "Abwärts schwarzer Pfeil"] # 0x2b07 (en: 'downwards black arrow', google: 'nach unten schwarzen pfeil') + - "⬈": [T: "Schwarzer Nordostpfeil"] # 0x2b08 (en: 'north east black arrow', google: 'nordostschwarzer pfeil') + - "⬉": [T: "Nordwestlicher schwarzer Pfeil"] # 0x2b09 (en: 'north west black arrow', google: 'nordwesten schwarzer pfeil') + - "⬊": [T: "Schwarzer Südostpfeil"] # 0x2b0a (en: 'south east black arrow', google: 'südostschwarzer pfeil') + - "⬋": [T: "Südwestlicher schwarzer Pfeil"] # 0x2b0b (en: 'south west black arrow', google: 'südwesten schwarzer pfeil') + - "⬌": [T: "Linker rechter schwarzer Pfeil"] # 0x2b0c (en: 'left right black arrow', google: 'links rechts schwarzer pfeil') + - "⬍": [T: "Schwarzer Pfeil nach unten"] # 0x2b0d (en: 'up down black arrow', google: 'runter schwarze pfeil') + - "⬎": [T: "Pfeil nach rechts mit Spitze nach unten"] # 0x2b0e (en: 'rightwards arrow with tip downwards', google: 'richtiger pfeil mit tipp nach unten') + - "⬏": [T: "Pfeil nach rechts mit Spitze nach oben"] # 0x2b0f (en: 'rightwards arrow with tip upwards', google: 'richtiger pfeil mit tipp nach oben') + - "⬐": [T: "Pfeil nach links mit Spitze nach unten"] # 0x2b10 (en: 'leftwards arrow with tip downwards', google: 'links pfeil mit tipp nach unten') + - "⬑": [T: "Pfeil nach links mit Spitze nach oben"] # 0x2b11 (en: 'leftwards arrow with tip upwards', google: 'linkspfeil mit tipp nach oben') + - "⬒": [T: "Quadrat mit oberer Hälfte schwarz"] # 0x2b12 (en: 'square with top half black', google: 'quadrat mit der oberen halbzeit') + - "⬓": [T: "Quadrat mit unterer Hälfte schwarz"] # 0x2b13 (en: 'square with bottom half black', google: 'quadrat mit unterer halb schwarz') + - "⬔": [T: "Quadrat mit oberer rechter diagonaler Hälfte schwarz"] # 0x2b14 (en: 'square with upper right diagonal half black', google: 'quadrat mit der oberen rechten diagonalen halbschwarz') + - "⬕": [T: "Quadrat mit unterer linker diagonaler Hälfte schwarz"] # 0x2b15 (en: 'square with lower left diagonal half black', google: 'quadrat mit der unteren linken diagonalen halbschwarz') + - "⬖": [T: "Diamant mit linker Hälfte schwarz"] # 0x2b16 (en: 'diamond with left half black', google: 'diamant mit linksem halb schwarz') + - "⬗": [T: "Diamant mit rechter Hälfte schwarz"] # 0x2b17 (en: 'diamond with right half black', google: 'diamant mit rechter halb schwarz') + - "⬘": [T: "Diamant mit oberer Hälfte schwarz"] # 0x2b18 (en: 'diamond with top half black', google: 'diamant mit oberem halben schwarz') + - "⬙": [T: "Diamant mit unterer Hälfte schwarz"] # 0x2b19 (en: 'diamond with bottom half black', google: 'diamant mit unterer halb schwarz') + - "⬚": [T: "Gepunktetes Quadrat"] # 0x2b1a (en: 'box', google: 'kasten') + - "⬛": [T: "Schwarzes großes Quadrat"] # 0x2b1b (en: 'black large square', google: 'schwarzes großes quadrat') + - "⬜": [T: "Weißes großes Quadrat"] # 0x2b1c (en: 'white large square', google: 'weiß großes quadrat') + - "⬝": [T: "Schwarzes sehr kleines Quadrat"] # 0x2b1d (en: 'black very small square', google: 'schwarz, sehr kleines quadrat') + - "⬞": [T: "Weißes sehr kleines Quadrat"] # 0x2b1e (en: 'white very small square', google: 'weiß sehr kleines quadrat') + - "⬟": [T: "Schwarzes Pentagon"] # 0x2b1f (en: 'black pentagon', google: 'schwarzes pentagon') + - "⬠": [T: "Weißes Pentagon"] # 0x2b20 (en: 'white pentagon', google: 'weißes pentagon') + - "⬡": [T: "Weißes Sechseck"] # 0x2b21 (en: 'white hexagon', google: 'weißes sechseck') + - "⬢": [T: "Schwarzes Sechseck"] # 0x2b22 (en: 'black hexagon', google: 'schwarzes sechseck') + - "⬣": [T: "Horizontales schwarzes Sechseck"] # 0x2b23 (en: 'horizontal black hexagon', google: 'horizontales schwarzes sechseck') + - "⬤": [T: "Schwarzer großer Kreis"] # 0x2b24 (en: 'black large circle', google: 'schwarzer großer kreis') + - "⬥": [T: "Schwarzer mittlerer Diamant"] # 0x2b25 (en: 'black medium diamond', google: 'schwarzer medium diamond') + - "⬦": [T: "Weißer mittlerer Diamant"] # 0x2b26 (en: 'white medium diamond', google: 'weißer medium diamant') + - "⬧": [T: "Schwarze mittlere Raute"] # 0x2b27 (en: 'black medium lozenge', google: 'schwarze mittelgroße rauten') + - "⬨": [T: "Weiße mittlere Raute"] # 0x2b28 (en: 'white medium lozenge', google: 'weiße mittelgroße rauten') + - "⬩": [T: "Schwarzer kleiner Diamant"] # 0x2b29 (en: 'black small diamond', google: 'schwarzer kleiner diamant') + - "⬪": [T: "Schwarze kleine Raute"] # 0x2b2a (en: 'black small lozenge', google: 'schwarze kleine rauten') + - "⬫": [T: "Weiße kleine Raute"] # 0x2b2b (en: 'white small lozenge', google: 'weiße kleine raute') + - "⬬": [T: "Schwarze horizontale Ellipse"] # 0x2b2c (en: 'black horizontal ellipse', google: 'schwarze horizontale ellipse') + - "⬭": [T: "Weiße horizontale Ellipse"] # 0x2b2d (en: 'white horizontal ellipse', google: 'weiße horizontale ellipse') + - "⬮": [T: "Schwarze vertikale Ellipse"] # 0x2b2e (en: 'black vertical ellipse', google: 'schwarze vertikale ellipse') + - "⬯": [T: "Weiße vertikale Ellipse"] # 0x2b2f (en: 'white vertical ellipse', google: 'weiße vertikale ellipse') + - "⬰": [T: "Linker Pfeil mit kleinem Kreis"] # 0x2b30 (en: 'left arrow with small circle', google: 'links pfeil mit kleinem kreis') + - "⬱": [T: "Drei nach links gerichtete Pfeile"] # 0x2b31 (en: 'three leftwards arrows', google: 'drei linke pfeile') + - "⬲": [T: "Linker Pfeil mit Circled Plus"] # 0x2b32 (en: 'left arrow with circled plus', google: 'links pfeil mit eingekreistem plus') + - "⬳": [T: "Langer nach links gerichteter Squiggle-Pfeil"] # 0x2b33 (en: 'long leftwards squiggle arrow', google: 'langer linkskundiger pfeil') + - "⬴": [T: "Pfeil nach links mit senkrechtem Strich"] # 0x2b34 (en: 'leftwards two headed arrow with vertical stroke', google: 'links zwei köpfe pfeil mit vertikalem schlaganfall') + - "⬵": [T: "Doppelpfeil nach links mit doppeltem vertikalem Strich"] # 0x2b35 (en: 'leftwards two headed arrow with double vertical stroke', google: 'links zwei köpfe pfeil mit doppelter vertikaler hub') + - "⬶": [T: "Doppelpfeil nach links von der Bar"] # 0x2b36 (en: 'leftwards two headed arrow from bar', google: 'links zwei köpfe pfeil aus der bar') + - "⬷": [T: "Pfeil nach links mit zwei Köpfen"] # 0x2b37 (en: 'leftwards two headed triple dash arrow', google: 'links zwei köpfe triple dash pfeil') + - "⬸": [T: "Pfeil nach links mit gepunktetem Stamm"] # 0x2b38 (en: 'leftwards arrow with dotted stem', google: 'links pfeil mit gepunktetem stiel') + - "⬹": [T: "Pfeil nach links mit Schwanz mit vertikalem Strich"] # 0x2b39 (en: 'leftwards arrow with tail with vertical stroke', google: 'linkspfeil mit schwanz mit vertikalem schlaganfall') + - "⬺": [T: "Pfeil nach links mit Schwanz mit doppeltem vertikalem Strich"] # 0x2b3a (en: 'leftwards arrow with tail with double vertical stroke', google: 'linkspfeil mit schwanz mit doppelter vertikaler hub') + - "⬻": [T: "Nach links gerichteter zweiköpfiger Pfeil mit Schwanz"] # 0x2b3b (en: 'leftwards two headed arrow with tail', google: 'links zwei köpfe pfeil mit schwanz') + - "⬼": [T: "Nach links gerichteter zweiköpfiger Pfeil mit Schwanz mit vertikalem Strich"] # 0x2b3c (en: 'leftwards two headed arrow with tail with vertical stroke', google: 'links zwei köpfe pfeil mit schwanz mit vertikalem schlaganfall') + - "⬽": [T: "Nach links gerichteter zweiköpfiger Pfeil mit Schwanz mit doppeltem vertikalem Strich"] # 0x2b3d (en: 'leftwards two headed arrow with tail with double vertical stroke', google: 'links zwei köpfe pfeil mit schwanz mit doppelter vertikaler hub') + - "⬾": [T: "Pfeil nach links durch X"] # 0x2b3e (en: 'leftwards arrow through x', google: 'links pfeil durch x') + - "⬿": [T: "Wellenpfeil, der direkt nach links zeigt"] # 0x2b3f (en: 'wave arrow pointing directly left', google: 'wellenpfeil direkt nach links zeigen') + - "⭀": [T: "Gleichheitszeichen über dem Pfeil nach links"] # 0x2b40 (en: 'equals sign above leftwards arrow', google: 'gleiches zeichen über dem linken pfeil') + - "⭁": [T: "Reverse-Tilde-Operator Über Linkspfeil"] # 0x2b41 (en: 'reverse tilde operator above leftwards arrow', google: 'operator umgekehrter tilde über dem linken pfeil') + - "⭂": [T: "Pfeil nach links über der Rückseite fast gleich"] # 0x2b42 (en: 'leftwards arrow above reverse almost equal to', google: 'linksspfeil über der rückseite fast gleich') + - "⭃": [T: "Pfeil nach rechts durch mehr als"] # 0x2b43 (en: 'rightwards arrow through greater than', google: 'richtiger pfeil durch größer als') + - "⭄": [T: "Pfeil nach rechts durch Superset"] # 0x2b44 (en: 'rightwards arrow through superset', google: 'richtiger pfeil durch superset') + - "⭅": [T: "Vierfachpfeil nach links"] # 0x2b45 (en: 'leftwards quadruple arrow', google: 'linksvierter pfeil') + - "⭆": [T: "Vierfachpfeil nach rechts"] # 0x2b46 (en: 'rightwards quadruple arrow', google: 'richtiger vierfachpfeil') + - "⭇": [T: "Reverse-Tilde-Operator über dem Pfeil nach rechts"] # 0x2b47 (en: 'reverse tilde operator above rightwards arrow', google: 'operator umgekehrter tilde oberhalb rechts pfeil') + - "⭈": [T: "Pfeil nach rechts oben fast gleich"] # 0x2b48 (en: 'rightwards arrow above reverse almost equal to', google: 'rightwards pfeil über der rückseite fast gleich') + - "⭉": [T: "Tilde-Operator über dem Pfeil nach links"] # 0x2b49 (en: 'tilde operator above leftwards arrow', google: 'tilde -operator über linksem pfeil') + - "⭊": [T: "Pfeil nach links oben fast gleich"] # 0x2b4a (en: 'leftwards arrow above almost equal to', google: 'links über den pfeil über fast gleich') + - "⭋": [T: "Pfeil nach links über Reverse-Tilde-Operator"] # 0x2b4b (en: 'leftwards arrow above reverse tilde operator', google: 'links -pfeil über dem operator des umgekehrten tilde') + - "⭌": [T: "Pfeil nach rechts über Reverse-Tilde-Operator"] # 0x2b4c (en: 'rightwards arrow above reverse tilde operator', google: 'rightwards pfeil über dem operator des umgekehrten tilde') + - "⭐": [T: "Weißer mittlerer Stern"] # 0x2b50 (en: 'white medium star', MathPlayer: 'white medium star', google: 'weißer mittelstern') + - "⭑": [T: "Schwarzer kleiner Stern"] # 0x2b51 (en: 'black small star', MathPlayer: 'black small star', google: 'schwarzer kleiner stern') + - "⭒": [T: "Weißer kleiner Stern"] # 0x2b52 (en: 'white small star', MathPlayer: 'white small star', google: 'weißer kleiner stern') + - "⭓": [T: "Schwarzes nach rechts zeigendes Pentagon"] # 0x2b53 (en: 'black right pointing pentagon', google: 'schwarzer rechter pentagon') + - "⭔": [T: "Weißes nach rechts zeigendes Pentagon"] # 0x2b54 (en: 'white right pointing pentagon', google: 'weißer rechts pentagon') + - "⭕": [T: "Schwerer großer Kreis"] # 0x2b55 (en: 'heavy large circle', google: 'schwerer großer kreis') + - "⭖": [T: "Schweres Oval mit innenliegendem Oval"] # 0x2b56 (en: 'heavy oval with oval inside', google: 'schweres oval mit oval im inneren') + - "⭗": [T: "Schwerer Kreis mit Kreis nach innen"] # 0x2b57 (en: 'heavy circle with circle inside', google: 'schwerer kreis mit kreis im inneren') + - "⭘": [T: "Schwerer Kreis"] # 0x2b58 (en: 'heavy circle', google: 'schwerer kreis') + - "⭙": [T: "Schwerer eingekreister Saltire"] # 0x2b59 (en: 'heavy circled saltire', google: 'schwer umgekreistes salzire') + - "⸀": [T: "rechtswinkel -substitutionsmarker"] # 0x2e00 (en: 'right angle substitution marker', google translation) + - "⸁": [T: "rechtswinkel gepunkteter substitutionsmarker"] # 0x2e01 (en: 'right angle dotted substitution marker', google translation) + - "⸂": [T: "links -substitution -halterung"] # 0x2e02 (en: 'left substitution bracket', google translation) + - "⸃": [T: "richtige substitutionshalterung"] # 0x2e03 (en: 'right substitution bracket', google translation) + - "⸄": [T: "links gepunktete substitutionshalterung"] # 0x2e04 (en: 'left dotted substitution bracket', google translation) + - "⸅": [T: "richtig gepunktete substitutionshalterung"] # 0x2e05 (en: 'right dotted substitution bracket', google translation) + - "⸆": [T: "erhöhter interpolationsmarker"] # 0x2e06 (en: 'raised interpolation marker', google translation) + - "⸇": [T: "erhöhter gepunkteter interpolationsmarker"] # 0x2e07 (en: 'raised dotted interpolation marker', google translation) + - "⸈": [T: "gepunktete transpositionsmarkermarker"] # 0x2e08 (en: 'dotted transposition marker marker', google translation) + - "⸉": [T: "linke transpositionshalterung"] # 0x2e09 (en: 'left transposition bracket', google translation) + - "⸊": [T: "rechte transpositionsklasse"] # 0x2e0a (en: 'right transposition bracket', google translation) + - "⸋": [T: "erhöhter quadrat"] # 0x2e0b (en: 'raised square', google translation) + - "⸌": [T: "links erhöhte unterlassungshalterung"] # 0x2e0c (en: 'left raised omission bracket', google translation) + - "⸍": [T: "rechte auslassungshalterung"] # 0x2e0d (en: 'right raised omission bracket', google translation) + - "⸎": [T: "redaktionelle coronis"] # 0x2e0e (en: 'editorial coronis', google translation) + - "⸏": [T: "absatz"] # 0x2e0f (en: 'paragraphos', google translation) + - "⸐": [T: "gabel absätze"] # 0x2e10 (en: 'forked paragraphos', google translation) + - "⸑": [T: "umgekehrte gabel absätze"] # 0x2e11 (en: 'reversed forked paragraphos', google translation) + - "⸒": [T: "hypodiastole"] # 0x2e12 (google translation) + - "⸓": [T: "gepunktete obelos"] # 0x2e13 (en: 'dotted obelos', google translation) + - "⸔": [T: "abwärts ancora"] # 0x2e14 (en: 'downwards ancora', google translation) + - "⸕": [T: "nach oben ancora"] # 0x2e15 (en: 'upwards ancora', google translation) + - "⸖": [T: "gepunktete rechte zeigewinkel"] # 0x2e16 (en: 'dotted right pointing angle', google translation) + - "⸗": [T: "doppelter schräger bindestrich"] # 0x2e17 (en: 'double oblique hyphen', google translation) + - "⸘": [T: "umgekehrter interrobang"] # 0x2e18 (en: 'inverted interrobang', google translation) + - "⸙": [T: "palmenzweig"] # 0x2e19 (en: 'palm branch', google translation) + - "⸚": [T: "bindestrich mit diaerese"] # 0x2e1a (en: 'hyphen with diaeresis', google translation) + - "⸛": [T: "tilde mit ring oben"] # 0x2e1b (en: 'tilde with ring above', google translation) + - "⸜": [T: "links niedrige paraphrasklasse"] # 0x2e1c (en: 'left low paraphrase bracket', google translation) + - "⸝": [T: "rechte niedrige paraphrase -klammer"] # 0x2e1d (en: 'right low paraphrase bracket', google translation) + - "⸞": [T: "tilde mit punkt oben"] # 0x2e1e (en: 'tilde with dot above', google translation) + - "⸟": [T: "tilde mit punkt unten"] # 0x2e1f (en: 'tilde with dot below', google translation) + - "⸠": [T: "links vertikale balken mit feder"] # 0x2e20 (en: 'left vertical bar with quill', google translation) + - "⸡": [T: "rechte vertikale balken mit feder"] # 0x2e21 (en: 'right vertical bar with quill', google translation) + - "⸢": [T: "Obere linke halbe Halterung"] # 0x2e22 (en: 'top left half bracket', google: 'oben links halbe halterung') + - "⸣": [T: "Obere rechte halbe Klammer"] # 0x2e23 (en: 'top right half bracket', google: 'oben rechts halbhalterung') + - "⸤": [T: "Linke halbe halterung unten"] # 0x2e24 (en: 'bottom left half bracket', google: 'unten linke halbe klammer') + - "⸥": [T: "Untere rechte halbe Halterung"] # 0x2e25 (en: 'bottom right half bracket', google: 'unten rechts halbe klammer') + - "⸦": [T: "U-Halterung links seitlich"] # 0x2e26 (en: 'left sideways u bracket', google: 'links seitwärts u klammer') + - "⸧": [T: "U-Halterung rechts seitlich"] # 0x2e27 (en: 'right sideways u bracket', google: 'rechte seitwärtshalterung') + - "⸨": [T: "Linke doppelte Klammer"] # 0x2e28 (en: 'left double parentheses', google: 'links doppelte klammern') + - "⸩": [T: "Rechte doppelte Klammer"] # 0x2e29 (en: 'right double parentheses', google: 'rechte doppelte klammern') + - "⸪": [T: "zwei punkte über eine punktzahl"] # 0x2e2a (en: 'two dots over one dot punctuation', google translation) + - "⸫": [T: "ein punkt über zwei punkte"] # 0x2e2b (en: 'one dot over two dots punctuation', google translation) + - "⸬": [T: "quadratische vier punkt -interpunktion"] # 0x2e2c (en: 'squared four dot punctuation', google translation) + - "⸭": [T: "fünf punkt mark"] # 0x2e2d (en: 'five dot mark', google translation) + - "⸮": [T: "umgekehrter fragezeichen"] # 0x2e2e (en: 'reversed question mark', google translation) + - "ⸯ": [T: "vertikale tilde"] # 0x2e2f (en: 'vertical tilde', google translation) + - "⸰": [T: "ringpunkt"] # 0x2e30 (en: 'ring point', google translation) + - "⸱": [T: "wortseparator mittlerer punkt"] # 0x2e31 (en: 'word separator middle dot', google translation) + - "⸲": [T: "drehte komma"] # 0x2e32 (en: 'turned comma', google translation) + - "⸳": [T: "erhöhter punkt"] # 0x2e33 (en: 'raised dot', google translation) + - "⸴": [T: "erhöhter komma"] # 0x2e34 (en: 'raised comma', google translation) + - "⸵": [T: "drehte semikolon"] # 0x2e35 (en: 'turned semicolon', google translation) + - "⸶": [T: "dolch mit der linken wache"] # 0x2e36 (en: 'dagger with left guard', google translation) + - "⸷": [T: "dolch mit der rechten wache"] # 0x2e37 (en: 'dagger with right guard', google translation) + - "⸸": [T: "drehte dolch"] # 0x2e38 (en: 'turned dagger', google translation) + - "⸹": [T: "abschnittszeichen der oberen halbzeit"] # 0x2e39 (en: 'top half section sign', google translation) + - "⸺": [T: "zwei em -dash"] # 0x2e3a (en: 'two em dash', google translation) + - "⸻": [T: "drei em -dash"] # 0x2e3b (en: 'three em dash', google translation) + - "〃": [T: "dito mark"] # 0x3003 (en: 'ditto mark', google translation) + - "〈": [T: "Linke Winkelklammer"] # 0x3008 (en: 'left angle bracket', google: 'linkswinkelhalter') + - "〉": [T: "Rechtwinklige Halterung"] # 0x3009 (en: 'right angle bracket', google: 'rechtswinkelhalterung') + - "《": [T: "Linke Doppelwinkelhalterung"] # 0x300a (en: 'left double angle bracket', MathPlayer: 'left double angle bracket', google: 'links zwei winkelhalterungen') + - "》": [T: "Rechte Doppelwinkelhalterung"] # 0x300b (en: 'right double angle bracket', MathPlayer: 'right double angle bracket', google: 'rechte doppelwinkelhalterung') + - "「": [T: "Linke Eckklammer"] # 0x300c (en: 'left corner bracket', google: 'linke eckhalterung') + - "」": [T: "Rechte Eckhalterung"] # 0x300d (en: 'right corner bracket', google: 'rechte eckhalterung') + - "『": [T: "Linke weiße Eckhalterung"] # 0x300e (en: 'left white corner bracket', google: 'links weiße eckhalterung') + - "』": [T: "Rechte weiße Eckhalterung"] # 0x300f (en: 'right white corner bracket', google: 'rechte weiße eckhalterung') + - "【": [T: "Linke schwarze linsenförmige Halterung"] # 0x3010 (en: 'left black lenticular bracket', google: 'links schwarze linsenhalterung') + - "】": [T: "Rechte schwarze linsenförmige Halterung"] # 0x3011 (en: 'right black lenticular bracket', google: 'rechte schwarze linsenhalterung') + - "〔": [T: "Linke Schildpatt-Klammer"] # 0x3014 (en: 'left tortoise shell bracket', MathPlayer: 'left tortoise shell bracket', google: 'links schildkrötenhalterung') + - "〕": [T: "Rechte Schildpattlasche"] # 0x3015 (en: 'right tortoise shell bracket', MathPlayer: 'right tortoise shell bracket', google: 'rechte schildkrötenhalterung') + - "〖": [T: "Linke weiße linsenförmige Halterung"] # 0x3016 (en: 'left white lenticular bracket', google: 'links weiße linsenhalterung') + - "〗": [T: "Rechte weiße linsenförmige Halterung"] # 0x3017 (en: 'right white lenticular bracket', google: 'rechte weiße linsenhalterung') + - "〘": [T: "Linke weiße Schildpatt-Klammer"] # 0x3018 (en: 'left white tortoise shell bracket', google: 'links weiße schildkröte') + - "〙": [T: "Rechte weiße Schildpatt-Klammer"] # 0x3019 (en: 'right white tortoise shell bracket', google: 'richtige weiße schildkrabbungshalterung') + - "〚": [T: "Linke weiße eckige Klammer"] # 0x301a (en: 'left white square bracket', MathPlayer: 'left white square bracket', google: 'linke weiße quadratklammer') + - "〛": [T: "Rechte weiße eckige Klammer"] # 0x301b (en: 'right white square bracket', MathPlayer: 'right white square bracket', google: 'rechte weiße quadratklasse') + - "〜": [T: "Wave Dash"] # 0x301c (en: 'wave dash', google: 'wave dash') + - "〰": [T: "zigzag"] # 0x3030 (en: 'wavy dash', google: 'welliger armaturenbrett') + - "㉈": [T: "eingekreiste Zehn auf schwarzem Quadrat"] # 0x3248 (en: 'circled number ten on black square', google: 'kreiste nummer zehn auf black square') + - "㉉": [T: "eingekreiste Zwanzig auf schwarzem Quadrat"] # 0x3249 (en: 'circled number twenty on black square', google: 'kreiste nummer zwanzig auf dem schwarzen quadrat') + - "㉊": [T: "eingekreiste Dreißig auf schwarzem Quadrat"] # 0x324a (en: 'circled number thirty on black square', google: 'kreiste nummer dreißig auf dem schwarzen platz') + - "㉋": [T: "eingekreiste Vierzig auf schwarzem Quadrat"] # 0x324b (en: 'circled number forty on blacks square', google: 'kreiste nummer vierzig auf dem blacks square') + - "㉌": [T: "eingekreiste Fünfzig auf schwarzem Quadrat"] # 0x324c (en: 'circled number fifty on black square', google: 'auf dem schwarzen platz um fünfzig umkreiste') + - "㉍": [T: "eingekreiste Sechzig auf schwarzem Quadrat"] # 0x324d (en: 'circled number sixty on black square', google: 'kreiste nummer sechzig auf black square') + - "㉎": [T: "eingekreiste Siebzig auf schwarzem Quadrat"] # 0x324e (en: 'circled number seventy on black square', google: 'kreiste nummer siebzig auf dem schwarzen quadrat') + - "㉏": [T: "eingekreiste Achtzig auf schwarzem Quadrat"] # 0x324f (en: 'circled number eighty on black square', google: 'eingekreiste nummer auf dem black square') + - "㉑": [T: "umkreiste nummer einundzwanzig"] # 0x3251 (en: 'circled number twenty one', google translation) + - "㉒": [T: "umkreiste nummer zweiundzwanzig"] # 0x3252 (en: 'circled number twenty two', google translation) + - "㉓": [T: "umgekreiste nummer dreiundzwanzig"] # 0x3253 (en: 'circled number twenty three', google translation) + - "㉔": [T: "umgekreiste nummer vierundzwanzig"] # 0x3254 (en: 'circled number twenty four', google translation) + - "㉕": [T: "umgekreiste nummer fünfundzwanzig"] # 0x3255 (en: 'circled number twenty five', google translation) + - "㉖": [T: "umgekreiste nummer 26"] # 0x3256 (en: 'circled number twenty six', google translation) + - "㉗": [T: "umgekreiste nummer siebenundzwanzig"] # 0x3257 (en: 'circled number twenty seven', google translation) + - "㉘": [T: "umkreiste nummer zwanzig bei"] # 0x3258 (en: 'circled number twenty eight', google translation) + - "㉙": [T: "umkreiste nummer neunundzwanzig"] # 0x3259 (en: 'circled number twenty nine', google translation) + - "㉚": [T: "umkreiste nummer dreißig"] # 0x325a (en: 'circled number thirty', google translation) + - "㉛": [T: "umkreiste nummer einunddreißig"] # 0x325b (en: 'circled number thirty one', google translation) + - "㉜": [T: "umkreiste nummer dreiunddreißig"] # 0x325c (en: 'circled number thirty two', google translation) + - "㉝": [T: "umkreiste nummer dreiunddreißig"] # 0x325d (en: 'circled number thirty three', google translation) + - "㉞": [T: "umkreiste nummer vierunddreißig"] # 0x325e (en: 'circled number thirty four', google translation) + - "㉟": [T: "umkreiste nummer fünfunddreißig"] # 0x325f (en: 'circled number thirty five', google translation) + - "㊱": [T: "umkreiste nummer dreiunddreißig"] # 0x32b1 (en: 'circled number thirty six', google translation) + - "㋌": [T: "quecksilber"] # 0x32cc (en: 'mercury', google translation) + - "㋍": [T: "ergs"] # 0x32cd (google translation) + - "㋎": [T: "elektronenvolt"] # 0x32ce (en: 'electron volts', google translation) + - "㋏": [T: "haftungsschild beschränkt"] # 0x32cf (en: 'limited liability sign', google translation) + - "㍱": [T: "hectopascals"] # 0x3371 (google translation) + - "㍲": [T: "daltons"] # 0x3372 (google translation) + - "㍳": [T: "astronomische einheiten"] # 0x3373 (en: 'astronomical units', google translation) + - "㍴": [T: "riegel"] # 0x3374 (en: 'bars', google translation) + - "㍵": [T: "o v"] # 0x3375 (google translation) + - "㍶": [T: "parsecs"] # 0x3376 (google translation) + - "㍷": [T: "dezimeter"] # 0x3377 (en: 'decimeters', google translation) + - "㍸": [T: "dezimeter quadratisch"] # 0x3378 (en: 'decimeters squared', google translation) + - "㍹": [T: "dezimeter gewonnen"] # 0x3379 (en: 'decimeters cubed', google translation) + - "㍺": [T: "instrumentaleinheiten"] # 0x337a (en: 'instrumental units', google translation) + - "㎀": [T: "picoamps"] # 0x3380 (google translation) + - "㎁": [T: "nanoamps"] # 0x3381 (google translation) + - "㎂": [T: "mikroamps"] # 0x3382 (en: 'microamps', google translation) + - "㎃": [T: "milliamps"] # 0x3383 (google translation) + - "㎄": [T: "kiloamps"] # 0x3384 (google translation) + - "㎅": [T: "kilobytes"] # 0x3385 (google translation) + - "㎆": [T: "megabyte"] # 0x3386 (en: 'megabytes', google translation) + - "㎇": [T: "gigabyte"] # 0x3387 (en: 'gigabytes', google translation) + - "㎈": [T: "kalorien"] # 0x3388 (en: 'calories', google translation) + - "㎉": [T: "kilokalorien"] # 0x3389 (en: 'kilocalories', google translation) + - "㎊": [T: "picofarads"] # 0x338a (google translation) + - "㎋": [T: "nanofarads"] # 0x338b (google translation) + - "㎌": [T: "mikrofaraden"] # 0x338c (en: 'microfarads', google translation) + - "㎍": [T: "mikrogramm"] # 0x338d (en: 'micrograms', google translation) + - "㎎": [T: "milligramm"] # 0x338e (en: 'milligrams', google translation) + - "㎏": [T: "kilogramm"] # 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: "terahertz"] # 0x3394 (google translation) + - "㎕": [T: "mikroliter"] # 0x3395 (en: 'microliters', google translation) + - "㎖": [T: "milliliter"] # 0x3396 (en: 'milliliters', google translation) + - "㎗": [T: "dezilierer"] # 0x3397 (en: 'deciliters', google translation) + - "㎘": [T: "kiloliter"] # 0x3398 (en: 'kiloliters', google translation) + - "㎙": [T: "femtometer"] # 0x3399 (en: 'femtometers', google translation) + - "㎚": [T: "nanometer"] # 0x339a (en: 'nanometers', google translation) + - "㎛": [T: "mikrometer"] # 0x339b (en: 'micrometers', google translation) + - "㎜": [T: "millimeter"] # 0x339c (en: 'millimeters', google translation) + - "㎝": [T: "zentimeter"] # 0x339d (en: 'centimeters', google translation) + - "㎞": [T: "kilometer"] # 0x339e (en: 'kilometers', google translation) + - "㎟": [T: "millimeter quadratisch"] # 0x339f (en: 'millimeters squared', google translation) + - "㎠": [T: "zentimeter quadratisch"] # 0x33a0 (en: 'centimeters squared', google translation) + - "㎡": [T: "quadratmeter"] # 0x33a1 (en: 'meters squared', google translation) + - "㎢": [T: "kilometer quadratisch"] # 0x33a2 (en: 'kilometers squared', google translation) + - "㎣": [T: "millimeter gewonnen"] # 0x33a3 (en: 'millimeters cubed', google translation) + - "㎤": [T: "zentimeter gewonnen"] # 0x33a4 (en: 'centimeters cubed', google translation) + - "㎥": [T: "meter gewonnen"] # 0x33a5 (en: 'meters cubed', google translation) + - "㎦": [T: "kilometer gewonnen"] # 0x33a6 (en: 'kilometers cubed', google translation) + - "㎧": [T: "meter pro sekunde"] # 0x33a7 (en: 'meters per second', google translation) + - "㎨": [T: "meter pro sekunde quadrat"] # 0x33a8 (en: 'meters per second squared', google translation) + - "㎩": [T: "pascals"] # 0x33a9 (google translation) + - "㎪": [T: "kilopascals"] # 0x33aa (google translation) + - "㎫": [T: "megapascals"] # 0x33ab (google translation) + - "㎬": [T: "gigapascals"] # 0x33ac (google translation) + - "㎭": [T: "rads"] # 0x33ad (google translation) + - "㎮": [T: "rads pro sekunde"] # 0x33ae (en: 'rads per second', google translation) + - "㎯": [T: "rads pro sekunde quadrat"] # 0x33af (en: 'rads per second squared', google translation) + - "㎰": [T: "pikosekunden"] # 0x33b0 (en: 'picoseconds', google translation) + - "㎱": [T: "nanosekunden"] # 0x33b1 (en: 'nanoseconds', google translation) + - "㎲": [T: "mikrosekunde"] # 0x33b2 (en: 'microseconds', google translation) + - "㎳": [T: "millisekunden"] # 0x33b3 (en: 'milliseconds', google translation) + - "㎴": [T: "picovolts"] # 0x33b4 (google translation) + - "㎵": [T: "nanovolts"] # 0x33b5 (google translation) + - "㎶": [T: "mikrovolte"] # 0x33b6 (en: 'microvolts', google translation) + - "㎷": [T: "millivolts"] # 0x33b7 (google translation) + - "㎸": [T: "kilovolts"] # 0x33b8 (google translation) + - "㎹": [T: "megavolts"] # 0x33b9 (google translation) + - "㎺": [T: "picowatts"] # 0x33ba (google translation) + - "㎻": [T: "nanowatts"] # 0x33bb (google translation) + - "㎼": [T: "mikrowatt"] # 0x33bc (en: 'microwatts', google translation) + - "㎽": [T: "milliwatt"] # 0x33bd (en: 'milliwatts', google translation) + - "㎾": [T: "kilowatt"] # 0x33be (en: 'kilowatts', google translation) + - "㎿": [T: "megawatt"] # 0x33bf (en: 'megawatts', google translation) + - "㏀": [T: "kilo-ohm"] # 0x33c0 (en: 'kilo-ohms', google translation) + - "㏁": [T: "megaohm"] # 0x33c1 (en: 'megaohms', google translation) + - "㏂": [T: "attometer"] # 0x33c2 (en: 'attometers', google translation) + - "㏃": [T: "becquerels"] # 0x33c3 (google translation) + - "㏄": [T: "kubikzentimeter"] # 0x33c4 (en: 'cubic centimeters', google translation) + - "㏅": [T: "candelas"] # 0x33c5 (google translation) + - "㏆": [T: "coulombs pro kilogramm"] # 0x33c6 (en: 'coulombs per kilogram', google translation) + - "㏇": [T: "herzzeitvolumen"] # 0x33c7 (en: 'cardiac output', google translation) + - "㏈": [T: "dezibel"] # 0x33c8 (en: 'decibels', google translation) + - "㏉": [T: "grautöne"] # 0x33c9 (en: 'grays', google translation) + - "㏊": [T: "hektar"] # 0x33ca (en: 'hectares', google translation) + - "㏋": [T: "pferdestärke"] # 0x33cb (en: 'horsepower', google translation) + - "㏌": [T: "zoll"] # 0x33cc (en: 'inches', google translation) + - "㏍": [T: "kilokelvins"] # 0x33cd (google translation) + - "㏎": [T: "kilometer"] # 0x33ce (en: 'kilometers', google translation) + - "㏏": [T: "knoten"] # 0x33cf (en: 'knots', google translation) + - "㏐": [T: "lumen"] # 0x33d0 (en: 'lumens', google translation) + - "㏑": [T: "natural log"] # 0x33d1 (google translation) + - "㏒": [T: "logarithmus"] # 0x33d2 (en: 'logarithm', google translation) + - "㏓": [T: "lux"] # 0x33d3 (google translation) + - "㏔": [T: "millibarns"] # 0x33d4 (google translation) + - "㏕": [T: "mühlen"] # 0x33d5 (en: 'mills', google translation) + - "㏖": [T: "maulwürfe"] # 0x33d6 (en: 'moles', google translation) + - "㏗": [T: "p h"] # 0x33d7 (google translation) + - "㏘": [T: "picometer"] # 0x33d8 (en: 'picometers', google translation) + - "㏙": [T: "teile pro million"] # 0x33d9 (en: 'parts per million', google translation) + - "㏚": [T: "petaroentgens"] # 0x33da (google translation) + - "㏛": [T: "steradier"] # 0x33db (en: 'steradians', google translation) + - "㏜": [T: "sieverts"] # 0x33dc (google translation) + - "㏝": [T: "webers"] # 0x33dd (google translation) + - "㏞": [T: "volt pro meter"] # 0x33de (en: 'volts per meter', google translation) + - "㏟": [T: "verstärker pro meter"] # 0x33df (en: 'amps per meter', google translation) + - "㏿": [T: "gallonen"] # 0x33ff (en: 'gallons', google translation) + - "": [T: "entspricht mit hut unten"] # 0xe900 (en: 'equals with hat below', google translation) + - "": [T: "entspricht plus oben"] # 0xe901 (en: 'equals with plus above', google translation) + - "": [T: "entspricht plus unten"] # 0xe902 (en: 'equals with plus below', google translation) + - "": [T: "tilde mit plus oben"] # 0xe903 (en: 'tilde with plus above', google translation) + - "": [T: "tilde mit plus unten"] # 0xe904 (en: 'tilde with plus below', google translation) + - "": [T: "gleich doppelt doppelt über größer als"] # 0xe908 (en: 'equal double over greater than', google translation) + - "": [T: "gleich doppelt über weniger als"] # 0xe909 (en: 'equal double over less than', google translation) + - "": [T: "enthält oder gleich"] # 0xe90a (en: 'contains or equal to', google translation) + - "": [T: "superset von oder gleich"] # 0xe90b (en: 'superset of or equal to', google translation) + - "": [T: "teilmenge von oder gleich"] # 0xe90c (en: 'subset of or equal to', google translation) + - "": [T: "gleich über weniger als"] # 0xe90d (en: 'equal over less than', google translation) + - "": [T: "element von oder gleich"] # 0xe912 (en: 'element of or equal to', google translation) + - "": [T: "gleich oder größer als"] # 0xe913 (en: 'equal to or greater than', google translation) + - "": [T: "ungefähre superset von"] # 0xe914 (en: 'approximate superset of', google translation) + - "": [T: "ungefähre teilmenge von"] # 0xe915 (en: 'approximate subset of', google translation) + - "": [T: "superset von with dot enthält als unterbeziehung"] # 0xe916 (en: 'superset of with dot includes as sub relation', google translation) + - "": [T: "die teilmenge von mit punkt ist in als sub -relation enthalten"] # 0xe917 (en: 'subset of with dot is included in as sub relation', google translation) + - "": [T: "gleich mit punkt unten"] # 0xe918 (en: 'equal with dot below', google translation) + - "": [T: "links punkt über minus über den rechten punkt"] # 0xe919 (en: 'left dot over minus over right dot', google translation) + - "": [T: "rechter punkt über minus über den linken punkt"] # 0xe91a (en: 'right dot over minus over left dot', google translation) + - "": [T: "fast gleich minus"] # 0xe91f (en: 'almost equal to minus', google translation) + - "": [T: "doppelter quadratbecher"] # 0xe920 (en: 'double square cup', google translation) + - "": [T: "doppelter quadrat in großbuchstaben"] # 0xe921 (en: 'double square cap', google translation) + - "": [T: "weniger als gleich oder größer als"] # 0xe922 (en: 'less than equal to or greater than', google translation) + - "": [T: "tilde mit punkt"] # 0xe924 (en: 'tilde with dot', google translation) + - "": [T: "tilde mit zwei punkten"] # 0xe925 (en: 'tilde with two dots', google translation) + - "": [T: "weniger als größer als oder gleich"] # 0xe926 (en: 'less than greater than or equal to', google translation) + - "": [T: "größer als weniger als oder gleich"] # 0xe927 (en: 'greater than less than or equal to', google translation) + - "": [T: "äquivalent zu oder weniger als"] # 0xe928 (en: 'equivalent to or less than', google translation) + - "": [T: "äquivalent zu oder größer als"] # 0xe929 (en: 'equivalent to or greater than', google translation) + - "": [T: "links geöffneter box -bediener"] # 0xe92a (en: 'left open box operator', google translation) + - "": [T: "rechts öffnen sie den box -bediener"] # 0xe92b (en: 'right open box operator', google translation) + - "": [T: "identisch mit punkt"] # 0xe92c (en: 'identical to with dot', google translation) + - "": [T: "größer als gleich oder weniger als"] # 0xe92d (en: 'greater than equal to or less than', google translation) + - "": [T: "barbetreiber"] # 0xe92e (en: 'bar operator', google translation) + - "": [T: "doppelbalkenbetreiber"] # 0xe92f (en: 'double bar operator', google translation) + - "": [T: "dreifachbetreiber"] # 0xe930 (en: 'triple bar operator', google translation) + - "": [T: "weniger als oder ungefähr gleich"] # 0xe932 (en: 'less than or approximately equal to', google translation) + - "": [T: "größer als oder ungefähr gleich"] # 0xe933 (en: 'greater than or approximately equal to', google translation) + - "": [T: "weniger als"] # 0xe936 (en: 'nested less than', google translation) + - "": [T: "verschachtelt größer als"] # 0xe937 (en: 'nested greater than', google translation) + - "": [T: "vorausgeht oder gleichwertig zu"] # 0xe93a (en: 'precedes or equivalent to', google translation) + - "": [T: "erfolg oder gleichwertig zu"] # 0xe93b (en: 'succeeds or equivalent to', google translation) + - "": [T: "geht über gleich"] # 0xe940 (en: 'precedes over equal', google translation) + - "": [T: "erfolgreich über gleich"] # 0xe941 (en: 'succeeds over equal', google translation) + - "": [T: "weniger gleicher neigung größer"] # 0xe942 (en: 'less equal slanted greater', google translation) + - "": [T: "mehr gleicher neigung weniger"] # 0xe943 (en: 'greater equal slanted less', google translation) + - "": [T: "zufrieden von"] # 0xe948 (en: 'satisfied by', google translation) + - "": [T: "faul s"] # 0xe949 (en: 'lazy s', google translation) + - "": [T: "keine behauptung"] # 0xe94a (en: 'not assertion', google translation) + - "": [T: "doppelt gleich"] # 0xe94b (en: 'double equal', google translation) + - "": [T: "dreifach gleich"] # 0xe94c (en: 'triple equal', google translation) + - "": [T: "regel verzögert"] # 0xe94d (en: 'rule delayed', google translation) + - "": [T: "alias gremiter"] # 0xe94e (en: 'alias delimiter', google translation) + - "": [T: "normale untergruppe mit bar"] # 0xe950 (en: 'normal subgroup of with bar', google translation) + - "": [T: "enthält als normale untergruppe mit balken"] # 0xe951 (en: 'contains as normal subgroup with bar', google translation) + - "": [T: "runde impliziert"] # 0xe954 (en: 'round implies', google translation) + - "": [T: "lächeln unter der bar"] # 0xe955 (en: 'smile under bar', google translation) + - "": [T: "stirnrunzeln über die bar"] # 0xe956 (en: 'frown over bar', google translation) + - "": [T: "superset von oder fast gleich"] # 0xe957 (en: 'superset of or almost equal to', google translation) + - "": [T: "teilmenge von oder fast gleich"] # 0xe958 (en: 'subset of or almost equal to', google translation) + - "": [T: "größer als fast gleich oder weniger als"] # 0xe959 (en: 'greater than almost equal to or less than', google translation) + - "": [T: "weniger als fast gleich oder größer als"] # 0xe95a (en: 'less than almost equal or greater than', google translation) + - "": [T: "doppelt logisch oder"] # 0xe95c (en: 'double logical or', google translation) + - "": [T: "doppelt logisch und"] # 0xe95d (en: 'double logical and', google translation) + - "": [T: "logisch oder mit einer doppelten balken unten"] # 0xe95e (en: 'logical or with double bar below', google translation) + - "": [T: "logisch oder mit bar unten"] # 0xe95f (en: 'logical or with bar below', google translation) + - "": [T: "fast gleich über gleich"] # 0xe962 (en: 'almost equal over equal', google translation) + - "": [T: "links zeigter dreieck mit halbierender stange"] # 0xe964 (en: 'left pointing triangle with bisecting bar', google translation) + - "": [T: "rechte dreieck mit halbierender balken"] # 0xe965 (en: 'right pointing triangle with bisecting bar', google translation) + - "": [T: "entspricht mit gepunkteten top -linien"] # 0xe966 (en: 'equals with dotted top line', google translation) + - "": [T: "geht mit dickdarm voraus"] # 0xe967 (en: 'precedes with colon', google translation) + - "": [T: "erfolg mit colon"] # 0xe968 (en: 'succeeds with colon', google translation) + - "": [T: "kleiner als oder gleich schräg"] # 0xe969 (en: 'smaller than or equal slanted', google translation) + - "": [T: "größer oder gleich schräg"] # 0xe96a (en: 'larger than or equal slanted', google translation) + - "": [T: "sehr viel weniger verschachtelt als"] # 0xe96b (en: 'nested very much less than', google translation) + - "": [T: "sehr viel größer als"] # 0xe96c (en: 'nested very much greater than', google translation) + - "": [T: "unterschied zwischen variante"] # 0xe96d (en: 'difference between variant', google translation) + - "": [T: "weniger als größer als overlay"] # 0xe96e (en: 'less than greater than overlay', google translation) + - "": [T: "logisch oder logisch und overlay"] # 0xe96f (en: 'logical or logical and overlay', google translation) + - "": [T: "superset über superset"] # 0xe970 (en: 'superset over superset', google translation) + - "": [T: "untergruppe über teilmenge"] # 0xe971 (en: 'subset over subset', google translation) + - "": [T: "superset über untergruppe"] # 0xe972 (en: 'superset over subset', google translation) + - "": [T: "untergruppe über superset"] # 0xe973 (en: 'subset over superset', google translation) + - "": [T: "dreifache vertikale bar"] # 0xe979 (en: 'triple vertical bar', google translation) + - "": [T: "gekoppelte vierfache vertikale punkte"] # 0xe97a (en: 'paired quadruple vertical dots', google translation) + - "": [T: "senkrecht über bar"] # 0xe97b (en: 'perpendicular over bar', google translation) + - "": [T: "linke drehkreuze doppelte vertikale balken"] # 0xe97c (en: 'left turnstile double vertical bar', google translation) + - "": [T: "doppelte linke drehklemme doppelte vertikale balken"] # 0xe97d (en: 'double left turnstile double vertical bar', google translation) + - "": [T: "senkrecht über invertierte senkrechte"] # 0xe97e (en: 'perpendicular over inverted perpendicular', google translation) + - "": [T: "vertikale balken mit doppelter linke"] # 0xe97f (en: 'double left turnstile vertical bar', google translation) + - "": [T: "kugelwinkel öffnen sich"] # 0xe980 (en: 'spherical angle opening up', google translation) + - "": [T: "doppelter schrägstrich"] # 0xe981 (en: 'double slash', google translation) + - "": [T: "rechtwinkel mit ecke"] # 0xe982 (en: 'right angle with corner', google translation) + - "": [T: "vertikaler balken"] # 0xe984 (en: 'circled vertical bar', google translation) + - "": [T: "umkreiste divisionszeichen"] # 0xe985 (en: 'circled division sign', google translation) + - "": [T: "gestrichelten solidus"] # 0xe986 (en: 'dashed solidus', google translation) + - "": [T: "gestürztes backslash"] # 0xe987 (en: 'dashed backslash', google translation) + - "": [T: "mitten in der mitte"] # 0xe988 (en: 'dashed mid line', google translation) + - "": [T: "gestrichelte vertikale balken"] # 0xe989 (en: 'dashed vertical bar', google translation) + - "": [T: "senkrecht mit s"] # 0xe98a (en: 'perpendicular with s', google translation) + - "": [T: "winkel mit s"] # 0xe98b (en: 'angle with s', google translation) + - "": [T: "kugelwinkelöffnung nach links"] # 0xe98c (en: 'spherical angle opening left', google translation) + - "": [T: "winkelöffnung links"] # 0xe98d (en: 'angle opening left', google translation) + - "": [T: "vertikale balken mit doppelhaken"] # 0xe98e (en: 'vertical bar with double hook', google translation) + - "": [T: "mittlerer punktbetreiber freie radikal"] # 0xe98f (en: 'medium dot operator free radical', google translation) + - "": [T: "weiß nach oben zeigte dreieck über die bar"] # 0xe990 (en: 'white up pointing triangle above bar', google translation) + - "": [T: "identisch und parallel zu"] # 0xe991 (en: 'identical and parallel to', google translation) + - "": [T: "produkt zerschlagen"] # 0xe992 (en: 'smash product', google translation) + - "": [T: "triple bar operator mit horizontaler balken"] # 0xe993 (en: 'triple bar operator with horizontal bar', google translation) + - "": [T: "identisch mit doppelter schrägstrich"] # 0xe994 (en: 'identical to with double slash', google translation) + - "": [T: "dreifach gekreuzte riegel"] # 0xe995 (en: 'triple crossed bars', google translation) + - "": [T: "vertikaler balken über den kreis"] # 0xe996 (en: 'vertical bar over circle', google translation) + - "": [T: "vertikal proportional zu"] # 0xe997 (en: 'vertical proportional to', google translation) + - "": [T: "schwarz im letzten quartal mond"] # 0xe998 (en: 'black last quarter moon', google translation) + - "": [T: "schwarzer mond im ersten quartal"] # 0xe999 (en: 'black first quarter moon', google translation) + - "": [T: "negative sinuswelle"] # 0xe9a0 (en: 'negative sine wave', google translation) + - "": [T: "klammern"] # 0xe9a1 (en: 'parenthesized dot', google translation) + - "": [T: "klammern"] # 0xe9a2 (en: 'parens', google translation) + - "": [T: "weißes lächeln"] # 0xe9a3 (en: 'white smile', google translation) + - "": [T: "weißes stirnrunzeln"] # 0xe9a4 (en: 'white frown', google translation) + - "": [T: "hexagon"] # 0xe9a5 (google translation) + - "": [T: "entspricht über plus"] # 0xe9a6 (en: 'equivalent to over plus', google translation) + - "": [T: "plus über gleichwertig zu"] # 0xe9a7 (en: 'plus over equivalent to', google translation) + - "": [T: "kreuzungserife"] # 0xe9b0 (en: 'intersection serifs', google translation) + - "": [T: "union serife"] # 0xe9b1 (en: 'union serifs', google translation) + - "": [T: "square intersection serifen"] # 0xe9b2 (en: 'square intersection serifs', google translation) + - "": [T: "square union serifen"] # 0xe9b3 (en: 'square union serifs', google translation) + - "": [T: "vor voraussichtlich dem gleichwertigen oder erfolgreich"] # 0xe9e0 (en: 'precedes equivalent to or succeeds', google translation) + - "": [T: "erfolgreich ist äquivalent zu oder geht voraus"] # 0xe9e1 (en: 'succeeds equivalent to or precedes', google translation) + - "": [T: "vor voraussichtlich fast gleich oder erfolgreich"] # 0xe9e2 (en: 'precedes almost equal to or succeeds', google translation) + - "": [T: "ist fast gleich oder voraus"] # 0xe9e3 (en: 'succeeds almost equal to or precedes', google translation) + - "": [T: "weniger als äquivalent zu oder größer als"] # 0xe9f0 (en: 'less than equivalent to or greater than', google translation) + - "": [T: "größer als äquivalent zu oder weniger als"] # 0xe9f1 (en: 'greater than equivalent to or less than', google translation) + - "": [T: "nicht viel weniger als"] # 0xea00 (en: 'not vert much less than', google translation) + - "": [T: "nicht viel größer als"] # 0xea01 (en: 'not vert much greater than', google translation) + - "": [T: "nicht viel weniger als variante"] # 0xea02 (en: 'not much less than variant', google translation) + - "": [T: "nicht viel größer als variante"] # 0xea03 (en: 'not much greater than variant', google translation) + - "": [T: "weniger vert doppelt nicht gleich"] # 0xea04 (en: 'less vert not double equals', google translation) + - "": [T: "gt vert doppelt nicht gleich"] # 0xea05 (en: 'gt vert not double equals', google translation) + - "": [T: "nicht weniger als oder gleich"] # 0xea06 (en: 'not less than or equal to', google translation) + - "": [T: "nicht größer als oder gleich"] # 0xea07 (en: 'not greater than or equal to', google translation) + - "": [T: "weder gleich noch weniger als"] # 0xea09 (en: 'neither equal to nor less than', google translation) + - "": [T: "enthält nicht oder gleich"] # 0xea0a (en: 'does not contain or equal to', google translation) + - "": [T: "weder superset von noch gleich"] # 0xea0b (en: 'neither superset of nor equal to', google translation) + - "": [T: "weder teilmenge von noch gleich"] # 0xea0c (en: 'neither subset of nor equal to', google translation) + - "": [T: "umgekehrte solidus -untergruppe"] # 0xea0d (en: 'reverse solidus subset', google translation) + - "": [T: "weder gleich noch größer als"] # 0xea0e (en: 'neither equal to nor greater than', google translation) + - "": [T: "nicht minus tilde -operator"] # 0xea0f (en: 'not minus tilde operator', google translation) + - "": [T: "weder gleich noch weniger als"] # 0xea10 (en: 'neither equal to nor less than', google translation) + - "": [T: "nicht tilde -operator"] # 0xea11 (en: 'not tilde operator', google translation) + - "": [T: "kein element von oder gleich"] # 0xea12 (en: 'not element of or equal to', google translation) + - "": [T: "weder gleich noch größer als"] # 0xea13 (en: 'neither equal to nor greater than', google translation) + - "": [T: "nicht fast gleich"] # 0xea14 (en: 'not almost equal', google translation) + - "": [T: "es ist nicht ähnlich erfolgreich"] # 0xea15 (en: 'not succeeds similar', google translation) + - "": [T: "weniger oder schräg gleich mit dem schrägstrich"] # 0xea16 (en: 'less than or slanted equal to with slash', google translation) + - "": [T: "größer als oder schräg gleich mit dem schrägstrich"] # 0xea17 (en: 'greater than or slanted equal to with slash', google translation) + - "": [T: "superset solidus"] # 0xea1a (google translation) + - "": [T: "beinhaltet nicht"] # 0xea1b (en: 'does not contain', google translation) + - "": [T: "nicht weniger als oder gleich"] # 0xea1d (en: 'not less than or equal to', google translation) + - "": [T: "nicht größer als oder gleich"] # 0xea1e (en: 'not greater than or equal to', google translation) + - "": [T: "nicht fast gleich minus"] # 0xea1f (en: 'not almost equal to minus', google translation) + - "": [T: "negated set -mitgliedschaftsdot oben"] # 0xea22 (en: 'negated set membership dot above', google translation) + - "": [T: "kein vertgle"] # 0xea2c (en: 'not vert angle', google translation) + - "": [T: "nicht parallel schräg"] # 0xea2d (en: 'not parallel slanted', google translation) + - "": [T: "kein barbetreiber"] # 0xea2e (en: 'not bar operator', google translation) + - "": [T: "nicht doppelbalkenbetreiber"] # 0xea2f (en: 'not double bar operator', google translation) + - "": [T: "nicht dreifacher barbetreiber"] # 0xea30 (en: 'not triple bar operator', google translation) + - "": [T: "weniger als aber nicht ungefähr gleich"] # 0xea32 (en: 'less than but not approximately equal to', google translation) + - "": [T: "größer als aber nicht ungefähr gleich"] # 0xea33 (en: 'greater than but not approximately equal to', google translation) + - "": [T: "weniger als oder nicht gleich"] # 0xea34 (en: 'less than or not equal to', google translation) + - "": [T: "größer als oder nicht gleich"] # 0xea35 (en: 'greater than or not equal to', google translation) + - "": [T: "nicht weniger verschachtelt als"] # 0xea36 (en: 'not nested less than', google translation) + - "": [T: "nicht mehr verschachtelt als"] # 0xea37 (en: 'not nested greater than', google translation) + - "": [T: "nicht viel weniger als"] # 0xea38 (en: 'not much less than', google translation) + - "": [T: "nicht viel größer als"] # 0xea39 (en: 'not much greater than', google translation) + - "": [T: "vor voraussichtlich, aber nicht gleichbedeutend mit"] # 0xea3a (en: 'precedes but not equivalent to', google translation) + - "": [T: "erfolg, aber nicht gleichwertig zu"] # 0xea3b (en: 'succeeds but not equivalent to', google translation) + - "": [T: "voraus, aber nicht gleich"] # 0xea3c (en: 'precedes but not equal to', google translation) + - "": [T: "erfolg, aber nicht gleich"] # 0xea3d (en: 'succeeds but not equal to', google translation) + - "": [T: "gleich oder vorausgegangen"] # 0xea3e (en: 'does not equal or precede', google translation) + - "": [T: "ist nicht gleich oder erfolgreich"] # 0xea3f (en: 'does not equal or succeed', google translation) + - "": [T: "voraus, aber nicht gleich"] # 0xea40 (en: 'precedes but not equal to', google translation) + - "": [T: "erfolg, aber nicht gleich"] # 0xea41 (en: 'succeeds but not equal to', google translation) + - "": [T: "keine untergruppe von oder gleich"] # 0xea42 (en: 'not subset of nor equal to', google translation) + - "": [T: "nicht superset von oder gleich"] # 0xea43 (en: 'not superset of nor equal to', google translation) + - "": [T: "teilmenge von oder nicht gleich"] # 0xea44 (en: 'subset of or not equal to', google translation) + - "": [T: "superset von oder nicht gleich"] # 0xea45 (en: 'superset of or not equal to', google translation) + - "": [T: "keine untergruppe von oder gleich"] # 0xea46 (en: 'not subset of nor equal to', google translation) + - "": [T: "nicht superset von oder gleich"] # 0xea47 (en: 'not superset of nor equal to', google translation) + - "": [T: "nicht dreifach weniger als"] # 0xea48 (en: 'not triple less than', google translation) + - "": [T: "nicht dreifach größer als"] # 0xea49 (en: 'not triple greater than', google translation) + - "": [T: "nicht vorausgeht"] # 0xea4c (en: 'not precedes equals', google translation) + - "": [T: "nicht erfolgreich ist gleich"] # 0xea4d (en: 'not succeeds equals', google translation) + - "": [T: "nicht normale untergruppe mit bar"] # 0xea50 (en: 'not normal subgroup of with bar', google translation) + - "": [T: "enthält nicht als normale untergruppe mit balken"] # 0xea51 (en: 'does not contain as normal subgroup with bar', google translation) + - "": [T: "kein unterschied zwischen"] # 0xea52 (en: 'not difference between', google translation) + - "": [T: "nicht geometrisch äquivalent zu"] # 0xea53 (en: 'not geometrically equivalent to', google translation) + - "": [T: "nicht vert ähnlich"] # 0xea54 (en: 'not vert similar', google translation) + - "": [T: "nicht gleich oder ähnlich"] # 0xea55 (en: 'not equal or similar', google translation) + - "": [T: "nicht verthergestellt"] # 0xea56 (en: 'not vert approximate', google translation) + - "": [T: "nicht ungefähr identisch mit"] # 0xea57 (en: 'not approximately identical to', google translation) + - "": [T: "nicht holprig gleich"] # 0xea58 (en: 'not bumpy equals', google translation) + - "": [T: "keine holprige single gleich"] # 0xea59 (en: 'not bumpy single equals', google translation) + - "": [T: "nicht gleicher punkt"] # 0xea5a (en: 'not equal dot', google translation) + - "": [T: "umgekehrt nicht äquivalent"] # 0xea5b (en: 'reverse not equivalent', google translation) + - "": [T: "nicht quadratische untergruppe"] # 0xea60 (en: 'not square subset', google translation) + - "": [T: "nicht quadratischer superset"] # 0xea61 (en: 'not square superset', google translation) + - "": [T: "nicht fast gleich über gleich"] # 0xea62 (en: 'not almost equal over equal', google translation) + - "": [T: "nicht streng gleich gleich zu"] # 0xea63 (en: 'not strictly equivalent to', google translation) + - "": [T: "nicht kongruenter punkt"] # 0xea64 (en: 'not congruent dot', google translation) + - "": [T: "rückwärts nicht gleich"] # 0xea65 (en: 'reverse not equal', google translation) + - "": [T: "nicht vert -dreieck ist gleich"] # 0xea70 (en: 'not vert left triangle equals', google translation) + - "": [T: "nicht vert rechtes dreieck ist gleich"] # 0xea71 (en: 'not vert right triangle equals', google translation) + - "": [T: "nicht teilweise"] # 0xea80 (en: 'not partial', google translation) + - "": [T: "pfeilverschmutzung extender"] # 0xeb00 (en: 'arrow embellishment extender', google translation) + - "": [T: "pfeil nach rechts über pfeil nach links"] # 0xeb01 (en: 'arrow rightwards over arrow leftwards', google translation) + - "": [T: "pfeil nach rechts über pfeil nach links"] # 0xeb02 (en: 'arrow rightwards over arrow leftwards', google translation) + - "": [T: "harpoon direkt über harpoon links"] # 0xeb03 (en: 'harpoon right over harpoon left', google translation) + - "": [T: "harpoon direkt über harpoon links"] # 0xeb04 (en: 'harpoon right over harpoon left', google translation) + - "": [T: "doppelpfeil nordöstlich südwest"] # 0xeb05 (en: 'double arrow northeast southwest', google translation) + - "": [T: "doppelpfeil nordwestlich südöstlich"] # 0xeb06 (en: 'double arrow northwest southeast', google translation) + - "": [T: "horizontaler harpoon -extender"] # 0xeb07 (en: 'horizontal harpoon extender', google translation) + - "": [T: "arc links -pfeil gegen den uhrzeigersinn"] # 0xeb08 (en: 'anticlockwise arc leftwards arrow', google translation) + - "": [T: "gegen den gegensatz zum arc rightwards pfeil"] # 0xeb09 (en: 'anticlockwise arc rightwards arrow', google translation) + - "": [T: "großer rechts pfeilakzent"] # 0xeb0b (en: 'large rightwards arrow accent', google translation) + - "": [T: "großer links pfeilakzent"] # 0xeb0c (en: 'large leftwards arrow accent', google translation) + - "": [T: "links pfeilspitze"] # 0xeb0d (en: 'leftwards arrowhead', google translation) + - "": [T: "rightwards pfeilspitze"] # 0xeb0e (en: 'rightwards arrowhead', google translation) + - "": [T: "großer links rechts pfeil mit schlaganfall"] # 0xeb0f (en: 'large left right arrow with stroke', google translation) + - "": [T: "horizontaler doppelpfeil -extender"] # 0xeb10 (en: 'horizontal double arrow extender', google translation) + - "": [T: "großer links rechts doppelpfeil mit schlaganfall"] # 0xeb11 (en: 'large left right double arrow with stroke', google translation) + - "": [T: "abwärts links nach oben auf pfeil"] # 0xeb12 (en: 'downwards arrow leftwards of upwards arrow', google translation) + - "": [T: "linkspfeil mit ecke nach unten"] # 0xeb13 (en: 'leftwards arrow with corner downwards', google translation) + - "": [T: "rightwards pfeil mit ecke nach oben"] # 0xeb14 (en: 'rightwards arrow with corner upwards', google translation) + - "": [T: "links pfeil mit ecke nach oben"] # 0xeb15 (en: 'leftwards arrow with corner upwards', google translation) + - "": [T: "gegen den top -semikkreis -pfeil gegen plus gegenüber dem gegen den gegenwart"] # 0xeb16 (en: 'anticlockwise top semicircle arrow with plus', google translation) + - "": [T: "im uhrzeigersinn oberen halbkreispfeil mit minus"] # 0xeb17 (en: 'clockwise top semicircle arrow with minus', google translation) + - "": [T: "richtiger pfeil mit schwanz mit schlaganfall"] # 0xeb18 (en: 'rightwards arrow with tail with stroke', google translation) + - "": [T: "richtige harpune unten"] # 0xeb19 (en: 'right harpoon down', google translation) + - "": [T: "ließ harpoon nieder"] # 0xeb1a (en: 'left harpoon down', google translation) + - "": [T: "linke rechte harpoon nach unten"] # 0xeb1b (en: 'left right harpoon down', google translation) + - "": [T: "linke rechte harpune hoch"] # 0xeb1c (en: 'left right harpoon up', google translation) + - "": [T: "die harpune runter links"] # 0xeb1d (en: 'up down harpoon left', google translation) + - "": [T: "runter harpoon rechts"] # 0xeb1e (en: 'up down harpoon right', google translation) + - "": [T: "auf den pfeil nach unten nach unten am pfeil"] # 0xeb1f (en: 'upwards arrow to the right of downwards arrow', google translation) + - "": [T: "links harpoon zur bar mit barb nach oben"] # 0xeb20 (en: 'leftwards harpoon to bar with barb upwards', google translation) + - "": [T: "rightwards harpoon zur bar mit barb nach oben"] # 0xeb21 (en: 'rightwards harpoon to bar with barb upwards', google translation) + - "": [T: "links harpoon zur bar mit barb nach unten"] # 0xeb22 (en: 'leftwards harpoon to bar with barb downwards', google translation) + - "": [T: "rightwards harpoon zur bar mit barb nach unten"] # 0xeb23 (en: 'rightwards harpoon to bar with barb downwards', google translation) + - "": [T: "links harpune aus der bar mit barb nach oben"] # 0xeb24 (en: 'leftwards harpoon from bar with barb upwards', google translation) + - "": [T: "richtige harpoon aus der bar mit barb nach oben"] # 0xeb25 (en: 'rightwards harpoon from bar with barb upwards', google translation) + - "": [T: "links harpoon aus der bar mit barb nach unten"] # 0xeb26 (en: 'leftwards harpoon from bar with barb downwards', google translation) + - "": [T: "rightwards harpoon aus der bar mit barb nach unten"] # 0xeb27 (en: 'rightwards harpoon from bar with barb downwards', google translation) + - "": [T: "harpune nach oben mit barb nach links"] # 0xeb28 (en: 'upwards harpoon to bar with barb leftwards', google translation) + - "": [T: "harpoon nach unten mit barb nach links"] # 0xeb29 (en: 'downwards harpoon to bar with barb leftwards', google translation) + - "": [T: "nach oben harpunieren zur bar mit barb rightwards"] # 0xeb2a (en: 'upwards harpoon to bar with barb rightwards', google translation) + - "": [T: "harpoon nach unten mit barb rightwards nach unten"] # 0xeb2b (en: 'downwards harpoon to bar with barb rightwards', google translation) + - "": [T: "harpoon von bar mit barb nach links nach oben"] # 0xeb2c (en: 'upwards harpoon from bar with barb leftwards', google translation) + - "": [T: "harpoon nach unten mit barb links nach unten"] # 0xeb2d (en: 'downwards harpoon from bar with barb leftwards', google translation) + - "": [T: "harpoon von bar mit barb rechts nach oben"] # 0xeb2e (en: 'upwards harpoon from bar with barb rightwards', google translation) + - "": [T: "harpoon nach unten aus barb mit barb rightwards"] # 0xeb2f (en: 'downwards harpoon from bar with barb rightwards', google translation) + - "": [T: "aufwärter pfeil in die bar"] # 0xeb30 (en: 'upwards arrow to bar', google translation) + - "": [T: "nach unten pfeil in die bar"] # 0xeb31 (en: 'downwards arrow to bar', google translation) + - "": [T: "harpune nach oben links von der abwärtsharpune"] # 0xeb32 (en: 'upwards harpoon to the left of downwards harpoon', google translation) + - "": [T: "harpunen nach oben rechts von der abwärtsharpune"] # 0xeb33 (en: 'upwards harpoon to the right of downwards harpoon', google translation) + - "": [T: "nach oben pfeilspitze"] # 0xeb34 (en: 'upwards arrowhead', google translation) + - "": [T: "nach unten pfeilspitze"] # 0xeb35 (en: 'downwards arrowhead', google translation) + - "": [T: "doppelte harpoon mit links nach unten nach rechts barb hoch"] # 0xeb36 (en: 'double harpoon with leftwards barb down rightwards barb up', google translation) + - "": [T: "doppelte harpoon mit links nach oben nach oben nach oben nach unten"] # 0xeb37 (en: 'double harpoon with leftwards barb up rightwards barb down', google translation) + - "": [T: "pfeil über die bar links"] # 0xeb38 (en: 'leftwards arrow over bar', google translation) + - "": [T: "richtiger pfeil über die bar"] # 0xeb39 (en: 'rightwards arrow over bar', google translation) + - "": [T: "links pfeil unter der bar"] # 0xeb3a (en: 'leftwards arrow under bar', google translation) + - "": [T: "richtiger pfeil unter der bar"] # 0xeb3b (en: 'rightwards arrow under bar', google translation) + - "": [T: "links rechts triple pfeil"] # 0xeb3c (en: 'left right triple arrow', google translation) + - "": [T: "doppelpfeil nordöstlich südost"] # 0xeb3f (en: 'double arrow northeast southeast', google translation) + - "": [T: "gegen den linken halbkreispfeil gegen den uhrzeigersinn"] # 0xeb40 (en: 'anticlockwise left semicircle arrow', google translation) + - "": [T: "linker semicircle -pfeil im uhrzeigersinn"] # 0xeb41 (en: 'clockwise left semicircle arrow', google translation) + - "": [T: "links geöffneter kreis links rechts pfeil"] # 0xeb42 (en: 'left open circle left right arrow', google translation) + - "": [T: "richtiger pfeil über tilde"] # 0xeb44 (en: 'rightwards arrow over tilde', google translation) + - "": [T: "links pfeil über tilde"] # 0xeb45 (en: 'leftwards arrow over tilde', google translation) + - "": [T: "links harpoon über der bar"] # 0xeb48 (en: 'leftwards harpoon over bar', google translation) + - "": [T: "richtige harpoon über bar"] # 0xeb49 (en: 'rightwards harpoon over bar', google translation) + - "": [T: "links harpun unter bar"] # 0xeb4a (en: 'leftwards harpoon under bar', google translation) + - "": [T: "rightwards harpoon unter bar"] # 0xeb4b (en: 'rightwards harpoon under bar', google translation) + - "": [T: "hocke schwarze pfeil nach links"] # 0xeb4c (en: 'squat black leftwards arrow', google translation) + - "": [T: "im uhrzeigersinn rechte halbkreispfeil"] # 0xeb50 (en: 'clockwise right semicircle arrow', google translation) + - "": [T: "gegen den rechten halbkreisspfeil gegen den uhrzeigersinn"] # 0xeb51 (en: 'anticlockwise right semicircle arrow', google translation) + - "": [T: "links offener kreis links rechts harpune"] # 0xeb52 (en: 'left open circle left right harpoon', google translation) + - "": [T: "aufwärtsspurte pfeil links von vertikaler balken"] # 0xeb58 (en: 'upwards arrow leftwards of vertical bar', google translation) + - "": [T: "abwärts links von vertikaler balken nach unten"] # 0xeb59 (en: 'downwards arrow leftwards of vertical bar', google translation) + - "": [T: "aufwärts nach rechts von vertikaler balken"] # 0xeb5a (en: 'upwards arrow rightwards of vertical bar', google translation) + - "": [T: "nach unten pfeil nach rechts von vertikaler balken"] # 0xeb5b (en: 'downwards arrow rightwards of vertical bar', google translation) + - "": [T: "rightwards pfeil mit erweitertem abwärtshaken"] # 0xeb5c (en: 'rightwards arrow with extended downwards hook', google translation) + - "": [T: "pfeil mit linksem pfeil mit verlängertem haken"] # 0xeb5d (en: 'leftwards arrow with extended hook', google translation) + - "": [T: "der pfeil nach links mit einem ausgedehnten abwärtshaken"] # 0xeb5e (en: 'leftwards arrow with extended downwards hook', google translation) + - "": [T: "richtiger pfeil mit verlängertem haken"] # 0xeb5f (en: 'rightwards arrow with extended hook', google translation) + - "": [T: "nicht richtig pfeil wellig"] # 0xeb60 (en: 'not right arrow wavy', google translation) + - "": [T: "nicht richtig pfeil gebogen"] # 0xeb61 (en: 'not right arrow curved', google translation) + - "": [T: "nach oben harpunieren links von vertikaler bar"] # 0xeb68 (en: 'upwards harpoon leftwards of vertical bar', google translation) + - "": [T: "abwärtsharpune links von vertikaler bar"] # 0xeb69 (en: 'downwards harpoon leftwards of vertical bar', google translation) + - "": [T: "nach oben harpoon rechts von vertikaler bar"] # 0xeb6a (en: 'upwards harpoon rightwards of vertical bar', google translation) + - "": [T: "abwärts harpoon rechts von vertikaler bar"] # 0xeb6b (en: 'downwards harpoon rightwards of vertical bar', google translation) + - "": [T: "vertikaler doppelpfeil -extender"] # 0xeb6c (en: 'vertical double arrow extender', google translation) + - "": [T: "vertikale harpune mit barb links extender"] # 0xeb6d (en: 'vertical harpoon with barb left extender', google translation) + - "": [T: "vertikale harpune mit barb right extender"] # 0xeb6e (en: 'vertical harpoon with barb right extender', google translation) + - "": [T: "rechte harpoon über die linke harpoon rechts"] # 0xeb6f (en: 'right harpoon over left harpoon right', google translation) + - "": [T: "rechte harpoon über linker harpoon links"] # 0xeb70 (en: 'right harpoon over left harpoon left', google translation) + - "": [T: "linke harpoon über die rechte harpoon rechts"] # 0xeb71 (en: 'left harpoon over right harpoon right', google translation) + - "": [T: "linke harpoon über die rechte harpoon links"] # 0xeb72 (en: 'left harpoon over right harpoon left', google translation) + - "": [T: "pfeil von links von der bar pfeilspitze"] # 0xeb73 (en: 'leftwards arrow from bar arrowhead', google translation) + - "": [T: "links nach rechts pfeil von bar extender"] # 0xeb74 (en: 'leftwards rightwards arrow from bar extender', google translation) + - "": [T: "links pfeil vom stangenschwanz"] # 0xeb75 (en: 'leftwards arrow from bar tail', google translation) + - "": [T: "richtiger pfeil vom stangenschwanz"] # 0xeb76 (en: 'rightwards arrow from bar tail', google translation) + - "": [T: "rightwards pfeil von der bar pfeilspitze"] # 0xeb77 (en: 'rightwards arrow from bar arrowhead', google translation) + - "": [T: "harpune nach oben aus der bar mit barb links pfeilspitze"] # 0xeb78 (en: 'upwards harpoon from bar with barb leftwards arrowhead', google translation) + - "": [T: "rechten pfeil über den linken pfeil nach rechts"] # 0xeb79 (en: 'rightwards arrow over leftwards arrow right', google translation) + - "": [T: "rechten pfeil über den linken pfeil nach links"] # 0xeb7a (en: 'rightwards arrow over leftwards arrow left', google translation) + - "": [T: "der pfeil nach links nach rechts nach rechts"] # 0xeb7b (en: 'leftwards arrow over rightwards arrow right', google translation) + - "": [T: "der pfeil nach links über den pfeil nach rechts links"] # 0xeb7c (en: 'leftwards arrow over rightwards arrow left', google translation) + - "": [T: "aufwärter pfeil von der bar pfeilspitze"] # 0xeb7d (en: 'upwards arrow from bar arrowhead', google translation) + - "": [T: "aufwärter pfeil vom stangenschwanz"] # 0xeb7e (en: 'upwards arrow from bar tail', google translation) + - "": [T: "nach unten pfeil vom stangenschwanz"] # 0xeb7f (en: 'downwards arrow from bar tail', google translation) + - "": [T: "nach unten pfeil von pfeilspitzen nach unten"] # 0xeb80 (en: 'downwards arrow from bar arrowhead', google translation) + - "": [T: "harpoon nach unten aus der bar mit barb rightwards arrowhead"] # 0xeb81 (en: 'downwards harpoon from bar with barb rightwards arrowhead', google translation) + - "": [T: "harpunen nach oben links von harpunenboden nach unten"] # 0xeb82 (en: 'upwards harpoon to the left of downwards harpoon bottom', google translation) + - "": [T: "harpunen nach oben links von der abwärtsharpoon extender"] # 0xeb83 (en: 'upwards harpoon to the left of downwards harpoon extender', google translation) + - "": [T: "harpoon nach unten links von der harpunenoberseite nach oben"] # 0xeb84 (en: 'downwards harpoon to the left of upwards harpoon top', google translation) + - "": [T: "harpunen nach oben links von der abwärtsharpoon -oberseite"] # 0xeb85 (en: 'upwards harpoon to the left of downwards harpoon top', google translation) + - "": [T: "harpunen nach unten links von der nach oben nach oben genannten harpoon -extender"] # 0xeb86 (en: 'downwards harpoon to the left of the upwards harpoon extender', google translation) + - "": [T: "harpunen nach unten links von der nach oben nach oben genannten harpunenboden"] # 0xeb87 (en: 'downwards harpoon to the left of the upwards harpoon bottom', google translation) + - "": [T: "aufwärts nach links nach unten pfeilboden"] # 0xeb88 (en: 'upwards arrow leftwards of downwards arrow bottom', google translation) + - "": [T: "nach unten pfeil nach oben von pfeiltop nach oben"] # 0xeb89 (en: 'downwards arrow leftwards of upwards arrow top', google translation) + - "": [T: "aufwärts links nach unten pfeiltop"] # 0xeb8a (en: 'upwards arrow leftwards of downwards arrow top', google translation) + - "": [T: "abwärts nach links nach oben am pfeil nach oben"] # 0xeb8b (en: 'downwards arrow leftwards of upwards arrow bottom', google translation) + - "": [T: "links nach rechts pfeile extender"] # 0xeb8c (en: 'leftwards rightwards arrows extender', google translation) + - "": [T: "north east arrow extender"] # 0xeb8d (google translation) + - "": [T: "north west arrow extender"] # 0xeb8e (google translation) + - "": [T: "daunen zeigen, links"] # 0xec00 (en: 'down pointing brace left', google translation) + - "": [T: "daunen zeigen mitte"] # 0xec01 (en: 'down pointing brace mid', google translation) + - "": [T: "runter zeigen klammer richtig"] # 0xec02 (en: 'down pointing brace right', google translation) + - "": [T: "horizontaler klammer -extender"] # 0xec03 (en: 'horizontal brace extender', google translation) + - "": [T: "nach dem zeigen links"] # 0xec04 (en: 'up pointing brace left', google translation) + - "": [T: "mitte zeigende klammer"] # 0xec05 (en: 'up pointing brace mid', google translation) + - "": [T: "ups-taste-klammer rechts"] # 0xec06 (en: 'up-pointing brace right', google translation) + - "": [T: "links vertikale balken"] # 0xec07 (en: 'left vertical bar', google translation) + - "": [T: "rechte vertikale balken"] # 0xec08 (en: 'right vertical bar', google translation) + - "": [T: "links doppelte vertikale balken"] # 0xec09 (en: 'left double vertical bar', google translation) + - "": [T: "rechte doppelte vertikale balken"] # 0xec0a (en: 'right double vertical bar', google translation) + - "": [T: "horizontaler bracket extender"] # 0xec0b (en: 'horizontal bracket extender', google translation) + - "": [T: "unter quadratischer klammer"] # 0xec0c (en: 'under square bracket', google translation) + - "⎵": [T: "Untere eckige Klammer"] # 0x23b5 (en: 'under square bracket', MathPlayer: 'under square bracket', google: 'unter quadratischer klammer') + - "": [T: "über quadratischer klammer"] # 0xec0d (en: 'over square bracket', google translation) + - "⎴": [T: "Obere eckige Klammer"] # 0x23b4 (en: 'over square bracket', MathPlayer: 'over square bracket', google: 'über quadratischer klammer') + - "": [T: "unter der klammer links"] # 0xec0e (en: 'under bracket left', google translation) + - "": [T: "unter der klammer rechts"] # 0xec0f (en: 'under bracket right', google translation) + - "": [T: "über die klammer ging"] # 0xec10 (en: 'over bracket left', google translation) + - "": [T: "über die klammer richtig"] # 0xec11 (en: 'over bracket right', google translation) + - "": [T: "links klammern 1"] # 0xec12 (en: 'left parens 1', google translation) + - "": [T: "links klammern 2"] # 0xec13 (en: 'left parens 2', google translation) + - "": [T: "links klammern 3"] # 0xec14 (en: 'left parens 3', google translation) + - "": [T: "links klammern 4"] # 0xec15 (en: 'left parens 4', google translation) + - "": [T: "rechte klammer 1"] # 0xec16 (en: 'right parens 1', google translation) + - "": [T: "rechte klammer 2"] # 0xec17 (en: 'right parens 2', google translation) + - "": [T: "rechte klammer 3"] # 0xec18 (en: 'right parens 3', google translation) + - "": [T: "rechte klammer 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: "radikaler boden"] # 0xec1f (en: 'radical bottom', google translation) + - "": [T: "radikaler vertikaler erweiterung"] # 0xec20 (en: 'radical vertical extender', google translation) + - "": [T: "radikaler oberteil"] # 0xec21 (en: 'radical top', google translation) + - "": [T: "links weiße halterung"] # 0xec22 (en: 'left white bracket top', google translation) + - "": [T: "links weiße klammer extender"] # 0xec23 (en: 'left white bracket extender', google translation) + - "": [T: "links weiße halterung"] # 0xec24 (en: 'left white bracket bottom', google translation) + - "": [T: "rechte weiße halterung"] # 0xec25 (en: 'right white bracket top', google translation) + - "": [T: "rechte weiße klammer extender"] # 0xec26 (en: 'right white bracket extender', google translation) + - "": [T: "rechte weiße halterung unten"] # 0xec27 (en: 'right white bracket bottom', google translation) + - "": [T: "links weiße lockige klammer"] # 0xec30 (en: 'left white curly bracket', google translation) + - "": [T: "rechte weiße lockige klammer"] # 0xec31 (en: 'right white curly bracket', google translation) + - "": [T: "langes divisionszeichen"] # 0xec32 (en: 'long division sign', google translation) + - "": [T: "langes divisionszeichen extender"] # 0xec33 (en: 'long division sign extender', google translation) + - "": [T: "kurze division"] # 0xec34 (en: 'short division', google translation) + - "": [T: "doppelte südwest nach nordost -em bond"] # 0xec40 (en: 'double southwest to northeast em bond', google translation) + - "": [T: "doppelte nordwestlich nach südost -em bond"] # 0xec41 (en: 'double northwest to southeast em bond', google translation) + - "": [T: "einzelne horizontale em -bindung"] # 0xec42 (en: 'single horizontal em bond', google translation) + - "": [T: "doppelte horizontale em -bindung"] # 0xec43 (en: 'double horizontal em bond', google translation) + - "": [T: "dreifache horizontale em -bond"] # 0xec44 (en: 'triple horizontal em bond', google translation) + - "": [T: "single vertikale em -bindung"] # 0xec45 (en: 'single vertical em bond', google translation) + - "": [T: "doppelte vertikale em -bindung"] # 0xec46 (en: 'double vertical em bond', google translation) + - "": [T: "dreifache vertikale em -bond"] # 0xec47 (en: 'triple vertical em bond', google translation) + - "": [T: "weniger als em bond"] # 0xec48 (en: 'less than em bond', google translation) + - "": [T: "größer als die em -bindung"] # 0xec49 (en: 'greater than em bond', google translation) + - "": [T: "einzelne horizontale bond"] # 0xec4a (en: 'single horizontal en bond', google translation) + - "": [T: "doppelte horizontale bond"] # 0xec4b (en: 'double horizontal en bond', google translation) + - "": [T: "dreifache horizontaler bond"] # 0xec4c (en: 'triple horizontal en bond', google translation) + - "": [T: "oben links rechteck"] # 0xec80 (en: 'top left rectangle', google translation) + - "": [T: "unten links rechteck"] # 0xec81 (en: 'bottom left rectangle', google translation) + - "": [T: "oben rechts rechteck"] # 0xec90 (en: 'top right rectangle', google translation) + - "": [T: "unten rechts rechteck"] # 0xec91 (en: 'bottom right rectangle', google translation) + - "": [T: "synthetische division ecke"] # 0xec92 (en: 'synthetic division corner', google translation) + - "": [T: "horizontale erweiterung der synthetischen teilung"] # 0xec93 (en: 'synthetic division horizontal extender', google translation) + - "": [T: "vertikale extender der synthetischen spaltung"] # 0xec94 (en: 'synthetic division vertical extender', google translation) + - "": [T: "verlängerung des linken deckenbodens"] # 0xec95 (en: 'left ceiling floor extender', google translation) + - "": [T: "rechte deckenboden erweiterung"] # 0xec96 (en: 'right ceiling floor extender', google translation) + - "": [T: "über klammer extender"] # 0xec97 (en: 'over bracket extender', google translation) + - "": [T: "vertikaler balken -erweiterung"] # 0xec98 (en: 'vertical bar extender', google translation) + - "": [T: "links doppelter vertikaler balken -extender"] # 0xec99 (en: 'left double vertical bar extender', google translation) + - "": [T: "horizontaler balken -erweiterung"] # 0xec9a (en: 'horizontal bar extender', google translation) + - "": [T: "unter der klammer extender"] # 0xec9c (en: 'under bracket extender', google translation) + - "": [T: "runter zeigen klammern nach rechts"] # 0xec9d (en: 'down pointing paren right', google translation) + - "": [T: "down -zeigen von klammern extender"] # 0xec9e (en: 'down pointing paren extender', google translation) + - "": [T: "down -zeigen von klammern übrig"] # 0xec9f (en: 'down pointing paren left', google translation) + - "": [T: "überzüge klammer -extender"] # 0xeca0 (en: 'up pointing brace extender', google translation) + - "": [T: "übergreifende klammern übrig"] # 0xeca1 (en: 'up pointing paren left', google translation) + - "": [T: "übergezeigte klammern"] # 0xeca2 (en: 'up pointing paren extender', google translation) + - "": [T: "übereinstimmung mit klammern richtig"] # 0xeca3 (en: 'up pointing paren right', google translation) + - "": [T: "down spointing acker extender"] # 0xeca4 (en: 'down pointing brace extender', google translation) + - "": [T: "planck konstant über zwei pi -bar"] # 0xed00 (en: 'planck constant over two pi bar', google translation) + - "": [T: "spiegel g"] # 0xed01 (en: 'mirror g', google translation) + - "": [T: "dotless j"] # 0xed02 (google translation) + - "": [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 + +# The private use chars are from MathType + - "": [T: "integralschleife gegen den gegensatz zu contour -kontur"] # 0xee00 (en: 'anticlockwise contour integral loop', google translation) + - "": [T: "contour integral loop im uhrzeigersinn"] # 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: "gemeinsame statusverzerrung"] # 0xee0d (en: 'joint status embellishment', google translation) + - "": [T: "gemeinsame statusverzerrung übrig"] # 0xee0e (en: 'joint status embellishment left', google translation) + - "": [T: "gemeinsame statusverzerrung recht"] # 0xee0f (en: 'joint status embellishment right', google translation) + - "": [T: "gemeinsamer statusverzerrungserweiterung"] # 0xee10 (en: 'joint status embellishment extender', google translation) + - "": [T: "integralschleife"] # 0xee11 (en: 'integral loop', google translation) + - "": [T: "integral loop double"] # 0xee12 (google translation) + - "": [T: "integral loop triple"] # 0xee13 (google translation) + - "": [T: "erweiterung integraler schleife doppel"] # 0xee15 (en: 'expanding integral loop double', google translation) + - "": [T: "erweiterung integraler schleife triple"] # 0xee16 (en: 'expanding integral loop triple', google translation) + - "": [T: "asymptotisch gleich dem akzent"] # 0xee17 (en: 'asymptotically equal to accent', google translation) + - "": [T: "gleicher zeichenakzent"] # 0xee18 (en: 'equal sign accent', google translation) + - "": [T: "vierfache prime"] # 0xee19 (en: 'quadruple prime', google translation) + - "": [T: "balkenakzent mit offenem kreis links"] # 0xee1a (en: 'bar accent with open circle left', google translation) + - "": [T: "barakzent mit geschlossenem kreis links"] # 0xee1b (en: 'bar accent with closed circle left', google translation) + - "": [T: "barakzent mit offenem kreis rechts"] # 0xee1c (en: 'bar accent with open circle right', google translation) + - "": [T: "barakzent mit over dot"] # 0xee1d (en: 'bar accent with over dot', google translation) + - "": [T: "barakzent mit under dot"] # 0xee1e (en: 'bar accent with under dot', google translation) + - "": [T: "barakzent mit double over dot"] # 0xee1f (en: 'bar accent with double over dot', google translation) + - "": [T: "barakzent mit double under dot"] # 0xee20 (en: 'bar accent with double under dot', google translation) + - "": [T: "barakzent mit pflege"] # 0xee21 (en: 'bar accent with caret', google translation) + - "": [T: "dick unter dem stabakzent"] # 0xee22 (en: 'thick under bar accent', google translation) + - "": [T: "barakzent mit geschlossenem kreis rechts"] # 0xee23 (en: 'bar accent with closed circle right', google translation) + - "": [T: "großer punkt oben"] # 0xee24 (en: 'large dot above', google translation) + - "": [T: "ausrichtung mark"] # 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: "fehlender begriff"] # 0xef41 (en: 'missing term', google translation) + - "": [T: "contour -integralpfeil im uhrzeigersinn links"] # 0xef80 (en: 'clockwise contour integral arrow on left', google translation) + - "": [T: "integral mit quadratisch"] # 0xef81 (en: 'integral with square', google translation) + - "": [T: "integral mit schrägstrich"] # 0xef82 (en: 'integral with slash', google translation) + - "": [T: "umgekehrter integral"] # 0xef83 (en: 'reversed integral', google translation) + - "": [T: "double null über double null"] # 0xef90 (en: 'double zero over double zero', google translation) + - "": [T: "null mit schrägstrich"] # 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 mutig" # (en: 'fraktur bold', google translation) + - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf040 - 0xf059 + - T: "fraktur mutig" # (en: 'fraktur bold', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝖆-𝖟": # 0x1d586 - 0x1d59f + - T: "fraktur mutig" # (en: 'fraktur bold', google translation) + - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf05a - 0xf073 + - T: "fraktur mutig" # (en: '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: "doppelt geschlagen"] # (en: 'double struck', google translation) + - spell: "translate('.', '𝔸𝔹𝔺𝔻𝔼𝔽𝔾𝔿𝕀𝕁𝕂𝕃𝕄𝕅𝕆𝕇𝕈𝕉𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf080 - 0xf098 + - test: + if: "$Verbosity!='Terse'" + then: [T: "doppelt geschlagen"] # (en: 'double struck', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝕒-𝕫": # 0x1d552 - 0x1d56b + - test: + if: "$Verbosity!='Terse'" + then: [T: "doppelt geschlagen"] # (en: 'double struck', google translation) + - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf09a - 0xf0b3 + - test: + if: "$Verbosity!='Terse'" + then: [T: "doppelt geschlagen"] # (en: 'double struck', google translation) + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 + - test: + if: "$Verbosity!='Terse'" + then: [T: "doppelt geschlagen"] # (en: 'double struck', google translation) + - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" + - "-": # 0xf0c0 - 0xf0c9 + - test: + if: "$Verbosity!='Terse'" + then: [T: "doppelt geschlagen"] # (en: 'double struck', google translation) + - spell: "translate('.', '', '0123456789')" + + - "": [T: "doppelt geschlagen nabla"] # 0xf0ca (en: 'double struck nabla', google translation) + - "": [T: "doppelt geschlagene euler konstant"] # 0xf0cb (en: 'double struck euler constant', google translation) + + # script chars in math alphabetic block and also MathType private use area + - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 + - T: "skript" # (en: 'script', google translation) + - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf100 - 0xf119 + - T: "skript" # (en: 'script', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf + - T: "skript" # (en: 'script', google translation) + - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf11a - 0xf133 + - T: "skript" # (en: 'script', google translation) + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + # bold script chars in math alphabetic block and also MathType private use area + - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 + - T: "skript mutig" # (en: 'script bold', google translation) + - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf140 - 0xf159 + - T: "skript mutig" # (en: 'script bold', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝓪-𝔃": # 0x1d4ea - 0x1d503 + - T: "skript mutig" # (en: 'script bold', google translation) + - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf15a - 0xf173 + - T: "skript mutig" # (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: "großbuchstaben"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "ligatur 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: "großbuchstaben"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "scharfes 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: "großbuchstaben"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "o mit schlaganfall"] # (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: "doppelt geschlagen"] # (en: 'double struck', google translation) + - spell: "translate('.', '', 'ΔΨΛΠΣΘΓΩΥ')" + + - "-": # 0xf220 - 0xf236 + - test: + if: "$Verbosity!='Terse'" + then: [T: "doppelt geschlagen"] # (en: 'double struck', google translation) + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "": [T: "doppelt geschlagenes final sigma"] # 0xf237 (en: 'double struck final sigma', google translation) + - "": [T: "doppelte rho geschlagen"] # 0xf250 (en: 'double struck rho', google translation) + - "": [T: "doppelt geschlagen phi"] # 0xf251 (en: 'double struck phi', google translation) + - "𝐀-𝐙": # 0x1d400 - 0x1d419 + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf260 - 0xf279 + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝐚-𝐳": # 0x1d41a - 0x1d433 + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf27a - 0xf293 + - T: "deutlich" # (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: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf2c8 - 0xf2e1 + # - T: "bold italic" + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝒂-𝒛": # 0x1d482 - 0x1d49b + # - T: "bold italic" + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf2e2 - 0xf2fb + # - T: "bold italic" + - T: "deutlich" # (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: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf334 - 0xf34d + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝗮-𝘇": # 0x1d5ee - 0x1d607 + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf34e - 0xf367 + - T: "deutlich" # (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: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf39c - 0xf3b5 + # - T: "bold italic" + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝙖-𝙯": # 0x1d656 - 0x1d66f + # - T: "bold italic" + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf3b6 - 0xf3cf + # - T: "bold italic" + - T: "deutlich" # (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: "dotless i"] # 0xf404 (google translation) + - "𝚤": [T: "punktloses i kursiv"] # 0x1d6a4 (en: 'dotless i', google: 'dotless i') + - "𝚥": [T: "punktloses j kursiv"] # 0x1d6a5 (en: 'dotless j', google: 'dotless j') + + - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 + - T: "punktloses j kursiv" # (en: 'bold', google: 'deutlich') + - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf408 - 0xf420 + - T: "punktloses j kursiv" # (en: 'bold', google: 'deutlich') + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da + - T: "punktloses j kursiv" # (en: 'bold', google: 'deutlich') + - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf422 - 0xf43a + - T: "punktloses j kursiv" # (en: 'bold', google: 'deutlich') + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "": [T: "mutiger nabla"] # 0xf421 (en: 'bold nabla', google translation) + - "𝛁": [T: "mutiger nabla"] # 0x1d6c1 (en: 'bold nabla', google translation) + + - "𝛛𝛜𝛝𝛞𝛟𝛠𝛡": # 0x1D6DB - 0x1D6E1 + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" + + - "": # 0xF43C - 0xF441 + - T: "deutlich" # (en: 'bold', google translation) + - 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: "kursiv nabla"] # 0xf45b (en: 'italic nabla', google translation) + - "𝛻": [T: "kursiv nabla"] # 0x1d6fb (en: 'italic nabla', google translation) + + - "𝜕𝜖𝜗𝜘𝜙𝜚𝜛": # 0x1d715 - 0x1d71b + # - T: "italic" + - spell: "translate('.', '𝜕𝜖𝜗𝜘𝜙𝜚𝜛', '∂εθκφρπ')" + + - "": # 0xf475 - 0xf47b + # - T: "italic" + - spell: "translate('.', '', '∂εθκφρπ')" + + - "𝜜-𝜴": # 0x1d71c - 0x1d734 + # - T: "bold italic" + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf47c - 0xf494 + # - T: "bold italic" + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝜶-𝝎": # 0x1d736 - 0x1d74e + # - T: "bold italic" + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf496 - 0xf4ae + # - T: "bold italic" + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": # 0x1d74f - 0x1d755 + # - T: "bold italic" + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εθκφρπ')" + + - "": # 0xf422 - 0xf43a + # - T: "bold italic" + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '', '∂εθκφρπ')" + + - "𝜵": [T: "mutiges kursives nabla"] # 0x1d735 (en: 'bold italic nabla', google translation) + - "": [T: "mutiges kursives nabla"] # 0xf495 (en: 'bold italic nabla', google translation) + + - "𝝖-𝝮": # 0x1d756 - 0x1d76e + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "-": # 0xf4b6 - 0xf4ce + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝝰-𝞈": # 0x1d770 - 0x1d788 + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇𝞈', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf4d0 - 0xf4e8 + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝞉𝞊𝞋𝞌𝞍𝞎𝞏": # 0x1d789 - 0x1d78f + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '𝞉𝞊𝞋𝞌𝞍𝞎𝞏', '∂εθκφρπ')" + + - "": # 0xf4e9 - 0xf4ef + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '', '∂εθκφρπ')" + + - "": [T: "mutiger nabla"] # 0xf4cf (en: 'bold nabla', google translation) + - "𝝯": [T: "mutiger nabla"] # 0x1d76f (en: 'bold nabla', google translation) + + - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 + # - T: "bold italic" + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf4f0 - 0xf508 + # - T: "bold italic" + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝞪-𝟂": # 0x1d7aa - 0x1d7c2 + # - T: "bold italic" + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf50a - 0xf522 + # - T: "bold italic" + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": # 0x1d7c3 - 0x1d7c9 + # - T: "bold italic" + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '𝟃𝟄𝟅𝟆𝟇𝟈𝟉', '∂εθκφρπ')" + + - "": # 0xf523 - 0xf529 + # - T: "bold italic" + - T: "deutlich" # (en: 'bold', google translation) + - spell: "translate('.', '', '∂εθκφρπ')" + + - "": [T: "mutiger nabla"] # 0xf509 (en: 'bold nabla', google translation) + - "𝞩": [T: "mutiger nabla"] # 0x1d7a9 (en: 'bold nabla', google translation) + + - "": [T: "bold null"] # 0xf52e (en: 'bold zero', google translation) + - "𝟎": [T: "bold null"] # 0x1d7ce (en: 'bold zero', google translation) + - "": [T: "mutig"] # 0xf52f (en: 'bold one', google translation) + - "𝟏": [T: "mutig"] # 0x1d7cf (en: 'bold one', google translation) + - "": [T: "fett zwei"] # 0xf530 (en: 'bold two', google translation) + - "𝟐": [T: "fett zwei"] # 0x1d7d0 (en: 'bold two', google translation) + - "": [T: "fett drei"] # 0xf531 (en: 'bold three', google translation) + - "𝟑": [T: "fett drei"] # 0x1d7d1 (en: 'bold three', google translation) + - "": [T: "fett vier"] # 0xf532 (en: 'bold four', google translation) + - "𝟒": [T: "fett vier"] # 0x1d7d2 (en: 'bold four', google translation) + - "": [T: "fett fünf"] # 0xf533 (en: 'bold five', google translation) + - "𝟓": [T: "fett fünf"] # 0x1d7d3 (en: 'bold five', google translation) + - "": [T: "mutige sechs"] # 0xf534 (en: 'bold six', google translation) + - "𝟔": [T: "mutige sechs"] # 0x1d7d4 (en: 'bold six', google translation) + - "": [T: "fett sieben"] # 0xf535 (en: 'bold seven', google translation) + - "𝟕": [T: "fett sieben"] # 0x1d7d5 (en: 'bold seven', google translation) + - "": [T: "mutig bei"] # 0xf536 (en: 'bold eight', google translation) + - "𝟖": [T: "mutig bei"] # 0x1d7d6 (en: 'bold eight', google translation) + - "": [T: "fett neun"] # 0xf537 (en: 'bold nine', google translation) + - "𝟗": [T: "fett neun"] # 0x1d7d7 (en: 'bold nine', google translation) + - "": [T: "null"] # 0xf542 (en: 'zero', google translation) + - "𝟢": [T: "null"] # 0x1d7e2 (en: 'zero', google translation) + - "": [T: "eins"] # 0xf543 (en: 'one', google translation) + - "𝟣": [T: "eins"] # 0x1d7e3 (en: 'one', google translation) + - "": [T: "zwei"] # 0xf544 (en: 'two', google translation) + - "𝟤": [T: "zwei"] # 0x1d7e4 (en: 'two', google translation) + - "": [T: "drei"] # 0xf545 (en: 'three', google translation) + - "𝟥": [T: "drei"] # 0x1d7e5 (en: 'three', google translation) + - "": [T: "vier"] # 0xf546 (en: 'four', google translation) + - "𝟦": [T: "vier"] # 0x1d7e6 (en: 'four', google translation) + - "": [T: "fünf"] # 0xf547 (en: 'five', google translation) + - "𝟧": [T: "fünf"] # 0x1d7e7 (en: 'five', google translation) + - "": [T: "sechs"] # 0xf548 (en: 'six', google translation) + - "𝟨": [T: "sechs"] # 0x1d7e8 (en: 'six', google translation) + - "": [T: "sieben"] # 0xf549 (en: 'seven', google translation) + - "𝟩": [T: "sieben"] # 0x1d7e9 (en: 'seven', google translation) + - "": [T: "bei"] # 0xf54a (en: 'eight', google translation) + - "𝟪": [T: "bei"] # 0x1d7ea (en: 'eight', google translation) + - "": [T: "neun"] # 0xf54b (en: 'nine', google translation) + - "𝟫": [T: "neun"] # 0x1d7eb (en: 'nine', google translation) + - "": [T: "bold null"] # 0xf54c (en: 'bold zero', google translation) + - "𝟬": [T: "bold null"] # 0x1d7ec (en: 'bold zero', google translation) + - "": [T: "mutig"] # 0xf54d (en: 'bold one', google translation) + - "𝟭": [T: "mutig"] # 0x1d7ed (en: 'bold one', google translation) + - "": [T: "fett zwei"] # 0xf54e (en: 'bold two', google translation) + - "𝟮": [T: "fett zwei"] # 0x1d7ee (en: 'bold two', google translation) + - "": [T: "fett drei"] # 0xf54f (en: 'bold three', google translation) + - "𝟯": [T: "fett drei"] # 0x1d7ef (en: 'bold three', google translation) + - "": [T: "fett vier"] # 0xf550 (en: 'bold four', google translation) + - "𝟰": [T: "fett vier"] # 0x1d7f0 (en: 'bold four', google translation) + - "": [T: "fett fünf"] # 0xf551 (en: 'bold five', google translation) + - "𝟱": [T: "fett fünf"] # 0x1d7f1 (en: 'bold five', google translation) + - "": [T: "mutige sechs"] # 0xf552 (en: 'bold six', google translation) + - "𝟲": [T: "mutige sechs"] # 0x1d7f2 (en: 'bold six', google translation) + - "": [T: "fett sieben"] # 0xf553 (en: 'bold seven', google translation) + - "𝟳": [T: "fett sieben"] # 0x1d7f3 (en: 'bold seven', google translation) + - "": [T: "mutig bei"] # 0xf554 (en: 'bold eight', google translation) + - "𝟴": [T: "mutig bei"] # 0x1d7f4 (en: 'bold eight', google translation) + - "": [T: "fett neun"] # 0xf555 (en: 'bold nine', google translation) + - "𝟵": [T: "fett neun"] # 0x1d7f5 (en: 'bold nine', google translation) + - "": [T: "null"] # 0xf556 (en: 'zero', google translation) + - "𝟶": [T: "null"] # 0x1d7f6 (en: 'zero', google translation) + - "": [T: "eins"] # 0xf557 (en: 'one', google translation) + - "𝟷": [T: "eins"] # 0x1d7f7 (en: 'one', google translation) + - "": [T: "zwei"] # 0xf558 (en: 'two', google translation) + - "𝟸": [T: "zwei"] # 0x1d7f8 (en: 'two', google translation) + - "": [T: "drei"] # 0xf559 (en: 'three', google translation) + - "𝟹": [T: "drei"] # 0x1d7f9 (en: 'three', google translation) + - "": [T: "vier"] # 0xf55a (en: 'four', google translation) + - "𝟺": [T: "vier"] # 0x1d7fa (en: 'four', google translation) + - "": [T: "fünf"] # 0xf55b (en: 'five', google translation) + - "𝟻": [T: "fünf"] # 0x1d7fb (en: 'five', google translation) + - "": [T: "sechs"] # 0xf55c (en: 'six', google translation) + - "𝟼": [T: "sechs"] # 0x1d7fc (en: 'six', google translation) + - "": [T: "sieben"] # 0xf55d (en: 'seven', google translation) + - "𝟽": [T: "sieben"] # 0x1d7fd (en: 'seven', google translation) + - "": [T: "bei"] # 0xf55e (en: 'eight', google translation) + - "𝟾": [T: "bei"] # 0x1d7fe (en: 'eight', google translation) + - "": [T: "neun"] # 0xf55f (en: 'nine', google translation) + - "𝟿": [T: "neun"] # 0x1d7ff (en: 'nine', google translation) + - "": [T: "unbekannter charakter"] # 0xf700 (en: 'unknown character', google translation) + - "": [T: "unter rechts und untere linke dreiecke"] # 0xf726 (en: 'lower right and lower left triangles', google translation) + - "": [T: "horizontaler ellipsis extender"] # 0xf72d (en: 'horizontal ellipsis extender', google translation) + - "": [T: "mittellinienhorizontale ellipsis extender"] # 0xf72e (en: 'midline horizontal ellipsis extender', google translation) + - "": [T: "radikaler erweiterung"] # 0xf8e5 (en: 'radical extender', google translation) + - "": [T: "vertikaler pfeiler extender"] # 0xf8e6 (en: 'vertical arrow extender', google translation) + - "": [T: "horizontaler pfeil extender"] # 0xf8e7 (en: 'horizontal arrow extender', google translation) + - "": [T: "registriertes zeichen sans serif"] # 0xf8e8 (en: 'registered sign sans serif', google translation) + - "": [T: "copyright zeichen sans serif"] # 0xf8e9 (en: 'copyright sign sans serif', google translation) + - "": [T: "markzeichen zeichen ohne serife"] # 0xf8ea (en: 'trade mark sign sans serif', google translation) + - "": [T: "links -klammern"] # 0xf8eb (en: 'left paren top', google translation) + - "": [T: "links -klammern extender"] # 0xf8ec (en: 'left paren extender', google translation) + - "": [T: "linke klammern"] # 0xf8ed (en: 'left paren bottom', google translation) + - "": [T: "linker halterung"] # 0xf8ee (en: 'left bracket top', google translation) + - "": [T: "linke klammer extender"] # 0xf8ef (en: 'left bracket extender', google translation) + - "": [T: "linke halterung unten"] # 0xf8f0 (en: 'left bracket bottom', google translation) + - "": [T: "links leichte oberseite"] # 0xf8f1 (en: 'left brace top', google translation) + - "": [T: "linksklammer mitten"] # 0xf8f2 (en: 'left brace mid', google translation) + - "": [T: "linker blace boden"] # 0xf8f3 (en: 'left brace bottom', google translation) + - "": [T: "absprace externen"] # 0xf8f4 (en: 'brace extender', google translation) + - "": [T: "integraler extender"] # 0xf8f5 (en: 'integral extender', google translation) + - "": [T: "rechte klammern"] # 0xf8f6 (en: 'right paren top', google translation) + - "": [T: "rechte klammer extender"] # 0xf8f7 (en: 'right paren extender', google translation) + - "": [T: "rechte klammer unten"] # 0xf8f8 (en: 'right paren bottom', google translation) + - "": [T: "rechte halterung"] # 0xf8f9 (en: 'right bracket top', google translation) + - "": [T: "rechte klammer extender"] # 0xf8fa (en: 'right bracket extender', google translation) + - "": [T: "rechte halterung unten"] # 0xf8fb (en: 'right bracket bottom', google translation) + - "": [T: "rechte klammerobertop"] # 0xf8fc (en: 'right brace top', google translation) + - "": [T: "richtige klammer in der mitte"] # 0xf8fd (en: 'right brace mid', google translation) + - "": [T: "rechtshalle unten"] # 0xf8fe (en: 'right brace bottom', google translation) + - "": [T: "apple logo"] # 0xf8ff (google translation) + - "ff": [T: "ligature ff"] # 0xfb00 (en: 'ff', google: 'ff') + - "fi": [T: "ligature fi"] # 0xfb01 (en: 'fi', google: 'fi') + - "fl": [T: "ligature fl"] # 0xfb02 (en: 'fl', google: 'fl') + - "ffi": [T: "ligature ffi"] # 0xfb03 (en: 'ffi', google: 'ffi') + - "ffl": [T: "ligature ffl"] # 0xfb04 (en: 'ffl', google: 'ffl') + - "ſt": [T: "ft"] # 0xfb05 (google translation) + - "st": [T: "st"] # 0xfb06 (google translation) + - "︠": [T: "die ligatur verließ die halbe verzierung"] # 0xfe20 (en: 'ligature left half embellishment', google translation) + - "︡": [T: "ligature rechte halbe verzierung"] # 0xfe21 (en: 'ligature right half embellishment', google translation) + - "︢": [T: "doppelte tilde verließ die halbe verzierung"] # 0xfe22 (en: 'double tilde left half embellishment', google translation) + - "︣": [T: "doppelte tilde rechte halbe verzierung"] # 0xfe23 (en: 'double tilde right half embellishment', google translation) + - "︤": [T: "macron verließ die halbe verzierung"] # 0xfe24 (en: 'macron left half embellishment', google translation) + - "︥": [T: "macron rechte halbe verzierung"] # 0xfe25 (en: 'macron right half embellishment', google translation) + - "︦": [T: "konjazieren von macron -verzierung"] # 0xfe26 (en: 'conjoining macron embellishment', google translation) + - "︵": [T: "Präsentationsformular für vertikale linke Klammer"] # 0xfe35 (en: 'over paren', MathPlayer: 'over paren', google: 'über klammern') + - "︶": [T: "Präsentationsformular für vertikale rechte Klammer"] # 0xfe36 (en: 'under paren', MathPlayer: 'under paren', google: 'unter klammern') + - "︷": [T: "Präsentationsformular für vertikale linke geschweifte Klammer"] # 0xfe37 (en: 'over brace', MathPlayer: 'over curly bracket', google: 'über klammer') + - "︸": [T: "Präsentationsformular für vertikale, recht geschweifte Klammer"] # 0xfe38 (en: 'under brace', MathPlayer: 'under curly bracket', google: 'unter klammer') + - "︿": [T: "Präsentationsformular für vertikale linke Winkelhalterung"] # 0xfe3f (en: 'over angle bracket', MathPlayer: 'over angle bracket', google: 'über winkelhalterung') + - "﹀": [T: "Präsentationsformular für vertikale rechtwinklige Halterung"] # 0xfe40 (en: 'under angle bracket', MathPlayer: 'under angle bracket', google: 'unter winkelklasse') + - "﹨": [T: "kleiner umgekehrter Schrägstrich"] # 0xfe68 (en: 'integer divide', MathPlayer: 'integer divide', google: 'ganzzahl teilt') + - "": [T: "unbekanntes oder fehlendes objekt"] # 0xfffc (en: 'unknown or missing object', google translation) + - "�": [T: "unknown or missing character"] # 0xfffd (google: 'unbekannter oder fehlender charakter') diff --git a/Rules/Languages/de/unicode.yaml b/Rules/Languages/de/unicode.yaml new file mode 100644 index 00000000..fa1edf93 --- /dev/null +++ b/Rules/Languages/de/unicode.yaml @@ -0,0 +1,497 @@ +--- + # 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: "backslash"] # 0x22 (en: 'quotation mark') #backslash?? + - "#": [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: "lamda"] # 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') + + - "–": [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') + - "…": # 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 + + - "⁡": # 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') + - "′": [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') + + - "ℂℕℚℝℤ": # 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') + - "℉": [T: "grad fahrenheit"] # 0x2109 (google: 'grad fahrenheit') + - "ℋℛℓ": # 0x210b #klären + - T: "schreibschrift" # (en: 'script', google: 'skript') + - spell: "translate('.', 'ℋℛℓ', 'HRl')" + - "ℎ": [T: "planck-konstante"] # 0x210e (en: 'planck constant', MathPlayer: 'planck constant', google: 'planck konstant') + - "ℜ": # 0x211c + - T: "frakturschrift groß r" # (en: 'fraktur', google: 'fraktur') + - spell: "'R'" + + - "Ω": [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') + - "ⅆⅇⅈⅉ": # 0x2146-9 + - T: "doppelstrich kursiv" # (en: 'double-struck italic', MathPlayer: 'angstroms', google: 'doppelt übertroffene kursivschrift') + - spell: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" + + - "←": [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') + - "→": # 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') + + - "↓": [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: "für alle"] # 0x2200 (en: 'for all') + - "∂": # 0x2202 + - test: + if: "$Verbosity='Terse'" + then: [T: "teilweise"] # (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: ""] # (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"] # (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: "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"] # (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: "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: "minus"] # 0x2212 + - "∓": [T: "minus plus"] # 0x2213 (en: 'minus or plus') + - "∗": [T: "mal"] # 0x2217 (en: 'times', MathPlayer: 'asterisk operator', google: 'mal') + - "∘": [T: "verknüpft mit"] # 0x2218 (en: 'composed with') + - "√": # 0x221a +<<<<<<< HEAD + - test: + if: "$Verbosity!='Terse'" + then: [T: "die"] # (en: 'the', google translation) +======= +>>>>>>> 2a2157c1f21e828e4d827022e1e0fc5490837efe + - T: "quadratwurzel" # (en: 'square root of', MathPlayer: 'radical', google: 'quadratwurzel von') + - "∝": # 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: "teilt"] # 0x2223 (en: 'divides') + - "∤": [T: "teilt nicht"] # 0x2224 (en: 'does not divide') + - "∥": # 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') + - "∧": [T: "und"] # 0x2227 (en: 'and') + - "∨": [T: "oder"] # 0x2228 (en: 'or') + - "∩": [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') + - "∶": # 0x2236 + - test: + if: "$Verbosity!='Terse'" + then: [T: "ist"] # (en: 'is', google translation) #unklar + - T: "zu" # (en: 'to') + - "∷": [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') + - "∾": # 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') + - "≠": # 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') + - "≤": # 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') + - "≦": [T: "kleiner als über gleich"] # 0x2266 (en: 'less than over equal to', MathPlayer: 'less than over equal to', google: 'weniger als überweg') + - "≧": [T: "größer als über gleich"] # 0x2267 (en: 'greater than over equal to', MathPlayer: 'greater than over equal to', google: 'größer als überweg') + - "≺": [T: "vorangehend"] # 0x227a (en: 'precedes', MathPlayer: 'precedes', google: 'voraus') + - "≻": [T: "nachfolgend"] # 0x227b (en: 'succeeds', MathPlayer: 'succeeds', google: 'gelingt es') + - "⊂": # 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 ein"] # (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 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') diff --git a/tests/Languages/de.rs b/tests/Languages/de.rs new file mode 100644 index 00000000..45bce3f9 --- /dev/null +++ b/tests/Languages/de.rs @@ -0,0 +1,34 @@ +#![allow(non_snake_case)] + +mod ClearSpeak { + mod functions; + mod large_ops; + mod menclose; + mod mfrac; + mod mroot; + mod msup; + mod sets; + mod symbols_and_adornments; + mod multiline; +} + +mod SimpleSpeak { + mod functions; + mod large_ops; + // mod menclose; + mod mfrac; + // mod mroot; + mod msup; + mod sets; + mod geometry; + mod linear_algebra; + mod multiline; + mod subscripts; +} +mod shared; +mod units; +mod chemistry; +mod alphabets; +mod intent; +mod mtable; + diff --git a/tests/Languages/de/ClearSpeak/functions.rs b/tests/Languages/de/ClearSpeak/functions.rs new file mode 100644 index 00000000..134fb3f8 --- /dev/null +++ b/tests/Languages/de/ClearSpeak/functions.rs @@ -0,0 +1,471 @@ +/// Tests for: +/// * functions including trig functions, logs, and functions to powers +/// * implied times/functional call and explicit times/function call +/// * parens +/// These are all intertwined, so they are in one file +use crate::common::*; + +#[test] +fn trig_names() { + let expr = " + sinx+ + cosy+ + tanz+ + secα+ + cscϕ+ + cotφ + "; + test("de", "ClearSpeak", expr, "sinus von x, plus kosinus von y, plus tangens von z, plus sekans von alpha, plus kosekans von phi, plus kotangens von phi"); +} + +#[test] +fn hyperbolic_trig_names() { + let expr = " + sinhx+ + coshy+ + tanhz+ + sechα+ + cschϕ+ + cothφ + "; + test("de", "ClearSpeak", expr, "hyperbolischer sinus von x, plus hyperbolischer cosinus von y, plus hyperbolischer tangens von z, plus, hyperbolischer sekans von alpha, plus, hyperbolischer kosekans, von phi; plus, hyperbolischer kotangens, von phi"); +} + + +#[test] +fn inverse_trig() { + let expr = "sin-1x"; + test("de", "ClearSpeak", expr, "umgekehrte sinus von x"); +} + +#[test] +fn inverse_trig_trig_inverse() { + let expr = "tan-1x"; + test_ClearSpeak("de", "ClearSpeak_Trig", "TrigInverse",expr, + "tangens umgekehrte von x"); +} + +#[test] +fn inverse_trig_arc() { + let expr = "cosh-1x"; + test_ClearSpeak("de", "ClearSpeak_Trig", "ArcTrig",expr, + "ark hyperbolischer cosinus, von x"); +} + +#[test] +fn trig_squared() { + let expr = "sin2x"; + test("de", "ClearSpeak", expr, "sinus quadrat von x"); +} + +#[test] +fn trig_cubed() { + let expr = "tan3x"; + test("de", "ClearSpeak", expr, "tangens hoch 3 von x"); +} + + +/* +#[test] +fn trig_fourth() { + let expr = "sec4x"; + test("de", "ClearSpeak", expr, "the fourth power of, secant of x"); +} + + +#[test] +fn trig_power_other() { + let expr = "sinh>n-1x"; + test("de", "ClearSpeak", expr, "the n minus 1 power of, hyperbolic sine of x"); +} + */ +#[test] +fn simple_log() { + let expr = " logx "; + test("de", "ClearSpeak", expr, "log x"); +} + +#[test] +fn normal_log() { + let expr = "log(x+y)"; + test("de", "ClearSpeak", expr, "der log von, klammer auf x plus y, klammer zu"); +} + +#[test] +fn simple_log_with_base() { + let expr = " logbx "; + test("de", "ClearSpeak", expr, "der logarithmus basis b; von x"); +} + +#[test] +fn normal_log_with_base() { + let expr = "logb(x+y)"; + test("de", "ClearSpeak", expr, "der logarithmus basis b; von, klammer auf x plus y, klammer zu"); +} + +#[test] +fn simple_ln() { + let expr = " lnx "; + test("de", "ClearSpeak", expr, "l n x"); +} + +#[test] +fn normal_ln() { + let expr = "ln(x+y)"; + test("de", "ClearSpeak", expr, "der l n von, klammer auf x plus y, klammer zu"); +} + + +#[test] +fn simple_natural_log() { + let expr = " lnx "; + test_ClearSpeak("de", "ClearSpeak_Log", "LnAsNaturalLog",expr, + "Natürliche Logarithmus x"); +} + + +#[test] +fn natural_log() { + let expr = "ln(x+y)"; + test_ClearSpeak("de", "ClearSpeak_Log", "LnAsNaturalLog",expr, + "der Natürliche Logarithmus von, klammer auf x plus y, klammer zu"); +} + + +#[test] +fn explicit_function_call_with_parens() { + let expr = "t(x)"; + test("de", "ClearSpeak", expr, "t von x"); +} + + +#[test] +fn explicit_times_with_parens() { + let expr = "t(x)"; + test("de", "ClearSpeak", expr, "t mal x"); +} + +#[test] +fn explicit_function_call() { + let expr = "tx"; + test("de", "ClearSpeak", expr, "t von x"); +} + +#[test] +fn explicit_times() { + let expr = "tx"; + test("de", "ClearSpeak", expr, "t x"); +} + + +#[test] +fn test_functions_none_pref() { + let expr = " + log(x+y) + + + f(x+y) + "; + // TODO: this should not succeed! + test_ClearSpeak("de", "ClearSpeak_Functions", "None",expr, + "der log von, klammer auf x plus y, klammer zu; plus, f mal, klammer auf x plus y, klammer zu"); +} + +#[test] +fn test_functions_none_pref_multiple_args() { + let expr = " + B ( 2,6 ) + "; + test_ClearSpeak("de", "ClearSpeak_Functions", "None",expr, + "groß b mal, klammer auf 2 komma 6, klammer zu"); +} + + +/* + * Tests for times + */ +#[test] +fn no_times_binomial() { + let expr = "x y"; + test("de", "ClearSpeak", expr, "x y"); +} + +#[test] +fn times_following_paren() { + let expr = " + 2 + ( 3 ) + "; + test("de", "ClearSpeak", expr, "2 mal 3"); +} + +#[test] +fn times_preceding_paren() { + let expr = " + ( 2 ) + 3 + "; + test("de", "ClearSpeak", expr, "2 mal 3"); +} + + +/* + +#[test] +fn times_sqrt() { + let expr = " + a + b + = + ab + "; + test("de", "ClearSpeak", expr, "the square root of eigh; times the square root of b; is equal to, the square root of eigh b"); +} + +#[test] +fn more_implied_times() { + let expr = " + + + + ( + 2x + ) + 2 + + + "; + test_ClearSpeak("de", "ClearSpeak_ImpliedTimes", "MoreImpliedTimes",expr, + "open paren 2 times x, close paren squared"); +} + +#[test] +fn explicit_times_more_implied_times() { + let expr = "tx"; + test_ClearSpeak("de", "ClearSpeak_ImpliedTimes", "MoreImpliedTimes",expr, "t times x"); +} + +#[test] +fn explicit_times_none_simple_right() { + let expr = "2[3 ]"; + test_ClearSpeak("de", "ClearSpeak_ImpliedTimes", "None", + expr, "2, open bracket 3 close bracket"); +} + +#[test] +fn explicit_times_none_simple_left() { + let expr = "(21)x"; + test_ClearSpeak("de", "ClearSpeak_ImpliedTimes", "None", + expr, "open paren 2 minus 1, close paren; x"); +} + +#[test] +fn explicit_times_none_superscript() { + let expr = " + f(x)= +x +2 + +( + +x+1 +) + "; + test_ClearSpeak_prefs("en", + vec![("ClearSpeak_ImpliedTimes", "None"), ("ClearSpeak_Functions", "None")], + expr, "f open paren x close paren; is equal to; x squared, open paren x plus 1, close paren"); +} + +/* + * Tests for parens + */ + #[test] + fn no_parens_number() { + let expr = " + ( + 25 + ) + x + "; + test("de", "ClearSpeak", expr, "25 times x"); + } + + #[test] + fn no_parens_monomial() { + let expr = " + b + ( + xy + ) + "; + test("de", "ClearSpeak", expr, "b, open paren x y close paren"); + } + + #[test] + fn no_parens_negative_number() { + let expr = " + 2+ + ( + 2 + ) + "; + test("de", "ClearSpeak", expr, "2 plus negative 2"); + } + + + #[test] + fn no_parens_negative_number_with_var() { + let expr = " + ( + 2x + ) + + +1 + "; + test("de", "ClearSpeak", expr, "negative 2 x, plus 1"); + } + + #[test] + fn parens_superscript() { + let expr = " + + + + ( + 2x + ) + 2 + + + "; + test("de", "ClearSpeak", expr, "open paren 2 x close paren squared"); + } + + #[test] + fn no_parens_fraction() { + let expr = " + 2 + + + + ( + 12 + ) + "; + test("de", "ClearSpeak", expr, "2 plus 1 half"); + } + + + // Tests for the ten types of intervals in ClearSpeak + #[test] + fn parens_interval_open_open() { + let expr = " + ( + c,d + ) + "; + test_ClearSpeak("de", "ClearSpeak_Paren", "Interval",expr, + "the interval from c to d, not including c or d"); +} + +#[test] + fn parens_interval_closed_open() { + let expr = " + [ + c,d + ) + "; + test_ClearSpeak("de", "ClearSpeak_Paren", "Interval ",expr, + "the interval from c to d, including c but not including d"); +} + + +#[test] +fn parens_interval_open_closed() { + let expr = " + ( + c,d + ] + "; + test_ClearSpeak("de", "ClearSpeak_Paren", "Interval ",expr, + "the interval from c to d, not including c but including d"); +} + + +#[test] +fn parens_interval_closed_closed() { + let expr = " + [ + c,d + ] +"; +test_ClearSpeak("de", "ClearSpeak_Paren", "Interval ",expr, +"the interval from c to d, including c and d"); +} + + #[test] + fn parens_interval_neg_infinity_open_open() { + let expr = " + ( + - ,d + ) + "; + test_ClearSpeak("de", "ClearSpeak_Paren", "Interval ",expr, + "the interval from negative infinity to d, not including d"); +} + + #[test] + fn parens_interval_neg_infinity_closed_open() { + let expr = " + ( + - ,d + ] + "; + test_ClearSpeak("de", "ClearSpeak_Paren", "Interval ",expr, + "the interval from negative infinity to d, including d"); +} + + +#[test] +fn parens_interval_open_open_infinity() { + let expr = " + ( + c, + ) + "; + test_ClearSpeak("de", "ClearSpeak_Paren", "Interval ",expr, + "the interval from c to infinity, not including c"); +} + + +#[test] +fn parens_interval_closed_open_infinity() { + let expr = " + [ + c, + ) + "; + test_ClearSpeak("de", "ClearSpeak_Paren", "Interval ",expr, +"the interval from c to infinity, including c"); +} + +#[test] +fn parens_interval_neg_infinity_to_infinity() { + let expr = " + ( + - , + ) + "; + test_ClearSpeak("de", "ClearSpeak_Paren", "Interval ",expr, + "the interval from negative infinity to infinity"); +} + +#[test] +fn parens_interval_neg_infinity_to_pos_infinity() { + let expr = " + ( + - ,+ + ) + "; + test_ClearSpeak("de", "ClearSpeak_Paren", "Interval ",expr, + "the interval from negative infinity to positive infinity"); +} +*/ \ No newline at end of file diff --git a/tests/Languages/de/ClearSpeak/large_ops.rs b/tests/Languages/de/ClearSpeak/large_ops.rs new file mode 100644 index 00000000..7b52fc2c --- /dev/null +++ b/tests/Languages/de/ClearSpeak/large_ops.rs @@ -0,0 +1,200 @@ +use crate::common::*; + +#[test] +fn sum_both() { + let expr = " + + + n=1 + 10 + + n + "; + test("de", "ClearSpeak", expr, "die summe von n ist gleich 1 bis 10 von n"); +} + +#[test] +fn sum_under() { + let expr = " + + + S + + i + "; + test("de", "ClearSpeak", expr, "die summe durch groß s von i"); +} +#[test] +fn sum_both_msubsup() { + let expr = " + + + n=1 + 10 + + n + "; + test("de", "ClearSpeak", expr, "die summe von n ist gleich 1 bis 10 von n"); +} + +#[test] +fn sum_sub() { + let expr = " + + + S + + i + "; + test("de", "ClearSpeak", expr, "die summe durch groß s von i"); +} + +#[test] +fn sum() { + let expr = " + + ai + "; + test("de", "ClearSpeak", expr, "die summe von a sub i"); +} + +#[test] +fn product_both() { + let expr = " + + + n=1 + 10 + + n + "; + test("de", "ClearSpeak", expr, "die produkt von n ist gleich 1 bis 10 von n"); +} + +#[test] +fn product_under() { + let expr = " + + + S + + i + "; + test("de", "ClearSpeak", expr, "die produkt durch groß s von i"); +} + +#[test] +fn product() { + let expr = " + + ai + "; + test("de", "ClearSpeak", expr, "die produkt von a sub i"); +} + +#[test] +fn intersection_both() { + let expr = " + + + i=1 + 10 + + Si + "; + test("de", "ClearSpeak", expr, "die N-stufiger Durchschnitt von i ist gleich 1 bis 10 von; groß s sub i"); +} + +#[test] +fn intersection_under() { + let expr = " + + + C + + Si + "; + test("de", "ClearSpeak", expr, "die N-stufiger Durchschnitt durch groß c von; groß s sub i"); +} + +#[test] +fn intersection() { + let expr = " + + Si + "; + test("de", "ClearSpeak", expr, "die N-stufiger Durchschnitt von groß s sub i"); +} + +#[test] +fn union_both() { + let expr = " + + + i=1 + 10 + + Si + "; + test("de", "ClearSpeak", expr, "die N-stufige Vereinigung von i ist gleich 1 bis 10 von; groß s sub i"); +} + +#[test] +fn union_under() { + let expr = " + + + C + + Si + "; + test("de", "ClearSpeak", expr, "die N-stufige Vereinigung durch groß c von; groß s sub i"); +} + +#[test] +fn union() { + let expr = " + + Si + "; + test("de", "ClearSpeak", expr, "die N-stufige Vereinigung von groß s sub i"); +} + +#[test] +fn integral_both() { + let expr = " + + + + 0 + 1 + + f(x ) + + dx + "; + test("de", "ClearSpeak", expr, "die integral von 0 bis 1 von, f von x; d x"); +} + +#[test] +fn integral_under() { + let expr = " + + + + + f(x ) + dx + "; + test("de", "ClearSpeak", expr, "die integral durch die reelen zahlen von; f von x d x"); +} + +#[test] +fn integral() { + let expr = " + + f(x ) + dx + "; + test("de", "ClearSpeak", expr, "die integral von f von x d x"); +} \ No newline at end of file diff --git a/tests/Languages/de/ClearSpeak/menclose.rs b/tests/Languages/de/ClearSpeak/menclose.rs new file mode 100644 index 00000000..38a92b8b --- /dev/null +++ b/tests/Languages/de/ClearSpeak/menclose.rs @@ -0,0 +1,197 @@ +use crate::common::*; + +#[test] +fn menclose_actuarial() { + let expr = " + 3+2i + "; + test("de", "ClearSpeak", expr, "versicherungsmathematische symbol, einschließen 3 plus 2 i ende der einschliessung"); +} + +#[test] +fn menclose_box() { + let expr = " + 3+2i + "; + test("de", "ClearSpeak", expr, "box, kreis, einschließen 3 plus 2 i ende der einschliessung"); +} + +#[test] +fn menclose_left() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "linie links, einschließen 3 hälften ende der einschliessung"); +} + +#[test] +fn menclose_right() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "linie rechts, einschließen 3 hälften ende der einschliessung"); +} + +#[test] +fn menclose_top_bottom() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "linie oben, unten, einschließen 3 hälften ende der einschliessung"); +} + +#[test] +fn menclose_updiagonalstrike() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "diagonal nach oben, durchstreichen, einschließen 3 hälften ende der einschliessung"); +} + +#[test] +fn menclose_downdiagonalstrike() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "diagonal nach unten, durchstreichen, einschließen 3 hälften ende der einschliessung"); +} + +#[test] +fn menclose_cross_out() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "x, durchstreichen, einschließen 3 hälften ende der einschliessung"); +} + +#[test] +fn menclose_vertical_horizontal_strike() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "vertikal, horizontal, durchstreichen, einschließen 3 hälften ende der einschliessung"); +} + +#[test] +fn menclose_leftarrow() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "pfeil nach links, einschließen 3 hälften ende der einschliessung"); +} + +#[test] +fn menclose_right_up_down_arrow() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "pfeil nach oben, pfeil nach unten, pfeil nach rechts, einschließen 3 hälften ende der einschliessung"); +} + +#[test] +fn menclose_northeastarrow() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "pfeil nach nordost, einschließen 3 hälften ende der einschliessung"); +} + +#[test] +fn menclose_other_single_arrows() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "pfeil nach südost, pfeil nach südwest, pfeil nach nordwest, einschließen 3 hälften ende der einschliessung"); +} + +#[test] +fn menclose_northwestsoutheastarrow() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "doppelpfeil diagonal nach unten, einschließen 3 hälften ende der einschliessung"); +} + +#[test] +fn menclose_other_double_arrows() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "doppelpfeil nach oben und unten, doppelpfeil nach links und rechts, doppelpfeil diagonal nach oben, einschließen 3 hälften ende der einschliessung"); +} + +#[test] +fn menclose_madrub() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "arabisches faktor-symbol, einschließen 3 hälften ende der einschliessung"); +} + +#[test] +fn menclose_phasorangle() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "phasenwinkel, einschließen 3 hälften ende der einschliessung"); +} + +#[test] +fn menclose_circle_phasorangle() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "kreis, phasenwinkel, einschließen 3 hälften ende der einschliessung"); +} + +#[test] +fn menclose_longdiv() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "symbol für schriftliche division, einschließen 3 hälften ende der einschliessung"); +} + +/* +#[test] +fn menclose_longdiv_default() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "symbol für schriftliche division, einschließen 3 hälften ende der einschliessung"); +} + + +#[test] +fn menclose_longdiv_empty_string() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "long division symbol, enclosing 3 halves end enclosure"); +} + +#[test] +fn menclose_longdiv_whitespace_string() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "long division symbol, enclosing 3 halves end enclosure"); +} + + */ + +#[test] +fn menclose_radical() { + let expr = " + 32 + "; + test("de", "ClearSpeak", expr, "quadratwurzel, einschließen 3 hälften ende der einschliessung"); +} + +#[test] +fn simple_speak_menclose_top_bottom() { + let expr = " + 32 + "; + test("de", "SimpleSpeak", expr, "linie oben, unten, einschließen 3 hälften ende der einschliessung"); +} diff --git a/tests/Languages/de/ClearSpeak/mfrac.rs b/tests/Languages/de/ClearSpeak/mfrac.rs new file mode 100644 index 00000000..18fc8284 --- /dev/null +++ b/tests/Languages/de/ClearSpeak/mfrac.rs @@ -0,0 +1,274 @@ +/// Tests for fractions +/// includes simple fractions and more complex fractions +/// also tests mixed fractions (implicit and explicit) +use crate::common::*; + +#[test] +fn common_fraction_half() { + let expr = " + 1 2 + "; + test("de", "ClearSpeak", expr, "1 hälfte"); +} + +#[test] +fn common_fraction_thirds() { + let expr = " + 2 3 + "; + test("de", "ClearSpeak", expr, "2 dritte"); +} + +#[test] +fn common_fraction_tenths() { + 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] +#[allow(non_snake_case)] +fn not_ClearSpeak_common_fraction_tenths() { + let expr = " + 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] +fn non_simple_fraction() { + let expr = " + + + + + x+y + + x-y + + + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr, "der bruch mit zähler; x plus y; und nenner x minus y"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Ordinal")], expr, "der bruch mit zähler; x plus y; und nenner x minus y"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Over")], expr, "x plus y durch x minus y"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "FracOver")], expr, "der bruch x plus y durch x minus y"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "General")], expr, "der bruch mit zähler; x plus y; und nenner x minus y"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "EndFrac")], expr, "der bruch mit zähler; x plus y; und nenner x minus y; ende des bruchs"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "GeneralEndFrac")], expr, "der bruch mit zähler; x plus y; und nenner x minus y; ende des bruchs"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "OverEndFrac")], expr, "x plus y durch x minus y, ende des bruchs"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Per")], expr, "x plus y pro x minus y"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Verbose"),("ClearSpeak_Fractions", "Auto")], expr, "der bruch mit zähler; x plus y; und nenner x minus y; ende des bruchs"); +} + +#[test] +fn frac_with_units() { + let expr = " + + + 62 + + mi + hr + + + "; + test("de", "ClearSpeak", expr, "62 meiles pro stunde"); +} + + +#[test] +fn mixed_number() { + let expr = " + 3 + 1 2 + "; + test("de", "ClearSpeak", expr, "3 und 1 hälfte"); +} + +#[test] +fn explicit_mixed_number() { + let expr = " + 3 + + 1 8 + "; + test("de", "ClearSpeak", expr, "3 und 1 achtel"); +} + +#[test] +fn mixed_number_big() { + let expr = " + 3 + 7 83 + "; + test("de", "ClearSpeak", expr, "3 und 7 durch 83"); +} + +#[test] +fn simple_text() { + let expr = " + rise run + "; + test("de", "ClearSpeak", expr, "rise durch run"); +} + +#[test] +fn number_and_text() { + let expr = " + + + 2miles + + 3gallons + + "; + test("de", "ClearSpeak", expr, "2 miles durch 3 gallons"); +} + + +#[test] +fn nested_simple_fractions() { + let expr = " + + + + + 1 + 2 + + + + + 2 + 3 + + + + + "; + 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", "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", "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, + "1 durch 2, ende des bruchs, durch 2 durch 3, ende des bruchs; ende des bruchs"); +} + + +#[test] +fn semi_nested_fraction() { + let expr = " + + + + + 2 + 3 + + x + + 6 + + + "; + test("de", "ClearSpeak", expr, "2 dritte x durch 6"); +} + +#[test] +fn general_nested_fraction() { + let expr = " + + + + + + 10 + n + + + + + 2 + n + + + + + + "; + test("de", "ClearSpeak", expr, "der bruch mit zähler; 10 durch n; und nenner 2 durch n"); +} + +#[test] +fn complex_nested_fraction() { + let expr = " + + + + + + n + 10 + n + + + + + 2 + n + + + + + + "; + test("de", "ClearSpeak", expr, "der bruch mit zähler; der bruch mit zähler; n plus 10; und nenner n; und nenner 2 durch n"); +} + +#[test] +fn simple_function() { + let expr = "f(x)2"; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr, "f von x durch 2"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Verbose"), ("ClearSpeak_Fractions", "Auto")], expr, "f von x durch 2, ende des bruchs"); +} + +#[test] +fn function_over_function() { + let expr = " + f(x) + g(x) + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr, "f von x durch g von x"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Verbose"), ("ClearSpeak_Fractions", "Auto")], expr, "f von x durch g von x, ende des bruchs"); +} + +#[test] +fn non_simple_function_over_function() { + let expr = " + f(x+1) + g(x) + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr, + "der bruch mit zähler; f von, klammer auf x plus 1, klammer zu; und nenner g von x"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Verbose"), ("ClearSpeak_Fractions", "Auto")], expr, + "der bruch mit zähler; f von, klammer auf x plus 1, klammer zu; und nenner g von x; ende des bruchs"); +} + +#[test] +fn binomial() { + let expr = " + 2 + ( + 7 3 + ) + "; + test("de", "ClearSpeak", expr, "2 mal 7 wählen 3"); +} diff --git a/tests/Languages/de/ClearSpeak/mroot.rs b/tests/Languages/de/ClearSpeak/mroot.rs new file mode 100644 index 00000000..b90312e8 --- /dev/null +++ b/tests/Languages/de/ClearSpeak/mroot.rs @@ -0,0 +1,136 @@ +use crate::common::*; + +#[test] +fn msqrt_simple() { + let expr = " + x + "; + test("de", "ClearSpeak", expr, "die quadratwurzel von x"); +} + +#[test] +fn msqrt_simple_end_root() { + let expr = " + x + "; + test_ClearSpeak("de", "ClearSpeak_Roots", "RootEnd", expr, "die quadratwurzel von x, ende der wurzel"); +} + +#[test] +fn msqrt_simple_positive() { + let expr = " + x + "; + test_ClearSpeak("de", "ClearSpeak_Roots", "PosNegSqRoot", expr, "die plus quadratwurzel von x"); +} + +#[test] +fn msqrt_simple_pos_end_root() { + let expr = " + x + "; + test_ClearSpeak("de", "ClearSpeak_Roots", "PosNegSqRootEnd", expr, "die plus quadratwurzel von x, ende der wurzel"); +} + +#[test] +fn msqrt_simple_pos_end_with_neg_root() { + let expr = " + - x + - x 3 + "; + test_ClearSpeak("de", "ClearSpeak_Roots", "PosNegSqRootEnd", expr, + "die minus quadratwurzel von x, ende der wurzel; minus, die positive kubikwurzel von x, ende der wurzel"); +} + +#[test] +fn mroot_simple_pos_end_with_neg_root() { + let expr = " + - x 3 + - x + + "; + test_ClearSpeak("de", "ClearSpeak_Roots", "PosNegSqRoot", expr, + "die negative kubikwurzel von x; minus die plus quadratwurzel von x"); +} + +#[test] +fn neg_without_root() { + let expr = " + - x - y + "; + test("de", "ClearSpeak", expr, "negative x minus y"); +} + +#[test] +fn msqrt() { + let expr = " + + x + y + + "; + test("de", "ClearSpeak", expr, "die quadratwurzel von x plus y"); +} + +#[test] +fn mroot_as_square_root() { + let expr = " + x 2 + "; + test("de", "ClearSpeak", expr, "die quadratwurzel von x"); +} + +#[test] +fn cube_root() { + let expr = " + x 3 + "; + test("de", "ClearSpeak", expr, "die kubikwurzel von x"); +} + +#[test] +fn ordinal_root() { + let expr = " + x 9 + "; + test("de", "ClearSpeak", expr, "die neunte Wurzel von x"); +} + + +/* // should have n-te wurze +#[test] +fn simple_mi_root() { + let expr = " + x n + "; + test("de", "ClearSpeak", expr, "die n-th wurzel von x"); +} + +#[test] +fn mroot_simple_pos_end_root() { + let expr = " + x t + "; + test_ClearSpeak("de", "ClearSpeak_Roots", "PosNegSqRootEnd", expr, "the positive t-th root of x, end root"); +} + + */ + +#[test] +fn mroot_simple_end_root() { + let expr = " + x + y + 21 + "; + test_ClearSpeak("de", "ClearSpeak_Roots", "RootEnd", expr, "die zwanzig erste Wurzel von x plus y, ende der wurzel"); +} + +#[test] +fn simple_fraction_power() { + let expr = " + + x + 13 + + "; + test("de", "ClearSpeak", expr, "die 1 drittel wurzel von x"); +} diff --git a/tests/Languages/de/ClearSpeak/msup.rs b/tests/Languages/de/ClearSpeak/msup.rs new file mode 100644 index 00000000..8dc876ec --- /dev/null +++ b/tests/Languages/de/ClearSpeak/msup.rs @@ -0,0 +1,351 @@ +/// Tests for superscripts +/// simple superscripts +/// complex/nested superscripts +use crate::common::*; + +#[test] +fn squared() { + let expr = " + x 2 + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "x quadrat"); +/* test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "x to the second"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "x to the second power"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "x raised to the power 2"); +*/ +} + +#[test] +fn cubed() { + let expr = " + x 3 + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "x hoch 3"); + +/* test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "x to the third"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "x to the third power"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "x raised to the power 3"); + */ +} + +/* +#[test] +fn ordinal_power() { + let expr = " + 3 5 + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 to the fifth power"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 to the fifth"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 to the fifth power"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 raised to the power 5"); +} + + +#[test] +fn zero_power() { + let expr = " + 3 0 + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 to the 0 power"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 to the 0"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 to the 0 power"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 raised to the power 0"); +} +#[test] +fn simple_mi_power() { + let expr = " + 4 x + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "4 to the x-th power"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "4 to the x-th"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "4 to the x-th power"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "4 raised to the power x"); +} + + +#[test] +fn decimal_power() { + let expr = " + 3 5.0 + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 raised to the 5.0 power"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 raised to the 5.0 power"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 raised to the 5.0 power"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 raised to the power 5.0"); +} + +#[test] +fn non_simple_power() { + let expr = " + 3 y+2 + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 raised to the y plus 2 power"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 raised to the y plus 2 power"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 raised to the y plus 2 power"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 raised to the power y plus 2"); +} + + +#[test] +fn negative_power() { + let expr = " + 3 - 2 + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 to the negative 2 power"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 to the negative 2"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 to the negative 2 power"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 raised to the power negative 2"); +} +*/ + +#[test] +fn simple_fraction_power() { + let expr = " + + x + 13 + + "; + test("de", "ClearSpeak", expr, "x hoch 1 drittel"); +} + +#[test] +fn nested_squared_power_with_coef() { + let expr = " + + + 3 + + 2 + + x + 2 + + + + + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 hoch 2 x quadrat"); + /* + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 raised to the exponent, 2 x to the second, end exponent"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 raised to the exponent, 2 x to the second power, end exponent"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 raised to the exponent, 2 x raised to the power 2; end exponent"); + */ + +} + +/* +#[test] +fn nested_squared_power_with_neg_coef() { + let expr = " + + + 3 + + - + 2 + + x + 2 + + + + + "; + test("de", "ClearSpeak", expr, "3 raised to the negative 2 x squared power"); +} + + +#[test] +fn nested_cubed_power() { + let expr = " + + y + + 45 + 3 + + + "; + test("de", "ClearSpeak", expr, "y raised to the 4 fifths cubed power"); +} + +#[test] +fn nested_cubed_power_with_neg_base() { + let expr = " + + y + + - + + 45 + 3 + + + + "; + test("de", "ClearSpeak", expr, "y raised to the negative 4 fifths cubed power"); +} + +#[test] +fn nested_number_times_squared() { + let expr = " + + + e + + + 1 + 2 + + + x + 2 + + + + + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "e raised to the 1 half x squared power"); +} + +#[test] +fn nested_negative_number_times_squared() { + let expr = " + + + e + + + 1 + 2 + + + x + 2 + + + + + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "e raised to the negative 1 half x squared power"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "e raised to the exponent, negative 1 half x to the second, end exponent"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "e raised to the exponent, negative 1 half x to the second power, end exponent"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "e raised to the exponent, negative 1 half x raised to the power 2; end exponent"); +} + +#[test] +fn nested_expr_to_tenth() { + let expr = " + + + 3 + + + 3 + + 10 + + + + + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 raised to the exponent, 3 to the tenth power, end exponent"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 raised to the exponent, 3 to the tenth, end exponent"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 raised to the exponent, 3 to the tenth power, end exponent"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 raised to the exponent, 3 raised to the power 10; end exponent"); + +} + +#[test] +fn nested_non_simple_squared_exp() { + let expr = " + + + 3 + + + + ( + + x+1 + ) + 2 + + + + + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 raised to the exponent, open paren x plus 1, close paren squared, end exponent"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 raised to the exponent, open paren x plus 1, close paren to the second, end exponent"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 raised to the exponent, open paren x plus 1, close paren to the second power, end exponent"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 raised to the exponent, open paren x plus 1, close paren raised to the power 2; end exponent"); +} + +#[test] +fn nested_default_power() { + let expr = " + + t + + 45 + n + + +"; + test("de", "ClearSpeak", expr, "t raised to the exponent, 4 fifths to the n-th power, end exponent"); +} + +#[test] +fn nested_complex_power() { + let expr = " + + + e + + + 1 + 2 + + + + ( + + + + xμ + σ + + + ) + 2 + + + + + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, + "e raised to the exponent, negative 1 half times; open paren; the fraction with numerator; x minus mu; and denominator sigma; close paren squared, end exponent"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, + "e raised to the exponent, negative 1 half times; open paren; the fraction with numerator; x minus mu; and denominator sigma; close paren to the second, end exponent"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, + "e raised to the exponent, negative 1 half times; open paren; the fraction with numerator; x minus mu; and denominator sigma; close paren to the second power, end exponent"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, + "e raised to the exponent, negative 1 half times; open paren; the fraction with numerator; x minus mu; and denominator sigma; close paren raised to the power 2; end exponent"); +} + +#[test] +fn default_power() { + let expr = " + + t + + b+1 + 3 + + + "; + test("de", "ClearSpeak", expr, "t raised to the fraction with numerator; b plus 1; and denominator 3; power"); +} + + */ \ No newline at end of file diff --git a/tests/Languages/de/ClearSpeak/multiline.rs b/tests/Languages/de/ClearSpeak/multiline.rs new file mode 100644 index 00000000..c324c9db --- /dev/null +++ b/tests/Languages/de/ClearSpeak/multiline.rs @@ -0,0 +1,196 @@ +use crate::common::*; + +/* // need to fix: 3 falls => 3 fälle +#[test] +fn case_1() { + let expr = " + f + + ( + x + ) + + = + + { + + -1ifx<0 + 0ifx=0 + 1ifx>0 + + + + "; + test_ClearSpeak("de", "ClearSpeak_MultiLineLabel", "Auto", expr, + "f of x is equal to; 3 cases; \ + case 1; negative 1 if x is less than 0; \ + case 2; 0 if x is equal to 0; \ + case 3; 1 if x is greater than 0" + ) +} + + */ + +#[test] +fn equation_auto() { + let expr = " + + + x+y = 7 + 2x+3y = 17 + + + "; + test_ClearSpeak("de", "ClearSpeak_MultiLineLabel", "Auto", expr, + "2 zeiles; zeile 1; x plus y, ist gleich 7; zeile 2; 2 x plus 3 y; ist gleich 17"); +} + + +/* // fixme: zeiles => zeilen +#[test] +fn equation_plus_at_start() { + let expr = " + + + x+y = 7 + 2x+3y = 17 + + + "; + test_ClearSpeak("de", "ClearSpeak_MultiLineLabel", "Auto", expr, "2 lines; \ + line 1; x plus y is equal to 7; \ + line 2; 2 x, plus 3 y, is equal to 17"); +} + + */ + +/* +#[test] +fn equation_case() { + let expr = " + + + x+y = 7 + 2x+3y = 17 + + + "; + test_ClearSpeak("de", "ClearSpeak_MultiLineLabel", "Case", expr, + "2 cases; case 1; x plus y, is equal to 7; case 2; 2 x plus 3 y; is equal to 17"); +} + + */ + +/* // fixme: Bedingungs => Bedingungen +#[test] +fn equation_constraint() { + let expr = " + + + x+y = 7 + 2x+3y = 17 + + + "; + test_ClearSpeak("de", "ClearSpeak_MultiLineLabel", "Constraint", expr, "2 constraints; \ + constraint 1; x plus y, is equal to 7; \ + constraint 2; 2 x plus 3 y; is equal to 17"); +} +*/ + +/* // fixme: Gleichungs => Gleichungen +#[test] +fn equation_equation() { + let expr = " + + + x+y = 7 + 2x+3y = 17 + + + "; + test_ClearSpeak("de", "ClearSpeak_MultiLineLabel", "Equation", expr, "2 equations; \ + equation 1; x plus y, is equal to 7; \ + equation 2; 2 x plus 3 y; is equal to 17"); +} + + */ + +/* // FIXME: Zeiles => Zeilen +#[test] +fn equation_line() { + let expr = " + + + x+y = 7 + 2x+3y = 17 + + + "; + test_ClearSpeak("de", "ClearSpeak_MultiLineLabel", "Line", expr, "2 lines; \ + line 1; x plus y, is equal to 7; \ + line 2; 2 x plus 3 y; is equal to 17"); +} + + +#[test] +fn equation_none() { + let expr = " + + + x+y = 7 + 2x+3y = 17 + + + "; + test_ClearSpeak("de", "ClearSpeak_MultiLineLabel", "None", expr, + "2 lines; \ + x plus y, is equal to 7; \ + 2 x plus 3 y; is equal to 17"); +} + +#[test] +fn equation_row() { + let expr = " + + + x+y = 7 + 2x+3y = 17 + + + "; + test_ClearSpeak("de", "ClearSpeak_MultiLineLabel", "Row", expr, "2 rows; \ + row 1; x plus y, is equal to 7; \ + row 2; 2 x plus 3 y; is equal to 17"); +} + */ + +/* // FIXME: stufes => Stufen +#[test] +fn equation_step() { + let expr = " + + + x+y = 7 + 2x+3y = 17 + + + "; + test_ClearSpeak("de", "ClearSpeak_MultiLineLabel", "Step", expr, "2 steps; \ + step 1; x plus y, is equal to 7; \ + step 2; 2 x plus 3 y; is equal to 17"); +} + +#[test] +fn continued_row() { + let expr = " + + x=y + +1 + y=1 + +"; +test("de", "SimpleSpeak", expr, + "2 equations; equation 1; x is equal to y plus 1; equation 2; y is equal to 1"); +} +*/ \ No newline at end of file diff --git a/tests/Languages/de/ClearSpeak/sets.rs b/tests/Languages/de/ClearSpeak/sets.rs new file mode 100644 index 00000000..2a400006 --- /dev/null +++ b/tests/Languages/de/ClearSpeak/sets.rs @@ -0,0 +1,452 @@ +use crate::common::*; + +#[test] +fn complex() { + let expr = " + + "; + test("de", "ClearSpeak", expr, "die komplexen zahlen"); +} + +#[test] +fn natural() { + let expr = " + + "; + test("de", "ClearSpeak", expr, "die natürlichen zahlen"); +} + +#[test] +fn rationals() { + let expr = " + + "; + test("de", "ClearSpeak", expr, "die rationalen zahlen"); +} + +#[test] +fn reals() { + let expr = " + + "; + test("de", "ClearSpeak", expr, "die reelen zahlen"); +} + +#[test] +fn integers() { + let expr = " + + "; + test("de", "ClearSpeak", expr, "die ganzen zahlen"); +} + + + +#[test] +fn msup_complex() { + let expr = " + + + 2 + + "; + test("de", "ClearSpeak", expr, "c 2"); +} + +#[test] +fn msup_natural() { + let expr = " + + + 2 + + "; + test("de", "ClearSpeak", expr, "n 2"); +} + +#[test] +fn msup_rationals() { + let expr = " + + + 2 + + "; + test("de", "ClearSpeak", expr, "q 2"); +} + +#[test] +fn msup_reals() { + let expr = " + + + 3 + + "; + test("de", "ClearSpeak", expr, "r 3"); +} + +#[test] +fn msup_integers() { + let expr = " + + + 4 + + "; + test("de", "ClearSpeak", expr, "z 4"); +} + +#[test] +fn msup_positive_integers() { + let expr = " + + + + + + "; + test("de", "ClearSpeak", expr, "die positiven ganze zahlen"); +} + +#[test] +fn msup_negative_integers() { + let expr = " + + + - + + "; + test("de", "ClearSpeak", expr, "die negativen ganze zahlen"); +} + +#[test] +fn msup_positive_rationals() { + let expr = " + + + + + + "; + test("de", "ClearSpeak", expr, "die positiven rationale zahlen"); +} + +#[test] +fn msup_negative_rationals() { + let expr = " + + + - + + "; + test("de", "ClearSpeak", expr, "die negativen rationale zahlen"); +} + +#[test] +fn empty_set() { + let expr = " + { } + "; + test("de", "ClearSpeak", expr, "leere Menge"); +} + +#[test] +fn single_element_set() { + let expr = " + { 12} + "; + test("de", "ClearSpeak", expr, "die Menge 12"); +} + +#[test] +fn multiple_element_set() { + let expr = " + { 5 , 10 , 15 } + "; + test("de", "ClearSpeak", expr, "die Menge 5 komma 10 komma 15"); +} + +#[test] +fn set_with_colon() { + let expr = " + { x:x>2 } + "; + test("de", "ClearSpeak", expr, "die Menge alle x so dass x ist größer als 2"); +} + +#[test] +fn set_with_bar() { + let expr = " + { x|x>2 } + "; + test("de", "ClearSpeak", expr, "die Menge alle x so dass x ist größer als 2"); +} + +#[test] +fn element_alone() { + let expr = " + 3+2i + "; + test("de", "ClearSpeak", expr, "3 plus 2 i, ist kein element von, die reelen zahlen"); +} + +#[test] +fn element_under_sum() { + let expr = " + + + i + + + 1 + i 2 + + "; + test("de", "ClearSpeak", expr, + "die summe durch i ist ein element von, die ganzen zahlen von; der bruch mit zähler 1; und nenner i quadrat"); +} + +#[test] +fn complicated_set_with_colon() { + let expr = " + { + x + + + : + 2 + < + x + < + 7 + } + "; + test("de", "ClearSpeak", expr, "die Menge alle x in die ganzen zahlen so dass 2 ist kleiner als x ist kleiner als 7"); +} + +#[test] +fn complicated_set_with_mtext() { + // as of 8/5/21, parsing of "|" is problematic in the example, so are needed for this test + let expr = " + { + x + | + x is an even number + } + "; + test("de", "ClearSpeak", expr, + "die Menge alle x in die natürlichen zahlen so dass x is an even number"); +} + + +#[test] +fn set_with_bar_member() { + let expr = " + { + x + + + : + x + > + 5 + } + "; + test_ClearSpeak("de", "ClearSpeak_SetMemberSymbol", "Member", + expr, "die Menge alle x element von die ganzen zahlen so dass x ist größer als 5"); +} + +#[test] +fn element_alone_member() { + let expr = " + 3+2i + "; + test_ClearSpeak("de", "ClearSpeak_SetMemberSymbol", "Member", + expr, "3 plus 2 i, ist kein element von, die reelen zahlen"); +} + +#[test] +fn element_under_sum_member() { + let expr = " + + + i + + + 1 + i 2 + + "; + test_ClearSpeak("de", "ClearSpeak_SetMemberSymbol", "Member", + expr, "die summe durch i ist ein element von, die ganzen zahlen von; der bruch mit zähler 1; und nenner i quadrat"); +} + + +#[test] +fn set_with_bar_element() { + let expr = " + { + x + + + : + x + > + 5 + } + "; + test_ClearSpeak("de", "ClearSpeak_SetMemberSymbol", "Element", + expr, "die Menge alle x element von die ganzen zahlen so dass x ist größer als 5"); +} + +#[test] +fn element_alone_element() { + let expr = " + 3+2i + "; + test_ClearSpeak("de", "ClearSpeak_SetMemberSymbol", "Element", + expr, "3 plus 2 i, ist kein element von, die reelen zahlen"); +} + +#[test] +fn element_under_sum_element() { + let expr = " + + + i + + + 1 + i 2 + + "; + test_ClearSpeak("de", "ClearSpeak_SetMemberSymbol", "Element", + expr, "die summe durch i ist ein element von, die ganzen zahlen von; der bruch mit zähler 1; und nenner i quadrat"); +} + +#[test] +fn set_with_bar_in() { + let expr = " + { + x + + + : + x + > + 5 + } + "; + test_ClearSpeak("de", "ClearSpeak_SetMemberSymbol", "In", + expr, "die Menge alle x in die ganzen zahlen so dass x ist größer als 5"); +} + +#[test] +fn element_alone_in() { + let expr = " + 3+2i + "; + test_ClearSpeak("de", "ClearSpeak_SetMemberSymbol", "In", + expr, "3 plus 2 i, ist nicht in die reelen zahlen"); +} + +#[test] +fn element_under_sum_in() { + let expr = " + + + i + + + 1 + i 2 + + "; + test_ClearSpeak("de", "ClearSpeak_SetMemberSymbol", "In", + expr, "die summe durch i ist in die ganzen zahlen von; der bruch mit zähler 1; und nenner i quadrat"); +} + +#[test] +fn set_with_bar_belongs() { + let expr = " + { + x + + + : + x + > + 5 + } + "; + test_ClearSpeak("de", "ClearSpeak_SetMemberSymbol", "Belongs", + expr, "die Menge alle x element von die ganzen zahlen so dass x ist größer als 5"); +} + +#[test] +fn element_alone_belongs() { + let expr = " + 3+2i + "; + test_ClearSpeak("de", "ClearSpeak_SetMemberSymbol", "Belongs", + expr, "3 plus 2 i, nicht element von, die reelen zahlen"); +} + +#[test] +fn element_under_sum_belongs() { + let expr = " + + + i + + + 1 + i 2 + + "; + test_ClearSpeak("de", "ClearSpeak_SetMemberSymbol", "Belongs", + expr, "die summe durch i element von die ganzen zahlen von; der bruch mit zähler 1; und nenner i quadrat"); +} + + +#[test] +fn set_member_woall() { + let expr = " + { + x + + + : + x + > + 5 + } + "; + test_ClearSpeak_prefs("en", vec![("ClearSpeak_SetMemberSymbol", "Member"), ("ClearSpeak_Sets", "woAll")], + expr, "the set of x member of the integers such that x is greater than 5"); +} + +#[test] +fn multiple_element_set_woall() { + let expr = " + { 5 , 10 , 15 } + "; + test_ClearSpeak("de", "ClearSpeak_Sets", "woAll", expr, "die Menge 5 komma 10 komma 15"); +} + +#[test] +fn multiple_element_set_silent_bracket() { + let expr = " + { 5 , 10 , 15 } + "; + test_ClearSpeak("de", "ClearSpeak_Sets", "SilentBracket", expr, "5 komma 10 komma 15"); + } + +#[test] +fn silent_bracket() { + let expr = " + {x|x>2} + "; + test_ClearSpeak("de", "ClearSpeak_Sets", "SilentBracket", expr, + "die Menge alle x so dass x ist größer als 2"); + } + diff --git a/tests/Languages/de/ClearSpeak/symbols_and_adornments.rs b/tests/Languages/de/ClearSpeak/symbols_and_adornments.rs new file mode 100644 index 00000000..2633fcd7 --- /dev/null +++ b/tests/Languages/de/ClearSpeak/symbols_and_adornments.rs @@ -0,0 +1,332 @@ +use crate::common::*; + +#[test] +fn multiplication() { + let expr = " + 2×3 + "; + test("de", "ClearSpeak", expr, "2 mal 3"); +} + +/* +#[test] +fn multiplication_by() { + let expr = " + 2×3 + "; + test_ClearSpeak("de", "ClearSpeak_MultSymbolX", "By", expr, "2 by 3"); +}*/ + +#[test] +fn multiplication_cross() { + let expr = " + u×v + "; + test_ClearSpeak("de", "ClearSpeak_MultSymbolX", "Cross", expr, "u mal v"); +} + +#[test] +fn ellipses_auto_start() { + let expr = " + , + -2,-1,0 + "; + test("de", "ClearSpeak", expr, "punkt punkt punkt komma negative 2 komma negative 1 komma 0"); +} + +#[test] +fn ellipses_auto_end() { + let expr = " + 1 + , + 2 + , + 3 + , + + "; + test_ClearSpeak("de", "ClearSpeak_Ellipses", "Auto", expr, "1 komma 2 komma 3 komma punkt punkt punkt"); +} + +#[test] +fn ellipses_auto_middle() { + let expr = " + + 1 + , + 2 + , + 3 + , + + , + 20 + + "; + test_ClearSpeak("de", "ClearSpeak_Ellipses", "Auto", expr, + "1 komma 2 komma 3 komma punkt punkt punkt komma 20"); +} + +#[test] +fn ellipses_auto_both() { + let expr = " + , + -2,-1,0,1,2 + , + "; + 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"); +} + +#[test] +fn ellipses_and_so_on_start() { + let expr = " + , + -2,-1,0 + "; + test_ClearSpeak("de", "ClearSpeak_Ellipses", "AndSoOn", expr, "punkt punkt punkt komma negative 2 komma negative 1 komma 0"); +} + +#[test] +fn ellipses_and_so_on_end() { + let expr = " + 1 + , + 2 + , + 3 + , + + "; + test_ClearSpeak("de", "ClearSpeak_Ellipses", "AndSoOn", expr, "1 komma 2 komma 3 und so weiter"); +} + +#[test] +fn ellipses_and_so_on_middle() { + let expr = " + + 1 + , + 2 + , + 3 + , + + , + 20 + + "; + test_ClearSpeak("de", "ClearSpeak_Ellipses", "AndSoOn", expr, + "1 komma 2 komma 3 punkt punkt punkt 20"); +} + +#[test] +fn ellipses_and_so_on_both() { + let expr = " + , + -2,-1,0,1,2 + , + "; + 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"); +} + +#[test] +fn vertical_line_auto() { + let expr = " + 3|6 + "; + test_ClearSpeak("de", "ClearSpeak_VerticalLine", "Auto", expr, + "3 teilt 6"); +} + +#[test] +fn vertical_line_divides() { + let expr = " + 3|6 + "; + test_ClearSpeak("de", "ClearSpeak_VerticalLine", "Divides", expr, + "3 teilt 6"); +} + + #[test] + fn vertical_line_given() { + let expr = " + 3|6 + "; + test_ClearSpeak("de", "ClearSpeak_VerticalLine", "Given", expr, + "3 gegeben 6"); + } + + #[test] + fn vertical_line_probability_given() { + let expr = " + P + + ( + + A + | + B + + ) + + "; + test_ClearSpeak_prefs("en", vec![("ClearSpeak_VerticalLine", "Given"), ("ClearSpeak_ImpliedTimes", "None")] + , expr, "cap p, open paren, cap eigh given cap b, close paren"); + } + +#[test] +fn vertical_line_set() { + let expr = " + { + + x + | + x + > + 0 + + } + "; + test_ClearSpeak("de", "ClearSpeak_VerticalLine", "Auto", expr, + "die Menge alle x so dass x ist größer als 0"); +} + + +#[test] +fn vertical_line_set_such_that() { + let expr = " + { + + x + | + x + > + 0 + + } + "; + test_ClearSpeak("de", "ClearSpeak_VerticalLine", "SuchThat", expr, + "die Menge alle x so dass x ist größer als 0"); +} + +#[test] +fn vertical_line_set_given() { + let expr = " + { + + x + | + x + > + 0 + + } + "; + // the rules for set will override all the options -- ClearSpeak spec should be clarified + test_ClearSpeak("de", "ClearSpeak_VerticalLine", "Given", expr, + "die Menge alle x so dass x ist größer als 0"); +} + +#[test] +fn vertical_line_set_and_abs() { + let expr = " + { + + x + | + + | + x + | + + > + 2 + + } + "; + test_ClearSpeak("de", "ClearSpeak_VerticalLine", "Auto", expr, + "die Menge alle x so dass der Betrag von x; ist größer als 2"); +} + +#[test] +fn vertical_line_evaluated_at() { + let expr = " + f + + ( + x + ) + + + | + + x + = + 5 + + + "; + test_ClearSpeak("de", "ClearSpeak_VerticalLine", "Auto", expr, + "f von x, ausgewertet bei, x ist gleich 5"); +} + +#[test] +fn vertical_line_evaluated_at_both() { + let expr = " + + x + 2 + + + + x + + | + 0 + 1 + + "; + test_ClearSpeak("de", "ClearSpeak_VerticalLine", "Auto", expr, + "x quadrat plus x, ausgewertet zwischen 1 und 0"); +} +#[test] +fn vertical_line_evaluated_at_divides() { + let expr = " + f + + ( + x + ) + + + | + + x + = + 5 + + + "; + test_ClearSpeak("de", "ClearSpeak_VerticalLine", "Divides", expr, + "f von x, ausgewertet bei, x ist gleich 5"); +} + +#[test] +fn vertical_line_evaluated_at_both_given() { + let expr = " + + x + 2 + + + + x + + | + 0 + 1 + + "; + test_ClearSpeak("de", "ClearSpeak_VerticalLine", "Given", expr, + "x quadrat plus x, ausgewertet zwischen 1 und 0"); +} \ No newline at end of file diff --git a/tests/Languages/de/SimpleSpeak/functions.rs b/tests/Languages/de/SimpleSpeak/functions.rs new file mode 100644 index 00000000..f6634643 --- /dev/null +++ b/tests/Languages/de/SimpleSpeak/functions.rs @@ -0,0 +1,340 @@ +/// Tests for: +/// * functions including trig functions, logs, and functions to powers +/// * implied times/functional call and explicit times/function call +/// * parens +/// These are all intertwined, so they are in one file +use crate::common::*; + +#[test] +fn trig_names() { + let expr = " + sinx+ + cosy+ + tanz+ + secα+ + cscϕ+ + cotφ + "; + test("de", "SimpleSpeak", expr, "sine of x plus cosine of y plus tangent of z plus secant of alpha, plus cosecant of phi, plus cotangent of phi"); +} + +#[test] +fn hyperbolic_trig_names() { + let expr = " + sinhx+ + coshy+ + tanhz+ + sechα+ + cschϕ+ + cothφ + "; + test("de", "SimpleSpeak", expr, "hyperbolic sine of x, plus \ + hyperbolic cosine of y, plus \ + hyperbolic tangent of z, plus \ + hyperbolic secant of alpha, plus \ + hyperbolic cosecant of phi, plus \ + hyperbolic cotangent of phi"); +} + + +#[test] +fn inverse_trig() { + let expr = "sin-1x"; + test("de", "SimpleSpeak", expr, "inverse sine of x"); +} + +#[test] +fn trig_squared() { + let expr = "sin2x"; + test("de", "SimpleSpeak", expr, "sine squared of x"); +} + +#[test] +fn trig_cubed() { + let expr = "tan3x"; + test("de", "SimpleSpeak", expr, "tangent cubed of x"); +} + +#[test] +fn trig_fourth() { + let expr = "sec4x"; + test("de", "SimpleSpeak", expr, "the fourth power of, secant of x"); +} + + +#[test] +fn trig_power_other() { + let expr = "sinh>n-1x"; + test("de", "SimpleSpeak", expr, "the n minus 1 power of, hyperbolic sine of x"); +} + +#[test] +fn simple_log() { + let expr = " logx "; + test("de", "SimpleSpeak", expr, "the log of x"); +} + +#[test] +fn normal_log() { + let expr = "log(x+y)"; + test("de", "SimpleSpeak", expr, "the log of, open paren x plus y, close paren"); +} + +#[test] +fn simple_log_with_base() { + let expr = " logbx "; + test("de", "SimpleSpeak", expr, "the log base b, of x"); +} + +#[test] +fn normal_log_with_base() { + let expr = "logb(x+y)"; + test("de", "SimpleSpeak", expr, "the log base b, of, open paren x plus y, close paren"); +} + +#[test] +fn normal_ln() { + let expr = "ln(x+y)"; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "l n, open x plus y close"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Medium")], + expr, "the natural log of, open paren x plus y, close paren"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Verbose")], + expr, "the natural log of, open paren x plus y, close paren"); +} + +#[test] +fn simple_ln() { + let expr = " lnx "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "l n x"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Medium")], + expr, "the natural log of x"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Verbose")], + expr, "the natural log of x"); +} + +#[test] +fn other_names() { + let expr = " Covx "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "Cov x"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Medium")], + expr, "covariance x"); + let expr = " exp(x) "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "exp of x"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Medium")], + expr, "exponential of x"); +} + +#[test] +fn explicit_function_call_with_parens() { + let expr = "t(x)"; + test("de", "SimpleSpeak", expr, "t of x"); +} + + +#[test] +fn explicit_times_with_parens() { + let expr = "t(x)"; + test("de", "SimpleSpeak", expr, "t times x"); +} + +#[test] +fn explicit_function_call() { + let expr = "tx"; + test("de", "SimpleSpeak", expr, "t of x"); +} + +#[test] +fn explicit_times() { + let expr = "tx"; + test("de", "SimpleSpeak", expr, "t x"); +} + + +/* + * Tests for times + */ +#[test] +fn no_times_binomial() { + let expr = "x y"; + test("de", "SimpleSpeak", expr, "x y"); +} + +#[test] +fn times_following_paren() { + let expr = " + 2 + ( 3 ) + "; + test("de", "SimpleSpeak", expr, "2 times 3"); +} + +#[test] +fn times_preceding_paren() { + let expr = " + ( 2 ) + 3 + "; + test("de", "SimpleSpeak", expr, "2 times 3"); +} + +#[test] +fn no_times_sqrt() { + let expr = " + a + b + = + ab + "; + test("de", "SimpleSpeak", expr, + "the square root of eigh; times the square root of b; is equal to, the square root of eigh b end root"); + test_prefs("de", "SimpleSpeak", vec![("Impairment", "LearningDisability")], expr, + "the square root of eigh; times the square root of b; is equal to, the square root of eigh b"); +} + +/* + * Tests for parens + */ + #[test] + fn no_parens_number() { + let expr = " + ( + 25 + ) + x + "; + test("de", "SimpleSpeak", expr, "25 times x"); + } + + #[test] + fn no_parens_monomial() { + let expr = " + b + ( + xy + ) + "; + test("de", "SimpleSpeak", expr, "b, open paren x y close paren"); + } + + #[test] + fn no_parens_negative_number() { + let expr = " + 2+ + ( + 2 + ) + "; + test("de", "SimpleSpeak", expr, "2 plus negative 2"); + } + + + #[test] + fn no_parens_negative_number_with_var() { + let expr = " + ( + 2x + ) + +1 + "; + test("de", "SimpleSpeak", expr, "negative 2 x, plus 1"); + } + + #[test] + fn parens_superscript() { + let expr = " + + + + ( + 2x + ) + 2 + + + "; + test("de", "SimpleSpeak", expr, "open paren 2 x close paren squared"); + } + + #[test] + fn no_parens_fraction() { + let expr = " + 2 + + + + ( + 12 + ) + "; + test("de", "SimpleSpeak", expr, "2 plus 1 half"); + } + + + // Tests for the four types of intervals in SimpleSpeak + #[test] + fn parens_interval_open_open() { + let expr = " + ( + (c,d) + ) + "; + test("de", "SimpleSpeak",expr, "the open interval from c to d"); +} + +#[test] + fn parens_interval_closed_open() { + let expr = " + [ + [(]c,d) + ) + "; + test("de", "SimpleSpeak",expr, "the closed open interval from c to d"); +} + + +#[test] +fn parens_interval_open_closed() { + let expr = " + ( + (c,d] + ] + "; + test("de", "SimpleSpeak",expr,"the open closed interval from c to d"); +} + + +#[test] +fn parens_interval_closed_closed() { + let expr = " + [ + [(]c,d] + ] + "; + test("de", "SimpleSpeak",expr, "the closed interval from c to d"); +} + + #[test] + fn parens_interval_neg_infinity_open_open() { + let expr = " + ( + - ,d) + ) + "; + test("de", "SimpleSpeak",expr, + "the open interval from negative infinity to d"); +} + + #[test] + fn parens_interval_neg_infinity_open_closed() { + let expr = " + ( + - ,d] + ] + "; + test("de", "SimpleSpeak",expr, + "the open closed interval from negative infinity to d"); +} + diff --git a/tests/Languages/de/SimpleSpeak/geometry.rs b/tests/Languages/de/SimpleSpeak/geometry.rs new file mode 100644 index 00000000..d1fc2438 --- /dev/null +++ b/tests/Languages/de/SimpleSpeak/geometry.rs @@ -0,0 +1,27 @@ +/// Tests for geometry listed in intent +/// ABC as mtext and as separated letters +use crate::common::*; + +#[test] +fn arc() { + let expr = " BC "; + test("de", "SimpleSpeak", expr, "arc cap b cap c"); +} + +#[test] +fn ray() { + let expr = " XY¯ "; + test("de", "SimpleSpeak", expr, "line segment cap x cap y"); +} + +#[test] +fn arc_mtext() { + let expr = " BC "; + test("de", "SimpleSpeak", expr, "arc cap b cap c"); +} + +#[test] +fn ray_mtext() { + let expr = " XY "; + test("de", "SimpleSpeak", expr, "ray cap x cap y"); +} diff --git a/tests/Languages/de/SimpleSpeak/large_ops.rs b/tests/Languages/de/SimpleSpeak/large_ops.rs new file mode 100644 index 00000000..213b2ab3 --- /dev/null +++ b/tests/Languages/de/SimpleSpeak/large_ops.rs @@ -0,0 +1,200 @@ +use crate::common::*; + +#[test] +fn sum_both() { + let expr = " + + + n=1 + 10 + + n + "; + test("de", "SimpleSpeak", expr, "the sum from n is equal to 1 to 10 of n"); +} + +#[test] +fn sum_under() { + let expr = " + + + S + + i + "; + test("de", "SimpleSpeak", expr, "the sum over cap s of i"); +} +#[test] +fn sum_both_msubsup() { + let expr = " + + + n=1 + 10 + + n + "; + test("de", "SimpleSpeak", expr, "the sum from n is equal to 1 to 10 of n"); +} + +#[test] +fn sum_sub() { + let expr = " + + + S + + i + "; + test("de", "SimpleSpeak", expr, "the sum over cap s of i"); +} + +#[test] +fn sum() { + let expr = " + + ai + "; + test("de", "SimpleSpeak", expr, "the sum of eigh sub i"); +} + +#[test] +fn product_both() { + let expr = " + + + n=1 + 10 + + n + "; + test("de", "SimpleSpeak", expr, "the product from n is equal to 1 to 10 of n"); +} + +#[test] +fn product_under() { + let expr = " + + + S + + i + "; + test("de", "SimpleSpeak", expr, "the product over cap s of i"); +} + +#[test] +fn product() { + let expr = " + + ai + "; + test("de", "SimpleSpeak", expr, "the product of eigh sub i"); +} + +#[test] +fn intersection_both() { + let expr = " + + + i=1 + 10 + + Si + "; + test("de", "SimpleSpeak", expr, "the intersection from i is equal to 1 to 10 of; cap s sub i"); +} + +#[test] +fn intersection_under() { + let expr = " + + + C + + Si + "; + test("de", "SimpleSpeak", expr, "the intersection over cap c of, cap s sub i"); +} + +#[test] +fn intersection() { + let expr = " + + Si + "; + test("de", "SimpleSpeak", expr, "the intersection of cap s sub i"); +} + +#[test] +fn union_both() { + let expr = " + + + i=1 + 10 + + Si + "; + test("de", "SimpleSpeak", expr, "the union from i is equal to 1 to 10 of; cap s sub i"); +} + +#[test] +fn union_under() { + let expr = " + + + C + + Si + "; + test("de", "SimpleSpeak", expr, "the union over cap c of, cap s sub i"); +} + +#[test] +fn union() { + let expr = " + + Si + "; + test("de", "SimpleSpeak", expr, "the union of cap s sub i"); +} + +#[test] +fn integral_both() { + let expr = " + + + + 0 + 1 + + f(x ) + + dx + "; + test("de", "SimpleSpeak", expr, "the integral from 0 to 1 of, f of x; d x"); +} + +#[test] +fn integral_under() { + let expr = " + + + + + f(x ) + dx + "; + test("de", "SimpleSpeak", expr, "the integral over the real numbers of; f of x d x"); +} + +#[test] +fn integral() { + let expr = " + + f(x ) + dx + "; + test("de", "SimpleSpeak", expr, "the integral of f of x d x"); +} \ No newline at end of file diff --git a/tests/Languages/de/SimpleSpeak/linear_algebra.rs b/tests/Languages/de/SimpleSpeak/linear_algebra.rs new file mode 100644 index 00000000..2eebfbae --- /dev/null +++ b/tests/Languages/de/SimpleSpeak/linear_algebra.rs @@ -0,0 +1,92 @@ +use crate::common::*; + +#[test] +fn transpose() { + let expr = " MT "; + test("de", "SimpleSpeak", expr, "cap m transpose"); +} + +#[test] +fn trace() { + let expr = " TrM "; + test("de", "SimpleSpeak", expr, "trace of cap m"); +} + +#[test] +fn dimension() { + let expr = " DimM "; + test("de", "SimpleSpeak", expr, "dimension of cap m"); +} + +#[test] +fn homomorphism() { + let expr = " Hom(M) "; + test("de", "SimpleSpeak", expr, "homomorphism of cap m"); +} + +#[test] +fn kernel() { + let expr = " ker(L) "; + test("de", "SimpleSpeak", expr, "kernel of cap l"); +} + +#[test] +fn norm() { + let expr = " + + + f + + + +"; + test("de", "SimpleSpeak", expr, "norm of f"); +} + +#[test] +fn norm_non_simple() { + let expr = " + + + x + + + y + + + +"; + test("de", "SimpleSpeak", expr, "norm of x plus y end norm"); +} + +#[test] +fn norm_subscripted() { + let expr = " + + + + f + + + p + + +"; + test("de", "SimpleSpeak", expr, "p norm of f"); +} + +#[test] +fn not_gradient() { + // the nabla is at the end, so it can't be gradient because it doesn't operate on anything + let expr = r#" + ( + b + + + + + ) + a + +"#; + test("de", "SimpleSpeak", expr, "open paren, b times nahblah, close paren; times eigh"); +} \ No newline at end of file diff --git a/tests/Languages/de/SimpleSpeak/mfrac.rs b/tests/Languages/de/SimpleSpeak/mfrac.rs new file mode 100644 index 00000000..286eba6c --- /dev/null +++ b/tests/Languages/de/SimpleSpeak/mfrac.rs @@ -0,0 +1,307 @@ +/// Tests for fractions +/// includes simple fractions and more complex fractions +/// also tests mixed fractions (implicit and explicit) +use crate::common::*; + +#[test] +fn common_fraction_half() { + let expr = " + 1 2 + "; + test("de", "SimpleSpeak", expr, "1 half"); +} + +#[test] +fn common_fraction_thirds() { + let expr = " + 2 3 + "; + test("de", "SimpleSpeak", expr, "2 thirds"); +} + +#[test] +fn common_fraction_tenths() { + let expr = " + 17 10 + "; + test("de", "SimpleSpeak", expr, "17 tenths"); +} + +#[test] +#[allow(non_snake_case)] +fn not_SimpleSpeak_common_fraction_tenths() { + let expr = " + 89 10 + "; + test("de", "SimpleSpeak", expr, "89 over 10"); +} + +#[test] +fn non_simple_fraction() { + let expr = " + + + + x+y + + x-y + + + + "; + test("de", "SimpleSpeak", expr, "fraction, x plus y, over, x minus y, end fraction"); +} + +#[test] +fn nested_fraction() { + let expr = " + + + + x+ 1y + + x-y + + + + "; + test("de", "SimpleSpeak", expr, "fraction, x plus, fraction, 1 over y, end fraction; over, x minus y, end fraction"); +} + + +#[test] +fn deeply_nested_fraction_msqrt() { + let expr = " + + + + x+ 1y + + x-y + + + + "; + test("de", "SimpleSpeak", expr, "fraction, x plus, the square root of 1 over y, end root; over, x minus y, end fraction"); +} + +#[test] +fn deeply_nested_fraction_mrow_msqrt() { + let expr = " + + + + x+ 2+1y + + x-y + + + + "; + test("de", "SimpleSpeak", expr, "fraction, x plus, the square root of 2 plus 1 over y, end root; over, x minus y, end fraction"); +} + +#[test] +fn numerator_simple_fraction() { + let expr = " + + + + x + + x-y + + + + "; + test("de", "SimpleSpeak", expr, "fraction, x over, x minus y, end fraction"); +} + +#[test] +fn denominator_simple_fraction() { + let expr = " + + + x-y + x + + + "; + test("de", "SimpleSpeak", expr, "fraction, x minus y, over x, end fraction"); +} + + +#[test] +fn frac_with_units() { + let expr = " + + + 62 + + mi + hr + + + "; + test("de", "SimpleSpeak", expr, "62 miles per hour"); +} + +#[test] +fn singular_frac_with_units() { + let expr = " + + + 1 + + gal + mi + + + "; + test("de", "SimpleSpeak", expr, "1 gallon per mile"); +} + +#[test] +fn number_in_numerator_with_units() { + let expr = " + + + + 3 + gal + + mi + + "; + test("de", "SimpleSpeak", expr, "3 gallons per mile"); +} + +#[test] +fn units_with_powers() { + let expr = " + + + 3 m + s2 + + "; + test("de", "SimpleSpeak", expr, "3 metres per second squared"); +} + + +#[test] +fn mixed_number() { + let expr = " + 3 + 1 2 + "; + test("de", "SimpleSpeak", expr, "3 and 1 half"); +} + +#[test] +fn explicit_mixed_number() { + let expr = " + 3 + + 1 8 + "; + test("de", "SimpleSpeak", expr, "3 and 1 eighth"); +} + +#[test] +fn mixed_number_big() { + let expr = " + 3 + 7 83 + "; + test("de", "SimpleSpeak", expr, "3 and 7 eighty thirds"); +} + +#[test] +fn simple_text() { + let expr = " + rise run + "; + test("de", "SimpleSpeak", expr, "rise over run"); +} + +#[test] +fn number_and_text() { + let expr = " + + + 2miles + + 3gallons + + "; + test("de", "SimpleSpeak", expr, "fraction, 2 miles, over, 3 gallons, end fraction"); +} + + +#[test] +fn nested_simple_fractions() { + let expr = " + + + + + 1 + 2 + + + + + 2 + 3 + + + + + "; + test("de", "SimpleSpeak", expr, "fraction, 1 half, over, 2 thirds, end fraction"); +} + +#[test] +fn binomial() { + let expr = " + 2 + ( + 7 3 + ) + "; + test("de", "SimpleSpeak", expr, "2 times 7 choose 3"); +} + +#[test] +fn binomial_non_simple_top() { + let expr = " + 2 + ( + n+7 3 + ) + "; + test("de", "SimpleSpeak", expr, "2 times, binomial n plus 7 choose 3"); +} + +#[test] +fn binomial_non_simple_bottom() { + let expr = " + 2 + ( + 7 k+3 + ) + "; + test("de", "SimpleSpeak", expr, "2 times, 7 choose k plus 3 end binomial"); +} + +#[test] +fn binomial_non_simple_top_and_bottom() { + let expr = " + 2 + ( + n+7 k+3 + ) + "; + test("de", "SimpleSpeak", expr, "2 times, binomial n plus 7 choose k plus 3 end binomial"); +} diff --git a/tests/Languages/de/SimpleSpeak/msup.rs b/tests/Languages/de/SimpleSpeak/msup.rs new file mode 100644 index 00000000..f292051a --- /dev/null +++ b/tests/Languages/de/SimpleSpeak/msup.rs @@ -0,0 +1,334 @@ +/// Tests for superscripts +/// simple superscripts +/// complex/nested superscripts +use crate::common::*; + +#[test] +fn squared() { + let expr = " + x 2 + "; + test("de", "SimpleSpeak", expr, "x squared"); +} + +#[test] +fn cubed() { + let expr = " + x 3 + "; + test("de", "SimpleSpeak", expr, "x cubed"); +} + +#[test] + fn ordinal_power() { + let expr = " + x 4 + "; + test("de", "SimpleSpeak", expr, "x to the fourth"); + } + +#[test] +fn simple_mi_power() { + let expr = " + x n + "; + test("de", "SimpleSpeak", expr, "x to the n-th"); +} + +#[test] +fn zero_power() { + let expr = " + x 0 + "; + test("de", "SimpleSpeak", expr, "x to the 0"); +} + + +#[test] +fn decimal_power() { + let expr = " + x 2.0 + "; + test("de", "SimpleSpeak", expr, "x to the 2.0"); +} + +#[test] +fn non_simple_power() { + let expr = " + + + 3 + + y+2 + + + "; + test("de", "SimpleSpeak", expr, "3 raised to the y plus 2 power"); +} + +#[test] +fn negative_power() { + let expr = " + + x + - 2 + + "; + test("de", "SimpleSpeak", expr, "x to the negative 2"); +} + +#[test] +fn simple_fraction_power() { + let expr = " + + x + 13 + + "; + test("de", "SimpleSpeak", expr, "x raised to the 1 third power"); +} + +#[test] +fn nested_squared_power_with_coef() { + let expr = " + + + 3 + + 2 + + x + 2 + + + + + "; + test("de", "SimpleSpeak", expr, "3 raised to the 2 x squared power"); +} + +#[test] +fn nested_squared_power_with_neg_coef() { + let expr = " + + + 3 + + - + 2 + + x + 2 + + + + + "; + test("de", "SimpleSpeak", expr, "3 raised to the negative 2 x squared power"); +} + + +#[test] +fn nested_cubed_power() { + let expr = " + + y + + 45 + 3 + + + "; + test("de", "SimpleSpeak", expr, "y raised to the 4 fifths cubed power"); +} + +#[test] +fn nested_cubed_power_with_neg_base() { + let expr = " + + y + + - + + 45 + 3 + + + + "; + test("de", "SimpleSpeak", expr, "y raised to the negative 4 fifths cubed power"); +} + +#[test] +fn nested_number_times_squared() { + let expr = " + + + e + + + 1 + 2 + + + x + 2 + + + + + "; + test("de", "SimpleSpeak", expr, "e raised to the 1 half x squared power"); +} + +#[test] +fn nested_negative_number_times_squared() { + let expr = " + + + e + + + 1 + 2 + + + x + 2 + + + + + "; + test("de", "SimpleSpeak", expr, "e raised to the negative 1 half x squared power"); +} + +#[test] +fn nested_expr_to_tenth() { + let expr = " + + + 3 + + + 3 + + 10 + + + + + "; + test("de", "SimpleSpeak", expr, "3 raised to the 3 to the tenth power"); +} + +#[test] +fn nested_non_simple_squared_exp() { + let expr = " + + + 3 + + + + ( + + x+1 + ) + 2 + + + + + "; + test("de", "SimpleSpeak", expr, "3 raised to the open paren x plus 1, close paren squared power"); +} + +#[test] +fn nested_simple_power() { + let expr = " + + t + + 45 + n + + + "; + test("de", "SimpleSpeak", expr, "t raised to the 4 fifths to the n-th power"); +} + +#[test] +fn nested_end_exponent_power() { + let expr = " + + t + + 45 + n+1 + + + "; + test("de", "SimpleSpeak", expr, "t raised to the 4 fifths raised to the n plus 1 power; end exponent"); + test_prefs("de", "SimpleSpeak", vec![("Impairment", "LearningDisability")], expr, + "t raised to the 4 fifths raised to the n plus 1 power"); +} + +#[test] +fn nested_end_exponent_neg_power() { + let expr = " + + t + + 45 + -3 + + + "; + test("de", "SimpleSpeak", expr, "t raised to the 4 fifths to the negative 3, end exponent"); +} + +#[test] +fn nested_complex_power() { + let expr = " + + + e + + + 1 + 2 + + + + ( + + + + xμ + σ + + + ) + 2 + + + + + "; + test("de", "SimpleSpeak", expr, "e raised to the negative 1 half times; open paren, fraction, x minus mu, over sigma, end fraction; close paren squared power"); +} + +#[test] +fn default_power() { + let expr = " + + t + + b+1 + 3 + + + "; + test("de", "SimpleSpeak", expr, "t raised to the fraction, b plus 1, over 3, end fraction; power"); +} diff --git a/tests/Languages/de/SimpleSpeak/multiline.rs b/tests/Languages/de/SimpleSpeak/multiline.rs new file mode 100644 index 00000000..8edc9d65 --- /dev/null +++ b/tests/Languages/de/SimpleSpeak/multiline.rs @@ -0,0 +1,75 @@ +use crate::common::*; + +#[test] +fn case_1() { + let expr = " + + f( + x + )={ + + + + + 1 if x<0 + + + + + + 0 if x=0 + + + + + + 1 if x>0 + + + + + "; + test("de", "SimpleSpeak", expr, "f of x is equal to; 3 cases; \ + case 1; negative 1 if x; is less than 0; \ + case 2; 0 if x, is equal to 0; \ + case 3; 1 if x, is greater than 0"); +} + +#[test] +fn equation_1() { + let expr = " + + + + + + x+y + + + = + + + 7 + + + + + + 2x+3y + + + = + + + + 17 + + + + + + "; + test("de", "SimpleSpeak", expr, "2 equations; \ + equation 1; x plus y, is equal to 7; \ + equation 2; 2 x plus 3 y; is equal to 17"); +} diff --git a/tests/Languages/de/SimpleSpeak/sets.rs b/tests/Languages/de/SimpleSpeak/sets.rs new file mode 100644 index 00000000..41f76755 --- /dev/null +++ b/tests/Languages/de/SimpleSpeak/sets.rs @@ -0,0 +1,238 @@ +use crate::common::*; + +#[test] +fn complex() { + let expr = " + + "; + test("de", "SimpleSpeak", expr, "the complex numbers"); +} + +#[test] +fn natural() { + let expr = " + + "; + test("de", "SimpleSpeak", expr, "the natural numbers"); +} + +#[test] +fn rationals() { + let expr = " + + "; + test("de", "SimpleSpeak", expr, "the rational numbers"); +} + +#[test] +fn reals() { + let expr = " + + "; + test("de", "SimpleSpeak", expr, "the real numbers"); +} + +#[test] +fn integers() { + let expr = " + + "; + test("de", "SimpleSpeak", expr, "the integers"); +} + + + +#[test] +fn msup_complex() { + let expr = " + + + 2 + + "; + test("de", "SimpleSpeak", expr, "C 2"); +} + +#[test] +fn msup_natural() { + let expr = " + + + 2 + + "; + test("de", "SimpleSpeak", expr, "N 2"); +} + +#[test] +fn msup_rationals() { + let expr = " + + + 2 + + "; + test("de", "SimpleSpeak", expr, "Q 2"); +} + +#[test] +fn msup_reals() { + let expr = " + + + 3 + + "; + test("de", "SimpleSpeak", expr, "R 3"); +} + +#[test] +fn msup_integers() { + let expr = " + + + 4 + + "; + test("de", "SimpleSpeak", expr, "Z 4"); +} + +#[test] +fn msup_positive_integers() { + let expr = " + + + + + + "; + test("de", "SimpleSpeak", expr, "the positive integers"); +} + +#[test] +fn msup_negative_integers() { + let expr = " + + + - + + "; + test("de", "SimpleSpeak", expr, "the negative integers"); +} + +#[test] +fn msup_positive_rationals() { + let expr = " + + + + + + "; + test("de", "SimpleSpeak", expr, "the positive rational numbers"); +} + +#[test] +fn msup_negative_rationals() { + let expr = " + + + - + + "; + test("de", "SimpleSpeak", expr, "the negative rational numbers"); +} + +#[test] +fn empty_set() { + let expr = " + { } + "; + test("de", "SimpleSpeak", expr, "the empty set"); +} + +#[test] +fn single_element_set() { + let expr = " + { 12} + "; + test("de", "SimpleSpeak", expr, "the set 12"); +} + +#[test] +fn multiple_element_set() { + let expr = " + { 5 , 10 , 15 } + "; + test("de", "SimpleSpeak", expr, "the set 5 comma, 10 comma, 15"); +} + +#[test] +fn set_with_colon() { + let expr = " + { x:x>2 } + "; + test("de", "SimpleSpeak", expr, "the set of all x such that x is greater than 2"); +} + +#[test] +fn set_with_bar() { + let expr = " + { x|x>2 } + "; + test("de", "SimpleSpeak", expr, "the set of all x such that x is greater than 2"); +} + +#[test] +fn element_alone() { + let expr = " + 3+2i + "; + test("de", "SimpleSpeak", expr, "3 plus 2 i, is not an element of, the real numbers"); +} + +#[test] +fn element_under_sum() { + let expr = " + + + i + + + 1 + i 2 + + "; + test("de", "SimpleSpeak", expr, + "the sum over i is an element of the integers of; fraction, 1 over, i squared, end fraction"); +} + +#[test] +fn complicated_set_with_colon() { + let expr = " + { + x + + + : + 2 + < + x + < + 7 + } + "; + test("de", "SimpleSpeak", expr, "the set of all x an element of the integers such that 2 is less than x is less than 7"); +} + +#[test] +fn complicated_set_with_mtext() { + // as of 8/5/21, parsing of "|" is problematic an element of the example, so are needed for this test + let expr = " + { + x + | + x  is an even number + } + "; + test("de", "SimpleSpeak", expr, + "the set of all x an element of the natural numbers such that x is an even number"); +} diff --git a/tests/Languages/de/SimpleSpeak/subscripts.rs b/tests/Languages/de/SimpleSpeak/subscripts.rs new file mode 100644 index 00000000..82b022e0 --- /dev/null +++ b/tests/Languages/de/SimpleSpeak/subscripts.rs @@ -0,0 +1,49 @@ +use crate::common::*; + +#[test] +fn msub_simple() { + let expr = " x 1 "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x 1"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Medium")], expr, "x sub 1"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "x sub 1"); + } + +#[test] +fn msub_not_simple() { + let expr = " x 1.2 "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x sub 1.2"); + } + +#[test] +fn msubsup_not_simple() { + let expr = " x 1.2 3 "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x sub 1.2, cubed"); + } + +#[test] +fn msub_simple_mi() { + let expr = " x i "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x sub i"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "x sub i"); +} + +#[test] +fn msub_simple_number_follows() { + let expr = " x 1 102 "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x 1, 10 squared"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "x sub 1, 10 squared"); +} + +#[test] +fn msub_simple_non_number_follows() { + let expr = " x 1 2 "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x 1, squared"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "x sub 1, squared"); +} + +#[test] +fn msubsup_simple() { + let expr = " x 1 x,2 "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x 1, x squared"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "x sub 1, x squared"); +} \ No newline at end of file diff --git a/tests/Languages/de/alphabets.rs b/tests/Languages/de/alphabets.rs new file mode 100644 index 00000000..731e77c3 --- /dev/null +++ b/tests/Languages/de/alphabets.rs @@ -0,0 +1,344 @@ +/// Tests for rules shared between various speech styles: +/// * this has tests focused on the various alphabets +use crate::common::*; + + +/* +#[test] +fn special_alphabet_chars() { + let expr = " ,"; + test("de", "SimpleSpeak", expr, "fraktur cap h comma, fraktur cap c"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "double struck cap h, comma, double struck cap pi"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "script cap i comma, script cap m"); +} + +#[test] +fn greek() { + let expr = " Α,Ω"; + test("de", "SimpleSpeak", expr, "cap alpha comma, cap omega"); + let expr = " α,ω"; + test("de", "SimpleSpeak", expr, "alpha comma, omega"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "double struck cap delta, comma, double struck cap upsilon"); + let expr = " α,ω"; + test("de", "SimpleSpeak", expr, "alpha comma, omega"); +} + +#[test] +fn cap_cyrillic() { + let expr = " А,Я"; + test("de", "SimpleSpeak", expr, "cap a comma, cap ya"); +} + +#[test] +fn parenthesized() { + let expr = " ,"; + test("de", "SimpleSpeak", expr, "parenthesized eigh comma, parenthesized z"); +} + +#[test] +fn circled() { + let expr = " ,"; + test("de", "SimpleSpeak", expr, "circled cap eigh comma, circled cap z"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "circled eigh comma, circled z"); +} + +#[test] +fn fraktur() { + let expr = " 𝔄,𝔜"; + test("de", "SimpleSpeak", expr, "fraktur cap eigh comma, fraktur cap y"); + let expr = " 𝔞,𝔷"; + test("de", "SimpleSpeak", expr, "fraktur eigh comma, fraktur z"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "fraktur cap eigh comma, fraktur cap y"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "fraktur eigh comma, fraktur z"); +} + +#[test] +fn bold_fraktur() { + let expr = " 𝕬,𝖅"; + test("de", "SimpleSpeak", expr, "fraktur bold cap eigh, comma, fraktur bold cap z"); + let expr = " 𝖆,𝖟"; + test("de", "SimpleSpeak", expr, "fraktur bold eigh comma, fraktur bold z"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "fraktur bold cap eigh, comma, fraktur bold cap z"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "fraktur bold eigh comma, fraktur bold z"); +} + +#[test] +fn double_struck() { + let expr = " 𝔸,𝕐"; + test("de", "SimpleSpeak", expr, "double struck cap eigh, comma, double struck cap y"); + let expr = " 𝕒,𝕫"; + test("de", "SimpleSpeak", expr, "double struck eigh comma, double struck z"); + let expr = " 𝟘,𝟡"; + test("de", "SimpleSpeak", expr, "double struck 0 comma, double struck 9"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "double struck cap eigh, comma, double struck cap y"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "double struck eigh comma, double struck z"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "double struck 0 comma, double struck 9"); +} + +#[test] +fn script() { + let expr = " 𝒜,𝒵"; + test("de", "SimpleSpeak", expr, "script cap eigh comma, script cap z"); + let expr = " 𝒶,𝓏"; + test("de", "SimpleSpeak", expr, "script eigh comma, script z"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "script cap eigh comma, script cap z"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "script eigh comma, script z"); +} + +#[test] +fn bold_script() { + let expr = " 𝓐,𝓩"; + test("de", "SimpleSpeak", expr, "eingekreist groß a komma eingekreist groß z"); + let expr = " 𝓪,𝔃"; + test("de", "SimpleSpeak", expr, "script bold eigh comma, script bold z"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "script bold cap eigh, comma, script bold cap z"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "script bold eigh comma, script bold z"); +} + +#[test] +fn bold() { + let expr = " 𝐀,𝐙"; + test("de", "SimpleSpeak", expr, "bold cap eigh comma, bold cap z"); + let expr = " 𝐚,𝐳"; + test("de", "SimpleSpeak", expr, "bold eigh comma, bold z"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "bold cap eigh comma, bold cap z"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "bold eigh comma, bold z"); +} + +#[test] +fn italic() { + let expr = " 𝐴,𝑍"; + test("de", "SimpleSpeak", expr, "cap eigh comma, cap z"); + let expr = " 𝑎,𝑧"; + test("de", "SimpleSpeak", expr, "eigh comma, z"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "cap eigh comma, cap z"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "eigh comma, z"); +} + +#[test] +fn sans_serif() { + let expr = " 𝖠,𝖹"; + test("de", "SimpleSpeak", expr, "cap eigh comma, cap z"); + let expr = " 𝖺,𝗓"; + test("de", "SimpleSpeak", expr, "eigh comma, z"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "cap eigh comma, cap z"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "eigh comma, z"); +} + +#[test] +fn sans_serif_bold() { + let expr = " 𝗔,𝗭"; + test("de", "SimpleSpeak", expr, "bold cap eigh comma, bold cap z"); + let expr = " 𝗮,𝘇"; + test("de", "SimpleSpeak", expr, "bold eigh comma, bold z"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "bold cap eigh comma, bold cap z"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "bold eigh comma, bold z"); +} + +#[test] +fn sans_serif_italic() { + let expr = " 𝘈,𝘡"; + test("de", "SimpleSpeak", expr, "cap eigh comma, cap z"); + let expr = " 𝘢,𝘻"; + test("de", "SimpleSpeak", expr, "eigh comma, z"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "cap eigh comma, cap z"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "eigh comma, z"); +} + +#[test] +fn sans_serif_bold_italic() { + let expr = " 𝘼,𝙕"; + test("de", "SimpleSpeak", expr, "bold cap eigh comma, bold cap z"); + let expr = " 𝙖,𝙯"; + test("de", "SimpleSpeak", expr, "bold eigh comma, bold z"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "bold cap eigh comma, bold cap z"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "bold eigh comma, bold z"); +} + +#[test] +fn monospace() { + let expr = " 𝙰,𝚉"; + test("de", "SimpleSpeak", expr, "cap eigh comma, cap z"); + let expr = " 𝚊,𝚣"; + test("de", "SimpleSpeak", expr, "eigh comma, z"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "cap eigh comma, cap z"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "eigh comma, z"); +} + + +#[test] +fn bold_greek() { + let expr = " 𝚨,𝛀"; + test("de", "SimpleSpeak", expr, "bold cap alpha comma, bold cap omega"); + let expr = " 𝛂,𝛚"; + test("de", "SimpleSpeak", expr, "bold alpha comma, bold omega"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "bold cap alpha comma, bold cap omega"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "bold alpha comma, bold omega"); +} + +#[test] +fn bold_greek_others() { + let expr = " 𝛛,𝛡"; + test("de", "SimpleSpeak", expr, "bold partial derivative, comma, bold pi"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "bold partial derivative, comma, bold pi"); +} + + +#[test] +fn italic_greek() { + let expr = " 𝛢,𝛺"; + test("de", "SimpleSpeak", expr, "cap alpha comma, cap omega"); + let expr = " 𝛼,𝜔"; + test("de", "SimpleSpeak", expr, "alpha comma, omega"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "cap alpha comma, cap omega"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "alpha comma, omega"); +} + +#[test] +fn italic_greek_others() { + let expr = " 𝜕,𝜛"; + test("de", "SimpleSpeak", expr, "partial derivative comma, pi"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "partial derivative comma, pi"); +} + +#[test] +fn bold_italic_greek() { + let expr = " 𝜜,𝜴"; + test("de", "SimpleSpeak", expr, "bold cap alpha comma, bold cap omega"); + let expr = " 𝜶,𝝎"; + test("de", "SimpleSpeak", expr, "bold alpha comma, bold omega"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "bold cap alpha comma, bold cap omega"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "bold alpha comma, bold omega"); +} + +#[test] +fn bold_italic_greek_others() { + let expr = " 𝝏,𝝕"; + test("de", "SimpleSpeak", expr, "bold partial derivative, comma, bold pi"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "bold partial derivative, comma, bold pi"); +} + +#[test] +fn sans_serif_bold_greek() { + let expr = " 𝝖,𝝮"; + test("de", "SimpleSpeak", expr, "bold cap alpha comma, bold cap omega"); + let expr = " 𝝰,𝞈"; + test("de", "SimpleSpeak", expr, "bold alpha comma, bold omega"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "bold cap alpha comma, bold cap omega"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "bold alpha comma, bold omega"); +} + +#[test] +fn sans_serif_bold_greek_others() { + let expr = " 𝞉,𝞏"; + test("de", "SimpleSpeak", expr, "bold partial derivative, comma, bold pi"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "bold partial derivative, comma, bold pi"); +} + +#[test] +fn sans_serif_bold_italic_greek() { + let expr = " 𝞐,𝞨"; + test("de", "SimpleSpeak", expr, "bold cap alpha comma, bold cap omega"); + let expr = " 𝞪,𝟂"; + test("de", "SimpleSpeak", expr, "bold alpha comma, bold omega"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "bold cap alpha comma, bold cap omega"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "bold alpha comma, bold omega"); +} + +#[test] +fn sans_serif_bold_italic_greek_others() { + let expr = " 𝟃,𝟉"; + test("de", "SimpleSpeak", expr, "bold partial derivative, comma, bold pi"); + // MathType private space versions + let expr = " ,"; + test("de", "SimpleSpeak", expr, "bold partial derivative, comma, bold pi"); +} + +#[test] +fn pua_regular() { + let expr = " ,"; + test("de", "SimpleSpeak", expr, "cap eigh comma, cap z"); +} + +#[test] +fn turned() { + let expr = " ,"; + test("de", "SimpleSpeak", expr, "turned cap f comma, turned sans-serif cap y"); + } +*/ +#[test] +fn enclosed_numbers() { + let expr = " ,"; + test("de", "SimpleSpeak", expr, "umkreiste 1 komma umkreiste 9"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "klammern 1 komma klammern 9"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "1 mit periode komma 9 mit periode"); + let expr = " ,"; + test("de", "SimpleSpeak", expr, "doppelt umkreist 1 komma doppelt umkreist 9"); +} diff --git a/tests/Languages/de/chemistry.rs b/tests/Languages/de/chemistry.rs new file mode 100644 index 00000000..e65763e4 --- /dev/null +++ b/tests/Languages/de/chemistry.rs @@ -0,0 +1,737 @@ +/// Tests for rules shared between various speech styles: +/// * modified var +use crate::common::*; + +#[test] +fn salt() { + let expr = "NaCl"; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "groß n a, groß c l"); +} + +#[test] +fn water() { + let expr = "H2O"; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "groß h, 2 groß o"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium")], expr, "groß h, sub 2 groß o"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, "groß h, index 2, groß o"); +} + +#[test] +fn carbon() { + let expr = "C"; // not enough to trigger recognition + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "groß c"); +} + +#[test] +fn sulfate() { + let expr = " + [SO4] + 2 + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium")], expr, "offene eckige klammer, groß s, groß o, sub 4; schließende eckige klammer super 2 minus"); +} + + +/* // ignored below +#[test] +fn aluminum_sulfate() { + let expr = "Al2 + (SO4)3"; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "groß a l, 2, open groß s, groß o, 4, close 3"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium")], expr, "groß a l, sub 2; open paren, groß s, groß o, sub 4; close paren sub 3"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, "groß a l, subscript 2; open paren, groß s, groß o, subscript 4; close paren subscript 3"); +} + +#[test] +fn ethanol_bonds() { + let expr = " + + C + H 3 + + C + H 2 + + O + H + + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "groß c, groß h, 3 single bond groß c, groß h, 2 single bond groß o, groß h"); + +} + +#[test] +fn dichlorine_hexoxide() { + let expr = " + + [ClO2] + + + + + [ClO4] + - + + "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "open bracket, groß c l, groß o, 2, close bracket plus; \ + open bracket, groß c l, groß o, 4, close bracket minus"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Medium")], + expr, "open bracket, groß c l, groß o, sub 2; close bracket super plus; \ + open bracket, groß c l, groß o, sub 4; close bracket super minus"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Verbose")], + expr, "open bracket, groß c l, groß o, subscript 2; close bracket superscript plus; \ + open bracket, groß c l, groß o, subscript 4; close bracket superscript minus"); +} + + +#[test] +fn ethylene_with_bond() { + let expr = " + H2C + = + CH2 + "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "groß h, 2 groß c, double bond groß c, groß h, 2"); +} + +#[test] +fn ferric_chloride_aq() { + let expr = " + Fe + Cl3 + (aq) + "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "groß f e, groß c l, 3 aqueous"); + } + +#[test] +fn ethylene_with_colon_bond() { + let expr = " + H2C + :: + CH2 + "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "groß h, 2 groß c, double bond groß c, groß h, 2"); +} + +#[test] +fn beta_decay() { + let expr = " + + C + + 6 + 14 + + + + N + + 7 + 14 + + + + + e + + + + 1 + + 0 + + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Terse")], expr, + "14, 6, groß c; forms, 14, 7, groß n; plus 0, negative 1, e"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium")], expr, + "super 14, sub 6, groß c; reacts to form; super 14, sub 7, groß n; plus super 0, sub negative 1, e"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, + "superscript 14, subscript 6, groß c; reacts to form; superscript 14, subscript 7, groß n; plus, superscript 0, subscript negative 1, e"); +} + +#[test] +fn mhchem_beta_decay() { + 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 + + + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Terse")], expr, + "14, 6, groß c; forms, 14, 7, groß n; plus 0, negative 1, e"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium")], expr, + "super 14, sub 6, groß c; reacts to form; super 14, sub 7, groß n; plus super 0, sub negative 1, e"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, + "superscript 14, subscript 6, groß c; reacts to form; superscript 14, subscript 7, groß n; plus, superscript 0, subscript negative 1, e"); +} + +#[test] +fn hcl_na_yields() { + let expr = " + 2HCl+2Na + + 2NaCl+ + H 2 + + "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, + "2, groß h, groß c l; plus 2 groß n a; reacts to form; 2, groß n a, groß c l; plus groß h, subscript 2"); +} + +#[test] +fn mhchem_so4_2plus() { + let expr = " + + + SO + + + + + + + A + + + + + + + + 4 + + + + + + + + + + A + + + + + + 2 + + + + + + "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "groß s; groß o, 4, 2 plus"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Medium")], expr, "groß s; groß o, sub 4, super 2 plus"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "groß s; groß o, subscript 4, superscript 2 plus"); +} + + +#[test] +fn mhchem_hcl_aq_etc() { + let expr = " + + 2 + + + + + HCl + + + ( + + aq + + ) + + + + + 2 + + + + + Na + + + ( + + s + + ) + + + + + + 2 + + + + + NaCl + + + ( + + aq + + ) + + + + + + H + + + + + + + A + + + + + + + + 2 + + + + + + ( + + g + + ) + + "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "2, groß h, groß c l, aqueous; plus, 2, groß n a, solid; forms; 2, groß n a, groß c l, aqueous; plus, groß h, 2, gas"); + +} + + +#[test] +fn mhchem_barbed_equilibrium() { + let expr = " + + + + H + 2 + + + + + ( + g + ) + + + + + + + + I + 2 + + + + + ( + g + ) + + + + + + + - + + + - + + + + + 2 + + + H + + I + + + ( + g + ) + + + + + "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "groß h, 2, gas; plus; groß i, 2, gas; is in equilibrium with, 2, groß h, groß i, gas"); +} + + + +#[test] +fn mhchem_roman_in_superscript() { + let expr = " + + + Fe + + II + + + + Fe + + III + + + + O + 4 + + + + "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "groß f e, 2; groß f e, 3; groß o, 4"); +} + + +#[test] +fn dropped_msubsup_bug_358() { + let expr = r#" + + + 2 + + + SO + + 2 + + + + + + + + + O + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + SO + + 3 + + + + + + + + "#; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "2, groß s, groß o, 2; plus; groß o, 2 is in equilibrium with, 2, groß s, groß o, 3"); +} + + + + */ + diff --git a/tests/Languages/de/intent.rs b/tests/Languages/de/intent.rs new file mode 100644 index 00000000..6faaa664 --- /dev/null +++ b/tests/Languages/de/intent.rs @@ -0,0 +1,117 @@ +/// Tests for rules shared between various speech styles: +/// * this has tests focused on the various alphabets +use crate::common::*; + + +#[test] +fn silent_intent() { + let expr = " 2 x "; + test("de", "SimpleSpeak", expr, "2 x"); + test("de", "LiteralSpeak", expr, "2 x"); +} + +#[test] +fn prefix_intent() { + let expr = r#" x T "#; + test("de", "SimpleSpeak", expr, "testing x"); +} + +#[test] +fn postfix_intent() { + let expr = r#" x T "#; + test("de", "SimpleSpeak", expr, "x testing"); +} + +#[test] +fn infix_intent() { + let expr = r#" + x + y + z + "#; + test("de", "SimpleSpeak", expr, "x testing y testing z testing 2"); +} + +#[test] +fn infix_intent_no_args() { + // this is illegal intent, so it is just an mrow with one child + let expr = r#" + x + "#; + test("de", "SimpleSpeak", expr, "x"); +} + +#[test] +fn infix_intent_one_arg() { + let expr = r#" + x + "#; + // Note: we say the intent name because there are infix plus/minus with a single arg due to continued rows or combined columns + test("de", "SimpleSpeak", expr, "testing x"); +} + +#[test] +fn function_intent() { + let expr = r#" + x + y + z + "#; + test("de", "SimpleSpeak", expr, "testing von x komma y komma z komma 2"); +} + +#[test] +fn function_no_args_intent() { + // this is illegal intent, so it is just an mrow with one child + let expr = r#" + x + "#; + test("de", "SimpleSpeak", expr, "x"); +} + +#[test] +fn function_one_arg_intent() { + let expr = r#" + x + "#; + test("de", "SimpleSpeak", expr, "testing von x"); +} + +#[test] +fn silent_intent_mi() { + let expr = " 2 x"; + test("de", "SimpleSpeak", expr, "2"); + test("de", "ClearSpeak", expr, "2"); +} + +#[test] +fn silent_intent_msup() { + let expr = " + + H + 2 + "; + test("de", "SimpleSpeak", expr, "groß h 2"); + test("de", "ClearSpeak", expr, "groß h 2"); +} + +#[test] +fn silent_intent_underscore() { + let expr = " + + H + 2 + "; + test("de", "SimpleSpeak", expr, "groß h 2"); + test("de", "ClearSpeak", expr, "groß h 2"); +} + +#[test] +fn intent_prob_x() { + let expr = " + + x + P + "; + test("de", "ClearSpeak", expr, "wahrscheinlichtkeit von x"); +} diff --git a/tests/Languages/de/mtable.rs b/tests/Languages/de/mtable.rs new file mode 100644 index 00000000..32d33e62 --- /dev/null +++ b/tests/Languages/de/mtable.rs @@ -0,0 +1,1103 @@ +use crate::common::*; + +#[test] +fn matrix_1x1() { + let expr = " + + + ( + + 3 + + ) + + "; + test("de", "ClearSpeak", expr, "die 1 mal 1 matrix mit eintrag 3"); + test("de", "SimpleSpeak", expr, "die 1 mal 1 matrix mit eintrag 3"); +} + +#[test] +fn determinant_1x1() { + let expr = " + + + | + + 3 + + | + + "; + test("de", "ClearSpeak", expr, "die 1 mal 1 determinante mit eintrag 3"); + test("de", "SimpleSpeak", expr, "die 1 mal 1 determinante mit eintrag 3"); +} + + +/* +#[test] +fn matrix_1x2() { + let expr = " + + + ( + + + + 3 + + + 5 + + + + ) + + "; + test("de", "ClearSpeak", expr, "the 1 by 2 row matrix; 3, 5"); + test("de", "SimpleSpeak", expr, "the 1 by 2 row matrix; 3, 5"); +} + + +#[test] +fn matrix_1x3() { + let expr = " + + + ( + + + + -x + + + 5 + + + 12 + + + + ) + + "; + test("de", "ClearSpeak", expr, "the 1 by 3 row matrix; negative x, 5, 12"); + test("de", "SimpleSpeak", expr, "the 1 by 3 row matrix; negative x, 5, 12"); +} + +#[test] +fn matrix_2x1_not_simple() { + let expr = " + + + ( + + + + + x+1 + + + + + + + x-1 + + + + ) + + "; + test("de", "ClearSpeak", expr, "the 2 by 1 column matrix; row 1; x plus 1; row 2; x minus 1"); + test("de", "SimpleSpeak", expr, "the 2 by 1 column matrix; row 1; x plus 1; row 2; x minus 1"); +} +#[test] +fn matrix_3x1_not_simple() { + let expr = " + + + ( + + + + + x + + + + + + + a + + + + + + + x + + x+1 + + + + + + ) + "; + test("de", "SimpleSpeak", expr, "the 3 by 1 column matrix; \ + row 1; x; \ + row 2; eigh; \ + row 3; fraction, x over, x plus 1, end fraction"); + test("de", "ClearSpeak", expr, "the 3 by 1 column matrix; \ + row 1; x; \ + row 2; eigh; \ + row 3; the fraction with numerator x; and denominator x plus 1"); +} + +#[test] +fn determinant_2x2() { + let expr = " + + | + + + + 2 + + + 1 + + + + + 7 + + + 5 + + + + + | + "; + test("de", "ClearSpeak", expr, "the 2 by 2 determinant; row 1; 2, 1; row 2; 7, 5"); + test("de", "SimpleSpeak", expr, "the 2 by 2 determinant; row 1; 2, 1; row 2; 7, 5"); +} + +#[test] +fn matrix_2x3() { + let expr = " + + + [ + + + + 3 + + + 1 + + + 4 + + + + + 0 + + + 2 + + + 6 + + + + ] + + "; + test("de", "ClearSpeak", expr, "the 2 by 3 matrix; row 1; 3, 1, 4; row 2; 0, 2, 6"); + test("de", "SimpleSpeak", expr, "the 2 by 3 matrix; row 1; 3, 1, 4; row 2; 0, 2, 6"); +} + +#[test] +fn matrix_2x3_labeled() { + let expr = " + + + [ + + + + (3.1) + + + 3 + + + 1 + + + 4 + + + + + 0 + + + 2 + + + 6 + + + + ] + + "; + test("de", "ClearSpeak", expr, + "the 2 by 3 matrix; row 1 with label (3.1); column 1; 3, column 2; 1, column 3; 4; \ + row 2; column 1; 0, column 2; 2, column 3; 6"); + test("de", "SimpleSpeak", expr, + "the 2 by 3 matrix; row 1 with label (3.1); column 1; 3, column 2; 1, column 3; 4; \ + row 2; column 1; 0, column 2; 2, column 3; 6"); +} + +#[test] +fn matrix_3x1() { + let expr = " + + + [ + + + + 1 + + + + + 2 + + + + + 3 + + + ] + + "; + test("de", "ClearSpeak", expr, "the 3 by 1 column matrix; 1; 2; 3"); + test("de", "SimpleSpeak", expr, "the 3 by 1 column matrix; 1; 2; 3"); +} + +#[test] +fn matrix_4x1() { + let expr = " + + + ( + + + + 3 + + + + + 6 + + + + + 1 + + + + + 2 + + + + ) + + "; + test("de", "ClearSpeak", expr, "die 4 nach 1 spalte matrix; reihe 1; 3; reihe 2; 6; reihe 3; 1; reihe 4; 2"); + test("de", "SimpleSpeak", expr, "die 4 nach 1 spalte matrix; reihe 1; 3; reihe 2; 6; reihe 3; 1; reihe 4; 2"); +} + +#[test] +fn matrix_4x1_labeled() { + let expr = " + + + ( + + + + 3 + + + + + 6 + + + + + 1 + + + + + (3.1) + + + 2 + + + + ) + + "; + test("de", "ClearSpeak", expr, + "die 4 nach 1 spalte matrix; reihe 1; 3; reihe 2; 6; reihe 3; 1; reihe 4 determinant (3.1); 2"); + test("de", "SimpleSpeak", expr, + "die 4 nach 1 spalte matrix; reihe 1; 3; reihe 2; 6; reihe 3; 1; reihe 4 mit der etikette (3.1); 2"); +} + +#[test] +fn matrix_1x4() { + let expr = " + + + ( + + + + 3 + + + 6 + + + 1 + + + 2 + + + + ) + + "; + test("de", "ClearSpeak", expr, "the 1 by 4 row matrix; column 1; 3, column 2; 6, column 3; 1, column 4; 2"); + test("de", "SimpleSpeak", expr, "the 1 by 4 row matrix; column 1; 3, column 2; 6, column 3; 1, column 4; 2"); +} + +#[test] +fn matrix_4x4() { + let expr = " + + + ( + + + + 0 + + + 3 + + + 4 + + + 3 + + + + + 2 + + + 1 + + + 0 + + + 9 + + + + + 3 + + + 0 + + + 2 + + + 1 + + + + + 6 + + + 2 + + + 9 + + + 0 + + + + ) + + "; + test("de", "ClearSpeak", expr, "the 4 by 4 matrix; \ + row 1; column 1; 0, column 2; 3, column 3; 4, column 4; 3; \ + row 2; column 1; 2, column 2; 1, column 3; 0, column 4; 9; \ + row 3; column 1; 3, column 2; 0, column 3; 2, column 4; 1; \ + row 4; column 1; 6, column 2; 2, column 3; 9, column 4; 0"); + test("de", "SimpleSpeak", expr, "the 4 by 4 matrix; \ + row 1; column 1; 0, column 2; 3, column 3; 4, column 4; 3; \ + row 2; column 1; 2, column 2; 1, column 3; 0, column 4; 9; \ + row 3; column 1; 3, column 2; 0, column 3; 2, column 4; 1; \ + row 4; column 1; 6, column 2; 2, column 3; 9, column 4; 0");} + +#[test] +fn matrix_4x2() { + let expr = " + + + ( + + + + 1 + + + 3 + + + + + 4 + + + 2 + + + + + 2 + + + 1 + + + + + 0 + + + 5 + + + + + ) + + "; + test("de", "ClearSpeak", expr, "the 4 by 2 matrix; \ + row 1; column 1; 1, column 2; 3; \ + row 2; column 1; 4, column 2; 2; \ + row 3; column 1; 2, column 2; 1; \ + row 4; column 1; 0, column 2; 5\ + "); + test("de", "SimpleSpeak", expr, "the 4 by 2 matrix; \ + row 1; column 1; 1, column 2; 3; \ + row 2; column 1; 4, column 2; 2; \ + row 3; column 1; 2, column 2; 1; \ + row 4; column 1; 0, column 2; 5\ + ");} + +// put absolute value test here since it is related to determinate and is small for its own file +#[test] +fn simple_absolute_value() { + let expr = " + | x | + "; + test("de", "SimpleSpeak", expr, "the absolute value of x"); + test("de", "ClearSpeak", expr, "the absolute value of x"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Terse"), ("ClearSpeak_AbsoluteValue", "Auto")], expr, "absolute value of x"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Verbose"), ("ClearSpeak_AbsoluteValue", "AbsEnd")], + expr, "the absolute value of x, end absolute value"); +} + +#[test] +fn absolute_value_plus_1() { +let expr = " + | + x+1 + | + "; + test("de", "ClearSpeak", expr, "der Betrag von x plus 1"); + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Terse"), ("ClearSpeak_AbsoluteValue", "AbsEnd")], + expr, "der betrag von x plus 1, end betrag"); +} + +#[test] +fn simple_cardinality_value() { + let expr = " + | S | + "; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_AbsoluteValue", "Cardinality")], expr, + "the cardinality of cap s"); +} + +// Test preferences +#[test] +fn simple_matrix_speak_col_num() { +let expr = " + + ( + + + + 2 + 1 + + + 7 + 5 + + + ) + "; + test_ClearSpeak("de", "ClearSpeak_Matrix", "SpeakColNum", + expr, "the 2 by 2 matrix; row 1; column 1; 2, column 2; 1; row 2; column 1; 7, column 2; 5"); +} + +#[test] +fn col_matrix_3x1_speak_col_num() { +let expr = " + + ( + + + + 1 + + + 2 + + + 3 + + + ) + "; +test_ClearSpeak("de", "ClearSpeak_Matrix", "SpeakColNum", + expr, "the 3 by 1 column matrix; row 1; 1; row 2; 2; row 3; 3"); +} + +#[test] +fn row_matrix_1x2_speak_col_num() { +let expr = " + + [ + + + + 1 2 + + + ] + "; +test_ClearSpeak("de", "ClearSpeak_Matrix", "SpeakColNum", + expr, "the 1 by 2 row matrix; column 1; 1, column 2; 2"); +} + +#[test] +fn matrix_2x2_speak_col_num() { +let expr = "( + + + b11 + b12 + + + b21 + b22 + + + )"; +test_ClearSpeak("de", "ClearSpeak_Matrix", "SpeakColNum", + expr, "the 2 by 2 matrix; row 1; column 1; b sub 1 1; column 2; b sub 1 2; \ + row 2; column 1; b sub 2 1; column 2; b sub 2 2"); +} + + +#[test] +fn simple_matrix_silent_col_num() { +let expr = " + + ( + + + + 2 + 1 + + + 7 + 5 + + + ) + "; + test_ClearSpeak("de", "ClearSpeak_Matrix", "SilentColNum", + expr, "the 2 by 2 matrix; row 1; 2, 1; row 2; 7, 5"); +} + +#[test] +fn col_matrix_3x1_silent_col_num() { +let expr = " + + ( + + + + 1 + + + 2 + + + 3 + + + ) + "; +test_ClearSpeak("de", "ClearSpeak_Matrix", "SilentColNum", + expr, "the 3 by 1 column matrix; 1; 2; 3"); +} + +#[test] +fn row_matrix_1x2_silent_col_num() { +let expr = " + + [ + + + + 1 2 + + + ] + "; +test_ClearSpeak("de", "ClearSpeak_Matrix", "SilentColNum", + expr, "the 1 by 2 row matrix; 1, 2"); +} + +#[test] +fn matrix_2x2_silent_col_num() { +let expr = "( + + + b11 + b12 + + + b21 + b22 + + + )"; +test_ClearSpeak("de", "ClearSpeak_Matrix", "SilentColNum", + expr, "the 2 by 2 matrix; row 1; b sub 1 1; b sub 1 2; \ + row 2; b sub 2 1; b sub 2 2"); +} + + +#[test] +fn simple_matrix_end_matrix() { +let expr = " + + ( + + + + 2 + 1 + + + 7 + 5 + + + ) + "; + test_ClearSpeak("de", "ClearSpeak_Matrix", "EndMatrix", + expr, "the 2 by 2 matrix; row 1; 2, 1; row 2; 7, 5; end matrix"); +} + +#[test] +fn col_matrix_3x1_end_matrix() { +let expr = " + + ( + + + + 1 + + + 2 + + + 3 + + + ) + "; +test_ClearSpeak("de", "ClearSpeak_Matrix", "EndMatrix", + expr, "the 3 by 1 column matrix; 1; 2; 3; end matrix"); +} + +#[test] +fn row_matrix_1x2_end_matrix() { +let expr = " + + [ + + + + 1 2 + + + ] + "; +test_ClearSpeak("de", "ClearSpeak_Matrix", "EndMatrix", + expr, "the 1 by 2 row matrix; 1, 2; end matrix"); +} + +#[test] +fn matrix_2x2_end_matrix() { +let expr = "( + + + b11 + b12 + + + b21 + b22 + + + )"; +test_ClearSpeak("de", "ClearSpeak_Matrix", "EndMatrix", + expr, "the 2 by 2 matrix; row 1; column 1; b sub 1 1; column 2; b sub 1 2; \ + row 2; column 1; b sub 2 1; column 2; b sub 2 2; end matrix"); +} + + +#[test] +fn simple_matrix_vector() { +let expr = " + + ( + + + + 2 + 1 + + + 7 + 5 + + + ) + "; + test_ClearSpeak("de", "ClearSpeak_Matrix", "Vector", + expr, "the 2 by 2 matrix; row 1; 2, 1; row 2; 7, 5"); +} + +#[test] +fn col_matrix_3x1_vector() { +let expr = " + + ( + + + + 1 + + + 2 + + + 3 + + + ) + "; +test_ClearSpeak("de", "ClearSpeak_Matrix", "Vector", + expr, "the 3 by 1 column vector; 1; 2; 3"); +} + +#[test] +fn row_matrix_1x2_vector() { +let expr = " + + [ + + + + 1 2 + + + ] + "; +test_ClearSpeak("de", "ClearSpeak_Matrix", "Vector", + expr, "the 1 by 2 row vector; 1, 2"); +} + +#[test] +fn matrix_2x2_vector() { +let expr = "( + + + b11 + b12 + + + b21 + b22 + + + )"; +test_ClearSpeak("de", "ClearSpeak_Matrix", "Vector", + expr, "the 2 by 2 matrix; row 1; column 1; b sub 1 1; column 2; b sub 1 2; \ + row 2; column 1; b sub 2 1; column 2; b sub 2 2"); +} + + +#[test] +fn simple_matrix_end_vector() { +let expr = " + + ( + + + + 2 + 1 + + + 7 + 5 + + + ) + "; + test_ClearSpeak("de", "ClearSpeak_Matrix", "EndVector", + expr, "the 2 by 2 matrix; row 1; 2, 1; row 2; 7, 5; end matrix"); +} + +#[test] +fn col_matrix_3x1_end_vector() { +let expr = " + + ( + + + + 1 + + + 2 + + + 3 + + + ) + "; +test_ClearSpeak("de", "ClearSpeak_Matrix", "EndVector", + expr, "the 3 by 1 column vector; 1; 2; 3; end vector"); +} + +#[test] +fn row_matrix_1x2_end_vector() { +let expr = " + + [ + + + + 1 2 + + + ] + "; +test_ClearSpeak("de", "ClearSpeak_Matrix", "EndVector", + expr, "the 1 by 2 row vector; 1, 2; end vector"); +} + +#[test] +fn matrix_2x2_end_vector() { +let expr = "( + + + b11 + b12 + + + b21 + b22 + + + )"; +test_ClearSpeak("de", "ClearSpeak_Matrix", "EndVector", + expr, "the 2 by 2 matrix; row 1; column 1; b sub 1 1; column 2; b sub 1 2; \ + row 2; column 1; b sub 2 1; column 2; b sub 2 2; end matrix"); +} + + + +#[test] +fn matrix_binomial() { + let expr = " + ( + 32 + ) + "; + test_ClearSpeak("de", "ClearSpeak_Matrix", "Combinatorics", expr, "3 choose 2"); +} + +#[test] +fn matrix_times() { + let expr = " + 1234 + abcd + "; + test("de", "SimpleSpeak", expr, + "the 2 by 2 matrix; row 1; 1, 2; row 2; 3, 4; times, the 2 by 2 matrix; row 1; eigh, b; row 2; c, d"); +} + +#[test] +fn unknown_mtable_property() { + let expr = " + + + + a + + + = + + + + b + + + c + + d + + + + + + + + + + e + + f + + + + "; + test("de", "ClearSpeak", expr, + "2 lines; line 1; eigh is equal to, b plus c minus d; line 2; plus e minus f"); +} + + +#[test] +fn zero_matrix() { + let expr = " + [ + + 00 + 00 + + ] + "; + test("de", "SimpleSpeak", expr, + "the 2 by 2 zero matrix"); +} + +#[test] +fn identity_matrix() { + let expr = " + ( + + 100 + 010 + 001 + + ) + "; + test("de", "SimpleSpeak", expr, + "the 3 by 3 identity matrix"); +} + +#[test] +fn diagonal_matrix() { + let expr = " + ( + + 200 + 010 + 00x2 + + ) + "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "the 3 by 3 diagonal matrix; column 1; 2; column 2; 1; column 3; x squared"); + // test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Verbose")], + // expr, "the 3 by 3 diagonal matrix; row 1, column 1, 2; row 2, column 2, 1; row 3, column 3, x squared"); +} + +#[test] +fn single_line_with_label() { + let expr = r#" + + + (2) + 𝑏 = 2 + + + "#; + test_prefs("de", "ClearSpeak", vec![("Verbosity", "Terse")], + expr, "1 line, with label 2; b equals 2"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "1 equation, with label 2; b equals 2"); +} + +*/ \ No newline at end of file diff --git a/tests/Languages/de/shared.rs b/tests/Languages/de/shared.rs new file mode 100644 index 00000000..9c4b8432 --- /dev/null +++ b/tests/Languages/de/shared.rs @@ -0,0 +1,459 @@ +/// Tests for rules shared between various speech styles: +/// * modified var +use crate::common::*; + +#[test] +fn modified_vars() { + let expr = " + a ` + b ~ + c ̆ + b ̌ + c ` + + r ˇ + + x . + y ˙ + z ¨ + u + v + + x ^ + + t + "; + test("de", "SimpleSpeak", expr, + "a gravis akzent; b tilde, c brevis, b combining caron; c gravis akzent; plus r caron plus; x punkt, y Überpunkt, z diaeresis; u dreifacher punkt verschönerung; v vierfacher punkt drüber; plus x zirkumflex, plus vektor t"); +} + +#[test] +fn limit() { + let expr = " + + lim + x 0 + + + + sin x + x + + + "; + test("de", "SimpleSpeak", expr, "der grenzwert bei x gegen 0; von, bruch, sinus von x, über x, ende der fraktion"); + test_prefs("de", "SimpleSpeak", vec![("Impairment", "LearningDisability")], expr, + "der grenzwert bei x gegen 0; von; sinus von x, über x"); +} + +#[test] +fn limit_from_below() { + let expr = " + + lim + x 0 + + + sin x + + "; + test("de", "SimpleSpeak", expr, "der grenzwert bei x annähernd von unten 0; von sinus von x"); +} + + +#[test] +fn binomial_mmultiscripts() { + let expr = "Cmn"; + test("de", "SimpleSpeak", expr, "n wählen m"); +} + +#[test] +fn binomial_mmultiscripts_other() { + let expr = "Cmn"; + test("de", "SimpleSpeak", expr, "n wählen m"); +} + +#[test] +fn binomial_subscript() { // C_{n,k} + let expr = "Cn,m"; + test("de", "SimpleSpeak", expr, "n wählen m"); +} + +#[test] +fn permutation_mmultiscripts() { + let expr = "Pkn"; + test("de", "SimpleSpeak", expr, "k permutationen von n"); +} + +#[test] +fn permutation_mmultiscripts_sup() { + let expr = "Pkn"; + test("de", "SimpleSpeak", expr, "k permutationen von n"); +} + +#[test] +fn permutation_msubsup() { + let expr = "Pkn"; + test("de", "SimpleSpeak", expr, "k permutationen von n"); +} + +#[test] +fn tensor_mmultiscripts() { + let expr = " + R i j k l + "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, + "groß r durch 4 postskripte, subscript i superscript j subscript k subscript l"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Medium")], expr, + "groß r durch 4 postskripte, sub i super j sub k sub l"); +} + +#[test] +fn huge_num_mmultiscripts() { + let expr = " + R i j k l m + I J K L + "; + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, + "groß r durch 4 präskripte, pre subscript groß i, pre superscript groß j und abwechselnde präskripte groß k none groß l none ende der präskripte und durch 5 postskripte, subscript i superscript j subscript k subscript l und wechselnde skripte m none ende der skripte"); +} + +#[test] +fn prime() { + let expr = " x "; + test("de", "SimpleSpeak", expr, "x strich"); +} + +/* +#[test] +fn given() { + let expr = "P(A|B)"; + test("de", "SimpleSpeak", expr, "cap p, open paren, cap a given cap b, close paren"); + test("de", "ClearSpeak", expr, "cap p, open paren, cap a given cap b, close paren"); // not good, but follows the spec +} + +#[test] +fn simple_msubsup() { + let expr = " + + + x + + k + + + i + + + + "; + test("de", "ClearSpeak", expr, "x sub k, to the i-th power"); +} + +#[test] +fn non_simple_msubsup() { + let expr = "ij2k"; + test("de", "SimpleSpeak", expr, "i sub j minus 2 end sub, to the k-th"); + test("de", "ClearSpeak", expr, "i sub j minus 2 end sub, to the k-th power"); + test_prefs("de", "SimpleSpeak", vec![("Impairment", "LearningDisability")], expr, + "i sub j minus 2, to the k-th"); +} + +#[test] +fn presentation_mathml_in_semantics() { + let expr = " + + {\\displaystyle x_k^i} + + + x + + k + + + i + + + + + "; + test("de", "ClearSpeak", expr, "x sub k, to the i-th power"); +} + +#[test] +fn ignore_period() { + // from https://en.wikipedia.org/wiki/Probability + let expr = " + + {\\displaystyle x_k^i} + + + + P + ( + A + + +  and  + + + B + ) + = + P + ( + A + + B + ) + = + P + ( + A + ) + P + ( + B + ) + . + + + + + "; + test("de", "SimpleSpeak", expr, "cap p; open paren, cap a and cap b; close paren; is equal to; cap p, open paren, cap a intersection cap b; close paren; is equal to, cap p of cap eigh, cap p of cap b"); +} + +#[test] +fn ignore_mtext_period() { + let expr = "{2}."; + test("de", "SimpleSpeak", expr, "the set 2"); +} + +#[test] +fn ignore_comma() { + // from https://en.wikipedia.org/wiki/Probability + let expr = " + + + ϕ + ( + x + ) + = + c + + e + + + + h + + 2 + + + + x + + 2 + + + + + , + + +"; + test("de", "SimpleSpeak", expr, "phi of x is equal to; c times, e raised to the negative h squared, x squared power"); +} + +#[test] +#[ignore] // issue #14 +fn ignore_period_and_space() { + // from https://en.wikipedia.org/wiki/Probability + let expr = " + + + P + ( + A + + B + ) + = + + + + P + ( + A + + B + ) + + + P + ( + B + ) + + + + . + + + +"; + test("de", "ClearSpeak", expr, "phi of x is equal to; c, e raised to the negative h squared x squared power"); +} + + +#[test] +fn bug_199_2pi() { + let expr = " + + [ + + 0 + + , + + 2 + π + + ) + + "; + test("de", "SimpleSpeak",expr, "the closed open interval from 0 to 2 pi"); +} + +#[test] +fn caret_and_hat() { + let expr = "x^2+y^"; + test("de", "SimpleSpeak",expr, "x caret 2 plus y hat"); +} + +#[test] +fn mn_with_space() { + let expr = "1 234 567"; + test_prefs("de", "SimpleSpeak", vec![("DecimalSeparators", "."), ("BlockSeparators", " ,")], expr, "1234567"); +} + +#[test] +fn mn_with_block_and_decimal_separators() { + let expr = "1,234.56"; // may want to change this for another language + test_prefs("de", "SimpleSpeak", vec![("DecimalSeparators", "."), ("BlockSeparators", " ,")], expr, "1234.56"); +} + +#[test] +fn divergence() { + let expr = "·F"; // may want to change this for another language + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "dihv cap f"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "divergence of cap f"); +} + +#[test] +fn curl() { + let expr = "×F"; + // may want to change this for another language + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "curl cap f"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "curl of cap f"); +} + +#[test] +fn gradient() { + let expr = "F"; + // may want to change this for another language + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "del cap f"); + test_prefs("de", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "gradient of cap f"); +} + +#[test] +fn literal_speak() { + let expr = r#" + + + A + + + + + B + + + + "#; + test("de", "LiteralSpeak", expr, "cap a right arrow, perpendicular to, cap b right arrow"); +} + +#[test] +fn literal_speak_with_name() { + let expr = r#" + + f + + + ( + + x + ! + + ) + + + "#; + test("de", "LiteralSpeak", expr, "forced f, left paren x exclamation point, right paren"); +} + +#[test] +fn literal_speak_with_property() { + let expr = r#" + + f + + + ( + + x + ! + + ) + + + "#; + test("de", "LiteralSpeak", expr, "f, left paren x exclamation point, right paren"); +} + +#[test] +fn literal_intent_property() { + let expr = r#" + + + A + + + + + B + + + + "#; + test("de", "SimpleSpeak", expr, "cap a right arrow, perpendicular to, cap b right arrow"); +} + +#[test] +fn literal_intent_property_with_name() { + let expr = r#" + + f + + + ( + + x + ! + + ) + + + "#; + test("de", "SimpleSpeak", expr, "forced f, open paren x exclamation point, close paren"); +} +*/ \ No newline at end of file diff --git a/tests/Languages/de/units.rs b/tests/Languages/de/units.rs new file mode 100644 index 00000000..c6a39d8f --- /dev/null +++ b/tests/Languages/de/units.rs @@ -0,0 +1,442 @@ +/// Tests for rules shared between various speech styles: +/// * modified var +use crate::common::*; + +// 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() { + 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("de", "SimpleSpeak", expr, + "quetta-gramms, komma ronna-gramms, komma yotta-gramms, komma zetta-gramms, komma exa-gramms, komma peta-gramms, komma tera-gramms, komma giga-gramms, komma mega-gramms, komma kilo-gramms, komma hekto-gramms, komma deka-gramms, komma dezi-gramms, komma zenti-gramms, komma milli-gramms, komma mikro-gramms, komma nano-gramms, komma piko-gramms, komma femto-gramms, komma atto-gramms, komma zepto-gramms, komma yocto-gramms, komma ronto-gramms, komma quecto-gramms"); +} + +#[test] +fn si_base() { + let expr = r#" + 1A,2A, + 1cd,2cd, + 1K,2K, + 1,2, + 1g,2g, + 1m,2m, + 1mol,2mol, + 1s,2s, + 1,2, + 1",2", + 1sec,2sec + "#; + test("de", "SimpleSpeak", expr, + "1 ampere, komma 2 amperes, komma 1 candela, komma 2 candelas, komma 1 kelvin, komma 2 kelvins, komma 1 kelvin, komma 2 kelvins, komma 1 gramm komma 2 gramms, komma 1 meter komma 2 meters, komma 1 mol komma 2 mols, komma 1 sekunde, komma 2 sekundes, komma 1 sekunde, komma 2 sekundes, komma 1 sekunde, komma 2 sekundes, komma 1 sekunde, komma 2 sekundes"); +} + +/* +#[test] +fn si_base_with_prefixes() { + let expr = r#" + 1QA,2RA, + 1Ycd,2Zcd, + 1EK,2PK, + 1TK,2GK, + 1Mg,2kg, + 1hm,2dam, + 1dmol,2cmol, + 1ms,2µs, + 1nsec,2psec + "#; + test("de", "SimpleSpeak", expr, + "1 quetta-ampere, komma, 2 ronna-amperes, komma 1 yotta-candela, komma, 2 zetta-candelas, komma 1 exa-kelvin, komma, 2 peta-kelvins, komma 1 tera-kelvin, komma, 2 giga-kelvins, komma 1 mega-gramm, komma, 2 kilo-gramms, komma 1 hekto-meter, komma, 2 deka-meters, komma 1 dezi-mol, komma, 2 zenti-mols, komma 1 milli-sekunde, komma, 2 mikro-sekundes, komma 1 nano-sekunde, komma, 2 piko-sekundes"); +} + + +#[test] +fn si_derived_1() { + 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("de", "SimpleSpeak", expr, + "1 becquerel, comma; 2 becquerels, komma \ + 1 coulomb, comma; 2 coulombs, comma; \ + 1 degree celsius, comma; 2 degrees celsius, comma; \ + 1 degree celsius, comma; 2 degrees celsius, komma \ + 1 farad, komma 2 farads, komma \ + 1 gray, komma 2 grays, komma \ + 1 henry, komma 2 henrys, komma \ + 1 hertz, komma 2 hertz, komma \ + 1 joule, komma 2 joules, komma \ + 1 kattel, komma 2 kattels, komma \ + 1 lumen, komma 2 lumens, komma \ + 1 lux, komma 2 luxs"); +} + +#[test] +fn si_derived_1_with_prefixes() { + 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("de", "SimpleSpeak", expr, + "1 quetta-becquerel, comma; 2 ronna-becquerels; comma; \ + 1 yotta-coulomb, comma; 2 zetta-coulombs, comma; \ + 1 exa-farad, comma; 2 peta-farads, comma; \ + 1 tera-gray, comma; 2 giga-grays, comma; \ + 1 mega-henry, comma; 2 kilo-henrys, comma; \ + 1 deka-hertz, comma; 2 dezi-hertz, comma; \ + 1 zenti-joule, comma; 2 milli-joules, comma; \ + 1 micro-kattel, comma; 2 nano-kattels, comma; \ + 1 pico-lumen, comma; 2 femto-lumens, comma; \ + 1 atto-lux, comma; 2 zepto-luxs, comma; \ + 1 milli-degree celsius; comma; 2 micro-degrees celsius; comma; \ + 1 pico-degree celsius; comma; 2 nano-degrees celsius"); +} + +#[test] +fn si_derived_2() { + let expr = r#" + 1N,2N, + 1Ω,2Ω, + 1,2, + 1Pa,2Pa, + 1S,2S, + 1Sv,2Sv, + 1T,2T, + 1V,2V, + 1W,2W, + 1Wb,2Wb + "#; + test("de", "SimpleSpeak", expr, + "1 newton, komma 2 newtons, komma \ + 1 ohm, komma 2 ohms, komma \ + 1 ohm, komma 2 ohms, komma \ + 1 pascal, komma 2 pascals, komma \ + 1 siemens, komma 2 siemens, komma \ + 1 sievert, comma; 2 sieverts, komma \ + 1 tesla, komma 2 teslas, komma \ + 1 volt, komma 2 volts, komma \ + 1 watt, komma 2 watts, komma \ + 1 weber, komma 2 webers"); +} + +#[test] +fn si_derived_2_with_prefixes() { + let expr = r#" + 1qN,2rN, + 1,2, + 1aΩ,2fΩ, + 1pPa,2nPa, + 1µS,2mS, + 1cSv,2dSv, + 1daT,2hT, + 1kV,2MV, + 1GW,2TW, + 1PWb,2EWb + "#; + test("de", "SimpleSpeak", expr, + "1 quecto-newton, comma; 2 ronto-newtons, comma; \ + 1 yocto-ohm, comma; 2 zepto-ohms, comma; \ + 1 atto-ohm, comma; 2 femto-ohms, comma; \ + 1 pico-pascal, comma; 2 nano-pascals, comma; \ + 1 micro-siemens, comma; 2 milli-siemens, comma; \ + 1 zenti-sievert, comma; 2 dezi-sieverts, comma; \ + 1 deka-tesla, comma; 2 hekto-teslas, comma; \ + 1 kilo-volt, comma; 2 mega-volts, comma; \ + 1 giga-watt, comma; 2 tera-watts, comma; \ + 1 peta-weber, comma; 2 exa-webers"); +} + + +#[test] +fn si_accepted() { + 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("de", "SimpleSpeak", expr, + "1 litre, komma 2 litres, komma \ + 1 litre, komma 2 litres, komma \ + 1 litre, komma 2 litres, komma \ + 1 metric ton, comma; 2 metric tons, komma \ + 1 dalton, komma 2 daltons, komma \ + 1 neper, komma 2 nepers, comma; \ + 1 atomic mass unit, comma; 2 atomic mass units, comma; \ + 1 electronvolt, comma; 2 electronvolts, komma \ + 1 radian, komma 2 radians, komma \ + 1 sterradion, comma; 2 sterradions, komma \ + 1 annum, komma 2 annums, komma \ + 1 arcsecond, comma; 2 arcseconds, komma \ + 1 bit, komma 2 bits, komma \ + 1 byte, komma 2 bytes, komma \ + 1 baud, komma 2 bauds"); +} + +#[test] +fn si_accepted_with_prefixes() { + 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("de", "SimpleSpeak", expr, + "1 quetta-liter, komma, 2 ronna-liters, komma 1 yotta-liter, komma, 2 zetta-liters, komma 1 exa-liter, komma, 2 peta-liters, komma 1 tera-tonne, komma, 2 giga-tonnes, komma 1 mega-dalton, komma, 2 kilo-daltons, komma 1 dezi-neper, komma, 2 zenti-nepers, komma, 1 hekto-atommasse-einheit; komma, 2 deka-atommasse-einheits; komma, 1 milli-elektronenvolt, komma, 2 mikro-elektronenvolts; komma 1 nano-radiant, komma, 2 piko-radiants, komma, 1 femto-steradiant, komma, 2 atto-steradiants, komma 1 giga-jahr, komma, 2 mega-jahrs, komma, 1 zepto-bogensekunde, komma, 2 yocto-bogensekundes; komma 1 kilo-bit, komma 2 mega-bits, komma 1 giga-byte, komma, 2 tera-bytes, komma 1 tera-baud, komma 2 exa-bauds"); +} + +#[test] +fn without_prefix_time() { + 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("de", "SimpleSpeak", expr, + "1 second, komma 2 seconds, komma \ + 1 second, komma 2 seconds, komma \ + 1 minute, komma 2 minutes, komma \ + 1 minute, komma 2 minutes, komma \ + 1 minute, komma 2 minutes, komma \ + 1 hour, komma 2 hours, komma \ + 1 hour, komma 2 hours, komma \ + 1 hour, komma 2 hours, komma \ + 1 day, komma 2 days, komma \ + 1 day, komma 2 days, komma \ + 1 week, komma 2 weeks, komma \ + 1 week, komma 2 weeks, komma \ + 1 year, komma 2 years, komma \ + 1 year, komma 2 years"); +} + +#[test] +fn without_prefix_angles() { + let expr = r#" + 1°,2°, + 1deg,2deg, + 1arcmin,2arcmin, + 1amin,2amin, + 1am,2am, + 1MOA,2MOA, + 1arcsec,2arcsec, + 1asec,2asec + "#; + test("de", "SimpleSpeak", expr, + "1 degree, komma 2 degrees, komma \ + 1 degree, komma 2 degrees, komma \ + 1 arcminute, comma; 2 arcminutes, komma \ + 1 arcminute, comma; 2 arcminutes, komma \ + 1 arcminute, comma; 2 arcminutes, komma \ + 1 arcminute, comma; 2 arcminutes, komma \ + 1 arcsecond, comma; 2 arcseconds, komma \ + 1 arcsecond, comma; 2 arcseconds"); +} + +#[test] +fn without_prefix_distance() { + let expr = r#" + 1au,2au, + 1ltyr,2ltyr, + 1pc,2pc, + 1Å,2Å, + 1,2, + 1fm,2fm + "#; + test("de", "SimpleSpeak", expr, + "1 astronomical unit, comma; 2 astronomical units, komma \ + 1 light year, comma; 2 light years, komma \ + 1 parsec, komma 2 parsecs, komma \ + 1 angstrom, comma; 2 angstroms, komma \ + 1 angstrom, comma; 2 angstroms, komma \ + 1 fermi, komma 2 fermis"); +} + +#[test] +fn without_prefix_other() { + 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("de", "SimpleSpeak", expr, + "1 hectare, comma; 2 hectares, komma \ + 1 dezibel, comma; 2 dezibels, komma \ + 1 atmosphere, comma; 2 atmospheres, comma; \ + 1 atomic mass unit, comma; 2 atomic mass units, komma \ + 1 bar, komma 2 bars, komma \ + 1 calorie, comma; 2 calories, komma \ + 1 curie, komma 2 curies, komma \ + 1 gradian, comma; 2 gradians, komma \ + 1 molar, komma 2 molars, komma \ + 1 roentgen, comma; 2 roentgens, comma; \ + 1 revolution per minute, comma; 2 revolutions per minute, komma \ + 1 m-h-o, komma 2 m-h-os, komma \ + 1 dyne, komma 2 dynes, komma \ + 1 erg, komma 2 ergs"); +} + +#[test] +fn without_prefix_powers_of_2() { + 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("de", "SimpleSpeak", expr, + "1 kibi-bit, comma; 2 kibi-bits, komma \ + 1 mebi-bit, comma; 2 mebi-bits, komma \ + 1 gibi-bit, comma; 2 gibi-bits, komma \ + 1 tebi-bit, comma; 2 tebi-bits, komma \ + 1 pebi-bit, comma; 2 pebi-bits, komma \ + 1 exbi-bit, comma; 2 exbi-bits, komma \ + 1 zebi-bit, comma; 2 zebi-bits, komma \ + 1 yobi-bit, comma; 2 yobi-bits, komma \ + 1 kibi-byte, comma; 2 kibi-bytes, komma \ + 1 mebi-byte, comma; 2 mebi-bytes, komma \ + 1 gibi-byte, comma; 2 gibi-bytes, komma \ + 1 tebi-byte, comma; 2 tebi-bytes, komma \ + 1 pebi-byte, comma; 2 pebi-bytes, komma \ + 1 exbi-byte, comma; 2 exbi-bytes, komma \ + 1 zebi-byte, comma; 2 zebi-bytes, komma \ + 1 yobi-byte, comma; 2 yobi-bytes"); +} + + +#[test] +fn si_other_numbers() { + let expr = r#"1.0l, + 2.0 m, + x ms, + yµs, + dag, + 1235daN, + 2.5µsec, + 32.34mol"#; + test("de", "SimpleSpeak", expr, + "1.0 litre, comma; 2.0 metres, comma; x milli-seconds, comma; y micro-seconds, komma \ + deka-grams, comma; 1235 deka-newtons; comma; 2.5 micro-seconds; comma; 32.34 moles"); +} + + +#[test] +fn test_mtext_inference() { + let expr = r#"[ + 1t, + 2PA, + 3Pa, + 4.5mT + ]"#; + test("de", "SimpleSpeak", expr, + "open bracket; 1 metric ton, comma; 2 peta-amps, komma \ + 3 pascals, comma; 4.5 milli-teslas; close bracket"); +} + + + */ \ No newline at end of file