---

- name: intent-literal-silent
  tag: [mi, mo, mn]
  match: "contains(@data-intent-property, ':silent:')"
  # say nothing
  replace: []

# handling of negative numbers is hard -- we do something that is close to right here
- name: intent-literal-negative-number
  tag: mn
  match: "starts-with(text(), '-')" 
  replace:
  - T: "trừ"
  - x: "translate(text(), '-_', '')"   # more accurate to translate "-" to nothing, but turning it into a space should be ok

- name: default
  tag: square-root
  match: "."
  replace:
  # - test:
  #     if: "$Verbosity!='Terse'"
  #     then: [t: the]
  - T: căn bậc hai
  - test:
      if: "$Verbosity!='Terse'"
      then: [T: của]
      else: [pause: short]
  - x: "*[1]"
  - test:
      if: IsNode(*[1], 'leaf')
      then: [pause: short]
      else: [T: hết căn, pause: short]

- name: default
  tag: root
  match: "."
  replace:
  # - test:
  #     if: "$Verbosity!='Terse'"
  #     then: [T: the]
  - test:
      if: "*[2][self::m:mn]"
      then_test:
      - if: "*[2][.='2']"
        then: [T: căn bậc hai]
      - else_if: "*[2][.='3']"
        then: [T: căn bậc ba]
      - else_if: "*[2][not(contains(., '.'))]"
        then: [T: căn bậc, x: "ToOrdinal(*[2])"]
      else:
      - test:
          if: "*[2][self::m:mi][string-length(.)=1]"
          then:
          - x: "*[2]"
          #- pronounce: [text: "-th", ipa: "θ", sapi5: "th", eloquence: "T"]
          else: [x: "*[2]"]
      - T: căn
    # - test: 
  - test:
      if: "$Verbosity!='Terse'"
      then: [T: của]
  - x: "*[1]"
  - test:
      if: IsNode(*[1], 'leaf')
      then: [pause: short]
      else: [T: hết căn, pause: short]

# Fraction rules
# Mixed numbers mostly "just work" because the invisible char reads as "and" and other parts read properly on their own
- name: common-fraction
  tag: fraction
  match:
  - "*[1][self::m:mn][not(contains(., '.')) and text()<20]   and"
  - "*[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]"
  replace: [x: ToCommonFraction(.)]
- name: common-fraction-mixed-number
  tag: fraction
  match:
  - "preceding-sibling::*[1][self::m:mo][.='⁤'] and" # preceding element is invisible plus
  - "*[1][self::m:mn][not(contains(., '.'))]   and"
  - "*[2][self::m:mn][not(contains(., '.'))]"
  replace: [x: ToCommonFraction(.)]

# Units (e.g., meters per second, m^2/s^2, (3m^2)/s)
- name: per-fraction
  tag: fraction
  match:
  - "BaseNode(*[1])[contains(@data-intent-property, ':unit') or"
  - "               ( self::m:mrow and count(*)=3 and"  # maybe a bit paranoid checking the structure...
  - "                 *[1][self::m:mn] and *[2][.='\u2062'] and BaseNode(*[3])[contains(@data-intent-property, ':unit')] ) ] and"
  - "BaseNode(*[2])[contains(@data-intent-property, ':unit')] "
  replace:
  - x: "*[1]"
  - t: "trên"      # phrase('5 meters 'per' second)
  - x: "*[2]"

- name: simple
  # don't include nested fractions. E.g, fraction a plus b over c + 1 end fraction" is ambiguous
  # by simplistic SimpleSpeak's rules "b over c" is a fraction, but if we say nested fractions
  # are never simple, then any 'over' applies only to enclosing "fraction...end fraction" pair.
  tag: fraction
  match:
  - "(IsNode(*[1],'leaf') and IsNode(*[2],'leaf')) and"
  - "not(ancestor::*[name() != 'mrow'][1]/self::m:fraction)" # FIX: can't test for mrow -- what should be used???
  replace:
  - x: "*[1]"
  - T: trên
  - x: "*[2]"
  - pause: short

- name: default
  tag: fraction
  match: "."
  replace:
  - T: phân số
  - pause: short
  - x: "*[1]"
  - test:
      if: "not(IsNode(*[1],'leaf'))"
      then: [pause: short]
  - T: trên
  - test:
      if: "not(IsNode(*[2],'leaf'))"
      then: [pause: short]
  - x: "*[2]"
  - pause: short
  - T: hết phân số
  - 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: hàm nghịch đảo
  - 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: bình phương]
      else: [T: lập phương]
- name: function-power
  tag: power
  match:
  - "following-sibling::*[1][self::m:mo][.='⁡']" #invisible function apply
  replace:
  # - test: 
  #     if: "$Verbosity!='Terse'"
  #    then: [T: the]
  - bookmark: "*[2]/@id"
  - test:
      if: "*[2][self::m:mn][not(contains(., '.'))]"
      then: [x: "ToOrdinal(*[2])"]
      else: [x: "*[2]"]
  - T: mũ
  - pause: short
  - x: "*[1]"

# non-function rules for power
- name: squared-or-cubed
  tag: power
  match: "*[2][self::m:mn][.='2' or .='3']"
  replace:
  - x: "*[1]"
  - bookmark: "*[2]/@id"
  - test:
      if: "*[2][.=2]"
      then: [T: bình phương]
      else: [T: lập phương]

- name: simple-integer
  tag: power
  match: "*[2][self::m:mn][not(contains(., '.'))]"
  replace:
  - x: "*[1]"
  - T: mũ
  - test:
      if: "*[2][.>0]"
      then: [x: "ToOrdinal(*[2])"]
      else: [x: "*[2]"]
- name: simple-negative-integer
  tag: power
  match:
  - "*[2][self::m:minus and count(*)=1 and"
  - "     *[1][self::m:mn][not(contains(., '.'))]]"
  replace:
  - x: "*[1]"
  - T: mũ
  - x: "*[2]"
- name: simple-var
  tag: power
  match: "*[2][self::m:mi][string-length(.)=1]"
  replace:
  - x: "*[1]"
  - T: mũ
  - x: "*[2]"
  #- pronounce: [text: "-th", ipa: "θ", sapi5: "th", eloquence: "T"]

- name: simple
  tag: power
  match: "IsNode(*[2], 'leaf')"
  replace:
  - x: "*[1]"
  - T: mũ
  - x: "*[2]"

- name: nested
  # it won't end in "power" if the exponent is simple enough
  # FIX: not that important, but this misses the case where the nested exp is a negative integer (change test if this is fixed)
  # ending nested exponents with "...power power" sounds bad
  tag: power
  match:
  - "*[2]["
  - "     (self::m:power and not(IsNode(*[2], 'leaf'))) or" # non-simple nested superscript
  - "     self::m:mrow[*[last()][self::m:power[not(IsNode(*[2], 'leaf'))]]]" # same as above but at the end of an mrow # FIX: need to figure out linear replacement
  - "    ]"
  replace:
  - x: "*[1]"
  - T: lũy thừa
  - x: "*[2]"
  - pause: short
  - T: hết lũy thừa
- name: default
  tag: power
  match: "."
  replace:
  - x: "*[1]"
  - T: mũ
  - x: "*[2]"
  #- T: power

#
# Some rules on mrows
#
- name: set
  tag: set
  match: "."
  replace:
  - test:
    - if: "count(*)=0"
      then:
      # - test: 
      #   if: "$Verbosity!='Terse'"
      #  then: [T: the]
      - T: tập hợp rỗng
    - else_if: "count(*[1]/*)=3 and *[1]/*[2][self::m:mo][.=':' or .='|' or .='∣']"
      then:
      # - test: 
      #   if: "$Verbosity!='Terse'"
      #  then: [T: the]
      - T: tập hợp của
      - x: "*[1]/*[1]"
      - T: sao cho
      - x: "*[1]/*[3]"
      else:
      #     if: "$Verbosity!='Terse'"
      #    then: [T: the]
      - T: tập hợp
        #   - test: 
      - x: "*[1]"

- name: times
  tag: mo
  match:
  # say "times" when invisible times is followed by parens or a superscript that has a base with parens or "|"s
  # added: say times is the superscript is not simple
  # if we aren't sure if it is times or not, don't say anything
  - ".='⁢' and"
  - "not(@data-function-guess) and ("
  - "not(ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) and "
  - "  following-sibling::*[1]["
  - "    IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|') or "
  - "    self::m:matrix or self::m:determinant or self::m:binomial or" # followed by parens
  - "    ( (self::m: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: nhân

- name: no-say-parens
  tag: mrow
  match:
  - "parent::*[not(self::m:msup) and not(self::m:msub) and not(self::m:msubsup) and not(self::m:power) and"
  - "          not(self::m:math) ] and "       # rule out [x] standing alone
  - "( IsBracketed(., '(', ')') or IsBracketed(., '[', ']') ) and "
  - "( IsNode(*[2], 'simple')  )"
  # missing clause: 'a positive fraction that is spoken as an ordinal
  #   (either by the Ordinal preference or by the default rules_'
  replace:
  - x: "*[2]"

- include: "SharedRules/geometry.yaml"
- include: "SharedRules/linear-algebra.yaml"
- include: "SharedRules/calculus.yaml"
- include: "SharedRules/general.yaml"
- include: "SharedRules/default.yaml"
