diff --git a/Rules/Languages/nb/ClearSpeak_Rules.yaml b/Rules/Languages/nb/ClearSpeak_Rules.yaml new file mode 100644 index 000000000..e30f57c3f --- /dev/null +++ b/Rules/Languages/nb/ClearSpeak_Rules.yaml @@ -0,0 +1,784 @@ +--- +- 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(10 'minus' 4 equals 6) + - x: "translate(text(), '-_', '')" + +- name: default + tag: square-root + match: "." + replace: + - test: + if: $ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd' + then: + - bookmark: "*[1]/@id" + - test: + if: parent::*[self::m:minus and count(*)=1] + then: [T: "den negative"] # phrase(minus 4 is a 'negative' number) + else: [T: "den positive"] # phrase(10 is a 'positive' number) + - test: + if: "$Verbosity!='Terse'" + then: [T: "kvadratroten av"] # phrase(the square root 'of' 5) + else: [T: "roten av"] + - x: "*[1]" + - test: + - if: "$ClearSpeak_Roots = 'RootEnd' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" + then: + - pause: short + - T: "slutt rot" # phrase(the square root of x 'end root') + - pause: medium + - else_if: "IsNode(*[1], 'simple')" + then: [pause: short] + else: [pause: long] + +- name: default + tag: root + match: "." + replace: + - test: + if: $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: "den negative"] # phrase(minus 6 is a 'negative' number) + else: [T: "den positive"] # phrase(10 is a 'positive' number) + - test: + if: "*[2][self::m:mn and not(contains(., $DecimalSeparators))]" #NORWEGIAN: Changed decimal point to $DecimalSeparators + then_test: + - if: "*[2][.='2']" + then: [T: "kvadratroten"] # phrase(5 is the 'square root' of 25) + - else_if: "*[2][.='3']" + then: [T: "kubikkroten"] # phrase(5 is the 'cube root' of 625) + - else: [x: "ToOrdinal(*[2])", T: "roten"] # phrase(the square 'root' of 25) + else: + - T: "roten av grad" # phrase(the square 'root' of 36) + - x: "*[2]" + - pause: short + # SWEDISH/NORWEGIAN: Removed verbosity settings. + - T: "av" # phrase(the square root 'of' 36) + - x: "*[1]" + - test: + if: $ClearSpeak_Roots = 'RootEnd' or $ClearSpeak_Roots = 'PosNegSqRootEnd' + then: + - pause: short + - T: "slutt rot" # phrase(start the fifth root of x 'end root') + - pause: medium + else_test: + if: IsNode(*[1], 'simple') + then: [pause: short] + else: [pause: long] + +# The 'negative' rule interacts with the msqrt/mroot rules as those might pick off this case ("the negative square root of x") +- name: negative_and_positive + tag: [plus, minus] + match: "count(*)=1 and contains(@data-intent-property, ':prefix:')" + replace: + - test: + if: + - "*[1][self::m:square-root or self::m:root] and" + - "($ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd')" + then: {T: ""} + else: + - bookmark: "@id" + - test: + if: "self::m:minus" + then: [T: "minus"] # phrase(minus 5 is a 'negative' number) + else: [T: "pluss"] # phrase(7 is a 'positive' number) + - x: "*[1]" + +# Fraction rules +# Mixed numbers mostly "just work" because the invisible char reads as "and" and other parts read properly on their own + +# Units (e.g., meters per second) +# NORWEGIAN: Added rule for t="time" +- 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') or (contains(@data-intent-property, ':unit') and .='t')] )" + replace: + - x: "*[1]" + - T: "per" # phrase('5 meters 'per' second) + - test: + if: "*[2]='t'" + then: [T: "time"] + else: + - x: "*[2]" + +- name: common-fraction + tag: fraction + match: + - "($ClearSpeak_Fractions='Auto' or $ClearSpeak_Fractions='Ordinal' or $ClearSpeak_Fractions='EndFrac') and" + - "*[1][self::m:mn][not(contains(., $DecimalSeparators)) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and" #NORWEGIAN: Changed decimal point to $DecimalSeparators + - "*[2][self::m:mn][not(contains(., $DecimalSeparators)) and (2<= text() and text()<=10)]" #NORWEGIAN: Removed $ClearSpeak_Fractions='Ordinal', cause the pattern for ordinal fractions is not right. + 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 + - "($ClearSpeak_Fractions='Auto' or $ClearSpeak_Fractions='Ordinal' or $ClearSpeak_Fractions='EndFrac') and" + - "*[1][self::m:mn][not(contains(., $DecimalSeparators)) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and" #NORWEGIAN: Changed decimal point to $DecimalSeparators + - "*[2][self::m:mn][not(contains(., $DecimalSeparators)) and (2<= text() and text()<=10)]" #NORWEGIAN: Removed $ClearSpeak_Fractions='Ordinal', cause the pattern for ordinal fractions is not right. + variables: [IsPlural: "*[1]!=1"] + replace: + - x: "*[1]" + - x: "ToOrdinal(*[2], true(), $IsPlural)" # extra args specify fractional ordinal and whether it is plural + +#NORWEGIAN: Changed to English version, but changed decimal point to $DecimalSeparators +- 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: [T: "brøken"] # phrase(the 'fraction' with 3 over 4) + else: [T: "brøk"] + - x: "*[1]" + - T: "over" # phrase(the fraction 3 'over' 4) + - 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(., $DecimalSeparators)) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and *[2][self::m:mn][not(contains(., $DecimalSeparators)) and ($ClearSpeak_Fractions='Ordinal' or (2<= text() and text()<=10))] ] and *[2][*[1][self::m:mn][not(contains(., $DecimalSeparators)) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and *[2][self::m:mn][not(contains(., $DecimalSeparators)) and ($ClearSpeak_Fractions='Ordinal' or (2<= text() and text()<=10))] ] ) )" + then: + - pause: short + - T: "slutt brøk" # phrase(7 over 8 'end fraction') + - pause: short + +- # fraction with text or numbers followed by text in both numerator and denominator + name: fraction-over-text + tag: fraction + match: + - "not($ClearSpeak_Fractions='General' or $ClearSpeak_Fractions='GeneralEndFrac') and" + - "( " + - " ((*[1][self::m:mi or self::m:mtext][string-length(.)>1]) or " # fractions with text + - " (*[1][self::m:mrow][count(*)=3][ " + - " *[1][self::m:mn] and " + - " *[2][self::m:mo][.='⁢'] and " # invisible times + - " *[3][self::m:mi or self::m:mtext][string-length(.)>1] ]) ) and" + - " ((*[2][self::m:mi or self::m:mtext][string-length(.)>1]) or " # fractions with text + - " (*[2][self::m:mrow][count(*)=3][ " + - " *[1][self::m:mn] and " + - " *[2][self::m:mo][.='⁢'] and " # invisible times + - " *[3][self::m:mi or self::m:mtext][string-length(.)>1] ]) )" + - ")" + replace: + - pause: short + - x: "*[1]" + - T: "over" # phrase(the fraction 3 'over' 4) + - x: "*[2]" + - test: + if: "$ClearSpeak_Fractions='EndFrac' or $ClearSpeak_Fractions='OverEndFrac'" + then: + - pause: short + - T: "slutt brøk" # phrase(7 over 8 'end fraction') + - pause: short + +#NORWEGIAN: Changed to English version +- name: default + tag: fraction + match: "." + replace: + - T: "brøken med teller" # phrase(the 'fraction with numerator' 6) + - test: + if: not(IsNode(*[1], 'simple')) + then: [pause: medium] + - x: "*[1]" + - pause: medium + - T: "og nevner" # phrase(the fraction with numerator 5 'and denominator' 8) + - x: "*[2]" + - pause: medium + - test: + if: "$ClearSpeak_Fractions='EndFrac' or $ClearSpeak_Fractions='GeneralEndFrac'" + then: + - pause: short + - T: "slutt brøk" # phrase(the fraction with 3 over 4 'end fraction') + - pause: short + +# rules for functions raised to a power +# these could have been written on 'mrow' but putting them on msup seems more specific +# to see if it is a function, we look right to see if the following sibling is apply-function +- name: ClearSpeak-function-inverse + tag: inverse-function + match: "." + replace: + - test: + if: $ClearSpeak_Trig = 'TrigInverse' + then: [{x: "*[1]"}, {bookmark: "*[2]/@id"}, T: "invers"] # phrase(8 over 5 is the 'inverse' of 5 over 8) + else_test: + if: $ClearSpeak_Trig = 'ArcTrig' + then: [bookmark: "*[2]/@id", T: "arcus", x: "*[1]"] # phrase(the 'buelenge' of a circle) + else: [bookmark: "*[2]/@id", T: "invers", x: "*[1]"] # default/Auto # phrase(8 over 5 is the 'inverse' of 5 over 8) + + +- 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: "i andre"] # phrase(25 equals 5 'squared') + else: [T: "i tredje"] # phrase(625 equals 5 'cubed') + +- name: function-power + tag: power + match: + - "following-sibling::*[1][self::m:mo][.='⁡']" #invisible function apply + replace: + - x: "*[1]" + - T: "opphøyd i" + - bookmark: "*[2]/@id" + - x: "*[2]" + - pause: short + +- 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: "opphøyd i eksponenten" # phrase(5 'raised to the exponent' x plus 1) + - pause: short + - x: "*[2]" + - pause: short + - T: "slutt eksponent" # phrase(5 raised to the exponent x plus 1 'end exponent') + +- name: AfterPower-default + tag: power + match: "$ClearSpeak_Exponents = 'AfterPower'" + replace: + - x: "*[1]" + - T: "opphøyd i" # phrase(x is 'raised to the power' 4) + - x: "*[2]" + - pause: short + +- name: squared + tag: power + match: "*[2][self::m:mn][.='2'] and $ClearSpeak_Exponents = 'Auto'" + replace: + - x: "*[1]" + - bookmark: "*[2]/@id" + - T: "i andre" # phrase(7 'squared' equals 49) + +- name: cubed + tag: power + match: "*[2][self::m:mn][.='3'] and $ClearSpeak_Exponents = 'Auto'" + replace: + - x: "*[1]" + - bookmark: "*[2]/@id" + - T: "i tredje" # phrase(5 'cubed' equals 125) + +- name: simple-integer + tag: power + match: "*[2][self::m:mn][not(contains(., $DecimalSeparators))]" #NORWEGIAN: Changed decimal point to $DecimalSeparators + replace: + - x: "*[1]" + - T: "opphøyd i" + - bookmark: "*[2]/@id" + - x: "*[2]" + - pause: short + +- name: simple-negative-integer + tag: power + match: + - "*[2][self::m:minus and count(*)=1 and" + - " *[1][self::m:mn][not(contains(., $DecimalSeparators))]" #NORWEGIAN: Changed decimal point to $DecimalSeparators + - " ]" + replace: + - x: "*[1]" + - T: "opphøyd i" + - bookmark: "*[2]/@id" + - x: "*[2]" + - pause: short + +- name: simple-var + tag: power + match: "*[2][self::m:mi][string-length(.)=1]" + replace: + - x: "*[1]" + - T: "opphøyd i" + - bookmark: "*[2]/@id" + - x: "*[2]" + - pause: short + +# 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(., $DecimalSeparators)) and text()<20] and" #NORWEGIAN: Changed decimal point to $DecimalSeparators + - " *[2][self::m:mn][not(contains(., $DecimalSeparators)) and 2<= text() and text()<=10]]" + - " ]" + - " ]" + replace: + - x: "*[1]" + - T: "opphøyd i" # phrase(x 'raised to the' second power) + - 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(., $DecimalSeparators)) and text()<20] and" #NORWEGIAN: Changed decimal point to $DecimalSeparators + - " *[2][self::m:mn][not(contains(., $DecimalSeparators)) and 2<= text() and text()<=10]]" + - " ]" + - " ]" + - " ]" + replace: + - x: "*[1]" + - T: "opphøyd i" # phrase(x 'raised to the' second power) + - 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(., $DecimalSeparators)) and text()<20] and" #NORWEGIAN: Changed decimal point to $DecimalSeparators + - " *[2][self::m:mn][not(contains(., $DecimalSeparators)) and 2<= text() and text()<=10]]" + - " ]" + - " ]" + replace: + - x: "*[1]" + - T: "opphøyd i" # phrase(x 'raised to the' second power) + - 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(., $DecimalSeparators)) and text()<20] and" #NORWEGIAN: Changed decimal point to $DecimalSeparators + - " *[2][self::m:mn][not(contains(., $DecimalSeparators)) and 2<= text() and text()<=10]]" + - " ]" + - " ]" + - " ]" + replace: + - x: "*[1]" + - T: "opphøyd i" # phrase(x 'raised to the' second power) + - 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: "opphøyd i eksponenten" # phrase(x is 'raised to the exponent') + - pause: short + - x: "*[2]" + - pause: short + - T: "slutt eksponent" # phrase(and now 'end exponent' has been reached) + +- name: default + tag: power + match: "." + replace: + - x: "*[1]" + - T: "opphøyd i" # phrase(x 'raised to the' second power) + - 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: "." + # SWEDISH/NORWEGIAN: Differentiate between the initial and ending declaration of the terms. + # NORWEGIAN: Say "kardinaliteten til", but "absoluttverdien av" + variables: + - WordToSay: "IFTHENELSE($ClearSpeak_AbsoluteValue = 'Cardinality', 'kardinaliteten til', 'absoluttverdien av')" + - EndToSay: "IFTHENELSE($ClearSpeak_AbsoluteValue = 'Cardinality', 'kardinalitet', 'absoluttverdi')" + replace: + - x: "$WordToSay" + - x: "*[1]" + - test: + if: "$ClearSpeak_AbsoluteValue = 'AbsEnd'" + then: + - pause: short + - T: "slutt" # phrase('end' absolute value) + - x: "$EndToSay" + - pause: short + +- name: set + tag: set + match: "." + replace: + - test: + - if: "count(*)=0" + then: [T: "den tomme mengden"] # phrase('the empty set') + - else_if: "count(*)=2" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: "den"] # phrase('the' empty set) + - T: "tomme mengden" # phrase(the 'empty set') + - else_if: "count(*[1]/*)=3 and *[1]/*[2][self::m:mo][.=':' or .='|' or .='∣']" + then: + - T: "mengden av" # phrase(this is a 'set of' numbers) + - test: + if: $ClearSpeak_Sets != 'woAll' + then: [T: "alle"] # phrase(the set of 'all' integers) + - x: "*[1]/*[1]" + - T: "slik at" # phrase(the set S 'such that' x is less than y) + - x: "*[1]/*[3]" + else: + - test: + if: $ClearSpeak_Sets != 'SilentBracket' + then: + - T: "mengden" # phrase(this is a 'set' of integers) + - x: "*[1]" + +#- # intervals are controlled by a ClearSpeak Preference -- parens/brackets don't have to match, so we avoid IsBracketed +# # alternatively, we could have four (or ten) rules, but there is a lot of duplication if we do that +# # this one rule handles all ten cases listed as part $ClearSpeak_Paren = 'Interval' +# # note that *[2] is an mrow with X, ",", Y, so getting X or Y is a double index + # onto the [not] [including]... part + + # SWEDISH/NORWEGIAN: rewrote the intervals function to better deal with Swedish/Norwegian convention of speaking intervals + # NORWEGIAN: Removed test for verbosity, cause you should always say "det åpne" etc. +- 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: + - test: + - if: "name(.)='open-interval'" + then: [T: "det åpne"] + - else_if: "name(.)='open-closed-interval' or name(.)='closed-open-interval'" + then: [T: "det halvåpne"] + - else_if: "name(.)='closed-interval'" + then: [T: "det lukkede"] + - T: "intervallet fra" # phrase('the interval from' a to b) + - test: + - if: "name(.)='closed-open-interval'" + then: [T: "og med"] + - x: "*[1]" + - T: "til" # phrase(the interval from a 'to' b) + - test: + - if: "name(.)='open-closed-interval'" + then: [T: "og med"] + - x: "*[2]" + +- name: binomial-frac-vector + tag: matrix + match: + - "$ClearSpeak_Matrix = 'Combinatorics' and " + - "count(*[1]/*)=1 and count(*)=2" + replace: + - x: "*[1]/*[1]/*" # mtable/mtr/mtd + - T: "over" # phrase(the binomial coefficient n 'choose' m) + - x: "*[2]/*[1]/*" + +- name: ClearSpeak-default + tag: [mtr, mlabeledtr] + match: "parent::m:matrix or parent::m:determinant" + variables: [NextLineIsContinuedRow: "following-sibling::*[1][contains(@data-intent-property, ':continued-row:')]"] + replace: + - pause: medium + - T: "rad" # phrase(the first 'row' of a matrix) + - x: "count(preceding-sibling::*)+1" + - test: + if: .[self::m:mlabeledtr] + then: + - T: "med etiketten" # phrase(the line 'with label' first equation) + - x: "*[1]/*" + - pause: short + - pause: medium + - test: + if: .[self::m:mlabeledtr] + then: [x: "*[position()>1]"] + else: {x: "*"} + +- # handle both log and ln + name: ClearSpeak-log + tag: mrow + variables: [{log_is_simple: "IsNode(*[3],'simple')"}] + match: + - "count(*)=3 and" + - "*[1][self::m:mi][.='log' or .='ln' or .='lg'] and" + - "*[2][self::m:mo][.='⁡']" + replace: + - test: + if: "$log_is_simple" + then_test: + - if: "*[1][.='log']" + then: [T: "log av"] # phrase(the 'log' of x) + - else_if: "*[1][.='lg']" + then: [{spell: "'lg'"}, {T: "av"}] # phrase(the 'lg' of x) + - else_if: $ClearSpeak_Log = 'LnAsNaturalLog' or $Verbosity='Verbose' + then: [T: "den naturlige logaritmen av"] # phrase(the 'natural log' of the product of 2 numbers) + else: [{spell: "'ln'"}, {T: "av"}] + else: + - test: + - if: "*[1][.='log']" + then: + - test: + - if: "$Verbosity='Verbose'" + then: [T: "logaritmen"] + else: [T: "log"] + - else_if: "*[1][.='lg']" + then: + - test: + - if: "$Verbosity='Verbose'" + then: [T: "tier-logaritmen"] + else: [spell: "'lg'"] # phrase(the 'lg' of x) + - else_if: $ClearSpeak_Log = 'LnAsNaturalLog' or $Verbosity='Verbose' + then: [T: "den naturlige logaritmen"] # phrase(the 'natural log' of x) + else: [spell: "'ln'"] + #NORWEGIAN: Removed test for verbosity + - T: "av" + - pause: short + - x: "*[3]" + +#NORWEGIAN: Changed to English version +- name: ClearSpeak-multi-line + tag: [piecewise, system-of-equations, lines] # these are ignored in favor of the ClearSpeak prefs + match: "." + variables: + - 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: + - test: + - if: "$LineCount > 1 and $ClearSpeak_MultiLineLabel != 'None'" + then: [T: "tilfeller"] + else: [T: "tilfelle"] # phrase(this is the first 'case' of three cases) + - else_if: "$ClearSpeak_MultiLineLabel = 'Auto' or $ClearSpeak_MultiLineLabel = 'Line'" # already dealt with Auto/Case + then: + - test: + - if: "$LineCount > 1 and $ClearSpeak_MultiLineLabel != 'None'" + then: [T: "rader"] # phrase(this is the first 'line' of three lines) + else: [T: "rad"] # phrase(this is the first 'line' of three lines) + - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" + then: + - test: + - if: "$LineCount > 1 and $ClearSpeak_MultiLineLabel != 'None'" + then: [T: "betingelser"] # phrase(this is the first 'constraint' of three constraints) + else: [T: "betingelse"] # phrase(this is the first 'constraint' of three constraints) + - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" + then: + - test: + - if: "$LineCount > 1 and $ClearSpeak_MultiLineLabel != 'None'" + then: [T: "likninger"] # phrase(this is the first 'equation' of three equations) + else: [T: "likning"] # phrase(this is the first 'equation' of three equations) + - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" + then: + - test: + - if: "$LineCount > 1 and $ClearSpeak_MultiLineLabel != 'None'" + then: [T: "rader"] # phrase(this is the first 'row' of three rows) + else: [T: "rad"] # phrase(this is the first 'row' of three rows) + - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" + then: + - test: + - if: "$LineCount > 1 and $ClearSpeak_MultiLineLabel != 'None'" + then: [T: "steg"] # phrase(this is the first 'step' of three steps) + else: [T: "steg"] # phrase(this is the first 'step' of three steps) + # SWEDISH/NORWEGIAN: Every expression had to be inflected separately. + - pause: short + - x: "*" + +#NORWEGIAN: Changed from Swedish to English version +- 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: "tilfelle"] # 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: "rad"] # phrase(the straight 'line' between x and y) + - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" + then: [T: "betingelse"] # phrase(there is a 'constraint' on possible values) + - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" + then: [T: "likning"] # phrase(the 'equation' pi r squared gives the area of a circle) + - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" + then: [T: "rad"] # phrase(the values on the top 'row' are relevant) + - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" + then: [T: "steg"] # 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: "med etiketten" # 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: "ganger"] # phrase(5 'times' 3 equals 15) + +- name: no-times + tag: mo + match: + # Note: this rule is also part of the paren rule so that the parens speak + - ".='⁢' and $ClearSpeak_ImpliedTimes = 'None'" + replace: + - T: "" + +# NORWEGIAN: Changed to English version +- name: ClearSpeak-times + tag: mo + match: + # say "times" when invisible times is followed by parens or a superscript that has a base with parens or "|"s + # if we aren't sure if it is times or not, don't say anything + - ".='⁢' and (not(@data-function-guess) or $ClearSpeak_Functions = 'None') and" + - "not(ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) and (" + - " $ClearSpeak_ImpliedTimes = 'MoreImpliedTimes'" + - " or " + - " following-sibling::*[1][" + - " IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|') or " + # most of these aren't mentioned in ClearSpeak spec, but are (I think) expected uses of "times" + - " self::m:matrix or self::m:determinant or self::m:binomial or" # followed by parens + - " self::m:square-root or self::m:msqrt or self::m:root or self::m:mroot or" + - " (self::m:msub or self::m:msubsup or" + - " ((self::m:msup or self::m:power) and not(IsNode(*[1], 'leaf') and *[2][self::m:mn and (.=2 or '.=3')]))) and " # followed by msup, etc. + - " (*[1][self::m:mrow[IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')] or " + - " self::m:matrix or self::m:determinant] or" # base has parens + - " not(IsNode(*[2], 'simple')) or " + - " (self::m:msubsup and not(IsNode(*[3], 'simple')))" + - " )" + - " ]" + # other possibility is the preceding element has parens (but not the following) + # this is not mentioned in the ClearSpeak rules or examples but seems like it should say "times". E.g, |x| y + - " or " + - " preceding-sibling::*[1][" + - " IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')]" # followed by parens + - " )" + replace: + - T: "ganger" # phrase(5 'times' 3 equals 15) + +- name: no-say-parens + tag: mrow + match: + - "parent::*[not(self::m:msup) and not(self::m:msub) and not(self::m:msubsup) and not(self::m:power) and" + - " not(self::m:math) ] and " # rule out [x] standing alone + - "( IsBracketed(., '(', ')') or IsBracketed(., '[', ']') ) and " + - "not( $ClearSpeak_Functions = 'None' and " + - " (preceding-sibling::*[1][.='⁡'] or following-sibling::*[1][.='⁡']) ) and " + - "not( $ClearSpeak_ImpliedTimes = 'None' and " + - " (preceding-sibling::*[1][.='⁢'] or following-sibling::*[1][.='⁢']) ) and " + - "IsNode(*[2], 'simple') and" + - "not(preceding-sibling::*[1][.='\u2062' and @data-function-guess]) and" + - "not(ancestor-or-self::*[contains(@data-intent-property, ':literal:')])" + # missing clause: 'a positive fraction that is spoken as an ordinal + # (either by the Ordinal preference or by the default rules)' + replace: + - x: "*[2]" + +- include: "SharedRules/geometry.yaml" +- include: "SharedRules/linear-algebra.yaml" +- include: "SharedRules/calculus.yaml" +- include: "SharedRules/general.yaml" +- include: "SharedRules/default.yaml" + diff --git a/Rules/Languages/nb/SharedRules/calculus.yaml b/Rules/Languages/nb/SharedRules/calculus.yaml new file mode 100644 index 000000000..d8fab660e --- /dev/null +++ b/Rules/Languages/nb/SharedRules/calculus.yaml @@ -0,0 +1,37 @@ +--- + +- name: divergence + tag: divergence + match: "count(*) = 1" + replace: + - test: + if: "$Verbosity='Verbose'" + then: [T: "divergensen til"] # phrase('divergence' from the mean) + else: [T: "div"] # phrase('divergence' from the mean) + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [pause: short] + - x: "*[1]" + +- name: curl + tag: curl + match: "count(*) = 1" + replace: + - test: + if: "$Verbosity='Verbose'" + then: [T: "curlen til"] + else: [T: "curl"] + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [pause: short] + - x: "*[1]" + +- name: gradient + tag: gradient + match: "count(*) = 1" + replace: + - T: "gradienten til" + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [pause: short] + - x: "*[1]" diff --git a/Rules/Languages/nb/SharedRules/default.yaml b/Rules/Languages/nb/SharedRules/default.yaml new file mode 100644 index 000000000..86db146f7 --- /dev/null +++ b/Rules/Languages/nb/SharedRules/default.yaml @@ -0,0 +1,724 @@ +--- +#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: "tekststrengen" # 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: "over" # phrase("the fraction x 'over' y") + - x: "*[2]" + - pause: short + +- name: literal-default + tag: mfrac + match: "." + replace: + - T: "start" # phrase("'start' fraction x over y end of fraction") + - pause: short + - x: "*[1]" + - test: + if: "not(IsNode(*[1],'leaf'))" + then: [pause: short] + - T: "over" # phrase("the fraction x 'over' y") + - test: + if: "not(IsNode(*[2],'leaf'))" + then: [pause: short] + - x: "*[2]" + - pause: short + - T: "slutt brøk" # 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 +#NORWEGIAN: Removed test for verbosity +- name: literal-default + tag: msqrt + match: "." + replace: + - T: "roten av" + - x: "*[1]" + - pause: short + - test: + if: "not(IsNode(*[1],'leaf'))" + then: [T: "slutt rot"] # 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 +# NORWEGIAN: Changed to "med grad", and changed the order of the index and the variable/number in the root. Removed test for verbosity. +- name: literal-default + tag: mroot + match: "." + replace: + - T: "rottegn" + - T: "med grad" # phrase("the root of x 'with index' 5") + - x: "*[2]" + - pause: short + - T: "av" + #- test: + #if: "$Verbosity!='Terse'" + #then: [T: "av"] # phrase("the root 'of' x") + - x: "*[1]" + - pause: short + - test: + if: "not(IsNode(*[2],'leaf'))" + then: [T: "slutt rottegn"] # 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 + +# NORWEGIAN: Removed the following test: if: "$Verbosity!='Terse' or not(*[2][self::m:mn])", which is in the Swedish translation. +# NORWEGIAN: Added "pause: short" before "senket" +- name: no-end-sub + tag: indexed-by + # invisible comma -- want "x 1 when subscript is an integer" + match: "count(*)=2 and (IsNode(*[2], 'leaf') or *[2][self::m:mrow][*[2][.='⁣']])" #NORWEGIAN: Don't change this to English version. Then the rule "indexed-by" in definitions.yaml kicks in instead. Want to keep the pause before "senket". + replace: + - x: "*[1]" + - pause: short + - T: "senket" + - x: "*[2]" + - pause: short + +- name: literal + tag: msub + match: "." + replace: + - x: "*[1]" + - test: + if: "not($Verbosity='Terse' and *[2][self::m:mn and not(translate(., '.,', '')!=.)])" # say "x 1" for terse vs "x sub 1". Say "x sub 1,2" + then: [T: "senket"] # phrase(x 'sub' 2) + - x: "*[2]" + +- name: literal + tag: [msup, msubsup] + match: "." + replace: + - x: "*[1]" + - test: + if: "name(.)='msubsup'" + then: + - T: "senket" # 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: "hevet" # phrase(x 'super' 2) + - x: "*[last()]" + - test: + if: "not(IsNode(*[last()], 'simple'))" + then: [T: "slutt hevet"] # phrase(x super 2 'end of super') + else: + - T: "opphøyd i" # phrase(5 'raised to the' second power equals 25) + - x: "*[last()]" + # - t: "power" # phrase(5 raised to the second 'power' equals 25) + +#NORWEGIAN: Changed to English version. +- name: default + tag: munder + match: "." + replace: + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [T: "uttrykk"] # phrase(phrase(x 'modified' with y above it) + - x: "*[1]" + - pause: short + - T: "med" # phrase(x 'with' z below it) + - x: "*[2]" + - T: "under" # phrase(x with z 'below' it) + - pause: short + +- name: diacriticals + tag: mover + match: "*[1][self::m:mi] and *[2][translate(., '\u0306\u030c.\u00A8\u02D9\u20DB\u20DC`^ˇ~→¯_', '')='']" + replace: + - x: "*[1]" + - x: "*[2]" + +#NORWEGIAN: Changed to English version. +- name: default + tag: mover + match: "." + replace: + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [T: "uttrykk"] # phrase(phrase(x 'modified' with y above it) + - x: "*[1]" + - pause: short + - T: "med" # phrase(x modified 'with' y above it) + - x: "*[2]" + - T: "over" # phrase(x modified 'with' y above it) + - pause: short + +#NORWEGIAN: Changed to English version. +- name: default + tag: munderover + match: "." + replace: + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [T: "uttrykk"] # phrase(the equation has been 'modified') + - x: "*[1]" + - T: "med" # phrase(x modified 'with' y above it) + - x: "*[2]" + - T: "under og" + - x: "*[3]" + - T: "over" # phrase(x modified with y 'above' it) + - pause: short + +- 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', 'senket', 'senket')" + - PreSuperscript: "IFTHENELSE($Verbosity='Verbose', 'hevet', 'hevet')" + replace: + - test: # only bother announcing if there is more than one prescript + if: "count($Prescripts) > 2" + then: + - T: "med" # phrase(substitute x 'with' y) + - x: "count($Prescripts) div 2" + - T: "venstre indeks" # phrase(in this equation certain 'prescripts' apply) + - pause: short + - test: + if: "not($Prescripts[1][self::m:none])" + then: + - x: "$PreSubscript" + - x: "$Prescripts[1]" + - pause: short + - test: + if: "not($Prescripts[1][self::m:none] or $Prescripts[2][self::m:none])" + then: [T: "og"] # 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]" + - pause: short + - test: + if: "not($Prescripts[3][self::m:none] or $Prescripts[4][self::m:none])" + then: [T: "og"] # phrase(10 is grater than 8 'and' less than 15) + - test: + if: "not($Prescripts[4][self::m:none])" + then: + - x: "$PreSuperscript" + - x: "$Prescripts[4]" + - pause: short + - test: + if: "count($Prescripts) > 4" # give up and just dump them out so at least the content is there + then: + - T: "og resterende venstre indeks" # phrase(in this case there are values 'and alternating prescripts') + - x: "$Prescripts[position() > 4]" + - T: "slutt venstre indeks" # phrase(This is where 'end prescripts' occurs) + - test: + if: "$Postscripts" + then: + - with: + variables: + - PostSubscript: "IFTHENELSE($Verbosity='Verbose', 'senket', 'senket')" + - PostSuperscript: "IFTHENELSE($Verbosity='Verbose', 'hevet', 'hevet')" + replace: + - test: # only bother announcing if there is more than one postscript + if: "count($Postscripts) > 2" + then: + - test: + if: "$Prescripts" + then: [T: "og"] # phrase(10 is greater than 8 'and' less than 15) + - T: "med" # phrase(substitute x 'with' y) + - x: "count($Postscripts) div 2" + - T: "høyre indeks" # phrase(this material includes several 'postscripts') + - pause: short + - test: + if: "not($Postscripts[1][self::m:none])" + then: + - x: "$PostSubscript" + - x: "$Postscripts[1]" + - pause: short + - test: + if: "not($Postscripts[1][self::m:none] or $Postscripts[2][self::m:none])" + then: [T: "og"] # phrase(10 is greater than 8 'and' less than 15) + - test: + if: "not($Postscripts[2][self::m:none])" + then: + - x: "$PostSuperscript" + - x: "$Postscripts[2]" + - pause: short + - test: + if: "count($Postscripts) > 2" + then: + - test: + if: "not($Postscripts[3][self::m:none])" + then: + - x: "$PostSubscript" + - x: "$Postscripts[3]" + - pause: short + - test: + if: "not($Postscripts[3][self::m:none] or $Postscripts[4][self::m:none])" + then: [T: "og"] # phrase(10 is greater than 8 'and' less than 15) + - test: + if: "not($Postscripts[4][self::m:none])" + then: + - x: "$PostSuperscript" + - x: "$Postscripts[4]" + - pause: short + - test: + if: "count($Postscripts) > 4" + then: + - test: + if: "not($Postscripts[5][self::m:none])" + then: + - x: "$PostSubscript" + - x: "$Postscripts[5]" + - pause: short + - test: + if: "not($Postscripts[5][self::m:none] or $Postscripts[6][self::m:none])" + then: [T: "og"] # phrase(10 is greater than 8 'and' less than 15) + - test: + if: "not($Postscripts[6][self::m:none])" + then: + - x: "$PostSuperscript" + - x: "$Postscripts[6]" + - pause: short + - test: + if: "count($Postscripts) > 6" + then: + - test: + if: "not($Postscripts[7][self::m:none])" + then: + - x: "$PostSubscript" + - x: "$Postscripts[7]" + - pause: short + - test: + if: "not($Postscripts[7][self::m:none] or $Postscripts[8][self::m:none])" + then: [T: "og"] # phrase(10 is less than 15 'and' greater than 5) + - test: + if: "not($Postscripts[8][self::m:none])" + then: + - x: "$PostSuperscript" + - x: "$Postscripts[8]" + - pause: short + - test: + if: "count($Postscripts) > 8" # give up and just dump them out so at least the content is there + then: + - T: "og resterende høyre indeks" # phrase(this situation involves complexities 'and alternating scripts') + - x: "$Postscripts[position() > 8]" + - T: "slutt indeks" # phrase(At this point 'end scripts' occurs) + +# NORWEGIAN: Changed to English version +- name: default + tag: mtable + variables: + - IsColumnSilent: "false()" + - NumColumns: "count(*[1]/*) - IfThenElse(*/self::m:mlabeledtr, 1, 0)" + match: "." + replace: + - T: "tabell med" # phrase(the 'table with' 3 rows) + - x: count(*) + - test: + if: count(*)=1 + then: [T: "rad"] # phrase(the table with 1 'row') + else: [T: "rader"] # phrase(the table with 3 'rows') + - T: "og" # phrase(the table with 3 rows 'and' 4 columns) + - x: "$NumColumns" + - test: + if: "NumColumns=1" + then: [T: "kolonne"] # phrase(the table with 3 rows and 1 'column') + else: [T: "kolonner"] # 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: + - T: "rad" # phrase(the first 'row' of a matrix) + - x: "count(preceding-sibling::*)+1" + - test: + if: "self::m:mlabeledtr" + then: + - T: "med etiketten" # 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: "kolonne" # 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: "tom rute" # 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: "boks", pause: short] # phrase(the 'boks' around the expression) + - test: + if: ".[contains(@notation,'roundedbox')]" + then: [T: "rund boks", pause: short] # phrase(the 'round box' around the expression) + - test: + if: ".[contains(@notation,'circle')]" + then: [T: "sirkel", 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: "linje" # phrase(draw a straight 'line' on the page) + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' left ')]" + then: [T: "venstre", pause: short] # phrase(line on 'left' of the expression) + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' right ')]" + then: [T: "høyre", pause: short] # phrase(line on 'right' of the expression) + - test: + if: ".[contains(@notation,'top')]" + then: [T: "over", pause: short] # phrase(line on 'top' of the expression) + - test: + if: ".[contains(@notation,'bottom')]" + then: [T: "under", 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: [T: "kryss", pause: short] # seems better to say 'x cross out' than 'up diagonal, down diagonal cross out' + else: + - test: + if: ".[contains(@notation,'updiagonalstrike')]" + then: [T: "diagonalt oppover", pause: short] # phrase(the line runs 'up diagonal') + - test: + if: ".[contains(@notation,'downdiagonalstrike')]" + then: [T: "diagonalt nedover", 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: "horisontal", pause: short] # phrase(the line is 'horizontal') + - T: "utstryking" # phrase(please 'cross out' the incorrect answer) + - pause: short + - test: + if: ".[contains(@notation,'uparrow')]" + then: [T: "oppoverpil", pause: short] # phrase(direction is shown by the 'up arrow') + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' downarrow ')]" + then: [T: "nedoverpil", pause: short] # phrase(the trend is shown by the 'down arrow') + - test: + if: ".[contains(@notation,'leftarrow')]" + then: [T: "venstrepil", pause: short] # phrase(the 'left arrow' indicates going back) + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' rightarrow ')]" + then: [T: "høyrepil", pause: short] # phrase(the 'right arrow' indicates moving forward) + - test: + if: ".[contains(@notation,'northeastarrow')]" + then: [T: "nordøst-pil", pause: short] # phrase(direction is indicated by the 'northeast arrow') + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' southeastarrow ')]" + then: [T: "sørøst-pil", pause: short] # phrase(direction is shown by the 'southeast arrow') + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' southwestarrow ')]" + then: [T: "sørvest-pil", pause: short] # phrase(direction is shown by the 'southwest arrow') + - test: + if: ".[contains(@notation,'northwestarrow')]" + then: [T: "nordvest-pil", pause: short] # phrase(direction is shown by the 'northwest arrow') + - test: + if: ".[contains(@notation,'updownarrow')]" + then: [T: "dobbelendet vertikal pil", pause: short] # phrase(upward movement is indicated by the 'double ended vertical arrow') + - test: + if: ".[contains(@notation,'leftrightarrow')]" + then: [T: "dobbelendet horisontal pil", pause: short] # phrase(progress is indicated by the 'double ended horizontal arrow') + - test: + if: ".[contains(@notation,'northeastsouthwestarrow')]" + then: [T: "dobbelendet diagonal oppoverpil", pause: short] # phrase(trend is indicated by the 'double ended up diagonal arrow') + - test: + if: ".[contains(@notation,'northwestsoutheastarrow')]" + then: [T: "dobbelendet diagonal nedoverpil", pause: short] # phrase(trend is indicated by the 'double ended down diagonal arrow') + - test: + if: ".[contains(@notation,'actuarial')]" + then: [T: "aktuarielt symbol", pause: short] # phrase(the 'actuarial symbol' represents a specific quantity) + - test: + if: ".[contains(@notation,'madrub')]" + then: [T: "arabisk fakultet", pause: short] # phrase(the 'arabic factorial symbol' represents a factorial operation) + - test: + if: ".[contains(@notation,'phasorangle')]" + then: [T: "fasevinkel", 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: "lang divisjon", pause: short] # phrase(the 'long division symbol' indicates a long division calculation) + - test: + if: ".[contains(@notation,'radical')]" + then: [T: "kvadratrot", pause: short] # phrase(5 is the 'square root' of 25) + - T: "omslutter" # phrase(parentheses are 'enclosing' part of the equation) + - test: + if: "*[self::m:mtext and .=' ']" + then: [T: "mellomrom"] # otherwise there is complete silence # phrase(there is a 'space' between the words) # SWEDISH: is this reasonable? + else: [x: "*"] + - test: + if: "$Impairment = 'Blindness' and ( $SpeechStyle != 'SimpleSpeak' or not(IsNode(*[1], 'leaf')) )" + then: [pause: short, T: "slutt omslutning"] # 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: "anvendt på" # 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: "not(contains(@data-intent-property, ':literal:')) and + not(count(*)=2 and (IsInDefinition(*[1], 'TrigFunctionNames') or IsInDefinition(name(.), 'TerseFunctionNames')) and IsNode(*[2], 'simple'))" + then: [T: "av", pause: auto] # phrase(sine 'of' 5) + - insert: + nodes: "*" + replace: [T: "", pause: short] + #- test: + #if: "not(contains(@data-intent-property, ':literal:'))" + #then: [x: "','"] + # SWEDISH/NORWEGIAN: After correspondence with a mathematician we have decided to not have any punctuation between variables, but a short pause. Length of pause needs to be tested. + - test: + + if: "$Impairment = 'Blindness' and not(*[last()][IsBracketed(., '', '') or IsNode(., 'simple')] )" + then: [x: "GetBracketingIntentName(name(.), $Verbosity, 'function', 'end')"] + - test: + if: "IsNode(., '2D')" + then: [pause: short] + else: [pause: auto] + +- name: default-text + # unknown leaf -- just speak the text -- could be a literal intent + tag: "*" + match: "." + replace: + - x: "translate(name(), '-_', ' ')" diff --git a/Rules/Languages/nb/SharedRules/general.yaml b/Rules/Languages/nb/SharedRules/general.yaml new file mode 100644 index 000000000..2499655b6 --- /dev/null +++ b/Rules/Languages/nb/SharedRules/general.yaml @@ -0,0 +1,1133 @@ +--- +# SWEDISH: This code preserves points in mtext elements. Only the first point, if there are more than one, is currently preserved. +- name: intercept-comma + tag: mtext + match: "contains(., '.')" + replace: + - x: "substring-before(., '.')" + - T: "punktum" + - x: "substring-after(., '.')" + +# 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: + # NORWEGIAN: Removed test for verbosity + #- test: + #if: "$Verbosity!='Terse'" + #then: + - T: "de" # phrase('the' square root of 25 equals 5) + - bookmark: "*[2]/@id" + - test: + - if: "*[2][.='+']" + then: [T: "positive"] # phrase(set of all 'positive' integers less than 10) + else: [T: "negative"] # phrase(set of all 'negative' integers less than minus 10) + - bookmark: "*[1]/@id" + - test: + - if: "*[1][.='ℂ']" + then: [T: "komplekse tallene"] # phrase('complex numbers' consist of two parts) + - else_if: "*[1][.='ℕ']" + then: [T: "naturlige tallene"] # phrase('natural numbers' are numbers from 1 to infinity) + - else_if: "*[1][.='ℚ']" + then: [T: "rasjonale tallene"] # phrase('rational numbers' are the fraction of 2 integers) + - else_if: "*[1][.='ℝ']" + then: [T: "reelle tallene"] # phrase('real numbers' can be both positive and negative) + - else_if: "*[1][.='ℤ']" + then: [T: "heltallene"] # 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: "de komplekse tallene"] # phrase('the complex numbers' include 2 parts) + - else_if: ".='ℕ'" + then: [T: "de naturlige tallene"] # phrase('the natural numbers' begin at 1) + - else_if: ".='ℚ'" + then: [T: "de rasjonale tallene"] # phrase('the rational numbers' are the fraction of 2 integers) + - else_if: ".='ℝ'" + then: [T: "de reelle tallene"] # phrase('the real numbers' can be both positive and negative) + - else_if: ".='ℤ'" + then: [T: "heltallene"] # 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: "den reelle delen" # 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: "den imaginære delen" # 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 + - test: + if: "$Verbosity!='Terse'" + then: [T: "evaluert i"] # phrase(results were 'evaluated at' a given point) + else: [T: "i"] + # SWEDISH/NORWEGIAN: Added a verbosity setting test to allow a shorter form. + - pause: auto + - x: "*[2]" + +- name: evaluated-at-3 + tag: evaluate + match: "count(*)=3" + replace: + - x: "*[1]" + - pause: auto + - test: + if: "$Verbosity!='Terse'" + then: [T: "evaluert for øvre verdi"] # phrase(results were 'evaluated at' a given point) + else: [T: "øvre verdi"] + - pause: short + - x: "*[3]" + - pause: short + - T: "og" # phrase(this result is 'minus the same expression evaluated at' an earlier point) + - T: "nedre verdi" + # SWEDISH/NORWEGIAN: Removed the expansion of the expression, keeping the output closer to what is actually shown visually. + - pause: short + - x: "*[2]" + +- name: permutation + tag: pochhammer + match: "count(*)=2" + replace: + - T: "antallet permutasjoner av" + - x: "*[2]" + - T: "elementer av" # phrase(the solution involves several 'permutations of' values) + - x: "*[1]" + +# NORWEGIAN: Removed test for verbosity +- name: intervals + tag: [open-interval, open-closed-interval, closed-interval, closed-open-interval] + match: "count(*)=2" + replace: + # SWEDISH/NORWEGIAN: The translate function doesn't work for non-English. Used the solution below instead. + - test: + - if: "self::m:open-interval" + then: [T: "det åpne intervallet"] + - else_if: "self::m:open-closed-interval" + then: [T: "det halvåpne intervallet"] + - else_if: "self::m:closed-interval" + then: [T: "det lukkede intervallet"] + else: [T: "det halvåpne intervallet"] + - T: "fra" # phrase(subtracting 5 'from' 10 gives 5) + - test: + - if: "self::m:closed-open-interval" + then: [T: "og med"] + - x: "*[1]" + - T: "til" # phrase(adding 6 'to' 6 equals 12) + - test: + - if: "self::m:open-closed-interval" + then: [T: "og med"] + - x: "*[2]" +# removed this option because it doesn't clarify in which end half-open intervals are open +# 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: + - T: "punktet" # 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: + - x: "*[1]" + - T: "fra" # phrase(subtracting 5 'from' 10 gives 5) + - x: "*[2]" + - pause: short + - T: "til" # phrase(adding 6 'to' 6 equals 12) + - x: "*[3]" + - pause: short + - test: + if: "following-sibling::*" + then: [T: "av"] # phrase(the square root 'of' 25 equals 5) + + +- name: bigop-under + tag: large-op + match: "count(*)=2" + replace: + - x: "*[1]" + - T: "over" # phrase(2 'over' 3 equals two thirds) + - x: "*[2]" + - pause: short + - test: + if: "following-sibling::*" + then: [T: "av"] # phrase(the square root 'of' 25 equals 5) + +- name: largeop + tag: mrow + match: "count(*)=2 and IsInDefinition(*[1], 'LargeOperators')" + replace: + - x: "*[1]" + - T: "av" # phrase(the square root 'of' 25 equals 5) + - pause: short + - x: "*[2]" + +#NORWEGIAN: Added this rule from English. +- name: repeating-decimal + tag: repeating-decimal + match: "." + replace: + - x: "*[1]" + - T: "med repeterende siffer" # 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: "nedre indeks"] # phrase(a 'subscript' may be used to indicate an index) + else: [T: "senket"] # phrase(the result is 'sub' optimal) + - x: "*[2]" + - test: + if: "not(IsNode(*[2],'leaf'))" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "slutt nedre indeks"] # phrase(this is the 'end subscript' position) + else: [T: "slutt senket"] # 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: "øvre indeks"] # phrase(a 'superscript' number indicates raised to a power) + else: [T: "hevet"] # 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 concatinated to the base + then: [x: "$Word"] + - else_if: "DefinitionValue($Word, 'Speech', 'PluralForms') != ''" + then: [x: "DefinitionValue($Word, 'Speech', 'PluralForms')"] + else: [x: "$Word"] + else: + - x: "$Prefix" + - ct: "-" + - test: + - if: "$IsSingular" + # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets the prefix concatinated to the base + then: [x: "concat('\uF8FE', $Word)"] + - else_if: "DefinitionValue($Word, 'Speech', 'PluralForms') != ''" + then: [x: "concat('\uF8FE', DefinitionValue($Word, 'Speech', 'PluralForms'))"] + else: [x: "concat('\uF8FE', $Word)"] + + +- name: sin + tag: mi + match: ".='sin'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: "sin"] # phrase('sin' is the abbreviation for sine) + else: [T: "sinus"] # phrase(the 'sine' of the angle) + # SWEDISH/NORWEGIAN: Added short form. + +- 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: "cosinus"] # 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: "sec"] # 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: "cosec"] # phrase(we will 'cosecant' a solution) + else: [T: "cosekans"] # phrase(the 'cosecant' is the reciprocal of the secant) + +- name: cot + tag: mi + match: ".='cot'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: "cotan"] # phrase(find the 'cotangent' in a right-angle triangle) + else: [T: "cotangens"] # phrase(the 'cotangent' is the reciprocal of the tangent) + +# NORWEGIAN: Removed tests for verbosity. We don't say "sin hype" etc., and "sinh" sounds like "sin" +- name: sinh + tag: mi + match: ".='sinh'" + replace: + - bookmark: "@id" + - T: "sinus hyperbolicus" + #- test: + #if: "$Verbosity='Terse'" + #then: {T: "sin hype"} # phrase(the word 'sinch' is an abbreviation for hyperbolic sine) + #else: {T: "sinus hyperbolicus"} # phrase(the 'hyperbolic sine' is used in mathematics) + +- name: cosh + tag: mi + match: ".='cosh'" + replace: + - bookmark: "@id" + - T: "cosinus hyperbolicus" + #- test: + #if: "$Verbosity='Terse'" + #then: {T: "cos hype"} # phrase('cosh' is an abbreviation of hyperbolic cosine) + #else: {T: "cosinus hyperbolicus"} # phrase(the 'hyperbolic cosine' is a mathematical function) + +- name: tanh + tag: mi + match: ".='tanh'" + replace: + - bookmark: "@id" + - T: "tangens hyperbolicus" + #- test: + #if: "$Verbosity='Terse'" + #then: {T: "tan hype"} # phrase('tanch' is shorthand for hyperbolic tangent) + #else: {T: "tangens hyperbolicus"} # phrase('hyperbolic tangent' is a mathematical function) + +- name: sech + tag: mi + match: ".='sech'" + replace: + - bookmark: "@id" + - T: "sekans hyperbolicus" + #- test: + #if: "$Verbosity='Terse'" + #then: {T: "sec hype"} # phrase('sheck' is shorthand for hyperbolic secant) + #else: {T: "sekans hyperbolicus"} # phrase('hyperbolic secant' is a mathematical function) + +- name: csch + tag: mi + match: ".='csch'" + replace: + - bookmark: "@id" + - T: "cosekans hyperbolicus" + #- test: + #if: "$Verbosity='Terse'" + #then: {T: "cosec hype"} # phrase('cosheck' is shorthand for hyperbolic cosecant) + #else: {T: "cosekans hyperbolicus"} # phrase('hyperbolic cosecant' is a mathematical function) + +- name: coth + tag: mi + match: ".='coth'" + replace: + - bookmark: "@id" + - T: "cotangens hyperbolicus" + #- test: + #if: "$Verbosity='Terse'" + #then: {T: "cotan hype"} # phrase('cotanch' is shorthand for hyperbolic cotangent) + #else: {T: "cotangens hyperbolicus"} # phrase(the 'hyperbolic cotangent' is a mathematical function) + +# NORWEGIAN: Added this rule from English version +- name: exponential + tag: mi + match: ".='exp'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: "exp"] # phrase('exp' means exponential function) + else: [T: "eksponensialfunksjonen"] # phrase('exponential' function) #Norwegian: Spelled wrong for correct pronunciation + +# NORWEGIAN: Added this rule from English version, but removed test for verbosity. +- name: covariance + tag: mi + match: ".='Cov'" + replace: + - bookmark: "@id" + - T: "kovarians" + +- # handle both log and ln + name: log + tag: mrow + variables: [{log_is_simple: "IsNode(*[3],'simple')"}] + match: + - "count(*)=3 and" + - "*[1][self::m:mi][.='log' or .='ln' or .='lg'] and" + - "*[2][self::m:mo][.='⁡']" + replace: + - bookmark: "*[1]/@id" + - test: + if: "$log_is_simple" + then_test: + - if: "*[1][.='log']" + then: [T: "log"] # phrase(the 'log' function is used in mathematics) + - else_if: "*[1][.='lg']" + then: [spell: "'lg'"] # phrase(the 'lg' of x) + # SWEDISH/NORWEGIAN: We have added the term "lg" for the logarithm with base 10. Also added a verbosity test for long and short form. + - else_if: "$Verbosity!='Verbose'" + then: [spell: "'ln'"] + else: [T: "den naturlige logaritmen"] # phrase(the 'natural log' function is used in mathematics) + else: + - test: + - if: "*[1][.='log']" + then_test: + - if: "$Verbosity!='Verbose'" + then: [T: "log"] # phrase(the 'log' function is used in mathematics) + else: [T: "logaritmen"] + - else_if: "*[1][.='lg']" + then_test: + - if: "$Verbosity!='Verbose'" + then: [spell: "'lg'"] # phrase(the 'lg' of x) + else: [T: "tier-logaritmen"] + - else_if: "$Verbosity='Terse'" + then: [spell: "'ln'"] + else: [T: "den naturlige logaritmen"] # phrase(the 'natural log' function is used in mathematics) + - T: "av" # phrase(5 is the square root 'of' 25) + #- pause: short + - x: "*[3]" + + +# NORWEGIAN: Changed from Swedish to English version. +- 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: + - test: + - if: "$LineCount != 1" + then: [T: "tilfeller"] + else: [T: "tilfelle"] # phrase(this is the first 'case' of three cases) + - else_if: "self::m:system-of-equations" + then: + - test: + - if: "$LineCount != 1" + then: [T: "likninger"] + else: [T: "likning"] # phrase(this is the first 'equation' of three equations) + - else: + - test: + - if: "$LineCount != 1" + then: [T: "rader"] + else: [T: "rad"] # phrase(this is the first 'line' of three lines) + - pause: short + - x: "*" + +# NORWEGIAN: Changed from Swedish to English version. +- 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: "tilfelle"] # phrase('case' 1 of 10 cases) + - else_if: "parent::m:system-of-equations" + then: [T: "likning"] # phrase('equation' 1 of 10 equations) + else: [T: "rad"] # 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: "med etiketten" # 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: "*"] + +# NORWEGIAN: Changed from Swedish to English version. +- 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: + - T: "1 ganger 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: "determinant"] # phrase(the 2 by 2 'determinant')) + else: [T: "matrise"] # phrase(the 2 by 2 'matrix') + + - T: "med element" # phrase(the 2 by 2 matrix 'with entry' x) + - x: "*[1]/*" + + +# simpler reading methods for special case matrices +# NORWEGIAN: Added these rules from the English. +- 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: + - x: count(*) + - T: "ganger" # phrase(the 1 'by' 2 matrix) + - x: count(*[self::m:mtr][1]/*) + - T: "null-matrise" # 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: + - x: count(*) + - T: "ganger" # phrase(the 1 'by' 2 matrix) + - x: count(*[self::m:mtr][1]/*) + - T: "identitetsmatrise" # 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: + - x: count(*) + - T: "ganger" # phrase(the 1 'by' 2 matrix) + - x: count(*[self::m:mtr][1]/*) + - T: "diagonalmatrise" # 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: + - x: count(*) + - T: "ganger 1" # phrase(the 2 'by 1 column' matrix) + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "kolonne-vektor"] # phrase(the 2 by 2 'vector') + else: [T: "kolonne-matrise"] # phrase(the 2 by 2 'matrix') + - pause: long + - x: "*/*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: "slutt" # phrase('end' of matrix) + - test: + if: $ClearSpeak_Matrix = 'EndVector' + then: [T: "vektor"] # phrase(the 2 column 'vector') + else: [T: "matrise"] # phrase(the 2 by 2 'matrix') + +- name: default-column-matrix + tag: matrix + variables: [IsColumnSilent: true()] + match: "*[self::m:mtr][count(*) = 1]" + replace: + - x: "count(*)" + - T: "ganger 1" # phrase(the 2 'by 1 column' matrix) + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "kolonne-vektor"] # phrase(the 2 column 'vector') + else: [T: "kolonne-matrise"] # phrase(the 2 by 2 'matrix') + - pause: long + - x: "*" # select the rows (mtr) + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: "slutt" # phrase('end' of matrix) + - test: + if: $ClearSpeak_Matrix = 'EndVector' + then: [T: "vektor"] # phrase(the 2 column 'vector') + else: [T: "matrise"] # phrase(the 2 by 2 'matrix') + +- 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: "1 ganger" # phrase('the 1 by' 2 matrix) + - x: count(*/*) + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "rad-vektor"] # phrase('the 1 by' 2 row 'vector') + else: [T: "rad-matrise"] # phrase('the 1 by' 2 'matrix') + - pause: long + - x: "*/*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: "slutt" # phrase(the 'end' of matrix has been reached) + - test: + if: $ClearSpeak_Matrix = 'EndMatrix' + then: [T: "matrise"] # 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: "1 ganger" # phrase('the 1 by' 2 matrix) + - x: "count(*/*)" + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "rad-vektor"] # phrase(the 2 by 1 'vector') + else: [T: "rad-matrise"] # 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: "slutt" # phrase(the 'end' of matrix has been reached) + - test: + if: $ClearSpeak_Matrix = 'EndMatrix' + then: [T: "matrise"] # 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: + - x: count(*) + - T: "ganger" # phrase(the 1 'by' 2 matrix) + - x: count(*[self::m:mtr][1]/*) + - test: + if: "self::m:determinant" + then: [T: "determinant"] # phrase(the 2 by 2 'determinant') + else: [T: "matrise"] # phrase(the 2 by 2 'matrix') + - pause: long + - x: "*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: "slutt" # phrase(the 'end' of matrix has been reached) + - test: + if: "self::m:determinant" + then: [T: "determinant"] # phrase(the 2 by 2 'determinant') + else: [T: "matrise"] # phrase(the 2 by 2 'matrix') + +- name: default-matrix + tag: [matrix, determinant] + variables: [IsColumnSilent: "$SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix = 'SilentColNum'"] + match: "." + replace: + - x: "count(*)" + - T: "ganger" # phrase(the 1 'by' 2 matrix) + - x: "count(*[self::m:mtr][1]/*)" + - test: + if: "self::m:determinant" + then: [T: "determinant"] # phrase(the 2 by 2 'determinant') + else: [T: "matrise"] # phrase(the 2 by 2 'matrix') + - pause: long + - x: "*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: "slutt" # phrase(the 'end' of matrix has been reached) + - test: + if: "self::m:determinant" + then: [T: "determinant"] # phrase(the 2 by 2 'determinant') + else: [T: "matrise"] # 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: "nedre indeks"] # phrase(H 'subscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "senket"] # phrase(H 'sub' 2) + - x: "*[3]" + - test: + if: "$Verbosity='Terse'" + then: [pause: short] + +#NORWEGIAN: Added from English. Not tested +- name: dimension-by + tag: mrow + match: dimension-product + replace: + - insert: + nodes: "*" + replace: [T: "ganger", 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: "øvre indeks"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "hevet"] # 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: "øvre indeks"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "hevet"] # phrase(H 'super' 2) + - x: "$Prescripts[2]" + - pause: "short" + - test: + if: "not($Prescripts[1][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "nedre indeks"] # phrase(a 'subscript' may be used to indicate an index) + else_test: + if: "$Verbosity='Medium'" + then: [T: "senket"] # 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: "øvre indeks"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "hevet"] # phrase(H 'super' 2) + - x: "$Prescripts[4]" + - pause: "short" + - test: + if: "not($Prescripts[3][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "nedre indeks"] # phrase(H 'subscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "senket"] # 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: "nedre indeks"] # phrase(phrase(H 'subscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "senket"] # 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: "øvre indeks"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "hevet"] # 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: "nedre indeks"] # phrase(H 'subscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "senket"] # phrase(H 'sub' 2) + - x: "$Postscripts[3]" + - pause: "short" + - test: + if: "not($Postscripts[4][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "øvre indeks"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "hevet"] # 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: "nedre indeks"] # phrase(H 'subscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "senket"] # phrase(H 'sub' 2) + - x: "$Postscripts[5]" + - pause: "short" + - test: + if: "not($Postscripts[6][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "øvre indeks"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "hevet"] # 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: "nedre indeks"] # phrase(H 'subscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "senket"] # phrase(H 'sub' 2) + - x: "$Postscripts[7]" + - pause: "short" + - test: + if: "not($Postscripts[8][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "øvre indeks"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [T: "hevet"] # 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: "fast"] # phrase(Boron is a 'solid' in its natural state) + - else_if: ".='l'" + then: [T: "flytende"] # phrase(water is a 'liquid') + - else_if: ".='g'" + then: [T: "gass"] # phrase(hydrogen is a 'gass' ) + else: [T: "løst i vann"] # 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: "enkeltbinding"] # phrase(a 'single bond' is formed when two atoms share one pair of electrons) + - else_if: ".='=' or .='∷'" + then: [T: "dobbeltbinding"] # phrase(a 'double bond' may occur when two atoms share two pairs of electrons) + - else_if: ".='≡'" + then: [T: "trippelbindning"] # phrase(a 'triple bond' occurs when two atoms share three pairs of electrons) + - else_if: ".='≣'" + then: [T: "firedobbel binding"] # 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: "danner"] # phrase(hydrogen and oxygen 'forms' water ) + else: [T: "reaksjon danner"] # phrase(hydrogen and oxygen 'reacts to form' water) + - else_if: ".='⇌' or .='\u1f8d2'" + then: [T: "er i likevekt med"] # phrase(a reactant 'is in equilibrium with' a product) + - else_if: ".='\u1f8d4'" + then: [T: "er i likevekt med, venstre"] # phrase(the reactant 'is in equilibrium biased to the left with' the product) + - else_if: ".='\u1f8d3'" + then: [T: "er i likevekt med, høyre"] # 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/nb/SharedRules/geometry.yaml b/Rules/Languages/nb/SharedRules/geometry.yaml new file mode 100644 index 000000000..85bacf8d2 --- /dev/null +++ b/Rules/Languages/nb/SharedRules/geometry.yaml @@ -0,0 +1,73 @@ +--- + +- name: line-segment + tag: line-segment + match: "count(*)=2" + replace: + - test: + if: "$Verbosity='Verbose'" + then: + - T: "linjestykket fra" # phrase('the line segment from' A to B) + - x: "*[1]" + - T: "til" # phrase(the line segment from A 'to' B) + - x: "*[2]" + else: + - T: "linjestykke" # 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: "strålen fra" # phrase('the ray from' A to B) + - x: "*[1]" + - T: "til" # phrase(the ray from A 'to' B) + - x: "*[2]" + else: + - T: "stråle" # phrase(the 'ray'A B) + - x: "*[1]" + - x: "*[2]" + +- name: geometry-arc + tag: arc + match: "count(*)=2" + replace: + - T: "bue" # 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: "størrelsen på vinkelen" # phrase('the measure of the angle' ABC) + else: + - T: "vinkel" # phrase('measure of angle' ABC) + - x: "*[1]" + - x: "*[2]" + - x: "*[3]" + +#NORWEGIAN: Added from English, but not testet yet. +- name: coordinate + tag: coordinate + match: "." + replace: + - T: "punktet" # phrase(the 'point' at 1, 2) + - test: + if: "$Verbosity='Verbose'" + then: [T: "i"] # 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: "slutt punkt"] # phrase(start point, 'end point') \ No newline at end of file diff --git a/Rules/Languages/nb/SharedRules/linear-algebra.yaml b/Rules/Languages/nb/SharedRules/linear-algebra.yaml new file mode 100644 index 000000000..b7de31cae --- /dev/null +++ b/Rules/Languages/nb/SharedRules/linear-algebra.yaml @@ -0,0 +1,77 @@ +--- +- name: scalar-determinant + tag: determinant + match: "count(*)=1 and not(*[1][self::m:mtr])" + replace: + - T: "determinanten" # phrase(the 'determinant' of a matrix) + # NORWEGIAN: Removed test for Verbosity + - T: "til" # phrase(systems 'of' linear equations) + - x: "*[1]" + - test: + if: "not(IsNode(*[1], 'simple'))" + then: [T: "slutt determinant"] # phrase('end determinant' of a matrix) + +- name: subscripted-norm + tag: subscripted-norm + match: "count(*)=2" + replace: + - x: "*[2]" + - T: "normen" # phrase(the 'norm' can be a measure of distance) + # NORWEGIAN: Removed test for Verbosity + - T: "til" # phrase(systems 'of' linear equations) + - x: "*[1]" + +- name: homomorphism + # can't use IntentMappings because this doesn't fit the function pattern + tag: homomorphism + match: "count(*)=1" + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "mengden av homomorfier på"] + else: [T: "homomorfiene på"] + - x: "*[1]" + - test: + if: "$Impairment = 'Blindness' and not(*[last()][IsBracketed(., '', '') or IsNode(., 'simple')] )" + then: [T: "slutt homomorfier"] + - test: + if: "IsNode(., '2D')" + then: [pause: short] + else: [pause: auto] + +# NORWEGIAN: Removed test for Verbosity +- name: kernel + # can't use IntentMappings because this doesn't fit the function pattern + tag: kernel + match: "count(*)=1" + replace: + - T: "nullrommet" # phrase(this is the 'kernel' of the function) + - T: "til" # phrase(systems 'of' linear equations) + - x: "*[1]" + - test: + if: "$Impairment = 'Blindness' and not(*[last()][IsBracketed(., '', '') or IsNode(., 'simple')] )" + then: [T: "slutt nullrommet"] + - test: + if: "IsNode(., '2D')" + then: [pause: short] + else: [pause: auto] + +# NORWEGIAN: Kept these rules here, cause we say "dimensjonen til" and "normen til" instead of "dimensjonen av" and "normen av". +- name: dimension + tag: dimension + match: "count(*)=1" + replace: + - T: "dimensjonen" # phrase(the 'dimension' of the matrix) + - T: "til" # phrase(systems 'of' linear equations) + - x: "*[1]" + +- name: norm + tag: norm + match: "count(*)=1" + replace: + - T: "normen" # phrase(the 'norm' can be a measure of distance) + - T: "til" # phrase(this is the mean 'of' the data) + - x: "*[1]" + - test: + if: "not(IsNode(*[1], 'simple'))" + then: [{pause: short}, {T: "slutt norm"}] # phrase('end norm' that is a measure of distance) \ No newline at end of file diff --git a/Rules/Languages/nb/SimpleSpeak_Rules.yaml b/Rules/Languages/nb/SimpleSpeak_Rules.yaml new file mode 100644 index 000000000..870907e76 --- /dev/null +++ b/Rules/Languages/nb/SimpleSpeak_Rules.yaml @@ -0,0 +1,318 @@ +--- +- 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: + - T: "kvadratroten av" # phrase(the 'square root' of x) + # NORWEGIAN: Removed test for Verbosity + - x: "*[1]" + - test: + if: IsNode(*[1], 'leaf') + then: [pause: short] + else: [pause: short, T: "slutt rot", pause: short] # phrase(start the square root of x 'end of root') + +- name: default + tag: root + match: "." + replace: + - test: + if: "*[2][self::m:mn and not(contains(., $DecimalSeparators))]" #NORWEGIAN: Changed decimal point to $DecimalSeparators + then_test: + - if: "*[2][.='2']" + then: [T: "kvadratroten"] # phrase(the 'square root' of x) + - else_if: "*[2][.='3']" + then: [T: "kubikkroten"] # phrase(the 'cube root' of x) + - else: [x: "ToOrdinal(*[2])", T: "roten"] # phrase(the square 'root' of x) + else: + - T: "roten av grad" # phrase(the square 'root' of 36) + - x: "*[2]" + - pause: short + # SWEDISH: Removed verbosity settings. + - T: "av" # phrase(the square root 'of' 36) + - x: "*[1]" + - test: + if: IsNode(*[1], 'leaf') + then: [pause: short] + else: [pause: short, T: "slutt rot", 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(., $DecimalSeparators)) and text()<20] and" #NORWEGIAN: Changed decimal point to $DecimalSeparators + - "*[2][self::m:mn][not(contains(., $DecimalSeparators)) 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(., $DecimalSeparators))] and" #NORWEGIAN: Changed decimal point to $DecimalSeparators + - "*[2][self::m:mn][not(contains(., $DecimalSeparators)) 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 + +# Units (e.g., meters per second, m^2/s^2, (3m^2)/s) +#NORWEGIAN: Added rule for t="time" +- 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') or (contains(@data-intent-property, ':unit') and .='t')] " + replace: + - x: "*[1]" + - T: "per" # phrase('5 meters 'per' second) + - test: + if: "*[2]='t'" + then: [T: "time"] + else: + - 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: "over" # phrase(the fraction 3 'over' 4) + - x: "*[2]" + - pause: short + +- name: default + tag: fraction + match: "." + replace: + - T: "brøk" # phrase(the 'fraction' 3 over 4) + - pause: short + - x: "*[1]" + - test: + if: "not(IsNode(*[1],'leaf'))" + then: [pause: short] + - T: "over" # phrase(the fraction 3 'over' 4) + - test: + if: "not(IsNode(*[2],'leaf'))" + then: [pause: short] + - x: "*[2]" + - pause: short + - T: "slutt brøk" # 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: "invers" # 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: "i andre"] # phrase(5 'squared' equals 25) + else: [T: "i tredje"] # phrase(5 'cubed' equals 125) + +- name: function-power + tag: power + match: + - "following-sibling::*[1][self::m:mo][.='⁡']" #invisible function apply + replace: + - x: "*[1]" + - T: "opphøyd i" + - bookmark: "*[2]/@id" + - x: "*[2]" + - pause: short + +# 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: "i andre"] # phrase(5 'squared' equals 25) + else: [T: "i tredje"] # phrase(5 'cubed' equals 125) + +- name: simple-integer + tag: power + match: "*[2][self::m:mn][not(contains(., $DecimalSeparators))]" #NORWEGIAN: Changed decimal point to $DecimalSeparators + replace: + - x: "*[1]" + - T: "opphøyd i" + - x: "*[2]" + - pause: short + +- name: simple-negative-integer + tag: power + match: + - "*[2][self::m:minus and count(*)=1 and" + - " *[1][self::m:mn][not(contains(., $DecimalSeparators))]]" #NORWEGIAN: Changed decimal point to $DecimalSeparators + replace: + - x: "*[1]" + - T: "opphøyd i" + - x: "*[2]" + - pause: short + +- name: simple-var + tag: power + match: "*[2][self::m:mi][string-length(.)=1]" + replace: + - x: "*[1]" + - T: "opphøyd i" + - x: "*[2]" + - pause: short + +- name: simple + tag: power + match: "IsNode(*[2], 'leaf')" + replace: + - x: "*[1]" + - T: "opphøyd i" + - x: "*[2]" + - pause: short + +- 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: "opphøyd i" # phrase(15 'raised to the' second power equals 225) + - x: "*[2]" + - pause: short + - T: "slutt eksponent" # phrase(start 2 raised to the exponent 4 'end of exponent') + +- name: default + tag: power + match: "." + replace: + - x: "*[1]" + - T: "opphøyd i" # phrase(15 'raised to the' second power equals 225) + - x: "*[2]" + +# +# Some rules on mrows +# +- name: set + tag: set + match: "." + replace: + - test: + - if: "count(*)=0" + then: + - T: "den tomme mengden" # 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: + - T: "mengden av alle" # phrase(the 'set of all' positive integers less than 10) + - x: "*[1]/*[1]" + - T: "slik at" # phrase(x 'such that' x is less than y) + - x: "*[1]/*[3]" + else: + - T: "mengden" # phrase(here is a 'set' of numbers) + - x: "*[1]" + +# NORWEGIAN: Added sqrt, so it, for example, says "sqrt a times sqrt b" +- 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: "ganger" # 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/calculus.yaml" +- include: "SharedRules/general.yaml" +- include: "SharedRules/default.yaml" diff --git a/Rules/Languages/nb/definitions.yaml b/Rules/Languages/nb/definitions.yaml new file mode 100644 index 000000000..1dd967e96 --- /dev/null +++ b/Rules/Languages/nb/definitions.yaml @@ -0,0 +1,463 @@ +--- +- include: "../../definitions.yaml" +# Lines starting with "#" are a comment +# Each definition in this file is of the form +# name: [ "...", "..." "..." ], + +# If an "intent" is used, the 'terse:medium:verbose' speech for the intent name is given here for a prefix||infix||postfix||function fixity +# If only one ":" is used, 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= ; senket: senket: nedre indeks; slutt senket: slutt senket: slutt nedre indeks", + "modified-variable": "silent= ", + "say-super": "infix=opphøyd: øvre indeks: øvre indeks", # used with 'mo' for superscripts (e.g, "<") + "skip-super": "silent=", # used with 'mo' for superscripts (e.g, "*") + + "absolute-value": "function= ; absoluttverdien; slutt absoluttverdi", + "binomial": "infix=binomialkoeffisient; over; slutt binomialkoeffisient", + #"greatest-common-divisor": "function=gcd: gcd: største felles divisor", #NORWEGIAN: We say "største felles divisor til 8 og 4" (greatest common divisor to 8 and 4) + #"imaginary-part": "function=den imaginære delen, den imaginære delen, den imaginære delen", + #"least-common-multiple": "function=lcm: lcm: minste felles multiplum" #NORWEGIAN: We say "minste felles multiplum til 2 og 6" (least common multiplum to 2 and 6) + "limit": "prefix=grenseverdien når", + "lim-sup": "prefix=den øvre grenseverdien når", + "lim-inf": "prefix=den nedre grenseverdien når", + "logarithm-with-base": "prefix=log med grunntall: logaritmen med grunntall: logaritmen med grunntall", + #"natural-logarithm": "function=l n: den naturlige logaritmen: den naturlige logaritmen", + "minus": "infix=minus || prefix=minus", + "plus": "infix=pluss || prefix=pluss", + #"real-part": "function=den reelle delen", + + "transpose": "postfix=transponert || function=transponert", + #"norm": "function=; normen; slutt norm", #NORWEGIAN: We say "normen til" (the norm to), so this rule is in linear-algebra + "trace": "function=;sporet; slutt spor", + #"dimension": "function=; dimensjonen; slutt dimensjon", #NORWEGIAN: We say "dimensjonen til" (the dimension to), so this rule is in linear-algebra + # "homomorphism": "function= ; homomorfism; slut homomorfism", # doesn't fit function pattern + # "kernel": "function= ; noll-rummet : noll-rummet till: noll-rummet till; slut noll-rummet", # doesn't fit function pattern + "vector": "function= ; vektor: vektoren: vektoren || prefix=vektor: vektoren: vektoren", + "cross-product": "infix=kryss: kryssprodukt: kryssprodukt", + "dot-product": "infix=prikk: skalarprodukt: skalarprodukt", + + #"divergence": "function= ; div: divergens: divergens; slutt divergens", #NORWEGIAN: We say "divergensen til" (the divergence to), so this rule is in calculus. + #"curl": "function= ; curl; slutt curl", #NORWEGIAN: We say "curlen til" (the curl to), so this rule is in calculus + #"gradient": "function= ; grad: gradient: gradient; slutt gradient", #NORWEGIAN: We say "gradienten til" (the gradient to), so this rule is in calculus + "laplacian": "function=laplace", # speech engines don't do a good job with "laplacian" (swedish ones might) + } + +- NavigationParts: { + "large-op": "base; nedre grense; øvre grense", + "mfrac": "teller;nevner", + "fraction": "teller;nevner", + "msqrt": "rot", + "square-root": "rot", + "mroot": "rot;rotindeks", + "root": "rot;rotindeks", + "msub": "base;nedre indeks", + "sub": "base;nedre indeks", + "msup": "base;øvre indeks", + "say-super": "base;opphøyd", + "skip-super": "base;opphøyd", + "power": "base;eksponent", + "msubsup": "base;nedre indeks;øvre indeks", + "munder": "base;nedre grense", + "mover": "base;øvre grense", + "munderover": "base;nedre grense;øvre grense", + + # words for moving into and out of one of the parts (e.g., "move right 'out of' numerator, 'in' denominator") + # it's a hack to put them here, but at least they are grouped with the other navigation parts + "in": "i", + "out": "ut av", + } + +- 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": "desi", "c": "centi", "m": "milli", "µ": "mikro", "n": "nano", "p": "piko", "f": "femto", "a": "atto", "z": "zepto", "y": "yokto", "r": "ronto", "q": "quecto" + } + +# this is a list of all units that accept SIPrefixes +# from www.bipm.org/documents/20126/41483022/SI-Brochure-9-EN.pdf +# Prefixes may be used with any of the 29 SI units with special names +# The SI prefixes can be used with several of accepted units, but not, for example, with the non-SI units of time. +- SIUnits: { + # base units + "A": "ampere", + "cd": "candela", + "K": "kelvin", "K": "kelvin", # U+212A + "g": "gram", + "m": "meter", # British spelling works for US also + "mol": "mol", + "s": "sekund", "sek": "sekund", # "sec" not actually legal + + # derived units + "Bq": "becquerel", + "C": "coulomb", + "°C": "grad celsius", "℃": "grad celsius", # should only take negative powers + "F": "farad", + "Gy": "gray", + "H": "henry", + "Hz": "hertz", + "J": "joule", + "kat": "katal", + "lm": "lumen", + "lx": "lux", + "N": "newton", + "Ω": "ohm", "Ω": "ohm", # Greek Cap letter, U+2126 OHM SIGN + "Pa": "pascal", + "S": "siemens", + "Sv": "sievert", + "T": "tesla", + "V": "volt", + "W": "watt", + "Wb": "weber", + + # accepted (plus a few variants) that take SI prefixes + "l": "liter", "L": "liter", "ℓ": "liter", # Should only take negative powers; British spelling works for US also + "t": "tonn", # should only take positive powers + "Da": "dalton", + "Np": "neper", # should only take negative powers + "u": "atommasseenhet", # 'u' is correct: https://en.wikipedia.org/wiki/Dalton_(unit) + "eV": "elektronvolt", + "rad": "radian", # should only take negative powers + "sr": "steradian", # should only take negative powers + + # others that take a prefix + "a": "annuum", # should only take positive powers + "as": "buesekund", # see en.wikipedia.org/wiki/Minute_and_second_of_arc + + # technically wrong, but used in practice with SI Units + "b": "bit", # should only take positive powers + "B": "byte", # should only take positive powers + "Bd": "baud", # should only take positive powers + } + + +- UnitsWithoutPrefixes: { + # time + "″": "sekund", "\"": "sekund", + "′": "minutt", "'": "minutt", "min": "minutt", + "h": "time", "hr": "time", "Hr": "time", "t": "time", #NORWEGIAN: t is often used for hour, but t is officially the symbol for "tonn". Added to rule "per-fraction" in SimpleSpeak and ClearSpeak + "d": "dag", "dy": "dag", + "w": "uke", "wk": "uke", + "y": "år", "yr": "år", + + # angles + "°": "grad", "deg": "grad", # should only take negative powers + "arcmin": "bueminutt", + "amin": "bueminutt", + "am": "bueminutt", + "MOA": "bueminutt", + "arcsec": "buesekund", + "asec": "buesekund", + + # distance + "au": "astronomisk enhet", "AU": "astronomisk enhet", "a.u.": "astronomisk enhet", + "ltyr": "lysår", "ly": "lysår", "l.y.": "lysår", + "pc": "parsec", + "Å": "ångstrøm", "Å": "ångstrøm", # U+00C5 and U+212B + "fm": "fermi", #Norwegian: F is the official symbol for "fermi", but this is also the symbol for "Farad"... + + # others + "ha": "hektar", + # "B": "bel", # "B" more commonly means bytes + "dB": "desibel", # already logarithmic, so not used with SI prefixes + + "amu": "atommasseenhet", + "atm": "atmosfære", + "bar": "bar", + "cal": "kalori", + "Ci": "curie", + "grad": "gon", + "M": "molar", + "R": "røntgen", + "rpm": "omdreining per minutt", + "℧": "m-h-o", + "dyn": "dyn", + "erg": "erg", + + # powers of 2 used with bits and bytes + "Kib": "kibibit", "Mib": "mebibit", "Gib": "gibibit", "Tib": "tebibit", "Pib": "pebibit", "Eib": "exbibit", "Zib": "zebibit", "Yib": "yobibit", + "KiB": "kibibyte", "MiB": "mebibyte", "GiB": "gibibyte", "TiB": "tebibyte", "PiB": "pebibyte", "EiB": "exbibyte", "ZiB": "zebibyte", "YiB": "yobibyte", + } + + # this will only be used if the language is English, so it can be empty for other countries + # not necessarily! imperial units can still occur in e.g. Swedish textbooks: "Exercise: convert this into proper units", also some are usen in Swedish cook-books. /Tim +- EnglishUnits: { + # length + "in": "tomme", + "ft": "fot", + "mi": "mile", + "rd": "rod", + "li": "link", + "ch": "chain", + + # area + "sq in": "kvadrattomme", "sq. in": "kvadrattomme", "sq. in.": "kvadrattomme", + "sq ft": "kvadratfot", "sq. ft": "kvadratfot", "sq. ft.": "kvadratfot", + "sq yd": "kvadratyard", "sq. yd": "kvadratyard", "sq. yd.": "kvadratyard", + "sq mi": "kvadratmile", "sq. mi": "kvadratmile", "sq. mi.": "kvadratmile", + "ac": "engelsk acre", + "FBM": "board foot", + + # volume + "cu in": "kubikktomme", "cu. in": "kubikktomme", "cu. in.": "kubikktomme", + "cu ft": "kubikkfot", "cu. ft": "kubikkfot", "cu. ft.": "kubikkfot", + "cu yd": "kubikkyard", "cu. yd": "kubikkyard", "cu. yd.": "kubikkyard", + "bbl": "fat", "BBL": "fat", + "pk": "peck", + "bu": "bushel", + "tsp": "teskje", "tsk": "teskje", "ts": "teskje", + "tbl": "spiseskje", "tbsp": "spiseskje", "ss": "spiseskje", + + # liquid + "fl dr": "fluid dram", + "fl oz": "fluid ounce", + "gi": "gill", + "cp": "kopp", "cup": "kopp", + "pt": "pint", + "qt": "quart", + "gal": "gallon", + + # weight + "gr": "grain", + "dr": "dram", + "oz": "ounce", "℥": "ounce", + "lb": "pund", + "cwt": "hundredweight", + "dwt": "pennyweight", + "oz t": "ounce troy", + "lb t": "pound troy", + + # energy + "hp": "hestekraft", "hk": "hestekraft", + "BTU": "B-T-U", + "°F": "grad fahrenheit", "℉": "grad fahrenheit", + + # other + "mph": "mile per hour", + "mpg": "mile per gallon", + } + +- PluralForms: { + # SWEDISH: this should be complete. Units not listed here are not modified when pluralised. /Tim + "sekund": "sekunder", + "grad celsius": "grader celsius", + "atommasseenhet": "atommasseenheter", + "radian": "radianer", + "steradian": "steradianer", + "buesekund": "buesekunder", + #"bit": "bits", + #"byte": "bytes", + "baud": "bauder", + "minutt": "minutter", + "time": "timer", + "dag": "dager", + "uke": "uker", + "grad": "grader", + "bueminutt": "bueminutter", + "astronomisk enhet": "astronomiske enheter", + "atmosfære": "atmosfærer", + "kalori": "kalorier", + #"kibibit": "kibibits", + #"mebibit": "mebibits", + #"gibibit": "gibibits", + #"tebibit": "tebibits", + #"pebibit": "pebibits", + #"exbibit": "exbibits", + #"zebibit": "zebibits", + #"yobibit": "yobibits", + #"kibibyte": "kibibytes", + #"mebibyte": "mebibytes", + #"gibibyte": "gibibytes", + #"tebibyte": "tebibytes", + #"pebibyte": "pebibytes", + #"exbibyte": "exbibytes", + #"zebibyte": "zebibytes", + #"yobibyte": "yobibytes", + "mile": "miles", + "rod": "rods", + "link": "links", + "chain": "chains", + "kvadratmile": "kvadratmiles", + "engelsk acre": "engelske acre", + "bushel": "bushels", + "teskje": "teskjeer", + "spiseskje": "spiseskjeer", + #"fluid dram": "fluid drams", + "fluid ounce": "fluid ouncer", + "ounce": "ouncer", + "kopp": "kopper", + "pint": "pints", + "quart": "quarts", + "grain": "grains", + #"hundredweight": "hundredweights", + #"pennyweight": "pennyweights", + "hestekraft": "hestekrefter", + "grad fahrenheit": "grader fahrenheit", + "mile per hour": "miles per hour", + "mile per gallon": "miles per gallon", + "tomme": "tommer", + "kvadrattomme": "kvadrattommer", + "kubikktomme": "kubikktommer", + "omdreining per minutt": "omdreininger per minutt", + "curie": "curier", + "annuum": "annua", + + } + +- NeuterUnits: { + #SIUnits + "g": "gram", + "mol": "mol", + "s": "sekund", "sek": "sekund", + "t": "tonn", + "a": "annuum", + "as": "buesekund", + + #UnitsWithoutPrefixes + "″": "sekund", "\"": "sekund", + "′": "minutt", "'": "minutt", "min": "minutt", + "y": "år", "yr": "år", + "arcmin": "bueminutt", "amin": "bueminutt", "am": "bueminutt", "MOA": "bueminutt", + "arcsec": "buesekund", "asec": "buesekund", + "ltyr": "lysår", "ly": "lysår", "l.y.": "lysår", + + #EnglishUnits + "bbl": "fat", "BBL": "fat", + "lb": "pund", + } + + +# ---------------- 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. + +# NORWEGIAN: The pattern for fraction is not correct. +# 1/20 = "1 tjuende". Needs a number set for NumbersOrdinalFractionalTens. ("tidel", "tjuedel"...) +# 2/24 = "2 tjue fjerde". The set NumbersOrdinalPluralOnes should be changed to ("", "endeler", "todeler", "tredeler"...) +# 1/100 = "1 hundrede". Needs a number set for NumbersOrdinalFractionalHundreds". ("hundredel", "to hundredel"...) +# 1/1000 = "1 én tusende". Needs number set for NumbersOrdinalFractionalLargeNumbers, and "én" should be removed. ("tusendel", "milliondel"...) +# 2/1000 = "2 én tusendeler". Needs to remove "én". +# 2/1008 = "2 én tusen åttende" + +# For English, a regular pattern starts at twenty +# NORWEGIAN: Added in front of the numbers in "NumbersOrdinalLarge" and "NumbersLarge". Easiest to just remove "én", but you will probably never see these big ordinal numbers. +- NumbersOnes: [ + "null", "én", "to", "tre", "fire", "fem", "seks", "sju", "åtte", "ni", + "ti", "elleve", "tolv", "tretten", "fjorten", "femten", "seksten", + "sytten", "atten", "nitten" + ] + +- NumbersOrdinalOnes: [ + "nullte", "første", "andre", "tredje", "fjerde", "femte", "sjette", "sjuende", "åttende", "niende", + "tiende", "ellevte", "tolvte", "trettende", "fjortende", "femtende", "sekstende", + "syttende", "attende", "nittende" + ] + +# NORWEGIAN: Should be changed to "", "endeler", "todeler"...Then, for example, the fraction 2/24 will be "2 tjue firedeler" +- NumbersOrdinalPluralOnes: [ + "nullte", "første", "andre", "tredje", "fjerde", "femte", "sjette", "sjuende", "åttende", "niende", + "tiende", "ellevte", "tolvte", "trettende", "fjortende", "femtende", "sekstende", + "syttende", "attende", "nittende" + ] + + # stop when regularity begins +- NumbersOrdinalFractionalOnes: [ + "nulldel", "hel", "halv", "tredjedel", "fjerdedel", "femtedel", "sjettedel", "sjudel", "åttedel", "nidel", "tidel", "ellevedel", + "tolvdel", "trettendel", "fjortendel", "femtendel", "sekstendel", "syttendel", "attendel", "nittendel" + ] + + # stop when regularity begins +- NumbersOrdinalFractionalPluralOnes: [ + "nulldeler", "hele", "halve", "tredjedeler", "fjerdedeler", "femtedeler", "sjettedeler", "sjudeler", "åttedeler", "nideler", + "tideler", "ellevedeler", "tolvdeler", "trettendeler", "fjortendeler", "femtendeler", "sekstendeler", + "syttendeler", "attendeler", "nittendeler" + ] + + # What to use for multiples of 10 +- NumbersTens: [ + "", "ti", "tjue", "tretti", "førti", "femti", "seksti", "sytti", "åtti", "nitti" + ] + +- NumbersOrdinalTens: [ + "", "tiende", "tjuende", "trettiende", "førtiende", "femtiende", "sekstiende", "syttiende", "åttiende", "nittiende" + ] + +- NumbersOrdinalPluralTens: [ + "", "tideler", "tjuedeler", "trettideler", "førtideler", "femtideler", "sekstideler", "syttideler", "åttideler", "nittideler" + ] + +- NumbersHundreds: [ + "", "hundre", "to hundre", "tre hundre", "fire hundre", "fem hundre", + "seks hundre", "sju hundre", "åtte hundre", "ni hundre" + ] + +- NumbersOrdinalHundreds: [ + "", "hundrede", "to hundrede", "tre hundrede", "fire hundrede", "fem hundrede", + "seks hundrede", "sju hundrede", "åtte hundrede", "ni hundrede" + ] + +- NumbersOrdinalPluralHundreds: [ + "", "hundredeler", "to hundredeler", "tre hundredeler", "fire hundredeler", "fem hundredeler", + "seks hundredeler", "sju hundredeler", "åtte hundredeler", "ni hundredeler" + ] + + # At this point, hopefully the language is regular. If not, code needs to be written +- NumbersLarge: [ + "", "tusen", "million", "milliard", "billion", "billiard", + "trillion", "trilliard", "kvadrillion", "kvadrilliard", "kvintillion", + "kvintilliard","sekstillion","sekstilliard","septillion","septilliard", + "oktillion","oktilliard","nonillion","nonilliard","desillion" + ] + #NORWEGIAN: These big numbers are never used. + #"desilliard","undesillion","undesilliard","duodesillion","tredesillion", + #"tredesilliard","kvattordesillion","kvattordesilliard","kvindesillion","kvindesilliard", + #"seksdesillion","seksdesilliard","septendesillion","septendesilliard", + #"oktodesillion","oktodesilliard","novemdesillion","novemdesilliard","vigintillion", + #"vigintilliard","unvigintillion","unvigintilliard","centillion","centilliard" + #] + +- NumbersOrdinalLarge: [ + "", "tusende", "millionte", "milliardte", "billionte", "billiardte", + "trillionte", "trilliardte", "kvadrillionte", "kvadrilliardte", "kvintillionte", + "kvintilliardte","sekstillionte","sekstilliardte","septillionte","septilliardte", + "oktillionte","oktilliardte","nonillionte","nonilliardte","desillionte" + ] + + #"desilliardte","undesillionte","undesillardte","duodesillionte","tredesillionte", + #"tredesilliardte","kvattordesillionte","kvattordesilliardte","kvindesillionte","kvindesilliardte", + #"seksdesillionte","seksdesilliardte","septendesillionte","septendesilliardte", + #"oktodesillionte","oktodesilliardte","novemdesillionte","novemdesilliardte","vigintillionte", + #"vigintilliardte","unvigintillionte","unvigintilliardte","centillionte","centilliardte" + #] + +- NumbersOrdinalPluralLarge: [ + "", "tusendeler", "milliondeler", "milliarddeler", "billiondeler", "billiarddeler", + "trilliondeler", "trilliarddeler", "kvadrilliondeler", "kvadrilliarddeler", "kvintilliondeler", + "kvintilliarddeler","sekstilliondeler","sekstilliarddeler","septilliondeler","septilliarddeler", + "oktilliondeler","oktilliarddeler","nonilliondeler","nonilliarddeler","desilliondeler" + ] + + #"desilliarddeler","undesilliondeler","undesilliarddeler","duodesilliondeler","tredesilliondeler", + #"tredesilliarddeler","kvattordesilliondeler","kvattordesilliarddeler","kvindesilliondeler","kvindesilliarddeler", + #"seksdesilliondeler","seksdesilliarddeler","septendesilliondeler","septendesilliarddeler", + #"oktodesilliondeler","oktodesilliarddeler","novemdesilliondeler","novemdesilliarddeler","vigintilliondeler", + #"vigintilliarddeler","unvigintilliondeler","unvigintilliarddeler","centilliondeler","centilliarddeler" + #] diff --git a/Rules/Languages/nb/navigate.yaml b/Rules/Languages/nb/navigate.yaml new file mode 100644 index 000000000..71863ab26 --- /dev/null +++ b/Rules/Languages/nb/navigate.yaml @@ -0,0 +1,1778 @@ +--- +# Documentation: +# +# The general form for many rules is: +# 1. Say the command if this is first rule to fire (MatchCounter) and depending upon "NavVerbosity"s value +# 2. Say info about moving into/out of 2D structures +# 3. Set some variables and possibly recurse. +# If recursing, "MatchCounter" should be incremented. +# If stopping, "NavNode" should be set. +# +# The meaning of NavVerbosity: +# * Verbose -- always echo the command and end points (e.g., "can't move right") +# * Medium -- only echo the command for obscure commands like the placemarker commands; also say end points +# * Terse -- no echo of commands or end points +# +# For the second item, a common set of rules is used. These rules require the variable "Move2D" +# to be set along with "Child2D", where "Move2D" is either 'in' or 'out'. +# +# In addition, the navigation rules make use of two functions: +# +# int DistanceFromLeaf(node, leftSide, treat2DElementsAsTokens) +# Returns the distance (number of children) until a leaf is reached by traversing the leftmost/rightmost child +# If 'treat2DElementsAsTokens' is true, then 2D notations such as fractions are treated like leaves +# A leaf has distance == 0 +# +# EdgeNode(node, "left"/"right", stopNodeName) +# Returns the stopNode if at left/right edge of named ancestor node. 'stopNodeName' can also be "2D" +# If the stopNode isn't found, the original node is returned +# Note: if stopNodeName=="math", then punctuation is taken into account since it isn't really part of the math +# +# A few other variables are of importance to Navigation +# NavMode -- Enhanced, Simple, Character +# ReadZoomLevel -- -1 for Enhanced, otherwise the distance from leaf the rules should maintain +# PlaceMarkerIndex + + +# Rules for speaking what happens when moving into or out of a notation +- name: into-or-out-of + tag: mfrac + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "telleren"] # phrase(the 'numerator' of a fraction) + else: [T: "nevneren"] # phrase(the 'denominator' of a fraction) + - pause: "medium" + +- name: into-or-out-of + tag: msqrt + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - T: "kvadratroten" # phrase(the 'square root' of x) + - pause: "medium" + +- name: into-or-out-of + tag: mroot + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "roten"] # phrase(the cube 'root' of x) + else: [T: "rotindeksen"] # phrase(the 'root index' of x is 3) + - pause: "medium" + +#NORWEGIAN: For powers we say "grunntallet" for the base, but since this markup is used for other things than powers and subindexes, use the word "basen". +- name: into-or-out-of + tag: msub + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "basen"] # phrase(the 'base' of the power) + else: [T: "nedre indeks"] # phrase(x with 'subscript' 2) + - pause: "medium" + +- name: into-or-out-of + tag: msup + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "basen"] # phrase(the 'base' of the power) + else: [T: "øvre indeks"] # phrase(x with 'superscript' 2) # FIX: it would be better to use the word used when reading (power, exponent, ...) + - pause: "medium" + +- name: into-or-out-of + tag: msubsup + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + - if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "basen"] # phrase(the 'base' of the power) + - else_if: "count($Child2D/preceding-sibling::*)=1" + then: [T: "nedre indeks"] # phrase(x with 'subscript' 2) + else: [T: "øvre indeks"] # phrase(x with 'superscript' 2) # FIX: it would be better to use the word used when reading (power, exponent, ...) + - pause: "medium" + +- name: into-or-out-of + tag: munder + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "basen"] # phrase(the 'base' of the power) + else: [T: "nedre indeks"] # phrase(the 'lower limit' of the function is zero) + - pause: "medium" + +- name: into-or-out-of + tag: mover + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "basen"] # phrase(the 'base' of the power) + else: [T: "øvre indeks"] # phrase(the 'upper limit' of the function is zero) + - pause: "medium" + +- name: into-or-out-of + tag: munderover + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + - if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "basen"] # phrase(the 'base' of the power) + - else_if: "count($Child2D/preceding-sibling::*)=1" + then: [T: "nedre indeks"] # phrase(the 'lower limit' of the function is zero) + else: [T: "øvre indeks"] # phrase(the 'upper limit' of the function is zero) + - pause: "medium" + +- name: into-or-out-of + tag: mmultiscripts + match: "$Move2D != ''" + replace: + - test: + if: "name($Child2D)!='none'" + then: + - with: + variables: + - NumPrecedingSiblings: "count($Child2D/preceding-sibling::*)" + replace: + - x: "$Move2D" + - test: + - if: "$NumPrecedingSiblings=0" + then: [T: "basen"] # 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: "nedre indeks"] # phrase(x with 'subscript' 2) + else: [T: "øvre indeks"] # phrase(x with 'superscript' 2) + else: + - test: + if: "$NumPrecedingSiblings mod 2 = 0" + then: [T: "øvre indeks"] # phrase(x with 'superscript' 2) + else: [T: "nedre indeks"] # phrase(x with 'subscript' 2) + - pause: "medium" + +- name: into-or-out-of + tag: mtd + match: "$Move2D = 'into'" + replace: + - x: "$Move2D" + - T: "kolonne" # phrase(the first 'column' in the table) + - x: "count($Child2D/preceding-sibling::*)+1" + - pause: "medium" + +- name: into-or-out-of + tag: [mtr, mlabeledtr] + match: "$Move2D = 'into'" + replace: + - x: "$Move2D" + - x: "count($Child2D/preceding-sibling::*)+1" + - pause: "medium" + +- name: default-move + # nothing to do (not 2D) -- need to catch $Move2D though so rules based on NavCommand don't trigger + tag: "*" + match: "$Move2D != ''" + replace: [] + +# ********* Go back to last position *************** +# This is first since start/end position shouldn't matter +- name: move-last-location + + + tag: "*" + match: "$NavCommand = 'MoveLastLocation'" + replace: + - test: + if: "$NavVerbosity != 'Terse'" + then: + - test: + - if: "$PreviousNavCommand = 'ZoomIn'" + then: [T: "angre innzooming"] # phrase('undo zoom in') + - else_if: "$PreviousNavCommand = 'ZoomOut'" + then: [T: "angre utzooming"] # phrase('undo zoom out') + - else_if: "$PreviousNavCommand = 'ZoomInAll'" + then: [T: "angre innzooming hele veien"] # phrase('undo zooming in all the way') + - else_if: "$PreviousNavCommand = 'ZoomOutAll'" + then: [T: "angre utzooming hele veien"] # phrase('undo zooming out all the way') + - else_if: "$PreviousNavCommand = 'MovePrevious' or $PreviousNavCommand = 'MovePreviousZoom'" + then: [T: "angre gå venstre"] # phrase('undo move left') + - else_if: "$PreviousNavCommand = 'MoveNext' or $PreviousNavCommand = 'MoveNextZoom'" + then: [T: "angre gå høyre"] # phrase('undo move right') + - else_if: "$PreviousNavCommand = 'None'" + then: [T: "ingen tidligere kommandoer"] # phrase('no previous command') + - pause: "long" + - set_variables: [NavNode: "@id"] + +# many times, for typographic reasons, people include punctuation at the end of a math expr +# these rules detect that and skip speaking it (should be similar regular rule) +- name: skip-punct-at-end-zoom-in + tag: mrow + match: + - "($NavCommand = 'ZoomIn' or $NavCommand = 'ZoomInAll' or $NavCommand = 'MoveNextZoom' or $NavCommand = 'MovePreviousZoom') and" + - " parent::m:math and count(*)=2 and" + - " *[2][translate(.,'.,;:?', '')='']" + replace: + - x: "*[1]" + +# ********* ZoomIn *************** +- name: zoom-in-leaf + + tag: "*" + match: "($NavCommand = 'ZoomIn' or $NavCommand = 'ZoomInAll') and IsNode(., 'leaf')" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse'" + then: [T: "innzoomet hele veien", 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 matrix or determinant -- move to the first row +- name: zoom-in-matrix + + tag: mrow + match: + - "$NavCommand = 'ZoomIn' and count(*)=3 and " + - "*[2][self::m:mtable and (IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|'))]" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "zoom inn", pause: "long"] # phrase('zoom in') + - set_variables: [NavNode: "*[2]/*[1]/@id"] + +# special case of zooming into a table -- move to the first row +- name: zoom-in-table + tag: mtable + match: "$NavCommand = 'ZoomIn'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "zoom inn", pause: "long"] # phrase('zoom in') + - set_variables: [NavNode: "*[1]/@id"] + +- name: zoom-in-mrow-in-math + # Moving to first or last is meaningless the 'math' has only an 'mrow' inside -- dig inside and do it again + tag: math + match: "count(*)=1 and ($NavCommand = 'ZoomIn' or $NavCommand = 'MoveNextZoom' or $NavCommand = 'MovePreviousZoom')" + replace: + - test: + if: "$NavCommand = 'MovePreviousZoom'" + then: [x: "*[last()]"] + else: [x: "*[1]"] + +- # For msqrt and menclose, if the single child isn't an mrow, don't zoom in + name: zoom-in-again + # If there is only one child, this isn't an interesting move -- zoom in again + tag: "*" + match: + - "($NavCommand = 'ZoomIn' or " + - " ($NavCommand = 'MoveNextZoom' or $NavCommand = 'MovePreviousZoom') and $NavMode='Enhanced') and " + - "count(*)=1 and (*[1][self::m:mrow] and not(self::m:msqrt or self::m:menclose))" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "zoom inn", pause: "long"] # phrase('zoom in') + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: + - test: + if: "$NavCommand = 'MovePreviousZoom'" + then: [x: "*[last()]"] + else: [x: "*[1]"] + +- name: zoom-in-enhanced + + tag: "*" + match: "$NavCommand = 'ZoomIn' and $NavMode='Enhanced'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "zoom inn", pause: "long"] # phrase('zoom in') + - test: + - if: "self::m:mtr or self::m:mlabeledtr" + then: + - with: + variables: [Move2D: "'i'", 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: "'i'", Child2D: "*[1]/*[2]"] # phrase('in' the denominator) + replace: [x: "."] + - set_variables: [NavNode: "*[1]/*[2]/@id"] # skip mtd + else: + - with: + variables: [Move2D: "'i'", 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')" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "zoom inn", pause: "long"] # phrase('zoom in') + - with: + variables: [Move2D: "'i'", Child2D: "*[1]"] # phrase('in' the denominator) + replace: [x: "."] + - with: + variables: [MatchCounter: "$MatchCounter + 1", NavCommand: "'MoveNextZoom'"] + replace: [x: "*[1]"] + +- name: zoom-in-default + tag: "*" + match: "$NavCommand = 'ZoomIn'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "zoom inn", pause: "long"] # phrase('zoom in') + - with: + variables: [Move2D: "'i'", Child2D: "*[1]"] # phrase('in' the denominator) + replace: [x: "."] + - test: + if: "$NavMode='Character'" + then: + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: "*[1]"] + else_test: + if: "self::m:mtd" + then: [x: "*[1]"] + else: + - test: + if: "$ReadZoomLevel!=-1" + then: + - set_variables: [ReadZoomLevel: "DistanceFromLeaf(*[1], true, $NavMode!='Character')"] + - set_variables: [NavNode: "*[1]/@id"] + +- name: zoom-in-all-default + tag: "*" + match: "$NavCommand = 'ZoomInAll'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "zoom inn hele veien", pause: "medium"] # phrase('zoom in all the way') + - with: + variables: [Move2D: "'i'", Child2D: "*[1]"] # phrase('in' the denominator) + replace: [x: "."] + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: "*[1]"] + +- name: zoom-out + tag: math + match: "$NavCommand = 'ZoomOut' or $NavCommand = 'ZoomOutAll'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse'" + then: [T: "utzoomet hele veien", pause: "long"] # phrase('zoomed out all the the way') + - set_variables: [NavNode: "*[1]/@id"] # no-op for $NavCommand = 'ZoomOut' + +- name: zoom-out-top + tag: "*" + match: + - "($NavCommand = 'ZoomOut' or $NavCommand = 'ZoomOutAll') and" + - "parent::m:math " + replace: + - x: ".." # let math rule deal with it + +- name: skip-punct-at-end-zoom-out + tag: mrow + match: + - "($NavCommand = 'ZoomOut' or $NavCommand = 'ZoomOutAll') and" + - " parent::m:math and count(*)=2 and" + - " *[2][translate(.,'.,;:?', '')='']" + replace: + - x: ".." + +- name: zoom-out-all-default + tag: "*" + match: "$NavCommand = 'ZoomOutAll'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse'" + then: [T: "utzoomet hele veien", pause: "medium"] # phrase('zoomed out all the the way') + - with: + variables: [Move2D: "'ut av'", Child2D: "."] + replace: [x: ".."] + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: ".."] + +# deal with internal zooming: MoveNextZoom and MovePreviousZoom + +# start with Enhanced mode +- name: move-zoom-enhanced + tag: "*" + match: + - "($NavCommand = 'MoveNextZoom' or $NavCommand = 'MovePreviousZoom') and " + - "$NavMode = 'Enhanced'" + replace: + # don't bother with MatchCounter since we only get here if > 1 + - with: + variables: [Move2D: "'i'", Child2D: "*[1]"] # phrase('in' the denominator) + replace: [x: "."] + - test: + - if: "count(*)> 1 or IsNode(., 'leaf') or self::m:msqrt or self::m:menclose" + then: [set_variables: [NavNode: "@id"]] + else: [x: "*[1]"] + +- name: move-next-zoom-not-enhanced + # $ReadZoomLevel must be >= 0 + tag: "*" + match: "$NavCommand = 'MoveNextZoom'" + replace: + #don't bother with MatchCounter since we only get here if > 1 + - test: + if: "$ReadZoomLevel >= DistanceFromLeaf(., false, $NavMode!='Character')" + then: + # - with: + # variables: [Move2D: "'i'", Child2D: "following-sibling::*[1]"] # phrase('in' the denominator) + # replace: [x: ".."] + - set_variables: [NavNode: "@id"] + else: + - with: + variables: [Move2D: "'i'", 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: "'i'", Child2D: "preceding-sibling::*[1]"] # phrase('in' the denominator) + # replace: [x: ".."] + - set_variables: [NavNode: "@id"] + else: + - with: + variables: [Move2D: "'i'", Child2D: "*[last()]"] # phrase('in' the denominator) + replace: [x: "."] + - x: "*[last()]" + +# ********* ZoomOut *************** +- name: zoom-out-default + + + tag: mtd + match: "$Move2D = '' and ($NavCommand = 'ZoomOut')" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "zoom ut", pause: "medium"] # phrase('zoom out' of expression) + # we need to speak it here + - T: "rad" # 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: [MatchCounter: "$MatchCounter + 1"] + replace: + - test: + if: "$MatchCounter = 1 and $NavVerbosity = 'Verbose'" + then: [T: "zoom ut", pause: "medium"] # phrase('zoom out' of the expression) + - 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: "'ut av'", 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: "gå til start matematikk"] # phrase('move to start of math') + - else_if: "$NavCommand = 'MoveLineStart'" + then: [T: "gå til starten av raden"] # phrase('move to start of line') + - else_if: "$NavCommand = 'MoveEnd'" + then: [T: "gå til slutt matematikk"] # phrase('move to end of math') + else: [T: "gå til slutten av raden"] # "$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) + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "*[1]/*[1]"] + else: + - with: + variables: [NavCommand: "'MovePreviousZoom'"] + replace: [x: "*[last()]/*[last()]"] + +# We stop when the parent is 2d (e.g., frac), but not if in leaf base of msub/msup/msubsup/mmultiscripts because that's really on the same line +- name: move-to-start-or-end-2d + tag: "*" + match: + - "($NavCommand = 'MoveLineStart' or $NavCommand = 'MoveLineEnd') and IsNode(.., '2D') and" + - "not( IsNode(., 'leaf') and (parent::m:msub or parent::m:msup or parent::m:msubsup or parent::m:mmultiscripts) )" + replace: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - test: + if: "$NavCommand = 'MoveLineStart'" + then: [T: "gå til starten av raden"] # phrase('move to start of line') + else: [T: "gå til slutten av raden"] # "$NavCommand = 'MoveLineEnd'" # phrase('move to end of line') + - pause: "medium" + - test: + if: "self::m:mrow" + then_test: + if: "$NavCommand = 'MoveLineStart'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "*[1]"] + else: + - with: + variables: [NavCommand: "'MovePreviousZoom'"] + replace: [x: "*[last()]"] + else: [set_variables: [NavNode: "@id"]] + +- name: move-to-start-or-end-default + tag: "*" + match: "$NavCommand = 'MoveStart' or $NavCommand = 'MoveLineStart' or $NavCommand = 'MoveEnd' or $NavCommand = 'MoveLineEnd'" + replace: + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: ".."] + +# Table-related movement +# Typically, we need to zoom out to the mtd level, then we move the appropriate direction +- name: not-in-table + + + tag: math + match: + - "$NavCommand='MoveCellPrevious' or $NavCommand='MoveCellNext' or" + - "$NavCommand='MoveCellUp' or $NavCommand='MoveCellDown' or" + - "$NavCommand='MoveColumnStart' or $NavCommand='MoveColumnEnd' or" + - "$NavCommand='ReadCellCurrent'" + replace: + - T: "ikke i tabell" # 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: "gå venstre" # phrase('move left') + - pause: short + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "kolonne" # 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: "ingen foregående kolonner" # 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: "gå høyre" # phrase('move right') + - pause: short + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "kolonne" # 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: "ingen påfølgende kolonner" # 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: "gå opp" # phrase('move up' to previous row in the table) + - pause: short + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "rad" # phrase(the previous 'row' in the table) + - x: "count(../preceding-sibling::*)" + - pause: short + - T: "kolonne" # 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: "ingen foregående rader" # 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: "gå ned" # phrase('move down to the next row in the table) + - pause: short + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "rad" # phrase(the next 'row' in the table) + - x: "count(../preceding-sibling::*)+2" + - pause: short + - T: "kolonne" # 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: "ingen påfølgende rader" # phrase('no next row' in the table) + - set_variables: [SpeakExpression: "'false'"] + +- name: move-cell-up + tag: [mtr, mlabeledtr] + match: "$NavCommand='MoveCellUp'" + replace: + - test: + if: "preceding-sibling::*" + then: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "gå opp" # phrase('move up' to the previous row in the table) + - pause: medium + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "rad" # phrase(the previous 'row' in the table) + - x: "count(preceding-sibling::*)" + - pause: medium + - test: + if: "$NavMode='Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "preceding-sibling::*[1]"] + else: + - set_variables: [NavNode: "preceding-sibling::*[1]/@id"] + else: + - T: "ingen foregående rader" # phrase('no previous row' in the table) + - set_variables: [SpeakExpression: "'false'"] + +- name: move-cell-down + tag: [mtr, mlabeledtr] + match: "$NavCommand='MoveCellDown'" + replace: + - test: + if: "following-sibling::*" + then: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "gå ned" # phrase('move down' to the next row in the table) + - pause: medium + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "rad" # phrase(the previous 'row' 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]/@id"] + else: + - T: "ingen påfølgende rader" # 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: "les nåværende verdi" # phrase('read current entry' in the table) + - pause: medium + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "rad" # phrase(the previous 'row' in the table) + - x: "count($MTD[1]/../preceding-sibling::*)+1" + - T: "kolonne" # 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: "ikke i tabell" # 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: "ikke i tabell" # 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: "'i'", 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: "'i'", 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: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: "gå"] # phrase('move' to next entry in table) + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "les"] # phrase('read' next entry in table) + else: [T: "beskriv"] # phrase('describe' next entry in table) + - T: "høyre" # phrase(move 'right') # phrase(move 'right') + - pause: short + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: + - test: + if: "following-sibling::*[1][.='\u2062' or .='\u2064'] and $NavMode='Enhanced'" # invisible times and plus + then: [set_variables: [NavNode: "following-sibling::*[1]/@id"]] + else: [x: "following-sibling::*[1]"] + +- name: move-next-no-auto-zoom-at-edge + # at edge of 2D and in a mode where moving right isn't an option + tag: "*" + variables: [EdgeNode: "EdgeNode(., 'right', '2D')"] + match: "$NavCommand = 'MoveNext' and $NavMode!='Character' and not($AutoZoomOut) and $EdgeNode/@id!=@id" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse' and $NavCommand = 'MoveNext'" + then: + - T: "kan ikke gå til høyre" # phrase('cannot move right') + - with: + variables: [Move2D: "'end of'", Child2D: "$EdgeNode/*[last()]"] #Should "end of" be translated? + replace: [x: "$EdgeNode"] + - pause: long + - set_variables: [SpeakExpression: "'false'"] + +- name: move-next-no-auto-zoom-at-edge-math + # at edge of math -- no where to go (must be after we rule out being at the edge of 2D) because we want to speak that + tag: "*" + match: + - "($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext') and" + - "(self::m:math or name(EdgeNode(., 'right', 'math'))='math')" # at edge of math + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse'" + then: + - T: "kan ikke" # phrase('cannot' move right in expression) + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: "gå"] # phrase('move' to next entry in table) + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "lese"] # phrase('read' next entry in table) + else: [T: "beskrive"] # phrase('describe' next entry in table) + - T: "høyre, slutt matematikk" # phrase(move 'right, 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: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: "gå"] # phrase('move' to next entry in table) + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "les"] # phrase('read' next entry in table) + else: [T: "beskriv"] # phrase('describe' next entry in table) + - T: "høyre" # phrase(move 'right') # phrase(move 'right') + - pause: short + - with: + variables: [MatchCounter: "$MatchCounter + 1", NavCommand: "'MoveNext'"] + replace: + - test: + if: "following-sibling::*" + then: + - with: + variables: [Move2D: "'i'", Child2D: "."] # phrase('in' the denominator) + replace: [x: ".."] + else: + - with: + variables: [Move2D: "'ut av'", Child2D: "."] + replace: [x: ".."] + - test: + if: "following-sibling::*" + then: + - x: ".." # move out of parens + else: + - x: ".." + +# At this point, if XXXNext, then we know there is must be a right sibling +- name: move-next-default + tag: mtd + match: "$Move2D = '' and ($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext')" + replace: + - test: + # can't get here with MatchCounter=0, so no need to echo command + if: "following-sibling::*" + then: + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "kolonne" # 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')" + replace: + - test: + # can't get here with MatchCounter=0, so no need to echo command + if: "following-sibling::*" + then: + - T: "rad" # phrase(the previous 'row' in the table) + - x: "count(preceding-sibling::*)+2" + - T: "kolonne 1" # phrase('column 1' in the table) + - pause: medium + - test: + if: "$NavMode = 'Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "following-sibling::*[1]"] + else: + - set_variables: [NavNode: "following-sibling::*[1]/*[1]/*[1]/@id"] + else: [x: ".."] # try again for after + +- name: move-next-auto-zoom-parens + # auto-zoom into next child if next child is parenthesized expr + tag: "*" + match: + - "($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext') and" + - "$NavMode='Enhanced' and" + - "parent::m:mrow and following-sibling::* and" + - "following-sibling::*[1][self::m:mrow and count(*)=3 and " #exclude empty parens + - " (IsBracketed(., '(', ')') or IsBracketed(., '[', ']'))" + - " ]" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: "gå"] # phrase('move' to next entry in table) + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "les"] # phrase('read' next entry in table) + else: [T: "beskriv"] # phrase('describe' next entry in table) + - T: "høyre" # phrase(move 'right') # phrase(move 'right') + - pause: short + - set_variables: [NavNode: "following-sibling::*[1]/*[2]/@id"] + +# normal cases for MoveNext +- name: move-next-locked-zoom-level + # locked zoom level + tag: "*" + match: + - "($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext') and" + - "$ReadZoomLevel>=0" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: "gå"] # phrase('move' to next entry in table) + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "les"] # phrase('read' next entry in table) + else: [T: "beskriv"] # phrase('describe' next entry in table) + - T: "høyre" # phrase(move 'right') # phrase(move 'right') + - pause: short + - test: + # if in base (nothing before), we must be moving to a script, so "in" will be said + if: "preceding-sibling::* and following-sibling::*[1][name(.)='none']" + then: + - with: + variables: [Move2D: "'ut av'", Child2D: "."] + replace: [x: ".."] + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: "following-sibling::*[1]"] # skip over 'none' + else: + - with: + variables: [Move2D: "'i'", 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: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: "gå"] # phrase('move' to next entry in table) + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "les"] # phrase('read' next entry in table) + else: [T: "beskriv"] # phrase('describe' next entry in table) + - T: "høyre" # phrase(move 'right') # phrase(move 'right') + - pause: short + - test: + if: "IsNode(.., '2D')" + then: + - with: + variables: [Move2D: "'i'", 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: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MovePrevious'" + then: [T: "gå"] # phrase('move' to next entry in table) + - else_if: "$NavCommand = 'ReadPrevious'" + then: [T: "les"] # phrase('read' next entry in table) + else: [T: "beskriv"] # phrase('describe' next entry in table) + - T: "venstre" # phrase(move 'left') + - pause: short + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: + - test: + if: "preceding-sibling::*[1][.='\u2062' or .='\u2064'] and $NavMode='Enhanced'" # invisible times and plus + then: [set_variables: [NavNode: "preceding-sibling::*[1]/@id"]] + else: [x: "preceding-sibling::*[1]"] + +# two rules for when can't move right +- name: move-previous-no-auto-zoom-at-edge + # at edge of 2D and in a mode where moving right isn't an option + tag: "*" + variables: [EdgeNode: "EdgeNode(., 'left', '2D')"] + match: "$NavCommand = 'MovePrevious' and $NavMode!='Character' and not($AutoZoomOut) and $EdgeNode/@id!=@id" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse' and $NavCommand = 'MovePrevious'" + then: + - T: "kan ikke gå til venstre" # phrase('cannot move left' in expression) + - with: + variables: [Move2D: "'end of'", Child2D: "$EdgeNode/*[1]"] #Should "end of" be translated? + 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 matematikk" # 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 != 'Terse'" + then: + - T: "kan ikke gå til venstre, start matematikk" # phrase('cannot move left, start of math') + - pause: long + - set_variables: [SpeakExpression: "'false'"] + +- name: move-previous-auto-zoom-up-one-level + # Last child or in auto-zoom'd in-- move up a level and try again + # Note: we've already checked the for the case where we are at an edge and should not AutoZoomOut + tag: "*" + match: + - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious') and" + - "( not(preceding-sibling::*) or" + - " ( $NavMode='Enhanced' and " + - " count(preceding-sibling::*)=1 and (IsBracketed(.., '(', ')') or IsBracketed(.., '[', ']'))" + - " )" + - ")" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MovePrevious'" + then: [T: "gå"] # phrase('move' to next entry in table) + - else_if: "$NavCommand = 'ReadPrevious'" + then: [T: "les"] # phrase('read' next entry in table) + else: [T: "beskriv"] # phrase('describe' next entry in table) + - T: "venstre" # phrase(move 'left') + - pause: short + - with: + variables: [MatchCounter: "$MatchCounter + 1", NavCommand: "'MovePrevious'"] + replace: + - test: + if: "preceding-sibling::*" + then: + - with: + variables: [Move2D: "'i'", Child2D: "."] # phrase('in' the denominator) + replace: [x: ".."] + else: + - with: + variables: [Move2D: "'ut av'", Child2D: "."] + replace: [x: ".."] + - test: + if: "preceding-sibling::*" + then: + - x: .. # move out of parens + else: + - 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: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MovePrevious'" + then: [T: "gå"] # phrase('move' to next entry in table) + - else_if: "$NavCommand = 'ReadPrevious'" + then: [T: "les"] # phrase('read' next entry in table) + else: [T: "beskriv"] # phrase('describe' next entry in table) + - T: "venstre" # phrase(move 'left') + - pause: short + - test: + if: "not(parent::m:mrow)" + then: + - with: + variables: [Move2D: "'i'", 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')" + replace: + - test: + # can't get here with MatchCounter=0, so no need to echo command + if: "preceding-sibling::*" + then: + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "kolonne" # 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"]] + else: + - x: ".." # try again at the row level + +- name: move-previous-default + tag: [mtr, mlabeledtr] + match: "$Move2D = '' and ($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious')" + replace: + - test: + # can't get here with MatchCounter=0, so no need to echo command + if: "preceding-sibling::*" + then: + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "rad" # phrase('row' five in table) + - x: "count(preceding-sibling::*)" + - T: "kolonne" # phrase('column' five in table) + - x: "count(*)" + - pause: medium + - test: + if: "$NavMode = 'Character'" + then: + - with: + variables: [NavCommand: "'MovePreviousZoom'"] + replace: [x: "preceding-sibling::*[1]"] + else: + - set_variables: [NavNode: "preceding-sibling::*[1]/*[last()]/*[last()]/@id"] + else: [x: ".."] # try again for after + +- name: move-previous-locked-zoom-level + # locked zoom level + tag: "*" + match: + - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious') and" + - "$ReadZoomLevel>=0" + replace: + - test: + # if moving into base (nothing before), we must be moving to the base, so "in" will be said + if: "count(preceding-sibling::*) > 2 and preceding-sibling::*[1][name(.)='none']" + then: + - with: + variables: [Move2D: "'ut av'", Child2D: "."] + replace: [x: ".."] + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: "preceding-sibling::*[1]"] # skip over 'none' + else: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MovePrevious'" + then: [T: "gå"] # phrase('move' to next entry in table) + - else_if: "$NavCommand = 'ReadPrevious'" + then: [T: "les"] # phrase('read' next entry in table) + else: [T: "beskriv"] # phrase('describe' next entry in table) + - T: "venstre" # phrase(move 'left') + - pause: short + - with: + variables: [Move2D: "'i'", Child2D: "preceding-sibling::*[1]"] # phrase('in' the denominator) + replace: [x: ".."] + - with: + variables: [MatchCounter: "$MatchCounter + 1", NavCommand: "'MovePreviousZoom'"] + replace: [x: "preceding-sibling::*[1]"] + +- name: move-previous-default + tag: "*" + match: "$NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MovePrevious'" + then: [T: "gå"] # phrase('move' to next entry in table) + - else_if: "$NavCommand = 'ReadPrevious'" + then: [T: "les"] # phrase('read' next entry in table) + else: [T: "beskriv"] # phrase('describe' next entry in table) + - T: "venstre" # phrase(move 'left') + - pause: short + - test: + if: "IsNode(.., '2D')" + then: + - with: + variables: [Move2D: "'i'", 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: "symbolmodus" # phrase(a mathematical 'character') + - set_variables: [NavMode: "'Character'", ReadZoomLevel: "1"] + - else_if: "$NavMode = 'Character'" + then: + - T: "forenklet modus" # phrase(a 'simple' way to do something) + - set_variables: [NavMode: "'Simple'", ReadZoomLevel: "1"] + - else: + - T: "utvidet modus" # phrase(an 'enhanced' way to do something) + - set_variables: [NavMode: "'Enhanced'", ReadZoomLevel: "-1"] + # - T: "läge" # phrase(a simple 'mode' of use) + # SWEDISH: Removed the ending "mode" string and added "läge" to the previous strings, for grammatical purposes. + - 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: "forenklet modus" # phrase(an 'simple' way to do something) + - set_variables: [NavMode: "'Simple'", ReadZoomLevel: "1"] + - else_if: "$NavMode = 'Character'" + then: + - T: "utvidet modus" # phrase(an 'enhanced' way to do something) + - set_variables: [NavMode: "'Enhanced'", ReadZoomLevel: "-1"] + - else: + - T: "symbolmodus" # phrase(a mathematical 'character') + - set_variables: [NavMode: "'Character'", ReadZoomLevel: "1"] + # - T: "användningsläge" # phrase(a simple 'mode' of use) + # SWEDISH: Removed the ending "mode" string and added "läge" to the previous strings, for grammatical purposes. + - 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: "les uttrykk etter navigering" # phrase('speak expression after move') + - set_variables: [Overview: "'false'"] + else: + - T: "oversikt over uttrykk etter navigering" # phrase('overview of expression after move') + - set_variables: [Overview: "'true'"] + - pause: long + +- name: current + tag: "*" + match: "$NavCommand = 'ReadCurrent' or $NavCommand = 'DescribeCurrent'" + replace: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'ReadCurrent'" + then: [T: "les"] # phrase('read' next entry in table) + else: [T: "beskriv"] # phrase('describe' next entry in table) + - T: "nåværende" # phrase('current' entry in table) + - set_variables: [NavNode: "@id"] + - pause: long + +# this needs to be near the end because we only test for 'Describe', "Read", etc., and we don't want to get 'DescribeNext', etc. +- name: placemarker + + tag: "*" + match: + - "starts-with($NavCommand, 'Read') or " + - "starts-with($NavCommand, 'Describe') or " + - "starts-with($NavCommand, 'MoveTo')" + replace: + - test: + if: "$NavVerbosity != 'Terse'" + then: + - test: + - if: "starts-with($NavCommand, 'Read')" + then: [T: "les"] # phrase('read' next entry in table) + - else_if: "starts-with($NavCommand, 'Describe')" + then: [T: "beskriv"] # phrase('describe' next entry in table) + - else_if: "starts-with($NavCommand, 'MoveTo')" + then: [T: "gå til"] # phrase('move to' the next entry in table) + else: [T: "angi"] # phrase('set' the value of the next entry in table) + - T: "plassholder" # 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: "angi plassholder" # 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: "ingenting mer" # phrase('inside of nothing more') + - pause: long + - set_variables: [SpeakExpression: "'false'"] + else: + - T: "inne i" # 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: "inne i" # 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/nb/overview.yaml b/Rules/Languages/nb/overview.yaml new file mode 100644 index 000000000..7bbeaccc1 --- /dev/null +++ b/Rules/Languages/nb/overview.yaml @@ -0,0 +1,112 @@ +--- +# 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 + match: "." + replace: + - test: + if: "IsNode(*[1], 'simple') and IsNode(*[2], 'simple')" + then: + - x: "*[1]" + - T: "gjennom" + - x: "*[2]" + else: + - T: "brøk" + +- name: overview-default + tag: msqrt + match: "." + replace: + - T: "roten" + - test: + if: "IsNode(*[1], 'simple')" + then: + - test: + if: "$Verbosity!='Terse'" + then: {T: "av"} + - x: "*[1]" + +- name: overview-default + tag: mroot + match: "." + replace: + - test: + if: "*[2][self::m:mn]" + then_test: + - if: "*[2][text()='2']" + then: {T: "kvadratroten"} + - else_if: "*[2][text()='3']" + then: {T: "kubikkroten"} + - else_if: "*[2][not(contains(., ','))]" + then: [{x: "ToOrdinal(*[2])"}, {T: "roten"}] + else: + - T: "roten av grad" + - x: "*[2]" + - test: + if: "IsNode(*[1], 'simple')" + then: + - test: + if: "$Verbosity!='Terse'" + then: {T: "av"} + - x: "*[1]" + +- name: matrix-override + tag: mrow + match: + - "*[2][self::m:mtable] and" + - "(IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|'))" + replace: + - x: count(*[2]/*) + - T: "ganger" + - x: count(*[2]/*[self::m:mtr][1]/*) + - test: + if: "*[1][text()='|']" # just need to check the first bracket since we know it must be (, [, or | + then: {T: "determinant"} + else: {T: "matrise"} + +- name: overview-default + tag: mtable + match: "." + replace: + - x: count(*[2]/*) + - T: "ganger" + - x: count(*[2]/*[self::m:mtr][1]/*) + - T: "tabell" + +- 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: "og så videre" + +- include: "SimpleSpeak_Rules.yaml" diff --git a/Rules/Languages/nb/unicode-full.yaml b/Rules/Languages/nb/unicode-full.yaml new file mode 100644 index 000000000..c9b4720ef --- /dev/null +++ b/Rules/Languages/nb/unicode-full.yaml @@ -0,0 +1,3664 @@ +--- + +#C1 Controls and Latin-1 Supplement OK + - "¢": [T: "cent"] # 0xa2 (en: 'cents') + - "£": [T: "pund"] # 0xa3 (en: 'pounds') + - "¤": [T: "valutategn"] # 0xa4 (en: 'currency sign') + - "¥": [T: "yen"] # 0xa5 + - "¦": [T: "brutt vertikalstrek"] # 0xa6 (en: 'broken bar') + - "§": [T: "paragraf"] # 0xa7 (en: 'section') + - "¨": [T: "trema"] # 0xa8 (en: 'double dot', MathPlayer: 'trema', google: 'dubbel prick') + - "©": [T: "opphavsrett"] # 0xa9 (en: 'copyright') + - "ª": [T: "feminin ordenstallindikator"] # 0xaa (en: 'feminine ordinal indicator', MathPlayer: 'feminine ordinal indicator', google: 'feminin ordinär indikator') + - "¬": [T: "ikke"] # 0xac (en: 'not') + - "«": [T: "venstre sitattegn"] # 0xab (en: 'left-pointing double angle quote mark') + - "¯": # 0xaf + - test: + if: "ancestor::m:modified-variable and preceding-sibling::*[1][self::m:mi]" + then: [T: "bar"] # (google translation) + else: [T: "strek"] # (en: 'line') + - "²": [T: "i andre"] # 0xb2 (en: 'two', MathPlayer: 'exponent två', google: 'två') + - "³": [T: "i tredje"] # 0xb3 (en: 'three', MathPlayer: 'exponent tre', google: 'tre') + - "´": [T: "akutt aksent"] # 0xb4 (en: 'acute') + - "µ": [T: "mikro"] # 0xb5 (en: 'micro') + - "¹": [T: "eksponent én"] # 0xb9 (en: 'one', google: 'ett') + - "º": [T: "maskulin ordenstallindikator"] # 0xba (en: 'masculine ordinal indicator', MathPlayer: 'masculine ordinal indicator', google: 'maskulina ordinära indikatorer') + - "·": + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolDot = 'Auto'" + then: [T: "ganger"] # (en: 'times', google translation) + else: [T: "midtstilt prikk"] # (en: 'dot', MathPlayer: 'mellanpunkt', google: 'punkt') + - "×": # 0xd7 + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolX = 'Auto'" + then: [T: "ganger"] # (en: 'times', google translation) + else_test: + if: $ClearSpeak_MultSymbolX = 'By' + then: [T: "ganger"] # (en: 'by', google translation) + else: [T: "kryss"] # (en: 'cross') + - "÷": [T: "delt på"] # 0xf7 (en: 'divided by') + #------------------------------------------------------------------------------------------------------- + # SWEDISH: The Swedish character translations are based on the placement and appearance of the characters rather than their function, as function might be context-dependent. Placement above is used as the baseline, and low characters are translated as "låg(t)" (eng "low"). In most cases, no difference has been made in the translation between non-combining, modifier (Spacing Modifier Letters), and combining/embellishment characters. However, in the case of alphabetical letters and punctuation marks as modifier characters (such as modifier small h or comma embellishment), the construction "med ...( efter)" (eng "with ...( placed after it)") is used to prevent any possible ambiguity. + # Norwegian: Same as Swedish +#Spacing Modifier Letters +#Latin superscript modifier letters OK + - "ʰ": [T: "med liten h etter"] # 0x2b0 (en: 'modifier small h', google translation) + - "ʱ": [T: "med liten h med krok etter"] # 0x2b1 (en: 'modifier small h with hook', google translation) + - "ʲ": [T: "med liten j etter"] # 0x2b2 (en: 'modifier small j', google translation) + - "ʳ": [T: "med liten r etter"] # 0x2b3 (en: 'modifier small r', google translation) + - "ʴ": [T: "med liten rotert r etter"] # 0x2b4 (en: 'modifier small turned r', google translation) + - "ʵ": [T: "med liten rotert r med krok etter"] # 0x2b5 (en: 'modifier small turned r with hook', google translation) + - "ʶ": # 0x2b6 + - T: "med liten rotert" # (en: 'modifier small inverted', google translation) + - spell: "translate('R', 'R', 'R')" + - "ʷ": [T: "med liten w etter"] # 0x2b7 (en: 'modifier small w', google translation) + - "ʸ": [T: "med liten y etter"] # 0x2b8 (en: 'modifier small y', google translation) + #-------------------------- + #Miscellaneous phonetic modifiers OK + - "ʹ": [T: "primtegn"] # 0x2b9 (en: 'modifier prime', google: 'modifier prime') + - "ʺ": [T: "dobbelt primtegn"] # 0x2ba (en: 'modifier double prime', google: 'modifier double prime') + - "ʻ": [T: "rotert komma"] # 0x2bb (en: 'modifier turned comma', google translation) + - "ʼ": [T: "apostrof"] # 0x2bc (google translation) + - "ʽ": [T: "speilvendt komma"] # 0x2bd (en: 'modifier reversed comma', google translation) + - "ʾ": [T: "høyrevendt halv ring"] # 0x2be (en: 'modifier right half ring', google: 'modifierare höger halva ring') + - "ʿ": [T: "venstrevendt halv ring"] # 0x2bf (en: 'modifier left half ring', google: 'modifierare lämnade halva ringen') + - "ˀ": [T: "glottal plosiv"] # 0x2c0 (google translation) + - "ˁ": [T: "speilvendt glottal plosiv"] # 0x2c1 (en: 'modifier reversed glottal stop', google translation) + - "˂": [T: "venstrevendt pilspiss"] # 0x2c2 (en: 'modifier left arrowhead', google translation) + - "˃": [T: "høyrevendt pilspiss"] # 0x2c3 (en: 'modifier right arrowhead', google translation) + - "˄": [T: "oppovervendt pilspiss"] # 0x2c4 (en: 'modifier up arrowhead', google translation) + - "˅": [T: "nedovervendt pilspiss"] # 0x2c5 (en: 'modifier down arrowhead', google translation) + - "ˆ": [T: "cirkumfleks"] # 0x2c6 (en: 'modifier circumflex accent', google: 'modifiercirumflex accent') + - "ˇ": [T: "hake"] # 0x2c7 (en: 'caron', google: 'caron') + - "ˈ": [T: "vertikal strek"] # 0x2c8 (en: 'modifier vertical line', google translation) + - "ˉ": [T: "makron"] # 0x2c9 (google translation) + - "ˊ": [T: "akutt aksent"] # 0x2ca (en: 'modifier acute accent', google translation) + - "ˋ": [T: "grav aksent"] # 0x2cb (en: 'modifier grave accent', google translation) + - "ˌ": [T: "lav vertikal strek"] # 0x2cc (en: 'modifier low vertical line', google translation) + - "ˍ": [T: "lav makron"] # 0x2cd (google translation) + - "ˎ": [T: "lav grav aksent"] # 0x2ce (en: 'modifier low grave accent', google translation) + - "ˏ": [T: "lav akutt aksent"] # 0x2cf (en: 'modifier low acute accent', google translation) + - "ː": [T: "kolon lengdetegn"] # 0x2d0 (en: 'modifier triangular colon', google translation) + - "ˑ": [T: "halvt kolon lengdetegn"] # 0x2d1 (en: 'modifier half triangular colon', google translation) + - "˒": [T: "lav høyrevendt halv ring"] # 0x2d2 (en: 'modifier centered right half ring', google translation) + - "˓": [T: "lav venstrevendt halv ring"] # 0x2d3 (en: 'modifier centered left half ring', google translation) + - "˔": [T: "lavt oppovervendt dreiekors"] # 0x2d4 (en: 'modifier up tadck', google translation) + - "˕": [T: "lavt nedovervendt dreiekors"] # 0x2d5 (en: 'modifier down tack', google translation) + - "˖": [T: "lavt plusstegn"] # 0x2d6 (google translation) + - "˗": [T: "lavt minustegn"] # 0x2d7 (en: 'modifier minus sign', google translation) + #---------------------------- + #Spacing clones of diacritics OK + - "˘": [T: "breve"] # 0x2d8 (en: 'breve') + - "˙": [T: "prikk"] # 0x2d9 (en: 'dot') + - "˚": [T: "ring"] # 0x2da (en: 'ring above') + - "˛": [T: "kvist"] # 0x2db (en: 'ogonek') + - "˜": [T: "liten tilde"] # 0x2dc (en: 'small tilde') + - "˝": [T: "dobbel akutt aksent"] # 0x2dd (en: 'double acute accent') + #----------------------------- + #Additions based on 1989 IPA OK + - "˞": [T: "rotisk hake"] # 0x2de (google translation) + - "˟": [T: "kryssaksent"] # 0x2df (en: 'modifier cross accent', google translation) + - "ˠ": [T: "med liten gamma etter"] # 0x2e0 (en: 'modifier small gamma', google translation) + - "ˡ": [T: "med liten l etter"] # 0x2e1 (en: 'modifier small l', google translation) + - "ˢ": [T: "med liten s etter"] # 0x2e2 (google translation) + - "ˣ": [T: "med liten x etter"] # 0x2e3 (en: 'modifier small x', google translation) + - "ˤ": [T: "liten speilvendt glottal plosiv"] # 0x2e4 (google translation) + #----------------------------- + #Tone letters OK + - "˥": [T: "ekstra høyt tonetegn"] # 0x2e5 (en: 'modifier extra-high tone bar', google translation) + - "˦": [T: "høyt tonetegn"] # 0x2e6 (google translation) + - "˧": [T: "mellom-tonetegn"] # 0x2e7 (en: 'modifier mid tone bar', google translation) + - "˨": [T: "lavt tonetegn"] # 0x2e8 (en: 'modifier low tone bar', google translation) + - "˩": [T: "ekstra lavt tonetegn"] # 0x2e9 (en: 'modifier extra-low tone bar', google translation) + #----------------------------- + #Extended Bopomofo tone marks OK + - "˪": [T: "mørkt fallende tonetegn"] # 0x2ea (en: 'modifier yin departing tone mark', google translation) + - "˫": [T: "lyst fallende tonetegn"] # 0x2eb (en: 'modifier yang departing tone mark', google translation) + #--------------------------- + #IPA modifiers OK + - "ˬ": [T: "lavt tonende tegn"] # 0x2ec (en: 'modifier voicing', google translation) + - "˭": [T: "ikke aspirert tegn"] # 0x2ed (en: 'modifier unaspirated', google translation) + #------------------------- + #Other modifier letter OK + - "ˮ": [T: "dobbel apostrof"] # 0x2ee (en: 'modifier double apostrophe', google translation) + #---------------------------- + #UPA modifiers OK + - "˯": [T: "lav nedoverpekende pilspiss"] # 0x2ef (en: 'modifier low down arrowhead', google translation) + - "˰": [T: "lav oppoverpekende pilspiss"] # 0x2f0 (google translation) + - "˱": [T: "lav venstrepekende pilspiss"] # 0x2f1 (en: 'modifier low left arrowhead', google translation) + - "˲": [T: "lav høyrepekende pilspiss"] # 0x2f2 (en: 'modifier low right arrowhead', google translation) + - "˳": [T: "lav ring"] # 0x2f3 (en: 'modifier low ring', google translation) + - "˴": [T: "lav grav aksent"] # 0x2f4 (google translation) + - "˵": [T: "lav dobbel grav aksent"] # 0x2f5 (en: 'modifier middle double grave accent', google translation) + - "˶": [T: "lav dobbel akutt aksent"] # 0x2f6 (en: 'modifier middle double acute accent', google translation) + - "˷": [T: "lav tilde"] # 0x2f7 (en: 'modifier low tilde', google translation) + - "˸": [T: "hevet kolon"] # 0x2f8 (en: 'modifier raised colon', google translation) + - "˹": [T: "start høy tone"] # 0x2f9 (en: 'modifier begin high tone', google translation) + - "˺": [T: "slutt høy tone"] # 0x2fa (en: 'modifier end high tone', google translation) + - "˻": [T: "start lav tone"] # 0x2fb (en: 'modifier begin low tone', google translation) + - "˼": [T: "slutt lav tone"] # 0x2fc (en: 'modifier end low tone', google translation) + - "˽": [T: "lav hylle"] # 0x2fd (en: 'modifier shelf', google translation) + - "˾": [T: "lav åpen hylle"] # 0x2fe (en: 'modifier open shelf', google translation) + - "˿": [T: "lav venstrepil"] # 0x2ff (en: 'modifier low left arrow', google translation) + #--------------------------------------------------------------------------------------------------------- + #Combining Diacritical Marks + #Ordinary diacritics OK + - "̀": [T: "grav aksent"] # 0x300 (en: 'grave accent embellishment', google: 'allvarlig accentutsmyckning') + - "́": [T: "akutt aksent"] # 0x301 (en: 'acute accent embellishment', google: 'akut accentutsmyckning') + - "̂": [T: "cirkumfleks"] # 0x302 (en: 'circumflex accent embellishment', google: 'circumflex accent utsmyckning') + - "̃": [T: "tilde"] # 0x303 (google: 'tilde utsmyckning') + - "̄": [T: "makron"] # 0x304 (en: 'macron embellishment', google: 'macron -utsmyckning') + - "̅": [T: "strek"] # 0x305 (google: 'överbar utsmyckning') + - "̆": [T: "breve"] # 0x306 (en: 'breve embellishment', google: 'breve utsmyckning') + - "̇": [T: "prikk"] # 0x307 (google: 'prick ovanför utsmyckning') + - "̈": [T: "trema"] # 0x308 (en: 'diaeresis embellishment', google: 'diaeresis utsmyckning') + - "̉": [T: "krok"] # 0x309 (en: 'hook above embellishment', google translation) + - "̊": [T: "ring"] # 0x30a (en: 'ring above embellishment', google: 'ring över utsmyckning') + - "̋": [T: "dobbel akutt aksent"] # 0x30b (en: 'double acute accent embellishment', google translation) + - "̌": [T: "hake"] # 0x30c (en: 'check', google: 'kolla upp') + - "̍": [T: "vertikal linje"] # 0x30d (en: 'vertical line above embellishment', google translation) + - "̎": [T: "dobbel vertikal linje"] # 0x30e (en: 'double vertical line above embellishment', google translation) + - "̏": [T: "dobbel grav aksent"] # 0x30f (en: 'double grave accent embellishment', google translation) + - "̐": [T: "Chandrabindu"] # 0x310 (en: 'candrabindu embellishment', google translation) + - "̑": [T: "omvendt breve"] # 0x311 (en: 'inverted breve embellishment', google: 'inverterad breve -utsmyckning') + - "̒": [T: "med rotert komma"] # 0x312 (en: 'turned comma above embellishment', google translation) + - "̓": [T: "med komma"] # 0x313 (en: 'comma above embellishment', google translation) + - "̔": [T: "med omvendt komma"] # 0x314 (en: 'reversed comma above embellishment', google translation) + - "̕": [T: "med høyrestilt komma"] # 0x315 (en: 'comma above right embellishment', google translation) + - "̖": [T: "lav grav aksent"] # 0x316 (en: 'grave accent below embellishment', google translation) + - "̗": [T: "lav akutt aksent"] # 0x317 (en: 'acute accent below embellishment', google translation) + - "̘": [T: "lavt venstre dreiekors"] # 0x318 (en: 'left tack below embellishment', google translation) + - "̙": [T: "lavt høyre dreiekors"] # 0x319 (en: 'right tack below embellishment', google translation) + - "̚": [T: "venstrevendt vinkeltegn"] # 0x31a (en: 'left angle above embellishment', google translation) + - "̛": [T: "horn"] # 0x31b (en: 'horn embellishment', google translation) + - "̜": [T: "lav venstrevendt halvring"] # 0x31c (en: 'left half ring below embellishment', google translation) + - "̝": [T: "lavt oppoverrotert dreiekors"] # 0x31d (en: 'up tack below embellishment', google translation) + - "̞": [T: "lavt nedoverrotert dreiekors"] # 0x31e (en: 'down tack below embellishment', google translation) + - "̟": [T: "lav pluss"] # 0x31f (en: 'plus sign below embellishment', google translation) + - "̠": [T: "lav minus"] # 0x320 (en: 'minus sign below embellishment', google translation) + - "̡": [T: "palatal krok"] # 0x321 (en: 'palatalized hook below embellishment', google translation) + - "̢": [T: "retrofleks krok"] # 0x322 (en: 'retroflex hook below embellishment', google translation) + - "̣": [T: "lav prikk"] # 0x323 (google: 'prick under utsmyckningen') + - "̤": [T: "lav trema"] # 0x324 (en: 'diaeresis below embellishment', google: 'diaeres under utsmyckning') + - "̥": [T: "lav ring"] # 0x325 (en: 'ring below embellishment', google translation) + - "̦": [T: "lavt komma"] # 0x326 (en: 'comma below embellishment', google translation) + - "̧": [T: "lav cédille"] # 0x327 (en: 'cedilla embellishment', google: 'cedilla -utsmyckning') + - "̨": [T: "lav kvist"] # 0x328 (en: 'ogonek embellishment', google translation) + - "̩": [T: "lav vertikal strek"] # 0x329 (en: 'vertical line below embellishment', google translation) + - "̪": [T: "lav bro"] # 0x32a (en: 'bridge below embellishment', google translation) + - "̫": [T: "lav omvendt dobbel bue"] # 0x32b (en: 'inverted double arch below embellishment', google translation) + - "̬": [T: "lav hake"] # 0x32c (en: 'caron below embellishment', google translation) + - "̭": [T: "lav omvendt cirkumfleks"] # 0x32d (en: 'circumflex accent below embellishment', google translation) + - "̮": [T: "lav breve"] # 0x32e (en: 'breve below embellishment', google: 'breve under utsmyckning') + - "̯": [T: "lav omvendt breve"] # 0x32f (en: 'inverted breve below embellishment', google translation) + - "̰": [T: "lav tilde"] # 0x330 (en: 'tilde below embellishment', google: 'tilde under utsmyckning') + - "̱": [T: "lav makron"] # 0x331 (en: 'macron below embellishment', google: 'macron under utsmyckning') + - "̲": [T: "lav strek"] # 0x332 (en: 'low line embellishment', google: 'låg linje utsmyckning') + - "̳": [T: "lav dobbeltstrek"] # 0x333 (en: 'double low line embellishment', google translation) + #------------------------------------------ + #Overstruck diacritics OK + - "̴": [T: "tilde i midten"] # 0x334 (en: 'tilde overlay embellishment', google translation) + - "̵": [T: "strek i midten"] # 0x335 (en: 'short stroke overlay embellishment', google translation) + - "̶": [T: "lang strek i midten"] # 0x336 (en: 'long stroke overlay embellishment', google translation) + - "̷": [T: "med kort skråstrek"] # 0x337 (en: 'short solidus overlay embellishment', google translation) + - "̸": [T: "med lang skråstrek"] # 0x338 (en: 'long solidus overlay embellishment', google: 'long solidus overlay embelling') + #------------------------------------ + #Miscellaneous additions OK + - "̹": [T: "lav høyrevendt halvring"] # 0x339 (en: 'right half ring below embellishment', google translation) + - "̺": [T: "lav omvendt bro"] # 0x33a (en: 'inverted bridge below embellishment', google translation) + - "̻": [T: "lavt kvadrat"] # 0x33b (en: 'square below embellishment', google translation) + - "̼": [T: "lavt måketegn"] # 0x33c (en: 'seagull below embellishment', google translation) + - "̽": [T: "med x over"] # 0x33d (en: 'x above embellishment', google translation) + - "̾": [T: "vertikal tilde"] # 0x33e (en: 'vertical tilde embellishment', google translation) + - "̿": [T: "dobbel strek"] # 0x33f (en: 'double overline embellishment', google translation) + - "̀": [T: "grav tone"] # 0x340 (en: 'grave tone mark embellishment', google translation) + - "́": [T: "akutt tone"] # 0x341 (en: 'acute tone mark embellishment', google translation) +#---------------------------------------------------------------------------------------------------------------- +# Greek and Coptic OK + - "ΪΫϏ": # 0x3aa, 0x3ab, 0x3cf + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "stor"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [spell: "translate('.', 'ΪΫϏ', 'ιυϗ')"] + - T: "med dialytika" # (en: 'with dialytika', google translation) + - "ϊ": [T: "iota med dialytika"] # 0x3ca (en: 'iota with dialytika', google translation) + - "ϋ": [T: "ypsilon med dialytika"] # 0x3cb (en: 'upsilon with dialytika', google translation) + - "ό": [T: "omikron med tonos"] # 0x3cc (en: 'omicron with tonos', google translation) + - "ύ": [T: "ypsilon med tonos"] # 0x3cd (en: 'upsilon with tonos', google translation) + - "ώ": [T: "omega med tonos"] # 0x3ce (en: 'omega with tonos', google translation) + - "ϐ": [T: "beta"] # 0x3d0 (en: 'beta') + - "ϑ": [T: "theta"] # 0x3d1 (en: 'theta', google: 'theta') + - "ϒ": [T: "ypsilon med krok"] # 0x3d2 (en: 'upsilon with hook', google: 'upsilon med krok') + - "ϓ": [T: "ypsilon med akutt aksent og krok"] # 0x3d3 (en: 'upsilon with acute and hook', google translation) + - "ϔ": [T: "ypsilon med trema og krok"] # 0x3d4 (en: 'upsilon with diaeresis and hook', google translation) + - "ϕ": [T: "fi"] # 0x3d5 (en: 'phi', google: 'phi') + - "ϖ": [T: "pi"] # 0x3d6 (en: 'pi', google: 'pi') + - "ϗ": [T: "kai"] # 0x3d7 (en: 'kai') + - "ϵ": [T: "epsilon"] # 0x3f5 + - "϶": [T: "omvendt epsilon"] # 0x3f6 (en: 'reversed epsilon') + #----------------------------------------------------------------------------------------------------------------- + #Cyrillic OK + - "А-Я": # 0x410 - 0x42f + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "stor"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [spell: "translate('.', 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ', 'абвгдежзийклмнопрстуфхцчшщъыьэюя')", {pause: short}] + - "а": [T: "a"] # 0x430 (google: 'а') + - "б": [T: "be"] # 0x431 (google: 'vara') + - "в": [T: "ve"] # 0x432 + - "г": [T: "ge"] # 0x433 + - "д": [T: "de"] # 0x434 + - "е": [T: "je"] # 0x435 (google: 'dvs') + - "ж": [T: "zhe"] # 0x436 + - "з": [T: "ze"] # 0x437 + - "и": [T: "i"] # 0x438 (google: 'и') + - "й": [T: "kort i"] # 0x439 (en: 'short i') + - "к": [T: "ka"] # 0x43a + - "л": [T: "el"] # 0x43b + - "м": [T: "em"] # 0x43c + - "н": [T: "en"] # 0x43d + - "о": [T: "o"] # 0x43e (google: 'о') + - "п": [T: "pe"] # 0x43f + - "р": [T: "er"] # 0x440 + - "с": [T: "es"] # 0x441 + - "т": [T: "te"] # 0x442 + - "у": [T: "u"] # 0x443 (google: 'у') + - "ф": [T: "ef"] # 0x444 + - "х": [T: "ha"] # 0x445 + - "ц": [T: "tse"] # 0x446 + - "ч": [T: "tsje"] # 0x447 + - "ш": [T: "sja"] # 0x448 + - "щ": [T: "sjtja"] # 0x449 + - "ъ": [T: "hardt tegn"] # 0x44a (en: 'hard sign') + - "ы": [T: "jeru"] # 0x44b + - "ь": [T: "mykt tegn"] # 0x44c (en: 'soft sign', google: 'mjukt skylt') + - "э": [T: "e"] # 0x44d (google: 'э') + - "ю": [T: "ju"] # 0x44e + - "я": [T: "ja"] # 0x44f + #----------------------------------------------------------------------------------------------------------- + #General punctuation OK + - "‐": [T: "bindestrek"] # 0x2010 (en: 'hyphen') + - "‑": [T: "bindestrek"] # 0x2011 (en: 'hyphen', google: 'bindestrek') + - "‒": [T: "tankestrek"] # 0x2012 (en: 'figure dash', google: 'figurstreck') + - "–": [T: "tankestrek"] # 0x2013 (en: 'en dash') + - "—": [T: "lang tankestrek"] # 0x2014 (en: 'em dash') + - "―": [T: "horisontal strek"] # 0x2015 (en: 'horizontal bar') + - "‖": [T: "dobbel loddrett strek"] # 0x2016 (en: 'double vertical line') + - "†": [T: "kors"] # 0x2020 (en: 'dagger') + - "‡": [T: "dobbelt kors"] # 0x2021 (en: 'double dagger') + + - "•": # 0x2022 + - test: + if: "@data-chem-formula-op" + then: [T: "ganger"] # (en: 'dot', google translation) + else: [T: "listeelement"] # (en: 'bullet') + + - "…": # 0x2026 + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak '…' as 'and so on...' unless expr starts with '…' + - "../*[1][.='…']" + then: [T: "prikk prikk prikk"] # (en: 'dot dot dot', google translation) + else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' + if: "count(following-sibling::*) = 0" + then: [T: "og så videre"] # (en: 'and so on', google translation) + else: [T: "og så videre opp til"] # (en: 'and so on up to') + + - "‰": [T: "promille"] # 0x2030 (en: 'per mille', MathPlayer: 'promilletecken') + - "‱": [T: "per titusen"] # 0x2031 (en: 'per ten thousand') + - "′": [T: "primtegn"] # 0x2032 (en: 'prime') + - "″": [T: "dobbelt primtegn"] # 0x2033 (en: 'double prime') + - "‴": [T: "trippelt primtegn"] # 0x2034 (en: 'triple prime') + - "‵": [T: "omvendt primtegn"] # 0x2035 (en: 'reversed prime') + - "‶": [T: "omvendt dobbelt primtegn"] # 0x2036 (en: 'reversed double prime') + - "‷": [T: "omvendt trippelt primtegn"] # 0x2037 (en: 'reversed triple prime', google: 'omvänd trippelprime') + - "‸": [T: "innsettingstegn"] # 0x2038 (en: 'to the', google: 'till') + - "‹": [T: "venstrepekende vinkel-sitattegn"] # 0x2039 (en: 'single left pointing angle quote mark') + - "›": [T: "høyrepekende vinkel-sitattegn"] # 0x203a (en: 'single right pointing angle quote mark') + - "‼": [T: "dobbelt utropstegn"] # 0x203c (en: 'double factorial', google: 'dubbel faktorie') + - "⁄": [T: "delt på"] # 0x2044 (en: 'divided by') + - "⁅": [T: "venstre piggparentes"] # 0x2045 (en: 'left square bracket with quill', google: 'vänster fyrkantig konsol med quill') + - "⁆": [T: "høyre piggparentes"] # 0x2046 (en: 'right square bracket with quill', google: 'höger fyrkantig konsol med quill') + - "⁗": [T: "firedobbelt primtegn"] # 0x2057 (en: 'quadruple prime', MathPlayer: 'quadruple prime', google: 'fyrdubbla prime') + - "⁠": [T: ""] # 0x2060 + #------------------------------------------------------------------------------------------------------------------------- + # Superscripts and subscripts OK + - "⁰": [T: "opphøyd i null"] # 0x2070 (en: 'to the zeroth power', google translation) + - "ⁱ": [T: "opphøyd i i"] # 0x2071 (en: 'to the eihth power', google: 'till eihth power') + - "⁴": [T: "opphøyd i fire"] # 0x2074 (en: 'to the fourth power', google translation) + - "⁵": [T: "opphøyd i fem"] # 0x2075 (en: 'to the fifth power', google translation) + - "⁶": [T: "opphøyd i seks"] # 0x2076 (en: 'to the sixth power', google translation) + - "⁷": [T: "opphøyd i sju"] # 0x2077 (en: 'to the seventh power', google translation) + - "⁸": [T: "opphøyd i åtte"] # 0x2078 (en: 'to the eighth power', google translation) + - "⁹": [T: "opphøyd i ni"] # 0x2079 (en: 'to the ninth power', google translation) + - "⁺": [T: "hevet pluss"] # 0x207a (en: 'superscript plus sign', google: 'superscript plus -skylt') + - "⁻": [T: "hevet minus"] # 0x207b (en: 'superscript minus', google: 'superscript minus') + - "⁼": [T: "hevet likhetstegn"] # 0x207c (en: 'superscript equals sign', google: 'superscript är lika med tecken') + - "⁽": [T: "hevet venstreparentes"] # 0x207d (en: 'superscript left parenthesis', google: 'superscript lämnade parentesen') + - "⁾": [T: "hevet høyreparentes"] # 0x207e (en: 'superscript right parenthesis', google: 'superscript höger parentes') + - "ⁿ": [T: "opphøyd i n"] # 0x207f (en: 'to the ennth power', google: 'till den ena kraften') + - "₀": [T: "senket null"] # 0x2080 (en: 'sub zero', google translation) + - "₁": [T: "senket én"] # 0x2081 (en: 'sub one', google translation) + - "₂": [T: "senket to"] # 0x2082 (en: 'sub two', google translation) + - "₃": [T: "senket tre"] # 0x2083 (en: 'sub three', google translation) + - "₄": [T: "senket fire"] # 0x2084 (en: 'sub four', google translation) + - "₅": [T: "senket fem"] # 0x2085 (en: 'sub five', google translation) + - "₆": [T: "senket seks"] # 0x2086 (en: 'sub six', google translation) + - "₇": [T: "senket sju"] # 0x2087 (en: 'sub seven', google translation) + - "₈": [T: "senket åtte"] # 0x2088 (en: 'sub eight', google translation) + - "₉": [T: "senket ni"] # 0x2089 (en: 'sub nine', google translation) + - "₊": [T: "senket pluss"] # 0x208a (en: 'subscript plus sign', google: 'subscript plus -skylt') + - "₋": [T: "senket minus"] # 0x208b (en: 'subscript minus sign', google: 'subscript minus sign') + - "₌": [T: "senket likhetstegn"] # 0x208c (en: 'subscript equals sign', google: 'subscript är lika med tecken') + - "₍": [T: "senket venstreparentes"] # 0x208d (en: 'subscript left parenthesis', google: 'subscript vänster-parentes av sig') + - "₎": [T: "senket høyreparentes"] # 0x208e (en: 'subscript right parenthesis', google: 'subscript höger parentes') + - "ₐ": [T: "senket a"] # 0x2090 (en: 'sub A', google: 'sub a') + - "ₑ": [T: "senket e"] # 0x2091 (en: 'sub E', google: 'sub e') + - "ₒ": [T: "senket o"] # 0x2092 (en: 'sub O', google: 'under o') + - "ₓ": [T: "senket x"] # 0x2093 (en: 'sub X', google: 'under x') + - "ₕ": [T: "senket h"] # 0x2095 (en: 'sub H', google: 'under h') + - "ₖ": [T: "senket k"] # 0x2096 (en: 'sub K', google: 'under k') + - "ₗ": [T: "senket l"] # 0x2097 (en: 'sub L', google: 'under l') + - "ₘ": [T: "senket m"] # 0x2098 (en: 'sub M', google: 'sub m') + - "ₙ": [T: "senket n"] # 0x2099 (en: 'sub N', google: 'under n') + - "ₚ": [T: "senket p"] # 0x209a (en: 'sub P', google: 'sub p') + - "ₛ": [T: "senket s"] # 0x209b (en: 'sub S', google: 'sub s') + - "ₜ": [T: "senket t"] # 0x209c (en: 'sub T', google: 'under t') + #-------------------------------------------------------------------------------------------------------------------- + #Currency symbols OK + - "₠": [T: "europeisk valutaenhet"] # 0x20a0 (en: 'european currenty units', google translation) + - "₡": [T: "colón"] # 0x20a1 + - "₢": [T: "cruzeiro"] # 0x20a2 + - "₣": [T: "franc"] # 0x20a3 + - "₤": [T: "lira"] # 0x20a4 (google: 'lire') + - "₥": [T: "mill"] # 0x20a5 + - "₦": [T: "naira"] # 0x20a6 + - "₧": [T: "peseta"] # 0x20a7 + - "₨": [T: "rupi"] # 0x20a8 (google: 'rupier') + - "₩": [T: "won"] # 0x20a9 (google: 'vann') + - "₪": [T: "ny shekel"] # 0x20aa (google: 'shekel') + - "₫": [T: "dong"] # 0x20ab + - "€": [T: "euro"] # 0x20ac (en: 'euros') + - "₭": [T: "kip"] # 0x20ad (google: 'slaf') + - "₮": [T: "tugrik"] # 0x20ae + - "₯": [T: "drakmer"] # 0x20af (google: 'drakma') + - "₰": [T: "pfenniger"] # 0x20b0 (google: 'tyska pennies') + - "₱": [T: "peso"] # 0x20b1 + - "₲": [T: "guaranier"] # 0x20b2 + - "₳": [T: "australes"] # 0x20b3 (google: 'österral') + - "₴": [T: "hryvnjaer"] # 0x20b4 + - "₵": [T: "cedi"] # 0x20b5 + - "₶": [T: "livre tournois"] # 0x20b6 (google translation) + - "₷": [T: "spesmilo"] # 0x20b7 (google translation) + - "₸": [T: "tenge"] # 0x20b8 (google translation) + - "₹": [T: "indiske rupi"] # 0x20b9 (en: 'indian rupees', google translation) + - "₺": [T: "tyrkiske lira"] # 0x20ba (en: 'turkish liras', google translation) + #-------------------------------------------------------------------------------------------------------------- + #Combining Diacritical Marks for Symbols OK + - "⃐": [T: "venstre-harpun"] # 0x20d0 (en: 'left harpoon above embellishment', google: 'vänster harpoon ovanför utsmyckning') + - "⃑": [T: "høyre-harpun"] # 0x20d1 (en: 'right harpoon above embellishment', google: 'höger harpoon ovanför utsmyckning') + - "⃒": [T: "lang vertikal strek"] # 0x20d2 (en: 'long vertical line overlay embellishment', google translation) + - "⃓": [T: "kort vertikal strek"] # 0x20d3 (en: 'short vertical line overlay embellishment', google translation) + - "⃔": [T: "pil mot klokken"] # 0x20d4 (en: 'anticlockwise arrow above embellishment', google translation) + - "⃕": [T: "pil med klokken"] # 0x20d5 (en: 'clockwise arrow above embellishment', google translation) + - "⃖": [T: "venstrepil"] # 0x20d6 (en: 'left arrow above embellishment', google: 'vänster pil över utsmyckningen') + - "⃗": [T: "høyrepil"] # 0x20d7 (en: 'right arrow above embellishment', google: 'höger-pil över utsmyckning') + - "⃘": [T: "ring"] # 0x20d8 (en: 'ring overlay embellishment', google translation) + - "⃙": [T: "ring med klokken"] # 0x20d9 (en: 'clockwise ring overlay embellishment', google translation) + - "⃚": [T: "ring mot klokken"] # 0x20da (en: 'anticlockwise ring overlay embellishment', google translation) + - "⃛": [T: "trippel prikk"] # 0x20db (en: 'triple dot', google: 'triple dot') + - "⃜": [T: "fire prikker"] # 0x20dc (en: 'quadruple dot', google: 'fyrdubbla prick') + - "⃝": [T: "i sirkel"] # 0x20dd (en: 'enclosing circle embellishment', google translation) + - "⃞": [T: "i firkant"] # 0x20de (en: 'enclosing square embellishment', google translation) + - "⃟": [T: "i diamant"] # 0x20df (en: 'enclosing diamond embellishment', google translation) + - "⃠": [T: "i sirkel med omvendt skråstrek"] # 0x20e0 (en: 'enclosing circle backslash embellishment', google translation) + - "⃡": [T: "venstre-høyre-pil"] # 0x20e1 (en: 'left right arrow above embellishment', google: 'vänster höger pil över utsmyckningen') + - "⃢": [T: "omsluttende skjerm"] # 0x20e2 (en: 'enclosing screen embellishment', google translation) + - "⃣": [T: "omsluttende tastehette"] # 0x20e3 (en: 'enclosing keycap embellishment', google translation) + - "⃤": [T: "i oppoverpekende trekant"] # 0x20e4 (en: 'enclosing upward pointing triangle embellishment', google translation) + - "⃥": [T: "omvendt skråstrek"] # 0x20e5 (en: 'reverse solidus overlay embellishment', google translation) + - "⃦": [T: "dobbel loddrett strek"] # 0x20e6 (en: 'double verticle stroke embellishment', google translation) + - "⃧": [T: "livrentesymbol"] # 0x20e7 (en: 'annuity symbol embellishment', google translation) + - "⃨": [T: "trippel prikk"] # 0x20e8 (en: 'triple underdot', google translation) + - "⃩": [T: "bred bro"] # 0x20e9 (en: 'wide bridge above embellishment', google translation) + - "⃪": [T: "venstrepil"] # 0x20ea (en: 'leftwards arrow overlay embellishment', google translation) + - "⃫": [T: "lang dobbel skråstrek"] # 0x20eb (en: 'long double solidus overlay embellishment', google translation) + - "⃬": [T: "høyre-harpun mothake ned"] # 0x20ec (en: 'rightwards harpoon with barb downwards embellishment', google translation) + - "⃭": [T: "venstre-harpun mothake ned"] # 0x20ed (en: 'leftwards harpoon with barb downwards embellishment', google translation) + - "⃮": [T: "venstrepil under"] # 0x20ee (en: 'left arrow below embellishment', google translation) + - "⃯": [T: "høyrepil under"] # 0x20ef (en: 'right arrow below embellishment', google translation) + - "⃰": [T: "asterisk"] # 0x20f0 (en: 'asterisk above embellishment', google translation) + #----------------------------------------------------------------------------------------------------- + #Letterlike Symbols OK + - "℄": [T: "midtlinjesymbol"] # 0x2104 (google translation) + - "℅": [T: "care of"] # 0x2105 (google: 'bry sig om') + - "℆": [T: "cada una"] # 0x2106 (google translation) + - "ℇ": [T: "eulers konstant"] # 0x2107 (en: 'euler's constant', google: 'eulers konstant') + - "℈": [T: "scruple"] # 0x2108 (en: 'scruples', google translation) + - "℉": [T: "grader fahrenheit"] # 0x2109 (en: 'degrees fahrenheit') + - "ℊ": [T: "script font g"] # 0x210a (en: 'script g') + - "ℌℑℨℭ": # 0x210c, 0x2111, 0x2128, 0x212d + - T: "fraktur" # (en: 'fraktur', google: 'fraktur') + - spell: "translate('.', 'ℌℑℨℭ', 'HIZC')" + + - "ℍℙℾℿ": # 0x210d, 0x2119, 0x213e, 0x213f + - T: "dobbeltstreket" # (en: 'double struck', google translation) + - spell: "translate('.', 'ℍℙℾℿ', 'HPΓΠ')" + + - "ℎ": [T: "plancks konstant"] # 0x210e + - "ℏ": [T: "h strek"] # 0x210f + # SWEDISH: finns bara ett sätt att säga h strek + + - "ℐℒ℘ℬℰℱℳ": # 0x2110, 0x2112, 0x2118, 0x2130, 0x2131, 0x2133 + - T: "script font" # (en: 'script') + - spell: "translate('.', 'ℐℒ℘ℬℰℱℳ', 'ILPBEFM')" + + - "ℓ": [T: "script font l"] # 0x2113 (en: 'script l') + - "℔": [T: "pund"] # 0x2114 (en: 'pounds', google: 'pund') + - "№": [T: "numero"] # 0x2116 (en: 'number') + - "℥": [T: "ounce"] # 0x2125 (en: 'ounces') + - "Ω": [T: "ohm"] # 0x2126 (en: 'ohms') + - "℧": [T: "mho"] # 0x2127 (en: 'mhos') + - "℩": [T: "rotert iota"] # 0x2129 (en: 'turned iota', google: 'vände iota') + - "K": [T: "grader kelvin"] # 0x212a (en: 'kelvin') + - "Å": [T: "ångstrøm"] # 0x212b + - "ℯ": [T: "script font e"] # 0x212f (en: 'script e') + + # coalesced some chars that use cap letters + - "Ⅎ℺⅁⅂⅃⅄": # 0x2132, 0x213a, 0x2141, 0x2142, 0x2143, 0x2144 + - test: + - if: "'.' = '℺'" + then: [T: "rotert"] # (en: 'rotated', google translation) + - else_if: "'.' = 'Ⅎ'" + then: [T: "rotert"] # (en: 'turned', google translation) + - else_if: "'.' = '⅃'" + then: [T: "omvendt sans-serif"] # (en: 'reversed sans-serif', google translation) + else: [T: "rotert sans-serif"] # (en: 'turned sans-serif', google: 'vände sans-serif') + - spell: "translate('.', 'Ⅎ℺⅁⅂⅃⅄', 'FQGLLY')" + + - "ℴ": [T: "script font o"] # 0x2134 (en: 'script o') + - "ℵ": [T: "alef"] # 0x2135 (en: 'first transfinite cardinal') + - "ℶ": [T: "bet"] # 0x2136 (en: 'second transfinite cardinal') + - "ℷ": [T: "gimel"] # 0x2137 (en: 'third transfinite cardinal') + - "ℸ": [T: "dalet"] # 0x2138 (en: 'fourth transfinite cardinal') + - "ℼ": [T: "dobbeltstreket pi"] # 0x213c (en: 'double struck pi', google: 'dobbelslaget pi') + - "ℽ": [T: "dobbeltstreket gamma"] # 0x213d (en: 'double struck gamma', google: 'dobbelslaget gamma') + - "⅀": [T: "dobbeltstreket summetegn"] # 0x2140 (en: 'double struck n-ary summation', google: 'dubbelslaget n-ary-sammanfattning') + - "⅋": [T: "rotert og-tegn"] # 0x214b (en: 'turned ampersand', google: 'vände ampersand') + - "⅌": [T: "per"] # 0x214c (en: 'per', google: 'per') + - "ⅎ": [T: "rotert f"] # 0x214e (en: 'turned F', google: 'vände f') + #-------------------------------------------------------------------------------------------------------------- + #Number formats OK + - "⅐": [T: "én sjudel"] # 0x2150 (en: 'one seventh', google: 'en sjunde') + - "⅑": [T: "én nidel"] # 0x2151 (en: 'one ninth', google: 'en nionde') + - "⅒": [T: "én tidel"] # 0x2152 (en: 'one tenth') + - "⅓": [T: "én tredjedel"] # 0x2153 (en: 'one third') + - "⅔": [T: "to tredjedeler"] # 0x2154 (en: 'two thirds') + - "⅕": [T: "én femtedel"] # 0x2155 (en: 'one fifth') + - "⅖": [T: "to femtedeler"] # 0x2156 (en: 'two fifths') + - "⅗": [T: "tre femtedeler"] # 0x2157 (en: 'three fifths') + - "⅘": [T: "fire femtedeler"] # 0x2158 (en: 'four fifths') + - "⅙": [T: "én sjettedel"] # 0x2159 (en: 'one sixth') + - "⅚": [T: "fem sjettedeler"] # 0x215a (en: 'five sixths') + - "⅛": [T: "én åttedel"] # 0x215b (en: 'one eighth') + - "⅜": [T: "tre åttedeler"] # 0x215c (en: 'three eighths') + - "⅝": [T: "fem åttedeler"] # 0x215d (en: 'five eighths') + - "⅞": [T: "sju åttedeler"] # 0x215e (en: 'seven eighths') + - "⅟": [T: "én over"] # 0x215f (en: 'one over', google: 'en över') + - "Ⅰ": [T: "i"] # 0x2160 (en: 'I', google translation) + - "Ⅱ": [T: "i i"] # 0x2161 (en: 'I I', google translation) + - "Ⅲ": [T: "i i i"] # 0x2162 (en: 'I I I', google translation) + - "Ⅳ": [T: "i v"] # 0x2163 (en: 'I V', google translation) + - "Ⅴ": [T: "v"] # 0x2164 (en: 'V', google translation) + - "Ⅵ": [T: "v i"] # 0x2165 (en: 'V I', google translation) + - "Ⅶ": [T: "v i i"] # 0x2166 (en: 'V I I', google translation) + - "Ⅷ": [T: "v i i i"] # 0x2167 (en: 'V I I I', google translation) + - "Ⅸ": [T: "i x"] # 0x2168 (en: 'I X', google translation) + - "Ⅹ": [T: "x"] # 0x2169 (en: 'X', google translation) + - "Ⅺ": [T: "x i"] # 0x216a (en: 'X I', google translation) + - "Ⅻ": [T: "x i i"] # 0x216b (en: 'X I I', google translation) + - "Ⅼ": [T: "l"] # 0x216c (en: 'L', google translation) + - "Ⅽ": [T: "c"] # 0x216d (en: 'C', google translation) + - "Ⅾ": [T: "d"] # 0x216e (en: 'D', google translation) + - "Ⅿ": [T: "m"] # 0x216f (en: 'M', google translation) + - "ⅰ": [T: "i"] # 0x2170 (en: 'I', google translation) + - "ⅱ": [T: "i i"] # 0x2171 (en: 'I I', google translation) + - "ⅲ": [T: "i i i"] # 0x2172 (en: 'I I I', google translation) + - "ⅳ": [T: "i v"] # 0x2173 (en: 'I V', google translation) + - "ⅴ": [T: "v"] # 0x2174 (en: 'V', google translation) + - "ⅵ": [T: "v i"] # 0x2175 (en: 'V I', google translation) + - "ⅶ": [T: "v i i"] # 0x2176 (en: 'V I I', google translation) + - "ⅷ": [T: "v i i i"] # 0x2177 (en: 'V I I I', google translation) + - "ⅸ": [T: "i x"] # 0x2178 (en: 'I X', google translation) + - "ⅹ": [T: "x"] # 0x2179 (en: 'X', google translation) + - "ⅺ": [T: "x i"] # 0x217a (en: 'X I', google translation) + - "ⅻ": [T: "x i i"] # 0x217b (en: 'X I I', google translation) + - "ⅼ": [T: "l"] # 0x217c (en: 'L', google translation) + - "ⅽ": [T: "c"] # 0x217d (en: 'C', google translation) + - "ⅾ": [T: "d"] # 0x217e (en: 'D', google translation) + - "ⅿ": [T: "m"] # 0x217f (en: 'M', google translation) + - "↉": [T: "null tredjedeler"] # 0x2189 (en: 'zero thirds') + #----------------------------------------------------------------------------------------------------- + #Arrows OK + - "←": [T: "venstrepil"] # 0x2190 (en: 'leftwards arrow') + - "↑": [T: "oppoverpil"] # 0x2191 (en: 'upwards arrow') + - "→": [T: "høyrepil"] # 0x2192 (en: 'rightwards arrow') + - "↓": [T: "nedoverpil"] # 0x2193 (en: 'downwards arrow') + - "↔": [T: "venstre-høyre-pil"] # 0x2194 (en: 'left right arrow') + - "↕": [T: "opp-ned-pil"] # 0x2195 (en: 'up down arrow') + - "↖": [T: "nordvest-pil"] # 0x2196 (en: 'north west arrow') + - "↗": # 0x2197 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "går fra venstre mot"] # (en: 'approaches from below', google translation) + else: [T: "nordøst-pil"] # (en: 'north east arrow') + + - "↘": # 0x2198 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "går fra høyre mot"] # (en: 'approaches from above', google translation) + else: [T: "sørøst-pil"] # (en: 'south east arrow') + + - "↙": [T: "sørvest-pil"] # 0x2199 (en: 'south west arrow') + - "↚": [T: "overstrøket venstrepil"] # 0x219a (en: 'leftwards arrow with stroke') + - "↛": [T: "overstrøket høyrepil"] # 0x219b (en: 'rightwards arrow with stroke') + - "↜": [T: "bølget venstrepil"] # 0x219c (en: 'leftwards wave arrow') + - "↝": [T: "bølget høyrepil"] # 0x219d (en: 'rightwards wave arrow') + - "↞": [T: "venstrepil med to spisser"] # 0x219e (en: 'leftwards two headed arrow') + - "↟": [T: "oppoverpil med to spisser"] # 0x219f (en: 'upwards two headed arrow') + - "↠": [T: "høyrepil med to spisser"] # 0x21a0 (en: 'rightwards two headed arrow') + - "↡": [T: "nedoverpil med to spisser"] # 0x21a1 (en: 'downwards two headed arrow') + - "↢": [T: "venstrepil med hale"] # 0x21a2 (en: 'leftwards arrow with tail') + - "↣": [T: "høyrepil med hale"] # 0x21a3 (en: 'rightwards arrow with tail') + - "↤": [T: "venstrepil fra strek"] # 0x21a4 (en: 'leftwards arrow from bar') + - "↥": [T: "oppoverpil fra strek"] # 0x21a5 (en: 'upwards arrow from bar') + - "↦": [T: "høyrepil fra strek"] # 0x21a6 (en: 'rightwards arrow from bar') + - "↧": [T: "nedoverpil fra strek"] # 0x21a7 (en: 'downwards arrow from bar') + - "↨": [T: "opp-ned-pil med base"] # 0x21a8 (en: 'up down arrow with base') + - "↩": [T: "venstrepil med krok"] # 0x21a9 (en: 'leftwards arrow with hook') + - "↪": [T: "høyrepil med krok"] # 0x21aa (en: 'rightwards arrow with hook') + - "↫": [T: "venstrepil med løkke"] # 0x21ab (en: 'leftwards arrow with loop') + - "↬": [T: "høyrepil med løkke"] # 0x21ac (en: 'rightwards arrow with loop') + - "↭": [T: "bølget venstre-høyre-pil"] # 0x21ad (en: 'left right wave arrow') + - "↮": [T: "overstrøket venstre-høyre-pil"] # 0x21ae (en: 'left right arrow with stroke') + - "↯": [T: "sikksakk nedoverpil"] # 0x21af (en: 'downwards zigzag arrow') + - "↰": [T: "oppoverpil med spissen mot venstre"] # 0x21b0 (en: 'upwards arrow with tip leftwards') + - "↱": [T: "oppoverpil med spissen mot høyre"] # 0x21b1 (en: 'upwards arrow with tip rightwards') + - "↲": [T: "nedoverpil med spissen mot venstre"] # 0x21b2 (en: 'downwards arrow with tip leftwards') + - "↳": [T: "nedoverpil med spissen mot høyre"] # 0x21b3 (en: 'downwards arrow with tip rightwards') + - "↴": [T: "høyrepil med hjørnet ned"] # 0x21b4 (en: 'rightwards arrow with corner downwards') + - "↵": [T: "nedoverpil med hjørnet mot venstre"] # 0x21b5 (en: 'downwards arrow with corner leftwards') + - "↶": [T: "øvre halvsirkelpil mot klokken"] # 0x21b6 (en: 'anticlockwise top semicircle arrow') + - "↷": [T: "øvre halvsirkelpil med klokken"] # 0x21b7 (en: 'clockwise top semicircle arrow') + - "↸": [T: "nordvest-pil mot strek"] # 0x21b8 (en: 'north west arrow to long bar') + - "↹": [T: "venstrepil mot strek over høyrepil mot strek"] # 0x21b9 (en: 'leftwards arrow to bar over rightwards arrow to bar') + - "↺": [T: "åpen sirkelpil mot klokken"] # 0x21ba (en: 'anticlockwise open circle arrow') + - "↻": [T: "åpen sirkelpil med klokken"] # 0x21bb (en: 'clockwise open circle arrow') + - "↼": [T: "venstre-harpun mothake opp"] # 0x21bc (en: 'left harpoon up') + - "↽": [T: "venstre-harpun mothake ned"] # 0x21bd (en: 'left harpoon down') + - "↾": [T: "opp-harpun mothake høyre"] # 0x21be (en: 'up harpoon right') + - "↿": [T: "opp-harpun mothake venstre"] # 0x21bf (en: 'up harpoon left') + - "⇀": [T: "høyre-harpun mothake opp"] # 0x21c0 (en: 'right harpoon up') + - "⇁": [T: "høyre-harpun mothake ned"] # 0x21c1 (en: 'right harpoon down') + - "⇂": [T: "ned-harpun mothake høyre"] # 0x21c2 (en: 'down harpoon right') + - "⇃": [T: "ned-harpun mothake venstre"] # 0x21c3 (en: 'down harpoon left') + - "⇄": [T: "høyrepil over venstrepil"] # 0x21c4 (en: 'rightwards arrow over leftwards arrow') + - "⇅": [T: "oppoverpil til venstre for nedoverpil"] # 0x21c5 (en: 'upwards arrow leftwards of downwards arrow') + - "⇆": [T: "venstrepil over høyrepil"] # 0x21c6 (en: 'leftwards arrow over rightwards arrow') + - "⇇": [T: "to venstrepiler"] # 0x21c7 (en: 'leftwards paired arrows') + - "⇈": [T: "to oppoverpiler"] # 0x21c8 (en: 'upwards paired arrows') + - "⇉": [T: "to høyrepiler"] # 0x21c9 (en: 'rightwards paired arrows') + - "⇊": [T: "to nedoverpiler"] # 0x21ca (en: 'downwards paired arrows') + - "⇋": [T: "venstre-harpun over høyre-harpun"] # 0x21cb (en: 'left harpoon over right harpoon') + - "⇌": [T: "høyre-harpun over venstre-harpun"] # 0x21cc (en: 'right harpoon over left harpoon') + - "⇍": [T: "overstrøket dobbeltstreket venstrepil"] # 0x21cd (en: 'leftwards double arrow with stroke') + - "⇎": [T: "overstrøket dobbeltstreket venstre-høyre-pil"] # 0x21ce (en: 'left right double arrow with stroke') + - "⇏": [T: "overstrøket dobbeltstreket høyrepil"] # 0x21cf (en: 'rightwards double arrow with stroke') + - "⇐": [T: "dobbeltstreket venstrepil"] # 0x21d0 (en: 'leftwards double arrow') + - "⇑": [T: "dobbeltstreket oppoverpil"] # 0x21d1 (en: 'upwards double arrow') + - "⇒": [T: "impliserer"] # 0x21d2 (en: 'rightwards double arrow') + - "⇓": [T: "dobbeltstreket nedoverpil"] # 0x21d3 (en: 'downwards double arrow') + - "⇔": [T: "er ekvivalent med"] # 0x21d4 (en: 'left right double arrow') + - "⇕": [T: "dobbeltstreket opp-ned-pil"] # 0x21d5 (en: 'up down double arrow') + - "⇖": [T: "dobbeltstreket nordvest-pil"] # 0x21d6 (en: 'north west double arrow') + - "⇗": [T: "dobbeltstreket nordøst-pil"] # 0x21d7 (en: 'north east double arrow') + - "⇘": [T: "dobbeltstreket sørøst-pil"] # 0x21d8 (en: 'south east double arrow') + - "⇙": [T: "dobbeltstreket sørvest-pil"] # 0x21d9 (en: 'south west double arrow') + - "⇚": [T: "trippelstreket venstrepil"] # 0x21da (en: 'leftwards triple arrow') + - "⇛": [T: "trippelstreket høyrepil"] # 0x21db (en: 'rightwards triple arrow') + - "⇜": [T: "slingrete venstrepil"] # 0x21dc (en: 'leftwards squiggle arrow') + - "⇝": [T: "slingrete høyrepil"] # 0x21dd (en: 'rightwards squiggle arrow') + - "⇞": [T: "oppoverpil med dobbel horisontal strek"] # 0x21de (en: 'upwards arrow with double stroke') + - "⇟": [T: "nedoverpil med dobbel horisontal strek"] # 0x21df (en: 'downwards arrow with double stroke') + - "⇠": [T: "stiplet venstrepil"] # 0x21e0 (en: 'leftwards dashed arrow') + - "⇡": [T: "stiplet oppoverpil"] # 0x21e1 (en: 'upwards dashed arrow') + - "⇢": [T: "stiplet høyrepil"] # 0x21e2 (en: 'rightwards dashed arrow') + - "⇣": [T: "stiplet nedoverpil"] # 0x21e3 (en: 'downwards dashed arrow') + - "⇤": [T: "venstrepil mot strek"] # 0x21e4 (en: 'leftwards arrow to bar') + - "⇥": [T: "høyrepil mot strek"] # 0x21e5 (en: 'rightwards arrow to bar') + - "⇦": [T: "hvit venstrepil"] # 0x21e6 (en: 'leftwards white arrow') + - "⇧": [T: "hvit oppoverpil"] # 0x21e7 (en: 'upwards white arrow') + - "⇨": [T: "hvit høyrepil"] # 0x21e8 (en: 'rightwards white arrow') + - "⇩": [T: "hvit nedoverpil"] # 0x21e9 (en: 'downwards white arrow') + - "⇪": [T: "hvit oppoverpil fra strek"] # 0x21ea (en: 'upwards white arrow from bar') + - "⇫": [T: "hvit oppoverpil på sokkel"] # 0x21eb (en: 'upwards white arrow on pedestal', google: 'uppåt vit pil på piedestal') + - "⇬": [T: "hvit oppoverpil på sokkel med horisontal strek"] # 0x21ec (en: 'upwards white arrow on pedestal with horizontal bar', google: 'uppåt vit pil på piedestal med horisontell stång') + - "⇭": [T: "hvit oppoverpil på sokkel med vertikal strek"] # 0x21ed (en: 'upwards white arrow on pedestal with vertical bar', google: 'uppåt vit pil på piedestal med vertikal bar') + - "⇮": [T: "hvit dobbel oppoverpil"] # 0x21ee (en: 'upwards white double arrow', google: 'uppåt vit dubbelpil') + - "⇯": [T: "hvit dobbel oppoverpil på sokkel"] # 0x21ef (en: 'upwards white double arrow on pedestal', google: 'uppåt vit dubbelpil på piedestal') + - "⇰": [T: "hvit høyrepil fra vegg"] # 0x21f0 (en: 'rightwards white arrow from wall', google: 'åtgärder vit pil från vägg') + - "⇱": [T: "nordvest-pil mot hjørne"] # 0x21f1 (en: 'north west arrow to corner', google: 'north west arrow till hörnet') + - "⇲": [T: "sørøst-pil mot hjørne"] # 0x21f2 (en: 'south east arrow to corner', google: 'south east arrow till corner') + - "⇳": [T: "hvit opp-ned-pil"] # 0x21f3 (en: 'up down white arrow', google: 'upp ner white arrow') + - "⇴": [T: "høyrepil med liten sirkel"] # 0x21f4 (en: 'right arrow with small circle') + - "⇵": [T: "nedoverpil til venstre for oppoverpil"] # 0x21f5 (en: 'downwards arrow leftwards of upwards arrow') + - "⇶": [T: "tre høyrepiler"] # 0x21f6 (en: 'three rightwards arrows', google: 'tre pilar med höger') + - "⇷": [T: "venstrepil med vertikal strek"] # 0x21f7 (en: 'leftwards arrow with vertical stroke', google: 'vänster pil med lodslag') + - "⇸": [T: "høyrepil med vertikal strek"] # 0x21f8 (en: 'rightwards arrow with vertical stroke', google: 'åtgärdspil med vertikal stroke') + - "⇹": [T: "venstre-høyre-pil med vertikal strek"] # 0x21f9 (en: 'left right arrow with vertical stroke', google: 'vänster höger pil med vertikalt slag') + - "⇺": [T: "venstrepil med dobbel vertikal strek"] # 0x21fa (en: 'leftwards arrow with double vertical stroke', google: 'vänster pil med dubbel vertikal stroke') + - "⇻": [T: "høyrepil med dobbel vertikal strek"] # 0x21fb (en: 'rightwards arrow with double vertical stroke', google: 'åtgärdspil med dubbel vertikal stroke') + - "⇼": [T: "venstre-høyre-pil med dobbel vertikal strek"] # 0x21fc (en: 'left right arrow with double vertical stroke', google: 'vänster höger pil med dubbel vertikal stroke') + - "⇽": [T: "venstrepil med åpen spiss"] # 0x21fd (en: 'leftwards open headed arrow') + - "⇾": [T: "høyrepil med åpen spiss"] # 0x21fe (en: 'rightwards open headed arrow') + - "⇿": [T: "venstre-høyre-pil med åpen spiss"] # 0x21ff (en: 'left right open headed arrow') + #---------------------------------------------------------------------------------------------------------------- + #Mathematical operators OK + - "∀": [T: "for alle"] # 0x2200 (en: 'for all') + - "∁": # 0x2201 + - T: "komplementet til" # (en: 'complement of') + - "∂": # 0x2202 + - T: "partiell derivert" + - "∃": [T: "det eksisterer"] # 0x2203 (en: 'there exists') + - "∄": [T: "det eksisterer ikke"] # 0x2204 (en: 'there does not exist') + - "∅": [T: "den tomme mengden"] # 0x2205 (en: 'empty set') + - "∆": # 0x2206 + - T: "laplace av" # (en: 'laplacian of') + - "∇": [T: "nabla"] # 0x2207 (en: 'gradient of', google: 'lutning av') + - "∈": # 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - T: "i" + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + # NORWEGIAN: "i" sounds best in all cases for the non-ClearSpeak case + # SWEDISH/NORWEGIAN: The word "medlem" is not commonly used in set theory, so we removed that rule. If the parsing has set the parameter to "Member" it will fall under the "else" case. + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "i"] # (en: 'in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "element i"] # (en: 'element of', google translation) + - else: [T: "tilhørende"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "i"] # NORWEGIAN: Set the "auto" case to be "i" + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "er et element i"] # (en: 'is in', google translation) + - else: [T: "tilhører"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - "∉": # 0x2209 + # rule is identical to 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - test: + if: "not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" + then: [T: "er"] + - T: "ikke et element i" + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + # SWEDISH/NORWEGIAN: The word "medlem" is not commonly used in set theory, so we removed that rule. If the parsing has set the parameter to "Member" it will fall under the "else" case. + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "ikke i"] # (en: 'not in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "ikke element i"] # (en: 'not element of', google translation) + - else: [T: "ikke tilhørende"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "er ikke et element i"] # (en: 'is not an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "er ikke i"] # (en: 'is not in', google translation) + - else: [T: "tilhører ikke"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to') + - "∊": # 0x220a + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - T: "i" + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + # NORWEGIAN: "i" sounds best in all cases for the non-ClearSpeak case + # SWEDISH/NORWEGIAN: The word "medlem" is not commonly used in set theory, so we removed that rule. If the parsing has set the parameter to "Member" it will fall under the "else" case. + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "i"] # (en: 'in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "element i"] # (en: 'element of', google translation) + - else: [T: "tilhørende"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "i"] # (en: 'is an element of', google translation) #NORWEGIAN: Set the "auto" case to be "i" + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "er et element i"] # (en: 'is in', google translation) + - else: [T: "tilhører"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - "∋": [T: "inneholder elementet"] # 0x220b (en: 'contains the member') + - "∌": [T: "inneholder ikke elementet"] # 0x220c (en: 'does not contain the member') + - "∍": [T: "inneholder elementet"] # 0x220d (en: 'contains the member') + - "∎": [T: "som skulle bevises"] # 0x220e (en: 'end of proof') + - "∏": [T: "produktet"] # 0x220f (en: 'product') + - "∐": [T: "koproduktet"] # 0x2210 (en: 'coproduct', MathPlayer: 'coproduct', google: 'coprodukt') + - "∑": [T: "sum"] # 0x2211 (en: 'sum') + - "−": [T: "minus"] # 0x2212 + - "∓": [T: "minus pluss"] # 0x2213 (en: 'minus or plus') + - "∔": [T: "prikk pluss"] # 0x2214 (en: 'dot plus') + - "∕": [T: "delt på"] # 0x2215 (en: 'divided by') + - "∖": [T: "minus"] # 0x2216 (en: 'set minus') + - "∗": [T: "ganger"] # 0x2217 (en: 'times') + - "∘": [T: "sammensatt med"] # 0x2218 (en: 'composed with') + - "∙": # 0x2219 + - test: + if: "@data-chem-formula-op" + then: [T: "ganger"] # (en: 'dot', google translation) + else: [T: "ganger"] # (en: 'times') + + - "√": # 0x221a + - T: "kvadratroten av" # (en: 'square root of') + - "∛": # 0x221b + - T: "kubikkroten av" # (en: 'cube root of') + - "∜": # 0x221c + - T: "fjerderoten av" # (en: 'fourth root of') + - "∝": # 0x221d + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "proporsjonal med" # (en: 'proportional to') + - "∞": [T: "uendelig"] # 0x221e (en: 'infinity') + - "∟": [T: "rett vinkel"] # 0x221f (en: 'right angle') + - "∠": [T: "vinkel"] # 0x2220 (en: 'angle') + - "∡": [T: "målt vinkel"] # 0x2221 (en: 'measured angle') + - "∢": [T: "sfærisk vinkel"] # 0x2222 (en: 'spherical angle') + - "∣": [T: "deler"] # 0x2223 (en: 'divides') + - "∤": [T: "deler ikke"] # 0x2224 (en: 'does not divide') + - "∧": [T: "og"] # 0x2227 (en: 'and') + - "∨": [T: "eller"] # 0x2228 (en: 'or') + - "∩": [T: "snitt"] # 0x2229 (en: 'intersection') + - "∪": [T: "union"] # 0x222a + - "∫": [T: "integralet"] # 0x222b + - "∬": [T: "dobbeltintegralet"] # 0x222c (en: 'double integral') + - "∭": [T: "trippelintegralet"] # 0x222d (en: 'triple integral') + - "∮": [T: "kurveintegralet"] # 0x222e (en: 'contour integral') + - "∯": [T: "flateintegralet"] # 0x222f (en: 'surface integral') + - "∰": [T: "volumintegralet"] # 0x2230 (en: 'volume integral') + - "∱": [T: "integralet med klokken"] # 0x2231 (en: 'clockwise integral', MathPlayer: 'clockwise integral', google: 'medurs integrerad') + - "∲": [T: "kurveintegralet med klokken"] # 0x2232 (en: 'clockwise contour integral', MathPlayer: 'clockwise contour integral (arrow on höger)', google: 'medurs konturintegral') + - "∳": [T: "kurveintegralet mot klokken"] # 0x2233 (en: 'anticlockwise contour integral', MathPlayer: 'anticlockwise contour integral', google: 'antikvis konturintegral') + - "∴": [T: "derfor"] # 0x2234 (en: 'therefore') + - "∵": [T: "ettersom"] # 0x2235 (en: 'because') + - "∶": # 0x2236 + - T: "til" # (en: 'to') + - "∷": [T: "som"] # 0x2237 (en: 'as', MathPlayer: 'proportion', google: 'som') + - "∸": [T: "prikk minus"] # 0x2238 (en: 'dot minus') + - "∹": [T: "har overskudd sammenlignet med"] # 0x2239 (en: 'has excess compared to', MathPlayer: 'excess', google: 'har överskott jämfört med') + - "∺": # 0x223a + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "geometrisk proporsjonal med" # (en: 'geometrically proportional to') + - "∻": # 0x223b + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "homotetisk til" # (en: 'homothetic to', MathPlayer: 'homothetic', google: 'homotetisk till') + - "∼": # 0x223c (en: 'varies with') + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "proporsjonal med" + - "∽": [T: "omvendt tilde"] # 0x223d (en: 'reversed tilde') + - "∾": # 0x223e + - T: "omvendt langstrakt s" # (en: 'most positive', MathPlayer: 'inverted lazy s', google: 'mest positiva') + - "∿": [T: "sinuskurve"] # 0x223f (en: 'sine wave') + - "≀": [T: "kransprodukt"] # 0x2240 (en: 'wreath product') + - "≁": # 0x2241 (en: 'not tilde') + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "ikke proporsjonal med" + - "≂": [T: "minus tilde"] # 0x2242 (SRE: 'minus och tilde') + - "≃": # 0x2243 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "asymptotisk lik" # (en: 'asymptotically equal to', MathPlayer: 'asymptotically lika med', google: 'asymptotisk lik') + - "≄": # 0x2244 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "ikke asymptotisk lik" # (en: 'not asymptotically equal to', MathPlayer: 'inte asymptotically lika med', google: 'ikke asymptotisk lik') + - "≅": # 0x2245 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "tilnærmet lik" # (en: 'approximately equal to', MathPlayer: 'approximativt lika med', google: 'omtrent lik') + - "≆": # 0x2246 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "tilnærmet men faktisk ikke lik" # (en: 'approximately but not actually equal to', MathPlayer: 'approximativt men inte faktiskt lika med', google: 'omtrentlig men faktisk ikke lik') + - "≇": # 0x2247 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "verken tilnærmet eller faktisk lik" # (en: 'neither approximately nor actually equal to', MathPlayer: 'varken approximativt eller fakiskt lika med', google: 'varken ungefär eller faktiskt lika med') + - "≈": # 0x2248 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "tilnærmet lik" # (en: 'almost equal to', SRE: 'är nästan lika med') + - "≉": # 0x2249 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "ikke tilnærmet lik" # (en: 'not almost equal to', SRE: 'är inte nästan lika med') + - "≊": # 0x224a + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "tilnærmet lik eller lik" # (en: 'almost equal or equal to', SRE: 'är nästan lika eller lika med') + - "≋": [T: "trippel tilde"] # 0x224b (en: 'triple tilde') + - "≌": [T: "er alle like med"] # 0x224c (en: 'are all equal to', MathPlayer: 'alla lika med') + - "≍": # 0x224d + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ekvivalent med" # (en: 'equivalent to') + - "≎": # 0x224e + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "geometrisk ekvivalent med" # (en: 'geometrically equivalent to', MathPlayer: 'geometriskt lika med', google: 'geometriskt motsvarande') + - "≏": # 0x224f + - T: "differansen mellom" # (en: 'difference between') + - "≐": [T: "nærmer seg grenseverdien"] # 0x2250 (en: 'approaches the limit') + - "≑": # 0x2251 + - T: "geometrisk lik" # (en: 'geometrically equal to', SRE: 'är geometriskt lika med') + - "≒": # 0x2252 + - T: "tilnærmet lik" # (en: 'approximately equal to or the image of', MathPlayer: 'uppskattningsvis lika med eller i likhet med', google: 'ungefär lika med eller bilden av') + - "≓": # 0x2253 + - T: "tilnærmet lik" # (en: 'image of or approximately equal to', MathPlayer: 'i likhet med eller uppskattningsvis lika med', google: 'bild av eller ungefär lika med') + - "≔": [T: "definert som"] # 0x2254 (en: 'colon equals', MathPlayer: 'kolon lika med', google: 'kolon är lika med') + - "≕": [T: "lik kolon"] # 0x2255 (en: 'equals colon', MathPlayer: 'lika med kolon') + - "≖": [T: "ring i likhetstegn"] # 0x2256 (en: 'ring in equal to', SRE: 'är ring i lika med') + - "≗": # 0x2257 + - T: "ring likhetstegn" # (en: 'approximately equal to') + - "≘": [T: "tilsvarer"] # 0x2258 (en: 'corresponds to') + - "≙": [T: "anslår"] # 0x2259 (en: 'estimates') + - "≚": # 0x225a + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "likevinklet med" # (en: 'equiangular to') + - "≛": [T: "stjerne lik"] # 0x225b (en: 'star equals') + # SWEDISH: misspelled delta to fix pronunciation + - "≜": [T: "delta lik"] # 0x225c (en: 'delta equals') + - "≝": [T: "er per definisjon lik"] # 0x225d (en: 'is defined to be') + - "≞": # 0x225e + - T: "måles med" # (en: 'measured by') + - "≟": [T: "spørsmål ved likhet"] # 0x225f (en: 'has an unknown relationship with') + - "≠": # 0x2260 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "ikke lik" # (en: 'not equal to') + - "≡": # 0x2261 + # SWEDISH: This symbol can mean different things. Can MathML differ between them? If so, build a test? + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "identisk med" # (en: 'identical to') + - "≢": # 0x2262 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke identisk med" # (en: 'not identical to') + - "≣": # 0x2263 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "strengt ekvivalent med" # (en: 'strictly equivalent to') + - "≦": # 0x2266 (en: 'less than over equal to') + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "mindre enn eller lik" + - "≧": # 0x2267 (en: 'greater than over equal to') + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "større enn eller lik" + - "≨": # 0x2268 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "mindre enn men ikke lik" # (en: 'less than but not equal to') + - "≩": # 0x2269 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "større enn men ikke lik" # (en: 'greater than but not equal to') + - "≪": # 0x226a + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "mye mindre enn" # (en: 'much less than') + - "≫": # 0x226b + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "mye større enn" # (en: 'much greater than') + - "≬": # 0x226c + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "mellom" # (en: 'between') + - "≭": # 0x226d + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke ekvivalent med" # (en: 'not equivalent to') + - "≮": # 0x226e + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke mindre enn" # (en: 'not less than') + - "≯": # 0x226f + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke større enn" # (en: 'not greater than') + - "≰": # 0x2270 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verken mindre enn eller lik" # (en: 'neither less than nor equal to') + - "≱": # 0x2271 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verken større enn eller lik" # (en: 'neither greater than nor equal to') + - "≲": # 0x2272 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "mindre enn eller tilnærmet lik" # (en: 'less than or equivalent to') + - "≳": # 0x2273 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "større enn eller tilnærmet lik" # (en: 'greater than or equivalent to') + - "≴": # 0x2274 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verken mindre enn eller tilnærmet lik" # (en: 'neither less than nor equivalent to') + - "≵": # 0x2275 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verken større enn eller tilnærmet lik" # (en: 'neither greater than nor equivalent to') + - "≶": # 0x2276 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "mindre enn eller større enn" # (en: 'less than or greater than') + - "≷": # 0x2277 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "større enn eller mindre enn" # (en: 'greater than or less than') + - "≸": # 0x2278 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verken mindre enn eller større enn" # (en: 'neither less than nor greater than') + - "≹": # 0x2279 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verken større enn eller mindre enn" # (en: 'neither greater than nor less than') + - "≺": [T: "foregår"] # 0x227a (en: 'precedes') + - "≻": [T: "følger"] # 0x227b (en: 'succeeds') + - "≼": [T: "foregår eller er lik"] # 0x227c (en: 'precedes or is equal to') + - "≽": [T: "følger eller er lik"] # 0x227d (en: 'succeeds or is equal to') + - "≾": [T: "foregår eller er ekvivalent med"] # 0x227e (en: 'precedes or is equivalent to') + - "≿": [T: "følger eller er ekvivalent med"] # 0x227f (en: 'succeeds or is equivalent to') + - "⊀": [T: "foregår ikke"] # 0x2280 (en: 'does not precede') + - "⊁": [T: "følger ikke"] # 0x2281 (en: 'does not succeed') + - "⊂": # 0x2282 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is a', google translation) + - T: "ekte delmengde av" # (en: 'subset of') + - "⊃": # 0x2283 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is a', google translation) + - T: "ekte overmengde av" # (en: 'superset of') + - "⊄": # 0x2284 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke en ekte delmengde av" # (en: 'not a subset of') + - "⊅": # 0x2285 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke en ekte overmengde av" # (en: 'not a superset of') + - "⊆": # 0x2286 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is a', google translation) + - T: "delmengde av" # (en: 'subset of or equal to') + - "⊇": # 0x2287 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is a', google translation) + - T: "overmengde av" # (en: 'superset of or equal to') + - "⊈": # 0x2288 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verken en delmengde av eller lik" # (en: 'neither a subset of nor equal to') + - "⊉": # 0x2289 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verken en overmengde av eller lik" # (en: 'neither a superset of nor equal to') + - "⊊": # 0x228a (en: 'subset of with not equal to') +# SWEDISH: added test + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] + - T: "ekte delmengde av" + - "⊋": # 0x228b (en: 'superset of with not equal to') + # SWEDISH: added test + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] + - T: "ekte overmengde av" + - "⊌": [T: "multimengde"] # 0x228c (SRE: 'multimängd') + - "⊍": [T: "multimengde multiplikasjon"] # 0x228d (en: 'multiset multiplication') + - "⊎": [T: "multimengde union"] # 0x228e (SRE: 'multimängdunion') + - "⊏": [T: "kvadratisk bilde av"] # 0x228f (en: 'square image of', MathPlayer: 'square image of', google: 'fyrkantig bild av') + - "⊐": [T: "kvadratisk original av"] # 0x2290 (en: 'square original of', MathPlayer: 'square original of', google: 'fyrkantig original av') + - "⊑": [T: "kvadratisk bilde av eller lik"] # 0x2291 (en: 'square image of or equal to', MathPlayer: 'square image of or equal to', google: 'fyrkantig bild av eller lika med') + - "⊒": [T: "kvadratisk original av eller lik"] # 0x2292 (en: 'square original of or equal to', MathPlayer: 'square original of or equal to', google: 'fyrkantig original av eller lika med') + # SWEDISH: misspelled to fix pronunciation + - "⊓": [T: "kvadratisk snitt"] # 0x2293 (en: 'square cap') + - "⊔": [T: "kvadratisk union"] # 0x2294 (SRE: 'kvadratisk kopp') + - "⊕": [T: "direkte sum"] # 0x2295 (en: 'circled plus') + - "⊖": [T: "symmetrisk differanse"] # 0x2296 (en: 'circled minus') + - "⊗": [T: "tensorprodukt"] # 0x2297 (en: 'circled times') + - "⊘": [T: "divisjon i sirkel"] # 0x2298 (en: 'circled slash') + - "⊙": [T: "direkte produkt"] # 0x2299 (en: 'circled dot operator') + - "⊚": [T: "ring-operator i sirkel"] # 0x229a (en: 'circled ring') + - "⊛": [T: "asterisk-operator i sirkel"] # 0x229b (en: 'circled asterisk') + - "⊜": [T: "likhetstegn i sirkel"] # 0x229c (en: 'circled equals') + - "⊝": [T: "tankestrek i sirkel"] # 0x229d (en: 'circled dash') + - "⊞": [T: "plusstegn i kvadrat"] # 0x229e (en: 'squared plus') + - "⊟": [T: "minustegn i kvadrat"] # 0x229f (en: 'squared minus') + - "⊠": [T: "multiplikasjonstegn i kvadrat"] # 0x22a0 (en: 'squared times') + - "⊡": [T: "dot-operator i kvadrat"] # 0x22a1 (en: 'squared dot operator') + - "⊢": [T: "beviser"] # 0x22a2 (en: 'proves') + - "⊣": [T: "beviser ikke"] # 0x22a3 (en: 'does not yield') + - "⊤": [T: "topp"] # 0x22a4 (en: 'top') + - "⊥": # 0x22a5 + - T: "bunn" # (en: 'bottom', MathPlayer: 'up tack', google: 'botten') + - "⊦": [T: "reduseres til"] # 0x22a6 (en: 'reduces to') + - "⊧": [T: "modellerer"] # 0x22a7 (en: 'models', MathPlayer: 'models') + - "⊨": # 0x22a8 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "sant" # (en: 'true') + - "⊩": [T: "tvinger"] # 0x22a9 (en: 'forces') + - "⊪": [T: "tre vertikale streker høyre dreiekors"] # 0x22aa (en: 'triple vertical bar right turnstile') + - "⊫": [T: "dobbel vertikal strek dobbelt høyre dreiekors"] # 0x22ab (en: 'double vertical bar double right turnstile') + - "⊬": [T: "beviser ikke"] # 0x22ac (en: 'does not prove') + - "⊭": # 0x22ad + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke sant" # (en: 'not true') + - "⊮": [T: "tvinger ikke"] # 0x22ae (en: 'does not force') + - "⊯": [T: "overstrøket dobbel vertikal strek dobbelt høyre dreiekors"] # 0x22af (en: 'negated double vertical bar double right turnstile') + - "⊰": [T: "foregår under relasjon"] # 0x22b0 (en: 'precedes under relation', MathPlayer: 'precedes under relation', google: 'går foran under relasjon') + - "⊱": [T: "følger under relasjon"] # 0x22b1 (en: 'succeeds under relation', MathPlayer: 'succeeds under relation', google: 'lyckas under relation') + - "⊲": # 0x22b2 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is', google translation) + - T: "normal undergruppe av" # (en: 'a normal subgroup of') + - "⊳": [T: "inneholder som normal undergruppe"] # 0x22b3 (en: 'contains as a normal subgroup') + - "⊴": # 0x22b4 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is', google translation) + - T: "normal undergruppe av eller lik" # (en: 'a normal subgroup of or equal to') + - "⊵": [T: "inneholder som normal undergruppe eller lik"] # 0x22b5 (en: 'contains as a normal subgroup or equal to') + - "⊶": # 0x22b6 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "definisjonsmengden til" # (en: 'the original of', MathPlayer: 'original of', google: 'originalet av') + - "⊷": # 0x22b7 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verdimengden til" # (en: 'an image of', MathPlayer: 'image of', google: 'en bild av') + - "⊸": [T: "multimap"] # 0x22b8 (SRE: 'multimatris') + - "⊹": [T: "hermitisk matrise"] # 0x22b9 (SRE: 'hermetisk konjugatmatris') + - "⊺": [T: "innskudd"] # 0x22ba (en: 'intercalate', MathPlayer: 'intercalate', google: 'interkalat') + - "⊻": [T: "eksklusiv eller"] # 0x22bb (en: 'xor') + - "⊼": [T: "ikke-og"] # 0x22bc (en: 'nand') + - "⊽": [T: "ikke-eller"] # 0x22bd (en: 'nor') + - "⊾": [T: "rett vinkel med bue"] # 0x22be (en: 'right angle with arc') + - "⊿": [T: "rettvinklet trekant"] # 0x22bf (en: 'right triangle') + - "⋀": [T: "logisk og"] # 0x22c0 (en: 'logical and') + - "⋁": [T: "logisk eller"] # 0x22c1 (en: 'logical or') + # SWEDISH: misspelled to fix pronunciation + - "⋂": [T: "snitt"] # 0x22c2 (en: 'intersection') + - "⋃": [T: "union"] # 0x22c3 + - "⋄": [T: "diamant-operator"] # 0x22c4 + - "⋅": # 0x22c5 + - test: + if: "@data-chem-formula-op" + then: [T: "ganger"] # (en: 'dot', google translation) + else: [T: "ganger"] # (en: 'times') + + - "⋆": [T: "stjerne"] # 0x22c6 (en: 'times') + - "⋇": [T: "divisjon ganger"] # 0x22c7 (en: 'division times') + - "⋈": [T: "naturlig join"] # 0x22c8 (en: 'bowtie', MathPlayer: 'bowtie') + - "⋉": # 0x22c9 + - T: "venstre semi-join" # (en: 'the left normal factor semidirect product of') + - "⋊": # 0x22ca + - T: "høyre semi-join" # (en: 'the right normal factor semidirect product of') + - "⋋": # 0x22cb + - T: "venstre semi-direkte produkt" # (en: 'the left semidirect product of') + - "⋌": # 0x22cc + - T: "høyre semi-direkte produkt" # (en: 'the right semidirect product of') + - "⋍": [T: "omvendt tilde likhetstegn"] # 0x22cd (en: 'reversed tilde equals') + - "⋎": [T: "krøllete logisk eller"] # 0x22ce + - "⋏": [T: "krøllete logisk og"] # 0x22cf (en: 'curly logical and') + - "⋐": # 0x22d0 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is', google translation) + - T: "dobbel delmengde av" # (en: 'a double subset of') + - "⋑": # 0x22d1 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is', google translation) + - T: "dobbel overmengde av" # (en: 'a double superset of') + - "⋒": # 0x22d2 + - T: "det doble snittet av" # (en: 'double intersection of') + - "⋓": # 0x22d3 + - T: "den doble unionen av" # (en: 'double union of') + - "⋔": # 0x22d4 + - T: "det ekte snittet av" # (en: 'proper intersection of', MathPlayer: 'pitchfork', google: 'korrekt skärningspunkt av') + - "⋕": # 0x22d5 + - T: "lik og parallell med" # (en: 'equal to and parallel to') + - "⋖": [T: "mindre enn med prikk"] # 0x22d6 (en: 'less than with dot') + - "⋗": [T: "større enn med prikk"] # 0x22d7 (en: 'greater than with dot') + - "⋘": # 0x22d8 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "veldig mye mindre enn" # (en: 'very much less than') + - "⋙": # 0x22d9 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "veldig mye større enn" # (en: 'very much greater than') + - "⋚": # 0x22da + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "mindre enn lik eller større enn" # (en: 'less than equal to or greater than') + - "⋛": # 0x22db + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "større enn lik eller mindre enn" # (en: 'greater than equal to or less than') + - "⋜": # 0x22dc + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "lik eller mindre enn" # (en: 'equal to or less than') + - "⋝": # 0x22dd + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "lik eller større enn" # (en: 'equal to or greater than') + - "⋞": # 0x22de + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "lik eller foregår" # (en: 'equal to or precedes') + - "⋟": # 0x22df + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "lik eller følger" # (en: 'equal to or succeeds') + - "⋠": [T: "verken foregår eller er lik"] # 0x22e0 (en: 'does not precede nor is equal to') + - "⋡": [T: "verken følger eller er lik"] # 0x22e1 (en: 'does not succeed nor is equal to') + - "⋢": [T: "verken et kvadratisk bilde av eller lik"] # 0x22e2 + - "⋣": [T: "verken kvadratisk original av eller lik"] # 0x22e3 + - "⋤": [T: "kvadratisk bilde av eller ikke lik"] # 0x22e4 + - "⋥": [T: "kvadratisk original av eller ikke lik"] # 0x22e5 + - "⋦": # 0x22e6 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "mindre enn men ikke ekvivalent med" # (en: 'less than but not equivalent to') + - "⋧": # 0x22e7 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "større enn men ikke ekvivalent med" # (en: 'greater than but not equivalent to') + - "⋨": [T: "foregår men er ikke ekvivalent med"] # 0x22e8 (en: 'precedes but is not equivalent to') + - "⋩": [T: "følger men er ikke ekvivalent med"] # 0x22e9 (en: 'succeeds but is not equivalent to') + - "⋪": # 0x22ea + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke en normal undergruppe av" # (en: 'not a normal subgroup of') + - "⋫": [T: "inneholder ikke som normal undergruppe"] # 0x22eb (en: 'does not contain as a normal subgroup') + - "⋬": # 0x22ec + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "verken en normal undergruppe av eller lik" # (en: 'not a normal subgroup of nor is equal to') + - "⋭": [T: "verken inneholder som normal undergruppe eller er lik"] # 0x22ed (en: 'does not contain as a normal subgroup nor is equal to') + - "⋮": [T: "vertikal ellipse"] # 0x22ee (en: 'vertical ellipsis') + - "⋯": [T: "halvhøy horisontal ellipse"] # 0x22ef (en: 'dot dot dot') + - "⋰": [T: "diagonal ellipse oppover"] # 0x22f0 (en: 'upwards diagonal ellipsis') + - "⋱": [T: "diagonal ellipse nedover"] # 0x22f1 (en: 'diagonal ellipsis') + - "⋲": [T: "tilhører med lang horisontal strek"] # 0x22f2 (en: 'element of with long horizontal stroke') + - "⋳": [T: "tilhører med vertikal strek på slutten av horisontal strek"] # 0x22f3 (en: 'element of with vertical bar at end of horizontal stroke') + - "⋴": [T: "tilhører med vertikal strek på slutten av horisontal strek"] # 0x22f4 (en: 'element of with vertical bar at end of horizontal stroke') + - "⋵": [T: "tilhører med prikk over"] # 0x22f5 (en: 'element of with dot above') + - "⋶": [T: "tilhører med strek over"] # 0x22f6 (en: 'element of with overbar') + - "⋷": [T: "tilhører med strek over"] # 0x22f7 (en: 'element of with overbar', MathPlayer: 'element of or equal to', google: 'element av med överbar') + - "⋸": [T: "tilhører med strek under"] # 0x22f8 (en: 'element of with underbar') + - "⋹": [T: "tilhører med to horisontale streker"] # 0x22f9 (en: 'element of with two horizontal strokes') + - "⋺": [T: "inneholder med lang horisontal strek"] # 0x22fa (en: 'contains with long horizontal stroke') + - "⋻": [T: "inneholder med vertikal strek på slutten av horisontal strek"] # 0x22fb (en: 'contains with vertical bar at end of horizontal stroke') + - "⋼": [T: "inneholder med vertikal strek på slutten av horisontal strek"] # 0x22fc (en: 'contains with vertical bar at end of horizontal stroke') + - "⋽": [T: "inneholder med strek over"] # 0x22fd (en: 'contains with overbar', MathPlayer: 'contains or equal to', google: 'innehåller med overbar') + - "⋾": [T: "inneholder med strek over"] # 0x22fe (en: 'contains with overbar') + - "⋿": [T: "tilhører ifølge z-notation"] # 0x22ff (en: 'z notation bag membership', MathPlayer: 'z notation bag membership', google: 'z medlemskap för notation bag') + #------------------------------------------------------------------------------------------------------------- + #Miscellaneous Technical OK + - "⌀": [T: "diameter"] # 0x2300 + - "⌁": [T: "elektrisk pil"] # 0x2301 (en: 'electric arrow') + - "⌂": [T: "hus"] # 0x2302 (en: 'house') + - "⌃": [T: "pilspiss opp"] # 0x2303 (en: 'up arrowhead', google: 'upp pilspetsen') + - "⌄": [T: "pilspiss ned"] # 0x2304 (en: 'down arrowhead', google: 'ner pilspetsen') + - "⌅": [T: "projektiv"] # 0x2305 (en: 'projective') + - "⌆": [T: "perspektiv"] # 0x2306 (en: 'perspective') + - "⌇": [T: "bølget linje"] # 0x2307 (en: 'wavy line', google: 'wavy line') + - "⌈": [T: "venstre tak"] # 0x2308 (en: 'left ceiling') + - "⌉": [T: "høyre tak"] # 0x2309 (en: 'right ceiling') + - "⌊": [T: "venstre gulv"] # 0x230a (en: 'left floor') + - "⌋": [T: "høyre gulv"] # 0x230b (en: 'right floor') + - "⌌": [T: "nedre høyre utsnitt"] # 0x230c (en: 'bottom right crop') + - "⌍": [T: "nedre venstre utsnitt"] # 0x230d (en: 'bottom left crop') + - "⌎": [T: "øvre høyre utsnitt"] # 0x230e (en: 'top right crop') + - "⌏": [T: "øvre venstre utsnitt"] # 0x230f (en: 'top left crop') + - "⌐": [T: "omvendt ikke"] # 0x2310 (en: 'reversed not sign') + - "⌑": [T: "kvadratisk rombe"] # 0x2311 (en: 'square lozenge', google: 'square pastill') + - "⌒": [T: "bue"] # 0x2312 (en: 'arc') + - "⌓": [T: "segment"] # 0x2313 + - "⌔": [T: "sektor"] # 0x2314 (en: 'sector') + - "⌕": [T: "telefonopptaker"] # 0x2315 (en: 'telephone recorder', google: 'telefoninspelare') + - "⌖": [T: "trådkors"] # 0x2316 (en: 'position indicator crosshairs', google: 'positionindikator korsstolar') + - "⌗": [T: "firkant"] # 0x2317 (google translation) + - "⌘": [T: "severdighet"] # 0x2318 (en: 'place of interest sign', google: 'plats för räntetecken') + - "⌙": [T: "rotert ikke"] # 0x2319 (en: 'turned not sign', google translation) + - "⌚": [T: "klokke"] # 0x231a (en: 'watch', google: 'kolla på') + - "⌛": [T: "timeglass"] # 0x231b (en: 'hourglass', google translation) + - "⌜": [T: "øvre venstre hjørne"] # 0x231c (en: 'top left corner') + - "⌝": [T: "øvre høyre hjørne"] # 0x231d (en: 'top right corner') + - "⌞": [T: "nedre venstre hjørne"] # 0x231e (en: 'bottom left corner') + - "⌟": [T: "nedre høyre hjørne"] # 0x231f (en: 'bottom right corner') + - "⌠": [T: "øvre halvdel integral"] # 0x2320 (en: 'top half integral') + - "⌡": [T: "nedre halvdel integral"] # 0x2321 (en: 'bottom half integral') + - "⌢": [T: "rynke"] # 0x2322 (en: 'frown', google: 'rynka pannan') + - "⌣": [T: "smil"] # 0x2323 (en: 'smile') + - "⌤": [T: "enter"] # 0x2324 (en: 'up arrowhead between two horizontal bars', google: 'upp pilspetsen mellan två horisontella staplar') + - "⌥": [T: "option-tast"] # 0x2325 (en: 'option key', google translation) + - "⌦": [T: "delete"] # 0x2326 (en: 'erase to the right', google translation) + - "⌧": [T: "clear"] # 0x2327 (en: 'x in a rectangle box', google translation) + - "⌨": [T: "tastatur"] # 0x2328 (en: 'keyboard', google translation) + - "〈": [T: "venstre vinkelparentes"] # 0x2329 (en: 'left pointing angle bracket') + - "〉": [T: "høyre vinkelparentes"] # 0x232a (en: 'right pointing angle bracket') + - "⌫": [T: "backspace"] # 0x232b (en: 'erase to the left', google translation) + - "⌬": [T: "benzenring"] # 0x232c (en: 'benzene ring', google translation) + - "⌭": [T: "sylindrisitet"] # 0x232d + - "⌮": [T: "all around profile"] # 0x232e (google: 'runt profilen') + - "⌯": [T: "symmetri"] # 0x232f (en: 'symmetry', google translation) + - "⌰": [T: "total runout"] # 0x2330 (google translation) + - "⌱": [T: "dimensjon origo"] # 0x2331 (google translation) + - "⌲": [T: "konisk avsmalning"] # 0x2332 (en: 'conical taper', google translation) + - "⌳": [T: "helning"] # 0x2333 (en: 'slope', google translation) + - "⌴": [T: "plansenkning"] # 0x2334 (en: 'counterbore', google translation) + - "⌵": [T: "forsenkning"] # 0x2335 (en: 'countersink', google translation) + - "⍰": [T: "ukjent boks"] # 0x2370 (en: 'unknown box', google: 'okänd ruta') + - "⎕": [T: "boks"] # 0x2395 (en: 'box', google translation) + - "⏞": [T: "øvre krøllparentes"] # 0x23DE (en: 'top brace') + - "⏟": [T: "nedre krøllparentes"] # 0x23DF (en: 'bottom brace') + #---------------------------------------------------------------------------------------------------- + #Enclosed Alphanumerics OK + - "①-⑨": # 0x2460 - 0x2469 + # SWEDISH: switched order + - spell: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" + - T: "i sirkel" # (en: 'circled') + - "⑩": [T: "ti i sirkel"] # 0x2469 (en: 'circled ten', google translation) + - "⑪": [T: "elleve i sirkel"] # 0x246a (en: 'circled eleven', google translation) + - "⑫": [T: "tolv i sirkel"] # 0x246b (en: 'circled twelve', google translation) + - "⑬": [T: "tretten i sirkel"] # 0x246c (en: 'circled thirteen', google translation) + - "⑭": [T: "fjorten i sirkel"] # 0x246d (en: 'circled fourteen', google translation) + - "⑮": [T: "femten i sirkel"] # 0x246e (en: 'circled fifteen', google translation) + - "⑯": [T: "seksten i sirkel"] # 0x246f (en: 'circled sixteen', google translation) + - "⑰": [T: "sytten i sirkel"] # 0x2470 (en: 'circled seventeen', google translation) + - "⑱": [T: "atten i sirkel"] # 0x2471 (en: 'circled eighteen', google translation) + - "⑳": [T: "tjue i sirkel"] # 0x2473 (en: 'circled twenty', google translation) + - "⑴-⑼": # 0x2474 - 0x247d + # SWEDISH: switched order + - spell: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" + - T: "i parentes" # (en: 'parenthesized', google translation) + - "⑽": [T: "ti i parentes"] # 0x247d (en: 'parenthesized ten', google translation) + - "⑾": [T: "elleve i parentes"] # 0x247e (en: 'parenthesized eleven', google translation) + - "⑿": [T: "tolv i parentes"] # 0x247f (en: 'parenthesized twelve', google translation) + - "⒀": [T: "tretten i parentes"] # 0x2480 (en: 'parenthesized thirteen', google translation) + - "⒁": [T: "fjorten i parentes"] # 0x2481 (en: 'parenthesized fourteen', google translation) + - "⒂": [T: "femten i parentes"] # 0x2482 (en: 'parenthesized fifteen', google translation) + - "⒃": [T: "seksten i parentes"] # 0x2483 (en: 'parenthesized sixteen', google translation) + - "⒄": [T: "sytten i parentes"] # 0x2484 (en: 'parenthesized seventeen', google translation) + - "⒅": [T: "atten i parentes"] # 0x2485 (en: 'parenthesized eighteen', google translation) + - "⒆": [T: "nitten i parentes"] # 0x2486 (en: 'parenthesized nineteen', google translation) + - "⒇": [T: "tjue i parentes"] # 0x2487 (en: 'parenthesized twenty', google translation) + - "⒈-⒐": # 0x2488 - 0x2491 + - spell: "translate('.', '⒈⒉⒊⒋⒌⒍⒎⒏⒐', '123456789')" + - T: "med punktum" # (en: 'with period', google translation) + - "⒑": [T: "ti med punktum"] # 0x2491 (en: 'ten with period', google translation) + - "⒒": [T: "elleve med punktum"] # 0x2492 (en: 'eleven with period', google translation) + - "⒓": [T: "tolv med punktum"] # 0x2493 (en: 'twelve with period', google translation) + - "⒔": [T: "tretten med punktum"] # 0x2494 (en: 'thirteen with period', google translation) + - "⒕": [T: "fjorten med punktum"] # 0x2495 (en: 'fourteen with period', google translation) + - "⒖": [T: "femten med punktum"] # 0x2496 (en: 'fifteen with period', google translation) + - "⒗": [T: "seksten med punktum"] # 0x2497 (en: 'sixteen with period', google translation) + - "⒘": [T: "sytten med punktum"] # 0x2498 (en: 'seventeen with period', google translation) + - "⒙": [T: "atten med punktum"] # 0x2499 (en: 'eighteen with period', google translation) + - "⒚": [T: "nitten med punktum"] # 0x249a (en: 'nineteen with period', google translation) + - "⒛": [T: "tjue med punktum"] # 0x249b (en: 'twenty with period', google translation) + - "⒜-⒵": # 0x249c - 0x24b5 + # SWEDISH: switched order + - spell: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" + - T: "i parentes" # (en: 'parenthesized', google translation) + + - "Ⓐ-Ⓩ": + # SWEDISH: switched order + - spell: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - T: "i sirkel" # (en: 'circled', google translation) + + - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 + # SWEDISH: switched order + - spell: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" + - T: "i sirkel" # (en: 'circled', google translation) + - "⓪": [T: "null i sirkel"] # 0x24ea (google translation) + - "⓫": [T: "elleve i fylt sirkel"] # 0x24eb (en: 'black circled eleven', google translation) + - "⓬": [T: "tolv i fylt sirkel"] # 0x24ec (en: 'black circled twelve', google translation) + - "⓭": [T: "tretten i fylt sirkel"] # 0x24ed (en: 'black circled thirteen', google translation) + - "⓮": [T: "fjorten i fylt sirkel"] # 0x24ee (en: 'black circled fourteen', google translation) + - "⓯": [T: "femten i fylt sirkel"] # 0x24ef (en: 'black circled fifteen', google translation) + - "⓰": [T: "seksten i fylt sirkel"] # 0x24f0 (en: 'black circled sixteen', google translation) + - "⓱": [T: "sytten i fylt sirkel"] # 0x24f1 (en: 'black circled seventeen', google translation) + - "⓲": [T: "atten i fylt sirkel"] # 0x24f2 (en: 'black circled eighteen', google translation) + - "⓳": [T: "nitten i fylt sirkel"] # 0x24f3 (en: 'black circled nineteen', google translation) + - "⓴": [T: "tjue i fylt sirkel"] # 0x24f4 (en: 'black circled twenty', google translation) + - "⓵-⓽": # 0x24f5 - 0x24fe + # SWEDISH: switched order + - spell: "translate('.', '⓵⓶⓷⓸⓹⓺⓻⓼⓽', '123456789')" + - T: "i dobbel sirkel" # (en: 'double circled', google translation) + - "⓾": [T: "ti i dobbel sirkel"] # 0x24fe (en: 'double circled ten', google translation) + - "⓿": [T: "null i fylt sirkel"] # 0x24ff (en: 'black circled zero', google translation) + #------------------------------------------------------------------------------------------------------------------ + #Geometric shapes OK + - "■": [T: "svart kvadrat"] # 0x25a0 (en: 'black square') + - "□": [T: "hvitt kvadrat"] # 0x25a1 (en: 'white square') + - "▢": [T: "hvitt kvadrat med avrundede hjørner"] # 0x25a2 (en: 'white square with rounded corners', google: 'vit fyrkant med rundade hörn') + - "▣": [T: "lite svart kvadrat i hvitt kvadrat"] # 0x25a3 (en: 'white square containing small black square', google: 'vit fyrkant som innehåller en liten svart fyrkant') + - "▤": [T: "kvadrat med horisontalt fyll"] # 0x25a4 (en: 'square with horizontal fill', google: 'fyrkantig med horisontell fyllning') + - "▥": [T: "kvadrat med vertikalt fyll"] # 0x25a5 (en: 'square with vertical fill', google: 'fyrkantig med vertikal fyllning') + - "▦": [T: "kvadrat med ortogonal skravering"] # 0x25a6 (en: 'square with orthogonal crosshatch fill', google: 'fyrkantig med ortogonal crosshatch -fyllning') + - "▧": [T: "kvadrat med fyll fra øvre venstre til nedre høyre"] # 0x25a7 (en: 'square with upper left to lower right fill', google: 'fyrkantig med övre vänster till nedre högra fyllning') + - "▨": [T: "kvadrat med fyll fra øvre høyre til nedre venstre"] # 0x25a8 (en: 'square with upper right to lower left fill', google: 'fyrkantig med övre höger till nedre vänsterfyllning') + - "▩": [T: "kvadrat med diagonal skravering"] # 0x25a9 (en: 'square with diagonal crosshatch fill', google: 'fyrkantig med diagonal korshatchfyllning') + - "▪": [T: "lite svart kvadrat"] # 0x25aa (en: 'black small square') + - "▫": [T: "lite hvitt kvadrat"] # 0x25ab (en: 'white small square') + - "▬": [T: "svart rektangel"] # 0x25ac (en: 'black rectangle') + - "▭": [T: "hvitt rektangel"] # 0x25ad (en: 'white rectangle') + - "▮": [T: "svart vertikalt rektangel"] # 0x25ae (en: 'black vertical rectangle') + - "▯": [T: "hvitt vertikalt rektangel"] # 0x25af (en: 'white vertical rectangle') + - "▰": [T: "svart parallellogram"] # 0x25b0 (en: 'black parallelogram') + - "▱": [T: "hvitt parallellogram"] # 0x25b1 (en: 'white parallelogram') + - "▲": [T: "svart oppoverpekende trekant"] # 0x25b2 (en: 'black up pointing triangle') + - "△": [T: "hvit oppoverpekende trekant"] # 0x25b3 (en: 'white up pointing triangle') + - "▴": [T: "liten svart oppoverpekende trekant"] # 0x25b4 (en: 'black up pointing small triangle') + - "▵": [T: "liten hvit oppoverpekende trekant"] # 0x25b5 (en: 'white up pointing small triangle') + - "▶": [T: "svart høyrepekende trekant"] # 0x25b6 (en: 'black right pointing triangle') + - "▷": [T: "hvit høyrepekende trekant"] # 0x25b7 (en: 'white right pointing triangle') + - "▸": [T: "liten svart høyrepekende trekant"] # 0x25b8 (en: 'black right pointing small triangle') + - "▹": [T: "liten hvit høyrepekende trekant"] # 0x25b9 (en: 'white right pointing small triangle') + - "►": [T: "svart høyre-peker"] # 0x25ba (en: 'black right pointing pointer', google: 'svart höger pekande pekare') + - "▻": [T: "hvit høyre-peker"] # 0x25bb (en: 'white right pointing pointer', google: 'vit höger pekande pekare') + - "▼": [T: "svart nedoverpekende trekant"] # 0x25bc (en: 'black down pointing triangle', MathPlayer: 'svart triangel med spetsen neråt', google: 'svart ner pekande triangel') + - "▽": [T: "hvit nedoverpekende trekant"] # 0x25bd (en: 'white down pointing triangle', MathPlayer: 'vit triangel med spetsen neråt', google: 'vit ner pekande triangel') + - "▾": [T: "liten svart nedoverpekende trekant"] # 0x25be (en: 'black down pointing small triangle', MathPlayer: 'svart triangel med spetsen neråt', google: 'svart ner pekande liten triangel') + - "▿": [T: "liten hvit nedoverpekende trekant"] # 0x25bf (en: 'white down pointing small triangle', MathPlayer: 'vit triangel med spetsen neråt', google: 'vit ner pekande liten triangel') + - "◀": [T: "svart venstrepekende trekant"] # 0x25c0 (en: 'black left pointing triangle') + - "◁": [T: "hvit venstrepekende trekant"] # 0x25c1 (en: 'white left pointing triangle') + - "◂": [T: "liten svart venstrepekende trekant"] # 0x25c2 (en: 'black left pointing small triangle') + - "◃": [T: "liten hvit venstrepekende trekant"] # 0x25c3 (en: 'white left pointing small triangle') + - "◄": [T: "svart venstre-peker"] # 0x25c4 (en: 'black left pointing pointer') + - "◅": [T: "hvit venstre-peker"] # 0x25c5 (en: 'white left pointing pointer') + - "◆": [T: "svart diamant"] # 0x25c6 (en: 'black diamond') + - "◇": [T: "hvit diamant"] # 0x25c7 (en: 'white diamond') + - "◈": [T: "svart diamant i hvit diamant"] # 0x25c8 (en: 'white diamond containing black small diamond') + - "◉": [T: "fiskeøye"] # 0x25c9 (en: 'fisheye') + - "◊": [T: "rombe"] # 0x25ca (en: 'lozenge') + - "○": [T: "hvit sirkel"] # 0x25cb (en: 'white circle') + - "◌": [T: "stiplet sirkel"] # 0x25cc (en: 'dotted circle') + - "◍": [T: "sirkel med vertikalt fyll"] # 0x25cd (en: 'circle with vertical fill') + - "◎": [T: "bullseye"] # 0x25ce (SRE: 'mitt-i-prick') + - "●": [T: "svart sirkel"] # 0x25cf (en: 'black circle') + - "◐": [T: "sirkel med venstre halvdel fylt"] # 0x25d0 (en: 'circle with left half black') + - "◑": [T: "sirkel med høyre halvdel fylt"] # 0x25d1 (en: 'circle with right half black') + - "◒": [T: "sirkel med nedre halvdel fylt"] # 0x25d2 (en: 'circle with lower half black') + - "◓": [T: "sirkel med øvre halvdel fylt"] # 0x25d3 (en: 'circle with upper half black') + - "◔": [T: "sirkel med øvre høyre kvadrant fylt"] # 0x25d4 (en: 'circle with upper right quadrant black') + - "◕": [T: "sirkel fylt bortsett fra øvre venstre kvadrant"] # 0x25d5 (en: 'circle with all but upper left quadrant black') + - "◖": [T: "venstre halvsirkel"] # 0x25d6 (en: 'left half black circle') + - "◗": [T: "høyre halvsirkel"] # 0x25d7 (en: 'right half black circle') + - "◘": [T: "invertert punkt"] # 0x25d8 (en: 'inverse bullet') + - "◙": [T: "invertert hvit sirkel"] # 0x25d9 (en: 'inverse white circle') + - "◚": [T: "invertert hvit øvre halvsirkel"] # 0x25da (en: 'upper half inverse white circle') + - "◛": [T: "invertert hvit nedre halvsirkel"] # 0x25db (en: 'lower half inverse white circle') + - "◜": [T: "øvre venstre kvadrant av sirkelbue"] # 0x25dc (en: 'upper left quadrant circular arc') + - "◝": [T: "øvre høyre kvadrant av sirkelbue"] # 0x25dd (en: 'upper right quadrant circular arc') + - "◞": [T: "nedre høyre kvadrant av sirkelbue"] # 0x25de (en: 'lower right quadrant circular arc') + - "◟": [T: "nedre venstre kvadrant av sirkelbue"] # 0x25df (en: 'lower left quadrant circular arc') + - "◠": [T: "øvre halvsirkel"] # 0x25e0 (en: 'upper half circle') + - "◡": [T: "nedre halvsirkel"] # 0x25e1 (en: 'lower half circle') + - "◢": [T: "svart trekant ned til høyre"] # 0x25e2 (en: 'black lower right triangle', MathPlayer: 'svart triangel neråt höger', google: 'svart nedre höger triangel') + - "◣": [T: "svart trekant ned til venstre"] # 0x25e3 (en: 'black lower left triangle', MathPlayer: 'svart triangel neråt vänster', google: 'svart nedre vänster triangel') + - "◤": [T: "svart trekant oppe til venstre"] # 0x25e4 (en: 'black upper left triangle') + - "◥": [T: "svart trekant oppe til høyre"] # 0x25e5 (en: 'black upper right triangle') + - "◦": [T: "hvitt punkt"] # 0x25e6 (en: 'composition') + - "◧": [T: "kvadrat med venstre halvdel fylt"] # 0x25e7 (en: 'square with left half black') + - "◨": [T: "kvadrat med høyre halvdel fylt"] # 0x25e8 (en: 'square with right half black') + - "◩": [T: "kvadrat med øvre venstre halvdel fylt"] # 0x25e9 (en: 'square with upper left half black') + - "◪": [T: "kvadrat med nedre høyre halvdel fylt"] # 0x25ea (en: 'square with lower right half black') + - "◫": [T: "hvitt kvadrat med midtlinje"] # 0x25eb (en: 'white square with bisecting line') + - "◬": [T: "hvit oppoverpekende trekant med prikk"] # 0x25ec (en: 'white up pointing triangle with dot') + - "◭": [T: "oppoverpekende trekant med venstre halvdel fylt"] # 0x25ed (en: 'up pointing triangle with left half black') + - "◮": [T: "oppoverpekende trekant med høyre halvdel fylt"] # 0x25ee (en: 'up pointing triangle with right half black') + - "◯": [T: "stor sirkel"] # 0x25ef (en: 'large circle') + - "◰": [T: "hvitt kvadrat med øvre venstre kvadrant"] # 0x25f0 (en: 'white square with upper left quadrant', google: 'vit fyrkant med övre vänstra kvadrant') + - "◱": [T: "hvitt kvadrat med nedre venstre kvadrant"] # 0x25f1 (en: 'white square with lower left quadrant', google: 'vit fyrkant med nedre vänster kvadrant') + - "◲": [T: "hvitt kvadrat med nedre høyre kvadrant"] # 0x25f2 (en: 'white square with lower right quadrant', google: 'vit fyrkant med nedre högra kvadrant') + - "◳": [T: "hvitt kvadrat med øvre høyre kvadrant"] # 0x25f3 (en: 'white square with upper right quadrant', google: 'vit fyrkant med övre högra kvadrant') + - "◴": [T: "hvit sirkel med øvre venstre kvadrant"] # 0x25f4 (en: 'white circle with upper left quadrant', google: 'vit cirkel med övre vänstra kvadrant') + - "◵": [T: "hvit sirkel med nedre venstre kvadrant"] # 0x25f5 (en: 'white circle with lower left quadrant') + - "◶": [T: "hvit sirkel med nedre høyre kvadrant"] # 0x25f6 (en: 'white circle with lower right quadrant', google: 'vit cirkel med nedre högra kvadrant') + - "◷": [T: "hvit sirkel med øvre høyre kvadrant"] # 0x25f7 (en: 'white circle with upper right quadrant', google: 'vit cirkel med övre högra kvadrant') + - "◸": [T: "trekant oppe til venstre"] # 0x25f8 (en: 'upper left triangle') + - "◹": [T: "trekant oppe til høyre"] # 0x25f9 (en: 'upper right triangle') + - "◺": [T: "trekant ned til venstre"] # 0x25fa (en: 'lower left triangle') + - "◻": [T: "mellomstort hvitt kvadrat"] # 0x25fb (en: 'white medium square') + - "◼": [T: "mellomstort svart kvadrat"] # 0x25fc (en: 'black medium square') + - "◽": [T: "hvitt middels lite kvadrat"] # 0x25fd (en: 'white medium small square') + - "◾": [T: "svart middels lite kvadrat"] # 0x25fe (en: 'black medium small square') + - "◿": [T: "trekant ned til høyre"] # 0x25ff (en: 'lower right triangle') + #------------------------------------------------------------------------------------------------ + #Miscellaneous symbols OK + + - "♠": [T: "svart spar"] # 0x2660 (en: 'black spade suit', google: 'svart spade kostym') + - "♡": [T: "hvit hjerter"] # 0x2661 (en: 'white heart suit', google: 'vit hjärtdräkt') + - "♢": [T: "hvit ruter"] # 0x2662 (en: 'white diamond suit', google: 'vit diamantdräkt') + - "♣": [T: "svart kløver"] # 0x2663 (en: 'black club suit', google: 'svart klubbdräkt') + - "♤": [T: "hvit spar"] # 0x2664 (en: 'white spade suit', google: 'vit spade kostym') + - "♥": [T: "svart hjerter"] # 0x2665 (en: 'black heart suit', google: 'black heart suit') + - "♦": [T: "svart ruter"] # 0x2666 (en: 'black diamond suit', google: 'svart diamantdräkt') + - "♧": [T: "hvit kløver"] # 0x2667 (en: 'white club suit', google: 'vit klubbdräkt') + #------------------------------------------------------------------------------------------------ + #Dingbats OK + - "❨": [T: "venstreparentes"] # 0x2768 (en: 'medium left parentheses ornament', google: 'medium vänster-parentesesprydnad') + - "❩": [T: "høyreparentes"] # 0x2769 (en: 'medium right parentheses ornament', google: 'medium höger parentesetheses ornament') + - "❪": [T: "avflatet venstreparentes"] # 0x276a (en: 'medium flattened left parentheses ornament', google: 'medium plattad vänster parentese -prydnad') + - "❫": [T: "avflatet høyreparentes"] # 0x276b (en: 'medium flattened right parentheses ornament', google: 'medium platta höger parentesetheses prydnad') + - "❬": [T: "venstre vinkel-parentes"] # 0x276c (en: 'medium left-pointing angle bracket ornament', google: 'medium vänsterpekande vinkelfäste prydnad') + - "❭": [T: "høyre vinkel-parentes"] # 0x276d (en: 'medium right-pointing angle bracket ornament', google: 'medium högerpekande vinkelfäste prydnad') + - "❮": [T: "fet venstre anførselstegn"] # 0x276e (en: 'heavy left-pointing angle quotation mark ornament', google: 'tung vänsterpekande vinkelcitationsmärke prydnad') + - "❯": [T: "fet høyre anførselstegn"] # 0x276f (en: 'heavy right-pointing angle quotation mark ornament', google: 'tung högerpekande vinkelcitationsmärke prydnad') + - "❰": [T: "fet venstre vinkel-parentes"] # 0x2770 (en: 'heavy left-pointing angle bracket ornament', google: 'tung vänsterpekande vinkelfäste prydnad') + - "❱": [T: "fet høyre vinkel-parentes"] # 0x2771 (en: 'heavy right-pointing angle bracket ornament', google: 'tung högerpekande vinkelfäste prydnad') + - "❲": [T: "venstre skilpaddeskall-parentes"] # 0x2772 (en: 'light left tortoise shell bracket ornament', google: 'ljus vänster sköldpaddsskalfäste prydnad') + - "❳": [T: "høyre skilpaddeskall-parentes"] # 0x2773 (en: 'light right tortoise shell bracket ornament', google: 'lätt höger sköldpaddsskalfäste prydnad') + - "❴": [T: "fet venstre krøllparentes"] # 0x2774 (en: 'medium left brace ornament', google: 'medium vänster stagprydnad') + - "❵": [T: "fet høyre krøllparentes"] # 0x2775 (en: 'medium right brace ornament', google: 'medium höger stagprydnad') + - "❶": [T: "én i fylt sirkel"] # 0x2776 (en: 'black circled one', google translation) + - "❷": [T: "to i fylt sirkel"] # 0x2777 (en: 'black circled two', google translation) + - "❸": [T: "tre i fylt sirkel"] # 0x2778 (en: 'black circled three', google translation) + - "❹": [T: "fire i fylt sirkel"] # 0x2779 (en: 'black circled four', google translation) + - "❺": [T: "fem i fylt sirkel"] # 0x277a (en: 'black circled five', google translation) + - "❻": [T: "seks i fylt sirkel"] # 0x277b (en: 'black circled six', google translation) + - "❼": [T: "sju i fylt sirkel"] # 0x277c (en: 'black circled seven', google translation) + - "❽": [T: "åtte i fylt sirkel"] # 0x277d (en: 'black circled eight', google translation) + - "❾": [T: "ni i fylt sirkel"] # 0x277e (en: 'black circled nine', google translation) + - "❿": [T: "ti i fylt sirkel"] # 0x277f (en: 'black circled ten', google translation) + - "➀": [T: "sans-serif én i sirkel"] # 0x2780 (en: 'circled sans serif one', google translation) + - "➁": [T: "sans-serif to i sirkel"] # 0x2781 (en: 'circled sans serif two', google translation) + - "➂": [T: "sans-serif tre i sirkel"] # 0x2782 (en: 'circled sans serif three', google translation) + - "➃": [T: "sans-serif fire i sirkel"] # 0x2783 (en: 'circled sans serif four', google translation) + - "➄": [T: "sans-serif fem i sirkel"] # 0x2784 (en: 'circled sans serif five', google translation) + - "➅": [T: "sans-serif seks i sirkel"] # 0x2785 (google translation) + - "➆": [T: "sans-serif sju i sirkel"] # 0x2786 (en: 'circled sans serif seven', google translation) + - "➇": [T: "sans-serif åtte i sirkel"] # 0x2787 (en: 'circled sans serif eight', google translation) + - "➈": [T: "sans-serif ni i sirkel"] # 0x2788 (en: 'circled sans serif nine', google translation) + - "➉": [T: "sans-serif ti i sirkel"] # 0x2789 (en: 'circled sans serif ten', google translation) + - "➊": [T: "sans-serif én i fylt sirkel"] # 0x278a (en: 'black circled sans serif one', google translation) + - "➋": [T: "sans-serif to i fylt sirkel"] # 0x278b (en: 'black circled sans serif two', google translation) + - "➌": [T: "sans-serif tre i fylt sirkel"] # 0x278c (en: 'black circled sans serif three', google translation) + - "➍": [T: "sans-serif fire i fylt sirkel"] # 0x278d (google translation) + - "➎": [T: "sans-serif fem i fylt sirkel"] # 0x278e (google translation) + - "➏": [T: "sans-serif seks i fylt sirkel"] # 0x278f (google translation) + - "➐": [T: "sans-serif sju i fylt sirkel"] # 0x2790 (google translation) + - "➑": [T: "sans-serif åtte i fylt sirkel"] # 0x2791 (en: 'black circled sans serif eight', google translation) + - "➒": [T: "sans-serif ni i fylt sirkel"] # 0x2792 (en: 'black circled sans serif nine', google translation) + - "➓": [T: "sans-serif ti i fylt sirkel"] # 0x2793 (google translation) + - "➔": [T: "fet høyrepil"] # 0x2794 (en: 'heavy wide-headed rightwards arrow', google: 'tungt huvud med höger om höger pil') + - "➕": [T: "fet pluss"] # 0x2795 (en: 'heavy plus sign', google: 'tungt plus -tecken') + - "➖": [T: "fet minus"] # 0x2796 (en: 'heavy minus sign', google: 'tung minusskylt') + - "➗": [T: "fet division"] # 0x2797 (en: 'heavy division sign', google: 'tung uppdelningstecken') + - "➘": [T: "fet sørøst-pil"] # 0x2798 (en: 'heavy south east arrow', google: 'tung south east arrow') + - "➙": [T: "fet høyrepil"] # 0x2799 (en: 'heavy rightwards arrow', google: 'tung åt höger-pil') + - "➚": [T: "fet nordøst-pil"] # 0x279a (en: 'heavy north east arrow', google: 'tung north east arrow') + - "➛": [T: "høyrepil"] # 0x279b (en: 'drafting point rightwards arrow', google: 'utarbetningspunkt åt höger pil') + - "➜": [T: "fet høyrepil med avrundet spiss"] # 0x279c (en: 'heavy round-tipped rightwards arrow', google: 'tung rundtippad höger-pil') + - "➝": [T: "høyrepil"] # 0x279d (en: 'triangle-headed rightwards arrow', google: 'triangelhuvud med höger pil') + - "➞": [T: "fet høyrepil"] # 0x279e (en: 'heavy triangle-headed rightwards arrow', google: 'tung triangelhuvud med höger pil') + - "➟": [T: "stiplet høyrepil"] # 0x279f (en: 'dashed triangle-headed rightwards arrow', google: 'streckad triangelhuvud med höger pil') + - "➠": [T: "fet stiplet høyrepil"] # 0x27a0 (en: 'heavy dashed triangle-headed rightwards arrow', google: 'tung streckad triangelhuvud med höger pil') + - "➡": [T: "høyrepil"] # 0x27a1 (en: 'black rightwards arrow', google: 'black rightwards arrow') + - "➢": [T: "3D-høyrepil med lys øvre del"] # 0x27a2 (en: 'three d top lighted rightwards arrow', google: 'tre d topplyst höger pil') + - "➣": [T: "3D-høyrepil med lys nedre del"] # 0x27a3 (en: 'three d bottom lighted rightwards arrow', google: 'tre d botten tände höger pil') + - "➤": [T: "pilspiss til høyre"] # 0x27a4 (en: 'black rightwards arrowhead', google: 'svart höger pilspets') + - "➥": [T: "fet høyrepil med hale oppover"] # 0x27a5 (en: 'heavy black curved downwards and rightwards arrow', google: 'tung svart krökt nedåt och höger-pil') + - "➦": [T: "fet høyrepil med hale nedover"] # 0x27a6 (en: 'heavy black curved upwards and rightwards arrow', google: 'tung svart krökt uppåt och pil med höger') + - "➧": [T: "kompakt høyrepil"] # 0x27a7 (en: 'squat black rightwards arrow', google: 'squat black rightwards arrow') + - "➨": [T: "fet høyrepil med konkav spiss"] # 0x27a8 (en: 'heavy concave-pointed black rightwards arrow', google: 'tung konkavspetsad svart höger-pil') + - "➩": [T: "høyre-skyggelagt hvit høyrepil"] # 0x27a9 (en: 'right-shaded white rightwards arrow', google: 'högerskuggad vit åt höger pil') + - "➪": [T: "venstre-skyggelagt hvit høyrepil"] # 0x27aa (en: 'left-shaded white rightwards arrow', google: 'vänsterskuggad vit åt höger pil') + - "➫": [T: "bakovervippet skyggelagt hvit høyrepil"] # 0x27ab (en: 'back-tilted shadowed white rightwards arrow', google: 'back-tiled shadowed white rightward arrow') + - "➬": [T: "fremoverlent skyggelagt hvit høyrepil"] # 0x27ac (en: 'front-tilted shadowed white rightwards arrow', google: 'front-lutad skuggad vit höger pil') + - "➭": [T: "hvit høyrepil skyggelagt under"] # 0x27ad (en: 'heavy lower right-shadowed white rightwards arrow', google: 'tung nedre högerskuggad vit höger pil') + - "➮": [T: "hvit høyrepil skyggelagt over"] # 0x27ae (en: 'heavy upper right-shadowed white rightwards arrow', google: 'tung övre högra skuggade vita höger-pil') + - "➯": [T: "hvit høyrepil med hakk skyggelagt under"] # 0x27af (en: 'notched lower right-shadowed white rightwards arrow', google: 'skåpad nedre högerskuggad vit åt höger pil') + - "➱": [T: "hvit høyrepil med hakk skyggelagt over"] # 0x27b1 (en: 'notched upper right-shadowed white rightwards arrow', google: 'skärmad övre högra skuggade vita höger-pil') + - "➲": [T: "fet hvit høyrepil med sirkel"] # 0x27b2 (en: 'circled heavy white rightwards arrow', google: 'circled heavy white rightwards arrow') + - "➳": [T: "hvit høyrepil med fjær"] # 0x27b3 (en: 'white-feathered rightwards arrow', google: 'vitfödd åt höger pil') + - "➴": [T: "sørøst-pil med fjær"] # 0x27b4 (en: 'black-feathered south east arrow', google: 'svartfödd south east arrow') + - "➵": [T: "høyrepil med fjær"] # 0x27b5 (en: 'black-feathered rightwards arrow', google: 'black-feeded rightwards arrow') + - "➶": [T: "nordøst-pil med fjær"] # 0x27b6 (en: 'black-feathered north east arrow', google: 'svartfödd nord-ostra pilen') + - "➷": [T: "fet sørøst-pil med fjær"] # 0x27b7 (en: 'heavy black-feathered south east arrow', google: 'tung svartfönad syd-ostpil') + - "➸": [T: "fet høyrepil med fjær"] # 0x27b8 (en: 'heavy black-feathered rightwards arrow', google: 'tung svartfjäder med höger pil') + - "➹": [T: "fet nordøst-pil med fjær"] # 0x27b9 (en: 'heavy black-feathered north east arrow', google: 'tung svartfönad nord-ostra pilen') + - "➺": [T: "høyrepil med mothaker"] # 0x27ba (en: 'teradrop-barbed rightwards arrow', google: 'teradrop-barbed till höger pil') + - "➻": [T: "tåreformet høyrepil"] # 0x27bb (en: 'heavy teardrop-shanked rightwards arrow', google: 'tung teardrop-shanked höger-pil') + - "➼": [T: "høyrepil med kileformet hale"] # 0x27bc (en: 'wedge-tailed rightwards arrow', google: 'wedge-tailed åt höger pil') + - "➽": [T: "fet høyrepil med kileformet hale"] # 0x27bd (en: 'heavy wedge-tailed rightwards arrow', google: 'tung kil-tailed höger-pil') + - "➾": [T: "høyrepil med åpne konturer"] # 0x27be (en: 'open-outlined rightwards arrow', google: 'öppen-outlinerad höger-pil') + #---------------------------------------------------------------------------------------------------------------------------------- + #Miscellaneous mathematical symbols-A OK + - "⟀": [T: "tredimensjonal vinkel"] # 0x27c0 (en: 'three dimensional angle') + - "⟁": [T: "hvit trekant med liten hvit trekant"] # 0x27c1 (en: 'white triangle containing small white triangle') + - "⟂": # 0x27c2 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "vinkelrett på" # (en: 'perpendicular to') + - "⟃": # 0x27c3 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is', google translation) + - T: "åpen delmengde av" # (en: 'an open subset of') + - "⟄": # 0x27c4 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is', google translation) + - T: "åpen overmengde av" # (en: 'an open superset of') + - "⟅": [T: "venstre s-formet bag delimiter"] # 0x27c5 (en: 'left s-shaped bag delimiter') + - "⟆": [T: "høyre s-formet bag delimiter"] # 0x27c6 (en: 'right s-shaped bag delimiter') + - "⟇": [T: "eller med prikk"] # 0x27c7 (en: 'or with dot inside') + - "⟈": [T: "omvendt skråstrek før delmengde"] # 0x27c8 (en: 'reverse solidus preceding subset') + - "⟉": [T: "overmengde før skråstrek"] # 0x27c9 (en: 'superset preceding solidus') + - "⟊": [T: "vertikal strek med horisontal strek"] # 0x27ca (en: 'vertical bar with horizontal stroke') + - "⟋": [T: "stigende diagonal"] # 0x27cb (en: 'mathematical rising diagonal', google: 'matematisk stigande diagonal') + - "⟌": [T: "lang divisjon"] # 0x27cc (en: 'long division') + - "⟍": [T: "synkende diagonal"] # 0x27cd (en: 'mathematical falling diagonal', google: 'matematisk fallande diagonal') + - "⟎": [T: "logisk og i kvadrat"] # 0x27ce (en: 'squared logical and', google: 'squared logical och') + - "⟏": [T: "logisk eller i kvadrat"] # 0x27cf (en: 'squared logical or', google: 'kvadratiska logiska eller') + - "⟐": [T: "hvit diamant med prikk i midten"] # 0x27d0 (en: 'white diamond with centered dot', google: 'vit diamant med centrerad prick') + - "⟑": [T: "og med prikk"] # 0x27d1 (en: 'and with dot') + - "⟒": [T: "tilhører med åpning oppover"] # 0x27d2 (en: 'element of opening upwards') + - "⟓": [T: "nedre høyre hjørne med prikk"] # 0x27d3 (en: 'lower right corner with dot') + - "⟔": [T: "øvre venstre hjørne med prikk"] # 0x27d4 (en: 'upper left corner with dot') + - "⟕": [T: "venstre outer join"] # 0x27d5 (en: 'left outer join') + - "⟖": [T: "høyre outer join"] # 0x27d6 (en: 'right outer join') + - "⟗": [T: "full outer join"] # 0x27d7 (en: 'full outer join') + - "⟘": [T: "stort oppoverrotert dreiekors"] # 0x27d8 (en: 'large up tack') + - "⟙": [T: "stort nedoverrotert dreiekors"] # 0x27d9 (en: 'large down tack') + - "⟚": [T: "venstre og høyre dobbelt dreiekors"] # 0x27da (en: 'left and right double turnstile') + - "⟛": [T: "venstre og høyre dreiekors"] # 0x27db (en: 'left and right tack') + - "⟜": [T: "venstre multimap"] # 0x27dc (en: 'left multimap') + - "⟝": [T: "langt høyre dreiekors"] # 0x27dd (en: 'long right tack') + - "⟞": [T: "langt venstre dreiekors"] # 0x27de (en: 'long left tack') + - "⟟": [T: "oppoverrotert dreiekors med sirkel over"] # 0x27df (en: 'up tack with circle above') + - "⟠": [T: "rombe delt med horisontal strek"] # 0x27e0 (en: 'lozenge divided by horizontal rule') + - "⟡": [T: "hvit konkav-sidet diamant"] # 0x27e1 (en: 'white concave sided diamond') + - "⟢": [T: "hvit konkav-sidet diamant med strek til venstre"] # 0x27e2 (en: 'white concave sided diamond with leftwards tick') + - "⟣": [T: "hvit konkav-sidet diamant med strek til høyre"] # 0x27e3 (en: 'white concave sided diamond with rightwards tick') + - "⟤": [T: "hvitt kvadrat med strek til venstre"] # 0x27e4 (en: 'white square with leftwards tick') + - "⟥": [T: "hvitt kvadrat med strek til høyre"] # 0x27e5 (en: 'white square with rightwards tick') + - "⟦": [T: "hvit venstre hakeparentes"] # 0x27e6 (en: 'left white square bracket') + - "⟧": [T: "hvit høyre hakeparentes"] # 0x27e7 (en: 'right white square bracket') + - "⟨": [T: "venstre vinkel-parentes"] # 0x27e8 (en: 'left angle bracket') + - "⟩": [T: "høyre vinkel-parentes"] # 0x27e9 (en: 'right angle bracket') + - "⟪": [T: "venstre dobbel vinkel-parentes"] # 0x27ea (en: 'left double angle bracket') + - "⟫": [T: "høyre dobbel vinkel-parentes"] # 0x27eb (en: 'right double angle bracket') + - "⟬": [T: "venstre hvit skilpaddeskall-parentes"] # 0x27ec (en: 'left white tortoise shell bracket') + - "⟭": [T: "høyre hvit skilpaddeskall-parentes"] # 0x27ed (en: 'right white tortoise shell bracket') + - "⟮": [T: "avflatet høyreparentes"] # 0x27ee (en: 'left flattened parenthesis') + - "⟯": [T: "avflatet venstreparentes"] # 0x27ef (en: 'right flattened parenthesis') + #-------------------------------------------------------------------------------------------------- + # Supplemental arrows-A OK + - "⟰": [T: "kvadrupel-streket oppoverpil"] # 0x27f0 (en: 'upwards quadruple arrow', google: 'uppåt fyrdubbla pilen') + - "⟱": [T: "kvadrupel-streket nedoverpil"] # 0x27f1 (en: 'downwards quadruple arrow', google: 'nedåt fyrdubbla pilen') + - "⟲": [T: "åpen sirkelpil mot klokken"] # 0x27f2 (en: 'anticlockwise gapped circle arrow', google: 'antikvis gappad cirkelpil') + - "⟳": [T: "åpen sirkelpil med klokken"] # 0x27f3 (en: 'clockwise gapped circle arrow', google: 'medurs gappad cirkelpil') + - "⟴": [T: "høyrepil med pluss i sirkel"] # 0x27f4 (en: 'right arrow with circled plus', google: 'höger-pil med circled plus') + - "⟵": [T: "lang venstrepil"] # 0x27f5 (en: 'long leftwards arrow') + - "⟶": [T: "lang høyrepil"] # 0x27f6 (en: 'long rightwards arrow') + - "⟷": [T: "lang venstre-høyre-pil"] # 0x27f7 (en: 'long left right arrow') + - "⟸": [T: "lang dobbeltstreket venstrepil"] # 0x27f8 (en: 'long leftwards double arrow') + - "⟹": [T: "lang dobbeltstreket høyrepil"] # 0x27f9 (en: 'long rightwards double arrow') + - "⟺": [T: "lang dobbeltstreket venstre-høyre-pil"] # 0x27fa (en: 'long left right double arrow') + - "⟻": [T: "lang venstrepil fra strek"] # 0x27fb (en: 'long leftwards arrow from bar', google: 'lång vänster pil från bar') + - "⟼": [T: "lang høyrepil fra strek"] # 0x27fc (en: 'long rightwards arrow from bar') + - "⟽": [T: "lang dobbeltstreket venstrepil fra strek"] # 0x27fd (en: 'long leftwards double arrow from bar', google: 'lång vänster dubbelpil från bar') + - "⟾": [T: "lang dobbeltstreket høyrepil fra strek"] # 0x27fe (en: 'long rightwards double arrow from bar', google: 'långt höger-pil från bar') + - "⟿": [T: "lang svingete høyrepil"] # 0x27ff (en: 'long rightwards squiggle arrow') + #------------------------------------------------------------------------------------------------------ + #Supplemental arrows-B OK + - "⤀": [T: "høyrepil med to spisser og vertikal strek"] # 0x2900 (en: 'rightwards two headed arrow with vertical stroke', google: 'åtgärd två ledde pil med vertikalt slag') + - "⤁": [T: "høyrepil med to spisser og dobbel vertikal strek"] # 0x2901 (en: 'rightwards two headed arrow with double vertical stroke', google: 'åtgärder två pil med dubbel vertikal stroke') + - "⤂": [T: "dobbeltstreket venstrepil med vertikal strek"] # 0x2902 (en: 'leftwards double arrow with vertical stroke', google: 'vänster dubbelpil med vertikalt slag') + - "⤃": [T: "dobbeltstreket høyrepil med vertikal strek"] # 0x2903 (en: 'rightwards double arrow with vertical stroke', google: 'åtgärd med höger med vertikal stroke') + - "⤄": [T: "dobbeltstreket venstre-høyre-pil med vertikal strek"] # 0x2904 (en: 'left right double arrow with vertical stroke', google: 'vänster höger dubbelpil med vertikalt slag') + - "⤅": [T: "høyrepil fra strek med dobbel spiss"] # 0x2905 (en: 'rightwards two headed arrow from bar') + - "⤆": [T: "dobbeltstreket venstrepil fra strek"] # 0x2906 (en: 'leftwards double arrow from bar', google: 'vänster dubbelpil från bar') + - "⤇": [T: "dobbeltstreket høyrepil fra strek"] # 0x2907 (en: 'rightwards double arrow from bar', google: 'åtgärd med höger pil från stången') + - "⤈": [T: "nedoverpil med horisontal strek"] # 0x2908 (en: 'downwards arrow with horizontal stroke', google: 'nedåt pil med horisontellt slag') + - "⤉": [T: "oppoverpil med horisontal strek"] # 0x2909 (en: 'upwards arrow with horizontal stroke', google: 'uppåt pil med horisontellt slag') + - "⤊": [T: "trippel-streket oppoverpil"] # 0x290a (en: 'upwards triple arrow', google: 'uppåt trippelpil') + - "⤋": [T: "trippel-streket nedoverpil"] # 0x290b (en: 'downwards triple arrow', google: 'nedåt trippelpil') + - "⤌": [T: "stiplet venstrepil"] # 0x290c (en: 'leftwards double dash arrow') + - "⤍": [T: "stiplet høyrepil"] # 0x290d (en: 'rightwards double dash arrow') + - "⤎": [T: "stiplet venstrepil"] # 0x290e (en: 'leftwards triple dash arrow') + - "⤏": [T: "stiplet høyrepil"] # 0x290f (en: 'rightwards triple dash arrow') + - "⤐": [T: "stiplet høyrepil med to spisser"] # 0x2910 (en: 'rightwards two headed triple dash arrow') + - "⤑": [T: "prikket høyrepil"] # 0x2911 (en: 'rightwards arrow with dotted stem') + - "⤒": [T: "oppoverpil mot strek"] # 0x2912 + - "⤓": [T: "nedoverpil mot strek"] # 0x2913 + - "⤔": [T: "høyrepil med hale og vertikal strek"] # 0x2914 (en: 'rightwards arrow with tail and vertical stroke', google: 'åtgärdspil med svans och vertikalt slag') + - "⤕": [T: "høyrepil med hale og dobbel vertikal strek"] # 0x2915 (en: 'rightwards arrow with tail and double vertical stroke', google: 'åtgärdspil med svans och dubbel vertikal stroke') + - "⤖": [T: "høyrepil med dobbel spiss og hale"] # 0x2916 (en: 'rightwards two headed arrow with tail') + - "⤗": [T: "høyrepil med dobbel spiss og hale og vertikal strek"] # 0x2917 (en: 'rightwards two headed arrow with tail with vertical stroke', google: 'åt höger två pil med svans med vertikalt stroke') + - "⤘": [T: "høyrepil med dobbel spiss og hale og dobbel vertikal strek"] # 0x2918 (en: 'rightwards two headed arrow with tail with double vertical stroke', google: 'åt höger två pil med svans med dubbel vertikal stroke') + - "⤙": [T: "venstre pil-hale"] # 0x2919 (en: 'leftwards arrow tail') + - "⤚": [T: "høyre pil-hale"] # 0x291a (en: 'rightwards arrow tail', google: 'åtgärder med höger pil') + - "⤛": [T: "dobbel venstre pil-hale"] # 0x291b (en: 'leftwards double arrow tail') + - "⤜": [T: "dobbel høyre pil-hale"] # 0x291c (en: 'rightwards double arrow tail') + - "⤝": [T: "venstrepil mot fylt diamant"] # 0x291d (en: 'leftwards arrow to filled diamond') + - "⤞": [T: "høyrepil mot fylt diamant"] # 0x291e (en: 'rightwards arrow to filled diamond') + - "⤟": [T: "venstrepil fra strek til fylt diamant"] # 0x291f (en: 'leftwards arrow from bar to filled diamond') + - "⤠": [T: "høyrepil fra strek til fylt diamant"] # 0x2920 (en: 'rightwards arrow from bar to filled diamond') + - "⤡": [T: "nordvest- og sørøst-pil"] # 0x2921 (en: 'north west and south east arrow', google: 'north west och south east arrow') + - "⤢": [T: "nordøst- og sørvest-pil"] # 0x2922 (en: 'north east and south west arrow', google: 'north east and south west arrow') + - "⤣": [T: "nordvest-pil med krok"] # 0x2923 (en: 'north west arrow with hook') + - "⤤": [T: "nordøst-pil med krok"] # 0x2924 (en: 'north east arrow with hook') + - "⤥": [T: "sørøst-pil med krok"] # 0x2925 (en: 'south east arrow with hook') + - "⤦": [T: "sørvest-pil med krok"] # 0x2926 (en: 'south west arrow with hook') + - "⤧": [T: "nordvest-pil og nordøst-pil"] # 0x2927 (en: 'north west arrow and north east arrow') + - "⤨": [T: "nordøst-pil og sørøst-pil"] # 0x2928 (en: 'north east arrow and south east arrow') + - "⤩": [T: "sørøst-pil og sørvest-pil"] # 0x2929 (en: 'south east arrow and south west arrow') + - "⤪": [T: "sørvest-pil og nordvest-pil"] # 0x292a (en: 'south west arrow and north west arrow') + - "⤫": [T: "stigende diagonal krysser synkende diagonal"] # 0x292b (en: 'rising diagonal crossing falling diagonal', google: 'stigande diagonal korsning fallande diagonal') + - "⤬": [T: "synkende diagonal krysser stigende diagonal"] # 0x292c (en: 'falling diagonal crossing rising diagonal', google: 'fallande diagonal korsning stigande diagonal') + - "⤭": [T: "sørøst-pil krysser nordøst-pil"] # 0x292d (en: 'south east arrow crossing north east arrow', google: 'south east arrow crossing north east arrow') + - "⤮": [T: "nordøst-pil krysser sørøst-pil"] # 0x292e (en: 'north east arrow crossing south east arrow', google: 'north east arrow crossing south east arrow') + - "⤯": [T: "synkende diagonal krysser nordøst-pil"] # 0x292f (en: 'falling diagonal crossing north east arrow', google: 'fallande diagonal korsar nord-ostra pilen') + - "⤰": [T: "stigende diagonal krysser sørøst-pil"] # 0x2930 (en: 'rising diagonal crossing south east arrow', google: 'rising diagonal crossing south east arrow') + - "⤱": [T: "nordøst-pil krysser nordvest-pil"] # 0x2931 (en: 'north east arrow crossing north west arrow', google: 'north east arrow crossing north west arrow') + - "⤲": [T: "nordvest-pil krysser nordøst-pil"] # 0x2932 (en: 'north west arrow crossing north east arrow', google: 'north west arrow crossing north east arrow') + - "⤳": [T: "bølgete høyrepil"] # 0x2933 (en: 'wave arrow pointing directly right') + - "⤴": [T: "høyrepil med vinkel oppover"] # 0x2934 (en: 'arrow pointing rightwards then curving upwards', google: 'arrow pekar åt höger och böjer sig sedan uppåt') + - "⤵": [T: "høyrepil med vinkel nedover"] # 0x2935 (en: 'arrow pointing rightwards then curving downwards') + - "⤶": [T: "nedoverpil med vinkel til venstre"] # 0x2936 (en: 'arrow pointing downwards then curving leftwards') + - "⤷": [T: "nedoverpil med vinkel til høyre"] # 0x2937 (en: 'arrow pointing downwards then curving rightwards') + - "⤸": [T: "halvsirkelpil med klokken"] # 0x2938 (en: 'right side arc clockwise arrow') + - "⤹": [T: "halvsirkelpil mot klokken"] # 0x2939 (en: 'left side arc anticlockwise arrow') + - "⤺": [T: "øvre halvsirkelpil mot klokken"] # 0x293a (en: 'top arc anticlockwise arrow', google: 'toppbåge moturs pil') + - "⤻": [T: "nedre halvsirkelpil mot klokken"] # 0x293b (en: 'bottom arc anticlockwise arrow', google: 'nedre båge anticurs pil') + - "⤼": [T: "øvre halvsirkelpil med klokken med minus"] # 0x293c (en: 'top arc clockwise arrow with minus') + - "⤽": [T: "øvre halvsirkelpil mot klokken med pluss"] # 0x293d (en: 'top arc anticlockwise arrow with plus') + - "⤾": [T: "halvsirkelpil med klokken"] # 0x293e (en: 'lower right semicircular clockwise arrow', google: 'nedre högra halvcirkelformade medurs pil') + - "⤿": [T: "halvsirkelpil mot klokken"] # 0x293f (en: 'lower left semicircular anticlockwise arrow', google: 'nedre vänstra halvcirkelformade pil moturs') + - "⥀": [T: "sirkel-pil mot klokken"] # 0x2940 (en: 'anticlockwise closed circle arrow', google: 'antikvis stängd cirkelpil') + - "⥁": [T: "sirkel-pil med klokken"] # 0x2941 (en: 'clockwise closed circle arrow', google: 'medurs stängd cirkelpil') + - "⥂": [T: "høyrepil over kort venstrepil"] # 0x2942 (en: 'rightwards arrow above short leftwards arrow', google: 'åtgärdspil över kort vänster pil') + - "⥃": [T: "venstrepil over kort høyrepil"] # 0x2943 (en: 'leftwards arrow above short rightwards arrow', google: 'vänster pil ovanför kort höger-pil') + - "⥄": [T: "kort høyrepil over venstrepil"] # 0x2944 (en: 'short rightwards arrow above leftwards arrow', google: 'kort höger-pil ovanför vänster pil') + - "⥅": [T: "høyrepil med pluss under"] # 0x2945 (en: 'rightwards arrow with plus below') + - "⥆": [T: "venstrepil med pluss under"] # 0x2946 (en: 'leftwards arrow with plus below', google: 'vänster pil med plus nedan') + - "⥇": [T: "høyrepil gjennom x"] # 0x2947 (en: 'rightwards arrow through x', google: 'åtgärdspil genom x') + - "⥈": [T: "venstre-høyre-pil gjennom sirkel"] # 0x2948 (en: 'left right arrow through circle') + - "⥉": [T: "oppoverpil med dobbel spiss fra sirkel"] # 0x2949 (en: 'upwards two headed arrow from circle') + - "⥊": [T: "toveis harpun venstre mothake opp høyre mothake ned"] # 0x294a (en: 'left barb up right barb down harpoon') + - "⥋": [T: "toveis harpun venstre mothake ned høyre mothake opp"] # 0x294b (en: 'left barb down right barb up harpoon') + - "⥌": [T: "toveis vertikal harpun øvre mothake høyre nedre mothake venstre"] # 0x294c (en: 'up barb right down barb left harpoon', google: 'upp barb höger ner barb vänster harpun') + - "⥍": [T: "toveis vertikal harpun øvre mothake venstre nedre mothake høyre"] # 0x294d (en: 'up barb left down barb right harpoon', google: 'upp barb vänster ner barb höger harpoon') + - "⥎": [T: "toveis harpun mothaker opp"] # 0x294e (en: 'left barb up right barb up harpoon', MathPlayer: 'vänster höger harpoon up', google: 'vänster barb upp höger barb upp harpoon') + - "⥏": [T: "toveis vertikal harpun mothaker høyre"] # 0x294f (en: 'up barb right down barb right harpoon') + - "⥐": [T: "toveis harpun mothaker ned"] # 0x2950 (en: 'left barb down right barb down harpoon', MathPlayer: 'vänster höger harpoon ner') + - "⥑": [T: "toveis vertikal harpun mothaker venstre"] # 0x2951 (en: 'up barb left down barb left harpoon') + - "⥒": [T: "venstre-harpun mot strek mothake opp"] # 0x2952 (en: 'leftwards harpoon with barb up to bar') + - "⥓": [T: "høyre-harpun mot strek mothake opp"] # 0x2953 (en: 'rightwards harpoon with barb up to bar') + - "⥔": [T: "opp-harpun mot strek mothake høyre"] # 0x2954 (en: 'upwards harpoon with barb right to bar') + - "⥕": [T: "ned-harpun mot strek mothake høyre"] # 0x2955 (en: 'downwards harpoon with barb right to bar') + - "⥖": [T: "venstre-harpun mot strek mothake ned"] # 0x2956 (en: 'leftwards harpoon with barb down to bar') + - "⥗": [T: "høyre-harpun mot strek mothake ned"] # 0x2957 (en: 'rightwards harpoon with barb down to bar') + - "⥘": [T: "opp-harpun mot strek mothake venstre"] # 0x2958 (en: 'upwards harpoon with barb left to bar') + - "⥙": [T: "ned-harpun mot strek mothake venstre"] # 0x2959 (en: 'downwards harpoon with barb left to bar') + - "⥚": [T: "venstre-harpun fra strek mothake opp"] # 0x295a (en: 'leftwards harpoon with barb up from bar') + - "⥛": [T: "høyre-harpun fra strek mothake opp"] # 0x295b (en: 'rightwards harpoon with barb up from bar') + - "⥜": [T: "opp-harpun fra strek mothake høyre"] # 0x295c (en: 'upwards harpoon with barb right from bar') + - "⥝": [T: "ned-harpun fra strek mothake høyre"] # 0x295d (en: 'downwards harpoon with barb right from bar') + - "⥞": [T: "venstre-harpun fra strek mothake ned"] # 0x295e (en: 'leftwards harpoon with barb down from bar') + - "⥟": [T: "høyre-harpun fra strek mothake ned"] # 0x295f (en: 'rightwards harpoon with barb down from bar') + - "⥠": [T: "opp-harpun fra strek mothake venstre"] # 0x2960 (en: 'upwards harpoon with barb left from bar') + - "⥡": [T: "ned-harpun fra strek mothake venstre"] # 0x2961 (en: 'downwards harpoon with barb left from bar') + - "⥢": [T: "venstre-harpun mothake opp over venstre-harpun mothake ned"] # 0x2962 (en: 'leftwards harpoon with barb up above leftwards harpoon with barb down') + - "⥣": [T: "opp-harpun mothake venstre ved siden av opp-harpun mothake høyre"] # 0x2963 (en: 'upwards harpoon with barb left beside upwards harpoon with barb right') + - "⥤": [T: "høyre-harpun mothake opp over høyre-harpun mothake ned"] # 0x2964 (en: 'rightwards harpoon with barb up above rightwards harpoon with barb down') + - "⥥": [T: "ned-harpun mothake venstre ved siden av ned-harpun mothake høyre"] # 0x2965 (en: 'downwards harpoon with barb left beside downwards harpoon with barb right') + - "⥦": [T: "venstre-harpun mothake opp over høyre-harpun mothake opp"] # 0x2966 (en: 'leftwards harpoon with barb up above rightwards harpoon with barb up') + - "⥧": [T: "venstre-harpun mothake ned over høyre-harpun mothake ned"] # 0x2967 (en: 'leftwards harpoon with barb down above rightwards harpoon with barb down') + - "⥨": [T: "høyre-harpun mothake opp over venstre-harpun mothake opp"] # 0x2968 (en: 'rightwards harpoon with barb up above leftwards harpoon with barb up') + - "⥩": [T: "høyre-harpun mothake ned over venstre-harpun mothake ned"] # 0x2969 (en: 'rightwards harpoon with barb down above leftwards harpoon with barb down') + - "⥪": [T: "venstre-harpun mothake opp over strek"] # 0x296a (en: 'leftwards harpoon with barb up above long dash') + - "⥫": [T: "venstre-harpun mothake ned under strek"] # 0x296b (en: 'leftwards harpoon with barb down below long dash') + - "⥬": [T: "høyre-harpun mothake opp over strek"] # 0x296c (en: 'rightwards harpoon with barb up above long dash') + - "⥭": [T: "høyre-harpun mothake ned under strek"] # 0x296d (en: 'rightwards harpoon with barb down below long dash') + - "⥮": [T: "opp-harpun mothake venstre ved siden av ned-harpun mothake høyre"] # 0x296e (en: 'upwards harpoon with barb left beside downwards harpoon with barb right') + - "⥯": [T: "ned-harpun mothake venstre ved siden av opp-harpun mothake høyre"] # 0x296f (en: 'downwards harpoon with barb left beside upwards harpoon with barb right') + - "⥰": [T: "dobbeltstreket høyrepil med avrundet spiss"] # 0x2970 (en: 'right double arrow with rounded head') + - "⥱": [T: "lik over høyrepil"] # 0x2971 (en: 'equals above rightwards arrow') + - "⥲": [T: "tilde over høyrepil"] # 0x2972 (en: 'tilde operator above rightwards arrow') + - "⥳": [T: "venstrepil over tilde"] # 0x2973 (en: 'leftwards arrow above tilde operator') + - "⥴": [T: "høyrepil over tilde"] # 0x2974 (en: 'rightwards arrow above tilde operator') + - "⥵": [T: "høyrepil over tilnærmet lik"] # 0x2975 (en: 'rightwards arrow above almost equal to') + - "⥶": [T: "mindre enn over venstrepil"] # 0x2976 (en: 'less than above leftwards arrow') + - "⥷": [T: "venstrepil gjennom mindre enn"] # 0x2977 (en: 'leftwards arrow through less than', google: 'vänster pil genom mindre än') + - "⥸": [T: "større enn over høyrepil"] # 0x2978 (en: 'greater than above rightwards arrow') + - "⥹": [T: "delmengde over høyrepil"] # 0x2979 (en: 'subset above rightwards arrow') + - "⥺": [T: "venstrepil gjennom delmengde"] # 0x297a (en: 'leftwards arrow through subset', google: 'vänster pil genom undergruppen') + - "⥻": [T: "overmengde over venstrepil"] # 0x297b (en: 'superset above leftwards arrow') + - "⥼": [T: "fiskehale til venstre"] # 0x297c (en: 'left fish tail') + - "⥽": [T: "fiskehale til høyre"] # 0x297d (en: 'right fish tail') + - "⥾": [T: "fiskehale oppover"] # 0x297e (en: 'up fish tail') + - "⥿": [T: "fiskehale nedover"] # 0x297f (en: 'down fish tail') + #--------------------------------------------------------------------------------------------- + # Miscellaneous Mathematical symbols-B OK + - "⦀": [T: "trippel loddrett strek"] # 0x2980 (en: 'triple vertical bar delimiter', google: 'trippel vertikal bar avgränsare') + - "⦁": [T: "punkt z-notasjon"] # 0x2981 (en: 'z notation spot', google: 'z notation spot') + - "⦂": [T: "kolon z-notasjon"] # 0x2982 (en: 'z notation type colon', google: 'z notationstyp kolon') + - "⦃": [T: "venstre hvit krøllparentes"] # 0x2983 (en: 'left white brace', google: 'vänster vit stag') + - "⦄": [T: "høyre hvit krøllparentes"] # 0x2984 (en: 'right white brace', google: 'höger vit stag') + - "⦅": [T: "hvit venstreparentes"] # 0x2985 (en: 'left white parenthesis') + - "⦆": [T: "hvit høyreparentes"] # 0x2986 (en: 'right white parenthesis') + - "⦇": [T: "venstre bilde-parentes z-notasjon"] # 0x2987 (en: 'z notation left image bracket', google: 'z notation vänster bildfäste') + - "⦈": [T: "høyre bilde-parentes z-notasjon"] # 0x2988 (en: 'z notation right image bracket', google: 'z notation rätt bildfäste') + - "⦉": [T: "venstre bindende parentes z-notasjon"] # 0x2989 (en: 'z notation left binding bracket') + - "⦊": [T: "høyre bindende parentes z-notasjon"] # 0x298a (en: 'z notation right binding bracket') + - "⦋": [T: "venstre hakeparentes med strek under"] # 0x298b (en: 'left square bracket with underbar') + - "⦌": [T: "høyre hakeparentes med strek under"] # 0x298c (en: 'right square bracket with underbar') + - "⦍": [T: "venstre hakeparentes med strek i øvre hjørne"] # 0x298d (en: 'left square bracket with tick in top corner') + - "⦎": [T: "høyre hakeparentes med strek i nedre hjørne"] # 0x298e (en: 'right square bracket with tick in bottom corner') + - "⦏": [T: "venstre hakeparentes med strek i nedre hjørne"] # 0x298f (en: 'left square bracket with tick in bottom corner') + - "⦐": [T: "høyre hakeparentes med strek i øvre hjørne"] # 0x2990 (en: 'right square bracket with tick in top corner') + - "⦑": [T: "venstre vinkelparentes med prikk"] # 0x2991 (en: 'left angle bracket with dot') + - "⦒": [T: "høyre vinkelparentes med prikk"] # 0x2992 (en: 'right angle bracket with dot') + - "⦓": [T: "venstre mindre enn parentes"] # 0x2993 (en: 'left arc less than bracket') + - "⦔": [T: "høyre større enn parentes"] # 0x2994 (en: 'right arc greater than bracket') + - "⦕": [T: "venstre dobbel større enn parentes"] # 0x2995 (en: 'double left arc greater than bracket') + - "⦖": [T: "høyre dobbel mindre enn parentes"] # 0x2996 (en: 'double right arc less than bracket') + - "⦗": [T: "venstre skilpaddeskall-parentes"] # 0x2997 (en: 'left black tortoise shell bracket', google: 'vänster svart sköldpaddsskalfäste') + - "⦘": [T: "høyre skilpaddeskall-parentes"] # 0x2998 (en: 'right black tortoise shell bracket', google: 'höger svart sköldpaddsskalfäste') + - "⦙": [T: "prikket loddrett strek"] # 0x2999 (en: 'dotted fence', google: 'prickat staket') + - "⦚": [T: "sikksakk loddrett strek"] # 0x299a (en: 'vertical zigzag line') + - "⦛": [T: "målt vinkel til venstre"] # 0x299b (en: 'measured angle opening left', google: 'uppmätt vinkelöppning vänster') + - "⦜": [T: "rett vinkel"] # 0x299c (en: 'right angle variant with square', google: 'rätt vinkelvariant med fyrkant') + - "⦝": [T: "målt rett vinkel med prikk"] # 0x299d (en: 'measured right angle with dot') + - "⦞": [T: "vinkel med s i"] # 0x299e (en: 'angle with s inside') + - "⦟": [T: "spiss vinkel"] # 0x299f (en: 'acute angle') + - "⦠": [T: "sfærisk vinkel til venstre"] # 0x29a0 (en: 'spherical angle opening left', google: 'sfärisk vinkelöppning vänster') + - "⦡": [T: "sfærisk vinkel oppover"] # 0x29a1 (en: 'spherical angle opening up', google: 'sfärisk vinkel öppnas') + - "⦢": [T: "snudd vinkel"] # 0x29a2 (en: 'turned angle', google: 'vände vinkel') + - "⦣": [T: "speilvendt vinkel"] # 0x29a3 (en: 'reversed angle') + - "⦤": [T: "vinkel med strek under"] # 0x29a4 (en: 'angle with underbar') + - "⦥": [T: "speilvendt vinkel med strek under"] # 0x29a5 (en: 'reversed angle with underbar') + - "⦦": [T: "stump vinkel oppover"] # 0x29a6 (en: 'oblique angle opening up') + - "⦧": [T: "stump vinkel nedover"] # 0x29a7 (en: 'oblique angle opening down') + - "⦨": [T: "målt vinkel med nordøst-pil i enden av øvre vinkelben"] # 0x29a8 (en: 'measured angle with open arm ending in arrow pointing up and to the right') + - "⦩": [T: "målt vinkel med nordvest-pil i enden av øvre vinkelben"] # 0x29a9 (en: 'measured angle with open arm ending in arrow pointing up and to the left') + - "⦪": [T: "målt vinkel med sørøst-pil i enden av nedre vinkelben"] # 0x29aa (en: 'measured angle with open arm ending in arrow pointing down and to the right') + - "⦫": [T: "målt vinkel med sørvest-pil i enden av nedre vinkelben"] # 0x29ab (en: 'measured angle with open arm ending in arrow pointing down and to the left') + - "⦬": [T: "målt vinkel med nordøst-pil i enden av høyre vinkelben"] # 0x29ac (en: 'measured angle with open arm ending in arrow pointing right and up') + - "⦭": [T: "målt vinkel med nordvest-pil i enden av venstre vinkelben"] # 0x29ad (en: 'measured angle with open arm ending in arrow pointing left and up') + - "⦮": [T: "målt vinkel med sørøst-pil i enden av høyre vinkelben"] # 0x29ae (en: 'measured angle with open arm ending in arrow pointing right and down') + - "⦯": [T: "målt vinkel med sørvest-pil i enden av venstre vinkelben"] # 0x29af (en: 'measured angle with open arm ending in arrow pointing left and down') + - "⦰": [T: "den tomme mengden speilvendt"] # 0x29b0 (en: 'reversed empty set') + - "⦱": [T: "den tomme mengden med strek over"] # 0x29b1 (en: 'empty set with overbar') + - "⦲": [T: "den tomme mengden med sirkel over"] # 0x29b2 (en: 'empty set with small circle above') + - "⦳": [T: "den tomme mengden med høyrepil over"] # 0x29b3 (en: 'empty set with right arrow above') + - "⦴": [T: "den tomme mengden med venstrepil over"] # 0x29b4 (en: 'empty set with left arrow above') + - "⦵": [T: "sirkel med horisontal strek"] # 0x29b5 (en: 'circle with horizontal bar') + - "⦶": [T: "sirkel med vertikal strek"] # 0x29b6 (SRE: 'vertikalt streck i cirkel') + - "⦷": [T: "parallell i sirkel"] # 0x29b7 (en: 'circled parallel') + - "⦸": [T: "sirkel med omvendt skråstrek"] # 0x29b8 (en: 'circled reverse solidus', google: 'circled reverse solidus') + - "⦹": [T: "vinkelrett i sirkel"] # 0x29b9 (en: 'circled perpendicular') + - "⦺": [T: "sirkel delt med horisontal strek og øvre del delt med vertikal strek"] # 0x29ba (en: 'circled divided by horizontal bar and top half divided by vertical bar', google: 'cirklade dividerat med horisontell stång och den övre halvan dividerad med vertikal stång') + - "⦻": [T: "sirkel med x"] # 0x29bb (en: 'circle with superimposed x') + - "⦼": [T: "sirkel med divisjon rotert mot klokken"] # 0x29bc (en: 'circled anticlockwise rotated division sign') + - "⦽": [T: "oppoverpil gjennom sirkel"] # 0x29bd (en: 'up arrow through circle', google: 'upp pilen genom cirkeln') + - "⦾": [T: "hvitt punkt i sirkel"] # 0x29be (en: 'circled white bullet') + - "⦿": [T: "punkt i sirkel"] # 0x29bf (en: 'circled bullet') + - "⧀": [T: "mindre enn i sirkel"] # 0x29c0 (en: 'circled less than') + - "⧁": [T: "større enn i sirkel"] # 0x29c1 (en: 'circled greater than') + - "⧂": [T: "sirkel med liten sirkel til høyre"] # 0x29c2 (en: 'circle with small circle to the right') + - "⧃": [T: "sirkel med to horisontale streker til høyre"] # 0x29c3 (en: 'circle with two horizontal strokes to the right') + - "⧄": [T: "kvadrat med diagonal oppover"] # 0x29c4 (en: 'squared rising diagonal slash') + - "⧅": [T: "kvadrat med diagonal nedover"] # 0x29c5 (en: 'squared falling diagonal slash') + - "⧆": [T: "asterisk i kvadrat"] # 0x29c6 (en: 'squared asterisk', google: 'kvadratisk asterisk') + - "⧇": [T: "liten sirkel i kvadrat"] # 0x29c7 (en: 'squared small circle', google: 'kvadrat liten cirkel') + - "⧈": [T: "kvadrat i kvadrat"] # 0x29c8 (en: 'squared square', google: 'squared square') + - "⧉": [T: "to sammenføyde kvadrat"] # 0x29c9 (en: 'two joined squares') + - "⧊": [T: "trekant med prikk over"] # 0x29ca (en: 'triangle with dot above', google: 'triangel med prick ovan') + - "⧋": [T: "trekant med strek under"] # 0x29cb (en: 'triangle with underbar', google: 'triangel med underbar') + - "⧌": [T: "trekant med s"] # 0x29cc (en: 's in triangle') + - "⧍": [T: "trekant med seriffer på bunnen"] # 0x29cd (en: 'triangle with serifs at bottom') + - "⧎": [T: "høyre trekant over venstre trekant"] # 0x29ce (en: 'right triangle above left triangle') + - "⧏": [T: "venstre trekant ved siden av vertikal strek"] # 0x29cf (en: 'left triangle beside vertical bar') + - "⧐": [T: "vertikal strek ved siden av høyre trekant"] # 0x29d0 (en: 'vertical bar beside right triangle') + - "⧑": [T: "sløyfe med venstre halvdel fylt"] # 0x29d1 (en: 'bowtie with left half black', google: 'bowtie med vänster halva svart') + - "⧒": [T: "sløyfe med høyre halvdel fylt"] # 0x29d2 (en: 'bowtie with right half black', google: 'bowtie med höger halv svart') + - "⧓": [T: "fylt sløyfe"] # 0x29d3 (en: 'black bowtie', google: 'svart bowtie') + - "⧔": [T: "sløyfe med venstre halvdel fylt og høyre halvdel åpen"] # 0x29d4 (en: 'times with left half black', google: 'gånger med vänster halva svart') + - "⧕": [T: "sløyfe med venstre halvdel åpen og høyre halvdel fylt"] # 0x29d5 (en: 'times with right half black', google: 'gånger med höger halv svart') + - "⧖": [T: "hvitt timeglass"] # 0x29d6 (en: 'white hourglass', google: 'vit timglas') + - "⧗": [T: "fylt timeglass"] # 0x29d7 (en: 'black hourglass') + - "⧘": [T: "venstre sikksakk gjerde"] # 0x29d8 (en: 'left wiggly fence', google: 'vänster wiggly staket') + - "⧙": [T: "høyre sikksakk gjerde"] # 0x29d9 (en: 'right wiggly fence', google: 'höger vinglt staket') + - "⧚": [T: "dobbelt venstre sikksakk gjerde"] # 0x29da (en: 'left double wiggly fence', MathPlayer: 'left double wiggly fence', google: 'vänster dubbel wiggly staket') + - "⧛": [T: "dobbelt høyre sikksakk gjerde"] # 0x29db (en: 'right double wiggly fence', MathPlayer: 'right double wiggly fence', google: 'höger dubbel wiggly staket') + - "⧜": [T: "ufullstendig uendelig"] # 0x29dc (en: 'incomplete infinity') + - "⧝": [T: "bånd over uendelighetstegn"] # 0x29dd (en: 'tie over infinity', google: 'bind över oändligheten') + - "⧞": [T: "uendelig med vertikal strek"] # 0x29de (en: 'infinity negated with vertical bar') + - "⧟": [T: "tosidig multimap"] # 0x29df (en: 'double-ended multimap', google: 'dubbel-sluten multimap') + - "⧠": [T: "kvadrat med omriss"] # 0x29e0 (en: 'square with contoured outline', google: 'fyrkantig med konturerad kontur') + - "⧡": [T: "øker som"] # 0x29e1 (en: 'increases as') + - "⧢": [T: "shuffle-produkt"] # 0x29e2 (en: 'shuffle product', google: 'shuffle -produkt') + - "⧣": [T: "likhetstegn og skråstilt parallell"] # 0x29e3 (en: 'equals sign and slanted parallel') + - "⧤": [T: "likhetstegn og skråstilt parallell med tilde over"] # 0x29e4 (en: 'equals sign and slanted parallel with tilde above') + - "⧥": [T: "identisk med og skråstilt parallell"] # 0x29e5 (en: 'identical to and slanted parallel') + - "⧦": [T: "gleich stark"] # 0x29e6 + - "⧧": [T: "termodynamisk"] # 0x29e7 (en: 'thermodynamic', google: 'termodynamisk') + - "⧨": [T: "trekant nedover venstre halvdel fylt"] # 0x29e8 (en: 'down pointing triangle with left half black', google: 'ner pekande triangel med vänster halvsvart') + - "⧩": [T: "trekant nedover høyre halvdel fylt"] # 0x29e9 (en: 'down pointing triangle with right half black', google: 'ner pekande triangel med höger halvsvart') + - "⧪": [T: "fylt diamant med pil ned"] # 0x29ea (en: 'black diamond with down arrow', google: 'svart diamant med nedpil') + - "⧫": [T: "fylt rombe"] # 0x29eb (en: 'black lozenge') + - "⧬": [T: "sirkel med pil ned"] # 0x29ec (en: 'white circle with down arrow', google: 'vit cirkel med nedpilen') + - "⧭": [T: "fylt sirkel med pil ned"] # 0x29ed (en: 'black circle with down arrow', google: 'svart cirkel med nedpilen') + - "⧮": [T: "firkant med utstikkere"] # 0x29ee (en: 'error-barred white square', google: 'fel-spärrvit fyrkant') + - "⧯": [T: "fylt firkant med utstikkere"] # 0x29ef (en: 'error-barred black square', google: 'fel-barred black square') + - "⧰": [T: "diamant med utstikkere"] # 0x29f0 (en: 'error-barred white diamond', google: 'fel-spärrad vit diamant') + - "⧱": [T: "fylt diamant med utstikkere"] # 0x29f1 (en: 'error-barred black diamond', google: 'fel-barred black diamond') + - "⧲": [T: "sirkel med utstikkere"] # 0x29f2 (en: 'error-barred white circle', google: 'fel-spärrad vit cirkel') + - "⧳": [T: "fylt sirkel med utstikkere"] # 0x29f3 (en: 'error-barred black circle', google: 'fel-barred black circle') + - "⧴": [T: "kolon høyrepil"] # 0x29f4 (en: 'rule-delayed', MathPlayer: 'rule delayed', google: 'regelförsenad') + - "⧵": [T: "omvendt skråstrek"] # 0x29f5 (en: 'reverse solidus operator', google: 'omvänd solidus -operatör') + - "⧶": [T: "skråstrek med strek over"] # 0x29f6 (en: 'solidus with overbar') + - "⧷": [T: "omvendt skråstrek med horisontal strek"] # 0x29f7 (en: 'reverse solidus with horizontal stroke', google: 'omvänd solidus med horisontellt slag') + - "⧸": [T: "stor skråstrek"] # 0x29f8 (en: 'big solidus', google: 'big solidus') + - "⧹": [T: "stor omvendt skråstrek"] # 0x29f9 (en: 'big reverse solidus', google: 'big reverse solidus') + - "⧺": [T: "dobbel pluss"] # 0x29fa (en: 'double plus', google: 'dubbel plus') + - "⧻": [T: "trippel pluss"] # 0x29fb (en: 'triple plus', google: 'trippel plus') + - "⧼": [T: "venstre buet vinkelparentes"] # 0x29fc (en: 'left pointing curved angle bracket', google: 'vänster pekande krökt vinkelfäste') + - "⧽": [T: "høyre buet vinkelparentes"] # 0x29fd (en: 'right pointing curved angle bracket', google: 'höger pekande krökt vinkelfäste') + # SWEDISH: kept English tiny & miny but changed spelling to get pronunciation right + - "⧾": [T: "tainy"] # 0x29fe (en: 'tiny', google: 'mycket liten') + - "⧿": [T: "mainy"] # 0x29ff (en: 'miny', google: 'miny') + #-------------------------------------------------------------------------------------------------------------- + # Supplemental Mathematical operators OK + - "⨀": [T: "dot-operator i sirkel"] # 0x2a00 (en: 'circled dot operator', google: 'circled dot operator') + - "⨁": [T: "pluss i sirkel"] # 0x2a01 (en: 'circled plus operator', google: 'circled plus operator') + - "⨂": [T: "multiplikasjon i sirkel"] # 0x2a02 (en: 'circled times operator', google: 'circled times operator') + - "⨃": [T: "union med prikk"] # 0x2a03 (en: 'union operator with dot', google: 'unionoperatör med dot') + - "⨄": [T: "union med pluss"] # 0x2a04 (en: 'union operator with plus', google: 'unionoperatör med plus') + - "⨅": [T: "kvadratisk snitt-operator"] # 0x2a05 (en: 'square intersection operator', google: 'square -korsningsoperatör') + - "⨆": [T: "kvadratisk union-operator"] # 0x2a06 (en: 'square union operator', google: 'square union operator') + - "⨇": [T: "to logiske og"] # 0x2a07 (en: 'two logical and operator', google: 'två logiska och operatörer') + - "⨈": [T: "to logiske eller"] # 0x2a08 (en: 'two logical or operator', google: 'två logiska eller operatörer') + - "⨉": [T: "ganger"] # 0x2a09 (en: 'times operator', google: 'times operator') + - "⨊": [T: "modulo to sum"] # 0x2a0a (en: 'modulo two sum', google: 'modulo två summa') + - "⨋": [T: "sum med integral"] # 0x2a0b (en: 'summation with integral', google: 'summering med integrerad') + - "⨌": [T: "firedobbelt integral"] # 0x2a0c (en: 'quadruple integral operator') + - "⨍": [T: "integral med horisontal strek"] # 0x2a0d (en: 'finite part integral') + - "⨎": [T: "integral med dobbel horisontal strek"] # 0x2a0e (en: 'integral with double stroke', google: 'integrerad med dubbelslag') + - "⨏": [T: "integral med skråstrek"] # 0x2a0f (en: 'integral average with slash', google: 'integrerat medelvärde med snedstreck') + - "⨐": [T: "sirkulasjons-funksjon"] # 0x2a10 (en: 'circulation function') + - "⨑": [T: "integrasjon mot klokka"] # 0x2a11 (en: 'anticlockwise integration') + - "⨒": [T: "linjeintegral med rektangulær vei rundt pol"] # 0x2a12 (en: 'line integration with rectangular path around pole') + - "⨓": [T: "linjeintegral med halvsirkel-vei rundt pol"] # 0x2a13 (en: 'line integration with semicircular path around pole') + - "⨔": [T: "linjeintegral eksklusiv polen"] # 0x2a14 (en: 'line integration not including the pole', MathPlayer: 'line integration not including the pole', google: 'linjeintegration inkluderar inte polen') + - "⨕": [T: "integral rund punkt-operator"] # 0x2a15 + - "⨖": [T: "integral med firkant"] # 0x2a16 + - "⨗": [T: "integral med venstrepil med krok"] # 0x2a17 (en: 'integral with leftwards arrow with hook') + - "⨘": [T: "integral med multiplikasjonstegn"] # 0x2a18 (en: 'integral with times sign', google: 'integrerad med times sign') + - "⨙": [T: "integral med snitt"] # 0x2a19 (en: 'integral with intersection', google: 'integrerad med korsning') + - "⨚": [T: "integral med union"] # 0x2a1a (en: 'integral with union', google: 'integrerad med unionen') + - "⨛": [T: "integral med horisontal strek over"] # 0x2a1b (en: 'integral with overbar', google: 'integrerad med overbar') + - "⨜": [T: "integral med horisontal strek under"] # 0x2a1c (en: 'integral with underbar', google: 'integrerad med underbar') + - "⨝": [T: "join"] # 0x2a1d (en: 'join', google: 'ansluta sig') + - "⨞": [T: "stor venstre trekant"] # 0x2a1e (en: 'large left triangle operator', google: 'stor vänster triangeloperatör') + - "⨟": [T: "skjema-sammensetning z-notasjon"] # 0x2a1f (en: 'z notation schema composition', google: 'z notationsschema komposition') + - "⨠": [T: "skjema-sluse z-notasjon"] # 0x2a20 (en: 'z notation schema piping', google: 'z notation schema piping') + - "⨡": [T: "skjema-projeksjon z-notasjon"] # 0x2a21 (en: 'z notation schema projection', google: 'z notation schema projection') + - "⨢": [T: "pluss med sirkel over"] # 0x2a22 (en: 'plus sign with circle above', MathPlayer: 'plustecken med ring över', google: 'plus skylt med cirkel ovan') + - "⨣": [T: "pluss med cirkumfleks over"] # 0x2a23 (en: 'plus sign with circumflex accent above', MathPlayer: 'plustecken med cirkumflex accent över', google: 'plus -tecken med circumflex -accent ovan') + - "⨤": [T: "pluss med tilde over"] # 0x2a24 (en: 'plus sign with tilde above') + - "⨥": [T: "pluss med prikk under"] # 0x2a25 (en: 'plus sign with dot below', MathPlayer: 'plustecken med punkt under', google: 'plus skylt med dot nedan') + - "⨦": [T: "pluss med tilde under"] # 0x2a26 (en: 'plus sign with tilde below') + - "⨧": [T: "pluss med nedre indeks to"] # 0x2a27 (en: 'plus sign with subscript two', MathPlayer: 'plustecken med index två', google: 'plus skylt med prenumeration två') + - "⨨": [T: "pluss med fylt trekant"] # 0x2a28 (en: 'plus sign with black triangle', google: 'plus skylt med svart triangel') + - "⨩": [T: "minus med komma over"] # 0x2a29 (en: 'minus sign with comma above', MathPlayer: 'minustecken med komma över', google: 'minus tecken med komma ovan') + - "⨪": [T: "minus med prikk under"] # 0x2a2a (en: 'minus sign with dot below', MathPlayer: 'minustecken med punkt under', google: 'minus tecken med prick nedan') + - "⨫": [T: "minus med fallende prikker"] # 0x2a2b (en: 'minus sign with falling dots', google: 'minus tecken med fallande prickar') + - "⨬": [T: "minus med stigende prikker"] # 0x2a2c (en: 'minus sign with rising dots', google: 'minus tecken med stigande prickar') + - "⨭": [T: "pluss i venstre halvsirkel"] # 0x2a2d (en: 'plus sign in left half circle', MathPlayer: 'plustecken i vänster halvcirkel', google: 'plus logga in vänster halva cirkeln') + - "⨮": [T: "pluss i høyre halvsirkel"] # 0x2a2e (en: 'plus sign in right half circle', MathPlayer: 'plustecken i höger halvcirkel', google: 'plus logga in höger halv cirkel') + - "⨯": [T: "kryssprodukt"] # 0x2a2f (en: 'cross product') + - "⨰": [T: "multiplikasjon med prikk over"] # 0x2a30 (en: 'multiplication sign with dot above') + - "⨱": [T: "multiplikasjon med strek under"] # 0x2a31 (en: 'multiplication sign with underbar') + - "⨲": [T: "semi-direkte produkt med lukket bunn"] # 0x2a32 (en: 'semidirect product with bottom closed', google: 'semidirect -produkt med botten stängd') + - "⨳": [T: "smash-produkt"] # 0x2a33 (en: 'smash product', MathPlayer: 'smash product', google: 'krossa produkten') + - "⨴": [T: "multiplikasjon i venstre halvsirkel"] # 0x2a34 (en: 'multiplication sign in left half circle') + - "⨵": [T: "multiplikasjon i høyre halvsirkel"] # 0x2a35 (en: 'multiplication sign in right half circle') + - "⨶": [T: "multiplikasjon i sirkel med cirkumfleks"] # 0x2a36 (en: 'circled multiplication sign with circumflex accent') + - "⨷": [T: "multiplikasjon i dobbel sirkel"] # 0x2a37 (en: 'multiplication sign in double circle') + - "⨸": [T: "divisjon i sirkel"] # 0x2a38 + - "⨹": [T: "pluss i trekant"] # 0x2a39 (en: 'plus sign in triangle', MathPlayer: 'plustecken i triangel', google: 'plus inloggning av triangeln') + - "⨺": [T: "minus i trekant"] # 0x2a3a (en: 'minus sign in triangle', MathPlayer: 'minustecken i triangel', google: 'minus logga in triangel') + - "⨻": [T: "multiplikasjon i trekant"] # 0x2a3b (en: 'multiplication sign in triangle') + - "⨼": [T: "interior product"] # 0x2a3c (en: 'interior product', MathPlayer: 'interior product', google: 'interiörprodukt') + - "⨽": [T: "invers interior product"] # 0x2a3d (en: 'righthand interior product', google: 'högra interiörprodukt') + - "⨿": [T: "koprodukt"] # 0x2a3f (en: 'amalgamation or coproduct', MathPlayer: 'amalgamation or coproduct', google: 'amalgamation eller coprodukt') + - "⩀": [T: "snitt med prikk"] # 0x2a40 (en: 'intersection with dot') + - "⩁": [T: "union med minus"] # 0x2a41 (en: 'union with minus sign', google: 'union med minus tecken') + - "⩂": [T: "union med horisontal strek over"] # 0x2a42 (en: 'union with overbar') + - "⩃": [T: "snitt med horisontal strek over"] # 0x2a43 (en: 'intersection with overbar') + - "⩄": [T: "snitt med logisk og"] # 0x2a44 (en: 'intersection with logical and') + - "⩅": [T: "union med logisk eller"] # 0x2a45 (en: 'union with logical or') + - "⩆": [T: "union over snitt"] # 0x2a46 (en: 'union above intersection') + - "⩇": [T: "snitt over union"] # 0x2a47 (en: 'intersection above union') + - "⩈": [T: "union over strek over snitt"] # 0x2a48 (en: 'union above bar above intersection') + - "⩉": [T: "snitt over strek over union"] # 0x2a49 (en: 'intersection above bar above union') + - "⩊": [T: "union ved siden av og sammensatt med union"] # 0x2a4a (en: 'union beside and joined with union') + - "⩋": [T: "snitt ved siden av og sammensatt med snitt"] # 0x2a4b (en: 'intersection beside and joined with intersection') + - "⩌": [T: "lukket union med seriffer"] # 0x2a4c (en: 'closed union with serifs') + - "⩍": [T: "lukket snitt med seriffer"] # 0x2a4d (en: 'closed intersection with serifs') + - "⩎": [T: "dobbelt kvadratisk snitt"] # 0x2a4e (en: 'double square intersection', google: 'korsning av dubbel kvadrat') + - "⩏": [T: "dobbel kvadratisk union"] # 0x2a4f (en: 'double square union', google: 'double square union') + - "⩐": [T: "lukket union med seriffer og smash-produkt"] # 0x2a50 (en: 'closed union with serifs and smash product') + - "⩑": [T: "logisk og med prikk over"] # 0x2a51 (en: 'logical and with dot above', google: 'logisk och med punkt ovan') + - "⩒": [T: "logisk eller med prikk over"] # 0x2a52 (en: 'logical or with dot above', google: 'logisk eller med punkt ovan') + - "⩓": [T: "dobbel logisk og"] # 0x2a53 (en: 'double logical and') + - "⩔": [T: "dobbel logisk eller"] # 0x2a54 (en: 'double logical or') + - "⩕": [T: "to kryssende logiske og"] # 0x2a55 (en: 'two intersecting logical and') + - "⩖": [T: "to kryssende logiske eller"] # 0x2a56 (en: 'two intersecting logical or') + - "⩗": [T: "skrånende eller"] # 0x2a57 (en: 'sloping large or') + - "⩘": [T: "skrånende og"] # 0x2a58 (en: 'sloping large and') + - "⩙": [T: "logisk eller overlapper logisk og"] # 0x2a59 (en: 'logical or overlapping logical and', google: 'logisk eller överlappande logisk och') + - "⩚": [T: "logisk og med vertikal strek"] # 0x2a5a (en: 'logical and with middle stem') + - "⩛": [T: "logisk eller med vertikal strek"] # 0x2a5b (en: 'logical or with middle stem') + - "⩜": [T: "logisk og med horisontal strek"] # 0x2a5c (en: 'logical and with horizontal dash') + - "⩝": [T: "logisk eller med horisontal strek"] # 0x2a5d (en: 'logical or with horizontal dash') + - "⩞": [T: "logisk og med dobbel horisontal strek over"] # 0x2a5e (en: 'logical and with double overbar', google: 'logiskt och med dubbelt överbar') + - "⩟": [T: "logisk og med understrek"] # 0x2a5f (en: 'logical and with underbar') + - "⩠": [T: "logisk og med dobbel understrek"] # 0x2a60 (en: 'logical and with double underbar', google: 'logisk och med dubbel underbar') + - "⩡": [T: "liten v med understrek"] # 0x2a61 (en: 'small vee with underbar', google: 'liten vee med underbar') + - "⩢": [T: "logisk eller med dobbel horisontal strek over"] # 0x2a62 (en: 'logical or with double overbar', google: 'logisk eller med dubbel överbar') + - "⩣": [T: "logisk eller med dobbel understrek"] # 0x2a63 (en: 'logical or with double underbar', google: 'logisk eller med dubbel underbar') + - "⩤": [T: "definisjonsmengde antibegrensning z-notasjon"] # 0x2a64 (en: 'z notation domain antirestriction', google: 'z notation domain antirestriction') + - "⩥": [T: "verdimengde antibegrensning z-notasjon"] # 0x2a65 (en: 'z notation range antirestriction', google: 'z notation range antirestriction') + - "⩦": [T: "lik med prikk under"] # 0x2a66 (en: 'equals sign with dot below') + - "⩧": [T: "prikk over identisk med"] # 0x2a67 (en: 'identical with dot above', google: 'identisk med prick ovan') + - "⩨": [T: "trippel horisontal strek med dobbel vertikal strek"] # 0x2a68 (en: 'triple horizontal bar with double vertical stroke', google: 'trippel horisontell stång med dubbel vertikal stroke') + - "⩩": [T: "trippel horisontal strek med trippel vertikal strek"] # 0x2a69 (en: 'triple horizontal bar with triple vertical stroke', google: 'trippel horisontell stång med trippel vertikal stroke') + - "⩪": [T: "tilde med prikk over"] # 0x2a6a (en: 'tilde operator with dot above') + - "⩫": [T: "tilde med stigende prikker"] # 0x2a6b (en: 'tilde operator with rising dots', google: 'tilde -operatör med stigande prickar') + - "⩬": [T: "asymptotisk lik over tilde"] # 0x2a6c (en: 'similar minus similar', google: 'liknande minus liknande') + - "⩭": [T: "tilnærmet lik med prikk over"] # 0x2a6d (en: 'congruent with dot above') + - "⩮": [T: "lik med asterisk over"] # 0x2a6e (en: 'equals with asterisk', google: 'lika med asterisk') + - "⩯": [T: "tilnærmet lik med cirkumfleks"] # 0x2a6f (en: 'almost equal to with circumflex accent') + - "⩰": [T: "tilnærmet lik eller lik"] # 0x2a70 (en: 'approximately equal to or equal to', google: 'ungefär lika med eller lika med') + - "⩱": [T: "lik over pluss"] # 0x2a71 (en: 'equals sign above plus sign') + - "⩲": [T: "pluss over lik"] # 0x2a72 (en: 'plus sign above equals sign') + - "⩳": [T: "lik over tilde"] # 0x2a73 (en: 'equals sign above tilde operator') + - "⩴": [T: "dobbelt kolon lik"] # 0x2a74 (en: 'double colon equal') + - "⩵": [T: "dobbelt likhetstegn"] # 0x2a75 (en: 'two consecutive equals signs') + - "⩶": [T: "trippelt likhetstegn"] # 0x2a76 (en: 'three consecutive equals signs', google: 'tre på varandra följande tecken') + - "⩷": [T: "lik med to prikker over og to prikker under"] # 0x2a77 (en: 'equals sign with two dots above and two dots below') + - "⩸": [T: "fire prikker over identisk med"] # 0x2a78 (en: 'equivalent with four dots above') + - "⩹": [T: "mindre enn med sirkel i"] # 0x2a79 (en: 'less than with circle inside') + - "⩺": [T: "større enn med sirkel i"] # 0x2a7a (en: 'greater than with circle inside') + - "⩻": [T: "mindre enn med spørsmålstegn over"] # 0x2a7b (en: 'less than with question mark above') + - "⩼": [T: "større enn med spørsmålstegn over"] # 0x2a7c (en: 'greater than with question mark above') + - "⩽": [T: "mindre enn eller lik"] # 0x2a7d (en: 'less than or slanted equal to') + - "⩾": [T: "større enn eller lik"] # 0x2a7e (en: 'greater than or slanted equal to') + - "⩿": [T: "mindre enn eller lik med prikk"] # 0x2a7f (en: 'less than or slanted equal to with dot inside') + - "⪀": [T: "større enn eller lik med prikk"] # 0x2a80 (en: 'greater than or slanted equal to with dot inside') + - "⪁": [T: "mindre enn eller lik med prikk over til venstre"] # 0x2a81 (en: 'less than or slanted equal to with dot above') + - "⪂": [T: "større enn eller lik med prikk over til høyre"] # 0x2a82 (en: 'greater than or slanted equal to with dot above') + - "⪃": [T: "mindre enn eller lik med prikk over til høyre"] # 0x2a83 (en: 'less than or slanted equal to with dot above right') + - "⪄": [T: "større enn eller lik med prikk over til venstre"] # 0x2a84 (en: 'greater than or slanted equal to with dot above left') + - "⪅": [T: "mindre enn eller tilnærmet lik"] # 0x2a85 (en: 'less than or approximate', google: 'mindre än eller ungefärligt') + - "⪆": [T: "større enn eller tilnærmet lik"] # 0x2a86 (en: 'greater than or approximate', google: 'större än eller ungefärligt') + - "⪇": [T: "mindre enn men ikke lik"] # 0x2a87 (en: 'less than and single line not equal to', google: 'mindre än och enstaka linjer inte lika med') + - "⪈": [T: "større enn men ikke lik"] # 0x2a88 (en: 'greater than and single line not equal to', google: 'större än och enstaka linjer inte lika med') + - "⪉": [T: "mindre enn men ikke tilnærmet lik"] # 0x2a89 (en: 'less than and not approximate') + - "⪊": [T: "større enn men ikke tilnærmet lik"] # 0x2a8a (en: 'greater than and not approximate') + - "⪋": [T: "mindre enn over lik over større enn"] # 0x2a8b (en: 'less than above double line equal above greater than', google: 'mindre än över dubbel linje lika över större än') + - "⪌": [T: "større enn over lik over mindre enn"] # 0x2a8c (en: 'greater than above double line equal above less than', google: 'större än över dubbel linje lika över mindre än') + - "⪍": [T: "mindre enn over asymptotisk lik"] # 0x2a8d (en: 'less than above similar or equal') + - "⪎": [T: "større enn over asymptotisk lik"] # 0x2a8e (en: 'greater than above similar or equal') + - "⪏": [T: "mindre enn over tilde over større enn"] # 0x2a8f (en: 'less than above similar above greater than') + - "⪐": [T: "større enn over tilde over mindre enn"] # 0x2a90 (en: 'greater than above similar above less than') + - "⪑": [T: "mindre enn over større enn over lik"] # 0x2a91 (en: 'less than above greater than above double line equal') + - "⪒": [T: "større enn over mindre enn over lik"] # 0x2a92 (en: 'greater than above less than above double line equal') + - "⪓": [T: "mindre enn eller lik over større enn eller lik"] # 0x2a93 (en: 'less than above slanted equal above greater than above slanted equal') + - "⪔": [T: "større enn eller lik over mindre enn eller lik"] # 0x2a94 (en: 'greater than above slanted equal above less than above slanted equal') + - "⪕": [T: "lik eller mindre enn"] # 0x2a95 (en: 'slanted equal to or less than', google: 'lutt lika med eller mindre än') + - "⪖": [T: "lik eller større enn"] # 0x2a96 (en: 'slanted equal to or greater than', google: 'lutt lika med eller större än') + - "⪗": [T: "lik eller mindre enn med prikk"] # 0x2a97 (en: 'slanted equal to or less than with dot inside') + - "⪘": [T: "lik eller større enn med prikk"] # 0x2a98 (en: 'slanted equal to or greater than with dot inside') + - "⪙": [T: "lik eller mindre enn"] # 0x2a99 (en: 'double line equal to or less than', MathPlayer: 'equal (dubbel) over less than', google: 'dubbel linje lika med eller mindre än') + - "⪚": [T: "lik eller større enn"] # 0x2a9a (en: 'double line equal to or greater than') + - "⪛": [T: "lik eller mindre enn"] # 0x2a9b (en: 'double line slanted equal to or less than', google: 'dubbel linje lutad lika med eller mindre än') + - "⪜": [T: "lik eller større enn"] # 0x2a9c (en: 'double line slanted equal to or greater than', google: 'dubbel linje lutad lika med eller större än') + - "⪝": [T: "tilnærmet lik eller mindre enn"] # 0x2a9d (en: 'similar or less than') + - "⪞": [T: "tilnærmet lik eller større enn"] # 0x2a9e (en: 'similar or greater than') + - "⪟": [T: "tilnærmet lik over mindre enn over lik"] # 0x2a9f (en: 'similar above less than above equals sign') + - "⪠": [T: "tilnærmet lik over større enn over lik"] # 0x2aa0 (en: 'similar above greater than above equals sign') + - "⪡": [T: "dobbel mindre enn"] # 0x2aa1 (en: 'double nested less than') + - "⪢": [T: "dobbel større enn"] # 0x2aa2 (en: 'double nested greater than') + - "⪣": [T: "dobbel mindre enn med strek under"] # 0x2aa3 (en: 'double nested less than with underbar', google: 'dubbel kapslad mindre än med underbar') + - "⪤": [T: "større enn overlapper mindre enn"] # 0x2aa4 (en: 'greater than overlapping less than') + - "⪥": [T: "større enn ved siden av mindre enn"] # 0x2aa5 (en: 'greater than beside less than') + - "⪦": [T: "mindre enn lukket av kurve"] # 0x2aa6 (en: 'less than closed by curve') + - "⪧": [T: "større enn lukket av kurve"] # 0x2aa7 (en: 'greater than closed by curve') + - "⪨": [T: "mindre enn lukket av kurve over lik"] # 0x2aa8 (en: 'less than closed by curve above slanted equal') + - "⪩": [T: "større enn lukket av kurve over lik"] # 0x2aa9 (en: 'greater than closed by curve above slanted equal') + - "⪪": [T: "mindre enn"] # 0x2aaa (en: 'smaller than') + - "⪫": [T: "større enn"] # 0x2aab (en: 'larger than') + - "⪬": [T: "mindre enn eller lik"] # 0x2aac (en: 'smaller than or equal to') + - "⪭": [T: "større enn eller lik"] # 0x2aad (en: 'larger than or equal to') + - "⪮": [T: "lik med hump over"] # 0x2aae (en: 'equals sign with bumpy above', MathPlayer: 'difference between (grav accentnt)', google: 'är lika med tecken med ojämn ovan') + - "⪯": [T: "foregår over likhetsstrek"] # 0x2aaf (en: 'precedes above single line equals sign') + - "⪰": [T: "følger over likhetsstrek"] # 0x2ab0 (en: 'succeeds above single line equals sign', google: 'lyckas över enstaka linjen är lika med tecken') + - "⪱": [T: "foregår over utstrøket likhetsstrek"] # 0x2ab1 (en: 'precedes above single line not equal to', google: 'föregår över enstaka linjer som inte är lika med') + - "⪲": [T: "følger over utstrøket likhetsstrek"] # 0x2ab2 (en: 'succeeds above single line not equal to', google: 'lyckas över enstaka linjer som inte är lika med') + - "⪳": [T: "foregår over lik"] # 0x2ab3 (en: 'precedes above equals sign', google: 'föregår över lika tecken') + - "⪴": [T: "følger over lik"] # 0x2ab4 (en: 'succeeds above equals sign', google: 'lyckas över lika tecken') + - "⪵": [T: "foregår over ikke lik"] # 0x2ab5 (en: 'precedes above not equal to') + - "⪶": [T: "følger over ikke lik"] # 0x2ab6 (en: 'succeeds above not equal to') + - "⪷": [T: "foregår over tilnærmet lik"] # 0x2ab7 (en: 'precedes above almost equal to', google: 'föregår över nästan lika med') + - "⪸": [T: "følger over tilnærmet lik"] # 0x2ab8 (en: 'succeeds above almost equal to', google: 'lyckas över nästan lika med') + - "⪹": [T: "foregår over ikke tilnærmet lik"] # 0x2ab9 (en: 'precedes above not almost equal to', google: 'föregår ovan inte nästan lika med') + - "⪺": [T: "følger over ikke tilnærmet lik"] # 0x2aba (en: 'succeeds above not almost equal to', google: 'lyckas ovan inte nästan lika med') + - "⪻": [T: "dobbel foregår"] # 0x2abb (en: 'double precedes') + - "⪼": [T: "dobbel følger"] # 0x2abc (en: 'double succeeds') + - "⪽": [T: "delmengde med prikk"] # 0x2abd (en: 'subset with dot') + - "⪾": [T: "overmengde med prikk"] # 0x2abe (en: 'superset with dot') + - "⪿": [T: "delmengde med pluss under"] # 0x2abf (en: 'subset with plus sign below', MathPlayer: 'delmängd med plustecken under', google: 'delmängd med plus -skylt nedan') + - "⫀": [T: "overmengde med pluss under"] # 0x2ac0 (en: 'superset with plus sign below', MathPlayer: 'delmängd med plustecken under', google: 'superset med plus -skylt nedan') + - "⫁": [T: "delmengde med multiplikasjon under"] # 0x2ac1 (en: 'subset with multiplication sign below') + - "⫂": [T: "overmengde med multiplikasjon under"] # 0x2ac2 (en: 'superset with multiplication sign below') + - "⫃": [T: "delmengde av eller lik med prikk over"] # 0x2ac3 (en: 'subset of or equal to with dot above') + - "⫄": [T: "overmengde av eller lik med prikk over"] # 0x2ac4 (en: 'superset of or equal to with dot above') + - "⫅": [T: "delmenge av over lik"] # 0x2ac5 (en: 'subset of above equals sign', google: 'undergruppen ovan är lika med tecken') + - "⫆": [T: "overmengde av over lik"] # 0x2ac6 (en: 'superset of above equals sign', google: 'superset av ovan är lika med tecken') + - "⫇": [T: "delmengde av over tilde"] # 0x2ac7 (en: 'subset of above tilde operator') + - "⫈": [T: "overmengde av over tilde"] # 0x2ac8 (en: 'superset of above tilde operator') + - "⫉": [T: "delmengde av over tilnærmet lik"] # 0x2ac9 (en: 'subset of above almost equal to', google: 'delmängd över nästan lika med') + - "⫊": [T: "overmengde av over tilnærmet lik"] # 0x2aca (en: 'superset of above almost equal to', google: 'superset över nästan lika med') + - "⫋": [T: "delmengde av over ikke lik"] # 0x2acb (en: 'subset above not equal to', google: 'delmängd ovan inte lika med') + - "⫌": [T: "overmengde av over ikke lik"] # 0x2acc (en: 'superset of above not equal to', google: 'superset av ovan inte lika med') + - "⫍": [T: "venstre kvadratisk åpen boks"] # 0x2acd (en: 'square left open box operator', google: 'square left open box operator') + - "⫎": [T: "høyre kvadratisk åpen boks"] # 0x2ace (en: 'square right open box operator', google: 'square right open box operator') + - "⫏": [T: "lukket delmengde"] # 0x2acf (en: 'closed subset') + - "⫐": [T: "lukket overmengde"] # 0x2ad0 (en: 'closed superset') + - "⫑": [T: "lukket delmengde eller lik"] # 0x2ad1 (en: 'closed subset or equal to') + - "⫒": [T: "lukket overmengde eller lik"] # 0x2ad2 (en: 'closed superset or equal to') + - "⫓": [T: "delmengde over overmengde"] # 0x2ad3 (en: 'subset above superset') + - "⫔": [T: "overmengde over delmengde"] # 0x2ad4 (en: 'superset above subset') + - "⫕": [T: "delmengde over delmengde"] # 0x2ad5 (en: 'subset above subset') + - "⫖": [T: "overmengde over overmengde"] # 0x2ad6 (en: 'superset above superset') + - "⫗": [T: "overmengde ved siden av delmengde"] # 0x2ad7 (en: 'superset beside subset') + - "⫘": [T: "overmengde ved siden av og sammenføyd med delmengde"] # 0x2ad8 (en: 'superset beside and joined by dash with subset') + - "⫙": [T: "tilhører med åpning nedover"] # 0x2ad9 (en: 'element of opening downwards') + - "⫚": [T: "høygaffel med t øverst"] # 0x2ada (en: 'pitchfork with tee top') + - "⫛": [T: "tverrgående snitt"] # 0x2adb (en: 'transversal intersection') + - "⫝̸": [T: "avhengig"] # 0x2adc (en: 'forking', google: 'gaffel') + - "⫝": [T: "uavhengig"] # 0x2add (en: 'nonforking', google: 'icke -förflyttning') + - "⫞": [T: "kort venstre dreiekors"] # 0x2ade (en: 'short left tack', google: 'kort vänster tack') + - "⫟": [T: "kort nedoverrotert dreiekors"] # 0x2adf (en: 'short down tack', google: 'kort ner') + - "⫠": [T: "kort oppoverrotert dreiekors"] # 0x2ae0 (en: 'short up tack', google: 'kort upp tack') + - "⫡": [T: "vinkelrett med s"] # 0x2ae1 (en: 'perpendicular with s', google: 'vinkelrätt med s') + - "⫢": [T: "vertikal strek trippelt høyre dreiekors"] # 0x2ae2 (en: 'vertical bar triple right turnstile', google: 'vertikal bar trippel höger turnstile') + - "⫣": [T: "dobbel vertikal strek venstre dreiekors"] # 0x2ae3 (en: 'double vertical bar left turnstile', google: 'dubbel vertikal stång vänster turnstile') + - "⫤": [T: "vertikal strek dobbelt venstre dreiekors"] # 0x2ae4 (en: 'vertical bar double left turnstile') + - "⫥": [T: "dobbel vertikal strek dobbelt venstre dreiekors"] # 0x2ae5 (en: 'double vertical bar double left turnstile', google: 'dubbel vertikal stång dubbel vänster vridstil') + - "⫦": [T: "dreiekors med vertikal strek"] # 0x2ae6 (en: 'long dash from left member of double vertical') + - "⫧": [T: "nedoverrotert kort dreiekors med horisontal strek over"] # 0x2ae7 (en: 'short down tack with overbar') + - "⫨": [T: "oppoverrotert kort dreiekors med horisontal strek under"] # 0x2ae8 (en: 'short up tack with underbar') + - "⫩": [T: "oppoverrotert kort dreiekors over nedoverrotert kort dreiekors"] # 0x2ae9 (en: 'short up tack above short down tack') + - "⫪": [T: "nedoverrotert dobbelt dreiekors"] # 0x2aea (en: 'double down tack', google: 'dubbel down tack') + - "⫫": [T: "oppoverrotert dobbelt dreiekors"] # 0x2aeb (en: 'double up tack') + - "⫬": [T: "dobbeltstreket ikke"] # 0x2aec (en: 'double stroke not sign') + - "⫭": [T: "omvendt dobbeltstreket ikke"] # 0x2aed (en: 'reversed double stroke not sign') + - "⫮": [T: "deler ikke med omvendt skråstrek"] # 0x2aee (en: 'does not divide with reversed negation slash') + - "⫯": [T: "vertikal strek med sirkel over"] # 0x2aef (en: 'vertical line with circle above') + - "⫰": [T: "vertikal strek med sirkel under"] # 0x2af0 (en: 'vertical line with circle below') + - "⫱": [T: "nedoverrotert dreiekors med sirkel under"] # 0x2af1 (en: 'down tack with circle below') + - "⫲": [T: "parallel med horisontal strek"] # 0x2af2 (en: 'parallel with horizontal stroke') + - "⫳": [T: "parallel med tilde"] # 0x2af3 (en: 'parallel with tilde operator') + - "⫴": [T: "trippel loddrett strek"] # 0x2af4 (en: 'triple vertical bar binary relation', google: 'trippel vertikal bar binär relation') + - "⫵": [T: "trippel loddrett strek med horisontal strek"] # 0x2af5 (en: 'triple vertical bar with horizontal stroke', google: 'trippel vertikal stång med horisontellt slag') + - "⫶": [T: "trippelkolon"] # 0x2af6 (en: 'triple colon operator', google: 'trippel kolonoperatör') + - "⫷": [T: "trippel mindre enn"] # 0x2af7 (en: 'triple nested less than', google: 'trippel kapslade mindre än') + - "⫸": [T: "trippel større enn"] # 0x2af8 (en: 'triple nested greater than', google: 'trippel kapslad större än') + - "⫹": [T: "mindre enn eller lik"] # 0x2af9 (en: 'double line slanted less than or equal to', google: 'dubbel linje lutad mindre än eller lika med') + - "⫺": [T: "større enn eller lik"] # 0x2afa (en: 'double line slanted greater than or equal to', google: 'dubbel linje lutad större än eller lika med') + - "⫻": [T: "trippel skråstrek"] # 0x2afb (en: 'triple solidus binary relation', google: 'trippel solidus binär relation') + - "⫼": [T: "stor trippel vertikal strek"] # 0x2afc (en: 'large triple vertical bar operator', google: 'stor trippel vertikal stångoperatör') + - "⫽": [T: "dobbel skråstrek"] # 0x2afd (en: 'double solidus operator', google: 'dubbel solidus -operatör') + - "⫾": [T: "hvit loddrett strek"] # 0x2afe (en: 'white vertical bar', google: 'vit vertikal stång') + - "⫿": [T: "hvit loddrett strek"] # 0x2aff (en: 'white vertical bar', google: 'vit vertikal stång') + #-------------------------------------------------------------------------------------------------------------- + # Miscellaneous symbols and arrows OK + - "⬀": [T: "hvit nordøst-pil"] # 0x2b00 (en: 'north east white arrow', google: 'north east white arrow') + - "⬁": [T: "hvit nordvest-pil"] # 0x2b01 (en: 'north west white arrow', google: 'north west white arrow') + - "⬂": [T: "hvit sørøst-pil"] # 0x2b02 (en: 'south east white arrow', google: 'south east white arrow') + - "⬃": [T: "hvit sørvest-pil"] # 0x2b03 (en: 'south west white arrow', google: 'south west white arrow') + - "⬄": [T: "hvit venstre-høyre-pil"] # 0x2b04 (en: 'left right white arrow', google: 'vänster höger vit pil') + - "⬅": [T: "fylt venstrepil"] # 0x2b05 (en: 'leftwards black arrow', google: 'vänster svart pil') + - "⬆": [T: "fylt oppoverpil"] # 0x2b06 (en: 'upwards black arrow', google: 'uppåt svart pil') + - "⬇": [T: "fylt nedoverpil"] # 0x2b07 (en: 'downwards black arrow', google: 'nedåt svart pil') + - "⬈": [T: "fylt nordøst-pil"] # 0x2b08 (en: 'north east black arrow', google: 'north east black arrow') + - "⬉": [T: "fylt nordvest-pil"] # 0x2b09 (en: 'north west black arrow', google: 'north west black arrow') + - "⬊": [T: "fylt sørøst-pil"] # 0x2b0a (en: 'south east black arrow', google: 'south east black arrow') + - "⬋": [T: "fylt sørvest-pil"] # 0x2b0b (en: 'south west black arrow', google: 'south west black arrow') + - "⬌": [T: "fylt venstre-høyre-pil"] # 0x2b0c (en: 'left right black arrow', google: 'vänster höger svart pil') + - "⬍": [T: "fylt opp-ned-pil"] # 0x2b0d (en: 'up down black arrow', google: 'upp ner black arrow') + - "⬎": [T: "høyrepil med spiss ned"] # 0x2b0e (en: 'rightwards arrow with tip downwards', google: 'åtgärdspil med spets nedåt') + - "⬏": [T: "høyrepil med spiss opp"] # 0x2b0f (en: 'rightwards arrow with tip upwards', google: 'åtgärdspil med spetsen uppåt') + - "⬐": [T: "venstrepil med spiss ned"] # 0x2b10 (en: 'leftwards arrow with tip downwards', google: 'vänster pil med spetsen nedåt') + - "⬑": [T: "venstrepil med spiss opp"] # 0x2b11 (en: 'leftwards arrow with tip upwards', google: 'vänster pil med spetsen uppåt') + - "⬒": [T: "kvadrat med øvre halvdel fylt"] # 0x2b12 (en: 'square with top half black', google: 'fyrkantig med topphalva svart') + - "⬓": [T: "kvadrat med nedre halvdel fylt"] # 0x2b13 (en: 'square with bottom half black', google: 'fyrkantig med botten halvsvart') + - "⬔": [T: "kvadrat med øvre høyre diagonal halvfylt"] # 0x2b14 (en: 'square with upper right diagonal half black', google: 'fyrkantig med övre högra diagonala halvsvart') + - "⬕": [T: "kvadrat med nedre venstre diagonal halvfylt"] # 0x2b15 (en: 'square with lower left diagonal half black', google: 'fyrkantig med nedre vänster diagonal halvsvart') + - "⬖": [T: "diamant med venstre halvdel fylt"] # 0x2b16 (en: 'diamond with left half black', google: 'diamant med vänster halvsvart') + - "⬗": [T: "diamant med høyre halvdel fylt"] # 0x2b17 (en: 'diamond with right half black', google: 'diamant med höger halv svart') + - "⬘": [T: "diamant med øvre halvdel fylt"] # 0x2b18 (en: 'diamond with top half black', google: 'diamant med topp halva svart') + - "⬙": [T: "diamant med nedre halvdel fylt"] # 0x2b19 (en: 'diamond with bottom half black', google: 'diamant med botten halvsvart') + - "⬚": [T: "prikket kvadrat"] # 0x2b1a (en: 'box', google: 'låda') + - "⬛": [T: "stort svart kvadrat"] # 0x2b1b (en: 'black large square', google: 'svart stort fyrkant') + - "⬜": [T: "stort hvitt kvadrat"] # 0x2b1c (en: 'white large square', google: 'vit stor fyrkant') + - "⬝": [T: "veldig lite svart kvadrat"] # 0x2b1d (en: 'black very small square', google: 'svart mycket litet fyrkant') + - "⬞": [T: "veldig lite hvitt kvadrat"] # 0x2b1e (en: 'white very small square', google: 'vit mycket liten fyrkant') + - "⬟": [T: "svart femkant"] # 0x2b1f (en: 'black pentagon', google: 'svart pentagon') + - "⬠": [T: "hvit femkant"] # 0x2b20 (en: 'white pentagon', google: 'vit pentagon') + - "⬡": [T: "hvit sekskant"] # 0x2b21 (en: 'white hexagon', google: 'vit hexagon') + - "⬢": [T: "svart sekskant"] # 0x2b22 (en: 'black hexagon', google: 'svart hexagon') + - "⬣": [T: "horisontal svart sekskant"] # 0x2b23 (en: 'horizontal black hexagon', google: 'horisontell svart hexagon') + - "⬤": [T: "stor svart sirkel"] # 0x2b24 (en: 'black large circle', google: 'svart stor cirkel') + - "⬥": [T: "svart diamant"] # 0x2b25 (en: 'black medium diamond', google: 'svart medium diamant') + - "⬦": [T: "hvit diamant"] # 0x2b26 (en: 'white medium diamond', google: 'vit medium diamant') + - "⬧": [T: "svart rombe"] # 0x2b27 (en: 'black medium lozenge', google: 'svart medium pastill') + - "⬨": [T: "hvit rombe"] # 0x2b28 (en: 'white medium lozenge', google: 'vit medium pastill') + - "⬩": [T: "liten svart diamant"] # 0x2b29 (en: 'black small diamond') + - "⬪": [T: "liten svart rombe"] # 0x2b2a (en: 'black small lozenge', google: 'svart liten pastill') + - "⬫": [T: "liten hvit rombe"] # 0x2b2b (en: 'white small lozenge', google: 'vit liten pastill') + - "⬬": [T: "svart horisontal ellipse"] # 0x2b2c (en: 'black horizontal ellipse') + - "⬭": [T: "hvit horisontal ellipse"] # 0x2b2d (en: 'white horizontal ellipse') + - "⬮": [T: "svart vertikal ellipse"] # 0x2b2e (en: 'black vertical ellipse', google: 'svart vertikalt ellips') + - "⬯": [T: "hvit vertikal ellipse"] # 0x2b2f (en: 'white vertical ellipse') + - "⬰": [T: "venstrepil med liten sirkel"] # 0x2b30 (en: 'left arrow with small circle', google: 'vänster pil med liten cirkel') + - "⬱": [T: "tre venstrepiler"] # 0x2b31 (en: 'three leftwards arrows') + - "⬲": [T: "venstrepil med pluss i sirkel"] # 0x2b32 (en: 'left arrow with circled plus', google: 'vänster pil med circled plus') + - "⬳": [T: "lang sikksakk venstrepil"] # 0x2b33 (en: 'long leftwards squiggle arrow', google: 'långt vänster squiggle pil') + - "⬴": [T: "venstrepil med dobbel spiss og vertikal strek"] # 0x2b34 (en: 'leftwards two headed arrow with vertical stroke', google: 'vänster två ledde pil med vertikalt slag') + - "⬵": [T: "venstrepil med dobbel spiss og dobbel vertikal strek"] # 0x2b35 (en: 'leftwards two headed arrow with double vertical stroke', google: 'vänster två ledde pil med dubbel vertikal stroke') + - "⬶": [T: "venstrepil med dobbel spiss fra strek"] # 0x2b36 (en: 'leftwards two headed arrow from bar', google: 'vänster två ledde pil från bar') + - "⬷": [T: "stiplet venstrepil med dobbel spiss"] # 0x2b37 (en: 'leftwards two headed triple dash arrow', google: 'vänster två ledde trippelstreckpil') + - "⬸": [T: "stiplet venstrepil"] # 0x2b38 (en: 'leftwards arrow with dotted stem', google: 'vänster pil med prickad stam') + - "⬹": [T: "venstrepil med vertikal strek og hale"] # 0x2b39 (en: 'leftwards arrow with tail with vertical stroke', google: 'vänster pil med svans med vertikalt slag') + - "⬺": [T: "venstrepil med hale og dobbel vertikal strek"] # 0x2b3a (en: 'leftwards arrow with tail with double vertical stroke', google: 'vänster pil med svans med dubbel vertikal stroke') + - "⬻": [T: "venstrepil med dobbel spiss og hale"] # 0x2b3b (en: 'leftwards two headed arrow with tail', google: 'vänster två ledde pil med svans') + - "⬼": [T: "venstrepil med dobbel spiss, hale og vertikal strek"] # 0x2b3c (en: 'leftwards two headed arrow with tail with vertical stroke', google: 'vänster två ledde pilen med svans med vertikal stroke') + - "⬽": [T: "venstrepil med dobbel spiss, hale og dobbel vertikal strek"] # 0x2b3d (en: 'leftwards two headed arrow with tail with double vertical stroke', google: 'vänster två ledde pilen med svans med dubbel vertikal stroke') + - "⬾": [T: "venstrepil gjennom x"] # 0x2b3e (en: 'leftwards arrow through x', google: 'vänster pil genom x') + - "⬿": [T: "bølget venstrepil"] # 0x2b3f (en: 'wave arrow pointing directly left', google: 'wave arrow pekade direkt kvar') + - "⭀": [T: "venstrepil med likhetstegn"] # 0x2b40 (en: 'equals sign above leftwards arrow', google: 'är lika med skylt över vänster pil') + - "⭁": [T: "venstrepil med speilvendt tilde"] # 0x2b41 (en: 'reverse tilde operator above leftwards arrow', google: 'omvänd tilde -operatör över vänster pil') + - "⭂": [T: "venstrepil over speilvendt omtrent lik"] # 0x2b42 (en: 'leftwards arrow above reverse almost equal to', google: 'vänster pil över omvänd nästan lika med') + - "⭃": [T: "høyrepil gjennom større enn"] # 0x2b43 (en: 'rightwards arrow through greater than', google: 'åtgärdspil genom större än') + - "⭄": [T: "høyrepil gjennom overmengde"] # 0x2b44 (en: 'rightwards arrow through superset', google: 'åtgärdspil genom superset') + - "⭅": [T: "kvadrupel-streket venstrepil"] # 0x2b45 (en: 'leftwards quadruple arrow', google: 'vänster fyrdubbla pil') + - "⭆": [T: "kvadrupel-streket høyrepil"] # 0x2b46 (en: 'rightwards quadruple arrow', google: 'åtgärd med höger fyrdubbla') + - "⭇": [T: "høyrepil med speilvendt tilde"] # 0x2b47 (en: 'reverse tilde operator above rightwards arrow', google: 'omvänd tilde -operatör ovanför höger-pilen') + - "⭈": [T: "høyrepil over speilvendt omtrent lik"] # 0x2b48 (en: 'rightwards arrow above reverse almost equal to', google: 'åtgärdspilen över omvänd nästan lika med') + - "⭉": [T: "venstrepil med tilde"] # 0x2b49 (en: 'tilde operator above leftwards arrow', google: 'tilde -operatören ovanför vänster pil') + - "⭊": [T: "venstrepil over omtrent lik"] # 0x2b4a (en: 'leftwards arrow above almost equal to', google: 'vänster pil över nästan lika med') + - "⭋": [T: "venstrepil over speilvendt tilde"] # 0x2b4b (en: 'leftwards arrow above reverse tilde operator', google: 'vänster pil ovanför omvänd tilde -operatör') + - "⭌": [T: "høyrepil over speilvendt tilde"] # 0x2b4c (en: 'rightwards arrow above reverse tilde operator', google: 'åtgärdspil över omvänd tilde -operatör') + - "⭐": [T: "hvit stjerne"] # 0x2b50 (en: 'white medium star') + - "⭑": [T: "liten svart stjerne"] # 0x2b51 (en: 'black small star') + - "⭒": [T: "liten hvit stjerne"] # 0x2b52 (en: 'white small star') + - "⭓": [T: "svart femkant som peker til høyre"] # 0x2b53 (en: 'black right pointing pentagon', google: 'svart höger pekande pentagon') + - "⭔": [T: "hvit femkant som peker til høyre"] # 0x2b54 (en: 'white right pointing pentagon', google: 'vit höger pekande pentagon') + - "⭕": [T: "fet stor sirkel"] # 0x2b55 (en: 'heavy large circle', google: 'tung stor cirkel') + - "⭖": [T: "fet oval med oval i"] # 0x2b56 (en: 'heavy oval with oval inside', google: 'tung oval med oval inuti') + - "⭗": [T: "fet sirkel med sirkel i"] # 0x2b57 (en: 'heavy circle with circle inside', google: 'tung cirkel med cirkel inuti') + - "⭘": [T: "fet sirkel"] # 0x2b58 (en: 'heavy circle', google: 'tung cirkel') + - "⭙": [T: "fet kryss i sirkel"] # 0x2b59 (en: 'heavy circled saltire', google: 'tung cirklad saltire') + #------------------------------------------------------------------------------------------------------------ + # Supplemental punctuation OK + - "⸀": [T: "rett vinkel erstatningsmarkør"] # 0x2e00 (en: 'right angle substitution marker', google translation) + - "⸁": [T: "rett vinkel erstatningsmarkør med prikk"] # 0x2e01 (en: 'right angle dotted substitution marker', google translation) + - "⸂": [T: "venstre erstatningsparentes"] # 0x2e02 (en: 'left substitution bracket', google translation) + - "⸃": [T: "høyre erstatningsparentes"] # 0x2e03 (en: 'right substitution bracket', google translation) + - "⸄": [T: "venstre erstatningsparentes med prikk"] # 0x2e04 (en: 'left dotted substitution bracket', google translation) + - "⸅": [T: "høyre erstatningsparentes med prikk"] # 0x2e05 (en: 'right dotted substitution bracket', google translation) + - "⸆": [T: "hevet interpolasjonsmarkør"] # 0x2e06 (en: 'raised interpolation marker', google translation) + - "⸇": [T: "hevet interpolasjonsmarkør med prikk"] # 0x2e07 (en: 'raised dotted interpolation marker', google translation) + - "⸈": [T: "venstre transposisjonsmarkør med prikk"] # 0x2e08 (en: 'dotted transposition marker marker', google translation) + - "⸉": [T: "venstre transposisjonsparentes"] # 0x2e09 (en: 'left transposition bracket', google translation) + - "⸊": [T: "høyre transposisjonsparentes"] # 0x2e0a (en: 'right transposition bracket', google translation) + - "⸋": [T: "hevet kvadrat"] # 0x2e0b (en: 'raised square', google translation) + - "⸌": [T: "venstre hevet utelatelses-parentes"] # 0x2e0c (en: 'left raised omission bracket', google translation) + - "⸍": [T: "høyre hevet utelatelses-parentes"] # 0x2e0d (en: 'right raised omission bracket', google translation) + - "⸎": [T: "redaksjonell coronis"] # 0x2e0e (en: 'editorial coronis', google translation) + - "⸏": [T: "paragraphos"] # 0x2e0f (google translation) + - "⸐": [T: "forgreinet paragraphos"] # 0x2e10 (en: 'forked paragraphos', google translation) + - "⸑": [T: "speilvendt forgreinet paragraphos"] # 0x2e11 (en: 'reversed forked paragraphos', google translation) + - "⸒": [T: "hypodiastol"] # 0x2e12 (google translation) + - "⸓": [T: "prikket obelus"] # 0x2e13 (en: 'dotted obelos', google translation) + - "⸔": [T: "nedover ancora"] # 0x2e14 (en: 'downwards ancora', google translation) + - "⸕": [T: "oppover ancora"] # 0x2e15 (en: 'upwards ancora', google translation) + - "⸖": [T: "prikket høyrepekende vinkel"] # 0x2e16 (en: 'dotted right pointing angle', google translation) + - "⸗": [T: "dobbel skrå bindestrek"] # 0x2e17 (en: 'double oblique hyphen', google translation) + - "⸘": [T: "omvendt interrobang"] # 0x2e18 (en: 'inverted interrobang', google translation) + - "⸙": [T: "palmegren"] # 0x2e19 (google translation) + - "⸚": [T: "bindestrek med trema"] # 0x2e1a (en: 'hyphen with diaeresis', google translation) + - "⸛": [T: "tilde med ring"] # 0x2e1b (en: 'tilde with ring above', google translation) + - "⸜": [T: "lav venstre parafraseparentes"] # 0x2e1c (en: 'left low paraphrase bracket', google translation) + - "⸝": [T: "lav høyre parafraseparentes"] # 0x2e1d (en: 'right low paraphrase bracket', google translation) + - "⸞": [T: "tilde med prikk over"] # 0x2e1e (en: 'tilde with dot above', google translation) + - "⸟": [T: "tilde med prikk under"] # 0x2e1f (en: 'tilde with dot below', google translation) + - "⸠": [T: "vertikal strek med pigg til høyre"] # 0x2e20 (en: 'left vertical bar with quill', google translation) + - "⸡": [T: "vertikal strek med pigg til venstre"] # 0x2e21 (en: 'right vertical bar with quill', google translation) + - "⸢": [T: "øvre venstre halv hakeparentes"] # 0x2e22 (en: 'top left half bracket', google: 'överst till vänster halvfäste') + - "⸣": [T: "øvre høyre halv hakeparentes"] # 0x2e23 (en: 'top right half bracket', google: 'överst till höger halva konsol') + - "⸤": [T: "nedre venstre halv hakeparentes"] # 0x2e24 (en: 'bottom left half bracket', google: 'nedre vänstra halvfästet') + - "⸥": [T: "nedre høyre halv hakeparentes"] # 0x2e25 (en: 'bottom right half bracket', google: 'nedre högra halvfästet') + - "⸦": [T: "venstre u-parentes"] # 0x2e26 (en: 'left sideways u bracket', google: 'vänster i sidled u konsol') + - "⸧": [T: "høyre u-parentes"] # 0x2e27 (en: 'right sideways u bracket', google: 'höger i sidled u konsol') + - "⸨": [T: "dobbel venstreparentes"] # 0x2e28 (en: 'left double parentheses', google: 'vänster dubbla parenteser') + - "⸩": [T: "dobbel høyreparentes"] # 0x2e29 (en: 'right double parentheses', google: 'höger dubbel parentes') + - "⸪": [T: "to prikker over én prikk"] # 0x2e2a (en: 'two dots over one dot punctuation', google translation) + - "⸫": [T: "én prikk over to prikker"] # 0x2e2b (en: 'one dot over two dots punctuation', google translation) + - "⸬": [T: "fire prikker i kvadrat"] # 0x2e2c (en: 'squared four dot punctuation', google translation) + - "⸭": [T: "fem prikker i kryss"] # 0x2e2d (en: 'five dot mark', google translation) + - "⸮": [T: "speilvendt spørsmålstegn"] # 0x2e2e (en: 'reversed question mark', google translation) + - "ⸯ": [T: "vertikal tilde"] # 0x2e2f (en: 'vertical tilde', google translation) + - "⸰": [T: "ringpunkt"] # 0x2e30 (en: 'ring point', google translation) + - "⸱": [T: "ordskille-punkt"] # 0x2e31 (google translation) + - "⸲": [T: "rotert komma"] # 0x2e32 (en: 'turned comma', google translation) + - "⸳": [T: "hevet prikk"] # 0x2e33 (en: 'raised dot', google translation) + - "⸴": [T: "hevet komma"] # 0x2e34 (en: 'raised comma', google translation) + - "⸵": [T: "rotert semikolon"] # 0x2e35 (en: 'turned semicolon', google translation) + - "⸶": [T: "dolk med venstre vaktstang"] # 0x2e36 (en: 'dagger with left guard', google translation) + - "⸷": [T: "dolk med høyre vaktstang"] # 0x2e37 (en: 'dagger with right guard', google translation) + - "⸸": [T: "rotert dolk"] # 0x2e38 (en: 'turned dagger', google translation) + - "⸹": [T: "øvre halvt avsnittssymbol"] # 0x2e39 (en: 'top half section sign', google translation) + - "⸺": [T: "dobbel tankestrek"] # 0x2e3a (en: 'two em dash', google translation) + - "⸻": [T: "trippel tankestrek"] # 0x2e3b (en: 'three em dash', google translation) + #------------------------------------------------------------------------------------------------------------------- + # CJK symbols and punctuation OK + - "〃": [T: "gjentategn"] # 0x3003 (google translation) + - "〈": [T: "venstre vinkelparentes"] # 0x3008 (en: 'left angle bracket', google: 'vänster vinkelfäste') + - "〉": [T: "høyre vinkelparentes"] # 0x3009 (en: 'right angle bracket', google: 'rätt vinkelfäste') + - "《": [T: "dobbel venstre vinkelparentes"] # 0x300a (en: 'left double angle bracket') + - "》": [T: "dobbel høyre vinkelparentes"] # 0x300b (en: 'right double angle bracket') + - "「": [T: "venstre hjørneparentes"] # 0x300c (en: 'left corner bracket', google: 'vänster hörnfäste') + - "」": [T: "høyre hjørneparentes"] # 0x300d (en: 'right corner bracket', google: 'höger hörnfäste') + - "『": [T: "venstre hvit hjørneparentes"] # 0x300e (en: 'left white corner bracket', google: 'vänster vit hörnfäste') + - "』": [T: "høyre hvit hjørneparentes"] # 0x300f (en: 'right white corner bracket', google: 'höger vit hörnfäste') + - "【": [T: "venstre svart linseformet hakeparentes"] # 0x3010 (en: 'left black lenticular bracket', google: 'vänster svart linsformell konsol') + - "】": [T: "høyre svart linseformet hakeparentes"] # 0x3011 (en: 'right black lenticular bracket', google: 'höger svart linsformell konsol') + - "〔": [T: "venstre skilpaddeskall-parentes"] # 0x3014 (en: 'left tortoise shell bracket') + - "〕": [T: "høyre skilpaddeskall-parentes"] # 0x3015 (en: 'right tortoise shell bracket') + - "〖": [T: "venstre hvit linseformet hakeparentes"] # 0x3016 (en: 'left white lenticular bracket', google: 'vänster vit linsformad konsol') + - "〗": [T: "høyre hvit linseformet hakeparentes"] # 0x3017 (en: 'right white lenticular bracket', google: 'höger vit linsformad konsol') + - "〘": [T: "venstre hvit skilpaddeskall-parentes"] # 0x3018 (en: 'left white tortoise shell bracket', google: 'vänster vit sköldpaddsskalfäste') + - "〙": [T: "høyre hvit skilpaddeskall-parentes"] # 0x3019 (en: 'right white tortoise shell bracket', google: 'höger vit sköldpaddsskalfäste') + - "〚": [T: "venstre hvit hakeparentes"] # 0x301a (en: 'left white square bracket') + - "〛": [T: "høyre hvit hakeparentes"] # 0x301b (en: 'right white square bracket') + - "〜": [T: "bølgestrek"] # 0x301c (en: 'wave dash', google: 'wave dash') + - "〰": [T: "bølget strek"] # 0x3030 (en: 'wavy dash', google: 'wavy dash') + #---------------------------------------------------------------------------------------------------------------------------------- + # Enclosed CJK letters and months OK + - "㉈": [T: "ti i sirkel på fylt kvadrat"] # 0x3248 (en: 'circled number ten on black square', google: 'cirklat nummer tio på black square') + - "㉉": [T: "tjue i sirkel på fylt kvadrat"] # 0x3249 (en: 'circled number twenty on black square', google: 'cirklat nummer tjugo på black square') + - "㉊": [T: "tretti i sirkel på fylt kvadrat"] # 0x324a (en: 'circled number thirty on black square', google: 'cirklat nummer trettio på black square') + - "㉋": [T: "førti i sirkel på fylt kvadrat"] # 0x324b (en: 'circled number forty on blacks square', google: 'cirklat nummer fyrtio på blacks square') + - "㉌": [T: "femti i sirkel på fylt kvadrat"] # 0x324c (en: 'circled number fifty on black square', google: 'cirklat nummer femtio på black square') + - "㉍": [T: "seksti i sirkel på fylt kvadrat"] # 0x324d (en: 'circled number sixty on black square', google: 'cirklat nummer sextio på black square') + - "㉎": [T: "sytti i sirkel på fylt kvadrat"] # 0x324e (en: 'circled number seventy on black square', google: 'cirklat nummer sjuttio på black square') + - "㉏": [T: "åtti i sirkel på fylt kvadrat"] # 0x324f (en: 'circled number eighty on black square', google: 'cirklat nummer aty på black square') + - "㉑": [T: "tjueen i sirkel"] # 0x3251 (en: 'circled number twenty one', google translation) + - "㉒": [T: "tjueto i sirkel"] # 0x3252 (en: 'circled number twenty two', google translation) + - "㉓": [T: "tjuetre i sirkel"] # 0x3253 (en: 'circled number twenty three', google translation) + - "㉔": [T: "tjuefire i sirkel"] # 0x3254 (en: 'circled number twenty four', google translation) + - "㉕": [T: "tjuefem i sirkel"] # 0x3255 (google translation) + - "㉖": [T: "tjueseks i sirkel"] # 0x3256 (google translation) + - "㉗": [T: "tjuesju i sirkel"] # 0x3257 (en: 'circled number twenty seven', google translation) + - "㉘": [T: "tjueåtte i sirkel"] # 0x3258 (en: 'circled number twenty eight', google translation) + - "㉙": [T: "tjueni i sirkel"] # 0x3259 (en: 'circled number twenty nine', google translation) + - "㉚": [T: "tretti i sirkel"] # 0x325a (en: 'circled number thirty', google translation) + - "㉛": [T: "trettien i sirkel"] # 0x325b (en: 'circled number thirty one', google translation) + - "㉜": [T: "trettito i sirkel"] # 0x325c (en: 'circled number thirty two', google translation) + - "㉝": [T: "trettitre i sirkel"] # 0x325d (google translation) + - "㉞": [T: "trettifire i sirkel"] # 0x325e (en: 'circled number thirty four', google translation) + - "㉟": [T: "trettifem i sirkel"] # 0x325f (en: 'circled number thirty five', google translation) + - "㊱": [T: "trettiseks i sirkel"] # 0x32b1 (en: 'circled number thirty six', google translation) + - "㋌": [T: "kvikksølv"] # 0x32cc (en: 'mercury', google translation) + - "㋍": [T: "erg"] # 0x32cd (google translation) + - "㋎": [T: "elektronvolt"] # 0x32ce (en: 'electron volts', google translation) + - "㋏": [T: "begrenset ansvar"] # 0x32cf (en: 'limited liability sign', google translation) + #----------------------------------------------------------------------------------------------------------------------- + # CJK compatibility OK + - "㍱": [T: "hektopascal"] # 0x3371 (en: 'hectopascals', google translation) + - "㍲": [T: "dalton"] # 0x3372 (google translation) + - "㍳": [T: "astronomisk enhet"] # 0x3373 (en: 'astronomical units', google translation) + - "㍴": [T: "bar"] # 0x3374 (en: 'bars', google translation) + - "㍵": [T: "o v"] # 0x3375 (google translation) + - "㍶": [T: "parsec"] # 0x3376 (google translation) + - "㍷": [T: "desimeter"] # 0x3377 (en: 'decimeters', google translation) + - "㍸": [T: "kvadratdesimeter"] # 0x3378 (en: 'decimeters squared', google translation) + - "㍹": [T: "kubikkdesimeter"] # 0x3379 (en: 'decimeters cubed', google translation) + - "㍺": [T: "kvadratisk I U"] # 0x337a (en: 'instrumental units', google translation) + - "㎀": [T: "piko-ampere"] # 0x3380 (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎁": [T: "nanoampere"] # 0x3381 (google translation) + - "㎂": [T: "mikroampere"] # 0x3382 (google translation) + - "㎃": [T: "milliampere"] # 0x3383 (google translation) + - "㎄": [T: "kiloampere"] # 0x3384 (google translation) + - "㎅": [T: "kilobyte"] # 0x3385 (google translation) + - "㎆": [T: "mega-byte"] # 0x3386 (en: 'megabytes', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎇": [T: "gigabyte"] # 0x3387 (en: 'gigabytes', google translation) + - "㎈": [T: "kalorier"] # 0x3388 (en: 'calories', google translation) + - "㎉": [T: "kilokalorier"] # 0x3389 (en: 'kilocalories', google translation) + - "㎊": [T: "piko-farad"] # 0x338a (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎋": [T: "nano-farad"] # 0x338b (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎌": [T: "mikrofarad"] # 0x338c (google translation) + - "㎍": [T: "mikro-gram"] # 0x338d (en: 'micrograms', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎎": [T: "milligram"] # 0x338e (google translation) + - "㎏": [T: "kilogram"] # 0x338f (en: 'kilograms', google translation) + - "㎐": [T: "hertz"] # 0x3390 (google translation) + - "㎑": [T: "kilohertz"] # 0x3391 (google translation) + - "㎒": [T: "megahertz"] # 0x3392 (google translation) + - "㎓": [T: "gigahertz"] # 0x3393 (google translation) + - "㎔": [T: "tera-hertz"] # 0x3394 (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎕": [T: "mikroliter"] # 0x3395 (google translation) + - "㎖": [T: "milliliter"] # 0x3396 (google translation) + - "㎗": [T: "desiliter"] # 0x3397 (google translation) + - "㎘": [T: "kiloliter"] # 0x3398 (en: 'kiloliters', google translation) + - "㎙": [T: "femto-meter"] # 0x3399 (en: 'femtometers', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎚": [T: "nanometer"] # 0x339a (en: 'nanometers', google translation) + - "㎛": [T: "mikro-meter"] # 0x339b (en: 'micrometers', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎜": [T: "millimeter"] # 0x339c (en: 'millimeters', google translation) + - "㎝": [T: "centimeter"] # 0x339d (en: 'centimeters', google translation) + - "㎞": [T: "kilometer"] # 0x339e (en: 'kilometers', google translation) + - "㎟": [T: "kvadratmillimeter"] # 0x339f (en: 'millimeters squared', google translation) + - "㎠": [T: "kvadratcentimeter"] # 0x33a0 (en: 'centimeters squared', google translation) + - "㎡": [T: "kvadratmeter"] # 0x33a1 (en: 'meters squared', google translation) + - "㎢": [T: "kvadratkilometer"] # 0x33a2 (en: 'kilometers squared', google translation) + - "㎣": [T: "kubikkmillimeter"] # 0x33a3 (en: 'millimeters cubed', google translation) + - "㎤": [T: "kubikkcentimeter"] # 0x33a4 (en: 'centimeters cubed', google translation) + - "㎥": [T: "kubikkmeter"] # 0x33a5 (en: 'meters cubed', google translation) + - "㎦": [T: "kubikk-kilometer"] # 0x33a6 (en: 'kilometers cubed', google translation) + - "㎧": [T: "meter per sekund"] # 0x33a7 (en: 'meters per second', google translation) + - "㎨": [T: "meter per sekund i andre"] # 0x33a8 (en: 'meters per second squared', google translation) + - "㎩": [T: "pascal"] # 0x33a9 (google translation) + - "㎪": [T: "kilopascal"] # 0x33aa (google translation) + - "㎫": [T: "megapascal"] # 0x33ab (google translation) + - "㎬": [T: "giga-pascal"] # 0x33ac (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎭": [T: "radianer"] # 0x33ad (google translation) + - "㎮": [T: "radianer per sekund"] # 0x33ae (en: 'rads per second', google translation) + - "㎯": [T: "radianer per sekund i andre"] # 0x33af (en: 'rads per second squared', google translation) + - "㎰": [T: "piko-sekunder"] # 0x33b0 (en: 'picoseconds', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎱": [T: "nanosekunder"] # 0x33b1 (en: 'nanoseconds', google translation) + - "㎲": [T: "mikrosekunder"] # 0x33b2 (en: 'microseconds', google translation) + - "㎳": [T: "millisekunder"] # 0x33b3 (en: 'milliseconds', google translation) + - "㎴": [T: "piko-volt"] # 0x33b4 (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎵": [T: "nanovolt"] # 0x33b5 (google translation) + - "㎶": [T: "mikrovolt"] # 0x33b6 (google translation) + - "㎷": [T: "millivolt"] # 0x33b7 (google translation) + - "㎸": [T: "kilovolt"] # 0x33b8 (google translation) + - "㎹": [T: "megavolt"] # 0x33b9 (google translation) + - "㎺": [T: "piko-watt"] # 0x33ba (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎻": [T: "nano-watt"] # 0x33bb (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㎼": [T: "mikrowatt"] # 0x33bc (en: 'microwatts', google translation) + - "㎽": [T: "milliwatt"] # 0x33bd (google translation) + - "㎾": [T: "kilowatt"] # 0x33be (google translation) + - "㎿": [T: "mega-watt"] # 0x33bf (google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㏀": [T: "kiloohm"] # 0x33c0 (google translation) + - "㏁": [T: "megaohm"] # 0x33c1 (google translation) + - "㏂": [T: "atto-meter"] # 0x33c2 (en: 'attometers', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㏃": [T: "becquerel"] # 0x33c3 (google translation) + - "㏄": [T: "kubikkcentimeter"] # 0x33c4 (en: 'cubic centimeters', google translation) + - "㏅": [T: "candela"] # 0x33c5 (google translation) + - "㏆": [T: "coulomb per kilogram"] # 0x33c6 (en: 'coulombs per kilogram', google translation) + - "㏇": [T: "kvadratisk C O"] # 0x33c7 (en: 'cardiac output', google translation) + - "㏈": [T: "desibel"] # 0x33c8 (en: 'decibels', google translation) + - "㏉": [T: "gray"] # 0x33c9 (en: 'grays', google translation) + - "㏊": [T: "hektar"] # 0x33ca (en: 'hectares', google translation) + - "㏋": [T: "hestekraft"] # 0x33cb (en: 'horsepower', google translation) + - "㏌": [T: "tomme"] # 0x33cc (en: 'inches', google translation) + - "㏍": [T: "kilokelvin"] # 0x33cd (google translation) + - "㏎": [T: "kilometer"] # 0x33ce (en: 'kilometers', google translation) + - "㏏": [T: "knop"] # 0x33cf (en: 'knots', google translation) + - "㏐": [T: "lumen"] # 0x33d0 (en: 'lumens', google translation) + - "㏑": [T: "den naturlige logaritmen"] # 0x33d1 (en: 'natural log', google translation) + - "㏒": [T: "logaritmen"] # 0x33d2 (en: 'logarithm', google translation) + - "㏓": [T: "lux"] # 0x33d3 (google translation) + - "㏔": [T: "millibarn"] # 0x33d4 (en: 'millibarns', google translation) + - "㏕": [T: "mill"] # 0x33d5 (google translation) + - "㏖": [T: "mol"] # 0x33d6 (en: 'moles', google translation) + - "㏗": [T: "p h"] # 0x33d7 (google translation) + - "㏘": [T: "piko-meter"] # 0x33d8 (en: 'picometers', google translation) #NORWEGIAN: More likely to be pronounced correctly with a hyphen + - "㏙": [T: "milliondeler"] # 0x33d9 (en: 'parts per million', google translation) + - "㏚": [T: "petarøntgen"] # 0x33da (google translation) + - "㏛": [T: "steradianer"] # 0x33db (google translation) + - "㏜": [T: "sievert"] # 0x33dc (google translation) + - "㏝": [T: "weber"] # 0x33dd (google translation) + - "㏞": [T: "volt per meter"] # 0x33de (en: 'volts per meter', google translation) + - "㏟": [T: "ampere per meter"] # 0x33df (google translation) + - "㏿": [T: "gallon"] # 0x33ff (en: 'gallons', google translation) + #---------------------------------------------------------------------------------------------------------- + # Private use area OK + - "": [T: "lik med hatt under"] # 0xe900 (en: 'equals with hat below', google translation) + - "": [T: "lik med pluss over"] # 0xe901 (en: 'equals with plus above', google translation) + - "": [T: "lik med pluss under"] # 0xe902 (en: 'equals with plus below', google translation) + - "": [T: "tilde med pluss over"] # 0xe903 (en: 'tilde with plus above', google translation) + - "": [T: "tilde med pluss under"] # 0xe904 (en: 'tilde with plus below', google translation) + - "": [T: "dobbel lik over større enn"] # 0xe908 (en: 'equal double over greater than', google translation) + - "": [T: "dobbel lik over mindre enn"] # 0xe909 (en: 'equal double over less than', google translation) + - "": [T: "inneholder eller er lik"] # 0xe90a (en: 'contains or equal to', google translation) + - "": [T: "overmengde av eller lik"] # 0xe90b (en: 'superset of or equal to', google translation) + - "": [T: "delmengde av eller lik"] # 0xe90c (en: 'subset of or equal to', google translation) + - "": [T: "lik over mindre enn"] # 0xe90d (en: 'equal over less than', google translation) + - "": [T: "tilhører eller lik"] # 0xe912 (en: 'element of or equal to', google translation) + - "": [T: "lik eller større enn"] # 0xe913 (en: 'equal to or greater than', google translation) + - "": [T: "tilnærmet overmengde av"] # 0xe914 (en: 'approximate superset of', google translation) + - "": [T: "tilnærmet delmengde av"] # 0xe915 (en: 'approximate subset of', google translation) + - "": [T: "overmengde av med prikk inkluderer som underrelasjon"] # 0xe916 (en: 'superset of with dot includes as sub relation', google translation) + - "": [T: "delmengde av med prikk inkluderes i som underrelasjon"] # 0xe917 (en: 'subset of with dot is included in as sub relation', google translation) + - "": [T: "lik med prikk under"] # 0xe918 (en: 'equal with dot below', google translation) + - "": [T: "venstre prikk over minus over høyre prikk"] # 0xe919 (en: 'left dot over minus over right dot', google translation) + - "": [T: "høyre prikk over minus over venstre prikk"] # 0xe91a (en: 'right dot over minus over left dot', google translation) + - "": [T: "nesten lik minus"] # 0xe91f (en: 'almost equal to minus', google translation) + - "": [T: "dobbel kvadratisk union"] # 0xe920 (en: 'double square cup', google translation) + - "": [T: "dobbelt kvadratisk snitt"] # 0xe921 (en: 'double square cap', google translation) + - "": [T: "mindre enn lik eller større enn"] # 0xe922 (en: 'less than equal to or greater than', google translation) + - "": [T: "tilde med prikk"] # 0xe924 (en: 'tilde with dot', google translation) + - "": [T: "tilde med to prikker"] # 0xe925 (en: 'tilde with two dots', google translation) + - "": [T: "mindre enn større enn eller lik"] #0xe926 (en: 'less than greater than or equal to', google translation) + - "": [T: "større enn mindre enn eller lik"] # 0xe927 (en: 'greater than less than or equal to', google translation) + - "": [T: "ekvivalent med eller mindre enn"] # 0xe928 (en: 'equivalent to or less than', google translation) + - "": [T: "ekvivalent med eller større enn"] # 0xe929 (en: 'equivalent to or greater than', google translation) + - "": [T: "venstre åpen boks"] # 0xe92a (en: 'left open box operator', google translation) + - "": [T: "høyre åpen boks"] # 0xe92b (en: 'right open box operator', google translation) + - "": [T: "identisk med med prikk"] # 0xe92c (en: 'identical to with dot', google translation) + - "": [T: "større enn lik eller mindre enn"] # 0xe92d (en: 'greater than equal to or less than', google translation) + - "": [T: "bar"] # 0xe92e (en: 'bar operator', google translation) + - "": [T: "dobbel bar"] # 0xe92f (en: 'double bar operator', google translation) + - "": [T: "trippel bar"] # 0xe930 (google translation) + - "": [T: "mindre enn eller tilnærmet lik"] # 0xe932 (en: 'less than or approximately equal to', google translation) + - "": [T: "større enn eller tilnærmet lik"] # 0xe933 (en: 'greater than or approximately equal to', google translation) + - "": [T: "nøstet mindre enn"] # 0xe936 (en: 'nested less than', google translation) + - "": [T: "nøstet større enn"] # 0xe937 (en: 'nested greater than', google translation) + - "": [T: "foregår eller ekvivalent med"] # 0xe93a (en: 'precedes or equivalent to', google translation) + - "": [T: "følger eller ekvivalent med"] # 0xe93b (en: 'succeeds or equivalent to', google translation) + - "": [T: "foregår over lik"] # 0xe940 (en: 'precedes over equal', google translation) + - "": [T: "følger over lik"] # 0xe941 (en: 'succeeds over equal', google translation) + - "": [T: "mindre enn eller lik"] # 0xe942 (en: 'less equal slanted greater', google translation) + - "": [T: "større enn eller lik"] # 0xe943 (en: 'greater equal slanted less', google translation) + - "": [T: "oppfylles av"] # 0xe948 (en: 'satisfied by', google translation) + - "": [T: "langstrakt s"] # 0xe949 (en: 'lazy s', google translation) + - "": [T: "ikke påstand"] # 0xe94a (en: 'not assertion', google translation) + - "": [T: "dobbel lik"] # 0xe94b (en: 'double equal', google translation) + - "": [T: "trippel lik"] # 0xe94c (en: 'triple equal', google translation) + - "": [T: "regel forsinket"] # 0xe94d (en: 'rule delayed', google translation) + - "": [T: "alias skilletegn"] # 0xe94e (en: 'alias delimiter', google translation) + - "": [T: "normal undergruppe av med strek"] # 0xe950 (en: 'normal subgroup of with bar', google translation) + - "": [T: "inneholder som normal undergruppe med strek"] # 0xe951 (en: 'contains as normal subgroup with bar', google translation) + - "": [T: "rund impliserer"] # 0xe954 (en: 'round implies', google translation) + - "": [T: "smil under strek"] # 0xe955 (en: 'smile under bar', google translation) + - "": [T: "rynke over strek"] # 0xe956 (en: 'frown over bar', google translation) + - "": [T: "overmengde av eller tilnærmet lik"] # 0xe957 (en: 'superset of or almost equal to', google translation) + - "": [T: "delmengde av eller tilnærmet lik"] # 0xe958 (en: 'subset of or almost equal to', google translation) + - "": [T: "større enn tilnærmet lik eller mindre enn"] # 0xe959 (en: 'greater than almost equal to or less than', google translation) + - "": [T: "mindre enn tilnærmet lik eller større enn"] # 0xe95a (en: 'less than almost equal or greater than', google translation) + - "": [T: "dobbel logisk eller"] # 0xe95c (en: 'double logical or', google translation) + - "": [T: "dobbel logisk og"] # 0xe95d (en: 'double logical and', google translation) + - "": [T: "logisk eller med dobbel strek under"] # 0xe95e (en: 'logical or with double bar below', google translation) + - "": [T: "logisk eller med strek under"] # 0xe95f (en: 'logical or with bar below', google translation) + - "": [T: "tilnærmet lik"] # 0xe962 (en: 'almost equal over equal', google translation) + - "": [T: "venstre trekant med midtstrek"] # 0xe964 (en: 'left pointing triangle with bisecting bar', google translation) + - "": [T: "høyre trekant med midtstrek"] # 0xe965 (en: 'right pointing triangle with bisecting bar', google translation) + - "": [T: "lik med prikket øvre linje"] # 0xe966 (en: 'equals with dotted top line', google translation) + - "": [T: "foregår med kolon"] # 0xe967 (en: 'precedes with colon', google translation) + - "": [T: "følger med kolon"] # 0xe968 (en: 'succeeds with colon', google translation) + - "": [T: "mindre enn eller lik"] # 0xe969 (en: 'smaller than or equal slanted', google translation) + - "": [T: "større enn eller lik"] # 0xe96a (en: 'larger than or equal slanted', google translation) + - "": [T: "nøstet veldig mye mindre enn"] # 0xe96b (en: 'nested very much less than', google translation) + - "": [T: "nøstet veldig mye større enn"] # 0xe96c (en: 'nested very much greater than', google translation) + - "": [T: "forskjell mellom"] # 0xe96d (en: 'difference between variant', google translation) + - "": [T: "mindre enn som overlapper med større enn"] # 0xe96e (en: 'less than greater than overlay', google translation) + - "": [T: "logisk eller som overlapper med logisk og"] # 0xe96f (en: 'logical or logical and overlay', google translation) + - "": [T: "overmengde over overmengde"] # 0xe970 (google translation) + - "": [T: "delmengde over delmengde"] # 0xe971 (en: 'subset over subset', google translation) + - "": [T: "overmengde over delmengde"] # 0xe972 (en: 'superset over subset', google translation) + - "": [T: "delmengde over overmengde"] # 0xe973 (en: 'subset over superset', google translation) + - "": [T: "trippel vertikal strek"] # 0xe979 (google translation) + - "": [T: "parvise firedoble vertikale prikker"] # 0xe97a (en: 'paired quadruple vertical dots', google translation) + - "": [T: "vinkelrett over strek"] # 0xe97b (en: 'perpendicular over bar', google translation) + - "": [T: "venstre dreiekors dobbel vertikal strek"] # 0xe97c (en: 'left turnstile double vertical bar', google translation) + - "": [T: "dobbelt venstre dreiekors dobbel vertikal strek"] # 0xe97d (en: 'double left turnstile double vertical bar', google translation) + - "": [T: "vinkelrett over rotert vinkelrett"] # 0xe97e (en: 'perpendicular over inverted perpendicular', google translation) + - "": [T: "dobbelt venstre dreiekors vertikal strek"] # 0xe97f (en: 'double left turnstile vertical bar', google translation) + - "": [T: "sfærisk vinkel oppover"] # 0xe980 (en: 'spherical angle opening up', google translation) + - "": [T: "dobbel skråstrek"] # 0xe981 (en: 'double slash', google translation) + - "": [T: "rett vinkel med hjørne"] # 0xe982 (en: 'right angle with corner', google translation) + - "": [T: "sirkel med vertikal strek"] # 0xe984 (google translation) + - "": [T: "sirkel med divisjon"] # 0xe985 (google translation) + - "": [T: "stiplet skråstrek"] # 0xe986 (en: 'dashed solidus', google translation) + - "": [T: "stiplet omvendt skråstrek"] # 0xe987 (en: 'dashed backslash', google translation) + - "": [T: "stiplet midtlinje"] # 0xe988 (en: 'dashed mid line', google translation) + - "": [T: "stiplet vertikal strek"] # 0xe989 (en: 'dashed vertical bar', google translation) + - "": [T: "vinkelrett med s"] # 0xe98a (en: 'perpendicular with s', google translation) + - "": [T: "vinkel med s"] # 0xe98b (en: 'angle with s', google translation) + - "": [T: "sfærisk vinkel mot venstre"] # 0xe98c (en: 'spherical angle opening left', google translation) + - "": [T: "vinkel mot venstre"] # 0xe98d (en: 'angle opening left', google translation) + - "": [T: "vertikal strek med dobbel krok"] # 0xe98e (en: 'vertical bar with double hook', google translation) + - "": [T: "medium dot-operator fri radikal"] # 0xe98f (google translation) + - "": [T: "hvit oppoverpekende trekant over strek"] # 0xe990 (en: 'white up pointing triangle above bar', google translation) + - "": [T: "identisk og parallell med"] # 0xe991 (en: 'identical and parallel to', google translation) + - "": [T: "smash-produkt"] # 0xe992 (en: 'smash product', google translation) + - "": [T: "trippel vertikal strek med horisontal strek"] # 0xe993 (en: 'triple bar operator with horizontal bar', google translation) + - "": [T: "identisk med med dobbel skråstrek"] # 0xe994 (en: 'identical to with double slash', google translation) + - "": [T: "triple kryssende streker"] # 0xe995 (en: 'triple crossed bars', google translation) + - "": [T: "sirkel med vertikal strek"] # 0xe996 (en: 'vertical bar over circle', google translation) + - "": [T: "vertikal proporsjonal med"] # 0xe997 (en: 'vertical proportional to', google translation) + - "": [T: "måne i siste kvarter"] # 0xe998 (en: 'black last quarter moon', google translation) + - "": [T: "måne i første kvarter"] # 0xe999 (google translation) + - "": [T: "negativ sinusbølge"] # 0xe9a0 (en: 'negative sine wave', google translation) + - "": [T: "prikk i parentes"] # 0xe9a1 (en: 'parenthesized dot', google translation) + - "": [T: "parenteser"] # 0xe9a2 (en: 'parens', google translation) + - "": [T: "hvitt smil"] # 0xe9a3 (en: 'white smile', google translation) + - "": [T: "hvit rynke"] # 0xe9a4 (en: 'white frown', google translation) + - "": [T: "heksagon"] # 0xe9a5 (en: 'hexagon', google translation) + - "": [T: "ekvivalent med over pluss"] # 0xe9a6 (en: 'equivalent to over plus', google translation) + - "": [T: "pluss over ekvivalent med"] # 0xe9a7 (en: 'plus over equivalent to', google translation) + - "": [T: "snitt"] # 0xe9b0 (en: 'intersection serifs', google translation) + - "": [T: "union"] # 0xe9b1 (google translation) + - "": [T: "kvadratisk snitt"] # 0xe9b2 (en: 'square intersection serifs', google translation) + - "": [T: "kvadratisk union"] # 0xe9b3 (google translation) + - "": [T: "foregår ekvivalent med eller følger"] # 0xe9e0 (en: 'precedes equivalent to or succeeds', google translation) + - "": [T: "følger ekvivalent med eller foregår"] # 0xe9e1 (en: 'succeeds equivalent to or precedes', google translation) + - "": [T: "foregår tilnærmet lik eller følger"] # 0xe9e2 (en: 'precedes almost equal to or succeeds', google translation) + - "": [T: "følger tilnærmet lik eller foregår"] # 0xe9e3 (en: 'succeeds almost equal to or precedes', google translation) + - "": [T: "mindre enn ekvivalent med eller større enn"] # 0xe9f0 (en: 'less than equivalent to or greater than', google translation) + - "": [T: "større enn ekvivalent med eller mindre enn"] # 0xe9f1 (en: 'greater than equivalent to or less than', google translation) + - "": [T: "ikke mye mindre enn"] # 0xea00 (en: 'not vert much less than', google translation) + - "": [T: "ikke mye større enn"] # 0xea01 (en: 'not vert much greater than', google translation) + - "": [T: "ikke mye mindre enn"] # 0xea02 (en: 'not much less than variant', google translation) + - "": [T: "ikke mye større enn"] # 0xea03 (en: 'not much greater than variant', google translation) + - "": [T: "mindre enn vertikal ikke dobbel lik"] # 0xea04 (en: 'less vert not double equals', google translation) + - "": [T: "større enn vertikal ikke dobbel lik"] # 0xea05 (en: 'gt vert not double equals', google translation) + - "": [T: "ikke mindre enn eller lik"] # 0xea06 (en: 'not less than or equal to', google translation) + - "": [T: "ikke større enn eller lik"] # 0xea07 (en: 'not greater than or equal to', google translation) + - "": [T: "verken lik eller mindre enn"] # 0xea09 (en: 'neither equal to nor less than', google translation) + - "": [T: "inneholder ikke eller er lik"] # 0xea0a (en: 'does not contain or equal to', google translation) + - "": [T: "verken overmengde av eller lik"] # 0xea0b (en: 'neither superset of nor equal to', google translation) + - "": [T: "verken delmengde av eller lik"] # 0xea0c (en: 'neither subset of nor equal to', google translation) + - "": [T: "omvendt skråstrek delmengde"] # 0xea0d (en: 'reverse solidus subset', google translation) + - "": [T: "verken lik eller større enn"] # 0xea0e (en: 'neither equal to nor greater than', google translation) + - "": [T: "ikke minus tilde"] # 0xea0f (en: 'not minus tilde operator', google translation) + - "": [T: "verken lik eller mindre enn"] # 0xea10 (en: 'neither equal to nor less than', google translation) + - "": [T: "ikke tilde"] # 0xea11 (en: 'not tilde operator', google translation) + - "": [T: "ikke element i eller lik"] # 0xea12 (en: 'not element of or equal to', google translation) + - "": [T: "verken lik eller større enn"] # 0xea13 (en: 'neither equal to nor greater than', google translation) + - "": [T: "ikke tilnærmet lik"] # 0xea14 (en: 'not almost equal', google translation) + - "": [T: "ikke følger tilnærmet lik"] # 0xea15 (en: 'not succeeds similar', google translation) + - "": [T: "mindre enn eller lik med skråstrek"] # 0xea16 (en: 'less than or slanted equal to with slash', google translation) + - "": [T: "større enn eller lik med skråstrek"] # 0xea17 (en: 'greater than or slanted equal to with slash', google translation) + - "": [T: "overmengde skråstrek"] # 0xea1a (google translation) + - "": [T: "inneholder ikke"] # 0xea1b (en: 'does not contain', google translation) + - "": [T: "ikke mindre enn eller lik"] # 0xea1d (en: 'not less than or equal to', google translation) + - "": [T: "ikke større enn eller lik"] # 0xea1e (en: 'not greater than or equal to', google translation) + - "": [T: "ikke nesten lik minus"] # 0xea1f (en: 'not almost equal to minus', google translation) + - "": [T: "tilhører ikke mengde med prikk"] # 0xea22 (en: 'negated set membership dot above', google translation) + - "": [T: "ikke rett vinkel"] # 0xea2c (en: 'not vert angle', google translation) + - "": [T: "ikke parallell"] # 0xea2d (en: 'not parallel slanted', google translation) + - "": [T: "ikke strek"] # 0xea2e (en: 'not bar operator', google translation) + - "": [T: "ikke dobbel strek"] # 0xea2f (en: 'not double bar operator', google translation) + - "": [T: "ikke trippel strek"] # 0xea30 (en: 'not triple bar operator', google translation) + - "": [T: "mindre enn men ikke tilnærmet lik"] # 0xea32 (en: 'less than but not approximately equal to', google translation) + - "": [T: "større enn men ikke tilnærmet lik"] # 0xea33 (en: 'greater than but not approximately equal to', google translation) + - "": [T: "mindre enn eller ikke lik"] # 0xea34 (en: 'less than or not equal to', google translation) + - "": [T: "større enn eller ikke lik"] # 0xea35 (en: 'greater than or not equal to', google translation) + - "": [T: "ikke nøstet mindre enn"] # 0xea36 (en: 'not nested less than', google translation) + - "": [T: "ikke nøstet større enn"] # 0xea37 (en: 'not nested greater than', google translation) + - "": [T: "ikke mye mindre enn"] # 0xea38 (en: 'not much less than', google translation) + - "": [T: "ikke mye større enn"] # 0xea39 (en: 'not much greater than', google translation) + - "": [T: "foregår men ikke ekvivalent med"] # 0xea3a (en: 'precedes but not equivalent to', google translation) + - "": [T: "følger men ikke ekvivalent med"] # 0xea3b (en: 'succeeds but not equivalent to', google translation) + - "": [T: "foregår men ikke lik"] # 0xea3c (en: 'precedes but not equal to', google translation) + - "": [T: "følger men ikke lik"] # 0xea3d (en: 'succeeds but not equal to', google translation) + - "": [T: "ikke lik eller foregår"] # 0xea3e (en: 'does not equal or precede', google translation) + - "": [T: "ikke lik eller følger"] # 0xea3f (en: 'does not equal or succeed', google translation) + - "": [T: "foregår men ikke lik"] # 0xea40 (en: 'precedes but not equal to', google translation) + - "": [T: "følger men ikke lik"] # 0xea41 (en: 'succeeds but not equal to', google translation) + - "": [T: "ikke delmengde av eller lik"] # 0xea42 (en: 'not subset of nor equal to', google translation) + - "": [T: "ikke overmengde av eller lik"] # 0xea43 (en: 'not superset of nor equal to', google translation) + - "": [T: "delmengde av eller ikke lik"] # 0xea44 (en: 'subset of or not equal to', google translation) + - "": [T: "overmengde av eller ikke lik"] # 0xea45 (en: 'superset of or not equal to', google translation) + - "": [T: "ikke delmengde av eller lik"] # 0xea46 (en: 'not subset of nor equal to', google translation) + - "": [T: "ikke overmengde av eller lik"] # 0xea47 (en: 'not superset of nor equal to', google translation) + - "": [T: "ikke trippel mindre enn"] # 0xea48 (en: 'not triple less than', google translation) + - "": [T: "ikke trippel større enn"] # 0xea49 (en: 'not triple greater than', google translation) + - "": [T: "ikke foregår lik"] # 0xea4c (en: 'not precedes equals', google translation) + - "": [T: "ikke følger lik"] # 0xea4d (en: 'not succeeds equals', google translation) + - "": [T: "ikke normal undergruppe av med strek"] # 0xea50 (en: 'not normal subgroup of with bar', google translation) + - "": [T: "inneholder ikke som normal undergruppe med strek"] # 0xea51 (en: 'does not contain as normal subgroup with bar', google translation) + - "": [T: "ikke forskjell mellom"] # 0xea52 (en: 'not difference between', google translation) + - "": [T: "ikke geometrisk ekvivalent med"] # 0xea53 (en: 'not geometrically equivalent to', google translation) + - "": [T: "ikke vertikal tilnærmet lik"] # 0xea54 (en: 'not vert similar', google translation) + - "": [T: "ikke lik eller tilnærmet lik"] # 0xea55 (en: 'not equal or similar', google translation) + - "": [T: "ikke vertikal tilnærmet lik"] # 0xea56 (en: 'not vert approximate', google translation) + - "": [T: "ikke tilnærmet identisk med"] # 0xea57 (en: 'not approximately identical to', google translation) + - "": [T: "ikke differansen mellom"] # 0xea58 (en: 'not bumpy equals', google translation) + - "": [T: "ikke differansen mellom"] # 0xea59 (en: 'not bumpy single equals', google translation) + - "": [T: "ikke lik prikk"] # 0xea5a (en: 'not equal dot', google translation) + - "": [T: "speilvendt ikke ekvivalent med"] # 0xea5b (en: 'reverse not equivalent', google translation) + - "": [T: "ikke kvadratisk delmengde"] # 0xea60 (en: 'not square subset', google translation) + - "": [T: "ikke kvadratisk overmengde"] # 0xea61 (en: 'not square superset', google translation) + - "": [T: "ikke tilnærmet lik over lik"] # 0xea62 (en: 'not almost equal over equal', google translation) + - "": [T: "ikke strengt ekvivalent med"] # 0xea63 (en: 'not strictly equivalent to', google translation) + - "": [T: "ikke kongruent prikk"] # 0xea64 (en: 'not congruent dot', google translation) + - "": [T: "speilvendt ikke lik"] # 0xea65 (en: 'reverse not equal', google translation) + - "": [T: "ikke vertikal venstre trekant lik"] # 0xea70 (en: 'not vert left triangle equals', google translation) + - "": [T: "ikke vertikal høyre trekant lik"] # 0xea71 (en: 'not vert right triangle equals', google translation) + - "": [T: "ikke partiell"] # 0xea80 (en: 'not partial', google translation) + - "": [T: "pilforlenger"] # 0xeb00 (en: 'arrow embellishment extender', google translation) + - "": [T: "høyrepil over venstrepil"] # 0xeb01 (en: 'arrow rightwards over arrow leftwards', google translation) + - "": [T: "høyrepil over venstrepil"] # 0xeb02 (en: 'arrow rightwards over arrow leftwards', google translation) + - "": [T: "høyre-harpun over venstre-harpun"] # 0xeb03 (en: 'harpoon right over harpoon left', google translation) + - "": [T: "høyre-harpun over venstre-harpun"] # 0xeb04 (en: 'harpoon right over harpoon left', google translation) + - "": [T: "dobbel-pil nordøst sørvest"] # 0xeb05 (en: 'double arrow northeast southwest', google translation) + - "": [T: "dobbel-pil nordvest sørøst"] # 0xeb06 (en: 'double arrow northwest southeast', google translation) + - "": [T: "horisontal harpun-forlenger"] # 0xeb07 (en: 'horizontal harpoon extender', google translation) + - "": [T: "venstrepil i bue mot klokka"] # 0xeb08 (en: 'anticlockwise arc leftwards arrow', google translation) + - "": [T: "høyrepil i bue mot klokka"] # 0xeb09 (en: 'anticlockwise arc rightwards arrow', google translation) + - "": [T: "stor høyrepil"] # 0xeb0b (en: 'large rightwards arrow accent', google translation) + - "": [T: "stor venstrepil"] # 0xeb0c (en: 'large leftwards arrow accent', google translation) + - "": [T: "venstre pilspiss"] # 0xeb0d (en: 'leftwards arrowhead', google translation) + - "": [T: "høyre pilspiss"] # 0xeb0e (en: 'rightwards arrowhead', google translation) + - "": [T: "stor venstre-høyre-pil med strek"] # 0xeb0f (en: 'large left right arrow with stroke', google translation) + - "": [T: "horisontal dobbel pil-forlenger"] # 0xeb10 (en: 'horizontal double arrow extender', google translation) + - "": [T: "stor venstre-høyre-pil med strek"] # 0xeb11 (en: 'large left right double arrow with stroke', google translation) + - "": [T: "nedoverpil til venstre for oppoverpil"] # 0xeb12 (en: 'downwards arrow leftwards of upwards arrow', google translation) + - "": [T: "venstrepil med hjørne nedover"] # 0xeb13 (en: 'leftwards arrow with corner downwards', google translation) + - "": [T: "høyrepil med hjørne oppover"] # 0xeb14 (en: 'rightwards arrow with corner upwards', google translation) + - "": [T: "venstrepil med hjørne oppover"] # 0xeb15 (en: 'leftwards arrow with corner upwards', google translation) + - "": [T: "øvre halvsirkel-pil mot klokka med pluss"] # 0xeb16 (en: 'anticlockwise top semicircle arrow with plus', google translation) + - "": [T: "øvre halvsirkel-pil med klokka med minus"] # 0xeb17 (en: 'clockwise top semicircle arrow with minus', google translation) + - "": [T: "høyrepil med hale og strek"] # 0xeb18 (en: 'rightwards arrow with tail with stroke', google translation) + - "": [T: "høyre-harpun mothake ned"] # 0xeb19 (en: 'right harpoon down', google translation) + - "": [T: "venstre-harpun mothake ned"] # 0xeb1a (en: 'left harpoon down', google translation) + - "": [T: "venstre-høyre-harpun mothake ned"] # 0xeb1b (en: 'left right harpoon down', google translation) + - "": [T: "venstre-høyre-harpun mothake opp"] # 0xeb1c (en: 'left right harpoon up', google translation) + - "": [T: "opp-ned-harpun mothake venstre"] # 0xeb1d (en: 'up down harpoon left', google translation) + - "": [T: "opp-ned-harpun mothake høyre"] # 0xeb1e (en: 'up down harpoon right', google translation) + - "": [T: "oppoverpil til høyre for nedoverpil"] # 0xeb1f (en: 'upwards arrow to the right of downwards arrow', google translation) + - "": [T: "venstre-harpun mot strek mothake opp"] # 0xeb20 (en: 'leftwards harpoon to bar with barb upwards', google translation) + - "": [T: "høyre-harpun mot strek mothake opp"] # 0xeb21 (en: 'rightwards harpoon to bar with barb upwards', google translation) + - "": [T: "venstre-harpun mot strek mothake ned"] # 0xeb22 (en: 'leftwards harpoon to bar with barb downwards', google translation) + - "": [T: "høyre-harpun mot strek mothake ned"] # 0xeb23 (en: 'rightwards harpoon to bar with barb downwards', google translation) + - "": [T: "venstre-harpun fra strek mothake opp"] # 0xeb24 (en: 'leftwards harpoon from bar with barb upwards', google translation) + - "": [T: "høyre-harpun fra strek mothake opp"] # 0xeb25 (en: 'rightwards harpoon from bar with barb upwards', google translation) + - "": [T: "venstre-harpun fra strek mothake ned"] # 0xeb26 (en: 'leftwards harpoon from bar with barb downwards', google translation) + - "": [T: "høyre-harpun fra strek mothake ned"] # 0xeb27 (en: 'rightwards harpoon from bar with barb downwards', google translation) + - "": [T: "opp-harpun mot strek mothake venstre"] # 0xeb28 (en: 'upwards harpoon to bar with barb leftwards', google translation) + - "": [T: "ned-harpun mot strek mothake venstre"] # 0xeb29 (en: 'downwards harpoon to bar with barb leftwards', google translation) + - "": [T: "opp-harpun mot strek mothake høyre"] # 0xeb2a (en: 'upwards harpoon to bar with barb rightwards', google translation) + - "": [T: "ned-harpun mot strek mothake høyre"] # 0xeb2b (en: 'downwards harpoon to bar with barb rightwards', google translation) + - "": [T: "opp-harpun fra strek mothake venstre"] # 0xeb2c (en: 'upwards harpoon from bar with barb leftwards', google translation) + - "": [T: "ned-harpun fra strek mothake venstre"] # 0xeb2d (en: 'downwards harpoon from bar with barb leftwards', google translation) + - "": [T: "opp-harpun fra strek mothake høyre"] # 0xeb2e (en: 'upwards harpoon from bar with barb rightwards', google translation) + - "": [T: "ned-harpun fra strek mothake høyre"] # 0xeb2f (en: 'downwards harpoon from bar with barb rightwards', google translation) + - "": [T: "oppoverpil mot strek"] # 0xeb30 (en: 'upwards arrow to bar', google translation) + - "": [T: "nedoverpil mot strek"] # 0xeb31 (en: 'downwards arrow to bar', google translation) + - "": [T: "opp-harpun til venstre for ned-harpun"] # 0xeb32 (en: 'upwards harpoon to the left of downwards harpoon', google translation) + - "": [T: "opp-harpun til høyre for ned-harpun"] # 0xeb33 (en: 'upwards harpoon to the right of downwards harpoon', google translation) + - "": [T: "pilspiss oppover"] # 0xeb34 (en: 'upwards arrowhead', google translation) + - "": [T: "pilspiss nedover"] # 0xeb35 (en: 'downwards arrowhead', google translation) + - "": [T: "dobbel harpun venstre mothake ned høyre mothake opp"] # 0xeb36 (en: 'double harpoon with leftwards barb down rightwards barb up', google translation) + - "": [T: "dobbel harpun venstre mothake opp høyre mothake ned"] # 0xeb37 (en: 'double harpoon with leftwards barb up rightwards barb down', google translation) + - "": [T: "venstrepil over strek"] # 0xeb38 (en: 'leftwards arrow over bar', google translation) + - "": [T: "høyrepil over strek"] # 0xeb39 (en: 'rightwards arrow over bar', google translation) + - "": [T: "venstrepil under strek"] # 0xeb3a (en: 'leftwards arrow under bar', google translation) + - "": [T: "høyrepil under strek"] # 0xeb3b (en: 'rightwards arrow under bar', google translation) + - "": [T: "venstre-høyre trippel pil"] # 0xeb3c (en: 'left right triple arrow', google translation) + - "": [T: "dobbel-pil nordøst sørøst"] # 0xeb3f (en: 'double arrow northeast southeast', google translation) + - "": [T: "venstre halvsirkel-pil mot klokka"] # 0xeb40 (en: 'anticlockwise left semicircle arrow', google translation) + - "": [T: "venstre halvsirkel-pil med klokka"] # 0xeb41 (en: 'clockwise left semicircle arrow', google translation) + - "": [T: "venstre-høyre-pil i venstre åpen sirkel"] # 0xeb42 (en: 'left open circle left right arrow', google translation) + - "": [T: "høyrepil over tilde"] # 0xeb44 (en: 'rightwards arrow over tilde', google translation) + - "": [T: "venstrepil over tilde"] # 0xeb45 (en: 'leftwards arrow over tilde', google translation) + - "": [T: "venstre-harpun over strek"] # 0xeb48 (en: 'leftwards harpoon over bar', google translation) + - "": [T: "høyre-harpun over strek"] # 0xeb49 (en: 'rightwards harpoon over bar', google translation) + - "": [T: "venstre-harpun under strek"] # 0xeb4a (en: 'leftwards harpoon under bar', google translation) + - "": [T: "høyre-harpun under strek"] # 0xeb4b (en: 'rightwards harpoon under bar', google translation) + - "": [T: "sammenpresset venstrepil"] # 0xeb4c (en: 'squat black leftwards arrow', google translation) + - "": [T: "høyre halvsirkel-pil med klokka"] # 0xeb50 (en: 'clockwise right semicircle arrow', google translation) + - "": [T: "høyre halvsirkel-pil mot klokka"] # 0xeb51 (en: 'anticlockwise right semicircle arrow', google translation) + - "": [T: "venstre-høyre-harpun i venstre åpen sirkel"] # 0xeb52 (en: 'left open circle left right harpoon', google translation) + - "": [T: "oppoverpil til venstre for vertikal strek"] # 0xeb58 (en: 'upwards arrow leftwards of vertical bar', google translation) + - "": [T: "nedoverpil til venstre for vertikal strek"] # 0xeb59 (en: 'downwards arrow leftwards of vertical bar', google translation) + - "": [T: "oppoverpil til høyre for vertikal strek"] # 0xeb5a (en: 'upwards arrow rightwards of vertical bar', google translation) + - "": [T: "nedoverpil til høyre for vertikal strek"] # 0xeb5b (en: 'downwards arrow rightwards of vertical bar', google translation) + - "": [T: "høyrepil med krok ned"] # 0xeb5c (en: 'rightwards arrow with extended downwards hook', google translation) + - "": [T: "venstrepil med krok"] # 0xeb5d (en: 'leftwards arrow with extended hook', google translation) + - "": [T: "venstrepil med krok ned"] # 0xeb5e (en: 'leftwards arrow with extended downwards hook', google translation) + - "": [T: "høyrepil med krok"] # 0xeb5f (en: 'rightwards arrow with extended hook', google translation) + - "": [T: "ikke bølgete høyrepil"] # 0xeb60 (en: 'not right arrow wavy', google translation) + - "": [T: "ikke buet høyrepil"] # 0xeb61 (en: 'not right arrow curved', google translation) + - "": [T: "opp-harpun til venstre for vertikal strek"] # 0xeb68 (en: 'upwards harpoon leftwards of vertical bar', google translation) + - "": [T: "ned-harpun til venstre for vertikal strek"] # 0xeb69 (en: 'downwards harpoon leftwards of vertical bar', google translation) + - "": [T: "opp-harpun til høyre for vertikal strek"] # 0xeb6a (en: 'upwards harpoon rightwards of vertical bar', google translation) + - "": [T: "ned-harpun til høyre for vertikal strek"] # 0xeb6b (en: 'downwards harpoon rightwards of vertical bar', google translation) + - "": [T: "vertikal dobbel pil-forlenger"] # 0xeb6c (en: 'vertical double arrow extender', google translation) + - "": [T: "vertikal harpun med mothake venstre forlenger"] # 0xeb6d (en: 'vertical harpoon with barb left extender', google translation) + - "": [T: "vertikal harpun med mothake høyre forlenger"] # 0xeb6e (en: 'vertical harpoon with barb right extender', google translation) + - "": [T: "høyre-harpun over venstre-harpun høyre"] # 0xeb6f (en: 'right harpoon over left harpoon right', google translation) + - "": [T: "høyre-harpun over venstre-harpun venstre"] # 0xeb70 (en: 'right harpoon over left harpoon left', google translation) + - "": [T: "venstre-harpun over høyre-harpun høyre"] # 0xeb71 (en: 'left harpoon over right harpoon right', google translation) + - "": [T: "venstre-harpun over høyre-harpun venstre"] # 0xeb72 (en: 'left harpoon over right harpoon left', google translation) + - "": [T: "venstrepil fra strek pilspiss"] # 0xeb73 (en: 'leftwards arrow from bar arrowhead', google translation) + - "": [T: "venstre-høyre-pil fra strek forlenger"] # 0xeb74 (en: 'leftwards rightwards arrow from bar extender', google translation) + - "": [T: "venstrepil fra strek med hale"] # 0xeb75 (en: 'leftwards arrow from bar tail', google translation) + - "": [T: "høyrepil fra strek med hale"] # 0xeb76 (en: 'rightwards arrow from bar tail', google translation) + - "": [T: "høyrepil fra strek pilspiss"] # 0xeb77 (en: 'rightwards arrow from bar arrowhead', google translation) + - "": [T: "opp-harpun fra strek med mothake venstre pilspiss"] # 0xeb78 (en: 'upwards harpoon from bar with barb leftwards arrowhead', google translation) + - "": [T: "høyrepil over venstrepil høyre"] # 0xeb79 (en: 'rightwards arrow over leftwards arrow right', google translation) + - "": [T: "høyrepil over venstrepil venstre"] # 0xeb7a (en: 'rightwards arrow over leftwards arrow left', google translation) + - "": [T: "venstrepil over høyrepil høyre"] # 0xeb7b (en: 'leftwards arrow over rightwards arrow right', google translation) + - "": [T: "venstrepil over høyrepil venstre"] # 0xeb7c (en: 'leftwards arrow over rightwards arrow left', google translation) + - "": [T: "oppoverpil fra strek pilspiss"] # 0xeb7d (en: 'upwards arrow from bar arrowhead', google translation) + - "": [T: "oppoverpil fra strek hale"] # 0xeb7e (en: 'upwards arrow from bar tail', google translation) + - "": [T: "nedoverpil fra strek hale"] # 0xeb7f (en: 'downwards arrow from bar tail', google translation) + - "": [T: "nedoverpil fra strek pilspiss"] # 0xeb80 (en: 'downwards arrow from bar arrowhead', google translation) + - "": [T: "ned-harpun fra strek med mothake høyre pilspiss"] # 0xeb81 (en: 'downwards harpoon from bar with barb rightwards arrowhead', google translation) + - "": [T: "opp-harpun til venstre for ned-harpun bunn"] # 0xeb82 (en: 'upwards harpoon to the left of downwards harpoon bottom', google translation) + - "": [T: "opp-harpun til venstre for ned-harpun forlenger"] # 0xeb83 (en: 'upwards harpoon to the left of downwards harpoon extender', google translation) + - "": [T: "ned-harpun til venstre for opp-harpun topp"] # 0xeb84 (en: 'downwards harpoon to the left of upwards harpoon top', google translation) + - "": [T: "opp-harpun til venstre for ned-harpun topp"] # 0xeb85 (en: 'upwards harpoon to the left of downwards harpoon top', google translation) + - "": [T: "ned-harpun til venstre for opp-harpunens forlenger"] # 0xeb86 (en: 'downwards harpoon to the left of the upwards harpoon extender', google translation) + - "": [T: "ned-harpun til venstre for opp-harpunens bunn"] # 0xeb87 (en: 'downwards harpoon to the left of the upwards harpoon bottom', google translation) + - "": [T: "oppoverpil til venstre for nedoverpil bunn"] # 0xeb88 (en: 'upwards arrow leftwards of downwards arrow bottom', google translation) + - "": [T: "nedoverpil til venstre for oppoverpil topp"] # 0xeb89 (en: 'downwards arrow leftwards of upwards arrow top', google translation) + - "": [T: "oppoverpil til venstre for nedoverpil topp"] # 0xeb8a (en: 'upwards arrow leftwards of downwards arrow top', google translation) + - "": [T: "nedoverpil til venstre for oppoverpil bunn"] # 0xeb8b (en: 'downwards arrow leftwards of upwards arrow bottom', google translation) + - "": [T: "venstre-høyre-pil forlenger"] # 0xeb8c (en: 'leftwards rightwards arrows extender', google translation) + - "": [T: "nordøst-pil forlenger"] # 0xeb8d (google translation) + - "": [T: "nordvest-pil forlenger"] # 0xeb8e (google translation) + - "": [T: "nedoverpekende krøllparentes venstre"] # 0xec00 (en: 'down pointing brace left', google translation) + - "": [T: "nedoverpekende krøllparentes midten"] # 0xec01 (en: 'down pointing brace mid', google translation) + - "": [T: "nedoverpekende krøllparentes høyre"] # 0xec02 (en: 'down pointing brace right', google translation) + - "": [T: "horisontal krøllparentes forlenger"] # 0xec03 (en: 'horizontal brace extender', google translation) + - "": [T: "oppoverpekende krøllparentes venstre"] # 0xec04 (en: 'up pointing brace left', google translation) + - "": [T: "oppoverpekende krøllparentes midten"] # 0xec05 (en: 'up pointing brace mid', google translation) + - "": [T: "oppoverpekende krøllparentes høyre"] # 0xec06 (en: 'up-pointing brace right', google translation) + - "": [T: "venstre vertikal strek"] # 0xec07 (en: 'left vertical bar', google translation) + - "": [T: "høyre vertikal strek"] # 0xec08 (en: 'right vertical bar', google translation) + - "": [T: "venstre dobbel vertikal strek"] # 0xec09 (en: 'left double vertical bar', google translation) + - "": [T: "høyre dobbel vertikal strek"] # 0xec0a (en: 'right double vertical bar', google translation) + - "": [T: "horisontal hakeparentes forlenger"] # 0xec0b (en: 'horizontal bracket extender', google translation) + - "": [T: "under hakeparentes"] # 0xec0c (en: 'under square bracket', google translation) + - "⎵": [T: "under hakeparentes"] # 0x23b5 + - "": [T: "over hakeparentes"] # 0xec0d (en: 'over square bracket', google translation) + - "⎴": [T: "over hakeparentes"] # 0x23b4 + - "": [T: "under hakeparentes venstre"] # 0xec0e (en: 'under bracket left', google translation) + - "": [T: "under hakeparentes høyre"] # 0xec0f (en: 'under bracket right', google translation) + - "": [T: "over hakeparentes venstre"] # 0xec10 (en: 'over bracket left', google translation) + - "": [T: "over hakeparentes høyre"] # 0xec11 (en: 'over bracket right', google translation) + - "": [T: "venstreparentes 1"] # 0xec12 (en: 'left parens 1', google translation) + - "": [T: "venstreparentes 2"] # 0xec13 (en: 'left parens 2', google translation) + - "": [T: "venstreparentes 3"] # 0xec14 (en: 'left parens 3', google translation) + - "": [T: "venstreparentes 4"] # 0xec15 (en: 'left parens 4', google translation) + - "": [T: "høyreparentes 1"] # 0xec16 (en: 'right parens 1', google translation) + - "": [T: "høyreparentes 2"] # 0xec17 (en: 'right parens 2', google translation) + - "": [T: "høyreparentes 3"] # 0xec18 (en: 'right parens 3', google translation) + - "": [T: "høyreparentes 4"] # 0xec19 (en: 'right parens 4', google translation) + - "": [T: "radikal 1"] # 0xec1a (en: 'radical 1', google translation) + - "": [T: "radikal 2"] # 0xec1b (en: 'radical 2', google translation) + - "": [T: "radikal 3"] # 0xec1c (en: 'radical 3', google translation) + - "": [T: "radikal 4"] # 0xec1d (en: 'radical 4', google translation) + - "": [T: "radikal 5"] # 0xec1e (en: 'radical 5', google translation) + - "": [T: "radikal bunn"] # 0xec1f (en: 'radical bottom', google translation) + - "": [T: "radikal vertikal forlenger"] # 0xec20 (en: 'radical vertical extender', google translation) + - "": [T: "radikal topp"] # 0xec21 (en: 'radical top', google translation) + - "": [T: "venstre hvit hakeparentes topp"] # 0xec22 (en: 'left white bracket top', google translation) + - "": [T: "venstre hvit hakeparentes forlenger"] # 0xec23 (en: 'left white bracket extender', google translation) + - "": [T: "venstre hvit hakeparentes bunn"] # 0xec24 (en: 'left white bracket bottom', google translation) + - "": [T: "høyre hvit hakeparentes topp"] # 0xec25 (en: 'right white bracket top', google translation) + - "": [T: "høyre hvit hakeparentes forlenger"] # 0xec26 (en: 'right white bracket extender', google translation) + - "": [T: "høyre hvit hakeparentes bunn"] # 0xec27 (en: 'right white bracket bottom', google translation) + - "": [T: "venstre hvit krøllparentes"] # 0xec30 (en: 'left white curly bracket', google translation) + - "": [T: "høyre hvit krøllparentes"] # 0xec31 (en: 'right white curly bracket', google translation) + - "": [T: "lang divisjon"] # 0xec32 (en: 'long division sign', google translation) + - "": [T: "lang divisjon forlenger"] # 0xec33 (google translation) + - "": [T: "kort divisjon"] # 0xec34 (en: 'short division', google translation) + - "": [T: "dobbel sørvest til nordøst em-binding"] # 0xec40 (en: 'double southwest to northeast em bond', google translation) + - "": [T: "dobbel nordvest til sørøst em-binding"] # 0xec41 (en: 'double northwest to southeast em bond', google translation) + - "": [T: "enkel horisontal em-binding"] # 0xec42 (en: 'single horizontal em bond', google translation) + - "": [T: "dobbel horisontal em-binding"] # 0xec43 (en: 'double horizontal em bond', google translation) + - "": [T: "trippel horisontal em-binding"] # 0xec44 (en: 'triple horizontal em bond', google translation) + - "": [T: "enkel vertikal em-binding"] # 0xec45 (en: 'single vertical em bond', google translation) + - "": [T: "dobbel vertikal em-binding"] # 0xec46 (en: 'double vertical em bond', google translation) + - "": [T: "trippel vertikal em-binding"] # 0xec47 (google translation) + - "": [T: "mindre enn em-binding"] # 0xec48 (en: 'less than em bond', google translation) + - "": [T: "større enn em-binding"] # 0xec49 (en: 'greater than em bond', google translation) + - "": [T: "enkel horisontal en-binding"] # 0xec4a (en: 'single horizontal en bond', google translation) + - "": [T: "dobbel horisontal en-binding"] # 0xec4b (en: 'double horizontal en bond', google translation) + - "": [T: "trippel horisontal en-binding"] # 0xec4c (en: 'triple horizontal en bond', google translation) + - "": [T: "øvre venstre rektangel"] # 0xec80 (en: 'top left rectangle', google translation) + - "": [T: "nedre venstre rektangel"] # 0xec81 (en: 'bottom left rectangle', google translation) + - "": [T: "øvre høyre rektangel"] # 0xec90 (en: 'top right rectangle', google translation) + - "": [T: "nedre høyre rektangel"] # 0xec91 (en: 'bottom right rectangle', google translation) + - "": [T: "syntetisk divisjon hjørne"] # 0xec92 (en: 'synthetic division corner', google translation) + - "": [T: "syntetisk divisjon horisontal forlenger"] # 0xec93 (en: 'synthetic division horizontal extender', google translation) + - "": [T: "syntetisk divisjon vertikal forlenger"] # 0xec94 (en: 'synthetic division vertical extender', google translation) + - "": [T: "venstre tak gulv forlenger"] # 0xec95 (en: 'left ceiling floor extender', google translation) + - "": [T: "høyre tak gulv forlenger"] # 0xec96 (en: 'right ceiling floor extender', google translation) + - "": [T: "over hakeparentes forlenger"] # 0xec97 (en: 'over bracket extender', google translation) + - "": [T: "vertikal strek forlenger"] # 0xec98 (en: 'vertical bar extender', google translation) + - "": [T: "venstre dobbel vertikal strek forlenger"] # 0xec99 (en: 'left double vertical bar extender', google translation) + - "": [T: "horisontal strek forlenger"] # 0xec9a (en: 'horizontal bar extender', google translation) + - "": [T: "under hakeparentes forlenger"] # 0xec9c (en: 'under bracket extender', google translation) + - "": [T: "nedoverpekende parentes høyre"] # 0xec9d (en: 'down pointing paren right', google translation) + - "": [T: "nedoverpekende parentes forlenger"] # 0xec9e (en: 'down pointing paren extender', google translation) + - "": [T: "nedoverpekende parentes venstre"] # 0xec9f (en: 'down pointing paren left', google translation) + - "": [T: "oppoverpekende krøllparentes forlenger"] # 0xeca0 (en: 'up pointing brace extender', google translation) + - "": [T: "oppoverpekende parentes venstre"] # 0xeca1 (en: 'up pointing paren left', google translation) + - "": [T: "oppoverpekende parentes forlenger"] # 0xeca2 (en: 'up pointing paren extender', google translation) + - "": [T: "oppoverpekende parentes høyre"] # 0xeca3 (en: 'up pointing paren right', google translation) + - "": [T: "nedoverpekende krøllparentes forlenger"] # 0xeca4 (en: 'down pointing brace extender', google translation) + - "": [T: "plancks konstant over to pi strek"] # 0xed00 (en: 'planck constant over two pi bar', google translation) + - "": [T: "speilvendt g"] # 0xed01 (en: 'mirror g', google translation) + - "": [T: "j uten prikk"] # 0xed02 (google translation) + - "": [T: "digamma"] # 0xed03 (google translation) + - "ϝ": [T: "digamma"] # 0x3dd + - "": [t: ""] # 0xed10 (en: 'd', google translation) + - "ⅆ": [T: "d"] # 0x2146 + - "": [t: ""] # 0xed11 (en: 'e', google translation) + - "ⅇ": [T: "e"] # 0x2147 + - "": [t: ""] # 0xed12 (en: 'i', google translation) + - "ⅈ": [T: "i"] # 0x2148 + - "": [T: ""] # 0xed13 (en: 'j', google translation) + - "ⅅ": + - spell: "translate('.', 'ⅅ', 'DD')" # 0xed16, 0x2145 + +# The private use chars are from MathType + - "": [T: "kurveintegral-loop mot klokka"] # 0xee00 (en: 'anticlockwise contour integral loop', google translation) + - "": [T: "kurveintegral-loop med klokka"] # 0xee01 (en: 'clockwise contour integral loop', google translation) + - "": [T: ""] # 0xee04 + - "": [T: ""] # 0xee05 + - "": [T: ""] # 0xee06 + - "": [T: ""] # 0xee07 + - "": [T: ""] # 0xee08 + - "": [T: ""] # 0xee09 + - "": [T: ""] # 0xee0a + - "": [T: ""] # 0xee0b + - "": [T: ""] # 0xee0c + - "": [T: "joint status"] # 0xee0d (en: 'joint status embellishment', google translation) + - "": [T: "joint status venstre"] # 0xee0e (en: 'joint status embellishment left', google translation) + - "": [T: "joint status høyre"] # 0xee0f (en: 'joint status embellishment right', google translation) + - "": [T: "joint status forlenger"] # 0xee10 (en: 'joint status embellishment extender', google translation) + - "": [T: "integral-loop"] # 0xee11 (en: 'integral loop', google translation) + - "": [T: "dobbel integral-loop"] # 0xee12 (google translation) + - "": [T: "trippel integral-loop"] # 0xee13 (en: 'integral loop triple', google translation) + - "": [T: "ekspanderende dobbel integral-loop"] # 0xee15 (google translation) + - "": [T: "ekspanderende trippel integral-loop"] # 0xee16 (en: 'expanding integral loop triple', google translation) + - "": [T: "asymptotisk lik"] # 0xee17 (en: 'asymptotically equal to accent', google translation) + - "": [T: "lik"] # 0xee18 (en: 'equal sign accent', google translation) + - "": [T: "kvadrupelt primtegn"] # 0xee19 (en: 'quadruple prime', google translation) + - "": [T: "strek med åpen sirkel venstre"] # 0xee1a (en: 'bar accent with open circle left', google translation) + - "": [T: "strek med lukket sirkel venstre"] # 0xee1b (en: 'bar accent with closed circle left', google translation) + - "": [T: "strek med åpen sirkel høyre"] # 0xee1c (en: 'bar accent with open circle right', google translation) + - "": [T: "strek med prikk"] # 0xee1d (en: 'bar accent with over dot', google translation) + - "": [T: "strek over prikk"] # 0xee1e (en: 'bar accent with under dot', google translation) + - "": [T: "strek med dobbel prikk over"] # 0xee1f (en: 'bar accent with double over dot', google translation) + - "": [T: "strek over dobbel prikk"] # 0xee20 (en: 'bar accent with double under dot', google translation) + - "": [T: "strek med hatt"] # 0xee21 (en: 'bar accent with caret', google translation) + - "": [T: "fet understrek"] # 0xee22 (en: 'thick under bar accent', google translation) + - "": [T: "strek med lukket sirkel høyre"] # 0xee23 (en: 'bar accent with closed circle right', google translation) + - "": [T: "stor prikk"] # 0xee24 (en: 'large dot above', google translation) + - "": [T: "justeringsmerke"] # 0xef00 (en: 'alignment mark', google translation) + - "": [T: ""] # 0xef01 + - "​": [T: ""] # 0x200b + - "": [T: ""] # 0xef02 + - " ": [T: ""] # 0x2009 + - "": [T: ""] # 0xef03 + - " ": [T: ""] # 0x205f + - "": [T: ""] # 0xef04 + - "": [T: ""] # 0xef05 + - " ": [T: ""] # 0x2003 + - "": [T: ""] # 0xef06 + - "": [T: ""] # 0xef07 + - "": [T: ""] # 0xef08 + - "": [T: ""] # 0xef09 + - "": [T: ""] # 0xef0a + - " ": [T: ""] # 0x200a + - "": [T: ""] # 0xef22 + - "": [T: ""] # 0xef23 + - "": [T: ""] # 0xef24 + - "": [T: ""] # 0xef29 + - "": [T: "savnet begrep"] # 0xef41 (en: 'missing term', google translation) + - "": [T: "kurveintegral med klokka pil til venstre"] # 0xef80 (en: 'clockwise contour integral arrow on left', google translation) + - "": [T: "integral med kvadrat"] # 0xef81 (en: 'integral with square', google translation) + - "": [T: "integral med skråstrek"] # 0xef82 (en: 'integral with slash', google translation) + - "": [T: "speilvendt integral"] # 0xef83 (en: 'reversed integral', google translation) + - "": [T: "dobbel null over dobbel null"] # 0xef90 (en: 'double zero over double zero', google translation) + - "": [T: "null med skråstrek"] # 0xef91 (en: 'zero with slash', google translation) + #------------------------------------------------------------------------------------------------------------- + # fraktur chars in math alphabetic block and also MathType private use area + # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display + - "𝔄-𝔜": # 0x1d504 - 0x1d51d ('z' version is reserved) + - T: "fraktur" # (google translation) + - spell: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" + - "-": # 0xf000 - 0xf018 + - T: "fraktur" # (google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" + + - "𝔞-𝔷": # 0x1d51e - 0x1d537 + - T: "fraktur" # (google translation) + - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf01a - 0xf033 + - T: "fraktur" # (google translation) + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝕬-𝖅": # 0x1D56C - 0x1D585 + - T: "fraktur fet" # (google translation) + - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf040 - 0xf059 + - T: "fraktur fet" # (google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝖆-𝖟": # 0x1d586 - 0x1d59f + - T: "fraktur fet" # (google translation) + - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf05a - 0xf073 + - T: "fraktur fet" # (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) + - T: "dobbeltstreket" # (en: 'double struck', google translation) + - spell: "translate('.', '𝔸𝔹𝔺𝔻𝔼𝔽𝔾𝔿𝕀𝕁𝕂𝕃𝕄𝕅𝕆𝕇𝕈𝕉𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf080 - 0xf098 + - T: "dobbeltstreket" # (en: 'double struck', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝕒-𝕫": # 0x1d552 - 0x1d56b + - T: "dobbeltstreket" # (en: 'double struck', google translation) + - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf09a - 0xf0b3 + - T: "dobbeltstreket" # (en: 'double struck', google translation) + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 + - T: "dobbeltstreket" # (en: 'double struck', google translation) + - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" + - "-": # 0xf0c0 - 0xf0c9 + - T: "dobbeltstreket" # (en: 'double struck', google translation) + - spell: "translate('.', '', '0123456789')" + + - "": [T: "dobbeltstreket nabla"] # 0xf0ca (en: 'double struck nabla', google translation) + - "": [T: "dobbeltstreket eulerkonstant"] # 0xf0cb (en: 'double struck euler constant', google translation) + + # script chars in math alphabetic block and also MathType private use area + # SWEDISH: We've used "skrivstilt" instead of skript for clarity + # NORWEGIAN: Used "script font" + - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 + - T: "script font" # (en: 'script', google translation) + - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf100 - 0xf119 + - T: "script font" # (en: 'script', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf + - T: "script font" # (en: 'script', google translation) + - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf11a - 0xf133 + - T: "script font" # (en: 'script', google translation) + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + # bold script chars in math alphabetic block and also MathType private use area + - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 + - T: "script font fet" # (en: 'script bold', google translation) + - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf140 - 0xf159 + - T: "script font fet" # (en: 'script bold', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝓪-𝔃": # 0x1d4ea - 0x1d503 + - T: "script font fet" # (en: 'script bold', google translation) + - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf15a - 0xf173 + - T: "script font fet" # (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: "stor"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "ligatur a e"] # (en: 'ligature ae', google translation) + - "": # 0xf19b + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "stor"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "dobbel s"] # (en: 'sharp s', google translation) + - "": # 0xf19c + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "stor"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "ø"] # (en: 'o with stroke', google translation) + + # MathType only has a few of the cap Greek letters in PUA + - "": # 0xf201 - 0xf209 + - T: "dobbeltstreket" # (en: 'double struck', google translation) + - spell: "translate('.', '', 'ΔΨΛΠΣΘΓΩΥ')" + + - "-": # 0xf220 - 0xf236 + - T: "dobbeltstreket" # (en: 'double struck', google translation) + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "": [T: "dobbeltstreket sluttsigma"] # 0xf237 (en: 'double struck final sigma', google translation) + - "": [T: "dobbeltstreket rho"] # 0xf250 (en: 'double struck rho', google translation) + - "": [T: "dobbeltstreket fi"] # 0xf251 (en: 'double struck phi', google translation) + - "𝐀-𝐙": # 0x1d400 - 0x1d419 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf260 - 0xf279 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝐚-𝐳": # 0x1d41a - 0x1d433 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf27a - 0xf293 + - T: "fet" # (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: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf2c8 - 0xf2e1 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝒂-𝒛": # 0x1d482 - 0x1d49b + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf2e2 - 0xf2fb + - T: "fet" # (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: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf334 - 0xf34d + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝗮-𝘇": # 0x1d5ee - 0x1d607 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf34e - 0xf367 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝘈-𝘡": # 0x1d608 - 0x1d621 + - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": # 0xf368 - 0xf381 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝘢-𝘻": # 0x1d622 - 0x1d63b + - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf382 - 0xf39b + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝘼-𝙕": # 0x1d63c - 0x1d655 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf39c - 0xf3b5 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝙖-𝙯": # 0x1d656 - 0x1d66f + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf3b6 - 0xf3cf + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝙰-𝚉": # 0x1d670 - 0x1d689 + - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "-": # 0xf3d0 - 0xf3e9 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 + - spell: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" + + - "-": # 0xf3ea - 0xf403 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + + - "": [T: "i uten prikk"] # 0xf404 (google translation) + - "𝚤": [T: "kursiv i uten prikk"] # 0x1d6a4 (en: 'dotless i', google: 'dotless i') + - "𝚥": [T: "kursiv j uten prikk"] # 0x1d6a5 (en: 'dotless j', google: 'dotless j') + + - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 + - T: "fet" # (en: 'bold', google: 'djärv') + - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf408 - 0xf420 + - T: "fet" # (en: 'bold', google: 'djärv') + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da + - T: "fet" # (en: 'bold', google: 'djärv') + - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf422 - 0xf43a + - T: "fet" # (en: 'bold', google: 'djärv') + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "": [T: "fet nabla"] # 0xf421 (en: 'bold nabla', google translation) + - "𝛁": [T: "fet nabla"] # 0x1d6c1 (en: 'bold nabla', google translation) + + - "𝛛𝛜𝛝𝛞𝛟𝛠𝛡": # 0x1D6DB - 0x1D6E1 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" + + - "": # 0xF43C - 0xF441 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '', '∂εθκφρπ')" + + - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa + - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf442 - 0xf45a + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝛼-𝜔": # 0x1d6fc - 0x1d714 + - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓𝜔', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf45c - 0xf474 + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "": [T: "kursiv nabla"] # 0xf45b (en: 'italic nabla', google translation) + - "𝛻": [T: "kursiv nabla"] # 0x1d6fb (en: 'italic nabla', google translation) + + - "𝜕𝜖𝜗𝜘𝜙𝜚𝜛": # 0x1d715 - 0x1d71b + - spell: "translate('.', '𝜕𝜖𝜗𝜘𝜙𝜚𝜛', '∂εθκφρπ')" + + - "": # 0xf475 - 0xf47b + - spell: "translate('.', '', '∂εθκφρπ')" + + - "𝜜-𝜴": # 0x1d71c - 0x1d734 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf47c - 0xf494 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝜶-𝝎": # 0x1d736 - 0x1d74e + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf496 - 0xf4ae + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": # 0x1d74f - 0x1d755 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εθκφρπ')" + + - "": # 0xf422 - 0xf43a + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '', '∂εθκφρπ')" + + - "𝜵": [T: "fet kursiv nabla"] # 0x1d735 (en: 'bold italic nabla', google translation) + - "": [T: "fet kursiv nabla"] # 0xf495 (en: 'bold italic nabla', google translation) + + - "𝝖-𝝮": # 0x1d756 - 0x1d76e + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "-": # 0xf4b6 - 0xf4ce + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝝰-𝞈": # 0x1d770 - 0x1d788 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇𝞈', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf4d0 - 0xf4e8 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝞉𝞊𝞋𝞌𝞍𝞎𝞏": # 0x1d789 - 0x1d78f + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '𝞉𝞊𝞋𝞌𝞍𝞎𝞏', '∂εθκφρπ')" + + - "": # 0xf4e9 - 0xf4ef + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '', '∂εθκφρπ')" + + - "": [T: "fet nabla"] # 0xf4cf (en: 'bold nabla', google translation) + - "𝝯": [T: "fet nabla"] # 0x1d76f (en: 'bold nabla', google translation) + + - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "-": # 0xf4f0 - 0xf508 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + + - "𝞪-𝟂": # 0x1d7aa - 0x1d7c2 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "-": # 0xf50a - 0xf522 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + + - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": # 0x1d7c3 - 0x1d7c9 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '𝟃𝟄𝟅𝟆𝟇𝟈𝟉', '∂εθκφρπ')" + + - "": # 0xf523 - 0xf529 + - T: "fet" # (en: 'bold', google translation) + - spell: "translate('.', '', '∂εθκφρπ')" + + - "": [T: "fet nabla"] # 0xf509 (en: 'bold nabla', google translation) + - "𝞩": [T: "fet nabla"] # 0x1d7a9 (en: 'bold nabla', google translation) + + - "": [T: "fet null"] # 0xf52e (en: 'bold zero', google translation) + - "𝟎": [T: "fet null"] # 0x1d7ce (en: 'bold zero', google translation) + - "": [T: "fet én"] # 0xf52f (en: 'bold one', google translation) + - "𝟏": [T: "fet én"] # 0x1d7cf (en: 'bold one', google translation) + - "": [T: "fet to"] # 0xf530 (en: 'bold two', google translation) + - "𝟐": [T: "fet to"] # 0x1d7d0 (en: 'bold two', google translation) + - "": [T: "fet tre"] # 0xf531 (en: 'bold three', google translation) + - "𝟑": [T: "fet tre"] # 0x1d7d1 (en: 'bold three', google translation) + - "": [T: "fet fire"] # 0xf532 (en: 'bold four', google translation) + - "𝟒": [T: "fet fire"] # 0x1d7d2 (en: 'bold four', google translation) + - "": [T: "fet fem"] # 0xf533 (en: 'bold five', google translation) + - "𝟓": [T: "fet fem"] # 0x1d7d3 (en: 'bold five', google translation) + - "": [T: "fet seks"] # 0xf534 (en: 'bold six', google translation) + - "𝟔": [T: "fet seks"] # 0x1d7d4 (en: 'bold six', google translation) + - "": [T: "fet sju"] # 0xf535 (en: 'bold seven', google translation) + - "𝟕": [T: "fet sju"] # 0x1d7d5 (en: 'bold seven', google translation) + - "": [T: "fet åtte"] # 0xf536 (en: 'bold eight', google translation) + - "𝟖": [T: "fet åtte"] # 0x1d7d6 (en: 'bold eight', google translation) + - "": [T: "fet ni"] # 0xf537 (en: 'bold nine', google translation) + - "𝟗": [T: "fet ni"] # 0x1d7d7 (en: 'bold nine', google translation) + - "": [T: "null"] # 0xf542 (en: 'zero', google translation) + - "𝟢": [T: "null"] # 0x1d7e2 (en: 'zero', google translation) + - "": [T: "én"] # 0xf543 (en: 'one', google translation) + - "𝟣": [T: "én"] # 0x1d7e3 (en: 'one', google translation) + - "": [T: "to"] # 0xf544 (en: 'two', google translation) + - "𝟤": [T: "to"] # 0x1d7e4 (en: 'two', google translation) + - "": [T: "tre"] # 0xf545 (en: 'three', google translation) + - "𝟥": [T: "tre"] # 0x1d7e5 (en: 'three', google translation) + - "": [T: "fire"] # 0xf546 (en: 'four', google translation) + - "𝟦": [T: "fire"] # 0x1d7e6 (en: 'four', google translation) + - "": [T: "fem"] # 0xf547 (en: 'five', google translation) + - "𝟧": [T: "fem"] # 0x1d7e7 (en: 'five', google translation) + - "": [T: "seks"] # 0xf548 (en: 'six', google translation) + - "𝟨": [T: "seks"] # 0x1d7e8 (en: 'six', google translation) + - "": [T: "sju"] # 0xf549 (en: 'seven', google translation) + - "𝟩": [T: "sju"] # 0x1d7e9 (en: 'seven', google translation) + - "": [T: "åtte"] # 0xf54a (en: 'eight', google translation) + - "𝟪": [T: "åtte"] # 0x1d7ea (en: 'eight', google translation) + - "": [T: "ni"] # 0xf54b (en: 'nine', google translation) + - "𝟫": [T: "ni"] # 0x1d7eb (en: 'nine', google translation) + - "": [T: "fet null"] # 0xf54c (en: 'bold zero', google translation) + - "𝟬": [T: "fet null"] # 0x1d7ec (en: 'bold zero', google translation) + - "": [T: "fet én"] # 0xf54d (en: 'bold one', google translation) + - "𝟭": [T: "fet én"] # 0x1d7ed (en: 'bold one', google translation) + - "": [T: "fet to"] # 0xf54e (en: 'bold two', google translation) + - "𝟮": [T: "fet to"] # 0x1d7ee (en: 'bold two', google translation) + - "": [T: "fet tre"] # 0xf54f (en: 'bold three', google translation) + - "𝟯": [T: "fet tre"] # 0x1d7ef (en: 'bold three', google translation) + - "": [T: "fet fire"] # 0xf550 (en: 'bold four', google translation) + - "𝟰": [T: "fet fire"] # 0x1d7f0 (en: 'bold four', google translation) + - "": [T: "fet fem"] # 0xf551 (en: 'bold five', google translation) + - "𝟱": [T: "fet fem"] # 0x1d7f1 (en: 'bold five', google translation) + - "": [T: "fet seks"] # 0xf552 (en: 'bold six', google translation) + - "𝟲": [T: "fet seks"] # 0x1d7f2 (en: 'bold six', google translation) + - "": [T: "fet sju"] # 0xf553 (en: 'bold seven', google translation) + - "𝟳": [T: "fet sju"] # 0x1d7f3 (en: 'bold seven', google translation) + - "": [T: "fet åtte"] # 0xf554 (en: 'bold eight', google translation) + - "𝟴": [T: "fet åtte"] # 0x1d7f4 (en: 'bold eight', google translation) + - "": [T: "fet ni"] # 0xf555 (en: 'bold nine', google translation) + - "𝟵": [T: "fet ni"] # 0x1d7f5 (en: 'bold nine', google translation) + - "": [T: "null"] # 0xf556 (en: 'zero', google translation) + - "𝟶": [T: "null"] # 0x1d7f6 (en: 'zero', google translation) + - "": [T: "én"] # 0xf557 (en: 'one', google translation) + - "𝟷": [T: "én"] # 0x1d7f7 (en: 'one', google translation) + - "": [T: "to"] # 0xf558 (en: 'two', google translation) + - "𝟸": [T: "to"] # 0x1d7f8 (en: 'two', google translation) + - "": [T: "tre"] # 0xf559 (en: 'three', google translation) + - "𝟹": [T: "tre"] # 0x1d7f9 (en: 'three', google translation) + - "": [T: "fire"] # 0xf55a (en: 'four', google translation) + - "𝟺": [T: "fire"] # 0x1d7fa (en: 'four', google translation) + - "": [T: "fem"] # 0xf55b (en: 'five', google translation) + - "𝟻": [T: "fem"] # 0x1d7fb (en: 'five', google translation) + - "": [T: "seks"] # 0xf55c (en: 'six', google translation) + - "𝟼": [T: "seks"] # 0x1d7fc (en: 'six', google translation) + - "": [T: "sju"] # 0xf55d (en: 'seven', google translation) + - "𝟽": [T: "sju"] # 0x1d7fd (en: 'seven', google translation) + - "": [T: "åtte"] # 0xf55e (en: 'eight', google translation) + - "𝟾": [T: "åtte"] # 0x1d7fe (en: 'eight', google translation) + - "": [T: "ni"] # 0xf55f (en: 'nine', google translation) + - "𝟿": [T: "ni"] # 0x1d7ff (en: 'nine', google translation) + - "": [T: "ukjent tegn"] # 0xf700 (en: 'unknown character', google translation) + - "": [T: "nedre høyre og nedre venstre trekanter"] # 0xf726 (en: 'lower right and lower left triangles', google translation) + - "": [T: "horisontal ellipse forlenger"] # 0xf72d (en: 'horizontal ellipsis extender', google translation) + - "": [T: "midtlinje horisontal ellipse forlenger"] # 0xf72e (en: 'midline horizontal ellipsis extender', google translation) + - "": [T: "radikal forlenger"] # 0xf8e5 (en: 'radical extender', google translation) + - "": [T: "vertikal pil-forlenger"] # 0xf8e6 (en: 'vertical arrow extender', google translation) + - "": [T: "horisontal pil-forlenger"] # 0xf8e7 (en: 'horizontal arrow extender', google translation) + - "": [T: "registrert"] # 0xf8e8 (en: 'registered sign sans serif', google translation) + - "": [T: "opphavsrett"] # 0xf8e9 (google translation) + - "": [T: "varemerke"] # 0xf8ea (google translation) + - "": [T: "venstreparentes topp"] # 0xf8eb (en: 'left paren top', google translation) + - "": [T: "venstreparentes forlenger"] # 0xf8ec (en: 'left paren extender', google translation) + - "": [T: "venstreparentes bunn"] # 0xf8ed (en: 'left paren bottom', google translation) + - "": [T: "venstre hakeparentes topp"] # 0xf8ee (en: 'left bracket top', google translation) + - "": [T: "venstre hakeparentes forlenger"] # 0xf8ef (en: 'left bracket extender', google translation) + - "": [T: "venstre hakeparentes bunn"] # 0xf8f0 (en: 'left bracket bottom', google translation) + - "": [T: "venstre krøllparentes topp"] # 0xf8f1 (en: 'left brace top', google translation) + - "": [T: "venstre krøllparentes midten"] # 0xf8f2 (en: 'left brace mid', google translation) + - "": [T: "venstre krøllparentes bunn"] # 0xf8f3 (en: 'left brace bottom', google translation) + - "": [T: "krøllparentes forlenger"] # 0xf8f4 (en: 'brace extender', google translation) + - "": [T: "integral forlenger"] # 0xf8f5 (en: 'integral extender', google translation) + - "": [T: "høyreparentes topp"] # 0xf8f6 (en: 'right paren top', google translation) + - "": [T: "høyreparentes forlenger"] # 0xf8f7 (en: 'right paren extender', google translation) + - "": [T: "høyreparentes bunn"] # 0xf8f8 (en: 'right paren bottom', google translation) + - "": [T: "høyre hakeparentes topp"] # 0xf8f9 (en: 'right bracket top', google translation) + - "": [T: "høyre hakeparentes forlenger"] # 0xf8fa (en: 'right bracket extender', google translation) + - "": [T: "høyre hakeparentes bunn"] # 0xf8fb (en: 'right bracket bottom', google translation) + - "": [T: "høyre krøllparentes topp"] # 0xf8fc (en: 'right brace top', google translation) + - "": [T: "høyre krøllparentes midten"] # 0xf8fd (en: 'right brace mid', google translation) + - "": [T: "høyre krøllparentes bunn"] # 0xf8fe (en: 'right brace bottom', google translation) + - "": [T: "apple logo"] # 0xf8ff (en: 'apple logo', google translation) + #-------------------------------------------------------------------------------------------------------------- + #Alphabetic presentation forms + - "ff": [T: "f f"] # 0xfb00 (en: 'ff', google: 'ff') + - "fi": [T: "f i"] # 0xfb01 (en: 'fi', google: 'fi') + - "fl": [T: "f l"] # 0xfb02 (en: 'fl', google: 'fl') + - "ffi": [T: "f f i"] # 0xfb03 (en: 'ffi', google: 'ffi') + - "ffl": [T: "f f l"] # 0xfb04 (en: 'ffl', google: 'ffl') + - "ſt": [T: "f t"] # 0xfb05 (en: 'ft', google translation) + - "st": [T: "s t"] # 0xfb06 (google translation) + #------------------------------------------------------------------------------------------------------------------ + # Combining half marks + - "︠": [T: "ligatur venstre halvdel"] # 0xfe20 (en: 'ligature left half embellishment', google translation) + - "︡": [T: "ligatur høyre halvdel"] # 0xfe21 (en: 'ligature right half embellishment', google translation) + - "︢": [T: "dobbel tilde venstre halvdel"] # 0xfe22 (en: 'double tilde left half embellishment', google translation) + - "︣": [T: "dobbel tilde høyre halvdel"] # 0xfe23 (en: 'double tilde right half embellishment', google translation) + - "︤": [T: "makron venstre halvdel"] # 0xfe24 (en: 'macron left half embellishment', google translation) + - "︥": [T: "makron høyre halvdel"] # 0xfe25 (en: 'macron right half embellishment', google translation) + - "︦": [T: "sammenkoblet makron"] # 0xfe26 (en: 'conjoining macron embellishment', google translation) + #----------------------------------------------------------------------------------------------------------------- + #CJK compatibility forms + - "︵": [T: "parentes over"] # 0xfe35 + - "︶": [T: "parentes under"] # 0xfe36 + - "︷": [T: "krøllparentes over"] # 0xfe37 (en: 'over brace') + - "︸": [T: "krøllparentes under"] # 0xfe38 (en: 'under brace') + - "︿": [T: "vinkelparentes over"] # 0xfe3f + - "﹀": [T: "vinkelparentes under"] # 0xfe40 +#------------------------------------------------------------------------------------------------------------------ +#Halfwidth and Fullwidth forms + - "﹡": [T: "liten asterisk"] # 0xfe61 + - "﹢": [T: "liten pluss"] # 0xfe62 + - "﹣": [T: "liten minus"] # 0xfe63 + - "﹤": [T: "liten mindre enn"] # 0xfe64 + - "﹥": [T: "liten større enn"] # 0xfe65 + - "﹦": [T: "lite likhetstegn"] # 0xfe66 + - "+": [T: "pluss"] # 0xff0b + - "<": [T: "mindre enn"] # 0xff1c + - "=": [T: "lik"] # 0xff1d + - ">": [T: "større enn"] # 0xff1e + - "\": [T: "omvendt skråstrek"] # 0xff3c + - "^": [T: "hatt"] # 0xff3e + - "|": # 0xff5c + # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' + - with: + variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) + replace: + - test: + - if: "$SpeechStyle != 'ClearSpeak'" + then_test: + if: "$DefaultToGiven" + then: [{pause: short}, {T: "gitt"}] + else: [T: "vertikal strek"] + - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" + then: [T: "vertikal strek"] + - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" + then: [T: "slik at"] + - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" + then: [{pause: short}, {T: "gitt"}] + - else: [T: "deler"] + - "~": [T: "tilde"] # 0xff5e + - "¬": [T: "ikke"] # 0xffe2 + - "←": [T: "venstrepil"] # 0xffe9 + - "↑": [T: "oppoverpil"] # 0xffea + - "→": [T: "høyrepil"] # 0xffeb + - "↓": [T: "nedoverpil"] # 0xffec + #-------------------------------------------------------------------------------------------------------------------- + #Small form variants + - "﹨": [T: "liten speilvendt skråstrek"] # 0xfe68 + #--------------------------------------------------------------------------------------------------------------------- + #Specials + - "": [T: "ukjent eller savnet objekt"] # 0xfffc (en: 'unknown or missing object', google translation) + - "�": [T: "ukjent eller savnet tegn"] # 0xfffd (google: 'okänd eller saknad karaktär') diff --git a/Rules/Languages/nb/unicode.yaml b/Rules/Languages/nb/unicode.yaml new file mode 100644 index 000000000..9b3c8f103 --- /dev/null +++ b/Rules/Languages/nb/unicode.yaml @@ -0,0 +1,513 @@ +--- + - "a-z": + - test: + if: "$TTS='none'" + then: [T: "."] # (en: '.', google translation) + else: [spell: "'.'"] + + # Capital letters are a little tricky: users can pick their favorite word (something that was requested) and + # screen readers have options to use pitch changes or beeps instead of or in addition to say "cap" + # Also, if a user can see the screen, they probably don't need to hear "cap", but if they specified an override, they must want to hear the override. + + - "A-Z": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "stor"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] + + - "0-9": [T: "."] # (en: '.', google: 'A') + + - " ": [T: " "] # 0x20 #NORWEGIAN: Added from English version. Not in Swedish version. + + - "!": # 0x21 + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" #NORWEGIAN: Changed from ":structure" to be equal to English translation + then_test: + if: "$Verbosity = 'Terse'" + then: [T: "utropstegn"] # 0x21 (en: 'bang', google translation) + else: [T: "utropstegn"] # 0x21 (en: 'exclamation point') + else: [T: "fakultet"] # 0x21 (en: 'factorial') + + - "\"": [T: "anførselstegn"] # 0x22 (en: 'quotation mark') + - "#": [T: "nummertegn"] # 0x23 (en: 'number', MathPlayer: 'numeriskt tecken', google: 'siffra') + - "$": [T: "dollar"] # 0x24 (en: 'dollars') + - "%": [T: "prosent"] # 0x25 (en: 'percent') + - "&": [T: "og-tegn"] # 0x26 (en: 'ampersand') + - "'": [T: "apostrof"] # 0x27 (en: 'apostrophe') + - "(": # 0x28 + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [{pause: short}, {T: "startparentes"}] # 0x28 (en: 'open', google translation) + else: [{pause: short}, {T: "startparentes"}] # 0x28 (en: 'open paren') + else: [T: "venstreparentes"] # 0x28 (en: 'left paren') + - pause: short + - ")": # 0x29 + - pause: short + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [T: "sluttparentes"] # 0x29 (en: 'close', google translation) + else: [T: "sluttparentes"] # 0x29 (en: 'close paren') + else: [T: "høyreparentes"] # 0x29 (en: 'right paren') + + - "*": # 0x2a + test: + if: "parent::*[name(.)='msup' or name(.)='msubsup' or name(.)='skip-super']" + then: [T: "stjerne"] # 0x2a (en: 'star', google translation) + else: [T: "ganger"] # 0x2a (en: 'times') + - "+": [T: "pluss"] # 0x2b + - ",": # 0x2c + # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent + # that this test is here and not with "…" is not ideal, but seems simplest + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak "comma" when not adjacent to '…' + - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " + # except if expression starts with '…' + - "../*[1][.='…'] " + then: + - T: "komma" # (en: 'comma', google translation) + - test: + if: "$Verbosity != Terse" + then: [pause: short] + # else silent + + - "-": [T: "minus"] # 0x2d + - ".": # 0x2e + - test: + if: "parent::*[1][self::m:mn]" + then: [T: "punktum"] # (en: 'point', google translation) + else: [T: "prikk"] # (en: 'dot') + - "/": [T: "delt på"] # 0x2f (en: 'divided by') + - ":": [T: "kolon"] # 0x3a (en: 'colon') + - ";": [T: "semikolon"] # 0x3b (en: 'semicolon') + - "<": # 0x3c + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "mindre enn" # (en: 'less than') + - "=": # 0x3d + # SWEDISH: We remove "är" from all occurrences of = after consulting our mathematician advisor. + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "lik" # (en: 'equals', MathPlayer: 'lik', google: 'lika') + + - ">": # 0x3e + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "større enn" # (en: 'greater than') + - "?": [T: "spørsmålstegn"] # 0x3f (en: 'question mark') + - "@": [T: "krøllalfa"] # 0x40 (en: 'at sign') + - "[": # 0x5b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "start hakeparentes"] # (en: 'open bracket', google translation) + else: [T: "venstre hakeparentes"] # (en: 'left bracket') + - pause: short + - "\\": [T: "omvendt skråstrek"] # 0x5c (en: 'back slash') + - "]": # 0x5d + - pause: short + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "slutt hakeparentes"] # (en: 'close bracket', google translation) + else: [T: "høyre hakeparentes"] # (en: 'right bracket') + - "^": [T: "hatt"] # 0x5e (en: 'hat') + - "_": [T: "understrek"] # 0x5f (en: 'under bar', MathPlayer: 'streck under', google: 'under bar') + - "`": [T: "grav aksent"] # 0x60 (en: 'grave') + - "{": # 0x7b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "start krøllparentes"] # (en: 'open brace', google translation) + else: [T: "venstre krøllparentes"] # (en: 'left brace') + - pause: short + - "|": # 0x7c NORWEGIAN: Changed to English version + # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' + - with: + variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) + replace: + - test: + - if: "$SpeechStyle != 'ClearSpeak'" + then_test: + if: "$DefaultToGiven" + then: [{pause: short}, {T: "gitt"}] + else: [T: "vertikal strek"] + - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" + then: [T: "vertikal strek"] + - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" + then: [T: "slik at"] + - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" + then: [{pause: short}, {T: "gitt"}] + - else: [T: "deler"] + + - "}": # 0x7d + - pause: short + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "slutt krøllparentes"] # (en: 'close brace', google translation) + else: [T: "høyre krøllparentes"] # (en: 'right brace') + + - "~": [T: "tilde"] # 0x7e + - " ": # 0xa0 + - test: + if: "@data-empty-in-2D and not(ancestor::*[self::m:piecewise or self::m:system-of-equations or self::m:lines])" #NORWEGIAN: Changed to English version. Now it doesn't speak "tom tom" for continued_row + then: [T: "tom"] # want to say something for fraction (etc) with empty child (en: 'empty', google translation) + else: [T: ""] + + - "¬": [T: "ikke"] # 0xac (en: 'not') + - "°": [T: "grader"] # 0xb0 (en: 'degrees') + - "±": [T: "pluss minus"] # 0xb1 (en: 'plus or minus') + - "´": [T: "akutt aksent"] # 0xb4 (en: 'acute') + - "·": # 0xB7 + - test: + if: "$SpeechStyle = 'LiteralSpeak' or not($SpeechStyle = 'ClearSpeak' and $ClearSpeak_MultSymbolDot = 'Auto')" + then: [T: "midtstilt prikk"] # (en: 'times', google translation) + else: [T: "ganger"] # (en: 'dot', MathPlayer: 'mellanpunkt', google: 'punkt') + - "×": # 0xd7 + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolX = 'Auto'" + then: [T: "ganger"] # (en: 'times', google translation) + else_test: + if: $ClearSpeak_MultSymbolX = 'By' + then: [T: "ganger"] # (en: 'by', google translation) + else: [T: "kryss"] # (en: 'cross') + - "÷": [T: "delt på"] # 0xf7 (en: 'divided by') + - "̀": [T: "grav aksent"] # 0x300 (en: 'grave accent embellishment', google: 'allvarlig accentutsmyckning') + - "́": [T: "akutt aksent"] # 0x301 (en: 'acute accent embellishment', google: 'akut accentutsmyckning') + - "̂": [T: "cirkumfleks"] # 0x302 (en: 'circumflex accent embellishment', google: 'circumflex accent utsmyckning') + - "̃": [T: "tilde"] # 0x303 (google: 'tilde utsmyckning') + - "̄": [T: "makron"] # 0x304 (en: 'macron embellishment', google: 'macron -utsmyckning') + - "̅": [T: "strek"] # 0x305 (google: 'överbar utsmyckning') + - "̆": [T: "breve"] # 0x306 (en: 'breve', google: 'breve') + - "̇": [T: "prikk"] # 0x307 (google: 'prick ovanför utsmyckning') + + # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong + - "Α-Ω": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "stor"] # (en: 'cap', google translation) + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [spell: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] + + - "α": [T: "alfa"] # 0x3b1 (en: 'alpha') + - "β": [T: "beta"] # 0x3b2 + - "γ": [T: "gamma"] # 0x3b3 + - "δ": [T: "delta"] # 0x3b4 + - "ε": [T: "epsilon"] # 0x3b5 + - "ζ": [T: "zeta"] # 0x3b6 + - "η": [T: "eta"] # 0x3b7 + - "θ": [T: "theta"] # 0x3b8 + - "ι": [T: "jota"] # 0x3b9 (en: 'iota', google: 'iota') + - "κ": [T: "kappa"] # 0x3ba + - "λ": [T: "lambda"] # 0x3bb (en: 'lambda', google: 'lambda') + - "μ": [T: "my"] # 0x3bc (en: 'mu', google: 'mu') + - "ν": [T: "ny"] # 0x3bd (en: 'nu', google: 'nu') + - "ξ": [T: "ksi"] # 0x3be (en: 'zai', google: 'zai') + - "ο": [T: "omikron"] # 0x3bf (en: 'omicron', google: 'omicron') + - "π": [T: "pi"] # 0x3c0 + - "ρ": [T: "rho"] # 0x3c1 + - "ς": [T: "sluttsigma"] # 0x3c2 (en: 'final sigma', google: 'slutlig sigma') + - "σ": [T: "sigma"] # 0x3c3 + - "τ": [T: "tau"] # 0x3c4 + - "υ": [T: "ypsilon"] # 0x3c5 (en: 'upsilon', google: 'upsilon') + - "φ": [T: "fi"] # 0x3c6 (en: 'phi', google: 'phi') + - "χ": [T: "khi"] # 0x3c7 + - "ψ": [T: "psi"] # 0x3c8 + - "ω": [T: "omega"] # 0x3c9 + - "ϕ": [T: "fi"] # 0x3d5 (en: 'phi', google: 'phi') + - "ϖ": [T: "pi"] # 0x3d6 (en: 'pi', google: 'pi') + - "ϵ": [T: "epsilon"] # 0x3f5 + - "϶": [T: "omvendt epsilon"] # 0x3f6 (en: 'reversed epsilon') + + - "–": [T: "tankestrek"] # 0x2013 (en: 'en dash') + - "—": [T: "lang tankestrek"] # 0x2014 (en: 'em dash') + - "―": [T: "horisontal strek"] # 0x2015 (en: 'horizontal bar') + - "‖": [T: "dobbel loddrett strek"] # 0x2016 (en: 'double vertical line') + - "…": # 0x2026 + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak '…' as 'and so on...' unless expr starts with '…' + - "../*[1][.='…']" + then: [T: "prikk prikk prikk"] # (en: 'dot dot dot', google translation) + else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' + if: "count(following-sibling::*) = 0" + then: [T: "og så videre"] # (en: 'and so on', google translation) + else: [T: "og så videre opp til"] # (en: 'and so on up to') + + - "⁡": # 0x2061 #NORWEGIAN: Changed to literal. Didn't add the test with "TrigFunctionName, cause want to say "sinus hyperbolicus av" + - test: + if: "not(preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')]) and + not(@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')])" + then: [T: "av"] # (en: 'of', google translation) + - "⁢": [T: ""] # 0x2062 + - "⁣": [T: ""] # 0x2063 + - "⁤": [T: "og"] # 0x2064 (en: 'and', google: 'og') + - "′": [T: "primtegn"] # 0x2032 (en: 'prime') + - "″": [T: "dobbelt primtegn"] # 0x2033 (en: 'double prime') + - "‴": [T: "trippelt primtegn"] # 0x2034 (en: 'triple prime') + + - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" + - T: "dobbeltstreket" # (en: 'double-struck') + - spell: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" + + - "℃": [T: "grader celsius"] # 0x2103 (en: 'degrees celsius') + - "℉": [T: "grader fahrenheit"] # 0x2109 (en: 'degrees fahrenheit') + - "ℋℛℓ": # 0x210b + - T: "script font" # (en: 'script', google: 'manus') + - spell: "translate('.', 'ℋℛℓ', 'HRl')" + - "ℎ": [T: "plancks konstant"] # 0x210e + - "ℜ": # 0x211c + - T: "fraktur" # (en: 'fraktur', google: 'fraktur') + - spell: "'R'" + + - "Ω": [T: "ohm"] # 0x2126 (en: 'ohms') + - "K": [T: "kelvin"] # 0x212a (en: 'kelvin') + - "Å": [T: "ångstrøm"] # 0x212b + - "ⅆⅇⅈⅉ": # 0x2146-9 + - T: "dobbeltstreket kursiv" # (en: 'double-struck italic') + - spell: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" + + - "←": [T: "venstrepil"] # 0x2190 (en: 'leftwards arrow') + - "↑": [T: "oppoverpil"] # 0x2191 (en: 'upwards arrow') + - "→": # 0x2192 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "går mot"] # (en: 'approaches', google translation) + else: [T: "høyrepil"] # (en: 'right arrow') + + - "↓": [T: "nedoverpil"] # 0x2193 (en: 'downwards arrow') + - "⇒": [T: "impliserer"] # 0x21d2 (en: 'rightwards double arrow') + - "∀": [T: "for alle"] # 0x2200 (en: 'for all') + - "∂": [T: "partiell derivert"] # 0x2202 + # SWEDISH: This is only refered to as "del" in Swedish, but we write "dell" for correct pronounciation. + - "∃": [T: "det eksisterer"] # 0x2203 (en: 'there exists') + - "∄": [T: "det eksisterer ikke"] # 0x2204 (en: 'there does not exist') + - "∅": [T: "den tomme mengden"] # 0x2205 (en: 'empty set') + - "∆": [T: "laplace av"] # 0x2206 (en: 'laplacian of') + - "∈": # 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - T: "i" #(en: "is an element of") + # NORWEGIAN: "i" sounds best in all cases for the non-ClearSpeak case + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + # SWEDISH/NORWEGIAN: The word "medlem" is not commonly used in set theory, so we removed that rule. If the parsing has set the parameter to "Member" it will fall under the "else" case. + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "i"] # (en: 'in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "element i"] # (en: 'element of', google translation) + - else: [T: "tilhørende"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "i"] # NORWEGIAN: Set the "auto" case to be "i" + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "er et element i"] # (en: 'is in', google translation) + - else: [T: "tilhører"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - "∉": # 0x2209 + # rule is identical to 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - test: + if: "not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" + then: [T: "er"] + - T: "ikke et element i" + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + # SWEDISH/NORWEGIAN: The word "medlem" is not commonly used in set theory, so we removed that rule. If the parsing has set the parameter to "Member" it will fall under the "else" case. + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "ikke i"] # (en: 'not in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "ikke element i"] # (en: 'not element of', google translation) + - else: [T: "ikke tilhørende"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "er ikke et element i"] # (en: 'is not an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "er ikke i"] # (en: 'is not in', google translation) + - else: [T: "tilhører ikke"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to') + - "∊": # 0x220a + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then: + - T: "i" #(en: "is an element of") + # NORWEGIAN: "i" sounds best in all cases for the non-ClearSpeak case + # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option + # SWEDISH/NORWEGIAN: The word "medlem" is not commonly used in set theory, so we removed that rule. If the parsing has set the parameter to "Member" it will fall under the "else" case. + else_test: + if: "../../self::m:set or ../../../self::m:set" # inside a set + then_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "i"] # (en: 'in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "element i"] # (en: 'element of', google translation) + - else: [T: "tilhørende"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "i"] # (en: 'is an element of', google translation) #NORWEGIAN: Set the "auto" case to be "i" + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "er et element i"] # (en: 'is in', google translation) + - else: [T: "tilhører"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - "∏": [T: "produktet"] # 0x220f (en: 'product') + - "∐": [T: "koproduktet"] # 0x2210 (en: 'co-product', MathPlayer: 'coproduct', google: 'samprodukt') + - "∑": [T: "sum"] # 0x2211 (en: 'sum') + - "−": [T: "minus"] # 0x2212 + - "∓": [T: "minus pluss"] # 0x2213 (en: 'minus or plus') + - "∗": [T: "ganger"] # 0x2217 (en: 'times') + - "∘": [T: "sammensatt med"] # 0x2218 (en: 'composed with') + - "√": [T: "kvadratroten av"] # 0x221a (en: 'square root of') + - "∝": # 0x221d + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "proporsjonal med" # (en: 'proportional to') + - "∞": [T: "uendelig"] # 0x221e (en: 'infinity') + - "∟": [T: "rett vinkel"] # 0x221f (en: 'right angle') + - "∠": [T: "vinkel"] # 0x2220 (en: 'angle') + - "∡": [T: "målt vinkel"] # 0x2221 (en: 'measured angle') + - "∣": [T: "deler"] # 0x2223 (en: 'divides') + - "∤": [T: "deler ikke"] # 0x2224 (en: 'does not divide') + - "∥": # 0x2225 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "parallell med" # (en: 'parallel to') + - "∦": # 0x2226 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke parallell med" # (en: 'not parallel to') + - "∧": [T: "og"] # 0x2227 (en: 'and') + - "∨": [T: "eller"] # 0x2228 (en: 'or') + - "∩": [T: "snitt"] # 0x2229 (en: 'intersection') + - "∪": [T: "union"] # 0x222a + - "∫": [T: "integralet"] # 0x222b + - "∬": [T: "dobbeltintegralet"] # 0x222c (en: 'double integral') + - "∭": [T: "trippelintegralet"] # 0x222d (en: 'triple integral') + - "∮": [T: "kurveintegralet"] # 0x222e (en: 'contour integral') + - "∶": # 0x2236 + - T: "til" # (en: 'to') + - "∷": [T: "som"] # 0x2237 (en: 'as', MathPlayer: 'proportion', google: 'som') + - "∼": # 0x223c (en: 'varies with') + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "proporsjonal med" + - "∽": [T: "omvendt tilde"] # 0x223d (en: 'reversed tilde') + - "∾": # 0x223e + # SWEDISH: Could not find any examples of how this character is used and what specific meaning it has. In ClearSpeak rules, it is + # translated as "omvänt långdraget s". + - T: "omvendt langstrakt s" # (en: 'most positive', MathPlayer: 'inverted lazy s', google: 'mest positiva') + - "∿": [T: "sinuskurve"] # 0x223f (en: 'sine wave') + - "≠": # 0x2260 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "ikke lik" # (en: 'not equal to') + - "≡": # 0x2261 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "identisk med" # (en: 'identical to') + - "≤": # 0x2264 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "mindre enn eller lik" + + - "≥": # 0x2265 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "større enn eller lik" + + - "≦": # 0x2266 (en: 'less than over equal to') + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "mindre enn eller lik" + + - "≧": # 0x2267 (en: 'greater than over equal to') + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] + - T: "større enn eller lik" + + - "≺": [T: "foregår"] # 0x227a (en: 'precedes') + - "≻": [T: "følger"] # 0x227b (en: 'succeeds') + - "⊂": # 0x2282 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is a', google translation) + - T: "ekte delmengde av" + + - "⊃": # 0x2283 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is a', google translation) + - T: "ekte overmengde av" + + - "⊄": # 0x2284 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke en ekte delmengde av" + + - "⊅": # 0x2285 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er"] # (en: 'is', google translation) + - T: "ikke en ekte overmengde av" + + - "⊆": # 0x2286 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is a', google translation) + - T: "delmengde av" + + - "⊇": # 0x2287 + - test: + if: "$Verbosity!='Terse'" + then: [T: "er en"] # (en: 'is a', google translation) + - T: "overmengde av" + diff --git a/tests/Languages/nb.rs b/tests/Languages/nb.rs new file mode 100644 index 000000000..810c7fe9e --- /dev/null +++ b/tests/Languages/nb.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/nb/ClearSpeak/functions.rs b/tests/Languages/nb/ClearSpeak/functions.rs new file mode 100644 index 000000000..93c55a9c1 --- /dev/null +++ b/tests/Languages/nb/ClearSpeak/functions.rs @@ -0,0 +1,469 @@ +/// 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("nb", "ClearSpeak", expr, "sinus av x pluss cosinus av y pluss tangens av z pluss sekans av alfa, pluss cosekans av fi, pluss cotangens av fi"); +} + +#[test] +fn hyperbolic_trig_names() { + let expr = " + sinhx+ + coshy+ + tanhz+ + sechα+ + cschϕ+ + cothφ + "; + test("nb", "ClearSpeak", expr, "sinus hyperbolicus av x, pluss \ + cosinus hyperbolicus av y, pluss \ + tangens hyperbolicus av z, pluss, \ + sekans hyperbolicus av alfa, pluss \ + cosekans hyperbolicus av fi, pluss \ + cotangens hyperbolicus av fi"); +} + + +#[test] +fn inverse_trig() { + let expr = "sin-1x"; + test("nb", "ClearSpeak", expr, "invers sinus av x"); +} + +#[test] +fn inverse_trig_trig_inverse() { + let expr = "tan-1x"; + test_ClearSpeak("nb", "ClearSpeak_Trig", "TrigInverse",expr, + "tangens invers av x"); +} + +#[test] +fn inverse_trig_arc() { + let expr = "cosh-1x"; + test_ClearSpeak("nb", "ClearSpeak_Trig", "ArcTrig",expr, + "arcus cosinus hyperbolicus av x"); +} + +#[test] +fn trig_squared() { + let expr = "sin2x"; + test("nb", "ClearSpeak", expr, "sinus i andre av x"); +} + +#[test] +fn trig_cubed() { + let expr = "tan3x"; + test("nb", "ClearSpeak", expr, "tangens i tredje av x"); +} + +#[test] +fn trig_fourth() { + let expr = "sec4x"; + test("nb", "ClearSpeak", expr, "sekans opphøyd i 4, av x"); +} + + +#[test] +fn trig_power_other() { + let expr = "sinh>n-1x"; + test("nb", "ClearSpeak", expr, "sinus hyperbolicus opphøyd i n minus 1, av x"); +} + +#[test] +fn simple_log() { + let expr = " logx "; + test("nb", "ClearSpeak", expr, "log av x"); +} + +#[test] +fn normal_log() { + let expr = "log(x+y)"; + test("nb", "ClearSpeak", expr, "log av; startparentes; x pluss y; sluttparentes"); +} + +#[test] +fn simple_log_with_base() { + let expr = " logbx "; + test("nb", "ClearSpeak", expr, "logaritmen med grunntall b, av x"); +} + +#[test] +fn normal_log_with_base() { + let expr = "logb(x+y)"; + test("nb", "ClearSpeak", expr, "logaritmen med grunntall b, av; startparentes; x pluss y; sluttparentes"); +} + +#[test] +fn simple_ln() { + let expr = " lnx "; + test("nb", "ClearSpeak", expr, "l n av x"); +} + +#[test] +fn normal_ln() { + let expr = "ln(x+y)"; + test("nb", "ClearSpeak", expr, "l n av; startparentes; x pluss y; sluttparentes"); +} + + +#[test] +fn simple_natural_log() { + let expr = " lnx "; + test_ClearSpeak("nb", "ClearSpeak_Log", "LnAsNaturalLog",expr, + "den naturlige logaritmen av x"); +} + + +#[test] +fn natural_log() { + let expr = "ln(x+y)"; + test_ClearSpeak("nb", "ClearSpeak_Log", "LnAsNaturalLog",expr, + "den naturlige logaritmen av; startparentes; x pluss y; sluttparentes"); +} + + +#[test] +fn explicit_function_call_with_parens() { + let expr = "t⁡(x)"; + test("nb", "ClearSpeak", expr, "t av x"); +} + + +#[test] +fn explicit_times_with_parens() { + let expr = "t⁢(x)"; + test("nb", "ClearSpeak", expr, "t ganger x"); +} + +#[test] +fn explicit_function_call() { + let expr = "t⁡x"; + test("nb", "ClearSpeak", expr, "t av x"); +} + +#[test] +fn explicit_times() { + let expr = "t⁢x"; + test("nb", "ClearSpeak", expr, "t x"); +} + + +#[test] +fn test_functions_none_pref() { + let expr = " + log⁡(x+y) + + + f⁡(x+y) + "; + test_ClearSpeak("nb", "ClearSpeak_Functions", "None",expr, + "log av; startparentes; x pluss y; sluttparentes; pluss; f ganger; startparentes; x pluss y; sluttparentes"); +} + +#[test] +fn test_functions_none_pref_multiple_args() { + let expr = " + B ( 2,6 ) + "; + test_ClearSpeak("nb", "ClearSpeak_Functions", "None",expr, + "stor b ganger; startparentes; 2 komma, 6; sluttparentes"); +} + + +/* + * Tests for times + */ +#[test] +fn no_times_binomial() { + let expr = "x ⁢ y"; + test("nb", "ClearSpeak", expr, "x y"); +} + +#[test] +fn times_following_paren() { + let expr = " + 2 + ( 3 ) + "; + test("nb", "ClearSpeak", expr, "2 ganger 3"); +} + +#[test] +fn times_preceding_paren() { + let expr = " + ( 2 ) + 3 + "; + test("nb", "ClearSpeak", expr, "2 ganger 3"); +} + +#[test] +fn times_sqrt() { + let expr = " + a + b + = + ab + "; + test("nb", "ClearSpeak", expr, "kvadratroten av a; ganger kvadratroten av b; er lik kvadratroten av a b"); +} + +#[test] +fn more_implied_times() { + let expr = " + + + + ( + 2x + ) + 2 + + + "; + test_ClearSpeak("nb", "ClearSpeak_ImpliedTimes", "MoreImpliedTimes",expr, + ", startparentes; 2 ganger x; sluttparentes i andre"); +} + +#[test] +fn explicit_times_more_implied_times() { + let expr = "t⁢x"; + test_ClearSpeak("nb", "ClearSpeak_ImpliedTimes", "MoreImpliedTimes",expr, "t ganger x"); +} + +#[test] +fn explicit_times_none_simple_right() { + let expr = "2[3 ]"; + test_ClearSpeak("nb", "ClearSpeak_ImpliedTimes", "None", + expr, "2, start hakeparentes, 3, slutt hakeparentes"); +} + +#[test] +fn explicit_times_none_simple_left() { + let expr = "(2−1)x"; + test_ClearSpeak("nb", "ClearSpeak_ImpliedTimes", "None", + expr, ", startparentes; 2 minus 1; sluttparentes; x"); +} + +#[test] +fn explicit_times_none_superscript() { + let expr = " + f(x)= +x +2 + +( + +x+1 +) + "; + test_ClearSpeak_prefs("nb", + vec![("ClearSpeak_ImpliedTimes", "None"), ("ClearSpeak_Functions", "None")], + expr, "f; startparentes, x, sluttparentes; er lik; x i andre; startparentes; x pluss 1; sluttparentes"); +} + +/* + * Tests for parens + */ + #[test] + fn no_parens_number() { + let expr = " + ( + 25 + ) + x + "; + test("nb", "ClearSpeak", expr, "25 ganger x"); + } + + #[test] + fn no_parens_monomial() { + let expr = " + b + ( + xy + ) + "; + test("nb", "ClearSpeak", expr, "b; startparentes; x y, sluttparentes"); + } + + #[test] + fn no_parens_negative_number() { + let expr = " + 2+ + ( + −2 + ) + "; + test("nb", "ClearSpeak", expr, "2 pluss minus 2"); + } + + + #[test] + fn no_parens_negative_number_with_var() { + let expr = " + ( + −2x + ) + + +1 + "; + test("nb", "ClearSpeak", expr, "minus 2 x pluss 1"); + } + + #[test] + fn parens_superscript() { + let expr = " + + + + ( + 2x + ) + 2 + + + "; + test("nb", "ClearSpeak", expr, ", startparentes; 2 x, sluttparentes i andre"); + } + + #[test] + fn no_parens_fraction() { + let expr = " + 2 + + + + ( + 12 + ) + "; + test("nb", "ClearSpeak", expr, "2 pluss 1 halv"); + } + + + // Tests for the ten types of intervals in ClearSpeak + #[test] + fn parens_interval_open_open() { + let expr = " + ( + c,d + ) + "; + test_ClearSpeak("nb", "ClearSpeak_Paren", "Interval",expr, + "det åpne intervallet fra c til d"); +} + +#[test] + fn parens_interval_closed_open() { + let expr = " + [ + c,d + ) + "; + test_ClearSpeak("nb", "ClearSpeak_Paren", "Interval ",expr, + "det halvåpne intervallet fra og med c til d"); +} + + +#[test] +fn parens_interval_open_closed() { + let expr = " + ( + c,d + ] + "; + test_ClearSpeak("nb", "ClearSpeak_Paren", "Interval ",expr, + "det halvåpne intervallet fra c til og med d"); +} + + +#[test] +fn parens_interval_closed_closed() { + let expr = " + [ + c,d + ] +"; +test_ClearSpeak("nb", "ClearSpeak_Paren", "Interval ",expr, +"det lukkede intervallet fra c til d"); +} + + #[test] + fn parens_interval_neg_infinity_open_open() { + let expr = " + ( + - ∞,d + ) + "; + test_ClearSpeak("nb", "ClearSpeak_Paren", "Interval ",expr, + "det åpne intervallet fra minus uendelig til d"); +} + + #[test] + fn parens_interval_neg_infinity_closed_open() { + let expr = " + ( + - ∞,d + ] + "; + test_ClearSpeak("nb", "ClearSpeak_Paren", "Interval ",expr, + "det halvåpne intervallet fra minus uendelig til og med d"); +} + + +#[test] +fn parens_interval_open_open_infinity() { + let expr = " + ( + c,∞ + ) + "; + test_ClearSpeak("nb", "ClearSpeak_Paren", "Interval ",expr, + "det åpne intervallet fra c til uendelig"); +} + + +#[test] +fn parens_interval_closed_open_infinity() { + let expr = " + [ + c,∞ + ) + "; + test_ClearSpeak("nb", "ClearSpeak_Paren", "Interval ",expr, +"det halvåpne intervallet fra og med c til uendelig"); +} + +#[test] +fn parens_interval_neg_infinity_to_infinity() { + let expr = " + ( + - ∞,∞ + ) + "; + test_ClearSpeak("nb", "ClearSpeak_Paren", "Interval ",expr, + "det åpne intervallet fra minus uendelig til uendelig"); +} + +#[test] +fn parens_interval_neg_infinity_to_pos_infinity() { + let expr = " + ( + - ∞,+∞ + ) + "; + test_ClearSpeak("nb", "ClearSpeak_Paren", "Interval ",expr, + "det åpne intervallet fra minus uendelig til pluss uendelig"); +} diff --git a/tests/Languages/nb/ClearSpeak/large_ops.rs b/tests/Languages/nb/ClearSpeak/large_ops.rs new file mode 100644 index 000000000..ecfa9af7b --- /dev/null +++ b/tests/Languages/nb/ClearSpeak/large_ops.rs @@ -0,0 +1,200 @@ +use crate::common::*; + +#[test] +fn sum_both() { + let expr = " + + ∑ + n=1 + 10 + + n + "; + test("nb", "ClearSpeak", expr, "sum fra n er lik 1, til 10, av n"); +} + +#[test] +fn sum_under() { + let expr = " + + ∑ + S + + i + "; + test("nb", "ClearSpeak", expr, "sum over stor s, av i"); +} +#[test] +fn sum_both_msubsup() { + let expr = " + + ∑ + n=1 + 10 + + n + "; + test("nb", "ClearSpeak", expr, "sum fra n er lik 1, til 10, av n"); +} + +#[test] +fn sum_sub() { + let expr = " + + ∑ + S + + i + "; + test("nb", "ClearSpeak", expr, "sum over stor s, av i"); +} + +#[test] +fn sum() { + let expr = " + ∑ + ai + "; + test("nb", "ClearSpeak", expr, "sum av, a, senket i"); +} + +#[test] +fn product_both() { + let expr = " + + ∏ + n=1 + 10 + + n + "; + test("nb", "ClearSpeak", expr, "produktet fra n er lik 1, til 10, av n"); +} + +#[test] +fn product_under() { + let expr = " + + ∏ + S + + i + "; + test("nb", "ClearSpeak", expr, "produktet over stor s, av i"); +} + +#[test] +fn product() { + let expr = " + ∏ + ai + "; + test("nb", "ClearSpeak", expr, "produktet av, a, senket i"); +} + +#[test] +fn intersection_both() { + let expr = " + + ⋂ + i=1 + 10 + + Si + "; + test("nb", "ClearSpeak", expr, "snitt fra i er lik 1, til 10, av; stor s, senket i"); +} + +#[test] +fn intersection_under() { + let expr = " + + ⋂ + C + + Si + "; + test("nb", "ClearSpeak", expr, "snitt over stor c, av, stor s, senket i"); +} + +#[test] +fn intersection() { + let expr = " + ⋂ + Si + "; + test("nb", "ClearSpeak", expr, "snitt av, stor s, senket i"); +} + +#[test] +fn union_both() { + let expr = " + + ⋃ + i=1 + 10 + + Si + "; + test("nb", "ClearSpeak", expr, "union fra i er lik 1, til 10, av; stor s, senket i"); +} + +#[test] +fn union_under() { + let expr = " + + ⋃ + C + + Si + "; + test("nb", "ClearSpeak", expr, "union over stor c, av, stor s, senket i"); +} + +#[test] +fn union() { + let expr = " + ⋃ + Si + "; + test("nb", "ClearSpeak", expr, "union av, stor s, senket i"); +} + +#[test] +fn integral_both() { + let expr = " + + + ∫ + 0 + 1 + + f(x ) + +  dx + "; + test("nb", "ClearSpeak", expr, "integralet fra 0, til 1, av, f av x; d x"); +} + +#[test] +fn integral_under() { + let expr = " + + ∫ + ℝ + + f(x ) + dx + "; + test("nb", "ClearSpeak", expr, "integralet over de reelle tallene, av; f av x d x"); +} + +#[test] +fn integral() { + let expr = " + ∫ + f(x ) + dx + "; + test("nb", "ClearSpeak", expr, "integralet av, f av x d x"); +} \ No newline at end of file diff --git a/tests/Languages/nb/ClearSpeak/menclose.rs b/tests/Languages/nb/ClearSpeak/menclose.rs new file mode 100644 index 000000000..255988b52 --- /dev/null +++ b/tests/Languages/nb/ClearSpeak/menclose.rs @@ -0,0 +1,193 @@ +use crate::common::*; + +#[test] +fn menclose_actuarial() { + let expr = " + 3+2i + "; + test("nb", "ClearSpeak", expr, "aktuarielt symbol, omslutter 3 pluss 2 i, slutt omslutning"); +} + +#[test] +fn menclose_box() { + let expr = " + 3+2i + "; + test("nb", "ClearSpeak", expr, "boks, sirkel, omslutter 3 pluss 2 i, slutt omslutning"); +} + +#[test] +fn menclose_left() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "linje venstre, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_right() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "linje høyre, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_top_bottom() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "linje over, under, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_updiagonalstrike() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "diagonalt oppover, utstryking, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_downdiagonalstrike() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "diagonalt nedover, utstryking, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_cross_out() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "kryss, utstryking, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_vertical_horizontal_strike() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "vertikal, horisontal, utstryking, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_leftarrow() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "venstrepil, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_right_up_down_arrow() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "oppoverpil, nedoverpil, høyrepil, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_northeastarrow() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "nordøst-pil, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_other_single_arrows() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "sørøst-pil, sørvest-pil, nordvest-pil, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_northwestsoutheastarrow() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "dobbelendet diagonal nedoverpil, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_other_double_arrows() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "dobbelendet vertikal pil, dobbelendet horisontal pil, dobbelendet diagonal oppoverpil, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_madrub() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "arabisk fakultet, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_phasorangle() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "fasevinkel, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_circle_phasorangle() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "sirkel, fasevinkel, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_longdiv() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "lang divisjon, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_longdiv_default() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "lang divisjon, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_longdiv_empty_string() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "lang divisjon, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_longdiv_whitespace_string() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "lang divisjon, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn menclose_radical() { + let expr = " + 32 + "; + test("nb", "ClearSpeak", expr, "kvadratrot, omslutter 3 halve, slutt omslutning"); +} + +#[test] +fn simple_speak_menclose_top_bottom() { + let expr = " + 32 + "; + test("nb", "SimpleSpeak", expr, "linje over, under, omslutter 3 halve, slutt omslutning"); +} diff --git a/tests/Languages/nb/ClearSpeak/mfrac.rs b/tests/Languages/nb/ClearSpeak/mfrac.rs new file mode 100644 index 000000000..db11bb43d --- /dev/null +++ b/tests/Languages/nb/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("nb", "ClearSpeak", expr, "1 halv"); +} + +#[test] +fn common_fraction_thirds() { + let expr = " + 2 3 + "; + test("nb", "ClearSpeak", expr, "2 tredjedeler"); +} + +#[test] +fn common_fraction_tenths() { + let expr = " + 17 10 + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr, "17 tideler"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Ordinal")], expr, "17 tideler"); +} + +#[test] +#[allow(non_snake_case)] +fn not_ClearSpeak_common_fraction_tenths() { + let expr = " + 89 10 + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr, "89 over 10"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Ordinal")], expr, "89 tideler"); +} + +#[test] +fn non_simple_fraction() { + let expr = " + + + + + x+y + + x-y + + + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr, "brøken med teller; x pluss y; og nevner x minus y"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Ordinal")], expr, "brøken med teller; x pluss y; og nevner x minus y"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Over")], expr, "x pluss y over x minus y"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "FracOver")], expr, "brøken x pluss y over x minus y"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "General")], expr, "brøken med teller; x pluss y; og nevner x minus y"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "EndFrac")], expr, "brøken med teller; x pluss y; og nevner x minus y; slutt brøk"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "GeneralEndFrac")], expr, "brøken med teller; x pluss y; og nevner x minus y; slutt brøk"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "OverEndFrac")], expr, "x pluss y over x minus y, slutt brøk"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Per")], expr, "x pluss y per x minus y"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Verbose"),("ClearSpeak_Fractions", "Auto")], expr, "brøken med teller; x pluss y; og nevner x minus y; slutt brøk"); +} + +#[test] +fn frac_with_units() { + let expr = " + + + 62 + + mi + hr + + + "; + test("nb", "ClearSpeak", expr, "62 miles per time"); +} + + +#[test] +fn mixed_number() { + let expr = " + 3 + 1 2 + "; + test("nb", "ClearSpeak", expr, "3 og 1 halv"); +} + +#[test] +fn explicit_mixed_number() { + let expr = " + 3 + ⁤ + 1 8 + "; + test("nb", "ClearSpeak", expr, "3 og 1 åttedel"); +} + +#[test] +fn mixed_number_big() { + let expr = " + 3 + 7 83 + "; + test("nb", "ClearSpeak", expr, "3 og 7 over 83"); +} + +#[test] +fn simple_text() { + let expr = " + rise run + "; + test("nb", "ClearSpeak", expr, ", rise over run"); +} + +#[test] +fn number_and_text() { + let expr = " + + + 2miles + + 3gallons + + "; + test("nb", "ClearSpeak", expr, ", 2 miles over 3 gallons"); +} + + +#[test] +fn nested_simple_fractions() { + let expr = " + + + + + 1 + 2 + + + + + 2 + 3 + + + + + "; + test_prefs("nb", "ClearSpeak", vec![("ClearSpeak_Fractions", "Auto")], expr, "1 halv over 2 tredjedeler"); + test_prefs("nb", "ClearSpeak", vec![("ClearSpeak_Fractions", "Ordinal")], expr, "1 halv over 2 tredjedeler"); + test_prefs("nb", "ClearSpeak", vec![("ClearSpeak_Fractions", "Over")], expr, "1 over 2 over 2 over 3"); + test_prefs("nb", "ClearSpeak", vec![("ClearSpeak_Fractions", "FracOver")], expr, + "brøken brøken 1 over 2 over brøken 2 over 3"); + test_prefs("nb", "ClearSpeak", vec![("ClearSpeak_Fractions", "General")], expr, + "brøken med teller brøken med teller 1; og nevner 2; og nevner brøken med teller 2; og nevner 3"); + test_prefs("nb", "ClearSpeak", vec![("ClearSpeak_Fractions", "EndFrac")], expr, "1 halv over 2 tredjedeler"); + test_prefs("nb", "ClearSpeak", vec![("ClearSpeak_Fractions", "GeneralEndFrac")], expr, + "brøken med teller brøken med teller 1; og nevner 2; slutt brøk; og nevner brøken med teller 2; og nevner 3; slutt brøk; slutt brøk"); + test_prefs("nb", "ClearSpeak", vec![("ClearSpeak_Fractions", "OverEndFrac")], expr, + "1 over 2, slutt brøk, over 2 over 3, slutt brøk; slutt brøk"); +} + + +#[test] +fn semi_nested_fraction() { + let expr = " + + + + + 2 + 3 + + x + + 6 + + + "; + test("nb", "ClearSpeak", expr, "2 tredjedeler x over 6"); +} + +#[test] +fn general_nested_fraction() { + let expr = " + + + + + + 10 + n + + + + + 2 + n + + + + + + "; + test("nb", "ClearSpeak", expr, "brøken med teller; 10 over n; og nevner 2 over n"); +} + +#[test] +fn complex_nested_fraction() { + let expr = " + + + + + + n + 10 + n + + + + + 2 + n + + + + + + "; + test("nb", "ClearSpeak", expr, "brøken med teller; brøken med teller; n pluss 10; og nevner n; og nevner 2 over n"); +} + +#[test] +fn simple_function() { + let expr = "f(x)2"; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr, "f av x over 2"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Verbose"), ("ClearSpeak_Fractions", "Auto")], expr, "f av x over 2, slutt brøk"); +} + +#[test] +fn function_over_function() { + let expr = " + f(x) + g(x) + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr, "f av x over g av x"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Verbose"), ("ClearSpeak_Fractions", "Auto")], expr, "f av x over g av x, slutt brøk"); +} + +#[test] +fn non_simple_function_over_function() { + let expr = " + f(x+1) + g(x) + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr, + "brøken med teller; f av; startparentes; x pluss 1; sluttparentes; og nevner g av x"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Verbose"), ("ClearSpeak_Fractions", "Auto")], expr, + "brøken med teller; f av; startparentes; x pluss 1; sluttparentes; og nevner g av x; slutt brøk"); +} + +#[test] +fn binomial() { + let expr = " + 2 + ( + 7 3 + ) + "; + test("nb", "ClearSpeak", expr, "2 ganger 7 over 3"); +} diff --git a/tests/Languages/nb/ClearSpeak/mroot.rs b/tests/Languages/nb/ClearSpeak/mroot.rs new file mode 100644 index 000000000..8e09b64de --- /dev/null +++ b/tests/Languages/nb/ClearSpeak/mroot.rs @@ -0,0 +1,132 @@ +use crate::common::*; + +#[test] +fn msqrt_simple() { + let expr = " + x + "; + test("nb", "ClearSpeak", expr, "kvadratroten av x"); +} + +#[test] +fn msqrt_simple_end_root() { + let expr = " + x + "; + test_ClearSpeak("nb", "ClearSpeak_Roots", "RootEnd", expr, "kvadratroten av x, slutt rot"); +} + +#[test] +fn msqrt_simple_positive() { + let expr = " + x + "; + test_ClearSpeak("nb", "ClearSpeak_Roots", "PosNegSqRoot", expr, "den positive kvadratroten av x"); +} + +#[test] +fn msqrt_simple_pos_end_root() { + let expr = " + x + "; + test_ClearSpeak("nb", "ClearSpeak_Roots", "PosNegSqRootEnd", expr, "den positive kvadratroten av x, slutt rot"); +} + +#[test] +fn msqrt_simple_pos_end_with_neg_root() { + let expr = " + - x + - x 3 + "; + test_ClearSpeak("nb", "ClearSpeak_Roots", "PosNegSqRootEnd", expr, + "den negative kvadratroten av x, slutt rot; minus, den positive kubikkroten av x, slutt rot"); +} + +#[test] +fn mroot_simple_pos_end_with_neg_root() { + let expr = " + - x 3 + - x + + "; + test_ClearSpeak("nb", "ClearSpeak_Roots", "PosNegSqRoot", expr, + "den negative kubikkroten av x; minus den positive kvadratroten av x"); +} + +#[test] +fn neg_without_root() { + let expr = " + - x - y + "; + test("nb", "ClearSpeak", expr, "minus x minus y"); +} + +#[test] +fn msqrt() { + let expr = " + + x + y + + "; + test("nb", "ClearSpeak", expr, "kvadratroten av x pluss y"); +} + +#[test] +fn mroot_as_square_root() { + let expr = " + x 2 + "; + test("nb", "ClearSpeak", expr, "kvadratroten av x"); +} + +#[test] +fn cube_root() { + let expr = " + x 3 + "; + test("nb", "ClearSpeak", expr, "kubikkroten av x"); +} + +#[test] +fn ordinal_root() { + let expr = " + x 9 + "; + test("nb", "ClearSpeak", expr, "niende roten av x"); +} + +#[test] +fn simple_mi_root() { + let expr = " + x n + "; + test("nb", "ClearSpeak", expr, "roten av grad n, av x"); +} + +#[test] +fn mroot_simple_pos_end_root() { + let expr = " + x t + "; + test_ClearSpeak("nb", "ClearSpeak_Roots", "PosNegSqRootEnd", expr, "den positive roten av grad t, av x, slutt rot"); +} + +#[test] +fn mroot_simple_end_root() { + let expr = " + x + y + 21 + "; + test_ClearSpeak("nb", "ClearSpeak_Roots", "RootEnd", expr, "tjue første roten av x pluss y, slutt rot"); +} + +#[test] +fn simple_fraction_power() { + let expr = " + + x + 13 + + "; + test("nb", "ClearSpeak", expr, "roten av grad 1 tredjedel, av x"); +} diff --git a/tests/Languages/nb/ClearSpeak/msup.rs b/tests/Languages/nb/ClearSpeak/msup.rs new file mode 100644 index 000000000..f008bbdb0 --- /dev/null +++ b/tests/Languages/nb/ClearSpeak/msup.rs @@ -0,0 +1,341 @@ +/// Tests for superscripts +/// simple superscripts +/// complex/nested superscripts +use crate::common::*; + +#[test] +fn squared() { + let expr = " + x 2 + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "x i andre"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "x opphøyd i 2"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "x opphøyd i 2"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "x opphøyd i 2"); + +} + +#[test] +fn cubed() { + let expr = " + x 3 + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "x i tredje"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "x opphøyd i 3"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "x opphøyd i 3"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "x opphøyd i 3"); +} + +#[test] +fn ordinal_power() { + let expr = " + 3 5 + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 opphøyd i 5"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 opphøyd i 5"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 opphøyd i 5"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 opphøyd i 5"); +} + + +#[test] +fn zero_power() { + let expr = " + 3 0 + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 opphøyd i 0"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 opphøyd i 0"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 opphøyd i 0"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 opphøyd i 0"); +} + +#[test] +fn simple_mi_power() { + let expr = " + 4 x + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "4 opphøyd i x"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "4 opphøyd i x"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "4 opphøyd i x"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "4 opphøyd i x"); +} + +#[test] +fn decimal_power() { + let expr = " + 3 5,0 + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 opphøyd i 5,0"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 opphøyd i 5,0"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 opphøyd i 5,0"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 opphøyd i 5,0"); +} + +#[test] +fn non_simple_power() { + let expr = " + 3 y+2 + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 opphøyd i y pluss 2"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 opphøyd i y pluss 2"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 opphøyd i y pluss 2"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 opphøyd i y pluss 2"); +} + +#[test] +fn negative_power() { + let expr = " + 3 - 2 + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 opphøyd i minus 2"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 opphøyd i minus 2"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 opphøyd i minus 2"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 opphøyd i minus 2"); +} + +#[test] +fn simple_fraction_power() { + let expr = " + + x + 13 + + "; + test("nb", "ClearSpeak", expr, "x opphøyd i 1 tredjedel"); +} + +#[test] +fn nested_squared_power_with_coef() { + let expr = " + + + 3 + + 2 + + x + 2 + + + + + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 opphøyd i 2 x i andre"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 opphøyd i eksponenten, 2 x opphøyd i 2; slutt eksponent"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 opphøyd i eksponenten, 2 x opphøyd i 2; slutt eksponent"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 opphøyd i eksponenten, 2 x opphøyd i 2; slutt eksponent"); + +} + +#[test] +fn nested_squared_power_with_neg_coef() { + let expr = " + + + 3 + + - + 2 + + x + 2 + + + + + "; + test("nb", "ClearSpeak", expr, "3 opphøyd i minus 2 x i andre"); +} + + +#[test] +fn nested_cubed_power() { + let expr = " + + y + + 45 + 3 + + + "; + test("nb", "ClearSpeak", expr, "y opphøyd i 4 femtedeler i tredje"); +} + +#[test] +fn nested_cubed_power_with_neg_base() { + let expr = " + + y + + - + + 45 + 3 + + + + "; + test("nb", "ClearSpeak", expr, "y opphøyd i minus 4 femtedeler i tredje"); +} + +#[test] +fn nested_number_times_squared() { + let expr = " + + + e + + + 1 + 2 + + + x + 2 + + + + + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "e opphøyd i 1 halv x i andre"); +} + +#[test] +fn nested_negative_number_times_squared() { + let expr = " + + + e + + − + 1 + 2 + + + x + 2 + + + + + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "e opphøyd i minus 1 halv x i andre"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "e opphøyd i eksponenten, minus 1 halv x opphøyd i 2; slutt eksponent"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "e opphøyd i eksponenten, minus 1 halv x opphøyd i 2; slutt eksponent"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "e opphøyd i eksponenten, minus 1 halv x opphøyd i 2; slutt eksponent"); +} + +#[test] +fn nested_expr_to_tenth() { + let expr = " + + + 3 + + + 3 + + 10 + + + + + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 opphøyd i eksponenten, 3 opphøyd i 10; slutt eksponent"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 opphøyd i eksponenten, 3 opphøyd i 10; slutt eksponent"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 opphøyd i eksponenten, 3 opphøyd i 10; slutt eksponent"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 opphøyd i eksponenten, 3 opphøyd i 10; slutt eksponent"); + +} + +#[test] +fn nested_non_simple_squared_exp() { + let expr = " + + + 3 + + + + ( + + x+1 + ) + 2 + + + + + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 opphøyd i eksponenten; startparentes; x pluss 1; sluttparentes i andre, slutt eksponent"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 opphøyd i eksponenten; startparentes; x pluss 1; sluttparentes opphøyd i 2; slutt eksponent"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 opphøyd i eksponenten; startparentes; x pluss 1; sluttparentes opphøyd i 2; slutt eksponent"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 opphøyd i eksponenten; startparentes; x pluss 1; sluttparentes opphøyd i 2; slutt eksponent"); +} + +#[test] +fn nested_default_power() { + let expr = " + + t + + 45 + n + + +"; + test("nb", "ClearSpeak", expr, "t opphøyd i eksponenten, 4 femtedeler opphøyd i n; slutt eksponent"); +} + +#[test] +fn nested_complex_power() { + let expr = " + + + e + + − + 1 + 2 + + + + ( + + + + x−μ + σ + + + ) + 2 + + + + + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, + "e opphøyd i eksponenten, minus 1 halv ganger; startparentes; brøken med teller; x minus my; og nevner sigma; sluttparentes i andre, slutt eksponent"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, + "e opphøyd i eksponenten, minus 1 halv ganger; startparentes; brøken med teller; x minus my; og nevner sigma; sluttparentes opphøyd i 2; slutt eksponent"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, + "e opphøyd i eksponenten, minus 1 halv ganger; startparentes; brøken med teller; x minus my; og nevner sigma; sluttparentes opphøyd i 2; slutt eksponent"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, + "e opphøyd i eksponenten, minus 1 halv ganger; startparentes; brøken med teller; x minus my; og nevner sigma; sluttparentes opphøyd i 2; slutt eksponent"); +} + +#[test] +fn default_power() { + let expr = " + + t + + b+1 + 3 + + + "; + test("nb", "ClearSpeak", expr, "t opphøyd i brøken med teller; b pluss 1; og nevner 3"); +} diff --git a/tests/Languages/nb/ClearSpeak/multiline.rs b/tests/Languages/nb/ClearSpeak/multiline.rs new file mode 100644 index 000000000..6484899a8 --- /dev/null +++ b/tests/Languages/nb/ClearSpeak/multiline.rs @@ -0,0 +1,177 @@ +use crate::common::*; + +#[test] +fn case_1() { + let expr = " + f + + ( + x + ) + + = + + { + + -1ifx<0 + 0ifx=0 + 1ifx>0 + + + + "; + test_ClearSpeak("nb", "ClearSpeak_MultiLineLabel", "Auto", expr, + "f av x er lik; 3 tilfeller; \ + tilfelle 1; minus 1 if x er mindre enn 0; \ + tilfelle 2; 0 if x er lik 0; \ + tilfelle 3; 1 if x er større enn 0" + ) +} + +#[test] +fn equation_auto() { + let expr = " + + + x+y = 7 + 2x+3y = 17 + + + "; + test_ClearSpeak("nb", "ClearSpeak_MultiLineLabel", "Auto", expr, + "2 rader; \ + rad 1; x pluss y er lik 7; \ + rad 2; 2 x pluss 3 y; er lik 17"); +} + + +#[test] +fn equation_plus_at_start() { + let expr = " + + + x+y = 7 + 2x+3y = 17 + + + "; + test_ClearSpeak("nb", "ClearSpeak_MultiLineLabel", "Auto", expr, "2 rader; \ + rad 1; x pluss y er lik 7; \ + rad 2; 2 x, pluss 3 y, er lik 17"); +} + +#[test] +fn equation_case() { + let expr = " + + + x+y = 7 + 2x+3y = 17 + + + "; + test_ClearSpeak("nb", "ClearSpeak_MultiLineLabel", "Case", expr, + "2 tilfeller; tilfelle 1; x pluss y er lik 7; tilfelle 2; 2 x pluss 3 y; er lik 17"); +} + +#[test] +fn equation_constraint() { + let expr = " + + + x+y = 7 + 2x+3y = 17 + + + "; + test_ClearSpeak("nb", "ClearSpeak_MultiLineLabel", "Constraint", expr, "2 betingelser; \ + betingelse 1; x pluss y er lik 7; \ + betingelse 2; 2 x pluss 3 y; er lik 17"); +} + +#[test] +fn equation_equation() { + let expr = " + + + x+y = 7 + 2x+3y = 17 + + + "; + test_ClearSpeak("nb", "ClearSpeak_MultiLineLabel", "Equation", expr, "2 likninger; \ + likning 1; x pluss y er lik 7; \ + likning 2; 2 x pluss 3 y; er lik 17"); +} + +#[test] +fn equation_line() { + let expr = " + + + x+y = 7 + 2x+3y = 17 + + + "; + test_ClearSpeak("nb", "ClearSpeak_MultiLineLabel", "Line", expr, "2 rader; \ + rad 1; x pluss y er lik 7; \ + rad 2; 2 x pluss 3 y; er lik 17"); +} + +#[test] +fn equation_none() { + let expr = " + + + x+y = 7 + 2x+3y = 17 + + + "; + test_ClearSpeak("nb", "ClearSpeak_MultiLineLabel", "None", expr, + "2; x pluss y er lik 7; 2 x pluss 3 y; er lik 17"); +} + +#[test] +fn equation_row() { + let expr = " + + + x+y = 7 + 2x+3y = 17 + + + "; + test_ClearSpeak("nb", "ClearSpeak_MultiLineLabel", "Row", expr, "2 rader; \ + rad 1; x pluss y er lik 7; \ + rad 2; 2 x pluss 3 y; er lik 17"); +} + +#[test] +fn equation_step() { + let expr = " + + + x+y = 7 + 2x+3y = 17 + + + "; + test_ClearSpeak("nb", "ClearSpeak_MultiLineLabel", "Step", expr, "2 steg; \ + steg 1; x pluss y er lik 7; \ + steg 2; 2 x pluss 3 y; er lik 17"); +} + +#[test] +fn continued_row() { + let expr = " + + x=y + +1 + y=1 + +"; +test("nb", "SimpleSpeak", expr, + "2 likninger; likning 1; x er lik y pluss 1; likning 2; y er lik 1"); +} diff --git a/tests/Languages/nb/ClearSpeak/sets.rs b/tests/Languages/nb/ClearSpeak/sets.rs new file mode 100644 index 000000000..94687b741 --- /dev/null +++ b/tests/Languages/nb/ClearSpeak/sets.rs @@ -0,0 +1,452 @@ +use crate::common::*; + +#[test] +fn complex() { + let expr = " + ℂ + "; + test("nb", "ClearSpeak", expr, "de komplekse tallene"); +} + +#[test] +fn natural() { + let expr = " + ℕ + "; + test("nb", "ClearSpeak", expr, "de naturlige tallene"); +} + +#[test] +fn rationals() { + let expr = " + ℚ + "; + test("nb", "ClearSpeak", expr, "de rasjonale tallene"); +} + +#[test] +fn reals() { + let expr = " + ℝ + "; + test("nb", "ClearSpeak", expr, "de reelle tallene"); +} + +#[test] +fn integers() { + let expr = " + ℤ + "; + test("nb", "ClearSpeak", expr, "heltallene"); +} + + + +#[test] +fn msup_complex() { + let expr = " + + ℂ + 2 + + "; + test("nb", "ClearSpeak", expr, "C 2"); +} + +#[test] +fn msup_natural() { + let expr = " + + ℕ + 2 + + "; + test("nb", "ClearSpeak", expr, "N 2"); +} + +#[test] +fn msup_rationals() { + let expr = " + + ℚ + 2 + + "; + test("nb", "ClearSpeak", expr, "Q 2"); +} + +#[test] +fn msup_reals() { + let expr = " + + ℝ + 3 + + "; + test("nb", "ClearSpeak", expr, "R 3"); +} + +#[test] +fn msup_integers() { + let expr = " + + ℤ + 4 + + "; + test("nb", "ClearSpeak", expr, "Z 4"); +} + +#[test] +fn msup_positive_integers() { + let expr = " + + ℤ + + + + "; + test("nb", "ClearSpeak", expr, "de positive heltallene"); +} + +#[test] +fn msup_negative_integers() { + let expr = " + + ℤ + - + + "; + test("nb", "ClearSpeak", expr, "de negative heltallene"); +} + +#[test] +fn msup_positive_rationals() { + let expr = " + + ℚ + + + + "; + test("nb", "ClearSpeak", expr, "de positive rasjonale tallene"); +} + +#[test] +fn msup_negative_rationals() { + let expr = " + + ℚ + - + + "; + test("nb", "ClearSpeak", expr, "de negative rasjonale tallene"); +} + +#[test] +fn empty_set() { + let expr = " + { } + "; + test("nb", "ClearSpeak", expr, "den tomme mengden"); +} + +#[test] +fn single_element_set() { + let expr = " + { 12} + "; + test("nb", "ClearSpeak", expr, "mengden 12"); +} + +#[test] +fn multiple_element_set() { + let expr = " + { 5 , 10 , 15 } + "; + test("nb", "ClearSpeak", expr, "mengden 5 komma, 10 komma, 15"); +} + +#[test] +fn set_with_colon() { + let expr = " + { x:x>2 } + "; + test("nb", "ClearSpeak", expr, "mengden av alle x slik at x er større enn 2"); +} + +#[test] +fn set_with_bar() { + let expr = " + { x|x>2 } + "; + test("nb", "ClearSpeak", expr, "mengden av alle x slik at x er større enn 2"); +} + +#[test] +fn element_alone() { + let expr = " + 3+2i∉ℝ + "; + test("nb", "ClearSpeak", expr, "3 pluss 2 i, er ikke et element i, de reelle tallene"); +} + +#[test] +fn element_under_sum() { + let expr = " + + ∑ + i ∈ ℤ + + + 1 + i 2 + + "; + test("nb", "ClearSpeak", expr, + "sum over i i heltallene, av; brøken med teller 1; og nevner i i andre"); +} + +#[test] +fn complicated_set_with_colon() { + let expr = " + { + x + ∈ + ℤ + : + 2 + < + x + < + 7 + } + "; + test("nb", "ClearSpeak", expr, "mengden av alle x i heltallene slik at 2 er mindre enn x er mindre enn 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("nb", "ClearSpeak", expr, + "mengden av alle x i de naturlige tallene slik at x is an even number"); +} + + +#[test] +fn set_with_bar_member() { + let expr = " + { + x + ∈ + ℤ + : + x + > + 5 + } + "; + test_ClearSpeak("nb", "ClearSpeak_SetMemberSymbol", "Member", + expr, "mengden av alle x tilhørende heltallene slik at x er større enn 5"); +} + +#[test] +fn element_alone_member() { + let expr = " + 3+2i∉ℝ + "; + test_ClearSpeak("nb", "ClearSpeak_SetMemberSymbol", "Member", + expr, "3 pluss 2 i, tilhører ikke de reelle tallene"); +} + +#[test] +fn element_under_sum_member() { + let expr = " + + ∑ + i ∈ ℤ + + + 1 + i 2 + + "; + test_ClearSpeak("nb", "ClearSpeak_SetMemberSymbol", "Member", + expr, "sum over i tilhører heltallene, av; brøken med teller 1; og nevner i i andre"); +} + + +#[test] +fn set_with_bar_element() { + let expr = " + { + x + ∈ + ℤ + : + x + > + 5 + } + "; + test_ClearSpeak("nb", "ClearSpeak_SetMemberSymbol", "Element", + expr, "mengden av alle x element i heltallene slik at x er større enn 5"); +} + +#[test] +fn element_alone_element() { + let expr = " + 3+2i∉ℝ + "; + test_ClearSpeak("nb", "ClearSpeak_SetMemberSymbol", "Element", + expr, "3 pluss 2 i, er ikke et element i, de reelle tallene"); +} + +#[test] +fn element_under_sum_element() { + let expr = " + + ∑ + i ∈ ℤ + + + 1 + i 2 + + "; + test_ClearSpeak("nb", "ClearSpeak_SetMemberSymbol", "Element", + expr, "sum over i er et element i heltallene, av; brøken med teller 1; og nevner i i andre"); +} + +#[test] +fn set_with_bar_in() { + let expr = " + { + x + ∈ + ℤ + : + x + > + 5 + } + "; + test_ClearSpeak("nb", "ClearSpeak_SetMemberSymbol", "In", + expr, "mengden av alle x i heltallene slik at x er større enn 5"); +} + +#[test] +fn element_alone_in() { + let expr = " + 3+2i∉ℝ + "; + test_ClearSpeak("nb", "ClearSpeak_SetMemberSymbol", "In", + expr, "3 pluss 2 i, er ikke i de reelle tallene"); +} + +#[test] +fn element_under_sum_in() { + let expr = " + + ∑ + i ∈ ℤ + + + 1 + i 2 + + "; + test_ClearSpeak("nb", "ClearSpeak_SetMemberSymbol", "In", + expr, "sum over i i heltallene, av; brøken med teller 1; og nevner i i andre"); +} + +#[test] +fn set_with_bar_belongs() { + let expr = " + { + x + ∈ + ℤ + : + x + > + 5 + } + "; + test_ClearSpeak("nb", "ClearSpeak_SetMemberSymbol", "Belongs", + expr, "mengden av alle x tilhørende heltallene slik at x er større enn 5"); +} + +#[test] +fn element_alone_belongs() { + let expr = " + 3+2i∉ℝ + "; + test_ClearSpeak("nb", "ClearSpeak_SetMemberSymbol", "Belongs", + expr, "3 pluss 2 i, tilhører ikke de reelle tallene"); +} + +#[test] +fn element_under_sum_belongs() { + let expr = " + + ∑ + i ∈ ℤ + + + 1 + i 2 + + "; + test_ClearSpeak("nb", "ClearSpeak_SetMemberSymbol", "Belongs", + expr, "sum over i tilhører heltallene, av; brøken med teller 1; og nevner i i andre"); +} + + +#[test] +fn set_member_woall() { + let expr = " + { + x + ∈ + ℤ + : + x + > + 5 + } + "; + test_ClearSpeak_prefs("nb", vec![("ClearSpeak_SetMemberSymbol", "Member"), ("ClearSpeak_Sets", "woAll")], + expr, "mengden av x tilhørende heltallene slik at x er større enn 5"); +} + +#[test] +fn multiple_element_set_woall() { + let expr = " + { 5 , 10 , 15 } + "; + test_ClearSpeak("nb", "ClearSpeak_Sets", "woAll", expr, "mengden 5 komma, 10 komma, 15"); +} + +#[test] +fn multiple_element_set_silent_bracket() { + let expr = " + { 5 , 10 , 15 } + "; + test_ClearSpeak("nb", "ClearSpeak_Sets", "SilentBracket", expr, "5 komma, 10 komma, 15"); + } + +#[test] +fn silent_bracket() { + let expr = " + {x|x>2} + "; + test_ClearSpeak("nb", "ClearSpeak_Sets", "SilentBracket", expr, + "mengden av alle x slik at x er større enn 2"); + } + diff --git a/tests/Languages/nb/ClearSpeak/symbols_and_adornments.rs b/tests/Languages/nb/ClearSpeak/symbols_and_adornments.rs new file mode 100644 index 000000000..a5d66a96e --- /dev/null +++ b/tests/Languages/nb/ClearSpeak/symbols_and_adornments.rs @@ -0,0 +1,331 @@ +use crate::common::*; + +#[test] +fn multiplication() { + let expr = " + 2×3 + "; + test("nb", "ClearSpeak", expr, "2 ganger 3"); +} + +#[test] +fn multiplication_by() { + let expr = " + 2×3 + "; + test_ClearSpeak("nb", "ClearSpeak_MultSymbolX", "By", expr, "2 ganger 3"); +} + +#[test] +fn multiplication_cross() { + let expr = " + u×v + "; + test_ClearSpeak("nb", "ClearSpeak_MultSymbolX", "Cross", expr, "u kryss v"); +} + +#[test] +fn ellipses_auto_start() { + let expr = " + …, + -2,-1,0 + "; + test("nb", "ClearSpeak", expr, "prikk prikk prikk komma, minus 2 komma, minus 1 komma, 0"); +} + +#[test] +fn ellipses_auto_end() { + let expr = " + 1 + , + 2 + , + 3 + , + … + "; + test_ClearSpeak("nb", "ClearSpeak_Ellipses", "Auto", expr, "1 komma, 2 komma, 3 komma, prikk prikk prikk"); +} + +#[test] +fn ellipses_auto_middle() { + let expr = " + + 1 + , + 2 + , + 3 + , + … + , + 20 + + "; + test_ClearSpeak("nb", "ClearSpeak_Ellipses", "Auto", expr, + "1 komma, 2 komma, 3 komma, prikk prikk prikk komma, 20"); +} + +#[test] +fn ellipses_auto_both() { + let expr = " + …, + -2,-1,0,1,2 + ,… + "; + test_ClearSpeak("nb", "ClearSpeak_Ellipses", "Auto", expr, + "prikk prikk prikk komma, minus 2 komma, minus 1 komma, 0 komma, 1 komma, 2 komma, prikk prikk prikk"); +} + +#[test] +fn ellipses_and_so_on_start() { + let expr = " + …, + -2,-1,0 + "; + test_ClearSpeak("nb", "ClearSpeak_Ellipses", "AndSoOn", expr, "prikk prikk prikk komma, minus 2 komma, minus 1 komma, 0"); +} + +#[test] +fn ellipses_and_so_on_end() { + let expr = " + 1 + , + 2 + , + 3 + , + … + "; + test_ClearSpeak("nb", "ClearSpeak_Ellipses", "AndSoOn", expr, "1 komma, 2 komma, 3 og så videre"); +} + +#[test] +fn ellipses_and_so_on_middle() { + let expr = " + + 1 + , + 2 + , + 3 + , + … + , + 20 + + "; + test_ClearSpeak("nb", "ClearSpeak_Ellipses", "AndSoOn", expr, + "1 komma, 2 komma, 3 og så videre opp til, 20"); +} + +#[test] +fn ellipses_and_so_on_both() { + let expr = " + …, + -2,-1,0,1,2 + ,… + "; + test_ClearSpeak("nb", "ClearSpeak_Ellipses", "AndSoOn", expr, + "prikk prikk prikk komma, minus 2 komma, minus 1 komma, 0 komma, 1 komma, 2 komma, prikk prikk prikk"); +} + +#[test] +fn vertical_line_auto() { + let expr = " + 3|6 + "; + test_ClearSpeak("nb", "ClearSpeak_VerticalLine", "Auto", expr, + "3 deler 6"); +} + +#[test] +fn vertical_line_divides() { + let expr = " + 3|6 + "; + test_ClearSpeak("nb", "ClearSpeak_VerticalLine", "Divides", expr, + "3 deler 6"); +} + + #[test] + fn vertical_line_given() { + let expr = " + 3|6 + "; + test_ClearSpeak("nb", "ClearSpeak_VerticalLine", "Given", expr, + "3, gitt 6"); + } + + #[test] + fn vertical_line_probability_given() { + let expr = " + P + + ( + + A + | + B + + ) + + "; + test_ClearSpeak_prefs("nb", vec![("ClearSpeak_VerticalLine", "Given"), ("ClearSpeak_ImpliedTimes", "None")] + , expr, "stor p; startparentes; stor a, gitt stor b; sluttparentes"); + } + +#[test] +fn vertical_line_set() { + let expr = " + { + + x + | + x + > + 0 + + } + "; + test_ClearSpeak("nb", "ClearSpeak_VerticalLine", "Auto", expr, + "mengden av alle x slik at x er større enn 0"); +} + + +#[test] +fn vertical_line_set_such_that() { + let expr = " + { + + x + | + x + > + 0 + + } + "; + test_ClearSpeak("nb", "ClearSpeak_VerticalLine", "SuchThat", expr, + "mengden av alle x slik at x er større enn 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("nb", "ClearSpeak_VerticalLine", "Given", expr, + "mengden av alle x slik at x er større enn 0"); +} + +#[test] +fn vertical_line_set_and_abs() { + let expr = " + { + + x + | + + | + x + | + + > + 2 + + } + "; + test_ClearSpeak("nb", "ClearSpeak_VerticalLine", "Auto", expr, + "mengden av alle x slik at absoluttverdien av x; er større enn 2"); +} + +#[test] +fn vertical_line_evaluated_at() { + let expr = " + f + + ( + x + ) + + + | + + x + = + 5 + + + "; + test_ClearSpeak("nb", "ClearSpeak_VerticalLine", "Auto", expr, + "f av x evaluert i x er lik 5"); +} + +#[test] +fn vertical_line_evaluated_at_both() { + let expr = " + + x + 2 + + + + x + + | + 0 + 1 + + "; + test_ClearSpeak("nb", "ClearSpeak_VerticalLine", "Auto", expr, + "x i andre pluss x, evaluert for øvre verdi, 1, og nedre verdi, 0"); +} +#[test] +fn vertical_line_evaluated_at_divides() { + let expr = " + f + + ( + x + ) + + + | + + x + = + 5 + + + "; + test_ClearSpeak("nb", "ClearSpeak_VerticalLine", "Divides", expr, + "f av x evaluert i x er lik 5"); +} + +#[test] +fn vertical_line_evaluated_at_both_given() { + let expr = " + + x + 2 + + + + x + + | + 0 + 1 + + "; + test_ClearSpeak("nb", "ClearSpeak_VerticalLine", "Given", expr, + "x i andre pluss x, evaluert for øvre verdi, 1, og nedre verdi, 0"); +} \ No newline at end of file diff --git a/tests/Languages/nb/SimpleSpeak/functions.rs b/tests/Languages/nb/SimpleSpeak/functions.rs new file mode 100644 index 000000000..d95f5b927 --- /dev/null +++ b/tests/Languages/nb/SimpleSpeak/functions.rs @@ -0,0 +1,335 @@ +/// 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("nb", "SimpleSpeak", expr, "sinus av x pluss cosinus av y pluss tangens av z pluss sekans av alfa, pluss cosekans av fi, pluss cotangens av fi"); +} + +#[test] +fn hyperbolic_trig_names() { + let expr = " + sinhx+ + coshy+ + tanhz+ + sechα+ + cschϕ+ + cothφ + "; + test("nb", "SimpleSpeak", expr, "sinus hyperbolicus av x, pluss cosinus hyperbolicus av y, pluss tangens hyperbolicus av z, pluss, sekans hyperbolicus av alfa, pluss cosekans hyperbolicus av fi, pluss cotangens hyperbolicus av fi"); +} + + +#[test] +fn inverse_trig() { + let expr = "sin-1x"; + test("nb", "SimpleSpeak", expr, "invers sinus av x"); +} + +#[test] +fn trig_squared() { + let expr = "sin2x"; + test("nb", "SimpleSpeak", expr, "sinus i andre av x"); +} + +#[test] +fn trig_cubed() { + let expr = "tan3x"; + test("nb", "SimpleSpeak", expr, "tangens i tredje av x"); +} + +#[test] +fn trig_fourth() { + let expr = "sec4x"; + test("nb", "SimpleSpeak", expr, "sekans opphøyd i 4, av x"); +} + + +#[test] +fn trig_power_other() { + let expr = "sinh>n-1x"; + test("nb", "SimpleSpeak", expr, "sinus hyperbolicus opphøyd i n minus 1, av x"); +} + +#[test] +fn simple_log() { + let expr = " logx "; + test("nb", "SimpleSpeak", expr, "log av x"); +} + +#[test] +fn normal_log() { + let expr = "log(x+y)"; + test("nb", "SimpleSpeak", expr, "log av, startparentes; x pluss y; sluttparentes"); +} + +#[test] +fn simple_log_with_base() { + let expr = " logbx "; + test("nb", "SimpleSpeak", expr, "logaritmen med grunntall b, av x"); +} + +#[test] +fn normal_log_with_base() { + let expr = "logb(x+y)"; + test("nb", "SimpleSpeak", expr, "logaritmen med grunntall b, av; startparentes; x pluss y; sluttparentes"); +} + +#[test] +fn normal_ln() { + let expr = "ln(x+y)"; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "l n av, startparentes; x pluss y; sluttparentes"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Medium")], + expr, "den naturlige logaritmen av, startparentes; x pluss y; sluttparentes"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Verbose")], + expr, "den naturlige logaritmen av, startparentes; x pluss y; sluttparentes"); +} + +#[test] +fn simple_ln() { + let expr = " lnx "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "l n av x"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Medium")], + expr, "l n av x"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Verbose")], + expr, "den naturlige logaritmen av x"); +} + +#[test] +fn other_names() { + let expr = " Covx "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "kovarians x"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Medium")], + expr, "kovarians x"); + let expr = " exp(x) "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "exp av x"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Medium")], + expr, "eksponensialfunksjonen av x"); +} + +#[test] +fn explicit_function_call_with_parens() { + let expr = "t⁡(x)"; + test("nb", "SimpleSpeak", expr, "t av x"); +} + + +#[test] +fn explicit_times_with_parens() { + let expr = "t⁢(x)"; + test("nb", "SimpleSpeak", expr, "t ganger x"); +} + +#[test] +fn explicit_function_call() { + let expr = "t⁡x"; + test("nb", "SimpleSpeak", expr, "t av x"); +} + +#[test] +fn explicit_times() { + let expr = "t⁢x"; + test("nb", "SimpleSpeak", expr, "t x"); +} + + +/* + * Tests for times + */ +#[test] +fn no_times_binomial() { + let expr = "x ⁢ y"; + test("nb", "SimpleSpeak", expr, "x y"); +} + +#[test] +fn times_following_paren() { + let expr = " + 2 + ( 3 ) + "; + test("nb", "SimpleSpeak", expr, "2 ganger 3"); +} + +#[test] +fn times_preceding_paren() { + let expr = " + ( 2 ) + 3 + "; + test("nb", "SimpleSpeak", expr, "2 ganger 3"); +} + +#[test] +fn no_times_sqrt() { + let expr = " + a + b + = + ab + "; + test("nb", "SimpleSpeak", expr, + "kvadratroten av a; ganger kvadratroten av b; er lik, kvadratroten av a b, slutt rot"); + test_prefs("nb", "SimpleSpeak", vec![("Impairment", "LearningDisability")], expr, + "kvadratroten av a; ganger kvadratroten av b; er lik, kvadratroten av a b, slutt rot"); +} + +/* + * Tests for parens + */ + #[test] + fn no_parens_number() { + let expr = " + ( + 25 + ) + x + "; + test("nb", "SimpleSpeak", expr, "25 ganger x"); + } + + #[test] + fn no_parens_monomial() { + let expr = " + b + ( + xy + ) + "; + test("nb", "SimpleSpeak", expr, "b; startparentes; x y, sluttparentes"); + } + + #[test] + fn no_parens_negative_number() { + let expr = " + 2+ + ( + −2 + ) + "; + test("nb", "SimpleSpeak", expr, "2 pluss minus 2"); + } + + + #[test] + fn no_parens_negative_number_with_var() { + let expr = " + ( + −2x + ) + +1 + "; + test("nb", "SimpleSpeak", expr, "minus 2 x, pluss 1"); + } + + #[test] + fn parens_superscript() { + let expr = " + + + + ( + 2x + ) + 2 + + + "; + test("nb", "SimpleSpeak", expr, ", startparentes; 2 x, sluttparentes i andre"); + } + + #[test] + fn no_parens_fraction() { + let expr = " + 2 + + + + ( + 12 + ) + "; + test("nb", "SimpleSpeak", expr, "2 pluss 1 halv"); + } + + + // Tests for the four types of intervals in SimpleSpeak + #[test] + fn parens_interval_open_open() { + let expr = " + ( + (c,d) + ) + "; + test("nb", "SimpleSpeak",expr, "det åpne intervallet fra c til d"); +} + +#[test] + fn parens_interval_closed_open() { + let expr = " + [ + [(]c,d) + ) + "; + test("nb", "SimpleSpeak",expr, "det halvåpne intervallet fra og med c til d"); +} + + +#[test] +fn parens_interval_open_closed() { + let expr = " + ( + (c,d] + ] + "; + test("nb", "SimpleSpeak",expr,"det halvåpne intervallet fra c til og med d"); +} + + +#[test] +fn parens_interval_closed_closed() { + let expr = " + [ + [(]c,d] + ] + "; + test("nb", "SimpleSpeak",expr, "det lukkede intervallet fra c til d"); +} + + #[test] + fn parens_interval_neg_infinity_open_open() { + let expr = " + ( + - ∞,d) + ) + "; + test("nb", "SimpleSpeak",expr, + "det åpne intervallet fra minus uendelig til d"); +} + + #[test] + fn parens_interval_neg_infinity_open_closed() { + let expr = " + ( + - ∞,d] + ] + "; + test("nb", "SimpleSpeak",expr, + "det halvåpne intervallet fra minus uendelig til og med d"); +} + diff --git a/tests/Languages/nb/SimpleSpeak/geometry.rs b/tests/Languages/nb/SimpleSpeak/geometry.rs new file mode 100644 index 000000000..0d56fec02 --- /dev/null +++ b/tests/Languages/nb/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("nb", "SimpleSpeak", expr, "bue stor b stor c"); +} + +#[test] +fn ray() { + let expr = " XY¯ "; + test("nb", "SimpleSpeak", expr, "linjestykke stor x stor y"); +} + +#[test] +fn arc_mtext() { + let expr = " BC⌒ "; + test("nb", "SimpleSpeak", expr, "bue stor b stor c"); +} + +#[test] +fn ray_mtext() { + let expr = " XY→ "; + test("nb", "SimpleSpeak", expr, "stråle stor x stor y"); +} diff --git a/tests/Languages/nb/SimpleSpeak/large_ops.rs b/tests/Languages/nb/SimpleSpeak/large_ops.rs new file mode 100644 index 000000000..89947d756 --- /dev/null +++ b/tests/Languages/nb/SimpleSpeak/large_ops.rs @@ -0,0 +1,200 @@ +use crate::common::*; + +#[test] +fn sum_both() { + let expr = " + + ∑ + n=1 + 10 + + n + "; + test("nb", "SimpleSpeak", expr, "sum fra n er lik 1, til 10, av n"); +} + +#[test] +fn sum_under() { + let expr = " + + ∑ + S + + i + "; + test("nb", "SimpleSpeak", expr, "sum over stor s, av i"); +} +#[test] +fn sum_both_msubsup() { + let expr = " + + ∑ + n=1 + 10 + + n + "; + test("nb", "SimpleSpeak", expr, "sum fra n er lik 1, til 10, av n"); +} + +#[test] +fn sum_sub() { + let expr = " + + ∑ + S + + i + "; + test("nb", "SimpleSpeak", expr, "sum over stor s, av i"); +} + +#[test] +fn sum() { + let expr = " + ∑ + ai + "; + test("nb", "SimpleSpeak", expr, "sum av, a, senket i"); +} + +#[test] +fn product_both() { + let expr = " + + ∏ + n=1 + 10 + + n + "; + test("nb", "SimpleSpeak", expr, "produktet fra n er lik 1, til 10, av n"); +} + +#[test] +fn product_under() { + let expr = " + + ∏ + S + + i + "; + test("nb", "SimpleSpeak", expr, "produktet over stor s, av i"); +} + +#[test] +fn product() { + let expr = " + ∏ + ai + "; + test("nb", "SimpleSpeak", expr, "produktet av, a, senket i"); +} + +#[test] +fn intersection_both() { + let expr = " + + ⋂ + i=1 + 10 + + Si + "; + test("nb", "SimpleSpeak", expr, "snitt fra i er lik 1, til 10, av; stor s, senket i"); +} + +#[test] +fn intersection_under() { + let expr = " + + ⋂ + C + + Si + "; + test("nb", "SimpleSpeak", expr, "snitt over stor c, av, stor s, senket i"); +} + +#[test] +fn intersection() { + let expr = " + ⋂ + Si + "; + test("nb", "SimpleSpeak", expr, "snitt av, stor s, senket i"); +} + +#[test] +fn union_both() { + let expr = " + + ⋃ + i=1 + 10 + + Si + "; + test("nb", "SimpleSpeak", expr, "union fra i er lik 1, til 10, av; stor s, senket i"); +} + +#[test] +fn union_under() { + let expr = " + + ⋃ + C + + Si + "; + test("nb", "SimpleSpeak", expr, "union over stor c, av, stor s, senket i"); +} + +#[test] +fn union() { + let expr = " + ⋃ + Si + "; + test("nb", "SimpleSpeak", expr, "union av, stor s, senket i"); +} + +#[test] +fn integral_both() { + let expr = " + + + ∫ + 0 + 1 + + f(x ) + +  dx + "; + test("nb", "SimpleSpeak", expr, "integralet fra 0, til 1, av, f av x; d x"); +} + +#[test] +fn integral_under() { + let expr = " + + ∫ + ℝ + + f(x ) + dx + "; + test("nb", "SimpleSpeak", expr, "integralet over de reelle tallene, av; f av x d x"); +} + +#[test] +fn integral() { + let expr = " + ∫ + f(x ) + dx + "; + test("nb", "SimpleSpeak", expr, "integralet av, f av x d x"); +} \ No newline at end of file diff --git a/tests/Languages/nb/SimpleSpeak/linear_algebra.rs b/tests/Languages/nb/SimpleSpeak/linear_algebra.rs new file mode 100644 index 000000000..d31b95e27 --- /dev/null +++ b/tests/Languages/nb/SimpleSpeak/linear_algebra.rs @@ -0,0 +1,92 @@ +use crate::common::*; + +#[test] +fn transpose() { + let expr = " MT "; + test("nb", "SimpleSpeak", expr, "stor m transponert"); +} + +#[test] +fn trace() { + let expr = " TrM "; + test("nb", "SimpleSpeak", expr, "sporet av stor m"); +} + +#[test] +fn dimension() { + let expr = " DimM "; + test("nb", "SimpleSpeak", expr, "dimensjonen til stor m"); +} + +#[test] +fn homomorphism() { + let expr = " Hom(M) "; + test("nb", "SimpleSpeak", expr, "mengden av homomorfier på stor m"); +} + +#[test] +fn kernel() { + let expr = " ker(L) "; + test("nb", "SimpleSpeak", expr, "nullrommet til stor l"); +} + +#[test] +fn norm() { + let expr = " + + ∥ + f + ∥ + + +"; + test("nb", "SimpleSpeak", expr, "normen til f"); +} + +#[test] +fn norm_non_simple() { + let expr = " + + ∥ + x + + + y + ∥ + + +"; + test("nb", "SimpleSpeak", expr, "normen til x pluss y, slutt norm"); +} + +#[test] +fn norm_subscripted() { + let expr = " + + + ∥ + f + ∥ + + p + + +"; + test("nb", "SimpleSpeak", expr, "p normen til 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("nb", "SimpleSpeak", expr, ", startparentes; b ganger nabla; sluttparentes; ganger a"); +} \ No newline at end of file diff --git a/tests/Languages/nb/SimpleSpeak/mfrac.rs b/tests/Languages/nb/SimpleSpeak/mfrac.rs new file mode 100644 index 000000000..830b424d7 --- /dev/null +++ b/tests/Languages/nb/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("nb", "SimpleSpeak", expr, "1 halv"); +} + +#[test] +fn common_fraction_thirds() { + let expr = " + 2 3 + "; + test("nb", "SimpleSpeak", expr, "2 tredjedeler"); +} + +#[test] +fn common_fraction_tenths() { + let expr = " + 17 10 + "; + test("nb", "SimpleSpeak", expr, "17 tideler"); +} + +#[test] +#[allow(non_snake_case)] +fn not_SimpleSpeak_common_fraction_tenths() { + let expr = " + 89 10 + "; + test("nb", "SimpleSpeak", expr, "89 over 10"); +} + +#[test] +fn non_simple_fraction() { + let expr = " + + + + x+y + + x-y + + + + "; + test("nb", "SimpleSpeak", expr, "brøk, x pluss y, over, x minus y, slutt brøk"); +} + +#[test] +fn nested_fraction() { + let expr = " + + + + x+ 1y + + x-y + + + + "; + test("nb", "SimpleSpeak", expr, "brøk, x pluss, brøk, 1 over y, slutt brøk; over, x minus y, slutt brøk"); +} + + +#[test] +fn deeply_nested_fraction_msqrt() { + let expr = " + + + + x+ 1y + + x-y + + + + "; + test("nb", "SimpleSpeak", expr, "brøk, x pluss, kvadratroten av 1 over y; slutt rot; over, x minus y, slutt brøk"); +} + +#[test] +fn deeply_nested_fraction_mrow_msqrt() { + let expr = " + + + + x+ 2+1y + + x-y + + + + "; + test("nb", "SimpleSpeak", expr, "brøk, x pluss, kvadratroten av 2 pluss 1 over y; slutt rot; over, x minus y, slutt brøk"); +} + +#[test] +fn numerator_simple_fraction() { + let expr = " + + + + x + + x-y + + + + "; + test("nb", "SimpleSpeak", expr, "brøk, x over, x minus y, slutt brøk"); +} + +#[test] +fn denominator_simple_fraction() { + let expr = " + + + x-y + x + + + "; + test("nb", "SimpleSpeak", expr, "brøk, x minus y, over x, slutt brøk"); +} + + +#[test] +fn frac_with_units() { + let expr = " + + + 62 + + mi + hr + + + "; + test("nb", "SimpleSpeak", expr, "62 miles per time"); +} + +#[test] +fn singular_frac_with_units() { + let expr = " + + + 1 + + gal + mi + + + "; + test("nb", "SimpleSpeak", expr, "1 gallon per mile"); +} + +#[test] +fn number_in_numerator_with_units() { + let expr = " + + + + 3 + gal + + mi + + "; + test("nb", "SimpleSpeak", expr, "3 gallon per mile"); +} + +#[test] +fn units_with_powers() { + let expr = " + + + 3 m + s2 + + "; + test("nb", "SimpleSpeak", expr, "3 meter per sekund i andre"); +} + + +#[test] +fn mixed_number() { + let expr = " + 3 + 1 2 + "; + test("nb", "SimpleSpeak", expr, "3 og 1 halv"); +} + +#[test] +fn explicit_mixed_number() { + let expr = " + 3 + ⁤ + 1 8 + "; + test("nb", "SimpleSpeak", expr, "3 og 1 åttedel"); +} + +#[test] +fn mixed_number_big() { + let expr = " + 3 + 7 83 + "; + test("nb", "SimpleSpeak", expr, "3 og 7 over 83"); +} + +#[test] +fn simple_text() { + let expr = " + rise run + "; + test("nb", "SimpleSpeak", expr, "rise over run"); +} + +#[test] +fn number_and_text() { + let expr = " + + + 2miles + + 3gallons + + "; + test("nb", "SimpleSpeak", expr, "brøk, 2 miles, over, 3 gallons, slutt brøk"); +} + + +#[test] +fn nested_simple_fractions() { + let expr = " + + + + + 1 + 2 + + + + + 2 + 3 + + + + + "; + test("nb", "SimpleSpeak", expr, "brøk, 1 halv, over, 2 tredjedeler, slutt brøk"); +} + +#[test] +fn binomial() { + let expr = " + 2 + ( + 7 3 + ) + "; + test("nb", "SimpleSpeak", expr, "2 ganger 7 over 3"); +} + +#[test] +fn binomial_non_simple_top() { + let expr = " + 2 + ( + n+7 3 + ) + "; + test("nb", "SimpleSpeak", expr, "2 ganger, binomialkoeffisient n pluss 7 over 3"); +} + +#[test] +fn binomial_non_simple_bottom() { + let expr = " + 2 + ( + 7 k+3 + ) + "; + test("nb", "SimpleSpeak", expr, "2 ganger, 7 over k pluss 3 slutt binomialkoeffisient"); +} + +#[test] +fn binomial_non_simple_top_and_bottom() { + let expr = " + 2 + ( + n+7 k+3 + ) + "; + test("nb", "SimpleSpeak", expr, "2 ganger; binomialkoeffisient n pluss 7 over k pluss 3 slutt binomialkoeffisient"); +} diff --git a/tests/Languages/nb/SimpleSpeak/msup.rs b/tests/Languages/nb/SimpleSpeak/msup.rs new file mode 100644 index 000000000..e410cff41 --- /dev/null +++ b/tests/Languages/nb/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("nb", "SimpleSpeak", expr, "x i andre"); +} + +#[test] +fn cubed() { + let expr = " + x 3 + "; + test("nb", "SimpleSpeak", expr, "x i tredje"); +} + +#[test] + fn ordinal_power() { + let expr = " + x 4 + "; + test("nb", "SimpleSpeak", expr, "x opphøyd i 4"); + } + +#[test] +fn simple_mi_power() { + let expr = " + x n + "; + test("nb", "SimpleSpeak", expr, "x opphøyd i n"); +} + +#[test] +fn zero_power() { + let expr = " + x 0 + "; + test("nb", "SimpleSpeak", expr, "x opphøyd i 0"); +} + + +#[test] +fn decimal_power() { + let expr = " + x 2,0 + "; + test_prefs("nb", "SimpleSpeak", vec![("DecimalSeparators", ","), ("BlockSeparators", ".")], expr, "x opphøyd i 2,0"); +} + +#[test] +fn non_simple_power() { + let expr = " + + + 3 + + y+2 + + + "; + test("nb", "SimpleSpeak", expr, "3 opphøyd i y pluss 2"); +} + +#[test] +fn negative_power() { + let expr = " + + x + - 2 + + "; + test("nb", "SimpleSpeak", expr, "x opphøyd i minus 2"); +} + +#[test] +fn simple_fraction_power() { + let expr = " + + x + 13 + + "; + test("nb", "SimpleSpeak", expr, "x opphøyd i 1 tredjedel"); +} + +#[test] +fn nested_squared_power_with_coef() { + let expr = " + + + 3 + + 2 + + x + 2 + + + + + "; + test("nb", "SimpleSpeak", expr, "3 opphøyd i 2 x i andre"); +} + +#[test] +fn nested_squared_power_with_neg_coef() { + let expr = " + + + 3 + + - + 2 + + x + 2 + + + + + "; + test("nb", "SimpleSpeak", expr, "3 opphøyd i minus 2 x i andre"); +} + + +#[test] +fn nested_cubed_power() { + let expr = " + + y + + 45 + 3 + + + "; + test("nb", "SimpleSpeak", expr, "y opphøyd i 4 femtedeler i tredje"); +} + +#[test] +fn nested_cubed_power_with_neg_base() { + let expr = " + + y + + - + + 45 + 3 + + + + "; + test("nb", "SimpleSpeak", expr, "y opphøyd i minus 4 femtedeler i tredje"); +} + +#[test] +fn nested_number_times_squared() { + let expr = " + + + e + + + 1 + 2 + + + x + 2 + + + + + "; + test("nb", "SimpleSpeak", expr, "e opphøyd i 1 halv x i andre"); +} + +#[test] +fn nested_negative_number_times_squared() { + let expr = " + + + e + + − + 1 + 2 + + + x + 2 + + + + + "; + test("nb", "SimpleSpeak", expr, "e opphøyd i minus 1 halv x i andre"); +} + +#[test] +fn nested_expr_to_tenth() { + let expr = " + + + 3 + + + 3 + + 10 + + + + + "; + test("nb", "SimpleSpeak", expr, "3 opphøyd i 3 opphøyd i 10"); +} + +#[test] +fn nested_non_simple_squared_exp() { + let expr = " + + + 3 + + + + ( + + x+1 + ) + 2 + + + + + "; + test("nb", "SimpleSpeak", expr, "3 opphøyd i, startparentes; x pluss 1; sluttparentes i andre"); +} + +#[test] +fn nested_simple_power() { + let expr = " + + t + + 45 + n + + + "; + test("nb", "SimpleSpeak", expr, "t opphøyd i 4 femtedeler opphøyd i n"); +} + +#[test] +fn nested_end_exponent_power() { + let expr = " + + t + + 45 + n+1 + + + "; + test("nb", "SimpleSpeak", expr, "t opphøyd i 4 femtedeler opphøyd i n pluss 1, slutt eksponent"); + test_prefs("nb", "SimpleSpeak", vec![("Impairment", "LearningDisability")], expr, + "t opphøyd i 4 femtedeler opphøyd i n pluss 1, slutt eksponent"); +} + +#[test] +fn nested_end_exponent_neg_power() { + let expr = " + + t + + 45 + -3 + + + "; + test("nb", "SimpleSpeak", expr, "t opphøyd i 4 femtedeler opphøyd i minus 3; slutt eksponent"); +} + +#[test] +fn nested_complex_power() { + let expr = " + + + e + + − + 1 + 2 + + + + ( + + + + x−μ + σ + + + ) + 2 + + + + + "; + test("nb", "SimpleSpeak", expr, "e opphøyd i minus 1 halv ganger; startparentes; brøk, x minus my, over sigma, slutt brøk; sluttparentes i andre"); +} + +#[test] +fn default_power() { + let expr = " + + t + + b+1 + 3 + + + "; + test("nb", "SimpleSpeak", expr, "t opphøyd i brøk, b pluss 1, over 3, slutt brøk"); +} diff --git a/tests/Languages/nb/SimpleSpeak/multiline.rs b/tests/Languages/nb/SimpleSpeak/multiline.rs new file mode 100644 index 000000000..7e46673ae --- /dev/null +++ b/tests/Languages/nb/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("nb", "SimpleSpeak", expr, "f av x er lik; 3 tilfeller; \ + tilfelle 1; minus 1 if x; er mindre enn 0; \ + tilfelle 2; 0 if x, er lik 0; \ + tilfelle 3; 1 if x, er større enn 0"); +} + +#[test] +fn equation_1() { + let expr = " + + + + + + x+y + + + = + + + 7 + + + + + + 2x+3y + + + = + + + + 17 + + + + + + "; + test("nb", "SimpleSpeak", expr, "2 likninger; \ + likning 1; x pluss y er lik 7; \ + likning 2; 2 x pluss 3 y; er lik 17"); +} diff --git a/tests/Languages/nb/SimpleSpeak/sets.rs b/tests/Languages/nb/SimpleSpeak/sets.rs new file mode 100644 index 000000000..51bdc0ddf --- /dev/null +++ b/tests/Languages/nb/SimpleSpeak/sets.rs @@ -0,0 +1,238 @@ +use crate::common::*; + +#[test] +fn complex() { + let expr = " + ℂ + "; + test("nb", "SimpleSpeak", expr, "de komplekse tallene"); +} + +#[test] +fn natural() { + let expr = " + ℕ + "; + test("nb", "SimpleSpeak", expr, "de naturlige tallene"); +} + +#[test] +fn rationals() { + let expr = " + ℚ + "; + test("nb", "SimpleSpeak", expr, "de rasjonale tallene"); +} + +#[test] +fn reals() { + let expr = " + ℝ + "; + test("nb", "SimpleSpeak", expr, "de reelle tallene"); +} + +#[test] +fn integers() { + let expr = " + ℤ + "; + test("nb", "SimpleSpeak", expr, "heltallene"); +} + + + +#[test] +fn msup_complex() { + let expr = " + + ℂ + 2 + + "; + test("nb", "SimpleSpeak", expr, "C 2"); +} + +#[test] +fn msup_natural() { + let expr = " + + ℕ + 2 + + "; + test("nb", "SimpleSpeak", expr, "N 2"); +} + +#[test] +fn msup_rationals() { + let expr = " + + ℚ + 2 + + "; + test("nb", "SimpleSpeak", expr, "Q 2"); +} + +#[test] +fn msup_reals() { + let expr = " + + ℝ + 3 + + "; + test("nb", "SimpleSpeak", expr, "R 3"); +} + +#[test] +fn msup_integers() { + let expr = " + + ℤ + 4 + + "; + test("nb", "SimpleSpeak", expr, "Z 4"); +} + +#[test] +fn msup_positive_integers() { + let expr = " + + ℤ + + + + "; + test("nb", "SimpleSpeak", expr, "de positive heltallene"); +} + +#[test] +fn msup_negative_integers() { + let expr = " + + ℤ + - + + "; + test("nb", "SimpleSpeak", expr, "de negative heltallene"); +} + +#[test] +fn msup_positive_rationals() { + let expr = " + + ℚ + + + + "; + test("nb", "SimpleSpeak", expr, "de positive rasjonale tallene"); +} + +#[test] +fn msup_negative_rationals() { + let expr = " + + ℚ + - + + "; + test("nb", "SimpleSpeak", expr, "de negative rasjonale tallene"); +} + +#[test] +fn empty_set() { + let expr = " + { } + "; + test("nb", "SimpleSpeak", expr, "den tomme mengden"); +} + +#[test] +fn single_element_set() { + let expr = " + { 12} + "; + test("nb", "SimpleSpeak", expr, "mengden 12"); +} + +#[test] +fn multiple_element_set() { + let expr = " + { 5 , 10 , 15 } + "; + test("nb", "SimpleSpeak", expr, "mengden 5 komma, 10 komma, 15"); +} + +#[test] +fn set_with_colon() { + let expr = " + { x:x>2 } + "; + test("nb", "SimpleSpeak", expr, "mengden av alle x slik at x er større enn 2"); +} + +#[test] +fn set_with_bar() { + let expr = " + { x|x>2 } + "; + test("nb", "SimpleSpeak", expr, "mengden av alle x slik at x er større enn 2"); +} + +#[test] +fn element_alone() { + let expr = " + 3+2i∉ℝ + "; + test("nb", "SimpleSpeak", expr, "3 pluss 2 i, er ikke et element i, de reelle tallene"); +} + +#[test] +fn element_under_sum() { + let expr = " + + ∑ + i ∈ ℤ + + + 1 + i 2 + + "; + test("nb", "SimpleSpeak", expr, + "sum over i i heltallene, av; brøk, 1 over, i i andre, slutt brøk"); +} + +#[test] +fn complicated_set_with_colon() { + let expr = " + { + x + ∈ + ℤ + : + 2 + < + x + < + 7 + } + "; + test("nb", "SimpleSpeak", expr, "mengden av alle x i heltallene slik at 2 er mindre enn x er mindre enn 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("nb", "SimpleSpeak", expr, + "mengden av alle x i de naturlige tallene slik at x is an even number"); +} diff --git a/tests/Languages/nb/SimpleSpeak/subscripts.rs b/tests/Languages/nb/SimpleSpeak/subscripts.rs new file mode 100644 index 000000000..ac497ec34 --- /dev/null +++ b/tests/Languages/nb/SimpleSpeak/subscripts.rs @@ -0,0 +1,49 @@ +use crate::common::*; + +#[test] +fn msub_simple() { + let expr = " x 1 "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x 1"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Medium")], expr, "x, senket 1"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "x, senket 1"); + } + +#[test] +fn msub_not_simple() { + let expr = " x 1,2 "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse"), ("DecimalSeparators", ","), ("BlockSeparators", ".")], expr, "x, senket 1,2"); + } + +#[test] +fn msubsup_not_simple() { + let expr = " x 1,2 3 "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse"), ("DecimalSeparators", ","), ("BlockSeparators", ".")], expr, "x, senket 1,2, i tredje"); + } + +#[test] +fn msub_simple_mi() { + let expr = " x i "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x, senket i"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "x, senket i"); +} + +#[test] +fn msub_simple_number_follows() { + let expr = " x 1 102 "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x 1, 10 i andre"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "x, senket 1; 10 i andre"); +} + +#[test] +fn msub_simple_non_number_follows() { + let expr = " x 1 2 "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x 1, i andre"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "x, senket 1, i andre"); +} + +#[test] +fn msubsup_simple() { + let expr = " x 1 x,2 "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x 1, x i andre"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "x, senket 1; x i andre"); +} \ No newline at end of file diff --git a/tests/Languages/nb/alphabets.rs b/tests/Languages/nb/alphabets.rs new file mode 100644 index 000000000..47bd8e411 --- /dev/null +++ b/tests/Languages/nb/alphabets.rs @@ -0,0 +1,343 @@ +/// 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("nb", "SimpleSpeak", expr, "fraktur stor h komma, fraktur stor c"); + let expr = " ℍ,ℿ"; + test("nb", "SimpleSpeak", expr, "dobbeltstreket stor h, komma, dobbeltstreket stor pi"); + let expr = " ℐ,ℳ"; + test("nb", "SimpleSpeak", expr, "script font stor i, komma, script font stor m"); +} + +#[test] +fn greek() { + let expr = " Α,Ω"; + test("nb", "SimpleSpeak", expr, "stor alfa komma, stor omega"); + let expr = " α,ω"; + test("nb", "SimpleSpeak", expr, "alfa komma, omega"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "dobbeltstreket stor delta, komma; dobbeltstreket stor ypsilon"); + let expr = " α,ω"; + test("nb", "SimpleSpeak", expr, "alfa komma, omega"); +} + +#[test] +fn cap_cyrillic() { + let expr = " А,Я"; + test("nb", "SimpleSpeak", expr, "stor a, komma, stor ja"); +} + +#[test] +fn parenthesized() { + let expr = " ⒜,⒵"; + test("nb", "SimpleSpeak", expr, "a i parentes komma, z i parentes"); +} + +#[test] +fn circled() { + let expr = " Ⓐ,Ⓩ"; + test("nb", "SimpleSpeak", expr, "stor a i sirkel komma, stor z i sirkel"); + let expr = " ⓐ,ⓩ"; + test("nb", "SimpleSpeak", expr, "a i sirkel komma, z i sirkel"); +} + +#[test] +fn fraktur() { + let expr = " 𝔄,𝔜"; + test("nb", "SimpleSpeak", expr, "fraktur stor a komma, fraktur stor y"); + let expr = " 𝔞,𝔷"; + test("nb", "SimpleSpeak", expr, "fraktur a komma, fraktur z"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fraktur stor a komma, fraktur stor y"); + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fraktur a komma, fraktur z"); +} + +#[test] +fn bold_fraktur() { + let expr = " 𝕬,𝖅"; + test("nb", "SimpleSpeak", expr, "fraktur fet stor a, komma, fraktur fet stor z"); + let expr = " 𝖆,𝖟"; + test("nb", "SimpleSpeak", expr, "fraktur fet a komma, fraktur fet z"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fraktur fet stor a, komma, fraktur fet stor z"); + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fraktur fet a komma, fraktur fet z"); +} + +#[test] +fn double_struck() { + let expr = " 𝔸,𝕐"; + test("nb", "SimpleSpeak", expr, "dobbeltstreket stor a, komma, dobbeltstreket stor y"); + let expr = " 𝕒,𝕫"; + test("nb", "SimpleSpeak", expr, "dobbeltstreket a komma, dobbeltstreket z"); + let expr = " 𝟘,𝟡"; + test("nb", "SimpleSpeak", expr, "dobbeltstreket 0 komma, dobbeltstreket 9"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "dobbeltstreket stor a, komma, dobbeltstreket stor y"); + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "dobbeltstreket a komma, dobbeltstreket z"); + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "dobbeltstreket 0 komma, dobbeltstreket 9"); +} + +#[test] +fn script() { + let expr = " 𝒜,𝒵"; + test("nb", "SimpleSpeak", expr, "script font stor a, komma, script font stor z"); + let expr = " 𝒶,𝓏"; + test("nb", "SimpleSpeak", expr, "script font a komma, script font z"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "script font stor a, komma, script font stor z"); + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "script font a komma, script font z"); +} + +#[test] +fn bold_script() { + let expr = " 𝓐,𝓩"; + test("nb", "SimpleSpeak", expr, "script font fet stor a, komma, script font fet stor z"); + let expr = " 𝓪,𝔃"; + test("nb", "SimpleSpeak", expr, "script font fet a komma, script font fet z"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "script font fet stor a, komma, script font fet stor z"); + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "script font fet a komma, script font fet z"); +} + +#[test] +fn bold() { + let expr = " 𝐀,𝐙"; + test("nb", "SimpleSpeak", expr, "fet stor a komma, fet stor z"); + let expr = " 𝐚,𝐳"; + test("nb", "SimpleSpeak", expr, "fet a komma, fet z"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fet stor a komma, fet stor z"); + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fet a komma, fet z"); +} + +#[test] +fn italic() { + let expr = " 𝐴,𝑍"; + test("nb", "SimpleSpeak", expr, "stor a komma, stor z"); + let expr = " 𝑎,𝑧"; + test("nb", "SimpleSpeak", expr, "a komma, z"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "stor a komma, stor z"); + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "a komma, z"); +} + +#[test] +fn sans_serif() { + let expr = " 𝖠,𝖹"; + test("nb", "SimpleSpeak", expr, "stor a komma, stor z"); + let expr = " 𝖺,𝗓"; + test("nb", "SimpleSpeak", expr, "a komma, z"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "stor a komma, stor z"); + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "a komma, z"); +} + +#[test] +fn sans_serif_bold() { + let expr = " 𝗔,𝗭"; + test("nb", "SimpleSpeak", expr, "fet stor a komma, fet stor z"); + let expr = " 𝗮,𝘇"; + test("nb", "SimpleSpeak", expr, "fet a komma, fet z"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fet stor a komma, fet stor z"); + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fet a komma, fet z"); +} + +#[test] +fn sans_serif_italic() { + let expr = " 𝘈,𝘡"; + test("nb", "SimpleSpeak", expr, "stor a komma, stor z"); + let expr = " 𝘢,𝘻"; + test("nb", "SimpleSpeak", expr, "a komma, z"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "stor a komma, stor z"); + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "a komma, z"); +} + +#[test] +fn sans_serif_bold_italic() { + let expr = " 𝘼,𝙕"; + test("nb", "SimpleSpeak", expr, "fet stor a komma, fet stor z"); + let expr = " 𝙖,𝙯"; + test("nb", "SimpleSpeak", expr, "fet a komma, fet z"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fet stor a komma, fet stor z"); + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fet a komma, fet z"); +} + +#[test] +fn monospace() { + let expr = " 𝙰,𝚉"; + test("nb", "SimpleSpeak", expr, "stor a komma, stor z"); + let expr = " 𝚊,𝚣"; + test("nb", "SimpleSpeak", expr, "a komma, z"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "stor a komma, stor z"); + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "a komma, z"); +} + + +#[test] +fn bold_greek() { + let expr = " 𝚨,𝛀"; + test("nb", "SimpleSpeak", expr, "fet stor alfa komma, fet stor omega"); + let expr = " 𝛂,𝛚"; + test("nb", "SimpleSpeak", expr, "fet alfa komma, fet omega"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fet stor alfa komma, fet stor omega"); + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fet alfa komma, fet omega"); +} + +#[test] +fn bold_greek_others() { + let expr = " 𝛛,𝛡"; + test("nb", "SimpleSpeak", expr, "fet partiell derivert, komma, fet pi"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fet partiell derivert, komma, fet pi"); +} + + +#[test] +fn italic_greek() { + let expr = " 𝛢,𝛺"; + test("nb", "SimpleSpeak", expr, "stor alfa komma, stor omega"); + let expr = " 𝛼,𝜔"; + test("nb", "SimpleSpeak", expr, "alfa komma, omega"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "stor alfa komma, stor omega"); + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "alfa komma, omega"); +} + +#[test] +fn italic_greek_others() { + let expr = " 𝜕,𝜛"; + test("nb", "SimpleSpeak", expr, "partiell derivert komma, pi"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "partiell derivert komma, pi"); +} + +#[test] +fn bold_italic_greek() { + let expr = " 𝜜,𝜴"; + test("nb", "SimpleSpeak", expr, "fet stor alfa komma, fet stor omega"); + let expr = " 𝜶,𝝎"; + test("nb", "SimpleSpeak", expr, "fet alfa komma, fet omega"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fet stor alfa komma, fet stor omega"); + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fet alfa komma, fet omega"); +} + +#[test] +fn bold_italic_greek_others() { + let expr = " 𝝏,𝝕"; + test("nb", "SimpleSpeak", expr, "fet partiell derivert, komma, fet pi"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fet partiell derivert, komma, fet pi"); +} + +#[test] +fn sans_serif_bold_greek() { + let expr = " 𝝖,𝝮"; + test("nb", "SimpleSpeak", expr, "fet stor alfa komma, fet stor omega"); + let expr = " 𝝰,𝞈"; + test("nb", "SimpleSpeak", expr, "fet alfa komma, fet omega"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fet stor alfa komma, fet stor omega"); + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fet alfa komma, fet omega"); +} + +#[test] +fn sans_serif_bold_greek_others() { + let expr = " 𝞉,𝞏"; + test("nb", "SimpleSpeak", expr, "fet partiell derivert, komma, fet pi"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fet partiell derivert, komma, fet pi"); +} + +#[test] +fn sans_serif_bold_italic_greek() { + let expr = " 𝞐,𝞨"; + test("nb", "SimpleSpeak", expr, "fet stor alfa komma, fet stor omega"); + let expr = " 𝞪,𝟂"; + test("nb", "SimpleSpeak", expr, "fet alfa komma, fet omega"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fet stor alfa komma, fet stor omega"); + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fet alfa komma, fet omega"); +} + +#[test] +fn sans_serif_bold_italic_greek_others() { + let expr = " 𝟃,𝟉"; + test("nb", "SimpleSpeak", expr, "fet partiell derivert, komma, fet pi"); + // MathType private space versions + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "fet partiell derivert, komma, fet pi"); +} + +#[test] +fn pua_regular() { + let expr = " ,"; + test("nb", "SimpleSpeak", expr, "stor a komma, stor z"); +} + +#[test] +fn turned() { + let expr = " Ⅎ,⅄"; + test("nb", "SimpleSpeak", expr, "rotert stor f komma, rotert sans-serif stor y"); + } + +#[test] +fn enclosed_numbers() { + let expr = " ①,⑨"; + test("nb", "SimpleSpeak", expr, "1 i sirkel komma, 9 i sirkel"); + let expr = " ⑴,⑼"; + test("nb", "SimpleSpeak", expr, "1 i parentes komma, 9 i parentes"); + let expr = " ⒈,⒐"; + test("nb", "SimpleSpeak", expr, "1 med punktum komma, 9 med punktum"); + let expr = " ⓵,⓽"; + test("nb", "SimpleSpeak", expr, "1 i dobbel sirkel komma, 9 i dobbel sirkel"); +} diff --git a/tests/Languages/nb/chemistry.rs b/tests/Languages/nb/chemistry.rs new file mode 100644 index 000000000..184c77db3 --- /dev/null +++ b/tests/Languages/nb/chemistry.rs @@ -0,0 +1,732 @@ +/// Tests for rules shared between various speech styles: +/// * modified var +use crate::common::*; + +#[test] +fn salt() { + let expr = "NaCl"; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "stor n a, stor c l"); +} + +#[test] +fn water() { + let expr = "H2O"; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "stor h, 2, stor o"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium")], expr, "stor h, senket 2, stor o"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, "stor h, nedre indeks 2, stor o"); +} + +#[test] +fn carbon() { + let expr = "C"; // not enough to trigger recognition + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "stor c"); +} + +#[test] +fn sulfate() { + let expr = " + [SO4] + 2− + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium")], expr, "start hakeparentes; stor s, stor o, senket 4; slutt hakeparentes hevet 2 minus"); +} + +#[test] +fn aluminum_sulfate() { + let expr = "Al2 + (SO4)3"; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "stor a l, 2; startparentes; stor s, stor o, 4; sluttparentes 3"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium")], expr, "stor a l, senket 2; startparentes; stor s, stor o, senket 4; sluttparentes senket 3"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, "stor a l, nedre indeks 2; startparentes; stor s, stor o, nedre indeks 4; sluttparentes nedre indeks 3"); +} + +#[test] +fn ethanol_bonds() { + let expr = " + + C + H 3 + − + C + H 2 + − + O + H + + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "stor c, stor h, 3; enkeltbinding stor c, stor h, 2; enkeltbinding stor o, stor h"); + +} + +#[test] +fn dichlorine_hexoxide() { + let expr = " + + [ClO2] + + + + + [ClO4] + - + + "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "start hakeparentes; stor c l, stor o, 2; slutt hakeparentes pluss; \ + start hakeparentes; stor c l, stor o, 4; slutt hakeparentes minus"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Medium")], + expr, "start hakeparentes; stor c l, stor o, senket 2; slutt hakeparentes hevet pluss; \ + start hakeparentes; stor c l, stor o, senket 4; slutt hakeparentes hevet minus"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Verbose")], + expr, "start hakeparentes; stor c l, stor o, nedre indeks 2; slutt hakeparentes øvre indeks pluss; \ + start hakeparentes; stor c l, stor o, nedre indeks 4; slutt hakeparentes øvre indeks minus"); +} + + +#[test] +fn ethylene_with_bond() { + let expr = " + H2C + = + CH2 + "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "stor h, 2, stor c, dobbeltbinding stor c, stor h, 2"); +} + +#[test] +fn ferric_chloride_aq() { + let expr = " + Fe + Cl3 + (aq) + "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "stor f e, stor c l, 3; løst i vann"); + } + +#[test] +fn ethylene_with_colon_bond() { + let expr = " + H2C + :: + CH2 + "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "stor h, 2, stor c, dobbeltbinding stor c, stor h, 2"); +} + +#[test] +fn beta_decay() { + let expr = " + + C + + 6 + 14 + + → + + N + + 7 + 14 + + + + + e + + + − + 1 + + 0 + + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Terse")], expr, + "14, 6, stor c; danner, 14, 7, stor n; pluss 0, minus 1, e"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium")], expr, + "hevet 14, senket 6, stor c; reaksjon danner; hevet 14, senket 7, stor n; pluss, hevet 0, senket minus 1, e"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, + "øvre indeks 14, nedre indeks 6, stor c; reaksjon danner; øvre indeks 14, nedre indeks 7, stor n; pluss, øvre indeks 0, nedre indeks minus 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("nb", "ClearSpeak", vec![("Verbosity", "Terse")], expr, + "14, 6, stor c; danner, 14, 7, stor n; pluss 0, minus 1, e"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium")], expr, + "hevet 14, senket 6, stor c; reaksjon danner; hevet 14, senket 7, stor n; pluss, hevet 0, senket minus 1, e"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, + "øvre indeks 14, nedre indeks 6, stor c; reaksjon danner; øvre indeks 14, nedre indeks 7, stor n; pluss, øvre indeks 0, nedre indeks minus 1, e"); +} + +#[test] +fn hcl_na_yields() { + let expr = " + 2HCl+2Na + → + 2NaCl+ + H 2 + + "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, + "2, stor h, stor c l; pluss 2 stor n a; reaksjon danner; 2, stor n a, stor c l; pluss stor h, nedre indeks 2"); +} + +#[test] +fn mhchem_so4_2plus() { + let expr = " + + + SO + + + + + + + A + + + + + + + + 4 + + + + + + + + + + A + + + + + + 2 + + + + + + "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "stor s; stor o, 4, 2 pluss"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Medium")], expr, "stor s; stor o, senket 4, hevet 2 pluss"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "stor s; stor o, nedre indeks 4, øvre indeks 2 pluss"); +} + + +#[test] +fn mhchem_hcl_aq_etc() { + let expr = " + + 2 + + + + + HCl + + + ( + + aq + + ) + + + + + 2 + + + + + Na + + + ( + + s + + ) + + + ⟶ + + + 2 + + + + + NaCl + + + ( + + aq + + ) + + + + + + H + + + + + + + A + + + + + + + + 2 + + + + + + ( + + g + + ) + + "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "2, stor h, stor c l, løst i vann; pluss, 2, stor n a, fast; danner; 2, stor n a, stor c l, løst i vann; pluss, stor h, 2, gass"); + +} + + +#[test] +fn mhchem_barbed_equilibrium() { + let expr = " + + + + H + 2 + + + ⁣ + + ( + g + ) + + + + + + + + I + 2 + + + ⁣ + + ( + g + ) + + + ⁢ + + + ↽ + - + + + - + ⇀ + + + ⁢ + 2 + ⁢ + + H + ⁣ + I + ⁣ + + ( + g + ) + + + + + "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "stor h, 2, gass; pluss; stor i, 2, gass; er i likevekt med 2, stor h, stor i, gass"); +} + + + +#[test] +fn mhchem_roman_in_superscript() { + let expr = " + + + Fe + + II + + ⁣ + + Fe + + III + + ⁣ + + O + 4 + + + + "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "stor f e, 2; stor f e, 3; stor o, 4"); +} + + +#[test] +fn dropped_msubsup_bug_358() { + let expr = r#" + + + 2 + + + SO + + 2 + + + + + + + + + O + + 2 + + + + + + + + + + + + ↽ + + + + + − + + + + + + + + − + + + + + ⇀ + + + + + + 2 + + + SO + + 3 + + + + + + + + "#; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "2, stor s, stor o, 2; pluss; stor o, 2, er i likevekt med 2, stor s, stor o, 3"); +} + + diff --git a/tests/Languages/nb/intent.rs b/tests/Languages/nb/intent.rs new file mode 100644 index 000000000..18796ab4d --- /dev/null +++ b/tests/Languages/nb/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("nb", "SimpleSpeak", expr, "2 x"); + test("nb", "LiteralSpeak", expr, "2 x"); +} + +#[test] +fn prefix_intent() { + let expr = r#" x T "#; + test("nb", "SimpleSpeak", expr, "testing x"); +} + +#[test] +fn postfix_intent() { + let expr = r#" x T "#; + test("nb", "SimpleSpeak", expr, "x testing"); +} + +#[test] +fn infix_intent() { + let expr = r#" + x + y + z + "#; + test("nb", "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("nb", "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("nb", "SimpleSpeak", expr, "testing x"); +} + +#[test] +fn function_intent() { + let expr = r#" + x + y + z + "#; + test("nb", "SimpleSpeak", expr, "testing av x, y, z, 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("nb", "SimpleSpeak", expr, "x"); +} + +#[test] +fn function_one_arg_intent() { + let expr = r#" + x + "#; + test("nb", "SimpleSpeak", expr, "testing av x"); +} + +#[test] +fn silent_intent_mi() { + let expr = " 2 x"; + test("nb", "SimpleSpeak", expr, "2"); + test("nb", "ClearSpeak", expr, "2"); +} + +#[test] +fn silent_intent_msup() { + let expr = " + + H + 2 + "; + test("nb", "SimpleSpeak", expr, "stor h 2"); + test("nb", "ClearSpeak", expr, "stor h 2"); +} + +#[test] +fn silent_intent_underscore() { + let expr = " + + H + 2 + "; + test("nb", "SimpleSpeak", expr, "stor h 2"); + test("nb", "ClearSpeak", expr, "stor h 2"); +} + +#[test] +fn intent_prob_x() { + let expr = " + + x + P + "; + test("nb", "ClearSpeak", expr, "sannsynligheten av x"); +} diff --git a/tests/Languages/nb/mtable.rs b/tests/Languages/nb/mtable.rs new file mode 100644 index 000000000..889fb63cf --- /dev/null +++ b/tests/Languages/nb/mtable.rs @@ -0,0 +1,1077 @@ +use crate::common::*; + +#[test] +fn matrix_1x1() { + let expr = " + + + ( + + 3 + + ) + + "; + test("nb", "ClearSpeak", expr, "1 ganger 1 matrise med element 3"); + test("nb", "SimpleSpeak", expr, "1 ganger 1 matrise med element 3"); +} + +#[test] +fn determinant_1x1() { + let expr = " + + + | + + 3 + + | + + "; + test("nb", "ClearSpeak", expr, "1 ganger 1 determinant med element 3"); + test("nb", "SimpleSpeak", expr, "1 ganger 1 determinant med element 3"); +} + + +#[test] +fn matrix_1x2() { + let expr = " + + + ( + + + + 3 + + + 5 + + + + ) + + "; + test("nb", "ClearSpeak", expr, "1 ganger 2 rad-matrise; 3, 5"); + test("nb", "SimpleSpeak", expr, "1 ganger 2 rad-matrise; 3, 5"); +} + + +#[test] +fn matrix_1x3() { + let expr = " + + + ( + + + + -x + + + 5 + + + 12 + + + + ) + + "; + test("nb", "ClearSpeak", expr, "1 ganger 3 rad-matrise; minus x, 5, 12"); + test("nb", "SimpleSpeak", expr, "1 ganger 3 rad-matrise; minus x, 5, 12"); +} + +#[test] +fn matrix_2x1_not_simple() { + let expr = " + + + ( + + + + + x+1 + + + + + + + x-1 + + + + ) + + "; + test("nb", "ClearSpeak", expr, "2 ganger 1 kolonne-matrise; rad 1; x pluss 1; rad 2; x minus 1"); + test("nb", "SimpleSpeak", expr, "2 ganger 1 kolonne-matrise; rad 1; x pluss 1; rad 2; x minus 1"); +} +#[test] +fn matrix_3x1_not_simple() { + let expr = " + + + ( + + + + + x + + + + + + + a + + + + + + + x + + x+1 + + + + + + ) + "; + test("nb", "SimpleSpeak", expr, "3 ganger 1 kolonne-matrise; \ + rad 1; x; \ + rad 2; a; \ + rad 3; brøk, x over, x pluss 1, slutt brøk"); + test("nb", "ClearSpeak", expr, "3 ganger 1 kolonne-matrise; \ + rad 1; x; \ + rad 2; a; \ + rad 3; brøken med teller x; og nevner x pluss 1"); +} + +#[test] +fn determinant_2x2() { + let expr = " + + | + + + + 2 + + + 1 + + + + + 7 + + + 5 + + + + + | + "; + test("nb", "ClearSpeak", expr, "2 ganger 2 determinant; rad 1; 2, 1; rad 2; 7, 5"); + test("nb", "SimpleSpeak", expr, "2 ganger 2 determinant; rad 1; 2, 1; rad 2; 7, 5"); +} + +#[test] +fn matrix_2x3() { + let expr = " + + + [ + + + + 3 + + + 1 + + + 4 + + + + + 0 + + + 2 + + + 6 + + + + ] + + "; + test("nb", "ClearSpeak", expr, "2 ganger 3 matrise; rad 1; 3, 1, 4; rad 2; 0, 2, 6"); + test("nb", "SimpleSpeak", expr, "2 ganger 3 matrise; rad 1; 3, 1, 4; rad 2; 0, 2, 6"); +} + +#[test] +fn matrix_2x3_labeled() { + let expr = " + + + [ + + + + (3.1) + + + 3 + + + 1 + + + 4 + + + + + 0 + + + 2 + + + 6 + + + + ] + + "; + test("nb", "ClearSpeak", expr, + "2 ganger 3 matrise; rad 1 med etiketten (3 punktum 1); kolonne 1; 3, kolonne 2; 1, kolonne 3; 4; rad 2; kolonne 1; 0, kolonne 2; 2, kolonne 3; 6"); + test("nb", "SimpleSpeak", expr, + "2 ganger 3 matrise; rad 1 med etiketten (3 punktum 1); kolonne 1; 3, kolonne 2; 1, kolonne 3; 4; rad 2; kolonne 1; 0, kolonne 2; 2, kolonne 3; 6"); +} + +#[test] +fn matrix_3x1() { + let expr = " + + + [ + + + + 1 + + + + + 2 + + + + + 3 + + + ] + + "; + test("nb", "ClearSpeak", expr, "3 ganger 1 kolonne-matrise; 1; 2; 3"); + test("nb", "SimpleSpeak", expr, "3 ganger 1 kolonne-matrise; 1; 2; 3"); +} + +#[test] +fn matrix_4x1() { + let expr = " + + + ( + + + + 3 + + + + + 6 + + + + + 1 + + + + + 2 + + + + ) + + "; + test("nb", "ClearSpeak", expr, "4 ganger 1 kolonne-matrise; rad 1; 3; rad 2; 6; rad 3; 1; rad 4; 2"); + test("nb", "SimpleSpeak", expr, "4 ganger 1 kolonne-matrise; rad 1; 3; rad 2; 6; rad 3; 1; rad 4; 2"); +} + +#[test] +fn matrix_4x1_labeled() { + let expr = " + + + ( + + + + 3 + + + + + 6 + + + + + 1 + + + + + (3.1) + + + 2 + + + + ) + + "; + test("nb", "ClearSpeak", expr, + "4 ganger 1 kolonne-matrise; rad 1; 3; rad 2; 6; rad 3; 1; rad 4 med etiketten (3 punktum 1); 2"); + test("nb", "SimpleSpeak", expr, + "4 ganger 1 kolonne-matrise; rad 1; 3; rad 2; 6; rad 3; 1; rad 4 med etiketten (3 punktum 1); 2"); +} + +#[test] +fn matrix_1x4() { + let expr = " + + + ( + + + + 3 + + + 6 + + + 1 + + + 2 + + + + ) + + "; + test("nb", "ClearSpeak", expr, "1 ganger 4 rad-matrise; kolonne 1; 3, kolonne 2; 6, kolonne 3; 1, kolonne 4; 2"); + test("nb", "SimpleSpeak", expr, "1 ganger 4 rad-matrise; kolonne 1; 3, kolonne 2; 6, kolonne 3; 1, kolonne 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("nb", "ClearSpeak", expr, "4 ganger 4 matrise; \ + rad 1; kolonne 1; 0, kolonne 2; 3, kolonne 3; 4, kolonne 4; 3; \ + rad 2; kolonne 1; 2, kolonne 2; 1, kolonne 3; 0, kolonne 4; 9; \ + rad 3; kolonne 1; 3, kolonne 2; 0, kolonne 3; 2, kolonne 4; 1; \ + rad 4; kolonne 1; 6, kolonne 2; 2, kolonne 3; 9, kolonne 4; 0"); + test("nb", "SimpleSpeak", expr, "4 ganger 4 matrise; \ + rad 1; kolonne 1; 0, kolonne 2; 3, kolonne 3; 4, kolonne 4; 3; \ + rad 2; kolonne 1; 2, kolonne 2; 1, kolonne 3; 0, kolonne 4; 9; \ + rad 3; kolonne 1; 3, kolonne 2; 0, kolonne 3; 2, kolonne 4; 1; \ + rad 4; kolonne 1; 6, kolonne 2; 2, kolonne 3; 9, kolonne 4; 0");} + +#[test] +fn matrix_4x2() { + let expr = " + + + ( + + + + 1 + + + 3 + + + + + 4 + + + 2 + + + + + 2 + + + 1 + + + + + 0 + + + 5 + + + + + ) + + "; + test("nb", "ClearSpeak", expr, "4 ganger 2 matrise; \ + rad 1; kolonne 1; 1, kolonne 2; 3; \ + rad 2; kolonne 1; 4, kolonne 2; 2; \ + rad 3; kolonne 1; 2, kolonne 2; 1; \ + rad 4; kolonne 1; 0, kolonne 2; 5\ + "); + test("nb", "SimpleSpeak", expr, "4 ganger 2 matrise; \ + rad 1; kolonne 1; 1, kolonne 2; 3; \ + rad 2; kolonne 1; 4, kolonne 2; 2; \ + rad 3; kolonne 1; 2, kolonne 2; 1; \ + rad 4; kolonne 1; 0, kolonne 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("nb", "SimpleSpeak", expr, "absoluttverdien av x"); + test("nb", "ClearSpeak", expr, "absoluttverdien av x"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Terse"), ("ClearSpeak_AbsoluteValue", "Auto")], expr, "absoluttverdien av x"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Verbose"), ("ClearSpeak_AbsoluteValue", "AbsEnd")], + expr, "absoluttverdien av x, slutt absoluttverdi"); +} + +#[test] +fn absolute_value_plus_1() { +let expr = " + | + x+1 + | + "; + test("nb", "ClearSpeak", expr, "absoluttverdien av x pluss 1"); + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Terse"), ("ClearSpeak_AbsoluteValue", "AbsEnd")], + expr, "absoluttverdien av x pluss 1, slutt absoluttverdi"); +} + +#[test] +fn simple_cardinality_value() { + let expr = " + | S | + "; + test_prefs("nb", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_AbsoluteValue", "Cardinality")], expr, + "kardinaliteten til stor s"); +} + +// Test preferences +#[test] +fn simple_matrix_speak_col_num() { +let expr = " + + ( + + + + 2 + 1 + + + 7 + 5 + + + ) + "; + test_ClearSpeak("nb", "ClearSpeak_Matrix", "SpeakColNum", + expr, "2 ganger 2 matrise; rad 1; kolonne 1; 2, kolonne 2; 1; rad 2; kolonne 1; 7, kolonne 2; 5"); +} + +#[test] +fn col_matrix_3x1_speak_col_num() { +let expr = " + + ( + + + + 1 + + + 2 + + + 3 + + + ) + "; +test_ClearSpeak("nb", "ClearSpeak_Matrix", "SpeakColNum", + expr, "3 ganger 1 kolonne-matrise; rad 1; 1; rad 2; 2; rad 3; 3"); +} + +#[test] +fn row_matrix_1x2_speak_col_num() { +let expr = " + + [ + + + + 1 2 + + + ] + "; +test_ClearSpeak("nb", "ClearSpeak_Matrix", "SpeakColNum", + expr, "1 ganger 2 rad-matrise; kolonne 1; 1, kolonne 2; 2"); +} + +#[test] +fn matrix_2x2_speak_col_num() { +let expr = "( + + + b11 + b12 + + + b21 + b22 + + + )"; +test_ClearSpeak("nb", "ClearSpeak_Matrix", "SpeakColNum", + expr, "2 ganger 2 matrise; rad 1; kolonne 1; b, senket 1 1; kolonne 2; b, senket 1 2; rad 2; kolonne 1; b, senket 2 1; kolonne 2; b, senket 2 2"); +} + + +#[test] +fn simple_matrix_silent_col_num() { +let expr = " + + ( + + + + 2 + 1 + + + 7 + 5 + + + ) + "; + test_ClearSpeak("nb", "ClearSpeak_Matrix", "SilentColNum", + expr, "2 ganger 2 matrise; rad 1; 2, 1; rad 2; 7, 5"); +} + +#[test] +fn col_matrix_3x1_silent_col_num() { +let expr = " + + ( + + + + 1 + + + 2 + + + 3 + + + ) + "; +test_ClearSpeak("nb", "ClearSpeak_Matrix", "SilentColNum", + expr, "3 ganger 1 kolonne-matrise; 1; 2; 3"); +} + +#[test] +fn row_matrix_1x2_silent_col_num() { +let expr = " + + [ + + + + 1 2 + + + ] + "; +test_ClearSpeak("nb", "ClearSpeak_Matrix", "SilentColNum", + expr, "1 ganger 2 rad-matrise; 1, 2"); +} + +#[test] +fn matrix_2x2_silent_col_num() { +let expr = "( + + + b11 + b12 + + + b21 + b22 + + + )"; +test_ClearSpeak("nb", "ClearSpeak_Matrix", "SilentColNum", + expr, "2 ganger 2 matrise; rad 1; b, senket 1 1; b, senket 1 2; rad 2; b, senket 2 1; b, senket 2 2"); +} + + +#[test] +fn simple_matrix_end_matrix() { +let expr = " + + ( + + + + 2 + 1 + + + 7 + 5 + + + ) + "; + test_ClearSpeak("nb", "ClearSpeak_Matrix", "EndMatrix", + expr, "2 ganger 2 matrise; rad 1; 2, 1; rad 2; 7, 5; slutt matrise"); +} + +#[test] +fn col_matrix_3x1_end_matrix() { +let expr = " + + ( + + + + 1 + + + 2 + + + 3 + + + ) + "; +test_ClearSpeak("nb", "ClearSpeak_Matrix", "EndMatrix", + expr, "3 ganger 1 kolonne-matrise; 1; 2; 3; slutt matrise"); +} + +#[test] +fn row_matrix_1x2_end_matrix() { +let expr = " + + [ + + + + 1 2 + + + ] + "; +test_ClearSpeak("nb", "ClearSpeak_Matrix", "EndMatrix", + expr, "1 ganger 2 rad-matrise; 1, 2; slutt matrise"); +} + +#[test] +fn matrix_2x2_end_matrix() { +let expr = "( + + + b11 + b12 + + + b21 + b22 + + + )"; +test_ClearSpeak("nb", "ClearSpeak_Matrix", "EndMatrix", + expr, "2 ganger 2 matrise; rad 1; kolonne 1; b, senket 1 1; kolonne 2; b, senket 1 2; rad 2; kolonne 1; b, senket 2 1; kolonne 2; b, senket 2 2; slutt matrise"); +} + + +#[test] +fn simple_matrix_vector() { +let expr = " + + ( + + + + 2 + 1 + + + 7 + 5 + + + ) + "; + test_ClearSpeak("nb", "ClearSpeak_Matrix", "Vector", + expr, "2 ganger 2 matrise; rad 1; 2, 1; rad 2; 7, 5"); +} + +#[test] +fn col_matrix_3x1_vector() { +let expr = " + + ( + + + + 1 + + + 2 + + + 3 + + + ) + "; +test_ClearSpeak("nb", "ClearSpeak_Matrix", "Vector", + expr, "3 ganger 1 kolonne-vektor; 1; 2; 3"); +} + +#[test] +fn row_matrix_1x2_vector() { +let expr = " + + [ + + + + 1 2 + + + ] + "; +test_ClearSpeak("nb", "ClearSpeak_Matrix", "Vector", + expr, "1 ganger 2 rad-vektor; 1, 2"); +} + +#[test] +fn matrix_2x2_vector() { +let expr = "( + + + b11 + b12 + + + b21 + b22 + + + )"; +test_ClearSpeak("nb", "ClearSpeak_Matrix", "Vector", + expr, "2 ganger 2 matrise; rad 1; kolonne 1; b, senket 1 1; kolonne 2; b, senket 1 2; rad 2; kolonne 1; b, senket 2 1; kolonne 2; b, senket 2 2"); +} + + +#[test] +fn simple_matrix_end_vector() { +let expr = " + + ( + + + + 2 + 1 + + + 7 + 5 + + + ) + "; + test_ClearSpeak("nb", "ClearSpeak_Matrix", "EndVector", + expr, "2 ganger 2 matrise; rad 1; 2, 1; rad 2; 7, 5; slutt matrise"); +} + +#[test] +fn col_matrix_3x1_end_vector() { +let expr = " + + ( + + + + 1 + + + 2 + + + 3 + + + ) + "; +test_ClearSpeak("nb", "ClearSpeak_Matrix", "EndVector", + expr, "3 ganger 1 kolonne-vektor; 1; 2; 3; slutt vektor"); +} + +#[test] +fn row_matrix_1x2_end_vector() { +let expr = " + + [ + + + + 1 2 + + + ] + "; +test_ClearSpeak("nb", "ClearSpeak_Matrix", "EndVector", + expr, "1 ganger 2 rad-vektor; 1, 2; slutt vektor"); +} + +#[test] +fn matrix_2x2_end_vector() { +let expr = "( + + + b11 + b12 + + + b21 + b22 + + + )"; +test_ClearSpeak("nb", "ClearSpeak_Matrix", "EndVector", + expr, "2 ganger 2 matrise; rad 1; kolonne 1; b, senket 1 1; kolonne 2; b, senket 1 2; rad 2; kolonne 1; b, senket 2 1; kolonne 2; b, senket 2 2; slutt matrise"); +} + + + +#[test] +fn matrix_binomial() { + let expr = " + ( + 32 + ) + "; + test_ClearSpeak("nb", "ClearSpeak_Matrix", "Combinatorics", expr, "3 over 2"); +} + +#[test] +fn matrix_times() { + let expr = " + 1234 + abcd + "; + test("nb", "SimpleSpeak", expr, + "2 ganger 2 matrise; rad 1; 1, 2; rad 2; 3, 4; ganger, 2 ganger 2 matrise; rad 1; a, b; rad 2; c, d"); +} + +#[test] +fn unknown_mtable_property() { + let expr = " + + + + a + + + = + + + + b + + + c + − + d + + + + + + + + + + e + − + f + + + + "; + test("nb", "ClearSpeak", expr, + "2 rader; rad 1; a er lik, b pluss c minus d; rad 2; pluss e minus f"); +} + + +#[test] +fn zero_matrix() { + let expr = " + [ + + 00 + 00 + + ] + "; + test("nb", "SimpleSpeak", expr, + "2 ganger 2 null-matrise"); +} + +#[test] +fn identity_matrix() { + let expr = " + ( + + 100 + 010 + 001 + + ) + "; + test("nb", "SimpleSpeak", expr, + "3 ganger 3 identitetsmatrise"); +} + +#[test] +fn diagonal_matrix() { + let expr = " + ( + + 200 + 010 + 00x2 + + ) + "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "3 ganger 3 diagonalmatrise; kolonne 1; 2; kolonne 2; 1; kolonne 3; x i andre"); + // test_prefs("en", "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"); +} diff --git a/tests/Languages/nb/shared.rs b/tests/Languages/nb/shared.rs new file mode 100644 index 000000000..65c791267 --- /dev/null +++ b/tests/Languages/nb/shared.rs @@ -0,0 +1,458 @@ +/// 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("nb", "SimpleSpeak", expr, + "a grav aksent, b tilde, c breve, b hake, c grav aksent; pluss \ + r hake pluss; x prikk, y prikk, z trema, u trippel prikk; v fire prikker; pluss x hatt, pluss vektoren t"); +} + +#[test] +fn limit() { + let expr = " + + lim + x → 0 + + + + sin ⁡ x + x + + + "; + test("nb", "SimpleSpeak", expr, "grenseverdien når x går mot 0, av, brøk, sinus av x, over x, slutt brøk"); + test_prefs("nb", "SimpleSpeak", vec![("Impairment", "LearningDisability")], expr, + "grenseverdien når x går mot 0, av, brøk, sinus av x, over x, slutt brøk"); +} + +#[test] +fn limit_from_below() { + let expr = " + + lim + x ↗ 0 + + + sin ⁡ x + + "; + test("nb", "SimpleSpeak", expr, "grenseverdien når x går fra venstre mot 0, av sinus av x"); +} + + +#[test] +fn binomial_mmultiscripts() { + let expr = "Cmn"; + test("nb", "SimpleSpeak", expr, "n over m"); +} + +#[test] +fn binomial_mmultiscripts_other() { + let expr = "Cmn"; + test("nb", "SimpleSpeak", expr, "n over m"); +} + +#[test] +fn binomial_subscript() { // C_{n,k} + let expr = "Cn,m"; + test("nb", "SimpleSpeak", expr, "n over m"); +} + +#[test] +fn permutation_mmultiscripts() { + let expr = "Pkn"; + test("nb", "SimpleSpeak", expr, "antallet permutasjoner av k elementer av n"); +} + +#[test] +fn permutation_mmultiscripts_sup() { + let expr = "Pkn"; + test("nb", "SimpleSpeak", expr, "antallet permutasjoner av k elementer av n"); +} + +#[test] +fn permutation_msubsup() { + let expr = "Pkn"; + test("nb", "SimpleSpeak", expr, "antallet permutasjoner av k elementer av n"); +} + +#[test] +fn tensor_mmultiscripts() { + let expr = " + R i j k l + "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, + "stor r med 4 høyre indeks, senket i, hevet j, senket k, senket l"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Medium")], expr, + "stor r med 4 høyre indeks, senket i, hevet j, senket k, senket l"); +} + +#[test] +fn huge_num_mmultiscripts() { + let expr = " + R i j k l m + I J K L + "; + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, + "stor r med 4 venstre indeks, senket stor i; hevet stor j, og resterende venstre indeks stor k none stor l none slutt venstre indeks og med 5 høyre indeks, senket i, hevet j, senket k, senket l, og resterende høyre indeks m none slutt indeks"); +} + +#[test] +fn prime() { + let expr = " x′ "; + test("nb", "SimpleSpeak", expr, "x primtegn"); +} + +#[test] +fn given() { + let expr = "P(A|B)"; + test("nb", "SimpleSpeak", expr, "stor p; startparentes; stor a, gitt stor b; sluttparentes"); + test("nb", "ClearSpeak", expr, "stor p; startparentes; stor a, gitt stor b; sluttparentes"); // not good, but follows the spec +} + +#[test] +fn simple_msubsup() { + let expr = " + + + x + + k + + + i + + + + "; + test("nb", "ClearSpeak", expr, "x, senket k, opphøyd i i"); +} + +#[test] +fn non_simple_msubsup() { + let expr = "ij−2k"; + test("nb", "SimpleSpeak", expr, "i senket j minus 2 slutt senket, opphøyd i k"); + test("nb", "ClearSpeak", expr, "i senket j minus 2 slutt senket, opphøyd i k"); + test_prefs("nb", "SimpleSpeak", vec![("Impairment", "LearningDisability")], expr, + "i senket j minus 2, opphøyd i k"); +} + +#[test] +fn presentation_mathml_in_semantics() { + let expr = " + + {\\displaystyle x_k^i} + + + x + + k + + + i + + + + + "; + test("nb", "ClearSpeak", expr, "x, senket k, opphøyd i i"); +} + +#[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("nb", "SimpleSpeak", expr, "stor p; startparentes; stor a and stor b; sluttparentes; er lik; stor p; startparentes; stor a snitt stor b; sluttparentes; er lik, stor p av stor a, stor p av stor b"); +} + +#[test] +fn ignore_mtext_period() { + let expr = "{2}."; + test("nb", "SimpleSpeak", expr, "mengden 2"); +} + +#[test] +fn ignore_comma() { + // from https://en.wikipedia.org/wiki/Probability + let expr = " + + + ϕ + ( + x + ) + = + c + + e + + − + + h + + 2 + + + + x + + 2 + + + + + , + + +"; + test("nb", "SimpleSpeak", expr, "fi av x er lik, c ganger, e opphøyd i minus h i andre, x i andre"); +} + +#[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("nb", "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("nb", "SimpleSpeak",expr, "det halvåpne intervallet fra og med 0 til 2 pi"); +} + +#[test] +fn caret_and_hat() { + let expr = "x^2+y^"; + test("nb", "SimpleSpeak",expr, "x hatt 2 pluss y hatt"); +} + +#[test] +fn mn_with_space() { + let expr = "1 234 567"; + test_prefs("nb", "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("nb", "SimpleSpeak", vec![("DecimalSeparators", ","), ("BlockSeparators", " .")], expr, "1234,56"); +} + +#[test] +fn divergence() { + let expr = "∇·F"; // may want to change this for another language + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "div stor f"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "divergensen til stor f"); +} + +#[test] +fn curl() { + let expr = "∇×F"; + // may want to change this for another language + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "curl stor f"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "curlen til stor f"); +} + +#[test] +fn gradient() { + let expr = "∇F"; + // may want to change this for another language + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "gradienten til stor f"); + test_prefs("nb", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "gradienten til stor f"); +} + +#[test] +fn literal_speak() { + let expr = r#" + + + A + → + + ⊥ + + B + → + + + "#; + test("nb", "LiteralSpeak", expr, "stor a høyrepil, perpendicular to, stor b høyrepil"); +} + +#[test] +fn literal_speak_with_name() { + let expr = r#" + + f + ⁡ + + ( + + x + ! + + ) + + + "#; + test("nb", "LiteralSpeak", expr, "forced f, venstreparentes; x utropstegn; høyreparentes"); +} + +#[test] +fn literal_speak_with_property() { + let expr = r#" + + f + ⁡ + + ( + + x + ! + + ) + + + "#; + test("nb", "LiteralSpeak", expr, "f, venstreparentes; x utropstegn; høyreparentes"); +} + +#[test] +fn literal_intent_property() { + let expr = r#" + + + A + → + + ⊥ + + B + → + + + "#; + test("nb", "SimpleSpeak", expr, "stor a høyrepil, perpendicular to, stor b høyrepil"); +} + +#[test] +fn literal_intent_property_with_name() { + let expr = r#" + + f + ⁡ + + ( + + x + ! + + ) + + + "#; + test("nb", "SimpleSpeak", expr, "forced f; startparentes; x utropstegn; sluttparentes"); +} diff --git a/tests/Languages/nb/units.rs b/tests/Languages/nb/units.rs new file mode 100644 index 000000000..a41951aec --- /dev/null +++ b/tests/Languages/nb/units.rs @@ -0,0 +1,477 @@ +/// 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("nb", "SimpleSpeak", expr, + "quetta-gram, komma, \ + ronna-gram komma, \ + yotta-gram komma, \ + zetta-gram komma, \ + exa-gram komma, \ + peta-gram komma, \ + tera-gram komma, \ + giga-gram komma, \ + mega-gram komma, \ + kilo-gram komma, \ + hekto-gram komma, \ + deka-gram komma, \ + desi-gram komma, \ + centi-gram komma, \ + milli-gram komma, \ + mikro-gram komma, \ + nano-gram komma, \ + piko-gram komma, \ + femto-gram komma, \ + atto-gram komma, \ + zepto-gram komma, \ + yokto-gram komma, \ + ronto-gram komma, \ + quecto-gram"); +} + +#[test] +fn si_base() { + let expr = r#" + 1A,2A, + 1cd,2cd, + 1K,2K, + 1K,2K, + 1g,2g, + 1m,2m, + 1mol,2mol, + 1s,2s, + 1″,2″, + 1",2", + 1sek,2sek + "#; + test("nb", "SimpleSpeak", expr, + "1 ampere, komma, 2 ampere, komma, \ + 1 candela, komma, 2 candela, komma, \ + 1 kelvin, komma, 2 kelvin, komma, \ + 1 kelvin, komma, 2 kelvin, komma, \ + 1 gram, komma, 2 gram, komma, \ + 1 meter, komma, 2 meter, komma, \ + 1 mol, komma, 2 mol, komma, \ + 1 sekund, komma, 2 sekunder, komma, \ + 1 sekund, komma, 2 sekunder, komma, \ + 1 sekund, komma, 2 sekunder, komma, \ + 1 sekund, komma, 2 sekunder"); +} + +#[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, + 1nsek,2psek + "#; + test("nb", "SimpleSpeak", expr, + "1 quetta-ampere, komma; 2 ronna-ampere, komma; \ + 1 yotta-candela, komma; 2 zetta-candela, komma; \ + 1 exa-kelvin, komma; 2 peta-kelvin, komma; \ + 1 tera-kelvin, komma; 2 giga-kelvin, komma; \ + 1 mega-gram, komma; 2 kilo-gram, komma; \ + 1 hekto-meter, komma; 2 deka-meter, komma; \ + 1 desi-mol, komma; 2 centi-mol, komma; \ + 1 milli-sekund, komma; 2 mikro-sekunder, komma; \ + 1 nano-sekund, komma; 2 piko-sekunder"); +} + + +#[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("nb", "SimpleSpeak", expr, + "1 becquerel, komma, 2 becquerel, komma, \ + 1 coulomb, komma, 2 coulomb, komma; \ + 1 grad celsius, komma; 2 grader celsius, komma; \ + 1 grad celsius, komma; 2 grader celsius, komma, \ + 1 farad, komma, 2 farad, komma, \ + 1 gray, komma, 2 gray, komma, \ + 1 henry, komma, 2 henry, komma, \ + 1 hertz, komma, 2 hertz, komma, \ + 1 joule, komma, 2 joule, komma, \ + 1 katal, komma, 2 katal, komma, \ + 1 lumen, komma, 2 lumen, komma, \ + 1 lux, komma, 2 lux"); +} + +#[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("nb", "SimpleSpeak", expr, + "1 quetta-becquerel, komma; 2 ronna-becquerel, komma; \ + 1 yotta-coulomb, komma; 2 zetta-coulomb, komma; \ + 1 exa-farad, komma; 2 peta-farad, komma; \ + 1 tera-gray, komma; 2 giga-gray, komma; \ + 1 mega-henry, komma; 2 kilo-henry, komma; \ + 1 deka-hertz, komma; 2 desi-hertz, komma; \ + 1 centi-joule, komma; 2 milli-joule, komma; \ + 1 mikro-katal, komma; 2 nano-katal, komma; \ + 1 piko-lumen, komma; 2 femto-lumen, komma; \ + 1 atto-lux, komma; 2 zepto-lux, komma; \ + 1 milli-grad celsius, komma; 2 mikro-grader celsius; komma; \ + 1 piko-grad celsius, komma; 2 nano-grader 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("nb", "SimpleSpeak", expr, + "1 newton, komma, 2 newton, komma, \ + 1 ohm, komma, 2 ohm, komma, \ + 1 ohm, komma, 2 ohm, komma, \ + 1 pascal, komma, 2 pascal, komma, \ + 1 siemens, komma, 2 siemens, komma, \ + 1 sievert, komma, 2 sievert, komma, \ + 1 tesla, komma, 2 tesla, komma, \ + 1 volt, komma, 2 volt, komma, \ + 1 watt, komma, 2 watt, komma, \ + 1 weber, komma, 2 weber"); +} + +#[test] +fn si_derived_2_with_prefixes() { + let expr = r#" + 1qN,2rN, + 1yΩ,2zΩ, + 1aΩ,2fΩ, + 1pPa,2nPa, + 1µS,2mS, + 1cSv,2dSv, + 1daT,2hT, + 1kV,2MV, + 1GW,2TW, + 1PWb,2EWb + "#; + test("nb", "SimpleSpeak", expr, + "1 quecto-newton, komma; 2 ronto-newton, komma; \ + 1 yokto-ohm, komma; 2 zepto-ohm, komma; \ + 1 atto-ohm, komma; 2 femto-ohm, komma; \ + 1 piko-pascal, komma; 2 nano-pascal, komma; \ + 1 mikro-siemens, komma; 2 milli-siemens, komma; \ + 1 centi-sievert, komma; 2 desi-sievert, komma; \ + 1 deka-tesla, komma; 2 hekto-tesla, komma; \ + 1 kilo-volt, komma; 2 mega-volt, komma; \ + 1 giga-watt, komma; 2 tera-watt, komma; \ + 1 peta-weber, komma; 2 exa-weber"); +} + + +#[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("nb", "SimpleSpeak", expr, + "1 liter, komma, 2 liter, komma, 1 liter, komma, 2 liter, komma, 1 liter, komma, 2 liter, komma, 1 tonn, komma, 2 tonn, komma, 1 dalton, komma, 2 dalton, komma, 1 neper, komma, 2 neper, komma; 1 atommasseenhet, komma; 2 atommasseenheter, komma; 1 elektronvolt, komma; 2 elektronvolt, komma, 1 radian, komma, 2 radianer, komma, 1 steradian, komma, 2 steradianer, komma, 1 annuum, komma, 2 annua, komma, 1 buesekund, komma, 2 buesekunder, komma, 1 bit, komma, 2 bit, komma, 1 byte, komma, 2 byte, komma, 1 baud, komma, 2 bauder"); +} + +#[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("nb", "SimpleSpeak", expr, + "1 quetta-liter, komma; 2 ronna-liter, komma; \ + 1 yotta-liter, komma; 2 zetta-liter, komma; \ + 1 exa-liter, komma; 2 peta-liter, komma; \ + 1 tera-tonn, komma; 2 giga-tonn, komma; \ + 1 mega-dalton, komma; 2 kilo-dalton, komma; \ + 1 desi-neper, komma; 2 centi-neper, komma; \ + 1 hekto-atommasseenhet; komma; 2 deka-atommasseenheter; komma; \ + 1 milli-elektronvolt, komma; 2 mikro-elektronvolt, komma; \ + 1 nano-radian, komma; 2 piko-radianer, komma; \ + 1 femto-steradian, komma; 2 atto-steradianer, komma; \ + 1 giga-annuum, komma; 2 mega-annua, komma; \ + 1 zepto-buesekund, komma; 2 yokto-buesekunder, komma; \ + 1 kilo-bit, komma; 2 mega-bit, komma; \ + 1 giga-byte, komma; 2 tera-byte, komma; \ + 1 tera-baud, komma; 2 exa-bauder"); +} + +#[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("nb", "SimpleSpeak", expr, + "1 sekund, komma, 2 sekunder, komma, \ + 1 sekund, komma, 2 sekunder, komma, \ + 1 minutt, komma, 2 minutter, komma, \ + 1 minutt, komma, 2 minutter, komma, \ + 1 minutt, komma, 2 minutter, komma, \ + 1 time, komma, 2 timer, komma, \ + 1 time, komma, 2 timer, komma, \ + 1 time, komma, 2 timer, komma, \ + 1 dag, komma, 2 dager, komma, \ + 1 dag, komma, 2 dager, komma, \ + 1 uke, komma, 2 uker, komma, \ + 1 uke, komma, 2 uker, komma, \ + 1 år, komma, 2 år, komma, \ + 1 år, komma, 2 år"); +} + +#[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("nb", "SimpleSpeak", expr, + "1 grad, komma, 2 grader, komma, \ + 1 grad, komma, 2 grader, komma, \ + 1 bueminutt, komma, 2 bueminutter, komma, \ + 1 bueminutt, komma, 2 bueminutter, komma, \ + 1 bueminutt, komma, 2 bueminutter, komma, \ + 1 bueminutt, komma, 2 bueminutter, komma, \ + 1 buesekund, komma, 2 buesekunder, komma, \ + 1 buesekund, komma, 2 buesekunder"); +} + +#[test] +fn without_prefix_distance() { + let expr = r#" + 1au,2au, + 1ltyr,2ltyr, + 1pc,2pc, + 1Å,2Å, + 1Å,2Å, + 1fm,2fm + "#; + test("nb", "SimpleSpeak", expr, + "1 astronomisk enhet, komma; 2 astronomiske enheter, komma, \ + 1 lysår, komma, 2 lysår, komma, \ + 1 parsec, komma, 2 parsec, komma, \ + 1 ångstrøm, komma, 2 ångstrøm, komma, \ + 1 ångstrøm, komma, 2 ångstrøm, komma, \ + 1 fermi, komma, 2 fermi"); +} + +#[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("nb", "SimpleSpeak", expr, + "1 hektar, komma, 2 hektar, komma, \ + 1 desibel, komma, 2 desibel, komma, \ + 1 atmosfære, komma, 2 atmosfærer, komma; \ + 1 atommasseenhet, komma; 2 atommasseenheter, komma, \ + 1 bar, komma, 2 bar, komma, \ + 1 kalori, komma, 2 kalorier, komma, \ + 1 curie, komma, 2 curier, komma, \ + 1 gon, komma, 2 gon, komma, \ + 1 molar, komma, 2 molar, komma, \ + 1 røntgen, komma, 2 røntgen, komma; \ + 1 omdreining per minutt, komma; 2 omdreininger per minutt, komma, \ + 1 m-h-o, komma, 2 m-h-o, komma, \ + 1 dyn, komma, 2 dyn, komma, \ + 1 erg, komma, 2 erg"); +} + +#[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("nb", "SimpleSpeak", expr, + "1 kibibit, komma, 2 kibibit, komma, \ + 1 mebibit, komma, 2 mebibit, komma, \ + 1 gibibit, komma, 2 gibibit, komma, \ + 1 tebibit, komma, 2 tebibit, komma, \ + 1 pebibit, komma, 2 pebibit, komma, \ + 1 exbibit, komma, 2 exbibit, komma, \ + 1 zebibit, komma, 2 zebibit, komma, \ + 1 yobibit, komma, 2 yobibit, komma, \ + 1 kibibyte, komma, 2 kibibyte, komma, \ + 1 mebibyte, komma, 2 mebibyte, komma, \ + 1 gibibyte, komma, 2 gibibyte, komma, \ + 1 tebibyte, komma, 2 tebibyte, komma, \ + 1 pebibyte, komma, 2 pebibyte, komma, \ + 1 exbibyte, komma, 2 exbibyte, komma, \ + 1 zebibyte, komma, 2 zebibyte, komma, \ + 1 yobibyte, komma, 2 yobibyte"); +} + + +#[test] +fn si_other_numbers() { + let expr = r#"1,0l, + 2,0 m, + x ms, + yµs, + dag, + 1235daN, + 2,5µsek, + 32,34mol"#; + test_prefs("nb", "SimpleSpeak", vec![("DecimalSeparators", ","), ("BlockSeparators", ".")], expr, + "1,0 liter, komma, 2,0 meter, komma; x milli-sekunder, komma; y mikro-sekunder, komma, deka-gram komma; 1235 deka-newton, komma; 2,5 mikro-sekunder, komma, 32,34 mol"); +} + + +#[test] +fn test_mtext_inference() { + let expr = r#"[ + 1t, + 2PA, + 3Pa, + 4,5mT + ]"#; + test_prefs("nb", "SimpleSpeak", vec![("DecimalSeparators", ","), ("BlockSeparators", ".")], expr, + "start hakeparentes; 1 tonn, komma; 2 peta-ampere, komma, 3 pascal, komma; 4,5 milli-tesla; slutt hakeparentes"); +} \ No newline at end of file diff --git a/tests/languages.rs b/tests/languages.rs index b2b69e559..52975c5cc 100644 --- a/tests/languages.rs +++ b/tests/languages.rs @@ -8,6 +8,7 @@ mod Languages { mod en; mod fi; mod sv; + mod nb; mod vi { mod vi; }