---
- 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   #audit-ignore
  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   # audit-ignore
  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    # audit-ignore
  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]"

# Note: if the bounds change for what is a common fraction, change them in general.yaml for units
- name: common-fraction  # audit-ignore
  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: "not(*[1]=1)"
    # set right level for the location of the common fraction/mixed fraction
  - IsMixedFraction: "preceding-sibling::*[1][.='\u2064']"
  - UnitSibling: "IfThenElse($IsMixedFraction, .., .)"
    # set the potential unit node -- otherwise set it to a empty node set (use a made up name)
  - UnitNodeLocation: "IfThenElse($UnitSibling/..[self::m:mrow and count(*)=3 and *[2][.='\u2062']],
                                  $UnitSibling/following-sibling::*[2],
                                  self::m:select-no-nodes)"
    # pick out the right node to test for being a neuter unit
  - UnitNode: "IfThenElse($UnitNodeLocation[self::m:unit],
                          $UnitNodeLocation[self::m:unit],
                          $UnitNodeLocation[self::m:fraction[contains(@data-intent-property, ':unit:')]]/*[1])"
    # test the node for being a neuter unit
    # note: bias ha->hektar and Pa->Pascal, not si-prefix "a" (annum)
  - NeuterUnitFollows: "$UnitNode[IsInDefinition(., 'Speech', 'NeuterUnits') or 
                                  IsInDefinition(., 'Speech', 'NeuterUnitsWithoutPrefixes') or
                                  (string-length(.) >= 2 and
                                    . != 'ha' and . != 'Pa' and
                                    DefinitionValue(substring(., 1, 1), 'Speech', 'SIPrefixes') != '' and
                                    IsInDefinition(substring(., 2), 'Speech', 'NeuterUnits') != ''
                                  ) ]"  
  replace:
  - test:
    - if: "not($UnitNode)"
      then:
      - x: "*[1]"
      - x: "ToOrdinal(*[2], true(), $IsPlural)"   # extra args specify fractional ordinal and whether it is plural
    # unit follows the fraction -- special cases
    - else:
      - test:
          if: "$NeuterUnitFollows and *[1]=1"
          then: [T: "ett"]
          else: [x: "*[1]"]
      - test:
        - if: "*[1]=1 and *[2]=2"
          then_test:
          - if: "$NeuterUnitFollows"
            then: [T: "halvt"]
            else: [T: "halv"]
        - else_if: "*[2] <= 10"
          then: [x: "DefinitionValue(*[2], 'Speech', 'OrdinalFractionalDenominatorsForUnits')"]
          else: [x: "*[2]", CT: "dels"]   # this is wrong but shouldn't occur normally -- need to write a function to compute cardinal numbers as words

# NORWEGIAN: Changed to English version, but changed decimal point to $DecimalSeparators 
- name: fraction-over-simple    # audit-ignore
  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
      else: 
      - pause: short

- # fraction with text or numbers followed by text in both numerator and denominator
  name: fraction-over-text    # audit-ignore
  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
      else: 
      - 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')

# The following element is invisible function application. Used for expressions like sin^n x.
- name: function-power    # audit-ignore
  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)

# Norwegian: Changed to longer pause at the end.
- name: simple-integer    # audit-ignore
  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: medium

# Norwegian: Changed to longer pause at the end.
- name: simple-negative-integer    # audit-ignore
  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: medium

# Norwegian: Changed to longer pause at the end.
- name: simple-var    # audit-ignore
  tag: power
  match: "*[2][self::m:mi][string-length(.)=1]"
  replace:
  - x: "*[1]"
  - T: "opphøyd i"
  - bookmark: "*[2]/@id"
  - x: "*[2]"
  - pause: medium

# 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
  # Norwegian: Added "end exponent" for verbose, and longer pause for terse and medium.
  name: nested-squared-or-cubed   # audit-ignore
  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]"
  - test:
      if: "$Verbosity='Verbose'"
      then: 
        - pause: short
        - T: "slutt eksponent"
      else: [pause: medium]

- # - [xxx]^n
  # Norwegian: Added "end exponent" for verbose, and longer pause for terse and medium.
  name: nested-negative-squared-or-cubed    # audit-ignore
  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]"
  - test:
      if: "$Verbosity='Verbose'"
      then: 
        - pause: short
        - T: "slutt eksponent"
      else: [pause: medium]

- # [xxx] var^n
  # Norwegian: Added "end exponent" for verbose, and longer pause for terse and medium.
  name: nested-var-squared-or-cubed   # audit-ignore
  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]"
  - test:
      if: "$Verbosity='Verbose'"
      then: 
        - pause: short
        - T: "slutt eksponent"
      else: [pause: medium]

- # -[xxx] var^n
  # Norwegian: Added "end exponent" for verbose, and longer pause for terse and medium.
  name: nested-negative-var-squared-or-cubed    # audit-ignore
  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]"
  - test:
      if: "$Verbosity='Verbose'"
      then: 
        - pause: short
        - T: "slutt eksponent"
      else: [pause: medium]

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

# Norwegian: Added "end exponent" for verbose, and longer pause for terse and medium.
- name: default   # audit-ignore
  tag: power
  match: "."
  replace:
  - x: "*[1]"
  - T: "opphøyd i"      # phrase(x 'raised to the' second power)
  - x: "*[2]"
  - test:
      if: "$Verbosity='Verbose'"
      then: 
        - pause: short
        - T: "slutt eksponent"
      else: [pause: medium]

#
# Some rules on mrows
#
- # the inference rules lump absolute value and cardinality together, so those rules are implemented here
  name: ClearSpeak-absolute-value   # audit-ignore
  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   # audit-ignore
  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 # audit-ignore
  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    # audit-ignore
  tag: mi
  variables: [log_is_simple: "IsNode(following-sibling::*[2],'simple')"] # skip function apply
  match: ".='log' or .='ln' or .='lg'"
  replace:
  - bookmark: "@id"
  - test:
      if: "$log_is_simple"
      then:
      - test:
        - if: ".='log'"
          then: [T: "log"]      # phrase(the 'log' of x)
        - else_if: ".='lg'"
          then: [SPELL: "'lg'"]      # phrase(the 'lg' of x)
        - else_if: $ClearSpeak_Log = 'LnAsNaturalLog'
          then: [T: "den naturlige logaritmen"]      # phrase(the 'natural log' of the product of 2 numbers)
          else: [SPELL: "'ln'"]
      else:
      - test:
        - if: ".='log'"
          then:
          - test:
            - if: "$Verbosity='Verbose'"
              then: [T: "logaritmen"]
              else: [T: "log"]
        - else_if: ".='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'"]

- name: ClearSpeak-multi-line   # audit-ignore
  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"
                then: [T: "tilfeller"]
                else: [T: "tilfelle"]      # phrase(this is the first 'case' of three cases)
        - else_if: "$ClearSpeak_MultiLineLabel = 'Auto' or $ClearSpeak_MultiLineLabel = 'Line'  or $ClearSpeak_MultiLineLabel = 'None'" # already dealt with Auto/Case
          then:
            - test:
              - if: "$LineCount > 1"
                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"
                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"
                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"
                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"
                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   # audit-ignore
  tag: mo
  match:
  - ".='⁡' and $ClearSpeak_Functions = 'None' and"
  - "not(preceding-sibling::*[1][IsInDefinition(., 'Speech', '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"

