---
- 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()
      - IsColumnSilent: false()
      replace:
      - test:
          if: "$MathRate = 100"
          then: [x: "*"]
          else:
          - rate:
              value: "$MathRate"
              replace: [x: "*"]

- name: empty-mrow
  tag: mrow
  match: "not(*)"
  replace:
  - T: " "

- name: default
  tag: mrow
  match: "."
  replace:
  - insert:
      nodes: "*"
      replace: [pause: auto]

- name: default
  tag: mn
  match: "."
  replace:
  - bookmark: "@id"
  - x: "translate(., $BlockSeparators, '')"

- 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() != '_'"
      then: [x: "text()"]
    - else_if: "@data-chem-element"
      then: [SPELL: "text()", pause: "short"]
      else: [x: "translate(., '-_\u00A0', '  ')"]

- name: default
  tag: ms
  match: "."
  replace:
  - T: "la chaîne"
  - pause: short
  - x: "text()"

- name: default
  tag: mstyle
  match: "."
  replace: [x: "*"]

- name: literal-simple
  tag: mfrac
  match:
  - "(IsNode(*[1],'leaf') and IsNode(*[2],'leaf')) and"
  - "not(ancestor::*[name() != 'mrow'][1]/self::m:fraction)"
  replace:
  - x: "*[1]"
  - T: "sur"
  - x: "*[2]"
  - pause: short

- name: literal-default
  tag: mfrac
  match: "."
  replace:
  - T: "début"
  - pause: short
  - x: "*[1]"
  - test:
      if: "not(IsNode(*[1],'leaf'))"
      then: [pause: short]
  - T: "sur"
  - test:
      if: "not(IsNode(*[2],'leaf'))"
      then: [pause: short]
  - x: "*[2]"
  - pause: short
  - test:
      if: "$Impairment = 'Blindness'"
      then: [T: "fin"]
  - pause: medium

- name: literal-default
  tag: msqrt
  match: "."
  replace:
  - T: "racine"
  - test:
      if: "$Verbosity!='Terse'"
      then: [T: "de"]
  - x: "*[1]"
  - pause: short
  - test:
      if: "not(IsNode(*[1],'leaf')) or $Impairment = 'Blindness'"
      then: [T: "fin de racine", pause: medium]

- name: literal-default
  tag: mroot
  match: "."
  replace:
  - T: "racine d'indice"
  - x: "*[2]"
  - pause: short
  - T: "de"
  - x: "*[1]"
  - pause: short
  - test:
      if: "not(IsNode(*[2],'leaf'))"
      then: [T: "fin de racine"]

- name: simple-sub
  tag: indexed-by
  match: "count(*)=2 and $Verbosity='Terse' and *[2][self::m:mn and translate(., '.,', '')=.]"
  replace:
  - x: "*[1]"
  - x: "*[2]"
  - pause: short

- name: no-end-sub
  tag: indexed-by
  match: "count(*)=2 and *[2][self::m:mrow and *[2][.='⁣']]"
  replace:
  - x: "*[1]"
  - T: "indice"
  - x: "*[2]"
  - pause: short

- name: power-indexed-by
  tag: power-indexed-by
  match: "."
  replace:
  - x: "*[1]"
  - T: "indice"
  - 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(., '.,', '')!=.)])"
      then: [T: "indice"]
  - x: "*[2]"

- name: literal
  tag: [msup, msubsup]
  match: "."
  replace:
  - x: "*[1]"
  - test:
      if: "name(.)='msubsup'"
      then:
      - T: "indice"
      - x: "*[2]"
  - test:
      if: "*[last()][translate(., '′″‴⁗†‡°*', '')='']"
      then:  [x: "*[last()]"]
      else_test:
          if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]"
          then:
          - T: "exposant"
          - x: "*[last()]"
          - test:
              if: "not(IsNode(*[last()], 'simple')) or $Impairment = 'Blindness'"
              then: [T: "fin d'exposant"]
          else:
          - T: "exposant"
          - x: "*[last()]"
          - T: "fin d'exposant"

- name: default
  tag: munder
  match: "."
  replace:
  - test:
      if: "not(IsNode(*[1], 'leaf'))"
      then: [T: "quantité"]
  - x: "*[1]"
  - T: "avec"
  - x: "*[2]"
  - T: "en dessous"

- name: diacriticals
  tag: mover
  match: "*[1][self::m:mi] and *[2][translate(., '\u0306\u030c.\u00A8\u02D9\u20DB\u20DC`^ˇ~→¯_', '')='']"
  replace:
  - x: "*[1]"
  - x: "*[2]"

- name: default
  tag: mover
  match: "."
  replace:
  - test:
      if: "not(IsNode(*[1], 'leaf'))"
      then: [T: "quantité"]
  - x: "*[1]"
  - T: "avec"
  - x: "*[2]"
  - T: "au-dessus"

- name: default
  tag: munderover
  match: "."
  replace:
  - test:
      if: "not(IsNode(*[1], 'leaf'))"
      then: [T: "quantité"]
  - x: "*[1]"
  - T: "avec"
  - x: "*[2]"
  - T: "en dessous et"
  - x: "*[3]"
  - T: "au-dessus"

- name: default
  tag: mmultiscripts
  match: "."
  variables:
  - Prescripts: "m:mprescripts/following-sibling::*"
  - NumChildren: "count(*)"
  - Postscripts: "*[position()>1 and position() < (last() + ($NumChildren mod 2) -count($Prescripts))]"
  replace:
  - x: "*[1]"
  - test:
      if: "$Prescripts"
      then:
      - with:
          variables:
          - PreSubscript: "IfThenElse($Verbosity='Verbose', 'pré-indice', 'pré-indice')"
          - PreSuperscript: "IfThenElse($Verbosity='Verbose', 'pré-exposant', 'pré-exposant')"
          replace:
          - test:
              if: "count($Prescripts) > 2"
              then:
              - T: "avec"
              - x: "count($Prescripts) div 2"
              - T: "préscripts"
              - pause: short
          - test:
              if: "not($Prescripts[1][self::m:none])"
              then:
              - x: "$PreSubscript"
              - x: "$Prescripts[1]"
          - test:
              if: "not($Prescripts[1][self::m:none] or $Prescripts[2][self::m:none])"
              then: [T: "et"]
          - test:
              if: "not($Prescripts[2][self::m:none])"
              then:
              - x: "$PreSuperscript"
              - x: "$Prescripts[2]"
          - pause: short
          - test:
              if: "count($Prescripts) > 2"
              then:
              - test:
                  if: "not($Prescripts[3][self::m:none])"
                  then:
                  - x: "$PreSubscript"
                  - x: "$Prescripts[3]"
              - test:
                  if: "not($Prescripts[3][self::m:none] or $Prescripts[4][self::m:none])"
                  then: [T: "et"]
              - test:
                  if: "not($Prescripts[4][self::m:none])"
                  then:
                  - x: "$PreSuperscript"
                  - x: "$Prescripts[4]"
              - test:
                  if: "count($Prescripts) > 4"
                  then:
                  - T: "et préscripts alternés"
                  - x: "$Prescripts[position() > 4]"
                  - T: "fin préscripts"
  - test:
      if: "$Postscripts"
      then:
      - with:
          variables:
          - PostSubscript: "IfThenElse($Verbosity='Verbose', 'indice', 'indice')"
          - PostSuperscript: "IfThenElse($Verbosity='Verbose', 'exposant', 'exposant')"
          replace:
          - test:
              if: "count($Postscripts) > 2"
              then:
              - test:
                  if: "$Prescripts"
                  then: [T: "et"]
              - T: "avec"
              - x: "count($Postscripts) div 2"
              - T: "postscripts"
              - pause: short
          - test:
              if: "not($Postscripts[1][self::m:none])"
              then:
              - x: "$PostSubscript"
              - x: "$Postscripts[1]"
          - test:
              if: "not($Postscripts[1][self::m:none] or $Postscripts[2][self::m:none])"
              then: [T: "et"]
          - test:
              if: "not($Postscripts[2][self::m:none])"
              then:
              - x: "$PostSuperscript"
              - x: "$Postscripts[2]"
          - test:
              if: "count($Postscripts) > 2"
              then:
              - test:
                  if: "not($Postscripts[3][self::m:none])"
                  then:
                  - x: "$PostSubscript"
                  - x: "$Postscripts[3]"
              - test:
                  if: "not($Postscripts[3][self::m:none] or $Postscripts[4][self::m:none])"
                  then: [T: "et"]
              - test:
                  if: "not($Postscripts[4][self::m:none])"
                  then:
                  - x: "$PostSuperscript"
                  - x: "$Postscripts[4]"
              - test:
                  if: "count($Postscripts) > 4"
                  then:
                  - test:
                      if: "not($Postscripts[5][self::m:none])"
                      then:
                      - x: "$PostSubscript"
                      - x: "$Postscripts[5]"
                  - test:
                      if: "not($Postscripts[5][self::m:none] or $Postscripts[6][self::m:none])"
                      then: [T: "et"]
                  - test:
                      if: "not($Postscripts[6][self::m:none])"
                      then:
                      - x: "$PostSuperscript"
                      - x: "$Postscripts[6]"
                  - test:
                      if: "count($Postscripts) > 6"
                      then:
                      - test:
                          if: "not($Postscripts[7][self::m:none])"
                          then:
                          - x: "$PostSubscript"
                          - x: "$Postscripts[7]"
                      - test:
                          if: "not($Postscripts[7][self::m:none] or $Postscripts[8][self::m:none])"
                          then: [T: "et"]
                      - test:
                          if: "not($Postscripts[8][self::m:none])"
                          then:
                          - x: "$PostSuperscript"
                          - x: "$Postscripts[8]"
                      - test:
                          if: "count($Postscripts) > 8"
                          then:
                          - T: "et scripts alternés"
                          - x: "$Postscripts[position() > 8]"
                          - T: "fin scripts"

- name: default
  tag: mtable
  variables:
  - IsColumnSilent: "false()"
  - NumColumns: "count(*[1]/*) - IfThenElse(*/self::m:mlabeledtr, 1, 0)"
  match: "."
  replace:
  - T: "table avec"             # phrase(the 'table with' 3 rows)
  - x: count(*)
  - test:
      if: count(*)=1
      then: [T: "rangée"]       # phrase(the table with 1 'row')
      else: [T: "rangées"]      # phrase(the table with 3 'rows')
  - T: "et"                     # phrase(the table with 3 rows 'and' 4 columns)
  - x: "$NumColumns"
  - test:
      if: "NumColumns=1"
      then: [T: "colonne"]      # phrase(the table with 3 rows and 1 'column')
      else: [T: "colonnes"]     # phrase(the table with 3 rows and 4 'columns')
  - pause: long
  - x: "*"

- name: default
  # callers/context should do that.
  # this may get called from navigation -- in that case, there is no context to speak the row #, so don't do it
  tag: [mtr, mlabeledtr]
  match: "."
  replace:
  - pause: medium
  - T: "rangée"      # phrase(the first 'row' of a matrix)
  - x: "count(preceding-sibling::*)+1"
  - test:
      if: "self::m:mlabeledtr"
      then:
      - T: "avec nom"      # 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: "colonne"      # 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: "Case vide"      # 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: "case", pause: short]      # phrase(the 'box' around the expression)
  - test:
      if: ".[contains(@notation,'roundedbox')]"
      then: [T: "case arrondie", pause: short]      # phrase(the 'round box' around the expression)
  - test:
      if: ".[contains(@notation,'circle')]"
      then: [T: "rond", 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:
      - test:
          if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' left ')]"
          then: [T: "ligne à gauche", pause: short]      # phrase('line on left' of the expression)
      - test:
          if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' right ')]"
          then: [T: "ligne à droite", pause: short]      # phrase('line on right' of the expression)
      - test:
          if: ".[contains(@notation,'top')]"
          then: [T: "ligne au dessus", pause: short]      # phrase('line on top' of the expression)
      - test:
          if: ".[contains(@notation,'bottom')]"
          then: [T: "ligne en dessous", pause: short]      # phrase('line on the bottom' of the expression)
  - test:
      if: ".[ contains(@notation,'updiagonalstrike') or contains(@notation,'downdiagonalstrike') or contains(@notation,'verticalstrike') or contains(@notation,'horizontalstrike') ]"
      then:
      - test:
          if: ".[contains(@notation,'updiagonalstrike') and contains(@notation,'downdiagonalstrike')]"
          then: [SPELL: "'x'", pause: short] # seems better to say 'x cross out' than 'up diagonal, down diagonal cross out'
          else:
          - test:
              if: ".[contains(@notation,'updiagonalstrike')]"
              then: [T: "diagonale vers le haut", pause: short]      # phrase(the line runs 'up diagonal')
          - test:
              if: ".[contains(@notation,'downdiagonalstrike')]"
              then: [T: "diagonale vers le bas", pause: short]      # phrase(the line runs 'down diagonal')
      - test:
          if: ".[contains(@notation,'verticalstrike')]"
          then: [T: "verticale", pause: short]      # phrase(the line is  'vertical')
      - test:
          if: ".[contains(@notation,'horizontalstrike')]"
          then: [T: "horizontale", pause: short]      # phrase(the line is 'horizontal')
      - T: "barré"      # phrase(please 'cross out' the incorrect answer)
      - pause: short
  - test:
      if: ".[contains(@notation,'uparrow')]"
      then: [T: "flèche vers le haut", pause: short]      # phrase(direction is shown by the 'up arrow')
  - test:
      if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' downarrow ')]"
      then: [T: "flèche vers le bas", pause: short]      # phrase(the trend is shown by the 'down arrow')
  - test:
      if: ".[contains(@notation,'leftarrow')]"
      then: [T: "flèche vers la gauche", pause: short]      # phrase(the 'left arrow' indicates going back)
  - test:
      if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' rightarrow ')]"
      then: [T: "flèche vers la droite", pause: short]      # phrase(the 'right arrow' indicates moving forward)
  - test:
      if: ".[contains(@notation,'northeastarrow')]"
      then: [T: "flèche nord-est", pause: short]      # phrase(direction is indicated by the 'northeast arrow')
  - test:
      if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' southeastarrow ')]"
      then: [T: "flèche sud-est", pause: short]      # phrase(direction is shown by the 'southeast arrow')
  - test:
      if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' southwestarrow ')]"
      then: [T: "flèche sud-ouest", pause: short]      # phrase(direction is shown by the 'southwest arrow')
  - test:
      if: ".[contains(@notation,'northwestarrow')]"
      then: [T: "flèche nord-ouest", pause: short]      # phrase(direction is shown by the 'northwest arrow')
  - test:
      if: ".[contains(@notation,'updownarrow')]"
      then: [T: "flèche verticale à double extrémité", pause: short]      # phrase(upward movement is indicated by the 'double ended vertical arrow')
  - test:
      if: ".[contains(@notation,'leftrightarrow')]"
      then: [T: "flèche horizontale à double extrémité", pause: short]      # phrase(progress is indicated by the 'double ended horizontal arrow')
  - test:
      if: ".[contains(@notation,'northeastsouthwestarrow')]"
      then: [T: "flèche diagonale vers le haut à double extrémité", pause: short]      # phrase(trend is indicated by the 'double ended up diagonal arrow')
  - test:
      if: ".[contains(@notation,'northwestsoutheastarrow')]"
      then: [T: "flèche diagonale vers le bas à double extrémité", pause: short]      # phrase(trend is indicated by the 'double ended down diagonal arrow')
  - test:
      if: ".[contains(@notation,'actuarial')]"
      then: [T: "symbole actuariel", pause: short]      # phrase(the 'actuarial symbol' represents a specific quantity)
  - test:
      if: ".[contains(@notation,'madrub')]"
      then: [T: "symbole factoriel arabe", pause: short]      # phrase(the 'arabic factorial symbol' represents a factorial operation)
  - test:
      if: ".[contains(@notation,'phasorangle')]"
      then: [T: "angle de phaseur", 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: "symbole de division longue", pause: short]      # phrase(the 'long division symbol' indicates  a long division calculation)
  - test:
      if: ".[contains(@notation,'radical')]"
      then: [T: "racine carrée", pause: short]      # phrase(5 is the 'square root' of 25)
  - T: "contenant"      # phrase(parentheses are 'enclosing' part of the equation)
  - test:
      if: "*[self::m:mtext and .=' ']"
      then: [T: "espace"]     # otherwise there is complete silence      # phrase(there is a 'space' between the words)
      else: [x: "*"]
  - test:
      if: "$Impairment = 'Blindness' and ( $SpeechStyle != 'SimpleSpeak' or not(IsNode(*[1], 'leaf')) )"
      then: [T: "fin d'encadrement"]      # 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: "de"
  - pause: auto
  - x: "*[position() > 1]"

# 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:') or translate(name(.), '-_', '')='')"
  replace:
  - x: "*"
  - test:
      if: "IsNode(., '2D')"
      then: [pause: short]
      else: [pause: auto]


- name: prefix-intent
  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
  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
  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"
      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')"
      then: [pause: short]
      else: [pause: auto]

- name: function-intent
  tag: "*"
  match: "count(*)>0"
  replace:
  - x: "DEBUG(SpeakIntentName(name(.), $Verbosity, 'function'))"
  - test:
      if: "$Verbosity != 'Terse' and not(contains(@data-intent-property, ':literal:')) and
           not(count(*)=2 and (IsInDefinition(*[1], 'TrigFunctionNames') or IsInDefinition(name(.), 'TerseFunctionNames')) and IsNode(*[2], 'simple'))"
      then: [T: "de", pause: auto]
  - insert:
      nodes: "*"
      replace:
      - test:
          if: "not(contains(@data-intent-property, ':literal:'))"
          then: [x: "','"]
      - pause: auto
  - test:
      if: "$Impairment = 'Blindness' and not(*[last()][IsBracketed(., '', '') or IsNode(., 'simple')] )"
      then: [x: "GetBracketingIntentName(name(.), $Verbosity, 'function', 'end')"]
  - test:
      if: "IsNode(., '2D')"
      then: [pause: short]
      else: [pause: auto]

- name: default-text
  tag: "*"
  match: "."
  replace:
  - x: "translate(name(), '-_', ' ')"
